wt config

Manage user & project configs. Includes shell integration, hooks, and saved state.

Examples

Install shell integration (required for directory switching):

wt config shell install

Create user config file with documented examples:

wt config create

Create project config file (.config/wt.toml) for hooks:

wt config create --project

Show current configuration and file locations:

wt config show

Configuration files

FileLocationContainsCommitted & shared
User config~/.config/worktrunk/config.tomlWorktree path template, LLM commit configs, etc
Project config.config/wt.tomlProject hooks, dev server URL

Worktrunk User Configuration

Create with wt config create.

Location:

Worktree path template

Controls where new worktrees are created. Paths are relative to the repository root.

Variables:

Examples for repo at ~/code/myproject, branch feature/auth:

# Default — siblings in parent directory
# Creates: ~/code/myproject.feature-auth
worktree-path = "../{{ repo }}.{{ branch | sanitize }}"

# Inside the repository
# Creates: ~/code/myproject/.worktrees/feature-auth
worktree-path = ".worktrees/{{ branch | sanitize }}"

# Namespaced (useful when multiple repos share a parent directory)
# Creates: ~/code/worktrees/myproject/feature-auth
worktree-path = "../worktrees/{{ repo }}/{{ branch | sanitize }}"

# Nested bare repo (git clone --bare <url> project/.git)
# Creates: ~/code/project/feature-auth (sibling to .git)
worktree-path = "../{{ branch | sanitize }}"

LLM commit messages

Generate commit messages automatically during merge. Requires an external CLI tool. See LLM commits docs for setup and template customization.

Using llm (install: pip install llm llm-anthropic):

[commit-generation]
command = "llm"
args = ["-m", "claude-haiku-4.5"]

Using aichat:

[commit-generation]
command = "aichat"
args = ["-m", "claude:claude-haiku-4.5"]

See Custom prompt templates for inline template options.

Commands

List

Persistent flag values for wt list. Override on command line as needed.

[list]
full = false       # Show CI status and main…± diffstat columns (--full)
branches = false   # Include branches without worktrees (--branches)
remotes = false    # Include remote-only branches (--remotes)

Commit

Shared by wt step commit, wt step squash, and wt merge.

[commit]
stage = "all"      # What to stage before commit: "all", "tracked", or "none"

Merge

All flags are on by default. Set to false to change default behavior.

[merge]
squash = true      # Squash commits into one (--no-squash to preserve history)
commit = true      # Commit uncommitted changes first (--no-commit to skip)
rebase = true      # Rebase onto target before merge (--no-rebase to skip)
remove = true      # Remove worktree after merge (--no-remove to keep)
verify = true      # Run project hooks (--no-verify to skip)

Select

Pager behavior for wt select diff previews.

[select]
# Pager command with flags for diff preview (overrides git's core.pager)
# Use this to specify pager flags needed for non-TTY contexts
# Example:
# pager = "delta --paging=never"

Approved commands

Commands approved for project hooks. Auto-populated when approving hooks on first run, or via wt hook approvals add.

[projects."github.com/user/repo"]
approved-commands = ["npm ci", "npm test"]

For project-specific hooks (post-create, post-start, pre-merge, etc.), use a project config at <repo>/.config/wt.toml. Run wt config create --project to create one, or see wt hook docs.

Custom prompt templates

Templates use minijinja syntax.

Commit template

Available variables:

Default template:

[commit-generation]
template = """
Write a commit message for the staged changes below.

<format>
- Subject under 50 chars, blank line, then optional body
- Output only the commit message, no quotes or code blocks
</format>

<style>
- Imperative mood: "Add feature" not "Added feature"
- Match recent commit style (conventional commits if used)
- Describe the change, not the intent or benefit
</style>

<diffstat>
{{ git_diff_stat }}
</diffstat>

<diff>
{{ git_diff }}
</diff>

<context>
Branch: {{ branch }}
{% if recent_commits %}<recent_commits>
{% for commit in recent_commits %}- {{ commit }}
{% endfor %}</recent_commits>{% endif %}
</context>

"""

Squash template

Available variables (in addition to commit template variables):

Default template:

[commit-generation]
squash-template = """
Combine these commits into a single commit message.

<format>
- Subject under 50 chars, blank line, then optional body
- Output only the commit message, no quotes or code blocks
</format>

<style>
- Imperative mood: "Add feature" not "Added feature"
- Match the style of commits being squashed (conventional commits if used)
- Describe the change, not the intent or benefit
</style>

<commits branch="{{ branch }}" target="{{ target_branch }}">
{% for commit in commits %}- {{ commit }}
{% endfor %}</commits>

<diffstat>
{{ git_diff_stat }}
</diffstat>

<diff>
{{ git_diff }}
</diff>

"""

Worktrunk Project Configuration

The project config defines lifecycle hooks and project-specific settings. This file is checked into version control and shared across the team.

Create .config/wt.toml in the repository root:

[post-create]
install = "npm ci"

[pre-merge]
test = "npm test"
lint = "npm run lint"

See wt hook for complete documentation on hook types, execution order, template variables, and JSON context.

Dev server URL

The [list] section adds a URL column to wt list:

[list]
url = "http://localhost:{{ branch | hash_port }}"

URLs are dimmed when the port isn't listening.

CI platform override

The [ci] section overrides CI platform detection for GitHub Enterprise or self-hosted GitLab with custom domains:

[ci]
platform = "github"  # or "gitlab"

By default, the platform is detected from the remote URL. Use this when URL detection fails (e.g., git.mycompany.com instead of github.mycompany.com).


Shell integration

Worktrunk needs shell integration to change directories when switching worktrees. Install with:

wt config shell install

Or manually add to the shell config:

# 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

Without shell integration, wt switch prints the target directory but cannot cd into it.

Skip first-run prompt

On first run without shell integration, Worktrunk offers to install it. Suppress this prompt in CI or automated environments:

skip-shell-integration-prompt = true

Or via environment variable:

export WORKTRUNK_SKIP_SHELL_INTEGRATION_PROMPT=true

Environment variables

All user config options can be overridden with environment variables using the WORKTRUNK_ prefix.

Naming convention

Config keys use kebab-case (worktree-path), while env vars use SCREAMING_SNAKE_CASE (WORKTRUNK_WORKTREE_PATH). The conversion happens automatically.

For nested config sections, use double underscores to separate levels:

ConfigEnvironment Variable
worktree-pathWORKTRUNK_WORKTREE_PATH
commit-generation.commandWORKTRUNK_COMMIT_GENERATION__COMMAND
commit-generation.argsWORKTRUNK_COMMIT_GENERATION__ARGS

Note the single underscore after WORKTRUNK and double underscores between nested keys.

Array values

Array config values like args = ["-m", "claude-haiku"] can be specified as a single string in environment variables:

export WORKTRUNK_COMMIT_GENERATION__ARGS="-m claude-haiku"

Example: CI/testing override

Override the LLM command in CI to use a mock:

WORKTRUNK_COMMIT_GENERATION__COMMAND=echo \
WORKTRUNK_COMMIT_GENERATION__ARGS="test: automated commit" \
  wt merge

Other environment variables

VariablePurpose
WORKTRUNK_BINOverride binary path for shell wrappers (useful for testing dev builds)
WORKTRUNK_CONFIG_PATHOverride user config file location
WORKTRUNK_DIRECTIVE_FILEInternal: set by shell wrappers to enable directory changes
WORKTRUNK_SHELLInternal: set by shell wrappers to indicate shell type (e.g., powershell)
WORKTRUNK_MAX_CONCURRENT_COMMANDSMax parallel git commands (default: 32). Lower if hitting file descriptor limits.
NO_COLORDisable colored output (standard)
CLICOLOR_FORCEForce colored output even when not a TTY

Command reference

wt config - Manage user & project configs

Includes shell integration, hooks, and saved state.

Usage: wt config [OPTIONS] <COMMAND>

Commands:
  shell   Shell integration setup
  create  Create configuration file
  show    Show configuration files & locations
  state   Manage internal data and cache

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...
          Verbose output (-v: hooks, templates; -vv: debug report)

wt config show

Shows location and contents of user config (~/.config/worktrunk/config.toml) and project config (.config/wt.toml).

If a config file doesn't exist, shows defaults that would be used.

Full diagnostics

Use --full to run diagnostic checks:

wt config show --full

This tests:

Command reference

wt config show - Show configuration files & locations

Usage: wt config show [OPTIONS]

Options:
      --full
          Run diagnostic checks (CI tools, commit generation)

  -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...
          Verbose output (-v: hooks, templates; -vv: debug report)

wt config state

State is stored in .git/ (config entries and log files), separate from configuration files. Use wt config show to view file-based configuration.

Keys

Examples

Get the default branch:

wt config state default-branch

Set the default branch manually:

wt config state default-branch set main

Set a marker for current branch:

wt config state marker set "🚧 WIP"

Clear all CI status cache:

wt config state ci-status clear --all

Show all stored state:

wt config state get

Clear all stored state:

wt config state clear

Command reference

wt config state - Manage internal data and cache

Usage: wt config state [OPTIONS] <COMMAND>

Commands:
  default-branch   Default branch setting
  previous-branch  Previous branch (for wt switch -)
  ci-status        CI status cache
  marker           Branch markers
  logs             Background operation logs
  hints            One-time hints shown in this repo
  get              Get all stored state
  clear            Clear all stored state

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...
          Verbose output (-v: hooks, templates; -vv: debug report)

wt config state default-branch

Useful in scripts to avoid hardcoding main or master:

git rebase $(wt config state default-branch)

Without a subcommand, runs get. Use set to override, or clear then get to re-detect.

Detection

Worktrunk detects the default branch automatically:

  1. Worktrunk cache — Checks git config worktrunk.default-branch (single command)
  2. Git cache — Detects primary remote and checks its HEAD (e.g., origin/HEAD)
  3. Remote query — If not cached, queries git ls-remote (100ms–2s)
  4. Local inference — If no remote, infers from local branches

Once detected, the result is cached in worktrunk.default-branch for fast access.

The local inference fallback uses these heuristics in order:

Command reference

wt config state default-branch - Default branch setting

Usage: wt config state default-branch [OPTIONS] [COMMAND]

Commands:
  get    Get the default branch
  set    Set the default branch
  clear  Clear the default branch cache

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...
          Verbose output (-v: hooks, templates; -vv: debug report)

wt config state ci-status

Caches GitHub/GitLab CI status for display in wt list.

How it works

  1. Platform detection — From [ci] platform in project config, or detected from remote URL (github.com → GitHub, gitlab.com → GitLab)
  2. CLI requirement — Requires gh (GitHub) or glab (GitLab) CLI, authenticated
  3. What's checked — PRs/MRs first, then branch pipelines for branches with upstream
  4. Caching — Results cached 30-60 seconds per branch+commit

Status values

StatusMeaning
passedAll checks passed
runningChecks in progress
failedChecks failed
conflictsPR has merge conflicts
no-ciNo checks configured
errorFetch error (rate limit, network, auth)

See wt list CI status for display symbols and colors.

Without a subcommand, runs get for the current branch. Use clear to reset cache for a branch or clear --all to reset all.

Command reference

wt config state ci-status - CI status cache

Usage: wt config state ci-status [OPTIONS] [COMMAND]

Commands:
  get    Get CI status for a branch
  clear  Clear CI status cache

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...
          Verbose output (-v: hooks, templates; -vv: debug report)

wt config state marker

Custom status text or emoji shown in the wt list Status column.

Display

Markers appear at the start of the Status column:

Branch    Status   Path
main      ^        ~/code/myproject
feature   🚧↑      ~/code/myproject.feature
bugfix    🤖!↑⇡    ~/code/myproject.bugfix

Use cases

Storage

Stored in git config as worktrunk.state.<branch>.marker. Set directly with:

git config worktrunk.state.feature.marker '{"marker":"🚧","set_at":0}'

Without a subcommand, runs get for the current branch. For --branch, use get --branch=NAME.

Command reference

wt config state marker - Branch markers

Usage: wt config state marker [OPTIONS] [COMMAND]

Commands:
  get    Get marker for a branch
  set    Set marker for a branch
  clear  Clear marker for a branch

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...
          Verbose output (-v: hooks, templates; -vv: debug report)

wt config state logs

View and manage logs from background operations.

What's logged

OperationLog file
post-start hooks{branch}-{source}-post-start-{name}.log
Background removal{branch}-remove.log

Source is user or project depending on where the hook is defined.

Location

All logs are stored in .git/wt-logs/ (in the main worktree's git directory).

Behavior

Examples

List all log files:

wt config state logs get

View a specific log:

cat "$(git rev-parse --git-dir)/wt-logs/feature-project-post-start-build.log"

Clear all logs:

wt config state logs clear

Command reference

wt config state logs - Background operation logs

Usage: wt config state logs [OPTIONS] [COMMAND]

Commands:
  get    List background operation log files
  clear  Clear background operation logs

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...
          Verbose output (-v: hooks, templates; -vv: debug report)