@cliftonc/finius 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -0
  3. package/dist/branding.js +28 -0
  4. package/dist/cli/backfill.js +122 -0
  5. package/dist/cli/claude-settings.js +54 -0
  6. package/dist/cli/codex-config.js +60 -0
  7. package/dist/cli/codex.js +97 -0
  8. package/dist/cli/config.js +41 -0
  9. package/dist/cli/doctor.js +159 -0
  10. package/dist/cli/hook.js +70 -0
  11. package/dist/cli/identity.js +163 -0
  12. package/dist/cli/import.js +61 -0
  13. package/dist/cli/index.js +70 -0
  14. package/dist/cli/install.js +23 -0
  15. package/dist/cli/password.js +14 -0
  16. package/dist/cli/serve.js +63 -0
  17. package/dist/cli/setup.js +314 -0
  18. package/dist/cli/ui.js +15 -0
  19. package/dist/client/assets/TranscriptView-CBf7-4Bo.css +1 -0
  20. package/dist/client/assets/TranscriptView-CLCPX5bI.js +194 -0
  21. package/dist/client/assets/TranscriptView-D056GDHO.js +194 -0
  22. package/dist/client/assets/TranscriptView-MIgsAwMN.js +194 -0
  23. package/dist/client/assets/index-6OIY_8fO.css +1 -0
  24. package/dist/client/assets/index-9aN8py7_.js +1 -0
  25. package/dist/client/assets/index-B-sjMmTS.js +1636 -0
  26. package/dist/client/assets/index-B4HbP3X6.js +1 -0
  27. package/dist/client/assets/index-B9wgN1BV.js +1636 -0
  28. package/dist/client/assets/index-BHlFz1Th.js +1652 -0
  29. package/dist/client/assets/index-BJyvYca7.js +1636 -0
  30. package/dist/client/assets/index-BKBTeJLz.js +1 -0
  31. package/dist/client/assets/index-BN6CbirS.js +1444 -0
  32. package/dist/client/assets/index-BW4_7xR6.js +1460 -0
  33. package/dist/client/assets/index-BaLElA30.js +1 -0
  34. package/dist/client/assets/index-BaQ02V5d.css +1 -0
  35. package/dist/client/assets/index-Bh0dgUU-.js +1636 -0
  36. package/dist/client/assets/index-Bie86XRc.js +1 -0
  37. package/dist/client/assets/index-Bijt5al-.css +1 -0
  38. package/dist/client/assets/index-BikJP2HS.js +1636 -0
  39. package/dist/client/assets/index-BkwrvP-J.js +1 -0
  40. package/dist/client/assets/index-BwVuUJSv.js +1 -0
  41. package/dist/client/assets/index-BweXI4-D.css +1 -0
  42. package/dist/client/assets/index-BwqdHcDE.js +1 -0
  43. package/dist/client/assets/index-C-Z0w-tQ.js +1652 -0
  44. package/dist/client/assets/index-C2RmKzem.js +1636 -0
  45. package/dist/client/assets/index-CHz-iKIQ.js +1 -0
  46. package/dist/client/assets/index-CIGl5oW_.js +1646 -0
  47. package/dist/client/assets/index-CVYmd4Bm.js +1465 -0
  48. package/dist/client/assets/index-Ca9UVGK1.js +1 -0
  49. package/dist/client/assets/index-CeWDkmJN.js +1 -0
  50. package/dist/client/assets/index-CpsNq0zm.css +1 -0
  51. package/dist/client/assets/index-CrUS6abD.css +1 -0
  52. package/dist/client/assets/index-Ctq8vj2Z.js +1 -0
  53. package/dist/client/assets/index-D1ktp0pp.js +1 -0
  54. package/dist/client/assets/index-D3BoYpFi.css +1 -0
  55. package/dist/client/assets/index-D59GxlrT.js +1636 -0
  56. package/dist/client/assets/index-D5Wkww8x.css +1 -0
  57. package/dist/client/assets/index-DC94jMGe.js +1 -0
  58. package/dist/client/assets/index-DFcIBkv1.js +1652 -0
  59. package/dist/client/assets/index-DmKj5Jqc.css +1 -0
  60. package/dist/client/assets/index-Dx52i05H.js +1465 -0
  61. package/dist/client/assets/index-L3GnPzmU.css +1 -0
  62. package/dist/client/assets/index-OZADsKet.js +1652 -0
  63. package/dist/client/assets/index-Qt124kj1.js +1652 -0
  64. package/dist/client/assets/index-nHzwQ3EM.js +1 -0
  65. package/dist/client/assets/index-s9Mg6LTO.js +1 -0
  66. package/dist/client/assets/index-ye8oxz8P.js +1 -0
  67. package/dist/client/assets/index-yqJS7tUY.css +1 -0
  68. package/dist/client/favicon.svg +35 -0
  69. package/dist/client/finius-dashboard.png +0 -0
  70. package/dist/client/index.html +38 -0
  71. package/dist/server/app.js +285 -0
  72. package/dist/server/claude.js +124 -0
  73. package/dist/server/codex.js +94 -0
  74. package/dist/server/events.js +12 -0
  75. package/dist/server/index.js +119 -0
  76. package/dist/server/otel.js +231 -0
  77. package/dist/server/pricing-backfill.js +41 -0
  78. package/dist/server/pricing.js +138 -0
  79. package/dist/server/queue.js +35 -0
  80. package/dist/server/storage/blob.js +17 -0
  81. package/dist/server/storage/query-helpers.js +104 -0
  82. package/dist/server/storage/sqlite.js +1167 -0
  83. package/dist/server/transcripts.js +46 -0
  84. package/dist/server/types.js +1 -0
  85. package/dist/shared/api-types.js +1 -0
  86. package/package.json +72 -0
@@ -0,0 +1,104 @@
1
+ export const GRANULARITY_MS = {
2
+ minute: 60_000,
3
+ five_minute: 300_000,
4
+ quarter_hour: 900_000,
5
+ hour: 3_600_000,
6
+ day: 86_400_000,
7
+ week: 604_800_000
8
+ };
9
+ // The source OTel metrics ingest under (see parseOtelMetricPoints). JSONL transcripts ingest under a
10
+ // different source ('claude-code-jsonl'), so this is also the authoritative side of precedence.
11
+ export const OTEL_SOURCE = "claude-code";
12
+ export function canUseRollup(filters, granularity) {
13
+ if (filters.session != null)
14
+ return false;
15
+ // An explicit non-OTel source filter is the comparison view: it must see ALL of that source's
16
+ // (JSONL) points, including ones shadowed by OTel, which the effective rollup omits. Serve those
17
+ // from metric_points instead, where an explicit source filter returns the raw per-source numbers.
18
+ if (filters.source != null && filters.source !== OTEL_SOURCE)
19
+ return false;
20
+ if (granularity != null && GRANULARITY_MS[granularity] < GRANULARITY_MS.hour)
21
+ return false;
22
+ return hourAligned(filters.from) && hourAligned(filters.to);
23
+ }
24
+ export function rollupWhere(filters) {
25
+ const clauses = [];
26
+ const params = [];
27
+ if (filters.from) {
28
+ clauses.push("bucket >= ?");
29
+ params.push(filters.from);
30
+ }
31
+ if (filters.to) {
32
+ clauses.push("bucket <= ?");
33
+ params.push(filters.to);
34
+ }
35
+ if (filters.user) {
36
+ clauses.push("user_identity = ?");
37
+ params.push(filters.user);
38
+ }
39
+ if (filters.model) {
40
+ clauses.push("model = ?");
41
+ params.push(filters.model);
42
+ }
43
+ if (filters.source) {
44
+ clauses.push("source = ?");
45
+ params.push(filters.source);
46
+ }
47
+ return { where: clauses.length ? `WHERE ${clauses.join(" AND ")}` : "", params };
48
+ }
49
+ export const EFFECTIVE_ROLLUP = `(
50
+ SELECT bucket, source, user_identity, model, kind, token_type, sum_value FROM metric_rollup
51
+ UNION ALL
52
+ SELECT
53
+ CAST(timestamp / 3600000 AS INTEGER) * 3600000 AS bucket,
54
+ source,
55
+ COALESCE(user_email, user_account_id, user_id, 'unknown') AS user_identity,
56
+ COALESCE(model, '') AS model,
57
+ kind,
58
+ COALESCE(token_type, '') AS token_type,
59
+ value AS sum_value
60
+ FROM metric_points
61
+ WHERE signal = 'jsonl'
62
+ AND session_row_id IN (SELECT id FROM sessions WHERE metric_source = 'jsonl')
63
+ )`;
64
+ export function pointWhere(filters, opts = {}) {
65
+ const clauses = [];
66
+ const params = [];
67
+ if (filters.from) {
68
+ clauses.push("timestamp >= ?");
69
+ params.push(filters.from);
70
+ }
71
+ if (filters.to) {
72
+ clauses.push("timestamp <= ?");
73
+ params.push(filters.to);
74
+ }
75
+ if (filters.user) {
76
+ clauses.push("COALESCE(user_email, user_account_id, user_id, 'unknown') = ?");
77
+ params.push(filters.user);
78
+ }
79
+ if (filters.model) {
80
+ clauses.push("model = ?");
81
+ params.push(filters.model);
82
+ }
83
+ if (filters.source) {
84
+ clauses.push("source = ?");
85
+ params.push(filters.source);
86
+ }
87
+ if (filters.session) {
88
+ clauses.push("session_row_id = ?");
89
+ params.push(filters.session);
90
+ }
91
+ // An explicit source filter means "show that source raw" (for OTel-vs-JSONL comparison), so the
92
+ // precedence predicate only applies to the default, cross-source view.
93
+ if (opts.dedupe && !filters.source)
94
+ clauses.push(jsonlWins());
95
+ return { where: clauses.length ? `WHERE ${clauses.join(" AND ")}` : "", params };
96
+ }
97
+ // Per-session precedence, read from the session's stored authoritative source rather than recomputed.
98
+ // A point counts toward deduped totals when its signal IS its session's metric_source.
99
+ export function jsonlWins(alias = "") {
100
+ return `(${alias}signal <> 'jsonl' OR ${alias}session_row_id IN (SELECT id FROM sessions WHERE metric_source = 'jsonl'))`;
101
+ }
102
+ function hourAligned(t) {
103
+ return t == null || t % GRANULARITY_MS.hour === 0;
104
+ }