{"version":3,"file":"Telemetry-D-Jpt27O.cjs","names":["getAgentProfile","process","os","randomBytes"],"sources":["../../../internals/utils/src/env.ts","../../../internals/utils/src/runtime.ts","../src/agent.ts","../src/constants.ts","../src/Telemetry.ts"],"sourcesContent":["/**\n * Returns `true` when the process is running in a CI environment.\n * Covers GitHub Actions, GitLab CI, CircleCI, Travis CI, Jenkins, Bitbucket,\n * TeamCity, Buildkite, and Azure Pipelines.\n *\n * @example\n * ```ts\n * if (isCIEnvironment()) {\n *   logger.level = 'error'\n * }\n * ```\n */\nexport function isCIEnvironment(): boolean {\n  return !!(\n    process.env.CI ||\n    process.env.GITHUB_ACTIONS ||\n    process.env.GITLAB_CI ||\n    process.env.BITBUCKET_BUILD_NUMBER ||\n    process.env.JENKINS_URL ||\n    process.env.CIRCLECI ||\n    process.env.TRAVIS ||\n    process.env.TEAMCITY_VERSION ||\n    process.env.BUILDKITE ||\n    process.env.TF_BUILD\n  )\n}\n\n/**\n * Returns `true` when the process has an interactive TTY with a valid terminal\n * width and is not running in CI.\n *\n * Some IDE-embedded terminals report `isTTY = true` but set `columns` to `0`,\n * which breaks clack's box-drawing helpers (they call `String.prototype.repeat`\n * with a negative count and throw a `RangeError`).  We therefore require a\n * positive column count before declaring the TTY usable.\n *\n * @example\n * ```ts\n * if (canUseTTY()) {\n *   renderProgressBar()\n * }\n * ```\n */\nexport function canUseTTY(): boolean {\n  return process.stdout.isTTY && (process.stdout.columns ?? 0) > 0 && !isCIEnvironment()\n}\n","/**\n * Name of the JavaScript runtime executing the current process.\n */\ntype RuntimeName = 'bun' | 'deno' | 'node'\n\n/**\n * Detects the JavaScript runtime executing the current process and exposes its name and version.\n *\n * Prefer the shared {@link runtime} instance over constructing your own.\n */\nclass Runtime {\n  /**\n   * `true` when the current process is running under Bun.\n   *\n   * Detection keys off the global `Bun` object rather than `process.versions`,\n   * because Bun polyfills `process.versions.node` for Node compatibility and would\n   * otherwise look like Node.\n   *\n   * @example\n   * ```ts\n   * if (runtime.isBun) {\n   *   await Bun.write(path, data)\n   * }\n   * ```\n   */\n  get isBun(): boolean {\n    return typeof Bun !== 'undefined'\n  }\n\n  /**\n   * `true` when the current process is running under Deno.\n   */\n  get isDeno(): boolean {\n    return typeof (globalThis as { Deno?: unknown }).Deno !== 'undefined'\n  }\n\n  /**\n   * `true` when the current process is running under Node.\n   *\n   * Bun and Deno are excluded first so a polyfilled `process` does not register as Node.\n   */\n  get isNode(): boolean {\n    return !this.isBun && !this.isDeno && typeof process !== 'undefined' && process.versions?.node != null\n  }\n\n  /**\n   * Name of the runtime executing the current process.\n   *\n   * @example\n   * ```ts\n   * runtime.name // 'bun' when run with `bun kubb`, 'node' otherwise\n   * ```\n   */\n  get name(): RuntimeName {\n    if (this.isBun) return 'bun'\n    if (this.isDeno) return 'deno'\n\n    return 'node'\n  }\n\n  /**\n   * Version of the active runtime, or an empty string when it cannot be read.\n   *\n   * @example\n   * ```ts\n   * runtime.version // '1.3.11' under Bun, '22.22.2' under Node\n   * ```\n   */\n  get version(): string {\n    if (this.isBun) return process.versions.bun ?? ''\n    if (this.isDeno) return (globalThis as { Deno?: { version?: { deno?: string } } }).Deno?.version?.deno ?? ''\n\n    return process.versions?.node ?? ''\n  }\n}\n\n/**\n * Shared {@link Runtime} instance describing the JavaScript runtime executing the current process.\n */\nexport const runtime = new Runtime()\n","import { getAgentProfile } from 'gunshi/agent'\n\n/**\n * Name of the AI coding agent driving this process, when one is detected (e.g. `'claude'`,\n * `'cursor'`). `undefined` when run by a human or an unrecognized caller.\n */\nexport function getAgentName(): string | undefined {\n  const profile = getAgentProfile()\n  return profile.isAgent ? profile.name : undefined\n}\n","/**\n * NPM registry endpoint used to check for @kubb/cli updates.\n */\nexport const KUBB_NPM_PACKAGE_URL = 'https://registry.npmjs.org/@kubb/cli/latest' as const\n\n/**\n * OpenTelemetry ingestion endpoint for anonymous usage telemetry.\n */\nexport const OTLP_ENDPOINT = 'https://otlp.kubb.dev' as const\n\n/**\n * Glob pattern for paths the file watcher ignores.\n */\nexport const WATCHER_IGNORED_PATHS = '**/{.git,node_modules}/**' as const\n\n/**\n * Quiet window in milliseconds that collapses a burst of watcher events (an editor save emits\n * several) into a single rebuild.\n */\nexport const WATCHER_DEBOUNCE_MS = 100\n\n/**\n * Upper bound in milliseconds for the npm update check, so a slow registry never stalls a run.\n */\nexport const UPDATE_CHECK_TIMEOUT_MS = 3_000\n\n/**\n * Flags that short-circuit execution (help and version). The telemetry notice is suppressed for these.\n */\nexport const QUIET_FLAGS = new Set<string>(['--help', '-h', '--version', '-v'])\n","import { randomBytes } from 'node:crypto'\nimport os from 'node:os'\nimport process from 'node:process'\nimport { isCIEnvironment, runtime } from '@internals/utils'\nimport { getAgentName } from './agent.ts'\nimport { OTLP_ENDPOINT } from './constants.ts'\n\ntype OtlpKeyValue = {\n  key: string\n  value:\n    | { stringValue: string }\n    | { boolValue: boolean }\n    | { intValue: number }\n    | { arrayValue: { values: Array<{ kvlistValue: { values: Array<OtlpKeyValue> } }> } }\n    | { kvlistValue: { values: Array<OtlpKeyValue> } }\n}\n\ntype OtlpSpan = {\n  traceId: string\n  spanId: string\n  name: string\n  kind: 1\n  startTimeUnixNano: string\n  endTimeUnixNano: string\n  attributes: Array<OtlpKeyValue>\n  status: { code: 1 | 2 }\n}\n\ntype OtlpExportTraceServiceRequest = {\n  resourceSpans: Array<{\n    resource: { attributes: Array<OtlpKeyValue> }\n    scopeSpans: Array<{\n      scope: { name: string; version: string }\n      spans: Array<OtlpSpan>\n    }>\n  }>\n}\n\n/**\n * Anonymous plugin name and options snapshot sent with each telemetry event.\n */\nexport type TelemetryPlugin = {\n  /**\n   * Plugin name as registered in the Kubb config, e.g. `'@kubb/plugin-ts'`.\n   */\n  name: string\n  /**\n   * Anonymized snapshot of the plugin options. Values are included but cannot be traced back to a user.\n   */\n  options: Record<string, unknown>\n}\n\n/**\n * Anonymous snapshot of a single Kubb run, built by {@link buildTelemetryEvent} and sent by {@link sendTelemetry}.\n */\nexport type TelemetryEvent = {\n  command: string\n  kubbVersion: string\n  /**\n   * Major version of Node that executed the run, e.g. `'22'`.\n   */\n  nodeVersion: string\n  /**\n   * Name of the JavaScript runtime that executed the run, `'bun'`, `'deno'`, or `'node'`.\n   */\n  runtime: string\n  /**\n   * Major version of the active runtime, e.g. `'1'` under Bun or `'22'` under Node.\n   */\n  runtimeVersion: string\n  platform: string\n  ci: boolean\n  /**\n   * Name of the detected AI coding agent (e.g. `'claude'`, `'cursor'`), when the CLI is invoked\n   * by one. `undefined` when run by a human or an unrecognized caller.\n   */\n  agent?: string\n  plugins: Array<TelemetryPlugin>\n  duration: number\n  filesCreated: number\n  status: 'success' | 'failed'\n}\n\n/**\n * Returns `true` when telemetry is disabled via `DO_NOT_TRACK` or `KUBB_DISABLE_TELEMETRY`.\n */\nexport function isDisabled(): boolean {\n  return (\n    process.env['DO_NOT_TRACK'] === '1' ||\n    process.env['DO_NOT_TRACK'] === 'true' ||\n    process.env['KUBB_DISABLE_TELEMETRY'] === '1' ||\n    process.env['KUBB_DISABLE_TELEMETRY'] === 'true'\n  )\n}\n\n/**\n * Build an anonymous telemetry payload from a completed generation run.\n */\nexport function buildTelemetryEvent(options: {\n  command: 'generate' | 'mcp' | 'validate'\n  kubbVersion: string\n  plugins?: Array<TelemetryPlugin>\n  hrStart: [number, number]\n  filesCreated?: number\n  status: 'success' | 'failed'\n}): TelemetryEvent {\n  const [seconds, nanoseconds] = process.hrtime(options.hrStart)\n  const duration = Math.round(seconds * 1000 + nanoseconds / 1e6)\n\n  return {\n    command: options.command,\n    kubbVersion: options.kubbVersion,\n    nodeVersion: process.versions.node.split('.')[0] as string,\n    runtime: runtime.name,\n    runtimeVersion: runtime.version.split('.')[0] as string,\n    platform: os.platform(),\n    ci: isCIEnvironment(),\n    agent: getAgentName(),\n    plugins: options.plugins ?? [],\n    duration,\n    filesCreated: options.filesCreated ?? 0,\n    status: options.status,\n  }\n}\n\n/**\n * Convert a {@link TelemetryEvent} into an OTLP-compatible JSON trace payload.\n *\n * @see https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/\n */\nexport function buildOtlpPayload(event: TelemetryEvent): OtlpExportTraceServiceRequest {\n  const traceId = randomBytes(16).toString('hex')\n  const spanId = randomBytes(8).toString('hex')\n  const endTimeNs = BigInt(Date.now()) * 1_000_000n\n  const startTimeNs = endTimeNs - BigInt(event.duration) * 1_000_000n\n\n  const attributes: Array<OtlpKeyValue> = [\n    { key: 'kubb.command', value: { stringValue: event.command } },\n    { key: 'kubb.version', value: { stringValue: event.kubbVersion } },\n    { key: 'kubb.node_version', value: { stringValue: event.nodeVersion } },\n    { key: 'kubb.runtime', value: { stringValue: event.runtime } },\n    { key: 'kubb.runtime_version', value: { stringValue: event.runtimeVersion } },\n    { key: 'kubb.platform', value: { stringValue: event.platform } },\n    { key: 'kubb.ci', value: { boolValue: event.ci } },\n    ...(event.agent ? [{ key: 'kubb.agent', value: { stringValue: event.agent } }] : []),\n    { key: 'kubb.files_created', value: { intValue: event.filesCreated } },\n    { key: 'kubb.status', value: { stringValue: event.status } },\n    {\n      key: 'kubb.plugins',\n      value: {\n        arrayValue: {\n          values: event.plugins.map((p) => ({\n            kvlistValue: {\n              values: [\n                { key: 'name', value: { stringValue: p.name } },\n                {\n                  key: 'options',\n                  value: {\n                    stringValue: JSON.stringify({\n                      ...p.options,\n                      usedEnumNames: undefined,\n                    }),\n                  },\n                },\n              ],\n            },\n          })),\n        },\n      },\n    },\n  ]\n\n  return {\n    resourceSpans: [\n      {\n        resource: {\n          attributes: [\n            { key: 'service.name', value: { stringValue: 'kubb-core' } },\n            {\n              key: 'service.version',\n              value: { stringValue: event.kubbVersion },\n            },\n            { key: 'telemetry.sdk.language', value: { stringValue: 'nodejs' } },\n          ],\n        },\n        scopeSpans: [\n          {\n            scope: { name: 'kubb-core', version: event.kubbVersion },\n            spans: [\n              {\n                traceId,\n                spanId,\n                name: event.command,\n                kind: 1,\n                startTimeUnixNano: String(startTimeNs),\n                endTimeUnixNano: String(endTimeNs),\n                attributes,\n                status: {\n                  code: event.status === 'success' ? 1 : 2,\n                },\n              },\n            ],\n          },\n        ],\n      },\n    ],\n  }\n}\n\n/**\n * Send an anonymous telemetry event to the Kubb OTLP endpoint. Respects `DO_NOT_TRACK` and\n * `KUBB_DISABLE_TELEMETRY`, and fails silently so telemetry never interrupts a run. No file\n * paths, OpenAPI specs, or secrets are sent.\n */\nexport async function sendTelemetry(event: TelemetryEvent): Promise<void> {\n  if (isDisabled()) {\n    return\n  }\n\n  try {\n    await fetch(`${OTLP_ENDPOINT}/v1/traces`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'Kubb-Telemetry-Version': '1',\n        'Kubb-Telemetry-Source': 'kubb-core',\n      },\n      body: JSON.stringify(buildOtlpPayload(event)),\n      signal: AbortSignal.timeout(5_000),\n    })\n  } catch (_e) {\n    // Fail silently, telemetry must never break the run\n  }\n}\n"],"mappings":"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"}