# Changelog ## [Unreleased] ## [2.3.6] - 2026-06-10 **Community-response release.** Built from a full audit of every open PR, issue, and discussion: community fixes merged with credit, verified defects fixed (including two open Windows bugs), benchmark claims made independently checkable, and the project's first self-hosted PR review bot — this repo now reviews its own pull requests with its own graph. No breaking changes. ### Added - **Custom languages without forking** (#320): drop a `.code-review-graph/languages.toml` into your repo to index any grammar shipped by tree-sitter-language-pack (extension map + node-type lists, validated and capped, built-ins always win). See docs/CUSTOM_LANGUAGES.md. - **GitHub Action** for risk-scored PR review comments: composite `action.yml` builds/restores the graph from CI cache, runs `detect-changes` against the PR base, and upserts a sticky comment with risk table, affected flows, test gaps, and the Token Savings line. Dogfooded on this repo via `.github/workflows/pr-review.yml`. See docs/GITHUB_ACTION.md. - **`agent_baseline` eval benchmark**: compares graph queries against a realistic grep-and-read-top-k agent baseline instead of the whole-corpus strawman; wired into all six pinned eval configs. - **Co-change ground truth for `impact_accuracy`**: predictions are now also graded against files actually co-changed in the same commit; the legacy metric is explicitly labelled "graph-derived (circular — upper bound)". - **Weekly eval CI** (`.github/workflows/eval.yml`): report-only cron run of the two smallest pinned configs with CSV artifacts and a job summary. - **docs/FAQ.md**: how CRG compares to LSP, RAG, grep/agentic search, and adjacent tools; when NOT to use it; verification steps; monorepo/worktree and registry guidance. Linked from the README. - GitHub issue forms (bug/feature/platform), a PR template mirroring the CONTRIBUTING checklist, and dependabot config for pip + GitHub Actions. ### Fixed - `store_file_batch` is now guarded against open transactions like its sibling (#489, merged from community PR #529 by @Devilthelegend — thank you). - **Windows: `daemon status` no longer crashes with WinError 87** (#511): PID liveness now uses `OpenProcess`/`WaitForSingleObject` on win32 instead of `os.kill(pid, 0)`. - **Windows: CLI `detect-changes` mapped 0 functions** (#528): diff paths are now remapped to absolute native paths before node lookup, matching the MCP tool's behavior; also prevents the misleading "~100% token savings" line on an empty result. - Eval benchmarks no longer record failed runs as inflated wins: thrown `get_review_context`/`analyze_changes` calls are marked `status=error` and excluded from aggregates instead of producing naive/1 ratios or recall=1.0. - Unknown embedding provider names now raise a clear error listing valid providers instead of silently falling back to the local model. - The five analysis MCP tools and the wiki-page tool no longer leak SQLite connections (try/finally `store.close()`). - `install` git hooks now resolve the real hooks directory via `git rev-parse --git-path hooks`, so linked worktrees and `core.hooksPath` (husky) setups get a working pre-commit hook (#313 residue). - Shipped `hooks/hooks.json` and `hooks/session-start.sh` now drain stdin, matching the generated configs (#493 class). - `fastmcp` is now capped `<4` so the next major cannot silently break the server (the #488 failure mode). ### Changed - README benchmarks section now leads with the ~82x median per-question reduction (528x presented as the best case, not the headline), the limitations block is visible instead of collapsed, and "100% impact recall" is reframed as a graph-derived upper bound alongside the new co-change metric. - Stale translated READMEs (zh-CN, ja-JP, ko-KR, hi-IN) carry a staleness banner; the zh-CN benchmark captions and docs/USAGE.md no longer contradict the English README. - SECURITY.md now points to GitHub private vulnerability reporting as the canonical channel. ## [2.3.5] - 2026-05-25 **Real-time token savings, visible to humans.** The estimated context-savings metric introduced in 2.3.4 was JSON-only. In 2.3.5 it surfaces as a clean boxed panel on the CLI and is verifiable against a real tokenizer in one flag — so when you reach for `code-review-graph` to review a change, you can immediately *see* how much of your context window the graph just kept out. No breaking changes. ### Added — Token Savings (headline feature) - **Boxed `Token Savings` panel on every `--brief` CLI call.** Both `code-review-graph detect-changes --brief` and the new `code-review-graph update --brief` print a four-line panel: the full-context baseline, the graph response size, total saved tokens with percent, and a per-category breakdown (Functions / Tests / Risk / Other) that **sums exactly** to the graph response size — no padding, no rounding magic. ```text ┌─────────────────────── Token Savings ────────────────────────┐ │ Full context would be: 12,921 tokens │ │ Graph context used: 762 tokens │ │ Saved: 12,159 tokens (~94%) │ │ Breakdown: Functions 244 · Tests 191 · Risk 244 · Other 83 │ └──────────────────────────────────────────────────────────────┘ ``` - **`--verify` flag** cross-checks the displayed numbers against OpenAI's `cl100k_base` tokenizer (the GPT-4 family). Adds a second `Verified (tiktoken)` row to the panel showing the real token counts. Requires `pip install tiktoken`. A one-time calibration across 222 mixed source files (Python/JS/TS/Go/Rust/RST/MD) committed in `docs/REPRODUCING.md` shows the `chars/4` approximation stays within **+0.5%** of real tokens in aggregate; per-repo bias is bounded to ±12% and the **ratio** stays stable because both sides of the divide are equally biased. - **`code-review-graph update --brief`** — incremental update plus the same risk + Token Savings panel in one command. Distinct from `detect-changes --brief` (which is read-only against the existing graph). Use `update --brief` when the graph might be stale (post-rebase, large change set); use `detect-changes --brief` when hooks/`crg-daemon` have already kept the graph fresh. ### Added — Reproducible benchmarks - **`docs/REPRODUCING.md`** — end-to-end reproduction recipe with canonical numbers, the tiktoken calibration table, and an explicit explanation of the three different "token" benchmarks in the codebase and what each measures. Two people running the recipe on different machines on different days now produce **identical** numbers, within float rounding. - **`multi_hop_retrieval` benchmark** — 11 hand-curated 2-step tool-chain tasks (semantic_search → query_graph) across the 6 test repos. Average score **0.909**. Per-task CSV in `evaluate/results/`. - **`code-review-graph embed` CLI subcommand** — explicit shell-level access to embedding generation. Previously only reachable via MCP, which made the benchmark recipe awkward. ### Changed — Deterministic eval pipeline - **Every config under `code_review_graph/eval/configs/*.yaml` now pins an upstream SHA.** Previously every config used `commit: HEAD`, which made benchmarks drift whenever upstream pushed. Pinned SHAs: express `b4ab7d65`, fastapi `0227991a`, flask `a29f88ce`, gin `5c00df8a`, httpx `b55d4635`, code-review-graph `84bde354`. - **`nextjs.yaml` renamed to `code-review-graph.yaml`.** The historical "nextjs" entry pointed at this repo, not a Next.js codebase. Renamed to match reality. - **`eval/runner.py` uses full clones with explicit `returncode` checks.** Previously `--depth 50` silently fell back to `HEAD~1..HEAD` whenever a pinned test-commit SHA was past the shallow window, producing benchmark numbers tied to whichever HEAD the clone happened to grab. - **Leiden community detection seeded** (`CRG_LEIDEN_SEED`, default `42`). Previously unseeded — community IDs and sizes drifted run-to-run on the same graph, breaking benchmark comparability. - **`eval/runner.py` resolves repo paths absolutely before storing.** The parser previously stored file_path as the path you passed in, so eval builds and CLI/MCP builds could disagree, producing duplicate nodes for the same source location. Fixed by `.resolve()` in the runner. - **`eval/runner.py` calls `run_post_processing` after `full_build`.** Previously the eval framework left FTS5 unpopulated (shadow tables `nodes_fts_idx` and `nodes_fts_docsize` empty), so downstream search and multi-hop benchmarks silently returned no results. ### Changed — Search and embeddings - **`embeddings._node_to_text` is richer.** Embedded text per node now includes the dotted form (`Parent.name`, e.g. `APIRoute.get_route_handler`), the identifier split into words (`get route handler`), and the enclosing module directory (`routing`, `dependencies`). Forces an automatic re-embedding because the text hash changes. Lifts multi-hop benchmark accuracy from **0.545 → 0.818**. - **Identifier-aware search boost** (`search.extract_query_identifiers`). Natural-language queries like *"Who advances the gin middleware chain via Context.Next"* now have their dotted / snake_case / CamelCase tokens extracted and used to boost matching qualified-names by 2.0× in hybrid search. Combined with the richer embed text, multi-hop accuracy reaches **0.909** (10 of 11 tasks pass). ### Fixed - **Test-gap dedup in the brief summary.** If duplicate `qualified_names` ever slip into the graph (e.g. after a path-normalization mismatch), the `Untested:` line in the human summary now collapses to unique names. The underlying `test_gaps` list still carries every entry. - **`token_benchmark.py` warns when embeddings are missing.** The standalone benchmark's default NL questions need semantic search to match anything; without embeddings the benchmark used to silently report 0× reduction ratios. Now logs an explicit warning pointing users to `embed`. ### Documentation - **`docs/REPRODUCING.md`** (new). End-to-end recipe, canonical numbers, the tiktoken calibration table, and a side-by-side explanation of the three "token" benchmarks in the codebase. - **`README.md` Token Savings section** (new collapsible block under Usage). Plain-English explanation of `detect-changes --brief` vs `update --brief` — read-only vs re-parses-first — with a side-by-side decision table. - **`docs/COMMANDS.md`** lists the new `--brief`, `--verify`, and `embed` forms with an inline "which one?" comment block on the analysis pair. - **Updated benchmark headline** to reflect today's pinned-SHA snapshot: range **38× – 528×** (median ~82×) across the 6 repos, **100% impact recall**, **F1 0.71** across 13 commits. Old numbers (73× – 895×) reflected pre-fix conditions (leftover build artifacts, smaller graph responses) and have been superseded. - **9 Excalidraw diagrams** regenerated with current canonical numbers (`diagrams/*.excalidraw`, source kept locally; PNG re-exports manual). ### Demo - **`diagrams/context-savings-demo.gif`** — 44 s screencast showing both CLI surfaces and the `--verify` cross-check. Rendered from `diagrams/context-savings-demo.tape` (regenerable with `vhs`). ## [2.3.4] - 2026-05-25 Focused reliability and token-efficiency release for MCP/CLI review workflows. No breaking changes. ### Added - **Estimated context savings metadata** for graph-filtered review/impact/architecture responses. The new `context_savings` field is intentionally compact (`estimated`, `saved_tokens`, `saved_percent`) and uses the existing conservative character-count approximation rather than claiming exact tokenization. - **CLI estimated savings line** for `code-review-graph detect-changes --brief`; full JSON output includes the same compact `context_savings` metadata. ### Changed - **Architecture overview is compact by default**: `get_architecture_overview_tool` now defaults to `detail_level="minimal"`, dropping per-community member lists and aggregating cross-community edges by community pair. Full per-edge output remains available with `detail_level="standard"`. - **Bounded change analysis**: `detect_changes_tool` can now cap very large changed-function and transitive-test frontiers with `CRG_MAX_CHANGED_FUNCS` and `CRG_MAX_TRANSITIVE_FRONTIER`, and can return a structured timeout error via `CRG_TOOL_TIMEOUT`. ### Fixed - **Windows semantic search deadlock** (#508/#507): local embedding models are pre-warmed on the main thread on Windows before FastMCP starts worker dispatch. - **Rust test detection** (#503/#502): Rust `#[test]` and common async test attributes now produce `Test` nodes. - **Generated hook stdin handling** (#494/#493): Codex and Claude hook commands drain stdin to avoid caller-side broken pipes on large hook payloads. - **Cross-file callers** (#486/#472): `callers_of` now returns cross-file callers even when same-file callers exist. - **Graph path lookup** (#469): review, impact, and file-summary tools resolve user-facing paths to the path format stored in the graph. - **Bundled MCP docs** (#485/#480): `get_docs_section` can load the packaged `LLM-OPTIMIZED-REFERENCE.md` from installed wheels. - **Local embedding provider availability** (#484/#448): missing `sentence-transformers` now reports local provider unavailability instead of silently producing zero embeddings. - **Dead-code response fields** (#481/#447): dead-code results now include `file_path`, `relative_path`, and `language` while preserving the legacy `file` key. - **SVN root validation** (#456): MCP/daemon/registry root validation now accepts `.svn` working copies consistently. - **CLI postprocess flags** (#487): `build --skip-postprocess` and `update --skip-flows` no longer run an extra full post-processing pass. ### Documentation - Updated stale release-facing version references for 2.3.4. - Replaced fragile language-count wording with current broad language and notebook support wording. - Added the missing VS Code extension `0.2.2` changelog entry without changing the extension package version. ### Tests - Added regression coverage for compact architecture overview output and #476 mitigation. - Added tests for estimated context savings calculation, compact metadata shape, MCP metadata, CLI brief/JSON output, Rust test parsing, hook stdin draining, graph path resolution, dead-code fields, SVN root validation, CLI postprocess flags, embedding availability, and bounded detect-changes behavior. ## [2.3.3] - 2026-05-08 Large additive release accumulated since v2.3.2 — 141 non-merge commits, 8 new languages/extensions, 5 new platform install targets, 6 new framework call resolvers, comprehensive Windows hardening, VS Code accessibility pass, and a full sweep of community PRs. ### Added #### Languages and extensions - **Nix support** (flake-aware): `.nix` files are parsed via the `nix` tree-sitter grammar shipped with `tree-sitter-language-pack`. Top-level and nested attrset bindings become `Function` nodes with flattened dotted names (e.g. `packages.default`, `devShells.default`). In `flake.nix`, `inputs..url = "..."` strings emit `IMPORTS_FROM` edges to the URL; `import ` and `callPackage ` applications in any `.nix` file emit `IMPORTS_FROM` edges (relative paths are resolved against the caller's directory). Adds 7 tests (`TestNixParsing`) and fixtures `tests/fixtures/sample.nix`, `tests/fixtures/sample_module.nix`. - **GDScript support** (Godot, PR #316): `.gd` files are parsed via the `gdscript` tree-sitter grammar. Extracts inner classes (`class Name:`), the file-level `class_name` identity, functions (including `static func`), `extends` parent class as an IMPORTS_FROM edge, direct calls and method calls. Adds 10 tests and `tests/fixtures/sample.gd`. - **Verilog / SystemVerilog support** (PR #428): `.v`, `.sv`, `.svh` files parse modules, classes, packages, interfaces, programs, functions, and tasks via the `verilog` tree-sitter grammar. Per-construct extractors with dedicated unit tests. - **SQL support** (PR #398): `.sql` files parse `CREATE FUNCTION`, `CREATE PROCEDURE`, `CREATE TABLE`, and `CREATE VIEW` statements; emits CALLS edges for function invocations. - **ReScript support** (PR #309/323): `.res`/`.resi` parsing for modules, let-bindings, and external declarations. - **`.hh` extension support**: C++ header variants now resolve into the C++ parser path. - **`.ksh` extension and shebang-based detection** (PR #276): `.ksh` files parsed as shell; extension-less scripts detected via `#!/usr/bin/env ` shebang lines. - **Julia improvements**: parametric constructors, `@enum` declarations, and `public` module exports now produce graph nodes. #### Platforms and install targets - **GitHub Copilot platform support** (PR #445): `code-review-graph install --platform copilot` writes Copilot-CLI-compatible MCP config without generating Claude-specific skill artifacts. - **Gemini CLI platform support** (PR #391): `--platform gemini-cli` skips Claude skills and writes Gemini-native MCP config. - **Qoder platform support** (PR #245): `--platform qoder` adds MCP server registration for Qoder. - **OpenCode plugin support** (PR #198 via #366): `--platform opencode` registers the MCP server with the OpenCode plugin manifest. - **Cursor hooks support** (PR #196): `install` now writes Cursor hook entries (gated behind `~/.cursor` detection so non-Cursor users are not affected). - **Codex install alignment**: native Codex integration path; no Claude skill files generated for Codex targets. #### MCP server and CLI features - **`crg-daemon`**: new multi-repo watch daemon that supervises per-repo file watchers via `subprocess.Popen` child processes. Documented in README, COMMANDS.md, and ROADMAP.md. 35 dedicated tests. - **Streamable HTTP transport** (PR #277): MCP server can now run over streamable HTTP in addition to stdio. - **`serve --tools` flag and `CRG_TOOLS` env var**: MCP tool filtering at startup so callers can expose only the subset they need. - **`--repo` precedence and validation in `get_docs_section`** (PR #378): honors `serve --repo` and validates path containment before returning section content. - **Search enrichment via PreToolUse hooks** (PR #248): hook-driven search index enrichment ahead of tool calls. - **External database directory support**: graph DB can now live on a network filesystem via the existing `CRG_DATA_DIR` mechanism, with the file locking path adjusted accordingly. - **SVN support** (PR #255): basic Subversion working-copy detection alongside git for change analysis. #### Parser and resolver improvements - **Spring DI call resolution** (PR #413): receiver method calls (`this.userService.find(...)`) resolve through `@Autowired`/constructor-injected fields to the concrete `InjectedType.method`. Emits `INJECTS` edges and stereotype metadata (`@Service`, `@Component`, `@Repository`, `@Controller`); writes fully-qualified `target_qualified` so `callers_of` queries work. - **Temporal workflow/activity call resolution**: `WorkflowStub.start(...)` and `ActivityStub.execute(...)` resolve to their concrete workflow/activity implementations. - **Kafka consumer/producer detection**: `@KafkaListener`-annotated methods and `KafkaTemplate.send(...)` calls emit `CONSUMES` and `PRODUCES` edges keyed on topic. - **Jedi-based Python call resolution** (PR #247): improved cross-file Python call resolution using the Jedi static-analysis library. - **Python callback REFERENCES edges** (PR #363): function names passed as callback arguments (`schedule(my_handler)`) now emit `REFERENCES` edges instead of being dropped. - **Mocha TDD `suite()` recognition** (PR #423): files using Mocha's TDD interface now classify as tests. - **Bun test runtime support** (PR #421): files importing `bun:test` are detected as tests. - **`__tests__/` directory detection** (PR #422): all files under `__tests__/` are classified as test files regardless of name. #### Embeddings - **OpenAI-compatible embedding provider** (PR #321): pluggable provider supporting OpenAI, Azure OpenAI, and any OpenAI-API-compatible endpoint, with configurable batch size. - **Localized embedding READMEs**: provider docs translated for non-English users. #### Visualization, accessibility, and VS Code extension - **WCAG 2.1 AA contrast pass**: 4.5:1 minimum text contrast across the standalone HTML and VS Code webview. - **Distinct `d3.symbol` shapes per node kind**: colorblind-friendly differentiation in both the standalone visualization and the VS Code webview. - **Keyboard navigation**: tab/arrow/enter/escape navigation across nodes, with focus styles and a skip-link to bypass the legend. - **ARIA roles and labels**: tooltip, detail panel, legend, search results, communities button, edge-pill keyboard activation, search input label. - **Help overlay**: interaction guide for both the standalone HTML and the keyboard-help overlay. - **Empty-state webview** in VS Code with a contextual depth slider and tooltip. - **Edge filter popover** in the VS Code toolbar — fixes density on narrow panels. - **Detail panel relocated to the left** so it no longer occludes top controls; close button restyled to match the toolbar. - **CONTAINS edge opacity** raised from 0.08 → 0.14 for visibility on dense graphs. - **GitHub Dark palette** unified across the VS Code extension. - **`IMPLEMENTS`, `TESTED_BY`, `DEPENDS_ON` edge types** rendered in the standalone HTML visualization. ### Fixed #### `__version__` reporting - **`code_review_graph.__version__` now matches `pyproject.toml`** (was `2.1.0` since the v2.1.0 release). The User-Agent header that `embeddings.py` sends on cloud HTTP requests is built from this string, so cloud-embedding traffic was being mis-attributed across all releases between v2.1.0 and v2.3.2. #### C++ / Java / PHP parsing - **C++ scoped/destructor/operator method names** (PR #371, PR #403): `void Foo::bar()`, `Foo::~Foo()`, `Foo::operator==(...)` now extract the correct member name instead of the qualifier or the operator token. - **Java method name extraction** (PR #275): method names are now read from the `identifier` child of `method_declaration` rather than the return-type child (which was producing names like `int64`). - **Java superclass / super-interfaces** (PR #278): `extends Foo` and `implements Bar, Baz` now extract bare type names from the `superclass`/`super_interfaces` AST nodes. - **Java import resolution to file paths** (PR #280): `import com.example.foo.Bar` resolves through `src/main/java/...` and configured source roots to the actual file. - **PHP `CALL` extraction** (PR #298): method calls (`$obj->foo()`), static calls (`Foo::bar()`), and unqualified function calls now produce CALLS edges. - **Module-scope `CALLS` edges** (PR #285): top-level executable statements emit CALLS edges (previously only function/method bodies did). #### Windows - **Windows MCP stdio hang on long-running tools** (PR #400, PR #292): thread-pool selection now auto-selects on Windows MCP stdio so build/embed do not deadlock. - **Windows MCP stdin hang** (PR #425): all `git`/`svn` subprocesses now run with `stdin=DEVNULL`, preventing the FastMCP-stdio buffer from filling on Windows. - **Windows non-UTF-8 locale**: `subprocess.run` calls now pass `encoding="utf-8"` so cp1252 hosts no longer mis-decode git output. - **Windows test failures** (PR #274): UTF-8 encoding, CRLF normalization, and `stop_at` boundary handling fixes for Windows CI. #### Hooks and install - **Hooks JSON schema** (PR #288): `hooks.json` validation no longer fails on the wrapper layout — `matcher` is required and the wrapper is removed. - **Hooks merge instead of overwrite** (PR #114, PR #145, PR #203): `install_hooks` now merges into existing hook arrays and creates a `settings.json.bak` backup before modifying user config. - **Pre-commit hook adds `update` command** (PR #315): generated pre-commit hook runs `code-review-graph update` rather than the obsolete subcommand. - **Skip hooks gracefully outside git** (PR #293): `install` no longer fails when invoked from a non-git directory. - **Poetry / uv environment detection** (PR #287): `install` now generates the correct MCP serve command for projects using Poetry or uv. - **Hook quoting and `docs` repo_root** (PR #192): hook commands now quote repo paths with spaces, and the docs repo path is restored on install. #### MCP server - **fastmcp 3.x compatibility**: `_apply_tool_filter` restored on fastmcp ≥3, dependency floor bumped to `fastmcp>=3.2.4` to pick up the upstream Windows stdio EOF fixes. - **FastMCP banner suppressed for stdio transport** (PR #290): the startup banner no longer corrupts the stdio handshake. - **MCP config `cwd`, skills path, and JSONC parsing**: install now writes `cwd` into MCP config, points skills at the correct project path, and tolerates JSONC (comments + trailing commas) in existing config files. #### SQLite and post-processing - **SQLite transaction safety, FTS5 sync, and atomic operations** (PR #94, PR #279): nested-transaction handling, FTS5 content-table synchronization, and resource cleanup on error paths. - **CLI build/update/watch run post-processing** (PR #98): signatures, FTS, flows, and communities are now refreshed after every CLI graph mutation (was previously only refreshed by the MCP server). - **`reconcile()` auto-builds graphs and registers new repos**: cold-start path no longer requires a manual `build` before `reconcile`. - **Flow trace adjacency in-memory** (PR #296): `trace_flows` loads adjacency once instead of querying SQLite per hop. #### Other - **`UnicodeDecodeError` in `read_text`** (PR #303): all text reads now use `errors="replace"`. - **Dead-code callback references** (PR #424): functions referenced as callbacks no longer mis-classify as dead code. - **Skills.py table formatting** (PR #302). - **Search.py duplicate logger** removed. - **`status` command reports alive/dead** from the persisted state file. ### Security - **Embeddings RCE hardening** (PR #397): remote code execution paths in the embedding provider are gated behind an explicit env var; cloud HTTP requests now send a versioned User-Agent (PR #390) and refuse to mix indexes built with different providers. ### Documentation - **MCP tools documentation** (PR #306): catalog of all MCP tools with usage examples. - **venv usage guide** (PR #307). - **Windows setup guide** for Claude Code MCP integration. - **pipx / PyPI failure troubleshooting** with a `diagnose_pypi_connectivity.py` diagnostic script. - **MseeP.ai badge** added to README (PR #399). ### Maintenance - **Beads (`bd`) issue tracking** initialized for the project (`bd prime` for workflow context). - **iCloud sync duplicate files** removed from the working tree. - **Working spec docs** moved out of git (already in `.gitignore`). - **CI lint and test failures** swept across multiple merged PRs. ### Upgrade notes - `uvx --reinstall code-review-graph` or `pip install -U code-review-graph`. - Re-run `code-review-graph install` once after upgrading to pick up the JSONC-tolerant config writer and the corrected `cwd` / skills path in `.mcp.json`. - The `__version__` fix changes the User-Agent string emitted by cloud embedding providers from `code-review-graph/2.1.0` to `code-review-graph/2.3.3`. Anyone allow-listing the old User-Agent on a proxy needs to update their rule. - VS Code extension still ships separately — repackage and republish the `.vsix` if you want the v2.3.3 a11y improvements in the Marketplace build. ## [2.3.2] - 2026-04-14 Major feature release — 15 new capabilities, 6 community PRs merged, 6 new MCP tools, 4 new languages, multi-format export, and graph analysis suite. ### Added - **Hub node detection** (`get_hub_nodes_tool`): find the most-connected nodes in the codebase (architectural hotspots) by in+out degree, excluding File nodes. - **Bridge node detection** (`get_bridge_nodes_tool`): find architectural chokepoints via betweenness centrality with sampling approximation for graphs >5000 nodes. - **Knowledge gap analysis** (`get_knowledge_gaps_tool`): identify structural weaknesses — isolated nodes, thin communities (<3 members), untested hotspots, and single-file communities. - **Surprise scoring** (`get_surprising_connections_tool`): composite scoring for unexpected architectural coupling (cross-community, cross-language, peripheral-to-hub, cross-test-boundary). - **Suggested questions** (`get_suggested_questions_tool`): auto-generate prioritized review questions from graph analysis (bridge nodes, untested hubs, surprising connections, thin communities). - **BFS/DFS traversal** (`traverse_graph_tool`): free-form graph exploration from any node with configurable depth (1-6) and token budget. - **Edge confidence scoring**: three-tier system (EXTRACTED/INFERRED/AMBIGUOUS) with float confidence scores on all edges. Schema migration v9. - **Export formats**: GraphML (Gephi/yEd/Cytoscape), Neo4j Cypher statements, Obsidian vault (wikilinks + YAML frontmatter + community pages), SVG static graph. CLI: `visualize --format graphml|cypher|obsidian|svg`. - **Graph diff**: snapshot/compare graph state over time — new/removed nodes, edges, community membership changes. - **Token reduction benchmark**: measure naive full-corpus tokens vs graph query tokens with per-question reduction ratios. - **Memory/feedback loop**: persist Q&A results as markdown for re-ingestion via `save_result` / `list_memories` / `clear_memories`. - **Oversized community auto-splitting**: communities exceeding 25% of graph are recursively split via Leiden algorithm. - **4 new languages**: Zig, PowerShell, Julia, Svelte SFC (23 total). - **Visualization enhancements**: node size scaled by degree, community legend with toggle visibility, improved interactivity. - **README translations**: Simplified Chinese, Japanese, Korean, Hindi. ### Merged community PRs - **#127** (xtfer): SQLite compound edge indexes for query performance. - **#184** (realkotob): batch `_compute_summaries` — fixes build hangs on large repos. - **#202** (lngyeen): Swift extension detection, inheritance edges, type kind metadata. - **#249** (gzenz): community detection resolution scaling (21x speedup), expanded framework patterns, framework-aware dead code detection (56 new tests). - **#253** (cwoolum): automatic graph build for new worktrees in Claude Code. - **#267** (jindalarpit): Kiro platform support with 9 tests. ### Changed - MCP tool count: 22 → 28. - Schema version: 8 → 9 (edge confidence columns). - Community detection uses resolution scaling for large graphs. - Risk scoring uses weighted flow criticality and graduated test coverage. - Dead code detection is framework-aware (ORM models, Pydantic, CDK constructs filtered). - Flow entry points expanded with 30+ framework decorator patterns. ## [2.3.1] - 2026-04-11 Hotfix for the Windows long-running-MCP-tool hang that v2.2.4 only partially fixed. ### Fixed - **Windows MCP hang on long-running tools** (PR #231, fixes #46, #136): follow-up to v2.2.4. [@dev-limucc reported on #136](https://github.com/tirth8205/code-review-graph/issues/136) that the `WindowsSelectorEventLoopPolicy` fix from v2.2.4 was necessary but not sufficient — read-only tools worked, but `build_or_update_graph_tool(full_rebuild=True)` and `embed_graph_tool` still hung indefinitely on Windows 11 / Python 3.14. Root cause: FastMCP 2.x dispatches sync handlers inline on the only event-loop thread, so handlers that run for more than a few seconds (especially those that spawn subprocesses or do CPU-bound inference) stop the loop from pumping stdin/stdout. **Fix**: converted the five heavy tools (`build_or_update_graph_tool`, `run_postprocess_tool`, `embed_graph_tool`, `detect_changes_tool`, `generate_wiki_tool`) to `async def` and offloaded the blocking work via `asyncio.to_thread`. The other 19 tools are fast SQLite-read paths and stay sync. Zero config, works on every platform. New regression tests assert the five tools are registered as coroutines AND that each one's source literally contains `asyncio.to_thread` as a defense-in-depth lock-in. ## [2.3.0] - 2026-04-11 Additive feature release — new language parsers, new platform install target, MCP tool UX improvements, and out-of-tree graph storage. No breaking changes from v2.2.4. ### Added - **Elixir parser** (PR #228, closes #112): `.ex` and `.exs` files now produce modules as Class nodes, `def`/`defp`/`defmacro`/`defmacrop` as Function/Test nodes attached to their enclosing module, `alias`/`import`/`require`/`use` as `IMPORTS_FROM` edges, and everything else as `CALLS` edges. Internal call resolution walks into `do_block` bodies so `MathHelpers.double` correctly resolves its call to `Calculator.compute`. - **Objective-C parser** (PR #227, closes #88): `.m` files parse classes (`@interface`, `@implementation`, `@protocol`), instance and class methods, `[receiver message:args]` message expressions, C-style `main()`, and `#import`/`#include`. Multi-part selectors like `add:to:` keep `add` as the canonical method name. - **Bash/Shell parser** (PR #227, closes #197): `.sh`, `.bash`, and `.zsh` files parse functions, `command` invocations as `CALLS`, and `source path` / `. path` as `IMPORTS_FROM` edges with path resolution when the target file exists. - **Qwen Code as a supported MCP install platform** (PR #227, closes #83): `code-review-graph install --platform qwen` writes a merged `~/.qwen/settings.json` using the same `mcpServers` schema as Cursor/Windsurf — it does not clobber existing Qwen config. - **`apply_refactor_tool` dry-run mode** (PR #228, closes #176): new `dry_run: bool = False` parameter on the MCP tool and underlying `apply_refactor()` function. When true, returns a unified diff per file without touching disk and leaves the `refactor_id` valid for a follow-up real apply. Multi-edit files now apply sequentially against updated content in both modes (fixes a subtle bug where separate edits on the same file could stomp each other). - **`CRG_DATA_DIR` environment variable** (PR #228, closes #155): when set, replaces the default `/.code-review-graph` directory verbatim. Useful for ephemeral workspaces, Docker volumes, shared CI caches, and multi-repo orchestrators. Supported by the CLI, MCP tools, and the registry. - **`CRG_REPO_ROOT` environment variable** (PR #228, closes #155): `find_project_root()` now checks `CRG_REPO_ROOT` before the usual git-root walk — useful for anyone scripting the CLI from a cwd outside the target repo. - **`install --no-instructions` and `-y`/`--yes` flags** (PR #228, closes #173): new flags on `code-review-graph install` to opt out of the `CLAUDE.md`/`AGENTS.md`/`.cursorrules`/`.windsurfrules` injection entirely (`--no-instructions`) or auto-confirm it without an interactive prompt (`-y`/`--yes`). The CLI also now prints the list of files it will touch before writing, so even without `--dry-run` users see what's coming. - **Cloud embeddings stderr warning** (PR #228, closes #174): `get_provider()` now prints an explicit warning to stderr before returning a Google Gemini or MiniMax provider, explaining that source code will be sent to an external API. `CRG_ACCEPT_CLOUD_EMBEDDINGS=1` suppresses the warning for scripted workflows. The warning is on stderr only — it never writes to stdout or reads from stdin, so the MCP stdio transport remains uncorrupted. - **TROUBLESHOOTING quick-reference** (PR #228): new top section in `docs/TROUBLESHOOTING.md` covering the four most common support questions — hook schema errors, `command not found` after pip install, project-vs-user scoping, and "built the graph but Claude Code doesn't see it". ### Fixed - **Multi-edit refactor correctness** (PR #228): when a single `apply_refactor` call had multiple edits targeting the same file, the previous implementation re-read the file once per edit and could silently stomp earlier changes. The plan-computation step now groups edits by file and applies them sequentially against the updated content; this fix applies to both the real-write and the new dry-run path. ### Changed - `install` and `init` commands now preview instruction-file targets before writing (no-op if nothing would change). This is always-on and does not require `--dry-run`. - Default embedding path remains fully local (`sentence-transformers`); no behavior change unless you explicitly opt in to a cloud provider. ### Deprecated Nothing. ### Security - The cloud-embedding stderr warning (#174) is a privacy improvement; it does not change the behavior of offline local embeddings, which remain the default. ### Upgrade notes - Nothing to do beyond `uvx --reinstall code-review-graph` or `pip install -U code-review-graph`. If you're coming from v2.2.2 or earlier, re-run `code-review-graph install` once to pick up the v2.2.3 hook schema rewrite. - `CRG_DATA_DIR` is optional — if you don't set it, graphs continue to live at `/.code-review-graph` as before. - VS Code extension v0.2.2 (from v2.2.4) still needs to be **repackaged and republished** separately; the PyPI `publish.yml` workflow does not cover it. ### Superseded PRs - PR #204 (install preview, @lngyeen) — reimplemented cleanly in #228 with `isatty()`-guarded confirmation. - PR #207 (`CRG_DATA_DIR`/`CRG_REPO_ROOT`, @yashmewada9618) — reimplemented cleanly in #228 without `input()`-on-stdio and `mcp._local_only` fragility. - PR #179 (cloud embeddings warning, @Bakul2006) — reimplemented cleanly in #228 with stderr-only messaging and no stdio reads. Credit to @lngyeen, @yashmewada9618, and @Bakul2006 for the original designs. ## [2.2.4] - 2026-04-11 Ships the 11 bugs from PR #222 plus the `v2.2.3.1` smoke-test hotfixes, for users upgrading directly from `v2.2.3` or earlier. ### Security - **fastmcp bumped from 1.0 → ≥2.14.0** (PR #222, fixes #139, #195): closes CVE-2025-62800 (XSS), CVE-2025-62801 (command injection via server_name), CVE-2025-66416 (Confused Deputy). Transitively drops the `docket → fakeredis` chain that was broken by a `FakeConnection` → `FakeRedisConnection` rename in recent fakeredis releases (#195). The FastMCP public API (`FastMCP(name, instructions=...)`, `@mcp.tool()`, `@mcp.prompt()`, `mcp.run(transport="stdio")`) is unchanged across the 1 → 2 bump, so no source changes were needed beyond the pin. All 24 tools verified to register on fastmcp 2.14.6 and round-trip real per-repo data via stdio MCP in a 6-repo smoke test. ### Fixed - **Windows build/embed hangs** (PR #222, fixes #46, #136): `main()` now sets `WindowsSelectorEventLoopPolicy` before `mcp.run()` on `sys.platform == "win32"`. The default `ProactorEventLoop` on Windows Python 3.8+ deadlocks with `ProcessPoolExecutor` (used by `full_build`) over a stdio MCP transport — producing the silent "Synthesizing…" hangs on `build` and `embed_graph_tool`. This is a no-op on macOS/Linux. **Note**: the fix was applied blind; maintainer could not verify on Windows. Please open a fresh issue if you still see a hang on v2.2.4 Windows with either `sentence-transformers` or Gemini providers. - **Go method receivers** (PR #222, fixes #190): `func (s *T) Foo()` now attaches `Foo` to `T` as a member (`parent_name="T"`) with the usual `CONTAINS` edge instead of appearing as a top-level function. New `_get_go_receiver_type()` helper walks the method_declaration's first parameter_list to extract the receiver type name. - **Dart parser — three bugs** (PR #222, fixes #87): - Dart `CALLS` edges (`_extract_dart_calls_from_children()`) — tree-sitter-dart doesn't wrap calls in a single `call_expression` node; the pattern is `identifier + selector > argument_part`. New walker handles both direct (`print('x')`) and method-chained (`obj.foo()`) shapes. - Dart `package:` URI resolution in `_do_resolve_module()` — `package:/` now walks up to a `pubspec.yaml` whose `name:` declaration matches `` and resolves to `/lib/`. - `inheritors_of` bare-vs-qualified name mismatch in `tools/query.py` — falls back to `search_edges_by_target_name(node.name, kind=...)` for `INHERITS`/`IMPLEMENTS` when the qualified-name lookup returns nothing. Affects all languages (INHERITS targets are stored as bare strings for every language), not just Dart. - **Nested `node_modules` and framework ignore defaults** (PR #222, fixes #91): `_should_ignore()` now treats single-segment `/**` patterns as "this directory at any depth", so `node_modules/**` also matches `packages/app/node_modules/react/index.js` inside monorepos. Extended `DEFAULT_IGNORE_PATTERNS` with Laravel/Composer (`vendor/**`, `bootstrap/cache/**`, `public/build/**`), Ruby (`.bundle/**`), Gradle (`.gradle/**`, `*.jar`), Flutter/Dart (`.dart_tool/**`, `.pub-cache/**`), and generic `coverage/**`, `.cache/**`. Deliberately did **not** add `packages/**` or `bin/**`/`obj/**` — those are false positives in yarn/pnpm workspace monorepos and .NET source trees respectively. - **Bare `except Exception` cleanup** (PR #222, fixes #194): Replaced with specific exception classes + `logger.debug(...)` in 11 files (`cli.py`, `graph.py`, `migrations.py`, `parser.py`, `registry.py`, `tools/context.py`, `tsconfig_resolver.py`, `visualization.py`, `wiki.py`, `eval/benchmarks/search_quality.py`). No behavioral change; debuggability improvement. - **Visualization auto-collapse hiding all edges** (PR #222, fixes #132): `visualization.py` no longer unconditionally auto-collapses every File node on page load. Auto-collapse now only kicks in above 2000 nodes — previously any graph above ~300 nodes would silently hide every CALLS/IMPORTS/INHERITS edge because they connect Functions/Classes nested inside the collapsed Files. - **`eval` command crashes on `yaml.safe_load`** (PR #222, fixes #212): `eval.runner.load_all_configs()` now calls `_require_yaml()` before reading YAML, so users without `code-review-graph[eval]` installed get `ImportError: pyyaml is required: pip install code-review-graph[eval]` instead of `AttributeError: 'NoneType' object has no attribute 'safe_load'`. ### VS Code extension (0.2.2) - **`better-sqlite3` bumped 11.x → 12.x** (PR #222, fixes #218): VS Code 1.115 ships Electron 39 / V8 14.2 which removed `v8::Context::GetIsolate()`, the C++ API used by `better-sqlite3@11`. The extension couldn't activate at all — every command was undefined. `better-sqlite3@12.4.1+` (installs 12.8.0) uses the new V8 API and ships Electron 39 prebuilds. `@types/better-sqlite3: ^7.6.8 → ^7.6.13`, plus type-import adjustments in `src/backend/sqlite.ts` for the `Node16` module resolution and the new CJS `export =` types. Extension version bumped to 0.2.2. **Remember to repackage and republish the `.vsix`** — the existing `publish.yml` workflow only covers PyPI. ### Carried forward from 2.2.3.1 - `serve --repo ` is now honored by all 24 MCP tools (was only read by `get_docs_section_tool`). See #223. - Wiki slug collisions no longer silently overwrite pages (~70% data loss on real repos). See #223. ### Upgrade notes - `uvx --reinstall code-review-graph` or `pip install -U code-review-graph`, then re-run `code-review-graph install` (the 2.2.3 hook-schema rewrite is still a requirement if you're coming from 2.2.2 or earlier). - VS Code extension needs to be repackaged + republished separately; the Python release does not include it. ## [2.2.3.1] - 2026-04-11 Hotfix on top of 2.2.3 for two bugs surfaced by a full first-time-user smoke test against six real OSS repos (express, fastapi, flask, gin, httpx, next.js). ### Fixed - **`serve --repo ` was ignored by 21 of 24 MCP tools** (PR #223): `main.py` captured the `--repo` CLI flag into `_default_repo_root`, but only `get_docs_section_tool` read it. The other 21 `@mcp.tool()` wrappers all took `repo_root: Optional[str] = None` and passed that straight through to the impl, which fell back to `find_repo_root()` from cwd. The real-world blast radius is small — the `install` command writes `.mcp.json` without a `--repo` flag and Claude Code launches the server with `cwd=` — but anyone scripting `serve` manually or running a multi-repo orchestrator would silently get the wrong graph. Added a single `_resolve_repo_root()` helper with explicit precedence (client arg > `--repo` flag > `None → cwd`) and threaded it through all 24 wrappers. New unit tests cover the precedence rules. - **Wiki slug collisions silently overwrote pages** (PR #223): `_slugify()` folds non-alphanumerics to dashes and truncates to 80 chars, so similar community names collided (`"Data Processing"`, `"data processing"`, `"Data Processing"` all → `data-processing.md`). `generate_wiki()` wrote each community to `.md` regardless, so later iterations overwrote earlier files while the counter reported them as "updated". On the express smoke test this was **~70% silent data loss** (32 real files vs 107 claimed pages). Fixed by tracking used slugs per-run and appending `-2`, `-3`, … until unique. Every community now gets its own page; the counter matches the physical file count; `get_wiki_page()` still resolves by name via the existing partial-match fallback. New regression test monkey-patches three colliding names and asserts no content loss. ## [2.2.3] - 2026-04-11 ### Fixed - **Claude Code hook schema** (PR #208, fixes #97, #138, #163, #168, #172, #182, #188, #191, #201): `generate_hooks_config()` now emits the valid v1.x+ Claude Code schema — every hook entry has `matcher` + a nested `hooks: [{type, command, timeout}]` array, and timeouts are in seconds. The invalid `PreCommit` event has been removed; pre-commit checks are now installed as a real git hook via `install_git_hook()`. Users upgrading from 2.2.2 must re-run `code-review-graph install` to rewrite `.claude/settings.json`. - **SQLite transaction nesting** (PR #205, fixes #110, #135, #181): `GraphStore.__init__` now connects with `isolation_level=None`, disabling Python's implicit transactions that were the root cause of `sqlite3.OperationalError: cannot start a transaction within a transaction` on `update`. `store_file_nodes_edges` adds a defensive `in_transaction` flush before `BEGIN IMMEDIATE`. - **Go method receivers** (PR #166): `_extract_name_from_node` now resolves Go method names from `field_identifier` inside `method_declaration`, fixing method names that were previously picked up as the result type (e.g. `int64`) instead of the method name. - **UTF-8 decode errors in `detect_changes`** (PR #170, fixes #169): Diff parsing now uses `errors="replace"` so diffs containing binary files no longer crash the tool. - **`--platform` target scope** (PR #142, fixes #133): `code-review-graph install --platform ` now correctly filters skills, hooks, and instruction files so you only get configuration for the requested platform. - **Large-repo community detection hangs** (PR #213, PR #183): Removed recursive sub-community splitting, capped Leiden at `n_iterations=2`, and batched `store_communities` writes. 100k+ node graphs no longer hang in `_compute_summaries`. - **CI**: ruff lint + `tomllib` on Python 3.10 (PR #220) — `tests/test_skills.py` now uses a conditional `tomli` backport on 3.10, `N806`/`E501`/`W291` fixes in `skills.py`/`communities.py`/`parser.py`, and the embedded `noqa` reference in `visualization.py` was rephrased so ruff stops parsing it as a directive. - **Missing dev dependencies** (PR #159): `pytest-cov` added to dev extras, 50 ruff errors swept, one failing test fixed. - **JSX component CALLS edges** (PR #154): JSX component usage now produces CALLS edges so component-to-component relationships appear in the graph. ### Added - **Codex platform install support** (PR #177): `code-review-graph install --platform codex` appends a `mcp_servers.code-review-graph` section to `~/.codex/config.toml` without overwriting existing Codex settings. - **Luau language support** (PR #165, closes #153): Roblox Luau (`.luau`) parsing — functions, classes, local functions, requires, tests. - **REFERENCES edge type** (PR #217): New edge kind for symbol references that aren't direct calls (map/dispatch lookups, string-keyed handlers), including Python and TypeScript patterns. - **`recurse_submodules` build option** (PR #215): Build/update can now optionally recurse into git submodules. - **`.gitignore` default for `.code-review-graph/`** (PR #185): Fresh installs automatically add the SQLite DB directory to `.gitignore` so the database isn't accidentally committed. - **Clearer gitignore docs** (PR #171, closes #157): Documentation now spells out that `code-review-graph` already respects `.gitignore` via `git ls-files`. ### Changed - Community detection is now bounded — large repos complete in reasonable time instead of hanging indefinitely. ### Fixed - **`install_hooks` now merges instead of overwriting** (PR #203, fixes #114): `install_hooks()` previously used `dict.update()` which clobbered any user-defined hooks in `.claude/settings.json`. Now merges new entries into existing hook arrays, preserving user hooks. Creates a backup (`settings.json.bak`) before modification. ## [2.2.2] - 2026-04-08 ### Added - **Kotlin call extraction**: `simple_identifier` + `navigation_expression` support for Kotlin method calls (PR #107) - **JUnit/Kotlin test detection**: Annotation-based test classification (`@Test`, `@ParameterizedTest`, etc.) for Java/Kotlin/C# (PR #107) ### Fixed - **Windows encoding crash**: All `write_text`/`read_text` calls in `skills.py` now use `encoding='utf-8'` explicitly (PR #152, fixes #147, #148) - **Invalid `--quiet` flag in hooks**: Removed non-existent `--quiet` and `--json` flags from generated hook commands (PR #152, fixes #149) ### Housekeeping - Untracked `.claude-plugin/` directory and added to `.gitignore` - GitHub issue triage: responded to 30+ issues, closed 14, reviewed 24 PRs ## [2.2.1] - 2026-04-07 ### Added - **Parallel parsing**: `ProcessPoolExecutor` for 3-5x faster builds (`CRG_PARSE_WORKERS`, `CRG_SERIAL_PARSE`) - **Lazy post-processing**: `postprocess="full"|"minimal"|"none"` parameter, `run_postprocess` MCP tool + CLI command - **SQLite-native BFS**: Recursive CTE replaces NetworkX for impact analysis (`CRG_BFS_ENGINE`) - **Configurable limits**: `CRG_MAX_IMPACT_NODES`, `CRG_MAX_IMPACT_DEPTH`, `CRG_MAX_BFS_DEPTH`, `CRG_MAX_SEARCH_RESULTS` - **Multi-hop dependents**: N-hop `find_dependents()` with `CRG_DEPENDENT_HOPS` (default 2) and 500-file cap - **Token-efficient output**: `detail_level="minimal"` on 8 tools for 40-60% token reduction - **`get_minimal_context` tool**: Ultra-compact entry point (~100 tokens) with task-based tool routing - **Token-efficient prompts**: All 5 MCP prompts rewritten with minimal-first workflows - **Incremental flow/community updates**: `incremental_trace_flows()`, `incremental_detect_communities()` - **Visualization aggregation**: Community/file/auto modes with drill-down for large graphs (`--mode`) - **Token-efficiency benchmarks**: 5 workflow benchmarks in `eval/token_benchmark.py` - **DB schema v6**: Pre-computed `community_summaries`, `flow_snapshots`, `risk_index` tables - **Token Efficiency Rules** in all skill templates and CLAUDE.md ### Changed - CLI `build`/`update` support `--skip-flows`, `--skip-postprocess` flags - PostToolUse hook uses `--skip-flows` for faster incremental updates - VS Code extension schema version bumped to v6 ### Fixed - mypy type errors in parallel parsing and context tool - Bandit false positive on prompt preamble string - Import sorting in graph.py, main.py, tools/__init__.py - Unused imports cleaned up in cli.py ### Housekeeping - Gitignore: untrack `marketing-diagram.excalidraw`, `evaluate/results/`, `evaluate/reports/` - Updated FEATURES.md, LLM-OPTIMIZED-REFERENCE.md, CHANGELOG.md for v2.2.1 ## [2.1.0] - 2026-04-03 ### Added - **Jupyter notebook parsing**: Parse `.ipynb` files — extract functions, classes, imports across Python, R, and SQL cells - **Databricks notebook parsing**: Parse Databricks `.py` notebook exports with `# COMMAND ----------` cell boundaries - **Lua language support**: Full parsing for `.lua` files (functions, local functions, method calls, requires) — 20th language - **Perl XS support**: Parse `.xs` files with improved Perl call detection and test coverage - **Zero-config onboarding**: `install` now sets up skills, hooks, and CLAUDE.md by default so the graph is used automatically - **Platform rule injection**: Graph instructions injected into all platform rule files (CLAUDE.md, .cursorrules, etc.) on install - **Smart install detection**: Auto-detects whether installed via uvx or pip and generates correct `.mcp.json` - **`--platform claude-code` alias**: Accepts both `claude` and `claude-code` as platform names ### Fixed - **JS/TS arrow functions indexed**: `const foo = () => {}` and `const bar = function() {}` now correctly appear as nodes (#66) - **`importers_of` path resolution**: Normalized with `resolve()` to match stored edge targets (#65) - **Custom embedding models**: Support for custom model architectures and restored model param wiring in search (#79) ## [2.0.0] - 2026-03-27 ### Added - **12 new features**: flows, communities, hybrid search, change analysis, refactoring, hints, prompts, skills, wiki, multi-repo registry, migrations, eval framework - **14 new modules** (~10,000 lines): `flows.py`, `communities.py`, `search.py`, `changes.py`, `refactor.py`, `hints.py`, `prompts.py`, `skills.py`, `wiki.py`, `registry.py`, `migrations.py`, `eval/` - **15 new MCP tools**: `list_flows`, `get_flow`, `get_affected_flows`, `list_communities`, `get_community`, `get_architecture_overview`, `detect_changes`, `refactor`, `apply_refactor`, `generate_wiki`, `get_wiki_page`, `list_repos`, `cross_repo_search`, `find_large_functions`, `semantic_search_nodes` - **5 MCP prompts**: `review_changes`, `architecture_map`, `debug_issue`, `onboard_developer`, `pre_merge_check` - **7 new CLI commands**: `detect-changes`, `wiki`, `eval`, `register`, `unregister`, `repos`, `install --skills/--hooks/--all` - **Interactive visualization upgrade**: Detail panel, community coloring, flow path highlighting, search-to-zoom, kind filters ### Security - Fix path traversal in wiki page reader - Add regex allowlist for git ref validation - Add explicit SSL context for MiniMax API ### Fixed - Fix git diff argument ordering (broke incremental updates) - Fix `node_qualified_name` schema mismatch in wiki flow query - Batch N+1 queries in `get_impact_radius` and risk scoring ### Architecture - Decompose `_extract_from_tree` into 6 focused methods - Add 17 public query methods to `GraphStore` - Split `tools.py` into 10 themed sub-modules ## [1.8.4] - 2026-03-20 ### Added - **Vue SFC parsing**: Parse `.vue` Single File Components by extracting `