Skip to content

Back to the catalog

media.licdn.comwriteup

https://media.licdn.com/dms/document/media/v2/D4D1FAQGtvK5tUnN0EQ/feedshare-document-url-metadata-scrapper-pdf/B4DaEgDW2kKUA4-/0/1791539116721?e=1792170000&v=beta&t=6lNyWkJparrDrHu4bE6lW0AGmrORP_M9VmFbuMKjk98

A LinkedIn-hosted PDF guide to Claude Code automation. It explains hook configuration in .claude/settings.json (matchers, JSON stdin payloads, exit code 2 to block) and the hook events: PreToolUse, PostToolUse, Notification, Stop, SubagentStop, SessionStart, UserPromptSubmit and PreCompact. Worked examples include sound and TTS alerts with pyttsx3, a regex guard against rm -rf and other dangerous Bash commands, TDD enforcement, auto-formatting with black, ruff and prettier, and session context loading. It adds troubleshooting and a cheat sheet, and its table of contents lists sections on multi-agent observability, slash commands, MCP tools, sub-agents and professional development patterns. The later sections are cut off in the fetched text. It is useful as deterministic guardrails and automation for a non-deterministic coding agent.

TL;DR Practical Claude Code guide: hooks with working scripts and configs, plus coverage of subagents, MCP tools and custom slash commands.
Also seen from another angleπŸ›‘οΈ Security β†’
Document

What it claims

This is a tutorial guide, not a spec. Its central idea is that hooks add deterministic guardrails to Claude Code. A hook is a shell command attached to a lifecycle event. It receives a JSON payload on stdin, and its exit code decides whether a tool call goes ahead. The useful material is the event contract (which events can block and which fields each one receives) and a set of copy-pasteable scripts.

How it works

Config locations

  • Project hooks go in .claude/settings.json.
  • User-global hooks go in ~/.claude/settings.json.
  • Settings load at startup, so you must restart Claude Code after editing them.

Matchers

  • "" matches all tools.
  • A tool name such as "Bash" matches that tool only.
  • Regex alternation works, for example "Edit|MultiEdit|Write".

Exit codes

  • 0 is normal operation.
  • 2 blocks the action, and stderr is fed back to Claude.
  • The guide warns that an accidental non-zero exit can block unintentionally. It recommends wrapping logic in try/except and always ending with sys.exit(0).

Events, as listed in the cheat sheet:

EventCan block?Key fields
PreToolUseYes (exit 2)tool_name, tool_input
PostToolUseNotool_response (also tool_name, tool_input)
SubagentStopYes (exit 2)stop_hook_active
StopNotranscript_path
NotificationNomessage
SessionStartNosession_id, source
UserPromptSubmitNo (described as "modify user prompts")prompt
PreCompactNocut off (trig…)

Every payload carries hook_event_name.

Per-hook options

  • "timeout": 5 limits how long a hook may run.
  • Appending & to the command runs a non-critical hook in the background.
  • Hooks are synchronous, so the guide says to keep them fast.

Writing context into the session The SessionStart script prints its output to stdout. That output is git status, the last 5 commits, and up to 500 characters of TODO: grep results.

How to use it

Log the raw payloads first, before writing any logic:

{"hooks": {"PreToolUse": [{"matcher": "", "hooks": [{"type": "command", "command": "jq '.' >> .claude/hooks/log.jsonl"}]}]}}

Format edited files after each edit. This relies on a $CLAUDE_FILE_PATHS environment variable:

if [[ "$CLAUDE_FILE_PATHS" =~ \.(py)$ ]]; then black $CLAUDE_FILE_PATHS && ruff check --fix $CLAUDE_FILE_PATHS; fi

Other practical advice from the guide:

  • Run hook scripts that have dependencies with uv run my_script.py.
  • Use absolute script paths.
  • Make scripts executable with chmod +x .claude/hooks/*.py.
  • Validate your settings file with jq '.' .claude/settings.json.

The advanced Bash guard (PreToolUse, matcher Bash) blocks five pattern families:

  • rm -[rf]
  • chmod 777
  • curl … | sh
  • npm install … --global
  • docker … --privileged

It emits a JSON error with the risks and a suggestion on stderr, then exits with code 2.

Limits

  • Truncated text. The fetched text cuts off midway through the TDD example and at the PreCompact row. Sections 9–16 are absent: workflows, security, multi-agent observability, slash commands, MCP, sub-agents and patterns.
  • Guard over-matches. In the advanced guard, rm\s+-[^\s]*[rf] matches plain rm -f as well as rm -rf.
  • Guard can be bypassed. Regex guards of this kind can be sidestepped by aliases, variables or other interpreters. The guide does not discuss this.
  • Unverified details. Several details are the guide's own assertions and are not sourced here: the "can block" column, $CLAUDE_FILE_PATHS and the timeout field. Check them against current Claude Code documentation before relying on a hook as a security control.

Organisations named here

  • Astral
  • Anthropic
  • Claude Code
  • Cursor

Technologies named here

  • Claude Code
  • Claude Code hooks
  • MCP tools
  • Custom slash commands
  • Subagents
  • pyttsx3
  • uv
  • jq
  • black
  • ruff
  • prettier
  • tsc
  • Cursor
  • Model Context Protocol
  • TypeScript
  • Python

Techniques named here

  • PreToolUse blocking hook
  • Payload logging for debugging
  • Formatter hooks on PostToolUse
  • Session context loading
  • TDD enforcement hook
  • Voice and sound notifications