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:
65
backend/app/api/websocket_endpoint.py
Normal file
65
backend/app/api/websocket_endpoint.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""WebSocket API endpoint for real-time updates."""
|
||||
|
||||
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
import logging
|
||||
import json
|
||||
|
||||
from app.websocket import manager
|
||||
from app.database import get_db
|
||||
from app.crud import get_statistics
|
||||
|
||||
router = APIRouter(tags=["websocket"])
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@router.websocket("/ws")
|
||||
async def websocket_endpoint(websocket: WebSocket):
|
||||
"""
|
||||
WebSocket endpoint for real-time event updates.
|
||||
|
||||
Clients connect to this endpoint to receive:
|
||||
- New events as they're created
|
||||
- Updated statistics
|
||||
- Reset notifications
|
||||
|
||||
Message types:
|
||||
- event_created: New event with updated statistics
|
||||
- stats_updated: Statistics update
|
||||
- stats_reset: All stats have been reset
|
||||
- connection_status: Connection status message
|
||||
"""
|
||||
await manager.connect(websocket)
|
||||
|
||||
try:
|
||||
# Send initial connection message
|
||||
await manager.send_personal_message(
|
||||
{"type": "connection_status", "message": "Connected to Claude Code Monitor"},
|
||||
websocket,
|
||||
)
|
||||
|
||||
# Keep connection alive and handle incoming messages
|
||||
while True:
|
||||
try:
|
||||
# Receive messages from client (for future features like pings)
|
||||
data = await websocket.receive_text()
|
||||
message = json.loads(data)
|
||||
|
||||
# Handle ping/pong for connection health
|
||||
if message.get("type") == "ping":
|
||||
await manager.send_personal_message(
|
||||
{"type": "pong", "timestamp": message.get("timestamp")},
|
||||
websocket,
|
||||
)
|
||||
|
||||
except WebSocketDisconnect:
|
||||
logger.info("Client disconnected")
|
||||
break
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling WebSocket message: {e}")
|
||||
# Don't break on error, continue listening
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"WebSocket error: {e}")
|
||||
finally:
|
||||
manager.disconnect(websocket)
|
||||
Reference in New Issue
Block a user