Left is a small macOS menu-bar view of how much Claude Code, ChatGPT/Codex, and Grok allowance you have left. The menu bar carries each provider at once — each one's own mark against its own tightest remaining percentage — and the overlay shows every session, weekly, model, and credits window on one compact dark surface: one line each, no scrolling, no empty space under the last row.
Claude, ChatGPT, and Grok marks are trademarks of Anthropic, OpenAI, and xAI.
Left is not affiliated with, endorsed by, or sponsored by those companies.
The numbers in these screenshots come from Fixtures/demo-quota.json, a
synthetic fixture invented for tests and docs — not a dump from a live account.
Left reads quota-axi's normalized
JSON. It does not implement provider authentication, store tokens, or call
provider APIs itself.
The app was called UsageBar until 2026-07-28; docs/naming.md
records why it is Left, and what the rename deliberately left alone.
Requirements:
- macOS 13 or newer
- Swift from Xcode or the Xcode command-line tools
quota-axi0.1.6 or newer onPATH
From this checkout, build, package, install, and launch the app with one command:
./scripts/install.shThe default destination is ~/Applications/Left.app. Pass an explicit
destination or skip launch when needed:
./scripts/install.sh \
--destination "$PWD/.build/Left.app" \
--no-launchThe installer builds the app, renders its icon from the app's own mark, ad-hoc
signs the bundle, and verifies the signature. Before replacing anything it
quits whatever is running from the old and new bundles, so only one instance
survives, and it moves — never deletes — any existing Left.app and any
pre-rename UsageBar.app into ~/Library/Application Support/Left/Rollbacks
as a timestamped *.previous.<stamp>.app. Copies stay there rather than
beside ~/Applications/Left.app, so LaunchServices does not register a
second claimant of the same identifier. Rolling back is moving that bundle
back to the install path and opening it.
The installer registers no login item and no launch agent: whether Left starts at login is yours to set, and the rename does not touch it. It never changes subscription credentials.
If quota-axi is missing, install the researched release explicitly:
npm install -g quota-axi@0.1.13Claude Code may eventually need a one-time Keychain grant after its file token expires. Left shows that stale state, the provider's own reason for it, and an allowlisted repair command, instead of prompting or changing access itself.
Fixtures/demo-quota.json is synthetic: round invented percentages and
generic plan labels, not a live account dump. It exercises live and stale
states without reading credentials:
swift run Left --fixture Fixtures/demo-quota.jsonRender the overlay, the menu-bar readout, or the app icon:
swift run Left --render-preview Fixtures/demo-quota.json docs/demo.png
swift run Left --render-status Fixtures/demo-quota.json docs/menubar.png
swift run Left --render-iconset .build/Left.iconsetdocs/demo.png and docs/menubar.png are committed evidence; verify.sh
compares both byte for byte, so re-render them whenever the surface changes.
./scripts/verify.shVerification runs the parser, state, layout, contrast, and mark tests, builds
release mode, packages and signs a temporary app, exercises the UsageBar →
Left migration and its rollback copy, checks the bundle identifier and icon,
asserts no login-item machinery, re-renders the overlay at 340 × 430 and the
menu-bar readout and compares both to the committed evidence, scans for common
secret patterns, and checks the Git diff.
verify.sh cannot click things or read the menu bar. After an install, check
these five by hand — they take under a minute:
- The menu bar shows Claude's own mark with its percentage, ChatGPT's own mark with Codex's, and Grok's own mark with its remaining percentage — three glyphs, nothing clipped. They are the vendors' published logos, recognisable at a glance rather than a shape standing in for one. The readout inverts correctly on a light menu bar and under click highlight, because the whole thing is one template image.
- Clicking it opens the overlay. Every allowance window is visible at once; nothing scrolls, and the footer sits directly under the last row rather than below a void.
- The header reads
Left · checked … ago, and it is the only place on the surface that says how current the data is. - Pressing Refresh updates that statement to
checked just now. ~/Library/Application Support/Left/Rollbacks/Left.previous.<stamp>.app(orUsageBar.previous.<stamp>.appafter a rename install) still exists. That is the rollback: quit Left, move that bundle back to~/Applications/Left.app(orUsageBar.app), and open it.
- One line per allowance window, on a fixed grid: label, a continuous rail,
the exact remaining percentage, and the exact reset countdown. Every window
is visible at once; the layout tests hold that promise
(
PopoverLayoutTests), including the worst case where every provider is unhealthy and a global error banner is showing. - Rails are monochrome. Colour is reserved for state: amber at 25% or less, red at 10% or less, and for a provider that is stale, unauthenticated, rate limited, or broken. Nothing else on the surface is coloured.
- Freshness is stated once, in the header, from the last successful check.
A provider's own badge ages only what is stale (
12m OLD). - Plain language, never the provider's. Upstream reasons like
keychain_access_requiredare translated (Last good reading 12m ago · keychain blocked) and untranslatable jargon is dropped rather than printed. The raw string stays in the row's tooltip.PlainLanguage.swiftowns every sentence the overlay says about a state. - Left's own mark is drawn in code; the providers' are theirs.
LeftCore/LeftMark.swiftis the app's own mark — an open ring, one shape, whose sweep is a constant because the mark is identity and the numbers beside it are data. The provider marks are Anthropic's, OpenAI's, and xAI's official logos, vendored from the vendors' own sites intoAssets/provider-marks/and drawn from their published geometry rather than redrawn: monochrome templates in the menu bar, because macOS owns a status item's appearance, and in each vendor's own colour in the overlay. docs/provider-marks.md records the sources, hashes, and trademark position;ProviderMarkProvenanceTestsfails if any of it drifts.
- Refresh runs on launch, whenever the overlay opens, every five minutes, and from the labelled Refresh button.
- Provider stale, authentication-required, rate-limited, unavailable, and
error states have distinct badges. A failed whole-command refresh restates
every menu-bar reading as the last known one (
~50%) and adds a banner to the overlay, so held-over data never looks current. - The production process arguments are fixed to
--provider claude,codex,grok --json. Left never passes--full, account identity, tokens, or keys as arguments, and it never prints provider errors. - The child process gets an allowlisted environment: reconstructed
HOMEandPATH, plus locale, temp, and user-name variables when they are already set. It does not inherit the rest of the app environment. - Command stderr is discarded. Stdout is read in a stream and aborted at 1 MiB, so a runaway child cannot fill memory. The app does not log or persist quota output.
- Only the exact non-secret
quota-axi --allow-keychain-promptrepair command can reach the UI.
Sources/LeftCore/QuotaModels.swiftowns schema-version 2 decoding.Sources/LeftCore/QuotaAXIAdapter.swiftdefines the adapter protocol, production process runner, and fixture adapter.Sources/LeftCore/UsagePresentation.swiftmaps raw states and windows to safe display values.Sources/LeftCore/PlainLanguage.swiftowns every state sentence, badge, and spoken value, so the menu bar and the overlay cannot word the same state two ways.Sources/LeftCore/MenuBarStatus.swiftcomposes the status item into one template image and states it in words for VoiceOver.Sources/LeftCore/PopoverLayout.swift,Palette.swift,LeftMark.swift, andProviderMark.swifthold the grid, the dark language, and the marks, so the view, the icon, and the tests all quote one source.Sources/Left/contains the status item, refresh store, SwiftUI overlay, preview renderer, and iconset renderer.Fixtures/demo-quota.jsonis the synthetic fixture for tests, demo mode, and visual evidence.
The research and trade-offs are recorded in docs/research.md; the rebrand and redesign decision is in docs/naming.md.
MIT. See LICENSE. The Anthropic, OpenAI, and xAI marks are not licensed as project copyright; see NOTICE and docs/provider-marks.md.

