Configuration¶
Global config lives at ~/.config/kwt/config.toml, or at
$KWT_HOME/config.toml when KWT_HOME is set. Repository-local overrides live
in .kwt.toml and are trust-gated before use.
The global file is the source of truth for worktree naming, tmux layouts, agent commands, repository setup rules, and the known project registry.
[worktree]
basedir = "~/.kwt/worktrees"
auto_mkdir = true
[naming]
template = "{{.FullPath}}/{{.Branch}}"
[naming.sanitize_chars]
"/" = "-"
":" = "-"
[agents]
codex = "codex"
claude = "claude"
roborev = "roborev tui"
[layouts]
# default = "quad" # unset or "none" = blank single-pane session
auto_launch_on_add = true
[[layouts.presets]]
name = "quad"
arrange = "even-horizontal"
panes = ["agent:codex", "agent:claude", "agent:roborev", ""]
[[layouts.presets]]
name = "stack"
arrange = "even-vertical"
panes = ["agent:codex", "agent:claude", "agent:roborev", ""]
The default places newly created worktrees under ~/.kwt/worktrees. Relative
paths in a trusted repository-local .kwt.toml are resolved from that
repository's root; a repository-local worktree.basedir cannot be empty.
Repository-local path fields cannot reference environment variables, including
naming.template and naming.sanitize_chars replacements. Generated paths
influenced by repository-local naming are not environment-expanded after
rendering, so a template cannot synthesize a reference. Environment expansion
remains available for paths in the global configuration and for explicit
command-line paths. In a global naming template, expansion applies only to
literal template text, preserving Go template variables inside actions.
Global naming.sanitize_chars replacement values expand before branch
sanitization.
Resolved worktree and directory-workspace paths cannot contain #, which tmux
reserves for format expansion. kwt rejects such paths before creating or
registering a workspace.
Pane entries are shell commands. agent:<name> expands through the [agents]
table before tmux starts, so command flags live in one local config file.
layouts.default is optional. When it is unset — or set to the reserved name
none — workspaces launch as a blank single-pane session in the worktree
directory. Repository-local .kwt.toml files may also set
layouts.default = "none" to opt a single project back into blank sessions
when the global config names a preset.
Project registry¶
The dashboard lists worktrees from the configured base directory, the current
launch repository, and registered projects. Running kwt inside a repository
registers or refreshes that repository so future dashboard launches can find its
worktrees from anywhere.
Automation and graphical clients can perform the same explicit registration
without opening the dashboard by running kwt projects add <path> --json.
Project entries are discovery metadata, not worktree-creation policy:
[[projects]]
repository = "github.com/kenn-io/kwt"
name = "kwt"
path = "~/code/kwt"
last_touched = "2026-07-04T12:00:00Z"
Directory workspaces¶
Plain directories registered as tmux workspaces, independent of any Git worktree:
Paths are expanded and symlink-resolved on load. Entries are machine-level
configuration: repository-local .kwt.toml files cannot set them, and they are
never published over multi-machine sync. Manage entries with
kwt workspace add|list|remove rather than editing the file; see
Directory workspaces for the workflow.
Repository setup¶
Optional repository settings can copy files or run commands when new worktrees
are created by kwt add:
[[repository_settings]]
repository = "~/code/myapp"
basedir = "./worktrees"
copy_files = ["templates/.env.example"]
setup_commands = [
"npm install",
'printf "branch=%s\npath=%s\n" "{{.Branch}}" "{{.Path}}" > .worktree-info',
]
Template variables include Host, Owner, Repository, FullPath, Branch,
Hash, and Path. Quote variables in shell commands when values may contain
spaces. repository may also be a glob such as **/acme/widget; trusted
repository-local glob selectors remain repository selectors rather than being
resolved as paths beneath that repository.
Remote-only multi-machine sync skips repository setup (copy_files and
setup_commands) because the branch name is reported by another host. Run any
project bootstrap command manually after syncing if that branch needs it.
Multi-machine sync config¶
Multi-machine sync is an opt-in subsystem. The public command namespace is
kwt sync, and the config section is [fleet]. All [fleet] settings must be
set in the global config.toml; values in repository-local .kwt.toml files
are ignored.
[fleet]
enabled = true
host_id = "host-a"
hub_url = "https://host-a.example"
token_file = "~/.config/kwt/fleet.token"
[fleet.hub]
listen_addr = "127.0.0.1:8787"
store_path = "~/.local/share/kwt/fleet/state.json"
Plain http:// hub URLs and hub listeners are accepted only for loopback
hosts. Loopback client requests bypass environment HTTP proxies. Every
multi-machine hub URL must use HTTPS, commonly by serving the loopback hub
through a private TLS endpoint.
See Multi-machine sync for the user-facing workflow and Multi-machine sync architecture for the wire protocol and hub behavior.