SLOPSHOPPER

mission-control

Mission control: session/turn tool-call counters in a Pane, an AbovePrompt band and a status entry

newpanebandguardstatusprompt
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · mission-control
│ ┃ Mission control ✕ › fix the failing auth test and add an audit log call │ ┃ Mission control │ ┃ session calls: 9 ⏺ Read(src/auth.ts) │ ┃ turn calls: 9 ⎿ Read 6 lines │ ┃ last tool: Bash ⏺ 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 │ │ │ │ mission-control · session 9 · turn 9 · last Bash ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts ⚠ mission-control: mc 9/9

Draws

Band
mission-control · session 9 · turn 9 · last Bash
Pane · Mission control
Mission control session calls: 9 turn calls: 9 last tool: Bash
Source 1 files
hooks/register.tsx 56 lines
1import type { Register } from 'claude-code'
2
3const PANE = 'mission-control'
4
5// 模块级计数:热重载后归零(会话仪表可接受)——精简版只做
6// 「state 计数 + Pane/AbovePrompt/status」,不引入 $.state 契约文件。
7let sessionCalls = 0
8let turnCalls = 0
9let lastTool = '-'
10
11export const register: Register = on => {
12  on('session.start', async ($, e, next) => {
13    await $.ui.open({ id: PANE, title: 'Mission control' })
14    return next(e)
15  })
16
17  on('prompt.submit', ($, e, next) => {
18    turnCalls = 0
19    $.ui.invalidate()
20    return next(e)
21  })
22
23  on('tool.call', ($, e, next) => {
24    sessionCalls += 1
25    turnCalls += 1
26    lastTool = String(e.tool)
27    $.ui.status(`mc ${sessionCalls}/${turnCalls}`)
28    $.ui.invalidate()
29    return next(e)
30  })
31
32  on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
33    const { Box, Text } = $.ui.resolve(e)
34    return (
35      <Box flexDirection="column">
36        <Text bold>Mission control</Text>
37        <Text>session calls: {sessionCalls}</Text>
38        <Text>turn calls: {turnCalls}</Text>
39        <Text dimColor>last tool: {lastTool}</Text>
40      </Box>
41    )
42  })
43
44  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
45    if (e.props.hasSurvey) return next(e)
46    const { Box, Text } = $.ui.resolve(e)
47    return (
48      <Box>
49        <Text dimColor>
50          mission-control · session {sessionCalls} · turn {turnCalls} · last {lastTool}
51        </Text>
52      </Box>
53    )
54  })
55}
56