@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
|
@@ -72,46 +72,12 @@ Roll the high-impact + low/med-effort survivors into the Step 4 plan as band-A i
|
|
|
72
72
|
|
|
73
73
|
Some skills/components in this project (or in the marketplace plugins it ships) were derived from an upstream source. Upstream keeps evolving - it fixes bugs and adds features. This step detects upstream drift so we can decide whether to pull the improvements back.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"label": "<human name for this derivation>",
|
|
80
|
-
"localPath": "<repo-relative dir where our derived copy lives>",
|
|
81
|
-
"upstreamMarketplace": "<installed marketplace name>", // resolved under ~/.claude/plugins/cache/<marketplace>/
|
|
82
|
-
"upstreamPlugin": "<plugin name>",
|
|
83
|
-
"upstreamSkills": ["<skill-a>", "<skill-b>"], // the upstream skills we took
|
|
84
|
-
"derivedFromVersion": "<x.y.z>", // the version we last synced from
|
|
85
|
-
"upstreamVersionSource": "marketplace.json", // which manifest is authoritative; default marketplace.json
|
|
86
|
-
"upstreamLocalClone": "<optional path>", // working copy of the upstream repo, preferred over the cache
|
|
87
|
-
"upstreamRepoUrl": "<optional https url>" // used when neither a clone nor the marketplace is available
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**The plugin cache is a mirror, not the authority.** `~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/` only holds whatever the last `claude plugin marketplace update` fetched. Reading it as the current upstream version is how this step reported "up to date" while the derivation was four releases behind: the cache sat at 0.2.1 and upstream was at 0.4.1. Resolve in the order below and never let the cache alone produce an "up to date" verdict.
|
|
92
|
-
|
|
93
|
-
**Which manifest carries the version** is `upstreamVersionSource`, default `marketplace.json`. That is what a marketplace consumer actually resolves, and some upstreams keep per-plugin `plugin.json` versions deliberately unused - reading those records a version nobody ships. An entry here was recorded at 0.7.0 from `plugin.json` while the upstream marketplace said 0.6.0 and its CHANGELOG stated in as many words that `plugin.json` is not used.
|
|
94
|
-
|
|
95
|
-
Procedure:
|
|
96
|
-
1. If `global.derivedSkillSources` is missing or empty -> **skip** this step and report "no derived-skill sources configured" (nothing to check). Never invent a source.
|
|
97
|
-
2. For each entry, resolve the current upstream version, in this order, stopping at the first that answers:
|
|
98
|
-
- **`upstreamLocalClone`** if set: read `<clone>/.claude-plugin/<upstreamVersionSource>`. Also run `git -C <clone> fetch --dry-run` (or compare against `@{u}`) and say so when the clone is itself behind, so a stale working copy is not silently trusted either.
|
|
99
|
-
- **`upstreamRepoUrl`**: read the same manifest over the API (`gh api` / `WebFetch`). A private upstream can 404 for the currently active account even when the repo exists - that is an unreachable result, not a "no drift" result.
|
|
100
|
-
- **Plugin cache** under `~/.claude/plugins/cache/<upstreamMarketplace>/<upstreamPlugin>/*/`: last resort only. When the cache is the only source that answered, report the entry as **`unverified (cache only)`**, never as "up to date", and add a plan item to configure `upstreamLocalClone`.
|
|
101
|
-
- If nothing is reachable, record the entry as "upstream unreachable" and move on (do not fail the whole run).
|
|
102
|
-
3. Compare the resolved upstream version to `derivedFromVersion`:
|
|
103
|
-
- equal, from an authoritative source -> "up to date" (no drift)
|
|
104
|
-
- equal, from the cache only -> "unverified (cache only)"
|
|
105
|
-
- newer -> **drift**: read the CHANGELOG entries between the two versions, and diff each `upstreamSkills` SKILL.md (+ any templates) against our `localPath` copy. Summarize what changed upstream (bug fixes, new sections, new templates, renamed inputs). Ignore changelog entries that only touch skills outside `upstreamSkills` - they are not ours to port.
|
|
106
|
-
4. Emit the drift table (plan band D):
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
| Derivation | Our copy (localPath) | Derived-from | Upstream now | Drift | What changed upstream |
|
|
110
|
-
|------------|----------------------|--------------|--------------|-------|-----------------------|
|
|
111
|
-
| <label> | <path> | 0.2.1 | 0.3.0 | YES | <changelog + diff summary> |
|
|
112
|
-
```
|
|
75
|
+
Rules that hold for every entry:
|
|
76
|
+
- The upstream mapping is **configuration, never hardcoded**: `global.derivedSkillSources` in `~/.claude/multi-agent-preferences.json`. Missing or empty -> **skip** and report "no derived-skill sources configured". Never invent a source.
|
|
77
|
+
- **The plugin cache is a mirror, not the authority.** Never let the cache alone produce an "up to date" verdict; report it as **`unverified (cache only)`**. An unreachable upstream is recorded as "upstream unreachable" and the run continues.
|
|
78
|
+
- Each drifted entry becomes a band-D plan item. Do not auto-apply upstream changes - they go through Step 5 approval like everything else, and after porting, bump the entry's `derivedFromVersion`.
|
|
113
79
|
|
|
114
|
-
|
|
80
|
+
Full procedure: `$HOME/.claude/multi-agent-refs/refactor/drift.md`. Read it when `global.derivedSkillSources` has at least one entry (entry schema, source resolution order, version manifest, comparison, band-D table).
|
|
115
81
|
|
|
116
82
|
## Step 0c: DEV-TOOLKIT - current MCP practice for the companion toolkit
|
|
117
83
|
|
|
@@ -121,44 +87,9 @@ Full procedure - resolution (configuration first, never a hardcoded path; skip
|
|
|
121
87
|
|
|
122
88
|
## Step 0d: RUN-ERRORS - what the pipeline actually failed on
|
|
123
89
|
|
|
124
|
-
Before speculating about improvements, read what real runs already failed on. When usage logging is enabled, every terminated run appends its errors to a local ledger:
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
LEDGER="$HOME/.claude/logs/multi-agent/errors-ledger.jsonl"
|
|
128
|
-
[ -f "$LEDGER" ] || echo "no run-error ledger yet - skip band F"
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Each line is one run: `{ t, id, u, c, rp, ph, v, errs[] }`. The `errs[]` entries are cause tags (`<phase>:<cause>` halt reasons, `phase-<id>-failed`, `run-failed`).
|
|
132
|
-
|
|
133
|
-
1. Read the ledger (best-effort; a missing or unreadable file means skip band F, not a failure).
|
|
134
|
-
2. Group by error tag. For each tag compute: occurrences, distinct users affected, distinct repos, the phase it usually strikes, first + last seen, and which pipeline versions it spans (a tag that persists across versions is unfixed; one that stopped at a version is already resolved - do not re-raise it).
|
|
135
|
-
3. Rank by `occurrences x users-affected`. A failure that recurs across users or tasks is lived evidence, not a hypothesis - it outranks a speculative improvement.
|
|
136
|
-
4. For each surviving tag, trace it to the phase doc / script that emits that cause and propose the concrete fix.
|
|
137
|
-
|
|
138
|
-
This band mirrors the admin dashboard's "Gelişim alanları" panel, but reads the local ledger so it needs no auth and works offline. If `$ARGUMENTS` names a focus area, still read the ledger - a recurring run error in that area is the strongest possible signal.
|
|
139
|
-
|
|
140
|
-
Then read what the transcripts themselves record, which is the half no model noticed:
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
node "$HOME/.claude/scripts/learn-from-transcripts.mjs" --json
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
It correlates rather than interprets - a failed read against the read that then worked, an identical invocation that kept failing, a search that was too narrow, a call the user refused twice, a file too big to read whole. Dry run by default; `--apply` writes them to the learnings ledger as `source: transcript-mining` and renders a marked block in `CLAUDE.local.md`. Zero candidates alongside a non-zero `toolResultsExamined` means there was nothing to find; zero of both means the read is broken.
|
|
147
|
-
|
|
148
|
-
Output (plan band F):
|
|
149
|
-
|
|
150
|
-
```
|
|
151
|
-
| # | Error tag | Occurrences | Users | Usual phase | Versions | Root cause (file) | Fix | In plan? |
|
|
152
|
-
|---|-----------|-------------|-------|-------------|----------|-------------------|-----|----------|
|
|
153
|
-
| 1 | 4:reviewer-json-invalid | 12 | 3 | 4 | 14.x-15.x | reviewer prompt lets prose leak | tighten schema instruction in phase-3-review.md | Yes (P0) |
|
|
154
|
-
| 2 | phase-3-failed | 5 | 2 | 3 | 15.0.x | build step misses a stack toolchain | add preflight in phase-2-dev.md | Yes (P1) |
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
Rules for this band:
|
|
90
|
+
Before speculating about improvements, read what real runs already failed on. When usage logging is enabled, every terminated run appends its errors to a local ledger at `$HOME/.claude/logs/multi-agent/errors-ledger.jsonl`. A missing, unreadable or empty ledger means skip band F silently - it is additive signal, never a gate. If `$ARGUMENTS` names a focus area, still read the ledger - a recurring run error in that area is the strongest possible signal. A tag that stopped recurring after a version bump is resolved: report it, do not re-raise it. Never quote a user's identity as blame.
|
|
158
91
|
|
|
159
|
-
|
|
160
|
-
- Never quote a user's identity as blame. The `u` field is for counting distinct affected users, not for naming anyone in the plan.
|
|
161
|
-
- If the ledger is empty or absent, skip band F silently - it is additive signal, never a gate.
|
|
92
|
+
Full procedure: `$HOME/.claude/multi-agent-refs/refactor/run-errors.md`. Read it when the ledger exists (record shape, grouping and ranking, transcript mining, band-F table).
|
|
162
93
|
|
|
163
94
|
## Step 0e: BACKLOG - friction this pipeline already noticed
|
|
164
95
|
|
|
@@ -32,7 +32,7 @@ Read `$HOME/.claude/multi-agent-refs/analysis/review.md` and execute it:
|
|
|
32
32
|
|
|
33
33
|
## Why it cites Locked decisions
|
|
34
34
|
|
|
35
|
-
The analysis flow already declares
|
|
35
|
+
The analysis flow already declares 37 Locked decisions and two deterministic validators. A reviewer that says "I would have written this differently" gives the author nothing to act on; one that says "Locked 33: the Confluence page is in the evidence record but not in Section 21" gives them a fix and a reason. Findings that map to no rule are still allowed, but they are marked as judgement, not dressed up as a violation.
|
|
36
36
|
|
|
37
37
|
## What it never does
|
|
38
38
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Audit test scenarios from a CSV against the code: mark each PRESENT, PARTIAL, ABSENT or UNCLEAR, every PRESENT backed by a file:line that resolves at HEAD. Read-only. Use when a test set or acceptance list has to be checked against what the code does."
|
|
3
|
+
description-tr: "Test senaryolarını koda karşı denetler: CSV'deki (ya da CSV'ye aktarılmış Jira test setindeki) her senaryo için kodun onu nerede karşıladığını bulur ve VAR, KISMEN, YOK ya da BELİRSİZ olarak işaretler; her VAR, HEAD'de çözülen bir dosya:satır ile desteklenir. Salt-okunur."
|
|
4
|
+
allowed-tools: Bash, Read, Grep, AskUserQuestion
|
|
5
|
+
argument-hint: "<scenarios.csv> [--repo <path>]"
|
|
6
|
+
parameters: [{"name":"scenarios","kind":"path","required":true},{"name":"--repo","kind":"path"}]
|
|
7
|
+
gui: form
|
|
8
|
+
destructive: false
|
|
9
|
+
confirm: none
|
|
10
|
+
not-for: test, manual-test, review
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# multi-agent scenario-audit
|
|
14
|
+
|
|
15
|
+
**Input**: $ARGUMENTS
|
|
16
|
+
|
|
17
|
+
Checks a list of test scenarios against a repository and says, per scenario,
|
|
18
|
+
whether the code implements it. The judgement is yours; the evidence rule is
|
|
19
|
+
the script's. Nothing is written and nothing leaves the machine.
|
|
20
|
+
|
|
21
|
+
Script: `$HOME/.claude/scripts/scenario-audit.mjs`.
|
|
22
|
+
|
|
23
|
+
## Gotchas
|
|
24
|
+
|
|
25
|
+
- A verdict without a resolving `file:line` is not PRESENT. `verify` turns it into UNCLEAR and says why; do not argue with it, find the line.
|
|
26
|
+
- ABSENT is a claim about a search. Record the terms you searched; an ABSENT with no terms becomes UNCLEAR.
|
|
27
|
+
- Scenario text is usually business language and the code is not. Search for identifiers, localization keys, endpoint paths and error codes, not for the scenario's words.
|
|
28
|
+
- The audit reads HEAD. Uncommitted work is not seen; say so when the working tree is dirty.
|
|
29
|
+
|
|
30
|
+
## Step 1 - Inventory
|
|
31
|
+
|
|
32
|
+
The scenarios file is a CSV with an id column and a title column (`id`/`no`/`key`,
|
|
33
|
+
`title`/`scenario`/`senaryo`/`başlık`; optional `steps`/`adımlar` and
|
|
34
|
+
`expected`/`beklenen`). Comma or semicolon. A Jira test set is exported to this
|
|
35
|
+
shape first.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
node "$HOME/.claude/scripts/scenario-audit.mjs" inventory --csv "<scenarios.csv>" > /tmp/ma-scenarios.json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Exit 2 names the missing column. With no `--repo`, the repository is the
|
|
42
|
+
current directory; confirm it in one line before searching.
|
|
43
|
+
|
|
44
|
+
## Step 2 - Search
|
|
45
|
+
|
|
46
|
+
For each scenario, write the code-level terms that would implement it into
|
|
47
|
+
`/tmp/ma-terms.json` (`{"<id>": ["term", ...]}`), then:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
node "$HOME/.claude/scripts/scenario-audit.mjs" search --terms /tmp/ma-terms.json --repo "<repo>"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Read the candidate lines it returns. A term nothing matched is listed under
|
|
54
|
+
`missing`; try a second term before concluding anything.
|
|
55
|
+
|
|
56
|
+
## Step 3 - Verdict
|
|
57
|
+
|
|
58
|
+
Write `/tmp/ma-verdicts.json`: `[{id, status, citations, searched, note}]`.
|
|
59
|
+
|
|
60
|
+
| Status | When | Needs |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `PRESENT` | the code does what the scenario expects | `citations`: the `file:line` that does it |
|
|
63
|
+
| `PARTIAL` | part of it, e.g. the happy path without the error case | `citations`, and `note` saying what is missing |
|
|
64
|
+
| `ABSENT` | nothing implements it | `searched`: the terms that found nothing relevant |
|
|
65
|
+
| `UNCLEAR` | the code exists but its behaviour cannot be told from reading | `note` |
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
node "$HOME/.claude/scripts/scenario-audit.mjs" verify --csv "<scenarios.csv>" \
|
|
69
|
+
--verdicts /tmp/ma-verdicts.json --repo "<repo>" --lang "<outputLanguage>"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Step 4 - Report
|
|
73
|
+
|
|
74
|
+
Print the table `verify` produced, verbatim, and its count line. Then the
|
|
75
|
+
scenarios that moved to UNCLEAR during verification, with the reason. State
|
|
76
|
+
which verdicts rest on a resolved citation (mechanical) and that the reading of
|
|
77
|
+
the code behind them is judgement.
|
|
78
|
+
|
|
79
|
+
**Stop. No issue, no comment, no worktree.**
|
|
@@ -56,7 +56,10 @@ Or leave it: it exits on its own when idle.
|
|
|
56
56
|
## What it will not do
|
|
57
57
|
|
|
58
58
|
There is no route that merges, marks ready, runs a command or starts a host.
|
|
59
|
-
`POST /v1/launch`
|
|
60
|
-
|
|
59
|
+
`POST /v1/launch` and `POST /v1/runs/{id}/resume` return the argv and
|
|
60
|
+
environment `launch.json` declares; the client starts the process.
|
|
61
61
|
`POST /v1/runs/{id}/answer` accepts only an option the run's pending question
|
|
62
|
-
offered.
|
|
62
|
+
offered. `POST /v1/runs/{id}/kill` and `POST /v1/gc` act only on a second
|
|
63
|
+
request carrying the single-use confirm token the first one returned, and a
|
|
64
|
+
kill never deletes the remote branch or the logs. Autopilot can be turned off
|
|
65
|
+
over HTTP, never on.
|
|
@@ -9,6 +9,13 @@ confirm: none
|
|
|
9
9
|
allowed-tools: Bash, Read, Write, AskUserQuestion, WebFetch
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## Gotchas
|
|
13
|
+
|
|
14
|
+
- A token is read and written only through `~/.claude/lib/credential-store.sh`. Never echo it, never pass it on argv, never paste it back to the user.
|
|
15
|
+
- A mapping in `keychainMapping` with no value in the store is not onboarded: offer the Token Save Flow, do not ask for the secret in chat.
|
|
16
|
+
- Hosts are stored without a scheme (`jira.example.com`); the callers add `https://`.
|
|
17
|
+
- Publishing tokens differ by registry: npmjs takes an npm token, GitHub Packages a classic PAT with `write:packages` from the account that owns the scope.
|
|
18
|
+
|
|
12
19
|
## Step 0 - What is actually wrong
|
|
13
20
|
|
|
14
21
|
```bash
|
|
@@ -89,88 +96,7 @@ command -v pdftotext >/dev/null 2>&1 || echo "pdftotext: MISSING"
|
|
|
89
96
|
|
|
90
97
|
### Step 1 - Dynamic Credential Discovery
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
**1a. Discover all keys:**
|
|
95
|
-
```bash
|
|
96
|
-
DISCOVERED=$(~/.claude/lib/credential-store.sh list 2>/dev/null | grep -i "^${USER}" | sort -u)
|
|
97
|
-
echo "$DISCOVERED"
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
**1b. Search keywords (per service):**
|
|
101
|
-
|
|
102
|
-
Standard key names - the ones to use when creating a NEW key - live in `$HOME/.claude/multi-agent-refs/keychain.md` "Standard key names"; read the name for a service from there. Existing keys under other names are perfectly valid, which is what these keywords are for.
|
|
103
|
-
|
|
104
|
-
| Service ID | Search Keywords |
|
|
105
|
-
|------------|-----------------|
|
|
106
|
-
| `jira` | `jira` |
|
|
107
|
-
| `bitbucket_token` | `bitbucket` + (`token` or `access` or `pass`) |
|
|
108
|
-
| `bitbucket_user` | `bitbucket` + (`user` or `name`) |
|
|
109
|
-
| `github` | `github` or `gh` (exclude `ssh`) |
|
|
110
|
-
| `confluence` | `confluence` |
|
|
111
|
-
| `figma` | `figma` + (`token` or `pat` or `access`) + NOT `mcp` |
|
|
112
|
-
| `figma_mcp` | `figma` + `mcp` |
|
|
113
|
-
| `fortify` | `fortify` |
|
|
114
|
-
| `graylog` | `graylog` |
|
|
115
|
-
| `graylog_test` | `graylog` + `test` |
|
|
116
|
-
| `firebase` | `firebase` (any variant: `sa`, `service`, `account`, `access`, `json`) |
|
|
117
|
-
| `jenkins` | `jenkins` |
|
|
118
|
-
| `appstore_connect_key_id` | (`appstore` or `asc` or `app_store`) + (`key` or `keyid`) |
|
|
119
|
-
| `appstore_connect_issuer_id` | (`appstore` or `asc` or `app_store`) + `issuer` |
|
|
120
|
-
| `appstore_connect_private_key` | (`appstore` or `asc` or `app_store`) + (`private` or `p8`) |
|
|
121
|
-
| `appstore_connect_apple_id` | (`appstore` or `asc`) + (`apple` or `account` or `user`) |
|
|
122
|
-
| `appstore_connect_password_item` | (`appstore` or `asc` or `altool`) + (`password` or `app_specific`) |
|
|
123
|
-
| `google_play` | (`googleplay` or `google_play` or `play_console` or `play`) + (`service` or `account` or `access` or `json` or `console`), NOT `firebase` |
|
|
124
|
-
|
|
125
|
-
> Multi-agent setup onboards **both** Figma tokens because the pipeline's 3-tier Figma access chain (see `$HOME/.claude/rules/figma-pipeline.md`) uses them in priority order: Tier 1 = MCP (`figma_mcp`), Tier 2 = REST PAT (`figma`), Tier 3 = user screenshot fallback. Missing either token forces a downshift; missing both leaves Tier 3 as the only path. The Tier 2 logical key is `figma`, not `figma_pat`: `figma_pat` is the pre-v13.6 name that `migrate-prefs.mjs` consolidates away, and writing a new mapping under it means the next migration deletes it.
|
|
126
|
-
|
|
127
|
-
> The five App Store Connect entries are **iOS-only and optional** - skipping them all reports Gate 2 of `/multi-agent:store-ready` as `SKIPPED`, never as a pass. Two hold identifiers, one an email, one a keychain ITEM NAME, and `appstore_connect_private_key` the `.p8` itself; all go through the mapping layer. `google_play` is the Android-only counterpart (Step 3d). Tiers and mechanics: Step 3b and `$HOME/.claude/multi-agent-refs/setup/app-store-connect.md`.
|
|
128
|
-
|
|
129
|
-
> The `firebase` entry is **optional and any-platform**. Discovery maps a stored service-account JSON like any other credential but cannot see what decides whether Crashlytics is readable: a fresh `firebase-adminsdk-*` account authenticates perfectly and holds no Crashlytics role. Step 3c measures the tier rather than assuming it.
|
|
130
|
-
|
|
131
|
-
**1c. Resolution logic (per service):**
|
|
132
|
-
|
|
133
|
-
For each service in the table above, follow this order:
|
|
134
|
-
|
|
135
|
-
1. **Check standard key** -> `~/.claude/lib/credential-store.sh get "<standard_key>" 2>/dev/null`
|
|
136
|
-
- Found (non-empty stdout, exit 0) -> auto-map, done
|
|
137
|
-
3. **Search discovered keys** -> filter `$DISCOVERED` by the service's search keywords (case-insensitive)
|
|
138
|
-
- Exactly 1 match -> show: `"Found '${matched_key}' for ${service} - use this? (enter=yes / n=skip)"` -> if yes, map it
|
|
139
|
-
- Multiple matches -> show numbered list, user picks:
|
|
140
|
-
```
|
|
141
|
-
Multiple keys found for GitHub:
|
|
142
|
-
1. ${USER}_Github
|
|
143
|
-
2. ${USER}_Github_Access_Token_Old
|
|
144
|
-
3. ${USER}_Github_Access_Token
|
|
145
|
-
Select [number] or skip:
|
|
146
|
-
```
|
|
147
|
-
- 0 keyword matches -> go to Step 4
|
|
148
|
-
4. **Suggest candidates from full keychain** -> When keyword search yields 0 results, do NOT immediately mark as MISSING. Show broad candidates from `$DISCOVERED_ALL` and ask the user:
|
|
149
|
-
```
|
|
150
|
-
No exact match found for Jira in your keychain.
|
|
151
|
-
|
|
152
|
-
These entries might be your Jira token - do any look right?
|
|
153
|
-
1. MyPersonalJiraToken
|
|
154
|
-
2. work_jira_pat
|
|
155
|
-
3. JiraPAT_2024
|
|
156
|
-
n. None of these (skip)
|
|
157
|
-
|
|
158
|
-
Select [number] or n to skip:
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Candidate selection:
|
|
162
|
-
- Show entries that partially match the service name, common token suffixes (`token`, `pat`, `key`, `secret`, `access`, `password`), or relaxed keyword matching (substring instead of prefix)
|
|
163
|
-
- Exclude entries already mapped to other services and system entries (Apple, com.apple.*, iCloud, etc.)
|
|
164
|
-
- Cap at 10 candidates, sorted by relevance (shortest edit distance to service keywords)
|
|
165
|
-
- If 0 candidates even after broad search -> MISSING (truly not in keychain)
|
|
166
|
-
|
|
167
|
-
**Important:** Steps 3-4 search the FULL `$DISCOVERED` list (both passes from 1a), not just user-prefixed entries. This catches tokens saved under any naming convention.
|
|
168
|
-
|
|
169
|
-
**1d. Check preferences for existing mapping:**
|
|
170
|
-
|
|
171
|
-
Before running discovery, check `prefs.global.keychainMapping`. If a mapping already exists for a service AND the mapped key still exists in Keychain -> skip discovery for that service (show as already mapped from preferences).
|
|
172
|
-
|
|
173
|
-
If a previously mapped key NO LONGER exists in Keychain -> clear the stale mapping, re-run discovery for that service.
|
|
99
|
+
Full procedure: `$HOME/.claude/multi-agent-refs/setup/discovery.md`. Read it for Step 1.
|
|
174
100
|
|
|
175
101
|
### Step 2 - Show Discovery Summary + Save Mapping
|
|
176
102
|
|
|
@@ -294,131 +220,7 @@ Loop rules:
|
|
|
294
220
|
|
|
295
221
|
### Token Save Flow (reusable)
|
|
296
222
|
|
|
297
|
-
|
|
298
|
-
- **Setup Step 4** - for missing tokens during first-time onboarding
|
|
299
|
-
- **Phase 0 token pre-check** - when a token is missing or expired (401/403) at runtime
|
|
300
|
-
|
|
301
|
-
**Trigger**: token missing (`keychainMapping` is `null`) OR token expired (API returned 401/403).
|
|
302
|
-
|
|
303
|
-
**Step A - Ask** (options depend on whether the token is missing or expired):
|
|
304
|
-
|
|
305
|
-
Missing token (first-time / unmapped):
|
|
306
|
-
```
|
|
307
|
-
{Service} token missing.
|
|
308
|
-
Where to get it: {source URL/instructions}
|
|
309
|
-
|
|
310
|
-
[1] Add now - I'll generate the token and copy it
|
|
311
|
-
[2] Skip - I'll set it up later
|
|
312
|
-
|
|
313
|
-
Select:
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
Expired / rejected token (401 / 403 mid-run) - the Expired-token decision from `$HOME/.claude/multi-agent-refs/keychain.md` Rule 1:
|
|
317
|
-
```
|
|
318
|
-
{Service} token expired (the service returned 401/403).
|
|
319
|
-
Where to get a fresh one: {source URL/instructions}
|
|
320
|
-
|
|
321
|
-
[1] Regenerate - replace {KEY_NAME} in place, then retry
|
|
322
|
-
[2] Use a different token - map another Keychain entry, then retry
|
|
323
|
-
[3] Skip and continue - drop this source (halts only if the token is required for the input)
|
|
324
|
-
|
|
325
|
-
Select:
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
Render `question` + `label` + `description` in `outputLanguage`; `header` English. Names below are option semantics, not strings to print. The picked option is a choice, never the secret: the value enters via Step B clipboard.
|
|
329
|
-
|
|
330
|
-
- **Skip** (missing `[2]` / expired `[3]`) → skip semantics. During setup: `keychainMapping` stays `null`. During Phase 0 / mid-run: abort that service's contribution, warn and continue if non-critical, halt if critical (e.g. Jira token for Jira input).
|
|
331
|
-
- **Add now** / **Regenerate** → proceed to Step B (clipboard save). Regenerate reuses the same `{KEY_NAME}`.
|
|
332
|
-
- **Use a different token** → proceed to Step B, then re-run Step C identity binding for the new entry.
|
|
333
|
-
|
|
334
|
-
**Step B - Clipboard save** (token NEVER appears in terminal):
|
|
335
|
-
|
|
336
|
-
For PAT / API key / username:
|
|
337
|
-
```
|
|
338
|
-
Copy the token to your clipboard, then press Enter.
|
|
339
|
-
(Token will be read from clipboard and saved to Keychain automatically)
|
|
340
|
-
|
|
341
|
-
Press Enter when ready...
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
Pipeline runs silently - value is piped via stdin (`-` sentinel) so it never lands on argv / shell history:
|
|
345
|
-
```bash
|
|
346
|
-
pbpaste | ~/.claude/lib/credential-store.sh set "<KEY_NAME>" -
|
|
347
|
-
pbcopy < /dev/null
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
(The shell driver auto-delegates to `~/.claude/scripts/keychain.py`, which writes both `-l` (label) and `-s` (service) attributes so callers using either convention find the same entry.)
|
|
351
|
-
|
|
352
|
-
For JSON file (Firebase) - same clipboard flow, JSON content never lands in argv or shell history:
|
|
353
|
-
```
|
|
354
|
-
Open the Service Account JSON, copy its FULL contents to your clipboard,
|
|
355
|
-
then press Enter.
|
|
356
|
-
(Contents are saved to the Keychain exactly as issued)
|
|
357
|
-
|
|
358
|
-
Press Enter when ready...
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
The pipeline then runs the same `pbpaste | ... set "<KEY_NAME>" -` and `pbcopy < /dev/null` as above. A key that arrives as a file (the App Store Connect `.p8`, the Google Play JSON) skips the clipboard: `set <key> - < <file>`.
|
|
362
|
-
|
|
363
|
-
**Firebase repeats per project.** Teams own several Firebase projects (legacy plus redesign, staging plus prod), each with its own key, and a crash URL from the second one used to fail the `project_id` check as if it were misconfigured. After each saved key, read `project_id` from the stored JSON (never ask) and offer another round: `Saved: <project_id>. Add another Firebase project? [y/N]`.
|
|
364
|
-
|
|
365
|
-
- Every key appends `{projectId, keychainKey, label?}` to `prefs.global.firebase.accounts`; the first one also fills `keychainMapping.firebase`, so a one-project setup is unchanged.
|
|
366
|
-
- Keys after the first are named `${USER}_Firebase_Access_Json_<projectId>` so they cannot collide.
|
|
367
|
-
- At run time `fetch-crashlytics.sh` picks the account matching the console URL's projectId, falling back to `keychainMapping.firebase`.
|
|
368
|
-
|
|
369
|
-
For GitHub (special case):
|
|
370
|
-
```
|
|
371
|
-
! gh auth login
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
**Step C - Identity binding** (after token saved):
|
|
375
|
-
|
|
376
|
-
```
|
|
377
|
-
✓ Saved to Keychain as <KEY_NAME>
|
|
378
|
-
✓ Clipboard cleared
|
|
379
|
-
|
|
380
|
-
Which git identity uses this token?
|
|
381
|
-
|
|
382
|
-
Existing identities:
|
|
383
|
-
1. Ada Lovelace <ada@example.com>
|
|
384
|
-
2. Ada Lovelace <ada@personal.com>
|
|
385
|
-
n. Create new identity
|
|
386
|
-
|
|
387
|
-
Select:
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
- Existing identity selected → add `{service}: <KEY_NAME>` to that identity's `servicePatMap`
|
|
391
|
-
- `n` (create new) → ask name + email → create identity → add to `prefs.global.identities[]` → map token
|
|
392
|
-
- First token ever (no identities exist) → skip picker, go straight to name + email
|
|
393
|
-
- `bitbucket_user` is excluded from identity binding (it's a username, not a PAT)
|
|
394
|
-
|
|
395
|
-
**Step D - Confirm + update**:
|
|
396
|
-
|
|
397
|
-
```
|
|
398
|
-
✓ Token mapped to identity: Ada Lovelace <ada@example.com>
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
Update `prefs.global.keychainMapping.{service}` with the key name.
|
|
402
|
-
Update `identity.servicePatMap.{service}` with the key name.
|
|
403
|
-
Update `serviceStatus.{service} = { ok: true, checkedAt: <now> }`.
|
|
404
|
-
|
|
405
|
-
**→ Next: if `{service}` is `jira` / `confluence` / `bitbucket` / `fortify` / `graylog` AND the corresponding
|
|
406
|
-
`prefs.global.hosts.{service}` is unset, run Step 3.5 (Host Prompt) inline before
|
|
407
|
-
the Auto-routing rule below. required - the pipeline cannot build API URLs without
|
|
408
|
-
the host. Firebase is exempt (see Step 3.5).**
|
|
409
|
-
|
|
410
|
-
**Auto-routing rule** (optional, on first token per platform):
|
|
411
|
-
|
|
412
|
-
If `platformIdentityRouting` has no rule for this platform yet, auto-suggest one:
|
|
413
|
-
```
|
|
414
|
-
Auto-add routing rule?
|
|
415
|
-
bitbucket.example.com/* → Ada Lovelace <ada@example.com>
|
|
416
|
-
[enter=yes / n=skip]
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
This builds `platformIdentityRouting` incrementally - no separate Step 7 needed for most users.
|
|
420
|
-
|
|
421
|
-
---
|
|
223
|
+
Full procedure: `$HOME/.claude/multi-agent-refs/setup/token-save-flow.md`. Read it for every token prompt (Steps 3, 3b, 3c and any command that saves a token).
|
|
422
224
|
|
|
423
225
|
### Step 3b - App Store Connect onboarding (iOS only, optional)
|
|
424
226
|
|
|
@@ -434,81 +236,7 @@ Runs inside Step 3, only when the target repo is Android. One entry, `google_pla
|
|
|
434
236
|
|
|
435
237
|
### Step 3.5 - Host Prompt (embedded in Token Save Flow)
|
|
436
238
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
Right after Step D (identity mapping confirmed), ask:
|
|
440
|
-
|
|
441
|
-
```
|
|
442
|
-
Service host - needed to build API URLs for this token.
|
|
443
|
-
|
|
444
|
-
{Service} host (e.g. jira.example.com): ___
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
Save to `prefs.global.hosts.{service}`. For Fortify, also ask `Fortify project version ids (optional, comma-separated - e.g. 1234,5678)` → `prefs.global.fortify.versionIds`. A ticket naming only an instance id carries no version, so the lookup silently no-ops without these; URL-referenced findings resolve either way.
|
|
448
|
-
|
|
449
|
-
For Jira, **discover the project keys instead of asking the user to recall them.** The token is already saved and the host is already known, so ask Jira which projects this person actually works in - a corporate instance has thousands of projects, and a typed key is a typo waiting to route branches and new issues at the wrong board:
|
|
450
|
-
|
|
451
|
-
```bash
|
|
452
|
-
printf 'Authorization: Bearer %s\n' "$TOKEN" | curl -s -H @- \
|
|
453
|
-
"https://{JIRA_HOST}/rest/api/2/search?jql=assignee%3DcurrentUser()%20OR%20reporter%3DcurrentUser()%20ORDER%20BY%20updated%20DESC&fields=project&maxResults=100" \
|
|
454
|
-
| jq -r '[.issues[].fields.project | "\(.key)\t\(.name)"] | unique | .[]'
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
Present the distinct keys, most-recently-worked first, as a picker; fall back to the free-text prompt `Default Jira project key (e.g. PROJ)` when the call fails or returns nothing (no VPN, fresh account). The picked key → `prefs.global.defaultJiraKey`. From the Jira host, derive `corpDomain` (`jira.example.com` → `example.com`) and pre-fill it so the Confluence / Bitbucket prompts only need the subdomain.
|
|
458
|
-
|
|
459
|
-
`defaultJiraKey` is a single global fallback, but one Jira host usually serves several repos with DIFFERENT keys, so the pass continues with a per-repo mapping. Show the repos, and let the key come from the discovered list rather than being typed again:
|
|
460
|
-
|
|
461
|
-
```
|
|
462
|
-
Per-repo Jira keys (optional) - repos whose project key differs from {defaultJiraKey}:
|
|
463
|
-
|
|
464
|
-
[ ] 1. my-ios-app (current: PROJA)
|
|
465
|
-
[ ] 2. my-other-app (current: - )
|
|
466
|
-
|
|
467
|
-
Toggle repos, then pick a project for each - discovered: PROJA, PROJB, PROJC. Enter to skip.
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
- The repo list comes from `prefs.projects` + `recentProjects` (when Step 5 already ran); a free-text repo path is accepted for repos not discovered yet, and a free-text key for a project the search did not surface.
|
|
471
|
-
- Each answer is PREPENDED to `prefs.projects[{slug}].jiraProjectKeys` (deduped, max 10 per schema). Example: `my-ios-app` → `PROJA`, `my-other-app` → `PROJB` - two repos on the same Jira host, two different project keys.
|
|
472
|
-
- Resolution order everywhere a Jira key is needed (placeholder replacement, branch names, new-issue creation): `prefs.projects[{slug}].jiraProjectKeys[0]` first, `global.defaultJiraKey` as fallback.
|
|
473
|
-
- **Re-run / update**: `/multi-agent:setup jira-keys` re-opens only this mapping without touching tokens or hosts.
|
|
474
|
-
|
|
475
|
-
Resulting shape:
|
|
476
|
-
|
|
477
|
-
```json
|
|
478
|
-
{
|
|
479
|
-
"global": {
|
|
480
|
-
"hosts": {
|
|
481
|
-
"jira": "jira.example.com",
|
|
482
|
-
"confluence": "confluence.example.com",
|
|
483
|
-
"bitbucket": "bitbucket.example.com",
|
|
484
|
-
"fortify": "ssc.example.com",
|
|
485
|
-
"graylog": "graylog.example.com",
|
|
486
|
-
"graylogTest": "graylog-test.example.com",
|
|
487
|
-
"corpDomain": "example.com"
|
|
488
|
-
},
|
|
489
|
-
"defaultJiraKey": "PROJ"
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
Placeholders `{JIRA_HOST}`, `{CONFLUENCE_HOST}`, `{BITBUCKET_HOST}`, `{FORTIFY_HOST}`, `{GRAYLOG_HOST}`, `{GRAYLOG_TEST_HOST}`, `{CORP_DOMAIN}`, `{JIRA_KEY}` in skills/commands are resolved from this block at runtime. If a host is ever missing when a phase needs it, Phase 0 prompts the same Host Prompt inline.
|
|
495
|
-
|
|
496
|
-
Graylog uses a **PAT** whose API auth is HTTP Basic with the token as username and the literal `token` as password - no separate username entry. It is optional by the null-mapping convention: `keychainMapping.graylog` or `hosts.graylog` left `null` degrades the log fetch to empty and never blocks a run.
|
|
497
|
-
|
|
498
|
-
Graylog is asked **twice** - test and production are separate instances, and a tester-minted trx id does not exist in production. After the production host:
|
|
499
|
-
|
|
500
|
-
```
|
|
501
|
-
Graylog test host (optional - Enter to skip): ___
|
|
502
|
-
Does the test instance use a different token? [y/N]
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
Test host → `hosts.graylogTest` (`{GRAYLOG_TEST_HOST}`); skipped means production-only search, which degrades nothing. Yes to the token question runs one more Token Save Flow pass for `graylog_test`; no (default) leaves it null and the fetcher reuses the production key. Run-time order is `--env auto`: production first, test on empty or unreachable, and the payload names which answered.
|
|
506
|
-
|
|
507
|
-
**Re-run / update**: `/multi-agent:setup hosts` re-opens the prompt to edit values without touching tokens.
|
|
508
|
-
|
|
509
|
-
Team-sharing note: Hosts are the only corporate metadata the pipeline needs. Tokens live in macOS Keychain (encrypted, never on disk inside the repo). Preferences file lives in `~/.claude/` - fully outside the repo clone. A teammate cloning the repo runs `/multi-agent:setup` once; host + token prompts run naturally together.
|
|
510
|
-
|
|
511
|
-
---
|
|
239
|
+
Full procedure: `$HOME/.claude/multi-agent-refs/setup/token-save-flow.md`. Read it for the host question inside the Token Save Flow.
|
|
512
240
|
|
|
513
241
|
### Step 3.6 - Per-account host overrides (optional)
|
|
514
242
|
|
|
@@ -635,64 +363,7 @@ Repo identifiers in the label are the human label from `recentProjects` (basenam
|
|
|
635
363
|
|
|
636
364
|
### Step 7 - Platform Identity Routing (optional)
|
|
637
365
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
Auto-skipped if `identities` has fewer than 2 entries (single-identity case has nothing to route).
|
|
641
|
-
|
|
642
|
-
**9a. Auto-suggest from `servicePatMap` ownership**
|
|
643
|
-
|
|
644
|
-
For each identity, derive a default routing rule from where its PATs work:
|
|
645
|
-
- Identity owns `bitbucket` PAT → propose `<bitbucket-host>/*` glob, mapped to that identity.
|
|
646
|
-
- Identity owns `github` PAT → propose `github.com/<gh-username>/*` if known (from `identities[].username`), else `github.com/*`.
|
|
647
|
-
- Identity owns `confluence` / `jira` only → no URL routing applies (those aren't repo origins) - skip.
|
|
648
|
-
|
|
649
|
-
Auto-suggestions are **proposals**, not forced. User confirms or edits each one.
|
|
650
|
-
|
|
651
|
-
**9b. Confirm or edit each suggested rule**
|
|
652
|
-
|
|
653
|
-
```
|
|
654
|
-
Step 7 - Platform Identity Routing (optional)
|
|
655
|
-
Auto-suggested rules:
|
|
656
|
-
|
|
657
|
-
1. bitbucket.{corp-domain}/* -> corporate [confirm/edit/skip]
|
|
658
|
-
2. github.com/{personal-username}/* -> personal [confirm/edit/skip]
|
|
659
|
-
3. github.com/{org-name}/* -> corporate [confirm/edit/skip]
|
|
660
|
-
|
|
661
|
-
Add another rule? [Add another / Done]
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
Each rule answer:
|
|
665
|
-
- `Enter` or `c` → confirm
|
|
666
|
-
- `e` → edit (prompt for new glob and/or new identity name)
|
|
667
|
-
- `s` → skip this rule
|
|
668
|
-
- `n` (final question) → finish
|
|
669
|
-
|
|
670
|
-
**9c. Save**
|
|
671
|
-
|
|
672
|
-
```json
|
|
673
|
-
{
|
|
674
|
-
"global": {
|
|
675
|
-
"platformIdentityRouting": {
|
|
676
|
-
"bitbucket.{corp-domain}/*": "corporate",
|
|
677
|
-
"github.com/{personal-username}/*": "personal",
|
|
678
|
-
"github.com/{org-name}/*": "corporate"
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
```
|
|
683
|
-
|
|
684
|
-
Glob matching semantics (Phase 0 implementation):
|
|
685
|
-
- `*` matches any characters except `/`
|
|
686
|
-
- `**` matches any characters including `/`
|
|
687
|
-
- Most-specific match wins (longer literal prefix > shorter)
|
|
688
|
-
- No match → Phase 0 falls back to the interactive identity picker
|
|
689
|
-
|
|
690
|
-
**9d. Skip / degrade rules**
|
|
691
|
-
|
|
692
|
-
- Zero rules saved is valid - Phase 0 always falls back to the identity picker.
|
|
693
|
-
- A rule may point to an identity name that doesn't (yet) exist in `identities`; on Phase 0 lookup, an unknown identity name surfaces as a warning and the picker is shown.
|
|
694
|
-
- Step 7 is idempotent - re-running merges new rules; existing rules are preserved unless the user explicitly edits them.
|
|
695
|
-
- Routing is **advisory**: the user can always override the auto-picked identity in Phase 0.
|
|
366
|
+
Full procedure: `$HOME/.claude/multi-agent-refs/setup/identity-routing.md`. Read it for Step 7.
|
|
696
367
|
|
|
697
368
|
### Cross-Platform Notes (Step 1-9)
|
|
698
369
|
|
|
@@ -729,31 +400,7 @@ pbpaste | ~/.claude/scripts/keychain.py set "<SERVICE_NAME>" -
|
|
|
729
400
|
|
|
730
401
|
### Figma MCP Setup (Remote / Local question)
|
|
731
402
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
```
|
|
735
|
-
Figma MCP mode?
|
|
736
|
-
|
|
737
|
-
[1] Remote - mcp.figma.com, OAuth token (figu_) (recommended)
|
|
738
|
-
[2] Local - @anthropic-ai/figma-mcp via npx, uses the Figma PAT
|
|
739
|
-
```
|
|
740
|
-
|
|
741
|
-
**Remote** (`figu_` OAuth token - generate it FOR the current user, never just point at docs):
|
|
742
|
-
- No OAuth app and no client_id/secret needed: Dynamic Client Registration against `api.figma.com/v1/oauth/mcp/register` + PKCE, the browser opens, the user clicks Allow, and the resulting access + refresh token pair is saved to the credential store under a name the user confirms. Map that entry to `keychainMapping.figma_mcp` (Token Save Flow Step D applies as usual).
|
|
743
|
-
- If `prefs.global.figmaMcp.remoteGeneratorScript` is set, run that script - it drives the whole flow end to end (registration, browser, keychain save) for the current user. Otherwise guide the flow inline.
|
|
744
|
-
- Renewal is silent afterwards via `$HOME/.claude/lib/figma-mcp-refresh.sh` (refresh token). Never echo token values.
|
|
745
|
-
|
|
746
|
-
**Local** (PAT-based):
|
|
747
|
-
- Validates the Figma PAT against the REST API, saves it to the credential store (reusing the `figma` mapping when present), and writes the `@anthropic-ai/figma-mcp` server block into Claude Code `settings.json` `mcpServers`:
|
|
748
|
-
```bash
|
|
749
|
-
# stdin sentinel keeps the value out of shell history
|
|
750
|
-
pbpaste | ~/.claude/scripts/keychain.py set "${USER}_Figma_Access_Token" -
|
|
751
|
-
pbcopy < /dev/null
|
|
752
|
-
# then: ~/.claude/settings.json -> mcpServers -> figma
|
|
753
|
-
```
|
|
754
|
-
- If `prefs.global.figmaMcp.localGeneratorScript` is set, run that script instead.
|
|
755
|
-
|
|
756
|
-
Choosing Remote does NOT skip the `figma` PAT pass (Tier 2 still uses the PAT); choosing Local leaves `keychainMapping.figma_mcp` null and Tier 1 unavailable until Remote is onboarded.
|
|
403
|
+
Full procedure: `$HOME/.claude/multi-agent-refs/setup/figma.md`. Read it for the Figma MCP question.
|
|
757
404
|
|
|
758
405
|
### Security Rules
|
|
759
406
|
|