AI-powered git commit message generator CLI.
Analyzes your staged changes and suggests Conventional Commit messages using Claude or OpenAI. Supports Gitmoji, multiple languages, and interactive selection.
No need to clone this repo. Just run these commands in your own git project:
# 1. Stage your changes
git add .
# 2. Let AI generate your commit message
npx aicommitOn first run, you'll be prompted to set up your API key automatically.
$ npx aicommit
Staged files:
src/auth/login.js
src/auth/token.js
β Analysis complete
π Suggested commit messages:
1. feat(auth): add JWT token refresh endpoint
2. feat: implement token refresh logic with Redis cache
3. feat(auth): add automatic JWT refresh with 7-day expiry
? Select a message: (Use arrow keys)
β― 1. feat(auth): add JWT token refresh endpoint
2. feat: implement token refresh logic with Redis cache
3. feat(auth): add automatic JWT refresh with 7-day expiry
ββββββββββββββ
βοΈ Edit message
π Regenerate
β Cancel
β
Committed: feat(auth): add JWT token refresh endpoint
Undo: git reset --soft HEAD~1 | Amend: git commit --amend
With --gitmoji:
π Suggested commit messages:
1. β¨ feat(auth): add JWT token refresh endpoint
2. π fix(api): resolve timeout issue on token refresh
3. β»οΈ refactor: simplify auth middleware chain
- Multi-provider β Claude and OpenAI, switchable via
--provideror config - Conventional Commits β Standard format (
feat,fix,refactor, ...) enabled by default - Gitmoji β Optional emoji prefixes (
--gitmoji) for β¨ π β»οΈ and more - Multilingual β English and Korean commit messages (
--lang ko) - Interactive β Select, edit, or regenerate suggestions in a loop
- Zero config start β Works with
npx, auto-prompts setup on first run - Staged file preview β Shows which files will be committed before AI analysis
- Configurable models β Change AI models without touching code
- Request timeout β 30-second fetch timeout prevents hanging on slow networks
- Safe commit UX β Shows undo/amend commands after every commit
# Option 1: Use directly with npx (no install needed)
npx aicommit
# Option 2: Install globally for faster access
npm install -g aicommitRequirements: Node.js >= 18
git clone https://github.com/solzip/ai-commit.git
cd ai-commit
npm install
node bin/ai-commit.js --helpaicommit # Generate commit messages (default provider)
aicommit --provider openai # Use OpenAI instead of Claude
aicommit --lang ko # Korean commit messages
aicommit --gitmoji # Add gitmoji prefixes (β¨ π β»οΈ)
aicommit config # Interactive setup (API keys, preferences)| Option | Description | Default |
|---|---|---|
--provider <name> |
AI provider (claude or openai) |
claude |
--lang <code> |
Commit message language (en or ko) |
en |
--gitmoji |
Add gitmoji emoji prefixes | false |
-V, --version |
Show version number | β |
-h, --help |
Show help | β |
The format depends on your conventionalCommit and gitmoji settings:
| conventionalCommit | gitmoji | Format | Example |
|---|---|---|---|
| true | false | <type>(<scope>): <description> |
feat(auth): add login endpoint |
| true | true | <emoji> <type>(<scope>): <description> |
β¨ feat(auth): add login endpoint |
| false | true | <emoji> <description> |
β¨ add login endpoint |
| false | false | Free-form | add login endpoint |
| Emoji | Type | Meaning |
|---|---|---|
| β¨ | feat | New feature |
| π | fix | Bug fix |
| β»οΈ | refactor | Refactor |
| π | docs | Documentation |
| π | style | UI/style |
| β | test | Tests |
| π§ | chore | Config/tooling |
| β‘ | perf | Performance |
| π· | ci | CI/CD |
| π¦ | build | Build system |
| π₯ | remove | Remove code/files |
| π | deploy | Deploy |
| π | security | Security fix |
| β¬οΈ | upgrade | Upgrade dependency |
| π¨ | format | Code formatting |
aicommit configWalks you through:
- Default AI provider (Claude / OpenAI)
- API key for the selected provider (Enter to keep existing key)
- Default language (English / Korean)
- Conventional Commits on/off
- Gitmoji on/off
All settings are stored in ~/.ai-commit.json:
{
"provider": "claude",
"claudeApiKey": "sk-ant-...",
"openaiApiKey": "sk-...",
"language": "en",
"conventionalCommit": true,
"gitmoji": false,
"maxSuggestions": 3,
"claudeModel": "claude-sonnet-4-20250514",
"openaiModel": "gpt-4o-mini",
"timeout": 30000
}| Field | Type | Default | Description |
|---|---|---|---|
provider |
string | "claude" |
Default AI provider |
claudeApiKey |
string | β | Claude API key |
openaiApiKey |
string | β | OpenAI API key |
language |
string | "en" |
Commit message language (en, ko) |
conventionalCommit |
boolean | true |
Use Conventional Commits format |
gitmoji |
boolean | false |
Add gitmoji prefixes |
maxSuggestions |
number | 3 |
Number of suggestions to generate |
claudeModel |
string | "claude-sonnet-4-20250514" |
Claude model to use |
openaiModel |
string | "gpt-4o-mini" |
OpenAI model to use |
timeout |
number | 30000 |
API request timeout in milliseconds |
API keys can be set via environment variables (takes priority over config file):
export AI_COMMIT_CLAUDE_KEY=sk-ant-...
export AI_COMMIT_OPENAI_KEY=sk-...This is useful for CI/CD environments or shared machines where you don't want a config file.
CLI options (--provider, --lang, --gitmoji)
β overrides
Environment variables (AI_COMMIT_CLAUDE_KEY, AI_COMMIT_OPENAI_KEY)
β overrides
Config file (~/.ai-commit.json)
β overrides
Default values
| Provider | Default Model | Max Diff | API |
|---|---|---|---|
| Claude | claude-sonnet-4-20250514 | ~15,000 chars | Anthropic Messages API |
| OpenAI | gpt-4o-mini | ~12,000 chars | OpenAI Chat Completions |
Models can be changed in ~/.ai-commit.json via claudeModel and openaiModel without modifying any code.
Adding a new AI provider (e.g., Gemini) requires 3 steps:
Step 1. Create src/providers/gemini.js:
import { AIProvider } from './AIProvider.js';
import { parseAIResponse } from './parse.js';
export class GeminiProvider extends AIProvider {
constructor(apiKey, config = {}) {
super('gemini', apiKey, 12000);
this.model = config.geminiModel || 'gemini-pro';
this.timeout = config.timeout || 30000;
}
async generateCommitMessages(prompt, options) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), this.timeout);
try {
const response = await fetch('https://generativelanguage.googleapis.com/...', {
// ... your API call
signal: controller.signal,
});
// ... parse response
return parseAIResponse(text, options.maxSuggestions);
} finally {
clearTimeout(timer);
}
}
}Step 2. Register in src/providers/registry.js:
import { GeminiProvider } from './gemini.js';
registerProvider('gemini', GeminiProvider);Step 3. Add geminiApiKey in config wizard (src/core/config.js)
git diff --staged
β Show staged file list
β truncateDiff() (if too large)
β buildPrompt(diff, {lang, format, gitmoji})
β provider.generateCommitMessages(prompt)
β parseAIResponse() (JSON β newline fallback β retry)
β Inquirer (select / edit / regenerate loop)
β git commit -m "selected message"
β Show undo/amend hint
- Check environment β Verify git repo, read staged diff, show staged file list
- Load config β Merge defaults < config file < env vars < CLI options
- Auto setup β If API key missing, prompt to run config wizard immediately
- Truncate diff β If diff exceeds provider's limit, include stat summary + partial diff
- Build prompt β Combine diff with language, format (conventional/gitmoji), and suggestion count
- Call AI β Send to provider with 30s timeout. On parse failure, auto-retry once
- Interactive selection β Choose a message, edit it, or regenerate (loop until commit or cancel)
- Commit β Run
git commit -m "message"and show undo commands
| Error | Message | Recovery |
|---|---|---|
| Not a git repo | Not a git repository |
Exit |
| No staged changes | No staged changes. Run 'git add' first |
Exit |
| No API key | API key not configured for {provider} |
Auto-prompt config wizard |
| Unknown provider | Unknown provider: {name}. Available: claude, openai |
Exit |
| Invalid API key (401) | Invalid API key for {provider} |
Suggest aicommit config |
| Rate limited (429) | Rate limited. Please try again later |
Exit |
| Server error (5xx) | {provider} API error ({status}) |
Exit |
| Network/timeout | Network error. Check your connection |
Exit (30s timeout) |
| Diff too large | Diff truncated (too large for AI context) |
Auto-truncate with stat summary |
| Parse failure | β | Auto-retry once, then exit |
- API keys are stored in
~/.ai-commit.jsonwithchmod 600(owner-only read/write) - Environment variables (
AI_COMMIT_CLAUDE_KEY,AI_COMMIT_OPENAI_KEY) take priority over config file - Key masking β Existing keys shown as
sk-ant-***...***in config wizard - Diff privacy β Staged diff is sent only to the selected AI provider's API
- Home directory storage β Config file lives in
~/, never tracked by git
ai-commit/
βββ bin/
β βββ ai-commit.js # CLI entrypoint + interaction (211 lines)
βββ src/
β βββ core/
β β βββ config.js # Config load/save/wizard (128 lines)
β β βββ git.js # Git operations (29 lines)
β β βββ prompt.js # Prompt builder + diff truncate (62 lines)
β βββ providers/
β βββ AIProvider.js # Abstract base class (14 lines)
β βββ registry.js # Provider registry (26 lines)
β βββ parse.js # AI response parser, 3-stage fallback (33 lines)
β βββ claude.js # Claude API implementation (49 lines)
β βββ openai.js # OpenAI API implementation (48 lines)
βββ package.json
βββ README.md
βββ README.ko.md
βββ .gitignore
Total: ~600 lines across 9 source files, 4 dependencies.
| Category | Choice | Reason |
|---|---|---|
| Runtime | Node.js >= 18 (ESM) | Native fetch, wide adoption, npx distribution |
| CLI | Commander v12 | Lightweight, standard CLI parsing |
| Interaction | Inquirer v9 | Rich interactive prompts (list, password, confirm) |
| Styling | chalk v5 + ora v8 | Terminal colors + spinner |
| AI APIs | Native fetch (no SDK) |
Zero extra dependencies, consistent pattern across providers |
MIT