nexus-agents 8.7.1 → 8.8.1
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-EX3ZL4BZ.js → ast-rule-runner-WANOR3MX.js} +5 -5
- package/dist/{child-mcp-config-25OKN6ZQ.js → child-mcp-config-N4HLLCEH.js} +5 -5
- package/dist/{chunk-CDZ7OWH6.js → chunk-276GRITW.js} +4 -4
- package/dist/{chunk-CVXYAPJB.js → chunk-3CLKYFE3.js} +74 -7
- package/dist/chunk-3CLKYFE3.js.map +1 -0
- package/dist/{chunk-JWWNTXSI.js → chunk-3XQK4MEF.js} +2 -2
- package/dist/{chunk-JWDVKO3Q.js → chunk-3YKFLM2B.js} +2 -2
- package/dist/{chunk-4WB3SB7K.js → chunk-64VMTY3M.js} +2 -2
- package/dist/{chunk-LRXMR353.js → chunk-6HETGJSB.js} +3 -3
- package/dist/{chunk-ODBLHHTP.js → chunk-6URMW3DB.js} +2 -2
- package/dist/{chunk-NJ66YYG5.js → chunk-7AU5WLAJ.js} +2 -2
- package/dist/{chunk-5I47G22O.js → chunk-7J7UYJXC.js} +7 -7
- package/dist/{chunk-YOEB6RVH.js → chunk-7QQ5F7T5.js} +9 -9
- package/dist/{chunk-ITCKXMOH.js → chunk-7WJGV5DN.js} +2 -2
- package/dist/{chunk-PFMNPQI7.js → chunk-AOS7F4QR.js} +2 -2
- package/dist/{chunk-4HXPNLZS.js → chunk-DKHBIJO4.js} +2 -2
- package/dist/chunk-DROYVWGE.js +7 -0
- package/dist/{chunk-IBGMNZWT.js → chunk-EALWAQAQ.js} +49 -16
- package/dist/chunk-EALWAQAQ.js.map +1 -0
- package/dist/{chunk-HCN3FRNG.js → chunk-ERL3XHQO.js} +54 -7
- package/dist/chunk-ERL3XHQO.js.map +1 -0
- package/dist/{chunk-YAQ6OYOI.js → chunk-F2GERNMF.js} +2 -2
- package/dist/{chunk-FLHLOQ5H.js → chunk-FBWOWMEB.js} +3 -3
- package/dist/{chunk-7NW6RNJK.js → chunk-FKKVZRSY.js} +2 -2
- package/dist/{chunk-O6GVBBGY.js → chunk-FUMZUCP2.js} +10 -10
- package/dist/{chunk-BM2QAXLR.js → chunk-GXLI2E4U.js} +4 -4
- package/dist/{chunk-SNNEXDCG.js → chunk-II5NJRKH.js} +2 -2
- package/dist/{chunk-MM223CVS.js → chunk-J7QCZRVK.js} +6 -1
- package/dist/{chunk-MM223CVS.js.map → chunk-J7QCZRVK.js.map} +1 -1
- package/dist/{chunk-JG2W7NC5.js → chunk-K2PVLCHR.js} +2 -2
- package/dist/{chunk-H32Z7H3Y.js → chunk-MXQG3A5W.js} +6 -6
- package/dist/{chunk-YAZ4CCF6.js → chunk-N347WXTT.js} +2 -2
- package/dist/{chunk-MBKTQ5U6.js → chunk-NEJF4F6R.js} +4 -4
- package/dist/{chunk-ZIRGSFK3.js → chunk-NR62IQDC.js} +6 -6
- package/dist/{chunk-WUC3YSW6.js → chunk-OCAMHBJ6.js} +10 -10
- package/dist/{chunk-6OY47Y5W.js → chunk-Q5V3KTUL.js} +2 -2
- package/dist/{chunk-JKNVGOQH.js → chunk-QCSXKQTK.js} +2 -2
- package/dist/{chunk-GK3NWFSX.js → chunk-SNSPYZQT.js} +5 -5
- package/dist/{chunk-THKP4RUM.js → chunk-TZWJ7QLW.js} +2 -2
- package/dist/{chunk-AQZSXWPJ.js → chunk-VADACTVB.js} +2 -2
- package/dist/{chunk-KUVHSVZT.js → chunk-VBC4JBRH.js} +5 -5
- package/dist/{chunk-UVUZMLEJ.js → chunk-WXU4Y5T3.js} +2 -2
- package/dist/{chunk-EYYICIRG.js → chunk-Z55IEIBU.js} +113 -105
- package/dist/{chunk-EYYICIRG.js.map → chunk-Z55IEIBU.js.map} +1 -1
- package/dist/{chunk-R7Z535GF.js → chunk-ZGHJMFQ6.js} +3 -3
- package/dist/{cli-circuit-breaker-55QP7IJF.js → cli-circuit-breaker-AAHYLFXZ.js} +5 -5
- package/dist/cli.js +47 -47
- package/dist/{composite-router-7TJ2CPZ3.js → composite-router-VAVDLJGT.js} +4 -4
- package/dist/{consensus-vote-73JHBSPS.js → consensus-vote-YYAWXULO.js} +21 -21
- package/dist/{context-retriever-TODKVXFP.js → context-retriever-MYKBBDAN.js} +11 -11
- package/dist/doctor-deep-AKOPPCXB.js +13 -0
- package/dist/{doctor-live-EZ54XOSM.js → doctor-live-3PVIYQST.js} +12 -12
- package/dist/{expert-bridge-H7OXGW4O.js → expert-bridge-G3KN7QWL.js} +6 -6
- package/dist/factory-KVMLFEWJ.js +15 -0
- package/dist/factory-ROTP63IZ.js +25 -0
- package/dist/{improvement-review-UBAMECJM.js → improvement-review-LEITEY7D.js} +8 -8
- package/dist/index.d.ts +61 -5
- package/dist/index.js +38 -36
- package/dist/index.js.map +1 -1
- package/dist/{init-opencode-G2THTE4E.js → init-opencode-C63LASGX.js} +8 -8
- package/dist/issue-triage-PIE3YVCV.js +17 -0
- package/dist/{learning-persistence-7N5SZHNX.js → learning-persistence-JK2FELZL.js} +3 -3
- package/dist/{pr-reviewer-helpers-TMIOHSRZ.js → pr-reviewer-helpers-4VDGMGV5.js} +6 -6
- package/dist/{registry-command-IPCVJL7U.js → registry-command-IRDP2L2R.js} +4 -4
- package/dist/{repo-security-plan-KSD46QDB.js → repo-security-plan-NS47HQEF.js} +5 -5
- package/dist/research-helpers-synthesize-5NBL637T.js +14 -0
- package/dist/{routing-memory-4BHIRI57.js → routing-memory-2IELT5GT.js} +4 -4
- package/dist/{session-memory-YAES7LJ3.js → session-memory-CH3CVLIT.js} +5 -5
- package/dist/setup-config-MKZZDUJP.js +11 -0
- package/dist/{setup-custom-api-JNFW5LFD.js → setup-custom-api-2I52S7XU.js} +6 -6
- package/dist/setup-data-dir-I6LJVAPB.js +29 -0
- package/dist/{tool-memory-4FCZAUV6.js → tool-memory-STS3DWOK.js} +8 -8
- package/dist/{tool-memory-registry-adapters-PCOYMYRF.js → tool-memory-registry-adapters-MZ5CSCYW.js} +3 -3
- package/dist/unified-registry-NJS4ZWC3.js +26 -0
- package/dist/{weather-report-XGPJTPHN.js → weather-report-YG4T4Q23.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-CVXYAPJB.js.map +0 -1
- package/dist/chunk-HCN3FRNG.js.map +0 -1
- package/dist/chunk-IBGMNZWT.js.map +0 -1
- package/dist/chunk-Q55BOZUM.js +0 -7
- package/dist/doctor-deep-EZLG3E2Q.js +0 -13
- package/dist/factory-B3SHAF4G.js +0 -15
- package/dist/factory-IOQC3B5Y.js +0 -25
- package/dist/issue-triage-2MSODPKO.js +0 -17
- package/dist/research-helpers-synthesize-I34CSJDD.js +0 -14
- package/dist/setup-config-SZ2NM2SE.js +0 -11
- package/dist/setup-data-dir-UMVVYGNX.js +0 -29
- package/dist/unified-registry-7GGDIT6Q.js +0 -26
- /package/dist/{ast-rule-runner-EX3ZL4BZ.js.map → ast-rule-runner-WANOR3MX.js.map} +0 -0
- /package/dist/{child-mcp-config-25OKN6ZQ.js.map → child-mcp-config-N4HLLCEH.js.map} +0 -0
- /package/dist/{chunk-CDZ7OWH6.js.map → chunk-276GRITW.js.map} +0 -0
- /package/dist/{chunk-JWWNTXSI.js.map → chunk-3XQK4MEF.js.map} +0 -0
- /package/dist/{chunk-JWDVKO3Q.js.map → chunk-3YKFLM2B.js.map} +0 -0
- /package/dist/{chunk-4WB3SB7K.js.map → chunk-64VMTY3M.js.map} +0 -0
- /package/dist/{chunk-LRXMR353.js.map → chunk-6HETGJSB.js.map} +0 -0
- /package/dist/{chunk-ODBLHHTP.js.map → chunk-6URMW3DB.js.map} +0 -0
- /package/dist/{chunk-NJ66YYG5.js.map → chunk-7AU5WLAJ.js.map} +0 -0
- /package/dist/{chunk-5I47G22O.js.map → chunk-7J7UYJXC.js.map} +0 -0
- /package/dist/{chunk-YOEB6RVH.js.map → chunk-7QQ5F7T5.js.map} +0 -0
- /package/dist/{chunk-ITCKXMOH.js.map → chunk-7WJGV5DN.js.map} +0 -0
- /package/dist/{chunk-PFMNPQI7.js.map → chunk-AOS7F4QR.js.map} +0 -0
- /package/dist/{chunk-4HXPNLZS.js.map → chunk-DKHBIJO4.js.map} +0 -0
- /package/dist/{chunk-Q55BOZUM.js.map → chunk-DROYVWGE.js.map} +0 -0
- /package/dist/{chunk-YAQ6OYOI.js.map → chunk-F2GERNMF.js.map} +0 -0
- /package/dist/{chunk-FLHLOQ5H.js.map → chunk-FBWOWMEB.js.map} +0 -0
- /package/dist/{chunk-7NW6RNJK.js.map → chunk-FKKVZRSY.js.map} +0 -0
- /package/dist/{chunk-O6GVBBGY.js.map → chunk-FUMZUCP2.js.map} +0 -0
- /package/dist/{chunk-BM2QAXLR.js.map → chunk-GXLI2E4U.js.map} +0 -0
- /package/dist/{chunk-SNNEXDCG.js.map → chunk-II5NJRKH.js.map} +0 -0
- /package/dist/{chunk-JG2W7NC5.js.map → chunk-K2PVLCHR.js.map} +0 -0
- /package/dist/{chunk-H32Z7H3Y.js.map → chunk-MXQG3A5W.js.map} +0 -0
- /package/dist/{chunk-YAZ4CCF6.js.map → chunk-N347WXTT.js.map} +0 -0
- /package/dist/{chunk-MBKTQ5U6.js.map → chunk-NEJF4F6R.js.map} +0 -0
- /package/dist/{chunk-ZIRGSFK3.js.map → chunk-NR62IQDC.js.map} +0 -0
- /package/dist/{chunk-WUC3YSW6.js.map → chunk-OCAMHBJ6.js.map} +0 -0
- /package/dist/{chunk-6OY47Y5W.js.map → chunk-Q5V3KTUL.js.map} +0 -0
- /package/dist/{chunk-JKNVGOQH.js.map → chunk-QCSXKQTK.js.map} +0 -0
- /package/dist/{chunk-GK3NWFSX.js.map → chunk-SNSPYZQT.js.map} +0 -0
- /package/dist/{chunk-THKP4RUM.js.map → chunk-TZWJ7QLW.js.map} +0 -0
- /package/dist/{chunk-AQZSXWPJ.js.map → chunk-VADACTVB.js.map} +0 -0
- /package/dist/{chunk-KUVHSVZT.js.map → chunk-VBC4JBRH.js.map} +0 -0
- /package/dist/{chunk-UVUZMLEJ.js.map → chunk-WXU4Y5T3.js.map} +0 -0
- /package/dist/{chunk-R7Z535GF.js.map → chunk-ZGHJMFQ6.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-55QP7IJF.js.map → cli-circuit-breaker-AAHYLFXZ.js.map} +0 -0
- /package/dist/{composite-router-7TJ2CPZ3.js.map → composite-router-VAVDLJGT.js.map} +0 -0
- /package/dist/{consensus-vote-73JHBSPS.js.map → consensus-vote-YYAWXULO.js.map} +0 -0
- /package/dist/{context-retriever-TODKVXFP.js.map → context-retriever-MYKBBDAN.js.map} +0 -0
- /package/dist/{doctor-deep-EZLG3E2Q.js.map → doctor-deep-AKOPPCXB.js.map} +0 -0
- /package/dist/{doctor-live-EZ54XOSM.js.map → doctor-live-3PVIYQST.js.map} +0 -0
- /package/dist/{expert-bridge-H7OXGW4O.js.map → expert-bridge-G3KN7QWL.js.map} +0 -0
- /package/dist/{factory-B3SHAF4G.js.map → factory-KVMLFEWJ.js.map} +0 -0
- /package/dist/{factory-IOQC3B5Y.js.map → factory-ROTP63IZ.js.map} +0 -0
- /package/dist/{improvement-review-UBAMECJM.js.map → improvement-review-LEITEY7D.js.map} +0 -0
- /package/dist/{init-opencode-G2THTE4E.js.map → init-opencode-C63LASGX.js.map} +0 -0
- /package/dist/{issue-triage-2MSODPKO.js.map → issue-triage-PIE3YVCV.js.map} +0 -0
- /package/dist/{learning-persistence-7N5SZHNX.js.map → learning-persistence-JK2FELZL.js.map} +0 -0
- /package/dist/{pr-reviewer-helpers-TMIOHSRZ.js.map → pr-reviewer-helpers-4VDGMGV5.js.map} +0 -0
- /package/dist/{registry-command-IPCVJL7U.js.map → registry-command-IRDP2L2R.js.map} +0 -0
- /package/dist/{repo-security-plan-KSD46QDB.js.map → repo-security-plan-NS47HQEF.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-I34CSJDD.js.map → research-helpers-synthesize-5NBL637T.js.map} +0 -0
- /package/dist/{routing-memory-4BHIRI57.js.map → routing-memory-2IELT5GT.js.map} +0 -0
- /package/dist/{session-memory-YAES7LJ3.js.map → session-memory-CH3CVLIT.js.map} +0 -0
- /package/dist/{setup-config-SZ2NM2SE.js.map → setup-config-MKZZDUJP.js.map} +0 -0
- /package/dist/{setup-custom-api-JNFW5LFD.js.map → setup-custom-api-2I52S7XU.js.map} +0 -0
- /package/dist/{setup-data-dir-UMVVYGNX.js.map → setup-data-dir-I6LJVAPB.js.map} +0 -0
- /package/dist/{tool-memory-4FCZAUV6.js.map → tool-memory-STS3DWOK.js.map} +0 -0
- /package/dist/{tool-memory-registry-adapters-PCOYMYRF.js.map → tool-memory-registry-adapters-MZ5CSCYW.js.map} +0 -0
- /package/dist/{unified-registry-7GGDIT6Q.js.map → unified-registry-NJS4ZWC3.js.map} +0 -0
- /package/dist/{weather-report-XGPJTPHN.js.map → weather-report-YG4T4Q23.js.map} +0 -0
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
getBuiltInAstRulesPath,
|
|
10
10
|
loadRules,
|
|
11
11
|
runAstQaRules
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-3XQK4MEF.js";
|
|
13
|
+
import "./chunk-ERL3XHQO.js";
|
|
14
|
+
import "./chunk-7WJGV5DN.js";
|
|
15
|
+
import "./chunk-J7QCZRVK.js";
|
|
16
16
|
import "./chunk-ZPWHCABL.js";
|
|
17
17
|
export {
|
|
18
18
|
AST_RULE_LANGUAGES,
|
|
@@ -26,4 +26,4 @@ export {
|
|
|
26
26
|
loadRules,
|
|
27
27
|
runAstQaRules
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=ast-rule-runner-
|
|
29
|
+
//# sourceMappingURL=ast-rule-runner-WANOR3MX.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
nexusMkdtemp
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DKHBIJO4.js";
|
|
4
4
|
import {
|
|
5
5
|
createLogger
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-ERL3XHQO.js";
|
|
7
|
+
import "./chunk-7WJGV5DN.js";
|
|
8
|
+
import "./chunk-J7QCZRVK.js";
|
|
9
9
|
import "./chunk-ZPWHCABL.js";
|
|
10
10
|
|
|
11
11
|
// src/cli-adapters/child-mcp-config.ts
|
|
@@ -62,4 +62,4 @@ export {
|
|
|
62
62
|
generateMcpConfig,
|
|
63
63
|
getDefaultAllowedTools
|
|
64
64
|
};
|
|
65
|
-
//# sourceMappingURL=child-mcp-config-
|
|
65
|
+
//# sourceMappingURL=child-mcp-config-N4HLLCEH.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createAutoAdapter
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7QQ5F7T5.js";
|
|
4
4
|
import {
|
|
5
5
|
getDefaultCliCircuitBreakerRegistry,
|
|
6
6
|
mapModelErrorToCategory
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VADACTVB.js";
|
|
8
8
|
import {
|
|
9
9
|
CLI_NAMES,
|
|
10
10
|
CircularBuffer,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
recordRateLimitEvent,
|
|
25
25
|
resolveModelIdentitySync,
|
|
26
26
|
toRateLimitError
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-ERL3XHQO.js";
|
|
28
28
|
|
|
29
29
|
// src/config/model-equivalence.ts
|
|
30
30
|
function canonicalModelKey(modelId) {
|
|
@@ -904,4 +904,4 @@ export {
|
|
|
904
904
|
getGlobalRegistry,
|
|
905
905
|
resetGlobalRegistry
|
|
906
906
|
};
|
|
907
|
-
//# sourceMappingURL=chunk-
|
|
907
|
+
//# sourceMappingURL=chunk-276GRITW.js.map
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ParseError,
|
|
3
3
|
SecurityError,
|
|
4
|
+
createLogger,
|
|
4
5
|
err,
|
|
5
6
|
getErrorMessage,
|
|
6
7
|
ok,
|
|
7
8
|
parseBoolEnv
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ERL3XHQO.js";
|
|
10
|
+
import {
|
|
11
|
+
findRepoRoot,
|
|
12
|
+
getActiveWorkspaceRoot,
|
|
13
|
+
isRepoRoot
|
|
14
|
+
} from "./chunk-J7QCZRVK.js";
|
|
9
15
|
|
|
10
16
|
// src/cli/research-helpers-io.ts
|
|
11
17
|
import * as fs2 from "node:fs/promises";
|
|
12
|
-
import {
|
|
18
|
+
import { realpathSync, statSync } from "node:fs";
|
|
19
|
+
import { dirname as dirname2, join, resolve as resolve3 } from "node:path";
|
|
13
20
|
|
|
14
21
|
// src/security/safe-path.ts
|
|
15
22
|
import { resolve, sep } from "node:path";
|
|
@@ -84,8 +91,67 @@ async function ensureRegistryFile(rootDir, filename) {
|
|
|
84
91
|
var REGISTRY_PATH = "docs/research/registry";
|
|
85
92
|
var TECHNIQUES_FILE = "techniques.yaml";
|
|
86
93
|
var PAPERS_FILE = "papers.yaml";
|
|
94
|
+
var logger = createLogger({ component: "research-registry-root" });
|
|
95
|
+
var registryRootByOrigin = /* @__PURE__ */ new Map();
|
|
96
|
+
var warnedCwdFallback = false;
|
|
97
|
+
function hasRegistryDir(dir) {
|
|
98
|
+
try {
|
|
99
|
+
return statSync(join(dir, REGISTRY_PATH)).isDirectory();
|
|
100
|
+
} catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function findRegistryAncestor(start) {
|
|
105
|
+
let current;
|
|
106
|
+
let startDev;
|
|
107
|
+
try {
|
|
108
|
+
current = realpathSync(start);
|
|
109
|
+
startDev = statSync(current).dev;
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
for (let depth = 0; depth < 64; depth++) {
|
|
114
|
+
if (hasRegistryDir(current)) return current;
|
|
115
|
+
if (isRepoRoot(current)) return null;
|
|
116
|
+
const parent = dirname2(current);
|
|
117
|
+
if (parent === current) return null;
|
|
118
|
+
try {
|
|
119
|
+
if (statSync(parent).dev !== startDev) return null;
|
|
120
|
+
} catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
current = parent;
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
function resolveRegistryRoot(rootDir) {
|
|
128
|
+
if (rootDir !== void 0) return resolve3(rootDir);
|
|
129
|
+
const origin = getActiveWorkspaceRoot() ?? process.cwd();
|
|
130
|
+
const memoised = registryRootByOrigin.get(origin);
|
|
131
|
+
if (memoised !== void 0) return memoised;
|
|
132
|
+
const discovered = findRegistryAncestor(origin) ?? findRepoRoot(origin);
|
|
133
|
+
if (discovered !== null) {
|
|
134
|
+
registryRootByOrigin.set(origin, discovered);
|
|
135
|
+
return discovered;
|
|
136
|
+
}
|
|
137
|
+
let fallback;
|
|
138
|
+
try {
|
|
139
|
+
fallback = realpathSync(origin);
|
|
140
|
+
} catch {
|
|
141
|
+
fallback = resolve3(origin);
|
|
142
|
+
}
|
|
143
|
+
if (!warnedCwdFallback) {
|
|
144
|
+
warnedCwdFallback = true;
|
|
145
|
+
logger.warn(
|
|
146
|
+
"No research registry or git repo found above the working directory; using cwd as the research registry root",
|
|
147
|
+
{ cwd: fallback, registryPath: REGISTRY_PATH }
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
registryRootByOrigin.set(origin, fallback);
|
|
151
|
+
return fallback;
|
|
152
|
+
}
|
|
87
153
|
function getProjectRoot() {
|
|
88
|
-
return
|
|
154
|
+
return resolveRegistryRoot();
|
|
89
155
|
}
|
|
90
156
|
function validatePath(constructedPath, allowedRoot) {
|
|
91
157
|
const resolved = resolveInsideRoot(constructedPath, allowedRoot);
|
|
@@ -100,7 +166,7 @@ function validatePath(constructedPath, allowedRoot) {
|
|
|
100
166
|
return { ok: true, value: resolved };
|
|
101
167
|
}
|
|
102
168
|
async function loadTechniquesRegistry(rootDir) {
|
|
103
|
-
const root = rootDir
|
|
169
|
+
const root = resolveRegistryRoot(rootDir);
|
|
104
170
|
const filePath = join(root, REGISTRY_PATH, TECHNIQUES_FILE);
|
|
105
171
|
const pathValidation = validatePath(filePath, root);
|
|
106
172
|
if (!pathValidation.ok) {
|
|
@@ -116,7 +182,7 @@ async function loadTechniquesRegistry(rootDir) {
|
|
|
116
182
|
}
|
|
117
183
|
}
|
|
118
184
|
async function loadPapersRegistry(rootDir) {
|
|
119
|
-
const root = rootDir
|
|
185
|
+
const root = resolveRegistryRoot(rootDir);
|
|
120
186
|
const filePath = join(root, REGISTRY_PATH, PAPERS_FILE);
|
|
121
187
|
const pathValidation = validatePath(filePath, root);
|
|
122
188
|
if (!pathValidation.ok) {
|
|
@@ -132,7 +198,7 @@ async function loadPapersRegistry(rootDir) {
|
|
|
132
198
|
}
|
|
133
199
|
}
|
|
134
200
|
async function savePapersRegistry(registry, rootDir) {
|
|
135
|
-
const root = rootDir
|
|
201
|
+
const root = resolveRegistryRoot(rootDir);
|
|
136
202
|
const filePath = join(root, REGISTRY_PATH, PAPERS_FILE);
|
|
137
203
|
const pathValidation = validatePath(filePath, root);
|
|
138
204
|
if (!pathValidation.ok) {
|
|
@@ -151,9 +217,10 @@ async function savePapersRegistry(registry, rootDir) {
|
|
|
151
217
|
export {
|
|
152
218
|
resolveInsideRoot,
|
|
153
219
|
REGISTRY_PATH,
|
|
220
|
+
resolveRegistryRoot,
|
|
154
221
|
getProjectRoot,
|
|
155
222
|
loadTechniquesRegistry,
|
|
156
223
|
loadPapersRegistry,
|
|
157
224
|
savePapersRegistry
|
|
158
225
|
};
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
226
|
+
//# sourceMappingURL=chunk-3CLKYFE3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/research-helpers-io.ts","../src/security/safe-path.ts","../src/cli/research-scaffold.ts"],"sourcesContent":["/**\n * Research Registry I/O Operations\n *\n * File operations for loading and saving research registry YAML files.\n * Includes path traversal protection per Issue #353.\n *\n * @see docs/research/RESEARCH_INDEX.md\n * @see Issue #237 (Epic #225)\n * @see Issue #353 (Security - Path traversal fix)\n * @see Issue #5053 (Registry root resolution — workspace/repo root, not cwd)\n */\n\nimport * as fs from 'node:fs/promises';\nimport { realpathSync, statSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { resolveInsideRoot } from '../security/safe-path.js';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport type { Result } from '../core/index.js';\nimport { SecurityError, createLogger, getErrorMessage } from '../core/index.js';\nimport { getActiveWorkspaceRoot } from '../config/nexus-data-dir.js';\nimport { findRepoRoot, isRepoRoot } from '../config/repo-root-detection.js';\nimport { ParseError } from '../core/types/workflow.js';\nimport type { TechniquesRegistry, PapersRegistry } from './research-types.js';\nimport { ensureRegistryFile } from './research-scaffold.js';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Path to research registry directory relative to project root */\nexport const REGISTRY_PATH = 'docs/research/registry';\n\n/** Filename for techniques registry */\nexport const TECHNIQUES_FILE = 'techniques.yaml';\n\n/** Filename for papers registry */\nexport const PAPERS_FILE = 'papers.yaml';\n\n// =============================================================================\n// PROJECT ROOT\n// =============================================================================\n\nconst logger = createLogger({ component: 'research-registry-root' });\n\n/**\n * Per-process memo of discovered registry roots (#5053), keyed on the origin\n * the walk started from (the active workspace root, else cwd). The MCP server\n * fetches its client's `roots` asynchronously after `initialized`, so a\n * `research_*` call can land before — or a `roots/list_changed` after — the\n * workspace root is known; keying on the origin means a changed origin\n * resolves afresh instead of inheriting the first caller's cwd-derived root.\n */\nconst registryRootByOrigin = new Map<string, string>();\n/** The cwd-fallback warning fires once per process overall, not per origin. */\nlet warnedCwdFallback = false;\n\n// @export-no-consumer-yet — see #5053. Test-only reset hook for the per-origin\n// memo and the one-shot cwd warning, the same shape as the data-dir module's\n// `_reset*ForTests` helpers; no production consumer is intended.\n/** Test helper — clears the registry-root memo and the one-shot warning. */\nexport function _resetRegistryRootForTests(): void {\n registryRootByOrigin.clear();\n warnedCwdFallback = false;\n}\n\n/** True iff `<dir>/docs/research/registry` exists as a directory. */\nfunction hasRegistryDir(dir: string): boolean {\n try {\n return statSync(join(dir, REGISTRY_PATH)).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Walks upward from `start` looking for the nearest ancestor (inclusive) that\n * already contains `docs/research/registry`, searching only within the\n * enclosing git repo: the walk ends at the first directory that `isRepoRoot`\n * (after checking that directory itself), so a nested checkout never adopts —\n * or writes into — an outer repo's registry. Mirrors `findRepoRoot`'s other\n * defenses: bounded depth, stops at the filesystem root, and refuses to cross\n * a mount point so a sandboxed workdir cannot pick up a host-side registry.\n */\nfunction findRegistryAncestor(start: string): string | null {\n let current: string;\n let startDev: number;\n try {\n current = realpathSync(start);\n startDev = statSync(current).dev;\n } catch {\n return null;\n }\n for (let depth = 0; depth < 64; depth++) {\n if (hasRegistryDir(current)) return current;\n if (isRepoRoot(current)) return null;\n const parent = dirname(current);\n if (parent === current) return null;\n try {\n if (statSync(parent).dev !== startDev) return null;\n } catch {\n return null;\n }\n current = parent;\n }\n return null;\n}\n\n/**\n * Resolves the directory that owns `docs/research/registry` (#5053).\n *\n * Resolution order:\n * 1. An explicit `rootDir` argument wins outright (resolved, never memoised).\n * 2. The nearest ancestor of the active workspace root (MCP `roots`, #3991)\n * — or of `process.cwd()` when none is set — that already contains\n * `docs/research/registry`, without crossing a repo boundary: the search\n * stops at the enclosing repo root, so a nested checkout never resolves\n * to an outer repo's registry.\n * 3. Otherwise the enclosing git repo root via `findRepoRoot`, so the\n * first-run scaffold (#2470) lands at the repo root rather than below it.\n * 4. Otherwise cwd, with a warning emitted once per process: nothing above\n * cwd identifies a project, so cwd is a guess rather than a discovery.\n *\n * Steps 2–4 are memoised per origin (workspace root or cwd), so a workspace\n * root that arrives after the first call — MCP roots are fetched after\n * `initialized` — is honoured rather than shadowed by an earlier cwd-derived\n * result. Before this resolver every helper defaulted to cwd, so a server\n * started inside `packages/nexus-agents` read (and scaffolded) a shadow\n * registry there instead of the repo's.\n */\nexport function resolveRegistryRoot(rootDir?: string): string {\n if (rootDir !== undefined) return resolve(rootDir);\n\n const origin = getActiveWorkspaceRoot() ?? process.cwd();\n const memoised = registryRootByOrigin.get(origin);\n if (memoised !== undefined) return memoised;\n\n const discovered = findRegistryAncestor(origin) ?? findRepoRoot(origin);\n if (discovered !== null) {\n registryRootByOrigin.set(origin, discovered);\n return discovered;\n }\n\n let fallback: string;\n try {\n fallback = realpathSync(origin);\n } catch {\n fallback = resolve(origin);\n }\n if (!warnedCwdFallback) {\n warnedCwdFallback = true;\n logger.warn(\n 'No research registry or git repo found above the working directory; using cwd as the research registry root',\n { cwd: fallback, registryPath: REGISTRY_PATH }\n );\n }\n registryRootByOrigin.set(origin, fallback);\n return fallback;\n}\n\n/**\n * Get the project root directory that owns the research registry.\n * Delegates to {@link resolveRegistryRoot} — no longer bare `process.cwd()`.\n */\nexport function getProjectRoot(): string {\n return resolveRegistryRoot();\n}\n\n// =============================================================================\n// PATH VALIDATION\n// =============================================================================\n\n/**\n * Validates that a constructed path stays within the allowed root directory.\n * Prevents path traversal attacks (e.g., ../../../etc/passwd).\n *\n * @param constructedPath - The full path to validate\n * @param allowedRoot - The root directory that paths must be within\n * @returns Result with validated absolute path or SecurityError\n */\nfunction validatePath(constructedPath: string, allowedRoot: string): Result<string, SecurityError> {\n const resolved = resolveInsideRoot(constructedPath, allowedRoot);\n if (resolved === null) {\n return {\n ok: false,\n error: new SecurityError('Path traversal detected: path escapes allowed root directory', {\n context: { constructedPath, allowedRoot: resolve(allowedRoot) },\n }),\n };\n }\n return { ok: true, value: resolved };\n}\n\n// =============================================================================\n// LOAD OPERATIONS\n// =============================================================================\n\n/**\n * Load techniques registry from YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param rootDir - Project root directory (defaults to the resolved registry root, see {@link resolveRegistryRoot})\n * @returns Result with TechniquesRegistry or SecurityError/ParseError\n */\nexport async function loadTechniquesRegistry(\n rootDir?: string\n): Promise<Result<TechniquesRegistry, SecurityError | ParseError>> {\n const root = resolveRegistryRoot(rootDir);\n const filePath = join(root, REGISTRY_PATH, TECHNIQUES_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n // #2470: try to scaffold an empty techniques.yaml on first run so research_*\n // workflows don't error on a fresh install. No-op when file exists.\n // When scaffold refuses (e.g. <rootDir>/docs/ doesn't exist, or\n // NEXUS_NO_SCAFFOLD=1), fall through and let readFile produce the original\n // ENOENT error — that's the existing contract.\n await ensureRegistryFile(root, TECHNIQUES_FILE);\n\n try {\n const content = await fs.readFile(pathValidation.value, 'utf-8');\n return { ok: true, value: parseYaml(content) as TechniquesRegistry };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to load techniques registry: ${message}`) };\n }\n}\n\n/**\n * Load papers registry from YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param rootDir - Project root directory (defaults to the resolved registry root, see {@link resolveRegistryRoot})\n * @returns Result with PapersRegistry or SecurityError/ParseError\n */\nexport async function loadPapersRegistry(\n rootDir?: string\n): Promise<Result<PapersRegistry, SecurityError | ParseError>> {\n const root = resolveRegistryRoot(rootDir);\n const filePath = join(root, REGISTRY_PATH, PAPERS_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n // #2470: try to scaffold an empty papers.yaml on first run so research_*\n // workflows don't error on a fresh install. No-op when file exists; falls\n // through silently when scaffold refuses (no docs/ root, or NEXUS_NO_SCAFFOLD).\n await ensureRegistryFile(root, PAPERS_FILE);\n\n try {\n const content = await fs.readFile(pathValidation.value, 'utf-8');\n return { ok: true, value: parseYaml(content) as PapersRegistry };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to load papers registry: ${message}`) };\n }\n}\n\n// =============================================================================\n// SAVE OPERATIONS\n// =============================================================================\n\n/**\n * Save techniques registry to YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param registry - The techniques registry to save\n * @param rootDir - Project root directory (defaults to the resolved registry root, see {@link resolveRegistryRoot})\n * @returns Result with void on success or SecurityError/ParseError on failure\n */\nexport async function saveTechniquesRegistry(\n registry: TechniquesRegistry,\n rootDir?: string\n): Promise<Result<void, SecurityError | ParseError>> {\n const root = resolveRegistryRoot(rootDir);\n const filePath = join(root, REGISTRY_PATH, TECHNIQUES_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n try {\n const content = stringifyYaml(registry, { lineWidth: 100 });\n await fs.writeFile(pathValidation.value, content, 'utf-8');\n return { ok: true, value: undefined };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to save techniques registry: ${message}`) };\n }\n}\n\n/**\n * Save papers registry to YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param registry - The papers registry to save\n * @param rootDir - Project root directory (defaults to the resolved registry root, see {@link resolveRegistryRoot})\n * @returns Result with void on success or SecurityError/ParseError on failure\n */\nexport async function savePapersRegistry(\n registry: PapersRegistry,\n rootDir?: string\n): Promise<Result<void, SecurityError | ParseError>> {\n const root = resolveRegistryRoot(rootDir);\n const filePath = join(root, REGISTRY_PATH, PAPERS_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n try {\n const content = stringifyYaml(registry, { lineWidth: 100 });\n await fs.writeFile(pathValidation.value, content, 'utf-8');\n return { ok: true, value: undefined };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to save papers registry: ${message}`) };\n }\n}\n","/**\n * Safe Path — Path traversal guards for scanner-controlled inputs (#1813, #1814)\n *\n * When reading files whose path comes from untrusted input (e.g., SARIF\n * scanner output), we must verify the resolved path stays within the\n * workspace root. Without this, a malicious scanner can cause arbitrary\n * file reads whose contents are exfiltrated via downstream LLM prompts\n * (CWE-22).\n *\n * Shared helper to prevent the finding-triage/fix-generator drift that\n * required two separate fixes.\n *\n * @module security/safe-path\n */\n\nimport { resolve, sep } from 'node:path';\n\n/**\n * Resolve a scanner-supplied path against the workspace root, returning null\n * if it escapes. Null means the caller must fall back to a safe alternative\n * (e.g., scanner-provided snippet) rather than reading the file.\n *\n * @param filePath - Scanner-supplied path (may be relative or absolute)\n * @param root - Workspace root (defaults to process.cwd())\n * @returns Resolved absolute path if inside root, null otherwise\n */\nexport function resolveInsideRoot(filePath: string, root: string = process.cwd()): string | null {\n const resolvedRoot = resolve(root);\n const resolved = resolve(resolvedRoot, filePath);\n if (resolved === resolvedRoot) return resolved;\n if (resolved.startsWith(resolvedRoot + sep)) return resolved;\n return null;\n}\n","/**\n * research-scaffold — auto-create empty research registry files when missing.\n *\n * On a fresh install or in a sandboxed environment where the project doesn't\n * have `docs/research/registry/`, the research workflows previously errored\n * with `Failed to load papers registry: ENOENT`. The user has no idea what\n * to do.\n *\n * This module provides `ensureResearchRegistry()`: idempotent scaffolding\n * that creates empty YAML registries on ENOENT, announces what it did to\n * stderr (so the operator knows), and returns the path that's now safe to\n * read.\n *\n * Source: Issue #2470 (epic #2467 child).\n */\n\nimport * as fs from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { stringify as stringifyYaml } from 'yaml';\n\nimport type { Result } from '../core/index.js';\nimport { ok, err, getErrorMessage } from '../core/index.js';\nimport { ParseError } from '../core/types/workflow.js';\n\nimport {\n REGISTRY_PATH,\n PAPERS_FILE,\n TECHNIQUES_FILE,\n resolveRegistryRoot,\n} from './research-helpers-io.js';\nimport { parseBoolEnv } from '../config/defaults-env.js';\n\n/**\n * Names of the registry files this scaffolder knows how to create.\n * `sources.yaml` and `alignments.yaml` live alongside but are populated by\n * different code paths; this scaffolder only owns the two YAML registries\n * that block `research_query` / `research_synthesize` on a fresh install.\n */\ntype ScaffoldedFile = typeof PAPERS_FILE | typeof TECHNIQUES_FILE;\n\nconst SCHEMA_VERSION = '1.0';\n\nconst ANNOUNCED = new Set<string>();\n\nfunction announceOnce(path: string, kind: ScaffoldedFile): void {\n // De-dupe so that running multiple research commands in one session\n // produces one announcement per scaffolded file, not per call.\n if (ANNOUNCED.has(path)) return;\n ANNOUNCED.add(path);\n process.stderr.write(\n `[scaffold] Created empty ${kind} at ${path}; add entries via 'nexus-agents research add' or research_add MCP tool.\\n`\n );\n}\n\n/**\n * Operator opt-out. When set, scaffolding errors loudly with an actionable\n * message instead of silently writing files. Useful for CI and for\n * environments that want strict \"fail when state is wrong\" semantics.\n */\nfunction scaffoldDisabled(): boolean {\n return parseBoolEnv('NEXUS_NO_SCAFFOLD', false);\n}\n\nfunction emptyPapersYaml(): string {\n return stringifyYaml({ schema_version: SCHEMA_VERSION, papers: {} });\n}\n\nfunction emptyTechniquesYaml(): string {\n return stringifyYaml({ schema_version: SCHEMA_VERSION, techniques: {} });\n}\n\n/**\n * Create the registry directory + an empty YAML file if either is missing.\n * Idempotent: existing files are left untouched.\n *\n * Scaffolds only when `<rootDir>/docs/` already exists. That guard keeps\n * tests, vitest's package cwd, and random scratch directories from getting\n * a `docs/research/` subtree implicitly. Operators on a real project root\n * (which always has `docs/`, either from cloning the repo or running\n * `nexus-agents init`) still get the auto-create behavior the issue asks for.\n *\n * Returns the resolved file path on success, or a ParseError when scaffolding\n * is disabled / refused (so the caller can pass the error through unchanged\n * for backwards compat with existing call sites).\n */\nexport async function ensureRegistryFile(\n rootDir: string,\n filename: ScaffoldedFile\n): Promise<Result<string, ParseError>> {\n const filePath = resolve(rootDir, REGISTRY_PATH, filename);\n\n if (existsSync(filePath)) return ok(filePath);\n\n if (scaffoldDisabled()) {\n return err(\n new ParseError(\n `Registry file missing: ${filePath}. Scaffolding disabled (NEXUS_NO_SCAFFOLD=1). Create the file manually or unset the env var.`\n )\n );\n }\n\n // Refuse to create a docs/ subtree in directories that aren't already\n // documented project roots. The presence of `<rootDir>/docs/` is the\n // strong signal we use.\n if (!existsSync(resolve(rootDir, 'docs'))) {\n return err(\n new ParseError(\n `Registry file missing: ${filePath}. ${rootDir}/docs/ does not exist; ` +\n `refusing to create a Nexus subtree in a non-documented root. ` +\n `Run 'nexus-agents init' first, or create ${rootDir}/docs/ manually.`\n )\n );\n }\n\n try {\n await fs.mkdir(dirname(filePath), { recursive: true });\n const content = filename === PAPERS_FILE ? emptyPapersYaml() : emptyTechniquesYaml();\n await fs.writeFile(filePath, content, 'utf-8');\n announceOnce(filePath, filename);\n return ok(filePath);\n } catch (e: unknown) {\n return err(\n new ParseError(\n `Failed to scaffold ${filename} at ${filePath}: ${getErrorMessage(e)}. Set NEXUS_NO_SCAFFOLD=1 and create manually if scaffolding is unwanted.`\n )\n );\n }\n}\n\n/**\n * Convenience: scaffold both papers.yaml and techniques.yaml. Used by the\n * research workflow startup paths that need both registries available.\n * Without an explicit `rootDir` the files land at the resolved registry root\n * (#5053), never at a bare cwd below it.\n */\nexport async function ensureResearchRegistry(rootDir?: string): Promise<Result<void, ParseError>> {\n const root = resolveRegistryRoot(rootDir);\n const papers = await ensureRegistryFile(root, PAPERS_FILE);\n if (!papers.ok) return papers;\n const techniques = await ensureRegistryFile(root, TECHNIQUES_FILE);\n if (!techniques.ok) return techniques;\n return ok(undefined);\n}\n\n/**\n * Test-only reset of the announcement de-dupe set. Production code never\n * needs this; tests do because Vitest reuses process state across files.\n */\nexport function _resetAnnouncedForTests(): void {\n ANNOUNCED.clear();\n}\n"],"mappings":"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","names":["fs","dirname","resolve","stringifyYaml","resolve","resolve","dirname","resolve","stringifyYaml"]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ValidationError,
|
|
4
4
|
createLogger,
|
|
5
5
|
formatZodError
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ERL3XHQO.js";
|
|
7
7
|
|
|
8
8
|
// src/security/ast-rule-runner.ts
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
@@ -241,4 +241,4 @@ export {
|
|
|
241
241
|
collectAstQaFindings,
|
|
242
242
|
runAstQaRules
|
|
243
243
|
};
|
|
244
|
-
//# sourceMappingURL=chunk-
|
|
244
|
+
//# sourceMappingURL=chunk-3XQK4MEF.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getTimeProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ERL3XHQO.js";
|
|
4
4
|
|
|
5
5
|
// src/security/audit-trail.ts
|
|
6
6
|
var MAX_EVENTS = 1e4;
|
|
@@ -205,4 +205,4 @@ export {
|
|
|
205
205
|
createGraphAuditBridge,
|
|
206
206
|
createAuditTrail
|
|
207
207
|
};
|
|
208
|
-
//# sourceMappingURL=chunk-
|
|
208
|
+
//# sourceMappingURL=chunk-3YKFLM2B.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getErrorMessage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ERL3XHQO.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-64VMTY3M.js.map
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
createLogger,
|
|
4
4
|
getDefaultRegistry,
|
|
5
5
|
roundToMicroUsd
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ERL3XHQO.js";
|
|
7
7
|
import {
|
|
8
8
|
getNexusDataDir
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-J7QCZRVK.js";
|
|
10
10
|
|
|
11
11
|
// src/learning/usage-log.ts
|
|
12
12
|
import { z } from "zod";
|
|
@@ -176,4 +176,4 @@ export {
|
|
|
176
176
|
loadUsageEvents,
|
|
177
177
|
rollupByModel
|
|
178
178
|
};
|
|
179
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
//# sourceMappingURL=chunk-6HETGJSB.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-YYJFZ7TO.js";
|
|
6
6
|
import {
|
|
7
7
|
nexusDataPath
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-J7QCZRVK.js";
|
|
9
9
|
|
|
10
10
|
// src/mcp/tools/tool-memory-registry-adapters.ts
|
|
11
11
|
var DEFAULT_SEARCH_LIMIT = 10;
|
|
@@ -93,4 +93,4 @@ export {
|
|
|
93
93
|
StatsOnlyAdapter,
|
|
94
94
|
ensureSharedMemoryRegistry
|
|
95
95
|
};
|
|
96
|
-
//# sourceMappingURL=chunk-
|
|
96
|
+
//# sourceMappingURL=chunk-6URMW3DB.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
createLogger,
|
|
6
6
|
getTimeProvider
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ERL3XHQO.js";
|
|
8
8
|
|
|
9
9
|
// src/mcp/tools/scanner-registry-fetcher.ts
|
|
10
10
|
import { z } from "zod";
|
|
@@ -721,4 +721,4 @@ export {
|
|
|
721
721
|
generateSecurityPlan,
|
|
722
722
|
buildPlanFromAnalysis
|
|
723
723
|
};
|
|
724
|
-
//# sourceMappingURL=chunk-
|
|
724
|
+
//# sourceMappingURL=chunk-7AU5WLAJ.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveCliSlot
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TZWJ7QLW.js";
|
|
4
4
|
import {
|
|
5
5
|
createLogger,
|
|
6
6
|
getTimeProvider,
|
|
7
7
|
isRateLimitText
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ERL3XHQO.js";
|
|
9
9
|
|
|
10
10
|
// src/pipeline/expert-bridge.ts
|
|
11
11
|
function resolveCliFromModelString(model) {
|
|
@@ -21,7 +21,7 @@ async function getMcpConfigPath() {
|
|
|
21
21
|
if (cachedMcpConfigPath !== null) return cachedMcpConfigPath;
|
|
22
22
|
mcpConfigInitPromise ??= (async () => {
|
|
23
23
|
try {
|
|
24
|
-
const { generateMcpConfig } = await import("./child-mcp-config-
|
|
24
|
+
const { generateMcpConfig } = await import("./child-mcp-config-N4HLLCEH.js");
|
|
25
25
|
const config = await generateMcpConfig();
|
|
26
26
|
cachedMcpConfigPath = config.configPath;
|
|
27
27
|
cachedMcpConfigCleanup = config.cleanup;
|
|
@@ -93,8 +93,8 @@ var routerInitPromise = null;
|
|
|
93
93
|
async function getRouter() {
|
|
94
94
|
if (cachedRouter !== null) return cachedRouter;
|
|
95
95
|
routerInitPromise ??= (async () => {
|
|
96
|
-
const { createAllAdapters } = await import("./factory-
|
|
97
|
-
const { createCompositeRouter } = await import("./composite-router-
|
|
96
|
+
const { createAllAdapters } = await import("./factory-ROTP63IZ.js");
|
|
97
|
+
const { createCompositeRouter } = await import("./composite-router-VAVDLJGT.js");
|
|
98
98
|
const adapters = createAllAdapters();
|
|
99
99
|
if (adapters.size === 0) {
|
|
100
100
|
routerInitPromise = null;
|
|
@@ -102,7 +102,7 @@ async function getRouter() {
|
|
|
102
102
|
}
|
|
103
103
|
cachedRouter = adaptCompositeRouter(createCompositeRouter(adapters));
|
|
104
104
|
try {
|
|
105
|
-
const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-
|
|
105
|
+
const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-AAHYLFXZ.js");
|
|
106
106
|
cachedCircuitBreaker = createCliCircuitBreakerIntegration([...adapters.values()]);
|
|
107
107
|
} catch (error) {
|
|
108
108
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -213,4 +213,4 @@ export {
|
|
|
213
213
|
tokenSplitFromUsage,
|
|
214
214
|
executeExpert
|
|
215
215
|
};
|
|
216
|
-
//# sourceMappingURL=chunk-
|
|
216
|
+
//# sourceMappingURL=chunk-7J7UYJXC.js.map
|
|
@@ -5,34 +5,34 @@ import {
|
|
|
5
5
|
planOptionalParams,
|
|
6
6
|
requireApiKey,
|
|
7
7
|
validateApiKeyPresence
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-FKKVZRSY.js";
|
|
9
9
|
import {
|
|
10
10
|
CUSTOM_API_DEFAULT_MODEL
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QCSXKQTK.js";
|
|
12
12
|
import {
|
|
13
13
|
CUSTOM_API_BASE_URL_ENV,
|
|
14
14
|
PROVIDER_ENV_KEYS,
|
|
15
15
|
assertCustomApiHostResolvesPublic,
|
|
16
16
|
validateCustomApiBaseUrl
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-F2GERNMF.js";
|
|
18
18
|
import {
|
|
19
19
|
nexusMkdtempSync
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-DKHBIJO4.js";
|
|
21
21
|
import {
|
|
22
22
|
getAvailabilityCache
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-TZWJ7QLW.js";
|
|
24
24
|
import {
|
|
25
25
|
extractSystemPrompt
|
|
26
26
|
} from "./chunk-QZUG667L.js";
|
|
27
27
|
import {
|
|
28
28
|
generateHyphenId
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-WXU4Y5T3.js";
|
|
30
30
|
import {
|
|
31
31
|
CliCircuitBreaker,
|
|
32
32
|
DEFAULT_CIRCUIT_BREAKER_CONFIG,
|
|
33
33
|
getCliCircuitBreakerSnapshot,
|
|
34
34
|
getDefaultCliCircuitBreakerRegistry
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-VADACTVB.js";
|
|
36
36
|
import {
|
|
37
37
|
CLI_SUBPROCESS_TIMEOUTS,
|
|
38
38
|
CLI_TIMEOUTS,
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
resolveCliAlias,
|
|
73
73
|
resolveRetryAfterMs,
|
|
74
74
|
retryAfterMsFromContext
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-ERL3XHQO.js";
|
|
76
76
|
|
|
77
77
|
// src/cli-adapters/cli-to-model-adapter.ts
|
|
78
78
|
var CliToModelAdapter = class {
|
|
@@ -4946,4 +4946,4 @@ export {
|
|
|
4946
4946
|
SdkAdapter,
|
|
4947
4947
|
createAutoAdapter
|
|
4948
4948
|
};
|
|
4949
|
-
//# sourceMappingURL=chunk-
|
|
4949
|
+
//# sourceMappingURL=chunk-7QQ5F7T5.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getNexusDataDir
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-J7QCZRVK.js";
|
|
4
4
|
|
|
5
5
|
// src/config/learning-persistence.ts
|
|
6
6
|
import { mkdirSync } from "node:fs";
|
|
@@ -45,4 +45,4 @@ export {
|
|
|
45
45
|
isPersistenceEnabled,
|
|
46
46
|
ensureLearningDir
|
|
47
47
|
};
|
|
48
|
-
//# sourceMappingURL=chunk-
|
|
48
|
+
//# sourceMappingURL=chunk-7WJGV5DN.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
TASK_CATEGORIES,
|
|
3
3
|
getAdaptiveBonus,
|
|
4
4
|
getOutcomeStore
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ERL3XHQO.js";
|
|
6
6
|
|
|
7
7
|
// src/cli/doctor-deep.ts
|
|
8
8
|
var CLI_NAMES = ["claude", "gemini", "codex", "opencode"];
|
|
@@ -106,4 +106,4 @@ export {
|
|
|
106
106
|
runDeepDiagnostics,
|
|
107
107
|
formatDeepDiagnostics
|
|
108
108
|
};
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
109
|
+
//# sourceMappingURL=chunk-AOS7F4QR.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
nexusDataPathEnsure
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-J7QCZRVK.js";
|
|
4
4
|
|
|
5
5
|
// src/config/nexus-tmp-dir.ts
|
|
6
6
|
import { mkdirSync, mkdtempSync } from "node:fs";
|
|
@@ -36,4 +36,4 @@ export {
|
|
|
36
36
|
nexusMkdtempSync,
|
|
37
37
|
nexusMkdtemp
|
|
38
38
|
};
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
39
|
+
//# sourceMappingURL=chunk-DKHBIJO4.js.map
|