Pre-commit Hook¶
CI is the truth source — it runs on every PR and gates merges. A pre-commit hook is the local optimisation: same lint, sub-second, fails the commit before you even push. Together they form belt-and-suspenders: pre-commit catches it on the contributor's machine, CI catches it for everyone who skips the hook.
When to use¶
- Recommended for any warehouse contributor who runs
pre-commit installas part of their workflow. - Required if your warehouse lives in an air-gapped environment — the hook is the only local enforcement layer until the PR reaches your private CI mirror.
- Optional but cheap for warehouses where CI is the only enforcement point — adds ~800ms to a
git commit, saves a CI round-trip on issues you would have caught.
Drop-in config¶
The hook shells out to the abc binary contributors already have installed (per the Installation page) — pre-commit doesn't manage its own copy. This works identically for connected and air-gapped environments; the only difference is how agentic-beacon reaches PATH (PyPI vs offline bundle), which installation.md covers.
Add .pre-commit-config.yaml to your warehouse root:
repos:
- repo: local
hooks:
- id: warehouse-lint
name: warehouse lint
entry: abc warehouse lint .
language: system
pass_filenames: false
always_run: true
Each contributor (one-time):
# 1. Install agentic-beacon globally (see Installation page for connected
# vs offline-bundle variants).
uv tool install agentic-beacon # connected
# OR
uv tool install --reinstall --no-index --find-links ./bundle agentic-beacon # air-gapped
# 2. Install pre-commit (uv tool install or your team's private mirror)
# and wire the hook into git:
uv tool install pre-commit
pre-commit install
From then on, every git commit runs the lint against the whole working tree. A failure aborts the commit; fix the artifact and re-commit.
Field rationale¶
| Field | Why |
|---|---|
repo: local |
Self-contained in the warehouse — no dependency on agentic-beacon's release surface, and no GitHub access required (which would break air-gapped). See Why not a published pre-commit hook? for the longer rationale. |
language: system |
Pre-commit invokes the system abc binary directly — no isolated env, no pip, no duplicate install. The contributor already has abc on PATH because they need it for abc warehouse connect, abc sync, etc. — so pre-commit reuses the same binary. Hook version automatically tracks the contributor's globally-installed version, so the lint at commit time is the same lint they run interactively. |
pass_filenames: false |
Without this, pre-commit appends staged filenames to entry, which would call abc warehouse lint . file1 file2 …. Suppressing keeps the invocation to the canonical abc warehouse lint .. |
always_run: true |
Runs the hook even when no warehouse-touching files are staged (the linter validates the dependency graph, not individual files — a delete in one place can break a requires: reference elsewhere). |
"abc: command not found" or "No such command 'lint'"¶
The hook assumes a recent agentic-beacon is on PATH. If a contributor sees either error, they need to (re)install agentic-beacon per the Installation page. The warehouse lint subcommand requires agentic-beacon >= 3.4.0.
The whole-tree gotcha¶
abc warehouse lint . validates the entire working tree, not just staged files. That means:
- If you stage a fix to
skills/foo/SKILL.mdwhileskills/bar/SKILL.mdalready has broken frontmatter on disk, the hook fails the commit forbartoo. - Usually what you want — the warehouse-wide invariant is what you're protecting.
- Escape hatch when you really need to commit through a known unrelated breakage:
If this trips contributors regularly, that's a signal main is broken — fix the underlying artifact instead of teaching everyone to skip the hook.
Why not a published pre-commit hook?¶
The canonical pre-commit pattern (used by ruff, black, mypy) is for the tool's source repo to publish a .pre-commit-hooks.yaml and have consumers reference it via repo: https://github.com/... + rev:. That pattern exists to let consumers run a tool without installing it.
agentic-beacon doesn't fit that premise: anyone touching a warehouse already has abc installed locally — they need it for abc warehouse connect, abc sync, abc adopt, and authoring skills. A published hook would either re-install the same binary inside pre-commit's pip env (duplication + version-skew risk) or add a github.com dependency for zero benefit (and break air-gapped warehouses). repo: local + language: system avoids both.
Skipping the hook on a single commit¶
When a hook fires on something you intentionally want to defer (rare but real — e.g. a mid-refactor checkpoint):
Use sparingly. Every --no-verify is a future "why did this slip through CI" investigation.
Pair with CI¶
The pre-commit hook is the local optimisation. The GitHub Actions workflow is the canonical enforcement that catches every contribution from every angle — including PRs from contributors who haven't run pre-commit install. Run both.