Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2d1cc99
refactor: restructure commit-generation config to [commit.generation]
max-sixty Jan 23, 2026
2860e18
fix: update tests and docs for new commit.generation config format
max-sixty Jan 23, 2026
876730a
fix: update doc comments and add validation for new config path
max-sixty Jan 23, 2026
09aabe5
Merge branch 'main' into commit-gen-claude
max-sixty Jan 23, 2026
9cdef9a
fix: address remaining Codex review issues
max-sixty Jan 23, 2026
a72f26f
refactor: use shell_escape crate for reproduction command escaping
max-sixty Jan 23, 2026
3f15d5b
feat: unify deprecation handling with single .new migration file
max-sixty Jan 23, 2026
c74bb0b
Merge branch 'main' into commit-gen-claude
max-sixty Jan 23, 2026
7a25757
fix: harden commit-generation migration against edge cases
max-sixty Jan 23, 2026
dc38d57
test: add coverage for project-level inline table migration
max-sixty Jan 23, 2026
b3c18eb
test: add integration test for commit-generation deprecation warning
max-sixty Jan 23, 2026
d24964f
test: add integration test for project-level commit-generation deprec…
max-sixty Jan 23, 2026
141d69a
test: add edge case tests for merge_args_into_command
max-sixty Jan 23, 2026
22b4500
test: cover malformed config fallback branches in migration
max-sixty Jan 23, 2026
4cd6d7d
test: add coverage for edge cases in deprecation migration
max-sixty Jan 23, 2026
eccd96c
test: add unit tests for llm helper functions
max-sixty Jan 23, 2026
dfee623
test: add unit tests for config merge logic
max-sixty Jan 23, 2026
ebff819
test: add validation tests for new commit.generation format
max-sixty Jan 23, 2026
34b3bbd
test: add save_to() tests for commit.generation serialization
max-sixty Jan 23, 2026
569be04
docs: fix "Claude CLI" to "Claude Code"
max-sixty Jan 23, 2026
864673d
docs: deduplicate LLM setup from config page
max-sixty Jan 23, 2026
b39e3de
Merge remote-tracking branch 'origin/main' into commit-gen-claude
max-sixty Jan 23, 2026
593f351
fix: trigger deprecation warnings in `wt config show`
max-sixty Jan 23, 2026
c06de14
docs: move aichat into Setup section with other options
max-sixty Jan 23, 2026
e04ed44
docs: reframe LLM setup as examples, not numbered options
max-sixty Jan 23, 2026
a67f7da
Simplify LLM commit generation setup documentation
max-sixty Jan 23, 2026
ca47614
Skip deprecated section key in unknown fields warning
max-sixty Jan 23, 2026
ee81bae
Extract DEPRECATED_SECTION_KEYS constant for reuse
max-sixty Jan 23, 2026
08e1d03
Remove unused has_args field from CommitGenerationDeprecations
max-sixty Jan 23, 2026
027d1ca
Move deprecated section filtering to callers of warn_unknown_fields
max-sixty Jan 23, 2026
96dbbcf
fix: use Unix shell escaping for migration hint command
max-sixty Jan 24, 2026
6922cfe
fix: normalize path separators before shell escaping
max-sixty Jan 24, 2026
e2beb0c
fix: remove shell escaping from migration hint paths
max-sixty Jan 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 7 additions & 33 deletions .claude-plugin/skills/worktrunk/reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,9 @@ worktree-path = "../{{ branch | sanitize }}"

## LLM commit messages

Generate commit messages automatically during merge. Requires an external CLI tool. See [LLM commits docs](https://worktrunk.dev/llm-commits/) for setup and template customization.
Generate commit messages automatically during merge. Requires an external CLI tool.

Using [llm](https://github.com/simonw/llm) (install: `pip install llm llm-anthropic`):

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

Using [aichat](https://github.com/sigoden/aichat):

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

See [Custom prompt templates](#custom-prompt-templates) for inline template options.
See [LLM commits docs](https://worktrunk.dev/llm-commits/) for setup and [Custom prompt templates](#custom-prompt-templates) for template customization.

## Commands

Expand Down Expand Up @@ -182,7 +166,7 @@ Default template:

<!-- DEFAULT_TEMPLATE_START -->
```toml
[commit-generation]
[commit.generation]
template = """
Write a commit message for the staged changes below.

Expand Down Expand Up @@ -227,7 +211,7 @@ Default template:

<!-- DEFAULT_SQUASH_TEMPLATE_START -->
```toml
[commit-generation]
[commit.generation]
squash-template = """
Combine these commits into a single commit message.

Expand Down Expand Up @@ -352,27 +336,17 @@ 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-generation.args` | `WORKTRUNK_COMMIT_GENERATION__ARGS` |
| `commit.generation.command` | `WORKTRUNK_COMMIT__GENERATION__COMMAND` |
| `commit.stage` | `WORKTRUNK_COMMIT__STAGE` |

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

### Array values

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

```bash
export WORKTRUNK_COMMIT_GENERATION__ARGS="-m claude-haiku"
```

### Example: CI/testing override

Override the LLM command in CI to use a mock:

```bash
WORKTRUNK_COMMIT_GENERATION__COMMAND=echo \
WORKTRUNK_COMMIT_GENERATION__ARGS="test: automated commit" \
wt merge
WORKTRUNK_COMMIT__GENERATION__COMMAND="echo 'test: automated commit'" wt merge
```

### Other environment variables
Expand Down
72 changes: 18 additions & 54 deletions .claude-plugin/skills/worktrunk/reference/llm-commits.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,38 @@ Worktrunk generates commit messages by building a templated prompt and piping it

## Setup

### Install llm
Any command that reads a prompt from stdin and outputs a commit message works. Add to `~/.config/worktrunk/config.toml`:

[llm](https://llm.datasette.io/) from Simon Willison is recommended:
### Claude Code

```bash
$ uv tool install -U llm
```toml
[commit.generation]
command = "claude -p --model haiku"
```

### Configure an API key

For Claude (recommended):

```bash
$ llm install llm-anthropic
$ llm keys set anthropic
```
See [Claude Code docs](https://docs.anthropic.com/en/docs/build-with-claude/claude-code) for installation.

For OpenAI:
### llm

```bash
$ llm keys set openai
```toml
[commit.generation]
command = "llm -m claude-haiku-4.5"
```

### Add to user config

Create the config file if it doesn't exist:
Install with `uv tool install llm llm-anthropic && llm keys set anthropic`. See [llm docs](https://llm.datasette.io/).

```bash
$ wt config create
```

Then add the commit generation settings to `~/.config/worktrunk/config.toml`:
### aichat

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

Or for OpenAI:

```toml
[commit-generation]
command = "llm"
args = ["-m", "gpt-5-nano"]
```
See [aichat docs](https://github.com/sigoden/aichat).

## How it works

When worktrunk needs a commit message, it builds a prompt from a template and pipes it to the configured LLM command. The default templates include the git diff and style guidance.
When worktrunk needs a commit message, it builds a prompt from a template and pipes it to the configured command via shell (`sh -c`). Environment variables can be set inline in the command string.

## Usage

Expand Down Expand Up @@ -111,9 +93,8 @@ All variables are available in both templates:
Override the defaults with inline templates or external files:

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

template = """
Write a commit message for this diff. One line, under 50 chars.
Expand Down Expand Up @@ -147,23 +128,6 @@ Templates use [minijinja](https://docs.rs/minijinja/latest/minijinja/syntax/inde

See `wt config create --help` for the full default templates.

## Alternative tools

Any command that reads a prompt from stdin and outputs a commit message works:

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

# Custom script
[commit-generation]
command = "./scripts/generate-commit.sh"
```

See [llm documentation](https://llm.datasette.io/) and [aichat](https://github.com/sigoden/aichat).

## Fallback behavior

When no LLM is configured, worktrunk generates deterministic messages based on changed filenames (e.g., "Changes to auth.rs & config.rs").
5 changes: 3 additions & 2 deletions .claude/skills/writing-user-outputs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,9 @@ output::print(hint_message("Run 'wt list' to see worktrees"))?;
- **`cformat!` for styling** — Never manual escape codes (`\x1b[...`)
- **`cformat!` variables are safe** — Tags like `<bold>` are processed at compile
time only. Runtime variable values are NOT interpreted as markup, so user
content (branch names, commit messages, paths) can be interpolated directly
without escaping. Do NOT escape `<`/`>` in variables — it adds extra chars.
content (branch names, commit messages, paths, shell commands with `<`/`>`
redirects) can be interpolated directly without escaping. Do NOT escape
`<`/`>` in variables — it adds extra chars.
- **`output::` for printing** — Preferred for consistency; direct `println!`/`eprintln!` acceptable
- **YAGNI** — Most output needs no styling
- **Graceful degradation** — Colors auto-adjust (NO_COLOR, TTY detection)
Expand Down
20 changes: 4 additions & 16 deletions dev/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,9 @@
#
# ## LLM commit messages
#
# Generate commit messages automatically during merge. Requires an external CLI tool. See LLM commits docs (https://worktrunk.dev/llm-commits/) for setup and template customization.
# Generate commit messages automatically during merge. Requires an external CLI tool.
#
# Using llm (https://github.com/simonw/llm) (install: `pip install llm llm-anthropic`):
#
# [commit-generation]
# command = "llm"
# args = ["-m", "claude-haiku-4.5"]
#
# Using aichat (https://github.com/sigoden/aichat):
#
# [commit-generation]
# command = "aichat"
# args = ["-m", "claude:claude-haiku-4.5"]
#
# See Custom prompt templates (#custom-prompt-templates) for inline template options.
# See LLM commits docs (https://worktrunk.dev/llm-commits/) for setup and Custom prompt templates (#custom-prompt-templates) for template customization.
#
# ## Commands
#
Expand Down Expand Up @@ -125,7 +113,7 @@
# Default template:
#
# <!-- DEFAULT_TEMPLATE_START -->
# [commit-generation]
# [commit.generation]
# template = """
# Write a commit message for the staged changes below.
#
Expand Down Expand Up @@ -168,7 +156,7 @@
# Default template:
#
# <!-- DEFAULT_SQUASH_TEMPLATE_START -->
# [commit-generation]
# [commit.generation]
# squash-template = """
# Combine these commits into a single commit message.
#
Expand Down
40 changes: 7 additions & 33 deletions docs/content/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,25 +88,9 @@ worktree-path = "../{{ branch | sanitize }}"

## LLM commit messages

Generate commit messages automatically during merge. Requires an external CLI tool. See [LLM commits docs](@/llm-commits.md) for setup and template customization.
Generate commit messages automatically during merge. Requires an external CLI tool.

Using [llm](https://github.com/simonw/llm) (install: `pip install llm llm-anthropic`):

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

Using [aichat](https://github.com/sigoden/aichat):

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

See [Custom prompt templates](#custom-prompt-templates) for inline template options.
See [LLM commits docs](@/llm-commits.md) for setup and [Custom prompt templates](#custom-prompt-templates) for template customization.

## Commands

Expand Down Expand Up @@ -190,7 +174,7 @@ Default template:

<!-- DEFAULT_TEMPLATE_START -->
```toml
[commit-generation]
[commit.generation]
template = """
Write a commit message for the staged changes below.

Expand Down Expand Up @@ -235,7 +219,7 @@ Default template:

<!-- DEFAULT_SQUASH_TEMPLATE_START -->
```toml
[commit-generation]
[commit.generation]
squash-template = """
Combine these commits into a single commit message.

Expand Down Expand Up @@ -360,27 +344,17 @@ 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-generation.args` | `WORKTRUNK_COMMIT_GENERATION__ARGS` |
| `commit.generation.command` | `WORKTRUNK_COMMIT__GENERATION__COMMAND` |
| `commit.stage` | `WORKTRUNK_COMMIT__STAGE` |

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

### Array values

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

```bash
export WORKTRUNK_COMMIT_GENERATION__ARGS="-m claude-haiku"
```

### Example: CI/testing override

Override the LLM command in CI to use a mock:

```bash
WORKTRUNK_COMMIT_GENERATION__COMMAND=echo \
WORKTRUNK_COMMIT_GENERATION__ARGS="test: automated commit" \
wt merge
WORKTRUNK_COMMIT__GENERATION__COMMAND="echo 'test: automated commit'" wt merge
```

### Other environment variables
Expand Down
Loading
Loading