README.md

  1<!--
  2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  3
  4SPDX-License-Identifier: CC0-1.0
  5-->
  6
  7# formatted-commit
  8
  9[![REUSE status](https://api.reuse.software/badge/git.secluded.site/formatted-commit)](https://api.reuse.software/info/git.secluded.site/formatted-commit)
 10[![Go Report Card](https://goreportcard.com/badge/git.secluded.site/formatted-commit)](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 may install `formatted-commit` manually using the following command. You may
 43also skip this and just add the prompt snippet; it tells the model about the
 44command so it can try to run it on its own or ask you to run it.
 45
 46```bash
 47go install git.secluded.site/formatted-commit@latest
 48```
 49
 50Check for upgrades with `formatted-commit upgrade`, then apply with
 51`formatted-commit upgrade -a`.
 52
 53Copy/paste this into wherever you tell your models how to write commits. For
 54Crush, that might be `~/.config/crush/CRUSH.md` or `./CRUSH.md` in a repo. For
 55[my Crush fork](https://git.secluded.site/crush) and Amp, that's
 56`~/.config/AGENTS.md`. Look up where your tool checks for rules files and put
 57this in a section like `## Creating git commits` or something.
 58
 59```markdown
 60Create/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:
 61<formatted-commit_flags>
 62-t --type Commit type (required)
 63-s --scope Commit scope (optional)
 64-B --breaking Mark as breaking change (optional)
 65-m --message Commit message (required)
 66-b --body Commit body (optional)
 67-T --trailer Trailer in 'Sentence-case-key: value' format (optional, repeatable)
 68-a --amend Amend the previous commit (optional)
 69-h --help
 70</formatted-commit_flags>
 71<formatted-commit_example>
 72formatted-commit -t feat -s "web/git-bug" -m "do a fancy new thing" -T "Assisted-by: GLM 4.6 via Crush" -b "$(cat <<'EOF'
 73Multi-line
 74
 75- Body
 76- Here
 77
 78EOF
 79)"
 80</formatted-commit_example>
 81```
 82
 83## Contributions
 84
 85Patch requests are in [amolith/llm-projects] on [pr.pico.sh]. You don't need a
 86new account to contribute, you don't need to fork this repo, you don't need to
 87fiddle with `git send-email`, you don't need to faff with your email client to
 88get `git request-pull` working...
 89
 90You just need:
 91
 92- Git
 93- SSH
 94- An SSH key
 95
 96```sh
 97# Clone this repo, make your changes, and commit them
 98# Create a new patch request with
 99git format-patch origin/main --stdout | ssh pr.pico.sh pr create amolith/llm-projects
100# After potential feedback, submit a revision to an existing patch request with
101git format-patch origin/main --stdout | ssh pr.pico.sh pr add {prID}
102# List patch requests
103ssh pr.pico.sh pr ls amolith/llm-projects
104```
105
106See "How do Patch Requests work?" on [pr.pico.sh]'s home page for a more
107complete example workflow.
108
109[amolith/llm-projects]: https://pr.pico.sh/r/amolith/llm-projects
110[pr.pico.sh]: https://pr.pico.sh
111
112## Usage
113
114```text
115$ formatted-commit -h
116
117  formatted-commit helps you create well-formatted Git commits that follow
118  the Conventional Commits specification with proper subject length validation,
119  body wrapping, and trailer formatting.
120
121  USAGE
122
123    formatted-commit [command] [--flags]
124
125  EXAMPLES
126
127    # With Assisted-by
128    formatted-commit -t feat -m "do a thing" -T "Assisted-by: GLM 4.6 via Crush"
129
130    # Breaking change with longer body
131    formatted-commit -t feat -m "do a thing that borks a thing" -B -b "$(cat <<'EOF'
132    Multi-line
133    - Body
134    - Here
135
136    This is what borked because of new shiny, this is how migrate
137    EOF
138    )"
139
140    # Including scope for more precise changes
141    formatted-commit -t refactor -s "web/git-bug" -m "fancy shmancy" \
142      -b "Had to do a weird thing because..."
143
144    # Check for upgrades
145    formatted-commit upgrade
146
147    # Then apply
148    formatted-commit upgrade -a
149
150  COMMANDS
151
152    help [command]     Help about any command
153    upgrade [--flags]  Check for and apply updates
154
155  FLAGS
156
157    -a --amend         Amend the previous commit (optional)
158    -b --body          Commit body (optional)
159    -B --breaking      Mark as breaking change (optional)
160    -h --help          Help for formatted-commit
161    -m --message       Commit message (required)
162    -s --scope         Commit scope (optional)
163    -T --trailer       Trailer in 'Sentence-case-key: value' format (optional, repeatable)
164    -t --type          Commit type (required)
165    -v --version       Version for formatted-commit
166```