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

claude-code / mods / telemetry / README.md
54 lines · 2.7 KBPreviewCodeRaw
1# telemetry
2
3Plugin analytics as a plugin: one `engine.create` step adds `$.telemetry` to
4the engine interface every plugin above it is handed, built over the
5`$.session` and `$.http` nouns beneath. `$.telemetry.log({ event, props })`
6sends one event as one first-party row, `tengu_plugin_<event>`;
7`$.telemetry.mark({ feature, kind, reason?, props? })` marks one use of a
8feature as the CLI's own feature events do, `tengu_feature_<kind>` with a
9`feature_name` and the mark's properties beside it. Each call is one POST to
10the event-logging ingest with the session's own credential
11(`$.session.authorize()`, resolved at each call), one attempt, nothing
12batched; a session with no first-party credential, or an ingest that
13refuses, rejects the caller's promise.
14
15It sends nothing wherever the CLI's own analytics are off: under
16`DISABLE_TELEMETRY`, `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` or
17`DO_NOT_TRACK`, on any third-party provider (Bedrock, Vertex, Foundry and
18kin), and on a deployment with its own OAuth URL. Each is read through
19`$.env` at every call, rows go one after another, and the credential is
20authorized afresh right before each POST, so a session that has since moved
21to a third-party provider or a cloud gateway sends nothing more. The row's
22`user_type` is `ant` when `USER_TYPE` says so, else `external`.
23
24Nothing free-form reaches a row. An event name and every property key is a
25snake_case token; a value is a finite number, a boolean, or a Choice (a
26string named together with the list it is chosen from), under `log` and
27`mark` alike; `mark` takes `ok`, `sad` or `bad`, with a `reason` required on
28the last two and refused on the first. An entry that breaks a rule is
29refused before anything is sent.
30
31`hooks/register.ts` is the module; `types/index.d.ts` is the noun's contract,
32the one declaration of `$.telemetry` that this mod's hooks, a mod calling the
33noun and a test answering it all read.
34
35## What it hooks
36
37`engine.create`: `{ ...await next(e), telemetry }`, so the noun is added and
38nothing beneath is replaced.
39
40## What it calls on `$`
41
42`session.authorize`, `session.id`, `session.model`, `http.fetch`, `env.get`
43(the switches above and `USER_TYPE`, by literal name), each on the
44interface the fold handed it.
45
46## Where it runs
47
48This plugin is seated by the CLI itself, on internal builds whose own
49analytics are on, and nowhere else: `session.authorize` exists only there,
50and the rows it writes join tables only the CLI's own events reach. It is
51not meant to be installed or loaded with `--plugin-dir`; the folder has a
52manifest so it reads like every other plugin, not so it can stand alone. A
53plugin that calls `$.telemetry` where this one is absent finds no such noun
54and should treat that as "no analytics here".