buddy-agent-harness 0.13.1 → 0.15.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 +155 -50
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +109 -5
- package/dist/index.mjs.map +1 -1
- package/dist/skill-scripts/doctor.mjs +4 -4
- package/dist/skill-scripts/init.mjs +4 -4
- package/dist/skill-scripts/mcp.mjs +4 -4
- package/dist/skill-scripts/reference.mjs +4 -4
- package/llms.txt +101 -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 +4 -4
- package/skills/init-buddy-agent-harness/SKILL.md +1 -1
- package/skills/init-buddy-agent-harness/scripts/doctor.mjs +4 -4
- package/skills/init-buddy-agent-harness/scripts/init.mjs +4 -4
- package/skills/reference/README.md +53 -0
- package/skills/reference/SKILL.md +80 -0
- package/skills/reference/references/create.md +56 -0
- package/skills/{load-reference/SKILL.md → reference/references/load.md} +2 -7
- package/skills/{load-reference → reference}/scripts/reference.mjs +4 -4
- package/skills/repair/SKILL.md +1 -1
- package/skills/repair/scripts/doctor.mjs +4 -4
- package/skills/repair/scripts/mcp.mjs +4 -4
- package/src/cli.ts +12 -11
- package/src/command-output/command-output.ts +1 -1
- package/src/references/{load-reference-invocation.ts → reference-invocation.ts} +4 -4
- package/src/references/reference.command.ts +116 -2
- package/src/references/resolve-reference.ts +2 -1
- package/src/skill-scripts/launchers.ts +1 -1
- package/skills/load-reference/README.md +0 -33
package/dist/cli.mjs
CHANGED
|
@@ -27118,6 +27118,7 @@ function pluginLabel(layer) {
|
|
|
27118
27118
|
function layerName(layer) {
|
|
27119
27119
|
return layer.tier === "plugin" ? `plugin ${pluginLabel(layer)}` : layer.tier;
|
|
27120
27120
|
}
|
|
27121
|
+
/** The layers a name is resolved through, in the order `resolveReference` traces them. */
|
|
27121
27122
|
function layersFor$2(ref, layers) {
|
|
27122
27123
|
const plugin = ref.plugin;
|
|
27123
27124
|
if (plugin === void 0) return [...layers];
|
|
@@ -28551,70 +28552,160 @@ const listFormatOption = {
|
|
|
28551
28552
|
type: optionalType(stringType()),
|
|
28552
28553
|
default: "toon"
|
|
28553
28554
|
};
|
|
28555
|
+
const referenceListCommand = command({
|
|
28556
|
+
name: "list",
|
|
28557
|
+
description: "List every layer, and every reference at every layer that holds it, marked used or shadowed.",
|
|
28558
|
+
options: {
|
|
28559
|
+
root: rootOption,
|
|
28560
|
+
format: listFormatOption
|
|
28561
|
+
},
|
|
28562
|
+
async run(args) {
|
|
28563
|
+
try {
|
|
28564
|
+
const format = parseFormat(args.format);
|
|
28565
|
+
const home = homedir();
|
|
28566
|
+
const layers = await layersFor(args, home);
|
|
28567
|
+
const { rows, warnings } = listReferences(layers, { display: (path) => collapseHome(home, path) });
|
|
28568
|
+
const report = {
|
|
28569
|
+
layers: layers.map(({ tier, plugins, dir, status }) => ({
|
|
28570
|
+
tier,
|
|
28571
|
+
plugin: plugins[0] ?? "",
|
|
28572
|
+
path: collapseHome(home, dir),
|
|
28573
|
+
status
|
|
28574
|
+
})),
|
|
28575
|
+
references: rows.length ? rows.map((row) => ({
|
|
28576
|
+
...row,
|
|
28577
|
+
path: collapseHome(home, row.path)
|
|
28578
|
+
})) : "0 references — no layer holds one"
|
|
28579
|
+
};
|
|
28580
|
+
if (warnings.length) report.warnings = warnings;
|
|
28581
|
+
writeResult(report, format);
|
|
28582
|
+
return exitCodes.success;
|
|
28583
|
+
} catch (error) {
|
|
28584
|
+
return fail(error, "Reference listing failed.");
|
|
28585
|
+
}
|
|
28586
|
+
}
|
|
28587
|
+
});
|
|
28588
|
+
const referenceSearchCommand = command({
|
|
28589
|
+
name: "search",
|
|
28590
|
+
description: "Find references by name, description, tags, headings, or body, best match first.",
|
|
28591
|
+
arguments: [{
|
|
28592
|
+
name: "query",
|
|
28593
|
+
description: "What the reference is about.",
|
|
28594
|
+
type: stringType()
|
|
28595
|
+
}],
|
|
28596
|
+
options: {
|
|
28597
|
+
root: rootOption,
|
|
28598
|
+
format: listFormatOption
|
|
28599
|
+
},
|
|
28600
|
+
async run(args) {
|
|
28601
|
+
try {
|
|
28602
|
+
const format = parseFormat(args.format);
|
|
28603
|
+
const query = args.query.trim();
|
|
28604
|
+
if (!query) throw new Error("Search needs a query.");
|
|
28605
|
+
const home = homedir();
|
|
28606
|
+
const matches = searchReferences(query, await layersFor(args, home), { display: (path) => collapseHome(home, path) });
|
|
28607
|
+
writeResult({
|
|
28608
|
+
query,
|
|
28609
|
+
references: matches.length ? matches : `0 references match "${query}"`
|
|
28610
|
+
}, format);
|
|
28611
|
+
return exitCodes.success;
|
|
28612
|
+
} catch (error) {
|
|
28613
|
+
return fail(error, "Reference search failed.");
|
|
28614
|
+
}
|
|
28615
|
+
}
|
|
28616
|
+
});
|
|
28617
|
+
/** Managed is left out: writing there needs an admin, and most of it cannot be read locally. */
|
|
28618
|
+
const slotScopes = {
|
|
28619
|
+
project: "everyone working in this repository",
|
|
28620
|
+
user: "only you, in every repository",
|
|
28621
|
+
plugin: "read-only; override it with the project or user file"
|
|
28622
|
+
};
|
|
28623
|
+
const callerScope = "read-only; the calling skill's own copy, read only when no layer holds the name";
|
|
28624
|
+
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.";
|
|
28625
|
+
function slotStatus(outcome) {
|
|
28626
|
+
if (outcome === "missing") return "empty";
|
|
28627
|
+
return outcome.startsWith("shadowed") ? "shadowed" : outcome;
|
|
28628
|
+
}
|
|
28629
|
+
/** Where Load reads the caller's copy when no layer holds the name, in the order it tries them. */
|
|
28630
|
+
function callerCopy(caller, name) {
|
|
28631
|
+
return [join(caller, "references", `${name}.md`), join(caller, "references", "governances", `${name}.md`)].find((path) => existsSync(path));
|
|
28632
|
+
}
|
|
28633
|
+
function callerStatus(resolved) {
|
|
28634
|
+
if (resolved.status === "missing") return "used";
|
|
28635
|
+
return resolved.status === "ambiguous" ? "not read — the name is ambiguous" : "shadowed";
|
|
28636
|
+
}
|
|
28554
28637
|
const referenceCommand = command({
|
|
28555
28638
|
name: "reference",
|
|
28556
28639
|
description: "Read on-demand reference documents by name, layered across the managed, project, user, and plugin tiers. Read-only.",
|
|
28557
28640
|
commands: [
|
|
28558
28641
|
referenceShowCommand,
|
|
28642
|
+
referenceListCommand,
|
|
28643
|
+
referenceSearchCommand,
|
|
28559
28644
|
command({
|
|
28560
|
-
name: "
|
|
28561
|
-
description: "List
|
|
28645
|
+
name: "where",
|
|
28646
|
+
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.",
|
|
28647
|
+
arguments: [{
|
|
28648
|
+
name: "name",
|
|
28649
|
+
description: "Reference name, without the `.md` extension; `<plugin>/<name>` picks one plugin.",
|
|
28650
|
+
type: stringType()
|
|
28651
|
+
}],
|
|
28562
28652
|
options: {
|
|
28563
28653
|
root: rootOption,
|
|
28654
|
+
caller: {
|
|
28655
|
+
description: "Folder of the skill that loads the reference, so its own copy is reported as the reference skill's Load mode reads it.",
|
|
28656
|
+
type: optionalType(stringType())
|
|
28657
|
+
},
|
|
28564
28658
|
format: listFormatOption
|
|
28565
28659
|
},
|
|
28566
28660
|
async run(args) {
|
|
28567
28661
|
try {
|
|
28568
28662
|
const format = parseFormat(args.format);
|
|
28663
|
+
const name = parseReferenceName(args.name);
|
|
28569
28664
|
const home = homedir();
|
|
28570
28665
|
const layers = await layersFor(args, home);
|
|
28571
|
-
const
|
|
28666
|
+
const root = resolve(args.root ?? process.cwd());
|
|
28667
|
+
const display = (path) => collapseHome(home, path);
|
|
28668
|
+
const resolved = resolveReference(name, layers, { display });
|
|
28669
|
+
const traced = layersFor$2(name, layers);
|
|
28670
|
+
const slots = [];
|
|
28671
|
+
for (const [index, step] of resolved.trace.entries()) {
|
|
28672
|
+
const layer = traced[index];
|
|
28673
|
+
const scope = slotScopes[step.tier];
|
|
28674
|
+
if (!scope || (layer.status || step.tier === "plugin") && !step.found) continue;
|
|
28675
|
+
const path = step.found ? step.path : join(layer.dir, `${name.name}.md`);
|
|
28676
|
+
slots.push({
|
|
28677
|
+
layer: step.tier === "plugin" ? `plugin ${step.plugin}` : step.tier,
|
|
28678
|
+
path: step.tier === "project" ? relative(root, path) : display(path),
|
|
28679
|
+
status: slotStatus(step.outcome),
|
|
28680
|
+
scope
|
|
28681
|
+
});
|
|
28682
|
+
}
|
|
28683
|
+
const copy = args.caller === void 0 ? void 0 : callerCopy(resolve(args.caller), name.name);
|
|
28684
|
+
if (copy) slots.push({
|
|
28685
|
+
layer: "caller",
|
|
28686
|
+
path: display(copy),
|
|
28687
|
+
status: callerStatus(resolved),
|
|
28688
|
+
scope: callerScope
|
|
28689
|
+
});
|
|
28572
28690
|
const report = {
|
|
28573
|
-
|
|
28574
|
-
|
|
28575
|
-
|
|
28576
|
-
|
|
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"
|
|
28691
|
+
name: name.name,
|
|
28692
|
+
root: display(root),
|
|
28693
|
+
slots,
|
|
28694
|
+
merge: mergeNote
|
|
28583
28695
|
};
|
|
28584
|
-
if (
|
|
28696
|
+
if (resolved.status === "ambiguous") report.plugins = resolved.plugins;
|
|
28697
|
+
if (resolved.warnings.length) report.warnings = resolved.warnings;
|
|
28585
28698
|
writeResult(report, format);
|
|
28586
|
-
return exitCodes.success;
|
|
28587
|
-
|
|
28588
|
-
|
|
28589
|
-
|
|
28590
|
-
|
|
28591
|
-
|
|
28592
|
-
|
|
28593
|
-
|
|
28594
|
-
description: "Find references by name, description, tags, headings, or body, best match first.",
|
|
28595
|
-
arguments: [{
|
|
28596
|
-
name: "query",
|
|
28597
|
-
description: "What the reference is about.",
|
|
28598
|
-
type: stringType()
|
|
28599
|
-
}],
|
|
28600
|
-
options: {
|
|
28601
|
-
root: rootOption,
|
|
28602
|
-
format: listFormatOption
|
|
28603
|
-
},
|
|
28604
|
-
async run(args) {
|
|
28605
|
-
try {
|
|
28606
|
-
const format = parseFormat(args.format);
|
|
28607
|
-
const query = args.query.trim();
|
|
28608
|
-
if (!query) throw new Error("Search needs a query.");
|
|
28609
|
-
const home = homedir();
|
|
28610
|
-
const matches = searchReferences(query, await layersFor(args, home), { display: (path) => collapseHome(home, path) });
|
|
28611
|
-
writeResult({
|
|
28612
|
-
query,
|
|
28613
|
-
references: matches.length ? matches : `0 references match "${query}"`
|
|
28614
|
-
}, format);
|
|
28615
|
-
return exitCodes.success;
|
|
28699
|
+
if (resolved.status !== "ambiguous") return exitCodes.success;
|
|
28700
|
+
process.stderr.write(`error: ${missReason({
|
|
28701
|
+
name: name.raw,
|
|
28702
|
+
status: "ambiguous",
|
|
28703
|
+
plugins: resolved.plugins,
|
|
28704
|
+
warnings: []
|
|
28705
|
+
})}\n`);
|
|
28706
|
+
return exitCodes.error;
|
|
28616
28707
|
} catch (error) {
|
|
28617
|
-
return fail(error, "Reference
|
|
28708
|
+
return fail(error, "Reference placement lookup failed.");
|
|
28618
28709
|
}
|
|
28619
28710
|
}
|
|
28620
28711
|
})
|
|
@@ -31605,12 +31696,26 @@ const mcpCommand = command({
|
|
|
31605
31696
|
//#endregion
|
|
31606
31697
|
//#region src/cli.ts
|
|
31607
31698
|
const version = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
31699
|
+
/** Exported for `scripts/generate-llms-txt.ts`, which lists the CLI from it; `app()` must stay built from it. */
|
|
31700
|
+
const rootCommand = {
|
|
31701
|
+
name: "buddy-agent-harness",
|
|
31702
|
+
description: "Initialize agent harness skill compatibility in consumer repositories.",
|
|
31703
|
+
commands: [
|
|
31704
|
+
initCommand,
|
|
31705
|
+
doctorCommand,
|
|
31706
|
+
mcpCommand,
|
|
31707
|
+
depPluginsCommand,
|
|
31708
|
+
referenceCommand,
|
|
31709
|
+
governanceCommand
|
|
31710
|
+
]
|
|
31711
|
+
};
|
|
31608
31712
|
function app() {
|
|
31609
|
-
|
|
31610
|
-
|
|
31713
|
+
const [first, ...rest] = rootCommand.commands;
|
|
31714
|
+
return rest.reduce((builder, command) => builder.command(command), cli({
|
|
31715
|
+
name: rootCommand.name,
|
|
31611
31716
|
version,
|
|
31612
|
-
description:
|
|
31613
|
-
}).command(
|
|
31717
|
+
description: rootCommand.description
|
|
31718
|
+
}).command(first));
|
|
31614
31719
|
}
|
|
31615
31720
|
/**
|
|
31616
31721
|
* The application boundary: argv in, exit code out — returned rather than written, so a caller that
|
|
@@ -31626,4 +31731,4 @@ async function run(argv) {
|
|
|
31626
31731
|
}
|
|
31627
31732
|
}
|
|
31628
31733
|
//#endregion
|
|
31629
|
-
export { run };
|
|
31734
|
+
export { rootCommand, run };
|
package/dist/index.d.mts
CHANGED
|
@@ -651,7 +651,7 @@ type ListMcpServersOptions = {
|
|
|
651
651
|
export declare function listMcpServers(options: ListMcpServersOptions): McpServerEntry[];
|
|
652
652
|
//#endregion
|
|
653
653
|
//#region src/references/reference.command.d.ts
|
|
654
|
-
/** One per name asked, in the order asked — the contract the `
|
|
654
|
+
/** One per name asked, in the order asked — the contract the `reference` skill's Load mode builds on. */
|
|
655
655
|
type ReferenceShowEntry = {
|
|
656
656
|
name: string;
|
|
657
657
|
status: ResolvedReference["status"];
|
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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"}
|
package/dist/index.mjs
CHANGED
|
@@ -2264,6 +2264,7 @@ function pluginLabel(layer) {
|
|
|
2264
2264
|
function layerName(layer) {
|
|
2265
2265
|
return layer.tier === "plugin" ? `plugin ${pluginLabel(layer)}` : layer.tier;
|
|
2266
2266
|
}
|
|
2267
|
+
/** The layers a name is resolved through, in the order `resolveReference` traces them. */
|
|
2267
2268
|
function layersFor$2(ref, layers) {
|
|
2268
2269
|
const plugin = ref.plugin;
|
|
2269
2270
|
if (plugin === void 0) return [...layers];
|
|
@@ -3761,13 +3762,102 @@ const referenceSearchCommand = command({
|
|
|
3761
3762
|
}
|
|
3762
3763
|
}
|
|
3763
3764
|
});
|
|
3765
|
+
/** Managed is left out: writing there needs an admin, and most of it cannot be read locally. */
|
|
3766
|
+
const slotScopes = {
|
|
3767
|
+
project: "everyone working in this repository",
|
|
3768
|
+
user: "only you, in every repository",
|
|
3769
|
+
plugin: "read-only; override it with the project or user file"
|
|
3770
|
+
};
|
|
3771
|
+
const callerScope = "read-only; the calling skill's own copy, read only when no layer holds the name";
|
|
3772
|
+
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.";
|
|
3773
|
+
function slotStatus(outcome) {
|
|
3774
|
+
if (outcome === "missing") return "empty";
|
|
3775
|
+
return outcome.startsWith("shadowed") ? "shadowed" : outcome;
|
|
3776
|
+
}
|
|
3777
|
+
/** Where Load reads the caller's copy when no layer holds the name, in the order it tries them. */
|
|
3778
|
+
function callerCopy(caller, name) {
|
|
3779
|
+
return [join(caller, "references", `${name}.md`), join(caller, "references", "governances", `${name}.md`)].find((path) => existsSync(path));
|
|
3780
|
+
}
|
|
3781
|
+
function callerStatus(resolved) {
|
|
3782
|
+
if (resolved.status === "missing") return "used";
|
|
3783
|
+
return resolved.status === "ambiguous" ? "not read — the name is ambiguous" : "shadowed";
|
|
3784
|
+
}
|
|
3785
|
+
const referenceWhereCommand = command({
|
|
3786
|
+
name: "where",
|
|
3787
|
+
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.",
|
|
3788
|
+
arguments: [{
|
|
3789
|
+
name: "name",
|
|
3790
|
+
description: "Reference name, without the `.md` extension; `<plugin>/<name>` picks one plugin.",
|
|
3791
|
+
type: z.string()
|
|
3792
|
+
}],
|
|
3793
|
+
options: {
|
|
3794
|
+
root: rootOption,
|
|
3795
|
+
caller: {
|
|
3796
|
+
description: "Folder of the skill that loads the reference, so its own copy is reported as the reference skill's Load mode reads it.",
|
|
3797
|
+
type: z.optional(z.string())
|
|
3798
|
+
},
|
|
3799
|
+
format: listFormatOption
|
|
3800
|
+
},
|
|
3801
|
+
async run(args) {
|
|
3802
|
+
try {
|
|
3803
|
+
const format = parseFormat(args.format);
|
|
3804
|
+
const name = parseReferenceName(args.name);
|
|
3805
|
+
const home = homedir();
|
|
3806
|
+
const layers = await layersFor(args, home);
|
|
3807
|
+
const root = resolve(args.root ?? process.cwd());
|
|
3808
|
+
const display = (path) => collapseHome(home, path);
|
|
3809
|
+
const resolved = resolveReference(name, layers, { display });
|
|
3810
|
+
const traced = layersFor$2(name, layers);
|
|
3811
|
+
const slots = [];
|
|
3812
|
+
for (const [index, step] of resolved.trace.entries()) {
|
|
3813
|
+
const layer = traced[index];
|
|
3814
|
+
const scope = slotScopes[step.tier];
|
|
3815
|
+
if (!scope || (layer.status || step.tier === "plugin") && !step.found) continue;
|
|
3816
|
+
const path = step.found ? step.path : join(layer.dir, `${name.name}.md`);
|
|
3817
|
+
slots.push({
|
|
3818
|
+
layer: step.tier === "plugin" ? `plugin ${step.plugin}` : step.tier,
|
|
3819
|
+
path: step.tier === "project" ? relative(root, path) : display(path),
|
|
3820
|
+
status: slotStatus(step.outcome),
|
|
3821
|
+
scope
|
|
3822
|
+
});
|
|
3823
|
+
}
|
|
3824
|
+
const copy = args.caller === void 0 ? void 0 : callerCopy(resolve(args.caller), name.name);
|
|
3825
|
+
if (copy) slots.push({
|
|
3826
|
+
layer: "caller",
|
|
3827
|
+
path: display(copy),
|
|
3828
|
+
status: callerStatus(resolved),
|
|
3829
|
+
scope: callerScope
|
|
3830
|
+
});
|
|
3831
|
+
const report = {
|
|
3832
|
+
name: name.name,
|
|
3833
|
+
root: display(root),
|
|
3834
|
+
slots,
|
|
3835
|
+
merge: mergeNote
|
|
3836
|
+
};
|
|
3837
|
+
if (resolved.status === "ambiguous") report.plugins = resolved.plugins;
|
|
3838
|
+
if (resolved.warnings.length) report.warnings = resolved.warnings;
|
|
3839
|
+
writeResult(report, format);
|
|
3840
|
+
if (resolved.status !== "ambiguous") return exitCodes.success;
|
|
3841
|
+
process.stderr.write(`error: ${missReason({
|
|
3842
|
+
name: name.raw,
|
|
3843
|
+
status: "ambiguous",
|
|
3844
|
+
plugins: resolved.plugins,
|
|
3845
|
+
warnings: []
|
|
3846
|
+
})}\n`);
|
|
3847
|
+
return exitCodes.error;
|
|
3848
|
+
} catch (error) {
|
|
3849
|
+
return fail(error, "Reference placement lookup failed.");
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
});
|
|
3764
3853
|
const referenceCommand = command({
|
|
3765
3854
|
name: "reference",
|
|
3766
3855
|
description: "Read on-demand reference documents by name, layered across the managed, project, user, and plugin tiers. Read-only.",
|
|
3767
3856
|
commands: [
|
|
3768
3857
|
referenceShowCommand,
|
|
3769
3858
|
referenceListCommand,
|
|
3770
|
-
referenceSearchCommand
|
|
3859
|
+
referenceSearchCommand,
|
|
3860
|
+
referenceWhereCommand
|
|
3771
3861
|
]
|
|
3772
3862
|
});
|
|
3773
3863
|
//#endregion
|
|
@@ -4638,12 +4728,26 @@ const mcpCommand = command({
|
|
|
4638
4728
|
//#endregion
|
|
4639
4729
|
//#region src/cli.ts
|
|
4640
4730
|
const version = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
4731
|
+
/** Exported for `scripts/generate-llms-txt.ts`, which lists the CLI from it; `app()` must stay built from it. */
|
|
4732
|
+
const rootCommand = {
|
|
4733
|
+
name: "buddy-agent-harness",
|
|
4734
|
+
description: "Initialize agent harness skill compatibility in consumer repositories.",
|
|
4735
|
+
commands: [
|
|
4736
|
+
initCommand,
|
|
4737
|
+
doctorCommand,
|
|
4738
|
+
mcpCommand,
|
|
4739
|
+
depPluginsCommand,
|
|
4740
|
+
referenceCommand,
|
|
4741
|
+
governanceCommand
|
|
4742
|
+
]
|
|
4743
|
+
};
|
|
4641
4744
|
function app() {
|
|
4642
|
-
|
|
4643
|
-
|
|
4745
|
+
const [first, ...rest] = rootCommand.commands;
|
|
4746
|
+
return rest.reduce((builder, command) => builder.command(command), cli({
|
|
4747
|
+
name: rootCommand.name,
|
|
4644
4748
|
version,
|
|
4645
|
-
description:
|
|
4646
|
-
}).command(
|
|
4749
|
+
description: rootCommand.description
|
|
4750
|
+
}).command(first));
|
|
4647
4751
|
}
|
|
4648
4752
|
/**
|
|
4649
4753
|
* The application boundary: argv in, exit code out — returned rather than written, so a caller that
|