Vibe Coding for Production
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 PreToolUse hook that refuses any Read under secrets/,
  • a SessionEnd hook 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.

claude

What 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.js still works.
  • .claude/hooks.log shows at least one entry from on-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).

See also

On this page