@zuvia-software-solutions/code-mapper 2.0.0 → 2.0.1

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.
@@ -259,52 +259,91 @@ export async function refreshFiles(db, repoPath, dirtyFiles) {
259
259
  catch (err) {
260
260
  console.error(`Code Mapper: refresh tsgo failed: ${err instanceof Error ? err.message : err}`);
261
261
  }
262
- if (tsgoReady) {
263
- // Build the set of dirty file relative paths for Phase 5 filtering
264
- const dirtyFilePaths = new Set(dirtyFiles.map(f => f.relativePath));
265
- // Wrap Phase 4 + 5 in a transaction for performance
262
+ // Phase 4: Resolve call edges from dirty files
263
+ // Always runs tsgo provides 0.99 confidence, heuristic fallback provides 0.5-0.95
264
+ if (callSites.length > 0) {
266
265
  db.exec('BEGIN');
267
266
  try {
268
- // Notify tsgo about changed files so it has fresh state
269
- for (const entry of filesToProcess) {
270
- const absPath = path.resolve(repoPath, entry.relativePath);
271
- if (isTypeScriptOrJavaScript(entry.relativePath)) {
272
- await tsgoService.notifyFileChanged(absPath);
267
+ const { findNodesByName } = await import('../db/adapter.js');
268
+ // Notify tsgo about changed files if available
269
+ if (tsgoReady) {
270
+ for (const entry of filesToProcess) {
271
+ const absPath = path.resolve(repoPath, entry.relativePath);
272
+ if (isTypeScriptOrJavaScript(entry.relativePath)) {
273
+ await tsgoService.notifyFileChanged(absPath);
274
+ }
273
275
  }
274
276
  }
275
- // Phase 4: Resolve call edges from dirty files
276
277
  console.error(`Code Mapper: refresh Phase 4 — ${callSites.length} call sites to resolve`);
277
- if (callSites.length > 0) {
278
- for (const callSite of callSites) {
279
- if (!isTypeScriptOrJavaScript(callSite.filePath))
280
- continue;
281
- const def = await tsgoService.resolveDefinition(callSite.absPath, callSite.line, callSite.character);
282
- if (!def)
283
- continue;
284
- // Find the source node (enclosing function of the call site)
285
- const sourceNode = findEnclosingNode(db, callSite.filePath, callSite.line);
286
- if (!sourceNode)
287
- continue;
288
- // Find the target node (the definition the call resolves to)
289
- const targetNode = findNodeByFileAndLine(db, def.filePath, def.line);
290
- if (!targetNode)
291
- continue;
292
- // Skip self-edges
293
- if (sourceNode.id === targetNode.id)
294
- continue;
295
- const edgeId = toEdgeId(`${sourceNode.id}_CALLS_${targetNode.id}`);
296
- insertEdge(db, {
297
- id: edgeId,
298
- sourceId: sourceNode.id,
299
- targetId: targetNode.id,
300
- type: 'CALLS',
301
- confidence: 0.99,
302
- reason: 'tsgo-lsp',
303
- callLine: callSite.line,
304
- });
305
- edgesInserted++;
278
+ for (const callSite of callSites) {
279
+ const sourceNode = findEnclosingNode(db, callSite.filePath, callSite.line);
280
+ if (!sourceNode)
281
+ continue;
282
+ let targetNode;
283
+ let confidence = 0.5;
284
+ let reason = 'global';
285
+ // Try tsgo first for TS/JS files
286
+ if (tsgoReady && isTypeScriptOrJavaScript(callSite.filePath)) {
287
+ try {
288
+ const def = await tsgoService.resolveDefinition(callSite.absPath, callSite.line, callSite.character);
289
+ if (def) {
290
+ targetNode = findNodeByFileAndLine(db, def.filePath, def.line);
291
+ if (targetNode) {
292
+ confidence = 0.99;
293
+ reason = 'tsgo-lsp';
294
+ }
295
+ }
296
+ }
297
+ catch { }
306
298
  }
299
+ // Heuristic fallback: name-based lookup in DB
300
+ if (!targetNode) {
301
+ const candidates = findNodesByName(db, callSite.name, undefined, 5);
302
+ const sameFile = candidates.find(c => c.filePath === callSite.filePath);
303
+ if (sameFile) {
304
+ targetNode = sameFile;
305
+ confidence = 0.95;
306
+ reason = 'same-file';
307
+ }
308
+ else if (candidates.length === 1) {
309
+ targetNode = candidates[0];
310
+ confidence = 0.9;
311
+ reason = 'import-resolved';
312
+ }
313
+ else if (candidates.length > 0) {
314
+ targetNode = candidates[0];
315
+ confidence = 0.5;
316
+ reason = 'global';
317
+ }
318
+ }
319
+ if (!targetNode)
320
+ continue;
321
+ if (sourceNode.id === targetNode.id)
322
+ continue;
323
+ const edgeId = toEdgeId(`${sourceNode.id}_CALLS_${targetNode.id}`);
324
+ insertEdge(db, {
325
+ id: edgeId,
326
+ sourceId: sourceNode.id,
327
+ targetId: targetNode.id,
328
+ type: 'CALLS',
329
+ confidence,
330
+ reason,
331
+ callLine: callSite.line,
332
+ });
333
+ edgesInserted++;
307
334
  }
335
+ db.exec('COMMIT');
336
+ }
337
+ catch (err) {
338
+ db.exec('ROLLBACK');
339
+ console.error(`Code Mapper: Phase 4 call resolution failed: ${err instanceof Error ? err.message : err}`);
340
+ }
341
+ }
342
+ // Phase 5: Repair cross-file edges (tsgo only — needs findReferences)
343
+ if (tsgoReady) {
344
+ const dirtyFilePaths = new Set(dirtyFiles.map(f => f.relativePath));
345
+ db.exec('BEGIN');
346
+ try {
308
347
  // Phase 5: Repair cross-file edges
309
348
  // For each newly inserted definition, find references from UNCHANGED files
310
349
  // and create CALLS edges so the graph stays consistent.
@@ -39,6 +39,8 @@ export declare class TsgoService {
39
39
  * @typescript/native-preview is not installed or tsgo fails to start.
40
40
  */
41
41
  start(): Promise<boolean>;
42
+ /** Get the resolved project root (where tsconfig.json was found) */
43
+ getProjectRoot(): string;
42
44
  /** Whether the server is running and ready for queries */
43
45
  isReady(): boolean;
44
46
  /** Resolve what a symbol at a given position points to (go-to-definition) */
@@ -59,6 +59,10 @@ export class TsgoService {
59
59
  this.initPromise = this.doStart();
60
60
  return this.initPromise;
61
61
  }
62
+ /** Get the resolved project root (where tsconfig.json was found) */
63
+ getProjectRoot() {
64
+ return this.projectRoot;
65
+ }
62
66
  /** Whether the server is running and ready for queries */
63
67
  isReady() {
64
68
  return this.ready;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuvia-software-solutions/code-mapper",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",