@hasna/economy 0.4.0 → 0.5.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.
Files changed (205) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +12 -9
  3. package/dist/chunks/agent-registry-store-tpnhx3wj.js +39 -0
  4. package/dist/chunks/billing-bkpxy4kv.js +13 -0
  5. package/dist/chunks/config-j9mv3ehk.js +15 -0
  6. package/dist/chunks/index-2hwzmfgv.js +3407 -0
  7. package/dist/chunks/index-49f12css.js +124 -0
  8. package/dist/chunks/index-d480p2wh.js +1322 -0
  9. package/dist/chunks/index-ez9thsr7.js +3440 -0
  10. package/dist/chunks/index-hesxq90g.js +62 -0
  11. package/dist/chunks/index-k540hfww.js +258 -0
  12. package/dist/chunks/index-p35cyhc4.js +4 -0
  13. package/dist/chunks/index-r1jv3kpy.js +451 -0
  14. package/dist/chunks/index-w3bvv0ns.js +26 -0
  15. package/dist/chunks/index-xsah93s2.js +2085 -0
  16. package/dist/chunks/index-zpvea08j.js +3372 -0
  17. package/dist/chunks/menubar-6xtkt17h.js +296 -0
  18. package/dist/chunks/open-projects-6z4pq6mx.js +39 -0
  19. package/dist/chunks/pricing-f80p81gr.js +29 -0
  20. package/dist/chunks/pricing-vf2pycmh.js +30 -0
  21. package/dist/chunks/pricing-y21mcjsa.js +30 -0
  22. package/dist/chunks/serve-2knem98x.js +4655 -0
  23. package/dist/chunks/sqlite-store-501f32ts.js +258 -0
  24. package/dist/chunks/sqlite-store-fq4natnf.js +256 -0
  25. package/dist/chunks/sqlite-store-st99garx.js +258 -0
  26. package/dist/chunks/third-party-sqlite-5e85fxa2.js +11 -0
  27. package/dist/chunks/tui-khmnkat2.js +22 -0
  28. package/dist/chunks/watch-4y064yys.js +196 -0
  29. package/dist/chunks/webhooks-k4fh2t9c.js +109 -0
  30. package/dist/cli/commands/brief.d.ts.map +1 -1
  31. package/dist/cli/commands/extras.d.ts.map +1 -1
  32. package/dist/cli/commands/journal.d.ts +3 -0
  33. package/dist/cli/commands/journal.d.ts.map +1 -0
  34. package/dist/cli/commands/menubar.d.ts +97 -4
  35. package/dist/cli/commands/menubar.d.ts.map +1 -1
  36. package/dist/cli/commands/tui.d.ts +1 -1
  37. package/dist/cli/commands/tui.d.ts.map +1 -1
  38. package/dist/cli/commands/watch.d.ts.map +1 -1
  39. package/dist/cli/index.js +1358 -10114
  40. package/dist/db/cloud.d.ts +7 -9
  41. package/dist/db/cloud.d.ts.map +1 -1
  42. package/dist/db/database.d.ts +14 -12
  43. package/dist/db/database.d.ts.map +1 -1
  44. package/dist/db/ingest-concurrency-worker.d.ts +2 -0
  45. package/dist/db/ingest-concurrency-worker.d.ts.map +1 -0
  46. package/dist/db/ingest-errors.d.ts +9 -0
  47. package/dist/db/ingest-errors.d.ts.map +1 -0
  48. package/dist/db/ingest-schema.d.ts +3 -0
  49. package/dist/db/ingest-schema.d.ts.map +1 -0
  50. package/dist/db/ingest-specs.d.ts +8 -0
  51. package/dist/db/ingest-specs.d.ts.map +1 -0
  52. package/dist/db/ingest-test-contract.d.ts +3 -0
  53. package/dist/db/ingest-test-contract.d.ts.map +1 -0
  54. package/dist/db/ingest-validation.d.ts +12 -0
  55. package/dist/db/ingest-validation.d.ts.map +1 -0
  56. package/dist/db/ingest.d.ts +27 -0
  57. package/dist/db/ingest.d.ts.map +1 -0
  58. package/dist/db/legacy-schema.d.ts +7 -0
  59. package/dist/db/legacy-schema.d.ts.map +1 -0
  60. package/dist/db/observation-contract.d.ts +3 -0
  61. package/dist/db/observation-contract.d.ts.map +1 -0
  62. package/dist/db/observation-provenance.d.ts +23 -0
  63. package/dist/db/observation-provenance.d.ts.map +1 -0
  64. package/dist/db/observation-schema.d.ts +24 -0
  65. package/dist/db/observation-schema.d.ts.map +1 -0
  66. package/dist/db/pg-connection.d.ts +10 -0
  67. package/dist/db/pg-connection.d.ts.map +1 -0
  68. package/dist/db/pg-legacy-schema.d.ts +12 -0
  69. package/dist/db/pg-legacy-schema.d.ts.map +1 -0
  70. package/dist/db/pg-migrate.d.ts +4 -9
  71. package/dist/db/pg-migrate.d.ts.map +1 -1
  72. package/dist/db/pg-migrations.d.ts.map +1 -1
  73. package/dist/db/pg-protocol.d.ts +28 -0
  74. package/dist/db/pg-protocol.d.ts.map +1 -0
  75. package/dist/db/sqlite-store.d.ts +4 -0
  76. package/dist/db/sqlite-store.d.ts.map +1 -0
  77. package/dist/db/sync-pg.d.ts +17 -21
  78. package/dist/db/sync-pg.d.ts.map +1 -1
  79. package/dist/db/third-party-sqlite.d.ts +10 -0
  80. package/dist/db/third-party-sqlite.d.ts.map +1 -0
  81. package/dist/index.d.ts +3 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +1171 -2465
  84. package/dist/ingest/claude-quota.d.ts.map +1 -1
  85. package/dist/ingest/claude.d.ts.map +1 -1
  86. package/dist/ingest/codex-quota.d.ts.map +1 -1
  87. package/dist/ingest/codex.d.ts +25 -0
  88. package/dist/ingest/codex.d.ts.map +1 -1
  89. package/dist/ingest/collection-outcome.d.ts +17 -0
  90. package/dist/ingest/collection-outcome.d.ts.map +1 -0
  91. package/dist/ingest/cursor.d.ts.map +1 -1
  92. package/dist/ingest/gemini.d.ts.map +1 -1
  93. package/dist/ingest/hermes.d.ts +1 -1
  94. package/dist/ingest/hermes.d.ts.map +1 -1
  95. package/dist/ingest/loops.d.ts.map +1 -1
  96. package/dist/ingest/opencode.d.ts +1 -1
  97. package/dist/ingest/opencode.d.ts.map +1 -1
  98. package/dist/ingest/pi.d.ts +1 -1
  99. package/dist/ingest/pi.d.ts.map +1 -1
  100. package/dist/ingest/quota-observation.d.ts +16 -0
  101. package/dist/ingest/quota-observation.d.ts.map +1 -0
  102. package/dist/ingest/source-time.d.ts +4 -0
  103. package/dist/ingest/source-time.d.ts.map +1 -0
  104. package/dist/lib/accounts-store.d.ts +39 -13
  105. package/dist/lib/accounts-store.d.ts.map +1 -1
  106. package/dist/lib/analytics.d.ts.map +1 -1
  107. package/dist/lib/api-display-url.d.ts +1 -1
  108. package/dist/lib/autosync-gate.d.ts +12 -5
  109. package/dist/lib/autosync-gate.d.ts.map +1 -1
  110. package/dist/lib/billing-diff.d.ts +18 -40
  111. package/dist/lib/billing-diff.d.ts.map +1 -1
  112. package/dist/lib/brief.d.ts +2 -0
  113. package/dist/lib/brief.d.ts.map +1 -1
  114. package/dist/lib/budget-decimal.d.ts +14 -0
  115. package/dist/lib/budget-decimal.d.ts.map +1 -0
  116. package/dist/lib/cloud-ingest.d.ts +15 -0
  117. package/dist/lib/cloud-ingest.d.ts.map +1 -1
  118. package/dist/lib/cloud-storage.d.ts.map +1 -1
  119. package/dist/lib/ingest-batches.d.ts +21 -0
  120. package/dist/lib/ingest-batches.d.ts.map +1 -0
  121. package/dist/lib/ingest-journal-client.d.ts +37 -0
  122. package/dist/lib/ingest-journal-client.d.ts.map +1 -0
  123. package/dist/lib/ingest-journal-lock.d.ts +5 -0
  124. package/dist/lib/ingest-journal-lock.d.ts.map +1 -0
  125. package/dist/lib/ingest-journal-maintenance.d.ts +92 -0
  126. package/dist/lib/ingest-journal-maintenance.d.ts.map +1 -0
  127. package/dist/lib/ingest-journal-operation.d.ts +55 -0
  128. package/dist/lib/ingest-journal-operation.d.ts.map +1 -0
  129. package/dist/lib/ingest-journal.d.ts +73 -0
  130. package/dist/lib/ingest-journal.d.ts.map +1 -0
  131. package/dist/lib/money-display.d.ts +13 -0
  132. package/dist/lib/money-display.d.ts.map +1 -0
  133. package/dist/lib/periods.d.ts +12 -0
  134. package/dist/lib/periods.d.ts.map +1 -1
  135. package/dist/lib/pricing.d.ts +14 -0
  136. package/dist/lib/pricing.d.ts.map +1 -1
  137. package/dist/lib/savings.d.ts +64 -7
  138. package/dist/lib/savings.d.ts.map +1 -1
  139. package/dist/lib/store/index.d.ts +25 -21
  140. package/dist/lib/store/index.d.ts.map +1 -1
  141. package/dist/lib/summary-contract.d.ts +32 -0
  142. package/dist/lib/summary-contract.d.ts.map +1 -0
  143. package/dist/lib/summary-test-contract.d.ts +3 -0
  144. package/dist/lib/summary-test-contract.d.ts.map +1 -0
  145. package/dist/lib/sync-all.d.ts +4 -0
  146. package/dist/lib/sync-all.d.ts.map +1 -1
  147. package/dist/lib/sync-maintenance.d.ts.map +1 -1
  148. package/dist/lib/sync-report.d.ts +4 -0
  149. package/dist/lib/sync-report.d.ts.map +1 -0
  150. package/dist/lib/test-keychain-fixture.d.ts +9 -0
  151. package/dist/lib/test-keychain-fixture.d.ts.map +1 -0
  152. package/dist/mcp/agent-registry-store.d.ts +30 -0
  153. package/dist/mcp/agent-registry-store.d.ts.map +1 -0
  154. package/dist/mcp/agent-registry.d.ts +9 -16
  155. package/dist/mcp/agent-registry.d.ts.map +1 -1
  156. package/dist/mcp/index.js +2291 -3458
  157. package/dist/mcp/ingest-journal-tool.d.ts +2 -0
  158. package/dist/mcp/ingest-journal-tool.d.ts.map +1 -0
  159. package/dist/mcp/server.d.ts.map +1 -1
  160. package/dist/openapi.d.ts.map +1 -1
  161. package/dist/otel/index.js +1960 -289
  162. package/dist/server/human-auth.d.ts +20 -0
  163. package/dist/server/human-auth.d.ts.map +1 -0
  164. package/dist/server/index.js +10639 -6720
  165. package/dist/server/legacy-inventory.d.ts +52 -0
  166. package/dist/server/legacy-inventory.d.ts.map +1 -0
  167. package/dist/server/legacy-operations.d.ts +64 -0
  168. package/dist/server/legacy-operations.d.ts.map +1 -0
  169. package/dist/server/legacy-plan.d.ts +55 -0
  170. package/dist/server/legacy-plan.d.ts.map +1 -0
  171. package/dist/server/legacy-preservation.d.ts +58 -0
  172. package/dist/server/legacy-preservation.d.ts.map +1 -0
  173. package/dist/server/pg-sync-worker.js +195 -21
  174. package/dist/server/serve.d.ts +20 -16
  175. package/dist/server/serve.d.ts.map +1 -1
  176. package/dist/server/service-admission.d.ts +10 -0
  177. package/dist/server/service-admission.d.ts.map +1 -0
  178. package/dist/server/service-dispatcher.d.ts +45 -0
  179. package/dist/server/service-dispatcher.d.ts.map +1 -0
  180. package/dist/server/service-operations.d.ts +5 -0
  181. package/dist/server/service-operations.d.ts.map +1 -0
  182. package/dist/server/service-protocol.d.ts +50 -0
  183. package/dist/server/service-protocol.d.ts.map +1 -0
  184. package/dist/server/service-worker.d.ts +2 -0
  185. package/dist/server/service-worker.d.ts.map +1 -0
  186. package/dist/server/service-worker.js +8038 -0
  187. package/dist/types/index.d.ts +66 -0
  188. package/dist/types/index.d.ts.map +1 -1
  189. package/docs/README.md +1 -1
  190. package/docs/cli.md +1 -1
  191. package/docs/configuration.md +5 -5
  192. package/docs/cost-reporting.md +49 -0
  193. package/docs/historical-data-reconciliation.md +203 -0
  194. package/docs/ingest-journal.md +108 -0
  195. package/docs/ingestion.md +60 -4
  196. package/docs/mcp.md +2 -2
  197. package/docs/native-budget-save.md +84 -0
  198. package/docs/native-human-auth.md +102 -0
  199. package/docs/postgresql-legacy-schema-repair.md +30 -0
  200. package/docs/rest-api.md +2 -2
  201. package/package.json +25 -13
  202. package/dist/lib/test-hermetic-accounts.d.ts +0 -7
  203. package/dist/lib/test-hermetic-accounts.d.ts.map +0 -1
  204. package/dist/lib/test-hermetic-fleet-env.d.ts +0 -4
  205. package/dist/lib/test-hermetic-fleet-env.d.ts.map +0 -1
@@ -0,0 +1,124 @@
1
+ // @bun
2
+ import {
3
+ getServeApiToken
4
+ } from "./index-w3bvv0ns.js";
5
+ import {
6
+ getStore
7
+ } from "./index-r1jv3kpy.js";
8
+ import {
9
+ formatReportedUsd,
10
+ formatSummaryCoverage,
11
+ formatSummaryValue
12
+ } from "./index-ez9thsr7.js";
13
+
14
+ // src/cli/commands/tui.ts
15
+ import chalk from "chalk";
16
+ function topAgentFrom(rows) {
17
+ let top;
18
+ for (const row of rows) {
19
+ if (!top || row.cost_usd > top.cost_usd)
20
+ top = row;
21
+ }
22
+ return top?.agent ?? "\u2014";
23
+ }
24
+ function quotaFrom(snapshots) {
25
+ const claude = snapshots.find((s) => s.agent === "claude" && s.metric === "five_hour_utilization");
26
+ const codex = snapshots.find((s) => s.agent === "codex" && s.metric === "five_hour_utilization");
27
+ const parts = [];
28
+ if (claude)
29
+ parts.push(`claude ${claude.value.toFixed(0)}%`);
30
+ if (codex)
31
+ parts.push(`codex ${codex.value.toFixed(0)}%`);
32
+ return parts.length ? parts.join(" \xB7 ") : null;
33
+ }
34
+ async function gatherStatusData(store = getStore()) {
35
+ const [today, week, month, savings, machines, agents, usage] = await Promise.all([
36
+ store.summary("today"),
37
+ store.summary("week"),
38
+ store.summary("month"),
39
+ store.savings("month"),
40
+ store.machines(),
41
+ store.agentBreakdown({ period: "month" }),
42
+ store.usage("today")
43
+ ]);
44
+ return {
45
+ today,
46
+ week,
47
+ month,
48
+ savings,
49
+ machineCount: machines.length,
50
+ topAgent: topAgentFrom(agents),
51
+ quota: quotaFrom(usage?.snapshots ?? []),
52
+ transport: store.transport
53
+ };
54
+ }
55
+ function modeLabel(transport) {
56
+ return transport === "cloud-http" ? "hosted" : "local";
57
+ }
58
+ function buildStatusLine(data) {
59
+ const parts = [
60
+ `today ${formatSummaryValue(data.today)}`,
61
+ `week ${formatSummaryValue(data.week)}`,
62
+ `top ${data.topAgent}`,
63
+ `${data.machineCount} machines`,
64
+ modeLabel(data.transport),
65
+ "UTC; stored records only; source coverage unverified"
66
+ ];
67
+ if (data.quota)
68
+ parts.push(data.quota);
69
+ return parts.join(" \xB7 ");
70
+ }
71
+ function buildWaybarJson(data) {
72
+ return {
73
+ text: formatSummaryValue(data.today),
74
+ tooltip: buildStatusLine(data),
75
+ class: data.quota?.includes("%") && Number(data.quota.match(/(\d+)%/)?.[1] ?? 0) >= 80 ? "warning" : "default",
76
+ percentage: null,
77
+ summary: data.today,
78
+ summary_coverage: formatSummaryCoverage(data.today),
79
+ savings_usd: data.savings.saved_usd,
80
+ comparison_status: data.savings.comparison_status
81
+ };
82
+ }
83
+ async function printStatusLine() {
84
+ console.log(buildStatusLine(await gatherStatusData()));
85
+ }
86
+ async function printWaybarJson() {
87
+ console.log(JSON.stringify(buildWaybarJson(await gatherStatusData())));
88
+ }
89
+ async function runTui(opts) {
90
+ const interval = opts.interval ?? 30;
91
+ const render = async () => {
92
+ const data = await gatherStatusData();
93
+ process.stdout.write("\x1B[H\x1B[2J");
94
+ console.log(chalk.bold.cyan(" economy"));
95
+ console.log(chalk.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
96
+ console.log(` Today ${chalk.green(formatSummaryValue(data.today))} ${data.today.sessions} sessions`);
97
+ console.log(` Week ${formatSummaryValue(data.week)} ${data.week.sessions} sessions`);
98
+ console.log(` Month ${formatSummaryValue(data.month)} estimated plan benefit ${formatReportedUsd(data.savings.saved_usd)}`);
99
+ console.log(chalk.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
100
+ console.log(` ${formatSummaryCoverage(data.today)}`);
101
+ console.log(` Top agent: ${data.topAgent}`);
102
+ if (data.quota)
103
+ console.log(` Quota: ${data.quota}`);
104
+ console.log(` Fleet: ${data.machineCount} machines`);
105
+ console.log(` Store: ${data.transport === "cloud-http" ? "hosted API" : "local"}`);
106
+ if (getServeApiToken())
107
+ console.log(chalk.dim(" API auth: HASNA_ECONOMY_API_TOKEN set"));
108
+ console.log(chalk.dim(`
109
+ ${opts.watch ? `Refreshing every ${interval}s \u2014 Ctrl+C to exit` : "Run with --watch for live refresh"}`));
110
+ };
111
+ await render();
112
+ if (!opts.watch)
113
+ return;
114
+ const timer = setInterval(() => {
115
+ render();
116
+ }, interval * 1000);
117
+ process.on("SIGINT", () => {
118
+ clearInterval(timer);
119
+ process.exit(0);
120
+ });
121
+ await new Promise(() => {});
122
+ }
123
+
124
+ export { gatherStatusData, buildStatusLine, buildWaybarJson, printStatusLine, printWaybarJson, runTui };