diff --git a/README.md b/README.md index 6a8835b..3104a8c 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@
-# ๐Ÿ”ฎ CodeGraph +# CodeGraph ### Supercharge Claude Code with Semantic Code Intelligence -**94% fewer tool calls โ€ข 77% faster exploration โ€ข 100% local** +**94% fewer tool calls ยท 77% faster exploration ยท 100% local** [![npm version](https://img.shields.io/npm/v/@colbymchenry/codegraph.svg)](https://www.npmjs.com/package/@colbymchenry/codegraph) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) @@ -28,15 +28,15 @@ npx @colbymchenry/codegraph --- -## ๐Ÿš€ Why CodeGraph? +## Why CodeGraph? -When you ask Claude Code to work on a complex task, it spawns **Explore agents** that scan your codebase using grep, glob, and file reads. These agents consume tokens with every tool call. +When Claude Code explores a codebase, it spawns **Explore agents** that scan files with grep, glob, and Read โ€” consuming tokens on every tool call. -**CodeGraph gives those agents a semantic knowledge graph** โ€” pre-indexed symbol relationships, call graphs, and code structure. Instead of scanning files, agents query the graph instantly. +**CodeGraph gives those agents a pre-indexed knowledge graph** โ€” symbol relationships, call graphs, and code structure. Agents query the graph instantly instead of scanning files. -### ๐Ÿ“Š Benchmark Results +### Benchmark Results -We tested exploration queries across 6 real-world codebases in different languages, comparing Claude Code's Explore agent **with** and **without** CodeGraph: +Tested across 6 real-world codebases comparing Claude Code's Explore agent **with** and **without** CodeGraph: > **Average: 92% fewer tool calls ยท 71% faster** @@ -94,100 +94,22 @@ All tests used Claude Opus 4.6 (1M context) with Claude Code v2.1.91. Each test -### ๐Ÿ”„ How It Works +--- -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ Claude Code โ”‚ -โ”‚ โ”‚ -โ”‚ "Implement user authentication" โ”‚ -โ”‚ โ”‚ โ”‚ -โ”‚ โ–ผ โ”‚ -โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ -โ”‚ โ”‚ Explore Agent โ”‚ โ”€โ”€โ”€โ”€ โ”‚ Explore Agent โ”‚ โ”‚ -โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ -โ”‚ โ”‚ โ”‚ โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ โ”‚ - โ–ผ โ–ผ -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ CodeGraph MCP Server โ”‚ -โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ -โ”‚ โ”‚ Search โ”‚ โ”‚ Callers โ”‚ โ”‚ Context โ”‚ โ”‚ -โ”‚ โ”‚ "auth" โ”‚ โ”‚ "login()" โ”‚ โ”‚ for task โ”‚ โ”‚ -โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ -โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ -โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ -โ”‚ โ–ผ โ”‚ -โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ -โ”‚ โ”‚ SQLite Graph DB โ”‚ โ”‚ -โ”‚ โ”‚ โ€ข 387 symbols โ”‚ โ”‚ -โ”‚ โ”‚ โ€ข 1,204 edges โ”‚ โ”‚ -โ”‚ โ”‚ โ€ข Instant lookups โ”‚ โ”‚ -โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` +## Key Features -**Without CodeGraph:** Explore agents use `grep`, `glob`, and `Read` to scan files โ†’ many API calls, high token usage - -**With CodeGraph:** Explore agents query the graph via MCP tools โ†’ instant results, local processing, fewer tokens +| | | +|---|---| +| **Smart Context Building** | One tool call returns entry points, related symbols, and code snippets โ€” no expensive exploration agents | +| **Full-Text Search** | Find code by name instantly across your entire codebase, powered by FTS5 | +| **Impact Analysis** | Trace callers, callees, and the full impact radius of any symbol before making changes | +| **Always Fresh** | File watcher uses native OS events (FSEvents/inotify/ReadDirectoryChangesW) with debounced auto-sync โ€” the graph stays current as you code, zero config | +| **19+ Languages** | TypeScript, JavaScript, Python, Go, Rust, Java, C#, PHP, Ruby, C, C++, Swift, Kotlin, Dart, Svelte, Liquid, Pascal/Delphi | +| **100% Local** | No data leaves your machine. No API keys. No external services. SQLite database only | --- -## โœจ Key Features - - - - - - - - - - - - -
- -### ๐Ÿง  Smart Context Building -One tool call returns everything Claude needsโ€”entry points, related symbols, and code snippets. No more expensive exploration agents. - - - -### ๐Ÿ” Full-Text Search -Find code by name across your entire codebase instantly. Search for "auth" and find `authenticate`, `AuthService`, `validateToken` โ€” powered by FTS5. - - - -### ๐Ÿ“ˆ Impact Analysis -Know exactly what breaks before you change it. Trace callers, callees, and the full impact radius of any symbol. - -
- -### ๐ŸŒ 19+ Languages -TypeScript, JavaScript, Python, Go, Rust, Java, C#, PHP, Ruby, C, C++, Swift, Kotlin, Dart, Svelte, Liquid, Pascal/Delphiโ€”all with the same API. - - - -### ๐Ÿ”’ 100% Local -No data leaves your machine. No API keys. No external services. Everything runs on your local SQLite database. - - - -### โšก Always Fresh -The MCP server watches your files and auto-syncs on save โ€” debounced, filtered to source files only, zero config. Your code intelligence is always up to date. - -
- ---- - -## ๐Ÿ“‹ Requirements - -- **Node.js >= 18.0.0** - ---- - -## ๐ŸŽฏ Quick Start +## Quick Start ### 1. Run the Installer @@ -195,11 +117,11 @@ The MCP server watches your files and auto-syncs on save โ€” debounced, filtered npx @colbymchenry/codegraph ``` -The interactive installer will: -- Prompt to install `codegraph` globally (needed for the MCP server to work) +The installer will: +- Prompt to install `codegraph` globally (needed for the MCP server) - Configure the MCP server in `~/.claude.json` - Set up auto-allow permissions for CodeGraph tools -- Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph) +- Add global instructions to `~/.claude/CLAUDE.md` - Optionally initialize your current project ### 2. Restart Claude Code @@ -208,20 +130,16 @@ Restart Claude Code for the MCP server to load. ### 3. Initialize Projects -For each project you want to use CodeGraph with: - ```bash cd your-project codegraph init -i ``` -That's it! Claude Code will now use CodeGraph tools automatically when a `.codegraph/` directory exists. +That's it! Claude Code will use CodeGraph tools automatically when a `.codegraph/` directory exists.
Manual Setup (Alternative) -If you prefer manual configuration: - **Install globally:** ```bash npm install -g @colbymchenry/codegraph @@ -263,7 +181,7 @@ npm install -g @colbymchenry/codegraph
Global Instructions Reference -The installer automatically adds these instructions to `~/.claude/CLAUDE.md`. This is provided here for reference: +The installer automatically adds these instructions to `~/.claude/CLAUDE.md`: ```markdown ## CodeGraph @@ -303,377 +221,147 @@ At the start of a session, ask the user if they'd like to initialize CodeGraph: --- -## ๐Ÿ’ป CLI Usage +## How It Works -```bash -codegraph # Run interactive installer -codegraph install # Run interactive installer (explicit) -codegraph init [path] # Initialize in a project -codegraph uninit [path] # Remove CodeGraph from a project -codegraph index [path] # Full index -codegraph sync [path] # Incremental update -codegraph status [path] # Show statistics -codegraph query # Search symbols -codegraph files [path] # Show project file structure -codegraph context # Build context for AI -codegraph affected [files] # Find test files affected by changes -codegraph serve --mcp # Start MCP server +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Claude Code โ”‚ +โ”‚ โ”‚ +โ”‚ "Implement user authentication" โ”‚ +โ”‚ โ”‚ โ”‚ +โ”‚ โ–ผ โ”‚ +โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ +โ”‚ โ”‚ Explore Agent โ”‚ โ”€โ”€โ”€โ”€ โ”‚ Explore Agent โ”‚ โ”‚ +โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ โ”‚ + โ–ผ โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ CodeGraph MCP Server โ”‚ +โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ +โ”‚ โ”‚ Search โ”‚ โ”‚ Callers โ”‚ โ”‚ Context โ”‚ โ”‚ +โ”‚ โ”‚ "auth" โ”‚ โ”‚ "login()" โ”‚ โ”‚ for task โ”‚ โ”‚ +โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ +โ”‚ โ–ผ โ”‚ +โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ +โ”‚ โ”‚ SQLite Graph DB โ”‚ โ”‚ +โ”‚ โ”‚ โ€ข 387 symbols โ”‚ โ”‚ +โ”‚ โ”‚ โ€ข 1,204 edges โ”‚ โ”‚ +โ”‚ โ”‚ โ€ข Instant lookups โ”‚ โ”‚ +โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` -## ๐Ÿ“– CLI Commands +1. **Extraction** โ€” [tree-sitter](https://tree-sitter.github.io/) parses source code into ASTs. Language-specific queries extract nodes (functions, classes, methods) and edges (calls, imports, extends, implements). -### `codegraph` / `codegraph install` +2. **Storage** โ€” Everything goes into a local SQLite database (`.codegraph/codegraph.db`) with FTS5 full-text search. -Run the interactive installer for Claude Code integration. Configures MCP server and permissions automatically. +3. **Resolution** โ€” After extraction, references are resolved: function calls โ†’ definitions, imports โ†’ source files, class inheritance, and framework-specific patterns. + +4. **Auto-Sync** โ€” The MCP server watches your project using native OS file events. Changes are debounced (2-second quiet window), filtered to source files only, and incrementally synced. The graph stays fresh as you code โ€” no configuration needed. + +--- + +## CLI Reference ```bash -codegraph # Run installer (when no args) +codegraph # Run interactive installer codegraph install # Run installer (explicit) -npx @colbymchenry/codegraph # Run via npx (no global install needed) +codegraph init [path] # Initialize in a project (--index to also index) +codegraph uninit [path] # Remove CodeGraph from a project (--force to skip prompt) +codegraph index [path] # Full index (--force to re-index, --quiet for less output) +codegraph sync [path] # Incremental update +codegraph status [path] # Show statistics +codegraph query # Search symbols (--kind, --limit, --json) +codegraph files [path] # Show file structure (--format, --filter, --max-depth, --json) +codegraph context # Build context for AI (--format, --max-nodes) +codegraph affected [files...] # Find test files affected by changes (see below) +codegraph serve --mcp # Start MCP server ``` -The installer will: -1. Prompt to install `codegraph` globally (needed for the MCP server) -2. Ask for installation location (global `~/.claude` or local `./.claude`) -3. Optionally set up auto-allow permissions -4. Configure the MCP server in `claude.json` -5. Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph) -6. For local installs: initialize and index the current project +### `codegraph affected` -### `codegraph init [path]` - -Initialize CodeGraph in a project directory. Creates a `.codegraph/` directory with the database and configuration. - -```bash -codegraph init # Initialize in current directory -codegraph init /path/to/project # Initialize in specific directory -codegraph init --index # Initialize and immediately index -``` - -### `codegraph uninit [path]` - -Remove CodeGraph from a project. Deletes the `.codegraph/` directory and all indexed data. - -```bash -codegraph uninit # Remove from current directory -codegraph uninit --force # Skip confirmation prompt -``` - -### `codegraph index [path]` - -Index all files in the project. Extracts functions, classes, methods, and their relationships. - -```bash -codegraph index # Index current directory -codegraph index --force # Force full re-index -codegraph index --quiet # Suppress progress output -``` - -### `codegraph sync [path]` - -Incrementally sync changes since the last index. Only processes added, modified, or removed files. - -```bash -codegraph sync # Sync current directory -codegraph sync --quiet # Suppress output -``` - -### `codegraph status [path]` - -Show index status and statistics. - -```bash -codegraph status -``` - -Output includes: -- Files indexed, nodes, edges -- Nodes by kind (functions, classes, methods, etc.) -- Files by language -- Pending changes (if any) - -### `codegraph query ` - -Search for symbols in the codebase by name. - -```bash -codegraph query "authenticate" # Search for symbols -codegraph query "User" --kind class # Filter by kind -codegraph query "process" --limit 20 # Limit results -codegraph query "validate" --json # Output as JSON -``` - -### `codegraph files [path]` - -Show the project file structure from the index. Faster than filesystem scanning since it reads from the indexed data. - -```bash -codegraph files # Show file tree -codegraph files --format flat # Simple list -codegraph files --format grouped # Group by language -codegraph files --filter src/components # Filter by directory -codegraph files --pattern "*.test.ts" # Filter by glob pattern -codegraph files --max-depth 2 # Limit tree depth -codegraph files --no-metadata # Hide language/symbol counts -codegraph files --json # Output as JSON -``` - -### `codegraph context ` - -Build relevant code context for a task. Uses full-text search to find entry points, then expands through the graph to find related code. - -```bash -codegraph context "fix checkout bug" -codegraph context "add user authentication" --format json -codegraph context "refactor payment service" --max-nodes 30 -``` - -### `codegraph affected [files...]` - -Find test files affected by changed source files. Traces import dependencies transitively through the graph to discover which test files depend on the code you changed. Works with any test framework and any language CodeGraph supports. +Traces import dependencies transitively to find which test files are affected by changed source files. ```bash codegraph affected src/utils.ts src/api.ts # Pass files as arguments git diff --name-only | codegraph affected --stdin # Pipe from git diff -codegraph affected --stdin --json < changed.txt # JSON output codegraph affected src/auth.ts --filter "e2e/*" # Custom test file pattern -codegraph affected src/lib.ts --depth 3 --quiet # Shallow search, paths only ``` -**Options:** - | Option | Description | Default | |--------|-------------|---------| -| `--stdin` | Read file list from stdin (one per line) | `false` | +| `--stdin` | Read file list from stdin | `false` | | `-d, --depth ` | Max dependency traversal depth | `5` | | `-f, --filter ` | Custom glob to identify test files | auto-detect | | `-j, --json` | Output as JSON | `false` | -| `-q, --quiet` | Output file paths only, no decoration | `false` | -| `-p, --path ` | Project path | auto-detect | +| `-q, --quiet` | Output file paths only | `false` | -**How it works:** - -1. For each changed file, BFS-traverses its transitive dependents (files that import from it, directly or indirectly) -2. Filters results to test files using common conventions (`*.spec.*`, `*.test.*`, `e2e/`, `tests/`, `__tests__/`) or a custom `--filter` glob -3. Changed files that are themselves test files are always included - -**Example: CI/hook integration** +**CI/hook example:** ```bash #!/usr/bin/env bash -# In a pre-commit hook or CI step: AFFECTED=$(git diff --name-only HEAD | codegraph affected --stdin --quiet) if [ -n "$AFFECTED" ]; then - echo "Running affected tests..." npx vitest run $AFFECTED fi ``` -### `codegraph serve` +--- -Start CodeGraph as an MCP server for AI assistants. +## MCP Tools -```bash -codegraph serve # Show MCP configuration help -codegraph serve --mcp # Start MCP server (stdio) -codegraph serve --mcp --path /project # Specify project path -``` +When running as an MCP server, CodeGraph exposes these tools to Claude Code: -## ๐Ÿ”Œ MCP Tools Reference +| Tool | Purpose | +|------|---------| +| `codegraph_search` | Find symbols by name across the codebase | +| `codegraph_context` | Build relevant code context for a task | +| `codegraph_callers` | Find what calls a function | +| `codegraph_callees` | Find what a function calls | +| `codegraph_impact` | Analyze what code is affected by changing a symbol | +| `codegraph_node` | Get details about a specific symbol (optionally with source code) | +| `codegraph_files` | Get indexed file structure (faster than filesystem scanning) | +| `codegraph_status` | Check index health and statistics | -When running as an MCP server, CodeGraph exposes these tools to AI assistants. **These tools are designed to be used by Claude's Explore agents** for faster, more efficient codebase exploration. +--- -### `codegraph_context` - -Build context for a specific task. Good for focused queries. - -``` -codegraph_context(task: "fix checkout validation bug", maxNodes: 20) -``` - -### `codegraph_search` - -Quick symbol search by name. Returns locations only. - -``` -codegraph_search(query: "UserService", kind: "class", limit: 10) -``` - -### `codegraph_callers` / `codegraph_callees` - -Find what calls a function, or what a function calls. - -``` -codegraph_callers(symbol: "validatePayment", limit: 20) -codegraph_callees(symbol: "processOrder", limit: 20) -``` - -### `codegraph_impact` - -Analyze what code would be affected by changing a symbol. - -``` -codegraph_impact(symbol: "UserService", depth: 2) -``` - -### `codegraph_node` - -Get details about a specific symbol. Use `includeCode: true` only when needed. - -``` -codegraph_node(symbol: "authenticate", includeCode: true) -``` - -### `codegraph_files` - -Get the project file structure from the index. Faster than filesystem scanning. - -``` -codegraph_files(path: "src/components", format: "tree", includeMetadata: true) -``` - -### `codegraph_status` - -Check index health and statistics. - -### How It Works With Claude Code - -Claude's **Explore agents** use these tools instead of grep/glob/Read for faster exploration: - -| Without CodeGraph | With CodeGraph | Benefit | -|-------------------|----------------|---------| -| `grep -r "auth"` | `codegraph_search("auth")` | Instant symbol lookup | -| Multiple `Read` calls | `codegraph_context(task)` | Related code in one call | -| Manual file tracing | `codegraph_callers/callees` | Call graph traversal | -| Guessing impact | `codegraph_impact(symbol)` | Know what breaks | -| `Glob`/`find` scanning | `codegraph_files(path)` | Indexed file structure | - -This gives Explore agents **~94% fewer tool calls** and **~77% faster exploration** while producing equally thorough answers. - -## ๐Ÿ“š Library Usage - -CodeGraph can also be used as a library in your Node.js applications: +## Library Usage ```typescript import CodeGraph from '@colbymchenry/codegraph'; -// Initialize a new project const cg = await CodeGraph.init('/path/to/project'); +// Or: const cg = await CodeGraph.open('/path/to/project'); -// Or open an existing one -const cg = await CodeGraph.open('/path/to/project'); - -// Index with progress callback await cg.indexAll({ - onProgress: (progress) => { - console.log(`${progress.phase}: ${progress.current}/${progress.total}`); - } + onProgress: (p) => console.log(`${p.phase}: ${p.current}/${p.total}`) }); -// Search for symbols const results = cg.searchNodes('UserService'); +const callers = cg.getCallers(results[0].node.id); +const context = await cg.buildContext('fix login bug', { maxNodes: 20, includeCode: true, format: 'markdown' }); +const impact = cg.getImpactRadius(results[0].node.id, 2); -// Get callers of a function -const node = results[0].node; -const callers = cg.getCallers(node.id); - -// Build context for a task -const context = await cg.buildContext('fix login bug', { - maxNodes: 20, - includeCode: true, - format: 'markdown' -}); - -// Get impact radius -const impact = cg.getImpactRadius(node.id, 2); - -// Sync changes manually -const syncResult = await cg.sync(); - -// Or watch for changes and auto-sync -cg.watch(); // uses native OS file events, debounced +cg.watch(); // auto-sync on file changes cg.unwatch(); // stop watching - -// Clean up cg.close(); ``` -## โš™๏ธ How It Works +--- -### 1. Extraction +## Configuration -CodeGraph uses [tree-sitter](https://tree-sitter.github.io/) to parse source code into ASTs. Language-specific queries (`.scm` files) extract: - -- **Nodes**: Functions, methods, classes, interfaces, types, variables -- **Edges**: Calls, imports, extends, implements, returns_type - -Each node gets a unique ID based on its kind, file path, name, and line number. - -### 2. Storage - -All data is stored in a local SQLite database (`.codegraph/codegraph.db`): - -- **nodes** table: All code entities with metadata -- **edges** table: Relationships between nodes -- **files** table: File tracking for incremental updates -- **unresolved_refs** table: References pending resolution -- **nodes_fts**: FTS5 virtual table for full-text search -- **schema_versions** table: Schema version tracking -- **project_metadata** table: Project-level key-value metadata - -### 3. Reference Resolution - -After extraction, CodeGraph resolves references: - -1. Match function calls to function definitions -2. Resolve imports to their source files -3. Link class inheritance and interface implementations -4. Apply framework-specific patterns (Express routes, etc.) - -### 4. File Watching - -The MCP server automatically watches your project for file changes using native OS file events (FSEvents on macOS, inotify on Linux, ReadDirectoryChangesW on Windows): - -1. File saves are detected instantly via OS-level events โ€” no polling -2. Changes are **debounced** (2-second quiet window) so rapid saves don't thrash -3. Only source files matching your include/exclude patterns trigger a sync -4. Build outputs, node_modules, and `.codegraph/` changes are ignored -5. Incremental sync runs automatically โ€” only changed files are re-parsed - -No configuration needed. The graph stays fresh as you code. - -### 5. Graph Queries - -The graph structure enables powerful queries: - -- **Callers/Callees**: Direct call relationships -- **Impact Radius**: BFS traversal to find all potentially affected code -- **Dependencies**: What a symbol depends on -- **Dependents**: What depends on a symbol - -### 6. Context Building - -When you request context for a task: - -1. FTS search finds relevant entry points -2. Graph traversal expands to related code -3. Code snippets are extracted -4. Results are formatted for AI consumption - -## โš™๏ธ Configuration - -The `.codegraph/config.json` file controls indexing behavior: +The `.codegraph/config.json` file controls indexing: ```json { "version": 1, "languages": ["typescript", "javascript"], - "exclude": [ - "node_modules/**", - "dist/**", - "build/**", - "*.min.js" - ], + "exclude": ["node_modules/**", "dist/**", "build/**", "*.min.js"], "frameworks": [], "maxFileSize": 1048576, "extractDocstrings": true, @@ -681,18 +369,16 @@ The `.codegraph/config.json` file controls indexing behavior: } ``` -### Options - | Option | Description | Default | |--------|-------------|---------| | `languages` | Languages to index (auto-detected if empty) | `[]` | | `exclude` | Glob patterns to ignore | `["node_modules/**", ...]` | | `frameworks` | Framework hints for better resolution | `[]` | | `maxFileSize` | Skip files larger than this (bytes) | `1048576` (1MB) | -| `extractDocstrings` | Whether to extract docstrings from code | `true` | -| `trackCallSites` | Whether to track call site locations | `true` | +| `extractDocstrings` | Extract docstrings from code | `true` | +| `trackCallSites` | Track call site locations | `true` | -## ๐ŸŒ Supported Languages +## Supported Languages | Language | Extension | Status | |----------|-----------|--------| @@ -714,33 +400,17 @@ The `.codegraph/config.json` file controls indexing behavior: | Liquid | `.liquid` | Full support | | Pascal / Delphi | `.pas`, `.dpr`, `.dpk`, `.lpr` | Full support (classes, records, interfaces, enums, DFM/FMX form files) | -## ๐Ÿ”ง Troubleshooting +## Troubleshooting -### "CodeGraph not initialized" +**"CodeGraph not initialized"** โ€” Run `codegraph init` in your project directory first. -Run `codegraph init` in your project directory first. +**Indexing is slow** โ€” Check that `node_modules` and other large directories are excluded. Use `--quiet` to reduce output overhead. -### Indexing is slow +**MCP server not connecting** โ€” Ensure the project is initialized/indexed, verify the path in your MCP config, and check that `codegraph serve --mcp` works from the command line. -- Check if `node_modules` or other large directories are excluded -- Use `--quiet` flag to reduce console output overhead -- Consider increasing `maxFileSize` if you have large files to skip +**Missing symbols** โ€” The MCP server auto-syncs on save (wait a couple seconds). Run `codegraph sync` manually if needed. Check that the file's language is supported and isn't excluded by config patterns. -### MCP server not connecting - -1. Ensure the project is initialized and indexed -2. Check the path in your MCP configuration is correct -3. Verify `codegraph serve --mcp` works from the command line -4. Check Claude Code logs for connection errors - -### Missing symbols in search - -- The MCP server auto-syncs on file changes โ€” wait a couple seconds after saving -- Run `codegraph sync` manually if needed -- Check if the file's language is supported -- Verify the file isn't excluded by config patterns - -## ๐Ÿ“„ License +## License MIT @@ -748,7 +418,7 @@ MIT
-**Made for the Claude Code community** ๐Ÿค– +**Made for the Claude Code community** [Report Bug](https://github.com/colbymchenry/codegraph/issues) ยท [Request Feature](https://github.com/colbymchenry/codegraph/issues) diff --git a/src/bin/codegraph.ts b/src/bin/codegraph.ts index eb508b8..d118a1f 100644 --- a/src/bin/codegraph.ts +++ b/src/bin/codegraph.ts @@ -16,18 +16,12 @@ * codegraph files [options] Show project file structure * codegraph context Build context for a task * codegraph affected [files] Find test files affected by changes - * codegraph mark-dirty [path] Mark project as needing sync (hooks) - * codegraph sync-if-dirty [path] Sync if marked dirty (hooks) - * - * Note: Git hooks have been removed. CodeGraph sync is triggered automatically - * through codegraph's Claude Code hooks integration. */ import { Command } from 'commander'; import * as path from 'path'; import * as fs from 'fs'; -import { spawn } from 'child_process'; -import { getCodeGraphDir, findNearestCodeGraphRoot, isInitialized } from '../directory'; +import { getCodeGraphDir, isInitialized } from '../directory'; import { createShimmerProgress } from '../ui/shimmer-progress'; // Lazy-load heavy modules (CodeGraph, runInstaller) to keep CLI startup fast. @@ -1078,88 +1072,6 @@ program } }); -/** - * codegraph mark-dirty [path] - * - * Touches .codegraph/.dirty to signal that files have changed. - * Used by Claude Code PostToolUse hooks to batch syncs. - * Runs silently and always exits 0. - */ -program - .command('mark-dirty [path]') - .description('Mark project as needing sync (used by Claude Code hooks)') - .action(async (pathArg: string | undefined) => { - try { - const startPath = path.resolve(pathArg || process.cwd()); - const projectRoot = findNearestCodeGraphRoot(startPath); - if (!projectRoot) { - // No .codegraph/ found โ€” exit silently - process.exit(0); - } - const dirtyPath = path.join(getCodeGraphDir(projectRoot), '.dirty'); - fs.writeFileSync(dirtyPath, Date.now().toString(), 'utf-8'); - } catch { - // Never fail โ€” this runs in the background during edits - } - process.exit(0); - }); - -/** - * codegraph sync-if-dirty [path] - * - * Checks if .codegraph/.dirty exists and, if so, spawns a detached - * background process to run `codegraph sync`. The hook process exits - * immediately so Claude Code's Stop hook never blocks. - * - * Removes the marker BEFORE spawning so edits during sync - * create a new marker for the next Stop event. - * Runs silently and always exits 0. - */ -program - .command('sync-if-dirty [path]') - .description('Sync if project was marked dirty (used by Claude Code hooks)') - .action(async (pathArg: string | undefined) => { - try { - const startPath = path.resolve(pathArg || process.cwd()); - const projectRoot = findNearestCodeGraphRoot(startPath); - if (!projectRoot) { - process.exit(0); - } - const dirtyPath = path.join(getCodeGraphDir(projectRoot!), '.dirty'); - - // No marker โ†’ nothing to do (sub-ms exit) - if (!fs.existsSync(dirtyPath)) { - process.exit(0); - } - - // Remove marker FIRST so edits during sync create a new one - try { fs.unlinkSync(dirtyPath); } catch { /* ignore */ } - - // If not fully initialized (no DB), exit - if (!isInitialized(projectRoot!)) { - process.exit(0); - } - - // Spawn sync as a detached background process - // so this hook exits immediately and doesn't block Claude Code. - // Uses process.argv[0]/[1] (e.g. node /path/to/codegraph.js) so it - // works whether invoked via global install, npx, or directly. - const child = spawn( - process.argv[0]!, - [process.argv[1]!, 'sync', '--quiet', projectRoot!], - { - detached: true, - stdio: 'ignore', - windowsHide: true, - } - ); - child.unref(); - } catch { - // Never fail โ€” this runs at the end of Claude responses - } - process.exit(0); - }); - /** * codegraph unlock [path] */ diff --git a/src/bin/uninstall.ts b/src/bin/uninstall.ts index 8ae3d13..4344a04 100644 --- a/src/bin/uninstall.ts +++ b/src/bin/uninstall.ts @@ -6,7 +6,6 @@ * Removes all CodeGraph configuration from Claude Code: * - MCP server entry from ~/.claude.json * - Permissions from ~/.claude/settings.json - * - Hooks from ~/.claude/settings.json * - CodeGraph section from ~/.claude/CLAUDE.md * * This script must never throw โ€” a failed cleanup must not block uninstall. @@ -51,22 +50,20 @@ function removeMcpConfig(): void { } /** - * Remove CodeGraph permissions and hooks from ~/.claude/settings.json + * Remove CodeGraph permissions from ~/.claude/settings.json */ function removeSettings(): void { const filePath = path.join(os.homedir(), '.claude', 'settings.json'); const settings = readJson(filePath); if (!settings) return; - let changed = false; - // Remove codegraph permissions if (Array.isArray(settings.permissions?.allow)) { const before = settings.permissions.allow.length; settings.permissions.allow = settings.permissions.allow.filter( (p: string) => !p.startsWith('mcp__codegraph__') ); - if (settings.permissions.allow.length !== before) changed = true; + if (settings.permissions.allow.length === before) return; // Clean up empty allow array if (settings.permissions.allow.length === 0) { @@ -76,33 +73,7 @@ function removeSettings(): void { if (Object.keys(settings.permissions).length === 0) { delete settings.permissions; } - } - // Remove codegraph hooks - if (settings.hooks) { - for (const event of Object.keys(settings.hooks)) { - if (!Array.isArray(settings.hooks[event])) continue; - - const before = settings.hooks[event].length; - settings.hooks[event] = settings.hooks[event].filter((entry: any) => { - const json = JSON.stringify(entry); - return !json.includes('codegraph mark-dirty') && !json.includes('codegraph sync-if-dirty'); - }); - if (settings.hooks[event].length !== before) changed = true; - - // Clean up empty event arrays - if (settings.hooks[event].length === 0) { - delete settings.hooks[event]; - } - } - - // Clean up empty hooks object - if (Object.keys(settings.hooks).length === 0) { - delete settings.hooks; - } - } - - if (changed) { writeJson(filePath, settings); } } diff --git a/src/installer/config-writer.ts b/src/installer/config-writer.ts index b0bf19a..5e01990 100644 --- a/src/installer/config-writer.ts +++ b/src/installer/config-writer.ts @@ -192,94 +192,6 @@ export function hasPermissions(location: InstallLocation): boolean { return permissions.some((p: string) => p.startsWith('mcp__codegraph__')); } -// ============================================================================= -// Hooks Configuration -// ============================================================================= - -/** - * Get the hooks configuration for Claude Code auto-sync. - * - * PostToolUse(Edit|Write) โ†’ mark-dirty (async, non-blocking) - * Stop โ†’ sync-if-dirty (sync, ensures fresh index before next user turn) - */ -function getHooksConfig(): Record { - const command = 'codegraph'; - - return { - PostToolUse: [ - { - matcher: 'Edit|Write', - hooks: [ - { - type: 'command', - command: `${command} mark-dirty`, - async: true, - }, - ], - }, - ], - Stop: [ - { - matcher: '.*', - hooks: [ - { - type: 'command', - command: `${command} sync-if-dirty`, - }, - ], - }, - ], - }; -} - -/** - * Check if Claude Code hooks already exist for CodeGraph - */ -export function hasHooks(location: InstallLocation): boolean { - const settingsPath = getSettingsJsonPath(location); - const settings = readJsonFile(settingsPath); - const hooks = settings.hooks; - if (!hooks) return false; - - // Check if any hook command references codegraph - const json = JSON.stringify(hooks); - return json.includes('codegraph mark-dirty') || json.includes('codegraph sync-if-dirty'); -} - -/** - * Write Claude Code hooks to settings.json for auto-sync. - * Merges with existing hooks, deduplicating any previous codegraph entries. - */ -export function writeHooks(location: InstallLocation): void { - const settingsPath = getSettingsJsonPath(location); - const settings = readJsonFile(settingsPath); - - if (!settings.hooks) { - settings.hooks = {}; - } - - const newHooks = getHooksConfig(); - - // For each hook event (PostToolUse, Stop), merge with existing entries - for (const [event, newEntries] of Object.entries(newHooks)) { - if (!Array.isArray(settings.hooks[event])) { - settings.hooks[event] = []; - } - - // Remove any existing codegraph entries for this event - settings.hooks[event] = (settings.hooks[event] as any[]).filter((entry: any) => { - // Keep entries that don't reference codegraph - const entryJson = JSON.stringify(entry); - return !entryJson.includes('codegraph mark-dirty') && !entryJson.includes('codegraph sync-if-dirty'); - }); - - // Add new codegraph entries - settings.hooks[event].push(...(newEntries as any[])); - } - - writeJsonFile(settingsPath, settings); -} - /** * Get the path to CLAUDE.md * - Global: ~/.claude/CLAUDE.md diff --git a/src/installer/index.ts b/src/installer/index.ts index 0e58d21..7d01af9 100644 --- a/src/installer/index.ts +++ b/src/installer/index.ts @@ -8,8 +8,8 @@ import { execSync } from 'child_process'; import * as path from 'path'; import * as fs from 'fs'; import { - writeMcpConfig, writePermissions, writeClaudeMd, writeHooks, - hasMcpConfig, hasPermissions, hasHooks, + writeMcpConfig, writePermissions, writeClaudeMd, + hasMcpConfig, hasPermissions, } from './config-writer'; import type { InstallLocation } from './config-writer'; @@ -50,7 +50,7 @@ export async function runInstaller(): Promise { // Step 1: Install globally const shouldInstallGlobally = await clack.confirm({ - message: 'Install codegraph globally? (Required for hooks & MCP server)', + message: 'Install codegraph globally? (Required for MCP server)', initialValue: true, }); @@ -70,7 +70,7 @@ export async function runInstaller(): Promise { clack.log.warn('Try: sudo npm install -g @colbymchenry/codegraph'); } } else { - clack.log.info('Skipped global install โ€” hooks and MCP server may not work without it'); + clack.log.info('Skipped global install โ€” MCP server may not work without it'); } // Step 2: Installation location @@ -140,11 +140,6 @@ function writeConfigs( clack.log.success(`${permAction} permissions in ${locationLabel}/settings.json`); } - // Hooks - const hookAction = hasHooks(location) ? 'Updated' : 'Added'; - writeHooks(location); - clack.log.success(`${hookAction} auto-sync hooks in ${locationLabel}/settings.json`); - // CLAUDE.md const claudeMdResult = writeClaudeMd(location); const claudeMdPath = `${locationLabel}/CLAUDE.md`;