slavedriver 0.1.0
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 +165 -0
- package/agents/executor.md +26 -0
- package/agents/planner.md +41 -0
- package/agents/researcher.md +28 -0
- package/agents/verifier.md +25 -0
- package/dist/agents/backends/claude-code.d.ts +2 -0
- package/dist/agents/backends/claude-code.js +215 -0
- package/dist/agents/backends/claude-code.js.map +1 -0
- package/dist/agents/backends/mock.d.ts +9 -0
- package/dist/agents/backends/mock.js +31 -0
- package/dist/agents/backends/mock.js.map +1 -0
- package/dist/agents/context-builder.d.ts +10 -0
- package/dist/agents/context-builder.js +61 -0
- package/dist/agents/context-builder.js.map +1 -0
- package/dist/agents/prompt-compiler.d.ts +27 -0
- package/dist/agents/prompt-compiler.js +549 -0
- package/dist/agents/prompt-compiler.js.map +1 -0
- package/dist/agents/runtime.d.ts +40 -0
- package/dist/agents/runtime.js +2 -0
- package/dist/agents/runtime.js.map +1 -0
- package/dist/cli/arg-parser.d.ts +6 -0
- package/dist/cli/arg-parser.js +59 -0
- package/dist/cli/arg-parser.js.map +1 -0
- package/dist/cli/commands/config.d.ts +9 -0
- package/dist/cli/commands/config.js +120 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +1 -0
- package/dist/cli/commands/dashboard.js +54 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/find-root.d.ts +14 -0
- package/dist/cli/commands/find-root.js +55 -0
- package/dist/cli/commands/find-root.js.map +1 -0
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.js +65 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/next.d.ts +1 -0
- package/dist/cli/commands/next.js +61 -0
- package/dist/cli/commands/next.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +2 -0
- package/dist/cli/commands/plan.js +53 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/replan.d.ts +1 -0
- package/dist/cli/commands/replan.js +54 -0
- package/dist/cli/commands/replan.js.map +1 -0
- package/dist/cli/commands/run-pipeline.d.ts +2 -0
- package/dist/cli/commands/run-pipeline.js +74 -0
- package/dist/cli/commands/run-pipeline.js.map +1 -0
- package/dist/cli/commands/run.d.ts +2 -0
- package/dist/cli/commands/run.js +106 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/status.d.ts +1 -0
- package/dist/cli/commands/status.js +51 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +1 -0
- package/dist/cli/commands/verify.js +63 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/commands/wizard.d.ts +8 -0
- package/dist/cli/commands/wizard.js +39 -0
- package/dist/cli/commands/wizard.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +82 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/wizard/index.d.ts +11 -0
- package/dist/cli/wizard/index.js +40 -0
- package/dist/cli/wizard/index.js.map +1 -0
- package/dist/cli/wizard/interview.d.ts +26 -0
- package/dist/cli/wizard/interview.js +284 -0
- package/dist/cli/wizard/interview.js.map +1 -0
- package/dist/cli/wizard/prompt.d.ts +18 -0
- package/dist/cli/wizard/prompt.js +72 -0
- package/dist/cli/wizard/prompt.js.map +1 -0
- package/dist/cli/wizard/template-generator.d.ts +8 -0
- package/dist/cli/wizard/template-generator.js +133 -0
- package/dist/cli/wizard/template-generator.js.map +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +68 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/protocol.d.ts +33 -0
- package/dist/mcp/protocol.js +82 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/resources.d.ts +20 -0
- package/dist/mcp/resources.js +101 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/run-manager.d.ts +36 -0
- package/dist/mcp/run-manager.js +179 -0
- package/dist/mcp/run-manager.js.map +1 -0
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +99 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +32 -0
- package/dist/mcp/tools.js +259 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/orchestrator/alert-types.d.ts +16 -0
- package/dist/orchestrator/alert-types.js +2 -0
- package/dist/orchestrator/alert-types.js.map +1 -0
- package/dist/orchestrator/alerts.d.ts +20 -0
- package/dist/orchestrator/alerts.js +76 -0
- package/dist/orchestrator/alerts.js.map +1 -0
- package/dist/orchestrator/checkpoints.d.ts +8 -0
- package/dist/orchestrator/checkpoints.js +24 -0
- package/dist/orchestrator/checkpoints.js.map +1 -0
- package/dist/orchestrator/engine.d.ts +71 -0
- package/dist/orchestrator/engine.js +420 -0
- package/dist/orchestrator/engine.js.map +1 -0
- package/dist/orchestrator/phase-gates.d.ts +6 -0
- package/dist/orchestrator/phase-gates.js +127 -0
- package/dist/orchestrator/phase-gates.js.map +1 -0
- package/dist/orchestrator/plan-approval.d.ts +10 -0
- package/dist/orchestrator/plan-approval.js +51 -0
- package/dist/orchestrator/plan-approval.js.map +1 -0
- package/dist/orchestrator/safety.d.ts +22 -0
- package/dist/orchestrator/safety.js +126 -0
- package/dist/orchestrator/safety.js.map +1 -0
- package/dist/orchestrator/task-graph.d.ts +17 -0
- package/dist/orchestrator/task-graph.js +156 -0
- package/dist/orchestrator/task-graph.js.map +1 -0
- package/dist/orchestrator/wave-executor.d.ts +37 -0
- package/dist/orchestrator/wave-executor.js +237 -0
- package/dist/orchestrator/wave-executor.js.map +1 -0
- package/dist/session/in-process.d.ts +2 -0
- package/dist/session/in-process.js +149 -0
- package/dist/session/in-process.js.map +1 -0
- package/dist/session/log-capture.d.ts +7 -0
- package/dist/session/log-capture.js +56 -0
- package/dist/session/log-capture.js.map +1 -0
- package/dist/session/manager.d.ts +20 -0
- package/dist/session/manager.js +2 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/state/file-store.d.ts +3 -0
- package/dist/state/file-store.js +124 -0
- package/dist/state/file-store.js.map +1 -0
- package/dist/state/lock.d.ts +6 -0
- package/dist/state/lock.js +71 -0
- package/dist/state/lock.js.map +1 -0
- package/dist/state/plan-parser.d.ts +6 -0
- package/dist/state/plan-parser.js +54 -0
- package/dist/state/plan-parser.js.map +1 -0
- package/dist/state/store.d.ts +27 -0
- package/dist/state/store.js +2 -0
- package/dist/state/store.js.map +1 -0
- package/dist/steps/events.d.ts +49 -0
- package/dist/steps/events.js +2 -0
- package/dist/steps/events.js.map +1 -0
- package/dist/steps/pipeline.d.ts +14 -0
- package/dist/steps/pipeline.js +284 -0
- package/dist/steps/pipeline.js.map +1 -0
- package/dist/steps/plan-parser.d.ts +35 -0
- package/dist/steps/plan-parser.js +147 -0
- package/dist/steps/plan-parser.js.map +1 -0
- package/dist/steps/runner.d.ts +13 -0
- package/dist/steps/runner.js +155 -0
- package/dist/steps/runner.js.map +1 -0
- package/dist/steps/store.d.ts +26 -0
- package/dist/steps/store.js +164 -0
- package/dist/steps/store.js.map +1 -0
- package/dist/steps/types.d.ts +36 -0
- package/dist/steps/types.js +2 -0
- package/dist/steps/types.js.map +1 -0
- package/dist/tui/app.d.ts +15 -0
- package/dist/tui/app.js +297 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/banner.d.ts +1 -0
- package/dist/tui/banner.js +11 -0
- package/dist/tui/banner.js.map +1 -0
- package/dist/tui/colors.d.ts +22 -0
- package/dist/tui/colors.js +30 -0
- package/dist/tui/colors.js.map +1 -0
- package/dist/tui/components/agent-panel.d.ts +8 -0
- package/dist/tui/components/agent-panel.js +80 -0
- package/dist/tui/components/agent-panel.js.map +1 -0
- package/dist/tui/components/header.d.ts +15 -0
- package/dist/tui/components/header.js +69 -0
- package/dist/tui/components/header.js.map +1 -0
- package/dist/tui/components/status-bar.d.ts +2 -0
- package/dist/tui/components/status-bar.js +8 -0
- package/dist/tui/components/status-bar.js.map +1 -0
- package/dist/tui/components/task-board.d.ts +3 -0
- package/dist/tui/components/task-board.js +96 -0
- package/dist/tui/components/task-board.js.map +1 -0
- package/dist/tui/display.d.ts +23 -0
- package/dist/tui/display.js +125 -0
- package/dist/tui/display.js.map +1 -0
- package/dist/tui/input.d.ts +2 -0
- package/dist/tui/input.js +44 -0
- package/dist/tui/input.js.map +1 -0
- package/dist/tui/layout-master.d.ts +7 -0
- package/dist/tui/layout-master.js +31 -0
- package/dist/tui/layout-master.js.map +1 -0
- package/dist/tui/layout.d.ts +13 -0
- package/dist/tui/layout.js +37 -0
- package/dist/tui/layout.js.map +1 -0
- package/dist/tui/pane-formatter.d.ts +27 -0
- package/dist/tui/pane-formatter.js +153 -0
- package/dist/tui/pane-formatter.js.map +1 -0
- package/dist/tui/renderer.d.ts +8 -0
- package/dist/tui/renderer.js +30 -0
- package/dist/tui/renderer.js.map +1 -0
- package/dist/tui/screen.d.ts +12 -0
- package/dist/tui/screen.js +32 -0
- package/dist/tui/screen.js.map +1 -0
- package/dist/tui/structured-display.d.ts +5 -0
- package/dist/tui/structured-display.js +74 -0
- package/dist/tui/structured-display.js.map +1 -0
- package/dist/tui/tmux-display.d.ts +6 -0
- package/dist/tui/tmux-display.js +187 -0
- package/dist/tui/tmux-display.js.map +1 -0
- package/dist/tui/tmux.d.ts +26 -0
- package/dist/tui/tmux.js +265 -0
- package/dist/tui/tmux.js.map +1 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/git.d.ts +6 -0
- package/dist/utils/git.js +35 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/hello.d.ts +1 -0
- package/dist/utils/hello.js +4 -0
- package/dist/utils/hello.js.map +1 -0
- package/dist/utils/id.d.ts +1 -0
- package/dist/utils/id.js +5 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/jsonl.d.ts +2 -0
- package/dist/utils/jsonl.js +18 -0
- package/dist/utils/jsonl.js.map +1 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.js +40 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pricing.d.ts +3 -0
- package/dist/utils/pricing.js +26 -0
- package/dist/utils/pricing.js.map +1 -0
- package/dist/utils/xml.d.ts +13 -0
- package/dist/utils/xml.js +67 -0
- package/dist/utils/xml.js.map +1 -0
- package/dist/utils/yaml.d.ts +5 -0
- package/dist/utils/yaml.js +126 -0
- package/dist/utils/yaml.js.map +1 -0
- package/package.json +45 -0
- package/templates/CONSTITUTION.md +10 -0
- package/templates/STATE.md +3 -0
- package/templates/config.json +11 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { createAlertHandler } from './alerts.js';
|
|
2
|
+
import { createTaskGraph } from './task-graph.js';
|
|
3
|
+
import { executeWave } from './wave-executor.js';
|
|
4
|
+
import { canTransition } from './phase-gates.js';
|
|
5
|
+
import { createCheckpoint } from './checkpoints.js';
|
|
6
|
+
import { parsePlan } from '../state/plan-parser.js';
|
|
7
|
+
import { generateId } from '../utils/id.js';
|
|
8
|
+
import { buildContext } from '../agents/context-builder.js';
|
|
9
|
+
import { compilePrompt, compileTaskPrompt, isValidAgentRole } from '../agents/prompt-compiler.js';
|
|
10
|
+
async function runAgent(runtime, prompt, systemPrompt, workingDirectory, options, safety) {
|
|
11
|
+
const executionId = generateId();
|
|
12
|
+
if (safety) {
|
|
13
|
+
safety.totalAgentInvocations++;
|
|
14
|
+
}
|
|
15
|
+
const stream = runtime.execute({
|
|
16
|
+
executionId,
|
|
17
|
+
prompt,
|
|
18
|
+
systemPrompt,
|
|
19
|
+
workingDirectory,
|
|
20
|
+
model: options?.model,
|
|
21
|
+
maxTurns: options?.maxTurns,
|
|
22
|
+
outputFormat: 'stream-json',
|
|
23
|
+
dangerouslySkipPermissions: true,
|
|
24
|
+
});
|
|
25
|
+
// Accumulate text from text_delta events since the result event
|
|
26
|
+
// from Claude Code CLI doesn't include the full text output
|
|
27
|
+
let textAccumulator = '';
|
|
28
|
+
let completeResult = '';
|
|
29
|
+
for await (const event of stream) {
|
|
30
|
+
if (event.type === 'text_delta') {
|
|
31
|
+
textAccumulator += event.text;
|
|
32
|
+
}
|
|
33
|
+
else if (event.type === 'complete') {
|
|
34
|
+
completeResult = event.result;
|
|
35
|
+
}
|
|
36
|
+
else if (event.type === 'error') {
|
|
37
|
+
throw new Error(event.error);
|
|
38
|
+
}
|
|
39
|
+
else if (event.type === 'cost_update' && safety) {
|
|
40
|
+
safety.totalInputTokens += event.inputTokens;
|
|
41
|
+
safety.totalOutputTokens += event.outputTokens;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Prefer the complete event's result if non-empty, otherwise use accumulated text
|
|
45
|
+
return completeResult || textAccumulator;
|
|
46
|
+
}
|
|
47
|
+
function checkAbort(signal) {
|
|
48
|
+
if (signal?.aborted) {
|
|
49
|
+
throw new Error('Run aborted');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function createEngine(params) {
|
|
53
|
+
let currentPhase = 'idle';
|
|
54
|
+
const safetyState = {
|
|
55
|
+
totalInputTokens: 0,
|
|
56
|
+
totalOutputTokens: 0,
|
|
57
|
+
totalIterations: 0,
|
|
58
|
+
totalAgentInvocations: 0,
|
|
59
|
+
activeAgents: 0,
|
|
60
|
+
startTimeMs: Date.now(),
|
|
61
|
+
};
|
|
62
|
+
function transitionTo(to, tasks) {
|
|
63
|
+
const gate = canTransition(currentPhase, to, tasks);
|
|
64
|
+
if (!gate.canTransition) {
|
|
65
|
+
throw new Error(`Cannot transition from '${currentPhase}' to '${to}': ${gate.reason}`);
|
|
66
|
+
}
|
|
67
|
+
const from = currentPhase;
|
|
68
|
+
currentPhase = to;
|
|
69
|
+
params.onEvent({ type: 'phase_changed', from, to });
|
|
70
|
+
// Persist phase change as task event
|
|
71
|
+
const phaseEvent = {
|
|
72
|
+
ts: new Date().toISOString(),
|
|
73
|
+
type: 'phase_changed',
|
|
74
|
+
phase: to,
|
|
75
|
+
};
|
|
76
|
+
params.store.appendTaskEvent(phaseEvent).catch((err) => {
|
|
77
|
+
process.stderr.write(`[engine] Failed to persist phase transition to '${to}': ${err instanceof Error ? err.message : String(err)}\n`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// Shared wave executor params builder — avoids duplicating callbacks
|
|
81
|
+
function buildWaveParams(graph, alertHandler, promptCtx) {
|
|
82
|
+
return {
|
|
83
|
+
graph,
|
|
84
|
+
runtime: params.runtime,
|
|
85
|
+
config: params.config,
|
|
86
|
+
workingDirectory: params.workingDirectory,
|
|
87
|
+
buildPrompt: async (task) => {
|
|
88
|
+
// Resolve dependency summaries
|
|
89
|
+
const deps = graph.getDependencies(task.id);
|
|
90
|
+
let dependencySummaries;
|
|
91
|
+
if (deps.length > 0) {
|
|
92
|
+
const resolved = {};
|
|
93
|
+
for (const dep of deps) {
|
|
94
|
+
const summary = await params.store.readTaskSummary(dep.id).catch(() => '');
|
|
95
|
+
if (summary) {
|
|
96
|
+
resolved[`${dep.id}: ${dep.title}`] = summary;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (Object.keys(resolved).length > 0) {
|
|
100
|
+
dependencySummaries = resolved;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Read previous wave summary
|
|
104
|
+
let waveSummary;
|
|
105
|
+
if (task.wave > 1) {
|
|
106
|
+
const ws = await params.store.readWaveSummary(task.wave - 1).catch(() => '');
|
|
107
|
+
if (ws)
|
|
108
|
+
waveSummary = ws;
|
|
109
|
+
}
|
|
110
|
+
return buildContext({
|
|
111
|
+
task,
|
|
112
|
+
store: params.store,
|
|
113
|
+
constitution: promptCtx?.constitution,
|
|
114
|
+
dependencySummaries,
|
|
115
|
+
waveSummary,
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
buildExecutionConfig: (task) => {
|
|
119
|
+
const compiled = compilePrompt(isValidAgentRole(task.agent) ? task.agent : 'executor', promptCtx);
|
|
120
|
+
return { systemPrompt: compiled.systemPrompt, model: compiled.model, maxTurns: compiled.maxTurns };
|
|
121
|
+
},
|
|
122
|
+
onTaskEvent: async (event) => {
|
|
123
|
+
params.onEvent({ type: 'task_event', event });
|
|
124
|
+
await params.store.appendTaskEvent(event);
|
|
125
|
+
},
|
|
126
|
+
onAgentEvent: (taskId, event) => {
|
|
127
|
+
params.onEvent({ type: 'agent_event', taskId, event });
|
|
128
|
+
if (event.type === 'cost_update') {
|
|
129
|
+
safetyState.totalInputTokens += event.inputTokens;
|
|
130
|
+
safetyState.totalOutputTokens += event.outputTokens;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
onAlert: async (alert) => {
|
|
134
|
+
const response = await alertHandler.handleAlert(alert);
|
|
135
|
+
params.onEvent({ type: 'alert', alert, response });
|
|
136
|
+
return response;
|
|
137
|
+
},
|
|
138
|
+
abortSignal: params.abortSignal,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async function run(goal) {
|
|
142
|
+
let graph = createTaskGraph();
|
|
143
|
+
let allTasks = [];
|
|
144
|
+
// Create checkpoint handler once for the entire run
|
|
145
|
+
const checkpoint = params.config.checkpoints
|
|
146
|
+
? createCheckpoint(params.config.checkpoints, params.onCheckpoint)
|
|
147
|
+
: undefined;
|
|
148
|
+
// Create alert handler once for the entire run
|
|
149
|
+
const alertHandler = createAlertHandler({
|
|
150
|
+
onAlert: params.onAlert,
|
|
151
|
+
alertPolicy: params.config.alertPolicy ?? 'skip',
|
|
152
|
+
enableAlerts: params.config.enableAlerts ?? true,
|
|
153
|
+
});
|
|
154
|
+
// Load project constitution and context once for the entire run
|
|
155
|
+
const constitutionContent = await safeReadStore(() => params.store.readConstitution());
|
|
156
|
+
const projectContext = await safeReadStore(() => params.store.readContext());
|
|
157
|
+
const promptContext = (constitutionContent || projectContext)
|
|
158
|
+
? { constitution: constitutionContent || undefined, projectContext: projectContext || undefined }
|
|
159
|
+
: undefined;
|
|
160
|
+
try {
|
|
161
|
+
// --- Discover phase ---
|
|
162
|
+
if (!params.skipDiscovery) {
|
|
163
|
+
checkAbort(params.abortSignal);
|
|
164
|
+
transitionTo('discover', allTasks);
|
|
165
|
+
const researcherPrompt = compileTaskPrompt('researcher', { goal });
|
|
166
|
+
const researcherCompiled = compilePrompt('researcher', promptContext);
|
|
167
|
+
const stateResult = await runAgent(params.runtime, researcherPrompt, researcherCompiled.systemPrompt, params.workingDirectory, { model: researcherCompiled.model, maxTurns: researcherCompiled.maxTurns }, safetyState);
|
|
168
|
+
await params.store.writeState(stateResult);
|
|
169
|
+
}
|
|
170
|
+
// --- Plan phase ---
|
|
171
|
+
checkAbort(params.abortSignal);
|
|
172
|
+
transitionTo('plan', allTasks);
|
|
173
|
+
const stateContent = await safeReadStore(() => params.store.readState());
|
|
174
|
+
const plannerPrompt = compileTaskPrompt('planner', { goal, state: stateContent || undefined });
|
|
175
|
+
const plannerCompiled = compilePrompt('planner', promptContext);
|
|
176
|
+
const planResult = await runAgent(params.runtime, plannerPrompt, plannerCompiled.systemPrompt, params.workingDirectory, { model: plannerCompiled.model, maxTurns: plannerCompiled.maxTurns }, safetyState);
|
|
177
|
+
await params.store.writePlan(planResult);
|
|
178
|
+
// Parse plan into task graph
|
|
179
|
+
const parsed = parsePlan(planResult);
|
|
180
|
+
graph = createTaskGraph();
|
|
181
|
+
for (const task of parsed.tasks) {
|
|
182
|
+
graph.addTask(task);
|
|
183
|
+
}
|
|
184
|
+
// Validate: warn about dangling dependencies but don't block
|
|
185
|
+
const depErrors = graph.validateDependencies();
|
|
186
|
+
if (depErrors.length > 0) {
|
|
187
|
+
process.stderr.write(`Warning: ${depErrors.length} dangling dependency reference(s) in plan:\n`);
|
|
188
|
+
for (const msg of depErrors) {
|
|
189
|
+
process.stderr.write(` - ${msg}\n`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
allTasks = graph.getAllTasks();
|
|
193
|
+
params.onEvent({ type: 'tasks_loaded', tasks: allTasks, totalWaves: graph.getWaves().length });
|
|
194
|
+
// --- Approval gate ---
|
|
195
|
+
if (params.config.requirePlanApproval) {
|
|
196
|
+
params.onEvent({ type: 'approval_required', plan: planResult });
|
|
197
|
+
if (params.onApproval) {
|
|
198
|
+
const approved = await params.onApproval(planResult);
|
|
199
|
+
if (!approved) {
|
|
200
|
+
throw new Error('Plan was rejected by user');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
throw new Error('Plan approval required but no onApproval callback provided');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// --- After-plan checkpoint ---
|
|
208
|
+
if (checkpoint?.shouldPause('plan')) {
|
|
209
|
+
const action = await checkpoint.execute('plan', `Plan created with ${allTasks.length} tasks`);
|
|
210
|
+
if (action === 'abort') {
|
|
211
|
+
throw new Error('Aborted at plan checkpoint');
|
|
212
|
+
}
|
|
213
|
+
if (action === 'modify') {
|
|
214
|
+
// Re-enter plan phase
|
|
215
|
+
transitionTo('plan', allTasks);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// --- Dry run: stop after plan ---
|
|
219
|
+
if (params.dryRun) {
|
|
220
|
+
allTasks = graph.getAllTasks();
|
|
221
|
+
params.onEvent({
|
|
222
|
+
type: 'complete',
|
|
223
|
+
totalInputTokens: safetyState.totalInputTokens,
|
|
224
|
+
totalOutputTokens: safetyState.totalOutputTokens,
|
|
225
|
+
totalAgentInvocations: safetyState.totalAgentInvocations,
|
|
226
|
+
taskCount: allTasks.length,
|
|
227
|
+
});
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
// --- Execute phase ---
|
|
231
|
+
checkAbort(params.abortSignal);
|
|
232
|
+
transitionTo('execute', allTasks);
|
|
233
|
+
const waveParams = buildWaveParams(graph, alertHandler, promptContext);
|
|
234
|
+
const waves = graph.getWaves();
|
|
235
|
+
for (let i = 0; i < waves.length; i++) {
|
|
236
|
+
checkAbort(params.abortSignal);
|
|
237
|
+
const waveTasks = waves[i];
|
|
238
|
+
const waveNumber = waveTasks.length > 0 ? waveTasks[0].wave : i;
|
|
239
|
+
if (params.targetWave !== undefined && waveNumber !== params.targetWave) {
|
|
240
|
+
// Mark tasks in skipped waves as 'skipped'
|
|
241
|
+
for (const t of waveTasks) {
|
|
242
|
+
t.status = 'skipped';
|
|
243
|
+
}
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
params.onEvent({
|
|
247
|
+
type: 'wave_started',
|
|
248
|
+
wave: waveNumber,
|
|
249
|
+
taskCount: waveTasks.length,
|
|
250
|
+
});
|
|
251
|
+
safetyState.totalIterations++;
|
|
252
|
+
const waveResult = await executeWave(waveNumber, waveParams, safetyState);
|
|
253
|
+
// Persist task summaries
|
|
254
|
+
for (const taskResult of waveResult.tasks) {
|
|
255
|
+
if (taskResult.status === 'completed' && taskResult.result) {
|
|
256
|
+
params.store.writeTaskSummary(taskResult.taskId, taskResult.result).catch((err) => {
|
|
257
|
+
process.stderr.write(`[engine] Failed to write summary for ${taskResult.taskId}: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Build and persist wave summary
|
|
262
|
+
const MAX_SUMMARY_LENGTH = 2000;
|
|
263
|
+
const waveParts = [];
|
|
264
|
+
for (const tr of waveResult.tasks) {
|
|
265
|
+
const task = graph.getTask(tr.taskId);
|
|
266
|
+
const title = task?.title ?? tr.taskId;
|
|
267
|
+
waveParts.push(`### ${tr.taskId}: ${title} [${tr.status}]`);
|
|
268
|
+
if (tr.result) {
|
|
269
|
+
waveParts.push(tr.result.length > MAX_SUMMARY_LENGTH
|
|
270
|
+
? tr.result.slice(0, MAX_SUMMARY_LENGTH) + '\n...(truncated)'
|
|
271
|
+
: tr.result);
|
|
272
|
+
}
|
|
273
|
+
if (tr.error) {
|
|
274
|
+
waveParts.push(`Error: ${tr.error}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
params.store.writeWaveSummary(waveNumber, `# Wave ${waveNumber} Summary\n\n${waveParts.join('\n\n')}`).catch((err) => {
|
|
278
|
+
process.stderr.write(`[engine] Failed to write wave ${waveNumber} summary: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
279
|
+
});
|
|
280
|
+
params.onEvent({ type: 'wave_completed', wave: waveNumber, results: waveResult });
|
|
281
|
+
// --- After-wave checkpoint ---
|
|
282
|
+
if (checkpoint?.shouldPause('wave')) {
|
|
283
|
+
const action = await checkpoint.execute('wave', `Wave ${waveNumber} completed`);
|
|
284
|
+
if (action === 'abort') {
|
|
285
|
+
throw new Error('Aborted at wave checkpoint');
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// --- After-execute checkpoint ---
|
|
290
|
+
if (checkpoint?.shouldPause('execute')) {
|
|
291
|
+
const totalTok = safetyState.totalInputTokens + safetyState.totalOutputTokens;
|
|
292
|
+
const action = await checkpoint.execute('execute', `All waves completed, ${totalTok} tokens used`);
|
|
293
|
+
if (action === 'abort') {
|
|
294
|
+
throw new Error('Aborted at execute checkpoint');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// --- Knowledge accumulation: append wave summaries to CONTEXT.md ---
|
|
298
|
+
{
|
|
299
|
+
const waveSummaries = [];
|
|
300
|
+
for (const waveGroup of waves) {
|
|
301
|
+
if (waveGroup.length > 0) {
|
|
302
|
+
const ws = await safeReadStore(() => params.store.readWaveSummary(waveGroup[0].wave));
|
|
303
|
+
if (ws)
|
|
304
|
+
waveSummaries.push(ws);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (waveSummaries.length > 0) {
|
|
308
|
+
const existing = await safeReadStore(() => params.store.readContext());
|
|
309
|
+
const timestamp = new Date().toISOString().split('T')[0];
|
|
310
|
+
const section = `\n\n## Run ${timestamp}\n\n${waveSummaries.join('\n\n---\n\n')}`;
|
|
311
|
+
params.store.writeContext(existing + section).catch((err) => {
|
|
312
|
+
process.stderr.write(`[engine] Failed to append to CONTEXT.md: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// --- Security review phase (optional) ---
|
|
317
|
+
allTasks = graph.getAllTasks();
|
|
318
|
+
if (params.config.enableSecurityReview) {
|
|
319
|
+
transitionTo('security-review', allTasks);
|
|
320
|
+
const securityPrompt = compileTaskPrompt('security', { goal });
|
|
321
|
+
const securityCompiled = compilePrompt('security', promptContext);
|
|
322
|
+
await runAgent(params.runtime, securityPrompt, securityCompiled.systemPrompt, params.workingDirectory, { model: securityCompiled.model, maxTurns: securityCompiled.maxTurns }, safetyState);
|
|
323
|
+
// --- After-security checkpoint ---
|
|
324
|
+
if (checkpoint?.shouldPause('security')) {
|
|
325
|
+
const action = await checkpoint.execute('security', 'Security review completed');
|
|
326
|
+
if (action === 'abort') {
|
|
327
|
+
throw new Error('Aborted at security checkpoint');
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// --- QA review phase (optional) ---
|
|
332
|
+
allTasks = graph.getAllTasks();
|
|
333
|
+
if (params.config.enableQAReview) {
|
|
334
|
+
transitionTo('qa-review', allTasks);
|
|
335
|
+
const qaPrompt = compileTaskPrompt('qa', { goal });
|
|
336
|
+
const qaCompiled = compilePrompt('qa', promptContext);
|
|
337
|
+
await runAgent(params.runtime, qaPrompt, qaCompiled.systemPrompt, params.workingDirectory, { model: qaCompiled.model, maxTurns: qaCompiled.maxTurns }, safetyState);
|
|
338
|
+
// --- After-QA checkpoint ---
|
|
339
|
+
if (checkpoint?.shouldPause('qa')) {
|
|
340
|
+
const action = await checkpoint.execute('qa', 'QA review completed');
|
|
341
|
+
if (action === 'abort') {
|
|
342
|
+
throw new Error('Aborted at QA checkpoint');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// --- Verify phase (with retry loop) ---
|
|
347
|
+
allTasks = graph.getAllTasks();
|
|
348
|
+
if (!params.skipVerification && params.config.requireVerification) {
|
|
349
|
+
let verificationPassed = false;
|
|
350
|
+
while (!verificationPassed && safetyState.totalIterations < params.config.maxIterations) {
|
|
351
|
+
checkAbort(params.abortSignal);
|
|
352
|
+
transitionTo('verify', allTasks);
|
|
353
|
+
const planContent = await safeReadStore(() => params.store.readPlan());
|
|
354
|
+
const verifierPrompt = compileTaskPrompt('verifier', { goal, plan: planContent || undefined });
|
|
355
|
+
const verifierCompiled = compilePrompt('verifier', promptContext);
|
|
356
|
+
const verifyResult = await runAgent(params.runtime, verifierPrompt, verifierCompiled.systemPrompt, params.workingDirectory, { model: verifierCompiled.model, maxTurns: verifierCompiled.maxTurns }, safetyState);
|
|
357
|
+
verificationPassed = /\bPASS\b/i.test(verifyResult);
|
|
358
|
+
if (!verificationPassed) {
|
|
359
|
+
// Collect failed tasks across all waves
|
|
360
|
+
const failedTasks = graph.getAllTasks().filter((t) => t.status === 'failed');
|
|
361
|
+
if (failedTasks.length === 0) {
|
|
362
|
+
// Verifier said FAIL but no tasks actually failed — nothing to retry
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
// Transition back to execute for rerun
|
|
366
|
+
allTasks = graph.getAllTasks();
|
|
367
|
+
transitionTo('execute', allTasks);
|
|
368
|
+
for (const wave of graph.getWaves()) {
|
|
369
|
+
const failedInWave = wave.filter((t) => t.status === 'failed');
|
|
370
|
+
if (failedInWave.length === 0)
|
|
371
|
+
continue;
|
|
372
|
+
const waveNumber = failedInWave[0].wave;
|
|
373
|
+
for (const t of failedInWave) {
|
|
374
|
+
t.status = 'pending';
|
|
375
|
+
}
|
|
376
|
+
safetyState.totalIterations++;
|
|
377
|
+
const rerunResult = await executeWave(waveNumber, waveParams, safetyState);
|
|
378
|
+
params.onEvent({ type: 'wave_completed', wave: waveNumber, results: rerunResult });
|
|
379
|
+
}
|
|
380
|
+
allTasks = graph.getAllTasks();
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
// --- Complete phase ---
|
|
385
|
+
allTasks = graph.getAllTasks();
|
|
386
|
+
transitionTo('complete', allTasks);
|
|
387
|
+
params.onEvent({
|
|
388
|
+
type: 'complete',
|
|
389
|
+
totalInputTokens: safetyState.totalInputTokens,
|
|
390
|
+
totalOutputTokens: safetyState.totalOutputTokens,
|
|
391
|
+
totalAgentInvocations: safetyState.totalAgentInvocations,
|
|
392
|
+
taskCount: allTasks.length,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
catch (err) {
|
|
396
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
397
|
+
params.onEvent({ type: 'error', error: errorMsg, phase: currentPhase });
|
|
398
|
+
throw err;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
run,
|
|
403
|
+
get phase() {
|
|
404
|
+
return currentPhase;
|
|
405
|
+
},
|
|
406
|
+
get safetyState() {
|
|
407
|
+
return safetyState;
|
|
408
|
+
},
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
async function safeReadStore(fn) {
|
|
412
|
+
try {
|
|
413
|
+
return await fn();
|
|
414
|
+
}
|
|
415
|
+
catch (err) {
|
|
416
|
+
process.stderr.write(`[engine] Failed to read store: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
417
|
+
return '';
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/orchestrator/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
const ALLOWED = { canTransition: true };
|
|
2
|
+
function deny(reason) {
|
|
3
|
+
return { canTransition: false, reason };
|
|
4
|
+
}
|
|
5
|
+
// Orchestration-layer roles that are NOT execution tasks
|
|
6
|
+
const ORCHESTRATION_ROLES = new Set(['researcher', 'planner', 'verifier']);
|
|
7
|
+
function isExecutionTask(task) {
|
|
8
|
+
return !ORCHESTRATION_ROLES.has(task.agent);
|
|
9
|
+
}
|
|
10
|
+
function allTasksWithAgentCompleted(tasks, agent) {
|
|
11
|
+
const matching = tasks.filter((t) => t.agent === agent);
|
|
12
|
+
return matching.every((t) => t.status === 'completed');
|
|
13
|
+
}
|
|
14
|
+
function allExecutionTasksSettled(tasks) {
|
|
15
|
+
const execTasks = tasks.filter(isExecutionTask);
|
|
16
|
+
return execTasks.every((t) => t.status === 'completed' || t.status === 'failed' || t.status === 'skipped');
|
|
17
|
+
}
|
|
18
|
+
export function canTransition(from, to, tasks) {
|
|
19
|
+
// idle -> discover: always allowed
|
|
20
|
+
if (from === 'idle' && to === 'discover') {
|
|
21
|
+
return ALLOWED;
|
|
22
|
+
}
|
|
23
|
+
// idle -> plan: allowed when discovery is skipped
|
|
24
|
+
if (from === 'idle' && to === 'plan') {
|
|
25
|
+
return ALLOWED;
|
|
26
|
+
}
|
|
27
|
+
// discover -> plan: all discover tasks must be completed (or none exist)
|
|
28
|
+
if (from === 'discover' && to === 'plan') {
|
|
29
|
+
if (!allTasksWithAgentCompleted(tasks, 'researcher')) {
|
|
30
|
+
return deny('Not all discover tasks have completed');
|
|
31
|
+
}
|
|
32
|
+
return ALLOWED;
|
|
33
|
+
}
|
|
34
|
+
// plan -> execute: all plan tasks completed, at least one execution task exists
|
|
35
|
+
if (from === 'plan' && to === 'execute') {
|
|
36
|
+
if (!allTasksWithAgentCompleted(tasks, 'planner')) {
|
|
37
|
+
return deny('Not all plan tasks have completed');
|
|
38
|
+
}
|
|
39
|
+
const executeTasks = tasks.filter(isExecutionTask);
|
|
40
|
+
if (executeTasks.length === 0) {
|
|
41
|
+
return deny('No execution tasks exist');
|
|
42
|
+
}
|
|
43
|
+
return ALLOWED;
|
|
44
|
+
}
|
|
45
|
+
// execute -> verify: all execution tasks settled
|
|
46
|
+
if (from === 'execute' && to === 'verify') {
|
|
47
|
+
if (!allExecutionTasksSettled(tasks)) {
|
|
48
|
+
return deny('Not all execution tasks have settled (some are still running or pending)');
|
|
49
|
+
}
|
|
50
|
+
return ALLOWED;
|
|
51
|
+
}
|
|
52
|
+
// execute -> security-review: all execution tasks settled
|
|
53
|
+
if (from === 'execute' && to === 'security-review') {
|
|
54
|
+
if (!allExecutionTasksSettled(tasks)) {
|
|
55
|
+
return deny('Not all execution tasks have settled (some are still running or pending)');
|
|
56
|
+
}
|
|
57
|
+
return ALLOWED;
|
|
58
|
+
}
|
|
59
|
+
// execute -> qa-review: all execution tasks settled (when security review not enabled)
|
|
60
|
+
if (from === 'execute' && to === 'qa-review') {
|
|
61
|
+
if (!allExecutionTasksSettled(tasks)) {
|
|
62
|
+
return deny('Not all execution tasks have settled (some are still running or pending)');
|
|
63
|
+
}
|
|
64
|
+
return ALLOWED;
|
|
65
|
+
}
|
|
66
|
+
// security-review -> qa-review: always allowed
|
|
67
|
+
if (from === 'security-review' && to === 'qa-review') {
|
|
68
|
+
return ALLOWED;
|
|
69
|
+
}
|
|
70
|
+
// security-review -> verify: always allowed (when QA review not enabled)
|
|
71
|
+
if (from === 'security-review' && to === 'verify') {
|
|
72
|
+
return ALLOWED;
|
|
73
|
+
}
|
|
74
|
+
// qa-review -> verify: always allowed
|
|
75
|
+
if (from === 'qa-review' && to === 'verify') {
|
|
76
|
+
return ALLOWED;
|
|
77
|
+
}
|
|
78
|
+
// security-review -> complete: allowed when verification is skipped
|
|
79
|
+
if (from === 'security-review' && to === 'complete') {
|
|
80
|
+
const failedCritical = tasks.filter((t) => t.priority === 'critical' && t.status === 'failed');
|
|
81
|
+
if (failedCritical.length > 0) {
|
|
82
|
+
return deny(`${failedCritical.length} critical task(s) failed`);
|
|
83
|
+
}
|
|
84
|
+
return ALLOWED;
|
|
85
|
+
}
|
|
86
|
+
// qa-review -> complete: allowed when verification is skipped
|
|
87
|
+
if (from === 'qa-review' && to === 'complete') {
|
|
88
|
+
const failedCritical = tasks.filter((t) => t.priority === 'critical' && t.status === 'failed');
|
|
89
|
+
if (failedCritical.length > 0) {
|
|
90
|
+
return deny(`${failedCritical.length} critical task(s) failed`);
|
|
91
|
+
}
|
|
92
|
+
return ALLOWED;
|
|
93
|
+
}
|
|
94
|
+
// verify -> complete: all verify tasks completed, no failed critical tasks
|
|
95
|
+
if (from === 'verify' && to === 'complete') {
|
|
96
|
+
const verifyTasks = tasks.filter((t) => t.agent === 'verifier');
|
|
97
|
+
if (!verifyTasks.every((t) => t.status === 'completed')) {
|
|
98
|
+
return deny('Not all verify tasks have completed');
|
|
99
|
+
}
|
|
100
|
+
const failedCritical = tasks.filter((t) => t.priority === 'critical' && t.status === 'failed');
|
|
101
|
+
if (failedCritical.length > 0) {
|
|
102
|
+
return deny(`${failedCritical.length} critical task(s) failed`);
|
|
103
|
+
}
|
|
104
|
+
return ALLOWED;
|
|
105
|
+
}
|
|
106
|
+
// execute -> complete: allowed when verification is skipped, all execution tasks must be settled
|
|
107
|
+
if (from === 'execute' && to === 'complete') {
|
|
108
|
+
if (!allExecutionTasksSettled(tasks)) {
|
|
109
|
+
return deny('Not all execution tasks have settled (some are still running or pending)');
|
|
110
|
+
}
|
|
111
|
+
const failedCritical = tasks.filter((t) => t.priority === 'critical' && t.status === 'failed');
|
|
112
|
+
if (failedCritical.length > 0) {
|
|
113
|
+
return deny(`${failedCritical.length} critical task(s) failed`);
|
|
114
|
+
}
|
|
115
|
+
return ALLOWED;
|
|
116
|
+
}
|
|
117
|
+
// execute -> plan (replan): always allowed
|
|
118
|
+
if (from === 'execute' && to === 'plan') {
|
|
119
|
+
return ALLOWED;
|
|
120
|
+
}
|
|
121
|
+
// verify -> execute (rerun): always allowed
|
|
122
|
+
if (from === 'verify' && to === 'execute') {
|
|
123
|
+
return ALLOWED;
|
|
124
|
+
}
|
|
125
|
+
return deny(`Transition from '${from}' to '${to}' is not allowed`);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=phase-gates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase-gates.js","sourceRoot":"","sources":["../../src/orchestrator/phase-gates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ApprovalResult {
|
|
2
|
+
readonly approved: boolean;
|
|
3
|
+
readonly reason?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function requestCliApproval(plan: string): Promise<ApprovalResult>;
|
|
6
|
+
export declare function createApprovalCallback(mode: 'cli' | 'tui'): (plan: string) => Promise<boolean>;
|
|
7
|
+
export interface ApprovalCallbackWithResolver {
|
|
8
|
+
(plan: string): Promise<boolean>;
|
|
9
|
+
resolve: (approved: boolean) => void;
|
|
10
|
+
}
|