Skip to content

dennykim123/claude-codex-battery

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

35 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ”‹ Claude & Codex Usage Battery

License: MIT Platform: macOS SwiftBar plugin Runtime: bun Zero dependencies GitHub stars

A macOS menu bar widget that shows your remaining Claude Code and Codex usage limits as battery icons โ€” so you never have to open /usage again.

Menu bar battery widget

C = Claude ยท X = Codex. Each battery shows the remaining % of a limit window โ€” full & green means plenty left, red means almost out. Click for a detailed breakdown with reset times.

Ships two ways: a notarized native app (double-click install, zero prerequisites) and a single SwiftBar plugin โ€” one self-contained script, no third-party libraries. The battery icons are rendered as PNGs from scratch in pure JavaScript (node:zlib only), so there's no image library and no npm install. Network calls: two official usage endpoints โ€” Anthropic's and OpenAI's โ€” each fetched with your own local Claude Code / Codex login (the same data /usage and Codex's /status show โ€” see Privacy), plus an optional once-a-day update check (see Updating). (ccusage is an optional extra for the cost breakdown.)


What it shows

Group Batteries Source
C Claude 5-hour session ยท weekly ยท Fable (top-model weekly cap) Anthropic's OAuth usage API โ€” queried live with your local Claude Code login; account-level, so usage from every device/surface is included
X Codex 5-hour ยท weekly (or credit balance on the premium plan) Codex's account-level usage API (backend-api/wham/usage), queried live with your local Codex login โ€” same data Codex CLI's /status shows; falls back to ~/.codex/sessions/**/*.jsonl if offline

Click the widget for a dropdown with, per limit:

Claude Code ยท % left
  5h    โ–•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–โ–‘โ–‘โ– 87%  ยท  resets 2h 36m
  week  โ–•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ– 67%  ยท  resets 4d 2h
  Fable โ–•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–Žโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ– 41%  ยท  resets 4d 2h
  today by model ยท $55 total โ–ธ

Codex ยท prolite ยท % left
  week  โ–•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ– 100% ยท  resets 7d 0h

Colors follow a traffic-light scale: green โ‰ฅ 50 % left, amber < 50 %, red < 20 %.


Requirements

Using the native app? Skip this table โ€” it has no prerequisites (Claude Code just needs to be logged in; ccusage optional). The table below is for the SwiftBar-plugin variant.

Required? Install
macOS โœ… โ€”
SwiftBar โœ… brew install swiftbar
bun โœ… curl -fsSL https://bun.sh/install | bash
Claude Code โœ… for C batteries just needs to be logged in on this Mac (the widget reuses its login to query the usage API)
Codex CLI optional for the X batteries; without it, only Claude is shown
ccusage optional adds the cost / token / per-model breakdown in the dropdown โ€” the battery works fully without it

Note: This widget shows your own account's limits โ€” via your local Claude Code login and your local Codex session logs. If you don't use Claude Code (or Codex), there simply won't be any data to display.


Install

Option 1 โ€” Native app (no SwiftBar, no bun)

App iconย ย ย  App dropdown

Download ClaudeCodexBattery-vX.Y.Z.dmg from Releases, open it, and drag ClaudeCodexBattery.app into Applications. That's it โ€” the app is signed & notarized, so it runs with a double-click, and on first launch it offers to start at login. (A .zip is also published; it's what the in-app self-updater downloads.)

It's a native Swift port of the same widget: identical battery rendering, identical dropdown, same privacy model (see Privacy โ€” your tokens go only to the two usage endpoints). ccusage remains optional for the cost breakdown. Source lives in app/ โ€” ./build.sh for a local ad-hoc build, ./release.sh for the notarized release.

UI languages: English ยท ํ•œ๊ตญ์–ด ยท ๆ—ฅๆœฌ่ชž ยท ็ฎ€ไฝ“ไธญๆ–‡ ยท ็น้ซ”ไธญๆ–‡ ยท Espaรฑol โ€” follows your system language, or pick one in Settings โ†’ Language (the SwiftBar plugin follows the same choice).

Option 2 โ€” SwiftBar plugin (single auditable script)

git clone https://github.com/dennykim123/claude-codex-battery.git
cd claude-codex-battery
./install.sh

install.sh will:

  1. Verify bun and SwiftBar are present (and tell you how to install them if not)
  2. Copy the plugin into ~/.swiftbar-plugins/, rewriting the shebang to your machine's bun path (SwiftBar runs plugins with a minimal PATH, so an absolute shebang is required)
  3. Point SwiftBar at the plugin folder and launch it
  4. Install a launchd KeepAlive agent so SwiftBar comes back on its own โ€” after a reboot, after sleep, and even if SwiftBar crashes (it occasionally does). The battery just stays there; you never have to relaunch it by hand. (To turn it off completely: launchctl bootout gui/$(id -u)/com.dennykim.claude-codex-battery && osascript -e 'quit app "SwiftBar"'.)

No npm install, no bundled libraries โ€” the plugin is a single self-contained script.

The battery appears in your menu bar within a few seconds. It refreshes every 2 minutes (the .2m. in the filename).

Manual install

If you prefer not to run the script:

mkdir -p ~/.swiftbar-plugins
# rewrite shebang to your bun path, then copy:
sed "1s|.*|#!$(command -v bun)|" claude-codex-usage.2m.js > ~/.swiftbar-plugins/claude-codex-usage.2m.js
chmod +x ~/.swiftbar-plugins/claude-codex-usage.2m.js
defaults write com.ameba.SwiftBar PluginDirectory -string ~/.swiftbar-plugins
open -a SwiftBar

Updating

Native app โ€” checks GitHub for a newer version once a day (a tiny request for the VERSION file). When one is out, a green Install update row appears in the dropdown: one click downloads the signed zip from Releases, verifies its Developer ID code signature (team-pinned, so a tampered zip is refused), replaces itself in place, and relaunches. Headless equivalent: ClaudeCodexBattery.app/Contents/MacOS/ClaudeCodexBattery --self-update.

SwiftBar plugin โ€” the widget checks GitHub for a newer version at most once a day โ€” a tiny background request for the VERSION file. When a new version is out, a green ๐Ÿ†• update row appears in the dropdown; click it to replace the plugin in place and refresh (your previous copy is kept as .bak). There's also an always-visible โฌ†๏ธ update now row that replaces the plugin with the latest main on demand โ€” no waiting for the daily check.

Prefer to do it yourself? From your clone: git pull && ./install.sh.

To turn the check off entirely, comment out the getUpdateInfo() call near the bottom of the script โ€” then the only network call left is the Anthropic usage query.


Privacy & security

  • Claude limits come straight from Anthropic. The widget reads your Claude Code OAuth token from the macOS Keychain (item Claude Code-credentials) and calls api.anthropic.com/api/oauth/usage โ€” the same endpoint /usage uses. The token is sent only to api.anthropic.com, passed via stdin (never visible in ps), and never written to disk or logs. macOS may show a one-time Keychain permission prompt โ€” click Always Allow. (Clicking Deny makes macOS re-prompt on every refresh โ€” if you'd rather the widget never touch the Keychain, run touch ~/.claude/swiftbar/.no-live instead; it then reads local cache files only, like v1.1.)
  • Codex limits come straight from OpenAI. Likewise, the widget reads your Codex OAuth token from ~/.codex/auth.json and calls chatgpt.com/backend-api/wham/usage โ€” the same account-level endpoint Codex CLI polls itself. The token is sent only to chatgpt.com, via stdin (never visible in ps), and never written to disk or logs. (touch ~/.claude/swiftbar/.no-live disables both live queries; it then reads local files only.)
  • No API keys touched. Only the OAuth login tokens above are read โ€” never any OPENAI_API_KEY / ANTHROPIC_API_KEY.
  • No usage data leaves your machine. Nothing is uploaded anywhere; the only outbound calls are the two usage queries above (to Anthropic and OpenAI) and the optional daily update check (Updating).
  • No conversation content. From the Codex session-log fallback it parses only the rate_limits object (numbers), never the messages.
  • Auditable in one sitting. The whole widget is a single dependency-free script โ€” grep for curl/fetch and you've seen every network call it can make.

How accurate / in-sync is it?

Claude โ€” live. Every refresh queries Anthropic's usage API directly with your local Claude Code login โ€” the same server-side data /usage shows, so the numbers match it by construction. Because the limits are account-level, usage from every surface and device (terminal, desktop app, web, another machine) is already included. If the query fails (offline, logged out), the widget falls back to its last successful response and labels the reading with its age in amber.

Codex โ€” live too. The widget queries the same account-level usage endpoint Codex CLI polls internally (backend-api/wham/usage), using your local Codex login token. It's a read-only call that costs no tokens, and because it's account-level, all your machines see the same numbers โ€” so two Macs stay in sync. If the query fails (offline, logged out), it falls back to the newest local session log (labeled "measured N ago", warns past 3h) and then to its last live response.

TL;DR โ€” Both Claude and Codex are live and account-level, so every device shows the same numbers. When a live query fails, each falls back to a clearly-labeled cached/snapshot reading.


How it works

The whole thing is one .js file run by bun on a timer.

  • Battery icons are drawn pixel-by-pixel into an RGBA buffer and encoded to PNG using only node:zlib (hand-rolled CRC32 + IHDR/IDAT/IEND chunks). A 5ร—7 bitmap font renders the numbers and the C/X group labels. SwiftBar displays the PNG at pixels รท 2 pt.
  • Claude limits are fetched from Anthropic's OAuth usage endpoint using the Claude Code login token in your Keychain, with the last good response cached at ~/.claude/swiftbar/.claude-usage.json as an offline fallback. The Fable cap is the weekly_scoped entry.
  • Codex limits are fetched live from backend-api/wham/usage with the token in ~/.codex/auth.json, normalized to the same shape as the session-log format, and cached at ~/.claude/swiftbar/.codex-usage.json as an offline fallback (with the newest session log as a second fallback). The premium plan reports a credits object instead of percentages when exhausted; the widget handles both shapes.

Both queries are read-only and cost no tokens โ€” you never have to use Claude or Codex to get a fresh reading, and every device sees the same account-level numbers. Older builds refreshed Codex by quietly running a real codex command in the background (spending tokens) when the session-log value went stale; that's gone โ€” the live endpoint makes it unnecessary.


Customizing

Want to change Where
Refresh interval filename .2m. โ†’ .1m., .5m., .30s., โ€ฆ
Battery size โ†• row in the dropdown โ€” toggles between big (4ร—6 font, default) and small (3ร—5 font, ~25% narrower); stored in ~/.claude/swiftbar/.batt-size
Color thresholds heatRemain / heatRemainHex (20 % / 50 %)
Disable live Claude + Codex APIs (Keychain / token access) touch ~/.claude/swiftbar/.no-live (falls back to local cache files)
Which Claude limits to show the battItems.push(...) block

App or plugin โ€” which one?

Both variants show exactly the same batteries and dropdown, from the same two usage endpoints.

  • Native app โ€” one notarized .app, zero prerequisites, double-click and done. For anyone who just wants the battery in the menu bar (this was the roadmap item; it shipped in v2.0.0).
  • SwiftBar plugin โ€” one self-contained script, easy to audit in a sitting and trivial to fork. Its audience (Claude Code / Codex developers) already lives in the terminal, so brew install swiftbar is no barrier.

Contributing

Issues and PRs welcome โ€” especially for other plans/tools (e.g. mapping additional rate_limit shapes, or adding providers). Keep it dependency-free.

License

MIT

About

macOS menu bar widget showing Claude Code & Codex usage limits as battery icons ๐Ÿ”‹

Topics

Resources

License

Stars

79 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors