# clui
A ratatui TUI that renders Claude Code and Codex (OpenAI) usage limits the
same way fulcrum's "Usage Limits" monitoring tab does: a grid of cards, each
with a circular progress gauge, the limit name, and a human-friendly reset
time.
```
Claude Code · Usage Limits
╭──────────────────────────────╮╭────────────────────────────────────╮
│ ⢀⣀⣤⣤⣤⣄⣀ ││ ⢀⣀⣤⣤⣤⣄⣀ │
│ ⣤⣾⣿⠿⠛⠛⠛⠻⢿⣿⣦⡄ ││ ⣤⣾⣿⠿⠛⠛⠛⠻⢿⣿⣦⡄ │
│ ⣼⣿⠃ ⢻⣿⡄ 5-Hour ││ ⣼⣿⠃ ⢻⣿⡄ 7-Day Rolling │
│ ⣿⣿ 10% ⢸⣿⡇ Block ││ ⣿⣿ 10% ⢸⣿⡇ Resets Mon 02:00 │
│ ⢹⣿⣆ ⢀⣾⣿⠁ Resets in ││ ⢹⣿⣆ ⢀⣾⣿⠁ · 41% through │
│ ⠉⠻⢿⣿⣶⣶⣶⣾⣿⠿⠋⁁ 3h 54m ││ ⠉⠻⢿⣿⣶⣶⣶⣾⣿⠿⠋⁁ week │
╰──────────────────────────────╯╰────────────────────────────────────╯
Codex · Plus
╭──────────────────────────────╮╭────────────────────────────────────╮
│ ⣼⣿⠃ ⢻⣿⡄ Session ││ ⣼⣿⠃ ⢻⣿⡄ Weekly │
│ ⣿⣿ 1% ⢸⣿⡇ Resets in ││ ⣿⣿ 0% ⢸⣿⡇ Resets Jun 17 │
│ ⢹⣿⣆ ⢀⣾⣿⠁ 4h 59m ││ ⢹⣿⣆ ⢀⣾⣿⠁ 22:21 │
╰──────────────────────────────╯╰────────────────────────────────────╯
q quit r refresh · updated 22:21:30
```
## Data sources
### Claude Code
Same as fulcrum (`server/routes/monitoring.ts`):
1. Reads the OAuth token from `~/.claude/.credentials.json`
(`claudeAiOauth.accessToken`, must start with `sk-ant-oat`), falling back
to the GNOME keyring via `secret-tool`.
2. Calls `GET https://api.anthropic.com/api/oauth/usage` with the
`anthropic-beta: oauth-2025-04-20` header.
3. Renders up to four limit blocks: **5-Hour Block**, **7-Day Rolling**,
**Opus Weekly**, **Sonnet Weekly** (the model-specific cards only appear
when the API reports them, as in fulcrum).
### Codex
Same as [CodexBar](https://github.com/steipete/CodexBar)'s OAuth fetcher:
1. Reads credentials from `$CODEX_HOME/auth.json` (default `~/.codex/auth.json`):
a top-level `OPENAI_API_KEY` if present, otherwise `tokens.access_token`
plus `tokens.account_id`.
2. Calls `GET https://chatgpt.com/backend-api/wham/usage` with
`Authorization: Bearer …` and `ChatGPT-Account-Id: …` headers.
3. Refreshes tokens via `POST https://auth.openai.com/oauth/token` (CodexBar's
client id) when `last_refresh` is older than 8 days or the API returns
401/403, writing the new tokens back to `auth.json`.
4. Normalizes the two rate-limit windows by size — smaller is **Session**
(5h), larger is **Weekly** — and shows the plan from `plan_type`
(`pro` → "Pro 20x", `pro_lite` → "Pro 5x", else title-cased).
## Install
```sh
cargo install clui
```
Or from a checkout:
```sh
cargo install --path .
```
## Usage
```sh
clui
```
```
clui [OPTIONS]
-t, --theme <NAME> Color theme to start with (default: default)
--themes-file <PATH> Custom themes JSON (default: ~/.config/clui/themes.json)
--list-themes Print available themes and exit
```
Keys: `q`/`Esc` quit, `r` refresh now, `t`/`T` next/previous theme.
## Themes
Built-in themes: `default`, `dracula`, `gruvbox`, `nord`, `solarized`, `mono`.
Pick one at startup with `--theme nord` and cycle at runtime with `t` (the
footer shows the active theme).
Custom themes live in `~/.config/clui/themes.json` (or wherever
`--themes-file` points): a JSON object mapping theme names to color
overrides. Unset fields inherit from `base` (default: `default`), and a
custom theme named after a built-in replaces it. Colors are ratatui color
names (`"cyan"`, `"darkgray"`), hex (`"#ff5555"`), or 256-color indexes
(`237`).
```json
{
"neon": {
"base": "mono",
"gauge_low": "#39ff14",
"gauge_mid": "#ffe600",
"gauge_high": "#ff2052",
"accent": 213
}
}
```
Fields: `gauge_low` (< 70% used), `gauge_mid` (70–89%), `gauge_high` (≥ 90%),
`ring_bg` (unfilled ring), `accent` (key hints), `dim` (secondary text),
`error`, `border`.