A unified AI-quota dashboard — OpenRouter · Gemini · Codex · Claude · Copilot · Kiro, all in one TUI.
Languages: English · 简体中文 · 繁體中文
- ✅ Provider abstraction (
Usage/Window/Credits/SubQuota) - ✅ Local-availability detection — only show providers whose credentials exist on this machine
- ✅
oneshot(plain text) andjsonoutput for scripting - ✅ OpenRouter — API key via
/api/v1/auth/key - ✅ Gemini — OAuth creds + auto-refresh +
retrieveUserQuota(ported from the Python tool) - ✅ Kiro — shells out to
kiro-cli chat --no-interactive /usage, regex-extracts - ✅ Copilot — GitHub token (env /
gh auth token) →/copilot_internal/user; handles paid (quota_snapshots) and free-limited (monthly_quotas) tiers - ✅ Claude — macOS Keychain (
Claude Code-credentials) for plan/tier; tallies~/.claude/projects/*.jsonlinto 5h session + 7d weekly token counts (Anthropic doesn't publish quotas → no gauge, only raw numbers) - ✅ Codex —
~/.codex/auth.jsonOAuth; decodesid_tokenJWT for account/plan (ChatGPT usage API not public → account + plan + token freshness only) - ✅ TUI (ratatui) — card layout, concurrent fetch, live refresh
- ✅ i18n — English / 简体中文 / 繁體中文, data-driven via
rust-i18n+locales/app.yml
cargo install --path .
# or directly from GitHub
cargo install --git https://github.com/wangyuyan-agent/aitopBy default, aitop launches the TUI and only shows providers whose credentials are found locally. Pass --all to reveal every provider (including the unimplemented ones).
aitop # TUI, auto-filtered
aitop --all # TUI, show every provider
aitop --lang en # force English (defaults to $AITOP_LANG / $LANG)
aitop --lang zh-TW # force Traditional Chinese
# Scripting / CI
aitop oneshot # text, detected providers only
aitop oneshot --provider all # text, every provider
aitop oneshot --provider openrouter # single provider
aitop json --pretty # machine-readable
aitop json --provider gemini,openrouter
# Single-provider live watcher
aitop watch gemini --interval 30TUI keys: q / Ctrl-C quit · r refresh · ↑↓ / jk navigate · g / G jump to top/bottom.
| Provider | Source | How to detect |
|---|---|---|
| OpenRouter | env OPENROUTER_API_KEY |
env var set and non-empty |
| Gemini | ~/.gemini/oauth_creds.json |
file exists (run gemini CLI once to log in) |
| Kiro | kiro-cli on PATH |
which kiro-cli succeeds (override with KIRO_CLI_BIN) |
| Copilot | env GITHUB_TOKEN / GH_TOKEN / COPILOT_API_TOKEN, or gh on PATH |
env var set, or which gh succeeds |
| Claude | macOS Keychain Claude Code-credentials or ~/.claude/.credentials.json or ~/.claude/projects/ |
any of the three present |
| Codex | ~/.codex/auth.json (override: CODEX_HOME) |
file exists and parses with tokens field |
detect() does local I/O only — no network requests — so unconfigured providers can be filtered out instantly at startup.
cargo run # TUI (auto-filtered)
cargo run -- --all # TUI (every provider)
cargo run -- oneshot
cargo run -- json --pretty
RUST_LOG=debug cargo runsrc/providers/mod.rs— unified data model +Providertrait +Availabilitydetection + selectorsrc/providers/<name>.rs— per-provider implementation (async_trait, each owns its own auth path)src/ui/— ratatui layer (header · provider cards · footer)src/lang.rs— language detection; parses--lang/$AITOP_LANG/$LANGand pushes the BCP 47 code intorust-i18nlocales/app.yml— every user-facing string, one YAML entry per key with columns for each supported locale
Each provider returns a Usage struct. Text rendering, JSON serialization, and TUI painting all live above the provider layer.
All user-facing strings live in locales/app.yml, loaded at compile time by rust-i18n. Adding another language takes three steps:
- Add a new column (e.g.
ja:) to every entry inlocales/app.yml. - Add a
Lang::Javariant tosrc/lang.rs(code,parse,detect). - Rebuild — no runtime code changes needed.
Locale precedence at startup: --lang flag → $AITOP_LANG → $LANG / $LC_ALL → English.
MIT