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

Organizations can also deploy a system-wide config file for shared defaults — run wt config show for the platform-specific location.

User config — personal preferences:

# ~/.config/worktrunk/config.toml
worktree-path = ".worktrees/{{ branch | sanitize }}"

[commit.generation]
command = "MAX_THINKING_TOKENS=0 claude -p --model=haiku --tools='' --disable-slash-commands --setting-sources='' --system-prompt=''"

Project config — shared team settings:

# .config/wt.toml
[post-create]
deps = "npm ci"

[pre-merge]
test = "npm test"

User Configuration

Create with wt config create.

Location:

Worktree path template

Controls where new worktrees are created.

Variables:

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

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

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

# Centralized worktrees directory
# Creates: ~/worktrees/myproject/feature-auth
worktree-path = "~/worktrees/{{ repo }}/{{ branch | sanitize }}"

~ expands to the home directory. Relative paths are relative to the repository root.

LLM commit messages

Generate commit messages automatically during merge. Requires an external CLI tool.

See LLM commits docs for setup and Custom prompt templates for template customization.

Command config

List

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

[list]
summary = false    # Enable LLM branch summaries (requires [commit.generation])

full = false       # Show CI, main…± diffstat, and LLM summaries (--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)

Switch picker

Configuration for wt switch interactive picker.

[switch.picker]
# Pager command for diff preview (overrides git's core.pager)
# pager = "delta --paging=never"

# Timeout (ms) for git commands during picker loading (default: 200)
# Lower values show the TUI faster; 0 disables timeouts
# timeout-ms = 200

User project-specific settings

For context:

Entries are keyed by project identifier (e.g., github.com/user/repo).

Setting overrides (Experimental)

Override global user config for a specific project. Scalar values (like worktree-path) replace the global value. Hooks append — both global and per-project hooks run.

[projects."github.com/user/repo"]
worktree-path = ".worktrees/{{ branch | sanitize }}"
list.full = true
merge.squash = false
post-create.env = "cp .env.example .env"

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 line under 50 chars
- For material changes, add a blank line then a body paragraph explaining the change
- 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 line under 50 chars
- For material changes, add a blank line then a body paragraph explaining the change
- 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>

"""

Project Configuration

Project config (.config/wt.toml) defines lifecycle hooks and project-specific settings. This file is checked into version control and shared with the team. Create with wt config create --project.

See wt hook for hook types, execution order, template variables, and examples.

Non-hook settings

# .config/wt.toml

# URL column in wt list (dimmed when port not listening)
[list]
url = "http://localhost:{{ branch | hash_port }}"

# Override CI platform detection for self-hosted instances
[ci]
platform = "github"  # or "gitlab"

Shell Integration

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

wt config shell install

For manual setup, see wt config shell init --help.

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

First-run prompts

On first run without shell integration, Worktrunk offers to install it. Similarly, on first commit without LLM configuration, it offers to configure a detected tool (claude, codex). Declining sets skip-shell-integration-prompt or skip-commit-generation-prompt automatically.

Other

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.stageWORKTRUNK_COMMIT__STAGE

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

Example: CI/testing override

Override the LLM command in CI to use a mock:

WORKTRUNK_COMMIT__GENERATION__COMMAND="echo '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_SYSTEM_CONFIG_PATHOverride system config file location
XDG_CONFIG_DIRSColon-separated system config directories (default: /etc/xdg)
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
  update  Update deprecated config settings
  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)

Subcommands

wt config show

Show configuration files & locations.

Shows location and contents of user config (~/.config/worktrunk/config.toml) and project config (.config/wt.toml). Also shows system config if present.

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, version)

  -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

Manage internal data and cache.

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 detection and override
  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

Default branch detection and override.

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 detection and override

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

CI status cache.

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

Requires gh (GitHub) or glab (GitLab) CLI, authenticated. Platform auto-detects from remote URL; override with ci.platform = "github" in .config/wt.toml for self-hosted instances.

Checks open PRs/MRs first, then branch pipelines for branches with upstream. Local-only branches (no remote tracking) show blank.

Results cache for 30-60 seconds. Indicators dim when local changes haven't been pushed.

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

Branch markers.

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

Background operation logs.

View and manage logs from background operations.

What's logged

Two kinds of logs live in .git/wt-logs/:

Command log (commands.jsonl)

All hook executions and LLM commands are recorded automatically — one JSON object per line with timestamp, command, exit code, and duration. Rotates to commands.jsonl.old at 1MB (~2MB total).

Hook output logs

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

Query the command log:

tail -5 .git/wt-logs/commands.jsonl | jq .

View a specific hook 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    Get log file paths
  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)