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 | # telemetry |
| 2 | |
| 3 | Plugin analytics as a plugin: one `engine.create` step adds `$.telemetry` to |
| 4 | the engine interface every plugin above it is handed, built over the |
| 5 | `$.session` and `$.http` nouns beneath. `$.telemetry.log({ event, props })` |
| 6 | sends one event as one first-party row, `tengu_plugin_<event>`; |
| 7 | `$.telemetry.mark({ feature, kind, reason?, props? })` marks one use of a |
| 8 | feature 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 |
| 10 | the event-logging ingest with the session's own credential |
| 11 | (`$.session.authorize()`, resolved at each call), one attempt, nothing |
| 12 | batched; a session with no first-party credential, or an ingest that |
| 13 | refuses, rejects the caller's promise. |
| 14 | |
| 15 | It 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 |
| 18 | kin), 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 |
| 20 | authorized afresh right before each POST, so a session that has since moved |
| 21 | to 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 | |
| 24 | Nothing free-form reaches a row. An event name and every property key is a |
| 25 | snake_case token; a value is a finite number, a boolean, or a Choice (a |
| 26 | string 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 |
| 28 | the last two and refused on the first. An entry that breaks a rule is |
| 29 | refused before anything is sent. |
| 30 | |
| 31 | `hooks/register.ts` is the module; `types/index.d.ts` is the noun's contract, |
| 32 | the one declaration of `$.telemetry` that this mod's hooks, a mod calling the |
| 33 | noun 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 |
| 38 | nothing 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 |
| 44 | interface the fold handed it. |
| 45 | |
| 46 | ## Where it runs |
| 47 | |
| 48 | This plugin is seated by the CLI itself, on internal builds whose own |
| 49 | analytics are on, and nowhere else: `session.authorize` exists only there, |
| 50 | and the rows it writes join tables only the CLI's own events reach. It is |
| 51 | not meant to be installed or loaded with `--plugin-dir`; the folder has a |
| 52 | manifest so it reads like every other plugin, not so it can stand alone. A |
| 53 | plugin that calls `$.telemetry` where this one is absent finds no such noun |
| 54 | and should treat that as "no analytics here". |