nexus-agents 8.45.0 → 8.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/{ast-rule-runner-EBTFBTKZ.js → ast-rule-runner-367HC4UY.js} +5 -5
  2. package/dist/{child-mcp-config-A3YWHFOY.js → child-mcp-config-2IJ3TXG5.js} +5 -5
  3. package/dist/{chunk-5XEPU5ZV.js → chunk-45V73GBS.js} +7 -7
  4. package/dist/{chunk-5OHQT3IJ.js → chunk-5NQPBDRX.js} +2 -2
  5. package/dist/{chunk-RNFQP4HB.js → chunk-63BQ4CVP.js} +2 -2
  6. package/dist/{chunk-4XESQ3X6.js → chunk-7BHQKEC2.js} +2 -2
  7. package/dist/{chunk-336MFOVV.js → chunk-A2CMDQFD.js} +2 -2
  8. package/dist/{chunk-4KEMUKVZ.js → chunk-AEIHBQCV.js} +10 -10
  9. package/dist/{chunk-UIVQ2B7J.js → chunk-AWZKJQHK.js} +3 -13
  10. package/dist/{chunk-UIVQ2B7J.js.map → chunk-AWZKJQHK.js.map} +1 -1
  11. package/dist/{chunk-HNTWLAPQ.js → chunk-BI6AHQKQ.js} +5 -5
  12. package/dist/{chunk-PWLSN7FQ.js → chunk-BLXOJN3P.js} +2 -2
  13. package/dist/{chunk-WD6CZRSW.js → chunk-CB75PV3Y.js} +4 -4
  14. package/dist/{chunk-KO3KUF5M.js → chunk-CI45MILR.js} +3 -3
  15. package/dist/{chunk-F5O7U6W5.js → chunk-DFNBVXOU.js} +2 -2
  16. package/dist/{chunk-UCPM532W.js → chunk-ENJLFHMA.js} +2 -2
  17. package/dist/{chunk-6GAUJAMO.js → chunk-FQHRDJZH.js} +3 -11
  18. package/dist/chunk-FQHRDJZH.js.map +1 -0
  19. package/dist/{chunk-O5TIFR2H.js → chunk-GEUZK7QR.js} +7 -7
  20. package/dist/{chunk-7PPGN5C5.js → chunk-H6JJL3PK.js} +2 -2
  21. package/dist/{chunk-WRGVTEKL.js → chunk-HI7VU3WE.js} +6 -6
  22. package/dist/{chunk-2QZVFXR7.js → chunk-HRJ4TWXZ.js} +3 -3
  23. package/dist/{chunk-YIKC3GNF.js → chunk-LEKS5OZR.js} +2 -2
  24. package/dist/{chunk-JVNJJ2VL.js → chunk-MBAREN43.js} +5 -78
  25. package/dist/chunk-MBAREN43.js.map +1 -0
  26. package/dist/{chunk-QN5ME2N2.js → chunk-NAC62SMO.js} +2 -2
  27. package/dist/{chunk-JH4L3SH4.js → chunk-NX4QAUSU.js} +2 -2
  28. package/dist/{chunk-BBH3SKC3.js → chunk-O335AIP4.js} +6 -6
  29. package/dist/{chunk-ZYJT5CMY.js → chunk-PUKFCRHE.js} +3 -3
  30. package/dist/{chunk-3HELETAQ.js → chunk-S72HKOOH.js} +2 -2
  31. package/dist/{chunk-AOQDLJHG.js → chunk-SECO5QH5.js} +2 -2
  32. package/dist/{chunk-RZF4GUMI.js → chunk-SMYK36R3.js} +6 -6
  33. package/dist/{chunk-ACDZL6ZM.js → chunk-T6KMATAB.js} +10 -10
  34. package/dist/{chunk-5SAXCJAB.js → chunk-T6KTCUCO.js} +4 -4
  35. package/dist/{chunk-NNL4EPHA.js → chunk-TTLQO25X.js} +2 -2
  36. package/dist/{chunk-OZXILWVN.js → chunk-UCIAHROV.js} +5 -5
  37. package/dist/{chunk-GFXWGCWS.js → chunk-URM6RDIR.js} +2 -2
  38. package/dist/{chunk-XJZF7HTC.js → chunk-USD7DWRG.js} +2 -2
  39. package/dist/{chunk-26E2ECC5.js → chunk-VWW2POE3.js} +4 -4
  40. package/dist/{chunk-T5GVEXSA.js → chunk-WLKZ6PNC.js} +2 -2
  41. package/dist/{chunk-6MMF7U4L.js → chunk-WR76BZG6.js} +11 -11
  42. package/dist/{chunk-ISEN3JQL.js → chunk-YEGJ5GWY.js} +41 -65
  43. package/dist/chunk-YEGJ5GWY.js.map +1 -0
  44. package/dist/{chunk-TIUE5KC4.js → chunk-YOCOC4DG.js} +2 -2
  45. package/dist/{cli-circuit-breaker-DNKQCKSD.js → cli-circuit-breaker-ROZJLYNB.js} +5 -5
  46. package/dist/cli.js +47 -47
  47. package/dist/{composite-router-CKTUXIDB.js → composite-router-2TDAOPFD.js} +4 -4
  48. package/dist/{consensus-vote-PPZKMRZ4.js → consensus-vote-OJZZXQHS.js} +21 -21
  49. package/dist/{context-retriever-I4VJWGPK.js → context-retriever-E2Q7RLL5.js} +11 -11
  50. package/dist/doctor-deep-EN2IAJ6Q.js +13 -0
  51. package/dist/{doctor-live-LBTEIOOH.js → doctor-live-KIXE3UGI.js} +12 -12
  52. package/dist/{expert-bridge-6KCCGNC3.js → expert-bridge-ULRWQKFB.js} +6 -6
  53. package/dist/factory-GUD4XQK6.js +25 -0
  54. package/dist/factory-N3RPD7NP.js +15 -0
  55. package/dist/{improvement-review-KABSY3S4.js → improvement-review-6QP66XN2.js} +8 -8
  56. package/dist/index.js +35 -35
  57. package/dist/{init-opencode-2MM576TQ.js → init-opencode-YIRTOTBD.js} +8 -8
  58. package/dist/issue-triage-SUTFBOAF.js +17 -0
  59. package/dist/{learning-persistence-TX2WE7Y7.js → learning-persistence-P4WE4M27.js} +3 -3
  60. package/dist/{pr-reviewer-helpers-G5MW4CBB.js → pr-reviewer-helpers-Q6XF2YBR.js} +6 -6
  61. package/dist/{registry-command-E4FZ56OB.js → registry-command-EZVZ52OP.js} +4 -4
  62. package/dist/{repo-security-plan-3FGTIZY4.js → repo-security-plan-54YQQ7BM.js} +5 -5
  63. package/dist/research-helpers-synthesize-SWBJP7GK.js +14 -0
  64. package/dist/{routing-memory-CRDEOBRO.js → routing-memory-ZES5DGQA.js} +4 -4
  65. package/dist/{session-memory-XPBKOHCX.js → session-memory-ZDI6VNTB.js} +5 -5
  66. package/dist/setup-config-6ZAUJKVT.js +11 -0
  67. package/dist/{setup-custom-api-GWZIDL3X.js → setup-custom-api-5ZIZUPJO.js} +6 -6
  68. package/dist/setup-data-dir-IVU6HU3M.js +29 -0
  69. package/dist/{tool-memory-EUBYXYAI.js → tool-memory-WZKIW5HV.js} +8 -8
  70. package/dist/{tool-memory-registry-adapters-LU44GFKH.js → tool-memory-registry-adapters-GZGXUBEN.js} +3 -3
  71. package/dist/unified-registry-PN2VQQJK.js +26 -0
  72. package/dist/{weather-report-Q4EJXE5F.js → weather-report-BBEUSTYU.js} +4 -4
  73. package/package.json +1 -1
  74. package/dist/chunk-6GAUJAMO.js.map +0 -1
  75. package/dist/chunk-ISEN3JQL.js.map +0 -1
  76. package/dist/chunk-JVNJJ2VL.js.map +0 -1
  77. package/dist/doctor-deep-JOFIWKO5.js +0 -13
  78. package/dist/factory-HJPJTSHY.js +0 -15
  79. package/dist/factory-YIFRH73W.js +0 -25
  80. package/dist/issue-triage-D43CVBDL.js +0 -17
  81. package/dist/research-helpers-synthesize-LRYFH55A.js +0 -14
  82. package/dist/setup-config-7G2UV4FN.js +0 -11
  83. package/dist/setup-data-dir-GR23BXBF.js +0 -29
  84. package/dist/unified-registry-H6DRGQ37.js +0 -26
  85. /package/dist/{ast-rule-runner-EBTFBTKZ.js.map → ast-rule-runner-367HC4UY.js.map} +0 -0
  86. /package/dist/{child-mcp-config-A3YWHFOY.js.map → child-mcp-config-2IJ3TXG5.js.map} +0 -0
  87. /package/dist/{chunk-5XEPU5ZV.js.map → chunk-45V73GBS.js.map} +0 -0
  88. /package/dist/{chunk-5OHQT3IJ.js.map → chunk-5NQPBDRX.js.map} +0 -0
  89. /package/dist/{chunk-RNFQP4HB.js.map → chunk-63BQ4CVP.js.map} +0 -0
  90. /package/dist/{chunk-4XESQ3X6.js.map → chunk-7BHQKEC2.js.map} +0 -0
  91. /package/dist/{chunk-336MFOVV.js.map → chunk-A2CMDQFD.js.map} +0 -0
  92. /package/dist/{chunk-4KEMUKVZ.js.map → chunk-AEIHBQCV.js.map} +0 -0
  93. /package/dist/{chunk-HNTWLAPQ.js.map → chunk-BI6AHQKQ.js.map} +0 -0
  94. /package/dist/{chunk-PWLSN7FQ.js.map → chunk-BLXOJN3P.js.map} +0 -0
  95. /package/dist/{chunk-WD6CZRSW.js.map → chunk-CB75PV3Y.js.map} +0 -0
  96. /package/dist/{chunk-KO3KUF5M.js.map → chunk-CI45MILR.js.map} +0 -0
  97. /package/dist/{chunk-F5O7U6W5.js.map → chunk-DFNBVXOU.js.map} +0 -0
  98. /package/dist/{chunk-UCPM532W.js.map → chunk-ENJLFHMA.js.map} +0 -0
  99. /package/dist/{chunk-O5TIFR2H.js.map → chunk-GEUZK7QR.js.map} +0 -0
  100. /package/dist/{chunk-7PPGN5C5.js.map → chunk-H6JJL3PK.js.map} +0 -0
  101. /package/dist/{chunk-WRGVTEKL.js.map → chunk-HI7VU3WE.js.map} +0 -0
  102. /package/dist/{chunk-2QZVFXR7.js.map → chunk-HRJ4TWXZ.js.map} +0 -0
  103. /package/dist/{chunk-YIKC3GNF.js.map → chunk-LEKS5OZR.js.map} +0 -0
  104. /package/dist/{chunk-QN5ME2N2.js.map → chunk-NAC62SMO.js.map} +0 -0
  105. /package/dist/{chunk-JH4L3SH4.js.map → chunk-NX4QAUSU.js.map} +0 -0
  106. /package/dist/{chunk-BBH3SKC3.js.map → chunk-O335AIP4.js.map} +0 -0
  107. /package/dist/{chunk-ZYJT5CMY.js.map → chunk-PUKFCRHE.js.map} +0 -0
  108. /package/dist/{chunk-3HELETAQ.js.map → chunk-S72HKOOH.js.map} +0 -0
  109. /package/dist/{chunk-AOQDLJHG.js.map → chunk-SECO5QH5.js.map} +0 -0
  110. /package/dist/{chunk-RZF4GUMI.js.map → chunk-SMYK36R3.js.map} +0 -0
  111. /package/dist/{chunk-ACDZL6ZM.js.map → chunk-T6KMATAB.js.map} +0 -0
  112. /package/dist/{chunk-5SAXCJAB.js.map → chunk-T6KTCUCO.js.map} +0 -0
  113. /package/dist/{chunk-NNL4EPHA.js.map → chunk-TTLQO25X.js.map} +0 -0
  114. /package/dist/{chunk-OZXILWVN.js.map → chunk-UCIAHROV.js.map} +0 -0
  115. /package/dist/{chunk-GFXWGCWS.js.map → chunk-URM6RDIR.js.map} +0 -0
  116. /package/dist/{chunk-XJZF7HTC.js.map → chunk-USD7DWRG.js.map} +0 -0
  117. /package/dist/{chunk-26E2ECC5.js.map → chunk-VWW2POE3.js.map} +0 -0
  118. /package/dist/{chunk-T5GVEXSA.js.map → chunk-WLKZ6PNC.js.map} +0 -0
  119. /package/dist/{chunk-6MMF7U4L.js.map → chunk-WR76BZG6.js.map} +0 -0
  120. /package/dist/{chunk-TIUE5KC4.js.map → chunk-YOCOC4DG.js.map} +0 -0
  121. /package/dist/{cli-circuit-breaker-DNKQCKSD.js.map → cli-circuit-breaker-ROZJLYNB.js.map} +0 -0
  122. /package/dist/{composite-router-CKTUXIDB.js.map → composite-router-2TDAOPFD.js.map} +0 -0
  123. /package/dist/{consensus-vote-PPZKMRZ4.js.map → consensus-vote-OJZZXQHS.js.map} +0 -0
  124. /package/dist/{context-retriever-I4VJWGPK.js.map → context-retriever-E2Q7RLL5.js.map} +0 -0
  125. /package/dist/{doctor-deep-JOFIWKO5.js.map → doctor-deep-EN2IAJ6Q.js.map} +0 -0
  126. /package/dist/{doctor-live-LBTEIOOH.js.map → doctor-live-KIXE3UGI.js.map} +0 -0
  127. /package/dist/{expert-bridge-6KCCGNC3.js.map → expert-bridge-ULRWQKFB.js.map} +0 -0
  128. /package/dist/{factory-HJPJTSHY.js.map → factory-GUD4XQK6.js.map} +0 -0
  129. /package/dist/{factory-YIFRH73W.js.map → factory-N3RPD7NP.js.map} +0 -0
  130. /package/dist/{improvement-review-KABSY3S4.js.map → improvement-review-6QP66XN2.js.map} +0 -0
  131. /package/dist/{init-opencode-2MM576TQ.js.map → init-opencode-YIRTOTBD.js.map} +0 -0
  132. /package/dist/{issue-triage-D43CVBDL.js.map → issue-triage-SUTFBOAF.js.map} +0 -0
  133. /package/dist/{learning-persistence-TX2WE7Y7.js.map → learning-persistence-P4WE4M27.js.map} +0 -0
  134. /package/dist/{pr-reviewer-helpers-G5MW4CBB.js.map → pr-reviewer-helpers-Q6XF2YBR.js.map} +0 -0
  135. /package/dist/{registry-command-E4FZ56OB.js.map → registry-command-EZVZ52OP.js.map} +0 -0
  136. /package/dist/{repo-security-plan-3FGTIZY4.js.map → repo-security-plan-54YQQ7BM.js.map} +0 -0
  137. /package/dist/{research-helpers-synthesize-LRYFH55A.js.map → research-helpers-synthesize-SWBJP7GK.js.map} +0 -0
  138. /package/dist/{routing-memory-CRDEOBRO.js.map → routing-memory-ZES5DGQA.js.map} +0 -0
  139. /package/dist/{session-memory-XPBKOHCX.js.map → session-memory-ZDI6VNTB.js.map} +0 -0
  140. /package/dist/{setup-config-7G2UV4FN.js.map → setup-config-6ZAUJKVT.js.map} +0 -0
  141. /package/dist/{setup-custom-api-GWZIDL3X.js.map → setup-custom-api-5ZIZUPJO.js.map} +0 -0
  142. /package/dist/{setup-data-dir-GR23BXBF.js.map → setup-data-dir-IVU6HU3M.js.map} +0 -0
  143. /package/dist/{tool-memory-EUBYXYAI.js.map → tool-memory-WZKIW5HV.js.map} +0 -0
  144. /package/dist/{tool-memory-registry-adapters-LU44GFKH.js.map → tool-memory-registry-adapters-GZGXUBEN.js.map} +0 -0
  145. /package/dist/{unified-registry-H6DRGQ37.js.map → unified-registry-PN2VQQJK.js.map} +0 -0
  146. /package/dist/{weather-report-Q4EJXE5F.js.map → weather-report-BBEUSTYU.js.map} +0 -0
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  GitHubProvider,
3
3
  ScmError
4
- } from "./chunk-5OHQT3IJ.js";
4
+ } from "./chunk-5NQPBDRX.js";
5
5
  import {
6
6
  resolveToken
7
- } from "./chunk-JH4L3SH4.js";
7
+ } from "./chunk-NX4QAUSU.js";
8
8
  import {
9
9
  err,
10
10
  ok
11
- } from "./chunk-RZF4GUMI.js";
11
+ } from "./chunk-SMYK36R3.js";
12
12
 
13
13
  // src/scm/factory.ts
14
14
  async function createScmProvider(config) {
@@ -41,4 +41,4 @@ export {
41
41
  createScmProvider,
42
42
  createGitHubProvider
43
43
  };
44
- //# sourceMappingURL=chunk-WD6CZRSW.js.map
44
+ //# sourceMappingURL=chunk-CB75PV3Y.js.map
@@ -5,13 +5,13 @@ import {
5
5
  err,
6
6
  getErrorMessage,
7
7
  ok
8
- } from "./chunk-RZF4GUMI.js";
8
+ } from "./chunk-SMYK36R3.js";
9
9
  import {
10
10
  findRepoRoot,
11
11
  getActiveWorkspaceRoot,
12
12
  isRepoRoot,
13
13
  parseBoolEnv
14
- } from "./chunk-JVNJJ2VL.js";
14
+ } from "./chunk-MBAREN43.js";
15
15
 
16
16
  // src/cli/research-helpers-io.ts
17
17
  import * as fs2 from "node:fs/promises";
@@ -223,4 +223,4 @@ export {
223
223
  loadPapersRegistry,
224
224
  savePapersRegistry
225
225
  };
226
- //# sourceMappingURL=chunk-KO3KUF5M.js.map
226
+ //# sourceMappingURL=chunk-CI45MILR.js.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  createLogger,
6
6
  getTimeProvider
7
- } from "./chunk-RZF4GUMI.js";
7
+ } from "./chunk-SMYK36R3.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-F5O7U6W5.js.map
724
+ //# sourceMappingURL=chunk-DFNBVXOU.js.map
@@ -1,6 +1,6 @@
1
1
  // src/version.ts
2
2
  import semver from "semver";
3
- var VERSION = true ? "8.45.0" : "dev";
3
+ var VERSION = true ? "8.46.0" : "dev";
4
4
  var NODE_ENGINE_RANGE = ">=22.5.0";
5
5
  function isNodeVersionSupported(version) {
6
6
  return semver.satisfies(version, NODE_ENGINE_RANGE);
@@ -11,4 +11,4 @@ export {
11
11
  NODE_ENGINE_RANGE,
12
12
  isNodeVersionSupported
13
13
  };
14
- //# sourceMappingURL=chunk-UCPM532W.js.map
14
+ //# sourceMappingURL=chunk-ENJLFHMA.js.map
@@ -5,15 +5,12 @@ import {
5
5
  MCP_TIMEOUTS,
6
6
  TEST_TIMEOUTS,
7
7
  WORKFLOW_TIMEOUTS
8
- } from "./chunk-RZF4GUMI.js";
8
+ } from "./chunk-SMYK36R3.js";
9
9
  import {
10
- createGetCircuitBreakerConfig,
11
10
  createGetEnvVarDocumentation,
12
- createGetRateLimitConfig,
13
- createGetRetryConfig,
14
11
  createGetTimeout,
15
12
  createGetToolRateLimit
16
- } from "./chunk-JVNJJ2VL.js";
13
+ } from "./chunk-MBAREN43.js";
17
14
 
18
15
  // src/config/defaults.ts
19
16
  var CUSTOM_API_DEFAULT_MODEL = "gpt-5.5";
@@ -220,11 +217,6 @@ var DEFAULTS = {
220
217
  }
221
218
  };
222
219
  var getTimeout = createGetTimeout(DEFAULTS.TIMEOUT_DEFAULTS);
223
- var getRetryConfig = createGetRetryConfig(DEFAULTS.RETRY_DEFAULTS);
224
- var getRateLimitConfig = createGetRateLimitConfig(DEFAULTS.RATE_LIMIT_DEFAULTS);
225
- var getCircuitBreakerConfig = createGetCircuitBreakerConfig(
226
- DEFAULTS.CIRCUIT_BREAKER_DEFAULTS
227
- );
228
220
  var getToolRateLimit = createGetToolRateLimit(DEFAULTS.TOOL_RATE_LIMITS);
229
221
  var getEnvVarDocumentation = createGetEnvVarDocumentation(DEFAULTS);
230
222
 
@@ -232,4 +224,4 @@ export {
232
224
  CUSTOM_API_DEFAULT_MODEL,
233
225
  DEFAULTS
234
226
  };
235
- //# sourceMappingURL=chunk-6GAUJAMO.js.map
227
+ //# sourceMappingURL=chunk-FQHRDJZH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/defaults.ts"],"sourcesContent":["/**\n * Central Configuration Defaults\n *\n * Consolidates common default values used across the codebase.\n * This prevents scattered magic numbers and ensures consistency.\n *\n * Usage:\n * import { DEFAULTS, getTimeout, TIMEOUT_PROFILES } from '../config/defaults.js';\n * const timeout = options.timeout ?? DEFAULTS.TIMEOUT_DEFAULTS.cliMs;\n * const cliTimeout = getTimeoutForCli('claude', 'complex');\n *\n * Environment overrides can be added via NEXUS_* environment variables.\n *\n * @module config/defaults\n * (Source: Central config consolidation initiative)\n */\n\n// Re-export types from defaults-types\nexport type {\n TaskComplexity,\n TimeoutProfile,\n KnownCliName,\n TimeoutDefaults,\n RateLimitDefaults,\n ToolRateLimitConfig,\n RetryDefaults,\n CircuitBreakerDefaults,\n} from './defaults-types.js';\n\nexport { isTaskComplexity, isKnownCliName } from './defaults-types.js';\n\n// Re-export timeout profiles (delegates to config/timeouts.ts)\nexport {\n TIMEOUT_PROFILES,\n getTimeoutProfile,\n getTimeoutForCli,\n} from './defaults-timeout-profiles.js';\n\n// Re-export canonical timeout modules (Issue #984)\nexport {\n CLI_TIMEOUTS,\n VOTE_TIMEOUTS,\n MCP_TIMEOUTS,\n WORKFLOW_TIMEOUTS,\n GRAPH_TIMEOUTS,\n PER_CLI_TASK_TIMEOUTS,\n API_TIMEOUTS,\n INTERNAL_TIMEOUTS,\n TEST_TIMEOUTS,\n TIMEOUT_ENV_VARS,\n getCliTimeoutProfile,\n getCliTimeout,\n resolveVoteTimeout,\n resolveEnvTimeout,\n validateTimeout,\n BACKOFF_CONFIG,\n AGENT_ROUTER_TIMEOUTS,\n CODEX_MCP_TIMEOUTS,\n} from './timeouts.js';\n\n// Re-export env helpers (internal use)\nexport { parseIntEnv, parseFloatEnv, parseBoolEnv } from './defaults-env.js';\n\nimport {\n createGetTimeout,\n createGetToolRateLimit,\n createGetEnvVarDocumentation,\n} from './defaults-env.js';\nimport {\n API_TIMEOUTS as _API,\n WORKFLOW_TIMEOUTS as _WF,\n MCP_TIMEOUTS as _MCP,\n INTERNAL_TIMEOUTS as _INT,\n TEST_TIMEOUTS as _TEST,\n CLI_TIMEOUTS as _CLI,\n} from './timeouts.js';\n\n// ============================================================================\n// Default Model IDs (#2200 Child 4)\n// ============================================================================\n\n/**\n * Default model identifier for the custom OpenAI-compatible API gateway.\n *\n * Used by both `cli/setup-custom-api.ts` (write to nexus-agents.yaml) and\n * `adapters/auto-adapter.ts` (NEXUS_CUSTOM_MODEL env-var fallback). Single\n * source of truth so changes flow through all consumers.\n *\n * `gpt-4o` was the previous value, chosen because it was widely supported across\n * OpenAI-compatible gateways. It is now END-OF-LIFE at OpenAI, so defaulting to\n * it points new operators at a model their gateway may well refuse (#4408).\n *\n * A custom gateway can serve anything, so ANY default here is a guess — the\n * right long-term answer is to discover the model list from the endpoint\n * (`GET /v1/models`, which this repo already implements) rather than assume one.\n * Until that is wired, guess a current model instead of a retired one.\n *\n * Operators are expected to override via `NEXUS_CUSTOM_MODEL`.\n */\nexport const CUSTOM_API_DEFAULT_MODEL = 'gpt-5.5';\n\n// ============================================================================\n// Central Defaults Object\n// ============================================================================\n\n/**\n * Central defaults object containing all configuration categories.\n */\nexport const DEFAULTS = {\n /**\n * Default timeout settings in milliseconds.\n * Values sourced from config/timeouts.ts (Issue #984).\n */\n TIMEOUT_DEFAULTS: {\n /** CLI tool execution timeout in milliseconds. */\n cliMs: _CLI.default.standard,\n // cliSimpleMs / cliComplexMs removed in #4180 — never read by any production\n // code (the matching NEXUS_TIMEOUT_CLISIMPLE/CLICOMPLEX env vars were silent\n // no-ops, #2977 class). Per-complexity CLI timeouts come from\n // getTimeoutForCli/TIMEOUT_PROFILES (CLI_TIMEOUTS in config/timeouts.ts).\n /** API request timeout in milliseconds. */\n apiMs: _API.defaultMs,\n /** Maximum API timeout in milliseconds. */\n apiMaxMs: _API.maxMs,\n /** Workflow-level timeout in milliseconds (5 minutes). */\n workflowMs: _WF.workflowMs,\n /** Maximum workflow timeout in milliseconds (30 minutes). */\n workflowMaxMs: _WF.workflowMaxMs,\n /** Step-level timeout in milliseconds. */\n stepMs: _INT.selfEvalMs,\n /** MCP operation default timeout in milliseconds (generic, not per-tool). */\n mcpMs: _API.defaultMs,\n /** MCP operation maximum timeout in milliseconds. */\n mcpMaxMs: _MCP.maxMs,\n /** Health check timeout in milliseconds. */\n healthCheckMs: _INT.healthCheckMs,\n /** Global test run timeout in milliseconds (10 minutes). */\n testGlobalMs: _TEST.globalMs,\n /** Per-task test timeout in milliseconds. */\n testTaskMs: _TEST.taskMs,\n /** Circuit breaker reset timeout in milliseconds. */\n circuitBreakerResetMs: _INT.circuitBreakerResetMs,\n },\n\n /**\n * Default rate limit settings for outbound operations.\n */\n RATE_LIMIT_DEFAULTS: {\n /** Global requests per minute. */\n requestsPerMinute: 60,\n /** Whether rate limiting is enabled by default. */\n enabled: true,\n /** Maximum number of concurrent requests. */\n maxConcurrent: 4,\n /** Token bucket capacity. */\n capacity: 100,\n /** Token bucket refill rate per second. */\n refillRate: 10,\n /** Refill interval in milliseconds. */\n refillIntervalMs: 100,\n },\n\n /**\n * Per-tool rate limit defaults for MCP tools.\n * (Source: Issue #274 Phase 2 - per-tool rate limits)\n */\n TOOL_RATE_LIMITS: {\n orchestrate: { capacity: 10, refillRate: 10, refillIntervalMs: 60_000 },\n delegate: { capacity: 20, refillRate: 20, refillIntervalMs: 60_000 },\n workflow: { capacity: 5, refillRate: 5, refillIntervalMs: 60_000 },\n expert: { capacity: 30, refillRate: 30, refillIntervalMs: 60_000 },\n },\n\n /**\n * Default retry strategy settings for transient failures.\n */\n RETRY_DEFAULTS: {\n /** Maximum retry attempts before failing. */\n maxRetries: 3,\n /** Base delay between retries in milliseconds. */\n baseDelayMs: 1_000,\n /** Maximum delay between retries in milliseconds. */\n maxDelayMs: 30_000,\n /** Jitter factor (0-1) to randomize retry delays. */\n jitterFactor: 0.1,\n },\n\n /**\n * Workflow-specific retry defaults.\n */\n WORKFLOW_RETRY_DEFAULTS: {\n /** Maximum retry attempts for workflow steps. */\n maxRetries: 2,\n /** Base delay for workflow retries in milliseconds. */\n baseDelayMs: 2_000,\n /** Maximum delay for workflow retries in milliseconds. */\n maxDelayMs: 60_000,\n /** Jitter factor for workflow retries. */\n jitterFactor: 0.15,\n },\n\n /**\n * CLI-specific retry defaults.\n */\n CLI_RETRY_DEFAULTS: {\n /** Maximum retry attempts for CLI operations. */\n maxRetries: 2,\n /** Base delay for CLI retries in milliseconds. */\n baseDelayMs: 5_000,\n /** Maximum delay for CLI retries in milliseconds. */\n maxDelayMs: 60_000,\n /** Jitter factor for CLI retries. */\n jitterFactor: 0.2,\n },\n\n /**\n * Test framework retry defaults.\n */\n TEST_RETRY_DEFAULTS: {\n /** Maximum retries per test task. */\n maxRetries: 2,\n /** Whether to retry failed tasks by default. */\n retryFailedTasks: true,\n },\n\n /**\n * Default buffer sizing for batching and chunked processing.\n */\n BUFFER_DEFAULTS: {\n /** Preferred batch size for bulk operations. */\n batchSize: 100,\n /** Chunk size for streaming or segmented processing. */\n chunkSize: 256,\n /** Maximum items allowed in a buffer. */\n maxItems: 1_000,\n /** Maximum memory size in bytes (10 MB). */\n maxMemoryBytes: 10 * 1024 * 1024,\n /** Log buffer flush interval in milliseconds. */\n logFlushIntervalMs: 5_000,\n },\n\n // WORKER_DEFAULTS removed in #2977 — the eight settings under this category\n // (maxWorkers, poolSize, idleTimeoutMs, workflowMaxParallel, testParallelism,\n // evaluationMaxWorkers, eventBusMaxHistory, swarmObserverMaxEvents) had zero\n // production consumers. `getWorkerConfig()` was never called from anywhere\n // in src/, and the matching NEXUS_WORKERS_* env vars were silent no-ops.\n // Silent config rot is worse than missing knobs; re-add when a concrete\n // consumer exists.\n\n /**\n * Default circuit breaker settings.\n * (Source: Issue #81 - Circuit breaker for CLI failures)\n */\n CIRCUIT_BREAKER_DEFAULTS: {\n /** Failure threshold to open circuit. */\n failureThreshold: 5,\n /** Reset timeout in milliseconds. */\n resetTimeoutMs: 30_000,\n /** Success threshold to close circuit in half-open state. */\n halfOpenSuccessThreshold: 2,\n /** Whether to count timeouts as failures. */\n countTimeoutsAsFailures: true,\n /** Whether to count auth failures as failures. */\n countAuthFailuresAsFailures: false,\n /** Whether to count rate limit errors as failures (#1529). */\n countRateLimitsAsFailures: true,\n /** Maximum requests allowed in half-open state. */\n halfOpenMaxRequests: 3,\n },\n\n /**\n * Default context/memory settings.\n */\n CONTEXT_DEFAULTS: {\n /** Maximum context tokens. */\n maxTokens: 100_000,\n /** Token budget warning threshold (80%). */\n warningThreshold: 0.8,\n /** Token budget critical threshold (95%). */\n criticalThreshold: 0.95,\n /** Maximum history entries to retain. */\n maxHistoryEntries: 1_000,\n },\n\n /**\n * Default provider/model settings.\n */\n PROVIDER_DEFAULTS: {\n /** Default timeout for provider API calls in ms. */\n timeout: 30_000,\n /** Maximum retries for provider requests. */\n maxRetries: 3,\n /** Default model tier. */\n defaultTier: 'balanced' as const,\n /** Default temperature. */\n temperatureDefault: 0.3,\n /** Minimum temperature. */\n temperatureMin: 0,\n /** Maximum temperature. */\n temperatureMax: 1,\n /** Billing mode: 'plan' (monthly subscription) or 'api' (pay-per-token). Env: NEXUS_BILLING_MODE */\n billingMode: 'plan' as const,\n },\n\n /**\n * Security-related defaults.\n */\n SECURITY_DEFAULTS: {\n /** Maximum system prompt length in characters. */\n maxSystemPromptLength: 4_000,\n /** Default policy execution mode. */\n policyDefaultMode: 'read-only' as const,\n /** Default policy mode. */\n policyMode: 'enforce' as const,\n /** Default sandbox mode. */\n sandboxMode: 'policy' as const,\n /** Whether to fall back to policy mode if container unavailable. */\n sandboxFallbackToPolicy: true,\n /** Whether network is enabled in container mode. */\n sandboxNetworkEnabled: false,\n },\n} as const;\n\n// ============================================================================\n// Type Exports for DEFAULTS\n// ============================================================================\n\n/** Type for the DEFAULTS object (readonly/const). */\nexport type DefaultsConfig = typeof DEFAULTS;\n\n/** Type for timeout defaults (readonly/const). */\nexport type TimeoutDefaultsConst = typeof DEFAULTS.TIMEOUT_DEFAULTS;\n\n/** Type for rate limit defaults (readonly/const). */\nexport type RateLimitDefaultsConst = typeof DEFAULTS.RATE_LIMIT_DEFAULTS;\n\n/** Type for retry defaults (readonly/const). */\nexport type RetryDefaultsConst = typeof DEFAULTS.RETRY_DEFAULTS;\n\n/** Type for buffer defaults (readonly/const). */\nexport type BufferDefaults = typeof DEFAULTS.BUFFER_DEFAULTS;\n\n/** Type for circuit breaker defaults (readonly/const). */\nexport type CircuitBreakerDefaultsConst = typeof DEFAULTS.CIRCUIT_BREAKER_DEFAULTS;\n\n/** Type for context defaults (readonly/const). */\nexport type ContextDefaults = typeof DEFAULTS.CONTEXT_DEFAULTS;\n\n/** Type for provider defaults (readonly/const). */\nexport type ProviderDefaults = typeof DEFAULTS.PROVIDER_DEFAULTS;\n\n/** Type for security defaults (readonly/const). */\nexport type SecurityDefaults = typeof DEFAULTS.SECURITY_DEFAULTS;\n\n// ============================================================================\n// Environment Override Functions (bound to DEFAULTS)\n// ============================================================================\n\n/**\n * Get timeout with environment override support.\n *\n * @param key - Timeout key (e.g., 'cliMs', 'apiMs')\n * @returns Timeout value in milliseconds\n */\nexport const getTimeout = createGetTimeout(DEFAULTS.TIMEOUT_DEFAULTS);\n\n// getRetryConfig, getRateLimitConfig and getCircuitBreakerConfig removed in\n// #5903. They promised \"environment override support\" for twelve NEXUS_*\n// variables that no running code read: `config get` reported them as\n// `Source: (env)` while the rate limiter took `enabled` from the config file,\n// retry used the static DEFAULT_RETRY_CONFIG, and the circuit breakers carried\n// their own config. Same treatment as the worker knobs in #2977 and the\n// per-complexity CLI timeouts in #4180. Read DEFAULTS.* directly.\n\n/**\n * Gets the tool rate limit configuration for a specific tool category.\n *\n * @param tool - Tool category (orchestrate, delegate, workflow, expert)\n * @returns Rate limit configuration\n */\nexport const getToolRateLimit = createGetToolRateLimit(DEFAULTS.TOOL_RATE_LIMITS);\n\n// ============================================================================\n// Documentation Helper\n// ============================================================================\n\n/**\n * Returns documentation for all environment variable overrides.\n *\n * @returns Markdown documentation string\n */\nexport const getEnvVarDocumentation = createGetEnvVarDocumentation(DEFAULTS);\n"],"mappings":"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","names":[]}
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  resolveCliSlot
3
- } from "./chunk-AOQDLJHG.js";
3
+ } from "./chunk-SECO5QH5.js";
4
4
  import {
5
5
  createLogger,
6
6
  getTimeProvider,
7
7
  isRateLimitText
8
- } from "./chunk-RZF4GUMI.js";
8
+ } from "./chunk-SMYK36R3.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-A3YWHFOY.js");
24
+ const { generateMcpConfig } = await import("./child-mcp-config-2IJ3TXG5.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-YIFRH73W.js");
97
- const { createCompositeRouter } = await import("./composite-router-CKTUXIDB.js");
96
+ const { createAllAdapters } = await import("./factory-GUD4XQK6.js");
97
+ const { createCompositeRouter } = await import("./composite-router-2TDAOPFD.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-DNKQCKSD.js");
105
+ const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-ROZJLYNB.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-O5TIFR2H.js.map
216
+ //# sourceMappingURL=chunk-GEUZK7QR.js.map
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-YYJFZ7TO.js";
6
6
  import {
7
7
  nexusDataPath
8
- } from "./chunk-JVNJJ2VL.js";
8
+ } from "./chunk-MBAREN43.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-7PPGN5C5.js.map
96
+ //# sourceMappingURL=chunk-H6JJL3PK.js.map
@@ -5,17 +5,17 @@ import {
5
5
  } from "./chunk-7LP6VJRP.js";
6
6
  import {
7
7
  SessionMemory
8
- } from "./chunk-GFXWGCWS.js";
8
+ } from "./chunk-URM6RDIR.js";
9
9
  import {
10
10
  StatsOnlyAdapter,
11
11
  ensureSharedMemoryRegistry
12
- } from "./chunk-7PPGN5C5.js";
12
+ } from "./chunk-H6JJL3PK.js";
13
13
  import {
14
14
  getMemoryRegistry
15
15
  } from "./chunk-YYJFZ7TO.js";
16
16
  import {
17
17
  generateId
18
- } from "./chunk-4XESQ3X6.js";
18
+ } from "./chunk-7BHQKEC2.js";
19
19
  import {
20
20
  ErrorCode,
21
21
  NexusError,
@@ -29,10 +29,10 @@ import {
29
29
  ok,
30
30
  openSqliteDatabase,
31
31
  setSharedMobiMemDbPathResolver
32
- } from "./chunk-RZF4GUMI.js";
32
+ } from "./chunk-SMYK36R3.js";
33
33
  import {
34
34
  nexusDataPath
35
- } from "./chunk-JVNJJ2VL.js";
35
+ } from "./chunk-MBAREN43.js";
36
36
 
37
37
  // src/mcp/tools/tool-memory.ts
38
38
  import * as fs3 from "node:fs";
@@ -5825,4 +5825,4 @@ export {
5825
5825
  reinitializeMemoryBackends,
5826
5826
  ToolMemoryManager
5827
5827
  };
5828
- //# sourceMappingURL=chunk-WRGVTEKL.js.map
5828
+ //# sourceMappingURL=chunk-HI7VU3WE.js.map
@@ -3,10 +3,10 @@ import {
3
3
  createLogger,
4
4
  getDefaultRegistry,
5
5
  roundToMicroUsd
6
- } from "./chunk-RZF4GUMI.js";
6
+ } from "./chunk-SMYK36R3.js";
7
7
  import {
8
8
  getNexusDataDir
9
- } from "./chunk-JVNJJ2VL.js";
9
+ } from "./chunk-MBAREN43.js";
10
10
 
11
11
  // src/learning/usage-log.ts
12
12
  import { z } from "zod";
@@ -196,4 +196,4 @@ export {
196
196
  loadUsageEvents,
197
197
  rollupByModel
198
198
  };
199
- //# sourceMappingURL=chunk-2QZVFXR7.js.map
199
+ //# sourceMappingURL=chunk-HRJ4TWXZ.js.map
@@ -2,7 +2,7 @@ import {
2
2
  TASK_CATEGORIES,
3
3
  getAdaptiveBonus,
4
4
  getOutcomeStore
5
- } from "./chunk-RZF4GUMI.js";
5
+ } from "./chunk-SMYK36R3.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-YIKC3GNF.js.map
109
+ //# sourceMappingURL=chunk-LEKS5OZR.js.map
@@ -7,14 +7,6 @@ function parseIntEnv(envKey, fallback) {
7
7
  const parsed = parseInt(envValue, 10);
8
8
  return isNaN(parsed) || parsed <= 0 ? fallback : parsed;
9
9
  }
10
- function parseFloatEnv(envKey, fallback) {
11
- const envValue = process.env[envKey];
12
- if (envValue === void 0) {
13
- return fallback;
14
- }
15
- const parsed = parseFloat(envValue);
16
- return isNaN(parsed) || !isFinite(parsed) ? fallback : parsed;
17
- }
18
10
  function parseBoolValue(value, fallback) {
19
11
  const normalized = value?.toLowerCase();
20
12
  if (normalized === void 0) {
@@ -33,47 +25,6 @@ function createGetTimeout(timeoutDefaults) {
33
25
  return parseIntEnv(envKey, timeoutDefaults[key]);
34
26
  };
35
27
  }
36
- function createGetRetryConfig(retryDefaults) {
37
- return () => {
38
- return {
39
- maxRetries: parseIntEnv("NEXUS_RETRY_MAX_RETRIES", retryDefaults.maxRetries),
40
- baseDelayMs: parseIntEnv("NEXUS_RETRY_BASE_DELAY", retryDefaults.baseDelayMs),
41
- maxDelayMs: parseIntEnv("NEXUS_RETRY_MAX_DELAY", retryDefaults.maxDelayMs),
42
- jitterFactor: parseFloatEnv("NEXUS_RETRY_JITTER", retryDefaults.jitterFactor)
43
- };
44
- };
45
- }
46
- function createGetRateLimitConfig(rateLimitDefaults) {
47
- return () => {
48
- return {
49
- requestsPerMinute: parseIntEnv("NEXUS_RATE_LIMIT_RPM", rateLimitDefaults.requestsPerMinute),
50
- enabled: parseBoolEnv("NEXUS_RATE_LIMIT_ENABLED", rateLimitDefaults.enabled),
51
- maxConcurrent: parseIntEnv(
52
- "NEXUS_RATE_LIMIT_MAX_CONCURRENT",
53
- rateLimitDefaults.maxConcurrent
54
- ),
55
- capacity: parseIntEnv("NEXUS_RATE_LIMIT_CAPACITY", rateLimitDefaults.capacity),
56
- refillRate: parseIntEnv("NEXUS_RATE_LIMIT_REFILL_RATE", rateLimitDefaults.refillRate),
57
- refillIntervalMs: parseIntEnv(
58
- "NEXUS_RATE_LIMIT_REFILL_INTERVAL",
59
- rateLimitDefaults.refillIntervalMs
60
- )
61
- };
62
- };
63
- }
64
- function createGetCircuitBreakerConfig(cbDefaults) {
65
- return () => {
66
- return {
67
- failureThreshold: parseIntEnv("NEXUS_CIRCUIT_BREAKER_THRESHOLD", cbDefaults.failureThreshold),
68
- resetTimeoutMs: parseIntEnv("NEXUS_CIRCUIT_BREAKER_RESET_TIMEOUT", cbDefaults.resetTimeoutMs),
69
- halfOpenSuccessThreshold: cbDefaults.halfOpenSuccessThreshold,
70
- countTimeoutsAsFailures: cbDefaults.countTimeoutsAsFailures,
71
- countAuthFailuresAsFailures: cbDefaults.countAuthFailuresAsFailures,
72
- countRateLimitsAsFailures: cbDefaults.countRateLimitsAsFailures,
73
- halfOpenMaxRequests: cbDefaults.halfOpenMaxRequests
74
- };
75
- };
76
- }
77
28
  function createGetToolRateLimit(toolRateLimits) {
78
29
  return (tool) => {
79
30
  return toolRateLimits[tool];
@@ -82,9 +33,6 @@ function createGetToolRateLimit(toolRateLimits) {
82
33
  function createGetEnvVarDocumentation(defaults) {
83
34
  return () => {
84
35
  const t = defaults.TIMEOUT_DEFAULTS;
85
- const r = defaults.RATE_LIMIT_DEFAULTS;
86
- const rt = defaults.RETRY_DEFAULTS;
87
- const cb = defaults.CIRCUIT_BREAKER_DEFAULTS;
88
36
  return `# Environment Variable Overrides
89
37
 
90
38
  All defaults can be overridden via environment variables using the NEXUS_ prefix.
@@ -98,29 +46,11 @@ All defaults can be overridden via environment variables using the NEXUS_ prefix
98
46
  | NEXUS_TIMEOUT_WORKFLOW | ${String(t.workflowMs)} | Workflow timeout (ms) |
99
47
  | NEXUS_TIMEOUT_MCP | ${String(t.mcpMs)} | MCP operation timeout (ms) |
100
48
 
101
- ## Rate Limits
102
-
103
- | Variable | Default | Description |
104
- | -------- | ------- | ----------- |
105
- | NEXUS_RATE_LIMIT_RPM | ${String(r.requestsPerMinute)} | Requests per minute |
106
- | NEXUS_RATE_LIMIT_ENABLED | ${String(r.enabled)} | Enable rate limiting |
107
- | NEXUS_RATE_LIMIT_CAPACITY | ${String(r.capacity)} | Token bucket capacity |
108
49
 
109
- ## Retries
110
-
111
- | Variable | Default | Description |
112
- | -------- | ------- | ----------- |
113
- | NEXUS_RETRY_MAX_RETRIES | ${String(rt.maxRetries)} | Maximum retry attempts |
114
- | NEXUS_RETRY_BASE_DELAY | ${String(rt.baseDelayMs)} | Base delay (ms) |
115
- | NEXUS_RETRY_MAX_DELAY | ${String(rt.maxDelayMs)} | Maximum delay (ms) |
116
- | NEXUS_RETRY_JITTER | ${String(rt.jitterFactor)} | Jitter factor (0-1) |
117
-
118
- ## Circuit Breaker
119
-
120
- | Variable | Default | Description |
121
- | -------- | ------- | ----------- |
122
- | NEXUS_CIRCUIT_BREAKER_THRESHOLD | ${String(cb.failureThreshold)} | Failure threshold |
123
- | NEXUS_CIRCUIT_BREAKER_RESET_TIMEOUT | ${String(cb.resetTimeoutMs)} | Reset timeout (ms) |
50
+ Rate-limit, retry and circuit-breaker sections removed in #5903: their twelve
51
+ variables were registered and documented but read by nothing that runs, so this
52
+ generator was advertising names an operator could set to no effect. Rate
53
+ limiting is configured through the config file's \`security.rateLimit\`.
124
54
  `;
125
55
  };
126
56
  }
@@ -518,9 +448,6 @@ export {
518
448
  parseBoolValue,
519
449
  parseBoolEnv,
520
450
  createGetTimeout,
521
- createGetRetryConfig,
522
- createGetRateLimitConfig,
523
- createGetCircuitBreakerConfig,
524
451
  createGetToolRateLimit,
525
452
  createGetEnvVarDocumentation,
526
453
  getNexusDataDir,
@@ -533,4 +460,4 @@ export {
533
460
  getPerRepoSubdirs,
534
461
  sessionsDbPath
535
462
  };
536
- //# sourceMappingURL=chunk-JVNJJ2VL.js.map
463
+ //# sourceMappingURL=chunk-MBAREN43.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/defaults-env.ts","../src/config/nexus-data-dir.ts","../src/config/sandbox-detection.ts","../src/config/repo-root-detection.ts","../src/config/portable-mode.ts"],"sourcesContent":["/**\n * Environment Variable Override Helpers\n *\n * Provides utilities for reading configuration from environment variables\n * with type-safe fallbacks to defaults.\n *\n * @module config/defaults-env\n */\n\nimport type {\n ToolRateLimitConfig,\n} from './defaults-types.js';\n\n// ============================================================================\n// Environment Variable Parsers\n// ============================================================================\n\n/**\n * Parses an integer from an environment variable with fallback.\n */\nexport function parseIntEnv(envKey: string, fallback: number): number {\n const envValue = process.env[envKey];\n if (envValue === undefined) {\n return fallback;\n }\n const parsed = parseInt(envValue, 10);\n return isNaN(parsed) || parsed <= 0 ? fallback : parsed;\n}\n\n/**\n * Parses a float from an environment variable with fallback.\n */\nexport function parseFloatEnv(envKey: string, fallback: number): number {\n const envValue = process.env[envKey];\n if (envValue === undefined) {\n return fallback;\n }\n const parsed = parseFloat(envValue);\n return isNaN(parsed) || !isFinite(parsed) ? fallback : parsed;\n}\n\n/**\n * Parses a boolean flag value with fallback — the ONE accept-set for every\n * `NEXUS_*` boolean flag (#5155): `true`/`1` are truthy, `false`/`0` are\n * falsy, case-insensitively. Any other value (including `yes`/`no`/`on`/`off`\n * and the empty string) returns the fallback; `config/env-schema.ts`\n * (`boolLooseStr`) reports those at startup so the fallback is never silent.\n *\n * Pure so consumers that read an injected env object rather than\n * `process.env` (e.g. `cli-adapters/subprocess-env.ts`) share the same set.\n */\nexport function parseBoolValue(value: string | undefined, fallback: boolean): boolean {\n const normalized = value?.toLowerCase();\n if (normalized === undefined) {\n return fallback;\n }\n if (normalized === 'true' || normalized === '1') return true;\n if (normalized === 'false' || normalized === '0') return false;\n return fallback;\n}\n\n/**\n * Parses a boolean from an environment variable with fallback.\n * Delegates to {@link parseBoolValue}: only 'true'/'1' are truthy,\n * 'false'/'0' are falsy (case-insensitive); any other value returns the fallback.\n */\nexport function parseBoolEnv(envKey: string, fallback: boolean): boolean {\n return parseBoolValue(process.env[envKey], fallback);\n}\n\n// ============================================================================\n// Config Getter Types (for lazy initialization)\n// ============================================================================\n\n/** Timeout defaults type from DEFAULTS object */\nexport interface TimeoutDefaultsConst {\n readonly cliMs: number;\n // cliSimpleMs / cliComplexMs removed in #4180 — see config/defaults.ts.\n readonly apiMs: number;\n readonly apiMaxMs: number;\n readonly workflowMs: number;\n readonly workflowMaxMs: number;\n readonly stepMs: number;\n readonly mcpMs: number;\n readonly mcpMaxMs: number;\n readonly healthCheckMs: number;\n readonly testGlobalMs: number;\n readonly testTaskMs: number;\n readonly circuitBreakerResetMs: number;\n}\n\n/** Tool rate limits type from DEFAULTS object */\nexport interface ToolRateLimitsConst {\n readonly orchestrate: ToolRateLimitConfig;\n readonly delegate: ToolRateLimitConfig;\n readonly workflow: ToolRateLimitConfig;\n readonly expert: ToolRateLimitConfig;\n}\n\n/** Rate limit defaults type from DEFAULTS object */\ninterface RateLimitDefaultsConst {\n readonly requestsPerMinute: number;\n readonly enabled: boolean;\n readonly maxConcurrent: number;\n readonly capacity: number;\n readonly refillRate: number;\n readonly refillIntervalMs: number;\n}\n\n/** Retry defaults type from DEFAULTS object */\ninterface RetryDefaultsConst {\n readonly maxRetries: number;\n readonly baseDelayMs: number;\n readonly maxDelayMs: number;\n readonly jitterFactor: number;\n}\n\n/** Circuit breaker defaults type from DEFAULTS object */\ninterface CircuitBreakerDefaultsConst {\n readonly failureThreshold: number;\n readonly resetTimeoutMs: number;\n readonly halfOpenSuccessThreshold: number;\n readonly countTimeoutsAsFailures: boolean;\n readonly countAuthFailuresAsFailures: boolean;\n readonly countRateLimitsAsFailures: boolean;\n readonly halfOpenMaxRequests: number;\n}\n\n// ============================================================================\n// Config Getter Factory Functions\n// ============================================================================\n\n/**\n * Creates a timeout getter function bound to the DEFAULTS object.\n */\nexport function createGetTimeout(\n timeoutDefaults: TimeoutDefaultsConst\n): (key: keyof TimeoutDefaultsConst) => number {\n return (key: keyof TimeoutDefaultsConst): number => {\n const envKey = `NEXUS_TIMEOUT_${key.replace(/Ms$/, '').toUpperCase()}`;\n return parseIntEnv(envKey, timeoutDefaults[key]);\n };\n}\n\n// createGetWorkerConfig removed in #2977. createGetRetryConfig,\n// createGetRateLimitConfig and createGetCircuitBreakerConfig removed in #5903\n// for the same reason: their twelve NEXUS_* variables were registered,\n// documented and echoed back by `config get` as `Source: (env)`, and read by\n// nothing that runs. The rate limiter takes `enabled` from the config file\n// (`cli-server-tools.ts`), retry builds DEFAULT_RETRY_CONFIG from the static\n// DEFAULTS (`adapters/retry.ts`), and the production circuit breakers carry\n// their own config. See the comment in config/defaults.ts.\n\n/**\n * Creates a tool rate limit getter function bound to the DEFAULTS object.\n */\nexport function createGetToolRateLimit(\n toolRateLimits: ToolRateLimitsConst\n): (tool: keyof ToolRateLimitsConst) => ToolRateLimitConfig {\n return (tool: keyof ToolRateLimitsConst): ToolRateLimitConfig => {\n return toolRateLimits[tool];\n };\n}\n\n// ============================================================================\n// Documentation Helper\n// ============================================================================\n\n/** DEFAULTS structure for documentation generation */\ninterface DefaultsForDocs {\n readonly TIMEOUT_DEFAULTS: TimeoutDefaultsConst;\n readonly RATE_LIMIT_DEFAULTS: RateLimitDefaultsConst;\n readonly RETRY_DEFAULTS: RetryDefaultsConst;\n readonly CIRCUIT_BREAKER_DEFAULTS: CircuitBreakerDefaultsConst;\n}\n\n/**\n * Creates a documentation generator function bound to the DEFAULTS object.\n *\n * @param defaults - The DEFAULTS object\n * @returns Function that generates environment variable documentation\n */\nexport function createGetEnvVarDocumentation(defaults: DefaultsForDocs): () => string {\n return (): string => {\n const t = defaults.TIMEOUT_DEFAULTS;\n\n return `# Environment Variable Overrides\n\nAll defaults can be overridden via environment variables using the NEXUS_ prefix.\n\n## Timeouts\n\n| Variable | Default | Description |\n| -------- | ------- | ----------- |\n| NEXUS_TIMEOUT_CLI | ${String(t.cliMs)} | CLI execution timeout (ms) |\n| NEXUS_TIMEOUT_API | ${String(t.apiMs)} | API request timeout (ms) |\n| NEXUS_TIMEOUT_WORKFLOW | ${String(t.workflowMs)} | Workflow timeout (ms) |\n| NEXUS_TIMEOUT_MCP | ${String(t.mcpMs)} | MCP operation timeout (ms) |\n\n\nRate-limit, retry and circuit-breaker sections removed in #5903: their twelve\nvariables were registered and documented but read by nothing that runs, so this\ngenerator was advertising names an operator could set to no effect. Rate\nlimiting is configured through the config file's \\`security.rateLimit\\`.\n`;\n };\n}\n","/**\n * Nexus runtime data directory resolver (#2302, child of #2301).\n *\n * Returns the absolute path under which nexus-agents stores runtime state.\n * Two categories of state exist (epic #2872, vote #2876):\n *\n * - **Per-repo** state (sessions, checkpoints, traces, runs, audit,\n * pipeline, tasks) — tied to the work happening in a specific codebase.\n * When `NEXUS_REPO_PREFERRED=1` is set and the caller is inside a git\n * repo, these resolve to `<repo-root>/.nexus-agents/<subdir>/`.\n * - **Cross-repo** state (learning, voting, memory, weather, research,\n * auth, usage, models manifest) — accumulates across the operator's\n * whole workflow. Always resolves to `~/.nexus-agents/<subdir>/` so the\n * learning/routing feedback loop from #1389 / #1407 keeps working.\n *\n * Resolution order (first match wins):\n * 1. `NEXUS_DATA_DIR` env var if set + non-empty. Wins for both categories\n * — the operator's explicit choice overrides the split.\n * 2. Sandbox-mode default (#2501): when `NEXUS_SANDBOX` is set, use\n * `${NEXUS_SANDBOX_ROOT ?? '/'}/.nexus-agents`. Sandboxed deployments\n * typically mount a multi-repo root; state goes there, shared across\n * repo subfolders rather than buried inside one.\n * 3. Per-repo subdirs (when a repo root is known AND `NEXUS_REPO_PREFERRED`\n * is not explicitly `'0'`): `<repo-root>/.nexus-agents/<subdir>/`. The\n * repo root is the active workspace root when one has been set via\n * `setActiveWorkspaceRoot()` (the MCP server derives it from the client's\n * declared `roots`, MCP spec — see #3991), otherwise `findRepoRoot(cwd)`.\n * The active-root path exists because a globally-installed MCP server runs\n * with `process.cwd()` outside the repo, so cwd-based detection would\n * wrongly route per-repo state to homedir. Auto-adds `.nexus-agents/` to\n * the repo's `.gitignore` on first resolution (fail-closed).\n * 4. Cross-repo subdirs when `~/.nexus-agents/` is unwritable AND we're\n * in a repo: per-repo fallback at `<repo-root>/.nexus-agents/<subdir>/`\n * with one-time stderr announce. Issue #2888 — gives sandbox users\n * a working `research/`, `memory/`, etc. without env-var wrangling\n * while preserving the vote #2876 default for normal-machine users.\n * 5. `<homedir>/.nexus-agents` (cross-repo state on normal machines,\n * plus everything when not in a git repo or when\n * `NEXUS_REPO_PREFERRED=0`).\n *\n * `NEXUS_REPO_PREFERRED` defaults **ON** as of this release per vote\n * #2876. Escape hatches preserved:\n * - `NEXUS_REPO_PREFERRED=0` — fully opt out (homedir for everything).\n * - `NEXUS_DATA_DIR=~/.nexus-agents` — explicit override wins over\n * the tier and the categorization both.\n * - `nexus-agents migrate` (#2879) — relocate existing homedir state\n * into `<repo>/.nexus-agents/` before flipping in production.\n *\n * @module config/nexus-data-dir\n */\n\nimport {\n accessSync,\n constants as fsConstants,\n copyFileSync,\n existsSync,\n mkdirSync,\n realpathSync,\n renameSync,\n statSync,\n unlinkSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\n\nimport { detectSandbox } from './sandbox-detection.js';\nimport { findRepoRoot } from './repo-root-detection.js';\nimport { ensureGitignored } from './portable-mode.js';\nimport { parseBoolEnv } from './defaults-env.js';\n\n/**\n * Subdirs scoped to a single repo's work (per the epic #2872 vote).\n * When `NEXUS_REPO_PREFERRED=1` and the caller is inside a git repo, these\n * route to `<repo-root>/.nexus-agents/`; otherwise homedir. The complement\n * (everything not in this set) always goes to homedir so cross-project\n * learning state stays intact.\n *\n * Source-of-truth for the categorization: vote #2876 conditions + audit\n * thread on epic #2872. Adding a new entry here is the appropriate way to\n * mark new state as per-repo — do that as a deliberate decision, not by\n * default.\n */\nconst PER_REPO_SUBDIRS: ReadonlySet<string> = new Set([\n // Scratch space for short-lived work (worktrees, prompt files, MCP configs).\n // Per-repo because a throwaway worktree of repo A is meaningless to repo B,\n // and because containing it here keeps it inside the already-gitignored\n // `.nexus-agents/` tree instead of accumulating in a shared `/tmp` nobody\n // reaps. A full `/tmp` is not a theoretical problem: it silently broke this\n // repo's own test suite, with ~1,100 files failing to COLLECT and zero\n // assertion failures, which reads like a code fault and is not one.\n 'tmp',\n 'sessions',\n 'checkpoints',\n 'traces',\n 'runs',\n 'audit',\n 'pipeline',\n 'tasks',\n // Async-mode job results (#3042 / epic #2631). Tied to work happening\n // in a specific codebase — a job dispatched on repo A shouldn't be\n // polled-against on repo B, which would happen if jobs/ were homedir-scoped.\n 'jobs',\n // CI health-check events (#3076 / #3084). Per-repo because outages\n // reported via `ci_health_check({ repo })` are repo-correlated; a wedge\n // on repo A's queue does not predict repo B's health.\n 'ci-health',\n // Governance artifacts — the runtime authentic-vote-record ledger\n // (`governance/vote-records.jsonl`, #3897/#3927/#3991). Per-repo because a\n // promotion proposal is scoped to the codebase being changed; with\n // `NEXUS_REPO_PREFERRED=1` (default) these route to\n // `<repo>/.nexus-agents/governance/` (gitignored), and to\n // `~/.nexus-agents/governance/` otherwise (global / non-repo install). This\n // is DISTINCT from the committed `<repo>/governance/vote-records.jsonl`\n // ledger the promotion gate reads — that artifact is reached only via the\n // explicit `NEXUS_VOTE_RECORDS_PATH` override (#3991).\n 'governance',\n]);\n\n/** Returns the absolute path to the nexus-agents data directory. */\nexport function getNexusDataDir(): string {\n const fromEnv = process.env['NEXUS_DATA_DIR']?.trim();\n if (fromEnv !== undefined && fromEnv !== '') {\n return resolve(fromEnv);\n }\n const sandbox = detectSandbox();\n if (sandbox.active) {\n return resolve(sandbox.root ?? '/', '.nexus-agents');\n }\n return join(homedir(), '.nexus-agents');\n}\n\n/**\n * No-op kept for source-compatibility with consumers that called this\n * earlier in development. The resolver is no longer cached, so resetting\n * is unnecessary. Kept exported (rather than removed) to avoid breaking\n * imports in tests that may have already adopted it.\n */\nexport function resetNexusDataDirCache(): void {\n // intentionally empty — see module docstring\n}\n\n/**\n * Tracks per-process state for the auto-gitignore wiring: we only need\n * to (a) probe + append to `.gitignore` once per repo, and (b) bail\n * cleanly if the operator has explicitly silenced the auto-add via\n * `NEXUS_GITIGNORE_AUTO=false`. Reset in tests via the helper below.\n */\nconst gitignoredRoots = new Set<string>();\n\n/** Test helper — clears the auto-gitignore \"already did this\" memo. */\nexport function _resetGitignoreMemoForTests(): void {\n gitignoredRoots.clear();\n}\n\n/**\n * Active workspace root, when known from a source more authoritative than\n * `process.cwd()`. Set by the MCP server (#3991) from the client's declared\n * `roots` (MCP spec) once the initialize handshake completes, because a\n * globally-installed server runs with cwd OUTSIDE the repo being worked on —\n * so cwd-based repo detection would route per-repo `.nexus-agents` state to\n * homedir instead of `<repo>/.nexus-agents/`. CLI / in-repo callers never set\n * this, so they keep resolving via `findRepoRoot(cwd)` exactly as before.\n */\nlet activeWorkspaceRoot: string | undefined;\n\n/**\n * Records the active workspace root for repo-scoped data resolution. The\n * value is cross-trust-boundary input (it arrives over the MCP transport from\n * the client), so it is validated before use: resolved to an absolute path,\n * canonicalized via `realpathSync` (defeats symlink games), and required to\n * be an existing directory. Returns `true` when accepted, `false` when the\n * value is empty/invalid (in which case the previous root is left untouched).\n * Passing `null`/empty explicitly clears any previously-set root.\n */\nexport function setActiveWorkspaceRoot(root: string | null | undefined): boolean {\n const trimmed = root?.trim();\n if (trimmed === undefined || trimmed === '') {\n activeWorkspaceRoot = undefined;\n return false;\n }\n try {\n const canonical = realpathSync(resolve(trimmed));\n if (!isAbsolute(canonical) || !statSync(canonical).isDirectory()) return false;\n activeWorkspaceRoot = canonical;\n return true;\n } catch {\n // Nonexistent path, permission error, or broken symlink — reject and keep\n // whatever was set before so a bad late signal can't corrupt resolution.\n return false;\n }\n}\n\n/** Returns the active workspace root if one has been set, else `undefined`. */\nexport function getActiveWorkspaceRoot(): string | undefined {\n return activeWorkspaceRoot;\n}\n\n/** Test helper — clears the active workspace root memo. */\nexport function _resetActiveWorkspaceRootForTests(): void {\n activeWorkspaceRoot = undefined;\n}\n\n/**\n * Returns the repo-scoped `.nexus-agents/` directory if all of the\n * following hold: `NEXUS_REPO_PREFERRED` is NOT explicitly `'0'` (it\n * defaults ON as of vote #2876), `NEXUS_DATA_DIR` is not explicitly set\n * (explicit override always wins), no sandbox is active, and a repo root is\n * known — either the active workspace root (set via\n * `setActiveWorkspaceRoot()`) or an ancestor `.git` found by\n * `findRepoRoot(cwd)`.\n *\n * Side effect: on the first successful resolution per process per repo,\n * appends `.nexus-agents/` to the repo's `.gitignore` if not already\n * present. The operator can silence this with the boolean\n * `NEXUS_GITIGNORE_AUTO` set to `false`/`0` (e.g. on CI runners with a\n * frozen working tree).\n *\n * Returns `null` when any precondition fails; callers fall back to\n * `getNexusDataDir()` (homedir).\n */\nexport function getNexusRepoDir(): string | null {\n if (process.env['NEXUS_REPO_PREFERRED'] === '0') return null;\n const fromEnv = process.env['NEXUS_DATA_DIR']?.trim();\n if (fromEnv !== undefined && fromEnv !== '') return null;\n if (detectSandbox().active) return null;\n // Prefer the MCP-client-declared workspace root (#3991) when the server has\n // set it; fall back to walking up from cwd for CLI / in-repo callers.\n const root = activeWorkspaceRoot ?? findRepoRoot(process.cwd());\n if (root === null) return null;\n maybeAutoGitignore(root);\n return join(root, '.nexus-agents');\n}\n\n/**\n * Best-effort fail-closed wiring: once per process per repo, ensure\n * `.nexus-agents/` is in `<repo>/.gitignore`. Silenced via the boolean\n * `NEXUS_GITIGNORE_AUTO=false` (or `0`; default on — #5155). Failures are\n * non-fatal — the helper logs to stderr and continues.\n */\nfunction maybeAutoGitignore(repoRoot: string): void {\n if (!parseBoolEnv('NEXUS_GITIGNORE_AUTO', true)) return;\n if (gitignoredRoots.has(repoRoot)) return;\n gitignoredRoots.add(repoRoot);\n // Only attempt when the repo root looks real — avoid spamming stderr\n // from temp-dir test fixtures that race the lifecycle.\n if (!existsSync(repoRoot)) return;\n ensureGitignored(repoRoot, '.nexus-agents/');\n}\n\n/**\n * Per-process memo: was the homedir base directory found writable on first\n * probe? Used to short-circuit the sandbox-fallback decision in\n * `nexusDataPath()` without spending a syscall on every call.\n */\nlet homedirWritable: boolean | undefined;\n\n/** Per-process memo: have we already announced a fallback for this subdir? */\nconst announcedFallbacks = new Set<string>();\n\n/** Test helper — clears the homedir-writability + announcement memos. */\nexport function _resetWritabilityMemoForTests(): void {\n homedirWritable = undefined;\n announcedFallbacks.clear();\n}\n\n/**\n * Returns true if `getNexusDataDir()` resolves to a writable location. Probed\n * once per process and memo'd — flips the sandbox-fallback on/off for\n * cross-repo subdirs. `mkdirSync(recursive: true)` is the safest probe\n * because it both creates the dir if missing and surfaces ENOENT/EACCES\n * issues at the same point. Failures here are non-fatal — they just route\n * cross-repo state to the per-repo fallback (issue #2888).\n */\nfunction isHomedirBaseWritable(): boolean {\n if (homedirWritable !== undefined) return homedirWritable;\n const base = getNexusDataDir();\n try {\n mkdirSync(base, { recursive: true });\n accessSync(base, fsConstants.W_OK);\n homedirWritable = true;\n } catch {\n homedirWritable = false;\n }\n return homedirWritable;\n}\n\n/**\n * Emit a one-time stderr warning when a cross-repo subdir falls back to\n * the per-repo location. Operators in sandboxes get a clear signal about\n * what happened without per-call noise.\n */\nfunction announceCrossRepoFallback(subdir: string, repoPath: string): void {\n if (announcedFallbacks.has(subdir)) return;\n announcedFallbacks.add(subdir);\n process.stderr.write(\n `[nexus] ${subdir}: homedir ~/.nexus-agents is not writable; ` +\n `using per-repo fallback at ${repoPath}. See docs/guides/SANDBOXED-USAGE.md.\\n`\n );\n}\n\n/**\n * Returns a path joined under the appropriate data directory for the\n * given subdir.\n *\n * Routing decision (first match wins):\n * 1. **Per-repo subdir + in a repo + `NEXUS_REPO_PREFERRED` not '0'** →\n * `<repo>/.nexus-agents/<subdir>/...`. Standard behavior since #2884.\n * 2. **Cross-repo subdir + homedir unwritable + in a repo** →\n * `<repo>/.nexus-agents/<subdir>/...` as a sandbox-friendly fallback\n * (issue #2888). Emits a one-time stderr warning per subdir.\n * 3. **Otherwise** → `<homedir>/.nexus-agents/<subdir>/...`. If homedir\n * is also unwritable, the actual write will surface the error.\n *\n * Existing callers don't need to change — the routing decision is driven\n * by the first segment, not by caller-declared intent.\n */\nexport function nexusDataPath(...segments: string[]): string {\n const first = segments[0];\n\n // Tier 1: per-repo subdir + repo-preferred default.\n if (first !== undefined && PER_REPO_SUBDIRS.has(first)) {\n const repoDir = getNexusRepoDir();\n if (repoDir !== null) {\n return join(repoDir, ...segments);\n }\n }\n\n // Tier 2: cross-repo subdir but homedir isn't reachable. Fall back to\n // the per-repo location if we're in a repo, so sandbox users get a\n // working `research/`, `memory/`, etc. without manual env-var setup.\n // Vote #2876 preserved: this only fires when homedir is physically\n // unreachable; normal-machine users see no change.\n if (first !== undefined && !isHomedirBaseWritable()) {\n const repoDir = getNexusRepoDir();\n if (repoDir !== null) {\n const fallbackPath = join(repoDir, ...segments);\n announceCrossRepoFallback(first, fallbackPath);\n return fallbackPath;\n }\n // No repo to fall back to AND homedir unreachable — return the\n // homedir path anyway. The caller's eventual write will surface\n // the underlying EACCES/ENOENT, which is the right error to show\n // because the environment is genuinely broken at that point.\n }\n\n return join(getNexusDataDir(), ...segments);\n}\n\n/**\n * Like `nexusDataPath()` but eagerly creates the parent directory so\n * callers don't have to remember `mkdirSync(dirname(p), { recursive: true })`\n * before every write. Issue #2890. Use when the returned path will be\n * written to immediately; for read-only resolution prefer `nexusDataPath()`.\n *\n * If the call resolves to a directory (single segment or no segments),\n * the target IS the resolved path. If it resolves to a file (multiple\n * segments), the target is its parent.\n */\nexport function nexusDataPathEnsure(...segments: string[]): string {\n const resolved = nexusDataPath(...segments);\n const target = segments.length > 1 ? dirname(resolved) : resolved;\n mkdirSync(target, { recursive: true });\n return resolved;\n}\n\n/**\n * Explicitly homedir-scoped path. Use this in code that handles\n * cross-project state (routing memory, model registry cache, auth,\n * research catalog) where you want a hard guarantee that the resolver\n * never routes per-repo, even if a new subdir gets accidentally added\n * to the `PER_REPO_SUBDIRS` allowlist later.\n */\nexport function nexusSharedPath(...segments: string[]): string {\n return join(getNexusDataDir(), ...segments);\n}\n\n/**\n * Returns the read-only categorization used by `nexusDataPath()`.\n * Exposed for tests and for tooling that wants to introspect which\n * subdirs are per-repo (e.g. the `nexus-agents migrate` command).\n */\nexport function getPerRepoSubdirs(): ReadonlySet<string> {\n return PER_REPO_SUBDIRS;\n}\n\n/** Per-process memo — the legacy session-DB relocation runs at most once. */\nlet legacySessionsDbMigrated = false;\n\n/** Test helper — clears the session-DB migration \"already did this\" memo. */\nexport function _resetSessionsDbMigrationMemoForTests(): void {\n legacySessionsDbMigrated = false;\n}\n\n/** SQLite sidecar suffixes that must travel with the main DB file. */\nconst SQLITE_SIDECAR_SUFFIXES = ['', '-wal', '-shm', '-journal'] as const;\n\n/**\n * Resolves the session-database path, performing a one-time relocation\n * of any pre-#2902 database on the first call per process.\n *\n * The session DB is per-repo episodic state and belongs in the\n * `sessions/` bucket alongside the session journals — vote #2876\n * categorized `sessions/` as per-repo, and issue #2902 (consensus\n * 3/3) extended that to the DB. Before #2902 the DB resolved via\n * `nexusDataPath('sessions.db')`; because `sessions.db` is not a\n * per-repo first segment, that landed cross-repo at\n * `~/.nexus-agents/sessions.db`, so a DB started in one repo leaked\n * into every other repo.\n *\n * If a legacy DB exists at the old location and none exists at the\n * new one, the legacy file (and any SQLite sidecars) is moved so\n * existing session history is preserved rather than silently\n * orphaned. The move is best-effort: a failure leaves the legacy DB\n * untouched for manual recovery and the caller gets a fresh DB at the\n * new path. `NEXUS_DATA_DIR` / `NEXUS_REPO_PREFERRED` / the\n * `NEXUS_SESSIONS_DB` override all sit upstream of this resolver.\n */\nexport function sessionsDbPath(): string {\n const target = nexusDataPath('sessions', 'sessions.db');\n if (!legacySessionsDbMigrated) {\n legacySessionsDbMigrated = true;\n migrateLegacySessionsDb(target);\n }\n return target;\n}\n\n/** One-time relocation of a pre-#2902 session DB. Best-effort — see `sessionsDbPath`. */\nfunction migrateLegacySessionsDb(target: string): void {\n const legacy = nexusDataPath('sessions.db'); // pre-#2902 resolution\n if (legacy === target || !existsSync(legacy) || existsSync(target)) return;\n try {\n mkdirSync(dirname(target), { recursive: true });\n for (const suffix of SQLITE_SIDECAR_SUFFIXES) {\n const from = `${legacy}${suffix}`;\n if (existsSync(from)) moveFile(from, `${target}${suffix}`);\n }\n } catch {\n // Best-effort — a migration failure must never break session storage.\n }\n}\n\n/** Moves a file, falling back to copy+unlink across a filesystem boundary. */\nfunction moveFile(from: string, to: string): void {\n try {\n renameSync(from, to);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EXDEV') throw err;\n copyFileSync(from, to);\n unlinkSync(from);\n }\n}\n","/**\n * Sandbox detection (#2501, child 1 of epic #2500).\n *\n * nexus-agents needs to know whether it's running inside a host-provided\n * sandbox (Docker Desktop Sandbox + OpenCode, Codex sandbox, locked-down\n * CI runner) so it can adjust behaviour:\n *\n * - default `NEXUS_DATA_DIR` to the multi-repo root rather than `~/...`\n * - skip CLI subprocess detection (binaries aren't there)\n * - fail-fast when the gateway is unreachable instead of degrading\n * - suppress diagnostics that don't apply\n *\n * The signal is **explicit**: the image author (Dockerfile, devcontainer,\n * harness wrapper) sets `NEXUS_SANDBOX=<flavor>`. The flavor string is\n * for diagnostics + per-flavor branching (`docker-opencode`, `codex`,\n * `claude-code`, `ci-restricted`, …); presence is the on/off signal.\n *\n * A heuristic check runs alongside for verification — if `NEXUS_SANDBOX`\n * claims `docker-opencode` but `/.dockerenv` is missing, that's a\n * misconfiguration worth surfacing to the operator.\n *\n * @module config/sandbox-detection\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\n\n/**\n * Heuristic detection result. Independent from the explicit\n * `NEXUS_SANDBOX` env var; produced by inspecting filesystem markers.\n */\nexport type SandboxHeuristic = 'docker' | 'podman' | 'unknown' | null;\n\nexport interface SandboxInfo {\n /**\n * True iff `NEXUS_SANDBOX` is set + non-empty. The explicit signal\n * the rest of the codebase keys off — never `true` by heuristic alone.\n */\n readonly active: boolean;\n /**\n * Operator-supplied flavor string, e.g. `docker-opencode`. Undefined\n * when `active === false` or the env var is empty.\n */\n readonly flavor: string | undefined;\n /**\n * Multi-repo root the user mounted. From `NEXUS_SANDBOX_ROOT`. Undefined\n * when unset; consumers that need a default substitute `/`.\n */\n readonly root: string | undefined;\n /**\n * Independent heuristic match — `null` when we couldn't run the check,\n * `'unknown'` when ran but no marker matched. Used by `doctor` to flag\n * mismatches between the explicit signal and the runtime environment.\n */\n readonly heuristicMatch: SandboxHeuristic;\n}\n\n/**\n * Detect whether nexus-agents is running inside a host-provided sandbox.\n * Pure read of env + filesystem; no caching (cheap enough to recompute,\n * and tests routinely mutate process.env).\n */\nexport function detectSandbox(): SandboxInfo {\n const flavorRaw = process.env['NEXUS_SANDBOX']?.trim();\n const flavor = flavorRaw !== undefined && flavorRaw !== '' ? flavorRaw : undefined;\n const active = flavor !== undefined;\n\n const rootRaw = process.env['NEXUS_SANDBOX_ROOT']?.trim();\n const root = rootRaw !== undefined && rootRaw !== '' ? rootRaw : undefined;\n\n return {\n active,\n flavor,\n root,\n heuristicMatch: detectContainerHeuristic(),\n };\n}\n\n/**\n * Look for filesystem markers indicating a container runtime. Used as a\n * cross-check against the explicit `NEXUS_SANDBOX` signal.\n *\n * Order of checks:\n * 1. `/.dockerenv` (Docker)\n * 2. `/run/.containerenv` (Podman)\n * 3. `/proc/1/cgroup` containing `docker` or `containerd` strings\n *\n * Returns `null` when none of the checks could run (non-Linux host with\n * no `/proc`, sandbox blocks `existsSync`, etc.) — distinct from\n * `'unknown'` (checks ran, no marker matched) so the doctor message can\n * differentiate \"we couldn't tell\" from \"we checked, no container\".\n */\nfunction detectContainerHeuristic(): SandboxHeuristic {\n try {\n if (existsSync('/.dockerenv')) return 'docker';\n if (existsSync('/run/.containerenv')) return 'podman';\n if (existsSync('/proc/1/cgroup')) {\n const cgroup = readFileSync('/proc/1/cgroup', 'utf8');\n if (/\\bdocker\\b/.test(cgroup)) return 'docker';\n if (/\\bcontainerd\\b/.test(cgroup)) return 'docker';\n }\n return 'unknown';\n } catch {\n return null;\n }\n}\n","/**\n * Repo-root detection — walks upward from a starting directory looking for\n * `.git` so callers can scope state to the current git repo. Built for\n * epic #2872 (issue #2882) to support the per-repo `.nexus-agents/` data\n * directory ratified by vote #2876.\n *\n * Defenses adopted:\n * - Walks upward but stops at filesystem root (no infinite loop on\n * symlinks-to-self).\n * - Stops at filesystem boundary (different `stat.dev`) — refuses to\n * escape across mount points. Prevents a sandboxed workdir from\n * resolving a `.git` on the host filesystem.\n * - Detects git worktrees: `.git` may be a *file* containing\n * `gitdir: <path>` rather than a directory.\n * - Realpath's the final root and rejects results that escape the\n * starting cwd by symlink.\n *\n * Deferred (tracked separately; not blocking #2882):\n * - CVE-2022-24765-style ownership check (refuse `.git` owned by a\n * different uid than the running process). The git CLI added\n * `safe.directory` for this; we don't have a comparable allowlist\n * surface yet. In CI the heuristic is too noisy to be useful\n * (runners often clone as a different uid than the workload).\n * File-system isolation (the `stat.dev` check above) covers the\n * bulk of the attack class.\n *\n * @module config/repo-root-detection\n */\n\nimport { existsSync, readFileSync, realpathSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\n\n/**\n * Walks upward from `start` looking for `.git` (file or directory).\n * Returns the absolute path to the directory containing it, or `null`.\n *\n * Worktrees: a `.git` file (not dir) with contents `gitdir: <path>` is\n * still recognised as marking the repo root. The pointed-to gitdir is\n * NOT followed — we just need the worktree's own root.\n *\n * Filesystem boundary: stops walking if the next ancestor lives on a\n * different filesystem (different `stat.dev`). This prevents a workdir\n * mounted inside a sandbox from finding a host-side `.git`.\n */\nexport function findRepoRoot(start: string): string | null {\n if (!isAbsolute(start)) {\n start = resolve(start);\n }\n\n let current: string;\n try {\n current = realpathSync(start);\n } catch {\n return null;\n }\n\n let startDev: number | undefined;\n try {\n startDev = statSync(current).dev;\n } catch {\n return null;\n }\n\n // Walk up. Depth cap is paranoid but bounds the loop on pathological\n // symlinks even though realpathSync above should already prevent cycles.\n for (let i = 0; i < 64; i++) {\n if (isRepoRoot(current)) {\n return current;\n }\n const parent = dirname(current);\n if (parent === current) {\n // Hit filesystem root.\n return null;\n }\n try {\n if (statSync(parent).dev !== startDev) {\n // Crossed a mount point; refuse to escape.\n return null;\n }\n } catch {\n return null;\n }\n current = parent;\n }\n return null;\n}\n\n/** True iff `dir/.git` exists as a directory or a git-worktree marker file. */\nexport function isRepoRoot(dir: string): boolean {\n const gitPath = `${dir}/.git`;\n if (!existsSync(gitPath)) return false;\n try {\n const st = statSync(gitPath);\n if (st.isDirectory()) return true;\n if (st.isFile()) {\n // Worktree: first line should be `gitdir: <path>`.\n const head = readFileSync(gitPath, 'utf-8').slice(0, 256);\n return head.startsWith('gitdir:');\n }\n } catch {\n return false;\n }\n return false;\n}\n","/**\n * portable-mode — auto-detect sandboxed execution environments and\n * redirect nexus-agents data to a workspace-local directory.\n *\n * The existing `getNexusDataDir()` already respects `NEXUS_DATA_DIR` and\n * `NEXUS_PORTABLE_MODE`. This module wires up the *auto-detection* path\n * so operators running inside a Docker / restricted-FS / sandboxed\n * environment don't have to set the env vars manually — nexus-agents\n * notices and announces the flip.\n *\n * Source: Issue #2471 (epic #2467 child).\n *\n * Detection rules (first match wins):\n * 1. `NEXUS_DATA_DIR` already set → respect, no auto-detect\n * 2. `NEXUS_PORTABLE_MODE=0` → operator opted out, no auto-detect\n * 3. `NEXUS_PORTABLE_MODE=1` → portable mode, no detection needed\n * 4. Heuristic: home directory not writable\n * 5. Heuristic: container env vars set (KUBERNETES_SERVICE_HOST,\n * DOCKER_CONTAINER, ECS_CONTAINER_METADATA_URI, SANDBOX, etc.)\n *\n * When portable mode fires:\n * - Sets `process.env.NEXUS_DATA_DIR` to `<cwd>/.nexus-agents`\n * - Announces once on stderr (subsequent calls are silent)\n * - If cwd is a git repo, appends `.nexus-agents/` to .gitignore\n *\n * To force off: `NEXUS_PORTABLE_MODE=0`. To force on without heuristics:\n * `NEXUS_PORTABLE_MODE=1`. To override target dir: `NEXUS_DATA_DIR=...`.\n */\n\nimport { accessSync, constants, existsSync, readFileSync, appendFileSync, statSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\n/** Container / sandbox environment variables that strongly imply portable mode. */\nconst SANDBOX_ENV_VARS: readonly string[] = [\n 'KUBERNETES_SERVICE_HOST',\n 'DOCKER_CONTAINER',\n 'ECS_CONTAINER_METADATA_URI',\n 'ECS_CONTAINER_METADATA_URI_V4',\n 'SANDBOX',\n 'NEXUS_SANDBOX',\n];\n\nlet DETECTED = false;\n\ninterface DetectionResult {\n readonly portable: boolean;\n readonly dataDir: string;\n readonly reason:\n 'env-data-dir' | 'env-opt-out' | 'env-opt-in' | 'home-unwritable' | 'container-env' | 'default';\n}\n\nfunction isHomeWritable(): boolean {\n try {\n const home = homedir();\n if (!existsSync(home)) return false;\n accessSync(home, constants.W_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction inSandboxEnv(): boolean {\n for (const v of SANDBOX_ENV_VARS) {\n const val = process.env[v];\n if (val !== undefined && val !== '') return true;\n }\n return false;\n}\n\n/**\n * The operator-declared sandbox root, when set (#5026).\n *\n * Read directly rather than through `detectSandbox()` to keep this module free\n * of imports — it runs as a side effect of `cli-log-bootstrap` before anything\n * else loads.\n */\nfunction sandboxRootFromEnv(): string | undefined {\n const raw = process.env['NEXUS_SANDBOX_ROOT']?.trim();\n return raw !== undefined && raw !== '' ? resolve(raw) : undefined;\n}\n\nfunction checkExplicitEnv(cwd: string): DetectionResult | null {\n const fromEnv = process.env['NEXUS_DATA_DIR']?.trim();\n if (fromEnv !== undefined && fromEnv !== '') {\n return { portable: false, dataDir: resolve(fromEnv), reason: 'env-data-dir' };\n }\n const portableEnv = process.env['NEXUS_PORTABLE_MODE'];\n if (portableEnv === '0' || portableEnv === 'false') {\n return { portable: false, dataDir: join(homedir(), '.nexus-agents'), reason: 'env-opt-out' };\n }\n if (portableEnv === '1' || portableEnv === 'true') {\n return { portable: true, dataDir: join(cwd, '.nexus-agents'), reason: 'env-opt-in' };\n }\n return null;\n}\n\nfunction checkHeuristics(cwd: string): DetectionResult | null {\n if (!isHomeWritable()) {\n return { portable: true, dataDir: join(cwd, '.nexus-agents'), reason: 'home-unwritable' };\n }\n if (inSandboxEnv()) {\n // #5026: prefer an explicitly declared sandbox root over cwd. `NEXUS_SANDBOX`\n // is one of SANDBOX_ENV_VARS, so setting it makes this heuristic fire and\n // stamp `NEXUS_DATA_DIR = <cwd>/.nexus-agents` — which then short-circuits\n // `getNexusDataDir`'s own sandbox branch (`nexus-data-dir.ts:124-127`)\n // before it can honour `NEXUS_SANDBOX_ROOT`. The documented purpose of that\n // variable (\"default NEXUS_DATA_DIR to the multi-repo root\") therefore never\n // happened, and state fragmented per working directory across a multi-repo\n // mount. `doctor`'s dataDirInsideRepo check exists to detect exactly that\n // layout and reports it as operator misconfiguration.\n const declaredRoot = sandboxRootFromEnv();\n return {\n portable: true,\n dataDir: join(declaredRoot ?? cwd, '.nexus-agents'),\n reason: 'container-env',\n };\n }\n return null;\n}\n\n/**\n * Decide whether to flip nexus-agents to portable mode and what data dir\n * to use. Pure function; no side effects beyond reading env + filesystem.\n */\nexport function detectPortableMode(cwd: string = process.cwd()): DetectionResult {\n return (\n checkExplicitEnv(cwd) ??\n checkHeuristics(cwd) ?? {\n portable: false,\n dataDir: join(homedir(), '.nexus-agents'),\n reason: 'default',\n }\n );\n}\n\n/**\n * Apply detected portable mode at process startup. Idempotent (subsequent\n * calls are no-ops). Announces on stderr once when the auto-detection\n * heuristic triggers — env-opt-in/out doesn't announce because the\n * operator already knows.\n */\nexport function applyPortableMode(cwd: string = process.cwd()): void {\n if (DETECTED) return;\n DETECTED = true;\n\n const result = detectPortableMode(cwd);\n\n // No env, no heuristic match — nothing to do.\n if (!result.portable) return;\n\n // The heuristic-driven cases announce; explicit opt-in is silent.\n if (result.reason === 'home-unwritable' || result.reason === 'container-env') {\n process.stderr.write(\n `[portable-mode] Sandbox detected (${result.reason}). Using ${result.dataDir} for all nexus-agents data.\\n` +\n ` Set NEXUS_PORTABLE_MODE=0 to override; see docs/guides/SANDBOXED-USAGE.md\\n`\n );\n }\n\n process.env['NEXUS_DATA_DIR'] = result.dataDir;\n\n if (isInsideGitRepo(cwd)) {\n ensureGitignored(cwd, '.nexus-agents/');\n }\n}\n\nfunction isInsideGitRepo(cwd: string): boolean {\n try {\n const gitDir = join(cwd, '.git');\n return existsSync(gitDir) && statSync(gitDir).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Append `entry` to `<cwd>/.gitignore` if not already present. Stderr\n * announce on the first append. Exported because the repo-preferred\n * resolver in `nexus-data-dir.ts` reuses the same auto-gitignore behavior\n * when `<repo>/.nexus-agents/` becomes the active data dir (epic #2872).\n */\nexport function ensureGitignored(cwd: string, entry: string): void {\n const path = join(cwd, '.gitignore');\n try {\n const existing = existsSync(path) ? readFileSync(path, 'utf-8') : '';\n const lines = existing.split('\\n').map((l) => l.trim());\n if (lines.includes(entry) || lines.includes(entry.replace(/\\/$/, ''))) return;\n const sep = existing.length > 0 && !existing.endsWith('\\n') ? '\\n' : '';\n appendFileSync(path, `${sep}${entry}\\n`, 'utf-8');\n process.stderr.write(\n `[portable-mode] Added '${entry}' to ${path} so nexus-agents data is gitignored.\\n`\n );\n } catch (e: unknown) {\n // Non-fatal — operator can add the line themselves.\n const msg = e instanceof Error ? e.message : String(e);\n process.stderr.write(\n `[portable-mode] Could not auto-update ${path} (${msg}). Add '${entry}' manually if you don't want nexus-agents data tracked by git.\\n`\n );\n }\n}\n\n/** Test-only reset of the once-only state. */\nexport function _resetDetectedForTests(): void {\n DETECTED = false;\n}\n"],"mappings":"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","names":["accessSync","existsSync","realpathSync","statSync","homedir","dirname","isAbsolute","join","resolve","existsSync","readFileSync","existsSync","readFileSync","statSync","resolve","resolve","join","homedir","realpathSync","resolve","isAbsolute","statSync","join","existsSync","accessSync","join","dirname","existsSync","dirname"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getTimeProvider
3
- } from "./chunk-RZF4GUMI.js";
3
+ } from "./chunk-SMYK36R3.js";
4
4
 
5
5
  // src/security/audit-trail.ts
6
6
  var MAX_EVENTS = 1e4;
@@ -214,4 +214,4 @@ export {
214
214
  createGraphAuditBridge,
215
215
  createAuditTrail
216
216
  };
217
- //# sourceMappingURL=chunk-QN5ME2N2.js.map
217
+ //# sourceMappingURL=chunk-NAC62SMO.js.map
@@ -2,7 +2,7 @@ import {
2
2
  createLogger,
3
3
  err,
4
4
  ok
5
- } from "./chunk-RZF4GUMI.js";
5
+ } from "./chunk-SMYK36R3.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-JH4L3SH4.js.map
90
+ //# sourceMappingURL=chunk-NX4QAUSU.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  GitHubProvider,
3
3
  ScmError
4
- } from "./chunk-5OHQT3IJ.js";
4
+ } from "./chunk-5NQPBDRX.js";
5
5
  import {
6
6
  ROLE_DEFAULT_TRUST,
7
7
  ReputationCache,
@@ -12,7 +12,7 @@ import {
12
12
  resolveEnvMode,
13
13
  resolveReputationGatingMode,
14
14
  sanitizeInput
15
- } from "./chunk-TIUE5KC4.js";
15
+ } from "./chunk-YOCOC4DG.js";
16
16
  import {
17
17
  MAX_STRIPPED_ELEMENTS_PER_EVENT,
18
18
  createAuditTrail,
@@ -20,10 +20,10 @@ import {
20
20
  emitReputationEvent,
21
21
  emitSanitizationEvent,
22
22
  emitTrustEvent
23
- } from "./chunk-QN5ME2N2.js";
23
+ } from "./chunk-NAC62SMO.js";
24
24
  import {
25
25
  hasToken
26
- } from "./chunk-JH4L3SH4.js";
26
+ } from "./chunk-NX4QAUSU.js";
27
27
  import {
28
28
  CLI_SUBPROCESS_TIMEOUTS,
29
29
  createLogger,
@@ -31,7 +31,7 @@ import {
31
31
  getErrorMessage,
32
32
  getTimeProvider,
33
33
  ok
34
- } from "./chunk-RZF4GUMI.js";
34
+ } from "./chunk-SMYK36R3.js";
35
35
 
36
36
  // src/security/firewall/firewall-policy-mode.ts
37
37
  import { z } from "zod";
@@ -2162,4 +2162,4 @@ export {
2162
2162
  IssueTriage,
2163
2163
  createIssueTriage
2164
2164
  };
2165
- //# sourceMappingURL=chunk-BBH3SKC3.js.map
2165
+ //# sourceMappingURL=chunk-O335AIP4.js.map
@@ -10,13 +10,13 @@ import {
10
10
  import {
11
11
  assessReputation,
12
12
  sanitizeInput
13
- } from "./chunk-TIUE5KC4.js";
13
+ } from "./chunk-YOCOC4DG.js";
14
14
  import {
15
15
  createLogger,
16
16
  err,
17
17
  getTimeProvider,
18
18
  ok
19
- } from "./chunk-RZF4GUMI.js";
19
+ } from "./chunk-SMYK36R3.js";
20
20
 
21
21
  // src/dogfooding/pr-reviewer-helpers.ts
22
22
  import { randomUUID } from "node:crypto";
@@ -416,4 +416,4 @@ export {
416
416
  createFailedReview,
417
417
  reviewPostingBlock
418
418
  };
419
- //# sourceMappingURL=chunk-ZYJT5CMY.js.map
419
+ //# sourceMappingURL=chunk-PUKFCRHE.js.map