buddy-agent-harness 0.17.0 → 0.19.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.
Files changed (42) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/.cursor-plugin/plugin.json +1 -1
  4. package/dist/cli.mjs +272 -11
  5. package/dist/index.d.mts +75 -5
  6. package/dist/index.d.mts.map +1 -1
  7. package/dist/index.mjs +277 -12
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/skill-scripts/doctor.mjs +73 -72
  10. package/dist/skill-scripts/init.mjs +73 -72
  11. package/dist/skill-scripts/mcp.mjs +73 -72
  12. package/dist/skill-scripts/reference.mjs +73 -72
  13. package/llms.txt +3 -2
  14. package/package.json +1 -1
  15. package/plugin.json +1 -1
  16. package/skills/doctor-buddy-agent-harness/SKILL.md +5 -1
  17. package/skills/doctor-buddy-agent-harness/references/global-instructions.md +33 -0
  18. package/skills/doctor-buddy-agent-harness/references/harnesses/claude-code.md +3 -2
  19. package/skills/doctor-buddy-agent-harness/references/harnesses/codex.md +4 -2
  20. package/skills/doctor-buddy-agent-harness/references/harnesses/copilot-cli.md +3 -2
  21. package/skills/doctor-buddy-agent-harness/references/harnesses/cursor.md +1 -1
  22. package/skills/doctor-buddy-agent-harness/references/harnesses/gemini-cli.md +2 -2
  23. package/skills/doctor-buddy-agent-harness/scripts/doctor.mjs +73 -72
  24. package/skills/enhance/SKILL.md +14 -2
  25. package/skills/enhance/scripts/doctor.mjs +486 -0
  26. package/skills/init-buddy-agent-harness/SKILL.md +1 -1
  27. package/skills/init-buddy-agent-harness/scripts/doctor.mjs +73 -72
  28. package/skills/init-buddy-agent-harness/scripts/init.mjs +73 -72
  29. package/skills/reference/SKILL.md +1 -1
  30. package/skills/reference/scripts/reference.mjs +73 -72
  31. package/skills/repair/SKILL.md +3 -1
  32. package/skills/repair/scripts/doctor.mjs +73 -72
  33. package/skills/repair/scripts/mcp.mjs +73 -72
  34. package/src/diagnose-bridges/diagnose-bridges.ts +27 -2
  35. package/src/diagnose-bridges/diagnose-global-instructions.ts +172 -0
  36. package/src/diagnose-bridges/diagnose-instructions.ts +7 -2
  37. package/src/diagnose-bridges/doctor-guidance.ts +175 -6
  38. package/src/diagnose-bridges/doctor.command.ts +6 -1
  39. package/src/harness-registry/harness-registry.ts +45 -4
  40. package/src/harness-registry/instruction-bridge.ts +25 -9
  41. package/src/index.ts +8 -0
  42. 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,14 @@ 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
+ emptyRelocatesToStart: true,
626
+ instructionBridge: {
627
+ kind: "import",
628
+ path: ".claude/CLAUDE.md",
629
+ line: `@~/${globalInstructions}`
630
+ }
618
631
  }
619
632
  },
620
633
  {
@@ -676,7 +689,13 @@ const harnessRegistry = [
676
689
  },
677
690
  user: {
678
691
  detect: ".codex",
679
- ...skillsProjection("codex", "user")
692
+ ...skillsProjection("codex", "user"),
693
+ instructionBridge: {
694
+ kind: "symlink",
695
+ path: ".codex/AGENTS.md"
696
+ },
697
+ shadowedBy: [".codex/AGENTS.override.md"],
698
+ relocatedBy: "CODEX_HOME"
680
699
  }
681
700
  },
682
701
  {
@@ -704,7 +723,12 @@ const harnessRegistry = [
704
723
  },
705
724
  user: {
706
725
  detect: ".copilot",
707
- ...skillsProjection("copilot-cli", "user")
726
+ ...skillsProjection("copilot-cli", "user"),
727
+ relocatedBy: "COPILOT_HOME",
728
+ instructionBridge: {
729
+ kind: "symlink",
730
+ path: ".copilot/copilot-instructions.md"
731
+ }
708
732
  }
709
733
  },
710
734
  {
@@ -736,7 +760,11 @@ const harnessRegistry = [
736
760
  },
737
761
  user: {
738
762
  detect: ".gemini",
739
- ...skillsProjection("gemini-cli", "user")
763
+ ...skillsProjection("gemini-cli", "user"),
764
+ instructionBridge: {
765
+ kind: "symlink",
766
+ path: ".gemini/GEMINI.md"
767
+ }
740
768
  }
741
769
  },
742
770
  {
@@ -952,6 +980,69 @@ const instructionTable = {
952
980
  }
953
981
  };
954
982
  const instructionRepairs = repairsOf(instructionTable);
983
+ const globalFile = `~/${globalInstructions}`;
984
+ /**
985
+ * The step that bridges one harness's user-scope file, in the words it is handed over in; `file` is
986
+ * where it was found, which a variable such as `$CODEX_HOME` may have moved.
987
+ */
988
+ function globalBridgeStep(bridge, file = `~/${bridge.path}`) {
989
+ return bridge.kind === "import" ? `add the line \`${bridge.line}\` to ${file}` : `run \`ln -s ${globalFile} ${file}\``;
990
+ }
991
+ /** Every spelling of a user-scope path a report can carry: from `~`, and from the variable that moves it. */
992
+ function userSpellings(scope, path) {
993
+ const under = `${scope.detect}/`;
994
+ return scope.relocatedBy !== void 0 && path.startsWith(under) ? [`~/${path}`, `$${scope.relocatedBy}/${path.slice(under.length)}`] : [`~/${path}`];
995
+ }
996
+ /** The bridge for a reported path; undefined for a path no harness registers, such as a table's `<path>`. */
997
+ function userBridgeAt(file) {
998
+ for (const { user } of harnessRegistry) {
999
+ const bridge = user?.instructionBridge;
1000
+ if (user && bridge && userSpellings(user, bridge.path).includes(file)) return bridge;
1001
+ }
1002
+ }
1003
+ /** The step for one reported file, or a pointer to where it is written when the path is not one. */
1004
+ function stepAt(file, keepContent) {
1005
+ const bridge = userBridgeAt(file);
1006
+ if (bridge === void 0) return `add the bridge the harness page names for ${file}`;
1007
+ return `${keepContent && bridge.kind !== "import" ? `move what ${file} says into ${globalFile} and remove it, then ` : ""}${globalBridgeStep(bridge, file)}`;
1008
+ }
1009
+ /** Outside the repository, so never written: a repair is a step handed to the user. */
1010
+ const handOver = "hand the user this step, since nothing here writes outside the repository:";
1011
+ const globalInstructionTable = {
1012
+ "global-instructions-missing": {
1013
+ detail: `no user-scope instruction file at this path — the harness loads none of ${globalFile}`,
1014
+ repair: ({ file }) => ({
1015
+ command: "",
1016
+ instruction: `${handOver} ${stepAt(file, false)}`
1017
+ }),
1018
+ skillRepair: () => "hand the user the step the harness page names for that file; write nothing yourself"
1019
+ },
1020
+ "global-instructions-unbridged": {
1021
+ detail: `the file holds its own content and does not load ${globalFile} — text placed there reaches no session of this harness`,
1022
+ repair: ({ file }) => ({
1023
+ command: "",
1024
+ instruction: `${handOver} ${stepAt(file, true)}`
1025
+ }),
1026
+ skillRepair: () => "hand the user the step the harness page names for that file, keeping what the file says; write nothing yourself"
1027
+ },
1028
+ "global-instructions-overridden": {
1029
+ 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}`,
1030
+ repair: ({ file }) => ({
1031
+ command: "",
1032
+ instruction: `${handOver} move what ${file} says into ${globalFile} and remove it`
1033
+ }),
1034
+ skillRepair: () => "hand the user the move of what that file says into the global file, and its removal; write nothing yourself"
1035
+ },
1036
+ "global-instructions-emptied": {
1037
+ detail: "the variable is set but empty, which this harness reads as the directory it starts in rather than as unset — its user-scope file is whichever one sits there, not the one in its own folder",
1038
+ repair: ({ file }) => ({
1039
+ command: "",
1040
+ instruction: `${handOver} unset ${file.slice(1)} where your shell sets it, or set it to the folder you meant`
1041
+ }),
1042
+ skillRepair: () => "hand the user the step of unsetting that variable; write nothing yourself"
1043
+ }
1044
+ };
1045
+ const globalInstructionRepairs = repairsOf(globalInstructionTable);
955
1046
  const configurationTable = {
956
1047
  "deprecated-harness": {
957
1048
  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 +1219,7 @@ repairsOf(nonstandardTable);
1128
1219
  const doctorTable = {
1129
1220
  ...bridgeTable,
1130
1221
  ...instructionTable,
1222
+ ...globalInstructionTable,
1131
1223
  ...configurationTable,
1132
1224
  ...mcpTable,
1133
1225
  ...nonstandardTable
@@ -1180,6 +1272,8 @@ The command is read-only. It never repairs anything, so it is safe to run at any
1180
1272
 
1181
1273
  \`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
1274
 
1275
+ \`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.
1276
+
1183
1277
  \`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
1278
 
1185
1279
  - \`command\` — a shell invocation that, run exactly as given, **completes** the repair.
@@ -1203,6 +1297,7 @@ Every \`problem\` name routes to exactly one page. Load the page for the finding
1203
1297
  | --- | --- |
1204
1298
  | \`references/bridges.md\` | any \`bridges\` row that is not \`ok\` |
1205
1299
  | \`references/instructions.md\` | any \`instructions\` row that is not \`ok\` |
1300
+ | \`references/global-instructions.md\` | any \`globalInstructions\` row that is not \`ok\` |
1206
1301
  | \`references/configuration.md\` | a finding about the configuration around the bridges rather than a bridge |
1207
1302
  | \`references/mcp.md\` | any finding whose path is an MCP locator — **always** before acting on a credential finding |
1208
1303
  | \`references/nonstandard.md\` | a finding about configuration only one harness can read |
@@ -1214,6 +1309,7 @@ Every \`problem\` name routes to exactly one page. Load the page for the finding
1214
1309
  - Edit skills at \`.agents/skills/<name>/SKILL.md\`. Editing through a bridge is only safe when that bridge is a symlink.
1215
1310
  - Do not add bridges to \`.gitignore\`. An untracked bridge swallows a real edit silently.
1216
1311
  - 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.
1312
+ - 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
1313
  - 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
1314
  `;
1219
1315
  }
@@ -2795,7 +2891,7 @@ function projectChain(root) {
2795
2891
  dir = parent;
2796
2892
  }
2797
2893
  }
2798
- function isDirectory$1(path) {
2894
+ function isDirectory$2(path) {
2799
2895
  try {
2800
2896
  return statSync(path).isDirectory();
2801
2897
  } catch {
@@ -2831,7 +2927,7 @@ function dependencyLayers(root, skip) {
2831
2927
  const dir = packageDir(pkg, manifestPath);
2832
2928
  if (!dir || skip.has(canonical(dir))) continue;
2833
2929
  const references = join(dir, "references");
2834
- if (!isDirectory$1(references)) continue;
2930
+ if (!isDirectory$2(references)) continue;
2835
2931
  const manifest = readJson(join(dir, "plugin.json"));
2836
2932
  const manifestName = isRecord(manifest) && typeof manifest["name"] === "string" ? manifest["name"] : void 0;
2837
2933
  const plugins = manifestName && manifestName !== pkg ? [pkg, manifestName] : [pkg];
@@ -2881,7 +2977,7 @@ async function referenceLayers({ root, home, platform, programData, packageRoot
2881
2977
  plugins: self,
2882
2978
  status: LEGACY_STATUS
2883
2979
  },
2884
- ...enabled.filter(({ dir, skipped }) => skipped || isDirectory$1(dir) && canonical(dirname(dir)) !== ownRoot),
2980
+ ...enabled.filter(({ dir, skipped }) => skipped || isDirectory$2(dir) && canonical(dirname(dir)) !== ownRoot),
2885
2981
  ...dependencyLayers(root, /* @__PURE__ */ new Set([ownRoot]))
2886
2982
  ];
2887
2983
  const seen = /* @__PURE__ */ new Set();
@@ -2978,6 +3074,165 @@ function projectSkills({ root, canonicalSkills, harnesses, copy, force }) {
2978
3074
  };
2979
3075
  }
2980
3076
  //#endregion
3077
+ //#region src/diagnose-bridges/diagnose-global-instructions.ts
3078
+ function isDirectory$1(path) {
3079
+ try {
3080
+ return lstatSync(path).isDirectory();
3081
+ } catch {
3082
+ return false;
3083
+ }
3084
+ }
3085
+ function exists$1(path) {
3086
+ try {
3087
+ lstatSync(path);
3088
+ return true;
3089
+ } catch {
3090
+ return false;
3091
+ }
3092
+ }
3093
+ /** The import a user wrote may spell the home directory either way; both load the same file. */
3094
+ function importsGlobal(body, bridge, home) {
3095
+ const spellings = bridge.kind === "import" ? [bridge.line, `@${join(home, globalInstructions)}`] : [];
3096
+ return body.split("\n").some((line) => spellings.includes(line.trim()));
3097
+ }
3098
+ /**
3099
+ * Follows `relocatedBy` the way each harness does. An empty value is no value to Codex and Copilot CLI
3100
+ * (E-CODEX-06, E-COPILOT-06), and the directory Claude Code starts in to Claude Code (E-CC-20).
3101
+ */
3102
+ function base(scope, env, start) {
3103
+ const variable = scope.relocatedBy;
3104
+ const value = variable === void 0 ? void 0 : env[variable];
3105
+ if (variable === void 0 || value === void 0) return {};
3106
+ if (value !== "") return { moved: {
3107
+ root: resolve(value),
3108
+ display: `$${variable}`
3109
+ } };
3110
+ return scope.emptyRelocatesToStart ? {
3111
+ moved: {
3112
+ root: start,
3113
+ display: "."
3114
+ },
3115
+ emptied: variable
3116
+ } : {};
3117
+ }
3118
+ function locate(home, scope, { moved }, path) {
3119
+ if (!moved || path !== scope.detect && !path.startsWith(`${scope.detect}/`)) return {
3120
+ absolute: join(home, path),
3121
+ display: `~/${path}`
3122
+ };
3123
+ const rest = path.slice(scope.detect.length);
3124
+ return {
3125
+ absolute: join(moved.root, rest),
3126
+ display: `${moved.display}${rest}`
3127
+ };
3128
+ }
3129
+ /** A shadow is read only where it is a file holding more than whitespace (E-CODEX-06). */
3130
+ function readsAsShadow(path) {
3131
+ try {
3132
+ return statSync(path).isFile() && readFileSync(path, "utf8").trim() !== "";
3133
+ } catch {
3134
+ return false;
3135
+ }
3136
+ }
3137
+ function inspect$1(home, target, bridge) {
3138
+ let stats;
3139
+ try {
3140
+ stats = lstatSync(target);
3141
+ } catch {
3142
+ return {
3143
+ kind: "none",
3144
+ status: "missing",
3145
+ problem: "global-instructions-missing"
3146
+ };
3147
+ }
3148
+ if (stats.isSymbolicLink()) return resolve(dirname(target), readlinkSync(target)) === join(home, ".agents/AGENTS.md") ? {
3149
+ kind: "symlink",
3150
+ status: "ok"
3151
+ } : {
3152
+ kind: "symlink",
3153
+ status: "unbridged",
3154
+ problem: "global-instructions-unbridged"
3155
+ };
3156
+ let body;
3157
+ try {
3158
+ body = readFileSync(target, "utf8");
3159
+ } catch {
3160
+ return {
3161
+ kind: "file",
3162
+ status: "unbridged",
3163
+ problem: "global-instructions-unbridged"
3164
+ };
3165
+ }
3166
+ return importsGlobal(body, bridge, home) ? {
3167
+ kind: "import",
3168
+ status: "ok"
3169
+ } : {
3170
+ kind: "file",
3171
+ status: "unbridged",
3172
+ problem: "global-instructions-unbridged"
3173
+ };
3174
+ }
3175
+ function finding(path, problem, cli) {
3176
+ const { detail, repair } = repairFor(problem);
3177
+ return {
3178
+ path,
3179
+ problem,
3180
+ detail,
3181
+ repair: repair({ file: path }, cli)
3182
+ };
3183
+ }
3184
+ /**
3185
+ * Whether each harness the user has installed loads `~/.agents/AGENTS.md` through its own user-scope
3186
+ * file, read from wherever `env` moves it — `start`, for a harness that reads an empty variable as
3187
+ * the directory it starts in. Read-only: the repair is handed to the user, since nothing here
3188
+ * writes outside the repository.
3189
+ */
3190
+ function diagnoseGlobalInstructions(home, preferred, cli, env = {}, start = process.cwd()) {
3191
+ const hasGlobal = exists$1(join(home, globalInstructions));
3192
+ const rows = [];
3193
+ const findings = [];
3194
+ for (const harness of harnessRegistry) {
3195
+ const user = harness.user;
3196
+ const bridge = user?.instructionBridge;
3197
+ if (!user || !bridge) continue;
3198
+ const moved = base(user, env, start);
3199
+ if (!preferred.includes(harness.name) && !isDirectory$1(locate(home, user, moved, user.detect).absolute)) continue;
3200
+ const file = locate(home, user, moved, bridge.path);
3201
+ const inspection = inspect$1(home, file.absolute, bridge);
3202
+ const shadow = (user.shadowedBy ?? []).map((path) => locate(home, user, moved, path)).find(({ absolute }) => readsAsShadow(absolute));
3203
+ if (shadow !== void 0) {
3204
+ const read = inspect$1(home, shadow.absolute, bridge);
3205
+ if (read.status === "ok") {
3206
+ rows.push({
3207
+ harness: harness.name,
3208
+ path: shadow.display,
3209
+ kind: read.kind,
3210
+ status: "ok"
3211
+ });
3212
+ continue;
3213
+ }
3214
+ rows.push({
3215
+ harness: harness.name,
3216
+ path: file.display,
3217
+ kind: inspection.kind,
3218
+ status: "overridden"
3219
+ });
3220
+ if (hasGlobal) findings.push(finding(shadow.display, "global-instructions-overridden", cli));
3221
+ } else rows.push({
3222
+ harness: harness.name,
3223
+ path: file.display,
3224
+ kind: inspection.kind,
3225
+ status: inspection.status
3226
+ });
3227
+ if (hasGlobal && moved.emptied) findings.push(finding(`$${moved.emptied}`, "global-instructions-emptied", cli));
3228
+ else if (hasGlobal && inspection.problem) findings.push(finding(file.display, inspection.problem, cli));
3229
+ }
3230
+ return {
3231
+ globalInstructions: rows,
3232
+ findings
3233
+ };
3234
+ }
3235
+ //#endregion
2981
3236
  //#region src/diagnose-bridges/agents-files.ts
2982
3237
  /** Directories that never hold instructions this repository is responsible for bridging. */
2983
3238
  const pruned = /* @__PURE__ */ new Set(["node_modules"]);
@@ -3092,7 +3347,7 @@ function diagnoseInstructions(root, harnesses, cli) {
3092
3347
  const bridged = harnesses.map((harness) => ({
3093
3348
  name: harness.name,
3094
3349
  bridge: harness.project.instructionBridge
3095
- })).filter((harness) => Boolean(harness.bridge));
3350
+ })).filter((harness) => harness.bridge?.kind === "settings-entry");
3096
3351
  const instructions = [];
3097
3352
  const findings = [];
3098
3353
  const directories = agentsFileDirectories(root);
@@ -3348,7 +3603,7 @@ function inspect(target, path, canonical, git) {
3348
3603
  * Read-only: nothing is created, moved, or repaired — the caller decides what to run from the
3349
3604
  * repair each finding carries.
3350
3605
  */
3351
- function diagnoseBridges({ root, harnesses: preferred = [], cli }) {
3606
+ function diagnoseBridges({ root, harnesses: preferred = [], cli, home, env }) {
3352
3607
  const canonical = join(root, ".agents", "skills");
3353
3608
  const git = new GitBridgeState(root);
3354
3609
  const selected = selectHarnesses(root, preferred);
@@ -3393,9 +3648,15 @@ function diagnoseBridges({ root, harnesses: preferred = [], cli }) {
3393
3648
  }
3394
3649
  const instructions = diagnoseInstructions(root, selected, cli);
3395
3650
  findings.push(...instructions.findings);
3651
+ const global = home === void 0 ? {
3652
+ globalInstructions: [],
3653
+ findings: []
3654
+ } : diagnoseGlobalInstructions(home, preferred, cli, env, root);
3655
+ findings.push(...global.findings);
3396
3656
  return {
3397
3657
  bridges,
3398
3658
  instructions: instructions.instructions,
3659
+ globalInstructions: global.globalInstructions,
3399
3660
  divergence,
3400
3661
  findings
3401
3662
  };
@@ -3416,6 +3677,7 @@ function buildDoctorReport(bin, result, configuration = [], held = []) {
3416
3677
  bin,
3417
3678
  bridges: result.bridges,
3418
3679
  instructions: result.instructions,
3680
+ globalInstructions: result.globalInstructions,
3419
3681
  references,
3420
3682
  findings: `0 problems found — ${bridges} and the configuration around them is current`
3421
3683
  };
@@ -3424,6 +3686,7 @@ function buildDoctorReport(bin, result, configuration = [], held = []) {
3424
3686
  bin,
3425
3687
  bridges: result.bridges,
3426
3688
  instructions: result.instructions,
3689
+ globalInstructions: result.globalInstructions,
3427
3690
  references,
3428
3691
  ...result.divergence.length ? { divergence: result.divergence } : {},
3429
3692
  findings: findings.map(({ path, problem, detail }) => ({
@@ -3436,7 +3699,7 @@ function buildDoctorReport(bin, result, configuration = [], held = []) {
3436
3699
  }
3437
3700
  const doctorCommand = command({
3438
3701
  name: "doctor",
3439
- description: "Report whether this repository's harness bridges still resolve — skills into .agents/skills, instructions into AGENTS.md. Read-only.",
3702
+ 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
3703
  options: {
3441
3704
  root: {
3442
3705
  description: "Repository or package directory. Defaults to the current directory.",
@@ -3461,7 +3724,9 @@ const doctorCommand = command({
3461
3724
  const result = diagnoseBridges({
3462
3725
  root,
3463
3726
  ...harnesses.length ? { harnesses } : {},
3464
- cli: commandInvocation
3727
+ cli: commandInvocation,
3728
+ home,
3729
+ env: process.env
3465
3730
  });
3466
3731
  const git = new GitBridgeState(root);
3467
3732
  const configuration = [
@@ -5190,6 +5455,6 @@ function listMcpServers(options) {
5190
5455
  return entries;
5191
5456
  }
5192
5457
  //#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 };
5458
+ 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
5459
 
5195
5460
  //# sourceMappingURL=index.mjs.map