nexus-agents 8.18.0 → 8.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/{ast-rule-runner-AJAWZQNS.js → ast-rule-runner-27XDHRZH.js} +3 -3
  2. package/dist/{child-mcp-config-JQCVNB3Y.js → child-mcp-config-ONSFGNNH.js} +2 -2
  3. package/dist/{chunk-V2XWRKIJ.js → chunk-2WAF3ZFK.js} +8 -8
  4. package/dist/{chunk-A62DB47B.js → chunk-3P5H74AV.js} +8 -8
  5. package/dist/{chunk-JYMFL4M6.js → chunk-3YC6CEI5.js} +2 -2
  6. package/dist/{chunk-LMJ7BKIL.js → chunk-4XNZKWKQ.js} +2 -2
  7. package/dist/{chunk-5OTOOVOF.js → chunk-4YMUPCRS.js} +5 -5
  8. package/dist/{chunk-EPVPVG25.js → chunk-5LAPFTNG.js} +36 -36
  9. package/dist/{chunk-N3TMUOHG.js → chunk-6B7E372N.js} +3 -3
  10. package/dist/{chunk-6T3EPABN.js → chunk-7LP6VJRP.js} +6 -1
  11. package/dist/{chunk-6T3EPABN.js.map → chunk-7LP6VJRP.js.map} +1 -1
  12. package/dist/{chunk-2LQAHGNZ.js → chunk-C7CSLODO.js} +7 -7
  13. package/dist/{chunk-KQRF4ZHX.js → chunk-CFAN2FPY.js} +2 -2
  14. package/dist/{chunk-KUKQ7UHD.js → chunk-DLWCNFEX.js} +4 -4
  15. package/dist/{chunk-ETMIOP3R.js → chunk-GNB4GPLQ.js} +2 -2
  16. package/dist/{chunk-KJFX7JUP.js → chunk-HN7EDIAH.js} +6 -6
  17. package/dist/{chunk-R3QNEXOU.js → chunk-ICKUT5LH.js} +2 -2
  18. package/dist/{chunk-GWQE5MBQ.js → chunk-K7QRRVKW.js} +2 -2
  19. package/dist/{chunk-KUR6TV4G.js → chunk-KJN5RWXY.js} +68 -7
  20. package/dist/chunk-KJN5RWXY.js.map +1 -0
  21. package/dist/{chunk-CQK5SIEX.js → chunk-KY3U2XEW.js} +3 -3
  22. package/dist/{chunk-XVAXLGKZ.js → chunk-LB7DDJOG.js} +325 -125
  23. package/dist/chunk-LB7DDJOG.js.map +1 -0
  24. package/dist/{chunk-NBXYA5O6.js → chunk-LZ6WZJRH.js} +3 -3
  25. package/dist/{chunk-6ZU3FUAX.js → chunk-LZU4O6RT.js} +2 -2
  26. package/dist/{chunk-46V3G76B.js → chunk-P7FSB7X2.js} +4 -4
  27. package/dist/{chunk-PBVNGI67.js → chunk-Q2M77IPR.js} +2 -2
  28. package/dist/{chunk-D7WQNTAK.js → chunk-Q76C5PG7.js} +2 -2
  29. package/dist/{chunk-JEOQY42Z.js → chunk-QFI5WT2Y.js} +5 -5
  30. package/dist/{chunk-IJH2U2QL.js → chunk-RIIWLQYM.js} +2 -2
  31. package/dist/{chunk-QBU2RG7U.js → chunk-SLLW6DVZ.js} +2 -2
  32. package/dist/{chunk-I4EHDJTI.js → chunk-TCTKOFNL.js} +2 -2
  33. package/dist/{chunk-ZB7XPHFZ.js → chunk-UCIRVMOZ.js} +2 -2
  34. package/dist/{chunk-4U555SVX.js → chunk-UNDZPTSD.js} +16 -8
  35. package/dist/chunk-UNDZPTSD.js.map +1 -0
  36. package/dist/{chunk-DBGIP6GK.js → chunk-VLNPDWIW.js} +2 -2
  37. package/dist/{chunk-ZXLF3NDV.js → chunk-WGYETY6P.js} +2 -2
  38. package/dist/chunk-XFDT265H.js +7 -0
  39. package/dist/{chunk-R7V4C5UL.js → chunk-ZECI6UI2.js} +2 -2
  40. package/dist/{chunk-JXHRZRKU.js → chunk-ZTB4Z23O.js} +4 -4
  41. package/dist/{chunk-2T2MSN7B.js → chunk-ZUK5BG3Q.js} +2 -2
  42. package/dist/{cli-circuit-breaker-2LQZLFVP.js → cli-circuit-breaker-FOPLEQK6.js} +3 -3
  43. package/dist/cli.d.ts +1 -1
  44. package/dist/cli.js +90 -104
  45. package/dist/cli.js.map +1 -1
  46. package/dist/{composite-router-XNVULYDV.js → composite-router-OSASGOMV.js} +2 -2
  47. package/dist/{consensus-vote-2WLWZOVR.js → consensus-vote-QS72DIWI.js} +18 -18
  48. package/dist/{consensus-vote-types-Br1h5IMv.d.ts → consensus-vote-types-BlEp-vlK.d.ts} +5 -0
  49. package/dist/{context-retriever-GWAJG6XT.js → context-retriever-7VPUIRVT.js} +9 -9
  50. package/dist/{doctor-deep-ZATGXGNC.js → doctor-deep-ZBNAR3QG.js} +3 -3
  51. package/dist/{doctor-live-L264NFJO.js → doctor-live-VIHVWQGF.js} +9 -9
  52. package/dist/{expert-bridge-KCQ457YZ.js → expert-bridge-ESJHWQ2Z.js} +4 -4
  53. package/dist/{factory-S2SVFA6W.js → factory-HFHYJ4P6.js} +9 -9
  54. package/dist/{factory-FFKHIV6Q.js → factory-HUUB4OWA.js} +5 -5
  55. package/dist/{improvement-review-ASVQR6VY.js → improvement-review-JRUO6SOJ.js} +6 -6
  56. package/dist/index.d.ts +34 -14
  57. package/dist/index.js +33 -33
  58. package/dist/{init-opencode-CDW4DAWF.js → init-opencode-VZKXSO72.js} +6 -6
  59. package/dist/issue-triage-77QQQXYR.js +17 -0
  60. package/dist/{pr-reviewer-helpers-PMRGV7IL.js → pr-reviewer-helpers-BINKSJSV.js} +8 -4
  61. package/dist/{registry-command-4Y7RJH47.js → registry-command-GCO7IPDP.js} +2 -2
  62. package/dist/{repo-security-plan-XZ6YBLUE.js → repo-security-plan-QTGNCDI7.js} +3 -3
  63. package/dist/{research-helpers-synthesize-OKCOMCE2.js → research-helpers-synthesize-KYDHWP7C.js} +4 -4
  64. package/dist/{routing-memory-QUA5ORUA.js → routing-memory-VMCHRNSE.js} +2 -2
  65. package/dist/{session-memory-XKHKWRP3.js → session-memory-MX2G4K2A.js} +3 -3
  66. package/dist/{setup-config-NMVR2OBN.js → setup-config-QKYFUR3C.js} +3 -3
  67. package/dist/{setup-custom-api-VV3FT66F.js → setup-custom-api-5CDXK3RY.js} +4 -4
  68. package/dist/setup-data-dir-4AUIRLO4.js +29 -0
  69. package/dist/{tool-memory-MCIIYDQR.js → tool-memory-WUZ66O4K.js} +6 -6
  70. package/dist/{unified-registry-LPSJ2KMV.js → unified-registry-EZ3QUCIO.js} +10 -10
  71. package/dist/{weather-report-KHFJ756C.js → weather-report-MUUYKM7C.js} +2 -2
  72. package/package.json +1 -1
  73. package/dist/chunk-4U555SVX.js.map +0 -1
  74. package/dist/chunk-KUR6TV4G.js.map +0 -1
  75. package/dist/chunk-WIG2XETC.js +0 -7
  76. package/dist/chunk-XVAXLGKZ.js.map +0 -1
  77. package/dist/issue-triage-4RX3UV2B.js +0 -17
  78. package/dist/setup-data-dir-OYYLDXTP.js +0 -29
  79. /package/dist/{ast-rule-runner-AJAWZQNS.js.map → ast-rule-runner-27XDHRZH.js.map} +0 -0
  80. /package/dist/{child-mcp-config-JQCVNB3Y.js.map → child-mcp-config-ONSFGNNH.js.map} +0 -0
  81. /package/dist/{chunk-V2XWRKIJ.js.map → chunk-2WAF3ZFK.js.map} +0 -0
  82. /package/dist/{chunk-A62DB47B.js.map → chunk-3P5H74AV.js.map} +0 -0
  83. /package/dist/{chunk-JYMFL4M6.js.map → chunk-3YC6CEI5.js.map} +0 -0
  84. /package/dist/{chunk-LMJ7BKIL.js.map → chunk-4XNZKWKQ.js.map} +0 -0
  85. /package/dist/{chunk-5OTOOVOF.js.map → chunk-4YMUPCRS.js.map} +0 -0
  86. /package/dist/{chunk-EPVPVG25.js.map → chunk-5LAPFTNG.js.map} +0 -0
  87. /package/dist/{chunk-N3TMUOHG.js.map → chunk-6B7E372N.js.map} +0 -0
  88. /package/dist/{chunk-2LQAHGNZ.js.map → chunk-C7CSLODO.js.map} +0 -0
  89. /package/dist/{chunk-KQRF4ZHX.js.map → chunk-CFAN2FPY.js.map} +0 -0
  90. /package/dist/{chunk-KUKQ7UHD.js.map → chunk-DLWCNFEX.js.map} +0 -0
  91. /package/dist/{chunk-ETMIOP3R.js.map → chunk-GNB4GPLQ.js.map} +0 -0
  92. /package/dist/{chunk-KJFX7JUP.js.map → chunk-HN7EDIAH.js.map} +0 -0
  93. /package/dist/{chunk-R3QNEXOU.js.map → chunk-ICKUT5LH.js.map} +0 -0
  94. /package/dist/{chunk-GWQE5MBQ.js.map → chunk-K7QRRVKW.js.map} +0 -0
  95. /package/dist/{chunk-CQK5SIEX.js.map → chunk-KY3U2XEW.js.map} +0 -0
  96. /package/dist/{chunk-NBXYA5O6.js.map → chunk-LZ6WZJRH.js.map} +0 -0
  97. /package/dist/{chunk-6ZU3FUAX.js.map → chunk-LZU4O6RT.js.map} +0 -0
  98. /package/dist/{chunk-46V3G76B.js.map → chunk-P7FSB7X2.js.map} +0 -0
  99. /package/dist/{chunk-PBVNGI67.js.map → chunk-Q2M77IPR.js.map} +0 -0
  100. /package/dist/{chunk-D7WQNTAK.js.map → chunk-Q76C5PG7.js.map} +0 -0
  101. /package/dist/{chunk-JEOQY42Z.js.map → chunk-QFI5WT2Y.js.map} +0 -0
  102. /package/dist/{chunk-IJH2U2QL.js.map → chunk-RIIWLQYM.js.map} +0 -0
  103. /package/dist/{chunk-QBU2RG7U.js.map → chunk-SLLW6DVZ.js.map} +0 -0
  104. /package/dist/{chunk-I4EHDJTI.js.map → chunk-TCTKOFNL.js.map} +0 -0
  105. /package/dist/{chunk-ZB7XPHFZ.js.map → chunk-UCIRVMOZ.js.map} +0 -0
  106. /package/dist/{chunk-DBGIP6GK.js.map → chunk-VLNPDWIW.js.map} +0 -0
  107. /package/dist/{chunk-ZXLF3NDV.js.map → chunk-WGYETY6P.js.map} +0 -0
  108. /package/dist/{chunk-WIG2XETC.js.map → chunk-XFDT265H.js.map} +0 -0
  109. /package/dist/{chunk-R7V4C5UL.js.map → chunk-ZECI6UI2.js.map} +0 -0
  110. /package/dist/{chunk-JXHRZRKU.js.map → chunk-ZTB4Z23O.js.map} +0 -0
  111. /package/dist/{chunk-2T2MSN7B.js.map → chunk-ZUK5BG3Q.js.map} +0 -0
  112. /package/dist/{cli-circuit-breaker-2LQZLFVP.js.map → cli-circuit-breaker-FOPLEQK6.js.map} +0 -0
  113. /package/dist/{composite-router-XNVULYDV.js.map → composite-router-OSASGOMV.js.map} +0 -0
  114. /package/dist/{consensus-vote-2WLWZOVR.js.map → consensus-vote-QS72DIWI.js.map} +0 -0
  115. /package/dist/{context-retriever-GWAJG6XT.js.map → context-retriever-7VPUIRVT.js.map} +0 -0
  116. /package/dist/{doctor-deep-ZATGXGNC.js.map → doctor-deep-ZBNAR3QG.js.map} +0 -0
  117. /package/dist/{doctor-live-L264NFJO.js.map → doctor-live-VIHVWQGF.js.map} +0 -0
  118. /package/dist/{expert-bridge-KCQ457YZ.js.map → expert-bridge-ESJHWQ2Z.js.map} +0 -0
  119. /package/dist/{factory-FFKHIV6Q.js.map → factory-HFHYJ4P6.js.map} +0 -0
  120. /package/dist/{factory-S2SVFA6W.js.map → factory-HUUB4OWA.js.map} +0 -0
  121. /package/dist/{improvement-review-ASVQR6VY.js.map → improvement-review-JRUO6SOJ.js.map} +0 -0
  122. /package/dist/{init-opencode-CDW4DAWF.js.map → init-opencode-VZKXSO72.js.map} +0 -0
  123. /package/dist/{issue-triage-4RX3UV2B.js.map → issue-triage-77QQQXYR.js.map} +0 -0
  124. /package/dist/{pr-reviewer-helpers-PMRGV7IL.js.map → pr-reviewer-helpers-BINKSJSV.js.map} +0 -0
  125. /package/dist/{registry-command-4Y7RJH47.js.map → registry-command-GCO7IPDP.js.map} +0 -0
  126. /package/dist/{repo-security-plan-XZ6YBLUE.js.map → repo-security-plan-QTGNCDI7.js.map} +0 -0
  127. /package/dist/{research-helpers-synthesize-OKCOMCE2.js.map → research-helpers-synthesize-KYDHWP7C.js.map} +0 -0
  128. /package/dist/{routing-memory-QUA5ORUA.js.map → routing-memory-VMCHRNSE.js.map} +0 -0
  129. /package/dist/{session-memory-XKHKWRP3.js.map → session-memory-MX2G4K2A.js.map} +0 -0
  130. /package/dist/{setup-config-NMVR2OBN.js.map → setup-config-QKYFUR3C.js.map} +0 -0
  131. /package/dist/{setup-custom-api-VV3FT66F.js.map → setup-custom-api-5CDXK3RY.js.map} +0 -0
  132. /package/dist/{setup-data-dir-OYYLDXTP.js.map → setup-data-dir-4AUIRLO4.js.map} +0 -0
  133. /package/dist/{tool-memory-MCIIYDQR.js.map → tool-memory-WUZ66O4K.js.map} +0 -0
  134. /package/dist/{unified-registry-LPSJ2KMV.js.map → unified-registry-EZ3QUCIO.js.map} +0 -0
  135. /package/dist/{weather-report-KHFJ756C.js.map → weather-report-MUUYKM7C.js.map} +0 -0
@@ -9,8 +9,8 @@ import {
9
9
  getBuiltInAstRulesPath,
10
10
  loadRules,
11
11
  runAstQaRules
12
- } from "./chunk-ZXLF3NDV.js";
13
- import "./chunk-NBXYA5O6.js";
12
+ } from "./chunk-WGYETY6P.js";
13
+ import "./chunk-LZ6WZJRH.js";
14
14
  import "./chunk-7WJGV5DN.js";
15
15
  import "./chunk-J7QCZRVK.js";
16
16
  import "./chunk-ZPWHCABL.js";
@@ -26,4 +26,4 @@ export {
26
26
  loadRules,
27
27
  runAstQaRules
28
28
  };
29
- //# sourceMappingURL=ast-rule-runner-AJAWZQNS.js.map
29
+ //# sourceMappingURL=ast-rule-runner-27XDHRZH.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-DKHBIJO4.js";
4
4
  import {
5
5
  createLogger
6
- } from "./chunk-NBXYA5O6.js";
6
+ } from "./chunk-LZ6WZJRH.js";
7
7
  import "./chunk-7WJGV5DN.js";
8
8
  import "./chunk-J7QCZRVK.js";
9
9
  import "./chunk-ZPWHCABL.js";
@@ -62,4 +62,4 @@ export {
62
62
  generateMcpConfig,
63
63
  getDefaultAllowedTools
64
64
  };
65
- //# sourceMappingURL=child-mcp-config-JQCVNB3Y.js.map
65
+ //# sourceMappingURL=child-mcp-config-ONSFGNNH.js.map
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  readOpenAICompatEnv
3
- } from "./chunk-JEOQY42Z.js";
3
+ } from "./chunk-QFI5WT2Y.js";
4
4
  import {
5
5
  allOf
6
6
  } from "./chunk-OQB3XC5O.js";
7
7
  import {
8
8
  VERSION
9
- } from "./chunk-WIG2XETC.js";
9
+ } from "./chunk-XFDT265H.js";
10
10
  import {
11
11
  capitalize
12
- } from "./chunk-6T3EPABN.js";
12
+ } from "./chunk-7LP6VJRP.js";
13
13
  import {
14
14
  createAllAdapters,
15
15
  probeCli
16
- } from "./chunk-A62DB47B.js";
16
+ } from "./chunk-3P5H74AV.js";
17
17
  import {
18
18
  getNexusTmpDir
19
19
  } from "./chunk-DKHBIJO4.js";
@@ -28,7 +28,7 @@ import {
28
28
  ok,
29
29
  symbols,
30
30
  writeLine
31
- } from "./chunk-NBXYA5O6.js";
31
+ } from "./chunk-LZ6WZJRH.js";
32
32
  import {
33
33
  getLearningDir,
34
34
  getOutcomesFile,
@@ -1220,13 +1220,13 @@ async function runDoctorFix(result) {
1220
1220
  writeLine2("\u2500".repeat(40));
1221
1221
  let fixCount = 0;
1222
1222
  if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
1223
- const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-OYYLDXTP.js");
1223
+ const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-4AUIRLO4.js");
1224
1224
  const outcome = describeDataDirFix2(initDataDirectories2());
1225
1225
  writeLine2(outcome.line);
1226
1226
  if (outcome.counted) fixCount++;
1227
1227
  }
1228
1228
  if (!result.configFile.found) {
1229
- const { runConfigInitSync } = await import("./setup-config-NMVR2OBN.js");
1229
+ const { runConfigInitSync } = await import("./setup-config-QKYFUR3C.js");
1230
1230
  const configResult = runConfigInitSync(process.cwd(), false, false);
1231
1231
  if (configResult.success && configResult.created) {
1232
1232
  writeLine2(`\u2713 Generated config: ${configResult.path}`);
@@ -1322,4 +1322,4 @@ export {
1322
1322
  startStdioServer,
1323
1323
  closeServer
1324
1324
  };
1325
- //# sourceMappingURL=chunk-V2XWRKIJ.js.map
1325
+ //# sourceMappingURL=chunk-2WAF3ZFK.js.map
@@ -5,34 +5,34 @@ import {
5
5
  planOptionalParams,
6
6
  requireApiKey,
7
7
  validateApiKeyPresence
8
- } from "./chunk-R7V4C5UL.js";
8
+ } from "./chunk-ZECI6UI2.js";
9
9
  import {
10
10
  CUSTOM_API_DEFAULT_MODEL
11
- } from "./chunk-R3QNEXOU.js";
11
+ } from "./chunk-ICKUT5LH.js";
12
12
  import {
13
13
  CUSTOM_API_BASE_URL_ENV,
14
14
  PROVIDER_ENV_KEYS,
15
15
  assertCustomApiHostResolvesPublic,
16
16
  validateCustomApiBaseUrl
17
- } from "./chunk-PBVNGI67.js";
17
+ } from "./chunk-Q2M77IPR.js";
18
18
  import {
19
19
  nexusMkdtempSync
20
20
  } from "./chunk-DKHBIJO4.js";
21
21
  import {
22
22
  getAvailabilityCache
23
- } from "./chunk-IJH2U2QL.js";
23
+ } from "./chunk-RIIWLQYM.js";
24
24
  import {
25
25
  extractSystemPrompt
26
26
  } from "./chunk-QZUG667L.js";
27
27
  import {
28
28
  generateHyphenId
29
- } from "./chunk-KQRF4ZHX.js";
29
+ } from "./chunk-CFAN2FPY.js";
30
30
  import {
31
31
  CliCircuitBreaker,
32
32
  DEFAULT_CIRCUIT_BREAKER_CONFIG,
33
33
  getCliCircuitBreakerSnapshot,
34
34
  getDefaultCliCircuitBreakerRegistry
35
- } from "./chunk-6ZU3FUAX.js";
35
+ } from "./chunk-LZU4O6RT.js";
36
36
  import {
37
37
  CLI_SUBPROCESS_TIMEOUTS,
38
38
  CLI_TIMEOUTS,
@@ -72,7 +72,7 @@ import {
72
72
  resolveCliAlias,
73
73
  resolveRetryAfterMs,
74
74
  retryAfterMsFromContext
75
- } from "./chunk-NBXYA5O6.js";
75
+ } from "./chunk-LZ6WZJRH.js";
76
76
 
77
77
  // src/cli-adapters/cli-to-model-adapter.ts
78
78
  var CliToModelAdapter = class {
@@ -4946,4 +4946,4 @@ export {
4946
4946
  SdkAdapter,
4947
4947
  createAutoAdapter
4948
4948
  };
4949
- //# sourceMappingURL=chunk-A62DB47B.js.map
4949
+ //# sourceMappingURL=chunk-3P5H74AV.js.map
@@ -2,7 +2,7 @@ import {
2
2
  createLogger,
3
3
  err,
4
4
  ok
5
- } from "./chunk-NBXYA5O6.js";
5
+ } from "./chunk-LZ6WZJRH.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-JYMFL4M6.js.map
90
+ //# sourceMappingURL=chunk-3YC6CEI5.js.map
@@ -4,7 +4,7 @@ import {
4
4
  getErrorMessage,
5
5
  getTimeProvider,
6
6
  ok
7
- } from "./chunk-NBXYA5O6.js";
7
+ } from "./chunk-LZ6WZJRH.js";
8
8
 
9
9
  // src/context/session-memory.ts
10
10
  import * as fs from "node:fs";
@@ -370,4 +370,4 @@ export {
370
370
  SessionMemory,
371
371
  createSessionMemory
372
372
  };
373
- //# sourceMappingURL=chunk-LMJ7BKIL.js.map
373
+ //# sourceMappingURL=chunk-4XNZKWKQ.js.map
@@ -2,10 +2,10 @@ import {
2
2
  stringifyValue,
3
3
  tokenize,
4
4
  tokenizeFiltered
5
- } from "./chunk-6T3EPABN.js";
5
+ } from "./chunk-7LP6VJRP.js";
6
6
  import {
7
7
  SessionMemory
8
- } from "./chunk-LMJ7BKIL.js";
8
+ } from "./chunk-4XNZKWKQ.js";
9
9
  import {
10
10
  StatsOnlyAdapter,
11
11
  ensureSharedMemoryRegistry
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-YYJFZ7TO.js";
16
16
  import {
17
17
  generateId
18
- } from "./chunk-KQRF4ZHX.js";
18
+ } from "./chunk-CFAN2FPY.js";
19
19
  import {
20
20
  ErrorCode,
21
21
  NexusError,
@@ -29,7 +29,7 @@ import {
29
29
  ok,
30
30
  openSqliteDatabase,
31
31
  setSharedMobiMemDbPathResolver
32
- } from "./chunk-NBXYA5O6.js";
32
+ } from "./chunk-LZ6WZJRH.js";
33
33
  import {
34
34
  nexusDataPath
35
35
  } from "./chunk-J7QCZRVK.js";
@@ -5661,4 +5661,4 @@ export {
5661
5661
  reinitializeMemoryBackends,
5662
5662
  ToolMemoryManager
5663
5663
  };
5664
- //# sourceMappingURL=chunk-5OTOOVOF.js.map
5664
+ //# sourceMappingURL=chunk-4YMUPCRS.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  generateSecurityPlan
3
- } from "./chunk-DBGIP6GK.js";
3
+ } from "./chunk-VLNPDWIW.js";
4
4
  import {
5
5
  analyzeGitHubRepo
6
6
  } from "./chunk-DGWT7DXX.js";
@@ -21,10 +21,10 @@ import {
21
21
  import {
22
22
  DEFAULT_TASK_TTL_MS,
23
23
  clampTaskTtl
24
- } from "./chunk-V2XWRKIJ.js";
24
+ } from "./chunk-2WAF3ZFK.js";
25
25
  import {
26
26
  executeExpert
27
- } from "./chunk-2LQAHGNZ.js";
27
+ } from "./chunk-C7CSLODO.js";
28
28
  import {
29
29
  JobStatusSchema,
30
30
  VOTER_ROLES,
@@ -48,26 +48,26 @@ import {
48
48
  simulationDeniedResult,
49
49
  toJobSummary,
50
50
  writeJobCancelled
51
- } from "./chunk-XVAXLGKZ.js";
51
+ } from "./chunk-LB7DDJOG.js";
52
52
  import {
53
53
  allOf
54
54
  } from "./chunk-OQB3XC5O.js";
55
55
  import {
56
56
  normalizeTopicToCanonical,
57
57
  synthesizeResearch
58
- } from "./chunk-CQK5SIEX.js";
58
+ } from "./chunk-KY3U2XEW.js";
59
59
  import {
60
60
  IssueTriage,
61
61
  createDurableAuditSink,
62
62
  createDurableAuditTrail
63
- } from "./chunk-4U555SVX.js";
63
+ } from "./chunk-UNDZPTSD.js";
64
64
  import {
65
65
  resolveEnvMode,
66
66
  sanitizeInput
67
- } from "./chunk-2T2MSN7B.js";
67
+ } from "./chunk-ZUK5BG3Q.js";
68
68
  import {
69
69
  withPrerequisite
70
- } from "./chunk-N3TMUOHG.js";
70
+ } from "./chunk-6B7E372N.js";
71
71
  import {
72
72
  NOOP_NOTIFIER,
73
73
  RateLimiter,
@@ -92,18 +92,18 @@ import {
92
92
  withAuditTrail,
93
93
  withProgressHeartbeat,
94
94
  wrapToolWithTimeout
95
- } from "./chunk-JXHRZRKU.js";
95
+ } from "./chunk-ZTB4Z23O.js";
96
96
  import {
97
97
  createAuditTrail,
98
98
  createGraphAuditBridge,
99
99
  emitPipelinePolicyEvent
100
- } from "./chunk-I4EHDJTI.js";
100
+ } from "./chunk-TCTKOFNL.js";
101
101
  import {
102
102
  EventTopics,
103
103
  createEvent,
104
104
  getGlobalEventBus,
105
105
  getGlobalRegistry
106
- } from "./chunk-46V3G76B.js";
106
+ } from "./chunk-P7FSB7X2.js";
107
107
  import {
108
108
  IDENTIFIER_RE,
109
109
  LANG_VALUES,
@@ -136,7 +136,7 @@ import {
136
136
  parseRegistry,
137
137
  sourceExistsInRegistry,
138
138
  summarizeContextForPrompt
139
- } from "./chunk-KJFX7JUP.js";
139
+ } from "./chunk-HN7EDIAH.js";
140
140
  import {
141
141
  REGISTRY_PATH,
142
142
  getProjectRoot,
@@ -144,24 +144,24 @@ import {
144
144
  loadTechniquesRegistry,
145
145
  resolveInsideRoot,
146
146
  resolveRegistryRoot
147
- } from "./chunk-GWQE5MBQ.js";
147
+ } from "./chunk-K7QRRVKW.js";
148
148
  import {
149
149
  getTokenEnvVars,
150
150
  resolveToken
151
- } from "./chunk-JYMFL4M6.js";
151
+ } from "./chunk-3YC6CEI5.js";
152
152
  import {
153
153
  DEFAULT_RELEVANCE_CONFIG,
154
154
  MemoryImportance,
155
155
  calculateTextJaccardSimilarity,
156
156
  getToolMemory
157
- } from "./chunk-5OTOOVOF.js";
157
+ } from "./chunk-4YMUPCRS.js";
158
158
  import {
159
159
  STOPWORDS,
160
160
  truncateWithInfo
161
- } from "./chunk-6T3EPABN.js";
161
+ } from "./chunk-7LP6VJRP.js";
162
162
  import {
163
163
  createSessionMemory
164
- } from "./chunk-LMJ7BKIL.js";
164
+ } from "./chunk-4XNZKWKQ.js";
165
165
  import {
166
166
  BUILT_IN_EXPERTS,
167
167
  BuiltInExpertTypeSchema,
@@ -179,25 +179,25 @@ import {
179
179
  getAvailableClis,
180
180
  sleep,
181
181
  withTimeout
182
- } from "./chunk-A62DB47B.js";
182
+ } from "./chunk-3P5H74AV.js";
183
183
  import {
184
184
  BaseAdapter,
185
185
  createStream,
186
186
  requireApiKey,
187
187
  validateApiKeyPresence
188
- } from "./chunk-R7V4C5UL.js";
188
+ } from "./chunk-ZECI6UI2.js";
189
189
  import {
190
190
  DEFAULTS
191
- } from "./chunk-R3QNEXOU.js";
191
+ } from "./chunk-ICKUT5LH.js";
192
192
  import {
193
193
  getAvailabilityCache,
194
194
  getCliForModelId,
195
195
  resolveFallback
196
- } from "./chunk-IJH2U2QL.js";
196
+ } from "./chunk-RIIWLQYM.js";
197
197
  import {
198
198
  generateHyphenId,
199
199
  generateUUID
200
- } from "./chunk-KQRF4ZHX.js";
200
+ } from "./chunk-CFAN2FPY.js";
201
201
  import {
202
202
  AGENT_ROUTER_TIMEOUTS,
203
203
  API_TIMEOUTS,
@@ -303,7 +303,7 @@ import {
303
303
  selectStrategyByManifest,
304
304
  toExpertTaskAnalysisResult,
305
305
  withStep
306
- } from "./chunk-NBXYA5O6.js";
306
+ } from "./chunk-LZ6WZJRH.js";
307
307
  import {
308
308
  ensureLearningDir,
309
309
  getMetaOutcomesFile,
@@ -29755,7 +29755,7 @@ function execIdFields(executionId) {
29755
29755
  async function populateUnifiedContextOnState(state, options) {
29756
29756
  const taskCandidate = state["task"];
29757
29757
  if (typeof taskCandidate !== "string" || taskCandidate === "") return;
29758
- const { getContextForTask: getContextForTask2, inferTaskCategory: inferTaskCategory2 } = await import("./context-retriever-GWAJG6XT.js");
29758
+ const { getContextForTask: getContextForTask2, inferTaskCategory: inferTaskCategory2 } = await import("./context-retriever-7VPUIRVT.js");
29759
29759
  const category = inferTaskCategory2(taskCandidate);
29760
29760
  const executionId = options?.executionId;
29761
29761
  const execFields = execIdFields(executionId);
@@ -45517,7 +45517,7 @@ async function tryIssueTriage(task) {
45517
45517
  try {
45518
45518
  const issueMatch = task.match(/github\.com\/([^/]+\/[^/]+)\/issues\/(\d+)/);
45519
45519
  if (issueMatch === null) return null;
45520
- const { createIssueTriage } = await import("./issue-triage-4RX3UV2B.js");
45520
+ const { createIssueTriage } = await import("./issue-triage-77QQQXYR.js");
45521
45521
  const triage = createIssueTriage();
45522
45522
  const owner = issueMatch[1] ?? "";
45523
45523
  const num = issueMatch[2] ?? "";
@@ -45545,7 +45545,7 @@ var VALID_TEMPLATES = /* @__PURE__ */ new Set([
45545
45545
  ]);
45546
45546
  async function classifyWithLLM(task) {
45547
45547
  try {
45548
- const { executeExpert: executeExpert2 } = await import("./expert-bridge-KCQ457YZ.js");
45548
+ const { executeExpert: executeExpert2 } = await import("./expert-bridge-ESJHWQ2Z.js");
45549
45549
  const prompt = [
45550
45550
  "Classify this task into exactly one pipeline template.",
45551
45551
  "Templates: dev (implementation/bug fix/refactor), research (investigate/evaluate/compare),",
@@ -47228,7 +47228,7 @@ var memoryInitPromise = null;
47228
47228
  async function initPipelineMemory() {
47229
47229
  if (cachedMemory !== null) return cachedMemory;
47230
47230
  try {
47231
- const { createSessionMemory: createSessionMemory2 } = await import("./session-memory-XKHKWRP3.js");
47231
+ const { createSessionMemory: createSessionMemory2 } = await import("./session-memory-MX2G4K2A.js");
47232
47232
  const { getLearningDir } = await import("./learning-persistence-JK2FELZL.js");
47233
47233
  const mem = createSessionMemory2(getLearningDir());
47234
47234
  mem.startSession(`pipeline-${String(getTimeProvider().now())}`);
@@ -47290,7 +47290,7 @@ function recordRoutingExperience(category, success, durationMs, tokensUsed = 0,
47290
47290
  callRecord(routingMemoryCache);
47291
47291
  return;
47292
47292
  }
47293
- routingMemoryInitPromise ??= import("./routing-memory-QUA5ORUA.js").then(({ createRoutingMemory }) => {
47293
+ routingMemoryInitPromise ??= import("./routing-memory-VMCHRNSE.js").then(({ createRoutingMemory }) => {
47294
47294
  routingMemoryCache ??= createRoutingMemory();
47295
47295
  return routingMemoryCache;
47296
47296
  }).catch((error) => {
@@ -47324,7 +47324,7 @@ ${text}` : "";
47324
47324
  }
47325
47325
  async function getWeatherContext() {
47326
47326
  try {
47327
- const { generateWeatherReport: generateWeatherReport2 } = await import("./weather-report-KHFJ756C.js");
47327
+ const { generateWeatherReport: generateWeatherReport2 } = await import("./weather-report-MUUYKM7C.js");
47328
47328
  const report = generateWeatherReport2({ includeAdaptive: true });
47329
47329
  const mappings = "recommendedMappings" in report ? report.recommendedMappings : [];
47330
47330
  if (!Array.isArray(mappings) || mappings.length === 0) return "";
@@ -47342,7 +47342,7 @@ ${lines}
47342
47342
  }
47343
47343
  async function getMemoryContext(task) {
47344
47344
  try {
47345
- const { createSessionMemory: createSessionMemory2 } = await import("./session-memory-XKHKWRP3.js");
47345
+ const { createSessionMemory: createSessionMemory2 } = await import("./session-memory-MX2G4K2A.js");
47346
47346
  const { getLearningDir } = await import("./learning-persistence-JK2FELZL.js");
47347
47347
  const memory = createSessionMemory2(getLearningDir(), { maxLearningsInContext: 10 });
47348
47348
  const learnings = memory.searchLearnings(task.slice(0, 200));
@@ -47461,7 +47461,7 @@ ${contextBlock}`;
47461
47461
  const strategy = config.votingStrategy ?? "higher_order";
47462
47462
  await postProgress(config, "Vote", `Running consensus with ${strategy} strategy...`);
47463
47463
  try {
47464
- const { executeVoting } = await import("./consensus-vote-2WLWZOVR.js");
47464
+ const { executeVoting } = await import("./consensus-vote-QS72DIWI.js");
47465
47465
  const votingResult = await executeVoting(
47466
47466
  {
47467
47467
  proposal: buildVoteProposal(plan, research),
@@ -47890,7 +47890,7 @@ async function searchCodebaseForTask(task) {
47890
47890
  }
47891
47891
  async function queryResearchRegistry(task) {
47892
47892
  try {
47893
- const { synthesizeResearch: synthesizeResearch2 } = await import("./research-helpers-synthesize-OKCOMCE2.js");
47893
+ const { synthesizeResearch: synthesizeResearch2 } = await import("./research-helpers-synthesize-KYDHWP7C.js");
47894
47894
  const topic = task.split(/[.!?\n]/).filter((s) => s.trim().length > 10)[0]?.trim();
47895
47895
  if (topic === void 0) return null;
47896
47896
  const result = await synthesizeResearch2(topic.slice(0, 50));
@@ -47961,7 +47961,7 @@ function createScanStageWrapper() {
47961
47961
  try {
47962
47962
  const slug = ctx.task.match(/([a-zA-Z0-9._-]+\/[a-zA-Z0-9._-]+)/)?.[1];
47963
47963
  if (slug !== void 0) {
47964
- const { generateSecurityPlan: generateSecurityPlan2 } = await import("./repo-security-plan-XZ6YBLUE.js");
47964
+ const { generateSecurityPlan: generateSecurityPlan2 } = await import("./repo-security-plan-QTGNCDI7.js");
47965
47965
  const plan = await generateSecurityPlan2({ repo: slug, maxScanners: 10 });
47966
47966
  const recs = plan.recommendations.slice(0, 5).map((r) => `${r.priority}: ${r.displayName} (${r.category})`).join("; ");
47967
47967
  return output(PIPELINE_STATE_KEYS.FINDINGS, recs, getTimeProvider().now() - start, true);
@@ -51132,7 +51132,7 @@ var GitHubTaskTracker = class {
51132
51132
  cachedProvider = null;
51133
51133
  async getProvider() {
51134
51134
  if (this.cachedProvider !== null) return this.cachedProvider;
51135
- const { createScmProvider } = await import("./factory-FFKHIV6Q.js");
51135
+ const { createScmProvider } = await import("./factory-HUUB4OWA.js");
51136
51136
  const result = await createScmProvider({ repo: this.config.repo ?? "" });
51137
51137
  if (!result.ok) throw new Error(`SCM provider error: ${result.error.message}`);
51138
51138
  this.cachedProvider = result.value;
@@ -52050,7 +52050,7 @@ async function probeSource(source, includeModelIds) {
52050
52050
  }
52051
52051
  }
52052
52052
  async function defaultSources(includeOpenRouter) {
52053
- const { createAllAdapters: createAllAdapters2 } = await import("./factory-S2SVFA6W.js");
52053
+ const { createAllAdapters: createAllAdapters2 } = await import("./factory-HFHYJ4P6.js");
52054
52054
  const adapters = createAllAdapters2();
52055
52055
  return buildDefaultModelSources(adapters, { includeOpenRouter });
52056
52056
  }
@@ -56125,4 +56125,4 @@ export {
56125
56125
  shutdownFeedbackSubscriber,
56126
56126
  createEventBusBridge
56127
56127
  };
56128
- //# sourceMappingURL=chunk-EPVPVG25.js.map
56128
+ //# sourceMappingURL=chunk-5LAPFTNG.js.map
@@ -7,7 +7,7 @@ import {
7
7
  toolStructuredError,
8
8
  toolSuccessStructured,
9
9
  wrapToolWithTimeout
10
- } from "./chunk-JXHRZRKU.js";
10
+ } from "./chunk-ZTB4Z23O.js";
11
11
  import {
12
12
  JsonlStore,
13
13
  SECURITY_KEYWORDS,
@@ -20,7 +20,7 @@ import {
20
20
  getTimeProvider,
21
21
  isDeclaredNeverDeprecate,
22
22
  isRegisteredToolName
23
- } from "./chunk-NBXYA5O6.js";
23
+ } from "./chunk-LZ6WZJRH.js";
24
24
  import {
25
25
  getNexusDataDir,
26
26
  nexusDataPath
@@ -2159,4 +2159,4 @@ export {
2159
2159
  runImprovementReview,
2160
2160
  registerImprovementReviewTool
2161
2161
  };
2162
- //# sourceMappingURL=chunk-N3TMUOHG.js.map
2162
+ //# sourceMappingURL=chunk-6B7E372N.js.map
@@ -98,6 +98,10 @@ function capitalizeWords(str) {
98
98
  function capitalizeKebab(str) {
99
99
  return str.split("-").map((word) => capitalize(word)).join(" ");
100
100
  }
101
+ function truncateText(text, maxLength, suffix = "...") {
102
+ if (text.length <= maxLength) return text;
103
+ return text.slice(0, maxLength - suffix.length) + suffix;
104
+ }
101
105
  function truncateWithInfo(text, maxLength) {
102
106
  if (text.length <= maxLength) return text;
103
107
  const truncatedBytes = text.length - maxLength;
@@ -121,7 +125,8 @@ export {
121
125
  capitalize,
122
126
  capitalizeWords,
123
127
  capitalizeKebab,
128
+ truncateText,
124
129
  truncateWithInfo,
125
130
  truncateSentence
126
131
  };
127
- //# sourceMappingURL=chunk-6T3EPABN.js.map
132
+ //# sourceMappingURL=chunk-7LP6VJRP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/text-utils.ts"],"sourcesContent":["/**\n * nexus-agents/utils - Text Processing Utilities\n *\n * Shared utility functions for text tokenization and processing.\n * Consolidates duplicate code from multiple modules per ADR-0013.\n *\n * Used by:\n * - context/agentic-memory-extraction.ts\n * - context/adaptive-memory-helpers.ts\n * - cli-adapters/agreement-cascade-helpers.ts\n *\n * @module utils/text-utils\n * @see docs/adr/0013-memory-helpers-consolidation.md\n */\n\n// ============================================================================\n// Stopwords\n// ============================================================================\n\n/**\n * Common English stopwords to filter from keyword extraction.\n */\nexport const STOPWORDS = new Set([\n 'a',\n 'an',\n 'and',\n 'are',\n 'as',\n 'at',\n 'be',\n 'by',\n 'for',\n 'from',\n 'has',\n 'he',\n 'in',\n 'is',\n 'it',\n 'its',\n 'of',\n 'on',\n 'or',\n 'that',\n 'the',\n 'to',\n 'was',\n 'were',\n 'will',\n 'with',\n 'this',\n 'but',\n 'they',\n 'have',\n 'had',\n 'what',\n 'when',\n 'where',\n 'who',\n 'which',\n 'why',\n 'how',\n 'all',\n 'each',\n 'every',\n 'both',\n 'few',\n 'more',\n 'most',\n 'other',\n 'some',\n 'such',\n 'no',\n 'nor',\n 'not',\n 'only',\n 'own',\n 'same',\n 'so',\n 'than',\n 'too',\n 'very',\n 'can',\n 'just',\n 'should',\n 'now',\n 'i',\n 'you',\n 'we',\n 'me',\n 'my',\n 'your',\n 'our',\n 'their',\n 'him',\n 'her',\n 'them',\n 'his',\n 'hers',\n 'able',\n]);\n\n// ============================================================================\n// Tokenization\n// ============================================================================\n\n/**\n * Tokenize text into normalized words.\n *\n * Process:\n * 1. Convert to lowercase\n * 2. Replace non-alphanumeric characters with spaces\n * 3. Split on whitespace\n * 4. Filter tokens by minimum length\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Array of normalized tokens\n */\nexport function tokenize(text: string, minLength = 2): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter((t) => t.length >= minLength);\n}\n\n/**\n * Tokenize text and return as a Set for fast lookups.\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Set of normalized tokens\n */\nexport function tokenizeToSet(text: string, minLength = 2): Set<string> {\n return new Set(tokenize(text, minLength));\n}\n\n/**\n * Tokenize text with stopword filtering.\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Array of tokens with stopwords removed\n */\nexport function tokenizeFiltered(text: string, minLength = 2): string[] {\n return tokenize(text, minLength).filter((t) => !STOPWORDS.has(t));\n}\n\n// ============================================================================\n// Value Stringification\n// ============================================================================\n\n/**\n * Convert a value to string for text processing.\n *\n * @param value - Value to stringify\n * @returns String representation\n */\nexport function stringifyValue(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value === null || value === undefined) return '';\n return JSON.stringify(value);\n}\n\n// ============================================================================\n// String Capitalization\n// ============================================================================\n\n/**\n * Capitalize the first character of a string.\n *\n * @param str - Input string\n * @returns String with first character uppercased\n * @example capitalize('hello') // 'Hello'\n */\nexport function capitalize(str: string): string {\n if (str.length === 0) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Capitalize the first character of each word in a string.\n *\n * @param str - Input string\n * @returns String with each word capitalized\n * @example capitalizeWords('hello world') // 'Hello World'\n */\nexport function capitalizeWords(str: string): string {\n return str\n .split(' ')\n .map((word) => capitalize(word))\n .join(' ');\n}\n\n/**\n * Convert a kebab-case string to Title Case.\n *\n * @param str - Kebab-case string\n * @returns Title Case string with hyphens replaced by spaces\n * @example capitalizeKebab('hello-world') // 'Hello World'\n */\nexport function capitalizeKebab(str: string): string {\n return str\n .split('-')\n .map((word) => capitalize(word))\n .join(' ');\n}\n\n// ============================================================================\n// Text Truncation\n// ============================================================================\n\n/**\n * Truncate text to a maximum length with a suffix.\n *\n * @param text - Input text\n * @param maxLength - Maximum length including suffix\n * @param suffix - Suffix to append when truncated (default: '...')\n * @returns Truncated text with suffix if needed\n * @example truncateText('hello world', 8) // 'hello...'\n */\nexport function truncateText(text: string, maxLength: number, suffix = '...'): string {\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength - suffix.length) + suffix;\n}\n\n/**\n * Truncate text and include byte count information.\n * Commonly used for output truncation in CLI tools.\n *\n * @param text - Input text\n * @param maxLength - Maximum length before truncation marker\n * @returns Truncated text with byte count info\n * @example truncateWithInfo('hello world...', 5) // 'hello\\n... [truncated 9 bytes]'\n */\nexport function truncateWithInfo(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n const truncatedBytes = text.length - maxLength;\n return `${text.slice(0, maxLength)}\\n... [truncated ${String(truncatedBytes)} bytes]`;\n}\n\n/**\n * Truncate to the first sentence or a maximum length.\n * Useful for extracting descriptions from longer text.\n *\n * @param text - Input text\n * @param maxLength - Maximum length (default: 150)\n * @returns First sentence or truncated text\n * @example truncateSentence('Hello world. More text.', 150) // 'Hello world.'\n */\nexport function truncateSentence(text: string, maxLength = 150): string {\n // Find first sentence ending\n const sentenceEnd = text.search(/[.!?](?:\\s|$)/);\n if (sentenceEnd !== -1 && sentenceEnd < maxLength) {\n return text.slice(0, sentenceEnd + 1).trim();\n }\n // Fall back to truncation\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength).trim() + '...';\n}\n\n// ============================================================================\n// Line Splitting\n// ============================================================================\n\n/**\n * Split text into lines.\n * Handles both Unix (\\n) and Windows (\\r\\n) line endings.\n *\n * @param text - Input text to split\n * @returns Array of lines (may include empty strings)\n * @example splitLines('a\\nb\\nc') // ['a', 'b', 'c']\n * @example splitLines('a\\n\\nb') // ['a', '', 'b']\n */\nexport function splitLines(text: string): string[] {\n return text.split(/\\r?\\n/);\n}\n\n/**\n * Split text into non-empty lines.\n * Filters out empty lines and whitespace-only lines.\n *\n * @param text - Input text to split\n * @returns Array of non-empty lines\n * @example splitNonEmptyLines('a\\n\\nb\\n \\nc') // ['a', 'b', 'c']\n */\nexport function splitNonEmptyLines(text: string): string[] {\n return text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n}\n\n/**\n * Split text into trimmed lines, preserving empty lines.\n * Trims each line but keeps empty lines in the output.\n *\n * @param text - Input text to split\n * @returns Array of trimmed lines\n * @example splitTrimmedLines(' a \\n\\n b ') // ['a', '', 'b']\n */\nexport function splitTrimmedLines(text: string): string[] {\n return text.split(/\\r?\\n/).map((line) => line.trim());\n}\n\n// ============================================================================\n// Sentence/Word Splitting\n// ============================================================================\n\n/**\n * Count the number of sentences in text.\n * Counts sentence-ending punctuation followed by space or end of string.\n *\n * @param text - Input text\n * @returns Number of sentences\n * @example countSentences('Hello world. How are you?') // 2\n */\nexport function countSentences(text: string): number {\n const matches = text.match(/[.!?]+(?:\\s|$)/g);\n return matches !== null ? matches.length : 0;\n}\n\n/**\n * Split text into sentences.\n * Splits on sentence-ending punctuation followed by space.\n *\n * @param text - Input text\n * @returns Array of sentences (trimmed)\n * @example splitSentences('Hello world. How are you?') // ['Hello world.', 'How are you?']\n */\nexport function splitSentences(text: string): string[] {\n // Split on sentence endings followed by space, keeping the punctuation\n return text\n .split(/(?<=[.!?])\\s+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/**\n * Count the number of words in text.\n * Splits on whitespace and counts non-empty tokens.\n *\n * @param text - Input text\n * @returns Number of words\n * @example countWords('Hello world') // 2\n */\nexport function countWords(text: string): number {\n return text\n .trim()\n .split(/\\s+/)\n .filter((w) => w.length > 0).length;\n}\n"],"mappings":";AAsBO,IAAM,YAAY,oBAAI,IAAI;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAmBM,SAAS,SAAS,MAAc,YAAY,GAAa;AAC9D,SAAO,KACJ,YAAY,EACZ,QAAQ,gBAAgB,GAAG,EAC3B,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,UAAU,SAAS;AACxC;AAoBO,SAAS,iBAAiB,MAAc,YAAY,GAAa;AACtE,SAAO,SAAS,MAAM,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;AAClE;AAYO,SAAS,eAAe,OAAwB;AACrD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,SAAO,KAAK,UAAU,KAAK;AAC7B;AAaO,SAAS,WAAW,KAAqB;AAC9C,MAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,SAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAClD;AASO,SAAS,gBAAgB,KAAqB;AACnD,SAAO,IACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,EAC9B,KAAK,GAAG;AACb;AASO,SAAS,gBAAgB,KAAqB;AACnD,SAAO,IACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,EAC9B,KAAK,GAAG;AACb;AA6BO,SAAS,iBAAiB,MAAc,WAA2B;AACxE,MAAI,KAAK,UAAU,UAAW,QAAO;AACrC,QAAM,iBAAiB,KAAK,SAAS;AACrC,SAAO,GAAG,KAAK,MAAM,GAAG,SAAS,CAAC;AAAA,iBAAoB,OAAO,cAAc,CAAC;AAC9E;AAWO,SAAS,iBAAiB,MAAc,YAAY,KAAa;AAEtE,QAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,MAAI,gBAAgB,MAAM,cAAc,WAAW;AACjD,WAAO,KAAK,MAAM,GAAG,cAAc,CAAC,EAAE,KAAK;AAAA,EAC7C;AAEA,MAAI,KAAK,UAAU,UAAW,QAAO;AACrC,SAAO,KAAK,MAAM,GAAG,SAAS,EAAE,KAAK,IAAI;AAC3C;","names":[]}
1
+ {"version":3,"sources":["../src/utils/text-utils.ts"],"sourcesContent":["/**\n * nexus-agents/utils - Text Processing Utilities\n *\n * Shared utility functions for text tokenization and processing.\n * Consolidates duplicate code from multiple modules per ADR-0013.\n *\n * Used by:\n * - context/agentic-memory-extraction.ts\n * - context/adaptive-memory-helpers.ts\n * - cli-adapters/agreement-cascade-helpers.ts\n *\n * @module utils/text-utils\n * @see docs/adr/0013-memory-helpers-consolidation.md\n */\n\n// ============================================================================\n// Stopwords\n// ============================================================================\n\n/**\n * Common English stopwords to filter from keyword extraction.\n */\nexport const STOPWORDS = new Set([\n 'a',\n 'an',\n 'and',\n 'are',\n 'as',\n 'at',\n 'be',\n 'by',\n 'for',\n 'from',\n 'has',\n 'he',\n 'in',\n 'is',\n 'it',\n 'its',\n 'of',\n 'on',\n 'or',\n 'that',\n 'the',\n 'to',\n 'was',\n 'were',\n 'will',\n 'with',\n 'this',\n 'but',\n 'they',\n 'have',\n 'had',\n 'what',\n 'when',\n 'where',\n 'who',\n 'which',\n 'why',\n 'how',\n 'all',\n 'each',\n 'every',\n 'both',\n 'few',\n 'more',\n 'most',\n 'other',\n 'some',\n 'such',\n 'no',\n 'nor',\n 'not',\n 'only',\n 'own',\n 'same',\n 'so',\n 'than',\n 'too',\n 'very',\n 'can',\n 'just',\n 'should',\n 'now',\n 'i',\n 'you',\n 'we',\n 'me',\n 'my',\n 'your',\n 'our',\n 'their',\n 'him',\n 'her',\n 'them',\n 'his',\n 'hers',\n 'able',\n]);\n\n// ============================================================================\n// Tokenization\n// ============================================================================\n\n/**\n * Tokenize text into normalized words.\n *\n * Process:\n * 1. Convert to lowercase\n * 2. Replace non-alphanumeric characters with spaces\n * 3. Split on whitespace\n * 4. Filter tokens by minimum length\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Array of normalized tokens\n */\nexport function tokenize(text: string, minLength = 2): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter((t) => t.length >= minLength);\n}\n\n/**\n * Tokenize text and return as a Set for fast lookups.\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Set of normalized tokens\n */\nexport function tokenizeToSet(text: string, minLength = 2): Set<string> {\n return new Set(tokenize(text, minLength));\n}\n\n/**\n * Tokenize text with stopword filtering.\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Array of tokens with stopwords removed\n */\nexport function tokenizeFiltered(text: string, minLength = 2): string[] {\n return tokenize(text, minLength).filter((t) => !STOPWORDS.has(t));\n}\n\n// ============================================================================\n// Value Stringification\n// ============================================================================\n\n/**\n * Convert a value to string for text processing.\n *\n * @param value - Value to stringify\n * @returns String representation\n */\nexport function stringifyValue(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value === null || value === undefined) return '';\n return JSON.stringify(value);\n}\n\n// ============================================================================\n// String Capitalization\n// ============================================================================\n\n/**\n * Capitalize the first character of a string.\n *\n * @param str - Input string\n * @returns String with first character uppercased\n * @example capitalize('hello') // 'Hello'\n */\nexport function capitalize(str: string): string {\n if (str.length === 0) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Capitalize the first character of each word in a string.\n *\n * @param str - Input string\n * @returns String with each word capitalized\n * @example capitalizeWords('hello world') // 'Hello World'\n */\nexport function capitalizeWords(str: string): string {\n return str\n .split(' ')\n .map((word) => capitalize(word))\n .join(' ');\n}\n\n/**\n * Convert a kebab-case string to Title Case.\n *\n * @param str - Kebab-case string\n * @returns Title Case string with hyphens replaced by spaces\n * @example capitalizeKebab('hello-world') // 'Hello World'\n */\nexport function capitalizeKebab(str: string): string {\n return str\n .split('-')\n .map((word) => capitalize(word))\n .join(' ');\n}\n\n// ============================================================================\n// Text Truncation\n// ============================================================================\n\n/**\n * Truncate text to a maximum length with a suffix.\n *\n * @param text - Input text\n * @param maxLength - Maximum length including suffix\n * @param suffix - Suffix to append when truncated (default: '...')\n * @returns Truncated text with suffix if needed\n * @example truncateText('hello world', 8) // 'hello...'\n */\nexport function truncateText(text: string, maxLength: number, suffix = '...'): string {\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength - suffix.length) + suffix;\n}\n\n/**\n * Truncate text and include byte count information.\n * Commonly used for output truncation in CLI tools.\n *\n * @param text - Input text\n * @param maxLength - Maximum length before truncation marker\n * @returns Truncated text with byte count info\n * @example truncateWithInfo('hello world...', 5) // 'hello\\n... [truncated 9 bytes]'\n */\nexport function truncateWithInfo(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n const truncatedBytes = text.length - maxLength;\n return `${text.slice(0, maxLength)}\\n... [truncated ${String(truncatedBytes)} bytes]`;\n}\n\n/**\n * Truncate to the first sentence or a maximum length.\n * Useful for extracting descriptions from longer text.\n *\n * @param text - Input text\n * @param maxLength - Maximum length (default: 150)\n * @returns First sentence or truncated text\n * @example truncateSentence('Hello world. More text.', 150) // 'Hello world.'\n */\nexport function truncateSentence(text: string, maxLength = 150): string {\n // Find first sentence ending\n const sentenceEnd = text.search(/[.!?](?:\\s|$)/);\n if (sentenceEnd !== -1 && sentenceEnd < maxLength) {\n return text.slice(0, sentenceEnd + 1).trim();\n }\n // Fall back to truncation\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength).trim() + '...';\n}\n\n// ============================================================================\n// Line Splitting\n// ============================================================================\n\n/**\n * Split text into lines.\n * Handles both Unix (\\n) and Windows (\\r\\n) line endings.\n *\n * @param text - Input text to split\n * @returns Array of lines (may include empty strings)\n * @example splitLines('a\\nb\\nc') // ['a', 'b', 'c']\n * @example splitLines('a\\n\\nb') // ['a', '', 'b']\n */\nexport function splitLines(text: string): string[] {\n return text.split(/\\r?\\n/);\n}\n\n/**\n * Split text into non-empty lines.\n * Filters out empty lines and whitespace-only lines.\n *\n * @param text - Input text to split\n * @returns Array of non-empty lines\n * @example splitNonEmptyLines('a\\n\\nb\\n \\nc') // ['a', 'b', 'c']\n */\nexport function splitNonEmptyLines(text: string): string[] {\n return text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n}\n\n/**\n * Split text into trimmed lines, preserving empty lines.\n * Trims each line but keeps empty lines in the output.\n *\n * @param text - Input text to split\n * @returns Array of trimmed lines\n * @example splitTrimmedLines(' a \\n\\n b ') // ['a', '', 'b']\n */\nexport function splitTrimmedLines(text: string): string[] {\n return text.split(/\\r?\\n/).map((line) => line.trim());\n}\n\n// ============================================================================\n// Sentence/Word Splitting\n// ============================================================================\n\n/**\n * Count the number of sentences in text.\n * Counts sentence-ending punctuation followed by space or end of string.\n *\n * @param text - Input text\n * @returns Number of sentences\n * @example countSentences('Hello world. How are you?') // 2\n */\nexport function countSentences(text: string): number {\n const matches = text.match(/[.!?]+(?:\\s|$)/g);\n return matches !== null ? matches.length : 0;\n}\n\n/**\n * Split text into sentences.\n * Splits on sentence-ending punctuation followed by space.\n *\n * @param text - Input text\n * @returns Array of sentences (trimmed)\n * @example splitSentences('Hello world. How are you?') // ['Hello world.', 'How are you?']\n */\nexport function splitSentences(text: string): string[] {\n // Split on sentence endings followed by space, keeping the punctuation\n return text\n .split(/(?<=[.!?])\\s+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/**\n * Count the number of words in text.\n * Splits on whitespace and counts non-empty tokens.\n *\n * @param text - Input text\n * @returns Number of words\n * @example countWords('Hello world') // 2\n */\nexport function countWords(text: string): number {\n return text\n .trim()\n .split(/\\s+/)\n .filter((w) => w.length > 0).length;\n}\n"],"mappings":";AAsBO,IAAM,YAAY,oBAAI,IAAI;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAmBM,SAAS,SAAS,MAAc,YAAY,GAAa;AAC9D,SAAO,KACJ,YAAY,EACZ,QAAQ,gBAAgB,GAAG,EAC3B,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,UAAU,SAAS;AACxC;AAoBO,SAAS,iBAAiB,MAAc,YAAY,GAAa;AACtE,SAAO,SAAS,MAAM,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;AAClE;AAYO,SAAS,eAAe,OAAwB;AACrD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,SAAO,KAAK,UAAU,KAAK;AAC7B;AAaO,SAAS,WAAW,KAAqB;AAC9C,MAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,SAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAClD;AASO,SAAS,gBAAgB,KAAqB;AACnD,SAAO,IACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,EAC9B,KAAK,GAAG;AACb;AASO,SAAS,gBAAgB,KAAqB;AACnD,SAAO,IACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,EAC9B,KAAK,GAAG;AACb;AAeO,SAAS,aAAa,MAAc,WAAmB,SAAS,OAAe;AACpF,MAAI,KAAK,UAAU,UAAW,QAAO;AACrC,SAAO,KAAK,MAAM,GAAG,YAAY,OAAO,MAAM,IAAI;AACpD;AAWO,SAAS,iBAAiB,MAAc,WAA2B;AACxE,MAAI,KAAK,UAAU,UAAW,QAAO;AACrC,QAAM,iBAAiB,KAAK,SAAS;AACrC,SAAO,GAAG,KAAK,MAAM,GAAG,SAAS,CAAC;AAAA,iBAAoB,OAAO,cAAc,CAAC;AAC9E;AAWO,SAAS,iBAAiB,MAAc,YAAY,KAAa;AAEtE,QAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,MAAI,gBAAgB,MAAM,cAAc,WAAW;AACjD,WAAO,KAAK,MAAM,GAAG,cAAc,CAAC,EAAE,KAAK;AAAA,EAC7C;AAEA,MAAI,KAAK,UAAU,UAAW,QAAO;AACrC,SAAO,KAAK,MAAM,GAAG,SAAS,EAAE,KAAK,IAAI;AAC3C;","names":[]}
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  resolveCliSlot
3
- } from "./chunk-IJH2U2QL.js";
3
+ } from "./chunk-RIIWLQYM.js";
4
4
  import {
5
5
  createLogger,
6
6
  getTimeProvider,
7
7
  isRateLimitText
8
- } from "./chunk-NBXYA5O6.js";
8
+ } from "./chunk-LZ6WZJRH.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-JQCVNB3Y.js");
24
+ const { generateMcpConfig } = await import("./child-mcp-config-ONSFGNNH.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-S2SVFA6W.js");
97
- const { createCompositeRouter } = await import("./composite-router-XNVULYDV.js");
96
+ const { createAllAdapters } = await import("./factory-HFHYJ4P6.js");
97
+ const { createCompositeRouter } = await import("./composite-router-OSASGOMV.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-2LQZLFVP.js");
105
+ const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-FOPLEQK6.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-2LQAHGNZ.js.map
216
+ //# sourceMappingURL=chunk-C7CSLODO.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getRandomProvider,
3
3
  getTimeProvider
4
- } from "./chunk-NBXYA5O6.js";
4
+ } from "./chunk-LZ6WZJRH.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-KQRF4ZHX.js.map
27
+ //# sourceMappingURL=chunk-CFAN2FPY.js.map