@chllming/wave-orchestration 0.8.4 → 0.8.6
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 -1
- package/README.md +31 -13
- package/docs/README.md +4 -0
- package/docs/agents/wave-design-role.md +47 -0
- package/docs/concepts/what-is-a-wave.md +11 -7
- package/docs/context7/bundles.json +19 -20
- package/docs/context7/planner-agent/README.md +4 -1
- package/docs/guides/author-and-run-waves.md +27 -0
- package/docs/guides/planner.md +46 -0
- package/docs/guides/signal-wrappers.md +165 -0
- package/docs/guides/terminal-surfaces.md +13 -0
- package/docs/plans/context7-wave-orchestrator.md +24 -7
- package/docs/plans/current-state.md +10 -2
- package/docs/plans/end-state-architecture.md +22 -5
- package/docs/plans/examples/wave-example-design-handoff.md +262 -0
- package/docs/plans/examples/wave-example-live-proof.md +1 -1
- package/docs/plans/migration.md +301 -75
- package/docs/plans/wave-orchestrator.md +16 -3
- package/docs/reference/cli-reference.md +22 -1
- package/docs/reference/npmjs-trusted-publishing.md +2 -2
- package/docs/reference/sample-waves.md +14 -7
- package/docs/reference/skills.md +18 -0
- package/docs/reference/wave-control.md +2 -0
- package/package.json +1 -1
- package/releases/manifest.json +38 -0
- package/scripts/context7-api-check.sh +57 -13
- package/scripts/wave-orchestrator/agent-state.mjs +64 -0
- package/scripts/wave-orchestrator/config.mjs +5 -0
- package/scripts/wave-orchestrator/control-cli.mjs +19 -0
- package/scripts/wave-orchestrator/coordination.mjs +77 -1
- package/scripts/wave-orchestrator/gate-engine.mjs +106 -2
- package/scripts/wave-orchestrator/install.mjs +5 -0
- package/scripts/wave-orchestrator/launcher-runtime.mjs +18 -1
- package/scripts/wave-orchestrator/launcher.mjs +75 -1
- package/scripts/wave-orchestrator/ledger.mjs +56 -27
- package/scripts/wave-orchestrator/local-executor.mjs +37 -0
- package/scripts/wave-orchestrator/planner.mjs +24 -4
- package/scripts/wave-orchestrator/result-envelope.mjs +32 -1
- package/scripts/wave-orchestrator/retry-control.mjs +17 -2
- package/scripts/wave-orchestrator/retry-engine.mjs +85 -0
- package/scripts/wave-orchestrator/role-helpers.mjs +73 -1
- package/scripts/wave-orchestrator/session-supervisor.mjs +113 -0
- package/scripts/wave-orchestrator/shared.mjs +2 -0
- package/scripts/wave-orchestrator/signals.mjs +681 -0
- package/scripts/wave-orchestrator/skills.mjs +1 -0
- package/scripts/wave-orchestrator/task-entity.mjs +65 -45
- package/scripts/wave-orchestrator/wave-control-schema.mjs +2 -0
- package/scripts/wave-orchestrator/wave-files.mjs +85 -1
- package/scripts/wave-orchestrator/wave-state-reducer.mjs +24 -7
- package/scripts/wave-status.sh +200 -0
- package/scripts/wave-watch.sh +200 -0
- package/skills/README.md +10 -0
- package/skills/role-design/SKILL.md +50 -0
- package/skills/role-design/skill.json +36 -0
- package/skills/signal-hygiene/SKILL.md +51 -0
- package/skills/signal-hygiene/skill.json +20 -0
- package/skills/tui-design/SKILL.md +77 -0
- package/skills/tui-design/references/tui-design.md +259 -0
- package/skills/tui-design/skill.json +36 -0
- package/wave.config.json +15 -1
|
@@ -96,7 +96,7 @@ Unified operator control surface. Preferred over legacy `wave coord`, `wave retr
|
|
|
96
96
|
|
|
97
97
|
### wave control status
|
|
98
98
|
|
|
99
|
-
Read-only view: blocking edges, logical agent state, tasks, dependencies, rerun intent, proof bundles, and
|
|
99
|
+
Read-only view: blocking edges, logical agent state, tasks, dependencies, rerun intent, proof bundles, next timers, and derived wave or agent signal snapshots.
|
|
100
100
|
|
|
101
101
|
When a launcher attempt is already running, `wave control status` treats that active attempt as the authoritative current fan-out. Older relaunch plans or unrelated closure blockers remain visible in the payload, but they do not override the live attempt view.
|
|
102
102
|
|
|
@@ -104,6 +104,15 @@ When a launcher attempt is already running, `wave control status` treats that ac
|
|
|
104
104
|
wave control status --lane <lane> --wave <n> [--agent <id>] [--run <id>] [--json]
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
+
The JSON payload now includes:
|
|
108
|
+
|
|
109
|
+
- `signals.wave`
|
|
110
|
+
Versioned wave-level signal state for wrappers and external operators.
|
|
111
|
+
- `signals.agents`
|
|
112
|
+
Versioned per-agent signal state, including `shouldWake` plus any observed ack metadata.
|
|
113
|
+
|
|
114
|
+
Starter repos also include `scripts/wave-status.sh` and `scripts/wave-watch.sh` as thin readers over this JSON payload. They use exit `0` for completed, `20` for input-required, `40` for failed, and `30` from `wave-watch.sh --until-change` when the signal changed but the wave stayed active. For the full wrapper contract, read [../guides/signal-wrappers.md](../guides/signal-wrappers.md).
|
|
115
|
+
|
|
107
116
|
### wave control telemetry
|
|
108
117
|
|
|
109
118
|
Inspect and deliver the local Wave Control event queue.
|
|
@@ -534,6 +543,18 @@ wave draft --show-run <run-id>
|
|
|
534
543
|
wave draft --apply-run <run-id>
|
|
535
544
|
```
|
|
536
545
|
|
|
546
|
+
Interactive draft currently offers worker role kinds:
|
|
547
|
+
|
|
548
|
+
- `design`
|
|
549
|
+
- `implementation`
|
|
550
|
+
- `qa`
|
|
551
|
+
- `infra`
|
|
552
|
+
- `deploy`
|
|
553
|
+
- `research`
|
|
554
|
+
- `security`
|
|
555
|
+
|
|
556
|
+
Agentic planner payloads also accept `workerAgents[].roleKind = "design"`. The shipped `0.8.6` surface uses `design-pass` as the default executor profile for that role and typically assigns a packet path like `docs/plans/waves/design/wave-<n>-<agentId>.md`. Interactive draft scaffolds the docs-first default; hybrid design stewards are authored by explicitly adding implementation-owned paths and the normal implementation contract sections.
|
|
557
|
+
|
|
537
558
|
## Ad-Hoc Task Commands
|
|
538
559
|
|
|
539
560
|
**Plan and run ad-hoc tasks:**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This repo now includes a dedicated npmjs publish workflow at [publish-npm.yml](../../.github/workflows/publish-npm.yml).
|
|
4
4
|
|
|
5
|
-
The current `0.8.
|
|
5
|
+
The current `0.8.6` release procedure publishes through a repository Actions secret named `NPM_TOKEN`.
|
|
6
6
|
|
|
7
7
|
## What This Repo Already Does
|
|
8
8
|
|
|
@@ -48,6 +48,6 @@ If this repo later needs private npm dependencies during CI, consider a separate
|
|
|
48
48
|
2. Confirm `NPM_TOKEN` exists in the GitHub repo secrets.
|
|
49
49
|
3. Confirm the package version has been bumped and committed.
|
|
50
50
|
4. Confirm `README.md`, `CHANGELOG.md`, `releases/manifest.json`, and `docs/plans/migration.md` all describe the same release surface.
|
|
51
|
-
5. Push the release commit and release tag, for example `v0.8.
|
|
51
|
+
5. Push the release commit and release tag, for example `v0.8.6`.
|
|
52
52
|
6. Verify both `publish-npm.yml` and `publish-package.yml` start from the tag push.
|
|
53
53
|
7. Verify the npmjs publish completes successfully for the tagged source.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Sample Waves"
|
|
3
|
-
summary: "Showcase-first sample waves that demonstrate the
|
|
3
|
+
summary: "Showcase-first sample waves that demonstrate the shipped 0.8.6 authored surface, including the optional design-role path."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Sample Waves
|
|
7
7
|
|
|
8
|
-
This guide points to showcase-first sample waves that demonstrate the
|
|
8
|
+
This guide points to showcase-first sample waves that demonstrate the shipped `0.8.6` authored Wave surface.
|
|
9
9
|
|
|
10
10
|
The examples are intentionally denser than typical production waves. Their job is to teach the current authoring and runtime surface quickly, not to be the smallest possible launch-ready files.
|
|
11
11
|
|
|
@@ -15,7 +15,10 @@ The examples are intentionally denser than typical production waves. Their job i
|
|
|
15
15
|
Shows what a good `repo-landed` outcome looks like when one promoted component only closes honestly if desired-state records, reconcile-loop substrate, and cluster-view surfaces land together. It emphasizes maturity discipline, explicit deliverables, and shared-plan closure without drifting into `pilot-live` claims.
|
|
16
16
|
|
|
17
17
|
- [Full modern sample wave](../plans/examples/wave-example-live-proof.md)
|
|
18
|
-
Shows the combined `0.8.
|
|
18
|
+
Shows the combined `0.8.6` authored surface in one file: closure roles, `E0`, optional security review, delegated and pinned benchmark targets, richer executor config, `### Skills`, `### Capabilities`, `### Deliverables`, `### Exit contract`, `### Proof artifacts`, sticky retry, deploy environments, and proof-first live-wave structure.
|
|
19
|
+
|
|
20
|
+
- [Optional design-steward handoff wave](../plans/examples/wave-example-design-handoff.md)
|
|
21
|
+
Shows the shipped design-role surface: one pre-implementation design steward publishes a design packet, downstream implementation owners read that packet before coding, and normal closure roles still decide final completion. For terminal or operator-surface work, pair that shape with explicit `tui-design` in the design steward's `### Skills`. For the hybrid variant, explicitly give that same design agent implementation-owned paths and the normal implementation contract sections.
|
|
19
22
|
|
|
20
23
|
## What These Examples Teach
|
|
21
24
|
|
|
@@ -35,10 +38,11 @@ The examples are intentionally denser than typical production waves. Their job i
|
|
|
35
38
|
- sticky retry for proof-bearing owners
|
|
36
39
|
- deploy environments and provider-skill examples
|
|
37
40
|
- infra and deploy-verifier specialist slices
|
|
41
|
+
- optional pre-implementation design packets and design-to-implementation handoff
|
|
38
42
|
|
|
39
43
|
## Feature Coverage Map
|
|
40
44
|
|
|
41
|
-
Together these samples cover the main surfaces added or hardened
|
|
45
|
+
Together these samples cover the main surfaces added or hardened through `0.8.6`:
|
|
42
46
|
|
|
43
47
|
- repo-landed maturity discipline and anti-overclaim framing
|
|
44
48
|
- explicit shared-plan closure for future-wave safety
|
|
@@ -56,6 +60,7 @@ Together these samples cover the main surfaces added or hardened for `0.8.4`:
|
|
|
56
60
|
- proof-first live-wave prompts
|
|
57
61
|
- deploy environments and deploy-kind-aware skills
|
|
58
62
|
- integration, documentation, and cont-QA closure-role structure
|
|
63
|
+
- optional `design` worker role and `design-pass` executor profile
|
|
59
64
|
|
|
60
65
|
## When To Copy Literally Vs Adapt
|
|
61
66
|
|
|
@@ -76,6 +81,7 @@ Adapt more aggressively when:
|
|
|
76
81
|
## How This Example Maps To Other Docs
|
|
77
82
|
|
|
78
83
|
- Use [docs/guides/planner.md](../guides/planner.md) for the planner-generated baseline, then use these samples to see how a human would enrich the generated draft for either repo-landed or proof-first work.
|
|
84
|
+
- Use [Optional design-steward handoff wave](../plans/examples/wave-example-design-handoff.md) when the wave should start with a reusable design packet before implementation begins.
|
|
79
85
|
- Use [docs/evals/README.md](../evals/README.md) with the full modern sample when you need to see delegated and pinned benchmark targets in a real wave.
|
|
80
86
|
- Use [docs/reference/live-proof-waves.md](./live-proof-waves.md) with the full modern sample when you need proof-first authoring for `pilot-live` and above.
|
|
81
87
|
- Use [docs/plans/wave-orchestrator.md](../plans/wave-orchestrator.md) for the operational runbook that explains how the launcher interprets these sections.
|
|
@@ -83,9 +89,10 @@ Adapt more aggressively when:
|
|
|
83
89
|
## Suggested Reading Order
|
|
84
90
|
|
|
85
91
|
1. Start with [High-fidelity repo-landed rollout wave](../plans/examples/wave-example-rollout-fidelity.md) if you want the clearest example of good closure-ready wave fidelity for a repo-only outcome.
|
|
86
|
-
2. Read [Full modern sample wave](../plans/examples/wave-example-live-proof.md) if you want the denser proof-first and eval-heavy surface.
|
|
87
|
-
3. Read [
|
|
88
|
-
4. Read [docs/
|
|
92
|
+
2. Read [Full modern sample wave](../plans/examples/wave-example-live-proof.md) if you want the denser proof-first and eval-heavy `0.8.6` surface.
|
|
93
|
+
3. Read [Optional design-steward handoff wave](../plans/examples/wave-example-design-handoff.md) if the task needs a design packet before implementation fan-out.
|
|
94
|
+
4. Read [docs/evals/README.md](../evals/README.md) if you want more background on benchmark target selection.
|
|
95
|
+
5. Read [docs/reference/live-proof-waves.md](./live-proof-waves.md) if you want more detail on proof-first `pilot-live` authoring.
|
|
89
96
|
|
|
90
97
|
## Why These Examples Live In `docs/plans/examples/`
|
|
91
98
|
|
package/docs/reference/skills.md
CHANGED
|
@@ -109,6 +109,7 @@ Top-level and lane-local skill attachment use the same shape:
|
|
|
109
109
|
"dir": "skills",
|
|
110
110
|
"base": ["wave-core", "repo-coding-rules"],
|
|
111
111
|
"byRole": {
|
|
112
|
+
"design": ["role-design"],
|
|
112
113
|
"deploy": ["role-deploy"]
|
|
113
114
|
},
|
|
114
115
|
"byRuntime": {
|
|
@@ -123,6 +124,10 @@ Top-level and lane-local skill attachment use the same shape:
|
|
|
123
124
|
|
|
124
125
|
Lane-local `lanes.<lane>.skills` extends the global config instead of replacing it.
|
|
125
126
|
|
|
127
|
+
Optional design workers in the shipped `0.8.6` surface normally attach `role-design`. That bundle is intended for docs/spec-first design packets and explicit implementation handoff work before implementation starts. When the design packet covers terminal UX, dashboards, or other operator surfaces, add `tui-design` explicitly in the wave's `### Skills`.
|
|
128
|
+
|
|
129
|
+
Long-running agents that should stay resident and react only to orchestrator signal changes can add `signal-hygiene` explicitly in `### Skills`. That bundle is not auto-attached and is not meant for normal one-shot implementation agents.
|
|
130
|
+
|
|
126
131
|
## Resolution Order
|
|
127
132
|
|
|
128
133
|
Resolved skills are gathered in this order:
|
|
@@ -195,6 +200,18 @@ Runtime delivery:
|
|
|
195
200
|
|
|
196
201
|
These runtime projections are guidance surfaces. They should stay aligned with the canonical authority model, but they are not replay inputs or decision state on their own.
|
|
197
202
|
|
|
203
|
+
For the optional `design` worker role, the default pattern is:
|
|
204
|
+
|
|
205
|
+
- `role-design` for the design packet contract
|
|
206
|
+
- `tui-design` only when the packet covers terminal UX, dashboards, or other operator surfaces
|
|
207
|
+
- no runtime-specific coding bundle unless the wave explicitly gives the design steward code ownership and makes it a hybrid design steward
|
|
208
|
+
|
|
209
|
+
For long-running watcher agents, the default pattern is:
|
|
210
|
+
|
|
211
|
+
- no special bundle by default
|
|
212
|
+
- add `signal-hygiene` only when the agent should stay alive and wait for signal-version changes
|
|
213
|
+
- use the provided signal state path plus signal ack path instead of inventing a second wakeup loop
|
|
214
|
+
|
|
198
215
|
## Generated Artifacts
|
|
199
216
|
|
|
200
217
|
Executor overlay directories can contain:
|
|
@@ -225,3 +242,4 @@ Missing or malformed bundles are configuration errors, not silent no-ops.
|
|
|
225
242
|
- Use explicit per-agent `### Skills` for true exceptions, not as a substitute for missing activation metadata.
|
|
226
243
|
- Keep provider skills role-scoped unless every role genuinely needs the provider context.
|
|
227
244
|
- Keep bundle ids stable so traces and prompt fingerprints remain intelligible across runs.
|
|
245
|
+
- Keep `role-design` docs/spec-first by default; add `tui-design` when terminal or operator-surface work is in scope, and only attach broader coding bundles when the wave explicitly assigns code ownership and expects the same design steward to return for implementation.
|
package/package.json
CHANGED
package/releases/manifest.json
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "@chllming/wave-orchestration",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"version": "0.8.6",
|
|
7
|
+
"date": "2026-03-25",
|
|
8
|
+
"summary": "Signal-hygiene starter surface, versioned signal wrappers, terminal watcher hardening, and 0.8.6 release-surface alignment.",
|
|
9
|
+
"features": [
|
|
10
|
+
"Versioned wave and agent signal snapshots now ship as part of the operator surface under `.tmp/<lane>-wave-launcher/signals/`, with resident-orchestrator and long-running-agent ack loops built on the same model.",
|
|
11
|
+
"Starter repos now include `skills/signal-hygiene/`, `scripts/wave-status.sh`, and `scripts/wave-watch.sh` for long-running watcher agents plus shell-friendly operator automation.",
|
|
12
|
+
"Wrapper exit semantics now expose terminal failure with exit `40`, while `wave-watch.sh --until-change` still returns `30` only when a signal changed and the wave stayed active.",
|
|
13
|
+
"Agent signal materialization now treats completed and failed as terminal even when stale answered feedback or old coordination tasks still exist in the materialized status payload.",
|
|
14
|
+
"The migration guide now covers fresh adoption plus upgrades from `0.8.5`, `0.8.4`, `0.8.3`, `0.8.0`-`0.8.4`, `0.6.x`-`0.7.x`, and `0.5.x` or earlier, including repo-owned sync guidance for `skills/signal-hygiene/`, the wrapper scripts, and the `planner-agentic` corpus."
|
|
15
|
+
],
|
|
16
|
+
"manualSteps": [
|
|
17
|
+
"Run `pnpm exec wave doctor` and `pnpm exec wave launch --lane main --dry-run --no-dashboard` after upgrading so the repo validates against the `0.8.6` signal-hygiene, wrapper, and design-role behavior.",
|
|
18
|
+
"If your repo copied starter prompts, skills, scripts, or runbooks, sync `skills/signal-hygiene/`, `scripts/wave-status.sh`, `scripts/wave-watch.sh`, `docs/guides/signal-wrappers.md`, `docs/guides/terminal-surfaces.md`, `docs/reference/cli-reference.md`, and any local operator docs that describe waiting or failure handling.",
|
|
19
|
+
"If your repo uses planner workflows and copied the planner starter corpus, keep `docs/agents/wave-planner-role.md`, `skills/role-planner/`, `docs/context7/planner-agent/`, `docs/reference/wave-planning-lessons.md`, and the `planner-agentic` bundle entry in sync before relying on local planner docs.",
|
|
20
|
+
"If your repo uses long-running watcher agents or shell automation, update local loops so wrapper exit `40` is treated as terminal failure and confirm watchers can write their signal ack files under `.tmp/<lane>-wave-launcher/signals/`."
|
|
21
|
+
],
|
|
22
|
+
"breaking": false
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"version": "0.8.5",
|
|
26
|
+
"date": "2026-03-25",
|
|
27
|
+
"summary": "Shipped design-role support, hybrid design-steward execution, release-surface alignment, and a practical migration guide.",
|
|
28
|
+
"features": [
|
|
29
|
+
"The optional `design` worker role is now part of the published release surface, including the standing design prompt, `role-design`, and `tui-design` starter bundles.",
|
|
30
|
+
"Design stewards are docs-first by default, but waves can now explicitly give them implementation ownership so the same agent runs a design pass first and then rejoins implementation with normal proof obligations.",
|
|
31
|
+
"Design-aware validation, prompts, gates, retry or resume planning, reducer state, local-executor smoke behavior, and result-envelope projection now all agree on the same hybrid-design contract.",
|
|
32
|
+
"The migration guide now covers fresh adoption plus upgrades from `0.8.4`, `0.8.0`-`0.8.4`, `0.6.x`-`0.7.x`, and `0.5.x` or earlier, including repo-owned starter-surface sync guidance and `planner-agentic` corpus notes.",
|
|
33
|
+
"Shipped package metadata, README, current-state notes, sample-wave docs, and publishing guidance now point at the `0.8.5` release surface."
|
|
34
|
+
],
|
|
35
|
+
"manualSteps": [
|
|
36
|
+
"Run `pnpm exec wave doctor` and `pnpm exec wave launch --lane main --dry-run --no-dashboard` after upgrading so the repo validates against the `0.8.5` design-role and hybrid-design behavior.",
|
|
37
|
+
"If your repo copied starter prompts, skills, or authoring docs, sync `docs/agents/wave-design-role.md`, `skills/role-design/`, `skills/tui-design/`, `wave.config.json` design-role keys, and any local planner or runbook pages that should describe the new design-steward model.",
|
|
38
|
+
"If a repo uses hybrid design stewards, make sure each one still owns a design packet path and that any explicit implementation ownership also carries the expected exit contract, deliverables, proof artifacts, and component declarations where your lane validation requires them.",
|
|
39
|
+
"If your repo uses planner workflows and copied the planner starter corpus, keep `docs/agents/wave-planner-role.md`, `skills/role-planner/`, `docs/context7/planner-agent/`, `docs/reference/wave-planning-lessons.md`, and the `planner-agentic` bundle entry in sync before relying on local planner docs."
|
|
40
|
+
],
|
|
41
|
+
"breaking": false
|
|
42
|
+
},
|
|
5
43
|
{
|
|
6
44
|
"version": "0.8.4",
|
|
7
45
|
"date": "2026-03-25",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Minimal Context7 API smoke test (expects CONTEXT7_API_KEY in the environment).
|
|
3
2
|
set -euo pipefail
|
|
4
3
|
|
|
5
4
|
if [[ -z "${CONTEXT7_API_KEY:-}" ]]; then
|
|
@@ -7,15 +6,60 @@ if [[ -z "${CONTEXT7_API_KEY:-}" ]]; then
|
|
|
7
6
|
exit 1
|
|
8
7
|
fi
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
9
|
+
node <<'NODE'
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
|
|
13
|
+
const apiKey = process.env.CONTEXT7_API_KEY || "";
|
|
14
|
+
const repoRoot = process.cwd();
|
|
15
|
+
const bundlePath = path.join(repoRoot, "docs/context7/bundles.json");
|
|
16
|
+
const payload = JSON.parse(fs.readFileSync(bundlePath, "utf8"));
|
|
17
|
+
|
|
18
|
+
const entries = [];
|
|
19
|
+
for (const [bundleId, bundle] of Object.entries(payload.bundles || {})) {
|
|
20
|
+
for (const library of bundle.libraries || []) {
|
|
21
|
+
if (!library.libraryId) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Bundle "${bundleId}" must pin exact Context7 libraryId values. Found libraryName=${JSON.stringify(library.libraryName || "")}.`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
entries.push({
|
|
27
|
+
bundleId,
|
|
28
|
+
libraryId: String(library.libraryId),
|
|
29
|
+
queryHint: String(library.queryHint || "overview"),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const uniqueEntries = [...new Map(entries.map((entry) => [entry.libraryId, entry])).values()];
|
|
35
|
+
|
|
36
|
+
async function validate(entry) {
|
|
37
|
+
const url = new URL("https://context7.com/api/v2/context");
|
|
38
|
+
url.searchParams.set("libraryId", entry.libraryId);
|
|
39
|
+
url.searchParams.set("query", entry.queryHint);
|
|
40
|
+
url.searchParams.set("type", "txt");
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
headers: {
|
|
43
|
+
Authorization: "Bearer " + apiKey,
|
|
44
|
+
Accept: "text/plain, application/json",
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
const text = await response.text();
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`Context7 ${entry.libraryId} failed (${response.status}): ${text.slice(0, 200)}`);
|
|
50
|
+
}
|
|
51
|
+
if (text.trim().length === 0) {
|
|
52
|
+
throw new Error(`Context7 ${entry.libraryId} returned empty context.`);
|
|
53
|
+
}
|
|
54
|
+
console.log(`ok -- ${entry.libraryId} (${entry.bundleId})`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
(async () => {
|
|
58
|
+
for (const entry of uniqueEntries) {
|
|
59
|
+
await validate(entry);
|
|
60
|
+
}
|
|
61
|
+
})().catch((error) => {
|
|
62
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
63
|
+
process.exit(1);
|
|
64
|
+
});
|
|
65
|
+
NODE
|
|
@@ -47,6 +47,8 @@ const WAVE_EVAL_REGEX =
|
|
|
47
47
|
/^\[wave-eval\]\s*state=(satisfied|needs-more-work|blocked)\s+targets=(\d+)\s+benchmarks=(\d+)\s+regressions=(\d+)(?:\s+target_ids=([^\s]+))?(?:\s+benchmark_ids=([^\s]+))?\s*(?:detail=(.*))?$/gim;
|
|
48
48
|
const WAVE_SECURITY_REGEX =
|
|
49
49
|
/^\[wave-security\]\s*state=(clear|concerns|blocked)\s+findings=(\d+)\s+approvals=(\d+)\s*(?:detail=(.*))?$/gim;
|
|
50
|
+
const WAVE_DESIGN_REGEX =
|
|
51
|
+
/^\[wave-design\]\s*state=(ready-for-implementation|needs-clarification|blocked)\s+decisions=(\d+)\s+assumptions=(\d+)\s+open_questions=(\d+)\s*(?:detail=(.*))?$/gim;
|
|
50
52
|
const WAVE_GATE_REGEX =
|
|
51
53
|
/^\[wave-gate\]\s*architecture=(pass|concerns|blocked)\s+integration=(pass|concerns|blocked)\s+durability=(pass|concerns|blocked)\s+live=(pass|concerns|blocked)\s+docs=(pass|concerns|blocked)\s*(?:detail=(.*))?$/gim;
|
|
52
54
|
const WAVE_GAP_REGEX =
|
|
@@ -64,6 +66,7 @@ const STRUCTURED_SIGNAL_KIND_BY_TAG = {
|
|
|
64
66
|
integration: "integration",
|
|
65
67
|
eval: "eval",
|
|
66
68
|
security: "security",
|
|
69
|
+
design: "design",
|
|
67
70
|
gate: "gate",
|
|
68
71
|
gap: "gap",
|
|
69
72
|
component: "component",
|
|
@@ -76,6 +79,7 @@ const STRUCTURED_SIGNAL_LINE_REGEX_BY_KIND = {
|
|
|
76
79
|
integration: new RegExp(WAVE_INTEGRATION_REGEX.source, "i"),
|
|
77
80
|
eval: new RegExp(WAVE_EVAL_REGEX.source, "i"),
|
|
78
81
|
security: new RegExp(WAVE_SECURITY_REGEX.source, "i"),
|
|
82
|
+
design: new RegExp(WAVE_DESIGN_REGEX.source, "i"),
|
|
79
83
|
gate: new RegExp(WAVE_GATE_REGEX.source, "i"),
|
|
80
84
|
gap: new RegExp(WAVE_GAP_REGEX.source, "i"),
|
|
81
85
|
component: new RegExp(WAVE_COMPONENT_REGEX.source, "i"),
|
|
@@ -89,6 +93,7 @@ function buildEmptyStructuredSignalDiagnostics() {
|
|
|
89
93
|
integration: { rawCount: 0, acceptedCount: 0, rejectedSamples: [] },
|
|
90
94
|
eval: { rawCount: 0, acceptedCount: 0, rejectedSamples: [] },
|
|
91
95
|
security: { rawCount: 0, acceptedCount: 0, rejectedSamples: [] },
|
|
96
|
+
design: { rawCount: 0, acceptedCount: 0, rejectedSamples: [] },
|
|
92
97
|
gate: { rawCount: 0, acceptedCount: 0, rejectedSamples: [] },
|
|
93
98
|
gap: { rawCount: 0, acceptedCount: 0, rejectedSamples: [] },
|
|
94
99
|
component: { rawCount: 0, acceptedCount: 0, rejectedSamples: [], seenComponentIds: [] },
|
|
@@ -509,6 +514,13 @@ export function buildAgentExecutionSummary({ agent, statusRecord, logPath, repor
|
|
|
509
514
|
approvals: Number.parseInt(String(match[3] || "0"), 10) || 0,
|
|
510
515
|
detail: cleanText(match[4]),
|
|
511
516
|
})),
|
|
517
|
+
design: findLastMatch(signalText, WAVE_DESIGN_REGEX, (match) => ({
|
|
518
|
+
state: match[1],
|
|
519
|
+
decisions: Number.parseInt(String(match[2] || "0"), 10) || 0,
|
|
520
|
+
assumptions: Number.parseInt(String(match[3] || "0"), 10) || 0,
|
|
521
|
+
openQuestions: Number.parseInt(String(match[4] || "0"), 10) || 0,
|
|
522
|
+
detail: cleanText(match[5]),
|
|
523
|
+
})),
|
|
512
524
|
gate: findLastMatch(signalText, WAVE_GATE_REGEX, (match) => ({
|
|
513
525
|
architecture: match[1],
|
|
514
526
|
integration: match[2],
|
|
@@ -951,6 +963,58 @@ export function validateSecuritySummary(agent, summary) {
|
|
|
951
963
|
};
|
|
952
964
|
}
|
|
953
965
|
|
|
966
|
+
export function validateDesignSummary(agent, summary) {
|
|
967
|
+
if (!summary?.design) {
|
|
968
|
+
return {
|
|
969
|
+
ok: false,
|
|
970
|
+
statusCode: "missing-wave-design",
|
|
971
|
+
detail: appendTerminationHint(
|
|
972
|
+
`Missing [wave-design] marker for ${agent?.agentId || "D1"}.`,
|
|
973
|
+
summary,
|
|
974
|
+
),
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
if (!summary.reportPath) {
|
|
978
|
+
return {
|
|
979
|
+
ok: false,
|
|
980
|
+
statusCode: "missing-design-packet",
|
|
981
|
+
detail: `Missing design packet path for ${agent?.agentId || "D1"}.`,
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
if (!fs.existsSync(path.resolve(REPO_ROOT, summary.reportPath))) {
|
|
985
|
+
return {
|
|
986
|
+
ok: false,
|
|
987
|
+
statusCode: "missing-design-packet",
|
|
988
|
+
detail: `Missing design packet at ${summary.reportPath}.`,
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
if (summary.design.state === "blocked") {
|
|
992
|
+
return {
|
|
993
|
+
ok: false,
|
|
994
|
+
statusCode: "design-blocked",
|
|
995
|
+
detail:
|
|
996
|
+
summary.design.detail ||
|
|
997
|
+
`Design packet reported blocked for ${agent?.agentId || "D1"}.`,
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
if (summary.design.state === "needs-clarification") {
|
|
1001
|
+
return {
|
|
1002
|
+
ok: false,
|
|
1003
|
+
statusCode: "design-needs-clarification",
|
|
1004
|
+
detail:
|
|
1005
|
+
summary.design.detail ||
|
|
1006
|
+
`Design packet requested clarification for ${agent?.agentId || "D1"}.`,
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
return {
|
|
1010
|
+
ok: true,
|
|
1011
|
+
statusCode: "pass",
|
|
1012
|
+
detail:
|
|
1013
|
+
summary.design.detail ||
|
|
1014
|
+
"Design packet is ready for implementation.",
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
|
|
954
1018
|
export function validateIntegrationSummary(agent, summary) {
|
|
955
1019
|
if (!summary?.integration) {
|
|
956
1020
|
return {
|
|
@@ -28,6 +28,7 @@ export const DEFAULT_INTEGRATION_ROLE_PROMPT_PATH = "docs/agents/wave-integratio
|
|
|
28
28
|
export const DEFAULT_DOCUMENTATION_ROLE_PROMPT_PATH =
|
|
29
29
|
"docs/agents/wave-documentation-role.md";
|
|
30
30
|
export const DEFAULT_SECURITY_ROLE_PROMPT_PATH = "docs/agents/wave-security-role.md";
|
|
31
|
+
export const DEFAULT_DESIGN_ROLE_PROMPT_PATH = "docs/agents/wave-design-role.md";
|
|
31
32
|
export const DEFAULT_TERMINALS_PATH = ".vscode/terminals.json";
|
|
32
33
|
export const DEFAULT_DOCS_DIR = "docs";
|
|
33
34
|
export const DEFAULT_STATE_ROOT = ".tmp";
|
|
@@ -348,6 +349,10 @@ function normalizeRoles(rawRoles = {}) {
|
|
|
348
349
|
rawRoles.securityRolePromptPath || DEFAULT_SECURITY_ROLE_PROMPT_PATH,
|
|
349
350
|
"roles.securityRolePromptPath",
|
|
350
351
|
),
|
|
352
|
+
designRolePromptPath: normalizeRepoRelativePath(
|
|
353
|
+
rawRoles.designRolePromptPath || DEFAULT_DESIGN_ROLE_PROMPT_PATH,
|
|
354
|
+
"roles.designRolePromptPath",
|
|
355
|
+
),
|
|
351
356
|
};
|
|
352
357
|
}
|
|
353
358
|
|
|
@@ -36,6 +36,10 @@ import { readWaveRelaunchPlanSnapshot, readWaveRetryOverride, resolveRetryOverri
|
|
|
36
36
|
import { flushWaveControlQueue, readWaveControlQueueState } from "./wave-control-client.mjs";
|
|
37
37
|
import { readAgentExecutionSummary, validateImplementationSummary } from "./agent-state.mjs";
|
|
38
38
|
import { isContEvalReportOnlyAgent, isSecurityReviewAgent } from "./role-helpers.mjs";
|
|
39
|
+
import {
|
|
40
|
+
buildSignalStatusLine,
|
|
41
|
+
syncWaveSignalProjections,
|
|
42
|
+
} from "./signals.mjs";
|
|
39
43
|
|
|
40
44
|
function printUsage() {
|
|
41
45
|
console.log(`Usage:
|
|
@@ -676,6 +680,7 @@ export function buildControlStatusPayload({ lanePaths, wave, agentId = "" }) {
|
|
|
676
680
|
proofBundles: (proofRegistry?.entries || []).filter(
|
|
677
681
|
(entry) => !agentId || entry.agentId === agentId,
|
|
678
682
|
),
|
|
683
|
+
feedbackRequests,
|
|
679
684
|
selectionSource: selection.source,
|
|
680
685
|
rerunRequest,
|
|
681
686
|
relaunchPlan,
|
|
@@ -690,6 +695,7 @@ function ensureWaveStateDirs(lanePaths) {
|
|
|
690
695
|
ensureDirectory(lanePaths.controlPlaneDir);
|
|
691
696
|
ensureDirectory(lanePaths.assignmentsDir);
|
|
692
697
|
ensureDirectory(lanePaths.inboxesDir);
|
|
698
|
+
ensureDirectory(lanePaths.signalsDir);
|
|
693
699
|
ensureDirectory(lanePaths.messageboardsDir);
|
|
694
700
|
ensureDirectory(lanePaths.docsQueueDir);
|
|
695
701
|
ensureDirectory(lanePaths.ledgerDir);
|
|
@@ -714,6 +720,9 @@ function printStatus(payload) {
|
|
|
714
720
|
? `${payload.blockingEdge.kind} ${payload.blockingEdge.id}: ${payload.blockingEdge.detail}`
|
|
715
721
|
: "none";
|
|
716
722
|
console.log(`lane=${payload.lane} wave=${payload.wave} phase=${payload.phase}`);
|
|
723
|
+
if (payload.signals?.wave) {
|
|
724
|
+
console.log(buildSignalStatusLine(payload.signals.wave, payload));
|
|
725
|
+
}
|
|
717
726
|
console.log(`blocking=${blocking}`);
|
|
718
727
|
if (payload.nextTimer) {
|
|
719
728
|
console.log(`next-timer=${payload.nextTimer.kind} ${payload.nextTimer.taskId} at ${payload.nextTimer.at}`);
|
|
@@ -901,6 +910,16 @@ export async function runControlCli(argv) {
|
|
|
901
910
|
wave,
|
|
902
911
|
agentId: options.agent || "",
|
|
903
912
|
});
|
|
913
|
+
const signalSync = syncWaveSignalProjections({
|
|
914
|
+
lanePaths,
|
|
915
|
+
wave,
|
|
916
|
+
statusPayload: payload,
|
|
917
|
+
includeResident: Boolean(options.orchestratorId),
|
|
918
|
+
});
|
|
919
|
+
payload.signals = {
|
|
920
|
+
wave: signalSync.wave?.snapshot || null,
|
|
921
|
+
agents: (signalSync.agents || []).map((entry) => entry.snapshot),
|
|
922
|
+
};
|
|
904
923
|
if (options.json) {
|
|
905
924
|
console.log(JSON.stringify(payload, null, 2));
|
|
906
925
|
} else {
|