Skip to content

feat(source-control): machine-agnostic worktree setup skill (detect -> decide -> install) #398

Description

@kyle-sexton

Summary (epic)

Build a machine-agnostic worktree setup skill/action in the source-control plugin that (1) detects the machine/environment, (2) applies research-backed decision logic to choose the right worktree layout for that machine/project, and (3) installs the chosen convention. The convention must not be hardcoded to any one machine, user, org, or toolset — the skill decides per environment.

Component

plugins/source-control/skills/worktree/** (new setup action, or a sibling setup skill).

Why

Worktree placement is currently inconsistent across tools and undocumented-by-convention. Claude Code's native default (.claude/worktrees/ inside the repo) has real problems (see the double-load issue and the unify issue). The right layout is environment-dependent (does the machine have ghq? gwq? which drive is the dev drive? which OS?), so a static rule is wrong — the skill should detect and decide.

Decision logic to encode (from consensus research; see Sources)

Detect, then choose:

  • Environment probes: OS; presence of ghq (+ ghq root); presence of gwq/wt; available drives / dev-drive; whether the repo is under a recursively-scanned tree (e.g. a chezmoi source dir) that would leak; Claude Code version (for hook-contract pinning).
  • Layout options + tradeoffs (all evidence-tiered):
    • Central external root (outside every source tree, e.g. <dev-drive>:\worktrees\<owner>-<repo>-<branch>): avoids ghq-list pollution, avoids the CC nested double-load, avoids recursive-scanner leaks; requires creation via git worktree add/a manager rather than CC-native. Default recommendation for the "many repos, occasional short-lived worktrees" profile.
    • Per-repo sibling: locality, IDE-native, but pollutes ghq list when the clone lives under the ghq tree (verified) — disqualified where one-folder-per-repo matters.
    • Inside-repo .claude/worktrees/ / .worktrees/: rejected — CC double-load + recursive-scanner leak.
    • Bare-clone hub: niche/experimental, high setup, fights ghq normal clones — not recommended for this profile.
    • gwq central root: same external-root model, tool-assisted; adopt only if worktree volume grows.
  • Windows constraints: keep repo and its worktrees on the same drive letter (cross-drive relative links are impossible — git stores absolute paths, defeating worktree.useRelativePaths); keep the base path short (MAX_PATH); set worktree.useRelativePaths=true when same-drive.
  • Cross-tool reality: there is no git-level knob and no universal unifier; Cursor/Gemini native worktree paths cannot be relocated; document the honest per-tool map, and route manual/CLI worktrees through one root. Codex ($CODEX_HOME/.codex/worktrees) and the babysit fleet root stay exempt (helper-managed, lease-scoped).

Install actions the skill should perform (per chosen layout)

  • Configure the CC WorktreeCreate hook (see the unify issue) with the computed root — after the two empirical gates pass.
  • Set worktree.useRelativePaths=true where same-drive.
  • Wire .worktreeinclude-equivalent local-file copying into the shared helper (the hook bypasses .worktreeinclude).
  • Emit the per-tool map + exemptions as skill output (discoverable), not a drift-prone standalone doc.

Acceptance criteria

  • setup detects: OS, ghq/gwq/wt presence, ghq root, dev drive, recursive-scanner source dirs, CC version.
  • Chooses a layout via the encoded tradeoff logic and explains the choice + limitations to the user.
  • Installs the convention idempotently; safe to re-run; reversible.
  • No hardcoded machine/user/org/drive paths — all derived.
  • Honors exemptions (Codex, babysit) and documents the per-tool map as skill output.
  • Depends on the unify issue (shared helper) and supersedes the stale dotfiles doc (see retire-doc issue).

Sources (consensus research, this session)

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions