Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Pre-commit and pre-push hook templates for AI agent projects that enforce quality gates automatically. Includes hooks for: code formatting (Prettier/Biome), linting (ESLint/Ruff/Clippy), type checking (TypeScript/pyright), security scanning (secrets detection, dependency audit), commit message convention (Conventional Commits), branch naming policy, and AI-generated code markers. One install, zero configuration - auto-detects your project stack and activates relevant hooks. Works with Git hooks,
.claude/skills/gitstq-universal-hooks/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flashlowest | 84% | 38 |
| gemini-3.1-pro-preview | 100% | 1 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 83% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 172% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 214% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 93% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 56% | 0% |
> Install once, forget forever. Your code quality is now on autopilot.
A smart hook system that auto-detects your project stack and installs exactly the quality gates you need. No configuration files to edit. No boilerplate to copy. It just works.
| Gate | What It Checks | Languages | |------|---------------|-----------| | Formatter | Code formatting consistency | All (Prettier, Biome, Black, gofmt) | | Linter | Code quality rules & anti-patterns | JS/TS (ESLint), Python (Ruff), Rust (Clippy), Go (golint) | | Type Check | Type correctness | TypeScript, Python (pyright/mypy) | | Import Sort | Import ordering & cleanup | JS/TS, Python |
| Gate | What It Checks | |------|---------------| | Secrets Detection | API keys, tokens, passwords in code | | Dependency Audit | Known vulnerable dependencies | | License Check | License compliance of dependencies | | Permissions Check | File permission anomalies |
| Gate | What It Checks | |------|---------------| | Commit Message | Conventional Commits format | | Branch Name | Team branch naming convention | | File Size | Prevent large file commits | | Binary Files | Prevent unexpected binary commits | | Merge Markers | Detect leftover conflict markers | | Debug Code | Detect console.log, debugger, TODO/FIXME | | AI Markers | Track AI-generated code with markers |
When you run "setup git hooks", the skill:
package.json, pyproject.toml, Cargo.toml, go.mod, etc.).husky/ or .git/hooks/Detected: package.json → JavaScript/TypeScript project
├─ eslint config found → Enable ESLint hook
├─ prettier config found → Enable Prettier hook
├─ typescript found → Enable TypeScript check hook
└─ No conventional commits → Enable commit message hook
Detected: pyproject.toml → Python project
├─ ruff config found → Enable Ruff hook
├─ mypy config found → Enable type check hook
└─ No black config → Suggest Biome for formatting
Detected: Cargo.toml → Rust project
├─ Enable cargo clippy hook
├─ Enable cargo fmt hook
└─ Enable cargo test hookbash#!/bin/bash # Auto-generated by Universal Hooks Skill # Project: my-awesome-project # Generated: 2026-03-20 set -e echo "🔍 Running quality gates..." # === Formatters === if command -v prettier &> /dev/null; then echo " ▶ Checking formatting (Prettier)..." npx prettier --check "src/**/*.{ts,tsx,js,jsx,json,css,md}" || { echo " ❌ Formatting issues found. Running auto-fix..." npx prettier --write "src/**/*.{ts,tsx,js,jsx,json,css,md}" echo " ✅ Formatting fixed. Please review and re-commit." exit 1 } fi # === Linters === if [ -f ".eslintrc*" ] || [ -f "eslint.config.*" ]; then echo " ▶ Running ESLint..." npx eslint src/ --max-warnings 0 || { echo " ❌ ESLint errors found. Fix them before committing." exit 1 } fi # === Type Checking === if [ -f "tsconfig.json" ]; then echo " ▶ Running TypeScript check..." npx tsc --noEmit || { echo " ❌ TypeScript errors found." exit 1 } fi # === Security === echo " ▶ Scanning for secrets..." if command -v trufflehog &> /dev/null; then trufflehog --no-update . 2>/dev/null || { echo " ❌ Potential secrets detected! Remove them before committing." exit 1 } fi # === AI Code Markers === echo " ▶ Checking AI code markers..." if grep -r "AI-GENERATED" --include="*.ts" --include="*.tsx" --include="*.py" .; then echo " ⚠️ AI-generated code detected. Ensure it's been reviewed." fi # === Debug Code === echo " ▶ Checking for debug code..." if grep -rn "console\.log\|console\.debug\|debugger\|binding\.pry" --include="*.ts" --include="*.tsx" --include="*.js" src/ 2>/dev/null; then echo " ⚠️ Debug code detected. Remove before committing." # Warning only, don't block fi # === Conflict Markers === if grep -rn "<<<<<<\|>>>>>>\|=======" --include="*.ts" --include="*.tsx" --include="*.py" --include="*.js" src/ 2>/dev/null; then echo " ❌ Merge conflict markers found! Resolve before committing." exit 1 fi # === Large Files === MAX_FILE_SIZE=500 # KB LARGE_FILES=$(find . -type f -size +${MAX_FILE_SIZE}k -not -path "./node_modules/*" -not -path "./.git/*" -not -path "./dist/*" -newer .git/HEAD 2>/dev/null) if [ -n "$LARGE_FILES" ]; then echo " ⚠️ Large files detected:" echo "$LARGE_FILES" | while read file; do echo " - $file ($(du -k "$file" | cut -f1)KB)" done echo " Consider using Git LFS for files > ${MAX_FILE_SIZE}KB." fi echo "✅ All quality gates passed!"
bash#!/bin/bash # Enforces Conventional Commits format COMMIT_MSG_FILE=$1 COMMIT_MSG=$(cat "$COMMIT_MSG_FILE") # Conventional Commits pattern: # type(scope): description # Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?:\s.+' if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then echo "❌ Invalid commit message format!" echo "" echo "Expected: type(scope): description" echo "" echo "Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert" echo "" echo "Examples:" echo " feat(auth): add JWT token refresh" echo " fix(api): handle null response from user endpoint" echo " docs: update README installation guide" echo " refactor(utils): extract date formatter to separate module" echo "" echo "Your message: $COMMIT_MSG" exit 1 fi # Check body line length (72 chars max) BODY=$(echo "$COMMIT_MSG" | sed '1d' | sed '/^$/d' | head -1) if [ -n "$BODY" ] && [ ${#BODY} -gt 72 ]; then echo "⚠️ Commit body line too long (${#BODY} > 72 chars). Consider wrapping." fi echo "✅ Commit message format valid."
bash#!/bin/bash # Runs before pushing to remote set -e echo "🚀 Pre-push checks..." # === Run Tests === if [ -f "package.json" ]; then if jq -e '.scripts.test' package.json > /dev/null 2>&1; then echo " ▶ Running tests..." npm test -- --passWithNoTests || { echo " ❌ Tests failed. Fix before pushing." exit 1 } fi fi # === Check Branch Name === BRANCH=$(git branch --show-current) PROTECTED_BRANCHES=("main" "master" "develop" "staging") if [[ " ${PROTECTED_BRANCHES[*]} " =~ " ${BRANCH} " ]]; then echo " ❌ Direct push to '$BRANCH' is not allowed. Use a feature branch and PR." exit 1 fi # === Dependency Audit === if [ -f "package.json" ]; then echo " ▶ Running dependency audit..." npm audit --audit-level=high || { echo " ❌ High severity vulnerabilities found. Run 'npm audit fix' first." exit 1 } fi echo "✅ Pre-push checks passed! Pushing to origin/$BRANCH..."
When the AI agent generates code, it should add markers for traceability:
typescript// AI-GENERATED: This function was generated by an AI coding assistant // Reviewed-by: <developer-name> on 2026-03-20 // Confidence: high export function calculateTotal(items: CartItem[]): number { return items.reduce((sum, item) => sum + item.price * item.quantity, 0); }
The pre-commit hook checks for unreviewed AI-generated code:
bash# Check for AI markers that haven't been reviewed if grep -r "AI-GENERATED" src/ | grep -v "Reviewed-by"; then echo "⚠️ Unreviewed AI-generated code found. Please review and add 'Reviewed-by' marker." fi
yamlname: Quality Gates on: [push, pull_request] jobs: quality: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: Install dependencies run: npm ci - name: Type Check run: npx tsc --noEmit - name: Lint run: npx eslint src/ --max-warnings 0 - name: Format Check run: npx prettier --check . - name: Test run: npm test -- --coverage - name: Security Audit run: npm audit --audit-level=high - name: Check AI Code Reviews run: | UNREVIEWED=$(grep -r "AI-GENERATED" src/ | grep -v "Reviewed-by" | wc -l) if [ "$UNREVIEWED" -gt 0 ]; then echo "::warning::$UNREVIEWED AI-generated files need review" fi
| Command | Description | |---------|-------------| | "setup git hooks" | Auto-detect stack and install all hooks | | "setup pre-commit only" | Install only pre-commit hook | | "setup commit convention" | Install only commit message hook | | "setup CI pipeline" | Generate GitHub Actions config | | "check hooks status" | Show currently active hooks | | "update hooks" | Re-run detection and update hooks |
| Stack | Formatter | Linter | Type Check | Test | Security | |-------|-----------|--------|------------|------|----------| | React/Next.js | Prettier | ESLint | tsc | Jest/Vitest | npm audit | | Vue/Nuxt | Prettier | ESLint | tsc | Vitest | npm audit | | Python/Django | Black/Biome | Ruff | mypy/pyright | pytest | pip audit | | Go | gofmt | golint | - | go test | govulncheck | | Rust | rustfmt | Clippy | - | cargo test | cargo audit | | Java/Spring | google-java-format | Checkstyle | javac | JUnit | OWASP Dep-Check |
This skill works with any AI coding agent that supports the SKILL.md standard:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 20,421 | 18,893 | -7% | 1 | 1 | 0% | 4,231 | 7,014 | +66% | 0 | 0 | — |
case-02 | pass→pass | 16,716 | 11,905 | -29% | 1 | 1 | 0% | 3,091 | 5,262 | +70% | 0 | 0 | — |
case-03 | fail→pass | 19,612 | 15,199 | -23% | 1 | 1 | 0% | 3,374 | 6,158 | +83% | 0 | 0 | — |
case-13 | pass→pass | 10,188 | 6,622 | -35% | 1 | 1 | 0% | 1,913 | 4,308 | +125% | 0 | 0 | — |
case-04 | pass→pass | 8,949 | 3,716 | -58% | 1 | 1 | 0% | 1,582 | 3,683 | +133% | 0 | 0 | — |
case-05 | pass→pass | 11,478 | 6,014 | -48% | 1 | 1 | 0% | 1,824 | 4,030 | +121% | 0 | 0 | — |
case-06 | fail→pass | 11,233 | 13,080 | +16% | 1 | 1 | 0% | 1,932 | 5,251 | +172% | 0 | 0 | — |
case-07 | pass→pass | 9,035 | 8,119 | -10% | 1 | 1 | 0% | 1,493 | 4,416 | +196% | 0 | 0 | — |
case-08 | pass→pass | 8,397 | 2,183 | -74% | 1 | 1 | 0% | 1,329 | 3,371 | +154% | 0 | 0 | — |
case-09 | pass→pass | 14,283 | 6,799 | -52% | 1 | 1 | 0% | 2,209 | 4,268 | +93% | 0 | 0 | — |
case-10 | pass→pass | 10,839 | 9,428 | -13% | 1 | 1 | 0% | 2,047 | 4,733 | +131% | 0 | 0 | — |
case-11 | fail→pass | 5,996 | 2,234 | -63% | 1 | 1 | 0% | 1,037 | 3,261 | +214% | 0 | 0 | — |
case-12 | pass→pass | 10,548 | 1,502 | -86% | 1 | 1 | 0% | 1,708 | 3,235 | +89% | 0 | 0 | — |
case-14 | fail→pass | 14,114 | 9,485 | -33% | 1 | 1 | 0% | 2,354 | 4,551 | +93% | 0 | 0 | — |
case-15 | fail→fail | 11,169 | 1,384 | -88% | 1 | 1 | 0% | 2,146 | 3,209 | +50% | 0 | 0 | — |
case-16 | fail→pass | 11,345 | 1,525 | -87% | 1 | 1 | 0% | 2,031 | 3,178 | +56% | 0 | 0 | — |
case-17 | pass→pass | 9,957 | 2,145 | -78% | 1 | 1 | 0% | 1,653 | 3,290 | +99% | 0 | 0 | — |
case-18 | pass→pass | 7,701 | 2,563 | -67% | 1 | 1 | 0% | 1,386 | 3,237 | +134% | 0 | 0 | — |
case-19 | pass→pass | 3,281 | 2,205 | -33% | 1 | 1 | 0% | 528 | 3,321 | +529% | 0 | 0 | — |
case-20 | fail→fail | 16,918 | 25,148 | +49% | 1 | 1 | 0% | 3,373 | 8,490 | +152% | 0 | 0 | — |
case-21 | fail→fail | 15,396 | 17,091 | +11% | 1 | 1 | 0% | 2,995 | 6,399 | +114% | 0 | 0 | — |
case-22 | fail→fail | 8,433 | 7,829 | -7% | 1 | 1 | 0% | 1,628 | 4,432 | +172% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.