This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
CodeGraph is a local-first code intelligence library + CLI + MCP server. It parses any supported codebase with tree-sitter, stores symbols/edges/files in SQLite (FTS5), and exposes a knowledge graph to AI agents (Claude Code, Cursor, Codex CLI, opencode) over MCP. Per-project data lives in .codegraph/. Extraction is deterministic — derived from AST, not LLM-summarized.
Distributed as @colbymchenry/codegraph on npm; same binary serves as installer, indexer, and MCP server.
npm run build # tsc + copy schema.sql and *.wasm into dist/; chmods dist/bin/codegraph.js
npm run dev # tsc --watch
npm run clean # rm -rf dist
npm test # vitest run (all)
npm run test:watch
npm run test:eval # only __tests__/evaluation/
npm run eval # build then run __tests__/evaluation/runner.ts via tsx
npm run cli # build then run the local dist binary
# Single test file / pattern
npx vitest run __tests__/installer-targets.test.ts
npx vitest run __tests__/extraction.test.ts -t "TypeScript"copy-assets (called from build) copies src/db/schema.sql and all src/extraction/wasm/*.wasm files into dist/. Any new SQL or grammar wasm must be copied or it won't ship.
Node engines: >=18.0.0 <25.0.0. There is a hard exit on Node 25.x (see src/bin/node-version-check.ts).
files → ExtractionOrchestrator (tree-sitter) → DB (nodes/edges/files)
↓
ReferenceResolver (imports, name-matching, framework patterns)
↓
GraphQueryManager / GraphTraverser (callers, callees, impact)
↓
ContextBuilder (markdown/JSON for AI consumption)
The public API surface is src/index.ts — the CodeGraph class wires all the layers and re-exports types. Library users only touch this file; the MCP server and CLI also drive it.
src/index.ts—CodeGraphclass:init/open/close,indexAll,sync,searchNodes,getCallers/getCallees,getImpactRadius,buildContext,watch/unwatch.src/db/—DatabaseConnection,QueryBuilder(prepared statements),schema.sql. Backed bybetter-sqlite3(native) when available, transparently falls back tonode-sqlite3-wasm.codegraph statussurfaces which backend is live; wasm is the slow path.src/extraction/—ExtractionOrchestrator, tree-sitter wrappers, per-language extractors underlanguages/(one file per language), plus standalone extractors for non-tree-sitter formats (svelte-extractor.ts,vue-extractor.ts,liquid-extractor.ts,dfm-extractor.tsfor Delphi).parse-worker.tsruns heavy parsing off the main thread.src/resolution/—ReferenceResolverorchestratesimport-resolver.ts(withpath-aliases.tsfor tsconfig path aliases + cargo workspace member globs),name-matcher.ts, andframeworks/(Express, Laravel, Rails, FastAPI, Django, Flask, Spring, Gin, Axum, ASP.NET, Vapor, React Router, SvelteKit, Vue/Nuxt, Cargo workspaces). Frameworks emitroutenodes andreferencesedges.src/graph/—GraphTraverser(BFS/DFS, impact radius, path finding) andGraphQueryManager(high-level queries).src/context/—ContextBuilder+ formatter for markdown/JSON output.src/search/— full-text query parser and helpers for FTS5.src/sync/—FileWatcher(native FSEvents/inotify/RDCW) with debounce + filter, and git-hook helpers.src/mcp/— MCP server (MCPServer,tools.ts,transport.ts).server-instructions.tsis what the server returns in the MCPinitializeresponse — keep it in sync with the user-facing tool guidance.src/installer/— see below.src/bin/codegraph.ts— CLI (commander). Subcommands:install,init,uninit,index,sync,status,query,files,context,affected,serve --mcp.src/ui/— terminal UI (shimmer progress, worker).
Defined in src/types.ts. Both extractors and resolvers must use these exact strings.
- NodeKind:
file,module,class,struct,interface,trait,protocol,function,method,property,field,variable,constant,enum,enum_member,type_alias,namespace,parameter,import,export,route,component. - EdgeKind:
contains,calls,imports,exports,extends,implements,references,type_of,returns,instantiates,overrides,decorates.
src/installer/ is the entry point for codegraph install (and the bare codegraph/npx @colbymchenry/codegraph invocation). Architecture:
targets/registry.tslists every supported agent.targets/types.tsdefines theAgentTargetinterface — adding a 5th agent (Continue, Zed, Windsurf…) is one new file intargets/+ one entry inregistry.ts. Each target owns its config-file location, MCP-server JSON/TOML/JSONC writing, and instructions-file path.- Current targets:
claude.ts,cursor.ts,codex.ts,opencode.ts. targets/toml.tsis a hand-rolled TOML serializer scoped to[mcp_servers.codegraph](used by Codex). Sibling tables and[[array_of_tables]]are preserved verbatim. No new dependency.- opencode reads
opencode.jsoncby default; the installer prefers existing.jsonc, falls back to.json, and creates.jsoncfor greenfield installs. Edits are surgical viajsonc-parserso user comments and formatting survive install/re-install/uninstall round-trips. instructions-template.tsis the agent-agnostic instructions file written to each target (e.g.CLAUDE.md,.cursor/rules/codegraph.mdc,~/.codex/AGENTS.md,~/.config/opencode/AGENTS.md). It explicitly says "trust codegraph results, don't re-verify with grep" — earlier versions prescribed Claude-specific "spawn an Explore agent" and confused other agents.claude-md-template.tsis the legacy Claude-only template, retained for compatibility paths.- All installer changes need matching coverage in
__tests__/installer-targets.test.ts— there are ~47 parameterized contract tests covering install idempotency, sibling preservation, uninstall reverses install, byte-equal re-runs returningunchanged, and partial-state recovery for Codex.
Cursor launches MCP subprocesses with the wrong cwd and doesn't pass rootUri in initialize. The installer injects --path into Cursor's MCP args — absolute path for local installs, ${workspaceFolder} for global installs. If you touch Cursor wiring, preserve this.
src/mcp/server-instructions.ts is sent back to the agent in the MCP initialize response. This is the first thing every agent sees about how to use the tools — treat it as the authoritative tool guidance and keep it in sync with instructions-template.ts and .cursor/rules/codegraph.mdc.
Tests live in __tests__/ and mirror the module they cover. Notable ones beyond the obvious:
installer-targets.test.ts— parameterized contract suite across all 4 agent targets (see installer notes above).evaluation/—runner.ts+test-cases.tsexercise codegraph against synthetic projects and score the results; run vianpm run eval(builds first). Not part ofnpm test.sqlite-backend.test.ts— covers native + wasm backend selection and fallback.pr19-improvements.test.ts,frameworks-integration.test.ts— regression coverage for specific past PRs/incidents; don't rename these, the names anchor to git history.
Tests create temp dirs with fs.mkdtempSync and clean up in afterEach. They write real files and exercise real SQLite — there is no DB mocking.
Released to npm and mirrored as GitHub Releases. CHANGELOG.md is the source of truth; GitHub Release notes are extracted from it.
When asked for an entry for a new version:
- Add a new
## [X.Y.Z] - YYYY-MM-DDblock at the top ofCHANGELOG.md(under the intro, above the previous version). - Group under
### Added,### Changed,### Fixed,### Removed,### Deprecated,### Security— omit empty sections. - Write from the user's perspective, not the implementation's. Lead with the observable symptom or capability; mention internals only if a user needs them (e.g., to work around an existing bad install).
- Add the link reference at the bottom:
[X.Y.Z]: https://github.com/colbymchenry/codegraph/releases/tag/vX.Y.Z.
After the changelog entry is written and package.json is bumped:
git add package.json package-lock.json CHANGELOG.md
git commit -m "release: X.Y.Z (<one-line summary>)"
git push
npm publish
./scripts/release.sh # idempotent: tags vX.Y.Z, pushes, creates GitHub Release with notes from CHANGELOG.mdscripts/release.sh is safe to re-run after a partial failure — it skips steps already done (tag exists locally, tag on origin, release published). It extracts release notes from CHANGELOG.md by matching the ## [X.Y.Z] block.
Do not run npm publish, git push, git tag, or ./scripts/release.sh yourself — these are publish actions on shared state. Write the file, hand the user the commands.
- The
0.7.xline is in active multi-agent rollout. Any change tosrc/installer/(especiallytargets/) needs corresponding test coverage and a CHANGELOG entry — installer regressions break every new install silently. - When changing what the MCP tools do or how agents should use them, update all three of
src/mcp/server-instructions.ts,src/installer/instructions-template.ts, and.cursor/rules/codegraph.mdc— they're written to different places but say the same thing. - CodeGraph provides code context, not product requirements. For new features, ask the user about UX, edge cases, and acceptance criteria — the graph won't tell you.