1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# # User Configuration
#
# Create with `wt config create`. Values shown are defaults unless noted otherwise.
#
# Location:
#
# - macOS/Linux: `~/.config/worktrunk/config.toml` (or `$XDG_CONFIG_HOME` if set)
# - Windows: `%APPDATA%\worktrunk\config.toml`
#
# ## Worktree path template
#
# Controls where new worktrees are created.
#
# **Available template variables:**
#
# - `{{ repo_path }}` — absolute path to the repository root (e.g., `/Users/me/code/myproject`. Or for bare repos, the bare directory itself)
# - `{{ repo }}` — repository directory name (e.g., `myproject`)
# - `{{ owner }}` — primary remote owner path (may include subgroups like `group/subgroup`)
# - `{{ branch }}` — raw branch name (e.g., `feature/auth`)
# - `{{ branch | sanitize }}` — filesystem-safe: `/` and `\` become `-` (e.g., `feature-auth`)
# - `{{ branch | sanitize_db }}` — database-safe: lowercase, underscores, hash suffix (e.g., `feature_auth_x7k`)
#
# **Examples** for repo at `~/code/myproject`, branch `feature/auth`:
#
# Default — sibling directory (`~/code/myproject.feature-auth`):
#
# worktree-path = "{{ repo_path }}/../{{ repo }}.{{ branch | sanitize }}"
#
# Inside the repository (`~/code/myproject/.worktrees/feature-auth`):
#
# worktree-path = "{{ repo_path }}/.worktrees/{{ branch | sanitize }}"
#
# Centralized worktrees directory (`~/worktrees/myproject/feature-auth`):
#
# worktree-path = "~/worktrees/{{ repo }}/{{ branch | sanitize }}"
#
# By remote owner path (`~/development/max-sixty/myproject/feature/auth`):
#
# worktree-path = "~/development/{{ owner }}/{{ repo }}/{{ branch }}"
#
# Bare repository (`~/code/myproject/feature-auth`):
#
# worktree-path = "{{ repo_path }}/../{{ branch | sanitize }}"
#
# `~` expands to the home directory. Relative paths resolve from `repo_path`.
#
# ## LLM commit messages
#
# Generate commit messages automatically during merge. Requires an external CLI tool.
#
# ### Claude Code
#
# [commit.generation]
# command = "CLAUDECODE= MAX_THINKING_TOKENS=0 claude -p --no-session-persistence --model=haiku --tools='' --disable-slash-commands --setting-sources='' --system-prompt=''"
#
# ### Codex
#
# [commit.generation]
# command = "codex exec -m gpt-5.1-codex-mini -c model_reasoning_effort='low' -c system_prompt='' --sandbox=read-only --json - | jq -sr '[.[] | select(.item.type? == \"agent_message\")] | last.item.text'"
#
# ### OpenCode
#
# [commit.generation]
# command = "opencode run -m anthropic/claude-haiku-4.5 --variant fast"
#
# ### llm
#
# [commit.generation]
# command = "llm -m claude-haiku-4.5"
#
# ### aichat
#
# [commit.generation]
# command = "aichat -m claude:claude-haiku-4.5"
#
# See LLM commits docs (https://worktrunk.dev/llm-commits/) for setup and Custom prompt templates (#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)
#
# task-timeout-ms = 0 # Kill individual git commands after N ms; 0 disables
# timeout-ms = 0 # Wall-clock budget for the entire collect phase; 0 disables
#
# ### 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
#
# Most 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-hooks to skip)
# ff = true # Fast-forward merge (--no-ff to create a merge commit instead)
#
# ### Switch
#
# [switch]
# cd = true # Change directory after switching (--no-cd to skip)
#
# [switch.picker]
# pager = "delta --paging=never" # Example: override git's core.pager for diff preview
# timeout-ms = 0 # Deprecated. Accepted for backward compatibility, currently ignored.
#
# ### Step
#
# [step.copy-ignored]
# exclude = [] # Additional excludes (e.g., [".cache/", ".turbo/"])
#
# Built-in excludes always apply: VCS metadata directories (`.bzr/`, `.hg/`, `.jj/`, `.pijul/`, `.sl/`, `.svn/`) and tool-state directories (`.conductor/`, `.entire/`, `.pi/`, `.worktrees/`). User config and project config exclusions are combined.
#
# ### Aliases
#
# Command templates that run with `wt step <name>`. See `wt step` aliases (https://worktrunk.dev/step/#aliases) for usage and flags.
#
# [aliases]
# greet = "echo Hello from {{ branch }}"
# url = "echo http://localhost:{{ branch | hash_port }}"
#
# Aliases defined here apply to all projects. For project-specific aliases, use the project config (https://worktrunk.dev/config/#project-configuration) `[aliases]` section instead.
#
# ### User project-specific settings
#
# For context:
#
# - Project config (https://worktrunk.dev/config/#project-configuration) settings are shared with teammates.
# - User configs generally apply to all projects.
# - User configs _also_ has a `[projects]` table which holds project-specific settings for the user, such as worktree layout and setting overrides. That's what this section covers.
#
# Entries are keyed by project identifier (e.g., `github.com/user/repo`). Scalar values (like `worktree-path`) replace the global value; everything else (hooks, aliases, etc.) appends, global first.
#
# [projects."github.com/user/repo"]
# worktree-path = ".worktrees/{{ branch | sanitize }}"
# list.full = true
# merge.squash = false
# pre-start.env = "cp .env.example .env"
# step.copy-ignored.exclude = [".repo-local-cache/"]
# aliases.deploy = "make deploy BRANCH={{ branch }}"
#
# ### Custom prompt templates
#
# Templates use minijinja (https://docs.rs/minijinja/) syntax.
#
# #### Commit template
#
# Available variables:
#
# - `{{ git_diff }}`, `{{ git_diff_stat }}` — diff content
# - `{{ branch }}`, `{{ repo }}` — context
# - `{{ recent_commits }}` — recent commit messages
#
# Default template:
#
# <!-- DEFAULT_TEMPLATE_START -->
# [commit.generation]
# template = """
# <task>Write a commit message for the staged changes below.</task>
#
# <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>
#
# """
# <!-- DEFAULT_TEMPLATE_END -->
#
# #### Squash template
#
# Available variables (in addition to commit template variables):
#
# - `{{ commits }}` — list of commits being squashed
# - `{{ target_branch }}` — merge target branch
#
# Default template:
#
# <!-- DEFAULT_SQUASH_TEMPLATE_START -->
# [commit.generation]
# squash-template = """
# <task>Write a commit message for the combined effect of these commits.</task>
#
# <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>
#
# """
# <!-- DEFAULT_SQUASH_TEMPLATE_END -->
#
# ## Hooks
#
# See `wt hook` (https://worktrunk.dev/hook/) for hook types, execution order, template variables, and examples. User hooks apply to all projects; project hooks (https://worktrunk.dev/config/#project-configuration) apply only to that repository.