From 3ef55df7d524af7e80a4114727efe023c539aa4d Mon Sep 17 00:00:00 2001 From: carlos-alm <127798846+carlos-alm@users.noreply.github.com> Date: Thu, 2 Apr 2026 21:52:21 -0600 Subject: [PATCH 1/3] fix(embed): handle absolute file paths from native engine (#752) The embed command unconditionally joined rootDir with node.file from the DB, producing doubled paths when the native engine stores absolute paths. Check path.isAbsolute before joining. Same fix applied to detect-changes reverse-dependency lookup. Regression test included. --- .../graph/builder/stages/detect-changes.ts | 2 +- src/domain/search/generator.ts | 2 +- tests/search/embedding-strategy.test.ts | 36 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/domain/graph/builder/stages/detect-changes.ts b/src/domain/graph/builder/stages/detect-changes.ts index e6524cb2..da82ec16 100644 --- a/src/domain/graph/builder/stages/detect-changes.ts +++ b/src/domain/graph/builder/stages/detect-changes.ts @@ -366,7 +366,7 @@ function findReverseDependencies( for (const relPath of changedRelPaths) { for (const row of findReverseDepsStmt.all(relPath) as Array<{ file: string }>) { if (!changedRelPaths.has(row.file) && !reverseDeps.has(row.file)) { - const absPath = path.join(rootDir, row.file); + const absPath = path.isAbsolute(row.file) ? row.file : path.join(rootDir, row.file); if (fs.existsSync(absPath)) { reverseDeps.add(row.file); } diff --git a/src/domain/search/generator.ts b/src/domain/search/generator.ts index af87d5aa..69363367 100644 --- a/src/domain/search/generator.ts +++ b/src/domain/search/generator.ts @@ -100,7 +100,7 @@ export async function buildEmbeddings( let overflowCount = 0; for (const [file, fileNodes] of byFile) { - const fullPath = path.join(rootDir, file); + const fullPath = path.isAbsolute(file) ? file : path.join(rootDir, file); let lines: string[]; try { lines = fs.readFileSync(fullPath, 'utf-8').split('\n'); diff --git a/tests/search/embedding-strategy.test.ts b/tests/search/embedding-strategy.test.ts index a8e58828..96010a24 100644 --- a/tests/search/embedding-strategy.test.ts +++ b/tests/search/embedding-strategy.test.ts @@ -289,6 +289,42 @@ describe('FTS5 index built alongside embeddings', () => { }); }); +describe('absolute file paths in DB (#752)', () => { + let absDir: string, absDbPath: string; + + beforeAll(() => { + absDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-abspath-test-')); + fs.writeFileSync( + path.join(absDir, 'math.js'), + 'export function add(a, b) { return a + b; }\n', + ); + + const dbDir = path.join(absDir, '.codegraph'); + fs.mkdirSync(dbDir, { recursive: true }); + absDbPath = path.join(dbDir, 'graph.db'); + + const db = new Database(absDbPath); + db.pragma('journal_mode = WAL'); + initSchema(db); + // Insert node with ABSOLUTE file path (simulates native engine behavior) + const absFile = path.join(absDir, 'math.js').split(path.sep).join('/'); + insertNode(db, 'add', 'function', absFile, 1, 1); + db.close(); + }); + + afterAll(() => { + if (absDir) fs.rmSync(absDir, { recursive: true, force: true }); + }); + + test('embeds symbols even when DB stores absolute file paths', async () => { + EMBEDDED_TEXTS.length = 0; + await buildEmbeddings(absDir, 'minilm', absDbPath, { strategy: 'source' }); + + expect(EMBEDDED_TEXTS.length).toBe(1); + expect(EMBEDDED_TEXTS[0]).toContain('add'); + }); +}); + describe('context window overflow detection', () => { let bigDir: string, bigDbPath: string; From 26bc6e751a6ae4ba8005d547fb9d6b21349386c6 Mon Sep 17 00:00:00 2001 From: carlos-alm <127798846+carlos-alm@users.noreply.github.com> Date: Thu, 2 Apr 2026 21:52:40 -0600 Subject: [PATCH 2/3] style: fix biome format in test --- tests/search/embedding-strategy.test.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/search/embedding-strategy.test.ts b/tests/search/embedding-strategy.test.ts index 96010a24..610fb844 100644 --- a/tests/search/embedding-strategy.test.ts +++ b/tests/search/embedding-strategy.test.ts @@ -294,10 +294,7 @@ describe('absolute file paths in DB (#752)', () => { beforeAll(() => { absDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-abspath-test-')); - fs.writeFileSync( - path.join(absDir, 'math.js'), - 'export function add(a, b) { return a + b; }\n', - ); + fs.writeFileSync(path.join(absDir, 'math.js'), 'export function add(a, b) { return a + b; }\n'); const dbDir = path.join(absDir, '.codegraph'); fs.mkdirSync(dbDir, { recursive: true }); From e44ad6058e0b64d7f37bb8819bd54a49e536690c Mon Sep 17 00:00:00 2001 From: carlos-alm <127798846+carlos-alm@users.noreply.github.com> Date: Thu, 2 Apr 2026 22:53:36 -0600 Subject: [PATCH 3/3] fix: apply isAbsolute guard to native fast-path and add source strategy test (#780) --- src/domain/graph/builder/stages/detect-changes.ts | 2 +- tests/search/embedding-strategy.test.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/domain/graph/builder/stages/detect-changes.ts b/src/domain/graph/builder/stages/detect-changes.ts index da82ec16..d46a11ab 100644 --- a/src/domain/graph/builder/stages/detect-changes.ts +++ b/src/domain/graph/builder/stages/detect-changes.ts @@ -349,7 +349,7 @@ function findReverseDependencies( const changedArray = [...changedRelPaths]; const nativeResults = nativeDb.findReverseDependencies(changedArray); for (const dep of nativeResults) { - const absPath = path.join(rootDir, dep); + const absPath = path.isAbsolute(dep) ? dep : path.join(rootDir, dep); if (fs.existsSync(absPath)) { reverseDeps.add(dep); } diff --git a/tests/search/embedding-strategy.test.ts b/tests/search/embedding-strategy.test.ts index 38eda6cd..ff0265c6 100644 --- a/tests/search/embedding-strategy.test.ts +++ b/tests/search/embedding-strategy.test.ts @@ -314,7 +314,7 @@ describe('absolute file paths in DB (#752)', () => { if (absDir) fs.rmSync(absDir, { recursive: true, force: true }); }); - test('produces embeddings when DB stores absolute paths', async () => { + test('produces embeddings when DB stores absolute paths (structured)', async () => { EMBEDDED_TEXTS.length = 0; await buildEmbeddings(absDir, 'minilm', absDbPath); @@ -325,6 +325,14 @@ describe('absolute file paths in DB (#752)', () => { db.close(); expect(count).toBe(1); }); + + test('produces embeddings when DB stores absolute paths (source)', async () => { + EMBEDDED_TEXTS.length = 0; + await buildEmbeddings(absDir, 'minilm', absDbPath, { strategy: 'source' }); + + expect(EMBEDDED_TEXTS.length).toBe(1); + expect(EMBEDDED_TEXTS[0]).toContain('add'); + }); }); describe('context window overflow detection', () => {