一键导入
commits-create
Analyze staged changes and create conventional commits with intelligent grouping. Use when creating commits, or when invoked from other skills.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Analyze staged changes and create conventional commits with intelligent grouping. Use when creating commits, or when invoked from other skills.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Perform deep analysis of the codebase, recent changes, and the requested task. Create a validated, expert-reviewed implementation plan
Review a pull request and provide constructive feedback with structured verdict. Used by awinogradov/code-review-action
Plan, implement, commit, create PR, and monitor until approved
Create a GitHub issue with a structured body (Context, What, Why, Scope, Solution) and curated labels via the gh CLI. Use when filing new issues, or when invoked from other skills.
Create a Linear issue with a structured body (Context, What, Why, Scope, Solution) and wizard-selected status, label, and assignee via the Linear MCP. Use when filing a Linear ticket on a linear-tracked project.
Answer a user comment on a PR review and update review state if needed
| name | commits:create |
| description | Analyze staged changes and create conventional commits with intelligent grouping. Use when creating commits, or when invoked from other skills. |
| argument-hint | [optional commit context] [--autopilot] |
| allowed-tools | ["Bash(git *)","Bash(gh *)","Read","AskUserQuestion","Skill(autopilot:preflight-check)","Skill(autopilot:pr-update)"] |
Analyze changes and create git commits with conventional commit messages. Supports intelligent grouping of changes into multiple atomic commits for better review and changelog.
/autopilot:commits-restructure after soft resetArguments: $ARGUMENTS
Expected form:
"<context>" — free-form context that helps generate a better commit message (e.g., "add auth feature")--autopilot — non-interactive mode used by /autopilot:run. Skips commit-strategy, commit-message, and PR-update prompts and commits directly using the auto-generated messages.Arguments are optional. When $ARGUMENTS is empty:
git diff --staged) plus recent conversation history (skill analyses, user instructions) to generate the message. Do NOT prompt.--autopilot — $ARGUMENTS only. Never inferred. Default: false (interactive mode). Strip from $ARGUMENTS before parsing the remainder as commit context.CONTRIBUTING.md directly from the repository root.gh pr view --json number,url 2>/dev/null at Phase 5. No user prompt needed.Autopilot bypass: When autopilotMode is true (from Phase 1), this entire contract is moot — every AskUserQuestion call in Phases 3, 4, and 5 is skipped. Generate the commit message(s), commit directly, and exit without prompting.
Every AskUserQuestion call that presents content for review (commit messages) MUST follow these exact rules. Simple choice dialogs (Phase 3 commit strategy, Phase 5 PR update offer) are exempt from the preview requirement.
question is FIXED TEXT — use the EXACT string specified in each phase. NEVER add commit messages, file names, diffs, metadata, or any other content to the question field.header is FIXED TEXT — use the EXACT string specified in each phase.preview is MANDATORY — every option MUST include a preview field. The commit message goes ONLY in preview. NEVER put content in question, label, or description.label values are EXACT — use the exact text specified (e.g., "Commit", "Edit", "Cancel"). No abbreviations, no paraphrasing, no creative alternatives.description values are EXACT — use the exact text specified. No rewording.preview on all options — the user chooses an action, not content. All options show identical preview text.preview — templates below use <commit message> as a placeholder. Before invoking AskUserQuestion, replace <commit message> with the full commit message string (title + body, literal \n escape sequences for line breaks). NEVER pass the literal string <commit message>, nor the shorthand "...", "<same>", or any placeholder. Every option's preview must contain the fully resolved commit message string.AskUserQuestion({
question: "feat(auth): add jwt refresh endpoint\n\n- Added /auth/refresh endpoint\n- Added 7-day expiry\n\nProceed?",
header: "Commit",
options: [
{ label: "Yes", description: "Commit" },
{ label: "Edit", description: "Change message" }
]
})
AskUserQuestion({
question: "Review the commit message and choose an action.",
header: "Commit",
options: [
{ label: "feat(auth): add jwt refresh endpoint", description: "Proceed with this commit" },
{ label: "Edit message", description: "Modify" }
]
})
AskUserQuestion({
question: "Review the commit message and choose an action.",
header: "Commit",
options: [
{ label: "Commit", description: "feat(auth): add jwt refresh endpoint - Added /auth/refresh" },
{ label: "Edit", description: "Modify the commit message" }
]
})
AskUserQuestion({
question: "Review the commit message and choose an action.",
header: "Commit",
options: [
{ label: "Commit", description: "Proceed with this commit message", preview: "feat(auth): add jwt refresh endpoint\n\n- Added /auth/refresh endpoint\n- Added 7-day expiry" },
{ label: "Edit", description: "Modify the commit message", preview: "feat(auth): add jwt refresh endpoint\n\n- Added /auth/refresh endpoint\n- Added 7-day expiry" },
{ label: "Cancel", description: "Abort commit creation", preview: "feat(auth): add jwt refresh endpoint\n\n- Added /auth/refresh endpoint\n- Added 7-day expiry" }
]
})
Invoke Skill(autopilot:preflight-check) with mode: commits from this conversation context. The skill verifies the current branch is appropriate for committing and warns if you are on main. If it outputs a "cancelled" message, stop immediately — do not proceed to Phase 1.
$ARGUMENTS: if it contains --autopilot, strip the flag and set autopilotMode = true. Otherwise autopilotMode = false. The remainder (if any) is the commit context.git status to see current stategit addInvoke the analyze-staged-changes sub-agent to categorize staged files, assess changeset size, and recommend a commit strategy:
Use the Agent tool with:
- `subagent_type`: "autopilot:analyze-staged-changes"
- `prompt`: "Analyze staged changes in the current repository."
- `description`: "Analyze staged changes"
After the agent completes, store the structured results (categories, file lists, strategy recommendation, recent commit style).
Autopilot bypass: If autopilotMode is true, do NOT call AskUserQuestion. Use single commit flow when singleCommitRecommended: true; otherwise use grouped commit flow. Proceed to Phase 4.
Use the agent's analysis to decide the commit flow:
If agent recommends singleCommitRecommended: true: single commit flow (Phase 4)
If agent recommends singleCommitRecommended: false: the changeset is large enough to consider splitting. Evaluate whether the changes represent genuinely distinct areas. If a single coherent commit message can describe all changes, use single commit flow. Otherwise, ask the user:
Formatting Note: Do not use markdown formatting (bold, italic, headers) in the question parameter — it renders as raw text. Use plain text with line breaks and simple labels instead.
Tool parameters:
question: "How would you like to commit these changes?"header: "Commit strategy"options: [
{ label: "Single commit (Recommended)", description: "One commit with a comprehensive message" },
{ label: "Separate commits", description: "Create N atomic commits by category" }
]multiSelect: falseIf user chooses "Separate commits": Continue to Phase 4 with grouped flow
If user chooses "Single commit": Continue to Phase 4 with single commit flow
git diff --staged to see what will be committedsubject-case, and the other checkable commitlint rules) plus commitlint when installed. On any violation, regenerate and re-validate (≤3 attempts); do not present or commit a message that still fails.Autopilot bypass: If autopilotMode is true, skip steps 6–9 below. Run git commit -m "<message>" directly with the generated message and continue to Phase 5.
Present using AskUserQuestion tool with preview:
Preview content rules:
preview MUST contain ONLY the commit message (title + body). DO NOT include file lists, diff content, or any other metadata in the previewTool call structure: See AskUserQuestion Contract above. All rules are mandatory.
Tool parameters:
question: "Review the commit message and choose an action."header: "Commit"options: [
{ label: "Commit", description: "Proceed with this commit message", preview: "" },
{ label: "Edit", description: "Modify the commit message", preview: "" },
{ label: "Cancel", description: "Abort commit creation", preview: "" }
]multiSelect: falseIf "Edit" selected, ask for changes and regenerate, then re-run Commit Message Validation on the edited message and re-present — a hand-typed subject is validated too, never committed unchecked
If "Cancel" selected, abort with "Commit cancelled."
Only proceed with git commit after "Commit" selected
When executing git commit, run git commit -m "<message>"
Every commit in a PR must leave the branch in a stable state — CI passes, lint rules are satisfied, tests pass for the code present at that point. Undocumented or untested code is acceptable; broken CI/lint is not.
Default order: ci → chore/build → feat/fix/refactor → test → docs
ci first — CI/CD pipeline changes establish the ruleschore/build — configuration and dependenciesfeat/fix/refactor — main implementation satisfies those rulestest — tests verify implementationdocs last — informational, never breaks stabilityThis is the default for the common case. Reason about the specific changes and deviate when needed. For example, if implementation changes are prerequisites for CI changes to pass, use feat → ci → ... instead. The goal is stability at every checkout, not rigid adherence to a fixed sequence.
Process categories in this order: ci → chore/build → feat/fix/refactor → test → docs
For each category that has files:
git reset HEAD (unstage all)git add <category files>git diff --staged — read the diff and identify what specifically changed (files, functions, values, behaviors)After analyzing all categories, git reset HEAD to unstage everything.
Autopilot bypass: If autopilotMode is true, skip this step entirely. Skip to Step 3 and execute each commit directly with its generated message.
Use a single AskUserQuestion with multiple questions (one per commit), each with preview.
Tool call structure: See AskUserQuestion Contract above. All rules are mandatory.
Tool parameters:
questions: [
{
question: "Commit 1/N: \nReview the commit message and choose an action.",
header: "Commit 1/N",
options: [
{ label: "Commit", description: "Proceed with this commit message", preview: "" },
{ label: "Edit", description: "Modify the commit message", preview: "" },
{ label: "Cancel", description: "Abort all commits", preview: "" }
],
multiSelect: false
},
{
question: "Commit 2/N: \nReview the commit message and choose an action.",
header: "Commit 2/N",
options: [...same structure with preview...],
multiSelect: false
},
...one question per category
]All options in each question use the same preview content (commit message only for that category). DO NOT include file lists in the preview.
If "Cancel" is selected for any commit, abort the entire grouped commit operation with "Commits cancelled." — do not execute any of the commits.
If there are 5 categories (exceeds the 4-question limit): present the first 4 in one dialog, then present the 5th in a follow-up single-question dialog.
For each commit where "Edit" was selected: ask a follow-up single AskUserQuestion for that commit's new message (question with the original message, header "Edit N/M", same options), then re-run Commit Message Validation on the edited message before re-presenting. Repeat until "Commit" is selected. If "Cancel" is selected, abort all commits with "Commits cancelled." A hand-typed message must pass validation before it reaches the commit loop in step 2.
Execute all commits sequentially in category order:
git add <category files>git commit -m "<message>"After all commits:
✓ All N commits created successfully.
<type>[optional scope]: <description>
- <what specifically changed>
- <what specifically changed>
The body is required for feat, fix, and refactor commits. It may be omitted for docs, test, style, chore, ci, build, perf, and revert commits where the title alone is fully descriptive.
feat - New featurefix - Bug fixdocs - Documentation changesstyle - Code style (formatting, semicolons)refactor - Code restructure (no behavior change)perf - Performance improvementstest - Testsbuild - Build system or dependenciesci - CI/CD configurationchore - Maintenance (tooling, deps)revert - Reverting a previous committype(scope): ) MUST be all lowercase — camelCase identifiers are not allowed (subject-case) — MUST NOT exceed 50 characters, and the whole header line (type(scope): subject) MUST NOT exceed 100 characters. Enforced by commitlint (subject-case / subject-max-length / header-max-length) and CI, and by the skill itself via Commit Message Validation before every commitfeat, fix, and refactor. Body bullet points list concrete modificationsCo-authored-by trailers (Claude, ChatGPT, Copilot, Codex). Disable co-authorship in your AI tool settings.Both the title and body MUST describe WHAT changed, NEVER WHY it changed. Context from calling skills (e.g., "fixes for PR review comments") must NOT influence the title — the title must describe what changed in the code.
Title: Name the specific technical change. Do NOT state the motivation, goal, or intent behind the change.
| WHY-focused (WRONG) | WHAT-focused (CORRECT) |
|---|---|
fix: close coverage gaps | fix(auth): add null-check and expiry validation |
fix: address review feedback | fix(parser): replace bcrypt with argon2 for hashing |
refactor: ensure compliance with rules | refactor(lint): change nesting depth threshold to 2 |
feat: improve error handling | feat(api): add retry with exponential backoff |
fix: cover edge cases | fix(validator): handle null and empty-string inputs |
refactor: address code quality concerns | refactor(db): extract connection pool into module |
Body: List the concrete modifications. Do NOT explain reasoning or reference rules.
| WHY-focused body bullet (WRONG) | WHAT-focused body bullet (CORRECT) |
|---|---|
- CLAUDE.md enforces max-depth of 2 | - Change nesting depth threshold from >5 to >2 |
- Tests were missing for auth edge cases | - Add tests for expired token and null user inputs |
- Review requested switching to argon2 | - Replace bcrypt with argon2 in hashPassword() |
- Needed to close coverage gap in validation | - Add boundary checks for negative and zero values |
WHY signal words to avoid in titles: "close", "address", "ensure", "improve", "cover", "resolve", "satisfy", "comply", "meet" (when followed by abstract goals rather than technical specifics — e.g., "handle edge cases" is WHY, "handle null input in parseToken" is WHAT)
The title must "contain the answer" — a reader should understand what changed without opening the diff.
| Bad (vague) | Good (specific) | Why |
|---|---|---|
fix: review updates | fix(auth): replace bcrypt with argon2 for hashing | Names the actual replacement |
fix: resolve issue | fix(api): return 404 instead of 500 for missing users | States the concrete behavior change |
feat: add new feature | feat(billing): add monthly invoice PDF export | Names the specific feature |
refactor: clean up code | refactor(db): extract query builder from repository | Names what was extracted |
chore: update dependencies | chore(deps): upgrade zod from 3.21 to 3.23 | Names the package and versions |
fix: close coverage gaps | fix(auth): add null-check and expiry validation | Names what was actually added |
refactor: address feedback | refactor(parser): extract tokenizer into separate file | Names the structural change |
Vague signal words to avoid in titles: "update", "fix stuff", "changes", "improvements", "tweaks", "adjustments", "various", "some", "misc", "review updates", "address feedback", "resolve issue", "close gaps", "cover edge cases", "ensure compliance", "improve handling", "address concerns", "satisfy requirements"
Run this on every fully-composed candidate message (title + optional body) BEFORE git commit — in both the Single and Grouped flows and in autopilot mode. It is the gate that guarantees a valid commit even when the husky commit-msg hook is absent (a fresh worktree that has not run bun install has no active hook, so nothing else catches a bad message). It mirrors the rules in commitlint.config.mjs — that file is the source of truth; keep this list in sync with it. Run the shell snippets under LC_ALL=C.UTF-8 so length and case folding are stable.
Extract type, subject (the text after type(scope): ), and body from the candidate message.
Inline floor (ALWAYS runs — no dependencies; the real gate in fresh worktrees). Each check maps to a commitlint rule; the first miss is a violation:
subject-max-length / header-max-length — subject ≤ 50 (printf '%s' "<subject>" | wc -m), full header ≤ 100 (printf '%s' "<title>" | wc -m).subject-case (lower-case) — the subject must equal its lowercased form: printf '%s' "<subject>" | tr '[:upper:]' '[:lower:]' must be byte-identical to <subject>. Any difference means an uppercase letter is present (e.g. a camelCase identifier like localeForEmail). This is an ASCII approximation; when commitlint runs below it is authoritative for non-ASCII.subject-full-stop — the subject must not end with ..no-issue-id-in-subject — the subject must not match [A-Za-z]+-[0-9]+.body-required-for-types — if type is feat, fix, or refactor, body must be non-empty.no-ai-coauthored-by — the raw message must not contain a Co-authored-by: trailer naming Claude, ChatGPT, Copilot, Codex, Devin, or Cursor.type-enum / type-case — type must be one of the lowercase types listed under Types.Full commitlint (best-effort — only when installed). If the binary is present ([ -x node_modules/.bin/commitlint ]), also run the same command the husky hook uses:
printf '%s\n' "<full message>" | bunx --no -- commitlint
Treat any reported problem as a violation. Gating on the binary's existence avoids an accidental network install in a bare worktree. If it is absent, skip this step silently — the inline floor already ran and is the gate.
On any violation — regenerate the message to fix the specific rule, then re-run the whole validation. Do NOT string-lowercase a subject to satisfy subject-case (that mangles identifiers, e.g. localeForEmail → localeforemail); instead rephrase the subject to avoid the mixed-case token (hyphenate or use plain words), or name the exact identifier in the backticked body — then re-confirm the subject still describes the change. Shorten to fix length. Retry up to 3 times.
Success = the whole inline floor passes (plus commitlint when it ran), not just one rule. NEVER git commit a message that still fails. After 3 failed attempts:
Autopilot bypass: If autopilotMode is true, skip this entire phase — the calling skill (/autopilot:run) creates or updates the PR itself in its next step.
After all commits are created successfully:
Check if a PR exists for the current branch: gh pr view --json number,url 2>/dev/null
If the command fails (no PR), skip silently — do not show any message
If a PR exists, ask using AskUserQuestion tool:
Formatting Note: Do not use markdown formatting (bold, italic, headers) in the question parameter — it renders as raw text. Use plain text with line breaks and simple labels instead.
Tool parameters:
question: "A pull request exists for this branch: #. Would you like to update it to reflect the new commits?"
header: "Update PR"
options: [
{ label: "Update PR", description: "Refresh PR title and description from all commits" },
{ label: "Skip", description: "Keep the PR as-is" }
]
multiSelect: false
If "Update PR" selected: invoke Skill(autopilot:pr-update)
If "Skip" selected: finish normally
feat(auth): add jwt token refresh endpoint
- Added /auth/refresh endpoint that issues new access token from refresh token
- Added 7-day expiry validation for refresh tokens
- Returns 401 with "refresh_expired" code when token is past expiry
fix(api): return 404 instead of 500 for missing user lookup
- Changed UserService.findById to return null instead of throwing
- Added explicit 404 response in GET /users/:id handler
docs: add environment variables reference to readme
Analyzing staged changes...
Detected 3 categories:
- impl: 3 files (auth.ts, auth.types.ts, index.ts)
- test: 1 file (auth.test.ts)
- docs: 2 files (docs/auth.md, docs/api-reference.md)
How would you like to commit these changes?
User selects "Separate commits" via AskUserQuestion tool.
All commits are analyzed upfront, then presented in a single dialog with previews:
AskUserQuestion with:
questions: [
{
question: "Commit 1/3: impl\nReview the commit message and choose an action.",
header: "Commit 1/3",
options: [
{ label: "Commit", description: "Proceed with this commit message", preview: "feat(auth): implement jwt validation\n\n- Added token validation logic\n- Added refresh token support" },
{ label: "Edit", description: "Modify the commit message", preview: "feat(auth): implement jwt validation\n\n- Added token validation logic\n- Added refresh token support" },
{ label: "Cancel", description: "Abort all commits", preview: "feat(auth): implement jwt validation\n\n- Added token validation logic\n- Added refresh token support" }
],
multiSelect: false
},
{
question: "Commit 2/3: test\nReview the commit message and choose an action.",
header: "Commit 2/3",
options: [
{ label: "Commit", description: "Proceed with this commit message", preview: "test(auth): add jwt validation tests\n\n- Added token expiry edge case tests\n- Added refresh flow integration test" },
{ label: "Edit", description: "Modify the commit message", preview: "test(auth): add jwt validation tests\n\n- Added token expiry edge case tests\n- Added refresh flow integration test" },
{ label: "Cancel", description: "Abort all commits", preview: "test(auth): add jwt validation tests\n\n- Added token expiry edge case tests\n- Added refresh flow integration test" }
],
multiSelect: false
},
{
question: "Commit 3/3: docs\nReview the commit message and choose an action.",
header: "Commit 3/3",
options: [
{ label: "Commit", description: "Proceed with this commit message", preview: "docs: update authentication documentation" },
{ label: "Edit", description: "Modify the commit message", preview: "docs: update authentication documentation" },
{ label: "Cancel", description: "Abort all commits", preview: "docs: update authentication documentation" }
],
multiSelect: false
}
]User selects "Commit" for all three.
✓ Created commit: feat(auth): implement jwt validation
✓ Created commit: test(auth): add jwt validation tests
✓ Created commit: docs: update authentication documentation
All 3 commits created successfully.
If user selects "Edit" for commit 2/3, a follow-up dialog appears only for that commit:
AskUserQuestion with:
question: "Review the updated commit message and choose an action."header: "Edit 2/3"options: [
{ label: "Commit", description: "Proceed with this commit message", preview: "test(auth): add jwt validation tests\n\n- Added token expiry edge case tests\n- Added refresh flow integration test" },
{ label: "Edit", description: "Modify the commit message", preview: "test(auth): add jwt validation tests\n\n- Added token expiry edge case tests\n- Added refresh flow integration test" },
{ label: "Cancel", description: "Abort all commits", preview: "test(auth): add jwt validation tests\n\n- Added token expiry edge case tests\n- Added refresh flow integration test" }
]Analyzing staged changes...
All changes are in 1 category (impl).
AskUserQuestion with:
question: "Review the commit message and choose an action."header: "Commit"options: [
{ label: "Commit", description: "Proceed with this commit message", preview: "feat(auth): implement jwt validation\n\n- Added token validation logic\n- Added refresh token support" },
{ label: "Edit", description: "Modify the commit message", preview: "feat(auth): implement jwt validation\n\n- Added token validation logic\n- Added refresh token support" },
{ label: "Cancel", description: "Abort commit creation", preview: "feat(auth): implement jwt validation\n\n- Added token validation logic\n- Added refresh token support" }
]User selects "Commit".
✓ Created commit: feat(auth): implement jwt validation
After committing on a branch with an existing PR:
✓ Created commit: feat(auth): add password reset flow
AskUserQuestion with:
question: "A pull request exists for this branch: #15. Would you like to update it to reflect the new commits?"header: "Update PR"options: [
{ label: "Update PR", description: "Refresh PR title and description from all commits" },
{ label: "Skip", description: "Keep the PR as-is" }
]User selects "Update PR". Invokes Skill(autopilot:pr-update).
✓ Updated PR #15: https://github.com/org/repo/pull/15
These rules govern references — when you point the reader at a real file, standard, section, commit, or issue. (A token named only as an example, with no real target, is a code specimen in backticks, like any code identifier.) Every reference must resolve: render it as a real link whose target exists, and prefer the most stable link form so it does not rot. Render the same kind of reference the same way everywhere:
buildReviewComments, reviewOutput.ts. A backticked token names a thing as an example; it is not a reference and carries no link.[release field spec](<repo-blob-url>/docs/06-release-field.md). Use a repo-relative path in repository files and the absolute <repo-blob-url> form in generated output posted outside the repo (PR/issue bodies, review comments, release notes), where relative paths do not resolve. Any prose mention of a file or path that exists in the repo is such a reference — link it so it resolves on the default branch at writing time; a path that does not exist yet (a file the text proposes to create) or one shown inside a command or fenced block is a code specimen, not a reference.[RFC-0001](<repo-blob-url>/rfc/0001-reference-formatting.md); an Accepted RFC is immutable except through an explicit version bump, so the link never rots.[title](url) to the canonical source, taking the title from the source (or the site name). Use only a URL present in your input or context — never produce one from memory; a source with no known URL stays plain prose. When several sources back one document, they may be gathered into a short references list.#anchor, e.g. [Phase 6](#phase-6-reply-to-review-threads). Another document: path#anchor — a repo-relative path in repository files, the absolute <repo-blob-url>/path#anchor form in generated output. A GitHub anchor is the heading lower-cased, spaces turned to hyphens, punctuation dropped.[0328a61](<repo-commit-url>/0328a61); a commit is immutable. If you cannot build the URL, leave the bare SHA un-backticked.ENG-123) is dead text when bare: in prose, ALWAYS render it as a markdown link, e.g. [ENG-123](https://linear.app/<workspace>/issue/ENG-123) — a slug-less issue URL resolves. On a magic-word line (Closes/Fixes/Related to in a PR body's **Issues:** section) use plain forms only: bare #N for GitHub, the plain issue URL for other trackers — never a markdown-bracket link, which breaks the close-parsers.Backticks suppress GitHub autolinking: a commit SHA or issue/PR number inside a code span renders as dead text — that is why a backticked SHA was un-clickable in a prior review. Never wrap a SHA or issue/PR number in backticks; link it, or leave it bare so GitHub auto-links it.
Write the most helpful, readable output you can: plain, direct prose; every reference resolvable; explain the "why", not the obvious "what".