# handlecusion/tokcat architecture

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

- Interactive diagram: https://gitdiagram.com/handlecusion/tokcat
- Repository: https://github.com/handlecusion/tokcat

## Overview

##### What the repo is
Tokcat is a **macOS menu-bar desktop app** for tracking AI coding token usage and cost. Architecturally it is a **local-first Tauri 2 application**: a Rust native shell handles data collection and macOS integration, while a React/Vite frontend renders the dashboard.

##### Top-level runtime split
The repo is organized around two execution worlds:
- **`src-tauri/`**: the native backend, packaging, tray/menu-bar behavior, update checks, and local data access.
- **`src/`**: the frontend UI for the popover dashboard, settings, graphs, and summary cards.
This boundary is the main architecture seam: Rust produces structured usage/state data; React consumes and visualizes it.

##### Local usage ingestion
The backend reads **local session logs** from supported AI clients rather than sending data to Tokcat services. The ingest layer appears to live in modules such as `agent_usage.rs`, `usage_tail.rs`, and `usage_graph.rs`, with `state.rs` likely holding shared cached state. The README describes the backend as scanning local client stores, deduplicating, normalizing token fields, and estimating cost when needed.

##### Live activity pipeline
There is a separate **live/session tailing path** that tracks recent log growth and turns it into a short-window throughput signal (tokens per minute). That live signal feeds both the **menu-bar title/animation** and the **Live session** card in the UI. This is distinct from historical usage aggregation, which is more batch-like and dashboard-oriented.

##### Vendor quota lookups are a separate boundary
Tokcat also queries **direct vendor endpoints** for agent-limit/quota data when local OAuth credentials exist. The README calls out Codex and Claude usage windows specifically. This means the app has two data sources:
- **local logs** for historical usage/cost
- **external vendor APIs** for quota/limit cards
These are separate from each other and from any analytics/telemetry, which the app does not appear to have.

##### UI composition
The frontend is a dashboard built from composable cards and controls in `src/components/`. Key visible areas include:
- overview/client tabs
- 2D token graphs
- 3D contribution graph
- streak summaries
- live trace rows
- agent-limit cards
- settings panel
The main app shell is in `src/App.tsx`, with shared styling in `src/styles.css`.

##### Frontend data/model layer
`src/lib/` contains the frontend’s data and presentation logic: formatting, stats, streaks, themes, runtime/settings helpers, usage transformations, and updater integration. `src/hooks/` (`useAgentUsage.ts`, `useGraphStream.ts`) likely bridges the backend data stream into React state. This is the UI-side counterpart to the Rust ingestion/cache layer.

##### Shared state and settings
Settings are persisted locally and influence both backend and frontend behavior: menu-bar title mode, animation style, launch-at-login, theme, live trace splitting, and update checks. The presence of `src/lib/settings.ts` and backend `state.rs` indicates a cross-layer configuration/state model, with the backend likely providing authoritative app state and the UI reflecting it.

##### Update and release flow
Tokcat includes an **in-app updater** that checks signed release metadata on launch and periodically thereafter. This is backed by GitHub Releases and a release pipeline in `.github/workflows/`. The update mechanism is part of the product architecture because it is a runtime network dependency separate from usage collection.

##### Development and mock data path
The repo supports a web/dev mode with `server.js` and Vite. The README notes that the frontend can run in a browser against a **mock graph payload**, while `pnpm tauri:dev` connects the UI to the native backend for real local log reading. That means there are two dev experiences: browser-only UI development and full desktop integration testing.

##### Docs, marketing, and generated assets
`docs/`, `public/`, `design/`, and `remotion/` support the project’s documentation and landing/media pipeline. The `remotion/` folder plus scripts like `render_docs_gifs.py` and `regenerate_*` indicate generated visual assets for screenshots, gifs, and motion clips. These are not core runtime subsystems, but they matter for the repo’s packaging and release surface.

##### Platform and packaging boundaries
The app targets **macOS 11+** on **Apple Silicon and Intel**. Packaging is handled through Tauri’s macOS build output, DMGs, and a Homebrew cask workflow. The architecture therefore has a clear native-app boundary: local desktop runtime, signed releases, and no server-side product backend.

##### High-level data flow
The end-to-end flow is:
local AI client logs and credentials → Rust backend scans/normalizes/caches usage and live signals → optional vendor quota calls and update checks → React UI renders dashboards, graphs, streaks, and settings → tray/menu-bar surfaces summary state for glanceable use.

Main entry points: [`src/components/TokenUsageCard.tsx`](https://github.com/handlecusion/tokcat/blob/main/src/components/TokenUsageCard.tsx) (Dashboard cards), [`src-tauri/src/state.rs`](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/state.rs) (State), [`src/hooks/useAgentUsage.ts`](https://github.com/handlecusion/tokcat/blob/main/src/hooks/useAgentUsage.ts) (Data hooks), [`src/App.tsx`](https://github.com/handlecusion/tokcat/blob/main/src/App.tsx) (App shell)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["Native backend"]
  node_src_tauri_main["Main<br/>tauri entry<br/>[main.rs]"]
  node_src_tauri_lib["Lib<br/>tauri module<br/>[lib.rs]"]
  node_state[("State<br/>[state.rs]")]
  node_agent_usage["Usage ingest<br/>log parser<br/>[agent_usage.rs]"]
  node_usage_tail["Live tail<br/>stream tail<br/>[usage_tail.rs]"]
  node_usage_graph["Usage graph<br/>aggregation<br/>[usage_graph.rs]"]
  node_tray["Tray<br/>menu-bar shell<br/>[tray.rs]"]
  node_native_tray["Native tray<br/>macos bridge<br/>[native_tray.rs]"]
  node_animation(("Animation<br/>icon motion<br/>[animation.rs]"))
end

subgraph group_frontend["React frontend"]
  node_app["App shell<br/>react root<br/>[App.tsx]"]
  node_hooks["Data hooks<br/>react bridge<br/>[useAgentUsage.ts]"]
  node_lib_usage["Usage models<br/>ui model<br/>[usage.ts]"]
  node_components_cards["Dashboard cards<br/>ui panels<br/>[TokenUsageCard.tsx]"]
  node_dashboard_tabs["Tabs<br/>navigation ui<br/>[DashboardTabs.tsx]"]
  node_usage_graph_card["Graphs<br/>visualization ui"]
  node_live_card["Live trace<br/>status ui<br/>[UsageTraceCard.tsx]"]
  node_limits_settings["Limits and settings<br/>control ui"]
end

subgraph group_surface["Product surface"]
  node_release_media["Release media<br/>docs assets<br/>[index.html]"]
end

node_src_tauri_main -->|"boots"| node_src_tauri_lib
node_src_tauri_lib -->|"owns"| node_state
node_agent_usage -->|"updates"| node_state
node_usage_tail -->|"streams"| node_state
node_usage_graph -->|"summarizes"| node_state
node_tray -->|"delegates"| node_native_tray
node_tray -->|"animates"| node_animation
node_app -->|"consumes"| node_hooks
node_hooks -->|"subscribes"| node_state
node_hooks -->|"transforms"| node_lib_usage
node_app -->|"composes"| node_components_cards
node_components_cards -->|"includes"| node_dashboard_tabs
node_components_cards -->|"includes"| node_usage_graph_card
node_components_cards -->|"includes"| node_live_card
node_components_cards -->|"includes"| node_limits_settings
node_release_media -.->|"documents"| node_app

click node_src_tauri_main "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/main.rs"
click node_src_tauri_lib "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/lib.rs"
click node_state "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/state.rs"
click node_agent_usage "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/agent_usage.rs"
click node_usage_tail "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/usage_tail.rs"
click node_usage_graph "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/usage_graph.rs"
click node_tray "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/tray.rs"
click node_native_tray "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/native_tray.rs"
click node_animation "https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/animation.rs"
click node_app "https://github.com/handlecusion/tokcat/blob/main/src/App.tsx"
click node_hooks "https://github.com/handlecusion/tokcat/blob/main/src/hooks/useAgentUsage.ts"
click node_lib_usage "https://github.com/handlecusion/tokcat/blob/main/src/lib/usage.ts"
click node_components_cards "https://github.com/handlecusion/tokcat/blob/main/src/components/TokenUsageCard.tsx"
click node_dashboard_tabs "https://github.com/handlecusion/tokcat/blob/main/src/components/DashboardTabs.tsx"
click node_usage_graph_card "https://github.com/handlecusion/tokcat/blob/main/src/components/UsageBarGraph2D.tsx"
click node_live_card "https://github.com/handlecusion/tokcat/blob/main/src/components/UsageTraceCard.tsx"
click node_limits_settings "https://github.com/handlecusion/tokcat/blob/main/src/components/AgentLimitsCard.tsx"
click node_release_media "https://github.com/handlecusion/tokcat/blob/main/docs/index.html"

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_src_tauri_main,node_src_tauri_lib,node_state,node_agent_usage,node_usage_tail,node_usage_graph,node_tray,node_native_tray,node_animation toneBlue
class node_app,node_hooks,node_lib_usage,node_components_cards,node_dashboard_tabs,node_usage_graph_card,node_live_card,node_limits_settings toneAmber
class node_release_media toneMint
```

## Components

### Native backend

Rust Tauri shell for local ingestion, state, tray behavior, and live signals.

- [Main](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/main.rs): tauri entry · Starts the native app and wires the Rust runtime together. · `src-tauri/src/main.rs`
- [Lib](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/lib.rs): tauri module · Shared native module wiring for commands and backend integration. · `src-tauri/src/lib.rs`
- [State](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/state.rs): app state · Central cached state and settings shared across backend features. · `src-tauri/src/state.rs`
- [Usage ingest](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/agent_usage.rs): log parser · Reads and normalizes local AI client usage logs into structured records. · `src-tauri/src/agent_usage.rs`
- [Live tail](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/usage_tail.rs): stream tail · Tracks recent log growth and derives short-window live activity. · `src-tauri/src/usage_tail.rs`
- [Usage graph](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/usage_graph.rs): aggregation · Builds historical usage summaries and graph-ready data. · `src-tauri/src/usage_graph.rs`
- [Tray](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/tray.rs): menu-bar shell · Owns macOS tray behavior and menu actions. · `src-tauri/src/tray.rs`
- [Native tray](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/native_tray.rs): macos bridge · Platform-specific tray and window integration. · `src-tauri/src/native_tray.rs`
- [Animation](https://github.com/handlecusion/tokcat/blob/main/src-tauri/src/animation.rs): icon motion · Drives optional animated tray/icon states. · `src-tauri/src/animation.rs`

### React frontend

Dashboard UI that consumes backend state and renders usage, graphs, and settings.

- [App shell](https://github.com/handlecusion/tokcat/blob/main/src/App.tsx): react root · Top-level frontend shell and layout orchestration. · `src/App.tsx`
- [Data hooks](https://github.com/handlecusion/tokcat/blob/main/src/hooks/useAgentUsage.ts): react bridge · Hooks that connect backend streams and graph state to React. · `src/hooks/useAgentUsage.ts`
- [Usage models](https://github.com/handlecusion/tokcat/blob/main/src/lib/usage.ts): ui model · Frontend transformations, formatting, stats, streaks, themes, and updater helpers. · `src/lib/usage.ts`
- [Dashboard cards](https://github.com/handlecusion/tokcat/blob/main/src/components/TokenUsageCard.tsx): ui panels · Main dashboard views for usage, graphs, live traces, limits, and settings. · `src/components/TokenUsageCard.tsx`
- [Tabs](https://github.com/handlecusion/tokcat/blob/main/src/components/DashboardTabs.tsx): navigation ui · Switches between overview and client-focused dashboard views. · `src/components/DashboardTabs.tsx`
- [Graphs](https://github.com/handlecusion/tokcat/blob/main/src/components/UsageBarGraph2D.tsx): visualization ui · 2D and 3D usage visualizations. · `src/components/UsageBarGraph2D.tsx`
- [Live trace](https://github.com/handlecusion/tokcat/blob/main/src/components/UsageTraceCard.tsx): status ui · Shows live session activity and throughput. · `src/components/UsageTraceCard.tsx`
- [Limits and settings](https://github.com/handlecusion/tokcat/blob/main/src/components/AgentLimitsCard.tsx): control ui · Displays vendor quota cards and app configuration controls. · `src/components/AgentLimitsCard.tsx`

### Product surface

Release, docs, and generated media that support packaging and distribution.

- [Release media](https://github.com/handlecusion/tokcat/blob/main/docs/index.html): docs assets · Landing docs, screenshots, generated motion, and release support files. · `docs/index.html`

## Connections

- Main → Lib: boots · Main starts the shared Rust app layer.
- Lib → State: owns · The native layer centers on shared app state.
- Usage ingest → State: updates · Parsed historical usage is cached into app state.
- Live tail → State: streams · Live tail updates short-window activity state.
- Usage graph → State: summarizes · Aggregated graphs are derived from shared usage state.
- Tray → Native tray: delegates · Tray behavior uses platform-specific macOS integration.
- Tray → Animation: animates · Menu-bar icon motion is driven from the tray layer.
- App shell → Data hooks: consumes · The React shell reads backend-fed state through hooks.
- Data hooks → State: subscribes · Hooks bridge into the authoritative backend state.
- Data hooks → Usage models: transforms · Raw backend data is reshaped for presentation.
- App shell → Dashboard cards: composes · The app shell assembles the dashboard panels.
- Dashboard cards → Tabs: includes · The dashboard uses tabs for major views.
- Dashboard cards → Graphs: includes · Usage visualizations are part of the dashboard surface.
- Dashboard cards → Live trace: includes · Live activity is shown as a dedicated card.
- Dashboard cards → Limits and settings: includes · Quota cards and settings controls sit in the same UI surface.
- Release media → App shell: documents · Docs and generated media support the product presentation.
