spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

mods/telemetry: its tests record through one /record command and match each post's batch as it was sentBrowse files
poteat authored on Sep 11, 2026 parent 9e7b391 · commit 07313f0e528c
1 changed file+56 -50compared with 9e7b391
Mmods/telemetry/tests/telemetry.test.ts
@@ -10,49 +10,37 @@
1010
1111 seat('builtin')
1212
13-const SURVEY: CommandRunInput = {
14- command: 'survey',
15- args: '',
16- origin: { kind: 'composer' },
17-}
18-const SHOWN: CommandRunInput = {
19- command: 'shown',
20- args: '',
21- origin: { kind: 'composer' },
22-}
2313 const BEARER: SessionAuthorization = { handle: 'the-handle', kind: 'bearer' }
2414 const ACCEPTED: HttpResponse = { status: 200, ok: true, headers: {}, text: '' }
2515
2616 /**
27- * A plugin that records through `$.telemetry`: `/survey` logs an answered
28- * survey, `/shown` a row under the built-in panel's own name; each answers
29- * "sent", or why the row was refused.
17+ * `/record <event>`, which the recording plugin answers.
3018 */
19+const record = (event: string): CommandRunInput => ({
20+ command: 'record',
21+ args: event,
22+ origin: { kind: 'composer' },
23+})
24+
25+/**
26+ * A plugin whose `/record <event>` logs that event through `$.telemetry`,
27+ * answering "sent", or why the row was refused.
28+ */
3129 const recording: Plugin = {
3230 name: 'recording',
3331 register(on) {
34- on('command.run', { command: 'survey' }, $ =>
35- $.telemetry
36- .log({ event: 'survey_answered', props: { answer: 2, seen: true } })
37- .then(
38- () => ({ text: 'sent' }),
39- (error: unknown) => ({ text: String(error) }),
40- ),
32+ on('command.run', { command: 'record' }, ($, e) =>
33+ $.telemetry.log({ event: e.args, props: { answer: 2, seen: true } }).then(
34+ () => ({ text: 'sent' }),
35+ (error: unknown) => ({ text: String(error) }),
36+ ),
4137 )
42- on('command.run', { command: 'shown' }, $ =>
43- $.telemetry
44- .log({ event: 'tengu_repl_diff_panel_shown', props: { seen: true } })
45- .then(
46- () => ({ text: 'sent' }),
47- (error: unknown) => ({ text: String(error) }),
48- ),
49- )
5038 },
5139 }
5240
5341 /**
5442 * A first-party session: its id and model, the credential it holds, and
55- * the ingest accepting each row, which is kept as it was posted.
43+ * the ingest accepting each row, each post kept as it was made.
5644 */
5745 function firstPartySession(
5846 on: On,
@@ -72,13 +60,10 @@
7260 }
7361
7462 /**
75- * The one row a post to the ingest carries.
63+ * The batch a post to the ingest carries, as it was sent.
7664 */
77-function rowOf(post: Args<'http.fetch'> | undefined) {
78- const batch: { events: { event_data: Readonly<Record<string, unknown>> }[] } =
79- JSON.parse(String(post?.init?.body))
80-
81- return batch.events[0]?.event_data
65+function batchOf(post: Args<'http.fetch'>): unknown {
66+ return JSON.parse(String(post.init?.body))
8267 }
8368
8469 test(
@@ -88,14 +73,25 @@
8873 memoryEnv(on, { USER_TYPE: 'ant' })
8974 const posts = firstPartySession(on)
9075
91- expect(await $.command.run(SURVEY)).toEqual({ text: 'sent' })
76+ expect(await $.command.run(record('survey_answered'))).toEqual({
77+ text: 'sent',
78+ })
9279 expect(posts).toHaveLength(1)
93- expect(posts[0]?.init).toMatchObject({ method: 'POST', auth: 'the-handle' })
94- expect(rowOf(posts[0])).toMatchObject({
95- event_name: 'tengu_plugin_survey_answered',
96- session_id: 'the-session',
97- model: 'the-model',
98- user_type: 'ant',
80+
81+ const [post] = posts
82+
83+ expect(post.init).toMatchObject({ method: 'POST', auth: 'the-handle' })
84+ expect(batchOf(post)).toMatchObject({
85+ events: [
86+ {
87+ event_data: {
88+ event_name: 'tengu_plugin_survey_answered',
89+ session_id: 'the-session',
90+ model: 'the-model',
91+ user_type: 'ant',
92+ },
93+ },
94+ ],
9995 })
10096 },
10197 )
@@ -107,12 +103,20 @@
107103 memoryEnv(on, {})
108104 const posts = firstPartySession(on)
109105
110- await $.command.run(SHOWN)
106+ await $.command.run(record('tengu_repl_diff_panel_shown'))
111107
112- expect(rowOf(posts[0])).toMatchObject({
113- event_name: 'tengu_repl_diff_panel_shown',
114- user_type: 'external',
115- })
108+ expect(posts.map(batchOf)).toMatchObject([
109+ {
110+ events: [
111+ {
112+ event_data: {
113+ event_name: 'tengu_repl_diff_panel_shown',
114+ user_type: 'external',
115+ },
116+ },
117+ ],
118+ },
119+ ])
116120 },
117121 )
118122
@@ -123,7 +127,9 @@
123127 memoryEnv(on, { DO_NOT_TRACK: '1' })
124128 const posts = firstPartySession(on)
125129
126- expect(await $.command.run(SURVEY)).toEqual({ text: 'sent' })
130+ expect(await $.command.run(record('survey_answered'))).toEqual({
131+ text: 'sent',
132+ })
127133 expect(posts).toEqual([])
128134 },
129135 )
@@ -135,7 +141,7 @@
135141 memoryEnv(on, { CLAUDE_CODE_USE_BEDROCK: '1' })
136142 const posts = firstPartySession(on)
137143
138- await $.command.run(SURVEY)
144+ await $.command.run(record('survey_answered'))
139145
140146 expect(posts).toEqual([])
141147 },
@@ -147,7 +153,7 @@
147153 async ($, on) => {
148154 memoryEnv(on, {})
149155 const posts = firstPartySession(on, null)
150- const { text } = await $.command.run(SURVEY)
156+ const { text } = await $.command.run(record('survey_answered'))
151157
152158 expect(text).toEndWith(
153159 '$.telemetry.log: this session has no first-party credential to ' +