@mmerterden/multi-agent-pipeline 20.24.0 → 20.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/docs/facts.json +3 -3
  3. package/docs/features.md +9 -4
  4. package/install/catalog-history.json +1 -1
  5. package/install/templates/claude-hooks.json +1 -1
  6. package/install/templates/codex-hooks.json +18 -0
  7. package/manifest.json +71 -68
  8. package/package.json +1 -1
  9. package/pipeline/agents/task-clarifier.md +1 -1
  10. package/pipeline/commands/multi-agent/model/SKILL.md +2 -2
  11. package/pipeline/commands/multi-agent/postmortem/SKILL.md +18 -6
  12. package/pipeline/commands/multi-agent/review/SKILL.md +5 -5
  13. package/pipeline/commands/multi-agent/route-on/SKILL.md +1 -1
  14. package/pipeline/commands/multi-agent/setup/SKILL.md +7 -5
  15. package/pipeline/commands/multi-agent/testflight-validation/SKILL.md +2 -3
  16. package/pipeline/contract/fixtures/runs-failed.json +1 -1
  17. package/pipeline/contract/fixtures/runs-old-schema.json +1 -1
  18. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +1 -1
  19. package/pipeline/contract/fixtures/runs-pr-opened.json +1 -1
  20. package/pipeline/contract/fixtures/runs-running.json +1 -1
  21. package/pipeline/lib/credential-inventory.sh +5 -5
  22. package/pipeline/lib/fetch-crashlytics.sh +6 -8
  23. package/pipeline/lib/model-rung.sh +1 -1
  24. package/pipeline/lib/plan-todos.sh +21 -4
  25. package/pipeline/lib/post-pr-review.sh +4 -6
  26. package/pipeline/lib/route-state.sh +1 -1
  27. package/pipeline/lib/shadow-git.sh +4 -5
  28. package/pipeline/multi-agent-refs/cross-cli-contract.md +4 -5
  29. package/pipeline/multi-agent-refs/features/cost-analysis.md +4 -0
  30. package/pipeline/multi-agent-refs/features/model-fallback.md +17 -12
  31. package/pipeline/multi-agent-refs/phases/phase-0-init.md +1 -1
  32. package/pipeline/multi-agent-refs/phases/phase-3-review.md +5 -5
  33. package/pipeline/multi-agent-refs/picker-contract.md +1 -1
  34. package/pipeline/multi-agent-refs/tracker-contract.md +6 -6
  35. package/pipeline/schemas/plan-todos.schema.json +4 -4
  36. package/pipeline/schemas/prefs.schema.json +4 -4
  37. package/pipeline/scripts/_code-graph.mjs +2 -2
  38. package/pipeline/scripts/_transcript-hosts.mjs +406 -0
  39. package/pipeline/scripts/build-stack-plugins.mjs +3 -3
  40. package/pipeline/scripts/capture-flush.sh +7 -7
  41. package/pipeline/scripts/code-graph-rules/android.json +1 -1
  42. package/pipeline/scripts/cost-analyze.mjs +26 -19
  43. package/pipeline/scripts/cost-table.json +35 -19
  44. package/pipeline/scripts/edit-syntax-gate.mjs +151 -29
  45. package/pipeline/scripts/edit-syntax-gate.sh +9 -6
  46. package/pipeline/scripts/gc-abandoned.sh +2 -2
  47. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -3
  48. package/pipeline/scripts/git-path.mjs +1 -2
  49. package/pipeline/scripts/host-hooks.mjs +265 -0
  50. package/pipeline/scripts/jira-attach.sh +1 -1
  51. package/pipeline/scripts/keychain.py +3 -3
  52. package/pipeline/scripts/output-quality-check.sh +1 -1
  53. package/pipeline/scripts/phase-tracker.sh +5 -6
  54. package/pipeline/scripts/phase0-exit-gate.mjs +3 -3
  55. package/pipeline/scripts/pre-push-check.sh +3 -6
  56. package/pipeline/scripts/transcript-index.mjs +423 -242
  57. package/pipeline/scripts/uninstall.mjs +90 -4
  58. package/pipeline/scripts/update-issue-progress.sh +4 -6
  59. package/pipeline/scripts/usage-report.mjs +2 -2
  60. package/pipeline/skills/.skill-manifest.json +8 -8
  61. package/pipeline/skills/shared/core/multi-agent/SKILL.md +6 -6
  62. package/pipeline/skills/shared/core/multi-agent-model/SKILL.md +2 -2
  63. package/pipeline/skills/shared/core/multi-agent-postmortem/SKILL.md +10 -7
  64. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +5 -5
  65. package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +1 -1
  66. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +7 -5
  67. package/pipeline/skills/shared/core/multi-agent-testflight-validation/SKILL.md +2 -3
  68. package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +2 -2
package/CHANGELOG.md CHANGED
@@ -16,6 +16,36 @@ Internal file-layout changes that don't affect the slash-command surface are sti
16
16
 
17
17
  ## [Unreleased]
18
18
 
19
+ ## [20.25.1] - 2026-10-14
20
+
21
+ ### Removed
22
+
23
+ - `/multi-agent:deps`, `dep-bump.mjs` and the `depBump` settings are removed: updating a project's own dependencies is outside what this pipeline does.
24
+
25
+ ## [20.25.0] - 2026-10-14
26
+
27
+ ### Added
28
+
29
+ - **Syntax check after an edit on Codex.** `edit-syntax-gate.sh` reads Codex's `PostToolUse` payload for `apply_patch` (every file the patch adds, updates or moves to) and answers in the shape Codex reads back. `/multi-agent:setup` Step 8 registers it through `host-hooks.mjs install --host codex` from the new `codex-hooks.json` template; Codex runs it once trusted in `/hooks`. Copilot CLI gets no registration: as of 1.0.45 it discards a `postToolUse` hook's output and applies no matcher, so the gate is Claude Code and Codex only. Still opt-in through `editSyntaxGate.enabled`, still never blocks; uninstall removes the registration, matching the template's full commands so the user's own hooks stay.
30
+ - **`/multi-agent:postmortem` reads Copilot CLI and Codex sessions.** `transcript-index.mjs` detects the format per file and indexes Copilot CLI session logs (`~/.copilot/session-state/<session>/events.jsonl`) and Codex rollouts (`~/.codex/sessions/**/rollout-*.jsonl`) into the same index with the same redaction, and `--run` finds a run's sessions on every host by session id or by checkout and time window. `COPILOT_TRANSCRIPTS_ROOT` and `CODEX_TRANSCRIPTS_ROOT` override the roots.
31
+ - **`/multi-agent:deps [package[@version]] [--major]`: bump one dependency and fix what it broke.** The normal pipeline with a fixed task (`state.mode: "deps"`, `taskType: chore`): pick a candidate (a picker when none is named), apply the bump, build and test, and when the run is red, fix rounds that may change only the files that use the dependency unless a build or test error names another. Each round is scope-checked; past `depBump.maxFixRounds` (default 2) the bump is rolled back (manifest, lockfile and the fix rounds' files; any other change is kept and listed) and the run reports what still fails instead of committing. A major, unparseable or prerelease bump needs `--major` or an explicit confirmation. Review gates, commit (`chore(deps): bump X from a to b`) and PR (`Ref:`, never a closing keyword) are the standard ones. Contract: `multi-agent-refs/features/dep-bump.md`.
32
+ - **`dep-bump.mjs`**, the deterministic half: `detect`, `list`, `apply`, `surface`, `scope`, `notes`, `rollback`, `config`, JSON out. SwiftPM (`Package.swift` / `Package.resolved`), Gradle version catalogs, npm and pip (`requirements*.txt`, `pyproject.toml`). Listing works offline from manifests, lockfiles, SwiftPM checkout tags and the Gradle module cache; `--registry` asks the ecosystem's own tool and notes a failed query per package. Risk is semver (a minor step under `0.x` counts as major, `+build` metadata is ignored, Maven release qualifiers such as `-jre` and `.Final` are stable under Gradle). Manifest names and urls are checked against their ecosystem's grammar before any registry tool sees them, and registry tools run in the manifest's directory. `apply` refuses a `--to` outside the ecosystem's version grammar (exit 2) and a worktree with uncommitted tracked changes; it edits only the dependency's own npm section, refuses a pip bump another clause excludes, widens SwiftPM ranges and skips commented `.package` calls, picks Poetry and yarn lockfile flags by tool version, uses a workspace root's lockfile, and lists Xcode-managed SwiftPM pins read-only. It updates the lockfile through the ecosystem tool and restores both files when that tool fails; a shared Gradle `version.ref` reports every module that moves with it. `scope` holds a fix to the surface recorded at apply: a file that starts importing the dependency passes only with an error line naming it in the `--log` it is given. `help` prints usage.
33
+ - **Settings** `depBump.maxFixRounds` (2) and `depBump.queryRegistry` (true); state root `depBump`.
34
+
35
+ ### Changed
36
+
37
+ - **Claude rungs move to the current generation.** `cost-table.json` resolves `fable` to `claude-fable-5-1` ($10 in / $50 out / $0.25 cache-read per MTok), `opus` to `claude-opus-5-5` ($4 / $20 / $0.20), `sonnet` to `claude-sonnet-5-5` ($2 / $10 / $0.10) and `haiku` to `claude-haiku-5-5` ($0.50 / $2.50 / $0.05, the over-100k-token tier, since the table holds one rate per rung and over-reporting is the safe direction for a ledger; prompts up to 100k bill at $0.10 / $0.50 / $0.01). The Claude Code column of the Phase 3 reviewer table, the review and orchestrator skills, the fallback contract and the live-eval pinned model follow. Copilot CLI dispatches the newest IDs `copilot help config` lists (1.0.45): `claude-opus-4.7`, `claude-sonnet-4.6` and `claude-haiku-4.5`, recorded per rung as `copilotModelId`; it lists no Fable model, so that rung is not offered there. `smoke-model-fallback.sh` accepts a `copilotModelId` as a known ID, checks each against `copilot help config` when the CLI is installed, and treats `claude-fable-5` and `claude-haiku-4-5` as retired. `cost-table.json` gains a `legacy` map of previous-generation wire IDs at their official prices (`claude-fable-5` $10 / $50 / $1, `claude-opus-5` $5 / $25 / $0.50, `claude-sonnet-5` $2 / $10 / $0.20, `claude-haiku-4-5` $1 / $5 / $0.10); `cost-analyze` prices a transcript by exact wire ID (current, Copilot or legacy) before matching a dated snapshot, so a session on a previous generation is priced at its own rate. A `models` map prices each `copilotModelId` at its own model's official rate (`claude-opus-4.7` $5 / $25 / $0.50, `claude-sonnet-4.6` $3 / $15 / $0.30, `claude-haiku-4.5` $1 / $5 / $0.10) ahead of the rung's, so a Copilot CLI session is not under-reported at the newer rung's lower price; the rung mapping still drives dispatch.
38
+ - The always-on description ceiling in `smoke-context-budget.sh` moves from 92500 to 93000 for the new command and its shared/core counterpart (181 bytes each).
39
+
40
+ ### Fixed
41
+
42
+ - `plan-todos.sh set` accepts the `T1`, `T2` ids a converted planning-output carries, and stops with exit 2 when a dependency matches no todo id exactly, naming an id that differs only in case.
43
+ - The syntax check after an edit looks at no more than 8 files per call and stops before a file would take the call past 8 s; the files it skipped are counted in its message, and when every checked file parsed a short note still says how many were not checked.
44
+ - `phases.json` declares the `deps` mode (all six phases), so the usage report counts a `/multi-agent:deps` run as `deps` rather than `unknown`.
45
+ - A Copilot CLI session with no `session.shutdown` record has its usage marked partial in the post-mortem.
46
+ - Uninstall removes every hook `claude-hooks.json` registers in `settings.json`, on every event, and leaves the user's own hooks in place.
47
+ - The Codex hooks file is written through a symlink with its mode kept, and a hooks file whose root or `hooks` value is not an object is refused with exit 1 and left unwritten.
48
+
19
49
  ## [20.24.0] - 2026-10-14
20
50
 
21
51
  ### Added
package/docs/facts.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "Generated by pipeline/scripts/gen-facts.mjs. Do not hand-edit: the site reads this, and a number edited here instead of at its source is the drift this file removes.",
3
- "generatedAt": "2026-10-13",
4
- "version": "20.24.0",
3
+ "generatedAt": "2026-10-14",
4
+ "version": "20.25.1",
5
5
  "phaseSchema": 2,
6
6
  "phases": [
7
7
  {
@@ -62,5 +62,5 @@
62
62
  "ui": 1
63
63
  },
64
64
  "pluginSkillCount": 252,
65
- "toolkitVersion": "3.22.2"
65
+ "toolkitVersion": "3.22.3"
66
66
  }
package/docs/features.md CHANGED
@@ -221,9 +221,9 @@ stamp fails the dispatch gate. Autopilot runs both phases; only the asking degra
221
221
 
222
222
  | Reviewer | Model | Focus | Where it runs |
223
223
  | ---------- | ------------------- | --------------------------------- | -------------------- |
224
- | Reviewer 1 | `claude-fable-5` (Claude Code) / `claude-opus-4-8` (Copilot CLI) | Deep security + architecture | Both CLIs |
225
- | Reviewer 2 | `gpt-5.4` | Edge cases, different perspective | **Copilot CLI only** |
226
- | Reviewer 3 | `claude-sonnet-4-6` | Quality + correctness + naming | Both CLIs |
224
+ | Reviewer 1 | `claude-fable-5-1` (Claude Code) / `claude-opus-4.7` (Copilot CLI) | Deep security + architecture | Both CLIs |
225
+ | Reviewer 2 | `claude-opus-5-5` (Claude Code) / `gpt-5.4` (Copilot CLI) | Edge cases, different perspective | Both CLIs |
226
+ | Reviewer 3 | `claude-sonnet-5-5` (Claude Code) / `claude-sonnet-4.6` (Copilot CLI) | Quality + correctness + naming | Both CLIs |
227
227
 
228
228
  The reviewer set is **CLI-aware**: Claude Code dispatches 3 reviewers in parallel (Fable + Opus + Sonnet - Opus fills the slot GPT-5.4 takes elsewhere); Copilot CLI dispatches all 3. Each returns structured JSON for deterministic aggregation. Cross-model diversity catches blind spots that any single model family would miss.
229
229
 
@@ -355,8 +355,9 @@ Commands (`commands.mjs --json`) and run questions (`launch-request.mjs question
355
355
  - **Pre-Commit Secret Detection** (12 patterns): `PreToolUse` hook scans staged files for API keys/tokens, AWS access keys, private keys, `.env` files, service account JSON. Commit **blocked** if found.
356
356
  - **Read-Size Gate** (opt-in, `prefs.global.bulkRead.mode`): a `PreToolUse` hook inspects `Read` and the shell commands that read a file whole. In `observe` it only logs what it would have caught - the baseline you measure before routing anything. In `enforce` a file over `minLines` (default 350) is blocked and delegated to a haiku-rung worker (`bulk-read.sh`), which returns a line-numbered summary so the follow-up is a bounded `Read(offset:limit:)` instead of the whole file; the full text is parked under `.multi-agent/refs/`. The development phase and any file the run has already touched are exempt, because Claude Code's `Edit` requires its own `Read` first.
357
357
  - **Free models for simple work** (opt-in, `/multi-agent:route-on --free`): large-file reads, log and document summaries, field extraction, labels and translation or commit-body drafts go to the multi-agent-toolkit's free-model chain (`llm_delegate`) first. Every answer is verified against its source and discarded when it does not hold, Claude takes over whenever none passes, and decisions, plans, code and reviews never leave Claude. By default only providers that do not train on prompts receive text. `route-status` reports what was answered free and the tokens kept off Claude; `doctor --probe` checks each provider key. Contract: `multi-agent-refs/features/free-models.md`.
358
- - **Capture Hooks** (`SessionEnd`, `PreCompact`, `SessionStart`): every durable write used to live in Phase 5, the phase a run is least likely to reach. `SessionEnd` flushes a run that never got there; `PreCompact` flushes before an auto-compaction summarizes a long phase mid-flight, which is the same loss one level down; `SessionStart` prints at most two lines about an unfinished run. None calls a model, none reads a payload, and all exit 0 on every path - a hook that fails a session over bookkeeping is worse than the bookkeeping.
358
+ - **Capture Hooks** (`SessionEnd`, `PreCompact`, `SessionStart`): durable writes do not wait for Phase 5, the phase a run is least likely to reach. `SessionEnd` flushes a run that never got there; `PreCompact` flushes before an auto-compaction summarizes a long phase mid-flight, which is the same loss one level down; `SessionStart` prints at most two lines about an unfinished run. None calls a model, none reads a payload, and all exit 0 on every path - a hook that fails a session over bookkeeping is worse than the bookkeeping.
359
359
  - **Operational Reporting** (`prefs.global.usageLog`): coarse run metadata - task id and type, current phase, run status (in progress, completed, halted, parked), phase durations, whether a PR opened, token counts - sent at every phase transition and at completion, halt and park, and never prompts, code, diffs or absolute paths (task title and PR URL only when `includeTitle` / `includePrUrl` are set). Runs are reported under the GitHub account on the machine that can read the pipeline repository, found with no question asked through gh, the git credential helper or an SSH key (`usage-identity.mjs`, cached in `usageLog.login` / `loginMethod`, `--refresh` to re-check); with no such account nothing is sent. The per-machine token is REQUESTED from the endpoint by `usage-register.mjs` (setup, update, and the Phase 0 exit gate as a backstop), is write-only, and lives in the OS credential store; prefs hold only the entry name and the switch. `usageLog.optOut: true` blocks registration permanently and is checked before the network call. Registration proves the login with that account's gh or credential-helper token, or with an SSH signature over a server challenge. The server issues a token only to the repository owner or a collaborator, pins the login to it, and shows only those accounts' records on the panel. An unreachable endpoint leaves reporting off with one line and exit 0 - a run is never failed over bookkeeping.
360
+ - **Post-Edit Syntax Gate** (opt-in, `prefs.global.editSyntaxGate.enabled`): after a file edit, `edit-syntax-gate.sh` parses the file within 2 s (`swiftc -parse`, `node --check`, `py_compile` into a temp dir, JSON, `bash -n`; Kotlin skipped) and hands a syntax error to the model as hook context. It never blocks and stays silent when a parser is missing or slow. Registered on Claude Code and Codex: Claude Code `PostToolUse` on `Edit|Write|MultiEdit` (`claude-hooks.json`), Codex `PostToolUse` on `apply_patch`, checking every file the patch adds, updates or moves to (`codex-hooks.json`, merged into `~/.codex/hooks.json`, run once trusted in Codex's `/hooks`). `/multi-agent:setup` Step 8 offers it; on Codex it calls `host-hooks.mjs install`, and uninstall takes it back. Copilot CLI gets no registration: as of 1.0.45 it loads `~/.copilot/hooks/*.json` but discards a `postToolUse` hook's output and applies no matcher, so the gate would spawn on every tool call and the model would never see its message. Source for the Codex contract: the Codex hooks guide plus `codex-rs` (`hooks/src/engine`, `core/src/tools/handlers/apply_patch.rs`).
360
361
  - **Build Queue**: All `xcodebuild` calls acquire a lock. Each worktree uses own `-derivedDataPath`. Stale locks auto-clean after 15 min. Non-Xcode builds don't need the lock.
361
362
  - **Context Management**: `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=65` - compaction at 65% usage (prevents degradation in 6-phase sessions).
362
363
  - **3-Iteration Hard Kill**: Any retry loop stops after 3 attempts, then pauses for user. No infinite loops.
@@ -403,6 +404,10 @@ Per-phase token budgets prevent runaway sessions. If a phase exceeds its budget,
403
404
  - **Phase Banner**: Terminal UI for phase transitions with Unicode box-drawing characters.
404
405
  - **Per-task Cost Breakdown in agent-log.md**: Phase 5 appends a 4-column block (Phase · Model · Tokens in/out · Est. USD) to every run's `agent-log.md`. Sourced from `phase-tracker.sh tokens` accumulators × `cost-table.json` prices. Independent of the channels-side `reportContent.costSummary` toggle. The `LOG_METRIC_FORWARD_TO_TRACKER=1` env flag mirrors `tokens_in`/`tokens_out`/`model` from `log-metric.sh` into the tracker so JSONL metrics and the cost block stay in sync from one call site.
405
406
 
407
+ ### Run Post-Mortem (`/multi-agent:postmortem`)
408
+
409
+ `transcript-index.mjs` reads a run's session transcripts from any host and detects the format per file: Claude Code (`~/.claude/projects/<dir>/<session>.jsonl` plus subagent files), Copilot CLI (`~/.copilot/session-state/<session>/events.jsonl`) and Codex (`~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl`). Each host's records are converted into one index: turns, tool calls, loops of identical calls, stalls, compactions, subagents, errors and denials, invocations and token use, every item cited as `file:line` and every excerpt redacted before it is printed. A run is found by its recorded session id on any host, else by the sessions whose working directory was the run's checkout inside its time window (reported as a heuristic). Copilot CLI reports tokens per session, so its totals come from the shutdown record; Codex reports them per request. `COPILOT_TRANSCRIPTS_ROOT` and `CODEX_TRANSCRIPTS_ROOT` override the two roots, as `TRANSCRIPTS_ROOT` does for Claude Code.
410
+
406
411
  ### Diff Risk Scoring
407
412
 
408
413
  `pipeline/scripts/diff-risk-score.mjs` runs at Phase 3 Step 1.75 - before reviewer dispatch. Heuristic, deterministic, sub-second, no LLM. Top-N risk-ranked files inject into each reviewer's prompt as a `${PRIORITY_FILES}` block; reviewers read those files first but still review the entire diff.