@mmerterden/multi-agent-pipeline 10.6.0 → 10.7.1
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 +36 -0
- package/README.md +10 -39
- package/install/index.mjs +9 -101
- package/package.json +1 -1
- package/pipeline/commands/multi-agent/delete.md +4 -5
- package/pipeline/commands/multi-agent/refs/phases/phase-4-review.md +1 -11
- package/pipeline/commands/multi-agent/refs/picker-contract.md +6 -10
- package/pipeline/commands/multi-agent/setup.md +0 -1
- package/pipeline/commands/multi-agent/sync.md +4 -73
- package/pipeline/commands/multi-agent/update.md +9 -0
- package/pipeline/lib/ask-choice.sh +1 -1
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +0 -7
- package/pipeline/scripts/smoke-install-layout.sh +1 -2
- package/pipeline/skills/.skills-index.json +65 -20
- package/pipeline/skills/shared/README.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-delete/SKILL.md +4 -4
- package/pipeline/skills/skills-index.md +24 -19
- package/install/_adapters.mjs +0 -73
- package/pipeline/adapters/_base.mjs +0 -640
- package/pipeline/adapters/antigravity.mjs +0 -140
- package/pipeline/adapters/codex.mjs +0 -159
- package/pipeline/adapters/copilot-chat-orchestration.mjs +0 -148
- package/pipeline/adapters/copilot-chat.mjs +0 -124
- package/pipeline/adapters/cursor-orchestration.mjs +0 -152
- package/pipeline/adapters/cursor.mjs +0 -146
- package/pipeline/scripts/smoke-adapters.sh +0 -276
- package/pipeline/scripts/smoke-delete-flow.sh +0 -151
- package/pipeline/scripts/smoke-shared-runtime.sh +0 -108
- package/pipeline/scripts/smoke-sync-adapters.sh +0 -113
- package/pipeline/scripts/sync-adapters.mjs +0 -183
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Google Antigravity adapter - the Gemini CLI successor (Gemini CLI
|
|
3
|
-
* consumer support ends 2026-06-18). Antigravity shares the `.gemini/` lineage
|
|
4
|
-
* but its subagents are ORCHESTRATOR-spawned, not file-declared, so the pipeline
|
|
5
|
-
* orchestration is encoded as a saved WORKFLOW prompt plus standing RULES rather
|
|
6
|
-
* than per-role agent files (contrast cursor-orchestration.mjs).
|
|
7
|
-
*
|
|
8
|
-
* Emits (project-scoped, target = repo root):
|
|
9
|
-
* .agent/rules/multi-agent-*.md standing pipeline conventions (rules tree)
|
|
10
|
-
* .agent/workflows/multi-agent.md the 8-phase orchestration as a saved prompt
|
|
11
|
-
* AGENTS.md marker-wrapped context block (rules + skill
|
|
12
|
-
* index); Antigravity reads AGENTS.md/GEMINI.md
|
|
13
|
-
* .agent/mcp_config.json dev-toolkit MCP registration
|
|
14
|
-
*
|
|
15
|
-
* NOTE: some Antigravity paths are community-documented, not yet in official
|
|
16
|
-
* docs (flagged in the install log). `.agent/rules` + `.agent/workflows` +
|
|
17
|
-
* AGENTS.md + mcp_config.json are the best-known conventions as of 2026-05; the
|
|
18
|
-
* emitted workflow tells the user to confirm placement against current docs.
|
|
19
|
-
*
|
|
20
|
-
* @module pipeline/adapters/antigravity
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { writeFileSync } from "fs";
|
|
24
|
-
import { join } from "path";
|
|
25
|
-
import {
|
|
26
|
-
collectSkills,
|
|
27
|
-
ensureDir,
|
|
28
|
-
installAdapterFiles,
|
|
29
|
-
installSharedRuntime,
|
|
30
|
-
mergeMcpJson,
|
|
31
|
-
removeFileAndPrune,
|
|
32
|
-
removeManagedBlock,
|
|
33
|
-
removePrefixedFiles,
|
|
34
|
-
renderSkillIndex,
|
|
35
|
-
replaceManagedBlock,
|
|
36
|
-
rewriteScriptRefs,
|
|
37
|
-
uninstallSharedRuntime,
|
|
38
|
-
unmergeMcpJson,
|
|
39
|
-
walkRules,
|
|
40
|
-
withoutOrchestrationSkills,
|
|
41
|
-
} from "./_base.mjs";
|
|
42
|
-
|
|
43
|
-
const NAME = "antigravity";
|
|
44
|
-
const RULE_PREFIX = "multi-agent-";
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @param {{ pipelineSrc: string, target: string, platformFilter?: "all"|"ios"|"android" }} opts
|
|
48
|
-
*/
|
|
49
|
-
export function install({ pipelineSrc, target, platformFilter = "all" }) {
|
|
50
|
-
// 1. Rules tree -> .agent/rules/
|
|
51
|
-
const rules = installAdapterFiles({
|
|
52
|
-
outDir: join(target, ".agent", "rules"),
|
|
53
|
-
items: walkRules(pipelineSrc),
|
|
54
|
-
fileFor: (rule) => `${RULE_PREFIX}${rule.name}.md`,
|
|
55
|
-
render: (rule) => `${rule.body.trim()}\n`,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// 2. Orchestration workflow.
|
|
59
|
-
const wfOut = join(target, ".agent", "workflows");
|
|
60
|
-
ensureDir(wfOut);
|
|
61
|
-
writeFileSync(join(wfOut, "multi-agent.md"), rewriteScriptRefs(ORCHESTRATION_WORKFLOW));
|
|
62
|
-
|
|
63
|
-
// 3. AGENTS.md context block (rules already in .agent/rules; here we add a
|
|
64
|
-
// skill index so the agent knows what reference skills exist).
|
|
65
|
-
const skills = withoutOrchestrationSkills(collectSkills(pipelineSrc, platformFilter));
|
|
66
|
-
const ctxAction = replaceManagedBlock(join(target, "AGENTS.md"), renderContext(skills));
|
|
67
|
-
|
|
68
|
-
// 4. MCP.
|
|
69
|
-
const mcp = mergeMcpJson(join(target, ".agent", "mcp_config.json"));
|
|
70
|
-
|
|
71
|
-
// 5. Shared runtime so the workflow's gate-script references resolve + run.
|
|
72
|
-
installSharedRuntime(pipelineSrc);
|
|
73
|
-
|
|
74
|
-
console.log(
|
|
75
|
-
` -> [antigravity] ${rules} rules + workflow + AGENTS.md (${ctxAction}) + mcp_config.json (${mcp})`,
|
|
76
|
-
);
|
|
77
|
-
console.log(
|
|
78
|
-
" -> [antigravity] NOTE: .agent/ paths are community-documented; confirm against current Antigravity docs.",
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* @param {{ target: string }} opts
|
|
84
|
-
*/
|
|
85
|
-
export function uninstall({ target }) {
|
|
86
|
-
let removed = removePrefixedFiles(join(target, ".agent", "rules"), RULE_PREFIX, ".md");
|
|
87
|
-
const wfDir = join(target, ".agent", "workflows");
|
|
88
|
-
removed += removeFileAndPrune(join(wfDir, "multi-agent.md"), wfDir);
|
|
89
|
-
removeManagedBlock(join(target, "AGENTS.md"));
|
|
90
|
-
unmergeMcpJson(join(target, ".agent", "mcp_config.json"));
|
|
91
|
-
if (uninstallSharedRuntime()) removed++;
|
|
92
|
-
return { removed };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function renderContext(skills) {
|
|
96
|
-
return renderSkillIndex({
|
|
97
|
-
title: "# multi-agent-pipeline (Antigravity)",
|
|
98
|
-
intro: [
|
|
99
|
-
"> Installed by @mmerterden/multi-agent-pipeline. Standing rules live in",
|
|
100
|
-
"> `.agent/rules/`; the orchestration runs via `.agent/workflows/multi-agent.md`.",
|
|
101
|
-
"> Below is the reference skill index. Remove with",
|
|
102
|
-
"> `npx @mmerterden/multi-agent-pipeline uninstall --antigravity`.",
|
|
103
|
-
],
|
|
104
|
-
skills,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const ORCHESTRATION_WORKFLOW = `# /multi-agent - run the pipeline in Antigravity
|
|
109
|
-
|
|
110
|
-
> Installed by @mmerterden/multi-agent-pipeline. Antigravity spawns subagents
|
|
111
|
-
> from your goal (they are not file-declared), so this workflow encodes the
|
|
112
|
-
> 8-phase orchestration as a prompt. Standing conventions are in
|
|
113
|
-
> \`.agent/rules/\`. Pickers/approvals follow refs/picker-contract.md (use
|
|
114
|
-
> Antigravity's approval UI or a numbered
|
|
115
|
-
> prompt). The dev-toolkit MCP server is registered in \`.agent/mcp_config.json\`.
|
|
116
|
-
>
|
|
117
|
-
> GATE SCRIPTS: the deterministic-gate scripts are installed to a shared
|
|
118
|
-
> \`$HOME/.multi-agent/scripts/\` runtime (evidence-gate.mjs, classify-intent.sh,
|
|
119
|
-
> learnings-ledger.mjs, validate-triage.mjs, pre-commit-check.sh, ...). Invoke
|
|
120
|
-
> them by that absolute path. Unlike Claude Code there is no PreToolUse hook
|
|
121
|
-
> forcing them, so run them as explicit workflow steps (workflow-enforced, not
|
|
122
|
-
> OS-blocked).
|
|
123
|
-
|
|
124
|
-
Input: a Jira id, GitHub issue, repo#N, or free-text task.
|
|
125
|
-
|
|
126
|
-
Run these phases in order, obeying every file under \`.agent/rules/\`:
|
|
127
|
-
|
|
128
|
-
0. **Init** - detect stack, resolve branch (\`bugfix/…\` / \`feature/…\`), confirm scope.
|
|
129
|
-
1. **Analysis** - explore the codebase (spawn a read-only investigator subagent); produce a structured analysis: stack, touchedAreas[], risks[], summary.
|
|
130
|
-
2. **Planning** - draft the task breakdown; present it and ask the user to Approve / Cancel / edit (picker-contract). Loop on edits until approved.
|
|
131
|
-
3. **Dev** - implement TDD-first (test -> code -> build), following the rules.
|
|
132
|
-
4. **Review** - run review in parallel. For cross-model coverage, spawn TWO parallel code-review agents in the Agent Manager and set each to a DIFFERENT model via the side-panel dropdown (recommended pair: Gemini 3 Pro + Claude Opus 4.6) - Antigravity selects an agent's model in the UI, not a file, so this is a manual two-agent setup. Add the stack architect (iOS / Android / backend) and a security pass when auth/secrets are touched. Merge findings, triage (accept / defer / reject), record the consensus block (same-model agreement on judgment calls = unverified), fix accepted blocking/important items, re-review.
|
|
133
|
-
5. **Test** - offer an interactive test pass (picker); use the dev-toolkit MCP server for simulator / emulator / web checks.
|
|
134
|
-
6. **Commit** - \`{type}(scope): description\`; never auto-close issues; PR uses \`Ref: #N\`.
|
|
135
|
-
7. **Report** - summarize changes, per-reviewer consensus, and cost.
|
|
136
|
-
|
|
137
|
-
No "AI / generated by" in code or commits. Attribute each finding to the review pass that raised it.
|
|
138
|
-
`;
|
|
139
|
-
|
|
140
|
-
export default { name: NAME, install, uninstall };
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file OpenAI Codex CLI adapter.
|
|
3
|
-
*
|
|
4
|
-
* Codex CLI is a GLOBAL-config tool, not a per-project rule consumer like
|
|
5
|
-
* Cursor / Antigravity / Copilot Chat. Its custom prompts (slash commands) and
|
|
6
|
-
* MCP servers live under `~/.codex/`, and there is no project-level prompt
|
|
7
|
-
* directory. The only project-scoped hook Codex reads is `AGENTS.md` (the shared
|
|
8
|
-
* open standard), which the Antigravity adapter already writes when installed.
|
|
9
|
-
*
|
|
10
|
-
* Therefore this adapter writes Codex's REAL surfaces, all global, and ignores
|
|
11
|
-
* the per-project `target`:
|
|
12
|
-
* ~/.codex/prompts/multi-agent.md the 8-phase orchestration as a /multi-agent
|
|
13
|
-
* slash command (sequential - Codex has no
|
|
14
|
-
* subagent fan-out, so parallel review
|
|
15
|
-
* degrades to a sequential two-pass)
|
|
16
|
-
* ~/.codex/AGENTS.md marker-wrapped global context block (rules
|
|
17
|
-
* pointer + skill index)
|
|
18
|
-
* ~/.codex/config.toml marker-wrapped [mcp_servers.dev-toolkit]
|
|
19
|
-
* registration (TOML managed block)
|
|
20
|
-
*
|
|
21
|
-
* Shared gate scripts install to the common `~/.multi-agent/` runtime, same as
|
|
22
|
-
* the other adapters.
|
|
23
|
-
*
|
|
24
|
-
* @module pipeline/adapters/codex
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import { writeFileSync } from "fs";
|
|
28
|
-
import { join } from "path";
|
|
29
|
-
import {
|
|
30
|
-
collectSkills,
|
|
31
|
-
ensureDir,
|
|
32
|
-
installSharedRuntime,
|
|
33
|
-
removeFileAndPrune,
|
|
34
|
-
removeManagedBlock,
|
|
35
|
-
renderSkillIndex,
|
|
36
|
-
replaceManagedBlock,
|
|
37
|
-
rewriteScriptRefs,
|
|
38
|
-
uninstallSharedRuntime,
|
|
39
|
-
withoutOrchestrationSkills,
|
|
40
|
-
} from "./_base.mjs";
|
|
41
|
-
|
|
42
|
-
const NAME = "codex";
|
|
43
|
-
|
|
44
|
-
// TOML cannot host HTML-comment markers, so config.toml uses its own
|
|
45
|
-
// `#`-comment managed block (kept independent of _base's MARKER_BEGIN/END).
|
|
46
|
-
const TOML_MARKERS = Object.freeze({
|
|
47
|
-
begin: "# multi-agent-pipeline:begin",
|
|
48
|
-
end: "# multi-agent-pipeline:end",
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
function codexHome() {
|
|
52
|
-
const home = process.env.HOME || process.env.USERPROFILE;
|
|
53
|
-
if (!home) throw new Error("$HOME (or $USERPROFILE) is not set");
|
|
54
|
-
return join(home, ".codex");
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* @param {{ pipelineSrc: string, target?: string, platformFilter?: "all"|"ios"|"android" }} opts
|
|
59
|
-
*/
|
|
60
|
-
export function install({ pipelineSrc, platformFilter = "all" }) {
|
|
61
|
-
const base = codexHome();
|
|
62
|
-
|
|
63
|
-
// 1. Slash command -> ~/.codex/prompts/multi-agent.md
|
|
64
|
-
const promptsDir = join(base, "prompts");
|
|
65
|
-
ensureDir(promptsDir);
|
|
66
|
-
writeFileSync(join(promptsDir, "multi-agent.md"), rewriteScriptRefs(ORCHESTRATION_PROMPT));
|
|
67
|
-
|
|
68
|
-
// 2. Global context block -> ~/.codex/AGENTS.md
|
|
69
|
-
const skills = withoutOrchestrationSkills(collectSkills(pipelineSrc, platformFilter));
|
|
70
|
-
const ctxAction = replaceManagedBlock(join(base, "AGENTS.md"), renderContext(skills));
|
|
71
|
-
|
|
72
|
-
// 3. MCP registration -> ~/.codex/config.toml
|
|
73
|
-
const mcp = mergeTomlMcp(join(base, "config.toml"));
|
|
74
|
-
|
|
75
|
-
// 4. Shared runtime so the prompt's gate-script references resolve + run.
|
|
76
|
-
installSharedRuntime(pipelineSrc);
|
|
77
|
-
|
|
78
|
-
console.log(
|
|
79
|
-
` -> [codex] prompts/multi-agent.md + AGENTS.md (${ctxAction}) + config.toml mcp (${mcp})`,
|
|
80
|
-
);
|
|
81
|
-
console.log(
|
|
82
|
-
" -> [codex] global install under ~/.codex (prompts + MCP are global; Codex has no per-project prompt dir).",
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Codex writes only to ~/.codex, so uninstall ignores `target`.
|
|
88
|
-
*/
|
|
89
|
-
export function uninstall() {
|
|
90
|
-
const base = codexHome();
|
|
91
|
-
let removed = removeFileAndPrune(join(base, "prompts", "multi-agent.md"));
|
|
92
|
-
|
|
93
|
-
if (removeManagedBlock(join(base, "AGENTS.md")).startsWith("removed")) removed++;
|
|
94
|
-
if (removeManagedBlock(join(base, "config.toml"), { markers: TOML_MARKERS }).startsWith("removed")) removed++;
|
|
95
|
-
if (uninstallSharedRuntime()) removed++;
|
|
96
|
-
|
|
97
|
-
return { removed };
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function renderContext(skills) {
|
|
101
|
-
return renderSkillIndex({
|
|
102
|
-
title: "# multi-agent-pipeline (Codex CLI)",
|
|
103
|
-
intro: [
|
|
104
|
-
"> Installed by @mmerterden/multi-agent-pipeline. Run the pipeline with the",
|
|
105
|
-
"> `/multi-agent` slash command (defined in `~/.codex/prompts/multi-agent.md`).",
|
|
106
|
-
"> The dev-toolkit MCP server is registered in `~/.codex/config.toml`.",
|
|
107
|
-
"> Below is the reference skill index. Remove with",
|
|
108
|
-
"> `npx @mmerterden/multi-agent-pipeline uninstall --codex`.",
|
|
109
|
-
],
|
|
110
|
-
skills,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const MCP_BLOCK_BODY = [
|
|
115
|
-
"[mcp_servers.dev-toolkit]",
|
|
116
|
-
'command = "npx"',
|
|
117
|
-
'args = ["-y", "@mmerterden/dev-toolkit-mcp"]',
|
|
118
|
-
].join("\n");
|
|
119
|
-
|
|
120
|
-
function mergeTomlMcp(tomlPath) {
|
|
121
|
-
ensureDir(join(tomlPath, ".."));
|
|
122
|
-
const action = replaceManagedBlock(tomlPath, MCP_BLOCK_BODY, { markers: TOML_MARKERS });
|
|
123
|
-
// A managed block landing in a pre-existing user TOML is a "merged" config.
|
|
124
|
-
return action === "appended" ? "merged" : action;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const ORCHESTRATION_PROMPT = `# /multi-agent - run the pipeline in Codex CLI
|
|
128
|
-
|
|
129
|
-
> Installed by @mmerterden/multi-agent-pipeline. Codex runs a single agent loop
|
|
130
|
-
> (no file-declared subagents and no parallel subagent fan-out), so this prompt
|
|
131
|
-
> encodes the 8-phase orchestration sequentially. The standing conventions (TDD,
|
|
132
|
-
> security, code-review, git) live in the skill index in \`~/.codex/AGENTS.md\`.
|
|
133
|
-
> Pickers/approvals follow refs/picker-contract.md - use a numbered prompt and
|
|
134
|
-
> wait for the user's choice. The dev-toolkit MCP server is registered in
|
|
135
|
-
> \`~/.codex/config.toml\`.
|
|
136
|
-
>
|
|
137
|
-
> GATE SCRIPTS: the deterministic-gate scripts are installed to a shared
|
|
138
|
-
> \`$HOME/.multi-agent/scripts/\` runtime (evidence-gate.mjs, classify-intent.sh,
|
|
139
|
-
> learnings-ledger.mjs, validate-triage.mjs, pre-commit-check.sh, ...). Invoke
|
|
140
|
-
> them by that absolute path as explicit steps - there is no PreToolUse hook
|
|
141
|
-
> forcing them, so they are workflow-enforced, not OS-blocked.
|
|
142
|
-
|
|
143
|
-
Input: a Jira id, GitHub issue, repo#N, or free-text task.
|
|
144
|
-
|
|
145
|
-
Run these phases in order, obeying every convention in \`~/.codex/AGENTS.md\`:
|
|
146
|
-
|
|
147
|
-
0. **Init** - detect stack, resolve branch (\`bugfix/…\` / \`feature/…\`), confirm scope.
|
|
148
|
-
1. **Analysis** - explore the codebase; produce a structured analysis: stack, touchedAreas[], risks[], summary.
|
|
149
|
-
2. **Planning** - draft the task breakdown; present it and ask the user to Approve / Cancel / edit (picker-contract). Loop on edits until approved.
|
|
150
|
-
3. **Dev** - implement TDD-first (test -> code -> build), following the conventions.
|
|
151
|
-
4. **Review** - Codex has no parallel subagents, so run review as a sequential two-pass: first a correctness/security pass, then a separate fresh-context pass that tries to REFUTE the first pass's findings (adversarial verify). Add a stack-architect lens (iOS / Android / backend) and a security pass when auth/secrets are touched. Merge findings, triage (accept / defer / reject), fix accepted blocking/important items, re-review.
|
|
152
|
-
5. **Test** - offer an interactive test pass (picker); use the dev-toolkit MCP server for simulator / emulator / web checks.
|
|
153
|
-
6. **Commit** - \`{type}(scope): description\`; never auto-close issues; PR uses \`Ref: #N\`.
|
|
154
|
-
7. **Report** - summarize changes, the review passes, and cost.
|
|
155
|
-
|
|
156
|
-
No "AI / generated by" in code or commits. Attribute each finding to the review pass that raised it.
|
|
157
|
-
`;
|
|
158
|
-
|
|
159
|
-
export default { name: NAME, install, uninstall };
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file VS Code Copilot Chat orchestration layer - emits the FULL-pipeline
|
|
3
|
-
* artifacts so the pipeline runs in VS Code Copilot Chat agent mode, not just
|
|
4
|
-
* the knowledge layer.
|
|
5
|
-
*
|
|
6
|
-
* VS Code Copilot Chat (2026) supports file-based custom agents
|
|
7
|
-
* (`.github/agents/*.agent.md`, with `description` / `tools` / `model` /
|
|
8
|
-
* `agents` / `handoffs`) and prompt-file commands (`.github/prompts/*.prompt.md`),
|
|
9
|
-
* plus native tool-approval / confirmation dialogs (the picker-contract render
|
|
10
|
-
* target for this platform). Parallelism is handoff-driven rather than a
|
|
11
|
-
* concurrent fan-out, so the review phase runs the reviewers as orchestrated
|
|
12
|
-
* sub-agents.
|
|
13
|
-
*
|
|
14
|
-
* Emits:
|
|
15
|
-
* .github/agents/ma-*.agent.md one custom agent per pipeline persona
|
|
16
|
-
* .github/prompts/multi-agent.prompt.md the /multi-agent orchestration driver
|
|
17
|
-
* .vscode/mcp.json dev-toolkit MCP registration (merged)
|
|
18
|
-
*
|
|
19
|
-
* @module pipeline/adapters/copilot-chat-orchestration
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { writeFileSync } from "fs";
|
|
23
|
-
import { join } from "path";
|
|
24
|
-
import {
|
|
25
|
-
ensureDir,
|
|
26
|
-
installPersonaAgents,
|
|
27
|
-
installSharedRuntime,
|
|
28
|
-
mergeMcpJson,
|
|
29
|
-
removeFileAndPrune,
|
|
30
|
-
removePrefixedFiles,
|
|
31
|
-
REVIEWER_MODELS,
|
|
32
|
-
rewriteScriptRefs,
|
|
33
|
-
uninstallSharedRuntime,
|
|
34
|
-
unmergeMcpJson,
|
|
35
|
-
} from "./_base.mjs";
|
|
36
|
-
|
|
37
|
-
const AGENT_PREFIX = "ma-";
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @param {{ pipelineSrc: string, target: string }} opts
|
|
41
|
-
*/
|
|
42
|
-
export function installOrchestration({ pipelineSrc, target }) {
|
|
43
|
-
// The code-reviewer pins a Claude model; every other persona inherits the
|
|
44
|
-
// picker model (omit `model`). The cross-vendor second reviewer is pinned to
|
|
45
|
-
// a different vendor so Phase 4 is a 2-model review (Claude + GPT) instead
|
|
46
|
-
// of single-model.
|
|
47
|
-
const cm = REVIEWER_MODELS.copilotChat.crossModel;
|
|
48
|
-
const { agents, names: personaNames } = installPersonaAgents({
|
|
49
|
-
pipelineSrc,
|
|
50
|
-
outDir: join(target, ".github", "agents"),
|
|
51
|
-
prefix: AGENT_PREFIX,
|
|
52
|
-
fileFor: (name) => `${AGENT_PREFIX}${name}.agent.md`,
|
|
53
|
-
render: renderAgent,
|
|
54
|
-
primaryOpts: (persona) => ({
|
|
55
|
-
model: persona === "code-reviewer" ? REVIEWER_MODELS.copilotChat.primary : null,
|
|
56
|
-
}),
|
|
57
|
-
crossReviewer: {
|
|
58
|
-
model: cm,
|
|
59
|
-
note: `Cross-vendor reviewer pinned to \`${cm}\` so Phase 4 runs two different models (vs the primary \`ma-code-reviewer\` on \`${REVIEWER_MODELS.copilotChat.primary}\`). Adjust the model labels to ones available in your Copilot plan.`,
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
const promptsOut = join(target, ".github", "prompts");
|
|
64
|
-
ensureDir(promptsOut);
|
|
65
|
-
writeFileSync(join(promptsOut, "multi-agent.prompt.md"), rewriteScriptRefs(renderDriver(personaNames)));
|
|
66
|
-
|
|
67
|
-
const mcp = mergeMcpJson(join(target, ".vscode", "mcp.json"), { rootKey: "servers" });
|
|
68
|
-
|
|
69
|
-
// Shared runtime so the agents' gate-script references resolve + run.
|
|
70
|
-
installSharedRuntime(pipelineSrc);
|
|
71
|
-
|
|
72
|
-
return { agents, mcp };
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* @param {{ target: string }} opts
|
|
77
|
-
*/
|
|
78
|
-
export function uninstallOrchestration({ target }) {
|
|
79
|
-
let removed = removePrefixedFiles(join(target, ".github", "agents"), AGENT_PREFIX, ".agent.md");
|
|
80
|
-
const promptsDir = join(target, ".github", "prompts");
|
|
81
|
-
removed += removeFileAndPrune(join(promptsDir, "multi-agent.prompt.md"), promptsDir);
|
|
82
|
-
unmergeMcpJson(join(target, ".vscode", "mcp.json"), { rootKey: "servers" });
|
|
83
|
-
if (uninstallSharedRuntime()) removed++;
|
|
84
|
-
return { removed };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function renderAgent(persona, frontmatter, body, opts = {}) {
|
|
88
|
-
const description = (frontmatter.description || `multi-agent pipeline ${persona}`).replace(/\n/g, " ").trim();
|
|
89
|
-
const tier = frontmatter.model || "inherit";
|
|
90
|
-
// VS Code Copilot Chat has no `inherit` keyword: OMIT `model` to inherit the
|
|
91
|
-
// picker's model, or pin a specific picker LABEL. (Writing `model: inherit`
|
|
92
|
-
// would name a non-existent model.) The agent name is derived from the filename.
|
|
93
|
-
const modelLine = opts.model ? [`model: ${opts.model}`] : [];
|
|
94
|
-
const fm = [
|
|
95
|
-
"---",
|
|
96
|
-
`description: ${JSON.stringify(description)}`,
|
|
97
|
-
"tools: ['codebase', 'search', 'usages']",
|
|
98
|
-
...modelLine,
|
|
99
|
-
"---",
|
|
100
|
-
"",
|
|
101
|
-
`> Pipeline persona \`${persona}\` (intended tier: ${tier}). Transformed for VS Code`,
|
|
102
|
-
"> Copilot Chat by @mmerterden/multi-agent-pipeline. Read-only analysis/review",
|
|
103
|
-
"> role; the main agent performs edits. Confirmations use the native approval UI",
|
|
104
|
-
"> (see refs/picker-contract.md).",
|
|
105
|
-
...(opts.note ? ["> ", `> ${opts.note}`] : []),
|
|
106
|
-
"",
|
|
107
|
-
].join("\n");
|
|
108
|
-
return `${fm}${rewriteScriptRefs(body.trim())}\n`;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function renderDriver(personaNames) {
|
|
112
|
-
const agentList = personaNames.map((n) => `\`${n}\``).join(", ");
|
|
113
|
-
return `---
|
|
114
|
-
mode: agent
|
|
115
|
-
description: "Run the multi-agent pipeline in VS Code Copilot Chat."
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
# /multi-agent - run the pipeline in VS Code Copilot Chat
|
|
119
|
-
|
|
120
|
-
> Installed by @mmerterden/multi-agent-pipeline. Drives the 8-phase pipeline
|
|
121
|
-
> using the custom agents in \`.github/agents/ma-*.agent.md\` and the dev-toolkit
|
|
122
|
-
> MCP server (\`.vscode/mcp.json\`). Confirmations/approvals use VS Code's native
|
|
123
|
-
> tool-approval dialogs (refs/picker-contract.md). Sub-agents available: ${agentList}.
|
|
124
|
-
>
|
|
125
|
-
> GATE SCRIPTS: installed at \`$HOME/.multi-agent/scripts/\` (evidence-gate.mjs,
|
|
126
|
-
> classify-intent.sh, learnings-ledger.mjs, validate-triage.mjs,
|
|
127
|
-
> pre-commit-check.sh); the agents invoke them there. Unlike Claude Code there is
|
|
128
|
-
> no PreToolUse hook forcing them, so they are workflow-enforced (run as steps)
|
|
129
|
-
> rather than OS-blocked.
|
|
130
|
-
|
|
131
|
-
Input: \${input:task:a Jira id, GitHub issue, repo#N, or free-text task}
|
|
132
|
-
|
|
133
|
-
Run the phases in order, following every \`.github/instructions/multi-agent-*\` file:
|
|
134
|
-
|
|
135
|
-
0. **Init** - detect stack, resolve branch (\`bugfix/…\` / \`feature/…\`), confirm scope.
|
|
136
|
-
1. **Analysis** - hand off to \`ma-explorer\`; produce stack / touchedAreas[] / risks[] / summary.
|
|
137
|
-
2. **Planning** - draft the task breakdown; present it and ask the user to Approve / Cancel / edit (native approval dialog). Loop on edits.
|
|
138
|
-
3. **Dev** - implement TDD-first (test -> code -> build), following the instructions; optionally \`ma-dev-critic\` before review.
|
|
139
|
-
4. **Review** - for cross-model coverage hand off to BOTH \`ma-code-reviewer\` (Claude) and \`ma-code-reviewer-x\` (GPT) as separate sessions so the code review runs on two vendors, plus the stack architect (\`ma-ios-architect\` / \`ma-android-architect\` / \`ma-backend-architect\`) and \`ma-security-auditor\` for auth/secret diffs. Merge findings, triage, record the \`consensus\` block (same-model agreement on judgment calls = \`unverified\`), fix accepted blocking/important, re-review.
|
|
140
|
-
5. **Test** - offer an interactive test pass; use the dev-toolkit MCP server for simulator / emulator / web checks.
|
|
141
|
-
6. **Commit** - \`{type}(scope): description\`; never auto-close issues; PR uses \`Ref: #N\`.
|
|
142
|
-
7. **Report** - summarize changes, per-reviewer consensus, and cost.
|
|
143
|
-
|
|
144
|
-
No "AI / generated by" in code or commits. Attribute each finding to the agent that raised it.
|
|
145
|
-
`;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export default { installOrchestration, uninstallOrchestration };
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file GitHub Copilot Chat adapter - emits `.github/copilot-instructions.md`
|
|
3
|
-
* (marker-wrapped) at the project root. Optionally also writes per-skill
|
|
4
|
-
* `.github/instructions/multi-agent-*.instructions.md` files which Copilot
|
|
5
|
-
* Chat picks up as scoped instructions.
|
|
6
|
-
*
|
|
7
|
-
* Note: this is **not** the same as `--copilot` (which targets the Copilot
|
|
8
|
-
* CLI's `~/.copilot/` configuration). Copilot Chat is a different product -
|
|
9
|
-
* the IDE-side chat that lives in VS Code / GitHub.com / JetBrains, reads
|
|
10
|
-
* repo-scoped instruction files, and has no subagent dispatch. So this
|
|
11
|
-
* adapter ports the knowledge layer only, like cursor/windsurf/cline.
|
|
12
|
-
*
|
|
13
|
-
* @module pipeline/adapters/copilot-chat
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { join } from "path";
|
|
17
|
-
import {
|
|
18
|
-
collectSkills,
|
|
19
|
-
concatSkills,
|
|
20
|
-
ensureDir,
|
|
21
|
-
inferGlobs,
|
|
22
|
-
installAdapterFiles,
|
|
23
|
-
jsonString,
|
|
24
|
-
rel,
|
|
25
|
-
removeManagedBlock,
|
|
26
|
-
removePrefixedFiles,
|
|
27
|
-
replaceManagedBlock,
|
|
28
|
-
withoutOrchestrationSkills,
|
|
29
|
-
} from "./_base.mjs";
|
|
30
|
-
import { installOrchestration, uninstallOrchestration } from "./copilot-chat-orchestration.mjs";
|
|
31
|
-
|
|
32
|
-
const NAME = "copilot-chat";
|
|
33
|
-
const MAIN_FILE = ".github/copilot-instructions.md";
|
|
34
|
-
const PER_SKILL_DIR = ".github/instructions";
|
|
35
|
-
const FILE_PREFIX = "multi-agent-";
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param {{ pipelineSrc: string, target: string, platformFilter?: "all"|"ios"|"android" }} opts
|
|
39
|
-
*/
|
|
40
|
-
export function install({ pipelineSrc, target, platformFilter = "all" }) {
|
|
41
|
-
const githubDir = join(target, ".github");
|
|
42
|
-
ensureDir(githubDir);
|
|
43
|
-
|
|
44
|
-
const skills = collectKnowledgeSkills(pipelineSrc, platformFilter);
|
|
45
|
-
const mainPath = join(target, MAIN_FILE);
|
|
46
|
-
|
|
47
|
-
// Main file: marker-wrapped block in copilot-instructions.md.
|
|
48
|
-
const block = renderMainBlock(skills);
|
|
49
|
-
const status = replaceManagedBlock(mainPath, block);
|
|
50
|
-
console.log(
|
|
51
|
-
` -> [copilot-chat] ${rel(target, mainPath)} ${status} (${skills.length} skills, marker-wrapped)`,
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
// Per-skill instruction files: each gets a scoped frontmatter so Copilot
|
|
55
|
-
// Chat applies it only when the user touches matching globs. Filename
|
|
56
|
-
// convention `<name>.instructions.md` is the GitHub Copilot Chat 2025+ format.
|
|
57
|
-
const perSkillOut = join(target, PER_SKILL_DIR);
|
|
58
|
-
const written = installAdapterFiles({
|
|
59
|
-
outDir: perSkillOut,
|
|
60
|
-
items: skills,
|
|
61
|
-
fileFor: (skill) => `${FILE_PREFIX}${skill.name}.instructions.md`,
|
|
62
|
-
render: renderInstructionFile,
|
|
63
|
-
});
|
|
64
|
-
console.log(
|
|
65
|
-
` -> [copilot-chat] ${written} per-skill instruction files in ${rel(target, perSkillOut)}`,
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
// Orchestration layer - custom agents + /multi-agent prompt + MCP, so the
|
|
69
|
-
// full pipeline runs in VS Code Copilot Chat agent mode.
|
|
70
|
-
const orch = installOrchestration({ pipelineSrc, target });
|
|
71
|
-
console.log(
|
|
72
|
-
` -> [copilot-chat] orchestration: ${orch.agents} custom agents (.github/agents/ma-*) + /multi-agent prompt + .vscode/mcp.json (${orch.mcp})`,
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @param {{ target: string }} opts
|
|
78
|
-
*/
|
|
79
|
-
export function uninstall({ target }) {
|
|
80
|
-
const status = removeManagedBlock(join(target, MAIN_FILE));
|
|
81
|
-
const removed = removePrefixedFiles(join(target, PER_SKILL_DIR), FILE_PREFIX, ".instructions.md");
|
|
82
|
-
const orch = uninstallOrchestration({ target });
|
|
83
|
-
|
|
84
|
-
// Don't touch .github itself - user may have other CI configs there
|
|
85
|
-
return { mainStatus: status, perSkillRemoved: removed + orch.removed };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function collectKnowledgeSkills(pipelineSrc, platformFilter) {
|
|
89
|
-
const sources = ["shared/core", "shared/external", "figma-common"];
|
|
90
|
-
if (platformFilter === "ios" || platformFilter === "all") sources.push("figma-ios");
|
|
91
|
-
if (platformFilter === "android" || platformFilter === "all") sources.push("figma-android");
|
|
92
|
-
return withoutOrchestrationSkills(collectSkills(pipelineSrc, platformFilter, { sources }));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @param {Array<{ name: string, frontmatter: Record<string,string>, body: string }>} skills
|
|
97
|
-
*/
|
|
98
|
-
function renderMainBlock(skills) {
|
|
99
|
-
const header = `# multi-agent-pipeline (GitHub Copilot Chat)
|
|
100
|
-
|
|
101
|
-
> Installed by @mmerterden/multi-agent-pipeline. Repo-scoped instructions for
|
|
102
|
-
> GitHub Copilot Chat. This block is the knowledge layer (rules + skills) loaded
|
|
103
|
-
> into every conversation; the 8-phase orchestration runs via the custom agents
|
|
104
|
-
> in \`.github/agents/ma-*.agent.md\` and the \`/multi-agent\` prompt
|
|
105
|
-
> (\`.github/prompts/multi-agent.prompt.md\`) in VS Code Copilot Chat agent mode.
|
|
106
|
-
> Confirmations use VS Code's native approval dialogs (refs/picker-contract.md).
|
|
107
|
-
|
|
108
|
-
`;
|
|
109
|
-
return header + concatSkills(skills);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @param {{ name: string, frontmatter: Record<string,string>, body: string }} skill
|
|
114
|
-
*/
|
|
115
|
-
function renderInstructionFile(skill) {
|
|
116
|
-
const description = (skill.frontmatter.description || "").replace(/\n/g, " ").trim();
|
|
117
|
-
const globs = inferGlobs(skill.name);
|
|
118
|
-
const fmLines = ["---", `description: ${jsonString(description)}`];
|
|
119
|
-
if (globs) fmLines.push(`applyTo: ${jsonString(globs)}`);
|
|
120
|
-
fmLines.push("---", "");
|
|
121
|
-
return `${fmLines.join("\n")}\n# ${skill.name}\n\n${skill.body.trim()}\n`;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export default { name: NAME, install, uninstall };
|