@zuvia-software-solutions/code-mapper 1.4.0 → 2.0.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 (137) hide show
  1. package/dist/cli/ai-context.js +1 -1
  2. package/dist/cli/analyze.d.ts +1 -0
  3. package/dist/cli/analyze.js +73 -82
  4. package/dist/cli/augment.js +0 -2
  5. package/dist/cli/eval-server.d.ts +2 -2
  6. package/dist/cli/eval-server.js +6 -6
  7. package/dist/cli/index.js +6 -10
  8. package/dist/cli/mcp.d.ts +1 -3
  9. package/dist/cli/mcp.js +3 -3
  10. package/dist/cli/refresh.d.ts +2 -2
  11. package/dist/cli/refresh.js +24 -29
  12. package/dist/cli/status.js +4 -13
  13. package/dist/cli/tool.d.ts +5 -4
  14. package/dist/cli/tool.js +8 -10
  15. package/dist/config/ignore-service.js +14 -34
  16. package/dist/core/augmentation/engine.js +53 -83
  17. package/dist/core/db/adapter.d.ts +99 -0
  18. package/dist/core/db/adapter.js +402 -0
  19. package/dist/core/db/graph-loader.d.ts +27 -0
  20. package/dist/core/db/graph-loader.js +148 -0
  21. package/dist/core/db/queries.d.ts +160 -0
  22. package/dist/core/db/queries.js +441 -0
  23. package/dist/core/db/schema.d.ts +108 -0
  24. package/dist/core/db/schema.js +136 -0
  25. package/dist/core/embeddings/embedder.d.ts +21 -12
  26. package/dist/core/embeddings/embedder.js +104 -50
  27. package/dist/core/embeddings/embedding-pipeline.d.ts +48 -22
  28. package/dist/core/embeddings/embedding-pipeline.js +220 -262
  29. package/dist/core/embeddings/text-generator.js +4 -19
  30. package/dist/core/embeddings/types.d.ts +1 -1
  31. package/dist/core/graph/graph.d.ts +1 -1
  32. package/dist/core/graph/graph.js +1 -0
  33. package/dist/core/graph/types.d.ts +11 -9
  34. package/dist/core/graph/types.js +4 -1
  35. package/dist/core/incremental/refresh.d.ts +46 -0
  36. package/dist/core/incremental/refresh.js +464 -0
  37. package/dist/core/incremental/types.d.ts +2 -1
  38. package/dist/core/incremental/types.js +42 -44
  39. package/dist/core/ingestion/ast-cache.js +1 -0
  40. package/dist/core/ingestion/call-processor.d.ts +15 -3
  41. package/dist/core/ingestion/call-processor.js +448 -60
  42. package/dist/core/ingestion/cluster-enricher.d.ts +1 -1
  43. package/dist/core/ingestion/cluster-enricher.js +2 -0
  44. package/dist/core/ingestion/community-processor.d.ts +1 -1
  45. package/dist/core/ingestion/community-processor.js +8 -3
  46. package/dist/core/ingestion/export-detection.d.ts +1 -1
  47. package/dist/core/ingestion/export-detection.js +1 -1
  48. package/dist/core/ingestion/filesystem-walker.js +1 -1
  49. package/dist/core/ingestion/heritage-processor.d.ts +2 -2
  50. package/dist/core/ingestion/heritage-processor.js +22 -11
  51. package/dist/core/ingestion/import-processor.d.ts +2 -2
  52. package/dist/core/ingestion/import-processor.js +24 -9
  53. package/dist/core/ingestion/language-config.js +7 -4
  54. package/dist/core/ingestion/mro-processor.d.ts +1 -1
  55. package/dist/core/ingestion/mro-processor.js +23 -11
  56. package/dist/core/ingestion/named-binding-extraction.js +5 -5
  57. package/dist/core/ingestion/parsing-processor.d.ts +4 -4
  58. package/dist/core/ingestion/parsing-processor.js +26 -18
  59. package/dist/core/ingestion/pipeline.d.ts +4 -2
  60. package/dist/core/ingestion/pipeline.js +50 -20
  61. package/dist/core/ingestion/process-processor.d.ts +2 -2
  62. package/dist/core/ingestion/process-processor.js +28 -14
  63. package/dist/core/ingestion/resolution-context.d.ts +1 -1
  64. package/dist/core/ingestion/resolution-context.js +14 -4
  65. package/dist/core/ingestion/resolvers/csharp.js +4 -3
  66. package/dist/core/ingestion/resolvers/go.js +3 -1
  67. package/dist/core/ingestion/resolvers/jvm.js +13 -4
  68. package/dist/core/ingestion/resolvers/standard.js +2 -2
  69. package/dist/core/ingestion/resolvers/utils.js +6 -2
  70. package/dist/core/ingestion/route-stitcher.d.ts +15 -0
  71. package/dist/core/ingestion/route-stitcher.js +92 -0
  72. package/dist/core/ingestion/structure-processor.d.ts +1 -1
  73. package/dist/core/ingestion/structure-processor.js +3 -2
  74. package/dist/core/ingestion/symbol-table.d.ts +2 -0
  75. package/dist/core/ingestion/symbol-table.js +5 -1
  76. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  77. package/dist/core/ingestion/tree-sitter-queries.js +177 -0
  78. package/dist/core/ingestion/type-env.js +20 -0
  79. package/dist/core/ingestion/type-extractors/csharp.js +4 -3
  80. package/dist/core/ingestion/type-extractors/go.js +23 -12
  81. package/dist/core/ingestion/type-extractors/php.js +18 -10
  82. package/dist/core/ingestion/type-extractors/ruby.js +15 -3
  83. package/dist/core/ingestion/type-extractors/rust.js +3 -2
  84. package/dist/core/ingestion/type-extractors/shared.js +3 -2
  85. package/dist/core/ingestion/type-extractors/typescript.js +11 -5
  86. package/dist/core/ingestion/utils.d.ts +27 -4
  87. package/dist/core/ingestion/utils.js +145 -100
  88. package/dist/core/ingestion/workers/parse-worker.d.ts +1 -0
  89. package/dist/core/ingestion/workers/parse-worker.js +97 -29
  90. package/dist/core/ingestion/workers/worker-pool.js +3 -0
  91. package/dist/core/search/bm25-index.d.ts +15 -8
  92. package/dist/core/search/bm25-index.js +48 -98
  93. package/dist/core/search/hybrid-search.d.ts +9 -3
  94. package/dist/core/search/hybrid-search.js +30 -25
  95. package/dist/core/search/reranker.js +9 -7
  96. package/dist/core/search/types.d.ts +0 -4
  97. package/dist/core/semantic/tsgo-service.d.ts +5 -1
  98. package/dist/core/semantic/tsgo-service.js +161 -66
  99. package/dist/lib/tsgo-test.d.ts +2 -0
  100. package/dist/lib/tsgo-test.js +6 -0
  101. package/dist/lib/type-utils.d.ts +25 -0
  102. package/dist/lib/type-utils.js +22 -0
  103. package/dist/lib/utils.d.ts +3 -2
  104. package/dist/lib/utils.js +3 -2
  105. package/dist/mcp/compatible-stdio-transport.js +1 -1
  106. package/dist/mcp/local/local-backend.d.ts +29 -56
  107. package/dist/mcp/local/local-backend.js +808 -1118
  108. package/dist/mcp/resources.js +35 -25
  109. package/dist/mcp/server.d.ts +1 -1
  110. package/dist/mcp/server.js +5 -5
  111. package/dist/mcp/tools.js +24 -25
  112. package/dist/storage/repo-manager.d.ts +2 -12
  113. package/dist/storage/repo-manager.js +1 -47
  114. package/dist/types/pipeline.d.ts +8 -5
  115. package/dist/types/pipeline.js +5 -0
  116. package/package.json +18 -11
  117. package/dist/cli/serve.d.ts +0 -5
  118. package/dist/cli/serve.js +0 -8
  119. package/dist/core/incremental/child-process.d.ts +0 -8
  120. package/dist/core/incremental/child-process.js +0 -649
  121. package/dist/core/incremental/refresh-coordinator.d.ts +0 -32
  122. package/dist/core/incremental/refresh-coordinator.js +0 -147
  123. package/dist/core/lbug/csv-generator.d.ts +0 -28
  124. package/dist/core/lbug/csv-generator.js +0 -355
  125. package/dist/core/lbug/lbug-adapter.d.ts +0 -96
  126. package/dist/core/lbug/lbug-adapter.js +0 -753
  127. package/dist/core/lbug/schema.d.ts +0 -46
  128. package/dist/core/lbug/schema.js +0 -402
  129. package/dist/mcp/core/embedder.d.ts +0 -24
  130. package/dist/mcp/core/embedder.js +0 -168
  131. package/dist/mcp/core/lbug-adapter.d.ts +0 -29
  132. package/dist/mcp/core/lbug-adapter.js +0 -330
  133. package/dist/server/api.d.ts +0 -5
  134. package/dist/server/api.js +0 -340
  135. package/dist/server/mcp-http.d.ts +0 -7
  136. package/dist/server/mcp-http.js +0 -95
  137. package/models/mlx-embedder.py +0 -185
@@ -1,109 +1,65 @@
1
1
  // code-mapper/src/core/search/bm25-index.ts
2
2
  /**
3
3
  * @file bm25-index.ts
4
- * @description Symbol-level full-text search via LadybugDB FTS indexes.
4
+ * @description Symbol-level full-text search via SQLite FTS5 index.
5
5
  *
6
6
  * Returns individual symbols (functions, classes, methods, interfaces, files)
7
- * with their nodeId, name, type NOT just filePaths.
7
+ * with their nodeId, name, type -- NOT just filePaths.
8
8
  * This gives the RRF merge symbol-level granularity for accurate ranking.
9
9
  *
10
- * All FTS tables are driven from FTS_TABLES in types.ts single source of truth.
10
+ * Backed by the unified FTS5 index on the `nodes` table (see adapter.searchFTS).
11
11
  */
12
- import { queryFTS } from '../lbug/lbug-adapter.js';
13
- import { FTS_TABLES } from './types.js';
14
- /**
15
- * Execute a single FTS query returning symbol-level results.
16
- * Each result has nodeId + name + type, not just filePath.
17
- */
18
- async function queryFTSSymbols(executor, tableName, indexName, query, limit) {
19
- const escapedQuery = query.replace(/\\/g, '\\\\').replace(/'/g, "''");
20
- // Return node.id and node.name alongside filePath so we get symbol-level results
21
- const isFile = tableName === 'File';
22
- const returnFields = isFile
23
- ? `node.id AS nodeId, node.name AS name, '${tableName}' AS type, node.filePath AS filePath, score`
24
- : `node.id AS nodeId, node.name AS name, '${tableName}' AS type, node.filePath AS filePath, node.startLine AS startLine, node.endLine AS endLine, score`;
25
- const cypher = `
26
- CALL QUERY_FTS_INDEX('${tableName}', '${indexName}', '${escapedQuery}', conjunctive := false)
27
- RETURN ${returnFields}
28
- ORDER BY score DESC
29
- LIMIT ${limit}
30
- `;
31
- try {
32
- const rows = await executor(cypher);
33
- return rows.map((row) => {
34
- const r = row;
35
- const rawScore = r.score ?? 0;
36
- const score = typeof rawScore === 'number' ? rawScore : parseFloat(String(rawScore)) || 0;
37
- return {
38
- nodeId: String(r.nodeId ?? ''),
39
- name: String(r.name ?? ''),
40
- type: String(r.type ?? tableName),
41
- filePath: String(r.filePath ?? ''),
42
- score,
43
- ...(!isFile && r.startLine != null ? { startLine: Number(r.startLine) } : {}),
44
- ...(!isFile && r.endLine != null ? { endLine: Number(r.endLine) } : {}),
45
- };
46
- });
47
- }
48
- catch {
49
- return [];
50
- }
51
- }
12
+ import { searchFTS } from '../db/adapter.js';
13
+ import {} from './types.js';
14
+ // ============================================================================
15
+ // SYMBOL-TYPE WEIGHT MULTIPLIERS
16
+ // ============================================================================
17
+ /** Functions/methods are more actionable than files in search results */
18
+ const TYPE_WEIGHTS = {
19
+ Function: 1.5,
20
+ Method: 1.5,
21
+ Class: 1.3,
22
+ Interface: 1.3,
23
+ File: 1.0,
24
+ };
52
25
  // ============================================================================
53
26
  // MAIN SEARCH FUNCTION
54
27
  // ============================================================================
55
28
  /**
56
- * Symbol-level BM25 search via LadybugDB FTS.
29
+ * Symbol-level BM25 search via SQLite FTS5.
57
30
  *
58
- * Queries all FTS_TABLES in parallel. Returns individual symbols (not filePaths).
59
- * Deduplicates by nodeId if the same symbol matches in multiple indexes,
60
- * take the highest score.
31
+ * Queries the unified `nodes_fts` virtual table, deduplicates by nodeId,
32
+ * applies type-based weighting, and returns ranked results.
33
+ *
34
+ * Synchronous under the hood (better-sqlite3), but the function is sync --
35
+ * callers that `await` it still work (await on a non-Promise is a no-op).
36
+ *
37
+ * @param query - Search text
38
+ * @param limit - Max results to return (default 20)
39
+ * @param db - Open SQLite database instance (required; returns [] if undefined)
61
40
  */
62
- export async function searchFTSFromLbug(query, limit = 20, repoId) {
63
- const queryAll = [];
64
- if (repoId) {
65
- const { executeQuery } = await import('../../mcp/core/lbug-adapter.js');
66
- const executor = (cypher) => executeQuery(repoId, cypher);
67
- for (const { table, index } of FTS_TABLES) {
68
- queryAll.push(queryFTSSymbols(executor, table, index, query, limit));
69
- }
70
- }
71
- else {
72
- for (const { table, index } of FTS_TABLES) {
73
- queryAll.push(queryFTS(table, index, query, limit, false)
74
- .then((rows) => rows.map(r => ({
75
- nodeId: String(r.nodeId ?? r.id ?? ''),
76
- name: String(r.name ?? ''),
77
- type: table,
78
- filePath: String(r.filePath ?? ''),
79
- score: typeof r.score === 'number' ? r.score : 0,
80
- ...(r.startLine != null ? { startLine: Number(r.startLine) } : {}),
81
- ...(r.endLine != null ? { endLine: Number(r.endLine) } : {}),
82
- })))
83
- .catch(() => []));
84
- }
85
- }
86
- const allResults = await Promise.all(queryAll);
87
- // Symbol-type weight multipliers: functions/methods are more actionable than files
88
- const TYPE_WEIGHTS = {
89
- Function: 1.5,
90
- Method: 1.5,
91
- Class: 1.3,
92
- Interface: 1.3,
93
- File: 1.0,
94
- };
95
- // Deduplicate by nodeId — keep highest score per symbol, apply type weighting
41
+ export function searchFTSSymbols(query, limit = 20, db) {
42
+ if (!db)
43
+ return [];
44
+ const ftsResults = searchFTS(db, query, limit * 2); // over-fetch for dedup headroom
45
+ // Deduplicate by node ID, apply type weighting, keep highest score per symbol
96
46
  const byNodeId = new Map();
97
- for (const tableResults of allResults) {
98
- for (const r of tableResults) {
99
- if (!r.nodeId)
100
- continue;
101
- const weight = TYPE_WEIGHTS[r.type] ?? 1.0;
102
- const weighted = { ...r, score: r.score * weight };
103
- const existing = byNodeId.get(r.nodeId);
104
- if (!existing || weighted.score > existing.score) {
105
- byNodeId.set(r.nodeId, weighted);
106
- }
47
+ for (const r of ftsResults) {
48
+ const id = r.id;
49
+ if (!id)
50
+ continue;
51
+ const weight = TYPE_WEIGHTS[r.label] ?? 1.0;
52
+ const weightedScore = r.score * weight;
53
+ const existing = byNodeId.get(id);
54
+ if (!existing || weightedScore > existing.score) {
55
+ byNodeId.set(id, {
56
+ nodeId: id,
57
+ name: r.name,
58
+ type: r.label,
59
+ filePath: r.filePath,
60
+ score: weightedScore,
61
+ rank: 0, // assigned below after sorting
62
+ });
107
63
  }
108
64
  }
109
65
  // Sort by score descending, assign rank
@@ -111,13 +67,7 @@ export async function searchFTSFromLbug(query, limit = 20, repoId) {
111
67
  .sort((a, b) => b.score - a.score)
112
68
  .slice(0, limit);
113
69
  return sorted.map((r, index) => ({
114
- nodeId: r.nodeId,
115
- name: r.name,
116
- type: r.type,
117
- filePath: r.filePath,
118
- score: r.score,
70
+ ...r,
119
71
  rank: index + 1,
120
- ...(r.startLine != null ? { startLine: r.startLine } : {}),
121
- ...(r.endLine != null ? { endLine: r.endLine } : {}),
122
72
  }));
123
73
  }
@@ -6,6 +6,7 @@
6
6
  * All constants come from types.ts (single source of truth)
7
7
  * This is the ONLY RRF implementation — local-backend.ts must import this, never reimplement
8
8
  */
9
+ import type Database from 'better-sqlite3';
9
10
  import { type BM25SearchResult, type SemanticSearchResult, type HybridSearchResult, type RRFConfig } from './types.js';
10
11
  export type { HybridSearchResult, RRFConfig } from './types.js';
11
12
  /**
@@ -26,7 +27,12 @@ export declare function formatHybridResults(results: readonly HybridSearchResult
26
27
  /**
27
28
  * Execute BM25 + semantic search and merge with weighted RRF
28
29
  *
29
- * Uses LadybugDB FTS for always-fresh BM25 results
30
- * The semanticSearch function is injected to keep this module environment-agnostic
30
+ * Uses SQLite FTS5 for always-fresh BM25 results.
31
+ * The semanticSearch function is injected to keep this module environment-agnostic.
32
+ *
33
+ * @param db - Open SQLite database instance
34
+ * @param query - Search text
35
+ * @param limit - Max results to return
36
+ * @param semanticSearchFn - Async function that performs vector search given a db + query
31
37
  */
32
- export declare function hybridSearch(query: string, limit: number, executeQuery: (cypher: string) => Promise<unknown[]>, semanticSearchFn: (executeQuery: (cypher: string) => Promise<unknown[]>, query: string, k?: number) => Promise<SemanticSearchResult[]>): Promise<HybridSearchResult[]>;
38
+ export declare function hybridSearch(db: Database.Database, query: string, limit: number, semanticSearchFn: (db: Database.Database, query: string, k?: number) => Promise<SemanticSearchResult[]>): Promise<HybridSearchResult[]>;
@@ -7,7 +7,7 @@
7
7
  * All constants come from types.ts (single source of truth)
8
8
  * This is the ONLY RRF implementation — local-backend.ts must import this, never reimplement
9
9
  */
10
- import { searchFTSFromLbug } from './bm25-index.js';
10
+ import { searchFTSSymbols } from './bm25-index.js';
11
11
  import { DEFAULT_RRF_CONFIG, } from './types.js';
12
12
  /**
13
13
  * Merge BM25 and semantic results using weighted Reciprocal Rank Fusion
@@ -24,9 +24,10 @@ export function mergeWithRRF(bm25Results, semanticResults, config = {}) {
24
24
  // Mutable accumulator for building results
25
25
  const merged = new Map();
26
26
  // Score BM25 results — key by nodeId for symbol-level merging
27
- for (let i = 0; i < bm25Results.length; i++) {
28
- const r = bm25Results[i];
29
- const rrfScore = bm25Weight * (1 / (k + i + 1)); // rank is 1-indexed
27
+ let bm25Rank = 0;
28
+ for (const r of bm25Results) {
29
+ bm25Rank++;
30
+ const rrfScore = bm25Weight * (1 / (k + bm25Rank)); // rank is 1-indexed
30
31
  const key = r.nodeId || r.filePath; // symbol-level key when available
31
32
  merged.set(key, {
32
33
  filePath: r.filePath,
@@ -36,14 +37,15 @@ export function mergeWithRRF(bm25Results, semanticResults, config = {}) {
36
37
  nodeId: r.nodeId,
37
38
  name: r.name,
38
39
  label: r.type,
39
- startLine: r.startLine,
40
- endLine: r.endLine,
40
+ ...(r.startLine != null ? { startLine: r.startLine } : {}),
41
+ ...(r.endLine != null ? { endLine: r.endLine } : {}),
41
42
  });
42
43
  }
43
44
  // Score and merge semantic results — same symbol-level keying
44
- for (let i = 0; i < semanticResults.length; i++) {
45
- const r = semanticResults[i];
46
- const rrfScore = semanticWeight * (1 / (k + i + 1));
45
+ let semRank = 0;
46
+ for (const r of semanticResults) {
47
+ semRank++;
48
+ const rrfScore = semanticWeight * (1 / (k + semRank));
47
49
  const key = r.nodeId || r.filePath;
48
50
  const existing = merged.get(key);
49
51
  if (existing) {
@@ -72,8 +74,8 @@ export function mergeWithRRF(bm25Results, semanticResults, config = {}) {
72
74
  nodeId: r.nodeId,
73
75
  name: r.name,
74
76
  label: r.label,
75
- startLine: r.startLine,
76
- endLine: r.endLine,
77
+ ...(r.startLine != null ? { startLine: r.startLine } : {}),
78
+ ...(r.endLine != null ? { endLine: r.endLine } : {}),
77
79
  });
78
80
  }
79
81
  }
@@ -86,13 +88,13 @@ export function mergeWithRRF(bm25Results, semanticResults, config = {}) {
86
88
  score: r.score,
87
89
  rank: i + 1,
88
90
  sources: r.sources,
89
- bm25Score: r.bm25Score,
90
- semanticScore: r.semanticScore,
91
- nodeId: r.nodeId,
92
- name: r.name,
93
- label: r.label,
94
- startLine: r.startLine,
95
- endLine: r.endLine,
91
+ ...(r.bm25Score != null ? { bm25Score: r.bm25Score } : {}),
92
+ ...(r.semanticScore != null ? { semanticScore: r.semanticScore } : {}),
93
+ ...(r.nodeId != null ? { nodeId: r.nodeId } : {}),
94
+ ...(r.name != null ? { name: r.name } : {}),
95
+ ...(r.label != null ? { label: r.label } : {}),
96
+ ...(r.startLine != null ? { startLine: r.startLine } : {}),
97
+ ...(r.endLine != null ? { endLine: r.endLine } : {}),
96
98
  }));
97
99
  }
98
100
  // Hybrid search convenience functions
@@ -119,13 +121,16 @@ export function formatHybridResults(results) {
119
121
  /**
120
122
  * Execute BM25 + semantic search and merge with weighted RRF
121
123
  *
122
- * Uses LadybugDB FTS for always-fresh BM25 results
123
- * The semanticSearch function is injected to keep this module environment-agnostic
124
+ * Uses SQLite FTS5 for always-fresh BM25 results.
125
+ * The semanticSearch function is injected to keep this module environment-agnostic.
126
+ *
127
+ * @param db - Open SQLite database instance
128
+ * @param query - Search text
129
+ * @param limit - Max results to return
130
+ * @param semanticSearchFn - Async function that performs vector search given a db + query
124
131
  */
125
- export async function hybridSearch(query, limit, executeQuery, semanticSearchFn) {
126
- const [bm25Results, semanticResults] = await Promise.all([
127
- searchFTSFromLbug(query, limit),
128
- semanticSearchFn(executeQuery, query, limit),
129
- ]);
132
+ export async function hybridSearch(db, query, limit, semanticSearchFn) {
133
+ const bm25Results = searchFTSSymbols(query, limit, db);
134
+ const semanticResults = await semanticSearchFn(db, query, limit);
130
135
  return mergeWithRRF(bm25Results, semanticResults, { limit });
131
136
  }
@@ -15,7 +15,7 @@
15
15
  // ============================================================================
16
16
  // BGE reranker base — cross-encoder that understands code structure.
17
17
  // 278M params, ONNX, runs on CPU via transformers.js.
18
- // Tested: correctly ranks "initLbug" > "checkout" > "parseCode" > "README" for "database connection pool".
18
+ // Tested: correctly ranks "openDb" > "checkout" > "parseCode" > "README" for "database connection pool".
19
19
  const RERANKER_MODEL_ID = 'Xenova/bge-reranker-base';
20
20
  let rerankerState = null;
21
21
  let initPromise = null;
@@ -69,7 +69,10 @@ export async function rerank(query, passages) {
69
69
  if (passages.length === 0)
70
70
  return [];
71
71
  if (passages.length === 1) {
72
- return [{ id: passages[0].id, score: 1, originalRank: 1 }];
72
+ const first = passages[0];
73
+ if (first === undefined)
74
+ return [];
75
+ return [{ id: first.id, score: 1, originalRank: 1 }];
73
76
  }
74
77
  let state;
75
78
  try {
@@ -86,11 +89,10 @@ export async function rerank(query, passages) {
86
89
  }
87
90
  const { tokenizer, model } = state;
88
91
  const tok = tokenizer;
89
- const mod = model;
90
92
  // Tokenize all (query, passage) pairs
91
93
  const queries = passages.map(() => query);
92
94
  const texts = passages.map(p => p.text);
93
- const inputs = tok.call
95
+ const inputs = tok['call']
94
96
  ? await tokenizer(queries, { text_pair: texts, padding: true, truncation: true })
95
97
  : await tok.__call__(queries, { text_pair: texts, padding: true, truncation: true });
96
98
  const output = await model(inputs);
@@ -100,7 +102,7 @@ export async function rerank(query, passages) {
100
102
  return passages
101
103
  .map((p, i) => ({
102
104
  id: p.id,
103
- score: scores[i],
105
+ score: scores[i] ?? 0,
104
106
  originalRank: i + 1,
105
107
  }))
106
108
  .sort((a, b) => b.score - a.score);
@@ -113,8 +115,8 @@ export function isRerankerReady() {
113
115
  export async function disposeReranker() {
114
116
  if (rerankerState) {
115
117
  const model = rerankerState.model;
116
- if (typeof model.dispose === 'function') {
117
- await model.dispose();
118
+ if (typeof model['dispose'] === 'function') {
119
+ await model['dispose']();
118
120
  }
119
121
  rerankerState = null;
120
122
  initPromise = null;
@@ -139,10 +139,6 @@ export interface RerankResult {
139
139
  readonly score: number;
140
140
  readonly originalRank: number;
141
141
  }
142
- /** Execute a raw Cypher query and return rows */
143
- export type CypherExecutor = (cypher: string) => Promise<readonly Record<string, unknown>[]>;
144
- /** Execute a parameterized Cypher query */
145
- export type ParameterizedCypherExecutor = (repoId: string, cypher: string, params: Record<string, unknown>) => Promise<readonly Record<string, unknown>[]>;
146
142
  export interface SearchPipelineItem {
147
143
  readonly nodeId?: string;
148
144
  readonly name: string;
@@ -24,8 +24,9 @@ export interface TsgoReference {
24
24
  }
25
25
  export declare class TsgoService {
26
26
  private process;
27
- private buf;
28
27
  private responses;
28
+ /** Pending resolve callbacks keyed by request ID — event-driven, no polling */
29
+ private pending;
29
30
  private nextId;
30
31
  private projectRoot;
31
32
  private tsgoPath;
@@ -50,10 +51,13 @@ export declare class TsgoService {
50
51
  notifyFileChanged(absFilePath: string): Promise<void>;
51
52
  /** Notify tsgo that a file was deleted */
52
53
  notifyFileDeleted(absFilePath: string): Promise<void>;
54
+ /** Pre-open multiple files in one batch (fire-and-forget, no await per file) */
55
+ preOpenFiles(absFilePaths: readonly string[]): void;
53
56
  /** Stop the tsgo process */
54
57
  stop(): void;
55
58
  private doStart;
56
59
  private findTsgoBinary;
60
+ private rawBuf;
57
61
  private onData;
58
62
  private send;
59
63
  private request;