Skip to content

tmonk/pi-committer

Repository files navigation

pi-committer

Conventional commit automation for the pi coding agent.

Creates commits as you work. The extension is opt-in — enable it per-project with a config file.

Features

  • Commits automatically when a pi-goal completes (on_goal trigger, opt-in). Other modes available.
  • Splits diffs into separate commits via a subagent (e.g. feature and tests in one commit, docs in another).
  • Commit messages generated by a subagent using your model.
  • Pick the model with /commit-model or the subagent_model config key.
  • Detects and commits in any git repositories the agent touched.
  • commit_changes tool that agents can call to checkpoint work.
  • Exclusion patterns for files matching glob patterns (*.log, build/, etc.).
  • Slash commands: /commit, /commit-config, /commit-model.

Quick start

Install from npm (recommended)

pi install npm:pi-committer

This installs the package globally. Pi auto-loads it on startup.

Install from source

git clone https://github.com/tmonk/pi-committer.git
cd pi-committer && npm install

# Load it in a session
pi -e ./index.ts

Global auto-discovery (source install)

ln -s ~/projects/pi-committer ~/.pi/agent/extensions/pi-committer

Configuration

Create .pi-committer.toml (or .pi-committer.json) in your project root. The extension walks up directories to find it.

[committer]
enabled           = false             # off by default; set to true to enable
trigger_mode      = "on_goal"       # on_goal | agent_sensible | after_tool | manual
detailed_body     = true
min_changes       = 1
staged_commits    = true
exclude_patterns  = ["*.log", "node_modules/"]

# When true and trigger_mode is "on_goal", the commit_changes tool will skip
# when pi-goal has an active goal and defer to the automatic commit-after-audit
# flow. Defaults to false — commit_changes always proceeds immediately unless
# you explicitly opt in to deferral.
# defer_to_goal_audit = false

# Minimum number of changed files before the subagent is called for grouping.
# Small change sets below this threshold use a single commit with a
# subagent-generated message (unless also below subagent_message_min_files).
# Default: 15 (determined empirically — see benchmark results).
# subagent_grouping_min_files = 15

# Minimum number of changed files before the subagent is called for the
# commit message. Below this threshold, the deterministic fallback is used
# directly (no LLM call at all). Default: 3 — 1-2 file changes are simple
# enough for deterministic.
# subagent_message_min_files = 3

# Optional: override the model used by the commit-message subagent
# subagent_model = "openai/gpt-4o-mini"

# Threshold for async (background subprocess) commits. When the number of changed
# files >= this value, /commit and commit_changes fork the commit pipeline into a
# detached subprocess so the conversation continues immediately. The widget shows
# progress and Esc cancels. Default: 10. Set to 0 to disable async (always sync).
# async_threshold = 10

# Optional: extend conventional commit types / restrict scopes
# custom_types    = ["api", "wip"]
# allowed_scopes  = ["api", "cli", "core"]

Trigger modes

Mode Behaviour
on_goal Commits when a goal transitions to complete
agent_sensible Commits after every agent turn
after_tool Commits after each tool call
manual (default) Never auto-commits; use /commit or commit_changes only

Usage

First, enable auto-commit in your project config:

# .pi-committer.toml
[committer]
enabled = true

Auto-commit on goal completion

With enabled = true and trigger_mode = "on_goal" (default), the extension hooks into pi-goal's lifecycle. When a goal managed by pi-goal transitions to complete status, pi-committer automatically stages and commits the changes:

/goals "Add user authentication"   ← start a goal via /goals
> agent implements auth logic       ← work happens
> pi-goal marks the goal complete   ← pi-committer auto-commits

The commit is triggered by the goal state transition — no manual /commit needed.

Manual commit

/commit

Or ask the agent to "save my progress" and it will call the commit_changes tool.

Choose the commit-message model

/commit-model

Opens an interactive selector. Defaults to your current agent model.

Reload config

/commit-config

Staged commits

When staged_commits = true (default), the subagent receives the diff and organizes changes into commit groups. Editing a source file, adding tests, and updating docs might produce:

feat(api): add user authentication endpoint
test(api): add authentication tests
docs: update API documentation

The subagent decides the grouping from the diff content, not from file extensions.

Multi-repo

If the agent edits files in multiple git repositories during a session, commit_changes finds and commits in all of them. Detection works via session tool-call history — repos where the agent created or modified files using write or edit tools are detected and added on top of the primary working directory.

Deterministic commit message fallback

When the subagent is unavailable (e.g., SDK load failure) or returns no result, pi-committer generates a deterministic commit message using string analysis — no LLM calls needed:

  • Smart scope: Uses the longest common ancestor directory across all changed files. If files span unrelated directories, scope is omitted entirely.
  • Specific description: Extracts meaningful keywords from file names (strips extensions, skips boilerplate like __init__ and conftest, converts snake_case to readable words). Never says "update N modules".
  • Structured body: Includes the description summary line followed by a file list with change stats.

Every subagent fallback decision point logs a DIAG: diagnostic message to help identify root causes.

Architecture

Extension events (turn_end, tool_result, goal_event)
        │
        ▼
  commitAllRepos(dir, ctx)
        │
        ├─ findDirtyRepos(ctx)     discover all dirty repos
        │
        └─ tryCommit(repo, ...)    for each dirty repo
               │
               ├─ stageAll / unstageExcluded
               │
               ├─ generateStagedCommitGroups   subagent decides grouping
               │      └─ createAgentSession    no tools, diff inline
               │             └─ prompt: "Organize changes into logical commits"
               │
               ├─ generateCommitMessageViaSubagent   single-commit fallback
               │
               └─ git commit for each group

The subagent uses createAgentSession from @earendil-works/pi-coding-agent, the same pattern as pi-goal's runGoalCompletionAuditor. No pi-subagents dependency required.

Requirements

  • pi coding agent 0.71+
  • Node.js 18+
  • Git
  • smol-toml (installed via npm install)

Development

git clone <this-repo>
cd pi-committer
npm install

npm test            # unit tests
npm run test:e2e    # end-to-end tests

License

MIT

About

Conventional commit automation for the pi coding agent.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors