@mmerterden/multi-agent-pipeline 20.30.0 → 20.33.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.
Files changed (120) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +45 -0
  3. package/README.tr.md +59 -0
  4. package/docs/facts.json +3 -3
  5. package/install/_unattended-profile.mjs +61 -0
  6. package/install/catalog-history.json +1 -1
  7. package/install/claude.mjs +9 -2
  8. package/install/index.mjs +10 -1
  9. package/install/templates/claude-hooks.json +12 -1
  10. package/manifest.json +123 -82
  11. package/package.json +2 -1
  12. package/pipeline/commands/multi-agent/analysis/SKILL.md +4 -4
  13. package/pipeline/commands/multi-agent/office-on/SKILL.md +8 -7
  14. package/pipeline/commands/multi-agent/office-status/SKILL.md +1 -1
  15. package/pipeline/commands/multi-agent/prune-logs/SKILL.md +4 -1
  16. package/pipeline/commands/multi-agent/review/SKILL.md +4 -3
  17. package/pipeline/commands/multi-agent/scenario-audit/SKILL.md +4 -2
  18. package/pipeline/commands/multi-agent/sync/SKILL.md +12 -0
  19. package/pipeline/commands/multi-agent/test-gen/SKILL.md +29 -3
  20. package/pipeline/contract/CHANGELOG.md +46 -0
  21. package/pipeline/contract/README.md +22 -8
  22. package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
  23. package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
  24. package/pipeline/contract/fixtures/error-unsigned.json +1 -1
  25. package/pipeline/contract/fixtures/launch-plan.json +1 -1
  26. package/pipeline/contract/fixtures/runs-awaiting-question.json +6 -1
  27. package/pipeline/contract/fixtures/runs-empty.json +1 -1
  28. package/pipeline/contract/fixtures/runs-failed.json +6 -1
  29. package/pipeline/contract/fixtures/runs-old-schema.json +6 -1
  30. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +5 -1
  31. package/pipeline/contract/fixtures/runs-pr-opened.json +6 -1
  32. package/pipeline/contract/fixtures/runs-running.json +6 -1
  33. package/pipeline/contract/manifest.json +153 -19
  34. package/pipeline/contract/types/index.d.ts +304 -6
  35. package/pipeline/lib/bg-launch.mjs +106 -0
  36. package/pipeline/lib/code-digest.mjs +49 -0
  37. package/pipeline/lib/credential-resolve.mjs +42 -2
  38. package/pipeline/multi-agent-refs/features/office-threat-model.md +24 -6
  39. package/pipeline/multi-agent-refs/features/unattended-security.md +1 -1
  40. package/pipeline/multi-agent-refs/help/en.md +2 -2
  41. package/pipeline/multi-agent-refs/help/tr.md +2 -2
  42. package/pipeline/multi-agent-refs/phases/modes.md +7 -7
  43. package/pipeline/multi-agent-refs/phases/phase-5-report.md +16 -10
  44. package/pipeline/multi-agent-refs/review-standalone-tracker.md +37 -0
  45. package/pipeline/multi-agent-refs/tracker-contract.md +8 -3
  46. package/pipeline/office/NOTICE.md +4 -1
  47. package/pipeline/office/assets/ARCHIVE_BOXES.png +0 -0
  48. package/pipeline/office/assets/COFFEE_MACHINE.png +0 -0
  49. package/pipeline/office/assets/COUNTER_SINK.png +0 -0
  50. package/pipeline/office/assets/DEVICE_STAND.png +0 -0
  51. package/pipeline/office/assets/FILING_CABINET.png +0 -0
  52. package/pipeline/office/assets/FRIDGE.png +0 -0
  53. package/pipeline/office/assets/MAILBOX.png +0 -0
  54. package/pipeline/office/assets/MOP_BUCKET.png +0 -0
  55. package/pipeline/office/assets/PRINTER.png +0 -0
  56. package/pipeline/office/assets/RECEPTION_DESK.png +0 -0
  57. package/pipeline/office/assets/SERVER_RACK.png +0 -0
  58. package/pipeline/office/assets/SERVER_RACK_2.png +0 -0
  59. package/pipeline/office/assets/TOILET_STALL.png +0 -0
  60. package/pipeline/office/assets/VENDING.png +0 -0
  61. package/pipeline/office/assets/WASHBASIN.png +0 -0
  62. package/pipeline/office/assets/WATER_COOLER.png +0 -0
  63. package/pipeline/office/index.html +3996 -884
  64. package/pipeline/office/toolkit.json +3 -0
  65. package/pipeline/schemas/activity.schema.json +188 -4
  66. package/pipeline/schemas/agent-state.schema.json +493 -115
  67. package/pipeline/schemas/contract-error.schema.json +12 -1
  68. package/pipeline/schemas/job-change.schema.json +72 -0
  69. package/pipeline/schemas/job-request.schema.json +38 -0
  70. package/pipeline/schemas/launch.json +4 -4
  71. package/pipeline/schemas/office-credentials.schema.json +71 -0
  72. package/pipeline/schemas/office-jobs.json +253 -0
  73. package/pipeline/schemas/office-jobs.schema.json +62 -0
  74. package/pipeline/schemas/office-memory.schema.json +105 -0
  75. package/pipeline/schemas/office-settings-request.schema.json +30 -0
  76. package/pipeline/schemas/office-settings.schema.json +67 -0
  77. package/pipeline/schemas/phases.json +10 -2
  78. package/pipeline/schemas/phases.schema.json +86 -19
  79. package/pipeline/schemas/prs.schema.json +5 -0
  80. package/pipeline/schemas/prune-logs-request.schema.json +26 -0
  81. package/pipeline/schemas/prune-logs.schema.json +52 -0
  82. package/pipeline/schemas/repo-change.schema.json +54 -0
  83. package/pipeline/schemas/repo-request.schema.json +29 -0
  84. package/pipeline/schemas/repos.schema.json +49 -1
  85. package/pipeline/schemas/runs-index.schema.json +257 -46
  86. package/pipeline/schemas/system-status.schema.json +111 -0
  87. package/pipeline/schemas/tools.schema.json +5 -0
  88. package/pipeline/schemas/unattended-profile.json +7 -2
  89. package/pipeline/scripts/_active-run.mjs +2 -1
  90. package/pipeline/scripts/_spawn-async.mjs +9 -5
  91. package/pipeline/scripts/activity-snapshot.mjs +219 -23
  92. package/pipeline/scripts/autopilot-runner.mjs +7 -5
  93. package/pipeline/scripts/contract-server.mjs +551 -25
  94. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -1
  95. package/pipeline/scripts/job-launch.mjs +477 -0
  96. package/pipeline/scripts/launch-request.mjs +94 -9
  97. package/pipeline/scripts/office-build.mjs +148 -11
  98. package/pipeline/scripts/office-control.mjs +34 -7
  99. package/pipeline/scripts/office-credentials.mjs +106 -0
  100. package/pipeline/scripts/office-memory.mjs +200 -0
  101. package/pipeline/scripts/office-prune.mjs +125 -0
  102. package/pipeline/scripts/office-settings.mjs +145 -0
  103. package/pipeline/scripts/phase-tracker.sh +12 -5
  104. package/pipeline/scripts/prune-logs.sh +53 -2
  105. package/pipeline/scripts/runs-index.mjs +62 -2
  106. package/pipeline/scripts/system-status.mjs +196 -0
  107. package/pipeline/scripts/task-mirror.mjs +150 -0
  108. package/pipeline/scripts/task-mirror.sh +20 -0
  109. package/pipeline/scripts/toolkit-tools.mjs +33 -7
  110. package/pipeline/scripts/transcript-index.mjs +4 -1
  111. package/pipeline/scripts/work-items.mjs +191 -22
  112. package/pipeline/skills/.skill-manifest.json +6 -6
  113. package/pipeline/skills/.skills-index.json +1 -1
  114. package/pipeline/skills/shared/README.md +1 -1
  115. package/pipeline/skills/shared/core/multi-agent-office-on/SKILL.md +3 -4
  116. package/pipeline/skills/shared/core/multi-agent-prune-logs/SKILL.md +4 -1
  117. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +19 -0
  118. package/pipeline/skills/shared/core/multi-agent-scenario-audit/SKILL.md +4 -2
  119. package/pipeline/skills/shared/core/multi-agent-test-gen/SKILL.md +26 -3
  120. package/pipeline/skills/skills-index.md +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmerterden/multi-agent-pipeline",
3
- "version": "20.30.0",
3
+ "version": "20.33.0",
4
4
  "description": "6-phase AI development pipeline with full orchestration on Claude Code, Copilot CLI and Codex CLI. Analysis, planning, TDD, CLI-aware parallel review with consensus surfacing + Fable triage, default-FAIL evidence gates, secret + intent guards, per-phase cost ledger, persistent learnings memory, wiki generation, commit automation. Token-preserving uninstall.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -87,6 +87,7 @@
87
87
  "LICENSE",
88
88
  "SECURITY.md",
89
89
  "!pipeline/office-src/**",
90
+ "!pipeline/office-art/**",
90
91
  "!pipeline/scripts/smoke-figma-config-schema.sh",
91
92
  "!pipeline/scripts/smoke-personal-data.sh",
92
93
  "!pipeline/scripts/validate-prefs.mjs",
@@ -117,7 +117,7 @@ Two channels run in parallel at every phase boundary:
117
117
  ```bash
118
118
  # Phase 0, very first shell call (every CLI):
119
119
  bash $HOME/.claude/scripts/phase-tracker.sh init "$TASK_ID"
120
- for p in "0:Init" "1:Plan" "3:Review" "4:Commit" "5:Report"; do
120
+ for p in "0:Intake" "1:Evidence" "2:Synthesis" "3:Review" "4:Publish" "5:Report"; do
121
121
  bash $HOME/.claude/scripts/phase-tracker.sh add "${p%%:*}" "${p#*:}"
122
122
  done
123
123
  bash $HOME/.claude/scripts/phase-tracker.sh update 0 in_progress
@@ -131,13 +131,13 @@ bash $HOME/.claude/scripts/phase-tracker.sh tokens <N> <in> <out> [cached]
131
131
 
132
132
  ### Visual channel - Claude Code (native TaskList widget, required)
133
133
 
134
- In Claude Code the agent MUST also drive the native TaskList widget so the user sees a sticky phase tile stack - this is the only progress signal Claude Code surfaces. Register one tile per phase of the active set (`0:Init 1:Plan 3:Review 4:Commit 5:Report`) with `TaskCreate`, persist each `taskId` via `phase-tracker.sh meta <N> tasklist_id "<taskId>"`, and at every phase entry, sub-step and exit pair a `TaskUpdate` (status or `activeForm`) with the matching `phase-tracker.sh update`. Call pattern: `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "Call pattern". Mirror each with `phase-tracker.sh task` ("Mirroring the host's task list").
134
+ In Claude Code the agent MUST also drive the native TaskList widget so the user sees a sticky phase tile stack - this is the only progress signal Claude Code surfaces. Register one tile per phase of the active set (`0:Intake 1:Evidence 2:Synthesis 3:Review 4:Publish 5:Report`) with `TaskCreate`, persist each `taskId` via `phase-tracker.sh meta <N> tasklist_id "<taskId>"`, and at every phase entry, sub-step and exit pair a `TaskUpdate` (status or `activeForm`) with the matching `phase-tracker.sh update`. Call pattern: `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "Call pattern". Mirror each with `phase-tracker.sh task` ("Mirroring the host's task list").
135
135
 
136
- `analysis` mode does NOT TaskCreate phase 2: register tiles for the active set only.
136
+ `analysis` mode TaskCreates all 6 phases (no phase is skipped).
137
137
 
138
138
  #### TaskCreate ordering (strict)
139
139
 
140
- **All TaskCreate calls in a batch fire in strict phase-number order BEFORE any TaskUpdate is applied**, and a later batch only ever appends phases numbered above everything already registered. For `analysis` that means: Phase 0 → Phase 1 → Phase 3 → Phase 4 → Phase 5. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks (e.g. `1 ✓ · 2 ✓ · 4 ✓ · 0 ▶ · 3 ☐`) even when the underlying state is correct. Pre-marking phases as completed/skipped before Phase 0 starts is FORBIDDEN - register the tile in order, then flip status via TaskUpdate when the phase actually short-circuits. Full ordering contract in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
140
+ **All TaskCreate calls in a batch fire in strict phase-number order BEFORE any TaskUpdate is applied**, and a later batch only ever appends phases numbered above everything already registered. For `analysis` that means: Phase 0 → Phase 1 → Phase 2 → Phase 3 → Phase 4 → Phase 5. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks (e.g. `1 ✓ · 2 ✓ · 4 ✓ · 0 ▶ · 3 ☐`) even when the underlying state is correct. Pre-marking phases as completed/skipped before Phase 0 starts is FORBIDDEN - register the tile in order, then flip status via TaskUpdate when the phase actually short-circuits. Full ordering contract in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
141
141
 
142
142
  ### Visual channel - Copilot CLI / plain shell
143
143
 
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "Open the office panel: a local browser page with agents at work, their chats, cost ledger and new runs. Use when you want to watch or drive runs from a browser."
3
- description-tr: "Ofis panelini açar: çalışan her ajanı (koşu başına bir masa, ekip faz sırasıyla oturur), sohbetlerini, maliyet defterini, autopilot'u, rutinleri, stack'leri, toolkit araçlarını ve yeni koşu başlatmayı gösteren yerel web sayfası. Yerel sözleşme sunucusunu gerektiğinde başlatır; panel kapanınca hiçbir şey çalışmaz."
2
+ description: "Open the office: a local browser page that shows runs and agents live and drives the ecosystem (new runs, jobs, PRs, keys, memory, system, cleanup). Use when you want to watch or drive runs from a browser."
3
+ description-tr: "Ofisi açar: koşuları ve ajanları canlı gösteren, ekosistemi yöneten yerel web sayfası (yeni koşu, işler, PR'lar, anahtarlar, hafıza, sistem, temizlik). Yerel sözleşme sunucusunu gerektiğinde başlatır; sunucu /multi-agent:office-off ile durdurulana kadar çalışır."
4
4
  argument-hint: "(no arguments)"
5
5
  parameters: []
6
6
  gui: button
@@ -33,16 +33,17 @@ fresh bearer token per start). This command and `office-off` /
33
33
  in this transcript.
34
34
 
35
35
  2. **Report** (in `outputLanguage`): the page URL (`url`, without a code),
36
- whether a server was started or reused, that it stops by itself after
37
- `idleMinutes` without a request (and after 8 hours in any case), and that
38
- `/multi-agent:office-off` stops it now. If `opened` is false, tell the user
36
+ whether a server was started or reused (`restarted` true means the running
37
+ one was older than the installed pipeline and was replaced), that it keeps
38
+ running until `/multi-agent:office-off` stops it. If `opened` is false, tell the user
39
39
  to run the command again from a desktop session; a link works once, so a
40
40
  reload of the page needs a new `office-on`.
41
41
 
42
42
  ## What it does not do
43
43
 
44
- - No daemon, hook or file watcher: when the page is closed, the server exits
45
- after its idle time and nothing else runs.
44
+ - No daemon or file watcher beside the one server, which runs until
45
+ `office-off`, and no hook of its own: the task lists come from the
46
+ `task-mirror` hook that install registers for every run.
46
47
  - The panel's writes call the same scripts the terminal commands call; it adds
47
48
  no behaviour of its own.
48
49
  - The server listens on 127.0.0.1 only. Remote access is not part of this
@@ -17,7 +17,7 @@ node "$HOME/.claude/scripts/office-control.mjs" status --json
17
17
 
18
18
  Report in `outputLanguage`:
19
19
 
20
- - `running`, and when it is, `url` and `idleMinutes`;
20
+ - `running`, and when it is, `url` and `idleMinutes` (0 means it runs until `office-off`);
21
21
  - `remote`: "not available in this installation" unless a separate remote
22
22
  layer is installed; report the line as given;
23
23
  - `pairedDevices`: the devices the phone registry lists; revoking one is
@@ -21,7 +21,10 @@ whole task dirs, with optional age / project / task filters.
21
21
  Backed by `$HOME/.claude/scripts/prune-logs.sh`. Safe by default: it previews
22
22
  and deletes nothing until you confirm. The audit trail (`audit.jsonl` +
23
23
  rotations) and the metrics corpus (`metrics.jsonl`, `metrics-summary.md`) live
24
- at the log-root top level and are never removed; `.counter` files survive too.
24
+ at the log-root top level and are never removed; `.counter` files survive too. A run that can still be resumed (its `agent-state.json` status is not
25
+ finished, abandoned or cancelled) keeps its log however old it is, and
26
+ so does a folder written in the last 10 minutes; `--task` names one dir and
27
+ bypasses both.
25
28
 
26
29
  Unlike `/multi-agent:purge` (which wipes worktrees, branches, logs, and state
27
30
  together), this only removes log dirs and leaves your worktrees and branches
@@ -41,10 +41,11 @@ Branch-mode runs print to chat only. PR-mode runs print to chat AND post the ver
41
41
  : "${TASK_ID:=review-$(date +%s)-$$}"
42
42
  export TASK_ID
43
43
 
44
- # Clean up scratch files on exit so /tmp doesn't accumulate diffs and SHAs.
45
44
  trap 'rm -f /tmp/multi-agent-review-${TASK_ID}-*' EXIT
46
45
  ```
47
46
 
47
+ Standalone only (a `review-` id): register a tracker record per `$HOME/.claude/multi-agent-refs/review-standalone-tracker.md`.
48
+
48
49
  ### 1. Parse the input - pick a resolution path
49
50
 
50
51
  ```bash
@@ -379,10 +380,10 @@ If the post fails (network, token, harness block), `post-pr-review.sh` exits non
379
380
  Per the `$HOME/.claude/multi-agent-refs/tracker-contract.md` tokens contract, after each reviewer LLM call:
380
381
 
381
382
  ```bash
382
- bash $HOME/.claude/scripts/phase-tracker.sh tokens 4 <input_count> <output_count>
383
+ bash $HOME/.claude/scripts/phase-tracker.sh tokens <N> <input_count> <output_count>
383
384
  ```
384
385
 
385
- Standalone `/multi-agent:review` runs use phase id 3 (matches Phase 3 Review in the full pipeline) so cost aggregation stays consistent.
386
+ `<N>`: the run's Review phase, or step 2 for a standalone review.
386
387
 
387
388
  ## Input matrix
388
389
 
@@ -55,7 +55,9 @@ Read the candidate lines it returns. A term nothing matched is listed under
55
55
 
56
56
  ## Step 3 - Verdict
57
57
 
58
- Write `/tmp/ma-verdicts.json`: `[{id, status, citations, searched, note}]`.
58
+ Write the verdicts to a file in a folder of this run's own
59
+ (`VERDICTS="$(mktemp -d)/verdicts.json"`, never a fixed `/tmp` name another
60
+ user or a second audit could share): `[{id, status, citations, searched, note}]`.
59
61
 
60
62
  | Status | When | Needs |
61
63
  |---|---|---|
@@ -66,7 +68,7 @@ Write `/tmp/ma-verdicts.json`: `[{id, status, citations, searched, note}]`.
66
68
 
67
69
  ```bash
68
70
  node "$HOME/.claude/scripts/scenario-audit.mjs" verify --csv "<scenarios.csv>" \
69
- --verdicts /tmp/ma-verdicts.json --repo "<repo>" --lang "<outputLanguage>"
71
+ --verdicts "$VERDICTS" --repo "<repo>" --lang "<outputLanguage>"
70
72
  ```
71
73
 
72
74
  ## Step 4 - Report
@@ -79,6 +79,7 @@ Step 3: REPO Claude Code -> pipeline repo (genericized, personal data scr
79
79
  Step 3c: PLUGINS pipeline shared/external -> multi-agent-plugins marketplace (rebuild knowledge/,
80
80
  bump changed plugins' patch version, commit + push the plugins repo)
81
81
  Step 3d: DEV-TOOLKIT companion MCP server -> detect movement, run the ship gates, commit + publish
82
+ Step 3e: OFFICE panel page is current, installed copies match it, toolkit version recorded
82
83
  Step 4: WEBSITE Version + phase/model counts -> {website-host} (i18n + projects.ts)
83
84
  Step 5: Commit Commit + push all changed repos
84
85
  Step 6: Report Summary: synced targets, platform, changed files, deploy status, multi-agent-toolkit version
@@ -131,6 +132,7 @@ Step 0 gate rules and why: `features/doctor.md`.
131
132
  - `~/.claude/CLAUDE.md`, `~/.claude/rules/`, `~/.claude/knowledge/`
132
133
  - `~/.claude/scripts/` - EXCEPT `pre-commit-check.sh`, `agent-guard.sh`, `agent-guard.py`, and `build-stack-plugins.mjs` (generic, synced)
133
134
  - `~/.claude/settings.json`
135
+ - `~/.claude/office/` - the office panel flows the other way: its source is the repo (`pipeline/office-src`, built by `office-build.mjs` into `pipeline/office`), and the installer copies it to each host. Never copy it from `~/.claude` into the repo; Step 3e checks it instead
134
136
  - `~/.claude/multi-agent-refs/registries/` - the installer copies gate registries there from `pipeline/skills/shared/external`; the repo already holds the source
135
137
  - **Any `~/.claude/commands/multi-agent/*/SKILL.md` whose frontmatter has `local-only: true`** - these are user/repo-specific alias wrappers that delegate to a private marketplace plugin's skills exposed as `multi-agent:<name>`. Syncing them would leak the private plugin/skill names into the public pipeline. Skip them at copy time; the backstop below proves none reached `pipeline/commands/`.
136
138
  ```bash
@@ -226,9 +228,19 @@ When invoked with the `release` argument:
226
228
  8. WEBSITE Version + features -> {website-host} (maintainer identity, build verified Ready)
227
229
  9. COPILOT Copilot CLI instructions + skills sync
228
230
  9b. CODEX Codex CLI router skill + refs + agent TOML (node install.js --codex)
231
+ 9c. OFFICE Step 3e: the installed panel matches the release
229
232
  10. Report Summary: version, touched repos, deploy status
230
233
  ```
231
234
 
235
+ ### Step 3e: OFFICE (every sync, and step 9c of a release)
236
+
237
+ The office panel ships with the pipeline, so a sync carries it by checking it, not by copying it:
238
+
239
+ 1. `node ~/multi-agent-pipeline/pipeline/scripts/office-build.mjs --check`: the committed page is what `pipeline/office-src` builds to, and `office/toolkit.json` carries the toolkit version in `docs/facts.json`. Either stale fails the sync until it is rebuilt and committed; a release that regenerates facts rebuilds the office right after.
240
+ 2. After the install steps, compare `pipeline/office/index.html` with the installed copies (`~/.claude/office/`, and the Copilot and Codex trees when installed), byte for byte, plus the asset list. A difference means the install is behind: run `node install.js --installed` and compare again.
241
+ 3. Report the toolkit version the installed `office/toolkit.json` carries: it is what the office Tools window starts, and it moves forward with every release.
242
+ 4. An office server that is already running picks the update up by itself: the open page shows a reload banner, and `/multi-agent:office-on` replaces a server whose code changed. Nothing to restart by hand.
243
+
232
244
  ---
233
245
 
234
246
  ## Sub-Command Sync (Claude Code <-> Copilot CLI Skills)
@@ -47,9 +47,32 @@ Scripts: `test-gen-gate.mjs` (artefact, handle and write gates),
47
47
  ## Step 1 - Prepare
48
48
 
49
49
  1. Repo: `--repo`, else the current directory; confirm it in one line.
50
- Platform: `--platform`, else detect as `/multi-agent:test` does. Run id
51
- `tg-<timestamp>`; `RUN="$HOME/.claude/logs/test-gen/<repo>/<timestamp>"`,
52
- created with `mkdir -p "$RUN"`.
50
+ Platform: `--platform`, else detect as `/multi-agent:test` does. One
51
+ timestamp names the run everywhere: `TS="$(date +%Y%m%d%H%M%S)"`, run id
52
+ `tg-$TS`, `RUN="$HOME/.claude/logs/test-gen/<repo>/$TS"`, created with
53
+ `mkdir -p "$RUN"`.
54
+ Register the run so its progress shows wherever runs are read (the office
55
+ panel, `/multi-agent:status`), with one step per stage below:
56
+
57
+ ```bash
58
+ TG_ID="tg-$TS"
59
+ S="${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}/$TG_ID"; mkdir -p "$S"
60
+ printf '{"taskId":"%s","mode":"test-gen","status":"in_progress","currentPhase":0}' "$TG_ID" \
61
+ | node "$HOME/.claude/scripts/write-state.mjs" "$S/agent-state.json" >/dev/null
62
+ export MULTI_AGENT_TASK_ID="$TG_ID"
63
+ bash "$HOME/.claude/scripts/phase-tracker.sh" init "$TG_ID"
64
+ for p in "0:Prepare" "1:Inventory" "2:Discovery" "3:Handles" "4:Tests" "5:Report"; do
65
+ bash "$HOME/.claude/scripts/phase-tracker.sh" add "${p%%:*}" "${p#*:}"
66
+ done
67
+ bash "$HOME/.claude/scripts/phase-tracker.sh" update 0 in_progress
68
+ ```
69
+
70
+ Each step below starts with `update <N> in_progress` and ends with
71
+ `update <N> completed` (Step 5 and Step 6 share step 4), every call prefixed
72
+ `MULTI_AGENT_TASK_ID=<the tg- id, written out> MULTI_AGENT_STRICT_TASK_ID=1`
73
+ since it runs in a new shell where `$TG_ID` is gone, and on
74
+ Claude Code each gets a task-widget tile named as its tracker line
75
+ (`tracker-contract.md`, "Call pattern").
53
76
  2. Toolkit: `test_results_classify`, `coverage_gap` and `ui_locator_codegen`
54
77
  need `@mmerterden/multi-agent-toolkit-mcp` >= v3.25.0. Check the tool list
55
78
  once. Each missing tool has a fallback in `stages.md` (classify from the
@@ -122,3 +145,6 @@ inventory, the gaps, the triage). Then record the change base
122
145
  Offer, one question: open the product bugs through `/multi-agent` with each
123
146
  failing test as the acceptance check, or stop. **No commit, no push, no issue
124
147
  from this command.**
148
+
149
+ Last, close the run record: `phase-tracker.sh update 5 completed`, then the
150
+ same `write-state.mjs` call with `"status":"complete","currentPhase":5`.
@@ -3,6 +3,52 @@
3
3
  Versions of the client contract (`manifest.json` `contractVersion`), separate
4
4
  from the package version. See `README.md` for what counts as minor and major.
5
5
 
6
+ ## 1.6.0
7
+
8
+ Added. Nothing existing changes shape.
9
+
10
+ - `GET /v1/system` (`system-status.mjs --json`): CPU, memory, disk and the
11
+ pipeline's own processes, numbers only.
12
+ - `GET /v1/credentials` (`office-credentials.mjs --json [--probe]`, local-only):
13
+ logical names, state and probe verdict per credential, never a value.
14
+ - `GET /v1/memory` (`office-memory.mjs --json`, local-only): per-repository code
15
+ graph age and learning, finding and session-note counts, redacted.
16
+ - `POST /v1/prune-logs` (two steps, local-only): the task log folders older than
17
+ 7, 30 or 90 days, then a prune of exactly that list; 409 `changed` when the
18
+ folders moved since the preview.
19
+ - `GET /v1/settings` and `POST /v1/settings` (two steps, local-only, one change
20
+ at a time): output language, the fable rung and model routing; a route-on
21
+ preview names a saved free provider chain in `change.freeChain`.
22
+ - runs and run (1.3.0): `source`, `prNumber`, `mode`, `channels`, and the
23
+ local-only `channelUrls`, dropped from a redacted answer.
24
+ - activity, activity stream, agent chat, routines, routine delete, repo add and
25
+ remove (1.1.0): tables carry `source`, `pr`, `channels`, `waitingFor`,
26
+ `currentTask`, `progress` and each phase's `tasks`; seats carry their own
27
+ `tasks` and recent `mcp` calls.
28
+ - prs, issue maturity, review verdict (1.1.0): a pull request names the
29
+ `account` it was listed for, numbered in a redacted answer.
30
+
31
+ ## 1.5.0
32
+
33
+ Added. Nothing existing changes shape.
34
+
35
+ - `GET /v1/repos?all=1` (`launch-request.mjs repos --all`): `suggested`
36
+ (checkouts earlier runs worked in that launch does not accept yet) and
37
+ `missing` (registered entries whose folder is gone), each with an `id`; a
38
+ page sees ids and names, never paths.
39
+ - `POST /v1/repos` (two steps, `repo-request.schema.json`,
40
+ `repo-change.schema.json`, `local-only`/`high`): register a suggestion by id
41
+ or an absolute path to a git checkout. `DELETE /v1/repos/{id}` (two steps)
42
+ removes a registered entry; configured autopilot repositories are not
43
+ touched.
44
+ - `version` on `GET /v1/tools`: the exact toolkit version the panel starts.
45
+ - `GET /v1/jobs` (`office-jobs.schema.json`): the jobs the office can start,
46
+ from `schemas/office-jobs.json`. `POST /v1/jobs` (two steps,
47
+ `job-request.schema.json`, `job-change.schema.json`, `local-only`/`high`)
48
+ starts one with `claude --bg` under the unattended profile; it is the one
49
+ route that starts a session itself.
50
+ - `--idle-minutes 0` and `--max-hours 0` mean no idle stop and no lifetime.
51
+
6
52
  ## 1.4.0
7
53
 
8
54
  Added. Nothing existing changes shape; one narrowing for browser pages.
@@ -42,7 +42,11 @@ same bytes (`test/contract-parity.test.mjs`):
42
42
  | Assigned issues | `issues.mjs --json [--source S] [--project K] [--max N]` | `GET /v1/issues` |
43
43
  | Worktrees | `worktrees.mjs --json [--measure] [--redact]` | `GET /v1/worktrees` |
44
44
  | Launch shape | `launch-request.mjs spec` | `GET /v1/launch-spec` |
45
- | Launch repositories | `launch-request.mjs repos [--redact]` | `GET /v1/repos` |
45
+ | Launch repositories | `launch-request.mjs repos [--redact] [--all]` | `GET /v1/repos[?all=1]` |
46
+ | Add a launch repository (two steps; the route also requires a git checkout) | `launch-request.mjs register-repo <path>` | `POST /v1/repos` |
47
+ | Remove a registered repository (two steps) | - | `DELETE /v1/repos/{id}` |
48
+ | Office jobs | `job-launch.mjs list` | `GET /v1/jobs` |
49
+ | Start an office job (two steps) | - | `POST /v1/jobs` |
46
50
  | Start a run | write the request file, then `launch-request.mjs plan FILE --repo P --session-id U [--channel phone]` | `POST /v1/launch?repo=P` |
47
51
  | Answer a question | `answer-question.mjs STATE --question Q --answer IDS` | `POST /v1/runs/{id}/answer` |
48
52
  | A run's log | `run-log.mjs ID [--tail N]` (1-2000, default 200) | `GET /v1/runs/{id}/log?tail=N` |
@@ -56,6 +60,12 @@ same bytes (`test/contract-parity.test.mjs`):
56
60
  | Agent activity | `activity-snapshot.mjs --json` | `GET /v1/activity`, `GET /v1/activity/stream` (SSE) |
57
61
  | An agent's chat | `activity-snapshot.mjs chat SESSION [AGENT] [--before N] [--limit N]` | `GET /v1/agents/{sessionId}/{agentId}/chat` |
58
62
  | Cost ledger | `office-ledger.mjs --json` | `GET /v1/ledger` |
63
+ | Machine resources | `system-status.mjs --json` | `GET /v1/system` |
64
+ | Key cabinet (names and verdicts, never values) | `office-credentials.mjs --json [--probe]` | `GET /v1/credentials` |
65
+ | Institutional memory | `office-memory.mjs --json` | `GET /v1/memory` |
66
+ | Prune old run logs (two steps) | `office-prune.mjs preview\|apply N --json` | `POST /v1/prune-logs` |
67
+ | Office settings | `office-settings.mjs --json` | `GET /v1/settings` |
68
+ | Change one setting (two steps) | `office-settings.mjs set SETTING VALUE --json` | `POST /v1/settings` |
59
69
  | What a run produced | `run-results.mjs ID --json` | `GET /v1/runs/{id}/results` |
60
70
  | One screenshot | `run-results.mjs ID --evidence NAME` | `GET /v1/runs/{id}/evidence/{name}` |
61
71
  | Post a review verdict (two steps) | `work-items.mjs verdict ID [--post]` | `POST /v1/runs/{id}/review-verdict` |
@@ -72,16 +82,19 @@ same bytes (`test/contract-parity.test.mjs`):
72
82
 
73
83
  Every surface in `manifest.json` carries `remote` (the scope a remote carrier
74
84
  would require: `read`, `answer`, `launch`, or `local-only` for anything that
75
- widens what runs on this machine: autopilot on, stack, routine removal, kill,
76
- gc) and `risk` (the confirmation tier: `read`, `low`, `high`). Locally the
85
+ widens what runs on this machine (autopilot on, stack, routine removal, kill,
86
+ gc, prune, settings) and for a read that stays on this machine for privacy
87
+ (credentials, memory, settings)) and `risk` (the confirmation tier: `read`, `low`, `high`). Locally the
77
88
  bearer token is the only credential; nothing enforces the tags yet. They are
78
89
  there so a later carrier reuses these routes without redefining them.
79
90
 
80
- Starting a run is always the client's act. `POST /v1/launch` validates the
91
+ Starting a run is the client's act. `POST /v1/launch` validates the
81
92
  request, writes it (0600) and returns the argv, environment and working
82
- directory from `launch.json`; it never starts a session (the only `claude` the
83
- server runs is `claude stop`, for a kill). Spawn the argv without
84
- a shell. `launch.json` is marked `verified: false` until a live launch trial, so
93
+ directory from `launch.json`; spawn the argv without a shell. The office panel
94
+ is a client that starts its own: `POST /v1/jobs` (two steps, `local-only`)
95
+ starts a job from `schemas/office-jobs.json` in the background after the
96
+ unattended profile, workspace trust and sandbox checks. Besides that the only
97
+ `claude` the server runs is `claude stop`, for a kill. `launch.json` is marked `verified: false` until a live launch trial, so
85
98
  treat the shape as provisional.
86
99
 
87
100
  The run starts with no permission prompts, so its input is held to a shape: a
@@ -155,7 +168,8 @@ answer to the old one.
155
168
  (own Origin only, no bearer); a used, expired or unknown code is 401.
156
169
  `GET /office/assets/<name>.png` serves the page's sprites, also without a
157
170
  token: a plain file name, a PNG of at most 256 KiB directly in the assets
158
- directory beside the page, and 404 for anything else.
171
+ directory beside the page, and 404 for anything else. `GET /favicon.ico`
172
+ answers an empty 204 without a token, since browsers request it on their own.
159
173
  - Every write route appends one line (who, route, step, status; never a body
160
174
  or token) to `~/.claude/logs/multi-agent/office-actions.jsonl`.
161
175
  - Bodies are JSON, at most 64 KiB, and must satisfy the route's schema.
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.4.0",
2
+ "contractVersion": "1.6.0",
3
3
  "error": "invalid-request",
4
4
  "message": "the launch request was refused",
5
5
  "errors": [
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.4.0",
2
+ "contractVersion": "1.6.0",
3
3
  "error": "unauthorized",
4
4
  "message": "a bearer token is required"
5
5
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.4.0",
2
+ "contractVersion": "1.6.0",
3
3
  "error": "unsigned",
4
4
  "message": "a device signature is required"
5
5
  }
@@ -22,7 +22,7 @@
22
22
  "MULTI_AGENT_UNATTENDED": "1",
23
23
  "MULTI_AGENT_SESSION_ID": "00000000-0000-4000-8000-000000000201",
24
24
  "MCP_TOOLKIT_URL_POLICY": "strict",
25
- "MCP_TOOLKIT_INDEX_DENY": "~/.ssh,~/.aws,~/.gnupg,~/Library/Keychains",
25
+ "MCP_TOOLKIT_INDEX_DENY": "~/.ssh,~/.aws,~/.gnupg,~/Library/Keychains,~/.claude/logs/multi-agent/contract-server,~/.claude/logs/multi-agent/office",
26
26
  "LOGS_ROOT": "/Users/example/.multi-agent-unattended/logs",
27
27
  "MA_LAUNCH_REQUEST": "/Users/example/.claude/autopilot/requests/00000000-0000-4000-8000-000000000201.json"
28
28
  },
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.2.0",
2
+ "contractVersion": "1.3.0",
3
3
  "logsRoot": "/Users/example/.claude/logs/multi-agent",
4
4
  "count": 1,
5
5
  "runs": [
@@ -68,7 +68,12 @@
68
68
  "estUsd": 0,
69
69
  "unlockedWrites": 0,
70
70
  "runType": "autopilot",
71
+ "mode": null,
71
72
  "title": null,
73
+ "source": null,
74
+ "prNumber": null,
75
+ "channels": [],
76
+ "channelUrls": {},
72
77
  "progress": 0,
73
78
  "currentTask": null,
74
79
  "processAlive": false
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.2.0",
2
+ "contractVersion": "1.3.0",
3
3
  "logsRoot": "/Users/example/.claude/logs/multi-agent",
4
4
  "count": 0,
5
5
  "runs": []
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.2.0",
2
+ "contractVersion": "1.3.0",
3
3
  "logsRoot": "/Users/example/.claude/logs/multi-agent",
4
4
  "count": 1,
5
5
  "runs": [
@@ -88,7 +88,12 @@
88
88
  "estUsd": 0.0353,
89
89
  "unlockedWrites": 0,
90
90
  "runType": "development",
91
+ "mode": null,
91
92
  "title": null,
93
+ "source": null,
94
+ "prNumber": null,
95
+ "channels": [],
96
+ "channelUrls": {},
92
97
  "progress": 0.75,
93
98
  "currentTask": null,
94
99
  "processAlive": null
@@ -64,7 +64,12 @@
64
64
  "cached": 1800
65
65
  },
66
66
  "estUsd": 0.0236,
67
- "unlockedWrites": 0
67
+ "unlockedWrites": 0,
68
+ "mode": null,
69
+ "source": null,
70
+ "prNumber": null,
71
+ "channels": [],
72
+ "channelUrls": {}
68
73
  }
69
74
  ]
70
75
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.2.0",
2
+ "contractVersion": "1.3.0",
3
3
  "count": 1,
4
4
  "runs": [
5
5
  {
@@ -109,7 +109,11 @@
109
109
  "estUsd": 0.0707,
110
110
  "unlockedWrites": 0,
111
111
  "runType": "development",
112
+ "mode": null,
112
113
  "title": null,
114
+ "source": null,
115
+ "prNumber": 104,
116
+ "channels": [],
113
117
  "progress": 1,
114
118
  "currentTask": null,
115
119
  "processAlive": null
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.2.0",
2
+ "contractVersion": "1.3.0",
3
3
  "logsRoot": "/Users/example/.claude/logs/multi-agent",
4
4
  "count": 1,
5
5
  "runs": [
@@ -114,7 +114,12 @@
114
114
  "estUsd": 0.0707,
115
115
  "unlockedWrites": 0,
116
116
  "runType": "development",
117
+ "mode": null,
117
118
  "title": null,
119
+ "source": null,
120
+ "prNumber": 104,
121
+ "channels": [],
122
+ "channelUrls": {},
118
123
  "progress": 1,
119
124
  "currentTask": null,
120
125
  "processAlive": null
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.2.0",
2
+ "contractVersion": "1.3.0",
3
3
  "logsRoot": "/Users/example/.claude/logs/multi-agent",
4
4
  "count": 1,
5
5
  "runs": [
@@ -99,7 +99,12 @@
99
99
  "estUsd": 0.0236,
100
100
  "unlockedWrites": 0,
101
101
  "runType": "autopilot",
102
+ "mode": null,
102
103
  "title": "Fix the crash on the login screen",
104
+ "source": null,
105
+ "prNumber": null,
106
+ "channels": [],
107
+ "channelUrls": {},
103
108
  "progress": 0.8333333333333334,
104
109
  "currentTask": {
105
110
  "subject": "Make the test pass",