SLOPSHOPPER

usage-band

Shows the remaining usage (5-hour and 7-day windows) above the prompt

newband
v0.1.0MITupdated 2026-10-25rwkmty-maker/claude-mods/usage-band
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · usage-band
› 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 残りの使用量: 5時間 残り69% ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Band
残りの使用量: 5時間 残り69%
README

usage-band

Shows how much of your Claude usage is left, in a single quiet line above the message box: for example 残りの使用量: 5時間 残り77%(回復まで2時間15分) · 7日間 残り60%(回復まで3日4時間). The figures are the rate-limit windows the last response reported; the line turns yellow when a window is 80% used or more. It needs no setup. The time until reset is shown as a duration, so it does not depend on the time zone.

Install

/plugin install usage-band --marketplace rwkmty-maker/claude-mods

Source 2 files
hooks/register.tsx 64 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4import type { Limit, Limits } from '../types'
5
6const limits = atom({ plugin: 'usage-band', key: 'limits' } as const, [] as Limits)
7
8const NAMES: Record<string, string> = { five_hour: '5時間', seven_day: '7日間', spend_limit: '利用上限' }
9
10// time left until the window resets, as 2時間15分 / 3日4時間 / 12分 (no time zone needed)
11function until(iso: string | undefined, now: number): string {
12  if (!iso) return ''
13  const ms = Date.parse(iso) - now
14  if (!(ms > 0)) return ''
15  const min = Math.ceil(ms / 60000)
16  const d = Math.floor(min / 1440), h = Math.floor((min % 1440) / 60), m = min % 60
17  if (d > 0) return `${d}日${h}時間`
18  if (h > 0) return `${h}時間${m}分`
19  return `${m}分`
20}
21
22function line(l: Limit, now: number): string {
23  const left = Math.max(0, Math.round((100 - l.percentUsed) * 10) / 10)
24  const reset = until(l.resetsAt, now)
25  return `${NAMES[l.kind] ?? l.kind} 残り${left}%` + (reset ? `(回復まで${reset})` : '')
26}
27
28export const register: Register = on => {
29  on('session.start', async ($, e, next) => {
30    const r = await next(e)
31    const u = await $.session.usage()
32    await update($, limits, () => u.rateLimits)
33    return r
34  })
35
36  on('session.measure', async ($, e, next) => {
37    await update($, limits, () => e.rateLimits)
38    return next(e)
39  })
40
41  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
42    const ls = await read($, limits)
43    if (e.props.hasSurvey) return next(e)
44    const { Box, Text } = $.ui.resolve(e)
45    if (ls.length === 0) {
46      // say so, instead of showing nothing: the engine has no usage reading in this environment (yet)
47      return (
48        <Box>
49          <Text dimColor>残りの使用量: まだ取得できていません(この環境では使用量の情報が届いていません)</Text>
50        </Box>
51      )
52    }
53    const now = await $.clock.now()
54    const low = ls.some(l => l.percentUsed >= 80)
55    return (
56      <Box>
57        <Text dimColor={!low} color={low ? 'yellow' : undefined}>
58          {'残りの使用量: ' + ls.map(l => line(l, now)).join(' · ')}
59        </Text>
60      </Box>
61    )
62  })
63}
64
types/index.d.ts 9 lines
1export type Limit = { kind: string; percentUsed: number; resetsAt?: string }
2export type Limits = Limit[]
3
4declare module 'claude-code' {
5  interface PluginState {
6    'usage-band': { limits: Limits }
7  }
8}
9