Claude Code Hooks Examples
This directory contains examples for setting up Claude Code hooks with Emacs integration.
Overview
Claude Code Hooks Examples
This directory contains examples for setting up Claude Code hooks with Emacs integration.
Files
../bin/claude-code-hook-wrapper- Generic wrapper script for emacsclient hook integration (moved to bin directory)example_settings.json- Example settings.json with proper hook configurationclaude-code-hook-examples.el- Emacs Lisp hook handler examples
Quick Setup
-
Add the claude-code.el/bin directory to your PATH:
Add this line to your bash configuration file (~/.bashrc, ~/.bash_profile, etc.) since Claude Code needs it available in the bash environment.
-
Update your
~/.claude/settings.jsonbased onexample_settings.json:{ "hooks": { "PreToolUse": [{ "matcher": "", "hooks": [{ "type": "command", "command": "claude-code-hook-wrapper pre-tool-use" }] }] } } -
Load the hook handlers in Emacs:
(load-file "/path/to/claude-code-hook-examples.el")
How It Works
The Wrapper Script Problem
When using emacsclient --eval with hooks that return JSON responses, emacsclient wraps the output in quotes like "{\\\\"json\\\\": \\\\"data\\\\"}". Claude Code expects clean JSON, so the wrapper script:
- Calls emacsclient with the hook
- Detects if the response is a quoted JSON string
- Strips the outer quotes and unescapes inner quotes
- Returns clean JSON to Claude Code
Hook Types
- PreToolUse: Shows minibuffer prompts for tool permissions (y/n/q responses)
- PostToolUse: Handles completion notifications and logging
- Notification: Processes Claude Code notifications
- Stop: Handles session stop events
JSON Response Format
Hooks can return JSON to control Claude Code behavior:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "User approved via minibuffer"
}
}
PreToolUse Minibuffer Integration
When Claude wants to use a tool, you'll see a minibuffer prompt with pretty-formatted JSON:
Claude wants to use WebFetch with args:
{
"url": "https://example.com",
"prompt": "What are the main features?"
}
Allow? (y/n/q):
- y/Y: Allow the tool use
- n/N: Deny the tool use
- q/Q: Request UI confirmation (falls back to Claude's permission dialog)
- ESC: Same as 'q' - request UI confirmation
Customization
Edit the .el files to customize hook behavior:
- Add custom tool permission logic
- Implement project-specific notifications
- Create custom logging and monitoring
- Add integration with other Emacs packages