v0.34.0

max-sixty/worktrunkv0.34.0Apr 3, 2026by github-actions[bot]

Upgrading?

Release notes summary

This release introduces per-branch custom variables, lazy template expansion in pipelines, and a new `[forge]` configuration section. It also adds Claude Code integration commands and renames several config fields to use positive-sense naming while maintaining backward compatibility.

Key Highlights

  • Per-branch custom variables stored in git config via `wt config state vars`
  • Lazy template expansion in pipelines allows variables set by step N to be used in step N+1
  • New `[forge]` section replaces `[ci]` with automatic migration support
  • Claude Code integration commands for plugin management and statusline configuration
  • Config field renames: `merge.no-ff` → `merge.ff` and `switch.no-cd` → `switch.cd`

New Features

  • Custom key-value pairs per branch accessible in templates
  • Lazy variable expansion runtime behavior
  • Claude Code plugin management CLI commands
  • Explicit forge configuration section
  • Commit to specific branch without switching with `wt step commit --branch`

Full Release Notes

## 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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/1830), [#1834](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/1771), thanks @amodelaweb; thanks @roytouw for reporting [#1790](https://github.com/max-sixty/worktrunk/issues/1790))

- **`--branch` flag for `wt step commit`**: Commit to a specific branch without switching to it — useful in automation and scripts. ([#1750](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/1856), [#1860](https://github.com/max-sixty/worktrunk/pull/1860))

- **Syntax highlighting for template blocks**: Documentation site now renders `{{ }}` template expressions with syntax highlighting. ([#1792](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/issues/1865). ([#1864](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/issues/1818). ([#1820](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/1858))

- **Fish shell getcwd error in Zellij**: Removing a worktree while using fish in Zellij produced "error retrieving current directory" messages. ([#1787](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/issues/1772). ([#1773](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/1855))

- **GitLab MR remote tracking**: `wt switch mr:N` could reuse branches tracking the correct merge-request ref but on the wrong remote. ([#1817](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/1812))

- **Placeholder directory on non-current worktree removal**: `wt remove` created unnecessary empty placeholder directories and slept for 1 second when removing worktrees other than the current one. ([#1868](https://github.com/max-sixty/worktrunk/pull/1868), [#1874](https://github.com/max-sixty/worktrunk/pull/1874))

- **Merge-tree errors silently swallowed**: `git merge-tree` failures (invalid refs, corrupt repos) were treated as conflicts instead of propagating, triggering expensive patch-id fallback unnecessarily. ([#1896](https://github.com/max-sixty/worktrunk/pull/1896))

- **Deprecated key in wrong config file**: A deprecated section key (e.g., `[commit-generation]`) in the wrong config file (e.g., project config) was silently filtered. Now warns "Key X belongs in Y config as Z". ([#1899](https://github.com/max-sixty/worktrunk/pull/1899))

- **Config migration mutex panic**: Replaced unsafe `unwrap()` with error propagation in config deprecation migration. ([#1887](https://github.com/max-sixty/worktrunk/pull/1887))

- **Hook show outside git repo**: `wt hook show` now provides a clear error message when run outside a git repository. ([#1809](https://github.com/max-sixty/worktrunk/pull/1809), thanks @noirbizarre)

### Documentation

- Help text rewritten for `switch`, `merge`, `hook`, and `remove` commands. ([#1782](https://github.com/max-sixty/worktrunk/pull/1782), [#1783](https://github.com/max-sixty/worktrunk/pull/1783), [#1785](https://github.com/max-sixty/worktrunk/pull/1785), [#1765](https://github.com/max-sixty/worktrunk/pull/1765), [#1764](https://github.com/max-sixty/worktrunk/pull/1764))

- Hook documentation restructured: types reordered by paired events, pipeline ordering rewritten with progressive examples, approval prompt shown in color. ([#1763](https://github.com/max-sixty/worktrunk/pull/1763), [#1756](https://github.com/max-sixty/worktrunk/pull/1756), [#1766](https://github.com/max-sixty/worktrunk/pull/1766))

- Hooks documented in user config reference. ([#1845](https://github.com/max-sixty/worktrunk/pull/1845))

- Deprecated `post-create` removed from documentation. ([#1776](https://github.com/max-sixty/worktrunk/pull/1776))

- Arch Linux official package added to installation instructions. ([#1872](https://github.com/max-sixty/worktrunk/pull/1872), thanks @ctrl-q)

- README template syntax fixed. Fixes [#1851](https://github.com/max-sixty/worktrunk/issues/1851). ([#1852](https://github.com/max-sixty/worktrunk/pull/1852), thanks @IlyaSemenov for reporting)

### Internal

- Config deprecation consolidated from two layers to one pre-deserialization TOML migration. ([#1879](https://github.com/max-sixty/worktrunk/pull/1879), [#1880](https://github.com/max-sixty/worktrunk/pull/1880), [#1876](https://github.com/max-sixty/worktrunk/pull/1876))

- Benchmark infrastructure extracted into `wt-perf` crate. ([#1878](https://github.com/max-sixty/worktrunk/pull/1878))

- `wt remove` approval path reuses already-loaded repo/config (~50ms savings). ([#1875](https://github.com/max-sixty/worktrunk/pull/1875))

### Deprecated

| Old | New | Action |
|-----|-----|--------|
| `[ci]` section | `[forge]` section | `wt config update` migrates; `wt config show` warns |
| `no-ff` in `[merge]` | `ff` (reversed) | `wt config update` migrates; `wt config show` warns |
| `no-cd` in `[switch]` | `cd` (reversed) | `wt config update` migrates; `wt config show` warns |

All deprecated fields continue to work. Run `wt config update` to migrate, or `wt config show` for details.

## Install worktrunk 0.34.0

### Install prebuilt binaries via shell script

```sh
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-installer.sh | sh && wt config shell install
```

### Install prebuilt binaries via powershell script

```sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
```

### Install prebuilt binaries via Homebrew

```sh
brew install worktrunk && wt config shell install
```

## Download worktrunk 0.34.0

|  File  | Platform | Checksum |
|--------|----------|----------|
| [worktrunk-aarch64-apple-darwin.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-aarch64-apple-darwin.tar.xz) | Apple Silicon macOS | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-aarch64-apple-darwin.tar.xz.sha256) |
| [worktrunk-x86_64-apple-darwin.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-x86_64-apple-darwin.tar.xz) | Intel macOS | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-x86_64-apple-darwin.tar.xz.sha256) |
| [worktrunk-x86_64-pc-windows-msvc.zip](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-x86_64-pc-windows-msvc.zip) | x64 Windows | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-x86_64-pc-windows-msvc.zip.sha256) |
| [worktrunk-aarch64-unknown-linux-musl.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-aarch64-unknown-linux-musl.tar.xz) | ARM64 MUSL Linux | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-aarch64-unknown-linux-musl.tar.xz.sha256) |
| [worktrunk-x86_64-unknown-linux-musl.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-x86_64-unknown-linux-musl.tar.xz) | x64 MUSL Linux | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.34.0/worktrunk-x86_64-unknown-linux-musl.tar.xz.sha256) |



### Install via Cargo

```sh
cargo install worktrunk && wt config shell install
```

### Install via Winget (Windows)

```sh
winget install max-sixty.worktrunk && git-wt config shell install
```

### Install via AUR (Arch Linux)

```sh
paru worktrunk-bin && wt config shell install
```

Related Repositories