AgentSkillsCN

create-commit

当用户提出“提交”、“创建提交”、“执行 git commit”、“提交我的更改”、“提交暂存的更改”、“撰写规范化的提交信息”、“编写提交信息”等请求,或希望基于暂存的 Git 更改生成格式规范的常规提交时,应使用此技能。该技能可自动执行分支安全检查、智能检测提交类型、依据常规提交规范生成提交信息、在提交前钩子失败时进行恢复处理,并支持可选的 PR 创建功能。

SKILL.md
--- frontmatter
name: create-commit
description: This skill should be used when the user asks to "commit", "create a commit", "git commit", "commit my changes", "commit staged changes", "make a conventional commit", "write a commit message", or wants to create a well-formatted conventional commit from staged git changes. Handles branch safety checks, automatic commit type detection, message composition following the conventional commits spec, pre-commit hook failure recovery, and optional PR creation.
disable-model-invocation: true
allowed-tools: Bash(git *), Bash(gh *), Read, Glob

Create Commit

Create a conventional commit from staged changes with branch safety, automatic type detection, and optional PR creation.

Isolation

CRITICAL: Each invocation of this skill operates in complete isolation. Ignore all prior conversation context, previous instructions, earlier diffs, commit messages, user decisions, and any other information from the current session. Base every decision — type, scope, message, branch handling — solely on the current state of the git repository as observed by the commands executed within this invocation.

Process

  1. Verify staged changes — Run git diff --cached --name-only. If no files are staged, inform the user and stop.

  2. Load commitlint config — Search the repository root for a commitlint configuration file. Use Glob to check for these files (in priority order):

    code
    commitlint.config.{js,cjs,mjs,ts,cts,mts}
    .commitlintrc
    .commitlintrc.{json,yaml,yml,js,cjs,mjs,ts,cts,mts}
    

    Also check package.json for a commitlint field.

    If a config is found, read it and extract all applicable rules:

    • type-enum — allowed commit types (overrides the default type table)
    • scope-enum — allowed scopes (restricts scope choices)
    • header-max-length — max header length (overrides the 72-char default)
    • subject-case — required casing for the subject
    • body-max-line-length — max line length in the body
    • body-leading-blank — whether a blank line is required before the body
    • footer-leading-blank — whether a blank line is required before the footer
    • Any other rules defined in the config

    If the config uses extends (e.g., @commitlint/config-conventional), acknowledge the base ruleset and apply any rule overrides on top.

    If no config is found, apply the default constraints defined in the steps below.

  3. Gather context (run in parallel):

    • git diff --cached — full diff of staged changes
    • git branch --show-current — current branch name
    • git log --oneline -5 — recent commits for style consistency
  4. Branch guard — If on main or master, ask whether to:

    • Create a new branch (derive name as <kebab-description>, max 50 chars), then run git checkout -b <name>
    • Continue committing directly to the protected branch
  5. Determine commit type — If commitlint config defines type-enum, only use types from that list. Otherwise, use the default table:

    TypeWhen to use
    featNew functionality, new public interfaces
    fixBug fixes, corrections preserving existing interfaces
    refactorCode restructuring without behavior change
    choreTooling, config, dependencies, non-functional changes
    docsDocumentation-only changes
    styleFormatting, whitespace, no logic change
    testAdding or updating tests
    ciCI/CD pipeline changes
    perfPerformance improvements
    revertReverting a previous commit
  6. Determine scope — If commitlint config defines scope-enum, only use scopes from that list. Otherwise, use a scope when all changes fall within a single logical module, component, or directory. Omit scope when changes span multiple areas or touch root-level config.

  7. Compose the commit message following the Conventional Commits specification and all loaded commitlint rules:

    • Format: type(scope): subject or type: subject
    • Subject rules:
      • Must contain a verb and a subject — the verb describes the action, the subject addresses the area
      • Use present simple, imperative mood (add not adds/added)
      • Start lowercase (unless commitlint subject-case requires otherwise)
      • Stay under 72 characters (or the header-max-length from commitlint config — note this limit applies to the entire header including type, scope, and colon)
      • Be specific and meaningful — the reader must understand what changed without looking at the diff
      • Keep it short — if motivation or context is needed, put it in the body
      • Describe what actually changed, not the meta-task you are working on
    • Body (when needed): Explain what changed and why, note breaking changes or migration steps. Use the body to clarify motivation when the subject alone is insufficient. If commitlint enforces body-max-line-length, wrap body lines accordingly.
    • Blank lines: Always add a blank line between header and body, and between body and footer (commitlint body-leading-blank and footer-leading-blank rules enforce this by default).
    • No metadata trailers: Do not append Co-Authored-By, AI attribution, or any trailers not explicitly requested by the user. The commit message contains only the header and optional body.

    Subject quality rules

    Must have verb + subject (action + area):

    • Bad: feat: bearer login functionality (no verb)
    • Bad: feat: add (no subject)
    • Good: feat: add bearer login functionality

    Must be meaningful — reader should understand the change:

    • Bad: style: change bunch files (unclear what changed)
    • Good: style: format src folder with prettier
    • Bad: chore: fix build (unclear how)
    • Good: chore: add env var extract plugin

    Must address a specific area, not be generic:

    • Bad: fix: fix bug (says nothing)
    • Bad: fix: fix schema (still vague)
    • Good: fix: change first name type in user schema

    Keep short — use body for context:

    • Bad: feat: add another get user endpoint because first endpoint doesn't return security information for admin
    • Good:
      code
      feat: add admin get user endpoint
      
      The existing endpoint works for simple user, but now admins
      want to get additional information about the user.
      

    Describe actual changes — never the meta-task:

    • Bad sequence: chore: final trychore: trying to enablechore: fixchore: fix build
    • Good sequence: chore: add extract env pluginchore: remove default env pluginchore: enable cache layer for webpack
    • Never use words like "trying", "another try", "final fix" — each commit must stand on its own
  8. Present the message to the user for approval before committing.

  9. Commit — Execute git commit with the approved message using a heredoc:

    bash
    git commit -m "$(cat <<'EOF'
    type(scope): subject
    
    Optional body explaining what and why.
    EOF
    )"
    
  10. Handle pre-commit failures — If the commit fails due to linting or formatting hooks:

  • Analyze the error output
  • Apply targeted fixes to the reported issues
  • Stage fixes with git add (specific files only, not git add .)
  • Re-attempt the commit
  • Repeat up to 3 times, then report remaining issues to the user
  1. Offer PR creation (non-main branches only) — After a successful commit, push the branch and ask whether to create a PR. Run the exact command as shown — no additional flags:
    • Create PRgh pr create --fill
    • Create draft PRgh pr create --fill --draft
    • Skip → do nothing

Commit Message Examples

code
feat(auth): add jwt token validation
fix(parser): handle empty input gracefully
refactor: consolidate duplicate helper functions
chore: update terraform provider versions
docs(api): add rate limiting section
test(billing): add edge case coverage for zero amounts
ci: add staging deployment workflow
perf(db): add index on users.email column
feat!: redesign authentication flow

BREAKING CHANGE: OAuth tokens from v1 are no longer valid.