@mmerterden/multi-agent-pipeline 12.4.0 → 12.6.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 (70) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +1 -1
  3. package/docs/features.md +20 -0
  4. package/index.js +7 -1
  5. package/install/_dev-only-files.mjs +1 -0
  6. package/package.json +4 -3
  7. package/pipeline/agents/security-auditor.md +1 -1
  8. package/pipeline/commands/archive-guard.md +5 -5
  9. package/pipeline/commands/multi-agent/SKILL.md +2 -0
  10. package/pipeline/commands/multi-agent/design-check/SKILL.md +287 -0
  11. package/pipeline/commands/multi-agent/help/SKILL.md +45 -5
  12. package/pipeline/commands/multi-agent/refactor/SKILL.md +92 -12
  13. package/pipeline/commands/multi-agent/review/SKILL.md +1 -1
  14. package/pipeline/commands/multi-agent/sync/SKILL.md +119 -12
  15. package/pipeline/commands/multi-agent/test/SKILL.md +1 -1
  16. package/pipeline/commands/sim-test.md +5 -5
  17. package/pipeline/lib/credential-store.sh +32 -0
  18. package/pipeline/lib/extract-conventions.sh +1 -0
  19. package/pipeline/lib/repo-cache.sh +1 -0
  20. package/pipeline/lib/shadow-git.sh +8 -0
  21. package/pipeline/multi-agent-refs/cross-cli-contract.md +3 -3
  22. package/pipeline/multi-agent-refs/phases/phase-0-init.md +9 -1
  23. package/pipeline/multi-agent-refs/phases/phase-3-dev.md +2 -2
  24. package/pipeline/multi-agent-refs/phases/phase-4-review.md +3 -2
  25. package/pipeline/multi-agent-refs/phases/phase-5-test.md +14 -4
  26. package/pipeline/multi-agent-refs/phases.md +2 -0
  27. package/pipeline/multi-agent-refs/prompt-assembly.md +31 -0
  28. package/pipeline/preferences-template.json +18 -1
  29. package/pipeline/schemas/agent-state.schema.json +90 -0
  30. package/pipeline/schemas/design-check-config.schema.json +162 -0
  31. package/pipeline/schemas/learnings-ledger.schema.json +4 -0
  32. package/pipeline/schemas/migrations/state-2.0.0-to-2.1.0.mjs +30 -12
  33. package/pipeline/schemas/prefs.schema.json +161 -5
  34. package/pipeline/schemas/token-budget.json +2 -2
  35. package/pipeline/schemas/triage-corpus.schema.json +5 -1
  36. package/pipeline/scripts/README.md +7 -5
  37. package/pipeline/scripts/classify-plan-safety.mjs +8 -3
  38. package/pipeline/scripts/cost-budget-check.mjs +9 -5
  39. package/pipeline/scripts/eval-mine-corpus.mjs +19 -5
  40. package/pipeline/scripts/fixtures/install-layout.tsv +7 -7
  41. package/pipeline/scripts/gc-worktrees.sh +23 -1
  42. package/pipeline/scripts/learning-curve.mjs +167 -0
  43. package/pipeline/scripts/learnings-ledger.mjs +27 -2
  44. package/pipeline/scripts/lint-mcp-refs.mjs +207 -0
  45. package/pipeline/scripts/memory-load.sh +5 -1
  46. package/pipeline/scripts/render-work-summary.sh +4 -1
  47. package/pipeline/scripts/repo-map.mjs +1 -1
  48. package/pipeline/scripts/smoke-command-inventory.sh +81 -0
  49. package/pipeline/scripts/smoke-commands-skills-parity.sh +1 -1
  50. package/pipeline/scripts/smoke-compliance-skills.sh +4 -4
  51. package/pipeline/scripts/smoke-cross-cli-behavior.sh +12 -2
  52. package/pipeline/scripts/smoke-generate-issue.sh +6 -5
  53. package/pipeline/scripts/smoke-learning-curve.sh +61 -0
  54. package/pipeline/scripts/smoke-per-repo-memory.sh +2 -2
  55. package/pipeline/scripts/smoke-review-readiness.sh +3 -2
  56. package/pipeline/scripts/smoke-schema-validation.sh +19 -5
  57. package/pipeline/scripts/smoke-shadow-git.sh +4 -2
  58. package/pipeline/scripts/triage-memory.mjs +66 -10
  59. package/pipeline/scripts/uninstall.mjs +1 -1
  60. package/pipeline/skills/.skill-manifest.json +24 -8
  61. package/pipeline/skills/.skills-index.json +39 -3
  62. package/pipeline/skills/shared/README.md +10 -6
  63. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +10 -8
  64. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +248 -0
  65. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +22 -0
  66. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +67 -11
  67. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +1 -1
  68. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +51 -9
  69. package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +1 -1
  70. package/pipeline/skills/skills-index.md +8 -4
@@ -0,0 +1,287 @@
1
+ ---
2
+ description: "Mock-mode vs Figma design audit (iOS / Android, local-only). Pick repo + module, gate on mock support, enumerate every state driver into a countable target set, build Debug in a worktree, launch in mock mode, fetch Figma variants, compare each pixel + px-spacing + typography + color, and export a side-by-side annotated report (HTML + PDF + Confluence) to ~/DesignChecks. A coverage gate fails the run when a target is neither audited nor skipped with a reason."
3
+ description-tr: "Mock-mod vs Figma tasarım denetimi (iOS / Android, yalnızca lokal). Repo + modül seç, mock desteğini geçitle, her state sürücüsünü sayılabilir bir hedef kümesine çıkar, worktree'de Debug derle, mock modda aç, Figma varyantlarını çek, her varyantı piksel + px-boşluk + tipografi + renk düzeyinde karşılaştır, yan yana annotasyonlu raporu (HTML + PDF + Confluence) ~/DesignChecks altına aktar. Bir hedef ne denetlenmiş ne de gerekçeyle atlanmışsa kapsam geçidi koşuyu başarısız sayar."
4
+ argument-hint: '[scope] - empty = whole module; screen name; screen@variant; Figma URL(s); --resume'
5
+ allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep, TaskCreate, TaskUpdate, AskUserQuestion, Skill, mcp__claude_ai_Figma__get_metadata, mcp__claude_ai_Figma__get_design_context, mcp__claude_ai_Figma__get_screenshot, mcp__dev-toolkit__design_mock_detect, mcp__dev-toolkit__design_scenario_inventory, mcp__dev-toolkit__design_mock_launch, mcp__dev-toolkit__design_ui_geometry, mcp__dev-toolkit__design_visual_compare, mcp__dev-toolkit__design_report, mcp__dev-toolkit__ios_list_devices, mcp__dev-toolkit__ios_boot_device, mcp__dev-toolkit__ios_launch_app, mcp__dev-toolkit__ios_terminate_app, mcp__dev-toolkit__ios_screenshot, mcp__dev-toolkit__ios_tap, mcp__dev-toolkit__ios_swipe, mcp__dev-toolkit__ios_type_text, mcp__dev-toolkit__ios_open_url, mcp__dev-toolkit__ios_get_ui_tree, mcp__dev-toolkit__ios_status_bar, mcp__dev-toolkit__ios_set_appearance, mcp__dev-toolkit__ios_set_locale, mcp__dev-toolkit__ios_xcodebuild, mcp__dev-toolkit__ios_xcresult, mcp__dev-toolkit__android_list_devices, mcp__dev-toolkit__android_screenshot, mcp__dev-toolkit__android_tap, mcp__dev-toolkit__android_swipe, mcp__dev-toolkit__android_type_text, mcp__dev-toolkit__android_open_url, mcp__dev-toolkit__android_launch_app, mcp__dev-toolkit__android_stop_app
6
+ ---
7
+
8
+ # /multi-agent:design-check - Mock-mode vs Figma design audit
9
+
10
+ Local, on-device design-conformance auditor. It runs the app in a **mock mode** on a simulator / emulator and compares each screen (and every mock variant the build exposes) against its Figma design at the **pixel + geometry + typography + color** level, then produces a detailed report.
11
+
12
+ **Local-only**: no CI/CD, no cron, no commits, no PR. It is a read-only audit that writes a report to `~/DesignChecks/`. The worktree exists only to build the Debug app without touching the user's working tree.
13
+
14
+ > **Language (read FIRST)**: Two independent axes.
15
+ >
16
+ > 1. **`prefs.global.promptLanguage` is always `en`** - this spec and every instruction to the LLM stay English.
17
+ > 2. **`prefs.global.outputLanguage` is user-selectable** - applies to conversational lines and the human-readable parts of the report. Pass it to `design_report` as `report.lang`; the engine defaults to English and ships an `en` + `tr` label pack, plus per-key `report.labels` overrides.
18
+ >
19
+ > Regardless of `outputLanguage`, these stay English: `AskUserQuestion` labels/headers, branch names, file paths, code identifiers, log lines. Full contract: `$HOME/.claude/multi-agent-refs/rules.md` "Language Application".
20
+
21
+ ## Scope - `$ARGUMENTS`
22
+
23
+ The scope decides which **inventory targets** (Phase 0 step 5) the run must audit. It never changes how thoroughly each target is audited.
24
+
25
+ | Form | Example | Scope |
26
+ |------|---------|-------|
27
+ | empty / `module` | `/multi-agent:design-check` | Every target in the module's inventory |
28
+ | screen name | `boarding-pass` | Every target whose `screen` matches (case/separator-insensitive) |
29
+ | `screen@variant` | `boarding-pass@expired` | One target |
30
+ | target id | `scenario-case:boardingpassoutcome-expired` | One target, exactly |
31
+ | Figma URL(s) | `https://figma.com/design/…?node-id=1-2` | Only the frames those URLs name |
32
+ | `--resume` | `/multi-agent:design-check --resume` | The unaudited remainder of the most recent run for this repo + module |
33
+ | combinations | `seat-map summary@semi-success` | Union of the above, space- or newline-separated |
34
+
35
+ Multiple forms may be combined. A scope that matches **no** inventory target is an error, not an empty run: print the closest inventory ids and halt.
36
+
37
+ **Whole-module is the default, and it is meant to finish.** The inventory prices each target (`cost: relaunch | in-app`) and batches them into a run `plan`, so a 50-target module is typically about a dozen relaunches rather than fifty - a full audit is one sitting, not a project. Scope exists for resuming an interrupted run and for re-checking one screen after a fix, **not** for trimming an audit down to what feels affordable. The coverage gate applies to the **scoped** target set, so a deliberate scoped run is never penalised for out-of-scope targets, and `--resume` closes the remainder.
38
+
39
+ ## Pipeline
40
+
41
+ ```
42
+ Phase 0: Init & Gate → repo + module picker, platform detect, MOCK FEASIBILITY GATE, SCENARIO INVENTORY, scope resolve, report dir, worktree
43
+ Phase 1: Build & Launch → Debug build in worktree, boot device, install, launch in mock mode
44
+ Phase 2: Figma → fetch module frame tree, enumerate + map variants (ask when ambiguous)
45
+ Phase 3: Drive & Compare → per plan batch: one launch → capture + flip in-app states → match → batch-ask → compare
46
+ Phase 4: Report → coverage gate + assemble + export HTML + PDF (+ Confluence) to ~/DesignChecks/
47
+ ```
48
+
49
+ ## Requirements
50
+
51
+ - **iOS**: Xcode + an available Simulator. **Android**: Android SDK + a running emulator / device.
52
+ - **MCP**: the `dev-toolkit` MCP server (>= 2.8.0, for `design_scenario_inventory`, the `design_report` coverage gate, and `design_visual_compare` region alignment). The Figma MCP (`mcp__claude_ai_Figma__*`) must be authenticated - the user supplies the Figma URL.
53
+ - The selected module must support a **mock mode** (Phase 0 gate decides this). No mock support → the command halts.
54
+
55
+ ## Phase Tracker Contract (mandatory)
56
+
57
+ Register one tile per phase in strict order BEFORE any update, on both channels. Full spec: `$HOME/.claude/multi-agent-refs/tracker-contract.md`.
58
+
59
+ ```bash
60
+ bash $HOME/.claude/scripts/phase-tracker.sh init "$TASK_ID"
61
+ for p in "0:Init & Gate" "1:Build & Launch" "2:Figma" "3:Drive & Compare" "4:Report"; do
62
+ bash $HOME/.claude/scripts/phase-tracker.sh add "${p%%:*}" "${p#*:}"
63
+ done
64
+ ```
65
+
66
+ In Claude Code also drive the native TaskList widget: fire all `TaskCreate` calls in phase order (0→1→2→3→4) first, persist each `taskId` via `phase-tracker.sh meta <N> tasklist_id`, then flip status with `TaskUpdate` + `phase-tracker.sh update` at every boundary. On Copilot / plain shell call `phase-tracker.sh render` instead (no TaskCreate).
67
+
68
+ ## STOP-AND-CONFIRM format
69
+
70
+ Every Phase 0 / Phase 2 decision uses a native `AskUserQuestion` picker (numbered text menus are forbidden - `feedback_native_picker_ui`). Print a `Step <i>/<n>: <what it decides>` breadcrumb before each picker. Confirmation is required even with a single option; state inheritance from a previous run is FORBIDDEN.
71
+
72
+ ---
73
+
74
+ ## Phase 0 - Init, Feasibility Gate & Inventory
75
+
76
+ 0. **MCP CURRENCY GATE (first, before anything expensive)** - an MCP stdio server publishes its tool list once at `initialize` and never re-reads the code, so a session connected to a server process that started before the last update keeps serving the OLD tool list while still reporting "connected". Discovering that after a Debug build and a device drive wastes the whole run and produces a report missing the very checks this spec relies on.
77
+
78
+ Assert both halves before continuing:
79
+
80
+ a. **Session** - `mcp__dev-toolkit__design_scenario_inventory` must be present in the tools available to you, and `mcp__dev-toolkit__design_visual_compare` must accept `live_region`. Absent → the session is bound to a stale process.
81
+
82
+ b. **Disk** - probe the configured server directly, which reports what a fresh connection WOULD serve:
83
+ ```bash
84
+ cd "$(python3 -c "import json,os;print(json.load(open(os.path.expanduser('~/.claude.json')))['mcpServers']['dev-toolkit']['args'][0].rsplit('/',1)[0])")" && \
85
+ printf '%s\n%s\n' \
86
+ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' \
87
+ '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
88
+ | node index.js 2>/dev/null | python3 -c "
89
+ import sys,json
90
+ for l in sys.stdin:
91
+ try: m=json.loads(l)
92
+ except: continue
93
+ if m.get('id')==1: print('version', m['result']['serverInfo']['version'])
94
+ if m.get('id')==2:
95
+ n=[t['name'] for t in m['result']['tools']]
96
+ print('tools', len(n), 'inventory', 'design_scenario_inventory' in n)"
97
+ ```
98
+
99
+ Branch on the two results:
100
+ - **disk OK, session missing the tool** → **HALT** and tell the user to reconnect: `/mcp` → `dev-toolkit` → Reconnect. Note the tool-count tell (a stale build advertises one fewer `design_*` tool). If a reconnect does not take, stale server processes may be lingering - `pgrep -f dev-toolkit-mcp/index.js` with `ps -o lstart=` shows their start times, and any that predate the code's mtime cannot serve the current tools.
101
+ - **disk itself stale** (older version, or `inventory False`) → **HALT**: the checkout needs updating before a reconnect can help.
102
+ - **both current** → continue.
103
+
104
+ Never work around a stale server by substituting a local `node` call for the missing tool: the run would silently lose the coverage gate and region alignment, which is exactly the failure this gate exists to prevent.
105
+
106
+ 1. **Repo picker** - reuse `$HOME/.claude/multi-agent-refs/_repo-picker.md`. The account picker is skipped (Figma token is user-supplied, no Jira/GitHub fetch happens) unless Confluence export is enabled, in which case resolve the Confluence token via `account-resolver.sh`.
107
+ 2. **Module / dev-context picker** - reuse `$HOME/.claude/multi-agent-refs/_dev-context.md`. Auto-suggest submodules from `.gitmodules` (`submodule-detector.sh`); the user selects the single module to audit (multi-module allowed - each is audited independently).
108
+ 3. **Platform detect** - `.xcodeproj` / `Package.swift` → iOS; `build.gradle*` → Android (same markers as `phase-0-init.md`). Persist `state.platform`.
109
+ 4. **MOCK FEASIBILITY GATE** - run against the selected module path:
110
+ ```
111
+ mcp__dev-toolkit__design_mock_detect({ repo_path: "<module path>", platform: "<ios|android>",
112
+ extra_keys: <design-check-config mock.keys, if any> })
113
+ ```
114
+ Branch on `supported`:
115
+ - **`false`** → **HALT**. Show `reason` + that no runtime mock switch / launchable app / mock fixtures were found. Tell the user this module cannot be audited by design-check and stop. Do not fabricate a comparison.
116
+ - **`"debug-only"`** → surface an `AskUserQuestion` warning: mocks are compiled into the Debug build via `#if DEBUG` DI, so **variants cannot be toggled at launch** - only the default Debug state is comparable. Options: `{ label: "Continue", description: "Audit the single default Debug state only" }`, `{ label: "Cancel", description: "Stop" }`.
117
+ - **`true`** → continue. Persist `state.designCheck.mock = <detect result>` (mechanism, activation, variantsHint, evidence).
118
+ 5. **SCENARIO INVENTORY (this is the audit's target set)**:
119
+ ```
120
+ mcp__dev-toolkit__design_scenario_inventory({ repo_path: "<module path>", platform,
121
+ extra_launch_args: <config inventory.extraLaunchArgs>,
122
+ extra_targets: <config inventory.extraTargets>,
123
+ ignore_targets: <config inventory.ignoreTargets> })
124
+ ```
125
+ Returns `targets[]` - each `{ id, kind, label, screen, driver, cost, evidence }` - plus `plan[]`, `relaunchCount`, `groups[]`, `byKind`, `byCost`, `ignored[]`, `truncated`, `scanStrategy`. Kinds: `launch-arg`, `scenario-case`, **`prefix-code`** (a mock repository branching on the prefix of the reference the user types - usually the LARGEST group, and the one a selector-only search misses entirely), `code-scenario`, `fixture`, `deep-link`.
126
+
127
+ This list, not the agent's reading of the code and not what the UI happens to expose to tapping, is what the run is measured against. Persist verbatim to `state.designCheck.inventory`.
128
+ - `targetCount: 0` → warn that no state driver was found and that only the default launch state can be audited; a `debug-only` project legitimately lands here.
129
+ - `truncated: true` → the inventory hit its cap, so the target set is INCOMPLETE. Say so now, and pass `coverage.truncatedInventory: true` in Phase 4 so the gate fails rather than reporting a clean percentage of a partial denominator. Narrow the scope to a screen and work through the module in `--resume` steps.
130
+ - `ignored[]` non-empty → list what the config dropped, so a stale `ignoreTargets` cannot quietly shrink the audit.
131
+ 6. **Scope resolve** - intersect `$ARGUMENTS` (grammar above) with `inventory.targets`. Persist `state.designCheck.scope = { argument, targetIds[] }`.
132
+
133
+ Print the resolved set grouped by screen **with its relaunch cost**: `<n> targets · <relaunchCount> relaunches`. Read the cost from `plan`, not from the target count - one relaunch serves every in-app target on that screen, so a 50-target module is typically a dozen relaunches, not fifty. **Whole-module is the intended default**; only ask for confirmation when `relaunchCount` exceeds `config coverage.confirmAbove` (default 25), and phrase it as a cost estimate, not as an invitation to shrink the audit. Never propose a smaller scope as the easy path - a scoped run is for resuming or for a focused re-check, not for avoiding work.
134
+ 7. **`--resume`** - read the most recent `~/DesignChecks/{repo}__{module}/*/run-state.json`; the scope becomes that run's targets minus its `covered` and minus its `skipped` entries. Skips carry a reason and are honoured, so a resume covers the genuinely unaudited remainder. No previous run → tell the user and fall back to whole-module scope after confirmation.
135
+ 8. **Report dir** - create `~/DesignChecks/{repo}__{module}/{UTC-timestamp}/` (and `assets/` inside it) now, and persist it as `state.designCheck.reportDir`. Phase 3 writes captures, comparison images, and `run-state.json` into it, so it must exist before driving starts - not at export time. This is report output, not a worktree; $HOME is intended here.
136
+ 9. **Worktree** - build the Debug app in an isolated worktree so the user's tree is untouched. Follow `phase-0-init.md` Step 8 convention exactly: `{projectRoot}/{worktreeBasePath}/{taskId}` (default `.worktrees/DC-<shortId>`), **never under $HOME** (`feedback_worktree_path_convention`). Stale-lock heal (`git worktree prune`) + residue guard (`.worktrees/` in `.git/info/exclude`) first. Local mode is not offered - the audit always uses a worktree checkout of the current branch's HEAD (no fetch/push).
137
+
138
+ Persist `agent-state.json` with `taskId`, `mode: "design-check"`, `platform`, `projectRoot`, `worktreePath`, `module`, `designCheck`.
139
+
140
+ ## Phase 1 - Build & Launch (mock)
141
+
142
+ 1. **Debug build** in the worktree (mock activation requires the Debug configuration):
143
+ - iOS: `mcp__dev-toolkit__ios_xcodebuild({ workspace|project, scheme, configuration: "Debug", action: "build", destination: "generic/platform=iOS Simulator" })`. Drill failures via `ios_xcresult`.
144
+ - Android: `./gradlew :<module>:assembleDebug` (or `installDebug`) via Bash.
145
+ 2. **Boot device + install**: iOS `ios_list_devices` → `ios_boot_device` → install the built `.app` (`xcrun simctl install`). Android: ensure an emulator is running, `adb install -r <apk>`.
146
+ 3. **Deterministic state**: iOS `ios_status_bar({ preset: "clean" })` (09:41 / full battery); set a fixed appearance + locale so captures are stable across runs.
147
+ 4. **Launch in mock mode** using the activation from Phase 0:
148
+ ```
149
+ mcp__dev-toolkit__design_mock_launch({ platform, bundle_id|package_name,
150
+ launch_arg: state.designCheck.mock.activation.launchArg, // iOS, e.g. "-debugMockMode YES"
151
+ intent_extra: state.designCheck.mock.activation.intentExtra }) // Android
152
+ ```
153
+ For `debug-only` there is no switch - just launch the Debug build. The build is installed once and stays installed: Phase 3 relaunches it per target rather than rebuilding.
154
+
155
+ ## Phase 2 - Figma fetch & variant mapping (module-scoped)
156
+
157
+ Figma **discovery** happens only here: the frame tree is fetched once and no later phase browses Figma looking for candidates. Phase 3 may still fetch a specific node the user hands over in the 3.3 batch-ask - that is a targeted fetch of an already-identified frame, not discovery, and it is the only Figma call allowed after this phase.
158
+
159
+ 1. Resolve the Figma URL (`$ARGUMENTS` or ask via `AskUserQuestion`). Parse `fileKey` + `nodeId` (`figma.com/design/{fileKey}/...?node-id={id}`; convert `-`→`:` in node ids).
160
+ 2. `mcp__claude_ai_Figma__get_metadata({ fileKey, nodeId })` → the frame tree. Treat direct child frames as **candidate variants**.
161
+ 3. **Map inventory targets → Figma frames**: match each scoped target's `screen` + `label` (and `state.designCheck.mock.variantsHint`) to frame names by similarity.
162
+ - Confident 1:1 match → accept.
163
+ - **Ambiguous or unmatched** → deferred to the Phase 3.3 batch-ask, where the live capture can be shown alongside the question. Never guess silently.
164
+ - `debug-only` projects → a single variant (the default state) mapped to the primary frame.
165
+ 4. For each mapped variant: `mcp__claude_ai_Figma__get_screenshot` (the design render PNG, download locally) and `mcp__claude_ai_Figma__get_design_context` (node geometry: `absoluteBoundingBox`, `itemSpacing`, paddings, text `fontSize`/`fontFamily`, `fills` colors, and any `CodeConnectSnippet` component name). Flatten the node subtree with the geometry helper into a `figma_spec` element list. Record the Figma frame size (`figmaFrame`).
166
+
167
+ Persist the variant list + spec + PNG paths to `state.designCheck.variants[]`.
168
+
169
+ ## Phase 3 - Drive every scoped target → capture → match → batch-ask → compare
170
+
171
+ **This phase iterates `state.designCheck.scope.targetIds` - a finite list decided in Phase 0. It ends when every id is resolved, not when the UI stops offering new taps.** Tap-walking alone cannot reach a state that needs a different launch argument, a different scenario case, or a typed scenario code, which is exactly how a module's error / edge states go missing.
172
+
173
+ ### 3.1 Drive the inventory's plan, batch by batch
174
+
175
+ **Follow `inventory.plan`, filtered to the scoped ids.** Each batch is one launch: the batch's relaunch target opens a screen, and every in-app target for that same screen is then flipped while the app is already sitting there. Driving the plan is what makes full coverage affordable - target-by-target relaunching is what made earlier runs give up a third of the way in.
176
+
177
+ For each batch:
178
+ 1. Launch once with the batch's `launch` driver (or the plain mock activation for the `(default launch)` batch).
179
+ 2. Navigate to the screen (`ios_tap` / `ios_swipe` / `ios_type_text` route through idb).
180
+ 3. Capture the batch's relaunch target.
181
+ 4. For each in-app target in the batch: flip its selector (scenario case / scenario code), let the screen re-render, capture. **No relaunch between these.**
182
+
183
+ Per-target activation by `driver.type`:
184
+
185
+ | `driver.type` | Activation |
186
+ |---|---|
187
+ | `launch-arg` | `design_mock_launch({ launch_arg: "<mock activation> <driver.launchArg>" })` - the mock switch AND the target's flag together |
188
+ | `intent-extra` | `design_mock_launch({ intent_extra: "<mock extra> <driver.intentExtra>" })` |
189
+ | `scenario` | Set `driver.enum` to `driver.case` through the build's debug scenario picker (navigate to it, select, return), then drive the flow that consumes it |
190
+ | `code` (from `prefix-code`) | Type a reference beginning with `driver.code` at the entry field the flow starts from, then walk to `driver.appliesTo`. The prefix decides which fixture the mock repository returns, so this is how most per-screen variants are reached |
191
+ | `code` (from `code-scenario`) | Same entry field, but the code is flow-wide rather than owned by one screen |
192
+ | `fixture` | Activate the launch arg / scenario that reads `driver.file`; when nothing does, the target is a skip with reason "fixture not reachable from any driver" |
193
+ | `deep-link` | `ios_open_url` / `android_open_url` with `driver.url` |
194
+ | `manual` | Config-declared: follow the config's note, or skip with that note as the reason |
195
+
196
+ While a target's state is on screen, also capture the **sub-states reachable from it by tapping** - overlays, bottom sheets, modals, popups, inline errors, QR / share sheets. These cost no relaunch and belong to the target that exposed them; record them as additional captures under that target id (`<id>#<sub-label>`).
197
+
198
+ For each capture: `ios_screenshot` (save PNG into the Phase 0 report dir) + `mcp__dev-toolkit__design_ui_geometry` (live boxes + screen size) → append to `state.designCheck.captured[]` with the target id and a human label. **Persist `state` and `run-state.json` after every capture**, so a run that dies mid-way resumes from where it stopped instead of starting over.
199
+
200
+ If a target cannot be reached, record it immediately as `{ id, reason }` in `state.designCheck.skipped[]` with a concrete reason ("scenario picker not present in this build", "needs a live PNR", "crashes on launch: <symbol>"). "Requires a scenario / prefix / launch-arg" is **not** a reason - that is a description of the work, and the work is this phase's job.
201
+
202
+ ### 3.2 Match each capture → Figma frame (auto)
203
+
204
+ For each captured screen, resolve its Figma frame: drill the relevant board (`get_metadata` result from Phase 2), match by structure/content; accept only a **confident** match. Add matched → `pairs[]`.
205
+
206
+ ### 3.3 Batch-ask the user for EVERYTHING unmatched (ONE prompt, WITH the visual)
207
+
208
+ Collect ALL captures with no confident Figma match into a single list and ask the user ONCE - never guess, never show a wrong frame. **For each unmatched screen you MUST SHOW its captured live screenshot** (render/attach the PNG so they see exactly which visual you mean), name the screen, and ask for the Figma node-id / URL (in `outputLanguage`). Optionally list your best-guess candidate frame names. The user supplies the node-id/URL per shown screenshot; each becomes a confirmed pair. A screen the user declines to map is a skip with reason "no Figma frame supplied".
209
+
210
+ ### 3.4 Compare ALL pairs in one pass
211
+
212
+ For each pair (matched + user-supplied), fetch `get_screenshot` + `get_design_context`, then:
213
+ ```
214
+ mcp__dev-toolkit__design_visual_compare({
215
+ figma_png, live_png, out_dir: "<report dir>/assets", label: "<variant>",
216
+ figma_spec, live_geometry, figma_frame, live_screen,
217
+ crop_top_live: <status-bar px>, // strip device chrome the Figma frame lacks
218
+ tolerance_px: 2, color_tolerance: 3, max_diff_pct: 1.0 })
219
+ ```
220
+ Collect `findings` (spacing / size / position in px, color ΔE with hex, typography), `perceptualPct`, and the written image paths (figma / live / diff / overlay / side-by-side).
221
+
222
+ **Bottom sheets, modals, and any partial overlay need region alignment.** Their Figma frame covers only the sheet, while the capture is the whole screen. Passing that pair as-is stretches a full screen onto a sheet-shaped frame, which misplaces every element inside the sheet and buries the real defect in noise. So for any capture whose frame is not full-screen:
223
+
224
+ ```
225
+ mcp__dev-toolkit__design_visual_compare({ ...as above,
226
+ live_region: <the sheet container's {x,y,w,h} from design_ui_geometry>,
227
+ expected_region: <where the design puts that sheet, same units> })
228
+ ```
229
+ - `live_region` rebases the comparison onto the sheet's own box. Take it from the `design_ui_geometry` element that is the sheet container (the outermost element whose height is well under the screen's and which holds the sheet's content), NOT from a guess.
230
+ - `expected_region` comes from the Figma frame's own placement inside its parent screen frame. With it, the engine emits an `inset` finding per edge.
231
+ - `crop_top_live` is ignored when `live_region` is given - the region crop has already excluded device chrome.
232
+
233
+ **Edge insets are defects, not tolerances.** A design that shows a sheet flush to the screen edges is not satisfied by one floating in from them, and the reverse is equally wrong. Report every `inset` finding as a deviation with its px delta; never absorb a side gap as "close enough", never raise `tolerance_px` to make one disappear. The same applies to the sheet's internal content padding, which the normal element pairing measures once the region alignment is right.
234
+
235
+ **Component reference (best-effort)**: if a Figma atom carries a Code Connect component name and the repo has a matching `*.figma.swift` / `*.figma.kt`, attach that component's reference render to the variant's `componentRefs`.
236
+
237
+ **Fix prompt**: from the findings, compose a ready-to-paste developer prompt (target file/screen + each deviation with expected vs actual token/value) so the user can hand it straight to an agent to apply the fix.
238
+
239
+ ### 3.5 Close the ledger
240
+
241
+ Every scoped target id must end in exactly one bucket:
242
+
243
+ - **covered** - captured AND compared (or captured and explicitly awaiting a Figma frame the user declined to supply, which is a skip)
244
+ - **skipped** - with a concrete reason recorded in 3.1 / 3.3
245
+
246
+ Write `run-state.json` into the Phase 0 report dir with `{ targetIds, covered, skipped }` so `--resume` can pick up the remainder. An id in neither bucket is a bug in this phase, and Phase 4's gate will fail the run for it.
247
+
248
+ Before leaving this phase, compare `covered.length + skipped.length` against `scope.targetIds.length`. If they differ, the difference is a set of targets nobody decided about - go back and drive them, or record why they cannot be driven. Reaching Phase 4 with a mismatch and letting the gate report it is the worst of both worlds: the work is undone AND the run is marked incomplete.
249
+
250
+ ## Phase 4 - Report, coverage gate & export
251
+
252
+ 1. **Output dir**: `state.designCheck.reportDir`, already created in Phase 0 - Phase 3's captures and comparison images are already inside it. Do not mint a second timestamped dir here.
253
+ 2. Assemble the report object:
254
+ ```
255
+ { project, module, platform, figmaUrl, figmaFileKey, timestamp,
256
+ lang: <prefs.global.outputLanguage>,
257
+ coverage: { targets: <scoped inventory targets, as the id array or the target objects>,
258
+ covered: <audited id array>,
259
+ skipped: [ { id, group, reason } ],
260
+ truncatedInventory: <inventory.truncated>,
261
+ floor: <config coverage.floor, optional> },
262
+ variants: [ { name, figmaNodeId, perceptualPct, passed, compareSize, liveSize,
263
+ images, findings, fixPrompt, componentRefs } ] }
264
+ ```
265
+ Pass **ids**, not counts: the engine then names each unaccounted target in the report instead of printing an anonymous tally. `compareSize` and `liveSize` come straight from the `design_visual_compare` result.
266
+ 3. **Render + export**:
267
+ ```
268
+ mcp__dev-toolkit__design_report({ report, out_dir: state.designCheck.reportDir,
269
+ formats: ["html", "pdf"] + (confluence enabled ? ["confluence"] : []) })
270
+ ```
271
+ - HTML: self-contained (base64 images, CSS-positioned annotations over the live capture, stacked findings, fix prompt), with the coverage gate banner at the top.
272
+ - PDF: via Playwright if present; if unavailable the tool returns `pdfError` - report it and note the HTML can be printed manually.
273
+ - **Confluence**: only if `figmaConfig.confluence.enabled` (or prefs). Reuse the pipeline's Confluence adapter (`/multi-agent:channels` storage-format upload) with the report HTML as the page body + PNGs as attachments. Disabled → graceful skip with a one-line note.
274
+ 4. **COVERAGE GATE (blocking, not advisory)** - read `coverage` from the tool result and persist it to `state.designCheck.coverage`:
275
+ - `gate: "pass"` → report per-variant PASS/FAIL + findings count + report paths.
276
+ - `gate: "fail"` → the run is **INCOMPLETE**. Print `coverageError`, the `unaccountedIds`, and the exact command that closes the gap: `/multi-agent:design-check --resume`. Do not present an incomplete audit as a finished one, do not bury the miss in a footnote, and never pad the covered list to make the gate pass.
277
+
278
+ The gate is a last line of defence, not the plan. If it fires, Phase 3 left work undone - the correct response is to drive the missing targets, and only then to report.
279
+ 5. Clean up the worktree (`git worktree remove --force`) unless the user asked to keep the built app. The report dir is never removed.
280
+
281
+ ## Notes
282
+
283
+ - **Feasibility is real**: many projects legitimately cannot be audited (no launchable app, no runtime switch). Report that honestly and stop - never substitute a fabricated or partial comparison.
284
+ - **The inventory is the contract**: Phase 0 step 5 decides what "done" means. An audit that visits the linear happy path and lists the rest as "not visited" is the failure mode this pipeline exists to prevent; the gate makes it visible instead of polite.
285
+ - **Chunk with scope, not with silence**: a 50-target module is a legitimate multi-run job. Scope it, finish each run's gate cleanly, and let `--resume` carry the remainder.
286
+ - **"Pixel perfect" is perceptual + geometric**: a Figma render never matches device dimensions 1:1, so the engine normalizes scale and crops chrome. Findings are reported with explicit px / pt / hex deltas and a tolerance, not as strict pixel equality.
287
+ - The engine (`design_*` tools) is generic and project-agnostic; all project specifics (mock switch keys, extra launch args / targets, variant→node overrides, status-bar crop, coverage floor, Confluence toggle) come from `design-check-config.json` / prefs, never hardcoded.
@@ -118,14 +118,14 @@ Post-Hoc & Side-Channel:
118
118
  /multi-agent:diff-explain Map a Phase 4 triage finding back to specific diff lines
119
119
  /multi-agent:search Cross-task log search with smart ranking; --semantic queries triage corpus
120
120
  /multi-agent:scan Skill security scan against tiered pattern catalog
121
- /multi-agent:refactor Adapted best-practices + bug hunt + upstream-drift check -> one plan, approval, dev + sync
121
+ /multi-agent:refactor Adapted best-practices + bug hunt + upstream-drift + dev-toolkit MCP research -> one plan, approval, dev + sync
122
122
 
123
123
  Setup & Maintenance:
124
124
 
125
125
  /multi-agent:setup First-run wizard - Keychain tokens + Git identity + language
126
126
  /multi-agent:language [en|tr] Show or set outputLanguage (promptLanguage stays English)
127
127
  /multi-agent:stack <id> Select stack by enabling the matching marketplace plugin(s) (ios / android / mobile / backend / frontend / fullstack / all)
128
- /multi-agent:sync Sync ecosystem (Claude Code + Copilot CLI + pipeline + website)
128
+ /multi-agent:sync Sync ecosystem (Claude Code + Copilot CLI + pipeline + website + dev-toolkit MCP)
129
129
  /multi-agent:update Pull latest pipeline + reinstall + run migrations
130
130
  /multi-agent:uninstall Uninstall pipeline from every CLI (--all-data also clears settings + logs; Keychain tokens always intact, double confirm)
131
131
 
@@ -170,6 +170,26 @@ Manual Test (Phase 5 standalone - Xcode hint flow):
170
170
  /multi-agent:manual-test Checkout task branch, print Xcode/SourceTree hints,
171
171
  /multi-agent:manual-test #N wait for your "ok" / "fix: ..." verdict.
172
172
 
173
+ Design Check (mock-mode vs Figma, local-only - powered by dev-toolkit-mcp design_* tools):
174
+
175
+ /multi-agent:design-check Whole-module design audit: pick repo+module, gate on mock support,
176
+ enumerate every state driver (launch args, scenario cases, scenario codes,
177
+ fixtures, deep links) into a countable target set, build Debug in a worktree,
178
+ drive each target in mock mode via idb, compare each vs its Figma frame
179
+ (padding/width/spacing/font/color/component/localization), and export a
180
+ report (HTML+PDF, ~/DesignChecks).
181
+ /multi-agent:design-check <screen> Scope to one screen's targets (e.g. boarding-pass).
182
+ /multi-agent:design-check <screen@var> Scope to a single variant (e.g. boarding-pass@expired).
183
+ /multi-agent:design-check <figma-url…> Scope to the frame(s) those URLs name.
184
+ /multi-agent:design-check --resume Audit the unaudited remainder of the last run for this repo+module.
185
+ # COVERAGE GATE: every target is either audited or skipped WITH a concrete reason. Anything else fails the
186
+ # gate and the run is reported INCOMPLETE with the missing target ids - a partial audit never reads as clean.
187
+ # "Requires a scenario / prefix / launch-arg" is not a reason; reaching those states is the run's job.
188
+ # When a live screen has no confident Figma match, it SHOWS you the screenshot and asks for the node-id.
189
+
190
+ dev-toolkit-mcp design_* tools it drives: design_mock_detect, design_scenario_inventory, design_mock_launch,
191
+ design_ui_geometry, design_visual_compare, design_report (+ ios_* / android_* device control).
192
+
173
193
  ------------------------------------------------------------
174
194
 
175
195
  Setup:
@@ -195,7 +215,7 @@ Key Features:
195
215
  Multi-Repo Per-repo worktrees, per-repo identity, integration build before commit
196
216
  Identity Routing Git identity auto-picked from repo origin URL (corporate vs personal)
197
217
  Issue Safety Never auto-closes issues (4 approvals required, GitHub + Jira)
198
- Store Compliance /multi-agent:test "store-ready" runs 17-rule iOS audit (ITMS / Privacy Manifest /
218
+ Store Compliance /multi-agent:test "store-ready" runs 18-rule iOS audit (ITMS / Privacy Manifest /
199
219
  code signing / debug-tool leak / IPv6 / SDK list / etc.) and 21-rule Android audit
200
220
  Bilingual EN + TR - outputLanguage toggles assistant explanations; promptLanguage is locked en
201
221
 
@@ -341,14 +361,14 @@ Post-Hoc & Side-Channel:
341
361
  /multi-agent:diff-explain Phase 4 triage bulgusunu diff satırlarına eşle
342
362
  /multi-agent:search Task log'larında akıllı arama; --semantic triage corpus'unu sorgular
343
363
  /multi-agent:scan Skill güvenlik taraması (tiered pattern catalog)
344
- /multi-agent:refactor Uyarlanmış best-practice + bug avı + upstream-drift kontrolü -> tek plan, onay, dev + sync
364
+ /multi-agent:refactor Uyarlanmış best-practice + bug avı + upstream-drift + dev-toolkit MCP araştırması -> tek plan, onay, dev + sync
345
365
 
346
366
  Setup & Maintenance:
347
367
 
348
368
  /multi-agent:setup İlk kurulum sihirbazı - Keychain token + Git kimliği + dil
349
369
  /multi-agent:language [en|tr] outputLanguage'ı göster veya ayarla (promptLanguage İngilizce kalır)
350
370
  /multi-agent:stack <id> Stack'i eşleşen marketplace plugin'i etkinleştirerek seç (ios / android / mobile / backend / frontend / fullstack / all)
351
- /multi-agent:sync Ekosistemi senkronize et (Claude Code + Copilot CLI + pipeline + website)
371
+ /multi-agent:sync Ekosistemi senkronize et (Claude Code + Copilot CLI + pipeline + website + dev-toolkit MCP)
352
372
  /multi-agent:update En son pipeline'ı çek + reinstall + migration çalıştır
353
373
  /multi-agent:uninstall Pipeline'ı tüm CLI'lerden kaldır (--all-data ayar + logları da siler; Keychain token her zaman dokunulmaz, çift onay)
354
374
 
@@ -393,6 +413,26 @@ Manuel Test (Phase 5 standalone - Xcode hint akışı):
393
413
  /multi-agent:manual-test Task branch'ine checkout, Xcode/SourceTree hint basar,
394
414
  /multi-agent:manual-test #N "ok" / "fix: ..." yanıtını bekler.
395
415
 
416
+ Design Check (mock-mod vs Figma, yalnızca lokal - dev-toolkit-mcp design_* tool'larıyla):
417
+
418
+ /multi-agent:design-check Tüm modül tasarım denetimi: repo+modül seç, mock desteğini geçitle,
419
+ her state sürücüsünü (launch arg, senaryo case'leri, senaryo kodları,
420
+ fixture'lar, deep link'ler) sayılabilir bir hedef kümesine çıkar,
421
+ worktree'de Debug derle, her hedefi mock modda idb ile sür, her birini
422
+ Figma frame'iyle karşılaştır (padding/genişlik/spacing/font/renk/
423
+ component/localization), rapor çıkar (HTML+PDF, ~/DesignChecks).
424
+ /multi-agent:design-check <ekran> Tek ekranın hedeflerine kapsa (örn. boarding-pass).
425
+ /multi-agent:design-check <ekran@varyant> Tek varyanta kapsa (örn. boarding-pass@expired).
426
+ /multi-agent:design-check <figma-url…> URL'lerin işaret ettiği frame'lere kapsa.
427
+ /multi-agent:design-check --resume Bu repo+modül için son koşunun denetlenmemiş kalanını denetle.
428
+ # KAPSAM GEÇİDİ: her hedef ya denetlenir ya da SOMUT bir gerekçeyle atlanır. Başka her durum geçidi
429
+ # düşürür ve koşu eksik hedef id'leriyle EKSİK raporlanır - kısmi denetim asla temiz görünmez.
430
+ # "Senaryo / prefix / launch-arg gerektirir" gerekçe değildir; o state'lere ulaşmak koşunun işidir.
431
+ # Canlı ekranın Figma karşılığı kesin bulunamazsa SANA screenshot'ı gösterip node-id sorar.
432
+
433
+ Sürdüğü dev-toolkit-mcp design_* tool'ları: design_mock_detect, design_scenario_inventory, design_mock_launch,
434
+ design_ui_geometry, design_visual_compare, design_report (+ ios_* / android_* cihaz kontrolü).
435
+
396
436
  ------------------------------------------------------------
397
437
 
398
438
  Setup:
@@ -1,37 +1,39 @@
1
1
  ---
2
- description: "Analyse the project: extract adapted best-practices, hunt real bugs + improvement areas, check upstream drift of derived skills, draft one plan, take approval, develop, then ask whether to sync."
3
- description-tr: "Projeyi analiz eder: uyarlanmış best-practice'leri çıkarır, gerçek bug + iyileştirme alanlarını avlar, türetilmiş skill'lerin upstream drift'ini kontrol eder, tek plan taslağı çıkarır, onay alır, geliştirir, sonra sync isteyip istemediğini sorar."
4
- allowed-tools: Read, Write, Edit, Bash, Glob, Grep, Agent, AskUserQuestion, WebFetch
2
+ description: "Analyse the project: extract adapted best-practices, hunt real bugs + improvement areas, check upstream drift of derived skills, research the companion dev-toolkit MCP server against current MCP practice, draft one plan, take approval, develop, then ask whether to sync."
3
+ description-tr: "Projeyi analiz eder: uyarlanmış best-practice'leri çıkarır, gerçek bug + iyileştirme alanlarını avlar, türetilmiş skill'lerin upstream drift'ini kontrol eder, dev-toolkit MCP sunucusunu güncel MCP pratiklerine göre araştırır, tek plan taslağı çıkarır, onay alır, geliştirir, sonra sync isteyip istemediğini sorar."
4
+ allowed-tools: Read, Write, Edit, Bash, Glob, Grep, Agent, AskUserQuestion, WebFetch, WebSearch
5
5
  ---
6
6
 
7
7
  # Multi-Agent Refactor
8
8
 
9
- **One command. Best-practices + Bug hunt + Upstream drift -> Score -> Plan -> Approval -> Develop -> Sync.**
9
+ **One command. Best-practices + Bug hunt + Upstream drift + Dev-toolkit -> Score -> Plan -> Approval -> Develop -> Sync.**
10
10
 
11
- Deep-analyses the current project, extracts the global best-practices worth adopting (adapted to our stack), hunts real bugs and improvement areas, checks whether any skills we derived from an upstream source have drifted, scores everything, drafts a single prioritized plan, asks the user for approval, applies the approved items, and asks about sync at the end.
11
+ Deep-analyses the current project, extracts the global best-practices worth adopting (adapted to our stack), hunts real bugs and improvement areas, checks whether any skills we derived from an upstream source have drifted, researches the companion dev-toolkit MCP server against current MCP practice, scores everything, drafts a single prioritized plan, asks the user for approval, applies the approved items, and asks about sync at the end.
12
12
 
13
- **Input**: $ARGUMENTS (optional - area to focus on: "security", "performance", "tests", "bugs", "best-practices", "drift", etc.)
13
+ **Input**: $ARGUMENTS (optional - area to focus on: "security", "performance", "tests", "bugs", "best-practices", "drift", "dev-toolkit", etc.)
14
14
 
15
15
  ## Flow
16
16
 
17
17
  ```
18
18
  Step 0: BEST-PRACTICES Research the field, extract the best approaches, ADAPT them to our stack -> plan band A
19
19
  Step 0b: DRIFT Check upstream-derived skills for updates we have not pulled -> plan band D
20
+ Step 0c: DEV-TOOLKIT Research current MCP practice + audit the companion dev-toolkit repo -> plan band E
20
21
  Step 1: SCAN Walk the project structure (files, LOC, dependencies, CI, tests)
21
22
  Step 2: ANALYZE 10 categories + an explicit BUG HUNT (real defects, not just scores) -> plan bands B, C
22
23
  Step 3: SCORE Each category /10, overall /100
23
- Step 4: PLAN Merge bands A (best-practice) + B (bugs) + C (improvements) + D (drift), priority-ordered
24
+ Step 4: PLAN Merge bands A (best-practice) + B (bugs) + C (improvements) + D (drift) + E (dev-toolkit)
24
25
  Step 5: ASK "Start the work?" - wait for user approval
25
26
  Step 6: IMPLEMENT Apply approved items one by one (lint, test, commit)
26
27
  Step 7: VERIFY Confirm every test + lint passes
27
28
  Step 8: ASK SYNC "Run /multi-agent:sync?" - wait for user approval
28
29
  ```
29
30
 
30
- Plan bands (all four feed the single Step 4 table):
31
+ Plan bands (all five feed the single Step 4 table):
31
32
  - **A - Best-practice**: the best field approaches, adapted so they actually fit this repo.
32
33
  - **B - Bug**: real defects found in the code (correctness, security, data-loss, crashes).
33
34
  - **C - Improvement**: quality/perf/DX gaps surfaced by the 10-category analysis.
34
35
  - **D - Drift**: upstream updates to skills we derived from an external source.
36
+ - **E - Dev-toolkit**: current-practice gaps in the companion dev-toolkit MCP server (the pipeline's device and browser hands), applied in that repo.
35
37
 
36
38
  ## Step 0: BEST-PRACTICES - research the field, adapt to us
37
39
 
@@ -96,6 +98,78 @@ Procedure:
96
98
 
97
99
  5. For each drifted entry, add a band-D plan item: "port upstream <plugin> <version> changes into <localPath>", with the specific skills to update. Do not auto-apply upstream changes - they go through Step 5 approval like everything else, and after porting, bump the entry's `derivedFromVersion`.
98
100
 
101
+ ## Step 0c: DEV-TOOLKIT - current MCP practice for the companion toolkit
102
+
103
+ 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.
104
+
105
+ **Resolution** - configuration first, never a hardcoded path:
106
+
107
+ 1. `prefs.global.devToolkit` in `~/.claude/multi-agent-preferences.json`:
108
+
109
+ ```jsonc
110
+ {
111
+ "enabled": true,
112
+ "label": "<human name>",
113
+ "localPath": "$HOME/<repo-dir>", // the companion repo working copy
114
+ "mcpServerName": "<registered MCP server name>",
115
+ "packageName": "@<scope>/<package>",
116
+ "registry": "github-packages", // github-packages | npmjs | none
117
+ "repoUrl": "https://github.com/<owner>/<repo>"
118
+ }
119
+ ```
120
+
121
+ 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`.
122
+ 3. If neither resolves, skip this step and report "no dev-toolkit configured". Never guess a path, never clone.
123
+ 4. `enabled: false` skips the step.
124
+
125
+ **Research axes** - a finding without a source link is not a finding:
126
+
127
+ | # | Axis | Where to look | What to extract |
128
+ |---|------|---------------|-----------------|
129
+ | 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 |
130
+ | 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 |
131
+ | 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 |
132
+ | 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 |
133
+ | 5 | Field practice | X / Twitter, Reddit, MCP community threads | what server authors actually changed recently (transport choice, output-token diets, sandboxing, error shape) |
134
+
135
+ **Audit the toolkit against the findings** - run the checks, do not assume:
136
+
137
+ ```bash
138
+ DT="<resolved localPath>"
139
+ node --check "$DT/index.js"
140
+ find "$DT/tools" -name "*.js" -type f -exec node --check {} \;
141
+
142
+ # stdout carries the JSON-RPC frames: a stray stdout write corrupts the stream
143
+ grep -rn "console\.log(" "$DT/index.js" "$DT/tools" || echo "stdout clean"
144
+
145
+ # advertised tool counts vs reality (README header + package.json description)
146
+ grep -nE "[0-9]+ tools" "$DT/README.md" "$DT/package.json"
147
+
148
+ # packaging: every runtime directory must be inside files[]
149
+ node -p "require('$DT/package.json').files.join('\n')"
150
+ ls -d "$DT"/tools/*/
151
+
152
+ cd "$DT" && npm outdated; npm audit --omit=dev 2>/dev/null | tail -20
153
+ ```
154
+
155
+ 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.
156
+
157
+ Output (plan band E):
158
+
159
+ ```
160
+ | # | Axis | Finding | Source | Adaptation in the toolkit (file) | Effort | Impact | In plan? |
161
+ |---|------|---------|--------|----------------------------------|--------|--------|----------|
162
+ | 1 | Protocol | read-only tools carry no annotations | <spec link> | add `annotations` to the read-only tools in index.js | Low | Medium | Yes (P1) |
163
+ | 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) |
164
+ | 3 | Peer servers | peer exposes <surface> | <repo link> | does not fit: outside the pipeline's phases | - | - | No |
165
+ ```
166
+
167
+ Rules for this band:
168
+
169
+ - Band-E work lands in the toolkit repo, never mirrored into this one. Shipping it is `/multi-agent:sync` Step 3d.
170
+ - 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.
171
+ - 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.
172
+
99
173
  ## Step 1: SCAN
100
174
 
101
175
  ```
@@ -168,7 +242,7 @@ Each category is scored out of 10. Output:
168
242
 
169
243
  ## Step 4: PLAN - one merged, prioritized table
170
244
 
171
- Merge all four bands into a single plan. Tag each row with its band (A best-practice / B bug / C improvement / D drift) so the source is visible.
245
+ Merge all five bands into a single plan. Tag each row with its band (A best-practice / B bug / C improvement / D drift / E dev-toolkit) so the source is visible.
172
246
 
173
247
  ```
174
248
  | # | Priority | Band | Category | Item | Impact |
@@ -177,7 +251,8 @@ Merge all four bands into a single plan. Tag each row with its band (A best-prac
177
251
  | 2 | P0 | B | Tests | Fix nil-deref on empty response (src/y:42) | High |
178
252
  | 3 | P1 | A | CI/CD | Adopt matrix build (adapt: .github/workflows/ci.yml) | Medium |
179
253
  | 4 | P1 | D | Skills | Port upstream <plugin> 0.3.0 fixes into <localPath> | Medium |
180
- | 5 | P2 | C | DevEx | Rename npm scripts for consistency | Low |
254
+ | 5 | P1 | E | Toolkit | Add read-only annotations to the dev-toolkit device tools | Medium |
255
+ | 6 | P2 | C | DevEx | Rename npm scripts for consistency | Low |
181
256
  ```
182
257
 
183
258
  Priority levels:
@@ -189,13 +264,14 @@ Priority levels:
189
264
 
190
265
  After showing the plan, ask:
191
266
 
192
- > "Found X items (P0: N, P1: M, P2: K) across bugs, best-practices, improvements, and upstream drift. Should I start the work?"
267
+ > "Found X items (P0: N, P1: M, P2: K) across bugs, best-practices, improvements, upstream drift, and dev-toolkit practice. Should I start the work?"
193
268
 
194
269
  Options:
195
270
  - "Yes, do all"
196
271
  - "Only P0"
197
272
  - "P0 + P1 only"
198
273
  - "Only bugs (band B)"
274
+ - "Only the dev-toolkit (band E)"
199
275
  - (the user may pick specific items)
200
276
 
201
277
  **Never start the work without approval.**
@@ -206,6 +282,7 @@ Apply the approved items one by one:
206
282
 
207
283
  1. For each item:
208
284
  - apply the change (for band D, port the upstream diff into `localPath`, then bump that entry's `derivedFromVersion` in preferences)
285
+ - band-E items are applied inside the toolkit repo, never mirrored here: edit there, re-run its gates (`node --check`, the `tools/list` handshake, advertised tool count matching reality), then commit there with that repo's own convention. Publishing is `/multi-agent:sync` Step 3d - do not publish from this step.
209
286
  - run the relevant tests
210
287
  - on success, move to the next
211
288
  - on failure, roll back and notify the user
@@ -229,6 +306,8 @@ echo "Lint: PASS/FAIL"
229
306
  echo "Test: PASS/FAIL (X/Y passed)"
230
307
  ```
231
308
 
309
+ If any band-E item was applied, verify the toolkit repo too - syntax check every file it loads, handshake the server and confirm `tools/list` still answers, and confirm the advertised tool counts (README header, `package.json` description) match the count the server reports.
310
+
232
311
  ## Step 8: ASK SYNC
233
312
 
234
313
  After every approved item is applied, ask:
@@ -236,7 +315,7 @@ After every approved item is applied, ask:
236
315
  > "Work is complete. Should I run /multi-agent:sync?"
237
316
 
238
317
  Options:
239
- - "Yes" -> run the `/multi-agent:sync` command (full ecosystem sync)
318
+ - "Yes" -> run the `/multi-agent:sync` command (full ecosystem sync - its Step 3d ships any band-E work in the toolkit repo)
240
319
  - "No" -> emit a report and stop
241
320
  - "Commit + push only" -> push the current repo without sync
242
321
 
@@ -249,6 +328,7 @@ If $ARGUMENTS is set, focus on that band/category only:
249
328
  | `bugs` | Bug hunt only (band B) |
250
329
  | `best-practices` | Field research + adapted plan only (band A) |
251
330
  | `drift` | Upstream derived-skill drift only (band D) |
331
+ | `dev-toolkit` | Companion MCP toolkit research + audit only (band E) |
252
332
  | `security` | Security analysis only |
253
333
  | `tests` | Test coverage and quality only |
254
334
  | `performance` | Performance optimisation only |
@@ -192,7 +192,7 @@ When release-relevant iOS/Android files change, load the matching catalog:
192
192
 
193
193
  | Platform | Trigger files | Catalog |
194
194
  |---|---|---|
195
- | iOS | `**/Info.plist`, `**/PrivacyInfo.xcprivacy`, `**/*.entitlements`, `**/*App.swift`, `**/AppDelegate*.swift`, `**/SceneDelegate*.swift`, `**/project.pbxproj` | `pipeline/skills/shared/core/apple-archive-compliance/SKILL.md` - 17 rules + ITMS refs |
195
+ | iOS | `**/Info.plist`, `**/PrivacyInfo.xcprivacy`, `**/*.entitlements`, `**/*App.swift`, `**/AppDelegate*.swift`, `**/SceneDelegate*.swift`, `**/project.pbxproj` | `pipeline/skills/shared/core/apple-archive-compliance/SKILL.md` - 18 rules + ITMS refs |
196
196
  | Android | `**/AndroidManifest.xml`, `**/build.gradle(.kts)`, `**/proguard-rules.pro`, `**/network_security_config.xml` | `pipeline/skills/shared/core/google-play-compliance/SKILL.md` - 21 rules + Play policy refs |
197
197
 
198
198
  Each finding gets the `ruleID` from the catalog plus the platform policy ref: