Initial commit: Claude Code Monitor v1.0.0

Complete real-time monitoring dashboard for Claude Code

Features:
- FastAPI backend with REST API and WebSocket
- React + TypeScript frontend with dark theme
- SQLite database for event storage
- 6 hook scripts for Claude Code events
- Docker deployment setup
- Real-time event tracking and statistics
- Event filtering (ALL, TOOLS, AGENTS, PROMPTS, SESSIONS)
- Connection status indicator
- Reset stats functionality

Tech Stack:
- Backend: Python 3.11, FastAPI, SQLAlchemy, WebSockets
- Frontend: React 18, TypeScript, Vite
- Database: SQLite
- Deployment: Docker, Docker Compose

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
felix.zoesch
2025-12-15 09:49:06 +01:00
commit f6ef7ff5d3
48 changed files with 3375 additions and 0 deletions

46
.claude/hooks/post_tool_use.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
# Post Tool Use Hook for Claude Code Monitor
# Captures tool execution events and sends them to the backend
# Read JSON from stdin
INPUT=$(cat)
# Extract fields using jq
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // null')
TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // {}')
TOOL_OUTPUT=$(echo "$INPUT" | jq -r '.tool_response // null')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp // (now | tonumber)')
SUCCESS=$(echo "$INPUT" | jq -r '.success // true')
# Build payload for backend
PAYLOAD=$(jq -n \
--arg session_id "$SESSION_ID" \
--arg event_type "PostToolUse" \
--arg tool_name "$TOOL_NAME" \
--argjson tool_input "$TOOL_INPUT" \
--arg tool_output "$TOOL_OUTPUT" \
--arg timestamp "$TIMESTAMP" \
--argjson success "$SUCCESS" \
'{
session_id: $session_id,
event_type: $event_type,
tool_name: $tool_name,
tool_input: $tool_input,
tool_output: $tool_output,
timestamp: ($timestamp | tonumber),
success: $success
}')
# Send to backend API (asynchronous, non-blocking)
curl -X POST \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
http://localhost:8000/api/events \
--max-time 2 \
--silent \
--show-error \
> /dev/null 2>&1 &
# Exit immediately (don't wait for curl)
exit 0

40
.claude/hooks/pre_tool_use.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
# Pre Tool Use Hook for Claude Code Monitor
# Captures tool preparation events before execution
# Read JSON from stdin
INPUT=$(cat)
# Extract fields using jq
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // null')
TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // {}')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp // (now | tonumber)')
# Build payload for backend
PAYLOAD=$(jq -n \
--arg session_id "$SESSION_ID" \
--arg event_type "PreToolUse" \
--arg tool_name "$TOOL_NAME" \
--argjson tool_input "$TOOL_INPUT" \
--arg timestamp "$TIMESTAMP" \
'{
session_id: $session_id,
event_type: $event_type,
tool_name: $tool_name,
tool_input: $tool_input,
timestamp: ($timestamp | tonumber)
}')
# Send to backend API (asynchronous, non-blocking)
curl -X POST \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
http://localhost:8000/api/events \
--max-time 2 \
--silent \
--show-error \
> /dev/null 2>&1 &
# Exit immediately (don't wait for curl)
exit 0

34
.claude/hooks/session_end.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# Session End Hook for Claude Code Monitor
# Captures session termination events
# Read JSON from stdin
INPUT=$(cat)
# Extract fields using jq
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp // (now | tonumber)')
# Build payload for backend
PAYLOAD=$(jq -n \
--arg session_id "$SESSION_ID" \
--arg event_type "SessionEnd" \
--arg timestamp "$TIMESTAMP" \
'{
session_id: $session_id,
event_type: $event_type,
timestamp: ($timestamp | tonumber)
}')
# Send to backend API (asynchronous, non-blocking)
curl -X POST \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
http://localhost:8000/api/events \
--max-time 2 \
--silent \
--show-error \
> /dev/null 2>&1 &
# Exit immediately (don't wait for curl)
exit 0

34
.claude/hooks/session_start.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# Session Start Hook for Claude Code Monitor
# Captures session initialization events
# Read JSON from stdin
INPUT=$(cat)
# Extract fields using jq
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp // (now | tonumber)')
# Build payload for backend
PAYLOAD=$(jq -n \
--arg session_id "$SESSION_ID" \
--arg event_type "SessionStart" \
--arg timestamp "$TIMESTAMP" \
'{
session_id: $session_id,
event_type: $event_type,
timestamp: ($timestamp | tonumber)
}')
# Send to backend API (asynchronous, non-blocking)
curl -X POST \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
http://localhost:8000/api/events \
--max-time 2 \
--silent \
--show-error \
> /dev/null 2>&1 &
# Exit immediately (don't wait for curl)
exit 0

37
.claude/hooks/subagent_stop.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# Subagent Stop Hook for Claude Code Monitor
# Captures agent completion events
# Read JSON from stdin
INPUT=$(cat)
# Extract fields using jq
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
AGENT_TYPE=$(echo "$INPUT" | jq -r '.agent_type // "unknown"')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp // (now | tonumber)')
# Build payload for backend
PAYLOAD=$(jq -n \
--arg session_id "$SESSION_ID" \
--arg event_type "SubagentStop" \
--arg agent_type "$AGENT_TYPE" \
--arg timestamp "$TIMESTAMP" \
'{
session_id: $session_id,
event_type: $event_type,
description: ("Agent completed: " + $agent_type),
timestamp: ($timestamp | tonumber)
}')
# Send to backend API (asynchronous, non-blocking)
curl -X POST \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
http://localhost:8000/api/events \
--max-time 2 \
--silent \
--show-error \
> /dev/null 2>&1 &
# Exit immediately (don't wait for curl)
exit 0

37
.claude/hooks/user_prompt.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# User Prompt Submit Hook for Claude Code Monitor
# Captures user prompt submission events
# Read JSON from stdin
INPUT=$(cat)
# Extract fields using jq
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
PROMPT_LENGTH=$(echo "$INPUT" | jq -r '.prompt_length // 0')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp // (now | tonumber)')
# Build payload for backend
PAYLOAD=$(jq -n \
--arg session_id "$SESSION_ID" \
--arg event_type "UserPromptSubmit" \
--arg prompt_length "$PROMPT_LENGTH" \
--arg timestamp "$TIMESTAMP" \
'{
session_id: $session_id,
event_type: $event_type,
description: ("User submitted prompt (" + $prompt_length + " chars)"),
timestamp: ($timestamp | tonumber)
}')
# Send to backend API (asynchronous, non-blocking)
curl -X POST \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
http://localhost:8000/api/events \
--max-time 2 \
--silent \
--show-error \
> /dev/null 2>&1 &
# Exit immediately (don't wait for curl)
exit 0