nexus-agents 8.111.0 → 8.112.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/dist/{ast-rule-runner-ZO3T66KP.js → ast-rule-runner-Y7JYRYIJ.js} +3 -3
- package/dist/{child-mcp-config-M4MRFMP3.js → child-mcp-config-T5ACQOUC.js} +2 -2
- package/dist/{chunk-UMESP2HX.js → chunk-22ORLI5U.js} +2 -2
- package/dist/{chunk-UPVOYMYO.js → chunk-2IIJQIMM.js} +13 -12
- package/dist/chunk-2IIJQIMM.js.map +1 -0
- package/dist/{chunk-NBSI5ICR.js → chunk-2T6Q3JTZ.js} +3 -3
- package/dist/{chunk-SARPPCY5.js → chunk-4YGPA6RY.js} +2 -2
- package/dist/{chunk-J2QYPARH.js → chunk-56BNVEYR.js} +2 -2
- package/dist/{chunk-6ECPHGKC.js → chunk-5U5MRUIO.js} +4 -4
- package/dist/{chunk-C4OZ4F67.js → chunk-6UI734G5.js} +5 -5
- package/dist/{chunk-YLQNJAJP.js → chunk-7MDXMFP7.js} +2 -2
- package/dist/{chunk-22AF7TYV.js → chunk-7OID2D3X.js} +2 -2
- package/dist/{chunk-O4QDBQI6.js → chunk-A6MJ5OT5.js} +2 -2
- package/dist/{chunk-JRDNNCM7.js → chunk-AXTUSOO2.js} +5 -5
- package/dist/{chunk-METD44P2.js → chunk-BD7DK7WH.js} +2 -2
- package/dist/{chunk-4QWRKVJS.js → chunk-CPZ6OYZV.js} +3 -3
- package/dist/{chunk-JFTSRUO3.js → chunk-DVGHZMUL.js} +61 -53
- package/dist/{chunk-JFTSRUO3.js.map → chunk-DVGHZMUL.js.map} +1 -1
- package/dist/{chunk-D6LZY3W7.js → chunk-EBWQVNA2.js} +2 -2
- package/dist/{chunk-RIF7TUYH.js → chunk-FDASKOC7.js} +681 -507
- package/dist/chunk-FDASKOC7.js.map +1 -0
- package/dist/{chunk-ZEDLXDDY.js → chunk-GG3UPYQC.js} +2 -2
- package/dist/{chunk-OM4JSIPB.js → chunk-H4NYL266.js} +2 -2
- package/dist/{chunk-FE2VYSSA.js → chunk-HWFC5ASC.js} +2 -2
- package/dist/{chunk-J2JGTORM.js → chunk-JEAVQI3X.js} +2 -2
- package/dist/{chunk-DNXEQKBR.js → chunk-JKAJK3GA.js} +2 -2
- package/dist/{chunk-CX3YZ4S6.js → chunk-JSHF2KFP.js} +48 -21
- package/dist/chunk-JSHF2KFP.js.map +1 -0
- package/dist/{chunk-ZTOTKIAO.js → chunk-K42UETAL.js} +5 -91
- package/dist/chunk-K42UETAL.js.map +1 -0
- package/dist/{chunk-AQZHRX7L.js → chunk-LOUQYL7L.js} +3 -3
- package/dist/{chunk-FRBFTFSQ.js → chunk-O7JOVLLY.js} +4 -4
- package/dist/{chunk-GCQLEDCY.js → chunk-OYV7SZGV.js} +5 -5
- package/dist/{chunk-52T77E5J.js → chunk-PQLW4ZXT.js} +14 -16
- package/dist/{chunk-52T77E5J.js.map → chunk-PQLW4ZXT.js.map} +1 -1
- package/dist/{chunk-G4UBTYE3.js → chunk-QIRFVULH.js} +3 -3
- package/dist/chunk-QIRFVULH.js.map +1 -0
- package/dist/{chunk-U5TT4C5O.js → chunk-THB3IYJX.js} +2 -2
- package/dist/{chunk-BJJOZV7O.js → chunk-TSDOTP53.js} +5 -5
- package/dist/{chunk-BE6L6MIE.js → chunk-U5K4FVMI.js} +4 -4
- package/dist/{chunk-5O4KT2WO.js → chunk-VOKK274H.js} +2 -2
- package/dist/{chunk-WKNSD7YL.js → chunk-WO2QMQUG.js} +20 -33
- package/dist/chunk-WO2QMQUG.js.map +1 -0
- package/dist/{chunk-CDPPWCGO.js → chunk-XIUCWV2L.js} +2 -2
- package/dist/{chunk-GDUB2OE4.js → chunk-YFNDV7FJ.js} +2 -2
- package/dist/{chunk-CGPKV4KH.js → chunk-ZNBVTWQX.js} +6 -6
- package/dist/{cli-circuit-breaker-FVO43RVL.js → cli-circuit-breaker-WIMKRL7H.js} +3 -3
- package/dist/cli.js +51 -47
- package/dist/cli.js.map +1 -1
- package/dist/{composite-router-SJVN7OB4.js → composite-router-JDU5RLVX.js} +2 -2
- package/dist/{consensus-vote-YUVLW5S4.js → consensus-vote-X5QSYJRA.js} +18 -18
- package/dist/{context-retriever-SONR6BIO.js → context-retriever-UZKQCWZY.js} +8 -8
- package/dist/{doctor-deep-KRSLLEPY.js → doctor-deep-TMRXDBKM.js} +3 -3
- package/dist/doctor-gateway-report-IH5SXTJS.js +17 -0
- package/dist/{doctor-live-XPJKPSRM.js → doctor-live-6HWHQ2WN.js} +23 -16
- package/dist/doctor-live-6HWHQ2WN.js.map +1 -0
- package/dist/{expert-bridge-R4AM2VPK.js → expert-bridge-HPMKPJFI.js} +5 -5
- package/dist/{factory-G7SSRQET.js → factory-PYFGNN5R.js} +5 -5
- package/dist/{factory-KHLGIPPZ.js → factory-QHGZKNBZ.js} +10 -10
- package/dist/{improvement-review-MCGHC4LL.js → improvement-review-2RVAMHCY.js} +6 -6
- package/dist/index.d.ts +13 -5
- package/dist/index.js +33 -33
- package/dist/{init-opencode-GVENWYH4.js → init-opencode-DO36MEWH.js} +6 -6
- package/dist/{issue-triage-CS4WXPIE.js → issue-triage-I2FL44CG.js} +6 -6
- package/dist/{openai-compat-adapter-CUETEQEQ.js → openai-compat-adapter-3Q7FLYBM.js} +6 -6
- package/dist/{pr-reviewer-helpers-FGON5RFG.js → pr-reviewer-helpers-EHQ4Z7L6.js} +4 -4
- package/dist/{registry-command-CARW7JBG.js → registry-command-MP57K2IU.js} +2 -2
- package/dist/{repo-security-plan-4KAW7ELW.js → repo-security-plan-EW2Z4UYX.js} +3 -3
- package/dist/{research-helpers-synthesize-CYO2YUAE.js → research-helpers-synthesize-2ORWR7IO.js} +4 -4
- package/dist/{routing-memory-SFXZODKG.js → routing-memory-7YDZMCBP.js} +2 -2
- package/dist/{session-memory-5DAEGAX5.js → session-memory-YWUVRCF7.js} +3 -3
- package/dist/{setup-config-J6YHOKO3.js → setup-config-56WKB7QE.js} +3 -3
- package/dist/{setup-custom-api-4XKOPRRP.js → setup-custom-api-TO2GWNSV.js} +4 -4
- package/dist/setup-data-dir-4ONA7QX7.js +34 -0
- package/dist/{tool-memory-YBFEA2W5.js → tool-memory-2JWYUQPL.js} +5 -5
- package/dist/{unified-registry-S7L5SYG2.js → unified-registry-QCVJ5M2A.js} +12 -12
- package/dist/{weather-report-MVSIUA23.js → weather-report-ERRSDDVB.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-CX3YZ4S6.js.map +0 -1
- package/dist/chunk-G4UBTYE3.js.map +0 -1
- package/dist/chunk-RIF7TUYH.js.map +0 -1
- package/dist/chunk-UPVOYMYO.js.map +0 -1
- package/dist/chunk-WKNSD7YL.js.map +0 -1
- package/dist/chunk-ZTOTKIAO.js.map +0 -1
- package/dist/doctor-gateway-report-N4H4LV2Q.js +0 -17
- package/dist/doctor-live-XPJKPSRM.js.map +0 -1
- package/dist/setup-data-dir-XKF4OJGK.js +0 -34
- /package/dist/{ast-rule-runner-ZO3T66KP.js.map → ast-rule-runner-Y7JYRYIJ.js.map} +0 -0
- /package/dist/{child-mcp-config-M4MRFMP3.js.map → child-mcp-config-T5ACQOUC.js.map} +0 -0
- /package/dist/{chunk-UMESP2HX.js.map → chunk-22ORLI5U.js.map} +0 -0
- /package/dist/{chunk-NBSI5ICR.js.map → chunk-2T6Q3JTZ.js.map} +0 -0
- /package/dist/{chunk-SARPPCY5.js.map → chunk-4YGPA6RY.js.map} +0 -0
- /package/dist/{chunk-J2QYPARH.js.map → chunk-56BNVEYR.js.map} +0 -0
- /package/dist/{chunk-6ECPHGKC.js.map → chunk-5U5MRUIO.js.map} +0 -0
- /package/dist/{chunk-C4OZ4F67.js.map → chunk-6UI734G5.js.map} +0 -0
- /package/dist/{chunk-YLQNJAJP.js.map → chunk-7MDXMFP7.js.map} +0 -0
- /package/dist/{chunk-22AF7TYV.js.map → chunk-7OID2D3X.js.map} +0 -0
- /package/dist/{chunk-O4QDBQI6.js.map → chunk-A6MJ5OT5.js.map} +0 -0
- /package/dist/{chunk-JRDNNCM7.js.map → chunk-AXTUSOO2.js.map} +0 -0
- /package/dist/{chunk-METD44P2.js.map → chunk-BD7DK7WH.js.map} +0 -0
- /package/dist/{chunk-4QWRKVJS.js.map → chunk-CPZ6OYZV.js.map} +0 -0
- /package/dist/{chunk-D6LZY3W7.js.map → chunk-EBWQVNA2.js.map} +0 -0
- /package/dist/{chunk-ZEDLXDDY.js.map → chunk-GG3UPYQC.js.map} +0 -0
- /package/dist/{chunk-OM4JSIPB.js.map → chunk-H4NYL266.js.map} +0 -0
- /package/dist/{chunk-FE2VYSSA.js.map → chunk-HWFC5ASC.js.map} +0 -0
- /package/dist/{chunk-J2JGTORM.js.map → chunk-JEAVQI3X.js.map} +0 -0
- /package/dist/{chunk-DNXEQKBR.js.map → chunk-JKAJK3GA.js.map} +0 -0
- /package/dist/{chunk-AQZHRX7L.js.map → chunk-LOUQYL7L.js.map} +0 -0
- /package/dist/{chunk-FRBFTFSQ.js.map → chunk-O7JOVLLY.js.map} +0 -0
- /package/dist/{chunk-GCQLEDCY.js.map → chunk-OYV7SZGV.js.map} +0 -0
- /package/dist/{chunk-U5TT4C5O.js.map → chunk-THB3IYJX.js.map} +0 -0
- /package/dist/{chunk-BJJOZV7O.js.map → chunk-TSDOTP53.js.map} +0 -0
- /package/dist/{chunk-BE6L6MIE.js.map → chunk-U5K4FVMI.js.map} +0 -0
- /package/dist/{chunk-5O4KT2WO.js.map → chunk-VOKK274H.js.map} +0 -0
- /package/dist/{chunk-CDPPWCGO.js.map → chunk-XIUCWV2L.js.map} +0 -0
- /package/dist/{chunk-GDUB2OE4.js.map → chunk-YFNDV7FJ.js.map} +0 -0
- /package/dist/{chunk-CGPKV4KH.js.map → chunk-ZNBVTWQX.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-FVO43RVL.js.map → cli-circuit-breaker-WIMKRL7H.js.map} +0 -0
- /package/dist/{composite-router-SJVN7OB4.js.map → composite-router-JDU5RLVX.js.map} +0 -0
- /package/dist/{consensus-vote-YUVLW5S4.js.map → consensus-vote-X5QSYJRA.js.map} +0 -0
- /package/dist/{context-retriever-SONR6BIO.js.map → context-retriever-UZKQCWZY.js.map} +0 -0
- /package/dist/{doctor-deep-KRSLLEPY.js.map → doctor-deep-TMRXDBKM.js.map} +0 -0
- /package/dist/{doctor-gateway-report-N4H4LV2Q.js.map → doctor-gateway-report-IH5SXTJS.js.map} +0 -0
- /package/dist/{expert-bridge-R4AM2VPK.js.map → expert-bridge-HPMKPJFI.js.map} +0 -0
- /package/dist/{factory-G7SSRQET.js.map → factory-PYFGNN5R.js.map} +0 -0
- /package/dist/{factory-KHLGIPPZ.js.map → factory-QHGZKNBZ.js.map} +0 -0
- /package/dist/{improvement-review-MCGHC4LL.js.map → improvement-review-2RVAMHCY.js.map} +0 -0
- /package/dist/{init-opencode-GVENWYH4.js.map → init-opencode-DO36MEWH.js.map} +0 -0
- /package/dist/{issue-triage-CS4WXPIE.js.map → issue-triage-I2FL44CG.js.map} +0 -0
- /package/dist/{openai-compat-adapter-CUETEQEQ.js.map → openai-compat-adapter-3Q7FLYBM.js.map} +0 -0
- /package/dist/{pr-reviewer-helpers-FGON5RFG.js.map → pr-reviewer-helpers-EHQ4Z7L6.js.map} +0 -0
- /package/dist/{registry-command-CARW7JBG.js.map → registry-command-MP57K2IU.js.map} +0 -0
- /package/dist/{repo-security-plan-4KAW7ELW.js.map → repo-security-plan-EW2Z4UYX.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-CYO2YUAE.js.map → research-helpers-synthesize-2ORWR7IO.js.map} +0 -0
- /package/dist/{routing-memory-SFXZODKG.js.map → routing-memory-7YDZMCBP.js.map} +0 -0
- /package/dist/{session-memory-5DAEGAX5.js.map → session-memory-YWUVRCF7.js.map} +0 -0
- /package/dist/{setup-config-J6YHOKO3.js.map → setup-config-56WKB7QE.js.map} +0 -0
- /package/dist/{setup-custom-api-4XKOPRRP.js.map → setup-custom-api-TO2GWNSV.js.map} +0 -0
- /package/dist/{setup-data-dir-XKF4OJGK.js.map → setup-data-dir-4ONA7QX7.js.map} +0 -0
- /package/dist/{tool-memory-YBFEA2W5.js.map → tool-memory-2JWYUQPL.js.map} +0 -0
- /package/dist/{unified-registry-S7L5SYG2.js.map → unified-registry-QCVJ5M2A.js.map} +0 -0
- /package/dist/{weather-report-MVSIUA23.js.map → weather-report-ERRSDDVB.js.map} +0 -0
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
getBuiltInAstRulesPath,
|
|
10
10
|
loadRules,
|
|
11
11
|
runAstQaRules
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-XIUCWV2L.js";
|
|
13
13
|
import "./chunk-XEPZSDN5.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-FDASKOC7.js";
|
|
15
15
|
import "./chunk-UE7A2XHM.js";
|
|
16
16
|
import "./chunk-LWOX65CP.js";
|
|
17
17
|
import "./chunk-PX6F3LHL.js";
|
|
@@ -27,4 +27,4 @@ export {
|
|
|
27
27
|
loadRules,
|
|
28
28
|
runAstQaRules
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=ast-rule-runner-
|
|
30
|
+
//# sourceMappingURL=ast-rule-runner-Y7JYRYIJ.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-OITVVSWO.js";
|
|
4
4
|
import {
|
|
5
5
|
createLogger
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FDASKOC7.js";
|
|
7
7
|
import "./chunk-UE7A2XHM.js";
|
|
8
8
|
import "./chunk-LWOX65CP.js";
|
|
9
9
|
import "./chunk-PX6F3LHL.js";
|
|
@@ -56,4 +56,4 @@ async function generateMcpConfig(options) {
|
|
|
56
56
|
export {
|
|
57
57
|
generateMcpConfig
|
|
58
58
|
};
|
|
59
|
-
//# sourceMappingURL=child-mcp-config-
|
|
59
|
+
//# sourceMappingURL=child-mcp-config-T5ACQOUC.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getErrorMessage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FDASKOC7.js";
|
|
4
4
|
|
|
5
5
|
// src/cli/setup-config.ts
|
|
6
6
|
import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
@@ -77,4 +77,4 @@ function ensureBackup(outputPath) {
|
|
|
77
77
|
export {
|
|
78
78
|
runConfigInitSync
|
|
79
79
|
};
|
|
80
|
-
//# sourceMappingURL=chunk-
|
|
80
|
+
//# sourceMappingURL=chunk-22ORLI5U.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SERVES_PROBE_PROMPT
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QIRFVULH.js";
|
|
4
4
|
import {
|
|
5
5
|
checkGatewayHealth,
|
|
6
6
|
cliFailsVerdict,
|
|
@@ -8,22 +8,22 @@ import {
|
|
|
8
8
|
gatewaySlotServing,
|
|
9
9
|
gatewayVerdict,
|
|
10
10
|
printVoterTransportCheck
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-6UI734G5.js";
|
|
12
12
|
import {
|
|
13
13
|
NODE_ENGINE_RANGE,
|
|
14
14
|
VERSION,
|
|
15
15
|
isNodeVersionSupported
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-JEAVQI3X.js";
|
|
17
17
|
import {
|
|
18
18
|
allOf
|
|
19
19
|
} from "./chunk-EZNIYU5T.js";
|
|
20
20
|
import {
|
|
21
21
|
readOpenAICompatEndpoint,
|
|
22
22
|
readOpenAICompatEnv
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-TSDOTP53.js";
|
|
24
24
|
import {
|
|
25
25
|
claimGlobalRegistry
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-ZNBVTWQX.js";
|
|
27
27
|
import {
|
|
28
28
|
capitalize
|
|
29
29
|
} from "./chunk-SX5DB6UR.js";
|
|
@@ -35,10 +35,10 @@ import {
|
|
|
35
35
|
createAllAdapters,
|
|
36
36
|
isCliAdmitted,
|
|
37
37
|
probeCli
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-WO2QMQUG.js";
|
|
39
39
|
import {
|
|
40
40
|
resolveGatewayEnv
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-JKAJK3GA.js";
|
|
42
42
|
import {
|
|
43
43
|
getNexusTmpDir
|
|
44
44
|
} from "./chunk-OITVVSWO.js";
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
resolveGatewayCostDeclaration,
|
|
64
64
|
symbols,
|
|
65
65
|
writeLine
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-FDASKOC7.js";
|
|
67
67
|
import {
|
|
68
68
|
getLearningDir,
|
|
69
69
|
getOutcomesFile,
|
|
@@ -1383,9 +1383,10 @@ async function runDoctor(deps = {}) {
|
|
|
1383
1383
|
}
|
|
1384
1384
|
async function doctorCommand(options = {}) {
|
|
1385
1385
|
const result = await runDoctor({ gatewayProbe: options.probe === true });
|
|
1386
|
+
options.onResult?.(result);
|
|
1386
1387
|
printDoctorResults(result);
|
|
1387
1388
|
if (options.gateway === true || options.probe === true) {
|
|
1388
|
-
const { formatGatewayReport } = await import("./doctor-gateway-report-
|
|
1389
|
+
const { formatGatewayReport } = await import("./doctor-gateway-report-IH5SXTJS.js");
|
|
1389
1390
|
for (const line of formatGatewayReport(result.gateway, result.clis)) {
|
|
1390
1391
|
process.stdout.write(line + "\n");
|
|
1391
1392
|
}
|
|
@@ -1404,13 +1405,13 @@ async function runDoctorFix(result) {
|
|
|
1404
1405
|
writeLine2("\u2500".repeat(40));
|
|
1405
1406
|
let fixCount = 0;
|
|
1406
1407
|
if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
|
|
1407
|
-
const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-
|
|
1408
|
+
const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-4ONA7QX7.js");
|
|
1408
1409
|
const outcome = describeDataDirFix2(initDataDirectories2());
|
|
1409
1410
|
writeLine2(outcome.line);
|
|
1410
1411
|
if (outcome.counted) fixCount++;
|
|
1411
1412
|
}
|
|
1412
1413
|
if (!result.configFile.found) {
|
|
1413
|
-
const { runConfigInitSync } = await import("./setup-config-
|
|
1414
|
+
const { runConfigInitSync } = await import("./setup-config-56WKB7QE.js");
|
|
1414
1415
|
const configResult = runConfigInitSync(process.cwd(), false, false);
|
|
1415
1416
|
if (configResult.success && configResult.created) {
|
|
1416
1417
|
writeLine2(`\u2713 Generated config: ${configResult.path}`);
|
|
@@ -1506,4 +1507,4 @@ export {
|
|
|
1506
1507
|
startStdioServer,
|
|
1507
1508
|
closeServer
|
|
1508
1509
|
};
|
|
1509
|
-
//# sourceMappingURL=chunk-
|
|
1510
|
+
//# sourceMappingURL=chunk-2IIJQIMM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/setup-data-dir.ts","../src/cli/doctor.ts","../src/cli/doctor-scratch-space.ts","../src/mcp/server.ts","../src/mcp/task-store.ts","../src/cli/doctor-claude-model.ts","../src/cli/doctor-disabled-clis.ts","../src/cli/doctor-mcp-client.ts","../src/cli/doctor-install-freshness.ts","../src/cli/doctor-verdict-terms.ts","../src/cli/doctor-formatting.ts","../src/cli/doctor-harness-alignment.ts"],"sourcesContent":["/**\n * nexus-agents data directory initialization\n *\n * Pre-creates the nexus-agents data directory structure (per-repo +\n * cross-repo roots per epic #2872) with proper permissions.\n * Used by `nexus-agents setup` to ensure data directories exist before first use.\n *\n * @module cli/setup-data-dir\n * (Source: Issue #1249 - Developer experience improvements)\n */\n\nimport { mkdirSync, existsSync } from 'node:fs';\nimport { DATA_SUBDIRECTORIES } from './doctor.js';\nimport { getNexusDataDir, nexusDataPath } from '../config/nexus-data-dir.js';\n\n/**\n * Homedir/cross-repo root data directory path.\n *\n * Resolves to `$NEXUS_DATA_DIR` when set, else `<homedir>/.nexus-agents`.\n * See `src/config/nexus-data-dir.ts` for resolution rules (#2302).\n *\n * Evaluated at module-import time. Tests that mutate `NEXUS_DATA_DIR`\n * mid-process should call `resetNexusDataDirCache()` and re-import, or\n * call `getNexusDataDir()` directly.\n *\n * NOTE: this is the cross-repo root ONLY. Per-repo subdirs (sessions,\n * checkpoints, audit, …) resolve to `<repo>/.nexus-agents/`;\n * `initDataDirectories()` routes each subdir through `nexusDataPath()`\n * so the per-repo split from epic #2872 is honored. Issue #2889.\n */\nexport const NEXUS_DATA_DIR = getNexusDataDir();\n\n/** Subdirectories requiring restricted permissions (owner-only). */\nconst RESTRICTED_DIRS = new Set(['auth']);\n\n/**\n * Result of data directory initialization.\n */\nexport interface DataDirInitResult {\n readonly success: boolean;\n readonly rootPath: string;\n readonly created: readonly string[];\n readonly alreadyExisted: readonly string[];\n readonly error: string | null;\n}\n\n/**\n * Creates the nexus-agents data directory structure. Each subdir is\n * routed through `nexusDataPath()` — per-repo subdirs land in\n * `<repo>/.nexus-agents/`, cross-repo subdirs in `~/.nexus-agents/`.\n * Sets restrictive permissions (0o700) on auth/ directory.\n *\n * @param dryRun - If true, reports what would be created without creating.\n * @returns Result of initialization.\n */\nexport function initDataDirectories(dryRun: boolean = false): DataDirInitResult {\n const created: string[] = [];\n const alreadyExisted: string[] = [];\n const failures: string[] = [];\n\n // No explicit root ensureDir: recursive mkdir of each subdir creates\n // its parent root. Crucially, NOT creating the homedir root up-front\n // means a read-only-homedir sandbox doesn't abort here before the\n // per-repo subdirs (which ARE writable) get a chance. Issue #2895.\n for (const subdir of DATA_SUBDIRECTORIES) {\n const mode = RESTRICTED_DIRS.has(subdir) ? 0o700 : undefined;\n // Route through nexusDataPath() so per-repo subdirs (sessions,\n // checkpoints, audit, …) land in `<repo>/.nexus-agents/`, cross-repo\n // subdirs in homedir, and cross-repo subdirs fall back per-repo when\n // homedir is unwritable (#2888). Split on '/' so the routing key is\n // the true first segment (e.g. 'memory/beliefs' → 'memory').\n const target = nexusDataPath(...subdir.split('/'));\n // Per-subdir failure is non-fatal: one unwritable location must not\n // abort the others. Genuinely-broken environments surface as a\n // non-empty `failures` list rather than a thrown exception.\n try {\n ensureDir(target, dryRun, created, alreadyExisted, mode);\n } catch (error: unknown) {\n failures.push(`${target}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n if (failures.length > 0) {\n return {\n success: false,\n rootPath: NEXUS_DATA_DIR,\n created,\n alreadyExisted,\n error: `Failed to create ${String(failures.length)} dir(s): ${failures.join('; ')}`,\n };\n }\n return { success: true, rootPath: NEXUS_DATA_DIR, created, alreadyExisted, error: null };\n}\n\n/** Creates a single directory if it doesn't exist, tracking the result. */\nfunction ensureDir(\n dirPath: string,\n dryRun: boolean,\n created: string[],\n alreadyExisted: string[],\n mode?: number\n): void {\n if (existsSync(dirPath)) {\n alreadyExisted.push(dirPath);\n return;\n }\n if (!dryRun) {\n mkdirSync(dirPath, { recursive: true, ...(mode !== undefined ? { mode } : {}) });\n }\n created.push(dirPath);\n}\n\n/** What `doctor --fix` should report after asking setup to create data dirs. */\ninterface DataDirFixOutcome {\n /** Operator-facing line. */\n readonly line: string;\n /** Whether this counts toward \"N issue(s) fixed\". */\n readonly counted: boolean;\n}\n\n/**\n * Turn a data-directory init result into an honest `doctor --fix` report (#4851).\n *\n * `doctor --fix` runs this step when a subdirectory is missing OR not writable,\n * then printed \"✓ Created missing data directories\" and incremented the fix\n * count on `success` alone. But `ensureDir` returns early for a path that\n * already exists and never checks writability, so an existing-but-unwritable\n * directory lands in `alreadyExisted`, `failures` stays empty, and `success` is\n * true — doctor claimed a fix for precisely the condition that triggered it,\n * having created nothing.\n *\n * `created.length` is the only thing that distinguishes the two, and it was\n * already on the result.\n */\nexport function describeDataDirFix(result: DataDirInitResult): DataDirFixOutcome {\n if (!result.success) {\n return {\n line: `✗ Could not create data directories: ${result.error ?? 'unknown error'}`,\n counted: false,\n };\n }\n if (result.created.length === 0) {\n return {\n line:\n '✗ Data directories already exist but are not writable — setup creates missing ' +\n 'directories and cannot repair permissions. Fix them manually (chmod u+w).',\n counted: false,\n };\n }\n return {\n line: `✓ Created ${String(result.created.length)} missing data director${result.created.length === 1 ? 'y' : 'ies'}`,\n counted: true,\n };\n}\n","/* eslint-disable max-lines -- Cohesive doctor command module (governance: 400-600 OK if cohesive) */\n/**\n * nexus-agents doctor command\n *\n * Health check utility for CLI integration validation.\n * Verifies CLI installations, versions, authentication, Node.js version,\n * API keys, configuration files, and MCP server readiness.\n *\n * (Source: Issue #91, cli-project_plan.md DevEx amendment)\n * (Source: Issue #422 - Doctor command validations)\n */\n\nimport {\n existsSync,\n readFileSync,\n readdirSync,\n accessSync,\n constants as fsConstants,\n} from 'node:fs';\nimport {\n getNexusDataDir,\n getNexusRepoDir,\n getPerRepoSubdirs,\n nexusDataPath,\n} from '../config/nexus-data-dir.js';\nimport { detectSandbox } from '../config/sandbox-detection.js';\nimport {\n checkScratchFilesystems,\n worstSeverity,\n type ScratchSpaceCheck,\n scratchSeverityIsAcceptable,\n} from './doctor-scratch-space.js';\nimport { getTimeProvider, getErrorMessage } from '../core/index.js';\nimport {\n isPersistenceEnabled,\n getLearningDir,\n getOutcomesFile,\n getRulesFile,\n} from '../config/learning-persistence.js';\nimport {\n countEligibleOutcomesInFile,\n countRoutedOutcomesInFile,\n type RoutedOutcomeCounts,\n} from '../learning/distiller-eligibility.js';\nimport { createAllAdapters } from '../cli-adapters/factory.js';\nimport { isCliAdmitted } from '../cli-adapters/cli-admission.js';\nimport { isCliDisabled } from '../cli-adapters/disabled-clis.js';\nimport { codexMcpServerAvailable } from '../cli-adapters/codex-mcp-server-probe.js';\nimport type { CliName, HealthStatus, CapacityStatus } from '../cli-adapters/types.js';\nimport { getInTreeCapabilitiesMatrix } from '../config/model-config-helpers.js';\nimport { createServer } from '../mcp/server.js';\nimport {\n readOpenAICompatEndpoint,\n readOpenAICompatEnv,\n} from '../adapters/openai-compat-adapter.js';\nimport { resolveGatewayEnv, type DeprecatedGatewayEnvUse } from '../adapters/sdk/gateway-env.js';\nimport {\n gatewayCostStatus,\n resolveGatewayCostDeclaration,\n type GatewayCostDeclaration,\n} from '../adapters/sdk/gateway-cost.js';\nimport { printDoctorResults } from './doctor-formatting.js';\nimport { disabledCliModelReason } from './doctor-disabled-clis.js';\nimport { probeCli } from './cli-auth-probe.js';\nimport { probeClaudePinnedModel, type ClaudeModelProbe } from './doctor-claude-model.js';\nimport type { AuthProbeResult } from './cli-auth-probe.js';\nimport { checkHarnessAlignment } from './doctor-harness-alignment.js';\nimport type { HarnessAlignmentCheck } from './doctor-harness-alignment.js';\nimport {\n assessInstallFreshness,\n installFreshnessIsHealthy,\n readGlobalVersion,\n type InstallFreshness,\n} from './doctor-install-freshness.js';\nimport { execFileSync } from 'node:child_process';\nimport { VERSION, isNodeVersionSupported } from '../version.js';\nimport { allOf } from '../utils/verdict-aggregation.js';\nimport {\n checkGatewayHealth,\n cliFailsVerdict,\n gatewayVerdict,\n type GatewayHealth,\n type GatewayVerdict,\n} from './doctor-gateway.js';\n\n/** API key environment variable names. */\nconst API_KEY_VARS = ['ANTHROPIC_API_KEY', 'OPENAI_API_KEY', 'GOOGLE_AI_API_KEY'] as const;\n\n/**\n * Configuration file paths to check (in order of priority). Per epic #2872\n * the dotdir-scoped variants are preferred over the legacy root-level\n * locations — must match the order in `config-loader.ts:CONFIG_LOOKUP_PATHS`.\n */\nconst CONFIG_FILE_PATHS = [\n './.nexus-agents/nexus-agents.yaml',\n './.nexus-agents/nexus-agents.yml',\n './nexus-agents.yaml',\n './nexus-agents.yml',\n] as const;\n\n/**\n * Check result for a single CLI.\n */\nexport interface CliCheckResult {\n readonly name: CliName;\n readonly installed: boolean;\n readonly version: string;\n readonly versionStatus: 'supported' | 'outdated' | 'unsupported' | 'breaking';\n readonly authenticated: boolean;\n /**\n * The auth probe's THREE-valued result (#4661).\n *\n * `authenticated` above is a boolean and cannot express \"we did not check\".\n * Some gateways expose no non-interactive auth check, so their probe can only\n * ever return `unknown` — routing admits that deliberately (#4391: absence of\n * evidence is not failure). Collapsing it to `false` printed a red\n * \"Not authenticated\" for a CLI that was demonstrably working, and offered a\n * login command that fixes nothing.\n */\n readonly authState: 'authenticated' | 'unverified' | 'not-authenticated';\n /**\n * Whether the router would route to this CLI: `isCliAdmitted` over the same\n * health check and auth probe (#6720). `doctor --gateway` reads it to say\n * whether a gateway slot is served by the CLI or the gateway, so the report\n * cannot claim the CLI while the router picks the gateway. Not installed is\n * `false`.\n */\n readonly routerAdmits: boolean;\n readonly authMethod?: string;\n readonly capacity?: CapacityStatus;\n readonly error?: string;\n readonly fix?: string;\n}\n\n/**\n * Node.js version check result.\n */\nexport interface NodeVersionCheck {\n readonly version: string;\n readonly major: number;\n readonly supported: boolean;\n}\n\n/**\n * API key check result.\n */\nexport interface ApiKeyCheck {\n readonly name: string;\n readonly configured: boolean;\n}\n\n/**\n * Configuration file check result.\n */\nexport interface ConfigFileCheck {\n readonly found: boolean;\n readonly path: string | null;\n}\n\n/**\n * Model availability advisory entry (#890).\n */\nexport interface ModelAdvisory {\n readonly modelId: string;\n readonly displayName: string;\n readonly cliName: string;\n readonly available: boolean;\n readonly reason: string;\n}\n\n/**\n * Learning persistence health check result (#1017).\n */\nexport interface LearningPersistenceCheck {\n readonly enabled: boolean;\n readonly dirExists: boolean;\n readonly dirWritable: boolean;\n readonly outcomeCount: number;\n /**\n * Eligible outcomes (`isDistillerEligible`) across the WHOLE outcomes.jsonl\n * (#6512). The distiller sees only the store's newest-10k window, so this can\n * exceed what it trains on; `trainedOnEligible` is that number.\n */\n readonly fileEligibleOutcomeCount: number;\n /**\n * Outcomes tagged `routedBy: 'composite-router'` in outcomes.jsonl, and how\n * many landed in the last 7 days (#6521): the routing loop's input rate.\n */\n readonly routedOutcomes: RoutedOutcomeCounts;\n /** Every persisted rule, whatever its status. */\n readonly ruleCount: number;\n /** Persisted rules with status `active`: the ones routing applies (#6512). */\n readonly activeRuleCount: number;\n /**\n * Eligible outcomes the last distill trained on, from the snapshot's\n * `eligibleOutcomes`. Null: no snapshot, or one written before the count.\n */\n readonly trainedOnEligible: number | null;\n /** `savedAt` of rules.json: the last distill time. Null means never distilled. */\n readonly rulesLastSaved: string | null;\n readonly error: string | null;\n}\n\n/**\n * Registry advisory summary (#890).\n */\nexport interface RegistryAdvisory {\n readonly totalModels: number;\n readonly availableModels: number;\n readonly unavailableModels: number;\n readonly models: readonly ModelAdvisory[];\n /** Days since the registry was last updated. */\n readonly registryAgeDays: number;\n /** True if the registry is >30 days old and may have stale model data. */\n readonly registryStale: boolean;\n}\n\n/**\n * SQLite (node:sqlite) availability check (#1249, #5388).\n */\nexport interface SqliteCheck {\n readonly available: boolean;\n readonly error: string | null;\n}\n\n/**\n * Data directory health check (#1249, extended #2892).\n * Reports the resolved location of every data subdirectory — per-repo\n * subdirs under `<repo>/.nexus-agents/`, cross-repo subdirs under\n * `~/.nexus-agents/` — so the operator can see where state actually\n * lives after the epic #2872 state-split.\n */\nexport interface DataDirectoryCheck {\n /** True if the homedir/cross-repo root exists. */\n readonly rootExists: boolean;\n /** The homedir/cross-repo root path. */\n readonly rootPath: string;\n /** `<repo>/.nexus-agents` when the repo-preferred tier is active, else null. */\n readonly repoRoot: string | null;\n readonly subdirectories: readonly DataSubdirStatus[];\n}\n\n/**\n * Status of a single data subdirectory.\n */\nexport interface DataSubdirStatus {\n readonly name: string;\n /** Actual resolved path (per-repo or homedir, per the #2872 split). */\n readonly path: string;\n /** Which side of the state-split this subdir belongs to. */\n readonly scope: 'per-repo' | 'cross-repo';\n readonly exists: boolean;\n readonly writable: boolean;\n}\n\n/** Standard data subdirectories — resolved per-repo or cross-repo (epic #2872). */\nexport const DATA_SUBDIRECTORIES = [\n 'memory',\n 'memory/beliefs',\n 'learning',\n 'sessions',\n 'audit',\n 'voting',\n 'auth',\n 'research',\n 'checkpoints',\n] as const;\n\n/**\n * Sandbox awareness (#2501, child 1 of epic #2500).\n *\n * Reports whether nexus-agents is running inside a host-provided sandbox\n * (Docker Desktop Sandbox + OpenCode, Codex sandbox, locked-down CI) and\n * whether the explicit `NEXUS_SANDBOX` signal matches the runtime\n * heuristic. Mismatches don't block startup but get surfaced here so the\n * operator can fix the image / launch config.\n */\nexport interface SandboxCheck {\n readonly active: boolean;\n readonly flavor: string | undefined;\n readonly root: string | undefined;\n readonly heuristicMatch: 'docker' | 'podman' | 'unknown' | null;\n /** True iff the explicit signal disagrees with the heuristic. */\n readonly mismatch: boolean;\n /** True iff `NEXUS_DATA_DIR` resolves inside a single repo subfolder. */\n readonly dataDirInsideRepo: boolean;\n}\n\n/**\n * Voter transport check (#4255): whether an OpenAI-compatible gateway is\n * configured (env vars or the opencode.json bridge). Presence-only, same\n * spirit as {@link checkApiKeys} — no network probe, and the key itself is\n * never surfaced. When configured, consensus/voter calls route in-process\n * through the gateway; otherwise they fall back to CLI subprocesses (see\n * `cli-server-gateway.ts` `tryWireGatewayAdapters`).\n */\nexport interface VoterTransportCheck {\n readonly configured: boolean;\n /**\n * The gateway's `NEXUS_GATEWAY_COST` declaration (#4392 increment 2),\n * present only when a gateway is configured. Three gaps are told apart\n * because each is a different fix: `'unset'` (variable absent),\n * `'invalid'` (set but does not parse — the startup env warning carries the\n * reason), and `'no-default'` (valid, but names neither a bare declaration\n * nor this gateway's `<endpoint>=` entry — the gateway registers as\n * `api:<endpoint>`, `NEXUS_OPENAI_COMPAT_ENDPOINT` or `openai-compat`, and a\n * scoped entry for it counts since step 2). Every gap is a warning, not a\n * failure: the\n * gateway still serves voters; the task-class cost ceiling and the\n * per-task budget exclude it (#6393).\n */\n readonly cost?: GatewayCostDeclaration | 'unset' | 'invalid' | 'no-default';\n /**\n * Deprecated gateway env aliases in use (#4392 increment 3): the\n * `NEXUS_CUSTOM_API_*` pair, each with its replacement and whether the\n * replacement shadows it. Present only when at least one is set. A warning,\n * not a failure — and, per panel option C, the legacy pair configures only\n * the single-model `custom-openai` path, so it never makes `configured`\n * true; renaming does.\n */\n readonly deprecatedEnv?: readonly DeprecatedGatewayEnvUse[];\n}\n\n/**\n * Complete doctor check results.\n */\nexport interface DoctorResult {\n /** CLIs that were probed: every CLI not disabled by `NEXUS_DISABLED_CLIS`. */\n readonly clis: CliCheckResult[];\n /**\n * CLIs taken out of service by `NEXUS_DISABLED_CLIS` (#6590), in slot order.\n * Not probed and not counted toward the verdict: disabling a CLI is an\n * operator decision, not a fault. Empty when the variable is unset.\n */\n readonly disabledClis: readonly CliName[];\n readonly nodeVersion: NodeVersionCheck;\n readonly apiKeys: ApiKeyCheck[];\n readonly configFile: ConfigFileCheck;\n readonly mcpServerReady: boolean;\n /**\n * MEASURED (#6119): codex is installed AND `codex mcp-server --help` names\n * the subcommand. Inferring this from the install alone printed \"Ready\" on\n * codex-cli 0.154, which has no `mcp-server`. `false` with codex installed\n * means the subprocess transport (`codex exec`) is in use.\n */\n readonly mcpClientReady: boolean;\n /** Model registry advisory — which models are available (#890). */\n readonly registryAdvisory: RegistryAdvisory;\n /** Learning persistence health check (#1017). */\n readonly learningPersistence: LearningPersistenceCheck;\n /** SQLite (node:sqlite) availability (#1249, #5388). */\n readonly sqliteCheck: SqliteCheck;\n /** Data directory health (#1249). */\n readonly dataDirectory: DataDirectoryCheck;\n /** Sandbox detection + heuristic verification (#2501). */\n readonly sandbox: SandboxCheck;\n /** Per-harness config alignment with AGENTS.md federation (#2805). */\n readonly harnessAlignment: HarnessAlignmentCheck;\n /**\n * Whether the globally installed package matches this build (#4767).\n *\n * `.mcp.json` runs the MCP server off the global install, so drift here\n * means every MCP call executes code the operator is not looking at.\n */\n readonly installFreshness: InstallFreshness;\n /** Voter transport: in-process gateway vs CLI subprocess fallback (#4255). */\n readonly voterTransport: VoterTransportCheck;\n /**\n * The gateway MEASURED (#6609): guard, `/models`, family census, slots,\n * proxy and, with `--probe`, one completion per family. `not_configured`\n * when no gateway is set; no network call is made then.\n */\n readonly gateway: GatewayHealth;\n /**\n * Whether the pinned claude voter model answers a one-line request (#6120).\n *\n * Measured, not inferred from the CLI's presence: a host whose pinned model\n * was out of usage credits passed every other check here while every claude\n * voter seat failed.\n */\n readonly claudeModel: ClaudeModelProbe;\n /**\n * Headroom on every distinct filesystem backing a scratch root (#4488).\n *\n * A list rather than one reading because the nexus scratch root and the\n * shared system temp dir are frequently on different volumes, and the\n * incident this check exists for was on the one it did not measure.\n */\n readonly scratchSpace: readonly ScratchSpaceCheck[];\n readonly allHealthy: boolean;\n readonly timestamp: Date;\n}\n\n/**\n * Gets the CLI install/upgrade fix command.\n */\nfunction getFixCommand(name: CliName, issue: 'install' | 'upgrade' | 'auth'): string {\n const commands: Record<CliName, Record<string, string>> = {\n claude: {\n install: 'npm install -g @anthropic-ai/claude-code',\n upgrade: 'npm update -g @anthropic-ai/claude-code',\n auth: 'claude auth login',\n },\n gemini: {\n install: 'npm install -g @google/gemini-cli',\n upgrade: 'npm update -g @google/gemini-cli',\n auth: 'gemini auth login',\n },\n codex: {\n install: 'npm install -g @openai/codex',\n upgrade: 'npm update -g @openai/codex',\n auth: 'codex auth login',\n },\n opencode: {\n install: 'npm install -g opencode-ai',\n upgrade: 'npm update -g opencode-ai',\n auth: 'opencode auth login',\n },\n };\n return commands[name][issue] ?? '';\n}\n\n/**\n * Creates a result for when a CLI is not found.\n */\nfunction createNotFoundResult(name: CliName, errorMsg: string): CliCheckResult {\n return {\n name,\n // Not installed, so auth was never probed. `not-authenticated` would claim\n // a determination nobody made; the auth line is not printed for an\n // uninstalled CLI anyway (#4661).\n authState: 'unverified',\n routerAdmits: false,\n installed: false,\n version: 'N/A',\n versionStatus: 'unsupported',\n authenticated: false,\n error: errorMsg,\n fix: getFixCommand(name, 'install'),\n };\n}\n\n/**\n * Determines the authentication method based on CLI name.\n * CLIs use their own auth mechanisms - we report the method type\n * rather than assuming a specific one like 'OAuth'.\n */\nfunction detectAuthMethod(name: CliName): string {\n const authMethods: Record<CliName, string> = {\n claude: 'CLI auth',\n gemini: 'ADC/CLI auth',\n codex: 'CLI auth',\n opencode: 'CLI auth',\n };\n return authMethods[name];\n}\n\n/**\n * Maps the probe's three-valued state onto the reported one (#4661).\n *\n * `unknown` means the probe ran and could not determine auth — a gateway with\n * no non-interactive auth check. That is distinct from a probe that determined\n * the CLI is logged out, and collapsing the two printed a red \"Not\n * authenticated\" for a CLI that was demonstrably working.\n */\nfunction resolveAuthState(\n authenticated: boolean,\n probeState: AuthProbeResult['state']\n): CliCheckResult['authState'] {\n if (authenticated) return 'authenticated';\n return probeState === 'unknown' ? 'unverified' : 'not-authenticated';\n}\n\n/**\n * Creates a result from a successful health check.\n *\n * Authentication state comes from the auth probe (#2439, #2447), not from\n * `health.healthy` (which only confirms version compatibility). Without the\n * probe, doctor falsely reports \"Auth: CLI auth ✓\" for installed-but-\n * unauthed CLIs.\n */\nfunction createHealthyResult(\n name: CliName,\n health: HealthStatus,\n authProbe: AuthProbeResult,\n capacity?: CapacityStatus\n): CliCheckResult {\n const versionOk = health.healthy;\n const authenticated = versionOk && authProbe.state === 'authenticated';\n const authState = resolveAuthState(authenticated, authProbe.state);\n\n const result: CliCheckResult = {\n name,\n installed: true,\n version: health.version,\n versionStatus: health.versionStatus,\n authenticated,\n authState,\n routerAdmits: isCliAdmitted(health, authProbe),\n ...(authenticated && { authMethod: detectAuthMethod(name) }),\n ...(capacity !== undefined && { capacity }),\n };\n\n if (health.message !== undefined && health.message !== '') {\n return { ...result, error: health.message };\n }\n // Surface the probe's reason when needs-login so operators see what to fix.\n if (!authenticated && authProbe.state === 'needs-login') {\n return {\n ...result,\n error: authProbe.reason,\n fix: authProbe.fixCommand,\n };\n }\n // Only offer a login command when the probe actually determined a logout.\n // An unverified state has nothing to fix, and naming one sends operators to\n // re-authenticate a working CLI (#4661).\n // `not-authenticated` already implies `!authenticated` — see resolveAuthState.\n if (authState === 'not-authenticated') {\n return { ...result, fix: getFixCommand(name, 'auth') };\n }\n if (health.versionStatus === 'outdated') {\n return { ...result, fix: getFixCommand(name, 'upgrade') };\n }\n\n return result;\n}\n\n/**\n * Runs health check on a single CLI adapter.\n *\n * Combines the version-compatibility check from `adapter.healthCheck()` with\n * the real auth probe from `cli-auth-probe.ts` — see #2439 for why both are\n * needed (version-OK alone misled doctor into reporting unauthed CLIs as ✓).\n */\nasync function checkCli(name: CliName): Promise<CliCheckResult> {\n // DELIBERATE raw-adapter probe, not drift (#5191, ratified 4/6).\n //\n // `getGlobalRegistry()` is canonical for adapter ACQUISITION, and its adapters\n // share a circuit-breaker registry (#4330). That is right for execution and\n // wrong here: an open breaker would make this report a CLI unavailable\n // WITHOUT testing it, so doctor would be reading its own cached memory rather\n // than measuring the CLI. A probe that cannot observe a healthy CLI because\n // something else saw it fail is not a probe.\n //\n // Pinned by `doctor-probe-exemption.test.ts` so a future \"canonical path\"\n // cleanup cannot silently flip it.\n const adapters = createAllAdapters();\n const adapter = adapters.get(name);\n\n if (!adapter) {\n return createNotFoundResult(name, 'Adapter not available');\n }\n\n try {\n const [health, authProbe] = await Promise.all([adapter.healthCheck(), probeCli(name)]);\n let capacity: CapacityStatus | undefined;\n\n try {\n capacity = await adapter.getCapacity();\n } catch {\n // Capacity check is optional — some adapters don't support it.\n // Optional catch binding: there is no variable to be unused.\n }\n\n return createHealthyResult(name, health, authProbe, capacity);\n } catch (error) {\n const message = getErrorMessage(error);\n const isNotFound = message.includes('ENOENT') || message.includes('not found');\n return createNotFoundResult(name, isNotFound ? 'Not found in PATH' : message);\n }\n}\n\n/**\n * Checks the Node.js version against the required version.\n */\nfunction checkNodeVersion(): NodeVersionCheck {\n const version = process.version;\n const major = Number(version.slice(1).split('.')[0]);\n return {\n version,\n major,\n supported: isNodeVersionSupported(version),\n };\n}\n\n/**\n * Checks which API keys are configured in the environment.\n * Does NOT expose the actual key values - only reports presence.\n *\n * Exported so `verify` (#2136) and other health gates can reuse it without\n * running the full doctor pipeline.\n */\nexport function checkApiKeys(): ApiKeyCheck[] {\n return API_KEY_VARS.map((name) => ({\n name,\n configured: typeof process.env[name] === 'string' && process.env[name] !== '',\n }));\n}\n\n/**\n * Checks for the existence of a configuration file.\n */\nfunction checkConfigFile(): ConfigFileCheck {\n for (const configPath of CONFIG_FILE_PATHS) {\n if (existsSync(configPath)) {\n return { found: true, path: configPath };\n }\n }\n return { found: false, path: null };\n}\n\n/**\n * Validates that the MCP server can be created successfully.\n * This is a lightweight check that verifies server instantiation works.\n */\nfunction checkMcpServerReady(): boolean {\n try {\n const result = createServer({ name: 'nexus-agents-doctor-check' });\n return result.ok;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds model registry advisory based on detected CLI availability (#890).\n *\n * Staleness threshold (#2445): bumped from 30 → 90 days. The published\n * npm tarball ships with a registry snapshot that's typically 1-4 weeks\n * old by the time an operator installs it (normal release cadence). A\n * 30-day threshold meant fresh installs of recently-published versions\n * showed `⚠ Model registry is 55 days old` on day one of usage, training\n * operators to ignore staleness warnings.\n *\n * Additionally, if the operator's data directory has no signs of prior\n * usage (no audit log, no outcome store), suppress the warning entirely\n * — staleness on first run is a publishing concern, not an operator\n * concern.\n */\nfunction buildRegistryAdvisory(\n cliResults: CliCheckResult[],\n disabledClis: readonly CliName[],\n gateway: GatewayHealth\n): RegistryAdvisory {\n const installedClis = new Set(cliResults.filter((c) => c.installed).map((c) => c.name));\n\n const matrix = getInTreeCapabilitiesMatrix();\n const models: ModelAdvisory[] = matrix.models\n .filter((m) => m.cliName !== undefined)\n .map((m) => {\n const cliName = m.cliName ?? '';\n const available = cliName.length > 0 && installedClis.has(cliName as CliName);\n // A disabled CLI is switched off, not missing (#6728): never say \"install it\".\n const disabled = disabledClis.find((cli) => cli === cliName);\n const reason = available\n ? `${cliName} CLI is installed`\n : disabled !== undefined\n ? disabledCliModelReason(disabled, gateway, cliResults)\n : `${cliName} CLI is not installed`;\n return { modelId: m.id, displayName: m.displayName, cliName, available, reason };\n });\n\n // Registry staleness check (#1549, threshold revised in #2445)\n const STALE_THRESHOLD_DAYS = 90;\n const updatedAt = new Date(matrix.updatedAt);\n const nowMs = getTimeProvider().now();\n const ageDays = Math.floor((nowMs - updatedAt.getTime()) / (1000 * 60 * 60 * 24));\n\n // First-install detection: if the operator has no prior activity in\n // their data dir, suppress the staleness warning. There's nothing they\n // can do about it on day one anyway, and it trains them to ignore\n // warnings.\n const isFreshInstall = !hasPriorUsage();\n const exceedsThreshold = ageDays > STALE_THRESHOLD_DAYS;\n\n return {\n totalModels: models.length,\n availableModels: models.filter((m) => m.available).length,\n unavailableModels: models.filter((m) => !m.available).length,\n models,\n registryAgeDays: ageDays,\n registryStale: exceedsThreshold && !isFreshInstall,\n };\n}\n\n/**\n * Cheap heuristic for \"operator has used nexus-agents before\": data dir\n * exists and contains audit / outcome / session evidence. Used to\n * suppress staleness warnings on day-one of a fresh install (#2445).\n */\nfunction hasPriorUsage(): boolean {\n try {\n const root = getNexusDataDir();\n if (!existsSync(root)) return false;\n // Check for any subdirectory with files. Lazy creation of empty\n // subdirs by `nexus-agents setup` would falsely register as usage —\n // hence we look for *files*, not just directories.\n for (const sub of ['audit', 'learning', 'sessions', 'voting']) {\n const p = `${root}/${sub}`;\n try {\n if (existsSync(p) && readdirSync(p).length > 0) return true;\n } catch {\n // ignore — best-effort heuristic\n }\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/** Counts non-empty lines in a JSONL file. Returns 0 if file doesn't exist. */\nfunction countJsonlLines(filePath: string): number {\n if (!existsSync(filePath)) return 0;\n return readFileSync(filePath, 'utf-8')\n .split('\\n')\n .filter((l) => l.trim().length > 0).length;\n}\n\ninterface RulesMetadata {\n readonly count: number;\n readonly activeCount: number;\n readonly eligibleOutcomes: number | null;\n readonly savedAt: string | null;\n}\n\nconst NO_RULES: RulesMetadata = { count: 0, activeCount: 0, eligibleOutcomes: null, savedAt: null };\n\nfunction isActiveRule(rule: unknown): boolean {\n return (\n typeof rule === 'object' &&\n rule !== null &&\n (rule as Record<string, unknown>)['status'] === 'active'\n );\n}\n\n/** Reads rules snapshot metadata: total and active rule counts, trained-on count, savedAt. */\nfunction readRulesMetadata(filePath: string): RulesMetadata {\n if (!existsSync(filePath)) return NO_RULES;\n try {\n const raw = JSON.parse(readFileSync(filePath, 'utf-8')) as Record<string, unknown>;\n const rules = Array.isArray(raw['rules']) ? (raw['rules'] as unknown[]) : [];\n const saved = raw['savedAt'];\n const eligible = raw['eligibleOutcomes'];\n return {\n count: rules.length,\n activeCount: rules.filter(isActiveRule).length,\n eligibleOutcomes: typeof eligible === 'number' ? eligible : null,\n savedAt: typeof saved === 'string' ? saved : null,\n };\n } catch {\n return NO_RULES;\n }\n}\n\n/** Checks if a directory exists and is writable. */\nfunction checkDirAccess(dir: string): { exists: boolean; writable: boolean } {\n const exists = existsSync(dir);\n if (!exists) return { exists: false, writable: false };\n try {\n accessSync(dir, fsConstants.W_OK);\n return { exists: true, writable: true };\n } catch {\n return { exists: true, writable: false };\n }\n}\n\nconst DISABLED_CHECK: LearningPersistenceCheck = {\n enabled: false,\n dirExists: false,\n dirWritable: false,\n outcomeCount: 0,\n fileEligibleOutcomeCount: 0,\n routedOutcomes: { total: 0, last7Days: 0 },\n ruleCount: 0,\n activeRuleCount: 0,\n trainedOnEligible: null,\n rulesLastSaved: null,\n error: null,\n};\n\n/** Checks learning persistence health (#1017). */\nfunction checkLearningPersistence(): LearningPersistenceCheck {\n if (!isPersistenceEnabled()) return DISABLED_CHECK;\n try {\n const { exists: dirExists, writable: dirWritable } = checkDirAccess(getLearningDir());\n const outcomeCount = countJsonlLines(getOutcomesFile());\n const fileEligibleOutcomeCount = countEligibleOutcomesInFile(getOutcomesFile());\n const routedOutcomes = countRoutedOutcomesInFile(getOutcomesFile(), getTimeProvider().now());\n const rules = readRulesMetadata(getRulesFile());\n return {\n enabled: true,\n dirExists,\n dirWritable,\n outcomeCount,\n fileEligibleOutcomeCount,\n routedOutcomes,\n ruleCount: rules.count,\n activeRuleCount: rules.activeCount,\n trainedOnEligible: rules.eligibleOutcomes,\n rulesLastSaved: rules.savedAt,\n error: null,\n };\n } catch (error: unknown) {\n return {\n enabled: true,\n dirExists: false,\n dirWritable: false,\n outcomeCount: 0,\n fileEligibleOutcomeCount: 0,\n routedOutcomes: { total: 0, last7Days: 0 },\n ruleCount: 0,\n activeRuleCount: 0,\n trainedOnEligible: null,\n rulesLastSaved: null,\n error: getErrorMessage(error),\n };\n }\n}\n\n/**\n * Checks if SQLite is available (#1249, #5388).\n * Memory backends (agentic, adaptive, typed, mobimem, decay) require it.\n *\n * Since #5388 this probes `node:sqlite`, a BUILTIN, so on a supported runtime\n * it cannot be missing. The check is kept rather than deleted because it can\n * still fail for a real reason: `node:sqlite` did not exist before Node 22.5.0,\n * so an older runtime reports unavailable here instead of crashing later inside\n * a memory backend. A check that can no longer fail would be worth removing;\n * this one still can.\n *\n * Exported so `verify` (#2136) can reuse it without running the full doctor\n * pipeline.\n */\nexport async function checkSqlite(): Promise<SqliteCheck> {\n try {\n await import('node:sqlite');\n return { available: true, error: null };\n } catch (error: unknown) {\n const msg = getErrorMessage(error);\n const isNotFound = msg.includes('Cannot find') || msg.includes('MODULE_NOT_FOUND');\n return {\n available: false,\n error: isNotFound\n ? `node:sqlite unavailable on ${process.version} — requires Node >= 22.5.0; 5 memory backends unavailable`\n : `node:sqlite load error: ${msg}`,\n };\n }\n}\n\n/**\n * Checks the nexus-agents data directory health (#1249, extended #2892).\n *\n * Resolves each subdir through `nexusDataPath()` so the reported path is\n * the REAL location after the epic #2872 state-split — per-repo subdirs\n * land in `<repo>/.nexus-agents/`, cross-repo subdirs in `~/.nexus-agents/`.\n *\n * Exported so `verify` (#2136) can reuse it without running the full doctor\n * pipeline.\n */\nexport function checkDataDirectory(): DataDirectoryCheck {\n const rootPath = getNexusDataDir();\n const rootExists = existsSync(rootPath);\n const repoRoot = getNexusRepoDir();\n const perRepoSet = getPerRepoSubdirs();\n\n const subdirectories: DataSubdirStatus[] = DATA_SUBDIRECTORIES.map((name) => {\n const segments = name.split('/');\n const fullPath = nexusDataPath(...segments);\n const exists = existsSync(fullPath);\n const scope: 'per-repo' | 'cross-repo' = perRepoSet.has(segments[0] ?? '')\n ? 'per-repo'\n : 'cross-repo';\n return { name, path: fullPath, scope, exists, writable: exists && isWritable(fullPath) };\n });\n\n return { rootExists, rootPath, repoRoot, subdirectories };\n}\n\n/** Checks if a directory is writable by the current user. */\nfunction isWritable(dirPath: string): boolean {\n try {\n accessSync(dirPath, fsConstants.W_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Sandbox awareness check (#2501).\n *\n * Cross-references the explicit `NEXUS_SANDBOX` signal against the runtime\n * heuristic and the resolved data dir. Surfaces mismatches that point at\n * a misconfigured image (claims docker but no `/.dockerenv`) or a\n * misconfigured launch (`NEXUS_DATA_DIR` inside a single repo while the\n * sandbox root spans multiple).\n */\nexport function checkSandbox(): SandboxCheck {\n const info = detectSandbox();\n const dataDir = getNexusDataDir();\n const root = info.root;\n const dataDirInsideRepo =\n info.active &&\n root !== undefined &&\n dataDir.startsWith(`${root.replace(/\\/$/, '')}/`) &&\n // path segments BETWEEN root and `.nexus-agents/` indicate the data dir\n // lives in a subfolder rather than at the multi-repo root.\n dataDir.replace(`${root.replace(/\\/$/, '')}/`, '').split('/').length > 1;\n\n // Mismatch: claimed sandbox but heuristic says not-a-container, or vice versa.\n const heuristicSaysContainer =\n info.heuristicMatch === 'docker' || info.heuristicMatch === 'podman';\n const mismatch =\n (info.active && info.heuristicMatch === 'unknown') || (!info.active && heuristicSaysContainer);\n\n return {\n active: info.active,\n flavor: info.flavor,\n root: info.root,\n heuristicMatch: info.heuristicMatch,\n mismatch,\n dataDirInsideRepo,\n };\n}\n\n/**\n * Checks whether an OpenAI-compatible gateway is configured (#4255).\n * Presence-only — mirrors {@link checkApiKeys}, no network probe and the\n * key value never leaves `process.env`.\n */\n/**\n * Compare the globally installed version with this build (#4767).\n *\n * Deliberately NOT exported: this is only the `npm ls -g` call. The verdict it\n * wraps lives in `doctor-install-freshness.ts`, where it is pure and testable\n * without npm — exporting this too would be an export whose only importer is a\n * test, which the producer/consumer ratchet correctly rejects.\n */\nfunction checkInstallFreshness(): InstallFreshness {\n const { version, reason } = readGlobalVersion((cmd, args) => {\n try {\n return execFileSync(cmd, [...args], {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n } catch {\n return null;\n }\n });\n return assessInstallFreshness(version, VERSION, reason);\n}\n\n/** The environment sub-checks, grouped so `runDoctor` stays under its line cap. */\nfunction collectEnvironmentChecks(): {\n harnessAlignment: HarnessAlignmentCheck;\n installFreshness: InstallFreshness;\n voterTransport: VoterTransportCheck;\n scratchSpace: readonly ScratchSpaceCheck[];\n} {\n return {\n harnessAlignment: checkHarnessAlignment(),\n installFreshness: checkInstallFreshness(),\n voterTransport: checkVoterTransport(),\n scratchSpace: checkScratchFilesystems(),\n };\n}\n\nexport function checkVoterTransport(): VoterTransportCheck {\n const gateway = readOpenAICompatEnv();\n // Read, never warned from here: doctor prints its own line for these.\n const { deprecated } = resolveGatewayEnv();\n const deprecatedEnv = deprecated.length > 0 ? { deprecatedEnv: deprecated } : {};\n if (gateway === null) return { configured: false, ...deprecatedEnv };\n return {\n configured: true,\n cost: voterGatewayCostDeclaration(gateway.endpoint ?? readOpenAICompatEndpoint()),\n ...deprecatedEnv,\n };\n}\n\n/**\n * The declaration that applies to the voter gateway's arm — a scoped\n * `<endpoint>=` entry or the bare default, resolved exactly as the cost\n * estimators resolve it (#4392 step 2) — or which gap (see\n * {@link VoterTransportCheck.cost}).\n */\nfunction voterGatewayCostDeclaration(endpoint: string): NonNullable<VoterTransportCheck['cost']> {\n const status = gatewayCostStatus();\n if (status.kind !== 'declared') return status.kind;\n return resolveGatewayCostDeclaration(`api:${endpoint}`) ?? 'no-default';\n}\n\n/** The inputs the overall verdict is computed from. */\nexport interface HealthVerdictInput {\n readonly nodeSupported: boolean;\n readonly hasAuthMethod: boolean;\n readonly mcpServerReady: boolean;\n readonly installFreshness: InstallFreshness;\n readonly scratchSpace: readonly ScratchSpaceCheck[];\n readonly clis: readonly CliCheckResult[];\n /**\n * The measured gateway (#6609). `fail` fails the verdict; `pass` makes a\n * missing CLI acceptable, because its slot is served by the gateway.\n */\n readonly gateway: GatewayVerdict;\n}\n\n/**\n * The overall doctor verdict.\n *\n * Extracted so the predicate is directly testable (#4488). It needed to be:\n * `worstSeverity` shipped in #4528 and was then called nowhere, so `doctor`\n * exited 0 with a 100%-full tmpfs — the check reported the very condition it\n * was built for and still could not fail on it.\n *\n * Scratch space counts at `critical` only. `warn` still leaves room for the\n * current run, and failing the whole command on it would collapse the\n * distinction between the two thresholds into one.\n */\n\nexport function isAllHealthy(input: HealthVerdictInput): boolean {\n return (\n input.gateway !== 'fail' &&\n input.nodeSupported &&\n input.hasAuthMethod &&\n input.mcpServerReady &&\n installFreshnessIsHealthy(input.installFreshness) &&\n scratchSeverityIsAcceptable(worstSeverity(input.scratchSpace)) &&\n // whenEmpty: zero detected CLIs is not a healthy install (#4581) — unless\n // a passing gateway serves the slots (#6609), as on a gateway-only host.\n allOf(input.clis, (c) => !cliFailsVerdict(c, input.gateway), input.gateway === 'pass')\n );\n}\n\n/**\n * Probe the pinned claude model, telling the probe whether the CLI was found\n * (#6120). A missing claude entry among `clis` is \"not installed\": nothing\n * was detected, so nothing can be probed.\n */\nfunction probeClaudeModelFor(\n clis: readonly CliCheckResult[],\n probe: (installed: boolean) => Promise<ClaudeModelProbe> = (installed) =>\n probeClaudePinnedModel({ installed })\n): Promise<ClaudeModelProbe> {\n const claudeCheck = clis.find((c) => c.name === 'claude');\n return probe(claudeCheck?.installed === true);\n}\n\n/** At least one API key configured, one CLI authenticated, or a passing gateway (#6609). */\nfunction hasAnyAuthMethod(\n apiKeys: readonly ApiKeyCheck[],\n clis: readonly CliCheckResult[],\n gateway: GatewayVerdict\n): boolean {\n return (\n apiKeys.some((k) => k.configured) ||\n clis.some((c) => c.installed && c.authenticated) ||\n gateway === 'pass'\n );\n}\n\n/** The gateway measurement, through the seam when one is given. */\nfunction measureGateway(\n check: GatewayCheck | undefined,\n probe: boolean | undefined\n): Promise<GatewayHealth> {\n return (check ?? checkGatewayHealth)({ probe: probe === true });\n}\n\n/** The gateway measurement seam (#6609); defaults to {@link checkGatewayHealth}. */\ntype GatewayCheck = (options: { readonly probe: boolean }) => Promise<GatewayHealth>;\n\n/** Seams and switches for {@link runDoctor}. */\ninterface RunDoctorDeps {\n /** The pinned-model probe seam (#6120), injectable so the suite spends no quota. */\n readonly probeClaudeModel?: (installed: boolean) => Promise<ClaudeModelProbe>;\n /** The gateway measurement seam (#6609). */\n readonly checkGateway?: GatewayCheck;\n /** Send one completion per gateway family (`--probe`). Spends tokens. */\n readonly gatewayProbe?: boolean;\n}\n\n/** Runs the complete doctor check. */\nexport async function runDoctor(deps: RunDoctorDeps = {}): Promise<DoctorResult> {\n const allClis: readonly CliName[] = ['claude', 'gemini', 'codex', 'opencode'];\n const disabledClis = allClis.filter((cli) => isCliDisabled(cli));\n const clis = await Promise.all(\n allClis.filter((cli) => !isCliDisabled(cli)).map((cli) => checkCli(cli))\n );\n const claudeModel = await probeClaudeModelFor(clis, deps.probeClaudeModel);\n const nodeVersion = checkNodeVersion();\n const apiKeys = checkApiKeys();\n const configFile = checkConfigFile();\n const mcpServerReady = checkMcpServerReady();\n const codexCheck = clis.find((c) => c.name === 'codex');\n const mcpClientReady = (codexCheck?.installed ?? false) && codexMcpServerAvailable();\n const learningPersistence = checkLearningPersistence();\n const sqliteCheck = await checkSqlite();\n const dataDirectory = checkDataDirectory();\n const sandbox = checkSandbox();\n const env = collectEnvironmentChecks();\n const gateway = await measureGateway(deps.checkGateway, deps.gatewayProbe);\n const gatewayTerm = gatewayVerdict(gateway);\n const registryAdvisory = buildRegistryAdvisory(clis, disabledClis, gateway);\n\n const allHealthy = isAllHealthy({\n nodeSupported: nodeVersion.supported,\n hasAuthMethod: hasAnyAuthMethod(apiKeys, clis, gatewayTerm),\n mcpServerReady,\n installFreshness: env.installFreshness,\n scratchSpace: env.scratchSpace,\n clis,\n gateway: gatewayTerm,\n });\n\n return {\n clis,\n disabledClis,\n nodeVersion,\n apiKeys,\n configFile,\n mcpServerReady,\n mcpClientReady,\n registryAdvisory,\n learningPersistence,\n sqliteCheck,\n dataDirectory,\n sandbox,\n ...env,\n gateway,\n claudeModel,\n allHealthy,\n timestamp: new Date(getTimeProvider().now()),\n };\n}\n\n/** Doctor command options. */\nexport interface DoctorOptions {\n /** Auto-fix safe issues (run setup, generate config). */\n readonly fix?: boolean;\n /** Print the gateway section: census, slots, guard, proxy (#6609). */\n readonly gateway?: boolean;\n /** Also send one completion per gateway family; implies `gateway`. Spends tokens. */\n readonly probe?: boolean;\n /**\n * Receives the measured result, so `doctor --live` can compare its own CLI\n * availability check against the CLI list's (#6781).\n */\n readonly onResult?: (result: DoctorResult) => void;\n}\n\n/**\n * Runs the doctor command and prints results.\n * Returns exit code (0 = healthy, 1 = issues found).\n */\nexport async function doctorCommand(options: DoctorOptions = {}): Promise<number> {\n const result = await runDoctor({ gatewayProbe: options.probe === true });\n options.onResult?.(result);\n printDoctorResults(result);\n if (options.gateway === true || options.probe === true) {\n const { formatGatewayReport } = await import('./doctor-gateway-report.js');\n for (const line of formatGatewayReport(result.gateway, result.clis)) {\n process.stdout.write(line + '\\n');\n }\n }\n\n if (options.fix === true) {\n await runDoctorFix(result);\n }\n\n return result.allHealthy ? 0 : 1;\n}\n\n/**\n * Auto-fixes safe issues found by doctor (#1254).\n * Only runs our own code — never execs external package managers.\n */\nasync function runDoctorFix(result: DoctorResult): Promise<void> {\n const writeLine = (text: string): void => {\n process.stdout.write(text + '\\n');\n };\n\n writeLine('');\n writeLine('\\x1b[1mAuto-fix\\x1b[0m');\n writeLine('─'.repeat(40));\n\n let fixCount = 0;\n\n // Fix: data directories (missing or not writable)\n if (\n !result.dataDirectory.rootExists ||\n result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)\n ) {\n // Calls the data-dir initializer directly rather than `runSetup` with\n // every other step skipped: the result carries `created`, and that is the\n // only thing distinguishing a real fix from a no-op.\n //\n // #4851: this reported on `setupResult.success` alone and so claimed\n // \"✓ Created missing data directories\" for the unwritable case — which\n // setup cannot repair. `ensureDir` returns early for a path that already\n // exists and never checks writability, so nothing is created and success\n // is still true, for precisely the condition that triggered the fix.\n const { initDataDirectories, describeDataDirFix } = await import('./setup-data-dir.js');\n const outcome = describeDataDirFix(initDataDirectories());\n writeLine(outcome.line);\n if (outcome.counted) fixCount++;\n }\n\n // Fix: config file\n if (!result.configFile.found) {\n const { runConfigInitSync } = await import('./setup-config.js');\n const configResult = runConfigInitSync(process.cwd(), false, false);\n if (configResult.success && configResult.created) {\n writeLine(`✓ Generated config: ${configResult.path}`);\n fixCount++;\n }\n }\n\n // Display-only: SQLite availability\n if (!result.sqliteCheck.available) {\n writeLine('');\n writeLine('⚠ SQLite unavailable (node:sqlite needs Node >= 22.5.0):');\n writeLine(` Upgrade Node (currently ${process.version})`);\n }\n\n if (fixCount > 0) {\n writeLine('');\n writeLine(\n `\\x1b[32m${String(fixCount)} issue(s) fixed.\\x1b[0m Re-run \\x1b[1mnexus-agents doctor\\x1b[0m to verify.`\n );\n } else {\n writeLine('No auto-fixable issues found.');\n }\n writeLine('');\n}\n\n// Re-export printDoctorResults for backward compatibility\nexport { printDoctorResults } from './doctor-formatting.js';\n","/**\n * Scratch-filesystem headroom check for `nexus-agents doctor` (#4488).\n *\n * A tmpfs at 100% is invisible until something fails, and it fails badly: a\n * subprocess does its work and then dies at the *write* step, so the output is\n * lost rather than the command being refused. During a long autonomous run\n * that reads as unexplained tool failure, not a disk problem. This check makes\n * the condition visible before it bites.\n *\n * ## Why two roots, not one\n *\n * The check originally measured only `getNexusTmpDir()`. That is the wrong\n * filesystem for the incident it was written for: `getNexusTmpDir()` defaults\n * to `<dataDir>/tmp` inside the repo, which on the reporting machine sits on a\n * 900 GiB volume, while the #4488 outage was a **32 GiB tmpfs at `os.tmpdir()`**\n * hitting 100%. Every subprocess failed, and the check graded `ok` throughout,\n * because the volume it measured had 200 GiB free the entire time.\n *\n * So both roots are measured: the nexus scratch root and the system temp dir\n * the harness and other tooling share. They are deduplicated by device id, so\n * the common case where both live on one filesystem still reports one line.\n * The overall grade is the WORST across filesystems — a roomy nexus root must\n * never mask a starved shared one, which is exactly the masking that made the\n * original check unable to fail for its own motivating incident.\n *\n * @module cli/doctor-scratch-space\n * (Source: Issue #4488)\n */\n\nimport { statSync, statfsSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\n\nimport { getNexusTmpDir } from '../config/nexus-tmp-dir.js';\n\nconst MIB = 1024 * 1024;\nconst GIB = 1024 * 1024 * 1024;\n\n/**\n * Below this, treat the filesystem as already failing.\n *\n * A single agent run writes subprocess output, prompt files, and worktrees;\n * the transcripts alone reached hundreds of MiB in the #4488 incident. Under\n * 512 MiB there is not enough room for one more run to complete.\n */\nexport const CRITICAL_FREE_BYTES = 512 * MIB;\n\n/**\n * Below this, warn. Two GiB leaves room for the current run plus a margin,\n * which is roughly what the #4488 incident consumed between the first symptom\n * and total exhaustion.\n */\nexport const WARN_FREE_BYTES = 2 * GIB;\n\nexport type ScratchSpaceSeverity = 'ok' | 'warn' | 'critical';\n\n/** Which scratch root a reading describes, for operator-facing output. */\nexport type ScratchRootLabel = 'nexus' | 'system';\n\n/** A scratch root to measure, paired with the label its line is reported under. */\nexport interface ScratchRoot {\n readonly label: ScratchRootLabel;\n readonly root: string;\n}\n\nexport interface ScratchSpaceCheck {\n /** Which of the scratch roots this reading describes. */\n readonly label: ScratchRootLabel;\n /** The scratch root whose backing filesystem was measured. */\n readonly root: string;\n /** False when the filesystem could not be interrogated at all. */\n readonly available: boolean;\n readonly freeBytes: number;\n readonly totalBytes: number;\n /** Whole-percent used, rounded. Zero when unavailable. */\n readonly percentUsed: number;\n readonly severity: ScratchSpaceSeverity;\n readonly message: string;\n}\n\n/** Subset of `statfsSync`'s result this check depends on. */\nexport interface StatfsReading {\n readonly bsize: number;\n readonly blocks: number;\n readonly bavail: number;\n}\n\ntype StatfsFn = (path: string) => StatfsReading;\n\n/** Renders a byte count as GiB/MiB, whichever reads better. */\nfunction formatBytes(bytes: number): string {\n if (bytes >= GIB) return `${(bytes / GIB).toFixed(1)} GiB`;\n return `${(bytes / MIB).toFixed(0)} MiB`;\n}\n\n/**\n * Grade the reading on absolute free bytes.\n *\n * Deliberately not percentage-based. The question this check answers is \"can\n * the next run write?\", which is an absolute quantity: 3% free on a 4 TiB\n * volume is ~123 GiB and entirely fine, while 20% free on a 1 GiB volume is\n * not enough for one agent run. Percentage is reported for context only.\n */\nfunction grade(freeBytes: number): ScratchSpaceSeverity {\n if (freeBytes < CRITICAL_FREE_BYTES) return 'critical';\n if (freeBytes < WARN_FREE_BYTES) return 'warn';\n return 'ok';\n}\n\n/**\n * Measure headroom on the filesystem backing the scratch root.\n *\n * Never throws: a platform without `statfs` support reports `available: false`\n * and grades `ok`, because an unreadable filesystem is not evidence of a full\n * one and doctor must not fail closed on a diagnostic.\n *\n * @param root - Scratch root to measure; defaults to the configured tmp dir.\n * @param statfs - Injection seam for tests.\n * @param label - Which root this is, for the reported line.\n */\nexport function checkScratchSpace(\n root: string = getNexusTmpDir(),\n statfs: StatfsFn = statfsSync,\n label: ScratchRootLabel = 'nexus'\n): ScratchSpaceCheck {\n let reading: StatfsReading;\n try {\n reading = statfs(root);\n } catch {\n return {\n label,\n root,\n available: false,\n freeBytes: 0,\n totalBytes: 0,\n percentUsed: 0,\n severity: 'ok',\n message: `Scratch filesystem at ${root} could not be read (statfs unavailable)`,\n };\n }\n\n const totalBytes = reading.blocks * reading.bsize;\n const freeBytes = reading.bavail * reading.bsize;\n const percentUsed =\n totalBytes > 0 ? Math.round(((totalBytes - freeBytes) / totalBytes) * 100) : 100;\n const severity = grade(freeBytes);\n\n return {\n label,\n root,\n available: true,\n freeBytes,\n totalBytes,\n percentUsed,\n severity,\n message: `${formatBytes(freeBytes)} free of ${formatBytes(totalBytes)} (${String(percentUsed)}% used)`,\n };\n}\n\n/** Resolves a path to the id of the device backing it. */\ntype DeviceFn = (path: string) => number;\n\n/** Severity ranking, worst last. */\nconst SEVERITY_ORDER: readonly ScratchSpaceSeverity[] = ['ok', 'warn', 'critical'];\n\nexport interface ScratchFilesystemsOptions {\n /** Roots to consider; defaults to the nexus scratch root and the system temp dir. */\n readonly roots?: readonly ScratchRoot[];\n readonly statfs?: StatfsFn;\n readonly deviceOf?: DeviceFn;\n}\n\n/** The roots worth measuring by default, in reporting order. */\nfunction defaultRoots(): readonly ScratchRoot[] {\n return [\n { label: 'nexus', root: getNexusTmpDir() },\n { label: 'system', root: tmpdir() },\n ];\n}\n\n/**\n * Measure every distinct filesystem backing a scratch root.\n *\n * Roots that resolve to the same device are measured once, keeping the common\n * single-volume machine to one line. A root whose device cannot be identified\n * is skipped rather than guessed at: it is dropped from the report entirely,\n * because a path that cannot be resolved is unmeasured, and reporting an\n * unmeasured root as healthy is the failure this whole check exists to avoid.\n */\nexport function checkScratchFilesystems(\n options: ScratchFilesystemsOptions = {}\n): readonly ScratchSpaceCheck[] {\n const roots = options.roots ?? defaultRoots();\n const statfs = options.statfs ?? statfsSync;\n const deviceOf = options.deviceOf ?? ((path: string): number => statSync(path).dev);\n\n const seen = new Set<number>();\n const checks: ScratchSpaceCheck[] = [];\n\n for (const { label, root } of roots) {\n let device: number;\n try {\n device = deviceOf(root);\n } catch {\n continue;\n }\n\n if (seen.has(device)) continue;\n seen.add(device);\n checks.push(checkScratchSpace(root, statfs, label));\n }\n\n return checks;\n}\n\n/**\n * The worst grade across measured filesystems.\n *\n * Worst rather than first, so a roomy volume cannot mask a full one. An empty\n * list grades `ok`: nothing was measured, and absence of a reading is not\n * evidence of a full disk — doctor must not fail closed on a diagnostic.\n */\nexport function worstSeverity(checks: readonly ScratchSpaceCheck[]): ScratchSpaceSeverity {\n return checks.reduce<ScratchSpaceSeverity>(\n (worst, check) =>\n SEVERITY_ORDER.indexOf(check.severity) > SEVERITY_ORDER.indexOf(worst)\n ? check.severity\n : worst,\n 'ok'\n );\n}\n\n/** Render every measured filesystem, one line each. */\nexport function formatScratchFilesystems(checks: readonly ScratchSpaceCheck[]): string {\n if (checks.length === 0) {\n return ' ⚠ Scratch space: no scratch filesystem could be identified';\n }\n return checks.map(formatScratchSpace).join('\\n');\n}\n\n/** Render the check as a doctor line, with remediation only when it is needed. */\nexport function formatScratchSpace(check: ScratchSpaceCheck): string {\n if (!check.available) {\n return ` ⚠ Scratch space [${check.label}]: ${check.message}`;\n }\n\n const icon = check.severity === 'ok' ? '✓' : check.severity === 'warn' ? '⚠' : '✗';\n const line = ` ${icon} Scratch space [${check.label}] (${check.root}): ${check.message}`;\n\n if (check.severity === 'ok') return line;\n\n // Only shown when short: an operator reading a healthy report does not need\n // instructions for a problem they do not have.\n return [\n line,\n ' A full scratch filesystem fails subprocesses at the write step, after',\n ' they have done their work, so output is lost rather than refused.',\n ' Free space, or point NEXUS_TMPDIR at a roomier filesystem.',\n ].join('\\n');\n}\n\n/**\n * Whether a scratch severity permits a healthy verdict (#4563).\n *\n * Exhaustive rather than `!== 'critical'`: a severity added later — say\n * `fatal` — would silently satisfy a negative test and let the verdict pass,\n * which is the same shape as the `skip`-reaching-`!== 'fail'` regression on\n * the ship gate. Each level must be classified deliberately.\n */\nexport function scratchSeverityIsAcceptable(severity: ScratchSpaceSeverity): boolean {\n switch (severity) {\n case 'ok':\n case 'warn':\n // warn still leaves room for the current run.\n return true;\n case 'critical':\n return false;\n default: {\n const exhaustive: never = severity;\n throw new Error(`Unhandled scratch severity: ${String(exhaustive)}`);\n }\n }\n}\n","/**\n * nexus-agents/mcp - MCP Server\n *\n * Main MCP server implementation for Nexus Agents orchestration.\n * Provides factory functions to create and start the server with\n * stdio or custom transports.\n *\n * (Source: MCP Protocol 2025-11-25)\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\n\nimport {\n getErrorMessage,\n createLogger,\n type Result,\n ok,\n err,\n type ILogger,\n} from '../core/index.js';\nimport { VERSION } from '../version.js';\nimport { getTaskStore } from './task-store.js';\nimport { claimGlobalRegistry } from '../adapters/unified-registry.js';\nimport { initDataDirectories } from '../cli/setup-data-dir.js';\n\n/**\n * Server configuration options.\n */\nexport interface ServerConfig {\n /** Server name (default: \"nexus-agents\") */\n readonly name?: string;\n /** Server version (default: package version) */\n readonly version?: string;\n /** Logger instance */\n readonly logger?: ILogger;\n}\n\n/**\n * Server creation result containing the server and logger.\n */\nexport interface ServerInstance {\n /** The MCP server instance */\n readonly server: McpServer;\n /** The logger instance for this server */\n readonly logger: ILogger;\n}\n\n/**\n * Error type for server operations.\n */\nexport interface ServerError {\n code: 'SERVER_CREATION_FAILED' | 'SERVER_START_FAILED' | 'SERVER_STOP_FAILED';\n message: string;\n cause?: Error;\n}\n\nconst DEFAULT_SERVER_NAME = 'nexus-agents';\n\n/**\n * Creates a ServerError with the given code, message, and optional cause.\n */\nfunction createServerError(\n code: ServerError['code'],\n message: string,\n error: unknown\n): ServerError {\n const serverError: ServerError = { code, message };\n if (error instanceof Error) {\n serverError.cause = error;\n }\n return serverError;\n}\n\n/**\n * Creates a new MCP server instance.\n *\n * @param config - Optional server configuration\n * @returns Result containing the server instance or an error\n *\n * @example\n * ```typescript\n * const result = createServer({ name: 'my-server' });\n * if (result.ok) {\n * const { server, logger } = result.value;\n * // Register tools on server\n * }\n * ```\n */\nexport function createServer(config?: ServerConfig): Result<ServerInstance, ServerError> {\n const serverName = config?.name ?? DEFAULT_SERVER_NAME;\n const serverVersion = config?.version ?? VERSION;\n const logger = config?.logger ?? createLogger({ component: 'mcp-server' });\n\n try {\n // Ensure data directories exist on first MCP server startup (#1398)\n initDataDirectories();\n\n logger.info('Creating MCP server', {\n name: serverName,\n version: serverVersion,\n });\n\n const server = new McpServer(\n {\n name: serverName,\n version: serverVersion,\n },\n {\n capabilities: {\n logging: {},\n prompts: {},\n resources: {},\n tasks: {},\n },\n taskStore: getTaskStore(),\n }\n );\n\n logger.debug('MCP server created successfully');\n\n return ok({ server, logger });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create MCP server', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_CREATION_FAILED',\n `Failed to create MCP server: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Connects the server to a transport.\n *\n * @param server - The MCP server instance\n * @param transport - The transport to connect to\n * @param logger - Logger for the operation\n * @returns Result indicating success or failure\n */\nexport async function connectTransport(\n server: McpServer,\n transport: Transport,\n logger?: ILogger\n): Promise<Result<void, ServerError>> {\n const log = logger ?? createLogger({ component: 'mcp-server' });\n\n // Composition root for the adapter registry in server mode (#6012) — see the\n // matching call in cli.ts `main()`. Claimed here, before any tool handler\n // runs, so the registry's logger is chosen deliberately instead of by\n // whichever tool is invoked first.\n claimGlobalRegistry(log);\n\n try {\n log.info('Connecting server to transport');\n await server.connect(transport);\n log.debug('Server connected to transport successfully');\n return ok(undefined);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n log.error('Failed to connect to transport', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_START_FAILED',\n `Failed to connect to transport: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Starts the MCP server with stdio transport.\n *\n * This is the main entry point for running the server as a standalone process.\n * The server will communicate over stdin/stdout using the MCP protocol.\n *\n * @param config - Optional server configuration\n * @returns Result indicating success or failure\n *\n * @example\n * ```typescript\n * const result = await startStdioServer();\n * if (!result.ok) {\n * console.error('Failed to start server:', result.error.message);\n * process.exit(1);\n * }\n * ```\n */\nexport async function startStdioServer(\n config?: ServerConfig\n): Promise<Result<ServerInstance, ServerError>> {\n const serverResult = createServer(config);\n if (!serverResult.ok) {\n return serverResult;\n }\n\n const { server, logger } = serverResult.value;\n\n try {\n // Defense-in-depth: stdio transport owns stdout for JSON-RPC frames.\n logger.setDestination?.('stderr');\n logger.info('Starting stdio transport');\n const transport = new StdioServerTransport();\n\n const connectResult = await connectTransport(server, transport, logger);\n if (!connectResult.ok) {\n return connectResult;\n }\n\n logger.info('MCP server running with stdio transport');\n return ok({ server, logger });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to start stdio server', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_START_FAILED',\n `Failed to start stdio server: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Gracefully closes the server connection.\n *\n * @param server - The MCP server to close\n * @param logger - Optional logger\n * @returns Result indicating success or failure\n */\nexport async function closeServer(\n server: McpServer,\n logger?: ILogger\n): Promise<Result<void, ServerError>> {\n const log = logger ?? createLogger({ component: 'mcp-server' });\n\n try {\n log.info('Closing MCP server');\n await server.close();\n log.info('MCP server closed successfully');\n return ok(undefined);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n log.error('Failed to close server', error instanceof Error ? error : undefined);\n return err(\n createServerError('SERVER_STOP_FAILED', `Failed to close server: ${errorMessage}`, error)\n );\n }\n}\n","/**\n * Nexus-Agents Task Store — wraps SDK InMemoryTaskStore with security controls.\n *\n * Provides:\n * - TTL enforcement (max 10 minutes per task)\n * - Capacity cap (max 50 tasks, FIFO eviction when exceeded)\n * - Singleton access via `getTaskStore()`\n * - Periodic cleanup of expired tasks\n *\n * @module mcp/task-store\n * (Source: Issue #1298 — Layer 2 MCP Tasks async execution)\n */\n\nimport { InMemoryTaskStore } from '@modelcontextprotocol/sdk/experimental/tasks';\nimport type { TaskStore } from '@modelcontextprotocol/sdk/experimental/tasks';\nimport { createLogger } from '../core/index.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Maximum TTL for any task (10 minutes). */\nexport const MAX_TASK_TTL_MS = 600_000;\n\n/** Default TTL applied when none specified (5 minutes). */\nexport const DEFAULT_TASK_TTL_MS = 300_000;\n\n/** Maximum number of tasks before FIFO eviction. */\nexport const MAX_TASK_CAPACITY = 50;\n\n/** Interval for periodic cleanup of expired tasks (60 seconds). */\nconst CLEANUP_INTERVAL_MS = 60_000;\n\n// ============================================================================\n// Singleton\n// ============================================================================\n\nconst logger = createLogger({ component: 'task-store' });\n\nlet singletonStore: InMemoryTaskStore | undefined;\nlet cleanupTimer: ReturnType<typeof setInterval> | undefined;\n\n/**\n * Returns the singleton InMemoryTaskStore, creating it on first call.\n *\n * The SDK's InMemoryTaskStore handles TTL cleanup internally.\n * We enforce our MAX_TASK_TTL_MS via `clampTaskTtl()` at task creation\n * (done by the ToolTaskHandler, not the store itself).\n */\nexport function getTaskStore(): TaskStore {\n if (singletonStore === undefined) {\n singletonStore = new InMemoryTaskStore();\n logger.info('Task store created', { maxCapacity: MAX_TASK_CAPACITY });\n\n // Periodic cleanup: evict oldest tasks if capacity exceeded\n cleanupTimer = setInterval(() => {\n evictExcessTasks();\n }, CLEANUP_INTERVAL_MS);\n\n // Prevent cleanup timer from keeping Node alive\n if (typeof cleanupTimer === 'object' && 'unref' in cleanupTimer) {\n cleanupTimer.unref();\n }\n }\n return singletonStore;\n}\n\n/**\n * Clamps a requested TTL to the maximum allowed value.\n * Returns DEFAULT_TASK_TTL_MS if no TTL is specified or null.\n */\nexport function clampTaskTtl(requestedTtl?: number | null): number {\n if (requestedTtl === undefined || requestedTtl === null) {\n return DEFAULT_TASK_TTL_MS;\n }\n if (requestedTtl > MAX_TASK_TTL_MS) {\n logger.warn('Task TTL clamped to maximum', {\n requested: requestedTtl,\n max: MAX_TASK_TTL_MS,\n });\n return MAX_TASK_TTL_MS;\n }\n return requestedTtl;\n}\n\n/**\n * Evicts oldest tasks when capacity is exceeded (FIFO).\n * Best-effort — logs warnings but does not throw.\n */\nfunction evictExcessTasks(): void {\n if (singletonStore === undefined) return;\n\n const allTasks = singletonStore.getAllTasks();\n if (allTasks.length <= MAX_TASK_CAPACITY) return;\n\n // Sort by creation time ascending (oldest first)\n const sorted = [...allTasks].sort(\n (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n );\n\n const evictCount = sorted.length - MAX_TASK_CAPACITY;\n for (let i = 0; i < evictCount; i++) {\n const task = sorted[i];\n if (task === undefined) continue;\n singletonStore\n .updateTaskStatus(task.taskId, 'cancelled', 'Evicted: capacity exceeded')\n .catch((err: unknown) => {\n logger.debug('Failed to evict task', {\n taskId: task.taskId,\n error: String(err),\n });\n });\n }\n\n logger.info('Evicted excess tasks', { evicted: evictCount, total: sorted.length });\n}\n\n/**\n * Shuts down the task store and cleanup timer.\n * Call during server shutdown. Safe to call multiple times.\n * @internal\n */\nfunction shutdownTaskStore(): void {\n if (cleanupTimer !== undefined) {\n clearInterval(cleanupTimer);\n cleanupTimer = undefined;\n }\n if (singletonStore !== undefined) {\n singletonStore.cleanup();\n singletonStore = undefined;\n logger.info('Task store shut down');\n }\n}\n\n/** Resets the singleton for testing. @internal */\nexport function resetTaskStore(): void {\n shutdownTaskStore();\n}\n","/**\n * nexus-agents/cli - Pinned claude model probe for `doctor` (#6120)\n *\n * `doctor` reported the claude CLI healthy on a host whose pinned voter model\n * (`fable`, the adapter's default) was out of usage credits: it checked the\n * binary and its auth and inferred the model from those. Meanwhile every\n * claude voter seat failed and fell over to another CLI. This probe measures\n * the model itself with one short request.\n *\n * Three answers a presence check cannot give, and one honest non-answer:\n * `available` (content came back), `out-of-credits` (the CLI's durable\n * capacity text for that model), `error` (anything else the call reported),\n * and `not-probed` when the CLI is not installed — nothing was measured, so\n * nothing is claimed.\n *\n * The request disables the adapter's in-family fallback: a probe answered by\n * `opus` would report `fable` available, which is the inference this module\n * exists to replace.\n *\n * @module cli/doctor-claude-model\n */\n\nimport { getErrorMessage } from '../core/index.js';\nimport { isDurableCapacityText } from '../adapters/rate-limit-detector.js';\nimport {\n ClaudeCliAdapter,\n IN_FAMILY_FALLBACK_OPTION,\n} from '../cli-adapters/adapters/claude-adapter.js';\nimport { getCliModelName, getDefaultModelForCli } from '../config/model-config-helpers.js';\nimport { getDefaultRegistry } from '../config/model-registry.js';\nimport { resolveClassGuardMs } from '../config/timeouts.js';\nimport { colors, symbols } from './ansi-output.js';\nimport { SERVES_PROBE_PROMPT } from './cli-readiness.js';\n\n/** What the probe learned about the pinned model. */\nexport interface ClaudeModelProbe {\n /** The CLI alias that was (or would have been) requested, e.g. `fable`. */\n readonly alias: string;\n readonly status: 'available' | 'out-of-credits' | 'error' | 'not-probed';\n /** The adapter's message on `out-of-credits` / `error`, why on `not-probed`, null on `available`. */\n readonly reason: string | null;\n}\n\n/** The adapter surface the probe needs — the same shape the `--live` ladder uses. */\nexport interface ClaudeModelProbeTarget {\n execute(\n task: { content: string; maxTokens?: number; options?: Record<string, unknown> },\n options?: { timeoutMs?: number }\n ): Promise<{ ok: true; value: { text: string } } | { ok: false; error: { message: string } }>;\n}\n\n/**\n * The alias the adapter pins by default — the `--model` value voters actually\n * request (`fable`), not the vendor model name behind it (`claude-fable-5`).\n * Falls back to the model name for an entry without a CLI alias.\n */\nfunction pinnedClaudeAlias(): string {\n const modelId = getDefaultModelForCli('claude');\n return getDefaultRegistry().getEntry(modelId).cliAlias ?? getCliModelName(modelId);\n}\n\n/**\n * Probe the pinned claude model with one short request.\n *\n * `installed` gates the call: an absent binary yields `not-probed`, never a\n * failure, because a failure would claim a measurement that was not taken.\n * `adapter` and `alias` are injectable so the verdicts are testable without\n * the host's CLI; the defaults are the real adapter and its default model.\n */\nexport async function probeClaudePinnedModel(deps: {\n readonly installed: boolean;\n readonly alias?: string;\n readonly adapter?: ClaudeModelProbeTarget;\n readonly timeoutMs?: number;\n}): Promise<ClaudeModelProbe> {\n const alias = deps.alias ?? pinnedClaudeAlias();\n if (!deps.installed) {\n return { alias, status: 'not-probed', reason: 'claude CLI not installed' };\n }\n const adapter = deps.adapter ?? new ClaudeCliAdapter({ model: alias });\n const timeoutMs = deps.timeoutMs ?? resolveClassGuardMs('interactive');\n\n let result: Awaited<ReturnType<ClaudeModelProbeTarget['execute']>>;\n try {\n result = await adapter.execute(\n {\n content: SERVES_PROBE_PROMPT,\n maxTokens: 16,\n options: { [IN_FAMILY_FALLBACK_OPTION]: false },\n },\n { timeoutMs }\n );\n } catch (caught: unknown) {\n return { alias, status: 'error', reason: `probe threw: ${getErrorMessage(caught)}` };\n }\n\n if (!result.ok) {\n const status = isDurableCapacityText(result.error.message) ? 'out-of-credits' : 'error';\n return { alias, status, reason: result.error.message };\n }\n if (result.value.text.trim() === '') {\n return { alias, status: 'error', reason: 'call succeeded but returned no content' };\n }\n return { alias, status: 'available', reason: null };\n}\n\nconst STATUS_LABEL: Record<ClaudeModelProbe['status'], string> = {\n available: 'available',\n 'out-of-credits': 'out of credits',\n error: 'error',\n 'not-probed': 'not probed',\n};\n\n/** One doctor line: `Claude model <alias>: available | out of credits | error | not probed`. */\nexport function formatClaudeModelLine(probe: ClaudeModelProbe): string {\n const icon =\n probe.status === 'available'\n ? `${colors.green}${symbols.check}${colors.reset}`\n : probe.status === 'not-probed'\n ? `${colors.dim}${symbols.warn}${colors.reset}`\n : `${colors.yellow}${symbols.warn}${colors.reset}`;\n const detail = probe.reason === null ? '' : ` ${colors.dim}— ${probe.reason}${colors.reset}`;\n return `${icon} Claude model ${probe.alias}: ${STATUS_LABEL[probe.status]}${detail}`;\n}\n","/**\n * Doctor notes under the CLI list: CLIs disabled by `NEXUS_DISABLED_CLIS`\n * (#6590), and missing CLIs a passing gateway cannot stand in for (#6658). A\n * sibling of `doctor-formatting.ts` for the file cap, in the same shape as\n * `doctor-voter-transport.ts`.\n *\n * @module cli/doctor-disabled-clis\n */\n\nimport type { CliName } from '../cli-adapters/types.js';\nimport { colors, symbols, writeLine } from './ansi-output.js';\nimport { formatGatewaySlotWarnings } from './doctor-gateway-report.js';\nimport type { CliCheckResult, DoctorResult } from './doctor.js';\nimport type { GatewayHealth } from './doctor-gateway.js';\nimport { gatewaySlotServing } from './doctor-gateway-slots.js';\n\n/** The reason every report line gives for a CLI switched off on purpose. */\nconst DISABLED_BY_ENV = 'disabled by NEXUS_DISABLED_CLIS';\n\n/**\n * The model-advisory reason for a model whose CLI is disabled (#6728): it is\n * switched off, not missing, so the report must not tell the operator to\n * install it. When a healthy gateway has a slot for the CLI, the reason also\n * says whether the gateway serves that slot — the same `decideSlotServing`\n * answer `doctor --gateway` prints.\n */\nexport function disabledCliModelReason(\n cli: CliName,\n gateway: GatewayHealth,\n clis: readonly CliCheckResult[]\n): string {\n const base = `${cli} CLI is ${DISABLED_BY_ENV}`;\n const slot = gatewaySlotServing(gateway, clis).find((s) => s.slot === cli);\n if (slot === undefined) return base;\n return slot.serving === 'gateway'\n ? `${base}; the gateway serves its slot with ${slot.model}`\n : `${base}; the gateway has no ${slot.family} model`;\n}\n\n/**\n * Names the disabled CLIs. They are not probed, so without this line they\n * would simply be missing from the CLI list. Prints nothing when none is.\n */\nfunction printDisabledClis(disabled: readonly CliName[]): void {\n if (disabled.length === 0) return;\n writeLine(\n ` ${colors.yellow}${symbols.circle}${colors.reset} Disabled by NEXUS_DISABLED_CLIS: ${disabled.join(', ')} (not probed)`\n );\n}\n\n/**\n * The notes under the CLI list. The gateway-slot warnings print with every\n * `doctor` run, `--gateway` or not: they do not fail the verdict, but a\n * missing CLI whose slot the gateway cannot serve is never silently excused.\n */\nexport function printCliListNotes(\n result: Pick<DoctorResult, 'disabledClis' | 'gateway' | 'clis'>\n): void {\n printDisabledClis(result.disabledClis);\n for (const line of formatGatewaySlotWarnings(result.gateway, result.clis)) writeLine(line);\n}\n","/**\n * The doctor `MCP Client mode` line. A sibling of `doctor-formatting.ts` for\n * the file cap, in the same shape as `doctor-voter-transport.ts`.\n *\n * @module cli/doctor-mcp-client\n */\n\nimport { CODEX_MCP_SERVER_UNAVAILABLE_REASON } from '../cli-adapters/codex-mcp-server-probe.js';\nimport { colors, symbols } from './ansi-output.js';\nimport type { DoctorResult } from './doctor.js';\n\nconst MCP_CLIENT_UNAVAILABLE = `unavailable — ${CODEX_MCP_SERVER_UNAVAILABLE_REASON}; using codex exec`;\n\n/**\n * Client mode four ways. `mcpClientReady` is measured by the\n * `codex mcp-server --help` probe (#6119), so codex installed without the\n * subcommand (codex-cli >=0.154) is a warning that names the transport in use —\n * not \"Ready\" off the install, and not \"not installed\".\n *\n * Codex disabled by `NEXUS_DISABLED_CLIS` is a choice, not a fault (#6728): it\n * takes the CLI list's neutral circle, never the failure cross, and never says\n * \"not installed\". `mcpClientReady` is not a verdict term, so the line only\n * reports; it counts against readiness in no state.\n */\nexport function formatMcpClientLine(\n result: Pick<DoctorResult, 'mcpClientReady' | 'disabledClis' | 'clis'>\n): string {\n const codexInstalled = result.clis.some((cli) => cli.name === 'codex' && cli.installed);\n const [glyph, text] = result.mcpClientReady\n ? [`${colors.green}${symbols.check}`, 'Ready (Codex mcp-server)']\n : result.disabledClis.includes('codex')\n ? [`${colors.yellow}${symbols.circle}`, 'Disabled (codex disabled by NEXUS_DISABLED_CLIS)']\n : codexInstalled\n ? [`${colors.yellow}${symbols.warn}`, MCP_CLIENT_UNAVAILABLE]\n : [`${colors.red}${symbols.cross}`, 'Not ready (Codex not installed)'];\n return `${glyph}${colors.reset} MCP Client mode: ${text}`;\n}\n","/**\n * nexus-agents doctor — install-freshness sub-check (#4767).\n *\n * `.mcp.json` runs the MCP server off the **globally installed** package, not\n * the working tree. Nothing keeps the two in step: the release workflow\n * publishes to npm, and the global install is a separate manual\n * `npm install -g`. Drift accumulates silently, and every MCP call then\n * executes code the operator did not think they were running.\n *\n * Measured twice on 2026-08-25 alone: eleven minor versions behind in the\n * morning, three more by the afternoon.\n *\n * @module cli/doctor-install-freshness\n * (Source: #4767)\n */\n\n/** What the check could determine about the installed versions. */\nexport type InstallFreshness =\n /** Global install matches the package under test. */\n | { readonly state: 'aligned'; readonly version: string }\n /** Global install is present and older. */\n | { readonly state: 'behind'; readonly global: string; readonly expected: string }\n /**\n * The global version could not be read.\n *\n * Reported as its own state rather than folded into `aligned`: \"no global\n * install found\" and \"the versions match\" are different facts, and a check\n * that renders the first as the second is the shape this repo treats as a p1\n * on instrumentation.\n */\n | { readonly state: 'unknown'; readonly reason: string };\n\n/** `version.ts` reports this when `__NEXUS_VERSION__` was never injected. */\nconst UNVERSIONED_BUILD = 'dev';\n\n/** The remediation an operator has to perform, in full. */\nexport const INSTALL_FRESHNESS_REMEDY =\n 'npm install -g nexus-agents@latest — then RESTART any running MCP server. ' +\n 'An already-spawned server keeps the old code until it is restarted, so ' +\n 'updating alone leaves the session on the stale build.';\n\n/**\n * Compare the globally installed version against the expected one.\n *\n * Pure so the verdict is testable without npm. `expected` is the version of\n * the package this CLI was built from — the drift that matters is between what\n * the operator invokes and what the MCP server loads, and both derive from the\n * installed tree rather than from the registry.\n */\nexport function assessInstallFreshness(\n globalVersion: string | null,\n expected: string,\n unavailableReason = 'no global nexus-agents install found'\n): InstallFreshness {\n // `VERSION` is `'dev'` when `__NEXUS_VERSION__` was not injected — i.e. the\n // CLI is running from source rather than a build. There is no version to\n // compare against, so the honest answer is `unknown`. Reporting `behind`\n // would fire on every developer checkout and train people to ignore the one\n // line that matters on a real install (#4959).\n if (expected === UNVERSIONED_BUILD) {\n return {\n state: 'unknown',\n reason: 'running from source — this build has no version to compare',\n };\n }\n if (globalVersion === null || globalVersion === '') {\n return { state: 'unknown', reason: unavailableReason };\n }\n if (globalVersion === expected) return { state: 'aligned', version: expected };\n return { state: 'behind', global: globalVersion, expected };\n}\n\n/** One operator-facing line for a freshness verdict. */\nexport function describeInstallFreshness(result: InstallFreshness): string {\n switch (result.state) {\n case 'aligned':\n return `✓ Global install matches this build (${result.version})`;\n case 'behind':\n return `✗ Global install is ${result.global}, this build is ${result.expected} — the MCP server runs the global one. ${INSTALL_FRESHNESS_REMEDY}`;\n case 'unknown':\n return `? Global install version not determined (${result.reason}) — cannot confirm the MCP server runs this build`;\n }\n}\n\n/** True only when install freshness was measured and matches this build. */\nexport function installFreshnessIsHealthy(result: InstallFreshness): boolean {\n // `unknown` is NOT healthy. It is the state that produced #4767: nobody\n // checked, so nobody knew, and the absence read as fine.\n return result.state === 'aligned';\n}\n\n/** A short qualification for the overall doctor summary. */\nexport function describeInstallFreshnessSummary(result: InstallFreshness): string {\n if (result.state === 'behind') return ' — stale global install';\n if (result.state === 'unknown') return ' — install freshness unmeasured';\n return '';\n}\n\n/**\n * Read the globally installed version, or null when it cannot be determined.\n *\n * `npm ls -g` is the only reliable source: the global prefix is not derivable\n * from this process, which may itself be running from the global install, a\n * workspace link, or `npx`. Any failure yields null — reported as `unknown`\n * rather than guessed at.\n */\nexport function readGlobalVersion(exec: (cmd: string, args: readonly string[]) => string | null): {\n version: string | null;\n reason: string;\n} {\n const raw = exec('npm', ['ls', '-g', 'nexus-agents', '--depth=0', '--json']);\n if (raw === null) return { version: null, reason: 'npm ls -g failed' };\n try {\n const parsed: unknown = JSON.parse(raw);\n const deps = (parsed as { dependencies?: Record<string, { version?: string }> }).dependencies;\n const version = deps?.['nexus-agents']?.version;\n if (typeof version !== 'string' || version === '') {\n return { version: null, reason: 'no global nexus-agents install found' };\n }\n return { version, reason: '' };\n } catch {\n return { version: null, reason: 'npm ls -g returned unparseable JSON' };\n }\n}\n","/**\n * Verdict accounting for `nexus-agents doctor` — which of `isAllHealthy`'s terms\n * are currently failing.\n *\n * A separate module from the formatting because it answers a different question:\n * formatting decides how a result is rendered, this decides what counts as a\n * problem. Keeping the count derivable from a named list is what stops the\n * count and the verdict drifting apart again (#4851).\n *\n * @module cli/doctor-verdict-terms\n */\n\nimport { scratchSeverityIsAcceptable, worstSeverity } from './doctor-scratch-space.js';\nimport * as installFreshness from './doctor-install-freshness.js';\nimport type { DoctorResult } from './doctor.js';\nimport { cliFailsVerdict, gatewayVerdict, type GatewayVerdict } from './doctor-gateway.js';\n\n/**\n * The verdict's failing terms, named.\n *\n * #4851 established the invariant — every term `isAllHealthy` reads must be a\n * term the count reads, or a lone failing diagnostic renders \"Summary: 0\n * issue(s) found\": a summary shown ONLY because something is wrong, saying\n * nothing is wrong. It was fixed by adding the terms that were missing at the\n * time, which left two still absent (an unsupported CLI version, and\n * `hasAuthMethod`) and the same bug reachable two other ways.\n *\n * Returning the terms instead of a bare number is what stops that recurring:\n * the list is the count, so a term cannot be added to the verdict and forgotten\n * in the total. Keep this in step with {@link isAllHealthy} — every `&&` there\n * needs a row here.\n */\nexport function failingVerdictTerms(result: DoctorResult): string[] {\n const gateway = gatewayVerdict(result.gateway);\n const terms: string[] = gatewayTerms(result.gateway, gateway);\n if (!result.nodeVersion.supported) terms.push('node version');\n if (!result.mcpServerReady) terms.push('MCP server');\n if (!installFreshness.installFreshnessIsHealthy(result.installFreshness)) {\n terms.push('install freshness');\n }\n if (!scratchSeverityIsAcceptable(worstSeverity(result.scratchSpace))) terms.push('scratch space');\n // `hasAuthMethod` (an API key OR an installed+authenticated CLI) deliberately\n // gets NO row of its own. Whenever it fails with CLIs present, every CLI is\n // unauthenticated and the per-CLI rows below already count it; a separate row\n // would report one problem twice. Its only otherwise-uncovered case is an\n // empty CLI list, which the 'no CLIs detected' row covers.\n // `versionStatus === 'unsupported'` was the term the per-CLI filter missed: an\n // installed, authenticated CLI on an unsupported version failed the verdict\n // while contributing nothing to the count.\n // With a passing gateway a missing CLI is not a term (#6609): the same\n // predicate `isAllHealthy` uses decides both.\n for (const c of result.clis) {\n if (cliFailsVerdict(c, gateway)) terms.push(`CLI ${c.name}`);\n }\n // `isAllHealthy` passes `whenEmpty = false` (#4581) unless a gateway passes:\n // zero detected CLIs is not a healthy install. Without this row an\n // API-key-only setup with no CLI reads as unhealthy with nothing counted.\n if (result.clis.length === 0 && gateway !== 'pass') terms.push('no CLIs detected');\n return terms;\n}\n\n/** A failing gateway's term, naming its host (#6609); none otherwise. */\nfunction gatewayTerms(health: DoctorResult['gateway'], verdict: GatewayVerdict): string[] {\n return verdict === 'fail' && health.state !== 'not_configured' ? [`gateway ${health.host}`] : [];\n}\n","/**\n * nexus-agents doctor command - Formatting utilities\n *\n * Terminal output formatting for doctor command results.\n * Extracted to comply with 400-line file limit.\n *\n * (Source: Issue #422 - Doctor command validations)\n */\n\nimport { DEFAULT_CAPABILITIES, type CapacityStatus } from '../cli-adapters/types.js';\nimport { formatScratchFilesystems } from './doctor-scratch-space.js';\nimport { formatClaudeModelLine } from './doctor-claude-model.js';\nimport { printVoterTransportCheck } from './doctor-voter-transport.js';\nimport { printCliListNotes } from './doctor-disabled-clis.js';\nimport { formatMcpClientLine } from './doctor-mcp-client.js';\nimport type {\n CliCheckResult,\n NodeVersionCheck,\n ApiKeyCheck,\n ConfigFileCheck,\n RegistryAdvisory,\n LearningPersistenceCheck,\n SqliteCheck,\n DataDirectoryCheck,\n DoctorResult,\n} from './doctor.js';\nimport { colors, symbols, writeLine } from './ansi-output.js';\nimport { capitalize } from '../utils/text-utils.js';\nimport { allOf } from '../utils/verdict-aggregation.js';\nimport * as installFreshness from './doctor-install-freshness.js';\nimport { failingVerdictTerms } from './doctor-verdict-terms.js';\nimport { NODE_ENGINE_RANGE } from '../version.js';\n\n/**\n * Formats a status symbol with color.\n */\nfunction formatStatus(healthy: boolean, warn = false): string {\n if (healthy) return `${colors.green}${symbols.check}${colors.reset}`;\n if (warn) return `${colors.yellow}${symbols.warn}${colors.reset}`;\n return `${colors.red}${symbols.cross}${colors.reset}`;\n}\n\n/**\n * Formats version status with color.\n */\nfunction formatVersionStatus(status: string): string {\n switch (status) {\n case 'supported':\n return `${colors.green}supported${colors.reset}`;\n case 'outdated':\n return `${colors.yellow}outdated${colors.reset}`;\n case 'unsupported':\n case 'breaking':\n return `${colors.red}${status}${colors.reset}`;\n default:\n return status;\n }\n}\n\n/**\n * Formats capacity as percentage string.\n */\nfunction formatCapacity(capacity?: CapacityStatus): string {\n if (capacity === undefined) return 'Unknown';\n // #4374: a tracker that has never recorded a request reports the full token\n // limit and 0% utilization, which used to render as a green \"100% remaining\".\n // That is a default, not a measurement — and it is fiction for a CLI whose\n // weekly quota was consumed by another process. Say so instead.\n if (!capacity.observed) {\n return `${colors.yellow}unknown (no usage observed this session)${colors.reset}`;\n }\n const remaining = 100 - capacity.utilizationPercent;\n const remainingStr = String(remaining);\n if (remaining > 80) return `${colors.green}${remainingStr}% remaining${colors.reset}`;\n if (remaining > 20) return `${colors.yellow}${remainingStr}% remaining${colors.reset}`;\n return `${colors.red}${remainingStr}% remaining${colors.reset}`;\n}\n\n/**\n * Prints details for an installed CLI.\n */\nfunction printInstalledCliDetails(cli: CliCheckResult): void {\n writeLine(` Version: ${cli.version} (${formatVersionStatus(cli.versionStatus)})`);\n\n // Three states, not two (#4661). `unverified` is yellow because nothing was\n // measured — the same honest register as the `Capacity: unknown` line below.\n const authText =\n cli.authState === 'authenticated'\n ? `${colors.green}${cli.authMethod ?? 'Authenticated'}${colors.reset}`\n : cli.authState === 'unverified'\n ? `${colors.yellow}unverified (no non-interactive auth check)${colors.reset}`\n : `${colors.red}Not authenticated${colors.reset}`;\n writeLine(` Auth: ${authText}`);\n\n if (cli.capacity !== undefined) {\n writeLine(` Capacity: ${formatCapacity(cli.capacity)}`);\n }\n}\n\n/**\n * Prints a single CLI result.\n */\nfunction printCliResult(cli: CliCheckResult): void {\n const status = cli.installed && cli.authenticated;\n const warn = cli.installed && (!cli.authenticated || cli.versionStatus === 'outdated');\n\n writeLine(\n `${formatStatus(status, warn)} ${colors.bold}${capitalize(cli.name)} CLI${colors.reset}`\n );\n\n if (cli.installed) {\n printInstalledCliDetails(cli);\n } else {\n const errorText = cli.error ?? 'Not installed';\n writeLine(` ${colors.red}Error: ${errorText}${colors.reset}`);\n }\n\n if (cli.fix !== undefined && cli.fix !== '') {\n writeLine(` ${colors.dim}Fix: ${cli.fix}${colors.reset}`);\n }\n\n writeLine('');\n}\n\n/**\n * Prints capability summary for installed CLIs.\n */\nfunction printCapabilities(clis: CliCheckResult[]): void {\n const installedClis = clis.filter((c) => c.installed);\n\n if (installedClis.length === 0) {\n writeLine(`${formatStatus(false)} No CLIs installed`);\n return;\n }\n\n const caps = DEFAULT_CAPABILITIES;\n const bestReasoning = installedClis.reduce((best, c) =>\n caps[c.name].reasoning > caps[best.name].reasoning ? c : best\n );\n const bestContext = installedClis.reduce((best, c) =>\n caps[c.name].contextWindow > caps[best.name].contextWindow ? c : best\n );\n const bestSpeed = installedClis.reduce((best, c) =>\n caps[c.name].speed > caps[best.name].speed ? c : best\n );\n\n const contextTokensK = (caps[bestContext.name].contextWindow / 1000).toFixed(0);\n\n writeLine(\n `${formatStatus(true)} Complex reasoning: ${colors.bold}${capitalize(bestReasoning.name)}${colors.reset}`\n );\n writeLine(\n `${formatStatus(true)} Large context: ${colors.bold}${capitalize(bestContext.name)}${colors.reset} (${contextTokensK}K tokens)`\n );\n writeLine(\n `${formatStatus(true)} Fast execution: ${colors.bold}${capitalize(bestSpeed.name)}${colors.reset}`\n );\n}\n\n/**\n * Prints Node.js version check result.\n */\nfunction printNodeVersionCheck(check: NodeVersionCheck): void {\n const versionText = check.supported\n ? `${colors.green}${check.version}${colors.reset}`\n : `${colors.yellow}${check.version}${colors.reset}`;\n writeLine(`${formatStatus(check.supported, !check.supported)} Node.js version: ${versionText}`);\n if (!check.supported) {\n writeLine(` ${colors.dim}Warning: Node.js ${NODE_ENGINE_RANGE} required${colors.reset}`);\n }\n}\n\n/**\n * Prints API key configuration check results.\n */\nfunction printApiKeysCheck(keys: ApiKeyCheck[]): void {\n const configuredCount = keys.filter((k) => k.configured).length;\n const configuredNames = keys.filter((k) => k.configured).map((k) => k.name);\n const hasAny = configuredCount > 0;\n\n writeLine(\n `${formatStatus(hasAny, !hasAny)} API keys configured: ${String(configuredCount)} of ${String(keys.length)}`\n );\n if (hasAny) {\n writeLine(` ${colors.dim}Keys: ${configuredNames.join(', ')}${colors.reset}`);\n } else {\n writeLine(\n ` ${colors.dim}Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_AI_API_KEY${colors.reset}`\n );\n }\n}\n\n/**\n * Prints configuration file check result.\n */\nfunction printConfigFileCheck(check: ConfigFileCheck): void {\n if (check.found && check.path !== null) {\n writeLine(`${formatStatus(true)} Configuration loaded: ${check.path}`);\n } else {\n writeLine(`${formatStatus(false, true)} Configuration file: Not found`);\n writeLine(` ${colors.dim}Run: nexus-agents config init${colors.reset}`);\n }\n}\n\n/**\n * Prints model registry advisory (#890).\n */\nfunction printRegistryAdvisory(advisory: RegistryAdvisory): void {\n const allAvailable = advisory.unavailableModels === 0;\n const countText = `${String(advisory.availableModels)} of ${String(advisory.totalModels)}`;\n writeLine(`${formatStatus(allAvailable, !allAvailable)} Models available: ${countText}`);\n if (advisory.unavailableModels > 0) {\n const missing = advisory.models.filter((m) => !m.available);\n for (const m of missing) {\n writeLine(` ${colors.dim}${m.displayName} — ${m.reason}${colors.reset}`);\n }\n }\n // Registry staleness warning (#1549, revised in #2445)\n const ageText = `${String(advisory.registryAgeDays)} days old`;\n if (advisory.registryStale) {\n writeLine(\n `${colors.yellow}${symbols.warn}${colors.reset} Model registry is ${ageText} — may have stale model data`\n );\n writeLine(\n ` ${colors.dim}Update with 'npm update -g nexus-agents' to pick up the latest registry,${colors.reset}`\n );\n writeLine(\n ` ${colors.dim}or run 'nexus-agents registry refresh' to probe currently-installed models.${colors.reset}`\n );\n } else {\n writeLine(`${formatStatus(true)} Model registry: ${ageText}`);\n }\n}\n\n/**\n * Prints learning persistence health check (#1017).\n */\nfunction printLearningPersistence(check: LearningPersistenceCheck): void {\n if (!check.enabled) {\n writeLine(`${formatStatus(true)} Learning persistence: ${colors.dim}Disabled${colors.reset}`);\n writeLine(` ${colors.dim}Set NEXUS_PERSIST_LEARNING=true to enable${colors.reset}`);\n return;\n }\n\n const healthy = check.dirExists && check.dirWritable && check.error === null;\n writeLine(`${formatStatus(healthy, !healthy)} Learning persistence: Enabled`);\n\n if (check.error !== null) {\n writeLine(` ${colors.red}Error: ${check.error}${colors.reset}`);\n return;\n }\n\n const dirStatus = check.dirExists\n ? check.dirWritable\n ? `${colors.green}writable${colors.reset}`\n : `${colors.red}not writable${colors.reset}`\n : `${colors.yellow}not created yet${colors.reset}`;\n writeLine(` Data directory: ${dirStatus}`);\n writeLine(` Outcomes: ${String(check.outcomeCount)} recorded`);\n // #6512: informational, never a failure. N is every persisted rule; A is the\n // active ones routing applies. E is what the last distill trained on (from\n // the snapshot); the whole-file eligible count is labelled separately because\n // the distiller only sees the store's newest-10k window.\n const trained =\n check.trainedOnEligible === null\n ? 'trained-on count not recorded'\n : `trained on ${String(check.trainedOnEligible)} eligible outcomes`;\n writeLine(\n ` Distilled rules: ${String(check.ruleCount)} (${String(check.activeRuleCount)} active; ${trained}; last distill: ${check.rulesLastSaved ?? 'never'})`\n );\n writeLine(\n ` Eligible outcomes in outcomes.jsonl (whole file): ${String(check.fileEligibleOutcomeCount)}`\n );\n // #6521: the routed count is the loop's input; a zero here is the finding,\n // not a failure, so it renders as a plain line.\n writeLine(\n ` Routed outcomes (CompositeRouter): ${String(check.routedOutcomes.total)} total, ${String(check.routedOutcomes.last7Days)} in the last 7 days`\n );\n}\n\n/**\n * Prints SQLite (node:sqlite) availability check (#1249).\n */\nfunction printSqliteCheck(check: SqliteCheck): void {\n if (check.available) {\n writeLine(\n `${formatStatus(true)} SQLite (node:sqlite): ${colors.green}Available${colors.reset}`\n );\n } else {\n writeLine(\n `${formatStatus(false, true)} SQLite (node:sqlite): ${colors.yellow}Not available${colors.reset}`\n );\n writeLine(\n ` ${colors.dim}Memory backends (agentic, adaptive, typed) require it${colors.reset}`\n );\n writeLine(` ${colors.dim}Fix: upgrade to Node >= 22.5.0${colors.reset}`);\n }\n}\n\n/** Prints one scope group of data subdirs with per-subdir resolved paths. */\nfunction printDataDirGroup(\n label: string,\n rootHint: string,\n subdirs: readonly DataDirectoryCheck['subdirectories'][number][]\n): void {\n if (subdirs.length === 0) return;\n const existCount = subdirs.filter((d) => d.exists).length;\n writeLine(\n ` ${colors.dim}${label} — ${rootHint} (${String(existCount)}/${String(subdirs.length)})${colors.reset}`\n );\n for (const dir of subdirs) {\n let marker: string;\n if (!dir.exists) marker = `${colors.dim}·${colors.reset}`;\n else if (!dir.writable) marker = `${colors.yellow}!${colors.reset}`;\n else marker = `${colors.green}✓${colors.reset}`;\n const note = !dir.exists\n ? ` ${colors.dim}(missing — created on first use)${colors.reset}`\n : !dir.writable\n ? ` ${colors.yellow}(not writable)${colors.reset}`\n : '';\n writeLine(` ${marker} ${dir.name} ${colors.dim}${dir.path}${colors.reset}${note}`);\n }\n}\n\n/**\n * Prints data directory health check (#1249, extended #2892).\n * Groups subdirs by the epic #2872 state-split so the operator sees\n * exactly where per-repo vs cross-repo state lives.\n */\nfunction printDataDirectory(check: DataDirectoryCheck): void {\n // whenEmpty = false: a layout with zero known subdirectories was not\n // measured, and printing it as healthy is the vacuous pass (#4581).\n const allExist = allOf(check.subdirectories, (d) => d.exists, false);\n const allWritable = allOf(check.subdirectories, (d) => !d.exists || d.writable, false);\n const healthy = check.rootExists && allWritable;\n\n writeLine(`${formatStatus(healthy, !healthy)} Data directory layout:`);\n\n const perRepo = check.subdirectories.filter((d) => d.scope === 'per-repo');\n const crossRepo = check.subdirectories.filter((d) => d.scope === 'cross-repo');\n\n if (check.repoRoot !== null) {\n printDataDirGroup('Per-repo', check.repoRoot, perRepo);\n } else {\n // Repo-preferred tier inactive — per-repo subdirs also live in homedir.\n printDataDirGroup('Per-repo (homedir — repo-preferred off)', check.rootPath, perRepo);\n }\n printDataDirGroup('Cross-repo', check.rootPath, crossRepo);\n\n if (!allExist) {\n writeLine(` ${colors.dim}Fix: nexus-agents setup${colors.reset}`);\n }\n}\n\nfunction printSandboxHeader(check: DoctorResult['sandbox']): void {\n if (check.active) {\n writeLine(`${formatStatus(true)} Sandbox flavor: ${check.flavor ?? '(unknown)'}`);\n writeLine(` ${colors.dim}NEXUS_SANDBOX_ROOT: ${check.root ?? '(unset)'}${colors.reset}`);\n return;\n }\n writeLine(\n `${formatStatus(false, true)} Container detected (${check.heuristicMatch ?? 'unknown'}) but ${colors.yellow}NEXUS_SANDBOX is unset${colors.reset}`\n );\n writeLine(\n ` ${colors.dim}Set NEXUS_SANDBOX=<flavor> in the image to opt into sandbox-aware behaviour.${colors.reset}`\n );\n}\n\nfunction printSandboxWarnings(check: DoctorResult['sandbox']): void {\n if (check.mismatch && check.active) {\n writeLine(\n ` ${colors.yellow}Mismatch: NEXUS_SANDBOX is set but no container heuristic matched (heuristic=${String(check.heuristicMatch)}).${colors.reset}`\n );\n }\n if (check.dataDirInsideRepo) {\n writeLine(\n ` ${colors.yellow}NEXUS_DATA_DIR resolves inside a single repo subfolder of NEXUS_SANDBOX_ROOT — state will be lost when switching repos. Set NEXUS_DATA_DIR at the multi-repo root.${colors.reset}`\n );\n }\n}\n\n/**\n * Prints the sandbox-awareness section (#2501). Section is suppressed when\n * neither the explicit signal nor the heuristic indicates a sandbox.\n */\nfunction printSandbox(check: DoctorResult['sandbox']): void {\n const heuristicSaysContainer =\n check.heuristicMatch === 'docker' || check.heuristicMatch === 'podman';\n if (!check.active && !heuristicSaysContainer) {\n return;\n }\n writeLine(`${colors.cyan}Checking sandbox awareness...${colors.reset}`);\n writeLine('');\n printSandboxHeader(check);\n printSandboxWarnings(check);\n writeLine('');\n}\n\n/** Prints the summary line with issue count. */\nfunction printDoctorSummary(result: DoctorResult): void {\n const terms = failingVerdictTerms(result);\n const freshnessNote = installFreshness.describeInstallFreshnessSummary(result.installFreshness);\n // Name the terms, don't just count them (#6011). `doctor` marks several lines\n // with a warning glyph, and only some of them are counted — the API-keys note\n // is advisory because CLI auth already satisfies `hasAuthMethod`. A bare count\n // left the reader to re-derive which warning it referred to, which meant\n // reading printDoctorSummary to find out.\n // Parenthesised, not after an em dash: `freshnessNote` already appends its own\n // ` — stale global install` clause, and two dash-separated clauses on one line\n // read as a single run-on. Seen in the real output before this was changed.\n const named = terms.length > 0 ? ` (${terms.join(', ')})` : '';\n const summary = result.allHealthy\n ? `${colors.green}${colors.bold}Status: Ready${colors.reset}${freshnessNote}`\n : `${colors.yellow}${colors.bold}Summary: ${String(terms.length)} issue(s) found${named}${colors.reset}${freshnessNote}`;\n writeLine(`${summary}\\n`);\n}\n\n/** MCP server mode, then client mode (`doctor-mcp-client.ts`). */\nfunction printMcpModes(result: DoctorResult): void {\n const server = result.mcpServerReady ? 'Ready' : 'Not ready';\n writeLine(`${formatStatus(result.mcpServerReady)} MCP Server mode: ${server}`);\n writeLine(formatMcpClientLine(result));\n}\n\n/**\n * Prints the doctor results to stdout.\n */\nexport function printDoctorResults(result: DoctorResult): void {\n writeLine('');\n writeLine(`${colors.bold}Nexus Agents Doctor${colors.reset}`);\n writeLine('===================');\n writeLine('');\n\n writeLine(`${colors.cyan}Checking environment...${colors.reset}`);\n writeLine('');\n printNodeVersionCheck(result.nodeVersion);\n printApiKeysCheck(result.apiKeys);\n printConfigFileCheck(result.configFile);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking CLI installations...${colors.reset}`);\n writeLine('');\n for (const cli of result.clis) printCliResult(cli);\n printCliListNotes(result);\n // #6120: the pinned voter model, MEASURED with one call, not inferred.\n writeLine(formatClaudeModelLine(result.claudeModel));\n writeLine('');\n\n writeLine(`${colors.cyan}Checking MCP configuration...${colors.reset}`);\n writeLine('');\n printMcpModes(result);\n printVoterTransportCheck(result.voterTransport, result.gateway);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking capabilities...${colors.reset}`);\n writeLine('');\n printCapabilities(result.clis);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking model registry...${colors.reset}`);\n writeLine('');\n printRegistryAdvisory(result.registryAdvisory);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking learning subsystem...${colors.reset}`);\n writeLine('');\n printLearningPersistence(result.learningPersistence);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking data storage...${colors.reset}`);\n writeLine('');\n printSqliteCheck(result.sqliteCheck);\n printDataDirectory(result.dataDirectory);\n // #4488: a full scratch filesystem is invisible until a subprocess dies at\n // the write step, so surface headroom alongside the other storage checks.\n writeLine(formatScratchFilesystems(result.scratchSpace));\n writeLine('');\n\n printSandbox(result.sandbox);\n\n printHarnessAlignment(result.harnessAlignment);\n\n printInstallFreshness(result.installFreshness);\n\n printDoctorSummary(result);\n}\n\n/** Prints the global install comparison added after its verdict was not surfaced (#4767, #4959). */\nfunction printInstallFreshness(check: DoctorResult['installFreshness']): void {\n writeLine(`${colors.cyan}Checking global install freshness...${colors.reset}\\n`);\n writeLine(` ${installFreshness.describeInstallFreshness(check)}\\n`);\n}\n\n/**\n * Prints harness-alignment status (#2805 Phase 3). Shows which harness\n * config files are present and whether they redirect to AGENTS.md per\n * the option-B federation contract.\n */\nfunction printHarnessAlignment(check: DoctorResult['harnessAlignment']): void {\n writeLine(`${colors.cyan}Checking agent-harness alignment...${colors.reset}\\n`);\n\n if (!check.inProject) {\n writeLine(\n `${colors.gray}${symbols.circle}${colors.reset} AGENTS.md: not run inside a project — harness alignment not applicable (run doctor from your repo root)\\n`\n );\n return;\n }\n\n writeLine(\n `${formatStatus(check.agentsMdExists)} AGENTS.md: ${check.agentsMdExists ? 'present (federated surface)' : 'MISSING — federation invariant broken'}`\n );\n\n for (const f of check.files) {\n if (!f.exists) {\n writeLine(` ${colors.gray}○${colors.reset} ${f.harness}: not present (${f.path})`);\n continue;\n }\n if (f.error !== null) {\n writeLine(` ${colors.red}✗${colors.reset} ${f.harness}: ${f.error}`);\n continue;\n }\n if (f.redirectsToAgentsMd) {\n writeLine(` ${colors.green}✓${colors.reset} ${f.harness}: aligned (${f.path})`);\n } else {\n writeLine(\n ` ${colors.yellow}⚠${colors.reset} ${f.harness}: drift — ${f.path} exists but does NOT mention AGENTS.md`\n );\n }\n }\n\n writeLine('');\n writeLine(\n ` Summary: ${String(check.alignedCount)} aligned, ${String(check.driftCount)} drift, ${String(check.missingCount)} absent`\n );\n if (check.driftCount > 0) {\n writeLine(\n ` ${colors.yellow}Drift detected.${colors.reset} Per docs/architecture/AGENT_COMPATIBILITY.md, harness configs must redirect to AGENTS.md — never duplicate content.`\n );\n }\n writeLine('');\n}\n","/**\n * nexus-agents doctor — harness-alignment sub-check.\n *\n * Phase 3 of #2805 (option B federation of #2764). Walks the\n * harness-specific config files in the current working directory and\n * reports whether each one redirects to AGENTS.md (aligned), exists\n * with non-redirect content (drift), or is absent (missing).\n *\n * \"Aligned\" means the file mentions AGENTS.md somewhere in its content.\n * That's intentionally loose — we don't try to parse Cursor MDC frontmatter\n * or Aider YAML semantics; the federation invariant is \"the file points\n * at AGENTS.md, never duplicates content.\" A grep for the literal string\n * is the right granularity.\n *\n * @module cli/doctor-harness-alignment\n * (Source: #2805 / #2764)\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { findRepoRoot } from '../config/repo-root-detection.js';\n\n/** Per-harness alignment status. */\nexport interface HarnessFileStatus {\n /** Human label, e.g. \"Cursor\". */\n readonly harness: string;\n /** Repo-relative path to the discovery file. */\n readonly path: string;\n /** True if the file exists on disk. */\n readonly exists: boolean;\n /** True if the file's content mentions `AGENTS.md` (the federation invariant). */\n readonly redirectsToAgentsMd: boolean;\n /** First read/stat error encountered, if any. */\n readonly error: string | null;\n}\n\n/** Aggregated harness-alignment health. */\nexport interface HarnessAlignmentCheck {\n /** True iff cwd or an ancestor contains a package.json or .git marker. */\n readonly inProject: boolean;\n /** True iff AGENTS.md is the federated surface (canonical doc exists). */\n readonly agentsMdExists: boolean;\n /** Per-harness rows. */\n readonly files: readonly HarnessFileStatus[];\n /** Count of harnesses with a properly-redirected config. */\n readonly alignedCount: number;\n /** Count of harnesses with a config file that exists but doesn't redirect (drift). */\n readonly driftCount: number;\n /** Count of harnesses with no config file (acceptable; harness not in use). */\n readonly missingCount: number;\n}\n\n/**\n * Each harness's expected discovery file. Order matches the compatibility\n * matrix in `docs/architecture/AGENT_COMPATIBILITY.md`.\n */\nconst HARNESS_FILES: ReadonlyArray<{ harness: string; path: string }> = [\n { harness: 'Cursor', path: '.cursor/rules/agents.mdc' },\n { harness: 'Windsurf', path: '.windsurf/rules/agents.md' },\n { harness: 'Aider', path: '.aider.conf.yml' },\n { harness: 'Continue', path: '.continue/rules/agents.md' },\n { harness: 'Cline', path: '.clinerules/agents.md' },\n // Gemini CLI reads a root-level GEMINI.md natively (unlike the .rules/-dir\n // harnesses); it redirects to AGENTS.md per the federation (#3446 Phase 4).\n { harness: 'Gemini', path: 'GEMINI.md' },\n];\n\n/**\n * Walk every known harness discovery file at the given root (defaults\n * to `process.cwd()`) and report alignment status.\n */\nexport function checkHarnessAlignment(cwd: string = process.cwd()): HarnessAlignmentCheck {\n const inProject = findRepoRoot(cwd) !== null || hasPackageJsonAncestor(cwd);\n const agentsMdPath = join(cwd, 'AGENTS.md');\n const agentsMdExists = existsSync(agentsMdPath);\n\n const files: HarnessFileStatus[] = HARNESS_FILES.map(({ harness, path }) =>\n inspectFile(harness, path, join(cwd, path))\n );\n\n const alignedCount = files.filter((f) => f.exists && f.redirectsToAgentsMd).length;\n const driftCount = files.filter((f) => f.exists && !f.redirectsToAgentsMd).length;\n const missingCount = files.filter((f) => !f.exists).length;\n\n return {\n inProject,\n agentsMdExists,\n files,\n alignedCount,\n driftCount,\n missingCount,\n };\n}\n\n/** Returns whether the starting directory or an ancestor contains package.json. */\nfunction hasPackageJsonAncestor(start: string): boolean {\n let current = resolve(start);\n for (;;) {\n if (existsSync(join(current, 'package.json'))) return true;\n const parent = dirname(current);\n if (parent === current) return false;\n current = parent;\n }\n}\n\nfunction inspectFile(\n harness: string,\n relativePath: string,\n absolutePath: string\n): HarnessFileStatus {\n if (!existsSync(absolutePath)) {\n return {\n harness,\n path: relativePath,\n exists: false,\n redirectsToAgentsMd: false,\n error: null,\n };\n }\n try {\n const content = readFileSync(absolutePath, 'utf-8');\n return {\n harness,\n path: relativePath,\n exists: true,\n redirectsToAgentsMd: content.includes('AGENTS.md'),\n error: null,\n };\n } catch (error: unknown) {\n return {\n harness,\n path: relativePath,\n exists: true,\n redirectsToAgentsMd: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n"],"mappings":"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","names":["existsSync","existsSync","readFileSync","err","logger","existsSync","readFileSync","writeLine","initDataDirectories","describeDataDirFix","existsSync"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadPapersRegistry
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EBWQVNA2.js";
|
|
4
4
|
import {
|
|
5
5
|
getErrorMessage
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FDASKOC7.js";
|
|
7
7
|
|
|
8
8
|
// src/cli/research-helpers-synthesize.ts
|
|
9
9
|
import { z } from "zod";
|
|
@@ -876,4 +876,4 @@ export {
|
|
|
876
876
|
AttributedInsightSchema,
|
|
877
877
|
synthesizeResearch
|
|
878
878
|
};
|
|
879
|
-
//# sourceMappingURL=chunk-
|
|
879
|
+
//# sourceMappingURL=chunk-2T6Q3JTZ.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
err,
|
|
5
5
|
getErrorMessage,
|
|
6
6
|
ok
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FDASKOC7.js";
|
|
8
8
|
|
|
9
9
|
// src/scm/types.ts
|
|
10
10
|
var ScmError = class extends Error {
|
|
@@ -281,4 +281,4 @@ export {
|
|
|
281
281
|
ScmError,
|
|
282
282
|
GitHubProvider
|
|
283
283
|
};
|
|
284
|
-
//# sourceMappingURL=chunk-
|
|
284
|
+
//# sourceMappingURL=chunk-4YGPA6RY.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getErrorMessage,
|
|
8
8
|
getTimeProvider,
|
|
9
9
|
ok
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FDASKOC7.js";
|
|
11
11
|
|
|
12
12
|
// src/context/session-memory.ts
|
|
13
13
|
import * as fs from "node:fs";
|
|
@@ -374,4 +374,4 @@ export {
|
|
|
374
374
|
SessionMemory,
|
|
375
375
|
createSessionMemory
|
|
376
376
|
};
|
|
377
|
-
//# sourceMappingURL=chunk-
|
|
377
|
+
//# sourceMappingURL=chunk-56BNVEYR.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JEAVQI3X.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveInsideRoot
|
|
6
6
|
} from "./chunk-XEPZSDN5.js";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
sanitizeErrorDetails,
|
|
12
12
|
sanitizeStringLeaves
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7OID2D3X.js";
|
|
14
14
|
import {
|
|
15
15
|
CACHE_TIMEOUTS,
|
|
16
16
|
MCP_TIMEOUTS,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
getTimeProvider,
|
|
28
28
|
ok,
|
|
29
29
|
resolveToolClassGuardMs
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-FDASKOC7.js";
|
|
31
31
|
import {
|
|
32
32
|
getNexusDataDir,
|
|
33
33
|
parseBoolValue
|
|
@@ -2329,4 +2329,4 @@ export {
|
|
|
2329
2329
|
DEFAULT_CONSENSUS_CONFIG,
|
|
2330
2330
|
ConsensusMetricsSchema
|
|
2331
2331
|
};
|
|
2332
|
-
//# sourceMappingURL=chunk-
|
|
2332
|
+
//# sourceMappingURL=chunk-5U5MRUIO.js.map
|