@mmerterden/multi-agent-pipeline 16.1.1 → 16.1.2
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 +13 -0
- package/install/codex.mjs +13 -0
- package/install/copilot.mjs +19 -4
- package/package.json +1 -1
- package/pipeline/rules/outside-the-pipeline.md +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,19 @@ Internal file-layout changes that don't affect the slash-command surface are sti
|
|
|
16
16
|
|
|
17
17
|
## [Unreleased]
|
|
18
18
|
|
|
19
|
+
## [16.1.2] - 2026-08-23
|
|
20
|
+
|
|
21
|
+
The rule reached all three hosts in 16.1.1. It only WORKED on one.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **Rules were installed with a byte copy, so every path in them dangled on two hosts.** Each CLI keeps its trees under its own root, and both installers carry a path-rewrite table that names `rules` explicitly - but `installRules` (Copilot) and `installTree` (Codex) used a plain `copyDir`, so the rewrite never ran on that tree. Result: all 13 rules told a Copilot or Codex session to run `~/.claude/lib/credential-store.sh`, a tree those installs never create. This is the same dangling-path class the Copilot rewrite was written to eliminate for skills; rules were named in the doctrine and left out of the code. It bites hardest on the one rule whose entire job is resolving that path. Both installers route rules through `copyTreeRewritten` now: `~/.copilot/lib/...` on Copilot, `~/.codex/lib/...` on Codex, unchanged on Claude Code. Twelve pre-existing rules were fixed along with the new one.
|
|
26
|
+
- `outside-the-pipeline.md` says what to do when the refs tree is absent. Copilot installs no `multi-agent-refs/` by design - the doctrine routes those references to `~/.claude` when Claude Code shares the machine - so a Copilot-only install was being sent to a file that is not there with no explanation. The rule now states that the summary it carries IS the contract in that case.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- `smoke-context-budget.sh` asserts both installers put rules through the rewriter. Verified by reverting the Copilot fix and watching it go red. Shipping a rule to a host is not the same as shipping a rule that works there, and only the second one is worth the bytes it costs every session.
|
|
31
|
+
|
|
19
32
|
## [16.1.1] - 2026-08-23
|
|
20
33
|
|
|
21
34
|
Found by reviewing 16.1.0 after it shipped, and by the `/mcp` reconnect confirming the fix worked.
|
package/install/codex.mjs
CHANGED
|
@@ -493,6 +493,14 @@ function installScripts(pipelineSrc, dest, useSymlinks) {
|
|
|
493
493
|
* Copy a pipeline tree verbatim (lib / schemas). These are executed, not read
|
|
494
494
|
* as prose, and they resolve their own paths at runtime.
|
|
495
495
|
*/
|
|
496
|
+
// Trees whose text references `$HOME/.claude/...` and therefore have to be
|
|
497
|
+
// retargeted on the way in. The rewrite table already carries rules -> .codex
|
|
498
|
+
// rules, but `rules` was installed with a byte copy, so every rule naming
|
|
499
|
+
// `~/.claude/lib/credential-store.sh` pointed at a tree a Codex-only install
|
|
500
|
+
// never creates. `lib` and `schemas` are data the pipeline reads by absolute
|
|
501
|
+
// path from the caller's side, so they stay byte-identical.
|
|
502
|
+
const REWRITTEN_TREES = new Set(["rules"]);
|
|
503
|
+
|
|
496
504
|
function installTree(name, pipelineSrc, dest, useSymlinks) {
|
|
497
505
|
const src = join(pipelineSrc, name);
|
|
498
506
|
if (!existsSync(src)) return;
|
|
@@ -501,6 +509,11 @@ function installTree(name, pipelineSrc, dest, useSymlinks) {
|
|
|
501
509
|
ensureDir(dest);
|
|
502
510
|
}
|
|
503
511
|
wipeDir(dest);
|
|
512
|
+
if (!useSymlinks && REWRITTEN_TREES.has(name)) {
|
|
513
|
+
const n = copyTreeRewritten(src, dest);
|
|
514
|
+
console.log(` -> ${n} ${name} file(s) copied to ${dest} (paths retargeted)`);
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
504
517
|
copyDir(src, dest, { useSymlinks });
|
|
505
518
|
console.log(` -> ${countFiles(src)} ${name} file(s) copied to ${dest}`);
|
|
506
519
|
}
|
package/install/copilot.mjs
CHANGED
|
@@ -283,8 +283,20 @@ function installRules(pipelineSrc, dest, useSymlinks) {
|
|
|
283
283
|
if (!existsSync(rulesSrc)) return;
|
|
284
284
|
if (!useSymlinks) ensureRealDir(dest);
|
|
285
285
|
wipeDir(dest);
|
|
286
|
-
|
|
287
|
-
|
|
286
|
+
if (useSymlinks) {
|
|
287
|
+
copyDir(rulesSrc, dest, { useSymlinks });
|
|
288
|
+
console.log(` -> ${countFiles(rulesSrc)} files linked to ${dest}`);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
// Rewritten, not copied. COPILOT_PATH_REWRITES lists `rules` among the trees
|
|
292
|
+
// Copilot owns, but this function used plain copyDir - so every rule shipped
|
|
293
|
+
// here naming `~/.claude/lib/credential-store.sh` pointed at a tree a
|
|
294
|
+
// Copilot-only install never creates. The same dangling-path class the
|
|
295
|
+
// rewrite was introduced to kill for skills, still live in rules because
|
|
296
|
+
// rules never went through it. It matters most for the one rule whose whole
|
|
297
|
+
// job is resolving that path.
|
|
298
|
+
const n = copyTreeRewritten(rulesSrc, dest);
|
|
299
|
+
console.log(` -> ${n} files copied to ${dest} (paths retargeted)`);
|
|
288
300
|
}
|
|
289
301
|
|
|
290
302
|
function installSkills(opts) {
|
|
@@ -379,7 +391,8 @@ function installSkills(opts) {
|
|
|
379
391
|
let prevDelivered = null;
|
|
380
392
|
try {
|
|
381
393
|
const parsed = JSON.parse(readFileSync(join(dest, EXTERNAL_SKILLS_MANIFEST), "utf-8"));
|
|
382
|
-
if (Array.isArray(parsed))
|
|
394
|
+
if (Array.isArray(parsed))
|
|
395
|
+
prevDelivered = new Set(parsed.filter((n) => typeof n === "string"));
|
|
383
396
|
} catch {
|
|
384
397
|
prevDelivered = null;
|
|
385
398
|
}
|
|
@@ -421,7 +434,9 @@ function installSkills(opts) {
|
|
|
421
434
|
}
|
|
422
435
|
}
|
|
423
436
|
writeExternalSkillsManifest(dest, keep);
|
|
424
|
-
console.log(
|
|
437
|
+
console.log(
|
|
438
|
+
` -> stack filter (${selectionSource}): ${keep.length} kept, ${skipped.length} skipped`,
|
|
439
|
+
);
|
|
425
440
|
if (keptForeign > 0) {
|
|
426
441
|
console.log(
|
|
427
442
|
` note: ${keptForeign} skipped-stack dir(s) kept - not delivered by this pipeline (no manifest entry, differs from catalog)`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmerterden/multi-agent-pipeline",
|
|
3
|
-
"version": "16.1.
|
|
3
|
+
"version": "16.1.2",
|
|
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",
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
`/multi-agent` is not the only way to use what the install set up. Reach for
|
|
4
4
|
these when the work calls for it - not eagerly, and not by starting an 8-phase
|
|
5
5
|
run to read one ticket. Detail, commands and the safety contract:
|
|
6
|
-
`$HOME/.claude/multi-agent-refs/outside-the-pipeline.md
|
|
6
|
+
`$HOME/.claude/multi-agent-refs/outside-the-pipeline.md` - absent on a host that
|
|
7
|
+
installs no refs tree, in which case the summary below is the contract.
|
|
7
8
|
|
|
8
9
|
**Services.** Tokens onboarded by `/multi-agent:setup` are readable now. Logical
|
|
9
10
|
name in `prefs.global.keychainMapping`, value via
|