SLOPSHOPPER

subagent-band

A band above the prompt showing each running subagent's model, effort and context tokens.

newband
v0.1.0MITupdated 2026-10-09kargarisaac/subagent-band
A shopper browsing a rack in a slop shop
README

subagent-band

A Claude Code mod that shows each running subagent's model, effort and context size in a band above the prompt.

worker · haiku-5-5 · xhigh · 12k

The statusline only shows the main session. This band gives each running subagent its own row.

Install

/plugin install subagent-band --marketplace kargarisaac/subagent-band

Answer y to add the marketplace, then pick a scope.

What it shows

  • One row per running subagent: type, model, effort, context tokens.
  • starting until the subagent's first model request finishes.
  • Context is a token count (input plus cache reads and writes), not a percentage.
  • Nothing shows when no subagent is running.

Develop

claude plugin validate .
claude plugin test .
Source 2 files
hooks/register.tsx 61 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4import type { AgentRow } from '../types'
5
6const rows = atom({ plugin: 'subagent-band', key: 'rows' } as const, {} as Record<string, AgentRow>)
7
8const kilo = (n: number) => (n >= 1000 ? `${Math.round(n / 1000)}k` : `${n}`)
9
10export const register: Register = on => {
11  on('turn.step', async function* ($, e, next) {
12    const id = e.agentId
13
14    if (id === undefined) {
15      return yield* next(e)
16    }
17
18    const response = yield* next(e)
19    const usage = response.usage
20
21    await update($, rows, current => ({
22      ...current,
23      [id]: {
24        model: usage?.model ?? e.model,
25        effort: e.effort === undefined ? '-' : String(e.effort),
26        context: usage
27          ? usage.input_tokens + usage.cache_read_input_tokens + usage.cache_creation_input_tokens
28          : (current[id]?.context ?? 0),
29        steps: (current[id]?.steps ?? 0) + 1,
30      },
31    }))
32
33    return response
34  })
35
36  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
37    const agents = (await $.agent.list()).filter(a => a.status === 'running')
38
39    if (e.props.hasSurvey || agents.length === 0) {
40      return next(e)
41    }
42
43    const known = await read($, rows)
44    const { Box, Text } = $.ui.resolve(e)
45
46    return (
47      <Box flexDirection="column">
48        {agents.map(a => {
49          const r = known[a.id]
50
51          return (
52            <Text key={a.id} dimColor>
53              {a.type} · {r ? `${r.model.replace(/^claude-/, '')} · ${r.effort} · ${kilo(r.context)}` : 'starting'}
54            </Text>
55          )
56        })}
57      </Box>
58    )
59  })
60}
61
types/index.d.ts 13 lines
1export type AgentRow = {
2  model: string
3  effort: string
4  context: number
5  steps: number
6}
7
8declare module 'claude-code' {
9  interface PluginState {
10    'subagent-band': { rows: Record<string, AgentRow> }
11  }
12}
13