by michellzappa
Local-first AI coding quotas and ship status, on your menu bar, iPhone, Watch and an ESP32 desk display.
# Add to your Claude Code skills
git clone https://github.com/michellzappa/headroomheadroom is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by michellzappa. Local-first AI coding quotas and ship status, on your menu bar, iPhone, Watch and an ESP32 desk display. It has 66 GitHub stars.
headroom's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/michellzappa/headroom" and add it to your Claude Code skills directory (see the Installation section above).
headroom is primarily written in Python. It is open-source under michellzappa on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh headroom against similar tools.
No comments yet. Be the first to share your thoughts!
Unlocks once the catalog security scan passes (runs nightly).
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
Your AI coding quotas and ship status — on the desk, in the menu bar, and on your phone.
When you're deep in Claude, Codex, or Cursor, you shouldn't have to dig through
billing pages, gh, and Vercel to answer: Am I about to hit a limit? Did CI
go red? Is prod healthy?
Headroom is a local-first desk gadget + macOS menu bar (+ optional iPhone) that consolidates that into one glance:
| Always on | What you see |
|---|---|
| ESP32 AMOLED | Quota rings for the same three providers the menu bar shows, with a combined seven-day burndown |
| Menu bar | Thin remaining-quota meters for the first three enabled providers + amber/red attention pip |
| Popover | Overview rings, daily burn, spend, Activity / Services |
| Notification Center | The same widget the iPhone runs: rings small, combined burndown medium |
| iPhone / iPad | Quotas, burndown, activity, services, controls, notifications, widgets |
| Apple Watch | Two complications: one ring per source, or the week's burndown |
One Python host on your Mac reads local auth + CLIs and serves a single JSON feed. No cloud account for Headroom itself — your tokens stay on the machine.
~/.claude JSONL + OAuth Mac (Python, stdlib) Clients
~/.codex + Cursor state.vscdb ┌──────────────────┐ ┌──────────────┐
~/.gemini + Windsurf profile ─▶│ headroom_ │◀── HTTP ────│ Menu bar app │
Copilot / JetBrains / Zed │ server.py :8737 │◀── HTTP ────│ iPhone app │
Vercel / git / gh / SB / Plaus. │ + usb_bridge │◀── HTTP/USB─│ ESP32 /usage │
~/.headroom/{config,sources} └──────────────────┘ └──────────────┘
Hardware is optional. The menu bar alone is useful. The Waveshare ESP32-S3-Touch-AMOLED-1.8 (368×448) is the always-on desk glance — same feed, tap a slot for detail, tap the header to switch Burndown / Activity, and long-press to force-refresh. Its three rings are the same three the menu bar draws — the host picks them and the board draws what it is sent, so a newer provider, an extra account, your pinned order and your color overrides all reach the desk. The default lower half combines those providers into the same seven-day burndown the Mac, phone and medium widget show.
| Need | Notes |
|---|---|
| macOS 14+ | Menu bar app |
| Python 3.9+ | Bundled host is stdlib only (system /usr/bin/python3) |
| At least one AI coding tool | Claude, Codex, Cursor, Copilot, Gemini, Windsurf, JetBrains AI or Zed, already signed in locally |
| Optional: iPhone / iPad (iOS 17+) | Same LAN or Tailscale as the Mac |
| To build from source: Xcode and XcodeGen | Not either/or — the .xcodeproj is generated, so brew install xcodegen is required, not optional |
| Optional: PlatformIO | Only if you flash the ESP32 |
No Headroom cloud account. Tokens stay on your Mac.
Headroom.app (notarized builds open normally;
ad-hoc builds need right-click → Open once)..app, the host starts automatically and installs a
LaunchAgent so it stays up at login (and after you quit the menu bar).
Use Start host & keep at login only if that didn’t happen.Updating. scripts/update-app.sh replaces an
installed Headroom.app with the current Release. It refuses anything that is
not notarized and signed by the project's team, and it brackets the swap with
launchctl bootout / bootstrap — the host runs from inside the bundle under
a KeepAlive agent, so replacing the app under a live agent leaves launchd
holding the old code.
./scripts/update-app.sh --check
./scripts/update-app.sh
git clone https://github.com/michellzappa/headroom.git
cd headroom
./scripts/build-app.sh # embeds host → dist/Headroom.app
open dist/Headroom.app
Or the two-piece flow (host from clone, debug app):
./scripts/install-host.sh
./scripts/gen-project.sh # embeds host + writes Headroom.xcodeproj
cd macos
xcodebuild -project Headroom.xcodeproj -scheme Headroom \
-configuration Debug -derivedDataPath .build build
open .build/Build/Products/Debug/Headroom.app
Foreground try (no login item): ./scripts/install-host.sh --foreground
Uninstall LaunchAgent: ./scripts/uninstall-host.sh (--purge wipes ~/.headroom)
A fresh clone contains no .xcodeproj, and that is expected: macos/project.yml
is the source of truth and XcodeGen writes the project from it, so the generated
macos/Headroom.xcodeproj is gitignored. On a new Mac, write it first:
brew install xcodegen
./scripts/gen-project.sh
open macos/Headroom.xcodeproj
Go through the script rather than calling xcodegen generate yourself.
project.yml lists macos/host as a source directory, and that folder is a
gitignored copy of the host made by sync-embedded-host.sh — on a fresh clone
bare xcodegen stops at a missing source directory, which does not point at the
real cause. The script syncs first.
Anything touching the watch app needs the beta toolchain, and that includes the iPhone app, which embeds it. Stable Xcode reports a watchOS SDK and still resolves every watch destination to "watchOS 26.5 is not installed":
open -a /Applications/Xcode-beta.app macos/Headroom.xcodeproj
Regenerate after any pull that adds files. A new file under Shared/ will not be
in the project you generated last week, and the failure reads as a missing type
rather than a stale project. Quit Xcode before regenerating — replacing the
project underneath a running Xcode is what produces "The project “Headroom” is
not a valid property list" on a file that is perfectly valid.
The phone uses the mobile token. The ESP32 uses the separate host token. See Tokens below.
~/.headroom/sources.json is seeded from local detection — only providers
that look signed-in are enabled. If none are found, every quota source stays
on so the UI can show sign-in errors.~/.headroom/config.json later for git authors / GitHub org / timezone.curl -s localhost:8737/health | python3 -m json.tool
curl -s localhost:8737/setup | python3 -m json.tool
Onboarding and Settings keep them apart, because they answer different questions and take different setup:
/usage).| Dev tool | Where |
|---|---|
| GitHub Actions | Settings → GitHub token (or gh / HEADROOM_GITHUB_TOKEN) |
| Supabase | Settings → Supabase PAT |
| Plausible | Settings → Plausible Stats API key |
| Vercel | Already signed into the Vercel CLI |
| Git / local servers | dev_root + git_authors in ~/.headroom/config.json |
Which repos Actions watches is editable in Settings → GitHub Actions: owner filters, an always-watch list, and the discovery cap. Settings also shows the repos those settings resolve to on this machine.
Both lists toggle under Settings, each in its own section — the same flags drive the menu bar, overview rings, iPhone, and the board.
More than one account per tool. Personal Claude and work Claude, two ChatGPT logins, a second Cursor profile — each is a separate plan with its own quota, and Headroom used to show only whichever one the CLI wrote last. Add the others in Settings → Extra accounts: pick the provider, name it, and point it at the credential location that login already uses.
| Provider | What to point it at |
|---|---|
| Claude | A second config folder — CLAUDE_CONFIG_DIR, e.g. ~/.claude-work |
| Codex | A second CODEX_HOME, e.g. ~/.codex-work |
| Gemini | A second Gemini CLI home, e.g. ~/.gemini-work |