# hooks-development > Claude Code hooks development guide covering all 10 hook events lifecycle, PostToolUse visibility patterns, PreToolUse guards, Stop hook schema, and debugging. Use when creating hooks, troubleshooting hook output, understanding hook lifecycle, or when user mentions decision block, hook JSON output, stop hook, or Claude Code hooks. - Author: semantic-release-bot - Repository: terrylica/cc-skills - Version: 20260122003203 - Stars: 15 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/terrylica/cc-skills - Web: https://mule.run/skillshub/@@terrylica/cc-skills~hooks-development:20260122003203 --- --- name: hooks-development description: Claude Code hooks development guide covering all 10 hook events lifecycle, PostToolUse visibility patterns, PreToolUse guards, Stop hook schema, and debugging. Use when creating hooks, troubleshooting hook output, understanding hook lifecycle, or when user mentions decision block, hook JSON output, stop hook, or Claude Code hooks. --- # Hooks Development Guide for developing Claude Code hooks with proper output visibility patterns. ## When to Use This Skill - Creating a new PostToolUse or PreToolUse hook - Hook output is not visible to Claude (most common issue) - User asks about `decision: block` pattern - Debugging why hook messages don't appear - User mentions "Claude Code hooks" or "hook visibility" --- ## Quick Reference: Visibility Patterns **Critical insight**: PostToolUse hook stdout is only visible to Claude when JSON contains `"decision": "block"`. | Output Format | Claude Visibility | | ------------------------------ | ----------------- | | Plain text | Not visible | | JSON without `decision: block` | Not visible | | JSON with `decision: block` | Visible | **Exit code behavior**: | Exit Code | stdout Behavior | Claude Visibility | | --------- | --------------------------------------- | ----------------------------- | | **0** | JSON parsed, shown in verbose mode only | Only if `"decision": "block"` | | **2** | Ignored, uses stderr instead | stderr shown to Claude | | **Other** | stderr shown in verbose mode | Not shown to Claude | --- ## Minimal Working Pattern ```bash /usr/bin/env bash << 'SKILL_SCRIPT_EOF' #!/usr/bin/env bash set -euo pipefail # Read hook payload from stdin PAYLOAD=$(cat) FILE_PATH=$(echo "$PAYLOAD" | jq -r '.tool_input.file_path // empty') [[ -z "$FILE_PATH" ]] && exit 0 # Your condition here if [[ condition_met ]]; then jq -n \ --arg reason "[HOOK] Your message to Claude" \ '{decision: "block", reason: $reason}' fi exit 0 SKILL_SCRIPT_EOF ``` **Key points**: 1. Use `jq -n` to generate valid JSON 2. Include `"decision": "block"` for visibility 3. Exit with code 0 4. The "blocking error" label is cosmetic - operation continues --- ## TodoWrite Templates ### Creating a PostToolUse Hook ```markdown 1. [pending] Create hook script with shebang and set -euo pipefail 2. [pending] Parse PAYLOAD from stdin with jq 3. [pending] Add condition check for when to trigger 4. [pending] Output JSON with decision:block pattern 5. [pending] Register hook in hooks.json with matcher 6. [pending] Test by editing a matching file 7. [pending] Verify Claude sees the message in system-reminder ``` ### Debugging Invisible Hook Output ```markdown 1. [pending] Verify hook executes (add debug log to /tmp) 2. [pending] Check JSON format is valid (pipe to jq .) 3. [pending] Confirm decision:block is present in output 4. [pending] Verify exit code is 0 5. [pending] Check hooks.json matcher pattern 6. [pending] Restart Claude Code session ``` --- ## Reference Documentation - [Lifecycle Reference](./references/lifecycle-reference.md) - All 10 hook events, diagrams, use cases, configuration pitfalls - [Visibility Patterns](./references/visibility-patterns.md) - Full exit code and JSON schema details - [Hook Templates](./references/hook-templates.md) - Copy-paste templates for common patterns - [Debugging Guide](./references/debugging-guide.md) - Troubleshooting invisible output --- ## Post-Change Checklist (Self-Evolution) When this skill is updated: - [ ] Update [evolution-log.md](./references/evolution-log.md) with discovery - [ ] Verify code examples still work - [ ] Check if ADR needs updating: [PostToolUse Hook Visibility ADR](../../../../docs/adr/2025-12-17-posttooluse-hook-visibility.md) --- ## Related Resources - [ADR: PostToolUse Hook Visibility](../../../../docs/adr/2025-12-17-posttooluse-hook-visibility.md) - [GitHub Issue #3983](https://github.com/anthropics/claude-code/issues/3983) - Original bug report - [Claude Code Hooks Reference](https://code.claude.com/docs/en/hooks) - Official documentation