Indexing Pipeline
Indexing is the path from raw files to a resolved graph. It runs on every full build and, in pieces, on every incremental update.
The stages
Scan root, .gitignore-aware, skip generated / dependency dirs
|
Extract tree-sitter (11 languages) or regex/structured extraction
|
Post-process import resolution -> raw call resolution -> relation resolution
| -> semantic deduplication -> community detection -> analysis
|
Export graph.json (+ html, svg, obsidian, cypher, call-flow)Scan
CGraph scans the source tree deterministically, honoring the root .gitignore
and skipping generated and dependency directories by default. Determinism here
is the foundation for everything downstream — the same tree yields the same
node set every time.
Extract
Each file is parsed into nodes and links. Supported languages (C, C++, Java, JavaScript, TypeScript, TSX, Kotlin, Scala, Groovy, Python, Ruby) use vendored tree-sitter grammars; the rest (Apex, Delphi, MSBuild/XML, MCP config) use regex/structured extraction.
Post-process
Extraction produces a raw graph; post-processing resolves it into a connected one, in order:
- Import resolution — connect files/modules to what they import.
- Raw call resolution — connect callers to callees.
- Relation resolution — resolve remaining relationships.
- Semantic deduplication — merge duplicate semantic nodes.
- Community detection — group related nodes into communities.
- Graph analysis — compute the analytical properties queries rely on.
The intermediate data shapes between these stages, and the exact ordering rules
within post-processing, are defined in src/engine and not enumerated in the
public README. This page documents the stages CGraph performs; the internal
representations are pending confirmation against the source.
Export
The resolved graph is written to cgraph-out/ as graph.json (canonical
node-link) plus the visual and interchange formats. See the
Graph Model for what those nodes and links mean.
Tradeoffs
Static resolution is precise for direct calls and imports but approximate where the language isn't: dynamic dispatch, reflection, and runtime wiring can't always be resolved from source alone. CGraph favors a deterministic, reproducible graph over chasing every dynamic edge.