cmtr
cmtr writes your git commit messages for you. It prefers Codex CLI (using your ChatGPT account) and also supports the OpenAI API. Both backends default to gpt-6-luna. It uses the staged diff and recent commit history to match the repository's style.
Quick start (recommended)
- Install uv (if needed), then run:
uvx cmtr@latest
- Optional: add a shell alias:
alias cmtr="uvx cmtr@latest"
- Authenticate (preferred: Codex):
- Codex CLI (preferred): run
npx @openai/codex@latestand sign in (uses your ChatGPT account) - API key (alternative):
export OPENAI_API_KEY=...
- Codex CLI (preferred): run
- Stage changes and run:
git add -Acmtr
Codex mode is preferred because it uses your ChatGPT account usage (not separate
API billing) and requires no API key. If Codex isn't on your PATH, cmtr will run
it via npx @openai/codex@latest as long as you're signed in. If Codex is
unavailable and OPENAI_API_KEY is set, cmtr falls back to the OpenAI API.
OpenAI API requests are sent with store = false.
Or install the git hook:
cmtr --hook- Installs a
prepare-commit-msghook that automatically generates a commit message right before the commit editor opens. If there is already a message or you're in a rebase/fixup/squash flow, it skips. - If the repo sets
core.hooksPathin its local git config, cmtr installs the hook in that directory. If only a globalcore.hooksPathis set, re-run with--globalor set a local override withgit config --local core.hooksPath .git/hooks. - If a
.pre-commit-config.yaml/.ymlis present, cmtr will prompt to install a pre-commitprepare-commit-msghook instead (adds an entry that runsuvx cmtr@latest prepare-commit-msg). You may need to runpre-commit install --hook-type prepare-commit-msgafter accepting.
- Installs a
Usage
cmtr- Behaves like
git commit -v, but injects a generated commit message.
- Behaves like
cmtr --dry-run- Print the generated message without committing.
cmtr --print-prompt- Print the prompts used to generate the message.
cmtr --no-edit- Skip opening the editor after generating the message.
cmtr --model gpt-6-luna- Override the selected backend's model for this run.
cmtr --codex-model gpt-6-luna- Override only the Codex CLI model for this run.
cmtr --organization org_... --project proj_...- Override the OpenAI organization/project for this run.
cmtr --hook- Install the
prepare-commit-msghook to auto-generate messages on every commit.
- Install the
cmtr --global --hook- Install the hook in the globally configured hooks path.
cmtr --uninstall-hook- Remove the hook.
Extra git commit flags can be passed directly (for example, --no-verify).
cmtr rejects message-supplying, message-shaping, and content-changing flags
such as -a, -i, -o, -m, -F, -t, -C, -c, --amend,
--allow-empty, --cleanup, --fixup, --squash, --patch,
--interactive, --dry-run, -e, --edit, --no-edit, --include, --only,
--pathspec-from-file, and their attached/long-form equivalents because cmtr
supplies the message, controls editor behavior, and analyzes the staged diff
before running git commit.
Safe metadata/trailer options such as --author, --date, --signoff,
--gpg-sign, and --trailer are passed through.
Pathspecs passed after -- are supported and limit the prompt context to those
staged paths. They are interpreted relative to the current directory, like
git commit. If those paths also have unstaged edits, cmtr stops instead of
generating a message from stale staged context.
AI backends are asked to return structured JSON with a single message string.
cmtr validates that string before use; obvious prompt leaks, diff echoes,
conflict markers, placeholders, malformed body spacing, and comment-only output
are rejected instead of being rewritten with heuristic cleanup.
How it builds context
- Uses staged files (
git diff --cached) for the actual changes. - Finds shared paths and samples recent
git logmessages on those paths to learn the repo's style. - For unrelated staged files, samples up to
max_log_pathshigh-signal paths instead of relying on only one fallback path. - Requests structured output from the model so the generated commit message is returned as data, not prose wrapped around a suggestion.
- Codex mode runs from a scratch directory and receives only the generated prompt context, not live access to the target checkout.
Configuration
Configuration is loaded in this order (later overrides earlier):
- XDG config file (
~/.config/cmtr/config.tomlor$XDG_CONFIG_HOME/cmtr/config.toml) cmtr.tomlin the repo root (optional repo-specific overrides)- Environment variables
- CLI flags
Manage global config with:
cmtr config pathcmtr config listcmtr config get modelcmtr config set model gpt-6-lunacmtr config unset model
Example config file:
model = "gpt-6-luna"
codex_model = "gpt-6-luna"
max_diff_bytes = 12000
max_patch_lines = 400
max_log_entries = 20
max_log_paths = 4
max_log_body_lines = 6
timeout_seconds = 60
reasoning_effort = ""
text_verbosity = "low"
prefer_codex = true
base_url = "https://api.openai.com/v1"
organization = "org_..."
project = "proj_..."
Unknown config keys and invalid numeric ranges fail fast so typoed settings do
not silently fall back to defaults. model/CMTR_MODEL configures OpenAI API
mode. codex_model/CMTR_CODEX_MODEL configures Codex mode. For one-off CLI
runs, --model overrides whichever backend is selected, while --codex-model
overrides only Codex mode.
Set reasoning_effort or text_verbosity to a blank string to avoid sending
that optional Responses API parameter for models or compatible providers that
do not support it.
Codex is preferred by default. timeout_seconds applies to both Codex CLI
execution and OpenAI API requests. Set prefer_codex = false to use the OpenAI
API first whenever OPENAI_API_KEY is set, while still allowing Codex when no
API key is available.
Use cmtr auth status to see which mode will be selected and why.
Environment variables:
OPENAI_API_KEYOPENAI_BASE_URLOPENAI_ORG_ID(also supportsOPENAI_ORGandOPENAI_ORGANIZATION)OPENAI_PROJECT_IDCMTR_MODELCMTR_CODEX_MODELCMTR_MAX_DIFF_BYTESCMTR_MAX_PATCH_LINESCMTR_MAX_LOG_ENTRIESCMTR_MAX_LOG_PATHSCMTR_MAX_LOG_BODY_LINESCMTR_TIMEOUT_SECONDSCMTR_REASONING_EFFORTCMTR_TEXT_VERBOSITYCMTR_PREFER_CODEX
Development
Local development:
mise installmise run installmise run run
Linting and type checking:
mise run lintuv run ruff check .mise run format-checkuv run ruff format --check .mise run typecheckuv run ty check
Testing and packaging:
mise run formatuv run ruff format .mise run testuv run pytestmise run builduv build
If you are installing manually, run uv sync --group dev first to install the
dev tools.
CI also checks a fresh wheel installation before publication. cmtr currently requires Typer below 0.26 because its command routing uses Click integration.
Troubleshooting
- No staged changes: run
git addbefore cmtr. - Missing API key: set
OPENAI_API_KEYor install/login to Codex CLI. - Unsure which auth mode is active: run
cmtr auth status. - Hook failures: a
# cmtr failed: ...comment is appended to the commit message template.
Metadata
Release files for cmtr 0.4.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cmtr-0.4.2.tar.gz | 30.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cmtr-0.4.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 64.7 kB
Release files / cmtr-0.4.2.tar.gz
| Download URL | cmtr-0.4.2.tar.gz |
|---|---|
| Size | 30.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a1232446fe32f72aea1259ee71234405da4a1f1d9068e55ad582d948a0649c88
|
|
BLAKE2b-256 checksum How to use checksums |
7657b364654315591dd538816906a7b147f83ffd608644ff2cbb222d7bc0d02e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency logRelease files / cmtr-0.4.2-py3-none-any.whl
| Download URL | cmtr-0.4.2-py3-none-any.whl |
|---|---|
| Size | 34.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3e06e66c50dba4d6a62ba3cca7ed5a8cade087d0f1b3bfbac6ea50a034d79d1b
|
|
BLAKE2b-256 checksum How to use checksums |
9c0d1fbb05290f563a5fcd90d65fccb11755ff061b8cfd434f55597d6b479943
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency log