You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The app has always been called "usage" publicly, but every internal
identifier — bundle id, filenames, launchctl label, ~/.claude/ paths —
spelled it "usag" (missing the trailing e). This unifies all of those
on "usage" and adds automatic migration so v0.1.x installs upgrade
cleanly:
- setup_hook clears legacy ~/.claude/usag-statusline.py and
usag-status.json, moves the "usag" backup key under settings to
"usage", and removes a statusLine command still pointing at the old
hook.
- install-launchagent / uninstall-launchagent bootout the old
com.lollapalooza.usag label and delete its plist before installing
the new one.
- usage_client reads usage-status.json first, falls back to the legacy
usag-status.json, then tt-status.json, so users running the new app
before Claude Code refreshes still see numbers.
Bumps to v0.2.0 as a breaking change. Users who only download the
.app will hit the in-app "立即安裝 hook" button on first launch and
not notice anything.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CONTRIBUTING.en.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,7 +23,7 @@ All three must be green to merge. CI runs the same three (`.github/workflows/che
23
23
## Code change guidelines
24
24
25
25
-**When changing prod modules, add tests alongside.** Pick the closest existing file under `tests/` as a style reference. Tests must never touch real `~/.claude/` or `~/.codex/` — use `monkeypatch` to redirect path constants.
26
-
-**Do not rename the technical short name `usag`.**All file paths, settings keys, binary names, environment variables, and the LaunchAgent label keep the `usag` prefix (it is a hook contract; renaming would break existing installs). The public-facing name is `usage`.
26
+
-**Keep internal and public naming unified as `usage`.**File paths, settings keys, binary names, environment variables, and the LaunchAgent label all use the `usage` prefix.
27
27
-**Be deliberate with `menubar.py` UI constants** (`CARD_HEIGHT`, `CARD_RADIUS`, `SECTION_GAP`, etc.); they are part of the popover's visual design.
Copy file name to clipboardExpand all lines: README.en.md
+19-19Lines changed: 19 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,15 +26,15 @@ usage installs a small **statusLine hook** — a script that Claude Code automat
26
26
27
27
1. Claude Code refreshes the status line and packages usage info (5-hour percentage, 7-day percentage, etc.) as JSON.
28
28
2. It pipes that JSON to the hook via stdin.
29
-
3. The hook writes the JSON to `~/.claude/usag-status.json`.
29
+
3. The hook writes the JSON to `~/.claude/usage-status.json`.
30
30
4. The usage UI reads that file.
31
31
32
32
Since both sides look at the same source data, **the numbers match exactly what Claude Code itself shows**.
33
33
34
34
```mermaid
35
35
flowchart LR
36
-
A[Claude Code main process] -->|pipes JSON to stdin<br/>on every statusLine refresh| B[usag-statusline.py<br/>hook script]
37
-
B -->|writes| C[(~/.claude/<br/>usag-status.json)]
36
+
A[Claude Code main process] -->|pipes JSON to stdin<br/>on every statusLine refresh| B[usage-statusline.py<br/>hook script]
37
+
B -->|writes| C[(~/.claude/<br/>usage-status.json)]
38
38
D[usage menu bar / TUI] -->|reads| C
39
39
D -->|renders| E[macOS menu bar]
40
40
F((Anthropic API)) -.x.- D
@@ -43,7 +43,7 @@ flowchart LR
43
43
44
44
Read priority:
45
45
46
-
1.`~/.claude/usag-status.json` — written by the hook usage installs.
46
+
1.`~/.claude/usage-status.json` — written by the hook usage installs.
47
47
2.`~/.claude/tt-status.json` — fallback. If you also use [token-tracker](https://github.com/stormzhang/token-tracker), usage will share its status file.
48
48
49
49
### Codex usage
@@ -68,16 +68,16 @@ If Codex isn't installed or the directory doesn't exist, that part of the UI hid
68
68
69
69
## Download the app
70
70
71
-
Go to the [GitHub Releases page](https://github.com/aqua5230/usage/releases/latest) and download the latest `usag.app.zip`. Unzip it and move `usag.app` wherever you like (e.g. `/Applications`).
71
+
Go to the [GitHub Releases page](https://github.com/aqua5230/usage/releases/latest) and download the latest `usage.app.zip`. Unzip it and move `usage.app` wherever you like (e.g. `/Applications`).
72
72
73
73
⚠️ Because this app is not signed with an Apple Developer certificate, **macOS Gatekeeper will block the first launch**.
74
-
To open it: find `usag.app` in Finder → right-click → Open → confirm Open. After that, double-clicking works normally.
74
+
To open it: find `usage.app` in Finder → right-click → Open → confirm Open. After that, double-clicking works normally.
75
75
76
76
### First launch: install the hook
77
77
78
-
The first time you open usag, if Claude Code has never been wired up yet, the popover will detect the missing status file and **show an extra "立即安裝 hook" (Install hook now) button at the bottom**. Click it once — it installs the hook for you. Then **fully quit Claude Code (Cmd+Q) and re-open it**, click "Refresh now" in usag, and the numbers will appear.
78
+
The first time you open usage, if Claude Code has never been wired up yet, the popover will detect the missing status file and **show an extra "立即安裝 hook" (Install hook now) button at the bottom**. Click it once — it installs the hook for you. Then **fully quit Claude Code (Cmd+Q) and re-open it**, click "Refresh now" in usage, and the numbers will appear.
79
79
80
-
If the button doesn't show, usag is already reading data (e.g. you previously installed [token-tracker](https://github.com/stormzhang/token-tracker) and its status file works as a fallback) — nothing else to do.
80
+
If the button doesn't show, usage is already reading data (e.g. you previously installed [token-tracker](https://github.com/stormzhang/token-tracker) and its status file works as a fallback) — nothing else to do.
81
81
82
82
> **Fallback: install via curl**
83
83
> If the in-app button doesn't work or you prefer the command line, paste this in Terminal:
@@ -107,7 +107,7 @@ This creates an isolated Python environment (`.venv`) for the project, activates
107
107
108
108
## First install (wire up the Claude Code hook — source mode only)
109
109
110
-
> Using the .app? Just click the "立即安裝 hook" button in the popover on first launch instead — you don't need this section. The steps below are for developers running usag from source.
110
+
> Using the .app? Just click the "立即安裝 hook" button in the popover on first launch instead — you don't need this section. The steps below are for developers running usage from source.
111
111
112
112
This single command does two things: copies the hook script into `~/.claude/`, and updates your Claude Code settings to point at it.
113
113
@@ -120,17 +120,17 @@ python3 main.py --setup
120
120
121
121
What `--setup` does in detail:
122
122
123
-
- Copies `usag_statusline.py` to `~/.claude/usag-statusline.py`.
123
+
- Copies `usage_statusline.py` to `~/.claude/usage-statusline.py`.
124
124
- Points `statusLine` in `~/.claude/settings.json` at that hook.
125
-
- If you already had a custom `statusLine`, it is backed up to `settings.usag.previousStatusLine` so nothing is overwritten.
125
+
- If you already had a custom `statusLine`, it is backed up to `settings.usage.previousStatusLine` so nothing is overwritten.
126
126
127
127
To uninstall:
128
128
129
129
```bash
130
130
python3 main.py --unsetup
131
131
```
132
132
133
-
`--unsetup` restores your original statusLine and removes the hook and `~/.claude/usag-status.json`.
133
+
`--unsetup` restores your original statusLine and removes the hook and `~/.claude/usage-status.json`.
134
134
135
135
## Run modes
136
136
@@ -180,12 +180,12 @@ A LaunchAgent (the macOS service that handles "what should start when this user
180
180
181
181
2.**Manual start (for testing):**
182
182
```bash
183
-
launchctl start com.lollapalooza.usag
183
+
launchctl start com.lollapalooza.usage
184
184
```
185
185
186
186
3.**Logs:**
187
-
- stdout: `~/Library/Logs/usag/usag.log`
188
-
- stderr: `~/Library/Logs/usag/usag.err.log`
187
+
- stdout: `~/Library/Logs/usage/usage.log`
188
+
- stderr: `~/Library/Logs/usage/usage.err.log`
189
189
190
190
4.**Uninstall:**
191
191
```bash
@@ -222,7 +222,7 @@ USAG_DEBUG=1 python3 main.py
222
222
223
223
## Behaviour notes
224
224
225
-
- usage only reads `~/.claude/usag-status.json`, `~/.claude/tt-status.json`, and Codex's session files. It does not call the Anthropic / OpenAI API and does not read the Keychain. The only network activity is a one-time download of the LiteLLM pricing table for Codex cost estimates (cached for 7 days; offline fallback available).
225
+
- usage only reads `~/.claude/usage-status.json`, `~/.claude/tt-status.json`, and Codex's session files. It does not call the Anthropic / OpenAI API and does not read the Keychain. The only network activity is a one-time download of the LiteLLM pricing table for Codex cost estimates (cached for 7 days; offline fallback available).
226
226
- When Claude Code isn't running, the status file isn't updated — but actual usage isn't changing either (until reset time), so the displayed value is still accurate. After reset time passes, it auto-resets to zero.
227
227
- If the status file hasn't been updated for more than 6 hours, the status line notes "status file is N minutes stale, numbers may be out of date."
228
228
@@ -234,7 +234,7 @@ USAG_DEBUG=1 python3 main.py
234
234
| Status says "N minutes stale" | Claude Code isn't running | Open Claude Code and let it run; it updates the file on its next status refresh |
235
235
| Codex section is empty |`~/.codex/sessions/` doesn't exist or has no `rate_limits` events yet | Run a Codex conversation to generate log entries |
236
236
| Today's cost shows $0.00 | Model name doesn't match the pricing table, or pricing download/cache failed | Delete `~/.claude/pricing_cache.json` to force a re-fetch; or run with `USAG_DEBUG=1` for details |
237
-
| App won't open (blocked by macOS) | Gatekeeper blocks unsigned apps | Finder → find `usag.app` → right-click → Open → confirm Open |
237
+
| App won't open (blocked by macOS) | Gatekeeper blocks unsigned apps | Finder → find `usage.app` → right-click → Open → confirm Open |
238
238
239
239
## Build a .app bundle (optional)
240
240
@@ -244,6 +244,6 @@ If you want to launch usage by double-clicking instead of opening a terminal, bu
244
244
./scripts/build_app.sh
245
245
```
246
246
247
-
The output is `dist/usag.app`. Double-click it or run `open dist/usag.app`.
247
+
The output is `dist/usage.app`. Double-click it or run `open dist/usage.app`.
248
248
249
-
Each GitHub Release build (push a `v*` tag) automatically builds the app in CI and attaches `usag.app.zip` to the Release page.
249
+
Each GitHub Release build (push a `v*` tag) automatically builds the app in CI and attaches `usage.app.zip` to the Release page.
0 commit comments