This is a documentation clone. The code in skills/ is not mine. It is a copy of
coleam00/skills at commit fb2e876. What I added is one
thing: a documentation page that explains how the hooks work and gives you the exact commands to
test each one.
The hooks pack comes from Cole Medin's video:
Watch This If Your Coding Agent is Ignoring Your Rules (You Need Hooks)
The argument in one line: a rule asks the agent to behave, a hook guarantees it. A rule is text the model reads and weighs against everything else in its context. A hook is code the harness runs on a lifecycle event, whether the model remembers it or not.
| Path | What it is |
|---|---|
hooks-explained.html |
The documentation page. Mechanism, exit codes, per-hook detail, 12 runnable tests, install warnings. |
skills/hooks/ |
The six hooks, as copy-in Python files. Cole's code. |
skills/.claude/skills/ |
The rest of Cole's skills pack, unmodified. |
| File | Event | What it does | Blocks? |
|---|---|---|---|
pre_tool_use_secrets.py |
PreToolUse | Refuses a route to a credential. Refuses rm -rf. |
Yes |
pre_tool_use_dependencies.py |
PreToolUse | Refuses an edit until the agent read the coupled files. | Yes |
post_tool_use_log.py |
PostToolUse | Appends one JSONL line per tool call. | No |
session_start_context.py |
SessionStart | Injects branch, uncommitted files, recent commits. | No |
stop_tests_must_pass.py |
Stop | Runs your tests. Red tests block the stop. | Yes |
stop_notify.py |
Stop | Desktop notification at the end of a turn. | No |
The mental model is short: pre = gate, post = log.
mkdir -p .claude/hooks
cp skills/hooks/*.py .claude/hooks/
cp skills/hooks/settings.json.example .claude/settings.json # merge if the file existsThen make two edits:
stop_tests_must_pass.pyline 25 — setTEST_COMMANDto your real test command.- Copy
dependencies.example.jsonto.claude/hooks/dependencies.json. Until that file exists the dependency hook allows everything, so it is safe to install first.
Full detail, plus the traps that cost people an afternoon, is on the
documentation page and in
skills/hooks/README.md.
A hook that always blocks and a hook that never blocks look identical until one fires wrong. Feed each one a payload and check the exit code:
# should BLOCK (exit 2)
echo '{"session_id":"t","cwd":".","tool_name":"Read","tool_input":{"file_path":".env"}}' \
| uv run .claude/hooks/pre_tool_use_secrets.py; echo "exit=$?"
# should ALLOW (exit 0)
echo '{"session_id":"t","cwd":".","tool_name":"Read","tool_input":{"file_path":"README.md"}}' \
| uv run .claude/hooks/pre_tool_use_secrets.py; echo "exit=$?"Exit 0 allows. Exit 2 blocks. Exit 1 does not block — it is a non-blocking error, the
opposite of every other CLI you use. That one catches people.
All 12 tests, one per behavior, are on the documentation page.
Hooks run real code, automatically, with your credentials, with no sandbox. Review a hook the way you review a CI script. Only run hooks you have read.
All hook and skill code: Cole Medin, from
coleam00/skills, under the licence in
skills/LICENSE. Go to the upstream repo for the current version — this clone is
pinned at fb2e876 and will not track later changes.
hooks-explained.html and this README are mine.