Your ChatGPT and Claude usage limits as activity rings in the menu bar / system tray
Download · How it works · Privacy · Development
English · Русский
The tray icon shows how much of each limit you have used: the fuller the ring, the less is left. Click it for the details: every limit, the percentage used and when it resets.
- Apple Fitness–style rings. A monochrome icon with 1–3 concentric rings. On macOS it follows the menu bar appearance; on Windows it matches the taskbar theme.
- Smart default layout:
- one provider connected: its session (5-hour) and weekly limits;
- several providers: the session limit of each.
- Ring colour per provider. Monochrome by default (it follows the menu bar / taskbar like system icons); pick a preset (Apple Fitness red, green, cyan…) or any custom colour. Applies to the tray icon, the rings and the progress bars.
- Fully customisable. Put any metric of any account into any ring, e.g. "Claude · Weekly · Opus".
- Details on click: percentages, progress bars, "resets in 2h 18m · 12:10", your plan (Plus, Pro, Max…).
- Tooltip on Windows: hover the tray icon to see the percentage used and time to reset for every account.
- Low-limit alerts. A system notification when less than a set share of a limit is left (15% by default). One notification per limit, re-armed after the limit resets. The threshold and the alerts themselves are configurable.
- Background refresh every minute by default (1–30 min, configurable), plus an instant refresh when you open the popover. Errors and rate limits back off exponentially.
- Multiple providers and accounts, including several accounts of the same provider (e.g. work and personal Claude), added and removed in two clicks.
- Self-healing connections. Expired tokens are refreshed automatically (on 401 and 403). If a sign-in really is gone, the card shows "Sign in again" and you get a single notification. After sleep or a network change the data refreshes right away.
- Starts with your computer (can be turned off in Settings).
- Automatic updates. The app checks GitHub Releases in the background every hour. When a new version is out you get a notification (repeated once a day until you update) and an "Update" button that restarts into the new version.
- Feels native: Liquid Glass on macOS, Fluent on Windows 11, light and dark themes.
- Lightweight. Built with Electrobun and the system WebView, no bundled Chromium.
- English and Russian, light and dark. Both follow the system by default and can be set manually in Settings.
The easiest way is one command. It downloads the latest release and installs it without Gatekeeper / SmartScreen prompts:
# macOS (Apple Silicon)
curl -fsSL https://raw.githubusercontent.com/alxrepin/aiusagebar/main/scripts/install.sh | bash# Windows 10 / 11 (PowerShell)
irm https://raw.githubusercontent.com/alxrepin/aiusagebar/main/scripts/install.ps1 | iexOr grab the file for your system from the Releases page:
| System | File |
|---|---|
| macOS (Apple Silicon) | AIUsageBar-<version>-macos-arm64.dmg |
| Windows 10 / 11 (x64) | AIUsageBar-<version>-windows-x64-Setup.exe |
Once installed, AIUsageBar updates itself: when a new version is out, the popover shows an Update button.
macOS: "app is damaged" or "developer cannot be verified"
Releases are ad-hoc signed but not notarised by Apple. After moving the app to Applications, run once:
xattr -dr com.apple.quarantine /Applications/AIUsageBar.appOr right-click the app → Open → Open.
Windows: SmartScreen warns about an unknown publisher
Click "More info" → "Run anyway". The build is not signed with a publisher certificate.
Why do the prompts appear, and why doesn't the install script trigger them?
macOS and Windows flag files downloaded by a browser (quarantine attribute / "Mark of the Web") and then check them for an Apple notarisation ticket or a code-signing certificate. AIUsageBar is free and doesn't have either (an Apple Developer ID costs $99/year; a Windows certificate is similar). Files downloaded by curl or PowerShell aren't flagged, so the install script and the in-app updater never hit the prompt. You only deal with it once, if you install from the browser.
On first launch, open the popover and connect a provider. Each provider offers two ways to sign in:
| Browser sign-in | Existing CLI login | |
|---|---|---|
| Claude | "Sign in with Claude" opens claude.ai | "Use Claude Code login" reuses the claude CLI sign-in |
| ChatGPT | "Sign in with ChatGPT" opens chatgpt.com | "Use Codex CLI login" reuses ~/.codex/auth.json |
Browser sign-in is OAuth 2.0 with PKCE. The app briefly listens on localhost, the browser redirects the authorization code there, and the app exchanges it for tokens itself. Tokens are refreshed automatically. No intermediate server.
CLI login is read-only: AIUsageBar never rotates Claude Code or Codex tokens, so your CLI keeps working.
Several accounts of one provider. Click + next to the provider in Settings again. For ChatGPT the sign-in page asks which account to use; for Claude, sign out on claude.ai first (or pick another account there). Accounts are told apart by their provider account id, so reconnecting the same account updates it instead of creating a duplicate.
When an API stops answering. On 401/403 the app refreshes the token and retries. If the refresh is rejected, the card switches to "Sign in again" (CLI-linked accounts also get "Sign in with browser"), and a notification is shown once. Other errors (network, 5xx, 429) keep the last known data on screen and retry with growing pauses (1 → 30 min, honouring Retry-After).
Limits come from the same endpoints the official CLIs use:
- Claude:
api.anthropic.com/api/oauth/usage— 5-hour, weekly, and per-model (Opus / Sonnet) limits; - ChatGPT:
chatgpt.com/backend-api/wham/usage— primary and secondary rate-limit windows.
Note
These endpoints are not part of a public API and may change. Their URLs live in the CLAUDE_OAUTH and CHATGPT_OAUTH constants so they are easy to update.
-
No server. The app only talks to OpenAI and Anthropic, directly from your computer.
-
No telemetry or analytics.
-
Tokens live in the OS secret store, never in the settings file:
System Where tokens are stored macOS files encrypted with AES-256-GCM; the key is in the login Keychain (service AIUsageBar)Windows a file encrypted with DPAPI for the current user Linux Secret Service / libsecret, falling back to a 0600file -
Removing an account in Settings deletes its tokens from the store.
The gear icon in the popover opens Settings:
- Accounts: connected accounts, remove, add new;
- Rings: "Auto" or "Custom" — pick the metric for the outer, middle and inner ring;
- Ring colours: default monochrome, a preset or a custom colour for each connected provider;
- Notifications: turn low-limit alerts on or off and choose the threshold — 5, 10, 15, 20, 25, 30 or 50% left (default 15%);
- Appearance: system, light or dark;
- Language: system, English or Russian (also used for notifications);
- Launch at login: on by default;
- Refresh every 1, 2, 5, 10, 15 or 30 minutes;
- Tray icon (Windows / Linux): match taskbar, white or black;
- % in menu bar (macOS): show a percentage next to the icon.
Requires Bun 1.3 or newer.
git clone https://github.com/alxrepin/aiusagebar && cd aiusagebar
bun install
bun run dev # build and launch the app
bun test # unit tests
bun run typecheck # type checking
bun run preview # the popover in a regular browser with mock data
# → http://localhost:5173/?platform=mac|win|linux&scenario=two|one|empty
bun run build:stable # installer for the current OS → artifacts/src/
├─ shared/ types and the RPC contract between Bun and the webview
├─ bun/ main process
│ ├─ providers/ UsageProvider + claude/ and chatgpt/ implementations
│ ├─ auth/ PKCE, loopback listener for OAuth
│ ├─ usage/ accounts & refresh service, rings, low-limit alerts
│ ├─ store/ config.json and the secret store
│ ├─ tray/ ring rasteriser → PNG, tray icon controller
│ └─ popover/ the popover window and its positioning
└─ views/popover/ popover UI (TypeScript + DOM, no framework)
The logic doesn't depend on Electrobun and is covered by bun test. Only index.ts, popover.ts, trayController.ts and bridge.ts touch Electrobun.
Say you want Gemini. Two steps:
1. Implement UsageProvider in src/bun/providers/gemini/index.ts:
export class GeminiProvider implements UsageProvider {
id = "gemini";
displayName = "Gemini";
iconPath = "M…"; // SVG path, 24×24, monochrome
authMethods = [{ id: "oauth", label: "Sign in with Google", description: "…", kind: "browser" as const }];
async authenticate(methodId, ctx) {
// createPkce(), startLoopback() and ctx.openUrl are ready to use
return { credentials: { … }, label: "me@gmail.com", identity: "<stable id>" };
}
async fetchUsage(credentials, ctx) {
return {
usage: {
plan: "Pro",
windows: [
{ id: "session", label: "Daily", shortLabel: "1d", kind: "short", usedPercent: 40, resetsAt: "…" },
],
},
credentials: rotated, // if tokens were refreshed
};
}
}2. Add new GeminiProvider() to src/bun/providers/registry.ts.
Sign-in buttons, cards, ring selection, alerts, background refresh and token storage all work automatically. Throw ReauthRequiredError to show a "Sign in again" button on the card; throw RateLimitedError to back off.
Builds and releases run on GitHub Actions (release.yml):
- Every push to
mainruns the type check and tests, then builds for macOS (arm64) and Windows (x64). - If the version in
package.jsonhas no tag yet, avX.Y.Zrelease is published with the installers, the in-app update feed (stable-<os>-<arch>-update.json+ bundle) and generated release notes. Installed apps pick it up fromreleases/latest/download/.
To ship a new version, bump version in package.json and merge into main.
Apple signing and notarisation are optional. To enable them, add ELECTROBUN_DEVELOPER_ID, ELECTROBUN_TEAMID, ELECTROBUN_APPLEID and ELECTROBUN_APPLEIDPASS as repository secrets.
- No blur behind the window. Liquid Glass is done in CSS with a near-opaque tint; Electrobun 1.x can't blur the desktop behind a window (
NSGlassEffectView, Mica/Acrylic), and CSSbackdrop-filterin a transparent WebView flickers, so it isn't used. - Linux. Many AppIndicator implementations don't deliver plain clicks, so the icon has a menu.
- Not yet: an Intel Mac build.
- Versions before 0.3.0 have no updater: install 0.3.0 once, updates are automatic from then on.
MIT. Use, modify and share freely.
AIUsageBar is an independent project and is not affiliated with OpenAI or Anthropic. ChatGPT and Claude are trademarks of their respective owners.


