@mmerterden/multi-agent-pipeline 15.3.1 → 15.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -16,6 +16,20 @@ Internal file-layout changes that don't affect the slash-command surface are sti
16
16
 
17
17
  ## [Unreleased]
18
18
 
19
+ ## [15.3.2] - 2026-08-17
20
+
21
+ ### Fixed
22
+
23
+ - `local` and `local-autopilot` mode docs pointed at the retired `commands/multi-agent.md` dispatcher spelling; they now reference `commands/multi-agent/SKILL.md`, and the Codex installer rewrites the directory-layout spelling to the router skill (dedicated rewrite rule, smoke guard for the new corruption shape, unit tests).
24
+ - The sync spec copies (command tree + Copilot shared-core mirror) disagreed on the Claude source list and file mapping; both now carry `multi-agent-refs/` and `lib/` and the same mapping rows.
25
+ - The dispatcher entry doc now declares the TaskCreate ordering rule and is scanned by `smoke-tasklist-ordering.sh`, closing the one mode (full interactive) the inventory missed.
26
+ - `check-md-links.mjs` resolves `$HOME/.claude/commands/` links against the repo source, so a future layout move cannot leave dangling dispatcher references silently.
27
+ - Install-layout fingerprint fixture regenerated for `usage-report.mjs` and the relocated reference files.
28
+
29
+ ### Changed
30
+
31
+ - refactor Step 0c (dev-toolkit research) and setup Step 3b (App Store Connect onboarding) moved to on-demand references under `multi-agent-refs/`, keeping both skills inside their token budgets.
32
+
19
33
  ## [15.3.1] - 2026-08-15
20
34
 
21
35
  ### Changed
package/install/codex.mjs CHANGED
@@ -82,6 +82,18 @@ export const CODEX_PATH_REWRITES = Object.freeze([
82
82
  to: "$HOME/.codex/skills/multi-agent/SKILL.md",
83
83
  },
84
84
  { from: /~\/\.claude\/commands\/multi-agent\.md/g, to: "~/.codex/skills/multi-agent/SKILL.md" },
85
+ // Current dispatcher spelling (directory layout). MUST also precede the
86
+ // sub-command rule: `commands/multi-agent/SKILL.md` would otherwise become
87
+ // `multi-agent-refs/commands/SKILL.md`, which installRefs deliberately never
88
+ // writes (the top-level SKILL.md ships as the router skill instead).
89
+ {
90
+ from: /\$HOME\/\.claude\/commands\/multi-agent\/SKILL\.md/g,
91
+ to: "$HOME/.codex/skills/multi-agent/SKILL.md",
92
+ },
93
+ {
94
+ from: /~\/\.claude\/commands\/multi-agent\/SKILL\.md/g,
95
+ to: "~/.codex/skills/multi-agent/SKILL.md",
96
+ },
85
97
  // Sub-command specs become reference files under the Codex refs tree.
86
98
  {
87
99
  from: /\$HOME\/\.claude\/commands\/multi-agent\b/g,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmerterden/multi-agent-pipeline",
3
- "version": "15.3.1",
3
+ "version": "15.3.2",
4
4
  "description": "8-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",
@@ -285,6 +285,10 @@ Quick pointers:
285
285
 
286
286
  Load `$HOME/.claude/multi-agent-refs/rules.md` for the full contract (Swift-specific rules, reviewer policy, secret scan, subagent contract).
287
287
 
288
+ ### TaskCreate ordering (strict)
289
+
290
+ **All TaskCreate calls fire in strict phase-number order BEFORE any TaskUpdate is applied** - this binds the full interactive `/multi-agent` run (all 8 phases) exactly like every mode alias. The native widget renders tiles by creation order, not by phase number; out-of-order calls produce visually scrambled tile stacks. Register every tile in order, then flip status via TaskUpdate when a phase actually starts or short-circuits. Full contract: `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
291
+
288
292
  ---
289
293
 
290
294
  ## Status Display
@@ -40,7 +40,7 @@ Phase 7: Report → Jira / Wiki / Confluence + log + knowledge/memory
40
40
 
41
41
  This command routes to the orchestrator with the `--local` flag set. The Phase 0-7 contract from `$HOME/.claude/multi-agent-refs/phases/phase-0-init.md` and the later phase docs applies as-is - only the worktree step is skipped, and `state.projects[*].worktreePath` stays `null`.
42
42
 
43
- Read the routing table in `$HOME/.claude/commands/multi-agent.md` and apply Phase 0 Step 8 in local mode (no worktree: continue on the current branch, state file under `.claude/logs/multi-agent/{project}/{taskId}/`).
43
+ Read the routing table in `$HOME/.claude/commands/multi-agent/SKILL.md` and apply Phase 0 Step 8 in local mode (no worktree: continue on the current branch, state file under `.claude/logs/multi-agent/{project}/{taskId}/`).
44
44
 
45
45
  ## Examples
46
46
 
@@ -69,7 +69,7 @@ Run the full pipeline **without a worktree** and **with every confirmation skipp
69
69
 
70
70
  ## Delegation
71
71
 
72
- Orchestrator routing: the routing table in `$HOME/.claude/commands/multi-agent.md` resolves `local-autopilot` as the union of the `dev-local` + `autopilot` mode mixins. Contract details: `$HOME/.claude/multi-agent-refs/phases/phase-0-init.md` Step 8 (local branch) + `$HOME/.claude/multi-agent-refs/phases/phase-2-planning.md` Step 5 (autopilot gate skip + safety classifier).
72
+ Orchestrator routing: the routing table in `$HOME/.claude/commands/multi-agent/SKILL.md` resolves `local-autopilot` as the union of the `dev-local` + `autopilot` mode mixins. Contract details: `$HOME/.claude/multi-agent-refs/phases/phase-0-init.md` Step 8 (local branch) + `$HOME/.claude/multi-agent-refs/phases/phase-2-planning.md` Step 5 (autopilot gate skip + safety classifier).
73
73
  ## Required: outward-facing payload contracts
74
74
 
75
75
  Before writing anything outward-facing - PR body, Jira comment, Confluence page, closing report - load `$HOME/.claude/multi-agent-refs/payload-contracts.md`. It names the canonical section set for each payload, the markup dialect per surface (PR body is Markdown, Jira is wiki markup - mixing them is a defect), and the token/duration numbers the closing report must carry. Improvising a payload shape from memory is the most common failure of the short modes.
@@ -112,73 +112,7 @@ Procedure:
112
112
 
113
113
  The pipeline's hands on devices and browsers are MCP tools served by a companion repo (`dev-toolkit-mcp`): Phase 5 test, `manual-test`, `design-check` and `apple-archive-compliance` all call them, and several pipeline skills declare a minimum toolkit version (see `cross-cli-contract.md`). That repo therefore has to track the MCP field, not just its own README. This step researches what current practice is and audits the toolkit against it.
114
114
 
115
- **Resolution** - configuration first, never a hardcoded path:
116
-
117
- 1. `prefs.global.devToolkit` in `~/.claude/multi-agent-preferences.json`:
118
-
119
- ```jsonc
120
- {
121
- "enabled": true,
122
- "label": "<human name>",
123
- "localPath": "$HOME/<repo-dir>", // the companion repo working copy
124
- "mcpServerName": "<registered MCP server name>",
125
- "packageName": "@<scope>/<package>",
126
- "registry": "github-packages", // github-packages | npmjs | none
127
- "repoUrl": "https://github.com/<owner>/<repo>"
128
- }
129
- ```
130
-
131
- 2. If unset, auto-detect from the MCP registration: read `mcpServers` in `~/.claude.json` (including each `projects[*].mcpServers`) and in `~/.claude/settings.json`; for a stdio entry whose command is `node`, take `dirname(args[0])`. Accept it only when that directory is a git repo whose `package.json` depends on `@modelcontextprotocol/sdk`.
132
- 3. If neither resolves, skip this step and report "no dev-toolkit configured". Never guess a path, never clone.
133
- 4. `enabled: false` skips the step.
134
-
135
- **Research axes** - a finding without a source link is not a finding:
136
-
137
- | # | Axis | Where to look | What to extract |
138
- |---|------|---------------|-----------------|
139
- | 1 | MCP protocol | spec revisions + `@modelcontextprotocol/sdk` releases | protocol features released since the pinned SDK range that the server does not use yet: tool annotations (`readOnlyHint` / `destructiveHint` / `idempotentHint` / `openWorldHint`), `outputSchema` + structured content, resource links in results, progress + cancellation, `tools/list_changed`, pagination, elicitation |
140
- | 2 | Host clients | Claude Code / Copilot CLI / Cursor / Antigravity docs + release notes | per-tool description budget, tool-count ceilings, naming conventions, image and output size limits, permission / allowlist ergonomics |
141
- | 3 | Peer servers | GitHub search on the same domain terms + `stars:>50` | tool surfaces we lack, conventions peers converged on, and what to discard as out of scope |
142
- | 4 | Wrapped tooling | `xcrun simctl help`, `idb`, `adb`, `xcodebuild`, Playwright release notes, Apple ITMS + App Store Review Guidelines | deprecated flags still in use, new capabilities worth a tool, audit rules that changed |
143
- | 5 | Field practice | X / Twitter, Reddit, MCP community threads | what server authors actually changed recently (transport choice, output-token diets, sandboxing, error shape) |
144
-
145
- **Audit the toolkit against the findings** - run the checks, do not assume:
146
-
147
- ```bash
148
- DT="<resolved localPath>"
149
- node --check "$DT/index.js"
150
- find "$DT/tools" -name "*.js" -type f -exec node --check {} \;
151
-
152
- # stdout carries the JSON-RPC frames: a stray stdout write corrupts the stream
153
- grep -rn "console\.log(" "$DT/index.js" "$DT/tools" || echo "stdout clean"
154
-
155
- # advertised tool counts vs reality (README header + package.json description)
156
- grep -nE "[0-9]+ tools" "$DT/README.md" "$DT/package.json"
157
-
158
- # packaging: every runtime directory must be inside files[]
159
- node -p "require('$DT/package.json').files.join('\n')"
160
- ls -d "$DT"/tools/*/
161
-
162
- cd "$DT" && npm outdated; npm audit --omit=dev 2>/dev/null | tail -20
163
- ```
164
-
165
- Also check: every tool carries a description and an `inputSchema`; token-heavy results (screenshots, UI trees, logs) are truncated or written to a file path instead of inlined; failures return an error result with an actionable message instead of throwing; `engines.node` matches what the SDK needs; `CHANGELOG.md`, a CI workflow and a test harness exist.
166
-
167
- Output (plan band E):
168
-
169
- ```
170
- | # | Axis | Finding | Source | Adaptation in the toolkit (file) | Effort | Impact | In plan? |
171
- |---|------|---------|--------|----------------------------------|--------|--------|----------|
172
- | 1 | Protocol | read-only tools carry no annotations | <spec link> | add `annotations` to the read-only tools in index.js | Low | Medium | Yes (P1) |
173
- | 2 | Wrapped tooling | uses a simctl flag removed in Xcode <v> | <release notes> | switch tools/<family>/<file>.js to <new flag> | Low | High | Yes (P0) |
174
- | 3 | Peer servers | peer exposes <surface> | <repo link> | does not fit: outside the pipeline's phases | - | - | No |
175
- ```
176
-
177
- Rules for this band:
178
-
179
- - Band-E work lands in the toolkit repo, never mirrored into this one. Shipping it is `/multi-agent:sync` Step 3d.
180
- - A finding that changes the tool surface (new / renamed / removed tool) pairs with a pipeline-side item: bump the minimum toolkit version wherever a pipeline skill declares one.
181
- - If the current working directory IS the toolkit repo, skip band E and let bands A/B/C cover it - never report the same finding twice.
115
+ Full procedure - resolution (configuration first, never a hardcoded path; skip when nothing resolves or `enabled` is false), the 5 research axes, the audit command block, and the band-E output table + rules - lives in `$HOME/.claude/multi-agent-refs/refactor/dev-toolkit-research.md`. Read it before running this step.
182
116
 
183
117
  ## Step 0d: RUN-ERRORS - what the pipeline actually failed on
184
118
 
@@ -402,55 +402,7 @@ This builds `platformIdentityRouting` incrementally - no separate Step 7 neede
402
402
 
403
403
  ### Step 3b - App Store Connect onboarding (iOS only, optional)
404
404
 
405
- Runs inside Step 3 alongside the other missing credentials, not as a late add-on:
406
- a user who already has an App Store Connect credential in their keychain gets it
407
- mapped by Step 1 discovery like any other token, and only the genuinely missing
408
- pieces reach this flow.
409
-
410
- Three of the four entries do not go through the normal Token Save Flow, because
411
- what they hold is not a pasteable secret:
412
-
413
- | Entry | Holds | Flow |
414
- |---|---|---|
415
- | `appstore_connect_key_id` | an identifier | plain value, not a secret; still mapped so it is read through the mapping layer |
416
- | `appstore_connect_issuer_id` | an identifier | same |
417
- | `appstore_connect_apple_id` | an email address | same |
418
- | `appstore_connect_password_item` | a keychain ITEM NAME | the password lives in Apple's own keychain item, referenced as `-p @keychain:<item>` and never read by the pipeline |
419
-
420
- Ask which tier to configure (picker): **API key** / **Apple ID + app-specific
421
- password** / **Skip**. Lead with the second when the user says they cannot create
422
- an API key.
423
-
424
- **API key.** The private key is a FILE and is never copied into the credential
425
- store. It must sit in a directory `altool` already searches:
426
-
427
- ```bash
428
- ls ~/.appstoreconnect/private_keys/AuthKey_*.p8 2>/dev/null \
429
- || echo "MISSING: put AuthKey_<keyId>.p8 in ~/.appstoreconnect/private_keys/"
430
- ```
431
-
432
- **Apple ID + app-specific password.** Use Apple's own keychain helper. The secret
433
- never enters chat and never becomes a shell argument, per the Token Save Flow rule:
434
-
435
- ```bash
436
- # the user exports AC_PASSWORD_ONCE in their own shell, for this one command
437
- xcrun altool --store-password-in-keychain-item "<item-name>" \
438
- -u "<apple-id>" -p @env:AC_PASSWORD_ONCE
439
- ```
440
-
441
- Then map only `<item-name>` as `appstore_connect_password_item`.
442
-
443
- **Multi-provider accounts.** A corporate Apple ID often belongs to several
444
- providers, and `altool` fails opaquely without one. Resolve it once with
445
- `ios_testflight_validate({list_providers: true, <credentials just configured>})`
446
- and store the answer under
447
- `prefs.projects[<key>].appStoreConnect.providerPublicId` - per-project, since a
448
- user can ship for more than one team.
449
-
450
- **Verify + expiry.** Re-run the `list_providers` probe and report the resolved
451
- tier. A credential that resolves but is rejected (401/403) follows the
452
- Expired-token decision in `refs/keychain.md` Rule 1 - Regenerate / Use a
453
- different token / Skip and continue - never a silent drop.
405
+ Runs inside Step 3 alongside the other missing credentials. The four `appstore_connect_*` entries, their non-secret handling (three hold identifiers / a keychain item name, not pasteable secrets), the API-key vs Apple-ID tier picker, and the verification probes live in `$HOME/.claude/multi-agent-refs/setup/app-store-connect.md`. Read that file when the user opts into App Store Connect onboarding; on Skip, nothing is written.
454
406
 
455
407
  ### Step 3.5 - Host Prompt (embedded in Token Save Flow)
456
408
 
@@ -25,7 +25,7 @@ When invoked, it synchronizes all targets in order. It detects what changed, upd
25
25
 
26
26
  | # | Target | Path | Direction |
27
27
  |---|-------|-----|-----|
28
- | 1 | Claude Code (source of truth) | `~/.claude/commands/multi-agent.md` + `~/.claude/commands/multi-agent/` + `~/.claude/agents/` + `~/.claude/scripts/` + `~/.claude/lib/` | source |
28
+ | 1 | Claude Code (source of truth) | `~/.claude/commands/multi-agent/` + `~/.claude/multi-agent-refs/` + `~/.claude/agents/` + `~/.claude/scripts/` + `~/.claude/lib/` | source |
29
29
  | 2 | Copilot CLI | `~/.copilot/copilot-instructions.md` + `~/.copilot/skills/` | <- from Claude |
30
30
  | 2b | Codex CLI | `~/.codex/AGENTS.md` + `~/.codex/skills/multi-agent/` + `~/.codex/multi-agent-refs/` + `~/.codex/agents/*.toml` | <- from Claude (path-rewritten) |
31
31
  | 3 | multi-agent-pipeline repo | `~/multi-agent-pipeline/pipeline/` | <- from Claude (genericized) |
@@ -87,7 +87,7 @@ If nothing is stale → report "All targets up to date" and stop.
87
87
 
88
88
  1. **Read first** - understand every target's current state before making any change
89
89
  2. **Preserve file structure** - each target has its own format:
90
- - `multi-agent.md` + phases/: detailed pipeline spec (frontmatter, phases, routing)
90
+ - `commands/multi-agent/` SKILL tree + `multi-agent-refs/phases/`: detailed pipeline spec (frontmatter, phases, routing)
91
91
  - `copilot-instructions.md`: general development instructions + pipeline summary section
92
92
  - `multi-agent-pipeline/pipeline/`: generic open-source version (NO personal data)
93
93
  3. **Sync the shared sections** (Claude ↔ Copilot):
@@ -105,7 +105,7 @@ If nothing is stale → report "All targets up to date" and stop.
105
105
 
106
106
  ## Pipeline Repo Sync Rules (CRITICAL)
107
107
 
108
- 1. **Source**: `~/.claude/commands/multi-agent.md` + `~/.claude/commands/multi-agent/` + `~/.claude/agents/`
108
+ 1. **Source**: `~/.claude/commands/multi-agent/` + `~/.claude/multi-agent-refs/` + `~/.claude/agents/` + `~/.claude/lib/`
109
109
  2. **Target**: `~/multi-agent-pipeline/pipeline/`
110
110
  3. **Genericization** (must be applied BEFORE writing to the target):
111
111
  - Jira project key (`prefs.global.defaultJiraKey`) -> `{JIRA_KEY}`, `PROJ` in examples
@@ -116,7 +116,6 @@ If nothing is stale → report "All targets up to date" and stop.
116
116
  - **Verify**: `grep` scan for personal/corporate data inside pipeline/ -> 0 results
117
117
  4. **File mapping**:
118
118
  ```
119
- ~/.claude/commands/multi-agent.md -> pipeline/commands/multi-agent.md
120
119
  ~/.claude/commands/multi-agent/ -> pipeline/commands/multi-agent/
121
120
  ~/.claude/multi-agent-refs/ -> pipeline/multi-agent-refs/ (refs + pickers, non-command)
122
121
  ~/.claude/commands/sim-test.md -> pipeline/commands/sim-test.md
@@ -0,0 +1,72 @@
1
+ # Dev-Toolkit Research (refactor Step 0c)
2
+
3
+ Loaded on demand by `/multi-agent:refactor` Step 0c. The SKILL.md carries the step intro; this file is the full procedure.
4
+
5
+ **Resolution** - configuration first, never a hardcoded path:
6
+
7
+ 1. `prefs.global.devToolkit` in `~/.claude/multi-agent-preferences.json`:
8
+
9
+ ```jsonc
10
+ {
11
+ "enabled": true,
12
+ "label": "<human name>",
13
+ "localPath": "$HOME/<repo-dir>", // the companion repo working copy
14
+ "mcpServerName": "<registered MCP server name>",
15
+ "packageName": "@<scope>/<package>",
16
+ "registry": "github-packages", // github-packages | npmjs | none
17
+ "repoUrl": "https://github.com/<owner>/<repo>"
18
+ }
19
+ ```
20
+
21
+ 2. If unset, auto-detect from the MCP registration: read `mcpServers` in `~/.claude.json` (including each `projects[*].mcpServers`) and in `~/.claude/settings.json`; for a stdio entry whose command is `node`, take `dirname(args[0])`. Accept it only when that directory is a git repo whose `package.json` depends on `@modelcontextprotocol/sdk`.
22
+ 3. If neither resolves, skip this step and report "no dev-toolkit configured". Never guess a path, never clone.
23
+ 4. `enabled: false` skips the step.
24
+
25
+ **Research axes** - a finding without a source link is not a finding:
26
+
27
+ | # | Axis | Where to look | What to extract |
28
+ |---|------|---------------|-----------------|
29
+ | 1 | MCP protocol | spec revisions + `@modelcontextprotocol/sdk` releases | protocol features released since the pinned SDK range that the server does not use yet: tool annotations (`readOnlyHint` / `destructiveHint` / `idempotentHint` / `openWorldHint`), `outputSchema` + structured content, resource links in results, progress + cancellation, `tools/list_changed`, pagination, elicitation |
30
+ | 2 | Host clients | Claude Code / Copilot CLI / Cursor / Antigravity docs + release notes | per-tool description budget, tool-count ceilings, naming conventions, image and output size limits, permission / allowlist ergonomics |
31
+ | 3 | Peer servers | GitHub search on the same domain terms + `stars:>50` | tool surfaces we lack, conventions peers converged on, and what to discard as out of scope |
32
+ | 4 | Wrapped tooling | `xcrun simctl help`, `idb`, `adb`, `xcodebuild`, Playwright release notes, Apple ITMS + App Store Review Guidelines | deprecated flags still in use, new capabilities worth a tool, audit rules that changed |
33
+ | 5 | Field practice | X / Twitter, Reddit, MCP community threads | what server authors actually changed recently (transport choice, output-token diets, sandboxing, error shape) |
34
+
35
+ **Audit the toolkit against the findings** - run the checks, do not assume:
36
+
37
+ ```bash
38
+ DT="<resolved localPath>"
39
+ node --check "$DT/index.js"
40
+ find "$DT/tools" -name "*.js" -type f -exec node --check {} \;
41
+
42
+ # stdout carries the JSON-RPC frames: a stray stdout write corrupts the stream
43
+ grep -rn "console\.log(" "$DT/index.js" "$DT/tools" || echo "stdout clean"
44
+
45
+ # advertised tool counts vs reality (README header + package.json description)
46
+ grep -nE "[0-9]+ tools" "$DT/README.md" "$DT/package.json"
47
+
48
+ # packaging: every runtime directory must be inside files[]
49
+ node -p "require('$DT/package.json').files.join('\n')"
50
+ ls -d "$DT"/tools/*/
51
+
52
+ cd "$DT" && npm outdated; npm audit --omit=dev 2>/dev/null | tail -20
53
+ ```
54
+
55
+ Also check: every tool carries a description and an `inputSchema`; token-heavy results (screenshots, UI trees, logs) are truncated or written to a file path instead of inlined; failures return an error result with an actionable message instead of throwing; `engines.node` matches what the SDK needs; `CHANGELOG.md`, a CI workflow and a test harness exist.
56
+
57
+ Output (plan band E):
58
+
59
+ ```
60
+ | # | Axis | Finding | Source | Adaptation in the toolkit (file) | Effort | Impact | In plan? |
61
+ |---|------|---------|--------|----------------------------------|--------|--------|----------|
62
+ | 1 | Protocol | read-only tools carry no annotations | <spec link> | add `annotations` to the read-only tools in index.js | Low | Medium | Yes (P1) |
63
+ | 2 | Wrapped tooling | uses a simctl flag removed in Xcode <v> | <release notes> | switch tools/<family>/<file>.js to <new flag> | Low | High | Yes (P0) |
64
+ | 3 | Peer servers | peer exposes <surface> | <repo link> | does not fit: outside the pipeline's phases | - | - | No |
65
+ ```
66
+
67
+ Rules for this band:
68
+
69
+ - Band-E work lands in the toolkit repo, never mirrored into this one. Shipping it is `/multi-agent:sync` Step 3d.
70
+ - A finding that changes the tool surface (new / renamed / removed tool) pairs with a pipeline-side item: bump the minimum toolkit version wherever a pipeline skill declares one.
71
+ - If the current working directory IS the toolkit repo, skip band E and let bands A/B/C cover it - never report the same finding twice.
72
+
@@ -0,0 +1,54 @@
1
+ # App Store Connect Onboarding (setup Step 3b)
2
+
3
+ Loaded on demand by `/multi-agent:setup` Step 3b (iOS only, optional). The SKILL.md carries the step intro; this file is the full flow.
4
+
5
+ Runs inside Step 3 alongside the other missing credentials, not as a late add-on:
6
+ a user who already has an App Store Connect credential in their keychain gets it
7
+ mapped by Step 1 discovery like any other token, and only the genuinely missing
8
+ pieces reach this flow.
9
+
10
+ Three of the four entries do not go through the normal Token Save Flow, because
11
+ what they hold is not a pasteable secret:
12
+
13
+ | Entry | Holds | Flow |
14
+ |---|---|---|
15
+ | `appstore_connect_key_id` | an identifier | plain value, not a secret; still mapped so it is read through the mapping layer |
16
+ | `appstore_connect_issuer_id` | an identifier | same |
17
+ | `appstore_connect_apple_id` | an email address | same |
18
+ | `appstore_connect_password_item` | a keychain ITEM NAME | the password lives in Apple's own keychain item, referenced as `-p @keychain:<item>` and never read by the pipeline |
19
+
20
+ Ask which tier to configure (picker): **API key** / **Apple ID + app-specific
21
+ password** / **Skip**. Lead with the second when the user says they cannot create
22
+ an API key.
23
+
24
+ **API key.** The private key is a FILE and is never copied into the credential
25
+ store. It must sit in a directory `altool` already searches:
26
+
27
+ ```bash
28
+ ls ~/.appstoreconnect/private_keys/AuthKey_*.p8 2>/dev/null \
29
+ || echo "MISSING: put AuthKey_<keyId>.p8 in ~/.appstoreconnect/private_keys/"
30
+ ```
31
+
32
+ **Apple ID + app-specific password.** Use Apple's own keychain helper. The secret
33
+ never enters chat and never becomes a shell argument, per the Token Save Flow rule:
34
+
35
+ ```bash
36
+ # the user exports AC_PASSWORD_ONCE in their own shell, for this one command
37
+ xcrun altool --store-password-in-keychain-item "<item-name>" \
38
+ -u "<apple-id>" -p @env:AC_PASSWORD_ONCE
39
+ ```
40
+
41
+ Then map only `<item-name>` as `appstore_connect_password_item`.
42
+
43
+ **Multi-provider accounts.** A corporate Apple ID often belongs to several
44
+ providers, and `altool` fails opaquely without one. Resolve it once with
45
+ `ios_testflight_validate({list_providers: true, <credentials just configured>})`
46
+ and store the answer under
47
+ `prefs.projects[<key>].appStoreConnect.providerPublicId` - per-project, since a
48
+ user can ship for more than one team.
49
+
50
+ **Verify + expiry.** Re-run the `list_providers` probe and report the resolved
51
+ tier. A credential that resolves but is rejected (401/403) follows the
52
+ Expired-token decision in `refs/keychain.md` Rule 1 - Regenerate / Use a
53
+ different token / Skip and continue - never a silent drop.
54
+
@@ -142,7 +142,7 @@ Mode-specific phase sets:
142
142
 
143
143
  Note: in `--dev` modes the omitted phases (1, 2 - plus 5 in the autopilot/local variants) **do not get TaskCreate calls at all** - they're not part of the mode's phase set. Phase 4 is in every mode's set as of v14.0.0, so it is always registered. The "[SKIPPED]" pattern above only applies if a phase that IS in the set is conditionally skipped at runtime. The authoritative per-mode set is the `for p in ...` init block in each mode's own entry doc, generated by `gen-mode-dispatch.mjs`; this table mirrors those blocks.
144
144
 
145
- **Enforcement**: `smoke-tasklist-ordering.sh` scans every mode entry point doc (`commands/multi-agent.md`, `commands/multi-agent/{autopilot,local,local-autopilot,dev,dev-autopilot,dev-local,dev-local-autopilot}.md` + Copilot mirrors) for the explicit "in phase-number order" rule. Inventory drift fails the smoke.
145
+ **Enforcement**: `smoke-tasklist-ordering.sh` scans the dispatcher (`commands/multi-agent/SKILL.md`) and every mode entry point doc (`commands/multi-agent/{dev,autopilot,local,local-autopilot,dev-autopilot,dev-local,dev-local-autopilot,resume-local}/SKILL.md` + the Copilot full-inline orchestrator mirror) for the explicit "in phase-number order" rule. Inventory drift fails the smoke.
146
146
 
147
147
  ### Other CLIs - call render after every state change
148
148
 
@@ -28,7 +28,7 @@ If user gives wrong format for the project, warn:
28
28
 
29
29
  ## Input Parsing
30
30
 
31
- Classify user input into one of 5 types (matches the colon-form `multi-agent.md` contract; cross-CLI parity is enforced by `smoke-cross-cli-behavior.sh`):
31
+ Classify user input into one of 5 types (matches the `commands/multi-agent/SKILL.md` dispatcher contract; cross-CLI parity is enforced by `smoke-cross-cli-behavior.sh`):
32
32
 
33
33
  | # | Pattern | Type | Action |
34
34
  |---|---------|------|--------|
@@ -114,73 +114,7 @@ Procedure:
114
114
 
115
115
  The pipeline's hands on devices and browsers are MCP tools served by a companion repo (`dev-toolkit-mcp`): Phase 5 test, `manual-test`, `design-check` and `apple-archive-compliance` all call them, and several pipeline skills declare a minimum toolkit version (see `cross-cli-contract.md`). That repo therefore has to track the MCP field, not just its own README. This step researches what current practice is and audits the toolkit against it.
116
116
 
117
- **Resolution** - configuration first, never a hardcoded path:
118
-
119
- 1. `prefs.global.devToolkit` in `~/.claude/multi-agent-preferences.json`:
120
-
121
- ```jsonc
122
- {
123
- "enabled": true,
124
- "label": "<human name>",
125
- "localPath": "$HOME/<repo-dir>", // the companion repo working copy
126
- "mcpServerName": "<registered MCP server name>",
127
- "packageName": "@<scope>/<package>",
128
- "registry": "github-packages", // github-packages | npmjs | none
129
- "repoUrl": "https://github.com/<owner>/<repo>"
130
- }
131
- ```
132
-
133
- 2. If unset, auto-detect from the MCP registration: read `mcpServers` in `~/.claude.json` (including each `projects[*].mcpServers`) and in `~/.claude/settings.json`; for a stdio entry whose command is `node`, take `dirname(args[0])`. Accept it only when that directory is a git repo whose `package.json` depends on `@modelcontextprotocol/sdk`.
134
- 3. If neither resolves, skip this step and report "no dev-toolkit configured". Never guess a path, never clone.
135
- 4. `enabled: false` skips the step.
136
-
137
- **Research axes** - a finding without a source link is not a finding:
138
-
139
- | # | Axis | Where to look | What to extract |
140
- |---|------|---------------|-----------------|
141
- | 1 | MCP protocol | spec revisions + `@modelcontextprotocol/sdk` releases | protocol features released since the pinned SDK range that the server does not use yet: tool annotations (`readOnlyHint` / `destructiveHint` / `idempotentHint` / `openWorldHint`), `outputSchema` + structured content, resource links in results, progress + cancellation, `tools/list_changed`, pagination, elicitation |
142
- | 2 | Host clients | Claude Code / Copilot CLI / Cursor / Antigravity docs + release notes | per-tool description budget, tool-count ceilings, naming conventions, image and output size limits, permission / allowlist ergonomics |
143
- | 3 | Peer servers | GitHub search on the same domain terms + `stars:>50` | tool surfaces we lack, conventions peers converged on, and what to discard as out of scope |
144
- | 4 | Wrapped tooling | `xcrun simctl help`, `idb`, `adb`, `xcodebuild`, Playwright release notes, Apple ITMS + App Store Review Guidelines | deprecated flags still in use, new capabilities worth a tool, audit rules that changed |
145
- | 5 | Field practice | X / Twitter, Reddit, MCP community threads | what server authors actually changed recently (transport choice, output-token diets, sandboxing, error shape) |
146
-
147
- **Audit the toolkit against the findings** - run the checks, do not assume:
148
-
149
- ```bash
150
- DT="<resolved localPath>"
151
- node --check "$DT/index.js"
152
- find "$DT/tools" -name "*.js" -type f -exec node --check {} \;
153
-
154
- # stdout carries the JSON-RPC frames: a stray stdout write corrupts the stream
155
- grep -rn "console\.log(" "$DT/index.js" "$DT/tools" || echo "stdout clean"
156
-
157
- # advertised tool counts vs reality (README header + package.json description)
158
- grep -nE "[0-9]+ tools" "$DT/README.md" "$DT/package.json"
159
-
160
- # packaging: every runtime directory must be inside files[]
161
- node -p "require('$DT/package.json').files.join('\n')"
162
- ls -d "$DT"/tools/*/
163
-
164
- cd "$DT" && npm outdated; npm audit --omit=dev 2>/dev/null | tail -20
165
- ```
166
-
167
- Also check: every tool carries a description and an `inputSchema`; token-heavy results (screenshots, UI trees, logs) are truncated or written to a file path instead of inlined; failures return an error result with an actionable message instead of throwing; `engines.node` matches what the SDK needs; `CHANGELOG.md`, a CI workflow and a test harness exist.
168
-
169
- Output (plan band E):
170
-
171
- ```
172
- | # | Axis | Finding | Source | Adaptation in the toolkit (file) | Effort | Impact | In plan? |
173
- |---|------|---------|--------|----------------------------------|--------|--------|----------|
174
- | 1 | Protocol | read-only tools carry no annotations | <spec link> | add `annotations` to the read-only tools in index.js | Low | Medium | Yes (P1) |
175
- | 2 | Wrapped tooling | uses a simctl flag removed in Xcode <v> | <release notes> | switch tools/<family>/<file>.js to <new flag> | Low | High | Yes (P0) |
176
- | 3 | Peer servers | peer exposes <surface> | <repo link> | does not fit: outside the pipeline's phases | - | - | No |
177
- ```
178
-
179
- Rules for this band:
180
-
181
- - Band-E work lands in the toolkit repo, never mirrored into this one. Shipping it is `/multi-agent:sync` Step 3d.
182
- - A finding that changes the tool surface (new / renamed / removed tool) pairs with a pipeline-side item: bump the minimum toolkit version wherever a pipeline skill declares one.
183
- - If the current working directory IS the toolkit repo, skip band E and let bands A/B/C cover it - never report the same finding twice.
117
+ Full procedure - resolution (configuration first, never a hardcoded path; skip when nothing resolves or `enabled` is false), the 5 research axes, the audit command block, and the band-E output table + rules - lives in `$HOME/.claude/multi-agent-refs/refactor/dev-toolkit-research.md`. Read it before running this step.
184
118
 
185
119
  ## Step 0d: RUN-ERRORS - what the pipeline actually failed on
186
120
 
@@ -18,7 +18,7 @@ When invoked, it synchronizes all targets in order. It detects what changed, upd
18
18
 
19
19
  | # | Target | Path | Direction |
20
20
  |---|-------|-----|-----|
21
- | 1 | Claude Code (source of truth) | `~/.claude/commands/multi-agent.md` + `~/.claude/commands/multi-agent/` + `~/.claude/agents/` + `~/.claude/scripts/` | source |
21
+ | 1 | Claude Code (source of truth) | `~/.claude/commands/multi-agent/` + `~/.claude/multi-agent-refs/` + `~/.claude/agents/` + `~/.claude/scripts/` + `~/.claude/lib/` | source |
22
22
  | 2 | Copilot CLI | `~/.copilot/copilot-instructions.md` + `~/.copilot/skills/` | <- from Claude |
23
23
  | 2b | Codex CLI | `~/.codex/AGENTS.md` + `~/.codex/skills/multi-agent/` + `~/.codex/multi-agent-refs/` + `~/.codex/agents/*.toml` | <- from Claude (path-rewritten) |
24
24
  | 3 | multi-agent-pipeline repo | `~/multi-agent-pipeline/pipeline/` | <- from Claude (genericized) |
@@ -56,7 +56,7 @@ If nothing is stale -> report "All targets up to date" and stop.
56
56
 
57
57
  1. **Read first** - Understand the current state of all targets before making changes
58
58
  2. **Preserve file structure** - Each target has its own format:
59
- - `multi-agent.md` + phases/: detailed pipeline spec (frontmatter, phases, routing)
59
+ - `commands/multi-agent/` SKILL tree + `multi-agent-refs/phases/`: detailed pipeline spec (frontmatter, phases, routing)
60
60
  - `copilot-instructions.md`: general development instructions + pipeline summary section
61
61
  - `multi-agent-pipeline/pipeline/`: generic open-source version (NO personal data)
62
62
  3. **Sync shared sections** (Claude <-> Copilot):
@@ -71,7 +71,7 @@ If nothing is stale -> report "All targets up to date" and stop.
71
71
 
72
72
  ## Pipeline Repo Sync Rules (CRITICAL)
73
73
 
74
- 1. **Source**: `~/.claude/commands/multi-agent.md` + `~/.claude/commands/multi-agent/` + `~/.claude/agents/`
74
+ 1. **Source**: `~/.claude/commands/multi-agent/` + `~/.claude/multi-agent-refs/` + `~/.claude/agents/` + `~/.claude/lib/`
75
75
  2. **Target**: `~/multi-agent-pipeline/pipeline/`
76
76
  3. **Genericization** (must be applied BEFORE writing to the target):
77
77
  - Jira project key (`prefs.global.defaultJiraKey`) -> `{JIRA_KEY}`, `PROJ` in examples
@@ -82,8 +82,8 @@ If nothing is stale -> report "All targets up to date" and stop.
82
82
  - **Verify**: scan for personal/corporate data inside pipeline/ with `grep` -> 0 results
83
83
  4. **File mapping**:
84
84
  ```
85
- ~/.claude/commands/multi-agent.md -> pipeline/commands/multi-agent.md
86
85
  ~/.claude/commands/multi-agent/ -> pipeline/commands/multi-agent/
86
+ ~/.claude/multi-agent-refs/ -> pipeline/multi-agent-refs/ (refs + pickers, non-command)
87
87
  ~/.claude/commands/sim-test.md -> pipeline/commands/sim-test.md
88
88
  ~/.claude/agents/*.md -> pipeline/agents/
89
89
  ```