This skill should be used when the user asks to "configure husky", "set up lefthook", "add pre-push hook", "add pre-commit hook", "git hooks not running", "husky not working", "modify git hooks", or needs deep reference for a specific git hook framework.
From code-qualitynpx claudepluginhub nthplusio/functional-claude --plugin code-qualityThis skill uses the workspace's default tool permissions.
Implements CQRS patterns with Python templates for command/query separation, event-sourcing, and scalable read/write models. Use for optimizing queries or independent scaling.
Implements Clean Architecture, Hexagonal Architecture (ports/adapters), and Domain-Driven Design for backend services. For microservice design, monolith refactoring to bounded contexts, and dependency debugging.
Provides REST and GraphQL API design principles including resource hierarchies, HTTP methods, versioning strategies, pagination, and filtering patterns for new APIs, reviews, or standards.
Deep reference for managing git hooks across frameworks. Use /code-quality-setup for initial setup; this skill is for modifying, extending, or understanding existing hook configurations.
Best for: Single-package JS/TS projects. Most popular in the JS ecosystem.
# Install
npm add -D husky
# Initialize (creates .husky/ directory and adds prepare script)
npx husky init
This creates:
.husky/pre-commit — default pre-commit hookpackage.json "prepare": "husky" script (runs on npm install)Hook files live in .husky/ and are plain shell scripts:
.husky/pre-commit:
npx lint-staged
.husky/pre-push:
npm run typecheck
npm run build
npm test
# Create a new hook file
echo "npm test" > .husky/pre-push
Husky automatically makes hooks in .husky/ executable. Supported git hooks: pre-commit, pre-push, commit-msg, pre-rebase, post-merge, etc.
# Skip hooks for a single operation
git commit --no-verify
git push --no-verify
npm install (triggers prepare script)chmod +x .husky/pre-commitpackage.json for "prepare": "husky", then run npm run preparenvm or specify path.Best for: Monorepos, polyglot projects, teams wanting parallel hook execution. No npm lifecycle dependency.
# Install via npm
npm add -D lefthook
# Or install standalone (no Node dependency)
# brew install lefthook
# go install github.com/evilmartians/lefthook@latest
# Initialize
npx lefthook install
All configuration lives in lefthook.yml:
pre-commit:
parallel: true
commands:
lint-js:
glob: "*.{js,jsx,ts,tsx}"
run: npx eslint --fix {staged_files} && git add {staged_files}
lint-py:
glob: "*.py"
run: ruff check --fix {staged_files} && git add {staged_files}
format:
glob: "*.{json,md,yml,yaml,css}"
run: npx prettier --write {staged_files} && git add {staged_files}
pre-push:
commands:
typecheck:
run: npm run typecheck
test:
run: npm test
{staged_files} — Expands to list of staged files matching the glob{all_files} — All tracked files matching the glob{push_files} — Files changed between local and remoteparallel: true — Run commands concurrently (faster)glob: — Filter which files trigger the commandroot: — Run command from a subdirectory (monorepo packages)exclude: — Regex to exclude filespre-commit:
parallel: true
commands:
lint-frontend:
root: "packages/frontend/"
glob: "*.{ts,tsx}"
run: npx eslint --fix {staged_files}
lint-backend:
root: "packages/backend/"
glob: "*.{ts,tsx}"
run: npx eslint --fix {staged_files}
test-shared:
root: "packages/shared/"
run: npx vitest run
npx lefthook install (re-installs git hooks)root: for subdirectories.parallel: true to the hook groupLEFTHOOK_VERBOSE=1 git commit -m "test"Best for: Python projects, polyglot repos. Manages hook dependencies automatically.
pip install pre-commit
pre-commit install
.pre-commit-config.yaml:
repos:
# Ruff (Python linting + formatting)
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
# MyPy (Python type checking)
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.13.0
hooks:
- id: mypy
additional_dependencies: []
# General file checks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
- id: check-merge-conflict
# ESLint (if JS/TS files present)
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v9.15.0
hooks:
- id: eslint
files: \.(js|jsx|ts|tsx)$
additional_dependencies:
- eslint@9
repos:
- repo: local
hooks:
- id: pytest
name: pytest
entry: pytest
language: system
stages: [pre-push]
pass_filenames: false
- id: mypy-full
name: mypy (full)
entry: mypy .
language: system
stages: [pre-push]
pass_filenames: false
pre-commit install --hook-type pre-push
# Run against all files (useful for initial setup)
pre-commit run --all-files
# Run a specific hook
pre-commit run ruff --all-files
# Update hook versions
pre-commit autoupdate
# Skip hooks
SKIP=ruff git commit -m "wip"
pre-commit run --all-files to initialize environmentspre-commit autoupdatepre-commit clean to clear cached environmentsBest for: Non-JS/Python projects, minimal dependencies, full control.
# Create hooks directory
mkdir -p .githooks
# Tell git to use it
git config core.hooksPath .githooks
.githooks/pre-commit:
#!/bin/sh
set -e
echo "Running pre-commit checks..."
# Format check (Rust)
if [ -f "Cargo.toml" ]; then
cargo fmt -- --check
cargo clippy -- -D warnings
fi
# Format check (Go)
if [ -f "go.mod" ]; then
# Check if any Go files need formatting
UNFORMATTED=$(gofmt -l $(find . -name "*.go" -not -path "./vendor/*") 2>/dev/null)
if [ -n "$UNFORMATTED" ]; then
echo "Files need formatting:"
echo "$UNFORMATTED"
exit 1
fi
fi
.githooks/pre-push:
#!/bin/sh
set -e
echo "Running pre-push checks..."
# Rust
if [ -f "Cargo.toml" ]; then
cargo check
cargo test
fi
# Go
if [ -f "go.mod" ]; then
go vet ./...
go test ./...
fi
# Make hooks executable (required)
chmod +x .githooks/pre-commit .githooks/pre-push
Add to project README or a setup script:
# Team members run this after cloning
git config core.hooksPath .githooks
Or add a Makefile target:
setup:
git config core.hooksPath .githooks
git config core.hooksPath — should output .githookschmod +x .githooks/*core.hooksPath not set: Run git config core.hooksPath .githooks again.githooks/ to the repo and document the setup stepAll frameworks support commit-msg hooks for enforcing conventions:
# Install
npm add -D @commitlint/cli @commitlint/config-conventional
Create commitlint.config.js:
export default { extends: ['@commitlint/config-conventional'] };
Husky: echo "npx commitlint --edit \$1" > .husky/commit-msg
Lefthook:
commit-msg:
commands:
commitlint:
run: npx commitlint --edit {1}
Pre-commit:
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
rev: v9.18.0
hooks:
- id: commitlint
stages: [commit-msg]