Claude Hooks for Enhanced Context
Claude Code supports a powerful hooks system that allows you to inject custom context and behavior at different stages of the conversation lifecycle. This guide provides ideas for leveraging hooks to improve your AI coding workflow.
What Are Claude Hooks?
Hooks are scripts that run at specific events:
- SessionStart - When a new session begins
- UserPromptSubmit - Before sending user input to Claude
- PostCompact - After compacting conversation history
- Clear - After clearing the conversation
Hook Basics
Hooks are configured in ~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "/path/to/your/hook-script.py",
"timeout": 5
}
]
}
]
}
}
Hook Input/Output:
- Hooks receive JSON via
stdinwith context data - Hooks can output text via
stdoutto inject into the conversation - Exit code 0 = success
Available Environment Variables:
CLAUDE_PROJECT_DIR- Current workspace pathCLAUDE_SESSION_ID- Current session identifier- Custom variables you set in settings.json
Practical Hook Ideas
1. Context Injection After /clear or /compact
When you clear or compact your conversation, you lose context. A hook can automatically re-inject important information:
Use case: After /clear, inject project structure, coding guidelines, or task context
Pattern:
#!/usr/bin/env python3
import json
import sys
hook_data = json.load(sys.stdin)
source = hook_data.get('source', '')
if source in ['clear', 'compact']:
# Inject your context here
print("Project: MyApp | Stack: Python/FastAPI | Current task: Refactoring auth")
sys.exit(0)
sys.exit(0)
2. JSON Cleaning Utility
LLM-generated JSON often has formatting issues. A cleaner hook can fix common problems:
Use case: Clean malformed JSON from tool outputs or AI responses
Features to implement:
- Remove comments (
//,/* */) - Fix trailing commas
- Replace smart quotes with regular quotes
- Remove zero-width characters
- Unescape quotes properly
- Fix unescaped quotes in strings
- Normalize line breaks
Example structure:
#!/usr/bin/env python3
import json
import re
import sys
def clean_json(data):
# Remove comments
data = re.sub(r'//.*?$|/\*.*?\*/|#.*?$', '', data, flags=re.MULTILINE)
# Fix trailing commas
data = re.sub(r',(\s*[\]}])', r'\1', data)
# Replace smart quotes
data = data.replace('"', '"').replace('"', '"')
data = data.replace(''', "'").replace(''', "'")
# Remove zero-width spaces
for char in ['\u200b', '\u200c', '\u200d', '\u2060', '\ufeff']:
data = data.replace(char, '')
return data
# Use this in your hook logic
3. Dynamic Context Based on Project
Different projects need different context. A smart hook can detect the project and inject relevant info:
Use case: Auto-detect project type and inject appropriate guidelines
Pattern:
import os
from pathlib import Path
project_dir = os.environ.get('CLAUDE_PROJECT_DIR', '')
if Path(project_dir, 'package.json').exists():
print("Node.js project detected. Using npm/pnpm conventions.")
elif Path(project_dir, 'requirements.txt').exists():
print("Python project detected. Using black/pytest conventions.")
elif Path(project_dir, 'Cargo.toml').exists():
print("Rust project detected. Using cargo conventions.")
4. Task Continuation After Context Loss
When context is cleared, ongoing tasks can be lost. A hook can preserve task state:
Use case: Remember what you were working on before /clear
Approach:
- On PreCompact/PreClear - Save current task/context to a file
- On SessionStart/PostClear - Reload and inject saved context
- Include: File references, decisions made, next steps
Conceptual flow:
User conversation → PreCompact hook → Save summary to ~/.claude/last_task.txt
User runs /clear → PostClear hook → Read ~/.claude/last_task.txt → Inject
5. Fun Engagement Hook
Keep conversations engaging with personality:
Use case: Start fresh conversations with a programming joke
Pattern:
This simple hook keeps the interaction light and fun after clearing context.
Hook Best Practices
Keep Hooks Fast
Hooks block the conversation flow. Keep execution under 5 seconds.
Recommendations:
- Cache when possible - Don't regenerate content on every hook call
- Use environment variables - Access
CLAUDE_PROJECT_DIR,CLAUDE_SESSION_ID - Log for debugging - Write to
~/.claude/hooks_debug.logfor troubleshooting - Handle errors gracefully - Always exit 0 even if hook logic fails
- Test incrementally - Start with simple hooks, add complexity gradually
- Avoid blocking operations - No network calls, heavy file I/O, or long computations
- Use proper shebang -
#!/usr/bin/env python3for portability
Complete Example: Minimal Context Injection
Here's a complete working example:
~/.claude/hooks/inject_context.py:
#!/usr/bin/env python3
import json
import sys
import os
from pathlib import Path
def main():
try:
hook_data = json.load(sys.stdin)
source = hook_data.get('source', '')
# Only inject after clear/compact
if source not in ['clear', 'compact']:
sys.exit(0)
# Get project info
project_dir = os.environ.get('CLAUDE_PROJECT_DIR', '')
project_name = Path(project_dir).name if project_dir else 'Unknown'
# Check if codebase is indexed
codebase_state = Path(project_dir, '.codebase', 'state.json')
indexed_status = "✅ Indexed" if codebase_state.exists() else "❌ Not indexed"
# Inject context
context = f"""
Project: {project_name}
Location: {project_dir}
Codebase: {indexed_status}
Remember to use semantic search for code references.
""".strip()
print(context)
sys.exit(0)
except Exception as e:
# Silent fail - don't break the conversation
sys.exit(0)
if __name__ == '__main__':
main()
Make it executable:
Configure in ~/.claude/settings.json:
{
"hooks": {
"PostCompact": [
{
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/inject_context.py",
"timeout": 5
}
]
}
]
}
}
Ideas for Advanced Hooks
Context Supervisor
A sophisticated system that maintains conversation continuity:
Concept: - Track conversation topics and decisions - Generate summaries before compact - Re-inject critical decisions after clear - Maintain task continuity across sessions
Benefits:
- Never lose important context
- Smooth transitions after /clear
- Automatic project context awareness
- Task continuity across multiple days
Implementation hints:
- Use PreCompact to analyze and save conversation state
- Store summaries in ~/.claude/supervisors/<project-name>/
- Use PostClear to reload relevant context
- Consider using an LLM to generate summaries (via API)
Smart File References
Automatically track and suggest relevant files:
Features:
- Track which files were discussed in conversation
- Maintain a "working set" of relevant files
- Auto-suggest related files based on current topic
- Persist file references across /clear
Use case:
Custom Prompts by Project
Load project-specific guidelines automatically:
Structure:
~/.claude/project-prompts/
├── my-api/
│ ├── coding-style.txt
│ ├── architecture.txt
│ └── conventions.txt
└── frontend-app/
├── component-rules.txt
└── state-management.txt
Hook logic:
project_name = Path(project_dir).name
prompts_dir = Path.home() / '.claude' / 'project-prompts' / project_name
if prompts_dir.exists():
for prompt_file in prompts_dir.glob('*.txt'):
with open(prompt_file) as f:
print(f.read())
Integration with Codebase Index
Make hooks aware of your indexing status:
Capabilities:
- Read .codebase/state.json for indexing status
- Warn if index is stale (last update > 1 hour ago)
- Inject collection name for semantic search tools
- Remind Claude to use semantic search instead of file browsing
Example:
state_file = Path(project_dir, '.codebase', 'state.json')
if state_file.exists():
state = json.loads(state_file.read_text())
collection = state.get('qdrantCollection', 'unknown')
total_vectors = state.get('qdrantStats', {}).get('totalVectors', 0)
print(f"Codebase indexed: {total_vectors} vectors in collection {collection}")
print("Use semantic_search tool for code queries.")
Debugging Hooks
If your hooks aren't working:
1. Check Claude Code Logs
# macOS
tail -f ~/Library/Logs/Claude/mcp*.log
# Linux
tail -f ~/.local/state/claude/logs/mcp*.log
# Custom hook log
tail -f ~/.claude/hooks_debug.log
2. Test Hook Manually
# Simulate hook input
echo '{"source": "clear", "session_id": "test"}' | ~/.claude/hooks/your-hook.py
# With project dir
CLAUDE_PROJECT_DIR=/path/to/project echo '{"source": "clear"}' | ~/.claude/hooks/your-hook.py
3. Verify Permissions
4. Check Timeout
If your hook takes longer than the configured timeout, increase it:
{
"type": "command",
"command": "~/.claude/hooks/slow-hook.py",
"timeout": 10 // Increase from default 5
}
5. Add Debug Logging
Add logging to your hooks for troubleshooting:
import logging
from pathlib import Path
log_file = Path.home() / '.claude' / 'hooks_debug.log'
logging.basicConfig(
filename=str(log_file),
level=logging.DEBUG,
format='[%(asctime)s] %(levelname)s: %(message)s'
)
logging.debug(f"Hook called with source: {source}")
logging.debug(f"Project dir: {project_dir}")
6. Common Issues
Hook not running:
- Check settings.json syntax (valid JSON)
- Verify path to hook script is absolute
- Ensure hook script is executable
Hook output not appearing: - Make sure you're printing to stdout (not stderr) - Check that exit code is 0 - Verify hook isn't timing out
Environment variables missing:
- CLAUDE_PROJECT_DIR only available in SessionStart and some other hooks
- Check Claude Code documentation for available variables per hook type
Hook Security Considerations
Security Best Practices
Hooks run with your user permissions. Be careful with external scripts.
Recommendations:
- Review hook scripts - Understand what they do before running
- Use absolute paths - Avoid relative paths that could be hijacked
- Validate input - Always validate JSON input from stdin
- Don't expose secrets - Never print API keys or sensitive data
- Sandbox if needed - Consider running untrusted hooks in containers
Ecosystem Integration
Hooks work seamlessly with the entire Codebase Index CLI ecosystem:
With Codebase Index CLI
- Read
.codebase/state.jsonfor indexing status - Check if collection exists before injecting context
- Remind Claude about available semantic search
With Semantic Search MCP
- Inject collection names for MCP tools
- Provide context about indexed commits
- Guide Claude to use appropriate search strategies
With Claude Code Chat UI
- Hooks complement the UI's status monitoring
- Both provide real-time indexer awareness
- Combine for complete workflow automation
Further Reading
Contributing Hook Examples
If you create useful hooks, consider sharing them with the community:
- Document what problem they solve
- Provide clear installation instructions
- Include example configuration
- Add debugging tips
This helps others learn and improves the ecosystem for everyone.