| name | smart-commit |
| description | Analyze working tree changes, group them into logical atomic commits with Conventional Commits messages, and push. Handles staging, sensitive file exclusion, and uv.lock bundling automatically. Use PROACTIVELY when: commit, git commit, save changes, commit and push, stage changes, push my changes, commit this work, ship it.
|
Smart Commit Workflow
Commit summaries may be written in Japanese or English. Conventional Commit
type/scope tokens remain English; keep the summary language consistent with the
work and surrounding history.
Dynamic Context
Current branch:
!git rev-parse --abbrev-ref HEAD
Working tree status:
!git status --short
Recent commit style:
!git log --oneline -5
Branch Guard
Never commit directly to main. If the current branch is main, abort
immediately and tell the user to create a feature branch first. The pre-commit
hook also enforces this, but check early to avoid wasted work.
Step 1: Analyze Changes
Review staged and unstaged changes to understand what was modified.
git status
git diff
git diff --cached
If changes are already staged, prioritize those — the user has expressed intent
about what to commit. If nothing is staged, treat all modified/untracked files
as candidates.
Step 2: Sensitive File Check
Never commit files that could contain secrets:
.env, .env.* (environment variables)
**/credentials.json, **/secrets.json, **/private-key.*
- Files matching
*password*, *secret*, *key*.pem
If any are detected among the candidates, exclude them and warn the user.
Do not automatically include unrelated or incomplete work merely because it is
not sensitive; preserve user-owned changes and report anything left out.
Step 3: Group Changes
Analyze the changes and group them into logical, atomic commits. Each commit
should be independently meaningful. The goal is to tell a clear story of what
happened through the commit history.
Grouping rules:
-
Tests (tests/): prefix test:
- New tests →
test: add ...
- Fixed tests →
test: fix ...
-
Documentation (.md, docs/): prefix docs:
-
Configuration (.json, .yml, .claude/): prefix chore:
-
Dependencies (pyproject.toml dependency changes): prefix chore:
- Always include
uv.lock in the same commit
-
Build system (pyproject.toml build/tool config, justfile): prefix build:
-
Source code (src/):
- New feature →
feat:
- Bug fix →
fix:
- Refactor →
refactor:
- Performance →
perf:
-
CI/CD (.github/): prefix ci:
Special cases:
uv.lock changes must be in the same commit as the pyproject.toml
dependency change that caused them
- A behavioral source change, its regression test, and any required canonical
requirement/design update belong in the same logical commit by default
If all changes are closely related, a single commit is fine. Don't split
artificially — three related one-line changes are better as one commit than
three separate commits.
Step 4: Verify Each Group
Before staging a behavioral group, run the narrowest relevant test target and
the applicable changed-path invariant review from AGENTS.md. Call counts may
be verified when retry, rate, budget, or no-call behavior is the contract.
If this commit completes the requested work, run just verify. For an
intermediate atomic commit, targeted tests plus the existing pre-commit hooks
are sufficient; report that full verification remains pending.
Do not commit a group whose relevant test fails.
Step 5: Create Commits
For each group, stage the relevant files and commit:
git add <file1> <file2> ...
git commit -m "$(cat <<'EOF'
<type>(<optional-scope>): <short summary>
EOF
)"
Commit message format:
- Conventional Commits:
<type>(<optional-scope>): <short summary>
- Types:
feat, fix, docs, refactor, test, ci, chore, perf, build
- Summary: imperative mood, lowercase start, no period at end
- Under 72 characters
- Focus on what changed, not how
Examples:
feat(core): add JSON export support
fix: handle empty input without raising TypeError
test: add parametrized tests for edge cases
docs: update API reference for new export function
chore: configure .claude/rules for path-scoped linting
Stage specific files by name — avoid git add . or git add -A which can
accidentally include sensitive files or unrelated changes.
Step 6: Push (if requested)
Only push if the user explicitly asked to push (e.g., "commit and push",
"ship it"). If the user only said "commit", skip this step — they may want
to make more commits before pushing, or use the create-pr skill which
handles push on its own.
git push
git push -u origin <current-branch>
Step 7: Verify
Show the final state to confirm everything is clean:
git status
git log --oneline -<number-of-new-commits>
Report any remaining uncommitted files and explain why they were excluded
(should only be sensitive files).
Pre-commit Hook Interaction
This project has pre-commit hooks (ruff, ruff-format, mypy, typos, etc.) that
run automatically on git commit. The skill does NOT duplicate these checks —
the hooks handle code quality, while the skill handles commit workflow.
When a hook fails:
- The commit did NOT happen — staged files remain staged but uncommitted
- Some hooks (ruff --fix, trailing-whitespace, end-of-file-fixer) auto-fix
files. These fixes are unstaged modifications after the failed commit
- Re-stage the auto-fixed files:
git add <fixed-files>
- Create a NEW commit (same message is fine) — never
--amend
- Never use
--no-verify to skip hooks — fix the underlying issue instead
Common hook failures and fixes:
ruff: fix the lint error reported, or the hook may have auto-fixed it
mypy: fix the type error in source code
typos: fix the typo, or add the word to typos.toml if it's a false positive
Notes
- When in doubt about grouping, fewer larger commits are better than many tiny ones