feat(mcp): detect borrowed git worktree index and surface on read tools (#312)

When a worktree is nested inside the main checkout (e.g. agent tools that place
worktrees under .claude/worktrees/<name>/), the nearest-.codegraph walk resolves
UP to the main checkout's index and queries silently return that tree's code —
usually a different branch. Symbols changed only in the worktree are invisible,
and nothing tells the user (#155).

Two layers:

- **Detection** (src/sync/worktree.ts): detectWorktreeIndexMismatch() compares
  the caller's git working-tree root vs the resolved index root via
  'git rev-parse --show-toplevel'. Best-effort; no git / not a repo / monorepo
  subdir / plain-ancestor index → no warning.
- **Surface**: codegraph status (CLI + MCP) embeds a verbose multi-line warning;
  every MCP read tool (search/context/trace/callers/callees/impact/explore/node/
  files) prefixes a compact one-line notice naming the borrowed index and the
  fix (codegraph init -i in the worktree). Detection is cached per session per
  start path, so it costs at most a single pair of 'git rev-parse' spawns per
  project no matter how many tool calls — respects the wall-clock-latency
  invariant.

Real-git tests (no mocking) cover both layers. Validated on macOS / Linux
(Docker) / Windows (Parallels VM); 11/11 worktree tests green on all three.

Closes #155

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
신주안
2026-05-25 20:57:20 -05:00
committed by GitHub
co-authored by Claude Opus 4.7
parent 8edd6cfafd
commit 4a4a37d135
6 changed files with 424 additions and 10 deletions
+14
View File
@@ -35,6 +35,20 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
standalone until it idles out — they never mix versions over the socket.
### Fixed
- **Git worktrees no longer silently borrow another tree's index (#155).**
When a worktree is nested inside the main checkout — exactly what agent
tools that place worktrees under gitignored paths like
`.claude/worktrees/<name>/` do — running CodeGraph from that worktree used
to walk *up* to the main checkout's `.codegraph/` and silently return that
tree's code (usually a different branch). Symbols changed only in the
worktree were invisible and nothing told you. Now `codegraph status` (CLI +
MCP) calls out the conflict explicitly, and every MCP read tool
(`codegraph_search`/`context`/`trace`/`callers`/`callees`/`impact`/
`explore`/`node`/`files`) prefixes a one-line notice naming the borrowed
index and the fix (`codegraph init -i` in the worktree). Detection is
best-effort (no git / not a repo / monorepo subdir → no warning) and runs
once per session per start path, so it never costs more than a single pair
of `git rev-parse` invocations.
- **The file watcher no longer exhausts the OS file-watch budget on large
repos (#276).** It used to register a recursive watch over the *entire*
project — `node_modules/`, build output, caches and all — and filter only