Token and cost reporting for pi sessions — a live footer, a /usage dashboard, and an agent-callable status tool. Local by default: no network calls, and no LLM tokens spent asking about tokens.
Part of the Pify suite. Install with pify install usage or pi install npm:@pify/usage.
Spend is invisible until the invoice arrives, and by then you cannot tell which session did it. Everything needed to answer that is already on disk — pi writes usage and cost into every session file — so the answer should cost nothing to produce.
📊 12.3k tok · $0.45
Folded from each message's usage.cost, which pi already computes. It survives /reload by replaying the session branch rather than keeping a running total in memory.
Session
tokens in 120.3k · out 8.2k · cache 1.1M read / 0 write
cost $0.45 (23 responses)
context ~34% of the window
History (214 local session files)
today $1.23 · 450.2k tok
7 days $8.90 · 3.2M tok
30 days $21.40 · 9.8M tok
By model (all time)
anthropic/claude-fable-5 $12.30 · 4.1M tok
openai/gpt-5.5 $9.10 · 5.7M tok
By project (all time)
D--project-pify-plugins $14.80 · 6.2M tok
D--project-shop-api $6.60 · 3.6M tok
History counts every usage-bearing entry in pi's session JSONL — assistant turns plus the tool-result and compaction usage pi persists — so a session's total matches what you were billed rather than what the visible messages add up to. Negative and NaN fields clamp to zero, days are your local calendar days, and a per-file mtime cache keeps repeat scans instant.
Per-project totals come for free: pi stores sessions one directory per project, so the dashboard can show where the money actually went.
Context window: 22.6k of 200.0k used (11%)
System prompt ···························· <1% 11
Context files ···························· 1% 3.0k
Tool definitions ···························· <1% 371
Tool results ██·························· 8% 16.8k
Conversation ···························· 1% 2.4k
Free space █████████████████████████··· 89% 177.4k
"Why am I at 60%?" usually has a boring answer — one read of a 4,000-line file — and this is where you find it.
Computed entirely from what pi already holds: the assembled system prompt, the files and skills embedded in it, the enabled tool definitions, and the entries that would be sent. No network, no model call.
Context files and skills are counted only when their text is genuinely embedded in the prompt, and the system-prompt row is the remainder after subtracting them, so the rows sum to the whole instead of double-counting. When the provider reports more than can be attributed, the difference is shown as Other rather than quietly dropped.
The one command here that touches the network, and only when you run it:
Quota (OpenRouter · sk-or-v1-abc...xyz)
spent $0.33 (no credit limit on this key)
window day $0.01 · week $0.33 · month $0.33
Quota (DeepSeek · granted 10 · topped up 100)
balance CNY 110.00
Documented endpoints only. OpenRouter's /api/v1/key and DeepSeek's /user/balance are published APIs that report a real balance. The subscription-quota endpoints available for some other providers are undocumented private APIs reverse-engineered from vendor CLIs — they break without notice and were never offered to third parties, so this package does not call them. A provider you have not configured is simply not shown; that is not a failure.
A credentialed request is pinned down, because it carries your provider key:
- HTTPS only, and the host must be on that provider's allowlist.
- Redirects are refused outright. Following one lets whatever answered choose where the next request goes, with the header already attached.
- A non-2xx body is never read. Error bodies echo request details back, and an echoed
Authorizationheader pasted into a notification is exactly the leak this must not cause — the status alone becomes the message. - Raw exception text is dropped rather than shown, and everything printed passes a redactor as a last line of defence.
- An 8-second timeout per provider; any failure renders as
unavailable — the provider rejected the keyrather than throwing.
The key comes from pi, resolved through modelRegistry rather than by reading auth.json. pi owns credential storage — env precedence, OAuth, whatever it grows next — and parsing that file here would mean handling secrets this package has no business touching, using a stale copy of pi's rules. Only the provider's own masked label is ever printed.
No parameters. Returns session and today's totals, so the agent can check the cost before committing to expensive work — a wide subagent fan-out, a large read — instead of finding out afterwards.
MIT © Pify maintainers