@mmerterden/multi-agent-pipeline 10.5.0 → 10.7.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 +55 -0
- package/README.md +11 -42
- package/install/index.mjs +9 -101
- package/package.json +1 -1
- package/pipeline/agents/android-architect.md +3 -3
- package/pipeline/agents/backend-architect.md +3 -3
- package/pipeline/agents/code-reviewer.md +3 -3
- package/pipeline/agents/ios-architect.md +3 -3
- package/pipeline/commands/multi-agent/finish.md +4 -4
- package/pipeline/commands/multi-agent/refs/features/model-fallback.md +18 -10
- package/pipeline/commands/multi-agent/refs/phases/phase-4-review.md +1 -11
- package/pipeline/commands/multi-agent/setup.md +18 -1
- package/pipeline/commands/multi-agent/stack.md +1 -1
- package/pipeline/commands/multi-agent/sync.md +5 -74
- package/pipeline/commands/multi-agent/update.md +9 -0
- package/pipeline/scripts/README.md +0 -1
- package/pipeline/scripts/build-stack-plugins.mjs +2 -2
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +0 -7
- package/pipeline/scripts/smoke-install-layout.sh +1 -2
- package/pipeline/scripts/smoke-model-fallback.sh +11 -10
- package/pipeline/skills/shared/core/multi-agent-finish/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +1 -1
- 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-shared-runtime.sh +0 -108
- package/pipeline/scripts/smoke-stack-swap.sh +0 -132
- package/pipeline/scripts/smoke-sync-adapters.sh +0 -113
- package/pipeline/scripts/stack-swap.sh +0 -182
- package/pipeline/scripts/sync-adapters.mjs +0 -183
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* sync-adapters.mjs - wire the orphaned per-project adapter installers
|
|
4
|
-
* (cursor / copilot-chat) into the sync flow.
|
|
5
|
-
*
|
|
6
|
-
* Three call shapes:
|
|
7
|
-
*
|
|
8
|
-
* 1. Single target (this repo, or any project root):
|
|
9
|
-
* node sync-adapters.mjs --target=. [--platform=ios|android|all]
|
|
10
|
-
*
|
|
11
|
-
* 2. All projects registered in prefs.global.projectsTouched[]:
|
|
12
|
-
* node sync-adapters.mjs --all
|
|
13
|
-
*
|
|
14
|
-
* 3. Doctor - show what would happen, no writes:
|
|
15
|
-
* node sync-adapters.mjs --doctor
|
|
16
|
-
*
|
|
17
|
-
* Discovery contract:
|
|
18
|
-
* - --target=. is the cwd; --target=<path> overrides.
|
|
19
|
-
* - --all reads prefs.global.projectsTouched[] (LRU). Skips entries
|
|
20
|
-
* whose path no longer exists.
|
|
21
|
-
* - For each target, the script inspects the per-project marker files
|
|
22
|
-
* (.cursor/, .cursorrules, .copilot/, .github/copilot-instructions.md)
|
|
23
|
-
* and only runs the matching adapter if the marker is present -
|
|
24
|
-
* a project that never set up Cursor won't get .cursor/rules/ filled
|
|
25
|
-
* in by sync. This mirrors Step 2b's "setup-then-sync" contract.
|
|
26
|
-
*
|
|
27
|
-
* Source layout: this script is the bridge between sync.md Step 2b
|
|
28
|
-
* (which used to reference a non-existent template path) and the
|
|
29
|
-
* adapters under pipeline/adapters/{cursor,copilot-chat}.mjs.
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
33
|
-
import { dirname, join, resolve } from "node:path";
|
|
34
|
-
import { fileURLToPath } from "node:url";
|
|
35
|
-
|
|
36
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
37
|
-
const PIPELINE_ROOT = resolve(__dirname, "..");
|
|
38
|
-
|
|
39
|
-
// --- arg parser ------------------------------------------------------------
|
|
40
|
-
|
|
41
|
-
const argv = process.argv.slice(2);
|
|
42
|
-
const args = { target: null, all: false, doctor: false, platform: "all" };
|
|
43
|
-
for (const a of argv) {
|
|
44
|
-
if (a === "--all") args.all = true;
|
|
45
|
-
else if (a === "--doctor") args.doctor = true;
|
|
46
|
-
else if (a.startsWith("--target=")) args.target = a.slice("--target=".length);
|
|
47
|
-
else if (a.startsWith("--platform=")) args.platform = a.slice("--platform=".length);
|
|
48
|
-
else if (a === "--help" || a === "-h") {
|
|
49
|
-
console.log(
|
|
50
|
-
"usage: sync-adapters.mjs --target=<path> single project\n" +
|
|
51
|
-
" sync-adapters.mjs --all every project in projectsTouched\n" +
|
|
52
|
-
" sync-adapters.mjs --doctor dry-run summary",
|
|
53
|
-
);
|
|
54
|
-
process.exit(0);
|
|
55
|
-
} else {
|
|
56
|
-
console.error(`sync-adapters: unknown arg ${a}`);
|
|
57
|
-
process.exit(2);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!args.target && !args.all && !args.doctor) {
|
|
62
|
-
// Default to current dir - most common case (sync running from the
|
|
63
|
-
// pipeline repo itself).
|
|
64
|
-
args.target = ".";
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// --- helpers ---------------------------------------------------------------
|
|
68
|
-
|
|
69
|
-
function loadPrefs() {
|
|
70
|
-
const home = process.env.HOME || process.env.USERPROFILE;
|
|
71
|
-
if (!home) return { global: { projectsTouched: [] } };
|
|
72
|
-
const p = join(home, ".claude", "multi-agent-preferences.json");
|
|
73
|
-
if (!existsSync(p)) return { global: { projectsTouched: [] } };
|
|
74
|
-
try {
|
|
75
|
-
return JSON.parse(readFileSync(p, "utf-8"));
|
|
76
|
-
} catch {
|
|
77
|
-
return { global: { projectsTouched: [] } };
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function detectAdapters(target) {
|
|
82
|
-
const out = [];
|
|
83
|
-
if (existsSync(join(target, ".cursor")) || existsSync(join(target, ".cursorrules"))) out.push("cursor");
|
|
84
|
-
if (existsSync(join(target, ".copilot")) || existsSync(join(target, ".github/copilot-instructions.md"))) out.push("copilot-chat");
|
|
85
|
-
if (existsSync(join(target, ".agent")) || existsSync(join(target, "AGENTS.md"))) out.push("antigravity");
|
|
86
|
-
return out;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async function runAdapter(name, target) {
|
|
90
|
-
const adapterPath = join(PIPELINE_ROOT, "adapters", `${name}.mjs`);
|
|
91
|
-
if (!existsSync(adapterPath)) {
|
|
92
|
-
console.error(`sync-adapters: adapter not found at ${adapterPath}`);
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
const mod = await import(adapterPath);
|
|
96
|
-
if (typeof mod.install !== "function") {
|
|
97
|
-
console.error(`sync-adapters: adapter ${name} has no install() export`);
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
mod.install({ pipelineSrc: PIPELINE_ROOT, target, platformFilter: args.platform });
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async function syncTarget(target) {
|
|
105
|
-
const absTarget = resolve(target);
|
|
106
|
-
if (!existsSync(absTarget)) {
|
|
107
|
-
console.error(`sync-adapters: target ${absTarget} does not exist`);
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
// Always-on first-time install signal: if the target is the pipeline
|
|
111
|
-
// repo itself (has pipeline/ + .git/), we ALWAYS install Cursor since
|
|
112
|
-
// the maintainer is the canonical cursor consumer.
|
|
113
|
-
const isPipelineRepo =
|
|
114
|
-
existsSync(join(absTarget, "pipeline")) && existsSync(join(absTarget, ".git"));
|
|
115
|
-
const adapters = detectAdapters(absTarget);
|
|
116
|
-
if (isPipelineRepo && !adapters.includes("cursor")) adapters.push("cursor");
|
|
117
|
-
if (adapters.length === 0) {
|
|
118
|
-
console.log(` [skip] ${absTarget} - no adapter markers (.cursor/.cursorrules/.copilot)`);
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
console.log(`→ ${absTarget}`);
|
|
122
|
-
for (const a of adapters) {
|
|
123
|
-
if (args.doctor) {
|
|
124
|
-
console.log(` [doctor] would run ${a} adapter`);
|
|
125
|
-
} else {
|
|
126
|
-
try {
|
|
127
|
-
await runAdapter(a, absTarget);
|
|
128
|
-
} catch (e) {
|
|
129
|
-
console.error(` [error] ${a}: ${e.message}`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// --- main ------------------------------------------------------------------
|
|
137
|
-
|
|
138
|
-
const targets = [];
|
|
139
|
-
if (args.all || args.doctor) {
|
|
140
|
-
const prefs = loadPrefs();
|
|
141
|
-
for (const entry of prefs.global?.projectsTouched ?? []) {
|
|
142
|
-
if (entry && entry.path) targets.push(entry.path);
|
|
143
|
-
}
|
|
144
|
-
if (targets.length === 0) {
|
|
145
|
-
console.log(
|
|
146
|
-
"sync-adapters: prefs.global.projectsTouched is empty - run multi-agent:setup in a project first",
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
if (args.target) targets.push(args.target);
|
|
151
|
-
|
|
152
|
-
let ok = 0;
|
|
153
|
-
let failed = 0;
|
|
154
|
-
for (const t of targets) {
|
|
155
|
-
if (await syncTarget(t)) ok++;
|
|
156
|
-
else failed++;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Codex CLI is a GLOBAL-config tool (prompts + MCP under ~/.codex, no per-project
|
|
160
|
-
// prompt dir), so it is synced once - not per target. Run it when Codex is
|
|
161
|
-
// present on this machine.
|
|
162
|
-
const codexHome = (() => {
|
|
163
|
-
const home = process.env.HOME || process.env.USERPROFILE;
|
|
164
|
-
return home ? join(home, ".codex") : null;
|
|
165
|
-
})();
|
|
166
|
-
if (codexHome && existsSync(codexHome)) {
|
|
167
|
-
if (args.doctor) {
|
|
168
|
-
console.log("→ ~/.codex (global)\n [doctor] would run codex adapter (global)");
|
|
169
|
-
} else {
|
|
170
|
-
console.log("→ ~/.codex (global)");
|
|
171
|
-
try {
|
|
172
|
-
const mod = await import(join(PIPELINE_ROOT, "adapters", "codex.mjs"));
|
|
173
|
-
mod.install({ pipelineSrc: PIPELINE_ROOT, platformFilter: args.platform });
|
|
174
|
-
ok++;
|
|
175
|
-
} catch (e) {
|
|
176
|
-
console.error(` [error] codex: ${e.message}`);
|
|
177
|
-
failed++;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
console.log(`sync-adapters: ${ok} ok · ${failed} failed`);
|
|
183
|
-
process.exit(failed > 0 ? 1 : 0);
|