Release Notes
Improved
-
wt listsizes and aligns its columns to the terminal width: one long branch name no longer sizes the Branch column for every row — it caps at 32 characters and elides, so a narrow terminal keeps its other columns instead of degenerating into a branch list.Remote⇅stops holding blank space open in a repo with no remote, and alignment now follows the value type.--format=jsonstill carries the whole name. (#3998) -
wt listnames what it hid and marks detached worktrees: the summary readshidden: Path, Commitinstead of counting columns, a detached worktree shows⊘rather than borrowing⚑, and a prunable row leaves its cells blank instead of showing loading dots that never resolve. (#3998) -
wt list --format=jsongains amarkerfield and stops reportingdetachedtwice: the branch marker set bywt config state markeris now readable without parsing it out ofsymbols, andstateno longer reports a detached worktree asbranch_worktree_mismatch— the siblingdetachedboolean carries it. (#3998) -
wt list --format=jsonnow defaults to schema 2: callers get the envelope with repository metadata and orthogonal per-item facts without configuring[list] json-schema.wt list statusline --format=jsonfollows the same key. Setjson-schema = 1to retain the original bare-array format. (Breaking.) (#4038) -
wt config showfails on a broken config: it exits 1 on an unreadable or invalid config, an invalid[list] columns, or an invalidapprovals.toml. Unknown keys and deprecations stay warnings and still exit 0. A newAPPROVALSsection counts project commands awaiting approval. (Breaking: it always exited 0 before.) (#3999) -
Config migration output names its destination:
wt config update --output <path>writes the migration artifact to that file instead of applying it in place, and--output=-writes it to stdout. Output mode includes project config when run from a linked worktree. (Breaking:--printwas removed.) (#4021) -
Pi joins the agent integrations:
wt config plugins pi installwrites an activity hook to~/.omp/agent/hooks/pre/worktrunk.ts, so Pi sessions show 🤖/💬 markers inwt listlike Claude Code, Codex, OpenCode, and Gemini.$PI_CONFIG_DIR,$PI_CODING_AGENT_DIR, and named$OMP_PROFILE/$PI_PROFILEprofiles are honored. Docs (#3594, thanks @adity982, and @ortonomy for the request) -
wt config plugins codex installinstalls the plugin too: it previously registered the marketplace and left you to run/pluginsin Codex yourself. Uninstall follows for both Codex and Claude Code, removing the plugin and then the marketplace, so the two commands are inverses. (Breaking: Codex uninstall previously left an installed plugin alone; Claude uninstall now also removes the marketplace.) (#4019) -
wt step copy-ignoredsays whether it reflinked or copied: the summary now reads(reflinked, no extra disk),(full copy), or a partial count, so the same29.5 GBline distinguishes a free copy from one that actually wrote the bytes.--format=jsongainsreflinkedandwritten. (#4025) -
wt config updateremoves keys its destination cannot hold: migrating[select]or[commit-generation]drops keys the new section has no field for, reporting each one. Otherwise the key landed at a path the user never typed and warned on every command, with no way to clear it. (#3994)
Fixed
-
A failed
wt switch pr:<n>against a fork no longer deletes a branch it didn't create: the rollback force-deleted the branch on any setup error, including the one case where the branch wasn't its own — apre-switchhook or a concurrent session claiming the name in the window after the forge answered. Branch and worktree are now created in onegit worktree add -b, which writes nothing when the name is taken. (#3984) -
Codex on Windows: the activity hooks no longer fail on every event: each hook led with a bare
bash, whichcmd.exeresolves to the WSL launcher rather than Git Bash, so every event raised aHook failedbanner. Hooks now runwt.shthrough a shim that finds Git Bash by path. (#4008, fixes #4007, thanks @McNultyyy for reporting and diagnosing) -
Templates leave
branchunset in a detached worktree: aliases and hooks rendered{{ branch }}as the literalHEAD, which git resolves, so an unguarded template ran against the wrong ref — the reported case ended ingit push origin --delete HEAD, which git refused.baseandtargetfollow. (Breaking: an unguarded{{ branch }}now errors.) (#4010, fixes #4009) -
The OpenCode plugin loads under OpenCode 2: OpenCode 2's loader dropped the old bare-function export silently, so activity markers stopped appearing. The plugin now exports one object carrying both the v2
setupand v1serverentry points, and spawnswtthroughnode:child_processrather than the Bun shell. Re-runwt config plugins opencode installto pick it up; the one file covers OpenCode 2 and OpenCode 1.16 or later. (#4018, thanks @pragmaticivan for the request) -
wt step commit --branchbuilds its prompt from the worktree being committed: prompt-building git plumbing ran in the invoking worktree, so with nothing staged there the generated message described none of the changes it committed.wt step relocate --commithad the same bug, and--dry-run/--show-promptnow preview the worktree--branchnames. (#3996) -
LLM commit messages keep diffs for quoted paths: a file whose name git quotes in the
diff --githeader — any non-ASCII name under the defaultcore.quotePath— had its whole diff section dropped from the prompt once the diff exceeded the 100 KB budget. (#4041) -
An unparsable user config is reported, not a panic:
wt config show --format=jsonand--full, pluswt step prune,relocate,eval, andfor-each, panicked on a debug build and printed a bare✗ Command failedon a release one. They now report✗ Failed to load configwith the parser's caret diagram. (#4002) -
wt switch --executenames the directory the program actually starts in: theExecuting (--execute) @ …header rendered the worktree the background hooks run in, not the program's own directory — which differs under--no-cdor a switch from a subdirectory. The path is omitted when the shell already stands there. (#4043, fixes #4042, thanks @yajo for reporting) -
wt config plugins claude|codex uninstallis safe to re-run: removing an already-absent marketplace reported a failure, and a Claude uninstall that removed the plugin and then failed left the marketplace with no way to clear it. Both now finish a half-done uninstall and succeed when there is nothing left to remove. (#4033, #4034) -
wt config state markerset and clear no-op outside a git repository: they exited 1 with a git error, so an agent plugin running outside a repository printed one every turn (the hook's|| truekept the session going). (#3981, thanks @mahirhir) -
wt listproduces output in a bare repo with no worktrees: it printed nothing at all and exited 0. It now reports○ No worktreeswith a hint,--brancheslists the branches, and--format jsonemits the envelope with an emptyitems. (#3992) -
wt listwarns when it can't parse the project config rather than ignoring it silently; the listing still succeeds. (#3993) -
Relayed command output no longer prints ahead of the delayed-stream progress line, and delayed-stream output routes through anstream so color is stripped consistently when redirected. (#4037, #3995)
-
A hook filter that matches nothing names the unconfigured source, rather than reporting no match without saying which source was empty. (#3997)
Documentation
-
wt hooksays thatpost-*hooks from the two sources run concurrently, so dependent commands belong in one source;wt mergerecords thatpost-commitcan't run when the merge removes the worktree it anchors on. (#4020, #4026) -
wt stephelp pages describe what the commands actually do:wt step prunesays it removes branches as well as worktrees,wt step copy-ignoreddocuments--from/--to,wt step commitdocuments--branch, and both it andsquashdocument their hooks and no-LLM fallback messages. (#3997) -
The FAQ lists the files Worktrunk writes outside its own config: OpenCode's plugin, Pi's hook, and the Claude Code
settings.jsonstatusline entry, alongside the existing inventory of what Worktrunk creates and deletes. The Claude and Codex plugin installs write nothing themselves. (#4036) -
wt step copy-ignoreddocuments its disk-space benefit per filesystem, and the bare-repoworktree-pathexample names the bare repo's own location. (#4022, #4006) -
Terminal examples on the docs site fit a desktop window rather than overflowing. (#4039)