@chllming/wave-orchestration 0.6.2 → 0.7.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 +64 -1
- package/README.md +44 -8
- package/docs/agents/wave-orchestrator-role.md +50 -0
- package/docs/agents/wave-planner-role.md +39 -0
- package/docs/context7/bundles.json +9 -0
- package/docs/context7/planner-agent/README.md +25 -0
- package/docs/context7/planner-agent/manifest.json +83 -0
- package/docs/context7/planner-agent/papers/cooperbench-why-coding-agents-cannot-be-your-teammates-yet.md +3283 -0
- package/docs/context7/planner-agent/papers/dova-deliberation-first-multi-agent-orchestration-for-autonomous-research-automation.md +1699 -0
- package/docs/context7/planner-agent/papers/dpbench-large-language-models-struggle-with-simultaneous-coordination.md +2251 -0
- package/docs/context7/planner-agent/papers/incremental-planning-to-control-a-blackboard-based-problem-solver.md +1729 -0
- package/docs/context7/planner-agent/papers/silo-bench-a-scalable-environment-for-evaluating-distributed-coordination-in-multi-agent-llm-systems.md +3747 -0
- package/docs/context7/planner-agent/papers/todoevolve-learning-to-architect-agent-planning-systems.md +1675 -0
- package/docs/context7/planner-agent/papers/verified-multi-agent-orchestration-a-plan-execute-verify-replan-framework-for-complex-query-resolution.md +1173 -0
- package/docs/context7/planner-agent/papers/why-do-multi-agent-llm-systems-fail.md +5211 -0
- package/docs/context7/planner-agent/topics/planning-and-orchestration.md +24 -0
- package/docs/evals/README.md +96 -1
- package/docs/evals/arm-templates/README.md +13 -0
- package/docs/evals/arm-templates/full-wave.json +15 -0
- package/docs/evals/arm-templates/single-agent.json +15 -0
- package/docs/evals/benchmark-catalog.json +7 -0
- package/docs/evals/cases/README.md +47 -0
- package/docs/evals/cases/wave-blackboard-inbox-targeting.json +73 -0
- package/docs/evals/cases/wave-contradiction-conflict.json +104 -0
- package/docs/evals/cases/wave-expert-routing-preservation.json +69 -0
- package/docs/evals/cases/wave-hidden-profile-private-evidence.json +81 -0
- package/docs/evals/cases/wave-premature-closure-guard.json +71 -0
- package/docs/evals/cases/wave-silo-cross-agent-state.json +77 -0
- package/docs/evals/cases/wave-simultaneous-lockstep.json +92 -0
- package/docs/evals/cooperbench/real-world-mitigation.md +341 -0
- package/docs/evals/external-benchmarks.json +85 -0
- package/docs/evals/external-command-config.sample.json +9 -0
- package/docs/evals/external-command-config.swe-bench-pro.json +8 -0
- package/docs/evals/pilots/README.md +47 -0
- package/docs/evals/pilots/swe-bench-pro-public-full-wave-review-10.json +64 -0
- package/docs/evals/pilots/swe-bench-pro-public-pilot.json +111 -0
- package/docs/evals/wave-benchmark-program.md +302 -0
- package/docs/guides/planner.md +48 -11
- package/docs/plans/context7-wave-orchestrator.md +20 -0
- package/docs/plans/current-state.md +9 -1
- package/docs/plans/examples/wave-benchmark-improvement.md +108 -0
- package/docs/plans/examples/wave-example-live-proof.md +1 -1
- package/docs/plans/examples/wave-example-rollout-fidelity.md +340 -0
- package/docs/plans/wave-orchestrator.md +73 -11
- package/docs/plans/waves/reviews/wave-1-benchmark-operator.md +118 -0
- package/docs/reference/coordination-and-closure.md +436 -0
- package/docs/reference/live-proof-waves.md +25 -3
- package/docs/reference/npmjs-trusted-publishing.md +3 -3
- package/docs/reference/proof-metrics.md +90 -0
- package/docs/reference/runtime-config/README.md +61 -0
- package/docs/reference/sample-waves.md +29 -18
- package/docs/reference/wave-control.md +164 -0
- package/docs/reference/wave-planning-lessons.md +131 -0
- package/package.json +5 -4
- package/releases/manifest.json +33 -0
- package/scripts/research/agent-context-archive.mjs +18 -0
- package/scripts/research/manifests/agent-context-expanded-2026-03-22.mjs +17 -0
- package/scripts/research/sync-planner-context7-bundle.mjs +133 -0
- package/scripts/wave-autonomous.mjs +2 -4
- package/scripts/wave-orchestrator/adhoc.mjs +32 -11
- package/scripts/wave-orchestrator/artifact-schemas.mjs +232 -0
- package/scripts/wave-orchestrator/autonomous.mjs +27 -6
- package/scripts/wave-orchestrator/benchmark-cases.mjs +374 -0
- package/scripts/wave-orchestrator/benchmark-external.mjs +1384 -0
- package/scripts/wave-orchestrator/benchmark.mjs +972 -0
- package/scripts/wave-orchestrator/clarification-triage.mjs +78 -12
- package/scripts/wave-orchestrator/config.mjs +175 -0
- package/scripts/wave-orchestrator/control-cli.mjs +1123 -0
- package/scripts/wave-orchestrator/control-plane.mjs +697 -0
- package/scripts/wave-orchestrator/coord-cli.mjs +360 -2
- package/scripts/wave-orchestrator/coordination-store.mjs +211 -9
- package/scripts/wave-orchestrator/coordination.mjs +84 -0
- package/scripts/wave-orchestrator/dashboard-renderer.mjs +38 -3
- package/scripts/wave-orchestrator/dashboard-state.mjs +22 -0
- package/scripts/wave-orchestrator/evals.mjs +23 -0
- package/scripts/wave-orchestrator/executors.mjs +3 -2
- package/scripts/wave-orchestrator/feedback.mjs +55 -0
- package/scripts/wave-orchestrator/install.mjs +253 -26
- package/scripts/wave-orchestrator/launcher-closure.mjs +4 -1
- package/scripts/wave-orchestrator/launcher-runtime.mjs +24 -21
- package/scripts/wave-orchestrator/launcher.mjs +800 -35
- package/scripts/wave-orchestrator/package-update-notice.mjs +230 -0
- package/scripts/wave-orchestrator/package-version.mjs +32 -0
- package/scripts/wave-orchestrator/planner-context.mjs +75 -0
- package/scripts/wave-orchestrator/planner.mjs +2270 -136
- package/scripts/wave-orchestrator/proof-cli.mjs +195 -0
- package/scripts/wave-orchestrator/proof-registry.mjs +317 -0
- package/scripts/wave-orchestrator/replay.mjs +10 -4
- package/scripts/wave-orchestrator/retry-cli.mjs +184 -0
- package/scripts/wave-orchestrator/retry-control.mjs +225 -0
- package/scripts/wave-orchestrator/shared.mjs +26 -0
- package/scripts/wave-orchestrator/swe-bench-pro-task.mjs +1004 -0
- package/scripts/wave-orchestrator/traces.mjs +157 -2
- package/scripts/wave-orchestrator/wave-control-client.mjs +532 -0
- package/scripts/wave-orchestrator/wave-control-schema.mjs +309 -0
- package/scripts/wave-orchestrator/wave-files.mjs +17 -5
- package/scripts/wave.mjs +39 -2
- package/skills/repo-coding-rules/SKILL.md +1 -0
- package/skills/role-cont-eval/SKILL.md +1 -0
- package/skills/role-cont-qa/SKILL.md +13 -6
- package/skills/role-deploy/SKILL.md +1 -0
- package/skills/role-documentation/SKILL.md +4 -0
- package/skills/role-implementation/SKILL.md +4 -0
- package/skills/role-infra/SKILL.md +2 -1
- package/skills/role-integration/SKILL.md +15 -8
- package/skills/role-planner/SKILL.md +39 -0
- package/skills/role-planner/skill.json +21 -0
- package/skills/role-research/SKILL.md +1 -0
- package/skills/role-security/SKILL.md +2 -2
- package/skills/runtime-claude/SKILL.md +2 -1
- package/skills/runtime-codex/SKILL.md +1 -0
- package/skills/runtime-local/SKILL.md +2 -0
- package/skills/runtime-opencode/SKILL.md +1 -0
- package/skills/wave-core/SKILL.md +25 -6
- package/skills/wave-core/references/marker-syntax.md +16 -8
- package/wave.config.json +45 -0
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
truncate,
|
|
22
22
|
writeJsonAtomic,
|
|
23
23
|
} from "./shared.mjs";
|
|
24
|
+
import { safeQueueWaveControlEvent } from "./wave-control-client.mjs";
|
|
24
25
|
|
|
25
26
|
function sanitizeToken(value) {
|
|
26
27
|
const token = String(value || "")
|
|
@@ -59,6 +60,7 @@ export function createFeedbackRequest({
|
|
|
59
60
|
orchestratorId,
|
|
60
61
|
question,
|
|
61
62
|
context,
|
|
63
|
+
recordTelemetry = false,
|
|
62
64
|
}) {
|
|
63
65
|
ensureDirectory(feedbackRequestsDir);
|
|
64
66
|
const requestId = buildRequestId({ lane, wave, agentId });
|
|
@@ -83,6 +85,31 @@ export function createFeedbackRequest({
|
|
|
83
85
|
}
|
|
84
86
|
writeJsonAtomic(filePath, payload);
|
|
85
87
|
});
|
|
88
|
+
if (recordTelemetry) {
|
|
89
|
+
try {
|
|
90
|
+
const lanePaths = buildLanePaths(lane);
|
|
91
|
+
safeQueueWaveControlEvent(lanePaths, {
|
|
92
|
+
category: "feedback",
|
|
93
|
+
entityType: "human_input",
|
|
94
|
+
entityId: requestId,
|
|
95
|
+
action: "requested",
|
|
96
|
+
source: "orchestrator",
|
|
97
|
+
actor: orchestratorId || "orchestrator",
|
|
98
|
+
recordedAt: now,
|
|
99
|
+
identity: {
|
|
100
|
+
lane,
|
|
101
|
+
wave,
|
|
102
|
+
agentId,
|
|
103
|
+
runKind: lanePaths.runKind,
|
|
104
|
+
runId: lanePaths.runId,
|
|
105
|
+
},
|
|
106
|
+
tags: ["feedback", "human-input"],
|
|
107
|
+
data: payload,
|
|
108
|
+
});
|
|
109
|
+
} catch {
|
|
110
|
+
// Best-effort telemetry only.
|
|
111
|
+
}
|
|
112
|
+
}
|
|
86
113
|
return { requestId, filePath, payload };
|
|
87
114
|
}
|
|
88
115
|
|
|
@@ -93,6 +120,7 @@ export function answerFeedbackRequest({
|
|
|
93
120
|
response,
|
|
94
121
|
operator = "human-operator",
|
|
95
122
|
force = false,
|
|
123
|
+
recordTelemetry = false,
|
|
96
124
|
}) {
|
|
97
125
|
const lockPath = path.join(feedbackStateDir, "requests.lock");
|
|
98
126
|
let answeredPayload = null;
|
|
@@ -117,6 +145,31 @@ export function answerFeedbackRequest({
|
|
|
117
145
|
};
|
|
118
146
|
writeJsonAtomic(filePath, answeredPayload);
|
|
119
147
|
});
|
|
148
|
+
if (recordTelemetry) {
|
|
149
|
+
try {
|
|
150
|
+
const lanePaths = buildLanePaths(answeredPayload?.lane || DEFAULT_WAVE_LANE);
|
|
151
|
+
safeQueueWaveControlEvent(lanePaths, {
|
|
152
|
+
category: "feedback",
|
|
153
|
+
entityType: "human_input",
|
|
154
|
+
entityId: answeredPayload.id,
|
|
155
|
+
action: "answered",
|
|
156
|
+
source: "operator",
|
|
157
|
+
actor: operator,
|
|
158
|
+
recordedAt: answeredPayload?.updatedAt || toIsoTimestamp(),
|
|
159
|
+
identity: {
|
|
160
|
+
lane: answeredPayload?.lane || DEFAULT_WAVE_LANE,
|
|
161
|
+
wave: answeredPayload?.wave ?? null,
|
|
162
|
+
agentId: answeredPayload?.agentId || null,
|
|
163
|
+
runKind: lanePaths.runKind,
|
|
164
|
+
runId: lanePaths.runId,
|
|
165
|
+
},
|
|
166
|
+
tags: ["feedback", "human-input", "answered"],
|
|
167
|
+
data: answeredPayload,
|
|
168
|
+
});
|
|
169
|
+
} catch {
|
|
170
|
+
// Best-effort telemetry only.
|
|
171
|
+
}
|
|
172
|
+
}
|
|
120
173
|
return answeredPayload;
|
|
121
174
|
}
|
|
122
175
|
|
|
@@ -292,6 +345,7 @@ export async function runFeedbackCli(argv) {
|
|
|
292
345
|
orchestratorId: options.orchestratorId,
|
|
293
346
|
question: options.question,
|
|
294
347
|
context: options.context,
|
|
348
|
+
recordTelemetry: true,
|
|
295
349
|
});
|
|
296
350
|
console.log(`[wave-human-feedback] created ${result.requestId}`);
|
|
297
351
|
console.log(`file: ${path.relative(REPO_ROOT, result.filePath)}`);
|
|
@@ -316,6 +370,7 @@ export async function runFeedbackCli(argv) {
|
|
|
316
370
|
response: options.response,
|
|
317
371
|
operator: options.operator,
|
|
318
372
|
force: options.force,
|
|
373
|
+
recordTelemetry: true,
|
|
319
374
|
});
|
|
320
375
|
console.log(`[wave-human-feedback] answered ${options.id}`);
|
|
321
376
|
return;
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
3
4
|
import {
|
|
4
5
|
applyContext7SelectionsToWave,
|
|
5
6
|
loadContext7BundleIndex,
|
|
6
7
|
} from "./context7.mjs";
|
|
8
|
+
import {
|
|
9
|
+
PLANNER_CONTEXT7_TEMPLATE_PATHS,
|
|
10
|
+
} from "./planner-context.mjs";
|
|
7
11
|
import { buildLanePaths, ensureDirectory, PACKAGE_ROOT, readJsonOrNull, REPO_ROOT, writeJsonAtomic } from "./shared.mjs";
|
|
12
|
+
import { fetchLatestPackageVersion } from "./package-update-notice.mjs";
|
|
13
|
+
import {
|
|
14
|
+
compareVersions,
|
|
15
|
+
readInstalledPackageMetadata,
|
|
16
|
+
WAVE_PACKAGE_NAME,
|
|
17
|
+
} from "./package-version.mjs";
|
|
8
18
|
import { loadWaveConfig } from "./config.mjs";
|
|
9
19
|
import { applyExecutorSelectionsToWave, parseWaveFiles, validateWaveDefinition } from "./wave-files.mjs";
|
|
10
20
|
import { validateLaneSkillConfiguration } from "./skills.mjs";
|
|
@@ -14,7 +24,7 @@ export const INSTALL_STATE_DIR = ".wave";
|
|
|
14
24
|
export const INSTALL_STATE_PATH = path.join(REPO_ROOT, INSTALL_STATE_DIR, "install-state.json");
|
|
15
25
|
export const UPGRADE_HISTORY_DIR = path.join(REPO_ROOT, INSTALL_STATE_DIR, "upgrade-history");
|
|
16
26
|
export const CHANGELOG_MANIFEST_PATH = path.join(PACKAGE_ROOT, "releases", "manifest.json");
|
|
17
|
-
export const
|
|
27
|
+
export const WORKSPACE_PACKAGE_JSON_PATH = path.join(REPO_ROOT, "package.json");
|
|
18
28
|
export const STARTER_TEMPLATE_PATHS = [
|
|
19
29
|
"wave.config.json",
|
|
20
30
|
"docs/README.md",
|
|
@@ -22,6 +32,7 @@ export const STARTER_TEMPLATE_PATHS = [
|
|
|
22
32
|
"docs/agents/wave-cont-qa-role.md",
|
|
23
33
|
"docs/agents/wave-cont-eval-role.md",
|
|
24
34
|
"docs/agents/wave-integration-role.md",
|
|
35
|
+
"docs/agents/wave-planner-role.md",
|
|
25
36
|
"docs/agents/wave-security-role.md",
|
|
26
37
|
"docs/concepts/context7-vs-skills.md",
|
|
27
38
|
"docs/concepts/operating-modes.md",
|
|
@@ -29,23 +40,48 @@ export const STARTER_TEMPLATE_PATHS = [
|
|
|
29
40
|
"docs/concepts/what-is-a-wave.md",
|
|
30
41
|
"docs/context7/bundles.json",
|
|
31
42
|
"docs/evals/benchmark-catalog.json",
|
|
43
|
+
"docs/evals/external-benchmarks.json",
|
|
44
|
+
"docs/evals/external-command-config.sample.json",
|
|
45
|
+
"docs/evals/external-command-config.swe-bench-pro.json",
|
|
46
|
+
"docs/evals/wave-benchmark-program.md",
|
|
47
|
+
"docs/evals/pilots/README.md",
|
|
48
|
+
"docs/evals/pilots/swe-bench-pro-public-pilot.json",
|
|
49
|
+
"docs/evals/pilots/swe-bench-pro-public-full-wave-review-10.json",
|
|
50
|
+
"docs/evals/arm-templates/README.md",
|
|
51
|
+
"docs/evals/arm-templates/single-agent.json",
|
|
52
|
+
"docs/evals/arm-templates/full-wave.json",
|
|
53
|
+
"docs/evals/cases/README.md",
|
|
54
|
+
"docs/evals/cases/wave-hidden-profile-private-evidence.json",
|
|
55
|
+
"docs/evals/cases/wave-premature-closure-guard.json",
|
|
56
|
+
"docs/evals/cases/wave-silo-cross-agent-state.json",
|
|
57
|
+
"docs/evals/cases/wave-blackboard-inbox-targeting.json",
|
|
58
|
+
"docs/evals/cases/wave-contradiction-conflict.json",
|
|
59
|
+
"docs/evals/cases/wave-simultaneous-lockstep.json",
|
|
60
|
+
"docs/evals/cases/wave-expert-routing-preservation.json",
|
|
32
61
|
"docs/guides/planner.md",
|
|
33
62
|
"docs/guides/terminal-surfaces.md",
|
|
34
63
|
"docs/plans/component-cutover-matrix.json",
|
|
35
64
|
"docs/plans/component-cutover-matrix.md",
|
|
36
65
|
"docs/plans/context7-wave-orchestrator.md",
|
|
37
66
|
"docs/plans/current-state.md",
|
|
67
|
+
"docs/plans/examples/wave-example-live-proof.md",
|
|
38
68
|
"docs/plans/master-plan.md",
|
|
39
69
|
"docs/plans/migration.md",
|
|
40
70
|
"docs/plans/wave-orchestrator.md",
|
|
41
71
|
"docs/plans/waves/wave-0.md",
|
|
72
|
+
"docs/reference/live-proof-waves.md",
|
|
42
73
|
"docs/reference/repository-guidance.md",
|
|
74
|
+
"docs/reference/sample-waves.md",
|
|
43
75
|
"docs/reference/skills.md",
|
|
76
|
+
"docs/reference/wave-planning-lessons.md",
|
|
44
77
|
"docs/reference/runtime-config/README.md",
|
|
45
78
|
"docs/reference/runtime-config/codex.md",
|
|
46
79
|
"docs/reference/runtime-config/claude.md",
|
|
47
80
|
"docs/reference/runtime-config/opencode.md",
|
|
81
|
+
"docs/research/coordination-failure-review.md",
|
|
48
82
|
"docs/research/agent-context-sources.md",
|
|
83
|
+
"docs/plans/examples/wave-benchmark-improvement.md",
|
|
84
|
+
...PLANNER_CONTEXT7_TEMPLATE_PATHS,
|
|
49
85
|
];
|
|
50
86
|
const REQUIRED_GITIGNORE_ENTRIES = [
|
|
51
87
|
".tmp/",
|
|
@@ -69,11 +105,7 @@ function collectDeclaredDeployKinds(waves = []) {
|
|
|
69
105
|
}
|
|
70
106
|
|
|
71
107
|
function packageMetadata() {
|
|
72
|
-
|
|
73
|
-
if (!payload?.name || !payload?.version) {
|
|
74
|
-
throw new Error(`Invalid package metadata: ${PACKAGE_METADATA_PATH}`);
|
|
75
|
-
}
|
|
76
|
-
return payload;
|
|
108
|
+
return readInstalledPackageMetadata();
|
|
77
109
|
}
|
|
78
110
|
|
|
79
111
|
function readInstallState() {
|
|
@@ -149,25 +181,6 @@ function nextHistoryRecord(existingState, entry) {
|
|
|
149
181
|
return history;
|
|
150
182
|
}
|
|
151
183
|
|
|
152
|
-
function normalizeVersionParts(version) {
|
|
153
|
-
return String(version || "")
|
|
154
|
-
.split(".")
|
|
155
|
-
.map((part) => Number.parseInt(part.replace(/[^0-9].*$/, ""), 10) || 0);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function compareVersions(a, b) {
|
|
159
|
-
const left = normalizeVersionParts(a);
|
|
160
|
-
const right = normalizeVersionParts(b);
|
|
161
|
-
const length = Math.max(left.length, right.length);
|
|
162
|
-
for (let index = 0; index < length; index += 1) {
|
|
163
|
-
const diff = (left[index] || 0) - (right[index] || 0);
|
|
164
|
-
if (diff !== 0) {
|
|
165
|
-
return diff;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return 0;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
184
|
function readChangelogManifest() {
|
|
172
185
|
const payload = readJsonOrNull(CHANGELOG_MANIFEST_PATH);
|
|
173
186
|
if (!payload?.releases || !Array.isArray(payload.releases)) {
|
|
@@ -249,6 +262,19 @@ function gitignoreWarnings() {
|
|
|
249
262
|
);
|
|
250
263
|
}
|
|
251
264
|
|
|
265
|
+
function plannerRequiredPaths() {
|
|
266
|
+
return Array.from(
|
|
267
|
+
new Set(
|
|
268
|
+
[
|
|
269
|
+
"docs/agents/wave-planner-role.md",
|
|
270
|
+
"docs/reference/wave-planning-lessons.md",
|
|
271
|
+
"skills/role-planner/SKILL.md",
|
|
272
|
+
...PLANNER_CONTEXT7_TEMPLATE_PATHS,
|
|
273
|
+
].filter(Boolean),
|
|
274
|
+
),
|
|
275
|
+
).sort();
|
|
276
|
+
}
|
|
277
|
+
|
|
252
278
|
export function runDoctor() {
|
|
253
279
|
const errors = [];
|
|
254
280
|
const warnings = [];
|
|
@@ -293,9 +319,21 @@ export function runDoctor() {
|
|
|
293
319
|
errors.push(`Missing required Wave file: ${relPath}`);
|
|
294
320
|
}
|
|
295
321
|
}
|
|
322
|
+
const context7BundleIndex = loadContext7BundleIndex(lanePaths.context7BundleIndexPath);
|
|
323
|
+
const plannerPaths = plannerRequiredPaths();
|
|
324
|
+
for (const relPath of plannerPaths) {
|
|
325
|
+
if (!fs.existsSync(path.join(REPO_ROOT, relPath))) {
|
|
326
|
+
errors.push(`Missing planner file: ${relPath}`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const plannerBundleId = String(config.planner?.agentic?.context7Bundle || "").trim();
|
|
330
|
+
if (plannerBundleId && !context7BundleIndex.bundles[plannerBundleId]) {
|
|
331
|
+
errors.push(
|
|
332
|
+
`planner.agentic.context7Bundle references unknown bundle "${plannerBundleId}".`,
|
|
333
|
+
);
|
|
334
|
+
}
|
|
296
335
|
let parsedWaves = [];
|
|
297
336
|
if (fs.existsSync(lanePaths.wavesDir)) {
|
|
298
|
-
const context7BundleIndex = loadContext7BundleIndex(lanePaths.context7BundleIndexPath);
|
|
299
337
|
parsedWaves = parseWaveFiles(lanePaths.wavesDir, { laneProfile: lanePaths.laneProfile })
|
|
300
338
|
.map((wave) =>
|
|
301
339
|
applyExecutorSelectionsToWave(wave, {
|
|
@@ -478,6 +516,186 @@ export function upgradeWorkspace() {
|
|
|
478
516
|
};
|
|
479
517
|
}
|
|
480
518
|
|
|
519
|
+
function readWorkspacePackageManifest(workspaceRoot = REPO_ROOT) {
|
|
520
|
+
const payload = readJsonOrNull(path.join(workspaceRoot, "package.json"));
|
|
521
|
+
if (!payload || typeof payload !== "object") {
|
|
522
|
+
throw new Error(`Missing package.json at ${path.join(workspaceRoot, "package.json")}`);
|
|
523
|
+
}
|
|
524
|
+
return payload;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
function readInstallStateForWorkspace(workspaceRoot = REPO_ROOT) {
|
|
528
|
+
const payload = readJsonOrNull(path.join(workspaceRoot, INSTALL_STATE_DIR, "install-state.json"));
|
|
529
|
+
return payload && typeof payload === "object" ? payload : null;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function parsePackageManagerId(value) {
|
|
533
|
+
const normalized = String(value || "")
|
|
534
|
+
.trim()
|
|
535
|
+
.toLowerCase();
|
|
536
|
+
if (!normalized) {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
if (normalized.startsWith("pnpm@")) {
|
|
540
|
+
return "pnpm";
|
|
541
|
+
}
|
|
542
|
+
if (normalized.startsWith("npm@")) {
|
|
543
|
+
return "npm";
|
|
544
|
+
}
|
|
545
|
+
if (normalized.startsWith("yarn@")) {
|
|
546
|
+
return "yarn";
|
|
547
|
+
}
|
|
548
|
+
if (normalized.startsWith("bun@")) {
|
|
549
|
+
return "bun";
|
|
550
|
+
}
|
|
551
|
+
return null;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
export function detectWorkspacePackageManager(workspaceRoot = REPO_ROOT) {
|
|
555
|
+
const manifest = readWorkspacePackageManifest(workspaceRoot);
|
|
556
|
+
const packageManagerFromManifest = parsePackageManagerId(manifest.packageManager);
|
|
557
|
+
if (packageManagerFromManifest) {
|
|
558
|
+
return {
|
|
559
|
+
id: packageManagerFromManifest,
|
|
560
|
+
source: "packageManager",
|
|
561
|
+
raw: manifest.packageManager,
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
for (const [fileName, id] of [
|
|
565
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
566
|
+
["package-lock.json", "npm"],
|
|
567
|
+
["npm-shrinkwrap.json", "npm"],
|
|
568
|
+
["yarn.lock", "yarn"],
|
|
569
|
+
["bun.lockb", "bun"],
|
|
570
|
+
["bun.lock", "bun"],
|
|
571
|
+
]) {
|
|
572
|
+
if (fs.existsSync(path.join(workspaceRoot, fileName))) {
|
|
573
|
+
return {
|
|
574
|
+
id,
|
|
575
|
+
source: "lockfile",
|
|
576
|
+
raw: fileName,
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return {
|
|
581
|
+
id: "npm",
|
|
582
|
+
source: "default",
|
|
583
|
+
raw: null,
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
function packageManagerCommands(managerId, packageName = WAVE_PACKAGE_NAME) {
|
|
588
|
+
if (managerId === "pnpm") {
|
|
589
|
+
return {
|
|
590
|
+
install: ["pnpm", ["add", "-D", `${packageName}@latest`]],
|
|
591
|
+
execWave: (args) => ["pnpm", ["exec", "wave", ...args]],
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
if (managerId === "npm") {
|
|
595
|
+
return {
|
|
596
|
+
install: ["npm", ["install", "--save-dev", `${packageName}@latest`]],
|
|
597
|
+
execWave: (args) => ["npm", ["exec", "--", "wave", ...args]],
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
if (managerId === "yarn") {
|
|
601
|
+
return {
|
|
602
|
+
install: ["yarn", ["add", "-D", `${packageName}@latest`]],
|
|
603
|
+
execWave: (args) => ["yarn", ["exec", "wave", ...args]],
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
if (managerId === "bun") {
|
|
607
|
+
return {
|
|
608
|
+
install: ["bun", ["add", "-d", `${packageName}@latest`]],
|
|
609
|
+
execWave: (args) => ["bun", ["x", "wave", ...args]],
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
throw new Error(`Unsupported package manager: ${managerId}`);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
function runCommandOrThrow(command, args, options = {}) {
|
|
616
|
+
const spawnImpl = options.spawnImpl || spawnSync;
|
|
617
|
+
const result = spawnImpl(command, args, {
|
|
618
|
+
cwd: options.workspaceRoot || REPO_ROOT,
|
|
619
|
+
stdio: options.stdio || "inherit",
|
|
620
|
+
env: options.env || process.env,
|
|
621
|
+
encoding: "utf8",
|
|
622
|
+
});
|
|
623
|
+
const status = Number.isInteger(result?.status) ? result.status : 1;
|
|
624
|
+
if (status !== 0) {
|
|
625
|
+
throw new Error(`${command} ${args.join(" ")} failed with status ${status}`);
|
|
626
|
+
}
|
|
627
|
+
return result;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
export async function selfUpdateWorkspace(options = {}) {
|
|
631
|
+
const workspaceRoot = options.workspaceRoot || REPO_ROOT;
|
|
632
|
+
const metadata = options.packageMetadata || packageMetadata();
|
|
633
|
+
const installState = readInstallStateForWorkspace(workspaceRoot);
|
|
634
|
+
const packageManager = detectWorkspacePackageManager(workspaceRoot);
|
|
635
|
+
const commands = packageManagerCommands(packageManager.id, metadata.name || WAVE_PACKAGE_NAME);
|
|
636
|
+
const emit = options.emit || console.log;
|
|
637
|
+
let latestVersion = null;
|
|
638
|
+
|
|
639
|
+
try {
|
|
640
|
+
latestVersion = await fetchLatestPackageVersion(metadata.name || WAVE_PACKAGE_NAME, {
|
|
641
|
+
fetchImpl: options.fetchImpl,
|
|
642
|
+
timeoutMs: options.timeoutMs,
|
|
643
|
+
});
|
|
644
|
+
} catch {
|
|
645
|
+
latestVersion = null;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
const currentVersion = String(metadata.version || "").trim();
|
|
649
|
+
const recordedVersion = String(installState?.installedVersion || "").trim() || null;
|
|
650
|
+
const needsUpgradeOnly = recordedVersion && compareVersions(currentVersion, recordedVersion) !== 0;
|
|
651
|
+
|
|
652
|
+
emit(`[wave:self-update] package_manager=${packageManager.id}`);
|
|
653
|
+
|
|
654
|
+
if (latestVersion && compareVersions(latestVersion, currentVersion) <= 0) {
|
|
655
|
+
if (!needsUpgradeOnly) {
|
|
656
|
+
emit(`[wave:self-update] ${metadata.name} is already current at ${currentVersion}.`);
|
|
657
|
+
return {
|
|
658
|
+
mode: "already-current",
|
|
659
|
+
packageManager: packageManager.id,
|
|
660
|
+
currentVersion,
|
|
661
|
+
latestVersion,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
emit(
|
|
665
|
+
`[wave:self-update] dependency is already at ${currentVersion}; recording workspace upgrade state.`,
|
|
666
|
+
);
|
|
667
|
+
const [upgradeCommand, upgradeArgs] = commands.execWave(["upgrade"]);
|
|
668
|
+
runCommandOrThrow(upgradeCommand, upgradeArgs, options);
|
|
669
|
+
return {
|
|
670
|
+
mode: "upgrade-only",
|
|
671
|
+
packageManager: packageManager.id,
|
|
672
|
+
currentVersion,
|
|
673
|
+
latestVersion,
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
emit(
|
|
678
|
+
`[wave:self-update] updating ${metadata.name} from ${currentVersion}${latestVersion ? ` to ${latestVersion}` : " to the latest published version"}.`,
|
|
679
|
+
);
|
|
680
|
+
const [installCommand, installArgs] = commands.install;
|
|
681
|
+
runCommandOrThrow(installCommand, installArgs, options);
|
|
682
|
+
|
|
683
|
+
emit("[wave:self-update] release notes since the recorded install:");
|
|
684
|
+
const [changelogCommand, changelogArgs] = commands.execWave(["changelog", "--since-installed"]);
|
|
685
|
+
runCommandOrThrow(changelogCommand, changelogArgs, options);
|
|
686
|
+
|
|
687
|
+
emit("[wave:self-update] recording install-state and upgrade report:");
|
|
688
|
+
const [upgradeCommand, upgradeArgs] = commands.execWave(["upgrade"]);
|
|
689
|
+
runCommandOrThrow(upgradeCommand, upgradeArgs, options);
|
|
690
|
+
|
|
691
|
+
return {
|
|
692
|
+
mode: "updated",
|
|
693
|
+
packageManager: packageManager.id,
|
|
694
|
+
currentVersion,
|
|
695
|
+
latestVersion,
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
|
|
481
699
|
function printJson(payload) {
|
|
482
700
|
console.log(JSON.stringify(payload, null, 2));
|
|
483
701
|
}
|
|
@@ -486,6 +704,7 @@ function printHelp() {
|
|
|
486
704
|
console.log(`Usage:
|
|
487
705
|
wave init [--adopt-existing] [--json]
|
|
488
706
|
wave upgrade [--json]
|
|
707
|
+
wave self-update
|
|
489
708
|
wave changelog [--since-installed] [--json]
|
|
490
709
|
wave doctor [--json]
|
|
491
710
|
`);
|
|
@@ -562,6 +781,14 @@ export async function runInstallCli(argv) {
|
|
|
562
781
|
return;
|
|
563
782
|
}
|
|
564
783
|
|
|
784
|
+
if (subcommand === "self-update") {
|
|
785
|
+
if (options.json) {
|
|
786
|
+
throw new Error("`wave self-update` does not support --json.");
|
|
787
|
+
}
|
|
788
|
+
await selfUpdateWorkspace();
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
|
|
565
792
|
if (subcommand === "changelog") {
|
|
566
793
|
const result = readChangelog({ sinceInstalled: options.sinceInstalled });
|
|
567
794
|
if (options.json) {
|
|
@@ -201,7 +201,7 @@ export async function runClosureSweepPhase({
|
|
|
201
201
|
refreshWaveDashboardAgentStates(dashboardState, [runInfo], pendingAgentIds, (event) =>
|
|
202
202
|
recordCombinedEvent(event),
|
|
203
203
|
);
|
|
204
|
-
monitorWaveHumanFeedbackFn({
|
|
204
|
+
const feedbackChanged = monitorWaveHumanFeedbackFn({
|
|
205
205
|
lanePaths,
|
|
206
206
|
waveNumber: wave.wave,
|
|
207
207
|
agentRuns: [runInfo],
|
|
@@ -211,6 +211,9 @@ export async function runClosureSweepPhase({
|
|
|
211
211
|
recordCombinedEvent,
|
|
212
212
|
appendCoordination,
|
|
213
213
|
});
|
|
214
|
+
if (feedbackChanged) {
|
|
215
|
+
refreshDerivedState?.(dashboardState?.attempt || 0);
|
|
216
|
+
}
|
|
214
217
|
updateWaveDashboardMessageBoard(dashboardState, runInfo.messageBoardPath);
|
|
215
218
|
flushDashboards();
|
|
216
219
|
},
|
|
@@ -69,6 +69,7 @@ export async function launchAgentSession(lanePaths, params, { runTmuxFn }) {
|
|
|
69
69
|
sharedSummaryText,
|
|
70
70
|
inboxPath,
|
|
71
71
|
inboxText,
|
|
72
|
+
promptOverride = "",
|
|
72
73
|
orchestratorId,
|
|
73
74
|
agentRateLimitRetries,
|
|
74
75
|
agentRateLimitBaseDelaySeconds,
|
|
@@ -101,27 +102,29 @@ export async function launchAgentSession(lanePaths, params, { runTmuxFn }) {
|
|
|
101
102
|
artifacts: skillArtifacts,
|
|
102
103
|
};
|
|
103
104
|
}
|
|
104
|
-
const prompt =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
105
|
+
const prompt =
|
|
106
|
+
String(promptOverride || "").trim() ||
|
|
107
|
+
buildExecutionPrompt({
|
|
108
|
+
lane: lanePaths.lane,
|
|
109
|
+
wave,
|
|
110
|
+
agent,
|
|
111
|
+
orchestratorId,
|
|
112
|
+
messageBoardPath,
|
|
113
|
+
messageBoardSnapshot,
|
|
114
|
+
sharedSummaryPath,
|
|
115
|
+
sharedSummaryText,
|
|
116
|
+
inboxPath,
|
|
117
|
+
inboxText,
|
|
118
|
+
context7,
|
|
119
|
+
componentPromotions: resolvedWaveDefinition.componentPromotions,
|
|
120
|
+
evalTargets: resolvedWaveDefinition.evalTargets,
|
|
121
|
+
benchmarkCatalogPath: lanePaths.laneProfile?.paths?.benchmarkCatalogPath,
|
|
122
|
+
sharedPlanDocs: lanePaths.sharedPlanDocs,
|
|
123
|
+
contQaAgentId: lanePaths.contQaAgentId,
|
|
124
|
+
contEvalAgentId: lanePaths.contEvalAgentId,
|
|
125
|
+
integrationAgentId: lanePaths.integrationAgentId,
|
|
126
|
+
documentationAgentId: lanePaths.documentationAgentId,
|
|
127
|
+
});
|
|
125
128
|
const promptHash = hashAgentPromptFingerprint(agent);
|
|
126
129
|
fs.writeFileSync(promptPath, `${prompt}\n`, "utf8");
|
|
127
130
|
const launchSpec = buildExecutorLaunchSpec({
|