@ulpi/cli 0.1.5 → 0.1.6

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/LICENSE +21 -0
  2. package/dist/{auth-PN7TMQHV-2W4ICG64.js → auth-FWM7MM4Q-VZC3U2XZ.js} +1 -1
  3. package/dist/{auth-BFFBUJUC.js → auth-HDK7ECJL.js} +2 -1
  4. package/dist/{chunk-RJIRWQJD.js → chunk-3BCW6ABU.js} +402 -142
  5. package/dist/{chunk-L3PWNHSA.js → chunk-3WB5CXH4.js} +180 -5
  6. package/dist/{chunk-K4OVPFY2.js → chunk-4UCJIAOU.js} +2 -2
  7. package/dist/chunk-4XTHZVDS.js +109 -0
  8. package/dist/chunk-4ZPOZULQ.js +6522 -0
  9. package/dist/{chunk-SIAQVRKG.js → chunk-5MI5GIXM.js} +48 -2
  10. package/dist/{chunk-KLEASXUR.js → chunk-6ZL6NXMV.js} +1 -1
  11. package/dist/{chunk-AV5RB3N2.js → chunk-76D3BYJD.js} +48 -0
  12. package/dist/{chunk-DOIKS6C5.js → chunk-AWOSRA5F.js} +1 -1
  13. package/dist/{chunk-UCMT5OKP.js → chunk-BFEKZZHM.js} +274 -57
  14. package/dist/chunk-C7CLUQI6.js +1286 -0
  15. package/dist/{chunk-ELTGWMDE.js → chunk-E3B5NROU.js} +7 -7
  16. package/dist/chunk-EJ7TW77N.js +1418 -0
  17. package/dist/{chunk-6OURRFP7.js → chunk-IV6MWETF.js} +383 -168
  18. package/dist/chunk-IZPJHSPX.js +1478 -0
  19. package/dist/chunk-JLHNLM3C.js +228 -0
  20. package/dist/{chunk-P2RESJRN.js → chunk-KYYI23AQ.js} +2 -2
  21. package/dist/chunk-S6ANCSYO.js +1271 -0
  22. package/dist/chunk-SEU7WWNQ.js +1251 -0
  23. package/dist/chunk-SNQ7NAIS.js +453 -0
  24. package/dist/{ulpi-RMMCUAGP-EWYUE7RU.js → chunk-TSLDGT5O.js} +73 -35
  25. package/dist/{chunk-EIWYSP3A.js → chunk-UXHCHOWQ.js} +83 -62
  26. package/dist/chunk-V2H5D6Y3.js +146 -0
  27. package/dist/{chunk-5SCG7UYM.js → chunk-VVEDXI7E.js} +1 -1
  28. package/dist/chunk-VXH5Y4FO.js +6761 -0
  29. package/dist/chunk-WED4LM5N.js +322 -0
  30. package/dist/{chunk-74WVVWJ4.js → chunk-YOKL7RB5.js} +184 -15
  31. package/dist/chunk-Z53CAR7G.js +298 -0
  32. package/dist/{ci-JQ56YIKC.js → ci-X3U2W4HC.js} +124 -26
  33. package/dist/cloud-2F3NLVHN.js +274 -0
  34. package/dist/{codemap-HMYBXJL2.js → codemap-XNGMAF3F.js} +37 -37
  35. package/dist/codex-MB5YTMRT.js +132 -0
  36. package/dist/{config-YYWEN7U2.js → config-OOELBYTH.js} +1 -1
  37. package/dist/dist-2BJYR5EI.js +59 -0
  38. package/dist/dist-3EIQTZHT.js +1380 -0
  39. package/dist/{dist-WAMAQVPK.js → dist-4U5L2X2C.js} +2 -2
  40. package/dist/{dist-4XTJ6HLM.js → dist-54KAMNLO.js} +16 -15
  41. package/dist/dist-6M4MZWZW.js +58 -0
  42. package/dist/dist-6X576SU2.js +27 -0
  43. package/dist/dist-7QOEYLFX.js +103 -0
  44. package/dist/dist-AYBGHEDY.js +2541 -0
  45. package/dist/dist-EK45QNEM.js +45 -0
  46. package/dist/{dist-U7ZIJMZD.js → dist-FKFEJRPX.js} +16 -15
  47. package/dist/dist-GTEJUBBT.js +66 -0
  48. package/dist/dist-HA74OKJZ.js +40 -0
  49. package/dist/{dist-XG2GG5SD.js → dist-HU5RZAON.js} +14 -2
  50. package/dist/dist-IYE3OBRB.js +374 -0
  51. package/dist/{dist-7WLLPWWB.js → dist-JLU26AB6.js} +12 -9
  52. package/dist/{dist-6G7JC2RA.js → dist-KUCI6JFE.js} +49 -9
  53. package/dist/dist-NUEMFZFL.js +33 -0
  54. package/dist/{dist-GWGTAHNM.js → dist-NUXMDXZ3.js} +31 -3
  55. package/dist/{dist-5R4RYNQO.js → dist-YCNWHSLN.js} +15 -5
  56. package/dist/{dist-6MFVWIFF.js → dist-YFFG2ZD6.js} +9 -16
  57. package/dist/dist-ZG4OKCSR.js +15 -0
  58. package/dist/doctor-SI4LLLDZ.js +345 -0
  59. package/dist/{export-import-4A5MWLIA.js → export-import-JFQH4KSJ.js} +1 -1
  60. package/dist/{history-RNUWO4JZ.js → history-5NE46ZAH.js} +7 -7
  61. package/dist/{hooks-installer-K2JXEBNN.js → hooks-installer-UN5JZLDQ.js} +2 -2
  62. package/dist/index.js +394 -618
  63. package/dist/{init-NQWFZPKO.js → init-5FK3VKRT.js} +76 -10
  64. package/dist/job-HIDMAFW2.js +376 -0
  65. package/dist/jobs.memory-PLMMSFHB-VBECCTHN.js +33 -0
  66. package/dist/kiro-VMUHDFGK.js +153 -0
  67. package/dist/{launchd-OYXUAVW6.js → launchd-6AWT54HR.js} +9 -17
  68. package/dist/mcp-PDUD7SGP.js +249 -0
  69. package/dist/mcp-installer-PQU3XOGO.js +259 -0
  70. package/dist/mcp-setup-OA7IB3H3.js +263 -0
  71. package/dist/{memory-D6ZFFCI2.js → memory-ZNAEAK3B.js} +17 -17
  72. package/dist/{ollama-3XCUZMZT-FYKHW4TZ.js → ollama-3XCUZMZT-4JMH6B7P.js} +1 -1
  73. package/dist/{openai-E7G2YAHU-IG33BFYF.js → openai-E7G2YAHU-T3HMBPH7.js} +2 -2
  74. package/dist/portal-JYWVHXDU.js +210 -0
  75. package/dist/prd-Q4J5NVAR.js +408 -0
  76. package/dist/repos-WWZXNN3P.js +271 -0
  77. package/dist/review-integration-5WHEJU2A.js +14 -0
  78. package/dist/{rules-3OFGWHP4.js → rules-Y4VSOY5Y.js} +3 -3
  79. package/dist/run-VPNXEIBY.js +687 -0
  80. package/dist/server-COL4AXKU-P7S7NNF6.js +11 -0
  81. package/dist/server-KKSETHDV-XSSLEENT.js +20 -0
  82. package/dist/{skills-GY2CTPWN.js → skills-QEYU2N27.js} +4 -2
  83. package/dist/start-JYOEL7AJ.js +303 -0
  84. package/dist/{status-SE43TIFJ.js → status-BHQYYGAL.js} +2 -2
  85. package/dist/{templates-O2XDKB5R.js → templates-CBRUJ66V.js} +6 -5
  86. package/dist/tui-DP7736EX.js +61 -0
  87. package/dist/ulpi-5EN6JCAS-LFE3WSL4.js +10 -0
  88. package/dist/{uninstall-KWGSGZTI.js → uninstall-ICUV6DDV.js} +3 -3
  89. package/dist/{update-QYZA4D23.js → update-7ZMAYRBH.js} +3 -3
  90. package/dist/{version-checker-MVB74DEX.js → version-checker-4ZFMZA7Y.js} +2 -2
  91. package/package.json +39 -31
  92. package/dist/chunk-26LLDX2T.js +0 -553
  93. package/dist/chunk-DDRLI6JU.js +0 -331
  94. package/dist/chunk-IFATANHR.js +0 -453
  95. package/dist/chunk-JWUUVXIV.js +0 -13694
  96. package/dist/chunk-LD52XG3X.js +0 -4273
  97. package/dist/chunk-MIAQVCFW.js +0 -39
  98. package/dist/chunk-YYZOFYS6.js +0 -415
  99. package/dist/dist-XD4YI27T.js +0 -26
  100. package/dist/mcp-installer-TOYDP77X.js +0 -124
  101. package/dist/projects-COUJP4ZC.js +0 -271
  102. package/dist/review-KMGP2S25.js +0 -152
  103. package/dist/server-USLHY6GH-F4JSXCWA.js +0 -18
  104. package/dist/server-X5P6WH2M-ULZF5WHZ.js +0 -11
  105. package/dist/skills/ulpi-generate-guardian/SKILL.md +0 -750
  106. package/dist/skills/ulpi-generate-guardian/references/framework-rules.md +0 -849
  107. package/dist/skills/ulpi-generate-guardian/references/language-rules.md +0 -591
  108. package/dist/ui-4SM2SUI6.js +0 -167
  109. package/dist/ui.html +0 -698
@@ -1,16 +1,13 @@
1
+ import {
2
+ extractTagsFromTree
3
+ } from "./chunk-AWOSRA5F.js";
1
4
  import {
2
5
  commitInWorktree,
3
6
  copyAndStage,
4
7
  historyBranchExists,
5
8
  withWorktree,
6
9
  writeAndStage
7
- } from "./chunk-L3PWNHSA.js";
8
- import {
9
- CodemapConfigSchema
10
- } from "./chunk-74WVVWJ4.js";
11
- import {
12
- extractTagsFromTree
13
- } from "./chunk-DOIKS6C5.js";
10
+ } from "./chunk-3WB5CXH4.js";
14
11
  import {
15
12
  LOGS_DIR,
16
13
  codemapBranchDir,
@@ -23,7 +20,10 @@ import {
23
20
  getCodemapBranch,
24
21
  getCurrentBranch,
25
22
  projectCodemapDir
26
- } from "./chunk-DDRLI6JU.js";
23
+ } from "./chunk-C7CLUQI6.js";
24
+ import {
25
+ CodemapConfigSchema
26
+ } from "./chunk-YOKL7RB5.js";
27
27
 
28
28
  // ../../packages/codemap-engine/dist/index.js
29
29
  import * as fs from "fs";
@@ -47,6 +47,174 @@ import * as path7 from "path";
47
47
  import { connect } from "@lancedb/lancedb";
48
48
  import * as fs9 from "fs";
49
49
  import * as path11 from "path";
50
+
51
+ // ../../packages/embed-engine/dist/index.js
52
+ async function createEmbedder(config) {
53
+ switch (config.provider) {
54
+ case "openai": {
55
+ const { OpenAIEmbedder: OpenAIEmbedder2 } = await import("./openai-E7G2YAHU-T3HMBPH7.js");
56
+ return new OpenAIEmbedder2(config.model, config.dimensions);
57
+ }
58
+ case "ollama": {
59
+ const { OllamaEmbedder: OllamaEmbedder2 } = await import("./ollama-3XCUZMZT-4JMH6B7P.js");
60
+ return new OllamaEmbedder2(config.model, config.dimensions);
61
+ }
62
+ case "ulpi": {
63
+ const { UlpiEmbedder: UlpiEmbedder2 } = await import("./ulpi-5EN6JCAS-LFE3WSL4.js");
64
+ return new UlpiEmbedder2(config.model, config.dimensions, config.baseUrl);
65
+ }
66
+ default:
67
+ throw new Error(`Unknown embedding provider: ${config.provider}`);
68
+ }
69
+ }
70
+ async function embedOne(embedder, text) {
71
+ const [vector] = await embedder.embed([text]);
72
+ return vector;
73
+ }
74
+ async function embedAll(embedder, texts, options) {
75
+ if (texts.length === 0) return [];
76
+ const {
77
+ onProgress,
78
+ onBatch,
79
+ chunkSize = 100,
80
+ timeoutMs = 3e5,
81
+ pollIntervalMs = 2e3,
82
+ batchSubmitSize = 1e3
83
+ } = options ?? {};
84
+ if (embedder.supportsBatch && embedder.submitBatch && embedder.pollBatch) {
85
+ return embedAllViaBatch(embedder, texts, {
86
+ onProgress,
87
+ onBatch,
88
+ timeoutMs,
89
+ pollIntervalMs,
90
+ batchSubmitSize
91
+ });
92
+ }
93
+ return embedAllViaSync(embedder, texts, {
94
+ onProgress,
95
+ onBatch,
96
+ chunkSize
97
+ });
98
+ }
99
+ async function embedAllViaBatch(embedder, texts, opts) {
100
+ const { onProgress, onBatch, timeoutMs, pollIntervalMs, batchSubmitSize } = opts;
101
+ const total = texts.length;
102
+ const collected = onBatch ? [] : new Array(total);
103
+ let globalProcessed = 0;
104
+ const MAX_POLL_ERRORS = 5;
105
+ for (let offset = 0; offset < total; offset += batchSubmitSize) {
106
+ const end = Math.min(offset + batchSubmitSize, total);
107
+ const batchTexts = texts.slice(offset, end);
108
+ const batchNum = Math.floor(offset / batchSubmitSize) + 1;
109
+ const totalBatches = Math.ceil(total / batchSubmitSize);
110
+ onProgress?.({
111
+ current: globalProcessed,
112
+ total,
113
+ message: `Submitting batch ${batchNum}/${totalBatches} (${batchTexts.length} texts)...`
114
+ });
115
+ const batchId = await embedder.submitBatch(batchTexts);
116
+ console.error(
117
+ `[embed-engine] Batch ${batchNum}/${totalBatches} submitted (${batchId.slice(0, 8)}...), starting poll loop...`
118
+ );
119
+ onProgress?.({
120
+ current: globalProcessed,
121
+ total,
122
+ message: `Batch ${batchNum}/${totalBatches} (${batchId.slice(0, 8)}...) polling...`
123
+ });
124
+ const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : 0;
125
+ let watermark = 0;
126
+ let pollCount = 0;
127
+ let consecutiveErrors = 0;
128
+ while (deadline === 0 || Date.now() < deadline) {
129
+ pollCount++;
130
+ let status;
131
+ try {
132
+ status = await embedder.pollBatch(batchId);
133
+ consecutiveErrors = 0;
134
+ } catch (err) {
135
+ consecutiveErrors++;
136
+ const msg = err instanceof Error ? err.message : String(err);
137
+ console.error(
138
+ `[embed-engine] Poll error #${consecutiveErrors} for batch ${batchId.slice(0, 8)}...: ${msg}`
139
+ );
140
+ if (consecutiveErrors >= MAX_POLL_ERRORS) {
141
+ throw new Error(
142
+ `Batch polling failed after ${MAX_POLL_ERRORS} consecutive errors (batch ${batchId}). Last error: ${msg}`
143
+ );
144
+ }
145
+ await new Promise((resolve2) => setTimeout(resolve2, pollIntervalMs * 2));
146
+ continue;
147
+ }
148
+ if (status.results && status.results.length > watermark) {
149
+ const newStart = watermark;
150
+ const newCount = status.results.length - watermark;
151
+ const newEmbeddings = status.results.slice(newStart, newStart + newCount);
152
+ if (onBatch) {
153
+ await onBatch(newEmbeddings, offset + newStart, newCount);
154
+ } else {
155
+ for (let i = 0; i < newCount; i++) {
156
+ collected[offset + newStart + i] = newEmbeddings[i];
157
+ }
158
+ }
159
+ watermark = status.results.length;
160
+ console.error(
161
+ `[embed-engine] Batch ${batchId.slice(0, 8)}... delivered ${watermark}/${batchTexts.length} embeddings`
162
+ );
163
+ }
164
+ if (status.status === "failed") {
165
+ throw new Error(
166
+ `Batch embedding failed (batch ${batchId}). ${globalProcessed + watermark} of ${total} texts were processed before failure.`
167
+ );
168
+ }
169
+ const currentProcessed = globalProcessed + watermark;
170
+ onProgress?.({
171
+ current: currentProcessed,
172
+ total,
173
+ message: `Embedded ${currentProcessed}/${total}`
174
+ });
175
+ if (status.status === "completed") {
176
+ console.error(
177
+ `[embed-engine] Batch ${batchId.slice(0, 8)}... completed after ${pollCount} polls, ${watermark} embeddings`
178
+ );
179
+ break;
180
+ }
181
+ await new Promise((resolve2) => setTimeout(resolve2, pollIntervalMs));
182
+ }
183
+ if (watermark < batchTexts.length && deadline > 0 && Date.now() >= deadline) {
184
+ throw new Error(
185
+ `Batch embedding timed out after ${Math.round(timeoutMs / 1e3)}s (batch ${batchId}). ${globalProcessed + watermark} of ${total} texts were processed.`
186
+ );
187
+ }
188
+ globalProcessed += batchTexts.length;
189
+ }
190
+ console.error(
191
+ `[embed-engine] All ${Math.ceil(total / batchSubmitSize)} batches complete, ${globalProcessed} embeddings total`
192
+ );
193
+ return onBatch ? [] : collected;
194
+ }
195
+ async function embedAllViaSync(embedder, texts, opts) {
196
+ const { onProgress, onBatch, chunkSize } = opts;
197
+ const total = texts.length;
198
+ const collected = [];
199
+ for (let i = 0; i < total; i += chunkSize) {
200
+ const chunk = texts.slice(i, i + chunkSize);
201
+ const embeddings = await embedder.embed(chunk);
202
+ if (onBatch) {
203
+ await onBatch(embeddings, i, embeddings.length);
204
+ } else {
205
+ collected.push(...embeddings);
206
+ }
207
+ const processed = Math.min(i + chunkSize, total);
208
+ onProgress?.({
209
+ current: processed,
210
+ total,
211
+ message: `Embedded ${processed}/${total}`
212
+ });
213
+ }
214
+ return onBatch ? [] : collected;
215
+ }
216
+
217
+ // ../../packages/codemap-engine/dist/index.js
50
218
  import * as fs6 from "fs";
51
219
  import * as path8 from "path";
52
220
  import * as fs7 from "fs";
@@ -931,24 +1099,6 @@ function diffManifest(oldManifest, newFiles) {
931
1099
  }
932
1100
  return { added, updated, removed };
933
1101
  }
934
- async function createEmbedder(config) {
935
- switch (config.provider) {
936
- case "openai": {
937
- const { OpenAIEmbedder: OpenAIEmbedder2 } = await import("./openai-E7G2YAHU-IG33BFYF.js");
938
- return new OpenAIEmbedder2(config.model, config.dimensions);
939
- }
940
- case "ollama": {
941
- const { OllamaEmbedder: OllamaEmbedder2 } = await import("./ollama-3XCUZMZT-FYKHW4TZ.js");
942
- return new OllamaEmbedder2(config.model, config.dimensions);
943
- }
944
- case "ulpi": {
945
- const { UlpiEmbedder } = await import("./ulpi-RMMCUAGP-EWYUE7RU.js");
946
- return new UlpiEmbedder(config.model, config.dimensions, config.baseUrl);
947
- }
948
- default:
949
- throw new Error(`Unknown embedding provider: ${config.provider}`);
950
- }
951
- }
952
1102
  var CodemapStore = class {
953
1103
  db = null;
954
1104
  table = null;
@@ -1002,14 +1152,44 @@ var CodemapStore = class {
1002
1152
  await this.table.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(records);
1003
1153
  }
1004
1154
  }
1155
+ /**
1156
+ * Append items to the store without merge/upsert semantics.
1157
+ * Uses simple `add()` which only creates data fragments (no `_deletions/` files).
1158
+ * Use this for bulk initial indexing where no duplicate IDs exist.
1159
+ */
1160
+ async appendItems(items) {
1161
+ if (items.length === 0) return;
1162
+ const records = items.map((item) => ({
1163
+ id: item.id,
1164
+ vector: item.vector,
1165
+ filePath: item.metadata.filePath,
1166
+ startLine: item.metadata.startLine,
1167
+ endLine: item.metadata.endLine,
1168
+ snippet: item.metadata.snippet
1169
+ }));
1170
+ if (!this.table) {
1171
+ this.table = await this.db.createTable("chunks", records);
1172
+ } else {
1173
+ await this.table.add(records);
1174
+ }
1175
+ }
1005
1176
  /**
1006
1177
  * Remove items by their chunk IDs.
1007
1178
  * Uses SQL IN clause with properly escaped string literals.
1179
+ * Silently ignores errors from missing data files (stale fragment references).
1008
1180
  */
1009
1181
  async removeItems(chunkIds) {
1010
1182
  if (!this.table || chunkIds.length === 0) return;
1011
1183
  const quoted = chunkIds.map((id) => "'" + id.replace(/'/g, "''") + "'").join(", ");
1012
- await this.table.delete("id IN (" + quoted + ")");
1184
+ try {
1185
+ await this.table.delete("id IN (" + quoted + ")");
1186
+ } catch (err) {
1187
+ const msg = err instanceof Error ? err.message : String(err);
1188
+ if (/Not found.*\.lance/i.test(msg) || /LanceError/i.test(msg)) {
1189
+ return;
1190
+ }
1191
+ throw err;
1192
+ }
1013
1193
  }
1014
1194
  /**
1015
1195
  * Query the store for similar vectors.
@@ -1034,6 +1214,26 @@ var CodemapStore = class {
1034
1214
  if (!this.table) return 0;
1035
1215
  return this.table.countRows();
1036
1216
  }
1217
+ /**
1218
+ * Close the LanceDB connection and table, releasing underlying native resources.
1219
+ * After calling close(), the store cannot be used — create a new instance instead.
1220
+ */
1221
+ close() {
1222
+ if (this.table) {
1223
+ try {
1224
+ this.table.close();
1225
+ } catch {
1226
+ }
1227
+ this.table = null;
1228
+ }
1229
+ if (this.db) {
1230
+ try {
1231
+ this.db.close();
1232
+ } catch {
1233
+ }
1234
+ this.db = null;
1235
+ }
1236
+ }
1037
1237
  /**
1038
1238
  * Get the index directory size in bytes.
1039
1239
  * Walks recursively since LanceDB stores data in subdirectories with fragment files.
@@ -1663,7 +1863,7 @@ async function runPipelineInner(projectDir, onProgress, branch) {
1663
1863
  let depgraphResult;
1664
1864
  if (allTags.size > 0) {
1665
1865
  try {
1666
- const { buildReferenceGraph, computePageRank, savePageRank, computeMetrics, saveMetrics, saveGraph } = await import("./dist-WAMAQVPK.js");
1866
+ const { buildReferenceGraph, computePageRank, savePageRank, computeMetrics, saveMetrics, saveGraph } = await import("./dist-4U5L2X2C.js");
1667
1867
  onProgress?.({
1668
1868
  phase: "graph",
1669
1869
  current: 0,
@@ -1735,6 +1935,7 @@ async function runPipelineInner(projectDir, onProgress, branch) {
1735
1935
  };
1736
1936
  writeStats(projectDir, resolvedBranch, stats);
1737
1937
  if (embeddingError) {
1938
+ store.close();
1738
1939
  onProgress?.({
1739
1940
  phase: "finalizing",
1740
1941
  current: 3,
@@ -1749,6 +1950,7 @@ async function runPipelineInner(projectDir, onProgress, branch) {
1749
1950
  total: 3,
1750
1951
  message: "Done"
1751
1952
  });
1953
+ store.close();
1752
1954
  return {
1753
1955
  totalFiles: scannedFiles.length,
1754
1956
  totalChunks: chunks.length,
@@ -1819,7 +2021,7 @@ async function rebuildDepgraphInner(projectDir, onProgress, branch) {
1819
2021
  log("warn", "No tags extracted \u2014 cannot build depgraph");
1820
2022
  return { nodeCount: 0, edgeCount: 0, definitionCount: 0, referenceCount: 0, cycleCount: 0, durationMs: Date.now() - startTime, taggedFiles: 0, totalFiles: scannedFiles.length };
1821
2023
  }
1822
- const { buildReferenceGraph, computePageRank, savePageRank, computeMetrics, saveMetrics, saveGraph } = await import("./dist-WAMAQVPK.js");
2024
+ const { buildReferenceGraph, computePageRank, savePageRank, computeMetrics, saveMetrics, saveGraph } = await import("./dist-4U5L2X2C.js");
1823
2025
  onProgress?.({ phase: "graph", current: 0, total: 3, message: "Building dependency graph..." });
1824
2026
  const graph = buildReferenceGraph(allTags, filePaths);
1825
2027
  for (const sf of scannedFiles) {
@@ -1854,121 +2056,39 @@ var STORE_BATCH_SIZE = 5e3;
1854
2056
  async function embedAndStore(embedder, texts, chunks, store, batchConfig, onProgress) {
1855
2057
  if (texts.length === 0) return;
1856
2058
  const total = texts.length;
1857
- if (embedder.supportsBatch && embedder.submitBatch && embedder.pollBatch) {
1858
- await embedAndStoreBatch(embedder, texts, chunks, store, batchConfig, onProgress);
1859
- return;
1860
- }
1861
2059
  onProgress?.({
1862
2060
  phase: "embedding",
1863
2061
  current: 0,
1864
2062
  total,
1865
2063
  message: "Creating embeddings..."
1866
2064
  });
1867
- const allEmbeddings = [];
1868
- for (let i = 0; i < texts.length; i += batchConfig.size) {
1869
- const batch = texts.slice(i, i + batchConfig.size);
1870
- const embeddings = await embedder.embed(batch);
1871
- allEmbeddings.push(...embeddings);
1872
- const processed = Math.min(i + batchConfig.size, total);
1873
- onProgress?.({
1874
- phase: "embedding",
1875
- current: processed,
1876
- total,
1877
- message: `Embedded ${processed}/${total} chunks`
1878
- });
1879
- }
1880
- onProgress?.({
1881
- phase: "storing",
1882
- current: 0,
1883
- total,
1884
- message: "Storing vectors..."
1885
- });
1886
- for (let i = 0; i < allEmbeddings.length; i += STORE_BATCH_SIZE) {
1887
- const items = buildVectorItems(chunks, allEmbeddings, i, Math.min(i + STORE_BATCH_SIZE, allEmbeddings.length));
1888
- await store.upsertItems(items);
1889
- const stored = Math.min(i + STORE_BATCH_SIZE, allEmbeddings.length);
1890
- onProgress?.({
1891
- phase: "storing",
1892
- current: stored,
1893
- total,
1894
- message: `Stored ${stored}/${total} vectors`
1895
- });
1896
- }
1897
- }
1898
- async function embedAndStoreBatch(embedder, texts, chunks, store, batchConfig, onProgress) {
1899
- const total = texts.length;
1900
- onProgress?.({
1901
- phase: "embedding",
1902
- current: 0,
1903
- total,
1904
- message: `Submitting batch of ${total} texts...`
1905
- });
1906
- const batchId = await embedder.submitBatch(texts);
1907
- log("info", `Batch submitted: id=${batchId}, texts=${total}`);
1908
- onProgress?.({
1909
- phase: "embedding",
1910
- current: 0,
1911
- total,
1912
- message: `Batch ${batchId.slice(0, 8)}... submitted, polling...`
1913
- });
1914
- await pollAndStoreProgressively(embedder, batchId, chunks, store, batchConfig, total, onProgress);
1915
- }
1916
- async function pollAndStoreProgressively(embedder, batchId, chunks, store, batchConfig, total, onProgress) {
1917
- const deadline = batchConfig.timeoutMs > 0 ? Date.now() + batchConfig.timeoutMs : 0;
1918
- let pollCount = 0;
1919
- let watermark = 0;
1920
- while (deadline === 0 || Date.now() < deadline) {
1921
- const status = await embedder.pollBatch(batchId);
1922
- pollCount++;
1923
- if (pollCount <= 3 || pollCount % 10 === 0) {
1924
- log("info", `Poll #${pollCount} batch=${batchId.slice(0, 8)}: status=${status.status}, processed=${status.processedInputs}/${status.totalInputs}, watermark=${watermark}`);
1925
- }
1926
- if (status.results && status.results.length > watermark) {
1927
- const newCount = status.results.length - watermark;
1928
- try {
1929
- for (let i = watermark; i < status.results.length; i += STORE_BATCH_SIZE) {
1930
- const end = Math.min(i + STORE_BATCH_SIZE, status.results.length);
1931
- const items = buildVectorItems(chunks, status.results, i, end);
1932
- await store.upsertItems(items);
1933
- }
1934
- const prevWatermark = watermark;
1935
- watermark = status.results.length;
1936
- log("info", `Stored ${newCount} new embeddings (${prevWatermark}\u2192${watermark}/${total})`);
1937
- } catch (storeErr) {
1938
- log("error", `Store failed at watermark=${watermark}: ${storeErr instanceof Error ? storeErr.message : String(storeErr)}`);
1939
- }
1940
- }
1941
- if (status.status === "failed") {
1942
- log("error", `Batch ${batchId.slice(0, 8)} failed (watermark=${watermark}/${total} stored)`);
1943
- throw new Error(`Batch embedding failed (batch ${batchId}). ${watermark} of ${total} chunks were stored before failure.`);
1944
- }
1945
- onProgress?.({
1946
- phase: "embedding",
1947
- current: watermark,
1948
- total,
1949
- message: `Embedded & stored ${watermark}/${total} chunks`
1950
- });
1951
- if (status.status === "completed") {
1952
- log("info", `Batch ${batchId.slice(0, 8)} completed: ${watermark}/${total} stored`);
2065
+ await embedAll(embedder, texts, {
2066
+ onProgress: (info) => {
1953
2067
  onProgress?.({
1954
2068
  phase: "embedding",
1955
- current: total,
1956
- total,
1957
- message: `Embedded & stored ${total}/${total} chunks`
2069
+ current: info.current,
2070
+ total: info.total,
2071
+ message: info.message
1958
2072
  });
1959
- return;
1960
- }
1961
- await new Promise((resolve2) => setTimeout(resolve2, batchConfig.pollIntervalMs));
1962
- }
1963
- log("error", `Batch ${batchId} timed out after ${Math.round(batchConfig.timeoutMs / 1e3)}s (${pollCount} polls, watermark=${watermark}/${total})`);
1964
- throw new Error(
1965
- `Batch embedding timed out after ${Math.round(batchConfig.timeoutMs / 1e3)}s (batch ${batchId}). ${watermark} of ${total} chunks were stored.`
1966
- );
2073
+ },
2074
+ onBatch: async (embeddings, startIndex, count) => {
2075
+ for (let i = 0; i < count; i += STORE_BATCH_SIZE) {
2076
+ const batchEnd = Math.min(i + STORE_BATCH_SIZE, count);
2077
+ const items = buildVectorItemsFromSlice(chunks, embeddings, startIndex, i, batchEnd);
2078
+ await store.appendItems(items);
2079
+ }
2080
+ log("info", `Stored ${count} embeddings at offset ${startIndex}`);
2081
+ },
2082
+ chunkSize: batchConfig.size,
2083
+ timeoutMs: batchConfig.timeoutMs,
2084
+ pollIntervalMs: batchConfig.pollIntervalMs,
2085
+ batchSubmitSize: 1e3
2086
+ });
1967
2087
  }
1968
- function buildVectorItems(chunks, embeddings, from, to) {
2088
+ function buildVectorItemsFromSlice(chunks, embeddings, chunkOffset, embFrom, embTo) {
1969
2089
  const items = [];
1970
- for (let i = from; i < to; i++) {
1971
- const chunk = chunks[i];
2090
+ for (let i = embFrom; i < embTo; i++) {
2091
+ const chunk = chunks[chunkOffset + i];
1972
2092
  items.push({
1973
2093
  id: chunk.id,
1974
2094
  vector: embeddings[i],
@@ -2072,7 +2192,12 @@ async function searchCode(projectDir, query, options = {}) {
2072
2192
  const resolvedBranch = options.branch ?? getCurrentBranch(projectDir);
2073
2193
  const config = loadCodemapConfig(projectDir);
2074
2194
  const embedder = await createEmbedder(config.embedding);
2075
- const [queryVector] = await embedder.embed([query]);
2195
+ const embedPromise = embedOne(embedder, query);
2196
+ const timeoutMs = config.searchTimeoutMs;
2197
+ const timeoutPromise = new Promise(
2198
+ (_, reject) => setTimeout(() => reject(new Error(`Embedding timed out after ${timeoutMs}ms`)), timeoutMs)
2199
+ );
2200
+ const queryVector = await Promise.race([embedPromise, timeoutPromise]);
2076
2201
  const store = new CodemapStore(projectDir, resolvedBranch);
2077
2202
  await store.initialize();
2078
2203
  const hybridConfig = config.hybrid;
@@ -2090,7 +2215,7 @@ async function searchCode(projectDir, query, options = {}) {
2090
2215
  let graphRanks;
2091
2216
  if (weights.graphRank && weights.graphRank > 0) {
2092
2217
  try {
2093
- const { loadPageRankMap } = await import("./dist-WAMAQVPK.js");
2218
+ const { loadPageRankMap } = await import("./dist-4U5L2X2C.js");
2094
2219
  graphRanks = loadPageRankMap(projectDir, resolvedBranch) ?? void 0;
2095
2220
  } catch {
2096
2221
  }
@@ -2330,7 +2455,7 @@ async function processIncremental(projectDir, events, config, store, embedder, b
2330
2455
  snippet: chunk.content.slice(0, 200)
2331
2456
  }
2332
2457
  }));
2333
- await store.upsertItems(vectorItems);
2458
+ await store.appendItems(vectorItems);
2334
2459
  if (bm25Index) {
2335
2460
  const bm25Docs = chunks.map((c) => ({
2336
2461
  id: c.id,
@@ -2427,6 +2552,19 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
2427
2552
  "__pycache__",
2428
2553
  ".tsbuildinfo"
2429
2554
  ]);
2555
+ var LANCE_CORRUPTION_PATTERNS = [
2556
+ /Not found:.*\.lance/i,
2557
+ /LanceError/i,
2558
+ /No such file or directory.*lance/i,
2559
+ /corrupted/i,
2560
+ /Invalid IPC message/i,
2561
+ /Panic in async function/i,
2562
+ /thread '.*' panicked/i
2563
+ ];
2564
+ function isIndexCorruptionError(err) {
2565
+ const message = err instanceof Error ? err.message : String(err);
2566
+ return LANCE_CORRUPTION_PATTERNS.some((pattern) => pattern.test(message));
2567
+ }
2430
2568
  var MAX_RECENT_EVENTS = 20;
2431
2569
  var CodemapWatcher = class {
2432
2570
  projectDir;
@@ -2441,6 +2579,7 @@ var CodemapWatcher = class {
2441
2579
  _recentEvents = [];
2442
2580
  _totalEventsProcessed = 0;
2443
2581
  _lastFlushAt = null;
2582
+ _store = null;
2444
2583
  constructor(options) {
2445
2584
  this.projectDir = options.projectDir;
2446
2585
  this.branch = options.branch ?? getCurrentBranch(options.projectDir);
@@ -2471,12 +2610,48 @@ var CodemapWatcher = class {
2471
2610
  async start() {
2472
2611
  if (this.running) return;
2473
2612
  this.running = true;
2474
- const config = loadCodemapConfig(this.projectDir);
2475
- const embedder = await createEmbedder(config.embedding);
2476
- const store = new CodemapStore(this.projectDir, this.branch);
2613
+ let config = loadCodemapConfig(this.projectDir);
2614
+ let embedder = await createEmbedder(config.embedding);
2615
+ let store = new CodemapStore(this.projectDir, this.branch);
2477
2616
  await store.initialize();
2478
- const ignorePatterns = loadCodemapIgnore(this.projectDir);
2479
- const denyPatterns = [...config.deny, ...ignorePatterns];
2617
+ this._store = store;
2618
+ try {
2619
+ await store.getItemCount();
2620
+ } catch (err) {
2621
+ if (isIndexCorruptionError(err)) {
2622
+ console.warn(
2623
+ `[codemap-watcher] LanceDB index corrupted on startup, rebuilding...`
2624
+ );
2625
+ store.close();
2626
+ const lanceDir = codemapLanceDir(this.projectDir, this.branch);
2627
+ fs12.rmSync(lanceDir, { recursive: true, force: true });
2628
+ await runInitPipeline(this.projectDir, void 0, this.branch);
2629
+ store = new CodemapStore(this.projectDir, this.branch);
2630
+ await store.initialize();
2631
+ this._store = store;
2632
+ config = loadCodemapConfig(this.projectDir);
2633
+ embedder = await createEmbedder(config.embedding);
2634
+ console.log(`[codemap-watcher] Index rebuilt successfully`);
2635
+ } else {
2636
+ throw err;
2637
+ }
2638
+ }
2639
+ const RECOVERY_COOLDOWN_MS = 5 * 60 * 1e3;
2640
+ let lastRecoveryAttempt = 0;
2641
+ let recovering = false;
2642
+ let cachedDenyPatterns = null;
2643
+ let denyPatternsReadAt = 0;
2644
+ const DENY_CACHE_TTL_MS = 5e3;
2645
+ const getDenyPatterns = () => {
2646
+ const now = Date.now();
2647
+ if (cachedDenyPatterns && now - denyPatternsReadAt < DENY_CACHE_TTL_MS) {
2648
+ return cachedDenyPatterns;
2649
+ }
2650
+ const ignorePatterns = loadCodemapIgnore(this.projectDir);
2651
+ cachedDenyPatterns = [...config.deny, ...ignorePatterns];
2652
+ denyPatternsReadAt = now;
2653
+ return cachedDenyPatterns;
2654
+ };
2480
2655
  const processBatch = async (initialEvents) => {
2481
2656
  this.processing = true;
2482
2657
  let events = initialEvents;
@@ -2486,7 +2661,37 @@ var CodemapWatcher = class {
2486
2661
  this._totalEventsProcessed += events.length;
2487
2662
  this._lastFlushAt = (/* @__PURE__ */ new Date()).toISOString();
2488
2663
  } catch (err) {
2489
- console.error(`[codemap-watcher] Incremental update error: ${err instanceof Error ? err.message : String(err)}`);
2664
+ const msg = err instanceof Error ? err.message : String(err);
2665
+ if (isIndexCorruptionError(err) && !recovering && Date.now() - lastRecoveryAttempt > RECOVERY_COOLDOWN_MS) {
2666
+ recovering = true;
2667
+ lastRecoveryAttempt = Date.now();
2668
+ console.warn(
2669
+ `[codemap-watcher] Detected corrupted LanceDB index, auto-recovering via full re-index...`
2670
+ );
2671
+ try {
2672
+ store.close();
2673
+ this._store = null;
2674
+ const lanceDir = codemapLanceDir(this.projectDir, this.branch);
2675
+ fs12.rmSync(lanceDir, { recursive: true, force: true });
2676
+ await runInitPipeline(this.projectDir, void 0, this.branch);
2677
+ store = new CodemapStore(this.projectDir, this.branch);
2678
+ await store.initialize();
2679
+ this._store = store;
2680
+ const freshConfig = loadCodemapConfig(this.projectDir);
2681
+ embedder = await createEmbedder(freshConfig.embedding);
2682
+ this.pendingEvents = [];
2683
+ console.log(`[codemap-watcher] Index recovered successfully via full re-index`);
2684
+ } catch (recoveryErr) {
2685
+ console.error(
2686
+ `[codemap-watcher] Auto-recovery failed: ${recoveryErr instanceof Error ? recoveryErr.message : String(recoveryErr)}`
2687
+ );
2688
+ } finally {
2689
+ recovering = false;
2690
+ }
2691
+ break;
2692
+ } else if (!recovering) {
2693
+ console.error(`[codemap-watcher] Incremental update error: ${msg}`);
2694
+ }
2490
2695
  }
2491
2696
  events = this.drainPendingEvents();
2492
2697
  }
@@ -2507,7 +2712,7 @@ var CodemapWatcher = class {
2507
2712
  }
2508
2713
  const ext = path14.extname(relPath).toLowerCase();
2509
2714
  if (BINARY_EXTENSIONS2.has(ext)) return false;
2510
- if (matchesDenyPattern(relPath, denyPatterns)) return false;
2715
+ if (matchesDenyPattern(relPath, getDenyPatterns())) return false;
2511
2716
  return true;
2512
2717
  };
2513
2718
  try {
@@ -2576,15 +2781,18 @@ var CodemapWatcher = class {
2576
2781
  const deduped = /* @__PURE__ */ new Map();
2577
2782
  for (const e of [...queued, ...pending]) deduped.set(e.filePath, e);
2578
2783
  const remaining = Array.from(deduped.values());
2579
- if (remaining.length > 0) {
2784
+ if (remaining.length > 0 && this._store) {
2580
2785
  try {
2581
2786
  const config = loadCodemapConfig(this.projectDir);
2582
2787
  const embedder = await createEmbedder(config.embedding);
2583
- const store = new CodemapStore(this.projectDir, this.branch);
2584
- await processIncremental(this.projectDir, remaining, config, store, embedder, this.branch);
2788
+ await processIncremental(this.projectDir, remaining, config, this._store, embedder, this.branch);
2585
2789
  } catch {
2586
2790
  }
2587
2791
  }
2792
+ if (this._store) {
2793
+ this._store.close();
2794
+ this._store = null;
2795
+ }
2588
2796
  this.queue.destroy();
2589
2797
  this.removePidFile();
2590
2798
  }
@@ -2681,16 +2889,9 @@ async function exportIndex(projectDir, branch) {
2681
2889
  }
2682
2890
  const metadataDir = codemapMetadataDir(projectDir, resolvedBranch);
2683
2891
  if (fs13.existsSync(metadataDir)) {
2684
- const metadataFiles = fs13.readdirSync(metadataDir);
2685
- for (const file of metadataFiles) {
2686
- const sourcePath = path15.join(metadataDir, file);
2687
- const stat = fs13.statSync(sourcePath);
2688
- if (stat.isFile()) {
2689
- copyAndStage(worktreeDir, `index/metadata/${file}`, sourcePath);
2690
- totalSizeBytes += stat.size;
2691
- filesExported++;
2692
- }
2693
- }
2892
+ const result = copyMetadataRecursive(metadataDir, worktreeDir, "index/metadata");
2893
+ filesExported += result.fileCount;
2894
+ totalSizeBytes += result.totalBytes;
2694
2895
  }
2695
2896
  const exportMeta = {
2696
2897
  exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -2776,6 +2977,26 @@ function copyDirRecursive(srcDir, worktreeDir, prefix) {
2776
2977
  }
2777
2978
  return { fileCount, totalBytes, warnings };
2778
2979
  }
2980
+ function copyMetadataRecursive(srcDir, worktreeDir, prefix) {
2981
+ let fileCount = 0;
2982
+ let totalBytes = 0;
2983
+ const entries = fs13.readdirSync(srcDir);
2984
+ for (const entry of entries) {
2985
+ const srcPath = path15.join(srcDir, entry);
2986
+ const destRelative = `${prefix}/${entry}`;
2987
+ const stat = fs13.statSync(srcPath);
2988
+ if (stat.isDirectory()) {
2989
+ const sub = copyMetadataRecursive(srcPath, worktreeDir, destRelative);
2990
+ fileCount += sub.fileCount;
2991
+ totalBytes += sub.totalBytes;
2992
+ } else if (stat.isFile()) {
2993
+ copyAndStage(worktreeDir, destRelative, srcPath);
2994
+ totalBytes += stat.size;
2995
+ fileCount++;
2996
+ }
2997
+ }
2998
+ return { fileCount, totalBytes };
2999
+ }
2779
3000
  async function importIndex(projectDir, branch) {
2780
3001
  const resolvedBranch = branch ?? getCurrentBranch(projectDir);
2781
3002
  const branchName = getCodemapBranch(resolvedBranch);
@@ -2827,17 +3048,9 @@ async function importIndex(projectDir, branch) {
2827
3048
  const metadataSrcDir = path16.join(worktreeDir, "index", "metadata");
2828
3049
  if (fs14.existsSync(metadataSrcDir)) {
2829
3050
  const metadataDestDir = path16.join(tmpDir, "index", "metadata");
2830
- fs14.mkdirSync(metadataDestDir, { recursive: true });
2831
- const files = fs14.readdirSync(metadataSrcDir);
2832
- for (const file of files) {
2833
- const src = path16.join(metadataSrcDir, file);
2834
- const stat = fs14.statSync(src);
2835
- if (stat.isFile()) {
2836
- fs14.copyFileSync(src, path16.join(metadataDestDir, file));
2837
- totalSizeBytes += stat.size;
2838
- filesImported++;
2839
- }
2840
- }
3051
+ const result = copyDirRecursiveImport(metadataSrcDir, metadataDestDir);
3052
+ filesImported += result.fileCount;
3053
+ totalSizeBytes += result.totalBytes;
2841
3054
  }
2842
3055
  if (fs14.existsSync(codemapDir)) {
2843
3056
  fs14.rmSync(codemapDir, { recursive: true });
@@ -3113,6 +3326,9 @@ async function runEvalHarness(projectDir, datasetPath) {
3113
3326
  }
3114
3327
 
3115
3328
  export {
3329
+ createEmbedder,
3330
+ embedOne,
3331
+ embedAll,
3116
3332
  DEFAULT_CODEMAP_CONFIG,
3117
3333
  loadCodemapConfig,
3118
3334
  saveCodemapConfig,
@@ -3135,7 +3351,6 @@ export {
3135
3351
  loadManifest,
3136
3352
  saveManifest,
3137
3353
  diffManifest,
3138
- createEmbedder,
3139
3354
  CodemapStore,
3140
3355
  saveSchema,
3141
3356
  loadSchema,