A live system monitor and Claude Code usage meter for the MacBook Pro Touch Bar — one tap away, whatever app you're in.
The strip shows:
| Section | Shows |
|---|---|
| CPU | Busy % with a neon progress bar |
| RAM | Memory used % (active + wired + compressed, like Activity Monitor) with a bar |
| ↓ / ↑ | Network throughput down / up |
| TMP | CPU temperature and top fan RPM, with a bar |
| Claude card | CL badge · model · status dot · 5h / Wk spend meters vs your budget |
Bars and meters are colour-coded green → amber → red as load (or budget) climbs.
By default the strip lives in the Control Strip (right of the bar) as a compact CPU glyph. Tap it and the full, centered strip expands with an ✕ button to close — so it never covers the buttons of the app you're using.
- A Mac with a Touch Bar (Intel MacBook Pro, 2016–2020).
- macOS 12 or later.
- Temperature and fan readings come from the Intel-only AppleSMC; they show
—on hardware without it.
make runThat builds a release binary, bundles it into build/TouchStats.app, and launches
it. Look for the CPU glyph in the Control Strip and tap to expand.
Other targets:
make app # build + bundle, but don't launch
make build # compile the release binary only
make stop # quit a running instance
make clean # remove build artifactsThere's no Dock icon — quit from the ▊ icon in the menu bar.
Set these in the environment (e.g. VAR=… open build/TouchStats.app):
TOUCHSTATS_BUDGET_5H/TOUCHSTATS_BUDGET_WK— the dollar budgets the Claude meters fall back to when your plan's real limits aren't available. Defaults are30and300; percentages arespend ÷ budget. See below.TOUCHSTATS_CONTROLSTRIP=0— show the full strip always, pinned in the app region next to esc, instead of the tap-to-expand Control Strip glyph. This covers the frontmost app's own Touch Bar controls.
The two meters show, in order of preference:
1. Your plan's real limits, read from ~/.claude/statusline-state.json. The same
5-hour and 7-day percentages /usage shows. Claude Code only ever pushes these —
they arrive in the JSON handed to a
statusLine command and nothing else
locally exposes them, so a statusLine script has to mirror them out.
claude-code-statusline writes
that file already; install it and the meters just switch over. Rolling your own?
Write the same shape:
state = {
"updated_at": int(time.time()),
"five_hour": {"used_percentage": 30.0, "resets_at": 1784203100},
"seven_day": {"used_percentage": 9.0, "resets_at": 1784458700},
}
dst = pathlib.Path.home() / ".claude" / "statusline-state.json"
tmp = dst.with_suffix(f".{os.getpid()}.tmp")
tmp.write_text(json.dumps(state))
os.replace(tmp, dst) # atomic — the widget never reads a half-written fileA window's number is trusted until its own resets_at passes, so closing Claude Code
doesn't make the meters lie — usage doesn't decay while nothing is running.
rate_limits is Claude.ai subscribers only; API-key users never get it.
2. A local estimate, when there's no such file (or a window has reset). The card
tails the JSONL transcripts under ~/.claude/projects, sums each assistant turn
inside the rolling windows, and prices per model (Opus / Sonnet / Haiku, including
cache reads and writes) against the dollar budgets above. Treat it as a rough gauge:
it's guesswork from a hardcoded price table, it reads $0 for any model it doesn't
know, and on a subscription it measures money you aren't actually spending.
Nothing leaves your machine either way.
To sit in the Touch Bar's Control Strip, TouchStats pins a glyph through the private
DFRFoundation framework — the same mechanism Pock
and MTMR use — and presents the full strip as a system-modal Touch Bar on tap. The
widget itself is a hand-drawn NSImage refreshed on a timer. See
CLAUDE.md for the architecture and the handful of load-bearing
constraints (it must run from an unsigned .app bundle, and launch as a regular
app before demoting to a background agent).