SLOPSHOPPER

context-tokens

Shows the context tokens in use beside the prompt footer of the desktop app, green under 100k, yellow to 150k, red beyond. Needs function hooks (early access).

newspinnerguard
A shopper browsing a rack in a slop shop
README

context-tokens

Shows how many tokens the context holds, beside the prompt footer of the Claude Code desktop app: 88.1k. The terminal is left to a status line, which already carries the figure.

tokenscolor
under 100kgreen
100k to 150kyellow
150k and morered

The figure is the last API response's input side (total_input_tokens in a status line's input) and refreshes at session start, after each tool call and when a turn ends. It takes the place of the mode labels (focus, memory paused), which follow it after a •.

Install

claude plugin marketplace add 0xBADC0FFEE/claude-code-mods
claude plugin install context-tokens@claude-code-mods

Needs CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1.

Source 2 files
hooks/register.tsx 64 lines
1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register } from 'claude-code'
3
4const TOKENS_WARN = 100_000
5const TOKENS_CRIT = 150_000
6const GREEN = '#4eba65'
7const YELLOW = '#ffc107'
8const RED = '#e5484d'
9
10const usedTokens = atom({ plugin: 'context-tokens', key: 'tokens' } as const, null)
11
12export const register: Register = on => {
13  on('session.start', async ($, e, next) => {
14    await refreshTokens($)
15    return next(e)
16  })
17
18  on('tool.call', async ($, e, next) => {
19    const result = await next(e)
20    await refreshTokens($)
21    return result
22  })
23
24  on('turn.complete', async ($, e, next) => {
25    const result = await next(e)
26    await refreshTokens($)
27    return result
28  })
29
30  on('ui.render', { component: 'SessionMode', surface: 'desktop' }, async ($, e, next) => {
31    const tokens = await read($, usedTokens)
32    if (tokens === null) {
33      return next(e)
34    }
35
36    const { Box, Text } = $.ui.resolve(e)
37    const modes = e.props.modes.join(' & ')
38
39    return (
40      <Box>
41        <Text color={tokensColor(tokens)}>{formatTokens(tokens)}</Text>
42        {modes && <Text dimColor> • {modes}</Text>}
43      </Box>
44    )
45  })
46}
47
48async function refreshTokens($: EngineInterface): Promise<void> {
49  const { context } = await $.session.usage()
50  await update($, usedTokens, () => context.tokens ?? null)
51}
52
53function tokensColor(tokens: number): string {
54  if (tokens >= TOKENS_CRIT) return RED
55  if (tokens >= TOKENS_WARN) return YELLOW
56  return GREEN
57}
58
59function formatTokens(tokens: number): string {
60  if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`
61  if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`
62  return String(tokens)
63}
64
types/index.d.ts 8 lines
1export type UsedTokens = number | null
2
3declare module 'claude-code' {
4  interface PluginState {
5    'context-tokens': { tokens: UsedTokens }
6  }
7}
8