SLOPSHOPPER

context-remaining

コンテキスト残量とプランの使用量をステータス行に常時表示する

newguardstatus
v0.1.0no licenseupdated 2026-10-02kj-nakamura/claude-mods/plugins/context-remaining
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · context-remaining
› 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 ⚠ context-remaining: ctx 残り 51% · セッション 31%
README

claude-mods

Claude Code 用の自作モッドのマーケットプレイス。

context-remaining

入力欄の下に、コンテキスト残量とプランの使用量(5時間・週間の上限とリセットまでの時間)を常時表示する。

ctx 残り 72% · セッション 4% (4時間50分後) · 週間 33% (18時間10分後)

インストール

claude plugin marketplace add kj-nakamura/claude-mods
claude plugin install context-remaining@kenji-mods
Source 1 files
hooks/register.ts 47 lines
1import type { Register, EngineInterface, SessionRateLimit } from 'claude-code'
2
3const LABELS: Record<string, string> = { five_hour: 'セッション', seven_day: '週間' }
4
5function untilReset(resetsAt: string | undefined, now: number) {
6  if (resetsAt === undefined) return ''
7  const resetMs = Date.parse(resetsAt)
8  if (!Number.isFinite(resetMs) || !Number.isFinite(now)) return ''
9  const minutes = Math.max(0, Math.round((resetMs - now) / 60000))
10  const h = Math.floor(minutes / 60)
11  const m = minutes % 60
12  return h > 0 ? ` (${h}時間${m}分後)` : ` (${m}分後)`
13}
14
15function formatLimit(limit: SessionRateLimit, now: number) {
16  const label = LABELS[limit.kind] ?? limit.kind
17  return `${label} ${Math.round(limit.percentUsed)}%${untilReset(limit.resetsAt, now)}`
18}
19
20async function refresh($: EngineInterface) {
21  const { context, rateLimits } = await $.session.usage()
22  const now = await $.clock.now()
23  const parts = [`ctx 残り ${100 - (context.percent ?? 0)}%`]
24  for (const limit of rateLimits) parts.push(formatLimit(limit, now))
25  $.ui.status(parts.join(' · '))
26}
27
28export const register: Register = on => {
29  on('session.start', async ($, e, next) => {
30    const result = await next(e)
31    await refresh($)
32    return result
33  })
34
35  on('session.measure', async ($, e, next) => {
36    const result = await next(e)
37    await refresh($)
38    return result
39  })
40
41  on('tool.call', async ($, e, next) => {
42    const result = await next(e)
43    await refresh($)
44    return result
45  })
46}
47