# parthmashroo/claude-code-monitor architecture

> Architecture diagram of the GitHub repository parthmashroo/claude-code-monitor, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/parthmashroo/claude-code-monitor
- Repository: https://github.com/parthmashroo/claude-code-monitor

## Overview

1. **Overall shape**
   - This repo is a very small, mostly self-contained desktop application: one main Python/Tkinter process in `monitor.py`, plus one optional Claude Code hook script in `hooks/capture-session.py`.
   - There is no backend service, database, or local daemon. The widget process owns the whole runtime.

2. **Primary runtime boundary: the desktop widget**
   - `monitor.py` creates a 30px-tall always-on-top floating window.
   - The UI is intentionally minimal: it displays usage counters, rate-limit bars, and session stats, and supports only drag, right-click theme switching, and close.
   - The app is meant to sit on the desktop above other apps, including VS Code.

3. **Data source #1: Anthropic usage API**
   - The widget makes a real network call to `api.anthropic.com/api/oauth/usage`.
   - This is the source of the 5h and 7d quota percentages and reset timestamps.
   - The README makes clear this uses the user’s existing Claude Code OAuth session; no separate authentication flow or account setup is introduced by this repo.

4. **Data source #2: local Claude project transcripts**
   - `monitor.py` scans `~/.claude/projects/**/*.jsonl` for today’s token and cost totals.
   - These files are local Claude Code project logs, aggregated across all projects and tabs.
   - This is a pure read-only local filesystem boundary; the widget does not modify the project transcripts.

5. **Data source #3: optional session hook output**
   - `hooks/capture-session.py` is an optional Claude Code “Stop” hook that receives JSON on stdin, including `session_id` and `transcript_path`.
   - It parses the current session transcript and writes per-session stats to `~/.claude/widgets/claude-code-monitor/session_data.json`.
   - `monitor.py` reads that file to populate the `sess` column; without the hook, the widget still works, but session stats show `--`.

6. **Persistence and local state**
   - The app persists user-specific state in `~/.claude/widgets/claude-code-monitor/`.
   - `config.json` stores widget position and theme.
   - `session_data.json` stores hook-generated session totals.
   - This separation keeps the live widget stateless except for reading/writing small local JSON files.

7. **Refresh model**
   - The widget polls the Anthropic usage API every 60 seconds.
   - It re-reads local token/session data every 5 seconds.
   - The countdown timers are derived locally from stored reset timestamps and update more frequently than the API poll, so the display feels live without constant network traffic.

8. **UI state and theming**
   - Theme selection is handled inside the widget process and persists across restarts.
   - The right-click theme picker maps to 10 built-in themes, grouped into dark and light variants.
   - Position is also persisted, so the widget resumes where the user left it.

9. **OS integration boundary: startup registration**
   - On first run, `monitor.py` registers itself to auto-start at login.
   - It uses platform-native mechanisms: Windows registry Run key, macOS LaunchAgent plist, or Linux autostart desktop entry.
   - This is one of the few places where the app crosses from pure application logic into OS configuration.

10. **Security and trust model**
   - The app’s trust boundary is intentionally narrow: local reads from Claude-owned files plus one outbound request to Anthropic for the user’s own usage stats.
   - There is no telemetry, analytics pipeline, or third-party service in the architecture.
   - That makes the repo essentially a local observability widget for Claude Code usage, with optional hook-based augmentation for session-level stats.

Main entry points: [`monitor.py`](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py) (Widget app), [`hooks/capture-session.py`](https://github.com/parthmashroo/claude-code-monitor/blob/master/hooks/capture-session.py) (Hook parser)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Desktop widget"]
  node_monitor["Widget app<br/>Tkinter app<br/>[monitor.py]"]
  node_ui["Compact UI<br/>display<br/>[monitor.py]"]
  node_polling(("Refresh loops<br/>scheduler<br/>[monitor.py]"))
  node_usage_api["Usage fetch<br/>network client<br/>[monitor.py]"]
  node_transcript_scan["Transcript scan<br/>filesystem reader<br/>[monitor.py]"]
  node_session_view["Session stats<br/>session overlay<br/>[monitor.py]"]
  node_theme_state["Theme state<br/>ui state<br/>[monitor.py]"]
  node_window_state["Window state<br/>ui state<br/>[monitor.py]"]
  node_autostart["Auto-start setup<br/>os integration<br/>[monitor.py]"]
  node_capture_hook["Stop hook<br/>Claude hook<br/>[capture-session.py]"]
  node_hook_parser["Hook parser<br/>transcript parser<br/>[capture-session.py]"]
end

subgraph group_local["Local state"]
  node_hook_write["Session writer<br/>state writer"]
  node_config_store["Config file<br/>json state"]
  node_session_store["Session file<br/>json cache"]
  node_claude_logs[("Claude logs<br/>local files")]
end

subgraph group_external["Outside systems"]
  node_anthropic(("Anthropic API<br/>external service"))
  node_os_login{{"OS startup<br/>platform feature"}}
end

node_monitor -->|"renders"| node_ui
node_monitor -->|"drives"| node_polling
node_polling -->|"polls"| node_usage_api
node_polling -->|"reads"| node_transcript_scan
node_usage_api -->|"requests"| node_anthropic
node_transcript_scan -->|"scans"| node_claude_logs
node_monitor -->|"shows"| node_session_view
node_capture_hook -->|"passes"| node_hook_parser
node_hook_parser -->|"writes"| node_hook_write
node_hook_write -->|"stores"| node_session_store
node_monitor -->|"reads"| node_session_store
node_monitor -->|"updates"| node_theme_state
node_theme_state -->|"persists"| node_config_store
node_monitor -->|"updates"| node_window_state
node_window_state -->|"persists"| node_config_store
node_monitor -->|"registers"| node_autostart
node_autostart -->|"uses"| node_os_login

click node_monitor "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_ui "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_polling "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_usage_api "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_transcript_scan "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_session_view "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_theme_state "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_window_state "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_autostart "https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py"
click node_capture_hook "https://github.com/parthmashroo/claude-code-monitor/blob/master/hooks/capture-session.py"
click node_hook_parser "https://github.com/parthmashroo/claude-code-monitor/blob/master/hooks/capture-session.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_monitor,node_ui,node_polling,node_usage_api,node_transcript_scan,node_session_view,node_theme_state,node_window_state,node_autostart,node_capture_hook,node_hook_parser toneBlue
class node_hook_write,node_config_store,node_session_store,node_claude_logs toneAmber
class node_anthropic,node_os_login toneMint
```

## Components

### Desktop widget

Main Python/Tkinter process that owns the UI, refresh loops, and app behavior.

- [Widget app](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): Tkinter app · Floating always-on-top desktop widget and process entrypoint. · `monitor.py`
- [Compact UI](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): display · Shows usage counters, quota bars, and session stats in a 30px desktop strip. · `monitor.py`
- [Refresh loops](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): scheduler · Polls network and local state on different intervals to keep the display current. · `monitor.py`
- [Usage fetch](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): network client · Calls Anthropic usage endpoint for 5h and 7d quota state and reset times. · `monitor.py`
- [Transcript scan](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): filesystem reader · Scans Claude project JSONL logs to aggregate today’s tokens and cost totals. · `monitor.py`
- [Session stats](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): session overlay · Displays per-session totals when hook-generated data is available; falls back to placeholders otherwise. · `monitor.py`
- [Theme state](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): ui state · Handles built-in theme selection and persists the chosen look across restarts. · `monitor.py`
- [Window state](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): ui state · Tracks widget position and drag behavior so the window reopens where the user left it. · `monitor.py`
- [Auto-start setup](https://github.com/parthmashroo/claude-code-monitor/blob/master/monitor.py): os integration · Registers the widget to launch at login using the host platform’s native mechanism. · `monitor.py`
- [Stop hook](https://github.com/parthmashroo/claude-code-monitor/blob/master/hooks/capture-session.py): Claude hook · Optional Claude Code hook that receives session metadata and transcript paths on stdin. · `hooks/capture-session.py`
- [Hook parser](https://github.com/parthmashroo/claude-code-monitor/blob/master/hooks/capture-session.py): transcript parser · Extracts the current session’s token and cost totals from the provided transcript. · `hooks/capture-session.py`

### Local state

Read-only Claude project logs plus small per-user JSON files under the widget data directory.

- **Session writer**: state writer · Writes per-session totals to the local widget data directory.
- **Config file**: json state · Stores widget position and theme selection.
- **Session file**: json cache · Stores hook-generated session totals for the widget to read.
- **Claude logs**: local files · Local Claude project JSONL transcripts aggregated across projects and tabs.

### Outside systems

Anthropic API and OS startup mechanisms the app integrates with.

- **Anthropic API**: external service · OAuth usage endpoint used for quota and reset information.
- **OS startup**: platform feature · Windows Run key, macOS LaunchAgent, or Linux autostart entry.

## Connections

- Widget app → Compact UI: renders · Creates the floating widget and updates the compact display.
- Widget app → Refresh loops: drives · Coordinates periodic refresh of network and local data.
- Refresh loops → Usage fetch: polls · Refreshes remote quota data on a slower interval.
- Refresh loops → Transcript scan: reads · Re-reads today’s local token and cost totals frequently.
- Usage fetch → Anthropic API: requests · Fetches the user’s Claude usage state from Anthropic.
- Transcript scan → Claude logs: scans · Aggregates values from local project transcript JSONL files.
- Widget app → Session stats: shows · Populates the session column from optional hook output.
- Stop hook → Hook parser: passes · Receives session metadata and transcript path from Claude Code.
- Hook parser → Session writer: writes · Persists parsed per-session totals for the widget.
- Session writer → Session file: stores · Writes session_data.json under the widget data directory.
- Widget app → Session file: reads · Loads hook-generated session data when available.
- Widget app → Theme state: updates · Handles right-click theme switching inside the widget process.
- Theme state → Config file: persists · Saves theme choice for restart reuse.
- Widget app → Window state: updates · Tracks drag position and window placement.
- Window state → Config file: persists · Saves widget position to local config.
- Widget app → Auto-start setup: registers · Installs login startup registration on first run.
- Auto-start setup → OS startup: uses · Delegates to the platform-native startup mechanism.
