clui 0.1.0

TUI for Claude Code and Codex usage limits
# 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`.