Compatibility: IfAskUserQuestionis unavailable, present options as a numbered list and wait for the user's reply. IfTaskis unavailable, run parallel steps sequentially. Thecontext: forkandagent:frontmatter fields are Claude Code-specific — on OpenCode and VS Code Copilot they are ignored and the skill runs inline using the current model.
Create a git commit following conventional commit standards with a professional, concise message.
Rules
Choosing the right type
- Does it add new functionality users can use? →
feat - Does it fix broken behavior? →
fix - Does it change existing behavior (breaking)? →
feat!orfix! - Does it only improve code structure? →
refactor - Does it only update documentation? →
docs - Does it only affect tests? →
test - Does it only affect build/CI? →
chore
Bump behavior is determined by your project's release config (.releaserc.*,commitizen.config.*,[tool.commitizen]). Do not predict version bumps — check those files if needed.
Never commit secrets
- Secrets or credentials (.env files, API keys, passwords)
- Warn user if such files are staged
Formatting
- Always use HEREDOC format for commit messages to ensure proper formatting.
- First line max 72 characters
- Use imperative mood: "add feature" not "added feature" or "adds feature"
- No period at end of first line
- Be professional and concise
- Do NOT include self-attribution (no "Generated with Claude Code", no "Co-Authored-By: Claude")
- Body: use bullet points, not prose paragraphs. Each bullet is one change or reason. Keep bullets terse — one line each, under 72 chars.
- Body is optional — only include if the changes aren't obvious from the subject line
- Make body as short as possible, as few bullets as possible
- Use
type(scope)format when changes touch a distinct subsystem — especially with--atomiccommits. Scope groups entries in the changelog under that feature/fix category (e.g.feat(opencode),fix(vscode)).
Scoped vs. unscoped
- Use
feat(scope)/fix(scope)when the change is clearly bounded to one area: a plugin, tool, subsystem, or named feature - Use plain
feat:/fix:for cross-cutting changes with no single scope - Scope should be short, lowercase, no spaces:
opencod,vscode,spec,help,e2e,docs,install
Flags
--yesor-y: Skip commit message confirmation (auto-approve message)--no-push: Commit only — do not push or monitor CI--autofix: After push, if CI fails, automatically attempt to fix failures and re-push--atomic: Detect logical change groups and create one commit per group--single(default): All staged changes in one commit
Workflow
Step 0: Parse Flags
YES=false; NO_PUSH=false; AUTOFIX=false; ATOMIC=false
[[ "$*" =~ --yes|-y ]] && YES=true
[[ "$*" =~ --no-push ]] && NO_PUSH=true
[[ "$*" =~ --autofix ]] && AUTOFIX=true
[[ "$*" =~ --atomic ]] && ATOMIC=trueStep 1: Check Git Status (Fast Path)
Use conversation context first - the changes are usually already in context from the work session.
Only run git commands if you need to verify:
git status
git diff --statSkip git log - you should already know the commit message style from:
- Previous commits in this session
- Project's CLAUDE.md conventions
- Standard conventional commit format
Skip reading plan.md - if you just implemented a plan, it's already in context.
Only run additional commands if you're truly uncertain about what changed.
Step 1.5: Format and Lint
Run formatters and linters before staging so any auto-fixes are included in the commit.
Formatters (auto-fix, run unconditionally if available):
npx @codevoyant/agent-kit task-runner run format 2>/dev/null || trueIf formatter ran and modified files: report ✓ Formatter applied — changes will be included in commit.
Linters (report errors, block commit if they fail):
npx @codevoyant/agent-kit task-runner run lint 2>/dev/null || \
npx @codevoyant/agent-kit task-runner run check 2>/dev/null || trueIf linting fails: report the errors and stop — do not proceed to staging until fixed:
✗ Linting failed — fix the errors above before committing.Skip silently if no formatter or linter is configured.
Step 2: Review with User
If ATOMIC is true:
Analyze staged file paths and detect logical groups (by component, package, or directory). Draft a commit message for each group. Output all proposed commits:
Proposed commits:
1. feat(auth): add JWT token validation
2. docs: update API reference
3. test(auth): add token expiry testsThen ask for confirmation using the AskUserQuestion tool:
questions:
- question: 'Do these commits look good?'
header: 'Review Commits'
multiSelect: false
options:
- label: 'Looks good — commit all'
description: '{N} commits'
- label: 'Cancel'
description: "Don't commit"- If "Looks good — commit all": proceed to Step 3.
- If "Cancel": exit without committing.
- If Other (user edits): apply their changes and proceed to Step 3.
If SINGLE (default):
Output the full proposed commit message:
Proposed commit message:
{full commit message, including body if present}Then ask for confirmation using the AskUserQuestion tool:
questions:
- question: 'Does this commit message look good?'
header: 'Review Commit'
multiSelect: false
options:
- label: 'Looks good — commit'
description: '{first line of proposed message}'
- label: 'Cancel'
description: "Don't commit"- If "Looks good — commit": proceed to Step 3.
- If "Cancel": exit without committing.
- If Other (user typed a custom message): use it as-is and proceed to Step 3.
If AUTO_APPROVE is true: skip this prompt entirely and proceed directly to Step 3. Report: ✓ Auto-approved with --yes flag.
Step 3: Stage and Commit
If ATOMIC is true: create one commit per group in order:
git add <files-in-group> && git commit -m "$(cat <<'EOF'
<type>(<scope>): <description for this group>
EOF
)"Default (SINGLE):
git add -A && git commit -m "$(cat <<'EOF'
<type>: <description>
[optional body]
EOF
)"Step 5: Push and Verify CI
If NO_PUSH is true: skip this step entirely and report ✓ Committed (push skipped).
Otherwise — always push, then launch CI monitoring in background:
- Push:
git push origin <branch> - After push succeeds, launch CI monitoring as a background Task — do NOT wait for it:
Agent:
subagent_type: general-purpose
run_in_background: true
description: "CI monitoring"
prompt: "Run /dev:ci [--autofix if AUTOFIX=true]. Monitor CI and report results when done."- Report immediately:
✓ Committed and pushed. CI monitoring running in background — you'll be notified when checks complete.
Skip CI monitoring if:
- Repo has no CI workflows configured
- Neither
ghnorglabCLI is installed (inform but don't block)