@ai-studio-3d/vyasa 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 (237) hide show
  1. package/README.md +69 -0
  2. package/data/common-kit.json +34 -0
  3. package/data/pricing.json +119 -0
  4. package/data/schema/AnalyticsData.json +214 -0
  5. package/data/schema/FoundationData.json +42 -0
  6. package/data/schema/KitData.json +321 -0
  7. package/data/schema/SearchData.json +173 -0
  8. package/data/schema/SessionDetailData.json +231 -0
  9. package/data/schema/SessionsListData.json +115 -0
  10. package/data/schema/WasteData.json +95 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +343 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/core/billing/index.d.ts +4 -0
  16. package/dist/core/billing/index.d.ts.map +1 -0
  17. package/dist/core/billing/index.js +43 -0
  18. package/dist/core/billing/index.js.map +1 -0
  19. package/dist/core/budget/index.d.ts +30 -0
  20. package/dist/core/budget/index.d.ts.map +1 -0
  21. package/dist/core/budget/index.js +61 -0
  22. package/dist/core/budget/index.js.map +1 -0
  23. package/dist/core/codex/index.d.ts +3 -0
  24. package/dist/core/codex/index.d.ts.map +1 -0
  25. package/dist/core/codex/index.js +212 -0
  26. package/dist/core/codex/index.js.map +1 -0
  27. package/dist/core/cursor/index.d.ts +3 -0
  28. package/dist/core/cursor/index.d.ts.map +1 -0
  29. package/dist/core/cursor/index.js +304 -0
  30. package/dist/core/cursor/index.js.map +1 -0
  31. package/dist/core/cursor/scan.d.ts +28 -0
  32. package/dist/core/cursor/scan.d.ts.map +1 -0
  33. package/dist/core/cursor/scan.js +79 -0
  34. package/dist/core/cursor/scan.js.map +1 -0
  35. package/dist/core/decisions/index.d.ts +21 -0
  36. package/dist/core/decisions/index.d.ts.map +1 -0
  37. package/dist/core/decisions/index.js +133 -0
  38. package/dist/core/decisions/index.js.map +1 -0
  39. package/dist/core/dlp/index.d.ts +7 -0
  40. package/dist/core/dlp/index.d.ts.map +1 -0
  41. package/dist/core/dlp/index.js +115 -0
  42. package/dist/core/dlp/index.js.map +1 -0
  43. package/dist/core/health/index.d.ts +10 -0
  44. package/dist/core/health/index.d.ts.map +1 -0
  45. package/dist/core/health/index.js +21 -0
  46. package/dist/core/health/index.js.map +1 -0
  47. package/dist/core/index/index.d.ts +9 -0
  48. package/dist/core/index/index.d.ts.map +1 -0
  49. package/dist/core/index/index.js +103 -0
  50. package/dist/core/index/index.js.map +1 -0
  51. package/dist/core/index/ingest.d.ts +16 -0
  52. package/dist/core/index/ingest.d.ts.map +1 -0
  53. package/dist/core/index/ingest.js +184 -0
  54. package/dist/core/index/ingest.js.map +1 -0
  55. package/dist/core/index/platforms.d.ts +21 -0
  56. package/dist/core/index/platforms.d.ts.map +1 -0
  57. package/dist/core/index/platforms.js +44 -0
  58. package/dist/core/index/platforms.js.map +1 -0
  59. package/dist/core/index/pricing-map.d.ts +10 -0
  60. package/dist/core/index/pricing-map.d.ts.map +1 -0
  61. package/dist/core/index/pricing-map.js +16 -0
  62. package/dist/core/index/pricing-map.js.map +1 -0
  63. package/dist/core/index/progress.d.ts +26 -0
  64. package/dist/core/index/progress.d.ts.map +1 -0
  65. package/dist/core/index/progress.js +59 -0
  66. package/dist/core/index/progress.js.map +1 -0
  67. package/dist/core/index/scan.d.ts +9 -0
  68. package/dist/core/index/scan.d.ts.map +1 -0
  69. package/dist/core/index/scan.js +42 -0
  70. package/dist/core/index/scan.js.map +1 -0
  71. package/dist/core/index/statements.d.ts +18 -0
  72. package/dist/core/index/statements.d.ts.map +1 -0
  73. package/dist/core/index/statements.js +82 -0
  74. package/dist/core/index/statements.js.map +1 -0
  75. package/dist/core/index/tail.d.ts +42 -0
  76. package/dist/core/index/tail.d.ts.map +1 -0
  77. package/dist/core/index/tail.js +123 -0
  78. package/dist/core/index/tail.js.map +1 -0
  79. package/dist/core/jsonl/index.d.ts +3 -0
  80. package/dist/core/jsonl/index.d.ts.map +1 -0
  81. package/dist/core/jsonl/index.js +106 -0
  82. package/dist/core/jsonl/index.js.map +1 -0
  83. package/dist/core/jsonl-validate/index.d.ts +10 -0
  84. package/dist/core/jsonl-validate/index.d.ts.map +1 -0
  85. package/dist/core/jsonl-validate/index.js +40 -0
  86. package/dist/core/jsonl-validate/index.js.map +1 -0
  87. package/dist/core/kit/detection.d.ts +94 -0
  88. package/dist/core/kit/detection.d.ts.map +1 -0
  89. package/dist/core/kit/detection.js +312 -0
  90. package/dist/core/kit/detection.js.map +1 -0
  91. package/dist/core/kit/index.d.ts +12 -0
  92. package/dist/core/kit/index.d.ts.map +1 -0
  93. package/dist/core/kit/index.js +131 -0
  94. package/dist/core/kit/index.js.map +1 -0
  95. package/dist/core/kit/scan.d.ts +28 -0
  96. package/dist/core/kit/scan.d.ts.map +1 -0
  97. package/dist/core/kit/scan.js +432 -0
  98. package/dist/core/kit/scan.js.map +1 -0
  99. package/dist/core/recap/index.d.ts +18 -0
  100. package/dist/core/recap/index.d.ts.map +1 -0
  101. package/dist/core/recap/index.js +88 -0
  102. package/dist/core/recap/index.js.map +1 -0
  103. package/dist/core/repetition/index.d.ts +5 -0
  104. package/dist/core/repetition/index.d.ts.map +1 -0
  105. package/dist/core/repetition/index.js +0 -0
  106. package/dist/core/repetition/index.js.map +1 -0
  107. package/dist/core/schema/index.d.ts +514 -0
  108. package/dist/core/schema/index.d.ts.map +1 -0
  109. package/dist/core/schema/index.js +2 -0
  110. package/dist/core/schema/index.js.map +1 -0
  111. package/dist/core/schema-watch/index.d.ts +34 -0
  112. package/dist/core/schema-watch/index.d.ts.map +1 -0
  113. package/dist/core/schema-watch/index.js +87 -0
  114. package/dist/core/schema-watch/index.js.map +1 -0
  115. package/dist/core/search/index.d.ts +44 -0
  116. package/dist/core/search/index.d.ts.map +1 -0
  117. package/dist/core/search/index.js +641 -0
  118. package/dist/core/search/index.js.map +1 -0
  119. package/dist/core/settings/index.d.ts +24 -0
  120. package/dist/core/settings/index.d.ts.map +1 -0
  121. package/dist/core/settings/index.js +76 -0
  122. package/dist/core/settings/index.js.map +1 -0
  123. package/dist/core/share/bundle.d.ts +40 -0
  124. package/dist/core/share/bundle.d.ts.map +1 -0
  125. package/dist/core/share/bundle.js +158 -0
  126. package/dist/core/share/bundle.js.map +1 -0
  127. package/dist/core/share/canonical/from-claude.d.ts +13 -0
  128. package/dist/core/share/canonical/from-claude.d.ts.map +1 -0
  129. package/dist/core/share/canonical/from-claude.js +129 -0
  130. package/dist/core/share/canonical/from-claude.js.map +1 -0
  131. package/dist/core/share/canonical/from-codex.d.ts +18 -0
  132. package/dist/core/share/canonical/from-codex.d.ts.map +1 -0
  133. package/dist/core/share/canonical/from-codex.js +183 -0
  134. package/dist/core/share/canonical/from-codex.js.map +1 -0
  135. package/dist/core/share/canonical/to-claude.d.ts +15 -0
  136. package/dist/core/share/canonical/to-claude.d.ts.map +1 -0
  137. package/dist/core/share/canonical/to-claude.js +146 -0
  138. package/dist/core/share/canonical/to-claude.js.map +1 -0
  139. package/dist/core/share/canonical/to-codex.d.ts +21 -0
  140. package/dist/core/share/canonical/to-codex.d.ts.map +1 -0
  141. package/dist/core/share/canonical/to-codex.js +124 -0
  142. package/dist/core/share/canonical/to-codex.js.map +1 -0
  143. package/dist/core/share/canonical/tool-map.d.ts +61 -0
  144. package/dist/core/share/canonical/tool-map.d.ts.map +1 -0
  145. package/dist/core/share/canonical/tool-map.js +299 -0
  146. package/dist/core/share/canonical/tool-map.js.map +1 -0
  147. package/dist/core/share/canonical/types.d.ts +57 -0
  148. package/dist/core/share/canonical/types.d.ts.map +1 -0
  149. package/dist/core/share/canonical/types.js +9 -0
  150. package/dist/core/share/canonical/types.js.map +1 -0
  151. package/dist/core/share/import.d.ts +28 -0
  152. package/dist/core/share/import.d.ts.map +1 -0
  153. package/dist/core/share/import.js +174 -0
  154. package/dist/core/share/import.js.map +1 -0
  155. package/dist/core/share/manifest.d.ts +37 -0
  156. package/dist/core/share/manifest.d.ts.map +1 -0
  157. package/dist/core/share/manifest.js +31 -0
  158. package/dist/core/share/manifest.js.map +1 -0
  159. package/dist/core/share/preview.d.ts +4 -0
  160. package/dist/core/share/preview.d.ts.map +1 -0
  161. package/dist/core/share/preview.js +153 -0
  162. package/dist/core/share/preview.js.map +1 -0
  163. package/dist/core/share/primer.d.ts +19 -0
  164. package/dist/core/share/primer.d.ts.map +1 -0
  165. package/dist/core/share/primer.js +196 -0
  166. package/dist/core/share/primer.js.map +1 -0
  167. package/dist/core/share/resume.d.ts +10 -0
  168. package/dist/core/share/resume.d.ts.map +1 -0
  169. package/dist/core/share/resume.js +58 -0
  170. package/dist/core/share/resume.js.map +1 -0
  171. package/dist/core/share/scrub.d.ts +10 -0
  172. package/dist/core/share/scrub.d.ts.map +1 -0
  173. package/dist/core/share/scrub.js +198 -0
  174. package/dist/core/share/scrub.js.map +1 -0
  175. package/dist/core/share/tar.d.ts +12 -0
  176. package/dist/core/share/tar.d.ts.map +1 -0
  177. package/dist/core/share/tar.js +78 -0
  178. package/dist/core/share/tar.js.map +1 -0
  179. package/dist/core/tags/index.d.ts +48 -0
  180. package/dist/core/tags/index.d.ts.map +1 -0
  181. package/dist/core/tags/index.js +113 -0
  182. package/dist/core/tags/index.js.map +1 -0
  183. package/dist/core/today/index.d.ts +25 -0
  184. package/dist/core/today/index.d.ts.map +1 -0
  185. package/dist/core/today/index.js +42 -0
  186. package/dist/core/today/index.js.map +1 -0
  187. package/dist/core/waste/abandoned.d.ts +12 -0
  188. package/dist/core/waste/abandoned.d.ts.map +1 -0
  189. package/dist/core/waste/abandoned.js +127 -0
  190. package/dist/core/waste/abandoned.js.map +1 -0
  191. package/dist/core/waste/cache-miss.d.ts +9 -0
  192. package/dist/core/waste/cache-miss.d.ts.map +1 -0
  193. package/dist/core/waste/cache-miss.js +84 -0
  194. package/dist/core/waste/cache-miss.js.map +1 -0
  195. package/dist/core/waste/index.d.ts +12 -0
  196. package/dist/core/waste/index.d.ts.map +1 -0
  197. package/dist/core/waste/index.js +45 -0
  198. package/dist/core/waste/index.js.map +1 -0
  199. package/dist/core/waste/wrong-model.d.ts +11 -0
  200. package/dist/core/waste/wrong-model.d.ts.map +1 -0
  201. package/dist/core/waste/wrong-model.js +104 -0
  202. package/dist/core/waste/wrong-model.js.map +1 -0
  203. package/dist/db/index.d.ts +10 -0
  204. package/dist/db/index.d.ts.map +1 -0
  205. package/dist/db/index.js +29 -0
  206. package/dist/db/index.js.map +1 -0
  207. package/dist/db/migrate.d.ts +8 -0
  208. package/dist/db/migrate.d.ts.map +1 -0
  209. package/dist/db/migrate.js +282 -0
  210. package/dist/db/migrate.js.map +1 -0
  211. package/dist/server/events.d.ts +4 -0
  212. package/dist/server/events.d.ts.map +1 -0
  213. package/dist/server/events.js +54 -0
  214. package/dist/server/events.js.map +1 -0
  215. package/dist/server/index.d.ts +7 -0
  216. package/dist/server/index.d.ts.map +1 -0
  217. package/dist/server/index.js +238 -0
  218. package/dist/server/index.js.map +1 -0
  219. package/dist/server/routes/foundation.d.ts +2 -0
  220. package/dist/server/routes/foundation.d.ts.map +1 -0
  221. package/dist/server/routes/foundation.js +2 -0
  222. package/dist/server/routes/foundation.js.map +1 -0
  223. package/dist/server/routes/search.d.ts +2 -0
  224. package/dist/server/routes/search.d.ts.map +1 -0
  225. package/dist/server/routes/search.js +2 -0
  226. package/dist/server/routes/search.js.map +1 -0
  227. package/dist/server/routes/sessions.d.ts +2 -0
  228. package/dist/server/routes/sessions.d.ts.map +1 -0
  229. package/dist/server/routes/sessions.js +2 -0
  230. package/dist/server/routes/sessions.js.map +1 -0
  231. package/dist/server/routes/waste.d.ts +2 -0
  232. package/dist/server/routes/waste.d.ts.map +1 -0
  233. package/dist/server/routes/waste.js +2 -0
  234. package/dist/server/routes/waste.js.map +1 -0
  235. package/dist/web/assets/index-Ba1VvTj0.js +37 -0
  236. package/dist/web/index.html +12 -0
  237. package/package.json +76 -0
@@ -0,0 +1,282 @@
1
+ import Database from 'better-sqlite3';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join, dirname } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ // Each migration is a SQL string. Add new ones at the end — never edit existing entries.
7
+ const MIGRATIONS = [
8
+ // 0001 — core schema
9
+ `
10
+ CREATE TABLE IF NOT EXISTS sessions (
11
+ id TEXT PRIMARY KEY,
12
+ project TEXT NOT NULL,
13
+ user_id TEXT NOT NULL DEFAULT 'local',
14
+ started_at TEXT,
15
+ ended_at TEXT,
16
+ message_count INTEGER NOT NULL DEFAULT 0,
17
+ total_input_tokens INTEGER NOT NULL DEFAULT 0,
18
+ total_output_tokens INTEGER NOT NULL DEFAULT 0,
19
+ total_cache_creation INTEGER NOT NULL DEFAULT 0,
20
+ total_cache_read INTEGER NOT NULL DEFAULT 0,
21
+ total_cost_cents REAL NOT NULL DEFAULT 0,
22
+ last_outcome TEXT
23
+ );
24
+
25
+ CREATE TABLE IF NOT EXISTS messages (
26
+ id TEXT PRIMARY KEY,
27
+ session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
28
+ idx INTEGER NOT NULL,
29
+ role TEXT NOT NULL CHECK(role IN ('user', 'assistant', 'system')),
30
+ ts TEXT NOT NULL,
31
+ model TEXT,
32
+ content_json TEXT NOT NULL DEFAULT '{}'
33
+ );
34
+
35
+ CREATE TABLE IF NOT EXISTS usage (
36
+ message_id TEXT PRIMARY KEY REFERENCES messages(id) ON DELETE CASCADE,
37
+ input_tokens INTEGER NOT NULL DEFAULT 0,
38
+ output_tokens INTEGER NOT NULL DEFAULT 0,
39
+ cache_creation_tokens INTEGER NOT NULL DEFAULT 0,
40
+ cache_read_tokens INTEGER NOT NULL DEFAULT 0
41
+ );
42
+
43
+ CREATE TABLE IF NOT EXISTS tool_calls (
44
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
45
+ message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
46
+ tool TEXT NOT NULL,
47
+ input_json TEXT,
48
+ output_json TEXT,
49
+ error TEXT,
50
+ duration_ms INTEGER
51
+ );
52
+
53
+ CREATE TABLE IF NOT EXISTS waste_attributions (
54
+ session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
55
+ category TEXT NOT NULL CHECK(category IN ('cache-miss', 'wrong-model', 'abandoned')),
56
+ amount_cents REAL NOT NULL,
57
+ anchor_msg_idx INTEGER,
58
+ evidence_json TEXT,
59
+ PRIMARY KEY (session_id, category)
60
+ );
61
+
62
+ CREATE TABLE IF NOT EXISTS pricing (
63
+ model TEXT NOT NULL,
64
+ period_start TEXT NOT NULL,
65
+ period_end TEXT,
66
+ input_per_mtok REAL NOT NULL,
67
+ output_per_mtok REAL NOT NULL,
68
+ cache_write_per_mtok REAL NOT NULL,
69
+ cache_read_per_mtok REAL NOT NULL,
70
+ PRIMARY KEY (model, period_start)
71
+ );
72
+
73
+ CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
74
+ session_id UNINDEXED,
75
+ message_id UNINDEXED,
76
+ content,
77
+ tool_inputs,
78
+ tool_outputs,
79
+ errors,
80
+ tokenize='porter unicode61'
81
+ );
82
+
83
+ CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);
84
+ CREATE INDEX IF NOT EXISTS idx_messages_ts ON messages(ts);
85
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_message ON tool_calls(message_id);
86
+ CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project);
87
+ CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at);
88
+ `,
89
+ // 0002 — FTS5 delete trigger (keeps messages_fts in sync when messages are cascade-deleted)
90
+ `
91
+ CREATE TRIGGER IF NOT EXISTS messages_fts_delete
92
+ AFTER DELETE ON messages
93
+ BEGIN
94
+ DELETE FROM messages_fts WHERE message_id = OLD.id;
95
+ END;
96
+ `,
97
+ // 0003 — file index for incremental mtime-based scanning
98
+ `
99
+ CREATE TABLE IF NOT EXISTS _file_index (
100
+ path TEXT PRIMARY KEY,
101
+ mtime_ms INTEGER NOT NULL,
102
+ indexed_at TEXT NOT NULL DEFAULT (datetime('now'))
103
+ );
104
+ `,
105
+ // 0004 — platform column for V2 Codex readiness
106
+ `
107
+ ALTER TABLE sessions ADD COLUMN platform TEXT NOT NULL DEFAULT 'claude-code';
108
+ CREATE INDEX IF NOT EXISTS idx_sessions_platform ON sessions(platform);
109
+ `,
110
+ // 0005 — parse_errors table for V2 JSONL validation
111
+ `
112
+ CREATE TABLE IF NOT EXISTS parse_errors (
113
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
114
+ file_path TEXT NOT NULL,
115
+ line_num INTEGER NOT NULL,
116
+ record_type TEXT,
117
+ error TEXT NOT NULL,
118
+ sample_json TEXT,
119
+ ts TEXT DEFAULT (datetime('now'))
120
+ );
121
+ `,
122
+ // 0006 — schema drift watcher: tracks observed JSONL record fingerprints per platform
123
+ `
124
+ CREATE TABLE IF NOT EXISTS _schema_observations (
125
+ platform TEXT NOT NULL,
126
+ fingerprint TEXT NOT NULL,
127
+ first_seen_file TEXT NOT NULL,
128
+ first_seen_line INTEGER NOT NULL,
129
+ last_seen TEXT NOT NULL,
130
+ count INTEGER NOT NULL DEFAULT 1,
131
+ PRIMARY KEY (platform, fingerprint)
132
+ );
133
+ `,
134
+ // 0007 — FTS perf: drop porter stemmer, remove tool_outputs column (not searched, was 80% of tokenization time).
135
+ // Clears _file_index to force full FTS rebuild on next run (~30s vs 4+ min with old schema).
136
+ `
137
+ DROP TABLE IF EXISTS messages_fts;
138
+ CREATE VIRTUAL TABLE messages_fts USING fts5(
139
+ session_id UNINDEXED,
140
+ message_id UNINDEXED,
141
+ content,
142
+ tool_inputs,
143
+ errors UNINDEXED,
144
+ tokenize='unicode61'
145
+ );
146
+ DROP TRIGGER IF EXISTS messages_fts_delete;
147
+ CREATE TRIGGER messages_fts_delete
148
+ AFTER DELETE ON messages
149
+ BEGIN
150
+ DELETE FROM messages_fts WHERE message_id = OLD.id;
151
+ END;
152
+ DELETE FROM _file_index;
153
+ `,
154
+ // 0008 — session transport: persist source JSONL path on sessions row so we can export the original file
155
+ // to a .vyasa bundle. Backfill from _file_index for previously-ingested sessions.
156
+ `
157
+ ALTER TABLE sessions ADD COLUMN file_path TEXT;
158
+ UPDATE sessions
159
+ SET file_path = (
160
+ SELECT fi.path FROM _file_index fi
161
+ INNER JOIN messages m ON m.session_id = sessions.id
162
+ WHERE fi.path LIKE '%' || sessions.id || '%'
163
+ LIMIT 1
164
+ )
165
+ WHERE file_path IS NULL;
166
+ `,
167
+ // 0009 — user session metadata: custom name override + freeform tags, plus captured Claude-native
168
+ // names (custom-title / ai-title from the JSONL). DELIBERATELY FK-FREE: ingest does
169
+ // `INSERT OR REPLACE INTO sessions`, which (with foreign_keys=ON) cascade-deletes child rows
170
+ // on every re-ingest. A FK here would wipe user tags/name on reindex — so these tables float
171
+ // free of the sessions lifecycle and ingest only ever writes the claude_* columns.
172
+ `
173
+ CREATE TABLE IF NOT EXISTS session_meta (
174
+ session_id TEXT PRIMARY KEY,
175
+ custom_name TEXT,
176
+ claude_custom_title TEXT,
177
+ claude_ai_title TEXT,
178
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
179
+ );
180
+ CREATE TABLE IF NOT EXISTS session_tags (
181
+ session_id TEXT NOT NULL,
182
+ tag TEXT NOT NULL,
183
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
184
+ PRIMARY KEY (session_id, tag)
185
+ );
186
+ CREATE INDEX IF NOT EXISTS idx_session_tags_tag ON session_tags(tag);
187
+ `,
188
+ // 0010 — app-level key/value settings (FK-free, app-scoped, survives ingest). Holds the
189
+ // user-entered weekly token cap + nudge bookkeeping (which threshold already fired
190
+ // this week, so the limit-burn push nudge fires once per threshold per week).
191
+ `
192
+ CREATE TABLE IF NOT EXISTS app_settings (
193
+ key TEXT PRIMARY KEY,
194
+ value TEXT,
195
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
196
+ );
197
+ `,
198
+ // 0011 — F1 search recall: re-add a `tool_outputs` FTS column so tool-result text becomes
199
+ // searchable (the 0007 perf trim dropped it). Additive + safe: messages_fts is derived
200
+ // data, rebuilt from messages on next run. Clearing _file_index forces that one-time rebuild.
201
+ `
202
+ DROP TABLE IF EXISTS messages_fts;
203
+ CREATE VIRTUAL TABLE messages_fts USING fts5(
204
+ session_id UNINDEXED,
205
+ message_id UNINDEXED,
206
+ content,
207
+ tool_inputs,
208
+ tool_outputs,
209
+ errors UNINDEXED,
210
+ tokenize='unicode61'
211
+ );
212
+ DROP TRIGGER IF EXISTS messages_fts_delete;
213
+ CREATE TRIGGER messages_fts_delete
214
+ AFTER DELETE ON messages
215
+ BEGIN
216
+ DELETE FROM messages_fts WHERE message_id = OLD.id;
217
+ END;
218
+ DELETE FROM _file_index;
219
+ `,
220
+ // 0012 — F3 permission_change: persist the per-record permissionMode (auto | acceptEdits |
221
+ // default | plan) so getDecisions can emit permission_change events. Clearing
222
+ // _file_index forces a re-index to populate the new column (harmless if 0011 already cleared it).
223
+ `
224
+ ALTER TABLE messages ADD COLUMN permission_mode TEXT;
225
+ DELETE FROM _file_index;
226
+ `,
227
+ ];
228
+ /**
229
+ * Opens (or creates) the SQLite database at dbPath, enables WAL mode,
230
+ * runs any pending migrations, and seeds pricing data.
231
+ * Returns the open database instance.
232
+ */
233
+ export function migrate(dbPath) {
234
+ const db = new Database(dbPath);
235
+ // WAL mode for concurrent reads (future Python sidecar)
236
+ db.pragma('journal_mode = WAL');
237
+ db.pragma('foreign_keys = ON');
238
+ db.pragma('synchronous = NORMAL'); // WAL+NORMAL: durable across crashes, eliminates per-commit fsync
239
+ db.pragma('cache_size = -64000'); // ~64 MB page cache
240
+ db.pragma('mmap_size = 268435456'); // 256 MB mmap window
241
+ db.pragma('temp_store = MEMORY'); // FTS5 temp btrees in RAM
242
+ db.pragma('wal_autocheckpoint = 1000'); // bound WAL growth during long rebuilds
243
+ // Migrations tracking table
244
+ db.exec(`
245
+ CREATE TABLE IF NOT EXISTS _migrations (
246
+ id INTEGER PRIMARY KEY,
247
+ run_at TEXT NOT NULL DEFAULT (datetime('now'))
248
+ )
249
+ `);
250
+ const ran = new Set(db.prepare('SELECT id FROM _migrations').all().map((r) => r.id));
251
+ for (let i = 0; i < MIGRATIONS.length; i++) {
252
+ if (ran.has(i))
253
+ continue;
254
+ db.transaction(() => {
255
+ db.exec(MIGRATIONS[i]);
256
+ db.prepare('INSERT INTO _migrations (id) VALUES (?)').run(i);
257
+ })();
258
+ }
259
+ // Seed pricing data (upsert — safe to run on every open)
260
+ seedPricing(db);
261
+ return db;
262
+ }
263
+ function seedPricing(db) {
264
+ const pricingPath = join(__dirname, '../../data/pricing.json');
265
+ const rows = JSON.parse(readFileSync(pricingPath, 'utf8'));
266
+ const upsert = db.prepare(`
267
+ INSERT INTO pricing (model, period_start, period_end, input_per_mtok, output_per_mtok, cache_write_per_mtok, cache_read_per_mtok)
268
+ VALUES (@model, @period_start, @period_end, @input_per_mtok, @output_per_mtok, @cache_write_per_mtok, @cache_read_per_mtok)
269
+ ON CONFLICT(model, period_start) DO UPDATE SET
270
+ period_end = excluded.period_end,
271
+ input_per_mtok = excluded.input_per_mtok,
272
+ output_per_mtok = excluded.output_per_mtok,
273
+ cache_write_per_mtok = excluded.cache_write_per_mtok,
274
+ cache_read_per_mtok = excluded.cache_read_per_mtok
275
+ `);
276
+ const insertAll = db.transaction((pricingRows) => {
277
+ for (const row of pricingRows)
278
+ upsert.run(row);
279
+ });
280
+ insertAll(rows);
281
+ }
282
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import type { TailWatcher } from '../core/index/tail.js';
3
+ export declare function registerEventsRoute(app: FastifyInstance, watcher: TailWatcher): void;
4
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/server/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,uBAAuB,CAAA;AAY7E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAyCpF"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * SSE endpoint that streams `session-updated` events from the tail watcher
3
+ * to web clients. The browser uses native `EventSource`, which auto-reconnects
4
+ * (5s default) on transient drops — we don't add custom retry logic server-side.
5
+ */
6
+ // Each open /api/events connection adds a listener to the watcher. React
7
+ // StrictMode (dev) doubles them and multiple tabs multiply; default cap of 10
8
+ // would spam EventEmitter warnings under normal use. Unlimited is correct here.
9
+ const HEARTBEAT_MS = 25_000;
10
+ export function registerEventsRoute(app, watcher) {
11
+ watcher.setMaxListeners(0);
12
+ app.get('/api/events', (req, reply) => {
13
+ // Tell Fastify we're managing the response lifecycle ourselves.
14
+ reply.hijack();
15
+ const raw = reply.raw;
16
+ raw.writeHead(200, {
17
+ 'Content-Type': 'text/event-stream',
18
+ 'Cache-Control': 'no-cache, no-transform',
19
+ Connection: 'keep-alive',
20
+ 'X-Accel-Buffering': 'no',
21
+ });
22
+ // Initial comment so the client knows the stream is live.
23
+ raw.write(': connected\n\n');
24
+ const handler = (event) => {
25
+ try {
26
+ raw.write(`data: ${JSON.stringify(event)}\n\n`);
27
+ }
28
+ catch {
29
+ // Write after socket close — cleanup will fire via 'close' below.
30
+ }
31
+ };
32
+ watcher.on('session-updated', handler);
33
+ // Heartbeat: silent ping keeps idle connections alive past proxy/firewall
34
+ // idle timeouts and lets us detect dead sockets quickly via write errors.
35
+ const heartbeat = setInterval(() => {
36
+ try {
37
+ raw.write(': ping\n\n');
38
+ }
39
+ catch { /* socket closed; cleanup will fire */ }
40
+ }, HEARTBEAT_MS);
41
+ const cleanup = () => {
42
+ clearInterval(heartbeat);
43
+ watcher.off('session-updated', handler);
44
+ try {
45
+ raw.end();
46
+ }
47
+ catch { /* already closed */ }
48
+ };
49
+ req.raw.on('close', cleanup);
50
+ req.raw.on('error', cleanup);
51
+ raw.on('error', cleanup);
52
+ });
53
+ }
54
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/server/events.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,yEAAyE;AACzE,8EAA8E;AAC9E,gFAAgF;AAChF,MAAM,YAAY,GAAG,MAAM,CAAA;AAE3B,MAAM,UAAU,mBAAmB,CAAC,GAAoB,EAAE,OAAoB;IAC5E,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IAE1B,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QACpC,gEAAgE;QAChE,KAAK,CAAC,MAAM,EAAE,CAAA;QAEd,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAA;QACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,wBAAwB;YACzC,UAAU,EAAE,YAAY;YACxB,mBAAmB,EAAE,IAAI;SAC1B,CAAC,CAAA;QACF,0DAA0D;QAC1D,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;QAE5B,MAAM,OAAO,GAAG,CAAC,KAA0B,EAAE,EAAE;YAC7C,IAAI,CAAC;gBACH,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YACjD,CAAC;YAAC,MAAM,CAAC;gBACP,kEAAkE;YACpE,CAAC;QACH,CAAC,CAAA;QACD,OAAO,CAAC,EAAE,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;QAEtC,0EAA0E;QAC1E,0EAA0E;QAC1E,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC;gBAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,sCAAsC,CAAC,CAAC;QAClF,CAAC,EAAE,YAAY,CAAC,CAAA;QAEhB,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,aAAa,CAAC,SAAS,CAAC,CAAA;YACxB,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;YACvC,IAAI,CAAC;gBAAC,GAAG,CAAC,GAAG,EAAE,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAClD,CAAC,CAAA;QACD,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC5B,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC5B,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import Fastify from 'fastify';
2
+ import Database from 'better-sqlite3';
3
+ import type { TailWatcher } from '../core/index/tail.js';
4
+ export declare function buildServer(db: Database.Database, tailWatcher?: TailWatcher): Fastify.FastifyInstance<import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>, import("node:http").IncomingMessage, import("node:http").ServerResponse<import("node:http").IncomingMessage>, Fastify.FastifyBaseLogger, Fastify.FastifyTypeProviderDefault> & PromiseLike<Fastify.FastifyInstance<import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>, import("node:http").IncomingMessage, import("node:http").ServerResponse<import("node:http").IncomingMessage>, Fastify.FastifyBaseLogger, Fastify.FastifyTypeProviderDefault>> & {
5
+ __linterBrands: "SafePromiseLike";
6
+ };
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAgBrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,WAAW;;EAoO3E"}
@@ -0,0 +1,238 @@
1
+ import Fastify from 'fastify';
2
+ import cors from '@fastify/cors';
3
+ import { getFoundation, getWaste, search, getSessionDetail, getSessions, getAnalytics, getLiveSessions } from '../core/search/index.js';
4
+ import { getDecisions } from '../core/decisions/index.js';
5
+ import { getRecap } from '../core/recap/index.js';
6
+ import { getKit } from '../core/kit/index.js';
7
+ import { getBilling } from '../core/billing/index.js';
8
+ import { importBundle, ImportError } from '../core/share/import.js';
9
+ import { indexProgress } from '../core/index/progress.js';
10
+ import { buildBundle, BundleError } from '../core/share/bundle.js';
11
+ import { buildSharePreview } from '../core/share/preview.js';
12
+ import { setSessionName, setTags, listAllTags, getSessionMeta, TagError } from '../core/tags/index.js';
13
+ import { getAllSettings, updateSettings, SettingsError } from '../core/settings/index.js';
14
+ import { capStatus, weeklyBurn } from '../core/budget/index.js';
15
+ import { buildPrimer, PrimerError } from '../core/share/primer.js';
16
+ import { registerEventsRoute } from './events.js';
17
+ export function buildServer(db, tailWatcher) {
18
+ const app = Fastify({ logger: false });
19
+ app.register(cors);
20
+ app.get('/api/foundation', async () => {
21
+ return getFoundation(db);
22
+ });
23
+ app.get('/api/waste', async (req) => {
24
+ const range = req.query.range ?? '7d';
25
+ const validRanges = ['7d', '30d', '90d', 'all'];
26
+ const safeRange = validRanges.includes(range)
27
+ ? range
28
+ : '7d';
29
+ return getWaste(db, safeRange);
30
+ });
31
+ app.get('/api/search', async (req) => {
32
+ const q = req.query;
33
+ return search(db, {
34
+ q: q.q,
35
+ project: q.project,
36
+ model: q.model,
37
+ platform: q.platform,
38
+ dateFrom: q.dateFrom,
39
+ dateTo: q.dateTo,
40
+ outcome: q.outcome,
41
+ limit: q.limit ? parseInt(q.limit, 10) : undefined, // NaN handled in search()
42
+ offset: q.offset ? parseInt(q.offset, 10) : undefined,
43
+ });
44
+ });
45
+ app.get('/api/sessions', async (req) => {
46
+ const q = req.query;
47
+ const validSorts = ['date', 'cost', 'duration'];
48
+ const sort = validSorts.includes(q.sort)
49
+ ? q.sort
50
+ : 'date';
51
+ const validOutcomes = ['any', 'completed', 'abandoned'];
52
+ const outcome = validOutcomes.includes(q.outcome)
53
+ ? q.outcome
54
+ : 'any';
55
+ return getSessions(db, {
56
+ project: q.project,
57
+ model: q.model,
58
+ platform: q.platform,
59
+ dateFrom: q.dateFrom,
60
+ dateTo: q.dateTo,
61
+ outcome,
62
+ sort,
63
+ tag: q.tag,
64
+ includeEmpty: q.includeEmpty === 'true',
65
+ limit: q.limit ? parseInt(q.limit, 10) : undefined,
66
+ offset: q.offset ? parseInt(q.offset, 10) : undefined,
67
+ });
68
+ });
69
+ app.get('/api/live', async (req) => {
70
+ const q = req.query;
71
+ const win = q.windowMinutes ? parseInt(q.windowMinutes, 10) : 15;
72
+ return getLiveSessions(db, Date.now(), Number.isFinite(win) && win > 0 ? win : 15);
73
+ });
74
+ app.get('/api/analytics', async (req) => {
75
+ const range = req.query.range ?? '30d';
76
+ const validRanges = ['7d', '30d', '90d', 'all'];
77
+ const safeRange = validRanges.includes(range)
78
+ ? range
79
+ : '30d';
80
+ return getAnalytics(db, safeRange);
81
+ });
82
+ app.get('/api/billing', async (req) => {
83
+ const range = req.query.range ?? '30d';
84
+ const validRanges = ['7d', '30d', '90d', 'all'];
85
+ const safeRange = validRanges.includes(range)
86
+ ? range
87
+ : '30d';
88
+ return getBilling(db, safeRange);
89
+ });
90
+ app.post('/api/import', async (req, reply) => {
91
+ const body = (req.body ?? {});
92
+ const path = typeof body.path === 'string' ? body.path.trim() : '';
93
+ if (!path)
94
+ return reply.code(400).send({ ok: false, error: 'path is required' });
95
+ try {
96
+ const { sessionId } = importBundle(path, { db });
97
+ return { ok: true, sessionId };
98
+ }
99
+ catch (err) {
100
+ if (err instanceof ImportError)
101
+ return reply.code(400).send({ ok: false, error: err.message });
102
+ throw err;
103
+ }
104
+ });
105
+ app.get('/api/kit', async (req) => {
106
+ const q = req.query;
107
+ const validPlatforms = ['claude-code', 'codex', 'cursor'];
108
+ const platform = validPlatforms.includes(q.platform)
109
+ ? q.platform
110
+ : undefined;
111
+ let days;
112
+ if (q.days) {
113
+ const n = parseInt(q.days, 10);
114
+ if (Number.isFinite(n) && n > 0 && n <= 365)
115
+ days = n;
116
+ }
117
+ return getKit(db, { platform, lookbackDays: days });
118
+ });
119
+ app.get('/api/sessions/:id', async (req, reply) => {
120
+ const { id } = req.params;
121
+ const detail = getSessionDetail(db, id);
122
+ if (!detail)
123
+ return reply.code(404).send({ error: 'session not found' });
124
+ // F3: derive plan/decision events at query time (empty for most sessions). Merged here so
125
+ // getSessionDetail stays focused on persisted data.
126
+ return { ...detail, decisions: getDecisions(db, id) };
127
+ });
128
+ app.get('/api/recap', async () => getRecap(db));
129
+ app.get('/api/index-status', async () => {
130
+ return indexProgress.get();
131
+ });
132
+ // ── App settings + budget (weekly token cap) ──────────────────────────────
133
+ app.get('/api/settings', async () => {
134
+ return { settings: getAllSettings(db), budget: weeklyBurn(db), cap: capStatus(db) };
135
+ });
136
+ app.put('/api/settings', async (req, reply) => {
137
+ const body = (req.body ?? {});
138
+ try {
139
+ const settings = updateSettings(db, body);
140
+ return { settings, budget: weeklyBurn(db), cap: capStatus(db) };
141
+ }
142
+ catch (err) {
143
+ if (err instanceof SettingsError)
144
+ return reply.code(err.status).send({ error: err.message });
145
+ throw err;
146
+ }
147
+ });
148
+ // ── Session tags + custom name (mutations) ─────────────────────────────────
149
+ app.get('/api/tags', async () => {
150
+ return listAllTags(db);
151
+ });
152
+ app.put('/api/sessions/:id/name', async (req, reply) => {
153
+ const { id } = req.params;
154
+ const body = req.body;
155
+ try {
156
+ setSessionName(db, id, body?.name ?? null);
157
+ return getSessionMeta(db, id);
158
+ }
159
+ catch (err) {
160
+ if (err instanceof TagError)
161
+ return reply.code(err.status).send({ error: err.message });
162
+ throw err;
163
+ }
164
+ });
165
+ app.put('/api/sessions/:id/tags', async (req, reply) => {
166
+ const { id } = req.params;
167
+ const body = req.body;
168
+ const tags = Array.isArray(body?.tags)
169
+ ? body.tags.filter((t) => typeof t === 'string')
170
+ : [];
171
+ try {
172
+ setTags(db, id, tags);
173
+ return getSessionMeta(db, id);
174
+ }
175
+ catch (err) {
176
+ if (err instanceof TagError)
177
+ return reply.code(err.status).send({ error: err.message });
178
+ throw err;
179
+ }
180
+ });
181
+ app.get('/api/sessions/:id/share-preview', async (req, reply) => {
182
+ const { id } = req.params;
183
+ try {
184
+ return buildSharePreview(db, id);
185
+ }
186
+ catch (err) {
187
+ if (err instanceof BundleError) {
188
+ return reply.code(err.status).send({ error: err.message });
189
+ }
190
+ throw err;
191
+ }
192
+ });
193
+ app.get('/api/sessions/:id/export', async (req, reply) => {
194
+ const { id } = req.params;
195
+ const q = req.query;
196
+ const redactUuids = q.redact ? q.redact.split(',').filter(Boolean) : undefined;
197
+ try {
198
+ const { buffer, filename } = buildBundle(db, id, {
199
+ scrub: q.scrub !== 'false',
200
+ includePlanFile: q.includePlan !== 'false',
201
+ redactUuids,
202
+ });
203
+ return reply
204
+ .type('application/gzip')
205
+ .header('Content-Disposition', `attachment; filename="${filename}"`)
206
+ .header('Content-Length', buffer.length)
207
+ .send(buffer);
208
+ }
209
+ catch (err) {
210
+ if (err instanceof BundleError) {
211
+ return reply.code(err.status).send({ error: err.message });
212
+ }
213
+ throw err;
214
+ }
215
+ });
216
+ app.get('/api/sessions/:id/primer', async (req, reply) => {
217
+ const { id } = req.params;
218
+ const q = req.query;
219
+ try {
220
+ const text = buildPrimer(db, id, {
221
+ recentTurns: q.recentTurns ? parseInt(q.recentTurns, 10) : undefined,
222
+ maxChars: q.maxChars ? parseInt(q.maxChars, 10) : undefined,
223
+ });
224
+ return reply.type('text/plain; charset=utf-8').send(text);
225
+ }
226
+ catch (err) {
227
+ if (err instanceof PrimerError) {
228
+ return reply.code(err.status).send({ error: err.message });
229
+ }
230
+ throw err;
231
+ }
232
+ });
233
+ if (tailWatcher) {
234
+ registerEventsRoute(app, tailWatcher);
235
+ }
236
+ return app;
237
+ }
238
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=foundation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundation.d.ts","sourceRoot":"","sources":["../../../src/server/routes/foundation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=foundation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundation.js","sourceRoot":"","sources":["../../../src/server/routes/foundation.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/server/routes/search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/server/routes/search.ts"],"names":[],"mappings":""}