@mmerterden/multi-agent-pipeline 14.2.2 → 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 +76 -6
- package/README.md +15 -8
- package/README.tr.md +15 -8
- 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 +7 -7
- package/docs/ecosystem.md +28 -28
- 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 +19 -8
- package/install/claude.mjs +144 -59
- package/install/codex.mjs +28 -3
- 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 +3 -3
- package/package.json +1 -2
- package/pipeline/commands/multi-agent/SKILL.md +2 -0
- package/pipeline/commands/multi-agent/analysis/SKILL.md +3 -3
- package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/build-optimize/SKILL.md +9 -9
- package/pipeline/commands/multi-agent/channels/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +186 -0
- package/pipeline/commands/multi-agent/dev/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-local/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +1 -1
- 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 +1 -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 +8 -8
- 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/issue-fetcher.sh +1 -1
- package/pipeline/lib/parse-complaints.sh +306 -0
- package/pipeline/multi-agent-refs/channels/wiki.md +3 -3
- 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/generate-issue.md +1 -1
- package/pipeline/multi-agent-refs/phases/modes.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +1 -1
- 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/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 +276 -66
- package/pipeline/schemas/token-budget.json +2 -2
- package/pipeline/scripts/_stack-routing.mjs +79 -0
- package/pipeline/scripts/audit-log-rotate.sh +4 -1
- package/pipeline/scripts/build-skills-index.mjs +11 -0
- package/pipeline/scripts/build-stack-plugins.mjs +28 -60
- package/pipeline/scripts/check-derived-drift.mjs +52 -28
- package/pipeline/scripts/gc-worktrees.sh +4 -1
- package/pipeline/scripts/gen-skills-index.mjs +1 -1
- package/pipeline/scripts/match-skills.mjs +8 -2
- package/pipeline/scripts/migrate-prefs.mjs +28 -20
- package/pipeline/scripts/phase-tracker.sh +13 -5
- package/pipeline/scripts/phase0-exit-gate.mjs +3 -2
- package/pipeline/scripts/run-aggregator.mjs +7 -2
- 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/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/uninstall.mjs +158 -11
- package/pipeline/scripts/validate-complaint-doc.mjs +229 -0
- package/pipeline/scripts/validate-reviewer.mjs +9 -3
- package/pipeline/skills/.skill-manifest.json +156 -108
- package/pipeline/skills/.skills-index.json +449 -12
- package/pipeline/skills/shared/README.md +14 -10
- package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +1 -1
- 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-dev/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +2 -2
- 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 +6 -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/example-mapping.json +53 -10
- package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +4 -3
- package/pipeline/skills/skills-index.md +7 -4
|
@@ -114,13 +114,13 @@ Detect the project's tech stack to load appropriate skills and tooling throughou
|
|
|
114
114
|
|
|
115
115
|
| Stack | Marker Files | Skills |
|
|
116
116
|
| -------------- | ----------------------------------------------- | ------------------------------------------------------------ |
|
|
117
|
-
| iOS/Swift | `.xcodeproj`, `Package.swift` |
|
|
118
|
-
| Android/Kotlin | `build.gradle`, `build.gradle.kts` | `android-jetpack-compose-expert`, `kotlin-coroutines-expert` |
|
|
119
|
-
| Python | `requirements.txt`, `pyproject.toml`, `Pipfile` | `fastapi-pro`, `api-patterns`
|
|
120
|
-
| Node.js | `package.json` | `nodejs-backend-patterns`, `api-patterns`
|
|
121
|
-
| Go | `go.mod` | `api-patterns`, `clean-code`
|
|
122
|
-
| Docker | `Dockerfile`, `docker-compose.yml` | `docker-expert`
|
|
123
|
-
| Monorepo | Multiple of above | `monorepo-architect`
|
|
117
|
+
| iOS/Swift | `.xcodeproj`, `Package.swift` | `ai-ios-toolkit:*` skills, `ai-ios-toolkit:swift-testing` |
|
|
118
|
+
| Android/Kotlin | `build.gradle`, `build.gradle.kts` | `ai-android-toolkit:android-jetpack-compose-expert`, `ai-android-toolkit:kotlin-coroutines-expert` |
|
|
119
|
+
| Python | `requirements.txt`, `pyproject.toml`, `Pipfile` | `ai-backend-toolkit:fastapi-pro`, `ai-backend-toolkit:api-patterns` |
|
|
120
|
+
| Node.js | `package.json` | `ai-backend-toolkit:nodejs-backend-patterns`, `ai-backend-toolkit:api-patterns` |
|
|
121
|
+
| Go | `go.mod` | `ai-backend-toolkit:api-patterns`, `ai-backend-toolkit:clean-code` |
|
|
122
|
+
| Docker | `Dockerfile`, `docker-compose.yml` | `ai-backend-toolkit:docker-expert` |
|
|
123
|
+
| Monorepo | Multiple of above | `ai-backend-toolkit:monorepo-architect` |
|
|
124
124
|
|
|
125
125
|
Store in `agent-state.json` → `"detectedStack": ["ios", "python", "docker"]`
|
|
126
126
|
|
|
@@ -97,11 +97,11 @@ Store approach in task metadata for Phase 3 agent.
|
|
|
97
97
|
|
|
98
98
|
Based on Phase 1 `detectedStack`, assign relevant skills:
|
|
99
99
|
|
|
100
|
-
- iOS tasks -> SwiftUI skills, iOS patterns
|
|
101
|
-
- Python tasks -> `fastapi-pro`, `api-patterns`
|
|
102
|
-
- Node tasks -> `nodejs-backend-patterns`
|
|
103
|
-
- Security-sensitive -> `api-security-best-practices`
|
|
104
|
-
- Multi-submodule -> `monorepo-architect`
|
|
100
|
+
- iOS tasks -> `ai-ios-toolkit:*` SwiftUI skills, iOS patterns
|
|
101
|
+
- Python tasks -> `ai-backend-toolkit:fastapi-pro`, `ai-backend-toolkit:api-patterns`
|
|
102
|
+
- Node tasks -> `ai-backend-toolkit:nodejs-backend-patterns`
|
|
103
|
+
- Security-sensitive -> `ai-backend-toolkit:api-security-best-practices`
|
|
104
|
+
- Multi-submodule -> `ai-backend-toolkit:monorepo-architect`
|
|
105
105
|
|
|
106
106
|
#### Output contract
|
|
107
107
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
### Phase 3: Dev (Sonnet)
|
|
2
2
|
|
|
3
|
-
> **TLDR** - Sonnet executes the plan task-by-task with TDD (red→green→refactor). Required: issue-tracker status moved to "In Progress" before any code, with a post-mutation verify step (re-reads the field, retries once on silent VALIDATION failures). Build verification after each task (up to 3 retries). Build-queue lock serializes concurrent xcodebuild. `--dev` mode uses Opus self-contained (no Phase 2 plan required). `taskType === component` **short-circuits the TDD path** and delegates the whole phase to the enabled `ai-<platform>-
|
|
3
|
+
> **TLDR** - Sonnet executes the plan task-by-task with TDD (red→green→refactor). Required: issue-tracker status moved to "In Progress" before any code, with a post-mutation verify step (re-reads the field, retries once on silent VALIDATION failures). Build verification after each task (up to 3 retries). Build-queue lock serializes concurrent xcodebuild. `--dev` mode uses Opus self-contained (no Phase 2 plan required). `taskType === component` **short-circuits the TDD path** and delegates the whole phase to the enabled `ai-<platform>-toolkit` marketplace plugin's component skill (`create-component`, fallback `create-ui-component`) - see next subsection.
|
|
4
4
|
|
|
5
5
|
## Phase 3 Pre-flight (BLOCKING, v9.0.0)
|
|
6
6
|
|
|
@@ -38,7 +38,7 @@ Pre-flight steps (run in order, abort on failure).
|
|
|
38
38
|
|
|
39
39
|
`targetFiles` is required - without it a skill applied to the wrong files still reads as "applied". Append at the moment of consultation, not at the end of the phase. Phase 4 Step 1.78 treats this as self-report only and resolves criteria independently; it is the one signal separating "applied to the wrong files" from "never opened".
|
|
40
40
|
|
|
41
|
-
9. **Stack skill routing (every `taskType`, when a stack toolkit plugin is enabled)**: ask the enabled `ai-<platform>-
|
|
41
|
+
9. **Stack skill routing (every `taskType`, when a stack toolkit plugin is enabled)**: ask the enabled `ai-<platform>-toolkit`'s own `index` skill which skills govern this task, load them BEFORE writing code, and record each into `state.telemetry.skillCalls[]` with `routedBy: "<toolkit>:index@<version>"`. The routing table stays in the plugin - a copy here would be the stale one. No toolkit, or none enabled, is a recorded no-op, not a halt. Contract: [`features/stack-skill-routing.md`]($HOME/.claude/multi-agent-refs/features/stack-skill-routing.md).
|
|
42
42
|
|
|
43
43
|
The analysis document is the SOLE design source in Phase 3. Variant choices, padding values, color tokens, copy strings, accessibility identifiers, and test method names all come from the rendered Pass B cells. If something is missing in the analysis doc, the fix is to re-run `/multi-agent:analysis`, not to fetch from Figma.
|
|
44
44
|
|
|
@@ -56,7 +56,7 @@ Phase 3 consumes the Phase 2 output object conforming to `$HOME/.claude/schemas/
|
|
|
56
56
|
|
|
57
57
|
#### Component tasks - delegated dispatch (taskType === "component")
|
|
58
58
|
|
|
59
|
-
When Phase 0 Step 7 classified the task as `component`, Phase 3 delegates the entire phase to the enabled `ai-<platform>-
|
|
59
|
+
When Phase 0 Step 7 classified the task as `component`, Phase 3 delegates the entire phase to the enabled `ai-<platform>-toolkit` marketplace plugin's component skill (`create-component`, fallback `create-ui-component`) via the Skill tool and does NOT run the TDD loop below. The dispatch layer passes the plugin skill the analysis Section 6 (Bileşen Envanteri) entry + Section 13.1 conventions for the named component as context. Because plugin skills do not write pipeline state, the **dispatch layer** (not the skill) owns `state.phases["3"].subphases[]`, recording a coarse component-build row - multi-agent's `phase-tracker` reads that array with no special case. Plugin resolution (dual-name), dispatch call, failure/resume, multi-repo, `--dev` elisions, and the intentional cross-CLI divergence live in `$HOME/.claude/multi-agent-refs/component-dispatch.md` - read it before editing component-task behaviour here. Phase 3 still owns: progress line `-> dispatching create-component <name>`, `retryCount` cap at 3, and fallthrough to the TDD path when dispatch prerequisites are missing (`taskType` absent OR the plugin is not enabled in this repo -> log anomaly, halt or run TDD per component-dispatch.md).
|
|
60
60
|
|
|
61
61
|
For non-component taskTypes (`bugfix`, `feature`, `refactor`, `chore`), continue with the standard TDD section below.
|
|
62
62
|
|
|
@@ -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
|
|
@@ -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
|
+
}
|