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 | /** |
| 2 | * The `$.telemetry` noun as every caller sees it: the one contract for the |
| 3 | * noun, its types exported here and the noun declared on `EngineInterface`. |
| 4 | * |
| 5 | * The telemetry mod adds the noun in the `engine.create` fold and checks its |
| 6 | * return against `EngineInterface['telemetry']`; its hooks import these types |
| 7 | * from this folder, a mod that calls the noun and a test that answers it read |
| 8 | * them by including it in their tsconfig, and the engine's repository imports |
| 9 | * the folder by path. Nothing here is imported, so it stands on its own. |
| 10 | */ |
| 11 | |
| 12 | /** |
| 13 | * A plugin's analytics, sent one event at a time through `$.telemetry`. |
| 14 | * |
| 15 | * Internal builds alone: the telemetry mod adds the noun in the |
| 16 | * `engine.create` fold, so a plugin on an external build, or one where the |
| 17 | * mod is off, finds no `$.telemetry` and its call throws. |
| 18 | */ |
| 19 | export type Telemetry = { |
| 20 | /** |
| 21 | * Sends one event, `tengu_plugin_<event>`, as one first-party row; |
| 22 | * resolves once the ingest accepted it. |
| 23 | * |
| 24 | * The calling mod names itself in `event`; one already named `tengu_…` is |
| 25 | * sent as named. A value is a finite number, a boolean or a |
| 26 | * TelemetryChoice; free text is refused. One input, as every op on `$` |
| 27 | * takes. |
| 28 | * |
| 29 | * @param entry the event's name, a snake_case token, and its properties by |
| 30 | * snake_case key |
| 31 | * @example |
| 32 | * await $.telemetry.log({ |
| 33 | * event: "suggest_learning_survey_answered", |
| 34 | * props: { |
| 35 | * answer: 2, |
| 36 | * page: { value: "ready", of: ["ready", "later"] }, |
| 37 | * }, |
| 38 | * }) |
| 39 | */ |
| 40 | log: (entry: TelemetryLogEntry) => Promise<void> |
| 41 | |
| 42 | /** |
| 43 | * Marks one use of a feature as the CLI's own feature events do, one |
| 44 | * `tengu_feature_<kind>` row; resolves once the ingest accepted it. |
| 45 | * |
| 46 | * The row carries `feature_name`, `error_code` on sad or bad (`reason`, |
| 47 | * required there and refused on ok) and the entry's `props`, checked as |
| 48 | * `log`'s are; it joins the product-wide feature surface, so no prefix. |
| 49 | * |
| 50 | * @param entry the feature, how it went, why when not ok, and the row's |
| 51 | * properties by snake_case key |
| 52 | * @example |
| 53 | * await $.telemetry.mark({ feature: "learn_page", kind: "ok" }) |
| 54 | * await $.telemetry.mark({ |
| 55 | * feature: "learn_page", |
| 56 | * kind: "sad", |
| 57 | * reason: "blocked", |
| 58 | * }) |
| 59 | */ |
| 60 | mark: (entry: TelemetryMarkEntry) => Promise<void> |
| 61 | } |
| 62 | |
| 63 | /** |
| 64 | * What `$.telemetry.log` takes: the event's name after the prefix, and its |
| 65 | * properties by snake_case key. |
| 66 | */ |
| 67 | export type TelemetryLogEntry = { |
| 68 | event: string |
| 69 | props?: Readonly<Record<string, TelemetryProp>> |
| 70 | } |
| 71 | |
| 72 | /** |
| 73 | * What `$.telemetry.mark` takes: the feature, how it went, why when not |
| 74 | * ok, and the properties the row carries beside them by snake_case key. |
| 75 | */ |
| 76 | export type TelemetryMarkEntry = { |
| 77 | feature: string |
| 78 | kind: TelemetryMarkKind |
| 79 | reason?: string |
| 80 | props?: Readonly<Record<string, TelemetryProp>> |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * How a feature went, as the CLI's own feature events count it. |
| 85 | * |
| 86 | * `ok`: used, the person got what they asked. `sad`: degraded, a fallback |
| 87 | * or a partial, the person still got something. `bad`: failed, the person |
| 88 | * got nothing. |
| 89 | */ |
| 90 | export type TelemetryMarkKind = 'ok' | 'sad' | 'bad' |
| 91 | |
| 92 | /** |
| 93 | * A property's value: a finite number, a boolean, or a TelemetryChoice; |
| 94 | * never free text. |
| 95 | */ |
| 96 | export type TelemetryProp = number | boolean | TelemetryChoice |
| 97 | |
| 98 | /** |
| 99 | * A string property: the value and the list it is chosen from, declared |
| 100 | * beside it, so no free text reaches the row. |
| 101 | * |
| 102 | * Every member of `of` is a lowercase token of letters, digits, `_` and |
| 103 | * `-`, which may start with a digit, at most 32 of them; `value` is one of |
| 104 | * them. |
| 105 | */ |
| 106 | export type TelemetryChoice = { value: string; of: readonly string[] } |
| 107 | |
| 108 | declare module 'claude-code' { |
| 109 | interface EngineInterface { |
| 110 | /** |
| 111 | * A plugin's analytics, one first-party row per call; present only where |
| 112 | * the telemetry mod is seated (internal builds), absent everywhere else. |
| 113 | */ |
| 114 | telemetry: Telemetry |
| 115 | } |
| 116 | } |