Release Notes
Improved
-
Experimental Azure DevOps support:
wt switch pr:<N>resolves Azure DevOps pull requests via theazCLI — auto-detected fromdev.azure.com/ssh.dev.azure.com/*.visualstudio.comremotes, or pinned with[forge] platform = "azure-devops".wt list --fullsurfaces Azure DevOps PR and pipeline CI status, andwt config show --fullreportsazinstall/auth state when Azure DevOps is the detected platform. Requires theazure-devopsCLI extension. GitHub still wins in mixed-remote setups. (#1256, thanks @mikeyroush; thanks @dlecan for #1144) -
Experimental Gitea support extended to
wt listandwt config show:wt switch pr:<N>already resolved Gitea PRs via theteaCLI;wt list --fullandwt config show --fullnow recognize Gitea repos too —wt list --fullshows a CI indicator (open-PR conflicts plus the PR head commit's combined status, falling back to the branch's latest status when no PR exists) linked to the PR, andwt config show --fullreportsteainstall/auth state. (#1320, thanks @SjB; #2702, #2707, #2732) -
Hooks resolve project config from the worktree they act on — no primary-worktree fallback: Previously
pre-removeread the primary worktree's.config/wt.tomlrather than the worktree being removed, andpost-remove/post-switchread the post-removal working directory's config, so apre-remove(orpost-remove) you added on a feature branch never fired when removing that branch's worktree. Now every hook reads the.config/wt.tomlof the worktree it acts on —pre-remove/post-removeread the removed worktree's config (snapshotted before removal),post-switchreads the destination worktree's — and the approval prompt collects hook commands from that same worktree, so a branch-localpre-removealways appears in the prompt before it runs. A worktree with no.config/wt.tomlruns no project hooks; a present-but-malformed config aborts the operation with the parse error instead of silently using the primary's. (Breaking: removing a worktree no longer runs the primary worktree'spre-remove/post-removehooks unless they're also defined in the removed worktree's.config/wt.toml. For an existing worktree that predates a hook added on the default branch, copy the hook into that worktree's.config/wt.tomlto restore the previous behavior; new worktrees branched off the default branch pick it up as before.) (#2690, #2703, #2714, #2717, #2701, #2708, #2727, #2736, #2748) -
wt config alias showwith no name lists every alias:wt config alias show <name>shows one alias's full definition; with no name it now prints that same○ Alias <name> (<source>):block for every configured alias, in name order.wt --help(andwt step --help) drop the inline aliases table for a compact names-only list that points here. (#2684, #2691, #2688) -
wt switchpicker validates hook templates before creating the worktree: Creating a branch from the picker (Alt-C) now runs the same template pre-flight thatwt switch --createdoes, so a project config with a broken hook template (syntax error, undefined variable) fails beforegit worktree addinstead of after — no orphaned worktree left blocking a re-run with the same name. (#2712) -
wt list --branchesskips a serial graph walk on warm runs: Branch ahead/behind counts for themain↕andRemote⇅columns are now cached SHA-keyed, so a warmwt list --branchesno longer pays the single-threadedgit for-each-ref --format='%(ahead-behind:…)'walk that ran before the parallel task pool opened — on a large repo (rust-lang/rust) that walk was ~40% ofwt list's wall time. The push-remote URL is cached and the local-branch scan is shared withcapture_refs, removing two more duplicatefor-each-refinvocations per render. (#2704, #2718, #2673) -
Claude Code plugin ships the
wt-switch-createskill: Installing the worktrunk Claude Code plugin now provides/wt-switch-create <branch> [task], which callsEnterWorktreeto create (or re-enter — it's idempotent) a worktree in worktrunk's sibling layout (<repo>.<branch>/) and re-roots the current Claude session into it; anything after the branch name runs as the task there. (#2737, thanks @onetom for #2631) -
Paths in warning messages are bold: Config-file-not-found, the legacy-fish-config removal warning, completions-not-configured, and outdated-shell-extension warnings now bold the path they mention, matching the convention used elsewhere. (#2677)
Fixed
-
Ctrl-C against a concurrent alias reports exit code 130, not 143:
wt step <concurrent-alias>interrupted by Ctrl-C could exit with 143 (SIGTERM) instead of 130 (SIGINT) when, under load, wt's SIGINT→SIGTERM escalation timer (200ms) fired before the child finished dying from the SIGINT. wt now records the user's originating signal and reports that as its exit code. (#2724) -
Branch names starting with
-no longer confuse git: A branch literally named-foo(creatable viagit update-ref refs/heads/-foo HEAD) could be misparsed as an option by the git subcommands wt invokes — most visibly the hook-approval gatewt switchruns before creating a worktree at such a ref, which reads.config/wt.tomlviagit show <ref>:…, andwt step relocate'sgit worktree add. User-controllable refs now pass--end-of-options(and--verifyforrev-parse) so git treats them as data. (#2711, #2725, #2738) -
wt switchpicker'salt-rremoval no longer runs unapproved project hooks: The picker's removal path was a parallel reimplementation ofwt remove's teardown that ranpre-remove/post-remove/post-switchhooks unconditionally, bypassing the approval gate every other removal path goes through. The picker now routes through the sharedhandle_remove_output(with asilentflag for the in-skim case) and consults the existing approval state read-only — unapproved hooks are skipped, approved ones run. Removing the current worktree viaalt-ralso registerspost-switchhooks against the home worktree now, matchingwt remove/wt merge/wt step prune. (#2746) -
Nushell and PowerShell shell-extension label:
wt config showand the--dry-run uninstallpreview labeled Nushell and PowerShell inconsistently; they now readshell extension & completionslike Bash and Zsh — Fish is the only supported shell whose completions live in a separate file. (#2699, #2705) -
Bash hook syntax highlighting no longer corrupts paths:
format_bash_with_gutterswapped Jinja{{ }}delimiters for internal placeholders that could collide with text in the command (e.g. a Windows tempdir path), splitting it mid-stream in--helpand snapshot output. The placeholders are now chosen to be collision-free. (#2722)
Internal
- Foreground signal forwarding (Ctrl-C handling for hook pipelines,
wt step for-each, concurrent alias groups) is unified into one module. (#2734) CiPlatformmoved to the library crate and is cached onRepoCache; the "override" framing around[forge] platformis dropped. The "invalid CI platform in config" warning is also deduplicated to once perwt listrun instead of firing per branch. (#2692, #2686)- The remove-hook approval helper is shared across
wt remove/wt merge/wt step prune, and thefor-each-refscan primitive is shared with the remote-inventory cache populated from the snapshot path. (#2709, #2735) - CI fails the build if tests leave files behind in the working tree;
LLVM_PROFILE_FILEdefaults to a temp-dir path when not inherited, keeping coverage runs from dropping*.profrawat the repo root. (#2719, #2730, #2713) codename_indexkeeps its hash inu64before narrowing, so thecodenamefilter picks the same word on 32-bit and 64-bit builds (no-op on 64-bit). (#2667)
Install worktrunk 0.50.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.50.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.50.0/worktrunk-installer.ps1 | iex"; git-wt config shell installInstall prebuilt binaries via Homebrew
brew install worktrunk && wt config shell installDownload worktrunk 0.50.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