Skip to content

docs(skill): say which worktree a command acts on - #3890

Merged
max-sixty merged 2 commits into
mainfrom
fix/issue-3889
Aug 25, 2026
Merged

max-sixty merged 2 commits into
mainfrom
fix/issue-3889

Conversation

@worktrunk-bot

Copy link
Copy Markdown
Collaborator

Problem

wt finds the repository from the working directory and the worktree from the command's own arguments, but the worktrunk skill never says so — so agents treat the global -C <path> as the worktree selector and layer it on top of a branch argument that already names the target. #3889 measured 144 same-repo wt -C calls across 87 transcripts, most of them redundant.

Solution

Three changes, matching the fix the issue proposes:

  • New "Which worktree a command acts on" section in skills/worktrunk/SKILL.md, placed before the config material so it reads early. Two rules: a command that names a branch already names its worktree, and -C moves the working directory (a different repository, a command with no branch argument, or a caller pinned outside a repo) rather than the worktree selection. Two ✓/✗ pairs from the issue make it concrete.
  • Skill description: extended so it fires while an agent is composing a command — "working out which worktree a wt command will act on, or reaching for the global -C <path> to target one" — not only when editing config or debugging hooks.
  • claude-code.md sentence scoped. The -C endorsement is now explicitly about the marker commands, which "take no worktree argument of their own", with a closing clause pointing at the general case.

Verified against the CLI rather than assumed:

Command Worktree selector -C warranted?
wt switch [BRANCH], wt remove [BRANCHES]... branch argument no
wt step diff --branch, wt step commit --branch --branch no
wt config state marker set --branch --branch, but cwd must be in the repo yes, when the host pins cwd outside
wt merge, wt step rebase|squash|push none — [TARGET] is the merge target yes

Also confirms the issue's second example: wt switch --create's --base already defaults to the default branch, so -C /path/to/repo "so it bases off main" changes nothing.

Not included

The issue's second suggestion — a paragraph on the -C doc comment in src/cli/mod.rs — is left out deliberately, as the issue itself flags it as "worth weighing separately": it regenerates the Global Options block on every command page and a large number of test_help snapshots. Happy to follow up if you want it.

Testing

cargo test --test integration test_docs_are_in_sync regenerated the four mirrors (skills/worktrunk/reference/claude-code.md, both plugin-skill copies, and the .well-known digest + description) and passes on a second run. cargo test --test integration readme_sync (16 tests) and test_plugin_layout_is_consolidated are green. The root-relative /switch/ and /remove/ links expand to https://worktrunk.dev/... in the skill copy as expected.


Closes #3889 — automated triage

@worktrunk-bot worktrunk-bot left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two factual problems, both in the assertion the PR is built around. Verified against wt config state marker set --help / marker clear --help and require_selected_branch in src/git/repository/worktrees.rs.

claude-code.md now contradicts the SKILL.md section this same PR adds. The new clause says the marker commands "take no worktree argument of their own" — but wt config state marker set and marker clear both take --branch <BRANCH>, the very next sentence of the same bullet describes it, and rule 1 of the new "Which worktree a command acts on" section lists wt config state marker set --branch <branch> as a command that already names its worktree. The trailing "That pairing is specific to commands with no worktree selector" repeats the error and drops marker from its branch-naming list. The real reason a pinned-elsewhere host needs -C here is the one rule 2 already gives: the repository lookup still comes from the working directory. That's a stronger scoping than the invented one, and it doesn't leave an agent concluding --branch isn't available on the marker commands — which is the redundant--C reach #3889 counted.

The path-alias sentence over-reaches on one of its four commands. marker set/clear resolve --branch through require_selected_branch, which returns GitError::DetachedHead for ResolvedWorktree::Worktree { branch: None } — a marker is keyed by branch name, so there's nothing to key. The other three do handle it: wt step diff --branch goes through require_worktree (takes Worktree { path, .. }), and wt remove matches Worktree { path, branch: _ } and removes by path.

Everything else checks out. I re-verified each row of the PR body's table against --help — [TARGET] on merge/step rebase|squash|push is the merge target with no worktree selector, switch --base does default to the default branch, ../<repo>.<branch> matches the documented default layout — and the sync taxonomy is right: the two primaries (docs/src/content/docs/claude-code.md, skills/worktrunk/SKILL.md) are edited, the three mirrors are generated, the .well-known digest matches sha256sum skills/worktrunk/SKILL.md, and test_docs_are_in_sync passes locally.

Suggestions are on the primaries only; the mirrors and digest regenerate from cargo test --test integration test_docs_are_in_sync. I'll push these myself shortly since this is a bot-authored PR with no human author waiting — flagging them here first so the review records the state they respond to.

Comment thread docs/src/content/docs/claude-code.md Outdated
Comment thread skills/worktrunk/SKILL.md Outdated
The new claude-code.md clause said the marker commands "take no worktree
argument of their own", but wt config state marker set/clear both take
--branch, the next sentence of the same bullet describes it, and rule 1 of
the new SKILL.md section lists it. Recast the reason as the one that is
actually true: --branch names the branch, but the repository lookup still
comes from the working directory, which is why a pinned-elsewhere caller
needs -C.

Also scope the path-alias sentence: marker resolves --branch through
require_selected_branch, which errors on a detached worktree because the
marker is keyed by branch name. switch, remove, and step diff --branch all
do accept a detached worktree by path.
@max-sixty
max-sixty merged commit a0cea60 into main Aug 25, 2026
44 checks passed
@max-sixty
max-sixty deleted the fix/issue-3889 branch August 25, 2026 16:20
social4hyq pushed a commit to social4hyq/homebrew-core that referenced this pull request Sep 20, 2026
worktrunk 0.75.0

Created-by: HarmonybrewBot
Commit-by: HarmonybrewBot
Merged-by: HarmonybrewBot
Description: Created by `brew bump`

---

Created with `brew bump-formula-pr`.<details>
  <summary>release notes</summary>
  <pre>## Release Notes

### Improved

- **The `wt switch` picker opens on one unified diff**: local rows combine committed, staged, unstaged, and untracked changes. Tab skips empty subsidiary views, while `Alt-1` through `Alt-8` retain direct access. [Docs](https://worktrunk.dev/switch/#interactive-picker) ([#3865](max-sixty/worktrunk#3865))

- **Git 2.43 is now the minimum supported version**: older Git exits with an upgrade message before Git-dependent commands run; `wt config shell` remains available so shell startup continues. (Breaking.) ([#3895](max-sixty/worktrunk#3895))

### Fixed

- **`wt list` no longer grows `.git/objects` during advisory conflict checks**: untracked content stays visible but is excluded from synthetic trees, and all probe-only objects use temporary storage. ([#3906](max-sixty/worktrunk#3906), fixes [#3883](max-sixty/worktrunk#3883), thanks @srobroek for reporting and the original fix)

- **`HEAD±` counts untracked files without inflating moves**: `wt list`, the picker, and statusline include untracked lines. Tracked deletions paired with untracked destinations count as renames, so pure moves are line-neutral and edited moves show only their edits. `HEAD±` now always detects renames, regardless of `diff.renames`. ([#3925](max-sixty/worktrunk#3925))

- **Timed child processes no longer abort `wt` in restricted sandboxes**: `wt switch --create`, picker pagers, and other bounded commands survive denied signal-handler wakes. TERM→KILL cleanup also returns promptly once the process group is gone. ([#3857](max-sixty/worktrunk#3857), [#3887](max-sixty/worktrunk#3887), fixes [#3856](max-sixty/worktrunk#3856), thanks @tomascamargo for reporting)

- **JSON list output ignores display-column gates**: `[list] columns` no longer makes `wt list --format json` contact a forge or generate summaries. CI requires `--full`; summaries also require `[list] summary = true` and a configured generator. (Breaking: schema 1 loses config-driven `ci` and `summary` fields.) ([#3812](max-sixty/worktrunk#3812), thanks @emeren for the request)

- **Long Windows paths compare consistently**: paths beyond 260 characters could retain a `\\?\` prefix and appear to be on another drive. `copy-ignored` then refused them, while switch, remove, merge, and relocate landed at the worktree root instead of the original subdirectory. ([#3899](max-sixty/worktrunk#3899), fixes [#3898](max-sixty/worktrunk#3898), thanks @Persedes for reporting and verifying the fix)

- **Shell configuration rechecks before it writes**: overlapping installs lock and reread rc files; Fish completion installs preserve files created after preview; uninstall applies only previewed rc removals and rejects changed Worktrunk-owned files. ([#3853](max-sixty/worktrunk#3853), [#3924](max-sixty/worktrunk#3924))

- **`-vv` profiles exclude their own collector commands**: command counts and cache summaries no longer include duplicate-looking work performed only to assemble the diagnostic report; raw traces still retain it. ([#3900](max-sixty/worktrunk#3900))

- **Fenced HTML comments survive picker Markdown rendering**: PR descriptions and comments now preserve fenced `<!-- … -->` lines; fenced `<!-- wt list … -->` markers also no longer affect the following block. ([#3908](max-sixty/worktrunk#3908))

### Documentation

- **Agent CLIs without a plugin can publish activity markers**: the integration guide now specifies the session-start, turn-end, and session-end calls, working-directory requirement, error guard, and cleanup contract. [Docs](https://worktrunk.dev/claude-code/#agent-clis-without-a-plugin) ([#3848](max-sixty/worktrunk#3848), thanks @AsafMah for requesting generic-agent guidance and @ortonomy for the related Pi use case)

- **Agent guidance explains worktree selection**: commands that name a branch already select its worktree; `-C` changes repository context and is needed only for commands without a worktree selector or callers outside the repository. ([#3890](max-sixty/worktrunk#3890))

- **The `wt up` recipe safely updates dirty worktrees**: it fetches all remotes, fast-forwards dirty branches without autostash, rebases clean branches, and continues past an ordinary refusal or a failed remote. [Docs](https://worktrunk.dev/extending/#recipe-rebase-every-worktree-onto-its-upstream) ([#3882](max-sixty/worktrunk#3882))

- **The docs site has a new responsive design**: rebuilt on Astro and Starlight while preserving public routes, anchors, and crawler URLs; generated reference pages remain synchronized. ([#3866](max-sixty/worktrunk#3866))

### Internal

- **Library API rework** (Breaking library API): `BranchDiffSpec` gained `working_base`, while remote-URL, shell-path, branch-push, approval, temporary-index, and repository helpers were removed. ([#3833](max-sixty/worktrunk#3833), [#3853](max-sixty/worktrunk#3853), [#3865](max-sixty/worktrunk#3865), [#3866](max-sixty/worktrunk#3866), [#3875](max-sixty/worktrunk#3875))

- **Codex loads repository maintainer skills**: `.agents/skills` now exposes the canonical `.claude/skills` tree; checkouts without symlink support keep the existing limitation. ([#3903](max-sixty/worktrunk#3903))

## Install worktrunk 0.75.0

### Install prebuilt binaries via shell script

```sh
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-installer.sh | sh && wt config shell install
```

### Install prebuilt binaries via powershell script

```sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
```

### Install prebuilt binaries via Homebrew

```sh
brew install worktrunk && wt config shell install
```

## Download worktrunk 0.75.0

|  File  | Platform | Checksum |
|--------|----------|----------|
| [worktrunk-aarch64-apple-darwin.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-aarch64-apple-darwin.tar.xz) | Apple Silicon macOS | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-aarch64-apple-darwin.tar.xz.sha256) |
| [worktrunk-x86_64-apple-darwin.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-x86_64-apple-darwin.tar.xz) | Intel macOS | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-x86_64-apple-darwin.tar.xz.sha256) |
| [worktrunk-x86_64-pc-windows-msvc.zip](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-x86_64-pc-windows-msvc.zip) | x64 Windows | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-x86_64-pc-windows-msvc.zip.sha256) |
| [worktrunk-aarch64-unknown-linux-musl.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-aarch64-unknown-linux-musl.tar.xz) | ARM64 MUSL Linux | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-aarch64-unknown-linux-musl.tar.xz.sha256) |
| [worktrunk-x86_64-unknown-linux-musl.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-x86_64-unknown-linux-musl.tar.xz) | x64 MUSL Linux | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.75.0/worktrunk-x86_64-unknown-linux-musl.tar.xz.sha256) |



### Install via Cargo

```sh
cargo install worktrunk && wt config shell install
```

### Install via Winget (Windows)

```sh
winget install max-sixty.worktrunk && git-wt config shell install
```

### Install via AUR (Arch Linux)

```sh
paru worktrunk-bin && wt config shell install
```
</pre>
  <p>View the full release notes at <a href="https://github.com/max-sixty/worktrunk/releases/tag/v0.75.0">https://github.com/max-sixty/worktrunk/releases/tag/v0.75.0</a>.</p>
</details>
<hr>

See merge request: Harmonybrew/homebrew-core!17938
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated-fix Automated CI fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agents reach for -C to target another worktree, where a branch argument would do

2 participants