6.2 KiB
name, description
| name | description |
|---|---|
| commit | 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:Mention that you wired it up. Subsequent commits will run hooks automatically.pre-commit install -t pre-commit -t commit-msg --overwrite - If both checks pass, no output needed.
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. - If NOT_INSTALLED, tell the user once: "⚠️ pre-commit is not on PATH. Install it with
-
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. 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. 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"Remove the temporary log after copying the receipt into the handoff.
-
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.