@mmerterden/multi-agent-pipeline 14.2.1 → 15.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 +118 -6
- package/README.md +20 -9
- package/README.tr.md +150 -0
- package/docs/FIGMA_PIPELINE.md +3 -3
- package/docs/adr/0006-skills-core-external-split.md +1 -1
- package/docs/adr/0009-claude-stack-skills-plugin-only.md +31 -0
- package/docs/adr/README.md +1 -0
- package/docs/architecture.md +24 -9
- package/docs/ecosystem.md +237 -0
- package/docs/features.md +5 -5
- package/index.js +2 -0
- package/install/_codex-agents.mjs +11 -2
- package/install/_common.mjs +65 -1
- package/install/_dev-only-files.mjs +0 -1
- package/install/_platform-filter.mjs +73 -7
- package/install/_plugin-skills.mjs +33 -8
- package/install/claude.mjs +144 -59
- package/install/codex.mjs +37 -7
- package/install/copilot.mjs +36 -11
- package/install/index.mjs +6 -2
- package/install/templates/codex-instructions.md +1 -1
- package/install/templates/copilot-instructions.md +15 -12
- package/package.json +1 -2
- package/pipeline/commands/multi-agent/SKILL.md +4 -2
- package/pipeline/commands/multi-agent/analysis/SKILL.md +5 -5
- package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/autopilot/SKILL.md +6 -2
- package/pipeline/commands/multi-agent/build-optimize/SKILL.md +9 -9
- package/pipeline/commands/multi-agent/channels/SKILL.md +16 -5
- package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +186 -0
- package/pipeline/commands/multi-agent/create-jira/SKILL.md +4 -4
- package/pipeline/commands/multi-agent/dev/SKILL.md +10 -23
- package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +10 -2
- package/pipeline/commands/multi-agent/dev-local/SKILL.md +10 -24
- package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +10 -3
- package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/help/SKILL.md +19 -4
- package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/jira/SKILL.md +13 -2
- package/pipeline/commands/multi-agent/language/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/local/SKILL.md +6 -2
- package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +6 -2
- package/pipeline/commands/multi-agent/log/SKILL.md +7 -1
- package/pipeline/commands/multi-agent/prune-prompts/SKILL.md +81 -0
- package/pipeline/commands/multi-agent/resume/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/{ship → resume-local}/SKILL.md +13 -9
- package/pipeline/commands/multi-agent/setup/SKILL.md +5 -5
- package/pipeline/commands/multi-agent/stack/SKILL.md +55 -43
- package/pipeline/commands/multi-agent/store-ready/SKILL.md +3 -3
- package/pipeline/commands/multi-agent/sync/SKILL.md +18 -11
- package/pipeline/commands/multi-agent/testflight-validation/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/uninstall/SKILL.md +2 -0
- package/pipeline/commands/multi-agent/update/SKILL.md +1 -1
- package/pipeline/lib/extract-conventions.sh +44 -15
- package/pipeline/lib/fetch-figma-annotations.sh +8 -1
- package/pipeline/lib/fetch-fortify.sh +23 -8
- package/pipeline/lib/figma-screenshot.sh +11 -1
- package/pipeline/lib/issue-fetcher.sh +77 -10
- package/pipeline/lib/md2confluence-v3.py +16 -2
- package/pipeline/lib/parse-complaints.sh +306 -0
- package/pipeline/lib/plan-todos.sh +5 -2
- package/pipeline/lib/post-pr-review.sh +8 -6
- package/pipeline/lib/shadow-git.sh +50 -9
- package/pipeline/lib/submodule-detector.sh +8 -1
- package/pipeline/multi-agent-refs/_input-parser.md +1 -1
- package/pipeline/multi-agent-refs/channels/confluence.md +3 -0
- package/pipeline/multi-agent-refs/channels/issue-comment.md +2 -2
- package/pipeline/multi-agent-refs/channels/jira.md +13 -2
- package/pipeline/multi-agent-refs/channels/pr-review-actions.md +1 -1
- package/pipeline/multi-agent-refs/channels/pr.md +20 -0
- package/pipeline/multi-agent-refs/channels/wiki.md +4 -4
- package/pipeline/multi-agent-refs/complaint-analysis-template.md +99 -0
- package/pipeline/multi-agent-refs/component-dispatch.md +6 -6
- package/pipeline/multi-agent-refs/cross-cli-contract.md +16 -16
- package/pipeline/multi-agent-refs/features/external-context-injection.md +1 -1
- package/pipeline/multi-agent-refs/features/stack-skill-routing.md +5 -5
- package/pipeline/multi-agent-refs/features/worktree-finalize.md +1 -1
- package/pipeline/multi-agent-refs/generate-issue.md +3 -3
- package/pipeline/multi-agent-refs/issue-jira-triad.md +3 -3
- package/pipeline/multi-agent-refs/payload-contracts.md +67 -0
- package/pipeline/multi-agent-refs/phases/modes.md +20 -0
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +2 -2
- package/pipeline/multi-agent-refs/phases/phase-1-analysis.md +7 -7
- package/pipeline/multi-agent-refs/phases/phase-2-planning.md +5 -5
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +3 -3
- package/pipeline/multi-agent-refs/phases/phase-4-review.md +12 -12
- package/pipeline/multi-agent-refs/phases/phase-5-test.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-6-commit.md +8 -40
- package/pipeline/multi-agent-refs/phases/phase-7-report.md +5 -3
- package/pipeline/multi-agent-refs/phases.md +6 -0
- package/pipeline/multi-agent-refs/rules.md +2 -0
- package/pipeline/multi-agent-refs/tracker-contract.md +1 -1
- package/pipeline/multi-agent-refs/wiki-capture.md +2 -2
- package/pipeline/preferences-template.json +13 -5
- package/pipeline/rules/figma-pipeline.md +2 -2
- package/pipeline/schemas/agent-state.schema.json +1 -1
- package/pipeline/schemas/complaint-analysis-spec.schema.json +216 -0
- package/pipeline/schemas/migrations/prefs-2.5.0-to-2.6.0.mjs +46 -0
- package/pipeline/schemas/prefs.schema.json +277 -67
- package/pipeline/schemas/token-budget.json +2 -2
- package/pipeline/scripts/_stack-routing.mjs +79 -0
- package/pipeline/scripts/audit-log-rotate.sh +14 -1
- package/pipeline/scripts/build-skills-index.mjs +11 -0
- package/pipeline/scripts/build-stack-plugins.mjs +35 -60
- package/pipeline/scripts/check-derived-drift.mjs +65 -29
- package/pipeline/scripts/diff-explain.mjs +41 -3
- package/pipeline/scripts/diff-risk-score.mjs +72 -8
- package/pipeline/scripts/gc-worktrees.sh +4 -1
- package/pipeline/scripts/gen-mode-dispatch.mjs +1 -1
- package/pipeline/scripts/gen-skills-index.mjs +1 -1
- package/pipeline/scripts/learning-curve.mjs +8 -2
- package/pipeline/scripts/match-skills.mjs +8 -2
- package/pipeline/scripts/migrate-prefs.mjs +28 -20
- package/pipeline/scripts/output-quality-check.sh +15 -4
- package/pipeline/scripts/phase-tracker.sh +33 -12
- package/pipeline/scripts/phase0-exit-gate.mjs +3 -2
- package/pipeline/scripts/pre-commit-check.sh +69 -22
- package/pipeline/scripts/render-agent-log-cost.sh +8 -3
- package/pipeline/scripts/render-cost-summary.sh +42 -22
- package/pipeline/scripts/render-work-summary.sh +47 -13
- package/pipeline/scripts/review-scope.mjs +1 -1
- package/pipeline/scripts/run-aggregator.mjs +43 -14
- package/pipeline/scripts/scan-agent-config.sh +1 -1
- package/pipeline/scripts/skill-conformance.mjs +165 -30
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +1 -1
- package/pipeline/scripts/smoke-schema-validation.sh +5 -1
- package/pipeline/scripts/test-gap-rules/android.json +25 -0
- package/pipeline/scripts/test-gap-rules/ios.json +34 -0
- package/pipeline/scripts/test-gap-rules/node.json +29 -0
- package/pipeline/scripts/test-gap-rules/python.json +25 -0
- package/pipeline/scripts/test-gap-scan.mjs +45 -6
- package/pipeline/scripts/uninstall.mjs +196 -14
- package/pipeline/scripts/update-issue-progress.sh +12 -16
- package/pipeline/scripts/validate-complaint-doc.mjs +229 -0
- package/pipeline/scripts/validate-reviewer.mjs +9 -3
- package/pipeline/scripts/worktree-finalize.sh +23 -2
- package/pipeline/skills/.skill-manifest.json +156 -108
- package/pipeline/skills/.skills-index.json +459 -13
- package/pipeline/skills/shared/README.md +15 -11
- package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +4 -0
- package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-complaint-analysis/SKILL.md +49 -0
- package/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +4 -17
- package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +8 -0
- package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +5 -18
- package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +8 -0
- package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +2 -2
- package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-local/SKILL.md +4 -0
- package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +4 -0
- package/pipeline/skills/shared/core/multi-agent-prune-prompts/SKILL.md +83 -0
- package/pipeline/skills/shared/core/{multi-agent-ship → multi-agent-resume-local}/SKILL.md +10 -6
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +79 -22
- package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +8 -8
- package/pipeline/skills/shared/core/multi-agent-testflight-validation/SKILL.md +1 -1
- package/pipeline/skills/shared/external/ios-coding-standard/modules/_TEMPLATE.yml +2 -2
- package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +368 -33
- package/pipeline/skills/shared/external/ios-coding-standard/references/swiftlint.draft.yml +1 -2
- package/pipeline/skills/shared/external/ios-coding-standard/scripts/check_structure.py +765 -0
- package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +75 -0
- package/pipeline/skills/shared/external/ios-module-structure/modules/_TEMPLATE.yml +131 -0
- package/pipeline/skills/shared/external/ios-module-structure/references/rules.yml +559 -0
- package/pipeline/skills/shared/external/ios-module-structure/scripts/check_structure.py +765 -0
- package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +302 -0
- package/pipeline/skills/shared/external/localization-reuse-map/example-mapping.json +187 -0
- package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +156 -0
- package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +108 -0
- package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +176 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +865 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +335 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +344 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +130 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +264 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-key-shots.py +298 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +529 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +187 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +171 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +184 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/snapshot-resources.sh +26 -0
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +173 -0
- package/pipeline/skills/skills-index.md +9 -5
|
@@ -75,7 +75,7 @@ If changes include UI files (iOS: `*View.swift`, `*Screen.swift`, `*Cell.swift`;
|
|
|
75
75
|
- Missing `.accessibilityIdentifier` / `testTag` → **important**
|
|
76
76
|
- Dynamic Type / font scaling not supported → **important**
|
|
77
77
|
|
|
78
|
-
**iOS - Apple HIG compliance** (skills: `hig-patterns`, `hig-components-layout`, `hig-foundations`):
|
|
78
|
+
**iOS - Apple HIG compliance** (skills: `ai-ios-toolkit:hig-patterns`, `ai-ios-toolkit:hig-components-layout`, `ai-ios-toolkit:hig-foundations`):
|
|
79
79
|
- Navigation pattern mismatch (e.g. custom back button instead of system) → **important**
|
|
80
80
|
- Non-standard gesture without discoverability hint → **suggestion**
|
|
81
81
|
- Missing safe area / keyboard avoidance → **important**
|
|
@@ -83,12 +83,12 @@ If changes include UI files (iOS: `*View.swift`, `*Screen.swift`, `*Cell.swift`;
|
|
|
83
83
|
|
|
84
84
|
**iOS - SwiftUI interaction & accessibility conventions.** Gated to changed SwiftUI files. These are rule-registry territory as of v14.0.0, not a list transcribed here: Step 1.78 resolves them from whichever registry declares SwiftUI scope, so the criteria and their severities live in one place instead of drifting between this doc and the skill. Reviewers receive the resolved rule IDs. Native-SwiftUI-first unless the project's `figma-config` `ui.*` declares a custom system, in which case check against that system. Reference skills, when no registry covers the change: `figma-navigation`, `figma-overlays`, `figma-bottom-sheets`, `figma-to-swiftui`.
|
|
85
85
|
|
|
86
|
-
**Android - Material Design compliance** (skills: `compose-components`, `android-architecture`):
|
|
86
|
+
**Android - Material Design compliance** (skills: `ai-android-toolkit:compose-components`, `ai-android-toolkit:android-architecture`):
|
|
87
87
|
- Non-Material3 component when M3 equivalent exists → **suggestion**
|
|
88
88
|
- Missing `contentDescription` on icons/images → **blocking**
|
|
89
89
|
- Hardcoded dp values instead of Material spacing tokens → **suggestion**
|
|
90
90
|
|
|
91
|
-
**App Store / Play Store readiness** (skills: `app-store-review`, `play-store-review`):
|
|
91
|
+
**App Store / Play Store readiness** (skills: `ai-ios-toolkit:app-store-review`, `ai-android-toolkit:play-store-review`):
|
|
92
92
|
- Privacy: API usage without purpose string / permission rationale → **blocking**
|
|
93
93
|
- Deprecated API usage flagged by latest SDK → **important**
|
|
94
94
|
|
|
@@ -249,7 +249,7 @@ Launch Agent instances **in parallel** using the shared `code-reviewer` subagent
|
|
|
249
249
|
| ---------- | --------------- | --- | --- | --- | --- | --- |
|
|
250
250
|
| Reviewer 1 | `code-reviewer` | `claude-fable-5` | `claude-opus-5` | `gpt-5.6` @ `xhigh` | Deep security + architecture | `api-security-best-practices`, `architecture` |
|
|
251
251
|
| Reviewer 2 | `code-reviewer` | (not dispatched) | `gpt-5.4` | `gpt-5.4` @ `high` | Edge cases, different perspective | cross-model diversity |
|
|
252
|
-
| Reviewer 3 | `code-reviewer` | `claude-sonnet-5` | `claude-sonnet-5` | `gpt-5.6` @ `medium` | Quality + correctness + naming | `clean-code`, stack-specific skill |
|
|
252
|
+
| Reviewer 3 | `code-reviewer` | `claude-sonnet-5` | `claude-sonnet-5` | `gpt-5.6` @ `medium` | Quality + correctness + naming | `ai-backend-toolkit:clean-code`, stack-specific skill |
|
|
253
253
|
| Triage | triage persona | `claude-fable-5` | `claude-opus-5` | `gpt-5.6` @ `max` | Filter false positives + out-of-scope | - |
|
|
254
254
|
|
|
255
255
|
Reviewer count per host: **Claude Code 2, Copilot CLI 3, Codex CLI 3**.
|
|
@@ -285,12 +285,12 @@ Each reviewer inherits the `code-reviewer` agent's focus areas (Security, Archit
|
|
|
285
285
|
|
|
286
286
|
| Stack | Reviewer 1 (Fable / Opus on Copilot) | Reviewer 2 (GPT-5.4 - Copilot CLI only) | Reviewer 3 (Sonnet) |
|
|
287
287
|
|-------|-------------------|-----------------------------------------|---------------------|
|
|
288
|
-
| iOS/Swift | `ios-security`, `swiftui-performance`, `hig-patterns` | `swift-concurrency`, `ios-accessibility` | `swiftui-pro`, `swift-testing` |
|
|
289
|
-
| Android/Kotlin | `android-security`, `android-performance` | `compose-testing`, `android-architecture` | `compose-components`, `kotlin-coroutines-expert` |
|
|
290
|
-
| Python | `api-security-best-practices` | `fastapi-pro` | `python-patterns` |
|
|
291
|
-
| Node.js | `api-security-best-practices` | `nodejs-backend-patterns` | `typescript-patterns` |
|
|
292
|
-
| Docker | `docker-expert` | `docker-expert` | `ci-cd-pipelines` |
|
|
293
|
-
| Generic | `security-review` | `clean-code` | `clean-code` |
|
|
288
|
+
| iOS/Swift | `ai-ios-toolkit:ios-security`, `ai-ios-toolkit:swiftui-performance`, `ai-ios-toolkit:hig-patterns` | `ai-ios-toolkit:swift-concurrency`, `ai-ios-toolkit:ios-accessibility` | `ai-ios-toolkit:swiftui-pro`, `ai-ios-toolkit:swift-testing` |
|
|
289
|
+
| Android/Kotlin | `ai-android-toolkit:android-security`, `ai-android-toolkit:android-performance` | `ai-android-toolkit:compose-testing`, `ai-android-toolkit:android-architecture` | `ai-android-toolkit:compose-components`, `ai-android-toolkit:kotlin-coroutines-expert` |
|
|
290
|
+
| Python | `ai-backend-toolkit:api-security-best-practices` | `ai-backend-toolkit:fastapi-pro` | `ai-backend-toolkit:python-patterns` |
|
|
291
|
+
| Node.js | `ai-backend-toolkit:api-security-best-practices` | `ai-backend-toolkit:nodejs-backend-patterns` | `ai-frontend-toolkit:typescript-patterns` |
|
|
292
|
+
| Docker | `ai-backend-toolkit:docker-expert` | `ai-backend-toolkit:docker-expert` | `ai-backend-toolkit:ci-cd-pipelines` |
|
|
293
|
+
| Generic | `security-review` | `ai-backend-toolkit:clean-code` | `ai-backend-toolkit:clean-code` |
|
|
294
294
|
|
|
295
295
|
Skills are injected into reviewer prompt context - the reviewer uses them as reference, not as commands.
|
|
296
296
|
|
|
@@ -299,7 +299,7 @@ Skills are injected into reviewer prompt context - the reviewer uses them as r
|
|
|
299
299
|
Runs when `state.taskType == "component"` **or** the diff touches SwiftUI UI files
|
|
300
300
|
AND the task carried a Figma reference. Two checks, in order:
|
|
301
301
|
|
|
302
|
-
1. **`ai-ios-
|
|
302
|
+
1. **`ai-ios-toolkit:figma-review`** over the implemented frames - the
|
|
303
303
|
plugin's own component review, including the 14-item checklist that covers design
|
|
304
304
|
tokens, accessibility identifiers, previews and Code Connect.
|
|
305
305
|
2. **`/multi-agent:design-check`** for pixel + spacing + typography + colour
|
|
@@ -320,7 +320,7 @@ reading a diff cannot see spacing; something has to compare against the design.
|
|
|
320
320
|
Skip only when the diff has no UI change. Record the outcome in
|
|
321
321
|
`consensus.visualConformance` so Phase 7 reports whether it ran.
|
|
322
322
|
|
|
323
|
-
**iOS/Swift - interaction & convention checks (conditional).** Step 1.78 resolves these. Where no registry covers the change, reviewers fall back to the analysis doc (Section 14 Code Connect mapping) and, when `ai-ios-
|
|
323
|
+
**iOS/Swift - interaction & convention checks (conditional).** Step 1.78 resolves these. Where no registry covers the change, reviewers fall back to the analysis doc (Section 14 Code Connect mapping) and, when `ai-ios-toolkit` is enabled, that plugin's navigation / overlay / bottom-sheet + accessibility conventions.
|
|
324
324
|
|
|
325
325
|
**Module review guides (conditional, all stacks).** Step 1.78 resolves them into `criteria-manifest.json` → `moduleGuides`. Inject with the directive: read each guide, apply its rules to the changed files under its directory - a guide governs only its own subtree, and its violations are findings triaged like any other. Same contract as `/multi-agent:review` Step 2b.
|
|
326
326
|
|
|
@@ -100,7 +100,7 @@ Tier 1 / Tier 2 records print `screenshotUrl` from the captured evidence (Tier 2
|
|
|
100
100
|
bash $HOME/.claude/scripts/phase-tracker.sh now 5 "awaiting local test (user)"
|
|
101
101
|
bash $HOME/.claude/scripts/phase-tracker.sh render
|
|
102
102
|
```
|
|
103
|
-
The waiting state persists in `tracker-state.json` across the handoff; `/multi-agent:
|
|
103
|
+
The waiting state persists in `tracker-state.json` across the handoff; `/multi-agent:resume-local` and `/multi-agent:manual-test` CONTINUE this state file and never re-init it (`$HOME/.claude/multi-agent-refs/tracker-contract.md` "Continuation runs").
|
|
104
104
|
6. If fix needed:
|
|
105
105
|
- Branch already has WIP commit (from step 2) - changes are safe
|
|
106
106
|
- **Heal stale admin state first** (same contract as Phase 0 - step 3's
|
|
@@ -106,6 +106,8 @@ Branch **deterministically**, no implicit fallback. Read `agent-state.json` and
|
|
|
106
106
|
|
|
107
107
|
#### Step 3 - PR Description (technical detail for reviewers)
|
|
108
108
|
|
|
109
|
+
**Section set + markup dialect: `channels/pr.md` - read it first.** Phase 7 channels replaces this body with that section set, so build to it. Required reading: `payload-contracts.md`.
|
|
110
|
+
|
|
109
111
|
Generate a structured PR description based on task type. The PR body targets **code reviewers** - it should be technical: what changed, why, architecture decisions, how to verify.
|
|
110
112
|
|
|
111
113
|
**required**: Run all generated text (PR body, commit message) through the `humanizer` skill before posting. This removes AI-generated patterns (inflated language, filler phrases, repetitive structure) and makes the output sound like a developer wrote it.
|
|
@@ -116,49 +118,15 @@ Generate a structured PR description based on task type. The PR body targets **c
|
|
|
116
118
|
- Bitbucket: similar patterns
|
|
117
119
|
- Use `Ref: #N`, `Related: #N`, or `See: {jiraId}` instead
|
|
118
120
|
|
|
119
|
-
**Default Reviewers**:
|
|
120
|
-
|
|
121
|
-
```
|
|
122
|
-
Default reviewers for this project? (comma-separated GitHub usernames, or skip):
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Save to `prefs.projects[{project}].defaultReviewers: ["user1", "user2", "user3", "user4"]`
|
|
121
|
+
**Default Reviewers**: use `prefs.projects[{project}].defaultReviewers` when set; otherwise ask once ("Default reviewers for this project? comma-separated, or skip") and persist the answer there. Per-remote resolution rules are in "Default reviewers (required on every PR)" below - this is the prefs half only.
|
|
126
122
|
|
|
127
|
-
**Standard PR (bug fix, feature, refactor)
|
|
123
|
+
**Standard PR (bug fix, feature, refactor)** - invocation shape; body comes from a file so newlines survive:
|
|
128
124
|
|
|
129
125
|
```bash
|
|
130
126
|
REVIEWERS=$(jq -r '.projects["'$PROJECT'"].defaultReviewers // [] | map("--reviewer " + .) | join(" ")' "$PREFS_FILE")
|
|
131
127
|
gh pr create --base {baseBranch} --head {branch} $REVIEWERS \
|
|
132
128
|
--title "{type}({scope}): {summary} [{jiraId}]" \
|
|
133
|
-
--body
|
|
134
|
-
## Summary
|
|
135
|
-
{1-3 bullet points: what changed and why}
|
|
136
|
-
|
|
137
|
-
## Jira
|
|
138
|
-
{jiraId} - {jira summary or link}
|
|
139
|
-
|
|
140
|
-
## Technical Details
|
|
141
|
-
### Changes
|
|
142
|
-
{For each changed file group, explain WHAT changed and WHY}
|
|
143
|
-
|
|
144
|
-
### Architecture
|
|
145
|
-
{Any structural decisions: new files, moved code, pattern changes}
|
|
146
|
-
|
|
147
|
-
### Dependencies
|
|
148
|
-
{New imports, framework changes, package updates - or "None"}
|
|
149
|
-
|
|
150
|
-
## How to Test
|
|
151
|
-
1. {Step-by-step manual test instructions}
|
|
152
|
-
2. {Verify specific behavior}
|
|
153
|
-
|
|
154
|
-
## Checklist
|
|
155
|
-
- [ ] Build passes (0 errors, 0 warnings)
|
|
156
|
-
- [ ] Tests pass
|
|
157
|
-
- [ ] No hardcoded values (tokens used)
|
|
158
|
-
- [ ] Accessibility verified
|
|
159
|
-
- [ ] Dark mode verified
|
|
160
|
-
EOF
|
|
161
|
-
)"
|
|
129
|
+
--body-file /tmp/pr-body-$TASK_ID.md
|
|
162
130
|
```
|
|
163
131
|
|
|
164
132
|
**UI Component PR (when SwiftUI component detected):**
|
|
@@ -175,9 +143,9 @@ Same `gh pr create` pattern with component-specific body sections:
|
|
|
175
143
|
|
|
176
144
|
CRITICAL: PR description **MUST** preserve real newlines. Never embed `\n` literally - Bitbucket saves it verbatim. Never use HTML entities. Pattern: heredoc → `jq --rawfile` → `curl --data-binary @file`.
|
|
177
145
|
|
|
178
|
-
Required payload fields: `title`, `description` (via rawfile), `fromRef` (id + repo slug + project key), `toRef` (same structure), `state: "OPEN"`, `open: true`, `closed: false`, `locked: false`, `reviewers
|
|
146
|
+
Required payload fields: `title`, `description` (via rawfile), `fromRef` (id + repo slug + project key), `toRef` (same structure), `state: "OPEN"`, `open: true`, `closed: false`, `locked: false`, `reviewers` (the fetched list - `[]` only if that endpoint really returned empty).
|
|
179
147
|
|
|
180
|
-
To **update** an existing PR:
|
|
148
|
+
To **update** an existing PR: use the `channels/pr.md` PUT payload - required, not illustrative. It carries `reviewers`/`fromRef`/`toRef`/`draft` (a PUT clears omitted fields) and the GET's `version` unmodified (`version + 1` → 409). Refetch after, assert the reviewer count held. GitHub: `--body-file`.
|
|
181
149
|
|
|
182
150
|
**Default reviewers (required on every PR)**
|
|
183
151
|
|
|
@@ -307,7 +275,7 @@ update_sibling_links "${PR_URLS[@]}"
|
|
|
307
275
|
|
|
308
276
|
**Then finalize each repo's worktree**, serially and only now - `update_sibling_links` updates one PR per repo and the loop `cd`s per repo, so removing repo 1's worktree mid-loop breaks 2..N. Run `worktree-finalize.sh` once per repo with that repo's `--worktree` / `--project-root` / `--project`; each skips or removes independently.
|
|
309
277
|
|
|
310
|
-
`update_sibling_links` does an UPDATE call per PR (Bitbucket: PUT
|
|
278
|
+
`update_sibling_links` does an UPDATE call per PR (Bitbucket: the `channels/pr.md` PUT payload, current `version`; GitHub: `gh pr edit --body-file`). Idempotent.
|
|
311
279
|
|
|
312
280
|
##### GitHub issue body - list all PRs
|
|
313
281
|
|
|
@@ -153,8 +153,8 @@ Skipped sections: when `planTodos.enabled` is false or no `plan.todos[]` was emi
|
|
|
153
153
|
|
|
154
154
|
## Timeline
|
|
155
155
|
|
|
156
|
-
| # | Phase | Model | Duration | Status | Detail |
|
|
157
|
-
| --- | ----- | ----- | -------- | ------ | ------ |
|
|
156
|
+
| # | Phase | Agent | Model | Duration | Tokens (in/out) | Status | Detail |
|
|
157
|
+
| --- | ----- | ----- | ----- | -------- | --------------- | ------ | ------ |
|
|
158
158
|
|
|
159
159
|
## Agent Activity Report
|
|
160
160
|
|
|
@@ -200,7 +200,7 @@ $HOME/.claude/scripts/log-metric.sh "$TASK_ID" 7 task.completed \
|
|
|
200
200
|
|
|
201
201
|
**Per-run outcome metrics (evidence corpus):** also emit `run-metrics.mjs --state <agent-state.json>` and append/persist its JSON. It records the numbers that actually answer "did this run go well" - review iterations (rework loops), first-pass-clean, reviewer signal-to-noise (accepted / raw findings), consensus verdict, build outcome. Accumulating these across real runs is the real-world validation that golden tasks + benchmarks only approximate; keep the corpus so the pipeline's quality can be measured, not asserted.
|
|
202
202
|
|
|
203
|
-
**Cost Breakdown emission (mandatory):** as part of agent-log compose, append the per-task cost block produced by `render-agent-log-cost.sh
|
|
203
|
+
**Cost Breakdown emission (mandatory):** as part of agent-log compose, append the per-task cost block produced by `render-agent-log-cost.sh`:
|
|
204
204
|
|
|
205
205
|
```bash
|
|
206
206
|
COST_BLOCK=$(bash $HOME/.claude/scripts/render-agent-log-cost.sh "$TASK_ID" 2>/dev/null) && \
|
|
@@ -209,6 +209,8 @@ COST_BLOCK=$(bash $HOME/.claude/scripts/render-agent-log-cost.sh "$TASK_ID" 2>/d
|
|
|
209
209
|
|
|
210
210
|
This is independent of the channels-side `reportContent.costSummary` (which gates the PR-body Cost Summary). agent-log always carries the breakdown when telemetry is present.
|
|
211
211
|
|
|
212
|
+
**Missing-telemetry disclosure (required).** Name untracked phase ids as cost-unavailable in the report and closing summary. Mechanic: `payload-contracts.md`.
|
|
213
|
+
|
|
212
214
|
**Triage memory ingest (mandatory):** after Phase 4 produces a final triage output, persist the accepted/deferred/rejected rows into the per-repo triage corpus so Phase 1 enrichment and Phase 4 prior-art lookup can recall them on future tasks. Idempotent - re-running on the same task writes 0 rows.
|
|
213
215
|
|
|
214
216
|
```bash
|
|
@@ -63,6 +63,12 @@ $HOME/.claude/scripts/phase-tracker.sh update <N> failed # phase failed
|
|
|
63
63
|
$HOME/.claude/scripts/phase-tracker.sh update <N> skipped # --dev mode etc.
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
After every LLM call (counts are additive; skipping this is why runs end with durations but no cost - nothing reconstructs spend afterwards):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
$HOME/.claude/scripts/phase-tracker.sh tokens <N> <in> <out> [cached]
|
|
70
|
+
```
|
|
71
|
+
|
|
66
72
|
For sub-phase progress (e.g. Phase 1's parallel Explore agents, Phase 4's reviewer dispatch + triage + validator gate, Phase 6's commit + push + PR sub-steps):
|
|
67
73
|
|
|
68
74
|
```bash
|
|
@@ -122,6 +122,8 @@ This is the single source of truth. When a contributor or model is unsure where
|
|
|
122
122
|
|
|
123
123
|
4. **Terminal output, log lines, and `echo`/`printf` calls** also use real newlines - never `\n` literals. For multi-line messages, prefer heredoc.
|
|
124
124
|
|
|
125
|
+
5. **Markup dialect is a second axis beyond language.** Markdown: PR body, GitHub issue, wiki files. Jira: wiki markup. Confluence: storage format. Wrong dialect renders literally. Table: `payload-contracts.md`.
|
|
126
|
+
|
|
125
127
|
## Issue Management
|
|
126
128
|
|
|
127
129
|
- **NEVER auto-close** GitHub issues or Jira tickets. Closure requires team review (configurable, typically 4 approvals).
|
|
@@ -310,7 +310,7 @@ The `tasklist_id` meta from the previous session is replaced with the new IDs du
|
|
|
310
310
|
|
|
311
311
|
## Continuation runs (finish / manual-test)
|
|
312
312
|
|
|
313
|
-
A pre-existing `tracker-state.json` for the task is never re-initialized. Rules for any command that continues an earlier run (`/multi-agent:
|
|
313
|
+
A pre-existing `tracker-state.json` for the task is never re-initialized. Rules for any command that continues an earlier run (`/multi-agent:resume-local`, `/multi-agent:manual-test`, resume):
|
|
314
314
|
|
|
315
315
|
1. `init` runs ONLY when no state file exists for the task. Otherwise the existing file is kept - phase history (elapsed, tokens, model, meta) survives.
|
|
316
316
|
2. The continuing command re-declares its phase set with `add` - `add` is idempotent, so existing phases keep their name, status, and token history; only genuinely new phases are appended. The card renders phases sorted by numeric id, so mixed sets stay in order.
|
|
@@ -77,9 +77,9 @@ Save the answer to `prefs.global.wikiDefault` for next run. Migration script (`m
|
|
|
77
77
|
|
|
78
78
|
## Dispatch
|
|
79
79
|
|
|
80
|
-
1. Resolve wiki mode from `figmaConfig.wiki.mode` - one of `submodule`, `in-repo`, `github-wiki`, `separate-repo`. Each has a dedicated adapter inside the `figma-component-wiki` skill; see the `ai-ios-
|
|
80
|
+
1. Resolve wiki mode from `figmaConfig.wiki.mode` - one of `submodule`, `in-repo`, `github-wiki`, `separate-repo`. Each has a dedicated adapter inside the `figma-component-wiki` skill; see the `ai-ios-toolkit:figma-component-wiki` plugin skill for per-mode path layout and push semantics.
|
|
81
81
|
2. Emit progress line: `→ writing wiki {componentName} (mode: {mode})`.
|
|
82
|
-
3. Dispatch to the plugin skill `ai-ios-
|
|
82
|
+
3. Dispatch to the plugin skill `ai-ios-toolkit:figma-component-wiki` (iOS) or `ai-android-toolkit:figma-component-wiki` (Android), passing `{componentName, componentPath, figmaConfig}`.
|
|
83
83
|
4. Skill returns `{ writtenPaths[], committedSha?, pushedRemote? }`. Write `writtenPaths` to Phase 7 summary's "Files written" section and push metadata (if any) to "External publishes".
|
|
84
84
|
5. On adapter failure - log the adapter + mode + error, continue Phase 7. Wiki is a non-blocking augmentation; the Jira comment in Step 3 already carries the component summary, so the developer is never left in the dark if wiki misfires.
|
|
85
85
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion": "2.
|
|
2
|
+
"schemaVersion": "2.6.0",
|
|
3
3
|
"global": {
|
|
4
4
|
"identities": [],
|
|
5
5
|
"keychainMapping": {
|
|
@@ -46,7 +46,12 @@
|
|
|
46
46
|
"autoDiff": false,
|
|
47
47
|
"manualNote": false
|
|
48
48
|
},
|
|
49
|
-
"wikiScope": [
|
|
49
|
+
"wikiScope": [
|
|
50
|
+
"main",
|
|
51
|
+
"ios",
|
|
52
|
+
"screenshots",
|
|
53
|
+
"index"
|
|
54
|
+
],
|
|
50
55
|
"autopilotReportTimeoutSeconds": 1800,
|
|
51
56
|
"promptLanguage": "en",
|
|
52
57
|
"outputLanguage": "en",
|
|
@@ -78,7 +83,7 @@
|
|
|
78
83
|
"skillConformance": {
|
|
79
84
|
"blockOnCoverageGap": false
|
|
80
85
|
},
|
|
81
|
-
"
|
|
86
|
+
"resumeLocal": {
|
|
82
87
|
"autoFix": false
|
|
83
88
|
}
|
|
84
89
|
},
|
|
@@ -164,13 +169,16 @@
|
|
|
164
169
|
}
|
|
165
170
|
},
|
|
166
171
|
"_derivedSkillSourcesTemplate": {
|
|
167
|
-
"_comment": "Optional. Populate global.derivedSkillSources[] to let /multi-agent:refactor check whether skills you derived from an upstream marketplace plugin have been updated. Kept in your LOCAL prefs only (never synced), so it may reference private sources. Copy an entry like the one below. Set upstreamLocalClone when you have a working copy: the installed plugin cache is only as fresh as your last marketplace update, and a stale cache makes the drift check answer 'up to date' when it is four releases behind.",
|
|
172
|
+
"_comment": "Optional. Populate global.derivedSkillSources[] to let /multi-agent:refactor check whether skills you derived from an upstream marketplace plugin have been updated. Kept in your LOCAL prefs only (never synced), so it may reference private sources. Copy an entry like the one below. Set upstreamLocalClone when you have a working copy: the installed plugin cache is only as fresh as your last marketplace update, and a stale cache makes the drift check answer 'up to date' when it is four releases behind. Set driftAcknowledged to the current upstream version to accept a known drift without failing the gate; the gate re-fails when upstream moves past it.",
|
|
168
173
|
"_example": {
|
|
169
174
|
"label": "Component toolkit skills",
|
|
170
175
|
"localPath": "plugins/<my-plugin>/skills/workflow",
|
|
171
176
|
"upstreamMarketplace": "<installed-marketplace-name>",
|
|
172
177
|
"upstreamPlugin": "<upstream-plugin-name>",
|
|
173
|
-
"upstreamSkills": [
|
|
178
|
+
"upstreamSkills": [
|
|
179
|
+
"<skill-a>",
|
|
180
|
+
"<skill-b>"
|
|
181
|
+
],
|
|
174
182
|
"derivedFromVersion": "0.0.0",
|
|
175
183
|
"upstreamVersionSource": "marketplace.json",
|
|
176
184
|
"upstreamLocalClone": "$HOME/<upstream-repo-working-copy>",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Figma -> Component Generation
|
|
2
2
|
|
|
3
|
-
Skill set lives in the marketplace plugins - `ai-ios-
|
|
3
|
+
Skill set lives in the marketplace plugins - `ai-ios-toolkit` (iOS/SwiftUI) and `ai-android-toolkit` (Android/Compose). Activated when the task contains a Figma URL and target files are `.swift` (iOS) or `.kt` (Android).
|
|
4
4
|
|
|
5
5
|
### MUST: Figma access - 3-tier fallback chain (BLOCKING, pipeline-wide)
|
|
6
6
|
|
|
@@ -190,7 +190,7 @@ Phase 3.3: figma-iteration-commit → Batch iteration commit (if iterating)
|
|
|
190
190
|
| Wiki | enabled/disabled | `wiki.enabled` |
|
|
191
191
|
| Figma API | MCP / REST fallback | `figma.mcpEnabled` |
|
|
192
192
|
|
|
193
|
-
Provider interfaces are defined inline in the plugin skill sets - see the `ai-ios-
|
|
193
|
+
Provider interfaces are defined inline in the plugin skill sets - see the `ai-ios-toolkit` and `ai-android-toolkit` marketplace plugins.
|
|
194
194
|
|
|
195
195
|
### Optional Features (graceful skip when disabled)
|
|
196
196
|
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"skill": {
|
|
145
145
|
"type": "string",
|
|
146
146
|
"minLength": 1,
|
|
147
|
-
"description": "Skill name as invoked, e.g. ios-coding-standard, ai-ios-
|
|
147
|
+
"description": "Skill name as invoked, e.g. ios-coding-standard, ai-ios-toolkit:create-component, or a guide path for a stack guide."
|
|
148
148
|
},
|
|
149
149
|
"phase": {
|
|
150
150
|
"type": "integer",
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/{owner}/multi-agent-pipeline/pipeline/schemas/complaint-analysis-spec.schema.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"title": "Multi-Agent Pipeline - /multi-agent:complaint-analysis run state",
|
|
6
|
+
"description": "Contract for state.complaintSpec, the run state of the customer-complaint triage command. Complaints arrive redacted (parse-complaints.sh strips PII before anything lands here), each one carries its Graylog evidence status, repo evidence rows, and a triage verdict: client / bff (our responsibility, root-cause analysis) or core (routing recommendation only) or insufficient-evidence.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"required": ["runName", "language", "repos", "complaints"],
|
|
10
|
+
"properties": {
|
|
11
|
+
"runName": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"minLength": 1,
|
|
14
|
+
"description": "Run name supplied by the user or defaulted to complaints-<YYYYMMDD>."
|
|
15
|
+
},
|
|
16
|
+
"phase": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"enum": [
|
|
19
|
+
"intake",
|
|
20
|
+
"fetching_graylog",
|
|
21
|
+
"correlating_repos",
|
|
22
|
+
"triaging",
|
|
23
|
+
"drafting",
|
|
24
|
+
"awaiting_output_decision",
|
|
25
|
+
"dispatching",
|
|
26
|
+
"reporting",
|
|
27
|
+
"done"
|
|
28
|
+
],
|
|
29
|
+
"description": "Resume marker. Set after each phase boundary."
|
|
30
|
+
},
|
|
31
|
+
"language": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"enum": ["tr", "en"],
|
|
34
|
+
"description": "Report body language, resolved from prefs.global.outputLanguage."
|
|
35
|
+
},
|
|
36
|
+
"account": {
|
|
37
|
+
"type": ["string", "null"],
|
|
38
|
+
"description": "Account id resolved by the account picker; null for local-only flows."
|
|
39
|
+
},
|
|
40
|
+
"repos": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"minItems": 1,
|
|
43
|
+
"items": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"additionalProperties": false,
|
|
46
|
+
"required": ["name", "layer"],
|
|
47
|
+
"properties": {
|
|
48
|
+
"name": { "type": "string", "minLength": 1 },
|
|
49
|
+
"layer": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"enum": ["ios", "android", "web", "mobile-bff", "web-bff", "other"],
|
|
52
|
+
"description": "User-confirmed layer tag (Phase 0 Step 3b). core is NOT a layer here - it is the residual verdict, not a repo."
|
|
53
|
+
},
|
|
54
|
+
"localPath": { "type": ["string", "null"] },
|
|
55
|
+
"provider": { "type": ["string", "null"] }
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"description": "Repos selected in the multi-select picker, each tagged with the layer it implements."
|
|
59
|
+
},
|
|
60
|
+
"input": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"additionalProperties": false,
|
|
63
|
+
"required": ["sources", "complaintCount", "redacted"],
|
|
64
|
+
"properties": {
|
|
65
|
+
"sources": {
|
|
66
|
+
"type": "array",
|
|
67
|
+
"minItems": 1,
|
|
68
|
+
"items": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"additionalProperties": false,
|
|
71
|
+
"required": ["type"],
|
|
72
|
+
"properties": {
|
|
73
|
+
"type": { "type": "string", "enum": ["file", "paste", "jira", "confluence"] },
|
|
74
|
+
"ref": {
|
|
75
|
+
"type": ["string", "null"],
|
|
76
|
+
"description": "File path, Jira issue key, or Confluence URL. null for paste."
|
|
77
|
+
},
|
|
78
|
+
"format": {
|
|
79
|
+
"type": ["string", "null"],
|
|
80
|
+
"enum": ["csv", "xlsx", "txt", "json", "text", null]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"complaintCount": { "type": "integer", "minimum": 0 },
|
|
86
|
+
"redacted": {
|
|
87
|
+
"type": "boolean",
|
|
88
|
+
"description": "Must be true for any run that dispatches output; only --no-redact debug runs of parse-complaints.sh produce false."
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"complaints": {
|
|
93
|
+
"type": "array",
|
|
94
|
+
"items": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
"required": ["id", "textRedacted"],
|
|
98
|
+
"properties": {
|
|
99
|
+
"id": { "type": "string", "pattern": "^C-[0-9]{2,}$" },
|
|
100
|
+
"textRedacted": { "type": "string", "minLength": 1 },
|
|
101
|
+
"trxId": { "type": ["string", "null"] },
|
|
102
|
+
"convId": { "type": ["string", "null"] },
|
|
103
|
+
"date": { "type": ["string", "null"] },
|
|
104
|
+
"platformHint": { "type": ["string", "null"] },
|
|
105
|
+
"skipGraylog": {
|
|
106
|
+
"type": "boolean",
|
|
107
|
+
"default": false,
|
|
108
|
+
"description": "True when the user explicitly marked the complaint skip-graylog at the Phase 0 Step 5 id-confirmation loop."
|
|
109
|
+
},
|
|
110
|
+
"graylog": {
|
|
111
|
+
"type": "object",
|
|
112
|
+
"additionalProperties": false,
|
|
113
|
+
"required": ["status"],
|
|
114
|
+
"properties": {
|
|
115
|
+
"status": { "type": "string", "enum": ["pending", "ok", "degraded", "skipped"] },
|
|
116
|
+
"totalResults": { "type": "integer", "minimum": 0 },
|
|
117
|
+
"degradeReason": { "type": ["string", "null"] }
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"repoEvidence": {
|
|
121
|
+
"type": "array",
|
|
122
|
+
"items": {
|
|
123
|
+
"type": "object",
|
|
124
|
+
"additionalProperties": false,
|
|
125
|
+
"required": ["repo", "layer", "file", "signal", "matchKind"],
|
|
126
|
+
"properties": {
|
|
127
|
+
"repo": { "type": "string" },
|
|
128
|
+
"layer": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"enum": ["ios", "android", "web", "mobile-bff", "web-bff", "other"]
|
|
131
|
+
},
|
|
132
|
+
"file": { "type": "string" },
|
|
133
|
+
"line": { "type": ["integer", "null"] },
|
|
134
|
+
"signal": {
|
|
135
|
+
"type": "string",
|
|
136
|
+
"description": "The Graylog-derived signal that matched: endpoint path, error code, exception name, message template, or source service name."
|
|
137
|
+
},
|
|
138
|
+
"matchKind": { "type": "string", "enum": ["direct", "partial"] }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"verdict": {
|
|
143
|
+
"type": "object",
|
|
144
|
+
"additionalProperties": false,
|
|
145
|
+
"required": ["category", "confidence", "rationale"],
|
|
146
|
+
"properties": {
|
|
147
|
+
"category": {
|
|
148
|
+
"type": "string",
|
|
149
|
+
"enum": ["client", "bff", "core", "insufficient-evidence"]
|
|
150
|
+
},
|
|
151
|
+
"layer": {
|
|
152
|
+
"type": ["string", "null"],
|
|
153
|
+
"enum": ["ios", "android", "web", "mobile-bff", "web-bff", null],
|
|
154
|
+
"description": "Set for client/bff verdicts; null for core and insufficient-evidence."
|
|
155
|
+
},
|
|
156
|
+
"confidence": { "type": "string", "enum": ["high", "medium", "low"] },
|
|
157
|
+
"rationale": { "type": "string", "minLength": 1 }
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"handoff": {
|
|
161
|
+
"type": ["object", "null"],
|
|
162
|
+
"additionalProperties": false,
|
|
163
|
+
"description": "Present only for client/bff verdicts: development handoff grounded in the existing architecture (repoEvidence files as reference).",
|
|
164
|
+
"properties": {
|
|
165
|
+
"fixPlan": {
|
|
166
|
+
"type": "array",
|
|
167
|
+
"items": { "type": "string" },
|
|
168
|
+
"description": "2-5 numbered steps, each referencing a cited file:line or component, reuse-first."
|
|
169
|
+
},
|
|
170
|
+
"devPrompt": {
|
|
171
|
+
"type": ["string", "null"],
|
|
172
|
+
"description": "English prompt block ready for /multi-agent:dev or a Jira description; includes the [C-NN] id."
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"routing": {
|
|
177
|
+
"type": ["object", "null"],
|
|
178
|
+
"additionalProperties": false,
|
|
179
|
+
"description": "Present only for core verdicts: the routing recommendation to the backend core team. Never contains fix analysis.",
|
|
180
|
+
"properties": {
|
|
181
|
+
"suspectedService": {
|
|
182
|
+
"type": ["string", "null"],
|
|
183
|
+
"description": "Graylog message source field of the failing upstream service."
|
|
184
|
+
},
|
|
185
|
+
"endpoint": { "type": ["string", "null"] },
|
|
186
|
+
"errorCode": { "type": ["string", "null"] },
|
|
187
|
+
"evidenceExcerpt": {
|
|
188
|
+
"type": ["string", "null"],
|
|
189
|
+
"description": "Short redacted English excerpt from the Graylog message."
|
|
190
|
+
},
|
|
191
|
+
"suggestedQueue": {
|
|
192
|
+
"type": ["string", "null"],
|
|
193
|
+
"description": "Optional team/queue label from prefs.projects[*].routing.coreTeamLabel; null when unset."
|
|
194
|
+
},
|
|
195
|
+
"confidence": { "type": ["string", "null"], "enum": ["high", "medium", "low", null] }
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"outputs": {
|
|
202
|
+
"type": "object",
|
|
203
|
+
"additionalProperties": false,
|
|
204
|
+
"properties": {
|
|
205
|
+
"draftDir": { "type": ["string", "null"] },
|
|
206
|
+
"files": { "type": "array", "items": { "type": "string" } },
|
|
207
|
+
"destinations": {
|
|
208
|
+
"type": "array",
|
|
209
|
+
"items": { "type": "string", "enum": ["local", "confluence", "jira"] }
|
|
210
|
+
},
|
|
211
|
+
"confluencePageUrl": { "type": ["string", "null"] },
|
|
212
|
+
"jiraIssueKey": { "type": ["string", "null"] }
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* prefs-2.5.0-to-2.6.0.mjs - preference schema upgrade 2.5.0 -> 2.6.0
|
|
3
|
+
*
|
|
4
|
+
* v15.0.0 renamed the pipeline-tail command a second time: /multi-agent:finish
|
|
5
|
+
* (pre-2.5.0) became :ship (2.5.0) and is now :resume-local, because the command
|
|
6
|
+
* continues locally-done work through review/commit/report - it opens the PR but
|
|
7
|
+
* merges nothing, so "ship" oversold it. One preference key follows:
|
|
8
|
+
*
|
|
9
|
+
* - global.resumeLocal.autoFix (default FALSE)
|
|
10
|
+
* Carried across from global.ship.autoFix (itself carried from
|
|
11
|
+
* global.finish.autoFix): a user who opted into auto-fix did so
|
|
12
|
+
* deliberately, so the value survives every hop of the rename chain.
|
|
13
|
+
*
|
|
14
|
+
* Idempotent: safe on already-2.6.0 input. Non-destructive: an existing explicit
|
|
15
|
+
* value is preserved; the legacy `ship`/`finish` blocks are removed because they
|
|
16
|
+
* are no longer declared properties and would fail a closed `global`.
|
|
17
|
+
*
|
|
18
|
+
* @param {object} data - parsed JSON content of the preferences file
|
|
19
|
+
* @returns {object} - same data with schemaVersion = "2.6.0"
|
|
20
|
+
*/
|
|
21
|
+
export default function migrate(data) {
|
|
22
|
+
const out = JSON.parse(JSON.stringify(data));
|
|
23
|
+
|
|
24
|
+
out.schemaVersion = "2.6.0";
|
|
25
|
+
|
|
26
|
+
if (!out.global) out.global = {};
|
|
27
|
+
|
|
28
|
+
if (typeof out.global.resumeLocal !== "object" || out.global.resumeLocal === null) {
|
|
29
|
+
out.global.resumeLocal = {};
|
|
30
|
+
}
|
|
31
|
+
if (typeof out.global.resumeLocal.autoFix !== "boolean") {
|
|
32
|
+
const legacy =
|
|
33
|
+
typeof out.global.ship?.autoFix === "boolean"
|
|
34
|
+
? out.global.ship.autoFix
|
|
35
|
+
: out.global.finish?.autoFix;
|
|
36
|
+
out.global.resumeLocal.autoFix = typeof legacy === "boolean" ? legacy : false;
|
|
37
|
+
}
|
|
38
|
+
for (const key of ["ship", "finish"]) {
|
|
39
|
+
if (out.global[key] && typeof out.global[key] === "object") {
|
|
40
|
+
delete out.global[key].autoFix;
|
|
41
|
+
if (Object.keys(out.global[key]).length === 0) delete out.global[key];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return out;
|
|
46
|
+
}
|