Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b4d9f5d
add: [AGENT-3] context window tracking UI
sagarsrc Jan 22, 2026
ac2c561
add: [AGENT-1] context storage CRUD methods
sagarsrc Jan 22, 2026
ecf0ee1
add: [AGENT-1] context tracking API endpoints
sagarsrc Jan 22, 2026
3e091aa
test: [AGENT-1] add context tracking unit tests
sagarsrc Jan 22, 2026
c3e36bd
add: [AGENT-2] context-tracker hook for CC integration
sagarsrc Jan 22, 2026
8f89024
fix: [AGENT-4] reposition copy buttons to avoid overlap
sagarsrc Jan 22, 2026
4369f23
fix: [AGENT-4] redesign copy buttons for better UX
sagarsrc Jan 22, 2026
15dace3
fix: [AGENT-4] add copy buttons to tool INPUT and RESULT sections
sagarsrc Jan 22, 2026
9199ec5
add: [AGENT-4] Copy All button for entire tool group
sagarsrc Jan 22, 2026
bd1b742
update: [AGENT-4] single Copy button per tool instead of INPUT/OUTPUT
sagarsrc Jan 22, 2026
2a97ed2
add: [AGENT-2] hooks module for context tracking
sagarsrc Jan 22, 2026
c9f9f09
add: [AGENT-3] session status bar with model, context, cost
sagarsrc Jan 22, 2026
ac4f18b
add: [AGENT-2] auto-register hooks on server startup
sagarsrc Jan 22, 2026
d908879
fix: [AGENT-2] use full path for hook command
sagarsrc Jan 22, 2026
7d9aac4
fix: [AGENT-2] context bar now displays correctly in UI
sagarsrc Jan 22, 2026
ddd628c
fix: simplify Import Sessions button to prevent overflow
sagarsrc Jan 22, 2026
5a41a0a
fix: [AGENT-2] show model name and calculated cost in status bar
sagarsrc Jan 22, 2026
498468b
fix: [AGENT-2] refresh context data when events change
sagarsrc Jan 22, 2026
2272cac
add: [AGENT-2] accurate cumulative session cost tracking
sagarsrc Jan 22, 2026
57d803e
add: [AGENT-2] real-time context updates via WebSocket
sagarsrc Jan 22, 2026
8c3e9f8
fix: [AGENT-2] restore context bar when no real-time data yet
sagarsrc Jan 22, 2026
1bc23ce
fix: [AGENT-2] simplify context data flow - each session fetches own …
sagarsrc Jan 22, 2026
341510c
fix: [AGENT-2] correct context % and cost calculation in hooks
sagarsrc Jan 22, 2026
96e9bda
fix: [AGENT-2] remove cost from status bar, redesign context UI
sagarsrc Jan 22, 2026
d5488c4
docs: update architecture with hooks system for context tracking
sagarsrc Jan 22, 2026
d328ecb
fix: race condition when switching sessions hides context bar
sagarsrc Jan 22, 2026
41e679b
fix: model not showing in status bar for historical sessions
sagarsrc Jan 22, 2026
9d2f0a6
add: derive context data from events for historical sessions
sagarsrc Jan 22, 2026
8a0cb9e
fix: make install scripts POSIX-compliant for Linux sh compatibility
sagarsrc Jan 22, 2026
d4c6786
docs: use bash instead of sh in install command for cross-platform re…
sagarsrc Jan 23, 2026
7ac982e
chore: bump version to 0.2.11
sagarsrc Jan 23, 2026
0cf0e65
add: unread indicator dot for sessions with new messages
sagarsrc Jan 23, 2026
cc59d6f
fix: broadcast session_updated to all clients for unread tracking
sagarsrc Jan 23, 2026
b587d5e
update: move unread dot to top-right corner
sagarsrc Jan 23, 2026
64b8f85
fix: show 'New messages' button when clicking unread session
sagarsrc Jan 23, 2026
0043b79
fix: adjust unread dot position for better alignment
sagarsrc Jan 23, 2026
5a51f68
fix: use ref to persist unread state across useEffect reset
sagarsrc Jan 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<p align="center">
<a href="#install">Install</a> |
<a href="#features">Features</a> |
<a href="#context-window-tracking-optional">Context Tracking</a> |
<a href="#configuration">Configuration</a> |
<a href="#docker">Docker</a> |
<a href="#troubleshooting">Troubleshooting</a>
Expand All @@ -33,7 +34,7 @@
## Install

```bash
curl -fsSL https://quickcall.dev/supertrace/install.sh | sh
curl -fsSL https://quickcall.dev/supertrace/install.sh | bash
```

Then run:
Expand All @@ -55,6 +56,46 @@ Open http://localhost:7845 in your browser.
- **Full-text search** - Find anything across all sessions
- **Export** - Download sessions as JSON or Markdown
- **WebSocket updates** - Live updates without page refresh
- **Context window tracking** - Real-time context usage with color-coded progress bar

## Context Window Tracking

Real-time context window tracking is **automatically enabled** when you run SuperTrace.

### How It Works

1. When `quickcall-supertrace` starts, it automatically configures Claude Code hooks
2. After each Claude response, the hook captures token usage
3. Context data is sent to the SuperTrace server
4. The UI displays a real-time progress bar:
- **Green** - Under 50% usage
- **Yellow** - 50-75% usage
- **Red** - Over 75% usage

### Setup

Just run SuperTrace - hooks are configured automatically:

```bash
quickcall-supertrace
```

Then **restart Claude Code** to load the hooks.

### Disable Auto-Registration

If you don't want automatic hook registration:

```bash
QUICKCALL_SUPERTRACE_AUTO_HOOKS=false quickcall-supertrace
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `QUICKCALL_SUPERTRACE_AUTO_HOOKS` | true | Auto-register Claude Code hooks |
| `QUICKCALL_SUPERTRACE_DEBUG` | false | Enable debug logging for hooks |

## Dashboard Metrics

Expand Down
87 changes: 81 additions & 6 deletions docs/concepts/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ How QuickCall SuperTrace captures and displays Claude Code sessions.

```mermaid
flowchart TB
subgraph "Real-time (Hooks)"
H1[Claude Code] -->|Stop event| H2[Hook CLI]
H2 -->|POST /context| API
end

subgraph Ingestion
A[~/.claude/projects/] --> B[Scanner]
B --> C[Parser]
Expand All @@ -14,6 +19,7 @@ flowchart TB

subgraph Storage
D --> E[(SQLite WAL)]
API --> E
end

subgraph API
Expand Down Expand Up @@ -41,7 +47,51 @@ Each line is a JSON object representing a message:
{"type":"assistant","message":{"content":[...],"usage":{...}},"timestamp":"2026-01-14T10:00:10Z"}
```

### 2. Ingestion Pipeline
### 2. Hooks System (Real-time Context Tracking)

Claude Code supports hooks that fire on specific events. SuperTrace uses the **Stop hook** to track context window usage in real-time.

**How it works:**
1. On server startup, SuperTrace registers hooks in `~/.claude/settings.json`
2. When Claude finishes responding, the Stop hook fires
3. Hook CLI reads the transcript and extracts token usage
4. Context data is POSTed to SuperTrace server
5. Server broadcasts via WebSocket to update UI instantly

**Components:**

| File | Purpose |
|------|---------|
| `hooks/setup.py` | Auto-registers hooks on server startup |
| `hooks/cli.py` | CLI entry point (`quickcall-supertrace-hook`) |
| `hooks/handlers.py` | Processes hook events, extracts context data |
| `hooks/models.py` | Pydantic models for hook input/output |

**Context Calculation:**
```
Total Context = input_tokens + cache_read_tokens + cache_create_tokens
Context % = (Total Context / Model Context Window) × 100
```

Note: Output tokens are NOT included in context window calculation.

**Hook Registration** (in `~/.claude/settings.json`):
```json
{
"hooks": {
"Stop": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "/path/to/quickcall-supertrace-hook stop",
"timeout": 5
}]
}]
}
}
```

### 3. Ingestion Pipeline (Batch Import)

**Scanner** (`packages/server/quickcall_supertrace/ingest/scanner.py`)
- Finds all JSONL files in `~/.claude/projects/`
Expand All @@ -64,7 +114,7 @@ Each line is a JSON object representing a message:
- Triggers incremental imports
- Broadcasts updates via WebSocket

### 3. Database (SQLite)
### 4. Database (SQLite)

Location: `~/.quickcall-supertrace/data.db`

Expand All @@ -75,6 +125,7 @@ Location: `~/.quickcall-supertrace/data.db`
| `sessions` | Session metadata (id, project_path, timestamps) |
| `messages` | Parsed JSONL messages with extracted fields |
| `transcript_files` | Tracks ingested files (mtime, byte offset) |
| `session_context` | Context window snapshots (from hooks) |
| `session_metrics` | Pre-computed aggregates |
| `messages_fts` | Full-text search index |

Expand All @@ -83,21 +134,23 @@ Location: `~/.quickcall-supertrace/data.db`
- Denormalized fields in `messages` for query performance
- FTS5 for full-text search across content

### 4. REST API (FastAPI)
### 5. REST API (FastAPI)

**Routes:**

| Endpoint | Purpose |
|----------|---------|
| `GET /api/sessions` | List sessions (paginated) |
| `GET /api/sessions/{id}` | Get session with events |
| `GET /api/sessions/{id}/context` | Get context window snapshots |
| `POST /api/sessions/{id}/context` | Store context update (from hooks) |
| `GET /api/sessions/{id}/export` | Export as JSON/Markdown |
| `GET /api/metrics/session/{id}` | Compute session metrics |
| `POST /api/ingest` | Trigger manual import |
| `GET /api/ingest/status` | Show tracked files |
| `WS /ws` | Real-time updates |

### 5. Metrics System
### 6. Metrics System

**Architecture:** Decorator-based plugin system

Expand All @@ -116,7 +169,7 @@ def estimated_cost(events: PreprocessedEvents) -> float:

**Preprocessing:** Single-pass extraction of commonly-needed data for efficiency.

### 6. React Frontend
### 7. React Frontend

**Tech Stack:** React 19, TypeScript, Tailwind CSS, Vite

Expand All @@ -139,7 +192,29 @@ def estimated_cost(events: PreprocessedEvents) -> float:

## Data Flow

### Import Flow
### Context Tracking Flow (Real-time)

```mermaid
sequenceDiagram
participant CC as Claude Code
participant Hook as Hook CLI
participant API as SuperTrace API
participant WS as WebSocket
participant UI as Frontend

CC->>CC: User sends prompt
CC->>CC: Claude responds
CC->>Hook: Stop event (stdin JSON)
Hook->>Hook: Read transcript JSONL
Hook->>Hook: Extract token usage
Hook->>Hook: Calculate context %
Hook->>API: POST /sessions/{id}/context
API->>API: Store snapshot
API->>WS: Broadcast context_updated
WS->>UI: Update status bar
```

### Import Flow (Batch)

```mermaid
sequenceDiagram
Expand Down
148 changes: 148 additions & 0 deletions install/hooks/context-tracker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#!/usr/bin/env bash
#
# SuperTrace Context Tracker Hook for Claude Code
#
# This hook captures context window usage data from Claude Code sessions
# and sends it to the SuperTrace backend for real-time tracking.
#
# Hook Event: PostToolUse (fires after each tool call)
#
# Installation:
# 1. Copy hooks directory to ~/.claude/plugins/supertrace/
# 2. Claude Code will automatically load hooks from the plugin
#
# Environment:
# SUPERTRACE_URL - SuperTrace backend URL (default: http://localhost:7845)
# SUPERTRACE_DEBUG - Enable debug logging (set to "true")
# SUPERTRACE_TIMEOUT - Request timeout in seconds (default: 2)
#

set -euo pipefail

# Configuration with defaults
SUPERTRACE_URL="${SUPERTRACE_URL:-http://localhost:7845}"
SUPERTRACE_DEBUG="${SUPERTRACE_DEBUG:-false}"
SUPERTRACE_TIMEOUT="${SUPERTRACE_TIMEOUT:-2}"

# Debug logging function
debug() {
if [ "$SUPERTRACE_DEBUG" = "true" ]; then
echo "[SuperTrace Debug] $*" >&2
fi
}

# Log errors but don't fail - hooks must be non-blocking
log_error() {
echo "[SuperTrace Error] $*" >&2
}

# Read stdin (Claude Code passes JSON input)
input=$(cat 2>/dev/null || echo "{}")

debug "Received hook input"

# Extract session_id from hook input
session_id=$(echo "$input" | jq -r '.session_id // empty' 2>/dev/null || true)

if [ -z "$session_id" ]; then
debug "No session_id found in hook input, skipping"
exit 0
fi

debug "Session ID: $session_id"

# Get transcript path from hook input
transcript_path=$(echo "$input" | jq -r '.transcript_path // empty' 2>/dev/null || true)

if [ -z "$transcript_path" ] || [ ! -f "$transcript_path" ]; then
debug "No valid transcript_path found, skipping"
exit 0
fi

debug "Transcript path: $transcript_path"

# Parse the latest API response from transcript to get token usage
# The transcript is JSONL format with API responses containing usage data
# Look for the most recent entry with usage data

# Get the last line with usage data from transcript
latest_usage=$(tail -100 "$transcript_path" 2>/dev/null | \
grep -o '"usage":{[^}]*}' 2>/dev/null | \
tail -1 || true)

if [ -z "$latest_usage" ]; then
debug "No usage data found in recent transcript entries"
exit 0
fi

debug "Found usage data: $latest_usage"

# Extract token counts from usage data
# Format: "usage":{"input_tokens":1234,"output_tokens":567,"cache_creation_input_tokens":0,"cache_read_input_tokens":890}
input_tokens=$(echo "{$latest_usage}" | jq -r '.usage.input_tokens // 0' 2>/dev/null || echo "0")
output_tokens=$(echo "{$latest_usage}" | jq -r '.usage.output_tokens // 0' 2>/dev/null || echo "0")
cache_read_tokens=$(echo "{$latest_usage}" | jq -r '.usage.cache_read_input_tokens // 0' 2>/dev/null || echo "0")
cache_creation_tokens=$(echo "{$latest_usage}" | jq -r '.usage.cache_creation_input_tokens // 0' 2>/dev/null || echo "0")

# Calculate totals
total_input_tokens=$((input_tokens + cache_read_tokens + cache_creation_tokens))
total_output_tokens=$output_tokens
total_tokens=$((total_input_tokens + total_output_tokens))

debug "Input tokens: $total_input_tokens, Output tokens: $total_output_tokens"

# Estimate context window size (default to 200k for Claude)
# This could be enhanced to detect model type from transcript
context_window_size=200000

# Calculate percentages
used_percentage=$(echo "scale=2; ($total_tokens * 100) / $context_window_size" | bc 2>/dev/null || echo "0")
remaining_percentage=$(echo "scale=2; 100 - $used_percentage" | bc 2>/dev/null || echo "100")

debug "Used: ${used_percentage}%, Remaining: ${remaining_percentage}%"

# Build the payload for SuperTrace API
payload=$(jq -n \
--argjson used_percentage "$used_percentage" \
--argjson remaining_percentage "$remaining_percentage" \
--argjson context_window_size "$context_window_size" \
--argjson total_input_tokens "$total_input_tokens" \
--argjson total_output_tokens "$total_output_tokens" \
--argjson cache_read_tokens "$cache_read_tokens" \
--argjson cache_creation_tokens "$cache_creation_tokens" \
'{
used_percentage: $used_percentage,
remaining_percentage: $remaining_percentage,
context_window_size: $context_window_size,
total_input_tokens: $total_input_tokens,
total_output_tokens: $total_output_tokens,
cache_read_tokens: $cache_read_tokens,
cache_creation_tokens: $cache_creation_tokens
}' 2>/dev/null || true)

if [ -z "$payload" ]; then
log_error "Failed to build payload"
exit 0
fi

debug "Payload: $payload"

# POST to SuperTrace API with timeout
# Use || true to ensure hook never blocks Claude Code
api_url="${SUPERTRACE_URL}/api/sessions/${session_id}/context"

debug "POSTing to: $api_url"

response=$(curl -s -X POST "$api_url" \
-H "Content-Type: application/json" \
-d "$payload" \
--connect-timeout "$SUPERTRACE_TIMEOUT" \
--max-time "$SUPERTRACE_TIMEOUT" \
2>/dev/null || true)

if [ -n "$response" ]; then
debug "Response: $response"
fi

# Always exit successfully - hooks must be non-blocking
exit 0
17 changes: 17 additions & 0 deletions install/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"description": "SuperTrace context tracking hook - sends context window usage to SuperTrace backend",
"hooks": {
"PostToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/context-tracker.sh",
"timeout": 5
}
]
}
]
}
}
Loading