buddy-agent-harness 0.17.0 → 0.18.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 +243 -11
- package/dist/index.d.mts +68 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +248 -12
- package/dist/index.mjs.map +1 -1
- package/dist/skill-scripts/doctor.mjs +44 -43
- package/dist/skill-scripts/init.mjs +44 -43
- package/dist/skill-scripts/mcp.mjs +44 -43
- package/dist/skill-scripts/reference.mjs +44 -43
- package/llms.txt +3 -2
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/skills/doctor-buddy-agent-harness/SKILL.md +5 -1
- package/skills/doctor-buddy-agent-harness/references/global-instructions.md +30 -0
- package/skills/doctor-buddy-agent-harness/references/harnesses/claude-code.md +3 -2
- package/skills/doctor-buddy-agent-harness/references/harnesses/codex.md +4 -2
- package/skills/doctor-buddy-agent-harness/references/harnesses/copilot-cli.md +3 -2
- package/skills/doctor-buddy-agent-harness/references/harnesses/cursor.md +1 -1
- package/skills/doctor-buddy-agent-harness/references/harnesses/gemini-cli.md +2 -2
- package/skills/doctor-buddy-agent-harness/scripts/doctor.mjs +44 -43
- package/skills/enhance/SKILL.md +13 -2
- package/skills/enhance/scripts/doctor.mjs +486 -0
- package/skills/init-buddy-agent-harness/SKILL.md +1 -1
- package/skills/init-buddy-agent-harness/scripts/doctor.mjs +44 -43
- package/skills/init-buddy-agent-harness/scripts/init.mjs +44 -43
- package/skills/reference/SKILL.md +1 -1
- package/skills/reference/scripts/reference.mjs +44 -43
- package/skills/repair/SKILL.md +3 -1
- package/skills/repair/scripts/doctor.mjs +44 -43
- package/skills/repair/scripts/mcp.mjs +44 -43
- package/src/diagnose-bridges/diagnose-bridges.ts +27 -2
- package/src/diagnose-bridges/diagnose-global-instructions.ts +154 -0
- package/src/diagnose-bridges/diagnose-instructions.ts +7 -2
- package/src/diagnose-bridges/doctor-guidance.ts +152 -6
- package/src/diagnose-bridges/doctor.command.ts +6 -1
- package/src/harness-registry/harness-registry.ts +38 -4
- package/src/harness-registry/instruction-bridge.ts +25 -9
- package/src/index.ts +8 -0
- package/src/skill-scripts/launchers.ts +1 -0
package/dist/index.mjs
CHANGED
|
@@ -574,6 +574,12 @@ function skillsProjection(harness, scope, directories = skillsDirectories(harnes
|
|
|
574
574
|
return listed.includes(".agents/skills") ? {} : { skillsDirectory: first };
|
|
575
575
|
}
|
|
576
576
|
/**
|
|
577
|
+
* The user-scope counterpart of the root `AGENTS.md`, relative to the home directory. No harness
|
|
578
|
+
* reads it natively; each loads it only through a user-scope `instructionBridge` (E-CC-18, E-CODEX-05,
|
|
579
|
+
* E-GEM-03, E-COPILOT-04, E-CUR-08).
|
|
580
|
+
*/
|
|
581
|
+
const globalInstructions = ".agents/AGENTS.md";
|
|
582
|
+
/**
|
|
577
583
|
* Skills directories come from `@cyberuni/agent-harness`, except for the harnesses it does not know
|
|
578
584
|
* (`devin-desktop`, `windsurf`); see `.research/agentic-configuration-standards/` for the rest.
|
|
579
585
|
*/
|
|
@@ -614,7 +620,13 @@ const harnessRegistry = [
|
|
|
614
620
|
},
|
|
615
621
|
user: {
|
|
616
622
|
detect: ".claude",
|
|
617
|
-
...skillsProjection("claude-code", "user")
|
|
623
|
+
...skillsProjection("claude-code", "user"),
|
|
624
|
+
relocatedBy: "CLAUDE_CONFIG_DIR",
|
|
625
|
+
instructionBridge: {
|
|
626
|
+
kind: "import",
|
|
627
|
+
path: ".claude/CLAUDE.md",
|
|
628
|
+
line: `@~/${globalInstructions}`
|
|
629
|
+
}
|
|
618
630
|
}
|
|
619
631
|
},
|
|
620
632
|
{
|
|
@@ -676,7 +688,13 @@ const harnessRegistry = [
|
|
|
676
688
|
},
|
|
677
689
|
user: {
|
|
678
690
|
detect: ".codex",
|
|
679
|
-
...skillsProjection("codex", "user")
|
|
691
|
+
...skillsProjection("codex", "user"),
|
|
692
|
+
instructionBridge: {
|
|
693
|
+
kind: "symlink",
|
|
694
|
+
path: ".codex/AGENTS.md"
|
|
695
|
+
},
|
|
696
|
+
shadowedBy: [".codex/AGENTS.override.md"],
|
|
697
|
+
relocatedBy: "CODEX_HOME"
|
|
680
698
|
}
|
|
681
699
|
},
|
|
682
700
|
{
|
|
@@ -704,7 +722,12 @@ const harnessRegistry = [
|
|
|
704
722
|
},
|
|
705
723
|
user: {
|
|
706
724
|
detect: ".copilot",
|
|
707
|
-
...skillsProjection("copilot-cli", "user")
|
|
725
|
+
...skillsProjection("copilot-cli", "user"),
|
|
726
|
+
relocatedBy: "COPILOT_HOME",
|
|
727
|
+
instructionBridge: {
|
|
728
|
+
kind: "symlink",
|
|
729
|
+
path: ".copilot/copilot-instructions.md"
|
|
730
|
+
}
|
|
708
731
|
}
|
|
709
732
|
},
|
|
710
733
|
{
|
|
@@ -736,7 +759,11 @@ const harnessRegistry = [
|
|
|
736
759
|
},
|
|
737
760
|
user: {
|
|
738
761
|
detect: ".gemini",
|
|
739
|
-
...skillsProjection("gemini-cli", "user")
|
|
762
|
+
...skillsProjection("gemini-cli", "user"),
|
|
763
|
+
instructionBridge: {
|
|
764
|
+
kind: "symlink",
|
|
765
|
+
path: ".gemini/GEMINI.md"
|
|
766
|
+
}
|
|
740
767
|
}
|
|
741
768
|
},
|
|
742
769
|
{
|
|
@@ -952,6 +979,61 @@ const instructionTable = {
|
|
|
952
979
|
}
|
|
953
980
|
};
|
|
954
981
|
const instructionRepairs = repairsOf(instructionTable);
|
|
982
|
+
const globalFile = `~/${globalInstructions}`;
|
|
983
|
+
/**
|
|
984
|
+
* The step that bridges one harness's user-scope file, in the words it is handed over in; `file` is
|
|
985
|
+
* where it was found, which a variable such as `$CODEX_HOME` may have moved.
|
|
986
|
+
*/
|
|
987
|
+
function globalBridgeStep(bridge, file = `~/${bridge.path}`) {
|
|
988
|
+
return bridge.kind === "import" ? `add the line \`${bridge.line}\` to ${file}` : `run \`ln -s ${globalFile} ${file}\``;
|
|
989
|
+
}
|
|
990
|
+
/** Every spelling of a user-scope path a report can carry: from `~`, and from the variable that moves it. */
|
|
991
|
+
function userSpellings(scope, path) {
|
|
992
|
+
const under = `${scope.detect}/`;
|
|
993
|
+
return scope.relocatedBy !== void 0 && path.startsWith(under) ? [`~/${path}`, `$${scope.relocatedBy}/${path.slice(under.length)}`] : [`~/${path}`];
|
|
994
|
+
}
|
|
995
|
+
/** The bridge for a reported path; undefined for a path no harness registers, such as a table's `<path>`. */
|
|
996
|
+
function userBridgeAt(file) {
|
|
997
|
+
for (const { user } of harnessRegistry) {
|
|
998
|
+
const bridge = user?.instructionBridge;
|
|
999
|
+
if (user && bridge && userSpellings(user, bridge.path).includes(file)) return bridge;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
/** The step for one reported file, or a pointer to where it is written when the path is not one. */
|
|
1003
|
+
function stepAt(file, keepContent) {
|
|
1004
|
+
const bridge = userBridgeAt(file);
|
|
1005
|
+
if (bridge === void 0) return `add the bridge the harness page names for ${file}`;
|
|
1006
|
+
return `${keepContent && bridge.kind !== "import" ? `move what ${file} says into ${globalFile} and remove it, then ` : ""}${globalBridgeStep(bridge, file)}`;
|
|
1007
|
+
}
|
|
1008
|
+
/** Outside the repository, so never written: a repair is a step handed to the user. */
|
|
1009
|
+
const handOver = "hand the user this step, since nothing here writes outside the repository:";
|
|
1010
|
+
const globalInstructionTable = {
|
|
1011
|
+
"global-instructions-missing": {
|
|
1012
|
+
detail: `no user-scope instruction file at this path — the harness loads none of ${globalFile}`,
|
|
1013
|
+
repair: ({ file }) => ({
|
|
1014
|
+
command: "",
|
|
1015
|
+
instruction: `${handOver} ${stepAt(file, false)}`
|
|
1016
|
+
}),
|
|
1017
|
+
skillRepair: () => "hand the user the step the harness page names for that file; write nothing yourself"
|
|
1018
|
+
},
|
|
1019
|
+
"global-instructions-unbridged": {
|
|
1020
|
+
detail: `the file holds its own content and does not load ${globalFile} — text placed there reaches no session of this harness`,
|
|
1021
|
+
repair: ({ file }) => ({
|
|
1022
|
+
command: "",
|
|
1023
|
+
instruction: `${handOver} ${stepAt(file, true)}`
|
|
1024
|
+
}),
|
|
1025
|
+
skillRepair: () => "hand the user the step the harness page names for that file, keeping what the file says; write nothing yourself"
|
|
1026
|
+
},
|
|
1027
|
+
"global-instructions-overridden": {
|
|
1028
|
+
detail: `the harness reads this file in place of its own user-scope file, so whatever that file loads goes unread, and this one does not load ${globalFile}`,
|
|
1029
|
+
repair: ({ file }) => ({
|
|
1030
|
+
command: "",
|
|
1031
|
+
instruction: `${handOver} move what ${file} says into ${globalFile} and remove it`
|
|
1032
|
+
}),
|
|
1033
|
+
skillRepair: () => "hand the user the move of what that file says into the global file, and its removal; write nothing yourself"
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
const globalInstructionRepairs = repairsOf(globalInstructionTable);
|
|
955
1037
|
const configurationTable = {
|
|
956
1038
|
"deprecated-harness": {
|
|
957
1039
|
detail: "a projection under a harness name that has been superseded — the replacement reads .agents/skills natively and needs no projection at all",
|
|
@@ -1128,6 +1210,7 @@ repairsOf(nonstandardTable);
|
|
|
1128
1210
|
const doctorTable = {
|
|
1129
1211
|
...bridgeTable,
|
|
1130
1212
|
...instructionTable,
|
|
1213
|
+
...globalInstructionTable,
|
|
1131
1214
|
...configurationTable,
|
|
1132
1215
|
...mcpTable,
|
|
1133
1216
|
...nonstandardTable
|
|
@@ -1180,6 +1263,8 @@ The command is read-only. It never repairs anything, so it is safe to run at any
|
|
|
1180
1263
|
|
|
1181
1264
|
\`instructions\` is everything standing between a harness and \`AGENTS.md\`, with a \`status\` of \`ok\`, \`missing\`, \`unbridged\`, \`unreadable\`, \`shadowing\`, or \`superseded\`. The last two are not bridges: they are files that suppress an \`AGENTS.md\` the harness would otherwise read by itself. A separate section because nothing about any of them is shared with \`bridges\`: a different \`kind\`, a different status vocabulary, and a repair that is never a command.
|
|
1182
1265
|
|
|
1266
|
+
\`globalInstructions\` is the same question one level up: whether each harness installed for this user loads \`${globalFile}\` through its own user-scope file, with a \`status\` of \`ok\`, \`missing\`, \`unbridged\`, or \`overridden\`. No harness reads that file by itself, so text placed there reaches only the harnesses whose row is \`ok\`. The rows are there whether or not the file exists; a finding is raised only when it exists and goes unread.
|
|
1267
|
+
|
|
1183
1268
|
\`findings\` explains each problem and carries more than the two sections above: the configuration, MCP, and non-standard findings have no section of their own, because they are about files rather than about bridges. \`help\` carries each repair, one row per distinct repair, with two columns:
|
|
1184
1269
|
|
|
1185
1270
|
- \`command\` — a shell invocation that, run exactly as given, **completes** the repair.
|
|
@@ -1203,6 +1288,7 @@ Every \`problem\` name routes to exactly one page. Load the page for the finding
|
|
|
1203
1288
|
| --- | --- |
|
|
1204
1289
|
| \`references/bridges.md\` | any \`bridges\` row that is not \`ok\` |
|
|
1205
1290
|
| \`references/instructions.md\` | any \`instructions\` row that is not \`ok\` |
|
|
1291
|
+
| \`references/global-instructions.md\` | any \`globalInstructions\` row that is not \`ok\` |
|
|
1206
1292
|
| \`references/configuration.md\` | a finding about the configuration around the bridges rather than a bridge |
|
|
1207
1293
|
| \`references/mcp.md\` | any finding whose path is an MCP locator — **always** before acting on a credential finding |
|
|
1208
1294
|
| \`references/nonstandard.md\` | a finding about configuration only one harness can read |
|
|
@@ -1214,6 +1300,7 @@ Every \`problem\` name routes to exactly one page. Load the page for the finding
|
|
|
1214
1300
|
- Edit skills at \`.agents/skills/<name>/SKILL.md\`. Editing through a bridge is only safe when that bridge is a symlink.
|
|
1215
1301
|
- Do not add bridges to \`.gitignore\`. An untracked bridge swallows a real edit silently.
|
|
1216
1302
|
- Never repeat a value from a file an \`mcp-literal-secret\` or \`mcp-committed-secret\` finding points at. The report withheld it on purpose, and quoting it back puts it in the transcript anyway.
|
|
1303
|
+
- Never write outside the repository. A \`globalInstructions\` repair is a step for the user to take in their own home directory; hand it over exactly as reported.
|
|
1217
1304
|
- Write instructions in \`AGENTS.md\`, never in \`CLAUDE.md\`. Content written there reaches one harness, drifts from the canonical file, and — because Claude Code prefers it — takes \`AGENTS.md\` out of that harness's context entirely.
|
|
1218
1305
|
`;
|
|
1219
1306
|
}
|
|
@@ -2795,7 +2882,7 @@ function projectChain(root) {
|
|
|
2795
2882
|
dir = parent;
|
|
2796
2883
|
}
|
|
2797
2884
|
}
|
|
2798
|
-
function isDirectory$
|
|
2885
|
+
function isDirectory$2(path) {
|
|
2799
2886
|
try {
|
|
2800
2887
|
return statSync(path).isDirectory();
|
|
2801
2888
|
} catch {
|
|
@@ -2831,7 +2918,7 @@ function dependencyLayers(root, skip) {
|
|
|
2831
2918
|
const dir = packageDir(pkg, manifestPath);
|
|
2832
2919
|
if (!dir || skip.has(canonical(dir))) continue;
|
|
2833
2920
|
const references = join(dir, "references");
|
|
2834
|
-
if (!isDirectory$
|
|
2921
|
+
if (!isDirectory$2(references)) continue;
|
|
2835
2922
|
const manifest = readJson(join(dir, "plugin.json"));
|
|
2836
2923
|
const manifestName = isRecord(manifest) && typeof manifest["name"] === "string" ? manifest["name"] : void 0;
|
|
2837
2924
|
const plugins = manifestName && manifestName !== pkg ? [pkg, manifestName] : [pkg];
|
|
@@ -2881,7 +2968,7 @@ async function referenceLayers({ root, home, platform, programData, packageRoot
|
|
|
2881
2968
|
plugins: self,
|
|
2882
2969
|
status: LEGACY_STATUS
|
|
2883
2970
|
},
|
|
2884
|
-
...enabled.filter(({ dir, skipped }) => skipped || isDirectory$
|
|
2971
|
+
...enabled.filter(({ dir, skipped }) => skipped || isDirectory$2(dir) && canonical(dirname(dir)) !== ownRoot),
|
|
2885
2972
|
...dependencyLayers(root, /* @__PURE__ */ new Set([ownRoot]))
|
|
2886
2973
|
];
|
|
2887
2974
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -2978,6 +3065,145 @@ function projectSkills({ root, canonicalSkills, harnesses, copy, force }) {
|
|
|
2978
3065
|
};
|
|
2979
3066
|
}
|
|
2980
3067
|
//#endregion
|
|
3068
|
+
//#region src/diagnose-bridges/diagnose-global-instructions.ts
|
|
3069
|
+
function isDirectory$1(path) {
|
|
3070
|
+
try {
|
|
3071
|
+
return lstatSync(path).isDirectory();
|
|
3072
|
+
} catch {
|
|
3073
|
+
return false;
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
function exists$1(path) {
|
|
3077
|
+
try {
|
|
3078
|
+
lstatSync(path);
|
|
3079
|
+
return true;
|
|
3080
|
+
} catch {
|
|
3081
|
+
return false;
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
/** The import a user wrote may spell the home directory either way; both load the same file. */
|
|
3085
|
+
function importsGlobal(body, bridge, home) {
|
|
3086
|
+
const spellings = bridge.kind === "import" ? [bridge.line, `@${join(home, globalInstructions)}`] : [];
|
|
3087
|
+
return body.split("\n").some((line) => spellings.includes(line.trim()));
|
|
3088
|
+
}
|
|
3089
|
+
/** Follows `relocatedBy` the way the harnesses do: an empty value is no value (E-CODEX-06, E-CC-19, E-COPILOT-05). */
|
|
3090
|
+
function locate(home, scope, env, path) {
|
|
3091
|
+
const variable = scope.relocatedBy;
|
|
3092
|
+
const moved = variable === void 0 ? void 0 : env[variable];
|
|
3093
|
+
if (!moved || path !== scope.detect && !path.startsWith(`${scope.detect}/`)) return {
|
|
3094
|
+
absolute: join(home, path),
|
|
3095
|
+
display: `~/${path}`
|
|
3096
|
+
};
|
|
3097
|
+
const rest = path.slice(scope.detect.length);
|
|
3098
|
+
return {
|
|
3099
|
+
absolute: join(resolve(moved), rest),
|
|
3100
|
+
display: `$${variable}${rest}`
|
|
3101
|
+
};
|
|
3102
|
+
}
|
|
3103
|
+
/** A shadow is read only where it is a file holding more than whitespace (E-CODEX-06). */
|
|
3104
|
+
function readsAsShadow(path) {
|
|
3105
|
+
try {
|
|
3106
|
+
return statSync(path).isFile() && readFileSync(path, "utf8").trim() !== "";
|
|
3107
|
+
} catch {
|
|
3108
|
+
return false;
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
function inspect$1(home, target, bridge) {
|
|
3112
|
+
let stats;
|
|
3113
|
+
try {
|
|
3114
|
+
stats = lstatSync(target);
|
|
3115
|
+
} catch {
|
|
3116
|
+
return {
|
|
3117
|
+
kind: "none",
|
|
3118
|
+
status: "missing",
|
|
3119
|
+
problem: "global-instructions-missing"
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
if (stats.isSymbolicLink()) return resolve(dirname(target), readlinkSync(target)) === join(home, ".agents/AGENTS.md") ? {
|
|
3123
|
+
kind: "symlink",
|
|
3124
|
+
status: "ok"
|
|
3125
|
+
} : {
|
|
3126
|
+
kind: "symlink",
|
|
3127
|
+
status: "unbridged",
|
|
3128
|
+
problem: "global-instructions-unbridged"
|
|
3129
|
+
};
|
|
3130
|
+
let body;
|
|
3131
|
+
try {
|
|
3132
|
+
body = readFileSync(target, "utf8");
|
|
3133
|
+
} catch {
|
|
3134
|
+
return {
|
|
3135
|
+
kind: "file",
|
|
3136
|
+
status: "unbridged",
|
|
3137
|
+
problem: "global-instructions-unbridged"
|
|
3138
|
+
};
|
|
3139
|
+
}
|
|
3140
|
+
return importsGlobal(body, bridge, home) ? {
|
|
3141
|
+
kind: "import",
|
|
3142
|
+
status: "ok"
|
|
3143
|
+
} : {
|
|
3144
|
+
kind: "file",
|
|
3145
|
+
status: "unbridged",
|
|
3146
|
+
problem: "global-instructions-unbridged"
|
|
3147
|
+
};
|
|
3148
|
+
}
|
|
3149
|
+
function finding(path, problem, cli) {
|
|
3150
|
+
const { detail, repair } = repairFor(problem);
|
|
3151
|
+
return {
|
|
3152
|
+
path,
|
|
3153
|
+
problem,
|
|
3154
|
+
detail,
|
|
3155
|
+
repair: repair({ file: path }, cli)
|
|
3156
|
+
};
|
|
3157
|
+
}
|
|
3158
|
+
/**
|
|
3159
|
+
* Whether each harness the user has installed loads `~/.agents/AGENTS.md` through its own user-scope
|
|
3160
|
+
* file, read from wherever `env` moves it. Read-only: the repair is handed to the user, since
|
|
3161
|
+
* nothing here writes outside the repository.
|
|
3162
|
+
*/
|
|
3163
|
+
function diagnoseGlobalInstructions(home, preferred, cli, env = {}) {
|
|
3164
|
+
const hasGlobal = exists$1(join(home, globalInstructions));
|
|
3165
|
+
const rows = [];
|
|
3166
|
+
const findings = [];
|
|
3167
|
+
for (const harness of harnessRegistry) {
|
|
3168
|
+
const user = harness.user;
|
|
3169
|
+
const bridge = user?.instructionBridge;
|
|
3170
|
+
if (!user || !bridge) continue;
|
|
3171
|
+
if (!preferred.includes(harness.name) && !isDirectory$1(locate(home, user, env, user.detect).absolute)) continue;
|
|
3172
|
+
const file = locate(home, user, env, bridge.path);
|
|
3173
|
+
const inspection = inspect$1(home, file.absolute, bridge);
|
|
3174
|
+
const shadow = (user.shadowedBy ?? []).map((path) => locate(home, user, env, path)).find(({ absolute }) => readsAsShadow(absolute));
|
|
3175
|
+
if (shadow !== void 0) {
|
|
3176
|
+
const read = inspect$1(home, shadow.absolute, bridge);
|
|
3177
|
+
if (read.status === "ok") {
|
|
3178
|
+
rows.push({
|
|
3179
|
+
harness: harness.name,
|
|
3180
|
+
path: shadow.display,
|
|
3181
|
+
kind: read.kind,
|
|
3182
|
+
status: "ok"
|
|
3183
|
+
});
|
|
3184
|
+
continue;
|
|
3185
|
+
}
|
|
3186
|
+
rows.push({
|
|
3187
|
+
harness: harness.name,
|
|
3188
|
+
path: file.display,
|
|
3189
|
+
kind: inspection.kind,
|
|
3190
|
+
status: "overridden"
|
|
3191
|
+
});
|
|
3192
|
+
if (hasGlobal) findings.push(finding(shadow.display, "global-instructions-overridden", cli));
|
|
3193
|
+
} else rows.push({
|
|
3194
|
+
harness: harness.name,
|
|
3195
|
+
path: file.display,
|
|
3196
|
+
kind: inspection.kind,
|
|
3197
|
+
status: inspection.status
|
|
3198
|
+
});
|
|
3199
|
+
if (hasGlobal && inspection.problem) findings.push(finding(file.display, inspection.problem, cli));
|
|
3200
|
+
}
|
|
3201
|
+
return {
|
|
3202
|
+
globalInstructions: rows,
|
|
3203
|
+
findings
|
|
3204
|
+
};
|
|
3205
|
+
}
|
|
3206
|
+
//#endregion
|
|
2981
3207
|
//#region src/diagnose-bridges/agents-files.ts
|
|
2982
3208
|
/** Directories that never hold instructions this repository is responsible for bridging. */
|
|
2983
3209
|
const pruned = /* @__PURE__ */ new Set(["node_modules"]);
|
|
@@ -3092,7 +3318,7 @@ function diagnoseInstructions(root, harnesses, cli) {
|
|
|
3092
3318
|
const bridged = harnesses.map((harness) => ({
|
|
3093
3319
|
name: harness.name,
|
|
3094
3320
|
bridge: harness.project.instructionBridge
|
|
3095
|
-
})).filter((harness) =>
|
|
3321
|
+
})).filter((harness) => harness.bridge?.kind === "settings-entry");
|
|
3096
3322
|
const instructions = [];
|
|
3097
3323
|
const findings = [];
|
|
3098
3324
|
const directories = agentsFileDirectories(root);
|
|
@@ -3348,7 +3574,7 @@ function inspect(target, path, canonical, git) {
|
|
|
3348
3574
|
* Read-only: nothing is created, moved, or repaired — the caller decides what to run from the
|
|
3349
3575
|
* repair each finding carries.
|
|
3350
3576
|
*/
|
|
3351
|
-
function diagnoseBridges({ root, harnesses: preferred = [], cli }) {
|
|
3577
|
+
function diagnoseBridges({ root, harnesses: preferred = [], cli, home, env }) {
|
|
3352
3578
|
const canonical = join(root, ".agents", "skills");
|
|
3353
3579
|
const git = new GitBridgeState(root);
|
|
3354
3580
|
const selected = selectHarnesses(root, preferred);
|
|
@@ -3393,9 +3619,15 @@ function diagnoseBridges({ root, harnesses: preferred = [], cli }) {
|
|
|
3393
3619
|
}
|
|
3394
3620
|
const instructions = diagnoseInstructions(root, selected, cli);
|
|
3395
3621
|
findings.push(...instructions.findings);
|
|
3622
|
+
const global = home === void 0 ? {
|
|
3623
|
+
globalInstructions: [],
|
|
3624
|
+
findings: []
|
|
3625
|
+
} : diagnoseGlobalInstructions(home, preferred, cli, env);
|
|
3626
|
+
findings.push(...global.findings);
|
|
3396
3627
|
return {
|
|
3397
3628
|
bridges,
|
|
3398
3629
|
instructions: instructions.instructions,
|
|
3630
|
+
globalInstructions: global.globalInstructions,
|
|
3399
3631
|
divergence,
|
|
3400
3632
|
findings
|
|
3401
3633
|
};
|
|
@@ -3416,6 +3648,7 @@ function buildDoctorReport(bin, result, configuration = [], held = []) {
|
|
|
3416
3648
|
bin,
|
|
3417
3649
|
bridges: result.bridges,
|
|
3418
3650
|
instructions: result.instructions,
|
|
3651
|
+
globalInstructions: result.globalInstructions,
|
|
3419
3652
|
references,
|
|
3420
3653
|
findings: `0 problems found — ${bridges} and the configuration around them is current`
|
|
3421
3654
|
};
|
|
@@ -3424,6 +3657,7 @@ function buildDoctorReport(bin, result, configuration = [], held = []) {
|
|
|
3424
3657
|
bin,
|
|
3425
3658
|
bridges: result.bridges,
|
|
3426
3659
|
instructions: result.instructions,
|
|
3660
|
+
globalInstructions: result.globalInstructions,
|
|
3427
3661
|
references,
|
|
3428
3662
|
...result.divergence.length ? { divergence: result.divergence } : {},
|
|
3429
3663
|
findings: findings.map(({ path, problem, detail }) => ({
|
|
@@ -3436,7 +3670,7 @@ function buildDoctorReport(bin, result, configuration = [], held = []) {
|
|
|
3436
3670
|
}
|
|
3437
3671
|
const doctorCommand = command({
|
|
3438
3672
|
name: "doctor",
|
|
3439
|
-
description: "Report whether this repository's harness bridges still resolve — skills into .agents/skills, instructions into AGENTS.md. Read-only.",
|
|
3673
|
+
description: "Report whether this repository's harness bridges still resolve — skills into .agents/skills, instructions into AGENTS.md — and whether each harness's user-scope file loads ~/.agents/AGENTS.md. Read-only.",
|
|
3440
3674
|
options: {
|
|
3441
3675
|
root: {
|
|
3442
3676
|
description: "Repository or package directory. Defaults to the current directory.",
|
|
@@ -3461,7 +3695,9 @@ const doctorCommand = command({
|
|
|
3461
3695
|
const result = diagnoseBridges({
|
|
3462
3696
|
root,
|
|
3463
3697
|
...harnesses.length ? { harnesses } : {},
|
|
3464
|
-
cli: commandInvocation
|
|
3698
|
+
cli: commandInvocation,
|
|
3699
|
+
home,
|
|
3700
|
+
env: process.env
|
|
3465
3701
|
});
|
|
3466
3702
|
const git = new GitBridgeState(root);
|
|
3467
3703
|
const configuration = [
|
|
@@ -5190,6 +5426,6 @@ function listMcpServers(options) {
|
|
|
5190
5426
|
return entries;
|
|
5191
5427
|
}
|
|
5192
5428
|
//#endregion
|
|
5193
|
-
export { activate, bridgeRepairs, buildDoctorReport, deprecatedManagedGovernancesDir, diagnoseBridges, diagnoseInstructions, diagnoseMcp, doctorCommand, doctorRepairs, doctorSkill, goldenSetPath, governanceCommand, governanceLayers, harnessCommand, harnessRegistry, initCommand, initializeHarnesses, instructionRepairs, listGovernances, listMcpServers, listReferences, managedGovernancesDir, managedReferencesDir, overrideLayers, parseGovernanceName, parseReferenceName, referenceCommand, referenceLayers, renderDoctorSkill, resolveGovernance, resolveReference, run, searchReferences };
|
|
5429
|
+
export { activate, bridgeRepairs, buildDoctorReport, deprecatedManagedGovernancesDir, diagnoseBridges, diagnoseGlobalInstructions, diagnoseInstructions, diagnoseMcp, doctorCommand, doctorRepairs, doctorSkill, globalInstructionRepairs, goldenSetPath, governanceCommand, governanceLayers, harnessCommand, harnessRegistry, initCommand, initializeHarnesses, instructionRepairs, listGovernances, listMcpServers, listReferences, managedGovernancesDir, managedReferencesDir, overrideLayers, parseGovernanceName, parseReferenceName, referenceCommand, referenceLayers, renderDoctorSkill, resolveGovernance, resolveReference, run, searchReferences };
|
|
5194
5430
|
|
|
5195
5431
|
//# sourceMappingURL=index.mjs.map
|