Skip to content

Teaching AI Coding Agents to Write Commits That Don't Suck

Published:
5 min read

If you’ve ever let an AI coding agent run git commit for you, you already know the problem. Every agent I’ve used defaults to something like:

fix stuff
update file.js
wip

Technically a commit. Utterly useless six months later when you’re running git blame trying to figure out why something was written the way it was. That annoyance is what turned into Smart Git Commit — not an app, but a skill: a portable set of instructions and scripts that any AI coding agent can load and follow, so the agent commits properly instead of however it feels like that day.

What a “skill” actually is

If you haven’t used Claude Code, Cursor, or similar tools, a skill is essentially a structured prompt plus supporting files that an agent reads before acting — a SKILL.md describing when to trigger and what to do, backed by scripts and reference docs it can call into. The trigger conditions live right in the frontmatter:

---
name: smart-git-commit
description: >
  Use this skill for ANY git operation — commits, pushes, PRs, releases,
  or version tagging. Triggers on: "commit", "push", "save my changes",
  "create a PR", "ship this", "make a release", "tag this version"...
---

The point of writing the description this way is that the agent’s own retrieval decides when to pull this skill in — you don’t have to remember to invoke it, it just activates whenever the conversation smells like a git operation.

An 11-phase workflow, not a one-liner

The core design decision was to stop treating “commit” as a single action and instead treat it as a pipeline with hard gates. The skill walks through phases like:

The secret scan and test gate are described in the skill as “never skip” — they’re not suggestions the agent can talk itself out of, they’re hard stops with an explicit exit code the agent has to check before moving forward.

The actual commit format

The part I cared about most was the message format itself. Instead of a single summary line, every commit follows a fixed five-part structure:

<type>(<scope>): <imperative summary — max 72 chars>

CONTEXT: <what state existed BEFORE this change — past tense>
CHANGE:  <exactly what was done — present tense, specific>
WHY:     <business or technical reason — not obvious from the code>
IMPACT:  <what this enables/unblocks>

<footers: Closes #N | BREAKING CHANGE: ...>

An example from the skill’s own reference set:

fix(payments): prevent double-charge on Stripe webhook retry

CONTEXT: Stripe delivered webhooks twice under high load due to 30s
         application timeout, causing duplicate charges.
CHANGE:  Adds idempotency_key (order_id + unix_ts hash) to all Stripe
         charge requests.
WHY:     Stripe's API natively deduplicates on idempotency keys —
         simpler than Redis-based deduplication.
IMPACT:  Eliminates billing support tickets for duplicate charges.

Fixes #301

The WHY line is the one that actually matters. Diffs already show you what changed — any agent can summarize that. What’s genuinely hard to reconstruct later is why a particular approach was chosen over the obvious alternative, so I made that a required field rather than an afterthought.

Making it portable across agents

Since I didn’t want this locked to one tool, the skill is installed the same way everywhere:

npx skills add Zarl-prog/Smart-git-commit

It’s currently set up to work across Claude Code, Cursor, Codex, Windsurf, OpenCode, and Gemini CLI, with a manual fallback (copying a CLAUDE.md-style config) for tools like GitHub Copilot that don’t support the skill format natively. Keeping the actual logic in plain bash scripts rather than anything agent-specific was what made that portability possible — the scripts don’t care which agent is calling them, they just take input and return an exit code.

What I’d change next

Right now the skill assumes a fairly standard repo layout to detect test runners and categorize files — monorepos with unusual structures can confuse the categorization step. Better handling for those is next on the list, along with expanding the secret-scanning patterns as new credential formats show up in the wild.

If you want to try it in your own agent setup, the repo has the full phase breakdown and all the supporting scripts.


Edit on GitHub