| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix(sync): git sync hooks refresh the project they were installed for (#1965) Git runs hooks from the top of the work tree, so a hook running a bare `codegraph sync` never reached a sub-project's index. Each hook block now names the project root it syncs, shell-quoted, one block per root, placed right after the shebang so a user hook that ends in exit cannot skip it. A hook in another language is left untouched and reported, and a block from an older install counts as the top-level project's. A project path with a line break is refused, since the root is written on a comment line in the hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> | 8 天前 | |
fix(watcher): retain pending files on zero-result sync (#450) * fix(watcher): retain pending files on zero-result sync * refactor(watcher): detect lock-unavailable at the wrapper Replace the heuristic `(filesChanged === 0 && durationMs === 0)` check inside `FileWatcher.flush()` with a typed `LockUnavailableError` thrown by `CodeGraph.watch()`'s sync wrapper. The wrapper has access to the full `SyncResult`, including `filesChecked` — which is **only** zero when `sync()` failed to acquire the cross-process file lock (a real empty sync always has `filesChecked > 0` because `scanDirectory` ran). That eliminates the heuristic's edge case where a fast no-op sync returns `durationMs === 0` by `Date.now()` rounding and gets mistaken for a lock failure on tiny projects. The watcher's `catch` block now distinguishes `LockUnavailableError` from real errors: it logs at `logDebug` (not `logWarn`) and does NOT call `onSyncError` — so a long-running external indexer holding the lock doesn't spam stderr every debounce cycle via the MCP daemon's `Auto-sync error` handler. The existing post-catch path already preserves `pendingFiles` and reschedules, so no new control flow is needed. A/B validated end-to-end against the built dist on macOS with a three-scenario repro (lock held, lock released mid-flight, real sync error): - main: lock-held silently clears pendingFiles (BUG); lock-released never recovers (no real sync runs). - PR-as-is: lock-held preserves pendingFiles; lock-released drains. Same observable behavior as wrapper-level. - wrapper-level: same outcomes; lock-failure goes through the catch path silently (logDebug only, no onSyncError noise); real errors still surface via onSyncError. Updates the regression test to throw `LockUnavailableError` (the real contract surfaced to `FileWatcher` by `CodeGraph.watch()`), and asserts `onSyncError` stays quiet during the lock-held cycle. Closes #449. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Colby McHenry <me@colbymchenry.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 5 个月前 | |
fix(wsl): keep WSL off Windows' index on /mnt drives, and explain the I/O error (#995) (#2061) When Windows-native and WSL CodeGraph both open the same .codegraph/codegraph.db under /mnt/<drive>/, SQLite's locking and -shm shared memory don't hold across the 9p/DrvFs bridge and WSL fails with a bare "disk I/O error". - A SQLite I/O error on the default index of a WSL /mnt/<drive> project is rewritten (in the SQLite adapter, so every open and query is covered) into the CODEGRAPH_DIR=.codegraph-wsl instruction. MCP answers it success-shaped, and a failed default-project open is reported instead of "no project loaded". - On WSL + /mnt/<drive> with CODEGRAPH_DIR unset, the data dir is resolved per root: an existing .codegraph-wsl/ wins, then an existing .codegraph/ index (kept, no silent re-index), else a fresh index goes in .codegraph-wsl/. `codegraph init` says where it went. Every other host is unchanged. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> | 1 个月前 | |
fix(watcher): a deleted link target no longer pins a CPU core on Windows (#2938) On Windows, libuv reports a watched folder that is being deleted by the folder's own absolute path (\\?\D:\...) and re-arms the read, which fails the same way at once: about 70,000 events in half a second until the stream is closed. The watcher gives each directory link in a project its own recursive stream, so deleting a link's target outside the project started that storm. handleDirEvent joined the absolute name onto the watched folder, got a path that doesn't exist, scheduled a full sync and nothing else. The stream was never closed, the server held a core until restart, and the storm kept re-arming the debounce, so no sync ever ran: the deleted files stayed in the index and later edits never auto-synced. The project root's stream had the same blind spot. Fix: handleDirEvent, which both stream callbacks use, now treats an absolute name as the watched folder itself reporting it is gone. The first such event on a stream arms one check 200 ms later; the rest of the burst finds it armed. The check closes a link's stream when the link no longer leads to the folder it watched (deleted, or pointed elsewhere) and re-reads the tree, whose full sync drops the link's files; a link that leads somewhere live is watched anew. A project root that is gone degrades the watcher with a "project folder was deleted or moved away" reason, which closes every stream. A normal event pays one path.isAbsolute check. Validation (Windows 11, Node 22.22, libuv 1.51): - Raw probe: fs.watch on a junction whose target is deleted gets 70,009 events named \\?\<the junction> in 500 ms (499 ms CPU), and none after close(). - Real MCP server over a project with a junction libs -> outside, outside deleted: main used 3484, 3406, 3391, 3281 ms of CPU per 3 s window and kept the linked symbol; an edit afterwards never synced. With the fix: 296, 0, 0, 79 ms; the linked symbol left the index; the edit synced. - New watcher tests: a fake fs.watch link storm (10,000 self-named events cost no fs call, the stream closes once, a full sync runs, the project stays watched), a fake root storm (degrades once, closes the stream), and a Windows-gated real junction whose storm must go quiet. All 3 fail on main's watcher.ts; watcher.test.ts passes 61/61. Reported in PR #2487 by @L0garithmic; this reimplements the fix independently. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> | 1 天前 | |
fix(worktree): a linked worktree is recognized however Windows spells its path (#2937) On Windows one directory has several spellings. VS Code and Cursor pass a lowercase drive letter, NTFS ignores case, a subst drive is a second name for a folder, and long names have 8.3 aliases. git answers with the spelling on disk, but src/sync/worktree.ts compared its paths with the caller's as strings, after a JS realpath that keeps the caller's spelling. The main checkout's git common dir comes back relative (".git"), so it took the caller's spelling while a linked worktree's came back absolute in git's. A worktree inside the indexed checkout, spelled unlike git, failed all four comparisons: - detectWorktreeIndexMismatch found no mismatch, so codegraph status (text and --json) dropped the borrowed-index warning; - nestedRepositoryBelow took the worktree for a different repository, so the MCP tools refused it as unindexed and told the agent not to call codegraph for it again. Fix: the four comparisons now ask whether two paths name one directory, with the identity canonicalProjectRoot already uses (the native realpath, lowercased on Windows), falling back to the JS realpath where the native call fails. Returned paths keep the caller's spelling for display. A nested repository below an index root outside git is still reported, as before. Validation (Windows 11, Node 22): - New Windows-gated tests with a lowercase drive letter, at the helper level and through ToolHandler (search and status, with and without a default project): the 3 behaviour tests fail on main's worktree.ts and pass with the fix. Both files: 32 passed. - Fixture: a checkout with a worktree under .claude/worktrees and an embedded clone, spelled four ways (on-disk, lowercase drive, other capitals, subst drive). Helper verdicts wrong: 6 on main, 0 with the fix. codegraph status warned in 2 of 8 runs on main, 8 of 8 with the fix. The real MCP server refused the lowercase, capitals and subst spellings on main; with the fix it serves all four with the borrowed-index notice, codegraph_status warns, and the embedded clone is still refused. An 8.3 short name (the contributor's case) went from 2 wrong verdicts to 0. Reported in PR #2517 by @nk33-dev; this reimplements the fix independently. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> | 1 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 8 天前 | ||
| 5 个月前 | ||
| 1 个月前 | ||
| 1 天前 | ||
| 1 天前 |