@hasna/economy 0.5.6 → 0.5.8

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/chunks/{billing-22az60hy.js → billing-7twygmtj.js} +2 -2
  3. package/dist/chunks/{config-hsp7ndhj.js → config-mjgbekxj.js} +2 -2
  4. package/dist/chunks/{index-9wa1f2kv.js → index-7ek4r0ww.js} +1 -1
  5. package/dist/chunks/{index-qvcafabj.js → index-9za4cmq2.js} +2 -2
  6. package/dist/chunks/{index-zs5dba3t.js → index-a1gh3d6t.js} +5 -4
  7. package/dist/chunks/{index-vajzfzgv.js → index-ep1pkyr3.js} +1 -1
  8. package/dist/chunks/{index-zqsx461z.js → index-gf3kan31.js} +2 -2
  9. package/dist/chunks/{index-dk5rq1rq.js → index-gtjqy0kd.js} +1 -1
  10. package/dist/chunks/{index-m12xttw1.js → index-h2mcj7gv.js} +82 -7
  11. package/dist/chunks/{index-c7h2rxx1.js → index-t0n32g8r.js} +1 -1
  12. package/dist/chunks/{index-f5jv6q5q.js → index-zgvmrqyc.js} +1 -1
  13. package/dist/chunks/{open-projects-8qm46m3d.js → open-projects-bj561k5j.js} +1 -1
  14. package/dist/chunks/{pricing-k9wsjwbz.js → pricing-bkgvzpe9.js} +1 -1
  15. package/dist/chunks/{pricing-462f8xkm.js → pricing-bn88mhqk.js} +1 -1
  16. package/dist/chunks/{pricing-vxejj1qa.js → pricing-nt31hf53.js} +1 -1
  17. package/dist/chunks/{serve-ept6cfbe.js → serve-14cgmx02.js} +14 -8
  18. package/dist/chunks/{sqlite-store-ht6frztj.js → sqlite-store-8t4anw98.js} +2 -2
  19. package/dist/chunks/{sqlite-store-13nhr1z0.js → sqlite-store-jfy0e8b6.js} +2 -2
  20. package/dist/chunks/{sqlite-store-gamn65xp.js → sqlite-store-r219qrjt.js} +2 -2
  21. package/dist/chunks/{tui-4bh067a3.js → tui-s6tpce3h.js} +4 -4
  22. package/dist/chunks/{watch-227kxmra.js → watch-cv5va8x6.js} +5 -5
  23. package/dist/chunks/{webhooks-nw4daw9y.js → webhooks-td46p6gk.js} +2 -2
  24. package/dist/cli/index.js +32 -28
  25. package/dist/cost-imports/contract.d.ts +84 -0
  26. package/dist/cost-imports/contract.d.ts.map +1 -0
  27. package/dist/cost-imports/decimal.d.ts +6 -0
  28. package/dist/cost-imports/decimal.d.ts.map +1 -0
  29. package/dist/cost-imports/providers.d.ts +4 -0
  30. package/dist/cost-imports/providers.d.ts.map +1 -0
  31. package/dist/index.js +66 -8
  32. package/dist/lib/analytics.d.ts +3 -0
  33. package/dist/lib/analytics.d.ts.map +1 -1
  34. package/dist/lib/comparison-contract.d.ts +8 -0
  35. package/dist/lib/comparison-contract.d.ts.map +1 -0
  36. package/dist/lib/comparison-test-contract.d.ts +3 -0
  37. package/dist/lib/comparison-test-contract.d.ts.map +1 -0
  38. package/dist/lib/store/index.d.ts.map +1 -1
  39. package/dist/mcp/index.js +69 -11
  40. package/dist/otel/index.js +1 -1
  41. package/dist/server/index.js +40 -6
  42. package/dist/server/service-operations.d.ts.map +1 -1
  43. package/dist/server/service-worker.js +40 -6
  44. package/docs/comparison-coverage.md +30 -0
  45. package/native/README.md +70 -2
  46. package/native/Tools/pair-qr.py +130 -34
  47. package/native/Tools/pair-qr.swift +19 -1
  48. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.8
4
+
5
+ ### Patch Changes
6
+
7
+ - Recognize macOS login shells when opening private QR setup, while continuing to refuse captured agent terminals.
8
+ - Preserve the QR camera permission description in iPhone archives and refuse native device artifacts that omit it.
9
+ - Keep unknown historical billing and pricing explicit in comparison reports. Preserve usage counts, expose known monetary subtotals and coverage, and refuse unsupported hosted responses or incomplete percentage comparisons.
10
+ - Support an explicit private release Keychain for native Mac signing and notarization with credentials projected in memory.
11
+
12
+ ## 0.5.7
13
+
14
+ ### Patch Changes
15
+
16
+ - Support first-phone QR setup through private owner-Terminal login or explicitly confirmed signup. Accept signup HTTP 201 and attempt cleanup on catchable Terminal shutdown while preserving supplied sessions.
17
+
3
18
  ## 0.5.6
4
19
 
5
20
  ### Patch Changes
@@ -3,8 +3,8 @@ import {
3
3
  syncAnthropicBilling,
4
4
  syncGeminiBilling,
5
5
  syncOpenAIBilling
6
- } from "./index-dk5rq1rq.js";
7
- import"./index-f5jv6q5q.js";
6
+ } from "./index-gtjqy0kd.js";
7
+ import"./index-zgvmrqyc.js";
8
8
  import"./index-p35cyhc4.js";
9
9
  export {
10
10
  syncOpenAIBilling,
@@ -4,8 +4,8 @@ import {
4
4
  loadConfig,
5
5
  saveConfig,
6
6
  setConfigValue
7
- } from "./index-9wa1f2kv.js";
8
- import"./index-f5jv6q5q.js";
7
+ } from "./index-7ek4r0ww.js";
8
+ import"./index-zgvmrqyc.js";
9
9
  import"./index-p35cyhc4.js";
10
10
  export {
11
11
  setConfigValue,
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  getDataDir
4
- } from "./index-f5jv6q5q.js";
4
+ } from "./index-zgvmrqyc.js";
5
5
 
6
6
  // src/lib/config.ts
7
7
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  LOCAL_STORAGE_OPT_IN_KEYS
4
- } from "./index-m12xttw1.js";
4
+ } from "./index-h2mcj7gv.js";
5
5
  import {
6
6
  assessCostFromDb,
7
7
  getIngestState,
@@ -19,7 +19,7 @@ import {
19
19
  upsertSession,
20
20
  upsertSubscription,
21
21
  upsertUsageSnapshot
22
- } from "./index-f5jv6q5q.js";
22
+ } from "./index-zgvmrqyc.js";
23
23
  import {
24
24
  __require
25
25
  } from "./index-p35cyhc4.js";
@@ -13,8 +13,9 @@ import {
13
13
  queryRangeStats,
14
14
  querySavingsSummary,
15
15
  requireCurrentBillingDiffSummary,
16
+ requireCurrentRangeStats,
16
17
  requireCurrentSavingsReport
17
- } from "./index-m12xttw1.js";
18
+ } from "./index-h2mcj7gv.js";
18
19
  import {
19
20
  deleteBudget,
20
21
  deleteGoal,
@@ -59,7 +60,7 @@ import {
59
60
  upsertSubscription,
60
61
  usageSnapshotFilterForPeriod,
61
62
  validateIngest
62
- } from "./index-f5jv6q5q.js";
63
+ } from "./index-zgvmrqyc.js";
63
64
  import {
64
65
  __require
65
66
  } from "./index-p35cyhc4.js";
@@ -92,7 +93,7 @@ class LocalStore {
92
93
  _db;
93
94
  async db() {
94
95
  if (!this._db) {
95
- const { openDatabase } = await import("./sqlite-store-13nhr1z0.js");
96
+ const { openDatabase } = await import("./sqlite-store-r219qrjt.js");
96
97
  this._db = openDatabase();
97
98
  ensurePricingSeeded(this._db);
98
99
  }
@@ -369,7 +370,7 @@ class ApiStore {
369
370
  return cloudListItems(this.cloud, "export", q({ type, period }));
370
371
  }
371
372
  async rangeStats(from, to) {
372
- return cloudObject(this.cloud, "/compare", q({ from, to }));
373
+ return requireCurrentRangeStats(await cloudObject(this.cloud, "/compare", q({ from, to })), from, to);
373
374
  }
374
375
  async forecast() {
375
376
  return cloudObject(this.cloud, "/forecast");
@@ -3430,4 +3430,4 @@ function computeCostWithPricing(model, pricing, inputTokens, outputTokens, cache
3430
3430
  return (inputTokens * effective.inputPer1M + outputTokens * effective.outputPer1M + cacheReadTokens * effective.cacheReadPer1M + cacheWriteTokens * effective.cacheWritePer1M + cacheWrite1hTokens * (effective.cacheWrite1hPer1M ?? effective.cacheWritePer1M) + cacheStorageTokenHours * (effective.cacheStoragePer1MHour ?? 0)) / 1e6;
3431
3431
  }
3432
3432
 
3433
- export { observationId, subscriptionId, scanReceiptId, AGENTS, MAX_INGEST_ROWS, MAX_INGEST_BYTES, stableJson, canonicalIngestBodyHash, validateIngest, resolveReportingInterval, calendarPeriodBounds, calendarPeriodWhere, usageSnapshotFilterForPeriod, sessionOverlapWhere, dataDir, cacheDir, getMachineId, getHomeDir, getResolverDataRoot, getLegacyDataRoot, adoptResolverDataRoot, getExactDataRoot, getDataDir, getDbPath, initSchema, upsertCostCenter, getCostCenter, upsertRequest, upsertSession, rollupSession, querySessions, queryTopSessions, querySummary, queryZeroCostTokenizedModels, queryModelBreakdown, queryAgentBreakdown, queryProjectBreakdown, queryAccountBreakdown, queryCostCenterBreakdown, queryProjectBreakdownSince, queryAgentBreakdownSince, queryModelBreakdownSince, queryAccountBreakdownSince, queryDailyBreakdown, queryHourlyBreakdown, upsertProject, getProject, listProjects, deleteProject, upsertBudget, listBudgets, deleteBudget, getBudgetStatuses, upsertGoal, deleteGoal, listGoals, getGoalStatuses, getIngestState, loadIngestState, setIngestState, queryRequestsSince, insertFeedback, upsertBillingDaily, clearBillingRange, queryBillingSummary, countBillingRecords, getSessionDetail, listMachines, upsertModelPricing, getModelPricing, listModelPricing, deleteModelPricing, seedModelPricing, upsertSubscription, listSubscriptions, deleteSubscription, upsertUsageSnapshot, upsertScanReceipt, queryScanReceipts, queryUsageSnapshots, listMachineRegistry, dedupeRequests, bulkIngest, DEFAULT_PRICING, normalizeModelName, ensurePricingSeeded, getPricingFromDb, getPricing, computeCost, computeCostFromDb, UnknownModelPricingError, assessCostFromDb, getPricingFromRows, estimateCostFromRows, assessCostFromRows, formatReportedUsd, formatPlanMoney, hasKnownUsagePrice, requireCurrentCostSummary, formatSummaryValue, formatSummaryCoverage, requireCurrentBillingSummary, formatBillingValue };
3433
+ export { observationId, subscriptionId, scanReceiptId, AGENTS, MAX_INGEST_ROWS, MAX_INGEST_BYTES, stableJson, canonicalIngestBodyHash, validateIngest, resolveReportingInterval, calendarPeriodBounds, calendarPeriodWhere, usageSnapshotFilterForPeriod, sessionOverlapWhere, dataDir, cacheDir, getMachineId, getHomeDir, getResolverDataRoot, getLegacyDataRoot, adoptResolverDataRoot, getExactDataRoot, getDataDir, getDbPath, initSchema, upsertCostCenter, getCostCenter, upsertRequest, upsertSession, rollupSession, querySessions, queryTopSessions, querySummary, queryZeroCostTokenizedModels, queryModelBreakdown, queryAgentBreakdown, queryProjectBreakdown, queryAccountBreakdown, queryCostCenterBreakdown, queryProjectBreakdownSince, queryAgentBreakdownSince, queryModelBreakdownSince, queryAccountBreakdownSince, queryDailyBreakdown, queryHourlyBreakdown, upsertProject, getProject, listProjects, deleteProject, upsertBudget, listBudgets, deleteBudget, getBudgetStatuses, upsertGoal, deleteGoal, listGoals, getGoalStatuses, getIngestState, loadIngestState, setIngestState, queryRequestsSince, insertFeedback, upsertBillingDaily, clearBillingRange, queryBillingSummary, countBillingRecords, getSessionDetail, listMachines, upsertModelPricing, getModelPricing, listModelPricing, deleteModelPricing, seedModelPricing, upsertSubscription, listSubscriptions, deleteSubscription, upsertUsageSnapshot, upsertScanReceipt, queryScanReceipts, queryUsageSnapshots, listMachineRegistry, dedupeRequests, bulkIngest, DEFAULT_PRICING, normalizeModelName, ensurePricingSeeded, getPricingFromDb, getPricing, computeCost, computeCostFromDb, UnknownModelPricingError, assessCostFromDb, getPricingFromRows, estimateCostFromRows, assessCostFromRows, formatReportedUsd, formatPlanMoney, hasKnownUsagePrice, buildCostSummary, requireCurrentCostSummary, formatSummaryValue, formatSummaryCoverage, requireCurrentBillingSummary, formatBillingValue };
@@ -4,12 +4,12 @@ import {
4
4
  } from "./index-w3bvv0ns.js";
5
5
  import {
6
6
  getStore
7
- } from "./index-zs5dba3t.js";
7
+ } from "./index-a1gh3d6t.js";
8
8
  import {
9
9
  formatReportedUsd,
10
10
  formatSummaryCoverage,
11
11
  formatSummaryValue
12
- } from "./index-f5jv6q5q.js";
12
+ } from "./index-zgvmrqyc.js";
13
13
 
14
14
  // src/cli/commands/tui.ts
15
15
  import chalk from "chalk";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  clearBillingRange,
4
4
  upsertBillingDaily
5
- } from "./index-f5jv6q5q.js";
5
+ } from "./index-zgvmrqyc.js";
6
6
 
7
7
  // src/ingest/billing.ts
8
8
  import { readFileSync } from "fs";
@@ -1,9 +1,11 @@
1
1
  // @bun
2
2
  import {
3
+ buildCostSummary,
3
4
  calendarPeriodBounds,
4
5
  calendarPeriodWhere,
5
6
  formatBillingValue,
6
7
  formatReportedUsd,
8
+ formatSummaryValue,
7
9
  hasKnownUsagePrice,
8
10
  listMachineRegistry,
9
11
  listMachines,
@@ -16,11 +18,75 @@ import {
16
18
  requireCurrentCostSummary,
17
19
  resolveReportingInterval,
18
20
  sessionOverlapWhere
19
- } from "./index-f5jv6q5q.js";
21
+ } from "./index-zgvmrqyc.js";
22
+
23
+ // src/lib/comparison-contract.ts
24
+ function comparisonDateBounds(from, to) {
25
+ const valid = (value) => /^\d{4}-\d{2}-\d{2}$/.test(value) && Number.isFinite(Date.parse(value + "T00:00:00Z")) && new Date(value + "T00:00:00Z").toISOString().slice(0, 10) === value;
26
+ if (!valid(from) || !valid(to) || from > to) {
27
+ throw new RangeError("from and to must be real YYYY-MM-DD UTC dates with from <= to");
28
+ }
29
+ const end = new Date(to + "T00:00:00Z");
30
+ end.setUTCDate(end.getUTCDate() + 1);
31
+ const exclusive = end.toISOString().slice(0, 10);
32
+ if (!valid(exclusive))
33
+ throw new RangeError("to exceeds the supported UTC date range");
34
+ return { time_zone: "UTC", start_date: from, end_date_exclusive: exclusive };
35
+ }
36
+ function requireCurrentRangeStats(value, from, to) {
37
+ if (!value || typeof value !== "object")
38
+ throw new Error("COMPARISON_REPORT_UNAVAILABLE: Invalid response");
39
+ const report = value;
40
+ let money;
41
+ try {
42
+ money = requireCurrentCostSummary(report.money);
43
+ } catch {
44
+ throw new Error("COMPARISON_REPORT_UNAVAILABLE: The service must support comparison coverage");
45
+ }
46
+ for (const key of ["sessions", "requests", "tokens"]) {
47
+ if (!Number.isSafeInteger(report[key]) || report[key] < 0)
48
+ throw new Error("COMPARISON_REPORT_UNAVAILABLE: Invalid " + key);
49
+ }
50
+ if (report.cost !== money.total_usd || report.requests !== money.request_rows || report.tokens !== money.tokens || money.session_only_sessions !== 0 || money.session_only_value_usd !== 0 || money.requests !== money.request_rows) {
51
+ throw new Error("COMPARISON_REPORT_UNAVAILABLE: Inconsistent monetary coverage");
52
+ }
53
+ const knownRows = money.request_rows - money.unknown_price_requests;
54
+ const completeness = money.request_rows === 0 ? "no_records" : money.unknown_price_requests === 0 ? "complete" : knownRows > 0 ? "partial" : "unavailable";
55
+ if (money.completeness !== completeness || knownRows === 0 && money.total_usd !== 0 || money.sessions > money.request_rows || money.request_rows === 0 && money.tokens !== 0) {
56
+ throw new Error("COMPARISON_REPORT_UNAVAILABLE: Inconsistent request coverage");
57
+ }
58
+ const bounds = money.period_bounds;
59
+ if (!bounds.start_date || !bounds.end_date_exclusive || bounds.start_date >= bounds.end_date_exclusive) {
60
+ throw new Error("COMPARISON_REPORT_UNAVAILABLE: Missing comparison dates");
61
+ }
62
+ if (from !== undefined || to !== undefined) {
63
+ const expected = comparisonDateBounds(from, to);
64
+ if (bounds.start_date !== expected.start_date || bounds.end_date_exclusive !== expected.end_date_exclusive) {
65
+ throw new Error("COMPARISON_REPORT_UNAVAILABLE: Response dates do not match the requested range");
66
+ }
67
+ }
68
+ return report;
69
+ }
70
+ function formatComparisonValue(report) {
71
+ return formatSummaryValue(requireCurrentRangeStats(report).money);
72
+ }
73
+ function comparisonValueChange(left, right) {
74
+ requireCurrentRangeStats(left);
75
+ requireCurrentRangeStats(right);
76
+ const a = left.money.complete_total_usd, b = right.money.complete_total_usd;
77
+ if (a === null || b === null)
78
+ return "unavailable (incomplete usage value)";
79
+ if (b === 0)
80
+ return "unavailable (zero baseline)";
81
+ const change = (a - b) / b * 100;
82
+ if (!Number.isFinite(change))
83
+ return "unavailable (outside supported range)";
84
+ return (change >= 0 ? "+" : "") + change.toFixed(1) + "% usage value";
85
+ }
20
86
  // package.json
21
87
  var package_default = {
22
88
  name: "@hasna/economy",
23
- version: "0.5.6",
89
+ version: "0.5.8",
24
90
  description: "AI coding cost tracker \u2014 CLI + MCP server + REST API for Claude Code, Codex, OpenCode, Cursor, Pi, and Hermes, with legacy Gemini CLI session and Gemini API billing ingestion",
25
91
  repository: {
26
92
  type: "git",
@@ -1281,11 +1347,20 @@ function queryExportRows(db, type, period) {
1281
1347
  return db.prepare(`SELECT * FROM economy_effective_sessions WHERE ${where} ORDER BY started_at DESC`).all();
1282
1348
  }
1283
1349
  function queryRangeStats(db, from, to) {
1284
- const r = db.prepare(`SELECT COALESCE(SUM(cost_usd),0) as cost, COUNT(*) as requests,
1285
- COALESCE(SUM(input_tokens+output_tokens+cache_read_tokens+cache_create_tokens),0) as tokens
1286
- FROM economy_effective_requests WHERE DATE(timestamp) BETWEEN ? AND ?`).get(from, to);
1350
+ const bounds = comparisonDateBounds(from, to);
1351
+ const groups = db.prepare(`
1352
+ SELECT cost_basis, model, CASE WHEN cost_usd = 0 THEN 1 WHEN cost_usd < 0 THEN 2 ELSE 0 END AS zero_cost,
1353
+ SUM(cost_usd) AS cost_usd, COUNT(*) AS requests,
1354
+ COALESCE(SUM(input_tokens),0) AS input_tokens, COALESCE(SUM(output_tokens),0) AS output_tokens,
1355
+ COALESCE(SUM(cache_read_tokens),0) AS cache_read_tokens, COALESCE(SUM(cache_create_tokens),0) AS cache_create_tokens,
1356
+ COALESCE(SUM(cache_create_1h_tokens),0) AS cache_create_1h_tokens
1357
+ FROM economy_effective_requests WHERE DATE(timestamp) BETWEEN ? AND ?
1358
+ GROUP BY cost_basis, model, CASE WHEN cost_usd = 0 THEN 1 WHEN cost_usd < 0 THEN 2 ELSE 0 END
1359
+ `).all(from, to);
1360
+ const requestSessions = db.prepare("SELECT COUNT(DISTINCT session_id) AS sessions FROM economy_effective_requests WHERE DATE(timestamp) BETWEEN ? AND ?").get(from, to);
1361
+ const money = buildCostSummary("all", bounds, groups, { sessions: 0, requests: 0, tokens: 0, cost_usd: 0 }, requestSessions.sessions, listModelPricing(db));
1287
1362
  const s = db.prepare(`SELECT COUNT(*) as sessions FROM economy_effective_sessions WHERE DATE(started_at) BETWEEN ? AND ?`).get(from, to);
1288
- return { cost: r.cost, requests: r.requests, tokens: r.tokens, sessions: s.sessions };
1363
+ return { cost: money.total_usd, money, requests: money.request_rows, tokens: money.tokens, sessions: s.sessions };
1289
1364
  }
1290
1365
  function queryForecast(db, now = new Date) {
1291
1366
  const month = resolveReportingInterval({ kind: "calendar", period: "month" }, now);
@@ -1322,4 +1397,4 @@ function queryModelEfficiency(db) {
1322
1397
  FROM economy_effective_requests GROUP BY model ORDER BY cost DESC`).all();
1323
1398
  }
1324
1399
 
1325
- export { packageMetadata, requireCurrentSavingsReport, querySavingsSummary, queryBillingDiff, requireCurrentBillingDiffSummary, billingDriftCheck, buildBrief, queryProjectDetail, queryExportRows, queryRangeStats, queryForecast, queryModelEfficiency, LOCAL_STORAGE_OPT_IN_KEYS, economyCloudStorage, cloudListItems, cloudObject, economyTransportReport };
1400
+ export { requireCurrentRangeStats, formatComparisonValue, comparisonValueChange, packageMetadata, requireCurrentSavingsReport, querySavingsSummary, queryBillingDiff, requireCurrentBillingDiffSummary, billingDriftCheck, buildBrief, queryProjectDetail, queryExportRows, queryRangeStats, queryForecast, queryModelEfficiency, LOCAL_STORAGE_OPT_IN_KEYS, economyCloudStorage, cloudListItems, cloudObject, economyTransportReport };
@@ -3395,4 +3395,4 @@ function computeCostWithPricing(model, pricing, inputTokens, outputTokens, cache
3395
3395
  return (inputTokens * effective.inputPer1M + outputTokens * effective.outputPer1M + cacheReadTokens * effective.cacheReadPer1M + cacheWriteTokens * effective.cacheWritePer1M + cacheWrite1hTokens * (effective.cacheWrite1hPer1M ?? effective.cacheWritePer1M) + cacheStorageTokenHours * (effective.cacheStoragePer1MHour ?? 0)) / 1e6;
3396
3396
  }
3397
3397
 
3398
- export { __require, AGENTS, COST_BASIS, isAgent, subscriptionId, MAX_INGEST_BYTES, stableJson, canonicalIngestBodyHash, validateIngest, resolveReportingInterval, calendarPeriodBounds, calendarPeriodWhere, usageSnapshotFilterForPeriod, sessionOverlapWhere, dataDir, cacheDir, getMachineId, getHomeDir, getResolverDataRoot, getLegacyDataRoot, adoptResolverDataRoot, getExactDataRoot, getDataDir, getDbPath, initSchema, upsertCostCenter, getCostCenter, upsertRequest, upsertSession, rollupSession, querySessions, queryTopSessions, querySummary, queryZeroCostTokenizedModels, queryModelBreakdown, queryAgentBreakdown, queryProjectBreakdown, queryAccountBreakdown, queryCostCenterBreakdown, queryProjectBreakdownSince, queryAgentBreakdownSince, queryModelBreakdownSince, queryAccountBreakdownSince, queryDailyBreakdown, queryHourlyBreakdown, upsertProject, getProject, listProjects, deleteProject, upsertBudget, listBudgets, deleteBudget, getBudgetStatuses, upsertGoal, deleteGoal, listGoals, getGoalStatuses, getIngestState, loadIngestState, setIngestState, queryRequestsSince, insertFeedback, upsertBillingDaily, clearBillingRange, queryBillingSummary, countBillingRecords, getSessionDetail, listMachines, upsertModelPricing, getModelPricing, listModelPricing, deleteModelPricing, seedModelPricing, upsertSubscription, listSubscriptions, deleteSubscription, upsertUsageSnapshot, upsertScanReceipt, queryScanReceipts, queryUsageSnapshots, listMachineRegistry, dedupeRequests, bulkIngest, DEFAULT_PRICING, normalizeModelName, ensurePricingSeeded, getPricingFromDb, getPricing, computeCost, computeCostFromDb, UnknownModelPricingError, assessCostFromDb, getPricingFromRows, estimateCostFromRows, assessCostFromRows, hasKnownUsagePrice, requireCurrentCostSummary, requireCurrentBillingSummary };
3398
+ export { __require, AGENTS, COST_BASIS, isAgent, subscriptionId, MAX_INGEST_BYTES, stableJson, canonicalIngestBodyHash, validateIngest, resolveReportingInterval, calendarPeriodBounds, calendarPeriodWhere, usageSnapshotFilterForPeriod, sessionOverlapWhere, dataDir, cacheDir, getMachineId, getHomeDir, getResolverDataRoot, getLegacyDataRoot, adoptResolverDataRoot, getExactDataRoot, getDataDir, getDbPath, initSchema, upsertCostCenter, getCostCenter, upsertRequest, upsertSession, rollupSession, querySessions, queryTopSessions, querySummary, queryZeroCostTokenizedModels, queryModelBreakdown, queryAgentBreakdown, queryProjectBreakdown, queryAccountBreakdown, queryCostCenterBreakdown, queryProjectBreakdownSince, queryAgentBreakdownSince, queryModelBreakdownSince, queryAccountBreakdownSince, queryDailyBreakdown, queryHourlyBreakdown, upsertProject, getProject, listProjects, deleteProject, upsertBudget, listBudgets, deleteBudget, getBudgetStatuses, upsertGoal, deleteGoal, listGoals, getGoalStatuses, getIngestState, loadIngestState, setIngestState, queryRequestsSince, insertFeedback, upsertBillingDaily, clearBillingRange, queryBillingSummary, countBillingRecords, getSessionDetail, listMachines, upsertModelPricing, getModelPricing, listModelPricing, deleteModelPricing, seedModelPricing, upsertSubscription, listSubscriptions, deleteSubscription, upsertUsageSnapshot, upsertScanReceipt, queryScanReceipts, queryUsageSnapshots, listMachineRegistry, dedupeRequests, bulkIngest, DEFAULT_PRICING, normalizeModelName, ensurePricingSeeded, getPricingFromDb, getPricing, computeCost, computeCostFromDb, UnknownModelPricingError, assessCostFromDb, getPricingFromRows, estimateCostFromRows, assessCostFromRows, hasKnownUsagePrice, buildCostSummary, requireCurrentCostSummary, requireCurrentBillingSummary };
@@ -3463,4 +3463,4 @@ function computeCostWithPricing(model, pricing, inputTokens, outputTokens, cache
3463
3463
  return (inputTokens * effective.inputPer1M + outputTokens * effective.outputPer1M + cacheReadTokens * effective.cacheReadPer1M + cacheWriteTokens * effective.cacheWritePer1M + cacheWrite1hTokens * (effective.cacheWrite1hPer1M ?? effective.cacheWritePer1M) + cacheStorageTokenHours * (effective.cacheStoragePer1MHour ?? 0)) / 1e6;
3464
3464
  }
3465
3465
 
3466
- export { OBSERVATION_PG_MIGRATIONS, IngestError, observationId, subscriptionId, scanReceiptId, AGENTS, isAgent, parseAgent, MAX_INGEST_ROWS, MAX_INGEST_BYTES, stableJson, canonicalIngestBodyHash, validateIngest, INGEST_SCHEMA_SQL, LEGACY_PG_SQL, reconcileIngestReceipt, resolveReportingInterval, calendarPeriodBounds, calendarPeriodWhere, usageSnapshotFilterForPeriod, sessionOverlapWhere, dataDir, cacheDir, getMachineId, getHomeDir, getResolverDataRoot, getLegacyDataRoot, adoptResolverDataRoot, getExactDataRoot, getDataDir, getDbPath, initSchema, upsertCostCenter, getCostCenter, upsertRequest, upsertSession, rollupSession, querySessions, queryTopSessions, querySummary, queryZeroCostTokenizedModels, queryModelBreakdown, queryAgentBreakdown, queryProjectBreakdown, queryAccountBreakdown, queryCostCenterBreakdown, queryProjectBreakdownSince, queryAgentBreakdownSince, queryModelBreakdownSince, queryAccountBreakdownSince, queryDailyBreakdown, queryHourlyBreakdown, upsertProject, getProject, listProjects, deleteProject, upsertBudget, listBudgets, deleteBudget, getBudgetStatuses, upsertGoal, deleteGoal, listGoals, getGoalStatuses, getIngestState, loadIngestState, setIngestState, queryRequestsSince, insertFeedback, upsertBillingDaily, clearBillingRange, queryBillingSummary, countBillingRecords, getSessionDetail, listMachines, upsertModelPricing, getModelPricing, listModelPricing, deleteModelPricing, seedModelPricing, upsertSubscription, listSubscriptions, deleteSubscription, upsertUsageSnapshot, upsertScanReceipt, queryScanReceipts, queryUsageSnapshots, listMachineRegistry, dedupeRequests, bulkIngest, DEFAULT_PRICING, normalizeModelName, ensurePricingSeeded, getPricingFromDb, getPricing, computeCost, computeCostFromDb, UnknownModelPricingError, assessCostFromDb, getPricingFromRows, estimateCostFromRows, assessCostFromRows, formatReportedUsd, formatPlanMoney, hasKnownUsagePrice, requireCurrentCostSummary, formatSummaryValue, formatSummaryCoverage, requireCurrentBillingSummary, formatBillingValue };
3466
+ export { OBSERVATION_PG_MIGRATIONS, IngestError, observationId, subscriptionId, scanReceiptId, AGENTS, isAgent, parseAgent, MAX_INGEST_ROWS, MAX_INGEST_BYTES, stableJson, canonicalIngestBodyHash, validateIngest, INGEST_SCHEMA_SQL, LEGACY_PG_SQL, reconcileIngestReceipt, resolveReportingInterval, calendarPeriodBounds, calendarPeriodWhere, usageSnapshotFilterForPeriod, sessionOverlapWhere, dataDir, cacheDir, getMachineId, getHomeDir, getResolverDataRoot, getLegacyDataRoot, adoptResolverDataRoot, getExactDataRoot, getDataDir, getDbPath, initSchema, upsertCostCenter, getCostCenter, upsertRequest, upsertSession, rollupSession, querySessions, queryTopSessions, querySummary, queryZeroCostTokenizedModels, queryModelBreakdown, queryAgentBreakdown, queryProjectBreakdown, queryAccountBreakdown, queryCostCenterBreakdown, queryProjectBreakdownSince, queryAgentBreakdownSince, queryModelBreakdownSince, queryAccountBreakdownSince, queryDailyBreakdown, queryHourlyBreakdown, upsertProject, getProject, listProjects, deleteProject, upsertBudget, listBudgets, deleteBudget, getBudgetStatuses, upsertGoal, deleteGoal, listGoals, getGoalStatuses, getIngestState, loadIngestState, setIngestState, queryRequestsSince, insertFeedback, upsertBillingDaily, clearBillingRange, queryBillingSummary, countBillingRecords, getSessionDetail, listMachines, upsertModelPricing, getModelPricing, listModelPricing, deleteModelPricing, seedModelPricing, upsertSubscription, listSubscriptions, deleteSubscription, upsertUsageSnapshot, upsertScanReceipt, queryScanReceipts, queryUsageSnapshots, listMachineRegistry, dedupeRequests, bulkIngest, DEFAULT_PRICING, normalizeModelName, ensurePricingSeeded, getPricingFromDb, getPricing, computeCost, computeCostFromDb, UnknownModelPricingError, assessCostFromDb, getPricingFromRows, estimateCostFromRows, assessCostFromRows, formatReportedUsd, formatPlanMoney, hasKnownUsagePrice, buildCostSummary, requireCurrentCostSummary, formatSummaryValue, formatSummaryCoverage, requireCurrentBillingSummary, formatBillingValue };
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  upsertProject
4
- } from "./index-f5jv6q5q.js";
4
+ } from "./index-zgvmrqyc.js";
5
5
  import"./index-p35cyhc4.js";
6
6
 
7
7
  // src/lib/open-projects.ts
@@ -12,7 +12,7 @@ import {
12
12
  getPricingFromDb,
13
13
  getPricingFromRows,
14
14
  normalizeModelName
15
- } from "./index-c7h2rxx1.js";
15
+ } from "./index-t0n32g8r.js";
16
16
  export {
17
17
  normalizeModelName,
18
18
  getPricingFromRows,
@@ -12,7 +12,7 @@ import {
12
12
  getPricingFromDb,
13
13
  getPricingFromRows,
14
14
  normalizeModelName
15
- } from "./index-f5jv6q5q.js";
15
+ } from "./index-zgvmrqyc.js";
16
16
  import"./index-p35cyhc4.js";
17
17
  export {
18
18
  normalizeModelName,
@@ -12,7 +12,7 @@ import {
12
12
  getPricingFromDb,
13
13
  getPricingFromRows,
14
14
  normalizeModelName
15
- } from "./index-vajzfzgv.js";
15
+ } from "./index-ep1pkyr3.js";
16
16
  import"./index-p35cyhc4.js";
17
17
  export {
18
18
  normalizeModelName,
@@ -5,7 +5,7 @@ import {
5
5
  } from "./index-w3bvv0ns.js";
6
6
  import {
7
7
  syncAll
8
- } from "./index-qvcafabj.js";
8
+ } from "./index-9za4cmq2.js";
9
9
  import {
10
10
  buildBrief,
11
11
  packageMetadata,
@@ -16,7 +16,7 @@ import {
16
16
  queryProjectDetail,
17
17
  queryRangeStats,
18
18
  querySavingsSummary
19
- } from "./index-m12xttw1.js";
19
+ } from "./index-h2mcj7gv.js";
20
20
  import {
21
21
  AGENTS,
22
22
  INGEST_SCHEMA_SQL,
@@ -67,7 +67,7 @@ import {
67
67
  upsertProject,
68
68
  upsertSubscription,
69
69
  usageSnapshotFilterForPeriod
70
- } from "./index-f5jv6q5q.js";
70
+ } from "./index-zgvmrqyc.js";
71
71
  import {
72
72
  __require
73
73
  } from "./index-p35cyhc4.js";
@@ -3910,7 +3910,7 @@ function createDataHandler(db, actorId) {
3910
3910
  if (providers.some((provider) => !allowedProviders.has(provider)))
3911
3911
  return err("invalid billing provider");
3912
3912
  const results = {};
3913
- const { syncAnthropicBilling, syncOpenAIBilling, syncGeminiBilling } = await import("./billing-22az60hy.js");
3913
+ const { syncAnthropicBilling, syncOpenAIBilling, syncGeminiBilling } = await import("./billing-7twygmtj.js");
3914
3914
  async function capture(provider, fn) {
3915
3915
  try {
3916
3916
  results[provider] = await fn();
@@ -4065,7 +4065,7 @@ function createDataHandler(db, actorId) {
4065
4065
  const results = {};
4066
4066
  if (sources === "all") {
4067
4067
  try {
4068
- const { syncOpenProjectsRegistry } = await import("./open-projects-8qm46m3d.js");
4068
+ const { syncOpenProjectsRegistry } = await import("./open-projects-bj561k5j.js");
4069
4069
  results["projects"] = await syncOpenProjectsRegistry(db);
4070
4070
  } catch {}
4071
4071
  }
@@ -4073,7 +4073,7 @@ function createDataHandler(db, actorId) {
4073
4073
  const syncResult = await syncAll(db, selected);
4074
4074
  Object.assign(results, syncResult);
4075
4075
  try {
4076
- const { checkAndFireWebhooks } = await import("./webhooks-nw4daw9y.js");
4076
+ const { checkAndFireWebhooks } = await import("./webhooks-td46p6gk.js");
4077
4077
  await checkAndFireWebhooks(db);
4078
4078
  } catch {}
4079
4079
  return ok(results);
@@ -4097,7 +4097,7 @@ function createDataHandler(db, actorId) {
4097
4097
  return err("invalid JSON body");
4098
4098
  const result = bulkIngest(db, body, { actorId });
4099
4099
  try {
4100
- const { checkAndFireWebhooks } = await import("./webhooks-nw4daw9y.js");
4100
+ const { checkAndFireWebhooks } = await import("./webhooks-td46p6gk.js");
4101
4101
  if (body["budget_mode"] !== "create")
4102
4102
  await checkAndFireWebhooks(db);
4103
4103
  } catch {}
@@ -4150,7 +4150,13 @@ function createDataHandler(db, actorId) {
4150
4150
  const to = url.searchParams.get("to")?.trim();
4151
4151
  if (!from || !to)
4152
4152
  return err("from and to are required (YYYY-MM-DD)");
4153
- return ok(queryRangeStats(db, from, to));
4153
+ try {
4154
+ return ok(queryRangeStats(db, from, to));
4155
+ } catch (error) {
4156
+ if (error instanceof RangeError)
4157
+ return err(error.message);
4158
+ throw error;
4159
+ }
4154
4160
  }
4155
4161
  if (path === "/api/forecast" && method === "GET") {
4156
4162
  return ok(queryForecast(db));
@@ -70,7 +70,7 @@ import {
70
70
  upsertSession,
71
71
  upsertSubscription,
72
72
  upsertUsageSnapshot
73
- } from "./index-c7h2rxx1.js";
73
+ } from "./index-t0n32g8r.js";
74
74
 
75
75
  // src/db/sqlite-adapter.ts
76
76
  import { Database } from "bun:sqlite";
@@ -178,7 +178,7 @@ function openDatabase(dbPath, skipSeed = false) {
178
178
  }
179
179
  }, `opening ${path}`);
180
180
  if (!skipSeed) {
181
- import("./pricing-k9wsjwbz.js").then(({ ensurePricingSeeded }) => ensurePricingSeeded(db)).catch(() => {});
181
+ import("./pricing-bkgvzpe9.js").then(({ ensurePricingSeeded }) => ensurePricingSeeded(db)).catch(() => {});
182
182
  }
183
183
  return db;
184
184
  }
@@ -69,7 +69,7 @@ import {
69
69
  upsertSession,
70
70
  upsertSubscription,
71
71
  upsertUsageSnapshot
72
- } from "./index-f5jv6q5q.js";
72
+ } from "./index-ep1pkyr3.js";
73
73
  import {
74
74
  __require
75
75
  } from "./index-p35cyhc4.js";
@@ -180,7 +180,7 @@ function openDatabase(dbPath, skipSeed = false) {
180
180
  }
181
181
  }, `opening ${path}`);
182
182
  if (!skipSeed) {
183
- import("./pricing-462f8xkm.js").then(({ ensurePricingSeeded }) => ensurePricingSeeded(db)).catch(() => {});
183
+ import("./pricing-nt31hf53.js").then(({ ensurePricingSeeded }) => ensurePricingSeeded(db)).catch(() => {});
184
184
  }
185
185
  return db;
186
186
  }
@@ -69,7 +69,7 @@ import {
69
69
  upsertSession,
70
70
  upsertSubscription,
71
71
  upsertUsageSnapshot
72
- } from "./index-vajzfzgv.js";
72
+ } from "./index-zgvmrqyc.js";
73
73
  import {
74
74
  __require
75
75
  } from "./index-p35cyhc4.js";
@@ -180,7 +180,7 @@ function openDatabase(dbPath, skipSeed = false) {
180
180
  }
181
181
  }, `opening ${path}`);
182
182
  if (!skipSeed) {
183
- import("./pricing-vxejj1qa.js").then(({ ensurePricingSeeded }) => ensurePricingSeeded(db)).catch(() => {});
183
+ import("./pricing-bn88mhqk.js").then(({ ensurePricingSeeded }) => ensurePricingSeeded(db)).catch(() => {});
184
184
  }
185
185
  return db;
186
186
  }
@@ -6,11 +6,11 @@ import {
6
6
  printStatusLine,
7
7
  printWaybarJson,
8
8
  runTui
9
- } from "./index-zqsx461z.js";
9
+ } from "./index-gf3kan31.js";
10
10
  import"./index-w3bvv0ns.js";
11
- import"./index-zs5dba3t.js";
12
- import"./index-m12xttw1.js";
13
- import"./index-f5jv6q5q.js";
11
+ import"./index-a1gh3d6t.js";
12
+ import"./index-h2mcj7gv.js";
13
+ import"./index-zgvmrqyc.js";
14
14
  import"./index-p35cyhc4.js";
15
15
  export {
16
16
  runTui,
@@ -2,15 +2,15 @@
2
2
  import {
3
3
  agentPaths,
4
4
  syncAll
5
- } from "./index-qvcafabj.js";
5
+ } from "./index-9za4cmq2.js";
6
6
  import {
7
7
  getStore,
8
8
  isCloudStore
9
- } from "./index-zs5dba3t.js";
10
- import"./index-m12xttw1.js";
9
+ } from "./index-a1gh3d6t.js";
10
+ import"./index-h2mcj7gv.js";
11
11
  import {
12
12
  formatSummaryValue
13
- } from "./index-f5jv6q5q.js";
13
+ } from "./index-zgvmrqyc.js";
14
14
  import {
15
15
  __require
16
16
  } from "./index-p35cyhc4.js";
@@ -86,7 +86,7 @@ function agentLabel(agent) {
86
86
  async function watchCosts(opts) {
87
87
  const store = getStore();
88
88
  const cloud = isCloudStore();
89
- const db = cloud ? null : (await import("./sqlite-store-13nhr1z0.js")).openDatabase();
89
+ const db = cloud ? null : (await import("./sqlite-store-r219qrjt.js")).openDatabase();
90
90
  let lastCheck = new Date(Date.now() - opts.interval * 1000).toISOString();
91
91
  const lines = [];
92
92
  const MAX_LINES = 20;
@@ -1,13 +1,13 @@
1
1
  // @bun
2
2
  import {
3
3
  loadConfig
4
- } from "./index-9wa1f2kv.js";
4
+ } from "./index-7ek4r0ww.js";
5
5
  import {
6
6
  getBudgetStatuses,
7
7
  getIngestState,
8
8
  resolveReportingInterval,
9
9
  setIngestState
10
- } from "./index-f5jv6q5q.js";
10
+ } from "./index-zgvmrqyc.js";
11
11
  import"./index-p35cyhc4.js";
12
12
 
13
13
  // src/lib/spikes.ts