Skip to content

Latest commit

 

History

History
291 lines (230 loc) · 9.64 KB

File metadata and controls

291 lines (230 loc) · 9.64 KB

GSD Monitor - Architecture Document

Purpose: Documentation for the GSD Monitor system, a lightweight event-driven monitoring and alert system for the Claude Code GSD extension.


Overview

GSD Monitor enhances the Get Shit Done (GSD) Claude Code extension by providing:

  • Real-time session status tracking across multiple concurrent sessions
  • Web-based monitoring dashboard accessible from any device on your network
  • Audio and browser alerts when Claude needs user input
  • Two-step notification system - yellow warning at 60s idle, red alert when input required
  • GSD project integration - shows current phase and plan progress
  • Cross-platform support (Windows, macOS, Linux)

The system operates by injecting hooks into Claude Code's hook system, capturing events, updating a shared state file, and serving a web dashboard with real-time updates via WebSocket.


Project Structure

gsd-monitor/
├── injector.py              # Installation & configuration manager
├── hooks/
│   ├── on_notification.py   # Handles idle_prompt & permission_prompt events
│   ├── on_session_start.py  # Handles session lifecycle events
│   ├── on_tool_use.py       # Tracks tool execution in real-time
│   ├── on_stop.py           # Handles completion events
│   └── state_utils.py       # Shared state file utilities
├── gsd-monitor-web/
│   ├── run.py               # CLI entry point with QR code display
│   ├── server.py            # FastAPI server with WebSocket
│   ├── state_manager.py     # Session CRUD and cleanup
│   ├── gsd_reader.py        # GSD project state parser
│   ├── requirements.txt     # Python dependencies
│   └── static/
│       ├── index.html       # Web UI
│       ├── app.js           # Frontend JavaScript
│       └── style.css        # Mobile-first responsive CSS
├── requirements.txt
└── README.md

Installed Location: ~/.claude/gsd-monitor/ State File: ~/.claude/gsd-monitor/state.json


Core Components

1. Injector (injector.py)

The installation manager responsible for:

  • Deploying hook scripts to ~/.claude/gsd-monitor/hooks/
  • Merging hooks into Claude Code's settings.json
  • Creating backups before modifications
  • Clean removal of injected hooks

Commands:

Command Description
python injector.py inject Install hooks globally
python injector.py inject --local Install to current project only
python injector.py remove Remove all GSD Monitor hooks
python injector.py status Check installation status

Key Design Decisions:

  • Uses "_marker": "__gsd_monitor__" to identify injected hooks for safe removal
  • Appends hooks (never replaces existing hooks)
  • Creates timestamped backups before any modification
  • Auto-detects Python executable per platform

2. Hook Scripts

on_notification.py - Alert Handler

Triggers: idle_prompt, permission_prompt notifications Actions:

  • Determines notification urgency (NEEDS_INPUT vs NEEDS_PERMISSION)
  • Updates state.json with current status (alerts handled by web UI)

on_tool_use.py - Activity Tracker

Triggers: PreToolUse event (before each tool execution) Actions:

  • Generates human-readable activity descriptions
  • Updates state with tool name and activity

Activity Description Examples:

  • Task: "Subagent: Fix authentication bug"
  • Bash: "$ git status"
  • Write: "Writing: src/index.ts"
  • Grep: "Searching: TODO"

on_session_start.py - Lifecycle Handler

Triggers: SessionStart event Actions:

  • Records session initialization
  • Distinguishes startup, resume, and context clear
  • Sets started_at timestamp

on_stop.py - Completion Handler

Triggers: Stop event Actions:

  • Marks Claude's response as complete
  • Preserves started_at for duration tracking
  • Sets status to STOPPED

3. Web Monitor (gsd-monitor-web/)

A real-time web dashboard providing:

  • Session picker - view all active Claude Code sessions
  • Live status updates via WebSocket
  • Two-step notifications - yellow warning (STOPPED), red alert (NEEDS_INPUT)
  • Browser notifications - native desktop alerts when input needed
  • Audio alerts - two-tone doorbell sound via Web Audio API
  • GSD integration - shows current phase and plan progress
  • Mobile support - responsive design with QR code for phone access
  • Auto-follow - tracks sessions across /clear operations

Usage:

cd gsd-monitor-web
pip install -r requirements.txt
python run.py                    # Start server on port 8765
python run.py --port 9000        # Custom port
python run.py --no-qr            # Disable QR code display

Data Flow

┌─────────────┐    Event     ┌─────────────┐    Stdin JSON    ┌─────────────┐
│ Claude Code │ ─────────────▶│ Hook System │ ─────────────────▶│ Hook Script │
└─────────────┘              └─────────────┘                   └──────┬──────┘
                                                                      │
                                                                      │ Updates
                                                                      ▼
┌─────────────┐    Reads     ┌─────────────┐
│ Web Monitor │ ◀────────────│ state.json  │
│  (Browser)  │              └─────────────┘
└─────────────┘

Complete Session Lifecycle:

  1. SessionStart → Status: STARTED, records started_at
  2. PreToolUse (repeated) → Status: RUNNING, updates tool activity
  3. Notification (if idle 60s) → Status: NEEDS_INPUT or NEEDS_PERMISSION
  4. Stop → Status: STOPPED, preserves timestamps

State File Structure

Location: ~/.claude/gsd-monitor/state.json

{
  "session-id-abc123": {
    "status": "NEEDS_INPUT",
    "message": "Claude is waiting for your input",
    "updated_at": "2026-01-25T14:32:15.123456",
    "started_at": "2026-01-25T14:30:00.000000",
    "project": "my-project",
    "cwd": "/home/user/projects/my-project",
    "tool": "AskUserQuestion",
    "transcript_path": "/path/to/transcript.json"
  }
}

Status Values:

Status Meaning Web UI Color
STARTED Session just initialized Blue
RUNNING Claude actively executing tools Green
STOPPED Waiting for next prompt Yellow (warning)
NEEDS_INPUT Claude waiting for user input Red (alert)
NEEDS_PERMISSION Permission required Red (alert)
NOTIFICATION Generic notification White

Hook Integration

Hooks are injected into Claude Code's settings.json:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "idle_prompt|permission_prompt",
        "hooks": [{ "type": "command", "command": "python ~/.claude/gsd-monitor/hooks/on_notification.py" }],
        "_marker": "__gsd_monitor__"
      }
    ],
    "PreToolUse": [
      {
        "hooks": [{ "type": "command", "command": "python ~/.claude/gsd-monitor/hooks/on_tool_use.py" }],
        "_marker": "__gsd_monitor__"
      }
    ],
    "Stop": [
      {
        "hooks": [{ "type": "command", "command": "python ~/.claude/gsd-monitor/hooks/on_stop.py" }],
        "_marker": "__gsd_monitor__"
      }
    ],
    "SessionStart": [
      {
        "hooks": [{ "type": "command", "command": "python ~/.claude/gsd-monitor/hooks/on_session_start.py" }],
        "_marker": "__gsd_monitor__"
      }
    ]
  }
}

Technical Specifications

Dependencies

Hook scripts (standard library only):

  • json, pathlib, datetime, sys

Web monitor (pip install):

  • fastapi - Web framework
  • uvicorn - ASGI server
  • watchfiles - File change detection
  • qrcode - QR code generation for mobile access

Error Handling

  • All hooks catch exceptions silently to avoid breaking Claude Code
  • JSON parse errors result in graceful exit
  • State file I/O wrapped in try/except

Configuration Points

Setting Location How to Modify
Web server port gsd-monitor-web/run.py Use --port argument
Disable QR code gsd-monitor-web/run.py Use --no-qr argument
State file location hooks/state_utils.py Edit STATE_FILE constant

Known Limitations

  1. 60-second alert delay - Relies on Claude Code's idle_prompt notification which fires after 60s idle. The web UI mitigates this with a yellow warning state when STOPPED.

  2. Single state file - All sessions share one file; potential for race conditions with many concurrent sessions (mitigated by atomic writes in state_utils.py).


Security Considerations

  • Non-invasive: Hooks append, never replace existing hooks
  • Clean removal: Marker-based identification enables complete uninstall
  • No privilege escalation: Runs entirely in user context
  • Trusted input: Only processes JSON from Claude Code via stdin
  • No eval(): Uses json.loads() for safe parsing

Quick Start

# Install hooks
cd gsd-monitor
python injector.py inject

# Start web monitor
cd gsd-monitor-web
pip install -r requirements.txt
python run.py

# Uninstall hooks
python injector.py remove

Last Updated: 2026-01-25