Testing showed semantic search produces significantly better results for
natural language queries that Claude writes. FTS alone often ranks
properties above their parent classes and misses conceptual matches.
Embeddings are now always on — the vector manager is created eagerly,
with model download and embedding generation still happening lazily.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Eliminates anonymous error reporting functionality that was collecting stack traces and error context via Sentry. Removes all telemetry-related code, configuration options, and documentation references.
Name matching was creating false `calls` edges between unrelated modules
in monorepos because `findBestMatch()` had no concept of directory
proximity — functions with common names (e.g. `navigate`) in different
apps scored identically and resolved to whichever came first.
Adds path proximity scoring (shared directory segments) so same-module
candidates strongly win over cross-boundary ones, and lowers confidence
for distant matches so import-based resolution takes precedence.
Closes#67
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sentry error reporting can now be disabled by:
1. Declining during the interactive installer (sets CODEGRAPH_TELEMETRY=off
in the MCP server config env)
2. Setting CODEGRAPH_TELEMETRY=off in your shell environment
README updated with a Telemetry section documenting what is collected
and how to opt out.
Closes#68
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The installer previously ran `npm install -g` silently without user
consent. Now it asks for confirmation first, explains why the global
install is needed (hooks & MCP server), and gracefully skips if declined.
README updated to document this step.
Closes#69
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
extractSearchTerms now splits camelCase, PascalCase, snake_case, and
dot.notation into individual tokens (e.g. "getUserName" → ["user", "name"]).
Stop words expanded with code-specific noise words (code, file, function,
method, class, type, etc.) to improve search precision.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
AI picking the entry point was unreliable. Now:
- Type a symbol name → dropdown shows matches
- Click a result (or Enter to pick first) → traces its call graph depth 3
- The user picks the starting point, the graph does the rest deterministically
No more AI guesswork. Search + graph traversal = reliable flows.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Completely reworked the explore approach:
- Claude (or keyword search) finds ONE entry point, not a list of symbols
- getCallGraph(entry, depth=3) traces the actual call chain deterministically
- No more AI-guessed symbol lists, bridge passes, or relevance filtering
- Search result clicks also trace the full call graph from that point
The graph data was always accurate — the problem was AI trying to guess
the whole flow. Now AI just finds the starting point, graph does the rest.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Stricter prompt rules: only symbols directly in the execution path,
every symbol must call or be called by the next, no tangential features.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update Claude prompt to identify the entry point and return symbols in
execution order. The graph now centers on the entry point and auto-opens
its detail panel, giving users a clear starting point to trace the flow.
- Claude returns {entry, flow} instead of flat array
- Entry point is auto-selected and centered on load
- Detail panel opens immediately for the entry point
- Prompt asks for max 8-10 symbols in execution order
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of expanding all callers/callees of seeds (which pulls in noise
from hub nodes like getSession), now:
1. Find direct edges between Claude's seeds
2. Only add non-seed nodes if they bridge 2+ isolated seeds
3. Cross-connection pass discovers hidden edges between result nodes
4. No more unrelated callers of hub nodes polluting the graph
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds `codegraph visualize` command that launches a localhost web UI for
visually exploring code relationships. Users can ask natural language
questions like "how does authentication work?" and see the relevant code
flow rendered as an interactive graph.
Key components:
- Visualizer HTTP server (src/visualizer/server.ts) with REST API
- Single-page frontend with Cytoscape.js graph + highlight.js code preview
- Claude CLI integration for intelligent query interpretation
- Dark theme, right-click context menus, keyboard shortcuts
- Detail panel with source code, callers, callees, hierarchy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Traverses dependency graph to identify which test files depend on changed source files. Supports stdin input for git integration, custom test file patterns, and configurable traversal depth. Useful for targeted test execution in CI/CD pipelines.
Fixes#47 — "database is locked" after crash and MCP "not initialized"
when project IS initialized.
- FileLock: treat locks older than 10 minutes as stale regardless of PID
status, covering cases where PID was reused or kill signal check fails
- MCP server: log errors from tryInitializeDefault() to stderr instead of
silently swallowing, so transient open failures are diagnosable
- MCP server: retryInitIfNeeded() properly cleans up failed instances
before retrying, preventing resource leaks
- CLI: add 'codegraph unlock' command for manual lock file removal
Fixes#42 — tree-sitter can produce nodes with empty names (e.g. from
complex C/C++ declarators in header files). These nodes were silently
skipped at DB insert time, but their containment edges were still
inserted, causing a FOREIGN KEY constraint violation that crashed
indexing.
Two-layer fix:
- createNode() now returns null for empty names, preventing the node
and its edges from ever being created (Option A)
- storeExtractionResult() filters edges and unresolved refs to only
reference nodes that passed validation, as a safety net (Option B)
Fixes#54 — `codegraph init -i` crashes with "Fatal process out of memory: Zone"
on large codebases because all 16 tree-sitter WASM grammar modules were compiled
upfront by V8, exhausting the WASM Zone allocator.
Changes:
- initGrammars() now only initializes the tree-sitter WASM runtime (Parser.init()),
no longer eagerly loads all grammar files
- New loadGrammarsForLanguages() loads only grammars for languages actually present
in the project (e.g. a Dart project loads ~2-3 grammars instead of 16)
- Orchestrator detects needed languages after file scan, before parsing begins
- Embedding pipeline now uses quantized model (~67MB vs ~270MB) to further reduce
WASM memory pressure when embeddings are enabled
The serve command without --mcp prints a help banner. Writing this to
stdout breaks MCP stdio clients (like Cursor) that expect only JSON-RPC
on stdout. Move all banner output to stderr so stdout stays clean.
Fixes#43
Bumps version to 0.6.2 in both package.json and lockfile to align release metadata and prevent silent install failures on fresh installs.
Relates to silent install fix
command -v codegraph is unreliable inside npx because npx puts a
temporary binary in PATH. The check always passes, so the global
install is always skipped — which is the root cause of #37 and #38.
Fix: remove the check entirely, always run npm install -g.
- Revert configs (MCP, hooks) to use bare `codegraph` command
- Remove all npx references from configs and messaging
- Add preuninstall script that runs on `npm uninstall -g` to clean up
MCP server, permissions, hooks, and CLAUDE.md section
- Show uninstall instructions in post-install next steps
Global install is still attempted for bare `codegraph` convenience,
but now verifies the command is actually in PATH after install. If it
fails, users get clear actionable messages instead of silent swallowing.
Configs (MCP server, hooks) always use npx regardless — those never
break even if global install fails.
Remove the npm install -g attempt from the installer that silently
fails on many systems (permissions, PATH, node version managers).
All configs (MCP server, hooks, next-steps) now always use
npx @colbymchenry/codegraph. Global install offered as an optional tip.
Fixes#37, #38
- Fix defProc method lookup collisions when multiple classes share
method names (e.g. Create) by indexing qualified forms
- Remove overly broad 'Id' prefix filter that swallowed user-defined
symbols like Identifier or IdleTimer
- Use case-insensitive extension matching for DFM/FMX routing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integrate main branch changes (WASM grammar architecture, centralized
resolution caches, SQLite adapter) with delphi-support branch. Pascal
grammar is now built as WASM and shipped in src/extraction/wasm/ for
consistency with the WASM-based grammar loading approach.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
web-tree-sitter has a known race condition when loading multiple WASM
grammars concurrently on Node.js 19+ (V8 10.8+). External scanner
symbols from one grammar can overwrite another's GOT entries, causing
"bad export type" errors for TypeScript, TSX, and other languages.
Replace Promise.allSettled(entries.map(...)) with a sequential for...of
loop so each grammar fully initializes before the next one starts.
Ref: https://github.com/tree-sitter/tree-sitter/issues/2338
Replace native tree-sitter with web-tree-sitter + tree-sitter-wasms for
universal cross-platform support. Add node-sqlite3-wasm as a fallback
when better-sqlite3 native bindings aren't available. Move better-sqlite3
and sqlite-vss to optionalDependencies so installs never fail.
Fix installer to use npx fallback when global npm install fails, so MCP
config, hooks, and quick-start instructions all work without the bare
codegraph command in PATH.
Fix tests: update schema version expectation, fix db test paths and
method names, extract MAX_OUTPUT_LENGTH as module constant, normalize
Windows path separators in import resolver.
Two major optimizations for the ref resolution phase:
1. Cache extractImportMappings() results per file path — previously
re-read and re-parsed the source file for every single ref from
that file (e.g. 100 refs from one file = 100 identical file reads)
2. Replace linear scan in matchFuzzy() with a lazily-built
case-insensitive Map index — O(1) lookup instead of iterating
all function/method/class nodes for every unresolved ref.
Also drop low-value prefix matching (confidence 0.3).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>