# Changelog ## [Unreleased] ### Added - `install` keeps a record of the files it writes inside the repository, in `.code-review-graph/install-manifest.json`, even when `--data-dir` or `CRG_DATA_DIR` keeps the graph somewhere else. Each install adds to it and never drops a file. `uninstall` drops each file it removes or cleans, and deletes the record when it is empty. `install --dry-run` shows the record like any other file. - New `code-review-graph doctor` command. It lists every `code-review-graph` on PATH with its version, the version each MCP entry in the repository's configs runs (read from a `uvx` pin or `uv tool list`, never by starting a download), the graph's schema, whether it is current with HEAD (a graph the pre-commit hook updated counts as current) and whether the last build finished, and which git and editor hooks are installed and the version of the copy they run. It changes nothing, exits 1 when a check fails, and takes `--json`. ### Changed - The reference that `get_docs_section_tool` serves no longer sets a budget of 800 tokens per task, and says that `detail_level="minimal"` drops source, so a search with `include_source=True` stays at standard. It now also covers `removed_symbols` in a change review, `resolution="direct"` on `query_graph_tool`, `import_cycles` in `get_knowledge_gaps_tool`, the `stale_graph` reason, the new `doctor` command and the CLI exit codes. - The skills `install` writes for Claude Code, Gemini CLI, CodeBuddy Code, Hermes Agent and Qoder say the same: no 800-token budget, and `detail_level="minimal"` drops source, so a search with `include_source=True` and `get_review_context_tool` stay at standard. Run `install` again for the new text. ### Fixed - The MCP entry and every hook `install` writes now run the copy of code-review-graph that ran `install`. The MCP entry used `uvx` whenever it was on PATH, and hooks ran the first copy on PATH, so an older copy could answer and refuse a newer graph. Inside a Poetry or uv project the entry still uses `poetry run` or `uv run`; `uvx` is now used only when `install` itself runs from `uvx` or a `uv tool` install; otherwise it is the Python that ran `install`. A hook whose copy is gone, as on a collaborator's machine, runs the copy on PATH. Run `install` again to update the entry and the hooks. - The git pre-commit hook runs `update --quiet`, so a commit shows only the short review from `detect-changes --brief`, not the update log. - `install` (and `install --platform all`) writes MCP entries, skills, hooks and instruction files only for the tools it finds on this machine. Claude Code, OpenCode, Qoder and CodeBuddy Code used to count as found everywhere, and Gemini CLI skills and hooks, Codex hooks and all nine instruction files were written whatever was found. Claude Code counts as found by `claude` on PATH, `~/.claude` or `~/.claude.json`, OpenCode by `opencode` on PATH, `~/.opencode` or its config or data folder, and Codex also by `codex` on PATH. `install` now lists the tools it did not find; add one anyway with `install --platform NAME`. - `install` writes each git hook once, so each one is reported once, and shows paths relative to the repository or with `~`. Outside Git it says once, not four times, that there is no hooks folder. - With no terminal, as when an AI agent runs it, `install` says it took the default answer (yes) to its question about instruction files, and how to skip them; `uninstall` says it took no and how to go ahead. At a terminal, `install` says that Ctrl-C at the question stops it before anything is written. - `uninstall` and `uninstall --dry-run` word every planned action as "would remove …" and every action they took as "removed …". Most planned actions read "would removed …", and a few that were taken read "remove …". - `uninstall` removes a config file `install` made, such as `.mcp.json`, `.vscode/mcp.json` or `.claude/settings.json`, when nothing else is left in it, and the empty folders `install` made, instead of leaving `{"mcpServers": {}}` and the like behind. It does so only for a file on the install record that Git does not track and that has no comments; any other file keeps everything but our entries, as before. - A second `install` that changes nothing no longer backs up a settings file that already holds the hooks, so it writes nothing at all. - `build` and change discovery leave out the files `install` wrote, as listed in `.code-review-graph/install-manifest.json`, until Git tracks them. Your first review now shows your change, not `.mcp.json` and hook scripts. A file you commit counts like any other. - `get_minimal_context_tool` no longer says `stale_graph` right after a commit the pre-commit hook updated. When every file changed since the graph's commit has the same content in the graph, the graph counts as current. - `next_tool_suggestions` give the names the server registers, which end in `_tool`, such as `build_or_update_graph_tool`. Some answers gave names no client could call. - `detect-changes --base` with a revision Git does not know exits 1 with one line saying how to check it. It used to review the working tree and exit 0. The MCP review tools answer `status: error`. In a repository with one commit, or none, the default base prints a plain note and reviews uncommitted and new files, with no Git error text. In a shallow clone, as in many CI jobs, the note says the clone is shallow and how to fetch the last commit. - The review tools review a new file Git does not track as a whole. It used to drop out of the review when another file had changed lines. - `detect-changes --brief` lists the top three things to review, each with its file and line, its risk out of 1.00, its callers and its tests, and gives the overall score out of 1.00 with its level, as in `Overall risk score: 0.80 of 1.00 (high)`. - A graph written by a newer copy now names the copy that refused it, its version and its folder, and points at `doctor` to find the others. - `build` ends with a next step, and warns on stderr when it found no source files ("Is this the project root?"). - A first build logs one line, `Created graph database (schema v15).`, instead of every migration step. The Spring event resolver and the Python import resolver are quiet when they found nothing, and a missing igraph is now a tip naming `pip install "code-review-graph[communities]"`. Upgrading an existing graph to schema 15 logs one line asking for a `build` once. - The banner lists every command, in groups, with a start line. `--help` shows `` instead of a list of every name and leaves out the hook-only `enrich`, `hook-update` and `hook-status`, which still run. A mistyped command exits 2 with "Did you mean ...?". Help text uses British spelling. - Every `pip install` hint for an extra quotes it, so it works in zsh. This includes the VS Code extension's hint for embeddings. - `impact --detail-level compact` and `get_impact_radius_tool(detail_level="compact")` now write their line to the context-history log when `CRG_CONTEXT_HISTORY=1`, as every other answer with `context_savings` does. - A yes/no question that gets no input, such as stdin from NUL on Windows, now takes the default and says so, instead of always meaning "no". - `build`, `update` and `postprocess` with a `--repo` that is not a folder print one `Error:` line and exit 1, with no traceback. - `detect-changes --brief` and `update --brief` no longer show "Saved ~98%" when no functions changed; one line says there is nothing to measure. - `code-review-graph query` takes all 19 patterns the MCP tool takes, including `references_to` and the Spring and event ones. - The enrich and edit hooks read their input as UTF-8 on Windows, so paths such as `C:\Users\José` work. - `update` works in a project that has a graph but no Git, and the OpenCode plugin logs commands that fail. - `uninstall` removes the OpenCode entry from both `opencode.jsonc` and `opencode.json`, and the OpenCode plugin goes under `$XDG_CONFIG_HOME` when it is set. - The git hook block now runs in a hook you wrote that ends with `exit 0`; a reinstall moves an old block above the `exit`. A hook that ends with a bare `exit` or `exit $?` is left alone, with a warning. - `git commit --amend`, even with `--no-verify`, now updates the graph. - The plugin hooks no longer say "Not a git repo" in a Git repository with no graph, and the worktree hook no longer builds a graph outside Git. - The Codex edit hook never builds a new graph; it only updates one that exists. Run `install` again for the new hook. - A reinstall keeps your first `settings.json.bak`, and `uninstall` removes a backup that holds only code-review-graph settings. - A Rust call such as `v.map(...)` on a value of unknown type no longer links to a method that just happens to share its file. - A PHP or Rust `Class::method` call now links only when the calling file backs it (same file, an import naming the class, the same PHP namespace, or `self`/`Self`), not just because the name is unique. - `path_to` no longer follows imports that never run (`if TYPE_CHECKING:`, `import type`). - `traverse_graph_tool` works from a symbol whose name is over 256 characters. - The graph page: hiding a community hides its edges too, labels come back when you show a community again or turn community colours off, Escape brings the legend back, and a node reached with the keyboard shows its tooltip beside it. - `visualize --format obsidian` is much faster when many names clash, such as `__init__`. - VS Code extension: the walkthrough's Build Graph says when a build fails; Build Graph, Update Graph, Compute Embeddings and Watch Mode no longer stop after 60 seconds; and seven settings that did nothing are gone (`graphTheme`, `graph.defaultEdges` and the five `treeView.show*`). - Two programs opening a new or old graph at the same time no longer fail with `duplicate column name` or `table nodes_fts already exists`. - `eval --report` shows only each repository's newest run of each benchmark, not old runs mixed in. - The PR comment workflow no longer shows a red run when the PR moved during its analysis; it leaves a notice naming both commits. - A call that could mean several functions now stores them in sorted order, so the same code gives the same graph whatever order its files are read in. ## [2.4.0] - 2026-11-10 Two new platforms, MiMo Code and DeepSeek Harness, so `install` now supports 18. HTML, XSLT, Liquid, JSON and plain YAML files are indexed, and so are `.cjs` and `.kts` files, which every build used to skip. The graph links calls, imports and tests more carefully: a call it could not check no longer looks like a real link, every call edge says how sure it is, calls to inherited methods and imports of workspace packages are followed, and `tests_for` finds Java, Ruby and PHP tests. The graph schema moves from 13 to 15. Several new settings are off unless you turn them on. Read the [Upgrade notes](#upgrade-notes) at the end of this section before you upgrade. ### Added - DeepSeek Harness is a supported platform (#1100, #1101, thanks @sumingwang233). `install --platform dsh` adds one `insert` entry for DSH's own MCP client to `~/.dsh/cordis.patch.yml` (or `$DSH_HOME/cordis.patch.yml`), which every DSH profile reads, and the graph block to `AGENTS.md`. Comments, `!!js` values and other entries in the file are kept byte for byte, and `uninstall` takes the entry out again. Plain `install` picks DSH up when its home folder exists. - HTML pages (`.html`, `.htm`) are indexed (#521). They used to give nothing at all. Inline scripts are parsed as JavaScript or TypeScript with the page's own line numbers, and a `