@wrongstack/tools 0.317.0 → 0.317.2

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 (109) hide show
  1. package/dist/_spawn-stream.d.ts +1 -1
  2. package/dist/audit.d.ts +37 -2
  3. package/dist/audit.js +4 -4
  4. package/dist/bash.js +1 -1
  5. package/dist/batch-tool-use.js +1 -1
  6. package/dist/browser/index.js +1 -1
  7. package/dist/browser/tools.d.ts +16 -1
  8. package/dist/builtin.js +43 -43
  9. package/dist/{chunk-SDLVH5RZ.js → chunk-3QQSBUXR.js} +6 -5
  10. package/dist/{chunk-K3WNSHUF.js → chunk-45JPRMC2.js} +62 -36
  11. package/dist/{chunk-EJWSCQ6D.js → chunk-4AEZIFOW.js} +6 -5
  12. package/dist/{chunk-PQKK5JH7.js → chunk-4E42D7UF.js} +2 -2
  13. package/dist/{chunk-JRJJX3L5.js → chunk-5WNDJHT6.js} +3 -2
  14. package/dist/{chunk-7EY5DCRO.js → chunk-5ZYEGP2P.js} +4 -4
  15. package/dist/{chunk-HPEO4EA7.js → chunk-6RR5VX6U.js} +35 -17
  16. package/dist/{chunk-QDQY7NQ2.js → chunk-A2PX7M7A.js} +5 -5
  17. package/dist/{chunk-JQRIR762.js → chunk-AK2K4KHR.js} +27 -19
  18. package/dist/{chunk-P7FYFZ6M.js → chunk-BANPF4LY.js} +11 -7
  19. package/dist/{chunk-RGISBZBD.js → chunk-CPSAF2AU.js} +3 -2
  20. package/dist/{chunk-BSLVR56S.js → chunk-CPVLVQYT.js} +6 -5
  21. package/dist/{chunk-VJNHFZ7J.js → chunk-CVALEVGA.js} +6 -5
  22. package/dist/{chunk-PY2IOS7C.js → chunk-CWALNI6K.js} +5 -5
  23. package/dist/{chunk-LIJQMYYX.js → chunk-ELFFQ4RU.js} +7 -3
  24. package/dist/{chunk-JNNVRHMV.js → chunk-FJEQZHZN.js} +8 -8
  25. package/dist/{chunk-S5CCLZL3.js → chunk-FRN7TIAA.js} +2 -2
  26. package/dist/{chunk-PCHQ6YRR.js → chunk-FYDKHXN7.js} +2 -2
  27. package/dist/{chunk-NKJW5GFO.js → chunk-H6AWAZ2Y.js} +3 -3
  28. package/dist/{chunk-IVWV2UM6.js → chunk-HTYEO67J.js} +6 -5
  29. package/dist/{chunk-UNSKG6DC.js → chunk-ICAXDRP6.js} +10 -15
  30. package/dist/{chunk-IYK7XGDZ.js → chunk-JJQB6R7Y.js} +7 -7
  31. package/dist/{chunk-LWKUTMD5.js → chunk-MRZOVQ5D.js} +6 -5
  32. package/dist/{chunk-YGG6X57C.js → chunk-NKX4SJ5R.js} +12 -9
  33. package/dist/{chunk-U4D5S3VQ.js → chunk-NWZ6XGBJ.js} +2 -1
  34. package/dist/{chunk-UKU2ZX4C.js → chunk-P7ZQ2FAJ.js} +27 -17
  35. package/dist/{chunk-4I4LWFOO.js → chunk-PQTONQ4P.js} +16 -11
  36. package/dist/{chunk-XGHMUZ77.js → chunk-RMB76PDS.js} +3 -3
  37. package/dist/{chunk-5OAOKALG.js → chunk-RUOMW2I6.js} +4 -3
  38. package/dist/{chunk-553IQUMO.js → chunk-S2JRYDYG.js} +7 -6
  39. package/dist/{chunk-OUBDL3WH.js → chunk-SOG7XIRF.js} +11 -8
  40. package/dist/{chunk-U6DZWHBA.js → chunk-TDLZIDCY.js} +9 -7
  41. package/dist/{chunk-TRDX25UH.js → chunk-TFEGJDH5.js} +293 -86
  42. package/dist/{chunk-AHHDWNXC.js → chunk-TKA4VEX2.js} +2 -2
  43. package/dist/{chunk-5H4GSJAI.js → chunk-UE3UBMCP.js} +7 -6
  44. package/dist/{chunk-IXMNTNW5.js → chunk-UKGMDCXT.js} +4 -3
  45. package/dist/{chunk-VGBUDLW4.js → chunk-UOXX4SQZ.js} +7 -6
  46. package/dist/{chunk-T2F4S7U4.js → chunk-WI3VDXHD.js} +18 -8
  47. package/dist/{chunk-O4MBV4AX.js → chunk-WJYXMB2R.js} +6 -5
  48. package/dist/{chunk-U4VAATKP.js → chunk-WXJY3BKV.js} +16 -6
  49. package/dist/{chunk-DR7JOQTC.js → chunk-X5K3U6GI.js} +3 -3
  50. package/dist/{chunk-DSEANA2W.js → chunk-XVGB6KYU.js} +37 -36
  51. package/dist/{chunk-TEBQ4VPZ.js → chunk-YOHO4DVT.js} +6 -5
  52. package/dist/{chunk-RXISBFR5.js → chunk-ZE6KLBUO.js} +5 -4
  53. package/dist/{chunk-22B7GE5T.js → chunk-ZHH3BEWU.js} +13 -12
  54. package/dist/codebase-index/bm25.d.ts +14 -1
  55. package/dist/codebase-index/index.js +8 -8
  56. package/dist/codebase-index/json-parser.d.ts +4 -0
  57. package/dist/codebase-index/parser-worker-script.js +2 -2
  58. package/dist/codebase-index/project-server.js +48 -9
  59. package/dist/codebase-index/worker.js +4 -4
  60. package/dist/codebase-index/writer-bulk-insert.d.ts +0 -1
  61. package/dist/codebase-index/writer-schema.d.ts +1 -1
  62. package/dist/codebase-index/writer.d.ts +38 -0
  63. package/dist/diff.js +1 -1
  64. package/dist/e2e.d.ts +40 -1
  65. package/dist/e2e.js +1 -1
  66. package/dist/edit.js +7 -7
  67. package/dist/exec.js +1 -1
  68. package/dist/fetch.js +1 -1
  69. package/dist/format.d.ts +42 -2
  70. package/dist/format.js +4 -4
  71. package/dist/git.d.ts +70 -1
  72. package/dist/git.js +1 -1
  73. package/dist/glob.js +3 -3
  74. package/dist/{go-parser-JXYKJHRC.js → go-parser-IKHW67WE.js} +2 -2
  75. package/dist/grep.js +3 -3
  76. package/dist/index.js +45 -45
  77. package/dist/install.d.ts +51 -2
  78. package/dist/install.js +4 -4
  79. package/dist/{json-parser-IBHZ4BZC.js → json-parser-2EOVP5MR.js} +81 -15
  80. package/dist/kanban.d.ts +19 -1
  81. package/dist/kanban.js +2 -2
  82. package/dist/languages/index.js +2 -2
  83. package/dist/{legacy-bridge-7M6QLUQN.js → legacy-bridge-SFNXIRAP.js} +4 -4
  84. package/dist/lint.js +4 -4
  85. package/dist/logs.js +1 -1
  86. package/dist/outdated.d.ts +25 -1
  87. package/dist/outdated.js +1 -1
  88. package/dist/pack.js +44 -44
  89. package/dist/{parser-dispatch-QH4XPGG6.js → parser-dispatch-X62UWXJS.js} +3 -3
  90. package/dist/patch.js +7 -7
  91. package/dist/plan.js +4 -4
  92. package/dist/{py-parser-IS4HKYMF.js → py-parser-TDXSQZBC.js} +2 -2
  93. package/dist/read.js +7 -7
  94. package/dist/replace.js +7 -7
  95. package/dist/{rs-parser-XHUUO2KZ.js → rs-parser-GIWPUA3T.js} +2 -2
  96. package/dist/scaffold.js +1 -1
  97. package/dist/search.js +1 -1
  98. package/dist/session-kanban.js +1 -1
  99. package/dist/task.js +4 -4
  100. package/dist/test.js +4 -4
  101. package/dist/todo.js +3 -3
  102. package/dist/tool-diff.js +1 -1
  103. package/dist/tool-tier.js +45 -45
  104. package/dist/tool-use.js +1 -1
  105. package/dist/{ts-parser-RCTYKSVI.js → ts-parser-7W26YB26.js} +2 -2
  106. package/dist/typecheck.js +4 -4
  107. package/dist/write.js +7 -7
  108. package/dist/{yaml-parser-4SAXV3PL.js → yaml-parser-RGBXEZE4.js} +2 -2
  109. package/package.json +5 -5
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  parseFilesContent
3
- } from "./chunk-IYK7XGDZ.js";
3
+ } from "./chunk-JJQB6R7Y.js";
4
4
  import {
5
5
  INDEXABLE_EXTENSIONS,
6
6
  LANG_FAMILY_ENTRIES,
7
7
  detectLang,
8
8
  languageFamily
9
- } from "./chunk-TEBQ4VPZ.js";
9
+ } from "./chunk-YOHO4DVT.js";
10
10
  import {
11
11
  loadGitignoreMatcher
12
- } from "./chunk-LIJQMYYX.js";
12
+ } from "./chunk-ELFFQ4RU.js";
13
13
 
14
14
  // src/codebase-index/circuit-breaker.ts
15
15
  var CircuitOpenError = class extends Error {
@@ -99,13 +99,59 @@ var K1 = 1.5;
99
99
  var B = 0.75;
100
100
  var TOKENISE_RE = new RegExp("[^\\p{L}\\p{N}$']", "gu");
101
101
  function tokenise(text) {
102
- return text.replace(TOKENISE_RE, " ").toLowerCase().trim().split(/\s+/).filter(Boolean);
102
+ if (!text) return [];
103
+ const cleaned = text.replace(TOKENISE_RE, " ").toLowerCase().trim();
104
+ if (!cleaned) return [];
105
+ return cleaned.split(/\s+/);
103
106
  }
107
+ var SPLIT_CANDIDATE_RE = /[A-Z_\d-]/;
104
108
  function splitName(name) {
109
+ if (!name || !SPLIT_CANDIDATE_RE.test(name)) return name;
105
110
  return name.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([\p{L}])(\d)/gu, "$1 $2").replace(/(\d)([\p{L}])/gu, "$1 $2").replace(/[_-]+/g, " ").trim();
106
111
  }
112
+ var FTS_SIGNATURE_MAX_CHARS = 300;
113
+ function ftsSignature(signature) {
114
+ if (!signature) return "";
115
+ const bodyStart = declarationBodyStart(signature);
116
+ const header = bodyStart === -1 ? signature : signature.slice(0, bodyStart);
117
+ return header.slice(0, FTS_SIGNATURE_MAX_CHARS);
118
+ }
119
+ function declarationBodyStart(s) {
120
+ let parenDepth = 0;
121
+ let paramsClosed = false;
122
+ let i = 0;
123
+ while (i < s.length) {
124
+ const ch = s[i];
125
+ if (!paramsClosed) {
126
+ if (ch === "(") parenDepth++;
127
+ else if (ch === ")") {
128
+ parenDepth = Math.max(0, parenDepth - 1);
129
+ if (parenDepth === 0) paramsClosed = true;
130
+ }
131
+ i++;
132
+ continue;
133
+ }
134
+ if (ch === "{") {
135
+ let j = i - 1;
136
+ while (j >= 0 && /\s/.test(s[j] ?? "")) j--;
137
+ if (s[j] === ":") {
138
+ let braceDepth = 1;
139
+ i++;
140
+ while (i < s.length && braceDepth > 0) {
141
+ if (s[i] === "{") braceDepth++;
142
+ else if (s[i] === "}") braceDepth--;
143
+ i++;
144
+ }
145
+ continue;
146
+ }
147
+ return i;
148
+ }
149
+ i++;
150
+ }
151
+ return -1;
152
+ }
107
153
  function buildIndexableText(name, signature, docComment) {
108
- return [splitName(name), name, signature, docComment].filter(Boolean).join(" ");
154
+ return [splitName(name), name, ftsSignature(signature), docComment].filter(Boolean).join(" ");
109
155
  }
110
156
  function buildBm25Index(docs) {
111
157
  const documents = docs.map((d) => {
@@ -189,7 +235,7 @@ var SCHEMA_VERSION = 5;
189
235
  // src/codebase-index/writer-helpers.ts
190
236
  import { resolveWstackPaths } from "@wrongstack/core/utils";
191
237
  function escapeLike(value) {
192
- return value.replace(/[\\%_]/g, (char) => `\\${char}`);
238
+ return /[\\%_]/.test(value) ? value.replace(/[\\%_]/g, (char) => `\\${char}`) : value;
193
239
  }
194
240
  function ladderChunkSizes(total, max) {
195
241
  if (total <= 0) return [];
@@ -214,8 +260,22 @@ function padToInBucket(values) {
214
260
  while (padded.length < target) padded.push(padded[0]);
215
261
  return padded;
216
262
  }
263
+ var PLACEHOLDER_BUCKETS = {
264
+ 1: "?",
265
+ 2: "?,?",
266
+ 4: "?,?,?,?",
267
+ 8: "?,?,?,?,?,?,?,?",
268
+ 16: "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?",
269
+ 32: "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?",
270
+ 64: "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?",
271
+ 128: Array.from({ length: 128 }, () => "?").join(","),
272
+ 256: Array.from({ length: 256 }, () => "?").join(","),
273
+ 512: Array.from({ length: 512 }, () => "?").join(","),
274
+ 1024: Array.from({ length: 1024 }, () => "?").join(",")
275
+ };
217
276
  function placeholders(count) {
218
- return Array.from({ length: count }, () => "?").join(",");
277
+ if (count <= 0) return "";
278
+ return PLACEHOLDER_BUCKETS[count] ?? Array.from({ length: count }, () => "?").join(",");
219
279
  }
220
280
  function inListChunks(total, max) {
221
281
  if (total <= 0) return [];
@@ -224,7 +284,8 @@ function inListChunks(total, max) {
224
284
  return ladderChunkSizes(total, powMax);
225
285
  }
226
286
  function posixIndexPath(file) {
227
- return file.replace(/\\/g, "/").replace(/^\.\//, "");
287
+ const p = file.includes("\\") ? file.replace(/\\/g, "/") : file;
288
+ return p.startsWith("./") ? p.slice(2) : p;
228
289
  }
229
290
  function indexedFileMatchSql(column = "file") {
230
291
  return `(${column} = ? OR replace(${column}, '\\', '/') = ? OR replace(${column}, '\\', '/') LIKE ? ESCAPE '\\')`;
@@ -373,11 +434,13 @@ function isLockError(err) {
373
434
  if (typeof code === "number" && (code === 5 || code === 6)) return true;
374
435
  return /SQLITE_(BUSY|LOCKED)/.test(err.message);
375
436
  }
437
+ var SLEEP_BUFFER;
376
438
  function sleepSync(ms) {
377
439
  try {
378
- const sab = new SharedArrayBuffer(4);
379
- const view = new Int32Array(sab);
380
- Atomics.wait(view, 0, 0, ms);
440
+ if (!SLEEP_BUFFER) {
441
+ SLEEP_BUFFER = new Int32Array(new SharedArrayBuffer(4));
442
+ }
443
+ Atomics.wait(SLEEP_BUFFER, 0, 0, ms);
381
444
  } catch {
382
445
  }
383
446
  }
@@ -453,11 +516,8 @@ function decodeVector(buf) {
453
516
  if (buf.byteLength % 4 !== 0) {
454
517
  throw new Error(`decodeVector: invalid vector byteLength ${buf.byteLength} (must be a multiple of 4)`);
455
518
  }
456
- const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
457
519
  const copy = new Float32Array(buf.byteLength / 4);
458
- for (let i = 0; i < copy.length; i++) {
459
- copy[i] = view.getFloat32(i * 4, true);
460
- }
520
+ new Uint8Array(copy.buffer).set(buf);
461
521
  return copy;
462
522
  }
463
523
  function reciprocalRankFusion(bm25Ranks, vectorRanks, k = RRF_K) {
@@ -480,9 +540,11 @@ import * as fs from "node:fs";
480
540
  import * as path from "node:path";
481
541
  var DB_FILE = "index.db";
482
542
  function getAllIndexableWithStatement(stmt) {
483
- return stmt("SELECT id, text FROM symbols").all().map(
484
- ({ id, text }) => ({ id, text })
485
- );
543
+ const rows = stmt("SELECT id, name, signature, doc_comment FROM symbols").all();
544
+ return rows.map((row) => ({
545
+ id: row.id,
546
+ text: buildIndexableText(row.name, row.signature, row.doc_comment)
547
+ }));
486
548
  }
487
549
  function getMaxSymbolIdWithStatement(stmt) {
488
550
  const rows = stmt("SELECT MAX(id) AS m FROM symbols").all();
@@ -557,6 +619,16 @@ function getIndexDbSizeBytes(indexDir) {
557
619
  }
558
620
 
559
621
  // src/codebase-index/writer-bulk-insert.ts
622
+ var ROW_PLACEHOLDERS_CACHE = /* @__PURE__ */ new Map();
623
+ function getRowPlaceholders(rowTemplate, count) {
624
+ const key = `${rowTemplate}\0${count}`;
625
+ let result = ROW_PLACEHOLDERS_CACHE.get(key);
626
+ if (result === void 0) {
627
+ result = Array.from({ length: count }, () => rowTemplate).join(", ");
628
+ ROW_PLACEHOLDERS_CACHE.set(key, result);
629
+ }
630
+ return result;
631
+ }
560
632
  function bulkInsertSymbolsWithStatement(stmt, maxSqlVars, rows) {
561
633
  if (rows.length === 0) return;
562
634
  const ladder = ladderChunkSizes(rows.length, Math.max(1, Math.floor(maxSqlVars / 12)));
@@ -564,9 +636,12 @@ function bulkInsertSymbolsWithStatement(stmt, maxSqlVars, rows) {
564
636
  for (const take of ladder) {
565
637
  const chunk = rows.slice(cursor, cursor + take);
566
638
  cursor += take;
567
- const placeholders2 = chunk.map(() => "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").join(", ");
639
+ const placeholders2 = getRowPlaceholders(
640
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
641
+ chunk.length
642
+ );
568
643
  const insert = stmt(
569
- `INSERT INTO symbols(id, lang, kind, name, file, line, col, signature, doc_comment, scope, text)
644
+ `INSERT INTO symbols(id, lang, kind, name, file, line, col, signature, doc_comment, scope)
570
645
  VALUES ${placeholders2}`
571
646
  );
572
647
  const binds = [];
@@ -581,8 +656,7 @@ function bulkInsertSymbolsWithStatement(stmt, maxSqlVars, rows) {
581
656
  r.col,
582
657
  r.signature,
583
658
  r.docComment,
584
- r.scope,
585
- r.text
659
+ r.scope
586
660
  );
587
661
  }
588
662
  insert.run(...binds);
@@ -595,7 +669,7 @@ function bulkInsertFtsWithStatement(stmt, maxSqlVars, ftsAvailable, rows) {
595
669
  for (const take of ladder) {
596
670
  const chunk = rows.slice(cursor, cursor + take);
597
671
  cursor += take;
598
- const placeholders2 = chunk.map(() => "(?, ?)").join(", ");
672
+ const placeholders2 = getRowPlaceholders("(?, ?)", chunk.length);
599
673
  const insert = stmt(`INSERT INTO symbols_fts(rowid, text) VALUES ${placeholders2}`);
600
674
  const binds = [];
601
675
  for (const r of chunk) binds.push(r.id, r.text);
@@ -609,7 +683,7 @@ function bulkInsertVectorsWithStatement(stmt, maxSqlVars, rows) {
609
683
  for (const take of ladder) {
610
684
  const chunk = rows.slice(cursor, cursor + take);
611
685
  cursor += take;
612
- const placeholders2 = chunk.map(() => "(?, ?)").join(", ");
686
+ const placeholders2 = getRowPlaceholders("(?, ?)", chunk.length);
613
687
  const insert = stmt(`INSERT INTO symbol_vectors(symbol_id, vector) VALUES ${placeholders2}`);
614
688
  const binds = [];
615
689
  for (const r of chunk) binds.push(r.id, r.vector);
@@ -623,7 +697,10 @@ function bulkInsertRefsWithStatement(stmt, maxSqlVars, refs) {
623
697
  for (const take of ladder) {
624
698
  const chunk = refs.slice(cursor, cursor + take);
625
699
  cursor += take;
626
- const placeholders2 = chunk.map(() => "(?, ?, ?, ?, ?, ?, ?, ?)").join(", ");
700
+ const placeholders2 = getRowPlaceholders(
701
+ "(?, ?, ?, ?, ?, ?, ?, ?)",
702
+ chunk.length
703
+ );
627
704
  const insert = stmt(
628
705
  `INSERT INTO refs(from_id, to_name, to_id, call_type, line, lang, module, to_file)
629
706
  VALUES ${placeholders2}`
@@ -649,7 +726,7 @@ function bulkInsertRefsWithStatement(stmt, maxSqlVars, refs) {
649
726
  import * as fs2 from "node:fs/promises";
650
727
  import * as path2 from "node:path";
651
728
  function toPortablePath(file) {
652
- return file.replace(/\\/g, "/");
729
+ return file.includes("\\") ? file.replace(/\\/g, "/") : file;
653
730
  }
654
731
  async function readTextIfPresent(file) {
655
732
  try {
@@ -953,9 +1030,16 @@ function createPackageLabeller(stored) {
953
1030
  function buildPackageGraphNodes(fileCounts, files, packageOf) {
954
1031
  const pkgNodes = /* @__PURE__ */ new Map();
955
1032
  const fileToPkg = /* @__PURE__ */ new Map();
1033
+ const getOrSetPkg = (file) => {
1034
+ let pkg = fileToPkg.get(file);
1035
+ if (pkg === void 0) {
1036
+ pkg = packageOf(file);
1037
+ fileToPkg.set(file, pkg);
1038
+ }
1039
+ return pkg;
1040
+ };
956
1041
  for (const { file, n } of fileCounts) {
957
- const pkg = packageOf(file);
958
- fileToPkg.set(file, pkg);
1042
+ const pkg = getOrSetPkg(file);
959
1043
  const node = pkgNodes.get(pkg);
960
1044
  if (node) {
961
1045
  node.symbolCount = (node.symbolCount ?? 0) + n;
@@ -971,8 +1055,7 @@ function buildPackageGraphNodes(fileCounts, files, packageOf) {
971
1055
  }
972
1056
  }
973
1057
  for (const { file } of files) {
974
- const pkg = packageOf(file);
975
- fileToPkg.set(file, pkg);
1058
+ const pkg = getOrSetPkg(file);
976
1059
  const node = pkgNodes.get(pkg);
977
1060
  if (node) {
978
1061
  node.fileCount = (node.fileCount ?? 0) + 1;
@@ -1004,9 +1087,11 @@ function buildFileGraphNodeState(pkgSyms, localFiles, packageOf) {
1004
1087
  const ensureFileNode = (file) => {
1005
1088
  if (fileNodes.has(file)) return;
1006
1089
  const stats = fileStats.get(file);
1090
+ const lastSlash = Math.max(file.lastIndexOf("/"), file.lastIndexOf("\\"));
1091
+ const label = lastSlash === -1 ? file : file.slice(lastSlash + 1);
1007
1092
  fileNodes.set(file, {
1008
1093
  id: `file:${file}`,
1009
- label: file.replace(/\\/g, "/").split("/").pop() ?? file,
1094
+ label,
1010
1095
  kind: "file",
1011
1096
  package: packageOf(file),
1012
1097
  file,
@@ -1021,17 +1106,25 @@ function buildFileGraphNodeState(pkgSyms, localFiles, packageOf) {
1021
1106
  return { fileNodes, symToFile, fileStats, ensureFileNode };
1022
1107
  }
1023
1108
  function buildSymbolGraphNodes(symById, relatedIds, localFiles, packageOf) {
1024
- const local = new Set(
1025
- [...typeof localFiles === "string" ? [localFiles] : localFiles].map(
1026
- (file) => file.replace(/\\/g, "/")
1027
- )
1028
- );
1029
- const isLocal = (file) => local.has(file.replace(/\\/g, "/"));
1030
- return [...relatedIds].map((id) => symById.get(id)).filter((symbol) => symbol !== void 0).sort((a, b) => {
1031
- const aExternal = isLocal(a.file) ? 0 : 1;
1032
- const bExternal = isLocal(b.file) ? 0 : 1;
1109
+ const rawSet = typeof localFiles === "string" ? [localFiles] : localFiles;
1110
+ const local = /* @__PURE__ */ new Set();
1111
+ for (const f of rawSet) {
1112
+ local.add(f.includes("\\") ? f.replace(/\\/g, "/") : f);
1113
+ }
1114
+ const isLocal = (file) => local.has(file.includes("\\") ? file.replace(/\\/g, "/") : file);
1115
+ const matched = [];
1116
+ for (const id of relatedIds) {
1117
+ const s = symById.get(id);
1118
+ if (s) {
1119
+ matched.push({ ...s, isExt: !isLocal(s.file) });
1120
+ }
1121
+ }
1122
+ matched.sort((a, b) => {
1123
+ const aExternal = a.isExt ? 1 : 0;
1124
+ const bExternal = b.isExt ? 1 : 0;
1033
1125
  return aExternal - bExternal || a.file.localeCompare(b.file) || a.line - b.line || a.id - b.id;
1034
- }).map((s) => ({
1126
+ });
1127
+ return matched.map((s) => ({
1035
1128
  id: `sym:${s.id}`,
1036
1129
  label: s.name,
1037
1130
  kind: "symbol",
@@ -1043,7 +1136,7 @@ function buildSymbolGraphNodes(symById, relatedIds, localFiles, packageOf) {
1043
1136
  line: s.line,
1044
1137
  signature: s.signature,
1045
1138
  scope: s.scope,
1046
- external: !isLocal(s.file)
1139
+ external: s.isExt
1047
1140
  }));
1048
1141
  }
1049
1142
  function addWeightedEdge(edgeMap, source, target, callType, weight) {
@@ -1089,7 +1182,7 @@ function mapWriterRefRow(row) {
1089
1182
  line: row.line,
1090
1183
  // `lang`/`module`/`to_file` are absent from the narrower column lists some
1091
1184
  // queries select; `undefined` keeps those rows valid Refs.
1092
- lang: row.lang || void 0,
1185
+ lang: row.lang ?? void 0,
1093
1186
  module: row.module ?? void 0,
1094
1187
  toFile: row.to_file ?? void 0
1095
1188
  };
@@ -1099,9 +1192,10 @@ function mapWriterRefRow(row) {
1099
1192
  var MAX_SQL_VARS = 900;
1100
1193
  function chunkedIdQuery(stmt, ids, buildSql, extraArgs = []) {
1101
1194
  const results = [];
1195
+ let cursor = 0;
1102
1196
  for (const take of inListChunks(ids.length, MAX_SQL_VARS)) {
1103
- const chunk = padToInBucket(ids.slice(0, take));
1104
- ids = ids.slice(take);
1197
+ const chunk = padToInBucket(ids.slice(cursor, cursor + take));
1198
+ cursor += take;
1105
1199
  const sql = buildSql(placeholders(chunk.length));
1106
1200
  results.push(...stmt(sql).all(...chunk, ...extraArgs));
1107
1201
  }
@@ -1109,9 +1203,10 @@ function chunkedIdQuery(stmt, ids, buildSql, extraArgs = []) {
1109
1203
  }
1110
1204
  function chunkedIdScalar(stmt, ids, buildSql, extraArgs = []) {
1111
1205
  let total = 0;
1206
+ let cursor = 0;
1112
1207
  for (const take of inListChunks(ids.length, MAX_SQL_VARS)) {
1113
- const chunk = padToInBucket(ids.slice(0, take));
1114
- ids = ids.slice(take);
1208
+ const chunk = padToInBucket(ids.slice(cursor, cursor + take));
1209
+ cursor += take;
1115
1210
  const sql = buildSql(placeholders(chunk.length));
1116
1211
  const rows = stmt(sql).all(...chunk, ...extraArgs);
1117
1212
  total += rows[0]?.n ?? 0;
@@ -1663,8 +1758,7 @@ function commitBatchWithStatement(stmtFn, maxSqlVars, ftsAvailable, vectorsAvail
1663
1758
  col: s.col,
1664
1759
  signature: s.signature,
1665
1760
  docComment: s.docComment,
1666
- scope: s.scope,
1667
- text: s.text
1761
+ scope: s.scope
1668
1762
  });
1669
1763
  if (ftsAvailable) {
1670
1764
  ftsRows.push({
@@ -1676,7 +1770,7 @@ function commitBatchWithStatement(stmtFn, maxSqlVars, ftsAvailable, vectorsAvail
1676
1770
  vectorRows.push({
1677
1771
  id,
1678
1772
  vector: encodeVector(
1679
- embedText(s.text || buildIndexableText(s.name, s.signature, s.docComment))
1773
+ embedText(buildIndexableText(s.name, s.signature, s.docComment))
1680
1774
  )
1681
1775
  });
1682
1776
  }
@@ -1770,8 +1864,7 @@ var CORE_TABLES_SQL = `
1770
1864
  col INTEGER NOT NULL,
1771
1865
  signature TEXT NOT NULL DEFAULT '',
1772
1866
  doc_comment TEXT NOT NULL DEFAULT '',
1773
- scope TEXT NOT NULL DEFAULT '',
1774
- text TEXT NOT NULL DEFAULT ''
1867
+ scope TEXT NOT NULL DEFAULT ''
1775
1868
  );
1776
1869
  `;
1777
1870
  var FILE_INDEX_SQL = [
@@ -1846,7 +1939,11 @@ function getNamespaceDeclarationsWithStatement(stmtFn) {
1846
1939
  }
1847
1940
  function getFilePackagesWithStatement(stmtFn) {
1848
1941
  const rows = stmtFn("SELECT file, package FROM files WHERE package != ''").all();
1849
- return new Map(rows.map((row) => [row.file, row.package]));
1942
+ const map = /* @__PURE__ */ new Map();
1943
+ for (const row of rows) {
1944
+ map.set(row.file, row.package);
1945
+ }
1946
+ return map;
1850
1947
  }
1851
1948
  function getUnresolvedImportsWithStatement(stmtFn, maxSqlVars, onlyFiles) {
1852
1949
  const base = `SELECT DISTINCT s.file AS fromFile, r.lang AS lang, r.module AS module
@@ -2061,8 +2158,15 @@ function buildWriterSearchWhere(query, filter) {
2061
2158
  }
2062
2159
  if (query.trim()) {
2063
2160
  const tokens = query.toLowerCase().split(/\s+/).filter(Boolean);
2064
- conditions.push(`(${tokens.map(() => "text LIKE ? ESCAPE '\\'").join(" OR ")})`);
2065
- for (const token of tokens) values.push(`%${escapeLike(token)}%`);
2161
+ conditions.push(
2162
+ `(${tokens.map(
2163
+ () => "(name LIKE ? ESCAPE '\\' OR signature LIKE ? ESCAPE '\\' OR doc_comment LIKE ? ESCAPE '\\')"
2164
+ ).join(" OR ")})`
2165
+ );
2166
+ for (const token of tokens) {
2167
+ const like = `%${escapeLike(token)}%`;
2168
+ values.push(like, like, like);
2169
+ }
2066
2170
  }
2067
2171
  return { where: conditions.length ? `WHERE ${conditions.join(" AND ")}` : "", values };
2068
2172
  }
@@ -2139,8 +2243,11 @@ function searchRankedWithStatement(stmtFn, searchFn, ftsAvailable, vectorsAvaila
2139
2243
  const conditions = ["symbols_fts MATCH ?"];
2140
2244
  const values = [match];
2141
2245
  for (const shortTok of shortTokens) {
2142
- conditions.push("s.text LIKE ? ESCAPE '\\'");
2143
- values.push(`%${escapeLike(shortTok)}%`);
2246
+ const like = `%${escapeLike(shortTok)}%`;
2247
+ conditions.push(
2248
+ "(s.name LIKE ? ESCAPE '\\' OR s.signature LIKE ? ESCAPE '\\' OR s.doc_comment LIKE ? ESCAPE '\\')"
2249
+ );
2250
+ values.push(like, like, like);
2144
2251
  }
2145
2252
  if (effectiveKind) {
2146
2253
  conditions.push("s.kind = ?");
@@ -2439,11 +2546,11 @@ var IndexStore = class _IndexStore {
2439
2546
  }
2440
2547
  ];
2441
2548
  for (const { table, columns } of expected) {
2442
- const present = new Set(
2443
- this.db.prepare(`PRAGMA table_info(${table})`).all().flatMap(
2444
- (row) => typeof row.name === "string" ? [row.name] : []
2445
- )
2446
- );
2549
+ const rows = this.db.prepare(`PRAGMA table_info(${table})`).all();
2550
+ const present = /* @__PURE__ */ new Set();
2551
+ for (const row of rows) {
2552
+ if (typeof row.name === "string") present.add(row.name);
2553
+ }
2447
2554
  if (present.size === 0) continue;
2448
2555
  for (const [name, type] of columns) {
2449
2556
  if (present.has(name)) continue;
@@ -2451,6 +2558,31 @@ var IndexStore = class _IndexStore {
2451
2558
  }
2452
2559
  }
2453
2560
  }
2561
+ /**
2562
+ * P4: `symbols.text` duplicated name + signature + doc_comment (~19 MB on
2563
+ * the live index) and is derived on demand now. In-place DROP COLUMN — no
2564
+ * SCHEMA_VERSION bump, so no wipe-and-reparse. Best-effort: a busy or
2565
+ * SQLite-without-DROP-COLUMN open leaves the column in place, where new
2566
+ * inserts simply default it to '' and the next open retries.
2567
+ */
2568
+ dropDeprecatedSymbolsColumns() {
2569
+ if (this.getMetadata(_IndexStore.SYMBOLS_TEXT_DROPPED_KEY) !== void 0) return;
2570
+ const present = new Set(
2571
+ this.db.prepare("PRAGMA table_info(symbols)").all().flatMap(
2572
+ (row) => typeof row.name === "string" ? [row.name] : []
2573
+ )
2574
+ );
2575
+ if (present.size === 0) return;
2576
+ if (!present.has("text")) {
2577
+ this.setMetadata(_IndexStore.SYMBOLS_TEXT_DROPPED_KEY, "1");
2578
+ return;
2579
+ }
2580
+ try {
2581
+ this.db.exec("ALTER TABLE symbols DROP COLUMN text");
2582
+ this.setMetadata(_IndexStore.SYMBOLS_TEXT_DROPPED_KEY, "1");
2583
+ } catch {
2584
+ }
2585
+ }
2454
2586
  initSchema() {
2455
2587
  this.db.exec(METADATA_TABLE_SQL);
2456
2588
  const storedRows = this.stmt("SELECT value FROM metadata WHERE key = ?").all("version");
@@ -2476,6 +2608,7 @@ var IndexStore = class _IndexStore {
2476
2608
  this.db.exec(CORE_TABLES_SQL);
2477
2609
  this.db.exec(REFS_TABLE_SQL);
2478
2610
  this.repairMissingColumns();
2611
+ this.dropDeprecatedSymbolsColumns();
2479
2612
  for (const sql of FILE_INDEX_SQL) this.db.exec(sql);
2480
2613
  for (const sql of SYMBOL_INDEX_SQL) this.db.exec(sql);
2481
2614
  for (const sql of REFS_INDEX_SQL) this.db.exec(sql);
@@ -2535,6 +2668,10 @@ var IndexStore = class _IndexStore {
2535
2668
  }
2536
2669
  static NEXT_SYMBOL_ID_KEY = "next_symbol_id";
2537
2670
  static MAX_SQL_VARS = 900;
2671
+ /** P2: persisted FTS-mutation churn counter — see {@link optimizeFtsIfNeeded}. */
2672
+ static FTS_CHURN_KEY = "fts_churn_since_maintain";
2673
+ /** P4: one-shot marker that the deprecated symbols.text column is gone. */
2674
+ static SYMBOLS_TEXT_DROPPED_KEY = "symbols_text_dropped";
2538
2675
  ensureNextSymbolIdSeeded() {
2539
2676
  const existing = this.stmt("SELECT value FROM metadata WHERE key = ?").get(
2540
2677
  _IndexStore.NEXT_SYMBOL_ID_KEY
@@ -2605,8 +2742,7 @@ var IndexStore = class _IndexStore {
2605
2742
  col: s.col,
2606
2743
  signature: s.signature,
2607
2744
  docComment: s.docComment,
2608
- scope: s.scope,
2609
- text: s.text
2745
+ scope: s.scope
2610
2746
  });
2611
2747
  if (this.ftsAvailable) {
2612
2748
  ftsRows.push({ id, text: buildIndexableText(s.name, s.signature, s.docComment) });
@@ -2615,7 +2751,7 @@ var IndexStore = class _IndexStore {
2615
2751
  vectorRows.push({
2616
2752
  id,
2617
2753
  vector: encodeVector(
2618
- embedText(s.text || buildIndexableText(s.name, s.signature, s.docComment))
2754
+ embedText(buildIndexableText(s.name, s.signature, s.docComment))
2619
2755
  )
2620
2756
  });
2621
2757
  }
@@ -2635,6 +2771,7 @@ var IndexStore = class _IndexStore {
2635
2771
  vectorRows
2636
2772
  );
2637
2773
  }
2774
+ this.recordFtsChurn(symbols.length);
2638
2775
  this.commitWriteTransaction(ownsTransaction);
2639
2776
  return result;
2640
2777
  } catch (err) {
@@ -2659,7 +2796,10 @@ var IndexStore = class _IndexStore {
2659
2796
  "DELETE FROM symbol_vectors WHERE symbol_id IN (SELECT id FROM symbols WHERE file = ?)"
2660
2797
  ).run(file);
2661
2798
  }
2662
- this.stmt("DELETE FROM symbols WHERE file = ?").run(file);
2799
+ const deletedChanges = Number(
2800
+ this.stmt("DELETE FROM symbols WHERE file = ?").run(file).changes
2801
+ );
2802
+ this.recordFtsChurn(deletedChanges);
2663
2803
  this.resolveRefsForNamesUnsafe(affectedNames);
2664
2804
  this.commitWriteTransaction(ownsTransaction);
2665
2805
  } catch (error) {
@@ -2687,7 +2827,10 @@ var IndexStore = class _IndexStore {
2687
2827
  this.stmt("DELETE FROM refs WHERE from_id IN (SELECT id FROM symbols WHERE file = ?)").run(
2688
2828
  file
2689
2829
  );
2690
- this.stmt("DELETE FROM symbols WHERE file = ?").run(file);
2830
+ const deletedChanges = Number(
2831
+ this.stmt("DELETE FROM symbols WHERE file = ?").run(file).changes
2832
+ );
2833
+ this.recordFtsChurn(deletedChanges);
2691
2834
  this.stmt("DELETE FROM files WHERE file = ?").run(file);
2692
2835
  this.resolveRefsForNamesUnsafe(affectedNames);
2693
2836
  this.commitWriteTransaction(ownsTransaction);
@@ -2856,6 +2999,19 @@ var IndexStore = class _IndexStore {
2856
2999
  return this.runWithRetry(() => {
2857
3000
  const ownsTransaction = this.beginWriteTransaction();
2858
3001
  try {
3002
+ const owned = options.deleteForFiles?.length ?? 0;
3003
+ let churnRows = entries.reduce((sum, e) => sum + e.symbols.length, 0);
3004
+ if (owned > 0) {
3005
+ let cursor = 0;
3006
+ for (const take of inListChunks(owned, Math.floor(_IndexStore.MAX_SQL_VARS / 4))) {
3007
+ const bucket = options.deleteForFiles.slice(cursor, cursor + take);
3008
+ cursor += take;
3009
+ const row = this.stmt(
3010
+ `SELECT COUNT(*) AS n FROM symbols WHERE file IN (${placeholders(bucket.length)})`
3011
+ ).get(...bucket);
3012
+ churnRows += Number(row?.n ?? 0);
3013
+ }
3014
+ }
2859
3015
  const result = commitBatchWithStatement(
2860
3016
  (sql) => this.stmt(sql),
2861
3017
  _IndexStore.MAX_SQL_VARS,
@@ -2867,6 +3023,7 @@ var IndexStore = class _IndexStore {
2867
3023
  entries,
2868
3024
  options
2869
3025
  );
3026
+ this.recordFtsChurn(churnRows);
2870
3027
  this.commitWriteTransaction(ownsTransaction);
2871
3028
  return result;
2872
3029
  } catch (err) {
@@ -2907,7 +3064,10 @@ var IndexStore = class _IndexStore {
2907
3064
  this.stmt("DELETE FROM refs WHERE from_id IN (SELECT id FROM symbols WHERE file = ?)").run(
2908
3065
  meta.file
2909
3066
  );
2910
- this.stmt("DELETE FROM symbols WHERE file = ?").run(meta.file);
3067
+ const deletedChanges = Number(
3068
+ this.stmt("DELETE FROM symbols WHERE file = ?").run(meta.file).changes
3069
+ );
3070
+ this.recordFtsChurn(deletedChanges);
2911
3071
  this.stmt(
2912
3072
  `INSERT INTO files(file, lang, mtime_ms, content_hash, symbol_count, last_indexed)
2913
3073
  VALUES (?, ?, ?, ?, ?, ?)
@@ -2939,6 +3099,54 @@ var IndexStore = class _IndexStore {
2939
3099
  } catch {
2940
3100
  }
2941
3101
  }
3102
+ /**
3103
+ * P2: churn-gated FTS5 segment maintenance.
3104
+ *
3105
+ * FTS5 postings only compact when FTS5 itself merges them: every delete
3106
+ * leaves tombstone postings in the segments, and neither VACUUM nor
3107
+ * `PRAGMA optimize` reclaims them. Measured on the live index (2026-08-30):
3108
+ * one delete+reinsert cycle grew symbols_fts_data 174.9→212.8 MB, while the
3109
+ * FTS5 'optimize'/'rebuild' merge resets it (rebuild: 212.9→28.2 MB in
3110
+ * 1.26 s for 131k rows). 'optimize' is the recurring command — an
3111
+ * incremental merge that discards deleted docs — and only runs once churn
3112
+ * crosses the gate, so a clean index never pays for it.
3113
+ *
3114
+ * Follows the {@link checkpointWal} contract: best-effort, returns whether
3115
+ * it ran, safe to call from the daemon's single-threaded idle path.
3116
+ */
3117
+ optimizeFtsIfNeeded(options = {}) {
3118
+ if (!this.ftsAvailable) return false;
3119
+ try {
3120
+ const minChurnRatio = options.minChurnRatio ?? 0.1;
3121
+ const minChurnRows = options.minChurnRows ?? 5e3;
3122
+ const churn = Number(this.getMetadata(_IndexStore.FTS_CHURN_KEY) ?? "0") || 0;
3123
+ const liveRows = Number(
3124
+ this.stmt("SELECT COUNT(*) AS n FROM symbols").get()?.n ?? 0
3125
+ );
3126
+ if (churn < Math.max(minChurnRows, liveRows * minChurnRatio)) return false;
3127
+ this.runWithRetry(() => {
3128
+ this.stmt(`INSERT INTO symbols_fts(symbols_fts) VALUES('optimize')`).run();
3129
+ });
3130
+ this.setMetadata(_IndexStore.FTS_CHURN_KEY, "0");
3131
+ return true;
3132
+ } catch {
3133
+ return false;
3134
+ }
3135
+ }
3136
+ /**
3137
+ * Best-effort churn bookkeeping for {@link optimizeFtsIfNeeded}. Counts the
3138
+ * FTS rows a mutation inserts or deletes so the maintenance gate can fire
3139
+ * after real churn, not on a timer. Persisted in metadata so the counter
3140
+ * survives store open/close cycles in the daemon pool.
3141
+ */
3142
+ recordFtsChurn(rows) {
3143
+ if (rows <= 0 || !this.ftsAvailable) return;
3144
+ try {
3145
+ const current = Number(this.getMetadata(_IndexStore.FTS_CHURN_KEY) ?? "0") || 0;
3146
+ this.setMetadata(_IndexStore.FTS_CHURN_KEY, String(current + rows));
3147
+ } catch {
3148
+ }
3149
+ }
2942
3150
  /**
2943
3151
  * P4.14: best-effort WAL checkpoint for idle-time maintenance.
2944
3152
  *
@@ -3066,15 +3274,11 @@ function rotl64(x, n) {
3066
3274
  const v = x & MASK64;
3067
3275
  return (v << BigInt(n) | v >> BigInt(64 - n)) & MASK64;
3068
3276
  }
3069
- function readU64LE(buf, off) {
3070
- let v = 0n;
3071
- for (let i = 7; i >= 0; i--) {
3072
- v = v << 8n | BigInt(buf[off + i] ?? 0);
3073
- }
3074
- return v & MASK64;
3277
+ function readU64LE(view, off) {
3278
+ return view.getBigUint64(off, true);
3075
3279
  }
3076
- function readU32LE(buf, off) {
3077
- return (BigInt(buf[off] ?? 0) | BigInt(buf[off + 1] ?? 0) << 8n | BigInt(buf[off + 2] ?? 0) << 16n | BigInt(buf[off + 3] ?? 0) << 24n) & MASK64;
3280
+ function readU32LE(view, off) {
3281
+ return BigInt(view.getUint32(off, true));
3078
3282
  }
3079
3283
  function xxh64Round(acc, lane) {
3080
3284
  return mul64(rotl64(acc + mul64(lane, PRIME64_2) & MASK64, 31), PRIME64_1);
@@ -3084,6 +3288,7 @@ function xxh64MergeRound(acc, val) {
3084
3288
  }
3085
3289
  function xxhash64Hex(buf, explicitLen) {
3086
3290
  const length = explicitLen ?? buf.length;
3291
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
3087
3292
  let h;
3088
3293
  let off = 0;
3089
3294
  if (length >= 32) {
@@ -3093,10 +3298,10 @@ function xxhash64Hex(buf, explicitLen) {
3093
3298
  let v4 = 0n - PRIME64_1 & MASK64;
3094
3299
  const end32 = length - 32;
3095
3300
  while (off <= end32) {
3096
- v1 = xxh64Round(v1, readU64LE(buf, off));
3097
- v2 = xxh64Round(v2, readU64LE(buf, off + 8));
3098
- v3 = xxh64Round(v3, readU64LE(buf, off + 16));
3099
- v4 = xxh64Round(v4, readU64LE(buf, off + 24));
3301
+ v1 = xxh64Round(v1, readU64LE(view, off));
3302
+ v2 = xxh64Round(v2, readU64LE(view, off + 8));
3303
+ v3 = xxh64Round(v3, readU64LE(view, off + 16));
3304
+ v4 = xxh64Round(v4, readU64LE(view, off + 24));
3100
3305
  off += 32;
3101
3306
  }
3102
3307
  h = rotl64(v1, 1) + rotl64(v2, 7) + rotl64(v3, 12) + rotl64(v4, 18) & MASK64;
@@ -3109,12 +3314,12 @@ function xxhash64Hex(buf, explicitLen) {
3109
3314
  }
3110
3315
  h = h + BigInt(length) & MASK64;
3111
3316
  while (off + 8 <= length) {
3112
- const k1 = xxh64Round(0n, readU64LE(buf, off));
3317
+ const k1 = xxh64Round(0n, readU64LE(view, off));
3113
3318
  h = mul64(rotl64(h ^ k1, 27), PRIME64_1) + PRIME64_4 & MASK64;
3114
3319
  off += 8;
3115
3320
  }
3116
3321
  if (off + 4 <= length) {
3117
- h = mul64(rotl64(h ^ mul64(readU32LE(buf, off), PRIME64_1), 23), PRIME64_2) + PRIME64_3 & MASK64;
3322
+ h = mul64(rotl64(h ^ mul64(readU32LE(view, off), PRIME64_1), 23), PRIME64_2) + PRIME64_3 & MASK64;
3118
3323
  off += 4;
3119
3324
  }
3120
3325
  while (off < length) {
@@ -3188,8 +3393,10 @@ var ModuleResolver = class {
3188
3393
  for (const { name, file } of namespaces) {
3189
3394
  const lang = detectLang(file);
3190
3395
  if (!lang) continue;
3191
- const key = `${languageFamily(lang)}:${normalizeNamespace(name)}`;
3192
- if (normalizeNamespace(name) && !this.byNamespace.has(key)) {
3396
+ const norm = normalizeNamespace(name);
3397
+ if (!norm) continue;
3398
+ const key = `${languageFamily(lang)}:${norm}`;
3399
+ if (!this.byNamespace.has(key)) {
3193
3400
  this.byNamespace.set(key, file);
3194
3401
  }
3195
3402
  }
@@ -3617,7 +3824,7 @@ var ParserWorkerPool = class {
3617
3824
  */
3618
3825
  async reparseInline(batch, orphaned, workerId) {
3619
3826
  try {
3620
- const { parseFileContent } = await import("./parser-dispatch-QH4XPGG6.js");
3827
+ const { parseFileContent } = await import("./parser-dispatch-X62UWXJS.js");
3621
3828
  for (const item of orphaned) {
3622
3829
  if (batch.settled) return;
3623
3830
  try {
@@ -4406,4 +4613,4 @@ export {
4406
4613
  incomingCallsService,
4407
4614
  outgoingCallsService
4408
4615
  };
4409
- //# sourceMappingURL=chunk-TRDX25UH.js.map
4616
+ //# sourceMappingURL=chunk-TFEGJDH5.js.map