codesift-mcp 0.1.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 (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/cli/args.d.ts +13 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +79 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/commands.d.ts +4 -0
  8. package/dist/cli/commands.d.ts.map +1 -0
  9. package/dist/cli/commands.js +336 -0
  10. package/dist/cli/commands.js.map +1 -0
  11. package/dist/cli/help.d.ts +3 -0
  12. package/dist/cli/help.d.ts.map +1 -0
  13. package/dist/cli/help.js +271 -0
  14. package/dist/cli/help.js.map +1 -0
  15. package/dist/cli.d.ts +3 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +80 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/config.d.ts +23 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +49 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/parser/extractors/go.d.ts +4 -0
  24. package/dist/parser/extractors/go.d.ts.map +1 -0
  25. package/dist/parser/extractors/go.js +185 -0
  26. package/dist/parser/extractors/go.js.map +1 -0
  27. package/dist/parser/extractors/javascript.d.ts +9 -0
  28. package/dist/parser/extractors/javascript.d.ts.map +1 -0
  29. package/dist/parser/extractors/javascript.js +10 -0
  30. package/dist/parser/extractors/javascript.js.map +1 -0
  31. package/dist/parser/extractors/markdown.d.ts +15 -0
  32. package/dist/parser/extractors/markdown.d.ts.map +1 -0
  33. package/dist/parser/extractors/markdown.js +217 -0
  34. package/dist/parser/extractors/markdown.js.map +1 -0
  35. package/dist/parser/extractors/prisma.d.ts +17 -0
  36. package/dist/parser/extractors/prisma.d.ts.map +1 -0
  37. package/dist/parser/extractors/prisma.js +121 -0
  38. package/dist/parser/extractors/prisma.js.map +1 -0
  39. package/dist/parser/extractors/python.d.ts +4 -0
  40. package/dist/parser/extractors/python.d.ts.map +1 -0
  41. package/dist/parser/extractors/python.js +203 -0
  42. package/dist/parser/extractors/python.js.map +1 -0
  43. package/dist/parser/extractors/rust.d.ts +4 -0
  44. package/dist/parser/extractors/rust.d.ts.map +1 -0
  45. package/dist/parser/extractors/rust.js +178 -0
  46. package/dist/parser/extractors/rust.js.map +1 -0
  47. package/dist/parser/extractors/typescript.d.ts +4 -0
  48. package/dist/parser/extractors/typescript.d.ts.map +1 -0
  49. package/dist/parser/extractors/typescript.js +296 -0
  50. package/dist/parser/extractors/typescript.js.map +1 -0
  51. package/dist/parser/languages/tree-sitter-css.wasm +0 -0
  52. package/dist/parser/languages/tree-sitter-go.wasm +0 -0
  53. package/dist/parser/languages/tree-sitter-java.wasm +0 -0
  54. package/dist/parser/languages/tree-sitter-javascript.wasm +0 -0
  55. package/dist/parser/languages/tree-sitter-json.wasm +0 -0
  56. package/dist/parser/languages/tree-sitter-php.wasm +0 -0
  57. package/dist/parser/languages/tree-sitter-python.wasm +0 -0
  58. package/dist/parser/languages/tree-sitter-ruby.wasm +0 -0
  59. package/dist/parser/languages/tree-sitter-rust.wasm +0 -0
  60. package/dist/parser/languages/tree-sitter-tsx.wasm +0 -0
  61. package/dist/parser/languages/tree-sitter-typescript.wasm +0 -0
  62. package/dist/parser/parser-manager.d.ts +6 -0
  63. package/dist/parser/parser-manager.d.ts.map +1 -0
  64. package/dist/parser/parser-manager.js +60 -0
  65. package/dist/parser/parser-manager.js.map +1 -0
  66. package/dist/parser/symbol-extractor.d.ts +22 -0
  67. package/dist/parser/symbol-extractor.d.ts.map +1 -0
  68. package/dist/parser/symbol-extractor.js +115 -0
  69. package/dist/parser/symbol-extractor.js.map +1 -0
  70. package/dist/retrieval/codebase-retrieval.d.ts +27 -0
  71. package/dist/retrieval/codebase-retrieval.d.ts.map +1 -0
  72. package/dist/retrieval/codebase-retrieval.js +472 -0
  73. package/dist/retrieval/codebase-retrieval.js.map +1 -0
  74. package/dist/search/bm25.d.ts +22 -0
  75. package/dist/search/bm25.d.ts.map +1 -0
  76. package/dist/search/bm25.js +179 -0
  77. package/dist/search/bm25.js.map +1 -0
  78. package/dist/search/chunker.d.ts +9 -0
  79. package/dist/search/chunker.d.ts.map +1 -0
  80. package/dist/search/chunker.js +91 -0
  81. package/dist/search/chunker.js.map +1 -0
  82. package/dist/search/hybrid.d.ts +16 -0
  83. package/dist/search/hybrid.d.ts.map +1 -0
  84. package/dist/search/hybrid.js +51 -0
  85. package/dist/search/hybrid.js.map +1 -0
  86. package/dist/search/semantic.d.ts +44 -0
  87. package/dist/search/semantic.d.ts.map +1 -0
  88. package/dist/search/semantic.js +194 -0
  89. package/dist/search/semantic.js.map +1 -0
  90. package/dist/server.d.ts +2 -0
  91. package/dist/server.d.ts.map +1 -0
  92. package/dist/server.js +285 -0
  93. package/dist/server.js.map +1 -0
  94. package/dist/storage/chunk-store.d.ts +32 -0
  95. package/dist/storage/chunk-store.d.ts.map +1 -0
  96. package/dist/storage/chunk-store.js +144 -0
  97. package/dist/storage/chunk-store.js.map +1 -0
  98. package/dist/storage/embedding-store.d.ts +41 -0
  99. package/dist/storage/embedding-store.d.ts.map +1 -0
  100. package/dist/storage/embedding-store.js +149 -0
  101. package/dist/storage/embedding-store.js.map +1 -0
  102. package/dist/storage/index-store.d.ts +23 -0
  103. package/dist/storage/index-store.d.ts.map +1 -0
  104. package/dist/storage/index-store.js +95 -0
  105. package/dist/storage/index-store.js.map +1 -0
  106. package/dist/storage/registry.d.ts +35 -0
  107. package/dist/storage/registry.d.ts.map +1 -0
  108. package/dist/storage/registry.js +99 -0
  109. package/dist/storage/registry.js.map +1 -0
  110. package/dist/storage/usage-stats.d.ts +32 -0
  111. package/dist/storage/usage-stats.d.ts.map +1 -0
  112. package/dist/storage/usage-stats.js +180 -0
  113. package/dist/storage/usage-stats.js.map +1 -0
  114. package/dist/storage/usage-tracker.d.ts +35 -0
  115. package/dist/storage/usage-tracker.d.ts.map +1 -0
  116. package/dist/storage/usage-tracker.js +245 -0
  117. package/dist/storage/usage-tracker.js.map +1 -0
  118. package/dist/storage/watcher.d.ts +12 -0
  119. package/dist/storage/watcher.d.ts.map +1 -0
  120. package/dist/storage/watcher.js +66 -0
  121. package/dist/storage/watcher.js.map +1 -0
  122. package/dist/tools/context-tools.d.ts +31 -0
  123. package/dist/tools/context-tools.d.ts.map +1 -0
  124. package/dist/tools/context-tools.js +219 -0
  125. package/dist/tools/context-tools.js.map +1 -0
  126. package/dist/tools/diff-tools.d.ts +22 -0
  127. package/dist/tools/diff-tools.d.ts.map +1 -0
  128. package/dist/tools/diff-tools.js +165 -0
  129. package/dist/tools/diff-tools.js.map +1 -0
  130. package/dist/tools/generate-tools.d.ts +11 -0
  131. package/dist/tools/generate-tools.d.ts.map +1 -0
  132. package/dist/tools/generate-tools.js +135 -0
  133. package/dist/tools/generate-tools.js.map +1 -0
  134. package/dist/tools/graph-tools.d.ts +60 -0
  135. package/dist/tools/graph-tools.d.ts.map +1 -0
  136. package/dist/tools/graph-tools.js +313 -0
  137. package/dist/tools/graph-tools.js.map +1 -0
  138. package/dist/tools/index-tools.d.ts +39 -0
  139. package/dist/tools/index-tools.d.ts.map +1 -0
  140. package/dist/tools/index-tools.js +451 -0
  141. package/dist/tools/index-tools.js.map +1 -0
  142. package/dist/tools/outline-tools.d.ts +59 -0
  143. package/dist/tools/outline-tools.d.ts.map +1 -0
  144. package/dist/tools/outline-tools.js +342 -0
  145. package/dist/tools/outline-tools.js.map +1 -0
  146. package/dist/tools/search-tools.d.ts +29 -0
  147. package/dist/tools/search-tools.d.ts.map +1 -0
  148. package/dist/tools/search-tools.js +309 -0
  149. package/dist/tools/search-tools.js.map +1 -0
  150. package/dist/tools/symbol-tools.d.ts +24 -0
  151. package/dist/tools/symbol-tools.d.ts.map +1 -0
  152. package/dist/tools/symbol-tools.js +172 -0
  153. package/dist/tools/symbol-tools.js.map +1 -0
  154. package/dist/types.d.ts +91 -0
  155. package/dist/types.d.ts.map +1 -0
  156. package/dist/types.js +3 -0
  157. package/dist/types.js.map +1 -0
  158. package/dist/utils/git-validation.d.ts +11 -0
  159. package/dist/utils/git-validation.d.ts.map +1 -0
  160. package/dist/utils/git-validation.js +19 -0
  161. package/dist/utils/git-validation.js.map +1 -0
  162. package/dist/utils/test-file.d.ts +11 -0
  163. package/dist/utils/test-file.d.ts.map +1 -0
  164. package/dist/utils/test-file.js +27 -0
  165. package/dist/utils/test-file.js.map +1 -0
  166. package/package.json +62 -0
  167. package/src/parser/languages/tree-sitter-css.wasm +0 -0
  168. package/src/parser/languages/tree-sitter-go.wasm +0 -0
  169. package/src/parser/languages/tree-sitter-java.wasm +0 -0
  170. package/src/parser/languages/tree-sitter-javascript.wasm +0 -0
  171. package/src/parser/languages/tree-sitter-json.wasm +0 -0
  172. package/src/parser/languages/tree-sitter-php.wasm +0 -0
  173. package/src/parser/languages/tree-sitter-python.wasm +0 -0
  174. package/src/parser/languages/tree-sitter-ruby.wasm +0 -0
  175. package/src/parser/languages/tree-sitter-rust.wasm +0 -0
  176. package/src/parser/languages/tree-sitter-tsx.wasm +0 -0
  177. package/src/parser/languages/tree-sitter-typescript.wasm +0 -0
@@ -0,0 +1,472 @@
1
+ import { loadConfig } from "../config.js";
2
+ import { isTestFile } from "../utils/test-file.js";
3
+ /**
4
+ * Estimate token count from a string. ~4 chars per token.
5
+ */
6
+ function estimateTokens(text) {
7
+ return Math.ceil(text.length / 4);
8
+ }
9
+ /**
10
+ * Execute a single sub-query and return the result with token estimate.
11
+ */
12
+ async function executeSubQuery(repo, query) {
13
+ const qType = query.type;
14
+ switch (qType) {
15
+ case "symbols": {
16
+ const { searchSymbols } = await import("../tools/search-tools.js");
17
+ const results = await searchSymbols(repo, query["query"], {
18
+ kind: query["kind"],
19
+ file_pattern: query["file_pattern"],
20
+ include_source: true,
21
+ top_k: query["top_k"] ?? 5,
22
+ });
23
+ const sourceLimit = query["source_chars"] ?? 200;
24
+ const data = results.map((r) => {
25
+ const sym = r.symbol;
26
+ return sourceLimit > 0 && sym.source && sym.source.length > sourceLimit
27
+ ? { ...sym, source: sym.source.slice(0, sourceLimit) }
28
+ : sym;
29
+ });
30
+ const text = JSON.stringify(data);
31
+ return { type: qType, data, tokens: estimateTokens(text) };
32
+ }
33
+ case "text": {
34
+ const { searchText } = await import("../tools/search-tools.js");
35
+ const results = await searchText(repo, query["query"], {
36
+ regex: query["regex"],
37
+ context_lines: query["context_lines"],
38
+ file_pattern: query["file_pattern"],
39
+ });
40
+ const text = JSON.stringify(results);
41
+ return { type: qType, data: results, tokens: estimateTokens(text) };
42
+ }
43
+ case "file_tree": {
44
+ const { getFileTree } = await import("../tools/outline-tools.js");
45
+ const result = await getFileTree(repo, {
46
+ path_prefix: (query["path"] ?? query["path_prefix"]),
47
+ name_pattern: query["name_pattern"],
48
+ depth: query["depth"],
49
+ compact: query["compact"],
50
+ min_symbols: query["min_symbols"],
51
+ });
52
+ const text = JSON.stringify(result);
53
+ return { type: qType, data: result, tokens: estimateTokens(text) };
54
+ }
55
+ case "outline": {
56
+ const { getFileOutline } = await import("../tools/outline-tools.js");
57
+ const result = await getFileOutline(repo, query["file_path"]);
58
+ const text = JSON.stringify(result);
59
+ return { type: qType, data: result, tokens: estimateTokens(text) };
60
+ }
61
+ case "references": {
62
+ const { findReferences } = await import("../tools/symbol-tools.js");
63
+ const results = await findReferences(repo, query["symbol_name"]);
64
+ const text = JSON.stringify(results);
65
+ return { type: qType, data: results, tokens: estimateTokens(text) };
66
+ }
67
+ case "call_chain": {
68
+ const { traceCallChain } = await import("../tools/graph-tools.js");
69
+ const result = await traceCallChain(repo, query["symbol_name"], query["direction"] ?? "callers", {
70
+ depth: query["depth"],
71
+ include_source: query["include_source"] ?? false,
72
+ });
73
+ const text = JSON.stringify(result);
74
+ return { type: qType, data: result, tokens: estimateTokens(text) };
75
+ }
76
+ case "impact": {
77
+ const { impactAnalysis } = await import("../tools/graph-tools.js");
78
+ const result = await impactAnalysis(repo, query["since"], {
79
+ depth: query["depth"],
80
+ until: query["until"],
81
+ include_source: query["include_source"] ?? false,
82
+ });
83
+ const text = JSON.stringify(result);
84
+ return { type: qType, data: result, tokens: estimateTokens(text) };
85
+ }
86
+ case "context": {
87
+ const { assembleContext } = await import("../tools/context-tools.js");
88
+ const result = await assembleContext(repo, query["query"], query["max_tokens"]);
89
+ const text = JSON.stringify(result);
90
+ return { type: qType, data: result, tokens: estimateTokens(text) };
91
+ }
92
+ case "knowledge_map": {
93
+ const { getKnowledgeMap } = await import("../tools/context-tools.js");
94
+ const result = await getKnowledgeMap(repo, query["focus"], query["depth"]);
95
+ const text = JSON.stringify(result);
96
+ return { type: qType, data: result, tokens: estimateTokens(text) };
97
+ }
98
+ case "semantic": {
99
+ const { getCodeIndex, getEmbeddingCache } = await import("../tools/index-tools.js");
100
+ const { createEmbeddingProvider, searchSemantic, cosineSimilarity } = await import("../search/semantic.js");
101
+ const { loadConfig: getConfig } = await import("../config.js");
102
+ const { getRepo } = await import("../storage/registry.js");
103
+ const { loadChunks, loadChunkEmbeddings, getChunkPath, getChunkEmbeddingPath } = await import("../storage/chunk-store.js");
104
+ const semanticConfig = getConfig();
105
+ if (!semanticConfig.embeddingProvider) {
106
+ throw new Error("No embedding provider configured. Set CODESIFT_VOYAGE_API_KEY, CODESIFT_OPENAI_API_KEY, or CODESIFT_OLLAMA_URL.");
107
+ }
108
+ const topK = query["top_k"] ?? 10;
109
+ const fileFilter = query["file_filter"];
110
+ const excludeTests = query["exclude_tests"] ?? true;
111
+ // Auto-decompose long queries for RRF merging (shared by both paths)
112
+ const provider = createEmbeddingProvider(semanticConfig.embeddingProvider, semanticConfig);
113
+ const subQueryTexts = decomposeQuery(query["query"]);
114
+ const vecs = await provider.embed(subQueryTexts);
115
+ // Try chunk-level semantic search first
116
+ const repoMeta = await getRepo(semanticConfig.registryPath, repo);
117
+ if (repoMeta) {
118
+ const chunkPath = getChunkPath(repoMeta.index_path);
119
+ const chunkEmbeddingPath = getChunkEmbeddingPath(repoMeta.index_path);
120
+ const [chunks, chunkEmbeddings] = await Promise.all([
121
+ loadChunks(chunkPath),
122
+ loadChunkEmbeddings(chunkEmbeddingPath),
123
+ ]);
124
+ if (chunks && chunkEmbeddings) {
125
+ // Filter embeddings by file path substring and/or test file exclusion
126
+ let filteredEmbeddings = chunkEmbeddings;
127
+ if (fileFilter || excludeTests) {
128
+ filteredEmbeddings = new Map([...chunkEmbeddings.entries()].filter(([id]) => {
129
+ const chunkFile = chunks.get(id)?.file;
130
+ if (!chunkFile)
131
+ return false;
132
+ if (fileFilter && !chunkFile.includes(fileFilter))
133
+ return false;
134
+ if (excludeTests && isTestFile(chunkFile))
135
+ return false;
136
+ return true;
137
+ }));
138
+ }
139
+ // RRF over sub-query rankings (k=60 per standard RRF)
140
+ const rrfScores = new Map();
141
+ const rrfK = 60;
142
+ for (const vec of vecs) {
143
+ if (!vec)
144
+ continue;
145
+ const qEmbed = new Float32Array(vec);
146
+ const subScores = [];
147
+ for (const [id, chunkVec] of filteredEmbeddings) {
148
+ if (chunkVec.length === qEmbed.length) {
149
+ subScores.push({ id, score: cosineSimilarity(qEmbed, chunkVec) });
150
+ }
151
+ }
152
+ subScores.sort((a, b) => b.score - a.score);
153
+ subScores.forEach((s, rank) => {
154
+ rrfScores.set(s.id, (rrfScores.get(s.id) ?? 0) + 1 / (rrfK + rank + 1));
155
+ });
156
+ }
157
+ const topIds = [...rrfScores.entries()]
158
+ .sort((a, b) => b[1] - a[1])
159
+ .slice(0, topK)
160
+ .map(([id]) => id);
161
+ // Group chunks by file and sort by line number within each file
162
+ const byFile = new Map();
163
+ for (const id of topIds) {
164
+ const chunk = chunks.get(id);
165
+ if (!chunk)
166
+ continue;
167
+ const existing = byFile.get(chunk.file) ?? [];
168
+ existing.push({ startLine: chunk.startLine, endLine: chunk.endLine, text: chunk.text });
169
+ byFile.set(chunk.file, existing);
170
+ }
171
+ // Format as plain text — same style as Augment's context engine
172
+ const sections = ["The following code sections were retrieved:"];
173
+ for (const [file, fileChunks] of byFile) {
174
+ fileChunks.sort((a, b) => a.startLine - b.startLine);
175
+ // Merge overlapping/adjacent chunks to avoid duplicate lines
176
+ const merged = [];
177
+ for (const chunk of fileChunks) {
178
+ const last = merged[merged.length - 1];
179
+ if (last && chunk.startLine <= last.endLine + 5) {
180
+ if (chunk.endLine > last.endLine) {
181
+ const overlapLines = last.endLine - chunk.startLine + 1;
182
+ const newLines = chunk.text.split("\n").slice(overlapLines);
183
+ last.text = last.text + "\n" + newLines.join("\n");
184
+ last.endLine = chunk.endLine;
185
+ }
186
+ }
187
+ else {
188
+ merged.push({ startLine: chunk.startLine, endLine: chunk.endLine, text: chunk.text });
189
+ }
190
+ }
191
+ sections.push(`Path: ${file}`);
192
+ for (const chunk of merged) {
193
+ // Add line numbers to each line (matching Auggie's format)
194
+ const lines = chunk.text.split("\n");
195
+ const numbered = lines.map((line, i) => {
196
+ const lineNo = String(chunk.startLine + i).padStart(6, " ");
197
+ return `${lineNo}\t${line}`;
198
+ }).join("\n");
199
+ sections.push(numbered);
200
+ }
201
+ sections.push("...");
202
+ }
203
+ const text = sections.join("\n");
204
+ return { type: qType, data: text, tokens: estimateTokens(text) };
205
+ }
206
+ }
207
+ // Fall back to symbol-level semantic search when no chunks are indexed
208
+ const index = await getCodeIndex(repo);
209
+ if (!index)
210
+ throw new Error(`Repository "${repo}" not found`);
211
+ const embeddings = await getEmbeddingCache(repo);
212
+ if (!embeddings)
213
+ throw new Error(`No embeddings for "${repo}". Run index_folder with an embedding provider configured.`);
214
+ const sourceLimit = query["source_chars"] ?? 200;
215
+ const symbolMap = new Map(index.symbols.map((s) => [s.id, s]));
216
+ // Filter embeddings by file path substring and/or test file exclusion
217
+ let filteredEmbeddings = embeddings;
218
+ if (fileFilter || excludeTests) {
219
+ filteredEmbeddings = new Map([...embeddings.entries()].filter(([id]) => {
220
+ const symFile = symbolMap.get(id)?.file;
221
+ if (!symFile)
222
+ return false;
223
+ if (fileFilter && !symFile.includes(fileFilter))
224
+ return false;
225
+ if (excludeTests && isTestFile(symFile))
226
+ return false;
227
+ return true;
228
+ }));
229
+ }
230
+ const primaryVec = vecs[0];
231
+ if (!primaryVec)
232
+ throw new Error("Embedding provider returned no vector");
233
+ const results = searchSemantic(new Float32Array(primaryVec), filteredEmbeddings, symbolMap, topK);
234
+ const data = results.map((r) => {
235
+ const sym = r.symbol;
236
+ return sourceLimit > 0 && sym.source && sym.source.length > sourceLimit
237
+ ? { ...sym, source: sym.source.slice(0, sourceLimit) }
238
+ : sym;
239
+ });
240
+ const text = JSON.stringify(data);
241
+ return { type: qType, data, tokens: estimateTokens(text) };
242
+ }
243
+ case "hybrid": {
244
+ // Hybrid: semantic embedding search + text/BM25 search, RRF-merged.
245
+ // Benefits: no need to choose semantic vs text — gets best of both.
246
+ const { getRepo: getRepoH } = await import("../storage/registry.js");
247
+ const { loadChunks: loadChunksH, loadChunkEmbeddings: loadChunkEmbeddingsH, getChunkPath: getChunkPathH, getChunkEmbeddingPath: getChunkEmbeddingPathH } = await import("../storage/chunk-store.js");
248
+ const { createEmbeddingProvider: createProviderH, cosineSimilarity: cosSimH } = await import("../search/semantic.js");
249
+ const { loadConfig: getConfigH } = await import("../config.js");
250
+ const { searchText: searchTextH } = await import("../tools/search-tools.js");
251
+ const hybridConfig = getConfigH();
252
+ if (!hybridConfig.embeddingProvider) {
253
+ throw new Error("No embedding provider configured.");
254
+ }
255
+ const topK = query["top_k"] ?? 10;
256
+ const fileFilter = query["file_filter"];
257
+ const excludeTests = query["exclude_tests"] ?? true;
258
+ const queryText = query["query"];
259
+ const repoMeta = await getRepoH(hybridConfig.registryPath, repo);
260
+ if (!repoMeta)
261
+ throw new Error(`Repository "${repo}" not found`);
262
+ const chunkPath = getChunkPathH(repoMeta.index_path);
263
+ const chunkEmbeddingPath = getChunkEmbeddingPathH(repoMeta.index_path);
264
+ // Run semantic embedding + text search in parallel
265
+ const provider = createProviderH(hybridConfig.embeddingProvider, hybridConfig);
266
+ const subQueryTexts = decomposeQuery(queryText);
267
+ const [chunks, chunkEmbeddings, textMatches, embVecs] = await Promise.all([
268
+ loadChunksH(chunkPath),
269
+ loadChunkEmbeddingsH(chunkEmbeddingPath),
270
+ searchTextH(repo, queryText, { file_pattern: fileFilter }).catch(() => []),
271
+ provider.embed(subQueryTexts),
272
+ ]);
273
+ if (!chunks || !chunkEmbeddings)
274
+ throw new Error(`No chunk index for "${repo}"`);
275
+ let filteredEmbeddings = chunkEmbeddings;
276
+ if (fileFilter || excludeTests) {
277
+ filteredEmbeddings = new Map([...chunkEmbeddings.entries()].filter(([id]) => {
278
+ const chunkFile = chunks.get(id)?.file;
279
+ if (!chunkFile)
280
+ return false;
281
+ if (fileFilter && !chunkFile.includes(fileFilter))
282
+ return false;
283
+ if (excludeTests && isTestFile(chunkFile))
284
+ return false;
285
+ return true;
286
+ }));
287
+ }
288
+ const rrfK = 60;
289
+ const rrfScores = new Map();
290
+ // 1. Semantic RRF contributions (one pass per decomposed sub-query)
291
+ for (const vec of embVecs) {
292
+ if (!vec)
293
+ continue;
294
+ const qEmbed = new Float32Array(vec);
295
+ const subScores = [];
296
+ for (const [id, chunkVec] of filteredEmbeddings) {
297
+ if (chunkVec.length === qEmbed.length) {
298
+ subScores.push({ id, score: cosSimH(qEmbed, chunkVec) });
299
+ }
300
+ }
301
+ subScores.sort((a, b) => b.score - a.score);
302
+ subScores.forEach((s, rank) => {
303
+ rrfScores.set(s.id, (rrfScores.get(s.id) ?? 0) + 1 / (rrfK + rank + 1));
304
+ });
305
+ }
306
+ // 2. Text match RRF contributions — map match line → covering chunk
307
+ // Build file → sorted-chunks index for efficient line lookup
308
+ const fileToChunks = new Map();
309
+ for (const [id, chunk] of chunks) {
310
+ const list = fileToChunks.get(chunk.file) ?? [];
311
+ list.push({ id, startLine: chunk.startLine, endLine: chunk.endLine });
312
+ fileToChunks.set(chunk.file, list);
313
+ }
314
+ for (const list of fileToChunks.values()) {
315
+ list.sort((a, b) => a.startLine - b.startLine);
316
+ }
317
+ for (let rank = 0; rank < textMatches.length; rank++) {
318
+ const match = textMatches[rank];
319
+ if (!match)
320
+ continue;
321
+ // Skip text matches from test files when excluding tests
322
+ if (excludeTests && isTestFile(match.file))
323
+ continue;
324
+ const list = fileToChunks.get(match.file) ?? [];
325
+ for (const chunk of list) {
326
+ if (chunk.startLine <= match.line && match.line <= chunk.endLine) {
327
+ rrfScores.set(chunk.id, (rrfScores.get(chunk.id) ?? 0) + 1 / (rrfK + rank + 1));
328
+ break;
329
+ }
330
+ }
331
+ }
332
+ // Top_k by combined RRF score
333
+ const topIds = [...rrfScores.entries()]
334
+ .sort((a, b) => b[1] - a[1])
335
+ .slice(0, topK)
336
+ .map(([id]) => id);
337
+ // Format as plain text (same as semantic case)
338
+ const byFile = new Map();
339
+ for (const id of topIds) {
340
+ const chunk = chunks.get(id);
341
+ if (!chunk)
342
+ continue;
343
+ // Double-check test file exclusion (text matches could contribute chunk IDs)
344
+ if (excludeTests && isTestFile(chunk.file))
345
+ continue;
346
+ const existing = byFile.get(chunk.file) ?? [];
347
+ existing.push({ startLine: chunk.startLine, endLine: chunk.endLine, text: chunk.text });
348
+ byFile.set(chunk.file, existing);
349
+ }
350
+ const sections = ["The following code sections were retrieved:"];
351
+ for (const [file, fileChunks] of byFile) {
352
+ fileChunks.sort((a, b) => a.startLine - b.startLine);
353
+ const merged = [];
354
+ for (const chunk of fileChunks) {
355
+ const last = merged[merged.length - 1];
356
+ if (last && chunk.startLine <= last.endLine + 5) {
357
+ if (chunk.endLine > last.endLine) {
358
+ const overlapLines = last.endLine - chunk.startLine + 1;
359
+ const newLines = chunk.text.split("\n").slice(overlapLines);
360
+ last.text = last.text + "\n" + newLines.join("\n");
361
+ last.endLine = chunk.endLine;
362
+ }
363
+ }
364
+ else {
365
+ merged.push({ startLine: chunk.startLine, endLine: chunk.endLine, text: chunk.text });
366
+ }
367
+ }
368
+ sections.push(`Path: ${file}`);
369
+ for (const chunk of merged) {
370
+ const lines = chunk.text.split("\n");
371
+ const numbered = lines.map((line, i) => {
372
+ const lineNo = String(chunk.startLine + i).padStart(6, " ");
373
+ return `${lineNo}\t${line}`;
374
+ }).join("\n");
375
+ sections.push(numbered);
376
+ }
377
+ sections.push("...");
378
+ }
379
+ const hybridText = sections.join("\n");
380
+ return { type: qType, data: hybridText, tokens: estimateTokens(hybridText) };
381
+ }
382
+ default:
383
+ return {
384
+ type: qType,
385
+ data: { error: `Unknown sub-query type: ${qType}` },
386
+ tokens: 50,
387
+ };
388
+ }
389
+ }
390
+ /**
391
+ * Split a long query into sub-queries at natural connectors for RRF merging.
392
+ * Queries ≤ 8 words are returned as-is.
393
+ */
394
+ function decomposeQuery(query) {
395
+ const words = query.split(/\s+/).filter(Boolean);
396
+ if (words.length <= 8)
397
+ return [query];
398
+ const splitWords = new Set(["and", "or", "from", "to", "with", "using", "for", "via", "then"]);
399
+ const lo = Math.floor(words.length * 0.35);
400
+ const hi = Math.floor(words.length * 0.65);
401
+ for (let i = lo; i <= hi; i++) {
402
+ if (splitWords.has((words[i] ?? "").toLowerCase())) {
403
+ const a = words.slice(0, i).join(" ");
404
+ const b = words.slice(i + 1).join(" ");
405
+ if (a.trim() && b.trim())
406
+ return [a, b];
407
+ }
408
+ }
409
+ const mid = Math.floor(words.length / 2);
410
+ return [words.slice(0, mid).join(" "), words.slice(mid).join(" ")];
411
+ }
412
+ /**
413
+ * Execute multiple sub-queries in a single batched call with shared token budget.
414
+ *
415
+ * Features:
416
+ * - Cross-query deduplication (same symbol in multiple results → included once)
417
+ * - Token budget enforcement
418
+ * - Max 20 sub-queries per call
419
+ * - Parallel execution where queries are independent
420
+ */
421
+ export async function codebaseRetrieval(repo, queries, tokenBudget) {
422
+ const config = loadConfig();
423
+ const budget = tokenBudget ?? config.defaultTokenBudget;
424
+ const maxQueries = 20;
425
+ const limited = queries.slice(0, maxQueries);
426
+ // Execute all sub-queries in parallel
427
+ const subResults = await Promise.all(limited.map((q) => executeSubQuery(repo, q).catch((err) => {
428
+ const message = err instanceof Error ? err.message : String(err);
429
+ return {
430
+ type: q.type,
431
+ data: { error: message },
432
+ tokens: estimateTokens(message),
433
+ };
434
+ })));
435
+ // Enforce token budget — include results until budget is exceeded
436
+ const results = [];
437
+ let totalTokens = 0;
438
+ let truncated = false;
439
+ for (const result of subResults) {
440
+ if (totalTokens + result.tokens > budget) {
441
+ truncated = true;
442
+ // Try to include a truncated version
443
+ const remaining = budget - totalTokens;
444
+ if (remaining > 100) {
445
+ const truncatedText = JSON.stringify(result.data).slice(0, remaining * 4);
446
+ let truncatedData;
447
+ try {
448
+ truncatedData = JSON.parse(truncatedText);
449
+ }
450
+ catch {
451
+ truncatedData = { partial: true, note: "Result truncated to fit token budget" };
452
+ }
453
+ results.push({
454
+ type: result.type,
455
+ data: truncatedData,
456
+ tokens: remaining,
457
+ });
458
+ totalTokens += remaining;
459
+ }
460
+ break;
461
+ }
462
+ results.push(result);
463
+ totalTokens += result.tokens;
464
+ }
465
+ return {
466
+ results,
467
+ total_tokens: totalTokens,
468
+ truncated,
469
+ query_count: limited.length,
470
+ };
471
+ }
472
+ //# sourceMappingURL=codebase-retrieval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase-retrieval.js","sourceRoot":"","sources":["../../src/retrieval/codebase-retrieval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { CodeSymbol, SearchResult } from "../types.js";
2
+ type FieldName = "name" | "signature" | "docstring" | "body";
3
+ export interface BM25Index {
4
+ /** Per-field inverted index: token -> Map<symbolId, termFrequency> */
5
+ fields: Record<FieldName, Map<string, Map<string, number>>>;
6
+ /** Per-field average document length (in tokens) */
7
+ avgFieldLengths: Record<FieldName, number>;
8
+ /** Total number of indexed documents */
9
+ docCount: number;
10
+ /** Symbol lookup by ID */
11
+ symbols: Map<string, CodeSymbol>;
12
+ }
13
+ /**
14
+ * General-purpose tokenizer for signature, docstring, and body text.
15
+ * Splits on non-alphanumeric chars, applies camelCase/snake_case splitting,
16
+ * lowercases, and filters tokens shorter than 2 chars.
17
+ */
18
+ export declare function tokenizeText(text: string): string[];
19
+ export declare function buildBM25Index(symbols: CodeSymbol[]): BM25Index;
20
+ export declare function searchBM25(index: BM25Index, query: string, topK: number, fieldWeights: Record<FieldName, number>): SearchResult[];
21
+ export {};
22
+ //# sourceMappingURL=bm25.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bm25.d.ts","sourceRoot":"","sources":["../../src/search/bm25.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAe5D,KAAK,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5D,oDAAoD;IACpD,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC3C,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBnD;AAqBD,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,SAAS,CAgD/D;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,GACtC,YAAY,EAAE,CAiGhB"}