[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80510":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":9,"pushedAt":9,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":15,"starSnapshotCount":15,"syncStatus":13,"lastSyncTime":29,"discoverSource":30},80510,"ai-usagebar","akitaonrails\u002Fai-usagebar","akitaonrails","Rust-based waybar widget to monitor status of Claude, GPT, GLM, OpenRouter plans\u002Fcredits - inspired by claudebar\u002Fcodexbar",null,"Rust",152,23,2,1,0,4,14,67,15,65.84,"MIT License",false,"main",true,[],"2026-06-12 04:01:28","# ai-usagebar\n\nWaybar widget and tabbed TUI for AI plan usage across **Anthropic Claude**, **OpenAI Codex\u002FChatGPT**, **Z.AI (GLM)**, **OpenRouter**, and **DeepSeek**.\n\nThis started as a Rust port of [`claudebar`](https:\u002F\u002Fgithub.com\u002Fmryll\u002Fclaudebar) 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.\n\n![Waybar widget showing `cld 29% · 1h 12m` in the top-right, with the hover tooltip showing Claude Max 20x session\u002Fweekly\u002Fsonnet\u002Fextra-usage progress bars](screenshot.png)\n\n## Features\n\n- **Per-vendor Waybar modules** with the same JSON shape as claudebar.\n- **Tabbed TUI** (`ai-usagebar-tui`) with Tab\u002Fh\u002Fl switching, per-tab refresh, and 60-second auto-refresh. Native ratatui widgets fill the available terminal width and keep the vendor tabs visually consistent.\n- **Scroll-to-cycle on the bar**: wire `on-scroll-up` \u002F `on-scroll-down`, and one bar item cycles through your enabled vendors.\n- **Config-driven primary vendor**: set `[ui] primary` once; the widget shows that vendor by default and the TUI opens on its tab.\n- **Local testing tools**: `--pretty` renders ANSI-colored terminal output (auto-detects TTY), and `--watch N` re-renders every N seconds.\n- **Drop-in claudebar compatibility** with the same flags (`--icon`, `--format`, `--tooltip-format`, `--pace-tolerance`, `--format-pace-color`, `--tooltip-pace-pts`, `--color-*`) and `{placeholders}`.\n- **Always exits 0**, because Waybar hides modules that don't.\n- **Atomic cache writes + flock**, so multi-monitor Waybar instances can coexist without API stampedes.\n- **Separate transient and hard errors**: DNS\u002Ftimeout failures show a quiet `Loading…`; HTTP 4xx\u002F5xx errors put the code in the tooltip.\n- **Live API smoke tests**: `make smoke` hits the real undocumented endpoints and catches schema drift early.\n\n## Install\n\n### Arch (AUR)\n\nTwo packages. Pick one:\n\n```bash\nyay -S ai-usagebar-bin    # prebuilt binary from GitHub Releases (fast, ~5s install)\nyay -S ai-usagebar        # compiles from source (~30-60s, hermetic)\n```\n\nThe `-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 `\u002Fusr\u002Fbin\u002F`. If you already have one installed, switch with `yay -S` the other package; pacman handles the swap through `conflicts`\u002F`provides`.\n\n### Other Linux \u002F macOS (crates.io)\n\n```bash\ncargo install ai-usagebar                # compile from source (needs rustup)\ncargo binstall ai-usagebar               # download prebuilt binary (needs cargo-binstall, no rustup)\n```\n\n`cargo binstall` fetches the same x86_64 \u002F aarch64 Linux tarball the AUR `-bin` package uses. Both install `ai-usagebar` + `ai-usagebar-tui` to `~\u002F.cargo\u002Fbin\u002F`.\n\n### From source\n\n```bash\ncargo build --release\nsudo make install                  # → \u002Fusr\u002Flocal\u002Fbin\n# or\nmake install PREFIX=$HOME\u002F.local   # → ~\u002F.local\u002Fbin\n```\n\n## Authentication\n\nEach 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`.\n\n| Vendor | Method | Action required |\n|---|---|---|\n| Anthropic | OAuth, read from `~\u002F.claude\u002F.credentials.json` (or the macOS login Keychain — see below) | Run `claude` once to log in. Token auto-refreshes. |\n| OpenAI | OAuth, read from `~\u002F.codex\u002Fauth.json` | Run `codex login` once. Token auto-refreshes. |\n| Z.AI | API key (`ZAI_API_KEY` env or `[zai] api_key` in config) | Set either. |\n| OpenRouter | API key (`OPENROUTER_API_KEY` env or `[openrouter] api_key` in config) | Set either. |\n| DeepSeek | API key (`DEEPSEEK_API_KEY` env or `[deepseek] api_key` in config) | Set either. Disabled by default — add `[deepseek] enabled = true` to config. |\n\n### Credential resolution order (for API-key vendors)\n\nFor each API-key vendor, ai-usagebar checks in this order:\n\n1. **Env var named by `api_key_env`** in config (defaults: `ZAI_API_KEY`, `OPENROUTER_API_KEY`). If set + non-empty, used.\n2. **Inline `api_key`** in the same config section.\n3. Otherwise, **error** with a message naming both options.\n\n### Security\n\n- If you put inline `api_key` values in config, `chmod 600 ~\u002F.config\u002Fai-usagebar\u002Fconfig.toml`. The default behavior reads only env vars, which is safer when your config might be world-readable.\n- Don't commit your config dir if you check it into dotfiles unless you've redacted `api_key` lines.\n- OAuth credential files (`~\u002F.claude\u002F.credentials.json`, `~\u002F.codex\u002Fauth.json`) are managed by their respective CLIs and already chmod-protected.\n\n#### macOS: Anthropic credentials in the Keychain\n\nOn macOS, recent Claude Code builds don't write `~\u002F.claude\u002F.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.\n\n## Configuration\n\n`~\u002F.config\u002Fai-usagebar\u002Fconfig.toml` (optional — defaults enable Anthropic, OpenAI, Z.AI, and OpenRouter; DeepSeek is opt-in). Full example:\n\n```toml\n[ui]\n# Which vendor the widget shows when --vendor is omitted, AND which tab\n# is selected when the TUI opens. Defaults to anthropic when not set.\n# primary = \"anthropic\"   # anthropic | openai | zai | openrouter | deepseek\n\n[anthropic]\nenabled = true\n# credentials_path = \"\u002Fhome\u002Fyou\u002F.claude\u002F.credentials.json\"\n\n[openai]\nenabled = true\n# codex_auth_path = \"\u002Fhome\u002Fyou\u002F.codex\u002Fauth.json\"\n\n[zai]\nenabled = true\napi_key_env = \"ZAI_API_KEY\"\n# api_key = \"...\"          # used if ZAI_API_KEY is unset; chmod 600 the file!\n# plan_tier = \"lite\"       # lite | pro | max — display-only\n\n[openrouter]\nenabled = true\napi_key_env = \"OPENROUTER_API_KEY\"\n# api_key = \"sk-or-v1-...\"\n\n[deepseek]\nenabled = true             # disabled by default; enable once you add an API key\napi_key_env = \"DEEPSEEK_API_KEY\"\n# api_key = \"sk-...\"       # used if DEEPSEEK_API_KEY is unset; chmod 600 the file!\n```\n\n## Quick start\n\n```bash\n# Local testing — auto-detects TTY and renders human-readable output.\nai-usagebar                        # uses [ui] primary (defaults to anthropic)\nai-usagebar --vendor openai\nai-usagebar --vendor zai\nai-usagebar --vendor openrouter\nai-usagebar --vendor deepseek\n\n# Force Waybar JSON (e.g. piping into jq).\nai-usagebar --json\n\n# Live preview while iterating on --format \u002F --tooltip-format.\nai-usagebar --vendor openrouter --watch 5\n\n# Interactive TUI with tabs.\nai-usagebar-tui\n```\n\n## Standalone TUI — no Waybar required\n\nThe 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:\n\n```bash\nai-usagebar-tui                    # opens in your current terminal\n```\n\nIt 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:\n\n- An ad-hoc check (\"am I close to my Claude weekly limit before I start a long session?\")\n- A foreground monitor on a secondary screen or tmux pane while you code\n- A shell-only tool on remote machines (just install the binary; no Waybar\u002FHyprland dependencies)\n\nThe 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.\n\n## Waybar config\n\n### Single module, scroll-to-cycle (recommended)\n\nUse one bar item and scroll through your vendors. The TUI on-click still shows them all:\n\n```jsonc\n\"modules-right\": [\"custom\u002Faibar\", ...],\n\n\"custom\u002Faibar\": {\n    \"exec\": \"ai-usagebar --format '{vendor_short} {session_pct}% · {session_reset}'\",\n    \"return-type\": \"json\",\n    \"interval\": 300,\n    \"signal\": 13,\n    \"tooltip\": true,\n    \"on-click\": \"ai-usagebar-tui\",\n    \"on-scroll-up\":   \"ai-usagebar --cycle-next\",\n    \"on-scroll-down\": \"ai-usagebar --cycle-prev\"\n}\n```\n\nThe `{vendor_short}` placeholder always expands to a 3-letter vendor ID (`cld` \u002F `gpt` \u002F `zai` \u002F `opr` \u002F `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_*}` \u002F `{zai_*}` \u002F `{or_*}` \u002F `{ds_*}` families, which expand to empty strings for vendors that don't define them.\n\n`signal: 13` lets the scroll-cycle commands refresh the bar instantly (via `SIGRTMIN+13`) instead of waiting for the next 300s interval.\n\n### Per-vendor modules\n\nIf you'd rather see them all at once:\n\n```jsonc\n\"modules-right\": [\"custom\u002Fclaude\", \"custom\u002Fopenai\", \"custom\u002Fopenrouter\", \"custom\u002Fzai\", \"custom\u002Fdeepseek\"],\n\n\"custom\u002Fclaude\": {\n    \"exec\": \"ai-usagebar --vendor anthropic --icon '󰚩'\",\n    \"return-type\": \"json\",\n    \"interval\": 300,\n    \"tooltip\": true,\n    \"on-click\": \"ai-usagebar-tui\"\n},\n\"custom\u002Fopenai\": {\n    \"exec\": \"ai-usagebar --vendor openai --icon '󱢆'\",\n    \"return-type\": \"json\",\n    \"interval\": 300,\n    \"tooltip\": true\n},\n\"custom\u002Fopenrouter\": {\n    \"exec\": \"ai-usagebar --vendor openrouter --icon '󱙺' --format '{or_balance} · {or_used_today}'\",\n    \"return-type\": \"json\",\n    \"interval\": 600,\n    \"tooltip\": true\n},\n\"custom\u002Fzai\": {\n    \"exec\": \"ai-usagebar --vendor zai --icon '󰚩'\",\n    \"return-type\": \"json\",\n    \"interval\": 300,\n    \"tooltip\": true\n},\n\"custom\u002Fdeepseek\": {\n    \"exec\": \"ai-usagebar --vendor deepseek --icon '󰧑'\",\n    \"return-type\": \"json\",\n    \"interval\": 600,\n    \"tooltip\": true\n}\n```\n\n> 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.\n\n## Hyprland: float the TUI window\n\nBy default Hyprland tiles the TUI. To make `ai-usagebar-tui` open as a centered floating window, the same way Omarchy floats its own settings TUIs (Wi-Fi\u002F`impala`, audio\u002F`wiremix`, Bluetooth\u002F`bluetui`), add this to `~\u002F.config\u002Fhypr\u002Fhyprland.conf` or any sourced `.conf`, such as `looknfeel.conf`:\n\n```ini\n# ai-usagebar TUI — float + center + fixed size. omarchy-launch-tui sets the\n# app-id from the binary basename, so the class is org.omarchy.ai-usagebar-tui.\n# 875x600 matches the size Omarchy gives its own `floating-window`-tagged TUIs.\nwindowrule = float on, match:class ^(org\\.omarchy\\.ai-usagebar-tui)$\nwindowrule = center on, match:class ^(org\\.omarchy\\.ai-usagebar-tui)$\nwindowrule = size 875 600, match:class ^(org\\.omarchy\\.ai-usagebar-tui)$\n```\n\nThen `hyprctl reload` (no logout needed).\n\n> Omarchy tags a hardcoded list of TUI app-ids with `floating-window` in `~\u002F.local\u002Fshare\u002Fomarchy\u002Fdefault\u002Fhypr\u002Fapps\u002Fsystem.conf`, which then applies `float + center + size 875 600`. The rules above set those values directly, so the size is deterministic regardless of which config is sourced first. If you launch the TUI differently (e.g. `kitty -e ai-usagebar-tui`), replace the class regex with whatever `hyprctl clients` reports for your terminal.\n\n> Hyprland 0.46+ uses the unified `windowrule` keyword with `match:…` filters. The older `windowrulev2 = …, class:…` syntax still works on legacy Hyprland but is deprecated — use the form above on current Omarchy \u002F Hyprland releases.\n\n## Vendor support matrix\n\n| Vendor | Endpoint | What you see |\n|---|---|---|\n| **Anthropic** | `api.anthropic.com\u002Fapi\u002Foauth\u002Fusage` (undocumented) | Session (5h), Weekly (7d), Sonnet (7d), Extra usage $ |\n| **OpenAI** | `chatgpt.com\u002Fbackend-api\u002Fwham\u002Fusage` (undocumented; used by official `codex` CLI) | Codex 5h, Codex weekly, Code-review weekly, Credits |\n| **Z.AI** | `api.z.ai\u002Fapi\u002Fmonitor\u002Fusage\u002Fquota\u002Flimit` (undocumented) | Session 5h, Weekly 7d, MCP tools monthly |\n| **OpenRouter** | `openrouter.ai\u002Fapi\u002Fv1\u002F{credits,key}` (documented) | Balance, today\u002Fweek\u002Fmonth spend, free vs paid tier |\n\n### Endpoint stability\n\nThree of the four endpoints are undocumented. The Anthropic and OpenAI endpoints are used by their official CLIs (`claude` and `codex`), so removing them would break those tools too. That makes them less shaky than scraped web endpoints. Z.AI's monitor endpoint is reverse-engineered from a third-party plugin; treat it as the most fragile one.\n\nWhen an endpoint drifts, **run `make smoke`**. The live API tests check the exact fields this project depends on and produce a precise failure pointing at what changed. Paste the failure back into Claude Code and the affected `types.rs` can usually be updated mechanically.\n\n## Format placeholders\n\n### Shared \u002F Anthropic (claudebar-compatible)\n\n| Placeholder | Example |\n|---|---|\n| `{plan}` | `Max 5x` |\n| `{session_pct}`, `{session_reset}`, `{session_bar}`, `{session_elapsed}` | `62`, `1h 30m`, `█████████████░░░░░░░`, `58` |\n| `{session_pace}`, `{session_pace_indicator}`, `{session_pace_pct}`, `{session_pace_pts}`, `{session_pace_delta}`, `{session_pace_abs_delta}` | `↑`, `↑`, `12% ahead`, `4pts ahead`, `4`, `4` |\n| `{weekly_*}` | same family for the 7d window |\n| `{sonnet_*}` | same family for the 7d Sonnet window (empty when absent) |\n| `{extra_spent}`, `{extra_limit}`, `{extra_pct}`, `{extra_bar}` | `$2.50`, `$50.00`, `5`, `█░░░░░░░░░░░░░░░░░░░` |\n\n### OpenAI (Codex OAuth)\n\n`{oai_plan}`, `{oai_session_pct}`, `{oai_session_reset}`, `{oai_session_elapsed}`, `{oai_session_pace}`, `{oai_session_pace_indicator}`, `{oai_weekly_*}` (same family), `{oai_code_review_pct}`, `{oai_credit_balance}`, `{oai_local_msgs}`, `{oai_cloud_msgs}`\n\n### Z.AI\n\n`{zai_plan}`, `{zai_session_pct}`, `{zai_session_reset}`, `{zai_weekly_pct}`, `{zai_weekly_reset}`, `{zai_mcp_pct}`, `{zai_mcp_reset}`\n\n### OpenRouter\n\n`{or_label}`, `{or_balance}`, `{or_total}`, `{or_used}`, `{or_used_today}`, `{or_used_week}`, `{or_used_month}`, `{or_consumed_pct}`, `{or_free_tier}`, `{or_limit}`, `{or_limit_remaining}`, `{or_balance_bar}`\n\n### DeepSeek\n\n`{ds_balance}`, `{ds_granted}`, `{ds_topped_up}`, `{ds_available}` — credit balance from `\u002Fuser\u002Fbalance`. USD is preferred when both currencies are present; falls back to CNY otherwise.\n\n## Local development\n\n```bash\nai-usagebar --watch 5                              # iterate on --format live\nai-usagebar --vendor openrouter --format '{or_balance} · today {or_used_today}'\n\nmake test                                          # unit + integration\nsource ~\u002F.config\u002Fzsh\u002Fsecrets                       # only needed for live smoke\nmake smoke                                         # live API drift detection\nmake clippy                                        # cargo clippy -D warnings\n```\n\n## TUI controls\n\n![ai-usagebar-tui showing the OpenAI tab — Codex 5h and weekly gauges, Credits block with message-count ranges, tabs at top, key hints in the footer](screenshots\u002Ftui-openai.png)\n\n- `Tab` \u002F `l` \u002F `→` — next tab\n- `Shift+Tab` \u002F `h` \u002F `←` — previous tab\n- `r` — refresh active tab\n- `R` — refresh all tabs\n- `s` — open Settings overlay (primary vendor + API keys)\n- `q` \u002F `Esc` \u002F `Ctrl-C` — quit\n\nAuto-refresh runs every 60 seconds in the background. Vendors use the same layout. Here's OpenRouter showing the credit balance gauge (red because 98% is consumed), usage-by-period totals, and tier:\n\n![ai-usagebar-tui showing the OpenRouter tab — Credit balance gauge at 98% in red ($13.67 left of $900), Usage by period with today\u002Fweek\u002Fmonth, paid tier](screenshots\u002Ftui-openrouter.png)\n\n### Settings overlay\n\n![Settings overlay floating over the TUI — Primary vendor radio (Anthropic selected), masked Z.AI API key (•••), masked OpenRouter API key (•••), Save button, key hints at bottom](screenshots\u002Ftui-settings.png)\n\nPress `s` while the TUI is open. The overlay lets you:\n\n- Pick the **primary vendor** that the widget defaults to and that the TUI selects on startup. Use `←` \u002F `→` to cycle.\n- Enter your **Z.AI API key** and **OpenRouter API key** inline. Keys are masked as you type; press `Ctrl-V` to reveal or hide them. Env vars (`ZAI_API_KEY`, `OPENROUTER_API_KEY`) still win at runtime if they're set; the inline key is the fallback.\n\nKey bindings inside the overlay:\n\n- `Tab` \u002F `↑↓` — move between fields\n- `←` \u002F `→` — cycle primary-vendor selection (only on the vendor field)\n- `Ctrl-V` — toggle key visibility on the focused key field\n- `Ctrl-S` — save and close\n- `Esc` — discard and close\n\nSave writes to `~\u002F.config\u002Fai-usagebar\u002Fconfig.toml` via `toml_edit` so your existing comments and unrelated fields are preserved. The file is automatically `chmod 600`ed on save, so inline keys aren't world-readable.\n\nAfter save, the Settings overlay fires `SIGRTMIN+13` so any Waybar module configured with `signal: 13` refreshes immediately. You don't need to wait for the next 300-second interval or kick the bar by hand. The TUI's own tabs also re-fetch right away, so a freshly set API key takes effect on the spot.\n\nIf your module doesn't use `signal: 13`, the signal is a no-op and the bar will refresh on its next normal tick (up to `interval` seconds away). To force-refresh manually: `pkill -SIGUSR2 waybar` (full reload).\n\n## Theming\n\n- One Dark palette by default.\n- Auto-merges with the active Omarchy theme at `~\u002F.config\u002Fomarchy\u002Fcurrent\u002Ftheme\u002Fcolors.toml`.\n- Per-color overrides: `--color-low`, `--color-mid`, `--color-high`, `--color-critical` (claudebar-compatible).\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for the release history. Each release also has its own page at \u003Chttps:\u002F\u002Fgithub.com\u002Fakitaonrails\u002Fai-usagebar\u002Freleases> with the auto-generated install snippet and checksum.\n\n## Acknowledgements\n\nThe OpenAI and Anthropic OAuth endpoint references came from [`claudebar`](https:\u002F\u002Fgithub.com\u002Fmryll\u002Fclaudebar) and [`codexbar`](https:\u002F\u002Fgithub.com\u002Fmryll\u002Fcodexbar), both by mryll. The visual design, including the bordered Pango tooltip, severity colors, and pacing math, is theirs. This project is a Rust port with multi-vendor support.\n\n## License\n\nMIT.\n","ai-usagebar 是一个基于 Rust 的 Waybar 小部件，用于监控 Claude、GPT、GLM 和 OpenRouter 等 AI 服务的使用情况。其核心功能包括为每个供应商提供独立的 Waybar 模块、带标签切换的 TUI 界面以及通过滚动在不同供应商之间循环的功能。该项目支持配置驱动的主要供应商选择，并提供了本地测试工具和实时 API 测试。此外，它还具有原子缓存写入和 flock 保护，以确保多显示器环境下的稳定运行。此项目适用于需要在一个简洁界面中同时跟踪多个 AI 服务使用状态的开发者或用户。","2026-06-11 04:01:01","CREATED_QUERY"]