A command-line tool that automatically generates conventional commit messages using AI, based on your staged git changes.
Your commit messages will look like this:
- 🤖 AI-powered commit message generation with multiple options:
- Local Ollama support - Completely FREE and private!
- No API key required
- Works offline
- Supports various models (codellama, llama2, etc.)
- Local LMStudio support - Completely FREE and private!
- Works with any model you have in LMStudio
- Uses the OpenAI-compatible API
- Great for privacy and offline use
- OpenRouter (default) using
google/gemini-flash-1.5-8b- SUPER CHEAP!- Around $0.00001/commit -> $1 per 100K commit messages!
- Custom API support - Bring your own provider!
- Local Ollama support - Completely FREE and private!
- 📝 Follows Conventional Commits format
- 🔒 Secure local API key storage
- 🚀 Automatic git commit and push
- 🐛 Debug mode for troubleshooting
- 💻 Cross-platform support (Windows, Linux, macOS)
- Git installed and configured
- For Windows: Git Bash or WSL installed
- For Linux/macOS: Bash shell environment
curlinstalled- One of the following:
- An OpenRouter API key (default)
- Ollama installed and running locally
- LMStudio installed and running locally
- Clone this repository:
git clone https://github.com/mrgoonie/cmai.git
cd cmai- Run the installation script:
./install.shThis will:
- Create necessary directories
- Install the script globally as
cmai - Set up proper permissions
- Clone this repository:
git clone https://github.com/mrgoonie/cmai.git
cd cmai- Run the installation script in Git Bash:
./install.shOr manually:
- Copy
git-commit.shto%USERPROFILE%\git-commit-ai\ - Add the directory to your PATH environment variable
- Rename
git-commit.shtocmai.sh
This will:
- Create necessary directories
- Install the script globally as
cmai - Set up proper permissions
Set up your OpenRouter API key:
cmai <your_openrouter_api_key>The API key will be securely stored in:
- Linux/macOS:
~/.config/git-commit-ai/config - Windows:
%USERPROFILE%\.config\git-commit-ai\config
- Install Ollama from https://ollama.ai/
- Pull your preferred model (e.g., codellama):
ollama pull deepseek-r1:7b- Make sure Ollama is running in the background
- Install LMStudio from https://lmstudio.ai/
- Download and load your preferred model in LMStudio
- Start the local server in LMStudio by clicking on "Start Server" in the Chat tab
- The server will run on http://localhost:1234/v1 by default
- Make your code changes
- Generate commit message and commit changes:
cmaiTo also push changes to remote:
cmai --push
# or
cmai -pBy default, CMAI uses OpenRouter with the google/gemini-flash-1.5-8b model. You can switch between different providers:
# Use Ollama (local)
cmai --use-ollama
# Use LMStudio (local)
cmai --use-lmstudio
# Switch back to OpenRouter
cmai --use-openrouter
# Use a custom provider
cmai --use-custom http://your-api-endpointThe provider choice is saved for future use, so you only need to specify it once.
When using OpenRouter, you can choose from their available models:
cmai --model qwen/qwen-2.5-coder-32b-instructList of available models: https://openrouter.ai/models
When using Ollama, first pull your desired model:
# Pull the model
ollama pull deepseek-r1:7b
# Use the model
cmai --model deepseek-r1:7bList of available models: https://ollama.ai/library
Popular models for commit messages:
deepseek-r1- Optimized for code understandingllama2- Good all-around performancemistral- Fast and efficient
This will:
- Stage all changes
- Generate a commit message using AI
- Commit the changes
- Push to the remote repository (if --push flag is used)
To see detailed information about what's happening:
cmai --debugYou can combine flags:
cmai --debug --pushTo generate a commit message without staging, committing, or pushing:
cmai --message-onlyThis is useful if you want to review the message before committing.
Diff context is capped from the configured model context window. CMAI defaults
to 131,072 context tokens, reserves 4,096 output tokens when no output limit is
set, keeps a 10% safety margin, and uses a conservative byte-based estimate.
For larger changes, CMAI keeps the file list and truncates the diff at a
complete line boundary.
--max-context-tokens only controls prompt budgeting; it is not sent to the
provider. When --max-output-tokens is omitted, the 4,096-token reserve only
affects budgeting and no output limit is sent.
You can also base this on a specific diff target:
cmai --message-only --diff main...HEADIf you haven't staged your changes yet (with git add), you can use the --unstaged flag:
cmai --unstaged --message-onlyThis will generate a message based on your current unstaged and untracked working tree changes without staging them first.
To generate a git branch name based on your changes:
cmai --branch-name-onlyThis will output a branch name like fix/api-error-handling or feat/new-login-page based on the context of your changes. It does not perform any git operations.
You can also base this on a specific diff target:
cmai --branch-name-only --diff HEAD~1..HEADUsage: cmai [options] [api_key]
Options:
--debug Enable debug mode
--push, -p Push changes after commit
--message-only Generate message only, no git add/commit/push
--branch-name-only Generate branch name only, no git add/commit/push
--unstaged Use unstaged and untracked changes for diff
--diff <diff> Use a custom git diff target for message/branch-only
--model <model> Use specific model (default: google/gemini-flash-1.5-8b)
--temperature <n> Set sampling temperature (0-2; saves for future use)
--top-p <n> Set nucleus sampling probability (0-1; saves for future use)
--top-k <n> Set top-k sampling count (non-negative integer)
--presence-penalty <n> Set presence penalty (-2 to 2; saves for future use)
--max-output-tokens <n> Set maximum generated tokens (saves for future use)
--max-context-tokens <n> Set model context window (default: 131072)
--reasoning-effort <level> Set none/minimal/low/medium/high/xhigh/max
--extra-body <json> Merge arbitrary JSON object into request body
--clear-model-options Clear saved model options
--use-ollama Use Ollama as provider (saves for future use)
--use-lmstudio Use LMStudio as provider (saves for future use)
--use-openrouter Use OpenRouter as provider (saves for future use)
--use-custom <url> Use custom provider with base URL (saves for future use)
-h, --help Show this help message# First time setup with API key
cmai <your_openrouter_api_key>
# Normal usage
cmai
# Use a different OpenRouter model
cmai --model "google/gemini-flash-1.5-8b"
# Debug mode with push
cmai --debug --push
# Generate message only
cmai --message-only
# Generate branch name
cmai --branch-name-only# Switch to Ollama provider
cmai --use-ollama
# Use a specific deepseek-r1 model
cmai --model deepseek-r1:7b
# Debug mode with Ollama
cmai --debug --use-ollama# Switch to LMStudio provider
cmai --use-lmstudio
# Use a specific model in LMStudio
cmai --model "your-model-name"
# Debug mode with LMStudio
cmai --debug --use-lmstudio# Use a custom API provider
cmai --use-custom http://my-api.com
# Use custom provider with specific model
cmai --use-custom http://my-api.com --model my-custom-modelcmai --use-ollama --model qwen-coder:7b
cmai --use-ollama --debug --push
### Common Options
```bash
# Commit and push
cmai --push
# or
cmai -p
# Debug mode
cmai --debug
# Use a different API endpoint
cmai --base-url https://api.example.com/v1
# Combine multiple flags
cmai --debug --push --model your-model --base-url https://api.example.com/v1
# Configure generation and pass provider-specific request fields
cmai --temperature 0.7 --top-p 0.8 --top-k 40 \
--presence-penalty -0.2 --max-output-tokens 4096 \
--max-context-tokens 262144 \
--extra-body '{"chat_template_kwargs":{"enable_thinking":false}}'
# Configure reasoning effort for a supported model
cmai --reasoning-effort high
Generation options persist across runs. OpenRouter receives reasoning.effort;
LM Studio and custom OpenAI-compatible providers receive reasoning_effort.
Supported effort levels depend on the selected model. OpenRouter accepts the
full listed set, including none; none is sent explicitly so it disables
reasoning instead of selecting the model default. For Ollama, only GPT-OSS
models accept effort levels (low, medium, or high) and cannot use none.
Other Ollama models accept --reasoning-effort none as "think": false; use
--extra-body '{"think":true}' to enable their boolean thinking mode.
--extra-body accepts any JSON object and merges it last into the raw HTTP
request, matching the Python SDK's extra_body behavior. Extra fields can add
provider-specific controls or override generated top-level fields. Ollama maps
generation controls into options, including top_k, presence_penalty, and
num_predict for maximum tokens, before applying the extra body.
Use --clear-model-options to omit all saved model controls again.
Example generated commit messages:
feat(api): add user authentication systemfix(data): resolve memory leak in data processingdocs(api): update API documentationstyle(ui): improve responsive layout for mobile devices
~
├── git-commit-ai/
│ └── git-commit.sh
├── .config/
│ └── git-commit-ai/
│ ├── config # API key
│ ├── model # Selected AI model
│ ├── provider # Selected provider (openrouter/ollama/custom)
│ ├── base_url # API base URL
│ ├── temperature # Sampling temperature (optional)
│ ├── top_p # Nucleus sampling probability (optional)
│ ├── top_k # Top-k sampling count (optional)
│ ├── presence_penalty # Presence penalty (optional)
│ ├── max_tokens # Maximum generated tokens (optional)
│ ├── reasoning_effort # Reasoning level (optional)
│ └── extra_body # Arbitrary request JSON fields (optional)
└── usr/
└── local/
└── bin/
└── cmai -> ~/git-commit-ai/git-commit.sh
%USERPROFILE%
├── git-commit-ai/
│ └── cmai.sh
└── .config/
└── git-commit-ai/
├── config
├── model
└── base_url
- API key is stored locally with restricted permissions (600)
- Configuration directory is protected (700)
- No data is stored or logged except the API key
- All communication is done via HTTPS
-
No API key found
- Run
cmai your_openrouter_api_keyto configure
- Run
-
Permission denied
- Check file permissions:
ls -la ~/.config/git-commit-ai - Should show:
drwx------for directory and-rw-------for config file
- Check file permissions:
-
Debug mode
- Run with
--debugflag to see detailed logs - Check API responses and git operations
- Run with
-
Windows-specific issues
- Make sure Git Bash is installed
- Check if curl is available in Git Bash
- Verify PATH environment variable includes the installation directory
bash
sudo rm /usr/local/bin/cmai
rm -rf ~/git-commit-ai
rm -rf ~/.config/git-commit-airm -rf "$USERPROFILE/git-commit-ai"
rm -rf "$USERPROFILE/.config/git-commit-ai"Then remove the directory from your PATH environment variable
- Fork the repository
- Create your feature branch
- Commit your changes (using
cmai😉) - Push to the branch
- Create a Pull Request
MIT License - see LICENSE file for details
- OpenRouter for providing the AI API
- Conventional Commits for the commit message format
- DigiCord AI - The Most Useful AI Chatbot on Discord
- IndieBacklink.com - Indie Makers Unite: Feature, Support, Succeed
- TopRanking.ai - AI Directory, listing AI products
- ZII.ONE - Personalized Link Shortener
- VidCap.xyz - Extract Youtube caption, download videos, capture screenshot, summarize,…
- ReadTube.me - Write blog articles based on Youtube videos
- BoostTogether.com - The Power of WE in Advertising
- AIVN.Site - Face Swap, Remove BG, Photo Editor,…
- DxUp.dev - Developer-focused platform for app deployment & centralized cloud resource management.

