@mmerterden/multi-agent-pipeline 12.5.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.
- package/CHANGELOG.md +130 -0
- package/README.md +1 -1
- package/docs/features.md +20 -0
- package/index.js +7 -1
- package/install/_dev-only-files.mjs +1 -0
- package/package.json +4 -3
- package/pipeline/agents/security-auditor.md +1 -1
- package/pipeline/commands/archive-guard.md +5 -5
- package/pipeline/commands/multi-agent/SKILL.md +2 -0
- package/pipeline/commands/multi-agent/design-check/SKILL.md +287 -0
- package/pipeline/commands/multi-agent/help/SKILL.md +45 -5
- package/pipeline/commands/multi-agent/refactor/SKILL.md +92 -12
- package/pipeline/commands/multi-agent/review/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/sync/SKILL.md +119 -12
- package/pipeline/commands/multi-agent/test/SKILL.md +1 -1
- package/pipeline/commands/sim-test.md +5 -5
- package/pipeline/lib/credential-store.sh +32 -0
- package/pipeline/multi-agent-refs/cross-cli-contract.md +3 -3
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +2 -2
- package/pipeline/multi-agent-refs/phases/phase-5-test.md +4 -4
- package/pipeline/preferences-template.json +18 -1
- package/pipeline/schemas/agent-state.schema.json +90 -0
- package/pipeline/schemas/design-check-config.schema.json +162 -0
- package/pipeline/schemas/migrations/state-2.0.0-to-2.1.0.mjs +30 -12
- package/pipeline/schemas/prefs.schema.json +161 -5
- package/pipeline/scripts/README.md +7 -5
- package/pipeline/scripts/classify-plan-safety.mjs +8 -3
- package/pipeline/scripts/cost-budget-check.mjs +9 -5
- package/pipeline/scripts/fixtures/install-layout.tsv +6 -6
- package/pipeline/scripts/learnings-ledger.mjs +18 -0
- package/pipeline/scripts/lint-mcp-refs.mjs +207 -0
- package/pipeline/scripts/memory-load.sh +5 -1
- package/pipeline/scripts/render-work-summary.sh +4 -1
- package/pipeline/scripts/smoke-command-inventory.sh +81 -0
- package/pipeline/scripts/smoke-commands-skills-parity.sh +1 -1
- package/pipeline/scripts/smoke-compliance-skills.sh +4 -4
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +12 -2
- package/pipeline/scripts/smoke-generate-issue.sh +6 -5
- package/pipeline/scripts/smoke-per-repo-memory.sh +2 -2
- package/pipeline/scripts/smoke-review-readiness.sh +3 -2
- package/pipeline/scripts/smoke-schema-validation.sh +19 -5
- package/pipeline/scripts/smoke-shadow-git.sh +4 -2
- package/pipeline/scripts/triage-memory.mjs +18 -0
- package/pipeline/scripts/uninstall.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +24 -8
- package/pipeline/skills/.skills-index.json +39 -3
- package/pipeline/skills/shared/README.md +10 -6
- package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +10 -8
- package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +248 -0
- package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +22 -0
- package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +67 -11
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +51 -9
- package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +1 -1
- package/pipeline/skills/skills-index.md +8 -4
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: multi-agent-design-check
|
|
3
|
+
language: en
|
|
4
|
+
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."
|
|
5
|
+
user-invocable: true
|
|
6
|
+
argument-hint: '[scope] - empty = whole module; screen name; screen@variant; Figma URL(s); --resume'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# multi-agent-design-check - Mock-mode vs Figma design audit
|
|
10
|
+
|
|
11
|
+
Local, on-device design-conformance auditor. 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.
|
|
12
|
+
|
|
13
|
+
**Local-only**: no CI/CD, no cron, no commits, no PR. Read-only audit; writes a report to `~/DesignChecks/`. The worktree only isolates the Debug build.
|
|
14
|
+
|
|
15
|
+
> **Language**: `promptLanguage=en` always (this spec stays English). `outputLanguage` applies to conversational lines and the human-readable report - pass it to `design_report` as `report.lang` (engine defaults to English, ships `en` + `tr` packs, per-key `report.labels` overrides). `ask_choice` labels/headers, branch names, paths, code identifiers stay English.
|
|
16
|
+
|
|
17
|
+
## Scope - `$ARGUMENTS`
|
|
18
|
+
|
|
19
|
+
The scope decides which **inventory targets** (Phase 0 step 5) the run must audit. It never changes how thoroughly each target is audited.
|
|
20
|
+
|
|
21
|
+
| Form | Example | Scope |
|
|
22
|
+
|------|---------|-------|
|
|
23
|
+
| empty / `module` | (no argument) | Every target in the module's inventory |
|
|
24
|
+
| screen name | `boarding-pass` | Every target whose `screen` matches (case/separator-insensitive) |
|
|
25
|
+
| `screen@variant` | `boarding-pass@expired` | One target |
|
|
26
|
+
| target id | `scenario-case:boardingpassoutcome-expired` | One target, exactly |
|
|
27
|
+
| Figma URL(s) | `https://figma.com/design/…?node-id=1-2` | Only the frames those URLs name |
|
|
28
|
+
| `--resume` | `--resume` | The unaudited remainder of the most recent run for this repo + module |
|
|
29
|
+
| combinations | `seat-map summary@semi-success` | Union of the above, space- or newline-separated |
|
|
30
|
+
|
|
31
|
+
A scope matching **no** inventory target is an error, not an empty run: print the closest inventory ids and halt.
|
|
32
|
+
|
|
33
|
+
**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** set, so a deliberate scoped run is never penalised for out-of-scope targets, and `--resume` closes the remainder.
|
|
34
|
+
|
|
35
|
+
## Pipeline
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
Phase 0: Init & Gate → repo + module picker, platform detect, MOCK FEASIBILITY GATE, SCENARIO INVENTORY, scope resolve, report dir, worktree
|
|
39
|
+
Phase 1: Build & Launch → Debug build in worktree, boot device, install, launch in mock mode
|
|
40
|
+
Phase 2: Figma → fetch module frame tree, enumerate + map variants (ask when ambiguous)
|
|
41
|
+
Phase 3: Drive & Compare → per plan batch: one launch → capture + flip in-app states → match → batch-ask → compare
|
|
42
|
+
Phase 4: Report → coverage gate + assemble + export HTML + PDF (+ Confluence) to ~/DesignChecks/
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
- **iOS**: Xcode + Simulator. **Android**: Android SDK + emulator / device.
|
|
48
|
+
- **MCP**: `dev-toolkit` (>= 2.8.0, for `design_scenario_inventory`, the `design_report` coverage gate, and `design_visual_compare` region alignment) + an authenticated Figma MCP (`mcp__claude_ai_Figma__*`).
|
|
49
|
+
- The selected module must support a mock mode (Phase 0 gate). No mock support → halt.
|
|
50
|
+
|
|
51
|
+
## Phase Tracker (mandatory)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bash $HOME/.copilot/scripts/phase-tracker.sh init "$TASK_ID"
|
|
55
|
+
for p in "0:Init & Gate" "1:Build & Launch" "2:Figma" "3:Drive & Compare" "4:Report"; do
|
|
56
|
+
bash $HOME/.copilot/scripts/phase-tracker.sh add "${p%%:*}" "${p#*:}"
|
|
57
|
+
done
|
|
58
|
+
```
|
|
59
|
+
Copilot / plain shell has no TaskList widget - after every state change call `phase-tracker.sh render` (prints a bordered ANSI card). Do NOT call TaskCreate here.
|
|
60
|
+
|
|
61
|
+
## STOP-AND-CONFIRM
|
|
62
|
+
|
|
63
|
+
Every Phase 0 / Phase 2 decision uses the `ask_choice` picker (`$HOME/.copilot/lib/ask-choice.sh`). Print a `Step <i>/<n>: <what it decides>` breadcrumb first. Confirmation required even with one option; state inheritance from a previous run is FORBIDDEN.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Phase 0 - Init, Feasibility Gate & Inventory
|
|
68
|
+
|
|
69
|
+
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 bound to a process that started before the last update keeps serving the OLD tool list while still reporting "connected". Finding that out after a Debug build and a device drive wastes the run and yields a report missing the checks this spec depends on.
|
|
70
|
+
|
|
71
|
+
Assert both halves:
|
|
72
|
+
|
|
73
|
+
a. **Session** - `mcp__dev-toolkit__design_scenario_inventory` must be callable and `mcp__dev-toolkit__design_visual_compare` must accept `live_region`. Absent → the session holds a stale process.
|
|
74
|
+
|
|
75
|
+
b. **Disk** - probe the configured server, which reports what a fresh connection WOULD serve:
|
|
76
|
+
```bash
|
|
77
|
+
printf '%s\n%s\n' \
|
|
78
|
+
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' \
|
|
79
|
+
'{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
|
|
80
|
+
| node "<dev-toolkit path>/index.js" 2>/dev/null | python3 -c "
|
|
81
|
+
import sys,json
|
|
82
|
+
for l in sys.stdin:
|
|
83
|
+
try: m=json.loads(l)
|
|
84
|
+
except: continue
|
|
85
|
+
if m.get('id')==1: print('version', m['result']['serverInfo']['version'])
|
|
86
|
+
if m.get('id')==2:
|
|
87
|
+
n=[t['name'] for t in m['result']['tools']]
|
|
88
|
+
print('tools', len(n), 'inventory', 'design_scenario_inventory' in n)"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- **disk OK, session missing the tool** → **HALT**; the user must reconnect the MCP server (a stale build advertises one fewer `design_*` tool, which is the quickest tell). If a reconnect does not take, lingering server processes are the usual cause - compare `ps -o lstart=` start times against the code's mtime.
|
|
92
|
+
- **disk stale** → **HALT**; the checkout needs updating first.
|
|
93
|
+
- **both current** → continue.
|
|
94
|
+
|
|
95
|
+
Never substitute a local `node` call for a missing tool: the run would silently lose the coverage gate and region alignment, which is the exact failure this gate prevents.
|
|
96
|
+
|
|
97
|
+
1. **Repo picker** - `$HOME/.copilot/multi-agent-refs/_repo-picker.md`. Account picker skipped (Figma token user-supplied) unless Confluence export needs a token.
|
|
98
|
+
2. **Module picker** - `$HOME/.copilot/multi-agent-refs/_dev-context.md` (auto-suggest `.gitmodules` via `submodule-detector.sh`). Pick the module to audit (multi-module = audit each independently).
|
|
99
|
+
3. **Platform detect** - `.xcodeproj`/`Package.swift`→iOS, `build.gradle*`→Android. Persist `state.platform`.
|
|
100
|
+
4. **MOCK FEASIBILITY GATE** on the module path:
|
|
101
|
+
```
|
|
102
|
+
mcp__dev-toolkit__design_mock_detect({ repo_path, platform, extra_keys })
|
|
103
|
+
```
|
|
104
|
+
(`extra_keys` from `config mock.keys`.)
|
|
105
|
+
- `false` → **HALT** with `reason`; the module cannot be audited. Never fabricate a comparison.
|
|
106
|
+
- `"debug-only"` → warn via ask_choice (variants can't be toggled at launch; only default Debug state comparable), Continue / Cancel.
|
|
107
|
+
- `true` → persist `state.designCheck.mock` (mechanism, activation, variantsHint, evidence).
|
|
108
|
+
5. **SCENARIO INVENTORY (this is the audit's target set)**:
|
|
109
|
+
```
|
|
110
|
+
mcp__dev-toolkit__design_scenario_inventory({ repo_path, platform,
|
|
111
|
+
extra_launch_args: <config inventory.extraLaunchArgs>,
|
|
112
|
+
extra_targets: <config inventory.extraTargets>,
|
|
113
|
+
ignore_targets: <config inventory.ignoreTargets> })
|
|
114
|
+
```
|
|
115
|
+
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`.
|
|
116
|
+
|
|
117
|
+
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`.
|
|
118
|
+
- `targetCount: 0` → warn that only the default launch state is auditable (a `debug-only` project legitimately lands here).
|
|
119
|
+
- `truncated: true` → the target set is INCOMPLETE. Say so now and pass `coverage.truncatedInventory: true` in Phase 4 so the gate fails instead of reporting a clean percentage of a partial denominator; narrow to a screen and work through the module in `--resume` steps.
|
|
120
|
+
- `ignored[]` non-empty → list what the config dropped, so a stale `ignoreTargets` cannot quietly shrink the audit.
|
|
121
|
+
6. **Scope resolve** - intersect `$ARGUMENTS` with `inventory.targets`; persist `state.designCheck.scope = { argument, targetIds[] }`.
|
|
122
|
+
|
|
123
|
+
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. **Whole-module is the intended default**; ask_choice only when `relaunchCount` exceeds `config coverage.confirmAbove` (default 25), phrased as a cost estimate rather than an invitation to shrink the audit. Never offer a smaller scope as the easy path.
|
|
124
|
+
7. **`--resume`** - read the most recent `~/DesignChecks/{repo}__{module}/*/run-state.json`; scope becomes that run's targets minus `covered` minus `skipped`. No previous run → say so and fall back to whole-module scope after confirmation.
|
|
125
|
+
8. **Report dir** - create `~/DesignChecks/{repo}__{module}/{UTC-timestamp}/` (plus `assets/`) now and persist as `state.designCheck.reportDir`. Phase 3 writes captures, comparison images, and `run-state.json` into it, so it must exist before driving starts.
|
|
126
|
+
9. **Worktree** - `{projectRoot}/{worktreeBasePath}/{taskId}` (default `.worktrees/DC-<shortId>`), never under $HOME. Prune stale locks + add `.worktrees/` to `.git/info/exclude` first.
|
|
127
|
+
|
|
128
|
+
Persist `agent-state.json` (`mode: "design-check"`, platform, projectRoot, worktreePath, module, designCheck).
|
|
129
|
+
|
|
130
|
+
## Phase 1 - Build & Launch (mock)
|
|
131
|
+
|
|
132
|
+
1. **Debug build** in the worktree: iOS `mcp__dev-toolkit__ios_xcodebuild({ scheme, configuration: "Debug", action: "build" })`; Android `./gradlew :<module>:assembleDebug`.
|
|
133
|
+
2. **Boot + install**: iOS list/boot device + `xcrun simctl install`; Android running emulator + `adb install -r`.
|
|
134
|
+
3. **Deterministic state**: iOS `ios_status_bar({ preset: "clean" })`; fix appearance + locale.
|
|
135
|
+
4. **Launch mock**: `mcp__dev-toolkit__design_mock_launch({ platform, bundle_id|package_name, launch_arg|intent_extra })` from Phase 0 activation. `debug-only` → just launch the Debug build. The build is installed once; Phase 3 relaunches it per target rather than rebuilding.
|
|
136
|
+
|
|
137
|
+
## Phase 2 - Figma fetch & variant mapping (module-scoped)
|
|
138
|
+
|
|
139
|
+
Figma **discovery** happens only here: the frame tree is fetched once and no later phase browses Figma for candidates. Phase 3 may fetch a specific node the user hands over in the 3.3 batch-ask - a targeted fetch of an already-identified frame, and the only Figma call allowed after this phase.
|
|
140
|
+
|
|
141
|
+
1. Resolve the Figma URL (`$ARGUMENTS` or ask). Parse `fileKey` + `nodeId` (`-`→`:`).
|
|
142
|
+
2. `mcp__claude_ai_Figma__get_metadata` → frame tree; direct child frames = candidate variants.
|
|
143
|
+
3. Map each scoped target's `screen` + `label` (and `variantsHint`) → frames by similarity. Ambiguous/unmatched → deferred to the Phase 3.3 batch-ask (where the live capture can be shown); never guess. `debug-only` → single default variant.
|
|
144
|
+
4. Per variant: `get_screenshot` (design PNG) + `get_design_context` (bbox, itemSpacing, paddings, fontSize/fontFamily, fills, CodeConnect name). Flatten to `figma_spec`; record `figmaFrame` size.
|
|
145
|
+
|
|
146
|
+
Persist `state.designCheck.variants[]`.
|
|
147
|
+
|
|
148
|
+
## Phase 3 - Drive every scoped target → capture → match → batch-ask → compare
|
|
149
|
+
|
|
150
|
+
**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 needing a different launch argument, scenario case, or typed scenario code - which is exactly how a module's error / edge states go missing.
|
|
151
|
+
|
|
152
|
+
### 3.1 Drive the inventory's plan, batch by batch
|
|
153
|
+
|
|
154
|
+
**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 screen is flipped while the app is already 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.
|
|
155
|
+
|
|
156
|
+
Per batch: launch once with the batch's `launch` driver (or the plain mock activation for `(default launch)`) → navigate → capture the relaunch target → for each in-app target, flip its selector, let the screen re-render, capture. **No relaunch between in-app targets.**
|
|
157
|
+
|
|
158
|
+
Per-target activation by `driver.type`:
|
|
159
|
+
|
|
160
|
+
| `driver.type` | Activation |
|
|
161
|
+
|---|---|
|
|
162
|
+
| `launch-arg` | `design_mock_launch({ launch_arg: "<mock activation> <driver.launchArg>" })` - the mock switch AND the target's flag together |
|
|
163
|
+
| `intent-extra` | `design_mock_launch({ intent_extra: "<mock extra> <driver.intentExtra>" })` |
|
|
164
|
+
| `scenario` | Set `driver.enum` to `driver.case` through the build's debug scenario picker, then drive the flow that consumes it |
|
|
165
|
+
| `code` (from `prefix-code`) | Type a reference beginning with `driver.code` at the entry field, then walk to `driver.appliesTo`. The prefix decides which fixture the mock repository returns - this is how most per-screen variants are reached |
|
|
166
|
+
| `code` (from `code-scenario`) | Same entry field, flow-wide code not owned by one screen |
|
|
167
|
+
| `fixture` | Activate the launch arg / scenario that reads `driver.file`; when nothing does → skip with reason "fixture not reachable from any driver" |
|
|
168
|
+
| `deep-link` | `ios_open_url` / `android_open_url` with `driver.url` |
|
|
169
|
+
| `manual` | Config-declared: follow the config's note, or skip with that note as the reason |
|
|
170
|
+
|
|
171
|
+
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 (`<id>#<sub-label>`).
|
|
172
|
+
|
|
173
|
+
Per capture: `ios_screenshot`/`android_screenshot` (save PNG into the Phase 0 report dir) + `mcp__dev-toolkit__design_ui_geometry` → append to `state.designCheck.captured[]` with the target id and a human label. **Persist `state` and `run-state.json` after every capture** so a dying run resumes from where it stopped.
|
|
174
|
+
|
|
175
|
+
Unreachable target → record `{ 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 describes the work, and the work is this phase's job.
|
|
176
|
+
|
|
177
|
+
### 3.2 Match each capture → Figma frame (auto)
|
|
178
|
+
|
|
179
|
+
Resolve each captured screen's frame from the Phase 2 tree; match by structure/content; accept only a **confident** match → `pairs[]`.
|
|
180
|
+
|
|
181
|
+
### 3.3 Batch-ask the user for EVERYTHING unmatched (ONE prompt, WITH the visual)
|
|
182
|
+
|
|
183
|
+
Collect ALL unmatched captures into a single list and ask ONCE - never guess, never show a wrong frame. **Show each unmatched screen's captured screenshot** (attach the PNG), name the screen, ask for the Figma node-id / URL in `outputLanguage`, optionally list best-guess candidates. Each answer becomes a confirmed pair; a declined screen is a skip with reason "no Figma frame supplied".
|
|
184
|
+
|
|
185
|
+
### 3.4 Compare ALL pairs in one pass
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
mcp__dev-toolkit__design_visual_compare({ figma_png, live_png, out_dir, label,
|
|
189
|
+
figma_spec, live_geometry, figma_frame, live_screen,
|
|
190
|
+
crop_top_live, tolerance_px: 2, color_tolerance: 3, max_diff_pct: 1.0 })
|
|
191
|
+
```
|
|
192
|
+
Collect findings (spacing/size/position px, color ΔE hex, typography), perceptualPct, images.
|
|
193
|
+
|
|
194
|
+
**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, misplacing every element inside the sheet and burying the real defect in noise. For any capture whose frame is not full-screen add:
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
live_region: <the sheet container's {x,y,w,h} from design_ui_geometry>,
|
|
198
|
+
expected_region: <where the design puts that sheet, same units>
|
|
199
|
+
```
|
|
200
|
+
- `live_region` rebases the comparison onto the sheet's own box - read it from the `design_ui_geometry` element that IS the sheet container, never from a guess.
|
|
201
|
+
- `expected_region` comes from the Figma frame's placement inside its parent screen frame; with it the engine emits an `inset` finding per edge.
|
|
202
|
+
- `crop_top_live` is ignored when `live_region` is given (the region crop already excluded chrome).
|
|
203
|
+
|
|
204
|
+
**Edge insets are defects, not tolerances.** A design showing 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" and never raise `tolerance_px` to make one disappear. The sheet's internal content padding is measured by the normal element pairing once the region alignment is right.
|
|
205
|
+
|
|
206
|
+
**Component reference** (best-effort): Code Connect atom → attach matching `*.figma.swift`/`*.figma.kt` component render.
|
|
207
|
+
**Fix prompt**: compose a paste-ready developer prompt from the findings.
|
|
208
|
+
|
|
209
|
+
### 3.5 Close the ledger
|
|
210
|
+
|
|
211
|
+
Every scoped target id ends in exactly one bucket: **covered** (captured AND compared) or **skipped** (with a concrete reason from 3.1 / 3.3). Write `run-state.json` into the Phase 0 report dir with `{ targetIds, covered, skipped }` so `--resume` can pick up the remainder.
|
|
212
|
+
|
|
213
|
+
Before leaving this phase, compare `covered.length + skipped.length` against `scope.targetIds.length`. A mismatch 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 is the worst of both worlds: the work is undone AND the run is marked incomplete.
|
|
214
|
+
|
|
215
|
+
## Phase 4 - Report, coverage gate & export
|
|
216
|
+
|
|
217
|
+
1. Output dir: `state.designCheck.reportDir`, already created in Phase 0, holding Phase 3's captures and comparison images. Do not mint a second timestamped dir.
|
|
218
|
+
2. Assemble the report object:
|
|
219
|
+
```
|
|
220
|
+
{ project, module, platform, figmaUrl, figmaFileKey, timestamp, lang: <outputLanguage>,
|
|
221
|
+
coverage: { targets: <scoped target ids/objects>, covered: <audited ids>,
|
|
222
|
+
skipped: [{ id, group, reason }],
|
|
223
|
+
truncatedInventory: <inventory.truncated>,
|
|
224
|
+
floor: <config coverage.floor, optional> },
|
|
225
|
+
variants: [{ name, figmaNodeId, perceptualPct, passed, compareSize, liveSize,
|
|
226
|
+
images, findings, fixPrompt, componentRefs }] }
|
|
227
|
+
```
|
|
228
|
+
Pass **ids**, not counts: the engine then names each unaccounted target instead of printing an anonymous tally. `compareSize` / `liveSize` come straight from the `design_visual_compare` result.
|
|
229
|
+
3. Export:
|
|
230
|
+
```
|
|
231
|
+
mcp__dev-toolkit__design_report({ report, out_dir: state.designCheck.reportDir,
|
|
232
|
+
formats: ["html","pdf"] (+ "confluence" if enabled) })
|
|
233
|
+
```
|
|
234
|
+
HTML self-contained with the gate banner on top; PDF via Playwright (reports `pdfError` if unavailable); Confluence only if enabled (reuse `multi-agent-channels` adapter), else graceful skip.
|
|
235
|
+
4. **COVERAGE GATE (blocking, not advisory)** - read `coverage` from the tool result and persist to `state.designCheck.coverage`:
|
|
236
|
+
- `gate: "pass"` → print per-variant PASS/FAIL + findings + report paths.
|
|
237
|
+
- `gate: "fail"` → the run is **INCOMPLETE**. Print `coverageError`, the `unaccountedIds`, and the command that closes the gap (`--resume`). Do not present an incomplete audit as finished, and never pad the covered list to make the gate pass.
|
|
238
|
+
|
|
239
|
+
The gate is a last line of defence, not the plan. If it fires, Phase 3 left work undone - drive the missing targets, then report.
|
|
240
|
+
5. Remove the worktree unless asked to keep it. The report dir is never removed.
|
|
241
|
+
|
|
242
|
+
## Notes
|
|
243
|
+
|
|
244
|
+
- Feasibility is real - report honestly and stop when a module has no mock support; never fabricate a partial comparison.
|
|
245
|
+
- **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.
|
|
246
|
+
- **Chunk with scope, not with silence**: a 50-target module is a legitimate multi-run job. Scope it, close each run's gate, let `--resume` carry the remainder.
|
|
247
|
+
- "Pixel perfect" is perceptual + geometric (scale normalized, chrome cropped); deltas reported in px/pt/hex with a tolerance.
|
|
248
|
+
- The `design_*` engine is generic; project specifics (mock keys, extra launch args / targets, node overrides, status-bar crop, coverage floor, Confluence toggle) come from `design-check-config.json` / prefs, never hardcoded.
|
|
@@ -128,6 +128,17 @@ Manual Test (Phase 5 standalone - Xcode hint flow):
|
|
|
128
128
|
/multi-agent:manual-test [#N] Checkout task branch, print Xcode/SourceTree hints.
|
|
129
129
|
(Renamed from :test in v5.7.4.)
|
|
130
130
|
|
|
131
|
+
Design Check (mock-mode vs Figma, local-only - dev-toolkit-mcp design_* tools):
|
|
132
|
+
|
|
133
|
+
/multi-agent:design-check Whole-module design audit: enumerate every state driver into a target set,
|
|
134
|
+
/multi-agent:design-check <scope> drive each one in mock mode via idb, compare vs Figma (padding/width/spacing/
|
|
135
|
+
/multi-agent:design-check --resume font/color/component/localization), export HTML+PDF to ~/DesignChecks.
|
|
136
|
+
Scope: empty=module / screen / screen@variant / target-id / Figma URL(s).
|
|
137
|
+
COVERAGE GATE: a target is audited or skipped WITH a reason, else the run
|
|
138
|
+
is reported INCOMPLETE. --resume covers the remainder of the last run.
|
|
139
|
+
Unresolved frame → shows you the screenshot and asks for the node-id.
|
|
140
|
+
Drives dev-toolkit design_* : design_mock_detect / _scenario_inventory / _mock_launch / _ui_geometry / _visual_compare / _report.
|
|
141
|
+
|
|
131
142
|
------------------------------------------------------------
|
|
132
143
|
|
|
133
144
|
Setup:
|
|
@@ -266,6 +277,17 @@ Manuel Test (Phase 5 standalone - Xcode hint akışı):
|
|
|
266
277
|
/multi-agent:manual-test [#N] Task branch'ine checkout, Xcode/SourceTree hint basar.
|
|
267
278
|
(v5.7.4'te :test'ten :manual-test'e rename.)
|
|
268
279
|
|
|
280
|
+
Design Check (mock-mod vs Figma, yalnızca lokal - dev-toolkit-mcp design_* tool'ları):
|
|
281
|
+
|
|
282
|
+
/multi-agent:design-check Tüm modül tasarım denetimi: her state sürücüsünü hedef kümesine çıkar,
|
|
283
|
+
/multi-agent:design-check <scope> her birini mock modda idb ile sür, Figma ile karşılaştır (padding/genişlik/
|
|
284
|
+
/multi-agent:design-check --resume spacing/font/renk/component/localization), HTML+PDF rapor ~/DesignChecks.
|
|
285
|
+
Kapsam: boş=modül / ekran / ekran@varyant / target-id / Figma URL(leri).
|
|
286
|
+
KAPSAM GEÇİDİ: hedef ya denetlenir ya da GEREKÇEYLE atlanır; aksi hâlde
|
|
287
|
+
koşu EKSİK raporlanır. --resume son koşunun kalanını kapatır.
|
|
288
|
+
Figma karşılığı bulunamazsa SANA screenshot'ı gösterip node-id sorar.
|
|
289
|
+
Sürdüğü dev-toolkit design_* : design_mock_detect / _scenario_inventory / _mock_launch / _ui_geometry / _visual_compare / _report.
|
|
290
|
+
|
|
269
291
|
------------------------------------------------------------
|
|
270
292
|
|
|
271
293
|
Setup:
|
|
@@ -1,39 +1,41 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: multi-agent-refactor
|
|
3
3
|
language: en
|
|
4
|
-
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."
|
|
4
|
+
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."
|
|
5
5
|
user-invocable: true
|
|
6
|
-
argument-hint: 'bugs | best-practices | drift | security | tests | performance | docs | ci | deps'
|
|
6
|
+
argument-hint: 'bugs | best-practices | drift | dev-toolkit | security | tests | performance | docs | ci | deps'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Multi-Agent Refactor
|
|
10
10
|
|
|
11
|
-
**One command. Best-practices + Bug hunt + Upstream drift -> Score -> Plan -> Approval -> Develop -> Sync.**
|
|
11
|
+
**One command. Best-practices + Bug hunt + Upstream drift + Dev-toolkit -> Score -> Plan -> Approval -> Develop -> Sync.**
|
|
12
12
|
|
|
13
|
-
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, takes approval, applies the approved items, and asks about sync when done.
|
|
13
|
+
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, takes approval, applies the approved items, and asks about sync when done.
|
|
14
14
|
|
|
15
|
-
**Input**: $ARGUMENTS (optional - area to focus on: "security", "performance", "tests", "bugs", "best-practices", "drift", etc.)
|
|
15
|
+
**Input**: $ARGUMENTS (optional - area to focus on: "security", "performance", "tests", "bugs", "best-practices", "drift", "dev-toolkit", etc.)
|
|
16
16
|
|
|
17
17
|
## Flow
|
|
18
18
|
|
|
19
19
|
```
|
|
20
20
|
Step 0: BEST-PRACTICES Research the field, extract the best approaches, ADAPT them to our stack -> plan band A
|
|
21
21
|
Step 0b: DRIFT Check upstream-derived skills for updates we have not pulled -> plan band D
|
|
22
|
+
Step 0c: DEV-TOOLKIT Research current MCP practice + audit the companion dev-toolkit repo -> plan band E
|
|
22
23
|
Step 1: SCAN Scan the project structure (files, LOC, dependencies, CI, tests)
|
|
23
24
|
Step 2: ANALYZE 10 categories + an explicit BUG HUNT (real defects, not just scores) -> plan bands B, C
|
|
24
25
|
Step 3: SCORE Each category out of 10, total /100
|
|
25
|
-
Step 4: PLAN Merge bands A (best-practice) + B (bugs) + C (improvements) + D (drift)
|
|
26
|
+
Step 4: PLAN Merge bands A (best-practice) + B (bugs) + C (improvements) + D (drift) + E (dev-toolkit)
|
|
26
27
|
Step 5: ASK "Shall I start developing?" - take approval
|
|
27
28
|
Step 6: IMPLEMENT Apply approved items in order (lint, test, commit)
|
|
28
29
|
Step 7: VERIFY Confirm all tests + lint pass
|
|
29
30
|
Step 8: ASK SYNC "Shall I run multi-agent-sync?" - take approval
|
|
30
31
|
```
|
|
31
32
|
|
|
32
|
-
Plan bands (all
|
|
33
|
+
Plan bands (all five feed the single Step 4 table):
|
|
33
34
|
- **A - Best-practice**: the best field approaches, adapted so they actually fit this repo.
|
|
34
35
|
- **B - Bug**: real defects found in the code (correctness, security, data-loss, crashes).
|
|
35
36
|
- **C - Improvement**: quality/perf/DX gaps surfaced by the 10-category analysis.
|
|
36
37
|
- **D - Drift**: upstream updates to skills we derived from an external source.
|
|
38
|
+
- **E - Dev-toolkit**: current-practice gaps in the companion dev-toolkit MCP server (the pipeline's device and browser hands), applied in that repo.
|
|
37
39
|
|
|
38
40
|
## Step 0: BEST-PRACTICES - research the field, adapt to us
|
|
39
41
|
|
|
@@ -94,6 +96,54 @@ Procedure:
|
|
|
94
96
|
|
|
95
97
|
5. For each drifted entry, add a band-D plan item: "port upstream <plugin> <version> changes into <localPath>". Do not auto-apply - it goes through Step 5 approval; after porting, bump the entry's `derivedFromVersion`.
|
|
96
98
|
|
|
99
|
+
## Step 0c: DEV-TOOLKIT - current MCP practice for the companion toolkit
|
|
100
|
+
|
|
101
|
+
The pipeline's device and browser hands are MCP tools served by a companion repo (`dev-toolkit-mcp`), and several pipeline skills declare a minimum toolkit version. This step researches current MCP practice and audits that repo against it.
|
|
102
|
+
|
|
103
|
+
**Resolution** - configuration first, never a hardcoded path:
|
|
104
|
+
|
|
105
|
+
1. `prefs.global.devToolkit`: `{ enabled, label, localPath, mcpServerName, packageName, registry, repoUrl }`.
|
|
106
|
+
2. If unset, auto-detect from the MCP registration: `mcpServers` in `~/.claude.json` (plus `projects[*].mcpServers`) and `~/.claude/settings.json`; for a stdio `node` entry take `dirname(args[0])`, and accept it only if that directory is a git repo whose `package.json` depends on `@modelcontextprotocol/sdk`.
|
|
107
|
+
3. Neither resolves (or `enabled: false`) -> skip and report "no dev-toolkit configured". Never guess a path, never clone.
|
|
108
|
+
|
|
109
|
+
**Research axes** - a finding without a source link is not a finding:
|
|
110
|
+
|
|
111
|
+
| # | Axis | Where to look | What to extract |
|
|
112
|
+
|---|------|---------------|-----------------|
|
|
113
|
+
| 1 | MCP protocol | spec revisions + `@modelcontextprotocol/sdk` releases | features released since the pinned SDK that the server does not use: tool annotations, `outputSchema` + structured content, resource links, progress + cancellation, `tools/list_changed`, pagination |
|
|
114
|
+
| 2 | Host clients | Claude Code / Copilot CLI / Cursor / Antigravity docs | description budget, tool-count ceilings, naming, output size limits, permission ergonomics |
|
|
115
|
+
| 3 | Peer servers | GitHub search on the same domain + `stars:>50` | surfaces we lack, conventions peers converged on, what to discard |
|
|
116
|
+
| 4 | Wrapped tooling | `simctl`, `idb`, `adb`, `xcodebuild`, Playwright notes, Apple ITMS + review guidelines | deprecated flags in use, new capabilities worth a tool, audit rules that changed |
|
|
117
|
+
| 5 | Field practice | X / Twitter, Reddit, MCP community | what server authors changed recently (transport, output-token diets, error shape) |
|
|
118
|
+
|
|
119
|
+
**Audit the toolkit** - run the checks, do not assume:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
DT="<resolved localPath>"
|
|
123
|
+
node --check "$DT/index.js"; find "$DT/tools" -name "*.js" -exec node --check {} \;
|
|
124
|
+
grep -rn "console\.log(" "$DT/index.js" "$DT/tools" || echo "stdout clean" # stdout = JSON-RPC channel
|
|
125
|
+
grep -nE "[0-9]+ tools" "$DT/README.md" "$DT/package.json" # advertised count vs reality
|
|
126
|
+
node -p "require('$DT/package.json').files.join('\n')"; ls -d "$DT"/tools/*/ # files[] covers runtime dirs
|
|
127
|
+
cd "$DT" && npm outdated; npm audit --omit=dev 2>/dev/null | tail -20
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Also check: every tool has a description + `inputSchema`; token-heavy results (screenshots, UI trees) are truncated or file-backed; failures return an error result, not a throw; `CHANGELOG.md`, CI and tests exist.
|
|
131
|
+
|
|
132
|
+
Output (plan band E):
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
| # | Axis | Finding | Source | Adaptation in the toolkit (file) | Effort | Impact | In plan? |
|
|
136
|
+
|---|------|---------|--------|----------------------------------|--------|--------|----------|
|
|
137
|
+
| 1 | Protocol | read-only tools carry no annotations | <spec link> | add `annotations` to the read-only tools in index.js | Low | Medium | Yes (P1) |
|
|
138
|
+
| 2 | Peer servers | peer exposes <surface> | <repo link> | does not fit: outside the pipeline's phases | - | - | No |
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Rules for this band:
|
|
142
|
+
|
|
143
|
+
- Band-E work lands in the toolkit repo, never mirrored into this one. Shipping it is `multi-agent-sync` Step 3d.
|
|
144
|
+
- A finding that changes the tool surface pairs with a pipeline-side item: bump the minimum toolkit version wherever a pipeline skill declares one.
|
|
145
|
+
- If the current working directory IS the toolkit repo, skip band E and let bands A/B/C cover it.
|
|
146
|
+
|
|
97
147
|
## Step 1: SCAN
|
|
98
148
|
|
|
99
149
|
```
|
|
@@ -166,7 +216,7 @@ Each category is scored out of 10. Output format:
|
|
|
166
216
|
|
|
167
217
|
## Step 4: PLAN - one merged, prioritized table
|
|
168
218
|
|
|
169
|
-
Merge all
|
|
219
|
+
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).
|
|
170
220
|
|
|
171
221
|
```
|
|
172
222
|
| # | Priority | Band | Category | Item | Impact |
|
|
@@ -175,7 +225,8 @@ Merge all four bands into a single plan. Tag each row with its band (A best-prac
|
|
|
175
225
|
| 2 | P0 | B | Testing | Fix nil-deref on empty response (src/y:42) | High |
|
|
176
226
|
| 3 | P1 | A | CI/CD | Adopt matrix build (adapt: .github/workflows/ci.yml) | Medium |
|
|
177
227
|
| 4 | P1 | D | Skills | Port upstream <plugin> 0.3.0 fixes into <localPath> | Medium |
|
|
178
|
-
| 5 |
|
|
228
|
+
| 5 | P1 | E | Toolkit | Add read-only annotations to the dev-toolkit device tools | Medium |
|
|
229
|
+
| 6 | P2 | C | DevEx | Rename npm scripts for consistency | Low |
|
|
179
230
|
```
|
|
180
231
|
|
|
181
232
|
Priority levels:
|
|
@@ -187,13 +238,14 @@ Priority levels:
|
|
|
187
238
|
|
|
188
239
|
After showing the plan, ask:
|
|
189
240
|
|
|
190
|
-
> "I found X items (P0: N, P1: M, P2: K) across bugs, best-practices, improvements, and
|
|
241
|
+
> "I found X items (P0: N, P1: M, P2: K) across bugs, best-practices, improvements, upstream drift, and dev-toolkit practice. Shall I start developing?"
|
|
191
242
|
|
|
192
243
|
Options:
|
|
193
244
|
- "Yes, do all of them"
|
|
194
245
|
- "Do only the P0 ones"
|
|
195
246
|
- "Do only P0 + P1"
|
|
196
247
|
- "Only the bugs (band B)"
|
|
248
|
+
- "Only the dev-toolkit (band E)"
|
|
197
249
|
- (the user can make a specific selection)
|
|
198
250
|
|
|
199
251
|
**NEVER start developing without approval.**
|
|
@@ -204,6 +256,7 @@ Apply approved items in order:
|
|
|
204
256
|
|
|
205
257
|
1. For each item:
|
|
206
258
|
- Make the change (for band D, port the upstream diff into `localPath`, then bump that entry's `derivedFromVersion`)
|
|
259
|
+
- Band-E items are applied inside the toolkit repo, never mirrored here: edit there, re-run its gates (`node --check`, `tools/list` handshake, advertised tool count matching reality), commit there. Publishing is `multi-agent-sync` Step 3d.
|
|
207
260
|
- Run the relevant tests
|
|
208
261
|
- If successful, move to the next
|
|
209
262
|
- If it fails, revert and notify the user
|
|
@@ -227,6 +280,8 @@ echo "Lint: PASS/FAIL"
|
|
|
227
280
|
echo "Test: PASS/FAIL (X/Y passed)"
|
|
228
281
|
```
|
|
229
282
|
|
|
283
|
+
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 match the count the server reports.
|
|
284
|
+
|
|
230
285
|
## Step 8: ASK SYNC
|
|
231
286
|
|
|
232
287
|
After all approved items are applied, ask:
|
|
@@ -234,7 +289,7 @@ After all approved items are applied, ask:
|
|
|
234
289
|
> "Development complete. Shall I run multi-agent-sync?"
|
|
235
290
|
|
|
236
291
|
Options:
|
|
237
|
-
- "Yes" -> run the `/sync` command (full ecosystem sync)
|
|
292
|
+
- "Yes" -> run the `/sync` command (full ecosystem sync - its Step 3d ships any band-E work in the toolkit repo)
|
|
238
293
|
- "No" -> report and finish
|
|
239
294
|
- "Only commit + push" -> push only the current repo without sync
|
|
240
295
|
|
|
@@ -247,6 +302,7 @@ If $ARGUMENTS is specified, focus on that band/category only:
|
|
|
247
302
|
| `bugs` | Bug hunt only (band B) |
|
|
248
303
|
| `best-practices` | Field research + adapted plan only (band A) |
|
|
249
304
|
| `drift` | Upstream derived-skill drift only (band D) |
|
|
305
|
+
| `dev-toolkit` | Companion MCP toolkit research + audit only (band E) |
|
|
250
306
|
| `security` | Security analysis only |
|
|
251
307
|
| `tests` | Test coverage and quality only |
|
|
252
308
|
| `performance` | Performance optimization only |
|
|
@@ -46,7 +46,7 @@ Skip Phase 0-3 and review a diff only. Input shapes: a PR (`#N`, `repo#N`, GitHu
|
|
|
46
46
|
|
|
47
47
|
| Platform | Trigger files | Catalog to load |
|
|
48
48
|
|---|---|---|
|
|
49
|
-
| iOS | `**/Info.plist`, `**/PrivacyInfo.xcprivacy`, `**/*.entitlements`, `**/*App.swift`, `**/AppDelegate*.swift`, `**/SceneDelegate*.swift`, `**/project.pbxproj` | `pipeline/skills/shared/core/apple-archive-compliance/SKILL.md` -
|
|
49
|
+
| 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 |
|
|
50
50
|
| 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 |
|
|
51
51
|
|
|
52
52
|
It appends the catalog's `ruleID` + the Apple ITMS / Play policy ref to each finding:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: multi-agent-sync
|
|
3
3
|
language: en
|
|
4
|
-
description: "One-shot sync of the entire multi-agent ecosystem: Claude Code, Copilot CLI, pipeline repo, and
|
|
4
|
+
description: "One-shot sync of the entire multi-agent ecosystem: Claude Code, Copilot CLI, pipeline repo, website, and the dev-toolkit MCP server."
|
|
5
5
|
user-invocable: true
|
|
6
|
-
argument-hint: 'release | "change description"'
|
|
6
|
+
argument-hint: 'release | dev-toolkit | "change description"'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Multi-Agent Sync
|
|
@@ -22,6 +22,7 @@ When invoked, it synchronizes all targets in order. It detects what changed, upd
|
|
|
22
22
|
| 2 | Copilot CLI | `~/.copilot/copilot-instructions.md` + `~/.copilot/skills/` | <- from Claude |
|
|
23
23
|
| 3 | multi-agent-pipeline repo | `~/multi-agent-pipeline/pipeline/` | <- from Claude (genericized) |
|
|
24
24
|
| 4 | Website | `{owner}/{website-host}` | <- version + features |
|
|
25
|
+
| 5 | dev-toolkit MCP server | resolved from `prefs.global.devToolkit` or the `mcpServers` registration | own repo: gate, commit, publish |
|
|
25
26
|
|
|
26
27
|
## Default Behavior (no argument)
|
|
27
28
|
|
|
@@ -29,11 +30,12 @@ Run all steps automatically:
|
|
|
29
30
|
|
|
30
31
|
```
|
|
31
32
|
Step 1: DETECT Compare timestamps, find stale targets
|
|
32
|
-
Step 2: COPILOT Claude Code -> Copilot CLI (instructions +
|
|
33
|
+
Step 2: COPILOT Claude Code -> Copilot CLI (instructions + 42 sub-command skills)
|
|
33
34
|
Step 3: REPO Claude Code -> pipeline repo (genericized, personal data scrub)
|
|
35
|
+
Step 3d: DEV-TOOLKIT Companion MCP server -> detect movement, ship gates, commit + publish
|
|
34
36
|
Step 4: WEBSITE Version + phase/model counts -> {website-host} (i18n + projects.ts)
|
|
35
37
|
Step 5: Commit Commit + push all changed repos
|
|
36
|
-
Step 6: Report Summary: synced targets, changed files, deploy status
|
|
38
|
+
Step 6: Report Summary: synced targets, changed files, deploy status, dev-toolkit version
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
If nothing is stale -> report "All targets up to date" and stop.
|
|
@@ -44,6 +46,7 @@ If nothing is stale -> report "All targets up to date" and stop.
|
|
|
44
46
|
|-------|----------|
|
|
45
47
|
| (no argument) | Full ecosystem sync (default) |
|
|
46
48
|
| `release` | Full sync + version bump + tag + npm publish + website deploy |
|
|
49
|
+
| `dev-toolkit` | Run Step 3d only: gate, commit and publish the companion MCP server |
|
|
47
50
|
| `"change description"` | Apply the description to ALL targets at once |
|
|
48
51
|
|
|
49
52
|
|
|
@@ -90,6 +93,43 @@ If nothing is stale -> report "All targets up to date" and stop.
|
|
|
90
93
|
- `~/.claude/settings.json`
|
|
91
94
|
|
|
92
95
|
|
|
96
|
+
## Dev-Toolkit Sync (Step 3d)
|
|
97
|
+
|
|
98
|
+
The companion MCP server (`dev-toolkit-mcp`) is its own repo with its own registry. Pipeline skills call its tools and several declare a minimum version, so when it moves it has to ship.
|
|
99
|
+
|
|
100
|
+
**Resolution**: identical to `multi-agent-refactor` Step 0c - `prefs.global.devToolkit` first, then the `mcpServers` registration, then skip.
|
|
101
|
+
|
|
102
|
+
**Detect movement**: dirty working tree, unpushed commits, or no `v<version>` tag for the version in `package.json`. Nothing moved -> report "up to date" and continue.
|
|
103
|
+
|
|
104
|
+
**Ship gates** (a failure aborts this step only, with file + line; the rest of the sync continues).
|
|
105
|
+
When the toolkit ships its own gate script (`npm run gates` / `scripts/gates.sh`), run that instead of the list below - the repo owns the definition, this skill owns the requirement. The list is the fallback, and the coverage the script must have:
|
|
106
|
+
|
|
107
|
+
1. `node --check index.js` plus every `tools/**/*.js`.
|
|
108
|
+
2. stdio handshake (`initialize` -> `notifications/initialized` -> `tools/list`) must answer with a non-zero tool count.
|
|
109
|
+
3. That count must match every advertised count (`package.json` description, README header and per-family rows). Fix the docs, never the gate.
|
|
110
|
+
4. `npm pack --dry-run` must list every `tools/*/` directory the server loads - a missing `files[]` entry publishes a broken package.
|
|
111
|
+
5. `grep -rn "console\.log(" index.js tools/` must be empty: stdout carries the JSON-RPC frames, diagnostics go to `console.error`.
|
|
112
|
+
6. Personal-data scan: no absolute `/Users/<name>` paths, no tokens, no corporate hostnames.
|
|
113
|
+
7. Version contract: every pipeline-side minimum version must be satisfied by what is about to ship; a new tool a pipeline skill now needs -> bump that minimum in the same sync.
|
|
114
|
+
|
|
115
|
+
**Version bump**: patch for fixes and docs, minor for a new tool, major for a removed or renamed tool.
|
|
116
|
+
|
|
117
|
+
**Ship**: commit with that repo's own convention, tag `v<version>`, push with `--tags`, then publish to the registry from `publishConfig` using a throwaway userconfig - never edit `~/.npmrc`, never a bare `npm publish`. The token depends on the registry: `npm.pkg.github.com` needs a GitHub PAT with `write:packages` (logical key `github`), `registry.npmjs.org` needs the `npm` key.
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
NPMRC=$(mktemp); trap 'rm -f "$NPMRC"' EXIT
|
|
121
|
+
REG=$(node -p "require('./package.json').publishConfig?.registry || 'https://registry.npmjs.org'")
|
|
122
|
+
HOST=${REG#https://}; HOST=${HOST%/}
|
|
123
|
+
case "$HOST" in npm.pkg.github.com*) KEY=github ;; *) KEY=npm ;; esac
|
|
124
|
+
TOKEN=$(bash "$HOME/.claude/lib/credential-store.sh" get "$KEY")
|
|
125
|
+
[ -n "$TOKEN" ] || echo "ABORT: no '$KEY' token - onboard it via /multi-agent:setup before publishing"
|
|
126
|
+
printf '%s\n' "registry=$REG" "//$HOST/:_authToken=$TOKEN" > "$NPMRC"
|
|
127
|
+
npm publish --userconfig "$NPMRC"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Approval**: outside autopilot and outside `release`, ask first: commit + push / commit + push + publish / skip. Never ship unapproved band-E work from `multi-agent-refactor` silently.
|
|
131
|
+
|
|
132
|
+
|
|
93
133
|
## Website Sync (Step 4)
|
|
94
134
|
|
|
95
135
|
Propagate the pipeline version, phase count, model count, and feature descriptions to the website.
|
|
@@ -124,9 +164,10 @@ When invoked with the `release` argument:
|
|
|
124
164
|
4. VERSION package.json version bump (patch/minor/major)
|
|
125
165
|
5. Commit + TAG git commit + git tag v{VERSION}
|
|
126
166
|
6. PUSH git push --tags -> release.yml auto-publish
|
|
127
|
-
7.
|
|
128
|
-
8.
|
|
129
|
-
9.
|
|
167
|
+
7. DEV-TOOLKIT Ship the companion MCP server if it moved (Step 3d gates, then publish)
|
|
168
|
+
8. WEBSITE Version + features -> {website-host}
|
|
169
|
+
9. COPILOT Copilot CLI instructions + skills sync
|
|
170
|
+
10. Report Summary: version, touched repos, deploy status
|
|
130
171
|
```
|
|
131
172
|
|
|
132
173
|
|
|
@@ -136,10 +177,10 @@ When invoked with the `release` argument:
|
|
|
136
177
|
|-------------|-------------|
|
|
137
178
|
| `~/.claude/commands/multi-agent/{cmd}.md` | `~/.copilot/skills/multi-agent-{cmd}/SKILL.md` |
|
|
138
179
|
|
|
139
|
-
**
|
|
180
|
+
**42 commands are synced** (canonical inventory - must match `cross-cli-contract.md` section 1; drift = contract violation):
|
|
140
181
|
|
|
141
182
|
```
|
|
142
|
-
analysis, analysis-resolve, autopilot, build-optimize, channels, create-jira, dev,
|
|
183
|
+
analysis, analysis-resolve, autopilot, build-optimize, channels, create-jira, design-check, dev,
|
|
143
184
|
dev-autopilot, dev-local, dev-local-autopilot, diff-explain, finish, forget, garbage-collect,
|
|
144
185
|
help, issue, jira, kill, language, local,
|
|
145
186
|
local-autopilot, log, manual-test, prune-logs, purge, refactor, resume, review, review-issue, review-jira,
|
|
@@ -159,6 +200,7 @@ routines, save, scan, search, setup, stack, status, sync, test, uninstall, updat
|
|
|
159
200
|
| `gh` CLI (personal) | `{owner}` gh auth (Keychain) |
|
|
160
201
|
| `gh` CLI (work) | `${USER}_{work-gh-alias}` gh auth (Keychain) |
|
|
161
202
|
| npm publish | `NODE_AUTH_TOKEN` - `GITHUB_TOKEN` in CI, Keychain PAT locally |
|
|
203
|
+
| dev-toolkit publish (Step 3d) | `npm` logical Keychain key -> throwaway `--userconfig`, registry from that repo's `publishConfig` |
|
|
162
204
|
|
|
163
205
|
```bash
|
|
164
206
|
gh auth switch --user {owner} # for personal repos
|
|
@@ -39,6 +39,6 @@ Pass `$ARGUMENTS` through verbatim - the target doc picks the right test matri
|
|
|
39
39
|
|
|
40
40
|
- **iOS**: Xcode + booted Simulator (`xcrun simctl list | grep Booted`)
|
|
41
41
|
- **Android**: Android SDK + running emulator or USB device (`adb devices`)
|
|
42
|
-
- **MCP**: `dev-toolkit` MCP server registered (tool names start with `
|
|
42
|
+
- **MCP**: `dev-toolkit` MCP server registered (tool names start with `mcp__dev-toolkit__*`)
|
|
43
43
|
|
|
44
44
|
For the Phase 5 manual test mode (branch checkout + Xcode hint), use `multi-agent-manual-test` instead.
|