nexus-agents 2.82.0 → 2.83.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 (125) hide show
  1. package/dist/{child-mcp-config-BMSYR7VV.js → child-mcp-config-XVPIO5HV.js} +2 -2
  2. package/dist/{chunk-OYDJ3C4N.js → chunk-2W4QJ27D.js} +3 -3
  3. package/dist/{chunk-BQ4YXGGQ.js → chunk-3ACDP4E6.js} +124 -2
  4. package/dist/chunk-3ACDP4E6.js.map +1 -0
  5. package/dist/{chunk-C7P2HLJX.js → chunk-3ASED5PR.js} +4 -4
  6. package/dist/{chunk-TXIUCEFT.js → chunk-3GJAAENS.js} +3 -3
  7. package/dist/{chunk-GNG7URCR.js → chunk-3WUVWZUC.js} +2 -2
  8. package/dist/{chunk-FTT2IYYX.js → chunk-4BXQ2OZY.js} +34 -16
  9. package/dist/chunk-4BXQ2OZY.js.map +1 -0
  10. package/dist/{chunk-SBZVRH4S.js → chunk-54UXPJVM.js} +2 -2
  11. package/dist/{chunk-QHL4KGNB.js → chunk-5T6SYCH2.js} +2 -2
  12. package/dist/{chunk-BL5IBHEY.js → chunk-6WDJ3IE4.js} +3 -3
  13. package/dist/{chunk-2R5UUBGA.js → chunk-AFPHR72D.js} +2 -2
  14. package/dist/{chunk-S36LIUV2.js → chunk-AINOJRZX.js} +7 -7
  15. package/dist/{chunk-HJUHDPXJ.js → chunk-BZUEUD4G.js} +3 -3
  16. package/dist/{chunk-2SQXJQTA.js → chunk-FHGDJKCZ.js} +16 -13
  17. package/dist/{chunk-2SQXJQTA.js.map → chunk-FHGDJKCZ.js.map} +1 -1
  18. package/dist/{chunk-XGUDCUMB.js → chunk-FI77TGBY.js} +2 -2
  19. package/dist/{chunk-7J7PNOJQ.js → chunk-HFOQKCD2.js} +22 -5
  20. package/dist/chunk-HFOQKCD2.js.map +1 -0
  21. package/dist/{chunk-PZESEBD3.js → chunk-L362KRSU.js} +2 -2
  22. package/dist/{chunk-HMXQKDUV.js → chunk-NLPMYBIV.js} +23 -7
  23. package/dist/chunk-NLPMYBIV.js.map +1 -0
  24. package/dist/{chunk-4XNVJS5A.js → chunk-PMLVZXAE.js} +763 -728
  25. package/dist/chunk-PMLVZXAE.js.map +1 -0
  26. package/dist/{chunk-JM3R267Z.js → chunk-PPBZQKRP.js} +5 -5
  27. package/dist/{chunk-WUUEKFKG.js → chunk-Q6PZMGLU.js} +2 -2
  28. package/dist/{chunk-W2AIGD35.js → chunk-RVRXKNND.js} +3 -3
  29. package/dist/{chunk-7VNVDFD5.js → chunk-RXVH52UI.js} +44 -18
  30. package/dist/{chunk-7VNVDFD5.js.map → chunk-RXVH52UI.js.map} +1 -1
  31. package/dist/{chunk-HVZ52LOL.js → chunk-U6LDVJS7.js} +2 -2
  32. package/dist/{chunk-X3JR3GMT.js → chunk-WGSRH5EQ.js} +3 -3
  33. package/dist/{chunk-SXL744NF.js → chunk-WJFUTRHX.js} +2 -2
  34. package/dist/{chunk-U7JXQSEM.js → chunk-YO27YAEX.js} +3 -3
  35. package/dist/{chunk-G2DZBEMU.js → chunk-Z64MSLEK.js} +2 -2
  36. package/dist/{chunk-NTLJ3INA.js → chunk-ZIWEEVMI.js} +2 -2
  37. package/dist/{chunk-SHWGK7X6.js → chunk-ZM5JKJHI.js} +2 -2
  38. package/dist/{cli-circuit-breaker-BIJUQRQI.js → cli-circuit-breaker-Y26NPPNO.js} +4 -4
  39. package/dist/cli.js +366 -344
  40. package/dist/cli.js.map +1 -1
  41. package/dist/codebase-search-ZFJUVMVR.js +8 -0
  42. package/dist/{composite-router-FB7P22L5.js → composite-router-X2ZYIEHH.js} +2 -2
  43. package/dist/{consensus-vote-KKAIFULI.js → consensus-vote-KZ6UURUI.js} +11 -11
  44. package/dist/{context-retriever-4JCGMWH7.js → context-retriever-QY4FNTDZ.js} +5 -5
  45. package/dist/{doctor-deep-7YK4BZIJ.js → doctor-deep-2E2GBMYR.js} +3 -3
  46. package/dist/expert-bridge-FHPWDFJX.js +13 -0
  47. package/dist/{factory-PK4EZL7K.js → factory-STNVY3Y3.js} +4 -4
  48. package/dist/{factory-DOWBGVAL.js → factory-W6KROBFN.js} +5 -5
  49. package/dist/index.d.ts +104 -60
  50. package/dist/index.js +100 -105
  51. package/dist/index.js.map +1 -1
  52. package/dist/{init-opencode-QP5CAMWN.js → init-opencode-6LVZ4CAQ.js} +5 -5
  53. package/dist/{issue-triage-T3SKNBH5.js → issue-triage-Y77JI7WF.js} +4 -4
  54. package/dist/{registry-command-TH7U6UMC.js → registry-command-P5VIAEOL.js} +2 -2
  55. package/dist/{repo-analyze-D2OY2QSR.js → repo-analyze-JZEMBE6R.js} +2 -2
  56. package/dist/{repo-security-plan-V257RYTW.js → repo-security-plan-RHSLO7H6.js} +4 -4
  57. package/dist/{research-helpers-synthesize-Y3O76PY4.js → research-helpers-synthesize-PVP6JRZV.js} +3 -3
  58. package/dist/{routing-memory-AAH7NIHD.js → routing-memory-QRIJPRVD.js} +2 -2
  59. package/dist/{session-memory-MY6YS2VX.js → session-memory-WARRGYY7.js} +3 -3
  60. package/dist/{setup-command-B6EC3OJA.js → setup-command-GMP5FI7F.js} +10 -10
  61. package/dist/{setup-config-HVO6ZSLW.js → setup-config-G3KKZM7O.js} +3 -3
  62. package/dist/{setup-custom-api-UOIKUQL4.js → setup-custom-api-B63X7ISD.js} +4 -4
  63. package/dist/{tool-memory-T7ZYIUJ2.js → tool-memory-E7JW4YLT.js} +4 -4
  64. package/dist/{weather-report-O3Z3BBAX.js → weather-report-RACZWJQL.js} +2 -2
  65. package/package.json +1 -1
  66. package/dist/chunk-4XNVJS5A.js.map +0 -1
  67. package/dist/chunk-7J7PNOJQ.js.map +0 -1
  68. package/dist/chunk-AP2FD37C.js +0 -127
  69. package/dist/chunk-AP2FD37C.js.map +0 -1
  70. package/dist/chunk-BQ4YXGGQ.js.map +0 -1
  71. package/dist/chunk-ED6VQWNG.js +0 -63
  72. package/dist/chunk-ED6VQWNG.js.map +0 -1
  73. package/dist/chunk-FTT2IYYX.js.map +0 -1
  74. package/dist/chunk-HMXQKDUV.js.map +0 -1
  75. package/dist/codebase-search-PIBRTGBE.js +0 -9
  76. package/dist/expert-bridge-DJM5GAWZ.js +0 -11
  77. package/dist/shared-memory-CM6T2MYE.js +0 -8
  78. package/dist/symbol-extractor-WYXPJH65.js +0 -10
  79. package/dist/tool-memory-T7ZYIUJ2.js.map +0 -1
  80. package/dist/weather-report-O3Z3BBAX.js.map +0 -1
  81. /package/dist/{child-mcp-config-BMSYR7VV.js.map → child-mcp-config-XVPIO5HV.js.map} +0 -0
  82. /package/dist/{chunk-OYDJ3C4N.js.map → chunk-2W4QJ27D.js.map} +0 -0
  83. /package/dist/{chunk-C7P2HLJX.js.map → chunk-3ASED5PR.js.map} +0 -0
  84. /package/dist/{chunk-TXIUCEFT.js.map → chunk-3GJAAENS.js.map} +0 -0
  85. /package/dist/{chunk-GNG7URCR.js.map → chunk-3WUVWZUC.js.map} +0 -0
  86. /package/dist/{chunk-SBZVRH4S.js.map → chunk-54UXPJVM.js.map} +0 -0
  87. /package/dist/{chunk-QHL4KGNB.js.map → chunk-5T6SYCH2.js.map} +0 -0
  88. /package/dist/{chunk-BL5IBHEY.js.map → chunk-6WDJ3IE4.js.map} +0 -0
  89. /package/dist/{chunk-2R5UUBGA.js.map → chunk-AFPHR72D.js.map} +0 -0
  90. /package/dist/{chunk-S36LIUV2.js.map → chunk-AINOJRZX.js.map} +0 -0
  91. /package/dist/{chunk-HJUHDPXJ.js.map → chunk-BZUEUD4G.js.map} +0 -0
  92. /package/dist/{chunk-XGUDCUMB.js.map → chunk-FI77TGBY.js.map} +0 -0
  93. /package/dist/{chunk-PZESEBD3.js.map → chunk-L362KRSU.js.map} +0 -0
  94. /package/dist/{chunk-JM3R267Z.js.map → chunk-PPBZQKRP.js.map} +0 -0
  95. /package/dist/{chunk-WUUEKFKG.js.map → chunk-Q6PZMGLU.js.map} +0 -0
  96. /package/dist/{chunk-W2AIGD35.js.map → chunk-RVRXKNND.js.map} +0 -0
  97. /package/dist/{chunk-HVZ52LOL.js.map → chunk-U6LDVJS7.js.map} +0 -0
  98. /package/dist/{chunk-X3JR3GMT.js.map → chunk-WGSRH5EQ.js.map} +0 -0
  99. /package/dist/{chunk-SXL744NF.js.map → chunk-WJFUTRHX.js.map} +0 -0
  100. /package/dist/{chunk-U7JXQSEM.js.map → chunk-YO27YAEX.js.map} +0 -0
  101. /package/dist/{chunk-G2DZBEMU.js.map → chunk-Z64MSLEK.js.map} +0 -0
  102. /package/dist/{chunk-NTLJ3INA.js.map → chunk-ZIWEEVMI.js.map} +0 -0
  103. /package/dist/{chunk-SHWGK7X6.js.map → chunk-ZM5JKJHI.js.map} +0 -0
  104. /package/dist/{cli-circuit-breaker-BIJUQRQI.js.map → cli-circuit-breaker-Y26NPPNO.js.map} +0 -0
  105. /package/dist/{codebase-search-PIBRTGBE.js.map → codebase-search-ZFJUVMVR.js.map} +0 -0
  106. /package/dist/{composite-router-FB7P22L5.js.map → composite-router-X2ZYIEHH.js.map} +0 -0
  107. /package/dist/{consensus-vote-KKAIFULI.js.map → consensus-vote-KZ6UURUI.js.map} +0 -0
  108. /package/dist/{context-retriever-4JCGMWH7.js.map → context-retriever-QY4FNTDZ.js.map} +0 -0
  109. /package/dist/{doctor-deep-7YK4BZIJ.js.map → doctor-deep-2E2GBMYR.js.map} +0 -0
  110. /package/dist/{expert-bridge-DJM5GAWZ.js.map → expert-bridge-FHPWDFJX.js.map} +0 -0
  111. /package/dist/{factory-DOWBGVAL.js.map → factory-STNVY3Y3.js.map} +0 -0
  112. /package/dist/{factory-PK4EZL7K.js.map → factory-W6KROBFN.js.map} +0 -0
  113. /package/dist/{init-opencode-QP5CAMWN.js.map → init-opencode-6LVZ4CAQ.js.map} +0 -0
  114. /package/dist/{issue-triage-T3SKNBH5.js.map → issue-triage-Y77JI7WF.js.map} +0 -0
  115. /package/dist/{registry-command-TH7U6UMC.js.map → registry-command-P5VIAEOL.js.map} +0 -0
  116. /package/dist/{repo-analyze-D2OY2QSR.js.map → repo-analyze-JZEMBE6R.js.map} +0 -0
  117. /package/dist/{repo-security-plan-V257RYTW.js.map → repo-security-plan-RHSLO7H6.js.map} +0 -0
  118. /package/dist/{research-helpers-synthesize-Y3O76PY4.js.map → research-helpers-synthesize-PVP6JRZV.js.map} +0 -0
  119. /package/dist/{routing-memory-AAH7NIHD.js.map → routing-memory-QRIJPRVD.js.map} +0 -0
  120. /package/dist/{session-memory-MY6YS2VX.js.map → session-memory-WARRGYY7.js.map} +0 -0
  121. /package/dist/{setup-command-B6EC3OJA.js.map → setup-command-GMP5FI7F.js.map} +0 -0
  122. /package/dist/{setup-config-HVO6ZSLW.js.map → setup-config-G3KKZM7O.js.map} +0 -0
  123. /package/dist/{setup-custom-api-UOIKUQL4.js.map → setup-custom-api-B63X7ISD.js.map} +0 -0
  124. /package/dist/{shared-memory-CM6T2MYE.js.map → tool-memory-E7JW4YLT.js.map} +0 -0
  125. /package/dist/{symbol-extractor-WYXPJH65.js.map → weather-report-RACZWJQL.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createLogger
3
- } from "./chunk-7VNVDFD5.js";
3
+ } from "./chunk-RXVH52UI.js";
4
4
  import "./chunk-I2HMWH4R.js";
5
5
  import "./chunk-PR4QN5HX.js";
6
6
 
@@ -59,4 +59,4 @@ export {
59
59
  generateMcpConfig,
60
60
  getDefaultAllowedTools
61
61
  };
62
- //# sourceMappingURL=child-mcp-config-BMSYR7VV.js.map
62
+ //# sourceMappingURL=child-mcp-config-XVPIO5HV.js.map
@@ -2,14 +2,14 @@ import {
2
2
  CircuitBreakerRegistry,
3
3
  CircuitError,
4
4
  mapCliErrorToCategory
5
- } from "./chunk-QHL4KGNB.js";
5
+ } from "./chunk-5T6SYCH2.js";
6
6
  import {
7
7
  createLogger,
8
8
  err,
9
9
  getFallbackChainForCategory,
10
10
  getTimeProvider,
11
11
  ok
12
- } from "./chunk-7VNVDFD5.js";
12
+ } from "./chunk-RXVH52UI.js";
13
13
 
14
14
  // src/cli-adapters/cli-circuit-breaker.ts
15
15
  var CATEGORY_TO_FALLBACK = {
@@ -152,4 +152,4 @@ export {
152
152
  CliCircuitBreakerIntegration,
153
153
  createCliCircuitBreakerIntegration
154
154
  };
155
- //# sourceMappingURL=chunk-OYDJ3C4N.js.map
155
+ //# sourceMappingURL=chunk-2W4QJ27D.js.map
@@ -1,3 +1,7 @@
1
+ // src/indexer/codebase-search.ts
2
+ import { readdir } from "fs/promises";
3
+ import { resolve, extname as extname2, relative } from "path";
4
+
1
5
  // src/indexer/symbol-extractor.ts
2
6
  import { readFile } from "fs/promises";
3
7
  import { extname } from "path";
@@ -120,8 +124,126 @@ async function extractSymbolIndex(filePath) {
120
124
  ${lines.join("\n")}`;
121
125
  }
122
126
 
127
+ // src/indexer/codebase-search.ts
128
+ var SCORE_EXACT = 20;
129
+ var SCORE_PREFIX = 10;
130
+ var SCORE_WORD = 5;
131
+ var SCORE_SUBSTRING = 2;
132
+ var SCORE_EXPORTED_BONUS = 3;
133
+ function isSourceFile(name) {
134
+ const ext = extname2(name).toLowerCase();
135
+ return [".ts", ".tsx", ".js", ".jsx"].includes(ext) && !name.endsWith(".test.ts") && !name.endsWith(".test.tsx") && !name.endsWith(".d.ts");
136
+ }
137
+ async function findSourceFiles(dir, maxDepth) {
138
+ if (maxDepth <= 0) return [];
139
+ const files = [];
140
+ const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
141
+ for (const entry of entries) {
142
+ const fullPath = resolve(dir, entry.name);
143
+ if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== "dist") {
144
+ files.push(...await findSourceFiles(fullPath, maxDepth - 1));
145
+ }
146
+ if (entry.isFile() && isSourceFile(entry.name)) {
147
+ files.push(fullPath);
148
+ }
149
+ }
150
+ return files;
151
+ }
152
+ function scoreMatch(symbolName, query) {
153
+ const nameLower = symbolName.toLowerCase();
154
+ const queryLower = query.toLowerCase();
155
+ if (nameLower === queryLower) return SCORE_EXACT;
156
+ if (nameLower.startsWith(queryLower)) return SCORE_PREFIX;
157
+ const words = symbolName.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(/[\s_-]+/);
158
+ if (words.some((w) => w === queryLower)) return SCORE_WORD;
159
+ if (nameLower.includes(queryLower)) return SCORE_SUBSTRING;
160
+ return null;
161
+ }
162
+ function getMatchType(score) {
163
+ if (score >= SCORE_EXACT) return "exact";
164
+ if (score >= SCORE_PREFIX) return "prefix";
165
+ if (score >= SCORE_WORD) return "word";
166
+ return "substring";
167
+ }
168
+ var CodebaseIndex = class {
169
+ symbols = [];
170
+ fileResults = /* @__PURE__ */ new Map();
171
+ rootDir;
172
+ constructor(rootDir) {
173
+ this.rootDir = rootDir;
174
+ }
175
+ /** Index all TS/JS source files in the directory. */
176
+ async index(maxDepth = 4) {
177
+ const files = await findSourceFiles(this.rootDir, maxDepth);
178
+ for (const file of files) {
179
+ const result = await extractSymbols(file);
180
+ const relPath = relative(this.rootDir, file);
181
+ this.fileResults.set(relPath, result);
182
+ for (const symbol of result.symbols) {
183
+ this.symbols.push({ ...symbol, filePath: relPath });
184
+ }
185
+ }
186
+ return {
187
+ totalFiles: files.length,
188
+ totalSymbols: this.symbols.length,
189
+ indexedAt: (/* @__PURE__ */ new Date()).toISOString()
190
+ };
191
+ }
192
+ /** Search symbols by keyword. Returns top N results sorted by relevance. */
193
+ search(query, limit = 20) {
194
+ const results = [];
195
+ for (const symbol of this.symbols) {
196
+ const baseScore = scoreMatch(symbol.name, query);
197
+ if (baseScore === null) continue;
198
+ const bonus = symbol.exported ? SCORE_EXPORTED_BONUS : 0;
199
+ results.push({
200
+ symbol,
201
+ score: baseScore + bonus,
202
+ matchType: getMatchType(baseScore)
203
+ });
204
+ }
205
+ return results.sort((a, b) => b.score - a.score).slice(0, limit);
206
+ }
207
+ /** Get a compact summary of a file's symbols. */
208
+ getFileSummary(filePath) {
209
+ const result = this.fileResults.get(filePath);
210
+ if (result === void 0) return void 0;
211
+ const kinds = {};
212
+ let exported = 0;
213
+ let priv = 0;
214
+ for (const s of result.symbols) {
215
+ kinds[s.kind] = (kinds[s.kind] ?? 0) + 1;
216
+ if (s.exported) exported++;
217
+ else priv++;
218
+ }
219
+ return {
220
+ filePath,
221
+ totalLines: result.totalLines,
222
+ exportedSymbols: exported,
223
+ privateSymbols: priv,
224
+ kinds
225
+ };
226
+ }
227
+ /** List all indexed files with symbol counts. */
228
+ listFiles() {
229
+ return [...this.fileResults.entries()].map(([path, result]) => ({
230
+ path,
231
+ symbols: result.symbols.length,
232
+ lines: result.totalLines
233
+ }));
234
+ }
235
+ /** Get index statistics. */
236
+ get stats() {
237
+ return {
238
+ files: this.fileResults.size,
239
+ symbols: this.symbols.length
240
+ };
241
+ }
242
+ };
243
+
123
244
  export {
124
245
  extractSymbols,
125
- extractSymbolIndex
246
+ extractSymbolIndex,
247
+ CodebaseIndex
126
248
  };
127
- //# sourceMappingURL=chunk-BQ4YXGGQ.js.map
249
+ //# sourceMappingURL=chunk-3ACDP4E6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/indexer/codebase-search.ts","../src/indexer/symbol-extractor.ts"],"sourcesContent":["/**\n * Codebase search — keyword search across symbol indices.\n *\n * Builds an in-memory symbol index for a directory of TS/JS files,\n * then supports keyword search, file summaries, and symbol lookup.\n *\n * Inspired by Augment Code's Context Engine. Uses the existing\n * extractSymbols() function for AST parsing.\n *\n * @module indexer/codebase-search\n */\n\nimport { readdir } from 'node:fs/promises';\nimport { resolve, extname, relative } from 'node:path';\nimport {\n extractSymbols,\n type CodeSymbol,\n type SymbolExtractionResult,\n} from './symbol-extractor.js';\n\n/** A symbol with its source file path. */\nexport interface IndexedSymbol extends CodeSymbol {\n /** Relative file path from the indexed root. */\n filePath: string;\n}\n\n/** Search result with relevance scoring. */\nexport interface SearchResult {\n symbol: IndexedSymbol;\n /** Relevance score (higher = better match). */\n score: number;\n /** How the query matched (exact, prefix, substring, word). */\n matchType: 'exact' | 'prefix' | 'substring' | 'word';\n}\n\n/** File summary — compact overview of a source file. */\nexport interface FileSummary {\n filePath: string;\n totalLines: number;\n exportedSymbols: number;\n privateSymbols: number;\n kinds: Record<string, number>;\n}\n\n/** Index statistics. */\nexport interface IndexStats {\n totalFiles: number;\n totalSymbols: number;\n indexedAt: string;\n}\n\n// Score weights for different match types\nconst SCORE_EXACT = 20;\nconst SCORE_PREFIX = 10;\nconst SCORE_WORD = 5;\nconst SCORE_SUBSTRING = 2;\nconst SCORE_EXPORTED_BONUS = 3;\n\nfunction isSourceFile(name: string): boolean {\n const ext = extname(name).toLowerCase();\n return (\n ['.ts', '.tsx', '.js', '.jsx'].includes(ext) &&\n !name.endsWith('.test.ts') &&\n !name.endsWith('.test.tsx') &&\n !name.endsWith('.d.ts')\n );\n}\n\nasync function findSourceFiles(dir: string, maxDepth: number): Promise<string[]> {\n if (maxDepth <= 0) return [];\n const files: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n const fullPath = resolve(dir, entry.name);\n if (entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== 'dist') {\n files.push(...(await findSourceFiles(fullPath, maxDepth - 1)));\n }\n if (entry.isFile() && isSourceFile(entry.name)) {\n files.push(fullPath);\n }\n }\n return files;\n}\n\nfunction scoreMatch(symbolName: string, query: string): SearchResult['score'] | null {\n const nameLower = symbolName.toLowerCase();\n const queryLower = query.toLowerCase();\n\n if (nameLower === queryLower) return SCORE_EXACT;\n if (nameLower.startsWith(queryLower)) return SCORE_PREFIX;\n\n // Word boundary match (camelCase splitting)\n const words = symbolName\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .toLowerCase()\n .split(/[\\s_-]+/);\n if (words.some((w) => w === queryLower)) return SCORE_WORD;\n\n if (nameLower.includes(queryLower)) return SCORE_SUBSTRING;\n\n return null;\n}\n\nfunction getMatchType(score: number): SearchResult['matchType'] {\n if (score >= SCORE_EXACT) return 'exact';\n if (score >= SCORE_PREFIX) return 'prefix';\n if (score >= SCORE_WORD) return 'word';\n return 'substring';\n}\n\n/** In-memory codebase symbol index. */\nexport class CodebaseIndex {\n private readonly symbols: IndexedSymbol[] = [];\n private readonly fileResults = new Map<string, SymbolExtractionResult>();\n private readonly rootDir: string;\n\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n /** Index all TS/JS source files in the directory. */\n async index(maxDepth = 4): Promise<IndexStats> {\n const files = await findSourceFiles(this.rootDir, maxDepth);\n\n for (const file of files) {\n const result = await extractSymbols(file);\n const relPath = relative(this.rootDir, file);\n this.fileResults.set(relPath, result);\n\n for (const symbol of result.symbols) {\n this.symbols.push({ ...symbol, filePath: relPath });\n }\n }\n\n return {\n totalFiles: files.length,\n totalSymbols: this.symbols.length,\n indexedAt: new Date().toISOString(),\n };\n }\n\n /** Search symbols by keyword. Returns top N results sorted by relevance. */\n search(query: string, limit = 20): SearchResult[] {\n const results: SearchResult[] = [];\n\n for (const symbol of this.symbols) {\n const baseScore = scoreMatch(symbol.name, query);\n if (baseScore === null) continue;\n\n const bonus = symbol.exported ? SCORE_EXPORTED_BONUS : 0;\n results.push({\n symbol,\n score: baseScore + bonus,\n matchType: getMatchType(baseScore),\n });\n }\n\n return results.sort((a, b) => b.score - a.score).slice(0, limit);\n }\n\n /** Get a compact summary of a file's symbols. */\n getFileSummary(filePath: string): FileSummary | undefined {\n const result = this.fileResults.get(filePath);\n if (result === undefined) return undefined;\n\n const kinds: Record<string, number> = {};\n let exported = 0;\n let priv = 0;\n\n for (const s of result.symbols) {\n kinds[s.kind] = (kinds[s.kind] ?? 0) + 1;\n if (s.exported) exported++;\n else priv++;\n }\n\n return {\n filePath,\n totalLines: result.totalLines,\n exportedSymbols: exported,\n privateSymbols: priv,\n kinds,\n };\n }\n\n /** List all indexed files with symbol counts. */\n listFiles(): Array<{ path: string; symbols: number; lines: number }> {\n return [...this.fileResults.entries()].map(([path, result]) => ({\n path,\n symbols: result.symbols.length,\n lines: result.totalLines,\n }));\n }\n\n /** Get index statistics. */\n get stats(): { files: number; symbols: number } {\n return {\n files: this.fileResults.size,\n symbols: this.symbols.length,\n };\n }\n}\n","/**\n * AST symbol extraction for token-efficient code retrieval.\n *\n * Uses TypeScript's compiler API to extract function, class, method,\n * interface, and type definitions from source files.\n *\n * Token savings: ~80-99% vs reading full files.\n * No additional dependencies — uses TypeScript (already a project dep).\n *\n * @module indexer/symbol-extractor\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport ts from 'typescript';\n\n/** A symbol extracted from source code. */\nexport interface CodeSymbol {\n /** Symbol name */\n name: string;\n /** Symbol kind */\n kind: 'function' | 'class' | 'method' | 'interface' | 'type' | 'variable' | 'enum';\n /** Start line (1-based) */\n startLine: number;\n /** End line (1-based) */\n endLine: number;\n /** Full source text of the symbol */\n text: string;\n /** Whether the symbol is exported */\n exported: boolean;\n}\n\n/** Result of extracting symbols from a file. */\nexport interface SymbolExtractionResult {\n filePath: string;\n symbols: CodeSymbol[];\n totalLines: number;\n totalChars: number;\n symbolChars: number;\n savingsPercent: number;\n}\n\nfunction getKind(node: ts.Node): CodeSymbol['kind'] | null {\n if (ts.isFunctionDeclaration(node)) return 'function';\n if (ts.isClassDeclaration(node)) return 'class';\n if (ts.isInterfaceDeclaration(node)) return 'interface';\n if (ts.isTypeAliasDeclaration(node)) return 'type';\n if (ts.isEnumDeclaration(node)) return 'enum';\n if (ts.isMethodDeclaration(node)) return 'method';\n if (ts.isVariableStatement(node)) return 'variable';\n return null;\n}\n\nfunction getName(node: ts.Node): string {\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isClassDeclaration(node) ||\n ts.isInterfaceDeclaration(node) ||\n ts.isTypeAliasDeclaration(node) ||\n ts.isEnumDeclaration(node) ||\n ts.isMethodDeclaration(node)\n ) {\n const nameNode = (node as ts.NamedDeclaration).name;\n return nameNode ? nameNode.getText() : '<anonymous>';\n }\n if (ts.isVariableStatement(node)) {\n const decls = node.declarationList.declarations;\n const firstDecl = decls[0];\n if (firstDecl !== undefined) {\n return firstDecl.name.getText();\n }\n }\n return '<anonymous>';\n}\n\nfunction isExported(node: ts.Node): boolean {\n const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;\n if (modifiers) {\n return modifiers.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);\n }\n return false;\n}\n\nfunction visitNode(node: ts.Node, sourceFile: ts.SourceFile, symbols: CodeSymbol[]): void {\n const kind = getKind(node);\n if (kind !== null) {\n const name = getName(node);\n if (name !== '<anonymous>') {\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n symbols.push({\n name,\n kind,\n startLine: start.line + 1,\n endLine: end.line + 1,\n text: node.getText(sourceFile),\n exported: isExported(node),\n });\n }\n }\n if (ts.isClassDeclaration(node)) {\n visitClassMembers(node, sourceFile, symbols);\n return;\n }\n ts.forEachChild(node, (child) => {\n visitNode(child, sourceFile, symbols);\n });\n}\n\nfunction visitClassMembers(\n node: ts.ClassDeclaration,\n sourceFile: ts.SourceFile,\n symbols: CodeSymbol[]\n): void {\n for (const member of node.members) {\n if (ts.isMethodDeclaration(member) || ts.isPropertyDeclaration(member)) {\n const memberName = member.name.getText();\n if (memberName !== '<anonymous>') {\n const start = sourceFile.getLineAndCharacterOfPosition(member.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(member.getEnd());\n symbols.push({\n name: memberName,\n kind: 'method',\n startLine: start.line + 1,\n endLine: end.line + 1,\n text: member.getText(sourceFile),\n exported: false,\n });\n }\n }\n }\n}\n\nfunction computeSavings(totalChars: number, symbolChars: number): number {\n return totalChars > 0 ? Math.round(100 * (1 - symbolChars / totalChars) * 10) / 10 : 0;\n}\n\n/**\n * Extract symbols from a TypeScript/JavaScript file.\n */\nexport async function extractSymbols(filePath: string): Promise<SymbolExtractionResult> {\n const ext = extname(filePath).toLowerCase();\n if (!['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {\n return {\n filePath,\n symbols: [],\n totalLines: 0,\n totalChars: 0,\n symbolChars: 0,\n savingsPercent: 0,\n };\n }\n\n const source = await readFile(filePath, 'utf-8');\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n const symbols: CodeSymbol[] = [];\n\n ts.forEachChild(sourceFile, (node) => {\n visitNode(node, sourceFile, symbols);\n });\n\n const totalChars = source.length;\n const symbolChars = symbols.reduce((sum, s) => sum + s.text.length, 0);\n\n return {\n filePath,\n symbols,\n totalLines: source.split('\\n').length,\n totalChars,\n symbolChars,\n savingsPercent: computeSavings(totalChars, symbolChars),\n };\n}\n\n/**\n * Extract a compact symbol index (names + locations only, no source text).\n * This is the minimal representation for LLM context — ~95%+ token savings.\n */\nexport async function extractSymbolIndex(filePath: string): Promise<string> {\n const result = await extractSymbols(filePath);\n if (result.symbols.length === 0) return '';\n\n const lines = result.symbols.map((s) => {\n const exp = s.exported ? 'export ' : '';\n return `${exp}${s.kind} ${s.name} (L${String(s.startLine)}-${String(s.endLine)})`;\n });\n\n return `// ${filePath} — ${String(result.symbols.length)} symbols\\n${lines.join('\\n')}`;\n}\n"],"mappings":";AAYA,SAAS,eAAe;AACxB,SAAS,SAAS,WAAAA,UAAS,gBAAgB;;;ACD3C,SAAS,gBAAgB;AACzB,SAAS,eAAe;AACxB,OAAO,QAAQ;AA4Bf,SAAS,QAAQ,MAA0C;AACzD,MAAI,GAAG,sBAAsB,IAAI,EAAG,QAAO;AAC3C,MAAI,GAAG,mBAAmB,IAAI,EAAG,QAAO;AACxC,MAAI,GAAG,uBAAuB,IAAI,EAAG,QAAO;AAC5C,MAAI,GAAG,uBAAuB,IAAI,EAAG,QAAO;AAC5C,MAAI,GAAG,kBAAkB,IAAI,EAAG,QAAO;AACvC,MAAI,GAAG,oBAAoB,IAAI,EAAG,QAAO;AACzC,MAAI,GAAG,oBAAoB,IAAI,EAAG,QAAO;AACzC,SAAO;AACT;AAEA,SAAS,QAAQ,MAAuB;AACtC,MACE,GAAG,sBAAsB,IAAI,KAC7B,GAAG,mBAAmB,IAAI,KAC1B,GAAG,uBAAuB,IAAI,KAC9B,GAAG,uBAAuB,IAAI,KAC9B,GAAG,kBAAkB,IAAI,KACzB,GAAG,oBAAoB,IAAI,GAC3B;AACA,UAAM,WAAY,KAA6B;AAC/C,WAAO,WAAW,SAAS,QAAQ,IAAI;AAAA,EACzC;AACA,MAAI,GAAG,oBAAoB,IAAI,GAAG;AAChC,UAAM,QAAQ,KAAK,gBAAgB;AACnC,UAAM,YAAY,MAAM,CAAC;AACzB,QAAI,cAAc,QAAW;AAC3B,aAAO,UAAU,KAAK,QAAQ;AAAA,IAChC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAAwB;AAC1C,QAAM,YAAY,GAAG,iBAAiB,IAAI,IAAI,GAAG,aAAa,IAAI,IAAI;AACtE,MAAI,WAAW;AACb,WAAO,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG,WAAW,aAAa;AAAA,EACrE;AACA,SAAO;AACT;AAEA,SAAS,UAAU,MAAe,YAA2B,SAA6B;AACxF,QAAM,OAAO,QAAQ,IAAI;AACzB,MAAI,SAAS,MAAM;AACjB,UAAM,OAAO,QAAQ,IAAI;AACzB,QAAI,SAAS,eAAe;AAC1B,YAAM,QAAQ,WAAW,8BAA8B,KAAK,SAAS,CAAC;AACtE,YAAM,MAAM,WAAW,8BAA8B,KAAK,OAAO,CAAC;AAClE,cAAQ,KAAK;AAAA,QACX;AAAA,QACA;AAAA,QACA,WAAW,MAAM,OAAO;AAAA,QACxB,SAAS,IAAI,OAAO;AAAA,QACpB,MAAM,KAAK,QAAQ,UAAU;AAAA,QAC7B,UAAU,WAAW,IAAI;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI,GAAG,mBAAmB,IAAI,GAAG;AAC/B,sBAAkB,MAAM,YAAY,OAAO;AAC3C;AAAA,EACF;AACA,KAAG,aAAa,MAAM,CAAC,UAAU;AAC/B,cAAU,OAAO,YAAY,OAAO;AAAA,EACtC,CAAC;AACH;AAEA,SAAS,kBACP,MACA,YACA,SACM;AACN,aAAW,UAAU,KAAK,SAAS;AACjC,QAAI,GAAG,oBAAoB,MAAM,KAAK,GAAG,sBAAsB,MAAM,GAAG;AACtE,YAAM,aAAa,OAAO,KAAK,QAAQ;AACvC,UAAI,eAAe,eAAe;AAChC,cAAM,QAAQ,WAAW,8BAA8B,OAAO,SAAS,CAAC;AACxE,cAAM,MAAM,WAAW,8BAA8B,OAAO,OAAO,CAAC;AACpE,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM;AAAA,UACN,WAAW,MAAM,OAAO;AAAA,UACxB,SAAS,IAAI,OAAO;AAAA,UACpB,MAAM,OAAO,QAAQ,UAAU;AAAA,UAC/B,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,eAAe,YAAoB,aAA6B;AACvE,SAAO,aAAa,IAAI,KAAK,MAAM,OAAO,IAAI,cAAc,cAAc,EAAE,IAAI,KAAK;AACvF;AAKA,eAAsB,eAAe,UAAmD;AACtF,QAAM,MAAM,QAAQ,QAAQ,EAAE,YAAY;AAC1C,MAAI,CAAC,CAAC,OAAO,QAAQ,OAAO,MAAM,EAAE,SAAS,GAAG,GAAG;AACjD,WAAO;AAAA,MACL;AAAA,MACA,SAAS,CAAC;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,gBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,SAAS,UAAU,OAAO;AAC/C,QAAM,aAAa,GAAG,iBAAiB,UAAU,QAAQ,GAAG,aAAa,QAAQ,IAAI;AACrF,QAAM,UAAwB,CAAC;AAE/B,KAAG,aAAa,YAAY,CAAC,SAAS;AACpC,cAAU,MAAM,YAAY,OAAO;AAAA,EACrC,CAAC;AAED,QAAM,aAAa,OAAO;AAC1B,QAAM,cAAc,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,KAAK,QAAQ,CAAC;AAErE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY,OAAO,MAAM,IAAI,EAAE;AAAA,IAC/B;AAAA,IACA;AAAA,IACA,gBAAgB,eAAe,YAAY,WAAW;AAAA,EACxD;AACF;AAMA,eAAsB,mBAAmB,UAAmC;AAC1E,QAAM,SAAS,MAAM,eAAe,QAAQ;AAC5C,MAAI,OAAO,QAAQ,WAAW,EAAG,QAAO;AAExC,QAAM,QAAQ,OAAO,QAAQ,IAAI,CAAC,MAAM;AACtC,UAAM,MAAM,EAAE,WAAW,YAAY;AACrC,WAAO,GAAG,GAAG,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,MAAM,OAAO,EAAE,SAAS,CAAC,IAAI,OAAO,EAAE,OAAO,CAAC;AAAA,EAChF,CAAC;AAED,SAAO,MAAM,QAAQ,WAAM,OAAO,OAAO,QAAQ,MAAM,CAAC;AAAA,EAAa,MAAM,KAAK,IAAI,CAAC;AACvF;;;ADxIA,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,aAAa;AACnB,IAAM,kBAAkB;AACxB,IAAM,uBAAuB;AAE7B,SAAS,aAAa,MAAuB;AAC3C,QAAM,MAAMC,SAAQ,IAAI,EAAE,YAAY;AACtC,SACE,CAAC,OAAO,QAAQ,OAAO,MAAM,EAAE,SAAS,GAAG,KAC3C,CAAC,KAAK,SAAS,UAAU,KACzB,CAAC,KAAK,SAAS,WAAW,KAC1B,CAAC,KAAK,SAAS,OAAO;AAE1B;AAEA,eAAe,gBAAgB,KAAa,UAAqC;AAC/E,MAAI,YAAY,EAAG,QAAO,CAAC;AAC3B,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC,CAAC;AAC1E,aAAW,SAAS,SAAS;AAC3B,UAAM,WAAW,QAAQ,KAAK,MAAM,IAAI;AACxC,QAAI,MAAM,YAAY,KAAK,MAAM,SAAS,kBAAkB,MAAM,SAAS,QAAQ;AACjF,YAAM,KAAK,GAAI,MAAM,gBAAgB,UAAU,WAAW,CAAC,CAAE;AAAA,IAC/D;AACA,QAAI,MAAM,OAAO,KAAK,aAAa,MAAM,IAAI,GAAG;AAC9C,YAAM,KAAK,QAAQ;AAAA,IACrB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,YAAoB,OAA6C;AACnF,QAAM,YAAY,WAAW,YAAY;AACzC,QAAM,aAAa,MAAM,YAAY;AAErC,MAAI,cAAc,WAAY,QAAO;AACrC,MAAI,UAAU,WAAW,UAAU,EAAG,QAAO;AAG7C,QAAM,QAAQ,WACX,QAAQ,mBAAmB,OAAO,EAClC,YAAY,EACZ,MAAM,SAAS;AAClB,MAAI,MAAM,KAAK,CAAC,MAAM,MAAM,UAAU,EAAG,QAAO;AAEhD,MAAI,UAAU,SAAS,UAAU,EAAG,QAAO;AAE3C,SAAO;AACT;AAEA,SAAS,aAAa,OAA0C;AAC9D,MAAI,SAAS,YAAa,QAAO;AACjC,MAAI,SAAS,aAAc,QAAO;AAClC,MAAI,SAAS,WAAY,QAAO;AAChC,SAAO;AACT;AAGO,IAAM,gBAAN,MAAoB;AAAA,EACR,UAA2B,CAAC;AAAA,EAC5B,cAAc,oBAAI,IAAoC;AAAA,EACtD;AAAA,EAEjB,YAAY,SAAiB;AAC3B,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EAGA,MAAM,MAAM,WAAW,GAAwB;AAC7C,UAAM,QAAQ,MAAM,gBAAgB,KAAK,SAAS,QAAQ;AAE1D,eAAW,QAAQ,OAAO;AACxB,YAAM,SAAS,MAAM,eAAe,IAAI;AACxC,YAAM,UAAU,SAAS,KAAK,SAAS,IAAI;AAC3C,WAAK,YAAY,IAAI,SAAS,MAAM;AAEpC,iBAAW,UAAU,OAAO,SAAS;AACnC,aAAK,QAAQ,KAAK,EAAE,GAAG,QAAQ,UAAU,QAAQ,CAAC;AAAA,MACpD;AAAA,IACF;AAEA,WAAO;AAAA,MACL,YAAY,MAAM;AAAA,MAClB,cAAc,KAAK,QAAQ;AAAA,MAC3B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,OAAe,QAAQ,IAAoB;AAChD,UAAM,UAA0B,CAAC;AAEjC,eAAW,UAAU,KAAK,SAAS;AACjC,YAAM,YAAY,WAAW,OAAO,MAAM,KAAK;AAC/C,UAAI,cAAc,KAAM;AAExB,YAAM,QAAQ,OAAO,WAAW,uBAAuB;AACvD,cAAQ,KAAK;AAAA,QACX;AAAA,QACA,OAAO,YAAY;AAAA,QACnB,WAAW,aAAa,SAAS;AAAA,MACnC,CAAC;AAAA,IACH;AAEA,WAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK;AAAA,EACjE;AAAA;AAAA,EAGA,eAAe,UAA2C;AACxD,UAAM,SAAS,KAAK,YAAY,IAAI,QAAQ;AAC5C,QAAI,WAAW,OAAW,QAAO;AAEjC,UAAM,QAAgC,CAAC;AACvC,QAAI,WAAW;AACf,QAAI,OAAO;AAEX,eAAW,KAAK,OAAO,SAAS;AAC9B,YAAM,EAAE,IAAI,KAAK,MAAM,EAAE,IAAI,KAAK,KAAK;AACvC,UAAI,EAAE,SAAU;AAAA,UACX;AAAA,IACP;AAEA,WAAO;AAAA,MACL;AAAA,MACA,YAAY,OAAO;AAAA,MACnB,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,YAAqE;AACnE,WAAO,CAAC,GAAG,KAAK,YAAY,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,MAAM,OAAO;AAAA,MAC9D;AAAA,MACA,SAAS,OAAO,QAAQ;AAAA,MACxB,OAAO,OAAO;AAAA,IAChB,EAAE;AAAA,EACJ;AAAA;AAAA,EAGA,IAAI,QAA4C;AAC9C,WAAO;AAAA,MACL,OAAO,KAAK,YAAY;AAAA,MACxB,SAAS,KAAK,QAAQ;AAAA,IACxB;AAAA,EACF;AACF;","names":["extname","extname"]}
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  resolveToken
3
- } from "./chunk-G2DZBEMU.js";
3
+ } from "./chunk-Z64MSLEK.js";
4
4
  import {
5
5
  GitHubProvider,
6
6
  ScmError
7
- } from "./chunk-PZESEBD3.js";
7
+ } from "./chunk-L362KRSU.js";
8
8
  import {
9
9
  err,
10
10
  ok
11
- } from "./chunk-7VNVDFD5.js";
11
+ } from "./chunk-RXVH52UI.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-C7P2HLJX.js.map
44
+ //# sourceMappingURL=chunk-3ASED5PR.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  getToolMemory
3
- } from "./chunk-U7JXQSEM.js";
3
+ } from "./chunk-YO27YAEX.js";
4
4
  import {
5
5
  CLI_NAMES,
6
6
  StrategyDistiller,
7
7
  createLogger,
8
8
  getOutcomeStore,
9
9
  registerPersistentDistillerFactory
10
- } from "./chunk-7VNVDFD5.js";
10
+ } from "./chunk-RXVH52UI.js";
11
11
  import {
12
12
  ensureLearningDir,
13
13
  getRulesFile
@@ -273,4 +273,4 @@ export {
273
273
  inferTaskCategory,
274
274
  summarizeContextForPrompt
275
275
  };
276
- //# sourceMappingURL=chunk-TXIUCEFT.js.map
276
+ //# sourceMappingURL=chunk-3GJAAENS.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_MODEL_PER_CLI,
3
3
  getTimeProvider
4
- } from "./chunk-7VNVDFD5.js";
4
+ } from "./chunk-RXVH52UI.js";
5
5
 
6
6
  // src/config/model-availability.ts
7
7
  var DEFAULT_TTL_MS = 6e4;
@@ -133,4 +133,4 @@ export {
133
133
  resetAvailabilityCache,
134
134
  filterAvailableModels
135
135
  };
136
- //# sourceMappingURL=chunk-GNG7URCR.js.map
136
+ //# sourceMappingURL=chunk-3WUVWZUC.js.map
@@ -1,24 +1,24 @@
1
- import {
2
- CUSTOM_API_BASE_URL_ENV,
3
- PROVIDER_ENV_KEYS,
4
- validateCustomApiBaseUrl
5
- } from "./chunk-NTLJ3INA.js";
6
1
  import {
7
2
  AdapterModelError,
8
3
  BaseAdapter,
9
4
  createStream,
10
5
  requireApiKey,
11
6
  validateApiKeyPresence
12
- } from "./chunk-SBZVRH4S.js";
7
+ } from "./chunk-54UXPJVM.js";
8
+ import {
9
+ CUSTOM_API_BASE_URL_ENV,
10
+ PROVIDER_ENV_KEYS,
11
+ validateCustomApiBaseUrl
12
+ } from "./chunk-ZIWEEVMI.js";
13
13
  import {
14
14
  getToolMemory
15
- } from "./chunk-U7JXQSEM.js";
15
+ } from "./chunk-YO27YAEX.js";
16
16
  import {
17
17
  getDefaultAvailableModelsCache
18
- } from "./chunk-WUUEKFKG.js";
18
+ } from "./chunk-Q6PZMGLU.js";
19
19
  import {
20
20
  CUSTOM_API_DEFAULT_MODEL
21
- } from "./chunk-SHWGK7X6.js";
21
+ } from "./chunk-ZM5JKJHI.js";
22
22
  import {
23
23
  createCliAdapter,
24
24
  createCliDetectionCache,
@@ -27,7 +27,7 @@ import {
27
27
  isCliAvailable,
28
28
  sanitizeOutput,
29
29
  withTimeout
30
- } from "./chunk-2SQXJQTA.js";
30
+ } from "./chunk-FHGDJKCZ.js";
31
31
  import {
32
32
  AgentError,
33
33
  CACHE_TIMEOUTS,
@@ -70,7 +70,7 @@ import {
70
70
  resolveCliAlias,
71
71
  resolveVoteTimeout,
72
72
  toRateLimitError
73
- } from "./chunk-7VNVDFD5.js";
73
+ } from "./chunk-RXVH52UI.js";
74
74
  import {
75
75
  ensureLearningDir,
76
76
  getNexusDataDir,
@@ -1345,11 +1345,15 @@ function toSdkCallback(handler) {
1345
1345
  }
1346
1346
  var MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS = 6e4;
1347
1347
  var TIMEOUT_MISMATCH_TELEMETRY_REL_PATH = "mcp-telemetry/timeout-mismatch-events.jsonl";
1348
+ var ensuredDirs = /* @__PURE__ */ new Set();
1348
1349
  function appendTimeoutMismatchEvent(event) {
1349
1350
  try {
1350
1351
  const path = join(getNexusDataDir(), TIMEOUT_MISMATCH_TELEMETRY_REL_PATH);
1351
1352
  const dir = dirname(path);
1352
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
1353
+ if (!ensuredDirs.has(dir)) {
1354
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
1355
+ ensuredDirs.add(dir);
1356
+ }
1353
1357
  appendFileSync(path, JSON.stringify(event) + "\n", "utf-8");
1354
1358
  } catch (err2) {
1355
1359
  wrapperLogger.debug("Best-effort timeout-mismatch event recording failed", {
@@ -3635,12 +3639,24 @@ async function pickFallback(retiredModelId, cache, registry) {
3635
3639
  }
3636
3640
  function wrapResilientWithFallback(inner, options = {}) {
3637
3641
  const wrapped = withModelNotFoundFallback(inner, options);
3638
- return Object.assign(wrapped, {
3642
+ const surface = {
3639
3643
  getHealth: inner.getHealth.bind(inner),
3640
3644
  refresh: inner.refresh.bind(inner),
3641
3645
  setPreferredCli: inner.setPreferredCli.bind(inner),
3642
3646
  onFailover: inner.onFailover.bind(inner),
3643
3647
  dispose: inner.dispose.bind(inner)
3648
+ };
3649
+ const explicit = Object.assign(wrapped, surface);
3650
+ const innerAsRecord = inner;
3651
+ return new Proxy(explicit, {
3652
+ get(target, prop, receiver) {
3653
+ if (prop in target) return Reflect.get(target, prop, receiver);
3654
+ const innerProp = innerAsRecord[prop];
3655
+ if (typeof innerProp === "function") {
3656
+ return innerProp.bind(inner);
3657
+ }
3658
+ return innerProp;
3659
+ }
3644
3660
  });
3645
3661
  }
3646
3662
 
@@ -8705,7 +8721,7 @@ async function processVotesWithCascade(engineVotes, opts) {
8705
8721
  var CONTRARIAN_ESCALATION_THRESHOLD = 0.8;
8706
8722
  async function runContrarianCheck(proposal, log) {
8707
8723
  try {
8708
- const { executeExpert } = await import("./expert-bridge-DJM5GAWZ.js");
8724
+ const { executeExpert } = await import("./expert-bridge-FHPWDFJX.js");
8709
8725
  const prompt = [
8710
8726
  "You are a contrarian analyst. Your job is to find reasons this proposal should be REJECTED.",
8711
8727
  "Look for: YAGNI (not needed), MISALIGNED (wrong tech/architecture), SECURITY_RISK, SCOPE_CREEP.",
@@ -8733,7 +8749,9 @@ async function runContrarianCheck(proposal, log) {
8733
8749
  return { shouldEscalate: true, reason: reasoning, confidence };
8734
8750
  }
8735
8751
  return { shouldEscalate: false, reason: "", confidence };
8736
- } catch {
8752
+ } catch (error) {
8753
+ const message = error instanceof Error ? error.message : String(error);
8754
+ log.warn("Contrarian check failed; defaulting to no escalation", { error: message });
8737
8755
  return { shouldEscalate: false, reason: "", confidence: 0 };
8738
8756
  }
8739
8757
  }
@@ -9122,4 +9140,4 @@ export {
9122
9140
  CONSENSUS_VOTE_OUTPUT_SCHEMA,
9123
9141
  registerConsensusVoteTool
9124
9142
  };
9125
- //# sourceMappingURL=chunk-FTT2IYYX.js.map
9143
+ //# sourceMappingURL=chunk-4BXQ2OZY.js.map