autotel-devtools 8.1.0 → 8.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/error-aggregator.ts","../src/server/telemetry-limits.ts","../src/server/origin-guard.ts","../src/server/server.ts","../src/server/resource-utils.ts","../src/server/otlp.ts","../src/server/otlp-proto.ts","../src/server/identity.ts","../src/server/http.ts","../src/server/listen.ts","../src/cli.ts"],"names":["createServer","WebSocketServer","WebSocket","resolve","protobuf","dirname","fileURLToPath","existsSync","readFileSync"],"mappings":"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","file":"cli.cjs","sourcesContent":["/**\n * Error Aggregator\n *\n * Groups similar errors together based on stack trace fingerprinting.\n * Tracks error frequency, first/last occurrence, and affected traces.\n *\n * @example\n * ```typescript\n * const aggregator = new ErrorAggregator({ maxGroups: 100 });\n *\n * // Add errors from spans\n * aggregator.addError({\n * traceId: '123',\n * spanId: '456',\n * spanName: 'api.createUser',\n * service: 'user-service',\n * timestamp: Date.now(),\n * error: {\n * type: 'ValidationError',\n * message: 'Invalid email format',\n * stackTrace: 'Error: Invalid email...'\n * }\n * });\n *\n * // Get aggregated error groups\n * const groups = aggregator.getErrorGroups();\n * ```\n */\n\nimport type { ErrorGroup, ErrorOccurrence, SpanData, TraceData } from './types';\n\nexport interface ErrorAggregatorOptions {\n /**\n * Maximum number of error groups to track (default: 100)\n * Oldest groups are evicted when limit is reached\n */\n maxGroups?: number;\n\n /**\n * Maximum number of affected traces to keep per group (default: 10)\n */\n maxAffectedTraces?: number;\n\n /**\n * Maximum number of affected span names to keep per group (default: 5)\n */\n maxAffectedSpans?: number;\n\n /**\n * Number of stack frames to use for fingerprinting (default: 5)\n */\n stackFramesForFingerprint?: number;\n}\n\nexport class ErrorAggregator {\n private errorGroups: Map<string, ErrorGroup> = new Map();\n private options: Required<ErrorAggregatorOptions>;\n\n constructor(options: ErrorAggregatorOptions = {}) {\n this.options = {\n maxGroups: options.maxGroups ?? 100,\n maxAffectedTraces: options.maxAffectedTraces ?? 10,\n maxAffectedSpans: options.maxAffectedSpans ?? 5,\n stackFramesForFingerprint: options.stackFramesForFingerprint ?? 5,\n };\n }\n\n /**\n * Add an error occurrence to the aggregator\n */\n addError(occurrence: ErrorOccurrence): ErrorGroup {\n const fingerprint = this.generateFingerprint(occurrence);\n const existing = this.errorGroups.get(fingerprint);\n\n if (existing) {\n // Update existing group\n existing.count++;\n existing.lastSeen = occurrence.timestamp;\n\n // Add trace ID if not already present (keep last N)\n if (!existing.affectedTraces.includes(occurrence.traceId)) {\n existing.affectedTraces.push(occurrence.traceId);\n if (existing.affectedTraces.length > this.options.maxAffectedTraces) {\n existing.affectedTraces.shift();\n }\n }\n\n // Add span name if not already present\n if (!existing.affectedSpans.includes(occurrence.spanName)) {\n existing.affectedSpans.push(occurrence.spanName);\n if (existing.affectedSpans.length > this.options.maxAffectedSpans) {\n existing.affectedSpans.shift();\n }\n }\n\n return existing;\n }\n\n // Create new group\n const newGroup: ErrorGroup = {\n fingerprint,\n type: occurrence.error.type,\n message: occurrence.error.message,\n stackTrace: this.normalizeStackTrace(occurrence.error.stackTrace),\n count: 1,\n firstSeen: occurrence.timestamp,\n lastSeen: occurrence.timestamp,\n affectedTraces: [occurrence.traceId],\n affectedSpans: [occurrence.spanName],\n service: occurrence.service,\n attributes: occurrence.attributes,\n };\n\n // Evict oldest group if at capacity\n if (this.errorGroups.size >= this.options.maxGroups) {\n this.evictOldestGroup();\n }\n\n this.errorGroups.set(fingerprint, newGroup);\n return newGroup;\n }\n\n /**\n * Extract errors from a trace and add them to the aggregator\n */\n addErrorsFromTrace(trace: TraceData): ErrorGroup[] {\n const addedGroups: ErrorGroup[] = [];\n\n for (const span of trace.spans) {\n if (span.status.code === 'ERROR') {\n const occurrence = this.extractErrorFromSpan(span, trace);\n if (occurrence) {\n const group = this.addError(occurrence);\n addedGroups.push(group);\n }\n }\n }\n\n return addedGroups;\n }\n\n /**\n * Extract error occurrence from a span\n */\n private extractErrorFromSpan(\n span: SpanData,\n trace: TraceData,\n ): ErrorOccurrence | null {\n // Try to get error info from span attributes or events\n const exceptionEvent = span.events?.find((e) => e.name === 'exception');\n const errorType =\n (span.attributes['exception.type'] as string) ||\n (span.attributes['error.type'] as string) ||\n (exceptionEvent?.attributes?.['exception.type'] as string) ||\n 'Error';\n\n const errorMessage =\n span.status.message ||\n (span.attributes['exception.message'] as string) ||\n (span.attributes['error.message'] as string) ||\n 'Unknown error';\n\n const stackTrace =\n (span.attributes['exception.stacktrace'] as string) ||\n (span.attributes['exception.stack'] as string) ||\n this.extractStackFromEvents(span);\n\n return {\n traceId: trace.traceId,\n spanId: span.spanId,\n spanName: span.name,\n service: trace.service,\n timestamp: span.endTime,\n error: {\n type: errorType,\n message: errorMessage,\n stackTrace,\n },\n attributes: this.extractRelevantAttributes(span.attributes),\n };\n }\n\n /**\n * Extract stack trace from span events (exception events)\n */\n private extractStackFromEvents(span: SpanData): string | undefined {\n if (!span.events) return undefined;\n\n const exceptionEvent = span.events.find((e) => e.name === 'exception');\n if (exceptionEvent?.attributes) {\n return (\n (exceptionEvent.attributes['exception.stacktrace'] as string) ||\n (exceptionEvent.attributes['exception.stack'] as string)\n );\n }\n\n return undefined;\n }\n\n /**\n * Extract relevant attributes for error context\n */\n private extractRelevantAttributes(\n attributes: Record<string, unknown>,\n ): Record<string, unknown> {\n const relevant: Record<string, unknown> = {};\n const keepKeys = [\n 'http.method',\n 'http.url',\n 'http.route',\n 'http.status_code',\n 'db.system',\n 'db.operation',\n 'rpc.method',\n 'rpc.service',\n 'code.function',\n 'code.filepath',\n 'user.id',\n 'operation.name',\n ];\n\n for (const key of keepKeys) {\n if (key in attributes) {\n relevant[key] = attributes[key];\n }\n }\n\n return relevant;\n }\n\n /**\n * Generate a fingerprint for error grouping\n *\n * Uses error type + first N stack frames (normalized)\n */\n private generateFingerprint(occurrence: ErrorOccurrence): string {\n const parts: string[] = [occurrence.error.type];\n\n if (occurrence.error.stackTrace) {\n const frames = this.extractStackFrames(\n occurrence.error.stackTrace,\n this.options.stackFramesForFingerprint,\n );\n parts.push(...frames);\n } else {\n // Fallback to error message if no stack trace\n parts.push(this.normalizeMessage(occurrence.error.message));\n }\n\n // Simple hash function\n return this.simpleHash(parts.join('|'));\n }\n\n /**\n * Extract and normalize stack frames from a stack trace\n */\n private extractStackFrames(stackTrace: string, count: number): string[] {\n const lines = stackTrace.split('\\n');\n const frames: string[] = [];\n\n for (const line of lines) {\n if (frames.length >= count) break;\n\n // Match common stack trace patterns\n const trimmed = line.trim();\n\n // Node.js style: \"at functionName (file:line:col)\"\n const nodeMatch = trimmed.match(/^at\\s+(.+?)\\s+\\((.+?):(\\d+):\\d+\\)$/);\n if (nodeMatch) {\n frames.push(`${nodeMatch[1]}@${this.normalizeFilePath(nodeMatch[2])}`);\n continue;\n }\n\n // Anonymous function style: \"at file:line:col\"\n const anonMatch = trimmed.match(/^at\\s+(.+?):(\\d+):\\d+$/);\n if (anonMatch) {\n frames.push(`anonymous@${this.normalizeFilePath(anonMatch[1])}`);\n continue;\n }\n\n // Browser style: \"functionName@file:line:col\"\n const browserMatch = trimmed.match(/^(.+?)@(.+?):(\\d+):\\d+$/);\n if (browserMatch) {\n frames.push(\n `${browserMatch[1]}@${this.normalizeFilePath(browserMatch[2])}`,\n );\n continue;\n }\n }\n\n return frames;\n }\n\n /**\n * Normalize file path by removing absolute path prefixes and node_modules paths\n */\n private normalizeFilePath(filePath: string): string {\n // Remove node_modules paths (keep package name)\n const nodeModulesMatch = filePath.match(\n /node_modules\\/(@[^/]+\\/[^/]+|[^/]+)/,\n );\n if (nodeModulesMatch) {\n return `[npm]/${nodeModulesMatch[1]}`;\n }\n\n // Remove common absolute path prefixes\n return filePath\n .replace(/^.*?\\/src\\//, 'src/')\n .replace(/^.*?\\/dist\\//, 'dist/')\n .replace(/^.*?\\/lib\\//, 'lib/')\n .replace(/^file:\\/\\//, '');\n }\n\n /**\n * Normalize error message by removing dynamic parts\n */\n private normalizeMessage(message: string): string {\n return (\n message\n // Remove UUIDs\n .replaceAll(\n /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,\n '[UUID]',\n )\n // Remove hex IDs\n .replaceAll(/\\b[0-9a-f]{16,}\\b/gi, '[ID]')\n // Remove numbers\n .replaceAll(/\\b\\d+\\b/g, '[N]')\n // Remove quoted strings\n .replaceAll(/\"[^\"]*\"/g, '\"[STR]\"')\n .replaceAll(/'[^']*'/g, \"'[STR]'\")\n // Truncate long messages\n .slice(0, 200)\n );\n }\n\n /**\n * Normalize stack trace for display\n */\n private normalizeStackTrace(stackTrace?: string): string | undefined {\n if (!stackTrace) return undefined;\n\n const lines = stackTrace.split('\\n').slice(0, 10); // Keep first 10 lines\n return lines.join('\\n');\n }\n\n /**\n * Simple hash function for fingerprinting\n */\n private simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(16).padStart(8, '0');\n }\n\n /**\n * Evict the oldest error group\n */\n private evictOldestGroup(): void {\n let oldest: { fingerprint: string; lastSeen: number } | null = null;\n\n for (const [fingerprint, group] of this.errorGroups) {\n if (!oldest || group.lastSeen < oldest.lastSeen) {\n oldest = { fingerprint, lastSeen: group.lastSeen };\n }\n }\n\n if (oldest) {\n this.errorGroups.delete(oldest.fingerprint);\n }\n }\n\n /**\n * Get all error groups, sorted by most recent\n */\n getErrorGroups(): ErrorGroup[] {\n return [...this.errorGroups.values()].sort(\n (a, b) => b.lastSeen - a.lastSeen,\n );\n }\n\n /**\n * Get error groups sorted by count (most frequent first)\n */\n getErrorGroupsByFrequency(): ErrorGroup[] {\n return [...this.errorGroups.values()].sort(\n (a, b) => b.count - a.count,\n );\n }\n\n /**\n * Get a specific error group by fingerprint\n */\n getErrorGroup(fingerprint: string): ErrorGroup | undefined {\n return this.errorGroups.get(fingerprint);\n }\n\n /**\n * Get error groups for a specific service\n */\n getErrorGroupsByService(service: string): ErrorGroup[] {\n return this.getErrorGroups().filter((g) => g.service === service);\n }\n\n /**\n * Get total error count across all groups\n */\n getTotalErrorCount(): number {\n let total = 0;\n for (const group of this.errorGroups.values()) {\n total += group.count;\n }\n return total;\n }\n\n /**\n * Get error statistics\n */\n getStats(): {\n totalGroups: number;\n totalErrors: number;\n recentErrors: number;\n topErrorTypes: Array<{ type: string; count: number }>;\n } {\n const now = Date.now();\n const oneHourAgo = now - 60 * 60 * 1000;\n\n let recentErrors = 0;\n const typeCount = new Map<string, number>();\n\n for (const group of this.errorGroups.values()) {\n if (group.lastSeen > oneHourAgo) {\n recentErrors += group.count;\n }\n typeCount.set(group.type, (typeCount.get(group.type) || 0) + group.count);\n }\n\n const topErrorTypes = [...typeCount.entries()]\n .map(([type, count]) => ({ type, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 5);\n\n return {\n totalGroups: this.errorGroups.size,\n totalErrors: this.getTotalErrorCount(),\n recentErrors,\n topErrorTypes,\n };\n }\n\n /**\n * Clear all error groups\n */\n clear(): void {\n this.errorGroups.clear();\n }\n\n /**\n * Clear old error groups (not seen in given time window)\n */\n clearOlderThan(maxAgeMs: number): number {\n const cutoff = Date.now() - maxAgeMs;\n let cleared = 0;\n\n for (const [fingerprint, group] of this.errorGroups) {\n if (group.lastSeen < cutoff) {\n this.errorGroups.delete(fingerprint);\n cleared++;\n }\n }\n\n return cleared;\n }\n}\n","import type { DevtoolsData } from './types'\n\nexport interface TelemetryLimits {\n maxTraceCount: number\n maxLogCount: number\n maxMetricCount: number\n}\n\nexport interface ResolveTelemetryLimitsArgs {\n maxHistory?: number\n maxTraceCount?: number\n maxLogCount?: number\n maxMetricCount?: number\n env?: NodeJS.ProcessEnv\n}\n\nconst defaultLimit = 100\n\nfunction parseLimit(value: string | undefined): number | undefined {\n if (!value) return undefined\n const parsed = Number.parseInt(value, 10)\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined\n}\n\nexport function resolveTelemetryLimits(\n args: ResolveTelemetryLimitsArgs = {},\n): TelemetryLimits {\n const env = args.env ?? process.env\n const fallback = args.maxHistory ?? defaultLimit\n\n return {\n maxTraceCount:\n args.maxTraceCount ??\n parseLimit(env.AUTOTEL_MAX_TRACE_COUNT) ??\n fallback,\n maxLogCount:\n args.maxLogCount ??\n parseLimit(env.AUTOTEL_MAX_LOG_COUNT) ??\n fallback,\n maxMetricCount:\n args.maxMetricCount ??\n parseLimit(env.AUTOTEL_MAX_METRIC_COUNT) ??\n fallback,\n }\n}\n\nexport function appendWithLimit<T>(items: T[], item: T, limit: number): T[] {\n if (limit <= 0) return []\n const next = [...items, item]\n return next.length > limit ? next.slice(next.length - limit) : next\n}\n\nexport function appendManyWithLimit<T>(\n items: T[],\n incoming: T[],\n limit: number,\n): T[] {\n if (limit <= 0 || incoming.length === 0) return limit <= 0 ? [] : items\n const next = [...items, ...incoming]\n return next.length > limit ? next.slice(next.length - limit) : next\n}\n\nexport function applyTelemetryLimits(\n data: DevtoolsData,\n limits: TelemetryLimits,\n): DevtoolsData {\n return {\n ...data,\n traces: data.traces.slice(-limits.maxTraceCount),\n logs: data.logs.slice(-limits.maxLogCount),\n metrics: data.metrics.slice(-limits.maxMetricCount),\n }\n}\n","// Guard the receiver's *read* surface (captured-telemetry read-back + the live\n// WebSocket) against being scraped by a web page the developer happens to be\n// visiting. The OTLP *ingest* endpoints stay wide open — browser apps on\n// arbitrary dev origins must be able to POST spans and load `widget.js`.\n//\n// Two browser-reachable attacks, two checks:\n// - Cross-origin read: a page at evil.com runs\n// `fetch('http://127.0.0.1:4318/v1/traces')` or opens `ws://…/ws`. The\n// browser attaches `Origin: https://evil.com` → reject non-loopback origins.\n// - DNS rebinding: attacker.com is made to resolve to 127.0.0.1, so the read\n// looks same-origin and may carry no `Origin` at all — but the `Host`\n// header is still `attacker.com` → reject non-loopback hosts. Only enforced\n// when the receiver is bound to loopback (the default); an explicit\n// non-loopback bind (`--host 0.0.0.0`) is an opt-in to network exposure, so\n// the Host check is skipped there and only the Origin check remains.\n//\n// Requests with no Origin and a loopback Host (curl, Node `fetch` in tests, the\n// UI's own same-origin calls) pass — exactly the legitimate read paths.\n\nconst LOOPBACK_IPV6 = new Set(['::1', '0:0:0:0:0:0:0:1'])\n\n/** True for `localhost`, any `127.x.x.x`, and IPv6 loopback. Case-insensitive. */\nexport function isLoopbackHostname(hostname: string): boolean {\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, '')\n return h === 'localhost' || /^127\\./.test(h) || LOOPBACK_IPV6.has(h)\n}\n\n/** Hostname from a `Host` header (`host`, `host:port`, `[::1]:port`). */\nfunction hostnameFromHostHeader(host: string): string {\n const h = host.trim()\n if (h.startsWith('[')) {\n const end = h.indexOf(']')\n return end > 0 ? h.slice(1, end) : h\n }\n const colon = h.indexOf(':')\n return colon === -1 ? h : h.slice(0, colon)\n}\n\n/** True when the `Host` header names a loopback host. */\nexport function hostHeaderIsLoopback(host: string): boolean {\n return isLoopbackHostname(hostnameFromHostHeader(host))\n}\n\n/** True when an `Origin` header names a loopback origin. A malformed or opaque\n * origin (e.g. the literal `null` from a sandboxed iframe) is treated as\n * non-loopback. */\nexport function originIsLoopback(origin: string): boolean {\n try {\n return isLoopbackHostname(new URL(origin).hostname)\n } catch {\n return false\n }\n}\n\nexport interface GuardHeaders {\n origin?: string\n host?: string\n}\n\n/**\n * Decide whether a request to a sensitive (read/mutate) endpoint is allowed.\n * - A present, non-loopback `Origin` is always rejected (cross-origin read).\n * - When `loopbackOnly`, a present, non-loopback `Host` is rejected (DNS\n * rebinding). Skipped when the receiver is bound to a non-loopback host.\n */\nexport function allowSensitiveRequest(\n headers: GuardHeaders,\n loopbackOnly: boolean,\n): boolean {\n const { origin, host } = headers\n if (origin && origin.length > 0 && !originIsLoopback(origin)) return false\n if (loopbackOnly && host && host.length > 0 && !hostHeaderIsLoopback(host)) {\n return false\n }\n return true\n}\n","// src/server/server.ts\nimport { WebSocketServer, WebSocket } from 'ws'\nimport type { Server as HTTPServer, IncomingMessage } from 'node:http'\nimport { createServer } from 'node:http'\nimport { ErrorAggregator } from './error-aggregator'\nimport type {\n TraceData,\n LogData,\n MetricData,\n DevtoolsData,\n} from './types'\nimport {\n appendManyWithLimit,\n appendWithLimit,\n resolveTelemetryLimits,\n type TelemetryLimits,\n} from './telemetry-limits'\nimport { allowSensitiveRequest, hostHeaderIsLoopback } from './origin-guard'\n\nexport interface DevtoolsServerOptions {\n port?: number\n server?: HTTPServer\n path?: string\n verbose?: boolean\n maxHistory?: number\n maxTraceCount?: number\n maxLogCount?: number\n maxMetricCount?: number\n /**\n * Bind host, used only to decide the WebSocket origin policy. A loopback host\n * (the default) enables the DNS-rebinding `Host` check on the live stream; an\n * explicit non-loopback bind opts out, leaving just the cross-origin check.\n */\n host?: string\n /**\n * Called after each ingest, with the incremental data just broadcast to WS\n * clients. Lets an embedder (e.g. the VS Code extension) react to new\n * telemetry — refresh its own tree views — while the server owns the buffer.\n */\n onData?: (incremental: DevtoolsData) => void\n}\n\nexport class DevtoolsServer {\n private wss: WebSocketServer\n private clients = new Set<WebSocket>()\n private httpServer: HTTPServer\n private traces: TraceData[] = []\n private logs: LogData[] = []\n private metrics: MetricData[] = []\n private errorAggregator = new ErrorAggregator()\n private limits: TelemetryLimits\n private verbose: boolean\n private _port: number\n private onData?: (incremental: DevtoolsData) => void\n\n constructor(options: DevtoolsServerOptions = {}) {\n this.limits = resolveTelemetryLimits(options)\n this.verbose = options.verbose ?? false\n this._port = options.port ?? 4318\n this.onData = options.onData\n\n this.httpServer = options.server ?? createServer()\n // Reject a live-stream subscription from a page that isn't same-machine —\n // a browser tab on evil.com opening `ws://127.0.0.1:PORT/ws` would otherwise\n // receive every captured span. Mirrors the read-back HTTP guard.\n const loopbackOnly = options.host == null || hostHeaderIsLoopback(options.host)\n this.wss = new WebSocketServer({\n server: this.httpServer,\n path: options.path ?? '/ws',\n verifyClient: ({ origin, req }: { origin: string; req: IncomingMessage }) =>\n allowSensitiveRequest({ origin, host: req.headers.host }, loopbackOnly),\n })\n\n // The `ws` library re-emits the http server's `error` event onto the\n // WebSocketServer itself. During the bind phase (EADDRINUSE etc.) the\n // http server's own listener owns recovery, and the re-emission here has\n // no listener — it would crash the process. Swallow ONLY that bind-phase\n // re-emission (server not yet listening). Anything emitted once the server\n // is live is a genuine WSS fault — re-throw so it surfaces.\n this.wss.on('error', (err) => {\n if (this.httpServer.listening) throw err\n })\n\n this.wss.on('connection', (ws) => {\n this.clients.add(ws)\n this.log(`Client connected (${this.clients.size} total)`)\n\n // Send history to late-connecting clients\n const data = this.getCurrentData()\n if (data.traces.length > 0 || data.logs.length > 0 || data.errors.length > 0) {\n ws.send(JSON.stringify(data))\n }\n\n ws.on('close', () => {\n this.clients.delete(ws)\n this.log(`Client disconnected (${this.clients.size} total)`)\n })\n })\n\n // Only start listening if no external server was provided\n if (!options.server) {\n this.httpServer.listen(this._port, () => {\n const addr = this.httpServer.address()\n if (addr && typeof addr === 'object') this._port = addr.port\n this.log(`WebSocket server listening on port ${this._port}`)\n })\n }\n }\n\n get port(): number {\n const addr = this.httpServer.address()\n if (addr && typeof addr === 'object') return addr.port\n return this._port\n }\n\n get clientCount(): number {\n return this.clients.size\n }\n\n addTrace(trace: TraceData): void {\n // Merge if trace already exists (out-of-order spans)\n const existing = this.traces.find(t => t.traceId === trace.traceId)\n if (existing) {\n const existingSpanIds = new Set(existing.spans.map(s => s.spanId))\n for (const span of trace.spans) {\n if (!existingSpanIds.has(span.spanId)) {\n existing.spans.push(span)\n }\n }\n existing.startTime = Math.min(existing.startTime, trace.startTime)\n existing.endTime = Math.max(existing.endTime, trace.endTime)\n existing.duration = existing.endTime - existing.startTime\n if (trace.status === 'ERROR') existing.status = 'ERROR'\n } else {\n this.traces = appendWithLimit(\n this.traces,\n trace,\n this.limits.maxTraceCount,\n )\n }\n\n this.errorAggregator.addErrorsFromTrace(trace)\n this.broadcast({ traces: [trace], metrics: [], logs: [], errors: this.errorAggregator.getErrorGroups() })\n }\n\n addTraces(traces: TraceData[]): void {\n for (const trace of traces) this.addTrace(trace)\n }\n\n // `errors` is full-state on every broadcast (the client replaces, not appends),\n // so non-trace broadcasts must echo the current error groups rather than `[]` —\n // otherwise a log/metric arriving after an error would wipe it from the UI.\n addLog(log: LogData): void {\n this.logs = appendWithLimit(this.logs, log, this.limits.maxLogCount)\n this.broadcast({ traces: [], metrics: [], logs: [log], errors: this.errorAggregator.getErrorGroups() })\n }\n\n addLogs(logs: LogData[]): void {\n this.logs = appendManyWithLimit(this.logs, logs, this.limits.maxLogCount)\n this.broadcast({ traces: [], metrics: [], logs, errors: this.errorAggregator.getErrorGroups() })\n }\n\n addMetric(metric: MetricData): void {\n this.metrics = appendWithLimit(\n this.metrics,\n metric,\n this.limits.maxMetricCount,\n )\n this.broadcast({ traces: [], metrics: [metric], logs: [], errors: this.errorAggregator.getErrorGroups() })\n }\n\n getCurrentData(): DevtoolsData {\n return {\n traces: this.traces,\n metrics: this.metrics,\n logs: this.logs,\n errors: this.errorAggregator.getErrorGroups(),\n }\n }\n\n clearData(): void {\n this.traces = []\n this.logs = []\n this.metrics = []\n this.errorAggregator.clear()\n }\n\n private broadcast(data: DevtoolsData): void {\n const msg = JSON.stringify(data)\n for (const client of this.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(msg)\n }\n }\n // Notify embedders after WS fan-out; never let a listener throw break ingest.\n if (this.onData) {\n try {\n this.onData(data)\n } catch {\n /* embedder listener errors are their own concern */\n }\n }\n }\n\n private log(message: string): void {\n if (this.verbose) console.log(`[autotel-devtools] ${message}`)\n }\n\n async close(): Promise<void> {\n for (const client of this.clients) client.close()\n this.clients.clear()\n this.wss.close()\n await new Promise<void>((resolve) => this.httpServer.close(() => resolve()))\n }\n}\n","export function getResourceName(\n resource: Record<string, unknown> | undefined,\n fallback = 'unknown',\n): string {\n if (!resource) return fallback\n\n const candidates = [\n resource['service.name'],\n resource['service.namespace'],\n resource['deployment.environment.name'],\n resource['host.name'],\n resource['container.name'],\n resource['process.executable.name'],\n ]\n\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n return candidate\n }\n }\n\n return fallback\n}\n","// src/server/otlp.ts\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { SpanData, TraceData, LogData } from './types'\nimport { getResourceName } from './resource-utils'\n\ntype OtlpAnyValue = {\n stringValue?: string\n boolValue?: boolean\n intValue?: string | number\n doubleValue?: number\n bytesValue?: string\n arrayValue?: { values?: OtlpAnyValue[] }\n kvlistValue?: { values?: OtlpKeyValue[] }\n}\n\ntype OtlpKeyValue = { key: string; value?: OtlpAnyValue }\n\nfunction resolveOtlpValue(v?: OtlpAnyValue): unknown {\n if (!v) return undefined\n if (v.stringValue !== undefined) return v.stringValue\n if (v.boolValue !== undefined) return v.boolValue\n if (v.intValue !== undefined) return typeof v.intValue === 'string' ? Number(v.intValue) : v.intValue\n if (v.doubleValue !== undefined) return v.doubleValue\n if (v.bytesValue !== undefined) return v.bytesValue\n if (v.arrayValue?.values) return v.arrayValue.values.map(resolveOtlpValue)\n if (v.kvlistValue?.values) return flattenAttributes(v.kvlistValue.values)\n return undefined\n}\n\nfunction flattenAttributes(attrs?: OtlpKeyValue[]): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n if (!attrs) return out\n for (const { key, value } of attrs) {\n out[key] = resolveOtlpValue(value)\n }\n return out\n}\n\nfunction nanoToMs(nano?: string): number {\n if (!nano) return 0\n // Split into integer ms (kept in BigInt to stay exact at epoch magnitude,\n // which exceeds Number.MAX_SAFE_INTEGER in nanoseconds) plus the sub-ms\n // remainder, so fast spans (<1ms) keep microsecond precision instead of\n // collapsing to 0ms.\n const ns = BigInt(nano)\n const ms = ns / 1_000_000n\n const remNs = ns % 1_000_000n\n return Number(ms) + Number(remNs) / 1_000_000\n}\n\nconst SPAN_KIND_MAP: Record<number | string, SpanData['kind']> = {\n 0: 'INTERNAL', 1: 'INTERNAL', 2: 'SERVER', 3: 'CLIENT', 4: 'PRODUCER', 5: 'CONSUMER',\n SPAN_KIND_INTERNAL: 'INTERNAL', SPAN_KIND_SERVER: 'SERVER',\n SPAN_KIND_CLIENT: 'CLIENT', SPAN_KIND_PRODUCER: 'PRODUCER', SPAN_KIND_CONSUMER: 'CONSUMER',\n}\n\nfunction normalizeHexId(id?: string): string {\n if (!id) return ''\n // Only attempt base64 decode for strings that look like base64-encoded binary IDs\n // (length 12 for 8-byte span IDs, 24/28 for 16-byte trace IDs, etc; valid base64\n // chars, not plain hex). Protobuf clients emit IDs as base64 (8-byte span IDs ->\n // 12 chars, 16-byte trace IDs -> 24 chars), so length 12 must be recognised too.\n const isBase64Like = /^[A-Za-z0-9+/=]+$/.test(id) && !(/^[0-9a-f]+$/i.test(id))\n const isLikelyBase64Id = isBase64Like && (id.length === 12 || id.length === 24 || id.length === 28 || id.length === 44 || id.length === 48)\n if (isLikelyBase64Id) {\n try {\n const bytes = Buffer.from(id, 'base64')\n return bytes.toString('hex')\n } catch { /* fall through */ }\n }\n return id\n}\n\nexport function parseOtlpTraces(payload: unknown): TraceData[] {\n if (!payload || typeof payload !== 'object') return []\n const { resourceSpans } = payload as any\n if (!Array.isArray(resourceSpans) || resourceSpans.length === 0) return []\n\n const traceMap = new Map<string, { spans: SpanData[]; service: string }>()\n\n for (const rs of resourceSpans) {\n const resourceAttrs = flattenAttributes(rs.resource?.attributes)\n const service = String(resourceAttrs['service.name'] || 'unknown')\n const scopeSpans = rs.scopeSpans || []\n\n for (const ss of scopeSpans) {\n const scope = ss.scope?.name\n ? { name: ss.scope.name, version: ss.scope.version || undefined }\n : undefined\n for (const span of ss.spans || []) {\n const traceId = normalizeHexId(span.traceId)\n if (!traceId) continue\n\n const startMs = nanoToMs(span.startTimeUnixNano)\n const endMs = nanoToMs(span.endTimeUnixNano)\n const statusCode = span.status?.code\n let status: SpanData['status']['code'] = 'UNSET'\n if (statusCode === 1 || statusCode === 'STATUS_CODE_OK') status = 'OK'\n if (statusCode === 2 || statusCode === 'STATUS_CODE_ERROR') status = 'ERROR'\n\n const spanData: SpanData = {\n traceId,\n spanId: normalizeHexId(span.spanId),\n parentSpanId: normalizeHexId(span.parentSpanId) || undefined,\n name: span.name || 'unknown',\n kind: SPAN_KIND_MAP[span.kind ?? 0] || 'INTERNAL',\n startTime: startMs,\n endTime: endMs,\n duration: endMs - startMs,\n attributes: { ...resourceAttrs, ...flattenAttributes(span.attributes) } as Record<string, any>,\n status: { code: status, message: span.status?.message },\n events: (span.events || []).map((e: any) => ({\n name: e.name || '',\n timestamp: nanoToMs(e.timeUnixNano),\n attributes: flattenAttributes(e.attributes) as Record<string, any>,\n })),\n links: (span.links || []).map((l: any) => ({\n traceId: normalizeHexId(l.traceId),\n spanId: normalizeHexId(l.spanId),\n attributes: flattenAttributes(l.attributes) as Record<string, any>,\n })),\n scope,\n }\n\n const existing = traceMap.get(traceId)\n if (existing) {\n existing.spans.push(spanData)\n } else {\n traceMap.set(traceId, { spans: [spanData], service })\n }\n }\n }\n }\n\n const traces: TraceData[] = []\n for (const [traceId, { spans, service }] of traceMap) {\n const sorted = spans.sort((a, b) => a.startTime - b.startTime)\n const rootSpan = sorted.find(s => !s.parentSpanId) || sorted[0]\n const startTime = Math.min(...sorted.map(s => s.startTime))\n const endTime = Math.max(...sorted.map(s => s.endTime))\n const hasError = sorted.some(s => s.status.code === 'ERROR')\n\n traces.push({\n traceId,\n correlationId: traceId.slice(0, 16),\n rootSpan,\n spans: sorted,\n startTime,\n endTime,\n duration: endTime - startTime,\n status: hasError ? 'ERROR' : 'OK',\n service,\n })\n }\n\n return traces\n}\n\nexport function parseOtlpLogs(payload: unknown): LogData[] {\n if (!payload || typeof payload !== 'object') return []\n const { resourceLogs } = payload as any\n if (!Array.isArray(resourceLogs)) return []\n\n const logs: LogData[] = []\n for (const rl of resourceLogs) {\n const resourceAttrs = flattenAttributes(rl.resource?.attributes)\n for (const sl of rl.scopeLogs || []) {\n for (const rec of sl.logRecords || []) {\n const timestamp = nanoToMs(rec.timeUnixNano || rec.observedTimeUnixNano)\n const traceId = normalizeHexId(rec.traceId) || undefined\n const spanId = normalizeHexId(rec.spanId) || undefined\n const body = rec.body ? resolveOtlpValue(rec.body) : ''\n\n logs.push({\n id: `${traceId || 'no-trace'}:${spanId || 'no-span'}:${timestamp}:${rec.severityNumber || 0}`,\n traceId,\n spanId,\n resourceName: getResourceName(resourceAttrs as Record<string, unknown>),\n severityText: rec.severityText,\n severityNumber: rec.severityNumber,\n body: typeof body === 'string' ? body : (body as Record<string, unknown>),\n timestamp,\n attributes: flattenAttributes(rec.attributes) as Record<string, unknown>,\n resource: resourceAttrs as Record<string, unknown>,\n })\n }\n }\n }\n\n return logs\n}\n\nexport function countOtlpMetrics(payload: unknown): number {\n if (!payload || typeof payload !== 'object') return 0\n const { resourceMetrics } = payload as any\n if (!Array.isArray(resourceMetrics)) return 0\n let count = 0\n for (const rm of resourceMetrics) {\n for (const sm of rm.scopeMetrics || []) {\n count += (sm.metrics || []).length\n }\n }\n return count\n}\n\nexport async function readJsonBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', () => {\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString()))\n } catch {\n reject(new Error('Invalid JSON'))\n }\n })\n req.on('error', reject)\n })\n}\n\nexport async function readRawBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', () => resolve(Buffer.concat(chunks)))\n req.on('error', reject)\n })\n}\n\n/**\n * True for OTLP/protobuf bodies. The OpenTelemetry Python/Java/Go SDKs default to\n * `http/protobuf` over OTLP HTTP, sending `application/x-protobuf`; some clients use\n * `application/protobuf`. Anything else (JSON, unset) is treated as OTLP/JSON.\n */\nexport function isProtobufContentType(contentType?: string): boolean {\n if (!contentType) return false\n const value = contentType.toLowerCase()\n return value.includes('application/x-protobuf') || value.includes('application/protobuf')\n}\n\nexport function sendJson(res: ServerResponse, status: number, data: Record<string, unknown>): void {\n const body = JSON.stringify(data)\n res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) })\n res.end(body)\n}\n","// src/server/otlp-proto.ts\n//\n// Decodes binary OTLP/protobuf request bodies (`Content-Type: application/x-protobuf`)\n// into the same plain-object shape the JSON parsers in `./otlp` already consume.\n//\n// Why this exists: the OpenTelemetry Python/Java/Go SDKs default to `http/protobuf`\n// when exporting over OTLP HTTP, so a receiver that only understood OTLP/JSON would\n// silently reject the most common real-world clients. Rather than re-implement the\n// wire format, we embed the (stable, v1) OTLP proto definitions and let protobufjs\n// do the decoding via reflection — no codegen step, no `.proto` assets to copy into\n// the build.\n//\n// The OTLP proto schema is frozen at v1 and only ever adds fields, so embedding the\n// subset we read is safe: unknown/newer fields are skipped by the decoder. The metrics\n// schema is intentionally minimal (we only count metrics, never inspect data points).\n//\n// `toObject` is configured to mirror OTLP/JSON exactly: 64-bit ints become decimal\n// strings and `bytes` (trace/span IDs) become base64 — which `normalizeHexId` in\n// `./otlp` already converts to hex. Enums are left numeric, which the parsers handle.\n\n// Default import (not `* as`): under esbuild's CJS->ESM interop a namespace import\n// only reliably exposes `.default`, leaving `protobuf.Root`/`protobuf.parse` undefined\n// in the bundled ESM output (`protobuf.Root is not a constructor` at runtime — the bug\n// that shipped in 5.0.1). The default import binds to protobufjs's `module.exports`, so\n// the constructors resolve in both the ESM and CJS bundles. Guarded by the dist ESM\n// smoke test in `__tests__/otlp-proto.dist.test.ts`.\nimport protobuf from 'protobufjs'\nimport type { IConversionOptions, Root } from 'protobufjs'\n\nconst COMMON_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.common.v1;\n\nmessage AnyValue {\n oneof value {\n string string_value = 1;\n bool bool_value = 2;\n int64 int_value = 3;\n double double_value = 4;\n ArrayValue array_value = 5;\n KeyValueList kvlist_value = 6;\n bytes bytes_value = 7;\n }\n}\nmessage ArrayValue { repeated AnyValue values = 1; }\nmessage KeyValueList { repeated KeyValue values = 1; }\nmessage KeyValue {\n string key = 1;\n AnyValue value = 2;\n}\nmessage InstrumentationScope {\n string name = 1;\n string version = 2;\n repeated KeyValue attributes = 3;\n uint32 dropped_attributes_count = 4;\n}\n`\n\nconst RESOURCE_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.resource.v1;\n\nmessage Resource {\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 1;\n uint32 dropped_attributes_count = 2;\n}\n`\n\nconst TRACE_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.trace.v1;\n\nmessage ResourceSpans {\n opentelemetry.proto.resource.v1.Resource resource = 1;\n repeated ScopeSpans scope_spans = 2;\n string schema_url = 3;\n}\nmessage ScopeSpans {\n opentelemetry.proto.common.v1.InstrumentationScope scope = 1;\n repeated Span spans = 2;\n string schema_url = 3;\n}\nmessage Span {\n bytes trace_id = 1;\n bytes span_id = 2;\n string trace_state = 3;\n bytes parent_span_id = 4;\n fixed32 flags = 16;\n string name = 5;\n SpanKind kind = 6;\n fixed64 start_time_unix_nano = 7;\n fixed64 end_time_unix_nano = 8;\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 9;\n uint32 dropped_attributes_count = 10;\n repeated Event events = 11;\n uint32 dropped_events_count = 12;\n repeated Link links = 13;\n uint32 dropped_links_count = 14;\n Status status = 15;\n\n enum SpanKind {\n SPAN_KIND_UNSPECIFIED = 0;\n SPAN_KIND_INTERNAL = 1;\n SPAN_KIND_SERVER = 2;\n SPAN_KIND_CLIENT = 3;\n SPAN_KIND_PRODUCER = 4;\n SPAN_KIND_CONSUMER = 5;\n }\n message Event {\n fixed64 time_unix_nano = 1;\n string name = 2;\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 3;\n uint32 dropped_attributes_count = 4;\n }\n message Link {\n bytes trace_id = 1;\n bytes span_id = 2;\n string trace_state = 3;\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 4;\n uint32 dropped_attributes_count = 5;\n fixed32 flags = 6;\n }\n}\nmessage Status {\n reserved 1;\n string message = 2;\n StatusCode code = 3;\n\n enum StatusCode {\n STATUS_CODE_UNSET = 0;\n STATUS_CODE_OK = 1;\n STATUS_CODE_ERROR = 2;\n }\n}\nmessage ExportTraceServiceRequest {\n repeated ResourceSpans resource_spans = 1;\n}\n`\n\nconst LOGS_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.logs.v1;\n\nenum SeverityNumber {\n SEVERITY_NUMBER_UNSPECIFIED = 0;\n SEVERITY_NUMBER_TRACE = 1;\n SEVERITY_NUMBER_TRACE2 = 2;\n SEVERITY_NUMBER_TRACE3 = 3;\n SEVERITY_NUMBER_TRACE4 = 4;\n SEVERITY_NUMBER_DEBUG = 5;\n SEVERITY_NUMBER_DEBUG2 = 6;\n SEVERITY_NUMBER_DEBUG3 = 7;\n SEVERITY_NUMBER_DEBUG4 = 8;\n SEVERITY_NUMBER_INFO = 9;\n SEVERITY_NUMBER_INFO2 = 10;\n SEVERITY_NUMBER_INFO3 = 11;\n SEVERITY_NUMBER_INFO4 = 12;\n SEVERITY_NUMBER_WARN = 13;\n SEVERITY_NUMBER_WARN2 = 14;\n SEVERITY_NUMBER_WARN3 = 15;\n SEVERITY_NUMBER_WARN4 = 16;\n SEVERITY_NUMBER_ERROR = 17;\n SEVERITY_NUMBER_ERROR2 = 18;\n SEVERITY_NUMBER_ERROR3 = 19;\n SEVERITY_NUMBER_ERROR4 = 20;\n SEVERITY_NUMBER_FATAL = 21;\n SEVERITY_NUMBER_FATAL2 = 22;\n SEVERITY_NUMBER_FATAL3 = 23;\n SEVERITY_NUMBER_FATAL4 = 24;\n}\nmessage ResourceLogs {\n opentelemetry.proto.resource.v1.Resource resource = 1;\n repeated ScopeLogs scope_logs = 2;\n string schema_url = 3;\n}\nmessage ScopeLogs {\n opentelemetry.proto.common.v1.InstrumentationScope scope = 1;\n repeated LogRecord log_records = 2;\n string schema_url = 3;\n}\nmessage LogRecord {\n reserved 4;\n fixed64 time_unix_nano = 1;\n fixed64 observed_time_unix_nano = 11;\n SeverityNumber severity_number = 2;\n string severity_text = 3;\n opentelemetry.proto.common.v1.AnyValue body = 5;\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 6;\n uint32 dropped_attributes_count = 7;\n fixed32 flags = 8;\n bytes trace_id = 9;\n bytes span_id = 10;\n}\nmessage ExportLogsServiceRequest {\n repeated ResourceLogs resource_logs = 1;\n}\n`\n\n// Minimal metrics schema: the receiver only counts metrics, it never inspects data\n// points. Decoding the structural envelope (resource -> scope -> metric name) is\n// enough; the data-point oneof and other Metric fields are skipped as unknown fields.\nconst METRICS_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.metrics.v1;\n\nmessage ResourceMetrics {\n opentelemetry.proto.resource.v1.Resource resource = 1;\n repeated ScopeMetrics scope_metrics = 2;\n string schema_url = 3;\n}\nmessage ScopeMetrics {\n opentelemetry.proto.common.v1.InstrumentationScope scope = 1;\n repeated Metric metrics = 2;\n string schema_url = 3;\n}\nmessage Metric {\n string name = 1;\n string description = 2;\n string unit = 3;\n}\nmessage ExportMetricsServiceRequest {\n repeated ResourceMetrics resource_metrics = 1;\n}\n`\n\n// Mirror the OTLP/JSON encoding so the existing parsers handle protobuf input\n// identically: 64-bit ints as decimal strings, bytes as base64 (IDs are then\n// hex-normalized downstream), enums left numeric, defaults omitted.\nconst TO_OBJECT_OPTIONS: IConversionOptions = {\n longs: String,\n bytes: String,\n defaults: false,\n}\n\nlet cachedRoot: Root | null = null\n\nfunction getRoot(): Root {\n if (cachedRoot) return cachedRoot\n const root = new protobuf.Root()\n for (const source of [COMMON_PROTO, RESOURCE_PROTO, TRACE_PROTO, LOGS_PROTO, METRICS_PROTO]) {\n protobuf.parse(source, root, { keepCase: false })\n }\n root.resolveAll()\n cachedRoot = root\n return root\n}\n\nfunction decodeRequest(typeName: string, body: Uint8Array): Record<string, unknown> {\n const messageType = getRoot().lookupType(typeName)\n const message = messageType.decode(body)\n return messageType.toObject(message, TO_OBJECT_OPTIONS) as Record<string, unknown>\n}\n\n/** Decode an OTLP/protobuf `ExportTraceServiceRequest` into the OTLP/JSON object shape. */\nexport function decodeOtlpTraceRequest(body: Uint8Array): Record<string, unknown> {\n return decodeRequest('opentelemetry.proto.trace.v1.ExportTraceServiceRequest', body)\n}\n\n/** Decode an OTLP/protobuf `ExportLogsServiceRequest` into the OTLP/JSON object shape. */\nexport function decodeOtlpLogsRequest(body: Uint8Array): Record<string, unknown> {\n return decodeRequest('opentelemetry.proto.logs.v1.ExportLogsServiceRequest', body)\n}\n\n/** Decode an OTLP/protobuf `ExportMetricsServiceRequest` into the OTLP/JSON object shape. */\nexport function decodeOtlpMetricsRequest(body: Uint8Array): Record<string, unknown> {\n return decodeRequest('opentelemetry.proto.metrics.v1.ExportMetricsServiceRequest', body)\n}\n","// src/server/identity.ts\n//\n// A first-class way to answer \"is the thing on this port actually\n// autotel-devtools?\". Clients and integrators used to have to sniff the shape\n// of GET /healthz (e.g. \"does the JSON have `ok` and `clients`?\"). That is\n// brittle. We now stamp every HTTP response with an `x-autotel-devtools`\n// header and put `service: \"autotel-devtools\"` in the /healthz body, so the\n// answer is unambiguous — and we use that here to tell our own instances apart\n// from a foreign OTLP collector squatting on the same port.\n\n/** Value of the `x-autotel-devtools` response header and the /healthz `service` field. */\nexport const DEVTOOLS_IDENTITY = 'autotel-devtools'\n\n/** Who is holding a TCP port, as far as we can tell over HTTP:\n * - `autotel-devtools` — another instance of us (benign; the user has two running)\n * - `foreign` — an HTTP server that is NOT us (e.g. an IDE's OTLP collector)\n * - `none` — nothing answered HTTP (refused, timed out, or non-HTTP listener) */\nexport type PortHolder = 'autotel-devtools' | 'foreign' | 'none'\n\n/**\n * Probe `host:port` over HTTP and classify what is listening. Used when our\n * requested port is busy: it lets us tell \"a stale autotel-devtools is still\n * up\" (benign) apart from \"a foreign collector owns this port\" — the latter is\n * the silent footgun where apps keep exporting OTLP to the busy port and reach\n * the wrong process, so the devtools UI stays empty and the app sees errors.\n */\nexport async function probePortHolder(\n host: string,\n port: number,\n timeoutMs = 500,\n): Promise<PortHolder> {\n // Bracket IPv6 literals for the URL authority (e.g. [::1]:4318).\n const authority = host.includes(':') ? `[${host}]` : host\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const res = await fetch(`http://${authority}:${port}/healthz`, {\n signal: controller.signal,\n })\n // The header is the fast, body-independent signal (present on every route).\n if (res.headers.get('x-autotel-devtools')) return 'autotel-devtools'\n // Fall back to the body in case a proxy stripped the header.\n try {\n const body = (await res.json()) as { service?: unknown }\n if (body && body.service === DEVTOOLS_IDENTITY) return 'autotel-devtools'\n } catch {\n // Not JSON — that's fine, it just isn't us.\n }\n return 'foreign'\n } catch {\n // Connection refused / timeout / non-HTTP listener. When the caller only\n // probes after a confirmed EADDRINUSE, `none` means \"occupied by something\n // that doesn't speak HTTP\" — still not us.\n return 'none'\n } finally {\n clearTimeout(timer)\n }\n}\n","// src/server/http.ts\nimport { createServer, type IncomingMessage, type ServerResponse, type Server } from 'node:http'\nimport { readFileSync, existsSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { parseOtlpTraces, parseOtlpLogs, countOtlpMetrics, readJsonBody, readRawBody, isProtobufContentType, sendJson } from './otlp'\nimport { decodeOtlpTraceRequest, decodeOtlpLogsRequest, decodeOtlpMetricsRequest } from './otlp-proto'\nimport { DEVTOOLS_IDENTITY } from './identity'\nimport { allowSensitiveRequest } from './origin-guard'\nimport type { DevtoolsServer } from './server'\n\ntype OtlpSignal = 'traces' | 'logs' | 'metrics'\n\n// Reply to a failed OTLP ingest. Echoing the content-type we received turns the\n// otherwise opaque \"Invalid OTLP payload\" into something a misconfigured\n// exporter can act on (e.g. it shows up as `null` when no header was sent, or\n// as a protobuf type the sender didn't expect to be using).\nfunction sendOtlpError(res: ServerResponse, req: IncomingMessage, e: unknown): void {\n sendJson(res, 400, {\n error: 'Invalid OTLP payload',\n message: e instanceof Error ? e.message : String(e),\n contentType: req.headers['content-type'] ?? null,\n })\n}\n\nconst PROTOBUF_DECODERS: Record<OtlpSignal, (body: Buffer) => Record<string, unknown>> = {\n traces: decodeOtlpTraceRequest,\n logs: decodeOtlpLogsRequest,\n metrics: decodeOtlpMetricsRequest,\n}\n\n// Read an OTLP request body as a plain object, transparently decoding both\n// OTLP/JSON (`application/json`) and OTLP/protobuf (`application/x-protobuf`).\n// Both shapes feed the same parsers, so callers don't care which the client sent.\nasync function readOtlpPayload(req: IncomingMessage, signal: OtlpSignal): Promise<unknown> {\n if (isProtobufContentType(req.headers['content-type'])) {\n return PROTOBUF_DECODERS[signal](await readRawBody(req))\n }\n return readJsonBody(req)\n}\n\nexport interface HttpServerOptions {\n port?: number\n host?: string\n}\n\nfunction findPackageRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 5; i++) {\n if (existsSync(resolve(dir, 'package.json'))) return dir\n dir = dirname(dir)\n }\n return dir\n}\n\nconst FULLPAGE_HTML = `<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>autotel-devtools</title><style>*{margin:0;padding:0;box-sizing:border-box}html,body{height:100%;width:100%;overflow:hidden}</style></head><body><script src=\"/widget.js?mode=fullpage\"></script></body></html>`\n\nlet cachedVersion: string | null = null\nfunction getVersion(): string {\n if (cachedVersion !== null) return cachedVersion\n let version = 'unknown'\n try {\n const pkg = JSON.parse(readFileSync(resolve(findPackageRoot(), 'package.json'), 'utf8'))\n if (typeof pkg.version === 'string') version = pkg.version\n } catch {\n /* keep 'unknown' */\n }\n cachedVersion = version\n return version\n}\n\nlet cachedWidgetJs: string | null = null\nfunction getWidgetJs(): string {\n if (!cachedWidgetJs) {\n const pkgRoot = findPackageRoot()\n const candidates = [\n resolve(pkgRoot, 'dist', 'widget.global.js'),\n resolve(pkgRoot, 'widget.global.js'),\n ]\n for (const candidate of candidates) {\n try {\n cachedWidgetJs = readFileSync(candidate, 'utf8')\n break\n } catch { /* try next */ }\n }\n if (!cachedWidgetJs) {\n cachedWidgetJs = '// widget bundle not found - run pnpm build first'\n }\n }\n return cachedWidgetJs\n}\n\nexport interface DevtoolsRoutesOptions {\n /** Bound to a loopback host (the default). Enables the DNS-rebinding `Host`\n * check on read endpoints; an explicit non-loopback bind opts out. */\n loopbackOnly?: boolean\n}\n\nexport function attachDevtoolsRoutes(\n httpServer: Server,\n devtools: DevtoolsServer,\n options: DevtoolsRoutesOptions = {},\n): void {\n const loopbackOnly = options.loopbackOnly ?? true\n httpServer.on('request', async (req: IncomingMessage, res: ServerResponse) => {\n // CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n\n // Identity stamp on every response: lets a client confirm it is really\n // talking to autotel-devtools (and not, say, an IDE's OTLP collector that\n // happens to share the port) without guessing from the body shape.\n res.setHeader('x-autotel-devtools', getVersion())\n res.setHeader('Access-Control-Expose-Headers', 'x-autotel-devtools')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n const url = req.url || '/'\n\n // GET / — fullpage HTML\n if (req.method === 'GET' && url === '/') {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': Buffer.byteLength(FULLPAGE_HTML) })\n res.end(FULLPAGE_HTML)\n return\n }\n\n // GET /widget.js — widget bundle\n if (req.method === 'GET' && url.startsWith('/widget.js')) {\n const js = getWidgetJs()\n res.writeHead(200, { 'Content-Type': 'application/javascript; charset=utf-8', 'Content-Length': Buffer.byteLength(js) })\n res.end(js)\n return\n }\n\n // GET /healthz — also the canonical identity probe: `service` + `version`\n // let a caller positively confirm this is autotel-devtools.\n if (req.method === 'GET' && url === '/healthz') {\n sendJson(res, 200, {\n ok: true,\n service: DEVTOOLS_IDENTITY,\n version: getVersion(),\n clients: devtools.clientCount,\n })\n return\n }\n\n // GET /v1/traces — read back what the collector has actually received.\n // This is the verification primitive for tests: poll the collector over\n // HTTP and assert receipt, instead of only asserting \"the client tried to\n // send\" (which a browser-level route intercept can fake). Bypasses the UI's\n // WebSocket entirely.\n if (req.method === 'GET' && url === '/v1/traces') {\n if (!allowSensitiveRequest(req.headers, loopbackOnly)) {\n sendJson(res, 403, { error: 'Forbidden' })\n return\n }\n const data = devtools.getCurrentData()\n sendJson(res, 200, { traces: data.traces, count: data.traces.length })\n return\n }\n\n // DELETE /v1/traces — clear captured telemetry (test isolation / reset).\n // Clears traces, logs, metrics and aggregated errors so each test starts clean.\n if (req.method === 'DELETE' && url === '/v1/traces') {\n if (!allowSensitiveRequest(req.headers, loopbackOnly)) {\n sendJson(res, 403, { error: 'Forbidden' })\n return\n }\n devtools.clearData()\n sendJson(res, 200, { cleared: true })\n return\n }\n\n // POST /v1/traces — accepts OTLP/JSON or OTLP/protobuf\n if (req.method === 'POST' && url === '/v1/traces') {\n try {\n const payload = await readOtlpPayload(req, 'traces')\n const traces = parseOtlpTraces(payload)\n devtools.addTraces(traces)\n sendJson(res, 200, { acceptedTraces: traces.length })\n } catch (e) {\n sendOtlpError(res, req, e)\n }\n return\n }\n\n // POST /v1/logs — accepts OTLP/JSON or OTLP/protobuf\n if (req.method === 'POST' && url === '/v1/logs') {\n try {\n const payload = await readOtlpPayload(req, 'logs')\n const logs = parseOtlpLogs(payload)\n devtools.addLogs(logs)\n sendJson(res, 200, { acceptedLogs: logs.length })\n } catch (e) {\n sendOtlpError(res, req, e)\n }\n return\n }\n\n // POST /v1/metrics — accepts OTLP/JSON or OTLP/protobuf\n if (req.method === 'POST' && url === '/v1/metrics') {\n try {\n const payload = await readOtlpPayload(req, 'metrics')\n const count = countOtlpMetrics(payload)\n sendJson(res, 200, { acceptedMetrics: count })\n } catch (e) {\n sendOtlpError(res, req, e)\n }\n return\n }\n\n sendJson(res, 404, { error: 'Not found' })\n })\n}\n\nexport function createDevtoolsHttpServer(devtools: DevtoolsServer, _options: HttpServerOptions = {}): Server {\n const server = createServer()\n attachDevtoolsRoutes(server, devtools)\n return server\n}\n","// src/server/listen.ts\nimport { createServer, type Server } from 'node:http'\n\nconst LOOPBACK = new Set(['localhost', '127.0.0.1', '::1'])\n\n/** How many consecutive ports to try before giving up. The default sweeps\n * 4318..4337 — a tight enough window that we don't accidentally squat on\n * something a sibling tool is using, but wide enough that the common case\n * (\"a previous devtools is still running\") succeeds. */\nconst DEFAULT_MAX_PORT_TRIES = 20\n\nexport interface LoopbackListeners {\n /** Resolves once the primary and (attempted) sibling listeners are up.\n * `port` is the port the primary actually bound to — it may differ from\n * the requested port when fallback was needed. */\n ready: Promise<{ addresses: string[]; port: number; warnings: string[] }>\n /** Close the sibling listener (the primary server is owned by the caller). */\n closeSibling: () => Promise<void>\n}\n\n/** Format host:port, bracketing IPv6 literals (e.g. `[::1]:4318`). */\nexport function formatAddress(host: string, port: number): string {\n return host.includes(':') ? `[${host}]:${port}` : `${host}:${port}`\n}\n\n/**\n * Listen on `host:port`, and when `host` is a loopback literal, ALSO listen on\n * the sibling loopback family (IPv4 ⟷ IPv6) so a client reaches the collector\n * whether the OS resolves `localhost` to `127.0.0.1` or `::1`.\n *\n * This kills a notoriously silent footgun: a dev-server proxy targeting\n * `http://localhost:PORT` on macOS resolves `localhost` to `::1`, but a\n * collector bound only to `127.0.0.1` never receives the request — spans\n * vanish with no error. Binding both loopback families makes `localhost` work\n * regardless of resolution order.\n *\n * If `port` is busy (EADDRINUSE), the listener walks forward up to `maxTries`\n * consecutive ports and binds the first one that's free. The resolved port\n * is returned in `ready` so callers can print correct URLs and OTLP\n * endpoints. Each fallback produces a warning.\n *\n * The sibling listener serves the same HTTP routes (via `attachSecondary`);\n * the WebSocket/UI stays on the primary address. If the sibling cannot bind\n * (e.g. no IPv6, or the port is taken on that family), it is reported as a\n * warning rather than a fatal error.\n */\nexport function listenLoopbackDualStack(args: {\n primary: Server\n port: number\n host: string\n attachSecondary: (server: Server) => void\n maxTries?: number\n}): LoopbackListeners {\n const { primary, port, host, attachSecondary, maxTries } = args\n const maxAttempts = Math.max(1, maxTries ?? DEFAULT_MAX_PORT_TRIES)\n let sibling: Server | undefined\n\n const ready = new Promise<{ addresses: string[]; port: number; warnings: string[] }>(\n (resolve, reject) => {\n const addresses: string[] = []\n const warnings: string[] = []\n // Normalise `localhost` to an explicit family so the primary bind is\n // deterministic and we know which sibling family to add.\n const primaryHost = host === 'localhost' ? '127.0.0.1' : host\n\n // The port currently being attempted, and how many we've burned so far.\n // One persistent handler pair owns the whole forward-walk; we just bump\n // `candidate` and re-`listen()` on the same server (the caller owns it\n // and has the WSS/routes attached, so we can't swap in a fresh one).\n let candidate = port\n let attempt = 0\n\n const bindFailed = (atPort: number, msg: string) =>\n reject(\n new Error(`could not bind ${formatAddress(primaryHost, atPort)}: ${msg}`),\n )\n\n // Walk forward from `port` until we find a free port. Anything that\n // isn't EADDRINUSE (EACCES, EAFNOSUPPORT, …) is fatal — it won't fix\n // itself on the next port.\n const onError = (e: NodeJS.ErrnoException) => {\n if (e.code !== 'EADDRINUSE') return bindFailed(candidate, e.message)\n if (++attempt >= maxAttempts) {\n reject(\n new Error(\n `could not bind ${formatAddress(primaryHost, port)}: ${maxAttempts} consecutive ports in use`,\n ),\n )\n return\n }\n candidate++\n listen()\n }\n\n const onListening = () => {\n // Bind succeeded — stop owning the primary's `error` event so a later\n // runtime error doesn't get mistaken for a bind failure.\n primary.removeListener('error', onError)\n if (candidate !== port) {\n warnings.push(`port ${port} was busy; using ${candidate} instead`)\n }\n const addr = primary.address()\n const resolvedPort =\n addr && typeof addr === 'object' ? addr.port : candidate\n addresses.push(formatAddress(primaryHost, resolvedPort))\n\n if (!LOOPBACK.has(host)) {\n resolve({ addresses, port: resolvedPort, warnings })\n return\n }\n\n const siblingHost = primaryHost === '::1' ? '127.0.0.1' : '::1'\n const s = createServer()\n attachSecondary(s)\n\n const onSiblingError = (se: Error) => {\n s.close()\n warnings.push(\n `could not also bind ${formatAddress(siblingHost, resolvedPort)} (${se.message}); ` +\n `clients using the ${siblingHost === '::1' ? 'IPv6' : 'IPv4'} form of \"localhost\" may not connect.`,\n )\n resolve({ addresses, port: resolvedPort, warnings })\n }\n s.once('error', onSiblingError)\n s.listen(resolvedPort, siblingHost, () => {\n s.off('error', onSiblingError)\n sibling = s\n addresses.push(formatAddress(siblingHost, resolvedPort))\n resolve({ addresses, port: resolvedPort, warnings })\n })\n }\n\n const listen = () => {\n try {\n primary.listen(candidate, primaryHost)\n } catch (e) {\n // `candidate` can overflow 65535 when the top port is busy; Node\n // throws a RangeError synchronously instead of emitting 'error'.\n primary.removeListener('error', onError)\n primary.removeListener('listening', onListening)\n bindFailed(candidate, (e as Error).message)\n }\n }\n\n primary.on('error', onError)\n primary.once('listening', onListening)\n listen()\n },\n )\n\n return {\n ready,\n closeSibling: () =>\n new Promise<void>((res) => {\n if (!sibling) return res()\n sibling.close(() => res())\n }),\n }\n}\n","#!/usr/bin/env node\n// src/cli.ts\nimport { createServer } from 'node:http'\nimport { readFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { DevtoolsServer } from './server/server'\nimport { attachDevtoolsRoutes } from './server/http'\nimport { hostHeaderIsLoopback } from './server/origin-guard'\nimport { listenLoopbackDualStack } from './server/listen'\nimport { probePortHolder } from './server/identity'\n\ninterface CliOptions {\n port: number\n host: string\n title?: string\n}\n\nfunction printHelp(): void {\n process.stdout.write(\n `autotel-devtools - Standalone OTLP receiver with web devtools UI\n\nUsage: autotel-devtools [port] [options]\n\nArguments:\n port Port to listen on (shorthand for --port; must be a positive integer)\n\nOptions:\n -p, --port <port> Port to listen on (default: 4318, env: AUTOTEL_DEVTOOLS_PORT).\n If the port is taken, the next free port is used and a warning is shown.\n -H, --host <host> Host to bind to (default: 127.0.0.1, env: AUTOTEL_DEVTOOLS_HOST)\n -t, --title <title> Dashboard title (env: AUTOTEL_DEVTOOLS_TITLE)\n Env limits: AUTOTEL_MAX_TRACE_COUNT, AUTOTEL_MAX_LOG_COUNT, AUTOTEL_MAX_METRIC_COUNT\n -h, --help Show this help message\n -v, --version Show version number\n\nEndpoints:\n GET / Web devtools UI (fullpage)\n GET /widget.js Widget bundle (embed in your app)\n POST /v1/traces Receive OTLP JSON trace data\n GET /v1/traces Read back received traces (verify ingestion in tests)\n DELETE /v1/traces Clear captured telemetry (test reset)\n POST /v1/logs Receive OTLP JSON log data\n POST /v1/metrics Receive OTLP JSON metric data\n WS /ws WebSocket stream for real-time updates\n GET /healthz Health check\n\nExamples:\n npx autotel-devtools\n npx autotel-devtools 4319\n npx autotel-devtools -p 4319 -H 0.0.0.0\n\nThen point your app:\n OTEL_EXPORTER_OTLP_PROTOCOL=http/json OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 node app.js\n\nView in browser:\n http://localhost:4318\n\nOr embed widget in your app:\n <script src=\"http://localhost:4318/widget.js\"></script>\n` + '\\n',\n )\n}\n\nfunction printVersion(): void {\n try {\n const dir = dirname(fileURLToPath(import.meta.url))\n const pkgPath = resolve(dir, '..', 'package.json')\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))\n process.stdout.write(`${pkg.version}\\n`)\n } catch {\n process.stdout.write('unknown\\n')\n }\n}\n\nfunction parseArgs(argv: string[]): CliOptions | null {\n const options: CliOptions = {\n port: parsePort(process.env.AUTOTEL_DEVTOOLS_PORT || '4318'),\n host: process.env.AUTOTEL_DEVTOOLS_HOST || '127.0.0.1',\n title: process.env.AUTOTEL_DEVTOOLS_TITLE,\n }\n\n // An explicit `--port`/`-p` always wins, regardless of where it sits in\n // argv. A bare numeric positional is shorthand for `--port`, but only when\n // no explicit flag was given — and only the first positional counts, so a\n // stray \"4318\" can't override an earlier positional either.\n let portWasExplicit = false\n let positionalPortConsumed = false\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]\n const next = argv[i + 1]\n if (arg === '--help' || arg === '-h') { printHelp(); return null }\n if (arg === '--version' || arg === '-v') { printVersion(); return null }\n if ((arg === '--port' || arg === '-p') && next) { options.port = parsePort(next); portWasExplicit = true; i++; continue }\n if ((arg === '--host' || arg === '-H') && next) { options.host = next; i++; continue }\n if ((arg === '--title' || arg === '-t') && next) { options.title = next; i++; continue }\n if (/^\\d+$/.test(arg) && !positionalPortConsumed) {\n if (!portWasExplicit) options.port = parsePort(arg)\n positionalPortConsumed = true\n continue\n }\n }\n\n return options\n}\n\nfunction parsePort(value: string): number {\n const n = Number(value)\n if (!Number.isInteger(n) || n < 0 || n > 65535) {\n process.stderr.write(`[autotel-devtools] invalid port: ${value}\\n`)\n process.exit(2)\n }\n return n\n}\n\nasync function main(): Promise<void> {\n const options = parseArgs(process.argv.slice(2))\n if (!options) { process.exit(0) }\n\n const httpServer = createServer()\n const loopbackOnly = hostHeaderIsLoopback(options.host)\n const wsServer = new DevtoolsServer({ server: httpServer, host: options.host, verbose: true })\n attachDevtoolsRoutes(httpServer, wsServer, { loopbackOnly })\n\n const listeners = listenLoopbackDualStack({\n primary: httpServer,\n port: options.port,\n host: options.host,\n attachSecondary: (s) => attachDevtoolsRoutes(s, wsServer, { loopbackOnly }),\n })\n\n const { addresses, warnings, port: boundPort } = await listeners.ready\n\n // Falling forward to a different port means the one we wanted is held by\n // someone else. Classify them: another autotel-devtools (benign) versus a\n // foreign process. The foreign case is the silent footgun — apps keep\n // exporting OTLP to the requested port and reach that process, not us, so\n // this UI stays empty while they see export errors. Say so, with the fix.\n if (boundPort !== options.port) {\n const holder = await probePortHolder(options.host, options.port)\n if (holder === 'autotel-devtools') {\n warnings.push(\n `another autotel-devtools is already running on port ${options.port}; ` +\n `this instance is on ${boundPort}. Use the existing one, or stop it and restart here.`,\n )\n } else {\n warnings.push(\n `port ${options.port} is held by another process that is NOT autotel-devtools. ` +\n `Anything exporting OTLP to :${options.port} is reaching that process, not this devtools. ` +\n `Point your exporter at :${boundPort}, or free :${options.port} and restart.`,\n )\n }\n }\n\n const uiBase = `http://${options.host === 'localhost' ? '127.0.0.1' : options.host}:${boundPort}`\n const title = options.title || 'autotel-devtools'\n process.stdout.write(`\\n ${title}\\n\\n`)\n process.stdout.write(` Listening: ${addresses.join(' + ')}\\n`)\n process.stdout.write(` UI: ${uiBase} (open in a browser)\\n`)\n process.stdout.write(` OTLP: ${uiBase}/v1/traces\\n`)\n process.stdout.write(` WebSocket: ${uiBase.replace('http', 'ws')}/ws\\n\\n`)\n // The widget bundle auto-mounts on load, so the bare <script> tag is all the\n // user needs — spell that out, plus the two opt-in variations, so nobody\n // wonders whether they also have to add an element by hand.\n process.stdout.write(\n ` Embed in your app — paste into your HTML; a floating panel appears automatically:\\n`,\n )\n process.stdout.write(` <script src=\"${uiBase}/widget.js\"></script>\\n\\n`)\n process.stdout.write(\n ` full screen instead: <script src=\"${uiBase}/widget.js?mode=fullpage\"></script>\\n`,\n )\n process.stdout.write(\n ` choose where it goes: add <autotel-devtools></autotel-devtools> to your markup\\n\\n`,\n )\n process.stdout.write(` Or point any OTLP exporter at this receiver:\\n`)\n process.stdout.write(` OTEL_EXPORTER_OTLP_PROTOCOL=http/json\\n`)\n process.stdout.write(` OTEL_EXPORTER_OTLP_ENDPOINT=${uiBase}\\n\\n`)\n // Self-check: confirm the collector is reachable AND that ingestion works,\n // not just that something is listening. Reading /v1/traces back is the same\n // check a test should make instead of trusting \"the client tried to send\".\n process.stdout.write(` Verify ingestion: curl -s ${uiBase}/v1/traces\\n\\n`)\n for (const w of warnings) {\n process.stdout.write(` ⚠ ${w}\\n`)\n }\n if (warnings.length > 0) process.stdout.write('\\n')\n\n const shutdown = () => {\n Promise.all([wsServer.close(), listeners.closeSibling()]).then(() =>\n process.exit(0),\n )\n }\n process.on('SIGINT', shutdown)\n process.on('SIGTERM', shutdown)\n}\n\nmain().catch((error) => {\n process.stderr.write(`[autotel-devtools] failed to start: ${error instanceof Error ? error.message : String(error)}\\n`)\n process.exit(1)\n})\n"]}
1
+ {"version":3,"sources":["../src/server/error-aggregator.ts","../src/server/telemetry-limits.ts","../src/server/origin-guard.ts","../src/server/server.ts","../src/server/resource-utils.ts","../src/server/otlp.ts","../src/server/otlp-proto.ts","../src/server/identity.ts","../src/server/http.ts","../src/server/listen.ts","../src/cli.ts"],"names":["createServer","WebSocketServer","WebSocket","resolve","protobuf","dirname","fileURLToPath","existsSync","readFileSync"],"mappings":"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","file":"cli.cjs","sourcesContent":["/**\n * Error Aggregator\n *\n * Groups similar errors together based on stack trace fingerprinting.\n * Tracks error frequency, first/last occurrence, and affected traces.\n *\n * @example\n * ```typescript\n * const aggregator = new ErrorAggregator({ maxGroups: 100 });\n *\n * // Add errors from spans\n * aggregator.addError({\n * traceId: '123',\n * spanId: '456',\n * spanName: 'api.createUser',\n * service: 'user-service',\n * timestamp: Date.now(),\n * error: {\n * type: 'ValidationError',\n * message: 'Invalid email format',\n * stackTrace: 'Error: Invalid email...'\n * }\n * });\n *\n * // Get aggregated error groups\n * const groups = aggregator.getErrorGroups();\n * ```\n */\n\nimport type { ErrorGroup, ErrorOccurrence, SpanData, TraceData } from './types';\n\nexport interface ErrorAggregatorOptions {\n /**\n * Maximum number of error groups to track (default: 100)\n * Oldest groups are evicted when limit is reached\n */\n maxGroups?: number;\n\n /**\n * Maximum number of affected traces to keep per group (default: 10)\n */\n maxAffectedTraces?: number;\n\n /**\n * Maximum number of affected span names to keep per group (default: 5)\n */\n maxAffectedSpans?: number;\n\n /**\n * Number of stack frames to use for fingerprinting (default: 5)\n */\n stackFramesForFingerprint?: number;\n}\n\nexport class ErrorAggregator {\n private errorGroups: Map<string, ErrorGroup> = new Map();\n private options: Required<ErrorAggregatorOptions>;\n\n constructor(options: ErrorAggregatorOptions = {}) {\n this.options = {\n maxGroups: options.maxGroups ?? 100,\n maxAffectedTraces: options.maxAffectedTraces ?? 10,\n maxAffectedSpans: options.maxAffectedSpans ?? 5,\n stackFramesForFingerprint: options.stackFramesForFingerprint ?? 5,\n };\n }\n\n /**\n * Add an error occurrence to the aggregator\n */\n addError(occurrence: ErrorOccurrence): ErrorGroup {\n const fingerprint = this.generateFingerprint(occurrence);\n const existing = this.errorGroups.get(fingerprint);\n\n if (existing) {\n // Update existing group\n existing.count++;\n existing.lastSeen = occurrence.timestamp;\n\n // Add trace ID if not already present (keep last N)\n if (!existing.affectedTraces.includes(occurrence.traceId)) {\n existing.affectedTraces.push(occurrence.traceId);\n if (existing.affectedTraces.length > this.options.maxAffectedTraces) {\n existing.affectedTraces.shift();\n }\n }\n\n // Add span name if not already present\n if (!existing.affectedSpans.includes(occurrence.spanName)) {\n existing.affectedSpans.push(occurrence.spanName);\n if (existing.affectedSpans.length > this.options.maxAffectedSpans) {\n existing.affectedSpans.shift();\n }\n }\n\n return existing;\n }\n\n // Create new group\n const newGroup: ErrorGroup = {\n fingerprint,\n type: occurrence.error.type,\n message: occurrence.error.message,\n stackTrace: this.normalizeStackTrace(occurrence.error.stackTrace),\n count: 1,\n firstSeen: occurrence.timestamp,\n lastSeen: occurrence.timestamp,\n affectedTraces: [occurrence.traceId],\n affectedSpans: [occurrence.spanName],\n service: occurrence.service,\n attributes: occurrence.attributes,\n };\n\n // Evict oldest group if at capacity\n if (this.errorGroups.size >= this.options.maxGroups) {\n this.evictOldestGroup();\n }\n\n this.errorGroups.set(fingerprint, newGroup);\n return newGroup;\n }\n\n /**\n * Extract errors from a trace and add them to the aggregator\n */\n addErrorsFromTrace(trace: TraceData): ErrorGroup[] {\n const addedGroups: ErrorGroup[] = [];\n\n for (const span of trace.spans) {\n if (span.status.code === 'ERROR') {\n const occurrence = this.extractErrorFromSpan(span, trace);\n if (occurrence) {\n const group = this.addError(occurrence);\n addedGroups.push(group);\n }\n }\n }\n\n return addedGroups;\n }\n\n /**\n * Extract error occurrence from a span\n */\n private extractErrorFromSpan(\n span: SpanData,\n trace: TraceData,\n ): ErrorOccurrence | null {\n // Try to get error info from span attributes or events\n const exceptionEvent = span.events?.find((e) => e.name === 'exception');\n const errorType =\n (span.attributes['exception.type'] as string) ||\n (span.attributes['error.type'] as string) ||\n (exceptionEvent?.attributes?.['exception.type'] as string) ||\n 'Error';\n\n const errorMessage =\n span.status.message ||\n (span.attributes['exception.message'] as string) ||\n (span.attributes['error.message'] as string) ||\n 'Unknown error';\n\n const stackTrace =\n (span.attributes['exception.stacktrace'] as string) ||\n (span.attributes['exception.stack'] as string) ||\n this.extractStackFromEvents(span);\n\n return {\n traceId: trace.traceId,\n spanId: span.spanId,\n spanName: span.name,\n service: trace.service,\n timestamp: span.endTime,\n error: {\n type: errorType,\n message: errorMessage,\n stackTrace,\n },\n attributes: this.extractRelevantAttributes(span.attributes),\n };\n }\n\n /**\n * Extract stack trace from span events (exception events)\n */\n private extractStackFromEvents(span: SpanData): string | undefined {\n if (!span.events) return undefined;\n\n const exceptionEvent = span.events.find((e) => e.name === 'exception');\n if (exceptionEvent?.attributes) {\n return (\n (exceptionEvent.attributes['exception.stacktrace'] as string) ||\n (exceptionEvent.attributes['exception.stack'] as string)\n );\n }\n\n return undefined;\n }\n\n /**\n * Extract relevant attributes for error context\n */\n private extractRelevantAttributes(\n attributes: Record<string, unknown>,\n ): Record<string, unknown> {\n const relevant: Record<string, unknown> = {};\n const keepKeys = [\n 'http.method',\n 'http.url',\n 'http.route',\n 'http.status_code',\n 'db.system',\n 'db.operation',\n 'rpc.method',\n 'rpc.service',\n 'code.function',\n 'code.filepath',\n 'user.id',\n 'operation.name',\n ];\n\n for (const key of keepKeys) {\n if (key in attributes) {\n relevant[key] = attributes[key];\n }\n }\n\n return relevant;\n }\n\n /**\n * Generate a fingerprint for error grouping\n *\n * Uses error type + first N stack frames (normalized)\n */\n private generateFingerprint(occurrence: ErrorOccurrence): string {\n const parts: string[] = [occurrence.error.type];\n\n if (occurrence.error.stackTrace) {\n const frames = this.extractStackFrames(\n occurrence.error.stackTrace,\n this.options.stackFramesForFingerprint,\n );\n parts.push(...frames);\n } else {\n // Fallback to error message if no stack trace\n parts.push(this.normalizeMessage(occurrence.error.message));\n }\n\n // Simple hash function\n return this.simpleHash(parts.join('|'));\n }\n\n /**\n * Extract and normalize stack frames from a stack trace\n */\n private extractStackFrames(stackTrace: string, count: number): string[] {\n const lines = stackTrace.split('\\n');\n const frames: string[] = [];\n\n for (const line of lines) {\n if (frames.length >= count) break;\n\n // Match common stack trace patterns\n const trimmed = line.trim();\n\n // Node.js style: \"at functionName (file:line:col)\"\n const nodeMatch = trimmed.match(/^at\\s+(.+?)\\s+\\((.+?):(\\d+):\\d+\\)$/);\n if (nodeMatch) {\n frames.push(`${nodeMatch[1]}@${this.normalizeFilePath(nodeMatch[2])}`);\n continue;\n }\n\n // Anonymous function style: \"at file:line:col\"\n const anonMatch = trimmed.match(/^at\\s+(.+?):(\\d+):\\d+$/);\n if (anonMatch) {\n frames.push(`anonymous@${this.normalizeFilePath(anonMatch[1])}`);\n continue;\n }\n\n // Browser style: \"functionName@file:line:col\"\n const browserMatch = trimmed.match(/^(.+?)@(.+?):(\\d+):\\d+$/);\n if (browserMatch) {\n frames.push(\n `${browserMatch[1]}@${this.normalizeFilePath(browserMatch[2])}`,\n );\n continue;\n }\n }\n\n return frames;\n }\n\n /**\n * Normalize file path by removing absolute path prefixes and node_modules paths\n */\n private normalizeFilePath(filePath: string): string {\n // Remove node_modules paths (keep package name)\n const nodeModulesMatch = filePath.match(\n /node_modules\\/(@[^/]+\\/[^/]+|[^/]+)/,\n );\n if (nodeModulesMatch) {\n return `[npm]/${nodeModulesMatch[1]}`;\n }\n\n // Remove common absolute path prefixes\n return filePath\n .replace(/^.*?\\/src\\//, 'src/')\n .replace(/^.*?\\/dist\\//, 'dist/')\n .replace(/^.*?\\/lib\\//, 'lib/')\n .replace(/^file:\\/\\//, '');\n }\n\n /**\n * Normalize error message by removing dynamic parts\n */\n private normalizeMessage(message: string): string {\n return (\n message\n // Remove UUIDs\n .replaceAll(\n /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,\n '[UUID]',\n )\n // Remove hex IDs\n .replaceAll(/\\b[0-9a-f]{16,}\\b/gi, '[ID]')\n // Remove numbers\n .replaceAll(/\\b\\d+\\b/g, '[N]')\n // Remove quoted strings\n .replaceAll(/\"[^\"]*\"/g, '\"[STR]\"')\n .replaceAll(/'[^']*'/g, \"'[STR]'\")\n // Truncate long messages\n .slice(0, 200)\n );\n }\n\n /**\n * Normalize stack trace for display\n */\n private normalizeStackTrace(stackTrace?: string): string | undefined {\n if (!stackTrace) return undefined;\n\n const lines = stackTrace.split('\\n').slice(0, 10); // Keep first 10 lines\n return lines.join('\\n');\n }\n\n /**\n * Simple hash function for fingerprinting\n */\n private simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(16).padStart(8, '0');\n }\n\n /**\n * Evict the oldest error group\n */\n private evictOldestGroup(): void {\n let oldest: { fingerprint: string; lastSeen: number } | null = null;\n\n for (const [fingerprint, group] of this.errorGroups) {\n if (!oldest || group.lastSeen < oldest.lastSeen) {\n oldest = { fingerprint, lastSeen: group.lastSeen };\n }\n }\n\n if (oldest) {\n this.errorGroups.delete(oldest.fingerprint);\n }\n }\n\n /**\n * Get all error groups, sorted by most recent\n */\n getErrorGroups(): ErrorGroup[] {\n return [...this.errorGroups.values()].sort(\n (a, b) => b.lastSeen - a.lastSeen,\n );\n }\n\n /**\n * Get error groups sorted by count (most frequent first)\n */\n getErrorGroupsByFrequency(): ErrorGroup[] {\n return [...this.errorGroups.values()].sort(\n (a, b) => b.count - a.count,\n );\n }\n\n /**\n * Get a specific error group by fingerprint\n */\n getErrorGroup(fingerprint: string): ErrorGroup | undefined {\n return this.errorGroups.get(fingerprint);\n }\n\n /**\n * Get error groups for a specific service\n */\n getErrorGroupsByService(service: string): ErrorGroup[] {\n return this.getErrorGroups().filter((g) => g.service === service);\n }\n\n /**\n * Get total error count across all groups\n */\n getTotalErrorCount(): number {\n let total = 0;\n for (const group of this.errorGroups.values()) {\n total += group.count;\n }\n return total;\n }\n\n /**\n * Get error statistics\n */\n getStats(): {\n totalGroups: number;\n totalErrors: number;\n recentErrors: number;\n topErrorTypes: Array<{ type: string; count: number }>;\n } {\n const now = Date.now();\n const oneHourAgo = now - 60 * 60 * 1000;\n\n let recentErrors = 0;\n const typeCount = new Map<string, number>();\n\n for (const group of this.errorGroups.values()) {\n if (group.lastSeen > oneHourAgo) {\n recentErrors += group.count;\n }\n typeCount.set(group.type, (typeCount.get(group.type) || 0) + group.count);\n }\n\n const topErrorTypes = [...typeCount.entries()]\n .map(([type, count]) => ({ type, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 5);\n\n return {\n totalGroups: this.errorGroups.size,\n totalErrors: this.getTotalErrorCount(),\n recentErrors,\n topErrorTypes,\n };\n }\n\n /**\n * Clear all error groups\n */\n clear(): void {\n this.errorGroups.clear();\n }\n\n /**\n * Clear old error groups (not seen in given time window)\n */\n clearOlderThan(maxAgeMs: number): number {\n const cutoff = Date.now() - maxAgeMs;\n let cleared = 0;\n\n for (const [fingerprint, group] of this.errorGroups) {\n if (group.lastSeen < cutoff) {\n this.errorGroups.delete(fingerprint);\n cleared++;\n }\n }\n\n return cleared;\n }\n}\n","import type { DevtoolsData } from './types'\n\nexport interface TelemetryLimits {\n maxTraceCount: number\n maxLogCount: number\n maxMetricCount: number\n}\n\nexport interface ResolveTelemetryLimitsArgs {\n maxHistory?: number\n maxTraceCount?: number\n maxLogCount?: number\n maxMetricCount?: number\n env?: NodeJS.ProcessEnv\n}\n\nconst defaultLimit = 100\n\nfunction parseLimit(value: string | undefined): number | undefined {\n if (!value) return undefined\n const parsed = Number.parseInt(value, 10)\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined\n}\n\nexport function resolveTelemetryLimits(\n args: ResolveTelemetryLimitsArgs = {},\n): TelemetryLimits {\n const env = args.env ?? process.env\n const fallback = args.maxHistory ?? defaultLimit\n\n return {\n maxTraceCount:\n args.maxTraceCount ??\n parseLimit(env.AUTOTEL_MAX_TRACE_COUNT) ??\n fallback,\n maxLogCount:\n args.maxLogCount ??\n parseLimit(env.AUTOTEL_MAX_LOG_COUNT) ??\n fallback,\n maxMetricCount:\n args.maxMetricCount ??\n parseLimit(env.AUTOTEL_MAX_METRIC_COUNT) ??\n fallback,\n }\n}\n\nexport function appendWithLimit<T>(items: T[], item: T, limit: number): T[] {\n if (limit <= 0) return []\n const next = [...items, item]\n return next.length > limit ? next.slice(next.length - limit) : next\n}\n\nexport function appendManyWithLimit<T>(\n items: T[],\n incoming: T[],\n limit: number,\n): T[] {\n if (limit <= 0 || incoming.length === 0) return limit <= 0 ? [] : items\n const next = [...items, ...incoming]\n return next.length > limit ? next.slice(next.length - limit) : next\n}\n\nexport function applyTelemetryLimits(\n data: DevtoolsData,\n limits: TelemetryLimits,\n): DevtoolsData {\n return {\n ...data,\n traces: data.traces.slice(-limits.maxTraceCount),\n logs: data.logs.slice(-limits.maxLogCount),\n metrics: data.metrics.slice(-limits.maxMetricCount),\n }\n}\n","// Guard the receiver's *read* surface (captured-telemetry read-back + the live\n// WebSocket) against being scraped by a web page the developer happens to be\n// visiting. The OTLP *ingest* endpoints stay wide open — browser apps on\n// arbitrary dev origins must be able to POST spans and load `widget.js`.\n//\n// Two browser-reachable attacks, two checks:\n// - Cross-origin read: a page at evil.com runs\n// `fetch('http://127.0.0.1:4318/v1/traces')` or opens `ws://…/ws`. The\n// browser attaches `Origin: https://evil.com` → reject non-loopback origins.\n// - DNS rebinding: attacker.com is made to resolve to 127.0.0.1, so the read\n// looks same-origin and may carry no `Origin` at all — but the `Host`\n// header is still `attacker.com` → reject non-loopback hosts. Only enforced\n// when the receiver is bound to loopback (the default); an explicit\n// non-loopback bind (`--host 0.0.0.0`) is an opt-in to network exposure, so\n// the Host check is skipped there and only the Origin check remains.\n//\n// Requests with no Origin and a loopback Host (curl, Node `fetch` in tests, the\n// UI's own same-origin calls) pass — exactly the legitimate read paths.\n\nconst LOOPBACK_IPV6 = new Set(['::1', '0:0:0:0:0:0:0:1'])\n\n/** True for `localhost`, any `127.x.x.x`, and IPv6 loopback. Case-insensitive. */\nexport function isLoopbackHostname(hostname: string): boolean {\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, '')\n return h === 'localhost' || /^127\\./.test(h) || LOOPBACK_IPV6.has(h)\n}\n\n/** Hostname from a `Host` header (`host`, `host:port`, `[::1]:port`). */\nfunction hostnameFromHostHeader(host: string): string {\n const h = host.trim()\n if (h.startsWith('[')) {\n const end = h.indexOf(']')\n return end > 0 ? h.slice(1, end) : h\n }\n const colon = h.indexOf(':')\n return colon === -1 ? h : h.slice(0, colon)\n}\n\n/** True when the `Host` header names a loopback host. */\nexport function hostHeaderIsLoopback(host: string): boolean {\n return isLoopbackHostname(hostnameFromHostHeader(host))\n}\n\n/** True when an `Origin` header names a loopback origin. A malformed or opaque\n * origin (e.g. the literal `null` from a sandboxed iframe) is treated as\n * non-loopback. */\nexport function originIsLoopback(origin: string): boolean {\n try {\n return isLoopbackHostname(new URL(origin).hostname)\n } catch {\n return false\n }\n}\n\nexport interface GuardHeaders {\n origin?: string\n host?: string\n}\n\n/**\n * Decide whether a request to a sensitive (read/mutate) endpoint is allowed.\n * - A present, non-loopback `Origin` is always rejected (cross-origin read).\n * - When `loopbackOnly`, a present, non-loopback `Host` is rejected (DNS\n * rebinding). Skipped when the receiver is bound to a non-loopback host.\n */\nexport function allowSensitiveRequest(\n headers: GuardHeaders,\n loopbackOnly: boolean,\n): boolean {\n const { origin, host } = headers\n if (origin && origin.length > 0 && !originIsLoopback(origin)) return false\n if (loopbackOnly && host && host.length > 0 && !hostHeaderIsLoopback(host)) {\n return false\n }\n return true\n}\n","// src/server/server.ts\nimport { WebSocketServer, WebSocket } from 'ws'\nimport type { Server as HTTPServer, IncomingMessage } from 'node:http'\nimport { createServer } from 'node:http'\nimport { ErrorAggregator } from './error-aggregator'\nimport type {\n TraceData,\n LogData,\n MetricData,\n DevtoolsData,\n} from './types'\nimport {\n appendManyWithLimit,\n appendWithLimit,\n resolveTelemetryLimits,\n type TelemetryLimits,\n} from './telemetry-limits'\nimport { allowSensitiveRequest, hostHeaderIsLoopback } from './origin-guard'\n\nexport interface DevtoolsServerOptions {\n port?: number\n server?: HTTPServer\n path?: string\n verbose?: boolean\n maxHistory?: number\n maxTraceCount?: number\n maxLogCount?: number\n maxMetricCount?: number\n /**\n * Bind host, used only to decide the WebSocket origin policy. A loopback host\n * (the default) enables the DNS-rebinding `Host` check on the live stream; an\n * explicit non-loopback bind opts out, leaving just the cross-origin check.\n */\n host?: string\n /**\n * Called after each ingest, with the incremental data just broadcast to WS\n * clients. Lets an embedder (e.g. the VS Code extension) react to new\n * telemetry — refresh its own tree views — while the server owns the buffer.\n */\n onData?: (incremental: DevtoolsData) => void\n}\n\nexport class DevtoolsServer {\n private wss: WebSocketServer\n private clients = new Set<WebSocket>()\n private httpServer: HTTPServer\n private traces: TraceData[] = []\n private logs: LogData[] = []\n private metrics: MetricData[] = []\n private errorAggregator = new ErrorAggregator()\n private limits: TelemetryLimits\n private verbose: boolean\n private _port: number\n private onData?: (incremental: DevtoolsData) => void\n\n constructor(options: DevtoolsServerOptions = {}) {\n this.limits = resolveTelemetryLimits(options)\n this.verbose = options.verbose ?? false\n this._port = options.port ?? 4318\n this.onData = options.onData\n\n this.httpServer = options.server ?? createServer()\n // Reject a live-stream subscription from a page that isn't same-machine —\n // a browser tab on evil.com opening `ws://127.0.0.1:PORT/ws` would otherwise\n // receive every captured span. Mirrors the read-back HTTP guard.\n const loopbackOnly = options.host == null || hostHeaderIsLoopback(options.host)\n this.wss = new WebSocketServer({\n server: this.httpServer,\n path: options.path ?? '/ws',\n verifyClient: ({ origin, req }: { origin: string; req: IncomingMessage }) =>\n allowSensitiveRequest({ origin, host: req.headers.host }, loopbackOnly),\n })\n\n // The `ws` library re-emits the http server's `error` event onto the\n // WebSocketServer itself. During the bind phase (EADDRINUSE etc.) the\n // http server's own listener owns recovery, and the re-emission here has\n // no listener — it would crash the process. Swallow ONLY that bind-phase\n // re-emission (server not yet listening). Anything emitted once the server\n // is live is a genuine WSS fault — re-throw so it surfaces.\n this.wss.on('error', (err) => {\n if (this.httpServer.listening) throw err\n })\n\n this.wss.on('connection', (ws) => {\n this.clients.add(ws)\n this.log(`Client connected (${this.clients.size} total)`)\n\n // Send history to late-connecting clients\n const data = this.getCurrentData()\n if (data.traces.length > 0 || data.logs.length > 0 || data.errors.length > 0) {\n ws.send(JSON.stringify(data))\n }\n\n ws.on('close', () => {\n this.clients.delete(ws)\n this.log(`Client disconnected (${this.clients.size} total)`)\n })\n })\n\n // Only start listening if no external server was provided\n if (!options.server) {\n this.httpServer.listen(this._port, () => {\n const addr = this.httpServer.address()\n if (addr && typeof addr === 'object') this._port = addr.port\n this.log(`WebSocket server listening on port ${this._port}`)\n })\n }\n }\n\n get port(): number {\n const addr = this.httpServer.address()\n if (addr && typeof addr === 'object') return addr.port\n return this._port\n }\n\n get clientCount(): number {\n return this.clients.size\n }\n\n addTrace(trace: TraceData): void {\n // Merge if trace already exists (out-of-order spans). Spans for one trace\n // arrive across multiple batches and services, so the root span and timing\n // must be recomputed from the merged span set — the first batch to arrive\n // (e.g. a downstream service) may not contain the parentless root span.\n const existing = this.traces.find(t => t.traceId === trace.traceId)\n const merged = existing ?? trace\n if (existing) {\n const existingSpanIds = new Set(existing.spans.map(s => s.spanId))\n for (const span of trace.spans) {\n if (!existingSpanIds.has(span.spanId)) {\n existing.spans.push(span)\n }\n }\n existing.startTime = Math.min(existing.startTime, trace.startTime)\n existing.endTime = Math.max(existing.endTime, trace.endTime)\n existing.duration = existing.endTime - existing.startTime\n if (trace.status === 'ERROR') existing.status = 'ERROR'\n\n const root = existing.spans.find(s => !s.parentSpanId)\n if (root) {\n existing.rootSpan = root\n const rootService = root.attributes?.['service.name']\n if (typeof rootService === 'string' && rootService.length > 0) {\n existing.service = rootService\n }\n }\n } else {\n this.traces = appendWithLimit(\n this.traces,\n trace,\n this.limits.maxTraceCount,\n )\n }\n\n this.errorAggregator.addErrorsFromTrace(trace)\n // Broadcast the merged trace (not just the incoming batch) so live clients\n // and any client that reconnects mid-trace converge on the full picture.\n this.broadcast({ traces: [merged], metrics: [], logs: [], errors: this.errorAggregator.getErrorGroups() })\n }\n\n addTraces(traces: TraceData[]): void {\n for (const trace of traces) this.addTrace(trace)\n }\n\n // `errors` is full-state on every broadcast (the client replaces, not appends),\n // so non-trace broadcasts must echo the current error groups rather than `[]` —\n // otherwise a log/metric arriving after an error would wipe it from the UI.\n addLog(log: LogData): void {\n this.logs = appendWithLimit(this.logs, log, this.limits.maxLogCount)\n this.broadcast({ traces: [], metrics: [], logs: [log], errors: this.errorAggregator.getErrorGroups() })\n }\n\n addLogs(logs: LogData[]): void {\n this.logs = appendManyWithLimit(this.logs, logs, this.limits.maxLogCount)\n this.broadcast({ traces: [], metrics: [], logs, errors: this.errorAggregator.getErrorGroups() })\n }\n\n addMetric(metric: MetricData): void {\n this.metrics = appendWithLimit(\n this.metrics,\n metric,\n this.limits.maxMetricCount,\n )\n this.broadcast({ traces: [], metrics: [metric], logs: [], errors: this.errorAggregator.getErrorGroups() })\n }\n\n getCurrentData(): DevtoolsData {\n return {\n traces: this.traces,\n metrics: this.metrics,\n logs: this.logs,\n errors: this.errorAggregator.getErrorGroups(),\n }\n }\n\n clearData(): void {\n this.traces = []\n this.logs = []\n this.metrics = []\n this.errorAggregator.clear()\n }\n\n private broadcast(data: DevtoolsData): void {\n const msg = JSON.stringify(data)\n for (const client of this.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(msg)\n }\n }\n // Notify embedders after WS fan-out; never let a listener throw break ingest.\n if (this.onData) {\n try {\n this.onData(data)\n } catch {\n /* embedder listener errors are their own concern */\n }\n }\n }\n\n private log(message: string): void {\n if (this.verbose) console.log(`[autotel-devtools] ${message}`)\n }\n\n async close(): Promise<void> {\n for (const client of this.clients) client.close()\n this.clients.clear()\n this.wss.close()\n await new Promise<void>((resolve) => this.httpServer.close(() => resolve()))\n }\n}\n","export function getResourceName(\n resource: Record<string, unknown> | undefined,\n fallback = 'unknown',\n): string {\n if (!resource) return fallback\n\n const candidates = [\n resource['service.name'],\n resource['service.namespace'],\n resource['deployment.environment.name'],\n resource['host.name'],\n resource['container.name'],\n resource['process.executable.name'],\n ]\n\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n return candidate\n }\n }\n\n return fallback\n}\n","// src/server/otlp.ts\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { SpanData, TraceData, LogData } from './types'\nimport { getResourceName } from './resource-utils'\n\ntype OtlpAnyValue = {\n stringValue?: string\n boolValue?: boolean\n intValue?: string | number\n doubleValue?: number\n bytesValue?: string\n arrayValue?: { values?: OtlpAnyValue[] }\n kvlistValue?: { values?: OtlpKeyValue[] }\n}\n\ntype OtlpKeyValue = { key: string; value?: OtlpAnyValue }\n\nfunction resolveOtlpValue(v?: OtlpAnyValue): unknown {\n if (!v) return undefined\n if (v.stringValue !== undefined) return v.stringValue\n if (v.boolValue !== undefined) return v.boolValue\n if (v.intValue !== undefined) return typeof v.intValue === 'string' ? Number(v.intValue) : v.intValue\n if (v.doubleValue !== undefined) return v.doubleValue\n if (v.bytesValue !== undefined) return v.bytesValue\n if (v.arrayValue?.values) return v.arrayValue.values.map(resolveOtlpValue)\n if (v.kvlistValue?.values) return flattenAttributes(v.kvlistValue.values)\n return undefined\n}\n\nfunction flattenAttributes(attrs?: OtlpKeyValue[]): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n if (!attrs) return out\n for (const { key, value } of attrs) {\n out[key] = resolveOtlpValue(value)\n }\n return out\n}\n\nfunction nanoToMs(nano?: string): number {\n if (!nano) return 0\n // Split into integer ms (kept in BigInt to stay exact at epoch magnitude,\n // which exceeds Number.MAX_SAFE_INTEGER in nanoseconds) plus the sub-ms\n // remainder, so fast spans (<1ms) keep microsecond precision instead of\n // collapsing to 0ms.\n const ns = BigInt(nano)\n const ms = ns / 1_000_000n\n const remNs = ns % 1_000_000n\n return Number(ms) + Number(remNs) / 1_000_000\n}\n\nconst SPAN_KIND_MAP: Record<number | string, SpanData['kind']> = {\n 0: 'INTERNAL', 1: 'INTERNAL', 2: 'SERVER', 3: 'CLIENT', 4: 'PRODUCER', 5: 'CONSUMER',\n SPAN_KIND_INTERNAL: 'INTERNAL', SPAN_KIND_SERVER: 'SERVER',\n SPAN_KIND_CLIENT: 'CLIENT', SPAN_KIND_PRODUCER: 'PRODUCER', SPAN_KIND_CONSUMER: 'CONSUMER',\n}\n\nfunction normalizeHexId(id?: string): string {\n if (!id) return ''\n // Only attempt base64 decode for strings that look like base64-encoded binary IDs\n // (length 12 for 8-byte span IDs, 24/28 for 16-byte trace IDs, etc; valid base64\n // chars, not plain hex). Protobuf clients emit IDs as base64 (8-byte span IDs ->\n // 12 chars, 16-byte trace IDs -> 24 chars), so length 12 must be recognised too.\n const isBase64Like = /^[A-Za-z0-9+/=]+$/.test(id) && !(/^[0-9a-f]+$/i.test(id))\n const isLikelyBase64Id = isBase64Like && (id.length === 12 || id.length === 24 || id.length === 28 || id.length === 44 || id.length === 48)\n if (isLikelyBase64Id) {\n try {\n const bytes = Buffer.from(id, 'base64')\n return bytes.toString('hex')\n } catch { /* fall through */ }\n }\n return id\n}\n\nexport function parseOtlpTraces(payload: unknown): TraceData[] {\n if (!payload || typeof payload !== 'object') return []\n const { resourceSpans } = payload as any\n if (!Array.isArray(resourceSpans) || resourceSpans.length === 0) return []\n\n const traceMap = new Map<string, { spans: SpanData[]; service: string }>()\n\n for (const rs of resourceSpans) {\n const resourceAttrs = flattenAttributes(rs.resource?.attributes)\n const service = String(resourceAttrs['service.name'] || 'unknown')\n const scopeSpans = rs.scopeSpans || []\n\n for (const ss of scopeSpans) {\n const scope = ss.scope?.name\n ? { name: ss.scope.name, version: ss.scope.version || undefined }\n : undefined\n for (const span of ss.spans || []) {\n const traceId = normalizeHexId(span.traceId)\n if (!traceId) continue\n\n const startMs = nanoToMs(span.startTimeUnixNano)\n const endMs = nanoToMs(span.endTimeUnixNano)\n const statusCode = span.status?.code\n let status: SpanData['status']['code'] = 'UNSET'\n if (statusCode === 1 || statusCode === 'STATUS_CODE_OK') status = 'OK'\n if (statusCode === 2 || statusCode === 'STATUS_CODE_ERROR') status = 'ERROR'\n\n const spanData: SpanData = {\n traceId,\n spanId: normalizeHexId(span.spanId),\n parentSpanId: normalizeHexId(span.parentSpanId) || undefined,\n name: span.name || 'unknown',\n kind: SPAN_KIND_MAP[span.kind ?? 0] || 'INTERNAL',\n startTime: startMs,\n endTime: endMs,\n duration: endMs - startMs,\n attributes: { ...resourceAttrs, ...flattenAttributes(span.attributes) } as Record<string, any>,\n status: { code: status, message: span.status?.message },\n events: (span.events || []).map((e: any) => ({\n name: e.name || '',\n timestamp: nanoToMs(e.timeUnixNano),\n attributes: flattenAttributes(e.attributes) as Record<string, any>,\n })),\n links: (span.links || []).map((l: any) => ({\n traceId: normalizeHexId(l.traceId),\n spanId: normalizeHexId(l.spanId),\n attributes: flattenAttributes(l.attributes) as Record<string, any>,\n })),\n scope,\n }\n\n const existing = traceMap.get(traceId)\n if (existing) {\n existing.spans.push(spanData)\n } else {\n traceMap.set(traceId, { spans: [spanData], service })\n }\n }\n }\n }\n\n const traces: TraceData[] = []\n for (const [traceId, { spans, service }] of traceMap) {\n const sorted = spans.sort((a, b) => a.startTime - b.startTime)\n const rootSpan = sorted.find(s => !s.parentSpanId) || sorted[0]\n const startTime = Math.min(...sorted.map(s => s.startTime))\n const endTime = Math.max(...sorted.map(s => s.endTime))\n const hasError = sorted.some(s => s.status.code === 'ERROR')\n\n traces.push({\n traceId,\n correlationId: traceId.slice(0, 16),\n rootSpan,\n spans: sorted,\n startTime,\n endTime,\n duration: endTime - startTime,\n status: hasError ? 'ERROR' : 'OK',\n service,\n })\n }\n\n return traces\n}\n\nexport function parseOtlpLogs(payload: unknown): LogData[] {\n if (!payload || typeof payload !== 'object') return []\n const { resourceLogs } = payload as any\n if (!Array.isArray(resourceLogs)) return []\n\n const logs: LogData[] = []\n for (const rl of resourceLogs) {\n const resourceAttrs = flattenAttributes(rl.resource?.attributes)\n for (const sl of rl.scopeLogs || []) {\n for (const rec of sl.logRecords || []) {\n const timestamp = nanoToMs(rec.timeUnixNano || rec.observedTimeUnixNano)\n const traceId = normalizeHexId(rec.traceId) || undefined\n const spanId = normalizeHexId(rec.spanId) || undefined\n const body = rec.body ? resolveOtlpValue(rec.body) : ''\n\n logs.push({\n id: `${traceId || 'no-trace'}:${spanId || 'no-span'}:${timestamp}:${rec.severityNumber || 0}`,\n traceId,\n spanId,\n resourceName: getResourceName(resourceAttrs as Record<string, unknown>),\n severityText: rec.severityText,\n severityNumber: rec.severityNumber,\n body: typeof body === 'string' ? body : (body as Record<string, unknown>),\n timestamp,\n attributes: flattenAttributes(rec.attributes) as Record<string, unknown>,\n resource: resourceAttrs as Record<string, unknown>,\n })\n }\n }\n }\n\n return logs\n}\n\nexport function countOtlpMetrics(payload: unknown): number {\n if (!payload || typeof payload !== 'object') return 0\n const { resourceMetrics } = payload as any\n if (!Array.isArray(resourceMetrics)) return 0\n let count = 0\n for (const rm of resourceMetrics) {\n for (const sm of rm.scopeMetrics || []) {\n count += (sm.metrics || []).length\n }\n }\n return count\n}\n\nexport async function readJsonBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', () => {\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString()))\n } catch {\n reject(new Error('Invalid JSON'))\n }\n })\n req.on('error', reject)\n })\n}\n\nexport async function readRawBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', () => resolve(Buffer.concat(chunks)))\n req.on('error', reject)\n })\n}\n\n/**\n * True for OTLP/protobuf bodies. The OpenTelemetry Python/Java/Go SDKs default to\n * `http/protobuf` over OTLP HTTP, sending `application/x-protobuf`; some clients use\n * `application/protobuf`. Anything else (JSON, unset) is treated as OTLP/JSON.\n */\nexport function isProtobufContentType(contentType?: string): boolean {\n if (!contentType) return false\n const value = contentType.toLowerCase()\n return value.includes('application/x-protobuf') || value.includes('application/protobuf')\n}\n\nexport function sendJson(res: ServerResponse, status: number, data: Record<string, unknown>): void {\n const body = JSON.stringify(data)\n res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) })\n res.end(body)\n}\n","// src/server/otlp-proto.ts\n//\n// Decodes binary OTLP/protobuf request bodies (`Content-Type: application/x-protobuf`)\n// into the same plain-object shape the JSON parsers in `./otlp` already consume.\n//\n// Why this exists: the OpenTelemetry Python/Java/Go SDKs default to `http/protobuf`\n// when exporting over OTLP HTTP, so a receiver that only understood OTLP/JSON would\n// silently reject the most common real-world clients. Rather than re-implement the\n// wire format, we embed the (stable, v1) OTLP proto definitions and let protobufjs\n// do the decoding via reflection — no codegen step, no `.proto` assets to copy into\n// the build.\n//\n// The OTLP proto schema is frozen at v1 and only ever adds fields, so embedding the\n// subset we read is safe: unknown/newer fields are skipped by the decoder. The metrics\n// schema is intentionally minimal (we only count metrics, never inspect data points).\n//\n// `toObject` is configured to mirror OTLP/JSON exactly: 64-bit ints become decimal\n// strings and `bytes` (trace/span IDs) become base64 — which `normalizeHexId` in\n// `./otlp` already converts to hex. Enums are left numeric, which the parsers handle.\n\n// Default import (not `* as`): under esbuild's CJS->ESM interop a namespace import\n// only reliably exposes `.default`, leaving `protobuf.Root`/`protobuf.parse` undefined\n// in the bundled ESM output (`protobuf.Root is not a constructor` at runtime — the bug\n// that shipped in 5.0.1). The default import binds to protobufjs's `module.exports`, so\n// the constructors resolve in both the ESM and CJS bundles. Guarded by the dist ESM\n// smoke test in `__tests__/otlp-proto.dist.test.ts`.\nimport protobuf from 'protobufjs'\nimport type { IConversionOptions, Root } from 'protobufjs'\n\nconst COMMON_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.common.v1;\n\nmessage AnyValue {\n oneof value {\n string string_value = 1;\n bool bool_value = 2;\n int64 int_value = 3;\n double double_value = 4;\n ArrayValue array_value = 5;\n KeyValueList kvlist_value = 6;\n bytes bytes_value = 7;\n }\n}\nmessage ArrayValue { repeated AnyValue values = 1; }\nmessage KeyValueList { repeated KeyValue values = 1; }\nmessage KeyValue {\n string key = 1;\n AnyValue value = 2;\n}\nmessage InstrumentationScope {\n string name = 1;\n string version = 2;\n repeated KeyValue attributes = 3;\n uint32 dropped_attributes_count = 4;\n}\n`\n\nconst RESOURCE_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.resource.v1;\n\nmessage Resource {\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 1;\n uint32 dropped_attributes_count = 2;\n}\n`\n\nconst TRACE_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.trace.v1;\n\nmessage ResourceSpans {\n opentelemetry.proto.resource.v1.Resource resource = 1;\n repeated ScopeSpans scope_spans = 2;\n string schema_url = 3;\n}\nmessage ScopeSpans {\n opentelemetry.proto.common.v1.InstrumentationScope scope = 1;\n repeated Span spans = 2;\n string schema_url = 3;\n}\nmessage Span {\n bytes trace_id = 1;\n bytes span_id = 2;\n string trace_state = 3;\n bytes parent_span_id = 4;\n fixed32 flags = 16;\n string name = 5;\n SpanKind kind = 6;\n fixed64 start_time_unix_nano = 7;\n fixed64 end_time_unix_nano = 8;\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 9;\n uint32 dropped_attributes_count = 10;\n repeated Event events = 11;\n uint32 dropped_events_count = 12;\n repeated Link links = 13;\n uint32 dropped_links_count = 14;\n Status status = 15;\n\n enum SpanKind {\n SPAN_KIND_UNSPECIFIED = 0;\n SPAN_KIND_INTERNAL = 1;\n SPAN_KIND_SERVER = 2;\n SPAN_KIND_CLIENT = 3;\n SPAN_KIND_PRODUCER = 4;\n SPAN_KIND_CONSUMER = 5;\n }\n message Event {\n fixed64 time_unix_nano = 1;\n string name = 2;\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 3;\n uint32 dropped_attributes_count = 4;\n }\n message Link {\n bytes trace_id = 1;\n bytes span_id = 2;\n string trace_state = 3;\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 4;\n uint32 dropped_attributes_count = 5;\n fixed32 flags = 6;\n }\n}\nmessage Status {\n reserved 1;\n string message = 2;\n StatusCode code = 3;\n\n enum StatusCode {\n STATUS_CODE_UNSET = 0;\n STATUS_CODE_OK = 1;\n STATUS_CODE_ERROR = 2;\n }\n}\nmessage ExportTraceServiceRequest {\n repeated ResourceSpans resource_spans = 1;\n}\n`\n\nconst LOGS_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.logs.v1;\n\nenum SeverityNumber {\n SEVERITY_NUMBER_UNSPECIFIED = 0;\n SEVERITY_NUMBER_TRACE = 1;\n SEVERITY_NUMBER_TRACE2 = 2;\n SEVERITY_NUMBER_TRACE3 = 3;\n SEVERITY_NUMBER_TRACE4 = 4;\n SEVERITY_NUMBER_DEBUG = 5;\n SEVERITY_NUMBER_DEBUG2 = 6;\n SEVERITY_NUMBER_DEBUG3 = 7;\n SEVERITY_NUMBER_DEBUG4 = 8;\n SEVERITY_NUMBER_INFO = 9;\n SEVERITY_NUMBER_INFO2 = 10;\n SEVERITY_NUMBER_INFO3 = 11;\n SEVERITY_NUMBER_INFO4 = 12;\n SEVERITY_NUMBER_WARN = 13;\n SEVERITY_NUMBER_WARN2 = 14;\n SEVERITY_NUMBER_WARN3 = 15;\n SEVERITY_NUMBER_WARN4 = 16;\n SEVERITY_NUMBER_ERROR = 17;\n SEVERITY_NUMBER_ERROR2 = 18;\n SEVERITY_NUMBER_ERROR3 = 19;\n SEVERITY_NUMBER_ERROR4 = 20;\n SEVERITY_NUMBER_FATAL = 21;\n SEVERITY_NUMBER_FATAL2 = 22;\n SEVERITY_NUMBER_FATAL3 = 23;\n SEVERITY_NUMBER_FATAL4 = 24;\n}\nmessage ResourceLogs {\n opentelemetry.proto.resource.v1.Resource resource = 1;\n repeated ScopeLogs scope_logs = 2;\n string schema_url = 3;\n}\nmessage ScopeLogs {\n opentelemetry.proto.common.v1.InstrumentationScope scope = 1;\n repeated LogRecord log_records = 2;\n string schema_url = 3;\n}\nmessage LogRecord {\n reserved 4;\n fixed64 time_unix_nano = 1;\n fixed64 observed_time_unix_nano = 11;\n SeverityNumber severity_number = 2;\n string severity_text = 3;\n opentelemetry.proto.common.v1.AnyValue body = 5;\n repeated opentelemetry.proto.common.v1.KeyValue attributes = 6;\n uint32 dropped_attributes_count = 7;\n fixed32 flags = 8;\n bytes trace_id = 9;\n bytes span_id = 10;\n}\nmessage ExportLogsServiceRequest {\n repeated ResourceLogs resource_logs = 1;\n}\n`\n\n// Minimal metrics schema: the receiver only counts metrics, it never inspects data\n// points. Decoding the structural envelope (resource -> scope -> metric name) is\n// enough; the data-point oneof and other Metric fields are skipped as unknown fields.\nconst METRICS_PROTO = `\nsyntax = \"proto3\";\npackage opentelemetry.proto.metrics.v1;\n\nmessage ResourceMetrics {\n opentelemetry.proto.resource.v1.Resource resource = 1;\n repeated ScopeMetrics scope_metrics = 2;\n string schema_url = 3;\n}\nmessage ScopeMetrics {\n opentelemetry.proto.common.v1.InstrumentationScope scope = 1;\n repeated Metric metrics = 2;\n string schema_url = 3;\n}\nmessage Metric {\n string name = 1;\n string description = 2;\n string unit = 3;\n}\nmessage ExportMetricsServiceRequest {\n repeated ResourceMetrics resource_metrics = 1;\n}\n`\n\n// Mirror the OTLP/JSON encoding so the existing parsers handle protobuf input\n// identically: 64-bit ints as decimal strings, bytes as base64 (IDs are then\n// hex-normalized downstream), enums left numeric, defaults omitted.\nconst TO_OBJECT_OPTIONS: IConversionOptions = {\n longs: String,\n bytes: String,\n defaults: false,\n}\n\nlet cachedRoot: Root | null = null\n\nfunction getRoot(): Root {\n if (cachedRoot) return cachedRoot\n const root = new protobuf.Root()\n for (const source of [COMMON_PROTO, RESOURCE_PROTO, TRACE_PROTO, LOGS_PROTO, METRICS_PROTO]) {\n protobuf.parse(source, root, { keepCase: false })\n }\n root.resolveAll()\n cachedRoot = root\n return root\n}\n\nfunction decodeRequest(typeName: string, body: Uint8Array): Record<string, unknown> {\n const messageType = getRoot().lookupType(typeName)\n const message = messageType.decode(body)\n return messageType.toObject(message, TO_OBJECT_OPTIONS) as Record<string, unknown>\n}\n\n/** Decode an OTLP/protobuf `ExportTraceServiceRequest` into the OTLP/JSON object shape. */\nexport function decodeOtlpTraceRequest(body: Uint8Array): Record<string, unknown> {\n return decodeRequest('opentelemetry.proto.trace.v1.ExportTraceServiceRequest', body)\n}\n\n/** Decode an OTLP/protobuf `ExportLogsServiceRequest` into the OTLP/JSON object shape. */\nexport function decodeOtlpLogsRequest(body: Uint8Array): Record<string, unknown> {\n return decodeRequest('opentelemetry.proto.logs.v1.ExportLogsServiceRequest', body)\n}\n\n/** Decode an OTLP/protobuf `ExportMetricsServiceRequest` into the OTLP/JSON object shape. */\nexport function decodeOtlpMetricsRequest(body: Uint8Array): Record<string, unknown> {\n return decodeRequest('opentelemetry.proto.metrics.v1.ExportMetricsServiceRequest', body)\n}\n","// src/server/identity.ts\n//\n// A first-class way to answer \"is the thing on this port actually\n// autotel-devtools?\". Clients and integrators used to have to sniff the shape\n// of GET /healthz (e.g. \"does the JSON have `ok` and `clients`?\"). That is\n// brittle. We now stamp every HTTP response with an `x-autotel-devtools`\n// header and put `service: \"autotel-devtools\"` in the /healthz body, so the\n// answer is unambiguous — and we use that here to tell our own instances apart\n// from a foreign OTLP collector squatting on the same port.\n\n/** Value of the `x-autotel-devtools` response header and the /healthz `service` field. */\nexport const DEVTOOLS_IDENTITY = 'autotel-devtools'\n\n/** Who is holding a TCP port, as far as we can tell over HTTP:\n * - `autotel-devtools` — another instance of us (benign; the user has two running)\n * - `foreign` — an HTTP server that is NOT us (e.g. an IDE's OTLP collector)\n * - `none` — nothing answered HTTP (refused, timed out, or non-HTTP listener) */\nexport type PortHolder = 'autotel-devtools' | 'foreign' | 'none'\n\n/**\n * Probe `host:port` over HTTP and classify what is listening. Used when our\n * requested port is busy: it lets us tell \"a stale autotel-devtools is still\n * up\" (benign) apart from \"a foreign collector owns this port\" — the latter is\n * the silent footgun where apps keep exporting OTLP to the busy port and reach\n * the wrong process, so the devtools UI stays empty and the app sees errors.\n */\nexport async function probePortHolder(\n host: string,\n port: number,\n timeoutMs = 500,\n): Promise<PortHolder> {\n // Bracket IPv6 literals for the URL authority (e.g. [::1]:4318).\n const authority = host.includes(':') ? `[${host}]` : host\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const res = await fetch(`http://${authority}:${port}/healthz`, {\n signal: controller.signal,\n })\n // The header is the fast, body-independent signal (present on every route).\n if (res.headers.get('x-autotel-devtools')) return 'autotel-devtools'\n // Fall back to the body in case a proxy stripped the header.\n try {\n const body = (await res.json()) as { service?: unknown }\n if (body && body.service === DEVTOOLS_IDENTITY) return 'autotel-devtools'\n } catch {\n // Not JSON — that's fine, it just isn't us.\n }\n return 'foreign'\n } catch {\n // Connection refused / timeout / non-HTTP listener. When the caller only\n // probes after a confirmed EADDRINUSE, `none` means \"occupied by something\n // that doesn't speak HTTP\" — still not us.\n return 'none'\n } finally {\n clearTimeout(timer)\n }\n}\n","// src/server/http.ts\nimport { createServer, type IncomingMessage, type ServerResponse, type Server } from 'node:http'\nimport { readFileSync, existsSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { parseOtlpTraces, parseOtlpLogs, countOtlpMetrics, readJsonBody, readRawBody, isProtobufContentType, sendJson } from './otlp'\nimport { decodeOtlpTraceRequest, decodeOtlpLogsRequest, decodeOtlpMetricsRequest } from './otlp-proto'\nimport { DEVTOOLS_IDENTITY } from './identity'\nimport { allowSensitiveRequest } from './origin-guard'\nimport type { DevtoolsServer } from './server'\n\ntype OtlpSignal = 'traces' | 'logs' | 'metrics'\n\n// Reply to a failed OTLP ingest. Echoing the content-type we received turns the\n// otherwise opaque \"Invalid OTLP payload\" into something a misconfigured\n// exporter can act on (e.g. it shows up as `null` when no header was sent, or\n// as a protobuf type the sender didn't expect to be using).\nfunction sendOtlpError(res: ServerResponse, req: IncomingMessage, e: unknown): void {\n sendJson(res, 400, {\n error: 'Invalid OTLP payload',\n message: e instanceof Error ? e.message : String(e),\n contentType: req.headers['content-type'] ?? null,\n })\n}\n\nconst PROTOBUF_DECODERS: Record<OtlpSignal, (body: Buffer) => Record<string, unknown>> = {\n traces: decodeOtlpTraceRequest,\n logs: decodeOtlpLogsRequest,\n metrics: decodeOtlpMetricsRequest,\n}\n\n// Read an OTLP request body as a plain object, transparently decoding both\n// OTLP/JSON (`application/json`) and OTLP/protobuf (`application/x-protobuf`).\n// Both shapes feed the same parsers, so callers don't care which the client sent.\nasync function readOtlpPayload(req: IncomingMessage, signal: OtlpSignal): Promise<unknown> {\n if (isProtobufContentType(req.headers['content-type'])) {\n return PROTOBUF_DECODERS[signal](await readRawBody(req))\n }\n return readJsonBody(req)\n}\n\nexport interface HttpServerOptions {\n port?: number\n host?: string\n}\n\nfunction findPackageRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 5; i++) {\n if (existsSync(resolve(dir, 'package.json'))) return dir\n dir = dirname(dir)\n }\n return dir\n}\n\nconst DEVTOOLS_FAVICON_SVG =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\"><rect width=\"64\" height=\"64\" rx=\"14\" fill=\"#0f172a\"/><text x=\"32\" y=\"41\" text-anchor=\"middle\" font-size=\"32\">🛰️</text></svg>'\n\nconst FULLPAGE_HTML = `<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>autotel-devtools</title><link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\"><style>*{margin:0;padding:0;box-sizing:border-box}html,body{height:100%;width:100%;overflow:hidden}</style></head><body><script src=\"/widget.js?mode=fullpage\"></script></body></html>`\n\nlet cachedVersion: string | null = null\nfunction getVersion(): string {\n if (cachedVersion !== null) return cachedVersion\n let version = 'unknown'\n try {\n const pkg = JSON.parse(readFileSync(resolve(findPackageRoot(), 'package.json'), 'utf8'))\n if (typeof pkg.version === 'string') version = pkg.version\n } catch {\n /* keep 'unknown' */\n }\n cachedVersion = version\n return version\n}\n\nlet cachedWidgetJs: string | null = null\nfunction getWidgetJs(): string {\n if (!cachedWidgetJs) {\n const pkgRoot = findPackageRoot()\n const candidates = [\n resolve(pkgRoot, 'dist', 'widget.global.js'),\n resolve(pkgRoot, 'widget.global.js'),\n ]\n for (const candidate of candidates) {\n try {\n cachedWidgetJs = readFileSync(candidate, 'utf8')\n break\n } catch { /* try next */ }\n }\n if (!cachedWidgetJs) {\n cachedWidgetJs = '// widget bundle not found - run pnpm build first'\n }\n }\n return cachedWidgetJs\n}\n\nexport interface DevtoolsRoutesOptions {\n /** Bound to a loopback host (the default). Enables the DNS-rebinding `Host`\n * check on read endpoints; an explicit non-loopback bind opts out. */\n loopbackOnly?: boolean\n}\n\nexport function attachDevtoolsRoutes(\n httpServer: Server,\n devtools: DevtoolsServer,\n options: DevtoolsRoutesOptions = {},\n): void {\n const loopbackOnly = options.loopbackOnly ?? true\n httpServer.on('request', async (req: IncomingMessage, res: ServerResponse) => {\n // WebSocket upgrade requests are handled by the 'upgrade' event (via the\n // ws library's WebSocketServer). Responding here would close the connection\n // before the upgrade can complete.\n if (req.headers.upgrade?.toLowerCase() === 'websocket') return\n\n // CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n\n // Identity stamp on every response: lets a client confirm it is really\n // talking to autotel-devtools (and not, say, an IDE's OTLP collector that\n // happens to share the port) without guessing from the body shape.\n res.setHeader('x-autotel-devtools', getVersion())\n res.setHeader('Access-Control-Expose-Headers', 'x-autotel-devtools')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n const url = req.url || '/'\n\n // GET / — fullpage HTML\n if (req.method === 'GET' && url === '/') {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': Buffer.byteLength(FULLPAGE_HTML) })\n res.end(FULLPAGE_HTML)\n return\n }\n\n // GET /widget.js — widget bundle\n if (req.method === 'GET' && url.startsWith('/widget.js')) {\n const js = getWidgetJs()\n res.writeHead(200, { 'Content-Type': 'application/javascript; charset=utf-8', 'Content-Length': Buffer.byteLength(js) })\n res.end(js)\n return\n }\n\n if (req.method === 'GET' && (url === '/favicon.svg' || url === '/favicon.ico')) {\n res.writeHead(200, {\n 'Content-Type': 'image/svg+xml; charset=utf-8',\n 'Cache-Control': 'public, max-age=86400',\n 'Content-Length': Buffer.byteLength(DEVTOOLS_FAVICON_SVG),\n })\n res.end(DEVTOOLS_FAVICON_SVG)\n return\n }\n\n // GET /healthz — also the canonical identity probe: `service` + `version`\n // let a caller positively confirm this is autotel-devtools.\n if (req.method === 'GET' && url === '/healthz') {\n sendJson(res, 200, {\n ok: true,\n service: DEVTOOLS_IDENTITY,\n version: getVersion(),\n clients: devtools.clientCount,\n })\n return\n }\n\n // GET /v1/traces — read back what the collector has actually received.\n // This is the verification primitive for tests: poll the collector over\n // HTTP and assert receipt, instead of only asserting \"the client tried to\n // send\" (which a browser-level route intercept can fake). Bypasses the UI's\n // WebSocket entirely.\n if (req.method === 'GET' && url === '/v1/traces') {\n if (!allowSensitiveRequest(req.headers, loopbackOnly)) {\n sendJson(res, 403, { error: 'Forbidden' })\n return\n }\n const data = devtools.getCurrentData()\n sendJson(res, 200, { traces: data.traces, count: data.traces.length })\n return\n }\n\n // DELETE /v1/traces — clear captured telemetry (test isolation / reset).\n // Clears traces, logs, metrics and aggregated errors so each test starts clean.\n if (req.method === 'DELETE' && url === '/v1/traces') {\n if (!allowSensitiveRequest(req.headers, loopbackOnly)) {\n sendJson(res, 403, { error: 'Forbidden' })\n return\n }\n devtools.clearData()\n sendJson(res, 200, { cleared: true })\n return\n }\n\n // POST /v1/traces — accepts OTLP/JSON or OTLP/protobuf\n if (req.method === 'POST' && url === '/v1/traces') {\n try {\n const payload = await readOtlpPayload(req, 'traces')\n const traces = parseOtlpTraces(payload)\n devtools.addTraces(traces)\n sendJson(res, 200, { acceptedTraces: traces.length })\n } catch (e) {\n sendOtlpError(res, req, e)\n }\n return\n }\n\n // POST /v1/logs — accepts OTLP/JSON or OTLP/protobuf\n if (req.method === 'POST' && url === '/v1/logs') {\n try {\n const payload = await readOtlpPayload(req, 'logs')\n const logs = parseOtlpLogs(payload)\n devtools.addLogs(logs)\n sendJson(res, 200, { acceptedLogs: logs.length })\n } catch (e) {\n sendOtlpError(res, req, e)\n }\n return\n }\n\n // POST /v1/metrics — accepts OTLP/JSON or OTLP/protobuf\n if (req.method === 'POST' && url === '/v1/metrics') {\n try {\n const payload = await readOtlpPayload(req, 'metrics')\n const count = countOtlpMetrics(payload)\n sendJson(res, 200, { acceptedMetrics: count })\n } catch (e) {\n sendOtlpError(res, req, e)\n }\n return\n }\n\n sendJson(res, 404, { error: 'Not found' })\n })\n}\n\nexport function createDevtoolsHttpServer(devtools: DevtoolsServer, _options: HttpServerOptions = {}): Server {\n const server = createServer()\n attachDevtoolsRoutes(server, devtools)\n return server\n}\n","// src/server/listen.ts\nimport { createServer, type Server } from 'node:http'\n\nconst LOOPBACK = new Set(['localhost', '127.0.0.1', '::1'])\n\n/** How many consecutive ports to try before giving up. The default sweeps\n * 4318..4337 — a tight enough window that we don't accidentally squat on\n * something a sibling tool is using, but wide enough that the common case\n * (\"a previous devtools is still running\") succeeds. */\nconst DEFAULT_MAX_PORT_TRIES = 20\n\nexport interface LoopbackListeners {\n /** Resolves once the primary and (attempted) sibling listeners are up.\n * `port` is the port the primary actually bound to — it may differ from\n * the requested port when fallback was needed. */\n ready: Promise<{ addresses: string[]; port: number; warnings: string[] }>\n /** Close the sibling listener (the primary server is owned by the caller). */\n closeSibling: () => Promise<void>\n}\n\n/** Format host:port, bracketing IPv6 literals (e.g. `[::1]:4318`). */\nexport function formatAddress(host: string, port: number): string {\n return host.includes(':') ? `[${host}]:${port}` : `${host}:${port}`\n}\n\n/**\n * Listen on `host:port`, and when `host` is a loopback literal, ALSO listen on\n * the sibling loopback family (IPv4 ⟷ IPv6) so a client reaches the collector\n * whether the OS resolves `localhost` to `127.0.0.1` or `::1`.\n *\n * This kills a notoriously silent footgun: a dev-server proxy targeting\n * `http://localhost:PORT` on macOS resolves `localhost` to `::1`, but a\n * collector bound only to `127.0.0.1` never receives the request — spans\n * vanish with no error. Binding both loopback families makes `localhost` work\n * regardless of resolution order.\n *\n * If `port` is busy (EADDRINUSE), the listener walks forward up to `maxTries`\n * consecutive ports and binds the first one that's free. The resolved port\n * is returned in `ready` so callers can print correct URLs and OTLP\n * endpoints. Each fallback produces a warning.\n *\n * The sibling listener serves the same HTTP routes (via `attachSecondary`);\n * the WebSocket/UI stays on the primary address. If the sibling cannot bind\n * (e.g. no IPv6, or the port is taken on that family), it is reported as a\n * warning rather than a fatal error.\n */\nexport function listenLoopbackDualStack(args: {\n primary: Server\n port: number\n host: string\n attachSecondary: (server: Server) => void\n maxTries?: number\n}): LoopbackListeners {\n const { primary, port, host, attachSecondary, maxTries } = args\n const maxAttempts = Math.max(1, maxTries ?? DEFAULT_MAX_PORT_TRIES)\n let sibling: Server | undefined\n\n const ready = new Promise<{ addresses: string[]; port: number; warnings: string[] }>(\n (resolve, reject) => {\n const addresses: string[] = []\n const warnings: string[] = []\n // Normalise `localhost` to an explicit family so the primary bind is\n // deterministic and we know which sibling family to add.\n const primaryHost = host === 'localhost' ? '127.0.0.1' : host\n\n // The port currently being attempted, and how many we've burned so far.\n // One persistent handler pair owns the whole forward-walk; we just bump\n // `candidate` and re-`listen()` on the same server (the caller owns it\n // and has the WSS/routes attached, so we can't swap in a fresh one).\n let candidate = port\n let attempt = 0\n\n const bindFailed = (atPort: number, msg: string) =>\n reject(\n new Error(`could not bind ${formatAddress(primaryHost, atPort)}: ${msg}`),\n )\n\n // Walk forward from `port` until we find a free port. Anything that\n // isn't EADDRINUSE (EACCES, EAFNOSUPPORT, …) is fatal — it won't fix\n // itself on the next port.\n const onError = (e: NodeJS.ErrnoException) => {\n if (e.code !== 'EADDRINUSE') return bindFailed(candidate, e.message)\n if (++attempt >= maxAttempts) {\n reject(\n new Error(\n `could not bind ${formatAddress(primaryHost, port)}: ${maxAttempts} consecutive ports in use`,\n ),\n )\n return\n }\n candidate++\n listen()\n }\n\n const onListening = () => {\n // Bind succeeded — stop owning the primary's `error` event so a later\n // runtime error doesn't get mistaken for a bind failure.\n primary.removeListener('error', onError)\n if (candidate !== port) {\n warnings.push(`port ${port} was busy; using ${candidate} instead`)\n }\n const addr = primary.address()\n const resolvedPort =\n addr && typeof addr === 'object' ? addr.port : candidate\n addresses.push(formatAddress(primaryHost, resolvedPort))\n\n if (!LOOPBACK.has(host)) {\n resolve({ addresses, port: resolvedPort, warnings })\n return\n }\n\n const siblingHost = primaryHost === '::1' ? '127.0.0.1' : '::1'\n const s = createServer()\n attachSecondary(s)\n\n const onSiblingError = (se: Error) => {\n s.close()\n warnings.push(\n `could not also bind ${formatAddress(siblingHost, resolvedPort)} (${se.message}); ` +\n `clients using the ${siblingHost === '::1' ? 'IPv6' : 'IPv4'} form of \"localhost\" may not connect.`,\n )\n resolve({ addresses, port: resolvedPort, warnings })\n }\n s.once('error', onSiblingError)\n s.listen(resolvedPort, siblingHost, () => {\n s.off('error', onSiblingError)\n sibling = s\n addresses.push(formatAddress(siblingHost, resolvedPort))\n resolve({ addresses, port: resolvedPort, warnings })\n })\n }\n\n const listen = () => {\n try {\n primary.listen(candidate, primaryHost)\n } catch (e) {\n // `candidate` can overflow 65535 when the top port is busy; Node\n // throws a RangeError synchronously instead of emitting 'error'.\n primary.removeListener('error', onError)\n primary.removeListener('listening', onListening)\n bindFailed(candidate, (e as Error).message)\n }\n }\n\n primary.on('error', onError)\n primary.once('listening', onListening)\n listen()\n },\n )\n\n return {\n ready,\n closeSibling: () =>\n new Promise<void>((res) => {\n if (!sibling) return res()\n sibling.close(() => res())\n }),\n }\n}\n","#!/usr/bin/env node\n// src/cli.ts\nimport { createServer } from 'node:http'\nimport { readFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { DevtoolsServer } from './server/server'\nimport { attachDevtoolsRoutes } from './server/http'\nimport { hostHeaderIsLoopback } from './server/origin-guard'\nimport { listenLoopbackDualStack } from './server/listen'\nimport { probePortHolder } from './server/identity'\n\ninterface CliOptions {\n port: number\n host: string\n title?: string\n}\n\nfunction printHelp(): void {\n process.stdout.write(\n `autotel-devtools - Standalone OTLP receiver with web devtools UI\n\nUsage: autotel-devtools [port] [options]\n\nArguments:\n port Port to listen on (shorthand for --port; must be a positive integer)\n\nOptions:\n -p, --port <port> Port to listen on (default: 4318, env: AUTOTEL_DEVTOOLS_PORT).\n If the port is taken, the next free port is used and a warning is shown.\n -H, --host <host> Host to bind to (default: 127.0.0.1, env: AUTOTEL_DEVTOOLS_HOST)\n -t, --title <title> Dashboard title (env: AUTOTEL_DEVTOOLS_TITLE)\n Env limits: AUTOTEL_MAX_TRACE_COUNT, AUTOTEL_MAX_LOG_COUNT, AUTOTEL_MAX_METRIC_COUNT\n -h, --help Show this help message\n -v, --version Show version number\n\nEndpoints:\n GET / Web devtools UI (fullpage)\n GET /widget.js Widget bundle (embed in your app)\n POST /v1/traces Receive OTLP JSON trace data\n GET /v1/traces Read back received traces (verify ingestion in tests)\n DELETE /v1/traces Clear captured telemetry (test reset)\n POST /v1/logs Receive OTLP JSON log data\n POST /v1/metrics Receive OTLP JSON metric data\n WS /ws WebSocket stream for real-time updates\n GET /healthz Health check\n\nExamples:\n npx autotel-devtools\n npx autotel-devtools 4319\n npx autotel-devtools -p 4319 -H 0.0.0.0\n\nThen point your app:\n OTEL_EXPORTER_OTLP_PROTOCOL=http/json OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 node app.js\n\nView in browser:\n http://localhost:4318\n\nOr embed widget in your app:\n <script src=\"http://localhost:4318/widget.js\"></script>\n` + '\\n',\n )\n}\n\nfunction printVersion(): void {\n try {\n const dir = dirname(fileURLToPath(import.meta.url))\n const pkgPath = resolve(dir, '..', 'package.json')\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))\n process.stdout.write(`${pkg.version}\\n`)\n } catch {\n process.stdout.write('unknown\\n')\n }\n}\n\nfunction parseArgs(argv: string[]): CliOptions | null {\n const options: CliOptions = {\n port: parsePort(process.env.AUTOTEL_DEVTOOLS_PORT || '4318'),\n host: process.env.AUTOTEL_DEVTOOLS_HOST || '127.0.0.1',\n title: process.env.AUTOTEL_DEVTOOLS_TITLE,\n }\n\n // An explicit `--port`/`-p` always wins, regardless of where it sits in\n // argv. A bare numeric positional is shorthand for `--port`, but only when\n // no explicit flag was given — and only the first positional counts, so a\n // stray \"4318\" can't override an earlier positional either.\n let portWasExplicit = false\n let positionalPortConsumed = false\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]\n const next = argv[i + 1]\n if (arg === '--help' || arg === '-h') { printHelp(); return null }\n if (arg === '--version' || arg === '-v') { printVersion(); return null }\n if ((arg === '--port' || arg === '-p') && next) { options.port = parsePort(next); portWasExplicit = true; i++; continue }\n if ((arg === '--host' || arg === '-H') && next) { options.host = next; i++; continue }\n if ((arg === '--title' || arg === '-t') && next) { options.title = next; i++; continue }\n if (/^\\d+$/.test(arg) && !positionalPortConsumed) {\n if (!portWasExplicit) options.port = parsePort(arg)\n positionalPortConsumed = true\n continue\n }\n }\n\n return options\n}\n\nfunction parsePort(value: string): number {\n const n = Number(value)\n if (!Number.isInteger(n) || n < 0 || n > 65535) {\n process.stderr.write(`[autotel-devtools] invalid port: ${value}\\n`)\n process.exit(2)\n }\n return n\n}\n\nasync function main(): Promise<void> {\n const options = parseArgs(process.argv.slice(2))\n if (!options) { process.exit(0) }\n\n const httpServer = createServer()\n const loopbackOnly = hostHeaderIsLoopback(options.host)\n const wsServer = new DevtoolsServer({ server: httpServer, host: options.host, verbose: true })\n attachDevtoolsRoutes(httpServer, wsServer, { loopbackOnly })\n\n const listeners = listenLoopbackDualStack({\n primary: httpServer,\n port: options.port,\n host: options.host,\n attachSecondary: (s) => attachDevtoolsRoutes(s, wsServer, { loopbackOnly }),\n })\n\n const { addresses, warnings, port: boundPort } = await listeners.ready\n\n // Falling forward to a different port means the one we wanted is held by\n // someone else. Classify them: another autotel-devtools (benign) versus a\n // foreign process. The foreign case is the silent footgun — apps keep\n // exporting OTLP to the requested port and reach that process, not us, so\n // this UI stays empty while they see export errors. Say so, with the fix.\n if (boundPort !== options.port) {\n const holder = await probePortHolder(options.host, options.port)\n if (holder === 'autotel-devtools') {\n warnings.push(\n `another autotel-devtools is already running on port ${options.port}; ` +\n `this instance is on ${boundPort}. Use the existing one, or stop it and restart here.`,\n )\n } else {\n warnings.push(\n `port ${options.port} is held by another process that is NOT autotel-devtools. ` +\n `Anything exporting OTLP to :${options.port} is reaching that process, not this devtools. ` +\n `Point your exporter at :${boundPort}, or free :${options.port} and restart.`,\n )\n }\n }\n\n const uiBase = `http://${options.host === 'localhost' ? '127.0.0.1' : options.host}:${boundPort}`\n const title = options.title || 'autotel-devtools'\n process.stdout.write(`\\n ${title}\\n\\n`)\n process.stdout.write(` Listening: ${addresses.join(' + ')}\\n`)\n process.stdout.write(` UI: ${uiBase} (open in a browser)\\n`)\n process.stdout.write(` OTLP: ${uiBase}/v1/traces\\n`)\n process.stdout.write(` WebSocket: ${uiBase.replace('http', 'ws')}/ws\\n\\n`)\n // The widget bundle auto-mounts on load, so the bare <script> tag is all the\n // user needs — spell that out, plus the two opt-in variations, so nobody\n // wonders whether they also have to add an element by hand.\n process.stdout.write(\n ` Embed in your app — paste into your HTML; a floating panel appears automatically:\\n`,\n )\n process.stdout.write(` <script src=\"${uiBase}/widget.js\"></script>\\n\\n`)\n process.stdout.write(\n ` full screen instead: <script src=\"${uiBase}/widget.js?mode=fullpage\"></script>\\n`,\n )\n process.stdout.write(\n ` choose where it goes: add <autotel-devtools></autotel-devtools> to your markup\\n\\n`,\n )\n process.stdout.write(` Or point any OTLP exporter at this receiver:\\n`)\n process.stdout.write(` OTEL_EXPORTER_OTLP_PROTOCOL=http/json\\n`)\n process.stdout.write(` OTEL_EXPORTER_OTLP_ENDPOINT=${uiBase}\\n\\n`)\n // Self-check: confirm the collector is reachable AND that ingestion works,\n // not just that something is listening. Reading /v1/traces back is the same\n // check a test should make instead of trusting \"the client tried to send\".\n process.stdout.write(` Verify ingestion: curl -s ${uiBase}/v1/traces\\n\\n`)\n for (const w of warnings) {\n process.stdout.write(` ⚠ ${w}\\n`)\n }\n if (warnings.length > 0) process.stdout.write('\\n')\n\n const shutdown = () => {\n Promise.all([wsServer.close(), listeners.closeSibling()]).then(() =>\n process.exit(0),\n )\n }\n process.on('SIGINT', shutdown)\n process.on('SIGTERM', shutdown)\n}\n\nmain().catch((error) => {\n process.stderr.write(`[autotel-devtools] failed to start: ${error instanceof Error ? error.message : String(error)}\\n`)\n process.exit(1)\n})\n"]}