v0.36.0

max-sixty/worktrunkv0.36.0Apr 11, 2026by github-actions[bot]

Upgrading?

Release notes summary

This release introduces Git-style external subcommands, typed environment variable config overrides, and restructures hook output log files into a nested layout.

Key Highlights

  • Git-style external subcommands allow third-party tools to be invoked as `wt <name>` without modifying the repo.
  • Typed env-var config overrides now work correctly, preventing silent failures that wiped user config.
  • Hook output log layout changed from flat files to nested `{branch}/{source}/{hook-type}/{name}.log`.
  • Config error attribution now identifies the source of errors with TOML line/column pointers.

Breaking Changes

  • Hook output log layout changed from flat to nested structure.

New Features

  • Git-style external subcommands
  • Typed env-var config overrides
  • Stale trash cleanup in `wt remove`

Full Release Notes

## 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](https://worktrunk.dev/tips-patterns/#external-subcommands) ([#2054](https://github.com/max-sixty/worktrunk/pull/2054), thanks @pablospe for the suggestion in [#2053](https://github.com/max-sixty/worktrunk/issues/2053))

- **`{{ owner }}` template variable**: Expands to the GitHub/GitLab repository owner, useful for constructing URLs or paths in hook templates and `worktree-path`. ([#2051](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/issues/1306). ([#2066](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/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](https://github.com/max-sixty/worktrunk/pull/2064))

### Documentation

- Surfaced vars & aliases on homepage and tips-patterns, cross-linked state keys to dedicated docs, tightened hook links. ([#2035](https://github.com/max-sixty/worktrunk/pull/2035), [#2036](https://github.com/max-sixty/worktrunk/pull/2036), [#2037](https://github.com/max-sixty/worktrunk/pull/2037), [#2038](https://github.com/max-sixty/worktrunk/pull/2038))

### Internal

- Subcommand ordering aligned to documented policies (pipeline order for step, CRUD for state actions). ([#2043](https://github.com/max-sixty/worktrunk/pull/2043), [#2044](https://github.com/max-sixty/worktrunk/pull/2044))

## Install worktrunk 0.36.0

### Install prebuilt binaries via shell script

```sh
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

```sh
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

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

## Download worktrunk 0.36.0

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