@chllming/wave-orchestration 0.5.1
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 +41 -0
- package/README.md +549 -0
- package/docs/agents/wave-deploy-verifier-role.md +34 -0
- package/docs/agents/wave-documentation-role.md +30 -0
- package/docs/agents/wave-evaluator-role.md +43 -0
- package/docs/agents/wave-infra-role.md +34 -0
- package/docs/agents/wave-integration-role.md +32 -0
- package/docs/agents/wave-launcher-role.md +37 -0
- package/docs/context7/bundles.json +91 -0
- package/docs/plans/component-cutover-matrix.json +112 -0
- package/docs/plans/component-cutover-matrix.md +49 -0
- package/docs/plans/context7-wave-orchestrator.md +130 -0
- package/docs/plans/current-state.md +44 -0
- package/docs/plans/master-plan.md +16 -0
- package/docs/plans/migration.md +23 -0
- package/docs/plans/wave-orchestrator.md +254 -0
- package/docs/plans/waves/wave-0.md +165 -0
- package/docs/reference/github-packages-setup.md +52 -0
- package/docs/reference/migration-0.2-to-0.5.md +622 -0
- package/docs/reference/npmjs-trusted-publishing.md +55 -0
- package/docs/reference/repository-guidance.md +18 -0
- package/docs/reference/runtime-config/README.md +85 -0
- package/docs/reference/runtime-config/claude.md +105 -0
- package/docs/reference/runtime-config/codex.md +81 -0
- package/docs/reference/runtime-config/opencode.md +93 -0
- package/docs/research/agent-context-sources.md +57 -0
- package/docs/roadmap.md +626 -0
- package/package.json +53 -0
- package/releases/manifest.json +101 -0
- package/scripts/context7-api-check.sh +21 -0
- package/scripts/context7-export-env.sh +52 -0
- package/scripts/research/agent-context-archive.mjs +472 -0
- package/scripts/research/generate-agent-context-indexes.mjs +85 -0
- package/scripts/research/import-agent-context-archive.mjs +793 -0
- package/scripts/research/manifests/harness-and-blackboard-2026-03-21.mjs +201 -0
- package/scripts/wave-autonomous.mjs +13 -0
- package/scripts/wave-cli-bootstrap.mjs +27 -0
- package/scripts/wave-dashboard.mjs +11 -0
- package/scripts/wave-human-feedback.mjs +11 -0
- package/scripts/wave-launcher.mjs +11 -0
- package/scripts/wave-local-executor.mjs +13 -0
- package/scripts/wave-orchestrator/agent-state.mjs +416 -0
- package/scripts/wave-orchestrator/autonomous.mjs +367 -0
- package/scripts/wave-orchestrator/clarification-triage.mjs +605 -0
- package/scripts/wave-orchestrator/config.mjs +848 -0
- package/scripts/wave-orchestrator/context7.mjs +464 -0
- package/scripts/wave-orchestrator/coord-cli.mjs +286 -0
- package/scripts/wave-orchestrator/coordination-store.mjs +987 -0
- package/scripts/wave-orchestrator/coordination.mjs +768 -0
- package/scripts/wave-orchestrator/dashboard-renderer.mjs +254 -0
- package/scripts/wave-orchestrator/dashboard-state.mjs +473 -0
- package/scripts/wave-orchestrator/dep-cli.mjs +219 -0
- package/scripts/wave-orchestrator/docs-queue.mjs +75 -0
- package/scripts/wave-orchestrator/executors.mjs +385 -0
- package/scripts/wave-orchestrator/feedback.mjs +372 -0
- package/scripts/wave-orchestrator/install.mjs +540 -0
- package/scripts/wave-orchestrator/launcher.mjs +3879 -0
- package/scripts/wave-orchestrator/ledger.mjs +332 -0
- package/scripts/wave-orchestrator/local-executor.mjs +263 -0
- package/scripts/wave-orchestrator/replay.mjs +246 -0
- package/scripts/wave-orchestrator/roots.mjs +10 -0
- package/scripts/wave-orchestrator/routing-state.mjs +542 -0
- package/scripts/wave-orchestrator/shared.mjs +405 -0
- package/scripts/wave-orchestrator/terminals.mjs +209 -0
- package/scripts/wave-orchestrator/traces.mjs +1094 -0
- package/scripts/wave-orchestrator/wave-files.mjs +1923 -0
- package/scripts/wave.mjs +103 -0
- package/wave.config.json +115 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { readJsonOrNull } from "./shared.mjs";
|
|
3
|
+
import { buildGateSnapshot } from "./launcher.mjs";
|
|
4
|
+
import {
|
|
5
|
+
buildQualityMetrics,
|
|
6
|
+
loadTraceBundle,
|
|
7
|
+
normalizeGateSnapshotForBundle,
|
|
8
|
+
validateTraceBundle,
|
|
9
|
+
} from "./traces.mjs";
|
|
10
|
+
|
|
11
|
+
function absoluteBundlePath(dir, relativePath) {
|
|
12
|
+
if (!relativePath) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return path.join(dir, relativePath);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function buildReplayLanePaths(metadata) {
|
|
19
|
+
const replayContext =
|
|
20
|
+
metadata?.replayContext && typeof metadata.replayContext === "object"
|
|
21
|
+
? metadata.replayContext
|
|
22
|
+
: null;
|
|
23
|
+
const roles = replayContext?.roles || metadata?.roles || {};
|
|
24
|
+
const validation = replayContext?.validation || metadata?.validation || {};
|
|
25
|
+
const evaluatorAgentId = roles.evaluatorAgentId || "A0";
|
|
26
|
+
const integrationAgentId = roles.integrationAgentId || "A8";
|
|
27
|
+
const documentationAgentId = roles.documentationAgentId || "A9";
|
|
28
|
+
return {
|
|
29
|
+
lane: replayContext?.lane || metadata?.lane || "main",
|
|
30
|
+
evaluatorAgentId,
|
|
31
|
+
integrationAgentId,
|
|
32
|
+
documentationAgentId,
|
|
33
|
+
requireIntegrationStewardFromWave:
|
|
34
|
+
validation.requireIntegrationStewardFromWave ?? null,
|
|
35
|
+
laneProfile: {
|
|
36
|
+
roles: {
|
|
37
|
+
evaluatorAgentId,
|
|
38
|
+
integrationAgentId,
|
|
39
|
+
documentationAgentId,
|
|
40
|
+
},
|
|
41
|
+
validation: {
|
|
42
|
+
requireDocumentationStewardFromWave:
|
|
43
|
+
validation.requireDocumentationStewardFromWave ?? null,
|
|
44
|
+
requireContext7DeclarationsFromWave:
|
|
45
|
+
validation.requireContext7DeclarationsFromWave ?? null,
|
|
46
|
+
requireExitContractsFromWave:
|
|
47
|
+
validation.requireExitContractsFromWave ?? null,
|
|
48
|
+
requireIntegrationStewardFromWave:
|
|
49
|
+
validation.requireIntegrationStewardFromWave ?? null,
|
|
50
|
+
requireComponentPromotionsFromWave:
|
|
51
|
+
validation.requireComponentPromotionsFromWave ?? null,
|
|
52
|
+
requireAgentComponentsFromWave:
|
|
53
|
+
validation.requireAgentComponentsFromWave ?? null,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function buildReplayAgentRuns(dir, wave, metadata) {
|
|
60
|
+
const isHermeticTrace = Number(metadata?.traceVersion) >= 2;
|
|
61
|
+
return (metadata?.agents || []).map((agentMetadata) => {
|
|
62
|
+
const waveAgent =
|
|
63
|
+
wave.agents.find((agent) => agent.agentId === agentMetadata.agentId) || {
|
|
64
|
+
agentId: agentMetadata.agentId,
|
|
65
|
+
title: agentMetadata.title || agentMetadata.agentId,
|
|
66
|
+
};
|
|
67
|
+
const summaryPath = absoluteBundlePath(dir, agentMetadata.summaryPath);
|
|
68
|
+
const summaryPayload = summaryPath ? readJsonOrNull(summaryPath) : null;
|
|
69
|
+
return {
|
|
70
|
+
agent: {
|
|
71
|
+
...waveAgent,
|
|
72
|
+
executorResolved: agentMetadata.executor
|
|
73
|
+
? {
|
|
74
|
+
...waveAgent.executorResolved,
|
|
75
|
+
...agentMetadata.executor,
|
|
76
|
+
id: agentMetadata.executor.executorId || agentMetadata.executor.id || null,
|
|
77
|
+
}
|
|
78
|
+
: waveAgent.executorResolved,
|
|
79
|
+
context7Resolved: agentMetadata.context7?.selection || waveAgent.context7Resolved || null,
|
|
80
|
+
},
|
|
81
|
+
promptPath: absoluteBundlePath(dir, agentMetadata.promptPath),
|
|
82
|
+
logPath: absoluteBundlePath(dir, agentMetadata.logPath),
|
|
83
|
+
statusPath: absoluteBundlePath(dir, agentMetadata.statusPath),
|
|
84
|
+
summaryPath,
|
|
85
|
+
summary:
|
|
86
|
+
summaryPayload && typeof summaryPayload === "object"
|
|
87
|
+
? summaryPayload
|
|
88
|
+
: !isHermeticTrace
|
|
89
|
+
? agentMetadata.summary || null
|
|
90
|
+
: null,
|
|
91
|
+
inboxPath: absoluteBundlePath(dir, agentMetadata.inboxPath),
|
|
92
|
+
lastLaunchAttempt: agentMetadata.launchedInAttempt ? metadata.attempt : null,
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function diffStructuredValues(expected, actual, basePath = "") {
|
|
98
|
+
if (JSON.stringify(expected) === JSON.stringify(actual)) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
const expectedIsObject =
|
|
102
|
+
expected !== null && typeof expected === "object" && !Array.isArray(expected);
|
|
103
|
+
const actualIsObject = actual !== null && typeof actual === "object" && !Array.isArray(actual);
|
|
104
|
+
if (expectedIsObject && actualIsObject) {
|
|
105
|
+
const keys = new Set([...Object.keys(expected), ...Object.keys(actual)]);
|
|
106
|
+
return Array.from(keys)
|
|
107
|
+
.toSorted()
|
|
108
|
+
.flatMap((key) =>
|
|
109
|
+
diffStructuredValues(
|
|
110
|
+
expected[key],
|
|
111
|
+
actual[key],
|
|
112
|
+
basePath ? `${basePath}.${key}` : key,
|
|
113
|
+
),
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
const expectedIsArray = Array.isArray(expected);
|
|
117
|
+
const actualIsArray = Array.isArray(actual);
|
|
118
|
+
if (expectedIsArray && actualIsArray) {
|
|
119
|
+
if (expected.length !== actual.length) {
|
|
120
|
+
return [basePath || "<root>"];
|
|
121
|
+
}
|
|
122
|
+
return expected.flatMap((value, index) =>
|
|
123
|
+
diffStructuredValues(value, actual[index], `${basePath}[${index}]`),
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return [basePath || "<root>"];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function buildReplayComparison(storedGateSnapshot, gateSnapshot, storedQuality, quality) {
|
|
130
|
+
const gateDiffPaths = diffStructuredValues(storedGateSnapshot || null, gateSnapshot || null);
|
|
131
|
+
const qualityDiffPaths = diffStructuredValues(storedQuality || null, quality || null);
|
|
132
|
+
return {
|
|
133
|
+
gateSnapshot: {
|
|
134
|
+
matches: gateDiffPaths.length === 0,
|
|
135
|
+
diffPaths: gateDiffPaths,
|
|
136
|
+
},
|
|
137
|
+
quality: {
|
|
138
|
+
matches: qualityDiffPaths.length === 0,
|
|
139
|
+
diffPaths: qualityDiffPaths,
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function replayTraceBundle(dir) {
|
|
145
|
+
const bundle = loadTraceBundle(dir);
|
|
146
|
+
const validation = validateTraceBundle(bundle);
|
|
147
|
+
const warnings = [...(validation.warnings || [])];
|
|
148
|
+
if (!validation.ok) {
|
|
149
|
+
return {
|
|
150
|
+
ok: false,
|
|
151
|
+
replayMode: validation.replayMode || "invalid",
|
|
152
|
+
validation,
|
|
153
|
+
warnings,
|
|
154
|
+
bundle,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const wave =
|
|
158
|
+
bundle.manifest?.waves?.find((entry) => Number(entry.wave) === Number(bundle.metadata.wave)) ||
|
|
159
|
+
bundle.manifest?.waves?.[0];
|
|
160
|
+
if (!wave) {
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
replayMode: validation.replayMode || "invalid",
|
|
164
|
+
validation: {
|
|
165
|
+
...validation,
|
|
166
|
+
ok: false,
|
|
167
|
+
errors: [...(validation.errors || []), "Trace manifest does not include a replayable wave definition."],
|
|
168
|
+
},
|
|
169
|
+
warnings,
|
|
170
|
+
bundle,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
const lanePaths = buildReplayLanePaths(bundle.metadata);
|
|
174
|
+
const agentRuns = buildReplayAgentRuns(dir, wave, bundle.metadata);
|
|
175
|
+
const derivedState = {
|
|
176
|
+
coordinationState: bundle.coordinationState,
|
|
177
|
+
ledger: bundle.ledger,
|
|
178
|
+
docsQueue: bundle.docsQueue,
|
|
179
|
+
capabilityAssignments: bundle.capabilityAssignments || [],
|
|
180
|
+
dependencySnapshot: bundle.dependencySnapshot || null,
|
|
181
|
+
integrationSummary: bundle.integrationSummary,
|
|
182
|
+
};
|
|
183
|
+
const gateSnapshot = normalizeGateSnapshotForBundle(
|
|
184
|
+
buildGateSnapshot({
|
|
185
|
+
wave,
|
|
186
|
+
agentRuns,
|
|
187
|
+
derivedState,
|
|
188
|
+
lanePaths,
|
|
189
|
+
componentMatrixPayload: bundle.componentMatrix,
|
|
190
|
+
componentMatrixJsonPath: bundle.componentMatrixPath,
|
|
191
|
+
}),
|
|
192
|
+
bundle.metadata.artifacts?.agents || {},
|
|
193
|
+
);
|
|
194
|
+
const summariesByAgentId = Object.fromEntries(
|
|
195
|
+
agentRuns
|
|
196
|
+
.map((run) => [run.agent.agentId, run.summary || null])
|
|
197
|
+
.filter(([, summary]) => summary),
|
|
198
|
+
);
|
|
199
|
+
const historySnapshot =
|
|
200
|
+
bundle.metadata.traceVersion >= 2
|
|
201
|
+
? bundle.metadata.historySnapshot || null
|
|
202
|
+
: null;
|
|
203
|
+
if (!historySnapshot) {
|
|
204
|
+
warnings.push(
|
|
205
|
+
"Legacy replay is best-effort: cumulative quality may depend on sibling attempts or available trace history.",
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
const quality = buildQualityMetrics({
|
|
209
|
+
historySnapshot,
|
|
210
|
+
tracesDir:
|
|
211
|
+
historySnapshot || bundle.metadata.traceVersion >= 2
|
|
212
|
+
? null
|
|
213
|
+
: path.dirname(path.dirname(dir)),
|
|
214
|
+
wave,
|
|
215
|
+
attempt: bundle.metadata.attempt,
|
|
216
|
+
coordinationLogPath: path.join(dir, "coordination.raw.jsonl"),
|
|
217
|
+
coordinationState: bundle.coordinationState,
|
|
218
|
+
integrationSummary: bundle.integrationSummary,
|
|
219
|
+
ledger: bundle.ledger,
|
|
220
|
+
docsQueue: bundle.docsQueue,
|
|
221
|
+
capabilityAssignments: bundle.capabilityAssignments || [],
|
|
222
|
+
dependencySnapshot: bundle.dependencySnapshot || null,
|
|
223
|
+
summariesByAgentId,
|
|
224
|
+
agentRuns,
|
|
225
|
+
gateSnapshot,
|
|
226
|
+
});
|
|
227
|
+
const storedGateSnapshot =
|
|
228
|
+
bundle.storedOutcome?.gateSnapshot || bundle.metadata.gateSnapshot || null;
|
|
229
|
+
const storedQuality = bundle.storedOutcome?.quality || bundle.quality || null;
|
|
230
|
+
const comparison = buildReplayComparison(storedGateSnapshot, gateSnapshot, storedQuality, quality);
|
|
231
|
+
return {
|
|
232
|
+
ok: validation.ok && gateSnapshot.overall.ok === true,
|
|
233
|
+
replayMode: validation.replayMode,
|
|
234
|
+
validation,
|
|
235
|
+
warnings,
|
|
236
|
+
bundle,
|
|
237
|
+
wave,
|
|
238
|
+
gateSnapshot,
|
|
239
|
+
quality,
|
|
240
|
+
storedGateSnapshot,
|
|
241
|
+
storedQuality,
|
|
242
|
+
comparison,
|
|
243
|
+
matchesStoredGateSnapshot: comparison.gateSnapshot.matches,
|
|
244
|
+
matchesStoredQuality: comparison.quality.matches,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
|
|
4
|
+
export const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
|
5
|
+
|
|
6
|
+
export function resolveWorkspaceRoot(value = process.env.WAVE_REPO_ROOT || process.cwd()) {
|
|
7
|
+
return path.resolve(String(value || process.cwd()));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const WORKSPACE_ROOT = resolveWorkspaceRoot();
|