Commit message drafting
Detailed commit messages drafted by Claude Code for Git and jj.
The commit history of this repository doubles as its change documentation: each message explains what changed and how. Writing that by hand for every change is tedious, so a hook drafts it, and you review and edit it in the editor before committing.
How it works
One script,
modules/home/vcs/hooks/prepare-commit-msg,
serves both version-control systems:
- Git runs it as a global
prepare-commit-msghook. It skips messages that already exist (-m, templates, merges, squashes, amends) and drafts from the staged diff. - jj runs it through
jj-commit-editor, the configuredui.editor. It only drafts when the description is still empty and the editor buffer contains jj's diff belowJJ: ignore-rest; that diff comes from thebuiltin_draft_commit_description_with_difftemplate. The draft is placed above the existing buffer content.
The script sends the diff to claude --print with the write-commit-msg agent
(see AI tooling). The agent runs on Haiku with
no tools, no MCP servers, no permission prompts, and no saved session.
Message style
The prompt asks for:
- An imperative subject of at most 72 characters, preferably
type: summarywithfeat,fix, orchore. - A body that explains what user-visible behaviour or repository state changed and how the implementation achieves it, including important constraints.
- Lines wrapped at 80 characters, with no Markdown, trailers, or validation results.
When drafting fails
Failures never block a commit; the normal editor opens either way. The reason is
written to stderr and also inserted as a comment at the top of the editor buffer
(# for Git, JJ: for jj), because the editor clears the terminal. This covers
a missing claude executable, a non-zero exit (with Claude Code's own output,
such as "Not logged in"), and an empty response.
Last updated on