@mmerterden/multi-agent-pipeline 15.0.0 → 15.2.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 (39) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/README.md +9 -9
  3. package/README.tr.md +9 -9
  4. package/SECURITY.md +43 -0
  5. package/docs/adr/0007-multi-tool-adapter-framework.md +1 -1
  6. package/docs/architecture.md +9 -9
  7. package/docs/ecosystem.md +10 -10
  8. package/index.js +4 -1
  9. package/install/_common.mjs +44 -2
  10. package/install/_platform-filter.mjs +6 -131
  11. package/install/_plugin-skills.mjs +17 -28
  12. package/install/claude.mjs +111 -6
  13. package/install/codex.mjs +0 -3
  14. package/install/copilot.mjs +36 -1
  15. package/install/index.mjs +3 -1
  16. package/package.json +2 -2
  17. package/pipeline/commands/multi-agent/refactor/SKILL.md +36 -1
  18. package/pipeline/commands/multi-agent/scan/SKILL.md +1 -1
  19. package/pipeline/commands/multi-agent/stack/SKILL.md +18 -8
  20. package/pipeline/commands/multi-agent/update/SKILL.md +31 -4
  21. package/pipeline/lib/parse-complaints.sh +12 -2
  22. package/pipeline/multi-agent-refs/complaint-analysis-template.md +1 -1
  23. package/pipeline/multi-agent-refs/phases/operations.md +7 -1
  24. package/pipeline/multi-agent-refs/phases/phase-7-report.md +6 -0
  25. package/pipeline/multi-agent-refs/tracker-contract.md +2 -1
  26. package/pipeline/preferences-template.json +6 -0
  27. package/pipeline/schemas/prefs.schema.json +27 -0
  28. package/pipeline/scripts/README.md +4 -3
  29. package/pipeline/scripts/check-derived-drift.mjs +5 -2
  30. package/pipeline/scripts/match-skills.mjs +4 -0
  31. package/pipeline/scripts/migrate-prefs.mjs +5 -1
  32. package/pipeline/scripts/phase-tracker.sh +19 -0
  33. package/pipeline/scripts/uninstall.mjs +3 -1
  34. package/pipeline/scripts/usage-report.mjs +457 -0
  35. package/pipeline/scripts/validate-complaint-doc.mjs +32 -11
  36. package/pipeline/skills/.skill-manifest.json +4 -4
  37. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +153 -90
  38. package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +18 -8
  39. package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +1 -1
package/CHANGELOG.md CHANGED
@@ -16,6 +16,133 @@ Internal file-layout changes that don't affect the slash-command surface are sti
16
16
 
17
17
  ## [Unreleased]
18
18
 
19
+ ## [15.2.0] - 2026-08-15
20
+
21
+ ### Added
22
+
23
+ - **`/multi-agent:update` auto-enables usage logging when a token is onboarded.**
24
+ The private dashboard stays opt-in and off by default, but once the shared
25
+ ingest token exists on a machine, an update flips `usageLog.enabled` on so the
26
+ admin's trusted group does not each have to toggle it by hand. It NEVER
27
+ fabricates or ships a secret: it activates only when a token resolves from
28
+ `MULTI_AGENT_USAGE_TOKEN`, `usageLog.token`, or the Keychain item named by the
29
+ new generic `keychainMapping.usage_ingest` slot - a machine that was never
30
+ given the token stays silent.
31
+ - **`usage-report.mjs` reads the ingest token from the Keychain** (via
32
+ `credential-store.sh`, resolved through `keychainMapping.usage_ingest`) as a
33
+ fallback after env and `usageLog.token`, so the secret never has to live in a
34
+ synced or plaintext file for logging to work.
35
+
36
+ ## [15.1.0] - 2026-08-14
37
+
38
+ Opt-in run telemetry to a private dashboard, and a refactor band that mines it.
39
+
40
+ ### Added
41
+
42
+ - **Opt-in usage telemetry (`usageLog`).** When `prefs.global.usageLog.enabled`
43
+ is set with an ingest token, each run emits one activity event, keyed by task
44
+ id and refreshed live at every phase boundary via `phase-tracker.sh`, so one
45
+ record always shows the last phase a run reached — including runs that halt
46
+ before Phase 7. Wired at Phase 7 report and the halt path; detached and
47
+ best-effort, never blocking a run. The event carries activity metadata only
48
+ (who, command, mode, input type, repo, phase, outcome, halt cause, review
49
+ iterations, duration, token spend, cost, per-phase breakdown, OS, CLI, models,
50
+ stack, plugins, integrations, credential health, invoked skills, error tags,
51
+ version) — never prompts, code, diffs, token values or absolute paths. New
52
+ `pipeline/scripts/usage-report.mjs`; prefs schema + template gain the
53
+ `usageLog` block. Off by default; the emitter no-ops unless enabled and a
54
+ token resolves.
55
+ - **`/multi-agent:refactor` Step 0d (band F).** Reads the local run-error ledger
56
+ (`errors-ledger.jsonl`, written by the telemetry emitter on terminal runs) and
57
+ ranks recurring failures as prioritized improvement areas — lived evidence,
58
+ offline, and without auth.
59
+
60
+ ### Changed
61
+
62
+ - Reconciled the Copilot shared-core `multi-agent-refactor` skill with the Claude
63
+ command version, ending the prose drift that had accumulated between the two.
64
+
65
+ ## [15.0.1] - 2026-08-13
66
+
67
+ Post-15.0.0 audit release: three blocking defects in the 15.0.0 surface, two
68
+ data-loss paths, and the doc drift that let a command count go stale in 17
69
+ places at once.
70
+
71
+ ### Fixed
72
+
73
+ - **The 15.0.0 plugin-only migration never ran on an upgrade.** Its prune was
74
+ gated on `.external-skills-manifest.json`, which no released version wrote on
75
+ Claude Code, so every machine upgrading from 14.x kept the whole ~151-dir
76
+ external catalog (the duplicated per-session descriptions and plugin-shadowing
77
+ copies ADR-0009 exists to remove), and `uninstall --claude` refused to clean it
78
+ for the same reason. Pre-manifest installs are now migrated by proof rather
79
+ than by name: a skill dir byte-identical to the shipped catalog is provably
80
+ pipeline-delivered and is removed, a dir that differs is kept and reported,
81
+ and the new `install --prune-external` flag removes those too (still never a
82
+ dir carrying `local-only: true`). Gate: `smoke-claude-external-migration.sh`.
83
+ - **The cross-host stack filter read a file nothing writes.** `pluginsToDeliver`
84
+ looked only at `~/.claude/settings.json` while `/multi-agent:stack` writes the
85
+ invoking repo's `.claude/settings.json`, so a stack selection either delivered
86
+ the entire catalog to Copilot/Codex (logged as if a filter had run) or, worse,
87
+ delivered a different stack than the repo asked for. Repo settings are now read
88
+ first, user-global second, `--platform` last.
89
+ - **Copilot's skipped-stack prune could delete user-authored skills.** The prune
90
+ was derived from catalog *names*, so a user's own `~/.copilot/skills/<name>/`
91
+ sharing a catalog name was removed with no prompt. It is now scoped to the
92
+ previous delivery manifest (or, pre-manifest, to dirs byte-identical to the
93
+ catalog) - the same contract `uninstall` already used.
94
+ - **Manifest-driven removal had no path containment.** A name carrying `..` or a
95
+ path separator in `.external-skills-manifest.json` resolved outside the skills
96
+ directory before reaching a recursive delete.
97
+ - **`validate-complaint-doc.mjs` rejected reports that follow the template.**
98
+ Section 1's coverage table cites `C-NN` ids in its last column and was read as
99
+ verdict-less triage rows, and verdict matching was positional-substring, so a
100
+ summary cell mentioning `core-data` classified the row as `core`. Triage rows
101
+ are now scoped to the Triage section with the id in the first cell, and verdict
102
+ tokens match cell-exact. The smoke fixture carries both Section 1 tables so the
103
+ gate is exercised against real template output.
104
+ - **`/multi-agent:stack` with no arguments wiped the repo's stack selection.**
105
+ The implementation block resolved an empty arg list to "common only" and then
106
+ applied the write rule that sets every other stack toolkit to `false`. Zero
107
+ args now exits into status mode, and the picker's `frontend (web)` label maps
108
+ back to its canonical arg.
109
+ - `parse-complaints.sh` returns the documented exit 4 when `--file` / `--format`
110
+ is passed without a value instead of dying on `set -u`, and redacts all-letter
111
+ PNRs that follow a PNR-ish keyword.
112
+ - `migrate-prefs.mjs`: the schema-unreadable fallback set now includes `2.5.0`,
113
+ so a 14.x prefs file no longer throws `unknown schemaVersion` on an install
114
+ tree whose `schemas/` cannot be read.
115
+ - `check-derived-drift.mjs`: an acknowledged drift pin no longer silences a
116
+ cache-only resolution, which had let the gate exit 0 while nothing
117
+ authoritative was consulted.
118
+ - `match-skills.mjs` gains the `~/.codex/multi-agent-refs/skills` index
119
+ candidate, so dynamic skill loading works on Codex instead of exiting 1.
120
+
121
+ ### Changed
122
+
123
+ - `smoke-command-inventory.sh` now derives the command count for `README.md`,
124
+ `README.tr.md`, `docs/architecture.md` and `docs/ecosystem.md` as well. Those
125
+ four files held 17 of the 20 "50 commands" sites and none was gated, so adding
126
+ `complaint-analysis` desynced all of them at once.
127
+ - Doc corrections: autopilot / local modes document 7 phases, not 8 (the
128
+ interactive Phase 5 test gate is dropped in every autopilot and local variant,
129
+ per `gen-mode-dispatch.mjs`) - README EN+TR and `tracker-contract.md`; the
130
+ Node badge matches `engines` (20.11+); the publish diagrams say public npm
131
+ rather than GitHub Packages; skill / schema / fixture counts match the tree;
132
+ `ecosystem.md` drops the retracted "frozen `figma-*` fallback" claim; ROADMAP
133
+ catches up four majors; ADR-0007 records Codex's return as a native target.
134
+ - `SECURITY.md` ships in the package, so the README link resolves on npmjs and
135
+ in an installed tree. Install help documents `--dry-run`, `--index-only` and
136
+ `--prune-external`.
137
+
138
+ ### Removed
139
+
140
+ - Dead pre-v15 code: `copyExternalSkillsFiltered`, `classifyExternalSkill` and
141
+ its prefix tables (superseded by the routing table), `existingSkillNames`
142
+ (superseded by `pipelineOwnedSkillNames`, and a hazard if called), and an
143
+ unconsumed `MCP_SERVER_NAME` re-export. Six internals no longer export a
144
+ surface nothing imports.
145
+
19
146
  ## [15.0.0] - 2026-08-13
20
147
 
21
148
  ### Changed (BREAKING)
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![GitHub Release](https://img.shields.io/github/v/release/mmerterden/multi-agent-pipeline?color=blue)](https://github.com/mmerterden/multi-agent-pipeline/releases)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Node.js](https://img.shields.io/badge/Node.js-18%20%7C%2020%20%7C%2022-green)](https://nodejs.org)
5
+ [![Node.js](https://img.shields.io/badge/Node.js-20%20%7C%2022-green)](https://nodejs.org)
6
6
  [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](https://github.com/mmerterden/multi-agent-pipeline/blob/main/package.json)
7
7
  [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/mmerterden/multi-agent-pipeline/badge)](https://scorecard.dev/viewer/?uri=github.com/mmerterden/multi-agent-pipeline)
8
8
 
@@ -70,14 +70,14 @@ The discipline behind all of this - bounded loops, evidence gates, token-budgete
70
70
  | Mode | Command | Flow |
71
71
  |---|---|---|
72
72
  | Full | `/multi-agent "task"` | All 8 phases, interactive |
73
- | Autopilot | `/multi-agent:autopilot "task"` | All 8 phases, no confirmations |
73
+ | Autopilot | `/multi-agent:autopilot "task"` | 7 phases (interactive Test gate dropped), no confirmations |
74
74
  | Dev | `/multi-agent:dev "task"` | Init → Dev → Review → Test → Commit → Report |
75
- | Local | `/multi-agent:local "task"` | Full pipeline, current branch (no worktree) |
75
+ | Local | `/multi-agent:local "task"` | Full pipeline minus the interactive Test gate, current branch (no worktree) |
76
76
  | Ship | `/multi-agent:resume-local` | Run the review→test→commit→report tail over local work |
77
77
  | Audit | `/multi-agent:design-check` | Mock-mode vs Figma conformance, local-only |
78
78
  | Audit | `/multi-agent:testflight-validation` | Pre-submission gates for a TestFlight build: static archive audit → Apple's `altool --validate-app` → Review-Guidelines check. Validates only, never uploads |
79
79
 
80
- Helpers: `setup`, `status`, `resume #N`, `kill #N`, `garbage-collect`, `prune-logs`, `purge`, `review`, `test`, `channels`, `stack`, `update`, `sync`, `refactor`, `jira`, `issue`, `analysis`, `create-jira`, `save`, `routines`, `forget`. 50 commands in all - full list: `/multi-agent:help`.
80
+ Helpers: `setup`, `status`, `resume #N`, `kill #N`, `garbage-collect`, `prune-logs`, `purge`, `review`, `test`, `channels`, `stack`, `update`, `sync`, `refactor`, `jira`, `issue`, `analysis`, `create-jira`, `save`, `routines`, `forget`. 51 commands in all - full list: `/multi-agent:help`.
81
81
 
82
82
  ## Stacks
83
83
 
@@ -91,17 +91,17 @@ This enables the matching plugin (+ the shared `ai-common` plugin) in the repo's
91
91
 
92
92
  ## Tool support
93
93
 
94
- The pipeline runs natively on **Claude Code**, **Copilot CLI** and **Codex CLI** - all three install from the same `pipeline/` source and get the same 50 commands.
94
+ The pipeline runs natively on **Claude Code**, **Copilot CLI** and **Codex CLI** - all three install from the same `pipeline/` source and get the same 51 commands.
95
95
 
96
96
  | Tool | Flag | What it installs |
97
97
  |---|---|---|
98
98
  | Claude Code | `--claude` (default) | slash commands + skills + agents + `PreToolUse` secret-scan hook |
99
- | Copilot CLI | `--copilot` | instructions + 50 sub-command skills + scripts |
100
- | Codex CLI | `--codex` | one router skill + 50 specs as refs + 8 agent TOML + `AGENTS.md` block + `codex mcp add` |
99
+ | Copilot CLI | `--copilot` | instructions + 51 sub-command skills + scripts |
100
+ | Codex CLI | `--codex` | one router skill + 51 specs as refs + 8 agent TOML + `AGENTS.md` block + `codex mcp add` |
101
101
 
102
102
  Filter skills by stack with `--platform=ios\|android\|all`.
103
103
 
104
- **Why Codex gets one skill and not 50.** Codex assembles every discovered skill's name
104
+ **Why Codex gets one skill and not 51.** Codex assembles every discovered skill's name
105
105
  and description into a single prompt block and drops entries when it overflows, with no
106
106
  error. Measured on 0.145: installing one plugin that declares 142 skills surfaced only
107
107
  75 of them and evicted an unrelated user skill. So on Codex the pipeline ships a single
@@ -135,7 +135,7 @@ The **secret scan** runs as a `PreToolUse` hook on Claude Code (hard-blocks a co
135
135
 
136
136
  ## Platform support
137
137
 
138
- Runs on **macOS**, **Linux**, and **Windows** (Git Bash / WSL). Shell and credential access go through a platform-agnostic layer - the keychain resolves automatically to **macOS Keychain**, **Linux libsecret** (`secret-tool`), or **Windows Credential Manager**, and scripts fall back between BSD and GNU tool variants. Node.js 18 / 20 / 22.
138
+ Runs on **macOS**, **Linux**, and **Windows** (Git Bash / WSL). Shell and credential access go through a platform-agnostic layer - the keychain resolves automatically to **macOS Keychain**, **Linux libsecret** (`secret-tool`), or **Windows Credential Manager**, and scripts fall back between BSD and GNU tool variants. Node.js 20.11+ (tested on 20 and 22).
139
139
 
140
140
  ## Companion repos
141
141
 
package/README.tr.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![GitHub Release](https://img.shields.io/github/v/release/mmerterden/multi-agent-pipeline?color=blue)](https://github.com/mmerterden/multi-agent-pipeline/releases)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Node.js](https://img.shields.io/badge/Node.js-18%20%7C%2020%20%7C%2022-green)](https://nodejs.org)
5
+ [![Node.js](https://img.shields.io/badge/Node.js-20%20%7C%2022-green)](https://nodejs.org)
6
6
  [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](https://github.com/mmerterden/multi-agent-pipeline/blob/main/package.json)
7
7
  [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/mmerterden/multi-agent-pipeline/badge)](https://scorecard.dev/viewer/?uri=github.com/mmerterden/multi-agent-pipeline)
8
8
 
@@ -70,14 +70,14 @@ Bunun arkasındaki disiplin - sınırlı loop'lar, kanıt kapıları, token-büt
70
70
  | Mod | Komut | Akış |
71
71
  |---|---|---|
72
72
  | Full | `/multi-agent "task"` | Tüm 8 faz, interaktif |
73
- | Autopilot | `/multi-agent:autopilot "task"` | Tüm 8 faz, onaysız |
73
+ | Autopilot | `/multi-agent:autopilot "task"` | 7 faz (interaktif Test kapısı atlanır), onaysız |
74
74
  | Dev | `/multi-agent:dev "task"` | Init → Dev → Review → Test → Commit → Report |
75
- | Local | `/multi-agent:local "task"` | Tam pipeline, mevcut branch (worktree yok) |
75
+ | Local | `/multi-agent:local "task"` | İnteraktif Test kapısı hariç tam pipeline, mevcut branch (worktree yok) |
76
76
  | Ship | `/multi-agent:resume-local` | Lokal iş üzerinde review→test→commit→report kuyruğunu çalıştır |
77
77
  | Audit | `/multi-agent:design-check` | Mock-mode vs Figma uygunluğu, yalnızca lokal |
78
78
  | Audit | `/multi-agent:testflight-validation` | TestFlight build için pre-submission kapıları: statik archive denetimi → Apple'ın `altool --validate-app`'i → Review-Guidelines kontrolü. Yalnızca doğrular, asla yüklemez |
79
79
 
80
- Yardımcılar: `setup`, `status`, `resume #N`, `kill #N`, `garbage-collect`, `prune-logs`, `purge`, `review`, `test`, `channels`, `stack`, `update`, `sync`, `refactor`, `jira`, `issue`, `analysis`, `create-jira`, `save`, `routines`, `forget`. Toplam 50 komut - tam liste: `/multi-agent:help`.
80
+ Yardımcılar: `setup`, `status`, `resume #N`, `kill #N`, `garbage-collect`, `prune-logs`, `purge`, `review`, `test`, `channels`, `stack`, `update`, `sync`, `refactor`, `jira`, `issue`, `analysis`, `create-jira`, `save`, `routines`, `forget`. Toplam 51 komut - tam liste: `/multi-agent:help`.
81
81
 
82
82
  ## Stack'ler
83
83
 
@@ -91,17 +91,17 @@ Bu, ilgili plugin'i (+ ortak `ai-common` plugin'ini) repo'nun `.claude/settings.
91
91
 
92
92
  ## Araç desteği
93
93
 
94
- Pipeline **Claude Code**, **Copilot CLI** ve **Codex CLI** üzerinde native çalışır - üçü de aynı `pipeline/` kaynağından kurulur ve aynı 50 komutu alır.
94
+ Pipeline **Claude Code**, **Copilot CLI** ve **Codex CLI** üzerinde native çalışır - üçü de aynı `pipeline/` kaynağından kurulur ve aynı 51 komutu alır.
95
95
 
96
96
  | Araç | Bayrak | Ne kurar |
97
97
  |---|---|---|
98
98
  | Claude Code | `--claude` (varsayılan) | slash komutları + skill'ler + agent'lar + `PreToolUse` secret-scan hook'u |
99
- | Copilot CLI | `--copilot` | talimatlar + 50 alt-komut skill'i + script'ler |
100
- | Codex CLI | `--codex` | bir router skill + ref olarak 50 spec + 8 agent TOML + `AGENTS.md` bloğu + `codex mcp add` |
99
+ | Copilot CLI | `--copilot` | talimatlar + 51 alt-komut skill'i + script'ler |
100
+ | Codex CLI | `--codex` | bir router skill + ref olarak 51 spec + 8 agent TOML + `AGENTS.md` bloğu + `codex mcp add` |
101
101
 
102
102
  Skill'leri stack'e göre filtrele: `--platform=ios\|android\|all`.
103
103
 
104
- **Codex neden 50 değil de tek bir skill alıyor.** Codex, keşfettiği her skill'in adını
104
+ **Codex neden 51 değil de tek bir skill alıyor.** Codex, keşfettiği her skill'in adını
105
105
  ve açıklamasını tek bir prompt bloğuna toplar ve blok taştığında girdileri hatasızca
106
106
  düşürür. 0.145 üzerinde ölçüldü: 142 skill deklare eden bir plugin kurulduğunda sadece
107
107
  75'i yüzeye çıktı ve alakasız bir kullanıcı skill'i tahliye edildi. Bu yüzden Codex'te
@@ -136,7 +136,7 @@ triage notu bunu belirtir.
136
136
 
137
137
  ## Platform desteği
138
138
 
139
- **macOS**, **Linux** ve **Windows** (Git Bash / WSL) üzerinde çalışır. Shell ve credential erişimi platform-agnostik bir katmandan geçer - keychain otomatik olarak **macOS Keychain**, **Linux libsecret** (`secret-tool`) veya **Windows Credential Manager**'a çözülür, ve script'ler BSD ile GNU araç varyantları arasında fallback yapar. Node.js 18 / 20 / 22.
139
+ **macOS**, **Linux** ve **Windows** (Git Bash / WSL) üzerinde çalışır. Shell ve credential erişimi platform-agnostik bir katmandan geçer - keychain otomatik olarak **macOS Keychain**, **Linux libsecret** (`secret-tool`) veya **Windows Credential Manager**'a çözülür, ve script'ler BSD ile GNU araç varyantları arasında fallback yapar. Node.js 20.11+ (20 ve 22'de test edildi).
140
140
 
141
141
  ## Yan repolar
142
142
 
package/SECURITY.md ADDED
@@ -0,0 +1,43 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ We provide security fixes for the latest minor of the current major. Older versions get fixes only for severity ≥ high.
6
+
7
+ | Version | Supported |
8
+ | ------- | ---------------------- |
9
+ | 12.x | ✅ active |
10
+ | 11.x | ⚠️ security fixes only |
11
+ | ≤ 10.x | ❌ end-of-life |
12
+
13
+ ## Reporting a Vulnerability
14
+
15
+ **Do not open a public GitHub issue for security reports.**
16
+
17
+ Please report vulnerabilities privately via GitHub's [Security Advisory](https://github.com/mmerterden/multi-agent-pipeline/security/advisories/new) flow. If GitHub Advisories are unavailable to you, email the package owner (see `package.json` → `author`) with:
18
+
19
+ - A clear description of the issue and its impact
20
+ - Steps to reproduce (a minimal repro is most helpful)
21
+ - Affected version(s) and platform
22
+ - Optional: a suggested patch or mitigation
23
+
24
+ You should receive an initial acknowledgement within **5 business days**. We'll keep you updated on progress and aim to release a patch within **30 days** for high/critical issues.
25
+
26
+ ## Scope
27
+
28
+ This pipeline orchestrates external systems (Jira, Bitbucket, GitHub, Confluence, Figma) using user-supplied tokens. We consider the following in scope for security reports:
29
+
30
+ - **Token leakage** - any code path that logs, echoes, or persists secrets outside macOS Keychain.
31
+ - **Command injection** - bash invocations built from untrusted input (Jira summary, branch names, PR titles, etc.).
32
+ - **Pre-commit bypass** - secret-detection hook silently failing or being skippable without `--no-verify`.
33
+ - **Pipeline tampering** - agent-state.json or preferences manipulation that escalates an installed package's effective permissions.
34
+
35
+ Out of scope:
36
+
37
+ - Misconfigured user systems (broken Keychain, expired tokens, missing CLI tools).
38
+ - Vulnerabilities in transitive dependencies that don't reach a code path we use (please report those upstream first).
39
+ - Issues that require an attacker to already control the user's local machine.
40
+
41
+ ## Coordinated Disclosure
42
+
43
+ We follow standard coordinated disclosure: researchers are credited (with permission) in the release notes once a fix is shipped. Public disclosure timelines are agreed with the reporter, defaulting to 90 days from initial report or 30 days after a patch is released - whichever is earlier.
@@ -1,6 +1,6 @@
1
1
  # 7. Multi-tool adapter framework + token-preserving uninstall
2
2
 
3
- **Status:** Superseded · 2026-07-02 (v10.7.0 removed all non-native adapters - the pipeline targets Claude Code + Copilot CLI only). Original acceptance: 2026-04-27 (v7.7.0 / v7.9.0). Kept as the historical record of why the adapter framework existed; install flags documented below no longer exist.
3
+ **Status:** Superseded · 2026-07-02 (v10.7.0 removed all non-native adapters - the pipeline targets Claude Code + Copilot CLI only; Codex CLI was later added as a third NATIVE target in v13.0.0, not through this adapter framework). Original acceptance: 2026-04-27 (v7.7.0 / v7.9.0). Kept as the historical record of why the adapter framework existed; install flags documented below no longer exist.
4
4
 
5
5
  ## Context
6
6
 
@@ -54,7 +54,7 @@ graph TD
54
54
  DIFF["Code Diff"]
55
55
 
56
56
  DIFF --> R1["Fable (Claude Code) / Opus (Copilot)<br/>Security + Architecture"]
57
- DIFF --> GPT["GPT-5.4<br/>Quality + Edge Cases"]
57
+ DIFF --> GPT["GPT-5.4<br/>Quality + Edge Cases<br/>(Copilot CLI only)"]
58
58
  DIFF --> SON["Sonnet<br/>Correctness + Style"]
59
59
 
60
60
  R1 --> TRIAGE["Fable Triage<br/>(Opus on Copilot CLI)"]
@@ -117,17 +117,17 @@ graph TB
117
117
  end
118
118
 
119
119
  subgraph "Pipeline Specs"
120
- CMD[commands/<br/>50 command files]
120
+ CMD[commands/<br/>51 command files]
121
121
  AGT[agents/<br/>8 agent personas]
122
122
  RUL[rules/<br/>12 domain rules]
123
123
  PHS[multi-agent-refs/phases/<br/>phase specs + contracts]
124
124
  CMP[skills/shared/core/<br/>orchestration skills<br/>incl. compliance]
125
- EXT["skills/shared/external/<br/>150 curated skills<br/>(authoring source for the<br/>multi-agent-plugins marketplace)"]
125
+ EXT["skills/shared/external/<br/>151 curated skills<br/>(authoring source for the<br/>multi-agent-plugins marketplace)"]
126
126
  end
127
127
 
128
128
  subgraph "Quality Gates"
129
- SCH[schemas/<br/>17 JSON schemas]
130
- EVL[eval/triage/<br/>12 regression fixtures]
129
+ SCH[schemas/<br/>19 JSON schemas]
130
+ EVL[eval/triage/<br/>11 regression fixtures]
131
131
  SMK[scripts/smoke-*<br/>100+ smoke suites]
132
132
  end
133
133
 
@@ -169,8 +169,8 @@ revisions of this diagram - Codex CLI and the two independently-shipped repos
169
169
  ```mermaid
170
170
  graph TD
171
171
  CC["Claude Code<br/>(source of truth)"]
172
- COP["Copilot CLI<br/>(instructions + 50 skills)"]
173
- COD["Codex CLI<br/>(1 router skill + 50 refs)"]
172
+ COP["Copilot CLI<br/>(instructions + 51 skills)"]
173
+ COD["Codex CLI<br/>(1 router skill + 51 refs)"]
174
174
  REPO["Pipeline Repo<br/>(npm package)"]
175
175
  WEB["Website"]
176
176
  PLUGREPO["multi-agent-plugins<br/>(5 stack plugins, own repo)"]
@@ -183,10 +183,10 @@ graph TD
183
183
  REPO -->|build-stack-plugins.mjs| PLUGREPO
184
184
  DTK -.->|sync only detects + ships, never authors| CC
185
185
 
186
- REPO -->|npm publish| NPM["GitHub Packages"]
186
+ REPO -->|npm publish| NPM["npm registry (public)"]
187
187
  WEB -->|auto-deploy| VERCEL["Vercel"]
188
188
  PLUGREPO -->|git push| MKT["Claude marketplace"]
189
- DTK -->|npm publish| NPM2["GitHub Packages (private)"]
189
+ DTK -->|npm publish| NPM2["npm registry (public)"]
190
190
  ```
191
191
 
192
192
  Full detail on how these three repos compose at install time and at run time -
package/docs/ecosystem.md CHANGED
@@ -5,7 +5,7 @@ separately, wired together at install time and at run time:
5
5
 
6
6
  | Repo | What it owns | Ships as |
7
7
  |---|---|---|
8
- | **`multi-agent-pipeline`** (this repo) | Orchestration: the 8-phase flow, the 50 slash commands, quality gates, review/triage, cross-CLI parity | npm package (`@mmerterden/multi-agent-pipeline`), installs itself onto Claude Code / Copilot CLI / Codex CLI |
8
+ | **`multi-agent-pipeline`** (this repo) | Orchestration: the 8-phase flow, the 51 slash commands, quality gates, review/triage, cross-CLI parity | npm package (`@mmerterden/multi-agent-pipeline`), installs itself onto Claude Code / Copilot CLI / Codex CLI |
9
9
  | **`multi-agent-plugins`** | Stack knowledge: per-platform component/lifecycle skills (iOS, Android, Frontend, Backend) + shared knowledge | Claude Code marketplace, 5 independently-versioned plugins |
10
10
  | **`dev-toolkit-mcp`** | The pipeline's hands on devices and browsers: 80 MCP tools across 6 categories (simulator/emulator control, accessibility audit, store compliance, web automation, Figma-vs-mock design audit, an agent-DSL batch runner) | npm package, registered as a standard stdio MCP server on every host |
11
11
 
@@ -18,7 +18,7 @@ Either can be swapped or removed without touching the other two's source.
18
18
  graph LR
19
19
  subgraph PIPE ["multi-agent-pipeline (orchestrator)"]
20
20
  direction TB
21
- PHASES["8 phases · 50 commands"]
21
+ PHASES["8 phases · 51 commands"]
22
22
  GATES["deterministic gates + review triage"]
23
23
  end
24
24
 
@@ -63,8 +63,8 @@ only those:
63
63
  graph TD
64
64
  CC["Claude Code<br/>~/.claude/commands/multi-agent/<br/>(source of truth)"]
65
65
 
66
- CC -->|"Step 2: copy + reformat<br/>50 sub-command skills"| COP["Copilot CLI<br/>~/.copilot/skills/"]
67
- CC -->|"Step 2b: transform<br/>(install.js --codex)"| COD["Codex CLI<br/>1 router skill + 50 refs<br/>+ 8 agent TOML"]
66
+ CC -->|"Step 2: copy + reformat<br/>51 sub-command skills"| COP["Copilot CLI<br/>~/.copilot/skills/"]
67
+ CC -->|"Step 2b: transform<br/>(install.js --codex)"| COD["Codex CLI<br/>1 router skill + 51 refs<br/>+ 8 agent TOML"]
68
68
  CC -->|"Step 3: genericize<br/>(strip personal data)"| REPO["multi-agent-pipeline repo<br/>pipeline/"]
69
69
  CC -->|"Step 4: version + feature sync"| WEB["Website<br/>projects.ts / i18n.tsx"]
70
70
 
@@ -75,10 +75,10 @@ graph TD
75
75
  CC -.->|"sync only SHIPS this,<br/>never authors it"| SYNC3D
76
76
  SYNC3D -.-> DTK2
77
77
 
78
- REPO -->|"npm publish"| NPM["GitHub Packages"]
78
+ REPO -->|"npm publish"| NPM["npm registry (public)"]
79
79
  WEB -->|"git push → auto-deploy"| VERCEL["Vercel"]
80
80
  PLUGREPO -->|"git push"| MKT["Claude Code marketplace"]
81
- DTK2 -->|"npm publish"| NPM2["GitHub Packages<br/>(private)"]
81
+ DTK2 -->|"npm publish"| NPM2["npm registry<br/>(public)"]
82
82
 
83
83
  style CC fill:#f9f,stroke:#333
84
84
  style DTK2 fill:#dff,stroke:#333,stroke-dasharray: 5 5
@@ -105,7 +105,7 @@ hand-authored *inside* `multi-agent-plugins` and are never touched by sync.
105
105
 
106
106
  ```mermaid
107
107
  graph TD
108
- EXT["pipeline/skills/shared/external/<br/>150 skills - single authoring source<br/>(the pipeline's own phases read these too)"]
108
+ EXT["pipeline/skills/shared/external/<br/>151 skills - single authoring source<br/>(the pipeline's own phases read these too)"]
109
109
 
110
110
  EXT -->|"cross-stack skills"| COMMONP["ai-common-toolkit<br/>10 skills · v0.2.3"]
111
111
  EXT -->|"Apple/Xcode-only"| IOSP["ai-ios-toolkit<br/>145 skills · v0.6.0"]
@@ -128,7 +128,7 @@ graph TD
128
128
 
129
129
  A skill counted in more than one platform plugin (a cross-stack knowledge skill
130
130
  plus, say, an iOS-specific one) is why the plugins' skill counts sum to more than
131
- the 150-skill source: `ai-common` skills are vendored into every stack plugin's
131
+ the 151-skill source: `ai-common` skills are vendored into every stack plugin's
132
132
  `knowledge/`, not deduplicated across them. Versioning is per-plugin and
133
133
  patch-only from this generator - a repo enabling only `ai-ios-toolkit`
134
134
  never pulls an Android-only change.
@@ -150,9 +150,9 @@ measurements behind this table):
150
150
 
151
151
  | | Claude Code | Copilot CLI | Codex CLI |
152
152
  |---|---|---|---|
153
- | **Pipeline commands** | 50 slash-command skills, native | 50 skills, `multi-agent-{cmd}` naming, copied in | 1 router skill (`multi-agent`) + 50 command specs as reference files - Codex silently truncates its skills block past a few dozen entries, so sub-commands are not peer skills here |
153
+ | **Pipeline commands** | 51 slash-command skills, native | 51 skills, `multi-agent-{cmd}` naming, copied in | 1 router skill (`multi-agent`) + 51 command specs as reference files - Codex silently truncates its skills block past a few dozen entries, so sub-commands are not peer skills here |
154
154
  | **Stack plugins** | Marketplace plugin, loaded natively, resolved by `.claude/settings.json` enabled-list | Enabled plugin's authored skills copied flat into `~/.copilot/skills/`; `knowledge/` **not** re-copied (already delivered via `shared/external`) | Copied as reference files under `~/.codex/multi-agent-refs/skills/`, plugin-prefixed on name clash (e.g. `architecture` → `ai-ios-toolkit-architecture`) |
155
- | **Component dispatch (Phase 3)** | Marketplace plugin's `create-component`/`create-screen` skill via the Skill tool | No plugin loader - falls back to local frozen `figma-*` skill copies | Not part of the enforced parity axis; classification + state-shape must match, skill *inventory* does not |
155
+ | **Component dispatch (Phase 3)** | Marketplace plugin's `create-component`/`create-screen` skill via the Skill tool | No plugin loader - the enabled stack plugin's authored skills (incl. `create-component`) are copied flat into `~/.copilot/skills/` at install time (the old frozen `figma-*` copies are pruned, they were never a fallback) | Not part of the enforced parity axis; classification + state-shape must match, skill *inventory* does not |
156
156
  | **dev-toolkit-mcp** | `claude mcp add dev-toolkit -- npx -y @mmerterden/dev-toolkit-mcp` | `copilot mcp add dev-toolkit -- npx -y @mmerterden/dev-toolkit-mcp` | `codex mcp add dev-toolkit -- npx -y @mmerterden/dev-toolkit-mcp` (skipped with a warning if `codex` isn't on `PATH`) |
157
157
 
158
158
  `smoke-cross-cli-behavior.sh` and `smoke-codex-install.sh` gate the axes that **do**
package/index.js CHANGED
@@ -53,6 +53,9 @@ if (command === "--version" || command === "-v" || command === "version") {
53
53
  npx @mmerterden/multi-agent-pipeline install --codex Install for Codex CLI
54
54
  npx @mmerterden/multi-agent-pipeline install --all Claude + Copilot + Codex
55
55
  npx @mmerterden/multi-agent-pipeline install --link Use symlinks (saves tokens, dev mode)
56
+ npx @mmerterden/multi-agent-pipeline install --dry-run Preview what would be written, write nothing
57
+ npx @mmerterden/multi-agent-pipeline install --index-only Ship only the skills index (dynamic skill loading)
58
+ npx @mmerterden/multi-agent-pipeline install --prune-external Also remove pre-v15 catalog copies that differ from the shipped catalog
56
59
 
57
60
  Uninstall (token-preserving - Keychain/Credential Manager untouched):
58
61
  npx @mmerterden/multi-agent-pipeline uninstall Interactive: remove from all installed targets
@@ -70,7 +73,7 @@ if (command === "--version" || command === "-v" || command === "version") {
70
73
 
71
74
  Options:
72
75
  --no-color Disable colored output
73
- --target=<path> Target dir for legacy adapter cleanup on uninstall (defaults to cwd)
76
+ --target=<path> Target dir override (install and legacy-adapter cleanup on uninstall; defaults to cwd)
74
77
  --platform=ios|android|all Filter external skills by platform (default: all)
75
78
 
76
79
  After installation:
@@ -15,6 +15,7 @@ import {
15
15
  existsSync,
16
16
  lstatSync,
17
17
  mkdirSync,
18
+ readFileSync,
18
19
  readdirSync,
19
20
  realpathSync,
20
21
  renameSync,
@@ -90,7 +91,7 @@ export function ensureRealDir(dir) {
90
91
  * @param {string} agentsSrc - pipeline/agents source directory
91
92
  * @returns {Set<string>}
92
93
  */
93
- export function pipelineAgentFileNames(agentsSrc) {
94
+ function pipelineAgentFileNames(agentsSrc) {
94
95
  const names = new Set();
95
96
  if (existsSync(agentsSrc)) {
96
97
  for (const entry of readdirSync(agentsSrc, { withFileTypes: true })) {
@@ -269,7 +270,7 @@ export function pruneLegacyMultiAgentSkills(skillsDir) {
269
270
  *
270
271
  * @type {ReadonlyArray<{dir: string, root?: "claude"|"home", reason: string}>}
271
272
  */
272
- export const ABANDONED_TREES = Object.freeze([
273
+ const ABANDONED_TREES = Object.freeze([
273
274
  {
274
275
  dir: "eval",
275
276
  reason: "eval corpora; the harnesses that read them are maintainer-only and no longer ship",
@@ -521,3 +522,44 @@ export function wipeDir(dir) {
521
522
  /* non-fatal */
522
523
  }
523
524
  }
525
+
526
+
527
+ /**
528
+ * @param {string} a
529
+ * @param {string} b
530
+ * @returns {boolean} true when both trees have identical entries and file bytes
531
+ */
532
+ export function dirsIdentical(a, b) {
533
+ const namesA = readdirSync(a).sort();
534
+ const namesB = readdirSync(b).sort();
535
+ if (namesA.length !== namesB.length || namesA.some((n, i) => n !== namesB[i])) return false;
536
+ for (const name of namesA) {
537
+ const pa = join(a, name);
538
+ const pb = join(b, name);
539
+ const sa = statSync(pa);
540
+ const sb = statSync(pb);
541
+ if (sa.isDirectory() !== sb.isDirectory()) return false;
542
+ if (sa.isDirectory()) {
543
+ if (!dirsIdentical(pa, pb)) return false;
544
+ } else if (!readFileSync(pa).equals(readFileSync(pb))) {
545
+ return false;
546
+ }
547
+ }
548
+ return true;
549
+ }
550
+
551
+ /**
552
+ * Same `local-only: true` frontmatter convention the command wrappers use:
553
+ * a dir carrying it is the user's and no prune path may take it.
554
+ *
555
+ * @param {string} dir
556
+ * @returns {boolean}
557
+ */
558
+ export function isLocalOnlySkill(dir) {
559
+ try {
560
+ const skill = join(dir, "SKILL.md");
561
+ return existsSync(skill) && /^local-only:\s*true\s*$/m.test(readFileSync(skill, "utf-8"));
562
+ } catch {
563
+ return true;
564
+ }
565
+ }