Learn-skills.dev quality-commit
Stage, lint, scan, review, and commit changes with full quality gates in a single standardized flow.
git clone https://github.com/NeverSight/learn-skills.dev
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/acedergren/agentic-tools/quality-commit" ~/.claude/skills/neversight-learn-skills-dev-quality-commit && rm -rf "$T"
data/skills-md/acedergren/agentic-tools/quality-commit/SKILL.mdQuality Commit
Run all quality gates (lint, typecheck, Semgrep, CodeRabbit, tests) on staged changes, then commit. This replaces the manual multi-step process that frequently causes pre-commit hook friction.
Steps
1. Determine Scope
Identify which workspace(s) have staged changes:
cd "$CLAUDE_PROJECT_DIR" STAGED=$(git diff --cached --name-only --diff-filter=ACMR)
Categorize staged files into:
- frontend:
apps/frontend/src/**/*.{ts,svelte,js} - api:
apps/api/src/**/*.ts - shared:
packages/shared/src/**/*.ts
If no files are staged, print a warning and exit.
2. Lint Staged Files
For each workspace with staged files:
- frontend:
cd apps/frontend && npx eslint <staged-files> - api:
(if eslint is configured)cd apps/api && npx eslint <staged-files> - shared:
(if eslint is configured)cd packages/shared && npx eslint <staged-files>
On failure: Print the specific errors. Do NOT proceed to commit. Fix the issues first.
3. Type Check
Run type checks only on affected workspaces:
- frontend:
cd apps/frontend && npx svelte-check --tsconfig ./tsconfig.json --threshold error- Note: 11 pre-existing errors in test files are known baseline — ignore those.
- api:
cd apps/api && npx tsc --noEmit - shared:
cd packages/shared && npx tsc --noEmit
On failure: Print errors. Do NOT proceed.
4. Semgrep Security Scan
Important: Semgrep crashes when given multiple file arguments (
Invalid_argument: invalid path bug in 1.146.0–1.151.0+). Always scan files one at a time:
SEMGREP_FINDINGS="" for f in <staged-files>; do RESULT=$(semgrep scan --config auto --json "$f" 2>/dev/null) || true SEMGREP_FINDINGS="$SEMGREP_FINDINGS$RESULT" done
- Parse JSON output from each file and aggregate findings with file:line and rule ID.
- On critical/high findings: Block the commit and show the findings.
- On medium/low findings: Warn but allow proceeding (print them for visibility).
- If
is not installed, skip with a warning.semgrep
5. CodeRabbit Review (Optional)
If
$ARGUMENTS contains --review or --full:
coderabbit review --plain -t uncommitted 2>&1
- Parse output and group by severity (Critical, Suggestions, Positive).
- On critical findings: Block the commit and show details.
- If
CLI is not installed, skip with a warning.coderabbit
6. Run Related Tests
For each staged
.ts/.svelte file, look for a colocated .test.ts:
# Example: src/lib/server/auth/rbac.ts → src/lib/server/auth/rbac.test.ts # Example: src/routes/chat.ts → src/routes/chat.test.ts
Run discovered test files with
npx vitest run <test-files> --reporter=verbose.
On failure: Print failing tests. Do NOT proceed.
7. Commit
If all gates pass:
-
Review the staged diff one more time.
-
Draft a commit message following the project convention:
type(scope): description Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> -
Create the commit using a HEREDOC for the message.
Types:
feat, fix, refactor, test, docs, chore
Scopes: security, phaseX.Y, api, frontend, database, auth, workflows
8. Push (only with --push
)
--pushIf
$ARGUMENTS contains --push:
-
Run semgrep on files from the last commit (one file at a time — see Step 4 note on multi-file bug):
COMMITTED_FILES=$(git diff --name-only HEAD~1 -- '*.ts' '*.svelte' '*.js') SEMGREP_FINDINGS="" for f in $COMMITTED_FILES; do RESULT=$(semgrep scan --config auto --json "$f" 2>/dev/null) || true SEMGREP_FINDINGS="$SEMGREP_FINDINGS$RESULT" done- On critical/high findings: Abort push, print findings. The commit stays intact.
- On medium/low findings: Warn but continue.
- If
is not installed, skip with a warning.semgrep
-
Determine branch and upstream:
BRANCH=$(git rev-parse --abbrev-ref HEAD) UPSTREAM=$(git rev-parse --abbrev-ref @{u} 2>/dev/null || echo "") -
Push:
- If upstream exists:
git push - If no upstream:
git push -u origin $BRANCH - If
is also set: Print "would push to origin/$BRANCH" and skip the actual push.--dry-run
- If upstream exists:
-
On push failure: Report the error. The commit remains intact — do NOT attempt to undo it.
If
--push is not passed, skip this step entirely.
9. Summary
Print a summary table:
| Gate | Status | Details | |-------------|--------|----------------------------| | Lint | PASS | 5 files, 0 errors | | TypeCheck | PASS | api + frontend | | Semgrep | PASS | 0 findings | | CodeRabbit | SKIP | (use --review to enable) | | Tests | PASS | 3 test files, 12 tests | | Commit | DONE | abc1234 | | Push | PASS | pushed to origin/feature-x |
When push is not requested, show:
| Push | SKIP | (use --push to enable) |
Arguments
: Optional flags:$ARGUMENTS
or--review
: Include CodeRabbit review (slower, ~30s)--full
: Run all gates but skip the actual commit (and push)--dry-run
: After successful commit, run semgrep on committed files and push to remote--push
: Use a custom commit message instead of auto-generating one--message "custom message"- If empty: Run lint + typecheck + semgrep + tests + commit (skip CodeRabbit, skip push)
Error Recovery
If any gate fails:
- Print the specific errors clearly
- Suggest targeted fixes
- Do NOT attempt to auto-fix and retry — let the user (or agent) fix first, then re-run
/quality-commit
Examples
— Standard flow: lint, typecheck, semgrep, tests, commit/quality-commit
— Full flow with CodeRabbit review included/quality-commit --review
— Validate everything but don't commit or push/quality-commit --dry-run
— Standard flow + push after commit/quality-commit --push
— Full flow with CodeRabbit + push/quality-commit --review --push
— Run all gates, print "would push", skip actual commit and push/quality-commit --push --dry-run
— Custom commit message/quality-commit --message "fix(security): add IPv6 SSRF checks"