mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
246c6bd919
Closes the `[list] columns` half of #3787, per the call in [this
comment](https://github.com/max-sixty/worktrunk/issues/3787#issuecomment-5273942067):
JSON always emits the same shape, and `list.columns` only affects the
actual columns.
Before, `--format json` planned `all_columns` (source `Default`)
*unioned* with the selection's forced-on columns, so the selection
reached JSON in one direction only — it couldn't narrow the emitted
fields, but a listed `ci` did force the forge fetch on without `--full`.
That made a presentation setting decide whether a machine-readable call
talks to GitHub, which is the thing the Neovim plugin in #3787 had to
pin `--config-set 'list.columns=[…]'` against. Now the JSON branch plans
`all_columns` alone; `--full` is the only switch for the gated data, and
it's the one a caller controls.
The table and the `wt switch` picker are untouched — a listed `ci` still
renders the CI column without `--full`, and the picker still unions the
selection in so its table matches `wt list`'s.
Only `ci` and `summary` are affected: every other column is ungated, so
`full_plan()` already covered them, and custom columns require no
background task.
**For the release note — this changes schema 1 too.** A caller with
`[list] columns = […, "ci"]` and no `--full` used to get the `ci` object
in schema-1 JSON and now won't; schema 1 has no `collected` envelope to
say why. The schema-1 `ci` row already documented `` `--full` only ``,
so the docs get *more* accurate, but the observable output changes for
anyone who was relying on the forcing path. Schema 2 reports the same
narrowing through `collected.ci`.
Docs updated in `after_long_help` (the `[list] columns` section plus the
schema-2 `pr`, `summary`, and `checks` rows — `summary` now names
`--full` alongside `[list] summary = true`, and `checks` names the
`--full` gate it shares with `pr`), with the generated mirrors,
`dev/config.example.toml`, and the `--help` snapshots regenerated. The
`CLAUDE.md` network inventory and the `collect` planning comment now
record the exemption too.
<details><summary>Test</summary>
`test_list_json_columns_selection_does_not_force_ci` in
`tests/integration_tests/list_config.rs` asserts schema 2's
`collected.ci` across three configs: unset (false), `columns =
["branch", "ci"]` without `--full` (false — the regression this fixes),
and the same with `--full` (true). `collected` records what the plan
requested rather than what a fetch returned, so the test needs no forge
and no `gh` on PATH. It sits next to
`test_list_json_ignores_columns_selection`, which owns the narrowing
direction, and `test_list_config_listed_column_overrides_full_gate`,
which owns the table's forcing behaviour and still passes unchanged.
Ran locally: full `cargo test --test integration` and `cargo test --lib
--bins`, plus `cargo clippy --all-targets` and `cargo fmt --check`. One
unrelated failure,
`test_copy_ignored_preserves_file_executable_permissions`, is a umask
artifact of this sandbox (expects `0644`, the runner's `umask 002`
produces `0664`); it touches no code in this diff.
The docs-row follow-up in df5c238 re-ran `cargo test --test integration
-- test_help test_docs_are_in_sync` (48 passed) and `cargo fmt --check`.
</details>
---------
Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
1464 lines
60 KiB
Markdown
1464 lines
60 KiB
Markdown
+++
|
||
title = "wt config"
|
||
description = "Manage user & project configs. Includes shell integration, hooks, and saved state."
|
||
weight = 15
|
||
|
||
[extra]
|
||
group = "Commands"
|
||
+++
|
||
|
||
<!-- ⚠️ AUTO-GENERATED from `wt config --help-page` — edit src/cli/mod.rs to update -->
|
||
|
||
Manage user & project configs. Includes shell integration, hooks, and saved state.
|
||
|
||
## Examples
|
||
|
||
Install shell integration (required for directory switching):
|
||
|
||
{{ terminal(cmd="wt config shell install") }}
|
||
|
||
Create user config file with documented examples:
|
||
|
||
{{ terminal(cmd="wt config create") }}
|
||
|
||
Create project config file (`.config/wt.toml`) for hooks:
|
||
|
||
{{ terminal(cmd="wt config create --project") }}
|
||
|
||
Show current configuration and file locations:
|
||
|
||
{{ terminal(cmd="wt config show") }}
|
||
|
||
## Configuration files
|
||
|
||
| File | Location | Contains | Committed & shared |
|
||
|------|----------|----------|--------------------|
|
||
| **User config** | `~/.config/worktrunk/config.toml` | Worktree path template, LLM commit configs, etc | ✗ |
|
||
| **Project config** | `.config/wt.toml` | Project hooks, dev server URL | ✓ |
|
||
|
||
Organizations can deploy a system-wide config file for shared defaults — run `wt config show` for the platform-specific location.
|
||
|
||
**User config** — personal preferences:
|
||
|
||
```toml
|
||
# ~/.config/worktrunk/config.toml
|
||
worktree-path = ".worktrees/{{ branch | sanitize }}"
|
||
|
||
[commit.generation]
|
||
command = "MAX_THINKING_TOKENS=0 claude -p --no-session-persistence --model=haiku --tools='' --safe-mode --setting-sources='user' --system-prompt=''"
|
||
```
|
||
|
||
**Project config** — shared team settings:
|
||
|
||
```toml
|
||
# .config/wt.toml
|
||
[pre-start]
|
||
deps = "npm ci"
|
||
|
||
[pre-merge]
|
||
test = "npm test"
|
||
```
|
||
|
||
<!-- USER_CONFIG_START -->
|
||
# 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`)
|
||
- `{{ remote_repo }}` — repository name in the primary remote URL, without `.git` (e.g., `myproject`); differs from `{{ repo }}`, the directory on disk, when a clone was renamed
|
||
- `{{ 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`)
|
||
- `{{ branch | codename(2) }}` — deterministic friendly name from a ~1.26M-combo pool (e.g., `malleable-opah`)
|
||
|
||
This is a smaller set than [the variables hooks and aliases get](@/hook.md#template-variables).
|
||
|
||
**Examples** for repo at `~/code/myproject`, branch `feature/auth`:
|
||
|
||
Default — sibling directory (`~/code/myproject.feature-auth`):
|
||
|
||
```toml
|
||
worktree-path = "{{ repo_path }}/../{{ repo }}.{{ branch | sanitize }}"
|
||
```
|
||
|
||
Inside the repository (`~/code/myproject/.worktrees/feature-auth`):
|
||
|
||
```toml
|
||
worktree-path = "{{ repo_path }}/.worktrees/{{ branch | sanitize }}"
|
||
```
|
||
|
||
Friendly branch-derived names (`~/code/myproject.malleable-opah`):
|
||
|
||
```toml
|
||
worktree-path = "{{ repo_path }}/../{{ repo }}.{{ branch | codename(2) }}"
|
||
```
|
||
|
||
Friendly names with branch identity in a parent directory (`~/code/worktrees/feature-auth/malleable-opah`):
|
||
|
||
```toml
|
||
worktree-path = "{{ repo_path }}/../worktrees/{{ branch | sanitize }}/{{ branch | codename(2) }}"
|
||
```
|
||
|
||
Centralized worktrees directory (`~/worktrees/myproject/feature-auth`):
|
||
|
||
```toml
|
||
worktree-path = "~/worktrees/{{ repo }}/{{ branch | sanitize }}"
|
||
```
|
||
|
||
By remote owner path (`~/development/max-sixty/myproject/feature/auth`):
|
||
|
||
```toml
|
||
worktree-path = "~/development/{{ owner }}/{{ repo }}/{{ branch }}"
|
||
```
|
||
|
||
Bare repository (`~/code/myproject/feature-auth`):
|
||
|
||
```toml
|
||
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
|
||
|
||
```toml
|
||
[commit.generation]
|
||
command = "MAX_THINKING_TOKENS=0 claude -p --no-session-persistence --model=haiku --tools='' --safe-mode --setting-sources='user' --system-prompt=''"
|
||
```
|
||
|
||
### Codex
|
||
|
||
```toml
|
||
[commit.generation]
|
||
command = "codex exec -m gpt-5.6-luna -c model_reasoning_effort='low' -c system_prompt='' --sandbox=read-only --json - | jq -sr '[.[] | select(.item.type? == \"agent_message\")] | last.item.text'"
|
||
```
|
||
|
||
### OpenCode
|
||
|
||
```toml
|
||
[commit.generation]
|
||
command = "opencode run -m anthropic/claude-haiku-4.5 --variant fast"
|
||
```
|
||
|
||
### llm
|
||
|
||
```toml
|
||
[commit.generation]
|
||
command = "llm -m claude-haiku-4.5"
|
||
```
|
||
|
||
### aichat
|
||
|
||
```toml
|
||
[commit.generation]
|
||
command = "aichat -m claude:claude-haiku-4.5"
|
||
```
|
||
|
||
See [LLM commits docs](@/llm-commits.md) 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.
|
||
|
||
```toml
|
||
[list]
|
||
summary = false # Enable LLM branch summaries (requires [commit.generation])
|
||
|
||
full = false # Show CI status and LLM summaries (--full)
|
||
branches = false # Include branches without worktrees (--branches)
|
||
remotes = false # Include remote-only branches (--remotes)
|
||
|
||
json-schema = 2 # JSON output schema: 2 (envelope) or 1 (bare array, the current default); unset emits 1 with a warning
|
||
|
||
columns = ["branch", "status", "ci", "path"] # Columns to show, in order — built-ins or custom headers (omit for the default set)
|
||
|
||
timeout-ms = 0 # Wall-clock budget for the entire collect phase; 0 disables
|
||
```
|
||
|
||
`columns` selects and orders the columns the `wt list` table and the `wt switch`
|
||
picker render; `--format json` ignores it and always emits every field. Omit it
|
||
for the default set. It is meant to drive a per-invocation
|
||
[alias](@/extending.md#aliases) (`wt --config-set 'list.columns=[…]' list`),
|
||
giving a named view without disturbing the default `wt list`. A static setting
|
||
works but pins one layout over a table that otherwise adapts to `--full` and
|
||
terminal width.
|
||
|
||
Valid built-in names:
|
||
|
||
- `branch` — The branch name
|
||
- `status` — Git status symbols, plus any user-defined status
|
||
- `working-diff` — Uncommitted line changes against `HEAD` (header `HEAD±`)
|
||
- `ahead-behind` — Commits ahead of and behind the default branch (header `main↕`)
|
||
- `branch-diff` — Line changes against the default branch (header `main…±`)
|
||
- `summary` — An LLM-generated summary of the branch
|
||
- `upstream` — Commits ahead of and behind the upstream tracking branch (header `Remote⇅`)
|
||
- `ci` — CI status of the head commit
|
||
- `path` — The worktree's path
|
||
- `url` — Dev-server URL from the `[list] url` template
|
||
- `commit` — The head commit's short hash
|
||
- `age` — Time since the last commit
|
||
- `message` — The head commit's subject
|
||
|
||
A selection mixes built-ins with [custom columns](#custom-columns), each named
|
||
by its `[list.custom-columns]` header (`columns = ["branch", "Ticket", "ci"]`),
|
||
and is exhaustive: only the listed columns render. Omit `columns` to keep the
|
||
default set, where custom columns append automatically. A built-in name wins a
|
||
header collision; the gutter type indicator always shows.
|
||
|
||
Listing a column forces it on, space permitting: `ci` shows without `--full`,
|
||
since `--full` only bundles columns into the default table rather than gating a
|
||
named one. A column whose data source is missing still stays hidden — `summary`
|
||
needs an LLM command (`[commit.generation]`), `url` needs a `[list] url`
|
||
template — since listing can't supply the data.
|
||
|
||
#### Custom columns
|
||
|
||
<span class="badge-experimental"></span>
|
||
|
||
Custom columns add per-branch context to the `wt list` table. Each
|
||
`[list.custom-columns]` entry is a column: the key is the header, the template
|
||
renders each row's cell.
|
||
|
||
```toml
|
||
[list.custom-columns.Ticket]
|
||
template = "{{ vars.ticket }}" # Required; the result is the cell text
|
||
width = 20 # Optional max display width (default: 40)
|
||
priority = 9 # Optional drop order when the terminal narrows;
|
||
# lower = kept longer (default: 9, the URL band)
|
||
```
|
||
|
||
Templates may reference `{{ branch }}`, `{{ worktree_path }}`,
|
||
`{{ worktree_name }}` (empty for branch-only rows), and two per-branch
|
||
namespaces:
|
||
|
||
- `{{ vars.* }}` — values stored with
|
||
[`wt config state vars set`](@/config.md#wt-config-state-vars).
|
||
- `{{ git.branch.* }}` — the branch's own git config under `branch.<name>.*`,
|
||
read straight from `git config` (e.g. `{{ git.branch.jira }}` for a key you
|
||
set yourself, or the git-native `description`). Git lowercases config variable
|
||
names, so `branch.<name>.nvciShelf` reads as `{{ git.branch.nvcishelf }}`.
|
||
|
||
All standard filters work (`sanitize`, `hash_port`, `codename`, …). A row
|
||
where the template renders empty (e.g. a branch without the key) shows an
|
||
empty cell; a column that is empty for every row is dropped from the table.
|
||
`wt list --format json` includes the rendered values under `columns`.
|
||
|
||
A `Jira` column reading a key kept in git config, and a `Summary` column
|
||
showing just the first line of the git-native branch description:
|
||
|
||
```toml
|
||
[list.custom-columns.Jira]
|
||
template = "{{ git.branch.jira }}"
|
||
|
||
[list.custom-columns.Summary]
|
||
template = "{{ git.branch.description | lines | first }}"
|
||
```
|
||
|
||
### Commit
|
||
|
||
Shared by `wt step commit`, `wt step squash`, and `wt merge`.
|
||
|
||
```toml
|
||
[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.
|
||
|
||
```toml
|
||
[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)
|
||
```
|
||
|
||
### Remove
|
||
|
||
Persistent flag values for `wt remove`. Override on command line as needed.
|
||
|
||
```toml
|
||
[remove]
|
||
delete-branch = true # Delete branch after removal (--no-delete-branch to keep)
|
||
```
|
||
|
||
### Switch
|
||
|
||
```toml
|
||
[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
|
||
```
|
||
|
||
### Step
|
||
|
||
```toml
|
||
[step.copy-ignored]
|
||
exclude = [] # Additional excludes (e.g., [".cache/", ".turbo/"])
|
||
```
|
||
|
||
Built-in excludes (VCS metadata and tool-state directories) always apply; [the `wt step copy-ignored` docs](@/step.md#wt-step-copy-ignored) list them. User config and project config exclusions are combined.
|
||
|
||
### Aliases
|
||
|
||
Command templates that run as `wt <name>`. See the [Extending Worktrunk guide](@/extending.md#aliases) for usage and flags.
|
||
|
||
```toml
|
||
[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](@/config.md#project-configuration) `[aliases]` section instead.
|
||
|
||
### User project-specific settings
|
||
|
||
User config can include a `[projects]` table for project-specific settings — worktree layout, setting overrides, anything else — separate from the [project config](@/config.md#project-configuration) shared with teammates.
|
||
|
||
Entries are keyed by project identifier — `<host>/<owner>/<repo>` derived from the primary remote URL (no `.git` suffix), or the canonical repo path when there is no remote. Run `wt config show` inside the repo to see the identifier for the current project; it appears in the `PROJECT CONFIG` section as `Identifier: …`.
|
||
|
||
Scalar values (like `worktree-path`) replace the global value; everything else (hooks, aliases, etc.) appends, global first. See [how the layers rank](@/config.md#precedence).
|
||
|
||
```toml
|
||
[projects."github.com/user/repo"]
|
||
worktree-path = ".worktrees/{{ branch | sanitize }}"
|
||
list.full = true
|
||
merge.squash = false
|
||
remove.delete-branch = false
|
||
pre-start.env = "cp .env.example .env"
|
||
step.copy-ignored.exclude = [".repo-local-cache/"]
|
||
aliases.deploy = "make deploy BRANCH={{ branch }}"
|
||
```
|
||
|
||
#### Matching several repositories with one entry
|
||
|
||
A key containing `*` matches any run of characters, `/` included, so one entry covers a whole host or namespace — including nested groups. `*` is the only wildcard; every other character, `.` among them, is literal.
|
||
|
||
```toml
|
||
# Every repository on a self-hosted forge whose hostname carries no brand
|
||
[projects."git.company.example/*"]
|
||
forge.platform = "gitlab"
|
||
|
||
# Everything under one namespace shares a layout
|
||
[projects."git.company.example/platform/*"]
|
||
worktree-path = ".worktrees/{{ branch | sanitize }}"
|
||
```
|
||
|
||
Every matching entry applies, least- to most-specific, following the rule above: a more specific entry — `git.company.example/platform/*` over `git.company.example/*` — wins where both set the same setting, while hooks and aliases from every matching entry all run, least-specific first. A literal key is the most specific of all; specificity is the count of non-`*` characters in the key. End a host-wide key with `/*` — a bare `git.company.example*` also covers hosts whose names merely start with that string.
|
||
|
||
`approved-commands` matches the same way, so a pattern entry approves its commands for every repository it covers. Only a key written by hand is ever a pattern: `wt config approvals add` and the interactive prompt record under the exact identifier, and `wt config approvals clear` removes only that exact entry, leaving a pattern other repositories share intact.
|
||
|
||
#### Forge platform and hostname
|
||
|
||
`forge` names the forge for the matched repositories — the user-level counterpart of the project config's [forge platform](@/config.md#forge-platform) block, for a self-hosted host whose name carries no `github`, `gitlab`, or `gitea` for detection to read.
|
||
|
||
```toml
|
||
[projects."git.company.example/*"]
|
||
forge.platform = "gitlab" # or "github", "gitea" (experimental), "azure-devops" (experimental)
|
||
forge.hostname = "api.git.company.example" # API host, when the remote's own host isn't it
|
||
```
|
||
|
||
Both fields describe the host rather than the repository, which is why a pattern keyed to a hostname suits them, and why an SSH alias resolved through `~/.ssh/config` — where the name in the remote URL is local to one machine — belongs here rather than in a repository's committed config. A repository's own `[forge]` block still wins over any entry here, field by field: a repository that sets only `platform` still takes a matching entry's `hostname`.
|
||
|
||
Hooks support all three [hook forms](@/hook.md#hook-forms). A table runs multiple commands concurrently; an array-of-tables pipeline runs steps in sequence. The dotted-key examples below are equivalent to the table forms — TOML treats `projects."github.com/user/repo".post-start.server = "..."` and a `[projects."github.com/user/repo".post-start]` table the same way:
|
||
|
||
```toml
|
||
# Single command
|
||
[projects."github.com/user/repo"]
|
||
post-start = "mise trust"
|
||
|
||
# Multiple commands, running concurrently
|
||
[projects."github.com/user/repo".post-start]
|
||
mise = "mise trust"
|
||
server = "npm run dev"
|
||
|
||
# Pipeline: steps run in sequence
|
||
[[projects."github.com/user/repo".post-start]]
|
||
install = "npm ci"
|
||
|
||
[[projects."github.com/user/repo".post-start]]
|
||
build = "npm run build"
|
||
server = "npm run dev"
|
||
```
|
||
|
||
### 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
|
||
- `{{ user_guidance }}`, `{{ project_guidance }}` — rendered append fragments (see [Appending to the prompt](@/config.md#appending-to-the-prompt))
|
||
|
||
Default template:
|
||
|
||
<!-- DEFAULT_TEMPLATE_START -->
|
||
```toml
|
||
[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>
|
||
{% if user_guidance %}
|
||
<user-guidance>
|
||
{{ user_guidance }}
|
||
</user-guidance>
|
||
{% endif %}{% if project_guidance %}
|
||
<project-guidance>
|
||
{{ project_guidance }}
|
||
</project-guidance>
|
||
{% endif %}
|
||
<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):
|
||
|
||
- `{{ commit_details }}` — list of commits being squashed; each renders as its subject and exposes `.subject` / `.body`
|
||
- `{{ target_branch }}` — merge target branch
|
||
|
||
Default template:
|
||
|
||
<!-- DEFAULT_SQUASH_TEMPLATE_START -->
|
||
```toml
|
||
[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>
|
||
{% if user_guidance %}
|
||
<user-guidance>
|
||
{{ user_guidance }}
|
||
</user-guidance>
|
||
{% endif %}{% if project_guidance %}
|
||
<project-guidance>
|
||
{{ project_guidance }}
|
||
</project-guidance>
|
||
{% endif %}
|
||
<commits branch="{{ branch }}" target="{{ target_branch }}">
|
||
{% for detail in commit_details %}- {{ detail.subject }}
|
||
{% endfor %}</commits>
|
||
|
||
<diffstat>
|
||
{{ git_diff_stat }}
|
||
</diffstat>
|
||
|
||
<diff>
|
||
{{ git_diff }}
|
||
</diff>
|
||
|
||
"""
|
||
```
|
||
<!-- DEFAULT_SQUASH_TEMPLATE_END -->
|
||
|
||
#### Appending to the prompt
|
||
|
||
<span class="badge-experimental"></span>
|
||
|
||
`template-append` adds personal conventions to the commit and squash prompts without restating the whole template:
|
||
|
||
```toml
|
||
[commit.generation]
|
||
template-append = """
|
||
- Explain the rationale in the body, not just the change
|
||
"""
|
||
```
|
||
|
||
How the fragment renders, and the project-config counterpart: [the LLM commits guide](@/llm-commits.md#appending-to-the-prompt).
|
||
|
||
## Hooks
|
||
|
||
See [`wt hook`](@/hook.md) for hook types, execution order, template variables, and examples. User hooks apply to all projects; [project hooks](@/config.md#project-configuration) apply only to that repository.
|
||
<!-- USER_CONFIG_END -->
|
||
<!-- PROJECT_CONFIG_START -->
|
||
# Project Configuration
|
||
|
||
Project configuration lets teams share repository-specific settings — hooks, dev server URLs, and other defaults. The file lives in `.config/wt.toml` and is typically checked into version control.
|
||
|
||
To create a starter file with commented-out examples, run `wt config create --project`.
|
||
|
||
## Hooks
|
||
|
||
Project hooks apply to this repository only. See [`wt hook`](@/hook.md) for hook types, execution order, and examples.
|
||
|
||
```toml
|
||
pre-start = "npm ci"
|
||
post-start = "npm run dev"
|
||
pre-merge = "npm test"
|
||
```
|
||
|
||
## Dev server URL
|
||
|
||
URL column in `wt list` (dimmed when port not listening):
|
||
|
||
```toml
|
||
[list]
|
||
url = "http://localhost:{{ branch | hash_port }}"
|
||
```
|
||
|
||
## Forge platform
|
||
|
||
The forge is read from the remote's hostname: any host carrying `github`, `gitlab`, or `gitea` anywhere in it, plus the Azure DevOps service domains. Name the forge explicitly for a host carrying none of those, such as a Forgejo instance at `forge.example.com`:
|
||
|
||
```toml
|
||
[forge]
|
||
platform = "github" # or "gitlab", "gitea" (experimental), "azure-devops" (experimental)
|
||
hostname = "github.example.com" # Example: API host (GHE / self-hosted GitLab)
|
||
```
|
||
|
||
When many repositories share one self-hosted host, name it once in user config with a [pattern-keyed `[projects]` entry](@/config.md#user-project-specific-settings) instead of repeating this block in each repo. A repository's own `[forge]` still wins, field by field.
|
||
|
||
## Commit-message append
|
||
|
||
<span class="badge-experimental"></span>
|
||
|
||
`template-append` adds project-wide conventions to the LLM commit and squash prompts, shared so every teammate's LLM sees the same style guide:
|
||
|
||
```toml
|
||
[commit.generation]
|
||
template-append = """
|
||
- Use conventional commits (feat:, fix:, docs:, …)
|
||
- Reference the relevant issue ID in the body
|
||
"""
|
||
```
|
||
|
||
The first time the fragment is used (and whenever it changes), `wt` prompts the user to approve it — the same one-shot gate as project-defined hooks. Only `template-append` is honored from the project file; the LLM command and the main prompt template stay in [user config](@/config.md), since they describe per-developer environment (which CLI is installed, which agent the developer prefers). How the fragment renders: [the LLM commits guide](@/llm-commits.md#appending-to-the-prompt).
|
||
|
||
## Copy-ignored excludes
|
||
|
||
Additional excludes for `wt step copy-ignored`:
|
||
|
||
```toml
|
||
[step.copy-ignored]
|
||
exclude = [".cache/", ".turbo/"]
|
||
```
|
||
|
||
Built-in excludes (VCS metadata and tool-state directories) always apply; [the `wt step copy-ignored` docs](@/step.md#wt-step-copy-ignored) list them. User config and project config exclusions are combined.
|
||
|
||
## Aliases
|
||
|
||
Command templates that run as `wt <name>`. See the [Extending Worktrunk guide](@/extending.md#aliases) for usage and flags.
|
||
|
||
```toml
|
||
[aliases]
|
||
deploy = "make deploy BRANCH={{ branch }}"
|
||
url = "echo http://localhost:{{ branch | hash_port }}"
|
||
```
|
||
|
||
Aliases defined here are shared with teammates. For personal aliases, use the [user config](@/config.md#aliases) `[aliases]` section instead.
|
||
<!-- PROJECT_CONFIG_END -->
|
||
|
||
# Shell Integration
|
||
|
||
Worktrunk needs shell integration to change directories when switching worktrees. Install with:
|
||
|
||
{{ terminal(cmd="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. 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:
|
||
|
||
| Config | Environment Variable |
|
||
|--------|---------------------|
|
||
| `worktree-path` | `WORKTRUNK_WORKTREE_PATH` |
|
||
| `commit.generation.command` | `WORKTRUNK_COMMIT__GENERATION__COMMAND` |
|
||
| `commit.stage` | `WORKTRUNK_COMMIT__STAGE` |
|
||
|
||
### Example: CI/testing override
|
||
|
||
Override the LLM command in CI to use a mock:
|
||
|
||
{{ terminal(cmd="WORKTRUNK_COMMIT__GENERATION__COMMAND=__WT_QUOT__echo 'test: automated commit'__WT_QUOT__ wt merge") }}
|
||
|
||
### Other environment variables
|
||
|
||
| Variable | Purpose |
|
||
|----------|---------|
|
||
| `WORKTRUNK_BIN` | Override binary path for shell wrappers; useful for testing dev builds |
|
||
| `WORKTRUNK_CONFIG_PATH` | Override user config file location |
|
||
| `WORKTRUNK_SYSTEM_CONFIG_PATH` | Override system config file location |
|
||
| `WORKTRUNK_PROJECT_CONFIG_PATH` | Override project config file location (defaults to `.config/wt.toml`); relative paths resolve from the worktree root |
|
||
| `XDG_CONFIG_DIRS` | Colon-separated system config directories (default: `/etc/xdg`) |
|
||
| `WORKTRUNK_DIRECTIVE_CD_FILE` | Internal: set by shell wrappers. wt writes a raw path; the wrapper `cd`s to it |
|
||
| `WORKTRUNK_DIRECTIVE_EXEC_FILE` | Internal: set by shell wrappers. wt writes shell commands; the wrapper sources the file |
|
||
| `WORKTRUNK_SHELL_CWD` | Internal: set by wt on alias and hook bodies, so a nested `wt` preserves the user's subdirectory |
|
||
| `WORKTRUNK_SHELL` | Internal: set by shell wrappers to indicate shell type (e.g., `powershell`) |
|
||
| `WORKTRUNK_COMPLETE_NAME` | Internal: set by shell wrappers to the command name completions register under (defaults to the binary name) |
|
||
| `WORKTRUNK_MAX_CONCURRENT_COMMANDS` | Max parallel git commands (default: 32). Lower if hitting file descriptor limits. |
|
||
| `WORKTRUNK_VERBOSE` | Verbosity level (`0`/`1`/`2`), like `-v`/`-vv` but applied everywhere — including shell completion, which no flag can reach |
|
||
| `RUST_LOG` | Logging directive (e.g. `worktrunk=debug`); overrides the verbosity baseline for what reaches stderr |
|
||
| `NO_COLOR` | Disable colored output ([standard](https://no-color.org/)) |
|
||
| `CLICOLOR_FORCE` | Force colored output even when not a TTY |
|
||
|
||
## Inline config overrides (`--config-set`)
|
||
|
||
`--config-set <toml>` overrides any user config key for a single invocation. The value is a TOML fragment, so arrays and tables work directly; the flag is global (works before or after the subcommand), repeatable, and a later `--config-set` replaces an earlier one for the same key.
|
||
|
||
{{ terminal(cmd="wt --config-set list.full=true list|||wt step copy-ignored --config-set 'step.copy-ignored.exclude=[__WT_QUOT__target__WT_QUOT__, __WT_QUOT__dist__WT_QUOT__]'") }}
|
||
|
||
This composes with aliases — an alias body can invoke `wt --config-set … <command>` to render a named view without changing the saved config.
|
||
|
||
## Precedence
|
||
|
||
Sources closer to the invocation rank higher (user config above system config), and within a config file a [project entry](@/config.md#user-project-specific-settings) outranks the global key of the same name. So `worktree-path` comes from the first of these that sets it:
|
||
|
||
1. `--config-set 'worktree-path = …'`
|
||
2. `WORKTRUNK_WORKTREE_PATH`
|
||
3. `[projects."github.com/owner/repo"]` in the config file
|
||
4. global `worktree-path` in the config file
|
||
|
||
A `--config-set` that names a project entry is both the highest layer and the most specific key, so it beats the same flag's global key:
|
||
|
||
{{ terminal(cmd="wt --config-set 'projects.__WT_QUOT__github.com/owner/repo__WT_QUOT__.worktree-path = __WT_QUOT__/tmp/scratch__WT_QUOT__' switch --create feature") }}
|
||
|
||
Hooks, aliases and `step.copy-ignored.exclude` accumulate rather than replace, so an env-set hook and a project's hook both run.
|
||
|
||
## Command reference
|
||
|
||
{% terminal() %}
|
||
wt config - Manage user & project configs
|
||
|
||
Includes shell integration, hooks, and saved state.
|
||
|
||
Usage: <b><span class=c>wt config</span></b> <span class=c>[OPTIONS]</span> <span class=c><COMMAND></span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>shell</span></b> Shell integration setup
|
||
<b><span class=c>create</span></b> Create configuration file
|
||
<b><span class=c>show</span></b> Show configuration files & locations
|
||
<b><span class=c>update</span></b> Update deprecated config settings
|
||
<b><span class=c>approvals</span></b> Manage command approvals
|
||
<b><span class=c>alias</span></b> Inspect and preview aliases
|
||
<b><span class=c>plugins</span></b> Plugin management
|
||
<b><span class=c>state</span></b> Manage internal data and cache
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
# 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:
|
||
|
||
{{ terminal(cmd="wt config show --full") }}
|
||
|
||
This tests:
|
||
- **CI tool status** — Whether `gh` (GitHub) or `glab` (GitLab) is installed and authenticated
|
||
- **Commit generation** — Whether the LLM command can generate commit messages
|
||
- **Version check** — Whether a newer version is available on GitHub
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config show - Show configuration files & locations
|
||
|
||
Usage: <b><span class=c>wt config show</span></b> <span class=c>[OPTIONS]</span>
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>--full</span></b>
|
||
Run diagnostic checks (CI tools, commit generation, version)
|
||
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Output:</span></b>
|
||
<b><span class=c>--format</span></b><span class=c> <FORMAT></span>
|
||
Output format
|
||
|
||
[default: text]
|
||
[possible values: text, json]
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config approvals
|
||
|
||
Manage command approvals.
|
||
|
||
Project hooks and project aliases prompt for approval on first run to prevent untrusted projects from running arbitrary commands. Approvals from both flows are stored together.
|
||
|
||
### Examples
|
||
|
||
List commands and their approval status for current project:
|
||
{{ terminal(cmd="wt config approvals list") }}
|
||
|
||
Pre-approve all hook and alias commands for current project:
|
||
{{ terminal(cmd="wt config approvals add") }}
|
||
|
||
Pre-approve without prompting, for a container or CI job:
|
||
{{ terminal(cmd="wt config approvals add --yes") }}
|
||
|
||
Clear approvals for current project:
|
||
{{ terminal(cmd="wt config approvals clear") }}
|
||
|
||
Clear only approvals for commands no longer in the project config:
|
||
{{ terminal(cmd="wt config approvals clear --stale") }}
|
||
|
||
Clear global approvals:
|
||
{{ terminal(cmd="wt config approvals clear --global") }}
|
||
|
||
Check whether an unattended run would stop for approval:
|
||
{{ terminal(cmd="wt config approvals list --format=json | jq -r .state") }}
|
||
|
||
### How approvals work
|
||
|
||
Approved commands are saved to `~/.config/worktrunk/approvals.toml`. Re-approval is required when the command template changes or the project moves.
|
||
|
||
`--yes` bypasses the prompt, and what it leaves behind depends on the command it is passed to. On a command that runs project commands it grants consent for that run alone and records nothing, so the next run asks again. On `wt config approvals add` the record is the whole point, so the approvals are written — which is how an unattended environment pre-approves a project it has just cloned.
|
||
|
||
### Reading approval state
|
||
|
||
`wt config approvals list` reads the state without prompting or writing it, so an orchestrator can find out whether a non-interactive run will stop for approval before scheduling one. `--format=json` emits:
|
||
|
||
```json
|
||
{
|
||
"state": "approval_required",
|
||
"commands": [
|
||
{"phase": "post-start", "name": "dev", "template": "npm run dev", "approved": false},
|
||
{"phase": "pre-merge", "template": "cargo test", "approved": true}
|
||
],
|
||
"stale": ["some removed command"]
|
||
}
|
||
```
|
||
|
||
`state` is `no_commands` (the project declares none), `approval_required` (at least one is unapproved), or `approved`. `name` is absent for an unnamed command and for the commit-template fragment.
|
||
|
||
`stale` is separate rather than a fourth `state`, because it co-occurs with all three: these are approvals recorded earlier whose command has since been edited or removed from the project config. They are what `--yes` would silently re-approve, so an orchestrator preserving the approval model reads them before choosing that flag.
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config approvals - Manage command approvals
|
||
|
||
Usage: <b><span class=c>wt config approvals</span></b> <span class=c>[OPTIONS]</span> <span class=c><COMMAND></span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>list</span></b> List project commands and their approval status
|
||
<b><span class=c>add</span></b> Store approvals in approvals.toml
|
||
<b><span class=c>clear</span></b> Clear approved commands from approvals.toml
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config alias
|
||
|
||
Inspect and preview aliases.
|
||
|
||
Aliases are command templates configured in user (`~/.config/worktrunk/config.toml`) or project (`.config/wt.toml`) config and run as `wt <name>`. See the [Extending Worktrunk guide](@/extending.md#aliases) for the configuration format.
|
||
|
||
### Examples
|
||
|
||
Show every configured alias's template:
|
||
{{ terminal(cmd="wt config alias show") }}
|
||
|
||
Show the template for `deploy`:
|
||
{{ terminal(cmd="wt config alias show deploy") }}
|
||
|
||
Preview an invocation without running it:
|
||
{{ terminal(cmd="wt config alias dry-run deploy|||wt config alias dry-run deploy -- --env=staging") }}
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config alias - Inspect and preview aliases
|
||
|
||
Usage: <b><span class=c>wt config alias</span></b> <span class=c>[OPTIONS]</span> <span class=c><COMMAND></span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>show</span></b> Show an alias's template, or all aliases' templates
|
||
<b><span class=c>dry-run</span></b> Preview an alias invocation with template expansion
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config state
|
||
|
||
Manage internal data and cache.
|
||
|
||
State is stored in `.git/` (config entries and log files), separate from configuration files.
|
||
|
||
### Keys
|
||
|
||
- **cache**: [Regenerable caches — CI status, summaries, git commands, hints, and the `wt switch -` target](@/config.md#wt-config-state-cache)
|
||
- **default-branch**: [The repository's default branch (`main`, `master`, etc.)](@/config.md#wt-config-state-default-branch)
|
||
- **marker**: [Custom status marker for a branch (shown in `wt list`)](@/config.md#wt-config-state-marker)
|
||
- **vars**: <span class="badge-experimental"></span> [Custom variables per branch](@/config.md#wt-config-state-vars)
|
||
- **logs**: [Operation and debug logs](@/config.md#wt-config-state-logs)
|
||
|
||
### Examples
|
||
|
||
Get the default branch:
|
||
{{ terminal(cmd="wt config state default-branch") }}
|
||
|
||
Set the default branch manually:
|
||
{{ terminal(cmd="wt config state default-branch set main") }}
|
||
|
||
Set a marker for current branch:
|
||
{{ terminal(cmd="wt config state marker set 🚧") }}
|
||
|
||
Store arbitrary data:
|
||
{{ terminal(cmd="wt config state vars set env=staging") }}
|
||
|
||
Drop the regenerable caches:
|
||
{{ terminal(cmd="wt config state cache clear") }}
|
||
|
||
Show all stored state:
|
||
{{ terminal(cmd="wt config state get") }}
|
||
|
||
Clear all stored state:
|
||
{{ terminal(cmd="wt config state clear") }}
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config state - Manage internal data and cache
|
||
|
||
Usage: <b><span class=c>wt config state</span></b> <span class=c>[OPTIONS]</span> <span class=c><COMMAND></span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>get</span></b> Get all stored state
|
||
<b><span class=c>clear</span></b> Clear all stored state
|
||
<b><span class=c>cache</span></b> Regenerable caches
|
||
<b><span class=c>default-branch</span></b> Default branch detection and override
|
||
<b><span class=c>logs</span></b> Operation and debug logs
|
||
<b><span class=c>marker</span></b> Branch markers
|
||
<b><span class=c>vars</span></b> [experimental] Custom variables per branch
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config state cache
|
||
|
||
Regenerable caches.
|
||
|
||
View or drop worktrunk's regenerable caches in one place. Everything here is rebuilt on demand — clearing only forces recomputation, never data loss.
|
||
|
||
### What's cached
|
||
|
||
- **CI status** — GitHub/GitLab CI per branch (30–60s TTL), shown in [`wt list`](@/list.md#ci-status), plus the largest PR/MR number seen (sizes the CI column)
|
||
- **Summaries** — LLM-generated branch summaries (`wt list --full`, `wt switch` preview)
|
||
- **Git commands** — SHA-keyed disk caches: merge-tree, ancestry, diff-stats, and `wt switch` preview renders
|
||
- **Hints** — one-time hints already shown in this repo
|
||
- **Previous branch** — the `wt switch -` target, re-recorded on the next switch
|
||
|
||
`cache clear` drops all of the above with no prompt. It re-shows one-time hints and forgets the `wt switch -` target until the next switch — both repopulate on their own.
|
||
|
||
Without a subcommand, runs `get`.
|
||
|
||
### Examples
|
||
|
||
Show cache contents:
|
||
{{ terminal(cmd="wt config state cache") }}
|
||
|
||
Drop all caches:
|
||
{{ terminal(cmd="wt config state cache clear") }}
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config state cache - Regenerable caches
|
||
|
||
Usage: <b><span class=c>wt config state cache</span></b> <span class=c>[OPTIONS]</span> <span class=c>[COMMAND]</span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>get</span></b> Show cache contents
|
||
<b><span class=c>clear</span></b> Drop all caches
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Output:</span></b>
|
||
<b><span class=c>--format</span></b><span class=c> <FORMAT></span>
|
||
Output format (text, json) [default: text]
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config state default-branch
|
||
|
||
Default branch detection and override.
|
||
|
||
Useful in scripts to avoid hardcoding `main` or `master`:
|
||
|
||
{{ terminal(cmd="git rebase $(wt config state default-branch)") }}
|
||
|
||
In a hook or alias template, prefer the `{{ default_branch }}` [template variable](@/hook.md#template-variables); `$(wt config state default-branch)` is for plain shell scripts.
|
||
|
||
Without a subcommand, runs `get`. Use `set` to override, or `clear` then `get` to re-detect.
|
||
|
||
`default-branch get` resolves the value and caches it on a miss; the aggregate `wt config state get` only reports the cache (read-only), so it can show `(none)` until something populates it.
|
||
|
||
### Detection
|
||
|
||
Worktrunk detects the default branch automatically:
|
||
|
||
1. **Worktrunk cache** — Checks `git config worktrunk.default-branch`
|
||
2. **Git cache** — Detects primary remote and checks its HEAD (e.g., `origin/HEAD`)
|
||
3. **Remote query** — If not cached, queries `git ls-remote` — typically 100ms–2s, abandoned after 10s
|
||
4. **Local inference** — If no remote, or the query was abandoned, infers from local branches
|
||
|
||
Once detected, the result is cached in `worktrunk.default-branch` for fast access. The cache isn't re-validated on every command, so a later change to `origin/HEAD` — a renamed default branch followed by `git remote set-head origin -a` — isn't picked up automatically. `wt config state` flags the drift when the cached value differs from the remote's local HEAD; `set` adopts the new branch and `clear` re-detects.
|
||
|
||
An abandoned remote query is the one case that isn't cached: the branch it inferred locally answers that command, but a value guessed while the remote was unreachable would otherwise become permanent, so the next command queries again.
|
||
|
||
The local inference fallback uses these heuristics in order:
|
||
- If only one local branch exists, uses it
|
||
- For bare repos or empty repos, checks `symbolic-ref HEAD`
|
||
- Checks `git config init.defaultBranch`
|
||
- Looks for common names: `main`, `master`, `develop`, `trunk`
|
||
|
||
If none of these match, detection fails; set it explicitly with `wt config state default-branch set BRANCH`.
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config state default-branch - Default branch detection and override
|
||
|
||
Usage: <b><span class=c>wt config state default-branch</span></b> <span class=c>[OPTIONS]</span> <span class=c>[COMMAND]</span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>get</span></b> Get the default branch
|
||
<b><span class=c>set</span></b> Set the default branch
|
||
<b><span class=c>clear</span></b> Clear the default branch cache
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config state logs
|
||
|
||
Operation and debug logs.
|
||
|
||
View and manage log files — hook output, command audit trail, and debug diagnostics.
|
||
|
||
### What's logged
|
||
|
||
Three 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. Rotates to `commands.jsonl.old` at 1MB (~2MB total). Fields:
|
||
|
||
| Field | Description |
|
||
|-------|-------------|
|
||
| `ts` | ISO 8601 timestamp |
|
||
| `wt` | The `wt` command that triggered this (e.g., `wt hook pre-merge --yes`) |
|
||
| `label` | What ran (e.g., `pre-merge user:lint`, `commit.generation`) |
|
||
| `cmd` | Shell command executed |
|
||
| `exit` | Exit code (`null` for background commands) |
|
||
| `dur_ms` | Duration in milliseconds (`null` for background commands) |
|
||
|
||
The command log appends entries and is not branch-specific — it records all activity across all worktrees.
|
||
|
||
#### Hook output logs
|
||
|
||
Hook output lives in per-branch subtrees under `.git/wt/logs/{branch}/`:
|
||
|
||
| Operation | Log path |
|
||
|-----------|----------|
|
||
| Background hooks | `{branch}/{source}/{hook-type}/{name}.log` |
|
||
| Background removal | `{branch}/internal/remove.log` |
|
||
|
||
All `post-*` hooks (post-start, post-switch, post-commit, post-merge) run in the background and produce log files. Source is `user` or `project`. Branch and hook names are sanitized for filesystem safety (invalid characters → `-`; short collision-avoidance hash appended). Same operation on same branch overwrites the previous log. Removing a branch clears its subtree; orphans from deleted branches can be swept with `wt config state logs clear`.
|
||
|
||
#### Diagnostic files
|
||
|
||
| File | Created when |
|
||
|------|-------------|
|
||
| `trace.log` | Running with `-vv` |
|
||
| `trace.jsonl` | Running with `-vv` |
|
||
| `subprocess.log` | Running with `-vv` |
|
||
| `diagnostic.md` | Running with `-vv` |
|
||
|
||
`trace.log` is the human-readable trace at `-vv` — each command's start (`$ …`) and completion (`✓`/`✗ … 12.3ms`), in-process spans, milestones, and bounded subprocess previews. `trace.jsonl` is the same event stream as one JSON object per line, for machines (`jq`, chrome://tracing); `wt config state logs profile` reads it to summarize a performance report (where time went, parallelism, redundant commands). `subprocess.log` holds the raw uncapped subprocess stdout/stderr bodies. `diagnostic.md` is a markdown bug-report bundle that leads with that same performance profile and inlines `trace.log`; `wt` prints a `gh gist create` command pointing at it. All four are overwritten on each `-vv` run.
|
||
|
||
### Location
|
||
|
||
All logs are stored in `.git/wt/logs/` (in the main worktree's git directory). All worktrees write to the same directory. Top-level files are shared logs (command audit + diagnostics); top-level directories are per-branch log trees.
|
||
|
||
### Structured output
|
||
|
||
`wt config state logs --format=json` emits three arrays — `command_log`, `hook_output`, `diagnostic`. Each entry carries a `file` (relative), `path` (absolute), `size`, and `modified_at` (unix seconds). Hook-output entries additionally expose `branch`, `source` (`user` / `project` / `internal`), `hook_type` (the `post-*` kind, or `null` for internal ops), and `name`. Filter with `jq` to pick out a specific entry.
|
||
|
||
### Examples
|
||
|
||
List all log files:
|
||
{{ terminal(cmd="wt config state logs") }}
|
||
|
||
Query the command log:
|
||
{{ terminal(cmd="tail -5 .git/wt/logs/commands.jsonl | jq .") }}
|
||
|
||
Path to one hook log (e.g. the `post-start` `server` hook for the current branch):
|
||
{{ terminal(cmd="wt config state logs --format=json | jq -r '.hook_output[] | select(.source == __WT_QUOT__user__WT_QUOT__ and .hook_type == __WT_QUOT__post-start__WT_QUOT__ and (.name | startswith(__WT_QUOT__server__WT_QUOT__))) | .path'") }}
|
||
|
||
Logs for a specific branch:
|
||
{{ terminal(cmd="wt config state logs --format=json | jq '.hook_output[] | select(.branch | startswith(__WT_QUOT__feature__WT_QUOT__))'") }}
|
||
|
||
Clear all logs:
|
||
{{ terminal(cmd="wt config state logs clear") }}
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config state logs - Operation and debug logs
|
||
|
||
Usage: <b><span class=c>wt config state logs</span></b> <span class=c>[OPTIONS]</span> <span class=c>[COMMAND]</span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>get</span></b> List all log file paths
|
||
<b><span class=c>profile</span></b> Performance profile from a trace
|
||
<b><span class=c>clear</span></b> Clear all log files
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Output:</span></b>
|
||
<b><span class=c>--format</span></b><span class=c> <FORMAT></span>
|
||
Output format (text, json) [default: text]
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config state ci-status
|
||
|
||
CI status cache.
|
||
|
||
**Deprecated** — the CI status cache is now part of [`wt config state cache`](@/config.md#wt-config-state-cache). This subcommand still works but prints a deprecation notice.
|
||
|
||
Status values, display symbols, and fetch behavior: [`wt list` CI status](@/list.md#ci-status).
|
||
|
||
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
|
||
|
||
{% terminal() %}
|
||
wt config state ci-status - CI status cache
|
||
|
||
Usage: <b><span class=c>wt config state ci-status</span></b> <span class=c>[OPTIONS]</span> <span class=c>[COMMAND]</span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>get</span></b> Get CI status for a branch
|
||
<b><span class=c>clear</span></b> Clear CI status cache
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Output:</span></b>
|
||
<b><span class=c>--format</span></b><span class=c> <FORMAT></span>
|
||
Output format (text, json) [default: text]
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config state marker
|
||
|
||
Branch markers.
|
||
|
||
Custom status text or emoji shown in the `wt list` Status column.
|
||
|
||
### Display
|
||
|
||
Markers appear at the end of the Status column, after git symbols:
|
||
|
||
{% terminal(cmd="wt list") %}
|
||
  <b>Branch</b> <b>Status</b> <b>HEAD±</b> <b>main↕</b> <b>main…±</b> <b>Remote⇅</b> <b>Commit</b> <b>Age</b> <b>Message</b>
|
||
@ main <span class=d>^</span><span class=d>⇡</span> <span class=g>⇡1</span> <span class=d>33323bc</span> <span class=d>1d</span> <span class=d>Initial commit</span>
|
||
+ feature-api <span class=d>↑</span> 🤖 <span class=g>↑1</span> <span class=g>+1</span> <span class=d>70343f0</span> <span class=d>1d</span> <span class=d>Add REST API endp…</span>
|
||
+ review-ui <span class=c>?</span> <span class=d>↑</span> 💬 <span class=g>↑1</span> <span class=g>+1</span> <span class=d>a585d6e</span> <span class=d>1d</span> <span class=d>Add dashboard com…</span>
|
||
+ wip-docs <span class=c>?</span> <span class=d>–</span> <span class=d>33323bc</span> <span class=d>1d</span> <span class=d>Initial commit</span>
|
||
|
||
<span class=d>○</span> <span class=d>Showing 4 worktrees, 2 with changes, 2 ahead, 1 column hidden</span>
|
||
{% end %}
|
||
|
||
### Use cases
|
||
|
||
- **Work status** — `🚧` WIP, `✅` ready for review, `🔥` urgent
|
||
- **Agent tracking** — The [Claude Code](@/claude-code.md) plugin sets markers automatically
|
||
- **Notes** — Any short text: `"blocked"`, `"needs tests"`
|
||
|
||
### Storage
|
||
|
||
Stored in git config as `worktrunk.state.<branch>.marker`. Set directly with:
|
||
|
||
{{ terminal(cmd="git config worktrunk.state.feature.marker '{__WT_QUOT__marker__WT_QUOT__:__WT_QUOT__🚧__WT_QUOT__,__WT_QUOT__set_at__WT_QUOT__:0}'") }}
|
||
|
||
Without a subcommand, runs `get` for the current branch. For `--branch`, use `get --branch=NAME`.
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config state marker - Branch markers
|
||
|
||
Usage: <b><span class=c>wt config state marker</span></b> <span class=c>[OPTIONS]</span> <span class=c>[COMMAND]</span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>get</span></b> Get marker for a branch
|
||
<b><span class=c>set</span></b> Set marker for a branch
|
||
<b><span class=c>clear</span></b> Clear marker for a branch
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Output:</span></b>
|
||
<b><span class=c>--format</span></b><span class=c> <FORMAT></span>
|
||
Output format (text, json) [default: text]
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
## wt config state vars
|
||
|
||
<span class="badge-experimental"></span>
|
||
|
||
Custom variables per branch.
|
||
|
||
Store custom variables per branch. Values are stored as-is — plain strings or JSON.
|
||
|
||
### Examples
|
||
|
||
Set and get values:
|
||
{{ terminal(cmd="wt config state vars set env=staging|||wt config state vars get env") }}
|
||
|
||
Store JSON:
|
||
{{ terminal(cmd="wt config state vars set config='{__WT_QUOT__port__WT_QUOT__: 3000, __WT_QUOT__debug__WT_QUOT__: true}'") }}
|
||
|
||
List all keys:
|
||
{{ terminal(cmd="wt config state vars list") }}
|
||
|
||
Operate on a different branch:
|
||
{{ terminal(cmd="wt config state vars set env=production --branch=main") }}
|
||
|
||
### Template access
|
||
|
||
Variables are available in [hook templates](@/hook.md#template-variables) as `{{ vars.<key> }}`. Use the `default` filter for keys that may not be set:
|
||
|
||
```toml
|
||
[post-start]
|
||
dev = "ENV={{ vars.env | default('development') }} npm start -- --port {{ vars.port | default('3000') }}"
|
||
```
|
||
|
||
JSON object and array values support dot access:
|
||
|
||
{{ terminal(cmd="wt config state vars set config='{__WT_QUOT__port__WT_QUOT__: 3000, __WT_QUOT__debug__WT_QUOT__: true}'") }}
|
||
```toml
|
||
[post-start]
|
||
dev = "npm start -- --port {{ vars.config.port }}"
|
||
```
|
||
|
||
### Storage format
|
||
|
||
Stored in git config as `worktrunk.state.<branch>.vars.<key>`. Keys must contain only letters, digits and hyphens — dots conflict with git config's section separator, underscores with its variable name format.
|
||
|
||
### Command reference
|
||
|
||
{% terminal() %}
|
||
wt config state vars - [experimental] Custom variables per branch
|
||
|
||
Usage: <b><span class=c>wt config state vars</span></b> <span class=c>[OPTIONS]</span> <span class=c><COMMAND></span>
|
||
|
||
<b><span class=g>Commands:</span></b>
|
||
<b><span class=c>get</span></b> Get a value
|
||
<b><span class=c>list</span></b> List all keys
|
||
<b><span class=c>set</span></b> Set a value
|
||
<b><span class=c>clear</span></b> Clear a key or all keys
|
||
|
||
<b><span class=g>Options:</span></b>
|
||
<b><span class=c>-h</span></b>, <b><span class=c>--help</span></b>
|
||
Print help (see a summary with '-h')
|
||
|
||
<b><span class=g>Global Options:</span></b>
|
||
<b><span class=c>-C</span></b><span class=c> <path></span>
|
||
Working directory for this command
|
||
|
||
<b><span class=c>--config</span></b><span class=c> <path></span>
|
||
User config file path
|
||
|
||
<b><span class=c>--config-set</span></b><span class=c> <toml></span>
|
||
Override config with inline TOML, e.g. --config-set list.full=true (repeatable)
|
||
|
||
<b><span class=c>-v</span></b>, <b><span class=c>--verbose</span></b><span class=c>...</span>
|
||
Verbose output (-v: info logs + hook/alias template variables on stderr; -vv: also debug
|
||
logs and raw subprocess output written to .git/wt/logs/). Set WORKTRUNK_VERBOSE=0|1|2 to
|
||
apply the same level everywhere — including shell completion, which no flag can reach
|
||
|
||
<b><span class=c>-y</span></b>, <b><span class=c>--yes</span></b>
|
||
Skip approval prompts
|
||
{% end %}
|
||
|
||
<!-- END AUTO-GENERATED -->
|