fix(cli): include resolution + synthesizer edges in indexAll report (#413)

The orchestrator's per-file counter only sees extraction-phase edges, so the `X nodes, Y edges` line printed after `codegraph init -i` / `codegraph index` undercounts the graph — often by more than half on repos with heavy cross-file resolution (mall: 20 047 reported vs 45 629 actually in the DB).

Snapshot (nodes, edges) before/after the full pipeline in `indexAll` and write the true delta back to the result. New lightweight `QueryBuilder.getNodeAndEdgeCount()` is one round-trip with no per-kind breakdowns. `indexFiles` (no resolution) and `sync` (uses `nodesUpdated`, not `nodesCreated`) are unaffected.

Regression test added: `__tests__/integration/full-pipeline.test.ts > reports edgesCreated including resolution + synthesizer phases`.
This commit is contained in:
Artem Bambalov
2026-05-26 21:08:59 -05:00
committed by GitHub
parent 625e5663c4
commit 3808b4d0a8
4 changed files with 60 additions and 1 deletions
@@ -241,4 +241,32 @@ describe('Integration: full pipeline', () => {
cg.destroy();
}
}, 30_000);
it('reports edgesCreated including resolution + synthesizer phases', async () => {
// The synthetic project has cross-file imports, calls, and extends —
// all wired up in the resolution phase, AFTER the orchestrator's
// per-file extraction counter is done. The CLI summary used to read
// only the extraction-phase counter and undercount the graph; this
// test pins the counter to the true DB totals across all phases.
generateSyntheticProject(tempDir, 30);
const cg = await CodeGraph.init(tempDir, {
config: { include: ['**/*.ts'], exclude: [] },
});
try {
const result = await cg.indexAll();
const stats = cg.getStats();
expect(result.success).toBe(true);
expect(result.nodesCreated).toBe(stats.nodeCount);
expect(result.edgesCreated).toBe(stats.edgeCount);
// Sanity: cross-file resolution had something to do — calls/extends
// edges should exist beyond the bare extraction-time contains edges.
const containsOnly = stats.edgesByKind.contains ?? 0;
expect(stats.edgeCount).toBeGreaterThan(containsOnly);
} finally {
cg.destroy();
}
}, 30_000);
});