ai-usagebar 1.25.0

Omarchy/Waybar widgets + TUI for tracking multi-provider AI plan usage
Documentation
# Contributing

Thanks for looking at this. Contributions land regularly and are genuinely
welcome — this file exists so review spends its time on your idea rather than
on the same handful of mechanical things.

## Before you open a PR

Run the gate. It is the same one CI runs, and it catches almost everything a
review would otherwise send back:

```
make test                                   # cargo test + the GNOME, KDE and Omarchy contract suites
cargo clippy --all-targets -- -D warnings
cargo fmt --all -- --check
cargo machete                               # no unused dependencies
```

`make test` rather than `cargo test`: the frontends have their own Node contract
tests, and a change to the report shape can break them without touching Rust.

## Checklist

Most review round-trips come from one of these. None takes long.

- [ ] **`CHANGELOG.md` entry**, under `## [Unreleased]`, in the right category
      (`Added` / `Changed` / `Fixed` / `Security`). Anything user-visible needs
      one — a new provider, a changed default, a fixed bug, a renamed flag.
      **Never edit a released section**; if your branch is older than the last
      tag, git will merge your entry cleanly into whatever now sits at that
      position, which has silently rewritten shipped history twice.
- [ ] **Tests that fail without your change.** For a bug fix, confirm the new
      test fails on `main` and passes on your branch — say so in the PR.
- [ ] **No leftovers.** If your change removes the last caller of a helper,
      remove the helper too. Dead shared machinery is how this codebase has
      previously grown copies that drift apart.
- [ ] **Documentation that mentions what you changed.** Grep for it: `README.md`,
      `config.example.toml`, `docs/configuration.md`,
      `docs/vendor-endpoints.md`, `docs/format-placeholders.md`. A doc that
      still describes the old behaviour is worse than one that says nothing —
      especially when it promises a security property that is no longer true.

## Project rules worth knowing

These are in `CLAUDE.md` in full. The ones contributors hit most:

- **The widget always exits 0.** Waybar hides a module that doesn't. Errors
  become a fallback `⚠` payload, never a non-zero exit.
- **No `PATH` lookups for a trusted binary** without a config override. The
  executable that runs on every refresh should not be an ambient choice — see
  `[supergrok] grok_binary` and `[copilot] gh_binary`.
- **Credentials are read, never rewritten**, unless the vendor owns the file.
  CLI, editor and browser credentials are never parsed, copied, or stored.
- **Tests are hermetic.** A `#[test]` must never read or write a real `$HOME`
  or `$XDG` path, or branch on an ambient environment variable — the AUR
  package runs `cargo test` during install, so a test coupled to your machine
  fails someone else's build. Inject the path: `Cache::at`, not `for_vendor`;
  `creds::read_from`, not `default_path`.
- **Money is formatted in one place** (`format::money` / `format::usd`), and
  a fetch outcome is built in one place (`outcome::Outcome`). Guard tests fail
  the build if a second copy appears.

## Adding a provider

The bar is: **quota reachable with a credential the user already has, obtained
the way this project obtains credentials** — an API key, an OAuth file an
official CLI wrote, or an official CLI invoked for a token. Scraped browser
sessions do not qualify. `docs/vendor-endpoints.md` records providers that have
been evaluated and why some were declined; check it before starting.

Open an issue first with the endpoint, the auth mechanism, and a real response
capture with the numbers redacted. Field names and nesting are what a parser
gets pinned to, and a paraphrase is not enough to build against.

## Changing the tray popover UI

The popover is the part of the project with the most opinions, and all of
them are valid: some people want every provider at a glance, others one at a
time in their system's own look. To keep one person's taste from replacing
another's, UI changes follow one rule: **add, don't replace.**

- A different look is a new **popover style** (Settings → Appearance →
  Popover Style), not a rewrite of Classic or Native. Scope its CSS to the
  style (tokens on `body:has(.<style>-panel)`, rules under `.<style>-panel` in
  `windows/popover/src/index.css`) and reuse the shared components; do not
  fork `ProviderSection`, the Settings rows or the menus.
- Native follows the host: a shared glass base, refined per OS under
  `.native-panel[data-os="<os>"]` (macOS after Apple's macOS 26 UI kit,
  Windows after Fluent). Making
  Native match another system — a GTK or Omarchy theme, should a Linux host
  ever share this popover — is adding that OS's tokens, not a new style.
- A style changes presentation only. Features, data and settings live in the
  shared components and work in every style; what a host cannot do is gated
  by the OS, never by the style.
- Do not change a default (style, width, menu-bar look) in the same PR as a
  new look. Propose it separately, with the reason.
- **Show a visual change.** Anything that changes how the popover, the menu
  bar or the tray icon looks puts before/after screenshots in the PR
  description, for every style, OS and theme it touches. A look cannot be
  judged from a diff: screenshots let it be reviewed without building it, and
  nobody finds out after an update. Fixes and features that apply to every
  style are welcome as usual; say which styles you checked.
- Open an issue first for a new style: a screenshot or mockup and who it is
  for is enough to agree it belongs before anyone writes it.

The frontends already work this way one level up — Waybar, GNOME, KDE,
Omarchy and the TUI all read the same `usage --json` and each looks the way
its users want. Styles bring that inside the popover.

## Platform reality

CI builds Linux, macOS and Windows, but the maintainer works on Linux. macOS
code paths — the Keychain, Claude Desktop, `safe_storage` — get compiled but
not exercised. If you are on a Mac and can test a change there, say so in the
PR; that is worth more than it sounds.