* 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)
| 1728 | * broken by this check. |
| 1729 | */ |
| 1730 | private worktreeMismatchFor(projectPath?: string): WorktreeIndexMismatch | null { |
| 1731 | const startPath = projectPath ?? this.defaultProjectHint ?? process.cwd(); |
| 1732 | |
| 1733 | // The verdict depends on BOTH the start path AND the index root it resolves |
| 1734 | // to, so the cache must be keyed on the pair. Resolve the index root first |
| 1735 | // (cheap — getCodeGraph re-walks to the nearest .codegraph/, no git), then |
| 1736 | // key on `(startPath, indexRoot)`. The moment that root changes — most |
| 1737 | // importantly when a git worktree gains its own index and the walk-up stops |
| 1738 | // there instead of at the parent checkout — the key changes and the verdict |
| 1739 | // is recomputed, instead of serving the stale "borrowed the parent's index" |
| 1740 | // warning for the server's whole lifetime. Keying on startPath alone pinned |
| 1741 | // that first verdict until restart (#926). |
| 1742 | let indexRoot: string; |
| 1743 | try { |
| 1744 | indexRoot = this.getCodeGraph(projectPath).getProjectRoot(); |
| 1745 | } catch { |
| 1746 | // No resolvable project (or any other resolution error) → nothing to warn. |
| 1747 | return null; |
| 1748 | } |
| 1749 | |
| 1750 | const cacheKey = `${startPath}\u0000${indexRoot}`; |
| 1751 | const cached = this.worktreeMismatchCache.get(cacheKey); |
| 1752 | if (cached !== undefined) return cached; |
| 1753 | |
| 1754 | const mismatch = detectWorktreeIndexMismatch(startPath, indexRoot); |
| 1755 | this.worktreeMismatchCache.set(cacheKey, mismatch); |
| 1756 | return mismatch; |
| 1757 | } |
| 1758 | |
| 1759 | /** |
| 1760 | * Prefix a successful read-tool result with a compact worktree-mismatch |
no test coverage detected