@chllming/wave-orchestration 0.5.2 → 0.5.4
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/CHANGELOG.md +15 -0
- package/README.md +56 -501
- package/docs/README.md +39 -0
- package/docs/concepts/context7-vs-skills.md +94 -0
- package/docs/concepts/operating-modes.md +91 -0
- package/docs/concepts/runtime-agnostic-orchestration.md +95 -0
- package/docs/concepts/what-is-a-wave.md +133 -0
- package/docs/guides/planner.md +113 -0
- package/docs/guides/terminal-surfaces.md +80 -0
- package/docs/image.png +0 -0
- package/docs/plans/context7-wave-orchestrator.md +2 -0
- package/docs/plans/current-state.md +10 -0
- package/docs/plans/master-plan.md +3 -3
- package/docs/plans/migration.md +4 -3
- package/docs/plans/wave-orchestrator.md +27 -3
- package/docs/reference/runtime-config/README.md +19 -0
- package/docs/reference/skills.md +156 -0
- package/docs/roadmap.md +160 -564
- package/package.json +2 -1
- package/releases/manifest.json +32 -0
- package/scripts/wave-orchestrator/config.mjs +17 -0
- package/scripts/wave-orchestrator/context7.mjs +9 -0
- package/scripts/wave-orchestrator/coordination.mjs +16 -0
- package/scripts/wave-orchestrator/executors.mjs +24 -11
- package/scripts/wave-orchestrator/install.mjs +41 -2
- package/scripts/wave-orchestrator/launcher.mjs +131 -25
- package/scripts/wave-orchestrator/planner.mjs +1328 -0
- package/scripts/wave-orchestrator/project-profile.mjs +190 -0
- package/scripts/wave-orchestrator/shared.mjs +2 -0
- package/scripts/wave-orchestrator/skills.mjs +448 -0
- package/scripts/wave-orchestrator/terminals.mjs +16 -0
- package/scripts/wave-orchestrator/traces.mjs +23 -0
- package/scripts/wave-orchestrator/wave-files.mjs +299 -84
- package/scripts/wave.mjs +11 -0
- package/skills/provider-aws/SKILL.md +6 -0
- package/skills/provider-aws/skill.json +5 -0
- package/skills/provider-custom-deploy/SKILL.md +5 -0
- package/skills/provider-custom-deploy/skill.json +5 -0
- package/skills/provider-docker-compose/SKILL.md +6 -0
- package/skills/provider-docker-compose/skill.json +5 -0
- package/skills/provider-github-release/SKILL.md +6 -0
- package/skills/provider-github-release/skill.json +5 -0
- package/skills/provider-kubernetes/SKILL.md +6 -0
- package/skills/provider-kubernetes/skill.json +5 -0
- package/skills/provider-railway/SKILL.md +6 -0
- package/skills/provider-railway/adapters/claude.md +1 -0
- package/skills/provider-railway/adapters/codex.md +1 -0
- package/skills/provider-railway/adapters/local.md +1 -0
- package/skills/provider-railway/adapters/opencode.md +1 -0
- package/skills/provider-railway/skill.json +5 -0
- package/skills/provider-ssh-manual/SKILL.md +6 -0
- package/skills/provider-ssh-manual/skill.json +5 -0
- package/skills/repo-coding-rules/SKILL.md +7 -0
- package/skills/repo-coding-rules/skill.json +5 -0
- package/skills/role-deploy/SKILL.md +6 -0
- package/skills/role-deploy/skill.json +5 -0
- package/skills/role-documentation/SKILL.md +6 -0
- package/skills/role-documentation/skill.json +5 -0
- package/skills/role-evaluator/SKILL.md +6 -0
- package/skills/role-evaluator/skill.json +5 -0
- package/skills/role-implementation/SKILL.md +6 -0
- package/skills/role-implementation/skill.json +5 -0
- package/skills/role-infra/SKILL.md +6 -0
- package/skills/role-infra/skill.json +5 -0
- package/skills/role-integration/SKILL.md +6 -0
- package/skills/role-integration/skill.json +5 -0
- package/skills/role-research/SKILL.md +6 -0
- package/skills/role-research/skill.json +5 -0
- package/skills/runtime-claude/SKILL.md +6 -0
- package/skills/runtime-claude/skill.json +5 -0
- package/skills/runtime-codex/SKILL.md +6 -0
- package/skills/runtime-codex/skill.json +5 -0
- package/skills/runtime-local/SKILL.md +5 -0
- package/skills/runtime-local/skill.json +5 -0
- package/skills/runtime-opencode/SKILL.md +6 -0
- package/skills/runtime-opencode/skill.json +5 -0
- package/skills/wave-core/SKILL.md +7 -0
- package/skills/wave-core/skill.json +5 -0
- package/wave.config.json +27 -0
|
@@ -87,9 +87,12 @@ import {
|
|
|
87
87
|
createGlobalDashboardTerminalEntry,
|
|
88
88
|
createTemporaryTerminalEntries,
|
|
89
89
|
killTmuxSessionIfExists,
|
|
90
|
+
normalizeTerminalSurface,
|
|
90
91
|
pruneOrphanLaneTemporaryTerminalEntries,
|
|
91
92
|
removeLaneTemporaryTerminalEntries,
|
|
92
93
|
removeTerminalEntries,
|
|
94
|
+
terminalSurfaceUsesTerminalRegistry,
|
|
95
|
+
TERMINAL_SURFACES,
|
|
93
96
|
} from "./terminals.mjs";
|
|
94
97
|
import {
|
|
95
98
|
buildCodexExecInvocation,
|
|
@@ -124,6 +127,12 @@ import { buildDocsQueue, readDocsQueue, writeDocsQueue } from "./docs-queue.mjs"
|
|
|
124
127
|
import { deriveWaveLedger, readWaveLedger, writeWaveLedger } from "./ledger.mjs";
|
|
125
128
|
import { buildQualityMetrics, writeTraceBundle } from "./traces.mjs";
|
|
126
129
|
import { triageClarificationRequests } from "./clarification-triage.mjs";
|
|
130
|
+
import { readProjectProfile, resolveDefaultTerminalSurface } from "./project-profile.mjs";
|
|
131
|
+
import {
|
|
132
|
+
resolveAgentSkills,
|
|
133
|
+
summarizeResolvedSkills,
|
|
134
|
+
writeResolvedSkillArtifacts,
|
|
135
|
+
} from "./skills.mjs";
|
|
127
136
|
import {
|
|
128
137
|
buildDependencySnapshot,
|
|
129
138
|
buildRequestAssignments,
|
|
@@ -133,7 +142,22 @@ import {
|
|
|
133
142
|
} from "./routing-state.mjs";
|
|
134
143
|
export { CODEX_SANDBOX_MODES, DEFAULT_CODEX_SANDBOX_MODE, normalizeCodexSandboxMode, buildCodexExecInvocation };
|
|
135
144
|
|
|
136
|
-
function
|
|
145
|
+
export function formatReconcileBlockedWaveLine(blockedWave) {
|
|
146
|
+
const parts = Array.isArray(blockedWave?.reasons)
|
|
147
|
+
? blockedWave.reasons
|
|
148
|
+
.map((reason) => {
|
|
149
|
+
const code = compactSingleLine(reason?.code || "", 80);
|
|
150
|
+
const detail = compactSingleLine(reason?.detail || "", 240);
|
|
151
|
+
return code && detail ? `${code}=${detail}` : "";
|
|
152
|
+
})
|
|
153
|
+
.filter(Boolean)
|
|
154
|
+
: [];
|
|
155
|
+
return `[reconcile] wave ${blockedWave?.wave ?? "unknown"} not reconstructable: ${
|
|
156
|
+
parts.join("; ") || "unknown reason"
|
|
157
|
+
}`;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function printUsage(lanePaths, terminalSurface) {
|
|
137
161
|
console.log(`Usage: pnpm exec wave launch [options]
|
|
138
162
|
|
|
139
163
|
Options:
|
|
@@ -158,6 +182,8 @@ Options:
|
|
|
158
182
|
--codex-sandbox <mode> Codex sandbox mode: ${CODEX_SANDBOX_MODES.join(" | ")} (default: ${DEFAULT_CODEX_SANDBOX_MODE})
|
|
159
183
|
--manifest-out <path> Write parsed wave manifest JSON (default: ${path.relative(REPO_ROOT, lanePaths.defaultManifestPath)})
|
|
160
184
|
--dry-run Parse waves and update manifest only
|
|
185
|
+
--terminal-surface <mode>
|
|
186
|
+
Terminal surface: ${TERMINAL_SURFACES.join(" | ")} (default: ${terminalSurface})
|
|
161
187
|
--no-dashboard Disable per-wave tmux dashboard session
|
|
162
188
|
--cleanup-sessions Kill lane tmux sessions after each wave (default: on)
|
|
163
189
|
--keep-sessions Keep lane tmux sessions after each wave
|
|
@@ -176,6 +202,7 @@ Options:
|
|
|
176
202
|
|
|
177
203
|
function parseArgs(argv) {
|
|
178
204
|
let lanePaths = buildLanePaths(DEFAULT_WAVE_LANE);
|
|
205
|
+
const projectProfile = readProjectProfile();
|
|
179
206
|
const options = {
|
|
180
207
|
lane: DEFAULT_WAVE_LANE,
|
|
181
208
|
startWave: 0,
|
|
@@ -193,6 +220,7 @@ function parseArgs(argv) {
|
|
|
193
220
|
codexSandboxMode: DEFAULT_CODEX_SANDBOX_MODE,
|
|
194
221
|
manifestOut: lanePaths.defaultManifestPath,
|
|
195
222
|
dryRun: false,
|
|
223
|
+
terminalSurface: resolveDefaultTerminalSurface(projectProfile),
|
|
196
224
|
dashboard: true,
|
|
197
225
|
cleanupSessions: true,
|
|
198
226
|
keepTerminals: false,
|
|
@@ -216,6 +244,8 @@ function parseArgs(argv) {
|
|
|
216
244
|
}
|
|
217
245
|
if (arg === "--dry-run") {
|
|
218
246
|
options.dryRun = true;
|
|
247
|
+
} else if (arg === "--terminal-surface") {
|
|
248
|
+
options.terminalSurface = normalizeTerminalSurface(argv[++i], "--terminal-surface");
|
|
219
249
|
} else if (arg === "--no-dashboard") {
|
|
220
250
|
options.dashboard = false;
|
|
221
251
|
} else if (arg === "--cleanup-sessions") {
|
|
@@ -305,6 +335,9 @@ function parseArgs(argv) {
|
|
|
305
335
|
if (!options.autoNext && options.endWave !== null && options.endWave < options.startWave) {
|
|
306
336
|
throw new Error("--end-wave must be >= --start-wave");
|
|
307
337
|
}
|
|
338
|
+
if (!options.dryRun && options.terminalSurface === "none") {
|
|
339
|
+
throw new Error("--terminal-surface none is only supported with --dry-run");
|
|
340
|
+
}
|
|
308
341
|
return { help: false, lanePaths, options };
|
|
309
342
|
}
|
|
310
343
|
|
|
@@ -1336,6 +1369,7 @@ export async function runClosureSweepPhase({
|
|
|
1336
1369
|
flushDashboards();
|
|
1337
1370
|
const launchResult = await launchAgentSessionFn(lanePaths, {
|
|
1338
1371
|
wave: wave.wave,
|
|
1372
|
+
waveDefinition: wave,
|
|
1339
1373
|
agent: runInfo.agent,
|
|
1340
1374
|
sessionName: runInfo.sessionName,
|
|
1341
1375
|
promptPath: runInfo.promptPath,
|
|
@@ -1359,6 +1393,7 @@ export async function runClosureSweepPhase({
|
|
|
1359
1393
|
runInfo.lastPromptHash = launchResult?.promptHash || null;
|
|
1360
1394
|
runInfo.lastContext7 = launchResult?.context7 || null;
|
|
1361
1395
|
runInfo.lastExecutorId = launchResult?.executorId || runInfo.agent.executorResolved?.id || null;
|
|
1396
|
+
runInfo.lastSkillProjection = launchResult?.skills || summarizeResolvedSkills(runInfo.agent.skillsResolved);
|
|
1362
1397
|
setWaveDashboardAgent(dashboardState, runInfo.agent.agentId, {
|
|
1363
1398
|
state: "running",
|
|
1364
1399
|
detail: `Closure sweep launched${launchResult?.context7?.mode ? ` (${launchResult.context7.mode})` : ""}`,
|
|
@@ -1573,7 +1608,7 @@ function removeOrphanWaveDashboards(lanePaths, activeSessionNames) {
|
|
|
1573
1608
|
return removedDashboardPaths;
|
|
1574
1609
|
}
|
|
1575
1610
|
|
|
1576
|
-
export function reconcileStaleLauncherArtifacts(lanePaths) {
|
|
1611
|
+
export function reconcileStaleLauncherArtifacts(lanePaths, options = {}) {
|
|
1577
1612
|
const outcome = {
|
|
1578
1613
|
removedLock: false,
|
|
1579
1614
|
removedSessions: [],
|
|
@@ -1597,12 +1632,14 @@ export function reconcileStaleLauncherArtifacts(lanePaths) {
|
|
|
1597
1632
|
|
|
1598
1633
|
outcome.removedSessions = cleanupLaneTmuxSessions(lanePaths);
|
|
1599
1634
|
const activeSessionNames = new Set(listLaneTmuxSessionNames(lanePaths));
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1635
|
+
if (terminalSurfaceUsesTerminalRegistry(options.terminalSurface || "vscode")) {
|
|
1636
|
+
const terminalCleanup = pruneOrphanLaneTemporaryTerminalEntries(
|
|
1637
|
+
lanePaths.terminalsPath,
|
|
1638
|
+
lanePaths,
|
|
1639
|
+
activeSessionNames,
|
|
1640
|
+
);
|
|
1641
|
+
outcome.removedTerminalNames = terminalCleanup.removedNames;
|
|
1642
|
+
}
|
|
1606
1643
|
|
|
1607
1644
|
const globalDashboard = readJsonOrNull(lanePaths.globalDashboardPath);
|
|
1608
1645
|
if (globalDashboard && typeof globalDashboard === "object" && Array.isArray(globalDashboard.waves)) {
|
|
@@ -1740,9 +1777,19 @@ function launchWaveDashboardSession(lanePaths, { sessionName, dashboardPath, mes
|
|
|
1740
1777
|
);
|
|
1741
1778
|
}
|
|
1742
1779
|
|
|
1780
|
+
function refreshResolvedSkillsForRun(runInfo, waveDefinition, lanePaths) {
|
|
1781
|
+
runInfo.agent.skillsResolved = resolveAgentSkills(
|
|
1782
|
+
runInfo.agent,
|
|
1783
|
+
waveDefinition || { deployEnvironments: [] },
|
|
1784
|
+
{ laneProfile: lanePaths.laneProfile },
|
|
1785
|
+
);
|
|
1786
|
+
return runInfo.agent.skillsResolved;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1743
1789
|
async function launchAgentSession(lanePaths, params) {
|
|
1744
1790
|
const {
|
|
1745
1791
|
wave,
|
|
1792
|
+
waveDefinition = null,
|
|
1746
1793
|
agent,
|
|
1747
1794
|
sessionName,
|
|
1748
1795
|
promptPath,
|
|
@@ -1770,6 +1817,20 @@ async function launchAgentSession(lanePaths, params) {
|
|
|
1770
1817
|
cacheDir: lanePaths.context7CacheDir,
|
|
1771
1818
|
disabled: !context7Enabled,
|
|
1772
1819
|
});
|
|
1820
|
+
const overlayDir = path.join(lanePaths.executorOverlaysDir, `wave-${wave}`, agent.slug);
|
|
1821
|
+
ensureDirectory(overlayDir);
|
|
1822
|
+
const skillsResolved =
|
|
1823
|
+
agent.skillsResolved || resolveAgentSkills(agent, waveDefinition || { deployEnvironments: [] }, {
|
|
1824
|
+
laneProfile: lanePaths.laneProfile,
|
|
1825
|
+
});
|
|
1826
|
+
agent.skillsResolved = skillsResolved;
|
|
1827
|
+
const skillArtifacts = writeResolvedSkillArtifacts(overlayDir, skillsResolved);
|
|
1828
|
+
if (skillArtifacts) {
|
|
1829
|
+
agent.skillsResolved = {
|
|
1830
|
+
...skillsResolved,
|
|
1831
|
+
artifacts: skillArtifacts,
|
|
1832
|
+
};
|
|
1833
|
+
}
|
|
1773
1834
|
const prompt = buildExecutionPrompt({
|
|
1774
1835
|
lane: lanePaths.lane,
|
|
1775
1836
|
wave,
|
|
@@ -1790,12 +1851,12 @@ async function launchAgentSession(lanePaths, params) {
|
|
|
1790
1851
|
});
|
|
1791
1852
|
const promptHash = hashAgentPromptFingerprint(agent);
|
|
1792
1853
|
fs.writeFileSync(promptPath, `${prompt}\n`, "utf8");
|
|
1793
|
-
const overlayDir = path.join(lanePaths.executorOverlaysDir, `wave-${wave}`, agent.slug);
|
|
1794
1854
|
const launchSpec = buildExecutorLaunchSpec({
|
|
1795
1855
|
agent,
|
|
1796
1856
|
promptPath,
|
|
1797
1857
|
logPath,
|
|
1798
1858
|
overlayDir,
|
|
1859
|
+
skillProjection: agent.skillsResolved,
|
|
1799
1860
|
});
|
|
1800
1861
|
const resolvedExecutorMode = launchSpec.executorId || agent.executorResolved?.id || "codex";
|
|
1801
1862
|
if (dryRun) {
|
|
@@ -1805,8 +1866,16 @@ async function launchAgentSession(lanePaths, params) {
|
|
|
1805
1866
|
env: launchSpec.env || {},
|
|
1806
1867
|
useRateLimitRetries: launchSpec.useRateLimitRetries === true,
|
|
1807
1868
|
invocationLines: launchSpec.invocationLines,
|
|
1869
|
+
skills: summarizeResolvedSkills(agent.skillsResolved),
|
|
1808
1870
|
});
|
|
1809
|
-
return {
|
|
1871
|
+
return {
|
|
1872
|
+
promptHash,
|
|
1873
|
+
context7,
|
|
1874
|
+
executorId: resolvedExecutorMode,
|
|
1875
|
+
launchSpec,
|
|
1876
|
+
dryRun: true,
|
|
1877
|
+
skills: summarizeResolvedSkills(agent.skillsResolved),
|
|
1878
|
+
};
|
|
1810
1879
|
}
|
|
1811
1880
|
killTmuxSessionIfExists(lanePaths.tmuxSocketName, sessionName);
|
|
1812
1881
|
|
|
@@ -1881,7 +1950,12 @@ async function launchAgentSession(lanePaths, params) {
|
|
|
1881
1950
|
["new-session", "-d", "-s", sessionName, `bash -lc ${shellQuote(command)}`],
|
|
1882
1951
|
`launch session ${sessionName}`,
|
|
1883
1952
|
);
|
|
1884
|
-
return {
|
|
1953
|
+
return {
|
|
1954
|
+
promptHash,
|
|
1955
|
+
context7,
|
|
1956
|
+
executorId: resolvedExecutorMode,
|
|
1957
|
+
skills: summarizeResolvedSkills(agent.skillsResolved),
|
|
1958
|
+
};
|
|
1885
1959
|
}
|
|
1886
1960
|
|
|
1887
1961
|
async function waitForWaveCompletion(lanePaths, agentRuns, timeoutMinutes, onProgress = null) {
|
|
@@ -2133,6 +2207,13 @@ function isClosureAgentId(agentId, lanePaths) {
|
|
|
2133
2207
|
].includes(agentId);
|
|
2134
2208
|
}
|
|
2135
2209
|
|
|
2210
|
+
export function selectInitialWaveRuns(agentRuns, lanePaths) {
|
|
2211
|
+
const implementationRuns = (agentRuns || []).filter(
|
|
2212
|
+
(run) => !isClosureAgentId(run?.agent?.agentId, lanePaths),
|
|
2213
|
+
);
|
|
2214
|
+
return implementationRuns.length > 0 ? implementationRuns : agentRuns;
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2136
2217
|
function isLauncherSeedRequest(record) {
|
|
2137
2218
|
return (
|
|
2138
2219
|
record?.source === "launcher" &&
|
|
@@ -2191,7 +2272,7 @@ function buildFallbackExecutorState(executorState, executorId, attempt, reason)
|
|
|
2191
2272
|
};
|
|
2192
2273
|
}
|
|
2193
2274
|
|
|
2194
|
-
function applyRetryFallbacks(agentRuns, failures, lanePaths, attemptNumber) {
|
|
2275
|
+
function applyRetryFallbacks(agentRuns, failures, lanePaths, attemptNumber, waveDefinition = null) {
|
|
2195
2276
|
const failedAgentIds = new Set(failures.map((failure) => failure.agentId));
|
|
2196
2277
|
let changed = false;
|
|
2197
2278
|
const outcomes = new Map();
|
|
@@ -2257,6 +2338,7 @@ function applyRetryFallbacks(agentRuns, failures, lanePaths, attemptNumber) {
|
|
|
2257
2338
|
continue;
|
|
2258
2339
|
}
|
|
2259
2340
|
run.agent.executorResolved = nextState;
|
|
2341
|
+
refreshResolvedSkillsForRun(run, waveDefinition, lanePaths);
|
|
2260
2342
|
changed = true;
|
|
2261
2343
|
outcomes.set(run.agent.agentId, {
|
|
2262
2344
|
applied: true,
|
|
@@ -2478,7 +2560,7 @@ export function buildGateSnapshot({
|
|
|
2478
2560
|
};
|
|
2479
2561
|
}
|
|
2480
2562
|
|
|
2481
|
-
export function resolveRelaunchRuns(agentRuns, failures, derivedState, lanePaths) {
|
|
2563
|
+
export function resolveRelaunchRuns(agentRuns, failures, derivedState, lanePaths, waveDefinition = null) {
|
|
2482
2564
|
const runsByAgentId = new Map(agentRuns.map((run) => [run.agent.agentId, run]));
|
|
2483
2565
|
const pendingFeedback = (derivedState?.coordinationState?.humanFeedback || []).filter((record) =>
|
|
2484
2566
|
isOpenCoordinationStatus(record.status),
|
|
@@ -2495,6 +2577,7 @@ export function resolveRelaunchRuns(agentRuns, failures, derivedState, lanePaths
|
|
|
2495
2577
|
failures,
|
|
2496
2578
|
lanePaths,
|
|
2497
2579
|
nextAttemptNumber,
|
|
2580
|
+
waveDefinition,
|
|
2498
2581
|
);
|
|
2499
2582
|
const retryBarrier = retryBarrierFromOutcomes(fallbackResolution.outcomes, failures);
|
|
2500
2583
|
if (retryBarrier) {
|
|
@@ -2664,7 +2747,7 @@ function preflightWavesForExecutorAvailability(waves, lanePaths) {
|
|
|
2664
2747
|
export async function runLauncherCli(argv) {
|
|
2665
2748
|
const parsed = parseArgs(argv);
|
|
2666
2749
|
if (parsed.help) {
|
|
2667
|
-
printUsage(parsed.lanePaths);
|
|
2750
|
+
printUsage(parsed.lanePaths, parsed.options.terminalSurface);
|
|
2668
2751
|
return;
|
|
2669
2752
|
}
|
|
2670
2753
|
const { lanePaths, options } = parsed;
|
|
@@ -2736,7 +2819,9 @@ export async function runLauncherCli(argv) {
|
|
|
2736
2819
|
}
|
|
2737
2820
|
|
|
2738
2821
|
try {
|
|
2739
|
-
const staleArtifactCleanup = reconcileStaleLauncherArtifacts(lanePaths
|
|
2822
|
+
const staleArtifactCleanup = reconcileStaleLauncherArtifacts(lanePaths, {
|
|
2823
|
+
terminalSurface: options.terminalSurface,
|
|
2824
|
+
});
|
|
2740
2825
|
const context7BundleIndex = loadContext7BundleIndex(lanePaths.context7BundleIndexPath);
|
|
2741
2826
|
const allWaves = parseWaveFiles(lanePaths.wavesDir, { laneProfile: lanePaths.laneProfile })
|
|
2742
2827
|
.map((wave) =>
|
|
@@ -2813,6 +2898,9 @@ export async function runLauncherCli(argv) {
|
|
|
2813
2898
|
? reconciliation.state.completedWaves.join(", ")
|
|
2814
2899
|
: "none";
|
|
2815
2900
|
console.log(`[reconcile] added from status files: ${addedSummary}`);
|
|
2901
|
+
for (const blockedWave of reconciliation.blockedFromStatus || []) {
|
|
2902
|
+
console.log(formatReconcileBlockedWaveLine(blockedWave));
|
|
2903
|
+
}
|
|
2816
2904
|
console.log(`[reconcile] completed waves now: ${completedSummary}`);
|
|
2817
2905
|
return;
|
|
2818
2906
|
}
|
|
@@ -2889,6 +2977,7 @@ export async function runLauncherCli(argv) {
|
|
|
2889
2977
|
for (const runInfo of agentRuns) {
|
|
2890
2978
|
await launchAgentSession(lanePaths, {
|
|
2891
2979
|
wave: wave.wave,
|
|
2980
|
+
waveDefinition: wave,
|
|
2892
2981
|
agent: runInfo.agent,
|
|
2893
2982
|
sessionName: runInfo.sessionName,
|
|
2894
2983
|
promptPath: runInfo.promptPath,
|
|
@@ -2918,6 +3007,9 @@ export async function runLauncherCli(argv) {
|
|
|
2918
3007
|
}
|
|
2919
3008
|
|
|
2920
3009
|
preflightWavesForExecutorAvailability(filteredWaves, lanePaths);
|
|
3010
|
+
const terminalRegistryEnabled = terminalSurfaceUsesTerminalRegistry(
|
|
3011
|
+
options.terminalSurface,
|
|
3012
|
+
);
|
|
2921
3013
|
|
|
2922
3014
|
globalDashboard = buildGlobalDashboardState({
|
|
2923
3015
|
lane: lanePaths.lane,
|
|
@@ -2929,7 +3021,7 @@ export async function runLauncherCli(argv) {
|
|
|
2929
3021
|
});
|
|
2930
3022
|
writeGlobalDashboard(lanePaths.globalDashboardPath, globalDashboard);
|
|
2931
3023
|
|
|
2932
|
-
if (!options.keepTerminals) {
|
|
3024
|
+
if (terminalRegistryEnabled && !options.keepTerminals) {
|
|
2933
3025
|
const removed = removeLaneTemporaryTerminalEntries(lanePaths.terminalsPath, lanePaths);
|
|
2934
3026
|
if (removed > 0) {
|
|
2935
3027
|
recordGlobalDashboardEvent(globalDashboard, {
|
|
@@ -2953,8 +3045,10 @@ export async function runLauncherCli(argv) {
|
|
|
2953
3045
|
lanePaths,
|
|
2954
3046
|
globalDashboard.runId || "global",
|
|
2955
3047
|
);
|
|
2956
|
-
|
|
2957
|
-
|
|
3048
|
+
if (terminalRegistryEnabled) {
|
|
3049
|
+
appendTerminalEntries(lanePaths.terminalsPath, [globalDashboardTerminalEntry]);
|
|
3050
|
+
globalDashboardTerminalAppended = true;
|
|
3051
|
+
}
|
|
2958
3052
|
launchWaveDashboardSession(lanePaths, {
|
|
2959
3053
|
sessionName: globalDashboardTerminalEntry.sessionName,
|
|
2960
3054
|
dashboardPath: lanePaths.globalDashboardPath,
|
|
@@ -3033,8 +3127,10 @@ export async function runLauncherCli(argv) {
|
|
|
3033
3127
|
runTag,
|
|
3034
3128
|
options.dashboard,
|
|
3035
3129
|
);
|
|
3036
|
-
|
|
3037
|
-
|
|
3130
|
+
if (terminalRegistryEnabled) {
|
|
3131
|
+
appendTerminalEntries(lanePaths.terminalsPath, terminalEntries);
|
|
3132
|
+
terminalsAppended = true;
|
|
3133
|
+
}
|
|
3038
3134
|
|
|
3039
3135
|
const agentRuns = wave.agents.map((agent) => {
|
|
3040
3136
|
const safeName = `wave-${wave.wave}-${agent.slug}`;
|
|
@@ -3149,7 +3245,10 @@ export async function runLauncherCli(argv) {
|
|
|
3149
3245
|
});
|
|
3150
3246
|
}
|
|
3151
3247
|
|
|
3152
|
-
let runsToLaunch =
|
|
3248
|
+
let runsToLaunch = selectInitialWaveRuns(
|
|
3249
|
+
agentRuns.filter((run) => !preCompletedAgentIds.has(run.agent.agentId)),
|
|
3250
|
+
lanePaths,
|
|
3251
|
+
);
|
|
3153
3252
|
let attempt = 1;
|
|
3154
3253
|
const feedbackStateByRequestId = new Map();
|
|
3155
3254
|
|
|
@@ -3219,6 +3318,7 @@ export async function runLauncherCli(argv) {
|
|
|
3219
3318
|
flushDashboards();
|
|
3220
3319
|
const launchResult = await launchAgentSession(lanePaths, {
|
|
3221
3320
|
wave: wave.wave,
|
|
3321
|
+
waveDefinition: wave,
|
|
3222
3322
|
agent: runInfo.agent,
|
|
3223
3323
|
sessionName: runInfo.sessionName,
|
|
3224
3324
|
promptPath: runInfo.promptPath,
|
|
@@ -3242,6 +3342,8 @@ export async function runLauncherCli(argv) {
|
|
|
3242
3342
|
runInfo.lastPromptHash = launchResult?.promptHash || null;
|
|
3243
3343
|
runInfo.lastContext7 = launchResult?.context7 || null;
|
|
3244
3344
|
runInfo.lastExecutorId = launchResult?.executorId || runInfo.agent.executorResolved?.id || null;
|
|
3345
|
+
runInfo.lastSkillProjection =
|
|
3346
|
+
launchResult?.skills || summarizeResolvedSkills(runInfo.agent.skillsResolved);
|
|
3245
3347
|
setWaveDashboardAgent(dashboardState, runInfo.agent.agentId, {
|
|
3246
3348
|
state: "running",
|
|
3247
3349
|
detail: "Session launched",
|
|
@@ -3271,16 +3373,19 @@ export async function runLauncherCli(argv) {
|
|
|
3271
3373
|
|
|
3272
3374
|
const waitResult = await waitForWaveCompletion(
|
|
3273
3375
|
lanePaths,
|
|
3274
|
-
|
|
3376
|
+
runsToLaunch,
|
|
3275
3377
|
options.timeoutMinutes,
|
|
3276
3378
|
({ pendingAgentIds }) => {
|
|
3277
|
-
refreshWaveDashboardAgentStates(
|
|
3278
|
-
|
|
3379
|
+
refreshWaveDashboardAgentStates(
|
|
3380
|
+
dashboardState,
|
|
3381
|
+
runsToLaunch,
|
|
3382
|
+
pendingAgentIds,
|
|
3383
|
+
(event) => recordCombinedEvent(event),
|
|
3279
3384
|
);
|
|
3280
3385
|
monitorWaveHumanFeedback({
|
|
3281
3386
|
lanePaths,
|
|
3282
3387
|
waveNumber: wave.wave,
|
|
3283
|
-
agentRuns,
|
|
3388
|
+
agentRuns: runsToLaunch,
|
|
3284
3389
|
orchestratorId: options.orchestratorId,
|
|
3285
3390
|
coordinationLogPath: derivedState.coordinationLogPath,
|
|
3286
3391
|
feedbackStateByRequestId,
|
|
@@ -3767,6 +3872,7 @@ export async function runLauncherCli(argv) {
|
|
|
3767
3872
|
failures,
|
|
3768
3873
|
derivedState,
|
|
3769
3874
|
lanePaths,
|
|
3875
|
+
wave,
|
|
3770
3876
|
);
|
|
3771
3877
|
if (relaunchResolution.barrier) {
|
|
3772
3878
|
for (const failure of relaunchResolution.barrier.failures) {
|