feat: in-repo .worktrees/ mode#388
Conversation
Adds the design spec for an opt-in worktree location mode that places new worktrees at <repoPath>/.worktrees/<name> instead of inside the global workspaceDir. Includes detect-and-prompt handling for the repo's .gitignore, a small refactor of computeWorktreePath to fold in path-traversal validation, and a two-tier segmented picker in the Workspace settings section.
Bite-sized TDD plan with 18 tasks plus pre-flight, covering types, gitignore module, computeWorktreePath refactor, IPC handlers, preload bridge, AddWorktreeDialog wiring, GeneralPane picker, and a manual smoke test pass. Reviewed against the design spec by both self-review and an independent Opus pass.
Brings the focus-follows-mouse feature plus incidental titlebar and terminal scrollbar fixes into main for local use while PR stablyai#389 is in review against stablyai/orca upstream. The titlebar cleanup and scrollbar fix commits are NOT in the upstream PR because they depend on local structural changes (in-repo-worktrees PR stablyai#388 and the previously-reverted tabs-system PR) that aren't yet on upstream main. They will follow in a separate PR once upstream catches up.
|
This is a good feature. Will try to help land it tmr |
|
@nwparker can you help review this? |
|
@Jinwoo-H or @brennanb2025 would you be able to review this? |
|
could this reviewed and merged please |
|
@sasha-id , sorry for the delay. We'll work on it It makes sense. @brennanb2025 if you can priortize this as next in line. You can help resolve merge conflicts here too |
|
Hi @sasha-id, really appreciate the work on this. I've opened #1010 to discuss whether we want to support this in-repo worktree feature, as while it is a valid design, I noticed a few possible issues with agent confusion.
Would love to hear any suggestions or comments you have about this feature there — there may be mitigations for the failure modes I raised that I'm missing. Leaving this PR open for now. Thanks! |
|
Replaced by #1129 — closing this in favor of the cleaner version. Why a new PR rather than a force-push: This branch was forked from main when upstream was at v1.1.7. Current upstream has moved ~700 commits ahead and PR #710 replaced One deliberate behavioral simplification: the inline Two bugs caught in self-review and fixed in #1129 (with new integration tests pinning the regression):
The original branch ( |
Summary
worktreeLocation: 'external' | 'in-repo'setting that creates new worktrees at<repoPath>/.worktrees/<name>instead of inside the globalworkspaceDirWorkspace DirectoryandNest Workspacescontrols render only in External mode.gitignoredoesn't already ignore.worktrees/, the create dialog shows an inline confirmation pane with[Cancel]/[Create anyway]/[Add and create]computeWorktreePathto fold the three modes (external-flat, external-nested, in-repo) into one function with internal validation, eliminating duplicated WSL+validation blocks in two call sites (worktrees.tsandorca-runtime.ts)Design + plan
docs/in-repo-worktrees-design.mddocs/in-repo-worktrees-plan.mdBoth went through brainstorming → spec self-review → independent Opus review → fixes → user approval before implementation.
What's new for users
[External directory | In-repo .worktrees/]<repo>/.worktrees/<name>worktree,location,in-repo,.worktrees,gitignore)Architecture notes
src/main/git/gitignore.ts(new) — Pure parsing (isWorktreesDirIgnoredByGitignore,appendWorktreesEntry) plus IO wrappers (readGitignore,isWorktreesDirIgnored,addWorktreesDirToGitignore). Parser uses exact-string matching against the four canonical root patterns; intentionally does NOT trim whitespace because git treats it as significant.src/main/git/repo.ts— NewisBareRepo()sync helper, used by the gitignore IPC to short-circuit prompting on bare repos.src/main/ipc/worktree-logic.ts—computeWorktreePathrefactored with three explicit branches; new privateensureWithinRoothelper accepts explicit path operations so UNC paths validate correctly on Linux CI; in-repo branch runs first and short-circuits the WSL special case.src/main/ipc/worktrees.ts+src/main/runtime/orca-runtime.ts— Both callers collapsed from ~10 lines (WSL root selection + standalone validation call) to a singlecomputeWorktreePath()invocation. The CLI runtime caller was a discovery during implementation — the plan only listedworktrees.ts.src/main/ipc/worktrees.ts— Two new IPC handlers:gitignore:checkWorktreesIgnored(fail-open on read errors) andgitignore:addWorktreesEntry(idempotent).src/preload/index.ts+index.d.ts— Newgitignorenamespace onwindow.api.src/renderer/src/components/sidebar/AddWorktreeDialog.tsx—handleCreatesplit intohandleCreate(decision/gate) andperformCreate(action body). NewpendingGitignoreConfirmstate. Inline confirmation pane is a separateif (...) return <Dialog>early return rather than a stacked modal. Suggested-name pool now considers in-repo mode as per-repo just like nested external mode (parameter renamed fromnestWorkspacestoperRepoNamePool).src/renderer/src/components/settings/GeneralPane.tsx— Two-tier picker; existing controls hidden (not disabled) when in-repo mode is on. Picker pattern mirrors the existingbranchPrefixsegmented control.Test plan
Automated:
isBareRepo(3 tests, mocks git rev-parse)gitignore.tspure parsing (13 cases including 2 regression guards for whitespace handling)gitignore.tsIO wrappers (7 cases usingmkdtempfor real fs)computeWorktreePathin-repo mode (4 cases) + WSL+in-repo regression test that asserts WSL helpers are NOT calledgitignore:checkWorktreesIgnoredandgitignore:addWorktreesEntry(7 cases usingmkdtemp)pnpm run typecheckclean across all 3 tsconfig targetspnpm run lintclean (0 warnings, 0 errors)Manual (smoke test — please run before merge):
.gitignoredoes NOT already contain.worktrees/, create a new worktree in in-repo mode → confirmation pane appears<repo>/.worktrees/<name>and.gitignoregains a single.worktrees/line.gitignoreuntouched (the new files will appear as untracked, as expected)Caveats — please read
Subagent reviews skipped after Task 2. The Anthropic API was overloaded for most of the implementation run, so per-task spec/quality reviewer dispatch failed. Tasks 3-17 were executed inline with TDD, full test suite + lint + typecheck after every commit, but no second pair of eyes verified them mid-flight. A pre-merge code review on this PR is the right place to catch anything I missed.
Plan deviation:
orca-runtime.tswas refactored too. The plan only called for collapsingworktrees.ts:134-142. During Task 5's typecheck I discovered the CLI runtime has the same WSL+validation pattern at line 599. I refactored both and updated the runtime's narrowedRuntimeStoreinterface + test fixtures. Without this, the build would have been broken on the CLI surface.