LLM Commit Messages

Worktrunk generates commit messages by building a templated prompt and piping it to an external command. This integrates with wt merge, wt step commit, and wt step squash.

LLM commit message generation demo

Setup

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

Claude Code

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

CLAUDECODE= unsets the nesting guard so claude -p works from within a Claude Code session. The other flags disable tools, skills, settings, and system prompt for fast text-only output. See Claude Code docs for installation.

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'"

Uses the fast mini model with low reasoning effort and an empty system prompt for faster output. Requires jq for JSON parsing. See Codex CLI docs.

Other tools

# opencode — use a fast model variant
command = "opencode run -m anthropic/claude-haiku-4.5 --variant fast"

# llm
command = "llm -m claude-haiku-4.5"

# aichat
command = "aichat -m claude:claude-haiku-4.5"

How it works

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

These examples assume a feature worktree with changes to commit.

wt merge

Squashes all changes (uncommitted + existing commits) into one commit with an LLM-generated message, then merges to the default branch:

$ wt merge
 Squashing 3 commits into a single commit (5 files, +48)...
 Generating squash commit message...
   feat(auth): Implement JWT authentication system
   ...

wt step commit

Stages and commits with LLM-generated message:

$ wt step commit

wt step squash

Squashes branch commits into one with LLM-generated message:

$ wt step squash

See wt merge and wt step for full documentation.

Branch summaries (experimental)

With summary = true and a [commit.generation] command configured, Worktrunk generates LLM branch summaries — one-line descriptions of each branch's changes since the default branch.

Summaries appear in:

Enable in user config:

[list]
summary = true

Disabled by default — when enabled, each branch's diff is sent to the configured LLM for summarization. Results are cached until the diff changes.

Prompt templates

Worktrunk uses minijinja templates (Jinja2-like syntax) to build prompts. There are sensible defaults, but templates are fully customizable.

Custom templates

Override the defaults with inline templates:

[commit.generation]
command = "llm -m claude-haiku-4.5"

template = """
Write a commit message for this diff. One line, under 50 chars.

Branch: {{ branch }}
Diff:
{{ git_diff }}
"""

squash-template = """
Combine these {{ commits | length }} commits into one message:
{% for c in commits %}
- {{ c }}
{% endfor %}

Diff:
{{ git_diff }}
"""

Template variables

VariableDescription
{{ git_diff }}The diff (staged changes or combined diff for squash)
{{ git_diff_stat }}Diff statistics (files changed, insertions, deletions)
{{ branch }}Current branch name
{{ repo }}Repository name
{{ recent_commits }}Recent commit subjects (for style reference)
{{ commits }}Commits being squashed (squash template only)
{{ target_branch }}Merge target branch (squash template only)

Template syntax

Templates use minijinja, which supports:

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

Fallback behavior

When no LLM is configured, worktrunk generates deterministic messages based on changed filenames (e.g., "Changes to auth.rs & config.rs").