Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed
- **`codegraph index` / `init -i` summary now reports the true edge count.**
The per-file counter in the orchestrator only saw extraction-phase edges,
so resolution and synthesizer edges (often >50% of the graph on
cross-file-heavy repos like Spring multi-module Java) were missing from
the `X nodes, Y edges` line. Snapshotting the DB before/after the full
pipeline now reports the actual additions. Example: indexing
`macrozheng/mall` previously reported `20 047 edges` while the DB held
`45 629`.

## [0.9.6] - 2026-05-27

Expand Down Expand Up @@ -62,7 +71,6 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Both targets are tested on the same parameterized contract as the existing five agents (idempotent install, sibling preservation, install/uninstall round-trip), with extra coverage for migration-marker detection, legacy → unified entry migration, sibling `disabled` field preservation, and the cross-target case where Gemini CLI and Antigravity IDE coexist in the same `~/.gemini/`. Closes #399.
- **Installer target for Kiro (CLI + IDE).** `codegraph install` now detects and configures Kiro out of the box on macOS, Linux, and Windows. Writes `mcpServers.codegraph` to `~/.kiro/settings/mcp.json` (global) or `./.kiro/settings/mcp.json` (local), and the codegraph usage block into a dedicated `~/.kiro/steering/codegraph.md` / `./.kiro/steering/codegraph.md` — Kiro's steering system loads every `*.md` file in `steering/` as agent context, so a dedicated file is the natural surface (no marker-based merging required). Sibling MCP servers in `mcp.json` and unrelated steering files (`product.md`, `tech.md`, etc.) are preserved across install / uninstall. Tested on the same parameterized contract as the other agent targets (idempotent install, sibling preservation, install/uninstall round-trip). Closes #385.

## [0.9.5] - 2026-05-25

### Added
Expand Down
28 changes: 28 additions & 0 deletions __tests__/integration/full-pipeline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
13 changes: 13 additions & 0 deletions src/db/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,19 @@ export class QueryBuilder {
// Statistics
// ===========================================================================

/**
* Lightweight (nodes, edges) count snapshot. Used around an index/sync
* run to compute true additions across extraction + resolution +
* synthesis — the per-phase counter in the orchestrator only sees
* extraction's contribution, which is why the CLI summary under-reported
* the edge count (resolution + synthesizer edges were invisible).
*/
getNodeAndEdgeCount(): { nodes: number; edges: number } {
return this.db
.prepare('SELECT (SELECT COUNT(*) FROM nodes) AS nodes, (SELECT COUNT(*) FROM edges) AS edges')
.get() as { nodes: number; edges: number };
}

/**
* Get graph statistics
*/
Expand Down
10 changes: 10 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export class CodeGraph {
return { success: false, filesIndexed: 0, filesSkipped: 0, filesErrored: 0, nodesCreated: 0, edgesCreated: 0, errors: [{ message: 'Could not acquire file lock - another process may be indexing', severity: 'error' as const }], durationMs: 0 };
}
try {
const before = this.queries.getNodeAndEdgeCount();
const result = await this.orchestrator.indexAll(options.onProgress, options.signal, options.verbose);

// Re-detect frameworks now that the index is populated. The resolver
Expand Down Expand Up @@ -367,6 +368,15 @@ export class CodeGraph {
this.db.runMaintenance();
}

// The orchestrator only sees extraction-phase counts; resolution and
// synthesizer edges (often >50% of the graph on JVM repos) come later.
// Recompute against the DB so the CLI summary reports the true totals.
if (result.success && result.filesIndexed > 0) {
const after = this.queries.getNodeAndEdgeCount();
result.nodesCreated = after.nodes - before.nodes;
result.edgesCreated = after.edges - before.edges;
}

return result;
} finally {
this.fileLock.release();
Expand Down