fix: make dependencies available in isolated worktrees - #321
Open
aaroncoville wants to merge 1 commit into
Open
Conversation
An isolated worktree does not include the base checkout's dependencies, so project validation can fail before it checks an agent's change. Link the dependencies after creating the worktree, while preserving existing entries and allowing the spawn to continue if linking fails. Before deciding whether a worker worktree is dirty, remove only a dependency link that resolves to the base checkout's node_modules. This keeps unignored links from preventing automatic cleanup while preserving real directories and foreign links. Use Windows junctions so directory links work without elevated privileges. The regression coverage verifies link creation, skip and failure paths, cleanup without a .gitignore, Windows link selection, and that git worktree removal leaves the base dependencies intact.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Spawning an agent into an isolated worktree gives it a checkout with no
node_modules. Typecheck then fails on missing type definitions and tests and build fail on missing packages.This links the base checkout's dependencies into the worktree right after the worktree is created successfully, and removes that link again before the retention and garbage-collection checks so an untracked entry cannot make a worktree look permanently dirty. An existing entry is left alone, and a link failure is logged without blocking the spawn, so the worst case is the behaviour we already have today.
Two notes for the reviewer. Cleanup only removes an entry that is a symlink and resolves to the base checkout's
node_modulesa real directory, or a link pointing anywhere else, is left alone, and there are tests pinning both refusals. And because the worktree shares the base'snode_modules, annpm installrun inside a worktree writes through the link into the base checkout; that is inherent to sharing rather than copying.Type of change
Evidence
Before
A fresh isolated worktree, running the project's own typecheck:
With the dependency-link step removed, three of the regression tests fail:
After
The same command in the same worktree, with the dependencies linked:
Full suite with the change applied:
How I tested it
mainwith nonode_modulesand rannpm run typecheck— reproduced the twoTS2688errors above.node_modulesand re-ran the identical command in the identical worktree — 0 errors.npm run test:focusedon a clean branch cut frommain: 564/564 (baseline onmainis 552; this adds 12).npm run typecheck— 0 errors.npm run build— succeeds.The deletion guards are covered by name: removing the symlink type check makes
does not remove a real worktree node_modules directoryfail, and removing the resolved-target comparison makesdoes not remove a worktree node_modules link to another directoryfail. Teardown safety was the other case worth being careful about:git worktree remove --forcemust not follow the link and delete the base checkout'snode_modules. Test 556 covers that, and it asserts the symlink exists before the removal runs.Checklist