buddy-agent-harness 0.14.0 → 0.16.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/dist/cli.mjs +314 -58
- package/dist/index.d.mts +35 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +267 -12
- package/dist/index.mjs.map +1 -1
- package/dist/skill-scripts/doctor.mjs +18 -6
- package/dist/skill-scripts/init.mjs +18 -6
- package/dist/skill-scripts/mcp.mjs +18 -6
- package/dist/skill-scripts/reference.mjs +18 -6
- package/llms.txt +102 -0
- package/package.json +4 -1
- package/plugin.json +1 -1
- package/skills/doctor-buddy-agent-harness/SKILL.md +1 -1
- package/skills/doctor-buddy-agent-harness/scripts/doctor.mjs +18 -6
- package/skills/init-buddy-agent-harness/SKILL.md +1 -1
- package/skills/init-buddy-agent-harness/scripts/doctor.mjs +18 -6
- package/skills/init-buddy-agent-harness/scripts/init.mjs +18 -6
- package/skills/reference/README.md +2 -2
- package/skills/reference/SKILL.md +8 -3
- package/skills/reference/references/create.md +15 -4
- package/skills/reference/scripts/reference.mjs +18 -6
- package/skills/repair/SKILL.md +1 -1
- package/skills/repair/scripts/doctor.mjs +18 -6
- package/skills/repair/scripts/mcp.mjs +18 -6
- package/src/cli.ts +12 -11
- package/src/command-output/command-output.ts +1 -1
- package/src/governance-overrides/governance-overrides.ts +32 -4
- package/src/governance-overrides/governance.command.ts +3 -0
- package/src/references/create-reference.ts +57 -0
- package/src/references/reference-document.ts +7 -1
- package/src/references/reference-invocation.ts +1 -1
- package/src/references/reference.command.ts +245 -9
- package/src/references/resolve-reference.ts +2 -1
package/dist/cli.mjs
CHANGED
|
@@ -26942,6 +26942,11 @@ function stripMergeComments(body) {
|
|
|
26942
26942
|
const inFence = fenceTracker();
|
|
26943
26943
|
return body.split("\n").filter((line) => inFence(line) || !mergeCommentPattern.test(line)).join("\n");
|
|
26944
26944
|
}
|
|
26945
|
+
/** Each heading with a single `#` outside a code fence, as written. */
|
|
26946
|
+
function titleHeadings(body) {
|
|
26947
|
+
const inFence = fenceTracker();
|
|
26948
|
+
return body.split("\n").filter((line) => !inFence(line) && headingPattern.exec(line)?.[1] === "#");
|
|
26949
|
+
}
|
|
26945
26950
|
function sectionKey(title) {
|
|
26946
26951
|
return title.trim().replace(/\s+/g, " ").toLowerCase();
|
|
26947
26952
|
}
|
|
@@ -27118,6 +27123,7 @@ function pluginLabel(layer) {
|
|
|
27118
27123
|
function layerName(layer) {
|
|
27119
27124
|
return layer.tier === "plugin" ? `plugin ${pluginLabel(layer)}` : layer.tier;
|
|
27120
27125
|
}
|
|
27126
|
+
/** The layers a name is resolved through, in the order `resolveReference` traces them. */
|
|
27121
27127
|
function layersFor$2(ref, layers) {
|
|
27122
27128
|
const plugin = ref.plugin;
|
|
27123
27129
|
if (plugin === void 0) return [...layers];
|
|
@@ -27366,6 +27372,7 @@ function searchReferences(query, layers, options = {}) {
|
|
|
27366
27372
|
}
|
|
27367
27373
|
//#endregion
|
|
27368
27374
|
//#region src/governance-overrides/governance-overrides.ts
|
|
27375
|
+
/** @deprecated Use `managedReferencesDir`. Removed in the next major version. */
|
|
27369
27376
|
function managedGovernancesDir(platform, programData) {
|
|
27370
27377
|
if (platform === "darwin") return "/Library/Application Support/BuddyAgentHarness/governances";
|
|
27371
27378
|
if (platform === "win32") return join(programData || "C:\\ProgramData", "BuddyAgentHarness", "governances");
|
|
@@ -27374,6 +27381,8 @@ function managedGovernancesDir(platform, programData) {
|
|
|
27374
27381
|
/**
|
|
27375
27382
|
* Still read below the layer above, so a machine already using it keeps working; reported as
|
|
27376
27383
|
* deprecated so an admin knows to move it.
|
|
27384
|
+
*
|
|
27385
|
+
* @deprecated Use `managedReferencesDir`. Removed in the next major version.
|
|
27377
27386
|
*/
|
|
27378
27387
|
function deprecatedManagedGovernancesDir(platform, programData) {
|
|
27379
27388
|
if (platform === "darwin") return "/Library/Application Support/UniPlugin/governances";
|
|
@@ -27399,6 +27408,7 @@ function packageGovernancesDir(from = fileURLToPath(import.meta.url)) {
|
|
|
27399
27408
|
dir = parent;
|
|
27400
27409
|
}
|
|
27401
27410
|
}
|
|
27411
|
+
/** @deprecated Use `referenceLayers`. Removed in the next major version. */
|
|
27402
27412
|
function governanceLayers({ root, home, platform, programData }) {
|
|
27403
27413
|
return [
|
|
27404
27414
|
{
|
|
@@ -27426,6 +27436,8 @@ function governanceLayers({ root, home, platform, programData }) {
|
|
|
27426
27436
|
/**
|
|
27427
27437
|
* Filters by scope rather than slicing the list, so a layer added later can't quietly become an
|
|
27428
27438
|
* override by position.
|
|
27439
|
+
*
|
|
27440
|
+
* @deprecated Use `referenceLayers`. Removed in the next major version.
|
|
27429
27441
|
*/
|
|
27430
27442
|
function overrideLayers(layers) {
|
|
27431
27443
|
return layers.filter((layer) => layer.scope !== "package");
|
|
@@ -27434,6 +27446,8 @@ const namePattern = /^[a-z0-9]+(?:[-.][a-z0-9]+)*$/i;
|
|
|
27434
27446
|
/**
|
|
27435
27447
|
* Rejects rather than sanitizes — silently answering a different question is how untrusted input
|
|
27436
27448
|
* reads a file outside the layer.
|
|
27449
|
+
*
|
|
27450
|
+
* @deprecated Use `parseReferenceName`. Removed in the next major version.
|
|
27437
27451
|
*/
|
|
27438
27452
|
function parseGovernanceName(value) {
|
|
27439
27453
|
if (value.endsWith(".md")) throw new Error(`"${value}" names a file. Ask for the governance by name, without the .md extension.`);
|
|
@@ -27455,7 +27469,11 @@ function documentNames(dir) {
|
|
|
27455
27469
|
return [];
|
|
27456
27470
|
}
|
|
27457
27471
|
}
|
|
27458
|
-
/**
|
|
27472
|
+
/**
|
|
27473
|
+
* The first layer that holds the name wins; the rest are not read.
|
|
27474
|
+
*
|
|
27475
|
+
* @deprecated Use `resolveReference`. Removed in the next major version.
|
|
27476
|
+
*/
|
|
27459
27477
|
function resolveGovernance(name, layers) {
|
|
27460
27478
|
for (const { scope, dir } of layers) {
|
|
27461
27479
|
const path = join(dir, `${name}.md`);
|
|
@@ -27468,7 +27486,11 @@ function resolveGovernance(name, layers) {
|
|
|
27468
27486
|
};
|
|
27469
27487
|
}
|
|
27470
27488
|
}
|
|
27471
|
-
/**
|
|
27489
|
+
/**
|
|
27490
|
+
* Every name any layer holds, each reported at the layer that would win, sorted by name.
|
|
27491
|
+
*
|
|
27492
|
+
* @deprecated Use `listReferences`. Removed in the next major version.
|
|
27493
|
+
*/
|
|
27472
27494
|
function listGovernances(layers) {
|
|
27473
27495
|
const found = /* @__PURE__ */ new Map();
|
|
27474
27496
|
for (const { scope, dir } of layers) for (const name of documentNames(dir)) if (!found.has(name)) found.set(name, {
|
|
@@ -28354,6 +28376,7 @@ const overridesOnlyOption = {
|
|
|
28354
28376
|
description: "Resolve only the project, user, and machine-wide layers. Never returns a governance this package ships, and exits non-zero when no layer has one.",
|
|
28355
28377
|
type: optionalType(booleanType())
|
|
28356
28378
|
};
|
|
28379
|
+
/** @deprecated Use `referenceCommand`. Removed in the next major version. */
|
|
28357
28380
|
const governanceCommand = command({
|
|
28358
28381
|
name: "governance",
|
|
28359
28382
|
description: "Deprecated: use `reference`. Read the governance documents the project, user, and machine-wide override layers hold. Read-only.",
|
|
@@ -28437,6 +28460,54 @@ const governanceCommand = command({
|
|
|
28437
28460
|
})]
|
|
28438
28461
|
});
|
|
28439
28462
|
//#endregion
|
|
28463
|
+
//#region src/references/create-reference.ts
|
|
28464
|
+
/** No `#` title: `merge-sections` matches by heading path, so a title would hold every section under it. */
|
|
28465
|
+
const defaultTemplate = `---
|
|
28466
|
+
description: What this reference covers, and when an agent should read it.
|
|
28467
|
+
tags: [topic]
|
|
28468
|
+
---
|
|
28469
|
+
|
|
28470
|
+
## Overview
|
|
28471
|
+
|
|
28472
|
+
Write the guidance here. Give each topic its own top-level \`##\` section.
|
|
28473
|
+
`;
|
|
28474
|
+
function readTemplate(path) {
|
|
28475
|
+
if (path === void 0) return parseTemplate(defaultTemplate, "the default template");
|
|
28476
|
+
let content;
|
|
28477
|
+
try {
|
|
28478
|
+
content = readFileSync(path, "utf8");
|
|
28479
|
+
} catch (error) {
|
|
28480
|
+
throw new Error(`cannot read the template ${path}: ${error.message}`);
|
|
28481
|
+
}
|
|
28482
|
+
return parseTemplate(content, `the template ${path}`);
|
|
28483
|
+
}
|
|
28484
|
+
function parseTemplate(content, label) {
|
|
28485
|
+
let mapping = true;
|
|
28486
|
+
const { metadata, body } = parseDocument(content, () => {
|
|
28487
|
+
mapping = false;
|
|
28488
|
+
});
|
|
28489
|
+
if (!mapping) throw new Error(`${label} has frontmatter that is not a YAML mapping.`);
|
|
28490
|
+
return {
|
|
28491
|
+
content,
|
|
28492
|
+
metadata,
|
|
28493
|
+
body
|
|
28494
|
+
};
|
|
28495
|
+
}
|
|
28496
|
+
/** Adds one line and changes nothing else, so the result still reads as the template it came from. */
|
|
28497
|
+
function withMergeSections(content) {
|
|
28498
|
+
const match = frontmatterPattern.exec(content);
|
|
28499
|
+
if (!match) return `---\nmerge: merge-sections\n---\n\n${content}`;
|
|
28500
|
+
const open = match[0].indexOf("\n") + 1;
|
|
28501
|
+
const newline = match[0][open - 2] === "\r" ? "\r\n" : "\n";
|
|
28502
|
+
const end = open + match[1].length;
|
|
28503
|
+
return `${content.slice(0, end)}${newline}merge: merge-sections${content.slice(end)}`;
|
|
28504
|
+
}
|
|
28505
|
+
function templateWarnings({ metadata, body }) {
|
|
28506
|
+
const warnings = titleHeadings(body).map((heading) => `"${heading.trim()}" is a heading with one hash; merge-sections matches by heading path, so an override would replace or duplicate the whole document. Use top-level ## sections.`);
|
|
28507
|
+
if (typeof metadata["description"] !== "string" || !metadata["description"].trim()) warnings.push("the reference has no `description` in its frontmatter; `list` and `search` show it blank.");
|
|
28508
|
+
return warnings;
|
|
28509
|
+
}
|
|
28510
|
+
//#endregion
|
|
28440
28511
|
//#region src/references/reference.command.ts
|
|
28441
28512
|
const rootOption = {
|
|
28442
28513
|
description: "Directory the project tier is read from, and each folder above it up to the repository root. Defaults to the current directory.",
|
|
@@ -28455,6 +28526,12 @@ function fail(error, fallback) {
|
|
|
28455
28526
|
process.stderr.write(`error: ${error instanceof Error ? error.message : fallback}\n`);
|
|
28456
28527
|
return exitCodes.error;
|
|
28457
28528
|
}
|
|
28529
|
+
function traceOf(resolved, home) {
|
|
28530
|
+
return resolved.trace.map(({ description: _, ...step }) => ({
|
|
28531
|
+
...step,
|
|
28532
|
+
path: collapseHome(home, step.path)
|
|
28533
|
+
}));
|
|
28534
|
+
}
|
|
28458
28535
|
function showEntry(resolved, home, suggestions, trace) {
|
|
28459
28536
|
const entry = {
|
|
28460
28537
|
name: resolved.name,
|
|
@@ -28476,10 +28553,7 @@ function showEntry(resolved, home, suggestions, trace) {
|
|
|
28476
28553
|
if (resolved.status === "missing") entry.suggestions = suggestions;
|
|
28477
28554
|
if (resolved.status === "ambiguous") entry.plugins = resolved.plugins;
|
|
28478
28555
|
entry.warnings = resolved.warnings;
|
|
28479
|
-
if (trace) entry.trace = resolved
|
|
28480
|
-
...step,
|
|
28481
|
-
path: collapseHome(home, step.path)
|
|
28482
|
-
}));
|
|
28556
|
+
if (trace) entry.trace = traceOf(resolved, home);
|
|
28483
28557
|
return entry;
|
|
28484
28558
|
}
|
|
28485
28559
|
function missReason(entry) {
|
|
@@ -28551,70 +28625,238 @@ const listFormatOption = {
|
|
|
28551
28625
|
type: optionalType(stringType()),
|
|
28552
28626
|
default: "toon"
|
|
28553
28627
|
};
|
|
28628
|
+
const referenceListCommand = command({
|
|
28629
|
+
name: "list",
|
|
28630
|
+
description: "List every layer, and every reference at every layer that holds it, marked used or shadowed.",
|
|
28631
|
+
options: {
|
|
28632
|
+
root: rootOption,
|
|
28633
|
+
format: listFormatOption
|
|
28634
|
+
},
|
|
28635
|
+
async run(args) {
|
|
28636
|
+
try {
|
|
28637
|
+
const format = parseFormat(args.format);
|
|
28638
|
+
const home = homedir();
|
|
28639
|
+
const layers = await layersFor(args, home);
|
|
28640
|
+
const { rows, warnings } = listReferences(layers, { display: (path) => collapseHome(home, path) });
|
|
28641
|
+
const report = {
|
|
28642
|
+
layers: layers.map(({ tier, plugins, dir, status }) => ({
|
|
28643
|
+
tier,
|
|
28644
|
+
plugin: plugins[0] ?? "",
|
|
28645
|
+
path: collapseHome(home, dir),
|
|
28646
|
+
status
|
|
28647
|
+
})),
|
|
28648
|
+
references: rows.length ? rows.map((row) => ({
|
|
28649
|
+
...row,
|
|
28650
|
+
path: collapseHome(home, row.path)
|
|
28651
|
+
})) : "0 references — no layer holds one"
|
|
28652
|
+
};
|
|
28653
|
+
if (warnings.length) report.warnings = warnings;
|
|
28654
|
+
writeResult(report, format);
|
|
28655
|
+
return exitCodes.success;
|
|
28656
|
+
} catch (error) {
|
|
28657
|
+
return fail(error, "Reference listing failed.");
|
|
28658
|
+
}
|
|
28659
|
+
}
|
|
28660
|
+
});
|
|
28661
|
+
const referenceSearchCommand = command({
|
|
28662
|
+
name: "search",
|
|
28663
|
+
description: "Find references by name, description, tags, headings, or body, best match first.",
|
|
28664
|
+
arguments: [{
|
|
28665
|
+
name: "query",
|
|
28666
|
+
description: "What the reference is about.",
|
|
28667
|
+
type: stringType()
|
|
28668
|
+
}],
|
|
28669
|
+
options: {
|
|
28670
|
+
root: rootOption,
|
|
28671
|
+
format: listFormatOption
|
|
28672
|
+
},
|
|
28673
|
+
async run(args) {
|
|
28674
|
+
try {
|
|
28675
|
+
const format = parseFormat(args.format);
|
|
28676
|
+
const query = args.query.trim();
|
|
28677
|
+
if (!query) throw new Error("Search needs a query.");
|
|
28678
|
+
const home = homedir();
|
|
28679
|
+
const matches = searchReferences(query, await layersFor(args, home), { display: (path) => collapseHome(home, path) });
|
|
28680
|
+
writeResult({
|
|
28681
|
+
query,
|
|
28682
|
+
references: matches.length ? matches : `0 references match "${query}"`
|
|
28683
|
+
}, format);
|
|
28684
|
+
return exitCodes.success;
|
|
28685
|
+
} catch (error) {
|
|
28686
|
+
return fail(error, "Reference search failed.");
|
|
28687
|
+
}
|
|
28688
|
+
}
|
|
28689
|
+
});
|
|
28690
|
+
/** Managed is left out: writing there needs an admin, and most of it cannot be read locally. */
|
|
28691
|
+
const slotScopes = {
|
|
28692
|
+
project: "everyone working in this repository",
|
|
28693
|
+
user: "only you, in every repository",
|
|
28694
|
+
plugin: "read-only; override it with the project or user file"
|
|
28695
|
+
};
|
|
28696
|
+
const callerScope = "read-only; the calling skill's own copy, read only when no layer holds the name";
|
|
28697
|
+
const mergeNote = "The default, first-wins, makes the override replace the whole document. Set `merge: merge-sections` in its frontmatter to keep the sections it does not redefine.";
|
|
28698
|
+
function slotStatus(outcome) {
|
|
28699
|
+
if (outcome === "missing") return "empty";
|
|
28700
|
+
return outcome.startsWith("shadowed") ? "shadowed" : outcome;
|
|
28701
|
+
}
|
|
28702
|
+
/** Where Load reads the caller's copy when no layer holds the name, in the order it tries them. */
|
|
28703
|
+
function callerCopy(caller, name) {
|
|
28704
|
+
return [join(caller, "references", `${name}.md`), join(caller, "references", "governances", `${name}.md`)].find((path) => existsSync(path));
|
|
28705
|
+
}
|
|
28706
|
+
function callerStatus(resolved) {
|
|
28707
|
+
if (resolved.status === "missing") return "used";
|
|
28708
|
+
return resolved.status === "ambiguous" ? "not read — the name is ambiguous" : "shadowed";
|
|
28709
|
+
}
|
|
28710
|
+
const referenceWhereCommand = command({
|
|
28711
|
+
name: "where",
|
|
28712
|
+
description: "List the project and user files an override of a reference can be written to, highest precedence first, with the copy each overrides and who it applies to.",
|
|
28713
|
+
arguments: [{
|
|
28714
|
+
name: "name",
|
|
28715
|
+
description: "Reference name, without the `.md` extension; `<plugin>/<name>` picks one plugin.",
|
|
28716
|
+
type: stringType()
|
|
28717
|
+
}],
|
|
28718
|
+
options: {
|
|
28719
|
+
root: rootOption,
|
|
28720
|
+
caller: {
|
|
28721
|
+
description: "Folder of the skill that loads the reference, so its own copy is reported as the reference skill's Load mode reads it.",
|
|
28722
|
+
type: optionalType(stringType())
|
|
28723
|
+
},
|
|
28724
|
+
format: listFormatOption
|
|
28725
|
+
},
|
|
28726
|
+
async run(args) {
|
|
28727
|
+
try {
|
|
28728
|
+
const format = parseFormat(args.format);
|
|
28729
|
+
const name = parseReferenceName(args.name);
|
|
28730
|
+
const home = homedir();
|
|
28731
|
+
const layers = await layersFor(args, home);
|
|
28732
|
+
const root = resolve(args.root ?? process.cwd());
|
|
28733
|
+
const display = (path) => collapseHome(home, path);
|
|
28734
|
+
const resolved = resolveReference(name, layers, { display });
|
|
28735
|
+
const traced = layersFor$2(name, layers);
|
|
28736
|
+
const slots = [];
|
|
28737
|
+
for (const [index, step] of resolved.trace.entries()) {
|
|
28738
|
+
const layer = traced[index];
|
|
28739
|
+
const scope = slotScopes[step.tier];
|
|
28740
|
+
if (!scope || (layer.status || step.tier === "plugin") && !step.found) continue;
|
|
28741
|
+
const path = step.found ? step.path : join(layer.dir, `${name.name}.md`);
|
|
28742
|
+
slots.push({
|
|
28743
|
+
layer: step.tier === "plugin" ? `plugin ${step.plugin}` : step.tier,
|
|
28744
|
+
path: step.tier === "project" ? relative(root, path) : display(path),
|
|
28745
|
+
status: slotStatus(step.outcome),
|
|
28746
|
+
scope
|
|
28747
|
+
});
|
|
28748
|
+
}
|
|
28749
|
+
const copy = args.caller === void 0 ? void 0 : callerCopy(resolve(args.caller), name.name);
|
|
28750
|
+
if (copy) slots.push({
|
|
28751
|
+
layer: "caller",
|
|
28752
|
+
path: display(copy),
|
|
28753
|
+
status: callerStatus(resolved),
|
|
28754
|
+
scope: callerScope
|
|
28755
|
+
});
|
|
28756
|
+
const report = {
|
|
28757
|
+
name: name.name,
|
|
28758
|
+
root: display(root),
|
|
28759
|
+
slots,
|
|
28760
|
+
merge: mergeNote
|
|
28761
|
+
};
|
|
28762
|
+
if (resolved.status === "ambiguous") report.plugins = resolved.plugins;
|
|
28763
|
+
if (resolved.warnings.length) report.warnings = resolved.warnings;
|
|
28764
|
+
writeResult(report, format);
|
|
28765
|
+
if (resolved.status !== "ambiguous") return exitCodes.success;
|
|
28766
|
+
process.stderr.write(`error: ${missReason({
|
|
28767
|
+
name: name.raw,
|
|
28768
|
+
status: "ambiguous",
|
|
28769
|
+
plugins: resolved.plugins,
|
|
28770
|
+
warnings: []
|
|
28771
|
+
})}\n`);
|
|
28772
|
+
return exitCodes.error;
|
|
28773
|
+
} catch (error) {
|
|
28774
|
+
return fail(error, "Reference placement lookup failed.");
|
|
28775
|
+
}
|
|
28776
|
+
}
|
|
28777
|
+
});
|
|
28778
|
+
function parseScope(value) {
|
|
28779
|
+
if (value !== "project" && value !== "user") throw new Error("--scope must be project or user.");
|
|
28780
|
+
return value;
|
|
28781
|
+
}
|
|
28554
28782
|
const referenceCommand = command({
|
|
28555
28783
|
name: "reference",
|
|
28556
|
-
description: "Read on-demand reference documents by name, layered across the managed, project, user, and plugin tiers
|
|
28784
|
+
description: "Read on-demand reference documents by name, layered across the managed, project, user, and plugin tiers, and start a new one in the project or user tier.",
|
|
28557
28785
|
commands: [
|
|
28558
28786
|
referenceShowCommand,
|
|
28787
|
+
referenceListCommand,
|
|
28788
|
+
referenceSearchCommand,
|
|
28789
|
+
referenceWhereCommand,
|
|
28559
28790
|
command({
|
|
28560
|
-
name: "
|
|
28561
|
-
description: "
|
|
28562
|
-
options: {
|
|
28563
|
-
root: rootOption,
|
|
28564
|
-
format: listFormatOption
|
|
28565
|
-
},
|
|
28566
|
-
async run(args) {
|
|
28567
|
-
try {
|
|
28568
|
-
const format = parseFormat(args.format);
|
|
28569
|
-
const home = homedir();
|
|
28570
|
-
const layers = await layersFor(args, home);
|
|
28571
|
-
const { rows, warnings } = listReferences(layers, { display: (path) => collapseHome(home, path) });
|
|
28572
|
-
const report = {
|
|
28573
|
-
layers: layers.map(({ tier, plugins, dir, status }) => ({
|
|
28574
|
-
tier,
|
|
28575
|
-
plugin: plugins[0] ?? "",
|
|
28576
|
-
path: collapseHome(home, dir),
|
|
28577
|
-
status
|
|
28578
|
-
})),
|
|
28579
|
-
references: rows.length ? rows.map((row) => ({
|
|
28580
|
-
...row,
|
|
28581
|
-
path: collapseHome(home, row.path)
|
|
28582
|
-
})) : "0 references — no layer holds one"
|
|
28583
|
-
};
|
|
28584
|
-
if (warnings.length) report.warnings = warnings;
|
|
28585
|
-
writeResult(report, format);
|
|
28586
|
-
return exitCodes.success;
|
|
28587
|
-
} catch (error) {
|
|
28588
|
-
return fail(error, "Reference listing failed.");
|
|
28589
|
-
}
|
|
28590
|
-
}
|
|
28591
|
-
}),
|
|
28592
|
-
command({
|
|
28593
|
-
name: "search",
|
|
28594
|
-
description: "Find references by name, description, tags, headings, or body, best match first.",
|
|
28791
|
+
name: "create",
|
|
28792
|
+
description: "Start a new reference in the project or user tier from a template, marked merge-sections when it overrides a copy below. Never overwrites.",
|
|
28595
28793
|
arguments: [{
|
|
28596
|
-
name: "
|
|
28597
|
-
description: "
|
|
28794
|
+
name: "name",
|
|
28795
|
+
description: "Reference name, without the `.md` extension.",
|
|
28598
28796
|
type: stringType()
|
|
28599
28797
|
}],
|
|
28600
28798
|
options: {
|
|
28601
28799
|
root: rootOption,
|
|
28602
|
-
|
|
28800
|
+
template: {
|
|
28801
|
+
description: "File whose text is written as it is, frontmatter included. Defaults to a built-in template of top-level `##` sections with no `#` title.",
|
|
28802
|
+
type: optionalType(stringType())
|
|
28803
|
+
},
|
|
28804
|
+
scope: {
|
|
28805
|
+
description: "Tier to write: project (default), `.agents/references/` at the root, or user, `~/.agents/references/`.",
|
|
28806
|
+
type: optionalType(stringType()),
|
|
28807
|
+
default: "project"
|
|
28808
|
+
},
|
|
28809
|
+
"dry-run": {
|
|
28810
|
+
description: "Print the target path and the exact content, and write nothing.",
|
|
28811
|
+
type: optionalType(booleanType())
|
|
28812
|
+
},
|
|
28813
|
+
format: {
|
|
28814
|
+
description: "Output format: text (default) writes the path, then the content or the trace; toon and json return an object.",
|
|
28815
|
+
type: optionalType(stringType()),
|
|
28816
|
+
default: "text"
|
|
28817
|
+
}
|
|
28603
28818
|
},
|
|
28604
28819
|
async run(args) {
|
|
28605
28820
|
try {
|
|
28606
28821
|
const format = parseFormat(args.format);
|
|
28607
|
-
const
|
|
28608
|
-
if (
|
|
28822
|
+
const name = parseReferenceName(args.name);
|
|
28823
|
+
if (name.plugin !== void 0) throw new Error(`an override is written under the bare name, which every tier resolves; ask for "${name.name}".`);
|
|
28824
|
+
const scope = parseScope(args.scope);
|
|
28825
|
+
const template = readTemplate(args.template === void 0 ? void 0 : resolve(args.template));
|
|
28609
28826
|
const home = homedir();
|
|
28610
|
-
const
|
|
28611
|
-
|
|
28612
|
-
|
|
28613
|
-
|
|
28614
|
-
},
|
|
28827
|
+
const dir = scope === "project" ? projectReferencesDir(resolve(args.root ?? process.cwd())) : join(home, ".agents", "references");
|
|
28828
|
+
const target = join(dir, `${name.name}.md`);
|
|
28829
|
+
const display = (path) => collapseHome(home, path);
|
|
28830
|
+
const layers = await layersFor(args, home);
|
|
28831
|
+
const { trace } = resolveReference(name, layers, { display });
|
|
28832
|
+
const at = layers.findIndex((layer) => layer.dir === dir);
|
|
28833
|
+
if (trace[at]?.found) throw new Error(`${display(trace[at].path)} already holds "${name.name}"; change it with the reference skill's Update mode.`);
|
|
28834
|
+
const shadow = trace.slice(0, at).find((step) => step.found && step.merge === "first-wins");
|
|
28835
|
+
if (shadow) throw new Error(`the ${shadow.tier} copy ${display(shadow.path)} is first-wins, so nothing would read a new ${scope} file; change that copy instead.`);
|
|
28836
|
+
const content = trace.slice(at + 1).some((step) => step.found) && template.metadata["merge"] === void 0 ? withMergeSections(template.content) : template.content;
|
|
28837
|
+
const warnings = templateWarnings(template);
|
|
28838
|
+
const report = {
|
|
28839
|
+
name: name.name,
|
|
28840
|
+
scope,
|
|
28841
|
+
path: display(target),
|
|
28842
|
+
dryRun: Boolean(args["dry-run"]),
|
|
28843
|
+
content,
|
|
28844
|
+
warnings
|
|
28845
|
+
};
|
|
28846
|
+
if (!report.dryRun) {
|
|
28847
|
+
mkdirSync(dir, { recursive: true });
|
|
28848
|
+
writeFileSync(target, content, { flag: "wx" });
|
|
28849
|
+
report.trace = traceOf(resolveReference(name, layers, { display }), home);
|
|
28850
|
+
}
|
|
28851
|
+
if (format !== "text") writeResult(report, format);
|
|
28852
|
+
else {
|
|
28853
|
+
for (const warning of warnings) process.stderr.write(`warning: ${warning}\n`);
|
|
28854
|
+
if (report.trace) process.stdout.write(`${report.path}\n\n${renderText({ trace: report.trace })}\n`);
|
|
28855
|
+
else writeDocument(`${report.path}\n\n${content}`);
|
|
28856
|
+
}
|
|
28615
28857
|
return exitCodes.success;
|
|
28616
28858
|
} catch (error) {
|
|
28617
|
-
return fail(error, "Reference
|
|
28859
|
+
return fail(error, "Reference creation failed.");
|
|
28618
28860
|
}
|
|
28619
28861
|
}
|
|
28620
28862
|
})
|
|
@@ -31605,12 +31847,26 @@ const mcpCommand = command({
|
|
|
31605
31847
|
//#endregion
|
|
31606
31848
|
//#region src/cli.ts
|
|
31607
31849
|
const version = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
31850
|
+
/** Exported for `scripts/generate-llms-txt.ts`, which lists the CLI from it; `app()` must stay built from it. */
|
|
31851
|
+
const rootCommand = {
|
|
31852
|
+
name: "buddy-agent-harness",
|
|
31853
|
+
description: "Initialize agent harness skill compatibility in consumer repositories.",
|
|
31854
|
+
commands: [
|
|
31855
|
+
initCommand,
|
|
31856
|
+
doctorCommand,
|
|
31857
|
+
mcpCommand,
|
|
31858
|
+
depPluginsCommand,
|
|
31859
|
+
referenceCommand,
|
|
31860
|
+
governanceCommand
|
|
31861
|
+
]
|
|
31862
|
+
};
|
|
31608
31863
|
function app() {
|
|
31609
|
-
|
|
31610
|
-
|
|
31864
|
+
const [first, ...rest] = rootCommand.commands;
|
|
31865
|
+
return rest.reduce((builder, command) => builder.command(command), cli({
|
|
31866
|
+
name: rootCommand.name,
|
|
31611
31867
|
version,
|
|
31612
|
-
description:
|
|
31613
|
-
}).command(
|
|
31868
|
+
description: rootCommand.description
|
|
31869
|
+
}).command(first));
|
|
31614
31870
|
}
|
|
31615
31871
|
/**
|
|
31616
31872
|
* The application boundary: argv in, exit code out — returned rather than written, so a caller that
|
|
@@ -31626,4 +31882,4 @@ async function run(argv) {
|
|
|
31626
31882
|
}
|
|
31627
31883
|
}
|
|
31628
31884
|
//#endregion
|
|
31629
|
-
export { run };
|
|
31885
|
+
export { rootCommand, run };
|
package/dist/index.d.mts
CHANGED
|
@@ -487,22 +487,34 @@ export declare const goldenSetPath = ".agents/buddy-agent-harness/mcp.toml";
|
|
|
487
487
|
/**
|
|
488
488
|
* Order here is search order. `package` is the only member that isn't an override —
|
|
489
489
|
* `--overrides-only` promises never to return it.
|
|
490
|
+
*
|
|
491
|
+
* @deprecated Use `ReferenceTier`. Removed in the next major version.
|
|
490
492
|
*/
|
|
491
493
|
type GovernanceScope = "project" | "user" | "managed" | "managed-deprecated" | "package";
|
|
494
|
+
/** @deprecated Use `ReferenceLayer`. Removed in the next major version. */
|
|
492
495
|
type GovernanceLayer = {
|
|
493
496
|
scope: GovernanceScope;
|
|
494
497
|
dir: string;
|
|
495
498
|
};
|
|
496
|
-
/**
|
|
499
|
+
/**
|
|
500
|
+
* A governance located but not read: what `list` reports.
|
|
501
|
+
*
|
|
502
|
+
* @deprecated Use `ReferenceRow`. Removed in the next major version.
|
|
503
|
+
*/
|
|
497
504
|
type GovernanceEntry = {
|
|
498
505
|
name: string;
|
|
499
506
|
scope: GovernanceScope;
|
|
500
507
|
path: string;
|
|
501
508
|
};
|
|
502
|
-
/**
|
|
509
|
+
/**
|
|
510
|
+
* A governance located and read: what `show` reports.
|
|
511
|
+
*
|
|
512
|
+
* @deprecated Use `ResolvedReference`. Removed in the next major version.
|
|
513
|
+
*/
|
|
503
514
|
type GovernanceDocument = GovernanceEntry & {
|
|
504
515
|
content: string;
|
|
505
516
|
};
|
|
517
|
+
/** @deprecated Use `ReferenceLayerOptions`. Removed in the next major version. */
|
|
506
518
|
type LayerOptions = {
|
|
507
519
|
root: string;
|
|
508
520
|
home: string;
|
|
@@ -510,29 +522,46 @@ type LayerOptions = {
|
|
|
510
522
|
/** `%ProgramData%`, read only on Windows. */
|
|
511
523
|
programData?: string | undefined;
|
|
512
524
|
};
|
|
525
|
+
/** @deprecated Use `managedReferencesDir`. Removed in the next major version. */
|
|
513
526
|
export declare function managedGovernancesDir(platform: NodeJS.Platform, programData?: string | undefined): string;
|
|
514
527
|
/**
|
|
515
528
|
* Still read below the layer above, so a machine already using it keeps working; reported as
|
|
516
529
|
* deprecated so an admin knows to move it.
|
|
530
|
+
*
|
|
531
|
+
* @deprecated Use `managedReferencesDir`. Removed in the next major version.
|
|
517
532
|
*/
|
|
518
533
|
export declare function deprecatedManagedGovernancesDir(platform: NodeJS.Platform, programData?: string | undefined): string;
|
|
534
|
+
/** @deprecated Use `referenceLayers`. Removed in the next major version. */
|
|
519
535
|
export declare function governanceLayers({ root, home, platform, programData }: LayerOptions): GovernanceLayer[];
|
|
520
536
|
/**
|
|
521
537
|
* Filters by scope rather than slicing the list, so a layer added later can't quietly become an
|
|
522
538
|
* override by position.
|
|
539
|
+
*
|
|
540
|
+
* @deprecated Use `referenceLayers`. Removed in the next major version.
|
|
523
541
|
*/
|
|
524
542
|
export declare function overrideLayers(layers: readonly GovernanceLayer[]): GovernanceLayer[];
|
|
525
543
|
/**
|
|
526
544
|
* Rejects rather than sanitizes — silently answering a different question is how untrusted input
|
|
527
545
|
* reads a file outside the layer.
|
|
546
|
+
*
|
|
547
|
+
* @deprecated Use `parseReferenceName`. Removed in the next major version.
|
|
528
548
|
*/
|
|
529
549
|
export declare function parseGovernanceName(value: string): string;
|
|
530
|
-
/**
|
|
550
|
+
/**
|
|
551
|
+
* The first layer that holds the name wins; the rest are not read.
|
|
552
|
+
*
|
|
553
|
+
* @deprecated Use `resolveReference`. Removed in the next major version.
|
|
554
|
+
*/
|
|
531
555
|
export declare function resolveGovernance(name: string, layers: readonly GovernanceLayer[]): GovernanceDocument | undefined;
|
|
532
|
-
/**
|
|
556
|
+
/**
|
|
557
|
+
* Every name any layer holds, each reported at the layer that would win, sorted by name.
|
|
558
|
+
*
|
|
559
|
+
* @deprecated Use `listReferences`. Removed in the next major version.
|
|
560
|
+
*/
|
|
533
561
|
export declare function listGovernances(layers: readonly GovernanceLayer[]): GovernanceEntry[];
|
|
534
562
|
//#endregion
|
|
535
563
|
//#region src/governance-overrides/governance.command.d.ts
|
|
564
|
+
/** @deprecated Use `ReferenceListReport`. Removed in the next major version. */
|
|
536
565
|
type GovernanceListReport = {
|
|
537
566
|
/**
|
|
538
567
|
* `status` is always a string, not optional — an optional key would drop this array out of
|
|
@@ -550,12 +579,14 @@ type GovernanceListReport = {
|
|
|
550
579
|
path: string;
|
|
551
580
|
}[] | string;
|
|
552
581
|
};
|
|
582
|
+
/** @deprecated Use `ReferenceShowEntry`. Removed in the next major version. */
|
|
553
583
|
type GovernanceShowReport = {
|
|
554
584
|
name: string;
|
|
555
585
|
scope: GovernanceScope;
|
|
556
586
|
path: string;
|
|
557
587
|
content: string;
|
|
558
588
|
};
|
|
589
|
+
/** @deprecated Use `referenceCommand`. Removed in the next major version. */
|
|
559
590
|
export declare const governanceCommand: cli$1.Command;
|
|
560
591
|
//#endregion
|
|
561
592
|
//#region src/initialize-harnesses/init.command.d.ts
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/cli.ts","../src/harness-registry/instruction-bridge.ts","../src/diagnose-mcp/mcp-model.ts","../src/mcp-dialects/mcp-dialects.ts","../src/harness-registry/mcp-config.ts","../src/harness-registry/nonstandard-artifact.ts","../src/harness-registry/harness-registry.ts","../src/diagnose-bridges/diagnose-instructions.ts","../src/diagnose-bridges/locator.ts","../src/diagnose-bridges/doctor-guidance.ts","../src/diagnose-bridges/git-bridge-state.ts","../src/diagnose-bridges/diagnose-bridges.ts","../src/diagnose-configuration/diagnose-configuration.ts","../src/references/reference-layers.ts","../src/references/reference-document.ts","../src/references/resolve-reference.ts","../src/references/reference-catalog.ts","../src/diagnose-bridges/doctor.command.ts","../src/diagnose-mcp/diagnose-mcp.ts","../src/diagnose-mcp/mcp-baseline.ts","../src/diagnose-mcp/mcp-sources.ts","../src/governance-overrides/governance-overrides.ts","../src/governance-overrides/governance.command.ts","../src/initialize-harnesses/init.command.ts","../src/skill-projection/skill-projection.ts","../src/initialize-harnesses/initialize-harnesses.ts","../src/mcp-inventory/mcp-inventory.ts","../src/references/reference.command.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/cli.ts","../src/harness-registry/instruction-bridge.ts","../src/diagnose-mcp/mcp-model.ts","../src/mcp-dialects/mcp-dialects.ts","../src/harness-registry/mcp-config.ts","../src/harness-registry/nonstandard-artifact.ts","../src/harness-registry/harness-registry.ts","../src/diagnose-bridges/diagnose-instructions.ts","../src/diagnose-bridges/locator.ts","../src/diagnose-bridges/doctor-guidance.ts","../src/diagnose-bridges/git-bridge-state.ts","../src/diagnose-bridges/diagnose-bridges.ts","../src/diagnose-configuration/diagnose-configuration.ts","../src/references/reference-layers.ts","../src/references/reference-document.ts","../src/references/resolve-reference.ts","../src/references/reference-catalog.ts","../src/diagnose-bridges/doctor.command.ts","../src/diagnose-mcp/diagnose-mcp.ts","../src/diagnose-mcp/mcp-baseline.ts","../src/diagnose-mcp/mcp-sources.ts","../src/governance-overrides/governance-overrides.ts","../src/governance-overrides/governance.command.ts","../src/initialize-harnesses/init.command.ts","../src/skill-projection/skill-projection.ts","../src/initialize-harnesses/initialize-harnesses.ts","../src/mcp-inventory/mcp-inventory.ts","../src/references/reference.command.ts"],"mappings":"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"}
|