@mmerterden/multi-agent-pipeline 16.10.0 → 16.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +110 -1
  3. package/README.tr.md +111 -1
  4. package/install/templates/copilot-instructions.md +1 -1
  5. package/package.json +1 -1
  6. package/pipeline/commands/multi-agent/SKILL.md +3 -3
  7. package/pipeline/commands/multi-agent/analysis/SKILL.md +9 -9
  8. package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +2 -2
  9. package/pipeline/commands/multi-agent/autopilot/SKILL.md +1 -1
  10. package/pipeline/commands/multi-agent/build-optimize/SKILL.md +2 -2
  11. package/pipeline/commands/multi-agent/channels/SKILL.md +1 -1
  12. package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +1 -1
  13. package/pipeline/commands/multi-agent/create-jira/SKILL.md +1 -1
  14. package/pipeline/commands/multi-agent/design-check/SKILL.md +2 -2
  15. package/pipeline/commands/multi-agent/help/SKILL.md +4 -4
  16. package/pipeline/commands/multi-agent/language/SKILL.md +3 -3
  17. package/pipeline/commands/multi-agent/local/SKILL.md +1 -1
  18. package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +1 -1
  19. package/pipeline/commands/multi-agent/purge/SKILL.md +2 -2
  20. package/pipeline/commands/multi-agent/resume-local/SKILL.md +2 -2
  21. package/pipeline/commands/multi-agent/review/SKILL.md +7 -6
  22. package/pipeline/commands/multi-agent/setup/SKILL.md +9 -9
  23. package/pipeline/commands/multi-agent/stack/SKILL.md +12 -13
  24. package/pipeline/commands/multi-agent/update/SKILL.md +1 -1
  25. package/pipeline/lib/extract-conventions.sh +19 -18
  26. package/pipeline/multi-agent-refs/_account-picker.md +1 -1
  27. package/pipeline/multi-agent-refs/_dev-context.md +2 -2
  28. package/pipeline/multi-agent-refs/_input-parser.md +1 -1
  29. package/pipeline/multi-agent-refs/analysis/evidence.md +4 -4
  30. package/pipeline/multi-agent-refs/analysis/intake.md +112 -36
  31. package/pipeline/multi-agent-refs/analysis/locked.md +1 -1
  32. package/pipeline/multi-agent-refs/analysis/render.md +37 -14
  33. package/pipeline/multi-agent-refs/analysis/synthesis.md +7 -7
  34. package/pipeline/multi-agent-refs/analysis-template-corporate.md +1 -1
  35. package/pipeline/multi-agent-refs/analysis-template.md +6 -6
  36. package/pipeline/multi-agent-refs/channels/confluence.md +1 -0
  37. package/pipeline/multi-agent-refs/channels/pr.md +2 -2
  38. package/pipeline/multi-agent-refs/conventions-defaults.md +13 -13
  39. package/pipeline/multi-agent-refs/features/stack-skill-routing.md +1 -1
  40. package/pipeline/multi-agent-refs/phases/modes.md +1 -1
  41. package/pipeline/multi-agent-refs/phases/phase-0-init.md +10 -6
  42. package/pipeline/multi-agent-refs/phases/phase-2-planning.md +6 -5
  43. package/pipeline/multi-agent-refs/phases/phase-3-dev.md +4 -4
  44. package/pipeline/multi-agent-refs/phases/phase-6-commit.md +7 -7
  45. package/pipeline/multi-agent-refs/picker-contract.md +29 -4
  46. package/pipeline/multi-agent-refs/readiness-review.md +1 -1
  47. package/pipeline/multi-agent-refs/rules.md +4 -4
  48. package/pipeline/multi-agent-refs/{frontend-guide.md → web-guide.md} +2 -2
  49. package/pipeline/schemas/analysis-output.schema.json +1 -1
  50. package/pipeline/schemas/analysis-spec.schema.json +3 -3
  51. package/pipeline/schemas/prefs.schema.json +18 -2
  52. package/pipeline/scripts/gen-skills-index.mjs +1 -1
  53. package/pipeline/scripts/validate-analysis-doc.mjs +7 -3
  54. package/pipeline/scripts/validate-analysis.mjs +6 -1
  55. package/pipeline/scripts/write-state.mjs +29 -11
  56. package/pipeline/skills/.skills-index.json +24 -2
  57. package/pipeline/skills/shared/README.md +9 -7
  58. package/pipeline/skills/shared/core/multi-agent/SKILL.md +1 -1
  59. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +3 -3
  60. package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +1 -1
  61. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +1 -1
  62. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +2 -2
  63. package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +2 -2
  64. package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +1 -1
  65. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +1 -1
  66. package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +11 -12
  67. package/pipeline/skills/skills-index.md +5 -3
@@ -27,12 +27,12 @@ audit trail and metrics corpus at the log root are always preserved.
27
27
  2. **First confirmation** - native `AskUserQuestion` picker (no typed keyword),
28
28
  in `outputLanguage`, including the dry-run counts:
29
29
  - `question`: "Wipe the listed worktrees, branches, and counter?"
30
- - `header`: "Purge" · `options`: `{ label: "Continue", description: "Proceed to the final confirmation" }`, `{ label: "Cancel", description: "Abort, change nothing" }`
30
+ - `header`: "Purge" (English, <=12 chars) · `options` (label + description in `outputLanguage`; the names below are the option SEMANTICS, not strings to print): option 1 "Continue" - proceed to the final confirmation; option 2 "Cancel" - abort, change nothing
31
31
  - **Cancel** → exit.
32
32
 
33
33
  3. **Second confirmation** (paranoia gate) - a second `AskUserQuestion` picker:
34
34
  - `question`: "This is irreversible. Permanently wipe every worktree, branch, and state now?" (`outputLanguage`)
35
- - `header`: "Confirm" · `options`: `{ label: "Purge permanently", description: "Delete all worktrees, branches, and the counter" }`, `{ label: "Cancel", description: "Abort, change nothing" }`
35
+ - `header`: "Confirm" (English, <=12 chars) · `options` (label + description in `outputLanguage`; the names below are the option SEMANTICS, not strings to print): option 1 "Purge permanently" - delete all worktrees, branches, and the counter; option 2 "Cancel" - abort, change nothing
36
36
  - Anything other than **Purge permanently** → cancel.
37
37
 
38
38
  4. **Remote branches** - ask once whether to delete the remote branches too;
@@ -6,7 +6,7 @@ allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep, TaskCreate, TaskUpdat
6
6
 
7
7
  # multi-agent resume-local - Take Existing Branch Work Through the Pipeline Tail
8
8
 
9
- > **Language (read FIRST)**: Before any status output, read `prefs.global.outputLanguage` and render every conversational line in it. `AskUserQuestion` `label`/`header` stay English, but its `question` and option `description`s render in `outputLanguage`; external payload bodies follow `outputLanguage` too (identifiers, commit messages, branch names stay English). Full contract: `$HOME/.claude/multi-agent-refs/rules.md` "Language Application".
9
+ > **Language (read FIRST)**: Before any status output, read `prefs.global.outputLanguage` and render every conversational line in it. `AskUserQuestion` renders its `question`, option `label`s and option `description`s in `outputLanguage`; only `header` stays English (<=12-char chip); external payload bodies follow `outputLanguage` too (identifiers, commit messages, branch names stay English). Full contract: `$HOME/.claude/multi-agent-refs/rules.md` "Language Application".
10
10
 
11
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 a Short run 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:resume-local` 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
 
@@ -55,7 +55,7 @@ Phases 1-3 (Analysis / Planning / Dev) are skipped by design - `ship` treats t
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
57
  - `autopilot` (or `prefs.global.resumeLocal.autoFix == true`): auto-fix accepted blocking/important findings, then re-review the fix, before advancing.
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.**
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/web 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
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
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
 
@@ -242,18 +242,19 @@ Optional opt-out prompt (interactive mode only; autopilot skips and posts):
242
242
  ```
243
243
  question (outputLanguage): "PR #{N} için review action gönderilsin mi?"
244
244
  header (English): "Post review"
245
- options:
246
- - label "Post review", description (outputLanguage): "Bulgular varsa inline yorum + Request changes; yoksa Approve"
247
- - label "Chat only", description (outputLanguage): "Sadece sohbet özetiyle yetin, PR'a dokunma"
248
- default: option 1 (Post review)
245
+ options (label + description in outputLanguage; semantics, not literals):
246
+ - option 1 - "Post review": inline comments + Request changes when there are
247
+ findings, Approve when there are none
248
+ - option 2 - "Chat only": leave the PR untouched, the chat summary is enough
249
+ default: option 1
249
250
  ```
250
251
 
251
252
  Defaults:
252
- - Interactive mode: prompt with default `Post review`
253
+ - Interactive mode: prompt with default option 1
253
254
  - Autopilot mode: auto-post (no prompt)
254
255
  - `--no-comment` / `--no-post` flag: skip the post entirely
255
256
 
256
- If the user picks "Post review":
257
+ If the user picks option 1 (post the review):
257
258
 
258
259
  ```bash
259
260
  bash $HOME/.claude/lib/post-pr-review.sh "$TASK_ID"
@@ -24,7 +24,7 @@ Ask BEFORE anything else, so every subsequent setup prompt and the rest of the p
24
24
 
25
25
  | Axis | What it controls | Configurable? |
26
26
  |---|---|---|
27
- | `promptLanguage` | The picker's structural UI chrome only: `AskUserQuestion` `label` (button text) and `header` (chip), plus host error UI and internal contract identifiers | **No - fixed to `en`.** Button and chip text stays English so tooling reads the same across CLIs. |
27
+ | `promptLanguage` | Picker chrome only: the `AskUserQuestion` `header` chip, host error UI, internal contract identifiers | **No - fixed to `en`.** The chip is capped at 12 chars, which most Turkish equivalents overflow. |
28
28
  | `outputLanguage` | The assistant's non-interactive explanations, status updates, error messages, and pipeline-generated reports rendered to the user | Yes - set here and changeable later via `/multi-agent:language <en\|tr>` |
29
29
 
30
30
  `promptLanguage` is seeded as `"en"` and never offered to the user. **External payloads always stay English** (commits, PR titles/bodies, Jira comments, wiki content, reviewer/triage prompts, agent-log.md).
@@ -53,21 +53,20 @@ Select (1-2):
53
53
 
54
54
  From this point forward, every prompt in Steps 1-6 below follows the canonical
55
55
  per-field matrix in `$HOME/.claude/multi-agent-refs/rules.md` ("Language Application"):
56
- the `question` text and each option's `description` render in `outputLanguage`, while
57
- `label` and `header` stay English. The wizard's status text and post-setup summary
58
- render in `outputLanguage`. External payloads remain English.
56
+ `question`, `label` and `description` render in `outputLanguage`; `header` stays
57
+ English. Wizard status and the post-setup summary follow `outputLanguage`. External
58
+ payloads remain English.
59
59
 
60
60
  > This paragraph used to say every prompt renders in English "per the fixed
61
61
  > `promptLanguage`", which contradicted the canonical matrix and produced
62
62
  > half-English pickers on Turkish runs: `promptLanguage` governs only the button and
63
63
  > chip chrome, never the question a user reads.
64
64
 
65
- ### Step 0.5 - Credential Backend Check
66
-
67
- Before discovery, verify the platform's credential backend is available:
65
+ ### Step 0.5 - Dependency check
68
66
 
69
67
  ```bash
70
68
  ~/.claude/lib/credential-store.sh doctor
69
+ command -v pdftotext >/dev/null 2>&1 || echo "pdftotext: MISSING"
71
70
  ```
72
71
 
73
72
  | Output | Action |
@@ -76,6 +75,7 @@ Before discovery, verify the platform's credential backend is available:
76
75
  | Linux: `secret-tool ✗ MISSING` | Prompt: `sudo apt install libsecret-tools` (Debian/Ubuntu) or `sudo dnf install libsecret` (Fedora). Re-run setup after install. |
77
76
  | Windows: `CredentialManager ✗ MISSING` | Prompt: `Install-Module CredentialManager -Scope CurrentUser -Force` in an elevated PowerShell. Re-run setup. |
78
77
  | Platform `unknown` | Halt - credential storage cannot proceed. |
78
+ | `pdftotext: MISSING` | Advisory. Print `brew install poppler` (or distro equivalent), continue. `.docx` needs nothing. |
79
79
 
80
80
  ### Credential Key Naming Rule
81
81
 
@@ -316,7 +316,7 @@ Expired / rejected token (401 / 403 mid-run) - the Expired-token decision from
316
316
  Select:
317
317
  ```
318
318
 
319
- Render `question` + `description` in `outputLanguage`; `label` + `header` English. The picked label is a choice, never the secret - the value still enters via Step B clipboard.
319
+ 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.
320
320
 
321
321
  - **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).
322
322
  - **Add now** / **Regenerate** → proceed to Step B (clipboard save). Regenerate reuses the same `{KEY_NAME}`.
@@ -835,6 +835,6 @@ Stack skills ship as versioned plugins in the `{owner}/multi-agent-plugins` mark
835
835
  - `requirements.txt` / `pyproject.toml` / server `package.json` → `ai-backend-toolkit`
836
836
  - **no clear marker → default `ai-ios-toolkit`**
837
837
  `ai-common-toolkit@multi-agent-plugins` and `ai-analyst-toolkit@multi-agent-plugins` are always set `true` alongside the stack plugin: neither is stack-specific.
838
- 3. Report the enabled set. To change later, run `/multi-agent:stack <ios|android|frontend|backend|...>` in the repo. Pipeline Phase 1 auto-detects the stack for its own routing regardless of enablement.
838
+ 3. Report the enabled set. To change later, run `/multi-agent:stack <ios|android|web|backend|...>` in the repo. Pipeline Phase 1 auto-detects the stack for its own routing regardless of enablement.
839
839
 
840
840
  The marketplace repo name (`multi-agent-plugins`) is generic; a different org points `{owner}` at its own fork - nothing in the pipeline is coupled to a specific account.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: "Select the active stack(s) for this repo by enabling the matching marketplace plugin(s) in .claude/settings.json. Multi-select: pass several stacks (ios backend) or pick them in the native picker. Use when a repo's stack changed or the wrong plugins are enabled for it."
3
3
  description-tr: "Bu repo için aktif stack'leri seçer: eşleşen marketplace plugin'lerini .claude/settings.json'da etkinleştirir. Çoklu seçim: birden fazla stack yazılabilir (ios backend) ya da native picker'dan seçilir."
4
- argument-hint: "[ios|android|frontend|web|backend|mobile|fullstack|all ...]"
4
+ argument-hint: "[ios|android|web|frontend|backend|mobile|fullstack|all ...]"
5
5
  allowed-tools: Bash, Read, Edit, Write, AskUserQuestion
6
6
  ---
7
7
 
@@ -22,8 +22,8 @@ This replaces the old `stack-swap.sh` mechanic that physically moved skill direc
22
22
  /multi-agent:stack android # Compose toolkit + common
23
23
  /multi-agent:stack mobile # alias: ios + android + common
24
24
  /multi-agent:stack backend # Python / Node spec-driven toolkit + common
25
- /multi-agent:stack frontend # React / TSX toolkit + common (alias: web)
26
- /multi-agent:stack fullstack # alias: frontend + backend + common
25
+ /multi-agent:stack web # React / TSX toolkit + common (alias: frontend)
26
+ /multi-agent:stack fullstack # alias: web + backend + common
27
27
  /multi-agent:stack all # all four stack toolkits + common
28
28
  ```
29
29
 
@@ -33,7 +33,7 @@ This replaces the old `stack-swap.sh` mechanic that physically moved skill direc
33
33
  |---|---|
34
34
  | `ios` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-ios-toolkit` |
35
35
  | `android` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-android-toolkit` |
36
- | `frontend` / `web` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-frontend-toolkit` |
36
+ | `web` / `frontend` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-frontend-toolkit` |
37
37
  | `backend` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-backend-toolkit` |
38
38
  | `mobile` | common + `ai-ios-toolkit` + `ai-android-toolkit` |
39
39
  | `fullstack` | common + `ai-frontend-toolkit` + `ai-backend-toolkit` |
@@ -46,10 +46,10 @@ Multiple args union their plugin sets: `ios backend` → common + iOS + backend.
46
46
  1. **No arg → native multi-select picker.** Read `.claude/settings.json` (repo) + `~/.claude/settings.json` (global) to learn the current state, then ask with `AskUserQuestion` (`multiSelect: true`) - NEVER a numbered text menu:
47
47
  - `question` (in `outputLanguage`): which stacks should be active in this repo, noting the currently enabled ones
48
48
  - `header`: "Stacks" (English, UI contract)
49
- - `options` (4): `ios` / `android` / `frontend (web)` / `backend`, each `description` (in `outputLanguage`) naming the plugin it enables and marking the ones already enabled with "(currently on)" / "(şu an açık)"
50
- - Map each selected label back to its canonical arg before step 2: the token before any parenthesis (`frontend (web)` → `frontend`).
49
+ - `options` (4): `ios` / `android` / `web` / `backend`, each `description` (in `outputLanguage`) naming the plugin it enables and marking the ones already enabled with "(currently on)" / "(şu an açık)"
50
+ - Map each selected label back to its canonical arg before step 2: the token before any parenthesis.
51
51
  - Empty selection or cancel → **status mode**: print the currently enabled `@multi-agent-plugins` plugins and exit without modifying anything. Status mode never runs the Implementation block below - that block is enable-mode only.
52
- 2. **Arg(s) present → enable mode.** Accept multiple space-separated stacks. Resolve each through the alias table (`web`→`frontend`, `mobile`→`ios android`, `fullstack`→`frontend backend`, `all`→every stack), union the plugin sets, then write the **current repo's** `.claude/settings.json`.
52
+ 2. **Arg(s) present → enable mode.** Accept multiple space-separated stacks. Resolve each through the alias table (`frontend`→`web`, `mobile`→`ios android`, `fullstack`→`web backend`, `all`→every stack), union the plugin sets, then write the **current repo's** `.claude/settings.json`.
53
53
  3. **Write rules:**
54
54
  - every plugin in the union is set to `true`
55
55
  - every stack toolkit **not** in the union is set to `false` (leave non-`@multi-agent-plugins` entries untouched)
@@ -74,7 +74,7 @@ COMMON="ai-common-toolkit@${MP}"
74
74
  ANALYST="ai-analyst-toolkit@${MP}"
75
75
  IOS="ai-ios-toolkit@${MP}"
76
76
  ANDROID="ai-android-toolkit@${MP}"
77
- FRONTEND="ai-frontend-toolkit@${MP}"
77
+ WEB="ai-frontend-toolkit@${MP}"
78
78
  BACKEND="ai-backend-toolkit@${MP}"
79
79
 
80
80
  # Enable-mode only: with zero args the write rules below would set every stack
@@ -91,13 +91,12 @@ for ARG in "$@"; do
91
91
  case "$ARG" in
92
92
  ios) ON="$ON $IOS" ;;
93
93
  android) ON="$ON $ANDROID" ;;
94
- frontend|web) ON="$ON $FRONTEND" ;;
95
- "frontend (web)") ON="$ON $FRONTEND" ;;
94
+ web|frontend) ON="$ON $WEB" ;;
96
95
  backend) ON="$ON $BACKEND" ;;
97
96
  mobile) ON="$ON $IOS $ANDROID" ;;
98
- fullstack) ON="$ON $FRONTEND $BACKEND" ;;
99
- all) ON="$ON $IOS $ANDROID $FRONTEND $BACKEND" ;;
100
- *) echo "Unknown stack '$ARG'. One of: ios android mobile backend frontend web fullstack all"; exit 1 ;;
97
+ fullstack) ON="$ON $WEB $BACKEND" ;;
98
+ all) ON="$ON $IOS $ANDROID $WEB $BACKEND" ;;
99
+ *) echo "Unknown stack '$ARG'. One of: ios android mobile backend web fullstack all"; exit 1 ;;
101
100
  esac
102
101
  done
103
102
  ```
@@ -184,7 +184,7 @@ A git clone of the pipeline repo is a maintainer workspace, kept in sync by `/mu
184
184
  ```
185
185
  Current: v15.6.0 Latest: v15.6.1
186
186
  -> npm pack @{npm-scope}/multi-agent-pipeline@15.6.1
187
- -> node install.js --all (53 commands, 245 scripts, 208 skills)
187
+ -> node install.js --all (53 commands, 263 scripts, 210 skills)
188
188
  -> migrate-prefs.mjs (0 changes - already v2.6.0)
189
189
 
190
190
  ✓ Updated: v15.6.0 → v15.6.1
@@ -6,7 +6,7 @@
6
6
  #
7
7
  # Usage:
8
8
  # extract-conventions.sh <repo-path> <platform>
9
- # Platform: ios | android | backend | frontend
9
+ # Platform: ios | android | backend | web ('frontend' accepted as the pre-rename alias)
10
10
  #
11
11
  # Output schema (per bucket):
12
12
  # { pattern, example, confidence, evidenceFiles[], alternativeCandidates[] }
@@ -28,9 +28,10 @@ if [ ! -d "$REPO_PATH" ]; then
28
28
  fi
29
29
 
30
30
  case "$PLATFORM" in
31
- ios|android|backend|frontend) ;;
31
+ frontend) PLATFORM=web ;;
32
+ ios|android|backend|web) ;;
32
33
  *)
33
- echo "extract-conventions: invalid platform: $PLATFORM (expected ios|android|backend|frontend)" >&2
34
+ echo "extract-conventions: invalid platform: $PLATFORM (expected ios|android|backend|web)" >&2
34
35
  exit 1
35
36
  ;;
36
37
  esac
@@ -100,7 +101,7 @@ scan_roots() {
100
101
  [ -d "$REPO_PATH/$d" ] && roots+=("$REPO_PATH/$d")
101
102
  done
102
103
  ;;
103
- frontend)
104
+ web)
104
105
  for d in src app components features lib hooks pages; do
105
106
  [ -d "$REPO_PATH/$d" ] && roots+=("$REPO_PATH/$d")
106
107
  done
@@ -341,7 +342,7 @@ bucket_folder_structure() {
341
342
  empty_bucket
342
343
  fi
343
344
  ;;
344
- frontend)
345
+ web)
345
346
  local feats
346
347
  feats=$(run_find -type d -name 'features' 2>/dev/null | head -10)
347
348
  if [ -z "$feats" ]; then
@@ -439,7 +440,7 @@ bucket_state_holder() {
439
440
  backend)
440
441
  empty_bucket
441
442
  ;;
442
- frontend)
443
+ web)
443
444
  # Look for hooks (useXxx) or stores
444
445
  local files
445
446
  files=$(run_find -type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.js' -o -name '*.jsx' \) 2>/dev/null || true)
@@ -480,7 +481,7 @@ bucket_view_naming() {
480
481
  backend)
481
482
  empty_bucket
482
483
  ;;
483
- frontend)
484
+ web)
484
485
  local files
485
486
  files=$(run_find -type f \( -name '*.tsx' -o -name '*.jsx' \) 2>/dev/null || true)
486
487
  if [ -z "$files" ]; then empty_bucket; return; fi
@@ -522,7 +523,7 @@ bucket_navigator_naming() {
522
523
  backend)
523
524
  empty_bucket
524
525
  ;;
525
- frontend)
526
+ web)
526
527
  empty_bucket
527
528
  ;;
528
529
  esac
@@ -542,7 +543,7 @@ bucket_usecase_naming() {
542
543
  backend)
543
544
  emit_naming_bucket "*.py" "" "Service" "Handler"
544
545
  ;;
545
- frontend)
546
+ web)
546
547
  # useFooQuery / useFooMutation as a proxy
547
548
  local files cnt sample
548
549
  files=$(run_find -type f \( -name '*.ts' -o -name '*.tsx' \) 2>/dev/null || true)
@@ -573,7 +574,7 @@ bucket_repository_naming() {
573
574
  backend)
574
575
  emit_naming_bucket "*.py" "" "Repository" "Dao"
575
576
  ;;
576
- frontend)
577
+ web)
577
578
  emit_naming_bucket "*.ts" "" "Api" "Client"
578
579
  ;;
579
580
  esac
@@ -593,7 +594,7 @@ bucket_dto_naming() {
593
594
  backend)
594
595
  emit_naming_bucket "*.py" "" "Response" "Request" "In" "Out"
595
596
  ;;
596
- frontend)
597
+ web)
597
598
  emit_naming_bucket "*.ts" "" "Dto" "Response" "Request"
598
599
  ;;
599
600
  esac
@@ -640,7 +641,7 @@ bucket_ui_state_model() {
640
641
  empty_bucket
641
642
  return
642
643
  ;;
643
- frontend)
644
+ web)
644
645
  local hook_files
645
646
  hook_files=$(run_find -type f \( -name 'use*.ts' -o -name 'use*.tsx' \) 2>/dev/null | head -50 || true)
646
647
  if [ -z "$hook_files" ]; then empty_bucket; return; fi
@@ -689,7 +690,7 @@ bucket_test_method_naming() {
689
690
  backend)
690
691
  test_files=$(run_find -type f -name 'test_*.py' 2>/dev/null | head -20 || true)
691
692
  ;;
692
- frontend)
693
+ web)
693
694
  test_files=$(run_find -type f \( -name '*.test.ts' -o -name '*.test.tsx' -o -name '*.spec.ts' -o -name '*.spec.tsx' \) 2>/dev/null | head -20 || true)
694
695
  ;;
695
696
  esac
@@ -709,7 +710,7 @@ bucket_test_method_naming() {
709
710
  backend)
710
711
  underscore_count=$((underscore_count + $(count_matches -E '^def +test_[a-z0-9_]+' "$f")))
711
712
  ;;
712
- frontend)
713
+ web)
713
714
  it_count=$((it_count + $(count_matches -E "(it|test)\\(['\"\`]" "$f")))
714
715
  ;;
715
716
  esac
@@ -739,7 +740,7 @@ bucket_test_method_naming() {
739
740
  empty_bucket
740
741
  fi
741
742
  ;;
742
- frontend)
743
+ web)
743
744
  if [ "$it_count" -gt 0 ]; then
744
745
  emit_bucket "it/test sentence" "it('returns error when email invalid', ...)" "$(confidence_for "$it_count")" "$evidence_json" '["describe-it","test-only"]'
745
746
  else
@@ -837,7 +838,7 @@ bucket_accessibility_identifier() {
837
838
  empty_bucket
838
839
  fi
839
840
  ;;
840
- frontend)
841
+ web)
841
842
  local files ids
842
843
  files=$(run_find -type f \( -name '*.tsx' -o -name '*.jsx' \) 2>/dev/null | head -100 || true)
843
844
  if [ -z "$files" ]; then empty_bucket; return; fi
@@ -901,7 +902,7 @@ bucket_localization_key() {
901
902
  ;;
902
903
  backend)
903
904
  empty_bucket; return ;;
904
- frontend)
905
+ web)
905
906
  local json_files
906
907
  json_files=$(run_find -type f -path '*i18n*' -name '*.json' 2>/dev/null | head -5 || true)
907
908
  if [ -n "$json_files" ]; then
@@ -1002,7 +1003,7 @@ bucket_di_registration() {
1002
1003
  empty_bucket
1003
1004
  fi
1004
1005
  ;;
1005
- frontend)
1006
+ web)
1006
1007
  files=$(run_find -type f \( -name '*.tsx' -o -name '*.ts' \) 2>/dev/null || true)
1007
1008
  if [ -z "$files" ]; then empty_bucket; return; fi
1008
1009
  local context_count zustand_count hook_count
@@ -31,7 +31,7 @@ First step of every `multi-agent` flow **that touches a remote provider**.
31
31
  - Breadcrumb (per `$HOME/.claude/multi-agent-refs/picker-contract.md` Step narration): before the question, print the narrator line `<localized: "Step 1/N: account selection">` (`N` = total Phase 0 steps for the active flow).
32
32
  - `header`: "Account" (English chip)
33
33
  - `question`: `<localized: "Which account should this run use?">`
34
- - one option per account: `label` = account label (English), `description` = providers in `outputLanguage`
34
+ - one option per account: `label` = the account name verbatim (a proper noun, never translated), `description` = providers in `outputLanguage`
35
35
  ```
36
36
  [1/N] {question}
37
37
  > {label} ({providers})
@@ -48,9 +48,9 @@ Selects extra repos the pipeline may touch beyond the primary repo(s) - typica
48
48
 
49
49
  4. **Empty submit** - user picks nothing → `extras=[]`, primary repo(s) only.
50
50
 
51
- ## Frontend repos - `frontendRepos`
51
+ ## Web repos - `webRepos`
52
52
 
53
- Frontend repos are rarely submodules of the app repo, so submodule detection never finds them. `prefs.projects[<key>].frontendRepos[]` is the primary source for them and is merged into the candidate list alongside the detected submodules. Only `/multi-agent:analysis` used to read this key, which meant the pipeline's own dev-context picker could not offer a frontend repo at all.
53
+ Web repos are rarely submodules of the app repo, so submodule detection never finds them. `prefs.projects[<key>].webRepos[]` (or the pre-rename `frontendRepos[]`) is the primary source for them and is merged into the candidate list alongside the detected submodules. Only `/multi-agent:analysis` used to read this key, which meant the pipeline's own dev-context picker could not offer a web repo at all.
54
54
 
55
55
  ## Pref override - `editableRelatedRepos`
56
56
 
@@ -6,7 +6,7 @@ description: "Internal - input type detection for multi-agent dispatcher."
6
6
 
7
7
  The top-level `multi-agent` command classifies user arguments per the rules below.
8
8
 
9
- > **Language**: Schema reference only - no user-facing text. Picker `label` + `header` always English (`promptLanguage` is locked to `"en"`); `question` + `description` follow `outputLanguage` per the `rules.md` matrix. Commit messages, branch names and PR titles stay English; PR/Jira/Confluence **bodies** follow `outputLanguage`.
9
+ > **Language**: Schema reference only - no user-facing text. Picker `header` is always English (`promptLanguage` is locked to `"en"`); `question` + `label` + `description` follow `outputLanguage` per the `rules.md` matrix. Commit messages, branch names and PR titles stay English; PR/Jira/Confluence **bodies** follow `outputLanguage`.
10
10
 
11
11
  ## Type Table
12
12
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  ### Phase 1 - Fetch & extract (parallel)
6
6
 
7
- For each entry in `state.analysisSpec.contextLinks[]`, fan out by `type`. Entries tagged `binding: true` (Q5 inputs) land in `evidence.standards[]` regardless of underlying source type so Section 7 can iterate them as one set.
7
+ For each entry in `state.analysisSpec.contextLinks[]`, fan out by `type`. Entries tagged `binding: true` (Standards-question inputs) land in `evidence.standards[]` regardless of underlying source type so Section 7 can iterate them as one set.
8
8
 
9
9
  | type | Command | Output bucket |
10
10
  |------|---------|---------------|
@@ -12,7 +12,7 @@ For each entry in `state.analysisSpec.contextLinks[]`, fan out by `type`. Entrie
12
12
  | confluence | `~/.claude/lib/fetch-confluence.sh <url>` | `state.analysisSpec.evidence.confluence[]` |
13
13
  | figma | **MUST** establish the Figma access tier per Locked decision #12. Tier 1 (preferred): call `mcp__claude_ai_Figma__get_design_context` (primary), `mcp__claude_ai_Figma__get_screenshot`, `mcp__claude_ai_Figma__get_metadata` for every node ID; auth failure runs `authenticate` + `complete_authentication` then retries. Tier 2 (fallback): `GET https://api.figma.com/v1/files/{fileKey}/nodes?ids={nodeId}` for design context and `GET /v1/images/{fileKey}?ids={nodeId}&format=png&scale=2` for screenshots, with PAT from `~/.claude/lib/credential-store.sh get <logical-key>` (logical key = `prefs.global.keychainMapping.figma`); canonical component resolves via repo `*.figma.swift` / `*.figma.kt` mapping. Tier 3 (last resort): user-attached screenshot, `codeConnectSnippets: []`, forced Open Question. Capture each `CodeConnectSnippet` block verbatim when on Tier 1 (component name + modifier chain). **Annotation capture (when the project `figma-config` has `annotations.enabled`):** on Tier 1, walk the `annotations[]` the `get_design_context` payload returns for each node (read `label` / `labelMarkdown`); on Tier 2, run `~/.claude/lib/fetch-figma-annotations.sh --file-key <fileKey> --node-id <ids> --lang-prefixes <config.annotations.langPrefixes>`. Parse each annotation by the configured language prefixes (prefixed `TR:/EN:` wins, else line1/line2, else single) and persist to `annotations[]`. The annotation is the authoritative copy for its node (Locked 3); the visible text layer is a placeholder. Persist `state.figmaAccess.tier`. See Locked decision #12 and `$HOME/.claude/rules/figma-pipeline.md` "MUST: Figma access - 3-tier fallback chain". | `state.analysisSpec.evidence.figma[]` (records: `nodeId`, `screenshotUrl`, `codeConnectSnippets[]`, `tokens[]`, `textLayers[]`, `annotations[]`, `tier`; see `analysis-spec.schema.json`) |
14
14
  | jira | `gh api` or Jira REST API for issue summary | `state.analysisSpec.evidence.jira[]` |
15
- | document | `~/.claude/lib/fetch-document.sh <path-or-url>` (`.docx` via python3 stdlib, `.md` / `.txt` read directly, `.pdf` only when `pdftotext` exists). Exit `6` is a soft skip, not a failure: record the file with `fetched: false` so Section 21 still cites it as referenced-but-not-fetched. | `state.analysisSpec.evidence.documents[]`, or `evidence.standards[]` when `binding: true` |
15
+ | document | `~/.claude/lib/fetch-document.sh <path-or-url>` (`.docx` via the python3 standard library - `python-docx` is never imported and must not be installed - `.md` / `.txt` read directly, `.pdf` only when `pdftotext` exists). Exit `6` is a soft skip, not a failure: record the file with `fetched: false` so Section 21 still cites it as referenced-but-not-fetched. | `state.analysisSpec.evidence.documents[]`, or `evidence.standards[]` when `binding: true` |
16
16
  | generic-doc | WebFetch on demand | `state.analysisSpec.evidence.confluence[]` (generic bucket) unless `binding: true` -> `evidence.standards[]` |
17
17
  | `local-file` | `Read` (no fetch) on tilde-expanded absolute path | `state.analysisSpec.evidence.standards[]` |
18
18
  | `wiki` | `git clone --depth 1 https://github.com/<owner>/<repo>.wiki.git /tmp/<repo>-wiki`, then `Read /tmp/<repo>-wiki/<PageName>.md` (`-` decoded back to space in PageName). Fallback chain: `gh api repos/<owner>/<repo>/contents/<file>.md` for repo-hosted docs if wiki repo is 404. | `state.analysisSpec.evidence.standards[]` |
@@ -61,7 +61,7 @@ After Phase 1 finishes, run a deeper scan per repo to enable Section 7's reuse-f
61
61
  | iOS | `Domains/`, `Common/`, `Core/`, `App/` |
62
62
  | Android | `app/src/`, `feature/`, `core/`, `common/` |
63
63
  | Backend | `src/`, `api/`, `services/` |
64
- | Frontend | `src/`, `app/`, `components/`, `features/`, `lib/` (override with `prefs.projects[<key>].frontendRoots[]`) |
64
+ | Web | `src/`, `app/`, `components/`, `features/`, `lib/` (override with `prefs.projects[<key>].webRoots[]`, or the pre-rename `frontendRoots[]`) |
65
65
 
66
66
  Skip dirs (always): `.build`, `DerivedData`, `Pods`, `node_modules`, `.next`, `build/`, `.gradle`, `vendor/`.
67
67
 
@@ -91,7 +91,7 @@ If `wc -l < $CANDIDATES` exceeds 200, record `fetchWarnings += "feature-name too
91
91
  | tokens | `*Token` enums under `UIAssetTokens/Generated/` | `Theme.kt` / `tokens.ts` / `tailwind.config.*` |
92
92
  | localizationKeys | `LocalizationStringKeys.swift` public enum + cases | `strings.xml` keys / `i18n/*.json` keys |
93
93
  | testingIdentifiers | `ui-testing-identifiers.json` | `testTag` strings / `data-testid` constants |
94
- | analyticsEvents | Generated `AnalyticsEvents/*.swift` + `Analytics.logEvent\(` call sites | Equivalent Android / Frontend / Backend telemetry |
94
+ | analyticsEvents | Generated `AnalyticsEvents/*.swift` + `Analytics.logEvent\(` call sites | Equivalent Android / Web / Backend telemetry |
95
95
 
96
96
  **Tagging rule** for each row:
97
97