commit
GitHub指导 Agent 使用 Conventional Commits 规范进行代码暂存和提交,确保符合项目格式要求及 CI 校验。
Trigger Scenarios
Install
npx skills add kdlbs/kandev --skill commit -g -y
SKILL.md
Frontmatter
{
"name": "commit",
"description": "Stage and commit changes using Conventional Commits. Use when there are dirty\/staged files to commit, the user says \"commit\", or before pushing a PR."
}
Commit
Planner Entry
Stage and commit changes in the primary conversation after the task-defined
implementation checks pass. Do not add broad post-commit /verify before push
by default. Preserve the hook receipt as normal commit evidence.
Create a git commit following this project's Conventional Commits convention. These messages are used by git-cliff (cliff.toml) to auto-generate changelogs and release notes. PRs are squash-merged, so the PR title becomes the commit on main — CI validates it via pr-title.yml.
Available skills
/pr-fixup— Use after the PR opens only for CI or actionable reviewer findings.
Format
type: lowercase description
Allowed Types
| Type | Use for | In changelog? |
|---|---|---|
feat |
New features | Yes (Features) |
fix |
Bug fixes | Yes (Bug Fixes) |
perf |
Performance improvements | Yes (Performance) |
refactor |
Code refactoring | Yes (Refactoring) |
docs |
Documentation changes | Yes (Documentation) |
chore |
Maintenance, deps, configs | No |
ci |
CI/CD changes | No |
test |
Test-only changes | No |
Rules
- Subject must start with a lowercase letter
- Scope is optional:
feat(ui): add dialogis valid - Include PR/issue number when relevant:
feat: add release notes (#295) - Breaking changes: add
!after type:feat!: remove legacy API - Keep the first line under 72 characters
- Body lines must be ≤100 characters (commitlint
body-max-line-length). Hard-wrap bullet points before committing; long URLs or prose lines that exceed 100 chars will fail the hook withbody's lines must not be longer than 100 characters. If a HEREDOC body fails, re-wrap and create a new commit — do not amend.
Examples
feat: add release notes dialog
fix: flaky test in orchestrator (#292)
refactor: extract session handler into separate module
chore: update dependencies
ci: add PR title linting workflow
Steps
Track these steps with an internal todo/checklist and mark them complete as you go. Do not create, update, or delete Kandev subtasks for this workflow unless the user explicitly requests task tracking.
-
Understand changes: Run
git statusandgit diffto understand all changes. Review recent commits withgit log --oneline -10to match project style. -
Ensure pre-commit hooks are wired up. This must work in worktrees too, where
.git/is a file (not a directory) and the real hooks path is shared with the main repo viacore.hooksPath. Usegit rev-parse --git-pathso the check resolves correctly regardless:# Is the framework on PATH? pre-commit --version >/dev/null 2>&1 && echo "INSTALLED" || echo "NOT_INSTALLED" # Is the hook actually wired into git's hook system? PRE_COMMIT_HOOK_PATH=$(git rev-parse --git-path hooks/pre-commit) COMMIT_MSG_HOOK_PATH=$(git rev-parse --git-path hooks/commit-msg) test -f "$PRE_COMMIT_HOOK_PATH" && grep -q "pre-commit" "$PRE_COMMIT_HOOK_PATH" \ && test -f "$COMMIT_MSG_HOOK_PATH" && grep -q "pre-commit" "$COMMIT_MSG_HOOK_PATH" \ && echo "ACTIVE" || echo "INACTIVE"-
If NOT_INSTALLED, tell the user once: "⚠️ pre-commit is not on PATH. Install it with
pip install pre-commitso format/lint runs on every commit." Then continue (don't block). -
If installed but INACTIVE, install it yourself — the project ships
.pre-commit-config.yamlandmake doctoris a no-op-on-already-installed wrapper around the same command:pre-commit install -t pre-commit -t commit-msg --overwriteMention that you wired it up. Subsequent commits will run hooks automatically.
-
If both checks pass, no output needed.
-
Before the first commit, ensure the worktree can run the commit-msg dependency. If
apps/node_modules/.bin/commitlintis absent, install it fromapps/before committing:cd apps && pnpm install --frozen-lockfileRetry the normal commit after the install; never bypass the hook.
-
After merging or rebasing the base branch, if
apps/package.jsonorapps/pnpm-lock.yamlchanged and a hook reportsERR_MODULE_NOT_FOUNDeven thoughapps/node_modules/.bin/commitlintexists, refresh the workspace dependencies fromapps/:cd apps && pnpm install --frozen-lockfileRetry the normal commit without bypassing hooks.
Why this matters: a missing hook lets lint regressions slip past local commits and only surface in CI (e.g. funlen / cognitive complexity on backend Go code). The hook catches them in <1s at commit time. See
Makefile'sdoctortarget for the idempotent install command. -
-
Capture the parent SHA and preserve hook evidence:
git rev-parse HEADNever use
--no-verify,SKIP, or another hook-bypass option or environment variable. A bypassed commit is allowed only when the user explicitly requests it, and its receipt must saybypass: true; it never qualifies as a successful hook receipt. -
Stage files: Stage relevant files (prefer specific files over
git add -A).- Splitting commits with new files: When introducing a brand-new file alongside the file that uses it, stage them together. The Go lint pre-commit hook stashes unstaged changes before linting but keeps untracked files in the working tree — so a new helper committed alone, while its (still-unstaged) caller sits in the working tree, lints as
unusedand rejects the commit.
- Splitting commits with new files: When introducing a brand-new file alongside the file that uses it, stage them together. The Go lint pre-commit hook stashes unstaged changes before linting but keeps untracked files in the working tree — so a new helper committed alone, while its (still-unstaged) caller sits in the working tree, lints as
-
Commit: Write a commit message following the format above. If changes span multiple concerns, consider separate commits. When
MERGE_HEADexists or a merge commit is being completed, usegit commit --no-editso a non-interactive runner does not open an editor; normal hooks still run. Confirm the merge commit exists andMERGE_HEADis gone before reporting success. If a formatter changes files and prevents the commit, review and re-stage those files, then create a new commit attempt; do not use--amend. When editing harness files such asAGENTS.md,CLAUDE.md, or skills, run the shared validation in.agents/skills/harness-improvement/references/validation.mdbefore committing. If a JSX layout-only edit touches an element containing an existing hardcoded user-facing literal,i18n-new-codemay classify that literal as changed copy and fail. Localize it and add matchingen/pseudocatalog entries before retrying; verify withcd apps/web && pnpm run i18n:checkand the normal hook receipt. Capture the normal hook stream in a temporary log while committing and use that log to record each hook ID and result. Do not infer hook results from a condensed launcher summary. For example:COMMIT_LOG="$(mktemp "${TMPDIR:-/tmp}/kandev-commit.XXXXXX.log")" set -o pipefail git commit -m "type(scope): description" 2>&1 | tee "$COMMIT_LOG" >/dev/nullRead the log to extract the hook receipt, rather than printing the full stream again. Remove the exact temporary file after copying the receipt into the handoff:
unlink "$COMMIT_LOG"If the commit exits nonzero, preserve and print the full or bounded log before cleanup so hook diagnostics are not lost. Remove the temporary log only after copying a successful hook receipt or recording the failed output.
If a hook fails only because another worktree is already running golangci-lint (for example,
parallel golangci-lint is running), wait for that run to finish and retry the same commit. Do not bypass hooks or change code for this transient lock; verify the retry has a normal hook receipt and a clean worktree.If a hook fails with
ENOSPC, load/verify's Disk-constrained runners guidance: inspectdf, preserve managed caches, relocate only the affected cache to an explicit persistent agent-owned path, and never bypass hooks or blindly delete shared caches. -
Return a hook receipt: After a successful commit, report:
parent_sha: <pre-commit HEAD> commit_sha: <new HEAD> pre_commit_hook: active|inactive commit_msg_hook: active|inactive hook_results: <hook-id=passed|skipped, ...> bypass: false|true commit_result: pass worktree: clean|dirtyverifymay use the receipt only when both hooks are active, bypass is false, the commit succeeded, the currentHEADstill equalscommit_sha, and the worktree is clean. The commit worker does not run verification.
Version History
-
1578843
Current 2026-08-16 08:47
新增 /pr-fixup 技能说明;细化 pre-commit hooks 在 worktrees 中的检测逻辑与硬换行规则。
- b4239d8 2026-07-24 17:32


