* 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)
| 1206 | * broken by this check. |
| 1207 | */ |
| 1208 | private worktreeMismatchFor(projectPath?: string): WorktreeIndexMismatch | null { |
| 1209 | const startPath = projectPath ?? this.defaultProjectHint ?? process.cwd(); |
| 1210 | |
| 1211 | // The verdict depends on BOTH the start path AND the index root it resolves |
| 1212 | // to, so the cache must be keyed on the pair. Resolve the index root first |
| 1213 | // (cheap — getCodeGraph re-walks to the nearest .codegraph/, no git), then |
| 1214 | // key on `(startPath, indexRoot)`. The moment that root changes — most |
| 1215 | // importantly when a git worktree gains its own index and the walk-up stops |
| 1216 | // there instead of at the parent checkout — the key changes and the verdict |
| 1217 | // is recomputed, instead of serving the stale "borrowed the parent's index" |
| 1218 | // warning for the server's whole lifetime. Keying on startPath alone pinned |
| 1219 | // that first verdict until restart (#926). |
| 1220 | let indexRoot: string; |
| 1221 | try { |
| 1222 | indexRoot = this.getCodeGraph(projectPath).getProjectRoot(); |
| 1223 | } catch { |
| 1224 | // No resolvable project (or any other resolution error) → nothing to warn. |
| 1225 | return null; |
| 1226 | } |
| 1227 | |
| 1228 | const cacheKey = `${startPath}\u0000${indexRoot}`; |
| 1229 | const cached = this.worktreeMismatchCache.get(cacheKey); |
| 1230 | if (cached !== undefined) return cached; |
| 1231 | |
| 1232 | const mismatch = detectWorktreeIndexMismatch(startPath, indexRoot); |
| 1233 | this.worktreeMismatchCache.set(cacheKey, mismatch); |
| 1234 | return mismatch; |
| 1235 | } |
| 1236 | |
| 1237 | /** |
| 1238 | * Prefix a successful read-tool result with a compact worktree-mismatch |
no test coverage detected