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

hooks/register.tsx 56 lines1import 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