# AI Usage Bar — macOS menu bar app The product UI is **`ai-usagebar-tray`**: an NSStatusItem plus a WKWebView popover. **Settings → Appearance → Popover Style** picks its look: **Classic** (every provider's card at a glance, the default) or **Native** (the system's own look — on macOS, one provider at a time behind tabs of logos and values, over AppKit glass). Both draw the same provider card: metrics, reset times, pace notes, the reset popover, the row menu and account switching. The menu-bar item shows the metrics you star in each provider (up to two): **Settings → Menu Bar → Menu Bar Shows** draws them as the usage **Chart** (the default) or as **Logos**, each starred provider's logo followed by its value, two starred metrics stacked. With nothing starred it shows the app icon. Left-click opens the popover; right-click opens the Options menu. ```bash cargo build --release --bin ai-usagebar-tray ./target/release/ai-usagebar-tray ``` Needs Node.js 20+ on PATH for the first build (`windows/popover/` Vite bundle). Left-click the status item to toggle the popover. Right-click it for the footer's Options menu as a native menu, in the popover's language: Customize (Classic only), Settings, Refresh, Detect Providers, Open TUI, Start at Login, Check for Updates, About, and Quit; the items that name a screen open the popover on it. No Dock icon. ![Right-click menu under the menu bar icon — Customize, Settings, Refresh, Detect Providers, Open TUI, Start at Login (checked), Check for Updates, About and Quit](../screenshots/macos-tray-right-click-menu.png) ![Chart mode in the macOS menu bar, next to the Cursor, Claude, Antigravity, Codex and Claude Code icons](../screenshots/macos-tray-icon.png) Star up to two metrics per provider from **Settings → Providers**, then open that provider's details, or right-click a row. Those metrics are what the status item shows. With named Claude or Codex accounts, each account's card also shows which login is active (a filled star) and an outline star to switch to the others; see "Switch from the macOS menu bar" in [docs/claude-accounts.md](../docs/claude-accounts.md). ![Customize Claude — Always Visible rows Weekly (starred) and Fable, On Demand row Session, each with a star and an on/off switch, Back and Reset in the top bar](../screenshots/macos-tray-provider-stars.png) The footer's Options menu opens Settings. Settings uses five tabs: **General** (startup, refresh, shortcut), **Providers** (visibility, order, metric details), **Menu** (the menu-bar summary), **Preferences** (language, appearance, usage display), and **Alerts** (system notifications and the quota threshold). Start at Login writes a LaunchAgent under `~/Library/LaunchAgents`. Alerts are sent through macOS Notification Center after a fresh reading crosses the threshold. In **Preferences → Usage Display**, enable **Usage goal** to show a second, subtle bar below each metric. It marks how much of the quota would be used now at an even pace from the start of its reset window to 100% at the end. Five-hour, weekly, and other windows use the provider's reported duration. Monthly windows without an exact duration use the previous calendar month and are labeled as estimates. The current usage and goal percentages sit at the right edge of their respective bars. The reset note below them can include the projected usage at the end of the window; **Always Show Pacing** makes that projection visible even for metrics comfortably below the limit. Metrics without a reset time or usable window do not show a goal. A legacy Swift `NSMenu` (`ai-usagebar-menubar.swift`) remains in this folder for the old dropdown. Prefer the tray. > **Installing?** Follow the step-by-step in **[INSTALL.md](INSTALL.md)**. ## Vendor scope The selector dynamically discovers **all providers** that ship in the binary via `ai-usagebar vendors --json`: - **Rate-limit windows (session / weekly / monthly):** Claude, Codex, Z.AI (GLM), Google Antigravity (two independent pools — Gemini, and Claude & GPT OSS — each with its own 5h/weekly pair), MiniMax (chat and video pools, each with 5h/weekly tracking), GitHub Copilot (premium finite pool, with unlimited chat and completions reported cleanly), SuperGrok, Kiro, Nous Research, OpenCode Go (session, weekly, and monthly pools), Command Code (session, weekly, and monthly pools), and Grok Bot (weekly included-usage pool from the Grok Bot desktop app). - **Included-usage pools:** Cursor (Cursor Models and Other Models, both reset on the billing cycle). - **Balance-only:** OpenRouter, DeepSeek, Kimi, Kilo, Novita, Moonshot, Grok (xAI), and Anthropic API. These have no 5h/weekly quota windows, so the app shows their balance/credits in the header (`cr `) and suppresses the session/weekly rows. Anthropic API additionally renders a spend-vs-limit bar when a monthly limit is configured. The app uses `ai-usagebar vendors --json` as its canonical metadata source so vendor availability, authentication status, and CLI requirements always match the backend without duplicated static tables. Only **enabled** vendors appear in the selector. The opt-in vendors default to disabled in the Rust config, matching `src/config.rs`; set `[vendor].enabled = true` (or save an API key via the TUI) to turn one on. Antigravity has no credential file to check, so the Vendors pane treats it as **configured** once it finds any of Antigravity 2.0/IDE/`agy`'s state directories (`~/.gemini/{antigravity,antigravity-cli,antigravity-ide}`) — the binary itself discovers whichever local server is actually reachable (Antigravity 2.0, the IDE, or an interactive `agy` session) via `lsof` at fetch time, so one of those must be running for quota to load. ## Requirements - Rust (`rustc` 1.90+) and **Node.js 20+** (the tray embeds the Vite popover). - Run `claude` once on the Mac so its OAuth creds are in the login **Keychain**; ai-usagebar reads them there automatically (no env vars). ## Build & run ```bash cargo build --release --bin ai-usagebar-tray ./target/release/ai-usagebar-tray ``` Start at login from the popover **Settings → Launch at Login**. That writes `~/Library/LaunchAgents/com.akitaonrails.ai-usagebar-tray.plist`. The legacy Swift dropdown: ```bash cd macos ./build.sh ./ai-usagebar-menubar & ``` > Not code-signed. It's a local binary you built yourself, so Gatekeeper > doesn't block it when launched from the terminal / LaunchAgent. If macOS ever > complains, right-click the binary in Finder → **Open** once. ## Configuration Open **Preferences** from the dropdown (or press **⌘,**) — a native window with toggles, color pickers, vendor, interval, bar width, and binary path. Settings persist in `UserDefaults` and apply **live, no rebuild**. | Setting | Default | Notes | |---|---|---| | Show 5h / weekly / extra | on / on / off | which bars appear | | Show percentage/value | on | numeric value next to each bar | | Show bars | on | off = numbers only | | Show pace marker | on | persisted `showMeta`; draws the elapsed-time marker only when the window has reset and elapsed output | | Show reset time instead of a countdown | off | persisted `showResetClock`; shows *when* a window resets as a wall-clock time — a date once the reset is past today — following the system's 12h/24h convention | | Bar width | 8 | cells per menu-bar bar (4–20) | | Colors (low/mid/high/critical/empty) | One Dark | bar color per severity (≥90 / ≥75 / ≥50 / else) | | Refresh interval | 30 s | 5–3600 | | Vendor | anthropic | selectors: only enabled vendors (see [Vendor scope](#vendor-scope)). Vendors expose rate-limit windows (session, weekly, monthly, or video pools); balance-only vendors show a credit balance instead. | | Binary path | auto | empty = `~/.cargo/bin`, Homebrew, then `PATH` | | Global vendor shortcut | on | **⌥⌘\\** cycles every configured vendor/account and Overview; turns itself back off if macOS cannot register it | | Global compact shortcut | on | **⌥⌘E** toggles Overview between mini bars and compact text; turns itself back off if unavailable | | Start at login | current LaunchAgent state | writes/removes the per-user LaunchAgent; write errors are shown below the toggle | `[ui] overview_vendors = ["anthropic", "cursor", "openai"]` in `config.toml` limits and orders the Overview on macOS exactly as it does in the TUI. Requesting `anthropic` includes every configured named Claude account. In Overview mode, each dropdown row is a **checkbox**: click it to drop that provider from the always-visible top-bar summary (checkmark = shown; unchecked + dimmed = hidden). Hidden providers stay listed so you can re-enable them, and the choice persists. Jumping to a provider's detail view is via the *Switch provider* submenu / ⌥⌘\ (the Overview row click toggles visibility instead). The Preferences window needs **macOS 12+** (the menu bar itself works on 10.15+). Tags/labels use the system label colors, so they adapt to a light or dark menu bar; only the bar fill/empty colors are configurable. Pace markers require both a real reset and elapsed-time output. Claude, Codex, Z.AI, MiniMax and Antigravity supply that pair; the remaining vendors render their generic windows without a pace marker. When available, the fixed blue `│` pace marker is placed at elapsed time. Fill past the marker follows the point-delta colors used by the Rust widget: at least 10 points ahead is critical/red, 1–9 ahead is high/orange, -10 through on-pace is mid/yellow, and more than 10 under is low/green. Windows without a reset (including a displayed `—`) retain their row but do not draw a marker. ## Indicator style The "Indicator style" preference chooses between **block bars** (`░█`, the default) and a **ring** (`○`) drawn with `NSBezierPath` (AppKit). The ring paints the usage fraction as a severity-colored arc over a faint track, with the same pace marker as the block bar: calm fill from 12 o'clock up to the lesser of the current percentage and the elapsed tick; any fill past the tick is warning-colored. Both the menu bar and the dropdown rows honor the choice. The track adapts to the effective appearance — faint white on dark menu bars (where the dark `COLOR_EMPTY` would be invisible) and `COLOR_EMPTY` on light ones. ## Quick vendor switch A **"Switch provider"** submenu in the dropdown (between "Refresh now" / "Open TUI" and "Preferences…") lists only configured vendors, with a checkmark on the active one. Selecting one switches immediately, without opening Preferences. The global **⌥⌘\\** shortcut performs the same cycle from any app; disable it under Preferences → Shortcut if that chord belongs to another application. ## Multiple Claude accounts Named Anthropic accounts from the binary's config (`[[anthropic.accounts]]` entries and `[anthropic] accounts_dir` auto-discovery — see the main README's "Multiple accounts") each get their own entry, "Claude · label", in the vendor submenu, the ⌥⌘\ swap ring, the Preferences selector, and the Overview. Each is fetched as `--vendor anthropic --account