SLOPSHOPPER

usage-status

Rate-limit usage (5h, 1w) in the prompt footer

newspinner
A shopper browsing a rack in a slop shop
README

claude-mods

Claude Code mods (plugins of function hooks), published as a plugin marketplace.

/plugin marketplace add seiya8bit/claude-mods
/plugin install usage-status@claude-mods
ModWhat it does
usage-statusShows 5h 2% 1w 5% ↻ 10/10 at the right of the prompt footer; turns amber at 70% and red at 90%, and adds the 5h reset time near the limit

Adding a mod

  1. Put it in plugins/<name>/ (.claude-plugin/plugin.json, hooks/hooks.json, hooks/register.tsx).
  2. Add it to .claude-plugin/marketplace.json and the table above.
  3. claude plugin validate plugins/<name> and claude plugin validate .
Source 1 files
hooks/register.tsx 61 lines
1import type { Register } from 'claude-code'
2
3const LABEL: Record<string, string> = { five_hour: '5h', seven_day: '1w' }
4
5// The desktop footer ignores Box gaps, drops whitespace-only text and renders every
6// Unicode space as one plain space, so a wide gap is braille blanks and a narrow one a space
7// behind a zero-width space (never leading whitespace)
8const GAP = '\u2800\u2800'
9const SPACE = '\u200b '
10// before the model name: one blank, half the gap between windows
11const END_GAP = '\u2800'
12
13const colorOf = (pct: number) => (pct >= 90 ? '#e5534b' : pct >= 70 ? '#d29922' : undefined)
14const PCT_COLOR: Record<string, string> = { five_hour: '#56b4e9', seven_day: '#2ec4a0' }
15// the footer mutes plain text; the theme's own text color matches the model name beside it
16const TEXT = 'text'
17
18const resetLabel = (iso: string, now: number) => {
19  const d = new Date(iso)
20  return d.toDateString() === new Date(now).toDateString()
21    ? d.toTimeString().slice(0, 5)
22    : `${d.getMonth() + 1}/${d.getDate()}`
23}
24
25export const register: Register = on => {
26  on('session.measure', ($, e, next) => {
27    $.ui.invalidate('ui.render')
28    return next(e)
29  })
30
31  on('ui.render', { component: 'SessionMode' }, async ($, e, next) => {
32    const { rateLimits } = await $.session.usage()
33    if (rateLimits.length === 0) return next(e)
34
35    const { Box, Text } = $.ui.resolve(e)
36    const now = await $.clock.now()
37    const modes = e.props.modes.join(' & ')
38
39    return (
40      <Box>
41        {modes && <Text color={TEXT}>{modes}</Text>}
42        {rateLimits.map((r, i) => {
43          const color = colorOf(r.percentUsed)
44          // weekly reset always; the others only near the limit
45          const showReset = r.resetsAt && (color || r.kind === 'seven_day')
46          return (
47            <Box key={r.kind} gap={1}>
48              <Text color={TEXT}>{(i > 0 || modes ? GAP : '') + (LABEL[r.kind] ?? r.kind)}</Text>
49              <Text bold={!!color} color={color ?? PCT_COLOR[r.kind] ?? TEXT}>{Math.round(r.percentUsed)}%</Text>
50              {showReset && (
51                <Text color={color}>{`${SPACE}↻ ${resetLabel(r.resetsAt!, now)}`}</Text>
52              )}
53            </Box>
54          )
55        })}
56        <Text>{END_GAP}</Text>
57      </Box>
58    )
59  })
60}
61