MCPcopy Index your code
hub / github.com/akitaonrails/ai-usagebar

github.com/akitaonrails/ai-usagebar @v0.11.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.11.0 ↗ · + Follow
776 symbols 2,271 edges 55 files 135 documented · 17% updated 2d agov0.11.0 · 2026-07-06★ 176
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

ai-usagebar

Waybar widget and tabbed TUI for AI plan usage across Anthropic Claude, OpenAI Codex/ChatGPT, Z.AI (GLM), OpenRouter, and DeepSeek.

This started as a Rust port of claudebar and stays drop-in compatible with it. It keeps the minimalist Pango-bordered tooltip, Omarchy theme auto-detection, and flock-protected OAuth refresh, then adds three more vendors and a proper testable codebase instead of one long shell script.

Waybar widget showing cld 29% · 1h 12m in the top-right, with the hover tooltip showing Claude Max 20x session/weekly/sonnet/extra-usage progress bars

Features

  • Per-vendor Waybar modules with the same JSON shape as claudebar.
  • Tabbed TUI (ai-usagebar-tui) with Tab/h/l switching, per-tab refresh, and 60-second auto-refresh. Native ratatui widgets fill the available terminal width and keep the vendor tabs visually consistent.
  • Scroll-to-cycle on the bar: wire on-scroll-up / on-scroll-down, and one bar item cycles through your enabled vendors.
  • Config-driven primary vendor: set [ui] primary once; the widget shows that vendor by default and the TUI opens on its tab.
  • Local testing tools: --pretty renders ANSI-colored terminal output (auto-detects TTY), and --watch N re-renders every N seconds.
  • Drop-in claudebar compatibility with the same flags (--icon, --format, --tooltip-format, --pace-tolerance, --format-pace-color, --tooltip-pace-pts, --color-*) and {placeholders}.
  • Always exits 0, because Waybar hides modules that don't.
  • Atomic cache writes + flock, so multi-monitor Waybar instances can coexist without API stampedes.
  • Separate transient and hard errors: DNS/timeout failures show a quiet Loading…; HTTP 4xx/5xx errors put the code in the tooltip.
  • Live API smoke tests: make smoke hits the real undocumented endpoints and catches schema drift early.

Install

Arch (AUR)

Two packages. Pick one:

yay -S ai-usagebar-bin    # prebuilt binary from GitHub Releases (fast, ~5s install)
yay -S ai-usagebar        # compiles from source (~30-60s, hermetic)

The -bin variant downloads the same x86_64 ELF that CI built and tested. The source variant compiles locally with your toolchain. Both install identical binaries to /usr/bin/. If you already have one installed, switch with yay -S the other package; pacman handles the swap through conflicts/provides.

Other Linux / macOS (crates.io)

cargo install ai-usagebar                # compile from source (needs rustup)
cargo binstall ai-usagebar               # download prebuilt binary (needs cargo-binstall, no rustup)

cargo binstall fetches the same x86_64 / aarch64 Linux tarball the AUR -bin package uses. Both install ai-usagebar + ai-usagebar-tui to ~/.cargo/bin/.

From source

cargo build --release
sudo make install                  # → /usr/local/bin
# or
make install PREFIX=$HOME/.local   # → ~/.local/bin

Windows

The Waybar widget is Wayland-only and does not apply to Windows. The ai-usagebar-tui binary, however, runs natively, and ai-usagebar --json / --pretty work too (handy for feeding a custom tray/widget). Build with a standard Rust toolchain:

cargo build --release
# binaries land in target\release\ai-usagebar.exe and ai-usagebar-tui.exe

Credentials are read from the Windows user profile rather than $HOME: %USERPROFILE%\.claude\.credentials.json (Anthropic) and %USERPROFILE%\.codex\auth.json (OpenAI Codex). Run the official claude / codex CLI once on Windows to populate them, exactly as on Linux/macOS. API-key vendors (Z.AI, OpenRouter, DeepSeek) work unchanged via environment variables or config.toml.

Authentication

Each vendor authenticates a little differently. Anthropic and OpenAI use OAuth credentials that their official CLIs already wrote to disk, so no env vars are needed. Z.AI and OpenRouter use API keys. You can pass those through env vars or, if you don't source secrets in your shell, put them inline in config.toml.

Vendor Method Action required
Anthropic OAuth, read from ~/.claude/.credentials.json (or the macOS login Keychain — see below) Run claude once to log in. Token auto-refreshes.
OpenAI OAuth, read from ~/.codex/auth.json Run codex login once. Token auto-refreshes.
Z.AI API key (ZAI_API_KEY env or [zai] api_key in config) Set either.
OpenRouter API key (OPENROUTER_API_KEY env or [openrouter] api_key in config) Set either.
DeepSeek API key (DEEPSEEK_API_KEY env or [deepseek] api_key in config) Set either. Disabled by default — add [deepseek] enabled = true to config.

Credential resolution order (for API-key vendors)

For each API-key vendor, ai-usagebar checks in this order:

  1. Env var named by api_key_env in config (defaults: ZAI_API_KEY, OPENROUTER_API_KEY). If set + non-empty, used.
  2. Inline api_key in the same config section.
  3. Otherwise, error with a message naming both options.

Security

  • If you put inline api_key values in config, chmod 600 ~/.config/ai-usagebar/config.toml. The default behavior reads only env vars, which is safer when your config might be world-readable.
  • Don't commit your config dir if you check it into dotfiles unless you've redacted api_key lines.
  • OAuth credential files (~/.claude/.credentials.json, ~/.codex/auth.json) are managed by their respective CLIs and already chmod-protected.

macOS: Anthropic credentials in the Keychain

On macOS, recent Claude Code builds don't write ~/.claude/.credentials.json — they keep the same OAuth JSON in the login Keychain under the generic-password service Claude Code-credentials. ai-usagebar detects the missing file and transparently reads (and writes refreshed tokens back to) that Keychain item via the built-in security tool, so no manual step is needed. If the file does exist it still takes precedence, matching Linux.

Configuration

~/.config/ai-usagebar/config.toml (optional — defaults enable Anthropic, OpenAI, Z.AI, and OpenRouter; DeepSeek is opt-in). Full example:

[ui]
# Which vendor the widget shows when --vendor is omitted, AND which tab
# is selected when the TUI opens. Defaults to anthropic when not set.
# primary = "anthropic"   # anthropic | openai | zai | openrouter | deepseek

[anthropic]
enabled = true
# credentials_path = "/home/you/.claude/.credentials.json"

[openai]
enabled = true
# codex_auth_path = "/home/you/.codex/auth.json"

[zai]
enabled = true
api_key_env = "ZAI_API_KEY"
# api_key = "..."          # used if ZAI_API_KEY is unset; chmod 600 the file!
# plan_tier = "lite"       # lite | pro | max — display-only

[openrouter]
enabled = true
api_key_env = "OPENROUTER_API_KEY"
# api_key = "sk-or-v1-..."

[deepseek]
enabled = true             # disabled by default; enable once you add an API key
api_key_env = "DEEPSEEK_API_KEY"
# api_key = "sk-..."       # used if DEEPSEEK_API_KEY is unset; chmod 600 the file!

Quick start

# Local testing — auto-detects TTY and renders human-readable output.
ai-usagebar                        # uses [ui] primary (defaults to anthropic)
ai-usagebar --vendor openai
ai-usagebar --vendor zai
ai-usagebar --vendor openrouter
ai-usagebar --vendor deepseek

# Force Waybar JSON (e.g. piping into jq).
ai-usagebar --json

# Live preview while iterating on --format / --tooltip-format.
ai-usagebar --vendor openrouter --watch 5

# Interactive TUI with tabs.
ai-usagebar-tui

Standalone TUI — no Waybar required

The two binaries are independent. If you don't run Waybar (or just want to check usage occasionally rather than have it on your bar permanently), ai-usagebar-tui works as a fully standalone terminal app:

ai-usagebar-tui                    # opens in your current terminal

It runs in any terminal emulator (Kitty, Alacritty, Foot, Ghostty, etc.), works in plain SSH sessions, and doesn't need a compositor or window manager integration. All controls and the Settings overlay work the same way. Use it as:

  • An ad-hoc check ("am I close to my Claude weekly limit before I start a long session?")
  • A foreground monitor on a secondary screen or tmux pane while you code
  • A shell-only tool on remote machines (just install the binary; no Waybar/Hyprland dependencies)

The Waybar widget is optional. The TUI is the best way to see every enabled vendor at once, even if you never set up the widget.

Waybar config

Single module, scroll-to-cycle (recommended)

Use one bar item and scroll through your vendors. The TUI on-click still shows them all:

"modules-right": ["custom/aibar", ...],

"custom/aibar": {
    "exec": "ai-usagebar --format '{vendor_short} {session_pct}% · {session_reset}'",
    "return-type": "json",
    "interval": 300,
    "signal": 13,
    "tooltip": true,
    "on-click": "ai-usagebar-tui",
    "on-scroll-up":   "ai-usagebar --cycle-next",
    "on-scroll-down": "ai-usagebar --cycle-prev"
}

The {vendor_short} placeholder always expands to a 3-letter vendor ID (cld / gpt / zai / opr / dsk), so the bar text tells you which vendor is active. The other usage placeholders ({session_pct} for Anthropic, {oai_session_pct} for OpenAI, etc.) are vendor-specific. If you want one format string for every cycled vendor, prefer the generic placeholders where available. For now, {session_pct} works for Anthropic only; the other vendors expose their own {oai_*} / {zai_*} / {or_*} / {ds_*} families, which expand to empty strings for vendors that don't define them.

signal: 13 lets the scroll-cycle commands refresh the bar instantly (via SIGRTMIN+13) instead of waiting for the next 300s interval.

If your Waybar theme puts a tray expander immediately after custom/aibar, such as Omarchy's group/tray-expander with custom/expand-icon, the usage text can sit very close to the expand icon. Add right padding for the module in your Waybar CSS if you want extra spacing:

#custom-aibar {
    padding-right: 18px;
}

Per-vendor modules

If you'd rather see them all at once:

"modules-right": ["custom/claude", "custom/openai", "custom/openrouter", "custom/zai", "custom/deepseek"],

"custom/claude": {
    "exec": "ai-usagebar --vendor anthropic --icon '󰚩'",
    "return-type": "json",
    "interval": 300,
    "tooltip": true,
    "on-click": "ai-usagebar-tui"
},
"custom/openai": {
    "exec": "ai-usagebar --vendor openai --icon '󱢆'",
    "return-type": "json",
    "interval": 300,
    "tooltip": true
},
"custom/openrouter": {
    "exec": "ai-usagebar --vendor openrouter --icon '󱙺' --format '{or_balance} · {or_used_today}'",
    "return-type": "json",
    "interval": 600,
    "tooltip": true
},
"custom/zai": {
    "exec": "ai-usagebar --vendor zai --icon '󰚩'",
    "return-type": "json",
    "interval": 300,
    "tooltip": true
},
"custom/deepseek": {
    "exec": "ai-usagebar --vendor deepseek --icon '󰧑'",
    "return-type": "json",
    "interval": 600,
    "tooltip": true
}

Why 300s? The Anthropic and OpenAI Codex endpoints are undocumented and rate-limit aggressively below ~300s. The cache TTL is 60s so multi-monitor instances coexist, but Waybar's polling interval should stay at 300s.

Multiple accounts (advanced)

To watch more than one account of the same vendor — say a personal and a work Claude subscription — run one module per account, giving each its own credentials file and its own cache directory:

"modules-right": ["custom/claude-personal", "custom/claude-work", ...],

"custom/claude-personal": {
    "exec": "ai-usagebar --vendor anthropic --icon '󰚩' --format 'p {session_pct}% · {session_reset}'",
    "return-type": "json",
    "interval": 300,
    "tooltip": true
},
"custom/claude-work": {
    "exec": "ai-usagebar --vendor anthropic --icon '󰚩' --format 'w {session_pct}% · {session_reset}' --creds-path ~/.config/ai-usagebar/accounts/work.credentials.json --cache-dir ~/.cache/ai-usagebar/anthropic-work",
    "return-type": "json",
    "interval": 300,
    "tooltip": true
}
  • --creds-path points the module at a different OAuth credentials file (same JSON shape Claude Code writes). To capture a second account's file, log in with claude under that account and copy ~/.claude/.credentials.json somewhere stable — token refreshes are written back to whatever file the flag names, so each account keeps itself alive independently. chmod 600 the copies.
  • --cache-dir gives the module a private cache so the two accounts don't overwrite each other's 60-second cache window. Any directory works; the per-vendor default is ~/.cache/ai-usagebar/<vendor>.
  • --creds-path currently applies to the Anthropic vendor only. For API-key vendors (Z.AI, OpenRouter, DeepSeek) point each module at a different key via a wrapper script that sets the env var, plus its own --cache-dir.
  • The TUI shows the default Claude tab plus one tab per configured [[anthropic.accounts]] entry (see the config example below); Tab / h / l cycle through them like any other tab.
  • On macOS, the login Keychain can hold only one Claude credential per OS user, so additional accounts must be file-based as shown above.

Config-driven accounts (--account)

Instead of repeating --creds-path/--cache-dir on every module, name your extra Anthropic accounts once in config and select them with --account <label>:

```toml [anthropic]

The default account. --vendor anthropic with no --account uses this,

exactly as before. Optional — falls back to ~/.claude/.credentials.json.

credentials_path = "~/.claude/.credentials.json"

[[anthropic.accounts]] label = "work" credentials_path = "~/.config/ai-usagebar/accounts/work.json"

[[anthropic.accounts]]

Core symbols most depended-on inside this repo

path
called by 51
src/anthropic/creds.rs
now
called by 46
src/tui/panels.rs
at
called by 21
src/pacing.rs
progress_bar
called by 21
src/pango.rs
calc
called by 19
src/pacing.rs
fetch_snapshot
called by 19
src/zai/fetch.rs
severity_color
called by 19
src/tui/style.rs
severity_for
called by 18
src/pango.rs

Shape

Function 569
Method 121
Class 71
Enum 15

Languages

Rust94%
TypeScript6%

Modules by API surface

src/tui/settings.rs46 symbols
src/anthropic/creds.rs40 symbols
src/config.rs37 symbols
src/cache.rs37 symbols
gnome-extension/extension.js31 symbols
src/widget/run.rs29 symbols
src/usage.rs27 symbols
src/tui/app.rs25 symbols
src/widget/render.rs23 symbols
src/tui/panels.rs23 symbols
src/theme.rs21 symbols
src/pango.rs20 symbols

For agents

$ claude mcp add ai-usagebar \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page