1<!--
  2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  3
  4SPDX-License-Identifier: CC0-1.0
  5-->
  6
  7# formatted-commit
  8
  9<!--[](https://api.reuse.software/info/git.secluded.site/formatted-commit)-->
 10
 11[](https://goreportcard.com/report/git.secluded.site/formatted-commit)
 12
 13CLI tool that produces commits following the Conventional Commits specification
 14through flags, made for LLMs and not really their operators (but I guess you can
 15use this directly if you want). Operators would likely prefer, as the author
 16does, [meteor](https://github.com/stefanlogue/meteor).
 17
 18I've found that LLMs consistently fail to
 19
 20- Format trailers correctly: they add too many newlines between trailers, which
 21  breaks tools like `git interpret-trailers`
 22- Include proper scope notation
 23- Follow the loose 50/72 subject/body standard held by projects like the Linux
 24  kernel. I try to stick to it, but LLMs writing badly-formatted commit messages
 25  means rewording work for me once they're done.
 26
 27`formatted-commit` enforces all of this. Where possible, we "correct" the
 28model's input. Where that's less possible, we error. For example, instead of
 29requiring the model wrap body text at 72 columns, we let it write whatever body
 30it wants and wrap it ourselves. We can't really fix the subject, so
 31`formatted-commit` emits an error when the subject is too long with clear
 32indication of where the 50-character cut-off is.
 33
 34## Installation
 35
 36As this is mostly meant for agentic coding tools, you'll need one. I like [Crush
 37💘](https://github.com/charmbracelet/crush) (and maintain [a
 38fork](https://git.secluded.site/crush)) or [OpenCode](https://opencode.ai/) as
 39the best more-open options and [Amp](https://ampcode.com/) as the overall best
 40option if you don't mind completely proprietary and paying for 100% of your API
 41usage.
 42
 43You may install `formatted-commit` manually using the following command. You may
 44also skip this and just add the prompt snippet; it tells the model about the
 45command so it can try to run it on its own or ask you to run it.
 46
 47```bash
 48go install git.secluded.site/formatted-commit@latest
 49```
 50
 51Copy/paste this into wherever you tell your models how to write commits. For
 52Crush, that might be `~/.config/crush/CRUSH.md` or `./CRUSH.md` in a repo. For
 53[my Crush fork](https://git.secluded.site/crush) and Amp, that's
 54`~/.config/AGENTS.md`. Look up where your tool checks for rules files and put
 55this in a section like `## Creating git commits` or something.
 56
 57```markdown
 58Create/amend commits exclusively using `formatted-commit`. Try to use it normally, but if it's not in my PATH, ask me to `go install git.secluded.site/formatted-commit@latest`. It has no sub-commands and the following options:
 59<formatted-commit_flags>
 60-t --type Commit type (required)
 61-s --scope Commit scope (optional)
 62-B --breaking Mark as breaking change (optional)
 63-m --message Commit message (required)
 64-b --body Commit body (optional)
 65-T --trailer Trailer in 'Sentence-case-key: value' format (optional, repeatable)
 66-a --amend Amend the previous commit (optional)
 67-h --help
 68</formatted-commit_flags>
 69<formatted-commit_example>
 70formatted-commit -t feat -s "web/git-bug" -m "do a fancy new thing" -T "Crush <crush@charm.land>" -b "$(cat <<'EOF'
 71Multi-line
 72
 73- Body
 74- Here
 75
 76EOF
 77)"
 78</formatted-commit_example>
 79```
 80
 81## Contributions
 82
 83Patch requests are in [amolith/llm-projects] on [pr.pico.sh]. You don't need a
 84new account to contribute, you don't need to fork this repo, you don't need to
 85fiddle with `git send-email`, you don't need to faff with your email client to
 86get `git request-pull` working...
 87
 88You just need:
 89
 90- Git
 91- SSH
 92- An SSH key
 93
 94```sh
 95# Clone this repo, make your changes, and commit them
 96# Create a new patch request with
 97git format-patch origin/main --stdout | ssh pr.pico.sh pr create amolith/llm-projects
 98# After potential feedback, submit a revision to an existing patch request with
 99git format-patch origin/main --stdout | ssh pr.pico.sh pr add {prID}
100# List patch requests
101ssh pr.pico.sh pr ls amolith/llm-projects
102```
103
104See "How do Patch Requests work?" on [pr.pico.sh]'s home page for a more
105complete example workflow.
106
107[amolith/llm-projects]: https://pr.pico.sh/r/amolith/llm-projects
108[pr.pico.sh]: https://pr.pico.sh
109
110## Usage
111
112```text
113$ formatted-commit -h
114
115  formatted-commit helps you create well-formatted Git commits that follow
116  the Conventional Commits specification with proper subject length validation,
117  body wrapping, and trailer formatting.
118
119  USAGE
120
121
122    formatted-commit [--flags]
123
124
125  EXAMPLES
126
127
128    # With co-author
129    formatted-commit -t feat -m "do a thing" -T "Crush <crush@charm.land>"
130
131    # Breaking change with longer body
132    formatted-commit -t feat -m "do a thing that borks a thing" -B -b "$(cat <<'EOF'
133    Multi-line
134    - Body
135    - Here
136
137    This is what borked because of new shiny, this is how migrate
138    EOF
139    )"
140
141    # Including scope for more precise changes
142    formatted-commit -t refactor -s "web/git-bug" -m "fancy shmancy" \
143      -b "Had to do a weird thing because..."
144
145
146  COMMANDS
147
148    help [command]  Help about any command
149
150  FLAGS
151
152    -a --amend      Amend the previous commit (optional)
153    -b --body       Commit body (optional)
154    -B --breaking   Mark as breaking change (optional)
155    -h --help       Help for formatted-commit
156    -m --message    Commit message (required)
157    -s --scope      Commit scope (optional)
158    -T --trailer    Trailer in 'Sentence-case-key: value' format (optional, repeatable)
159    -t --type       Commit type (required)
160    -v --version    Version for formatted-commit
161```