stapes-precommit
v0.1.1
Published
Zero-config pre-commit hook with five sanity checks: secrets, large files, console.log, TODO markers, sensitive paths. One command to install, zero config to maintain. Zero telemetry. Stable --json output for AI agents and CI.
Maintainers
Readme
stapes-precommit
A pre-commit hook only protects you if every commit goes through it. Most setups break within a week.
stapes-precommitis one command, five checks, zero per-developer setup. No Python. No Docker. No config file to maintain. No telemetry. Works offline.
Why
Three failure modes repeat across every team that doesn't have a working pre-commit hook:
- The leaked AWS key on day three. A new joiner runs
git commitwithoutpre-commit installever being run, and a key lands onmain. By the time anyone notices, it's been indexed. - The 300 MB binary that broke
git clone. Someone committed a generated asset; nobody noticed until a CI runner ran out of disk. - The 47
console.log("debug", payload)lines on a Friday afternoon. Shipped to staging. Customer sees stack-trace-shaped strings in the logs.
stapes-precommit catches all three. The binary is one file. The install is
one command. There is no config because the five checks are the sane defaults
for 90% of repos.
How
cd /path/to/your/repo
npx stapes-precommit --init
git commit -m "chore: add pre-commit hook"That's it. The hook lives at .git/hooks/pre-commit inside a marker block,
so it won't fight hooks from Husky, pre-commit.com, or lefthook if you later
add them.
The next time anyone runs git commit:
✓ secrets 0 hits
✓ large-files 0 hits
✗ console 1 hit(s)
⚠ todo 1 hit(s)
✓ sensitive-files 0 hits
console:
src/api/handler.ts:42
console.log/warn in production code
console.log("debug", req.body);
1 check(s) failed. Commit blocked.For AI agents and CI scripts, --json gives a stable, parseable shape:
npx stapes-precommit --json | jq '.exitCode, .findings[].message'{
"startedAt": "2026-08-09T10:49:45.195Z",
"tool": "[email protected]",
"exitCode": 1,
"checkCount": 5,
"failed": 1,
"warned": 0,
"findings": [
{
"file": "src/api/handler.ts",
"line": 42,
"message": "console.log/warn in production code",
"evidence": "console.log(\"debug\", req.body);",
"severity": "block"
}
]
}stderr is always empty in --json mode. exitCode is the contract: 0
clean, 1 blocked. That's the whole protocol.
What
The five checks:
| Check | What it catches | Severity | Default thresholds |
|---|---|---|---|
| secrets | AWS keys, GitHub PATs, OpenAI / Anthropic / Stripe / Google keys, JWTs, PEM blocks, generic Bearer tokens | block | matches at 80%+ confidence |
| large-files | files above the size cap | warn > 1 MB, block > 10 MB | --init-config to override |
| console | console.log / console.warn (and console?.log / console?.warn) in .ts / .js / .tsx / .jsx / .mjs / .cjs | block (skipped in *.test.*, *.spec.*, __tests__/, test/ or tests/ directories, and the scripts/ directory) | — |
| todo | TODO / FIXME / XXX without a ticket reference (#1234) | warn (block with --strict) | — |
| sensitive-files | sensitive filenames: .env, *.pem, *.key, id_rsa, credentials.json, service-account*.json, .npmrc, .netrc, *.sqlite | block | filename-based |
Flags:
--init install the pre-commit hook in current repo
--uninstall remove the pre-commit hook
--run run all checks against staged changes (default)
--check <name> run a single check (secrets|large-files|console|todo|sensitive-files)
--list list available checks
--strict treat warnings as errors
--json emit structured JSON on stdout (stable schema)
--init-config <path> write a default config file (then edit before running)
--no-color disable ANSI color output
--version
--helpIdempotent. npx stapes-precommit --init run twice is a no-op.
--uninstall removes the hook cleanly without touching other tools.
Agent-native
This tool is designed for AI agent runtimes and CI scripts:
- Zero telemetry. No network calls. No analytics. No update checks.
- Zero config. No files to write. No env vars to set.
--jsonemits parseable output with a stable schema (startedAt,tool,exitCode,checkCount,failed,warned,findings[]).- Exit codes are stable.
0clean,1blocked,2Node.js too old (engines>=18not met — seesrc/node-check.ts). All other failure modes (not in a git repo,--initfailure, unknown--checkname, unhandled exception) exit1. - Idempotent install.
--initis safe to re-run.--uninstallremoves cleanly. - Runs offline. No API keys. No service to log into.
Verify it yourself (5 lines)
The Agent-native section makes claims. Here's how to check each one in under 30 seconds:
# 1. Zero network calls during a run
npx stapes-precommit --json >/dev/null && \
lsof -p $$ -i 2>/dev/null | grep -E "node|npx" || \
echo "no outgoing TCP from this shell"
# 2. No files written outside .git/hooks/
npx stapes-precommit --init && \
find . -newer package.json -not -path "./.git/*" -not -path "./node_modules/*"
# 3. Stable exit code under --strict
npx stapes-precommit --strict --json | jq '.exitCode'Worked example — agent-style pre-commit block
#!/usr/bin/env bash
# .github/actions/pre-commit/style-check/action.yml step
npx stapes-precommit --json > precommit-report.json
code=$?
if [ "$code" -ne 0 ]; then
jq -r '.findings[] | "::error file=\(.file)::\(.message)"' precommit-report.json
exit 1
fiTelemetry
None. Zero network calls. The only filesystem write is
.git/hooks/pre-commit during --init.
Compared to
| Tool | What you trade away by choosing it |
|---|---|
| gitleaks | More secret patterns, but Docker/Python setup, config YAML to maintain, and a separate install step |
| pre-commit.com | Huge ecosystem of community hooks, but Python on every dev machine and .pre-commit-config.yaml to maintain |
| husky + lint-staged | Per-file hooks, runs linters on changed files only, but lockfile dance, Node-version drift, Windows breaks |
| lefthook | Fast (Go), YAML config, but you maintain the YAML. stapes-precommit is intentionally zero-config. |
| lint-staged alone | Just a runner. Needs linters to be useful. |
stapes-precommit is for teams that want the same five checks on every
commit, on every machine, with zero per-dev setup. If you need custom
checks, layer pre-commit.com on top — they don't fight each other.
Source
Visible at https://github.com/stapesco/precommit. Built by stapes. Read the code. Fork it. PRs are not accepted.
See AGENTS.md for machine-readable install instructions and
the stable --json schema.
Issues
If stapes-precommit doesn't work for you, the most likely fix is in
the five files under src/checks/. Read them, fork, patch.
For security disclosures, see SECURITY.md.
License
MIT
