Your Claude Code usage, always in the corner of your eye — so you never stop to click just to check.
Seeing how much Claude Code you've used means stopping what you're doing and clicking into the usage screen — every single time. I just wanted to know, at a glance, without breaking focus.
So Moth is a tiny always-on-top card that keeps your 5-hour and weekly usage in the corner of your screen. It glows warm amber when you're fine, deepens to orange past 70%, and burns red as you get close to the limit — so you feel the number without even reading it. No clicking, no context-switch. Like its namesake, it lives beside the light: the more you burn, the warmer it glows.
By default the numbers come straight from Claude Code's own official usage feed, so they
match the /usage screen exactly, and nothing is sent anywhere — everything runs on your
PC. Two opt-in modes go further: live sync reads directly from Anthropic, and
Codex adds your ChatGPT usage beside your Claude usage. Each has its own honesty
section at the bottom; both are off until you turn them on.
Moth has a sibling: Cricket buzzes your phone the moment your coding agent finishes. Moth watches how much you've used; Cricket tells you when the work is done.
Just have the link? Paste this whole repo URL to Claude Code and say "install this for me" — it can run every step below for you. Or do it yourself:
1. Get Moth onto your PC. In PowerShell, clone it to a folder you'll keep (Moth registers this location with Claude Code, so don't put it somewhere temporary like Downloads):
git clone https://github.com/vinvomero/claude-moth.git
cd claude-mothNo git? On the GitHub page click Code ▸ Download ZIP, extract it somewhere permanent, then open PowerShell in that folder.
2. Install:
powershell -ExecutionPolicy Bypass -File install.ps1That's it. Moth appears in the top-left of your desktop (drag it wherever you like —
it remembers). It launches automatically whenever a Claude Code session is active,
and you can bring it back any time by typing /moth in Claude Code.
The bars fill in the moment your next Claude Code session makes its first request. Until then it shows "waiting for Claude usage data…".
If you unplug a monitor Moth was sitting on, it moves itself back onto a screen you
still have the next time it starts, and notes the move in widget-error.log. Restoring a
saved position exactly is the right behavior until that position stops existing.
Resize it by dragging any edge or corner, like a normal window — width and height are independent, the text stays crisp, and Moth remembers the size. Drag it wide and short to tuck under your taskbar, or tall and narrow along a screen edge.
Prefer it to start when you log into Windows instead? Run
install.ps1 -AutoStart. By default Moth only launches with Claude.
- 5-hour — how much of your rolling 5-hour allowance you've used, and when it resets. The tiny hourglass beside the reset time turns as the window burns down.
- Weekly — same, for the 7-day window.
- Per-model (when live sync is on) — a third bar for your model-scoped weekly limit, labelled by whichever model it currently tracks (Fable, Opus, Sonnet…). This one is Claude-only; Codex doesn't publish per-model limits.
- Reset times show the actual clock time and the countdown — e.g. "resets 10:40 PM · in 4h 20m" — so you know exactly when, not just how long.
- The glow tells the story, and the whole card heats up with it: warm amber normally, deep orange past 70%, red past 90% — the flame rising as you get close to the limit. The halo tracks whichever limit is hottest across both providers, so a red card while you're looking at calm bars means the other provider is the hot one.
- The tab (only with Codex on) sits above the bars: click Claude or Codex to switch which one the card is showing. Moth also follows on its own — when the provider you aren't watching takes a turn, the card moves to it.
--%means no reading, not zero. Some plans report no weekly Codex window at all, and a0%bar there would be a claim rather than a gap.- "updated Nm ago" tells you how fresh the numbers are. If data ever goes stale, the bars and glow mute to grey and the label says "last synced Nm ago" — the card stays fully solid, never see-through.
Claude Code's status-line feed (Moth's default source) only runs in the terminal, not the desktop app. If you live in the desktop app, turn on live sync so Moth reads your usage directly instead:
// in config.json, or your gitignored window-state.json
"live_sync": trueLive sync pulls the same numbers the /usage command shows, using the login token
Claude Code already keeps on your machine. See the honesty section below before
enabling — it's off by default on purpose.
If you also code with Codex, Moth can show its usage on the same card:
// in config.json, or your gitignored window-state.json
"codex": trueThen type /moth to restart it. A Claude / Codex tab appears above the bars, and
the first Codex numbers land within seconds. The halo keeps tracking whichever limit is
hottest across both, so the card can warn you about the provider you aren't looking at.
Turning this on changes nothing in your Claude Code settings. Optionally, so Moth can follow along and switch to whichever provider you're actually using:
powershell -NoProfile -ExecutionPolicy Bypass -File tools\install-activity-hooks.ps1That one adds its own hooks — see "What install does" below. Without it the tab still works; you just click it yourself. (Auto-follow also needs terminal Claude Code; the desktop app fires no hooks.)
Read Codex — the honest details at the bottom before enabling. It runs a program on your machine, which the default mode never does.
There's a menu-bar Moth for macOS too — a SwiftBar
plugin in mac/. Same real 5-hour + weekly numbers, same amber palette, in
your menu bar — and the same optional Codex section. See mac/README.md
for setup. (The tab, auto-follow, and the per-model bar are Windows-only; the Mac plugin
shows both providers at once instead of switching between them.)
Closed the widget? Type /moth in any Claude Code session and it restarts —
same position, fresh numbers.
powershell -ExecutionPolicy Bypass -File uninstall.ps1This closes the widget, removes the /moth command, removes any login auto-start, removes
its status-line entry and SessionStart hook from your Claude settings, and removes the
activity hooks if you installed them. Everything else is left untouched. A status line or
hook that is no longer this widget's is left alone.
To turn Codex off without uninstalling anything, set "codex": false (or delete the
key) and type /moth. Nothing is spawned again. To remove the activity hooks on their own:
powershell -NoProfile -ExecutionPolicy Bypass -File tools\install-activity-hooks.ps1 -UninstallUninstall does not delete %LOCALAPPDATA%\Moth\. It holds the Codex snapshot and the
activity stamps; delete the folder yourself if you want it gone.
To hide the widget just for now, click the small × in its top-right corner — it
stays hidden for the rest of this session and returns the next time a Claude session
starts (or right away if you type /moth).
| File | What it does |
|---|---|
install.ps1 / uninstall.ps1 |
one-time setup / removal |
capture-usage.ps1 |
saves your latest usage whenever a Claude session is active (also relaunches Moth if it's not running) |
capture-codex.ps1 |
asks a local codex app-server for your ChatGPT limits — only ever run when codex is on |
touch-activity.ps1 |
records "a turn just happened", so the card can follow the provider you're using (only if you install the activity hooks) |
ensure-widget.ps1 |
what the SessionStart hook runs — brings Moth back with a new session |
widget.ps1 |
the moth itself |
restart-widget.ps1 |
what /moth runs — stop + relaunch |
commands/moth.md.tmpl |
template for the /moth command install |
launch-widget.vbs |
starts the widget with no console window |
mac/moth.5m.sh |
the macOS menu-bar version (see mac/README.md) |
tools/ |
the test suites, the fixtures they run against, the GIF renderer, and the optional activity-hook installer — nothing here runs unless you run it |
assets/moth-logo.svg |
the Moth mark |
config.json |
refresh rate, "stale" threshold, default position/size, live_sync, codex — edit if you like (size is also just drag-resizable) |
usage-cache.json |
the latest saved numbers (created automatically) |
window-state.json |
where you dragged the widget, plus your personal live_sync / codex / codex_exe overrides (created automatically, gitignored) |
widget-error.log |
errors the widget couldn't show you — a failed launch, an unparseable window-state.json, a window rescued from a monitor that no longer exists, a Codex failure that changed class |
Two runtime files live outside the repo, under %LOCALAPPDATA%\Moth\, because this
folder is often in OneDrive — which rewrites file times and would forge the activity
signal. Nothing here is created unless you turn Codex on.
| File | What it holds |
|---|---|
codex-cache.json |
the last Codex snapshot: percentages, reset times, window lengths, plan type, and a truncated error message. No account id, no credits, no token |
activity.json |
one timestamp per provider — when each last took a turn. No prompts, no content |
touch-activity.ps1 |
the execution copy the hooks run, if you installed them (the repo copy stays the source of truth) |
- Claude Code 2.1.80 or newer — that version is when the official status-line usage
feed shipped. Check with
claude --version; upgrade withwinget upgrade Anthropic.ClaudeCodeorclaude update. - Windows PowerShell 5.1 (the built-in
powershell.exe, present on every Windows 10/11). The widget uses WPF, which needs the Desktop edition's single-threaded apartment; the launcher callspowershell.exeexplicitly for this reason. If the widget ever fails to appear, checkwidget-error.login this folder.
For Codex ("codex": true) only:
- The
codexCLI, signed in with your ChatGPT account — not an API key. Tested with codex-cli 0.152.0 (the desktop app's bundled build). Annpm i -g @openai/codexinstall works too. - If yours lives somewhere unusual, point Moth at it with
"codex_exe"inwindow-state.json— forward slashes, so the JSON stays valid:"codex_exe": "C:/Users/you/AppData/Local/OpenAI/Codex/bin/abc123/codex.exe". - If you use Codex but not Claude Code in the terminal, nothing triggers Moth to launch.
Install with
-AutoStartso it starts with Windows.
install.ps1 makes exactly three changes by default and backs up your settings first:
- Adds a
statusLineentry to~/.claude/settings.json(your pre-install file is saved once tosettings.json.usage-widget.bak). If you already had a custom status line, it warns you before replacing it — and uninstall leaves a status line alone if it's no longer this widget's. - Adds a
SessionStarthook to the same file, so Moth comes back when a Claude session starts. Uninstall removes only its own entry and leaves your other hooks alone. - Adds a
/mothcommand file at~/.claude/commands/moth.mdso you can restart the widget from inside Claude Code.
Turning Codex on makes none of these changes — "codex": true is just a line in a
JSON file Moth already reads.
The activity-hook installer (tools/install-activity-hooks.ps1, optional, for
auto-follow) is separate and makes its own changes, which uninstall also reverses:
- Two hook entries in
~/.claude/settings.json, onUserPromptSubmitandStop. These fire on every prompt, not once per session. - One file,
%LOCALAPPDATA%\Moth\touch-activity.ps1— a copy, so a folder that moves or a OneDrive file that dehydrates can't break a hook that runs on every turn. - Its own backup at
settings.json.moth-activity.bak, taken on install only.
Run it with no Claude Code session open: Claude Code hot-reloads settings.json and
writes it itself, so a concurrent edit can be clobbered.
Optionally (only with -AutoStart): a Startup shortcut that runs the widget hidden
(-WindowStyle Hidden) with -ExecutionPolicy Bypass, from this folder. That's a normal
way to run a personal script on login, but you should know it's happening — and keep this
folder somewhere only you can write to, so nobody can swap widget.ps1 out from under it.
Run install from a normal (non-admin) PowerShell. If you install from an elevated "Run as administrator" window, the widget runs elevated too — and Claude Code (running normally) then can't see it to refresh or restart it, so
/mothand auto-relaunch stop working. A normal window is the right way to run a personal script.
uninstall.ps1 reverses all of it cleanly.
By default it does not touch your login token, call any private endpoints, or run any
program — it only reads the usage numbers Claude Code already shows you, and everything
stays on your machine. live_sync changes the first two; codex changes the third. Both
are off unless you turn them on, and each is spelled out below.
Off by default. Setting "live_sync": true (in config.json, or in your personal
window-state.json to keep the repo clean) makes Moth refresh directly from Anthropic
every ~3 minutes — even in the desktop app, even when no terminal session is running —
and shows a third per-model weekly bar (Opus/Sonnet/Fable) when available.
(The old key name fable_bar still works.)
Why you'd want it: the status-line feed only runs in the terminal. In the desktop app, live sync is the only way to keep the numbers current.
Read this before enabling: this mode calls an undocumented Anthropic endpoint
(api/oauth/usage) using the login token Claude Code already stores on your machine. Several
public tools do the same and it works reliably today, but Anthropic's policy language says
subscription tokens are for Claude Code/claude.ai use, and the endpoint could change or break
at any time. The widget never runs its own login, never logs or transmits the token anywhere
except to Anthropic, sends the User-Agent the endpoint expects, backs off politely on errors,
and degrades to the status-line feed if the endpoint fails. If any of that makes you
uncomfortable, leave it off — the default mode is fully within documented behavior.
Token nudge (part of live sync): the stored login token expires every ~8 hours, and a
long-running Claude app refreshes it in memory without writing the file — which would
freeze live sync mid-session. When Moth sees the token has expired, it wakes a minimal
headless Claude Code process (claude -p "ok" on Haiku — one tiny request, at most a few
times a day) so Claude itself refreshes and rewrites its token the official way. Moth
never touches the token lifecycle directly. Set "token_nudge": false in config.json to
disable; Moth will then just show "open a Claude session to re-sync" when it happens.
Off by default. This one is different in kind from live sync: it doesn't call an endpoint, it runs a program on your machine. Here is everything it does.
1. It uses an experimental interface. codex app-server is OpenAI's local JSON-RPC
server for editor integrations. It is not a documented public API, and the method Moth
calls (account/rateLimits/read) can change or vanish in any release. When it does, Moth
says so in plain words — the widget shows Codex too old for rateLimits/read — instead of
showing you a stale number. Every failure gets its own name: a CLI that never started, one
that quit before answering, one that answered with nothing usable, and each JSON-RPC error
code are four different messages, because they have four different fixes.
2. It launches a hidden process, as you, on a timer. Roughly every 3 minutes while
Moth is running, and again shortly after a Codex turn — never more often than once every
60 seconds, including across a /moth restart (the floor is read back from the last
snapshot on disk, not just held in memory). It runs
codex -s read-only -a never app-server --stdio with no console window, gives it 8
seconds to answer, then closes the pipe and kills the whole process tree — a hung one can
take a couple of seconds more to tear down. It never runs the bare codex command, which
can open an interactive browser sign-in.
3. Moth never reads your Codex credentials — but the process it starts does.
~/.codex/auth.json is never opened by any Moth script. The app-server owns its own login
and makes the request to OpenAI itself, exactly as it does when your editor talks to it —
which means it may refresh and rewrite that token file, the same as any other Codex
session would.
4. It loads your whole Codex config. Starting the app-server reads ~/.codex/config.toml,
including any MCP servers you have configured. On codex-cli 0.152.0 this was measured
not to start them for a rate-limit read — the only processes that appeared were the
app-server itself. That is an observation of one version, not a guarantee of every version.
5. Activity is a file's timestamp, never its contents. To follow the provider you're
actually using, Moth reads the modified time of the newest rollout-*.jsonl under
~/.codex/sessions/ — an allow-list of one filename pattern, not a scan of the folder. It
never opens those files: your prompts and transcripts are not read. (It deliberately
ignores logs_2.sqlite-wal, which ticks every ~12 seconds on its own and would report
activity that never happened.)
6. No Codex hooks are installed. Whether the Codex desktop app fires the hooks in
~/.codex/hooks.json is unconfirmed, and a hook that silently never fires is worse than
no hook. Nothing is added to any Codex config.
7. What the cache holds. %LOCALAPPDATA%\Moth\codex-cache.json: your two percentages,
their reset times and window lengths, your plan type, and — on failure — an error class,
a JSON-RPC code, and a message truncated to 200 characters. The reply is copied field by
field, so the account id, credit balance, and upsell text that arrive alongside it are
dropped, not stored.
8. The activity hooks, if you install them. Two entries in ~/.claude/settings.json
(UserPromptSubmit and Stop) that run %LOCALAPPDATA%\Moth\touch-activity.ps1. All it
writes is one epoch timestamp per provider. They fire on every prompt, so they run from a
copy outside this folder rather than from OneDrive. -Uninstall removes both, and refuses
to touch a settings.json it can't parse.
9. How it finds codex. In order: your "codex_exe" override, then CODEX_CLI_PATH
in ~/.codex/config.toml (which the desktop app rewrites on every update), then PATH
(preferring codex.exe, then codex.cmd — never the .ps1, which can't be launched
directly), then the newest build under %LOCALAPPDATA%\OpenAI\Codex\bin. If none of that
finds it, set the override with forward slashes:
"codex_exe": "C:/Users/you/AppData/Local/OpenAI/Codex/bin/abc123/codex.exe"If any of this makes you uncomfortable, leave it off. Nothing above happens while
"codex" is absent or false.
*
.~\ /~.
\ \ / /
`-.\ /.-'
(o o)
) (
' `
drawn to the light

