docs(skill): say which worktree a command acts on - #3890
Conversation
worktrunk-bot
left a comment
There was a problem hiding this comment.
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.
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.
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
Problem
wtfinds the repository from the working directory and the worktree from the command's own arguments, but theworktrunkskill 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-repowt -Ccalls across 87 transcripts, most of them redundant.Solution
Three changes, matching the fix the issue proposes:
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-Cmoves 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.description:extended so it fires while an agent is composing a command — "working out which worktree awtcommand will act on, or reaching for the global-C <path>to target one" — not only when editing config or debugging hooks.claude-code.mdsentence scoped. The-Cendorsement 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:
-Cwarranted?wt switch [BRANCH],wt remove [BRANCHES]...wt step diff --branch,wt step commit --branch--branchwt config state marker set --branch--branch, but cwd must be in the repowt merge,wt step rebase|squash|push[TARGET]is the merge targetAlso confirms the issue's second example:
wt switch --create's--basealready 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
-Cdoc comment insrc/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 oftest_helpsnapshots. Happy to follow up if you want it.Testing
cargo test --test integration test_docs_are_in_syncregenerated the four mirrors (skills/worktrunk/reference/claude-code.md, both plugin-skill copies, and the.well-knowndigest + description) and passes on a second run.cargo test --test integration readme_sync(16 tests) andtest_plugin_layout_is_consolidatedare green. The root-relative/switch/and/remove/links expand tohttps://worktrunk.dev/...in the skill copy as expected.Closes #3889 — automated triage