Always-on token usage: context fill, rate-limit windows and session cost

A Claude Code mod that keeps your token usage on the status line, all the time:
◆ ctx 84k/200k (42%) · 5h 23.5% · 7d 7% · $1.23
It updates after every reply and whenever a limit moves a whole point.
In a Claude Code terminal session:
/plugin install token-meter --marketplace 1619supply-sudo/token-meter
Answer y to add the marketplace, then pick the user scope. That makes it load in every Claude Code session, including the desktop app's Code tab.
hooks/register.ts 32 lines1import type { Register, SessionMeasureInput } from 'claude-code'
2
3type Usage = Pick<SessionMeasureInput, 'context' | 'rateLimits' | 'cost'>
4
5const LIMIT_NAMES: Record<string, string> = { five_hour: '5h', seven_day: '7d', spend_limit: 'spend' }
6
7const k = (n: number) => (n >= 1000 ? `${Math.round(n / 1000)}k` : `${n}`)
8
9export const formatUsage = ({ context, rateLimits, cost }: Usage): string => {
10 const parts = [
11 context.tokens === undefined
12 ? `ctx –/${k(context.window)}`
13 : `ctx ${k(context.tokens)}/${k(context.window)} (${context.percent ?? 0}%)`,
14 ...rateLimits.map(r => `${LIMIT_NAMES[r.kind] ?? r.kind} ${r.percentUsed}%`),
15 ]
16 if (cost) parts.push(`$${cost.usd.toFixed(2)}`)
17 return `◆ ${parts.join(' · ')}`
18}
19
20export const register: Register = on => {
21 on('session.start', async ($, e, next) => {
22 const result = await next(e)
23 $.ui.status(formatUsage(await $.session.usage()))
24 return result
25 })
26
27 on('session.measure', ($, e, next) => {
28 $.ui.status(formatUsage(e))
29 return next(e)
30 })
31}
32