Agent skill

smart-commit

Smart batch commit. Analyzes uncommitted changes, groups by cohesion, generates commit messages matching project style. Default: output git commands for manual execution. With --execute: directly run git add + git commit (requires user approval). Use when: user says 'commit', 'batch commit', 'prepare commit', 'write commit message', or /smart-commit

Stars 139
Forks 18

Install this agent skill to your Project

npx add-skill https://github.com/sd0xdev/sd0x-dev-flow/tree/main/skills/smart-commit

SKILL.md

Smart Commit

Analyze uncommitted changes → group by cohesion → generate commit messages → output git commands (or execute directly with --execute).

Workflow

mermaid
sequenceDiagram
    participant C as Claude
    participant U as User
    C->>C: Step 1a: Detect permissions
    C->>C: Step 1b: Learn commit style
    C->>C: Step 1c: Identity diagnostics
    C->>C: Step 1d: Signing diagnostics
    C->>C: Step 1e: AI guard readiness
    C->>C: Step 2: Pre-flight check (precommit)
    C->>C: Step 3: Collect changes + exclude sensitive files
    C->>C: Step 4: Group (high cohesion)
    C->>U: Show commit plan (with Author/Signing/Guard)
    U->>C: Confirm/adjust
    loop Each commit group
        C->>C: Read diff → generate message
        C->>C: AI trailer sanitization
        alt --execute mode
            C->>C: Runtime validation → git commit
        else manual mode
            C->>U: Output git commands
        end
    end
    C->>C: Step 6: Verification + post-commit leak detection

Step 1: Detect Permissions + Learn Style

1a. Permission Detection

Read CLAUDE.md and .claude/rules/git-workflow.md to determine mode:

Mode Condition Behavior
manual No --execute flag (default) Output commands only
execute --execute flag passed Execute directly (with user approval via AskUserQuestion)

Default to manual mode. Direct execution requires explicit --execute flag regardless of project git restrictions.

--execute mode: When --execute is passed, use AskUserQuestion to show the full commit plan and get explicit user approval before executing. This is a skill-level exception to git-workflow rules (same pattern as /push-ci).

1b. Learn Commit Style

bash
git log --oneline -15

Infer format, type vocabulary, subject conventions (capitalization/tense/ticket ID), and language from recent commits.

1c. Identity Diagnostics

Shared diagnostic (preferred path):

bash
bash scripts/run-skill.sh git-profile git-profile.sh doctor --json

If the script succeeds, parse the JSON output:

  • status: "ok" → silent continue, use effective_identity and signing fields
  • status: "warn" → display warnings from issues[], continue
  • status: "halt" → display halt issues, stop with guidance

If the script fails (not found, parse error, non-zero exit), fall back to the inline diagnostics below. Infrastructure failure = warn-only; never halt on fallback path itself.

Inline fallback:

bash
# Read effective identity + origin
git config --show-origin --show-scope --get-all user.name
git config --show-origin --show-scope --get-all user.email
# Check environment variable overrides
printf "GIT_AUTHOR_NAME=%s\nGIT_AUTHOR_EMAIL=%s\nGIT_COMMITTER_NAME=%s\nGIT_COMMITTER_EMAIL=%s\n" \
  "${GIT_AUTHOR_NAME:-}" "${GIT_AUTHOR_EMAIL:-}" \
  "${GIT_COMMITTER_NAME:-}" "${GIT_COMMITTER_EMAIL:-}"

Decision logic:

Condition Behavior
user.name and user.email resolve to single values Silent continue, record identity for commit plan
git config --get user.name returns nothing HALT — output git config --local user.name "..." setup guidance
git config --get user.email returns nothing HALT — output git config --local user.email "..." setup guidance
GIT_AUTHOR_* or GIT_COMMITTER_* env vars set Warn: env vars will override config; commit plan shows (env override)
--get-all returns multiple different values AskUserQuestion: list candidate profiles, user selects once
Conflict + CI=true env var HALT (fail-closed) — output fix guidance, do not silently inherit

Design principles:

  • Diagnostic, not override: Do not use git -c user.name=... to override. Respect includeIf settings.
  • Interrupt only on anomaly: Normal identity resolution produces no prompt.
  • Conflict ≠ multiple sources: includeIf producing multiple config sources that resolve to the same value = normal.

1d. Signing Diagnostics

bash
git config --show-origin --get commit.gpgsign 2>/dev/null || echo "unset"
git config --show-origin --get user.signingkey 2>/dev/null || echo "unset"
git config --show-origin --get gpg.format 2>/dev/null || echo "gpg"

Decision logic:

Condition Behavior
commit.gpgsign=true + key exists Display Signing: enabled (<gpg.format>)
commit.gpgsign=true + key missing ⚠️ Warning: signing enabled but key not configured
commit.gpgsign unset Display Signing: not configured (inherit)
--execute mode signing failure Immediate stop + fix guidance

Post-commit visibility (--execute mode):

bash
git log -1 --format='%G?' # N=unsigned, G=good, U=good-untrusted, etc.

Signing override flags (--sign / --no-sign):

Flag Effect Git flag
--sign Force signing for this batch -S on each git commit
--no-sign Disable signing for this batch --no-gpg-sign on each git commit
Both Error — mutually exclusive Halt with error message
Neither Inherit from commit.gpgsign config (default behavior)

When --sign or --no-sign is used, AskUserQuestion to confirm the override and warn about potential branch protection / CI policy conflicts.

1e. AI Guard Readiness

bash
# Detect effective hook path (handles relative paths and worktrees)
HOOK_FILE=$(git rev-parse --git-path hooks/commit-msg 2>/dev/null)
# If core.hooksPath is set, use it instead
CUSTOM_HOOKS=$(git config --get core.hooksPath 2>/dev/null)
if [ -n "$CUSTOM_HOOKS" ]; then
  # Resolve relative paths against repo root
  case "$CUSTOM_HOOKS" in
    /*) ;; # absolute — use as-is
    *)  CUSTOM_HOOKS="$(git rev-parse --show-toplevel 2>/dev/null)/${CUSTOM_HOOKS}" ;;
  esac
  HOOK_FILE="${CUSTOM_HOOKS}/commit-msg"
fi
# Check commit-msg hook
if [ -f "$HOOK_FILE" ] && [ ! -x "$HOOK_FILE" ]; then
  echo "guard:not-executable"
elif [ -x "$HOOK_FILE" ]; then
  echo "guard:installed"
else
  echo "guard:missing"
fi

Decision logic:

Condition Behavior
Hook installed + executable Display AI guard: active
Hook not installed ⚠️ Warning (non-blocking): suggest install (/install-scripts commit-msg-guard then cp .claude/scripts/commit-msg-guard.sh <hooks-path>/commit-msg && chmod +x <hooks-path>/commit-msg)
Hook exists but not executable ⚠️ Warning: suggest chmod +x <hook-path>

Important: Hook installation is NOT a blocker for --execute mode. Runtime validation (Step 5c) provides an independent safety layer.

Step 2: Pre-flight Check

Check precommit status based on change type. Structural .md files (skills/) have test coverage (e.g., skills-schema.test.js) that can catch reference errors CI would find.

Change Type Required Check Rationale
Code files (.ts/.js/.py/.go/.rs etc.) /precommit or /precommit-fast passed Code correctness + lint
Structural .md (skills/**) /precommit-fast passed Schema/ref tests cover SKILL.md structure
Other .md (README, docs/) /codex-review-doc passed (per CLAUDE.md) No structural tests; doc review sufficient
Comments / trivial whitespace Skip allowed No test coverage expected
Status Action
Required check passed in current session after last edit Continue
Not run, stale, or uncertain Halt — ask user to run the required check first

Freshness: A "passed" result is only valid if it ran after the most recent file edits in this session. Stale results from earlier in the session (before new edits) do not count.

Policy note: This pre-flight is intentionally stricter than the base auto-loop rule (@rules/auto-loop.md), which only requires /codex-review-doc for .md changes. /smart-commit is the last gate before commit — structural .md files under skills/ have test coverage (e.g., skills-schema.test.js) that can catch reference errors the doc review alone cannot detect. This extra check prevents CI failures post-push.

Fast vs full test suite warning: /precommit-fast runs a subset of tests (test:fast), while CI runs the full suite (test:ci). When changes include deletions (skills, scripts), orphaned test files may only fail in CI. If the pre-flight detects that only /precommit-fast was run (not /precommit), output: ⚠️ Only fast tests ran. If you deleted files, consider /precommit (full suite) to catch orphaned imports before commit.

Step 3: Collect Changes

bash
git status --short
git diff --stat
git diff --cached --stat

Classify changes:

Type Description
staged Already git add-ed
modified Tracked but unstaged
untracked New files (decide whether to include)
deleted Deleted files

Exclusion rules (warn user, do not include):

.env* | *.pem | *.key | *.p12 | id_rsa* | .aws/credentials
*.secret | credentials.json | .npmrc | token.txt
node_modules/ | dist/ | .cache/ | files covered by .gitignore

Partial-staged detection: If a file has both staged and unstaged changes (MM in git status), warn user and ask them to resolve first.

--scope filtering: When --scope <path> is specified, only include changes under that path. Apply after collecting all changes:

bash
git status --short -- "${SCOPE_PATH}"

Exclude changes outside the scope path. If no changes remain after filtering → report "No changes under <path>" and stop.

If no changes → report "No uncommitted changes" and stop.

Session-aware filtering (default, disable with --all):

After collecting changes and applying exclusion/scope rules above, filter by session commit scope:

  1. Read .claude_review_state.json field session_commit_scope
  2. Validate session_commit_scope.session_id matches current session
  3. If --all flag passed, or scope is unavailable/invalid → skip filtering (legacy behavior)
  4. Otherwise, classify remaining files:
Condition Result Display
Already staged (passed safety checks) Include Normal
Unstaged/untracked + in touched_files + NOT in baseline_dirty_files Include Normal
Unstaged/untracked + in touched_files + in baseline_dirty_files Include ⚠️ Warning badge
Unstaged/untracked + NOT in touched_files Exclude Show in "Excluded" section

If all unstaged files are excluded and nothing is staged → report "No session changes to commit. Use --all to include pre-existing changes." and stop.

Step 4: Group (High Cohesion)

Each group should form a semantically complete commit.

Grouping strategy (priority order):

  1. Already staged changes: Respect user intent — separate group (no git add, just git commit)
  2. Same feature/module: Group by path prefix + filename semantics
    • Same directory changes (e.g. src/service/xxx/)
    • Flat files by name prefix
    • Controller + Service + Test = complete feature
  3. Same type: Pure tests → test:, pure docs → docs:, pure config → chore:
  4. Related changes: src/xxx.ts + test/unit/xxx.test.ts in same group
  5. Remaining scattered files: Merge into misc commit or ask user

Group limit: No more than 15 files per commit.

Ticket ID: If {TICKET_PATTERN} is configured, extract ticket ID from branch name:

bash
git rev-parse --abbrev-ref HEAD

Show grouping plan and ask user to confirm. Include identity, signing, and AI guard metadata from Step 1c/1d/1e:

## Commit Plan

**Selection mode**: session-aware (default)
**Author**: Jane Doe <[email protected]> (local config)
**Signing**: enabled (GPG, key: ABCD1234)
**AI guard**: active (commit-msg hook installed)

| # | Type | Files | Summary |
|---|------|-------|---------|
| 1 | fix  | 3     | Fix circuit breaker logic |
| 2 | test | 2     | Add RPC client unit tests |
| 3 | docs | 4     | Update performance audit docs |

### Excluded — pre-existing uncommitted (not touched this session)
| File | Status | Reason |
|------|--------|--------|
| src/legacy.ts | M | Not touched in this session |
| config/dev.json | M | Not touched in this session |

⚠️ `src/config.ts` was already dirty before this session and was edited during this session. Pre-existing changes will be included.

> To include all uncommitted changes: rerun with `--all`

Adjust grouping?

Step 5: Generate Commits (Loop)

5a. Read diff

bash
git diff -- <files>          # unstaged
git diff --cached -- <files> # staged

5b. Generate commit message (following Step 1b inferred style)

  • Subject focuses on "what was done", not "which files changed"
  • If project convention includes scope → <type>(<scope>): <subject>
  • If project convention includes ticket ID → append [TICKET-ID]
  • --type override: When --type <type> is specified, use that type for all commit groups instead of inferring from changes. Takes precedence over inferred type.

AI trailer sanitization (mandatory, before outputting any commit command):

Scan the generated message for forbidden patterns and strip them silently unless --ai-co-author was explicitly passed:

Forbidden Pattern Regex (POSIX ERE, grep -Ei)
Co-Authored-By AI Co-Authored-By:.*(Claude|Anthropic|GPT|OpenAI|Copilot|noreply@anthropic)
Generated-by tag Generated (by|with).*(Claude|Claude Code|AI|GPT|Copilot)
Emoji robot tag 🤖.*(Claude|AI|GPT)

Note: \| in the table above is Markdown table escaping. Actual POSIX ERE uses unescaped |. Canonical regex source: scripts/commit-msg-guard.sh (POSIX ERE, grep -Ei)

If any pattern matches and --ai-co-author was not passed → remove the matching line(s) from the message before output/execute.

--ai-co-author narrow whitelist (enforced by runtime validation in Step 5c): When --ai-co-author is passed, only the exact line Co-Authored-By: Claude <[email protected]> is permitted. All other AI patterns (Generated by, 🤖, variant Co-Authored-By formats) remain blocked even with --ai-co-author. Note: the commit-msg hook (ALLOW_AI_COAUTHOR=1) bypasses all hook checks — the narrow whitelist is enforced solely by the runtime validate_msg() function, not by the hook.

5c. Output or execute commands

Manual mode — output copy-pasteable commands:

Already staged group (no git add needed):

markdown
### Commit 1/3: fix: Fix circuit breaker timeout logic

```bash
git commit -m "$(cat <<'EOF'
fix: Fix circuit breaker timeout logic

EOF
)"
```

Unstaged group (needs git add first):

markdown
### Commit 2/3: test: Add RPC client unit tests

```bash
git add test/unit/provider/clients/basic-json-rpc-client.test.ts \
       test/unit/utils/concurrence-as-one.test.ts
git commit -m "$(cat <<'EOF'
test: Add RPC client unit tests

EOF
)"
```

Execute mode (--execute) — run commands directly:

  1. Use AskUserQuestion to show the full commit plan (all groups) and get approval once
  2. For each approved commit group, execute git add (if needed)
  3. Runtime validation — before each git commit, validate the sanitized message via temp file + validate_msg(). See execute-mode.md for full implementation.
  4. After each commit, verify with git log --oneline -1 to confirm success
  5. If any commit fails or runtime validation fails, stop and report the error (do not continue to next group)

With --ai-co-author flag, append trailer and set ALLOW_AI_COAUTHOR=1 (required to pass commit-msg hook):

markdown
```bash
ALLOW_AI_COAUTHOR=1 git commit -m "$(cat <<'EOF'
fix: Fix circuit breaker timeout logic

Co-Authored-By: Claude <[email protected]>
EOF
)"
```

5d. Continue to next group

Manual mode: Output all groups' git commands at once, prompt user to execute in order. Execute mode: Proceed to next group automatically after successful commit.

Step 6: Verification

Execute mode:

bash
git status --short
  • Still has unhandled changes (committable files in included set) → return to Step 4
  • Only excluded files remain (sensitive files, or session-excluded pre-existing files) → stop with warning summary listing excluded files
  • All clear → output summary table

After each commit, run post-commit AI trailer detection (hard stop on leak): scan git log -1 --format='%B' for forbidden patterns. When --ai-co-author is active, strip the exact allowed line (Co-Authored-By: Claude <[email protected]>) before scanning — same logic as validate_msg(). If any remaining match → immediately stop all remaining groups + output amend guidance. See execute-mode.md § Post-commit Detection for implementation. Do NOT auto-amend — amending is a destructive git operation reserved for the developer.

Manual mode:

In manual mode, Step 6 outputs a post-execution checklist (Claude has NOT executed any commands):

## Post-Execution Checklist
After running the commands above:
1. git status --short  (verify all changes committed)
2. git log -3 --format='%H%n%B%n----'  (verify commit messages have no AI trailers)

Do NOT run git status convergence loops or git log -1 trailer detection in manual mode — the commands have not been executed yet.

AI Co-Author Attribution

Mode Condition Commit Message
Default No --ai-co-author flag No Co-Authored-By trailer
Opt-in --ai-co-author passed Append Co-Authored-By: Claude <[email protected]>

AI attribution is off by default. The developer owns the commit. Only add the trailer when explicitly requested via --ai-co-author.

Prohibited

  • No AI signatures by default: Never add Co-Authored-By, Generated by, or any AI attribution trailer unless --ai-co-author is explicitly passed
  • No guessing: If uncertain about file grouping, ask user
  • No merging unrelated changes: Better an extra commit than sacrificing cohesion
  • No omissions: Must git status verify after completion
  • No secrets: Sensitive files must be warned about, never included
  • No unauthorized execution: Without --execute flag, never directly execute git add/commit
  • No silent execution: In --execute mode, must use AskUserQuestion for approval before executing commits
  • No silent inclusion of pre-existing changes: Without --all, do not silently include unstaged files that were not touched in this session

Bundled References

File Purpose When
execute-mode.md Runtime validation (validate_msg()) + post-commit AI trailer detection --execute mode

Note: Bash code in references/execute-mode.md is a behavioral specification. Claude translates it to allowed tool calls (Bash(git:*) for git commit -F, etc.) — it is not a standalone script requiring additional shell permissions.

Examples

Input: Help me commit these changes
Action: Detect manual mode → pre-flight check → analyze 20 changes → group into 4 → output 4 sets of git commands
Input: /smart-commit
Action: Detect mode → pre-flight check → analyze 5 changes → all same feature → generate 1 commit
Input: /smart-commit --execute
Action: Override to execute mode → pre-flight check → analyze changes → group → AskUserQuestion approval → git add + git commit each group → git status verify
Input: /smart-commit --execute --ai-co-author
Action: Execute mode + AI co-author → group → approve → git add + git commit (with Co-Authored-By trailer) → verify

Expand your agent's capabilities with these related and highly-rated skills.

sd0xdev/sd0x-dev-flow

runbook

Generate and update feature release runbooks from existing docs and codebase. Use when: creating operational runbook, release handbook, deployment checklist, pre-release preparation. Not for: incident response (v2), code review (use codex-code-review), architecture design (use architecture).

139 18
Explore
sd0xdev/sd0x-dev-flow

ask

Context-aware Q&A with auto context gathering. Use when: user has a quick question about codebase, git history, rules, docs, or skills during development. Not for: code changes (use feature-dev), code review (use codex-review-fast), deep research (use deep-research), full code trace (use code-explore). Output: structured answer with source attribution.

139 18
Explore
sd0xdev/sd0x-dev-flow

project-brief

Convert a technical spec into a PM/CTO-readable executive summary. Simplify technical details, focus on business value.

139 18
Explore
sd0xdev/sd0x-dev-flow

codex-test-gen

Generate unit tests for specified functions using Codex MCP

139 18
Explore
sd0xdev/sd0x-dev-flow

bug-fix

Bug fix workflow. Use when: fixing bugs, resolving issues, regression fixes. Not for: new features (use feature-dev), understanding code (use code-explore). Output: fix + regression test + review gate.

139 18
Explore
sd0xdev/sd0x-dev-flow

skill-health-check

Validate skill quality against routing, progressive loading, and verification criteria. Use when: auditing skills, checking skill health, reviewing skill design. Not for: code review (use codex-code-review) or doc review (use doc-review). Output: health report with per-skill ratings + Gate.

139 18
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results