Status line shows which model each running subagent is using

Shows which model each subagent is running on, in the status line under the prompt.
When Claude starts subagents, the status line shows one entry per subagent:
agents: haiku-4-5, sonnet-5-5
When a subagent finishes, its entry gets a check mark and stays visible until your next prompt, so a short run can't flash past:
agents: haiku-4-5 ✓, sonnet-5-5
If several subagents ran in one turn, they all stay listed. Submitting a prompt clears the line.
The built-in subagent list doesn't say what model each one is using. A default subagent model set in your settings, or a subagent picking its own, can make that a surprise.
claude --plugin-dir /path/to/claude-code-mods/subagent-models
To load it in every session, see Install.
Try it: ask Claude to "use the Explore agent to list the files in this folder, then reply done."
? for its model.sonnet appears as its full name, for example sonnet-5-5. A default subagent model set in your settings (CLAUDE_CODE_SUBAGENT_MODEL) overrides what Claude chooses.Hooks on agent.spawn (records the model each subagent started with), turn.complete and tool.call (refresh which are still running), and prompt.submit (clears). It writes through $.ui.status.
hooks/register.ts 55 lines1import type { EngineInterface, Register } from 'claude-code'
2
3// Models of the subagents started since the last prompt, by agent id.
4const models = new Map<string, string>()
5
6const short = (model: string) => model.replace(/^claude-/, '')
7
8async function refresh($: EngineInterface) {
9 if (models.size === 0) {
10 $.ui.status(undefined)
11 return
12 }
13
14 const running = new Set(
15 (await $.agent.list()).filter(a => a.status === 'running').map(a => a.id),
16 )
17 const label = [...models].map(
18 ([id, model]) => `${short(model)}${running.has(id) ? '' : ' ✓'}`,
19 )
20
21 $.ui.status(`agents: ${label.join(', ')}`)
22}
23
24export const register: Register = on => {
25 on('prompt.submit', async ($, e, next) => {
26 models.clear()
27 await refresh($)
28 return next(e)
29 })
30
31 on('agent.spawn', async ($, e, next) => {
32 const started = await next(e)
33
34 if (!started.deny && started.agentId) {
35 models.set(started.agentId, started.model)
36 await refresh($)
37 }
38
39 return started
40 })
41
42 // Subagents finish with a turn.complete; tool calls catch the rest.
43 on('turn.complete', async ($, e, next) => {
44 const done = await next(e)
45 await refresh($)
46 return done
47 })
48
49 on('tool.call', async ($, e, next) => {
50 const ran = await next(e)
51 await refresh($)
52 return ran
53 })
54}
55