@burn0/burn0 0.1.0 → 0.2.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/register.js CHANGED
@@ -451,13 +451,16 @@ function createDispatcher(mode2, deps) {
451
451
  break;
452
452
  case "dev-cloud":
453
453
  deps.logEvent?.(event);
454
+ deps.writeLedger?.(event);
454
455
  deps.addToBatch?.(event);
455
456
  break;
456
457
  case "prod-cloud":
458
+ deps.logEvent?.(event);
459
+ deps.writeLedger?.(event);
457
460
  deps.addToBatch?.(event);
458
461
  break;
459
462
  case "prod-local":
460
- deps.accumulate?.(event);
463
+ deps.logEvent?.(event);
461
464
  break;
462
465
  case "test-enabled":
463
466
  deps.logEvent?.(event);
@@ -688,114 +691,114 @@ function estimateLocalCost(event) {
688
691
  }
689
692
 
690
693
  // src/transport/logger.ts
691
- var DIM = "\x1B[2m";
692
694
  var RESET = "\x1B[0m";
693
- var CYAN = "\x1B[36m";
694
695
  var GREEN = "\x1B[32m";
695
- var YELLOW = "\x1B[33m";
696
- var WHITE = "\x1B[37m";
697
696
  var BOLD = "\x1B[1m";
698
697
  var ORANGE = "\x1B[38;2;250;93;25m";
699
698
  var GRAY = "\x1B[90m";
700
- var headerPrinted = false;
701
- var sessionTotal = 0;
702
- var eventCount = 0;
703
- function formatTokens(count) {
704
- if (count >= 1e6) return `${(count / 1e6).toFixed(1)}M`;
705
- if (count >= 1e3) return `${(count / 1e3).toFixed(1)}K`;
706
- return count.toString();
707
- }
708
699
  function formatCost(cost) {
709
700
  if (cost >= 1) return `$${cost.toFixed(2)}`;
710
701
  if (cost >= 0.01) return `$${cost.toFixed(4)}`;
711
702
  return `$${cost.toFixed(6)}`;
712
703
  }
713
- function formatCostEstimate(estimate) {
714
- switch (estimate.type) {
715
- case "priced":
716
- return `${GREEN}${formatCost(estimate.cost)}${RESET}`;
717
- case "free":
718
- return `${GRAY}free${RESET}`;
719
- case "no-tokens":
720
- return `${YELLOW}no usage${RESET}`;
721
- case "fixed-tier":
722
- return `${YELLOW}plan?${RESET}`;
723
- case "unknown":
724
- return `${GRAY}untracked${RESET}`;
725
- case "loading":
726
- return `${GRAY}...${RESET}`;
727
- }
728
- }
729
- function printHeader() {
730
- if (headerPrinted) return;
731
- headerPrinted = true;
732
- process.stdout.write(`
733
- `);
734
- process.stdout.write(` ${ORANGE}${BOLD} burn0 ${RESET} ${DIM}live cost tracking${RESET}
735
- `);
736
- process.stdout.write(`
737
- `);
738
- process.stdout.write(` ${GRAY}SERVICE ENDPOINT / MODEL USAGE COST${RESET}
739
- `);
740
- process.stdout.write(` ${GRAY}${"\u2500".repeat(68)}${RESET}
741
- `);
742
- }
743
- function printSessionTotal() {
744
- process.stdout.write(` ${GRAY}${"\u2500".repeat(68)}${RESET}
745
- `);
746
- if (sessionTotal > 0) {
747
- process.stdout.write(` ${GRAY}${eventCount} calls${RESET} ${ORANGE}${BOLD}${formatCost(sessionTotal)}${RESET}
748
- `);
749
- } else {
750
- process.stdout.write(` ${GRAY}${eventCount} calls${RESET} ${GRAY}$0${RESET}
751
- `);
752
- }
753
- process.stdout.write(` ${GRAY}${"\u2500".repeat(68)}${RESET}
754
- `);
755
- }
756
- function formatEventLine(event) {
757
- const service = event.service.length > 15 ? event.service.substring(0, 14) + "." : event.service;
758
- const modelOrEndpoint = event.model ? event.model.length > 29 ? event.model.substring(0, 28) + "." : event.model : event.endpoint.length > 29 ? event.endpoint.substring(0, 28) + "." : event.endpoint;
759
- let usage = "";
760
- if (event.tokens_in !== void 0 && event.tokens_out !== void 0) {
761
- usage = `${formatTokens(event.tokens_in)} \u2192 ${formatTokens(event.tokens_out)}`;
762
- }
763
- const estimate = estimateLocalCost(event);
764
- const costStr = formatCostEstimate(estimate);
765
- return ` ${CYAN}${service.padEnd(16)}${RESET} ${WHITE}${modelOrEndpoint.padEnd(30)}${RESET}${GRAY}${usage.padEnd(15)}${RESET}${costStr}`;
766
- }
767
- function formatProcessSummary(events, uptimeSeconds) {
768
- const services = {};
769
- for (const event of events) {
770
- if (!services[event.service]) services[event.service] = { calls: 0 };
771
- services[event.service].calls++;
772
- if (event.tokens_in !== void 0) services[event.service].tokens_in = (services[event.service].tokens_in ?? 0) + event.tokens_in;
773
- if (event.tokens_out !== void 0) services[event.service].tokens_out = (services[event.service].tokens_out ?? 0) + event.tokens_out;
774
- }
775
- for (const svc of Object.values(services)) {
776
- if (svc.tokens_in === void 0) delete svc.tokens_in;
777
- if (svc.tokens_out === void 0) delete svc.tokens_out;
778
- }
779
- return JSON.stringify({
780
- burn0: "process-summary",
781
- uptime_hours: +(uptimeSeconds / 3600).toFixed(1),
782
- total_calls: events.length,
783
- services,
784
- message: "Add BURN0_API_KEY to see cost breakdowns \u2192 burn0.dev"
785
- });
786
- }
787
- function logEvent(event) {
788
- printHeader();
789
- const estimate = estimateLocalCost(event);
790
- if (estimate.type === "priced" && estimate.cost > 0) {
791
- sessionTotal += estimate.cost;
792
- }
793
- eventCount++;
794
- process.stdout.write(`${formatEventLine(event)}
795
- `);
796
- if (eventCount % 5 === 0) {
797
- printSessionTotal();
704
+ function formatDuration(ms) {
705
+ const seconds = Math.floor(ms / 1e3);
706
+ if (seconds < 60) return `${seconds}s`;
707
+ const minutes = Math.floor(seconds / 60);
708
+ const remainingSeconds = seconds % 60;
709
+ if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;
710
+ const hours = Math.floor(minutes / 60);
711
+ const remainingMinutes = minutes % 60;
712
+ return `${hours}h ${remainingMinutes}m`;
713
+ }
714
+ function formatServiceBreakdown(perServiceCosts2, maxWidth) {
715
+ const sorted = Object.entries(perServiceCosts2).filter(([, cost]) => cost > 0).sort((a, b) => b[1] - a[1]);
716
+ if (sorted.length === 0) return "";
717
+ const parts = [];
718
+ let currentWidth = 0;
719
+ let shown = 0;
720
+ for (let i = 0; i < sorted.length && shown < 3; i++) {
721
+ const [name, cost] = sorted[i];
722
+ const part = `${name}: ${formatCost(cost)}`;
723
+ if (currentWidth + part.length + 3 > maxWidth && shown > 0) {
724
+ break;
725
+ }
726
+ parts.push(part);
727
+ currentWidth += part.length + 3;
728
+ shown++;
729
+ }
730
+ const remaining = sorted.length - shown;
731
+ if (remaining > 0) {
732
+ parts.push(`+${remaining} more`);
733
+ }
734
+ return parts.join(" \xB7 ");
735
+ }
736
+ function createTicker(init) {
737
+ let sessionCost = 0;
738
+ let sessionCalls = 0;
739
+ const sessionStartTime = Date.now();
740
+ let todayCost2 = init.todayCost;
741
+ let todayCalls2 = init.todayCalls;
742
+ const perServiceCosts2 = { ...init.perServiceCosts };
743
+ let exitPrinted = false;
744
+ let pricedCalls = 0;
745
+ let lastLineLen = 0;
746
+ function render() {
747
+ if (!process.stderr.isTTY) return;
748
+ if (todayCalls2 === 0) return;
749
+ let content;
750
+ if (pricedCalls === 0 && todayCost2 === 0) {
751
+ content = ` burn0 \u25B8 ${todayCalls2} calls today`;
752
+ } else {
753
+ const breakdown = formatServiceBreakdown(perServiceCosts2, 40);
754
+ const breakdownPart = breakdown ? ` \u2500\u2500 ${breakdown}` : "";
755
+ content = ` burn0 \u25B8 ${formatCost(todayCost2)} today (${todayCalls2} calls)${breakdownPart}`;
756
+ }
757
+ const pad = lastLineLen > content.length ? " ".repeat(lastLineLen - content.length) : "";
758
+ lastLineLen = content.length;
759
+ let colored;
760
+ if (pricedCalls === 0 && todayCost2 === 0) {
761
+ colored = ` ${ORANGE}${BOLD}burn0 \u25B8${RESET} ${GRAY}${todayCalls2} calls today${RESET}`;
762
+ } else {
763
+ const breakdown = formatServiceBreakdown(perServiceCosts2, 40);
764
+ const breakdownPart = breakdown ? ` ${GRAY}\u2500\u2500${RESET} ${breakdown}` : "";
765
+ colored = ` ${ORANGE}${BOLD}burn0 \u25B8${RESET} ${GREEN}${formatCost(todayCost2)}${RESET} ${GRAY}today (${todayCalls2} calls)${RESET}${breakdownPart}`;
766
+ }
767
+ process.stderr.write(`\r${colored}${pad}`);
768
+ }
769
+ function tick(event) {
770
+ const estimate = estimateLocalCost(event);
771
+ todayCalls2++;
772
+ sessionCalls++;
773
+ if (estimate.type === "priced" && estimate.cost > 0) {
774
+ todayCost2 += estimate.cost;
775
+ sessionCost += estimate.cost;
776
+ pricedCalls++;
777
+ perServiceCosts2[event.service] = (perServiceCosts2[event.service] ?? 0) + estimate.cost;
778
+ }
779
+ render();
780
+ }
781
+ function printExitSummary() {
782
+ if (!process.stderr.isTTY) return;
783
+ if (sessionCalls === 0) return;
784
+ if (exitPrinted) return;
785
+ exitPrinted = true;
786
+ const duration = formatDuration(Date.now() - sessionStartTime);
787
+ let line;
788
+ if (pricedCalls === 0 && sessionCost === 0) {
789
+ line = `
790
+ ${ORANGE}${BOLD}burn0 \u25B8${RESET} ${GRAY}session: ${sessionCalls} calls (${duration})${RESET} ${GRAY}\u2500\u2500${RESET} ${GRAY}today: ${todayCalls2} calls${RESET}
791
+ `;
792
+ } else {
793
+ const monthlyEst = todayCost2 > 0 ? formatCost(todayCost2 * 30) : null;
794
+ const projPart = monthlyEst ? ` ${GRAY}\u2500\u2500${RESET} ${GRAY}~${GREEN}${monthlyEst}${RESET}${GRAY}/mo${RESET}` : "";
795
+ line = `
796
+ ${ORANGE}${BOLD}burn0 \u25B8${RESET} ${GRAY}session:${RESET} ${GREEN}${formatCost(sessionCost)}${RESET} ${GRAY}(${sessionCalls} calls, ${duration})${RESET} ${GRAY}\u2500\u2500${RESET} ${GRAY}today:${RESET} ${GREEN}${formatCost(todayCost2)}${RESET}${projPart}
797
+ `;
798
+ }
799
+ process.stderr.write(line);
798
800
  }
801
+ return { tick, printExitSummary };
799
802
  }
800
803
 
801
804
  // src/index.ts
@@ -804,12 +807,36 @@ var apiKey = getApiKey();
804
807
  var mode = detectMode({ isTTY: isTTY(), apiKey });
805
808
  var { track, startSpan, enrichEvent } = createTracker();
806
809
  var originalFetch2 = globalThis.fetch;
807
- if (mode !== "test-disabled") {
810
+ if (mode !== "test-disabled" && mode !== "prod-local") {
808
811
  fetchPricing(BURN0_API_URL, originalFetch2).catch(() => {
809
812
  });
810
813
  }
811
- var accumulatedEvents = [];
812
- var ledger = mode === "dev-local" || mode === "test-enabled" ? new LocalLedger(process.cwd()) : null;
814
+ var ledger = new LocalLedger(process.cwd());
815
+ function getTodayDateStr() {
816
+ const d = /* @__PURE__ */ new Date();
817
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
818
+ }
819
+ var todayCost = 0;
820
+ var todayCalls = 0;
821
+ var perServiceCosts = {};
822
+ try {
823
+ const todayStr = getTodayDateStr();
824
+ const allEvents = ledger.read();
825
+ for (const event of allEvents) {
826
+ const eventDate = new Date(event.timestamp);
827
+ const eventDateStr = `${eventDate.getFullYear()}-${String(eventDate.getMonth() + 1).padStart(2, "0")}-${String(eventDate.getDate()).padStart(2, "0")}`;
828
+ if (eventDateStr === todayStr) {
829
+ todayCalls++;
830
+ const estimate = estimateLocalCost(event);
831
+ if (estimate.type === "priced" && estimate.cost > 0) {
832
+ todayCost += estimate.cost;
833
+ perServiceCosts[event.service] = (perServiceCosts[event.service] ?? 0) + estimate.cost;
834
+ }
835
+ }
836
+ }
837
+ } catch {
838
+ }
839
+ var ticker = createTicker({ todayCost, todayCalls, perServiceCosts });
813
840
  var batch = null;
814
841
  if ((mode === "dev-cloud" || mode === "prod-cloud") && apiKey) {
815
842
  batch = new BatchBuffer({
@@ -822,17 +849,20 @@ if ((mode === "dev-cloud" || mode === "prod-cloud") && apiKey) {
822
849
  }
823
850
  });
824
851
  }
852
+ var shouldWriteLedger = mode !== "test-disabled" && mode !== "prod-local";
825
853
  var dispatch = createDispatcher(mode, {
826
- logEvent,
827
- writeLedger: ledger ? (e) => ledger.write(e) : void 0,
828
- addToBatch: batch ? (e) => batch.add(e) : void 0,
829
- accumulate: (e) => accumulatedEvents.push(e)
854
+ logEvent: (e) => ticker.tick(e),
855
+ writeLedger: shouldWriteLedger ? (e) => ledger.write(e) : void 0,
856
+ addToBatch: batch ? (e) => batch.add(e) : void 0
830
857
  });
831
858
  var preloaded = checkImportOrder();
832
859
  if (preloaded.length > 0) {
833
- console.warn(`[burn0] Warning: These SDKs were imported before burn0 and may not be tracked: ${preloaded.join(", ")}. Move \`import 'burn0'\` to the top of your entry file.`);
860
+ 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.`);
834
861
  }
835
- if (canPatch() && mode !== "test-disabled") {
862
+ if (mode === "prod-local") {
863
+ console.warn("[burn0] No API key \u2014 costs not tracked. Get one free at burn0.dev/api");
864
+ }
865
+ if (canPatch() && mode !== "test-disabled" && mode !== "prod-local") {
836
866
  const onEvent = (event) => {
837
867
  const enriched = enrichEvent(event);
838
868
  dispatch(enriched);
@@ -841,24 +871,15 @@ if (canPatch() && mode !== "test-disabled") {
841
871
  patchHttp(onEvent);
842
872
  markPatched();
843
873
  }
844
- if (mode === "prod-local") {
845
- const startTime = Date.now();
846
- process.on("beforeExit", () => {
847
- if (accumulatedEvents.length > 0) {
848
- const uptimeSeconds = (Date.now() - startTime) / 1e3;
849
- console.log(formatProcessSummary(accumulatedEvents, uptimeSeconds));
850
- }
851
- });
852
- }
853
- if (batch) {
854
- const exitFlush = () => {
874
+ var exitHandled = false;
875
+ process.on("exit", () => {
876
+ if (exitHandled) return;
877
+ exitHandled = true;
878
+ if (batch) {
855
879
  batch.flush();
856
880
  batch.destroy();
857
- };
858
- process.on("beforeExit", exitFlush);
859
- process.on("SIGTERM", exitFlush);
860
- process.on("SIGINT", exitFlush);
861
- process.on("SIGHUP", exitFlush);
862
- }
881
+ }
882
+ ticker.printExitSummary();
883
+ });
863
884
  var restore = createRestorer({ unpatchFetch, unpatchHttp, resetGuard });
864
885
  //# sourceMappingURL=register.js.map
package/dist/register.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import "./chunk-ZHAS7BCI.mjs";
1
+ import "./chunk-KKYHE4ZV.mjs";
2
2
  import "./chunk-DJ72YN4C.mjs";
3
3
  //# sourceMappingURL=register.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burn0/burn0",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Lightweight cost observability for every API call in your stack",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -24,7 +24,13 @@
24
24
  "import": "./dist/track.mjs"
25
25
  }
26
26
  },
27
- "files": ["dist", "scripts"],
27
+ "files": [
28
+ "dist/**/*.js",
29
+ "dist/**/*.mjs",
30
+ "dist/**/*.d.ts",
31
+ "dist/**/*.d.mts",
32
+ "scripts"
33
+ ],
28
34
  "scripts": {
29
35
  "build": "tsup",
30
36
  "dev": "tsup --watch",
@@ -34,7 +40,18 @@
34
40
  "prepublishOnly": "npm run build",
35
41
  "postinstall": "node scripts/postinstall.js || true"
36
42
  },
37
- "keywords": ["cost", "observability", "llm", "api", "tracking", "openai", "anthropic", "burn-rate", "cost-tracking", "api-costs"],
43
+ "keywords": [
44
+ "cost",
45
+ "observability",
46
+ "llm",
47
+ "api",
48
+ "tracking",
49
+ "openai",
50
+ "anthropic",
51
+ "burn-rate",
52
+ "cost-tracking",
53
+ "api-costs"
54
+ ],
38
55
  "author": "burn0",
39
56
  "license": "MIT",
40
57
  "repository": {
@@ -1,6 +1,28 @@
1
- const message = `
2
- Add \`import 'burn0'\` to your app entry point to start tracking costs.
1
+ const { execFileSync } = require('child_process')
2
+ const fs = require('fs')
3
+ const path = require('path')
3
4
 
4
- Optional: run \`npx burn0 init\` for full setup.
5
- `
6
- console.log(message)
5
+ const projectRoot = process.env.INIT_CWD || process.cwd()
6
+
7
+ if (!process.stdout.isTTY) {
8
+ console.log('[burn0] Run "npx burn0 init" to set up cost tracking.')
9
+ process.exit(0)
10
+ }
11
+
12
+ try {
13
+ const configPath = path.join(projectRoot, '.burn0', 'config.json')
14
+ if (fs.existsSync(configPath)) {
15
+ console.log('[burn0] Already configured. Run "npx burn0 init" to reconfigure.')
16
+ process.exit(0)
17
+ }
18
+ } catch {}
19
+
20
+ try {
21
+ const cliPath = path.join(__dirname, '..', 'dist', 'cli', 'index.js')
22
+ execFileSync('node', [cliPath, 'init'], {
23
+ stdio: 'inherit',
24
+ cwd: projectRoot,
25
+ })
26
+ } catch {
27
+ console.log('[burn0] Setup skipped. Run "npx burn0 init" when ready.')
28
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/track.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { Burn0Event, Span } from './types'\n\ninterface TrackContext {\n feature: string\n metadata?: Record<string, string | number | boolean>\n}\n\nconst storage = new AsyncLocalStorage<TrackContext>()\nlet activeSpan: TrackContext | null = null\n\nexport function createTracker() {\n async function track(\n feature: string,\n metadata: Record<string, string | number | boolean>,\n fn: () => Promise<void>\n ): Promise<void> {\n await storage.run({ feature, metadata }, fn)\n }\n\n function startSpan(\n feature: string,\n metadata?: Record<string, string | number | boolean>\n ): Span {\n activeSpan = { feature, metadata }\n return {\n end() { activeSpan = null },\n }\n }\n\n function enrichEvent(event: Burn0Event): Burn0Event {\n const ctx = storage.getStore() ?? activeSpan\n if (!ctx) return event\n return {\n ...event,\n feature: ctx.feature,\n metadata: ctx.metadata && Object.keys(ctx.metadata).length > 0 ? ctx.metadata : undefined,\n }\n }\n\n return { track, startSpan, enrichEvent }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,yBAAyB;AAQlC,IAAM,UAAU,IAAI,kBAAgC;AACpD,IAAI,aAAkC;AAE/B,SAAS,gBAAgB;AAC9B,iBAAe,MACb,SACA,UACA,IACe;AACf,UAAM,QAAQ,IAAI,EAAE,SAAS,SAAS,GAAG,EAAE;AAAA,EAC7C;AAEA,WAAS,UACP,SACA,UACM;AACN,iBAAa,EAAE,SAAS,SAAS;AACjC,WAAO;AAAA,MACL,MAAM;AAAE,qBAAa;AAAA,MAAK;AAAA,IAC5B;AAAA,EACF;AAEA,WAAS,YAAY,OAA+B;AAClD,UAAM,MAAM,QAAQ,SAAS,KAAK;AAClC,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS,IAAI;AAAA,MACb,UAAU,IAAI,YAAY,OAAO,KAAK,IAAI,QAAQ,EAAE,SAAS,IAAI,IAAI,WAAW;AAAA,IAClF;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,WAAW,YAAY;AACzC;","names":[]}
@@ -1 +0,0 @@
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 accumulate?: (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.addToBatch?.(event); break\n case 'prod-cloud':\n deps.addToBatch?.(event); break\n case 'prod-local':\n deps.accumulate?.(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, type CostEstimate } from './local-pricing'\n\nconst DIM = '\\x1b[2m'\nconst RESET = '\\x1b[0m'\nconst CYAN = '\\x1b[36m'\nconst GREEN = '\\x1b[32m'\nconst YELLOW = '\\x1b[33m'\nconst WHITE = '\\x1b[37m'\nconst BOLD = '\\x1b[1m'\nconst ORANGE = '\\x1b[38;2;250;93;25m'\nconst BG_DARK = '\\x1b[48;2;30;30;30m'\nconst GRAY = '\\x1b[90m'\n\nlet headerPrinted = false\nlet sessionTotal = 0\nlet eventCount = 0\n\nfunction formatTokens(count: number): string {\n if (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`\n if (count >= 1000) return `${(count / 1000).toFixed(1)}K`\n return count.toString()\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 formatCostEstimate(estimate: CostEstimate): string {\n switch (estimate.type) {\n case 'priced':\n return `${GREEN}${formatCost(estimate.cost)}${RESET}`\n case 'free':\n return `${GRAY}free${RESET}`\n case 'no-tokens':\n return `${YELLOW}no usage${RESET}`\n case 'fixed-tier':\n return `${YELLOW}plan?${RESET}`\n case 'unknown':\n return `${GRAY}untracked${RESET}`\n case 'loading':\n return `${GRAY}...${RESET}`\n }\n}\n\nfunction printHeader(): void {\n if (headerPrinted) return\n headerPrinted = true\n process.stdout.write(`\\n`)\n process.stdout.write(` ${ORANGE}${BOLD} burn0 ${RESET} ${DIM}live cost tracking${RESET}\\n`)\n process.stdout.write(`\\n`)\n process.stdout.write(` ${GRAY}SERVICE ENDPOINT / MODEL USAGE COST${RESET}\\n`)\n process.stdout.write(` ${GRAY}${'─'.repeat(68)}${RESET}\\n`)\n}\n\nfunction printSessionTotal(): void {\n process.stdout.write(` ${GRAY}${'─'.repeat(68)}${RESET}\\n`)\n if (sessionTotal > 0) {\n process.stdout.write(` ${GRAY}${eventCount} calls${RESET} ${ORANGE}${BOLD}${formatCost(sessionTotal)}${RESET}\\n`)\n } else {\n process.stdout.write(` ${GRAY}${eventCount} calls${RESET} ${GRAY}$0${RESET}\\n`)\n }\n process.stdout.write(` ${GRAY}${'─'.repeat(68)}${RESET}\\n`)\n}\n\nexport function formatEventLine(event: Burn0Event): string {\n const service = event.service.length > 15\n ? event.service.substring(0, 14) + '.'\n : event.service\n\n const modelOrEndpoint = event.model\n ? (event.model.length > 29 ? event.model.substring(0, 28) + '.' : event.model)\n : (event.endpoint.length > 29 ? event.endpoint.substring(0, 28) + '.' : event.endpoint)\n\n let usage = ''\n if (event.tokens_in !== undefined && event.tokens_out !== undefined) {\n usage = `${formatTokens(event.tokens_in)} → ${formatTokens(event.tokens_out)}`\n }\n\n const estimate = estimateLocalCost(event)\n const costStr = formatCostEstimate(estimate)\n\n return ` ${CYAN}${service.padEnd(16)}${RESET} ${WHITE}${modelOrEndpoint.padEnd(30)}${RESET}${GRAY}${usage.padEnd(15)}${RESET}${costStr}`\n}\n\nexport function formatProcessSummary(events: Burn0Event[], uptimeSeconds: number): string {\n const services: Record<string, { calls: number; tokens_in?: number; tokens_out?: number }> = {}\n for (const event of events) {\n if (!services[event.service]) services[event.service] = { calls: 0 }\n services[event.service].calls++\n if (event.tokens_in !== undefined) services[event.service].tokens_in = (services[event.service].tokens_in ?? 0) + event.tokens_in\n if (event.tokens_out !== undefined) services[event.service].tokens_out = (services[event.service].tokens_out ?? 0) + event.tokens_out\n }\n for (const svc of Object.values(services)) {\n if (svc.tokens_in === undefined) delete svc.tokens_in\n if (svc.tokens_out === undefined) delete svc.tokens_out\n }\n return JSON.stringify({\n burn0: 'process-summary',\n uptime_hours: +(uptimeSeconds / 3600).toFixed(1),\n total_calls: events.length,\n services,\n message: 'Add BURN0_API_KEY to see cost breakdowns → burn0.dev',\n })\n}\n\nexport function logEvent(event: Burn0Event): void {\n printHeader()\n\n const estimate = estimateLocalCost(event)\n if (estimate.type === 'priced' && estimate.cost > 0) {\n sessionTotal += estimate.cost\n }\n eventCount++\n\n process.stdout.write(`${formatEventLine(event)}\\n`)\n\n // Show running total every 5 events\n if (eventCount % 5 === 0) {\n printSessionTotal()\n }\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 { logEvent, formatProcessSummary } from './transport/logger'\nimport { fetchPricing } 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') {\n fetchPricing(BURN0_API_URL, originalFetch).catch(() => {})\n}\n\nconst accumulatedEvents: Burn0Event[] = []\n\nconst ledger = (mode === 'dev-local' || mode === 'test-enabled')\n ? new LocalLedger(process.cwd())\n : null\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\nconst dispatch = createDispatcher(mode, {\n logEvent,\n writeLedger: ledger ? (e) => ledger.write(e) : undefined,\n addToBatch: batch ? (e) => batch!.add(e) : undefined,\n accumulate: (e) => accumulatedEvents.push(e),\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'\\` to the top of your entry file.`)\n}\n\nif (canPatch() && mode !== 'test-disabled') {\n const onEvent = (event: Burn0Event) => {\n const enriched = enrichEvent(event)\n dispatch(enriched)\n }\n patchFetch(onEvent)\n patchHttp(onEvent)\n markPatched()\n}\n\nif (mode === 'prod-local') {\n const startTime = Date.now()\n process.on('beforeExit', () => {\n if (accumulatedEvents.length > 0) {\n const uptimeSeconds = (Date.now() - startTime) / 1000\n console.log(formatProcessSummary(accumulatedEvents, uptimeSeconds))\n }\n })\n}\n\nif (batch) {\n const exitFlush = () => {\n batch!.flush()\n batch!.destroy()\n }\n process.on('beforeExit', exitFlush)\n process.on('SIGTERM', exitFlush)\n process.on('SIGINT', exitFlush)\n process.on('SIGHUP', exitFlush)\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","originalFetch"]}