@jameslovespancakes/pi-plus 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -22
- package/config/skills/workflow-code-review-actions/SKILL.md +44 -0
- package/package.json +9 -4
- package/src/core/accounts/oauth-pool.ts +137 -0
- package/src/core/accounts/registry.ts +12 -25
- package/src/core/accounts/routing.ts +144 -0
- package/src/core/anthropic/client-identity.ts +9 -64
- package/src/core/anthropic/identity.ts +54 -0
- package/src/core/anthropic/oauth.ts +3 -0
- package/src/core/anthropic/quota.ts +232 -78
- package/src/core/anthropic/routing.ts +40 -115
- package/src/core/anthropic/store.ts +11 -10
- package/src/core/catalog/quality.ts +33 -15
- package/src/core/codex/quota.ts +46 -8
- package/src/core/codex/store.ts +29 -16
- package/src/core/config.ts +16 -17
- package/src/core/store.ts +13 -12
- package/src/domains/agents/format.ts +97 -0
- package/src/domains/agents/index.ts +58 -47
- package/src/domains/compact/archive.ts +140 -0
- package/src/domains/compact/chunking.ts +166 -0
- package/src/domains/compact/index.ts +452 -0
- package/src/domains/compact/jev.ts +242 -0
- package/src/domains/compact/policy.ts +255 -0
- package/src/domains/compact/types.ts +79 -0
- package/src/domains/models/provider-picker.ts +1 -1
- package/src/domains/setup/index.ts +23 -23
- package/src/domains/subscriptions/accounts-picker.ts +61 -40
- package/src/domains/subscriptions/accounts.ts +53 -36
- package/src/domains/subscriptions/footer.ts +48 -29
- package/src/domains/subscriptions/index.ts +11 -27
- package/src/domains/subscriptions/provider.ts +79 -103
- package/src/domains/subscriptions/providers/anthropic.ts +42 -22
- package/src/domains/subscriptions/providers/codex.ts +146 -113
- package/src/domains/subscriptions/providers/hosted.ts +18 -0
- package/src/domains/subscriptions/providers/oauth-pool.ts +325 -0
- package/src/domains/subscriptions/routing.ts +19 -11
- package/src/domains/workflows/LICENSE.md +21 -0
- package/src/domains/workflows/index.ts +836 -0
- package/src/domains/workflows/runtime/advisory-challenge.ts +75 -0
- package/src/domains/workflows/runtime/advisory-evidence.ts +90 -0
- package/src/domains/workflows/runtime/advisory-schema.ts +83 -0
- package/src/domains/workflows/runtime/agent-attempt.ts +177 -0
- package/src/domains/workflows/runtime/agent-failure.ts +14 -0
- package/src/domains/workflows/runtime/agent-limits.ts +66 -0
- package/src/domains/workflows/runtime/agent-replay.ts +399 -0
- package/src/domains/workflows/runtime/agent-retry.ts +116 -0
- package/src/domains/workflows/runtime/agent-runner-types.ts +96 -0
- package/src/domains/workflows/runtime/agent-runner.ts +225 -0
- package/src/domains/workflows/runtime/agent-session-identity.ts +256 -0
- package/src/domains/workflows/runtime/agent-session-providers.ts +50 -0
- package/src/domains/workflows/runtime/agent-session.ts +382 -0
- package/src/domains/workflows/runtime/agent-skills.ts +270 -0
- package/src/domains/workflows/runtime/agent-workspace.ts +79 -0
- package/src/domains/workflows/runtime/background-workflow-tool.ts +75 -0
- package/src/domains/workflows/runtime/background-workflows.ts +492 -0
- package/src/domains/workflows/runtime/budget.ts +53 -0
- package/src/domains/workflows/runtime/cancellation.ts +87 -0
- package/src/domains/workflows/runtime/command-completions.ts +36 -0
- package/src/domains/workflows/runtime/concurrency.ts +403 -0
- package/src/domains/workflows/runtime/debug.ts +3 -0
- package/src/domains/workflows/runtime/diff-capture.ts +81 -0
- package/src/domains/workflows/runtime/discovery.ts +137 -0
- package/src/domains/workflows/runtime/dynamax-shortcuts.ts +122 -0
- package/src/domains/workflows/runtime/dynamax.ts +330 -0
- package/src/domains/workflows/runtime/engine.ts +579 -0
- package/src/domains/workflows/runtime/filesystem-error.ts +4 -0
- package/src/domains/workflows/runtime/finalizers.ts +66 -0
- package/src/domains/workflows/runtime/identity-canonicalization.ts +138 -0
- package/src/domains/workflows/runtime/identity-fingerprint.ts +15 -0
- package/src/domains/workflows/runtime/inline-workflow.ts +403 -0
- package/src/domains/workflows/runtime/journal.ts +313 -0
- package/src/domains/workflows/runtime/model-profiles.ts +310 -0
- package/src/domains/workflows/runtime/options.ts +157 -0
- package/src/domains/workflows/runtime/perf.ts +146 -0
- package/src/domains/workflows/runtime/pi-compat.ts +32 -0
- package/src/domains/workflows/runtime/process-runner.ts +260 -0
- package/src/domains/workflows/runtime/progress-types.ts +59 -0
- package/src/domains/workflows/runtime/progress.ts +400 -0
- package/src/domains/workflows/runtime/provider-usage-limit.ts +191 -0
- package/src/domains/workflows/runtime/replay-path-identity.ts +48 -0
- package/src/domains/workflows/runtime/research-contract.ts +89 -0
- package/src/domains/workflows/runtime/research-evidence.ts +289 -0
- package/src/domains/workflows/runtime/resume-context.ts +751 -0
- package/src/domains/workflows/runtime/review/code-review-orchestration.ts +24 -0
- package/src/domains/workflows/runtime/review/github-pr-comments.ts +249 -0
- package/src/domains/workflows/runtime/review/patch-validation.ts +120 -0
- package/src/domains/workflows/runtime/review/review-actions.ts +180 -0
- package/src/domains/workflows/runtime/review/review-budget.ts +45 -0
- package/src/domains/workflows/runtime/review/review-fix-workflow.ts +153 -0
- package/src/domains/workflows/runtime/review/review-format.ts +133 -0
- package/src/domains/workflows/runtime/review/review-handoff.ts +38 -0
- package/src/domains/workflows/runtime/review/review-issues.ts +87 -0
- package/src/domains/workflows/runtime/review/review-report.ts +42 -0
- package/src/domains/workflows/runtime/review/review-results-flow.ts +52 -0
- package/src/domains/workflows/runtime/review/review-results-viewer.ts +312 -0
- package/src/domains/workflows/runtime/review/review-session-coordinator.ts +153 -0
- package/src/domains/workflows/runtime/review/review-snapshot.ts +294 -0
- package/src/domains/workflows/runtime/review-diff-target.ts +130 -0
- package/src/domains/workflows/runtime/session-identity.ts +6 -0
- package/src/domains/workflows/runtime/structured-output.ts +32 -0
- package/src/domains/workflows/runtime/tool-capabilities.ts +44 -0
- package/src/domains/workflows/runtime/tool-source-identity.ts +150 -0
- package/src/domains/workflows/runtime/tree-fingerprint.ts +404 -0
- package/src/domains/workflows/runtime/types.ts +255 -0
- package/src/domains/workflows/runtime/ui/display-text.ts +28 -0
- package/src/domains/workflows/runtime/ui/dynamax-editor-decoration.ts +220 -0
- package/src/domains/workflows/runtime/ui/workflow-format.ts +165 -0
- package/src/domains/workflows/runtime/ui/workflow-inspector.ts +435 -0
- package/src/domains/workflows/runtime/ui/workflow-result-renderer.ts +171 -0
- package/src/domains/workflows/runtime/ui/workflow-viewer-layout.ts +51 -0
- package/src/domains/workflows/runtime/ui/workflow-widget.ts +78 -0
- package/src/domains/workflows/runtime/unknown-error.ts +8 -0
- package/src/domains/workflows/runtime/usage.ts +341 -0
- package/src/domains/workflows/runtime/workflow-advisory-utils.ts +245 -0
- package/src/domains/workflows/runtime/workflow-execution.ts +121 -0
- package/src/domains/workflows/runtime/workflow-module.ts +75 -0
- package/src/domains/workflows/runtime/workflow-run-background.ts +72 -0
- package/src/domains/workflows/runtime/workflow-run-controller.ts +342 -0
- package/src/domains/workflows/runtime/workflow-run-history.ts +164 -0
- package/src/domains/workflows/runtime/workflow-run-record.ts +636 -0
- package/src/domains/workflows/runtime/workflow-run-store.ts +176 -0
- package/src/domains/workflows/runtime/workflow-usage-limit-scheduler.ts +80 -0
- package/src/domains/workflows/runtime/workflows.ts +40 -0
- package/src/domains/workflows/runtime/worktree.ts +615 -0
- package/src/domains/workflows/workflows/code-review.ts +232 -0
- package/src/domains/workflows/workflows/diagnose.ts +154 -0
- package/src/domains/workflows/workflows/perf-review.ts +149 -0
- package/src/domains/workflows/workflows/refactor-scout.ts +143 -0
- package/src/domains/workflows/workflows/research.ts +169 -0
- package/src/services/usage-service.ts +6 -30
- package/src/ui/usage-bars.ts +1 -2
- package/src/core/codex/oauth.ts +0 -129
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, join } from "node:path";
|
|
4
|
+
import { validateWorkflowRunId, workflowRunsDir } from "./journal.ts";
|
|
5
|
+
import type { WorkflowProgressSnapshot } from "./progress-types.ts";
|
|
6
|
+
import {
|
|
7
|
+
isWorkflowRunRecord,
|
|
8
|
+
transitionWorkflowRun,
|
|
9
|
+
updateWorkflowRunProgress,
|
|
10
|
+
type WorkflowRunRecord,
|
|
11
|
+
type WorkflowRunTransition,
|
|
12
|
+
} from "./workflow-run-record.ts";
|
|
13
|
+
|
|
14
|
+
export const WORKFLOW_RUN_RECORD_KEEP = 50;
|
|
15
|
+
export const WORKFLOW_RUN_RECORD_SUFFIX = ".run.json";
|
|
16
|
+
|
|
17
|
+
const MAX_RECORD_BYTES = 4 << 20;
|
|
18
|
+
|
|
19
|
+
export interface WorkflowRunStore {
|
|
20
|
+
save(record: WorkflowRunRecord): Promise<void>;
|
|
21
|
+
load(runId: string): Promise<WorkflowRunRecord | undefined>;
|
|
22
|
+
list(): Promise<WorkflowRunRecord[]>;
|
|
23
|
+
prune(keep?: number): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class ProjectWorkflowRunStore implements WorkflowRunStore {
|
|
27
|
+
private readonly cwd: string;
|
|
28
|
+
|
|
29
|
+
constructor(cwd: string) {
|
|
30
|
+
this.cwd = cwd;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async save(record: WorkflowRunRecord): Promise<void> {
|
|
34
|
+
const path = workflowRunRecordPath(this.cwd, record.runId);
|
|
35
|
+
const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
36
|
+
const content = `${JSON.stringify(record)}\n`;
|
|
37
|
+
if (Buffer.byteLength(content) > MAX_RECORD_BYTES) {
|
|
38
|
+
throw new Error(`Workflow run record exceeded ${MAX_RECORD_BYTES} bytes.`);
|
|
39
|
+
}
|
|
40
|
+
await mkdir(dirname(path), { recursive: true });
|
|
41
|
+
try {
|
|
42
|
+
await writeFile(temporaryPath, content, { encoding: "utf8", mode: 0o600 });
|
|
43
|
+
await rename(temporaryPath, path);
|
|
44
|
+
} finally {
|
|
45
|
+
await rm(temporaryPath, { force: true }).catch(() => undefined);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async load(runId: string): Promise<WorkflowRunRecord | undefined> {
|
|
50
|
+
return await loadWorkflowRunRecord(workflowRunRecordPath(this.cwd, runId));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async list(): Promise<WorkflowRunRecord[]> {
|
|
54
|
+
const dir = workflowRunsDir(this.cwd);
|
|
55
|
+
let files: string[];
|
|
56
|
+
try {
|
|
57
|
+
files = await readdir(dir);
|
|
58
|
+
} catch {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const records = await Promise.all(
|
|
62
|
+
files
|
|
63
|
+
.filter((file) => file.endsWith(WORKFLOW_RUN_RECORD_SUFFIX))
|
|
64
|
+
.map((file) => loadWorkflowRunRecord(join(dir, file))),
|
|
65
|
+
);
|
|
66
|
+
return records
|
|
67
|
+
.filter((record): record is WorkflowRunRecord => record !== undefined)
|
|
68
|
+
.sort((left, right) => right.updatedAt - left.updatedAt);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async prune(keep = WORKFLOW_RUN_RECORD_KEEP): Promise<void> {
|
|
72
|
+
const dir = workflowRunsDir(this.cwd);
|
|
73
|
+
let files: string[];
|
|
74
|
+
try {
|
|
75
|
+
files = await readdir(dir);
|
|
76
|
+
} catch {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const candidates = await Promise.all(
|
|
80
|
+
files
|
|
81
|
+
.filter((file) => file.endsWith(WORKFLOW_RUN_RECORD_SUFFIX))
|
|
82
|
+
.map(async (file) => {
|
|
83
|
+
const path = join(dir, file);
|
|
84
|
+
try {
|
|
85
|
+
const info = await stat(path);
|
|
86
|
+
return { path, mtimeMs: info.mtimeMs };
|
|
87
|
+
} catch {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
92
|
+
const stale = candidates
|
|
93
|
+
.filter((entry): entry is { readonly path: string; readonly mtimeMs: number } => entry !== undefined)
|
|
94
|
+
.sort((left, right) => right.mtimeMs - left.mtimeMs)
|
|
95
|
+
.slice(Math.max(0, keep));
|
|
96
|
+
await Promise.all(stale.map((entry) => rm(entry.path, { force: true }).catch(() => undefined)));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Owns one run record and coalesces progress writes while a prior atomic save is in flight. */
|
|
101
|
+
export class DurableWorkflowRun {
|
|
102
|
+
private record: WorkflowRunRecord;
|
|
103
|
+
private pending: WorkflowRunRecord | undefined;
|
|
104
|
+
private draining: Promise<void> | undefined;
|
|
105
|
+
private writeFailure: unknown;
|
|
106
|
+
private writeFailed = false;
|
|
107
|
+
|
|
108
|
+
constructor(
|
|
109
|
+
private readonly store: WorkflowRunStore,
|
|
110
|
+
initial: WorkflowRunRecord,
|
|
111
|
+
private readonly onWriteFailure?: (error: unknown) => void,
|
|
112
|
+
) {
|
|
113
|
+
this.record = initial;
|
|
114
|
+
this.queue(initial);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
updateProgress(progress: WorkflowProgressSnapshot, at = Date.now()): void {
|
|
118
|
+
this.record = updateWorkflowRunProgress(this.record, progress, at);
|
|
119
|
+
this.queue(this.record);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
transition(transition: WorkflowRunTransition): void {
|
|
123
|
+
this.record = transitionWorkflowRun(this.record, transition);
|
|
124
|
+
this.queue(this.record);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async flush(): Promise<void> {
|
|
128
|
+
while (this.draining) await this.draining;
|
|
129
|
+
if (this.writeFailed) throw this.writeFailure;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private queue(record: WorkflowRunRecord): void {
|
|
133
|
+
this.pending = record;
|
|
134
|
+
if (this.draining) return;
|
|
135
|
+
this.draining = this.drain().finally(() => {
|
|
136
|
+
this.draining = undefined;
|
|
137
|
+
if (this.pending) this.queue(this.pending);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private async drain(): Promise<void> {
|
|
142
|
+
while (this.pending) {
|
|
143
|
+
const next = this.pending;
|
|
144
|
+
this.pending = undefined;
|
|
145
|
+
try {
|
|
146
|
+
await this.store.save(next);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
this.writeFailed = true;
|
|
149
|
+
this.writeFailure = error;
|
|
150
|
+
try {
|
|
151
|
+
this.onWriteFailure?.(error);
|
|
152
|
+
} catch {
|
|
153
|
+
// Persistence observers must not create an unhandled rejection.
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function workflowRunRecordPath(cwd: string, runId: string): string {
|
|
161
|
+
return join(workflowRunsDir(cwd), `${validateWorkflowRunId(runId)}${WORKFLOW_RUN_RECORD_SUFFIX}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async function loadWorkflowRunRecord(path: string): Promise<WorkflowRunRecord | undefined> {
|
|
165
|
+
try {
|
|
166
|
+
const content = await readFile(path, "utf8");
|
|
167
|
+
if (Buffer.byteLength(content) > MAX_RECORD_BYTES) return undefined;
|
|
168
|
+
const parsed = JSON.parse(content) as unknown;
|
|
169
|
+
if (!isWorkflowRunRecord(parsed)) return undefined;
|
|
170
|
+
const file = basename(path);
|
|
171
|
+
const pathRunId = file.slice(0, -WORKFLOW_RUN_RECORD_SUFFIX.length);
|
|
172
|
+
return parsed.runId === pathRunId ? parsed : undefined;
|
|
173
|
+
} catch {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { WorkflowRunRecord } from "./workflow-run-record.ts";
|
|
3
|
+
import { unknownErrorMessage } from "./unknown-error.ts";
|
|
4
|
+
|
|
5
|
+
export interface WorkflowUsageLimitSchedulerClock {
|
|
6
|
+
now(): number;
|
|
7
|
+
setTimeout(callback: () => void, delayMs: number): unknown;
|
|
8
|
+
clearTimeout(handle: unknown): void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ScheduledUsageLimitResume {
|
|
12
|
+
readonly sessionId: string;
|
|
13
|
+
readonly handle: unknown;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const defaultWorkflowUsageLimitSchedulerClock: WorkflowUsageLimitSchedulerClock = {
|
|
17
|
+
now: () => Date.now(),
|
|
18
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
19
|
+
clearTimeout: (handle) => clearTimeout(handle as ReturnType<typeof setTimeout>),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** One in-process timer per paused run. Durable records remain the source of truth. */
|
|
23
|
+
export class WorkflowUsageLimitScheduler {
|
|
24
|
+
private readonly scheduled = new Map<string, ScheduledUsageLimitResume>();
|
|
25
|
+
private readonly inactiveSessions = new Set<string>();
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
private readonly resume: (ctx: ExtensionContext, runId: string, attempt: number) => Promise<void>,
|
|
29
|
+
private readonly clock: WorkflowUsageLimitSchedulerClock = defaultWorkflowUsageLimitSchedulerClock,
|
|
30
|
+
private readonly log: (message: string) => void = (message) => process.stderr.write(`${message}\n`),
|
|
31
|
+
) {}
|
|
32
|
+
|
|
33
|
+
arm(ctx: ExtensionContext, record: WorkflowRunRecord): boolean {
|
|
34
|
+
if (record.state !== "paused" || record.pause?.kind !== "provider_usage_limit") return false;
|
|
35
|
+
const pause = record.pause;
|
|
36
|
+
if (!pause.autoResume || pause.attempt >= pause.maxAttempts) return false;
|
|
37
|
+
const sessionId = ctx.sessionManager.getSessionId();
|
|
38
|
+
if (
|
|
39
|
+
this.inactiveSessions.has(sessionId)
|
|
40
|
+
|| record.background?.origin.sessionId !== sessionId
|
|
41
|
+
|| this.scheduled.has(record.runId)
|
|
42
|
+
) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const delayMs = Math.max(0, pause.nextEligibleAt - this.clock.now());
|
|
47
|
+
const handle = this.clock.setTimeout(() => {
|
|
48
|
+
this.scheduled.delete(record.runId);
|
|
49
|
+
void this.resume(ctx, record.runId, pause.attempt).catch((error: unknown) => {
|
|
50
|
+
this.log(`[workflow:${record.runId}] automatic provider-limit resume failed: ${unknownErrorMessage(error)}`);
|
|
51
|
+
});
|
|
52
|
+
}, delayMs);
|
|
53
|
+
this.scheduled.set(record.runId, { sessionId, handle });
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
cancel(runId: string): boolean {
|
|
58
|
+
const scheduled = this.scheduled.get(runId);
|
|
59
|
+
if (!scheduled) return false;
|
|
60
|
+
this.clock.clearTimeout(scheduled.handle);
|
|
61
|
+
this.scheduled.delete(runId);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
cancelSession(ctx: Pick<ExtensionContext, "sessionManager">): void {
|
|
66
|
+
const sessionId = ctx.sessionManager.getSessionId();
|
|
67
|
+
this.inactiveSessions.add(sessionId);
|
|
68
|
+
for (const [runId, scheduled] of this.scheduled) {
|
|
69
|
+
if (scheduled.sessionId === sessionId) this.cancel(runId);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
activateSession(ctx: Pick<ExtensionContext, "sessionManager">): void {
|
|
74
|
+
this.inactiveSessions.delete(ctx.sessionManager.getSessionId());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
has(runId: string): boolean {
|
|
78
|
+
return this.scheduled.has(runId);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import * as codeReview from "../workflows/code-review.ts";
|
|
3
|
+
import * as refactorScout from "../workflows/refactor-scout.ts";
|
|
4
|
+
import * as diagnose from "../workflows/diagnose.ts";
|
|
5
|
+
import * as perfReview from "../workflows/perf-review.ts";
|
|
6
|
+
import * as research from "../workflows/research.ts";
|
|
7
|
+
import type { WorkflowModule } from "./types.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Static imports share pi's bundled typebox instance. Add guaranteed workflows
|
|
11
|
+
* here; discovery.ts handles optional drop-ins.
|
|
12
|
+
*/
|
|
13
|
+
export const BUILTIN_SOURCE_ROOT = fileURLToPath(new URL("..", import.meta.url));
|
|
14
|
+
|
|
15
|
+
export interface BuiltinWorkflowDefinition {
|
|
16
|
+
readonly module: WorkflowModule;
|
|
17
|
+
readonly filename: string;
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly root: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const BUILTIN_WORKFLOW_DEFINITIONS: readonly BuiltinWorkflowDefinition[] = [
|
|
23
|
+
defineBuiltinWorkflow(codeReview, "code-review.ts"),
|
|
24
|
+
defineBuiltinWorkflow(refactorScout, "refactor-scout.ts"),
|
|
25
|
+
defineBuiltinWorkflow(diagnose, "diagnose.ts"),
|
|
26
|
+
defineBuiltinWorkflow(perfReview, "perf-review.ts"),
|
|
27
|
+
defineBuiltinWorkflow(research, "research.ts"),
|
|
28
|
+
];
|
|
29
|
+
export const BUILTIN_WORKFLOWS = BUILTIN_WORKFLOW_DEFINITIONS.map(({ module }) => module);
|
|
30
|
+
export const BUILTIN_WORKFLOW_FILES = new Set(BUILTIN_WORKFLOW_DEFINITIONS.map(({ filename }) => filename));
|
|
31
|
+
export const BUILTIN_WORKFLOW_NAMES = BUILTIN_WORKFLOWS.map((mod) => mod.meta.name);
|
|
32
|
+
|
|
33
|
+
function defineBuiltinWorkflow(module: WorkflowModule, filename: string): BuiltinWorkflowDefinition {
|
|
34
|
+
return {
|
|
35
|
+
module: { meta: module.meta, default: module.default },
|
|
36
|
+
filename,
|
|
37
|
+
path: fileURLToPath(new URL(`../workflows/${filename}`, import.meta.url)),
|
|
38
|
+
root: BUILTIN_SOURCE_ROOT,
|
|
39
|
+
};
|
|
40
|
+
}
|