<!--
SPDX-FileCopyrightText: Amolith <amolith@secluded.site>

SPDX-License-Identifier: CC0-1.0
-->

# formatted-commit

<!--[![REUSE status](https://api.reuse.software/badge/git.secluded.site/formatted-commit)](https://api.reuse.software/info/git.secluded.site/formatted-commit)-->

[![Go Report Card](https://goreportcard.com/badge/git.secluded.site/formatted-commit)](https://goreportcard.com/report/git.secluded.site/formatted-commit)

CLI tool that requires conformance with the Conventional Commits specification
through flags, made for LLMs and not really for the operators (but I guess you
can use this directly if you want). Operators would likely prefer, as the author
does, [meteor](https://github.com/stefanlogue/meteor).

`formatted-commit` enforces a 50-character subject limit and sanitises/wraps the body at 72
characters. I might make that configurable. Idk. It's a loose standard held by
projects like the Linux kernel and I try to stick to it.

## Installation

As this is mostly meant for agentic coding tools, you'll need one. I like [Crush
💘](https://github.com/charmbracelet/crush) (and maintain [a
fork](https://git.secluded.site/crush)) or [OpenCode](https://opencode.ai/) as
the best more-open options and [Amp](https://ampcode.com/) as the overall best
option if you don't mind completely proprietary and paying for 100% of your API
usage.

You may install `formatted-commit` manually using the following command. You may
also skip this and just add the prompt snippet; it tells the model about the
command so it can try to run it on its own or ask you to run it.

```bash
go install git.secluded.site/formatted-commits@latest
```

Copy/paste this into wherever you tell your models how to write commits. For
Crush, that might be `~/.config/crush/CRUSH.md` or `./CRUSH.md` in a repo. For
[my Crush fork](https://git.secluded.site/crush) and Amp, that's
`~/.config/AGENTS.md`. Look up where your tool checks for rules files and put
this in a section like `## Creating git commits` or something.

```markdown
Create 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:
<formatted-commit_flags>
-t --type Commit type (required)
-s --scope Commit scope (optional)
-B --breaking Mark as breaking change (optional)
-m --message Commit message (required)
-b --body Commit body (optional)
-T --trailer Trailer in 'Sentence-case-key: value' format (optional, repeatable)
-h --help
</formatted-commit_flags>
<formatted-commit_example>
formatted-commit -t feat -s "web/git-bug" -m "do a fancy new thing" -T "Crush <crush@charm.land>" -b "$(cat <<'EOF'
Multi-line

- Body
- Here

EOF
)"
</formatted-commit_example>
```

## Contributions

Patch requests are in [amolith/llm-projects] on [pr.pico.sh]. You don't need a
new account to contribute, you don't need to fork this repo, you don't need to
fiddle with `git send-email`, you don't need to faff with your email client to
get `git request-pull` working...

You just need:

- Git
- SSH
- An SSH key

```sh
# Clone this repo, make your changes, and commit them
# Create a new patch request with
git format-patch origin/main --stdout | ssh pr.pico.sh pr create amolith/llm-projects
# After potential feedback, submit a revision to an existing patch request with
git format-patch origin/main --stdout | ssh pr.pico.sh pr add {prID}
# List patch requests
ssh pr.pico.sh pr list amolith/llm-projects
```

See "How do Patch Requests work?" on [pr.pico.sh]'s home page for a more
complete example workflow.

[amolith/llm-projects]: https://pr.pico.sh/r/amolith/llm-projects
[pr.pico.sh]: https://pr.pico.sh

## Usage

```text
$ formatted-commit -h

  formatted-commit helps you create well-formatted Git commits that follow
  the Conventional Commits specification with proper subject length validation,
  body wrapping, and trailer formatting.

  USAGE


    formatted-commit [--flags]


  EXAMPLES


    # With co-author
    formatted-commit -t feat -m "do a thing" -T "Crush <crush@charm.land>"

    # Breaking change with longer body
    formatted-commit -t feat -m "do a thing that borks a thing" -B "$(cat <<'EOF'
    Multi-line
    - Body
    - Here

    This is what borked because of new shiny, this is how migrate
    EOF
    )"

    # Including scope for more precise changes
    formatted-commit -t refactor -s "web/git-bug" -m "fancy shmancy" \
      -b "Had to do a weird thing because..."


  COMMANDS

    help [command]  Help about any command

  FLAGS

    -b --body       Commit body (optional)
    -B --breaking   Mark as breaking change (optional)
    -h --help       Help for formatted-commit
    -m --message    Commit message (required)
    -s --scope      Commit scope (optional)
    -T --trailer    Trailer in 'Sentence-case-key: value' format (optional, repeatable)
    -t --type       Commit type (required)
    -v --version    Version for formatted-commit
```
