pi-ai-git-commit adds a /git-commit command to Pi. It collects the current Git changes, generates a commit message through a separate LLM call, and lets you review, edit, regenerate, or cancel before creating the commit.
The extension creates local commits only. It never runs git push.
- 🤖 Generates commit messages from staged, unstaged, and untracked changes through a separate LLM call, without switching the session model
- ✅ Interactive review before anything is written: commit, edit the message in a multi-line editor, regenerate, or cancel
- 🎯 One-time instructions:
/git-commit <instruction>adjusts format and style for a single generation - 📌 Persistent preferences: the
instructionsoption injects your style rules into every generation and can optionally use recent commit subjects as a style reference - 🌐 Output language switch (English, Simplified Chinese, Japanese, Korean, German, French) and fully replaceable prompt templates
- 🗂 Template management: create, switch, and remove prompt templates interactively with
/git-commit add,list, andremove - 🧹 Prompt budget management: filters lockfile, binary, and Base64 noise while keeping every file status visible in a structured summary
- 🔒 Safety first: a repository fingerprint blocks committing unreviewed changes; never pushes, never bypasses hooks
- Node.js >= 22.19.0
- A working model configuration in Pi
- Interactive TUI or RPC mode for
/git-commit
Install globally for all projects:
pi install npm:pi-ai-git-commitInstall for the current project only:
pi install -l npm:pi-ai-git-commitA project-local installation is written to .pi/settings.json and is loaded after the project is trusted.
If Pi is already running, reload it after installing:
/reload
Add the package to the global ~/.pi/agent/settings.json file:
{
"packages": ["npm:pi-ai-git-commit"]
}You can also add the same entry to the project-level .pi/settings.json file.
Install a local checkout persistently:
pi install /absolute/path/to/pi-ai-git-commitLoad a local checkout temporarily without changing Pi settings:
pi --no-extensions -e /absolute/path/to/pi-ai-git-commitSee the Pi Packages documentation for additional installation options.
Start Pi inside a Git repository that contains changes, then run:
/git-commit
Pi shows a Working indicator while the message is being generated. Cancel the generation at any time with the cancel key (Esc by default); nothing is written to the repository. When generation finishes, choose one of the following actions:
Commit Changes— create a local commit with the reviewed messageEdit Message— open a multi-line editor prefilled with the message; the edited message returns to the review dialog before committingRegenerate— collect the changes again and generate a new message; manual edits are passed to the model as contextCancel— stop without creating a commit
Text after the command applies only to the current generation:
/git-commit Emphasize the concurrency bug fixed by this change
/git-commit Do not use an emoji and return one line
/git-commit Use Gitmoji format without a Conventional Commit prefix
One-time instructions may change format and style, but the configured language remains authoritative. Without an explicit format instruction, the built-in prompt generates Conventional Commits by default:
feat(extension): ✨ add AI-powered Git commit generation
- Load user configuration and collect Git changes
- Generate commit messages through a separate model call
- Review, regenerate, or commit through the interactive dialog
For bodies that summarize two or more parallel changes, the built-in prompt prefers concise - bullets with one factual change per item. A single cause, consequence, or compatibility note remains a prose paragraph, and simple changes do not require a body.
/git-commit add with no arguments creates a new prompt template interactively:
/git-commit add
The flow asks for a template name, opens a multi-line editor for the template content, saves the file to ~/.pi/agent/ai-git-commit/templates/<name>.md, and offers to activate it immediately. If a template with the same name already exists, the flow asks before overwriting it.
Only the exact no-argument command is treated as the template shortcut. Additional text remains a one-time commit instruction, so /git-commit add a scope generates a commit message using that instruction instead of opening template management.
/git-commit list with no arguments shows every available template in a selector:
/git-commit list
The selector merges built-in templates with the files in ~/.pi/agent/ai-git-commit/templates/ (a user template with the same name replaces the built-in one), lists user templates before built-in ones, and marks the currently active entry. Use the arrow keys to pick a template and press Enter to activate it; press Esc to leave everything unchanged.
The selection is written to the closest configuration layer:
- If the project has
<repository>/.pi/ai-git-commit.json, itstemplatefield is updated. - Otherwise the global
~/.pi/agent/ai-git-commit/ai-git-commit.jsonis updated, and the file is created when it does not exist yet.
/git-commit remove with no arguments opens a selector for templates in ~/.pi/agent/ai-git-commit/templates/:
/git-commit remove
The command always asks for confirmation before deletion. Built-in templates cannot be removed; deleting a user template named default simply reveals the built-in default again. Additional text remains a one-time commit instruction, so /git-commit remove emoji requests a commit message without emoji rather than removing a template.
If the deleted template is still referenced by the current project or global configuration, those template fields are reset to default automatically, so the next generation keeps working.
When /git-commit runs, the extension:
- Verifies that the current directory is a Git repository and rejects unresolved conflicts.
- Collects staged, unstaged, and untracked changes according to
changeSource. - Builds a structured change summary and filters noisy lockfiles, binary files, source maps, long Base64 content, and other oversized data.
- Generates a commit message with the current session model or a separately configured model without switching the session model.
- Displays the generated message for review. The message can be edited manually, regenerated, committed, or cancelled.
- Checks the repository snapshot again before committing. If the repository changed, the commit is cancelled and must be regenerated.
- Creates a normal local Git commit while preserving Git hooks.
The changeSource option determines which changes are analyzed and committed.
| Value | Behavior |
|---|---|
auto |
Uses staged when the index contains changes; otherwise uses all. This is the default. |
staged |
Analyzes and commits only staged changes. It does not modify unstaged or untracked files. |
all |
Analyzes all non-ignored changes. After confirmation, it stages changes with the equivalent of git add -A -- . and creates the commit. |
auto prioritizes an existing partial staging selection. Before using all, make sure every non-ignored working-tree change belongs in the same commit.
The global user configuration file is:
~/.pi/agent/ai-git-commit/ai-git-commit.json
When PI_CODING_AGENT_DIR is set, the effective path is:
$PI_CODING_AGENT_DIR/ai-git-commit/ai-git-commit.json
Only fields that need to override the defaults are required. For example:
{
"template": "default",
"language": "en",
"changeSource": "auto",
"instructions": "Never use emoji. Always include a scope.",
"provider": null,
"model": null,
"maxDiffChars": 50000,
"maxOutputTokens": 2048,
"commitHistoryCount": 0,
"signoff": false,
"timeoutMs": null
}| Field | Type | Default | Description |
|---|---|---|---|
template |
string |
default |
Name of the prompt template that fully controls message format and writing rules. User templates take precedence over built-ins. A non-default template that cannot be read falls back to the built-in default with a warning. |
instructions |
string | null |
null |
Persistent style preferences appended to every generation. Maximum length: 16000 characters. |
changeSource |
staged | all | auto |
auto |
Selects the Git changes to analyze and commit. |
language |
en | zh | ja | ko | de | fr |
en |
Output language of the generated message: English, Simplified Chinese, Japanese, Korean, German, or French. |
provider |
string | null |
null |
Provider for the separate generation model. Must be configured together with model. |
model |
string | null |
null |
Model ID for the separate generation model. Must be configured together with provider. |
maxDiffChars |
number |
50000 |
Unicode character budget for change content and the maximum allowed template length. Template content is checked separately from the dynamic change prompt. Allowed range: 1000–500000. |
maxOutputTokens |
number |
2048 |
Model output token limit, including reasoning tokens used by some models. Allowed range: 1–4096. |
commitHistoryCount |
number |
0 |
Number of recent commit subjects injected as a style reference. 0 disables it. Allowed range: 0–50. |
signoff |
boolean |
false |
Adds a DCO Signed-off-by trailer by committing with --signoff. |
timeoutMs |
number | null |
null |
Timeout for the generation request in milliseconds. null disables it. Allowed range: 1000–600000. |
Package defaults are loaded from config/default.json first, then the global configuration overrides them, and finally the project-level configuration overrides both:
<project>/.pi/ai-git-commit.json
The project-level file is optional and follows the same format. Fields set there take precedence over the global configuration, which is useful for per-repository settings such as a different language or changeSource.
The language setting only controls the language of the generated commit message. It does not localize dialogs, error messages, or any other output.
Supported values: en (English), zh (Simplified Chinese), ja (Japanese), ko (Korean), de (German), fr (French).
Generate commit messages in English:
{
"language": "en"
}Generate commit messages in Simplified Chinese:
{
"language": "zh"
}instructions appends persistent style preferences to every generation while keeping the built-in prompt and its safety rules:
{
"instructions": "Never use emoji. Always include a scope."
}Precedence when rules conflict: one-time /git-commit <instruction> > persistent instructions > built-in defaults. The configured language remains authoritative. Set project-level instructions in <project>/.pi/ai-git-commit.json to enforce a different convention per repository. The maximum length is 16000 characters.
commitHistoryCount is 0 by default, so no history is read. Set it to N (up to 50) to inject the subjects of the N most recent commits (git log --format=%s) as a style reference, so generated messages match the existing repository conventions:
{
"commitHistoryCount": 10
}The subjects are treated as untrusted reference data, never as instructions. Repositories with fewer commits than N or without history are handled silently.
Set signoff to true to commit with --signoff, which appends the standard Signed-off-by trailer required by DCO-based projects such as the Linux kernel and many CNCF projects. The review dialog clearly indicates that Git will append the trailer:
{
"signoff": true
}By default the generation request waits until the model responds. Set timeoutMs to abort automatically on slow models or networks:
{
"timeoutMs": 60000
}When the timeout is reached, the request is aborted and an error explains how to adjust the value. In TUI mode, the generation loader can also be cancelled manually. Allowed range: 1000–600000 milliseconds; null disables the timeout.
Reasoning models can spend a long time thinking before the final message, and their thinking tokens count against maxOutputTokens. When the separate generation model is a reasoning model, set timeoutMs so slow generations fail with an actionable error instead of waiting silently, and increase maxOutputTokens if the model runs out of budget before producing text.
The template field selects the prompt template that has final authority over the message format. Templates are Markdown files resolved by name, with user templates taking precedence over the built-in ones:
~/.pi/agent/ai-git-commit/templates/<name>.md (user templates)
<package>/templates/<name>.md (built-in templates)
The built-in default template generates Conventional Commits with an optional type-matched emoji. To use a custom format, create a template file such as ~/.pi/agent/ai-git-commit/templates/team-style.md:
Generate one accurate and concise commit message. Start the subject with an uppercase verb and keep it under 50 characters. Return only the final message.
Then select it in the configuration:
{
"template": "team-style"
}A user template with the same name as a built-in one (for example default.md) overrides the built-in version. A missing, empty, or unreadable non-default template falls back to the built-in default and emits a warning. A user-provided default.md is authoritative: if that file is empty or unreadable, generation stops with an actionable error instead of silently bypassing it.
Template content is counted by Unicode characters. If it exceeds maxDiffChars, generation stops before the model request and asks you to shorten the template or increase the configured budget. The dynamic repository-change budget remains independent. When using the built-in template, /git-commit <instruction> can also change the format for one generation, but it cannot override the configured output language.
When provider and model are both null, the extension reuses the current session model:
{
"provider": null,
"model": null
}To use another model, set both fields to provider and model IDs available in the Pi model registry:
{
"provider": "your-provider-id",
"model": "your-model-id"
}Generation uses a separate blocking side-channel request and does not change the model selected for the current session.
- Never runs
git push. - Never bypasses Git hooks.
- Never uses destructive commands to restore the index or working tree.
- Executes Git commands with argument arrays rather than shell command concatenation.
- Refuses to generate or commit while unresolved conflicts exist.
- Refuses to commit unreviewed content when the repository changes after generation.
- Preserves staged changes when an
allmode commit fails, allowing inspection and retry. - Treats repository paths, source code, comments, and diffs as untrusted data rather than model instructions.
Pi packages can execute local code with the user's permissions. Review the source before installing any third-party extension.
Make sure the file is located at:
~/.pi/agent/ai-git-commit/ai-git-commit.json
Not at:
~/.pi/ai-git-commit.json
~/.pi/agent/ai-git-commit.json
Also verify that the file contains valid JSON, then restart or reload the Pi session.
When changeSource is staged, stage the intended files first:
git add <files>Alternatively, set changeSource to auto or all.
Both fields must be configured together or both set to null:
{
"provider": null,
"model": null
}The file content, index, or HEAD changed after the message was generated. To prevent unreviewed content from being committed, the extension cancels the commit. Run the command again or choose Regenerate.
The extension reports the model name, stop reason, and response content types without printing repository content or credentials.
stop reason: length— increasemaxOutputTokensinai-git-commit.json, up to 4096, or choose a model with a smaller reasoning budget.content types: thinkingwithouttext— the model used its output budget for reasoning before producing the final message; increasemaxOutputTokens.stop reason: toolUse— use a text-generation model and verify provider/model compatibility.- A provider request or authentication error — verify the provider, model ID, credentials, base URL, and network connection.
/git-commit requires an interactive TUI or RPC UI. In print/json mode, the extension reports that an interactive interface is required and does not create a commit.
Update the extension:
pi update npm:pi-ai-git-commitRemove the global installation:
pi remove npm:pi-ai-git-commitRemove the project-local installation:
pi remove -l npm:pi-ai-git-commitList installed Pi packages:
pi list