Auto-format after editing
PostToolUse hook on Edit|Write. Detects the extension of the modified file and applies the appropriate formatter.
INPUT=$(cat)FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path')EXT="${FILE##*.}"case "$EXT" in ts|tsx) npx prettier --write "$FILE" 2>/dev/null ;; py) black "$FILE" 2>/dev/null ;; go) gofmt -w "$FILE" 2>/dev/null ;; rs) rustfmt "$FILE" 2>/dev/null ;;esacexit 0Configure as async: true — formatting is cosmetic and should not block Claude.
macOS notification on completion
Stop hook. Triggers a macOS system alert with a contextual sound (success, error, waiting).
INPUT=$(cat)MESSAGE=$(echo "$INPUT" | jq -r '.message // "Done"')osascript -e "display notification \"$MESSAGE\" \ with title \"Claude Code\""afplay /System/Library/Sounds/Hero.aiff &exit 0Security: block dangerous commands
PreToolUse hook on Bash. Intercepts destructive patterns before execution.
COMMAND=$(echo "$TOOL_INPUT" | jq -r '.command')DANGEROUS=("rm -rf /" "dd if=" "DROP DATABASE" "git push --force.*main")for pattern in "${DANGEROUS[@]}"; do if [[ "$COMMAND" == *"$pattern"* ]]; then echo "BLOCKED: $pattern" >&2 exit 2 fidoneexit 0Exit code 2 blocks the action and surfaces the stderr message to Claude.
Git auto-stage after editing
PostToolUse hook on Edit|Write. Automatically prepares modified files for the next commit.
INPUT=$(cat)FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')[[ -z "$FILE" || "$FILE" == "null" ]] && exit 0git add "$FILE" 2>/dev/nullexit 0RTK auto-wrapper
PreToolUse hook on Bash. Detects commands optimizable by RTK and informs Claude of the available alternative.
The logic: if the command starts with git log, cargo test, pnpm list or verbose equivalents, suggest rtk <command> via stdout before letting it through.
Log all executed commands
PostToolUse hook on Bash. Useful for auditing and debugging long sessions.
COMMAND=$(cat | jq -r '.tool_input.command // empty')echo "$(date -u +%FT%T) | $COMMAND" \ >> ~/.claude/logs/commands.logexit 0Dispatcher pattern: a single entry point
Rather than multiplying entries in settings.json, a dispatch.sh script routes to specialized handlers based on the file or tool. Result: a single Edit|Write|Bash matcher in the config, with separately maintainable handlers in .claude/hooks/handlers/.
Installation checklist
chmod +x .claude/hooks/my-hook.sh # Required# Test manually before activating:echo '{"tool_name":"Edit","tool_input":{"file_path":"test.ts"}}' \ | .claude/hooks/my-hook.shEnter your email to read the full card and get the complete PDF bundle.
All content is free and open-source. We just ask for your email.