worktrunk 0.1.12

A Git worktree manager for trunk-based development
Documentation

Worktrunk

Crates.io License: MIT GitHub CI Status

Worktrunk is a CLI for Git worktree management, designed for parallel AI agent workflows. Git worktrees give each agent an isolated branch and directory; Worktrunk adds branch-based navigation, unified status, and lifecycle hooks. The goal is to make spinning up a new AI "developer" for a task feel as routine as git switch.

December 2025 Project Status

I've been using Worktrunk as my daily driver, and am releasing it as Open Source this week. It's built with love (there's no slop!). If social proof is helpful: I also created PRQL (10k stars) and am a maintainer of Xarray (4k stars), Insta, & Numbagg.

I'd recommend:

Demo

Worktrunk Demo

Quick Start

1. Install

Homebrew (macOS):

$ brew install max-sixty/worktrunk/wt
$ wt config shell install  # allows commands to change directories

Cargo:

$ cargo install worktrunk
$ wt config shell install

2. Create a worktree

$ wt switch --create fix-auth
 Created new worktree for fix-auth from main at ../repo.fix-auth

This creates ../repo.fix-auth on branch fix-auth.

3. Switch between worktrees

$ wt switch feature-api
 Switched to worktree for feature-api at ../repo.feature-api

4. List worktrees

$ wt list
  Branch       Status         HEAD±    main↕  Path                Remote⇅  Commit    Age   Message
@ feature-api  +   ↑⇡      +36  -11   ↑4      ./repo.feature-api   ⇡3      b1554967  30m   Add API tests
^ main             ^⇣                         ./repo                   ⇣1  b834638e  1d    Initial commit
+ fix-auth        _                           ./repo.fix-auth              b834638e  1d    Initial commit

 Showing 3 worktrees, 1 with changes, 1 ahead

--full adds CI status and conflicts. --branches includes all branches.

5. Clean up

Say we merged via CI, our changes are on main, and we're finished with the worktree:

$ wt remove
🔄 Removing feature-api worktree & branch in background (already in main)

Why git worktrees?

We have a few options for working with multiple agents:

  • one working tree with many branches — agents step on each other, can't use git for staging & committing
  • multiple clones — slow to set up, drift out of sync
  • git worktrees — multiple directories backed by a single .git directory

So we use git worktrees! But then...

Why Worktrunk?

Git's built-in worktree commands require remembering worktrees' locations, and composing git & cd commands together. In contrast, Worktrunk bundles creation, navigation, status, and cleanup into simple commands. A few examples:

...and check out examples below for more advanced workflows.

Advanced

Many Worktrunk users will just use the commands above. For more:

LLM commit messages

Worktrunk can invoke external commands to generate commit messages. llm from @simonw is recommended.

Add to user config (~/.config/worktrunk/config.toml):

[commit-generation]
command = "llm"
args = ["-m", "claude-haiku-4-5-20251001"]

wt merge generates commit messages automatically or wt step commit runs just the commit step.

For custom prompt templates: wt config --help.

Project hooks

Automate setup and validation at worktree lifecycle events:

Hook When Example
post-create After worktree created cp -r .cache, ln -s
post-start After worktree created (background) npm install, cargo build
pre-commit Before creating any commit pre-commit run
pre-merge After squash, before push cargo test, pytest
post-merge After successful merge cargo install --path .

Project commands require approval on first run; use --force to skip prompts or --no-verify to skip hooks entirely. Configure in .config/wt.toml:

# Install dependencies, build setup
[post-create]
"install" = "uv sync"

# Dev servers, file watchers (runs in background)
[post-start]
"dev" = "uv run dev"

# Tests and lints before merging (blocks on failure)
[pre-merge]
"lint" = "uv run ruff check"
"test" = "uv run pytest"

Example output:

$ wt switch --create feature-x
🔄 Running post-create install:
   uv sync

  Resolved 24 packages in 145ms
  Installed 24 packages in 1.2s
 Created new worktree for feature-x from main at ../repo.feature-x
🔄 Running post-start dev:
   uv run dev

Local merging with wt merge

wt merge handles the full merge workflow: stage, commit, squash, rebase, merge, cleanup. Includes LLM commit messages, project hooks, and config/flags for skipping steps.

$ wt merge
🔄 Squashing 3 commits into a single commit (3 files, +33)...
🔄 Generating squash commit message...
   feat(auth): Implement JWT authentication system

   Add comprehensive JWT token handling including validation, refresh logic,
   and authentication tests. This establishes the foundation for secure
   API authentication.

   - Implement token refresh mechanism with expiry handling
   - Add JWT encoding/decoding with signature verification
   - Create test suite covering all authentication flows
 Squashed @ 95c3316
🔄 Running pre-merge test:
   cargo test
    Finished test [unoptimized + debuginfo] target(s) in 0.12s
     Running unittests src/lib.rs (target/debug/deps/worktrunk-abc123)

running 18 tests
test auth::tests::test_jwt_decode ... ok
test auth::tests::test_jwt_encode ... ok
test auth::tests::test_token_refresh ... ok
test auth::tests::test_token_validation ... ok

test result: ok. 18 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
🔄 Running pre-merge lint:
   cargo clippy
    Checking worktrunk v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 1.23s
🔄 Merging 1 commit to main @ 95c3316 (no rebase needed)
   * 95c3316 feat(auth): Implement JWT authentication system
    auth.rs      |  8 ++++++++
    auth_test.rs | 17 +++++++++++++++++
    jwt.rs       |  8 ++++++++
    3 files changed, 33 insertions(+)
 Merged to main (1 commit, 3 files, +33)
🔄 Removing feature-auth worktree & branch in background (already in main)
🔄 Running post-merge install:
   cargo install --path .
  Installing worktrunk v0.1.0
   Compiling worktrunk v0.1.0
    Finished release [optimized] target(s) in 2.34s
  Installing ~/.cargo/bin/wt
   Installed package `worktrunk v0.1.0` (executable `wt`)

Claude Code Status Tracking

The Worktrunk plugin adds Claude Code session tracking to wt list:

$ wt list
  Branch       Status         HEAD±    main↕  Path                Remote⇅  Commit    Age   Message
@ main             ^                          ./repo                       b834638e  1d    Initial commit
+ feature-api      ↑  🤖              ↑1      ./repo.feature-api           9606cd0f  1d    Add REST API endpoints
+ review-ui      ? ↑  💬              ↑1      ./repo.review-ui             afd3b353  1d    Add dashboard component
+ wip-docs       ?_                           ./repo.wip-docs              b834638e  1d    Initial commit

 Showing 4 worktrees, 2 ahead
  • 🤖 — Claude is working
  • 💬 — Claude is waiting for input

Install the plugin:

claude plugin marketplace add max-sixty/worktrunk
claude plugin install worktrunk@worktrunk

Set status markers manually for any workflow:

wt config var set marker "🚧"                   # Current branch
wt config var set marker "" --branch feature  # Specific branch
git config worktrunk.marker.feature "💬"        # Direct git config

Interactive Worktree Picker

wt select opens a fzf-like fuzzy-search worktree picker with diff preview. Unix only.

Preview tabs (toggle with 1/2/3):

  • Tab 1: Working tree changes (uncommitted)
  • Tab 2: Commit history (commits not on main highlighted)
  • Tab 3: Branch diff (changes ahead of main)

Statusline Integration

wt list statusline outputs a single-line status for shell prompts, starship, or editor integrations[^1].

[^1]: Currently this grabs CI status, so is too slow to use in synchronous contexts. If a faster version would be helpful, please add an Issue.

Claude Code (--claude-code): Reads workspace context from stdin, outputs directory, branch status, and model.

~/w/myproject.feature-auth  !🤖  ±+42 -8  ↑3  ⇡1  ●  | Opus

Add to ~/.claude/settings.json:

{
  "statusLine": {
    "type": "command",
    "command": "wt list statusline --claude-code"
  }
}

Tips & patterns

Alias for new worktree + agent:

alias wsc='wt switch --create --execute=claude'
wsc new-feature  # Creates worktree, runs hooks, launches Claude

Eliminate cold startspost-create hooks install deps and copy caches. See .config/wt.toml for an example using copy-on-write.

Local CI gatepre-merge hooks run before merging. Failures abort the merge.

Track agent status — Custom emoji markers show agent state in wt list. Claude Code hooks can set these automatically. See Claude Code Status Tracking.

Monitor CI across brancheswt list --full --branches shows PR/CI status for all branches, including those without worktrees. CI column links to PR pages in terminals with hyperlink support.

JSON APIwt list --format=json for dashboards, statuslines, scripts.

Task runners — Reference Taskfile/Justfile/Makefile in hooks:

[post-create]
"setup" = "task install"

[pre-merge]
"validate" = "just test lint"

Shortcuts^ = default branch, @ = current branch, - = previous worktree. Example: wt switch --create hotfix --base=@ branches from current HEAD.

Commands Reference

wt switch — Switch to a worktree
Usage: wt switch [OPTIONS] <BRANCH>

Arguments:
  <BRANCH>
          Branch or worktree name

          Shortcuts: '^' (main), '-' (previous), '@' (current)

Options:
  -c, --create
          Create a new branch

  -b, --base <BASE>
          Base branch

          Defaults to default branch.

  -x, --execute <EXECUTE>
          Command to run after switch

  -f, --force
          Skip approval prompts

      --no-verify
          Skip all project hooks

  -h, --help
          Print help (see a summary with '-h')

Global Options:
  -C <path>
          Working directory for this command

      --config <path>
          User config file path

  -v, --verbose
          Show commands and debug info

Two distinct operations:

- **Switch to existing worktree** — Changes directory, nothing else
- **Create new worktree** (`--create`) — Creates branch and worktree, runs [hooks](/hooks/)

Examples

wt switch feature-auth           # Switch to existing worktree
wt switch -                      # Previous worktree (like cd -)
wt switch --create new-feature   # Create branch and worktree
wt switch --create hotfix --base production

For interactive selection, use wt select.

Shortcuts

Symbol Meaning
- Previous worktree
@ Current branch's worktree
^ Default branch worktree
wt switch -                      # Back to previous
wt switch ^                      # Main worktree
wt switch --create fix --base=@  # Branch from current HEAD

Path-First Lookup

Arguments resolve by checking the filesystem before git branches:

  1. Compute expected path from argument (using configured path template)
  2. If worktree exists at that path, switch to it
  3. Otherwise, treat argument as branch name

Edge case: If repo.foo/ exists but tracks branch bar:

  • wt switch foo → switches to repo.foo/ (the bar worktree)
  • wt switch bar → also works (branch lookup finds same worktree)

Creating Worktrees

With --create, worktrunk:

  1. Creates branch from --base (defaults to default branch)
  2. Creates worktree at configured path
  3. Runs post-create hooks (blocking)
  4. Switches to new directory
  5. Spawns post-start hooks (background)
wt switch --create api-refactor
wt switch --create fix --base release-2.0
wt switch --create docs --execute "code ."
wt switch --create temp --no-verify      # Skip hooks

See Also

wt merge — Merge worktree into target branch
Usage: wt merge [OPTIONS] [TARGET]

Arguments:
  [TARGET]
          Target branch

          Defaults to default branch.

Options:
      --no-squash
          Skip commit squashing

      --no-commit
          Skip commit, squash, and rebase

      --no-remove
          Keep worktree after merge

      --no-verify
          Skip all project hooks

  -f, --force
          Skip approval prompts

      --stage <STAGE>
          What to stage before committing [default: all]

          Possible values:
          - all:     Stage everything: untracked files + unstaged tracked changes
          - tracked: Stage tracked changes only (like git add -u)
          - none:    Stage nothing, commit only what's already in the index

  -h, --help
          Print help (see a summary with '-h')

Global Options:
  -C <path>
          Working directory for this command

      --config <path>
          User config file path

  -v, --verbose
          Show commands and debug info

Merge the current branch into the target branch and clean up. Handles the full workflow: commit uncommitted changes, squash commits, rebase, run hooks, push to target, and remove the worktree.

When already on the target branch or in the main worktree, the worktree is preserved automatically.

Examples

Basic merge to main:

wt merge

Keep the worktree after merging:

wt merge --no-remove

Preserve commit history (no squash):

wt merge --no-squash

Skip git operations, only run hooks and push:

wt merge --no-commit

Pipeline

wt merge runs these steps:

  1. Commit — Stages and commits uncommitted changes. Commit messages are LLM-generated. Use --stage to control what gets staged: all (default), tracked, or none.

  2. Squash — Combines all commits into one (like GitHub's "Squash and merge"). Skip with --no-squash to preserve individual commits. A backup ref is saved to refs/wt-backup/<branch>.

  3. Rebase — Rebases onto the target branch. Conflicts abort immediately.

  4. Pre-merge hooks — Project commands run after rebase, before push. Failures abort. See Hooks.

  5. Push — Fast-forward push to the target branch. Non-fast-forward pushes are rejected.

  6. Cleanup — Removes the worktree and branch. Use --no-remove to keep the worktree.

  7. Post-merge hooks — Project commands run after cleanup. Failures are logged but don't abort.

Use --no-commit to skip steps 1-3 and only run hooks and push. Requires a clean working tree and --no-remove.

See Also

  • wt step — Run individual merge steps (commit, squash, rebase, push)
  • wt remove — Remove worktrees without merging
  • wt switch — Navigate to other worktrees
wt remove — Remove worktree and branch
Usage: wt remove [OPTIONS] [WORKTREES]...

Arguments:
  [WORKTREES]...
          Worktree or branch (@ for current)

Options:
      --no-delete-branch
          Keep branch after removal

  -D, --force-delete
          Delete unmerged branches

      --no-background
          Run removal in foreground

  -h, --help
          Print help (see a summary with '-h')

Global Options:
  -C <path>
          Working directory for this command

      --config <path>
          User config file path

  -v, --verbose
          Show commands and debug info

Removes worktrees and their branches. Without arguments, removes the current worktree and returns to the main worktree.

Examples

Remove current worktree:

wt remove

Remove specific worktrees:

wt remove feature-branch
wt remove old-feature another-branch

Keep the branch:

wt remove --no-delete-branch feature-branch

Force-delete an unmerged branch:

wt remove -D experimental

When Branches Are Deleted

Branches delete automatically when their content is already in the target branch (typically main). This works with squash-merge and rebase workflows where commit history differs but file changes match.

Use -D to force-delete unmerged branches. Use --no-delete-branch to keep the branch.

Background Removal

Removal runs in the background by default (returns immediately). Logs are written to .git/wt-logs/{branch}-remove.log. Use --no-background to run in the foreground.

Path-First Lookup

Arguments resolve by checking the expected path first, then falling back to branch name:

  1. Compute expected path from argument (using configured path template)
  2. If a worktree exists there, remove it (regardless of branch name)
  3. Otherwise, treat argument as a branch name

If repo.foo/ exists on branch bar, both wt remove foo and wt remove bar remove the same worktree.

Shortcuts: @ (current), - (previous), ^ (main worktree)

See Also

  • wt merge — Remove worktree after merging
  • wt list — View all worktrees
wt list — List worktrees and optionally branches
Usage: wt list [OPTIONS]
       wt list <COMMAND>

Commands:
  statusline  Single-line status for shell prompts

Options:
      --format <FORMAT>
          Output format (table, json)

          [default: table]

      --branches
          Include branches without worktrees

      --remotes
          Include remote branches

      --full
          Show CI, conflicts, diffs

      --progressive
          Show fast info immediately, update with slow info

          Displays local data (branches, paths, status) first, then updates with remote data (CI, upstream) as it arrives. Auto-enabled for TTY.

  -h, --help
          Print help (see a summary with '-h')

Global Options:
  -C <path>
          Working directory for this command

      --config <path>
          User config file path

  -v, --verbose
          Show commands and debug info

Show all worktrees with their status. The table includes uncommitted changes, divergence from main and remote, and optional CI status.

Examples

List all worktrees:

wt list

Include CI status and conflict detection:

wt list --full

Include branches that don't have worktrees:

wt list --branches

Output as JSON for scripting:

wt list --format=json

Status Symbols

Symbols appear in the Status column in this order:

Working tree state:

  • + — Staged files
  • ! — Modified files (unstaged)
  • ? — Untracked files
  • — Merge conflicts
  • — Rebase in progress
  • — Merge in progress

Branch state:

  • — Would conflict if merged to main (--full only)
  • — Matches main (identical contents)
  • _ — No commits (empty branch)

Divergence from main:

  • — Ahead of main
  • — Behind main
  • — Diverged from main

Remote tracking:

  • — Ahead of remote
  • — Behind remote
  • — Diverged from remote

Other:

  • — Branch without worktree
  • — Prunable (directory missing)
  • — Locked worktree

Rows are dimmed when the branch has no marginal contribution ( matches main or _ no commits).

Columns

Column Shows
Branch Branch name
Status Compact symbols (see above)
HEAD± Uncommitted changes: +added -deleted lines
main↕ Commits ahead/behind main
main…± Line diffs in commits ahead of main (--full)
Path Worktree directory
Remote⇅ Commits ahead/behind tracking branch
CI Pipeline status (--full)
Commit Short hash (8 chars)
Age Time since last commit
Message Last commit message (truncated)

The CI column shows GitHub/GitLab pipeline status:

  • green — All checks passed
  • blue — Checks running
  • red — Checks failed
  • yellow — Merge conflicts with base
  • gray — No checks configured
  • blank — No PR/MR found
  • dimmed — Stale (unpushed local changes)

JSON Output

Query structured data with --format=json:

# Worktrees with conflicts
wt list --format=json | jq '.[] | select(.status.branch_state == "Conflicts")'

# Uncommitted changes
wt list --format=json | jq '.[] | select(.status.working_tree.modified)'

# Current worktree
wt list --format=json | jq '.[] | select(.is_current == true)'

# Branches ahead of main
wt list --format=json | jq '.[] | select(.status.main_divergence == "Ahead")'

Status fields:

  • working_tree: {untracked, modified, staged, renamed, deleted}
  • branch_state: "" | "Conflicts" | "MergeTreeConflicts" | "MatchesMain" | "NoCommits"
  • git_operation: "" | "Rebase" | "Merge"
  • main_divergence: "" | "Ahead" | "Behind" | "Diverged"
  • upstream_divergence: "" | "Ahead" | "Behind" | "Diverged"

Position fields:

  • is_main — Main worktree
  • is_current — Current directory
  • is_previous — Previous worktree from wt switch

See Also

  • wt select — Interactive worktree picker with live preview
wt config — Manage configuration and shell integration
Usage: wt config [OPTIONS] <COMMAND>

Commands:
  shell      Shell integration setup
  create     Create user configuration file
  show       Show configuration files & locations
  cache      Manage caches (CI status, default branch)
  var        Get or set runtime variables (stored in git config)
  approvals  Manage command approvals

Options:
  -h, --help
          Print help (see a summary with '-h')

Global Options:
  -C <path>
          Working directory for this command

      --config <path>
          User config file path

  -v, --verbose
          Show commands and debug info

Manages configuration, shell integration, and runtime settings. The command provides subcommands for setup, inspection, and cache management.

Examples

Install shell integration (required for directory switching):

wt config shell install

Create user config file with documented examples:

wt config create

Show current configuration and file locations:

wt config show

Shell Integration

Shell integration allows Worktrunk to change the shell's working directory after wt switch. Without it, commands run in a subprocess and directory changes don't persist.

The wt config shell install command adds integration to the shell's config file. Manual installation:

# For bash: add to ~/.bashrc
eval "$(wt config shell init bash)"

# For zsh: add to ~/.zshrc
eval "$(wt config shell init zsh)"

# For fish: add to ~/.config/fish/config.fish
wt config shell init fish | source

Configuration Files

User config~/.config/worktrunk/config.toml (or $WORKTRUNK_CONFIG_PATH):

Personal settings like LLM commit generation, path templates, and default behaviors. The wt config create command generates a file with documented examples.

Project config.config/wt.toml in repository root:

Project-specific hooks: post-create, post-start, pre-commit, pre-merge, post-merge. See Hooks for details.

LLM Commit Messages

Worktrunk can generate commit messages using an LLM. Enable in user config:

[commit-generation]
command = "llm"

See LLM Commits for installation, provider setup, and customization.

wt step — Run individual workflow operations
Usage: wt step [OPTIONS] <COMMAND>

Commands:
  commit       Commit changes with LLM commit message
  squash       Squash commits with LLM commit message
  push         Push changes to local target branch
  rebase       Rebase onto target
  post-create  Run post-create hook
  post-start   Run post-start hook
  pre-commit   Run pre-commit hook
  pre-merge    Run pre-merge hook
  post-merge   Run post-merge hook

Options:
  -h, --help
          Print help (see a summary with '-h')

Global Options:
  -C <path>
          Working directory for this command

      --config <path>
          User config file path

  -v, --verbose
          Show commands and debug info

Run individual workflow operations: commits, squashes, rebases, pushes, and [hooks](/hooks/).

Examples

Commit with LLM-generated message:

wt step commit

Run pre-merge hooks in CI:

wt step pre-merge --force

Manual merge workflow with review between steps:

wt step commit
wt step squash
# Review the squashed commit
wt step rebase
wt step push

Operations

Git operations:

  • commit — Stage and commit with LLM-generated message
  • squash — Squash all branch commits into one with LLM-generated message
  • rebase — Rebase onto target branch
  • push — Push to target branch (default: main)

Hooks — run project commands defined in .config/wt.toml:

  • post-create — After worktree creation
  • post-start — After switching to a worktree
  • pre-commit — Before committing
  • pre-merge — Before pushing to target
  • post-merge — After merge cleanup

See Also

  • wt merge — Runs commit → squash → rebase → hooks → push → cleanup automatically

FAQ

Worktrunk executes commands in three contexts:

  1. Project hooks (project config: .config/wt.toml) - Automation for worktree lifecycle
  2. LLM commands (user config: ~/.config/worktrunk/config.toml) - Commit message generation
  3. --execute flag - Commands provided explicitly

Commands from project hooks and LLM configuration require approval on first run. Approved commands are saved to user config under the project's configuration. If a command changes, Worktrunk requires new approval.

Example approval prompt:

🟡 repo needs approval to execute 3 commands:

⚪ post-create install:
   echo 'Installing dependencies...'

⚪ post-create build:
   echo 'Building project...'

⚪ post-create test:
   echo 'Running tests...'

💡 Allow and remember? [y/N]

Use --force to bypass prompts (useful for CI/automation).

vs. Branch Switching

Branch switching uses one directory, so only one agent can work at a time. Worktrees give each agent its own directory.

vs. Plain git worktree

Git's built-in worktree commands work but require manual lifecycle management:

# Plain git worktree workflow
git worktree add -b feature-branch ../myapp-feature main
cd ../myapp-feature
# ...work, commit, push...
cd ../myapp
git merge feature-branch
git worktree remove ../myapp-feature
git branch -d feature-branch

Worktrunk automates the full lifecycle:

wt switch --create feature-branch  # Creates worktree, runs setup hooks
# ...work...
wt merge                            # Squashes, merges, removes worktree

What git worktree doesn't provide:

  • Consistent directory naming and cleanup validation
  • Project-specific automation (install dependencies, start services)
  • Unified status across all worktrees (commits, CI, conflicts, changes)

Worktrunk adds path management, lifecycle hooks, and wt list --full for viewing all worktrees—branches, uncommitted changes, commits ahead/behind, CI status, and conflicts—in a single view.

vs. git-machete / git-town

Different scopes:

  • git-machete: Branch stack management in a single directory
  • git-town: Git workflow automation in a single directory
  • worktrunk: Multi-worktree management with hooks and status aggregation

These tools can be used together—run git-machete or git-town inside individual worktrees.

vs. Git TUIs (lazygit, gh-dash, etc.)

Git TUIs operate on a single repository. Worktrunk manages multiple worktrees, runs automation hooks, and aggregates status across branches. TUIs work inside each worktree directory.

Errors related to tree-sitter or C compilation (C99 mode, le16toh undefined) can be avoided by installing without syntax highlighting:

cargo install worktrunk --no-default-features

This disables bash syntax highlighting in command output but keeps all core functionality. The syntax highlighting feature requires C99 compiler support and can fail on older systems or minimal Docker images.

Thanks in advance!

Running Tests

Quick tests (no external dependencies):

cargo test --lib --bins           # Unit tests (~200 tests)
cargo test --test integration     # Integration tests without shell tests (~300 tests)

Full integration tests (requires bash, zsh, fish):

cargo test --test integration --features shell-integration-tests

Dependencies for shell integration tests:

  • bash, zsh, fish shells
  • Quick setup: ./dev/setup-claude-code-web.sh (installs shells on Linux)

Releases

Use cargo-release to publish new versions:

cargo install cargo-release

# Bump version, update Cargo.lock, commit, tag, and push
cargo release patch --execute   # 0.1.0 -> 0.1.1
cargo release minor --execute   # 0.1.0 -> 0.2.0
cargo release major --execute   # 0.1.0 -> 1.0.0

This updates Cargo.toml and Cargo.lock, creates a commit and tag, then pushes to GitHub. The tag push triggers GitHub Actions to build binaries, create the release, and publish to crates.io.

Run without --execute to preview changes first.

Updating Homebrew Formula

After cargo release completes and the GitHub release is created, update the homebrew-worktrunk tap:

./dev/update-homebrew.sh

This script fetches the new tarball, computes the SHA256, updates the formula, and pushes to homebrew-worktrunk.