Add comprehensive development intelligence system that tracks: - Development sessions with automatic start/stop - Full conversation history with semantic search - Tool usage and file operation analytics - Think time and engagement analysis - Git activity correlation - Learning pattern recognition - Productivity insights and metrics Features: - FastAPI backend with SQLite database - Modern web dashboard with interactive charts - Claude Code hook integration for automatic tracking - Comprehensive test suite with 100+ tests - Complete API documentation (OpenAPI/Swagger) - Privacy-first design with local data storage 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
10 KiB
Claude Code Hook Setup Guide
This guide explains how to configure Claude Code hooks to automatically track your development sessions with the Project Tracker API.
Overview
Claude Code hooks are shell commands that execute in response to specific events. We'll configure hooks to send HTTP requests to our tracking API whenever key development events occur.
Prerequisites
- Claude Code Project Tracker server running on
http://localhost:8000
- curl or httpie available in your shell
- jq for JSON processing (recommended)
Hook Configuration Location
Claude Code hooks are configured in your settings file:
- Linux/macOS:
~/.config/claude-code/settings.json
- Windows:
%APPDATA%\claude-code\settings.json
Complete Hook Configuration
Add this hooks section to your Claude Code settings:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"command": "curl -s -X POST http://localhost:8000/api/session/start -H 'Content-Type: application/json' -d '{\"session_type\":\"startup\",\"working_directory\":\"'\"$PWD\"'\",\"git_branch\":\"'$(git branch --show-current 2>/dev/null || echo \"unknown\")'\",\"git_repo\":\"'$(git config --get remote.origin.url 2>/dev/null || echo \"null\")'\",\"environment\":{\"pwd\":\"'\"$PWD\"'\",\"user\":\"'\"$USER\"'\",\"timestamp\":\"'$(date -Iseconds)'\"}}' > /dev/null 2>&1 &"
},
{
"matcher": "resume",
"command": "curl -s -X POST http://localhost:8000/api/session/start -H 'Content-Type: application/json' -d '{\"session_type\":\"resume\",\"working_directory\":\"'\"$PWD\"'\",\"git_branch\":\"'$(git branch --show-current 2>/dev/null || echo \"unknown\")'\",\"git_repo\":\"'$(git config --get remote.origin.url 2>/dev/null || echo \"null\")'\",\"environment\":{\"pwd\":\"'\"$PWD\"'\",\"user\":\"'\"$USER\"'\",\"timestamp\":\"'$(date -Iseconds)'\"}}' > /dev/null 2>&1 &"
},
{
"matcher": "clear",
"command": "curl -s -X POST http://localhost:8000/api/session/start -H 'Content-Type: application/json' -d '{\"session_type\":\"clear\",\"working_directory\":\"'\"$PWD\"'\",\"git_branch\":\"'$(git branch --show-current 2>/dev/null || echo \"unknown\")'\",\"git_repo\":\"'$(git config --get remote.origin.url 2>/dev/null || echo \"null\")'\",\"environment\":{\"pwd\":\"'\"$PWD\"'\",\"user\":\"'\"$USER\"'\",\"timestamp\":\"'$(date -Iseconds)'\"}}' > /dev/null 2>&1 &"
}
],
"UserPromptSubmit": [
{
"command": "echo '{\"session_id\":1,\"timestamp\":\"'$(date -Iseconds)'\",\"user_prompt\":\"'\"$CLAUDE_USER_PROMPT\"'\",\"exchange_type\":\"user_prompt\"}' | curl -s -X POST http://localhost:8000/api/conversation -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 &"
}
],
"Notification": [
{
"command": "curl -s -X POST http://localhost:8000/api/waiting/start -H 'Content-Type: application/json' -d '{\"session_id\":1,\"timestamp\":\"'$(date -Iseconds)'\",\"context_before\":\"Claude is waiting for input\"}' > /dev/null 2>&1 &"
}
],
"PostToolUse": [
{
"matcher": "Edit",
"command": "echo '{\"session_id\":1,\"tool_name\":\"Edit\",\"action\":\"file_edit\",\"file_path\":\"'\"$CLAUDE_TOOL_FILE_PATH\"'\",\"timestamp\":\"'$(date -Iseconds)'\",\"metadata\":{\"success\":true},\"success\":true}' | curl -s -X POST http://localhost:8000/api/activity -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 &"
},
{
"matcher": "Write",
"command": "echo '{\"session_id\":1,\"tool_name\":\"Write\",\"action\":\"file_write\",\"file_path\":\"'\"$CLAUDE_TOOL_FILE_PATH\"'\",\"timestamp\":\"'$(date -Iseconds)'\",\"metadata\":{\"success\":true},\"success\":true}' | curl -s -X POST http://localhost:8000/api/activity -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 &"
},
{
"matcher": "Read",
"command": "echo '{\"session_id\":1,\"tool_name\":\"Read\",\"action\":\"file_read\",\"file_path\":\"'\"$CLAUDE_TOOL_FILE_PATH\"'\",\"timestamp\":\"'$(date -Iseconds)'\",\"metadata\":{\"success\":true},\"success\":true}' | curl -s -X POST http://localhost:8000/api/activity -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 &"
},
{
"matcher": "Bash",
"command": "echo '{\"session_id\":1,\"tool_name\":\"Bash\",\"action\":\"command_execution\",\"timestamp\":\"'$(date -Iseconds)'\",\"metadata\":{\"command\":\"'\"$CLAUDE_BASH_COMMAND\"'\",\"success\":true},\"success\":true}' | curl -s -X POST http://localhost:8000/api/activity -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 &"
},
{
"matcher": "Grep",
"command": "echo '{\"session_id\":1,\"tool_name\":\"Grep\",\"action\":\"search\",\"timestamp\":\"'$(date -Iseconds)'\",\"metadata\":{\"pattern\":\"'\"$CLAUDE_GREP_PATTERN\"'\",\"success\":true},\"success\":true}' | curl -s -X POST http://localhost:8000/api/activity -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 &"
},
{
"matcher": "Glob",
"command": "echo '{\"session_id\":1,\"tool_name\":\"Glob\",\"action\":\"file_search\",\"timestamp\":\"'$(date -Iseconds)'\",\"metadata\":{\"pattern\":\"'\"$CLAUDE_GLOB_PATTERN\"'\",\"success\":true},\"success\":true}' | curl -s -X POST http://localhost:8000/api/activity -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 &"
},
{
"matcher": "Task",
"command": "echo '{\"session_id\":1,\"tool_name\":\"Task\",\"action\":\"subagent_call\",\"timestamp\":\"'$(date -Iseconds)'\",\"metadata\":{\"task_type\":\"'\"$CLAUDE_TASK_TYPE\"'\",\"success\":true},\"success\":true}' | curl -s -X POST http://localhost:8000/api/activity -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 &"
}
],
"Stop": [
{
"command": "echo '{\"session_id\":1,\"timestamp\":\"'$(date -Iseconds)'\",\"claude_response\":\"Response completed\",\"exchange_type\":\"claude_response\"}' | curl -s -X POST http://localhost:8000/api/conversation -H 'Content-Type: application/json' -d @- > /dev/null 2>&1 && curl -s -X POST http://localhost:8000/api/waiting/end -H 'Content-Type: application/json' -d '{\"session_id\":1,\"timestamp\":\"'$(date -Iseconds)'\"}' > /dev/null 2>&1 &"
}
]
}
}
Simplified Hook Configuration
For easier setup, you can use our provided configuration file:
# Copy the hook configuration to Claude Code settings
cp config/claude-hooks.json ~/.config/claude-code/
Hook Details
SessionStart Hooks
Triggered when starting Claude Code or resuming a session:
- startup: Fresh start of Claude Code
- resume: Resuming after --resume flag
- clear: Starting after clearing history
Data Captured:
- Working directory
- Git branch and repository
- System environment info
- Session type
UserPromptSubmit Hook
Triggered when you submit a prompt to Claude:
Data Captured:
- Your input message
- Timestamp
- Session context
Notification Hook
Triggered when Claude is waiting for input:
Data Captured:
- Wait start time
- Context before waiting
PostToolUse Hooks
Triggered after successful tool execution:
Tools Tracked:
- Edit/Write: File modifications
- Read: File examinations
- Bash: Command executions
- Grep/Glob: Search operations
- Task: Subagent usage
Data Captured:
- Tool name and action
- Target files
- Success/failure status
- Tool-specific metadata
Stop Hook
Triggered when Claude finishes responding:
Data Captured:
- Response completion
- End of waiting period
- Session activity summary
Testing Hook Configuration
-
Start the tracker server:
python main.py
-
Verify hooks are working:
# Check server logs for incoming requests tail -f tracker.log # Test a simple operation in Claude Code # You should see API calls in the logs
-
Manual hook testing:
# Test session start hook curl -X POST http://localhost:8000/api/session/start \ -H 'Content-Type: application/json' \ -d '{"session_type":"startup","working_directory":"'$(pwd)'"}'
Environment Variables
The hooks can use these Claude Code environment variables:
$CLAUDE_USER_PROMPT
- User's input message$CLAUDE_TOOL_FILE_PATH
- File path for file operations$CLAUDE_BASH_COMMAND
- Bash command being executed$CLAUDE_GREP_PATTERN
- Search pattern for Grep$CLAUDE_GLOB_PATTERN
- File pattern for Glob$CLAUDE_TASK_TYPE
- Type of Task/subagent
Troubleshooting
Hooks Not Firing
-
Check Claude Code settings syntax:
# Validate JSON syntax python -m json.tool ~/.config/claude-code/settings.json
-
Verify tracker server is running:
curl http://localhost:8000/api/projects
-
Check hook command syntax:
# Test commands manually in shell echo "Testing hook command..."
Missing Data
- Session ID issues: The static
session_id: 1
in examples needs dynamic generation - JSON escaping: Special characters in prompts/paths may break JSON
- Network issues: Hooks may fail if server is unreachable
Performance Impact
- Hooks run asynchronously (
&
at end of commands) - Failed hook calls don't interrupt Claude Code operation
- Network timeouts are handled gracefully
Advanced Configuration
Dynamic Session IDs
For production use, implement session ID management:
# Store session ID in temp file
CLAUDE_SESSION_FILE="/tmp/claude-session-id"
# In SessionStart hook:
SESSION_ID=$(curl -s ... | jq -r '.session_id')
echo $SESSION_ID > $CLAUDE_SESSION_FILE
# In other hooks:
SESSION_ID=$(cat $CLAUDE_SESSION_FILE 2>/dev/null || echo "1")
Conditional Hook Execution
Skip tracking for certain directories:
# Only track in specific directories
if [[ "$PWD" =~ "/projects/" ]]; then
curl -X POST ...
fi
Error Handling
Add error logging to hooks:
curl ... 2>> ~/claude-tracker-errors.log || echo "Hook failed: $(date)" >> ~/claude-tracker-errors.log
Security Considerations
- Hooks execute with your shell privileges
- API calls are made to localhost only
- No sensitive data is transmitted externally
- Hook commands are logged in shell history
Next Steps
After setting up hooks:
- Start using Claude Code normally
- Check the web dashboard at http://localhost:8000
- Review captured data and analytics
- Adjust hook configuration as needed
For detailed API documentation, see API Specification.