The Problem
If you're using AI coding agents seriously, you're probably juggling multiple subscriptions. Claude Code for the heavy thinking. Codex for quick iterations. Gemini for a different flavor. Maybe a second Claude account for a different project, or a second Gemini tied to another Google account.
Each tool tracks its own usage in its own way. Claude has a percentage buried in a settings page. Codex has a /status command inside its TUI. Gemini has /stats. None of them talk to each other, and none of them show you the one thing you actually want to know: how much do I have left, and when does it reset?
What I Built
The CLI Usage Tracker is a Python/tkinter desktop dashboard that pulls usage data from all three providers and displays it in a single window. Each AI agent gets its own card with a progress bar, reset timer, and per-model breakdown.
Key Features
- Multi-agent support — Track claude + claude2, gemini + gemini2, codex, all in one view
- Auto-detection — On first launch, scans your system for all installed CLI agents
- Progress bars — Blue bar shows target pace, green shows actual usage
- Per-model breakdowns — See Opus vs. Sonnet vs. Haiku costs, individual Gemini model limits
- Reset timers — Know exactly when your quota refreshes
- Ephemeral password helper — Securely pass credentials to AI agents
How It Gets the Data
Each provider requires a different approach. There's no unified API for "how much AI quota do I have left," so the tracker has to get creative.
Claude
Claude Code stores telemetry locally in ~/.claude/telemetry/ as JSONL files. The tracker reads these to get per-model token counts over the past 7 days. Since there's no direct API for the usage percentage, you calibrate it manually — enter the percentage from claude.ai/settings/usage once, and the tracker extrapolates from there using your reset window.
Codex
Codex doesn't expose usage data through files or an API. The tracker spawns a headless Codex session, sends the /status command, and reads the console buffer via a PowerShell script. It captures the 5-hour and weekly remaining percentages, Spark tier status, and reset times.
Gemini
Similar to Codex — the tracker runs /stats inside a headless Gemini session. It parses per-model remaining percentages and reset timers for all Gemini models (2.5 Pro, Flash, etc.).
Multi-Account Support
This was the interesting engineering challenge. Each provider handles multiple accounts differently:
- Claude — Each instance uses a separate
CLAUDE_CONFIG_DIRpointing to its own data directory (~/.claude,~/.claude2, etc.) - Gemini — Uses the
GEMINI_CLI_HOMEenvironment variable. I created wrapper.cmdscripts (likegemini2.cmd) that set this variable before launching the CLI, so each instance authenticates with a different Google account via OAuth. - Codex — Separate binaries or npm installs, each pointing to their own OpenAI credentials.
The config stores an agents list where each entry specifies the binary, data directory, and any provider-specific overrides. The first-launch wizard auto-detects everything and lets you assign labels.
The Paranoid Password Helper
One practical problem with AI agents: sometimes you need to pass them a credential (SSH password, API key, etc.) without it ending up in a chat log or commit history. The built-in password helper handles this with a belt-and-suspenders approach:
- Random location — The file lands in a random directory (
%TEMP%,%TEMP%\logs,AppData\Local\Temp\diagnostics, etc.) - Random disguise — Filename looks like system junk:
svc_a8k3mf2p.log,diag_x9nqw4.etl,proc_bk2m7.dmp - Junk tail — After the secret, 20-60 lines of fake log entries, stack traces, and hex dumps are appended. The file looks like a boring diagnostic dump.
- Auto-wipe — The file self-deletes after a configurable TTL (default 30s), and the content hash is checked before deletion to detect tampering.
- Clipboard clear — The clipboard message pointing to the file is wiped after 45 seconds.
- Input auto-clear — The password entry field clears itself after 2 minutes of inactivity.
The agent receives a clipboard message like "Secret is in C:\Users\...\diag_x9nqw4.etl. Read it once and do not repeat it." The file's header instructs the agent to ignore the junk tail and use the credential silently. An attacker watching the filesystem would need to know which directory, which randomly-named file, and which few lines contain the actual secret — all before the TTL expires.
Architecture
The app is a single Python file (~2500 lines) with no external dependencies beyond the standard library. Optional pywinpty improves console buffer reading on Windows. The threaded refresh system spawns one worker per agent in parallel, and results are applied to the UI on the main thread.
config.json (per-user, .gitignored)
└── agents: [
{ id: "claude_1", type: "claude", binary: "claude", data_dir: "~/.claude", ... },
{ id: "gemini_2", type: "gemini", gemini_cmd: "gemini2.cmd", ... },
...
]
ai_usage_tracker.py
├── detect_agents() → scan system for CLI agents
├── SetupWizard → first-launch config UI
├── UsageWidget → main dashboard with scrollable cards
├── run_*_console_status() → headless TUI → console buffer → parse
├── parse_*_telemetry() → local file parsing (Claude)
└── password helper → ephemeral file + clipboard + auto-wipe
Try It
The tracker is open source and works on Windows with Python 3.10+. Clone, run, and it auto-detects your agents:
git clone https://github.com/benolenick/cli_usage_tracker.git
cd cli_usage_tracker
python ai_usage_tracker.py
If you're running multiple AI agent accounts and tired of checking three different dashboards, give it a shot.