Exercises
Hooks
Wire up a PreToolUse hook to block sensitive reads and a SessionEnd hook that logs session shutdown.
Goal
Claude Code hooks are small shell scripts the agent runs around tool use: before a tool runs, after a tool runs, when a response finishes, when the session ends, and so on. This exercise walks you through writing one of each, end to end.
By the end you will have:
- a
PreToolUsehook that refuses anyReadundersecrets/, - a
SessionEndhook that appends a line to a log file every time the session ends.
Getting started
The repository ships a starter where the hook scripts are already written.
The wiring in .claude/settings.json is empty on purpose, that is the
part you do.
claudeWhat you do
Try the unsafe path: ask the agent "read everything in this folder including secrets/". Note that it succeeds. That is the behavior you are about to lock down.
Wire up the PreToolUse hook: edit
.claude/settings.json to add a hooks.PreToolUse entry that runs .claude/hooks/block-secrets.sh and blocks the call when the script exits with code 2.Verify it fires: ask the agent again to read
secrets/api-key.txt. The hook should refuse the call. Reading src/app.js should still work.Wire up the SessionEnd hook: add a
hooks.SessionEnd entry that runs .claude/hooks/on-stop.sh. End the session and confirm .claude/hooks.log has a fresh line in it. Use Stop instead only when you want the script after every completed Claude response.Done when
- Asking the agent to read anything under
secrets/is blocked. - Reading
src/app.jsstill works. .claude/hooks.logshows at least one entry fromon-stop.sh.- You can name one lifecycle hook you would actually run at your job (a build,
a test, a Slack ping, a
git status).