หน้านี้รวบรวม worktrunk ไว้ 126 เวอร์ชัน ตั้งแต่ 16 ธันวาคม 2568 จนถึงเวอร์ชันปัจจุบัน v0.81.0 ทุกเวอร์ชันลิงก์ไปยังไฟล์ตัวติดตั้งของผู้เผยแพร่เอง
| เวอร์ชัน | วันที่ | ขนาด | ไฟล์ |
|---|---|---|---|
| v0.81.0ล่าสุด | 20 ตุลาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Hooks can prompt: hooks that run serially in the foreground (pre-* hooks, wt hook <type> --foreground) inherit wt's stdin, so gum confirm 'trust this worktree?' && mise trust works as a hook. Concurrent and background hooks read EOF. (Breaking: hooks no longer receive their context as JSON on stdin; pass values as template arguments, or whole objects with the new tojson filter. wt step for-each keeps its JSON.) Docs (#3129, #4451, #4524, thanks @endigma for #3093)
- Experimental wt switch --path: places one worktree outside the worktree-path template and keeps its branch name, as in wt switch --create feature/JIRA-1234 --path ../dark-mode. Commands reach it by branch or by path. Docs (#4317, thanks @christowiz for #1982)
- wt merge --branch: merges another worktree's branch without leaving the current worktree. Commit, squash, rebase, and hooks run in the source worktree, and cleanup removes it. Docs (#4360, thanks @liuyinchu)
- OpenCode 2 worktrees go through Worktrunk: after re-running wt config plugins opencode install, worktrees OpenCode creates and removes use wt switch --create and wt remove, as the Claude Code plugin's do. OpenCode's worktree.directory stops applying, and new branches start from the default branch. Like the Claude Code plugin, it opens an existing branch's worktree, which OpenCode's remove then removes. Docs (#4489, thanks @rzane for #4488)
- Faster bulk removal: removal hands files to one background deleter per repository, not one rm -rf each, and deletes read-only directories it used to leave in .git/wt/trash. wt step prune no longer stalls when two worktrees share a directory name, as Codex worktrees do. (Breaking: prune runs pre-remove hooks concurrently; hooks writing shared state must coordinate.) (#4516, #4361, #4337)
- wt switch - returns to the worktree it left, including a detached worktree or the second checkout of a branch, and wt remove - targets the same worktree. Pre-switch hooks see the resolved destination, so wt switch origin/feature passes branch=feature. (Breaking: from a bare repository's directory, commands given no argument act on the worktree of the branch HEAD names.) (#4497, #4496, #4521)
- Template errors name the variable: {{ brnch }} reports undefined variable brnch and suggests branch. (Breaking: filters such as sanitize reject an undefined input, so {{ upstream | sanitize }} needs a guard or default on a branch with no upstream.) (#4350, #4440)
- Templates use MiniJinja 3 (Breaking): objects and lists render Python-style ({'port': 3000}) instead of as JSON, so use | tojson where JSON is needed; round rounds half to even; title capitalizes fewer word boundaries (feat/x-y becomes Feat/x-Y); division by zero errors. (#4442, #4524)
- CI status shows ⚠ for any failed forge call, where some failures, such as a Gitea 404, used to leave the cell blank. A forge CLI with no login for the host still leaves it blank, and wt config show --full names the host it checked. (#4436, #4449)
- Removal explains itself: --force lists the changes it discards, and a refusal over untracked files suggests git stash -u. A multi-target wt remove continues past a target whose pre-remove hook or removal fails, and exits 1. A branch-only removal names the detached worktree left at the branch's path. (#4347, #4357, #3791, #4313, thanks @chachi for #3769)
- The picker can open without its preview: [switch.picker] preview = false hides it until Alt-p. (#4428, thanks @emacampolo for #4072)
- Squash backups print a recovery command: squashing staged changes prints the refs/wt-backup/<branch> ref and a wt switch --create --base <sha> command that restores them in a new worktree, even after wt merge removed the original. (#4347)
- Shell integration: wt merge and wt remove suggest restarting the shell when integration is installed but inactive. On Unix, the PowerShell profile comes from the installed pwsh, so a custom XDG_CONFIG_HOME works. (Breaking: installing for Nushell requires nu, |
| v0.80.0 | 27 กันยายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt list and the wt switch picker settle faster in repos with many worktrees: rows fill from the top down, and on macOS with core.fsmonitor=true no daemon start is forked for a worktree whose daemon is already running. On a 50-worktree repo the picker's per-row work starts at 47ms, down from 120ms. (#4286, #4290, #4288, #4284)
- CI status skips branches that were never pushed: wt list --full, the picker, and the statusline no longer query the forge for a local branch no remote has, so a repo with 239 local branches made 25 gh calls instead of 249. A PR opened from a branch another clone pushed shows once you fetch. GitLab looks up its project ID once per command, not per row. (#4289, #4216)
- Leaner Codex commit generation: the recommended Codex command moves to gpt-6-luna with reasoning off and unneeded Codex features disabled, so each message sends fewer input tokens. Accepting the first-run Codex prompt now also creates ~/.codex/worktrunk-commit-instructions.txt, which the command reads. Docs (#4261)
- Releases ship a signed packslip: each GitHub release includes packslip.sigstore.json, a manifest of the archives' digests, platforms, completions, and agent skills, signed by the release workflow so installers such as mise can verify downloads before unpacking. (#4301, thanks @jdx)
Fixed
- A squash whose commit fails keeps the branch: when a git commit hook or signing stopped the commit in wt merge or wt step squash, the branch was left at the merge base with its changes staged, recoverable from the reflog. Now the branch is untouched. (Breaking: git commit hooks run on a detached HEAD during a squash.) (#4206, thanks @Bennyjitsu for finding it in #4193)
- wt step diff when local main lags origin/main: for a branch built on the newer origin/main, the diff included the upstream commits in between. It now uses the same base as wt merge. (#4281, thanks @starlightromero, whose #3519 reported the same case for wt merge)
- Submodules with an ignore setting: when submodule.<name>.ignore or diff.ignoreSubmodules hid uncommitted changes inside a submodule, wt remove and wt step prune read the worktree as clean and removed it along with them; they now keep it. With ignore=all, wt step commit and squashes now commit a staged submodule pointer instead of leaving it staged. (#4252, #4192, #4206, #4303, thanks @Duang777)
- Worktrees whose .git was deleted but whose directory remains (macOS $TMPDIR cleanup can do this): wt remove <branch> failed, and wt step prune skipped or errored on them. Both now unregister the worktree and leave its files; one with staged changes or an operation in progress is kept by wt step prune, and refused by wt remove without --force. (#4228, #4226, #4302)
- wt merge --no-squash with a stage mode that stages nothing: with --stage=none and only unstaged changes, --stage=tracked and only untracked files, or only dirty submodule contents, it stopped at "Nothing to commit"; it now merges the branch's commits. (#4251, thanks @Duang777)
- Nushell 0.116: the first wt tab completion in each session printed a Positional completer input deprecated warning. The completer now takes Nushell's new input and still works on older versions. (#4297)
- Hook-log JSON's branch field: wt config state logs --format=json put the sanitized log directory name (feature-x-x2d) there; it now holds feature/x, or null when no local branch owns the directory. (Breaking: filters on the sanitized form need updating.) (#4279)
- wt config show --full outside a git repository: it printed only a git rev-parse failure; it now shows the user config and diagnostics. (#4255)
- Fixes for unusual git setups: --no-ff merges are signed when commit.gpgSign is set without a value or only for one worktree; after git worktree repair, --separate-git-dir repos put worktrees beside the work tree and wt remove works (fixes #4235); removing an orphan worktree before its first commit no longer errors; with a custom merge driver, leaving the pic |
| v0.79.0 | 21 กันยายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch --no-cd -x <program> runs the program in the worktree: it started in the invoking directory, so a program meant for the new worktree had to be handed {{ worktree_path }}. --no-cd now governs only your shell — wt switch feature --no-cd -x code -- . opens the worktree in an editor and leaves your terminal put. (Breaking: a program that wanted the invoking directory needs an explicit cd.) Fixes #4042. (#4179, thanks @yajo for reporting)
- The picker's preview tabs show which have content: a tab's label is dim when that tab is empty for the selected row, and underlined when it's the active tab. Availability sat on the tab's number alone, so every inactive label read dim whatever the row held. (#4174)
- Messages name the destination, and end with the command to run: without shell integration, wt merge and wt remove printed Cannot change directory — shell integration not installed and no path; the warning now names the worktree, as wt switch already did. "Cannot determine default branch" had three wordings, and three recovery hints put their command first rather than last. (#4163, #4155, thanks @blrain3 for reporting)
- /wt-switch-create no longer stalls at Claude Code's path-entry dialog: Claude Code confirms every entry outside .claude/worktrees/, which is every Worktrunk worktree, so a background session waited for someone to attach. The plugin now approves entry into a worktree at its worktree-path location, and reads a bare name as the repo or the branch. (#4158, #4159)
- wt config update --output accepts the config being migrated: it refused that path when the migration dropped approved-commands. Those approvals now move to approvals.toml first, exactly as the in-place update moves them. (#4204)
Fixed
- wt merge on a dirty worktree describes what it commits: the generated message covered the branch's earlier commits and said nothing about the work the merge had just staged into the same commit. wt step squash --dry-run now previews what the run would commit, as wt step commit --dry-run does. (#4178)
- A config save no longer rewrites the rest of your config: declining a prompt, or setting the commit-generation command, rewrote the whole file, dropping values written at their default and re-spelling hook pipelines and dropping their comments. It also reloaded that file over the in-memory config, so wt step commit --config-set 'commit.stage="none"' staged everything once it had asked about commit generation. (#4160, #4156, #4151)
- Diff display config no longer reaches Worktrunk's prompts or its integration check: color.ui = always and diff.external reached the commit, squash, and summary prompts. Two corner cases also made wt remove and wt step prune delete an unmerged branch: diff.relative set and a Worktrunk command run from a subdirectory the branch's changes sat entirely outside, or submodule.<name>.ignore = all (git config or .gitmodules) and a submodule bump as its only change. (#4146, #4147)
- Auto-staging names a wholly untracked directory once: since 0.78.0 the warning expanded each one into its files, so wt step commit, wt step squash, and wt merge listed 300 paths for a directory of 300 new files. The listing also stops at ten rows, with a hint counting the rest. (#4152, thanks @Duang777)
- Valid empty per-project sections stop warning: [projects."host/org/repo".list] is accepted on load, yet every command reported unknown field projects.host/org/repo.list for it — as did the other six per-project sections. Fixes #4115. (#4123, thanks @zach-hammad-vs for reporting)
- An unstaged rename counts as a change: after git add -N, git reports the rename in the worktree column ( R), which Worktrunk read only in the index column. A worktree whose only change was such a rename showed clean in wt list, and wt merge's overlap check on the destination misparsed the old path. (#4190, #4191, thanks @Duang777)
- wt merge --no-ff and wt step push --no-ff sign their merge commit under commit.gpgSign: |
| v0.78.0 | 16 กันยายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Hook scripts read renamed context keys: the JSON piped to every hook drops worktree, repo_root, main_worktree, and main_worktree_path in favour of worktree_path, repo_path, repo, and primary_worktree_path. Config templates migrate on load, so hooks written with the old names keep working; scripts reading the JSON, --execute templates, and --var overrides need updating. (Breaking.) (#4080)
- wt config plugins pi installs for Pi; oh-my-pi moves to wt config plugins omp: pi install wrote an oh-my-pi hook, which Pi never loads; Pi users re-run it to get a Pi extension. Existing oh-my-pi hooks keep working, listed as outdated until wt config plugins omp install. (Breaking: scripts that run wt config plugins pi for oh-my-pi need omp.) Docs (#4135, thanks @ashebanow)
- Interactive prompts no longer open with a blank line: wt config shell install, wt config plugins claude install, and the commit-message setup offer in wt merge began with one. (#4059)
- wt config show gives a single wt config shell install hint: an outdated wrapper, a fish wrapper at the deprecated conf.d path, and missing fish completions each printed their own hint. The zsh compinit snippet is now syntax-highlighted. (#4059)
- wt config update --output <path> confirms the write: it now prints ✓ Wrote user config migration @ ~/migrated.toml where it printed nothing. --output=- stays silent. (#4053)
Fixed
- Removal no longer discards untracked files hidden by status.showUntrackedFiles = no: under that setting, a worktree holding only untracked files looked clean, so wt remove, wt merge, and wt step prune removed it without --force. Safety checks now always count untracked files, and auto-staging warnings list every file they stage. (#4111, thanks @Duang777)
- wt remove and wt merge check the right worktree under an inherited GIT_DIR: run from a !wt git alias or a git hook, which pass GIT_DIR down, wt remove could delete a dirty worktree without --force, and wt merge could refuse a clean merge. Both now check the worktree they act on. (#4082, thanks @Duang777)
- wt merge no longer deletes a worktree locked with git worktree lock: the merge completes and prints Worktree preserved (locked). Every Worktrunk removal refuses a locked worktree, even with --force; run git worktree unlock <path> first. (#4073, thanks @Duang777)
- wt config update no longer overwrites a config edited while its prompt is open: it wrote the pre-prompt snapshot over the newer file and reported success. It now fails with the path and leaves the newer file; re-running previews the current contents. (#4127, thanks @zach-hammad-vs for reporting)
- wt step prune no longer deletes a branch created minutes ago from an older commit: --min-age aged a branch without a worktree by its commit's date, so a new branch off a day-old commit was pruned on the next run. Age now comes from the branch's oldest reflog entry. (#4077)
- A comment or blank line above an inline config section no longer breaks the config: a save or migration that rewrote commit = { … } as [commit] put that line inside the brackets. wt switch, wt merge, wt remove, and several wt step commands then failed with Failed to load config; wt list warned and ran without the config. Saves also dropped unrecognized keys from inline sections. (#4120, thanks @zach-hammad-vs for reporting)
- Config saves keep the trailing comment on a value they rewrite: a save such as answering the commit-generation offer dropped the comment after each value it rewrote, including one after an inline section's closing brace. (#4138)
- Ignored project-config keys warn from every worktree: an unknown key in .config/wt.toml, or one that belongs in user config such as [merge], warned only in the main worktree, so wt merge from a linked worktree ignored it silently. (#4145, thanks @ee-prog for reporting)
- wt merge skips post-commit when it removes that hook's worktree: before, the hook ran in the primary worktree when the removed one sat inside the r |
| v0.77.0 | 8 กันยายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt list sizes 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=json still carries the whole name. (#3998)
- wt list names what it hid and marks detached worktrees: the summary reads hidden: Path, Commit instead 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=json gains a marker field and stops reporting detached twice: the branch marker set by wt config state marker is now readable without parsing it out of symbols, and state no longer carries detached — the sibling detached boolean already does. (#3998)
- wt list --format=json now 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=json follows the same key. Set json-schema = 1 to retain the original bare-array format. (Breaking.) (#4038)
- wt config show fails on a broken config: it exits 1 on an unreadable or invalid config, an invalid [list] columns, or an invalid approvals.toml. Unknown keys and deprecations stay warnings and still exit 0. A new APPROVALS section names 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: --print was removed.) (#4021)
- Pi joins the agent integrations: wt config plugins pi install writes an activity hook to ~/.omp/agent/hooks/pre/worktrunk.ts, so Pi sessions show 🤖/💬 markers in wt list like Claude Code, Codex, OpenCode, and Gemini. $PI_CONFIG_DIR, $PI_CODING_AGENT_DIR, and named $OMP_PROFILE/$PI_PROFILE profiles are honored. Docs (#3594, thanks @adity982, and @ortonomy for the request)
- wt config plugins codex install installs the plugin too: it no longer just registers the marketplace, instead of ending with a hint to run /plugins in Codex yourself. Uninstall follows for both Codex and Claude Code, removing the plugin and then the marketplace, so the two commands are inverses. (Breaking: uninstall previously left an installed plugin alone.) (#4019)
- wt step copy-ignored says whether it reflinked or copied: the summary now reads (reflinked, no extra disk), (full copy), or a partial count, so the same 29.5 GB line distinguishes a free copy from one that actually wrote the bytes. --format=json gains reflinked and written; a --dry-run plan no longer reports files/bytes. (#4025)
- wt config update removes keys its destination cannot hold: migrating [select] or [commit-generation] drops keys the new section has no field for, reporting each one, and removes a [projects."<id>"] section the removal empties. 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 your branch: the fork path rolled back by force-deleting the branch on any setup error — including when the branch already existed, so a pre-switch hook or a concurrent session claiming the name cost you that branch and any commits only it held. Branch and worktree are now created in one git 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, which cmd.exe resolves to the WSL launcher rather than Git Bash, so every event raised a Hook failed banner. Hooks |
| v0.76.0 | 1 กันยายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch --execute takes a program, not a shell string: -x names one program, with everything after -- passed as literal argv. Worktrunk spawns it as a child rather than running it in your interactive shell, so shell functions and its cd no longer reach you. -x sh -- -c '…' recovers shell syntax, not functions. (Breaking: existing -x strings, plus WORKTRUNK_DIRECTIVE_EXEC_FILE and WORKTRUNK_SHELL.) (#3977, closes #2860, fixes #3944, thanks @omgreenfield for testing the migration path)
- Worktrunk decides tracking for the branches it creates: a new branch gets an upstream only when its name matches the remote branch it starts from, whatever branch.autoSetupMerge says: --create release --base origin/release tracks, --create feature --base origin/release does not. Under autoSetupMerge = false this previously exited 128 after creating the worktree. (#3913, #3950, fixes #3937, thanks @mjakl for reporting and diagnosing)
- Retired config keys are no longer read: commit.generation.template-file and squash-template-file are gone — put the file's contents in template or squash-template. There is no migration: the key stays, warns as unknown on every load, and the prompt reverts to the built-in default. Setting both template and template-file used to fail the load; it now loads template. switch.picker.timeout-ms likewise warns rather than being stripped. (Breaking.) (#3949)
- Project aliases and hooks can use wt switch --execute: their bodies previously refused it. Worktrunk now starts the program itself instead of handing shell text to your shell, and the command-approval gate remains the control on project-defined commands. (#3977)
- Established automation and LLM customization interfaces are now stable: wt step eval, wt step for-each, wt step prune, LLM branch summaries, wt config state vars, and commit.generation.template-append are no longer marked experimental. (#3949)
- wt step prune stages removals concurrently again: only the git worktree remove teardowns serialize, so dirty checks, fsmonitor shutdown, and the trash rename overlap. The prune_e2e/live benchmark median went from 377 ms to 222 ms. (#3954)
- wt config approvals add reads as a review rather than a warning: it opens with a cyan Review 1 command for repo: instead of a yellow ▲ … needs approval to execute. The execution-time gate is unchanged. (#3953)
Fixed
- The wt switch picker survives a preview longer than 65,535 lines: skim keeps the pane's line count in a u16, so a larger diff aborted wt with exit 101 seconds after it painted — on screen the picker looked like it closed by itself. Panes now cap at 60,000 lines and say so. (#3959, fixes #3958, thanks @sandertammesoo for reporting and diagnosing)
- The nushell wrapper propagates exit codes without a POSIX shell: it reported a failing wt by spawning sh, so on Windows every failing command printed a Command `sh` not found trace and exit 1 whatever the real code was. Nushell's wrapper is a static file, so rerun wt config shell install to pick this up. (#3945)
- The picker no longer shows one detached worktree's diff for another: previews were keyed by branch name, so every detached row shared the key (detached). Rows now key by canonical identity, which also lets wt remove feature ~/repo.feature plan that worktree once instead of failing on the second. (#3926)
- wt switch pr:<n> gives pre-switch hooks the real branch: branch and target held the literal pr:3933, and target_worktree_path was unset even when that branch had a worktree. pr_number and pr_url are now set for same-repo PRs, not only forks. (#3941, fixes #3934, thanks @robsonpeixoto for reporting)
- wt config shell install no longer replaces an rc file created while it was checking: the missing-file path refuses to clobber and fails with a rerun hint. A dangling rc symlink is preserved and rejected rather than overwritten. (#3929)
- wt switch --create X --base pr:<n> works when the PR branch has no local branch: the fetch writes only |
| v0.75.0 | 27 สิงหาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่น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 (#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)
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, fixes #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)
- 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, #3887, fixes #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, 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, fixes #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, #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)
- 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)
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 (#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)
- 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 (#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)
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, #3853, #3865, #3866, #3875)
- Codex loads repository maintainer skills: .agents/skills now |
| v0.74.0 | 14 สิงหาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- A JSON bool or null nested in a vars value renders as True, False, or None: minijinja 2.22 adopted Jinja2's spelling for all three, so {{ vars.<key>.<field> }} into an object set by wt config state vars set prints those words. A var whose whole value is true stays a string. (Breaking: the old spellings were true, false, and none.) (#3795)
- wt config approvals add --yes records approvals without a terminal: the command refused every non-interactive run, so a container or CI job could not pre-approve a project it had just cloned. --yes now lists what it trusts and writes it, and a save it cannot make fails the command rather than warning and exiting 0. (#3819)
- remote_repo names the repository as the remote spells it: repo is the directory on disk, so a renamed clone reports the new name. {{ remote_repo }} takes it from the primary remote's URL, available everywhere owner is and unset when no remote parses. (#3745, thanks @canac)
Fixed
- wt remove --force deleted a live worktree moved onto another's registered path: the ownership gate asked which repository the occupant belonged to, which a sibling worktree of this repo satisfies, so the directory went to trash with its uncommitted work. The directory and the registration must now name each other, as git worktree remove requires. Also reaches wt merge, wt step prune, and picker removal, and refuses a bare repository's path that --force previously deleted. (#3808)
- wt step copy-ignored skips a source file that vanishes mid-copy: the walk collects leaves, then copies them in parallel, so a file removed in between — a concurrent build rewriting target/, say — aborted the batch, under --force after deleting the destination. The source is stat'd before anything is removed now. (#3744, fixes #3743, thanks @dataders for reporting and fixing)
- wt step promote refuses to delete a source it did not fully copy: across filesystems the move copies then deletes, and an entry with no copy — a socket or FIFO, or a file a concurrent build rewrote mid-walk — was deleted anyway. The copy now reports what it skipped, and a non-zero count fails the move. (#3820)
- An ssh:// remote's host comes from the authority, not a later path segment: the search for the userinfo @ covered the whole remainder, so ssh://git@attacker.example/owner/repo@github.com/org/repo.git resolved to github.com and borrowed that repository's approvals while git dialed the attacker. Every URL form now splits the authority first, so @ in a namespace parses instead of being rejected. (#3813)
- WORKTRUNK_* env vars and --config-set outrank a [projects."…"] entry: layer and specificity resolved separately, so a project entry answered for the global key whichever layer set it — WORKTRUNK_WORKTREE_PATH could not override a project's worktree-path. Both invocation layers now apply at either scope, and the help text gained a precedence section. (#3790, fixes #3788, thanks @jeremy0dell for reporting)
- Shell completions register under the --cmd name: wt config shell init zsh --cmd wot renamed the wrapper, but clap emitted the registration under wt. Bash and zsh completed nothing and regenerated the script on every TAB, PowerShell registered the wrong command, and zsh's compdef handed worktrunk's completer to the other wt. (#3817, fixes #3816, thanks @sbarre for reporting)
Documentation
- The picker's Alt-x never forces: the keybinding table read Remove selected worktree/branch, which sent a reader looking for a force-remove that isn't there. (#3811, raised in #3809, thanks @josh-burton)
Internal
- Library API rework (Breaking library API): GitError::WorktreePathNotOurs gained an occupant_registered_at field, and WorkingTree::ensure_belongs_to_repo is now ensure_holds_this_worktree. (#3808)
Install worktrunk 0.74.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-installer.sh | sh && wt config shell insta |
| v0.73.0 | 12 สิงหาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- wt remove refuses a registered path that now holds a different repository: A clone made at a stale registration's path was removed whole, uncommitted work included — and wt routed the user there, since the dirty gate read the occupant's files as this worktree's and offered --force as the cure. Removal now compares the directory's git dir against this repository's; --force waives uncommitted changes, not the check for whose directory it is. (#3785)
- The Nix flake names three systems, dropping Intel macOS: nixpkgs drops x86_64-darwin in 26.11, so the flake would stop evaluating there once flake.lock advances past it. (Breaking: nix build, nix run, and the home-manager module no longer resolve on Intel macOS. Release binaries are unaffected and still ship for it.) (#3776)
- NO_COLOR and a redirected stream reach every surface: Escapes still landed in progressive wt list, -v diagnostics, clap's error tips, and parts of stderr — the deprecation warning, the wt config update preview, the [y/N] prompt — so a redirected log carried escapes on one line and not the next. Color now resolves in one place. (#3777, #3771)
- A trailing separator no longer hides the branch: Git's ref format forbids a name ending in /, and shell completion produces exactly that spelling whenever a docs directory sits beside the branch, so wt switch docs/ never had a candidate. Selectors are normalized before resolution now — wt remove, merge targets, --base, and the pre-switch hook's target alike. (#3785)
- A path holding no worktree is reported as a path: wt remove ../repo.ghost answered No branch named … and pointed at a listing it could never appear in; wt switch and wt merge offered --create <path>, which git rejects; and wt config state marker set --branch <path> silently stored state keyed by a path. (#3773, thanks @judewang for reporting)
- A failed GitLab project lookup carries glab's own verdict: wt switch mr:<n> on a fork MR answered a 401, a 404, and a network failure with the same Failed to fetch project 456, swallowing the output every other remote_ref failure path forwards. A non-project response body now says so too. (#3799)
- A deleted-and-recreated worktree directory is reported, not leaked as git's exit 128: An rm -rf followed by a mkdir passes the Path::exists() probe, so wt switch, wt merge, wt step push, and wt remove walked into a raw git failure. All four now name the missing worktree and the git worktree prune that clears it. (#3785)
Internal
- Library API rework (Breaking library API): cargo-semver-checks fails four lints — GitError gained WorktreeNotFoundAtPath and WorktreePathNotOurs, shifting seven later discriminants, its DetachedHead variant gained a worktree field, ResolvedWorktree gained NoWorktreeAtPath, and Repository::resolve_worktree_name was removed. (#3785, #3773)
- Tests and benches spawn a pinned wt binary: a concurrent cargo removes and recreates target/debug/wt as it uplifts, so spawns hit a one-off NotFound; every spawn now routes through a hardlinked pin. (#3784, #3792)
- The nix devShell and task setup-web install what the test suite drives: both were missing nushell, pwsh, and jq, which --features shell-integration-tests shells out to. (#3768, #3776)
- Benchmark fixtures reduced to two provenance-based bases: Generated builds a repository locally and Imported copies the pinned rust-lang/rust corpus, with worktree, branch, and remote-ref populations as parameters. (#3761)
Install worktrunk 0.73.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.73.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.73.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
|
| v0.72.0 | 7 สิงหาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt merge and wt step push leave the target worktree's uncommitted changes in place: Both commands used to move a dirty target worktree's changes aside with an autostash (git stash push -u) and restore them after the push, because the fast-forward's receive.denyCurrentBranch=updateInstead refuses any dirty worktree at all. That design entered refs/stash — a repo-global namespace any process can mutate — and restored staged changes as unstaged. Both strategies now advance the target through one path: a compare-and-swap update-ref, then update-index --refresh plus read-tree -m -u in the target worktree (git's documented lenient push-to-checkout policy), with a CAS rollback if the sync can't apply, so branch and worktree move together or not at all. Uncommitted changes at paths the push doesn't touch never move — unstaged edits stay unstaged, staged entries stay staged, untracked files stay put, and refs/stash is never involved. The upfront check that names a conflicting file also reads --porcelain -uall now, so an untracked file inside an untracked directory is caught and named rather than slipping past a collapsed dir/ entry. (Breaking: the fast-forward path no longer runs a git push, so pre-push and the receive-side hooks — pre-receive, update, post-receive, post-update, and any push-to-checkout — no longer fire. A git merge run in the target wouldn't run them either, which is the line the module spec draws, and the new sync reimplements the lenient policy push-to-checkout documents rather than invoking the hook. Separately, a sync that can't apply now fails the command with the ref rolled back, where --no-ff previously warned and left the worktree stale behind its own branch.) (#3703, #3684, #3693, thanks @gubasso for reporting the stash race that started this)
- A host carrying a forge's name anywhere resolves to that forge again: 0.71.0 required github, gitlab, or gitea as a whole dot-separated label, which read as an ownership check but wasn't one — an attacker controls their own DNS, so github.attacker.example carried the exact label and classified fine, while the rule shut out the self-hoster with a hyphenated name. github-enterprise.acme.com, mygithub.com, gitlab-internal.company.com, and the github-personal SSH alias classify again, so CI status, wt switch --prs, and repo.provider work with no config. The cost is a host that merely sounds like a forge getting a forge CLI run at it, which surfaces as that CLI's error rather than as silence. Azure DevOps keeps suffix matching on dev.azure.com / visualstudio.com — those are service domains rather than a brand in the host — and userinfo still resolves to the network host, so https://github.com@attacker.example/… is attacker.example. The github-personal diagnostic 0.71.0 added is gone with the rule it explained. (#3673)
- One [projects."…"] entry can cover every repository on a host, and can set the forge: A key containing * matches any run of characters, / included, so [projects."git.company.example/*"] covers every repository on that host, nested groups and all. Every matching entry applies, least- to most-specific, so a narrower key wins where two set the same field and leaves the rest alone. The table also gained forge.platform and forge.hostname, which previously lived only in each repository's committed .config/wt.toml — so a self-hosted host carrying none of the three brand names needs one user-config entry rather than a block in every repo. A repository's own [forge] still wins field by field. approved-commands matches by the same rules, but only a hand-written key is ever a pattern: wt config approvals add records under the exact project identifier, and clear empties only the exact entry. Docs (#3701, thanks @chrishas35 for the request and @witt-bit for the workspace-scoped case it partly serves)
- wt list --format=json schema 2 has a published JSON Schema: The contract is at worktrunk.dev/schema/list-v2.json, and wt list --print-schema prin |
| v0.71.0 | 30 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Forge hosts are classified by exact DNS label: Host detection matched the bare substring, so github anywhere in a hostname selected the GitHub provider — evil-github.com and dev.azure.com.attacker.example included. Classification now requires github, gitlab, or gitea as a whole dot-separated label (Azure DevOps matches dev.azure.com / visualstudio.com as a domain suffix), and userinfo is split at the final @, so https://github.com@attacker.example/owner/repo resolves to attacker.example rather than GitHub. Ports and a trailing DNS root dot are normalized away first, so both transports classify identically.
github.mycompany.com still resolves, but a host that carries the forge name only as part of a label no longer does — gitlab-internal.company.com, github-mirror.example.com, and mygithub.com all become unknown, alongside the lookalikes the change targets. What is lost is forge-derived detail: CI status in wt list --full, wt switch --prs, and repo.provider in wt list --format=json, which reads unknown. Setting forge.platform in .config/wt.toml restores all of it, and wt switch pr:{N} keeps working either way.
Only one case announces itself — a single-label SSH alias of the github-personal form, the shape used for multi-account setups: SSH host alias github-personal is not auto-detected as a forge; enable CI status and wt switch --prs with forge.platform = "github" @ .config/wt.toml. A self-hosted instance at a hyphenated hostname gets no such message; it simply stops reporting CI. Going the other way, a recognized Gitea or Azure DevOps remote now knows its own change-request vocabulary, so wt switch 123 against a missing branch suggests wt switch pr:123 instead of offering both pr: and mr: forms. (Breaking: a remote whose host merely contains a forge name is no longer detected. Set forge.platform in project config.) (#3662)
- The retired single-file shell directive is no longer honored: Wrappers written before 0.37 passed one WORKTRUNK_DIRECTIVE_FILE, mixing a trusted directory path with arbitrary shell for the parent to source. The split WORKTRUNK_DIRECTIVE_CD_FILE / ..._EXEC_FILE pair replaced it in 0.37, the fallback has warned since 0.54, and it is now gone. A shell still running the old wrapper fails closed on both halves: Cannot change directory — shell wrapper is out of date, with the repair line To update the shell wrapper, run wt config shell install, and --execute disabled because the shell wrapper is out of date in place of running the payload. That makes a stale wrapper stricter than no wrapper at all, where --execute still runs the command directly — deliberate, since a retired wrapper is the one case where worktrunk cannot tell what the parent will do with what it writes. Child processes can no longer inherit the retired capability. (Breaking: a live shell on a pre-0.37 wrapper stops changing directory and stops running --execute until wt config shell install and a shell restart; nushell needs the reinstall because its wrapper is a static file.) (#3662)
- Every hyperlink is underlined: The statusline underlined its PR reference but not the dev-server port, so nothing marked the port as clickable. Both now route through one helper that emits the OSC 8 sequence and the underline together, closing with [24m rather than a full reset so a wrapping color or a dim survives the link. Text that is not a link stays plain: the picker cannot carry OSC 8 through skim, so it prints the same short text with no underline instead of underlining something unclickable, and on a terminal without OSC 8 support a dev-server URL still prints in full and stays copyable. (#3643, #3651)
- Shell completion answers a Tab press in roughly half the time: Completion forks a whole wt process on every Tab press, with the user's finger still on the key, and it has nowhere to hide work — nothing paints progressively, no cache survives the process, and no shell caches a dynamic completion. It was doing every git read in seq |
| v0.70.0 | 29 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step prune removes worktrees far faster: Each removal ran a serial chain of ~17 git subprocesses under the scan write lock, re-preparing a plan the scan had already computed and re-stating the worktree right after the fsmonitor daemon stop. The chain is now one check per guarantee, reusing the scan-time plan, and removals run concurrently on the scan lock's read side — the write side is kept for the candidates that need it (hook-bearing, --foreground, metadata-pruning, and the current worktree). The documented rust-scale live prune of 24 candidates goes from ~12 s to ~0.6 s wall, and the prune_e2e/live benchmark from ~620 ms to ~400 ms. (#3617, #3631)
- wt step prune --format=json is ordered, and a failed removal aborts the rest: Live JSON output is now sorted by scan index, matching --dry-run, with the current worktree last. The first failing removal drains the remaining queue unexecuted, matching the serial loop it replaced; in-flight removals complete. (#3631)
- A worktree can be named by its path wherever a branch is accepted: Every argument that takes a branch now also accepts the worktree's own path, resolved after the branch so a directory never shadows a branch sharing its name. A path names what a branch cannot — a detached worktree, or one of two checkouts of the same branch. Relative paths resolve against -C and a leading ~ against the home directory, so a path worktrunk printed can be pasted back. Docs (#3607)
- wt list flags a branch checked out in more than one worktree: Such a branch resolves to whichever worktree git lists first, so every worktree on it now carries ⚑ — worktree.state "duplicate_branch" in schema 1, a worktree.duplicate_branch boolean in schema 2. The flag makes the ambiguity visible in the listing; resolving such a branch from any command warns separately and names a duplicate to drop. (#3480, #3606)
- wt switch --execute computes only the template variables its command names: The switch path built every variable the template context could hold before rendering; it now resolves just the ones the command references. On a clone with no origin/HEAD and no cached default branch, that removes a git ls-remote the command never asked for — 13 subprocesses and one remote query down to 8 and none. (#3628)
Fixed
- A branch checked out in a second worktree is retained on removal, -D included: wt remove and wt step prune now act on the worktree named rather than the branch's first checkout, and all three of wt remove, wt step prune, and wt merge keep the branch while another worktree still has it out — deleting the ref would leave that worktree unable to resolve HEAD, which is why git branch -d refuses the same delete. The retention is reported and names the surviving checkout rather than passing silently. (#3533)
- Removal reports what it took, not what it selected: A removal's summary and JSON described the plan, so a worktree candidate whose branch was retained still counted as ✓ Pruned 1 branch, and wt remove --format=json reported "branch_deleted": true beside a stderr line saying the branch was kept. Execution now returns the branch's fate; wt step prune counts executed outcomes (--dry-run included), both JSON payloads gained branch_deleted, and a declined orphan deletion drops out of the removed list rather than being reported as removed. (#3633, #3637)
- Hook previews expand every variable except vars.*: One vars. token disabled expansion for the whole command, so wt hook show --expanded and wt hook <type> --dry-run printed {{ branch }} and {{ repo }} raw in a listing whose job is to show the expansion. A preview now substitutes a stand-in that renders each vars.* reference back as itself, nested access included, while every other variable expands — and no longer spawns the git read that resolving vars required. The listing is also derived from the execution path itself, so a context key added there reaches the preview with no second edit. wt config alias dry-run shares |
| v0.69.2 | 25 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt remove resolves every fsmonitor daemon in one lsof call: The end-of-command sweep forked one lsof per git fsmonitor--daemon on the machine — with core.fsmonitor enabled globally that is one daemon per repo ever touched, routinely over a hundred — and the spawn cost compounds under load rather than staying fixed per call. All daemons now resolve in a single call: 108 spawns to 1 on a live machine. (#3581)
Fixed
- Shell integration no longer deletes user data that merely quotes the init command: Three places decided whether text was worktrunk's by testing a blob for substrings, and two of them deleted on a wrong guess. wt config shell uninstall removed an rc line like alias setup='echo "run: wt config shell init fish | source"'; wt config shell install's legacy cleanup deleted a user's own ~/.config/fish/conf.d/wt.fish outright when the file happened to mention the init command. Both now require the command name in command position, not merely somewhere in the text. (#3589)
- Forge detection matches host labels, not substrings: wt switch pr:<n> and friends picked their provider with host.contains("github") / contains("dev.azure.com"), so a host that only spells the name inside a longer one — github-mirror.example, dev.azure.com.attacker.example — resolved as that provider. Matching is now label-wise, accepting the domain and its subdomains only; a self-hosted deployment this misses can still name its provider explicitly. (#3589)
- A crash mid-write no longer empties the file being written: wt config shell uninstall ended its rc rewrite by truncating in place, so a crash, a full disk, or a lost power cable between the truncate and the write left ~/.bashrc, ~/.zshrc, or a PowerShell profile empty or half-written, taking every line the user had ever added. Every user-file write now goes through one writer that writes a temp file beside the target and renames it into place. (#3585, #3591)
- wt step push refuses to run out of a half-finished operation: Mid-rebase the detached HEAD looks like a linear extension of the target, so wt step push main reported ✓ Pushed to main (1 commit) while moving the target branch onto a half-replayed history and leaving the rebase open; it now runs the same operation gate as wt step rebase and wt merge. The same change fixes an annotated-tag target always reporting as needing a rebase — the tag object's SHA was compared against a merge-base that peels it — and makes both push paths refuse a target worktree whose directory is gone, rather than --no-ff moving the ref over the stale registration. (#3578)
- Conflict markers can't reach a commit, and the refusal names the command you ran: wt step relocate --commit staged with git add -A and committed straight through an unresolved merge, reaching neither gate added for the other staging commands; every staging path is now gated on an unmerged index. wt merge already refused, but in a sub-step's name. (#3588, #3587)
- OpenCode activity markers land in the worktree they belong to: The plugin issued its marker commands through the process-global Bun shell without scoping them, so each ran in whatever the process-wide cwd happened to be — under concurrent parallel-agent sessions, a marker write could land in another session's worktree. (#3554, thanks @4i3n6)
Documentation
- wt step rebase and wt step push render on the docs site: the only two of twelve step operations whose help was terminal-only. Both bodies are rewritten, correcting (among others) the claim that conflicts abort immediately — nothing aborts; the worktree is left mid-rebase with git's markers — and a wt step squash note promising a backup ref unconditionally, when a clean-tree squash writes none. (#3578)
- Troubleshooting no longer suggests disabling core.fsmonitor globally: the guidance for a wedged daemon keeps to the targeted fixes — kill the daemon serving that worktree, or let the next wt list respawn the live ones. (#3581)
Internal
- The Windows zip ships the |
| v0.69.1 | 25 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch statusline dims the dev-server URL until its port answers: The Claude Code statusline's dev-server URL now dims until something answers on its port, matching the wt list cell it already copied in every other respect. (#3561)
Fixed
- wt step rebase and wt merge refuse to run mid-operation: With a git operation already in progress (a conflicted rebase stop, or a killed git), wt step rebase <target> reported Already up to date and exited 0 over a conflicted, mid-replay tree — it asked "already rebased?" before consulting the worktree's operation state — and wt merge failed with a detached-HEAD error whose suggested git switch would have discarded the in-progress rebase. Both commit-replaying commands now detect an open operation up front and refuse with a clear message. (#3558)
- Shell-integration install/uninstall correctness: wt config shell now validates the integration command name and rejects malformed values (empty, leading -, or shell-unsafe characters) with a clear error rather than writing a broken rc line; recognizes manually-added or older-form integration lines on install, reporting already-configured instead of appending a duplicate; and, on uninstall, scans for worktrunk-managed wrapper files and rc lines by content marker, so integration installed under an alternate binary name (git-wt, …) is cleaned up regardless of the name it was installed under — while a user's own file that merely mentions wt config shell init is left untouched. (#2864)
- wt switch picker reflects a mid-session removal after a deleted-CWD recovery: When the picker recovered from a deleted working directory, accepting a row reused the startup-time repository snapshot — so an in-picker alt-x removal of a worktree or branch during that recovered session wasn't observed on accept. The accept path now rebuilds the repository. (#3557)
Internal
- Windows code-signing upload no longer double-zips: The unsigned Windows artifact was uploaded wrapped in an artifact-storage zip around the already-zipped binary, so SignPath couldn't locate wt.exe inside it and the (non-blocking) signing request failed. The upload now sets archive: false, submitting the real zip to SignPath. (#3566)
- crates.io publishing via trusted publishing (OIDC): The release workflow mints a short-lived crates.io credential per run via rust-lang/crates-io-auth-action instead of a stored CARGO_REGISTRY_TOKEN. (#3564)
Install worktrunk 0.69.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.69.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.69.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.69.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Ins |
| v0.69.0 | 24 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch statusline links in Claude Code: The Claude Code statusline suppressed OSC 8 hyperlinks, so its CI segment printed colored but inert and its dev-server URL printed in full. Claude Code renders OSC 8, so both segments now link, matching wt list. (#3550)
- wt merge --no-rebase accepts merge-shaped histories: --no-rebase previously required a strictly linear rebased history and rejected a branch carrying a merge commit, even when the target could already fast-forward to its tip. It now accepts any history the target can fast-forward to, so wt merge --no-commit --no-rebase preserves an exact commit graph — merge commits and all. (#3509, thanks @reneleonhardt)
- -v variable blocks name their template and render consistently: The four -v template-variable listings (foreground/background hooks, aliases, wt step eval) now label each block with the template it belongs to, and eval renders through the shared formatter — curated help-table order rather than its own alphabetical layout. (#3495, #3536)
Fixed
- wt merge measures the squash/rebase span against the target's upstream: When the primary checkout's local default branch was behind its upstream (e.g. local main behind origin/main) and the branch descended from the newer upstream tip (created with --base origin/main), wt merge — and wt step squash / wt step rebase — measured the commit span against the stale local ref and swept in commits already upstream, folding them into the squash and corrupting the local default branch (duplicating upstream content under new SHAs if later pushed). The span is now measured against the target's upstream (a local-only check, no fetch), and a target that has genuinely diverged from its upstream is refused up front. Fixes #3519. (#3549, thanks @starlightromero for reporting)
- Ctrl-C during a rebase surfaces as an interrupt, not a conflict: A git rebase killed by a signal (SIGINT/SIGTERM) mid-operation left the worktree in REBASING state, which wt classified as a merge conflict — printing conflict-resolution guidance and the wrong exit code. A signal-killed rebase now exits cleanly with the signal's conventional code (130 for SIGINT, 143 for SIGTERM). (#3539)
- wt switch picker responsiveness: Accepting a row could stall for ~10s on a large repo (indefinitely under sustained background traffic) while the switch queued behind per-row preview diffs; the foreground thread now bypasses the command-concurrency semaphore. Separately, an idle picker with pending background work — a slow CI fetch, or an LLM branch summary ([list] summary = true) — spun 100% of a CPU core; the reader now exits once the last row batch lands. (#3544, #3534)
- Clear error when a new branch name collides with an existing branch namespace: Creating feat while feat/x exists (or the reverse) failed with git's raw ref-lock error; wt switch --create now explains the namespace conflict. (#3528)
- wt switch picker no longer shows another row's branch name in an empty diff preview: The branch-diff and upstream-diff caches are keyed by SHA, so branches parked at the same commit (common after merged branches reset to the default branch's tip) shared one entry — and the cached pane had the first row's branch name baked into its "no file changes" headline. The cached value is now branch-agnostic and the headline renders per row. (#3481)
- WorktreeRemove plugin hook no longer strands a completed session: Claude Code fires the hook on session teardown for the recorded worktree path, which may already be gone (removed by wt merge or wt remove). In that case the hook exited non-zero, which Claude Code read as a failed removal, leaving the completed session row undeletable; it now exits 0 when the worktree is already gone (#3493, closes #3488). Separately, the hook now anchors at the project directory rather than inheriting the session's working directory (#3489). Thanks @judewang for reporting #3488 and for #3489.
- WorktreeCreate plugin hook surfaces wt failu |
| v0.68.0 | 15 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch preview tabs fill on demand: Navigating to a preview tab (e.g. alt-3, the branch diff) could show "Loading…" for ~10 seconds in a large repo while the tab waited its turn in the background precompute queue. A local-git tab (working tree, log, branch diff, upstream) now computes as soon as it's viewed: a cold tab costs its own git command, and a previously computed one fills from the disk cache in milliseconds. An alt-r refresh also discards in-flight results from before the refresh rather than letting them repopulate the cleared cache. (#3439)
- wt config state flags a stale default-branch cache: The detected default branch is cached and not re-validated on every command, so a later change to origin/HEAD (a rename followed by git remote set-head origin -a) went unnoticed. wt config state now flags the cache when it differs from the remote's local HEAD; set adopts the new branch and clear re-detects. (#3478, closes #3471, thanks @starlightromero for reporting)
- Branch-worktree path mismatch demoted to a dim note: wt list flagged a worktree whose path doesn't match its templated location in red, alarming for the agent-harness worktrees that routinely park at non-standard paths. The mismatch now renders as a dim informational note, and only in wt list: the inline notices on wt switch, wt remove, wt merge, and wt step prune are removed. (#3419, for #3389, thanks @dmsmidt for raising it)
- wt config update writes the upcoming [list] json-schema = 2: With the key unset, update previously pinned the current default (= 1), entrenching the schema being retired; it now writes = 2, moving JSON consumers forward. The default is unchanged: schema 1 applies until the key is set. (#3436)
- wt step promote --format text|json: Parity with the other step subcommands (rebase, push, …). (#3424, thanks @fuleinist)
Fixed
- Bare-repo project config survives the default branch being checked out nowhere: When no worktree had the default branch checked out (e.g. a linked worktree parked on another branch, common in agent-driven workflows), wt found no on-disk .config/wt.toml and silently ran with no project config and no project hooks. It now reads the default branch's committed config from the object store, and wt config show reports that source. (#3462, #3466, #3477, closes #3461, thanks @shuntaka9576 for reporting)
- Relative WORKTRUNK_PROJECT_CONFIG_PATH anchors to the worktree root: A relative override resolved against the process's current directory, so running wt from a subdirectory silently disabled it. It now resolves from the worktree root, like the default .config/wt.toml. (#3460, thanks @indexzero for reporting in #3454)
- Misplaced nested config keys name the file they belong in: A key valid only in the other config file (e.g. list.columns, user-config only, set in the project config) was flagged only as an unknown field; the warning now says which file it belongs in. (#3473, thanks @KieranP for reporting in #3469)
- Shell integration detects the shell that invoked wt: wt switch could tell a fish user "shell integration requires a restart" because $SHELL names the login shell, not the shell in use. Detection now walks the process tree to find the enclosing shell, falling back to $SHELL when the walk can't resolve one. (#3455)
- Claude plugin's WorktreeCreate hook runs from the project directory: The hook inherited the session shell's working directory, so a session that had cd'd outside the repository failed every worktree creation with "not a git repository". (#3453, thanks @silvanshade)
- Codex plugin installs ship skills: codex plugin add copies the plugin via a mechanism that doesn't follow symlinks, so the skills symlink shipped no skills to Codex installs; Windows checkouts, where symlinks materialize as plain text files, had the same gap. The plugin now carries a generated real-file mirror of the skills. (#3440)
- LLM prompt size bounded for long diffs: Commit-message, squash, and branch-summary g |
| v0.67.0 | 10 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Experimental --reap flag for wt remove: wt remove --reap terminates processes still running in the worktree (a post-start dev server, a file watcher, a language server) before removing it, freeing the ports and file handles they hold. Processes are discovered by working directory and terminated with SIGTERM, then SIGKILL for survivors; the list prints before any signal is sent. A process holding a controlling terminal (an interactive shell, a terminal editor with unsaved buffers) is never touched. Unix only. Docs (#3396)
- wt switch -x without a branch opens the picker: --execute no longer requires a branch argument — wt switch -x claude opens the interactive picker and runs the command against the selected worktree. It composes with every picker mode (--branches, --remotes, --prs), and the picker path shares the same pipeline as the argument path, so hooks, approval, and template expansion behave identically. (#3394, closes #3370, thanks @gbcreation for the request)
- wt config state logs profile groups subprocess time by worktree: The report gained a BY CONTEXT table (and a by_context array in --format=json) — subprocess time per context, typically the worktree name — so a slow parallel phase can be attributed to the worktree causing it without exporting the trace to an external tool. (#3403)
- -vv diagnostics surface pager and terminal environment: The diagnostic report (.git/wt/logs/diagnostic.md, written on every -vv run) gained an "Environment variables" section listing a curated, non-secret allowlist of the pager / terminal / locale knobs (PAGER, GIT_PAGER, TERM, COLUMNS, NO_COLOR, LANG, …) plus git's resolved core.pager. These are the inputs that most often explain a rendering bug — like a pager interaction suspending wt config show (#3322) — and they were previously invisible in the report. The list is a strict allowlist, never a blanket env dump, so no credential-bearing variable can leak into an uploaded report.
- wt config update pins [list] json-schema while unset: The schema hint from 0.66.0 now comes with the standard one-command fix — wt config update pins json-schema = 1 (the behavior-preserving choice) when the key is unset, and the hint offers the command only when running it would actually write the pin. (#3411)
Fixed
- wt switch no longer crashes on ragged tables in PR comments: A PR/MR comment table with more cells in a data row than in its header could panic termimad's column fitter at narrow widths, and because the comments preview renders on a background worker, the panic aborted the whole picker. The table render is now contained; the preview falls back to the table's plain text. (#3408, closes #3407, thanks @ortonomy for reporting)
- wt config show no longer suspends on the zsh completion probe: The interactive zsh probe that detects a missing compinit claims the terminal foreground when job control is on; a slow or prompting zsh startup could hit the probe's kill-on-timeout before the foreground was restored, leaving wt in a background process group and its pager suspended with suspended (tty output). Both interactive probes now run with job control disabled (zsh +m), so a timed-out probe can't strand the terminal. (#3327, closes #3322, thanks @karmeleon for reporting)
- wt step for-each and the --execute fallback no longer inherit wt's GIT_* discovery vars: The command that for-each runs in each worktree — and the --execute payload, when wt executes it directly because shell integration isn't active — now discovers its repository from the worktree wt placed it in, rather than an inherited GIT_DIR/GIT_WORK_TREE. Previously such a command's git calls resolved against the one inherited repo (e.g. the invoking worktree, when wt runs as a !wt git alias from a linked worktree) while the per-worktree headers claimed otherwise. This extends the hook-spawn scrub from #3374 to the remaining spawn sites that relocate a user command into a wt-chosen worktree; aliases and commit.generat |
| v0.66.0 | 8 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Opt-in JSON schema 2 for wt list: wt list --format=json and wt list statusline --format=json can now emit a v2 schema, selected via the [list] json-schema config key. Schema 2 wraps the rows in an envelope (schema, repo.default_branch, repo.forge, collected) and separates "nothing to report" (field absent) from "requested but undetermined" (field null — a probe still pending, timed out, or failed). Schema 1 — the existing bare array — remains the default, byte-for-byte; with the key unset, a once-per-process stderr hint shows both values (= 1 to pin, = 2 to opt in; suppressed on the statusline surface). Docs (#3357)
- wt config approvals list and clear --stale: list shows every command the project config declares — hooks in lifecycle order, aliases, commit-message guidance — grouped into approved and unapproved, with approvals recorded for commands no longer in the config flagged as stale. clear --stale removes only those left-behind approvals, echoing each one; valid approvals survive, and a full wipe remains plain clear. Docs (#3380)
- Codex sessions show activity markers: The Codex plugin now ships Codex-native activity hooks, so wt list shows 🤖 (working) / 💬 (waiting) for Codex sessions as it does for Claude Code, OpenCode, and Gemini — and Claude-branded events no longer surface inside Codex sessions. Codex has no session-exit event, so the marker rests at 💬 after a session ends until the next session or wt config state marker clear. (#3364, closes #3362, thanks @ofek for reporting)
Fixed
- User hooks no longer inherit wt's GIT_* discovery vars: A user hook that shells out to git now discovers its repository from the worktree wt sets as its cwd, rather than an inherited GIT_DIR/GIT_WORK_TREE (e.g. from wt run as a !wt git alias, or nested under another tool's git hook). wt now scrubs the GIT_* discovery vars at every hook spawn site — foreground, background, and concurrent. Previously the inherited context leaked into hooks: with both GIT_DIR and GIT_WORK_TREE present, a hook that ran git init would write core.worktree into the inherited repo's config, silently redirecting later plain git commands there. wt's own internal git plumbing keeps the inherited context (the absolutize-and-forward behavior from #1914); aliases keep it too, since a top-level wt <alias> is the user's own command. (#3374, closes #3373, thanks @silvanshade for reporting)
- SCP-style SSH remotes with custom usernames: Remote URLs like org-12345678@github.com:owner/repo.git (GitHub account/org aliases) now parse canonically, so wt switch pr:<n> matches the local remote instead of failing with No remote found. Malformed and local-path forms that merely resemble SCP syntax are still rejected. (#3371, thanks @fcoury-oai)
Documentation
- Windows app-alias guidance matches current Settings: The instructions for disabling Windows Terminal's wt app-execution alias now point at the current Settings path (Apps → Advanced app settings → App execution aliases). (#3372, thanks @ofek)
- /wt-switch-create always creates a worktree: The plugin skill's wording let a session judge that a research or read-only task didn't need isolation and skip the worktree; invoking the command now counts as the explicit request, so the worktree is created unconditionally. (#3356)
Install worktrunk 0.66.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.66.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.66.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.66.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
──────────────────────── |
| v0.65.0 | 2 กรกฎาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Picker alt-x flashes why a worktree wasn't removed: When alt-x in the wt switch picker keeps a row instead of removing it, the reason now flashes in the picker header for a beat, rather than only draining to stderr after you quit — so the "why" is visible while the row is still in front of you. It covers both the by-design keeps (the current worktree; an unmerged branch-only row shows ○ Kept <branch> — branch is unmerged) and genuine removal failures (a dirty, locked, or main worktree, shown as an error). The full diagnostic still drains on exit. The --prs loading marker now also matches the picker's other in-flight placeholders (↳ Loading open PRs…). (#3336, #3350)
- -vv diagnostics consolidate on diagnostic.md, led by the performance profile: A -vv run now opens with a one-line pointer to the log directory (○ Verbose logging to .git/wt/logs/) and closes by naming what it captured — ○ Logs, performance profile, and diagnostics saved @ diagnostic.md — with the raw trace.jsonl / subprocess.log companions listed beneath and the gh gist create bug-report hint. diagnostic.md now leads with the performance profile, expanded by default and promoted above the environment / worktree / config dumps; that profile reports the 20 slowest calls (was 8) and 10 same-context redundant-command offenders (was 3). The profile lives in the diagnostic.md bundle, and wt config state logs profile re-renders it live from trace.jsonl. (#3329)
Fixed
- wt remove preserves your subdirectory position: Removing a worktree from a subdirectory (e.g. apps/gateway/) now lands you in the equivalent subdirectory of the destination worktree rather than at its root — matching how wt switch already behaves, and falling back to the root when that subdirectory doesn't exist there. wt merge lands through the same handler, so it gains the same behavior. (#3344, closes #3343, thanks @caillou for reporting)
Install worktrunk 0.65.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.65.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.65.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.65.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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.64.0 | 30 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- {{ git.branch.* }} template namespace for custom columns: wt list custom columns can now read a branch's own git config via {{ git.branch.<key> }} — both convention keys you set yourself (branch.<name>.jira) and the git-native branch.<name>.description — without re-storing the values through wt config state vars set. It complements {{ vars.* }}, which reads only worktrunk's own state namespace. (#3319, thanks @cazador481 for the request)
- Faster warm-cache wt list re-runs: A repeat wt list (with .git/wt/cache/ already populated) is ~36% faster, by removing redundant per-row git subprocesses — priming the commit→tree cache from the %ct batch already issued, persisting merge-base results to a content-addressed on-disk cache, and seeding worktree roots and git-dirs from the single git worktree list instead of re-forking git rev-parse per worktree. (#3334)
Fixed
- Refs that look like flags can't inject git options: wt's git diff previews and diffstats (picker diff previews, show_diffstat, push diffstat) now fence user-controlled refs behind --end-of-options, and branch removal (git branch -D) passes them after --, so a branch literally named like a flag (-x, --foo) reaches git as a positional ref instead of being misparsed as an option. (#3317)
- Statusline renders untruncated when COLUMNS=0: wt list statusline treated COLUMNS=0 as a zero-width budget and dropped every segment, rendering an empty line. A zero or unparsable COLUMNS is now treated as no detectable width, so the line renders everything untruncated — as the statusline sizing already documented for a missing width. (#3318)
- Watchdog "still waiting" line uses the hint symbol: The transient Waiting for the commit message (Ns) line shown during a slow wt step commit LLM call now uses the hint prefix (↳) instead of the info symbol (○), matching the convention for fully-dim status lines. (#3330)
Install worktrunk 0.64.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.64.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.64.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.64.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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.63.0 | 29 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- [list] columns can force a column on past --full: Listing a column now overrides the --full / [list] summary presets — columns = ["branch", "ci"] shows the CI column without --full. Hard data-source prerequisites still apply: a listed summary with no [commit.generation] command, or url with no template, stays hidden, since listing can't conjure data that isn't configured. (#3295)
- Alt-r in the picker refreshes the preview panes, not just the rows: Alt-r re-collected the rows but kept serving cached preview content, so editing a tracked file and refreshing still showed the pre-edit diff. It now clears the preview cache too, recomputing the working-tree / log / branch-diff / upstream / summary tabs and re-fetching pr / comments. Unchanged branches re-read from the content-keyed on-disk cache, so only genuinely changed content pays a recompute. (#3293)
- A narrowed wt list is now actually faster: A narrowed [list] columns selection (e.g. ["branch", "path"]) now runs only the git work its columns need. It previously ran every per-worktree git status, diff, and ahead/behind walk regardless, then discarded the unselected results — so a trimmed view was no faster than the full table, and on a repo with many dirty worktrees that discarded work was the bulk of the wall-clock cost. (#3274, thanks @jtaby for reporting)
- Fewer duplicate git calls in wt list --full: The two integration probes per row (the conflict bit for main-state and the clean-merge tree for the integration column) issued a byte-identical git merge-tree, and the shared default-branch tip was peeled to its tree once per row. Both are now deduplicated through the in-memory cache, so each resolves once per run instead of once per worktree. (#3288, #3289)
- Picker comments tab avoids redundant forge fetches: The picker's comments preview tab gained an on-disk cache keyed by the PR's updatedAt (which rides for free on the CI fetch the picker already makes), so a repeat wt switch skips the per-row gh pr view --json comments fetch when the thread is unchanged and paints the tab instantly instead of showing "Loading comments…". The cache is also primed from the gh pr list call the picker already makes, so the tab skips its own fetch even on a session's first open (including PRs with no comments). GitHub only. (#3294, #3299)
- Statusline width comes from COLUMNS, not a parent-process walk: wt list statusline used to spawn up to 10 ps calls plus stty per render to recover a terminal width, because Claude Code piped the subprocess with no inherited TTY. Claude Code now sets COLUMNS/LINES to the terminal dimensions before running the script (since v2.1.153), so the width comes straight from there — less a fixed 5-column margin for Claude Code's own UI — and the ps/stty walk is gone. On an older Claude Code that doesn't set COLUMNS, the line renders untruncated rather than walking the process tree. (#3286, closes #2950)
Fixed
- wt list diff and ahead/behind columns use the upstream default tip: The main↕ (ahead/behind) and main…± (diff) columns measured every branch against the local default-branch tip, so in a fork whose local main lagged its upstream they reported inflated counts — one fork branch showed ↑44 and +∞ / -5K when it was ~2 commits past the real upstream tip. They now diff against the same upstream-aware base the integration column already uses. (#3280)
- Integrated branches no longer flash ✗ in wt list: A squash-merged branch whose default branch later re-edited the same lines showed ✗ (would-conflict), even though wt step prune classified it as ⊂ (fully integrated) and removed it. The list now ranks the integration verdict above the downstream conflict, matching prune; a genuinely un-integrated conflict still shows ✗. (#3278)
- wt list divergence-overflow marker uses one emphasis level: When an ahead/behind count overflows its digit budget, the main↕ column's compact C/K/∞ marker rendered the "behind" subcolumn as dim + bold (reading as bol |
| v0.62.0 | 27 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Browse open PRs/MRs in the wt switch picker, with live CI: The picker now streams a live CI/review-status column per row — priming from the local cache, then fetching live (it previously showed only cached numbers with no network). A new --prs flag adds the repository's open PRs (GitHub) / MRs (GitLab) as rows alongside your worktrees, each with pr / comments / log preview tabs loaded from the forge in the background; selecting one fetches its branch and switches. Rows whose branch is already shown aren't duplicated, so --prs differs from plain wt switch only by the extra rows. Docs (#3128, #3169, #3189, #3252)
- main…± diff column shows by default in wt list: The main…± column (lines changed since the merge-base with the default branch) now renders in the default wt list and picker, served from a persistent cache rather than a history walk. --full now adds only the columns that reach off-machine — CI status and LLM branch summaries — and wt list --format=json populates main.diff for every item, not just under --full. (#3236)
- [list] columns selects and orders the columns wt list shows: A new [list] columns user-config key (also settable via --config-set) takes an ordered array of column names — built-in (branch, status, ci, path, …) and [list.custom-columns] headers alike — and renders exactly those, in that order. Where v0.61.0's custom columns add columns, this selects and reorders the whole set; omit the key for the default layout. (WORKTRUNK__LIST__COLUMNS isn't supported yet and warns if set.) (#3141)
- Picker PR preview shows full PR/MR detail: The pr tab now renders the PR/MR title, markdown description, author, draft state, comment count, bold branch name, and underlined URL for any row whose branch has an open PR — not just --prs rows — and the comments tab fetches the real thread. The title and description ride the CI fetch the picker already makes; the comment thread is fetched lazily in the background, once per row. (#3167, #3197, #3223, #3195, #3231)
- Interactive picker runs on Windows: The wt switch picker was Unix-only because its preview-tab keys shelled out through a per-process state file cmd.exe lacks; tab state moved to an in-memory atomic with native skim callbacks, lifting the platform gate. (#3217)
- Picker keyboard shortcuts: Alt-y copies the selected branch name, Alt-o opens the row's PR/MR in the browser, and Alt-r refreshes the list (picking up worktrees created or removed elsewhere). (Breaking: in the picker, remove moved from Alt-r to Alt-x) (#3233)
- Picker uses the full terminal: List height scales with the terminal (a roughly even split with the preview, minimum 3 rows) instead of a fixed 12-row cap, the table lays out at full width so toggling the preview off with Alt-p reveals the freed columns with no reflow, and a scrollbar appears when the list overflows. (#3205, #3214, #3198)
- Picker filters on more of each row: Typing a gutter sigil filters by row kind (+ for linked worktrees, @ for the current one), the fuzzy matcher ranks on the distinguishing path segment rather than the shared parent prefix, and rows with a PR/MR also match on its number, title, and author. (#3143, #3208, #3252)
- Picker visual polish: The legend recolored to dim-cyan and reordered so navigation leads, and preview loading placeholders moved to the dim-hint style (↳ transient, ○ settled, ▲ failed). (#3237, #3253)
- "Still waiting" status for slow commit-message generation: A configured commit.generation command captures stdout, so a slow or hung LLM previously showed nothing while wt step commit/squash waited. After a 2s delay worktrunk now shows a dim, in-place ○ Waiting for the commit message (Ns) status, escalating at 10s to reveal the exact shell-escaped invocation in a gutter beneath it; the block clears on completion, mirroring wt list's stall footer. (#3178)
- "Still waiting" status extended to more slow commands: The same waiting status now covers three more foreground commands that |
| v0.61.0 | 21 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt list custom columns: Each [list.custom-columns.<Header>] entry in user config adds a column to wt list (and the wt switch picker), rendered per row as a minijinja template over branch, worktree_path, worktree_name, and vars.*, with optional width and drop priority. Values expand from in-memory data only — no subprocess runs per cell — and a column that is empty on every row is dropped. wt list --format=json gains a columns map per item. The feature is experimental, so the config shape may still change. (#3073)
- --config-set for inline config overrides: A global, repeatable --config-set <toml> flag overrides any user-config key for a single invocation, layered above config files and WORKTRUNK_* env vars. The value is a real TOML fragment, so arrays and tables work natively (wt --config-set list.full=true list); nested tables deep-merge, and a malformed or invalid override drops the whole --config-set layer with an attributed warning rather than failing the command. (#3138)
- Picker shows cached PR/MR numbers: The wt switch picker skips the networked CI-status fetch, so it previously had no CI column. It now fills PR/MR numbers from the local .git/wt/cache/ci-status/ cache populated by earlier wt list --full or statusline runs, with zero network access. A stale entry (TTL passed or branch head moved) keeps its number dimmed; expired entries without a number are dropped. (#3073)
- Faster file copies on macOS: After a reflink (clonefile on APFS, which already preserves mode bits), worktrunk now skips the redundant follow-up chmod on macOS, saving one syscall per file in wt step copy-ignored and every other copy path. Linux (btrfs/XFS) still sets permissions, since FICLONE clones data extents only and drops the execute bit. (#3149)
Internal
- Picker migrated to skim 4.8 (ratatui/crossterm): The wt switch picker moved off skim 0.20.5 (tuikit) to skim 4.8.0, dropping the vendored vendor/skim-tuikit/ patch tree (both patches it carried are now native or upstream). Two cosmetic picker changes come with it: the match counter no longer overlaps the preview-tab header, and the HEAD column shows the full short-SHA. (#3137)
- All command spawns route through one trace chokepoint: CommandTrace is now the sole emitter of [wt-trace] command records, so a spawn path can't silently skip tracing — git worktree add, previously an unattributed gap, now shows up as a labeled slice in wt-perf timeline. (#3134)
Documentation
- Hook-approval skill guidance: The bundled worktrunk skill now frames hook approvals as user consent and no longer advocates --yes to bypass prompts. (#3146)
Install worktrunk 0.61.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.61.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.61.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.61.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-lin |
| v0.60.0 | 18 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Package installs complete branch and worktree names: A plain brew install worktrunk (or other package install) now tab-completes branch and worktree names, not just subcommands and flags. wt config shell completions <shell> emits a dynamic registration that calls the binary at completion time (the maintained clap_complete::env path), matching what gh, rustup, and kubectl ship. (#3105, thanks @bendrucker)
- wt step relocate moves dirty linked worktrees: Relocating a linked worktree with uncommitted or untracked changes no longer skips it. git worktree move carries those files along, so the dirty-skip was a worktrunk policy rather than a git limitation. The main worktree still skips when dirty (without --commit), since its relocation falls back to git checkout, which refuses to switch over a dirty tree. (#3104, thanks @lunaynx for reporting)
- --dry-run previews print to stdout: wt hook <type>, wt step relocate, wt step prune, wt step copy-ignored, and wt config shell install/uninstall now send their --dry-run preview to stdout (the command's answer) while narration stays on stderr. This matches wt list, git clean -n, and terraform plan, and keeps previews pageable and pipeable. (Breaking: scripts reading these previews from stderr should now read stdout) (#3085)
- Picker gutter distinguishes local and remote branches: With --branches and --remotes, the wt switch picker marks each row's kind in the gutter: / for a local branch without a worktree and | for a remote branch, alongside the existing @/^/+ worktree glyphs. (#3115)
- wt list --format=json gains structured repo metadata: JSON output adds repo (the local checkout's primary remote) and ci.repo (the repository ci.url targets, which differs for fork PRs) objects carrying host/owner/name/provider; the existing repo_url and ci.repo_url strings remain. The provider honors the configured [forge].platform on hosts that can't be auto-detected. (#3021, thanks @jeremy0dell)
- wt step eval --format=json: wt step eval gains a structured {name, template, result} JSON lane on stdout, the machine-readable analog of its -v view. Text mode is unchanged. (#3106)
- --format=claude-code rejected where it never applied: wt list and wt config state get accepted --format=claude-code silently and treated it as table; the value only ever meant anything on wt list statusline. Both now fail fast with invalid value 'claude-code'. (Breaking: wt list --format=claude-code and wt config state get --format=claude-code now error) (#3116)
Fixed
- cargo install worktrunk builds from crates.io: Installing from crates.io failed to compile with environment variable VERGEN_GIT_DESCRIBE not defined at compile time, because the package archive has no .git for the build script to read. The version lookup now falls back to the cargo package version when git-describe is unavailable. (#3124, fixes #3123, thanks @kerrickstaley for reporting)
- Tab-completion works in repos with no commits: wt switch <TAB> and wt remove <TAB> returned nothing on a fresh git init repo, because the unborn default branch has no entry under refs/heads/. Completion now also draws on worktree branches, so the unborn main (and any wt switch --create branch on an empty repo) completes. (#3097, closes #3094)
- wt config state get ci-status --format=json honors [forge].platform: On a self-hosted host the parser can't recognize (Gitea, Azure DevOps, GitHub Enterprise on a generic domain), this path reported provider: "unknown" while wt list --format=json reported the configured provider. All structured-output paths now route the [forge].platform override through one accessor, so they stay consistent. (#3120)
Documentation
- wt list --help example tables fit the terminal: The captured wt list example tables in --help chop to terminal width with a dimmed ellipsis (matching real wt list) instead of word-wrapping and shearing their columns; hand-authored command examples still wrap. (#3125)
- /wt-switch-create cross-repo hand |
| v0.59.0 | 17 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Picker frees digit keys for filtering; preview tabs move to Alt: In the wt switch picker, plain digits now go to the filter, so a branch name with a number in it can be typed directly. Preview tabs jump with Alt-1–Alt-5 or cycle with Tab/Shift-Tab. (Breaking: 1–5 no longer switch preview tabs) (#3079)
- Squash templates use commit_details instead of commits: The squash commit-message template's {{ commits }} variable (commit subjects) is deprecated in favor of {{ commit_details }}, which renders as the bare subject when printed directly and also exposes .subject and .body. wt config update migrates commits to commit_details as a plain rename. (#2985)
- wt step eval -v lists template variables: wt step eval -v now prints the available template variables on stderr in the gutter style, above the {{ template }} → result expansion it already showed. The result still goes to stdout, so $(wt step eval …) is unchanged. Since eval mutates nothing and is experimental, its --dry-run flag (which dumped the raw variable context) is removed rather than deprecated. (#3078)
Fixed
- Picker no longer freezes on the first keystroke: With many worktrees, typing the first character in the wt switch picker locked the UI for several seconds. The fuzzy matcher shares rayon's global thread pool with worktrunk's git collection, which floods it with blocking subprocess calls, so the matcher queued behind them. Collection and preview work now run on a dedicated pool, keeping the matcher responsive. (#3087, thanks @bendrucker; fixes #2926, thanks @mahume for reporting)
- Tab-completion covers all hook types: wt hook <type> <Tab> completed configured command names for only seven of the ten hook types; pre-switch, post-switch, and post-remove returned nothing. Completion now derives the type from the canonical hook list, so every type completes its command names. (#3070)
- Ctrl-C on a concurrent alias reports the right exit code: Interrupting wt step <concurrent-alias> could report exit 143 (SIGTERM) instead of 130 (SIGINT), because a per-child SIGINT → SIGTERM → SIGKILL escalation could land a SIGTERM on a child during the grace window; the escalation also serialized across process groups, so repeated Ctrl-C could wait. wt now forwards the user's signal once per process group, so a cooperative child dies from the signal actually sent (130 on Ctrl-C); a second signal kills any survivor immediately. (#3075)
Documentation
- Per-worktree env vars: A Tips & Patterns section shows how to give each worktree its own environment variables with direnv or mise. (#3074)
Internal
- The commit-generation command is not rewritten to disk when its value is unchanged. (#3084)
Install worktrunk 0.59.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.59.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.59.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.59.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
──────────────────────────────────────── |
| v0.58.0 | 13 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่น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, with wt config update offering 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, so wt <alias> | … works for that spelling too. (Breaking: multi-entry table-form pre-* hooks no longer run serially) (#3052)
- CI column shows the PR/MR number and review state: The CI column in wt list --full and the statusline shows the branch's open PR/MR reference (#3041 on GitHub/Gitea/Azure DevOps, !3041 on 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=json gains ci.number and ci.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, the wt switch - target) are consolidated under wt config state cache; cache clear drops them all without prompting, since everything regenerates. wt config state clear, which also wipes hand-authored markers and vars, now asks for confirmation; --yes skips, and non-interactive runs without --yes cancel. The ci-status, hints, and previous-branch subcommands 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 -vv logs each window's inputs and selection to .git/wt/logs/trace.log so the binding-window choice can be reconstructed. (#3057, #3053, #3029)
- /wt-switch-create branch 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/WorktreeRemove hooks validate the payload before running wt; a malformed payload previously created a branch named null or 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 the Notification event 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 --help no longer panics when piped: With no de |
| v0.57.0 | 9 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step diff --branch: wt step diff gained a -b/--branch flag, mirroring wt step commit, so the diff can target another worktree's branch without leaving the current one. The branch must have a checked-out worktree. (#2995)
- Squash templates can use commit bodies: The squash commit-message template gains an experimental {{ commit_details }} variable — a list of { subject, body } objects for the commits being squashed — alongside the existing {{ commits }} (now documented as the commit subjects). Templates can incorporate full commit bodies, not just subject lines. (#2983, thanks @florianilch)
- Recommended Claude Code commit command drops the CLAUDECODE= prefix: Claude Code removed the nested-session check that rejected claude -p launched from inside another session, so the workaround is gone. The recommended [commit.generation] command shown by wt config create no longer carries a leading CLAUDECODE=, and wt no longer strips CLAUDECODE from the environment before running commit-generation commands. (#2979)
Fixed
- Nushell wrapper installs where Nushell actually autoloads it: wt config shell install nu wrote wt.nu to $nu.default-config-dir/vendor/autoload, which Nushell never autoloads — on Linux the wrapper was written but silently never loaded, so wt was never wrapped (it happened to work on macOS/Windows by coincidence of path layout). It now installs to $nu.vendor-autoload-dirs | last, and install/uninstall clean up any worktrunk wrapper stranded at the old location. (#2992, thanks @nnutter for reporting)
- Claude Code hooks work for Fish shell users: The plugin's hook commands used ${CLAUDE_PLUGIN_ROOT} brace syntax, which Fish doesn't expand; they now use $CLAUDE_PLUGIN_ROOT, so the activity and worktree-lifecycle hooks fire correctly under Fish. (#2962, thanks @amw)
- Pager no longer wedges the terminal on Ctrl-C (Windows): Interrupting the --help pager (less) with Ctrl-C on Windows could leave the terminal in a broken state; less now quits cleanly on interrupt. (#2969, thanks @ofek for reporting)
- Clearer error when the default branch has no commits: In a freshly initialized repo whose default branch is unborn, merge/rebase/squash/push (and the diff report) failed with Default branch main does not exist locally plus a misleading hint to reset the cached value. They now report that the branch has no commits yet, without the wrong cache-reset suggestion. (#2990)
- diagnostic.md uploads as a gist again: The -vv diagnostic report inlined raw NUL bytes from NUL-separated git output, so gh gist create rejected it as a binary file. Control bytes in the subprocess preview are now escaped. (#2991)
- wt list tolerates a missing index file: A repo with no <gitdir>/index (nothing ever staged) made the temp-index probe fail; a missing index is now treated as an empty one, matching git's own behavior. (#2884)
- Inline code renders in --help section headings: Terminal --help showed literal backticks in headings authored with inline code (e.g. the wt config state logs heading Command log (commands.jsonl)). Headings now reduce inline code to plain text under the heading's uniform style. The --stage/--dry-run subsection headings in wt step commit/squash were also renamed to sentence case ("Staging", "Dry run"). (#3003)
Documentation
- wt switch docs give forge PR/MR URLs equal billing with pr:/mr:: The switch docs now present the full forge-URL form alongside the pr:N shortcut. (#2970)
- New FAQ entry on moving uncommitted changes to a new worktree. (#3002)
Internal
- Bare-repo prompt opt-out stored as a hint: worktrunk.skip-bare-repo-prompt moved under the worktrunk.hints. namespace, so it now lists under wt config state hints and clears with wt config state clear (previously a top-level key that escaped both). Clean cutover: users who already opted out are re-prompted once on their next wt switch --create in a dotted-name bare repo. (#3001)
Install worktrunk 0.57.0
Install prebuilt binaries via shell script
|
| v0.56.0 | 2 มิถุนายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt list JSON output includes repo_url: Each item now carries repo_url, the repository's web URL derived from the primary remote (absent when there's no parseable forge remote). It's the local checkout's repo — distinct from ci.repo_url, which is the repo a PR/MR targets. (#2941, thanks @bendrucker)
Fixed
- Bare-repo prompts: Two UX fixes. wt config create --project run in a bare repo with no linked worktrees now explains the next step (wt switch <branch> first, then create from inside the worktree) instead of failing with a generic "no worktree found". And the bare-repo worktree-path prompt no longer fires for symbolic identifiers (-, @, ^, pr:/mr:), where the example paths would be misleading — it waits for the next switch to a concrete branch name. (#2951, thanks @ammachado)
- Context gauge spacing in the Claude Code statusline: The context-gauge moon emoji rendered flush against the percent (🌕42%). Most terminals draw the emoji double-width and bleed it into the next cell, so the moon collided with the digits; it now carries a trailing space (🌕 42%). (#2944)
- Console storm on Windows: Detached background hook processes were created with DETACHED_PROCESS, which could flash a burst of console windows. They now use CREATE_NO_WINDOW and spawn fully hidden. (#2959, thanks @nathanbabcock)
Documentation
- Codex commit-generation model bumped to gpt-5.4-mini: The recommended [commit.generation] command for Codex — shown by wt config create and in the LLM-commits docs — now uses gpt-5.4-mini (was gpt-5.1-codex-mini). (#2949)
Internal
- Config-deprecation layer refactor: The deprecation detector now returns a Vec<DeprecationKind> instead of a struct of per-field flags, and the per-section config-table walks collapse into two combinators. Behavior-neutral — warning text and migration output are byte-for-byte unchanged. (#2946)
Install worktrunk 0.56.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.56.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.56.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.56.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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.55.0 | 30 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch accepts forge PR/MR URLs: wt switch https://github.com/owner/repo/pull/123 now resolves the same way as wt switch pr:123, and the URL form works anywhere a pr:N / mr:N shortcut does (positional argument and --base). Detection is shape-based, not host-based — any http(s):// URL whose path contains /pull/N, /pulls/N, /-/merge_requests/N, or /pullrequest/N matches, covering GitHub (including Enterprise), GitLab, Gitea, and Azure DevOps, including self-hosted instances. (#2898, thanks @thiagowfx for the request)
- -vv startup pointer names diagnostic.md: The -vv pointer now lists the shared log directory once with all three files it will contain — trace.log, subprocess.log, and diagnostic.md — so the diagnostic bundle is discoverable at startup rather than only when the gist hint fires at exit. The pointer verb reads Writing to … instead of Tracing to …. (#2919)
Fixed
- Claude Code plugin keeps unmerged branches during worktree cleanup: The plugin's WorktreeRemove hook passed -D (--force-delete) to wt remove, which removes a branch even when it carries commits that aren't merged or pushed. The hook now uses the default removal: a merged or integrated branch is removed cleanly, while one with unmerged commits is kept, with a wt remove -D <branch> hint for deleting it deliberately. (#2940, thanks @jbeda for reporting)
- wt list and wt step prune degrade gracefully on unborn worktrees: A linked worktree created with git worktree add --orphan sits on an unborn branch whose HEAD is the null OID. wt list used to show working-tree-diff (fatal: ambiguous argument 'HEAD') and a merge-tree error in its columns, and wt step prune aborted its entire scan with fatal: Needed a single revision, blocking pruning of every other worktree. Both now treat an unborn worktree as having no commits: wt list renders · for the commit-dependent columns, and wt step prune skips it (as it does locked worktrees) and continues. (#2937, thanks @nedtwigg for reporting)
Documentation
- Doc-site and --help prose cleanup: A writing-prose pass across the FAQ, config, list, remove, Claude Code, hook, LLM-commits, and Tips & Patterns pages (some via --help text in after_long_help). (#2922, #2925)
Internal
- Collapsed duplicated code paths and removed dead code left by completed cut-overs: A net reduction across the shell, git, and command layers. (#2931, #2932, #2934)
Install worktrunk 0.55.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.55.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.55.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.55.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 install
Install via Winget (Windows)
winget |
| v0.54.0 | 26 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Rate-limit pace segment in the Claude Code statusline: wt list statusline --format=claude-code now surfaces a yellow 1.3×pace(10am–3pm) segment when Claude Code's reported five-hour or seven-day rate-limit window is on track to be hit before its reset. The segment uses a Bayesian forecast on P(final ≥ 100%) so early-window bursts (e.g., 5% used at 3% elapsed) don't trigger spurious warnings — only the worse-projected of the two windows is shown, and the segment is hidden entirely when both are safe. The clock format inside the parentheses honors LC_ALL / LC_TIME / LANG: en_US/en_PH/en_CA get 12-hour (10am–3pm), everything else (including unset and C/POSIX) gets 24-hour (10:00–15:00). (#2899, #2911)
- wt step prune streams removals and never prompts mid-scan: Prune now bundles integration, removability, and age checks into a single parallel pass and starts removing candidates as soon as they qualify, instead of batching the scan and acting at the end. Dirty / locked / primary worktrees drop out before the age check, so a young + dirty + integrated worktree no longer surfaces as Skipped (younger than 1d) — the (younger than X) message now fires only when the worktree would actually have been pruned. With --yes, every project command is auto-approved as before; without --yes, a candidate whose hooks include an unapproved project command is SKIPPED with (approval required) rather than aborting the scan with an inline prompt the streaming structure couldn't accommodate. The end-of-run hint enumerates the unapproved hook templates from the invoking worktree's config and emits one copy-pasteable wt -C <path> remove line per skipped candidate, annotating candidates whose own .config/wt.toml differs from the invoking worktree's. (#2908, #2910)
- wt step prune default --min-age raised from 1h to 1d: A worktree just created from the default branch looks "merged" because its branch still points at the same commit; a one-day floor keeps an unattended prune from sweeping it up before its owner starts work. Explicit --min-age=0s or any other value is unchanged. (#2886)
- Legacy shell-wrapper deprecation warning: Users who upgrade wt without restarting their shell still run the previous release's wrapper, which sets only WORKTRUNK_DIRECTIVE_FILE instead of the new split WORKTRUNK_DIRECTIVE_CD_FILE / WORKTRUNK_DIRECTIVE_EXEC_FILE pair. That fallback used to be silent; wt now emits a one-shot per-process warning hinting at wt config shell install. bash, zsh, fish, and PowerShell pick up the new wrapper on the next shell restart; nushell is the one shell where users must rerun wt config shell install nu because its wrapper is a static file. (#2880)
- -vv no longer floods stderr; raw subprocess sink renamed to subprocess.log: A -vv invocation used to spray ~15K lines of stderr per command, forcing a redirect to a file even though trace.log already mirrored most of it. The debug-level log::* pipeline now writes to .git/wt/logs/trace.log at -vv; Info-level records (hook output, template expansions, the Tracing to … pointer) stay on stderr at every verbosity level. The companion raw-subprocess-bytes file is renamed from output.log to subprocess.log — the prior name read as "stuff wt printed" but actually held uncapped multi-MB subprocess bodies (git log -p, patch-id pipelines). RUST_LOG is now honored at every verbosity level: wt -v and wt -vv previously hardcoded Info / Debug and silently dropped any RUST_LOG directive (RUST_LOG=trace wt -vv was capped at Debug, RUST_LOG=worktrunk=trace wt -v was ignored); all three levels now flow through one builder shape with RUST_LOG layered on top of the flag baseline. (#2892, #2901, #2913)
Fixed
- Data-safety across the worktree merge / remove / prune lifecycle: Five TOCTOU and scoping fixes. wt merge and wt remove revalidate cleanliness and branch integration after pre-remove hooks run, so a hook (or concurrent process) that dirties the worktree or advances the branch can no longer t |
| v0.53.0 | 22 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch --execute deprecates shell command lines: A future release will switch --execute (-x) to an argv input model — a single program, with arguments after --, run with no implicit shell. This release is the warn phase: -x now warns when its value is a shell command line, multiple words, or template markup, and the hint shows a copy-pasteable migration (--execute sh -- -c '…') plus a link to comment on the cutover if the new form would regress a workflow. A single program name stays silent. (#2852, #2863)
- wt config show reports the project identifier: The PROJECT CONFIG section now prints the project identifier (<host>/<owner>/<repo> from the primary remote, or the canonical repo path), so you can find the key for a [projects."…"] block in your user config without deriving it by hand. wt config show --format=json gains a matching identifier field. Closes #2826. (#2827, thanks @airtonix for the request)
- Gemini CLI extension detection: wt config show now renders a GEMINI CLI section reporting whether the worktrunk Gemini extension is installed. The agent-integration docs gained install instructions for OpenCode and Gemini CLI alongside Claude Code and Codex. (#2819)
- pre-create/post-create hook aliases: The worktree-creation hooks pre-start/post-start now also accept pre-create/post-create as silent aliases — in config (top-level, [hooks.*], and per-project sections, in string, table, and array-of-tables form) and on the wt hook command line. Docs continue to recommend pre-start/post-start; the canonical names may switch in a later release. Full plan: #2838. (#2840, #2857)
Fixed
- Hooks resolve project config from the invoking worktree: Worktrunk resolved each hook's .config/wt.toml from a different worktree depending on the hook, and wt switch --create read the base ref's committed config via git show — so an uncommitted or branch-local .config/wt.toml silently failed to fire creation hooks, and wt config show disagreed with what actually ran. Every hook now resolves its commands from the .config/wt.toml of the worktree wt ran in — the same file wt config show displays. In the common case of a committed, repo-wide config this is unchanged; it diverges only when a branch carries its own working-tree edits. Fixes #2856 and #2818. (#2873, thanks @Oxygen66 and @sirianni for reporting)
- Picker prompts for approval before running project pre-switch hooks: Selecting a worktree in the interactive picker (wt switch with no argument) ran a project-defined pre-switch hook from .config/wt.toml without the approval prompt that gates every other hook — unapproved code from a freshly cloned repo executing silently. The picker now routes pre-switch hooks through the same approval gate as wt switch <branch> and as its own post-switch/pre-start/post-start hooks. (#2858)
- Interactive picker switches with cd = false: With [switch] cd = false (or wt switch --no-cd), opening the picker (wt switch with no branch argument) and selecting a worktree printed the branch name and exited — no switch, no hooks, and Alt-c created nothing. The picker now runs the same switch pipeline as wt switch <branch>, suppressing only the cd directive: pre-switch/post-switch hooks fire and Alt-c creates the worktree. --format=json works in the picker too, and replaces the old print-only output for scripting — it both switches and prints a structured result (action, branch, path) to stdout. (#2845, thanks @endigma for the discussion in #2837)
- alt-r in the picker removes the right worktree: The interactive picker identified each row by branch name for its alt-r removal signal; detached worktrees all report (detached), so two detached rows collided and alt-r could remove the wrong worktree. Rows backed by a worktree now carry a unique path-based identity. (#2866)
- --clobber backs up blocked paths atomically: wt switch --clobber and wt step relocate --clobber back up a path blocking the target before clobbering it. Both used an exists() |
| v0.52.0 | 19 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step tether: New [experimental] operation that runs a command in its own process group and kills the whole group when the command exits or its worktree is removed (a 250ms portable poll — killpg on Unix, taskkill /T /F on Windows). A single post-start hook (wt step tether -- npm run dev) replaces the usual post-start-to-launch / pre-remove-to-stop pair, and unlike pre-remove it also cleans up after a git worktree remove, an rm -rf, or a crashed hook — the leak path that eventually saturates macOS fseventsd. Arguments after -- run directly with no shell, matching wt step for-each. (#2785)
- Gemini CLI extension: Worktrunk now ships a Gemini CLI extension for wt list activity tracking, installable with gemini extensions install max-sixty/worktrunk. The extension's manifest, hooks, and skills resolve at the repo root, so the GitHub-name install path works without a local clone. (#2803, #2807, thanks @rafavital for the request in #2763)
Fixed
- Project hooks are frozen at the approval gate: A project-defined pre-*/post-* hook command was selected from .config/wt.toml twice — once to build the approval prompt, once at execution — and the operation itself mutates state between the two reads (a merge moves the target ref, an auto-rebase rewrites the feature config, a removal scrubs the worktree, git worktree add materializes a --create worktree). The second read could select a command the user never approved; on a freshly cloned repo that is unapproved code execution. The gate now freezes the command set into an immutable plan that the executor consumes verbatim, so post-operation hooks can never run an unapproved command. Behavior is otherwise unchanged, and wt merge --no-hooks (or a declined/empty plan) now returns before loading approvals, so a malformed approvals.toml no longer aborts a command that had nothing to authorize. (#2806)
- Declining the wt merge commit-append no longer skips hooks: When a project's pre-merge/post-merge hooks were already approved, wt merge bundled the commit-message append into the same prompt; declining the lone append prompt skipped every hook for that run even though the user only meant to skip the append. The append is now gated on its own path (the same one wt step commit/wt step squash use), so declining it drops only the append. On a fresh repo where both the hooks and the append are unapproved this is now two prompts instead of one bundled prompt. Decline messages are also canonicalized across merge, remove, prune, and switch (Commands declined, … without hooks). (#2802)
- Windows wt step prune .git/config race: wt step prune could intermittently fail on Windows with unable to access '.git/config': Permission denied — its parallel branch-integration checks read .git/config while an inline git branch -D rewrote it via git's lockfile rename, which on Windows briefly blocks concurrent readers. Branch-integration reads are now excluded from overlapping the git branch -D that rewrites config. (#2808)
Install worktrunk 0.52.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.52.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.52.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.52.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-aarch64-apple-darwin.tar.xz │Apple Silicon macOS│checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-x86_64-apple-darwin.tar.xz │Intel macOS │checksum
────────────────────────────── |
| v0.51.0 | 18 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Codex support: Worktrunk now ships a first-class Codex plugin alongside the Claude Code one. wt config plugins codex install installs it; wt config show --full reports its state. The Codex plugin bundles the shared configuration skill — documentation the agent reads to help set up LLM commits, hooks, and troubleshooting. Codex exposes no turn-end or worktree-lifecycle hooks, so unlike Claude Code it has no wt list activity tracking or session worktree isolation; the skill is the integration. Docs (#2512, thanks @douglas; #2780, #2782, #2786)
- Experimental project-level commit-message guidance: [commit.generation] template-append adds to the commit/squash LLM prompt instead of replacing it (template still replaces), and is now valid in both user config and project .config/wt.toml. The user fragment renders into a <user-guidance> block (no approval); the project fragment renders into a gated <project-guidance> block bundled into the existing wt merge hook-approval prompt — declining is non-fatal. User-only commit-generation keys placed in project config still get the "this belongs in user config" redirect. (#2774, #2790, thanks @gabimoncha for the request in #2758)
- /wt-switch-create takes an optional repo and a -- task delimiter: The Claude Code skill now accepts <branch> [<repo>] [-- <task>]. The optional second token names a different repository to create the worktree in; -- cleanly separates the task from the rest. Without a --, a path-shaped second token is treated as the repo and the remainder as the task. (#2751)
- wt list --full and wt statusline count untracked files in HEAD±: The HEAD± working-diff segment now includes untracked-file lines under --full and in wt statusline, matching wt step diff. Default wt list and the picker stay on the cheap tracked-only path. (#2764)
- wt step prune and wt list no longer stall on long-divergent branches: The patch-id squash-merge scan (is_squash_merged_via_patch_id) ran git log -p over the entire target-side history — tens of thousands of commits on a fast-moving repo, taking seconds to tens of seconds. It's now capped at 500 commits via a cheap graph-only pre-flight; above the cap the check returns "not squash-merged" (the safe answer). (#2752)
Fixed
- Config deprecation-layer correctness: Three independent fixes — structural migration now preserves unrelated [ci] keys and unparsable deprecated sections instead of discarding them; config update aborts on an approvals-copy I/O failure instead of silently dropping approvals; deprecated template-variable renaming rewrites the parsed TOML tree instead of doing a raw text replace that corrupted occurrences inside escaped strings. (#2783)
- Data-safety and correctness fixes: Six independent single-file fixes — wt step relocate --clobber refuses to overwrite an existing backup; wt remove re-checks cleanliness immediately before a forced submodule removal (time-of-check/time-of-use); wt switch re-discovers the base worktree via a fresh Repository after worktree add instead of reading a stale cached list; wt switch pr:<N> derives owner/repo from the forge remote rather than the primary remote and validates an empty Azure source branch at the provider boundary; user-controllable branch operands are guarded with --. (#2784)
Documentation
- Alias template timing: A new Aliases subsection documents that templates render at alias dispatch using the invoking worktree's context, so a nested wt command's own template variables resolve against the outer worktree unless wrapped in {% raw %}…{% endraw %}. Fixes #2753. (thanks @viicslen for reporting) (#2754)
Internal
- The Claude Code and Codex plugin payloads are consolidated into one shared directory. (#2789)
- WORKTRUNK_BOT_TOKEN is renamed to TEND_BOT_TOKEN in non-tend CI workflows. (#2781)
Install worktrunk 0.51.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.51.0/worktrunk-i |
| v0.50.0 | 13 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Experimental Azure DevOps support: wt switch pr:<N> resolves Azure DevOps pull requests via the az CLI — auto-detected from dev.azure.com / ssh.dev.azure.com / *.visualstudio.com remotes, or pinned with [forge] platform = "azure-devops". wt list --full surfaces Azure DevOps PR and pipeline CI status, and wt config show --full reports az install/auth state when Azure DevOps is the detected platform. Requires the azure-devops CLI extension. GitHub still wins in mixed-remote setups. (#1256, thanks @mikeyroush; thanks @dlecan for #1144)
- Experimental Gitea support extended to wt list and wt config show: wt switch pr:<N> already resolved Gitea PRs via the tea CLI; wt list --full and wt config show --full now recognize Gitea repos too — wt list --full shows 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, and wt config show --full reports tea install/auth state. (#1320, thanks @SjB; #2702, #2707, #2732)
- Hooks resolve project config from the worktree they act on — no primary-worktree fallback: Previously pre-remove read the primary worktree's .config/wt.toml rather than the worktree being removed, and post-remove / post-switch read the post-removal working directory's config, so a pre-remove (or post-remove) you added on a feature branch never fired when removing that branch's worktree. Now every hook reads the .config/wt.toml of the worktree it acts on — pre-remove / post-remove read the removed worktree's config (snapshotted before removal), post-switch reads the destination worktree's — and the approval prompt collects hook commands from that same worktree, so a branch-local pre-remove always appears in the prompt before it runs. A worktree with no .config/wt.toml runs 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's pre-remove / post-remove hooks 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.toml to 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 show with 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 (and wt step --help) drop the inline aliases table for a compact names-only list that points here. (#2684, #2691, #2688)
- wt switch picker validates hook templates before creating the worktree: Creating a branch from the picker (Alt-C) now runs the same template pre-flight that wt switch --create does, so a project config with a broken hook template (syntax error, undefined variable) fails before git worktree add instead of after — no orphaned worktree left blocking a re-run with the same name. (#2712)
- wt list --branches skips a serial graph walk on warm runs: Branch ahead/behind counts for the main↕ and Remote⇅ columns are now cached SHA-keyed, so a warm wt list --branches no longer pays the single-threaded git 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% of wt list's wall time. The push-remote URL is cached and the local-branch scan is shared with capture_refs, removing two more duplicate for-each-ref invocations per render. (#2704, #2718, #2673)
- Claude Code plugin ships the wt-switch-create skill: Installing the worktrunk Claude Code plugin now provides /wt-switch-create <branch> [task], which calls EnterWorktree to create (or re-enter — it's idempotent) a worktree in worktrunk's sibling layout (<repo>.< |
| v0.49.0 | 10 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- New codename(n) template filter: Produces deterministic friendly names from any input string — codename(1) returns a noun, codename(2) returns adjective-noun, higher counts add more adjectives. The pool is large enough (~1.26M combinations for codename(2)) that the result usually stands alone as a worktree leaf, e.g. worktree-path = "{{ repo_path }}/../{{ repo }}.{{ branch | codename(2) }}". (#2641, thanks @endigma)
- Picker preview disk cache: The wt switch picker now caches Log, BranchDiff, and UpstreamDiff previews to disk under .git/wt/cache/picker-preview/, keyed by SHA + width, so repeat invocations skip the git log / git diff subprocesses they already paid for. The Log cache splits SHA-deterministic raw output from the dim/bright styling that depends on main's position, and a background refresh worker rewrites stale entries after every disk hit so the next visit sees up-to-date ref decorations. State integration bundles the new cache with the existing git-commands cache for wt config state get / state clear --all. (#2628, #2646)
- Picker fans out fewer git rev-parse calls: compute_branch_diff_preview previously forked git rev-parse <default_branch> once per item to key its disk cache. A new Repository::default_branch_sha() reads the SHA from the already-cached branch inventory, collapsing N redundant subprocesses down to one. (#2658)
- "X has uncommitted changes" errors now list the dirty files: GitError::UncommittedChanges carries the porcelain lines from git status and the renderer prints them between the title and hint, so users hitting the error on wt remove, wt merge cleanup, wt step promote, or wt merge --no-commit see exactly what's blocking without re-running git status. No new git subprocesses — is_dirty() was already running git status --porcelain and discarding the output. (Breaking: GitError::UncommittedChanges gained a dirty_files: Vec<String> field.) (#2653)
Fixed
- wt switch integrates with cd aliases like zoxide: Previously the shell wrapper invoked the cd shell function directly, so users with cd aliased to __zoxide_z or similar saw zoxide: no match found when switching to a fresh worktree. The bash and zsh wrappers now use builtin cd to bypass the alias. Fixes #2643. (#2644, thanks @xkumiyu for reporting)
- Empty hook tables no longer panic during wt switch --create: A config like [post-start] with no entries below it would crash the background HookAnnouncer path. The config layer now treats an empty hook table as zero steps. Fixes #2634. (#2635, thanks @topit for reporting)
- Repository accessors no longer leak the process CWD: Repository::current_worktree() resolved against the global CWD instead of the Repository's own discovery path, so callers using Repository::at(p) (output handlers, picker, recovery, tests) silently got a WorkingTree at the process CWD rather than at p. Five sibling sites had the same bug — project_config_path, project_config, require_current_branch, resolve_worktree_name("@"), resolve_worktree("@"). Fixed at the helper itself, replacing PR #2625's per-site workaround. (#2652)
- WorkingTree::is_linked tolerates non-git CWDs: When wt's process CWD was outside any git repo (e.g. the Nix build sandbox), infer_default_branch_locally would error out trying to call is_linked on a non-git path. The check now returns false instead. Fixes #2624. (#2625, thanks @DArtagan for reporting)
- Picker no longer overlays warnings on the active TUI: Warnings emitted by collect::collect (stale default branch, batch-fetch failure, drain timeout) used to print to stderr from a background thread while skim's TUI owned the terminal, corrupting the rendered frame and leaving fragments visible after the user picked. Warnings now stash through the picker and drain to stderr after skim releases the terminal. The drain-timeout warning is also subcommand-agnostic instead of hardcoding wt list. (#2627)
- Picker clears its frame on exit in inline mode: On some Linux terminals the picke |
| v0.48.0 | 5 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- --format=json extends to seven more commands: wt step rebase, wt step push, wt step commit, wt step squash, wt step relocate, wt step copy-ignored, and wt hook show now accept --format=json. Shapes follow the existing pattern (additive on stdout; human prose stays on stderr) and use stable snake_case outcome discriminators where the result has multiple variants. (#2560)
- wt step commit and wt step squash gain --dry-run: Renders the prompt, prints the shell invocation that would call the LLM, calls the LLM and prints the generated message in three labeled sections (PROMPT, COMMAND, MESSAGE), then exits without staging, running hooks, or committing. For commit, --stage is honored against a temporary index — the previewed prompt matches what a real run would send the LLM, but the user's real index is never touched. --show-prompt is now hidden from --help but kept working for piping the rendered prompt to another LLM. (#2557)
- New dirname and basename template filters: Two new filters expose Path::parent and Path::file_name, enabling path traversal that previous filters couldn't express. They unblock the bare-repo-in-hidden-directory layout (myproject/.git), where {{ repo }} resolves to .git: users can write {{ repo_path | dirname | basename }} to recover myproject. (#2592, #2605, thanks @seakayone for reporting #1279 and @Xilis for raising the parent_dir question)
- New [remove] delete-branch config option: Setting delete-branch = false defaults wt remove to keeping branches, equivalent to passing --no-delete-branch every time. CLI flags still override the config either direction. (#2589, thanks @jameslairdsmith for #2587)
- wt-perf timeline subcommand for trace capture: One command runs wt, captures stderr, parses [wt-trace] records, and prints a column-aligned text timeline (sorted by start time, with subprocess totals and externally-measured wall) or emits Chrome Trace Format JSON for Perfetto. Replaces the previous RUST_LOG=debug wt … 2>&1 | wt-perf trace > trace.json dance. (#2558)
- wt list skips redundant merge-tree probes on dirty worktrees: For dirty worktrees with no unmerged entries, the dirty-tree probe is authoritative and the HEAD-only probe is skipped — one merge-tree subprocess per dirty row instead of two. The dirty probe also reflects the current working state, so when uncommitted changes resolve a HEAD conflict, wt list no longer reports it as conflicting. (#2602)
- Faster alias dispatch: Two changes compound to cut warm alias-dispatch latency by ~25 ms — Repository::prewarm overlaps the three independent pre-dispatch reads (rev-parse, git config, user-config TOML) on scoped threads instead of running them in series, and build_hook_context only executes the four shell-out blocks (default_branch, primary_worktree, commit/short_commit, remote/remote_url/upstream) when the alias body actually references those template variables. (#2556, #2573)
- Short-SHA display honors core.abbrev: Sites that abbreviated a commit SHA previously sliced &sha[..7] or ran ad-hoc git rev-parse --short calls — 7-char prefixes regularly collide in larger repos and none of the slicing sites respected core.abbrev. The step commit / step squash success lines, the step push --no-ff "Merged to" line, the {{ short_commit }} template variable, post-remove hook context, the safety-backup ref display, the orphan-check (detached <sha>) label, and wt list row display all route through one canonical helper now. (#2576, #2577, #2584)
- Shell-integration hint escalates after repeat showings: worktrunk.hints.<name> migrates from "true" to an integer counter so the system tracks how many times a hint has been displayed. After 5+ displays of the shell-integration install hint, it appends a wt config show pointer so users who keep seeing it can investigate why their wrapper isn't intercepting. Legacy "true" values parse as 0, so the next display normalises to 1; first-time-skip behaviour is unchanged. (#2603)
- Cleaner wt confi |
| v0.47.0 | 3 พฤษภาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch <number> suggests pr:N / mr:N first: When wt switch 2474 fails because no branch by that name exists, the hint now leads with how to switch to the matching PR/MR before mentioning --create. Platform is detected by hostname-matching the primary remote's effective URL (so url.insteadOf rewrites are respected): GitHub → wt switch pr:N, GitLab → wt switch mr:N, unknown host → both. Non-numeric branch names keep the original hint unchanged. (#2516)
- Faster alias and hook dispatch: Trivial-alias wall time drops 30.4ms → 20.4ms (1.49× via hyperfine) from three changes — replacing the 10ms try_wait+sleep poll in Cmd::stream with an event-driven Signals::forever() listener (and the matching 25ms poll in spawn_signal_forwarder), merging the two cold-path git rev-parse forks (--git-common-dir and the prewarm_info batch) into one, and loading user and project config on scoped threads instead of sequentially. Ctrl-C latency on concurrent steps drops from "up to 25 ms" to "as soon as signal-hook delivers". (#2537, #2538, #2541, #2543)
- Running … hook announce uses one canonical grammar: Replaces the overloaded Running <hook>: ... punctuation with a layered grammar where each separator carries one meaning — & joins concurrent commands within a step, , joins serial steps within a pipeline, ; joins source pipelines and hook-type clauses. Source label moves to a per-pipeline suffix annotation (sync, push (user)), so multi-source events no longer double-colon, and multi-hook-type events bundle onto a single line: Running post-commit: mark (user); post-remove: cleanup (user); post-switch: notify (user); post-merge: sync (user) @ ~/repo. (#2504)
- (user) / (project) source labels no longer rendered bold: The Running … background-hook announce wrapped each pipeline's source label in <bold>, producing visually noisy bold inner text against parens that weren't bold. Source labels render as plain inner text now; named command names (sync, push, …) stay bold as before. (#2514)
Fixed
- Integration detection now ORs local + upstream: wt list, wt remove, wt merge, and wt step prune previously checked a single integration target picked by effective_integration_target, so a branch merged into local main while origin/main had unique commits (or vice versa) was misreported as unintegrated and skipped. integration_reason now considers both — integrated if either matches. (#2507, #2513, #2515)
- wt step copy-ignored no longer writes outside the destination through symlinked directories: A symlinked destination directory (e.g. target -> /tmp/outside) let copy-ignored create files outside the worktree; --force made it riskier still by overwriting outside files. New guarded entry points reject paths whose resolved parent chain escapes the destination root. Leaf-symlink behavior is unchanged. (#2501, thanks @douglas)
- wt step copy-ignored no longer hardcodes .pi/ in built-in excludes: Removed from the default excludes list; users who need it can add it via the [step.copy-ignored] config. (#2527, thanks @indigoviolet for reporting #2526)
- wt step for-each -- <argv> preserves quoting and argument boundaries: The post--- argv was rebuilt with args.join(" ") and passed through sh -c, breaking anything with spaces, ;, or shell metacharacters inside an argv element. It's now exec'd directly with no implicit shell. Users wanting shell features (pipes, redirects, $VAR, globs) write sh -c '<snippet>' explicitly — same pattern as xargs, find -exec. (Breaking: previously wt step for-each -- <snippet> accepted shell snippets without sh -c; for-each is [experimental].) (#2465)
Documentation
- extending.md hooks-vs-aliases comparison gains a stdin row: The comparison table covered invocation, positional handling, approval flags, source filters, and template-context extras, but never said anything about stdin. Hooks have always received the template context as JSON on stdin; aliases inherit the parent's stdin so pipes pass through and intera |
| v0.46.1 | 30 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- No spurious Skipping pre-commit hooks (--no-hooks) line after declined approval: wt step commit, wt step squash, and wt merge collapsed two distinct hook-skip reasons — the user passing --no-hooks and the user declining an interactive approval prompt — into a single verify: bool. With hooks configured, declining produced both ○ Commands declined, committing without hooks and ○ Skipping pre-commit hooks (--no-hooks) back-to-back; the second line was wrong because the user never passed --no-hooks. The call chain now carries a HookGate (Run / NoHooksFlag / Silent), so declined-approval paths skip hooks silently while the explicit --no-hooks flag still prints its message exactly once. (#2485)
Internal
- HookAnnouncer is the single entry point for hook dispatch: post-commit and post-switch now route through the same announcer used by other phases, and remaining call sites adopt TemplateVars for variable assembly. (#2481, #2482, #2484)
- Merge cleanup extracted: The post-merge finish sequence moves into worktree::finish_after_merge, and wt list threads the placeholder explicitly instead of reaching through Cell. (#2491, #2492)
- CI consolidated onto a shared composite action: New advisory cargo-affected jobs land, and the test matrix and affected-jobs setup now share one composite action. (#2475, #2483, #2486)
Install worktrunk 0.46.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.46.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.46.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.46.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.46.0 | 29 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- sanitize_db template filter caps output at 48 chars (was 63 — PostgreSQL's identifier limit). The new budget leaves headroom for users composing the output into longer paths or identifiers, e.g., Unix socket paths capped at 107 bytes. The 3-character hash suffix is unchanged, so collision avoidance is preserved at the new budget; only the truncated base shrinks. (Breaking: branches whose previous sanitize_db output exceeded 48 chars get a different identifier — most names are well under 48 and pass through unchanged.) (#2467, thanks @yajo for #2397)
- New hash template filter: {{ value | hash }} produces a 3-character base36 digest of the input — useful for composing custom truncate-with-collision-avoidance recipes when sanitize_db's 48-char budget still isn't tight enough. (#2453)
- Background hook announces collapse to one line per command: wt merge (with removal) previously emitted two or three separate ◎ Running … lines for post-remove + post-switch and post-merge. Hooks across all phases of a single command now share one combined announce: ◎ Running post-remove: user:cleanup; post-switch: user:notify; post-merge: user:sync. (#2457)
- Picker-driven post-switch hooks now receive target / target_worktree_path template variables, matching hooks fired from wt switch <branch>. Closes a pre-existing asymmetry where interactive switching exposed strictly fewer variables than the non-interactive path. (#2470)
Fixed
- wt <alias> stdout is pipeable again: wt my-alias | tr … (and any other downstream pipe) silently produced no output because the foreground executor redirected every alias body's stdout to wt's stderr — a hook-only redirect that PR #2089 inherited uniformly. Aliases now pass stdout through; hooks and wt step for-each keep the merged-stderr behavior so their output stays ordered with wt's own status messages. (#2479, thanks @davidmyersdev for reporting #2478)
- wt switch <symlink> resolves to the existing worktree instead of failing with No branch named …. The path-based fallback in Repository::worktree_at_path previously compared paths via lexical normalization only, so symlink-equivalent spellings never matched. The same symlink-aware comparison is now used everywhere the library identifies a worktree by path. (#2466)
- Deleted-CWD recovery handles symlinked subdirectories: When a worktree is removed while a shell sits in a subdirectory whose parents include a symlink (e.g. ~/link/repo.feature/src), wt now finds the parent repository and recovers as expected. Previously the symlink-aware path compared only file names and bailed for any path deeper than the worktree root. (#2464)
- Merge safety backups for slash branches: WorkingTree::create_safety_backup() flattened / to - in the ref path, so distinct branches like a/b and a-b collided at the same refs/wt-backup/a-b ref — the latest backup for one could clobber the other, and the documented refs/wt-backup/<branch> recovery path didn't match what was actually written. Slashes are valid in git ref names; the branch name is now used as-is. (#2463)
- Nushell wrapper migrates to function-level @complete: Per fdncred's recommendation in nushell/nushell#18128, the wrapper replaces the parameter-level [...args: string@"nu-complete wt"] with a function-level @complete attribute on an untyped [...args] rest, and the completer signature moves from [context: string] (with manual split row " " reconstruction) to [spans: list<string>]. Net deletion of seven lines of fragile token reassembly; once nushell/nushell#18131 ships in stable nu the wrapper will automatically benefit from --flag="value" quote stripping and ~ expansion. (#2458)
Internal
- Hook dispatch unified: A single HookAnnouncer orchestrates per-command announces across phases, replacing scattered CommandOrigin-keyed dispatch with closures, and the various background-hook entry points now share one path. Switch and merge sites assemble template variables through a single TemplateVars builder. (# |
| v0.45.2 | 28 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- Interactive pickers via aliases no longer freeze with a blank screen: After the v0.44.0 fix that let aliases inherit the controlling tty (#2380), wt sw (and other aliases that wrap wt switch) still hung — the alias child was placed in a new process group, so when the skim picker called tcsetattr on /dev/tty the kernel raised SIGTTOU and stopped it mid-render. The interactive (no-stdin-payload) execution path now keeps the alias child in wt's process group; a PID-targeted signal forwarder ensures externally-delivered signals (kill -TERM <wt-pid>) still reach the child. Hooks (which receive JSON on stdin) are unaffected. (#2444)
Improved
- wt <alias> --help hint follows output guidelines: The hint emitted on wt <alias> --help previously printed to stdout without a status symbol, used backticks around commands, and stacked three indented bullet suggestions. It now renders as an info line plus a single semicolon-joined hint on stderr, with commands styled via underline (dim-safe). (#2447)
Install worktrunk 0.45.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.45.2/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.45.2/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.45.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.45.1 | 28 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- worktrunk builds again with --no-default-features (regression in v0.45.0): The TTY progress spinner added in #2420 used crossterm unconditionally, but crossterm is gated behind the cli feature in Cargo.toml. cargo install --locked --no-default-features worktrunk and library consumers depending on worktrunk with default-features = false failed to compile. The crossterm-using internals are now #[cfg(feature = "cli")]-gated; without cli, Progress degrades to a no-op (the public API is unchanged). The bug slipped past the in-workspace cargo hack check --feature-powerset --no-dev-deps because workspace dev-dependencies pull crossterm in transitively and Cargo's feature unifier leaks it into the lib build. (#2441)
Improved
- Deprecation warnings for --claude-code flag and wt hook post-create alias: Both surfaces previously mapped silently to their canonical replacements (--format=claude-code and pre-start), giving users no signal to migrate before eventual removal. Each invocation now emits a stderr warning, matching the pattern used by wt select, --no-verify, and wt hook approvals. (#2436)
Install worktrunk 0.45.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.45.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.45.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.45.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.45.0 | 27 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt remove --foreground shows a TTY progress spinner: Removing a worktree with a fat node_modules (or any large trash payload) now prints ⠼ Removing 7,272 files · 64.5 MiB to stderr while the unlink proceeds, with a matching (N files · X MiB) suffix on the success line. TTY-gated; pipes and the background path are byte-for-byte unchanged. Driven by the same machinery introduced for wt step copy-ignored in #2413. (#2420)
- wt step copy-ignored shows a TTY progress spinner: Large copies of node_modules, build/, or target/ previously ran silently. A stderr-only spinner (⠼ Copying 7,272 files · 64.5 MiB) ticks while the copy proceeds, gated on TTY + verbosity == 0 + not --dry-run, with a 300ms startup delay so sub-second copies stay quiet. (#2413, thanks @tehdb for the suggestion)
- wt switch -c <new> --base <name> accepts a remote-only base: --base releases/4.x.x previously failed with No branch, tag, or commit named "releases/4.x.x" when the branch existed only as a remote-tracking ref. The bare name now resolves through the single matching remote (the existing safety code still unsets the new branch's upstream so a stray git push doesn't target the base). Multi-remote and zero-remote cases pass through unchanged. (#2411, thanks @viicslen for reporting #2410)
- LLM wt step commit summaries surfaced in wt config state: wt config state get now includes a SUMMARY CACHE table (and JSON section) listing per-branch entries, and wt config state clear removes them alongside markers/vars/CI status. Backed by a new content-addressed layout at .git/wt/cache/summary/{branch}/{hash}.json so a cache hit is a single file-existence check. (#2407)
Fixed
- wt config state clear no longer reports "Cleared 0" when an I/O or config error actually occurred: Across markers, vars, previous-branch, default-branch, and CI-status (single + aggregate), eleven unwrap_or(false) / let _ = unset_config(...) swallows silently turned real failures into "nothing to clear" messages. Genuine git config --unset failures and read_dir/remove_file errors now surface; the common "key didn't exist" exit-5 path stays silent. The shared clear_* machinery for the on-disk caches is now consolidated in worktrunk::cache. (#2394, #2400)
- wt config state ci-status clear <branch> actually clears the cache file: The single-branch path was still calling unset_config("worktrunk.state.<branch>.ci-status") from before the cache moved to .git/wt/cache/ci-status/<branch>.json. The command always took the info branch and never touched the real cache; --all was already correct. (#2392)
- wt config state get/clear ci-status for origin/foo-style branches when a same-named local branch exists: A local branch literally named origin/foo would shadow the remote-tracking ref — is_remote resolved against the remote while the SHA used for cache keys came from the local branch, so gh/glab was invoked for the remote while the cache tracked the local. A single for-each-ref query now sources is_remote, the short name, and the HEAD SHA from the same ref. Tags and raw SHAs passed via --branch now return BranchNotFound instead of being accepted as "local branches" with nonsensical CI lookups. (#2388)
Documentation
- worktrunk.dev/llms.txt plus .md companions for every page: Each docs page is now also served as clean markdown at worktrunk.dev/<page>.md, with an llms.txt index per the llms.txt spec so LLM tools can find the docs without scraping HTML. (#2404)
- Static command-output blocks for the GIF-heavy docs pages: merge, step, remove, hook, and llm-commits now include realistic colorized command-output blocks driven by insta snapshots, alongside (or instead of) the GIFs — so they stay in lockstep with what wt actually prints. (#2405, thanks @drewnoakes for reporting #2403)
- Conda / Pixi installation listed in the install section: The README and worktrunk-page install table now mention the conda-forge package alongside Homebrew, Cargo, winget, and pacman. (#2425, thanks @noamg |
| v0.44.0 | 22 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- Interactive alias children (e.g. sw = "wt switch") keep the tty again: Alias execution was piping the template context JSON into each child's stdin, displacing the controlling terminal; interactive commands like wt switch then saw a pipe and bailed with Interactive picker requires an interactive terminal. Hooks still receive the documented JSON-on-stdin contract; aliases now inherit stdin unchanged. (#2380, thanks @KieranP for reporting in #406)
- wt list --remotes stats were shadowed by a same-named local branch: If a user created a local branch literally named origin/foo, the remote row for origin/foo silently reported ahead/behind (and every other integration stat) against the local branch, because git rev-parse prefers refs/heads/ over refs/remotes/. Integration helpers now pass fully-qualified refs; a follow-up refactor makes the disambiguation unrepresentable at the type level by storing full refs on BranchRef. (#2365, #2378)
- {{ commit }} resolves to the per-worktree HEAD in wt step for-each on detached worktrees: The hook context was reading HEAD via a process-CWD-keyed cache, so when for-each iterated over sibling worktrees with one on detached HEAD, {{ commit }} resolved to the running worktree's SHA instead of the sibling's. (#2382)
- Global-scope core.worktree no longer misdetects the repo root in normal non-bare repos: The 0.43.0 repo_path() fast path (#2350) read core.worktree from the bulk config map, which merges global and system scope — but git itself only honors core.worktree from local config for worktree discovery. When the bulk map reports core.worktree we now delegate to git rev-parse --show-toplevel so git applies its own scope rules. The common case (no core.worktree anywhere) still skips the subprocess. (#2362)
- post-create hook config is now rejected with an explicit error instead of silently migrating to pre-start: Paves the way to reclaim post-create as a background-semantics counterpart to post-start (see #1571). (Breaking: existing configs using post-create must be renamed to pre-start.) (#2361)
Internal
- Branch enumeration consolidated into a single canonical inventory, with follow-on perf wins: Five overlapping for-each-ref accessors in src/git/repository/branches.rs collapsed into two cached scans (refs/heads/ and refs/remotes/), exposed as Repository::local_branches() and remote_branches(). Shared inventory also powers Branch::remotes() (#2371), strip_remote_prefix (#2372), and is_remote_tracking_branch (#2377), dropping a rev-parse/git remote subprocess each. BranchRef stores full refs (#2378); prewarm_info returns a typed snapshot with HEAD SHA folded in (#2367); alias on-branch dispatch reuses the cached HEAD SHA (#2374); list_worktrees caches on RepoCache (#2375, #2383); wt list commit subjects batched pre-skeleton, retiring CommitDetailsTask (#2369, #2379); picker's speculative preview warm-up primes prewarm_info once (#2381). (Breaking library API: Repository::list_local_branches, list_remote_branches, list_tracked_upstreams, list_untracked_remote_branches, commit_timestamps, commit_details, current_worktree_info, Branch::upstream_single, and BranchRef { branch, is_remote } fields are removed; Repository::batch_ahead_behind returns ().) (#2368)
Install worktrunk 0.44.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.44.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.44.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.44.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
────────────────────────────────────────────────┼───────────────── |
| v0.43.0 | 21 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- wt step copy-ignored no longer self-lowers priority in the foreground: Since v0.37.0, copy-ignored wrapped its work in taskpolicy -b (macOS) / ionice -c3 (Linux) unconditionally, which throttled disk I/O for interactive runs and synchronous pre-* hooks — not just the background post-start flows the lowering was meant for. Detached background hook pipelines now set an internal sentinel, and copy-ignored only self-lowers when it sees it. Interactive wt step copy-ignored and foreground hooks run at normal priority. See wt step copy-ignored --help → Background-hook priority. (#2358, thanks @bram-rongen for reporting #2342)
- wt step commit no longer panics on large CRLF diffs containing multi-byte UTF-8: parse_diff_sections used str::lines() (strips \n and \r\n) but advanced the byte-offset accumulator by line.len() + 1, under-counting one byte per CRLF line. Once the diff exceeded the 400k filtering threshold the drift landed inside a multi-byte character and panicked with byte index N is not a char boundary. Now iterates with split_inclusive('\n') so offsets match real byte positions regardless of line-ending style. (#2356, closes #2355, thanks @Qnurye for reporting with a minimal reproduction)
- wt step relocate surfaces failed git checkout/git worktree move instead of printing false success: The four raw Cmd::new("git")...run()? call sites in relocate.rs swallowed non-zero exit codes — only spawn errors propagated through ? — so a failed checkout or move returned Ok and the caller printed Relocated 1 worktree. All four sites now route through repo.worktree_at(path).run_command(...), the project's fail-fast git pattern. Triggered most often when worktrunk.default-branch cached a branch that no longer resolves locally. (#2348)
Improved
- Alias dispatch ~15-20% faster via batched rev-parse: Parent-side alias dispatch was firing four separate git rev-parse subprocesses on the worktree path (--is-inside-work-tree, --show-toplevel, --git-dir, --symbolic-full-name HEAD). A new WorkingTree::prewarm_info folds all four selectors into a single invocation and populates the worktree_roots, git_dirs, and current_branches caches so later accessors hit cache. benches/alias: warm/1 53.3 → 43.5 ms (−19.6%), cold/100 62.1 → 49.7 ms (−18.2%). On systems with slow execve (macOS Gatekeeper, AV), three saved forks translate to ~600 ms per wt <alias>. (#2352, thanks @markjaquith for continuing to report #2322)
- Non-submodule repos no longer pay for a failing submodule probe: Repository::repo_path() used to run git rev-parse --show-toplevel inside .git to resolve the submodule case — that probe fails unconditionally on normal repos, costing ~5 ms per call. Now reads core.worktree directly from the bulk config map (the same signal git itself uses): bare repos short-circuit on core.bare, submodules read core.worktree, normal repos fall through to parent(git_common_dir). hyperfine on a healthy macOS system: wt noop in a normal repo 53.2 → 48.8 ms (1.09×); in a submodule 62.1 → 55.5 ms (1.12×). repo_path() fires ~2× during alias dispatch, so the win compounds. (#2350, thanks @markjaquith for reporting #2322)
Documentation
- pre-start and post-start hook rows say when the hook fires, not just what to put in it: The hook types table rows for pre-start and post-start now match the phrasing of neighbouring rows (pre-switch has "Runs before…", post-merge has "Runs in the target…"): "Runs once when a new worktree is created, blocking post-start/--execute until complete" and "Runs once when a new worktree is created, in the background". (#2360, thanks @ortonomy for reporting #1571)
- Hook docs: Recipes restructured as a table of contents: The "Designing Effective Hooks" umbrella heading was removed; "Recipes" is promoted to a top-level section with each bullet leading with a specifically-named link to its Tips & Patterns section. "Copying untracked files" moved up next to the JSON context section. (#2349, #2351)
- Refreshed stale docstrin |
| v0.42.0 | 21 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Alias banner is silent when there's nothing to summarize: ◎ Running alias <name> now only prints when the alias has at least one named step worth naming. Single unnamed aliases (ls = "wt list") and all-anonymous pipelines return no announcement — the banner was just echoing the user's typed name. Pipelines with named steps keep their informative summary (◎ Running alias deploy: install; build, lint). -v still prints the bare form as a confirmation line. (#2339, thanks @markjaquith for reporting #2322)
- Alias dispatch ~30% faster via batched git config reads: RepoCache now reads every config key with a single git config --list -z instead of one git config subprocess per key. Config-backed accessors (is_bare, primary_remote, remote_url, default_branch fast path, switch_previous, has_shown_hint, core.fsmonitor, core.pager, and more) resolve via an O(1) map lookup. Writes route through set_config_value / unset_config helpers that update the on-disk config and the in-memory map together. Benchmarked on benches/alias: warm/1 77.4 → 56.9 ms (−29%), cold/100 80.5 → 54.5 ms (−30%) — ~25 ms saved per wt <alias> invocation. (#2344, #2346, thanks @markjaquith for reporting #2322)
- Further O(1) single-branch upstream lookups on wt merge / wt switch: Follow-up to #2337. effective_integration_target and the wt switch tracking-info report switched from bulk Branch::upstream() (a for-each-ref over every local branch) to upstream_single() — wt list still uses the bulk cache, but one-shot callers no longer pay for it. (#2338)
- Stale cached default branch surfaces a clear error with a reset hint: default_branch()'s fast path no longer re-validates the cached worktrunk.default-branch on every call; when the cached value is stale, require_target_branch / require_target_ref raise a new StaleDefaultBranch error that names the cache key and suggests clearing it. wt list --branches opportunistically warns when the cached default isn't among the enumerated branches — no extra git fork. (The old silent fallback + two preflight warning sites are removed.) (#2344)
Documentation
- worktrunk skill: non-interactive hook approval guidance: skills/worktrunk/SKILL.md now covers the hook-approval prompt error that agents hit running wt merge (or any command that runs project hooks) in a non-interactive session. Explains wt config approvals add (interactive, persists to ~/.config/worktrunk/approvals.toml) vs --yes (single-invocation bypass for CI/CD), and directs agents to escalate rather than auto---yes, since pre-approval is a trust decision. (#2343)
Internal
- Flaky test_switch_picker_preview_panel_main_diff on macOS: Under heavy parallel load, skim's N/M match counter updated ahead of the list-panel repaint, so wait_for_stable could declare a screen stable with stale rows still visible (~1-in-120 failure rate). The stability check now rejects states where skim's parsed match count doesn't equal the visible list-row count. Closes #2334. (#2345)
- benches/alias regression guard for parent-side dispatch overhead: Five-variant harness (wt --version startup floor; noop alias at 1/100 worktrees × warm/cold caches) protects the #2337/#2338 O(1) upstream work and the #2344 bulk config read. (#2340)
- Remove/TTFO benches invalidate wt caches between iterations: benches/remove.rs::first_output and benches/time_to_first_output.rs::remove were reporting warm-cache cost because iter 1 populated .git/wt/cache/ and iter 2+ hit it. Now use iter_batched + invalidate_caches_auto (which also clears worktrunk.default-branch). benches/CLAUDE.md documents the rule and the full list of what invalidate_caches_auto clears vs. preserves. (#2341)
Install worktrunk 0.42.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.42.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm h |
| v0.41.0 | 20 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Hooks accept the same --KEY=VALUE smart routing as aliases: wt hook pre-merge --branch=foo --yes binds {{ branch }} when the template references it; unreferenced --KEY=VALUE tokens and everything after -- forward as {{ args }}, now available in hook templates. wt hook --help lists every hook type. --var KEY=VALUE still works but emits a deprecation warning pointing at the new form. (#2313)
- -v prints resolved template variables for every hook and alias: Before each ◎ Running … line, wt shows a template variables: block listing every variable in scope for that hook type or alias and the value it resolved to for this invocation. Vars in scope but unpopulated render as (unset) — which is how e.g. target_worktree_path surfaces during wt switch - on hooks that don't receive it. Alias args renders shell-escaped so the table matches what {{ args }} substitutes below. Works in foreground, background hook pipelines, and alias expansion. (#2316, #2324, #2328, thanks @nicolasff for reporting #2309)
- O(1) upstream lookup in alias/hook template context: Branch::upstream() triggered a for-each-ref scanning every local branch — amortized across bulk consumers like wt list, but wasted work for alias/hook template dispatch, which only needs the current branch. A new upstream_single() runs a scoped for-each-ref refs/heads/<branch>, so the parent-side alias dispatch is fully O(1) in branch count. Noticeable on machines with slow fork cost (macOS Gatekeeper, AV, slow FS). (#2337, thanks @markjaquith for reporting #2322)
Fixed
- Symbolic switch targets (-, @, ^) resolve before pre-switch hooks fire: wt switch - previously built the pre-switch hook context from the raw - argument, so {{ target }} and {{ target_worktree_path }} were wrong or unset. Symbolic targets are now resolved to the concrete branch name before the hook context is built, so hooks see the destination worktree correctly. (#2310, thanks @nicolasff for reporting #2309)
- Typo errors across wt, wt step, and wt config alias show/dry-run share one format: Four typo surfaces previously split across clap-native error: / tip: output (exit 2) and custom anyhow gutters (exit 1). All four now render the same clap-native layout — config alias show/dry-run say "alias" / "aliases" instead of "subcommand" / "subcommands" since the positional is an alias name. The wt <typo> and wt step <typo> paths also now run finish_command cleanup, so diagnostic dumps and ANSI resets still fire. (#2306, #2307, #2308)
Documentation
- Extending and hook guides consolidated: Recipes on extending.md and hook.md were trimmed, overlapping sections (pre-start vs post-start, copy-ignored variants, pipeline forms) folded together, template-engine scope clarified, and dev-server / database / target-specific hook recipes moved to Tips & Patterns. (#2314, #2315, #2317, #2318, #2319, #2321, #2323, #2326, #2329, #2333)
- Render fixes: Tables inside <details> blocks pick up the site's table styling (#2325); alternate pages excluded from the sitemap with trailing slashes on nav links (#2320); the [Aliases] help link renamed to [Extending Worktrunk guide] so it reads as a doc pointer rather than a self-reference in terminal help (#2330).
Internal
- Zola link regex handles code spans in link text: The skill-sync regex rejected [`…code…`](@/…) links, silently shipping dead @/…md references into skill reference files. The regex now balances code spans, and a post-transform guardrail panics on any leftover @/…md so future misses fail loudly. (#2327)
Install worktrunk 0.41.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.41.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.41.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt bin |
| v0.40.0 | 19 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Aliases route --KEY=VALUE to template variables and forward everything else as {{ args }}: --KEY=VALUE (or --KEY VALUE) binds KEY whenever the template references {{ KEY }} — wt deploy --env=staging sets {{ env }} to staging. Everything else joins {{ args }}, a space-joined, shell-escaped sequence ready to splice into a command. With s = "wt switch {{ args }}", wt s some-branch expands to wt switch some-branch. Index with {{ args[0] }}, loop with {% for a in args %}…, count with {{ args | length }}; each element is escaped individually, so wt run 'a b' 'c;d' renders as 'a b' 'c;d' — no shell injection. Tokens after -- forward unconditionally, bypassing any binding. Hyphens in keys become underscores: --my-var=x binds {{ my_var }}. Built-in vars can be overridden inside the template — --branch=foo sets {{ branch }} for the invocation, but the worktree's actual branch doesn't move. (Breaking: --var KEY=VALUE and --var=KEY=VALUE removed; wt <alias> no longer errors on unrecognized flags — they forward to {{ args }}.) (#2280, #2287, #2304)
- -y, --yes is a top-level global flag: Lives once on Cli instead of being duplicated across switch, remove, merge, commit, squash, prune, the ten hook subcommands, shell install/uninstall, plugin install/uninstall, and config update. wt -y <anything>, wt <anything> --yes, and wt --yes <anything> all skip approval and confirmation prompts for that invocation. (Breaking: post-alias --yes removed — use the global form wt -y <alias>.) (#2279, #2290)
- wt config alias show and wt config alias dry-run: show prints the configured template tagged by source (user/project). dry-run previews what an invocation would run without executing — wt config alias dry-run s -- target-branch renders exactly what wt s target-branch would produce. Output annotates routing with # bound: and # args: comments so you can see how each token was interpreted. Both warn when the alias name shadows a top-level built-in (e.g. list, switch); the alias is only reachable via wt step <name>. wt <alias> --help / -h prints a hint pointing at these subcommands rather than silently forwarding the flag into {{ args }}; use wt <alias> -- --help to forward. (Breaking: wt <alias> --dry-run and wt step <alias> --dry-run retired — use the new subcommand.) (#2291, #2304)
- wt config approvals replaces wt hook approvals: Approvals cover both project hooks and project aliases, so the old namespace under hook mis-scoped the command. add now walks both hook and alias commands — a project that only declares aliases can bulk-pre-approve in one shot. wt hook approvals remains as a hidden alias that emits a deprecation warning and forwards. (#2282)
- Scope-aware template variable validation: A new ValidationScope (Hook(HookType), SwitchExecute, Alias) drives validation across every template surface. {{ args }} only validates inside aliases; {{ target }} only in switch/start/merge contexts; {{ pr_number }} only in PR-aware switch hooks. A typo like {{ target }} in a pre-start hook is caught at validation time instead of failing at runtime with an undefined-var error after the worktree was created. (#2288)
- pr_number and pr_url template variables for PR/MR worktree hooks: Available in pre-switch, post-switch, pre-start, and post-start when the worktree was created via wt switch pr:N / mr:N. One canonical pair for both GitHub and GitLab — no separate mr_* aliases. Previously the runtime injected these in pre-start only and the validator rejected them, so the feature was unreachable. (#2300)
- target template variable injected symmetrically on switch/create/start: pre-switch already injected target (and conditionally target_worktree_path); post-switch, pre-start, and post-start now do too. A user writing {{ target }} in post-start no longer hits an undefined-var error at runtime. (#2295)
- Single announce line for combined background hooks: When user and project hooks both fire on post-merge, post-commit, post-start/post-switch |
| v0.39.0 | 17 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Aliases dispatch from top-level wt <name> (and graduate from experimental): Configured aliases now resolve as first-class commands — wt deploy works the same as wt step deploy, reading better as an everyday shortcut. Precedence is built-in → alias → wt-<name> PATH binary → unrecognized-subcommand error, matching git's model where [alias] entries shadow git-foo externals. The old "alias shadows a built-in" warning is gone; an alias named commit now simply runs via wt commit (only wt step commit remains shadowed). (#2266)
- wt switch --base accepts pr:N / mr:N: --base now routes through the same resolver as the positional branch argument, so wt switch -c feat-x --base pr:42 works symmetrically with wt switch pr:42. Same-repo PRs/MRs resolve to the source branch name; fork PRs/MRs fetch refs/pull/N/head (GitHub) or refs/merge-requests/N/head (GitLab) and use the resolved SHA, avoiding fork-branch pollution in the local namespace. (#2263, thanks @jrdncstr for the request in #2261)
- WORKTRUNK_PROJECT_CONFIG_PATH env override: Mirrors the existing WORKTRUNK_CONFIG_PATH (user) and WORKTRUNK_SYSTEM_CONFIG_PATH (system) overrides for the project config. Missing files at the overridden path resolve to no project config, same as a missing .config/wt.toml. wt config show --format=json now reports the overridden path in the project.path field. (#2267)
Fixed
- wt list handles [gone] upstreams gracefully: When a branch's configured upstream ref is gone (remote branch deleted, local tracking ref pruned), the Remote column was surfacing a raw fatal: ambiguous argument 'origin/<branch>' error from git rev-parse. Upstream resolution now reads %(upstream:track) and treats [gone] the same as no upstream, so the row renders cleanly. (#2262)
- Nix flake build with vendored skim-tuikit: The [patch.crates-io] path dependency on vendor/skim-tuikit was being stubbed out by crane's mkDummySrc during buildDepsOnly, breaking downstream skim resolution. The flake now preserves real sources for vendored path deps while still benefiting from dependency caching. (#2265, thanks @nickdichev)
Documentation
- Renamed "external subcommand" to "custom subcommand": The user-facing name for wt-<name> PATH-dispatched subcommands is now "custom subcommand" in docs and internal code, matching cargo's vocabulary. Avoids overloading "external," which the codebase already uses for shell_exec subprocesses. Internal renames: src/commands/external.rs → custom.rs, Commands::External → Commands::Custom. (#2270)
- Trimmed filler in prose docs: Removed sentences that restated obvious error behavior, duplicated nearby prose, or added visual weight without information across extending.md, faq.md, and tips-patterns.md. (#2271, #2272)
Internal
- Extracted a shared did_you_mean helper used by both top-level and wt step suggestion sites, so the 0.7 Jaro-Winkler threshold and sort order are defined in one place. (#2268)
Install worktrunk 0.39.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.39.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.39.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.39.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- |
| v0.38.0 | 16 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Concurrent execution in pre-* pipeline hooks: Pipeline blocks ([[pre-start]], [[pre-merge]], etc.) now run their concurrent commands in parallel for foreground hooks, matching the existing behavior in post-* hooks and aliases. The deprecated single-table form ([pre-start]) remains serial. (#2249)
- cli feature unbundles CLI-only deps for library consumers: The worktrunk crate is also consumed as a library (e.g. by worktrunk-sync). Everything reachable from src/lib.rs previously pulled in clap, clap_complete, skim, crossterm, termimad, env_logger, and humantime transitively. A new cli feature (on by default) gates these; library consumers with default-features = false drop from 195 to 126 transitive crates. (#2238)
- Faster wt list and wt switch on warm caches:
- In-memory caches for remote URLs, commit details, and diff stats in RepoCache eliminate ~11 duplicate git subprocesses per wt switch. (#2252)
- list_local_branches() primes ref/SHA caches from for-each-ref data already collected; Branch::upstream() uses a single batch for-each-ref call instead of N per-branch rev-parse commands. Reduces rev-parse calls from 53 to 27 on a typical-8 benchmark. (#2255)
- Share git status --porcelain output between WorkingTreeDiffTask and WorkingTreeConflictsTask, halving duplicate subprocesses. (#2259)
- Faster wt statusline: terminal_width() no longer walks parent processes to find a TTY — the fallback is now behind a dedicated helper used only by wt statusline under Claude Code. Picker, wt list, and help callers skip the walker entirely. (#2260)
- switch.picker.timeout-ms deprecated: After progressive rendering landed in 0.37.1, this config field was parsed but silently ignored. It's now flagged as deprecated with migration via wt config update. (Breaking for library consumers: SwitchPickerConfig::timeout_ms field and timeout() accessor removed.) (#2236)
Fixed
- Picker panic on terminal resize: Term::on_resize panicked with attempt to subtract with overflow when the terminal was smaller than the picker's preferred height (reachable under script(1) with stdin closed, or in small tmux panes). Vendored skim-tuikit now uses saturating_sub. (#2233)
- Picker previews no longer show stale "no commits ahead" text: BranchDiff/UpstreamDiff tabs read async fields that sometimes hadn't landed at skeleton-time precompute, caching wrong "has no commits ahead" / "has no upstream tracking branch" text. Previews now derive only from skeleton-time fields plus direct git queries. (#2245)
- Picker preview height with --branches/--remotes: The Down-layout item count estimate only counted worktrees, so with --branches or --remotes the estimate underflowed and the preview claimed space the list needed. (#2247)
- GitLab CI status in wt list: glab ci list now runs with the correct working directory. (#2244)
- Picker Summary tab empty state: aligns with the other preview tabs (bullet + branch header) instead of a dimmed sentence. (#2246)
Documentation
- Use concurrent form in multi-key hook examples, now that pre-* concurrent is supported. (#2248)
- Catalog skim 4.x upgrade impact and stability assessment. (#2239)
- Picker and collect module docstrings gain phase timing tables and trace instrumentation at key picker phases. (#2250)
Internal
- Simplified wt-perf output; cache-check JSON adds wasted-time fields, sorts duplicates by wasted time, and renames total_extra_calls to extra_calls. (#2253, #2254)
Install worktrunk 0.38.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.38.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.38.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download workt |
| v0.37.1 | 15 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Progressive rendering in wt switch picker: The picker now mirrors wt list's skeleton-first model — branch and path render immediately, while status, diff stats, counts, and summaries fill in in place as they resolve. Replaces the previous ~500ms blocking freeze before first render. (#2231)
- Clean rows no longer flash the timeout glyph in the picker: The LLM semaphore is now acquired only around the actual LLM call, so the no-changes and cache-hit fast paths return immediately instead of sitting behind up to 8 concurrent LLM calls. A clean main row in the picker now renders blank rather than the · "timed out" placeholder. (#2222)
Fixed
- Picker preview styling bleed: color_print's </> emits SGR 22 to reset <bold>/<dim>, which skim 0.20's ANSI parser silently drops. Preview spans now emit an explicit full reset (\x1b[0m), so dim and bold no longer bleed across the rest of the preview pane. (#2232)
- Picker alt-screen enter/exit asymmetry: In partial-height mode (height=90%), skim-tuikit skipped smcup on startup but still emitted rmcup on exit, corrupting the outer terminal's scrollback. The vendored tuikit now pairs enter/exit symmetrically. (#2230)
- Partial first render under tmux: Under tmux PTY pressure, rows past the first ~1024 bytes would silently vanish because Output::flush used write instead of write_all. Vendored skim-tuikit fixes the short-write bug. (#2226)
Library
- Expose worktree removal API from the worktrunk library: remove_worktree_with_cleanup, RemoveOptions, and BranchDeletionMode are now public, letting external tools reuse the canonical removal flow (fsmonitor cleanup, trash-path staging) instead of reimplementing it with raw git commands. Motivated by worktrunk-sync. (#2227, thanks @pablospe for the request in #2053)
Documentation
- Document worktrunk-sync: Linked from the Extending page and the FAQ as a community-maintained companion tool for rebasing stacked worktree branches. (#2225)
- Catalog vendored skim patches: vendor/skim-tuikit/PATCHES.md now records both landed and candidate patches against skim-tuikit, and a Cargo.toml comment records why skim is pinned to 0.20.x. (#2228, #2229)
Internal
- Drop unreachable rayon::spawn fallback in the picker orchestrator. (#2216)
Install worktrunk 0.37.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.37.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.37.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.37.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.37.0 | 14 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- pre-* hook table form temporarily deprecated ahead of concurrent-execution unification: Today, pre-* hooks run serially: pipeline form is serial by construction, and table form ([[pre-merge]]) — which already runs concurrently for post-* hooks and for aliases — is forced serial for pre-*. A future release will lift that restriction so pre-* table form runs concurrently too, matching post-* and aliases. To make the switch safe, pre-* table form is deprecated now. Run wt config update to migrate to pipeline form; existing configs keep working until then. (#2135, #2151)
- Concurrent commands in alias table form: Aliases defined with multi-entry table form ([[aliases.deploy]]) now run their commands concurrently; pipeline form (commands = [...]) remains serial. Output streams through a shared executor that prefixes every line with a colored {label} │ , identifying which child produced it. Writes are line-atomic even under heavy load. (#2089, #2145)
- --KEY=VALUE shorthand for alias and hook variables: wt step deploy --env=staging and wt hook pre-start --branch=feature/test now work without the --var prefix. --my-var=value becomes {{ my_var }} in templates. Hooks also accept custom variable names (previously a fixed list; now matches alias behavior) and warn when a --var isn't referenced by any template — catching typos like --branch=feature. (#2091, #2096, #2117)
- wt step discovers configured aliases: Running wt step (or wt step --help) now lists user and project aliases alongside the built-in subcommands, each with a one-line template summary. Aliases that shadow a built-in are flagged (shadowed by built-in). (#2131, #2141)
- Shell completions for external wt-* subcommands: Tab completion now discovers wt-* binaries on PATH and forwards completion requests to them, so wt sync --<tab> shows the external command's flags. Builds on the git-style external subcommand dispatch in 0.36.0. (#2074, thanks @pablospe)
- Persistent on-disk cache for expensive git operations: Five SHA-keyed probes that previously ran live on every wt list and wt switch — merge-tree conflict checks, the integration/add-probe, is-ancestor, has-added-changes, and branch diff stats — are now cached to disk under .git/wt/cache/. Because commit SHAs are content-addressed, cached results never go stale; an LRU bound (5000 entries per kind) keeps disk usage bounded. User-visible effects:
- wt list and the wt switch picker open much faster on big repos, especially those with many stale branches. A warm cache skips the expensive probes entirely; a cold cache still benefits from the faster per-worktree check below.
- Dirty-worktree conflict check is ~10× faster on cold cache. Swapped git stash create for git write-tree as the ephemeral tree snapshot — same answer, far less plumbing per worktree. (#2119)
- The picker now shows the same status info as wt list. The old "skip stale branches" shortcut hid conflict and ahead/behind info on branches 50+ commits behind main to keep the picker responsive. The cache makes the shortcut unnecessary, so stale branches now display full status.
- Consistent results during in-progress rebases. Tasks now track the branch ref rather than the worktree's transient HEAD, so rows no longer contradict themselves mid-rebase (e.g., is_ancestor=true alongside 1 ahead / 1 behind).
Cache is cleared by wt config state clear. (#2085, #2090, #2098, #2119)
- Lower-priority background operations: Extends the CPU/IO priority throttling already used by wt step copy-ignored to the background rm -rf in wt remove and the trash sweep, so cleanup doesn't compete with foreground work. On macOS this now uses taskpolicy -b, which throttles disk I/O as well as CPU; Linux uses nice -n 19 with best-effort ionice. User hooks are unchanged. (#2130, #2133)
- Pipeline structure in alias announcements: Aliases now announce their pipeline structure: Running alias deploy: install; build, lint rather than the bare alias name. (#2092)
- Graceful pe |
| v0.36.0 | 11 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Git-style external subcommands: wt foo now runs wt-foo from PATH when foo is not a built-in, mirroring git foo → git-foo. Third-party tools can be installed and invoked as wt <name> without touching this repo. Unrecognized commands show a git-style error with typo suggestions. Docs (#2054, thanks @pablospe for the suggestion in #2053)
- {{ owner }} template variable: Expands to the GitHub/GitLab repository owner, useful for constructing URLs or paths in hook templates and worktree-path. (#2051, thanks @greggdonovan)
- Typed env-var config overrides: WORKTRUNK__LIST__TIMEOUT_MS=30 and other typed overrides now work correctly. Previously, string-typed env values silently failed deserialization, wiping all user config and falling back to defaults. (#2062)
- Config error attribution: Config load errors now identify the source — file errors show TOML line/column pointers, env-var errors list the offending WORKTRUNK_* variable. Previously all failures showed a generic message. (#2068)
- Per-symbol atomic status rendering: The Status column in wt list and the wt switch picker now renders each symbol independently — unresolved gates show ⋯ at their position instead of fabricating defaults when the collect deadline expires. (#2067)
- Hook error messages: Malformed hook command config now lists the three accepted forms (string, named table, pipeline list) with a pointer to wt hook --help, instead of an opaque serde error. (#2042)
- Stale trash cleanup: wt remove now sweeps orphaned .git/wt/trash entries older than 24 hours after each removal, reclaiming space from interrupted background removals. (#2039)
Changed
- wt hook <type> exits successfully when no hooks are configured: Previously errored; now prints a warning and exits 0, so scripts and CI can invoke wt hook unconditionally. (#2056)
- Hook output log layout: Log files moved from flat .git/wt/logs/{name}.log to nested {branch}/{source}/{hook-type}/{name}.log. Per-branch listing/clearing is now O(that branch). logs get --format=json paths changed to relative. Legacy flat files are swept automatically. (#2041)
Fixed
- wt config show false "Not configured": When the shell init line lives in a sourced file (common with dotfile managers), config show no longer reports "Not configured" — it checks whether integration is actually active at runtime. Fixes #1306. (#2066, thanks @wouter-intveld for reporting)
- Remove-then-switch hint: The hint for shadowed remote branches now uses --foreground so the chained wt remove && wt switch actually works (background removal left a placeholder directory blocking the switch). (#2040)
- Conflict detection unified: The wt switch picker and wt list now both run both conflict probes (commit-level and working-tree). Previously the picker skipped the cheaper probe, leaving the fallback unreachable for clean worktrees; wt list non-full skipped the working-tree probe, missing conflicts from interrupted rebases. (#2064)
Documentation
- Surfaced vars & aliases on homepage and tips-patterns, cross-linked state keys to dedicated docs, tightened hook links. (#2035, #2036, #2037, #2038)
Internal
- Subcommand ordering aligned to documented policies (pipeline order for step, CRUD for state actions). (#2043, #2044)
Install worktrunk 0.36.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.36.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.36.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.36.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
────────────────────────────────────────────────┼───────────────────┼────── |
| v0.35.3 | 9 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step prune streams removals inline: Removals and "Skipped" messages now print as each integration check completes, overlapping with still-running checks — previously there was a visible gap of silence while all parallel checks finished before any output appeared. (#2015)
- Fewer redundant git worktree list calls in prune and multi-remove: prepare_worktree_removal() now accepts a pre-fetched worktree list, eliminating N+1 subprocess calls when removing many worktrees. (#2025)
Fixed
- Picker preview UI lag: The picker's preview cache now stores pager-rendered output, so cache hits skip the pager subprocess entirely. Previously, scrolling past an item with a large diff froze the UI briefly on every re-render because the pager ran on every call. (#2021)
- Template error hint underlining: The "Available variables" hint in template expansion errors now underlines each variable name individually instead of wrapping the entire comma-separated list in a single underline span. (#2028)
Documentation
- Cross-linked vars references: The vars feature is documented in the hook template variables table, wt config state vars page, and tips-patterns recipes — these now link to each other so readers can navigate between "how to set" and "how to use in templates". (#2034)
- Clearer project config intro: Improved the project config introduction and template variable heading in wt config help text. (#2032)
Install worktrunk 0.35.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.35.3/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.35.3/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.35.3
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.35.2 | 8 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Multiple NAME filters for hook subcommands: wt hook pre-merge --yes insta doctest doc runs a subset of hooks in one command, instead of chaining separate invocations. (#2013)
- Branch context in batch removal hooks: During prune or multi-remove, hook announcement messages now include the branch name (Running post-remove for **branch-name**: project:cleanup), disambiguating which worktree triggered each hook. (#2014)
Fixed
- Bare repo false positive when core.bare is unset: Repos cloned by Eclipse/EGit (and other tools that don't write core.bare) were incorrectly detected as bare. Replaced git rev-parse --is-bare-repository with git config --type=bool core.bare. Fixes #1939. (#1976, thanks @daniel-iwan-datacore for reporting)
Install worktrunk 0.35.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.35.2/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.35.2/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.35.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.35.1 | 8 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- PR lookup on forks respects gh repo set-default: wt switch pr:N now checks the gh-configured default repo when origin points to a fork, instead of always querying the fork's repo (which returns 404). The error message is also context-aware based on the configured default. Fixes #2002. (#2004, thanks @JustinPierce for reporting)
- JSON output stability: config show --format=json log file sort is now deterministic (filename tiebreaker for identical timestamps). step for-each --format=json includes a consistent error field on all failure variants. (#2001)
Internal
- Continued TestRepo consolidation: bare() constructor, at(path) constructor, removed lifetime guard field. (#2000, #2005, #2007)
Install worktrunk 0.35.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.35.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.35.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.35.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.35.0 | 8 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- --no-verify deprecated in favor of --no-hooks: All commands (switch, remove, merge, step commit, step squash) now use --no-hooks. --no-verify remains as a hidden alias with a deprecation warning. (#1932)
- JSON output: --format=json on config show, config state subcommands, switch, remove, merge, step prune, and step for-each. (#1969, #1959)
- Per-command hook log files: Each background hook command writes to its own log file instead of sharing a pipeline log. Combined hook announcements (e.g., post-remove + post-switch) display on a single status line. (#1934, #1980)
- Prune and list performance: step prune streams integration checks and removes candidates in parallel (~3x faster on repos with many branches). Multiple caching layers (integration target, git_dir, rev_parse_tree, resolve_preferring_branch) reduce redundant git rev-parse calls during wt list. (#1950, #1957, #1966, #1948, #1943)
- Itemized state clear output: wt config state clear shows per-category counts and cleans up stale trash from incomplete worktree removals. (#1961, #1960)
- Hook pipeline summary: Serial steps separated by ; instead of →, repeated unnamed sources collapsed into counted form (user ×2), and named steps show source:name prefix. (#1994)
- Copy-pasteable help text: --help output strips $ prompts from code examples for direct copy-paste in the terminal. (#1992)
- Better PR lookup errors: wt switch pr:N 404 errors now include the repository name and suggest gh repo set-default for fork workflows. Fixes #1925. (#1927, thanks @JustinPierce for reporting)
- Claude Code worktree hooks: WorktreeCreate and WorktreeRemove hooks for the Claude Code plugin. (#1959)
Fixed
- File permissions lost on copy-ignored: wt step copy-ignored now preserves execute bits when copying files via reflink. Fixes #1936. (#1937, thanks @RileyMathews for reporting)
- Git alias breaks wt: Relative GIT_DIR/GIT_WORK_TREE paths inherited from git aliases now normalized to absolute paths at startup. Fixes #1914. (#1915, thanks @yasuhiroki for reporting)
- Diagnostic files in state logs: verbose.log and diagnostic.md now properly categorized in wt config state logs output. (#1981)
- Integration target in removal display: Background removal now shows origin/main (effective target) instead of main when the remote is ahead. (#1993)
- Worktree-path hint suppression: The "customize worktree locations" hint no longer appears when project-specific worktree-path is configured. (#1941)
- State logs formatting: Missing newline between log sections in wt config state logs output. (#1968)
- Claude Code WorktreeCreate hook: Fixed jq filter using wrong input field. (#1964)
- OpenCode unicode escaping: Fixed broken emoji markers depending on Bun version. (#1935, thanks @noirbizarre)
Documentation
- Clarified plugin install command. (#1906, thanks @suyua9)
- Fixed inaccurate logs documentation. (#1986)
Internal
- Consolidated TestRepo into single src/testing module, shared across lib and bin unit tests. (#1944, #1963, #1971, #1991)
- Simplified dispatch, timeout, and copy pool internals. (#1949, #1930, #1931)
Install worktrunk 0.35.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.35.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.35.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.35.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-aarch64-apple-darwin.tar.xz │Apple Silicon macOS│checksum
────────────────────────────────────────────────┼───────────── |
| v0.34.2 | 6 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- OpenCode integration: Activity tracking plugin shows agent status (🤖 working, 💬 waiting) in wt list, with wt config plugins opencode install/uninstall for management. Also adds OpenCode as an LLM commit generation backend. (#1807, thanks @noirbizarre)
- Lower priority for copy-ignored: wt step copy-ignored now runs at the lowest OS scheduling priority (renice -n 19), yielding CPU to interactive foreground tasks on large trees. (#1916)
- Diff stats performance: Switched from --numstat (one line per file) to --shortstat (single summary line), reducing diff output from O(files) to O(1) per worktree. (#1917)
Fixed
- Remote detection with includeIf config: primary_remote() failed when non-remote git config keys (like includeIf.hasconfig:remote.*.url) matched the remote regex. (#1908, thanks @nirvdrum)
- Background hook execution: Fixed three issues — list-form configs lost serial/concurrent semantics in post-merge/post-remove hooks, pipeline hook_name context leaked across steps, and lazy template expansion was broken for name-filtered hooks (e.g., wt hook post-start db). (#1910)
- Copy-ignored parallelism: The outer loop in wt step copy-ignored ran on the global rayon pool instead of the dedicated copy pool, effectively serializing top-level entries. Now runs entirely on the 4-thread copy pool. (#1913)
- Windows stack overflow in copy-ignored: Copy pool worker threads used platform default stack size (~2 MiB on Windows), causing overflow with 200+ directories. Now uses explicit 8 MiB stack size across all platforms. (#1911)
- Nix flake build: Fixed flake.nix filtering out the dev/ directory, which broke builds after OpenCode integration added include_str!("../../../dev/opencode-plugin.ts"). (#1924, thanks @mariuskimmina)
Internal
- Unified background hook execution into a single pipeline-based path, removing ~260 lines of dual-path branching. (#1912)
- Replaced deprecated codecov/test-results-action with codecov/codecov-action. (#1918)
- Bumped AUR deploy action to v4.1.2 (fixes argument order with Arch Linux's updated runuser). (#1909)
Install worktrunk 0.34.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.34.2/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.34.2/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.34.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.34.1 | 4 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- step prune performance: Integration checks now run in parallel, dramatically reducing prune time for repos with many branches (3+ minutes → seconds with 100+ branches). Fixes #1888. (#1890, thanks @ortonomy for reporting)
Fixed
- CPU saturation during copy operations: Restored a dedicated 4-thread copy pool that was accidentally removed in v0.34.0, preventing ~1000% CPU usage on copy-heavy operations like step copy-ignored. (#1905)
- Background pipeline template variables: When wt switch --create fires both post-switch and post-start hooks, pipeline steps were incorrectly accumulated into a single background process, causing {{ hook_type }} to expand to the wrong value. Each hook type now spawns its own pipeline. (#1904)
Internal
- Extracted shared classify_unknown_key to deduplicate config warning logic. (#1902)
Install worktrunk 0.34.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.34.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.34.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.34.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.34.0 | 3 เมษายน 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Per-branch custom variables: New wt config state vars set/get/list/clear commands store custom key-value pairs per branch, accessible as {{ vars.key }} in hook templates and wt step eval. Variables persist in git config and appear in wt list --format=json. (#1006)
- Lazy template expansion in pipelines: Pipeline steps now expand {{ vars.* }} at execution time rather than at pipeline construction, so variables set by step N are available in step N+1. (#1840)
- wt config plugins claude commands: New install, uninstall, and install-statusline subcommands manage Claude Code integration. install registers the worktrunk plugin via the Claude marketplace, install-statusline configures the Claude Code status line, and wt config show suggests these commands instead of raw CLI instructions. (#1830, #1834)
- [forge] config section: New explicit [forge] section with platform and hostname fields for SSH host aliases and non-standard remotes. ci.platform is deprecated with automatic migration. (#1826)
- Forge detection with url.insteadOf: Forge platform detection now falls back to the effective URL (after git url.insteadOf rewrites), fixing CI status, PR/MR detection, and push-remote features for users with SSH aliases or corporate mirrors. (#1771, thanks @amodelaweb; thanks @roytouw for reporting #1790)
- --branch flag for wt step commit: Commit to a specific branch without switching to it — useful in automation and scripts. (#1750)
- Last fetch time in branch-not-found hint: When wt switch can't find a branch, the hint now shows when the remote was last fetched (e.g., "last fetched 3h ago") to help identify stale local refs. (#1877)
- Config field renames: merge.no-ff → merge.ff and switch.no-cd → switch.cd, using positive-sense naming. Old names continue to work with deprecation warnings and automatic migration via wt config update. (#1856, #1860)
- Syntax highlighting for template blocks: Documentation site now renders {{ }} template expressions with syntax highlighting. (#1792)
- Hide Claude Code section when CLI unavailable: wt config show no longer displays the Claude Code integration section if the claude CLI is not found. (#1827)
Fixed
- Copy-ignored too many open files: wt step copy-ignored could exhaust file descriptors on large trees. Now reuses a single thread pool across all copy operations. Fixes #1865. (#1864, thanks @fspeirs)
- Squash-merged branch detection with merge-tree conflicts: wt step prune and wt list failed to detect squash-merged branches when the default branch modified the same files. Now uses patch-id matching as fallback. Fixes #1818. (#1820, thanks @tthyer for reporting)
- Background removal blocked for 1 second: wt remove blocked unnecessarily due to incorrect shell operator precedence in the background process spawn. (#1858)
- Fish shell getcwd error in Zellij: Removing a worktree while using fish in Zellij produced "error retrieving current directory" messages. (#1787)
- Alias detection false positive on path substrings: wt config show incorrectly flagged unrelated aliases when the alias target path contained "wt" as a substring. Fixes #1772. (#1773, thanks @nicolasff for reporting)
- Branch names with dots in vars: Vars parsing incorrectly split branch names containing dots (e.g., release.1.0) as nested config keys. (#1837)
- Lazy pipeline vars expansion in background hooks: Background hook execution failed with lazy vars expansion due to raw string quoting and overly strict template validation. (#1855)
- GitLab MR remote tracking: wt switch mr:N could reuse branches tracking the correct merge-request ref but on the wrong remote. (#1817)
- Fork CI and integration target detection: Fixed CI check-runs querying the wrong repo for forks, branch tracking checking only merge config, and diverged local branches missing remote merges. (#1812)
- Placeholder directory on non-current worktree removal: wt remove created unnecessary empty placeholder directories and slept for 1 second when r |
| v0.33.0 | 26 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Hook execution pipelines: Post-* hooks support TOML array syntax for serial dependencies — steps execute in order, with maps within steps running concurrently. post-start = [{ install = "npm install" }, { build = "npm run build", lint = "npm run lint" }] runs install first, then build and lint in parallel. Docs (#1713)
- Copy-ignored exclude patterns: wt step copy-ignored now skips built-in VCS metadata and tool-state directories (.bzr/, .conductor/, .entire/, .hg/, .jj/, .pi/, .pijul/, .sl/, .svn/, .worktrees/) by default. Additional excludes are configurable via [step.copy-ignored] exclude = [...] in user or project config. (#1667, thanks @shunkakinoki for #1653)
- Copy-ignored parallelized: wt step copy-ignored directory walks run in parallel with a dedicated 4-thread pool, improving performance on multi-core systems. (#1721)
- Alias append semantics: Aliases now use append semantics across all config layers, matching hook merge behavior. Within user config, per-project aliases append to global aliases on collision (global first). Across configs, project-config aliases also run alongside user aliases (user first, then project with approval) — previously the user version silently suppressed the project version. (#1724, #1727)
- Agent skill discovery: The website now serves .well-known/agent-skills/ for web-based skill discovery by AI agents. (#1751)
Fixed
- Picker alt-r skipped remove hooks: Removing a worktree via alt-r in the picker bypassed pre-remove and post-remove hooks. Pre-remove hooks now run synchronously (non-zero exit aborts removal), and post-remove hooks spawn in the background. (#1710)
- False positive shell integration warning: wt config show reported "Found wt in ... but not detected as integration" for Nushell and Fish wrapper files that ARE the integration. Fixes #1735. (#1736, thanks @saschabratton)
- Bare repo config path ignored: wt hook approvals add and other config commands failed to find .config/wt.toml in bare repositories because they looked relative to the current worktree instead of the primary worktree. Fixes #1744. (#1745, thanks @jrdncstr)
Documentation
- Help text for wt step subcommands cleaned up — redundant openers removed. (#1737)
- Experimental badge placement fixed in generated documentation. (#1742, #1729, #1734, #1746)
Internal
- Copy-ignored built-in exclude constants consolidated. (#1738)
- Cmd::env() accepts AsRef<OsStr> for direct path compatibility. (#1723)
- Picker width survey snapshots for layout testing at various terminal sizes. (#1613)
Install worktrunk 0.33.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.33.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.33.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.33.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
─────────────────────────────── |
| v0.32.0 | 25 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Hooks rationalized: Every lifecycle event now has a symmetric pre- (blocking) / post- (background) pair. This required one rename: post-create → pre-start, reflecting that it runs before post-start as a blocking dependency step. A new post-commit hook fires in the background after commits (including squash commits during merge). post-merge is now background instead of blocking, consistent with all other post-* hooks. Configs using post-create get a deprecation warning on any wt command; run wt config update to rename automatically. The old name continues to work during the deprecation period. Docs (#1679, closes #1670, thanks @ortonomy for reporting #1571)
- Hook template variables consolidated: Bare variables (branch, worktree_path, commit) now consistently point to the Active worktree — the destination for switch/create, the source for merge/remove. New directional variables ({{ base }}, {{ base_worktree_path }}, {{ target_worktree_path }}, {{ cwd }}) give hooks explicit access to both sides of two-worktree operations. (Breaking: {{ worktree_path }} changed in pre-switch for existing worktrees and in post-merge — use {{ cwd }} or {{ base_worktree_path }} for the previous behavior.) Docs (#1655, #1660, #1663, thanks @sysradium for reporting #1543)
- Detached worktree support: Detached HEAD worktrees can now be removed via wt remove /path/to/worktree and switched to via wt switch /path/to/worktree. The interactive picker also handles detached worktrees for both operations. (#1665, #1680, thanks @mjakl for reporting #1661)
- In-place worktree removal in picker: Press alt-r in the wt switch picker to remove the selected worktree without leaving the picker. Currently hidden from picker legend and help text pending a cursor-reset issue (#1695). (#1677, #1696)
- Smarter column dropping in wt list: Low-priority columns (Message, Time, Commit) are now dropped when Summary needs more space, using graduated thresholds based on priority distance. Extends the no-data column dropping from v0.31.0. (#1678)
Fixed
- Bare repo project config ignored: .config/wt.toml placed in the primary worktree of a bare repository was not found when running commands from the bare repo root directory. Config is now loaded from the primary worktree as fallback, and accidental config in the bare repo root itself is skipped. Fixes #1691. (#1692, #1697, thanks @seakayone)
- pre-start hook failure was non-blocking: pre-start was the only pre-* hook that warned on failure instead of aborting. All pre-* hooks now consistently use FailFast. (Breaking: pre-start hook failures that previously only warned now abort the operation.) (#1708)
- Spurious mismatch warning for detached worktree switches: Switching to a detached worktree by path produced a "Branch-worktree mismatch" warning because the directory name was treated as a branch name. (#1686)
- Detached worktree switch output showed redundant path: Output now shows "detached worktree" instead of repeating the directory name (which duplicated the path after @). (#1685)
- Picker alt-r removal fixes: Picker removals now validate the worktree synchronously before removing it from the list, perform the actual git removal on a background thread to prevent UI freezing, and correctly handle detached worktrees. (#1699, #1702, #1717)
Documentation
- Migration guide for hook rationalization and template variable changes. (#1666, #1693)
Internal
- All test git commands now go through Cmd for consistent debug logging and timing traces. (#1714, #1716, #1718)
- Worktree removal logic extracted into shared helpers. (#1683, #1700, #1701)
Install worktrunk 0.32.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.32.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v |
| v0.31.0 | 23 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Hook template variables consolidated: Bare variables (branch, worktree_path, commit) now consistently point to the Active worktree — the destination for switch/create, the source for merge/remove. New directional variables ({{ base }}, {{ base_worktree_path }}, {{ target_worktree_path }}, {{ cwd }}) give hooks explicit access to both sides of two-worktree operations. (Breaking: {{ worktree_path }} changed in pre-switch for existing worktrees and in post-merge — use {{ cwd }} or {{ base_worktree_path }} for the previous behavior.) Docs (#1655, #1660, #1663)
- Bare repo worktree-path prompt: When a bare repo lives at a hidden path like .git or .bare, wt switch now detects that worktrees would get awkward names (e.g., project/.git.feature) and offers to configure a worktree-path override. Non-interactive environments show the config to add manually. (#1656, thanks @seakayone for reporting #1279)
- Shell completion for step aliases: Tab-completing wt step <TAB> now shows configured aliases alongside built-in step commands, with --dry-run, --yes, and --var flags. (#1641)
- wt list reclaims space from redundant columns: When the Path column carries no useful information (all worktree paths are predictable from branch names), its space is reclaimed for Summary and Message. (#1634)
- Syntax highlighting for alias dry-run: wt step <alias> --dry-run now uses bash syntax highlighting, matching hook dry-run output. (#1635)
Fixed
- wt list hang from fsmonitor daemon: On macOS with builtin fsmonitor, wt list could hang at the "(loading...)" stage because git fsmonitor--daemon start inherited pipe file descriptors and held them open indefinitely. (#1648)
- Post-remove hooks ran at wrong directory: Post-remove hooks executed at the user's cwd (which could be the worktree being removed) instead of the primary worktree. (#1645)
- Picker showed loading indicator for unavailable data: The interactive picker used ⋯ (loading) for fields that would never arrive; now uses · (unavailable). (#1651)
- wt hook --dry-run missing directional variables: Hook dry-run and --show --expanded output was missing base, target, and target_worktree_path variables for switch, create, and remove hooks. (#1669)
Documentation
- Bare repository layout guide and worktree-path example in config docs. (#1664)
- Migration guide for template variable changes in hook docs. (#1666)
Internal
- Renamed internal select module to picker. (#1650)
- Consolidated merge/remove removal validation. (#1625)
Install worktrunk 0.31.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.31.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.31.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.31.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
────────────────────────────────────────────────┴───────────────────┴─────── |
| v0.30.1 | 20 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- Narrow terminal layout: wt switch picker now uses vertical (Down) layout on terminals narrower than 80 columns, and the Branch column shrinks instead of being dropped — branch names are always visible. (#1564, #1626, thanks @armstrjare for reporting #1563)
- Bash tab completion showed all branches: wt switch feat<TAB> displayed every branch instead of filtering by prefix, prompting "Display all N possibilities?" for users with many branches. Fish and zsh still use their native substring/fuzzy matching. (#1622, thanks @altruic for reporting #1621)
- Hook command completion pre-filtered in all shells: HookCommandCompleter filtered by prefix before returning candidates, preventing fish/zsh substring matching on hook command names. (#1627)
- wt merge failed with submodule.recurse=true: Users with submodule.recurse=true in their git config saw push errors during merge. Local push now passes --recurse-submodules=no. (#1619, thanks @viicslen for reporting #1604)
- Worktree sync uses safe read-tree: Target worktree sync after --no-ff push uses read-tree -m -u instead of reset --hard, consistent with the project's norms. (#1623)
Internal
- Inlined complete_branches and complete_hook_commands into their respective completers. (#1628, #1627)
Install worktrunk 0.30.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.30.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.30.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.30.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.30.0 | 19 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt merge --no-ff: Create a merge commit instead of fast-forwarding, for semi-linear history (rebased commits plus a merge commit). Also available as merge.no-ff = true in user config. Docs (#1438, thanks @siriobalmelli)
- wt step eval [experimental]: Evaluate template expressions from the command line. All hook variables (branch, repo, worktree_path) and filters (hash_port, sanitize, sanitize_db) are available. Designed for scripting: curl http://localhost:$(wt step eval '{{ branch | hash_port }}')/health. Docs (#1004, thanks @EduardoSimon for the feature request in #947)
- wt step push --no-ff: Mirrors wt merge --no-ff for manual step-by-step workflows: wt step commit && wt step rebase && wt step push --no-ff. (#1587)
- Worktree removal now hidden: Removed worktrees are staged in .git/wt/trash/ instead of a visible .wt-removing-* sibling directory. All worktrunk state consolidated under .git/wt/. (#1583, thanks @ortonomy for reporting #1572)
Fixed
- wt merge could remove the default branch worktree in bare repos: In bare repository layouts, merging from the default branch worktree could remove it instead of preserving it. (#1620, thanks @viicslen for reporting #1618)
- wt switch panicked on empty picker selection: Entering a non-existent branch name in the interactive picker caused a panic. Now returns an error message gracefully. (#1566, thanks @dlnilsson for reporting #1565)
- copy-ignored lost directory permissions: Source directory permissions (e.g., mode 0700 for Postgres data directories) were replaced with default 0755. (#1590, thanks @RileyMathews for reporting #1589)
- copy-ignored failed on broken symlinks at destination: If a gitignored file's destination was already an invalid symlink, the copy failed with "No such file or directory". (#1549, thanks @armstrjare for reporting #1547)
- Nushell $env.PWD errors after wt remove: Removing a worktree from inside it produced repeated $env.PWD points to a non-existent directory errors in Nushell. (#1508, thanks @mystilleef for reporting #1507)
- Remote URL used insteadOf rewrites: wt list and PR detection used the rewritten remote URL instead of the raw config value, causing mismatches with CI and forge detection. (#1546, thanks @volkanbicer)
- SIGPIPE from pager quit treated as error: Quitting a pager (e.g., q in less) during wt step diff showed "terminated by signal 13" instead of exiting cleanly. (#1559)
- Missing vs corrupt git config errors conflated: Missing config keys and corrupt config files both returned the same error, making corrupt configurations hard to diagnose. (#1610)
- Shell operator precedence in remove command: The || true for fsmonitor stop had incorrect precedence, potentially swallowing failures from the entire removal chain. (#1584)
- Missing shell escaping in error hints: Branch names and paths in suggested cd ... && git switch ... commands were not shell-escaped. (#1584)
Documentation
- pnpm post-create example: Added a recipe for running pnpm install after worktree creation via copy-ignored. (#1581)
- Hook execution order: Clarified that post-create hooks run before post-start hooks. (#1573)
Install worktrunk 0.30.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.30.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.30.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.30.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-aarch64-apple-darwin.tar.xz │Apple Silicon macOS│checksum
────────────────────────────── |
| v0.29.4 | 15 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Destination branch in pre-switch hooks: {{ branch }} in pre-switch hooks now expands to the destination branch (as typed by the user) instead of the source worktree's branch. Previously, pre-switch hooks could only see where you were, not where you were going. Docs (#1497, thanks @mayureshwaykole for the discussion in #1494)
- LLM tool commands in example config: wt config create now includes double-commented entries for Claude, Codex, opencode, llm, and aichat commands, making them discoverable without reading the docs. Docs (#1531, #1533)
Fixed
- Extra blank line in config create output: The success path printed a blank line between the success message and hint lines, inconsistent with the "already exists" path. (#1525)
Documentation
- Switch docs: Trimmed upstream tracking paragraph, added missing pre-switch/post-switch hooks to creation lifecycle, combined GitHub/GitLab sections. (#1521)
- List docs: Restored --full prerequisite note for LLM summaries. (#1517)
- Experimental badges in headings: Moved experimental badges from description paragraphs to headings in web docs for cleaner TOC entries. (#1523)
Internal
- CI improvements: Prevented duplicate inline review comments across cycles, banned blocking gh pr checks --watch, fixed verify step for concurrency-cancelled runs, stopped hourly audit from flagging CI polling, added rolling file survey to nightly cleaner. (#1514, #1498, #1519, #1520, #1522)
- Simplified review-pr skill: Cut metacognitive coaching and collapsed confidence tiers; 504 → 369 lines (−27%). (#1530)
Install worktrunk 0.29.4
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.29.4/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.29.4/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.29.4
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.29.3 | 14 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Unified timeout model for list and picker: Consolidated the picker's per-command timeout and list's experimental timeout-ms into a shared config with [list] task-timeout-ms (per-task, shared by both) and per-context wall-clock budgets ([list] timeout-ms, [switch.picker] timeout-ms). Picker default budget raised from 200ms per-command to 500ms wall-clock. (#1515, #1487)
- Pre-flight template validation for wt switch: Switch templates (--execute and hook commands) are now validated before worktree creation, preventing orphan worktrees from syntax errors like {{ unclosed. (#1500)
Fixed
- wt remove allowed removing default branch worktree: The default branch worktree (e.g., main) could be removed because it was trivially "integrated" into itself. Now blocked unless -D is used. (#1460, thanks @cperalt for reporting #1448)
- Symlinks copied as regular files in copy-ignored: Top-level gitignored symlinks were copied as regular files instead of preserved as symlinks, breaking setups like Yarn monorepos. (#1489, thanks @karmeleon for reporting #1488)
- Missing placeholders in WorkingDiff and Upstream columns: These columns showed blank instead of ⋯/· placeholders when data wasn't loaded, breaking the visual loading signal. (#1503)
Documentation
- Step command docs: Added promote subdoc, improved swap description, linked Operations index to subcommand sections, moved aliases section after subcommands, fixed cross-filesystem fallback description. (#1505, #1495, #1502, #1513)
- List docs: Documented placeholder symbols (⋯, ·) in help text, rewrote LLM summaries section. (#1496, #1506)
- Homepage: Added headline features (CI status, PR checkout, hash_port) and tips link. (#1501)
- Experimental badge pills: Styled [experimental] markers as pill badges in web docs. (#1499)
Internal
- Deduplicated hook config resolution: Extracted shared hook-type list and made lookup_hook_configs pub(crate). (#1512)
- Agent Skills metadata: Added metadata.internal: true to repo-scoped skills so npx skills add only offers user-facing ones. (#1491)
Install worktrunk 0.29.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.29.3/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.29.3/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.29.3
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.29.2 | 13 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- [switch] no-cd config option: Disable directory change by default with no-cd = true in the [switch] section. Use --cd flag to override when needed. Useful for tmux workflows where sessions handle navigation. Docs (#1401, thanks @jradtilbrook)
Fixed
- GPG signature output breaks wt list: When log.showSignature is set in git config, GPG verification lines contaminated stdout in git log calls, causing parse failures. All git log invocations now pass --no-show-signature. (#1465, thanks @apre)
- Tab completions ignore shell substring matching: The binary was prefix-filtering branch candidates before returning them to the shell, preventing fish substring matching (auth<TAB> → feature/user-auth) and zsh fuzzy matching. Completions now return all candidates and let the shell apply its own matching. (#1471, thanks @benjaminbauer for reporting #1468)
- Tab completions unusable in large repos: Repos with many remote branches triggered the "do you wish to see all N possibilities?" prompt. Remote-only branches are now excluded when the total exceeds 100. (#1442, thanks @cperalt for reporting #1415)
- Nushell shell integration broken in Home Manager module: The Nix Home Manager module used use instead of source for the nushell init script, and template definitions were not exported, preventing the wt wrapper function from loading. (#1476, thanks @mystilleef for reporting #1475)
Documentation
- Manual commit message recipes: Added recipes to Tips & Patterns for using commit.generation.command config to write commit messages by hand with $EDITOR instead of an LLM. (#1469, thanks @viicslen for the feature request in #1467)
Internal
- Skill/CI guidance: Improved Claude bot skills for triage, code review, and CI monitoring. (#1485, #1477, #1474, #1472, #1470, #1458, #1447)
Install worktrunk 0.29.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.29.2/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.29.2/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.29.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.29.1 | 12 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- GitHub Enterprise support for wt switch: wt switch pr:<number> now works with GitHub Enterprise instances by extracting the hostname from the remote URL and passing --hostname to gh. (#1408, thanks @TomRomeo)
- wt switch --no-cd print mode: When wt switch --no-cd opens the interactive picker (no branch argument), selecting a branch prints its name to stdout and exits — useful for scripting. (#1445, thanks @ruudk for the feature request in #1404)
- Shadow warning for step aliases: wt step now warns when a user-defined alias has the same name as a built-in step command (e.g., commit, rebase), since clap intercepts the built-in before the alias runs. (#1389)
Fixed
- Post-switch hooks on wt remove: When removing the current worktree, post-switch hooks now fire correctly as the user is implicitly switched to the primary worktree. Previously, project hooks were silently skipped because config lookup failed from the removed CWD. (#1452, thanks @mjakl for reporting #1450)
- LLM commit session isolation: The recommended Claude command for commit generation now includes --no-session-persistence, preventing commit conversations from polluting claude --continue. (#1454)
- Color formatting in error messages: DetachedHead and NotInWorktree error messages now support color-print styling, matching other error variants. (#1387)
- Windows error handling: Replaced std::process::exit() with proper error returns in Windows-specific code paths, so destructors and cleanup run correctly. (#1456)
Documentation
- Hook JSON context section: Fixed documentation that incorrectly described hook_type and hook_name as extras; added the TOML hook definition showing how JSON stdin is wired. (#1360)
- wt remove help text: Updated example heading to clarify that wt remove works on both worktrees and branches. (#1449)
- Xcode DerivedData cleanup recipe: Added recipe for cleaning Xcode build artifacts across worktrees. (#1423, thanks @RickeyBoy)
Internal
- Refactoring: Extracted handler functions from main() dispatch, replaced negated boolean variables with positive-polarity names (no_verify → verify, no_delete_branch → keep_branch). (#1394, #1388, #1393)
- Test reliability: Resolved flaky PTY/timing issues in integration tests, consolidated trivial tests into inline snapshots. (#1459, #1392, #1382, #1390)
- CI: Added Zola docs validation to PR checks, catching broken internal anchor links before merge. (#1396)
Install worktrunk 0.29.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.29.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.29.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.29.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 insta |
| v0.29.0 | 9 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step <alias> command: User-defined command templates with template variables ({{ branch }}, {{ worktree }}, custom --var KEY=VALUE). Project-config aliases require approval; user-config aliases are trusted. Docs (#1348, thanks @cavanaug for the feature request in #1214)
- Remove worktrees from switch picker: alt-r in wt switch interactive picker removes the highlighted worktree directly (no force flags — matches safety defaults). (#1253, thanks @alfredomtx for the feature request in #1251)
- wt hook <type> --dry-run: Preview hook expansion with template variables resolved, without executing. (#1361)
- Hook template variables: {{ hook_type }} and {{ hook_name }} are now available in hook command templates. (#1364)
- Typo suggestions for step commands: Unknown step commands and aliases now suggest the closest match. (#1363)
- Syntax-highlighted --help: Code blocks in --help output now render with language-aware syntax highlighting (TOML, bash) instead of plain dimmed text. Help options are grouped under navigational headings (Picker Options, Automation). (#1365, #1355, #1359)
- Nix Home Manager module: Install worktrunk via Nix Home Manager. (#1287, thanks @DuskyElf; thanks @meicale for reporting #1257)
- Output styling: Bold names replace quoted names in error messages, underlined references replace bright-black in hints, @ path convention unified in section headings, and branch-worktree mismatch warnings now show both actual and expected paths. (#1375, #1380, #1285, #1376, #1377, thanks @jhigh2000 for reporting #1184)
Fixed
- --no-cd with interactive picker: The --no-cd flag is now passed through when using wt switch with the interactive picker. (#1331, thanks @cperalt for reporting #1330)
- Remote branches with / in picker: wt switch --remotes now correctly handles remote branches with / in the name (e.g., origin/user/feature). (#1266, thanks @curtbushko for reporting #1260)
- Nushell config path on Windows: wt config shell install now uses the platform-appropriate config directory for nushell on Windows. (#1294, thanks @deltoss for reporting #1293)
- Git for Windows per-user install: Detect per-user Git for Windows installations and show a clean error message instead of panicking when Git Bash is not found. (#1261, #1262, thanks @JefMasereel for reporting #1259)
- JSON output summary field: wt list --format=json now includes the summary field. (#1339)
- Squash merge message: Uses source branch name instead of target branch in the merge commit message. (#1319, thanks @ricafeal)
- Alias approval errors: Propagate the real error (e.g., "no remote URL found") instead of a vague "Cannot determine project identifier". (#1374)
- wt step prune output: Summary uses cleaner paired format ("Pruned 1 worktree & branch") and fixes post-remove hook display path for non-current worktrees. (#1344)
- VCS metadata in copy-ignored: Exclude .git, .hg, .svn, _darcs directories from wt step copy-ignored. (#1250)
- Nix evaluation warning: Use stdenv.hostPlatform.system instead of deprecated system. (#1336, thanks @onelocked)
Documentation
- Home page SEO: Canonical URL deduplication and consistent tagline. (#1357)
- LLM commit tools: Add opencode and consolidate other LLM commit tool references. (#1295)
Internal
- Git plumbing: Replace porcelain commands with plumbing alternatives (rev-parse --symbolic-full-name, log --no-walk, for-each-ref) for more robust output parsing. Cache deprecated-variable regexes and fix silent wrong results in same_commit()/trees_match(). (#1345, #1338, #1358)
- Error propagation: repo_path() and ShellConfig::get() now return Result instead of silently falling back. (#1280, #1262)
- CI improvements: Consolidated setup into composite action, replaced gh run watch with poll loops, added conflict resolution for bot PRs in nightly cleaner. (#1273, #1329, #1307)
Install worktrunk 0.29.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/wo |
| v0.28.2 | 3 มีนาคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step prune output: Dirty or locked worktrees are silently skipped instead of printing warnings, and "No worktree found for branch" info messages are suppressed — prune output now shows only what was actually removed. (#1236)
Fixed
- CWD removal hint: After a worktree is removed while a shell is in that directory, the hint now checks whether wt switch ^ would actually work before suggesting it — falls back to suggesting wt list when the default branch worktree doesn't exist (e.g., bare repos). (#1238, thanks @davidbeesley for reporting #1168)
- Submodule detection in worktree removal: Submodule detection now uses git submodule status output instead of parsing error messages, avoiding locale-dependent and version-dependent string matching. (#1247)
Internal
- Hook dispatch: Introduced HookCommandSpec struct and extracted helper functions to deduplicate hook dispatch code (~50 lines net reduction). (#1248)
- CI skills: Fixed jq escaping in ad-hoc CI polling queries and improved Step 5 dismissal ordering in pr-review skill. (#1241, #1246)
Install worktrunk 0.28.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.28.2/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.28.2/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.28.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.28.1 | 28 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Nushell tab completions: wt switch <TAB> and subcommand completions now work in nushell. (#1220, thanks @omerxx for reporting #1215)
- wt step prune reliability: Candidates are now removed inline as they're discovered instead of scan-then-remove, with per-candidate error handling (dirty worktrees are warned and skipped). Dry-run and execution summaries now distinguish worktrees, branches, and detached worktrees. Command marked [experimental]. (#1234, #1232, #1223)
- wt step diff performance: Copies the real git index instead of creating an empty one, preserving git's stat cache so unchanged tracked files are skipped. (#1230)
Fixed
- Branch delete race on fast-path remove: wt remove now deletes merged branches synchronously on the fast path instead of deferring to the background process, fixing a race where wt switch --create <branch> fails with "branch already exists". (#1216)
- Panic in is_bare() on unusual repositories: is_bare() now propagates errors instead of panicking. (#1221, @bendrucker)
- Help text table coloring: Status symbols and backtick-enclosed text in --help tables now render with proper ANSI colors. (#1231)
Internal
- CI workflow: Added concurrency group to claude-mention workflow, fixed external contributor PR review permissions. (#1233, #1226)
Install worktrunk 0.28.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.28.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.28.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.28.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.28.0 | 26 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step prune command: Remove worktrees whose branches are already merged into the default branch. Skips unmerged and recently created worktrees, with --min-age to control the staleness threshold. Docs (#1191)
- Color palette in wt config shell show-theme: Shows each color and style rendered in itself — base colors, modifiers, bold+color and dim+color variants — for diagnosing legibility issues on different terminal themes. (#1185, thanks @jhigh2000 for reporting #1184)
- Smarter column layout in wt list: The Message column is hidden when the terminal is too narrow for Summary to reach 40 characters, preventing both columns from being truncated to unreadable widths. (#1166)
Fixed
- Submodules in worktree removal: wt remove now handles worktrees containing initialized git submodules, which previously failed with "working trees containing submodules cannot be moved or removed". (#1196, thanks @dlecan for reporting #1194)
- CWD recovery validation: Recovery from a deleted worktree directory now validates that candidate repositories actually contain the deleted path as a worktree, preventing false matches when multiple repos share a parent directory. (#1193)
- Shell-escape paths in -C flag hints: Paths containing spaces or special characters in -C hints are now properly shell-escaped. (#1173)
- ANSI handling in CWD recovery: Recovery messages now use anstream for proper ANSI handling on terminals that don't support color. (#1183)
- Worktree path in detached HEAD removal messages: Removal output for detached HEAD worktrees now includes the worktree path for clarity. (#1210)
- Pruned worktree output: Worktree and branch deletion for pruned worktrees are combined into a single output line instead of two separate messages. (#1211)
Documentation
- Page metadata and SEO: All doc pages now have <meta name="description">, canonical URLs, and structured data (JSON-LD) for better search engine visibility. (#1167)
Internal
- CI bot improvements: Inline suggestions, confidence-based review scrutiny, consolidated review+CI analysis, self-poll prevention, verified-facts guideline for triage, and explicit issue-closing in nightly cleaner. (#1172, #1181, #1199, #1204, #1212, #1198, #1209)
Install worktrunk 0.28.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.28.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.28.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.28.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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.27.0 | 22 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step promote command (experimental): Exchange branches between the main worktree and any linked worktree, including swapping gitignored files (build artifacts, .env, node_modules/). Shows mismatch state in wt list with ⚑ indicator; restore with no arguments from main worktree. Docs (#789, thanks @zpeleg for the feature request in #738)
- Instant worktree removal: wt remove now renames the worktree to a staging path before spawning the background cleanup, making the path unavailable immediately instead of after a 1-second sleep. Falls back to legacy removal if rename fails (cross-filesystem, permissions). (#773)
- Graceful recovery from deleted worktree directory: When a worktree is removed while a shell is still in that directory, wt switch and wt list now recover automatically — find the parent repository from $PWD and proceed without pre-switch hooks. (#1146, thanks @davidbeesley for reporting #1109)
- PR/MR support promoted out of experimental: GitHub PR (pr:<number>) and GitLab MR (mr:<number>) targets in wt switch are now considered stable — 11 minor releases with no interface changes since v0.15.0. (#1114)
Fixed
- SSH URLs with ports: Remote matching now handles ssh://git@host:2222/owner/repo.git — ports are stripped during URL parsing instead of rejecting the URL. (#1151)
- Config path resolution: wt config create now resolves the same path as config loading, fixing a mismatch when using XDG directories. (#1135, thanks @christopher-buss for reporting #1134)
- PTY prompt echo interleaving: Approval prompts no longer intermix with echoed input on slower systems. Uses quiescence detection instead of a fixed sleep. (#1133)
- Better diagnostics when foreground removal fails: When wt remove --foreground fails with "Directory not empty", now shows the remaining top-level entries (capped at 10) and suggests trying background removal. (#1150)
- Output formatting consistency: Hints use canonical "To X, run Y" phrasing, config update hints render in gutter blocks with correct -C flag for linked worktrees, and ANSI color nesting fixed in hint messages. (#1138, #1137)
- Panic-safe error propagation: Replaced .unwrap() and .expect() calls in functions returning Result with proper ? and bail! error propagation. (#1127)
Documentation
- Bot trigger renamed: CI bot responds to @worktrunk-bot instead of @claude, matching the actual GitHub username. (#1149)
- wt step promote documented in worktree model: The branch-exchange operation is noted as the sole exception to the "never retarget a worktree" rule. (#1154)
Internal
- CI security model: Rulesets, token consolidation, and environment protection hardened for GitHub Actions workflows. (#1118)
- Nightly CI workflows: Automated review of Claude CI session logs and 24-hour code quality sweep for bugs, missing tests, and stale docs. (#1111)
- CI reviewer and bot improvements: Better failure tracing, Dependabot PR reviews, thread resolution ordering, LGTM dedup, actionable feedback, automatic response to bot PR comments, and graceful handling of mentions on merged/closed PRs. (#1117, #1128, #1129, #1131, #1141, #1142, #1145, #1147, #1153, #1158, #1164)
Install worktrunk 0.27.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.27.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.27.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.27.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
────────────────────────────────────────────────┼───────────────────┼─────────────
worktrunk-aarch64-apple-darwin.tar.xz │Apple Silicon macOS│checksum
──────────── |
| v0.26.1 | 19 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- Statusline panic without LLM config: wt list statusline panicked when no LLM command was configured. Now skips summary generation gracefully. (#1107)
Internal
- Demo GIFs now show the Summary column in wt list --full output. (#1104, #1106)
- CI session log uploads fixed to use correct path. (#1103)
Install worktrunk 0.26.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.26.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.26.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.26.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.26.0 | 19 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Summary column in wt list --full: LLM-generated one-line branch descriptions. Opt-in via [list] summary = true in config (experimental). Requires [commit.generation] config. (#1100)
- wt step diff command: Show all uncommitted and untracked changes that wt merge would include as a unified diff against the merge base. Pass -- --stat for a summary. Docs Closes #1043. (#1074, thanks @davidbeesley for the feature discussion)
- pre-switch hook: New hook that runs before wt switch validation. Use it to fetch-if-stale or run pre-flight checks before switching. Respects --no-verify. Docs (#1094, thanks @jdb8 for the use case in #1085)
- wt config update command: Automatically apply config migrations — detects deprecated patterns (template variables, [commit-generation], approved-commands), shows a diff preview, and applies with confirmation. Use --yes to skip the prompt. (#1083)
- Configurable picker timeout: New [switch.picker] timeout-ms setting (default: 200ms, 0 to disable). The [select] config section is deprecated in favor of [switch.picker] — run wt config update to migrate. (#1087)
- Command audit log: All hook executions and LLM commands are logged to .git/wt-logs/commands.jsonl with timestamps, exit codes, and duration. Auto-rotates at 1MB. View with wt config state logs get or query with jq. (#1088)
Fixed
- Hook CWD wrong from subdirectories: Hooks invoked from a subdirectory within a worktree ran with incorrect CWD and {{ worktree_path }}/{{ worktree_name }} template variables resolved incorrectly. (#1097)
- copy-ignored verbose output and error handling: -v flag was silently ignored, error messages lacked file paths, and broken symlinks from interrupted copies caused failures. Also skips non-regular files (sockets, FIFOs) instead of failing. Fixes #1084. (#1090, thanks @jdb8 for reporting)
- Nushell wt list piping: wt list --format json | from json failed in nushell because the wrapper's stdout capture prevented piping. Fixes #1062. (#1081, thanks @omerxx for reporting)
- Approved-commands lost during config migration: Running the config migration could silently discard existing approval data. Now copies approved-commands entries to approvals.toml before migration. (#1079)
- Deprecation messages reference wt config update: Deprecation warnings now point to the new wt config update command for one-step migration instead of manual mv instructions. (#1089)
Documentation
- wt switch help text: Updated description to "Switch to a worktree; create if needed" to surface auto-create behavior. (#1082)
- Docs syntax highlighting: Migrated to giallo engine with a warm theme. (#1080)
Internal
- CI reviewer improvements: File-based GraphQL queries, centralized shell quoting guidance, artifact upload path fixes. (#1091, #1098, #1099)
- Issue triage for external contributors: CI triage workflow now runs for all external contributor issues. (#1086)
Install worktrunk 0.26.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.26.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.26.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.26.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 W |
| v0.25.0 | 17 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- System-wide config file: Load organization-wide defaults from a system config file (/etc/xdg/worktrunk/config.toml on Linux, /Library/Application Support/worktrunk/config.toml on macOS) before user config. Override the path with $WORKTRUNK_SYSTEM_CONFIG_PATH. Visible in wt config show. (#963, thanks @goodtune)
- AI summary preview in wt switch: New 5th tab shows AI-generated branch summaries using your configured [commit.generation] LLM command. Opt-in via [list] summary = true in config. Summaries are cached in .git/wt-cache/summaries/ with hash-based invalidation. Docs (#1049)
- Approvals stored in dedicated file: Approved commands moved from config.toml to approvals.toml, enabling dotfile management of config without exposing machine-local trust state. Existing approvals in config.toml are read automatically with a deprecation warning and migration instructions in wt config show. (#1042)
- Error hints include --execute context: When wt switch --execute=<cmd> fails, suggested commands now include the full --execute and trailing args so you can copy-paste the fix directly. (#1064)
- wt list startup performance: Config resolution moved into the parallel phase, running concurrently with other git commands instead of sequentially on the critical path. (#1054)
Fixed
- Submodule worktree path resolution: wt switch resolved to .git/modules/ instead of the working directory inside git submodules. Fixes #1069. (#1070, thanks @SokiKawashima for reporting)
- Per-project [list] timeout ignored: The timeout setting from per-project config ([projects."name".list]) was not applied — only the global config value was used. (#1063)
- Empty repos crash wt list: Repositories with no commits (unborn HEAD) caused errors. Now renders empty cells for commit-dependent fields. (#1058)
- Stray blank lines before hints in error output: Error messages with hints (↳) had an extra blank line separating the hint from its subject. (#1072)
Internal
- Shell escaping consolidation: Dropped shlex crate, consolidated on shell_escape across the codebase. (#1065)
- CI reviewer improvements: Resolve review threads, skip trivial re-approvals, default to suggestions. (#1068)
Install worktrunk 0.25.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.25.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.25.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.25.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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.24.1 | 16 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Template error messages: Template expansion errors now show what failed, the failing template line, and available variables for undefined variable errors. (#1041)
- Interactive picker preview speed: Preview pre-computation is parallelized via rayon, reducing the chance of a blocking cache miss when switching preview tabs. (#1048)
- wt switch performance: Switching to existing worktrees defers path computation, reducing startup latency. (#1029, #1030, #1031)
Fixed
- PowerShell wrapper swallows -D flag: The wrapper's [Parameter(ValueFromRemainingArguments)] promoted it to an "advanced function", causing PowerShell to consume -D as -Debug instead of passing it to wt.exe. Fixes #885. (#1057, thanks @DiTo97 for reporting)
- Nushell shell integration: Multiple fixes for nushell — auto-detect for install even without vendor/autoload directory (#1032), detection checks multiple config paths (#1038), uninstall cleans all candidate locations (#1050), wrapper hardening and improved diagnostics (#1059). (thanks @arnaudlimbourg for #1032, #1038, and @omerxx for reporting in #964)
- Interactive picker leaves screen artifacts: The picker left visual artifacts after exiting. Fixes #1027. (#1028, #1044, thanks @davidbeesley)
- Statusline counts files outside sparse checkout cone: Branch diff statistics in the statusline included files outside the sparse checkout cone, inflating counts. (#1024, thanks @bendrucker)
- Template placeholders leak into displayed commands: {{ }} delimiters in hook commands were incorrectly syntax-highlighted, showing ANSI artifacts instead of the template text. (#1022)
- Hook announcement trailing colon: Hook announcements like "Running post-merge project:sync:" had a trailing colon that created visual noise. (#1025)
- Blank line after approval prompts: Approval prompts showed an extra blank line after the user pressed Enter. (#1040)
Internal
- Automated Claude PR review: Added workflow for automated code review on PRs. (#1037)
- Time-to-first-output benchmarks: Added benchmarks for remove, switch, and list startup latency. (#1023)
Install worktrunk 0.24.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.24.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.24.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.24.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.24.0 | 15 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Nushell support (experimental): Initial nushell shell integration — shell wrapper, completions, and wt config shell install support. This is a proof-of-concept and will need iteration before it's usable; if you're a nushell user feel free to try it and report issues. (#964, thanks @arnaudlimbourg)
- Version check in wt config show --full: The diagnostics section now queries GitHub for the latest release and shows "Up to date", "Update available", or "Version check unavailable". Gated behind --full so normal commands are unaffected. Closes #1003. (#1011, thanks @risperdal for requesting)
- Fish outdated wrapper detection: wt config show now detects when the installed fish shell wrapper has outdated code (e.g., from a previous version) and shows "Outdated shell extension" with a reinstall hint, instead of incorrectly reporting "Not configured". (#1009)
Fixed
- LLM subprocess blocked in Claude Code sessions: Claude Code sets CLAUDECODE=1 which blocks nested invocations, breaking wt step commit and wt merge commit generation. Now strips the env var before spawning the LLM command. (#1021)
- Blank line between hint and subject in config show: The "To configure, run wt config shell install" hint was visually detached from the shell entries it referred to. (#1007)
Documentation
- Status symbol descriptions: Corrected quick start documentation — ↕ means diverged from default branch (not unpushed commits), + means staged changes (not uncommitted changes). (#1017)
- Claude Code commit command: Added CLAUDECODE env var unsetting to the Claude Code documentation for commit message generation. (#1020)
Internal
- Environment variable prefix standardization: Renamed remaining WT_TEST_* env vars to WORKTRUNK_TEST_*, completing the prefix migration. (#1016)
- Plugin metadata: Aligned plugin description with Cargo.toml tagline (#1019), fixed duplicate skills declaration (#1014, thanks @jacksonblankenship for reporting #1013), corrected marketplace source path (#1012).
Install worktrunk 0.24.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.24.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.24.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.24.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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.23.3 | 13 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Error display for failed commands: Failed git commands are now shown in a separate bash-highlighted gutter block instead of inline parenthesized text, making long commands much more readable. (#1001)
- PowerShell detection and diagnostics: Detect PowerShell via PSModulePath environment variable so Windows users get "shell requires restart" instead of "not installed". wt config show now displays the detected shell and verification hints. Fixes #885. (#987, thanks @DiTo97 for reporting)
Fixed
- Fish shell wrapper incompatible with fish < 3.1: The shell wrapper used VAR=value command syntax which requires fish 3.1+. Now uses env VAR=value ... for compatibility with all fish versions. Fixes #999. (#1000, thanks @chrisrickard for reporting)
- Symlink paths resolved in display messages: Status messages like "Created worktree @ path" showed canonical paths instead of the user's symlink path. Now consistent with cd directives. Fixes #968. (#985, thanks @brooke-hamilton for reporting)
Documentation
- Deduplicated manual shell setup: Removed duplicated per-shell eval snippets from wt config --help, referencing wt config shell init --help instead. (#986)
- PowerShell diagnostic guidance: Added PowerShell-specific debugging steps to shell integration and troubleshooting references. (#993)
Install worktrunk 0.23.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.23.3/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.23.3/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.23.3
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.23.2 | 11 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- --force flag for wt step copy-ignored: Overwrite existing destination files when copying gitignored files to new worktrees. Closes #971. (#974, thanks @williamgoulois for requesting)
Fixed
- wt switch pr:NNNN / mr:NNNN fails in repos without fetch refspecs: Same-repo PRs and MRs failed with "No branch named X" in single-branch clones or bare repos because fetch didn't create remote tracking branches, and worktree creation relied on DWIM. Now uses explicit refspecs and -b fallback. (#965, thanks @andoniaf)
- Progressive table garbled when output exceeds terminal height: wt list output was corrupted when more lines than the terminal height, because cursor-up commands tried to reach scrolled-off lines. Now detects overflow and falls back to a clean full-table print. (#981)
- Symlink paths resolved to canonical in cd directives: When navigating via symlinks, cd directives wrote canonical paths, silently moving users out of their symlink tree. Now preserves the user's logical path. Fixes #968. (#976, thanks @brooke-hamilton for reporting)
- Terminal artifacts when cancelling interactive picker: Pressing Esc to cancel the picker left terminal artifacts and a misplaced cursor. Now skim handles cleanup symmetrically for both cancel and accept. (#984)
Documentation
- Hook examples: safer port cleanup: Added -sTCP:LISTEN to lsof in hook examples to prevent accidentally killing unrelated processes with connections to the port. (#952, thanks @andoniaf)
Install worktrunk 0.23.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.23.2/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.23.2/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.23.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.23.1 | 7 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Interactive picker runs hooks: wt switch without arguments (the interactive picker) now runs post-switch, post-start, and post-create hooks, matching the non-interactive path. (#942)
- Combined hook output during removal: Post-remove and post-switch hooks during worktree removal are now shown on a single output line instead of two separate lines. (#943)
Fixed
- Shell escape corruption with template filters: Shell escaping was applied before template rendering, so filters like sanitize operated on already-escaped strings, corrupting values with special characters (e.g., apostrophes in branch names). (#944)
- wt switch - history corruption: wt switch foo while already in foo would incorrectly record foo as the previous branch, breaking wt switch - ping-pong. (#944)
- --base without --create showed wrong error: Using --base without --create could produce misleading errors (e.g., "No previous branch") instead of the expected warning that --base requires --create. (#944)
Install worktrunk 0.23.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.23.1/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.23.1/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.23.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.23.0 | 6 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Preserve subdirectory position when switching: wt switch now lands in the same subdirectory of the target worktree if it exists, falling back to the root if it doesn't. Docs (#939, thanks @frederik-suerig for requesting)
- wt switch --no-cd: Skip the directory change after switching, useful for scripting or running commands in another worktree without leaving your current shell position. Docs (#932, thanks @ArnaudRinquin for requesting)
- Alt-c to create worktree from picker: In the interactive picker, press Alt-c to create a new worktree using the current query as the branch name. (#933)
- Faster preview tab switching: Preview tabs (HEAD±, log, main…±, remote⇅) are now pre-computed in a background thread, making tab switching near-instant. (#935)
Fixed
- Pager width detection: Makes preview pane width available to pagers via $COLUMNS, so tools like delta can use it for correct side-by-side rendering (e.g., pager = "delta --width=$COLUMNS"). Fixes #924. (thanks @tnlanh for reporting) (#930)
- ANSI style bleeding in preview tabs: Fixed styling artifacts where dividers appeared emphasized and diffstat lines appeared dim. (#931)
- URL template expansion with --skip: Skip URL template expansion when --skip url-status is used, avoiding unnecessary work. (#923)
- Hook error consistency: wt hook <type> now errors consistently for all hook types when no hooks are configured, instead of silently succeeding for some types. (#916)
Documentation
- Improved install instructions in release notes. (#918)
Internal
- CI: check for existing fix PRs before creating duplicates. (#922)
Install worktrunk 0.23.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.23.0/worktrunk-installer.sh | sh && wt config shell install
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.23.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
Install prebuilt binaries via Homebrew
brew install worktrunk && wt config shell install
Download worktrunk 0.23.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 install
Install via Winget (Windows)
winget install max-sixty.worktrunk && git-wt config shell install
Install via AUR (Arch Linux)
paru worktrunk-bin && wt config shell install |
| v0.22.0 | 2 กุมภาพันธ์ 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch integrates interactive picker: wt switch without arguments now opens the interactive picker (previously wt select). The separate wt select command is deprecated with a warning directing users to use wt switch instead. Closes #890. (thanks @strangemonad for the suggestion) (#894)
- TOML syntax highlighting: Config output from wt config show and wt config shell show-theme now renders TOML with syntax highlighting (table headers cyan, string values green, comments dimmed). (#905)
- Bash syntax highlighting improvements: Multi-line bash commands in hook previews now preserve syntax highlighting across newlines. Wrapped continuation lines are indented with 3 extra spaces to distinguish terminal-forced wraps from actual newlines. (#906)
- Unified background hook output: Contiguous post-switch and post-start hooks are now combined into a single output line instead of two separate lines. (#908)
Documentation
- Removed redundant horizontal rules before H1 headers in documentation pages. (#909)
Internal
- Updated GitHub Actions and Rust nightly versions. (#910)
- Bumped tree-sitter ecosystem to 0.26 for unified multi-line highlighting. (#906)
- Dependency updates: minijinja 2.15.1, clap, indexmap, ignore, thiserror, time, and others. (#912, #913)
Install worktrunk 0.22.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.22.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.22.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.22.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.21.0 | 30 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Absolute paths in worktree-path templates: New {{ repo_path }} variable enables absolute path configurations like {{ repo_path }}/../{{ repo }}.{{ branch | sanitize }}. Tilde expansion is also supported (~/worktrees/{{ repo }}/{{ branch }}). Fixes #902. (thanks @bingryan for reporting) (#904)
Documentation
- Documented prefix stripping in worktree-path templates using minijinja's built-in replace filter and slicing syntax. Closes #900. (thanks @laurentkempe for requesting) (#903)
Install worktrunk 0.21.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.21.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.21.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.21.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.20.3 | 29 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- PowerShell auto-configuration on Windows: When running wt config shell install from cmd.exe or PowerShell, both PowerShell profile files are now created automatically (Documents/PowerShell and Documents/WindowsPowerShell). Fixes #885. (thanks @DiTo97 for reporting) (#898)
- -C flag respected in hook context: The -C flag now correctly sets the worktree path for hooks, fixing wt -C /path hook ... commands that were using the wrong context. (#899)
- --config path validation: Now warns when --config points to a non-existent file instead of silently using defaults. (#895)
Documentation
- Fix shell quoting in hook examples — template variables are auto-escaped, so manual quoting caused issues with special characters. (#895)
- Updated documentation to use tool-agnostic terminology for LLM commit messages. (#891)
Internal
- Consolidated PR/MR resolution into unified remote_ref module. (#893)
- Simplified command structure and removed dead code. (#892)
- Eliminated Settings types, added accessor methods to Config types. (#896)
Install worktrunk 0.20.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.20.3/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.20.3/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.20.3
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.20.2 | 28 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- PowerShell shell integration: Fixed shell integration not working on Windows PowerShell. The init script now includes | Out-String to convert array output to a string. Existing configs without this fix are detected as "not installed" so wt config shell install will update them automatically. Fixes #885. (thanks @DiTo97 for reporting) (#888)
- Branch removal message: "No worktree found for branch X" now shows as info (○) instead of warning (▲) when removing a branch-only, since this is expected behavior. (#887)
Documentation
- Documented main worktree behavior in wt step relocate --help. (#889)
Install worktrunk 0.20.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.20.2/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.20.2/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.20.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.20.1 | 27 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt statusline --format=json: Output current worktree as JSON (same structure as wt list --format=json). Also adds --format=claude-code as canonical syntax (the old --claude-code flag remains supported). Fixes nested worktree detection that incorrectly identified parent worktrees. (#875)
- wt config show shell status: Each shell integration line now starts with the shell name (e.g., "bash: Already configured...") for easier scanning. (#881)
- wt config show performance: 8x faster (~1.2s → ~150ms) by using PATH lookup instead of running claude --version. (#883)
Fixed
- Config TOML formatting: Fixed spurious empty [commit] header appearing when only [commit.generation] is configured. (#879)
- Documentation URLs: Fixed broken worktrunk.dev URLs in fish wrapper and config templates. (#882)
Documentation
- Fixed worktree-path example on tips page. (#876, thanks @uriahcarpenter)
- Fixed OSC 8 hyperlink sequences leaking through to web docs as garbage text. (#870)
Internal
- Demo snapshot mode for regression testing of command output. (#871)
- CI improvements: nextest binary compatibility fix, pinned runner versions, weekly renovation workflow. (#878, #884)
Install worktrunk 0.20.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.20.1/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.20.1/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.20.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.20.0 | 26 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step relocate command: Move worktrees to their expected paths based on the worktree-path template. Supports --dry-run preview, filtering by branch name, and --commit to auto-commit dirty worktrees before moving. Handles complex scenarios including worktree swaps (A→B, B→A), chains, and the --clobber flag to back up blocking non-worktree paths. Docs (#790)
- LLM setup prompt: First-time interactive prompt when users attempt wt merge, wt step commit, or wt step squash without LLM configuration. Detects available tools (claude, codex) and offers auto-configuration with ? to preview the generated config. Add skip-commit-generation-prompt to user config to suppress. (#867)
- Consistent prompt styling: Interactive prompts now use consistent cyan styling via prompt_message() formatting. (#858)
Fixed
- Path display in error messages: User-facing paths now consistently use format_path_for_display(), fixing cases where raw .display() output could show inconsistent path formats. (#856)
Documentation
- Added Quick Start section to front page showing the switch → list → merge workflow. (#864)
- Updated template documentation: removed deprecated template-file options, added {{ git_diff_stat }} variable, clarified squash-only variables. (#854)
- Fixed stale documentation for [commit.generation] config format, statusline context gauge, and CI status for remote-only branches. (#853)
Internal
- Bumped nix crate from 0.30.1 to 0.31.1. (#860)
- Refactored deprecation detection for better modularity. (#852)
Install worktrunk 0.20.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.20.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.20.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.20.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.19.0 | 25 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- LLM commit configuration redesign: The [commit-generation] section is now [commit.generation], and command + args are unified into a single shell-executed command string. Existing configs continue to work — a deprecation warning shows the new format and creates a .new config file you can apply with mv. Claude Code (claude -p) and Codex (codex exec) are documented as first-class options alongside llm. See the LLM commits guide. (#809, #837)
- Per-project hooks: User config can define hooks per-project that append to global hooks. Execution order: global → per-project → project config. Configure under [projects."owner/repo".hooks]. (#842)
- Context window gauge for Claude Code: Statusline mode shows a moon phase gauge (🌕🌔🌓🌒🌑) for context window usage. (#840)
- CI status for remote-only branches: wt list --remotes shows CI status for branches that only exist on the remote. (#817)
- Hook log file lookup: wt config state logs get --hook=<spec> returns the path to a specific hook's log file. (#816, thanks @EduardoSimon for requesting)
- Branch/fork info in PR/MR display: wt switch pr:N shows the source branch (e.g., feature-auth) or fork reference (e.g., contributor:feature) alongside PR details. (#808)
- Claude Code section in wt config show: Shows Claude CLI installation status, plugin status, and statusline configuration. (#833)
- Deprecation details moved to wt config show: Other commands show a brief pointer instead of full deprecation details. (#828)
- Config validation suggests correct file: When a config key belongs in user config but appears in project config (or vice versa), the warning suggests the correct location. (#804)
- Tilde paths in hints: Shell command hints use ~ instead of full home directory paths when safe. (#710)
- Improved --create conflict error: wt switch --create pr:101 shows the existing branch name in the error. (#807)
- CI status prioritized in statusline: CI status is retained longer when the statusline truncates. (#845)
Fixed
- Template expansion bugs: Fixed worktree_path_of_branch not respecting shell_escape flag, Windows CI cache rename failures, and WORKTRUNK_MAX_CONCURRENT_COMMANDS=0 meaning "no limit". (#847, #849)
- Hook and CI status panics: Fixed panic when serializing mixed named/unnamed hook configs, banned colons in hook names to prevent parsing ambiguity, and fixed GitLab MR detection when multiple MRs exist without project ID. (#846, #848)
- Pre-commit hooks for clean worktree squash: Pre-commit hooks are collected for approval when squashing on a clean worktree. Previously only collected when dirty. (#695)
- Hint message formatting: Fixed ANSI escape code interference in dim hint messages. (#836)
- Spurious [commit] header: Fixed config migration showing [commit] section header when only commit-generation fields needed migration. (#834)
Documentation
- Added at-a-glance examples to config documentation. (#826)
- Clarified user project-specific settings section. (#835)
- Consistent worktree terminology throughout docs. (#813)
- Added tip for monitoring hook logs. (#838)
Internal
- Replaced manual quote escaping with shell_escape crate. (#810)
- Used sanitize-filename crate for filename sanitization. (#832)
- Cached CI tool availability checks. (#831)
- Moved inline imports to module top level. (#818, #819, #820, #822)
Install worktrunk 0.19.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.19.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.19.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.19.0
────────────────────────────────────────────────┬───────────────────┬─────────────
File │Platform │Checksum
────────────────────────────────────────────────┼──────── |
| v0.18.2 | 22 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- PR/MR context display: wt switch pr:N and mr:N now show PR/MR details (title, author, state, URL) after fetching. (#782)
- Fork PR branch conflicts: When a fork PR's branch name conflicts with an existing local branch (e.g., contributor opens PR from their main), worktrunk now creates a prefixed branch like contributor/main instead of failing. Closes #714. (thanks @vimtor for reporting)
Fixed
- Help output formatting: Fixed double blank lines appearing after demo comments in help output. (#795)
- Error handling reliability: Replaced fragile string-based error parsing with structured approaches for git stash, GitHub CLI, and GitLab CLI operations. (#787)
Documentation
- ci-status help text: Improved clarity of the ci-status configuration documentation. (#794)
- wt remove help text: Simplified short description and added documentation for pre-remove and post-remove hooks. (#792)
- Subcommand documentation: Fixed generated website docs for subcommands (like wt step copy-ignored, wt config state) to include their short descriptions. (#793)
Install worktrunk 0.18.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.18.2/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.18.2/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.18.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.18.1 | 21 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- Submodule worktree paths: Worktrees are now created in the correct location when running inside a git submodule. Previously, worktrees were created relative to the parent repo's .git/modules/ directory instead of the submodule's working directory. (#762, thanks @lajarre; #777, thanks @mhonsel for reporting)
- Shell integration warnings: Warnings about shell integration now check if the current shell has integration configured, not whether any shell does. This fixes misleading "shell requires restart" messages when e.g. bash had integration but the user was running fish. (#772)
- "Not found" error messages: Improved error message phrasing — "No branch named X" instead of "Branch X not found", "Branch X has no worktree" instead of "No worktree found for branch X". Context-appropriate hints now appear (e.g., wt remove no longer suggests --create). (#774)
Internal
- Unified PR/MR reference resolution, reducing code duplication. (#778)
Install worktrunk 0.18.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.18.1/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.18.1/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.18.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.18.0 | 21 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Post-remove hook: New hook type runs after worktree removal. Template variables ({{ branch }}, {{ worktree_path }}, {{ commit }}) reference the removed worktree, enabling cleanup scripts for containers, servers, or other resources. (#757)
- Graceful handling of missing worktree directories: wt remove now prunes stale git metadata when the worktree directory was deleted externally (e.g., rm -rf), making the command more idempotent. Fixes #724. (thanks @strangemonad for reporting)
- Config validation warnings at load time: Unknown fields in config files (typos like [commit-gen] instead of [commit-generation]) now show warnings immediately instead of only in wt config show. (#758)
Fixed
- Age column shows "future" on NixOS/direnv: wt list no longer uses SOURCE_DATE_EPOCH for time calculations, which NixOS and direnv commonly set to past timestamps for reproducible builds. Fixes #763. (thanks @ngotchac for reporting)
- CI status with URL-based pushremote: CI detection now works when branch.<name>.pushremote is set to a URL directly (as gh pr checkout does) instead of a remote name. (#769)
- GitLab nested groups in URL parsing: URLs like gitlab.com/group/subgroup/repo now correctly identify repo as the repository name instead of subgroup. This was a security fix — previously, approval bypass was possible across sibling repos in the same parent group. (#768)
- GitLab CI status detection: Fixed multiple issues with glab CLI compatibility — MR lookup now uses two-step resolution, "manual" pipelines show as running instead of failed, and rate limit errors are handled properly. Fixes #764. (thanks @ngotchac for reporting)
Internal
- Refactored accessor functions to use bare nouns per Rust convention. (#765)
- Clarified target/integration naming across codebase. (#755)
Install worktrunk 0.18.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.18.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.18.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.18.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.17.0 | 20 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Per-project config overrides (Experimental): Override settings per-project in user config. Supports worktree-path, commit-generation, list, commit, and merge sections. Config precedence: CLI arg > project config > global config > default. Closes #596. (#749)
- Search all remotes for branch existence: Branch existence checks and completions now search all remotes instead of just the primary remote, matching git's behavior. When a branch exists on multiple remotes, completions show all of them (e.g., feature ⇣ 2d origin, upstream). (#744)
- CI detection for fork workflows: CI status detection now searches all remotes and uses gh config get git_protocol / glab config get git_protocol for fork URL protocol preference instead of inferring from existing remotes. (#753)
Fixed
- Same-repo PR switching with stale refs: wt switch pr:N for same-repo PRs now fetches the branch before validation, fixing "Branch not found" errors when local refs were stale. (#742)
- Project identifier collision for repos without remotes: Repos without remotes now use their full canonical path as the project identifier instead of just the directory name, preventing approval collisions between unrelated repos (e.g., ~/work/myproject vs ~/personal/myproject). Users with remoteless repos will need to re-approve commands. (#747)
Internal
- Cross-platform path handling improvements using path-slash crate and Path::file_name(). (#750)
- Renamed WorktrunkConfig to UserConfig internally. (#746)
Install worktrunk 0.17.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.17.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.17.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.17.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.16.0 | 19 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Background hook verbosity: Background hooks (post-start, post-switch) now show a single-line summary by default instead of per-hook output. Use -v to see detailed output with expanded commands. We're open to feedback on this change — let us know in #690. (thanks @clutchski for reporting)
Internal
- Fixed dead Apple documentation link in copy-ignored rationale. (#743)
Install worktrunk 0.16.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.16.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.16.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.16.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.15.5 | 19 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- Hook execution order: Hooks now run in the order defined in the config file. Previously, HashMap iteration randomized the order. Fixes #737. (thanks @ngotchac for reporting)
Install worktrunk 0.15.5
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.15.5/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.15.5/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.15.5
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.15.4 | 19 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Git progress for slow worktree creation: When git worktree add takes more than 400ms (common on large repos), worktrunk now shows a progress message and streams git's output instead of going silent. (#725)
- Verbose template expansion output: -v now shows template expansion details: the template, expanded command, and any undefined variables with SemiStrict fallback behavior. (#712)
- Shell integration hint for explicit path invocation: When running wt via explicit path (e.g., ./target/debug/wt) with shell integration configured, the warning now suggests running wt switch <branch> to use the shell-wrapped command. (#721)
Fixed
- Unsafe upstream when creating branch from remote base: wt switch --create feature --base=origin/main no longer sets up tracking to origin/main, preventing accidental pushes to the base branch. Fixes #713. (thanks @kfirba)
- Credential redaction in debug logs: URLs with embedded credentials (e.g., https://token@github.com/...) are now redacted in -vv debug output. (#718)
- Hook preview shows template on expansion failure: wt hook show --expanded now displays both the error message and original template when expansion fails, instead of hiding the template. (#722)
Documentation
- Homebrew install uses core tap: Install command updated from max-sixty/worktrunk/wt to worktrunk. (#716, thanks @chenrui333)
- Hook docs reordered: post-start (background) is now the recommended default, with post-create for blocking dependencies. (#733)
Internal
- Simplified GitHub/GitLab CI status detection. (#730)
- Previous worktree gutter changed from - to + for visual consistency. (#699)
Install worktrunk 0.15.4
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.15.4/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.15.4/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.15.4
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.15.3 | 18 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- --execute command display: Shows the expanded command in a gutter with path context instead of showing the raw template before expansion. (#708)
- CRLF line endings in error display: Multiline errors with Windows (\r\n) or old Mac (\r) line endings now display correctly instead of falling through to single-line handling. (#707)
Documentation
- Arch Linux install via AUR: Added installation instructions and shell integration command. (#709, #561, thanks @razor-x)
Install worktrunk 0.15.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.15.3/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.15.3/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.15.3
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.15.2 | 18 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt config shell completions <shell>: Generate static shell completion scripts for package managers and custom installation. (#701, thanks @chenrui333)
- Debug logging threshold: Now requires -vv instead of -v for debug logging and diagnostic file generation, freeing -v for future use. (#702)
Fixed
- Fork PR fetching: wt switch pr:N now works when origin points to a fork by fetching PR refs from the upstream remote. Shows actionable error with git remote add command if upstream remote is missing. (#704)
- Fork PR branch naming: Fork PR branches now use the original branch name (e.g., feature-fix) instead of owner/feature-fix, so git push works correctly. (#706)
- Config race conditions: File locking prevents corruption when multiple wt processes modify config simultaneously. (#693)
- Nested worktree detection: Current worktree indicator (@) now shows on the correct worktree when worktrees are nested (e.g., .worktrees/ layout inside repo). (#697)
- Symlink path resolution: Worktree commands work correctly on systems with symlinks (e.g., macOS /var → /private/var). (#696)
- Pre-remove hook failures: Shell no longer cd's to main worktree when pre-remove hooks fail, leaving user in their current location. (#692)
- PowerShell completion robustness: Completion registration errors no longer break the shell wrapper function. (#674)
Documentation
- Added missing orphan (∅) symbol and no_worktree state to JSON output documentation. (#687)
- Clarified Unicode handling in shell detection. (#700)
Internal
- Refactored large files into focused modules. (#688)
- Consolidated integration reason computation into Repository method. (#689)
- Added verbose level tracking infrastructure for future -v output. (#703)
- PowerShell template uses WORKTRUNK_BIN for test isolation. (#674)
Install worktrunk 0.15.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.15.2/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.15.2/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.15.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.15.1 | 16 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt config show diagnostics: When shell integration is not active, now shows how the command was invoked, the binary path (if different), and $SHELL environment variable. Helps diagnose setup issues. (#683)
- Help pager follows git convention: -h never opens a pager, --help uses pager when available. Closes #583. (#651, thanks @razor-x)
- Verbose mode logging: -v now logs command stdout/stderr and all spawned processes including background hooks, wt for-each commands, and shell probes. (#680)
Documentation
- FAQ reordered: Questions now ordered by frequency and importance.
Internal
- AUR package: Worktrunk now published to Arch Linux AUR on each release. (#585, thanks @razor-x)
- Codecov Test Analytics: Integration tests now report to Codecov Test Analytics. (#682)
Install worktrunk 0.15.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.15.1/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.15.1/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.15.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.15.0 | 16 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt switch pr:<number> syntax (experimental): Switch directly to a GitHub PR by number. Same-repo PRs delegate to normal switch flow; fork PRs fetch from refs/pull/N/head and configure pushRemote. (#673, closes #657, thanks @wladpaiva for requesting)
- --force hint for dirty worktrees: When wt remove fails due to uncommitted changes, the hint now shows the full command: wt remove <branch> --force. (#671)
Documentation
- Windows install guidance: Winget as recommended install (ships git-wt by default), plus the App Execution Aliases workaround to use wt directly. Closes #133. (thanks @ctolkien for reporting, @shanselman for the aliases tip, @Farley-Chen for #648)
- Caddy subdomain routing pattern: Clean URLs like feature-auth.myproject.lvh.me via Caddy reverse proxy with dynamic route registration.
- tmux session per worktree pattern: Dedicated tmux session with multi-pane layout per worktree.
Install worktrunk 0.15.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.15.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.15.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.15.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.14.2 | 15 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- wt remove --force works with dirty worktrees: The --force flag was documented to allow removal with uncommitted changes, but worktrunk's own cleanliness check blocked it before git could apply the flag. Fixes #658. (thanks @pedro93)
- Correct output when switching to existing local branch: When switching to a local branch that tracks a remote, worktrunk incorrectly reported "Created branch X" instead of "Created worktree for X". Now only reports branch creation when git's DWIM actually creates a new tracking branch from a remote. Fixes #656. (thanks @guidupuy-ws)
- PowerShell handles multiple wt.exe binaries: On Windows, when both Windows Terminal's wt.exe and worktrunk's wt.exe exist in PATH, shell integration errored with "Cannot convert 'System.Object[]' to the type 'System.String'". Now correctly uses the first match. Relates to #648. (thanks @Farley-Chen)
Install worktrunk 0.14.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.14.2/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.14.2/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.14.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.14.1 | 15 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- --base accepts commit-ish refs: wt switch --create --base now accepts HEAD, tags, commit SHAs, and relative refs (e.g., HEAD~2), not just branch names. Fixes #630. (thanks @myhau)
- Upfront validation for target refs: wt merge and wt step commands now validate target refs before approval prompts, giving clearer "Branch X not found" errors immediately.
- Visual hierarchy in help: Section dividers, improved heading structure, and sentence case in --help output.
Fixed
- macOS shell freeze during copy-ignored: Atomic clonefile() on directories saturated disk I/O, blocking shell startup. Now uses per-file reflink which is slower but keeps the system responsive.
- copy-ignored no longer copies nested worktrees: When worktree-path places worktrees inside the main worktree, copy-ignored now skips them. Also now copies symlinks (fixes node_modules/.bin/ etc.). Fixes #641. (thanks @razor-x)
- Context-aware hints for wt config create: Hints now suggest relevant next steps based on which configs exist.
Install worktrunk 0.14.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.14.1/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.14.1/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.14.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.14.0 | 14 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- worktree_path_of_branch(branch) template function: Look up the filesystem path of any branch's worktree in hooks. Enables copying files between worktrees: setup = "cp {{ worktree_path_of_branch('main') }}/config.local {{ worktree_path }}". Returns empty string if no worktree exists for the branch.
- Per-task timeout for wt list: Configure timeout for git operations via [list] timeout-ms in user config. Shows timeout count in footer. Use --full to disable timeout for complete data collection.
- Atomic COW directory cloning on macOS: wt step copy-ignored uses clonefile() syscall on APFS for O(1) directory cloning instead of file-by-file copying. ~12-15x faster for large directories like target/.
- Template variable renamed: main_worktree_path → primary_worktree_path for clarity. Old name still works with deprecation warning.
Fixed
- wt step copy-ignored in bare repositories: Fixed "this operation must be run in a work tree" error when using bare repo setups. Closes #598. (thanks @sbennett33 for reporting)
Internal
- Help system extraction: Moved help and invocation utilities from main.rs to dedicated modules.
- wt list model refactor: Split monolithic model.rs into modular directory structure.
Install worktrunk 0.14.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.14.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.14.0/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.14.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.13.4 | 13 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- LESS flag concatenation with long options: Fixed "invalid option" error when users have long options in LESS (e.g., LESS=--mouse). The pager auto-quit feature from v0.13.1 now correctly separates flags. Fixes #594. (thanks @tnlanh for reporting)
Internal
- Homebrew formula generation: Release workflow now uses cargo-dist for Homebrew formula generation, simplifying the release process.
Install worktrunk 0.13.4
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.13.4/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.13.4/worktrunk-installer.ps1 | iex"
Install prebuilt binaries via Homebrew
brew install max-sixty/worktrunk/wt
Download worktrunk 0.13.4
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.13.2 | 13 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Validate before approval prompts: wt switch and wt remove now validate operations before prompting for hook approval, so users don't approve hooks for operations that will fail.
Fixed
- Homebrew formula SHA256 hashes: Fixed release workflow that was setting incorrect checksums for Intel and Linux binaries, causing brew install to fail. Fixes #589. (thanks @kobrigo for reporting)
Install worktrunk 0.13.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.13.2/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.13.2/worktrunk-installer.ps1 | iex"
Download worktrunk 0.13.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.13.1 | 13 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- Pager auto-quit: Help text now auto-quits when it fits on screen, even when LESS is set without the F flag (common with oh-my-zsh's LESS=-R default). Fixes #583. (thanks @razor-x for reporting)
- --create hint for remote branch shadowing: Improved recovery hint when --create shadows a remote branch — now shows the full recovery command.
Install worktrunk 0.13.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.13.1/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.13.1/worktrunk-installer.ps1 | iex"
Download worktrunk 0.13.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.13.0 | 13 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt list parallelization: Parallel worktree operations reduce latency significantly. Respects RAYON_NUM_THREADS environment variable for controlling parallelism.
- Template variables in --execute: Hook template variables ({{ branch }}, {{ worktree_path }}, etc.) are now expanded in --execute commands and trailing args. With --create, {{ base }} and {{ base_worktree_path }} are also available.
- Fish shell Homebrew compatibility: Fish shell integration now installs to ~/.config/fish/functions/wt.fish instead of conf.d/, ensuring PATH is fully configured before the wt function loads. wt config show detects legacy installations and wt config shell install handles migration automatically.
- Chrome Trace Format export: Performance traces can be exported for analysis with Chrome's trace viewer or Perfetto.
- --dry-run flag for shell commands: wt config shell install and wt config shell uninstall now support --dry-run to preview changes without prompting.
- Nested subcommand suggestions: When typing wt squash instead of wt step squash, the error now suggests the correct command path.
- Orphan branch indicator: wt list shows ∅ (empty set) for orphan branches with no common ancestor to the default branch.
- Improved -vv diagnostic workflow: Bug reporting hint now uses a gist workflow to avoid URL length limits.
Fixed
- wt switch --create --base error message: Now correctly identifies the invalid base branch instead of the target branch. Fixes #562. (thanks @fablefactor)
- AheadBehind column loading indicator: Shows ⋯ when not yet loaded instead of appearing empty, distinguishing loading state from "in sync".
- Post-merge hook failure output: Simplified error messages and removed confusing --no-verify hint.
- wt select log preview: Graph structure is now preserved when displaying commit history, and columns dynamically align.
Documentation
- FAQ entry for shell setup issues: Added troubleshooting guidance for common shell integration problems.
- Template variables reference: Consolidated template variables documentation into hook.md.
- Clarified --force vs -D flags: Updated wt remove documentation. (thanks @hlee-cb)
- Performance benchmarks: Added documentation for copy-ignored performance.
Install worktrunk 0.13.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.13.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.13.0/worktrunk-installer.ps1 | iex"
Download worktrunk 0.13.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.12.0 | 12 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt select --branches and --remotes flags: Control which items appear in the selection UI. Shares the [list] config section with wt list for consistent defaults.
- Graceful degradation when default branch unavailable: When the default branch cannot be determined (e.g., misconfigured), wt list shows warnings and empty cells rather than failing. wt switch --create without --base gives a clear error message.
- Remove --refresh flag from state commands: wt config state default-branch get and wt config state ci-status get now purely read cached state. To force re-detection, use the explicit workflow: clear then get. (Breaking: --refresh flag removed)
- Windows: Require Git for Windows: Removed PowerShell fallback. Worktrunk now requires Git for Windows (Git Bash) and shows a clear error message pointing to the download page if not found. (Breaking: PowerShell no longer supported)
Fixed
- Flag styling in messages: Flags like --clobber and --no-verify in parentheses now inherit message color instead of using bright-black styling.
- Nix flake: Remove apple_sdk framework dependency. (#525, thanks @MattiasMTS)
- gh issue create hint: Now includes --web flag to open the issue form in browser.
Internal
- Binary size reduced ~1MB: Trimmed unused config/minijinja features (13MB → 12MB).
- Repository module split: Split 2200-line module into 8 focused submodules for maintainability.
Install worktrunk 0.12.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.12.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.12.0/worktrunk-installer.ps1 | iex"
Download worktrunk 0.12.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.11.0 | 10 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Nix flake for packaging: New flake.nix for Nix users with crane for efficient Rust builds. (#502, thanks @marktoda)
- sanitize_db template filter: New filter that transforms strings into database-safe identifiers with a 3-character hash suffix for collision/keyword safety.
- wt select performance: 500ms timeout for git commands improves TUI responsiveness on large repos with many branches.
- wt select stale branch handling: Branches 50+ commits behind the default branch now skip expensive operations, showing ... in the diff column. Improves performance on repos with many stale branches.
- Global merge-base cache: Cached merge-base results improve wt list performance by avoiding redundant git calls.
- wt config show git version: Now displays the git version alongside the worktrunk version.
- wt step copy-ignored default: Now copies all gitignored files by default. Use .worktreeinclude to limit what gets copied (previously required .worktreeinclude to specify what to copy).
- Trace log analysis: New analyze-trace binary for analyzing [wt-trace] performance logs.
Fixed
- Statusline truncation: No longer truncates when terminal width is unknown, fixing Claude Code statusline display.
- Shell completions: Deprecated args like --no-background no longer appear in tab completions.
- wt remove progress ordering: Progress message now appears after pre-remove hooks, not before.
- wt list index lock: Uses --no-optional-locks for git status to avoid lock contention with parallel tasks.
Install worktrunk 0.11.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.11.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.11.0/worktrunk-installer.ps1 | iex"
Download worktrunk 0.11.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.10.0 | 8 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- wt step copy-ignored: Copy gitignored files listed in .worktreeinclude between worktrees. Useful for syncing .env files, IDE settings, and build caches to new worktrees via post-create hooks. Uses COW (reflink) copying for efficient handling of large directories. Matches Claude Code Desktop's worktree file syncing behavior.
- --foreground flag: Debug background hooks by running them in the foreground. Available on wt hook post-start, wt hook post-switch, and wt remove. Replaces the deprecated --no-background flag.
- --var flag for hooks: Override template variables when running hooks manually, e.g., wt hook post-create --var target=main.
- [ci] platform config: Explicitly set CI platform (github or gitlab) for GitHub Enterprise or self-hosted GitLab where URL-based detection fails.
- Upstream diff in wt select: Tab 4 shows ahead/behind diff vs upstream tracking branch (remote⇅), matching the column in wt list.
- {{ base }} and {{ base_worktree_path }} variables: New template variables for creation hooks (post-create, post-start, post-switch) to access the base branch name and worktree path.
- -vv diagnostic reports: Double-verbose flag writes a diagnostic report to .git/wt-logs/diagnostic.md with environment info, configs, and logs for easy bug reporting.
Fixed
- Warning ordering: Warnings about state discovered during evaluation now appear before the action message, making them feel like considered observations rather than afterthoughts.
- Config validation in wt config show: Now validates TOML syntax and schema, displaying parse errors with details.
Documentation
- Undocumented features: Added documentation for --show-prompt and --stage flags on wt step commit/squash, skip-shell-integration-prompt config, and [select] pager config.
Install worktrunk 0.10.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.10.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.10.0/worktrunk-installer.ps1 | iex"
Download worktrunk 0.10.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.9.5 | 7 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Pager config for wt select: New [select] pager config option to customize the diff pager in wt select previews. Auto-detects delta/bat when not configured.
- Infinity symbol for extreme diffs: wt list shows ∞ instead of 9K for diffs >= 10,000 commits, avoiding misleading values.
Fixed
- Windows shell integration message: Warning now shows just the command name instead of the full absolute path, and gives targeted advice when only the .exe suffix differs.
- URL column width: Column width in wt list now accounts for hyperlink display showing just :PORT instead of full URLs.
Internal
- Deprecated template-file and squash-template-file: Legacy LLM template config options now show deprecation warnings.
- Path handling improvements: Replaced string manipulation with proper Path/PathBuf stdlib methods throughout the codebase.
Install worktrunk 0.9.5
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.9.5/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.9.5/worktrunk-installer.ps1 | iex"
Download worktrunk 0.9.5
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.9.4 | 6 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Diagnostic report generation: wt list --verbose generates diagnostic reports (.git/wt-logs/diagnostic.md) when warnings or errors occur, with a gh issue create command hint when GitHub CLI is available.
- Alias bypass detection: wt config show detects shell aliases that point to binary paths (e.g., alias gwt="/usr/bin/wt") and warns that they bypass shell integration with suggested fixes.
- Switch message clarity: Messages now explicitly state what was created — "Created branch X and worktree" vs "Created worktree for X" vs "Switched to worktree for X".
- Worktree-path hint: One-time hint after first wt switch --create suggesting wt config create to customize worktree locations.
- Path mismatch warnings: wt remove and wt merge show warnings when worktree paths don't match the config template.
- CLI command ordering: Commands reordered by usage frequency in --help (switch, list, remove, merge...).
Fixed
- Progress counter overflow: Fixed wt list progressive rendering when URL sends caused completed count to exceed expected count.
- Windows shell integration: Shell function now correctly strips .exe suffix, relying on MSYS2/Git Bash automatic resolution (fixes #348).
- Prunable worktrees: Gracefully handle worktrees where the directory was deleted but git still tracks metadata.
- Help text tables: Disabled clap text wrapping to preserve markdown tables in --help output.
Documentation
- FAQ entries: Added entries for "What files does Worktrunk create?" and "What can Worktrunk delete?".
Internal
- Hint state management: New wt config state hints subcommand for viewing and clearing shown hints.
- Deprecated config deduplication: Migration files (.new) only written once per repo, tracked via git config hints.
Install worktrunk 0.9.4
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.9.4/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.9.4/worktrunk-installer.ps1 | iex"
Download worktrunk 0.9.4
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.9.3 | 5 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Terminal hyperlinks for URLs: The URL column in wt list now shows clickable links (OSC 8) in supported terminals, displaying a compact :port that links to the full URL.
- Statusline truncation: Statusline output now intelligently truncates by dropping low-priority segments (URL, CI) before high-priority ones (branch, model) when exceeding terminal width.
- Statusline URL: When a project has a [list] url template configured, the URL now appears in statusline output for shell prompts.
- Bare repo default branch detection: Uses symbolic-ref HEAD as a heuristic for detecting the default branch in bare repos and empty repos before the first commit.
- Terminology: Renamed "path mismatch" to "branch-worktree mismatch" for clarity. In JSON output (wt list --format=json), the field path_mismatch is now branch_worktree_mismatch.
Fixed
- Empty bare repo bootstrap: wt switch --create main now works in empty bare repos by handling unborn branches correctly.
Documentation
- CLI help text: Improved descriptions across multiple commands including wt, wt list, wt select, wt step, wt merge, wt remove, and wt hook.
- Web docs copy button: Fixed copy button position so it stays at top-right when scrolling horizontally through code blocks.
Internal
- Claude Code plugin detection: wt config show now displays whether the worktrunk Claude Code plugin is installed, with install hints if needed.
- Hyperlink diagnostics: wt config show shows hyperlink support status (active/inactive).
Install worktrunk 0.9.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.9.3/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.9.3/worktrunk-installer.ps1 | iex"
Download worktrunk 0.9.3
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.9.2 | 4 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Fixed
- Locked worktree detection: wt remove now detects locked worktrees upfront and shows a clear error with unlock instructions, instead of reporting success but silently failing. (#408, #412)
- Windows Git Bash shell integration: Shell detection now handles Windows-style paths in $SHELL (e.g., C:\Program Files\Git\usr\bin\bash.exe). Fixes #348. (#398)
Documentation
- CLI help text clarity: Improved descriptions for wt, wt list, wt step push, wt step squash, wt remove, and wt config state. (#410)
- Installation commands: Removed $ prefixes from install commands for easier copy-paste. (#405, thanks @muzzlol)
Internal
- Home worktree lookup: Centralized with find_home() and home_path() methods for more consistent behavior with bare repos.
- Windows CI: Added cross-platform mock infrastructure for testing Windows-specific behavior.
Install worktrunk 0.9.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.9.2/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.9.2/worktrunk-installer.ps1 | iex"
Download worktrunk 0.9.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.9.1 | 3 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Shell integration debug info: wt config show now displays invocation details (path, git subcommand mode, explicit path usage) to help diagnose shell integration issues. "Shell integration not active" is now a warning instead of a hint.
Install worktrunk 0.9.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.9.1/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.9.1/worktrunk-installer.ps1 | iex"
Download worktrunk 0.9.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.9.0 | 3 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Shell integration prompt: When shell integration isn't active after wt switch, an interactive prompt offers to install it. The prompt remembers your choice and falls back to a hint for non-TTY environments.
- Template variable names: Renamed for clarity: repo_root → repo_path, worktree → worktree_path, main_worktree → repo. Added main_worktree_path for accessing the main worktree's absolute path. Deprecated names work with migration warnings and auto-generated .new config files.
- Shell integration warnings: Specific diagnostic messages when shell cd won't work: "shell integration not installed", "shell requires restart", "ran ./wt; shell integration wraps wt", or "ran git wt; running through git prevents cd".
- RUNTIME section in wt config show: Displays binary name, version, and shell integration status to help debug invocation issues.
- Clickable CI indicator: The CI status indicator (●) in wt list output is now a clickable link to the PR in terminals that support OSC 8 hyperlinks.
- wt switch help text: Clarifies the difference from git switch and documents common failure conditions.
Fixed
- Hook path display: Hook announcements show the execution path when shell integration isn't active.
- Approval matching with deprecated vars: Approvals now match regardless of whether they were saved with deprecated or current variable names.
- Documentation filter syntax: Fixed incorrect Jinja filter examples that showed ~ concatenation with | filter without parentheses. (#373, thanks @coriocactus)
Documentation
- Pre-remove hook example: Added pattern for cleaning up background processes (e.g., killing dev servers) when worktrees are removed.
Install worktrunk 0.9.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.9.0/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.9.0/worktrunk-installer.ps1 | iex"
Download worktrunk 0.9.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.8.5 | 2 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Windows git-wt command: Winget now ships with git-wt as a workaround to the Windows Terminal wt naming conflict. We're still considering better options — see #133.
Install worktrunk 0.8.5
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.8.5/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.8.5/worktrunk-installer.ps1 | iex"
Download worktrunk 0.8.5
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.8.4 | 2 มกราคม 2569 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Shell integration detection: More robust detection of git wt (space) vs git-wt patterns. wt config show now displays line numbers for detected shell integration.
- Windows wt select error: Shows a helpful error message with alternatives instead of "unrecognized subcommand".
Fixed
- Markdown table rendering: Escaped pipe characters (\|) in help output now render correctly.
- Dim styling on wrapped lines: Dim text attribute now preserved on continuation lines when text wraps.
- Path occupied hint: Fixed tilde expansion issue where ~/... paths didn't work in shell commands.
Documentation
- Hook design guide: Added comprehensive guide for designing hooks.
- Command docs: Added wt config show to command documentation.
- Windows paths: Documented MSYS2 auto path conversion for Windows shell integration.
Internal
- Output system: Consolidated output functions, removed redundant aliases.
- Zsh compinit: Improved handling of "insecure directories" warning in tests.
Install worktrunk 0.8.4
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.8.4/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.8.4/worktrunk-installer.ps1 | iex"
Download worktrunk 0.8.4
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.8.3 | 31 ธันวาคม 2568 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Hook execution path: Shows the execution path when post-merge hooks run in a different directory than where the user invoked the command (e.g., with --no-remove).
- TTY check for wt select: Now fails gracefully when run in a non-interactive terminal instead of hanging.
- Background hooks: post-start and post-switch hooks spawn in background via stdin piping, matching their normal behavior during wt switch.
- Occupied path error message: When a worktree path is occupied by a different branch, the error now explains the situation clearly and suggests git switch.
- Shell integration hint: Shows a hint to restart the shell when shell integration is configured but not active.
- Message style: Removed 2nd person pronouns ("you/your") from user-facing messages following CLI guidelines.
Fixed
- wt hook post-start blocking: Fixed bug where wt hook post-start ran in foreground blocking the command, instead of spawning in background like during normal wt switch --create.
- Approval bypass with project: prefix: Fixed security issue where using project: filter prefix (e.g., wt hook pre-merge project:) bypassed the approval check, allowing unapproved project commands to run.
Documentation
- License file: Added combined MIT and Apache-2.0 license file.
- Demo GIFs: Added demo GIFs to command pages on the documentation site.
- Install instructions: Simplified to single-line commands.
Internal
- Pre-commit hooks: Updated to immutable tags.
- Lychee exclusions: Cleaned up link checker configuration.
Install worktrunk 0.8.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.8.3/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.8.3/worktrunk-installer.ps1 | iex"
Download worktrunk 0.8.3
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.8.1 | 31 ธันวาคม 2568 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Shell and PowerShell installers: Added one-line install commands for Linux/macOS and Windows.
- Consistent terminology: CLI now uses "branch name" consistently instead of mixing "worktree" and "branch". The wt remove argument is renamed from worktrees to branches to reflect that worktrees are addressed by branch name.
Fixed
- Switch hints: Removed incorrect wt switch @ hint and improved error output spacing.
Documentation
- Dev server and database patterns: Added practical examples for running per-worktree dev servers with subdomain routing and databases with unique ports.
Install worktrunk 0.8.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.8.1/worktrunk-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.8.1/worktrunk-installer.ps1 | iex"
Download worktrunk 0.8.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.7.0 | 26 ธันวาคม 2568 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Working tree conflict detection: wt list --full now detects conflicts using uncommitted working tree changes, not just committed content. This catches conflicts earlier—before committing changes that would conflict with the target branch.
- Dev server URL column: New optional URL column in wt list configured via [list] url template in project config (.config/wt.toml). URLs show with health-check styling: normal if the port is listening, dimmed otherwise.
- Shell integration simplification: The shell wrapper is now self-contained with all directive handling inlined. Removes the separate helper function that could become unavailable if shell initialization order changed.
- Performance: Repository caching reduces git subprocess spawns; parallelized pre-skeleton operations for faster initial display.
- Improved error hints: When a worktree path already exists during creation, the error hint now correctly suggests --create --clobber.
Fixed
- Docs syntax highlighting: Fixed syntax highlighting colors being stripped by 1Password browser extension on the documentation site.
Download worktrunk 0.7.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.6.1 | 24 ธันวาคม 2568 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- post-switch hook: New hook that runs in the background after every wt switch operation. Unlike post-start (which only runs on creation), post-switch runs on all switch results. Use cases include renaming terminal tabs, updating tmux window names, and IDE notifications.
- Signal forwarding for hooks: Hooks now receive SIGINT/SIGTERM when the parent process is interrupted, allowing proper cleanup. Previously, non-interactive shells continued executing after signals.
- Faster wt list skeleton: Time-to-skeleton reduced by caching default branch lookup, batching timestamp fetching, and deferring non-essential git operations. Skeleton shows · placeholder for gutter symbols until data loads.
- Clearer --clobber hint: Error message now says "to overwrite (with backup)" instead of "to retry with backup".
Documentation
- State side-effects: Added section explaining how Worktrunk state operations may trigger git commands.
- wt merge location: Clarified that wt merge runs from the feature worktree.
Download worktrunk 0.6.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.6.0 | 21 ธันวาคม 2568 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Single-width Unicode symbols: Replaced emojis (🔄, ✅, ❌) with single-width Unicode symbols (◎, ✓, ✗, ▲, ↳, ○, ❯) for better terminal compatibility and consistent alignment.
- Output system overhaul: Clean separation of output channels (data→stdout, status→stderr, directives→file) means piping works with shell integration active. wt list --format=json | jq and wt switch feature | tee log.txt both work correctly. Background processes use process_group(0) instead of nohup for more reliable detachment.
- Trailing arguments for --execute: wt switch --execute now accepts arguments after --, enabling shell aliases like alias wsc='wt switch --create -x claude' then wsc feature -- 'implement login'.
- hash_port template filter: {{ branch | hash_port }} hashes the branch name to a deterministic port number (10000-19999), useful for running dev servers without port conflicts.
- sanitize template filter: {{ branch | sanitize }} explicitly replaces / and \ with - for filesystem-safe paths. (Breaking: {{ branch }} now provides raw branch names. Update templates that use {{ branch }} in filesystem paths to use {{ branch | sanitize }} instead)
- Log directory in state output: wt config state logs and wt config state get now show the log directory path under a LOG FILES heading.
- Actionable error hints: Error messages now include hints about what command to run next.
- Unified directory change output: wt remove now shows "Switched to worktree for {branch} @ {path}" matching wt switch format.
- Consistent "already up to date" formatting: Standardized message wording and styling across commands.
Fixed
- wt step rebase with merge commits: Fixed incorrect "Already up-to-date" when a branch has merge commits from merging target into itself.
Documentation
- Local CI workflow: Added "Local CI" section to wt merge --help explaining how pre-merge hooks enable faster iteration.
- Colored command reference: Web docs now preserve ANSI colors in command reference output.
- Clarified terminology: Help text uses "default branch" instead of hardcoded "main".
Download worktrunk 0.6.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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.5.2 | 19 ธันวาคม 2568 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- --clobber flag for wt switch: When encountering a stale directory or file at the target worktree path, --clobber moves it to a timestamped .bak file instead of failing.
- Relative paths in wt list: Paths are now shown relative to the main worktree (., ./subdir, ../repo.feature) instead of a computed common prefix that could degenerate to /.
- Multiline error formatting: Errors with context now show a header describing what worktrunk was trying to do, with the full error chain in a gutter block.
- Semantic switch messaging: Switching to an existing worktree now shows ⚪ (info) instead of ✅ (success), reflecting that nothing was created.
Fixed
- Symbol styling in removal messages: Integration symbols (_, ⊂) now render in their canonical dim appearance instead of inheriting the message's cyan color.
- ConflictingChanges error formatting: Fixed double newlines in the error message output.
Download worktrunk 0.5.2
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| v0.5.1 | 17 ธันวาคม 2568 | — | 64 บิต ZIP บันทึกประจำรุ่นRelease Notes
Improved
- Integration status in removal messages: Shows integration symbols (_ for same commit, ⊂ for integrated) when removing worktrees, matching wt list display.
- Concurrent command limiting: Limits concurrent git processes to 32 (configurable via WORKTRUNK_MAX_CONCURRENT_COMMANDS), preventing resource exhaustion on repos with many branches.
- Better error display for wt list: Task errors are now collected and displayed as warnings after the table renders, instead of being silently swallowed.
- Remove continues on partial failures: wt remove continues removing other worktrees when some fail, reporting all errors at the end.
- Bash syntax highlighting: Shell commands in error gutters now have syntax highlighting.
- Shell integration is command-aware: Detection and removal works correctly when installed as git-wt or other names.
- CI fetch error documentation: Yellow warning symbol (⚠) in CI column is now documented in help text.
Fixed
- CI status with multiple workflows: Fixed incorrect status when multiple workflows exist (e.g., ci and publish-docs). Now uses GitHub's check-runs API to aggregate all workflow statuses.
- State storage unification: Unified branch-keyed state under worktrunk.state.<branch>.*. Numeric branch names now work. (Existing CI cache and markers regenerate on first access)
Internal
- Environment variable prefix: Standardized to WORKTRUNK_ prefix (e.g., WORKTRUNK_MAX_CONCURRENT_COMMANDS).
- Automatic winget package publishing on releases.
Download worktrunk 0.5.1
────────────────────────────────────────────────┬───────────────────┬─────────────
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
────────────────────────────────────────────────┴───────────────────┴───────────── |
| 0.5.0 | 16 ธันวาคม 2568 | — | 64 บิต ZIP |