@thedevdavid/sage
v0.2.0
Published
Local-only usage & billing-cycle tracker for LLM API keys and subscriptions (OpenAI, Anthropic/Claude, Kimi, Cursor).
Maintainers
Readme
🌿 sage
Know your LLM usage at a glance. Nothing else.
sage is a tiny, open-source, local-only toolkit that shows what you have
left: subscription usage for Claude Max, ChatGPT (Codex), Kimi Code, and
Cursor — plus billing-cycle spend/balance for OpenAI, Anthropic, and
Kimi (Moonshot) API keys. No signup, no server, no database, no telemetry —
everything lives in ~/.sage/ on your machine.
Four pieces, one shared local store (the website is just this product's page):
| Piece | What it is |
| --- | --- |
| CLI (cli/) | Zero-dependency CLI (Bun or Node ≥ 18), on npm and Homebrew |
| macOS app (sage/) | Menu bar app, on Homebrew and GitHub releases |
| Agent skill (skills/sage/) | Teaches coding agents to answer usage questions via the CLI |
| Website (site/) | This product's single-page static site |
Install
brew install thedevdavid/tap/sage # CLI
brew install --cask thedevdavid/tap/sage # macOS menu bar appOr without Homebrew: run the CLI straight from npm
(bunx @thedevdavid/sage status), or grab sage.app.zip from
GitHub releases.
Quick start
sage add openai # or anthropic, kimi — prompts securely for your key
sage status● claude · Max (20x)
Weekly ████████░░░░░░░░ 52% left · 3d 4h
Session (5h) ██░░░░░░░░░░░░░░ 87% left · 2h 10m
● cursor · Pro
Monthly █████░░░░░░░░░░░ 34% left · 2026-08-06
API keys
openai $14.20 spent this cycle
kimi 38.44 CNY balance
cycle: day 12/31 · resets 2026-09-01 (19d left)Subscription tracking
Nothing to configure: sage auto-detects local sessions from Claude Desktop
(its encrypted Cookies database and Keychain safe-storage item), Claude
Code, Codex, Kimi Code, or Cursor (its state.vscdb), and queries the same
backend endpoints those tools use. Claude Desktop's session is preferred when
present, so Claude Max does not require a separate Claude Code login. Expiring
Kimi Code access tokens are refreshed through Kimi Code's existing local OAuth
credential store; no tool or browser is opened. Env overrides:
CLAUDE_CODE_OAUTH_TOKEN, CODEX_HOME, KIMI_CODE_API_KEY.
You get plan name, usage windows (session/weekly/monthly), and reset times. An expired session shows the provider's own recovery step instead of stale numbers.
What each API provider can report
sage never invents numbers — provider APIs differ a lot:
- Kimi (Moonshot): account balance via
/v1/users/me/balancewith a regular key. - OpenAI: regular key → validity only. Add an admin key for per-cycle
spend (
/v1/organization/costs). - Anthropic: regular key → validity only. Add an admin key
(
sk-ant-admin…) for per-cycle spend (/v1/organizations/cost_report).
No provider exposes your actual billing cycle via API, so sage anchors the cycle to a monthly reset day you choose:
sage cycle --set-reset-day 15CLI commands
sage status [--json] cycle + usage for keys and subscriptions (default)
sage add <provider> add an API key (openai, anthropic, kimi)
[--key K] [--admin-key K] prompts securely when flags are omitted
sage remove <provider> remove an API-key provider
sage usage [name] [--json] detailed usage for one source or all of them
sage cycle [--set-reset-day N] show billing cycle, or set the monthly reset day
sage skill install [--project] install the agent skill
sage help show help
sage version show version--json output is stable and agent/script-friendly.
Local storage
~/.sage/config.json— keys + cycle reset day, writtenchmod 600. Shared by the CLI and the menu bar app (you can add keys from either).~/.sage/cache.json— last successful fetch per provider, so the menu bar app and offline runs still show something (marked as cached).
macOS menu bar app
brew install --cask thedevdavid/tap/sageA leaf appears in your menu bar with subscription windows and per-provider
usage. Add keys directly from the app (+ button → paste, validates on save) or
from the CLI — both share ~/.sage/. It refreshes every 15 minutes, and the
Refresh now button forces an immediate pull from every detected source.
Agent skill
npx skills add thedevdavid/sage # via skills.sh, into your agent's skill dirOr via the CLI (same SKILL.md, copied to ~/.agents/skills/sage/, or
./.agents/skills/sage/ with --project):
sage skill install [--project]Your coding agent then knows to run sage status --json when you ask
about API spend or cycle status — without ever reading your keys.
Development
- CLI:
bun cli/bin/sage.js --help(Bun or Node ≥ 18, no dependencies, no build step). - App:
xcodebuild -project sage.xcodeproj -scheme sage -destination 'platform=macOS' build(macOS 26+, Xcode 26+). The project is kept at object format 77 (Xcode 16+) so hosted CI runners can build it. If Xcode offers to upgrade the project format, decline — a newer format makes the release workflow fail to open the project. - Site:
python3 -m http.server 8080 -d site— one staticindex.html, no build step. - Screenshots:
scripts/build-capture-window.shonce, thenbuild/capture-window.app/Contents/MacOS/capture-window out.png --app-name sagecaptures the menu bar popover programmatically (ScreenCaptureKit; it opens the popover itself). Needs one-time Screen Recording + Accessibility permission for thecapture-windowapp.
Releasing
make release VERSION=0.1.9That bumps cli/package.json, commits, tags v0.1.9 and pushes. The tag
triggers .github/workflows/release.yml, which does the rest on a macOS
runner: smoke-tests the CLI, builds and zips the app, creates the GitHub
release, publishes to npm (trusted publishing — no token stored), and commits
the bumped formula + cask to thedevdavid/homebrew-tap.
The only stored credential is TAP_TOKEN, a fine-grained PAT limited to the
tap repo (Contents: read and write) — cross-repo pushes are the one thing the
built-in Actions token cannot do.
The app ships ad-hoc signed, so macOS warns on first launch. See SIGNING.md to set up Developer ID signing and notarization, which the release workflow picks up automatically once the secrets exist.
License
MIT
