@mmerterden/multi-agent-pipeline 13.5.0 → 14.0.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 +243 -0
- package/README.md +3 -3
- package/docs/features.md +1 -1
- package/install/_common.mjs +73 -0
- package/install/_mcp-register.mjs +70 -31
- package/install/_plugin-skills.mjs +73 -14
- package/install/claude.mjs +28 -4
- package/install/codex.mjs +33 -2
- package/install/copilot.mjs +145 -9
- package/install/index.mjs +10 -6
- package/install/templates/copilot-instructions.md +1 -1
- package/package.json +1 -1
- package/pipeline/agents/code-reviewer.md +58 -1
- package/pipeline/commands/multi-agent/SKILL.md +7 -5
- package/pipeline/commands/multi-agent/analysis/SKILL.md +7 -7
- package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/build-optimize/SKILL.md +7 -7
- package/pipeline/commands/multi-agent/channels/SKILL.md +5 -5
- package/pipeline/commands/multi-agent/dev/SKILL.md +23 -18
- package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +19 -13
- package/pipeline/commands/multi-agent/dev-local/SKILL.md +14 -12
- package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +17 -12
- package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/help/SKILL.md +4 -4
- package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +4 -4
- package/pipeline/commands/multi-agent/resume/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/review/SKILL.md +5 -5
- package/pipeline/commands/multi-agent/scan/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/search/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/setup/SKILL.md +6 -6
- package/pipeline/commands/multi-agent/{finish → ship}/SKILL.md +12 -12
- package/pipeline/commands/multi-agent/testflight-validation/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/update/SKILL.md +5 -2
- package/pipeline/commands/sim-test.md +2 -2
- package/pipeline/lib/credential-store-resolver.sh +16 -0
- package/pipeline/lib/credential-store.sh +47 -4
- package/pipeline/lib/fetch-figma-annotations.sh +26 -28
- package/pipeline/lib/figma-screenshot.sh +28 -39
- package/pipeline/lib/figma-token.sh +63 -0
- package/pipeline/multi-agent-refs/analysis-template.md +1 -1
- package/pipeline/multi-agent-refs/android-guide.md +1 -1
- package/pipeline/multi-agent-refs/channels/issue-comment.md +1 -1
- package/pipeline/multi-agent-refs/component-dispatch.md +2 -2
- package/pipeline/multi-agent-refs/cross-cli-contract.md +4 -4
- package/pipeline/multi-agent-refs/features/dev-critic.md +2 -2
- package/pipeline/multi-agent-refs/features/model-fallback.md +35 -2
- package/pipeline/multi-agent-refs/features/plan-todos.md +1 -1
- package/pipeline/multi-agent-refs/features/repo-map.md +1 -1
- package/pipeline/multi-agent-refs/features/review-multi-repo.md +3 -3
- package/pipeline/multi-agent-refs/features/shadow-git.md +1 -1
- package/pipeline/multi-agent-refs/features/skill-conformance.md +116 -0
- package/pipeline/multi-agent-refs/features/verify-by-test.md +1 -1
- package/pipeline/multi-agent-refs/generate-issue.md +1 -1
- package/pipeline/multi-agent-refs/multi-repo-integration-build.md +1 -1
- package/pipeline/multi-agent-refs/phases/log-format.md +4 -4
- package/pipeline/multi-agent-refs/phases/modes.md +7 -7
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +13 -11
- package/pipeline/multi-agent-refs/phases/phase-1-analysis.md +17 -15
- package/pipeline/multi-agent-refs/phases/phase-2-planning.md +7 -7
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +28 -13
- package/pipeline/multi-agent-refs/phases/phase-4-review.md +90 -58
- package/pipeline/multi-agent-refs/phases/phase-5-test.md +7 -7
- package/pipeline/multi-agent-refs/phases/phase-6-commit.md +8 -8
- package/pipeline/multi-agent-refs/phases/phase-7-report.md +8 -8
- package/pipeline/multi-agent-refs/phases.md +13 -13
- package/pipeline/multi-agent-refs/progress-contract.md +2 -2
- package/pipeline/multi-agent-refs/rules.md +7 -5
- package/pipeline/multi-agent-refs/swiftui-guide.md +1 -1
- package/pipeline/multi-agent-refs/tracker-contract.md +16 -15
- package/pipeline/preferences-template.json +7 -1
- package/pipeline/rules/figma-pipeline.md +2 -2
- package/pipeline/schemas/agent-state.schema.json +333 -79
- package/pipeline/schemas/criteria-manifest.schema.json +228 -0
- package/pipeline/schemas/migrations/prefs-2.4.0-to-2.5.0.mjs +64 -0
- package/pipeline/schemas/prefs.schema.json +118 -262
- package/pipeline/schemas/reviewer-output.schema.json +48 -3
- package/pipeline/schemas/token-budget.json +34 -10
- package/pipeline/schemas/triage-output.schema.json +112 -27
- package/pipeline/scripts/cost-table.json +7 -4
- package/pipeline/scripts/gc-worktrees.sh +1 -1
- package/pipeline/scripts/gen-mode-dispatch.mjs +6 -6
- package/pipeline/scripts/match-skills.mjs +37 -4
- package/pipeline/scripts/migrate-prefs.mjs +88 -17
- package/pipeline/scripts/phase-tracker.sh +14 -3
- package/pipeline/scripts/pre-commit-check.sh +49 -2
- package/pipeline/scripts/skill-conformance.mjs +960 -0
- package/pipeline/scripts/smoke-schema-validation.sh +17 -4
- package/pipeline/scripts/uninstall.mjs +35 -9
- package/pipeline/scripts/validate-reviewer.mjs +108 -1
- package/pipeline/skills/.skill-manifest.json +1 -1
- package/pipeline/skills/.skills-index.json +36 -9
- package/pipeline/skills/shared/README.md +15 -12
- package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +1 -0
- package/pipeline/skills/shared/core/apple-archive-compliance/references/rules.yml +167 -0
- package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +1 -0
- package/pipeline/skills/shared/core/google-play-compliance/references/rules.yml +184 -0
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +10 -10
- package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +4 -4
- package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +3 -3
- package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +2 -2
- package/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +6 -5
- package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +7 -6
- package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +4 -3
- package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +2 -2
- package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +4 -4
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +5 -5
- package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +1 -1
- package/pipeline/skills/shared/core/{multi-agent-finish → multi-agent-ship}/SKILL.md +8 -8
- package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +44 -5
- package/pipeline/skills/shared/external/ios-coding-standard/modules/_TEMPLATE.yml +82 -0
- package/pipeline/skills/shared/external/ios-coding-standard/references/STANDARD.md +169 -10
- package/pipeline/skills/shared/external/ios-coding-standard/references/lint-local.sh +13 -1
- package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +335 -16
- package/pipeline/skills/skills-index.md +11 -8
|
@@ -75,7 +75,7 @@ Pipeline (after Phase 0) - shown as visual cards in terminal:
|
|
|
75
75
|
Modes:
|
|
76
76
|
|
|
77
77
|
(normal) Full 8 phases, Sonnet dev, Plan Approval Gate active, parallel review + Fable triage
|
|
78
|
-
--dev Fast: Init -> Dev(Opus) ->
|
|
78
|
+
--dev Fast: Init -> Dev(Opus) -> Review -> Test -> Commit -> Report
|
|
79
79
|
--local No worktree - works directly on local branch
|
|
80
80
|
autopilot Skip all confirmations INCLUDING plan gate, auto commit/PR
|
|
81
81
|
(EXCEPT Phase 7 channels menu - always pauses)
|
|
@@ -91,7 +91,7 @@ Dedicated commands (same as flags above):
|
|
|
91
91
|
/multi-agent:local-autopilot "task" = multi-agent "task" --local autopilot
|
|
92
92
|
/multi-agent:dev-local "task" = multi-agent "task" --dev --local
|
|
93
93
|
/multi-agent:dev-local-autopilot "task" = multi-agent "task" --dev --local autopilot
|
|
94
|
-
/multi-agent:
|
|
94
|
+
/multi-agent:ship [jira-id] [autopilot] Continue already-done LOCAL work: Review → Build+Test → PR → Jira analysis + test scenarios (no dev)
|
|
95
95
|
|
|
96
96
|
------------------------------------------------------------
|
|
97
97
|
|
|
@@ -318,7 +318,7 @@ Pipeline (Phase 0'dan sonra) - terminalde görsel kart olarak görünür:
|
|
|
318
318
|
Modlar:
|
|
319
319
|
|
|
320
320
|
(normal) Tam 8 faz, Sonnet dev, Plan Onay Kapısı aktif, paralel review + Fable triage
|
|
321
|
-
--dev Hızlı: Init -> Dev(Opus) ->
|
|
321
|
+
--dev Hızlı: Init -> Dev(Opus) -> Review -> Test -> Commit -> Report
|
|
322
322
|
--local Worktree yok - doğrudan local branch'te çalışır
|
|
323
323
|
autopilot Plan gate dahil tüm onayları atla, otomatik commit/PR
|
|
324
324
|
(İSTİSNA: Phase 7 channels menüsü - her zaman durur)
|
|
@@ -334,7 +334,7 @@ Dedicated komutlar (yukarıdaki flag'lerin eşdeğeri):
|
|
|
334
334
|
/multi-agent:local-autopilot "task" = multi-agent "task" --local autopilot
|
|
335
335
|
/multi-agent:dev-local "task" = multi-agent "task" --dev --local
|
|
336
336
|
/multi-agent:dev-local-autopilot "task" = multi-agent "task" --dev --local autopilot
|
|
337
|
-
/multi-agent:
|
|
337
|
+
/multi-agent:ship [jira-id] [autopilot] Lokalde biten işi sürdür: Review → Build+Test → PR → Jira teknik analiz + test senaryoları (dev yok)
|
|
338
338
|
|
|
339
339
|
------------------------------------------------------------
|
|
340
340
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Audit an iOS module against the shared coding-standard registry (
|
|
3
|
-
description-tr: "Bir iOS modulunu paylasilan kodlama-standardi registry'sine (
|
|
2
|
+
description: "Audit an iOS module against the shared coding-standard registry (99 stable-ID rules), produce a remediation plan, then hand off to dev/dev-local. Use for a standards pass on a module, or when a review needs rule IDs rather than opinions."
|
|
3
|
+
description-tr: "Bir iOS modulunu paylasilan kodlama-standardi registry'sine (99 sabit-ID kural) gore denetler, duzeltme plani cikarir, sonra dev/dev-local'e devreder. Bir modulde standart gecisi icin, ya da bir review'un gorus yerine kural ID'si istedigi durumda kullan."
|
|
4
4
|
argument-hint: "[module name or path]"
|
|
5
5
|
allowed-tools: Skill, Bash, Read, Edit, Write, AskUserQuestion
|
|
6
6
|
---
|
|
@@ -21,10 +21,10 @@ Run the full pipeline **without a worktree** and **with every confirmation skipp
|
|
|
21
21
|
| `/multi-agent:autopilot "task"` | 7 phases (no User Test) | ✅ | ❌ (autopilot) |
|
|
22
22
|
| `/multi-agent:local "task"` | 7 phases (no User Test) | ❌ | ✅ (interactive) |
|
|
23
23
|
| **`/multi-agent:local-autopilot "task"`** | **7 phases (no User Test)** | **❌** | **❌ (autopilot)** |
|
|
24
|
-
| `/multi-agent:dev "task"` | Init → Dev → Commit → Report | ✅ | ✅ |
|
|
25
|
-
| `/multi-agent:dev-autopilot "task"` | Init → Dev → Commit → Report | ✅ | ❌ |
|
|
26
|
-
| `/multi-agent:dev-local "task"` | Init → Dev → Commit → Report | ❌ | ✅ |
|
|
27
|
-
| `/multi-agent:dev-local-autopilot "task"` | Init → Dev → Commit → Report | ❌ | ❌ (fastest) |
|
|
24
|
+
| `/multi-agent:dev "task"` | Init → Dev → Review → Test → Commit → Report | ✅ | ✅ |
|
|
25
|
+
| `/multi-agent:dev-autopilot "task"` | Init → Dev → Review → Commit → Report | ✅ | ❌ |
|
|
26
|
+
| `/multi-agent:dev-local "task"` | Init → Dev → Review → Commit → Report | ❌ | ✅ |
|
|
27
|
+
| `/multi-agent:dev-local-autopilot "task"` | Init → Dev → Review → Commit → Report | ❌ | ❌ (fastest) |
|
|
28
28
|
|
|
29
29
|
## What changes
|
|
30
30
|
|
|
@@ -10,7 +10,7 @@ argument-hint: "[#id] - optional: task ID (e.g. #2). If omitted, the most rece
|
|
|
10
10
|
|
|
11
11
|
Resume a paused or failed task from the last successful phase.
|
|
12
12
|
|
|
13
|
-
> **Not the same as `/multi-agent:
|
|
13
|
+
> **Not the same as `/multi-agent:ship`.** `resume` continues a **tracked pipeline task** (needs its `agent-state.json`/worktree) from where it stopped. `/multi-agent:ship` takes **ad-hoc local work** on the current branch (no prior task required) and runs the pipeline tail - Review → Build+Test → PR → Jira report - over it.
|
|
14
14
|
|
|
15
15
|
## Steps
|
|
16
16
|
|
|
@@ -177,12 +177,12 @@ Scope note: a guide governs only files under its own directory - a guide found
|
|
|
177
177
|
|
|
178
178
|
**Claude Code (2 in parallel):**
|
|
179
179
|
- Agent 1: `claude-fable-5` → security + architecture
|
|
180
|
-
- Agent 2: `claude-sonnet-
|
|
180
|
+
- Agent 2: `claude-sonnet-5` → general quality
|
|
181
181
|
|
|
182
182
|
**Copilot CLI (3 in parallel):**
|
|
183
|
-
- Agent 1: `claude-opus-
|
|
183
|
+
- Agent 1: `claude-opus-5` → security + architecture (Fable 5 is not offered on Copilot CLI)
|
|
184
184
|
- Agent 2: `gpt-5.4` → edge cases, alternate perspective
|
|
185
|
-
- Agent 3: `claude-sonnet-
|
|
185
|
+
- Agent 3: `claude-sonnet-5` → general quality
|
|
186
186
|
|
|
187
187
|
Each reviewer receives the diff, the module review guides from Step 2b (when any were found), plus the standard reviewer system prompt (see `$HOME/.claude/multi-agent-refs/phases/phase-4-review.md` for the prompt contract). Output: structured `findings[]` per reviewer.
|
|
188
188
|
|
|
@@ -192,8 +192,8 @@ When release-relevant iOS/Android files change, load the matching catalog:
|
|
|
192
192
|
|
|
193
193
|
| Platform | Trigger files | Catalog |
|
|
194
194
|
|---|---|---|
|
|
195
|
-
| iOS | `**/Info.plist`, `**/PrivacyInfo.xcprivacy`, `**/*.entitlements`, `**/*App.swift`, `**/AppDelegate*.swift`, `**/SceneDelegate*.swift`, `**/project.pbxproj` |
|
|
196
|
-
| Android | `**/AndroidManifest.xml`, `**/build.gradle(.kts)`, `**/proguard-rules.pro`, `**/network_security_config.xml` |
|
|
195
|
+
| iOS | `**/Info.plist`, `**/PrivacyInfo.xcprivacy`, `**/*.entitlements`, `**/*App.swift`, `**/AppDelegate*.swift`, `**/SceneDelegate*.swift`, `**/project.pbxproj` | `$HOME/.claude/skills/apple-archive-compliance/SKILL.md` - 18 rules + ITMS refs |
|
|
196
|
+
| Android | `**/AndroidManifest.xml`, `**/build.gradle(.kts)`, `**/proguard-rules.pro`, `**/network_security_config.xml` | `$HOME/.claude/skills/google-play-compliance/SKILL.md` - 21 rules + Play policy refs |
|
|
197
197
|
|
|
198
198
|
Each finding gets the `ruleID` from the catalog plus the platform policy ref:
|
|
199
199
|
- iOS: `(apple-archive-compliance / info-plist - Guideline 5.1.1)`
|
|
@@ -45,7 +45,7 @@ A single command that scans `pipeline/skills/` (or optionally `~/.claude/skills/
|
|
|
45
45
|
|
|
46
46
|
1. **Run the script:**
|
|
47
47
|
```bash
|
|
48
|
-
bash "$
|
|
48
|
+
bash "$HOME/.claude/scripts/scan-skills.sh" $ARGUMENTS
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
2. **Interpret the output:**
|
|
@@ -103,10 +103,8 @@ These are the RECOMMENDED key names. When creating NEW keys, use these. But exis
|
|
|
103
103
|
| `bitbucket_user` | `${USER}_Bitbucket_Username` | `bitbucket` + (`user` or `name`) |
|
|
104
104
|
| `github` | `${USER}_Github_Access_Token` | `github` or `gh` (exclude `ssh`) |
|
|
105
105
|
| `confluence` | `${USER}_Confluence_Access_Token` | `confluence` |
|
|
106
|
-
| `
|
|
106
|
+
| `figma` | `${USER}_Figma_Access_Token` | `figma` + (`token` or `pat` or `access`) + NOT `mcp` |
|
|
107
107
|
| `figma_mcp` | `${USER}_Figma_Mcp_Access_Token` | `figma` + `mcp` |
|
|
108
|
-
|
|
109
|
-
> Multi-agent setup onboards **both** Figma tokens because the pipeline's 3-tier Figma access chain (see `pipeline/rules/figma-pipeline.md`) uses them in priority order: Tier 1 = MCP (`figma_mcp`), Tier 2 = REST PAT (`figma_pat`), Tier 3 = user screenshot fallback. Missing either token forces a downshift; missing both leaves Tier 3 as the only path.
|
|
110
108
|
| `fortify` | `${USER}_Fortify_Access_Token` | `fortify` |
|
|
111
109
|
| `graylog` | `${USER}_Graylog_Access_Token` | `graylog` |
|
|
112
110
|
| `firebase` | `${USER}_Firebase_Access_Json` | `firebase` (any variant: `sa`, `service`, `account`, `access`, `json`) |
|
|
@@ -116,6 +114,8 @@ These are the RECOMMENDED key names. When creating NEW keys, use these. But exis
|
|
|
116
114
|
| `appstore_connect_apple_id` | `${USER}_AppStoreConnect_Apple_Id` | (`appstore` or `asc`) + (`apple` or `account` or `user`) |
|
|
117
115
|
| `appstore_connect_password_item` | `${USER}_AppStoreConnect_Password_Item` | (`appstore` or `asc` or `altool`) + (`password` or `app_specific`) |
|
|
118
116
|
|
|
117
|
+
> 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.
|
|
118
|
+
|
|
119
119
|
> The four App Store Connect entries are **iOS-only and optional**: skip them all and the pipeline still works, it just reports Gate 2 of `/multi-agent:testflight-validation` as `SKIPPED` (never as a pass). They mirror the Figma 3-tier shape - Tier 1 = API key (`appstore_connect_key_id` + `appstore_connect_issuer_id`), Tier 2 = Apple ID + app-specific password (`appstore_connect_apple_id` + `appstore_connect_password_item`), Tier 3 = nothing configured. **Offer Tier 2 first when the user says they cannot create an API key**: creating one needs an Admin or App Manager role in App Store Connect, while an app-specific password is generated by the account holder at `appleid.apple.com` with no team permission at all. Two of these hold identifiers rather than secrets (key id, issuer id) and one holds a keychain ITEM NAME, not a password - they still go through the mapping layer so every credential is read the same way. Onboarding mechanics in Step 3b.
|
|
120
120
|
|
|
121
121
|
**1c. Resolution logic (per service):**
|
|
@@ -193,7 +193,7 @@ Save the resolved mapping to preferences:
|
|
|
193
193
|
"bitbucket_user": "${USER}_Bitbucket_Username",
|
|
194
194
|
"github": "${USER}_Github",
|
|
195
195
|
"confluence": null,
|
|
196
|
-
"
|
|
196
|
+
"figma": "${USER}_Figma_Access_Token",
|
|
197
197
|
"figma_mcp": "${USER}_Figma_Mcp_Access_Token",
|
|
198
198
|
"fortify": null,
|
|
199
199
|
"graylog": null,
|
|
@@ -761,7 +761,7 @@ Clipboard helpers (`pbpaste`, `pbcopy`) are macOS-specific - for Copilot CLI o
|
|
|
761
761
|
| `pbpaste` | `xclip -selection clipboard -o` (X11) or `wl-paste` (Wayland) | Install with `apt install xclip` or `apt install wl-clipboard` |
|
|
762
762
|
| `pbcopy < /dev/null` | `xclip -selection clipboard < /dev/null` or `wl-copy --clear` | Same intent: clear clipboard after token paste |
|
|
763
763
|
|
|
764
|
-
If you need to bypass the helper (debugging, raw inspection), the underlying platform commands are documented at the top of
|
|
764
|
+
If you need to bypass the helper (debugging, raw inspection), the underlying platform commands are documented at the top of `$HOME/.claude/lib/credential-store.sh`. Otherwise stay on the helper - it keeps secrets off argv (stdin sentinel `-`) and writes both `-l` and `-s` attributes on macOS.
|
|
765
765
|
|
|
766
766
|
If no backend is available, setup falls back to a plain-text prompt + a warning that the token is **not persisted** - pipeline phases will re-ask each session.
|
|
767
767
|
|
|
@@ -776,7 +776,7 @@ Standard key names (used when creating NEW tokens). Discovery may find existing
|
|
|
776
776
|
| `bitbucket_user` | `${USER}_Bitbucket_Username` | Plain text | Bitbucket profile username |
|
|
777
777
|
| `github` | `${USER}_Github_Access_Token` | PAT | GitHub Settings -> Tokens (scopes: repo, read:org, project) |
|
|
778
778
|
| `confluence` | `${USER}_Confluence_Access_Token` | PAT | Confluence -> Profile -> Personal Access Tokens (VPN required) |
|
|
779
|
-
| `
|
|
779
|
+
| `figma` | `${USER}_Figma_Access_Token` | PAT (Tier 2, REST API) | Figma Developer Settings (max 90 days). Token Save Flow prompt copy: "Figma Personal Access Token (for Tier 2)". |
|
|
780
780
|
| `figma_mcp` | `${USER}_Figma_Mcp_Access_Token` | OAuth (Tier 1, MCP) | Automatic via Claude Code Figma MCP remote auth. Token Save Flow prompt copy: "Figma MCP token (for Tier 1)". |
|
|
781
781
|
| `fortify` | `${USER}_Fortify_Access_Token` | API Token | Fortify SSC -> Token Management (VPN required) |
|
|
782
782
|
| `graylog` | `${USER}_Graylog_Access_Token` | PAT (API Basic `<token>:token`) | Graylog -> System -> Users and Teams -> Edit Tokens (VPN required). Auth is HTTP Basic with the token as username and literal `token` as password. |
|
|
@@ -4,11 +4,11 @@ description-tr: "Halihazırda bitmiş LOKAL işi pipeline kuyruğundan geçirir:
|
|
|
4
4
|
allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep, TaskCreate, TaskUpdate, TaskList, TaskGet, AskUserQuestion, WebFetch, WebSearch, Skill
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# multi-agent
|
|
7
|
+
# multi-agent ship - Take Existing Branch Work Through the Pipeline Tail
|
|
8
8
|
|
|
9
9
|
> **Language (read FIRST)**: Before any status output, read `prefs.global.outputLanguage` and render every conversational line in it. `AskUserQuestion` and external payloads stay English. Full contract: `$HOME/.claude/multi-agent-refs/rules.md` "Language Application".
|
|
10
10
|
|
|
11
|
-
You already did the work locally - wrote code on the current branch and maybe tested it by hand
|
|
11
|
+
You already did the work locally - wrote code on the current branch and maybe tested it by hand, or committed it outside the pipeline entirely. (As of v14.0.0 the `--dev` family reviews its own output, so this command is for work that had no pipeline run behind it, not a patch for a mode that skipped review.) `/multi-agent:ship` picks up from there and runs the **pipeline tail** over that existing local work in one command: parallel review, a build + test success gate, commit/push + PR, then the technical analysis and a **Jira comment with test scenarios**. It does NOT re-develop - Analysis / Planning / Dev (phases 1-3) are intentionally skipped; the diff already on the branch IS the input.
|
|
12
12
|
|
|
13
13
|
## When to use it
|
|
14
14
|
|
|
@@ -24,10 +24,10 @@ You already did the work locally - wrote code on the current branch and maybe
|
|
|
24
24
|
## Input
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
/multi-agent:
|
|
28
|
-
/multi-agent:
|
|
29
|
-
/multi-agent:
|
|
30
|
-
/multi-agent:
|
|
27
|
+
/multi-agent:ship # current branch vs its base; resolve Jira id from branch name
|
|
28
|
+
/multi-agent:ship PROJ-12345 # bind to an explicit Jira id for the Phase 7 comment
|
|
29
|
+
/multi-agent:ship --base develop # override the base branch for the diff
|
|
30
|
+
/multi-agent:ship autopilot # no gate prompts: auto-fix blocking findings, auto-PR, auto-comment
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## Pipeline
|
|
@@ -40,7 +40,7 @@ Phase 6: Commit → commit remaining local changes + push + open PR if no
|
|
|
40
40
|
Phase 7: Report → technical analysis + Jira comment with test scenarios (channels: Jira / PR / Confluence / Wiki)
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Phases 1-3 (Analysis / Planning / Dev) are skipped by design - `
|
|
43
|
+
Phases 1-3 (Analysis / Planning / Dev) are skipped by design - `ship` treats the current branch's local changes as the Phase 3 output.
|
|
44
44
|
|
|
45
45
|
## Phase 0 - Context resolution (finish-specific)
|
|
46
46
|
|
|
@@ -54,10 +54,10 @@ Phases 1-3 (Analysis / Planning / Dev) are skipped by design - `finish` treats
|
|
|
54
54
|
|
|
55
55
|
- **Phase 4 Review** - run per `$HOME/.claude/multi-agent-refs/phases/phase-4-review.md` against the resolved diff: deterministic gates (Step 1.x), stack-specific parallel reviewers (Fable + Sonnet on Claude Code; GPT + Opus + Sonnet on Copilot CLI), Fable triage → `triage.accepted`. Blocking/important accepted findings:
|
|
56
56
|
- interactive: present them and ask (`AskUserQuestion`) whether to fix now (loop back through a minimal Phase-3-style TDD fix) or proceed;
|
|
57
|
-
- `autopilot` (or `prefs.global.
|
|
57
|
+
- `autopilot` (or `prefs.global.ship.autoFix == true`): auto-fix accepted blocking/important findings, then re-review the fix, before advancing.
|
|
58
58
|
- **Phase 5 Build+Test** - the **automated success gate** (this is what "build+test success" means here; the interactive device user-test is `/multi-agent:manual-test`). Stack-aware: build via `figma-config.build` (iOS scheme / Android gradle / detected backend/frontend build) and run the existing test suite if present (`swift test` / `xcodebuild test` / `./gradlew test` / `pytest` / `npm test` / `vitest`). Require success to advance; on failure, surface logs and (interactive) stop or (autopilot) attempt a bounded fix loop. **If the repo has no tests, report "no tests present" - never fabricate test results.**
|
|
59
|
-
- **Phase 6 Commit/PR** - per `$HOME/.claude/multi-agent-refs/phases/phase-6-commit.md`: stage + commit any remaining local changes with a conventional message (`{type}(scope): desc [{JIRA_KEY}-{id}]`), push, and open a PR **only if one does not already exist** for the branch. PR body per `$HOME/.claude/
|
|
60
|
-
- **Phase 7 Report** - per `$HOME/.claude/multi-agent-refs/phases/phase-7-report.md` + `channels.md`: produce the **technical analysis** and **test scenarios**, then post to the configured channels. Default content for `
|
|
59
|
+
- **Phase 6 Commit/PR** - per `$HOME/.claude/multi-agent-refs/phases/phase-6-commit.md`: stage + commit any remaining local changes with a conventional message (`{type}(scope): desc [{JIRA_KEY}-{id}]`), push, and open a PR **only if one does not already exist** for the branch. PR body per `$HOME/.claude/multi-agent-refs/rules.md "External System Outputs"` and `$HOME/.claude/rules/git-conventions.md` - `Ref: #N` / `Related: #N`, never `Closes/Fixes/Resolves`; NO AI/bot attribution anywhere.
|
|
60
|
+
- **Phase 7 Report** - per `$HOME/.claude/multi-agent-refs/phases/phase-7-report.md` + `channels.md`: produce the **technical analysis** and **test scenarios**, then post to the configured channels. Default content for `ship`: a Jira **comment** carrying the technical analysis + the test scenarios (and, when the PR was opened, the PR description). Every body runs through the humanizer; bot/tool/AI signatures are FORBIDDEN in comments.
|
|
61
61
|
|
|
62
62
|
## Modes
|
|
63
63
|
|
|
@@ -66,7 +66,7 @@ Phases 1-3 (Analysis / Planning / Dev) are skipped by design - `finish` treats
|
|
|
66
66
|
|
|
67
67
|
## Required: Phase Tracker Contract
|
|
68
68
|
|
|
69
|
-
**The phase tracker is required.** Full spec: [`$HOME/.claude/multi-agent-refs/tracker-contract.md`]($HOME/.claude/multi-agent-refs/tracker-contract.md). `
|
|
69
|
+
**The phase tracker is required.** Full spec: [`$HOME/.claude/multi-agent-refs/tracker-contract.md`]($HOME/.claude/multi-agent-refs/tracker-contract.md). `ship` registers its active phase set - `0:Init 4:Review 5:Build+Test 6:Commit 7:Report` - but NEVER resets a tracker that an earlier run already built (load-or-continue; contract section "Continuation runs"):
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
72
|
# Phase 0, first shell call (every CLI). init ONLY when no prior state exists -
|
|
@@ -104,5 +104,5 @@ No TaskList widget. After every state change call `bash $HOME/.claude/scripts/ph
|
|
|
104
104
|
```bash
|
|
105
105
|
/multi-agent:dev-local "PROJ-12345" # develop locally (Init→Dev→Commit→Report, no review/test)
|
|
106
106
|
# ... you inspect / hand-test the change ...
|
|
107
|
-
/multi-agent:
|
|
107
|
+
/multi-agent:ship # now: review + build/test + PR + Jira analysis & test scenarios
|
|
108
108
|
```
|
|
@@ -205,7 +205,7 @@ Rules for the report:
|
|
|
205
205
|
- No AI or assistant attribution anywhere, per
|
|
206
206
|
`$HOME/.claude/rules/git-conventions.md`.
|
|
207
207
|
- Real newlines, no HTML entities, per
|
|
208
|
-
`$HOME/.claude/
|
|
208
|
+
`$HOME/.claude/multi-agent-refs/rules.md "External System Outputs"`.
|
|
209
209
|
|
|
210
210
|
## Step 8 - offer the next action, do not take it
|
|
211
211
|
|
|
@@ -89,8 +89,11 @@ Update the pipeline in one command. Existing preferences are preserved; only ski
|
|
|
89
89
|
```bash
|
|
90
90
|
echo ""
|
|
91
91
|
echo "Verification:"
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
# Repo-relative on purpose: these are maintainer smokes, excluded from installs.
|
|
93
|
+
# Both lines name $PIPE_DIR rather than relying on the cd from the line above,
|
|
94
|
+
# so neither can be read - or copied - as an installed-tree invocation.
|
|
95
|
+
bash "$PIPE_DIR/pipeline/scripts/smoke-schema-validation.sh" 2>&1 | tail -1
|
|
96
|
+
bash "$PIPE_DIR/pipeline/scripts/smoke-cross-cli-behavior.sh" 2>&1 | tail -1
|
|
94
97
|
```
|
|
95
98
|
|
|
96
99
|
## Output
|
|
@@ -133,7 +133,7 @@ Step A - run the standard visual + accessibility sweep (light + dark + large t
|
|
|
133
133
|
|
|
134
134
|
Step B - dispatch compliance skill:
|
|
135
135
|
iOS:
|
|
136
|
-
Load
|
|
136
|
+
Load $HOME/.claude/skills/apple-archive-compliance/SKILL.md
|
|
137
137
|
Prereq: @mmerterden/dev-toolkit-mcp ≥ v2.9.0 (provides ios_app_store_audit MCP tool)
|
|
138
138
|
- installable via npm; standalone ArchiveGuard binary deprecated in v8.4.0
|
|
139
139
|
Artifact: pick newest .xcarchive under ~/Library/Developer/Xcode/Archives/**
|
|
@@ -142,7 +142,7 @@ Step B - dispatch compliance skill:
|
|
|
142
142
|
OR (Node fallback): node -e "import('@mmerterden/dev-toolkit-mcp/tools/ios-app-store-audit/index.js').then(m => m.runAudit({ archivePath: '<path>', rules: 'all' }).then(r => console.log(JSON.stringify(r))))"
|
|
143
143
|
Humanize via --lang en (promptLanguage is locked to "en"; pass --lang=tr explicitly to opt into Turkish)
|
|
144
144
|
Android:
|
|
145
|
-
Load
|
|
145
|
+
Load $HOME/.claude/skills/google-play-compliance/SKILL.md
|
|
146
146
|
Prereq: bundletool, aapt2, apksigner in PATH (Android SDK build-tools)
|
|
147
147
|
Artifact: newest .aab under **/build/outputs/bundle/**/*.aab
|
|
148
148
|
OR explicit path argument
|
|
@@ -31,6 +31,22 @@
|
|
|
31
31
|
# always succeeds by design, so the caller stays alive to report a useful error.
|
|
32
32
|
|
|
33
33
|
resolve_credential_store() {
|
|
34
|
+
# An explicit override wins. The usage note below has always documented
|
|
35
|
+
# `CRED_STORE` as an override, but this function used to assign over it
|
|
36
|
+
# unconditionally, so setting it did nothing whenever any host tree happened to
|
|
37
|
+
# carry a credential-store.sh - which is every normal machine. Honour it, and
|
|
38
|
+
# require it to be executable so a typo surfaces here rather than as a confusing
|
|
39
|
+
# failure three layers down.
|
|
40
|
+
if [ -n "${CRED_STORE:-}" ]; then
|
|
41
|
+
if [ -x "$CRED_STORE" ]; then
|
|
42
|
+
export CRED_STORE
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
echo "credential helper: CRED_STORE is set to '$CRED_STORE', which is not executable." >&2
|
|
46
|
+
echo "Unset it to fall back to the installed helpers, or point it at a real file." >&2
|
|
47
|
+
return 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
34
50
|
# All three supported hosts. Codex was missing here, so a Codex-only install could
|
|
35
51
|
# not resolve the credential helper at all - every fetcher on that host reported
|
|
36
52
|
# "credential helper not found" while the file sat in ~/.codex/lib.
|
|
@@ -94,10 +94,18 @@ require_cmd() {
|
|
|
94
94
|
# entries whose name already equals the logical key).
|
|
95
95
|
PREFS_FILE="${MULTI_AGENT_PREFS:-$HOME/.claude/multi-agent-preferences.json}"
|
|
96
96
|
|
|
97
|
+
# Reader order is python3 then node, and both are here on purpose. python3 is present
|
|
98
|
+
# on macOS and every mainstream Linux; node is guaranteed wherever this pipeline is
|
|
99
|
+
# installed at all, because the installer IS a node program. Windows commonly has node
|
|
100
|
+
# and no python3, and with a python3-only reader the mapping was skipped there in
|
|
101
|
+
# silence: the lookup fell back to the LOGICAL key, searched Credential Manager for a
|
|
102
|
+
# target that does not exist, and reported the token as missing while it sat under its
|
|
103
|
+
# mapped name. A missing interpreter must not look like a missing token.
|
|
97
104
|
resolve_key() {
|
|
98
105
|
local logical="$1" mapped=""
|
|
99
|
-
if [ -f "$PREFS_FILE" ]
|
|
100
|
-
|
|
106
|
+
if [ -f "$PREFS_FILE" ]; then
|
|
107
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
108
|
+
mapped=$(python3 -c '
|
|
101
109
|
import json, sys
|
|
102
110
|
try:
|
|
103
111
|
with open(sys.argv[1], encoding="utf-8") as fh:
|
|
@@ -108,6 +116,19 @@ name = prefs.get("global", {}).get("keychainMapping", {}).get(sys.argv[2])
|
|
|
108
116
|
if isinstance(name, str) and name.strip():
|
|
109
117
|
sys.stdout.write(name.strip())
|
|
110
118
|
' "$PREFS_FILE" "$logical" 2>/dev/null || true)
|
|
119
|
+
fi
|
|
120
|
+
if [ -z "$mapped" ] && command -v node >/dev/null 2>&1; then
|
|
121
|
+
mapped=$(node -e '
|
|
122
|
+
try {
|
|
123
|
+
const prefs = JSON.parse(require("fs").readFileSync(process.argv[1], "utf-8"));
|
|
124
|
+
const name = ((prefs.global || {}).keychainMapping || {})[process.argv[2]];
|
|
125
|
+
if (typeof name === "string" && name.trim()) process.stdout.write(name.trim());
|
|
126
|
+
} catch { /* no mapping readable - caller falls back to the logical key */ }
|
|
127
|
+
' "$PREFS_FILE" "$logical" 2>/dev/null || true)
|
|
128
|
+
fi
|
|
129
|
+
if [ -z "$mapped" ] && ! command -v python3 >/dev/null 2>&1 && ! command -v node >/dev/null 2>&1; then
|
|
130
|
+
echo "WARN: neither python3 nor node found; keychainMapping ignored, looking up '$logical' verbatim." >&2
|
|
131
|
+
fi
|
|
111
132
|
fi
|
|
112
133
|
printf '%s' "${mapped:-$logical}"
|
|
113
134
|
}
|
|
@@ -239,8 +260,23 @@ do_delete() {
|
|
|
239
260
|
do_list() {
|
|
240
261
|
case "$PLATFORM" in
|
|
241
262
|
macos)
|
|
263
|
+
# Read `svce` - the SERVICE attribute, which is what `set` writes with -s and
|
|
264
|
+
# `get` looks up with -s. This used to read `0x00000007`, which is the LABEL:
|
|
265
|
+
# it happens to match for items written by keychain.py (which stamps both -l and
|
|
266
|
+
# -s), but it is the wrong key in principle and diverges on any item whose label
|
|
267
|
+
# was set independently, listing a name `get` cannot resolve.
|
|
268
|
+
#
|
|
269
|
+
# `dump-keychain` prints the first few attributes under numeric tags and the rest
|
|
270
|
+
# under named ones, and `svce` is in the named group - so the tag to match is
|
|
271
|
+
# `"svce"`, not `0x00000008`.
|
|
272
|
+
#
|
|
273
|
+
# Without `-d` this reads attributes only and does not prompt for access; only
|
|
274
|
+
# the data-dumping form does.
|
|
275
|
+
#
|
|
276
|
+
# A trailing `\000` appears when security prints the value in its hex+C-string
|
|
277
|
+
# form; it is not part of the service name.
|
|
242
278
|
security dump-keychain 2>/dev/null \
|
|
243
|
-
| awk -F'"' '/
|
|
279
|
+
| awk -F'"' '/"svce"<blob>=/ && NF >= 5 { v = $4; sub(/\\000$/, "", v); if (v != "") print v }' \
|
|
244
280
|
| sort -u
|
|
245
281
|
;;
|
|
246
282
|
linux)
|
|
@@ -287,7 +323,14 @@ do_doctor() {
|
|
|
287
323
|
fi
|
|
288
324
|
;;
|
|
289
325
|
*)
|
|
290
|
-
|
|
326
|
+
# This used to advertise an env-var fallback. There isn't one here: `get` on an
|
|
327
|
+
# unrecognised platform exits 2. Individual callers have their own env escape
|
|
328
|
+
# hatches (figma-token.sh honours $FIGMA_PAT, for instance), but this helper
|
|
329
|
+
# does not, and claiming otherwise sent people looking for a mechanism that
|
|
330
|
+
# does not exist.
|
|
331
|
+
echo "Backend: none - unrecognised platform, \`get\` exits 2"
|
|
332
|
+
echo "Workaround: set the credential in the caller's own env var where one"
|
|
333
|
+
echo " exists (e.g. FIGMA_PAT), or run on macOS / Linux / Windows"
|
|
291
334
|
;;
|
|
292
335
|
esac
|
|
293
336
|
}
|
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
# [--lang-prefixes TR,EN] [--batch 4]
|
|
17
17
|
# fetch-figma-annotations.sh --url <figma-url> [--lang-prefixes TR,EN]
|
|
18
18
|
#
|
|
19
|
-
# Token source:
|
|
20
|
-
#
|
|
21
|
-
# environment variable. No literal keychain service name is
|
|
19
|
+
# Token source: figma-token.sh, which resolves the canonical `figma` logical key
|
|
20
|
+
# through credential-store.sh (falling back to the legacy `figma_pat` key, then
|
|
21
|
+
# to the FIGMA_PAT environment variable). No literal keychain service name is
|
|
22
|
+
# embedded here.
|
|
22
23
|
#
|
|
23
24
|
# Label parsing (config-driven via --lang-prefixes, ordered):
|
|
24
25
|
# prefixed : lines like "TR: ...", "EN: ..." win regardless of order
|
|
@@ -37,7 +38,6 @@
|
|
|
37
38
|
|
|
38
39
|
set -uo pipefail
|
|
39
40
|
|
|
40
|
-
PREFS="$HOME/.claude/multi-agent-preferences.json"
|
|
41
41
|
# Locate the resolver with an existence check, not a `.`-chain: sourcing a missing file
|
|
42
42
|
# aborts the shell under `set -e`, `||` included, so a chain skips both its later
|
|
43
43
|
# candidates and its trailing `|| true`. A missing store is tolerated here - CRED_STORE
|
|
@@ -57,6 +57,26 @@ for _cred_resolver in \
|
|
|
57
57
|
done
|
|
58
58
|
unset _cred_resolver
|
|
59
59
|
CRED_STORE="${CRED_STORE:-}"
|
|
60
|
+
|
|
61
|
+
# Tier 2 token lookup lives in one file so it cannot drift per fetcher. Same
|
|
62
|
+
# existence-check discipline as the resolver loop above, and the same tolerance:
|
|
63
|
+
# without it, resolution still works through the FIGMA_PAT env fallback below.
|
|
64
|
+
for _figma_token_lib in \
|
|
65
|
+
"$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/figma-token.sh" \
|
|
66
|
+
"$HOME/.claude/lib/figma-token.sh" \
|
|
67
|
+
"$HOME/.copilot/lib/figma-token.sh" \
|
|
68
|
+
"$HOME/.codex/lib/figma-token.sh"; do
|
|
69
|
+
[ -f "$_figma_token_lib" ] || continue
|
|
70
|
+
# shellcheck source=/dev/null
|
|
71
|
+
. "$_figma_token_lib" 2>/dev/null || true
|
|
72
|
+
if command -v resolve_figma_token >/dev/null 2>&1; then break; fi
|
|
73
|
+
done
|
|
74
|
+
unset _figma_token_lib
|
|
75
|
+
if ! command -v resolve_figma_token >/dev/null 2>&1; then
|
|
76
|
+
resolve_figma_token() { [ -n "${FIGMA_PAT:-}" ] && printf '%s' "$FIGMA_PAT"; }
|
|
77
|
+
figma_token_remediation() { printf 'figma-token.sh not found - reinstall the pipeline, or export FIGMA_PAT.'; }
|
|
78
|
+
fi
|
|
79
|
+
|
|
60
80
|
FIGMA_API="https://api.figma.com/v1"
|
|
61
81
|
HTTP_TIMEOUT=60
|
|
62
82
|
|
|
@@ -92,32 +112,10 @@ fi
|
|
|
92
112
|
[ -z "$FILE_KEY" ] && die 1 "missing --file-key (or a --url to parse it from)"
|
|
93
113
|
[ -z "$NODE_IDS" ] && die 1 "missing --node-id (or a --url to parse it from)"
|
|
94
114
|
|
|
95
|
-
|
|
96
|
-
resolve_token() {
|
|
97
|
-
local token_key=""
|
|
98
|
-
if [ -f "$PREFS" ] && command -v python3 >/dev/null 2>&1; then
|
|
99
|
-
token_key=$(python3 -c "
|
|
100
|
-
import json
|
|
101
|
-
try:
|
|
102
|
-
p = json.load(open('$PREFS'))
|
|
103
|
-
print(p.get('global', {}).get('keychainMapping', {}).get('figma_pat') or '')
|
|
104
|
-
except Exception:
|
|
105
|
-
print('')
|
|
106
|
-
" 2>/dev/null || true)
|
|
107
|
-
fi
|
|
108
|
-
if [ -n "$token_key" ] && [ -n "$CRED_STORE" ] && [ -x "$CRED_STORE" ]; then
|
|
109
|
-
local tok
|
|
110
|
-
tok=$("$CRED_STORE" get "$token_key" 2>/dev/null || true)
|
|
111
|
-
if [ -n "$tok" ]; then printf '%s' "$tok"; return 0; fi
|
|
112
|
-
fi
|
|
113
|
-
if [ -n "${FIGMA_PAT:-}" ]; then printf '%s' "$FIGMA_PAT"; return 0; fi
|
|
114
|
-
return 1
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
FIGMA_TOKEN=$(resolve_token || true)
|
|
115
|
+
FIGMA_TOKEN=$(resolve_figma_token || true)
|
|
118
116
|
if [ -z "$FIGMA_TOKEN" ]; then
|
|
119
117
|
printf '{"ok":false,"reason":"missing-token","source":"figma-rest","fileKey":"%s"}\n' "$FILE_KEY"
|
|
120
|
-
die 2 "
|
|
118
|
+
die 2 "$(figma_token_remediation)"
|
|
121
119
|
fi
|
|
122
120
|
|
|
123
121
|
TMPDIR_A=$(mktemp -d "${TMPDIR:-/tmp}/figma-annot.XXXXXX")
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
# Tier 2 (Figma REST + PAT) -> primary path here
|
|
24
24
|
# Tier 3 (user screenshot) -> not handled; exit 3 with guidance
|
|
25
25
|
#
|
|
26
|
-
# Token source:
|
|
27
|
-
#
|
|
28
|
-
# FIGMA_PAT environment variable. No literal keychain service name
|
|
29
|
-
# embedded in this script.
|
|
26
|
+
# Token source: figma-token.sh, which resolves the canonical `figma` logical
|
|
27
|
+
# key through credential-store.sh (falling back to the legacy `figma_pat` key,
|
|
28
|
+
# then to the FIGMA_PAT environment variable). No literal keychain service name
|
|
29
|
+
# is embedded in this script.
|
|
30
30
|
#
|
|
31
31
|
# Exit codes:
|
|
32
32
|
# 0 success
|
|
@@ -41,7 +41,6 @@ set -euo pipefail
|
|
|
41
41
|
|
|
42
42
|
# --- Globals ----------------------------------------------------------------
|
|
43
43
|
|
|
44
|
-
PREFS="$HOME/.claude/multi-agent-preferences.json"
|
|
45
44
|
# Locate the resolver with an existence check, not a `.`-chain: sourcing a missing file
|
|
46
45
|
# aborts the shell under `set -e`, `||` included, so a chain skips both its later
|
|
47
46
|
# candidates and its trailing `|| true`. A missing store is tolerated here - CRED_STORE
|
|
@@ -61,6 +60,26 @@ for _cred_resolver in \
|
|
|
61
60
|
done
|
|
62
61
|
unset _cred_resolver
|
|
63
62
|
CRED_STORE="${CRED_STORE:-}"
|
|
63
|
+
|
|
64
|
+
# Tier 2 token lookup lives in one file so it cannot drift per fetcher. Same
|
|
65
|
+
# existence-check discipline as the resolver loop above, and the same tolerance:
|
|
66
|
+
# without it, resolution still works through the FIGMA_PAT env fallback.
|
|
67
|
+
for _figma_token_lib in \
|
|
68
|
+
"$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/figma-token.sh" \
|
|
69
|
+
"$HOME/.claude/lib/figma-token.sh" \
|
|
70
|
+
"$HOME/.copilot/lib/figma-token.sh" \
|
|
71
|
+
"$HOME/.codex/lib/figma-token.sh"; do
|
|
72
|
+
[ -f "$_figma_token_lib" ] || continue
|
|
73
|
+
# shellcheck source=/dev/null
|
|
74
|
+
. "$_figma_token_lib" 2>/dev/null || true
|
|
75
|
+
if command -v resolve_figma_token >/dev/null 2>&1; then break; fi
|
|
76
|
+
done
|
|
77
|
+
unset _figma_token_lib
|
|
78
|
+
if ! command -v resolve_figma_token >/dev/null 2>&1; then
|
|
79
|
+
resolve_figma_token() { [ -n "${FIGMA_PAT:-}" ] && printf '%s' "$FIGMA_PAT"; }
|
|
80
|
+
figma_token_remediation() { printf 'figma-token.sh not found - reinstall the pipeline, or export FIGMA_PAT.'; }
|
|
81
|
+
fi
|
|
82
|
+
|
|
64
83
|
FIGMA_API="https://api.figma.com/v1"
|
|
65
84
|
PARALLEL_DL=4
|
|
66
85
|
HTTP_TIMEOUT=60
|
|
@@ -105,8 +124,8 @@ Options:
|
|
|
105
124
|
--help Show this help text and exit.
|
|
106
125
|
|
|
107
126
|
Token resolution:
|
|
108
|
-
Read via credential-store.sh using
|
|
109
|
-
|
|
127
|
+
Read via credential-store.sh using prefs.global.keychainMapping.figma
|
|
128
|
+
(legacy figma_pat still honoured). Falls back to FIGMA_PAT env.
|
|
110
129
|
|
|
111
130
|
Output:
|
|
112
131
|
PNG files plus manifest.json in the output directory.
|
|
@@ -151,35 +170,6 @@ print(f"{file_key}\t{node}")
|
|
|
151
170
|
PY
|
|
152
171
|
}
|
|
153
172
|
|
|
154
|
-
resolve_token() {
|
|
155
|
-
# 1) Try the keychain via credential-store.sh, keyed by prefs mapping.
|
|
156
|
-
local token_key=""
|
|
157
|
-
if [ -f "$PREFS" ] && command -v python3 >/dev/null 2>&1; then
|
|
158
|
-
token_key=$(python3 -c "
|
|
159
|
-
import json, sys
|
|
160
|
-
try:
|
|
161
|
-
p = json.load(open('$PREFS'))
|
|
162
|
-
print(p.get('global', {}).get('keychainMapping', {}).get('figma_pat') or '')
|
|
163
|
-
except Exception:
|
|
164
|
-
print('')
|
|
165
|
-
" 2>/dev/null || true)
|
|
166
|
-
fi
|
|
167
|
-
if [ -n "$token_key" ] && [ -x "$CRED_STORE" ]; then
|
|
168
|
-
local tok
|
|
169
|
-
tok=$("$CRED_STORE" get "$token_key" 2>/dev/null || true)
|
|
170
|
-
if [ -n "$tok" ]; then
|
|
171
|
-
printf '%s' "$tok"
|
|
172
|
-
return 0
|
|
173
|
-
fi
|
|
174
|
-
fi
|
|
175
|
-
# 2) Env fallback so CI / one-shot use still works.
|
|
176
|
-
if [ -n "${FIGMA_PAT:-}" ]; then
|
|
177
|
-
printf '%s' "$FIGMA_PAT"
|
|
178
|
-
return 0
|
|
179
|
-
fi
|
|
180
|
-
return 1
|
|
181
|
-
}
|
|
182
|
-
|
|
183
173
|
# curl_figma <output> <url>
|
|
184
174
|
# Honours retries: 429 retries once after a 5s pause; 5xx uses exponential
|
|
185
175
|
# backoff (1s, 2s, 4s). Writes the body to <output>, returns the HTTP code on
|
|
@@ -409,11 +399,10 @@ require_cmd python3
|
|
|
409
399
|
# Tier 1 (Figma MCP) is not reachable from a bash script. Stay on Tier 2 (REST).
|
|
410
400
|
log "INFO: Tier 1 (Figma MCP) not available from shell; using Tier 2 (REST)."
|
|
411
401
|
|
|
412
|
-
FIGMA_TOKEN=$(
|
|
402
|
+
FIGMA_TOKEN=$(resolve_figma_token || true)
|
|
413
403
|
if [ -z "${FIGMA_TOKEN:-}" ]; then
|
|
414
404
|
log "Tier 3 (user-provided screenshot required): no PAT resolved."
|
|
415
|
-
log "Hint:
|
|
416
|
-
log " prefs.global.keychainMapping.figma_pat, or export FIGMA_PAT."
|
|
405
|
+
log "Hint: $(figma_token_remediation)"
|
|
417
406
|
exit 3
|
|
418
407
|
fi
|
|
419
408
|
|