@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
package/install/claude.mjs
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* @module install/claude
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { existsSync, readFileSync, readdirSync,
|
|
17
|
+
import { existsSync, readFileSync, readdirSync, renameSync, rmSync } from "fs";
|
|
18
18
|
import { join, dirname } from "path";
|
|
19
19
|
import { execSync } from "child_process";
|
|
20
20
|
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
wipeDir,
|
|
36
36
|
writeFile,
|
|
37
37
|
} from "./_common.mjs";
|
|
38
|
-
import {
|
|
38
|
+
import { EXTERNAL_SKILLS_MANIFEST } from "./_platform-filter.mjs";
|
|
39
39
|
import { DEV_ONLY_SCRIPTS, countDevOnlyFiles } from "./_dev-only-files.mjs";
|
|
40
40
|
import { registerMcpServer } from "./_mcp-register.mjs";
|
|
41
41
|
|
|
@@ -46,6 +46,16 @@ import { registerMcpServer } from "./_mcp-register.mjs";
|
|
|
46
46
|
*/
|
|
47
47
|
export const LEGACY_PRE_COMMIT_MATCHER = "Bash(git commit:*)";
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* The only skills installed locally on Claude Code. Everything else reaches
|
|
51
|
+
* Claude Code through the marketplace plugins (`ai-<stack>-toolkit`), namespaced
|
|
52
|
+
* by the plugin loader. These two stay local by policy: they are pipeline-owned
|
|
53
|
+
* compliance catalogs that may carry audit rules not meant for the public
|
|
54
|
+
* marketplace, and `scripts/uninstall.mjs` (PIPELINE_CORE_SKILL_DIRS) already
|
|
55
|
+
* treats exactly this pair as pipeline-owned.
|
|
56
|
+
*/
|
|
57
|
+
export const PIPELINE_LOCAL_SKILLS = ["apple-archive-compliance", "google-play-compliance"];
|
|
58
|
+
|
|
49
59
|
/**
|
|
50
60
|
* @param {{
|
|
51
61
|
* home: string,
|
|
@@ -128,13 +138,16 @@ function installCommands(pipelineSrc, dest, useSymlinks) {
|
|
|
128
138
|
//
|
|
129
139
|
// Preserve local-only alias wrappers (frontmatter `local-only: true`) across
|
|
130
140
|
// the wipe. They live ONLY under ~/.claude (never in pipeline/commands, and
|
|
131
|
-
// never synced), so without this
|
|
132
|
-
// every install/update.
|
|
133
|
-
|
|
141
|
+
// never synced), so without this stash+restore they would be destroyed on
|
|
142
|
+
// every install/update. The stash is an on-disk rename, not an in-memory
|
|
143
|
+
// snapshot: the only copy of user-authored content stays on disk at every
|
|
144
|
+
// instant, so an install interrupted between wipe and restore loses nothing,
|
|
145
|
+
// and the next run adopts any leftover stash.
|
|
146
|
+
const wrapperStash = stashLocalOnlyWrappers(ownedCmdDir);
|
|
134
147
|
wipeDir(ownedCmdDir);
|
|
135
148
|
|
|
136
149
|
copyDir(commandsSrc, dest, { useSymlinks });
|
|
137
|
-
const restored =
|
|
150
|
+
const restored = unstashLocalOnlyWrappers(ownedCmdDir, wrapperStash);
|
|
138
151
|
console.log(` -> ${countFiles(commandsSrc)} files copied to ${dest}`);
|
|
139
152
|
if (restored > 0) {
|
|
140
153
|
console.log(` -> preserved ${restored} local-only alias wrapper(s)`);
|
|
@@ -163,36 +176,51 @@ function localizeCommandDescriptions(pipelineSrc, ownedCmdDir) {
|
|
|
163
176
|
}
|
|
164
177
|
}
|
|
165
178
|
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
function
|
|
170
|
-
const
|
|
171
|
-
if (!existsSync(ownedCmdDir)) return
|
|
179
|
+
// Move command dirs whose SKILL.md declares `local-only: true` into an on-disk
|
|
180
|
+
// stash beside the namespace, so installCommands can restore them after the
|
|
181
|
+
// namespace wipe. Returns the stash path.
|
|
182
|
+
function stashLocalOnlyWrappers(ownedCmdDir) {
|
|
183
|
+
const stashDir = join(dirname(ownedCmdDir), ".multi-agent-wrapper-stash");
|
|
184
|
+
if (isDryRun() || !existsSync(ownedCmdDir)) return stashDir;
|
|
172
185
|
for (const name of readdirSync(ownedCmdDir)) {
|
|
173
186
|
const dir = join(ownedCmdDir, name);
|
|
174
187
|
const skill = join(dir, "SKILL.md");
|
|
175
188
|
if (!existsSync(skill)) continue;
|
|
176
189
|
if (!/^local-only:\s*true\s*$/m.test(readFileSync(skill, "utf-8"))) continue;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
190
|
+
ensureDir(stashDir);
|
|
191
|
+
const target = join(stashDir, name);
|
|
192
|
+
if (existsSync(target)) rmSync(target, { recursive: true, force: true });
|
|
193
|
+
renameSync(dir, target);
|
|
181
194
|
}
|
|
182
|
-
return
|
|
195
|
+
return stashDir;
|
|
183
196
|
}
|
|
184
197
|
|
|
185
|
-
// Restore
|
|
186
|
-
//
|
|
187
|
-
|
|
198
|
+
// Restore stashed local-only wrappers (including any leftover from an earlier
|
|
199
|
+
// interrupted run), but never clobber a real command the pipeline just
|
|
200
|
+
// installed under the same name. Returns the count restored.
|
|
201
|
+
function unstashLocalOnlyWrappers(ownedCmdDir, stashDir) {
|
|
202
|
+
if (isDryRun() || !existsSync(stashDir)) return 0;
|
|
188
203
|
let n = 0;
|
|
189
|
-
for (const
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
204
|
+
for (const name of readdirSync(stashDir)) {
|
|
205
|
+
const from = join(stashDir, name);
|
|
206
|
+
const to = join(ownedCmdDir, name);
|
|
207
|
+
if (existsSync(to)) {
|
|
208
|
+
// The pipeline now ships a real command under a name the user's wrapper
|
|
209
|
+
// was using, so the wrapper cannot be restored. Say whose content is
|
|
210
|
+
// being dropped: /multi-agent:save writes exactly these, and a release
|
|
211
|
+
// claiming a new name would otherwise delete a saved routine in silence.
|
|
212
|
+
console.log(
|
|
213
|
+
` -> WARNING: dropped local-only wrapper '${name}' - this release ships a command ` +
|
|
214
|
+
`with that name. Re-save it under a different name if you still need it.`,
|
|
215
|
+
);
|
|
216
|
+
rmSync(from, { recursive: true, force: true });
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
ensureDir(ownedCmdDir);
|
|
220
|
+
renameSync(from, to);
|
|
194
221
|
n++;
|
|
195
222
|
}
|
|
223
|
+
rmSync(stashDir, { recursive: true, force: true });
|
|
196
224
|
return n;
|
|
197
225
|
}
|
|
198
226
|
|
|
@@ -327,7 +355,7 @@ function runPreDeployScans(pipelineSrc) {
|
|
|
327
355
|
}
|
|
328
356
|
|
|
329
357
|
function installSkills(opts) {
|
|
330
|
-
const { pipelineSrc, dest, indexOnly, useSymlinks
|
|
358
|
+
const { pipelineSrc, dest, indexOnly, useSymlinks } = opts;
|
|
331
359
|
console.log(" [Claude Code] Installing skills...");
|
|
332
360
|
|
|
333
361
|
// Same symlink guard as the other owned trees: never prune or copy through
|
|
@@ -343,40 +371,49 @@ function installSkills(opts) {
|
|
|
343
371
|
}
|
|
344
372
|
|
|
345
373
|
const sharedCoreSrc = join(pipelineSrc, "skills", "shared", "core");
|
|
346
|
-
const sharedExternalSrc = join(pipelineSrc, "skills", "shared", "external");
|
|
347
374
|
|
|
348
375
|
let claudeSkillCount = 0;
|
|
349
376
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
377
|
+
// Claude Code no longer receives a local copy of the stack skills. The
|
|
378
|
+
// marketplace plugins (`ai-<stack>-toolkit`) are its only stack-skill source -
|
|
379
|
+
// a local copy duplicated ~110 skills against the enabled plugins (~10k
|
|
380
|
+
// tokens/session) and shadowed the plugin the moment it went stale. Only the
|
|
381
|
+
// two pipeline-owned compliance catalogs stay local (PIPELINE_LOCAL_SKILLS);
|
|
382
|
+
// they are deliberately not published to the marketplace.
|
|
383
|
+
ensureDir(dest);
|
|
384
|
+
for (const name of PIPELINE_LOCAL_SKILLS) {
|
|
385
|
+
const from = join(sharedCoreSrc, name);
|
|
386
|
+
if (!existsSync(from)) continue;
|
|
387
|
+
if (!useSymlinks) wipeDir(join(dest, name));
|
|
388
|
+
copyDir(from, join(dest, name), { useSymlinks });
|
|
389
|
+
claudeSkillCount += countFiles(from);
|
|
353
390
|
}
|
|
354
391
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
392
|
+
// Single-standard enforcement: Claude Code invokes pipeline commands via
|
|
393
|
+
// the `/multi-agent:*` slash-command namespace, so prune duplicate skill
|
|
394
|
+
// dirs left by older installs that copied shared/core wholesale. This used
|
|
395
|
+
// to live inside the external-copy branch; it must run unconditionally or
|
|
396
|
+
// the 51 multi-agent-* dirs return on the first install after a migration.
|
|
397
|
+
const pruned = pruneLegacyMultiAgentSkills(dest);
|
|
398
|
+
if (pruned > 0) {
|
|
399
|
+
console.log(
|
|
400
|
+
` -> pruned ${pruned} legacy multi-agent-* skill dirs (slash commands cover these)`,
|
|
401
|
+
);
|
|
402
|
+
}
|
|
366
403
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
)
|
|
376
|
-
|
|
404
|
+
// Migration prune: an older install delivered the full external catalog here.
|
|
405
|
+
// Its manifest names exactly what was delivered, so removal is manifest-scoped -
|
|
406
|
+
// user-authored skills in the same directory are untouched. Without a manifest
|
|
407
|
+
// nothing is guessed; the stale copy then outlives this install and the user
|
|
408
|
+
// can clean it via uninstall --claude.
|
|
409
|
+
const migrated = pruneManifestDeliveredSkills(dest);
|
|
410
|
+
if (migrated > 0) {
|
|
411
|
+
console.log(
|
|
412
|
+
` -> migration: removed ${migrated} stack skill dir(s) previously copied here (now plugin-only)`,
|
|
413
|
+
);
|
|
377
414
|
}
|
|
378
415
|
|
|
379
|
-
// Figma component skills moved to the ai-<platform>-
|
|
416
|
+
// Figma component skills moved to the ai-<platform>-toolkit marketplace
|
|
380
417
|
// plugin and are no longer bundled here. Prune any stale copies left by a
|
|
381
418
|
// pre-migration install so the installed tree stays consistent.
|
|
382
419
|
for (const sub of ["figma-ios", "figma-android", "figma-common", "figma-to-component"]) {
|
|
@@ -410,21 +447,69 @@ function installSkills(opts) {
|
|
|
410
447
|
console.log(` -> pruned ${orphans} stale flat skill file(s) from an older layout`);
|
|
411
448
|
}
|
|
412
449
|
|
|
413
|
-
console.log(` -> ${claudeSkillCount} skill files installed to ${dest}`);
|
|
450
|
+
console.log(` -> ${claudeSkillCount} skill files installed to ${dest} (stack skills: marketplace plugins)`);
|
|
414
451
|
|
|
415
|
-
//
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
452
|
+
// The shared skills README described the full local catalog; with the catalog
|
|
453
|
+
// gone it would document skills that are not here. Drop it, including copies
|
|
454
|
+
// an older install left behind.
|
|
455
|
+
const claudeReadme = join(dest, "README.md");
|
|
456
|
+
if (existsSync(claudeReadme) && !isDryRun()) {
|
|
419
457
|
try {
|
|
420
|
-
|
|
421
|
-
console.log(` ->
|
|
458
|
+
rmSync(claudeReadme);
|
|
459
|
+
console.log(` -> removed ${claudeReadme} (local catalog no longer installed)`);
|
|
422
460
|
} catch {
|
|
423
461
|
/* non-fatal */
|
|
424
462
|
}
|
|
425
463
|
}
|
|
426
464
|
}
|
|
427
465
|
|
|
466
|
+
/**
|
|
467
|
+
* Remove the external stack skills an older install copied into `dest`, scoped
|
|
468
|
+
* strictly to the delivery manifest that install wrote. NOTICE files rode along
|
|
469
|
+
* with the external catalog, so they go with it.
|
|
470
|
+
*
|
|
471
|
+
* @param {string} dest - the installed skills directory
|
|
472
|
+
* @returns {number} directories removed
|
|
473
|
+
*/
|
|
474
|
+
function pruneManifestDeliveredSkills(dest) {
|
|
475
|
+
const manifestPath = join(dest, EXTERNAL_SKILLS_MANIFEST);
|
|
476
|
+
if (!existsSync(manifestPath)) return 0;
|
|
477
|
+
if (isDryRun()) {
|
|
478
|
+
console.log(` [dry-run] would remove externally-delivered skills named in ${manifestPath}`);
|
|
479
|
+
return 0;
|
|
480
|
+
}
|
|
481
|
+
let removed = 0;
|
|
482
|
+
try {
|
|
483
|
+
const names = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
484
|
+
for (const name of Array.isArray(names) ? names : []) {
|
|
485
|
+
// The two local compliance catalogs are never external-delivered, but a
|
|
486
|
+
// corrupted manifest must not be able to take them out.
|
|
487
|
+
if (PIPELINE_LOCAL_SKILLS.includes(name)) continue;
|
|
488
|
+
const dir = join(dest, name);
|
|
489
|
+
if (!existsSync(dir)) continue;
|
|
490
|
+
try {
|
|
491
|
+
rmSync(dir, { recursive: true, force: true });
|
|
492
|
+
removed++;
|
|
493
|
+
} catch {
|
|
494
|
+
/* non-fatal */
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
for (const entry of readdirSync(dest)) {
|
|
498
|
+
if (entry.startsWith("NOTICE-") && entry.endsWith(".md")) {
|
|
499
|
+
try {
|
|
500
|
+
rmSync(join(dest, entry));
|
|
501
|
+
} catch {
|
|
502
|
+
/* non-fatal */
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
rmSync(manifestPath, { force: true });
|
|
507
|
+
} catch {
|
|
508
|
+
/* unreadable manifest: leave everything in place rather than guess */
|
|
509
|
+
}
|
|
510
|
+
return removed;
|
|
511
|
+
}
|
|
512
|
+
|
|
428
513
|
function ensureClaudeMd(home, pipelineSrc) {
|
|
429
514
|
console.log(" [Claude Code] Checking CLAUDE.md template...");
|
|
430
515
|
const CLAUDE_MD = join(home, ".claude", "CLAUDE.md");
|
package/install/codex.mjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* name + description into a single prompt block and silently drops entries once
|
|
11
11
|
* that block overflows - measured at install-design time, one 142-skill plugin
|
|
12
12
|
* surfaced only 75 of its skills AND evicted an unrelated user skill. So the
|
|
13
|
-
* pipeline contributes exactly one skill (`multi-agent`) and keeps its
|
|
13
|
+
* pipeline contributes exactly one skill (`multi-agent`) and keeps its
|
|
14
14
|
* sub-command specs as reference files that cost nothing until read. Converting
|
|
15
15
|
* them into peer skills would silently lose pipeline commands.
|
|
16
16
|
*
|
|
@@ -34,7 +34,15 @@ import {
|
|
|
34
34
|
import { DEV_ONLY_SCRIPTS, countDevOnlyFiles } from "./_dev-only-files.mjs";
|
|
35
35
|
import { registerMcpServer } from "./_mcp-register.mjs";
|
|
36
36
|
import { installCodexAgents } from "./_codex-agents.mjs";
|
|
37
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
installAuthoredPluginSkills,
|
|
39
|
+
pipelineOwnedSkillNames,
|
|
40
|
+
pluginsToDeliver,
|
|
41
|
+
} from "./_plugin-skills.mjs";
|
|
42
|
+
import {
|
|
43
|
+
partitionExternalSkillsByPlugins,
|
|
44
|
+
writeExternalSkillsManifest,
|
|
45
|
+
} from "./_platform-filter.mjs";
|
|
38
46
|
import { generateCodexInstructions } from "./_codex-instructions.mjs";
|
|
39
47
|
import { mergeManagedBlock } from "./_managed-block.mjs";
|
|
40
48
|
|
|
@@ -230,7 +238,12 @@ function installRouterSkill(pipelineSrc, skillsDir) {
|
|
|
230
238
|
const dest = join(skillsDir, "multi-agent");
|
|
231
239
|
ensureDir(dest);
|
|
232
240
|
writeFile(join(dest, "SKILL.md"), skill);
|
|
233
|
-
|
|
241
|
+
|
|
242
|
+
const commandsDir = join(pipelineSrc, "commands", "multi-agent");
|
|
243
|
+
const specCount = existsSync(commandsDir)
|
|
244
|
+
? readdirSync(commandsDir, { withFileTypes: true }).filter((e) => e.isDirectory()).length
|
|
245
|
+
: 0;
|
|
246
|
+
console.log(` -> 1 router skill written to ${dest} (${specCount} command specs stay as refs)`);
|
|
234
247
|
}
|
|
235
248
|
|
|
236
249
|
/**
|
|
@@ -264,7 +277,7 @@ function pruneLegacyCommandSkills(skillsDir) {
|
|
|
264
277
|
}
|
|
265
278
|
|
|
266
279
|
/**
|
|
267
|
-
* Install the reference tree: the shared `multi-agent-refs/` docs plus
|
|
280
|
+
* Install the reference tree: the shared `multi-agent-refs/` docs plus every
|
|
268
281
|
* sub-command specs, all path-rewritten. These are read on demand and never
|
|
269
282
|
* enter the skills block.
|
|
270
283
|
*/
|
|
@@ -279,10 +292,10 @@ function installRefs(pipelineSrc, dest) {
|
|
|
279
292
|
let count = 0;
|
|
280
293
|
if (existsSync(refsSrc)) count += copyTreeRewritten(refsSrc, dest);
|
|
281
294
|
|
|
282
|
-
// The
|
|
295
|
+
// The sub-command specs. Skip ONLY the top-level dispatcher SKILL.md -
|
|
283
296
|
// it already shipped as the router skill. The filter is on the path relative
|
|
284
297
|
// to the copy root, not the basename: every sub-command spec is itself named
|
|
285
|
-
// SKILL.md, so a basename filter would copy
|
|
298
|
+
// SKILL.md, so a basename filter would copy N empty directories and leave
|
|
286
299
|
// the orchestrator with nothing to read.
|
|
287
300
|
if (existsSync(commandsSrc)) {
|
|
288
301
|
count += copyTreeRewritten(commandsSrc, join(dest, "commands"), (rel) => rel !== "SKILL.md");
|
|
@@ -389,7 +402,24 @@ function installSkillRefs(pipelineSrc, dest, home, platformFlag) {
|
|
|
389
402
|
wipeDir(dest);
|
|
390
403
|
|
|
391
404
|
let count = 0;
|
|
392
|
-
if (existsSync(externalSrc))
|
|
405
|
+
if (existsSync(externalSrc)) {
|
|
406
|
+
// Active-stack filter (same contract as Copilot): Codex used to receive all
|
|
407
|
+
// 151 external skills regardless of stack - platformFlag only shaped the
|
|
408
|
+
// authored-plugin delivery below. The enabled-plugin set from
|
|
409
|
+
// ~/.claude/settings.json now bounds this copy too, so a Claude+Codex user
|
|
410
|
+
// sees one consistent stack surface across both hosts. The manifest makes
|
|
411
|
+
// the delivery inspectable; the wholesale wipeDir above already handles
|
|
412
|
+
// staleness on every install.
|
|
413
|
+
const { names: enabled, source: selectionSource } = pluginsToDeliver(home, platformFlag);
|
|
414
|
+
const { keep, skipped } = partitionExternalSkillsByPlugins(externalSrc, enabled);
|
|
415
|
+
for (const name of keep) {
|
|
416
|
+
count += copyTreeRewritten(join(externalSrc, name), join(dest, name));
|
|
417
|
+
}
|
|
418
|
+
writeExternalSkillsManifest(dest, keep);
|
|
419
|
+
console.log(
|
|
420
|
+
` -> stack filter (${selectionSource}): ${keep.length} kept, ${skipped.length} skipped`,
|
|
421
|
+
);
|
|
422
|
+
}
|
|
393
423
|
|
|
394
424
|
// `shared/core` also holds two skills that are NOT pipeline sub-commands:
|
|
395
425
|
// apple-archive-compliance and google-play-compliance. Copying only `external`
|
package/install/copilot.mjs
CHANGED
|
@@ -24,11 +24,18 @@ import {
|
|
|
24
24
|
wipeDir,
|
|
25
25
|
writeFile,
|
|
26
26
|
} from "./_common.mjs";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
partitionExternalSkillsByPlugins,
|
|
29
|
+
writeExternalSkillsManifest,
|
|
30
|
+
} from "./_platform-filter.mjs";
|
|
28
31
|
import { DEV_ONLY_SCRIPTS, countDevOnlyFiles } from "./_dev-only-files.mjs";
|
|
29
32
|
import { generateCopilotInstructions } from "./_copilot-instructions.mjs";
|
|
30
33
|
import { legacyTrailingContent, mergeManagedBlock } from "./_managed-block.mjs";
|
|
31
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
installAuthoredPluginSkills,
|
|
36
|
+
pipelineOwnedSkillNames,
|
|
37
|
+
pluginsToDeliver,
|
|
38
|
+
} from "./_plugin-skills.mjs";
|
|
32
39
|
import { registerMcpServer } from "./_mcp-register.mjs";
|
|
33
40
|
|
|
34
41
|
/**
|
|
@@ -357,16 +364,34 @@ function installSkills(opts) {
|
|
|
357
364
|
}
|
|
358
365
|
|
|
359
366
|
if (existsSync(sharedExternalSrc)) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
// Active-stack filter: Copilot has no plugin loader, so its local copy is the
|
|
368
|
+
// only stack-skill source it has - but it should still carry the SAME stack
|
|
369
|
+
// set the enabled plugins serve on Claude Code, not the whole catalog. The
|
|
370
|
+
// enabled set comes from ~/.claude/settings.json (pluginsToDeliver); the
|
|
371
|
+
// --platform flag stays as the fallback for machines without one.
|
|
372
|
+
const { names: enabled, source: selectionSource } = pluginsToDeliver(home, platformFlag);
|
|
373
|
+
const { keep, skipped } = partitionExternalSkillsByPlugins(sharedExternalSrc, enabled);
|
|
374
|
+
ensureDir(dest);
|
|
375
|
+
for (const name of keep) {
|
|
376
|
+
const src = join(sharedExternalSrc, name);
|
|
377
|
+
const dst = join(dest, name);
|
|
378
|
+
if (!useSymlinks) wipeDir(dst);
|
|
379
|
+
copyDir(src, dst, { useSymlinks });
|
|
380
|
+
copilotSkillCount += countFiles(src);
|
|
381
|
+
}
|
|
382
|
+
// Stale prune: a skill delivered by a previous, wider stack selection must
|
|
383
|
+
// leave when the selection narrows, or the old stack lingers forever.
|
|
384
|
+
for (const name of skipped) {
|
|
385
|
+
const stale = join(dest, name);
|
|
386
|
+
if (!existsSync(stale) || isDryRun()) continue;
|
|
387
|
+
try {
|
|
388
|
+
rmSync(stale, { recursive: true, force: true });
|
|
389
|
+
} catch {
|
|
390
|
+
/* non-fatal */
|
|
391
|
+
}
|
|
369
392
|
}
|
|
393
|
+
writeExternalSkillsManifest(dest, keep);
|
|
394
|
+
console.log(` -> stack filter (${selectionSource}): ${keep.length} kept, ${skipped.length} skipped`);
|
|
370
395
|
}
|
|
371
396
|
|
|
372
397
|
// The pre-migration figma-* skill copies are gone; the plugin owns component work
|
package/install/index.mjs
CHANGED
|
@@ -187,7 +187,9 @@ function printSummary(opts) {
|
|
|
187
187
|
// hand-registered entry became the only reason it worked on any given machine.
|
|
188
188
|
console.log(" For UI testing, the dev-toolkit MCP server is registered automatically:");
|
|
189
189
|
if (forClaude) {
|
|
190
|
-
console.log(
|
|
190
|
+
console.log(
|
|
191
|
+
" Claude Code: claude mcp add --scope user dev-toolkit (user scope, all projects)",
|
|
192
|
+
);
|
|
191
193
|
}
|
|
192
194
|
if (forCopilot) {
|
|
193
195
|
console.log(" Copilot CLI: copilot mcp add dev-toolkit");
|
|
@@ -195,7 +197,9 @@ function printSummary(opts) {
|
|
|
195
197
|
if (forCodex) {
|
|
196
198
|
console.log(" Codex CLI: codex mcp add dev-toolkit");
|
|
197
199
|
}
|
|
198
|
-
console.log(
|
|
200
|
+
console.log(
|
|
201
|
+
" Skipped only when the host CLI is not on PATH - the command to run is printed above.",
|
|
202
|
+
);
|
|
199
203
|
console.log("");
|
|
200
204
|
console.log(" Uninstall everything: npx @mmerterden/multi-agent-pipeline uninstall");
|
|
201
205
|
console.log(" (Personal access tokens in keychain are preserved.)");
|
|
@@ -62,7 +62,7 @@ failure this layout exists to prevent.
|
|
|
62
62
|
|
|
63
63
|
Codex assembles every discovered skill's name + description into one prompt block
|
|
64
64
|
and **silently drops entries when that block overflows**. The pipeline therefore
|
|
65
|
-
contributes exactly **one** skill (`multi-agent`) and keeps
|
|
65
|
+
contributes exactly **one** skill (`multi-agent`) and keeps every sub-command
|
|
66
66
|
specs as reference files that cost nothing until read. Do not convert those specs
|
|
67
67
|
into peer skills: doing so evicts other skills, including ones from installed
|
|
68
68
|
plugins, with no error surfaced.
|
|
@@ -33,17 +33,20 @@
|
|
|
33
33
|
- **Fast + Local (multi-agent-dev-local)**: Dev on current branch - no worktree
|
|
34
34
|
- **Fastest + Local (multi-agent-dev-local-autopilot)**: Dev + autopilot, no worktree
|
|
35
35
|
|
|
36
|
-
##
|
|
36
|
+
## Language axes (en/tr)
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
only** - e.g. the Phase 6 pre-commit local-checkout test prompt, Plan Approval Gate
|
|
41
|
-
questions, multi-repo branch picker labels, and phase-banner.sh banners (when
|
|
42
|
-
PHASE_LANG env is unset, it auto-reads prefs).
|
|
38
|
+
Two prefs, two jobs - the full matrix lives in `multi-agent-refs/rules.md`
|
|
39
|
+
"Language Application" and that file wins on any disagreement:
|
|
43
40
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
- `prefs.global.promptLanguage` is **locked to `en`**: every LLM-facing prompt,
|
|
42
|
+
spec file and instruction stays English.
|
|
43
|
+
- `prefs.global.outputLanguage` (set via `/multi-agent:setup` or
|
|
44
|
+
`/multi-agent:language en|tr`) drives what humans read: interactive prompts,
|
|
45
|
+
phase banners, AND the external payload **bodies** - PR description, Jira
|
|
46
|
+
comment, Confluence/Wiki pages all render in it.
|
|
47
|
+
|
|
48
|
+
Always English regardless of either pref: commit messages, branch names, PR
|
|
49
|
+
titles, code identifiers, file paths, and `AskUserQuestion` label/header.
|
|
47
50
|
|
|
48
51
|
When writing TR prompts, use the same keyword/menu numbers as EN (e.g. `[1-4]`)
|
|
49
52
|
so the user's input pattern stays language-agnostic.
|
|
@@ -242,7 +245,7 @@ Cost block reads `phase-tracker.sh tokens` accumulators × `cost-table.json` pri
|
|
|
242
245
|
|
|
243
246
|
## Stack Selection
|
|
244
247
|
|
|
245
|
-
Stack skill sets ship as versioned plugins in the `multi-agent-plugins` marketplace. Selecting a stack enables the matching plugin(s) in the target repo's `.claude/settings.json` `enabledPlugins`; the `ai-common-
|
|
248
|
+
Stack skill sets ship as versioned plugins in the `multi-agent-plugins` marketplace. Selecting a stack enables the matching plugin(s) in the target repo's `.claude/settings.json` `enabledPlugins`; the `ai-common-toolkit` is always enabled alongside. There is no session-start auto-swap script. Select or change the stack with:
|
|
246
249
|
|
|
247
250
|
```bash
|
|
248
251
|
multi-agent-stack [ios|android|mobile|backend|frontend|fullstack|all]
|
|
@@ -299,8 +302,8 @@ if [ "$(jq '.projects | length' "$STATE_FILE")" -ge 2 ]; then
|
|
|
299
302
|
fi
|
|
300
303
|
```
|
|
301
304
|
|
|
302
|
-
Full contract:
|
|
303
|
-
(
|
|
305
|
+
Full contract: https://github.com/mmerterden/multi-agent-pipeline/blob/main/pipeline/multi-agent-refs/multi-repo-integration-build.md
|
|
306
|
+
(the Copilot install ships no local refs tree, so the contract lives on GitHub only)
|
|
304
307
|
|
|
305
308
|
## Permissions Expectation
|
|
306
309
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmerterden/multi-agent-pipeline",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "15.0.0",
|
|
4
4
|
"description": "8-phase AI development pipeline with full orchestration on Claude Code, Copilot CLI and Codex CLI. Analysis, planning, TDD, CLI-aware parallel review with consensus surfacing + Fable triage, default-FAIL evidence gates, secret + intent guards, per-phase cost ledger, persistent learnings memory, wiki generation, commit automation. Token-preserving uninstall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -89,7 +89,6 @@
|
|
|
89
89
|
"!pipeline/scripts/sync-parity-check.sh",
|
|
90
90
|
"!pipeline/scripts/benchmark-phase-0.sh",
|
|
91
91
|
"!pipeline/scripts/fixtures/**",
|
|
92
|
-
"!pipeline/scripts/test-gap-rules/**",
|
|
93
92
|
"!pipeline/eval/**",
|
|
94
93
|
"pipeline/scripts/smoke-schema-validation.sh",
|
|
95
94
|
"pipeline/scripts/smoke-cross-cli-behavior.sh"
|
|
@@ -12,7 +12,7 @@ Parse the user input and route to the correct sub-command.
|
|
|
12
12
|
|
|
13
13
|
**Input**: $ARGUMENTS
|
|
14
14
|
|
|
15
|
-
> **Language (read FIRST)**: Before any status output, read `prefs.global.outputLanguage` from `$HOME/.claude/multi-agent-preferences.json` and render every conversational line in it. `AskUserQuestion` and external
|
|
15
|
+
> **Language (read FIRST)**: Before any status output, read `prefs.global.outputLanguage` from `$HOME/.claude/multi-agent-preferences.json` 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".
|
|
16
16
|
|
|
17
17
|
## Canonical Invocation (per CLI)
|
|
18
18
|
|
|
@@ -78,6 +78,7 @@ Lib scripts (`~/.claude/lib/`):
|
|
|
78
78
|
| `review-jira [KEY\|url]` | Grade a Jira issue's readiness for the pipeline (scope / AC / repro / design / API / stack), then post the gaps as a Jira comment. Read-only on code. |
|
|
79
79
|
| `review-issue [#N\|repo#N\|url]` | Grade a GitHub issue's readiness for the pipeline, then post the gaps as an issue comment. Read-only on code. |
|
|
80
80
|
| `analysis ["<feature>"]` | Standalone feature-spec analizi: Figma / Swagger / Confluence / Jira / repo girdileri sabit 7-bölümlük şablona dökülür, humanizer'dan geçer, Local/Confluence/Jira hedef(ler)ine post edilir. Worktree veya commit yok. Dev'e zincirleme yok. |
|
|
81
|
+
| `complaint-analysis ["<run-name>"] [--file <path>] [<jira-id\|confluence-url> ...]` | Müşteri şikayeti triyajı: şikayetler (serbest metin / csv-xlsx-txt-json dosya / Jira issue / Confluence URL) redakte edilerek alınır, trxId/conversationId ile Graylog kanıtı çekilir, seçili client + BFF repolarında salt-okunur eşleştirme yapılır; verdict: client/bff (kök neden + citation + mevcut mimariyi referans alan fix planı + hazır dev prompt'u) veya core (core ekibine yönlendirme önerisi) veya insufficient-evidence. Rapor + Stop; worktree, commit, dev zinciri yok. |
|
|
81
82
|
| `build-optimize` | iOS-only Xcode build performance wrapper. Vendored `xcode-build-orchestrator`'a dispatch eder; benchmark + compilation / project / SPM analyzer'lar + recommend-first plan `.build-benchmark/optimization-plan.md`. Non-iOS stack'lerde fail-fast. |
|
|
82
83
|
| `channels [PR-url\|#N\|Jira-url\|Jira-id] [--channels pr,jira,confluence,wiki] [--content normal,test,auto-diff,note] [--message "..."]` | Post task report to multi-select channels (PR description, Jira comment, Confluence page, Wiki pages) with multi-select content sources. Humanizer pass per-channel. Bitbucket PR updates use reviewer-preserving PUT. Phase 7 delegates to this command; also invocable post-hoc for fixes made outside the pipeline. No worktree. |
|
|
83
84
|
| `create-jira ["desc"] [figma-url] [swagger-url]` | Create a standards-compliant Jira issue: asks the type (**Task** / **Bug** / **Story**), mines the project's recent same-type issues for conventions (summary format, labels, priority, test-scenario style), detects the active sprint, drafts from a standard template with auto-sizing sections (Design Reference / API Contract / Screenshots appear only when their source is given), asks about unknown fields, then full draft preview + explicit approval before create. No worktree, no commits. |
|
|
@@ -120,6 +121,7 @@ This command uses lazy loading for token efficiency. Read the relevant sub-file
|
|
|
120
121
|
| `review-jira` | `$HOME/.claude/commands/multi-agent/review-jira/SKILL.md` (loads `$HOME/.claude/multi-agent-refs/readiness-review.md`) |
|
|
121
122
|
| `review-issue` | `$HOME/.claude/commands/multi-agent/review-issue/SKILL.md` (loads `$HOME/.claude/multi-agent-refs/readiness-review.md`) |
|
|
122
123
|
| `analysis` | `$HOME/.claude/commands/multi-agent/analysis/SKILL.md` |
|
|
124
|
+
| `complaint-analysis` | `$HOME/.claude/commands/multi-agent/complaint-analysis/SKILL.md` |
|
|
123
125
|
| `build-optimize` | `$HOME/.claude/commands/multi-agent/build-optimize/SKILL.md` |
|
|
124
126
|
| `local` | `$HOME/.claude/commands/multi-agent/local/SKILL.md` |
|
|
125
127
|
| `local-autopilot` | `$HOME/.claude/commands/multi-agent/local-autopilot/SKILL.md` |
|
|
@@ -207,7 +209,7 @@ When the user supplies an ID/URL/free-text:
|
|
|
207
209
|
2. **Pick account** - always asked (autopilot picks default)
|
|
208
210
|
3. **Fetch issue** - `lib/issue-fetcher.sh "$INPUT"` (Jira/GitHub fetch + maturity)
|
|
209
211
|
4. **Repo picker** - only for `gh-num` (e.g. `316`) when repo is ambiguous, multi-select
|
|
210
|
-
5. **Maturity check** - blocker halts (autopilot too), warning prompt/log
|
|
212
|
+
5. **Maturity check** - blocker halts (autopilot too), warning prompt/log. For a Jira input specifically, an empty own description with a non-empty parent surfaces as `description_empty_parent_available` (warning, not blocker) - ask the tailored parent-description question from `jira/SKILL.md`'s maturity section instead of the generic "Continue?" prompt.
|
|
211
213
|
6. **Dev context** - always runs, empty submit allowed
|
|
212
214
|
7. → Interactive Launcher → Phase 0
|
|
213
215
|
|
|
@@ -505,9 +505,9 @@ For each `platform` in `state.analysisSpec.platforms[]`:
|
|
|
505
505
|
|
|
506
506
|
2. **Per-platform markdown render**: for each platform in `state.analysisSpec.platforms[]`, concatenate the per-platform spec into one markdown file. Tables in pipe-syntax. Numbering uses plain `## 1.`, `## 2.`, ... - omitted sections do **not** create gaps. Visible numbering is sequential 1..N over the rendered set.
|
|
507
507
|
|
|
508
|
-
3. **Humanizer pass (MANDATORY: actually invoke the `humanizer` skill on the rendered markdown - the punctuation grep alone does NOT satisfy this step)** (`technical-explanatory` tone for the scratch buffer; per-channel re-humanize happens in Phase 4 when actually emitting):
|
|
508
|
+
3. **Humanizer pass (MANDATORY: actually invoke the `ai-common-toolkit:humanizer` skill on the rendered markdown - the punctuation grep alone does NOT satisfy this step)** (`technical-explanatory` tone for the scratch buffer; per-channel re-humanize happens in Phase 4 when actually emitting):
|
|
509
509
|
```
|
|
510
|
-
humanizer skill input:
|
|
510
|
+
ai-common-toolkit:humanizer skill input:
|
|
511
511
|
language: <tr|en>
|
|
512
512
|
tone: technical-explanatory
|
|
513
513
|
stripFancyPunctuation: true
|
|
@@ -543,7 +543,7 @@ options:
|
|
|
543
543
|
|
|
544
544
|
Conditional follow-ups:
|
|
545
545
|
- If `Confluence` selected: ask `header="Parent page"`, free-text via Other for the parent page key or URL. One Confluence page per platform is created under this parent, each titled `<Feature> - <Platform>`.
|
|
546
|
-
- If `Jira` selected: if Step 5 Q4 produced Jira IDs, AskUserQuestion (single-select) to pick which one; otherwise ask via Other. Per Locked decision 9 + design choice "single description with platform separators", the chosen issue receives one combined description body holding all per-platform sections under
|
|
546
|
+
- If `Jira` selected: if Step 5 Q4 produced Jira IDs, AskUserQuestion (single-select) to pick which one; otherwise ask via Other. Per Locked decision 9 + design choice "single description with platform separators", the chosen issue receives one combined description body holding all per-platform sections under `h2. Platform: <X>` separators (wiki markup - the description field does not render Markdown; conversion happens at dispatch, see Phase 4).
|
|
547
547
|
|
|
548
548
|
Result: `state.analysisSpec.outputs.requested[]`.
|
|
549
549
|
|
|
@@ -565,7 +565,7 @@ Iterate `state.analysisSpec.outputs.requested`. For each target:
|
|
|
565
565
|
|--------|--------|
|
|
566
566
|
| Local | For each per-platform draft, `cp /tmp/analysis-<feature-slug>-<ts>/<feature>-<platform>.md` into `analysis/<feature>-<platform>.md` in the matching repo's working tree. When multiple repos exist for the same platform, the file is duplicated into each and the dispatch report lists every destination. **No commit.** |
|
|
567
567
|
| Confluence | Re-humanize each per-platform draft with `formal-stakeholder` tone. One Confluence page per platform under the chosen parent, titled `<Feature> - <Platform>`. Cross-link siblings inside each page via `<ac:link><ri:page ri:content-title="<Feature> - <OtherPlatform>"/></ac:link>`. Markdown -> storage XML via `$HOME/.claude/multi-agent-refs/channels/confluence.md`. Re-emit on existing pages uses PUT with version bump. |
|
|
568
|
-
| Jira | Re-humanize the combined body with `informal-technical` tone. Concatenate per-platform drafts under
|
|
568
|
+
| Jira | Re-humanize the combined body with `informal-technical` tone. Concatenate per-platform drafts under `h2. Platform: iOS`, `h2. Platform: Android`, `h2. Platform: Backend`, `h2. Platform: Frontend` separators (in the order platforms were selected), then run the whole body through the markdown → Jira wiki conversion table in `$HOME/.claude/multi-agent-refs/channels/jira.md` - the `description` field renders wiki markup, so raw `##`/`**`/backticks arrive as literal text. Write with `PUT /rest/api/2/issue/{key}` body `{"fields": {"description": <converted body>}}` (`channels/jira.md` documents only the comment POST; the description update is this PUT). Same rawfile + `--data-binary` transport rules. |
|
|
569
569
|
|
|
570
570
|
**Output capture**: fill `state.analysisSpec.outputs.localPaths[]` (one entry per per-platform-per-repo write), `outputs.confluencePageUrls[]` (one entry per platform), `outputs.jiraIssueKey` (single string).
|
|
571
571
|
|
|
@@ -662,7 +662,7 @@ When `phase == "cancelled_at_pass_b_preview"`:
|
|
|
662
662
|
| `~/.claude/lib/extract-conventions.sh` | Phase 1c convention extractor (7 pattern groups, JSON output, confidence levels) |
|
|
663
663
|
| `~/.claude/lib/figma-screenshot.sh` | Phase 2b Tier 2 Figma image downloader (REST API, section drill, 2x scale PNG, manifest.json) |
|
|
664
664
|
| `~/.claude/lib/md2confluence-v3.py` | Phase 4 Confluence dispatch (multipart attachments, `<ac:image>` injection, mermaid macro + fallback, tooltip footnote macro, punctuation gate) |
|
|
665
|
-
|
|
|
665
|
+
| `ai-common-toolkit:humanizer` | Phase 3 tone pass |
|
|
666
666
|
| 8-locale set (ar, de, en, es, fr, it, ru, tr) + localization-key naming (inline) | Section 10 localization generation |
|
|
667
667
|
| `$HOME/.claude/multi-agent-refs/channels/confluence.md` | Phase 4 Confluence dispatch |
|
|
668
668
|
| `$HOME/.claude/multi-agent-refs/channels/jira.md` | Phase 4 Jira dispatch |
|