SLOPSHOPPER

usage-meter

Línea de estado con el uso de contexto, los límites de 5h/7d y el costo de la sesión

newstatustimer
v0.1.0no licenseupdated 2026-10-18nima8998/claude-mods/usage-meter
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · usage-meter
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ Read 6 lines ⏺ Update(src/auth.ts) ⎿ Added 2 lines, removed 1 line ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Worked for 42s · done 4:20 PM ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts ⚠ usage-meter: ctx 49% (97k/200k) · 5h 31% ↻NaNm · $0.42
README

claude-mods

Mods para la terminal de Claude Code.

Mods

usage-meter

Línea de estado con el uso de contexto, los límites de uso de 5 horas y 7 días (con lo que falta para que se reinicien) y el costo de la sesión.

ctx 42% (84k/200k) · 5h 23.5% ↻2h05m · 7d 61% ↻3d3h · $1.23
  • Los límites de 5h/7d aparecen solo con una suscripción (Pro/Max).
  • El costo es el mismo que muestra /cost, calculado a precio de lista de la API. Con una suscripción no se cobra: sirve como referencia.

cache-clock

Cuenta regresiva del prompt cache desde la última respuesta del modelo, y qué parte de esa respuesta salió del cache.

cache ● 47:12 · hit 98%
cache ○ frío (venció hace 3:05) · hit 98%

Claude Code no les dice a los mods cuánto dura el cache, así que es una opción: ttl, 1h por defecto (lo normal con suscripción) o 5m (lo normal con una API key). Se cambia desde /config.

Instalación

En la terminal de Claude Code:

/plugin install usage-meter --marketplace nima8998/claude-mods
/plugin install cache-clock --marketplace nima8998/claude-mods

Desde una terminal común:

claude plugin install usage-meter --marketplace nima8998/claude-mods
claude plugin install cache-clock --marketplace nima8998/claude-mods

En la app de escritorio, donde /plugin no funciona: hacé clic en el + que está al lado del cuadro del prompt, después en Plugins, Add marketplace con nima8998/claude-mods y Add plugin.

La primera vez Claude Code pregunta si querés agregar el catálogo: respondé y y elegí el alcance de usuario para que los mods se carguen en todas tus sesiones.

Source 1 files
hooks/register.ts 70 lines
1import type { Register, SessionCost, SessionContextUsage, SessionRateLimit } from 'claude-code'
2
3type Figures = {
4  context: SessionContextUsage
5  rateLimits: readonly SessionRateLimit[]
6  cost?: SessionCost
7}
8
9const LABELS: Record<string, string> = { five_hour: '5h', seven_day: '7d', spend_limit: 'gasto' }
10
11export function kilo(tokens: number): string {
12  return tokens >= 1000 ? `${Math.round(tokens / 1000)}k` : String(tokens)
13}
14
15export function until(resetsAt: string | undefined, now: number): string {
16  if (resetsAt === undefined) return ''
17  const minutes = Math.max(0, Math.round((Date.parse(resetsAt) - now) / 60000))
18  const days = Math.floor(minutes / 1440)
19  const hours = Math.floor((minutes % 1440) / 60)
20  const rest = minutes % 60
21
22  if (days > 0) return ` ↻${days}d${hours}h`
23  if (hours > 0) return ` ↻${hours}h${String(rest).padStart(2, '0')}m`
24  return ` ↻${rest}m`
25}
26
27export function line(figures: Figures, now: number): string {
28  const { context, rateLimits, cost } = figures
29  const parts: string[] = []
30
31  parts.push(
32    context.tokens === undefined
33      ? `ctx —/${kilo(context.window)}`
34      : `ctx ${context.percent ?? 0}% (${kilo(context.tokens)}/${kilo(context.window)})`,
35  )
36
37  for (const limit of rateLimits) {
38    const label = LABELS[limit.kind] ?? limit.kind
39    parts.push(`${label} ${limit.percentUsed}%${until(limit.resetsAt, now)}`)
40  }
41
42  if (cost !== undefined) parts.push(`$${cost.usd.toFixed(2)}`)
43
44  return parts.join(' · ')
45}
46
47export const register: Register = on => {
48  let last: Figures | undefined
49
50  on('session.start', async ($, e, next) => {
51    const usage = await $.session.usage()
52    last = usage
53    $.ui.status(line(usage, await $.clock.now()))
54
55    // The reset countdowns move on their own between measurements.
56    $.clock.every(60_000, async () => {
57      if (last !== undefined) $.ui.status(line(last, await $.clock.now()))
58    })
59
60    return next(e)
61  })
62
63  on('session.measure', async ($, e, next) => {
64    last = e
65    $.ui.status(line(e, await $.clock.now()))
66
67    return next(e)
68  })
69}
70