From engineering
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.
How this skill is triggered — by the user, by Claude, or both
Slash command
/engineering:create-commitThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Create a conventional commit from staged changes with branch safety, automatic type detection, and optional PR creation.
Create a conventional commit from staged changes with branch safety, automatic type detection, and optional PR creation.
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.
Verify staged changes — Run git diff --cached --name-only. If no files are staged, inform the user and stop.
Load commitlint config — Search the repository root for a commitlint configuration file. Use Glob to check for these files (in priority order):
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 subjectbody-max-line-length — max line length in the bodybody-leading-blank — whether a blank line is required before the bodyfooter-leading-blank — whether a blank line is required before the footerIf 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.
Gather context (run in parallel):
git diff --cached — full diff of staged changesgit branch --show-current — current branch namegit log --oneline -5 — recent commits for style consistencyBranch guard — If on main or master, ask whether to:
<kebab-description>, max 50 chars), then run git checkout -b <name>Determine commit type — If commitlint config defines type-enum, only use types from that list. Otherwise, use the default table:
| Type | When to use |
|---|---|
feat | New functionality, new public interfaces |
fix | Bug fixes, corrections preserving existing interfaces |
refactor | Code restructuring without behavior change |
chore | Tooling, config, dependencies, non-functional changes |
docs | Documentation-only changes |
style | Formatting, whitespace, no logic change |
test | Adding or updating tests |
ci | CI/CD pipeline changes |
perf | Performance improvements |
revert | Reverting a previous commit |
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.
Compose the commit message following the Conventional Commits specification and all loaded commitlint rules:
type(scope): subject or type: subjectadd not adds/added)subject-case requires otherwise)header-max-length from commitlint config — note this limit applies to the entire header including type, scope, and colon)body-max-line-length, wrap body lines accordingly.body-leading-blank and footer-leading-blank rules enforce this by default).Co-Authored-By, AI attribution, or any trailers not explicitly requested by the user. The commit message contains only the header and optional body.Must have verb + subject (action + area):
feat: bearer login functionality (no verb)feat: add (no subject)feat: add bearer login functionalityMust be meaningful — reader should understand the change:
style: change bunch files (unclear what changed)style: format src folder with prettierchore: fix build (unclear how)chore: add env var extract pluginMust address a specific area, not be generic:
fix: fix bug (says nothing)fix: fix schema (still vague)fix: change first name type in user schemaKeep short — use body for context:
Bad: feat: add another get user endpoint because first endpoint doesn't return security information for admin
Good:
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:
chore: final try → chore: trying to enable → chore: fix → chore: fix buildchore: add extract env plugin → chore: remove default env plugin → chore: enable cache layer for webpackCommit — Execute git commit immediately with the composed message. Do not present the message for approval first — commit directly:
git commit -m "type(scope): subject
Optional body explaining what and why."
The message string must contain no indentation, leading spaces, or extra formatting — only the raw text with newlines between header, blank line, and body lines.
If the user rejects the tool call with feedback, incorporate their feedback into a revised message and execute git commit again. Repeat until the user approves.
Handle pre-commit failures — If the commit fails due to linting or formatting hooks:
git add (specific files only, not git add .)Create PR (non-main branches only) — After a successful commit, push the branch and create a pull request. Use only one of these two commands based on the user's intention (draft vs. ready). Run the exact command as shown — no additional flags, no --title, no --body:
gh pr create --fillgh pr create --fill --draftIf the user did not specify draft or ready, ask which one they prefer.
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.
npx claudepluginhub seedium/skills --plugin engineeringDrafts Conventional Commits messages for staged git changes. Proposes a type-scoped subject line, waits for user approval, then commits.
Stages files safely avoiding sensitive ones, infers conventional commit type from git diff, drafts message with scope, and executes after confirmation. Use anytime like post-planning or mid-TDD.
Generates Conventional Commits messages for staged git changes and commits them. Follows v1.0.0 spec with types like feat, fix, refactor. Use for standardized commits or /commit invocation.