draken 0.1.6 → 0.3.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 (326) hide show
  1. package/ACCEPTANCE.md +34 -0
  2. package/CHANGELOG.md +65 -0
  3. package/CONTRIBUTING.md +129 -0
  4. package/MEMORY.md +118 -0
  5. package/PERSONA.md +67 -0
  6. package/README.md +168 -78
  7. package/SETUP.md +111 -0
  8. package/SOURCES.md +75 -0
  9. package/TRAY.md +54 -0
  10. package/VOICE.md +126 -0
  11. package/dist/auth/middleware.d.ts +3 -1
  12. package/dist/auth/middleware.d.ts.map +1 -1
  13. package/dist/auth/middleware.js +20 -15
  14. package/dist/auth/middleware.js.map +1 -1
  15. package/dist/cli.js +77 -113
  16. package/dist/cli.js.map +1 -1
  17. package/dist/db/agent-migration.d.ts +7 -0
  18. package/dist/db/agent-migration.d.ts.map +1 -0
  19. package/dist/db/agent-migration.js +36 -0
  20. package/dist/db/agent-migration.js.map +1 -0
  21. package/dist/db/evidence.d.ts +37 -0
  22. package/dist/db/evidence.d.ts.map +1 -0
  23. package/dist/db/evidence.js +110 -0
  24. package/dist/db/evidence.js.map +1 -0
  25. package/dist/db/pointer-migration.d.ts +7 -0
  26. package/dist/db/pointer-migration.d.ts.map +1 -0
  27. package/dist/db/pointer-migration.js +117 -0
  28. package/dist/db/pointer-migration.js.map +1 -0
  29. package/dist/db/retained-text.d.ts +8 -0
  30. package/dist/db/retained-text.d.ts.map +1 -0
  31. package/dist/db/retained-text.js +36 -0
  32. package/dist/db/retained-text.js.map +1 -0
  33. package/dist/db/schema.d.ts +1 -5
  34. package/dist/db/schema.d.ts.map +1 -1
  35. package/dist/db/schema.js +206 -55
  36. package/dist/db/schema.js.map +1 -1
  37. package/dist/db/snapshot-pointers.d.ts +5 -0
  38. package/dist/db/snapshot-pointers.d.ts.map +1 -0
  39. package/dist/db/snapshot-pointers.js +174 -0
  40. package/dist/db/snapshot-pointers.js.map +1 -0
  41. package/dist/memory/automatic.d.ts +38 -0
  42. package/dist/memory/automatic.d.ts.map +1 -0
  43. package/dist/memory/automatic.js +155 -0
  44. package/dist/memory/automatic.js.map +1 -0
  45. package/dist/memory/context.d.ts +12 -0
  46. package/dist/memory/context.d.ts.map +1 -0
  47. package/dist/memory/context.js +107 -0
  48. package/dist/memory/context.js.map +1 -0
  49. package/dist/memory/embedding-pool.d.ts +28 -0
  50. package/dist/memory/embedding-pool.d.ts.map +1 -0
  51. package/dist/memory/embedding-pool.js +135 -0
  52. package/dist/memory/embedding-pool.js.map +1 -0
  53. package/dist/memory/embedding-worker.d.ts +2 -0
  54. package/dist/memory/embedding-worker.d.ts.map +1 -0
  55. package/dist/memory/embedding-worker.js +32 -0
  56. package/dist/memory/embedding-worker.js.map +1 -0
  57. package/dist/memory/index.d.ts +32 -0
  58. package/dist/memory/index.d.ts.map +1 -0
  59. package/dist/memory/index.js +441 -0
  60. package/dist/memory/index.js.map +1 -0
  61. package/dist/memory/model-files.d.ts +9 -0
  62. package/dist/memory/model-files.d.ts.map +1 -0
  63. package/dist/memory/model-files.js +13 -0
  64. package/dist/memory/model-files.js.map +1 -0
  65. package/dist/memory/model.d.ts +15 -0
  66. package/dist/memory/model.d.ts.map +1 -0
  67. package/dist/memory/model.js +147 -0
  68. package/dist/memory/model.js.map +1 -0
  69. package/dist/memory/readiness.d.ts +16 -0
  70. package/dist/memory/readiness.d.ts.map +1 -0
  71. package/dist/memory/readiness.js +131 -0
  72. package/dist/memory/readiness.js.map +1 -0
  73. package/dist/memory/reconcile.d.ts +11 -0
  74. package/dist/memory/reconcile.d.ts.map +1 -0
  75. package/dist/memory/reconcile.js +132 -0
  76. package/dist/memory/reconcile.js.map +1 -0
  77. package/dist/memory/service.d.ts +10 -0
  78. package/dist/memory/service.d.ts.map +1 -0
  79. package/dist/memory/service.js +243 -0
  80. package/dist/memory/service.js.map +1 -0
  81. package/dist/memory/sources.d.ts +15 -0
  82. package/dist/memory/sources.d.ts.map +1 -0
  83. package/dist/memory/sources.js +94 -0
  84. package/dist/memory/sources.js.map +1 -0
  85. package/dist/memory/stamps.d.ts +13 -0
  86. package/dist/memory/stamps.d.ts.map +1 -0
  87. package/dist/memory/stamps.js +101 -0
  88. package/dist/memory/stamps.js.map +1 -0
  89. package/dist/memory/storage.d.ts +5 -0
  90. package/dist/memory/storage.d.ts.map +1 -0
  91. package/dist/memory/storage.js +116 -0
  92. package/dist/memory/storage.js.map +1 -0
  93. package/dist/memory/types.d.ts +89 -0
  94. package/dist/memory/types.d.ts.map +1 -0
  95. package/dist/memory/types.js +8 -0
  96. package/dist/memory/types.js.map +1 -0
  97. package/dist/memory/worker.d.ts +2 -0
  98. package/dist/memory/worker.d.ts.map +1 -0
  99. package/dist/memory/worker.js +84 -0
  100. package/dist/memory/worker.js.map +1 -0
  101. package/dist/npm-cli.d.ts +4 -0
  102. package/dist/npm-cli.d.ts.map +1 -0
  103. package/dist/npm-cli.js +36 -0
  104. package/dist/npm-cli.js.map +1 -0
  105. package/dist/pi/runtime.d.ts +34 -0
  106. package/dist/pi/runtime.d.ts.map +1 -0
  107. package/dist/pi/runtime.js +210 -0
  108. package/dist/pi/runtime.js.map +1 -0
  109. package/dist/pi/setup.d.ts +5 -0
  110. package/dist/pi/setup.d.ts.map +1 -0
  111. package/dist/pi/setup.js +147 -0
  112. package/dist/pi/setup.js.map +1 -0
  113. package/dist/routes/auth.d.ts.map +1 -1
  114. package/dist/routes/auth.js +3 -1
  115. package/dist/routes/auth.js.map +1 -1
  116. package/dist/routes/live-voice.d.ts +3 -0
  117. package/dist/routes/live-voice.d.ts.map +1 -0
  118. package/dist/routes/live-voice.js +49 -0
  119. package/dist/routes/live-voice.js.map +1 -0
  120. package/dist/routes/{browse.d.ts → memory.d.ts} +1 -1
  121. package/dist/routes/memory.d.ts.map +1 -0
  122. package/dist/routes/memory.js +18 -0
  123. package/dist/routes/memory.js.map +1 -0
  124. package/dist/routes/{tasks.d.ts → sync.d.ts} +1 -1
  125. package/dist/routes/sync.d.ts.map +1 -0
  126. package/dist/routes/sync.js +145 -0
  127. package/dist/routes/sync.js.map +1 -0
  128. package/dist/routes/{projects.d.ts → voice.d.ts} +1 -1
  129. package/dist/routes/voice.d.ts.map +1 -0
  130. package/dist/routes/voice.js +35 -0
  131. package/dist/routes/voice.js.map +1 -0
  132. package/dist/server-state.d.ts +30 -0
  133. package/dist/server-state.d.ts.map +1 -0
  134. package/dist/server-state.js +113 -0
  135. package/dist/server-state.js.map +1 -0
  136. package/dist/server-status.d.ts +7 -0
  137. package/dist/server-status.d.ts.map +1 -0
  138. package/dist/server-status.js +34 -0
  139. package/dist/server-status.js.map +1 -0
  140. package/dist/server.d.ts +5 -1
  141. package/dist/server.d.ts.map +1 -1
  142. package/dist/server.js +148 -46
  143. package/dist/server.js.map +1 -1
  144. package/dist/sources/adapters.d.ts +15 -0
  145. package/dist/sources/adapters.d.ts.map +1 -0
  146. package/dist/sources/adapters.js +159 -0
  147. package/dist/sources/adapters.js.map +1 -0
  148. package/dist/sources/registry.d.ts +17 -0
  149. package/dist/sources/registry.d.ts.map +1 -0
  150. package/dist/sources/registry.js +56 -0
  151. package/dist/sources/registry.js.map +1 -0
  152. package/dist/sync/collector.d.ts +3 -0
  153. package/dist/sync/collector.d.ts.map +1 -0
  154. package/dist/sync/collector.js +324 -0
  155. package/dist/sync/collector.js.map +1 -0
  156. package/dist/sync/cost.d.ts +7 -0
  157. package/dist/sync/cost.d.ts.map +1 -0
  158. package/dist/sync/cost.js +31 -0
  159. package/dist/sync/cost.js.map +1 -0
  160. package/dist/sync/jsonl.d.ts +34 -0
  161. package/dist/sync/jsonl.d.ts.map +1 -0
  162. package/dist/sync/jsonl.js +161 -0
  163. package/dist/sync/jsonl.js.map +1 -0
  164. package/dist/sync/manager.d.ts +15 -0
  165. package/dist/sync/manager.d.ts.map +1 -0
  166. package/dist/sync/manager.js +287 -0
  167. package/dist/sync/manager.js.map +1 -0
  168. package/dist/sync/normalize.d.ts +22 -0
  169. package/dist/sync/normalize.d.ts.map +1 -0
  170. package/dist/sync/normalize.js +107 -0
  171. package/dist/sync/normalize.js.map +1 -0
  172. package/dist/sync/pi-output.d.ts +33 -0
  173. package/dist/sync/pi-output.d.ts.map +1 -0
  174. package/dist/sync/pi-output.js +186 -0
  175. package/dist/sync/pi-output.js.map +1 -0
  176. package/dist/sync/pi.d.ts +15 -0
  177. package/dist/sync/pi.d.ts.map +1 -0
  178. package/dist/sync/pi.js +149 -0
  179. package/dist/sync/pi.js.map +1 -0
  180. package/dist/sync/recap.d.ts +25 -0
  181. package/dist/sync/recap.d.ts.map +1 -0
  182. package/dist/sync/recap.js +118 -0
  183. package/dist/sync/recap.js.map +1 -0
  184. package/dist/sync/reconciliation.d.ts +16 -0
  185. package/dist/sync/reconciliation.d.ts.map +1 -0
  186. package/dist/sync/reconciliation.js +22 -0
  187. package/dist/sync/reconciliation.js.map +1 -0
  188. package/dist/sync/references.d.ts +10 -0
  189. package/dist/sync/references.d.ts.map +1 -0
  190. package/dist/sync/references.js +50 -0
  191. package/dist/sync/references.js.map +1 -0
  192. package/dist/sync/source-files.d.ts +16 -0
  193. package/dist/sync/source-files.d.ts.map +1 -0
  194. package/dist/sync/source-files.js +56 -0
  195. package/dist/sync/source-files.js.map +1 -0
  196. package/dist/sync/store.d.ts +36 -0
  197. package/dist/sync/store.d.ts.map +1 -0
  198. package/dist/sync/store.js +359 -0
  199. package/dist/sync/store.js.map +1 -0
  200. package/dist/sync/summary-budget.d.ts +19 -0
  201. package/dist/sync/summary-budget.d.ts.map +1 -0
  202. package/dist/sync/summary-budget.js +39 -0
  203. package/dist/sync/summary-budget.js.map +1 -0
  204. package/dist/sync/tree.d.ts +69 -0
  205. package/dist/sync/tree.d.ts.map +1 -0
  206. package/dist/sync/tree.js +599 -0
  207. package/dist/sync/tree.js.map +1 -0
  208. package/dist/tray/controller.d.ts +51 -0
  209. package/dist/tray/controller.d.ts.map +1 -0
  210. package/dist/tray/controller.js +178 -0
  211. package/dist/tray/controller.js.map +1 -0
  212. package/dist/tray/launcher.d.ts +3 -0
  213. package/dist/tray/launcher.d.ts.map +1 -0
  214. package/dist/tray/launcher.js +47 -0
  215. package/dist/tray/launcher.js.map +1 -0
  216. package/dist/tray/native.d.ts +12 -0
  217. package/dist/tray/native.d.ts.map +1 -0
  218. package/dist/tray/native.js +93 -0
  219. package/dist/tray/native.js.map +1 -0
  220. package/dist/tray/processes.d.ts +5 -0
  221. package/dist/tray/processes.d.ts.map +1 -0
  222. package/dist/tray/processes.js +99 -0
  223. package/dist/tray/processes.js.map +1 -0
  224. package/dist/tray/worker.d.ts +4 -0
  225. package/dist/tray/worker.d.ts.map +1 -0
  226. package/dist/tray/worker.js +150 -0
  227. package/dist/tray/worker.js.map +1 -0
  228. package/dist/types.d.ts +221 -20
  229. package/dist/types.d.ts.map +1 -1
  230. package/dist/voice/continuation.d.ts +25 -0
  231. package/dist/voice/continuation.d.ts.map +1 -0
  232. package/dist/voice/continuation.js +95 -0
  233. package/dist/voice/continuation.js.map +1 -0
  234. package/dist/voice/history-focus.d.ts +14 -0
  235. package/dist/voice/history-focus.d.ts.map +1 -0
  236. package/dist/voice/history-focus.js +39 -0
  237. package/dist/voice/history-focus.js.map +1 -0
  238. package/dist/voice/legacy-history.d.ts +5 -0
  239. package/dist/voice/legacy-history.d.ts.map +1 -0
  240. package/dist/voice/legacy-history.js +34 -0
  241. package/dist/voice/legacy-history.js.map +1 -0
  242. package/dist/voice/live-context.d.ts +14 -0
  243. package/dist/voice/live-context.d.ts.map +1 -0
  244. package/dist/voice/live-context.js +137 -0
  245. package/dist/voice/live-context.js.map +1 -0
  246. package/dist/voice/live.d.ts +37 -0
  247. package/dist/voice/live.d.ts.map +1 -0
  248. package/dist/voice/live.js +462 -0
  249. package/dist/voice/live.js.map +1 -0
  250. package/dist/voice/preparation.d.ts +8 -0
  251. package/dist/voice/preparation.d.ts.map +1 -0
  252. package/dist/voice/preparation.js +59 -0
  253. package/dist/voice/preparation.js.map +1 -0
  254. package/package.json +49 -16
  255. package/public/assets/index-BQFBaSKm.js +40 -0
  256. package/public/assets/index-CYCbTSh1.js +131 -0
  257. package/public/assets/index-DntUQtGK.css +1 -0
  258. package/public/assets/persona-BVIfx5k8.js +1 -0
  259. package/public/assets/persona-C_m1CVKe.css +1 -0
  260. package/public/assets/scene-CBV2oPhA.js +3854 -0
  261. package/public/index.html +6 -8
  262. package/public/persona/THREE-LICENSE.txt +21 -0
  263. package/public/persona/call-poster.webp +0 -0
  264. package/public/persona/chat-avatar.webp +0 -0
  265. package/public/persona/reference.jpg +0 -0
  266. package/public/persona/sample.wav +0 -0
  267. package/public/persona.html +7 -0
  268. package/runtime/pi/package-lock.json +1549 -0
  269. package/runtime/pi/package.json +12 -0
  270. package/tests/fixtures/voice-question.wav +0 -0
  271. package/tray/assets/error.ico +0 -0
  272. package/tray/assets/error.png +0 -0
  273. package/tray/assets/running.ico +0 -0
  274. package/tray/assets/running.png +0 -0
  275. package/tray/assets/starting.ico +0 -0
  276. package/tray/assets/starting.png +0 -0
  277. package/tray/assets/stopped.ico +0 -0
  278. package/tray/assets/stopped.png +0 -0
  279. package/tray/assets/stopping.ico +0 -0
  280. package/tray/assets/stopping.png +0 -0
  281. package/tray/macos.js +72 -0
  282. package/tray/windows.ps1 +104 -0
  283. package/voice/realtime/README.md +84 -0
  284. package/voice/realtime/backend.mjs +81 -0
  285. package/voice/realtime/native.mjs +210 -0
  286. package/voice/realtime/peer.d.mts +15 -0
  287. package/voice/realtime/peer.mjs +116 -0
  288. package/voice/realtime/probe-browser.mjs +81 -0
  289. package/voice/realtime/probe-server.mjs +86 -0
  290. package/voice/realtime/probe.html +11 -0
  291. package/voice/realtime/probe.mjs +42 -0
  292. package/voice/realtime/rpc.mjs +118 -0
  293. package/voice/realtime/setup.mjs +32 -0
  294. package/voice/tls.mjs +49 -0
  295. package/dist/db/queries.d.ts +0 -16
  296. package/dist/db/queries.d.ts.map +0 -1
  297. package/dist/db/queries.js +0 -91
  298. package/dist/db/queries.js.map +0 -1
  299. package/dist/docker/dockerfile.d.ts +0 -50
  300. package/dist/docker/dockerfile.d.ts.map +0 -1
  301. package/dist/docker/dockerfile.js +0 -160
  302. package/dist/docker/dockerfile.js.map +0 -1
  303. package/dist/docker/manager.d.ts +0 -42
  304. package/dist/docker/manager.d.ts.map +0 -1
  305. package/dist/docker/manager.js +0 -421
  306. package/dist/docker/manager.js.map +0 -1
  307. package/dist/git/status.d.ts +0 -76
  308. package/dist/git/status.d.ts.map +0 -1
  309. package/dist/git/status.js +0 -332
  310. package/dist/git/status.js.map +0 -1
  311. package/dist/routes/browse.d.ts.map +0 -1
  312. package/dist/routes/browse.js +0 -49
  313. package/dist/routes/browse.js.map +0 -1
  314. package/dist/routes/git.d.ts +0 -9
  315. package/dist/routes/git.d.ts.map +0 -1
  316. package/dist/routes/git.js +0 -338
  317. package/dist/routes/git.js.map +0 -1
  318. package/dist/routes/projects.d.ts.map +0 -1
  319. package/dist/routes/projects.js +0 -220
  320. package/dist/routes/projects.js.map +0 -1
  321. package/dist/routes/tasks.d.ts.map +0 -1
  322. package/dist/routes/tasks.js +0 -313
  323. package/dist/routes/tasks.js.map +0 -1
  324. package/draken.dockerfile.template +0 -18
  325. package/public/assets/index-3ngsG5kF.css +0 -1
  326. package/public/assets/index-B3YSD0ee.js +0 -252
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EvidenceReader = exports.recordPointer = void 0;
4
+ exports.encodeEvidence = encodeEvidence;
5
+ const normalize_1 = require("../sync/normalize");
6
+ const jsonl_1 = require("../sync/jsonl");
7
+ const registry_1 = require("../sources/registry");
8
+ const retained_text_1 = require("./retained-text");
9
+ const pointers = new WeakMap();
10
+ const UNAVAILABLE_EVIDENCE = 'Original session evidence is unavailable or changed. Restore the original session file; Draken does not keep a text copy.';
11
+ const recordPointer = (row) => ({ record_offset: row.record_offset, record_bytes: row.record_bytes, record_hash: row.record_hash });
12
+ exports.recordPointer = recordPointer;
13
+ function encodeEvidence(item, pointer) {
14
+ const { text: _text, unavailable: _unavailable, ...metadata } = item;
15
+ return JSON.stringify({ ...metadata, source_key: (0, normalize_1.sourceKey)(item), source_pointer: pointer });
16
+ }
17
+ /** Frozen membership, attribution and projection; original bytes stay in pi.
18
+ * Share one reader per snapshot/request rather than reopening a file per item. */
19
+ class EvidenceReader {
20
+ db;
21
+ reader;
22
+ paths = new Map();
23
+ constructor(db, root = (0, registry_1.getSourceRoots)(), cache) {
24
+ this.db = db;
25
+ this.reader = new jsonl_1.RecordReader(root, cache);
26
+ }
27
+ project(item, pointer) {
28
+ if (pointer.version !== 1 && pointer.version !== 2)
29
+ throw new Error('Unknown frozen pointer version');
30
+ const source = pointer.version === 1 ? { agent: 'pi', external_id: item.session_id, parser_version: 1 } : pointer.source;
31
+ if (pointer.version === 2 && (!(0, registry_1.validIdentity)(source) || (0, registry_1.sessionId)(source) !== item.session_id))
32
+ throw new Error('Frozen source identity changed');
33
+ if (item.agent && item.agent !== source.agent)
34
+ throw new Error('Frozen agent attribution changed');
35
+ if (!this.paths.has(item.session_id))
36
+ this.paths.set(item.session_id, this.db.prepare('SELECT path FROM agent_sessions WHERE id=?').get(item.session_id)?.path);
37
+ const paths = [...new Set([this.paths.get(item.session_id), item.source_path].filter((value) => Boolean(value)))];
38
+ for (const file of paths) {
39
+ try {
40
+ const original = this.reader.read(item.session_id, file, pointer.original, item.entry_id, item.event_key, pointer.normalization, undefined, source);
41
+ if (original.role !== item.role || original.timestamp !== item.timestamp)
42
+ throw new Error('Frozen attribution changed');
43
+ let text = original.text;
44
+ if (pointer.edit) {
45
+ const edit = this.reader.read(item.session_id, file, pointer.edit, pointer.edit.entry_id, pointer.edit.event_key, pointer.edit.normalization, undefined, source);
46
+ if (edit.type !== 'context_edit' || edit.target_id !== item.entry_id || edit.replacement === null)
47
+ throw new Error('Invalid frozen edit');
48
+ text = edit.replacement;
49
+ }
50
+ if (pointer.clip) {
51
+ if (pointer.clip.limit !== 2000)
52
+ throw new Error('Unknown frozen excerpt limit');
53
+ text = (0, normalize_1.cleanText)(text, pointer.clip.limit, pointer.clip.normalization);
54
+ }
55
+ if ((0, normalize_1.digest)(text) !== pointer.text_hash)
56
+ throw new Error('Frozen projection changed');
57
+ return text;
58
+ }
59
+ catch { /* A recorded old path may still resolve after a file move. */ }
60
+ }
61
+ throw new Error(UNAVAILABLE_EVIDENCE);
62
+ }
63
+ read(value, tolerateUnavailable = false) {
64
+ const encoded = typeof value === 'string' ? JSON.parse(value) : value;
65
+ if (!encoded.source_pointer)
66
+ return (0, retained_text_1.thawEvidence)(this.db, encoded); // Legacy migration/import reader only.
67
+ const { source_pointer, source_key, ...metadata } = encoded;
68
+ let item;
69
+ try {
70
+ item = { ...metadata, text: this.project(metadata, source_pointer) };
71
+ }
72
+ catch (error) {
73
+ if (!tolerateUnavailable)
74
+ throw error;
75
+ item = { ...metadata, text: '', source_key, unavailable: UNAVAILABLE_EVIDENCE };
76
+ }
77
+ pointers.set(item, source_pointer);
78
+ return item;
79
+ }
80
+ freeze(item) {
81
+ const previous = pointers.get(item);
82
+ if (previous) {
83
+ if (this.project(item, previous) !== item.text)
84
+ throw new Error('Frozen evidence changed');
85
+ return encodeEvidence(item, previous);
86
+ }
87
+ const row = this.db.prepare('SELECT e.*,s.agent,s.external_id FROM agent_entries e JOIN agent_sessions s ON s.id=e.session_id WHERE e.session_id=? AND e.entry_id=?').get(item.session_id, item.entry_id);
88
+ if (!row || row.event_key !== item.event_key || !row.record_hash)
89
+ throw new Error('Cannot freeze evidence without its verified source record');
90
+ const pointer = { version: row.agent === 'pi' ? 1 : 2, ...(row.agent !== 'pi' ? { source: { agent: row.agent, external_id: row.external_id, parser_version: row.parser_version ?? 1 } } : {}), original: (0, exports.recordPointer)(row), normalization: row.normalization ?? 2, text_hash: (0, normalize_1.digest)(item.text) };
91
+ if (row.effective_id !== null) {
92
+ const edit = this.db.prepare('SELECT * FROM agent_entries WHERE id=? AND session_id=?').get(row.effective_id, item.session_id);
93
+ if (!edit || edit.target_id !== item.entry_id || !edit.record_hash)
94
+ throw new Error('Cannot freeze an unverified context edit');
95
+ pointer.edit = { ...(0, exports.recordPointer)(edit), entry_id: edit.entry_id, event_key: edit.event_key, normalization: edit.normalization ?? 2 };
96
+ }
97
+ try {
98
+ this.project(item, pointer);
99
+ }
100
+ catch {
101
+ pointer.clip = { limit: 2000, normalization: 2 };
102
+ this.project(item, pointer);
103
+ }
104
+ pointers.set(item, pointer);
105
+ return encodeEvidence(item, pointer);
106
+ }
107
+ close() { this.reader.close(); this.paths.clear(); }
108
+ }
109
+ exports.EvidenceReader = EvidenceReader;
110
+ //# sourceMappingURL=evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/db/evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function entryTable(name: string, legacy?: boolean): string;
3
+ /** Atomic representation migration. No scans, model calls, review or source-file writes.
4
+ * Unverifiable historical imports are preserved once, not discarded or guessed.
5
+ */
6
+ export declare function migratePointers(db: Database.Database): void;
7
+ //# sourceMappingURL=pointer-migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer-migration.d.ts","sourceRoot":"","sources":["../../src/db/pointer-migration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,UAAO,GAAG,MAAM,CAiB9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAgE3D"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.entryTable = entryTable;
7
+ exports.migratePointers = migratePointers;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const source_files_1 = require("../sync/source-files");
10
+ const normalize_1 = require("../sync/normalize");
11
+ const retained_text_1 = require("./retained-text");
12
+ function entryTable(name, legacy = true) {
13
+ return `CREATE TABLE IF NOT EXISTS ${name} (
14
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
15
+ session_id TEXT NOT NULL REFERENCES agent_sessions(id),
16
+ entry_id TEXT NOT NULL, parent_id TEXT, timestamp TEXT NOT NULL,
17
+ type TEXT NOT NULL, role TEXT NOT NULL, event_key TEXT NOT NULL,
18
+ is_activity INTEGER NOT NULL, active INTEGER NOT NULL DEFAULT 0,
19
+ present INTEGER NOT NULL DEFAULT 1, target_id TEXT,
20
+ record_offset INTEGER, record_bytes INTEGER, record_hash TEXT,
21
+ text_length INTEGER NOT NULL DEFAULT 0, replacement_length INTEGER NOT NULL DEFAULT 0,
22
+ effective_length INTEGER NOT NULL DEFAULT 0, effective_id INTEGER,
23
+ normalization INTEGER NOT NULL DEFAULT 2,
24
+ ${legacy ? `legacy_text_ref TEXT REFERENCES retained_text(key),
25
+ legacy_replacement_ref TEXT REFERENCES retained_text(key),
26
+ effective_legacy_ref TEXT REFERENCES retained_text(key),` : ''}
27
+ UNIQUE(session_id,entry_id)
28
+ )`;
29
+ }
30
+ /** Atomic representation migration. No scans, model calls, review or source-file writes.
31
+ * Unverifiable historical imports are preserved once, not discarded or guessed.
32
+ */
33
+ function migratePointers(db) {
34
+ const version = db.prepare("SELECT value FROM sync_settings WHERE key='storage_schema'").get()?.value;
35
+ if (version === 'pointer-v1' || version === 'pointer-v2')
36
+ return;
37
+ if (version)
38
+ throw new Error('Unknown canonical storage version; existing data was not converted');
39
+ db.transaction(() => {
40
+ const columns = db.prepare('PRAGMA table_info(agent_entries)').all();
41
+ if (columns.some(column => column.name === 'text')) {
42
+ const sequence = db.prepare("SELECT seq FROM sqlite_sequence WHERE name='agent_entries'").get()?.seq || 0;
43
+ db.exec(entryTable('agent_entries_pointer'));
44
+ const insert = db.prepare(`INSERT INTO agent_entries_pointer
45
+ (id,session_id,entry_id,parent_id,timestamp,type,role,event_key,is_activity,active,present,target_id,
46
+ record_offset,record_bytes,record_hash,text_length,replacement_length,effective_length,effective_id,legacy_text_ref,legacy_replacement_ref,effective_legacy_ref)
47
+ VALUES (@id,@session_id,@entry_id,@parent_id,@timestamp,@type,@role,@event_key,@is_activity,@active,@present,@target_id,
48
+ @record_offset,@record_bytes,@record_hash,@text_length,@replacement_length,@effective_length,@effective_id,@legacy_text_ref,@legacy_replacement_ref,@effective_legacy_ref)`);
49
+ for (const session of db.prepare('SELECT id,path,file_identity,byte_offset,leaf_id FROM agent_sessions').all()) {
50
+ const originals = db.prepare('SELECT * FROM agent_entries WHERE session_id=? ORDER BY id').all(session.id);
51
+ const wanted = new Set(originals.map(row => row.entry_id));
52
+ const found = new Map();
53
+ let fd;
54
+ try {
55
+ fd = (0, source_files_1.openSessionFile)(session.path, (0, source_files_1.getSessionRoot)(), session.file_identity);
56
+ (0, source_files_1.verifySessionHeader)(fd, session.id);
57
+ for (const pointer of (0, source_files_1.fileRecords)(fd, Math.min(fs_1.default.fstatSync(fd).size, session.byte_offset))) {
58
+ if (!wanted.has(pointer.value?.id))
59
+ continue;
60
+ const entry = (0, normalize_1.normalizeEntry)(pointer.value);
61
+ if (entry)
62
+ found.set(entry.entry_id, { record_offset: pointer.record_offset, record_bytes: pointer.record_bytes, record_hash: pointer.record_hash, entry });
63
+ }
64
+ }
65
+ catch {
66
+ found.clear();
67
+ } // Retain old text when a source cannot be safely verified.
68
+ finally {
69
+ if (fd !== undefined)
70
+ fs_1.default.closeSync(fd);
71
+ }
72
+ const byId = new Map(originals.filter(row => row.present).map(row => [row.entry_id, row]));
73
+ const branch = [], visited = new Set(), edits = new Map();
74
+ let leaf = session.leaf_id;
75
+ while (leaf && byId.has(leaf) && !visited.has(leaf)) {
76
+ visited.add(leaf);
77
+ const entry = byId.get(leaf);
78
+ branch.push(entry);
79
+ leaf = entry.parent_id;
80
+ }
81
+ for (const edit of branch.reverse())
82
+ if (edit.active && edit.type === 'context_edit' && edit.target_id)
83
+ edits.set(edit.target_id, edit);
84
+ for (const row of originals) {
85
+ const edit = row.active ? edits.get(row.entry_id) : undefined;
86
+ const effectiveId = edit && (edit.replacement || '') === row.effective_text ? edit.id : null;
87
+ const pointer = found.get(row.entry_id);
88
+ const verified = pointer && pointer.entry.event_key === row.event_key && pointer.entry.text === row.text && pointer.entry.replacement === row.replacement;
89
+ insert.run({ ...row,
90
+ record_offset: verified ? pointer.record_offset : null, record_bytes: verified ? pointer.record_bytes : null, record_hash: verified ? pointer.record_hash : null,
91
+ text_length: row.text.length, replacement_length: row.replacement?.length || 0, effective_length: row.effective_text.length, effective_id: effectiveId,
92
+ legacy_text_ref: !verified && row.text ? (0, retained_text_1.retainText)(db, row.text) : null,
93
+ legacy_replacement_ref: !verified && row.replacement !== null ? (0, retained_text_1.retainText)(db, row.replacement) : null,
94
+ effective_legacy_ref: !effectiveId && row.effective_text && row.effective_text !== row.text ? (0, retained_text_1.retainText)(db, row.effective_text) : null,
95
+ });
96
+ }
97
+ }
98
+ const before = db.prepare('SELECT COUNT(*) n FROM agent_entries').get().n;
99
+ if (db.prepare('SELECT COUNT(*) n FROM agent_entries_pointer').get().n !== before)
100
+ throw new Error('Pointer migration did not preserve every session entry');
101
+ db.exec('DROP TABLE agent_entries; ALTER TABLE agent_entries_pointer RENAME TO agent_entries');
102
+ if (!db.prepare("UPDATE sqlite_sequence SET seq=MAX(seq,?) WHERE name='agent_entries'").run(sequence).changes && sequence)
103
+ db.prepare('INSERT INTO sqlite_sequence(name,seq) VALUES(?,?)').run('agent_entries', sequence);
104
+ }
105
+ db.exec('CREATE INDEX IF NOT EXISTS agent_entries_pending ON agent_entries(active,is_activity,present); CREATE INDEX IF NOT EXISTS agent_entries_event ON agent_entries(event_key)');
106
+ const update = db.prepare('UPDATE sync_items SET evidence_json=? WHERE sync_id=? AND event_key=?');
107
+ for (const row of db.prepare('SELECT sync_id,event_key,evidence_json FROM sync_items').all()) {
108
+ update.run((0, retained_text_1.freezeEvidence)(db, (0, retained_text_1.thawEvidence)(db, row.evidence_json)), row.sync_id, row.event_key);
109
+ }
110
+ for (const row of db.prepare('SELECT id,context_json FROM syncs').all()) {
111
+ const context = JSON.parse(row.context_json).map(item => JSON.parse((0, retained_text_1.freezeEvidence)(db, (0, retained_text_1.thawEvidence)(db, item))));
112
+ db.prepare('UPDATE syncs SET context_json=? WHERE id=?').run(JSON.stringify(context), row.id);
113
+ }
114
+ db.prepare("INSERT OR REPLACE INTO sync_settings VALUES('storage_schema','pointer-v1')").run();
115
+ })();
116
+ }
117
+ //# sourceMappingURL=pointer-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer-migration.js","sourceRoot":"","sources":["../../src/db/pointer-migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { Evidence } from '../types';
3
+ /** Immutable canonical text shared by frozen evidence and unresolvable legacy imports. */
4
+ export declare function retainText(db: Database.Database, text: string): string;
5
+ export declare function retainedText(db: Database.Database, key: string): string;
6
+ export declare function freezeEvidence(db: Database.Database, item: Evidence): string;
7
+ export declare function thawEvidence(db: Database.Database, value: string | Record<string, any>): Evidence;
8
+ //# sourceMappingURL=retained-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retained-text.d.ts","sourceRoot":"","sources":["../../src/db/retained-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGzC,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtE;AACD,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvE;AACD,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAG5E;AACD,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,QAAQ,CAOjG"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.retainText = retainText;
4
+ exports.retainedText = retainedText;
5
+ exports.freezeEvidence = freezeEvidence;
6
+ exports.thawEvidence = thawEvidence;
7
+ const normalize_1 = require("../sync/normalize");
8
+ /** Immutable canonical text shared by frozen evidence and unresolvable legacy imports. */
9
+ function retainText(db, text) {
10
+ const key = (0, normalize_1.digest)(text);
11
+ db.prepare('INSERT OR IGNORE INTO retained_text(key,text) VALUES(?,?)').run(key, text);
12
+ if (retainedText(db, key) !== text)
13
+ throw new Error('Retained evidence hash mismatch');
14
+ return key;
15
+ }
16
+ function retainedText(db, key) {
17
+ const row = db.prepare('SELECT text FROM retained_text WHERE key=?').get(key);
18
+ if (!row || (0, normalize_1.digest)(row.text) !== key)
19
+ throw new Error('Retained evidence is missing or damaged');
20
+ return row.text;
21
+ }
22
+ function freezeEvidence(db, item) {
23
+ const { text, ...metadata } = item;
24
+ return JSON.stringify({ ...metadata, text_ref: retainText(db, text) });
25
+ }
26
+ function thawEvidence(db, value) {
27
+ const item = typeof value === 'string' ? JSON.parse(value) : value;
28
+ // Imported older snapshots and test fixtures remain readable, never silently rewritten on read.
29
+ if (typeof item.text === 'string')
30
+ return item;
31
+ const { text_ref, ...metadata } = item;
32
+ if (typeof text_ref !== 'string')
33
+ throw new Error('Frozen evidence has no content reference');
34
+ return { ...metadata, text: retainedText(db, text_ref) };
35
+ }
36
+ //# sourceMappingURL=retained-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retained-text.js","sourceRoot":"","sources":["../../src/db/retained-text.ts"],"names":[],"mappings":";;AAKA,gCAKC;AACD,oCAIC;AACD,wCAGC;AACD,oCAOC;AAzBD,iDAA2C;AAE3C,0FAA0F;AAC1F,SAAgB,UAAU,CAAC,EAAqB,EAAE,IAAY;IAC5D,MAAM,GAAG,GAAG,IAAA,kBAAM,EAAC,IAAI,CAAC,CAAC;IACzB,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACvF,IAAI,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACvF,OAAO,GAAG,CAAC;AACb,CAAC;AACD,SAAgB,YAAY,CAAC,EAAqB,EAAE,GAAW;IAC7D,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC,GAAG,CAAC,GAAG,CAAiC,CAAC;IAC9G,IAAI,CAAC,GAAG,IAAI,IAAA,kBAAM,EAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACjG,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AACD,SAAgB,cAAc,CAAC,EAAqB,EAAE,IAAc;IAClE,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC;AACD,SAAgB,YAAY,CAAC,EAAqB,EAAE,KAAmC;IACrF,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACnE,gGAAgG;IAChG,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAgB,CAAC;IAC3D,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC;IACvC,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9F,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAc,CAAC;AACvE,CAAC"}
@@ -1,10 +1,6 @@
1
1
  import Database from 'better-sqlite3';
2
- /**
3
- * Get the draken data directory
4
- * Uses DRAKEN_DATA_DIR env var if set, otherwise ~/.draken
5
- * Works cross-platform (Windows, macOS, Linux)
6
- */
7
2
  export declare function getDataDir(): string;
8
3
  export declare function getDb(): Database.Database;
4
+ export declare function initSchema(database: Database.Database): void;
9
5
  export declare function closeDb(): void;
10
6
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAKnC;AAOD,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAczC;AA2CD,wBAAgB,OAAO,IAAI,IAAI,CAK9B"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAQtC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAID,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAazC;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAuL5D;AAED,wBAAgB,OAAO,IAAI,IAAI,CAG9B"}
package/dist/db/schema.js CHANGED
@@ -5,81 +5,232 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getDataDir = getDataDir;
7
7
  exports.getDb = getDb;
8
+ exports.initSchema = initSchema;
8
9
  exports.closeDb = closeDb;
9
10
  const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
10
11
  const path_1 = __importDefault(require("path"));
11
12
  const os_1 = __importDefault(require("os"));
12
13
  const fs_1 = __importDefault(require("fs"));
13
- /**
14
- * Get the draken data directory
15
- * Uses DRAKEN_DATA_DIR env var if set, otherwise ~/.draken
16
- * Works cross-platform (Windows, macOS, Linux)
17
- */
14
+ const pointer_migration_1 = require("./pointer-migration");
15
+ const snapshot_pointers_1 = require("./snapshot-pointers");
16
+ const agent_migration_1 = require("./agent-migration");
18
17
  function getDataDir() {
19
- if (process.env.DRAKEN_DATA_DIR) {
20
- return process.env.DRAKEN_DATA_DIR;
21
- }
22
- return path_1.default.join(os_1.default.homedir(), '.draken');
18
+ return path_1.default.resolve(process.env.DRAKEN_DATA_DIR || path_1.default.join(os_1.default.homedir(), '.draken'));
23
19
  }
24
- const DATA_DIR = getDataDir();
25
- const DB_PATH = path_1.default.join(DATA_DIR, 'draken.db');
26
20
  let db = null;
27
21
  function getDb() {
28
22
  if (!db) {
29
- // Ensure data directory exists
30
- if (!fs_1.default.existsSync(DATA_DIR)) {
31
- fs_1.default.mkdirSync(DATA_DIR, { recursive: true });
32
- }
33
- db = new better_sqlite3_1.default(DB_PATH);
23
+ const dir = getDataDir();
24
+ fs_1.default.mkdirSync(dir, { recursive: true, mode: 0o700 });
25
+ db = new better_sqlite3_1.default(path_1.default.join(dir, 'draken.db'));
26
+ // Set mode before SQLite creates WAL/SHM sidecars, which inherit database permissions.
27
+ fs_1.default.chmodSync(path_1.default.join(dir, 'draken.db'), 0o600);
34
28
  db.pragma('journal_mode = WAL');
35
- initSchema(db);
36
- console.log(`Database: ${DB_PATH}`);
29
+ db.pragma('foreign_keys = ON');
30
+ db.pragma('busy_timeout = 5000');
31
+ try {
32
+ initSchema(db);
33
+ }
34
+ catch (error) {
35
+ db.close();
36
+ db = null;
37
+ throw error;
38
+ }
37
39
  }
38
40
  return db;
39
41
  }
40
- function initSchema(db) {
41
- // Create tables
42
- db.exec(`
43
- CREATE TABLE IF NOT EXISTS projects (
44
- id INTEGER PRIMARY KEY AUTOINCREMENT,
45
- name TEXT NOT NULL,
42
+ function initSchema(database) {
43
+ database.transaction(() => {
44
+ (0, agent_migration_1.renameAgentTables)(database);
45
+ const pointerOnly = database.prepare("SELECT 1 FROM sqlite_schema WHERE name='sync_settings'").get()
46
+ && database.prepare("SELECT value FROM sync_settings WHERE key='storage_schema'").get()?.value === 'pointer-v2';
47
+ // Existing project/task tables are untouched. The explicit pointer migration
48
+ // below changes representation transactionally, not historical evidence.
49
+ database.exec(`
50
+ CREATE TABLE IF NOT EXISTS sync_settings (
51
+ key TEXT PRIMARY KEY,
52
+ value TEXT NOT NULL
53
+ );
54
+ CREATE TABLE IF NOT EXISTS agent_sessions (
55
+ id TEXT PRIMARY KEY,
46
56
  path TEXT NOT NULL UNIQUE,
47
- dockerfile_exists INTEGER DEFAULT 0,
48
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP
57
+ cwd TEXT NOT NULL,
58
+ name TEXT NOT NULL DEFAULT '',
59
+ included INTEGER NOT NULL DEFAULT 1,
60
+ missing INTEGER NOT NULL DEFAULT 0,
61
+ modified_at TEXT NOT NULL,
62
+ file_identity TEXT NOT NULL DEFAULT '',
63
+ byte_offset INTEGER NOT NULL DEFAULT 0,
64
+ boundary_hash TEXT NOT NULL DEFAULT '',
65
+ prefix_hash TEXT NOT NULL DEFAULT '',
66
+ leaf_id TEXT
67
+ );
68
+ ${pointerOnly ? '' : 'CREATE TABLE IF NOT EXISTS retained_text (key TEXT PRIMARY KEY, text TEXT NOT NULL);'}
69
+ ${(0, pointer_migration_1.entryTable)('agent_entries', !pointerOnly)};
70
+ CREATE INDEX IF NOT EXISTS agent_entries_pending ON agent_entries(active, is_activity, present);
71
+ CREATE INDEX IF NOT EXISTS agent_entries_event ON agent_entries(event_key);
72
+ CREATE TABLE IF NOT EXISTS syncs (
73
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
74
+ status TEXT NOT NULL DEFAULT 'open' CHECK(status IN ('open', 'completed', 'discarded')),
75
+ created_at TEXT NOT NULL,
76
+ completed_at TEXT,
77
+ briefing TEXT NOT NULL DEFAULT '',
78
+ decisions TEXT NOT NULL DEFAULT '',
79
+ carry_forward TEXT NOT NULL DEFAULT '',
80
+ context_json TEXT NOT NULL DEFAULT '[]',
81
+ memory_json TEXT NOT NULL DEFAULT '[]',
82
+ remaining_count INTEGER NOT NULL DEFAULT 0
83
+ );
84
+ -- Snapshots can be opened independently. Inclusion is not review/coverage.
85
+ DROP INDEX IF EXISTS one_open_sync;
86
+ CREATE TABLE IF NOT EXISTS sync_items (
87
+ sync_id INTEGER NOT NULL REFERENCES syncs(id),
88
+ event_key TEXT NOT NULL,
89
+ evidence_json TEXT NOT NULL,
90
+ PRIMARY KEY(sync_id, event_key)
91
+ );
92
+ CREATE INDEX IF NOT EXISTS sync_items_event ON sync_items(event_key);
93
+ CREATE TABLE IF NOT EXISTS sync_presentations (
94
+ sync_id INTEGER PRIMARY KEY REFERENCES syncs(id),
95
+ request_id TEXT UNIQUE,
96
+ memory_inputs_json TEXT NOT NULL DEFAULT '[]',
97
+ recap TEXT NOT NULL DEFAULT '',
98
+ recap_hash TEXT NOT NULL DEFAULT '',
99
+ recap_state TEXT NOT NULL DEFAULT 'empty',
100
+ recap_error TEXT NOT NULL DEFAULT ''
101
+ );
102
+ CREATE TABLE IF NOT EXISTS sync_recap_cache (
103
+ key TEXT PRIMARY KEY,
104
+ summary TEXT NOT NULL,
105
+ created_at TEXT NOT NULL
106
+ );
107
+ CREATE TABLE IF NOT EXISTS sync_coverage (
108
+ event_key TEXT PRIMARY KEY,
109
+ sync_id INTEGER NOT NULL REFERENCES syncs(id)
110
+ );
111
+ CREATE TABLE IF NOT EXISTS summary_cache (
112
+ key TEXT PRIMARY KEY,
113
+ kind TEXT NOT NULL,
114
+ model TEXT NOT NULL,
115
+ prompt_version TEXT NOT NULL,
116
+ output_json TEXT NOT NULL,
117
+ created_at TEXT NOT NULL
49
118
  );
50
-
51
- CREATE TABLE IF NOT EXISTS tasks (
119
+ CREATE TABLE IF NOT EXISTS sync_tree_nodes (
120
+ sync_id INTEGER NOT NULL REFERENCES syncs(id),
121
+ key TEXT NOT NULL,
122
+ kind TEXT NOT NULL,
123
+ label TEXT NOT NULL,
124
+ status TEXT NOT NULL DEFAULT 'pending',
125
+ children_json TEXT NOT NULL,
126
+ source_count INTEGER NOT NULL,
127
+ error TEXT NOT NULL DEFAULT '',
128
+ PRIMARY KEY(sync_id, key)
129
+ );
130
+ CREATE TABLE IF NOT EXISTS sync_runs (
131
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
132
+ sync_id INTEGER NOT NULL REFERENCES syncs(id),
133
+ status TEXT NOT NULL DEFAULT 'running',
134
+ stage TEXT NOT NULL DEFAULT 'Planning',
135
+ summary_model TEXT NOT NULL,
136
+ final_model TEXT NOT NULL,
137
+ invocations INTEGER NOT NULL DEFAULT 0,
138
+ max_invocations INTEGER NOT NULL,
139
+ processed_entries INTEGER NOT NULL DEFAULT 0,
140
+ total_entries INTEGER NOT NULL,
141
+ cache_hits INTEGER NOT NULL DEFAULT 0,
142
+ error TEXT NOT NULL DEFAULT '',
143
+ question TEXT,
144
+ started_at TEXT NOT NULL,
145
+ completed_at TEXT
146
+ );
147
+ CREATE INDEX IF NOT EXISTS sync_runs_sync ON sync_runs(sync_id, id);
148
+ CREATE TABLE IF NOT EXISTS voice_calls (
149
+ id TEXT PRIMARY KEY,
150
+ sync_id INTEGER NOT NULL REFERENCES syncs(id),
151
+ status TEXT NOT NULL DEFAULT 'active',
152
+ model TEXT NOT NULL,
153
+ started_at TEXT NOT NULL,
154
+ ended_at TEXT,
155
+ end_reason TEXT NOT NULL DEFAULT ''
156
+ );
157
+ CREATE UNIQUE INDEX IF NOT EXISTS one_voice_call ON voice_calls(status) WHERE status = 'active';
158
+ CREATE TABLE IF NOT EXISTS voice_turns (
159
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
160
+ call_id TEXT NOT NULL REFERENCES voice_calls(id),
161
+ request_id TEXT NOT NULL,
162
+ question TEXT NOT NULL,
163
+ answer TEXT NOT NULL DEFAULT '',
164
+ evidence_json TEXT NOT NULL DEFAULT '[]',
165
+ heard_text TEXT NOT NULL DEFAULT '',
166
+ status TEXT NOT NULL DEFAULT 'thinking',
167
+ error TEXT NOT NULL DEFAULT '',
168
+ messages_saved INTEGER NOT NULL DEFAULT 0,
169
+ started_at TEXT NOT NULL,
170
+ completed_at TEXT,
171
+ model_ms INTEGER,
172
+ first_audio_ms INTEGER,
173
+ UNIQUE(call_id, request_id)
174
+ );
175
+ CREATE INDEX IF NOT EXISTS voice_turns_call ON voice_turns(call_id, id);
176
+ CREATE TABLE IF NOT EXISTS live_calls (
177
+ id TEXT PRIMARY KEY,
178
+ sync_id INTEGER NOT NULL REFERENCES syncs(id),
179
+ status TEXT NOT NULL DEFAULT 'active',
180
+ started_at TEXT NOT NULL,
181
+ ended_at TEXT,
182
+ end_reason TEXT NOT NULL DEFAULT ''
183
+ );
184
+ CREATE UNIQUE INDEX IF NOT EXISTS one_live_call ON live_calls(status) WHERE status = 'active';
185
+ CREATE TABLE IF NOT EXISTS live_messages (
52
186
  id INTEGER PRIMARY KEY AUTOINCREMENT,
53
- project_id INTEGER NOT NULL,
54
- prompt TEXT NOT NULL,
55
- status TEXT DEFAULT 'pending',
56
- container_id TEXT,
57
- logs TEXT,
58
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
59
- completed_at DATETIME,
60
- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
187
+ call_id TEXT NOT NULL REFERENCES live_calls(id),
188
+ request_id TEXT NOT NULL,
189
+ role TEXT NOT NULL CHECK(role IN ('user', 'assistant')),
190
+ text TEXT NOT NULL DEFAULT '',
191
+ sources_json TEXT NOT NULL DEFAULT '[]',
192
+ status TEXT NOT NULL DEFAULT 'streaming',
193
+ observed_audio_ms INTEGER NOT NULL DEFAULT 0,
194
+ first_audio_ms INTEGER,
195
+ started_at TEXT NOT NULL,
196
+ UNIQUE(call_id, request_id)
197
+ );
198
+ CREATE INDEX IF NOT EXISTS live_messages_call ON live_messages(call_id, id);
199
+ CREATE TABLE IF NOT EXISTS sync_messages (
200
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
201
+ sync_id INTEGER NOT NULL REFERENCES syncs(id),
202
+ role TEXT NOT NULL CHECK(role IN ('user', 'assistant')),
203
+ content TEXT NOT NULL,
204
+ created_at TEXT NOT NULL
61
205
  );
62
-
63
- CREATE INDEX IF NOT EXISTS idx_tasks_project_id ON tasks(project_id);
64
- CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
65
206
  `);
66
- // Migration: Add session_id column if it doesn't exist
67
- try {
68
- db.exec(`ALTER TABLE tasks ADD COLUMN session_id TEXT`);
69
- }
70
- catch { /* Column already exists */ }
71
- // Migration: Add parent_task_id column if it doesn't exist
72
- try {
73
- db.exec(`ALTER TABLE tasks ADD COLUMN parent_task_id INTEGER REFERENCES tasks(id) ON DELETE SET NULL`);
74
- }
75
- catch { /* Column already exists */ }
76
- // Create index on session_id (after migration ensures column exists)
77
- db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_session_id ON tasks(session_id)`);
207
+ const columns = new Set(database.prepare('PRAGMA table_info(syncs)').all().map(column => column.name));
208
+ for (const [name, definition] of Object.entries({
209
+ snapshot_version: 'INTEGER NOT NULL DEFAULT 1',
210
+ snapshot_at: 'TEXT',
211
+ model_config_json: "TEXT NOT NULL DEFAULT '{}'",
212
+ compression_complete: 'INTEGER NOT NULL DEFAULT 0',
213
+ })) {
214
+ if (!columns.has(name))
215
+ database.exec(`ALTER TABLE syncs ADD COLUMN ${name} ${definition}`);
216
+ }
217
+ const runColumns = new Set(database.prepare('PRAGMA table_info(sync_runs)').all().map(column => column.name));
218
+ if (!runColumns.has('metrics_json'))
219
+ database.exec("ALTER TABLE sync_runs ADD COLUMN metrics_json TEXT NOT NULL DEFAULT '[]'");
220
+ if (!runColumns.has('request_id'))
221
+ database.exec('ALTER TABLE sync_runs ADD COLUMN request_id TEXT');
222
+ database.exec('CREATE UNIQUE INDEX IF NOT EXISTS sync_run_request ON sync_runs(request_id) WHERE request_id IS NOT NULL');
223
+ database.prepare('UPDATE syncs SET snapshot_at = created_at WHERE snapshot_at IS NULL').run();
224
+ (0, pointer_migration_1.migratePointers)(database);
225
+ (0, snapshot_pointers_1.migrateSnapshotPointers)(database);
226
+ (0, agent_migration_1.migrateAgents)(database);
227
+ const sessionColumns = new Set(database.prepare('PRAGMA table_info(agent_sessions)').all().map(column => column.name));
228
+ if (!sessionColumns.has('scanned_bytes'))
229
+ database.exec('ALTER TABLE agent_sessions ADD COLUMN scanned_bytes INTEGER NOT NULL DEFAULT -1');
230
+ })();
78
231
  }
79
232
  function closeDb() {
80
- if (db) {
81
- db.close();
82
- db = null;
83
- }
233
+ db?.close();
234
+ db = null;
84
235
  }
85
236
  //# sourceMappingURL=schema.js.map