Skip to content

fix(workspace): discover worktrees nested in boundary dirs - #492

Merged
jahvon merged 1 commit into
mainfrom
fix/worktree-discovery
Oct 13, 2026
Merged

jahvon merged 1 commit into
mainfrom
fix/worktree-discovery

Conversation

@jahvon

@jahvon jahvon commented Oct 13, 2026

Copy link
Copy Markdown
Member

Summary

Dynamic workspace discovery walks past a flow.yaml found under .claude, vendor, third_party, and similar directories inside a registered workspace, so a vendored copy never becomes the workspace. Agent tools put worktrees inside the repo (Claude Code uses <repo>/.claude/worktrees/<name>), so commands run in those worktrees resolved to the registered main checkout and ran its executables instead of the worktree's.

The boundary now exempts linked git worktrees, detected by a .git file whose gitdir contains a commondir. The check doesn't depend on where a tool places its worktrees. Submodules also have a .git file but no commondir, so a vendored submodule stays excluded.

Notable Changes

  • discoveryBoundary accepts any linked-worktree root
  • Resolver specs for a worktree under .claude/worktrees and a submodule under vendor

No ticket

Dynamic workspace discovery skips a flow.yaml under .claude, vendor,
and similar directories inside a registered workspace, so vendored
copies never become the workspace. Claude Code creates worktrees at
<repo>/.claude/worktrees/<name>, so commands run in those worktrees
resolved to the main checkout instead.

A linked worktree (a .git file whose gitdir has a commondir) is now
always a valid root. Submodules have no commondir and stay behind
the boundary.

No ticket
@jahvon

jahvon commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

Verification

  • flow validate passed: generate, lint, unit and e2e tests, schema check
  • Manually: built ./bin/flow and ran flow workspace get in a real Claude Code worktree (tuikit/.claude/worktrees/pin-golangci-lint). v2.3.0 resolved it to the main tuikit checkout; this build resolves it to the worktree. The main checkout still resolves to tuikit.
  • Not verified: the generated-diff step reported "Skipping diff validation" locally, so CI's validate generated is the first real run of that check. No generated files are touched. Windows wasn't exercised; isLinkedWorktree uses filepath throughout.

Worth a close look

  • pkg/filesystem/resolve.go isLinkedWorktree: the commondir heuristic for telling a worktree from a submodule

Out of scope (follow-up)

  • An unregistered worktree is named after its folder, not the workspace it came from, so a self-qualified ref (tuikit/ns:x) inside a worktree still goes to the registered checkout. None of the current workspaces use self-qualified refs; revisit if someone reports one.

@codecov

codecov Bot commented Oct 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/filesystem/resolve.go 85.71% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@jahvon
jahvon merged commit 187d29c into main Oct 13, 2026
17 checks passed
@jahvon
jahvon deleted the fix/worktree-discovery branch October 13, 2026 05:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant