/** * Every field that may ever leave the machine, and nothing else. * * ## The rule this file exists to enforce * * **No value here may be free text.** Every property is either a number, a * boolean, or a string drawn from a set enumerated in this file. That is not * fussiness — free text is the mechanism by which telemetry leaks. An error * message carries `/Users/francesco/rebase/...`, which is a real person's name. * A collection name carries a customer's product vocabulary. A database URL * carries a password. None of those are things anyone intends to send; they * arrive by being interpolated into a string that a well-meaning field was * happy to accept. * * So the payload is closed by construction. Adding a field means adding it * here, where the review question — "can this ever contain something the user * typed?" — is unavoidable. * * ## What is deliberately absent * * Project names, directory paths, collection or table names, hostnames, * database URLs, error messages, stack traces, email addresses, exact row or * user counts. Anything that would let a payload be traced to an organisation * rather than to an anonymous id. */ /** * Bumped whenever a field is added, removed or changes meaning. * * Sent with every event so the receiving end can reject or migrate old shapes, * and so `rebase telemetry show` can state which contract the user agreed to. */ export declare const TELEMETRY_SCHEMA_VERSION = 1; /** The events the CLI reports. Closed set — a name not listed cannot be sent. */ export type TelemetryEventName = "cli.init" | "cli.dev" | "cli.deploy" | "cli.schema" | "cli.db" | "cli.error"; /** A single non-free-text value. */ export type TelemetryValue = string | number | boolean; export type TelemetryEvent = { schema: number; event: TelemetryEventName; /** Random per machine — see identity.ts on why it is not derived. */ machineId: string; /** Random per checkout. Absent when the command ran outside a project. */ projectId?: string; /** The CLI's own version, so old releases can be told apart. */ cliVersion: string; /** Coarse platform facts, for the support matrix. */ nodeMajor: number; platform: NodeJS.Platform; arch: string; /** UTC, second precision. Not a device clock reading anyone can fingerprint. */ at: string; properties: Record; }; /** * Buckets rather than exact counts. * * An exact figure is a surprisingly good fingerprint — "this install has 37 * collections" narrows the field a great deal when combined with a version and * a driver. A bucket answers "roughly how big" without doing that. */ export declare function bucket(value: number): string; /** Duration in coarse bands — enough to see "slow", not enough to fingerprint. */ export declare function durationBucket(ms: number): string; /** * An error reduced to something safe to transmit. * * The message and the stack are discarded, always. What survives is the * constructor name and, for the errors that carry one, a `code` — both of which * come from the program rather than from anything the user typed or named. * `EACCES` is useful and safe; "cannot write /Users/francesco/clients/acme" is * neither. */ export declare function errorClass(error: unknown): string; export declare function sanitize(properties: Record): Record; export declare function buildEvent(event: TelemetryEventName, properties: Record, identity: { machineId: string; projectId?: string; }): TelemetryEvent;