worktrunk Documentation

repository·main·Indexed 26 days ago

https://github.com/max-sixty/worktrunk

A CLI tool for Git worktree management (v0.69.2) optimized for parallel AI agent workflows, such as Claude Code. It simplifies the Git worktree UX, allowing users to create, switch, list, and merge worktrees with automation features including project hooks, LLM-generated commit messages, and a dedicated plugin for Claude Code session tracking.

Tokens
78.4K
Snippets
184
Records
454
Agent score
88%

What's inside worktrunk

  1. Understand Worktrunk's Code Signing Policy

    main

    Worktrunk uses Authenticode signatures for its Windows release binaries (wt.exe and git-wt.exe) to prevent false positive detections by Microsoft Defender (e.g., Trojan:Win32/Wacatac.B!ml).

    Scope of Signing:

    • Signed: Windows binaries (wt.exe and git-wt.exe) distributed via GitHub Releases and winget (winget install max-sixty.worktrunk).
    • Not Signed: macOS and Linux release artifacts, crates.io source distributions, and cargo install builds (which compile locally from source).

    Security Model:

    • Certificates are provided by the SignPath Foundation.
    • Private keys are held on a Hardware Security Module (HSM) and are never possessed by maintainers.
    • Signing is triggered by version tags in the official repository and requires manual approval by an authorized Approver.
  2. Worktrunk Workflow Overview

    main

    Worktrunk is designed to make git worktrees as easy to manage as branches, specifically optimized for running multiple AI agents in parallel.

    Key Capabilities:

    • Parallelism: Each agent gets its own working directory via git worktrees to prevent state conflicts.
    • Automation: Supports hooks (create, pre-merge, post-merge), LLM-generated commit messages, and automated merge workflows.
    • Developer Experience: Includes an interactive picker for browsing worktrees, PR checkout (wt switch pr:123), and build cache sharing (e.g., target/ or node_modules/) to speed up environment setup.
    • Customization: Supports aliases and per-branch variables for complex workflows.
  3. Understand Worktrunk configuration scopes

    main

    Worktrunk uses two distinct configuration files with different scopes:

    1. User config (~/.config/worktrunk/config.toml): Contains personal preferences like LLM integration, worktree path templates, and personal hooks. This file is never checked into git.
    2. Project config (<repo>/.config/wt.toml): Contains team-wide automation and lifecycle hooks (e.g., pre-start, post-merge). This file is checked into git and is versioned with the repository.

    Use User config for your own environment settings and Project config for automation that should run for everyone on the team.

  4. Run a dev server per worktree using `hash_port`

    main

    To avoid port collisions between multiple worktrees, use the hash_port filter to generate a stable, deterministic port (10000-19999) based on the branch name. Use wt step tether in a post-start hook to run the server in a managed process group that is automatically cleaned up when the worktree is removed.

    # .config/wt.toml
    [post-start]
    server = "wt step tether -- npm run dev -- --port {{ branch | hash_port }}"
    
    [list]
    url = "http://localhost:{{ branch | hash_port }}"
  5. Install Worktrunk without syntax highlighting

    main

    If you encounter C compilation errors related to tree-sitter or C99 mode (e.g., le16toh undefined) during installation, you can install Worktrunk without the syntax highlighting feature. This is useful for older systems or minimal Docker images.

    cargo install worktrunk --no-default-features --features cli
  6. Manage Project hook approvals

    main

    Project hooks (defined in .config/wt.toml) require manual approval on their first run for security. Approvals are stored in ~/.config/worktrunk/approvals.toml.

    • Bypass prompts: Use the --yes flag for CI or automation.
    • Skip all hooks: Use the --no-hooks flag.
    • Manage approvals: Use wt config approvals add or wt config approvals clear.

    If a command changes, a new approval is required. Declining a prompt skips all project commands for that specific operation.

  7. Remove worktrees and branches with `wt remove`

    main

    The wt remove command is used to clean up worktrees and branches. It includes built-in safeguards to prevent accidental data loss.

    Worktree Removal

    wt remove mirrors git worktree remove and will refuse to remove worktrees containing uncommitted changes (staged, modified, or untracked files).

    • To discard all changes and force removal, use the --force flag.
    • To protect a worktree from being deleted entirely (e.g., if it contains a local database), use git worktree lock.

    Branch Deletion

    By default, wt remove only deletes branches whose content is already integrated into the default branch. In wt list, safe branches are marked with _ (same commit) or (integrated).

    • Use -D to force-delete branches with unmerged changes.
    • Use --no-delete-branch to keep the branch regardless of its status.
    • Note: A branch currently checked out in a second worktree will always be retained, even with -D.
  8. Initialize project configuration in a bare repository

    main

    Because a bare .git directory has no tracked files, the project configuration file (.config/wt.toml) must be created within an existing worktree. Once created, it will be automatically available in all other worktrees of that project.

    Steps:

    1. Create the first worktree: wt switch <branch>.
    2. Enter the worktree: cd <worktree_path>.
    3. Create the project config: wt config create --project.
    cd myproject/main
    wt config create --project
  9. Defer Variable Expansion for Nested Commands

    main

    By default, alias bodies are rendered once at dispatch in the invoking worktree. If you are using an alias to run a command across all worktrees (like wt step for-each), variables like {{ branch }} will be 'baked in' to the current worktree's value before the loop starts.

    To defer expansion so the variable is evaluated per worktree, wrap the variable in {% raw %}…{% endraw %}.

    Important: When using for-each, the deferred variable contains spaces. To prevent shell splitting errors, wrap the command in sh -c '...' to keep the value as a single token.

    Example of a deferred alias to show each worktree's branch:

    [aliases]
    show-branches = "wt step for-each -- sh -c 'echo {% raw %}{{ branch }}{% endraw %}'"