AI-powered git commit messages directly in Neovim.
This plugin generates conventional commit messages using AI. Stage your changes, run :AICommit, and get a properly formatted commit message. It's that simple.
Minimal setup:
{
"pilo404/aicommits.nvim",
config = true,
}
With custom config:
{
"pilo404/aicommits.nvim",
config = function()
require("aicommits").setup({
providers = {
openai = {
model = "gpt-5.6-luna",
max_length = 72,
generate = 3,
},
},
})
end,
}
packer.nvim:
use {
"pilo404/aicommits.nvim",
config = function()
require("aicommits").setup()
end
}
vim-plug:
Plug 'pilo404/aicommits.nvim'
lua << EOF
require("aicommits").setup()
EOF
Set your OpenAI API key:
export AICOMMITS_NVIM_OPENAI_API_KEY="sk-..."
Or use the standard OpenAI environment variable:
export OPENAI_API_KEY="sk-..."
Prerequisites:
Authentication Setup:
Choose one of the following methods:
User credentials (recommended for development):
gcloud auth application-default login
Service account (recommended for production):
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
Configure in your Neovim setup:
require("aicommits").setup({
active_provider = "vertex",
providers = {
vertex = {
enabled = true,
model = "gemini-2.0-flash-lite",
project = "your-gcp-project-id", -- Required: Your GCP project ID
location = "us-central1", -- GCP region
max_length = 50,
generate = 3, -- Generate 3 options to choose from
temperature = 0.7,
},
},
})
Note: Authentication is handled automatically via gcloud. The plugin will call gcloud auth application-default print-access-token to obtain OAuth tokens as needed. Tokens are cached for 55 minutes to minimize gcloud calls.
Simpler alternative to Vertex AI - uses Google AI Studio API with straightforward API key authentication.
Prerequisites:
Key Differences from Vertex AI:
| Feature | Gemini API | Vertex AI |
|---|---|---|
| Authentication | Simple API key | Google Cloud credentials |
| Setup Required | Just get API key | GCP project, gcloud CLI |
| Target Users | Individuals, prototyping | Enterprise, production |
| Free Tier | Generous free tier | GCP billing required |
Authentication Setup:
Set your Gemini API key:
export AICOMMITS_NVIM_GEMINI_API_KEY="your-api-key-here"
Or use the generic Gemini environment variable:
export GEMINI_API_KEY="your-api-key-here"
Configure in your Neovim setup:
require("aicommits").setup({
active_provider = "gemini-api",
providers = {
["gemini-api"] = {
enabled = true,
model = "gemini-2.5-flash", -- Latest Gemini model
max_length = 50,
generate = 3, -- Generate 1-8 commit message options
temperature = 0.7,
max_tokens = 200,
thinking_budget = 0, -- 0 = disabled (default, faster/cheaper), -1 = dynamic, 1-24576 = manual
},
},
})
Available Models:
gemini-2.5-flash - Latest, recommended (GA)gemini-2.0-flash-exp - Experimental Gemini 2.0gemini-1.5-flash - Stable Gemini 1.5Performance Notes:
thinking_budget is set to 0 by default to disable internal reasoning, which keeps responses fast and token usage lowthinking_budget = -1 (dynamic) or a specific value (1-24576)max_tokens to 1000+ to accommodate reasoning tokensNote: This provider uses the generativelanguage.googleapis.com API endpoint, which is completely separate from Vertex AI. No Google Cloud project or gcloud CLI required!
Prerequisites:
Authentication Setup:
Set your Anthropic API key:
export AICOMMITS_NVIM_ANTHROPIC_API_KEY="sk-ant-..."
Or use the standard Anthropic environment variable:
export ANTHROPIC_API_KEY="sk-ant-..."
Configure in your Neovim setup:
require("aicommits").setup({
active_provider = "anthropic",
providers = {
anthropic = {
enabled = true,
model = "claude-haiku-4-5",
max_length = 50,
temperature = 0.7,
max_tokens = 200,
},
},
})
# Stage changes
git add .
In Neovim:
:AICommit
The plugin will:
If you use Neogit, press C in the status buffer to trigger AI commits.
All options with defaults:
require("aicommits").setup({
-- Provider Configuration
active_provider = "openai", -- Which AI provider to use
providers = {
-- OpenAI Configuration
openai = {
enabled = true, -- Enable/disable this provider
api_key = nil, -- API key (nil = use environment variables)
endpoint = nil, -- Custom endpoint (nil = use default)
model = "gpt-5.6-luna", -- Which model to use (gpt-5-family/o-series models are treated as reasoning models)
max_length = 50, -- Max characters in commit message
generate = 1, -- Number of options (1-5)
reasoning_effort = "none", -- Reasoning models only; valid values vary by model generation (see table below)
verbosity = "low", -- Reasoning models only; valid values vary by model generation (see table below)
-- Advanced options (ignored for reasoning models; see note below)
temperature = 0.7, -- Sampling temperature (0-2)
top_p = 1, -- Nucleus sampling parameter
frequency_penalty = 0, -- Frequency penalty (-2 to 2)
presence_penalty = 0, -- Presence penalty (-2 to 2)
max_tokens = 200, -- Maximum tokens in response
},
-- Google Vertex AI Configuration
-- Requires gcloud CLI: https://cloud.google.com/sdk/install
-- Authentication: gcloud auth application-default login
-- Or set GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
vertex = {
enabled = false, -- Enable/disable this provider
model = "gemini-2.0-flash-lite", -- Vertex AI model
project = nil, -- GCP project ID (required)
location = "us-central1", -- GCP region
max_length = 50, -- Max characters in commit message
generate = 3, -- Number of options (generates 3 by default)
temperature = 0.7, -- Sampling temperature (0-2)
max_tokens = 200, -- Maximum tokens in response
},
-- Google Gemini API (AI Studio) Configuration
-- Get API key from: https://aistudio.google.com
-- Simpler alternative to Vertex AI - no GCP project required
["gemini-api"] = {
enabled = false, -- Enable/disable this provider
api_key = nil, -- API key (nil = use environment variables)
model = "gemini-2.5-flash", -- Gemini model (gemini-2.5-flash, gemini-2.0-flash-exp, gemini-1.5-flash)
max_length = 50, -- Max characters in commit message
generate = 1, -- Number of options (1-8)
temperature = 0.7, -- Sampling temperature (0-2)
max_tokens = 200, -- Maximum tokens in response
thinking_budget = 0, -- Thinking budget: 0 = disabled (default, faster/cheaper), -1 = dynamic, 1-24576 = manual
},
-- Anthropic Claude Configuration
-- Get API key from: https://console.anthropic.com
anthropic = {
enabled = false, -- Enable/disable this provider
api_key = nil, -- API key (nil = use environment variables)
model = "claude-haiku-4-5", -- Claude model to use
max_length = 50, -- Max characters in commit message
temperature = 0.7, -- Sampling temperature (0-1)
max_tokens = 200, -- Maximum tokens in response
},
-- Future providers can be added here
-- ollama = { ... },
},
-- UI settings
ui = {
use_custom_picker = true, -- Custom picker vs vim.ui.select
picker = {
width = 0.4, -- Percentage of screen width
height = 0.3, -- Percentage of screen height
border = "rounded", -- Border style
},
},
-- Integrations
integrations = {
neogit = {
enabled = true, -- Auto-refresh after commit
mappings = {
enabled = true, -- Add keymap in status buffer
key = "C", -- Which key to use
},
},
},
-- Debugging
debug = false,
})
The plugin uses a provider system to support multiple AI services. Each provider has its own configuration section under providers.
Configure OpenAI with custom settings:
require("aicommits").setup({
active_provider = "openai",
providers = {
openai = {
model = "gpt-5.6-luna", -- Use a different model
max_length = 72, -- Longer commit messages
generate = 3, -- Generate 3 options to choose from
},
},
})
reasoning_effort and verbosity are optional and only take effect for gpt-5-family/o-series reasoning models like gpt-5.6-luna. For these models, temperature, top_p, frequency_penalty, and presence_penalty are ignored (fixed by the API), and max_tokens is sent as max_completion_tokens instead. Classic models like gpt-4.1-nano are unaffected and keep using all of the advanced options above.
reasoning_effort/verbosity valid values by model (verified against the live public Chat Completions API; this is a different enum per model generation, and a different enum entirely from the Codex provider below):
| Model | Valid reasoning_effort |
Valid verbosity |
|---|---|---|
gpt-5, gpt-5-mini, gpt-5-nano (no version decimal) |
minimal, low, medium, high |
low, medium, high |
gpt-5.1 (any -mini/-nano suffix) |
none, low, medium, high (no xhigh) |
low, medium, high |
gpt-5.2, 5.4, 5.5, 5.6 incl. 5.6-luna/5.6-sol/5.6-terra (any -mini/-nano suffix) |
none, low, medium, high, xhigh |
low, medium, high |
any *-chat-latest (overrides the base version's row) |
medium only |
low, medium, high |
o3, o4-mini |
low, medium, high, xhigh |
medium only |
none and minimal are the same intent under different names: gpt-5-base calls it minimal, gpt-5.2+ renamed it to none. Passing the wrong generation's spelling for the model you configured is the most common mistake here — validate_config catches it and tells you which spelling to use instead.
Only gpt-5.6-luna, gpt-5.6-sol, and gpt-5.6-terra are used elsewhere in this README/config, but the provider works with any gpt-5-family or o3/o4-mini model — override reasoning_effort/verbosity per the table above if you switch models. Models not listed in the table — including dated snapshot ids like gpt-5-2025-08-07 — are accepted without local validation; the API is the source of truth for those, and its own error message names the valid set. That deliberately includes future releases — a gpt-5.7 is not assumed to follow the gpt-5.6 row, because a new model shipping a new effort value would otherwise be rejected locally for a value the API accepts. *-codex and *-pro models are not usable through this provider at all — they 404 on /v1/chat/completions (they're Responses-API-only, or deprecated).
Use a custom OpenAI-compatible endpoint:
require("aicommits").setup({
providers = {
openai = {
endpoint = "https://your-proxy.com/v1/chat/completions",
api_key = "your-api-key", -- Or use environment variables
model = "gpt-4.1-nano",
},
},
})
Configure Vertex AI Gemini:
require("aicommits").setup({
active_provider = "vertex",
providers = {
vertex = {
enabled = true,
model = "gemini-2.0-flash-lite",
project = "my-gcp-project", -- Required: Your GCP project ID
location = "us-central1", -- GCP region
max_length = 50,
generate = 3, -- Generate 3 options to choose from
temperature = 0.7,
max_tokens = 200,
},
},
})
Authentication:
Vertex AI uses gcloud for authentication. You must have gcloud CLI installed and configured:
Install gcloud CLI:
# macOS
brew install google-cloud-sdk
# Or download from: https://cloud.google.com/sdk/install
Authenticate (choose one):
# Option 1: User credentials (development)
gcloud auth application-default login
# Option 2: Service account (production)
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
The plugin will automatically call gcloud auth application-default print-access-token to obtain OAuth tokens. Tokens are cached for 55 minutes to minimize gcloud calls.
Prerequisites:
codex login session.$CODEX_HOME/auth.json (defaulting to ~/.codex/auth.json) to obtain the session's access token and account id. This read is strictly read-only — the file is never written, refreshed, or moved by this plugin.Configure Codex:
require("aicommits").setup({
active_provider = "codex",
providers = {
codex = {
enabled = true, -- Opt in: disabled by default
endpoint = nil, -- API endpoint (nil = ChatGPT Codex backend default)
model = "gpt-5.6-terra", -- Known-good models: gpt-5.6-terra, gpt-5.6-luna, gpt-5.6-sol
reasoning_effort = "none", -- ChatGPT Codex backend enum (differs from openai provider): none|low|medium|high|xhigh|max
verbosity = "low", -- low|medium|high - the only supported length control
max_length = 50, -- Maximum commit message length
generate = 1, -- Must be 1; the backend gives no fan-out
request = { timeout_ms = 120000 }, -- Reasoning-model latency headroom
},
},
})
verbosity is the only working length control. temperature, top_p, and max_tokens are rejected outright by this backend at any reasoning effort, so no such keys exist in the Codex provider's configuration. generate must be 1 — the backend has no fan-out.
Risk disclosure — read before enabling
https://chatgpt.com/backend-api/codex/responses) is undocumented and internal to ChatGPT, not a published, supported API.A sudden run of transport failures may indicate Cloudflare fingerprint blocking of the underlying HTTP client rather than a bug in this plugin.
This provider ships with enabled = false. Opting in is a deliberate act.
Use vim.ui.select instead of custom picker:
require("aicommits").setup({
ui = {
use_custom_picker = false,
},
})
Disable Neogit integration:
require("aicommits").setup({
integrations = {
neogit = { enabled = false },
},
})
| Command | What it does |
|---|---|
:AICommit |
Generate and create commit |
:AICommitHealth |
Check if everything is set up |
:AICommitDebug |
Show debug info |
All commits follow Conventional Commits:
<type>(<scope>): <description>
Types:
feat - New featurefix - Bug fixdocs - Documentationstyle - Formattingrefactor - Code restructuringperf - Performancetest - Testsbuild - Build systemci - CI changeschore - OtherExamples:
feat(auth): add OAuth2 support
fix(api): handle null responses
docs: update installation steps
"OpenAI API key not found"
Set the environment variable and restart Neovim.
"No staged changes found"
Run git add first.
"Not in a git repository"
Navigate to a git repo or run git init.
Check setup
Run :AICommitHealth to verify everything is configured correctly.
Use app.sh to run the same checks that CI runs:
./app.sh setup # First-time setup
./app.sh test # Run tests (same as CI)
./app.sh lint # Check formatting (same as CI)
./app.sh ci # Run all CI checks locally
./app.sh status # Check environment
Contributions welcome! See CONTRIBUTING.md for guidelines.
MIT License - see LICENSE.