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[](https://goreportcard.com/report/git.secluded.site/formatted-commit)
11
12CLI tool that produces commits following the Conventional Commits specification
13through flags, made for LLMs and not really their operators (but I guess you can
14use this directly if you want). Operators would likely prefer, as the author
15does, [meteor](https://github.com/stefanlogue/meteor).
16
17I've found that LLMs consistently fail to
18
19- Format trailers correctly: they add too many newlines between trailers, which
20 breaks tools like `git interpret-trailers`
21- Include proper scope notation
22- Follow the loose 50/72 subject/body standard held by projects like the Linux
23 kernel. I try to stick to it, but LLMs writing badly-formatted commit messages
24 means rewording work for me once they're done.
25
26`formatted-commit` enforces all of this. Where possible, we "correct" the
27model's input. Where that's less possible, we error. For example, instead of
28requiring the model wrap body text at 72 columns, we let it write whatever body
29it wants and wrap it ourselves. We can't really fix the subject, so
30`formatted-commit` emits an error when the subject is too long with clear
31indication of where the 50-character cut-off is.
32
33## Installation
34
35As this is mostly meant for agentic coding tools, you'll need one. I like [Crush
36💘](https://github.com/charmbracelet/crush) (and maintain [a
37fork](https://git.secluded.site/crush)) or [OpenCode](https://opencode.ai/) as
38the best more-open options and [Amp](https://ampcode.com/) as the overall best
39option if you don't mind completely proprietary and paying for 100% of your API
40usage.
41
42You need both the binary and the prompt. If you don't have the binary
43when the model tries to use it, it's instructed to ask you to install
44it using the appropriate command.
45
46### The binary
47
48- Using [bin](https://github.com/marcosnils/bin) (highly recommended
49 because it's one tool to manage and update myriad CLI tools
50 distributed as statically-linked binaries, like _formatted-commit_)
51 ```bash
52 bin install goinstall://git.secluded.site/formatted-commit@latest
53 ```
54- Using the [go toolchain](https://go.dev/dl) (requires tracking updates
55 manually, though you can check with `formatted-commit upgrade` and
56 apply with `formatted-commit upgrade -a`)
57 ```bash
58 go install git.secluded.site/formatted-commit@latest
59 ```
60
61### The prompt
62
63Copy/paste this into wherever you tell your models how to write commits. For
64Crush, that might be `~/.config/crush/CRUSH.md` or `./CRUSH.md` in a repo. For
65[my Crush fork](https://git.secluded.site/crush) and Amp, that's
66`~/.config/AGENTS.md`. Look up where your tool checks for rules files and put
67this in a section like `## Creating git commits` or something.
68
69<details>
70<summary>Using <code>bin</code></summary>
71
72```markdown
73Create/amend commits exclusively using `formatted-commit`. Try to use it normally, but if it's not in my PATH, ask me to `bin install goinstall://git.secluded.site/formatted-commit@latest`. It has no sub-commands and the following options:
74<formatted-commit_flags>
75-t --type Commit type (required)
76-s --scope Commit scope (optional)
77-B --breaking Mark as breaking change (optional)
78-m --message Commit message (required)
79-b --body Commit body (optional)
80-T --trailer Trailer in 'Sentence-case-key: value' format (optional, repeatable)
81-a --add Stage all modified files before committing (optional)
82--amend Amend the previous commit (optional)
83-h --help
84</formatted-commit_flags>
85<formatted-commit_example>
86formatted-commit -t feat -s "web/git-bug" -m "do a fancy new thing" -T "Assisted-by: GLM 4.6 via Crush" -b "$(cat <<'EOF'
87Multi-line
88
89- Body
90- Here
91
92EOF
93)"
94</formatted-commit_example>
95```
96
97</details>
98
99<details>
100<summary>Using <code>go install</code></summary>
101
102```markdown
103Create/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:
104<formatted-commit_flags>
105-t --type Commit type (required)
106-s --scope Commit scope (optional)
107-B --breaking Mark as breaking change (optional)
108-m --message Commit message (required)
109-b --body Commit body (optional)
110-T --trailer Trailer in 'Sentence-case-key: value' format (optional, repeatable)
111-a --add Stage all modified files before committing (optional)
112--amend Amend the previous commit (optional)
113-h --help
114</formatted-commit_flags>
115<formatted-commit_example>
116formatted-commit -t feat -s "web/git-bug" -m "do a fancy new thing" -T "Assisted-by: GLM 4.6 via Crush" -b "$(cat <<'EOF'
117Multi-line
118
119- Body
120- Here
121
122EOF
123)"
124</formatted-commit_example>
125```
126
127</details>
128
129## Contributions
130
131Patch requests are in [amolith/llm-projects] on [pr.pico.sh]. You don't need a
132new account to contribute, you don't need to fork this repo, you don't need to
133fiddle with `git send-email`, you don't need to faff with your email client to
134get `git request-pull` working...
135
136You just need:
137
138- Git
139- SSH
140- An SSH key
141
142```sh
143# Clone this repo, make your changes, and commit them
144# Create a new patch request with
145git format-patch origin/main --stdout | ssh pr.pico.sh pr create amolith/llm-projects
146# After potential feedback, submit a revision to an existing patch request with
147git format-patch origin/main --stdout | ssh pr.pico.sh pr add {prID}
148# List patch requests
149ssh pr.pico.sh pr ls amolith/llm-projects
150```
151
152See "How do Patch Requests work?" on [pr.pico.sh]'s home page for a more
153complete example workflow.
154
155[amolith/llm-projects]: https://pr.pico.sh/r/amolith/llm-projects
156[pr.pico.sh]: https://pr.pico.sh
157
158## Usage
159
160```text
161$ formatted-commit -h
162
163 formatted-commit helps you create well-formatted Git commits that follow
164 the Conventional Commits specification with proper subject length validation,
165 body wrapping, and trailer formatting.
166
167 USAGE
168
169 formatted-commit [command] [--flags]
170
171 EXAMPLES
172
173 # With Assisted-by
174 formatted-commit -t feat -m "do a thing" -T "Assisted-by: GLM 4.6 via Crush"
175
176 # Breaking change with longer body
177 formatted-commit -t feat -m "do a thing that borks a thing" -B -b "$(cat <<'EOF'
178 Multi-line
179 - Body
180 - Here
181
182 This is what borked because of new shiny, this is how migrate
183 EOF
184 )"
185
186 # Including scope for more precise changes
187 formatted-commit -t refactor -s "web/git-bug" -m "fancy shmancy" \
188 -b "Had to do a weird thing because..."
189
190 # Check for upgrades
191 formatted-commit upgrade
192
193 # Then apply
194 formatted-commit upgrade -a
195
196 COMMANDS
197
198 help [command] Help about any command
199 upgrade [--flags] Check for and apply updates
200
201 FLAGS
202
203 -a --add Stage all modified files before committing (optional)
204 --amend Amend the previous commit (optional)
205 -b --body Commit body (optional)
206 -B --breaking Mark as breaking change (optional)
207 -h --help Help for formatted-commit
208 -m --message Commit message (required)
209 -s --scope Commit scope (optional)
210 -T --trailer Trailer in 'Sentence-case-key: value' format (optional, repeatable)
211 -t --type Commit type (required)
212 -v --version Version for formatted-commit
213```