Chisle
The coding-agent plugin that bills 52% of a bare model across 20 live tasks. Terse persona + tool-output compressor + context diet.
翻訳待ち
リポジトリ情報はまだ収集していません。
No updates detected yet. GitHub releases will appear here.
macOS menu-bar app for tracking Claude.ai usage
翻訳待ち
Loading the full README.
Read the full README ↗A minimalist Claude usage tracker for the macOS menu bar.
usagi shows your Claude.ai session usage as a small gauge in the menu bar, and the full picture — the rolling 5‑hour session (on plans that have one), the weekly limit, and any paid overage spend — in a native dropdown.
"Beware of bugs in the above code; I have only specified it, not written it." – @duggan
brew tap duggan/usagi
brew install --cask usagi
Or grab the DMG from Releases and drag to Applications.
Sign in with your Claude account on first launch — the session token lives in your macOS Keychain and never leaves the machine.
claude.ai — an embedded WKWebView pointed at claude.ai/login to sign in, then claude.ai/api/... to read your usage windows and overage limit. Nothing is sent anywhere else.ie.duggan.usagi.session). "Sign out" deletes that entry and clears the embedded web view's cookies/storage.SMAppService mechanism — toggle it here, or in System Settings → General → Login Items.When usagi misbehaves — blank bars, wrong account, "Signed out" loops — the menu-bar UI is too small to explain what happened, but every interesting decision is logged. Everything is prefixed usagi: so it filters cleanly.
In Console.app: open Console, pick your Mac in the sidebar, type usagi: in the search box, and click Start streaming. Then trigger a refresh (click the menu bar icon, or wait for the next interval).
Or stream from the terminal:
log stream --predicate 'eventMessage CONTAINS "usagi:"' --style compact
What to look for:
usagi: orgs count=N, selected=… (uuid) — confirms which organisation was picked. If you're on a team/enterprise plan that ranks ahead of your personal org in the list, usage for the wrong org will be empty.usagi: five_hour util=… resets_at=… — the parsed 5‑hour window; only logged on plans that have one.usagi: seven_day util=… resets_at=… — the parsed weekly window, logged on every successful refresh.usagi: non-JSON response for /usage content-type=text/html … — claude.ai handed back HTML instead of JSON (usually a Cloudflare challenge). The first ~200 bytes of the body are logged so you can confirm.usagi: decode failed for /usage response: … — the JSON parsed but didn't match the expected shape; the body preview is logged.Requires macOS 14+ to run, and Xcode 16 or newer to build — the SwiftUI code needs the macOS 15 SDK (View.body is @MainActor there). swift test runs the unit tests.
./build.sh # release build → bin/Usagi.app
UNIVERSAL=1 DMG=1 ./build.sh # universal binary + DMG (drag-install)
open bin/Usagi.app
For a Developer ID-signed and notarized build:
SIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
NOTARIZE_PROFILE="usagi-notarize" \
DMG=1 UNIVERSAL=1 \
./build.sh
NOTARIZE_PROFILE is a notarytool store-credentials profile in your login keychain. Alternatively, pass NOTARIZE_KEY (path to .p8), NOTARIZE_KEY_ID, and NOTARIZE_ISSUER to use an App Store Connect API key directly.
Tag a commit vX.Y.Z and push. The release GitHub Actions workflow signs, notarizes, and publishes a DMG to the matching GitHub Release. The workflow runs inside a release environment with required-reviewer approval, so a stray tag cannot expose signing secrets.
Export the Developer ID Application certificate from Keychain Access (right-click → Export → .p12 with a strong password). Then:
base64 -i developer-id.p12 | pbcopy # paste into MACOS_CERTIFICATE
Create an App Store Connect API key at App Store Connect → Users and Access → Integrations → App Store Connect API. Role: Developer. Apple lets you download the .p8 exactly once. Then:
base64 -i AuthKey_XXXXXXXXXX.p8 | pbcopy # paste into APPLE_API_KEY
Create a release environment in repo Settings → Environments → New environment. Add yourself as a required reviewer.
Add secrets to the release environment (not repo-level secrets):
| Secret | Value |
|---|---|
MACOS_CERTIFICATE | base64 of the exported .p12 |
MACOS_CERTIFICATE_PWD | the .p12 password |
KEYCHAIN_PWD | any random password — used for the temp keychain |
SIGN_IDENTITY | full cert common name, e.g. Developer ID Application: Ross Duggan (XXXXXXXXXX) |
APPLE_API_KEY | base64 of the .p8 |
APPLE_API_KEY_ID | 10-character Key ID from App Store Connect |
APPLE_API_ISSUER_ID | the Issuer ID UUID at the top of the Keys page |
HOMEBREW_TAP_TOKEN | optional — fine-grained PAT with Contents: read & write on duggan/homebrew-usagi; enables auto-bumping the cask. Omit it and the release just skips that step. |
The temporary keychain is deleted on every job exit (success or failure), so secrets never persist on the runner.
The cask lives in duggan/homebrew-usagi (Casks/usagi.rb). Its source of truth is homebrew/usagi.rb in this repo — the release workflow substitutes the new version + sha256 and pushes the result to the tap, so a release auto-publishes the cask. Edit homebrew/usagi.rb here for anything else (zap paths, deps, …).
AppDelegate owning the NSStatusItem and its NSMenu (the first item hosts the SwiftUI usage bars; the rest are standard menu items rebuilt per state). The status-item image is redrawn reactively via withObservationTracking whenever AppState changes.@Observable root state: phase, snapshot, overage, organization, refresh interval. Coordinates load → refresh → sign-out lifecycle.URLSession-backed actor calling claude.ai/api/organizations, /usage, /overage_spend_limit. Sends Cookie: sessionKey=....WKWebView window pointed at claude.ai/login; observes the cookie store and persists the captured sessionKey to the Keychain.ie.duggan.usagi.session).AppState.refresh() on the configured interval.MIT.