{"version":3,"file":"cli.cjs","names":["#subscribers","path","getTerminalLogStream"],"sources":["../src/listen.ts","../src/cli-stream.ts","../src/otlp-http-json.ts","../src/cli.ts"],"sourcesContent":["import { createServer, type Server } from 'node:http';\n\nconst LOOPBACK = new Set(['localhost', '127.0.0.1', '::1']);\n\nexport interface LoopbackListeners {\n  /** Resolves once the primary and (attempted) sibling listeners are up. */\n  ready: Promise<{ addresses: string[]; 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]:4319`). */\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 * Kills a silent footgun: a dev-server proxy targeting `http://localhost:PORT`\n * on macOS resolves `localhost` to `::1`, but a collector bound only to\n * `127.0.0.1` never receives the request — spans vanish with no error. If the\n * sibling family cannot bind, it is surfaced as a warning, never fatal.\n */\nexport function listenLoopbackDualStack(args: {\n  primary: Server;\n  port: number;\n  host: string;\n  attachSecondary: (server: Server) => void;\n}): LoopbackListeners {\n  const { primary, port, host, attachSecondary } = args;\n  let sibling: Server | undefined;\n\n  const ready = new Promise<{ addresses: string[]; warnings: string[] }>(\n    (resolve) => {\n      const addresses: string[] = [];\n      const warnings: string[] = [];\n      const primaryHost = host === 'localhost' ? '127.0.0.1' : host;\n\n      primary.listen(port, primaryHost, () => {\n        const addr = primary.address();\n        const resolvedPort =\n          addr && typeof addr === 'object' ? addr.port : port;\n        addresses.push(formatAddress(primaryHost, resolvedPort));\n\n        if (!LOOPBACK.has(host)) {\n          resolve({ addresses, 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 onError = (e: Error) => {\n          s.close();\n          warnings.push(\n            `could not also bind ${formatAddress(siblingHost, resolvedPort)} (${e.message}); ` +\n              `clients using the ${siblingHost === '::1' ? 'IPv6' : 'IPv4'} form of \"localhost\" may not connect.`,\n          );\n          resolve({ addresses, warnings });\n        };\n        s.once('error', onError);\n        s.listen(resolvedPort, siblingHost, () => {\n          s.off('error', onError);\n          sibling = s;\n          addresses.push(formatAddress(siblingHost, resolvedPort));\n          resolve({ addresses, warnings });\n        });\n      });\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","import type { TerminalSpanEvent, TerminalSpanStream } from './span-stream';\n\ntype Subscriber = (event: TerminalSpanEvent) => void;\n\n/**\n * In-memory stream implementation for standalone CLI ingestion.\n */\nexport class CliTerminalSpanStream implements TerminalSpanStream {\n  #subscribers = new Set<Subscriber>();\n\n  onSpanEnd(callback: Subscriber): () => void {\n    this.#subscribers.add(callback);\n    return () => {\n      this.#subscribers.delete(callback);\n    };\n  }\n\n  push(event: TerminalSpanEvent): void {\n    for (const subscriber of this.#subscribers) {\n      subscriber(event);\n    }\n  }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { TerminalSpanEvent, SpanEvent, SpanLink } from './span-stream';\nimport type { TerminalLogEvent, LogLevel } from './lib/log-model';\n\nconst MAX_BODY_BYTES = 10 * 1024 * 1024; // 10 MB\n\ntype OtlpAnyValue = {\n  stringValue?: string;\n  boolValue?: boolean;\n  intValue?: string | number;\n  doubleValue?: number;\n  bytesValue?: string;\n};\n\ntype OtlpKeyValue = {\n  key: string;\n  value?: OtlpAnyValue;\n};\n\ntype OtlpSpan = {\n  traceId?: string;\n  spanId?: string;\n  parentSpanId?: string;\n  name?: string;\n  kind?: number | string;\n  startTimeUnixNano?: string;\n  endTimeUnixNano?: string;\n  attributes?: OtlpKeyValue[];\n  status?: {\n    code?: number | string;\n  };\n  events?: {\n    timeUnixNano?: string;\n    name?: string;\n    attributes?: OtlpKeyValue[];\n  }[];\n  links?: {\n    traceId?: string;\n    spanId?: string;\n    attributes?: OtlpKeyValue[];\n  }[];\n};\n\nfunction anyValueToPrimitive(value: OtlpAnyValue | undefined): unknown {\n  if (!value) return undefined;\n  if (value.stringValue !== undefined) return value.stringValue;\n  if (value.boolValue !== undefined) return value.boolValue;\n  if (value.intValue !== undefined) {\n    const num = Number(value.intValue);\n    return Number.isNaN(num) ? value.intValue : num;\n  }\n  if (value.doubleValue !== undefined) return value.doubleValue;\n  if (value.bytesValue !== undefined) return value.bytesValue;\n  return undefined;\n}\n\nfunction attrsToRecord(\n  attributes: OtlpKeyValue[] | undefined,\n): Record<string, unknown> {\n  if (!attributes || attributes.length === 0) return {};\n  const out: Record<string, unknown> = {};\n  for (const attribute of attributes) {\n    out[attribute.key] = anyValueToPrimitive(attribute.value);\n  }\n  return out;\n}\n\nfunction normalizeHexId(\n  id: string | undefined,\n  expectedHexLength: number,\n): string {\n  if (!id) return ''.padStart(expectedHexLength, '0');\n  const trimmed = id.trim();\n  if (/^[a-fA-F0-9]+$/.test(trimmed)) {\n    return trimmed\n      .toLowerCase()\n      .padStart(expectedHexLength, '0')\n      .slice(-expectedHexLength);\n  }\n  try {\n    const decoded = Buffer.from(trimmed, 'base64').toString('hex');\n    if (decoded.length > 0) {\n      return decoded\n        .toLowerCase()\n        .padStart(expectedHexLength, '0')\n        .slice(-expectedHexLength);\n    }\n  } catch {\n    // ignore and fall through\n  }\n  return ''.padStart(expectedHexLength, '0');\n}\n\nfunction toMs(unixNano: string | undefined): number {\n  if (!unixNano) return Date.now();\n  const parsed = Number(unixNano);\n  if (Number.isNaN(parsed)) return Date.now();\n  return parsed / 1_000_000;\n}\n\nfunction mapStatus(\n  code: number | string | undefined,\n): 'OK' | 'ERROR' | 'UNSET' {\n  const normalized = typeof code === 'string' ? code.toUpperCase() : code;\n  if (\n    normalized === 1 ||\n    normalized === 'STATUS_CODE_OK' ||\n    normalized === 'OK'\n  )\n    return 'OK';\n  if (\n    normalized === 2 ||\n    normalized === 'STATUS_CODE_ERROR' ||\n    normalized === 'ERROR'\n  ) {\n    return 'ERROR';\n  }\n  return 'UNSET';\n}\n\nfunction mapKind(kind: number | string | undefined): string {\n  if (typeof kind === 'string') return kind.toUpperCase();\n  switch (kind) {\n    case 1: {\n      return 'INTERNAL';\n    }\n    case 2: {\n      return 'SERVER';\n    }\n    case 3: {\n      return 'CLIENT';\n    }\n    case 4: {\n      return 'PRODUCER';\n    }\n    case 5: {\n      return 'CONSUMER';\n    }\n    default: {\n      return 'INTERNAL';\n    }\n  }\n}\n\nfunction* extractSpans(\n  payload: unknown,\n): Generator<{ span: OtlpSpan; resourceAttrs: Record<string, unknown> }> {\n  if (!payload || typeof payload !== 'object') return;\n  const resourceSpans = (payload as { resourceSpans?: unknown[] })\n    .resourceSpans;\n  if (!Array.isArray(resourceSpans)) return;\n  for (const resourceSpan of resourceSpans) {\n    if (!resourceSpan || typeof resourceSpan !== 'object') continue;\n    const resource = (resourceSpan as { resource?: { attributes?: OtlpKeyValue[] } }).resource;\n    const resourceAttrs = attrsToRecord(resource?.attributes);\n    const scopeSpans = (resourceSpan as { scopeSpans?: unknown[] }).scopeSpans;\n    if (!Array.isArray(scopeSpans)) continue;\n    for (const scopeSpan of scopeSpans) {\n      if (!scopeSpan || typeof scopeSpan !== 'object') continue;\n      const spans = (scopeSpan as { spans?: unknown[] }).spans;\n      if (!Array.isArray(spans)) continue;\n      for (const span of spans) {\n        if (span && typeof span === 'object') {\n          yield { span: span as OtlpSpan, resourceAttrs };\n        }\n      }\n    }\n  }\n}\n\nexport function otlpSpanToTerminalEvent(\n  span: OtlpSpan,\n  resourceAttrs: Record<string, unknown> = {},\n): TerminalSpanEvent {\n  const startTime = toMs(span.startTimeUnixNano);\n  const endTime = toMs(span.endTimeUnixNano);\n  const spanAttrs = attrsToRecord(span.attributes);\n  // Merge resource attributes (e.g. service.name) under span attributes,\n  // with span-level attributes taking precedence\n  const mergedAttrs: Record<string, unknown> = {};\n  for (const [k, v] of Object.entries(resourceAttrs)) {\n    mergedAttrs[k] = v;\n  }\n  for (const [k, v] of Object.entries(spanAttrs)) {\n    mergedAttrs[k] = v;\n  }\n  const parsedEvents: SpanEvent[] | undefined = span.events?.length\n    ? span.events.map((e) => ({\n        name: e.name || '',\n        timeMs: toMs(e.timeUnixNano),\n        attributes: attrsToRecord(e.attributes),\n      }))\n    : undefined;\n\n  const parsedLinks: SpanLink[] | undefined = span.links?.length\n    ? span.links.map((l) => ({\n        traceId: normalizeHexId(l.traceId, 32),\n        spanId: normalizeHexId(l.spanId, 16),\n        attributes: attrsToRecord(l.attributes),\n      }))\n    : undefined;\n\n  return {\n    name: span.name || 'unnamed',\n    spanId: normalizeHexId(span.spanId, 16),\n    traceId: normalizeHexId(span.traceId, 32),\n    parentSpanId: span.parentSpanId\n      ? normalizeHexId(span.parentSpanId, 16)\n      : undefined,\n    startTime,\n    endTime,\n    durationMs: Math.max(0, endTime - startTime),\n    status: mapStatus(span.status?.code),\n    kind: mapKind(span.kind),\n    attributes: mergedAttrs,\n    ...(parsedEvents ? { events: parsedEvents } : {}),\n    ...(parsedLinks ? { links: parsedLinks } : {}),\n  };\n}\n\nexport async function readJsonBody(req: IncomingMessage): Promise<unknown> {\n  const chunks: Buffer[] = [];\n  let totalLength = 0;\n  for await (const chunk of req) {\n    const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n    totalLength += buf.length;\n    if (totalLength > MAX_BODY_BYTES) {\n      throw new Error(`Body exceeds ${MAX_BODY_BYTES} byte limit`);\n    }\n    chunks.push(buf);\n  }\n  const raw = Buffer.concat(chunks).toString('utf8');\n  if (!raw) return {};\n  return JSON.parse(raw);\n}\n\nexport function sendJson(\n  res: ServerResponse,\n  status: number,\n  data: Record<string, unknown>,\n): void {\n  res.statusCode = status;\n  res.setHeader('content-type', 'application/json');\n  res.end(JSON.stringify(data));\n}\n\nexport function parseOtlpEvents(payload: unknown): TerminalSpanEvent[] {\n  const events: TerminalSpanEvent[] = [];\n  for (const { span, resourceAttrs } of extractSpans(payload)) {\n    events.push(otlpSpanToTerminalEvent(span, resourceAttrs));\n  }\n  return events;\n}\n\n// --- OTLP Log parsing ---\n\ntype OtlpLogRecord = {\n  timeUnixNano?: string;\n  observedTimeUnixNano?: string;\n  severityNumber?: number;\n  severityText?: string;\n  body?: OtlpAnyValue;\n  attributes?: OtlpKeyValue[];\n  traceId?: string;\n  spanId?: string;\n};\n\nfunction mapSeverityToLevel(\n  severityNumber?: number,\n  severityText?: string,\n): LogLevel {\n  if (severityText) {\n    const lower = severityText.toLowerCase();\n    if (lower.startsWith('debug') || lower === 'trace') return 'debug';\n    if (lower.startsWith('info')) return 'info';\n    if (lower.startsWith('warn')) return 'warn';\n    if (lower.startsWith('error') || lower.startsWith('fatal')) return 'error';\n  }\n  if (severityNumber !== undefined) {\n    if (severityNumber <= 4) return 'debug';\n    if (severityNumber <= 8) return 'debug';\n    if (severityNumber <= 12) return 'info';\n    if (severityNumber <= 16) return 'warn';\n    return 'error';\n  }\n  return 'info';\n}\n\nfunction bodyToMessage(body: OtlpAnyValue | undefined): string {\n  if (!body) return '';\n  const value = anyValueToPrimitive(body);\n  return value === undefined ? '' : String(value);\n}\n\nfunction* extractLogRecords(payload: unknown): Generator<OtlpLogRecord> {\n  if (!payload || typeof payload !== 'object') return;\n  const resourceLogs = (payload as { resourceLogs?: unknown[] }).resourceLogs;\n  if (!Array.isArray(resourceLogs)) return;\n  for (const resourceLog of resourceLogs) {\n    if (!resourceLog || typeof resourceLog !== 'object') continue;\n    const scopeLogs = (resourceLog as { scopeLogs?: unknown[] }).scopeLogs;\n    if (!Array.isArray(scopeLogs)) continue;\n    for (const scopeLog of scopeLogs) {\n      if (!scopeLog || typeof scopeLog !== 'object') continue;\n      const logRecords = (scopeLog as { logRecords?: unknown[] }).logRecords;\n      if (!Array.isArray(logRecords)) continue;\n      for (const record of logRecords) {\n        if (record && typeof record === 'object') {\n          yield record as OtlpLogRecord;\n        }\n      }\n    }\n  }\n}\n\nexport function parseOtlpLogEvents(payload: unknown): TerminalLogEvent[] {\n  const events: TerminalLogEvent[] = [];\n  for (const record of extractLogRecords(payload)) {\n    const time = toMs(record.timeUnixNano || record.observedTimeUnixNano);\n    events.push({\n      time,\n      level: mapSeverityToLevel(record.severityNumber, record.severityText),\n      message: bodyToMessage(record.body),\n      traceId: record.traceId ? normalizeHexId(record.traceId, 32) : undefined,\n      spanId: record.spanId ? normalizeHexId(record.spanId, 16) : undefined,\n      attributes: attrsToRecord(record.attributes),\n    });\n  }\n  return events;\n}\n\n// --- OTLP Metrics parsing (accept and count) ---\n\nexport function countOtlpMetrics(payload: unknown): number {\n  if (!payload || typeof payload !== 'object') return 0;\n  let count = 0;\n  const resourceMetrics = (payload as { resourceMetrics?: unknown[] })\n    .resourceMetrics;\n  if (!Array.isArray(resourceMetrics)) return 0;\n  for (const resourceMetric of resourceMetrics) {\n    if (!resourceMetric || typeof resourceMetric !== 'object') continue;\n    const scopeMetrics = (resourceMetric as { scopeMetrics?: unknown[] })\n      .scopeMetrics;\n    if (!Array.isArray(scopeMetrics)) continue;\n    for (const scopeMetric of scopeMetrics) {\n      if (!scopeMetric || typeof scopeMetric !== 'object') continue;\n      const metrics = (scopeMetric as { metrics?: unknown[] }).metrics;\n      if (Array.isArray(metrics)) {\n        count += metrics.length;\n      }\n    }\n  }\n  return count;\n}\n","#!/usr/bin/env node\nimport { readFileSync } from 'node:fs';\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport path from 'node:path';\nimport { renderTerminal } from './index';\nimport { listenLoopbackDualStack } from './listen';\nimport { getTerminalLogStream } from './log-stream';\nimport { CliTerminalSpanStream } from './cli-stream';\nimport {\n  countOtlpMetrics,\n  parseOtlpEvents,\n  parseOtlpLogEvents,\n  readJsonBody,\n  sendJson,\n} from './otlp-http-json';\n\nimport type { AIConfig, AIProviderType } from './ai/types';\n\ntype CliOptions = {\n  port: number;\n  host: string;\n  title?: string;\n  ai: Partial<AIConfig>;\n};\n\nfunction printHelp(): void {\n  process.stdout.write(\n    String.raw`autotel-terminal - Standalone OTLP receiver with terminal dashboard\n\nUsage: autotel-terminal [options]\n\nOptions:\n  -p, --port <port>          Port to listen on (default: 4319, env: AUTOTEL_TERMINAL_PORT)\n  -H, --host <host>          Host to bind to (default: 127.0.0.1, env: AUTOTEL_TERMINAL_HOST)\n  -t, --title <title>        Dashboard title (env: AUTOTEL_TERMINAL_TITLE)\n  -h, --help                 Show this help message\n  -v, --version              Show version number\n\nAI Options:\n  --ai-provider <provider>   AI provider: ollama, openai, openai-compatible (env: AI_PROVIDER)\n  --ai-model <model>         AI model name (env: AI_MODEL)\n  --ai-api-key <key>         API key for cloud providers (env: AI_API_KEY)\n  --ai-base-url <url>        Custom AI endpoint URL (env: AI_BASE_URL)\n\n  Auto-detection: if Ollama is running locally, it is used automatically.\n  If OPENAI_API_KEY is set, OpenAI is used. Press 'a' in the dashboard to toggle AI.\n\nEndpoints:\n  POST /v1/traces            Receive OTLP JSON trace data\n  POST /v1/logs              Receive OTLP JSON log data\n  POST /v1/metrics           Receive OTLP JSON metric data (accepted and counted)\n  GET  /healthz              Health check\n\nExamples:\n  npx autotel-terminal\n  npx autotel-terminal --ai-provider ollama --ai-model granite4\n  AI_API_KEY=sk-... npx autotel-terminal --ai-provider openai --ai-model gpt-4o\n` + '\\n',\n  );\n}\n\nfunction printVersion(): void {\n  try {\n    const dir = import.meta.dirname ?? new URL('.', import.meta.url).pathname;\n    const pkgPath = path.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: Number(process.env.AUTOTEL_TERMINAL_PORT || 4319),\n    host: process.env.AUTOTEL_TERMINAL_HOST || '127.0.0.1',\n    title: process.env.AUTOTEL_TERMINAL_TITLE,\n    ai: {},\n  };\n\n  for (let i = 0; i < argv.length; i++) {\n    const arg = argv[i];\n    const next = argv[i + 1];\n\n    if (arg === '--help' || arg === '-h') {\n      printHelp();\n      return null;\n    }\n    if (arg === '--version' || arg === '-v') {\n      printVersion();\n      return null;\n    }\n    if ((arg === '--port' || arg === '-p') && next) {\n      options.port = Number(next);\n      i++;\n      continue;\n    }\n    if ((arg === '--host' || arg === '-H') && next) {\n      options.host = next;\n      i++;\n      continue;\n    }\n    if ((arg === '--title' || arg === '-t') && next) {\n      options.title = next;\n      i++;\n      continue;\n    }\n    if (arg === '--ai-provider' && next) {\n      options.ai.provider = next as AIProviderType;\n      i++;\n      continue;\n    }\n    if (arg === '--ai-model' && next) {\n      options.ai.model = next;\n      i++;\n      continue;\n    }\n    if (arg === '--ai-api-key' && next) {\n      options.ai.apiKey = next;\n      i++;\n      continue;\n    }\n    if (arg === '--ai-base-url' && next) {\n      options.ai.baseUrl = next;\n      i++;\n    }\n  }\n\n  return options;\n}\n\nconst OTLP_ROUTES = new Set(['/v1/traces', '/v1/logs', '/v1/metrics']);\n\nasync function main(): Promise<void> {\n  const options = parseArgs(process.argv.slice(2));\n  if (!options) {\n    process.exit(0);\n  }\n\n  const spanStream = new CliTerminalSpanStream();\n  const logStream = getTerminalLogStream();\n\n  renderTerminal(\n    {\n      title:\n        options.title || `Autotel Terminal (${options.host}:${options.port})`,\n      ai: options.ai,\n    },\n    spanStream,\n  );\n\n  const requestHandler = async (\n    req: IncomingMessage,\n    res: ServerResponse,\n  ): Promise<void> => {\n    if (req.method === 'GET' && req.url === '/healthz') {\n      sendJson(res, 200, { ok: true });\n      return;\n    }\n\n    if (req.method !== 'POST' || !OTLP_ROUTES.has(req.url ?? '')) {\n      sendJson(res, 404, { error: 'Not found' });\n      return;\n    }\n\n    try {\n      const payload = await readJsonBody(req);\n\n      if (req.url === '/v1/traces') {\n        const events = parseOtlpEvents(payload);\n        for (const event of events) {\n          spanStream.push(event);\n        }\n        sendJson(res, 200, { acceptedSpans: events.length });\n        return;\n      }\n\n      if (req.url === '/v1/logs') {\n        const events = parseOtlpLogEvents(payload);\n        for (const event of events) {\n          logStream.emit(event);\n        }\n        sendJson(res, 200, { acceptedLogs: events.length });\n        return;\n      }\n\n      if (req.url === '/v1/metrics') {\n        const count = countOtlpMetrics(payload);\n        sendJson(res, 200, { acceptedMetrics: count });\n        return;\n      }\n    } catch (error) {\n      sendJson(res, 400, {\n        error: 'Invalid OTLP JSON payload',\n        message: error instanceof Error ? error.message : String(error),\n      });\n    }\n  };\n\n  const server = createServer(requestHandler);\n\n  // Bind both loopback families when host is loopback, so a `localhost` proxy\n  // reaches us whether it resolves to 127.0.0.1 or ::1 (the macOS IPv6 footgun).\n  const listeners = listenLoopbackDualStack({\n    primary: server,\n    port: options.port,\n    host: options.host,\n    attachSecondary: (s) => s.on('request', requestHandler),\n  });\n\n  const { addresses, warnings } = await listeners.ready;\n  process.stdout.write(\n    `[autotel-terminal] listening on ${addresses.join(' + ')}\\n`,\n  );\n  process.stdout.write(\n    '[autotel-terminal] endpoints: /v1/traces, /v1/logs, /v1/metrics\\n',\n  );\n  process.stdout.write(\n    '[autotel-terminal] set OTEL_EXPORTER_OTLP_PROTOCOL=http/json and OTEL_EXPORTER_OTLP_ENDPOINT to this host/port\\n',\n  );\n  for (const w of warnings) {\n    process.stdout.write(`[autotel-terminal] ⚠ ${w}\\n`);\n  }\n\n  const shutdown = () => {\n    Promise.all([\n      new Promise<void>((r) => server.close(() => r())),\n      listeners.closeSibling(),\n    ]).then(() => process.exit(0));\n  };\n  process.on('SIGINT', shutdown);\n  process.on('SIGTERM', shutdown);\n}\n\nmain().catch((error) => {\n  process.stderr.write(\n    `[autotel-terminal] failed to start: ${error instanceof Error ? error.message : String(error)}\\n`,\n  );\n  process.exit(1);\n});\n"],"mappings":"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"}