Kicks off v3-alpha on branch v3-dev. Locked decisions: rate-limit % via CLI subscriptions, provider switch on both PC and watch, brand-colored themes (clay / OpenAI green / z.ai blue). Architecture: daemon Provider abstraction, `pv` payload field, firmware runtime palette + shared LVGL styles for live recolor. Milestones M1 (framework+Anthropic+theming) → M2 (OpenAI) → M3 (z.ai). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
90 lines
4.8 KiB
Markdown
90 lines
4.8 KiB
Markdown
# Clawdmeter v3 — multi-provider (alpha)
|
|
|
|
Extend the watch beyond Claude Code to show usage for several AI coding
|
|
providers, let you pick which one the display tracks, and recolor the whole UI
|
|
to the active provider's brand.
|
|
|
|
Branch: **`v3-dev`** (off v2 `d55dc4a`). v2 stays on `v2-dev`.
|
|
|
|
## Providers (initial set)
|
|
|
|
| id | provider | used via | brand accent |
|
|
| ----------- | --------------------- | -------------------------------- | ------------ |
|
|
| `anthropic` | Claude Code | Anthropic OAuth (today's daemon) | `#d97757` clay |
|
|
| `openai` | OpenAI Codex | Codex CLI subscription (`~/.codex`) | `#10a37f` green |
|
|
| `zai` | z.ai GLM Coding Plan | Anthropic-compatible endpoint | blue (TBD) |
|
|
|
|
## Locked decisions (2026-07-10)
|
|
|
|
- **Metric = rate-limit %** — the same two-bar 5h / weekly model as Claude, read
|
|
from each provider's CLI subscription. Fall back to spend / token counts for a
|
|
provider only if it genuinely doesn't expose limits.
|
|
- **Switch on both PC and watch** — pick the active provider in the desktop
|
|
panel *and* on the watch (cycle / selector); the theme recolors live.
|
|
- **Brand palette** (starting point, tuned on-device): Anthropic clay `#d97757`,
|
|
OpenAI `#10a37f`, z.ai blue (exact hex TBD).
|
|
|
|
## Architecture
|
|
|
|
### Daemon — provider abstraction
|
|
- New `daemon/providers/` package:
|
|
- `base.py` — `Provider` ABC: `id`, `label`, `accent`, `async poll() -> ProviderStatus`.
|
|
- `anthropic.py` — today's logic moved here (`poll_api`, `compute_today_usage`,
|
|
OAuth refresh), behaviour-identical.
|
|
- `openai_codex.py`, `zai.py` — added in M2 / M3.
|
|
- `ProviderStatus` = normalized `{s, sr, w, wr, st, ok, tokens_today?, cost_cents_today?}`.
|
|
- **Config v2** (`config.py`): add `providers` (per-provider enable + creds),
|
|
`active_provider`, `display_order`. Migrate v1→v2 by wrapping the existing
|
|
setup as `anthropic`.
|
|
- Poll loop drives the **active** provider; for on-watch cycling it may poll all
|
|
enabled providers and cache, so switching is instant.
|
|
|
|
### Payload
|
|
- Add **`pv`** (provider id) so the watch knows which theme to wear; usage fields
|
|
stay normalized (`s/sr/w/wr/st/tk/tc/...`).
|
|
- On-watch switch: watch → PC command **`{"cmd":"prov","id":"..."}`** sets
|
|
`active_provider` (same channel as the dimmer / button commands, no new GATT).
|
|
|
|
### Firmware — runtime theming (the meaty part)
|
|
- Convert `theme.h` compile-time `#define`s into a runtime **`Palette`**
|
|
(`lv_color_t accent/green/amber/panel/bar_bg/...`) plus shared `lv_style_t`
|
|
objects for the accent / panel / text roles.
|
|
- `ui_set_theme(pv)` swaps the palette + updates the shared styles + invalidates
|
|
— **no widget recreation** (LVGL styles propagate to attached widgets).
|
|
- Per-provider **logo** on the usage screen (swap the image source).
|
|
- On-watch provider switch: a small selector (button on the usage screen, or a
|
|
Providers entry in the launcher) → sends `{"cmd":"prov",...}`.
|
|
|
|
### Panel (desktop)
|
|
- Provider selector (which one displays) + per-provider credential / enable
|
|
fields. Reuses the existing FastAPI + WebView2 settings panel.
|
|
|
|
## Milestones
|
|
|
|
- **M1 — framework + Anthropic refactor + runtime theming.** Provider ABC +
|
|
`AnthropicProvider` (identical behaviour) + config v2 + `pv` in the payload.
|
|
Firmware runtime palette + shared styles + `ui_set_theme` + per-provider logo
|
|
slot + on-watch switch plumbing. Panel provider selector (only Anthropic active
|
|
yet). *Deliverable: behaviour unchanged, but themeable and switch-ready.* This
|
|
is the big refactor and de-risks M2/M3.
|
|
- **M2 — OpenAI (Codex) provider.** Read Codex rate-limit / usage. Source TBD —
|
|
Codex is installed at `~/.codex` (`auth.json`, `config.toml`, `state_*.sqlite`,
|
|
`logs_*.sqlite`, `sessions/`); investigate whether limits come from the state
|
|
DB or ChatGPT backend headers. Green theme + OpenAI logo. Fall back to
|
|
spend/tokens if the % model isn't available.
|
|
- **M3 — z.ai (GLM Coding Plan) provider.** `ANTHROPIC_BASE_URL` is already set on
|
|
the dev machine → z.ai is likely used through its Anthropic-compatible endpoint,
|
|
so reuse the Anthropic poll pointed at z.ai's base URL + z.ai key, reading the
|
|
same `anthropic-ratelimit-*` headers. Blue theme + z.ai logo.
|
|
- **M4 — polish.** On-watch switch UX, per-provider splash decision, panel niceties.
|
|
|
|
## Open items / assets
|
|
|
|
- Exact brand hexes (OpenAI `#10a37f` proposed; z.ai blue TBD — finalize on device).
|
|
- **Logos** — need official OpenAI + z.ai marks as RGB565 (user provides / points
|
|
to source, per the "don't hand-author brand art" preference). Claude logo already
|
|
in `logo.h`.
|
|
- Splash — currently Claude pixel-art (claudepix); per-provider splash is an open
|
|
choice (keep Claude, go neutral, or per-provider).
|
|
- Naming — keep **Clawdmeter**; multi-provider under the same identity.
|