* Cached git worktree/index mismatch for a tool call's effective project. * * The "effective project" is what the request targets: an explicit * `projectPath` arg, else the directory the server resolved its default * project from (`defaultProjectHint`), else cwd. Memoized per start path
(projectPath?: string)
| 2519 | * broken by this check. |
| 2520 | */ |
| 2521 | private worktreeMismatchFor(projectPath?: string): WorktreeIndexMismatch | null { |
| 2522 | const startPath = projectPath ?? this.defaultProjectHint ?? process.cwd(); |
| 2523 | |
| 2524 | // The verdict depends on BOTH the start path AND the index root it resolves |
| 2525 | // to, so the cache must be keyed on the pair. Resolve the index root first |
| 2526 | // (cheap — getCodeGraph re-walks to the nearest .codegraph/, no git), then |
| 2527 | // key on `(startPath, indexRoot)`. The moment that root changes — most |
| 2528 | // importantly when a git worktree gains its own index and the walk-up stops |
| 2529 | // there instead of at the parent checkout — the key changes and the verdict |
| 2530 | // is recomputed, instead of serving the stale "borrowed the parent's index" |
| 2531 | // warning for the server's whole lifetime. Keying on startPath alone pinned |
| 2532 | // that first verdict until restart (#926). |
| 2533 | let indexRoot: string; |
| 2534 | try { |
| 2535 | indexRoot = this.getCodeGraph(projectPath).getProjectRoot(); |
| 2536 | } catch { |
| 2537 | // No resolvable project (or any other resolution error) → nothing to warn. |
| 2538 | return null; |
| 2539 | } |
| 2540 | |
| 2541 | const cacheKey = `${startPath}\u0000${indexRoot}`; |
| 2542 | const cached = this.worktreeMismatchCache.get(cacheKey); |
| 2543 | if (cached !== undefined) return cached; |
| 2544 | |
| 2545 | const mismatch = detectWorktreeIndexMismatch(startPath, indexRoot); |
| 2546 | this.worktreeMismatchCache.set(cacheKey, mismatch); |
| 2547 | return mismatch; |
| 2548 | } |
| 2549 | |
| 2550 | /** |
| 2551 | * Prefix a successful read-tool result with a compact worktree-mismatch |
no test coverage detected