pre-commit-setup
Pre-commit setup
Wire pre-commit hooks into any git repo. Default to the universal pre-commit framework (works for any language); use Husky + lint-staged for pure-Node repos when the user explicitly asks. Always cover formatting, linting, type-checking (where applicable), secret scanning, and Conventional Commits.
When to use
- The user asked to set up pre-commit hooks, install husky, configure lint-staged, or wire up commit-time checks.
- A new repo is being bootstrapped and you're standardizing the dev experience.
- An existing repo has commit-time issues (secrets leaked, lint fails after merge, large files committed) and the user wants prevention.
- A monorepo or polyglot repo needs a single pre-commit configuration that covers multiple languages.
Skip this skill for: repos that already have a working pre-commit configuration the user is happy with (touch only with explicit ask), build-time CI checks (those belong in CI, not pre-commit), or pre-push hooks (different lifecycle).
Required outcome
After this runs, a fresh git commit in the repo must:
- Auto-format staged files (Prettier / Black / gofmt / etc., per language).
- Lint staged files (ESLint / Ruff / PHPStan / Checkstyle / golangci-lint / etc.).
- Run type checks (where the language supports them).
- Scan for secrets and large files.
- Validate the commit message format (Conventional Commits).
- Block the commit on any failure with a readable error.
- Be fast — the full pre-commit run should be under ~10 seconds for typical changes.
Workflow
- Verify a git repo.
git rev-parse --is-inside-work-tree. If not, ask whether togit initor stop. - Detect languages. Run
bash scripts/detect-languages.shor do the equivalent: check forpackage.json,pyproject.toml/requirements.txt/setup.py,composer.json,pom.xml/build.gradle*,go.mod,Cargo.toml,Gemfile,*.shfiles. Multiple matches → multi-language. - Pick the framework:
- Default → universal
pre-commitframework (pre-commit.com). Works for any language, has thousands of hook integrations. Loadreferences/pre-commit-framework.md. - Pure-Node repo + user explicitly asked for Husky → Husky + lint-staged + Prettier track. Load
references/husky-track.md. - Polyglot repo → always pre-commit framework. Husky doesn't handle non-JS files cleanly.
- Default → universal
- Pick the hooks per detected language. Load
references/language-hooks.mdand copy the matching block(s) into.pre-commit-config.yaml. Cover formatter, linter, and type-checker per language. - Add universal hooks. Load
references/universal-hooks.md. Always include trailing-whitespace, end-of-file-fixer, check-merge-conflict, check-added-large-files, check-yaml/json/toml (when present), and a secret scanner (gitleaksordetect-secrets). - Add commit-msg hook. Load
references/commit-msg.md. Wirecommitlint(Node) orcommitizen(cross-language) for Conventional Commits. - Install. Run
pre-commit install(writes.git/hooks/pre-commit) andpre-commit install --hook-type commit-msg(for the commit-msg hook). For Husky,npx husky init. - Smoke test. Run
pre-commit run --all-filesonce. Expect the first run to fix formatting on existing files; that's normal. Re-run to confirm it's clean. - Commit. Stage the new config files and commit with a Conventional message:
chore: add pre-commit hooks (formatter, linter, secrets, conventional commits). The commit itself is the final smoke test.
Available resources
references/pre-commit-framework.md— universalpre-commitframework: install,.pre-commit-config.yamlsyntax, common hooks, troubleshooting.references/husky-track.md— Node-only Husky + lint-staged + Prettier setup, plus the optional heavyweight variant that runs typecheck + tests on every commit.references/language-hooks.md— recommended formatter / linter / type-checker hooks per language: Node.js, Python, PHP, Java, Go, Rust, Ruby, Shell. Copy-paste blocks.references/universal-hooks.md— language-agnostic hooks: whitespace, EOF, large files, merge-conflict markers, JSON/YAML/TOML validation, secret scanners.references/commit-msg.md— Conventional Commits enforcement viacommitlintorcommitizen.assets/templates/pre-commit-config-multi-language.yaml— kitchen-sink config covering all languages this skill knows about.assets/templates/pre-commit-config-minimal.yaml— universal hooks only (whitespace, EOF, secrets, conventional commits) for unknown-language repos.assets/templates/husky-pre-commit— Husky v9 pre-commit script for Node repos.assets/templates/lintstagedrc.json— lint-staged config for the Husky track.assets/templates/prettierrc.json— Prettier defaults.assets/examples/full-example.md— worked setup on a polyglot repo.scripts/detect-languages.sh— detect what languages a repo uses; run before picking hooks.
Top gotchas (always inline — do not skip)
- Polyglot repo → use
pre-commit, not Husky. Husky + lint-staged works well for pure-JS, but fights non-JS files and doesn't have ecosystem coverage for Python / Java / PHP / Go. Thepre-commitframework is the universal answer. - Detect first, configure second. Do not paste a Python-only or Node-only template into a polyglot repo. Run the detection step or you'll ship hooks that fail loudly on every commit.
pre-commitis a Python tool, not a JS tool. It runs hooks for any language, but it itself installs viapip install pre-commit(orpipx, orbrew install pre-commit). Don't confuse it with Husky.- The first
pre-commit run --all-fileswill modify existing files. Formatters fix existing whitespace, EOF, formatting. That's expected — commit the auto-fixes, then re-run. The user should know this before you run it. - Pin hook versions. Use
rev: v1.2.3notrev: mainin.pre-commit-config.yaml.pre-commit autoupdateis the maintenance command for bumping. Floating refs break repos when upstream changes. - Don't run full test suites in pre-commit. Tests take too long; pre-commit should be < 10s. Tests belong in pre-push or CI. The heavyweight Husky variant runs
npm run testin pre-commit; that's a trade-off the user should opt into, not a default. - Type-checking is repo-scoped, not file-scoped. ESLint runs per-file, but
tsc,mypy, and most type checkers need the whole project. Run them outsidelint-staged's file-scoping (top-level command), or accept that incremental mode misses some errors. gitleaksanddetect-secretsare not interchangeable.detect-secretsrequires a baseline file (.secrets.baseline) and only flags new secrets vs the baseline.gitleaksflags any secret matching its rules. Pick one and document the workflow — don't add both.- Conventional Commits enforcement is opinionated. Some teams want it, some hate it. Default to enforcing it only when the user asked for it or when the repo already uses it (check existing commit messages with
git log --oneline -20). - Hooks must work on Windows / WSL / macOS / Linux. The
pre-commitframework handles this; raw shell hooks in Husky don't. If you're writing a custom hook, use a portable shebang and POSIX shell, or pin it to one OS in the docs. - Do not bypass with
--no-verifyto "fix" failing hooks. If hooks fail, fix the cause. The only legitimate--no-verifyis for emergency hotfixes the user explicitly chooses. - The hook config file is the source of truth.
.pre-commit-config.yaml(or Husky's.husky/pre-commit) is what the team commits and reviews. Don't sneak hooks into local-only Git config.
What you DO
- Confirm it's a git repo before doing anything (
git rev-parse --is-inside-work-tree). - Detect languages via
scripts/detect-languages.shor equivalent. - Default to the
pre-commitframework. Use Husky only when the repo is pure-Node and the user asked for Husky by name. - Pick formatter + linter + (where applicable) type-checker for each detected language.
- Add universal hooks: whitespace, EOF, large files, merge-conflict markers, JSON/YAML/TOML validation, secret scanner.
- Add commit-msg hook for Conventional Commits when appropriate (see gotchas).
- Pin all hook versions (
rev: v1.2.3, nevermain). - Run
pre-commit run --all-filesonce to surface and auto-fix the existing-file format drift. - Commit the new config with a Conventional message; that's the final smoke test.
- Tell the user what's now blocked at commit and how to bypass for emergencies (
--no-verify).
What you do NOT do
- Do not paste a single-language template into a polyglot repo.
- Do not use Husky in a polyglot repo.
- Do not run full test suites in pre-commit (move to pre-push or CI).
- Do not add
gitleaksanddetect-secretstogether — pick one. - Do not use floating refs (
rev: main,rev: HEAD) in.pre-commit-config.yaml. - Do not silently overwrite an existing pre-commit config without showing the user the diff.
- Do not enforce Conventional Commits on a repo that doesn't use them, unless the user asked.
- Do not bypass failing hooks with
--no-verifyto "make it pass". Fix the underlying cause. - Do not add tooling for languages the repo doesn't use.
- Do not introduce a Python dependency (
pre-commit) into a Node-only repo if the user wants Husky — respect the explicit ask. - Do not commit a
.pre-commit-config.yamlwithout first running it once and verifying it's clean.
More from mkabumattar/skills
linux-script-developer
Write production-ready Bash scripts with strict error handling (`set -euo pipefail`), validated argument parsing, colored user feedback, and cross-platform compatibility (Linux, macOS, Windows via Git Bash/WSL). Use this skill whenever the user asks for a `.sh` script, a shell script, a Bash one-liner installer, a deployment script, an automation/CI script, a CLI wrapper, or a file-batch processor — including casual phrasings like "write a script to ...", "automate this in bash", or "make me a shell tool". Also use when reviewing or hardening an existing Bash script.
16skill-builder
Build a new Agent Skill that follows the agentskills.io specification and best practices — slim `SKILL.md` (≤ 200 lines / 5K tokens), valid kebab-case `name`, imperative `description` under 1024 chars, progressive disclosure via `references/`, bundled `assets/` and `scripts/`, and an MIT `LICENSE`. Use this skill whenever the user asks to create, scaffold, build, write, or author a new Agent Skill — including phrasings like "build a skill for X", "scaffold a new skill", "create an agent skill", "make me a skill that does X", "write a SKILL.md for ...", or "I want to publish a skill on agentskills.io". Also use when reviewing or refactoring an existing oversized `SKILL.md` (a sign that detail should be moved to `references/`).
15python-script-developer
Write production-ready Python CLI tools, automation scripts, and batch file processors with type hints, structured `logging` (never `print` for diagnostics), `argparse` interfaces, `pathlib` for filesystem work, specific exception handling, and cross-platform support (Linux, macOS, Windows). Use this skill whenever the user asks to create a Python script, `.py` utility, CLI tool, automation, batch processor, or data pipeline — including casual phrasings like "write a python script that ...", "automate this in python", "I need a small tool", or "give me a one-off processor". Also use when reviewing or hardening an existing Python script.
15information-architecture
Plan the structural and execution architecture of a feature, app, or site — produce both an `INFORMATION_ARCHITECTURE.md` (site map, navigation, content hierarchy, user flows, URL strategy, naming conventions, component reuse map) AND a phased `PLAN.md` (phases by impact/effort/risk, vertical-slice tasks with sub-tasks, dependencies, estimates, and a detailed task breakdown with Why/How/Impact/Effort). Use this skill whenever the user wants to plan a product or feature, design site structure, lay out information architecture, map user flows, organize content, break work into phases, build a roadmap, plan an implementation order, or hits you with phrases like "plan the IA", "map the structure", "break this into tasks", "give me a roadmap", "phase out the work", "create an enhancement plan", or "what should I build first". Also use when reviewing or refactoring an existing IA or project plan.
15makefile-script-developer
Write production-ready GNU Makefiles with strict shell mode (`SHELL := /bin/bash` + `.SHELLFLAGS := -euo pipefail -c`), validated multi-environment configuration via `$(filter ...)`, pre-flight check targets (`check-tools`, `check-env`), structured logging with timestamps, confirmation gates for destructive ops, layered `.env` includes, platform detection, and self-documenting help. Use this skill whenever the user asks to write a Makefile, harden an existing one, add a target, build a deploy/release pipeline, automate Terraform/Helm/Kubernetes/Docker/build workflows, or expose tasks as `make <target>` — including casual phrasings like "write a Makefile", "add a make target", "automate this in make", "give me a build pipeline", or "clean up the Makefile". Also use when reviewing an existing Makefile for safety, error handling, or organization issues.
15qa
Run an interactive QA session — the user describes bugs and issues conversationally, you ask brief clarifying questions, explore the codebase for domain context, decide whether to file one issue or break it down, and create durable user-focused GitHub issues via `gh issue create` — without referencing internal file paths or line numbers. Use this skill whenever the user wants to do QA, report bugs, file issues, walk through a list of problems, or hits you with phrases like "let's do a QA session", "I found a bug", "this is broken", "file this as an issue", "I have a few things to report", or "let's go through these one by one". Also use when the user is reviewing a deployed feature and wants to track defects.
14