Skip to main content
Back to docs
workflowpre-commit-hooks
Install
Source: packages/harness-kit/src/registry/bundles/workflow/pre-commit-hooks/README.md

Pre-commit Hooks

Blocks bad commits at the git layer — conflict markers, obvious secrets, and tech-stack-appropriate lint/typecheck/test. No framework dependency (husky, lefthook, pre-commit.com) — just a portable shell script.

What it installs

ArtifactPath (in your project)Purpose
Git hook dispatcher.githooks/pre-commitCanonical dispatcher — runs every *.sh in .githooks/pre-commit.d/ in sorted order; blocks commit on any failure. Auto-installed by engine on any git-hook artifact
Check script.githooks/pre-commit.d/pre-commit-hooks.shTech-stack scanner — conflict markers, secrets, Node/Python/Go/Rust checks
Rule.claude/rules/pre-commit-hooks.mdTells the agent not to --no-verify on failure, and where to add project checks

How it works

The hook is a single self-gating script. Every check inspects the project for marker files before running — nothing fires on a stack you don't use:

CheckFires whenWhat it does
Conflict markersalways (if anything staged)Blocks commits containing <<<<<<<, =======, >>>>>>>
Secret scanalwaysHeuristic match for AWS keys, private-key headers, GitHub/Slack/OpenAI tokens
Node.jspackage.json present + JS/TS stagedRuns lint, typecheck, test npm scripts that exist (auto-detects pnpm/yarn/bun)
Pythonpyproject.toml/requirements.txt + .py stagedruff check on staged files; mypy if [tool.mypy] configured
Gogo.mod + .go stagedgofmt -l (blocks if unformatted), go vet ./...
RustCargo.toml + .rs stagedcargo fmt --check, cargo clippy -- -D warnings
User extensions.githooks/pre-commit.d/*.sh existsSources each script in sorted order; any non-zero exit blocks commit

The secret scan is a last-line guard, not a replacement for gitleaks/trufflehog. It catches the obvious leaks (committed .env with AKIA…, pasted private key) — integrate a dedicated scanner for deeper coverage.

Setup

After install, activate the hooks directory once per clone:

npx harness-kit activate
# or manually:
git config core.hooksPath .githooks

Adding project-specific checks

Drop any executable script into .githooks/pre-commit.d/:

mkdir -p .githooks/pre-commit.d
cat > .githooks/pre-commit.d/99-custom.sh <<'EOF'
#!/usr/bin/env bash
# your check here
EOF
chmod +x .githooks/pre-commit.d/99-custom.sh

Each bundle's check lands at .githooks/pre-commit.d/<bundle-name>.sh, so they compose without collision. If a non-harness-kit pre-commit hook existed before install, the engine migrates it to .githooks/pre-commit.d/00-legacy.sh automatically — it keeps running alongside the new checks.

Bypassing (rare)

If a check is a false positive and blocks legitimate work:

git commit --no-verify

Prefer fixing the check or filtering the file over habitual bypassing.

Pairs well with

  • conventional-commits — pre-commit runs before the commit; conventional-commits validates the commit message shape afterward. Different gates, different failure modes.
  • quality-gates — same philosophy at the agent-workflow layer (lint/typecheck/test before declaring done). This one enforces it at the git layer.
  • local-memory — its conflict-marker check migrates into .githooks/pre-commit.d/ and composes with the rest.