@mmerterden/multi-agent-pipeline 20.13.0 → 20.15.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 +61 -0
- package/README.md +8 -6
- package/README.tr.md +7 -5
- package/docs/architecture.md +3 -3
- package/docs/ecosystem.md +5 -5
- package/docs/facts.json +4 -4
- package/install/catalog-history.json +1 -1
- package/manifest.json +156 -96
- package/package.json +1 -1
- package/pipeline/commands/multi-agent/analysis/SKILL.md +11 -80
- package/pipeline/commands/multi-agent/autopilot/SKILL.md +2 -23
- package/pipeline/commands/multi-agent/autopilot-off/SKILL.md +24 -45
- package/pipeline/commands/multi-agent/channels/SKILL.md +11 -63
- package/pipeline/commands/multi-agent/design-check/SKILL.md +43 -178
- package/pipeline/commands/multi-agent/diff-explain/SKILL.md +2 -0
- package/pipeline/commands/multi-agent/estimate/SKILL.md +65 -0
- package/pipeline/commands/multi-agent/help/SKILL.md +5 -546
- package/pipeline/commands/multi-agent/kill/SKILL.md +13 -18
- package/pipeline/commands/multi-agent/refactor/SKILL.md +7 -76
- package/pipeline/commands/multi-agent/review-analysis/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/scenario-audit/SKILL.md +79 -0
- package/pipeline/commands/multi-agent/serve/SKILL.md +6 -3
- package/pipeline/commands/multi-agent/setup/SKILL.md +12 -365
- package/pipeline/commands/multi-agent/status/SKILL.md +2 -0
- package/pipeline/commands/multi-agent/store-ready/SKILL.md +56 -184
- package/pipeline/commands/multi-agent/sync/SKILL.md +14 -267
- package/pipeline/contract/CHANGELOG.md +52 -0
- package/pipeline/contract/README.md +41 -1
- package/pipeline/contract/build.mjs +49 -7
- package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
- package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
- package/pipeline/contract/fixtures/error-unsigned.json +1 -1
- package/pipeline/contract/fixtures/launch-plan.json +1 -2
- package/pipeline/contract/fixtures/runs-awaiting-question.json +10 -3
- package/pipeline/contract/fixtures/runs-empty.json +1 -1
- package/pipeline/contract/fixtures/runs-failed.json +19 -6
- package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +25 -8
- package/pipeline/contract/fixtures/runs-pr-opened.json +25 -8
- package/pipeline/contract/fixtures/runs-running.json +31 -4
- package/pipeline/contract/frozen/toolbox.json +13 -0
- package/pipeline/contract/manifest.json +112 -10
- package/pipeline/contract/types/index.d.ts +186 -17
- package/pipeline/lib/claude-sessions.mjs +93 -0
- package/pipeline/lib/credential-resolve.mjs +39 -0
- package/pipeline/lib/gc-report.sh +64 -0
- package/pipeline/lib/unattended-settings-location.mjs +4 -0
- package/pipeline/lib/workspace-trust.mjs +73 -0
- package/pipeline/multi-agent-refs/analysis/intake.md +5 -3
- package/pipeline/multi-agent-refs/analysis/locked.md +8 -7
- package/pipeline/multi-agent-refs/analysis/render.md +4 -3
- package/pipeline/multi-agent-refs/analysis/resolve.md +1 -1
- package/pipeline/multi-agent-refs/analysis/resume.md +37 -0
- package/pipeline/multi-agent-refs/analysis/reusable-refs.md +25 -0
- package/pipeline/multi-agent-refs/channels/board.md +17 -0
- package/pipeline/multi-agent-refs/channels/multi-repo.md +15 -0
- package/pipeline/multi-agent-refs/cross-cli-contract.md +4 -4
- package/pipeline/multi-agent-refs/design-check/build-launch.md +14 -0
- package/pipeline/multi-agent-refs/design-check/compare.md +44 -0
- package/pipeline/multi-agent-refs/design-check/drive-capture.md +35 -0
- package/pipeline/multi-agent-refs/design-check/export.md +37 -0
- package/pipeline/multi-agent-refs/design-check/figma-mapping.md +11 -0
- package/pipeline/multi-agent-refs/design-check/init-inventory.md +56 -0
- package/pipeline/multi-agent-refs/design-check/mcp-currency-gate.md +41 -0
- package/pipeline/multi-agent-refs/features/analysis-outline.md +55 -0
- package/pipeline/multi-agent-refs/features/analysis-sources.md +60 -0
- package/pipeline/multi-agent-refs/help/en.md +273 -0
- package/pipeline/multi-agent-refs/help/tr.md +271 -0
- package/pipeline/multi-agent-refs/orchestrator/operations.md +99 -0
- package/pipeline/multi-agent-refs/orchestrator/phase-0-projects.md +72 -0
- package/pipeline/multi-agent-refs/orchestrator/phase-3-user-test.md +40 -0
- package/pipeline/multi-agent-refs/orchestrator/phase-4-5-projects.md +68 -0
- package/pipeline/multi-agent-refs/orchestrator/skill-loading.md +99 -0
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +3 -2
- package/pipeline/multi-agent-refs/phases/phase-1-plan.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-2-dev.md +1 -1
- package/pipeline/multi-agent-refs/picker-contract.md +29 -0
- package/pipeline/multi-agent-refs/refactor/drift.md +49 -0
- package/pipeline/multi-agent-refs/refactor/run-errors.md +46 -0
- package/pipeline/multi-agent-refs/setup/discovery.md +84 -0
- package/pipeline/multi-agent-refs/setup/figma.md +27 -0
- package/pipeline/multi-agent-refs/setup/identity-routing.md +60 -0
- package/pipeline/multi-agent-refs/setup/token-save-flow.md +201 -0
- package/pipeline/multi-agent-refs/store-ready/build.md +49 -0
- package/pipeline/multi-agent-refs/store-ready/gate-1-static.md +37 -0
- package/pipeline/multi-agent-refs/store-ready/gate-3-policy.md +31 -0
- package/pipeline/multi-agent-refs/store-ready/preflight.md +50 -0
- package/pipeline/multi-agent-refs/store-ready/report.md +40 -0
- package/pipeline/multi-agent-refs/sync/codex.md +43 -0
- package/pipeline/multi-agent-refs/sync/dev-toolkit.md +174 -0
- package/pipeline/multi-agent-refs/sync/stack-plugins.md +51 -0
- package/pipeline/multi-agent-refs/tracker-contract.md +29 -4
- package/pipeline/schemas/agent-state.schema.json +13 -4
- package/pipeline/schemas/analysis-spec.schema.json +56 -4
- package/pipeline/schemas/autopilot-off-request.schema.json +20 -0
- package/pipeline/schemas/autopilot-off.schema.json +24 -0
- package/pipeline/schemas/autopilot-status.schema.json +63 -0
- package/pipeline/schemas/contract-error.schema.json +13 -2
- package/pipeline/schemas/gc-request.schema.json +31 -0
- package/pipeline/schemas/gc.schema.json +116 -0
- package/pipeline/schemas/kill-request.schema.json +22 -0
- package/pipeline/schemas/kill.schema.json +118 -0
- package/pipeline/schemas/launch-plan.schema.json +11 -2
- package/pipeline/schemas/launch-request.schema.json +7 -2
- package/pipeline/schemas/launch.json +65 -4
- package/pipeline/schemas/launch.schema.json +23 -8
- package/pipeline/schemas/prefs.schema.json +3 -3
- package/pipeline/schemas/repos.schema.json +39 -0
- package/pipeline/schemas/resume-request.schema.json +37 -0
- package/pipeline/schemas/run-log.schema.json +32 -0
- package/pipeline/schemas/run-questions.json +5 -1
- package/pipeline/schemas/run-questions.schema.json +1 -1
- package/pipeline/schemas/runs-index.schema.json +59 -3
- package/pipeline/scripts/_run-paths.mjs +8 -2
- package/pipeline/scripts/analysis-conform-coverage.mjs +96 -0
- package/pipeline/scripts/analysis-sources.mjs +264 -0
- package/pipeline/scripts/autopilot-control.mjs +223 -0
- package/pipeline/scripts/autopilot-runner.mjs +14 -39
- package/pipeline/scripts/build-references.mjs +5 -1
- package/pipeline/scripts/confluence-readback.mjs +4 -23
- package/pipeline/scripts/contract-server.mjs +373 -7
- package/pipeline/scripts/doctor.mjs +5 -2
- package/pipeline/scripts/estimate.mjs +223 -0
- package/pipeline/scripts/gate-ledger.mjs +64 -3
- package/pipeline/scripts/gc-plan.mjs +288 -0
- package/pipeline/scripts/gc-refs.sh +33 -2
- package/pipeline/scripts/gc-tmp.sh +33 -2
- package/pipeline/scripts/gc-worktrees.sh +42 -3
- package/pipeline/scripts/gen-mode-dispatch.mjs +3 -24
- package/pipeline/scripts/launch-request.mjs +182 -10
- package/pipeline/scripts/phase-tracker.sh +62 -1
- package/pipeline/scripts/run-kill.mjs +232 -0
- package/pipeline/scripts/run-log.mjs +111 -0
- package/pipeline/scripts/runs-index.mjs +177 -11
- package/pipeline/scripts/scenario-audit.mjs +245 -0
- package/pipeline/scripts/validate-analysis-doc.mjs +84 -6
- package/pipeline/skills/.skill-manifest.json +24 -16
- package/pipeline/skills/shared/README.md +5 -3
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +51 -450
- package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +7 -1
- package/pipeline/skills/shared/core/multi-agent-autopilot-off/SKILL.md +26 -44
- package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +31 -127
- package/pipeline/skills/shared/core/multi-agent-estimate/SKILL.md +61 -0
- package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +14 -19
- package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +7 -76
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review-analysis/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-scenario-audit/SKILL.md +77 -0
- package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +6 -3
- package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +205 -324
- package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +5 -0
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +4 -4
|
@@ -11,16 +11,17 @@ allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep, TaskCreate, TaskUpdat
|
|
|
11
11
|
|
|
12
12
|
# /multi-agent:design-check - Mock-mode vs Figma design audit
|
|
13
13
|
|
|
14
|
-
Local, on-device design-conformance auditor.
|
|
14
|
+
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.
|
|
15
15
|
|
|
16
|
-
**Local-only**: no CI/CD, no cron, no commits, no PR.
|
|
16
|
+
**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 from the user's working tree.
|
|
17
17
|
|
|
18
|
-
> **Language (read FIRST)**:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
> **Language (read FIRST)**: `prefs.global.promptLanguage` is always `en` - this spec and every instruction to the LLM stay English. `prefs.global.outputLanguage` applies to conversational lines and the human-readable parts of the report; pass it to `design_report` as `report.lang` (engine defaults to English, ships `en` + `tr` label packs, per-key `report.labels` overrides). `AskUserQuestion` `header` chips, branch names, file paths, code identifiers and log lines stay English; option `label`s follow `outputLanguage`. Full contract: `$HOME/.claude/multi-agent-refs/rules.md` "Language Application".
|
|
19
|
+
|
|
20
|
+
## Gotchas
|
|
21
|
+
|
|
22
|
+
- A scope that matches no inventory target is an error, not an empty run; print the closest ids and stop.
|
|
23
|
+
- The coverage gate fails the run when a target was neither audited nor skipped with a reason. "Not reached" is not "passed".
|
|
24
|
+
- A Figma variant with no matching mock state is a finding about the mock, not a pass for the screen.
|
|
24
25
|
|
|
25
26
|
## Scope - `$ARGUMENTS`
|
|
26
27
|
|
|
@@ -33,7 +34,7 @@ The scope decides which **inventory targets** (Phase 0 step 5) the run must audi
|
|
|
33
34
|
| `screen@variant` | `order-status@expired` | One target |
|
|
34
35
|
| target id | `scenario-case:orderstatusoutcome-expired` | One target, exactly |
|
|
35
36
|
| Figma URL(s) | `https://figma.com/design/...?node-id=1-2` | Only the frames those URLs name |
|
|
36
|
-
| `--resume` |
|
|
37
|
+
| `--resume` | `--resume` | The unaudited remainder of the most recent run for this repo + module |
|
|
37
38
|
| combinations | `seat-map summary@semi-success` | Union of the above, space- or newline-separated |
|
|
38
39
|
|
|
39
40
|
A scope that matches **no** inventory target is an error, not an empty run: print the closest inventory ids and halt.
|
|
@@ -77,104 +78,38 @@ Every Phase 0 / Phase 2 decision uses a native `AskUserQuestion` picker per `pic
|
|
|
77
78
|
|
|
78
79
|
## Phase 0 - Init, Feasibility Gate & Inventory
|
|
79
80
|
|
|
80
|
-
0. **MCP CURRENCY GATE (first, before anything expensive)** -
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
'{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
|
|
92
|
-
| eval "$MA_MCP_CMD" 2>/dev/null | python3 -c "
|
|
93
|
-
import sys,json
|
|
94
|
-
for l in sys.stdin:
|
|
95
|
-
try: m=json.loads(l)
|
|
96
|
-
except: continue
|
|
97
|
-
if m.get('id')==1: print('version',m['result']['serverInfo']['version'])
|
|
98
|
-
if m.get('id')==2:
|
|
99
|
-
n=[t['name'] for t in m['result']['tools']]
|
|
100
|
-
print('tools',len(n),'inventory','design_scenario_inventory' in n)"
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
Branch on the two results:
|
|
105
|
-
- **disk OK, session missing the tool** → **HALT** and tell the user to reconnect: `/mcp` → `multi-agent-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 multi-agent-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.
|
|
106
|
-
- **disk itself stale** (older version, or `inventory False`) → **HALT**: the checkout needs updating before a reconnect can help.
|
|
107
|
-
- **both current** → continue.
|
|
108
|
-
|
|
109
|
-
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.
|
|
110
|
-
|
|
111
|
-
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`.
|
|
112
|
-
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).
|
|
113
|
-
3. **Platform detect** - `.xcodeproj` / `Package.swift` → iOS; `build.gradle*` → Android (same markers as `phase-0-init.md`). Persist `state.designCheck.platform`.
|
|
114
|
-
4. **MOCK FEASIBILITY GATE** - run against the selected module path:
|
|
115
|
-
```
|
|
116
|
-
mcp__multi-agent-toolkit__design_mock_detect({ repo_path: "<module path>", platform: "<ios|android>",
|
|
117
|
-
extra_keys: <design-check-config mock.keys, if any> })
|
|
118
|
-
```
|
|
119
|
-
Branch on `supported`:
|
|
120
|
-
- **`false`** → try the **snapshot lane** before halting: a screen renderable from its own view model (filled, flow-advanced, no backend) is auditable without a runtime mock switch. Ask via `AskUserQuestion`, persist `state.designCheck.captureLane = "snapshot"`. State the trade: snapshots reach modules mocks cannot and cannot flip an in-app variant, so the target set is whatever the view model can be built into. Declined or not renderable → **HALT** with `reason`. Never fabricate a comparison.
|
|
121
|
-
- **`"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 + description in `outputLanguage`): option 1 semantically "Continue" - audit the single default Debug state only; option 2 semantically "Cancel" - stop.
|
|
122
|
-
- **`true`** → continue. Persist `state.designCheck.mock = <detect result>` (mechanism, activation, variantsHint, evidence).
|
|
123
|
-
5. **SCENARIO INVENTORY (this is the audit's target set)**:
|
|
124
|
-
```
|
|
125
|
-
mcp__multi-agent-toolkit__design_scenario_inventory({ repo_path: "<module path>", platform,
|
|
126
|
-
targets_file: <config inventory.targetsFile>,
|
|
127
|
-
extra_launch_args: <config inventory.extraLaunchArgs>,
|
|
128
|
-
extra_targets: <config inventory.extraTargets>,
|
|
129
|
-
ignore_targets: <config inventory.ignoreTargets> })
|
|
130
|
-
```
|
|
131
|
-
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`.
|
|
132
|
-
|
|
133
|
-
This list, not the agent's reading of the code or what the UI exposes to tapping, is what the run is measured against. Persist verbatim to `state.designCheck.inventory`.
|
|
134
|
-
- `targetCount: 0` → warn that no state driver was found and that only the default launch state can be audited; a `debug-only` project lands here.
|
|
135
|
-
- `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.
|
|
81
|
+
0. **MCP CURRENCY GATE (first, before anything expensive)** - a session started before the last update serves the OLD tool list while reporting "connected". Check both halves before the Debug build: (a) **session** - `design_scenario_inventory` is available and `design_visual_compare` accepts `live_region`; (b) **disk** - probe what a fresh connection would serve. Disk OK but session stale → **HALT**, tell the user to reconnect (`/mcp` → `multi-agent-toolkit` → Reconnect). Disk stale → **HALT**, the checkout needs updating. Both current → continue. Never substitute a local `node` call for a missing tool: the run would silently lose the coverage gate and region alignment. Full procedure: `$HOME/.claude/multi-agent-refs/design-check/mcp-currency-gate.md`. Read it for Phase 0 step 0.
|
|
82
|
+
1. **Repo picker** - `$HOME/.claude/multi-agent-refs/_repo-picker.md`. Account picker skipped unless Confluence export is enabled.
|
|
83
|
+
2. **Module / dev-context picker** - `$HOME/.claude/multi-agent-refs/_dev-context.md`; multi-module allowed, each audited independently.
|
|
84
|
+
3. **Platform detect** - persist `state.designCheck.platform`.
|
|
85
|
+
4. **MOCK FEASIBILITY GATE** - `mcp__multi-agent-toolkit__design_mock_detect` on the selected module path. Branch on `supported`:
|
|
86
|
+
- **`false`** → try the **snapshot lane** before halting: a screen renderable from its own view model is auditable without a runtime mock switch. Ask via `AskUserQuestion`, persist `state.designCheck.captureLane = "snapshot"`, and state the trade (no in-app variant flips). Declined or not renderable → **HALT** with `reason`. Never fabricate a comparison.
|
|
87
|
+
- **`"debug-only"`** → `AskUserQuestion` warning: variants cannot be toggled at launch, only the default Debug state is comparable. Continue / Cancel.
|
|
88
|
+
- **`true`** → continue; persist `state.designCheck.mock`.
|
|
89
|
+
5. **SCENARIO INVENTORY (this is the audit's target set)** - `mcp__multi-agent-toolkit__design_scenario_inventory` with the config's inventory overrides. This list, not the agent's reading of the code or what the UI exposes to tapping, is what the run is measured against. Persist verbatim to `state.designCheck.inventory`.
|
|
90
|
+
- `targetCount: 0` → warn that no state driver was found and only the default launch state can be audited; a `debug-only` project lands here.
|
|
91
|
+
- `truncated: true` → 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.
|
|
136
92
|
- `ignored[]` non-empty → list what the config dropped, so a stale `ignoreTargets` cannot quietly shrink the audit.
|
|
137
|
-
6. **Scope resolve** - intersect `$ARGUMENTS`
|
|
93
|
+
6. **Scope resolve** - intersect `$ARGUMENTS` with `inventory.targets`; persist `state.designCheck.scope = { argument, targetIds[] }`. Print the set grouped by screen as `<n> targets · <relaunchCount> relaunches` (cost from `plan`, not the target count). Ask for confirmation only when `relaunchCount` exceeds `config coverage.confirmAbove` (default 25), as a cost estimate; never propose a smaller scope as the easy path.
|
|
94
|
+
7. **`--resume`** - scope = the latest `run-state.json` targets minus `covered` minus `skipped`. No previous run → tell the user and fall back to whole-module scope after confirmation.
|
|
95
|
+
8. **Report dir** - create `~/DesignChecks/{repo}__{module}/{UTC-timestamp}/` (+ `assets/`) now, persist `state.designCheck.reportDir`; it exists before driving starts.
|
|
96
|
+
9. **Worktree** - `{projectRoot}/.worktrees/{taskId}`, `taskId` = `DC-<shortId>`, **never under $HOME**; prune stale locks and add the residue guard first. Local mode is not offered.
|
|
138
97
|
|
|
139
|
-
|
|
140
|
-
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.
|
|
141
|
-
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.
|
|
142
|
-
9. **Worktree** - build the Debug app in an isolated worktree so the user's tree is untouched. Follow the `phase-0-init.md` Step 6 worktree location convention exactly: `{projectRoot}/.worktrees/{taskId}` with `taskId` = `DC-<shortId>`, **never under $HOME** (the `.worktrees` segment is fixed, not a preference). 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).
|
|
143
|
-
|
|
144
|
-
Persist `agent-state.json` with `taskId`, `mode: "design-check"`, `projectRoot`, `worktreePath` and `designCheck` (which carries `module` and `platform`).
|
|
98
|
+
Then persist `agent-state.json`. Full procedure: `$HOME/.claude/multi-agent-refs/design-check/init-inventory.md`. Read it for Phase 0 steps 1-9.
|
|
145
99
|
|
|
146
100
|
## Phase 1 - Build & Launch (mock)
|
|
147
101
|
|
|
148
|
-
|
|
149
|
-
- iOS: `mcp__multi-agent-toolkit__ios_xcodebuild({ workspace|project, scheme, configuration: "Debug", action: "build", destination: "generic/platform=iOS Simulator" })`. Drill failures via `ios_xcresult`.
|
|
150
|
-
- Android: `./gradlew :<module>:assembleDebug` (or `installDebug`) via Bash.
|
|
151
|
-
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>`.
|
|
152
|
-
3. **Deterministic state**: iOS `ios_status_bar({ preset: "clean" })` (09:41 / full battery); set a fixed appearance + locale so captures are stable across runs.
|
|
153
|
-
4. **Launch in mock mode** using the activation from Phase 0:
|
|
154
|
-
```
|
|
155
|
-
mcp__multi-agent-toolkit__design_mock_launch({ platform, bundle_id|package_name,
|
|
156
|
-
launch_arg: state.designCheck.mock.activation.launchArg, // iOS, e.g. "-debugMockMode YES"
|
|
157
|
-
intent_extra: state.designCheck.mock.activation.intentExtra }) // Android
|
|
158
|
-
```
|
|
159
|
-
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.
|
|
102
|
+
Debug build in the worktree (mocks need Debug), boot, install once, fix status bar / appearance / locale, launch via `design_mock_launch` with the Phase 0 activation (`debug-only`: plain launch). Phase 3 relaunches, never rebuilds. Full procedure: `$HOME/.claude/multi-agent-refs/design-check/build-launch.md`. Read it for Phase 1.
|
|
160
103
|
|
|
161
104
|
## Phase 2 - Figma fetch & variant mapping (module-scoped)
|
|
162
105
|
|
|
163
106
|
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.
|
|
164
107
|
|
|
165
|
-
|
|
166
|
-
2. `mcp__claude_ai_Figma__get_metadata({ fileKey, nodeId })` → the frame tree. Treat direct child frames as **candidate variants**.
|
|
167
|
-
3. **Map inventory targets → Figma frames**: match each scoped target's `screen` + `label` (and `state.designCheck.mock.variantsHint`) to frame names by similarity.
|
|
168
|
-
- Confident 1:1 match → accept.
|
|
169
|
-
- **Ambiguous or unmatched** → deferred to the Phase 3.3 batch-ask, where the live capture can be shown alongside the question. Never guess silently.
|
|
170
|
-
- `debug-only` projects → a single variant (the default state) mapped to the primary frame.
|
|
171
|
-
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`).
|
|
172
|
-
|
|
173
|
-
Persist the variant list + spec + PNG paths to `state.designCheck.variants[]`.
|
|
108
|
+
Fetch the frame tree, map each scoped target to a frame, fetch screenshot + design context per variant, persist `state.designCheck.variants[]`. **Ambiguous or unmatched → defer to the Phase 3.3 batch-ask. Never guess silently.** Full procedure: `$HOME/.claude/multi-agent-refs/design-check/figma-mapping.md`. Read it for Phase 2.
|
|
174
109
|
|
|
175
110
|
## Phase 3 - Drive every scoped target → capture → match → batch-ask → compare
|
|
176
111
|
|
|
177
|
-
**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,
|
|
112
|
+
**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, scenario case, or typed scenario code - which is how a module's error / edge states go missing.
|
|
178
113
|
|
|
179
114
|
### 3.0 What every capture is compared against
|
|
180
115
|
|
|
@@ -182,69 +117,23 @@ Persist the variant list + spec + PNG paths to `state.designCheck.variants[]`.
|
|
|
182
117
|
|
|
183
118
|
### 3.1 Drive the inventory's plan, batch by batch
|
|
184
119
|
|
|
185
|
-
**Follow `inventory.plan`, filtered to the scoped ids.** Each batch is one launch: the
|
|
186
|
-
|
|
187
|
-
For each batch:
|
|
188
|
-
1. Launch once with the batch's `launch` driver (or the plain mock activation for the `(default launch)` batch).
|
|
189
|
-
2. Navigate to the screen (`ios_tap` / `ios_swipe` / `ios_type_text` route through idb).
|
|
190
|
-
3. Capture the batch's relaunch target.
|
|
191
|
-
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.**
|
|
192
|
-
|
|
193
|
-
Per-target activation by `driver.type`:
|
|
194
|
-
|
|
195
|
-
| `driver.type` | Activation |
|
|
196
|
-
|---|---|
|
|
197
|
-
| `launch-arg` | `design_mock_launch({ launch_arg: "<mock activation> <driver.launchArg>" })` - the mock switch AND the target's flag together |
|
|
198
|
-
| `intent-extra` | `design_mock_launch({ intent_extra: "<mock extra> <driver.intentExtra>" })` |
|
|
199
|
-
| `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 |
|
|
200
|
-
| `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 |
|
|
201
|
-
| `code` (from `code-scenario`) | Same entry field, but the code is flow-wide rather than owned by one screen |
|
|
202
|
-
| `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" |
|
|
203
|
-
| `deep-link` | `ios_open_url` / `android_open_url` with `driver.url` |
|
|
204
|
-
| `manual` | Config-declared: follow the config's note, or skip with that note as the reason |
|
|
120
|
+
**Follow `inventory.plan`, filtered to the scoped ids.** Each batch is one launch: the relaunch target opens a screen, then every in-app target for that screen is flipped while the app sits there - **no relaunch between them**. Driving the plan is what makes full coverage affordable. Activate each target by its `driver.type`, and capture the tap-reachable sub-states (sheets, modals, inline errors) under `<id>#<sub-label>`. Each capture (screenshot + `design_ui_geometry`) goes to `state.designCheck.captured[]`. **Persist `state` and `run-state.json` after every capture**, so a run that dies mid-way resumes from where it stopped. Full procedure (driver table, capture mechanics): `$HOME/.claude/multi-agent-refs/design-check/drive-capture.md`. Read it for Phase 3.1.
|
|
205
121
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
For each capture: `ios_screenshot` (save PNG into the Phase 0 report dir) + `mcp__multi-agent-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.
|
|
209
|
-
|
|
210
|
-
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 order", "crashes on launch: <symbol>"). "Requires a scenario / prefix / launch-arg" is **not** a reason - it describes the work, which is this phase's job.
|
|
122
|
+
An unreachable target is recorded immediately as `{ id, reason }` in `state.designCheck.skipped[]` with a concrete reason. "Requires a scenario / prefix / launch-arg" is **not** a reason - it describes the work, which is this phase's job.
|
|
211
123
|
|
|
212
124
|
### 3.2 Match each capture → Figma frame (auto)
|
|
213
125
|
|
|
214
|
-
|
|
126
|
+
Accept only a **confident** match against the Phase 2 tree; matched → `pairs[]`.
|
|
215
127
|
|
|
216
128
|
### 3.3 Batch-ask the user for EVERYTHING unmatched (ONE prompt, WITH the visual)
|
|
217
129
|
|
|
218
|
-
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
|
|
130
|
+
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**, name the screen, and ask for the Figma node-id / URL (in `outputLanguage`). Each answer becomes a confirmed pair. A screen the user declines to map is a skip with reason "no Figma frame supplied".
|
|
219
131
|
|
|
220
132
|
### 3.4 Compare ALL pairs in one pass
|
|
221
133
|
|
|
222
|
-
|
|
223
|
-
```
|
|
224
|
-
mcp__multi-agent-toolkit__design_visual_compare({
|
|
225
|
-
figma_png, live_png, out_dir: "<report dir>/assets", label: "<variant>",
|
|
226
|
-
figma_spec, live_geometry, figma_frame, live_screen,
|
|
227
|
-
crop_top_live: <status-bar px>, // strip device chrome the Figma frame lacks
|
|
228
|
-
tolerance_px: 2, color_tolerance: 3, max_diff_pct: 1.0 })
|
|
229
|
-
```
|
|
230
|
-
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).
|
|
231
|
-
|
|
232
|
-
**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:
|
|
233
|
-
|
|
234
|
-
```
|
|
235
|
-
mcp__multi-agent-toolkit__design_visual_compare({ ...as above,
|
|
236
|
-
live_region: <the sheet container's {x,y,w,h} from design_ui_geometry>,
|
|
237
|
-
expected_region: <where the design puts that sheet, same units> })
|
|
238
|
-
```
|
|
239
|
-
- `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.
|
|
240
|
-
- `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.
|
|
241
|
-
- `crop_top_live` is ignored when `live_region` is given - the region crop has already excluded device chrome.
|
|
242
|
-
|
|
243
|
-
**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.
|
|
244
|
-
|
|
245
|
-
**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`.
|
|
134
|
+
`design_visual_compare` per pair (matched + user-supplied) with `tolerance_px: 2, color_tolerance: 3, max_diff_pct: 1.0`. **Bottom sheets, modals, and any partial overlay need region alignment** (`live_region` from the sheet container in `design_ui_geometry`, never a guess, plus `expected_region` from the Figma placement). Attach Code Connect refs (best-effort); compose a paste-ready fix prompt. Full procedure (match, batch-ask mechanics, compare call, region alignment): `$HOME/.claude/multi-agent-refs/design-check/compare.md`. Read it for Phase 3.2-3.4.
|
|
246
135
|
|
|
247
|
-
**
|
|
136
|
+
**Edge insets are defects, not tolerances.** 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.
|
|
248
137
|
|
|
249
138
|
### 3.5 Close the ledger
|
|
250
139
|
|
|
@@ -255,48 +144,24 @@ Every scoped target id must end in exactly one bucket:
|
|
|
255
144
|
|
|
256
145
|
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.
|
|
257
146
|
|
|
258
|
-
Before leaving this phase, compare `covered.length + skipped.length` against `scope.targetIds.length`.
|
|
147
|
+
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.
|
|
259
148
|
|
|
260
149
|
## Phase 4 - Report, coverage gate & export
|
|
261
150
|
|
|
262
|
-
1. **Output dir**: `state.designCheck.reportDir
|
|
263
|
-
2. Assemble the report object:
|
|
264
|
-
|
|
265
|
-
{ project, module, platform, figmaUrl, figmaFileKey, timestamp,
|
|
266
|
-
lang: <prefs.global.outputLanguage>,
|
|
267
|
-
coverage: { targets: <scoped inventory targets, as the id array or the target objects>,
|
|
268
|
-
covered: <audited id array>,
|
|
269
|
-
skipped: [ { id, group, reason } ],
|
|
270
|
-
truncatedInventory: <inventory.truncated>,
|
|
271
|
-
floor: <config coverage.floor, optional> },
|
|
272
|
-
variants: [ { name, figmaNodeId, perceptualPct, passed, compareSize, liveSize,
|
|
273
|
-
images, findings, fixPrompt, componentRefs,
|
|
274
|
-
walk: { components: <inventoried>, converged: <count>,
|
|
275
|
-
didNotConverge: [ { component, attempts } ],
|
|
276
|
-
notVerified: [ { item, tag, reason } ] } } ] }
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
`walk` separates a checked screen from a viewed one. An empty `notVerified` on a run that never captured a dark or mirrored pass is a false clean - list the skip. Field definitions: `features/design-conformance.md`.
|
|
280
|
-
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.
|
|
281
|
-
3. **Render + export**:
|
|
282
|
-
```
|
|
283
|
-
mcp__multi-agent-toolkit__design_report({ report, out_dir: state.designCheck.reportDir,
|
|
284
|
-
formats: ["html", "pdf"] + (confluence enabled ? ["confluence"] : []) })
|
|
285
|
-
```
|
|
286
|
-
- HTML: self-contained (base64 images, CSS-positioned annotations over the live capture, stacked findings, fix prompt), with the coverage gate banner at the top.
|
|
287
|
-
- PDF: via Playwright if present; if unavailable the tool returns `pdfError` - report it and note the HTML can be printed manually.
|
|
288
|
-
- **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.
|
|
151
|
+
1. **Output dir**: `state.designCheck.reportDir` from Phase 0; never a second timestamped dir.
|
|
152
|
+
2. **Assemble** the report object: `coverage` (scoped `targets`, `covered`, `skipped` with reasons, `truncatedInventory`, optional `floor`) and per-variant results with a `walk` block (`components`, `converged`, `didNotConverge`, `notVerified`). `walk` separates a checked screen from a viewed one: an empty `notVerified` on a run that never captured a dark or mirrored pass is a false clean - list the skip. Pass **ids**, not counts.
|
|
153
|
+
3. **Render + export** with `design_report` (`html` + `pdf`, + `confluence` only when enabled; disabled → graceful skip). Full procedure (report object, export formats, cleanup): `$HOME/.claude/multi-agent-refs/design-check/export.md`. Read it for Phase 4.
|
|
289
154
|
4. **COVERAGE GATE (blocking, not advisory)** - read `coverage` from the tool result and persist it to `state.designCheck.coverage`:
|
|
290
155
|
- `gate: "pass"` → report per-variant PASS/FAIL + findings count + report paths.
|
|
291
156
|
- `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.
|
|
292
157
|
|
|
293
158
|
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.
|
|
294
|
-
5.
|
|
159
|
+
5. Remove the worktree unless the user asked to keep the built app. The report dir is never removed.
|
|
295
160
|
|
|
296
161
|
## Notes
|
|
297
162
|
|
|
298
|
-
- **Feasibility is real**:
|
|
163
|
+
- **Feasibility is real**: a project with no launchable app or no runtime switch cannot be audited. Report that honestly and stop - never substitute a fabricated or partial comparison.
|
|
299
164
|
- **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.
|
|
300
165
|
- **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.
|
|
301
|
-
- **"Pixel perfect" is perceptual + geometric**:
|
|
302
|
-
- The
|
|
166
|
+
- **"Pixel perfect" is perceptual + geometric**: scale normalized, chrome cropped; findings carry px / pt / hex deltas and a tolerance.
|
|
167
|
+
- The `design_*` engine is project-agnostic; project specifics (mock keys, launch args / targets, node overrides, status-bar crop, coverage floor, Confluence toggle) come from `design-check-config.json` / prefs, never hardcoded.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Estimate new work from similar closed Jira work: a P25-P75 range per role from logged time, with the tickets behind it and the modules touched. Read-only; never a single number, none below three samples. Use when a story, analysis or request needs an effort range."
|
|
3
|
+
description-tr: "Yeni işi ona benzeyen kapanmış işlerden tahmin eder: benzer bitmiş Jira kayıtlarını bulur, onlara ve rol alt görevlerine girilen süreyi okur, rol başına P25-P75 aralığını dayandığı ticket'larla ve işin dokunduğu modüllerle raporlar. Salt-okunur; asla tek sayı vermez, üç örneğin altında hiç sayı vermez."
|
|
4
|
+
allowed-tools: Bash, Read, Grep, AskUserQuestion
|
|
5
|
+
argument-hint: "<analysis.md | \"free text\"> [--project KEY]"
|
|
6
|
+
parameters: [{"name":"input","kind":"text","required":true},{"name":"--project","kind":"text"}]
|
|
7
|
+
gui: form
|
|
8
|
+
destructive: false
|
|
9
|
+
confirm: none
|
|
10
|
+
not-for: analysis, analysis-jira
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# multi-agent estimate
|
|
14
|
+
|
|
15
|
+
> **Pickers follow** `$HOME/.claude/multi-agent-refs/picker-contract.md`: never a one-option call, and branch on the option selected, not on its text.
|
|
16
|
+
|
|
17
|
+
**Input**: $ARGUMENTS
|
|
18
|
+
|
|
19
|
+
Turns history into a range. The query and the reading of the work are yours;
|
|
20
|
+
the arithmetic and the minimum-sample rule are the script's. Nothing is written
|
|
21
|
+
to Jira or anywhere else.
|
|
22
|
+
|
|
23
|
+
Script: `$HOME/.claude/scripts/estimate.mjs`.
|
|
24
|
+
|
|
25
|
+
## Gotchas
|
|
26
|
+
|
|
27
|
+
- The query must say `statusCategory = Done`; the script refuses anything else, because open work has no final time.
|
|
28
|
+
- Logged time is only as good as the team's logging. A role with sub-tasks but no `timespent` has no samples; say that rather than reading it as zero effort.
|
|
29
|
+
- Similar means similar work, not similar words: narrow by component or label first, then by text. A query that returns fifty unrelated issues gives a confident-looking range about nothing.
|
|
30
|
+
- Fewer than three samples gives no number for that row. Do not fill it in from judgement.
|
|
31
|
+
|
|
32
|
+
## Step 1 - What is being estimated
|
|
33
|
+
|
|
34
|
+
From an analysis document, read its feature name, the components or channels it
|
|
35
|
+
names and its story count; from free text, its nouns. Map the modules it
|
|
36
|
+
touches with the repo map when a repository is at hand:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
node "$HOME/.claude/scripts/repo-map.mjs" --root "<repo>" --budget 800
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Step 2 - The query
|
|
43
|
+
|
|
44
|
+
Build one JQL from the project (`--project`, else `prefs.global.issueTree.projectKey`),
|
|
45
|
+
`statusCategory = Done`, the components or labels found above, and at most two
|
|
46
|
+
`text ~` terms. Show it and let the user edit it with one `AskUserQuestion`
|
|
47
|
+
(**Run it** / **Edit the query** / **Cancel**).
|
|
48
|
+
|
|
49
|
+
## Step 3 - Run
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
node "$HOME/.claude/scripts/estimate.mjs" --jql "<jql>" \
|
|
53
|
+
--roles "$(jq -r '.global.issueTree.subtaskRoles // [] | join(",")' "$HOME/.claude/multi-agent-preferences.json")"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
With no roles configured the report has the total and story-point rows only.
|
|
57
|
+
|
|
58
|
+
## Step 4 - Report
|
|
59
|
+
|
|
60
|
+
Print the table verbatim, then the modules from Step 1. Say which rows had too
|
|
61
|
+
little history, how many issues were sampled, and that the range describes the
|
|
62
|
+
past work the query found: the choice of query is judgement, the numbers are
|
|
63
|
+
arithmetic over it.
|
|
64
|
+
|
|
65
|
+
**Stop. No ticket is created or edited.**
|