@burn0/burn0 0.1.0 → 0.2.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/env.ts","../src/interceptor/guard.ts","../src/services/map.ts","../src/types.ts","../src/interceptor/stream.ts","../src/interceptor/fetch.ts","../src/interceptor/http.ts","../src/restore.ts","../src/transport/dispatcher.ts","../src/transport/batch.ts","../src/transport/local.ts","../src/transport/api.ts","../src/transport/local-pricing.ts","../src/transport/logger.ts","../src/index.ts"],"sourcesContent":["import type { RuntimeMode } from '../types'\n\nexport function getApiKey(): string | undefined {\n const key = process.env.BURN0_API_KEY\n return key && key.length > 0 ? key : undefined\n}\n\nexport function detectMode(opts: { isTTY: boolean; apiKey: string | undefined }): RuntimeMode {\n const isTest = process.env.NODE_ENV === 'test'\n if (isTest) {\n return process.env.BURN0_ENABLE_TEST === '1' ? 'test-enabled' : 'test-disabled'\n }\n if (opts.apiKey) {\n return opts.isTTY ? 'dev-cloud' : 'prod-cloud'\n }\n return opts.isTTY ? 'dev-local' : 'prod-local'\n}\n\nexport function isTTY(): boolean {\n return Boolean(process.stdout.isTTY)\n}\n\nexport function isDebug(): boolean {\n return process.env.BURN0_DEBUG === '1' || process.env.BURN0_DEBUG === 'true'\n}\n","let patched = false\n\nexport function canPatch(): boolean {\n return !patched\n}\n\nexport function markPatched(): void {\n patched = true\n}\n\nexport function resetGuard(): void {\n patched = false\n}\n\nconst KNOWN_SDK_MODULES = [\n 'openai', '@anthropic-ai/sdk', '@google/generative-ai',\n '@mistralai/mistralai', 'cohere-ai', 'stripe',\n '@sendgrid/mail', 'twilio', 'resend', '@supabase/supabase-js',\n]\n\nexport function checkImportOrder(): string[] {\n const preloaded: string[] = []\n if (typeof require !== 'undefined' && require.cache) {\n for (const sdk of KNOWN_SDK_MODULES) {\n if (Object.keys(require.cache).some(k => k.includes(`/node_modules/${sdk}/`))) {\n preloaded.push(sdk)\n }\n }\n }\n return preloaded\n}\n","const BUILT_IN_MAP: Record<string, string> = {\n // LLMs\n 'api.openai.com': 'openai',\n 'api.anthropic.com': 'anthropic',\n 'generativelanguage.googleapis.com': 'google-gemini',\n 'api.mistral.ai': 'mistral',\n 'api.cohere.com': 'cohere',\n 'api.groq.com': 'groq',\n 'api.together.xyz': 'together-ai',\n 'api.perplexity.ai': 'perplexity',\n 'api.fireworks.ai': 'fireworks-ai',\n 'api.deepseek.com': 'deepseek',\n 'api.replicate.com': 'replicate',\n 'api.ai21.com': 'ai21',\n // APIs\n 'api.stripe.com': 'stripe',\n 'api.paypal.com': 'paypal',\n 'api.sendgrid.com': 'sendgrid',\n 'api.resend.com': 'resend',\n 'api.postmarkapp.com': 'postmark',\n 'api.mailgun.net': 'mailgun',\n 'api.twilio.com': 'twilio',\n 'api.vonage.com': 'vonage',\n 'api.clerk.com': 'clerk',\n 'api.cloudinary.com': 'cloudinary',\n 'upload.uploadcare.com': 'uploadcare',\n 'maps.googleapis.com': 'google-maps',\n 'api.mapbox.com': 'mapbox',\n 'api.segment.io': 'segment',\n 'api.mixpanel.com': 'mixpanel',\n 'api.github.com': 'github-api',\n 'api.plaid.com': 'plaid',\n 'api.pinecone.io': 'pinecone',\n 'supabase.co': 'supabase',\n}\n\nconst IGNORED_PATTERNS = ['localhost', '127.0.0.1', '0.0.0.0', '[::1]']\n\nlet serviceMap: Record<string, string> = { ...BUILT_IN_MAP }\n\nexport function identifyService(hostname: string): string | null {\n if (IGNORED_PATTERNS.includes(hostname) || hostname.startsWith('localhost:')) {\n return null\n }\n\n // Exact match\n if (serviceMap[hostname]) return serviceMap[hostname]\n\n // Try suffix matching for subdomains (e.g., myproject.supabase.co → supabase.co)\n for (const [mapHost, service] of Object.entries(serviceMap)) {\n if (hostname.endsWith('.' + mapHost)) return service\n }\n\n return `unknown:${hostname}`\n}\n\nexport function mergeServiceMap(remote: Record<string, string>): void {\n serviceMap = { ...serviceMap, ...remote }\n}\n\nexport function resetServiceMap(): void {\n serviceMap = { ...BUILT_IN_MAP }\n}\n","export interface Burn0Event {\n schema_version: number\n service: string\n endpoint: string\n model?: string\n tokens_in?: number\n tokens_out?: number\n status_code: number\n timestamp: string\n duration_ms: number\n estimated: boolean\n feature?: string\n metadata?: Record<string, string | number | boolean>\n}\n\nexport type RuntimeMode =\n | 'dev-cloud'\n | 'dev-local'\n | 'prod-cloud'\n | 'prod-local'\n | 'test-disabled'\n | 'test-enabled'\n\nexport interface Burn0Config {\n projectName?: string\n services?: ServiceConfig[]\n}\n\nexport interface ServiceConfig {\n name: string\n pricingModel: 'auto' | 'fixed-tier'\n plan?: string\n monthlyCost?: number\n}\n\nexport interface Span {\n end: () => void\n}\n\nexport const SCHEMA_VERSION = 1\n","export function teeReadableStream(\n stream: ReadableStream<Uint8Array>\n): [ReadableStream<Uint8Array>, ReadableStream<Uint8Array>] {\n return stream.tee() as [ReadableStream<Uint8Array>, ReadableStream<Uint8Array>]\n}\n\ninterface Usage {\n prompt_tokens?: number\n completion_tokens?: number\n input_tokens?: number\n output_tokens?: number\n}\n\nexport function extractUsageFromSSE(raw: string): Usage | null {\n const lines = raw.split('\\n')\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i]\n if (!line.startsWith('data: ') || line === 'data: [DONE]') continue\n try {\n const parsed = JSON.parse(line.slice(6))\n if (parsed.usage) return parsed.usage\n } catch {}\n }\n return null\n}\n\nexport async function collectStream(stream: ReadableStream<Uint8Array>, timeoutMs = 30000): Promise<string> {\n const reader = stream.getReader()\n const chunks: string[] = []\n const decoder = new TextDecoder()\n\n const timeout = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error('stream timeout')), timeoutMs)\n })\n\n try {\n while (true) {\n const result = await Promise.race([reader.read(), timeout]) as ReadableStreamReadResult<Uint8Array>\n if (result.done) break\n chunks.push(decoder.decode(result.value, { stream: true }))\n }\n } catch {\n // Timeout or error — return what we have\n } finally {\n try { reader.releaseLock() } catch {}\n }\n\n return chunks.join('')\n}\n","import { identifyService } from '../services/map'\nimport type { Burn0Event } from '../types'\nimport { SCHEMA_VERSION } from '../types'\nimport { teeReadableStream, collectStream, extractUsageFromSSE } from './stream'\n\ntype EventCallback = (event: Burn0Event) => void\nlet originalFetch: typeof globalThis.fetch | null = null\n\nexport function patchFetch(onEvent: EventCallback): void {\n originalFetch = globalThis.fetch\n\n globalThis.fetch = async function burn0Fetch(\n input: RequestInfo | URL,\n init?: RequestInit\n ): Promise<Response> {\n const startTime = Date.now()\n const url = new URL(typeof input === 'string' ? input : input instanceof URL ? input.href : input.url)\n const hostname = url.hostname\n const service = identifyService(hostname)\n\n if (!service) {\n return originalFetch!(input, init)\n }\n\n let model: string | undefined\n\n // Extract model from request body (OpenAI, Anthropic, etc.)\n if (init?.body && typeof init.body === 'string') {\n try {\n const parsed = JSON.parse(init.body)\n if (parsed.model) model = parsed.model\n } catch {}\n }\n\n // Extract model from URL path (Gemini-style: /v1beta/models/gemini-2.0-flash:generateContent)\n if (!model) {\n const modelMatch = url.pathname.match(/\\/models\\/([^/:]+)/)\n if (modelMatch) model = modelMatch[1]\n }\n\n const response = await originalFetch!(input, init)\n const duration = Date.now() - startTime\n\n let tokensIn: number | undefined\n let tokensOut: number | undefined\n\n // Check for SSE streaming response\n if (response.headers.get('content-type')?.includes('text/event-stream') && response.body) {\n const [forCaller, forBurn0] = teeReadableStream(response.body)\n\n collectStream(forBurn0).then((raw) => {\n const usage = extractUsageFromSSE(raw)\n let sseTokensIn = usage?.prompt_tokens ?? usage?.input_tokens\n let sseTokensOut = usage?.completion_tokens ?? usage?.output_tokens\n if (sseTokensIn !== undefined && sseTokensIn < 0) sseTokensIn = undefined\n if (sseTokensOut !== undefined && sseTokensOut < 0) sseTokensOut = undefined\n const sseEvent: Burn0Event = {\n schema_version: SCHEMA_VERSION,\n service,\n endpoint: url.pathname,\n model,\n tokens_in: sseTokensIn,\n tokens_out: sseTokensOut,\n status_code: response.status,\n timestamp: new Date().toISOString(),\n duration_ms: duration,\n estimated: !usage,\n }\n try { onEvent(sseEvent) } catch {}\n }).catch(() => {\n const sseEvent: Burn0Event = {\n schema_version: SCHEMA_VERSION,\n service,\n endpoint: url.pathname,\n model,\n status_code: response.status,\n timestamp: new Date().toISOString(),\n duration_ms: duration,\n estimated: true,\n }\n try { onEvent(sseEvent) } catch {}\n })\n\n return new Response(forCaller, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n }\n\n if (response.headers.get('content-type')?.includes('application/json')) {\n try {\n const cloned = response.clone()\n const body = await cloned.json()\n // Standard format (OpenAI, Anthropic, Perplexity)\n if (body.usage) {\n tokensIn = body.usage.prompt_tokens ?? body.usage.input_tokens\n tokensOut = body.usage.completion_tokens ?? body.usage.output_tokens\n }\n // Gemini format\n if (body.usageMetadata) {\n tokensIn = body.usageMetadata.promptTokenCount\n tokensOut = body.usageMetadata.candidatesTokenCount\n }\n if (body.model) model = body.model\n } catch {}\n }\n\n if (tokensIn !== undefined && tokensIn < 0) tokensIn = undefined\n if (tokensOut !== undefined && tokensOut < 0) tokensOut = undefined\n\n const event: Burn0Event = {\n schema_version: SCHEMA_VERSION,\n service,\n endpoint: url.pathname,\n model,\n tokens_in: tokensIn,\n tokens_out: tokensOut,\n status_code: response.status,\n timestamp: new Date().toISOString(),\n duration_ms: duration,\n estimated: false,\n }\n\n try { onEvent(event) } catch {}\n return response\n }\n}\n\nexport function unpatchFetch(): void {\n if (originalFetch) {\n globalThis.fetch = originalFetch\n originalFetch = null\n }\n}\n","import http from 'node:http'\nimport https from 'node:https'\nimport { identifyService } from '../services/map'\nimport type { Burn0Event } from '../types'\nimport { SCHEMA_VERSION } from '../types'\n\ntype EventCallback = (event: Burn0Event) => void\n\nlet originalHttpRequest: typeof http.request | null = null\nlet originalHttpsRequest: typeof https.request | null = null\nlet originalHttpGet: typeof http.get | null = null\nlet originalHttpsGet: typeof https.get | null = null\n\nfunction wrapRequest(original: typeof http.request, onEvent: EventCallback): typeof http.request {\n return function burn0Request(this: unknown, ...args: Parameters<typeof http.request>): http.ClientRequest {\n const req = original.apply(this, args)\n const startTime = Date.now()\n\n const firstArg = args[0]\n let hostname = ''\n let endpoint = '/'\n\n if (typeof firstArg === 'string') {\n try {\n const parsed = new URL(firstArg)\n hostname = parsed.hostname\n endpoint = parsed.pathname\n } catch {}\n } else if (firstArg instanceof URL) {\n hostname = firstArg.hostname\n endpoint = firstArg.pathname\n } else if (firstArg && typeof firstArg === 'object') {\n hostname = (firstArg as http.RequestOptions).hostname ?? (firstArg as http.RequestOptions).host ?? ''\n endpoint = (firstArg as http.RequestOptions).path ?? '/'\n }\n\n const cleanHostname = hostname.replace(/:\\d+$/, '')\n const service = identifyService(cleanHostname)\n\n if (!service) return req\n\n req.on('response', (res: http.IncomingMessage) => {\n const isJson = res.headers['content-type']?.includes('application/json')\n const chunks: Buffer[] = []\n const MAX_RESPONSE_SIZE = 5 * 1024 * 1024 // 5MB\n let totalSize = 0\n let tooLarge = false\n\n if (isJson) {\n res.on('data', (chunk: Buffer) => {\n totalSize += chunk.length\n if (totalSize > MAX_RESPONSE_SIZE) {\n tooLarge = true\n return\n }\n chunks.push(chunk)\n })\n }\n res.on('end', () => {\n const duration = Date.now() - startTime\n let tokensIn: number | undefined\n let tokensOut: number | undefined\n let model: string | undefined\n\n if (isJson && chunks.length > 0 && !tooLarge) {\n try {\n const body = JSON.parse(Buffer.concat(chunks).toString())\n if (body.usage) {\n tokensIn = body.usage.prompt_tokens ?? body.usage.input_tokens\n tokensOut = body.usage.completion_tokens ?? body.usage.output_tokens\n }\n if (body.model) model = body.model\n } catch {}\n }\n\n if (tokensIn !== undefined && tokensIn < 0) tokensIn = undefined\n if (tokensOut !== undefined && tokensOut < 0) tokensOut = undefined\n\n const event: Burn0Event = {\n schema_version: SCHEMA_VERSION,\n service,\n endpoint: endpoint.toString(),\n model,\n tokens_in: tokensIn,\n tokens_out: tokensOut,\n status_code: res.statusCode ?? 0,\n timestamp: new Date().toISOString(),\n duration_ms: duration,\n estimated: false,\n }\n try { onEvent(event) } catch {}\n })\n })\n return req\n } as typeof http.request\n}\n\nexport function patchHttp(onEvent: EventCallback): void {\n originalHttpRequest = http.request\n originalHttpsRequest = https.request\n originalHttpGet = http.get\n originalHttpsGet = https.get\n http.request = wrapRequest(originalHttpRequest, onEvent)\n https.request = wrapRequest(originalHttpsRequest as unknown as typeof http.request, onEvent) as unknown as typeof https.request\n http.get = wrapRequest(originalHttpGet as typeof http.request, onEvent) as typeof http.get\n https.get = wrapRequest(originalHttpsGet as unknown as typeof http.request, onEvent) as unknown as typeof https.get\n}\n\nexport function unpatchHttp(): void {\n if (originalHttpRequest) { http.request = originalHttpRequest; originalHttpRequest = null }\n if (originalHttpsRequest) { https.request = originalHttpsRequest; originalHttpsRequest = null }\n if (originalHttpGet) { http.get = originalHttpGet; originalHttpGet = null }\n if (originalHttpsGet) { https.get = originalHttpsGet; originalHttpsGet = null }\n}\n","interface RestoreDeps {\n unpatchFetch: () => void\n unpatchHttp: () => void\n resetGuard: () => void\n}\n\nexport function createRestorer(deps: RestoreDeps): () => void {\n return () => {\n deps.unpatchFetch()\n deps.unpatchHttp()\n deps.resetGuard()\n }\n}\n","import type { Burn0Event, RuntimeMode } from '../types'\n\ninterface DispatcherDeps {\n logEvent?: (event: Burn0Event) => void\n writeLedger?: (event: Burn0Event) => void\n addToBatch?: (event: Burn0Event) => void\n}\n\nexport function createDispatcher(mode: RuntimeMode, deps: DispatcherDeps): (event: Burn0Event) => void {\n return (event: Burn0Event) => {\n switch (mode) {\n case 'dev-local':\n deps.logEvent?.(event); deps.writeLedger?.(event); break\n case 'dev-cloud':\n deps.logEvent?.(event); deps.writeLedger?.(event); deps.addToBatch?.(event); break\n case 'prod-cloud':\n deps.logEvent?.(event); deps.writeLedger?.(event); deps.addToBatch?.(event); break\n case 'prod-local':\n deps.logEvent?.(event); break\n case 'test-enabled':\n deps.logEvent?.(event); deps.writeLedger?.(event); deps.addToBatch?.(event); break\n case 'test-disabled':\n break\n }\n }\n}\n","import type { Burn0Event } from '../types'\n\nexport interface BatchBufferOptions {\n sizeThreshold: number\n timeThresholdMs: number\n maxSize: number\n onFlush: (events: Burn0Event[]) => void\n}\n\nexport class BatchBuffer {\n private events: Burn0Event[] = []\n private timer: ReturnType<typeof setInterval> | null = null\n private options: BatchBufferOptions\n\n constructor(options: BatchBufferOptions) {\n this.options = options\n this.timer = setInterval(() => {\n if (this.events.length > 0) this.flush()\n }, options.timeThresholdMs)\n if (this.timer && typeof this.timer === 'object' && 'unref' in this.timer) {\n this.timer.unref()\n }\n }\n\n add(event: Burn0Event): void {\n this.events.push(event)\n if (this.events.length > this.options.maxSize) {\n this.events = this.events.slice(-this.options.maxSize)\n }\n if (this.events.length >= this.options.sizeThreshold) {\n this.flush()\n }\n }\n\n flush(): void {\n if (this.events.length === 0) return\n const batch = [...this.events]\n this.events = []\n this.options.onFlush(batch)\n }\n\n destroy(): void {\n if (this.timer) { clearInterval(this.timer); this.timer = null }\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { Burn0Event } from '../types'\n\nconst BURN0_DIR = '.burn0'\nconst LEDGER_FILE = 'costs.jsonl'\nconst MAX_FILE_SIZE = 10 * 1024 * 1024\nconst MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000\n\nexport class LocalLedger {\n private filePath: string\n private dirPath: string\n\n constructor(projectRoot: string) {\n this.dirPath = path.join(projectRoot, BURN0_DIR)\n this.filePath = path.join(this.dirPath, LEDGER_FILE)\n }\n\n write(event: Burn0Event): void {\n this.ensureDir()\n this.rotateIfNeeded()\n fs.appendFileSync(this.filePath, JSON.stringify(event) + '\\n')\n }\n\n read(): Burn0Event[] {\n try {\n const content = fs.readFileSync(this.filePath, 'utf-8').trim()\n if (!content) return []\n return content.split('\\n').map((line) => JSON.parse(line) as Burn0Event)\n } catch { return [] }\n }\n\n private ensureDir(): void {\n if (!fs.existsSync(this.dirPath)) fs.mkdirSync(this.dirPath, { recursive: true })\n }\n\n private rotateIfNeeded(): void {\n try {\n const stat = fs.statSync(this.filePath)\n if (stat.size > MAX_FILE_SIZE) { this.pruneOldEntries(); return }\n } catch { return }\n const events = this.read()\n if (events.length > 0) {\n const oldest = new Date(events[0].timestamp).getTime()\n if (Date.now() - oldest > MAX_AGE_MS) this.pruneOldEntries()\n }\n }\n\n private pruneOldEntries(): void {\n const cutoff = Date.now() - MAX_AGE_MS\n const events = this.read().filter(e => new Date(e.timestamp).getTime() > cutoff)\n const content = events.map(e => JSON.stringify(e)).join('\\n') + (events.length ? '\\n' : '')\n fs.writeFileSync(this.filePath, content)\n }\n}\n","import type { Burn0Event } from '../types'\nimport { isDebug } from '../config/env'\n\nconst SDK_VERSION = '0.1.0'\n\nexport async function shipEvents(\n events: Burn0Event[],\n apiKey: string,\n baseUrl: string,\n fetchFn: typeof globalThis.fetch = globalThis.fetch\n): Promise<boolean> {\n const maxAttempts = 3\n const baseDelayMs = 1000\n const maxDelayMs = 5000\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n const response = await fetchFn(`${baseUrl}/v1/events`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n 'X-Burn0-SDK-Version': SDK_VERSION,\n },\n body: JSON.stringify({ events, sdk_version: SDK_VERSION }),\n })\n if (response.ok) return true\n } catch (err) {\n if (isDebug()) {\n console.warn('[burn0] Event shipping failed:', (err as Error).message)\n }\n }\n\n if (attempt < maxAttempts - 1) {\n const delay = Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs)\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n }\n\n return false\n}\n","/**\n * Pricing data for terminal display.\n * Fetched from the burn0 backend on startup, cached locally.\n * Falls back to \"no cost display\" if backend is unreachable.\n */\nimport fs from 'node:fs'\nimport path from 'node:path'\n\ninterface PricingData {\n version: number\n updated_at: string\n services: Record<string, any>\n}\n\nlet pricingData: PricingData | null = null\nconst CACHE_FILE = '.burn0/pricing-cache.json'\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000 // 24 hours\n\n// Free services — no API call cost\nconst FREE_SERVICES = new Set([\n 'github-api', 'slack-api', 'discord-api',\n])\n\nexport type CostEstimate =\n | { type: 'priced'; cost: number }\n | { type: 'free' }\n | { type: 'no-tokens' }\n | { type: 'fixed-tier' }\n | { type: 'unknown' }\n | { type: 'loading' } // pricing not fetched yet\n\n/**\n * Fetch pricing from backend and cache locally.\n * Non-blocking — called on init, doesn't delay the app.\n */\nexport async function fetchPricing(\n apiUrl: string,\n fetchFn: typeof globalThis.fetch\n): Promise<void> {\n // Try cache first\n try {\n const cachePath = path.join(process.cwd(), CACHE_FILE)\n if (fs.existsSync(cachePath)) {\n const raw = fs.readFileSync(cachePath, 'utf-8')\n const cached = JSON.parse(raw) as PricingData & { cached_at: number }\n if (Date.now() - cached.cached_at < CACHE_TTL_MS) {\n pricingData = cached\n return\n }\n }\n } catch {}\n\n // Fetch from backend\n try {\n const response = await fetchFn(`${apiUrl}/v1/pricing`, {\n headers: { 'Accept': 'application/json' },\n })\n if (response.ok) {\n const data = await response.json() as PricingData\n pricingData = data\n\n // Cache to disk\n try {\n const dir = path.join(process.cwd(), '.burn0')\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(\n path.join(process.cwd(), CACHE_FILE),\n JSON.stringify({ ...data, cached_at: Date.now() }, null, 2)\n )\n } catch {}\n }\n } catch {}\n}\n\nexport function estimateLocalCost(event: {\n service: string\n model?: string\n tokens_in?: number\n tokens_out?: number\n endpoint?: string\n status_code?: number\n}): CostEstimate {\n // Free services\n if (FREE_SERVICES.has(event.service)) {\n return { type: 'free' }\n }\n\n // Unknown services\n if (event.service.startsWith('unknown:')) {\n return { type: 'unknown' }\n }\n\n // No pricing data loaded yet\n if (!pricingData) {\n return { type: 'loading' }\n }\n\n const svc = pricingData.services[event.service]\n if (!svc) {\n return { type: 'unknown' }\n }\n\n // LLM pricing\n if (svc.type === 'llm') {\n if (!event.model) return { type: 'unknown' }\n if (event.tokens_in === undefined || event.tokens_out === undefined) {\n return { type: 'no-tokens' }\n }\n\n // Try exact match, then prefix match\n let prices: [number, number] | undefined = svc.models[event.model]\n if (!prices) {\n const match = Object.keys(svc.models).find((m: string) => event.model!.startsWith(m))\n if (match) prices = svc.models[match]\n }\n if (prices) {\n const inputCost = (event.tokens_in / 1_000_000) * prices[0]\n const outputCost = (event.tokens_out / 1_000_000) * prices[1]\n return { type: 'priced', cost: inputCost + outputCost }\n }\n return { type: 'unknown' }\n }\n\n // API pricing with endpoint matching\n if (svc.type === 'api') {\n const endpoint = event.endpoint ?? ''\n // Try prefix match\n for (const [prefix, cost] of Object.entries(svc.endpoints)) {\n if (prefix !== '*' && endpoint.startsWith(prefix)) {\n return (cost as number) === 0 ? { type: 'free' } : { type: 'priced', cost: cost as number }\n }\n }\n // Fall back to default\n const defaultCost = svc.endpoints['*'] as number | undefined\n if (defaultCost !== undefined) {\n return defaultCost === 0 ? { type: 'free' } : { type: 'priced', cost: defaultCost }\n }\n return { type: 'unknown' }\n }\n\n // Fixed-tier services\n if (svc.type === 'fixed') {\n return { type: 'fixed-tier' }\n }\n\n return { type: 'unknown' }\n}\n","import type { Burn0Event } from '../types'\nimport { estimateLocalCost } from './local-pricing'\n\nconst RESET = '\\x1b[0m'\nconst GREEN = '\\x1b[32m'\nconst BOLD = '\\x1b[1m'\nconst ORANGE = '\\x1b[38;2;250;93;25m'\nconst GRAY = '\\x1b[90m'\nconst CLEAR_LINE = '\\x1b[2K\\r'\n\nexport interface TickerInit {\n todayCost: number\n todayCalls: number\n perServiceCosts: Record<string, number>\n}\n\nexport interface Ticker {\n tick: (event: Burn0Event) => void\n printExitSummary: () => void\n}\n\nfunction formatCost(cost: number): string {\n if (cost >= 1) return `$${cost.toFixed(2)}`\n if (cost >= 0.01) return `$${cost.toFixed(4)}`\n return `$${cost.toFixed(6)}`\n}\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n if (seconds < 60) return `${seconds}s`\n const minutes = Math.floor(seconds / 60)\n const remainingSeconds = seconds % 60\n if (minutes < 60) return `${minutes}m ${remainingSeconds}s`\n const hours = Math.floor(minutes / 60)\n const remainingMinutes = minutes % 60\n return `${hours}h ${remainingMinutes}m`\n}\n\nfunction formatServiceBreakdown(perServiceCosts: Record<string, number>, maxWidth: number): string {\n const sorted = Object.entries(perServiceCosts)\n .filter(([, cost]) => cost > 0)\n .sort((a, b) => b[1] - a[1])\n\n if (sorted.length === 0) return ''\n\n const parts: string[] = []\n let currentWidth = 0\n\n let shown = 0\n for (let i = 0; i < sorted.length && shown < 3; i++) {\n const [name, cost] = sorted[i]\n const part = `${name}: ${formatCost(cost)}`\n if (currentWidth + part.length + 3 > maxWidth && shown > 0) {\n break\n }\n parts.push(part)\n currentWidth += part.length + 3\n shown++\n }\n\n const remaining = sorted.length - shown\n if (remaining > 0) {\n parts.push(`+${remaining} more`)\n }\n\n return parts.join(' · ')\n}\n\nexport function createTicker(init: TickerInit): Ticker {\n let sessionCost = 0\n let sessionCalls = 0\n const sessionStartTime = Date.now()\n\n let todayCost = init.todayCost\n let todayCalls = init.todayCalls\n const perServiceCosts = { ...init.perServiceCosts }\n\n let exitPrinted = false\n\n let pricedCalls = 0\n let lastLineLen = 0\n\n function render(): void {\n if (!process.stderr.isTTY) return\n if (todayCalls === 0) return\n\n let content: string\n if (pricedCalls === 0 && todayCost === 0) {\n content = ` burn0 ▸ ${todayCalls} calls today`\n } else {\n const breakdown = formatServiceBreakdown(perServiceCosts, 40)\n const breakdownPart = breakdown ? ` ── ${breakdown}` : ''\n content = ` burn0 ▸ ${formatCost(todayCost)} today (${todayCalls} calls)${breakdownPart}`\n }\n\n // Pad with spaces to clear any leftover characters from the previous render\n const pad = lastLineLen > content.length ? ' '.repeat(lastLineLen - content.length) : ''\n lastLineLen = content.length\n\n // Apply colors after measuring length (ANSI codes don't take terminal width)\n let colored: string\n if (pricedCalls === 0 && todayCost === 0) {\n colored = ` ${ORANGE}${BOLD}burn0 ▸${RESET} ${GRAY}${todayCalls} calls today${RESET}`\n } else {\n const breakdown = formatServiceBreakdown(perServiceCosts, 40)\n const breakdownPart = breakdown ? ` ${GRAY}──${RESET} ${breakdown}` : ''\n colored = ` ${ORANGE}${BOLD}burn0 ▸${RESET} ${GREEN}${formatCost(todayCost)}${RESET} ${GRAY}today (${todayCalls} calls)${RESET}${breakdownPart}`\n }\n\n process.stderr.write(`\\r${colored}${pad}`)\n }\n\n function tick(event: Burn0Event): void {\n const estimate = estimateLocalCost(event)\n\n todayCalls++\n sessionCalls++\n\n if (estimate.type === 'priced' && estimate.cost > 0) {\n todayCost += estimate.cost\n sessionCost += estimate.cost\n pricedCalls++\n perServiceCosts[event.service] = (perServiceCosts[event.service] ?? 0) + estimate.cost\n }\n\n render()\n }\n\n function printExitSummary(): void {\n if (!process.stderr.isTTY) return\n if (sessionCalls === 0) return\n if (exitPrinted) return\n exitPrinted = true\n\n const duration = formatDuration(Date.now() - sessionStartTime)\n let line: string\n if (pricedCalls === 0 && sessionCost === 0) {\n line = `\\n ${ORANGE}${BOLD}burn0 ▸${RESET} ${GRAY}session: ${sessionCalls} calls (${duration})${RESET} ${GRAY}──${RESET} ${GRAY}today: ${todayCalls} calls${RESET}\\n`\n } else {\n const monthlyEst = todayCost > 0 ? formatCost(todayCost * 30) : null\n const projPart = monthlyEst ? ` ${GRAY}──${RESET} ${GRAY}~${GREEN}${monthlyEst}${RESET}${GRAY}/mo${RESET}` : ''\n line = `\\n ${ORANGE}${BOLD}burn0 ▸${RESET} ${GRAY}session:${RESET} ${GREEN}${formatCost(sessionCost)}${RESET} ${GRAY}(${sessionCalls} calls, ${duration})${RESET} ${GRAY}──${RESET} ${GRAY}today:${RESET} ${GREEN}${formatCost(todayCost)}${RESET}${projPart}\\n`\n }\n\n process.stderr.write(line)\n }\n\n return { tick, printExitSummary }\n}\n","import { getApiKey, detectMode, isTTY } from './config/env'\nimport { canPatch, markPatched, resetGuard, checkImportOrder } from './interceptor/guard'\nimport { patchFetch, unpatchFetch } from './interceptor/fetch'\nimport { patchHttp, unpatchHttp } from './interceptor/http'\nimport { createTracker } from './track'\nimport { createRestorer } from './restore'\nimport { createDispatcher } from './transport/dispatcher'\nimport { BatchBuffer } from './transport/batch'\nimport { LocalLedger } from './transport/local'\nimport { shipEvents } from './transport/api'\nimport { createTicker } from './transport/logger'\nimport { fetchPricing, estimateLocalCost } from './transport/local-pricing'\nimport type { Burn0Event } from './types'\n\nconst BURN0_API_URL = process.env.BURN0_API_URL ?? 'https://api.burn0.dev'\n\nconst apiKey = getApiKey()\nconst mode = detectMode({ isTTY: isTTY(), apiKey })\n\nconst { track, startSpan, enrichEvent } = createTracker()\n\n// Store original fetch before patching (for API shipper and pricing fetch)\nconst originalFetch = globalThis.fetch\n\n// Fetch pricing data from backend (non-blocking, uses original fetch)\nif (mode !== 'test-disabled' && mode !== 'prod-local') {\n fetchPricing(BURN0_API_URL, originalFetch).catch(() => {})\n}\n\n// Always create ledger — used to seed today's cost for the ticker\nconst ledger = new LocalLedger(process.cwd())\n\n// Seed ticker with today's prior costs from ledger\nfunction getTodayDateStr(): string {\n const d = new Date()\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`\n}\n\nlet todayCost = 0\nlet todayCalls = 0\nconst perServiceCosts: Record<string, number> = {}\n\ntry {\n const todayStr = getTodayDateStr()\n const allEvents = ledger.read()\n for (const event of allEvents) {\n const eventDate = new Date(event.timestamp)\n const eventDateStr = `${eventDate.getFullYear()}-${String(eventDate.getMonth() + 1).padStart(2, '0')}-${String(eventDate.getDate()).padStart(2, '0')}`\n if (eventDateStr === todayStr) {\n todayCalls++\n const estimate = estimateLocalCost(event)\n if (estimate.type === 'priced' && estimate.cost > 0) {\n todayCost += estimate.cost\n perServiceCosts[event.service] = (perServiceCosts[event.service] ?? 0) + estimate.cost\n }\n }\n }\n} catch {}\n\nconst ticker = createTicker({ todayCost, todayCalls, perServiceCosts })\n\nlet batch: BatchBuffer | null = null\nif ((mode === 'dev-cloud' || mode === 'prod-cloud') && apiKey) {\n batch = new BatchBuffer({\n sizeThreshold: 50,\n timeThresholdMs: 10000,\n maxSize: 500,\n onFlush: (events) => {\n shipEvents(events, apiKey, BURN0_API_URL, originalFetch).catch(() => {})\n },\n })\n}\n\n// Always write to ledger — powers the ticker, report, and local cost tracking\nconst shouldWriteLedger = mode !== 'test-disabled' && mode !== 'prod-local'\n\nconst dispatch = createDispatcher(mode, {\n logEvent: (e) => ticker.tick(e),\n writeLedger: shouldWriteLedger ? (e) => ledger.write(e) : undefined,\n addToBatch: batch ? (e) => batch!.add(e) : undefined,\n})\n\nconst preloaded = checkImportOrder()\nif (preloaded.length > 0) {\n console.warn(`[burn0] Warning: These SDKs were imported before burn0 and may not be tracked: ${preloaded.join(', ')}. Move \\`import '@burn0/burn0'\\` to the top of your entry file.`)\n}\n\nif (mode === 'prod-local') {\n console.warn('[burn0] No API key — costs not tracked. Get one free at burn0.dev/api')\n}\n\nif (canPatch() && mode !== 'test-disabled' && mode !== 'prod-local') {\n const onEvent = (event: Burn0Event) => {\n const enriched = enrichEvent(event)\n dispatch(enriched)\n }\n patchFetch(onEvent)\n patchHttp(onEvent)\n markPatched()\n}\n\n// Cleanup on exit — flush batch and print summary\n// Only use 'exit' event — fires when process is already terminating\n// Never register SIGINT/SIGTERM handlers — that interferes with the app's lifecycle\nlet exitHandled = false\nprocess.on('exit', () => {\n if (exitHandled) return\n exitHandled = true\n if (batch) {\n batch.flush()\n batch.destroy()\n }\n ticker.printExitSummary()\n})\n\nconst restore = createRestorer({ unpatchFetch, unpatchHttp, resetGuard })\n\nexport { track, startSpan, restore }\n"],"mappings":"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","names":["preloaded","mode","batch","apiKey","fs","path","perServiceCosts","todayCost","todayCalls","originalFetch"]}