@chllming/wave-orchestration 0.8.8 → 0.9.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/CHANGELOG.md +48 -0
- package/README.md +23 -8
- package/docs/README.md +5 -3
- package/docs/concepts/context7-vs-skills.md +1 -1
- package/docs/concepts/operating-modes.md +1 -1
- package/docs/concepts/what-is-a-wave.md +1 -1
- package/docs/guides/author-and-run-waves.md +14 -1
- package/docs/guides/monorepo-projects.md +226 -0
- package/docs/guides/planner.md +9 -2
- package/docs/guides/{recommendations-0.8.8.md → recommendations-0.9.0.md} +7 -7
- package/docs/plans/current-state.md +8 -6
- package/docs/plans/end-state-architecture.md +1 -1
- package/docs/plans/examples/wave-example-design-handoff.md +3 -1
- package/docs/plans/examples/wave-example-live-proof.md +6 -1
- package/docs/plans/examples/wave-example-rollout-fidelity.md +2 -0
- package/docs/plans/migration.md +21 -18
- package/docs/plans/wave-orchestrator.md +4 -4
- package/docs/reference/cli-reference.md +55 -51
- package/docs/reference/coordination-and-closure.md +1 -1
- package/docs/reference/npmjs-trusted-publishing.md +2 -2
- package/docs/reference/runtime-config/README.md +140 -12
- package/docs/reference/sample-waves.md +100 -5
- package/docs/reference/skills.md +1 -1
- package/docs/reference/wave-control.md +23 -5
- package/docs/roadmap.md +2 -2
- package/package.json +1 -1
- package/releases/manifest.json +37 -0
- package/scripts/wave-orchestrator/adhoc.mjs +49 -17
- package/scripts/wave-orchestrator/autonomous.mjs +49 -15
- package/scripts/wave-orchestrator/benchmark-external.mjs +23 -7
- package/scripts/wave-orchestrator/benchmark.mjs +33 -10
- package/scripts/wave-orchestrator/config.mjs +239 -24
- package/scripts/wave-orchestrator/control-cli.mjs +29 -23
- package/scripts/wave-orchestrator/coord-cli.mjs +22 -14
- package/scripts/wave-orchestrator/coordination-store.mjs +8 -0
- package/scripts/wave-orchestrator/dashboard-renderer.mjs +10 -3
- package/scripts/wave-orchestrator/dep-cli.mjs +47 -21
- package/scripts/wave-orchestrator/feedback.mjs +28 -11
- package/scripts/wave-orchestrator/human-input-resolution.mjs +5 -1
- package/scripts/wave-orchestrator/launcher.mjs +200 -112
- package/scripts/wave-orchestrator/planner.mjs +48 -27
- package/scripts/wave-orchestrator/project-profile.mjs +31 -8
- package/scripts/wave-orchestrator/proof-cli.mjs +18 -12
- package/scripts/wave-orchestrator/retry-cli.mjs +19 -13
- package/scripts/wave-orchestrator/shared.mjs +77 -14
- package/scripts/wave-orchestrator/traces.mjs +7 -0
- package/scripts/wave-orchestrator/wave-control-client.mjs +84 -16
- package/scripts/wave-orchestrator/wave-files.mjs +5 -1
- package/scripts/wave-orchestrator/wave-state-reducer.mjs +8 -1
|
@@ -15,10 +15,10 @@ import { parseWaveFiles } from "./wave-files.mjs";
|
|
|
15
15
|
|
|
16
16
|
function printUsage() {
|
|
17
17
|
console.log(`Usage:
|
|
18
|
-
wave dep post --owner-lane <lane> --requester-lane <lane> --owner-wave <n> --requester-wave <n> --agent <id> --summary <text> [options]
|
|
19
|
-
wave dep show --lane <lane> [--wave <n>] [--json]
|
|
20
|
-
wave dep resolve --lane <lane> --id <id> --agent <id> [--detail <text>] [--status resolved|closed]
|
|
21
|
-
wave dep render --lane <lane> [--wave <n>] [--json]
|
|
18
|
+
wave dep post --owner-project <id> --owner-lane <lane> --requester-project <id> --requester-lane <lane> --owner-wave <n> --requester-wave <n> --agent <id> --summary <text> [options]
|
|
19
|
+
wave dep show --project <id> --lane <lane> [--wave <n>] [--json]
|
|
20
|
+
wave dep resolve --project <id> --lane <lane> --id <id> --agent <id> [--detail <text>] [--status resolved|closed]
|
|
21
|
+
wave dep render --project <id> --lane <lane> [--wave <n>] [--json]
|
|
22
22
|
`);
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -26,6 +26,9 @@ function parseArgs(argv) {
|
|
|
26
26
|
const args = argv[0] === "--" ? argv.slice(1) : argv;
|
|
27
27
|
const subcommand = String(args[0] || "").trim().toLowerCase();
|
|
28
28
|
const options = {
|
|
29
|
+
project: "",
|
|
30
|
+
ownerProject: "",
|
|
31
|
+
requesterProject: "",
|
|
29
32
|
lane: "",
|
|
30
33
|
ownerLane: "",
|
|
31
34
|
requesterLane: "",
|
|
@@ -46,7 +49,13 @@ function parseArgs(argv) {
|
|
|
46
49
|
};
|
|
47
50
|
for (let index = 1; index < args.length; index += 1) {
|
|
48
51
|
const arg = args[index];
|
|
49
|
-
if (arg === "--
|
|
52
|
+
if (arg === "--project") {
|
|
53
|
+
options.project = String(args[++index] || "").trim();
|
|
54
|
+
} else if (arg === "--owner-project") {
|
|
55
|
+
options.ownerProject = String(args[++index] || "").trim();
|
|
56
|
+
} else if (arg === "--requester-project") {
|
|
57
|
+
options.requesterProject = String(args[++index] || "").trim();
|
|
58
|
+
} else if (arg === "--lane") {
|
|
50
59
|
options.lane = String(args[++index] || "").trim();
|
|
51
60
|
} else if (arg === "--owner-lane") {
|
|
52
61
|
options.ownerLane = String(args[++index] || "").trim();
|
|
@@ -112,11 +121,15 @@ export async function runDependencyCli(argv) {
|
|
|
112
121
|
return;
|
|
113
122
|
}
|
|
114
123
|
const { subcommand, options } = parseArgs(argv);
|
|
124
|
+
const baseProject =
|
|
125
|
+
options.project || options.ownerProject || options.requesterProject || undefined;
|
|
115
126
|
const baseLane = options.lane || options.ownerLane || options.requesterLane || "main";
|
|
116
|
-
const lanePaths = buildLanePaths(baseLane);
|
|
127
|
+
const lanePaths = buildLanePaths(baseLane, { project: baseProject });
|
|
117
128
|
ensureDirectory(lanePaths.crossLaneDependenciesDir);
|
|
118
129
|
|
|
119
130
|
if (subcommand === "post") {
|
|
131
|
+
const ownerProject = options.ownerProject || options.project || lanePaths.project;
|
|
132
|
+
const requesterProject = options.requesterProject || options.project || lanePaths.project;
|
|
120
133
|
const ownerLane = options.ownerLane || options.lane;
|
|
121
134
|
const requesterLane = options.requesterLane || lanePaths.lane;
|
|
122
135
|
if (!ownerLane || !requesterLane || options.ownerWave === null || options.requesterWave === null) {
|
|
@@ -125,13 +138,17 @@ export async function runDependencyCli(argv) {
|
|
|
125
138
|
if (!options.agent || !options.summary) {
|
|
126
139
|
throw new Error("--agent and --summary are required");
|
|
127
140
|
}
|
|
128
|
-
const
|
|
141
|
+
const ownerLanePaths = buildLanePaths(ownerLane, { project: ownerProject });
|
|
142
|
+
ensureDirectory(ownerLanePaths.crossLaneDependenciesDir);
|
|
143
|
+
const record = appendDependencyTicket(ownerLanePaths.crossLaneDependenciesDir, ownerLane, {
|
|
129
144
|
id: options.id || `dep-${Date.now().toString(36)}`,
|
|
130
145
|
kind: "request",
|
|
131
146
|
lane: ownerLane,
|
|
132
147
|
wave: options.ownerWave,
|
|
148
|
+
ownerProject,
|
|
133
149
|
ownerLane,
|
|
134
150
|
ownerWave: options.ownerWave,
|
|
151
|
+
requesterProject,
|
|
135
152
|
requesterLane,
|
|
136
153
|
requesterWave: options.requesterWave,
|
|
137
154
|
agentId: options.agent,
|
|
@@ -155,14 +172,15 @@ export async function runDependencyCli(argv) {
|
|
|
155
172
|
if (!lane || !options.id || !options.agent) {
|
|
156
173
|
throw new Error("--lane, --id, and --agent are required for resolve");
|
|
157
174
|
}
|
|
158
|
-
const
|
|
159
|
-
const
|
|
175
|
+
const targetProject = options.project || options.ownerProject || lanePaths.project;
|
|
176
|
+
const targetLanePaths = buildLanePaths(lane, { project: targetProject });
|
|
177
|
+
const latest = materializeCoordinationState(readDependencyTickets(targetLanePaths.crossLaneDependenciesDir, lane)).byId.get(
|
|
160
178
|
options.id,
|
|
161
179
|
);
|
|
162
180
|
if (!latest) {
|
|
163
181
|
throw new Error(`Dependency ${options.id} not found for lane ${lane}`);
|
|
164
182
|
}
|
|
165
|
-
const record = appendDependencyTicket(
|
|
183
|
+
const record = appendDependencyTicket(targetLanePaths.crossLaneDependenciesDir, lane, {
|
|
166
184
|
...latest,
|
|
167
185
|
agentId: options.agent,
|
|
168
186
|
status: options.status || "resolved",
|
|
@@ -175,17 +193,23 @@ export async function runDependencyCli(argv) {
|
|
|
175
193
|
|
|
176
194
|
if (subcommand === "show") {
|
|
177
195
|
const lane = options.lane || options.ownerLane || lanePaths.lane;
|
|
196
|
+
const targetProject = options.project || options.ownerProject || lanePaths.project;
|
|
197
|
+
const targetLanePaths = buildLanePaths(lane, { project: targetProject });
|
|
178
198
|
const records =
|
|
179
199
|
options.wave === null
|
|
180
|
-
? readAllDependencyTickets(
|
|
181
|
-
(record) =>
|
|
200
|
+
? readAllDependencyTickets(targetLanePaths.crossLaneDependenciesDir).filter(
|
|
201
|
+
(record) =>
|
|
202
|
+
(record.ownerLane === lane || record.requesterLane === lane || record.lane === lane) &&
|
|
203
|
+
(!options.project ||
|
|
204
|
+
record.ownerProject === targetProject ||
|
|
205
|
+
record.requesterProject === targetProject),
|
|
182
206
|
)
|
|
183
207
|
: buildDependencySnapshot({
|
|
184
|
-
dirPath:
|
|
208
|
+
dirPath: targetLanePaths.crossLaneDependenciesDir,
|
|
185
209
|
lane,
|
|
186
210
|
waveNumber: options.wave,
|
|
187
|
-
agents: loadWaveAgents(
|
|
188
|
-
capabilityRouting:
|
|
211
|
+
agents: loadWaveAgents(targetLanePaths, options.wave),
|
|
212
|
+
capabilityRouting: targetLanePaths.capabilityRouting,
|
|
189
213
|
});
|
|
190
214
|
if (options.json || options.wave !== null) {
|
|
191
215
|
console.log(JSON.stringify(records, null, 2));
|
|
@@ -201,20 +225,22 @@ export async function runDependencyCli(argv) {
|
|
|
201
225
|
|
|
202
226
|
if (subcommand === "render") {
|
|
203
227
|
const lane = options.lane || options.ownerLane || lanePaths.lane;
|
|
228
|
+
const targetProject = options.project || options.ownerProject || lanePaths.project;
|
|
229
|
+
const targetLanePaths = buildLanePaths(lane, { project: targetProject });
|
|
204
230
|
const snapshot = buildDependencySnapshot({
|
|
205
|
-
dirPath:
|
|
231
|
+
dirPath: targetLanePaths.crossLaneDependenciesDir,
|
|
206
232
|
lane,
|
|
207
233
|
waveNumber: options.wave ?? 0,
|
|
208
|
-
agents: loadWaveAgents(
|
|
209
|
-
capabilityRouting:
|
|
234
|
+
agents: loadWaveAgents(targetLanePaths, options.wave ?? 0),
|
|
235
|
+
capabilityRouting: targetLanePaths.capabilityRouting,
|
|
210
236
|
});
|
|
211
|
-
const markdownPath = dependencyMarkdownPath(
|
|
212
|
-
writeDependencySnapshot(path.join(
|
|
237
|
+
const markdownPath = dependencyMarkdownPath(targetLanePaths, lane);
|
|
238
|
+
writeDependencySnapshot(path.join(targetLanePaths.crossLaneDependenciesDir, `${lane}.json`), snapshot, {
|
|
213
239
|
lane,
|
|
214
240
|
wave: options.wave ?? 0,
|
|
215
241
|
});
|
|
216
242
|
writeTextAtomic(markdownPath, `${renderDependencySnapshotMarkdown(snapshot)}\n`);
|
|
217
|
-
console.log(JSON.stringify({ markdownPath, jsonPath: path.join(
|
|
243
|
+
console.log(JSON.stringify({ markdownPath, jsonPath: path.join(targetLanePaths.crossLaneDependenciesDir, `${lane}.json`) }, null, 2));
|
|
218
244
|
return;
|
|
219
245
|
}
|
|
220
246
|
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
DEFAULT_WAIT_TIMEOUT_SECONDS,
|
|
7
7
|
DEFAULT_WATCH_REFRESH_MS,
|
|
8
8
|
DEFAULT_WAVE_LANE,
|
|
9
|
-
REPO_ROOT,
|
|
10
9
|
buildLanePaths,
|
|
11
10
|
compactSingleLine,
|
|
12
11
|
ensureDirectory,
|
|
12
|
+
findAdhocRunRecord,
|
|
13
13
|
formatAgeFromTimestamp,
|
|
14
14
|
parseNonNegativeInt,
|
|
15
15
|
parsePositiveInt,
|
|
@@ -41,9 +41,12 @@ function requestFilePath(feedbackRequestsDir, requestId) {
|
|
|
41
41
|
return path.join(feedbackRequestsDir, `${requestId}.json`);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function
|
|
45
|
-
const
|
|
46
|
-
return
|
|
44
|
+
function resolveRunContext(runId, fallbackProject, fallbackLane) {
|
|
45
|
+
const record = findAdhocRunRecord(runId);
|
|
46
|
+
return {
|
|
47
|
+
project: record?.project || fallbackProject,
|
|
48
|
+
lane: record?.result?.lane || fallbackLane,
|
|
49
|
+
};
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
function buildRequestId({ lane, wave, agentId }) {
|
|
@@ -55,6 +58,7 @@ function buildRequestId({ lane, wave, agentId }) {
|
|
|
55
58
|
export function createFeedbackRequest({
|
|
56
59
|
feedbackStateDir,
|
|
57
60
|
feedbackRequestsDir,
|
|
61
|
+
project = null,
|
|
58
62
|
lane,
|
|
59
63
|
wave,
|
|
60
64
|
agentId,
|
|
@@ -69,6 +73,7 @@ export function createFeedbackRequest({
|
|
|
69
73
|
const now = toIsoTimestamp();
|
|
70
74
|
const payload = {
|
|
71
75
|
id: requestId,
|
|
76
|
+
project: project || null,
|
|
72
77
|
createdAt: now,
|
|
73
78
|
updatedAt: now,
|
|
74
79
|
lane,
|
|
@@ -88,7 +93,9 @@ export function createFeedbackRequest({
|
|
|
88
93
|
});
|
|
89
94
|
if (recordTelemetry) {
|
|
90
95
|
try {
|
|
91
|
-
const lanePaths = buildLanePaths(lane
|
|
96
|
+
const lanePaths = buildLanePaths(lane, {
|
|
97
|
+
project: project || undefined,
|
|
98
|
+
});
|
|
92
99
|
safeQueueWaveControlEvent(lanePaths, {
|
|
93
100
|
category: "feedback",
|
|
94
101
|
entityType: "human_input",
|
|
@@ -148,7 +155,9 @@ export function answerFeedbackRequest({
|
|
|
148
155
|
});
|
|
149
156
|
if (recordTelemetry) {
|
|
150
157
|
try {
|
|
151
|
-
const lanePaths = buildLanePaths(answeredPayload?.lane || DEFAULT_WAVE_LANE
|
|
158
|
+
const lanePaths = buildLanePaths(answeredPayload?.lane || DEFAULT_WAVE_LANE, {
|
|
159
|
+
project: answeredPayload?.project || undefined,
|
|
160
|
+
});
|
|
152
161
|
safeQueueWaveControlEvent(lanePaths, {
|
|
153
162
|
category: "feedback",
|
|
154
163
|
entityType: "human_input",
|
|
@@ -245,6 +254,7 @@ function parseFeedbackArgs(argv) {
|
|
|
245
254
|
id: "",
|
|
246
255
|
response: "",
|
|
247
256
|
operator: "human-operator",
|
|
257
|
+
project: "",
|
|
248
258
|
force: false,
|
|
249
259
|
pending: false,
|
|
250
260
|
json: false,
|
|
@@ -255,7 +265,9 @@ function parseFeedbackArgs(argv) {
|
|
|
255
265
|
if (arg === "--") {
|
|
256
266
|
continue;
|
|
257
267
|
}
|
|
258
|
-
if (arg === "--
|
|
268
|
+
if (arg === "--project") {
|
|
269
|
+
out.project = String(args[++i] || "").trim();
|
|
270
|
+
} else if (arg === "--lane") {
|
|
259
271
|
out.lane = sanitizeLaneName(args[++i]);
|
|
260
272
|
} else if (arg === "--run") {
|
|
261
273
|
out.runId = sanitizeAdhocRunId(args[++i]);
|
|
@@ -310,10 +322,10 @@ async function waitForAnswer(filePath, timeoutSeconds) {
|
|
|
310
322
|
|
|
311
323
|
function printHelp() {
|
|
312
324
|
console.log(`Usage:
|
|
313
|
-
pnpm exec wave-feedback ask --lane <lane> --wave <n> --agent <id> --question "<text>" [options]
|
|
325
|
+
pnpm exec wave-feedback ask --project <id> --lane <lane> --wave <n> --agent <id> --question "<text>" [options]
|
|
314
326
|
pnpm exec wave-feedback respond --id <request-id> --response "<text>" [options]
|
|
315
|
-
pnpm exec wave-feedback list [--pending] [--lane <lane>] [--wave <n>] [--agent <id>] [--json]
|
|
316
|
-
pnpm exec wave-feedback watch [--pending] [--lane <lane>] [--wave <n>] [--agent <id>] [--refresh-ms <n>]
|
|
327
|
+
pnpm exec wave-feedback list [--pending] [--project <id>] [--lane <lane>] [--wave <n>] [--agent <id>] [--json]
|
|
328
|
+
pnpm exec wave-feedback watch [--pending] [--project <id>] [--lane <lane>] [--wave <n>] [--agent <id>] [--refresh-ms <n>]
|
|
317
329
|
pnpm exec wave-feedback show --id <request-id>
|
|
318
330
|
`);
|
|
319
331
|
}
|
|
@@ -325,9 +337,12 @@ export async function runFeedbackCli(argv) {
|
|
|
325
337
|
return;
|
|
326
338
|
}
|
|
327
339
|
if (options.runId) {
|
|
328
|
-
|
|
340
|
+
const context = resolveRunContext(options.runId, options.project, options.lane);
|
|
341
|
+
options.project = context.project;
|
|
342
|
+
options.lane = context.lane;
|
|
329
343
|
}
|
|
330
344
|
const lanePaths = buildLanePaths(options.lane, {
|
|
345
|
+
project: options.project || undefined,
|
|
331
346
|
adhocRunId: options.runId || null,
|
|
332
347
|
});
|
|
333
348
|
const requestsDir = lanePaths.feedbackRequestsDir;
|
|
@@ -340,6 +355,7 @@ export async function runFeedbackCli(argv) {
|
|
|
340
355
|
const result = createFeedbackRequest({
|
|
341
356
|
feedbackStateDir: stateDir,
|
|
342
357
|
feedbackRequestsDir: requestsDir,
|
|
358
|
+
project: lanePaths.project,
|
|
343
359
|
lane: options.lane,
|
|
344
360
|
wave: options.wave,
|
|
345
361
|
agentId: options.agent,
|
|
@@ -375,6 +391,7 @@ export async function runFeedbackCli(argv) {
|
|
|
375
391
|
});
|
|
376
392
|
if (answered?.lane && Number.isFinite(Number(answered.wave))) {
|
|
377
393
|
answerHumanInputByRequest({
|
|
394
|
+
project: answered.project || options.project || null,
|
|
378
395
|
lane: answered.lane,
|
|
379
396
|
waveNumber: Number(answered.wave),
|
|
380
397
|
requestId: options.id,
|
|
@@ -331,13 +331,17 @@ export function answerHumanInputAndReconcile({
|
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
export function answerHumanInputByRequest({
|
|
334
|
+
project = null,
|
|
334
335
|
lane,
|
|
335
336
|
waveNumber,
|
|
336
337
|
requestId,
|
|
337
338
|
operator = "human-operator",
|
|
338
339
|
runId = null,
|
|
339
340
|
}) {
|
|
340
|
-
const lanePaths = buildLanePaths(lane, {
|
|
341
|
+
const lanePaths = buildLanePaths(lane, {
|
|
342
|
+
project: project || undefined,
|
|
343
|
+
adhocRunId: runId || null,
|
|
344
|
+
});
|
|
341
345
|
const wave = loadWave(lanePaths, waveNumber);
|
|
342
346
|
return answerHumanInputAndReconcile({
|
|
343
347
|
lanePaths,
|