nexus-agents 8.107.0 → 8.108.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.
Files changed (144) hide show
  1. package/dist/{ast-rule-runner-PXPUTAD7.js → ast-rule-runner-KZMBJQLP.js} +3 -3
  2. package/dist/{child-mcp-config-NMZBXRRH.js → child-mcp-config-IB73HXHT.js} +2 -2
  3. package/dist/{chunk-PO4YA4WF.js → chunk-26G6WKXC.js} +2 -2
  4. package/dist/{chunk-LUHRNBAH.js → chunk-2FHRJR4I.js} +2 -2
  5. package/dist/{chunk-5NVMQ2XV.js → chunk-34KB3PTX.js} +8 -8
  6. package/dist/{chunk-2NDA4DHW.js → chunk-37GZJOQE.js} +31 -6
  7. package/dist/chunk-37GZJOQE.js.map +1 -0
  8. package/dist/{chunk-XIQSMZ2B.js → chunk-3DMMPHEZ.js} +2 -2
  9. package/dist/{chunk-7SM3L43A.js → chunk-4E5KLHUM.js} +3 -3
  10. package/dist/{chunk-AAXQHX6P.js → chunk-5CK27FJM.js} +2 -2
  11. package/dist/{chunk-X2KQAEWB.js → chunk-5CMHNRPS.js} +5 -5
  12. package/dist/{chunk-LB3HC45L.js → chunk-5TSGLULY.js} +3 -2
  13. package/dist/{chunk-LOSHQDR5.js → chunk-6JFXJWB5.js} +7 -18
  14. package/dist/chunk-6JFXJWB5.js.map +1 -0
  15. package/dist/{chunk-5FEDDPEN.js → chunk-A3NV45KD.js} +2 -2
  16. package/dist/{chunk-VLADJJWF.js → chunk-ARFKHTTR.js} +5 -5
  17. package/dist/{chunk-QREAYGVQ.js → chunk-BZOTBURT.js} +2 -2
  18. package/dist/{chunk-A35D54GB.js → chunk-CT6GAHMH.js} +2 -2
  19. package/dist/{chunk-NW2FXWFY.js → chunk-CTBQSJXR.js} +3 -3
  20. package/dist/{chunk-CVPIBK53.js → chunk-DMDDIONG.js} +21 -11
  21. package/dist/chunk-DMDDIONG.js.map +1 -0
  22. package/dist/{chunk-SYFH3NYH.js → chunk-ENJAJCBQ.js} +2 -2
  23. package/dist/{chunk-NNTKWAEQ.js → chunk-EPCENSPC.js} +42 -42
  24. package/dist/{chunk-IWOBVG4G.js → chunk-H27VYMC5.js} +2 -2
  25. package/dist/{chunk-LPPRG6HI.js → chunk-IRIN3UUI.js} +5 -5
  26. package/dist/{chunk-DWJ5WFH4.js → chunk-JKGZNPON.js} +8 -6
  27. package/dist/chunk-JKGZNPON.js.map +1 -0
  28. package/dist/{chunk-XQ7CKD4D.js → chunk-N6KPLEMJ.js} +2 -2
  29. package/dist/{chunk-BREYQTVV.js → chunk-OKGILMKQ.js} +2 -2
  30. package/dist/{chunk-BLNYHCXM.js → chunk-OQ6KK4UB.js} +11 -3
  31. package/dist/chunk-OQ6KK4UB.js.map +1 -0
  32. package/dist/{chunk-MPMIQSAR.js → chunk-Q4VLKRB4.js} +2 -2
  33. package/dist/{chunk-J5LSEI3D.js → chunk-RCUX2KV2.js} +4 -4
  34. package/dist/{chunk-4AVYG4NB.js → chunk-RTH5A2UF.js} +5 -4
  35. package/dist/chunk-RTH5A2UF.js.map +1 -0
  36. package/dist/{chunk-FZPQTC7I.js → chunk-SQ52P2FG.js} +9 -9
  37. package/dist/{chunk-VFXHJK46.js → chunk-SUN4XEIZ.js} +4 -4
  38. package/dist/{chunk-KEEBL2UH.js → chunk-TAAM2NGL.js} +1447 -1345
  39. package/dist/chunk-TAAM2NGL.js.map +1 -0
  40. package/dist/{chunk-IB7KPWNJ.js → chunk-UL6GDIKP.js} +2 -2
  41. package/dist/{chunk-GH34UXS4.js → chunk-UXWPD2F5.js} +2 -2
  42. package/dist/{chunk-REJ6H5DE.js → chunk-VWXFWJGM.js} +12 -12
  43. package/dist/{chunk-EQRVKQX6.js → chunk-W5LDCQ4I.js} +2 -2
  44. package/dist/{chunk-MENV3RNE.js → chunk-YKMMCFAK.js} +2 -2
  45. package/dist/{chunk-ICJYPHKI.js → chunk-ZHGIPNXY.js} +3 -3
  46. package/dist/{cli-circuit-breaker-QDJLE73G.js → cli-circuit-breaker-CLL3LOLL.js} +3 -3
  47. package/dist/cli.js +58 -47
  48. package/dist/cli.js.map +1 -1
  49. package/dist/{composite-router-4L4LEVTV.js → composite-router-FVXOTCQA.js} +2 -2
  50. package/dist/{consensus-vote-V456J4GH.js → consensus-vote-IM3ROFV2.js} +18 -18
  51. package/dist/{context-retriever-MMEQM5OA.js → context-retriever-VWRPBCPI.js} +8 -8
  52. package/dist/{doctor-deep-TZWCCPZ5.js → doctor-deep-DD4WSW75.js} +3 -3
  53. package/dist/doctor-gateway-report-DBDMVYWI.js +17 -0
  54. package/dist/{doctor-live-73HLLSTS.js → doctor-live-U3TPV5JL.js} +11 -11
  55. package/dist/{expert-bridge-DJ22MGQY.js → expert-bridge-UFC2UQSR.js} +5 -5
  56. package/dist/{factory-IBBHPT3G.js → factory-3G5OHH3N.js} +5 -5
  57. package/dist/{factory-Y57G22HJ.js → factory-LRJQQDEM.js} +10 -10
  58. package/dist/{improvement-review-2TQ7VIKW.js → improvement-review-WUVA2ANM.js} +6 -6
  59. package/dist/index.d.ts +9 -2
  60. package/dist/index.js +35 -34
  61. package/dist/index.js.map +1 -1
  62. package/dist/{init-opencode-JL2WP27P.js → init-opencode-7QQTP3GK.js} +6 -6
  63. package/dist/issue-triage-DU4W2KFJ.js +16 -0
  64. package/dist/{openai-compat-adapter-HBYIKTCC.js → openai-compat-adapter-XFWG24FI.js} +6 -6
  65. package/dist/{pr-reviewer-helpers-YHBTIYIT.js → pr-reviewer-helpers-L7DICRKO.js} +4 -4
  66. package/dist/{registry-command-MNHEKHOX.js → registry-command-PM3UKILO.js} +2 -2
  67. package/dist/{repo-security-plan-INKLL5XK.js → repo-security-plan-CDNABEGW.js} +3 -3
  68. package/dist/{research-helpers-synthesize-B537XJBQ.js → research-helpers-synthesize-JGRXBJIR.js} +4 -4
  69. package/dist/{routing-memory-HTGADKCH.js → routing-memory-5JRMFZCT.js} +2 -2
  70. package/dist/{session-memory-S45F2TFW.js → session-memory-TNY2LRPH.js} +3 -3
  71. package/dist/{setup-config-HEMRQGW2.js → setup-config-S75GGD75.js} +3 -3
  72. package/dist/{setup-custom-api-E5CFOQKG.js → setup-custom-api-Y3XWGWXR.js} +4 -4
  73. package/dist/setup-data-dir-RGIMEVWQ.js +34 -0
  74. package/dist/{tool-memory-6Q64UFNL.js → tool-memory-PMO6P5ST.js} +5 -5
  75. package/dist/{unified-registry-IAAU4HVA.js → unified-registry-EV5NRQUT.js} +12 -12
  76. package/dist/{weather-report-JFVK2U6U.js → weather-report-NVCCE3NE.js} +2 -2
  77. package/package.json +1 -1
  78. package/dist/chunk-2NDA4DHW.js.map +0 -1
  79. package/dist/chunk-4AVYG4NB.js.map +0 -1
  80. package/dist/chunk-BLNYHCXM.js.map +0 -1
  81. package/dist/chunk-CVPIBK53.js.map +0 -1
  82. package/dist/chunk-DWJ5WFH4.js.map +0 -1
  83. package/dist/chunk-KEEBL2UH.js.map +0 -1
  84. package/dist/chunk-LOSHQDR5.js.map +0 -1
  85. package/dist/doctor-gateway-report-3BT74JPU.js +0 -17
  86. package/dist/issue-triage-AL5KNJHK.js +0 -16
  87. package/dist/setup-data-dir-AOJT6QBS.js +0 -34
  88. /package/dist/{ast-rule-runner-PXPUTAD7.js.map → ast-rule-runner-KZMBJQLP.js.map} +0 -0
  89. /package/dist/{child-mcp-config-NMZBXRRH.js.map → child-mcp-config-IB73HXHT.js.map} +0 -0
  90. /package/dist/{chunk-PO4YA4WF.js.map → chunk-26G6WKXC.js.map} +0 -0
  91. /package/dist/{chunk-LUHRNBAH.js.map → chunk-2FHRJR4I.js.map} +0 -0
  92. /package/dist/{chunk-5NVMQ2XV.js.map → chunk-34KB3PTX.js.map} +0 -0
  93. /package/dist/{chunk-XIQSMZ2B.js.map → chunk-3DMMPHEZ.js.map} +0 -0
  94. /package/dist/{chunk-7SM3L43A.js.map → chunk-4E5KLHUM.js.map} +0 -0
  95. /package/dist/{chunk-AAXQHX6P.js.map → chunk-5CK27FJM.js.map} +0 -0
  96. /package/dist/{chunk-X2KQAEWB.js.map → chunk-5CMHNRPS.js.map} +0 -0
  97. /package/dist/{chunk-LB3HC45L.js.map → chunk-5TSGLULY.js.map} +0 -0
  98. /package/dist/{chunk-5FEDDPEN.js.map → chunk-A3NV45KD.js.map} +0 -0
  99. /package/dist/{chunk-VLADJJWF.js.map → chunk-ARFKHTTR.js.map} +0 -0
  100. /package/dist/{chunk-QREAYGVQ.js.map → chunk-BZOTBURT.js.map} +0 -0
  101. /package/dist/{chunk-A35D54GB.js.map → chunk-CT6GAHMH.js.map} +0 -0
  102. /package/dist/{chunk-NW2FXWFY.js.map → chunk-CTBQSJXR.js.map} +0 -0
  103. /package/dist/{chunk-SYFH3NYH.js.map → chunk-ENJAJCBQ.js.map} +0 -0
  104. /package/dist/{chunk-NNTKWAEQ.js.map → chunk-EPCENSPC.js.map} +0 -0
  105. /package/dist/{chunk-IWOBVG4G.js.map → chunk-H27VYMC5.js.map} +0 -0
  106. /package/dist/{chunk-LPPRG6HI.js.map → chunk-IRIN3UUI.js.map} +0 -0
  107. /package/dist/{chunk-XQ7CKD4D.js.map → chunk-N6KPLEMJ.js.map} +0 -0
  108. /package/dist/{chunk-BREYQTVV.js.map → chunk-OKGILMKQ.js.map} +0 -0
  109. /package/dist/{chunk-MPMIQSAR.js.map → chunk-Q4VLKRB4.js.map} +0 -0
  110. /package/dist/{chunk-J5LSEI3D.js.map → chunk-RCUX2KV2.js.map} +0 -0
  111. /package/dist/{chunk-FZPQTC7I.js.map → chunk-SQ52P2FG.js.map} +0 -0
  112. /package/dist/{chunk-VFXHJK46.js.map → chunk-SUN4XEIZ.js.map} +0 -0
  113. /package/dist/{chunk-IB7KPWNJ.js.map → chunk-UL6GDIKP.js.map} +0 -0
  114. /package/dist/{chunk-GH34UXS4.js.map → chunk-UXWPD2F5.js.map} +0 -0
  115. /package/dist/{chunk-REJ6H5DE.js.map → chunk-VWXFWJGM.js.map} +0 -0
  116. /package/dist/{chunk-EQRVKQX6.js.map → chunk-W5LDCQ4I.js.map} +0 -0
  117. /package/dist/{chunk-MENV3RNE.js.map → chunk-YKMMCFAK.js.map} +0 -0
  118. /package/dist/{chunk-ICJYPHKI.js.map → chunk-ZHGIPNXY.js.map} +0 -0
  119. /package/dist/{cli-circuit-breaker-QDJLE73G.js.map → cli-circuit-breaker-CLL3LOLL.js.map} +0 -0
  120. /package/dist/{composite-router-4L4LEVTV.js.map → composite-router-FVXOTCQA.js.map} +0 -0
  121. /package/dist/{consensus-vote-V456J4GH.js.map → consensus-vote-IM3ROFV2.js.map} +0 -0
  122. /package/dist/{context-retriever-MMEQM5OA.js.map → context-retriever-VWRPBCPI.js.map} +0 -0
  123. /package/dist/{doctor-deep-TZWCCPZ5.js.map → doctor-deep-DD4WSW75.js.map} +0 -0
  124. /package/dist/{doctor-gateway-report-3BT74JPU.js.map → doctor-gateway-report-DBDMVYWI.js.map} +0 -0
  125. /package/dist/{doctor-live-73HLLSTS.js.map → doctor-live-U3TPV5JL.js.map} +0 -0
  126. /package/dist/{expert-bridge-DJ22MGQY.js.map → expert-bridge-UFC2UQSR.js.map} +0 -0
  127. /package/dist/{factory-IBBHPT3G.js.map → factory-3G5OHH3N.js.map} +0 -0
  128. /package/dist/{factory-Y57G22HJ.js.map → factory-LRJQQDEM.js.map} +0 -0
  129. /package/dist/{improvement-review-2TQ7VIKW.js.map → improvement-review-WUVA2ANM.js.map} +0 -0
  130. /package/dist/{init-opencode-JL2WP27P.js.map → init-opencode-7QQTP3GK.js.map} +0 -0
  131. /package/dist/{issue-triage-AL5KNJHK.js.map → issue-triage-DU4W2KFJ.js.map} +0 -0
  132. /package/dist/{openai-compat-adapter-HBYIKTCC.js.map → openai-compat-adapter-XFWG24FI.js.map} +0 -0
  133. /package/dist/{pr-reviewer-helpers-YHBTIYIT.js.map → pr-reviewer-helpers-L7DICRKO.js.map} +0 -0
  134. /package/dist/{registry-command-MNHEKHOX.js.map → registry-command-PM3UKILO.js.map} +0 -0
  135. /package/dist/{repo-security-plan-INKLL5XK.js.map → repo-security-plan-CDNABEGW.js.map} +0 -0
  136. /package/dist/{research-helpers-synthesize-B537XJBQ.js.map → research-helpers-synthesize-JGRXBJIR.js.map} +0 -0
  137. /package/dist/{routing-memory-HTGADKCH.js.map → routing-memory-5JRMFZCT.js.map} +0 -0
  138. /package/dist/{session-memory-S45F2TFW.js.map → session-memory-TNY2LRPH.js.map} +0 -0
  139. /package/dist/{setup-config-HEMRQGW2.js.map → setup-config-S75GGD75.js.map} +0 -0
  140. /package/dist/{setup-custom-api-E5CFOQKG.js.map → setup-custom-api-Y3XWGWXR.js.map} +0 -0
  141. /package/dist/{setup-data-dir-AOJT6QBS.js.map → setup-data-dir-RGIMEVWQ.js.map} +0 -0
  142. /package/dist/{tool-memory-6Q64UFNL.js.map → tool-memory-PMO6P5ST.js.map} +0 -0
  143. /package/dist/{unified-registry-IAAU4HVA.js.map → unified-registry-EV5NRQUT.js.map} +0 -0
  144. /package/dist/{weather-report-JFVK2U6U.js.map → weather-report-NVCCE3NE.js.map} +0 -0
@@ -9,9 +9,9 @@ import {
9
9
  getBuiltInAstRulesPath,
10
10
  loadRules,
11
11
  runAstQaRules
12
- } from "./chunk-XQ7CKD4D.js";
12
+ } from "./chunk-N6KPLEMJ.js";
13
13
  import "./chunk-XEPZSDN5.js";
14
- import "./chunk-4AVYG4NB.js";
14
+ import "./chunk-RTH5A2UF.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-PXPUTAD7.js.map
30
+ //# sourceMappingURL=ast-rule-runner-KZMBJQLP.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-OITVVSWO.js";
4
4
  import {
5
5
  createLogger
6
- } from "./chunk-4AVYG4NB.js";
6
+ } from "./chunk-RTH5A2UF.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-NMZBXRRH.js.map
59
+ //# sourceMappingURL=child-mcp-config-IB73HXHT.js.map
@@ -13,7 +13,7 @@ import {
13
13
  lookupInTreeCapability,
14
14
  ok,
15
15
  resolveRetryAfterMs
16
- } from "./chunk-4AVYG4NB.js";
16
+ } from "./chunk-RTH5A2UF.js";
17
17
 
18
18
  // src/adapters/base-adapter.ts
19
19
  var AdapterModelError = class extends ModelError {
@@ -1046,4 +1046,4 @@ export {
1046
1046
  gatewayClientOptions,
1047
1047
  gatewayAiSdkOptions
1048
1048
  };
1049
- //# sourceMappingURL=chunk-PO4YA4WF.js.map
1049
+ //# sourceMappingURL=chunk-26G6WKXC.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getRandomProvider,
3
3
  getTimeProvider
4
- } from "./chunk-4AVYG4NB.js";
4
+ } from "./chunk-RTH5A2UF.js";
5
5
 
6
6
  // src/utils/id-utils.ts
7
7
  import { randomUUID } from "node:crypto";
@@ -24,4 +24,4 @@ export {
24
24
  generateHyphenId,
25
25
  generateUUID
26
26
  };
27
- //# sourceMappingURL=chunk-LUHRNBAH.js.map
27
+ //# sourceMappingURL=chunk-2FHRJR4I.js.map
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  ensureGatewayDiscovered,
3
3
  gatewayDiscoveryGeneration
4
- } from "./chunk-SYFH3NYH.js";
4
+ } from "./chunk-ENJAJCBQ.js";
5
5
  import {
6
6
  resolveCliSlot
7
- } from "./chunk-MENV3RNE.js";
7
+ } from "./chunk-YKMMCFAK.js";
8
8
  import {
9
9
  createLogger,
10
10
  getTimeProvider,
11
11
  isRateLimitText
12
- } from "./chunk-4AVYG4NB.js";
12
+ } from "./chunk-RTH5A2UF.js";
13
13
 
14
14
  // src/pipeline/expert-bridge.ts
15
15
  function resolveCliFromModelString(model) {
@@ -34,7 +34,7 @@ async function getMcpConfigPath() {
34
34
  if (cachedMcpConfigPath !== null) return cachedMcpConfigPath;
35
35
  mcpConfigInitPromise ??= (async () => {
36
36
  try {
37
- const { generateMcpConfig } = await import("./child-mcp-config-NMZBXRRH.js");
37
+ const { generateMcpConfig } = await import("./child-mcp-config-IB73HXHT.js");
38
38
  const config = await generateMcpConfig();
39
39
  cachedMcpConfigPath = config.configPath;
40
40
  cachedMcpConfigCleanup = config.cleanup;
@@ -122,8 +122,8 @@ async function getRouter() {
122
122
  }
123
123
  if (cachedRouter !== null) return cachedRouter;
124
124
  routerInitPromise ??= (async () => {
125
- const { createAllAdapters } = await import("./factory-Y57G22HJ.js");
126
- const { createCompositeRouter } = await import("./composite-router-4L4LEVTV.js");
125
+ const { createAllAdapters } = await import("./factory-LRJQQDEM.js");
126
+ const { createCompositeRouter } = await import("./composite-router-FVXOTCQA.js");
127
127
  const adapters = createAllAdapters();
128
128
  const superseded = generation !== routerGeneration;
129
129
  if (adapters.size === 0) {
@@ -134,7 +134,7 @@ async function getRouter() {
134
134
  if (superseded) return router;
135
135
  cachedRouter = router;
136
136
  try {
137
- const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-QDJLE73G.js");
137
+ const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-CLL3LOLL.js");
138
138
  cachedCircuitBreaker = createCliCircuitBreakerIntegration([...adapters.values()]);
139
139
  } catch (error) {
140
140
  const msg = error instanceof Error ? error.message : String(error);
@@ -267,4 +267,4 @@ export {
267
267
  tokenSplitFromUsage,
268
268
  executeExpert
269
269
  };
270
- //# sourceMappingURL=chunk-5NVMQ2XV.js.map
270
+ //# sourceMappingURL=chunk-34KB3PTX.js.map
@@ -17,6 +17,12 @@ var KEY_PATTERNS = [
17
17
  /ghp_[A-Za-z0-9]{20,}/g,
18
18
  // GitHub OAuth: gho_...
19
19
  /gho_[A-Za-z0-9]{20,}/g,
20
+ // GitHub user-to-server: ghu_...
21
+ /ghu_[A-Za-z0-9]{20,}/g,
22
+ // GitHub server-to-server (app installation): ghs_...
23
+ /ghs_[A-Za-z0-9]{20,}/g,
24
+ // GitHub fine-grained PAT: github_pat_...
25
+ /github_pat_[A-Za-z0-9_]{22,}/g,
20
26
  // GitLab PAT: glpat-...
21
27
  /glpat-[A-Za-z0-9_-]{10,}/g,
22
28
  // npm token: npm_...
@@ -24,6 +30,7 @@ var KEY_PATTERNS = [
24
30
  // PyPI token: pypi-...
25
31
  /pypi-[A-Za-z0-9_-]{20,}/g
26
32
  ];
33
+ var URL_USERINFO_PATTERN = /\b([a-z][a-z0-9+.-]{0,31}:\/\/)[^\s/?#@:]{0,256}(?::[^\s/?#@]{0,256})?@/gi;
27
34
  function sanitizeOutput(text, placeholder = REDACTED_KEY_PLACEHOLDER) {
28
35
  if (text === "") return text;
29
36
  let result = text;
@@ -31,7 +38,8 @@ function sanitizeOutput(text, placeholder = REDACTED_KEY_PLACEHOLDER) {
31
38
  pattern.lastIndex = 0;
32
39
  result = result.replace(pattern, placeholder);
33
40
  }
34
- return result;
41
+ URL_USERINFO_PATTERN.lastIndex = 0;
42
+ return result.replace(URL_USERINFO_PATTERN, `$1${placeholder}@`);
35
43
  }
36
44
  function sanitizeErrorDetails(text, apiKey, placeholder = REDACTED_KEY_PLACEHOLDER) {
37
45
  if (text === "") return "";
@@ -40,9 +48,6 @@ function sanitizeErrorDetails(text, apiKey, placeholder = REDACTED_KEY_PLACEHOLD
40
48
  result = result.replaceAll(apiKey.trim(), placeholder);
41
49
  }
42
50
  result = sanitizeOutput(result, placeholder);
43
- result = result.replace(/https?:\/\/[^\s/@]+@[^\s/]+/g, (match) => {
44
- return match.replace(/https?:\/\/[^\s/@]+@/, `https://${placeholder}@`);
45
- });
46
51
  result = result.replace(/(authorization:\s*bearer\s+)\S+/gi, `$1${placeholder}`);
47
52
  result = result.replace(/(authorization:\s*basic\s+)\S+/gi, `$1${placeholder}`);
48
53
  result = result.replace(/(bearer\s+)[A-Za-z0-9._~+/-]+=*/gi, `$1${placeholder}`);
@@ -57,9 +62,29 @@ function sanitizeErrorDetails(text, apiKey, placeholder = REDACTED_KEY_PLACEHOLD
57
62
  );
58
63
  return result;
59
64
  }
65
+ function serializedForm(value) {
66
+ if (typeof value !== "object" || value === null) return value;
67
+ const toJSON = value.toJSON;
68
+ return typeof toJSON === "function" ? toJSON.call(value) : value;
69
+ }
70
+ function sanitizeStringLeaves(input, sanitize) {
71
+ const value = serializedForm(input);
72
+ if (typeof value === "string") return sanitize(value);
73
+ if (Array.isArray(value)) return value.map((item) => sanitizeStringLeaves(item, sanitize));
74
+ if (typeof value === "object" && value !== null) {
75
+ const copy = {};
76
+ for (const [key, entry] of Object.entries(value)) {
77
+ copy[key] = sanitizeStringLeaves(entry, sanitize);
78
+ }
79
+ return copy;
80
+ }
81
+ return value;
82
+ }
60
83
 
61
84
  export {
85
+ REDACTED_KEY_PLACEHOLDER,
62
86
  sanitizeOutput,
63
- sanitizeErrorDetails
87
+ sanitizeErrorDetails,
88
+ sanitizeStringLeaves
64
89
  };
65
- //# sourceMappingURL=chunk-2NDA4DHW.js.map
90
+ //# sourceMappingURL=chunk-37GZJOQE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/security/output-sanitizer.ts"],"sourcesContent":["/**\n * nexus-agents/security - Output Sanitizer\n *\n * Redacts API keys and tokens from CLI subprocess stdout/stderr\n * before the output is returned, logged, or traced.\n *\n * @module security/output-sanitizer\n * (Source: Issue #1597 — subprocess output scrubbing gap)\n */\n\n/** Placeholder text that replaces redacted keys. */\nexport const REDACTED_KEY_PLACEHOLDER = '[REDACTED_KEY]';\n\n/**\n * Patterns matching known API key formats.\n *\n * Order matters: more-specific prefixes (sk-ant-, sk-proj-) come before\n * the generic sk-* pattern so they match first.\n *\n * Each pattern requires a minimum token length after the prefix to avoid\n * false positives on short strings like \"sk-ab\".\n */\nconst KEY_PATTERNS: readonly RegExp[] = [\n // Anthropic: sk-ant-api03-... (at least 20 chars after prefix)\n /sk-ant-[A-Za-z0-9_-]{20,}/g,\n // OpenAI project: sk-proj-... (at least 20 chars after prefix)\n /sk-proj-[A-Za-z0-9_-]{20,}/g,\n // Generic OpenAI: sk-... (at least 20 chars after prefix)\n /sk-[A-Za-z0-9_-]{20,}/g,\n // Public keys: pk-...\n /pk-[A-Za-z0-9_-]{20,}/g,\n // AWS access key ID\n /\\bAKIA[A-Z0-9]{16}\\b/g,\n // Google AI / Gemini: AIzaSy... (at least 30 chars total)\n /AIzaSy[A-Za-z0-9_-]{24,}/g,\n // GitHub PAT: ghp_...\n /ghp_[A-Za-z0-9]{20,}/g,\n // GitHub OAuth: gho_...\n /gho_[A-Za-z0-9]{20,}/g,\n // GitHub user-to-server: ghu_...\n /ghu_[A-Za-z0-9]{20,}/g,\n // GitHub server-to-server (app installation): ghs_...\n /ghs_[A-Za-z0-9]{20,}/g,\n // GitHub fine-grained PAT: github_pat_...\n /github_pat_[A-Za-z0-9_]{22,}/g,\n // GitLab PAT: glpat-...\n /glpat-[A-Za-z0-9_-]{10,}/g,\n // npm token: npm_...\n /npm_[A-Za-z0-9]{20,}/g,\n // PyPI token: pypi-...\n /pypi-[A-Za-z0-9_-]{20,}/g,\n];\n\n/**\n * URL userinfo: `scheme://user:pass@` or `scheme://token@`. Group 1 is the\n * scheme, kept so the redacted URL still names its host. The user part\n * excludes `:` and both parts exclude `/?#@` and whitespace, so a port\n * (`host:8080/…`) or an `@` in a path or query is never taken for\n * credentials. Bounded quantifiers keep the match linear.\n */\nconst URL_USERINFO_PATTERN =\n /\\b([a-z][a-z0-9+.-]{0,31}:\\/\\/)[^\\s/?#@:]{0,256}(?::[^\\s/?#@]{0,256})?@/gi;\n\n/**\n * Redacts known API key patterns from a string.\n *\n * Designed to be called on subprocess stdout/stderr before the output\n * is returned to callers, written to logs, or included in trace data.\n *\n * @param text - Raw subprocess output\n * @param placeholder - Replacement placeholder (default: [REDACTED_KEY])\n * @returns The same text with API keys replaced by placeholder\n */\nexport function sanitizeOutput(\n text: string,\n placeholder: string = REDACTED_KEY_PLACEHOLDER\n): string {\n if (text === '') return text;\n\n let result = text;\n for (const pattern of KEY_PATTERNS) {\n // Reset lastIndex for global regex reuse\n pattern.lastIndex = 0;\n result = result.replace(pattern, placeholder);\n }\n URL_USERINFO_PATTERN.lastIndex = 0;\n return result.replace(URL_USERINFO_PATTERN, `$1${placeholder}@`);\n}\n\n/**\n * Redacts credentials (API keys, authorization headers, Bearer tokens, URL credentials,\n * and sensitive JSON fields) from error messages and response bodies.\n *\n * Designed to be called on upstream API error representations before they are\n * attached to error envelopes, logged, or returned to callers.\n *\n * @param text - Raw error message or serialized error body\n * @param apiKey - Optional configured API key to redact by exact match\n * @returns The sanitized text with credentials redacted\n */\nexport function sanitizeErrorDetails(\n text: string,\n apiKey?: string,\n placeholder: string = REDACTED_KEY_PLACEHOLDER\n): string {\n if (text === '') return '';\n\n let result = text;\n if (apiKey !== undefined && apiKey.trim() !== '') {\n result = result.replaceAll(apiKey.trim(), placeholder);\n }\n\n // Redact known key patterns and URL credentials (user:pass@ / token@)\n result = sanitizeOutput(result, placeholder);\n\n // Redact Authorization headers: Bearer and Basic tokens\n result = result.replace(/(authorization:\\s*bearer\\s+)\\S+/gi, `$1${placeholder}`);\n result = result.replace(/(authorization:\\s*basic\\s+)\\S+/gi, `$1${placeholder}`);\n result = result.replace(/(bearer\\s+)[A-Za-z0-9._~+/-]+=*/gi, `$1${placeholder}`);\n\n // Redact plain text assignments like password=... or secret: ...\n result = result.replace(/(\\b(?:password|passwd|secret)\\s*[=:]\\s*)\\S{4,}/gi, `$1${placeholder}`);\n\n // Redact sensitive query parameters in URLs or logs (?api_key=..., &token=..., &prompt=...)\n result = result.replace(\n /([?&](?:api[_-]?key|token|access[_-]?token|secret|password|prompt|system_prompt|user_prompt)=)[^&\\s]+/gi,\n `$1${placeholder}`\n );\n\n // Redact sensitive JSON keys: \"api_key\": \"...\", \"token\": \"...\", \"prompt\": \"...\", etc.\n result = result.replace(\n /\"(api[_-]?key|access[_-]?token|token|secret|password|prompt|system_prompt|user_prompt)\"\\s*:\\s*\"(?:[^\"\\\\]|\\\\.)*\"/gi,\n `\"$1\": \"${placeholder}\"`\n );\n\n return result;\n}\n\n/** `value.toJSON()` when it has one (a `Date`), as `JSON.stringify` would; else `value`. */\nfunction serializedForm(value: unknown): unknown {\n if (typeof value !== 'object' || value === null) return value;\n const toJSON: unknown = (value as { toJSON?: unknown }).toJSON;\n return typeof toJSON === 'function' ? (toJSON as () => unknown).call(value) : value;\n}\n\n/**\n * `value` with `sanitize` applied to every string LEAF. A `toJSON` object (a\n * `Date`) is taken in its serialized form first, as `JSON.stringify` would;\n * arrays are mapped and objects copied from their own enumerable entries.\n * Keys, numbers, booleans and `null` are untouched, so the structure a JSON\n * reader sees survives. Returns a copy — the input is not mutated.\n */\nexport function sanitizeStringLeaves(input: unknown, sanitize: (text: string) => string): unknown {\n const value = serializedForm(input);\n if (typeof value === 'string') return sanitize(value);\n if (Array.isArray(value)) return value.map((item) => sanitizeStringLeaves(item, sanitize));\n if (typeof value === 'object' && value !== null) {\n const copy: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n copy[key] = sanitizeStringLeaves(entry, sanitize);\n }\n return copy;\n }\n return value;\n}\n"],"mappings":";AAWO,IAAM,2BAA2B;AAWxC,IAAM,eAAkC;AAAA;AAAA,EAEtC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AACF;AASA,IAAM,uBACJ;AAYK,SAAS,eACd,MACA,cAAsB,0BACd;AACR,MAAI,SAAS,GAAI,QAAO;AAExB,MAAI,SAAS;AACb,aAAW,WAAW,cAAc;AAElC,YAAQ,YAAY;AACpB,aAAS,OAAO,QAAQ,SAAS,WAAW;AAAA,EAC9C;AACA,uBAAqB,YAAY;AACjC,SAAO,OAAO,QAAQ,sBAAsB,KAAK,WAAW,GAAG;AACjE;AAaO,SAAS,qBACd,MACA,QACA,cAAsB,0BACd;AACR,MAAI,SAAS,GAAI,QAAO;AAExB,MAAI,SAAS;AACb,MAAI,WAAW,UAAa,OAAO,KAAK,MAAM,IAAI;AAChD,aAAS,OAAO,WAAW,OAAO,KAAK,GAAG,WAAW;AAAA,EACvD;AAGA,WAAS,eAAe,QAAQ,WAAW;AAG3C,WAAS,OAAO,QAAQ,qCAAqC,KAAK,WAAW,EAAE;AAC/E,WAAS,OAAO,QAAQ,oCAAoC,KAAK,WAAW,EAAE;AAC9E,WAAS,OAAO,QAAQ,qCAAqC,KAAK,WAAW,EAAE;AAG/E,WAAS,OAAO,QAAQ,oDAAoD,KAAK,WAAW,EAAE;AAG9F,WAAS,OAAO;AAAA,IACd;AAAA,IACA,KAAK,WAAW;AAAA,EAClB;AAGA,WAAS,OAAO;AAAA,IACd;AAAA,IACA,UAAU,WAAW;AAAA,EACvB;AAEA,SAAO;AACT;AAGA,SAAS,eAAe,OAAyB;AAC/C,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,SAAmB,MAA+B;AACxD,SAAO,OAAO,WAAW,aAAc,OAAyB,KAAK,KAAK,IAAI;AAChF;AASO,SAAS,qBAAqB,OAAgB,UAA6C;AAChG,QAAM,QAAQ,eAAe,KAAK;AAClC,MAAI,OAAO,UAAU,SAAU,QAAO,SAAS,KAAK;AACpD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,CAAC,SAAS,qBAAqB,MAAM,QAAQ,CAAC;AACzF,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAM,OAAgC,CAAC;AACvC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,WAAK,GAAG,IAAI,qBAAqB,OAAO,QAAQ;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  createLogger,
3
3
  err,
4
4
  ok
5
- } from "./chunk-4AVYG4NB.js";
5
+ } from "./chunk-RTH5A2UF.js";
6
6
 
7
7
  // src/scm/token-resolver.ts
8
8
  import { execFile } from "node:child_process";
@@ -87,4 +87,4 @@ export {
87
87
  hasToken,
88
88
  getTokenEnvVars
89
89
  };
90
- //# sourceMappingURL=chunk-XIQSMZ2B.js.map
90
+ //# sourceMappingURL=chunk-3DMMPHEZ.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  loadPapersRegistry
3
- } from "./chunk-5FEDDPEN.js";
3
+ } from "./chunk-A3NV45KD.js";
4
4
  import {
5
5
  getErrorMessage
6
- } from "./chunk-4AVYG4NB.js";
6
+ } from "./chunk-RTH5A2UF.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-7SM3L43A.js.map
879
+ //# sourceMappingURL=chunk-4E5KLHUM.js.map
@@ -2,7 +2,7 @@ import {
2
2
  CACHE_TIMEOUTS,
3
3
  createLogger,
4
4
  getTimeProvider
5
- } from "./chunk-4AVYG4NB.js";
5
+ } from "./chunk-RTH5A2UF.js";
6
6
 
7
7
  // src/security/trust-types.ts
8
8
  import { z } from "zod";
@@ -610,4 +610,4 @@ export {
610
610
  resolveReputationGatingMode,
611
611
  gateWithReputation
612
612
  };
613
- //# sourceMappingURL=chunk-AAXQHX6P.js.map
613
+ //# sourceMappingURL=chunk-5CK27FJM.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  GitHubProvider,
3
3
  ScmError
4
- } from "./chunk-MPMIQSAR.js";
4
+ } from "./chunk-Q4VLKRB4.js";
5
5
  import {
6
6
  ROLE_DEFAULT_TRUST,
7
7
  ReputationCache,
@@ -12,10 +12,10 @@ import {
12
12
  resolveEnvMode,
13
13
  resolveReputationGatingMode,
14
14
  sanitizeInput
15
- } from "./chunk-AAXQHX6P.js";
15
+ } from "./chunk-5CK27FJM.js";
16
16
  import {
17
17
  hasToken
18
- } from "./chunk-XIQSMZ2B.js";
18
+ } from "./chunk-3DMMPHEZ.js";
19
19
  import {
20
20
  CLI_SUBPROCESS_TIMEOUTS,
21
21
  createLogger,
@@ -23,7 +23,7 @@ import {
23
23
  getErrorMessage,
24
24
  getTimeProvider,
25
25
  ok
26
- } from "./chunk-4AVYG4NB.js";
26
+ } from "./chunk-RTH5A2UF.js";
27
27
 
28
28
  // src/security/firewall/firewall-policy-mode.ts
29
29
  import { z } from "zod";
@@ -2650,4 +2650,4 @@ export {
2650
2650
  IssueTriage,
2651
2651
  createIssueTriage
2652
2652
  };
2653
- //# sourceMappingURL=chunk-X2KQAEWB.js.map
2653
+ //# sourceMappingURL=chunk-5CMHNRPS.js.map
@@ -13,7 +13,7 @@ import {
13
13
  observedArmDisplaySlot,
14
14
  ok,
15
15
  parseRetryAfterMs
16
- } from "./chunk-4AVYG4NB.js";
16
+ } from "./chunk-RTH5A2UF.js";
17
17
 
18
18
  // src/cli-adapters/circuit-breaker-types.ts
19
19
  var CircuitErrorCode = {
@@ -682,6 +682,7 @@ export {
682
682
  CliCircuitBreaker,
683
683
  mapModelErrorToCategory,
684
684
  isCallerCancelled,
685
+ isTimeoutAbortReason,
685
686
  raceAbort,
686
687
  RETRYABLE_ERROR_CODES,
687
688
  isTimeoutText,
@@ -694,4 +695,4 @@ export {
694
695
  CliCircuitBreakerIntegration,
695
696
  createCliCircuitBreakerIntegration
696
697
  };
697
- //# sourceMappingURL=chunk-LB3HC45L.js.map
698
+ //# sourceMappingURL=chunk-5TSGLULY.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-A35D54GB.js";
3
+ } from "./chunk-CT6GAHMH.js";
4
4
  import {
5
5
  resolveInsideRoot
6
6
  } from "./chunk-XEPZSDN5.js";
@@ -8,8 +8,9 @@ import {
8
8
  DEFAULT_EXECUTION_MODE
9
9
  } from "./chunk-ECJ52NSK.js";
10
10
  import {
11
- sanitizeErrorDetails
12
- } from "./chunk-2NDA4DHW.js";
11
+ sanitizeErrorDetails,
12
+ sanitizeStringLeaves
13
+ } from "./chunk-37GZJOQE.js";
13
14
  import {
14
15
  CACHE_TIMEOUTS,
15
16
  MCP_TIMEOUTS,
@@ -26,7 +27,7 @@ import {
26
27
  getTimeProvider,
27
28
  ok,
28
29
  resolveToolClassGuardMs
29
- } from "./chunk-4AVYG4NB.js";
30
+ } from "./chunk-RTH5A2UF.js";
30
31
  import {
31
32
  getNexusDataDir,
32
33
  parseBoolValue
@@ -1244,22 +1245,10 @@ function sanitizeOutput(text, logger) {
1244
1245
  }
1245
1246
  return sanitized;
1246
1247
  }
1247
- function sanitizeDeep(value, logger) {
1248
- if (typeof value === "string") {
1249
- return sanitizeOutput(value, logger);
1250
- }
1251
- if (Array.isArray(value)) {
1252
- return value.map((item) => sanitizeDeep(item, logger));
1253
- }
1254
- if (typeof value === "object" && value !== null) {
1255
- return sanitizeDeepRecord(value, logger);
1256
- }
1257
- return value;
1258
- }
1259
1248
  function sanitizeDeepRecord(obj, logger) {
1260
1249
  const result = {};
1261
1250
  for (const [key, val] of Object.entries(obj)) {
1262
- result[key] = sanitizeDeep(val, logger);
1251
+ result[key] = sanitizeStringLeaves(val, (text) => sanitizeOutput(text, logger));
1263
1252
  }
1264
1253
  return result;
1265
1254
  }
@@ -2340,4 +2329,4 @@ export {
2340
2329
  DEFAULT_CONSENSUS_CONFIG,
2341
2330
  ConsensusMetricsSchema
2342
2331
  };
2343
- //# sourceMappingURL=chunk-LOSHQDR5.js.map
2332
+ //# sourceMappingURL=chunk-6JFXJWB5.js.map