Release Notes
Improved
-
Table-form
pre-*hooks run concurrently: A multi-entry table hook ([pre-merge]with several keys) now runs its commands concurrently, completing the cut-over announced in v0.37.0: every hook type has one execution semantic, where table form is concurrent and pipeline form ([[pre-merge]]blocks) is serial. Configs that need ordering should use pipeline form; affected configs have warned on every invocation since v0.37.0, withwt config updateoffering a serial-preserving migration. Two adjacent inconsistencies are also gone:wt hook <post-type>foreground runs of multi-entry table hooks now run concurrently like their background counterpart, and single-entry table aliases write to stdout like the other alias spellings, sowt <alias> | …works for that spelling too. (Breaking: multi-entry table-formpre-*hooks no longer run serially) (#3052) -
CI column shows the PR/MR number and review state: The CI column in
wt list --fulland the statusline shows the branch's open PR/MR reference (#3041on GitHub/Gitea/Azure DevOps,!3041on GitLab) instead of a plain dot: colored by CI status, hyperlinked to the PR, dimmed when stale or draft. Review state folds into the color, with magenta for changes requested and cyan for awaiting review.wt list --format=jsongainsci.numberandci.review_state. (#3041, #3044) -
Hook and alias templates render when each step runs: Templates are syntax-checked before the first step runs and rendered as each step executes, so
{{ vars.* }}always reads fresh values and hooks and aliases share one expansion model. Two consequences: a pipeline step with an undefined variable fails when that step is reached (earlier steps run first), and a template error in a background hook surfaces in the hook log rather than failing the foreground command. The background runner also labels template errors the way the foreground does. (#3042, #3047) -
wt config state cache: The regenerable caches (CI status, branch summaries, git-command caches, hints, thewt switch -target) are consolidated underwt config state cache;cache cleardrops them all without prompting, since everything regenerates.wt config state clear, which also wipes hand-authored markers and vars, now asks for confirmation;--yesskips, and non-interactive runs without--yescancel. Theci-status,hints, andprevious-branchsubcommands are deprecated but still work. (#3027) -
Statusline rate-limit segment: Above 90% of the binding window the segment shows the used percentage (
95%(8:30am–1:30pm)) instead of the pace ratio; near the cap, what's left matters more than the rate. The pace form drops the word "pace" (2.9×(Tue–Tue 5pm)), and-vvlogs each window's inputs and selection to.git/wt/logs/trace.logso the binding-window choice can be reconstructed. (#3057, #3053, #3029) -
/wt-switch-createbranch name is optional: The Claude Code plugin command picks a branch name from the task when none is given, and the skill's workflow is one route (create, then enter) with an error-driven fallback instead of three guarded paths. Worktrees created mid-session persist after the session ends. (#3058)
Fixed
-
Plugin worktree hooks fail before side effects: The Claude Code plugin's
WorktreeCreate/WorktreeRemovehooks validate the payload before runningwt; a malformed payload previously created a branch namednullor could remove the wrong worktree.wt remove's help now documents that the positional argument accepts a worktree path as well as a branch name. (#3058, #3060) -
Waiting-for-input marker covers questions, permission prompts, and turn end: The Claude Code plugin sets the 💬 marker on
AskUserQuestion, permission requests, and turn end. Previously only theNotificationevent set it, which never fires for the built-in question picker (and on some platforms not for permission prompts), so the marker stayed 🤖 while Claude waited. Part of #2916. (#3023, thanks @Ismael for reporting) -
wt list --helpno longer panics when piped: With no detectable terminal width (output piped,COLUMNSunset),wt list --helppanicked with a capacity overflow, and the post-commit diffstat truncated filenames to ~10 characters. Both now handle unknown width. (#3040) -
Deprecation warnings match
wt config update: A config deprecation warning now fires exactly whenwt config updatewould change the file. The old detection and migration logic had drifted in several places:ffandno-fftogether silently droppedno-ff, a scalarforgekey was overwritten by the[ci]migration, an empty[ci] platformmigrated without warning, and an emptyapproved-commands = []could be removed by an unrelated update. (#3055) -
Migrated
[forge]keeps[ci]'s spot: The[ci]→[forge]migration rendered the new section at the end of the file and could drop comments above[ci]; it now takes over[ci]'s position, comments included, sowt config showandwt config updatediffs stay minimal. (#3051) -
wt config state getis read-only: The aggregate dump resolved (and re-cached) the default branch, so running it right afterclearsilently repopulated the cache, and on a cold clone it could hit the network. It now reports the cached value or(none).wt config state default-branch getstill resolves and caches. (#3024)
Documentation
- Reading vs resolving cached state:
wt config state default-branch getresolves and caches; the aggregatewt config state getonly reports the cache. The help text and module docs now state the split. (#3028)
Internal
-
wt switch/wt removeorchestration moved frommain.rsto their command modules, and the hook execution call chain lost two delegation layers. (#3049, #3036) -
Config deprecations are driven by a single rule table; each rule is one function that migrates and reports what it changed. (#3045, #3055)
-
terminal_width()returnsOption<usize>instead of ausize::MAXsentinel, making the no-width case a compile-time concern. (#3043) -
Snapshot tests regenerate identically across machines: host-specific paths are guarded, host-dependent env-block markers are normalized, and help snapshots share one settings builder. (#3009, #3026, #3037, #3061)
-
Nightly CI runs lib tests across the full feature powerset. (#3059)
-
MSRV bumped from 1.94 to 1.95. (#2948)
Install worktrunk 0.58.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.58.0/worktrunk-installer.sh | sh && wt config shell installInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.58.0/worktrunk-installer.ps1 | iex"; git-wt config shell installInstall prebuilt binaries via Homebrew
brew install worktrunk && wt config shell installDownload worktrunk 0.58.0
| File | Platform | Checksum |
|---|---|---|
| worktrunk-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| worktrunk-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| worktrunk-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| worktrunk-aarch64-unknown-linux-musl.tar.xz | ARM64 MUSL Linux | checksum |
| worktrunk-x86_64-unknown-linux-musl.tar.xz | x64 MUSL Linux | checksum |
Install via Cargo
cargo install worktrunk && wt config shell installInstall via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell installInstall via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install