# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Claude Code Monitor is a real-time monitoring dashboard for tracking Claude Code activity through a hook-based event capture system. It consists of a FastAPI backend, React/TypeScript frontend, and shell scripts that integrate with Claude Code's hook system. ## Architecture ### Event Flow ``` Claude Code → Hook Scripts (.claude/hooks/*.sh) → FastAPI Backend (Python/SQLAlchemy/WebSockets) → SQLite Database → WebSocket broadcast → React Frontend ``` ### Key Components **Backend** (`backend/app/`): - `main.py` - FastAPI application entry point with CORS, routers, health checks - `database.py` - SQLAlchemy models (Event, Session, Statistics, ToolUsage), database initialization - `websocket.py` - ConnectionManager class for broadcasting events to connected clients - `crud.py` - Database CRUD operations and statistics calculations - `schemas.py` - Pydantic models for request/response validation - `api/events.py` - Event creation and listing endpoints - `api/statistics.py` - Statistics aggregation endpoints - `api/websocket_endpoint.py` - WebSocket connection handling **Frontend** (`frontend/src/`): - `App.tsx` - Main component orchestrating WebSocket, events, statistics, and filtering - `hooks/useWebSocket.ts` - WebSocket connection management with auto-reconnect - `hooks/useEvents.ts` - Event list management with pagination - `hooks/useStatistics.ts` - Statistics state management - `types/index.ts` - TypeScript type definitions and filter mappings - `components/` - React components for UI (Header, EventFeed, StatisticsCards, etc.) **Hook Scripts** (`.claude/hooks/`): Six bash scripts that capture Claude Code events and POST JSON to the backend via curl: - `pre_tool_use.sh` / `post_tool_use.sh` - Tool execution tracking - `session_start.sh` / `session_end.sh` - Session lifecycle - `subagent_stop.sh` - Agent completion tracking - `user_prompt.sh` - User prompt submission tracking All hooks use `jq` for JSON parsing and send data asynchronously (non-blocking) to `http://localhost:8000/api/events`. ## Common Commands ### Development **Backend** (requires Python 3.11+): ```bash cd backend python -m venv venv source venv/bin/activate pip install -r requirements.txt python -m app.main # Runs on http://localhost:8000 ``` **Frontend** (requires Node.js): ```bash cd frontend npm install npm run dev # Runs on http://localhost:5173 npm run build # Production build npm run lint # ESLint check ``` ### Docker Deployment ```bash # Build and start both services docker-compose up --build # Start in detached mode docker-compose up -d # View logs docker-compose logs -f backend docker-compose logs -f frontend # Stop services docker-compose down # Reset database (stops containers, removes database, restarts) docker-compose down && rm -f data/claude_monitor.db* && docker-compose up -d ``` ### Testing Hook Installation ```bash # Install hooks to ~/.claude/hooks/ ./install_hooks.sh # Test hook manually echo '{"session_id":"test","tool_name":"Bash","timestamp":1234567890}' | ~/.claude/hooks/post_tool_use.sh # Verify backend received it curl http://localhost:8000/api/events | jq ``` ## Database Schema **SQLAlchemy 2.0 Compatibility**: Uses explicit `text()` for raw SQL, proper relationship configurations, and modern declarative syntax. **Tables**: - `events` - All captured events with indexes on session_id, event_type, tool_name, timestamp - `sessions` - Session tracking with start/end times and event counts - `statistics` - Single-row cache table (id=1) for dashboard stats - `tool_usage` - Per-tool usage counters with first/last usage timestamps **SQLite Configuration**: WAL mode enabled for better concurrency in `init_db()`. ## Event Types | Event Type | Source Hook | Description | Frontend Filter | |------------|-------------|-------------|-----------------| | `PreToolUse` | pre_tool_use.sh | Before tool execution | TOOLS | | `PostToolUse` | post_tool_use.sh | After tool execution | TOOLS | | `SessionStart` | session_start.sh | Session started | SESSIONS | | `SessionEnd` | session_end.sh | Session ended | SESSIONS | | `SubagentStop` | subagent_stop.sh | Agent completed | AGENTS | | `UserPromptSubmit` | user_prompt.sh | User prompt submitted | PROMPTS | ## Port Configuration - **Backend**: 8000 (FastAPI/Uvicorn) - **Frontend (dev)**: 5173 (Vite dev server) - **Frontend (prod)**: 3000 (nginx in Docker) Change ports in `docker-compose.yml` if conflicts occur. ## Key Implementation Details ### WebSocket Protocol - Backend broadcasts three message types: `event_created`, `stats_updated`, `stats_reset` - Frontend auto-reconnects on disconnect with exponential backoff - Heartbeat ping/pong every 30 seconds to maintain connection ### Frontend State Management - Events stored in reverse chronological order (newest first) - Pagination loads 50 events at a time - Filter changes trigger new API fetch (events reset) - Statistics updated via WebSocket broadcasts, not polling ### Hook Performance - All hooks run curl in background (`&`) to avoid blocking Claude Code - 2-second timeout on HTTP requests - Silent mode prevents stderr noise in Claude Code output - Uses `jq` for JSON construction to handle escaping correctly ### TypeScript Build The frontend uses strict TypeScript with proper type definitions in `types/index.ts`. When making changes: - Run `npm run build` to check for type errors before committing - Event types must match backend Pydantic models - Filter mappings in `EVENT_FILTER_MAP` must stay synchronized with backend event types ## Configuration Files - `docker-compose.yml` - Service orchestration, volumes, network setup - `backend/requirements.txt` - Python dependencies (FastAPI, SQLAlchemy 2.0, uvicorn, websockets) - `frontend/package.json` - Node dependencies (React 18, Vite, TypeScript, Axios) - `frontend/vite.config.ts` - Vite build configuration with React plugin - `frontend/tsconfig.json` - TypeScript compiler options ## Debugging ### Backend Issues ```bash # Check backend health curl http://localhost:8000/health # View API documentation open http://localhost:8000/docs # Check database sqlite3 data/claude_monitor.db "SELECT COUNT(*) FROM events;" # Tail backend logs docker-compose logs -f backend ``` ### Frontend Issues ```bash # Check WebSocket connection in browser console # Should show "WebSocket connected" message # Verify API connectivity curl http://localhost:8000/api/statistics # Check for CORS errors in browser DevTools Network tab ``` ### Hook Issues ```bash # Verify jq is installed which jq # Should print path, not "not found" # Check hooks are executable ls -la ~/.claude/hooks/ # Test hook with verbose output (remove --silent from curl) echo '{"session_id":"test"}' | ~/.claude/hooks/session_start.sh ```