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
| 1 | import type { |
| 2 | Args, |
| 3 | CommandRunInput, |
| 4 | HttpResponse, |
| 5 | On, |
| 6 | SessionAuthorization, |
| 7 | } from 'claude-code' |
| 8 | import type { Plugin } from 'claude-code/testing' |
| 9 | import { expect, memoryEnv, seat, test } from 'claude-code/testing' |
| 10 | |
| 11 | seat('builtin') |
| 12 | |
| 13 | const BEARER: SessionAuthorization = { handle: 'the-handle', kind: 'bearer' } |
| 14 | const ACCEPTED: HttpResponse = { status: 200, ok: true, headers: {}, text: '' } |
| 15 | |
| 16 | /** |
| 17 | * `/record <event>`, which the recording plugin answers. |
| 18 | */ |
| 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 | */ |
| 29 | const recording: Plugin = { |
| 30 | name: 'recording', |
| 31 | register(on) { |
| 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 | ), |
| 37 | ) |
| 38 | }, |
| 39 | } |
| 40 | |
| 41 | /** |
| 42 | * A first-party session: its id and model, the credential it holds, and |
| 43 | * the ingest accepting each row, each post kept as it was made. |
| 44 | */ |
| 45 | function firstPartySession( |
| 46 | on: On, |
| 47 | authorization: SessionAuthorization = BEARER, |
| 48 | ) { |
| 49 | const posts: Args<'http.fetch'>[] = [] |
| 50 | on('session.id', () => ({ value: 'the-session' })) |
| 51 | on('session.model', () => ({ value: 'the-model' })) |
| 52 | on('session.authorize', () => ({ value: authorization })) |
| 53 | on('http.fetch', ($, e) => { |
| 54 | posts.push(e) |
| 55 | |
| 56 | return { value: ACCEPTED } |
| 57 | }) |
| 58 | |
| 59 | return posts |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * The batch a post to the ingest carries, as it was sent. |
| 64 | */ |
| 65 | function batchOf(post: Args<'http.fetch'>): unknown { |
| 66 | return JSON.parse(String(post.init?.body)) |
| 67 | } |
| 68 | |
| 69 | test( |
| 70 | 'a plugin’s $.telemetry.log posts one first-party row', |
| 71 | { plugins: [recording] }, |
| 72 | async ($, on) => { |
| 73 | memoryEnv(on, { USER_TYPE: 'ant' }) |
| 74 | const posts = firstPartySession(on) |
| 75 | |
| 76 | expect(await $.command.run(record('survey_answered'))).toEqual({ |
| 77 | text: 'sent', |
| 78 | }) |
| 79 | expect(posts).toHaveLength(1) |
| 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 | ], |
| 95 | }) |
| 96 | }, |
| 97 | ) |
| 98 | |
| 99 | test( |
| 100 | 'a row already named tengu_ is sent under its own name', |
| 101 | { plugins: [recording] }, |
| 102 | async ($, on) => { |
| 103 | memoryEnv(on, {}) |
| 104 | const posts = firstPartySession(on) |
| 105 | |
| 106 | await $.command.run(record('tengu_repl_diff_panel_shown')) |
| 107 | |
| 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 | ]) |
| 120 | }, |
| 121 | ) |
| 122 | |
| 123 | test( |
| 124 | 'nothing is sent for a person who asked not to be tracked', |
| 125 | { plugins: [recording] }, |
| 126 | async ($, on) => { |
| 127 | memoryEnv(on, { DO_NOT_TRACK: '1' }) |
| 128 | const posts = firstPartySession(on) |
| 129 | |
| 130 | expect(await $.command.run(record('survey_answered'))).toEqual({ |
| 131 | text: 'sent', |
| 132 | }) |
| 133 | expect(posts).toEqual([]) |
| 134 | }, |
| 135 | ) |
| 136 | |
| 137 | test( |
| 138 | 'nothing is sent on a third-party provider', |
| 139 | { plugins: [recording] }, |
| 140 | async ($, on) => { |
| 141 | memoryEnv(on, { CLAUDE_CODE_USE_BEDROCK: '1' }) |
| 142 | const posts = firstPartySession(on) |
| 143 | |
| 144 | await $.command.run(record('survey_answered')) |
| 145 | |
| 146 | expect(posts).toEqual([]) |
| 147 | }, |
| 148 | ) |
| 149 | |
| 150 | test( |
| 151 | 'a session with no first-party credential is refused, nothing sent', |
| 152 | { plugins: [recording] }, |
| 153 | async ($, on) => { |
| 154 | memoryEnv(on, {}) |
| 155 | const posts = firstPartySession(on, null) |
| 156 | const { text } = await $.command.run(record('survey_answered')) |
| 157 | |
| 158 | expect(text).toEndWith( |
| 159 | '$.telemetry.log: this session has no first-party credential to ' + |
| 160 | 'authorize', |
| 161 | ) |
| 162 | expect(posts).toEqual([]) |
| 163 | }, |
| 164 | ) |