A zero-dependency git hooks manager. One Python file, stdlib only.

$ curl -LO https://raw.githubusercontent.com/tianzhicdev/hookpack/main/hookpack.py
Python 3.9+stdlib onlyMIT

Quick start

Copy hookpack.py somewhere on your PATH (or run it directly), then install hooks into a repository:

# install the secret scanner and whitespace trimmer (both pre-commit)
$ hookpack add secretscan
$ hookpack add trimtrail

Pass --work-dir DIR before the subcommand to target another repository:

$ hookpack --work-dir ~/code/myrepo add trimtrail

All commands:

CommandDescription
hookpack add NAMEInstall a hook into the current repo
hookpack remove NAMERemove an installed hook
hookpack listList available and installed hooks
hookpack doctorVerify managed hooks, print hook dir, check PATH

Available hooks

HookEventWhat it does
secretscan pre-commit Runs the secretgate scanner (python3 secretgate.py scan .). Uses a local secretgate.py at the repo root if present, otherwise downloads the pinned copy to .git/hookpack/cache/. If neither works (e.g. no network), it prints a notice and skips gracefully instead of blocking your commit.
trimtrail pre-commit Strips trailing whitespace from staged text files (binary files are detected via grep -I and skipped), then re-stages the fixed files.

How it works

Common questions

What is a zero dependency git hooks manager?

A zero dependency git hooks manager installs and runs git hooks (pre-commit, pre-push, commit-msg) without a package ecosystem. hookpack is a single Python file using only the standard library — no Node, no virtualenv, no pip install, no .pre-commit-config.yaml. If the machine has Python 3, it works.

How is hookpack different from pre-commit?

pre-commit is excellent but pulls in a Python package, a per-repo virtualenv cache, and a config schema that assumes network access to resolve hook repositories. hookpack assumes nothing: each hook is one small script, dispatchers are written into .git/hooks/ between managed markers, and removing hookpack cleanly removes only what it added. For air-gapped CI, minimal containers, and "I just want a pre-commit secret scan" repos, it is the lighter path.

How do I run a secret scan on pre-commit without installing anything?

Use hookpack's secretscan hook: it fetches the single-file secretgate scanner with curl at run time and blocks commits containing API keys, tokens, or private keys. No scanner needs to be installed — python3 hookpack.py add secretscan is the whole setup.

Does hookpack touch or overwrite my existing git hooks?

No. Every file hookpack manages carries a # hookpack:managed marker, and hookpack refuses — with an error, before writing anything — to modify any hook file that lacks that marker. Your hand-written hooks are never overwritten, and hookpack remove deletes only hookpack's own files.

Can I verify a hookpack release wasn't tampered with?

Yes. Every release attaches a self-contained signed receipt, hookpack-<tag>-proof.md, with the exact release file embedded. One command proves it: python3 ethkey.py verify hookpack-<tag>-proof.md --require 0xFD4090e27C1f946Ff01a265cAa7d4ACA662acC15 exits 0 only if the payload hash, the EIP-191 signature, and the signer all check out — or paste the receipt into the browser verifier (the link pre-fills the address). The legacy <tag>.sig.txt asset is still attached for compatibility.

Ecosystem

hookpack is part of a small family of curl-and-run tools:

secretgate

Zero-dependency, curl-and-run secret scanner. Powers the secretscan hook.

secretgate-action

GitHub Action wrapper that runs secretgate checks in CI.

ethkey-lite

Lightweight crypto signing tool — paste any release receipt into the browser verifier.

Related reading: how to vet a GitHub bounty payout rail (the other thing our agents build).