This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
For any non-trivial analysis, review, or investigation (not routine edits), end with a confidence (High/Medium/Low) and a recommendation (e.g. merge/hold/needs more info) so the result is decision-ready.
Infigraph is an AST-powered code intelligence engine: indexes codebases (62 languages) into a persistent embedded graph database (LadybugDB) with Cypher queries, hybrid search, cross-file call resolution, and MCP tools for AI coding agents. Rust workspace, zero LLM dependency, fully local/offline.
cargo build --release -p infigraph-cli -p infigraph-mcp
cargo test --all
cargo fmt --all
cargo clippy --all-targets -- -D warningsRequires cmake. CI runs fmt-check, clippy, and the full test suite across macOS/Linux/Windows — match locally before pushing.
Change-safety workflow: check blast radius before editing a shared/foundational path (e.g. via cross-file reference lookups) — a change in infigraph-core can silently break the CLI/MCP crates on top of it. Run targeted tests for the area you touched first, then cargo test --all before considering it done — this repo has real process-level integration tests (e.g. under infigraph-mcp/tests/), not just unit tests, so --all matters. The pre-commit hook enforces fmt/clippy across the whole workspace, not just changed files — pre-existing unrelated drift elsewhere can block an otherwise-clean change; worth checking cargo fmt --all -- --check and cargo clippy --all-targets -- -D warnings once at the start of a session to know your baseline.
Release process: ./release.sh <version> (see README's release section). Windows has a few build quirks around the graph DB's static-lib size and CRT linkage — see root Cargo.toml comments.
infigraph-core— the engine: models, language registry, AST extraction, graph storage, search, cross-file resolution, multi-repo/groups, file watching, SCIP enrichment, and the analysis passes (taint, concerns, reflection, config binding).infigraph-languages— tree-sitter language packs (query files, not Rust code).infigraph-grammar-plugin— runtime ANTLR-based plugin system for languages without a tree-sitter grammar.infigraph-pipeline-plugin— runtime plugin system for data-pipeline metadata extraction.infigraph-docs/infigraph-confluence— document and wiki indexing, feeding the same search pipeline.infigraph-cli— theinfigraphbinary.infigraph-mcp— the MCP server binary, plus the embedded web UI and session persistence.lsp-to-scip— generic LSP→SCIP bridge for languages without a dedicated SCIP indexer.
Source → AST extraction → cross-file resolution → graph → optional SCIP enrichment → search index. Both local (embedded graph DB) and remote (--features remote: Neo4j + Postgres, multi-repo) modes share the same schema — see docs/REMOTE-MULTI-REPO.md.
- The graph DB is single-writer — write paths take an advisory lock; a new write path needs one too.
- Indexing respects
.gitignore/.infigraphignore— don't hand-roll path filtering. - The graph's edge/node schema is extensible per-language-plugin, not a fixed enum.
- File-watching uses a lock file for cross-process dedup — anything that starts a watcher must hold it for the watcher's lifetime.
- Route/decorator extraction differs by language syntax (query-based vs. AST-sibling-scan) — check both before assuming a language isn't covered.
- Background scratch files (SCIP enrichment log/tmp) use fixed, non-run-unique paths — concurrent
infigraph indexruns can race on them. - Never call
kuzu::Database::newon an unvalidated path — a truncated/corrupt file can make Kuzu's parser read a bogus size field and request a huge allocation, which aborts the whole process on some platforms (observed on Linux, not macOS) before anyResultexists to catch it. Check file size against a sane minimum first (seeGraphStore::open/DocStore::open). - Any "wipe and rebuild on open failure" logic must distinguish transient errors (lock contention, resource pressure) from actual corruption — treating every failure as corruption risks destroying real data mid-race with a concurrent reader/writer.
For deeper detail on any of these, see the matching skill/rule (code-indexing-pipeline for language/resolution/SCIP/watch; analysis-subsystems for multi-repo/taint).
- CI's
dtolnay/rust-toolchain@stablefloats to whatever "stable" resolves to at run time — a newer clippy than your local toolchain can fail on lints your local run never sees. If local and CI disagree on fmt/clippy, suspect this before assuming a bug — confirm by installing CI's exact version locally (rustup show active-toolchainwith a temporaryrust-toolchain.tomloverride) rather than guessing. - If a PR gets merged into
maindirectly and separately into a feature branch, GitHub's synthetic PR-merge-commit computation can silently duplicate content (e.g. two copies of the same test module) even when neither branch alone shows a problem — this only appears in the merge commit itself. Rebase the feature branch onto currentmainto fix it for real, rather than trying to resolve it in a synthetic merge. - Local test runs under high parallelism (
--test-threadsdefault) can produce resource-contention failures (e.g. mmap/buffer-manager exhaustion from multiple embedded-DB test processes) that aren't real bugs — always confirm a suspected regression with--test-threads=1before treating it as one.
tests/fixtures/microservices/ — real microservice repos (Python/Flask, TypeScript/Express, Rust/Actix) for route and cross-service tests. Prefer extending these over new synthetic fixtures.