A small, always-on-top desktop window that shows how much of your Claude and Codex subscription quota you have left — read locally, from your own credentials, with no account to create and nothing phoned home.
The entire value proposition is a small, auditable trust boundary. Credentials and the network are owned by two modules — crates/usage-core/src/credentials/ and crates/usage-core/src/egress/ — deliberately small enough to read end to end in one sitting; the two provider parsers consume what they return. Everything else is scheduling and rendering.
- Claude (Anthropic) — your 5-hour and 7-day subscription windows: percent used, and how long until each resets.
- Codex (OpenAI) — the rate-limit windows the Codex endpoint reports, labelled by their duration (typically a short rolling window plus a weekly one).
- Per-model breakdown — where a provider reports per-model limits, each provider pane has a collapsible toggle that expands them into their own rows.
- Staleness — the window tells you when the data is older than it should be, rather than quietly showing you a stale number.
- System tray — an icon rendering current usage, with a tooltip and a Show/Hide/Quit menu (Windows and macOS; see Platform support).
- Headless mode —
quotapane-cliprints the same normalized snapshot as text or JSON, for scripts, for cron, and for proving to yourself what the app talks to. (Text output is a compact summary; per-model rows and reset credits appear in--jsonand the window.)
Two binaries are produced: quotapane (the window) and quotapane-cli (headless).
The window ships with the Cipher Pine terminal theme. A tray-menu
item switches between it and a plain look, live; the choice is
remembered as a single word (plain or cipherpine) in
theme.cfg under your platform's config directory
(%APPDATA%\quotapane\ on Windows, ~/.config/quotapane/ on
Linux). No tray on your platform? Launch with --plain or
--themed to pick per run. The file stores nothing but that word;
deleting it restores the default.
--pace-demo renders a fixed made-up scenario so the pace markers can
be seen without waiting hours for real usage to produce one: it shows
fake data, polls nothing, reads no credentials, and talks to no host.
- Tokens are never persisted, never logged, never serialized. They live in memory in a
Secret<T>that zeroizes on drop and prints«redacted». - Network egress is deny-by-default through a single chokepoint with a compile-time allowlist of exactly two hosts (
api.anthropic.com,chatgpt.com). Anything else is a hard error, and tests prove it. - No first-party telemetry, of any kind, to anyone. CI enforces its absence on every push.
- No auto-update and no update check — there is no updater in the codebase at all. Updating is always something you do deliberately.
- Credential files are opened read-only. Token refresh is delegated to the official
claude/codexCLIs; QuotaPane never writes them. - Proxy support is opt-in and fails closed: with a proxy variable set and no opt-in, nothing is sent. Opting in is a per-run CLI flag behind an explicit warning that a TLS-inspecting proxy can observe your bearer token; the window has no opt-in at all.
Full detail: SECURITY.md · THREAT_MODEL.md · ARCHITECTURE.md.
Download the archive for your platform from GitHub Releases, then verify it (below) before running it.
| Platform | Artifact |
|---|---|
| Windows (x86-64) | quotapane-v<version>-x86_64-pc-windows-msvc.zip |
| Linux (x86-64, glibc) | quotapane-v<version>-x86_64-unknown-linux-gnu.tar.gz |
| macOS | Build from source — see below. |
Each archive contains both binaries, both licenses, this README, and a TOOLCHAIN.txt recording the exact rustc / cargo that built it. There is no installer and nothing to uninstall: the binaries are self-contained. The only file QuotaPane ever writes is theme.cfg — one word recording your theme choice (see Theming); credentials are never written.
QuotaPane reads credentials your provider CLI already wrote, so sign in with claude and/or codex first.
Release artifacts are built only by .github/workflows/release.yml on a version tag, never on a maintainer's machine. Every release ships SHA256SUMS covering all archives, a cosign keyless signature over that file as a Sigstore bundle (SHA256SUMS.sigstore.json, which carries both the signature and the signing certificate), and a build-provenance attestation on each archive. Verifying all three takes about a minute.
1. Checksum. Put the archive next to SHA256SUMS, then:
sha256sum --ignore-missing -c SHA256SUMSOn Windows PowerShell, compare manually against the matching line in SHA256SUMS:
Get-FileHash quotapane-v<version>-x86_64-pc-windows-msvc.zip -Algorithm SHA2562. Signature. SHA256SUMS is signed with cosign keyless signing, so the identity is this repo's release workflow rather than a long-lived key:
cosign verify-blob SHA256SUMS \
--bundle SHA256SUMS.sigstore.json \
--certificate-identity-regexp '^https://github\.com/cipherpine/quotapane/\.github/workflows/release\.yml@refs/tags/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comThis prints Verified OK. The identity regex is deliberately narrow: it matches only this repository's release.yml running on a tag ref, so a signature produced by any other workflow, or by this one on a branch, fails.
You need a cosign that understands Sigstore bundles — confirmed with cosign 3.1.2 against a bundle produced by cosign 3.0.6 in CI. Releases no longer ship the detached SHA256SUMS.sig / SHA256SUMS.pem pair that cosign 2.x used.
On Windows, run this from PowerShell or WSL rather than Git Bash. Git Bash rewrites the \. escapes in the identity regex before cosign sees them and the match fails; if you must use Git Bash, write [.] in place of each \..
3. Provenance. Each archive carries a GitHub build-provenance attestation, verifiable with the gh CLI:
gh attestation verify quotapane-v<version>-x86_64-pc-windows-msvc.zip --repo cipherpine/quotapaneA passing signature proves the artifact came from this repository's CI at a specific commit. It does not prove that commit was benign — see residual risk R2 in THREAT_MODEL.md. For maximum assurance, build from source.
cargo build --release --locked
cargo test --workspace --locked # includes the security invariant testsRequires Rust 1.92+ (the workspace sets rust-version = "1.92"; the floor comes from eframe 0.35). Binaries land in target/release/ as quotapane and quotapane-cli.
The window takes no arguments in normal use; drag it to position it, and scroll if the content is taller than the window.
quotapane [--client-version <VER>] [--codex-user-agent <UA>] [--no-tray]
| Flag | Meaning |
|---|---|
--client-version <VER> |
The claude-code version string sent as the Claude User-Agent. Defaults to 0.0.0, which the endpoint throttles aggressively — pass a real version for normal use. |
--codex-user-agent <UA> |
Override the User-Agent sent to the Codex endpoint. Defaults to the Codex CLI's own. |
--no-tray |
Start without the system tray icon. The escape hatch if tray creation fails. |
The headless CLI requires --once; one-shot polling is its only mode today.
quotapane-cli --once [--json] [--provider claude|codex|all]
[--client-version <VER>] [--debug-raw] [--debug-raw-unsafe]
| Flag | Meaning |
|---|---|
--once |
Poll once and exit. Required. |
--json |
Emit the normalized snapshot as JSON instead of a text summary. With --provider all, emits an array. |
--provider <WHICH> |
claude, codex, or all. Default: claude. |
--client-version <VER> |
As above. |
--debug-raw |
Print the provider's wire response instead of a snapshot, for pinning an undocumented endpoint's schema. Takes precedence over --json. Redacted by default: the value of every email, user_id, account_id, and id key is replaced with «redacted» at any nesting depth, and a body that is not valid JSON is withheld rather than dumped. |
--debug-raw-unsafe |
The same dump, byte-exact — no redaction, no withholding — after a stderr warning. The output can contain your email address and account identifiers, so treat it as private. Implies --debug-raw. |
--allow-proxy |
Send this run through the proxy in your environment. Off by default, and the default fails closed: while HTTPS_PROXY/HTTP_PROXY/ALL_PROXY (either casing) is set and this flag is absent, QuotaPane sends nothing and exits with an error naming the variable — it does not connect directly instead. A TLS-inspecting proxy can read your bearer token, so opting in is explicit and lasts one run. The window has no equivalent flag. |
-h, --help / --version |
Print help or version and exit. |
If a token has expired, QuotaPane says so and tells you to run claude or codex — it never refreshes tokens itself.
Windows is the primary target. macOS and Linux are built and tested in CI on a best-effort basis.
The system tray is Windows and macOS only. On Linux, QuotaPane is window-only: the tray backend would require the officially-unmaintained gtk-rs 0.18 + libappindicator chain, which is not a dependency this project is willing to put in its tree. See the tray-icon row in CONTRIBUTING.md for the full analysis.
v1.0 is the current scope: both subscription providers, the always-on-top window, the system tray, the per-model breakdown, and the headless CLI — packaged as signed, attested releases.
M4 (opt-in official billing APIs) was withdrawn on security grounds (ADR-002, in ARCHITECTURE.md). Both vendors' usage/cost endpoints require an organization admin API key, are unavailable to individual subscribers, measure a different thing than subscription quota, and would force this trust boundary to hold the highest-blast-radius secret in either ecosystem — the exact opposite of the point of this project.
Deferred to after 1.0: usage history and sparklines, forecast-to-limit, configurable thresholds and alerts, an optional token-free OtelSource (the only acceptable route to any cost view), and package-manager distribution (WinGet / Homebrew / AUR).
QuotaPane is an independent, community project — not affiliated with, endorsed, or supported by Anthropic or OpenAI. The subscription/quota view relies on undocumented endpoints that may change or break at any time, uses your own local credentials only, bypasses no authentication, and scrapes nothing. To read subscription usage, QuotaPane sends the same User-Agent: claude-code/<version> header the official Claude Code client uses — the endpoint rate-limits requests without it — so these requests present as the official client; the Codex provider likewise sends the Codex CLI's default User-Agent (codex-cli). Each provider queries only the endpoint its official client already calls, with your own token, read-only. Use at your own risk.
See CONTRIBUTING.md. Security issues go through GitHub private vulnerability reporting, not a public issue — see SECURITY.md.
Dual-licensed under MIT or Apache-2.0, at your option. Contributions are accepted under the same terms.



