vellum 0.2.13 → 0.3.2

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 (1019) hide show
  1. package/bin/vellum.js +2 -0
  2. package/package.json +6 -65
  3. package/.dockerignore +0 -27
  4. package/.env.example +0 -22
  5. package/Dockerfile +0 -99
  6. package/Dockerfile.sandbox +0 -5
  7. package/README.md +0 -169
  8. package/bun.lock +0 -1743
  9. package/bunfig.toml +0 -2
  10. package/docs/skills.md +0 -158
  11. package/drizzle/0000_dizzy_maggott.sql +0 -301
  12. package/drizzle/meta/0000_snapshot.json +0 -1999
  13. package/drizzle/meta/_journal.json +0 -13
  14. package/drizzle.config.ts +0 -7
  15. package/eslint.config.mjs +0 -17
  16. package/hook-templates/debug-prompt-logger/hook.json +0 -7
  17. package/hook-templates/debug-prompt-logger/run.sh +0 -68
  18. package/knip.json +0 -9
  19. package/scripts/capture-x-graphql.ts +0 -545
  20. package/scripts/ipc/check-contract-inventory.ts +0 -104
  21. package/scripts/ipc/check-swift-decoder-drift.ts +0 -164
  22. package/scripts/ipc/generate-swift.ts +0 -492
  23. package/scripts/test-filesystem-tools.sh +0 -48
  24. package/scripts/test.sh +0 -127
  25. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -2316
  26. package/src/__tests__/account-registry.test.ts +0 -245
  27. package/src/__tests__/active-skill-tools.test.ts +0 -378
  28. package/src/__tests__/agent-heartbeat-service.test.ts +0 -250
  29. package/src/__tests__/agent-loop-thinking.test.ts +0 -81
  30. package/src/__tests__/agent-loop.test.ts +0 -1135
  31. package/src/__tests__/anthropic-provider.test.ts +0 -778
  32. package/src/__tests__/app-builder-tool-scripts.test.ts +0 -290
  33. package/src/__tests__/app-bundler.test.ts +0 -292
  34. package/src/__tests__/app-executors.test.ts +0 -613
  35. package/src/__tests__/app-open-proxy.test.ts +0 -62
  36. package/src/__tests__/asset-materialize-tool.test.ts +0 -452
  37. package/src/__tests__/asset-search-tool.test.ts +0 -477
  38. package/src/__tests__/assistant-attachment-directive.test.ts +0 -401
  39. package/src/__tests__/assistant-attachments.test.ts +0 -437
  40. package/src/__tests__/assistant-event-hub.test.ts +0 -226
  41. package/src/__tests__/assistant-event.test.ts +0 -123
  42. package/src/__tests__/attachments-store.test.ts +0 -476
  43. package/src/__tests__/attachments.test.ts +0 -134
  44. package/src/__tests__/audit-log-rotation.test.ts +0 -154
  45. package/src/__tests__/browser-fill-credential.test.ts +0 -309
  46. package/src/__tests__/browser-manager.test.ts +0 -203
  47. package/src/__tests__/browser-runtime-check.test.ts +0 -55
  48. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +0 -68
  49. package/src/__tests__/browser-skill-endstate.test.ts +0 -195
  50. package/src/__tests__/bundle-scanner.test.ts +0 -313
  51. package/src/__tests__/call-bridge.test.ts +0 -425
  52. package/src/__tests__/call-constants.test.ts +0 -40
  53. package/src/__tests__/call-orchestrator.test.ts +0 -512
  54. package/src/__tests__/call-recovery.test.ts +0 -518
  55. package/src/__tests__/call-routes-http.test.ts +0 -459
  56. package/src/__tests__/call-state-machine.test.ts +0 -143
  57. package/src/__tests__/call-state.test.ts +0 -174
  58. package/src/__tests__/call-store.test.ts +0 -691
  59. package/src/__tests__/checker.test.ts +0 -3960
  60. package/src/__tests__/clarification-resolver.test.ts +0 -159
  61. package/src/__tests__/classifier.test.ts +0 -67
  62. package/src/__tests__/claude-code-skill-regression.test.ts +0 -127
  63. package/src/__tests__/claude-code-tool-profiles.test.ts +0 -88
  64. package/src/__tests__/cli-discover.test.ts +0 -85
  65. package/src/__tests__/cli.test.ts +0 -81
  66. package/src/__tests__/clipboard.test.ts +0 -80
  67. package/src/__tests__/commit-guarantee.test.ts +0 -335
  68. package/src/__tests__/commit-message-enrichment-service.test.ts +0 -550
  69. package/src/__tests__/compaction.benchmark.test.ts +0 -176
  70. package/src/__tests__/computer-use-session-compaction.test.ts +0 -132
  71. package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -293
  72. package/src/__tests__/computer-use-session-working-dir.test.ts +0 -117
  73. package/src/__tests__/computer-use-skill-baseline.test.ts +0 -74
  74. package/src/__tests__/computer-use-skill-endstate.test.ts +0 -89
  75. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -217
  76. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +0 -107
  77. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +0 -54
  78. package/src/__tests__/computer-use-tools.test.ts +0 -250
  79. package/src/__tests__/config-schema.test.ts +0 -1343
  80. package/src/__tests__/conflict-store.test.ts +0 -330
  81. package/src/__tests__/connection-policy.test.ts +0 -102
  82. package/src/__tests__/contacts-tools.test.ts +0 -331
  83. package/src/__tests__/context-memory-e2e.test.ts +0 -434
  84. package/src/__tests__/context-token-estimator.test.ts +0 -135
  85. package/src/__tests__/context-window-manager.test.ts +0 -376
  86. package/src/__tests__/contradiction-checker.test.ts +0 -216
  87. package/src/__tests__/conversation-store.test.ts +0 -612
  88. package/src/__tests__/credential-broker-browser-fill.test.ts +0 -517
  89. package/src/__tests__/credential-broker-server-use.test.ts +0 -554
  90. package/src/__tests__/credential-broker.test.ts +0 -167
  91. package/src/__tests__/credential-host-pattern-match.test.ts +0 -104
  92. package/src/__tests__/credential-metadata-store.test.ts +0 -779
  93. package/src/__tests__/credential-policy-validate.test.ts +0 -121
  94. package/src/__tests__/credential-resolve.test.ts +0 -328
  95. package/src/__tests__/credential-security-e2e.test.ts +0 -352
  96. package/src/__tests__/credential-security-invariants.test.ts +0 -567
  97. package/src/__tests__/credential-selection.test.ts +0 -354
  98. package/src/__tests__/credential-vault.test.ts +0 -852
  99. package/src/__tests__/daemon-assistant-events.test.ts +0 -164
  100. package/src/__tests__/daemon-server-session-init.test.ts +0 -522
  101. package/src/__tests__/date-context.test.ts +0 -373
  102. package/src/__tests__/db-schedule-syntax-migration.test.ts +0 -129
  103. package/src/__tests__/delete-managed-skill-tool.test.ts +0 -97
  104. package/src/__tests__/diff.test.ts +0 -121
  105. package/src/__tests__/domain-normalize.test.ts +0 -112
  106. package/src/__tests__/domain-policy.test.ts +0 -124
  107. package/src/__tests__/doordash-client.test.ts +0 -186
  108. package/src/__tests__/doordash-session.test.ts +0 -152
  109. package/src/__tests__/dynamic-page-surface.test.ts +0 -91
  110. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -132
  111. package/src/__tests__/edit-engine.test.ts +0 -180
  112. package/src/__tests__/elevenlabs-client.test.ts +0 -209
  113. package/src/__tests__/email-cli.test.ts +0 -283
  114. package/src/__tests__/encrypted-store.test.ts +0 -332
  115. package/src/__tests__/entity-extractor.test.ts +0 -190
  116. package/src/__tests__/ephemeral-permissions.test.ts +0 -312
  117. package/src/__tests__/evaluate-typescript-tool.test.ts +0 -286
  118. package/src/__tests__/event-bus.test.ts +0 -222
  119. package/src/__tests__/file-edit-tool.test.ts +0 -122
  120. package/src/__tests__/file-ops-service.test.ts +0 -330
  121. package/src/__tests__/file-read-tool.test.ts +0 -75
  122. package/src/__tests__/file-write-tool.test.ts +0 -113
  123. package/src/__tests__/fixtures/credential-security-fixtures.ts +0 -181
  124. package/src/__tests__/fixtures/media-reuse-fixtures.ts +0 -126
  125. package/src/__tests__/fixtures/mock-signup-server.ts +0 -387
  126. package/src/__tests__/fixtures/proxy-fixtures.ts +0 -147
  127. package/src/__tests__/followup-tools.test.ts +0 -303
  128. package/src/__tests__/forbidden-legacy-symbols.test.ts +0 -71
  129. package/src/__tests__/fuzzy-match-property.test.ts +0 -216
  130. package/src/__tests__/fuzzy-match.test.ts +0 -138
  131. package/src/__tests__/gateway-only-enforcement.test.ts +0 -436
  132. package/src/__tests__/gemini-image-service.test.ts +0 -261
  133. package/src/__tests__/gemini-provider.test.ts +0 -651
  134. package/src/__tests__/get-weather.test.ts +0 -318
  135. package/src/__tests__/gmail-integration.test.ts +0 -73
  136. package/src/__tests__/handlers-cu-observation-blob.test.ts +0 -351
  137. package/src/__tests__/handlers-ipc-blob-probe.test.ts +0 -190
  138. package/src/__tests__/handlers-slack-config.test.ts +0 -199
  139. package/src/__tests__/handlers-task-submit-slash.test.ts +0 -38
  140. package/src/__tests__/handlers-twitter-config.test.ts +0 -718
  141. package/src/__tests__/headless-browser-interactions.test.ts +0 -536
  142. package/src/__tests__/headless-browser-navigate.test.ts +0 -211
  143. package/src/__tests__/headless-browser-read-tools.test.ts +0 -261
  144. package/src/__tests__/headless-browser-snapshot.test.ts +0 -185
  145. package/src/__tests__/history-repair-observability.test.ts +0 -56
  146. package/src/__tests__/history-repair.test.ts +0 -510
  147. package/src/__tests__/home-base-bootstrap.test.ts +0 -82
  148. package/src/__tests__/hooks-blocking.test.ts +0 -128
  149. package/src/__tests__/hooks-cli.test.ts +0 -144
  150. package/src/__tests__/hooks-config.test.ts +0 -93
  151. package/src/__tests__/hooks-discovery.test.ts +0 -199
  152. package/src/__tests__/hooks-integration.test.ts +0 -189
  153. package/src/__tests__/hooks-manager.test.ts +0 -187
  154. package/src/__tests__/hooks-runner.test.ts +0 -178
  155. package/src/__tests__/hooks-settings.test.ts +0 -154
  156. package/src/__tests__/hooks-templates.test.ts +0 -137
  157. package/src/__tests__/hooks-ts-runner.test.ts +0 -125
  158. package/src/__tests__/hooks-watch.test.ts +0 -100
  159. package/src/__tests__/host-file-edit-tool.test.ts +0 -104
  160. package/src/__tests__/host-file-read-tool.test.ts +0 -61
  161. package/src/__tests__/host-file-write-tool.test.ts +0 -77
  162. package/src/__tests__/host-shell-tool.test.ts +0 -311
  163. package/src/__tests__/ingress-url-consistency.test.ts +0 -214
  164. package/src/__tests__/intent-routing.test.ts +0 -259
  165. package/src/__tests__/ipc-blob-store.test.ts +0 -315
  166. package/src/__tests__/ipc-contract-inventory.test.ts +0 -54
  167. package/src/__tests__/ipc-contract.test.ts +0 -74
  168. package/src/__tests__/ipc-protocol.test.ts +0 -113
  169. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +0 -237
  170. package/src/__tests__/ipc-snapshot.test.ts +0 -1698
  171. package/src/__tests__/ipc-validate.test.ts +0 -357
  172. package/src/__tests__/key-migration.test.ts +0 -183
  173. package/src/__tests__/keychain.test.ts +0 -258
  174. package/src/__tests__/llm-usage-store.test.ts +0 -221
  175. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -257
  176. package/src/__tests__/managed-store.test.ts +0 -608
  177. package/src/__tests__/media-generate-image.test.ts +0 -238
  178. package/src/__tests__/media-reuse-story.e2e.test.ts +0 -676
  179. package/src/__tests__/media-visibility-policy.test.ts +0 -141
  180. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -235
  181. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -481
  182. package/src/__tests__/memory-query-builder.test.ts +0 -59
  183. package/src/__tests__/memory-recall-quality.test.ts +0 -846
  184. package/src/__tests__/memory-regressions.experimental.test.ts +0 -538
  185. package/src/__tests__/memory-regressions.test.ts +0 -4336
  186. package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
  187. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -430
  188. package/src/__tests__/migration-cli-flows.test.ts +0 -169
  189. package/src/__tests__/migration-ordering.test.ts +0 -249
  190. package/src/__tests__/mock-signup-server.test.ts +0 -528
  191. package/src/__tests__/oauth-callback-registry.test.ts +0 -85
  192. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -285
  193. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -176
  194. package/src/__tests__/onboarding-template-contract.test.ts +0 -58
  195. package/src/__tests__/openai-provider.test.ts +0 -753
  196. package/src/__tests__/parallel-tool.benchmark.test.ts +0 -294
  197. package/src/__tests__/parser.test.ts +0 -472
  198. package/src/__tests__/path-classifier.test.ts +0 -73
  199. package/src/__tests__/path-policy.test.ts +0 -435
  200. package/src/__tests__/platform-move-helper.test.ts +0 -99
  201. package/src/__tests__/platform-socket-path.test.ts +0 -52
  202. package/src/__tests__/platform-workspace-migration.test.ts +0 -1000
  203. package/src/__tests__/platform.test.ts +0 -131
  204. package/src/__tests__/playbook-tools.test.ts +0 -342
  205. package/src/__tests__/prebuilt-home-base-seed.test.ts +0 -75
  206. package/src/__tests__/pricing.test.ts +0 -256
  207. package/src/__tests__/profile-compiler.test.ts +0 -374
  208. package/src/__tests__/provider-commit-message-generator.test.ts +0 -342
  209. package/src/__tests__/provider-registry-ollama.test.ts +0 -16
  210. package/src/__tests__/provider-streaming.benchmark.test.ts +0 -773
  211. package/src/__tests__/proxy-approval-callback.test.ts +0 -601
  212. package/src/__tests__/public-ingress-urls.test.ts +0 -222
  213. package/src/__tests__/ratelimit.test.ts +0 -297
  214. package/src/__tests__/recurrence-engine-rruleset.test.ts +0 -78
  215. package/src/__tests__/recurrence-engine.test.ts +0 -69
  216. package/src/__tests__/recurrence-types.test.ts +0 -71
  217. package/src/__tests__/registry.test.ts +0 -494
  218. package/src/__tests__/relay-server.test.ts +0 -688
  219. package/src/__tests__/reminder-store.test.ts +0 -223
  220. package/src/__tests__/reminder.test.ts +0 -229
  221. package/src/__tests__/request-file-tool.test.ts +0 -158
  222. package/src/__tests__/run-orchestrator-assistant-events.test.ts +0 -222
  223. package/src/__tests__/run-orchestrator.test.ts +0 -200
  224. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -189
  225. package/src/__tests__/runtime-events-sse-parity.test.ts +0 -343
  226. package/src/__tests__/runtime-events-sse.test.ts +0 -162
  227. package/src/__tests__/runtime-runs-http.test.ts +0 -433
  228. package/src/__tests__/runtime-runs.test.ts +0 -273
  229. package/src/__tests__/sandbox-diagnostics.test.ts +0 -408
  230. package/src/__tests__/sandbox-host-parity.test.ts +0 -950
  231. package/src/__tests__/scaffold-managed-skill-tool.test.ts +0 -253
  232. package/src/__tests__/schedule-store.test.ts +0 -482
  233. package/src/__tests__/schedule-tools.test.ts +0 -700
  234. package/src/__tests__/scheduler-recurrence.test.ts +0 -329
  235. package/src/__tests__/script-proxy-certs.test.ts +0 -90
  236. package/src/__tests__/script-proxy-connect-tunnel.test.ts +0 -177
  237. package/src/__tests__/script-proxy-decision-trace.test.ts +0 -156
  238. package/src/__tests__/script-proxy-http-forwarder.test.ts +0 -281
  239. package/src/__tests__/script-proxy-injection-runtime.test.ts +0 -401
  240. package/src/__tests__/script-proxy-mitm-handler.test.ts +0 -407
  241. package/src/__tests__/script-proxy-policy-runtime.test.ts +0 -287
  242. package/src/__tests__/script-proxy-policy.test.ts +0 -310
  243. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +0 -135
  244. package/src/__tests__/script-proxy-router.test.ts +0 -180
  245. package/src/__tests__/script-proxy-session-manager.test.ts +0 -382
  246. package/src/__tests__/script-proxy-session-runtime.test.ts +0 -113
  247. package/src/__tests__/secret-allowlist.test.ts +0 -229
  248. package/src/__tests__/secret-ingress-handler.test.ts +0 -99
  249. package/src/__tests__/secret-onetime-send.test.ts +0 -130
  250. package/src/__tests__/secret-prompt-log-hygiene.test.ts +0 -106
  251. package/src/__tests__/secret-response-routing.test.ts +0 -93
  252. package/src/__tests__/secret-scanner-executor.test.ts +0 -348
  253. package/src/__tests__/secret-scanner.test.ts +0 -857
  254. package/src/__tests__/secure-keys.test.ts +0 -323
  255. package/src/__tests__/server-history-render.test.ts +0 -431
  256. package/src/__tests__/session-abort-tool-results.test.ts +0 -240
  257. package/src/__tests__/session-conflict-gate.test.ts +0 -700
  258. package/src/__tests__/session-error.test.ts +0 -369
  259. package/src/__tests__/session-evictor.test.ts +0 -188
  260. package/src/__tests__/session-init.benchmark.test.ts +0 -462
  261. package/src/__tests__/session-load-history-repair.test.ts +0 -222
  262. package/src/__tests__/session-pre-run-repair.test.ts +0 -213
  263. package/src/__tests__/session-profile-injection.test.ts +0 -444
  264. package/src/__tests__/session-provider-retry-repair.test.ts +0 -306
  265. package/src/__tests__/session-queue.test.ts +0 -1535
  266. package/src/__tests__/session-runtime-assembly.test.ts +0 -476
  267. package/src/__tests__/session-runtime-workspace.test.ts +0 -183
  268. package/src/__tests__/session-skill-tools.test.ts +0 -2431
  269. package/src/__tests__/session-slash-known.test.ts +0 -368
  270. package/src/__tests__/session-slash-queue.test.ts +0 -288
  271. package/src/__tests__/session-slash-unknown.test.ts +0 -271
  272. package/src/__tests__/session-surfaces-task-progress.test.ts +0 -104
  273. package/src/__tests__/session-tool-setup-app-refresh.test.ts +0 -473
  274. package/src/__tests__/session-tool-setup-memory-scope.test.ts +0 -140
  275. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +0 -140
  276. package/src/__tests__/session-undo.test.ts +0 -75
  277. package/src/__tests__/session-workspace-cache-state.test.ts +0 -246
  278. package/src/__tests__/session-workspace-injection.test.ts +0 -327
  279. package/src/__tests__/session-workspace-tool-tracking.test.ts +0 -240
  280. package/src/__tests__/shared-filesystem-errors.test.ts +0 -78
  281. package/src/__tests__/shell-credential-ref.test.ts +0 -187
  282. package/src/__tests__/shell-parser-fuzz.test.ts +0 -544
  283. package/src/__tests__/shell-parser-property.test.ts +0 -433
  284. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -272
  285. package/src/__tests__/signup-e2e.test.ts +0 -353
  286. package/src/__tests__/size-guard.test.ts +0 -117
  287. package/src/__tests__/skill-include-graph.test.ts +0 -303
  288. package/src/__tests__/skill-load-tool.test.ts +0 -409
  289. package/src/__tests__/skill-projection.benchmark.test.ts +0 -328
  290. package/src/__tests__/skill-script-runner-host.test.ts +0 -489
  291. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -349
  292. package/src/__tests__/skill-script-runner.test.ts +0 -159
  293. package/src/__tests__/skill-tool-factory.test.ts +0 -252
  294. package/src/__tests__/skill-tool-manifest.test.ts +0 -658
  295. package/src/__tests__/skill-version-hash.test.ts +0 -182
  296. package/src/__tests__/skills.test.ts +0 -680
  297. package/src/__tests__/slash-commands-catalog.test.ts +0 -86
  298. package/src/__tests__/slash-commands-parser.test.ts +0 -119
  299. package/src/__tests__/slash-commands-resolver.test.ts +0 -193
  300. package/src/__tests__/slash-commands-rewrite.test.ts +0 -39
  301. package/src/__tests__/speaker-identification.test.ts +0 -52
  302. package/src/__tests__/starter-bundle.test.ts +0 -136
  303. package/src/__tests__/starter-task-flow.test.ts +0 -143
  304. package/src/__tests__/subagent-manager-notify.test.ts +0 -404
  305. package/src/__tests__/subagent-tools.test.ts +0 -218
  306. package/src/__tests__/subagent-types.test.ts +0 -78
  307. package/src/__tests__/swarm-orchestrator.test.ts +0 -428
  308. package/src/__tests__/swarm-plan-validator.test.ts +0 -330
  309. package/src/__tests__/swarm-recursion.test.ts +0 -165
  310. package/src/__tests__/swarm-router-planner.test.ts +0 -208
  311. package/src/__tests__/swarm-session-integration.test.ts +0 -274
  312. package/src/__tests__/swarm-tool.test.ts +0 -145
  313. package/src/__tests__/swarm-worker-backend.test.ts +0 -129
  314. package/src/__tests__/swarm-worker-runner.test.ts +0 -272
  315. package/src/__tests__/system-prompt.test.ts +0 -439
  316. package/src/__tests__/task-compiler.test.ts +0 -284
  317. package/src/__tests__/task-runner.test.ts +0 -216
  318. package/src/__tests__/task-scheduler.test.ts +0 -217
  319. package/src/__tests__/task-tools.test.ts +0 -595
  320. package/src/__tests__/terminal-sandbox-docker.test.ts +0 -1064
  321. package/src/__tests__/terminal-sandbox.integration.test.ts +0 -178
  322. package/src/__tests__/terminal-sandbox.test.ts +0 -202
  323. package/src/__tests__/test-support/browser-skill-harness.ts +0 -90
  324. package/src/__tests__/test-support/computer-use-skill-harness.ts +0 -45
  325. package/src/__tests__/tool-audit-listener.test.ts +0 -113
  326. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -253
  327. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -500
  328. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -516
  329. package/src/__tests__/tool-executor-redaction.test.ts +0 -289
  330. package/src/__tests__/tool-executor.test.ts +0 -2055
  331. package/src/__tests__/tool-metrics-listener.test.ts +0 -225
  332. package/src/__tests__/tool-notification-listener.test.ts +0 -49
  333. package/src/__tests__/tool-policy.test.ts +0 -54
  334. package/src/__tests__/tool-profiling-listener.test.ts +0 -268
  335. package/src/__tests__/tool-result-truncation.test.ts +0 -217
  336. package/src/__tests__/tool-trace-listener.test.ts +0 -226
  337. package/src/__tests__/top-level-renderer.test.ts +0 -121
  338. package/src/__tests__/top-level-scanner.test.ts +0 -141
  339. package/src/__tests__/trace-emitter.test.ts +0 -173
  340. package/src/__tests__/trust-store.test.ts +0 -2031
  341. package/src/__tests__/turn-commit.test.ts +0 -554
  342. package/src/__tests__/twilio-provider.test.ts +0 -179
  343. package/src/__tests__/twilio-routes-twiml.test.ts +0 -127
  344. package/src/__tests__/twilio-routes.test.ts +0 -822
  345. package/src/__tests__/twitter-auth-handler.test.ts +0 -666
  346. package/src/__tests__/url-safety.test.ts +0 -418
  347. package/src/__tests__/view-image-tool.test.ts +0 -217
  348. package/src/__tests__/weather-skill-regression.test.ts +0 -225
  349. package/src/__tests__/web-fetch.test.ts +0 -869
  350. package/src/__tests__/web-search.test.ts +0 -584
  351. package/src/__tests__/workspace-git-service.test.ts +0 -1153
  352. package/src/__tests__/workspace-heartbeat-service.test.ts +0 -486
  353. package/src/__tests__/workspace-lifecycle.test.ts +0 -292
  354. package/src/agent/attachments.ts +0 -35
  355. package/src/agent/loop.ts +0 -500
  356. package/src/agent/message-types.ts +0 -17
  357. package/src/agent-heartbeat/agent-heartbeat-service.ts +0 -155
  358. package/src/autonomy/autonomy-resolver.ts +0 -60
  359. package/src/autonomy/autonomy-store.ts +0 -122
  360. package/src/autonomy/disposition-mapper.ts +0 -31
  361. package/src/autonomy/index.ts +0 -11
  362. package/src/autonomy/types.ts +0 -39
  363. package/src/bundler/app-bundler.ts +0 -295
  364. package/src/bundler/bundle-scanner.ts +0 -535
  365. package/src/bundler/bundle-signer.ts +0 -124
  366. package/src/bundler/manifest.ts +0 -21
  367. package/src/bundler/signature-verifier.ts +0 -184
  368. package/src/calls/call-bridge.ts +0 -95
  369. package/src/calls/call-constants.ts +0 -48
  370. package/src/calls/call-domain.ts +0 -278
  371. package/src/calls/call-orchestrator.ts +0 -412
  372. package/src/calls/call-recovery.ts +0 -207
  373. package/src/calls/call-state-machine.ts +0 -68
  374. package/src/calls/call-state.ts +0 -87
  375. package/src/calls/call-store.ts +0 -416
  376. package/src/calls/elevenlabs-client.ts +0 -89
  377. package/src/calls/elevenlabs-config.ts +0 -29
  378. package/src/calls/relay-server.ts +0 -390
  379. package/src/calls/speaker-identification.ts +0 -213
  380. package/src/calls/twilio-config.ts +0 -45
  381. package/src/calls/twilio-provider.ts +0 -178
  382. package/src/calls/twilio-routes.ts +0 -316
  383. package/src/calls/types.ts +0 -37
  384. package/src/calls/voice-provider.ts +0 -14
  385. package/src/calls/voice-quality.ts +0 -92
  386. package/src/cli/autonomy.ts +0 -188
  387. package/src/cli/config-commands.ts +0 -334
  388. package/src/cli/contacts.ts +0 -149
  389. package/src/cli/core-commands.ts +0 -784
  390. package/src/cli/doordash.ts +0 -1055
  391. package/src/cli/email-guardrails.ts +0 -200
  392. package/src/cli/email.ts +0 -405
  393. package/src/cli/ipc-client.ts +0 -82
  394. package/src/cli/main-screen.tsx +0 -53
  395. package/src/cli/map.ts +0 -270
  396. package/src/cli/twitter.ts +0 -575
  397. package/src/cli.ts +0 -937
  398. package/src/commands/__tests__/cc-command-registry.test.ts +0 -319
  399. package/src/commands/cc-command-registry.ts +0 -209
  400. package/src/config/bundled-skills/.gitkeep +0 -0
  401. package/src/config/bundled-skills/agentmail/SKILL.md +0 -128
  402. package/src/config/bundled-skills/agentmail/icon.svg +0 -21
  403. package/src/config/bundled-skills/app-builder/SKILL.md +0 -1404
  404. package/src/config/bundled-skills/app-builder/TOOLS.json +0 -279
  405. package/src/config/bundled-skills/app-builder/icon.svg +0 -9
  406. package/src/config/bundled-skills/app-builder/tools/app-create.ts +0 -15
  407. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +0 -10
  408. package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +0 -11
  409. package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +0 -10
  410. package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +0 -18
  411. package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +0 -11
  412. package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -10
  413. package/src/config/bundled-skills/app-builder/tools/app-query.ts +0 -10
  414. package/src/config/bundled-skills/app-builder/tools/app-update.ts +0 -20
  415. package/src/config/bundled-skills/browser/SKILL.md +0 -28
  416. package/src/config/bundled-skills/browser/TOOLS.json +0 -234
  417. package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -9
  418. package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -9
  419. package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -9
  420. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -9
  421. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -9
  422. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -9
  423. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -9
  424. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -9
  425. package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -9
  426. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -9
  427. package/src/config/bundled-skills/claude-code/SKILL.md +0 -50
  428. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -40
  429. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -9
  430. package/src/config/bundled-skills/computer-use/SKILL.md +0 -17
  431. package/src/config/bundled-skills/computer-use/TOOLS.json +0 -326
  432. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +0 -9
  433. package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +0 -9
  434. package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +0 -9
  435. package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +0 -9
  436. package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +0 -9
  437. package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +0 -9
  438. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -9
  439. package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +0 -9
  440. package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +0 -9
  441. package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +0 -9
  442. package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +0 -9
  443. package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +0 -9
  444. package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +0 -9
  445. package/src/config/bundled-skills/contacts/SKILL.md +0 -39
  446. package/src/config/bundled-skills/contacts/TOOLS.json +0 -122
  447. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +0 -9
  448. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -9
  449. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -9
  450. package/src/config/bundled-skills/document/SKILL.md +0 -26
  451. package/src/config/bundled-skills/document/TOOLS.json +0 -53
  452. package/src/config/bundled-skills/document/tools/document-create.ts +0 -9
  453. package/src/config/bundled-skills/document/tools/document-update.ts +0 -9
  454. package/src/config/bundled-skills/doordash/SKILL.md +0 -163
  455. package/src/config/bundled-skills/followups/SKILL.md +0 -32
  456. package/src/config/bundled-skills/followups/TOOLS.json +0 -100
  457. package/src/config/bundled-skills/followups/icon.svg +0 -24
  458. package/src/config/bundled-skills/followups/tools/followup-create.ts +0 -9
  459. package/src/config/bundled-skills/followups/tools/followup-list.ts +0 -9
  460. package/src/config/bundled-skills/followups/tools/followup-resolve.ts +0 -9
  461. package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
  462. package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -108
  463. package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -165
  464. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -21
  465. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -42
  466. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -13
  467. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -30
  468. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -41
  469. package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -18
  470. package/src/config/bundled-skills/google-calendar/types.ts +0 -97
  471. package/src/config/bundled-skills/image-studio/SKILL.md +0 -32
  472. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -42
  473. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +0 -115
  474. package/src/config/bundled-skills/macos-automation/SKILL.md +0 -66
  475. package/src/config/bundled-skills/messaging/SKILL.md +0 -130
  476. package/src/config/bundled-skills/messaging/TOOLS.json +0 -357
  477. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +0 -23
  478. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +0 -23
  479. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +0 -25
  480. package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +0 -26
  481. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +0 -25
  482. package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +0 -23
  483. package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +0 -84
  484. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +0 -18
  485. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +0 -125
  486. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +0 -16
  487. package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +0 -49
  488. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +0 -21
  489. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +0 -25
  490. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +0 -28
  491. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +0 -29
  492. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +0 -22
  493. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -27
  494. package/src/config/bundled-skills/messaging/tools/shared.ts +0 -71
  495. package/src/config/bundled-skills/messaging/tools/slack-add-reaction.ts +0 -25
  496. package/src/config/bundled-skills/messaging/tools/slack-leave-channel.ts +0 -23
  497. package/src/config/bundled-skills/phone-calls/SKILL.md +0 -414
  498. package/src/config/bundled-skills/playbooks/SKILL.md +0 -31
  499. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -126
  500. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +0 -9
  501. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +0 -9
  502. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +0 -9
  503. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +0 -9
  504. package/src/config/bundled-skills/public-ingress/SKILL.md +0 -183
  505. package/src/config/bundled-skills/reminder/SKILL.md +0 -20
  506. package/src/config/bundled-skills/reminder/TOOLS.json +0 -67
  507. package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +0 -9
  508. package/src/config/bundled-skills/reminder/tools/reminder-create.ts +0 -9
  509. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +0 -9
  510. package/src/config/bundled-skills/schedule/SKILL.md +0 -74
  511. package/src/config/bundled-skills/schedule/TOOLS.json +0 -135
  512. package/src/config/bundled-skills/schedule/tools/schedule-create.ts +0 -9
  513. package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +0 -9
  514. package/src/config/bundled-skills/schedule/tools/schedule-list.ts +0 -9
  515. package/src/config/bundled-skills/schedule/tools/schedule-update.ts +0 -9
  516. package/src/config/bundled-skills/self-upgrade/SKILL.md +0 -68
  517. package/src/config/bundled-skills/start-the-day/SKILL.md +0 -70
  518. package/src/config/bundled-skills/start-the-day/icon.svg +0 -13
  519. package/src/config/bundled-skills/subagent/SKILL.md +0 -25
  520. package/src/config/bundled-skills/subagent/TOOLS.json +0 -107
  521. package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +0 -9
  522. package/src/config/bundled-skills/subagent/tools/subagent-message.ts +0 -9
  523. package/src/config/bundled-skills/subagent/tools/subagent-read.ts +0 -9
  524. package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +0 -9
  525. package/src/config/bundled-skills/subagent/tools/subagent-status.ts +0 -9
  526. package/src/config/bundled-skills/tasks/SKILL.md +0 -28
  527. package/src/config/bundled-skills/tasks/TOOLS.json +0 -281
  528. package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -9
  529. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -9
  530. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -9
  531. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -9
  532. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -9
  533. package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -9
  534. package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -9
  535. package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -9
  536. package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -9
  537. package/src/config/bundled-skills/transcribe/SKILL.md +0 -25
  538. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -32
  539. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +0 -370
  540. package/src/config/bundled-skills/twitter/SKILL.md +0 -134
  541. package/src/config/bundled-skills/watcher/SKILL.md +0 -27
  542. package/src/config/bundled-skills/watcher/TOOLS.json +0 -147
  543. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -9
  544. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -9
  545. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -9
  546. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -9
  547. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -9
  548. package/src/config/bundled-skills/weather/SKILL.md +0 -37
  549. package/src/config/bundled-skills/weather/TOOLS.json +0 -32
  550. package/src/config/bundled-skills/weather/icon.svg +0 -24
  551. package/src/config/bundled-skills/weather/tools/get-weather.ts +0 -9
  552. package/src/config/computer-use-prompt.ts +0 -97
  553. package/src/config/defaults.ts +0 -252
  554. package/src/config/loader.ts +0 -339
  555. package/src/config/schema.ts +0 -1356
  556. package/src/config/skill-state.ts +0 -95
  557. package/src/config/skills.ts +0 -972
  558. package/src/config/system-prompt.ts +0 -675
  559. package/src/config/templates/BOOTSTRAP.md +0 -70
  560. package/src/config/templates/IDENTITY.md +0 -25
  561. package/src/config/templates/LOOKS.md +0 -25
  562. package/src/config/templates/SOUL.md +0 -37
  563. package/src/config/templates/USER.md +0 -19
  564. package/src/config/types.ts +0 -40
  565. package/src/config/vellum-skills/deploy-fullstack-vercel/SKILL.md +0 -179
  566. package/src/config/vellum-skills/document-writer/SKILL.md +0 -195
  567. package/src/config/vellum-skills/google-oauth-setup/SKILL.md +0 -199
  568. package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +0 -153
  569. package/src/config/vellum-skills/telegram-setup/SKILL.md +0 -102
  570. package/src/contacts/contact-store.ts +0 -410
  571. package/src/contacts/index.ts +0 -11
  572. package/src/contacts/types.ts +0 -28
  573. package/src/context/token-estimator.ts +0 -108
  574. package/src/context/tool-result-truncation.ts +0 -128
  575. package/src/context/window-manager.ts +0 -531
  576. package/src/daemon/assistant-attachments.ts +0 -689
  577. package/src/daemon/classifier.ts +0 -110
  578. package/src/daemon/computer-use-session.ts +0 -903
  579. package/src/daemon/connection-policy.ts +0 -41
  580. package/src/daemon/date-context.ts +0 -136
  581. package/src/daemon/handlers/apps.ts +0 -461
  582. package/src/daemon/handlers/browser.ts +0 -54
  583. package/src/daemon/handlers/computer-use.ts +0 -187
  584. package/src/daemon/handlers/config.ts +0 -707
  585. package/src/daemon/handlers/diagnostics.ts +0 -338
  586. package/src/daemon/handlers/documents.ts +0 -173
  587. package/src/daemon/handlers/home-base.ts +0 -78
  588. package/src/daemon/handlers/identity.ts +0 -127
  589. package/src/daemon/handlers/index.ts +0 -128
  590. package/src/daemon/handlers/misc.ts +0 -331
  591. package/src/daemon/handlers/open-bundle-handler.ts +0 -80
  592. package/src/daemon/handlers/publish.ts +0 -187
  593. package/src/daemon/handlers/sessions.ts +0 -539
  594. package/src/daemon/handlers/shared.ts +0 -569
  595. package/src/daemon/handlers/signing.ts +0 -37
  596. package/src/daemon/handlers/skills.ts +0 -501
  597. package/src/daemon/handlers/subagents.ts +0 -210
  598. package/src/daemon/handlers/twitter-auth.ts +0 -198
  599. package/src/daemon/handlers/work-items.ts +0 -632
  600. package/src/daemon/handlers/workspace-files.ts +0 -75
  601. package/src/daemon/handlers.ts +0 -17
  602. package/src/daemon/history-repair.ts +0 -214
  603. package/src/daemon/ipc-blob-store.ts +0 -231
  604. package/src/daemon/ipc-contract-inventory.json +0 -463
  605. package/src/daemon/ipc-contract-inventory.ts +0 -126
  606. package/src/daemon/ipc-contract.ts +0 -2352
  607. package/src/daemon/ipc-protocol.ts +0 -75
  608. package/src/daemon/ipc-validate.ts +0 -171
  609. package/src/daemon/lifecycle.ts +0 -580
  610. package/src/daemon/main.ts +0 -21
  611. package/src/daemon/media-visibility-policy.ts +0 -57
  612. package/src/daemon/ride-shotgun-handler.ts +0 -309
  613. package/src/daemon/server.ts +0 -1207
  614. package/src/daemon/session-agent-loop.ts +0 -922
  615. package/src/daemon/session-attachments.ts +0 -196
  616. package/src/daemon/session-conflict-gate.ts +0 -128
  617. package/src/daemon/session-dynamic-profile.ts +0 -63
  618. package/src/daemon/session-error.ts +0 -290
  619. package/src/daemon/session-evictor.ts +0 -196
  620. package/src/daemon/session-history.ts +0 -437
  621. package/src/daemon/session-lifecycle.ts +0 -147
  622. package/src/daemon/session-media-retry.ts +0 -147
  623. package/src/daemon/session-memory.ts +0 -212
  624. package/src/daemon/session-messaging.ts +0 -145
  625. package/src/daemon/session-notifiers.ts +0 -193
  626. package/src/daemon/session-process.ts +0 -264
  627. package/src/daemon/session-queue-manager.ts +0 -82
  628. package/src/daemon/session-runtime-assembly.ts +0 -447
  629. package/src/daemon/session-skill-tools.ts +0 -356
  630. package/src/daemon/session-slash.ts +0 -305
  631. package/src/daemon/session-surfaces.ts +0 -702
  632. package/src/daemon/session-tool-setup.ts +0 -524
  633. package/src/daemon/session-usage.ts +0 -72
  634. package/src/daemon/session-workspace.ts +0 -19
  635. package/src/daemon/session.ts +0 -400
  636. package/src/daemon/trace-emitter.ts +0 -82
  637. package/src/daemon/video-thumbnail.ts +0 -60
  638. package/src/daemon/watch-handler.ts +0 -274
  639. package/src/doordash/client.ts +0 -999
  640. package/src/doordash/queries.ts +0 -1311
  641. package/src/doordash/query-extractor.ts +0 -93
  642. package/src/doordash/session.ts +0 -82
  643. package/src/email/provider.ts +0 -117
  644. package/src/email/providers/agentmail.ts +0 -317
  645. package/src/email/providers/index.ts +0 -58
  646. package/src/email/service.ts +0 -303
  647. package/src/email/types.ts +0 -126
  648. package/src/events/bus.ts +0 -157
  649. package/src/events/domain-events.ts +0 -83
  650. package/src/events/index.ts +0 -18
  651. package/src/events/tool-audit-listener.ts +0 -80
  652. package/src/events/tool-domain-event-publisher.ts +0 -111
  653. package/src/events/tool-metrics-listener.ts +0 -159
  654. package/src/events/tool-notification-listener.ts +0 -17
  655. package/src/events/tool-profiling-listener.ts +0 -158
  656. package/src/events/tool-trace-listener.ts +0 -75
  657. package/src/export/formatter.ts +0 -98
  658. package/src/followups/followup-store.ts +0 -168
  659. package/src/followups/index.ts +0 -10
  660. package/src/followups/types.ts +0 -29
  661. package/src/gallery/default-gallery.ts +0 -795
  662. package/src/gallery/gallery-manifest.ts +0 -24
  663. package/src/home-base/app-link-store.ts +0 -82
  664. package/src/home-base/bootstrap.ts +0 -68
  665. package/src/home-base/prebuilt/index.html +0 -662
  666. package/src/home-base/prebuilt/seed-metadata.json +0 -21
  667. package/src/home-base/prebuilt/seed.ts +0 -112
  668. package/src/home-base/prebuilt-home-base-updater.ts +0 -30
  669. package/src/hooks/cli.ts +0 -163
  670. package/src/hooks/config.ts +0 -88
  671. package/src/hooks/discovery.ts +0 -110
  672. package/src/hooks/manager.ts +0 -128
  673. package/src/hooks/runner.ts +0 -123
  674. package/src/hooks/templates.ts +0 -52
  675. package/src/hooks/types.ts +0 -72
  676. package/src/inbound/public-ingress-urls.ts +0 -123
  677. package/src/index.ts +0 -75
  678. package/src/instrument.ts +0 -60
  679. package/src/logfire.ts +0 -99
  680. package/src/media/gemini-image-service.ts +0 -136
  681. package/src/memory/account-store.ts +0 -108
  682. package/src/memory/admin.ts +0 -211
  683. package/src/memory/app-store.ts +0 -556
  684. package/src/memory/attachments-store.ts +0 -397
  685. package/src/memory/channel-delivery-store.ts +0 -353
  686. package/src/memory/checkpoints.ts +0 -52
  687. package/src/memory/clarification-resolver.ts +0 -298
  688. package/src/memory/conflict-intent.ts +0 -114
  689. package/src/memory/conflict-store.ts +0 -342
  690. package/src/memory/contradiction-checker.ts +0 -330
  691. package/src/memory/conversation-key-store.ts +0 -107
  692. package/src/memory/conversation-store.ts +0 -470
  693. package/src/memory/db.ts +0 -1825
  694. package/src/memory/embedding-backend.ts +0 -229
  695. package/src/memory/embedding-gemini.ts +0 -52
  696. package/src/memory/embedding-local.ts +0 -75
  697. package/src/memory/embedding-ollama.ts +0 -55
  698. package/src/memory/embedding-openai.ts +0 -25
  699. package/src/memory/entity-extractor.ts +0 -474
  700. package/src/memory/fingerprint.ts +0 -20
  701. package/src/memory/indexer.ts +0 -156
  702. package/src/memory/items-extractor.ts +0 -461
  703. package/src/memory/job-handlers/backfill.ts +0 -139
  704. package/src/memory/job-handlers/cleanup.ts +0 -58
  705. package/src/memory/job-handlers/conflict.ts +0 -121
  706. package/src/memory/job-handlers/embedding.ts +0 -61
  707. package/src/memory/job-handlers/extraction.ts +0 -123
  708. package/src/memory/job-handlers/index-maintenance.ts +0 -54
  709. package/src/memory/job-handlers/summarization.ts +0 -286
  710. package/src/memory/job-utils.ts +0 -170
  711. package/src/memory/jobs-store.ts +0 -401
  712. package/src/memory/jobs-worker.ts +0 -274
  713. package/src/memory/llm-request-log-store.ts +0 -45
  714. package/src/memory/llm-usage-store.ts +0 -60
  715. package/src/memory/message-content.ts +0 -54
  716. package/src/memory/profile-compiler.ts +0 -160
  717. package/src/memory/published-pages-store.ts +0 -137
  718. package/src/memory/qdrant-client.ts +0 -366
  719. package/src/memory/qdrant-manager.ts +0 -242
  720. package/src/memory/query-builder.ts +0 -45
  721. package/src/memory/retrieval-budget.ts +0 -30
  722. package/src/memory/retriever.ts +0 -653
  723. package/src/memory/runs-store.ts +0 -255
  724. package/src/memory/schema.ts +0 -588
  725. package/src/memory/search/entity.ts +0 -298
  726. package/src/memory/search/formatting.ts +0 -207
  727. package/src/memory/search/lexical.ts +0 -227
  728. package/src/memory/search/ranking.ts +0 -401
  729. package/src/memory/search/semantic.ts +0 -121
  730. package/src/memory/search/types.ts +0 -137
  731. package/src/memory/segmenter.ts +0 -68
  732. package/src/memory/shared-app-links-store.ts +0 -138
  733. package/src/memory/tool-usage-store.ts +0 -62
  734. package/src/messaging/activity-analyzer.ts +0 -76
  735. package/src/messaging/draft-store.ts +0 -88
  736. package/src/messaging/index.ts +0 -3
  737. package/src/messaging/provider-types.ts +0 -80
  738. package/src/messaging/provider.ts +0 -43
  739. package/src/messaging/providers/gmail/adapter.ts +0 -193
  740. package/src/messaging/providers/gmail/client.ts +0 -204
  741. package/src/messaging/providers/gmail/types.ts +0 -90
  742. package/src/messaging/providers/slack/adapter.ts +0 -202
  743. package/src/messaging/providers/slack/client.ts +0 -198
  744. package/src/messaging/providers/slack/types.ts +0 -119
  745. package/src/messaging/registry.ts +0 -34
  746. package/src/messaging/style-analyzer.ts +0 -159
  747. package/src/messaging/thread-summarizer.ts +0 -306
  748. package/src/messaging/triage-engine.ts +0 -323
  749. package/src/messaging/types.ts +0 -55
  750. package/src/permissions/checker.ts +0 -636
  751. package/src/permissions/defaults.ts +0 -254
  752. package/src/permissions/prompter.ts +0 -102
  753. package/src/permissions/secret-prompter.ts +0 -114
  754. package/src/permissions/trust-store.ts +0 -584
  755. package/src/permissions/types.ts +0 -62
  756. package/src/playbooks/index.ts +0 -2
  757. package/src/playbooks/playbook-compiler.ts +0 -90
  758. package/src/playbooks/types.ts +0 -55
  759. package/src/providers/anthropic/client.ts +0 -751
  760. package/src/providers/failover.ts +0 -129
  761. package/src/providers/fireworks/client.ts +0 -20
  762. package/src/providers/gemini/client.ts +0 -285
  763. package/src/providers/ollama/client.ts +0 -30
  764. package/src/providers/openai/client.ts +0 -337
  765. package/src/providers/openrouter/client.ts +0 -20
  766. package/src/providers/ratelimit.ts +0 -93
  767. package/src/providers/registry.ts +0 -146
  768. package/src/providers/retry.ts +0 -106
  769. package/src/providers/stream-timeout.ts +0 -38
  770. package/src/providers/types.ts +0 -109
  771. package/src/runtime/assistant-event-hub.ts +0 -120
  772. package/src/runtime/assistant-event.ts +0 -82
  773. package/src/runtime/gateway-client.ts +0 -42
  774. package/src/runtime/http-server.ts +0 -1056
  775. package/src/runtime/http-types.ts +0 -66
  776. package/src/runtime/routes/app-routes.ts +0 -174
  777. package/src/runtime/routes/attachment-routes.ts +0 -133
  778. package/src/runtime/routes/call-routes.ts +0 -140
  779. package/src/runtime/routes/channel-routes.ts +0 -382
  780. package/src/runtime/routes/conversation-routes.ts +0 -352
  781. package/src/runtime/routes/events-routes.ts +0 -79
  782. package/src/runtime/routes/run-routes.ts +0 -262
  783. package/src/runtime/routes/secret-routes.ts +0 -76
  784. package/src/runtime/run-orchestrator.ts +0 -296
  785. package/src/schedule/recurrence-engine.ts +0 -138
  786. package/src/schedule/recurrence-types.ts +0 -67
  787. package/src/schedule/schedule-store.ts +0 -497
  788. package/src/schedule/scheduler.ts +0 -171
  789. package/src/security/encrypted-store.ts +0 -238
  790. package/src/security/keychain.ts +0 -252
  791. package/src/security/oauth-callback-registry.ts +0 -66
  792. package/src/security/oauth2.ts +0 -274
  793. package/src/security/redaction.ts +0 -89
  794. package/src/security/secret-allowlist.ts +0 -164
  795. package/src/security/secret-ingress.ts +0 -57
  796. package/src/security/secret-scanner.ts +0 -543
  797. package/src/security/secure-keys.ts +0 -180
  798. package/src/security/token-manager.ts +0 -141
  799. package/src/services/published-app-updater.ts +0 -69
  800. package/src/services/vercel-deploy.ts +0 -73
  801. package/src/skills/active-skill-tools.ts +0 -81
  802. package/src/skills/clawhub.ts +0 -414
  803. package/src/skills/include-graph.ts +0 -146
  804. package/src/skills/managed-store.ts +0 -233
  805. package/src/skills/path-classifier.ts +0 -128
  806. package/src/skills/slash-commands.ts +0 -174
  807. package/src/skills/tool-manifest.ts +0 -165
  808. package/src/skills/version-hash.ts +0 -110
  809. package/src/slack/slack-webhook.ts +0 -61
  810. package/src/subagent/index.ts +0 -19
  811. package/src/subagent/manager.ts +0 -511
  812. package/src/subagent/types.ts +0 -69
  813. package/src/swarm/backend-claude-code.ts +0 -145
  814. package/src/swarm/index.ts +0 -44
  815. package/src/swarm/limits.ts +0 -37
  816. package/src/swarm/orchestrator.ts +0 -279
  817. package/src/swarm/plan-validator.ts +0 -151
  818. package/src/swarm/router-planner.ts +0 -100
  819. package/src/swarm/router-prompts.ts +0 -36
  820. package/src/swarm/synthesizer.ts +0 -62
  821. package/src/swarm/types.ts +0 -62
  822. package/src/swarm/worker-backend.ts +0 -121
  823. package/src/swarm/worker-prompts.ts +0 -79
  824. package/src/swarm/worker-runner.ts +0 -164
  825. package/src/tasks/SPEC.md +0 -139
  826. package/src/tasks/candidate-store.ts +0 -86
  827. package/src/tasks/ephemeral-permissions.ts +0 -50
  828. package/src/tasks/task-compiler.ts +0 -199
  829. package/src/tasks/task-runner.ts +0 -90
  830. package/src/tasks/task-scheduler.ts +0 -20
  831. package/src/tasks/task-store.ts +0 -127
  832. package/src/tasks/tool-sanitizer.ts +0 -36
  833. package/src/tools/apps/definitions.ts +0 -59
  834. package/src/tools/apps/executors.ts +0 -313
  835. package/src/tools/apps/open-proxy.ts +0 -43
  836. package/src/tools/apps/registry.ts +0 -16
  837. package/src/tools/assets/materialize.ts +0 -218
  838. package/src/tools/assets/search.ts +0 -361
  839. package/src/tools/browser/__tests__/auth-cache.test.ts +0 -219
  840. package/src/tools/browser/__tests__/auth-detector.test.ts +0 -362
  841. package/src/tools/browser/__tests__/jit-auth.test.ts +0 -189
  842. package/src/tools/browser/api-map.ts +0 -293
  843. package/src/tools/browser/auth-cache.ts +0 -149
  844. package/src/tools/browser/auth-detector.ts +0 -347
  845. package/src/tools/browser/auto-navigate.ts +0 -270
  846. package/src/tools/browser/browser-execution.ts +0 -980
  847. package/src/tools/browser/browser-handoff.ts +0 -79
  848. package/src/tools/browser/browser-manager.ts +0 -715
  849. package/src/tools/browser/browser-screencast.ts +0 -217
  850. package/src/tools/browser/headless-browser.ts +0 -450
  851. package/src/tools/browser/jit-auth.ts +0 -51
  852. package/src/tools/browser/network-recorder.ts +0 -349
  853. package/src/tools/browser/network-recording-types.ts +0 -49
  854. package/src/tools/browser/recording-store.ts +0 -49
  855. package/src/tools/browser/runtime-check.ts +0 -43
  856. package/src/tools/browser/x-auto-navigate.ts +0 -207
  857. package/src/tools/calls/call-end.ts +0 -67
  858. package/src/tools/calls/call-start.ts +0 -73
  859. package/src/tools/calls/call-status.ts +0 -81
  860. package/src/tools/claude-code/claude-code.ts +0 -428
  861. package/src/tools/computer-use/definitions.ts +0 -443
  862. package/src/tools/computer-use/registry.ts +0 -22
  863. package/src/tools/computer-use/request-computer-control.ts +0 -53
  864. package/src/tools/computer-use/skill-proxy-bridge.ts +0 -28
  865. package/src/tools/contacts/contact-merge.ts +0 -55
  866. package/src/tools/contacts/contact-search.ts +0 -58
  867. package/src/tools/contacts/contact-upsert.ts +0 -64
  868. package/src/tools/credentials/account-registry.ts +0 -127
  869. package/src/tools/credentials/broker-types.ts +0 -107
  870. package/src/tools/credentials/broker.ts +0 -372
  871. package/src/tools/credentials/domain-policy.ts +0 -51
  872. package/src/tools/credentials/host-pattern-match.ts +0 -60
  873. package/src/tools/credentials/metadata-store.ts +0 -335
  874. package/src/tools/credentials/policy-types.ts +0 -52
  875. package/src/tools/credentials/policy-validate.ts +0 -80
  876. package/src/tools/credentials/resolve.ts +0 -122
  877. package/src/tools/credentials/selection.ts +0 -159
  878. package/src/tools/credentials/tool-policy.ts +0 -25
  879. package/src/tools/credentials/vault.ts +0 -657
  880. package/src/tools/document/document-tool.ts +0 -92
  881. package/src/tools/document/editor-template.ts +0 -237
  882. package/src/tools/executor.ts +0 -944
  883. package/src/tools/filesystem/edit.ts +0 -127
  884. package/src/tools/filesystem/fuzzy-match.ts +0 -202
  885. package/src/tools/filesystem/read.ts +0 -71
  886. package/src/tools/filesystem/view-image.ts +0 -199
  887. package/src/tools/filesystem/write.ts +0 -79
  888. package/src/tools/followups/followup_create.ts +0 -76
  889. package/src/tools/followups/followup_list.ts +0 -60
  890. package/src/tools/followups/followup_resolve.ts +0 -56
  891. package/src/tools/host-filesystem/edit.ts +0 -125
  892. package/src/tools/host-filesystem/read.ts +0 -80
  893. package/src/tools/host-filesystem/write.ts +0 -76
  894. package/src/tools/host-terminal/cli-discover.ts +0 -180
  895. package/src/tools/host-terminal/host-shell.ts +0 -191
  896. package/src/tools/memory/definitions.ts +0 -69
  897. package/src/tools/memory/handlers.ts +0 -246
  898. package/src/tools/memory/register.ts +0 -66
  899. package/src/tools/network/__tests__/web-search.test.ts +0 -427
  900. package/src/tools/network/domain-normalize.ts +0 -85
  901. package/src/tools/network/script-proxy/__tests__/logging.test.ts +0 -248
  902. package/src/tools/network/script-proxy/__tests__/policy.test.ts +0 -234
  903. package/src/tools/network/script-proxy/__tests__/router.test.ts +0 -76
  904. package/src/tools/network/script-proxy/certs.ts +0 -237
  905. package/src/tools/network/script-proxy/connect-tunnel.ts +0 -82
  906. package/src/tools/network/script-proxy/http-forwarder.ts +0 -151
  907. package/src/tools/network/script-proxy/index.ts +0 -28
  908. package/src/tools/network/script-proxy/logging.ts +0 -196
  909. package/src/tools/network/script-proxy/mitm-handler.ts +0 -269
  910. package/src/tools/network/script-proxy/policy.ts +0 -152
  911. package/src/tools/network/script-proxy/router.ts +0 -60
  912. package/src/tools/network/script-proxy/server.ts +0 -136
  913. package/src/tools/network/script-proxy/session-manager.ts +0 -534
  914. package/src/tools/network/script-proxy/types.ts +0 -125
  915. package/src/tools/network/url-safety.ts +0 -227
  916. package/src/tools/network/web-fetch.ts +0 -713
  917. package/src/tools/network/web-search.ts +0 -319
  918. package/src/tools/playbooks/index.ts +0 -4
  919. package/src/tools/playbooks/playbook-create.ts +0 -96
  920. package/src/tools/playbooks/playbook-delete.ts +0 -52
  921. package/src/tools/playbooks/playbook-list.ts +0 -74
  922. package/src/tools/playbooks/playbook-update.ts +0 -111
  923. package/src/tools/registry.ts +0 -295
  924. package/src/tools/reminder/reminder-store.ts +0 -148
  925. package/src/tools/reminder/reminder.ts +0 -80
  926. package/src/tools/schedule/create.ts +0 -81
  927. package/src/tools/schedule/delete.ts +0 -28
  928. package/src/tools/schedule/list.ts +0 -69
  929. package/src/tools/schedule/update.ts +0 -90
  930. package/src/tools/shared/filesystem/edit-engine.ts +0 -56
  931. package/src/tools/shared/filesystem/errors.ts +0 -85
  932. package/src/tools/shared/filesystem/file-ops-service.ts +0 -215
  933. package/src/tools/shared/filesystem/format-diff.ts +0 -35
  934. package/src/tools/shared/filesystem/path-policy.ts +0 -125
  935. package/src/tools/shared/filesystem/size-guard.ts +0 -41
  936. package/src/tools/shared/filesystem/types.ts +0 -80
  937. package/src/tools/shared/shell-output.ts +0 -52
  938. package/src/tools/skills/delete-managed.ts +0 -60
  939. package/src/tools/skills/load.ts +0 -139
  940. package/src/tools/skills/sandbox-runner.ts +0 -279
  941. package/src/tools/skills/scaffold-managed.ts +0 -150
  942. package/src/tools/skills/script-contract.ts +0 -6
  943. package/src/tools/skills/skill-script-runner.ts +0 -86
  944. package/src/tools/skills/skill-tool-factory.ts +0 -64
  945. package/src/tools/skills/vellum-catalog.ts +0 -217
  946. package/src/tools/subagent/abort.ts +0 -33
  947. package/src/tools/subagent/message.ts +0 -39
  948. package/src/tools/subagent/read.ts +0 -67
  949. package/src/tools/subagent/spawn.ts +0 -46
  950. package/src/tools/subagent/status.ts +0 -45
  951. package/src/tools/swarm/delegate.ts +0 -183
  952. package/src/tools/system/request-permission.ts +0 -98
  953. package/src/tools/system/version.ts +0 -43
  954. package/src/tools/tasks/index.ts +0 -27
  955. package/src/tools/tasks/task-delete.ts +0 -82
  956. package/src/tools/tasks/task-list.ts +0 -44
  957. package/src/tools/tasks/task-run.ts +0 -97
  958. package/src/tools/tasks/task-save.ts +0 -47
  959. package/src/tools/tasks/work-item-enqueue.ts +0 -234
  960. package/src/tools/tasks/work-item-list.ts +0 -55
  961. package/src/tools/tasks/work-item-remove.ts +0 -60
  962. package/src/tools/tasks/work-item-run.ts +0 -78
  963. package/src/tools/tasks/work-item-update.ts +0 -114
  964. package/src/tools/terminal/backends/docker.ts +0 -372
  965. package/src/tools/terminal/backends/native.ts +0 -190
  966. package/src/tools/terminal/backends/types.ts +0 -26
  967. package/src/tools/terminal/evaluate-typescript.ts +0 -275
  968. package/src/tools/terminal/parser.ts +0 -415
  969. package/src/tools/terminal/safe-env.ts +0 -37
  970. package/src/tools/terminal/sandbox-diagnostics.ts +0 -149
  971. package/src/tools/terminal/sandbox.ts +0 -44
  972. package/src/tools/terminal/shell.ts +0 -257
  973. package/src/tools/tool-manifest.ts +0 -198
  974. package/src/tools/types.ts +0 -183
  975. package/src/tools/ui-surface/definitions.ts +0 -244
  976. package/src/tools/ui-surface/registry.ts +0 -14
  977. package/src/tools/watch/screen-watch.ts +0 -130
  978. package/src/tools/watch/watch-state.ts +0 -119
  979. package/src/tools/watcher/create.ts +0 -64
  980. package/src/tools/watcher/delete.ts +0 -27
  981. package/src/tools/watcher/digest.ts +0 -50
  982. package/src/tools/watcher/list.ts +0 -60
  983. package/src/tools/watcher/update.ts +0 -56
  984. package/src/tools/weather/service.ts +0 -551
  985. package/src/twitter/client.ts +0 -690
  986. package/src/twitter/session.ts +0 -91
  987. package/src/usage/actors.ts +0 -24
  988. package/src/usage/types.ts +0 -37
  989. package/src/util/clipboard.ts +0 -33
  990. package/src/util/content-id.ts +0 -16
  991. package/src/util/diff.ts +0 -181
  992. package/src/util/errors.ts +0 -129
  993. package/src/util/logger.ts +0 -243
  994. package/src/util/platform.ts +0 -607
  995. package/src/util/pricing.ts +0 -150
  996. package/src/util/spinner.ts +0 -51
  997. package/src/util/time.ts +0 -16
  998. package/src/util/truncate.ts +0 -6
  999. package/src/util/xml.ts +0 -4
  1000. package/src/version.ts +0 -3
  1001. package/src/watcher/constants.ts +0 -11
  1002. package/src/watcher/engine.ts +0 -199
  1003. package/src/watcher/provider-registry.ts +0 -15
  1004. package/src/watcher/provider-types.ts +0 -48
  1005. package/src/watcher/providers/gmail.ts +0 -198
  1006. package/src/watcher/providers/google-calendar.ts +0 -228
  1007. package/src/watcher/providers/slack.ts +0 -129
  1008. package/src/watcher/watcher-store.ts +0 -419
  1009. package/src/work-items/work-item-runner.ts +0 -171
  1010. package/src/work-items/work-item-store.ts +0 -325
  1011. package/src/workspace/commit-message-enrichment-service.ts +0 -284
  1012. package/src/workspace/commit-message-provider.ts +0 -95
  1013. package/src/workspace/git-service.ts +0 -840
  1014. package/src/workspace/heartbeat-service.ts +0 -345
  1015. package/src/workspace/provider-commit-message-generator.ts +0 -285
  1016. package/src/workspace/top-level-renderer.ts +0 -19
  1017. package/src/workspace/top-level-scanner.ts +0 -41
  1018. package/src/workspace/turn-commit.ts +0 -175
  1019. package/tsconfig.json +0 -21
package/src/memory/db.ts DELETED
@@ -1,1825 +0,0 @@
1
- import { Database } from 'bun:sqlite';
2
- import { drizzle } from 'drizzle-orm/bun-sqlite';
3
- import { computeMemoryFingerprint } from './fingerprint.js';
4
- import * as schema from './schema.js';
5
- import { getDbPath, ensureDataDir, migrateToDataLayout, migrateToWorkspaceLayout } from '../util/platform.js';
6
- import { getLogger } from '../util/logger.js';
7
-
8
- const log = getLogger('memory-db');
9
-
10
- let db: ReturnType<typeof drizzle<typeof schema>> | null = null;
11
-
12
- export function getDb() {
13
- if (!db) {
14
- migrateToDataLayout();
15
- migrateToWorkspaceLayout();
16
- ensureDataDir();
17
- const sqlite = new Database(getDbPath());
18
- sqlite.exec('PRAGMA journal_mode=WAL');
19
- sqlite.exec('PRAGMA foreign_keys = ON');
20
- db = drizzle(sqlite, { schema });
21
- }
22
- return db;
23
- }
24
-
25
- /** Reset the db singleton. Used by tests to ensure isolation between test files. */
26
- export function resetDb(): void {
27
- if (db) {
28
- const raw = (db as unknown as { $client: Database }).$client;
29
- raw.close();
30
- db = null;
31
- }
32
- }
33
-
34
- export function initializeDb(): void {
35
- const database = getDb();
36
-
37
- database.run(/*sql*/ `
38
- CREATE TABLE IF NOT EXISTS conversations (
39
- id TEXT PRIMARY KEY,
40
- title TEXT,
41
- created_at INTEGER NOT NULL,
42
- updated_at INTEGER NOT NULL,
43
- total_input_tokens INTEGER NOT NULL DEFAULT 0,
44
- total_output_tokens INTEGER NOT NULL DEFAULT 0,
45
- total_estimated_cost REAL NOT NULL DEFAULT 0,
46
- context_summary TEXT,
47
- context_compacted_message_count INTEGER NOT NULL DEFAULT 0,
48
- context_compacted_at INTEGER
49
- )
50
- `);
51
-
52
- database.run(/*sql*/ `
53
- CREATE TABLE IF NOT EXISTS messages (
54
- id TEXT PRIMARY KEY,
55
- conversation_id TEXT NOT NULL REFERENCES conversations(id),
56
- role TEXT NOT NULL,
57
- content TEXT NOT NULL,
58
- created_at INTEGER NOT NULL
59
- )
60
- `);
61
-
62
- database.run(/*sql*/ `
63
- CREATE TABLE IF NOT EXISTS tool_invocations (
64
- id TEXT PRIMARY KEY,
65
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
66
- tool_name TEXT NOT NULL,
67
- input TEXT NOT NULL,
68
- result TEXT NOT NULL,
69
- decision TEXT NOT NULL,
70
- risk_level TEXT NOT NULL,
71
- duration_ms INTEGER NOT NULL,
72
- created_at INTEGER NOT NULL
73
- )
74
- `);
75
-
76
- database.run(/*sql*/ `
77
- CREATE TABLE IF NOT EXISTS memory_segments (
78
- id TEXT PRIMARY KEY,
79
- message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
80
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
81
- role TEXT NOT NULL,
82
- segment_index INTEGER NOT NULL,
83
- text TEXT NOT NULL,
84
- token_estimate INTEGER NOT NULL,
85
- created_at INTEGER NOT NULL,
86
- updated_at INTEGER NOT NULL
87
- )
88
- `);
89
-
90
- database.run(/*sql*/ `
91
- CREATE TABLE IF NOT EXISTS memory_items (
92
- id TEXT PRIMARY KEY,
93
- kind TEXT NOT NULL,
94
- subject TEXT NOT NULL,
95
- statement TEXT NOT NULL,
96
- status TEXT NOT NULL,
97
- confidence REAL NOT NULL,
98
- fingerprint TEXT NOT NULL,
99
- first_seen_at INTEGER NOT NULL,
100
- last_seen_at INTEGER NOT NULL,
101
- last_used_at INTEGER
102
- )
103
- `);
104
-
105
- database.run(/*sql*/ `
106
- CREATE TABLE IF NOT EXISTS memory_item_sources (
107
- memory_item_id TEXT NOT NULL REFERENCES memory_items(id) ON DELETE CASCADE,
108
- message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
109
- evidence TEXT,
110
- created_at INTEGER NOT NULL,
111
- PRIMARY KEY (memory_item_id, message_id)
112
- )
113
- `);
114
-
115
- database.run(/*sql*/ `
116
- CREATE TABLE IF NOT EXISTS memory_item_conflicts (
117
- id TEXT PRIMARY KEY,
118
- scope_id TEXT NOT NULL DEFAULT 'default',
119
- existing_item_id TEXT NOT NULL REFERENCES memory_items(id) ON DELETE CASCADE,
120
- candidate_item_id TEXT NOT NULL REFERENCES memory_items(id) ON DELETE CASCADE,
121
- relationship TEXT NOT NULL,
122
- status TEXT NOT NULL,
123
- clarification_question TEXT,
124
- resolution_note TEXT,
125
- last_asked_at INTEGER,
126
- resolved_at INTEGER,
127
- created_at INTEGER NOT NULL,
128
- updated_at INTEGER NOT NULL
129
- )
130
- `);
131
-
132
- database.run(/*sql*/ `
133
- CREATE TABLE IF NOT EXISTS memory_summaries (
134
- id TEXT PRIMARY KEY,
135
- scope TEXT NOT NULL,
136
- scope_key TEXT NOT NULL,
137
- summary TEXT NOT NULL,
138
- token_estimate INTEGER NOT NULL,
139
- start_at INTEGER NOT NULL,
140
- end_at INTEGER NOT NULL,
141
- created_at INTEGER NOT NULL,
142
- updated_at INTEGER NOT NULL,
143
- UNIQUE (scope, scope_key)
144
- )
145
- `);
146
-
147
- database.run(/*sql*/ `
148
- CREATE TABLE IF NOT EXISTS memory_embeddings (
149
- id TEXT PRIMARY KEY,
150
- target_type TEXT NOT NULL,
151
- target_id TEXT NOT NULL,
152
- provider TEXT NOT NULL,
153
- model TEXT NOT NULL,
154
- dimensions INTEGER NOT NULL,
155
- vector_json TEXT NOT NULL,
156
- created_at INTEGER NOT NULL,
157
- updated_at INTEGER NOT NULL,
158
- UNIQUE (target_type, target_id, provider, model)
159
- )
160
- `);
161
-
162
- database.run(/*sql*/ `
163
- CREATE TABLE IF NOT EXISTS memory_jobs (
164
- id TEXT PRIMARY KEY,
165
- type TEXT NOT NULL,
166
- payload TEXT NOT NULL,
167
- status TEXT NOT NULL,
168
- attempts INTEGER NOT NULL DEFAULT 0,
169
- run_after INTEGER NOT NULL,
170
- last_error TEXT,
171
- created_at INTEGER NOT NULL,
172
- updated_at INTEGER NOT NULL
173
- )
174
- `);
175
-
176
- database.run(/*sql*/ `
177
- CREATE TABLE IF NOT EXISTS memory_checkpoints (
178
- key TEXT PRIMARY KEY,
179
- value TEXT NOT NULL,
180
- updated_at INTEGER NOT NULL
181
- )
182
- `);
183
-
184
- database.run(/*sql*/ `
185
- CREATE TABLE IF NOT EXISTS attachments (
186
- id TEXT PRIMARY KEY,
187
- original_filename TEXT NOT NULL,
188
- mime_type TEXT NOT NULL,
189
- size_bytes INTEGER NOT NULL,
190
- kind TEXT NOT NULL,
191
- data_base64 TEXT NOT NULL,
192
- created_at INTEGER NOT NULL
193
- )
194
- `);
195
-
196
- database.run(/*sql*/ `
197
- CREATE TABLE IF NOT EXISTS message_attachments (
198
- id TEXT PRIMARY KEY,
199
- message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
200
- attachment_id TEXT NOT NULL REFERENCES attachments(id) ON DELETE CASCADE,
201
- position INTEGER NOT NULL DEFAULT 0,
202
- created_at INTEGER NOT NULL
203
- )
204
- `);
205
-
206
- database.run(/*sql*/ `
207
- CREATE TABLE IF NOT EXISTS message_surfaces (
208
- id TEXT PRIMARY KEY,
209
- message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
210
- surface_id TEXT NOT NULL,
211
- surface_type TEXT NOT NULL,
212
- title TEXT,
213
- data TEXT NOT NULL,
214
- actions TEXT,
215
- surface_message TEXT,
216
- display TEXT,
217
- position INTEGER NOT NULL DEFAULT 0,
218
- created_at INTEGER NOT NULL
219
- )
220
- `);
221
-
222
- database.run(/*sql*/ `
223
- CREATE TABLE IF NOT EXISTS channel_inbound_events (
224
- id TEXT PRIMARY KEY,
225
- source_channel TEXT NOT NULL,
226
- external_chat_id TEXT NOT NULL,
227
- external_message_id TEXT NOT NULL,
228
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
229
- message_id TEXT REFERENCES messages(id) ON DELETE CASCADE,
230
- delivery_status TEXT NOT NULL DEFAULT 'pending',
231
- created_at INTEGER NOT NULL,
232
- updated_at INTEGER NOT NULL,
233
- UNIQUE (source_channel, external_chat_id, external_message_id)
234
- )
235
- `);
236
-
237
- database.run(/*sql*/ `
238
- CREATE TABLE IF NOT EXISTS message_runs (
239
- id TEXT PRIMARY KEY,
240
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
241
- message_id TEXT REFERENCES messages(id) ON DELETE CASCADE,
242
- status TEXT NOT NULL DEFAULT 'running',
243
- pending_confirmation TEXT,
244
- pending_secret TEXT,
245
- input_tokens INTEGER NOT NULL DEFAULT 0,
246
- output_tokens INTEGER NOT NULL DEFAULT 0,
247
- estimated_cost REAL NOT NULL DEFAULT 0,
248
- error TEXT,
249
- created_at INTEGER NOT NULL,
250
- updated_at INTEGER NOT NULL
251
- )
252
- `);
253
-
254
- try { database.run(/*sql*/ `ALTER TABLE message_runs ADD COLUMN pending_secret TEXT`); } catch (e) { log.debug({ err: e }, 'ALTER TABLE message_runs ADD COLUMN pending_secret (likely already exists)'); }
255
-
256
- database.run(/*sql*/ `
257
- CREATE TABLE IF NOT EXISTS reminders (
258
- id TEXT PRIMARY KEY,
259
- label TEXT NOT NULL,
260
- message TEXT NOT NULL,
261
- fire_at INTEGER NOT NULL,
262
- mode TEXT NOT NULL,
263
- status TEXT NOT NULL,
264
- fired_at INTEGER,
265
- conversation_id TEXT,
266
- created_at INTEGER NOT NULL,
267
- updated_at INTEGER NOT NULL
268
- )
269
- `);
270
-
271
- database.run(/*sql*/ `
272
- CREATE TABLE IF NOT EXISTS cron_jobs (
273
- id TEXT PRIMARY KEY,
274
- name TEXT NOT NULL,
275
- enabled INTEGER NOT NULL DEFAULT 1,
276
- cron_expression TEXT NOT NULL,
277
- schedule_syntax TEXT NOT NULL DEFAULT 'cron',
278
- timezone TEXT,
279
- message TEXT NOT NULL,
280
- next_run_at INTEGER NOT NULL,
281
- last_run_at INTEGER,
282
- last_status TEXT,
283
- retry_count INTEGER NOT NULL DEFAULT 0,
284
- created_by TEXT NOT NULL,
285
- created_at INTEGER NOT NULL,
286
- updated_at INTEGER NOT NULL
287
- )
288
- `);
289
-
290
- database.run(/*sql*/ `
291
- CREATE TABLE IF NOT EXISTS cron_runs (
292
- id TEXT PRIMARY KEY,
293
- job_id TEXT NOT NULL REFERENCES cron_jobs(id) ON DELETE CASCADE,
294
- status TEXT NOT NULL,
295
- started_at INTEGER NOT NULL,
296
- finished_at INTEGER,
297
- duration_ms INTEGER,
298
- output TEXT,
299
- error TEXT,
300
- conversation_id TEXT,
301
- created_at INTEGER NOT NULL
302
- )
303
- `);
304
-
305
- database.run(/*sql*/ `
306
- CREATE TABLE IF NOT EXISTS accounts (
307
- id TEXT PRIMARY KEY,
308
- service TEXT NOT NULL,
309
- username TEXT,
310
- email TEXT,
311
- display_name TEXT,
312
- status TEXT NOT NULL DEFAULT 'active',
313
- credential_ref TEXT,
314
- metadata_json TEXT,
315
- created_at INTEGER NOT NULL,
316
- updated_at INTEGER NOT NULL
317
- )
318
- `);
319
-
320
- database.run(/*sql*/ `
321
- CREATE TABLE IF NOT EXISTS documents (
322
- surface_id TEXT PRIMARY KEY,
323
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
324
- title TEXT NOT NULL,
325
- content TEXT NOT NULL,
326
- word_count INTEGER NOT NULL DEFAULT 0,
327
- created_at INTEGER NOT NULL,
328
- updated_at INTEGER NOT NULL
329
- )
330
- `);
331
-
332
- database.run(/*sql*/ `
333
- CREATE TABLE IF NOT EXISTS published_pages (
334
- id TEXT PRIMARY KEY,
335
- deployment_id TEXT NOT NULL UNIQUE,
336
- public_url TEXT NOT NULL,
337
- page_title TEXT,
338
- html_hash TEXT NOT NULL,
339
- published_at INTEGER NOT NULL,
340
- status TEXT NOT NULL DEFAULT 'active'
341
- )
342
- `);
343
-
344
- try { database.run(/*sql*/ `ALTER TABLE published_pages ADD COLUMN app_id TEXT`); } catch (e) { log.debug({ err: e }, 'ALTER TABLE published_pages ADD COLUMN app_id (likely already exists)'); }
345
- try { database.run(/*sql*/ `ALTER TABLE published_pages ADD COLUMN project_slug TEXT`); } catch (e) { log.debug({ err: e }, 'ALTER TABLE published_pages ADD COLUMN project_slug (likely already exists)'); }
346
-
347
- database.run(/*sql*/ `
348
- CREATE TABLE IF NOT EXISTS shared_app_links (
349
- id TEXT PRIMARY KEY,
350
- share_token TEXT NOT NULL UNIQUE,
351
- bundle_data BLOB NOT NULL,
352
- bundle_size_bytes INTEGER NOT NULL,
353
- manifest_json TEXT NOT NULL,
354
- download_count INTEGER NOT NULL DEFAULT 0,
355
- created_at INTEGER NOT NULL,
356
- expires_at INTEGER
357
- )
358
- `);
359
-
360
- database.run(/*sql*/ `
361
- CREATE TABLE IF NOT EXISTS home_base_app_links (
362
- id TEXT PRIMARY KEY,
363
- app_id TEXT NOT NULL,
364
- source TEXT NOT NULL,
365
- created_at INTEGER NOT NULL,
366
- updated_at INTEGER NOT NULL
367
- )
368
- `);
369
-
370
- // ── Watchers ─────────────────────────────────────────────────────────
371
-
372
- database.run(/*sql*/ `
373
- CREATE TABLE IF NOT EXISTS watchers (
374
- id TEXT PRIMARY KEY,
375
- name TEXT NOT NULL,
376
- provider_id TEXT NOT NULL,
377
- enabled INTEGER NOT NULL DEFAULT 1,
378
- poll_interval_ms INTEGER NOT NULL DEFAULT 60000,
379
- action_prompt TEXT NOT NULL,
380
- watermark TEXT,
381
- conversation_id TEXT,
382
- status TEXT NOT NULL DEFAULT 'idle',
383
- consecutive_errors INTEGER NOT NULL DEFAULT 0,
384
- last_error TEXT,
385
- last_poll_at INTEGER,
386
- next_poll_at INTEGER NOT NULL,
387
- config_json TEXT,
388
- credential_service TEXT NOT NULL,
389
- created_at INTEGER NOT NULL,
390
- updated_at INTEGER NOT NULL
391
- )
392
- `);
393
-
394
- database.run(/*sql*/ `
395
- CREATE TABLE IF NOT EXISTS watcher_events (
396
- id TEXT PRIMARY KEY,
397
- watcher_id TEXT NOT NULL REFERENCES watchers(id) ON DELETE CASCADE,
398
- external_id TEXT NOT NULL,
399
- event_type TEXT NOT NULL,
400
- summary TEXT NOT NULL,
401
- payload_json TEXT NOT NULL,
402
- disposition TEXT NOT NULL DEFAULT 'pending',
403
- llm_action TEXT,
404
- processed_at INTEGER,
405
- created_at INTEGER NOT NULL,
406
- UNIQUE (watcher_id, external_id)
407
- )
408
- `);
409
-
410
- database.run(/*sql*/ `
411
- CREATE TABLE IF NOT EXISTS llm_request_logs (
412
- id TEXT PRIMARY KEY,
413
- conversation_id TEXT NOT NULL,
414
- request_payload TEXT NOT NULL,
415
- response_payload TEXT NOT NULL,
416
- created_at INTEGER NOT NULL
417
- )
418
- `);
419
-
420
- database.run(/*sql*/ `
421
- CREATE TABLE IF NOT EXISTS llm_usage_events (
422
- id TEXT PRIMARY KEY,
423
- created_at INTEGER NOT NULL,
424
- conversation_id TEXT,
425
- run_id TEXT,
426
- request_id TEXT,
427
- actor TEXT NOT NULL,
428
- provider TEXT NOT NULL,
429
- model TEXT NOT NULL,
430
- input_tokens INTEGER NOT NULL,
431
- output_tokens INTEGER NOT NULL,
432
- cache_creation_input_tokens INTEGER,
433
- cache_read_input_tokens INTEGER,
434
- estimated_cost_usd REAL,
435
- pricing_status TEXT NOT NULL,
436
- metadata_json TEXT
437
- )
438
- `);
439
-
440
- database.run(/*sql*/ `
441
- CREATE TABLE IF NOT EXISTS memory_entities (
442
- id TEXT PRIMARY KEY,
443
- name TEXT NOT NULL,
444
- type TEXT NOT NULL,
445
- aliases TEXT,
446
- description TEXT,
447
- first_seen_at INTEGER NOT NULL,
448
- last_seen_at INTEGER NOT NULL,
449
- mention_count INTEGER NOT NULL DEFAULT 1
450
- )
451
- `);
452
-
453
- database.run(/*sql*/ `
454
- CREATE TABLE IF NOT EXISTS memory_entity_relations (
455
- id TEXT PRIMARY KEY,
456
- source_entity_id TEXT NOT NULL,
457
- target_entity_id TEXT NOT NULL,
458
- relation TEXT NOT NULL,
459
- evidence TEXT,
460
- first_seen_at INTEGER NOT NULL,
461
- last_seen_at INTEGER NOT NULL
462
- )
463
- `);
464
-
465
- database.run(/*sql*/ `
466
- CREATE TABLE IF NOT EXISTS memory_item_entities (
467
- memory_item_id TEXT NOT NULL,
468
- entity_id TEXT NOT NULL,
469
- PRIMARY KEY (memory_item_id, entity_id)
470
- )
471
- `);
472
-
473
- // FTS table for lexical retrieval over memory_segments.text.
474
- database.run(/*sql*/ `
475
- CREATE VIRTUAL TABLE IF NOT EXISTS memory_segment_fts USING fts5(
476
- segment_id UNINDEXED,
477
- text
478
- )
479
- `);
480
-
481
- database.run(/*sql*/ `
482
- CREATE TRIGGER IF NOT EXISTS memory_segments_ai
483
- AFTER INSERT ON memory_segments
484
- BEGIN
485
- INSERT INTO memory_segment_fts(segment_id, text) VALUES (new.id, new.text);
486
- END
487
- `);
488
-
489
- database.run(/*sql*/ `
490
- CREATE TRIGGER IF NOT EXISTS memory_segments_ad
491
- AFTER DELETE ON memory_segments
492
- BEGIN
493
- DELETE FROM memory_segment_fts WHERE segment_id = old.id;
494
- END
495
- `);
496
-
497
- database.run(/*sql*/ `
498
- CREATE TRIGGER IF NOT EXISTS memory_segments_au
499
- AFTER UPDATE ON memory_segments
500
- BEGIN
501
- DELETE FROM memory_segment_fts WHERE segment_id = old.id;
502
- INSERT INTO memory_segment_fts(segment_id, text) VALUES (new.id, new.text);
503
- END
504
- `);
505
-
506
- database.run(/*sql*/ `
507
- CREATE TABLE IF NOT EXISTS conversation_keys (
508
- id TEXT PRIMARY KEY,
509
- conversation_key TEXT NOT NULL UNIQUE,
510
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
511
- created_at INTEGER NOT NULL
512
- )
513
- `);
514
-
515
- // Migrations — ALTER TABLE ADD COLUMN throws if column already exists
516
- try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN total_input_tokens INTEGER NOT NULL DEFAULT 0`); } catch { /* already exists */ }
517
- try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN total_output_tokens INTEGER NOT NULL DEFAULT 0`); } catch { /* already exists */ }
518
- try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN total_estimated_cost REAL NOT NULL DEFAULT 0`); } catch { /* already exists */ }
519
- try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN context_summary TEXT`); } catch { /* already exists */ }
520
- try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN context_compacted_message_count INTEGER NOT NULL DEFAULT 0`); } catch { /* already exists */ }
521
- try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN context_compacted_at INTEGER`); } catch { /* already exists */ }
522
- try { database.run(/*sql*/ `ALTER TABLE memory_items ADD COLUMN importance REAL`); } catch { /* already exists */ }
523
- try { database.run(/*sql*/ `ALTER TABLE memory_items ADD COLUMN access_count INTEGER NOT NULL DEFAULT 0`); } catch { /* already exists */ }
524
- try { database.run(/*sql*/ `ALTER TABLE memory_summaries ADD COLUMN version INTEGER NOT NULL DEFAULT 1`); } catch { /* already exists */ }
525
- try { database.run(/*sql*/ `ALTER TABLE memory_items ADD COLUMN valid_from INTEGER`); } catch { /* already exists */ }
526
- try { database.run(/*sql*/ `ALTER TABLE memory_items ADD COLUMN invalid_at INTEGER`); } catch { /* already exists */ }
527
- try { database.run(/*sql*/ `ALTER TABLE memory_items ADD COLUMN verification_state TEXT NOT NULL DEFAULT 'assistant_inferred'`); } catch { /* already exists */ }
528
- try { database.run(/*sql*/ `ALTER TABLE memory_jobs ADD COLUMN deferrals INTEGER NOT NULL DEFAULT 0`); } catch { /* already exists */ }
529
- try { database.run(/*sql*/ `ALTER TABLE memory_segments ADD COLUMN scope_id TEXT NOT NULL DEFAULT 'default'`); } catch { /* already exists */ }
530
- try { database.run(/*sql*/ `ALTER TABLE memory_items ADD COLUMN scope_id TEXT NOT NULL DEFAULT 'default'`); } catch { /* already exists */ }
531
- try { database.run(/*sql*/ `ALTER TABLE memory_summaries ADD COLUMN scope_id TEXT NOT NULL DEFAULT 'default'`); } catch { /* already exists */ }
532
- try { database.run(/*sql*/ `ALTER TABLE memory_segments ADD COLUMN content_hash TEXT`); } catch { /* already exists */ }
533
- try { database.run(/*sql*/ `ALTER TABLE channel_inbound_events ADD COLUMN source_message_id TEXT`); } catch { /* already exists */ }
534
- try { database.run(/*sql*/ `ALTER TABLE attachments ADD COLUMN content_hash TEXT`); } catch { /* already exists */ }
535
- try { database.run(/*sql*/ `ALTER TABLE channel_inbound_events ADD COLUMN processing_status TEXT NOT NULL DEFAULT 'pending'`); } catch { /* already exists */ }
536
- try { database.run(/*sql*/ `ALTER TABLE channel_inbound_events ADD COLUMN processing_attempts INTEGER NOT NULL DEFAULT 0`); } catch { /* already exists */ }
537
- try { database.run(/*sql*/ `ALTER TABLE channel_inbound_events ADD COLUMN last_processing_error TEXT`); } catch { /* already exists */ }
538
- try { database.run(/*sql*/ `ALTER TABLE channel_inbound_events ADD COLUMN retry_after INTEGER`); } catch { /* already exists */ }
539
- try { database.run(/*sql*/ `ALTER TABLE channel_inbound_events ADD COLUMN raw_payload TEXT`); } catch { /* already exists */ }
540
- try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN thread_type TEXT NOT NULL DEFAULT 'standard'`); } catch { /* already exists */ }
541
- try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN memory_scope_id TEXT NOT NULL DEFAULT 'default'`); } catch { /* already exists */ }
542
- try { database.run(/*sql*/ `ALTER TABLE attachments ADD COLUMN thumbnail_base64 TEXT`); } catch { /* already exists */ }
543
- try { database.run(/*sql*/ `ALTER TABLE cron_jobs ADD COLUMN schedule_syntax TEXT NOT NULL DEFAULT 'cron'`); } catch { /* already exists */ }
544
- try { database.run(/*sql*/ `ALTER TABLE messages ADD COLUMN metadata TEXT`); } catch { /* already exists */ }
545
-
546
- migrateJobDeferrals(database);
547
- migrateToolInvocationsFk(database);
548
- migrateMemoryEntityRelationDedup(database);
549
- migrateMemoryItemsFingerprintScopeUnique(database);
550
- migrateMemoryItemsScopeSaltedFingerprints(database);
551
- migrateAssistantIdToSelf(database);
552
- migrateRemoveAssistantIdColumns(database);
553
- migrateLlmUsageEventsDropAssistantId(database);
554
-
555
- // Indexes for query performance on large datasets
556
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_llm_request_logs_conv_created ON llm_request_logs(conversation_id, created_at)`);
557
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_messages_conversation_id ON messages(conversation_id)`);
558
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_tool_invocations_conversation_id ON tool_invocations(conversation_id)`);
559
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_conversations_updated_at ON conversations(updated_at)`);
560
- database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_memory_segments_message_segment ON memory_segments(message_id, segment_index)`);
561
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_segments_conversation_created ON memory_segments(conversation_id, created_at DESC)`);
562
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_item_sources_message_id ON memory_item_sources(message_id)`);
563
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_item_conflicts_status_created ON memory_item_conflicts(status, created_at)`);
564
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_item_conflicts_status_resolved_at ON memory_item_conflicts(status, resolved_at)`);
565
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_item_conflicts_scope_status ON memory_item_conflicts(scope_id, status)`);
566
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_item_conflicts_existing_item_id ON memory_item_conflicts(existing_item_id)`);
567
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_item_conflicts_candidate_item_id ON memory_item_conflicts(candidate_item_id)`);
568
- database.run(/*sql*/ `
569
- CREATE UNIQUE INDEX IF NOT EXISTS idx_memory_item_conflicts_pending_pair_unique
570
- ON memory_item_conflicts(scope_id, existing_item_id, candidate_item_id)
571
- WHERE status = 'pending_clarification'
572
- `);
573
- database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_memory_items_fingerprint_scope ON memory_items(fingerprint, scope_id)`);
574
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_kind_status ON memory_items(kind, status)`);
575
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_status_invalid_at ON memory_items(status, invalid_at)`);
576
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_scope_status_kind ON memory_items(scope_id, status, kind)`);
577
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_last_seen_at ON memory_items(last_seen_at)`);
578
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_embeddings_target ON memory_embeddings(target_type, target_id)`);
579
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_embeddings_provider_model ON memory_embeddings(provider, model)`);
580
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_jobs_status_run_after ON memory_jobs(status, run_after)`);
581
- database.run(/*sql*/ `
582
- CREATE INDEX IF NOT EXISTS idx_memory_jobs_conflict_resolve_dedupe
583
- ON memory_jobs(
584
- type,
585
- status,
586
- json_extract(payload, '$.messageId'),
587
- COALESCE(json_extract(payload, '$.scopeId'), 'default')
588
- )
589
- `);
590
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_summaries_scope_time ON memory_summaries(scope, end_at DESC)`);
591
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_segments_scope_id ON memory_segments(scope_id)`);
592
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_scope_id ON memory_items(scope_id)`);
593
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_summaries_scope_id ON memory_summaries(scope_id)`);
594
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_conversation_keys_key ON conversation_keys(conversation_key)`);
595
- // Deduplicate before creating unique index — existing DBs may have duplicate content_hash values.
596
- // Re-point message_attachments to the survivor (MIN rowid per content_hash), then delete dupes.
597
- {
598
- const raw = (database as unknown as { $client: Database }).$client;
599
- raw.exec(/*sql*/ `
600
- UPDATE message_attachments
601
- SET attachment_id = (
602
- SELECT a_survivor.id
603
- FROM attachments a_survivor
604
- WHERE a_survivor.content_hash = (
605
- SELECT a_dup.content_hash FROM attachments a_dup
606
- WHERE a_dup.id = message_attachments.attachment_id
607
- )
608
- ORDER BY a_survivor.rowid
609
- LIMIT 1
610
- )
611
- WHERE attachment_id IN (
612
- SELECT id FROM attachments
613
- WHERE content_hash IS NOT NULL
614
- AND rowid NOT IN (
615
- SELECT MIN(rowid) FROM attachments
616
- WHERE content_hash IS NOT NULL
617
- GROUP BY content_hash
618
- )
619
- )
620
- `);
621
- raw.exec(/*sql*/ `
622
- DELETE FROM attachments
623
- WHERE content_hash IS NOT NULL
624
- AND rowid NOT IN (
625
- SELECT MIN(rowid) FROM attachments
626
- WHERE content_hash IS NOT NULL
627
- GROUP BY content_hash
628
- )
629
- `);
630
- }
631
- database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_attachments_content_dedup ON attachments(content_hash) WHERE content_hash IS NOT NULL`);
632
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_message_attachments_message_id ON message_attachments(message_id)`);
633
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_message_attachments_attachment_id ON message_attachments(attachment_id)`);
634
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_channel_inbound_events_lookup ON channel_inbound_events(source_channel, external_chat_id, external_message_id)`);
635
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_channel_inbound_events_conversation ON channel_inbound_events(conversation_id)`);
636
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_channel_inbound_events_source_msg ON channel_inbound_events(source_channel, external_chat_id, source_message_id)`);
637
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_channel_inbound_events_processing_retry ON channel_inbound_events(processing_status, retry_after)`);
638
-
639
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_message_runs_status ON message_runs(status)`);
640
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_message_runs_conversation ON message_runs(conversation_id)`);
641
-
642
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_reminders_status_fire_at ON reminders(status, fire_at)`);
643
-
644
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled_next_run ON cron_jobs(enabled, next_run_at)`);
645
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_cron_jobs_syntax_enabled_next_run ON cron_jobs(schedule_syntax, enabled, next_run_at)`);
646
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_cron_runs_job_id ON cron_runs(job_id)`);
647
-
648
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_accounts_service ON accounts(service)`);
649
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_accounts_status ON accounts(status)`);
650
-
651
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_llm_usage_events_created_at ON llm_usage_events(created_at)`);
652
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_llm_usage_events_provider ON llm_usage_events(provider)`);
653
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_llm_usage_events_model ON llm_usage_events(model)`);
654
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_llm_usage_events_actor ON llm_usage_events(actor)`);
655
-
656
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_shared_app_links_share_token ON shared_app_links(share_token)`);
657
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_home_base_app_links_app_id ON home_base_app_links(app_id)`);
658
-
659
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_published_pages_html_hash ON published_pages(html_hash)`);
660
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_published_pages_status ON published_pages(status)`);
661
-
662
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_watchers_enabled_next_poll ON watchers(enabled, next_poll_at)`);
663
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_watchers_status ON watchers(status)`);
664
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_watcher_events_watcher_id ON watcher_events(watcher_id)`);
665
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_watcher_events_disposition ON watcher_events(disposition)`);
666
-
667
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_entities_name ON memory_entities(name)`);
668
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_entities_type ON memory_entities(type)`);
669
- database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_memory_entity_relations_unique_edge ON memory_entity_relations(source_entity_id, target_entity_id, relation)`);
670
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_entity_relations_source ON memory_entity_relations(source_entity_id)`);
671
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_entity_relations_target ON memory_entity_relations(target_entity_id)`);
672
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_item_entities_memory_item ON memory_item_entities(memory_item_id)`);
673
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_item_entities_entity ON memory_item_entities(entity_id)`);
674
-
675
- // ── Contacts ────────────────────────────────────────────────────────
676
-
677
- database.run(/*sql*/ `
678
- CREATE TABLE IF NOT EXISTS contacts (
679
- id TEXT PRIMARY KEY,
680
- display_name TEXT NOT NULL,
681
- relationship TEXT,
682
- importance REAL NOT NULL DEFAULT 0.5,
683
- response_expectation TEXT,
684
- preferred_tone TEXT,
685
- last_interaction INTEGER,
686
- interaction_count INTEGER NOT NULL DEFAULT 0,
687
- created_at INTEGER NOT NULL,
688
- updated_at INTEGER NOT NULL
689
- )
690
- `);
691
-
692
- database.run(/*sql*/ `
693
- CREATE TABLE IF NOT EXISTS contact_channels (
694
- id TEXT PRIMARY KEY,
695
- contact_id TEXT NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
696
- type TEXT NOT NULL,
697
- address TEXT NOT NULL,
698
- is_primary INTEGER NOT NULL DEFAULT 0,
699
- created_at INTEGER NOT NULL
700
- )
701
- `);
702
-
703
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_contacts_display_name ON contacts(display_name)`);
704
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_contacts_importance ON contacts(importance DESC)`);
705
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_contacts_last_interaction ON contacts(last_interaction DESC)`);
706
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_contact_channels_contact_id ON contact_channels(contact_id)`);
707
- database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_contact_channels_type_address ON contact_channels(type, address)`);
708
-
709
- // ── Triage Results ─────────────────────────────────────────────────
710
-
711
- database.run(/*sql*/ `
712
- CREATE TABLE IF NOT EXISTS triage_results (
713
- id TEXT PRIMARY KEY,
714
- channel TEXT NOT NULL,
715
- sender TEXT NOT NULL,
716
- category TEXT NOT NULL,
717
- confidence REAL NOT NULL,
718
- suggested_action TEXT NOT NULL,
719
- matched_playbook_ids TEXT,
720
- message_id TEXT,
721
- created_at INTEGER NOT NULL
722
- )
723
- `);
724
-
725
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_triage_results_channel ON triage_results(channel)`);
726
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_triage_results_category ON triage_results(category)`);
727
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_triage_results_sender ON triage_results(sender)`);
728
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_triage_results_created_at ON triage_results(created_at DESC)`);
729
-
730
- // ── Call Sessions (outgoing AI phone calls) ────────────────────────
731
-
732
- database.run(/*sql*/ `
733
- CREATE TABLE IF NOT EXISTS call_sessions (
734
- id TEXT PRIMARY KEY,
735
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
736
- provider TEXT NOT NULL,
737
- provider_call_sid TEXT,
738
- from_number TEXT NOT NULL,
739
- to_number TEXT NOT NULL,
740
- task TEXT,
741
- status TEXT NOT NULL DEFAULT 'initiated',
742
- started_at INTEGER,
743
- ended_at INTEGER,
744
- last_error TEXT,
745
- created_at INTEGER NOT NULL,
746
- updated_at INTEGER NOT NULL
747
- )
748
- `);
749
-
750
- database.run(/*sql*/ `
751
- CREATE TABLE IF NOT EXISTS call_events (
752
- id TEXT PRIMARY KEY,
753
- call_session_id TEXT NOT NULL REFERENCES call_sessions(id) ON DELETE CASCADE,
754
- event_type TEXT NOT NULL,
755
- payload_json TEXT NOT NULL DEFAULT '{}',
756
- created_at INTEGER NOT NULL
757
- )
758
- `);
759
-
760
- database.run(/*sql*/ `
761
- CREATE TABLE IF NOT EXISTS call_pending_questions (
762
- id TEXT PRIMARY KEY,
763
- call_session_id TEXT NOT NULL REFERENCES call_sessions(id) ON DELETE CASCADE,
764
- question_text TEXT NOT NULL,
765
- status TEXT NOT NULL DEFAULT 'pending',
766
- asked_at INTEGER NOT NULL,
767
- answered_at INTEGER,
768
- answer_text TEXT
769
- )
770
- `);
771
-
772
- database.run(/*sql*/ `
773
- CREATE TABLE IF NOT EXISTS processed_callbacks (
774
- id TEXT PRIMARY KEY,
775
- dedupe_key TEXT NOT NULL UNIQUE,
776
- call_session_id TEXT NOT NULL REFERENCES call_sessions(id) ON DELETE CASCADE,
777
- created_at INTEGER NOT NULL
778
- )
779
- `);
780
-
781
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_call_sessions_conversation_id ON call_sessions(conversation_id)`);
782
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_call_sessions_provider_call_sid ON call_sessions(provider_call_sid)`);
783
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_call_sessions_status ON call_sessions(status)`);
784
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_call_events_call_session_id ON call_events(call_session_id)`);
785
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_call_pending_questions_call_session_id ON call_pending_questions(call_session_id)`);
786
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_call_pending_questions_status ON call_pending_questions(status)`);
787
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_processed_callbacks_dedupe_key ON processed_callbacks(dedupe_key)`);
788
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_processed_callbacks_call_session_id ON processed_callbacks(call_session_id)`);
789
-
790
- // Add claim ownership token to prevent cross-handler claim interference
791
- try { database.run(/*sql*/ `ALTER TABLE processed_callbacks ADD COLUMN claim_id TEXT`); } catch { /* already exists */ }
792
-
793
- // Unique constraint: at most one non-null provider_call_sid per (provider, provider_call_sid).
794
- // On upgraded databases that pre-date this constraint, duplicate rows may exist; deduplicate
795
- // them first to avoid a UNIQUE constraint failure that would prevent startup.
796
- migrateCallSessionsProviderSidDedup(database);
797
- database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_call_sessions_provider_sid_unique ON call_sessions(provider, provider_call_sid) WHERE provider_call_sid IS NOT NULL`);
798
-
799
- // ── Follow-ups ─────────────────────────────────────────────────────
800
-
801
- database.run(/*sql*/ `
802
- CREATE TABLE IF NOT EXISTS followups (
803
- id TEXT PRIMARY KEY,
804
- channel TEXT NOT NULL,
805
- thread_id TEXT NOT NULL,
806
- contact_id TEXT REFERENCES contacts(id) ON DELETE SET NULL,
807
- sent_at INTEGER NOT NULL,
808
- expected_response_by INTEGER,
809
- status TEXT NOT NULL DEFAULT 'pending',
810
- reminder_cron_id TEXT,
811
- created_at INTEGER NOT NULL,
812
- updated_at INTEGER NOT NULL
813
- )
814
- `);
815
-
816
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_followups_status ON followups(status)`);
817
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_followups_channel ON followups(channel)`);
818
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_followups_contact_id ON followups(contact_id)`);
819
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_followups_channel_thread ON followups(channel, thread_id)`);
820
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_followups_status_expected ON followups(status, expected_response_by)`);
821
-
822
- // ── Tasks ─────────────────────────────────────────────────────────
823
-
824
- database.run(/*sql*/ `
825
- CREATE TABLE IF NOT EXISTS tasks (
826
- id TEXT PRIMARY KEY,
827
- title TEXT NOT NULL,
828
- template TEXT NOT NULL,
829
- input_schema TEXT,
830
- context_flags TEXT,
831
- required_tools TEXT,
832
- created_from_conversation_id TEXT,
833
- status TEXT NOT NULL DEFAULT 'active',
834
- created_at INTEGER NOT NULL,
835
- updated_at INTEGER NOT NULL
836
- )
837
- `);
838
-
839
- database.run(/*sql*/ `
840
- CREATE TABLE IF NOT EXISTS task_runs (
841
- id TEXT PRIMARY KEY,
842
- task_id TEXT NOT NULL REFERENCES tasks(id),
843
- conversation_id TEXT,
844
- status TEXT NOT NULL DEFAULT 'pending',
845
- started_at INTEGER,
846
- finished_at INTEGER,
847
- error TEXT,
848
- principal_id TEXT,
849
- memory_scope_id TEXT,
850
- created_at INTEGER NOT NULL
851
- )
852
- `);
853
-
854
- database.run(/*sql*/ `
855
- CREATE TABLE IF NOT EXISTS task_candidates (
856
- id TEXT PRIMARY KEY,
857
- source_conversation_id TEXT NOT NULL,
858
- compiled_template TEXT NOT NULL,
859
- confidence REAL,
860
- required_tools TEXT,
861
- created_at INTEGER NOT NULL,
862
- promoted_task_id TEXT
863
- )
864
- `);
865
-
866
- // ── Work Items (Tasks) ──────────────────────────────────────────────
867
-
868
- database.run(/*sql*/ `
869
- CREATE TABLE IF NOT EXISTS work_items (
870
- id TEXT PRIMARY KEY,
871
- task_id TEXT NOT NULL REFERENCES tasks(id),
872
- title TEXT NOT NULL,
873
- notes TEXT,
874
- status TEXT NOT NULL DEFAULT 'queued',
875
- priority_tier INTEGER NOT NULL DEFAULT 1,
876
- sort_index INTEGER,
877
- last_run_id TEXT,
878
- last_run_conversation_id TEXT,
879
- last_run_status TEXT,
880
- source_type TEXT,
881
- source_id TEXT,
882
- created_at INTEGER NOT NULL,
883
- updated_at INTEGER NOT NULL
884
- )
885
- `);
886
-
887
- // Work item run contract snapshot
888
- try { database.run(/*sql*/ `ALTER TABLE work_items ADD COLUMN required_tools TEXT`); } catch (e) { log.debug({ err: e }, 'ALTER TABLE work_items ADD COLUMN required_tools (likely already exists)'); }
889
-
890
- // Work item permission preflight columns
891
- try { database.run(/*sql*/ `ALTER TABLE work_items ADD COLUMN approved_tools TEXT`); } catch (e) { log.debug({ err: e }, 'ALTER TABLE work_items ADD COLUMN approved_tools (likely already exists)'); }
892
- try { database.run(/*sql*/ `ALTER TABLE work_items ADD COLUMN approval_status TEXT DEFAULT 'none'`); } catch (e) { log.debug({ err: e }, 'ALTER TABLE work_items ADD COLUMN approval_status (likely already exists)'); }
893
-
894
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_work_items_status ON work_items(status)`);
895
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_work_items_task_id ON work_items(task_id)`);
896
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_work_items_priority_sort ON work_items(priority_tier, sort_index)`);
897
-
898
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)`);
899
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_task_runs_task_id ON task_runs(task_id)`);
900
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_task_runs_status ON task_runs(status)`);
901
- database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_task_candidates_promoted ON task_candidates(promoted_task_id)`);
902
-
903
- migrateMemoryFtsBackfill(database);
904
- }
905
-
906
- /**
907
- * One-shot migration: reconcile old deferral history into the new `deferrals` column.
908
- *
909
- * Before the `deferrals` column was added, `deferMemoryJob` incremented `attempts`.
910
- * After the column is added with DEFAULT 0, those legacy jobs still carry the old
911
- * attempt count (which was really a deferral count) while `deferrals` is 0. This
912
- * moves the attempt count into `deferrals` and resets `attempts` to 0.
913
- *
914
- * This migration MUST run only once. On subsequent startups, post-migration jobs
915
- * that genuinely failed via `failMemoryJob` (attempts > 0, deferrals = 0, non-null
916
- * last_error) must NOT be touched — resetting their attempts would let them bypass
917
- * the configured maxAttempts budget across restarts.
918
- *
919
- * We use a `memory_checkpoints` row to ensure the migration runs exactly once.
920
- */
921
- function migrateJobDeferrals(database: ReturnType<typeof drizzle<typeof schema>>): void {
922
- const raw = (database as unknown as { $client: Database }).$client;
923
- const checkpoint = raw.query(
924
- `SELECT 1 FROM memory_checkpoints WHERE key = 'migration_job_deferrals'`
925
- ).get();
926
- if (checkpoint) return;
927
-
928
- try {
929
- raw.exec(/*sql*/ `
930
- BEGIN;
931
- UPDATE memory_jobs
932
- SET deferrals = attempts,
933
- attempts = 0,
934
- last_error = NULL,
935
- updated_at = ${Date.now()}
936
- WHERE status = 'pending'
937
- AND attempts > 0
938
- AND deferrals = 0
939
- AND type IN ('embed_segment', 'embed_item', 'embed_summary');
940
- INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at)
941
- VALUES ('migration_job_deferrals', '1', ${Date.now()});
942
- COMMIT;
943
- `);
944
- } catch (e) {
945
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
946
- throw e;
947
- }
948
- }
949
-
950
- /**
951
- * Migrate existing tool_invocations table to add FK constraint with ON DELETE CASCADE.
952
- * SQLite doesn't support ALTER TABLE ADD CONSTRAINT, so we rebuild the table.
953
- * This is idempotent: it checks whether the FK already exists before migrating.
954
- */
955
- function migrateToolInvocationsFk(database: ReturnType<typeof drizzle<typeof schema>>): void {
956
- const raw = (database as unknown as { $client: Database }).$client;
957
- const row = raw.query(`SELECT sql FROM sqlite_master WHERE type='table' AND name='tool_invocations'`).get() as { sql: string } | null;
958
- if (!row) return; // table doesn't exist yet (will be created above)
959
-
960
- // If the DDL already contains REFERENCES, the FK is in place
961
- if (row.sql.includes('REFERENCES')) return;
962
-
963
- raw.exec('PRAGMA foreign_keys = OFF');
964
- try {
965
- raw.exec(/*sql*/ `
966
- BEGIN;
967
- CREATE TABLE tool_invocations_new (
968
- id TEXT PRIMARY KEY,
969
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
970
- tool_name TEXT NOT NULL,
971
- input TEXT NOT NULL,
972
- result TEXT NOT NULL,
973
- decision TEXT NOT NULL,
974
- risk_level TEXT NOT NULL,
975
- duration_ms INTEGER NOT NULL,
976
- created_at INTEGER NOT NULL
977
- );
978
- INSERT INTO tool_invocations_new SELECT t.* FROM tool_invocations t
979
- WHERE EXISTS (SELECT 1 FROM conversations c WHERE c.id = t.conversation_id);
980
- DROP TABLE tool_invocations;
981
- ALTER TABLE tool_invocations_new RENAME TO tool_invocations;
982
- COMMIT;
983
- `);
984
- } catch (e) {
985
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
986
- throw e;
987
- } finally {
988
- raw.exec('PRAGMA foreign_keys = ON');
989
- }
990
- }
991
-
992
- /**
993
- * Backfill FTS rows for existing memory_segments records when upgrading from a
994
- * version that may not have had trigger-managed FTS.
995
- */
996
- function migrateMemoryFtsBackfill(database: ReturnType<typeof drizzle<typeof schema>>): void {
997
- const raw = (database as unknown as { $client: Database }).$client;
998
- const ftsCountRow = raw.query(`SELECT COUNT(*) AS c FROM memory_segment_fts`).get() as { c: number } | null;
999
- const ftsCount = ftsCountRow?.c ?? 0;
1000
- if (ftsCount > 0) return;
1001
-
1002
- raw.exec(/*sql*/ `
1003
- INSERT INTO memory_segment_fts(segment_id, text)
1004
- SELECT id, text FROM memory_segments
1005
- `);
1006
- }
1007
-
1008
- /**
1009
- * One-shot migration: merge duplicate relation edges so uniqueness can be
1010
- * enforced on (source_entity_id, target_entity_id, relation).
1011
- */
1012
- function migrateMemoryEntityRelationDedup(database: ReturnType<typeof drizzle<typeof schema>>): void {
1013
- const raw = (database as unknown as { $client: Database }).$client;
1014
- const checkpointKey = 'migration_memory_entity_relations_dedup_v1';
1015
- const checkpoint = raw.query(
1016
- `SELECT 1 FROM memory_checkpoints WHERE key = ?`,
1017
- ).get(checkpointKey);
1018
- if (checkpoint) return;
1019
-
1020
- try {
1021
- raw.exec('BEGIN');
1022
-
1023
- raw.exec(/*sql*/ `
1024
- CREATE TEMP TABLE memory_entity_relation_merge AS
1025
- WITH ranked AS (
1026
- SELECT
1027
- source_entity_id,
1028
- target_entity_id,
1029
- relation,
1030
- first_seen_at,
1031
- last_seen_at,
1032
- evidence,
1033
- ROW_NUMBER() OVER (
1034
- PARTITION BY source_entity_id, target_entity_id, relation
1035
- ORDER BY last_seen_at DESC, first_seen_at DESC, id DESC
1036
- ) AS rank_latest
1037
- FROM memory_entity_relations
1038
- )
1039
- SELECT
1040
- source_entity_id,
1041
- target_entity_id,
1042
- relation,
1043
- MIN(first_seen_at) AS merged_first_seen_at,
1044
- MAX(last_seen_at) AS merged_last_seen_at,
1045
- MAX(CASE WHEN rank_latest = 1 THEN evidence ELSE NULL END) AS merged_evidence
1046
- FROM ranked
1047
- GROUP BY source_entity_id, target_entity_id, relation
1048
- `);
1049
-
1050
- raw.exec(/*sql*/ `DELETE FROM memory_entity_relations`);
1051
-
1052
- raw.exec(/*sql*/ `
1053
- INSERT INTO memory_entity_relations (
1054
- id,
1055
- source_entity_id,
1056
- target_entity_id,
1057
- relation,
1058
- evidence,
1059
- first_seen_at,
1060
- last_seen_at
1061
- )
1062
- SELECT
1063
- lower(hex(randomblob(16))),
1064
- source_entity_id,
1065
- target_entity_id,
1066
- relation,
1067
- merged_evidence,
1068
- merged_first_seen_at,
1069
- merged_last_seen_at
1070
- FROM memory_entity_relation_merge
1071
- `);
1072
-
1073
- raw.exec(/*sql*/ `DROP TABLE memory_entity_relation_merge`);
1074
-
1075
- raw.query(
1076
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1077
- ).run(checkpointKey, Date.now());
1078
-
1079
- raw.exec('COMMIT');
1080
- } catch (e) {
1081
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
1082
- throw e;
1083
- }
1084
- }
1085
-
1086
- /**
1087
- * Migrate from a column-level UNIQUE on fingerprint to a compound unique
1088
- * index on (fingerprint, scope_id) so that the same item can exist in
1089
- * different scopes independently.
1090
- */
1091
- function migrateMemoryItemsFingerprintScopeUnique(database: ReturnType<typeof drizzle<typeof schema>>): void {
1092
- const raw = (database as unknown as { $client: Database }).$client;
1093
- const checkpointKey = 'migration_memory_items_fingerprint_scope_unique_v1';
1094
- const checkpoint = raw.query(
1095
- `SELECT 1 FROM memory_checkpoints WHERE key = ?`,
1096
- ).get(checkpointKey);
1097
- if (checkpoint) return;
1098
-
1099
- // Check if the old column-level UNIQUE constraint still exists by inspecting
1100
- // the CREATE TABLE DDL for the word UNIQUE (the PK also creates an autoindex,
1101
- // so we cannot rely on sqlite_autoindex_* presence alone).
1102
- const tableDdl = raw.query(
1103
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'memory_items'`,
1104
- ).get() as { sql: string } | null;
1105
- if (!tableDdl || !tableDdl.sql.match(/fingerprint\s+TEXT\s+NOT\s+NULL\s+UNIQUE/i)) {
1106
- // No column-level UNIQUE on fingerprint — either fresh DB or already migrated.
1107
- raw.query(
1108
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1109
- ).run(checkpointKey, Date.now());
1110
- return;
1111
- }
1112
-
1113
- // Rebuild the table without the column-level UNIQUE constraint.
1114
- raw.exec('PRAGMA foreign_keys = OFF');
1115
- try {
1116
- raw.exec('BEGIN');
1117
-
1118
- // Create new table without UNIQUE on fingerprint — all other columns
1119
- // match the latest schema (including migration-added columns).
1120
- raw.exec(/*sql*/ `
1121
- CREATE TABLE memory_items_new (
1122
- id TEXT PRIMARY KEY,
1123
- kind TEXT NOT NULL,
1124
- subject TEXT NOT NULL,
1125
- statement TEXT NOT NULL,
1126
- status TEXT NOT NULL,
1127
- confidence REAL NOT NULL,
1128
- fingerprint TEXT NOT NULL,
1129
- first_seen_at INTEGER NOT NULL,
1130
- last_seen_at INTEGER NOT NULL,
1131
- last_used_at INTEGER,
1132
- importance REAL,
1133
- access_count INTEGER NOT NULL DEFAULT 0,
1134
- valid_from INTEGER,
1135
- invalid_at INTEGER,
1136
- verification_state TEXT NOT NULL DEFAULT 'assistant_inferred',
1137
- scope_id TEXT NOT NULL DEFAULT 'default'
1138
- )
1139
- `);
1140
-
1141
- raw.exec(/*sql*/ `
1142
- INSERT INTO memory_items_new
1143
- SELECT id, kind, subject, statement, status, confidence, fingerprint,
1144
- first_seen_at, last_seen_at, last_used_at, importance, access_count,
1145
- valid_from, invalid_at, verification_state, scope_id
1146
- FROM memory_items
1147
- `);
1148
-
1149
- raw.exec(/*sql*/ `DROP TABLE memory_items`);
1150
- raw.exec(/*sql*/ `ALTER TABLE memory_items_new RENAME TO memory_items`);
1151
-
1152
- raw.query(
1153
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1154
- ).run(checkpointKey, Date.now());
1155
-
1156
- raw.exec('COMMIT');
1157
- } catch (e) {
1158
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
1159
- throw e;
1160
- } finally {
1161
- raw.exec('PRAGMA foreign_keys = ON');
1162
- }
1163
- }
1164
-
1165
- /**
1166
- * One-shot migration: recompute fingerprints for existing memory items to
1167
- * include the scope_id prefix introduced in the scope-salted fingerprint PR.
1168
- *
1169
- * Old format: sha256(`${kind}|${subject.toLowerCase()}|${statement.toLowerCase()}`)
1170
- * New format: sha256(`${scopeId}|${kind}|${subject.toLowerCase()}|${statement.toLowerCase()}`)
1171
- *
1172
- * Without this migration, pre-upgrade items would never match on re-extraction,
1173
- * causing duplicates and broken deduplication.
1174
- */
1175
- function migrateMemoryItemsScopeSaltedFingerprints(database: ReturnType<typeof drizzle<typeof schema>>): void {
1176
- const raw = (database as unknown as { $client: Database }).$client;
1177
- const checkpointKey = 'migration_memory_items_scope_salted_fingerprints_v1';
1178
- const checkpoint = raw.query(
1179
- `SELECT 1 FROM memory_checkpoints WHERE key = ?`,
1180
- ).get(checkpointKey);
1181
- if (checkpoint) return;
1182
-
1183
- interface ItemRow {
1184
- id: string;
1185
- kind: string;
1186
- subject: string;
1187
- statement: string;
1188
- scope_id: string;
1189
- }
1190
-
1191
- const items = raw.query(
1192
- `SELECT id, kind, subject, statement, scope_id FROM memory_items`,
1193
- ).all() as ItemRow[];
1194
-
1195
- if (items.length === 0) {
1196
- raw.query(
1197
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1198
- ).run(checkpointKey, Date.now());
1199
- return;
1200
- }
1201
-
1202
- try {
1203
- raw.exec('BEGIN');
1204
-
1205
- const updateStmt = raw.prepare(
1206
- `UPDATE memory_items SET fingerprint = ? WHERE id = ?`,
1207
- );
1208
-
1209
- for (const item of items) {
1210
- const fingerprint = computeMemoryFingerprint(item.scope_id, item.kind, item.subject, item.statement);
1211
- updateStmt.run(fingerprint, item.id);
1212
- }
1213
-
1214
- raw.query(
1215
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1216
- ).run(checkpointKey, Date.now());
1217
-
1218
- raw.exec('COMMIT');
1219
- } catch (e) {
1220
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
1221
- throw e;
1222
- }
1223
- }
1224
-
1225
- /**
1226
- * One-shot migration: normalize all assistant_id values in assistant-scoped tables
1227
- * to "self" so they are visible after the daemon switched to the implicit single-tenant
1228
- * identity.
1229
- *
1230
- * Before this change, rows were keyed by the real assistantId string passed via the
1231
- * HTTP route. After the route change, all lookups use the constant "self". Without this
1232
- * migration an upgraded daemon would see empty history / attachment lists for existing
1233
- * data that was stored under the old assistantId.
1234
- *
1235
- * Affected tables:
1236
- * - conversation_keys UNIQUE (assistant_id, conversation_key)
1237
- * - attachments UNIQUE (assistant_id, content_hash) WHERE content_hash IS NOT NULL
1238
- * - channel_inbound_events UNIQUE (assistant_id, source_channel, external_chat_id, external_message_id)
1239
- * - message_runs no unique constraint on assistant_id
1240
- *
1241
- * Data-safety guarantees:
1242
- * - conversation_keys: when a key exists under both 'self' and a real assistantId, the
1243
- * 'self' row is updated to point to the real-assistantId conversation (which holds the
1244
- * historical message thread). The 'self' conversation may be orphaned but is not deleted.
1245
- * - attachments: message_attachments links are remapped to the surviving attachment before
1246
- * any duplicate row is deleted, so no message loses its attachment metadata.
1247
- * - channel_inbound_events: only delivery-tracking metadata, not user content; dedup
1248
- * keeps one row per unique (channel, chat, message) tuple.
1249
- * - All conversations and messages remain untouched — only assistant_id index columns
1250
- * and key-lookup rows are modified.
1251
- */
1252
- function migrateAssistantIdToSelf(database: ReturnType<typeof drizzle<typeof schema>>): void {
1253
- const raw = (database as unknown as { $client: Database }).$client;
1254
- const checkpointKey = 'migration_normalize_assistant_id_to_self_v1';
1255
- const checkpoint = raw.query(
1256
- `SELECT 1 FROM memory_checkpoints WHERE key = ?`,
1257
- ).get(checkpointKey);
1258
- if (checkpoint) return;
1259
-
1260
- // On fresh installs the tables are created without assistant_id (PR 7+). Skip the
1261
- // migration if NONE of the four affected tables have the column — pre-seed the
1262
- // checkpoint so subsequent startups are also skipped. Checking all four (not just
1263
- // conversation_keys) avoids a false negative on very old installs where
1264
- // conversation_keys may not exist yet but other tables still carry assistant_id data.
1265
- const affectedTables = ['conversation_keys', 'attachments', 'channel_inbound_events', 'message_runs'];
1266
- const anyHasAssistantId = affectedTables.some((tbl) => {
1267
- const ddl = raw.query(
1268
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?`,
1269
- ).get(tbl) as { sql: string } | null;
1270
- return ddl?.sql.includes('assistant_id') ?? false;
1271
- });
1272
- if (!anyHasAssistantId) {
1273
- raw.query(
1274
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1275
- ).run(checkpointKey, Date.now());
1276
- return;
1277
- }
1278
-
1279
- // Helper: returns true if the given table's current DDL contains 'assistant_id'.
1280
- const tableHasAssistantId = (tbl: string): boolean => {
1281
- const ddl = raw.query(
1282
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?`,
1283
- ).get(tbl) as { sql: string } | null;
1284
- return ddl?.sql.includes('assistant_id') ?? false;
1285
- };
1286
-
1287
- try {
1288
- raw.exec('BEGIN');
1289
-
1290
- // Each section is guarded so that SQL referencing assistant_id is only executed
1291
- // when the column still exists in that table. This handles mixed-schema states
1292
- // (e.g., very old installs where some tables may already lack the column).
1293
-
1294
- // conversation_keys: UNIQUE (assistant_id, conversation_key)
1295
- if (tableHasAssistantId('conversation_keys')) {
1296
- // Step 1: Among non-self rows, keep only one per conversation_key so the
1297
- // bulk UPDATE cannot hit a (non-self-A, key) + (non-self-B, key) collision.
1298
- raw.exec(/*sql*/ `
1299
- DELETE FROM conversation_keys
1300
- WHERE assistant_id != 'self'
1301
- AND rowid NOT IN (
1302
- SELECT MIN(rowid) FROM conversation_keys
1303
- WHERE assistant_id != 'self'
1304
- GROUP BY conversation_key
1305
- )
1306
- `);
1307
- // Step 2: For 'self' rows that have a non-self counterpart with the same
1308
- // conversation_key, update the 'self' row to use the non-self row's
1309
- // conversation_id. This preserves the historical conversation (which
1310
- // has the message history from before the route change) rather than
1311
- // discarding it in favour of a potentially-empty 'self' conversation.
1312
- raw.exec(/*sql*/ `
1313
- UPDATE conversation_keys
1314
- SET conversation_id = (
1315
- SELECT ck_ns.conversation_id
1316
- FROM conversation_keys ck_ns
1317
- WHERE ck_ns.assistant_id != 'self'
1318
- AND ck_ns.conversation_key = conversation_keys.conversation_key
1319
- ORDER BY ck_ns.rowid
1320
- LIMIT 1
1321
- )
1322
- WHERE assistant_id = 'self'
1323
- AND EXISTS (
1324
- SELECT 1 FROM conversation_keys ck_ns
1325
- WHERE ck_ns.assistant_id != 'self'
1326
- AND ck_ns.conversation_key = conversation_keys.conversation_key
1327
- )
1328
- `);
1329
- // Step 3: Delete the now-redundant non-self rows (their conversation_ids
1330
- // have been preserved in the 'self' rows above).
1331
- raw.exec(/*sql*/ `
1332
- DELETE FROM conversation_keys
1333
- WHERE assistant_id != 'self'
1334
- AND EXISTS (
1335
- SELECT 1 FROM conversation_keys ck2
1336
- WHERE ck2.assistant_id = 'self'
1337
- AND ck2.conversation_key = conversation_keys.conversation_key
1338
- )
1339
- `);
1340
- // Step 4: Remaining non-self rows have no 'self' counterpart — safe to bulk-update.
1341
- raw.exec(/*sql*/ `
1342
- UPDATE conversation_keys SET assistant_id = 'self' WHERE assistant_id != 'self'
1343
- `);
1344
- }
1345
-
1346
- // attachments: UNIQUE (assistant_id, content_hash) WHERE content_hash IS NOT NULL
1347
- //
1348
- // message_attachments rows reference attachment IDs with ON DELETE CASCADE, so we
1349
- // must remap links to the surviving row BEFORE deleting duplicates to avoid
1350
- // silently dropping attachment metadata from messages.
1351
- if (tableHasAssistantId('attachments')) {
1352
- // Step 1: Remap message_attachments from non-self duplicates to their survivor
1353
- // (MIN rowid per content_hash group), then delete the duplicates.
1354
- raw.exec(/*sql*/ `
1355
- UPDATE message_attachments
1356
- SET attachment_id = (
1357
- SELECT a_survivor.id
1358
- FROM attachments a_survivor
1359
- WHERE a_survivor.assistant_id != 'self'
1360
- AND a_survivor.content_hash = (
1361
- SELECT a_dup.content_hash FROM attachments a_dup
1362
- WHERE a_dup.id = message_attachments.attachment_id
1363
- )
1364
- ORDER BY a_survivor.rowid
1365
- LIMIT 1
1366
- )
1367
- WHERE attachment_id IN (
1368
- SELECT id FROM attachments
1369
- WHERE assistant_id != 'self'
1370
- AND content_hash IS NOT NULL
1371
- AND rowid NOT IN (
1372
- SELECT MIN(rowid) FROM attachments
1373
- WHERE assistant_id != 'self' AND content_hash IS NOT NULL
1374
- GROUP BY content_hash
1375
- )
1376
- )
1377
- `);
1378
- raw.exec(/*sql*/ `
1379
- DELETE FROM attachments
1380
- WHERE assistant_id != 'self'
1381
- AND content_hash IS NOT NULL
1382
- AND rowid NOT IN (
1383
- SELECT MIN(rowid) FROM attachments
1384
- WHERE assistant_id != 'self'
1385
- AND content_hash IS NOT NULL
1386
- GROUP BY content_hash
1387
- )
1388
- `);
1389
- // Step 2: Remap message_attachments from non-self rows conflicting with a 'self'
1390
- // row to the 'self' row, then delete the now-unlinked non-self rows.
1391
- raw.exec(/*sql*/ `
1392
- UPDATE message_attachments
1393
- SET attachment_id = (
1394
- SELECT a_self.id
1395
- FROM attachments a_self
1396
- WHERE a_self.assistant_id = 'self'
1397
- AND a_self.content_hash = (
1398
- SELECT a_ns.content_hash FROM attachments a_ns
1399
- WHERE a_ns.id = message_attachments.attachment_id
1400
- )
1401
- LIMIT 1
1402
- )
1403
- WHERE attachment_id IN (
1404
- SELECT id FROM attachments
1405
- WHERE assistant_id != 'self'
1406
- AND content_hash IS NOT NULL
1407
- AND EXISTS (
1408
- SELECT 1 FROM attachments a2
1409
- WHERE a2.assistant_id = 'self'
1410
- AND a2.content_hash = attachments.content_hash
1411
- )
1412
- )
1413
- `);
1414
- raw.exec(/*sql*/ `
1415
- DELETE FROM attachments
1416
- WHERE assistant_id != 'self'
1417
- AND content_hash IS NOT NULL
1418
- AND EXISTS (
1419
- SELECT 1 FROM attachments a2
1420
- WHERE a2.assistant_id = 'self'
1421
- AND a2.content_hash = attachments.content_hash
1422
- )
1423
- `);
1424
- // Step 3: Bulk-update remaining non-self rows.
1425
- raw.exec(/*sql*/ `
1426
- UPDATE attachments SET assistant_id = 'self' WHERE assistant_id != 'self'
1427
- `);
1428
- }
1429
-
1430
- // channel_inbound_events: UNIQUE (assistant_id, source_channel, external_chat_id, external_message_id)
1431
- if (tableHasAssistantId('channel_inbound_events')) {
1432
- // Step 1: Dedup non-self rows sharing the same (source_channel, external_chat_id, external_message_id).
1433
- raw.exec(/*sql*/ `
1434
- DELETE FROM channel_inbound_events
1435
- WHERE assistant_id != 'self'
1436
- AND rowid NOT IN (
1437
- SELECT MIN(rowid) FROM channel_inbound_events
1438
- WHERE assistant_id != 'self'
1439
- GROUP BY source_channel, external_chat_id, external_message_id
1440
- )
1441
- `);
1442
- // Step 2: Delete non-self rows conflicting with existing 'self' rows.
1443
- raw.exec(/*sql*/ `
1444
- DELETE FROM channel_inbound_events
1445
- WHERE assistant_id != 'self'
1446
- AND EXISTS (
1447
- SELECT 1 FROM channel_inbound_events e2
1448
- WHERE e2.assistant_id = 'self'
1449
- AND e2.source_channel = channel_inbound_events.source_channel
1450
- AND e2.external_chat_id = channel_inbound_events.external_chat_id
1451
- AND e2.external_message_id = channel_inbound_events.external_message_id
1452
- )
1453
- `);
1454
- // Step 3: Bulk-update remaining non-self rows.
1455
- raw.exec(/*sql*/ `
1456
- UPDATE channel_inbound_events SET assistant_id = 'self' WHERE assistant_id != 'self'
1457
- `);
1458
- }
1459
-
1460
- // message_runs: no unique constraint on assistant_id — simple bulk update
1461
- if (tableHasAssistantId('message_runs')) {
1462
- raw.exec(/*sql*/ `
1463
- UPDATE message_runs SET assistant_id = 'self' WHERE assistant_id != 'self'
1464
- `);
1465
- }
1466
-
1467
- raw.query(
1468
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1469
- ).run(checkpointKey, Date.now());
1470
-
1471
- raw.exec('COMMIT');
1472
- } catch (e) {
1473
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
1474
- throw e;
1475
- }
1476
- }
1477
-
1478
- /**
1479
- * One-shot migration: rebuild tables that previously stored assistant_id to remove
1480
- * that column now that all rows are keyed to the implicit single-tenant identity ("self").
1481
- *
1482
- * Must run AFTER migrateAssistantIdToSelf (which normalises all values to "self")
1483
- * so there are no constraint violations when recreating the tables without the
1484
- * assistant_id dimension.
1485
- *
1486
- * Each table section is guarded by a DDL check so this is safe on fresh installs
1487
- * where the column was never created in the first place.
1488
- *
1489
- * Tables rebuilt:
1490
- * - conversation_keys UNIQUE (conversation_key)
1491
- * - attachments no structural unique; content-dedup index updated
1492
- * - channel_inbound_events UNIQUE (source_channel, external_chat_id, external_message_id)
1493
- * - message_runs no unique constraint on assistant_id
1494
- * - llm_usage_events nullable column with no constraint
1495
- */
1496
- function migrateRemoveAssistantIdColumns(database: ReturnType<typeof drizzle<typeof schema>>): void {
1497
- const raw = (database as unknown as { $client: Database }).$client;
1498
- const checkpointKey = 'migration_remove_assistant_id_columns_v1';
1499
- const checkpoint = raw.query(
1500
- `SELECT 1 FROM memory_checkpoints WHERE key = ?`,
1501
- ).get(checkpointKey);
1502
- if (checkpoint) return;
1503
-
1504
- raw.exec('PRAGMA foreign_keys = OFF');
1505
- try {
1506
- raw.exec('BEGIN');
1507
-
1508
- // --- conversation_keys ---
1509
- const ckDdl = raw.query(
1510
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'conversation_keys'`,
1511
- ).get() as { sql: string } | null;
1512
- if (ckDdl?.sql.includes('assistant_id')) {
1513
- raw.exec(/*sql*/ `
1514
- CREATE TABLE conversation_keys_new (
1515
- id TEXT PRIMARY KEY,
1516
- conversation_key TEXT NOT NULL UNIQUE,
1517
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
1518
- created_at INTEGER NOT NULL
1519
- )
1520
- `);
1521
- raw.exec(/*sql*/ `
1522
- INSERT INTO conversation_keys_new (id, conversation_key, conversation_id, created_at)
1523
- SELECT id, conversation_key, conversation_id, created_at FROM conversation_keys
1524
- `);
1525
- raw.exec(/*sql*/ `DROP TABLE conversation_keys`);
1526
- raw.exec(/*sql*/ `ALTER TABLE conversation_keys_new RENAME TO conversation_keys`);
1527
- }
1528
-
1529
- // --- attachments ---
1530
- const attDdl = raw.query(
1531
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'attachments'`,
1532
- ).get() as { sql: string } | null;
1533
- if (attDdl?.sql.includes('assistant_id')) {
1534
- raw.exec(/*sql*/ `
1535
- CREATE TABLE attachments_new (
1536
- id TEXT PRIMARY KEY,
1537
- original_filename TEXT NOT NULL,
1538
- mime_type TEXT NOT NULL,
1539
- size_bytes INTEGER NOT NULL,
1540
- kind TEXT NOT NULL,
1541
- data_base64 TEXT NOT NULL,
1542
- content_hash TEXT,
1543
- thumbnail_base64 TEXT,
1544
- created_at INTEGER NOT NULL
1545
- )
1546
- `);
1547
- raw.exec(/*sql*/ `
1548
- INSERT INTO attachments_new (id, original_filename, mime_type, size_bytes, kind, data_base64, content_hash, thumbnail_base64, created_at)
1549
- SELECT id, original_filename, mime_type, size_bytes, kind, data_base64, content_hash, thumbnail_base64, created_at FROM attachments
1550
- `);
1551
- raw.exec(/*sql*/ `DROP TABLE attachments`);
1552
- raw.exec(/*sql*/ `ALTER TABLE attachments_new RENAME TO attachments`);
1553
- }
1554
-
1555
- // --- channel_inbound_events ---
1556
- const cieDdl = raw.query(
1557
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'channel_inbound_events'`,
1558
- ).get() as { sql: string } | null;
1559
- if (cieDdl?.sql.includes('assistant_id')) {
1560
- raw.exec(/*sql*/ `
1561
- CREATE TABLE channel_inbound_events_new (
1562
- id TEXT PRIMARY KEY,
1563
- source_channel TEXT NOT NULL,
1564
- external_chat_id TEXT NOT NULL,
1565
- external_message_id TEXT NOT NULL,
1566
- source_message_id TEXT,
1567
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
1568
- message_id TEXT REFERENCES messages(id) ON DELETE CASCADE,
1569
- delivery_status TEXT NOT NULL DEFAULT 'pending',
1570
- processing_status TEXT NOT NULL DEFAULT 'pending',
1571
- processing_attempts INTEGER NOT NULL DEFAULT 0,
1572
- last_processing_error TEXT,
1573
- retry_after INTEGER,
1574
- raw_payload TEXT,
1575
- created_at INTEGER NOT NULL,
1576
- updated_at INTEGER NOT NULL,
1577
- UNIQUE (source_channel, external_chat_id, external_message_id)
1578
- )
1579
- `);
1580
- raw.exec(/*sql*/ `
1581
- INSERT INTO channel_inbound_events_new (
1582
- id, source_channel, external_chat_id, external_message_id, source_message_id,
1583
- conversation_id, message_id, delivery_status, processing_status,
1584
- processing_attempts, last_processing_error, retry_after, raw_payload,
1585
- created_at, updated_at
1586
- )
1587
- SELECT
1588
- id, source_channel, external_chat_id, external_message_id, source_message_id,
1589
- conversation_id, message_id, delivery_status, processing_status,
1590
- processing_attempts, last_processing_error, retry_after, raw_payload,
1591
- created_at, updated_at
1592
- FROM channel_inbound_events
1593
- `);
1594
- raw.exec(/*sql*/ `DROP TABLE channel_inbound_events`);
1595
- raw.exec(/*sql*/ `ALTER TABLE channel_inbound_events_new RENAME TO channel_inbound_events`);
1596
- }
1597
-
1598
- // --- message_runs ---
1599
- const mrDdl = raw.query(
1600
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'message_runs'`,
1601
- ).get() as { sql: string } | null;
1602
- if (mrDdl?.sql.includes('assistant_id')) {
1603
- raw.exec(/*sql*/ `
1604
- CREATE TABLE message_runs_new (
1605
- id TEXT PRIMARY KEY,
1606
- conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
1607
- message_id TEXT REFERENCES messages(id) ON DELETE CASCADE,
1608
- status TEXT NOT NULL DEFAULT 'running',
1609
- pending_confirmation TEXT,
1610
- input_tokens INTEGER NOT NULL DEFAULT 0,
1611
- output_tokens INTEGER NOT NULL DEFAULT 0,
1612
- estimated_cost REAL NOT NULL DEFAULT 0,
1613
- error TEXT,
1614
- created_at INTEGER NOT NULL,
1615
- updated_at INTEGER NOT NULL
1616
- )
1617
- `);
1618
- raw.exec(/*sql*/ `
1619
- INSERT INTO message_runs_new (
1620
- id, conversation_id, message_id, status, pending_confirmation,
1621
- input_tokens, output_tokens, estimated_cost, error, created_at, updated_at
1622
- )
1623
- SELECT
1624
- id, conversation_id, message_id, status, pending_confirmation,
1625
- input_tokens, output_tokens, estimated_cost, error, created_at, updated_at
1626
- FROM message_runs
1627
- `);
1628
- raw.exec(/*sql*/ `DROP TABLE message_runs`);
1629
- raw.exec(/*sql*/ `ALTER TABLE message_runs_new RENAME TO message_runs`);
1630
- }
1631
-
1632
- // --- llm_usage_events ---
1633
- const lueDdl = raw.query(
1634
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'llm_usage_events'`,
1635
- ).get() as { sql: string } | null;
1636
- if (lueDdl?.sql.includes('assistant_id')) {
1637
- raw.exec(/*sql*/ `
1638
- CREATE TABLE llm_usage_events_new (
1639
- id TEXT PRIMARY KEY,
1640
- created_at INTEGER NOT NULL,
1641
- conversation_id TEXT,
1642
- run_id TEXT,
1643
- request_id TEXT,
1644
- actor TEXT NOT NULL,
1645
- provider TEXT NOT NULL,
1646
- model TEXT NOT NULL,
1647
- input_tokens INTEGER NOT NULL,
1648
- output_tokens INTEGER NOT NULL,
1649
- cache_creation_input_tokens INTEGER,
1650
- cache_read_input_tokens INTEGER,
1651
- estimated_cost_usd REAL,
1652
- pricing_status TEXT NOT NULL,
1653
- metadata_json TEXT
1654
- )
1655
- `);
1656
- raw.exec(/*sql*/ `
1657
- INSERT INTO llm_usage_events_new (
1658
- id, created_at, conversation_id, run_id, request_id, actor, provider, model,
1659
- input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens,
1660
- estimated_cost_usd, pricing_status, metadata_json
1661
- )
1662
- SELECT
1663
- id, created_at, conversation_id, run_id, request_id, actor, provider, model,
1664
- input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens,
1665
- estimated_cost_usd, pricing_status, metadata_json
1666
- FROM llm_usage_events
1667
- `);
1668
- raw.exec(/*sql*/ `DROP TABLE llm_usage_events`);
1669
- raw.exec(/*sql*/ `ALTER TABLE llm_usage_events_new RENAME TO llm_usage_events`);
1670
- }
1671
-
1672
- raw.query(
1673
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1674
- ).run(checkpointKey, Date.now());
1675
-
1676
- raw.exec('COMMIT');
1677
- } catch (e) {
1678
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
1679
- throw e;
1680
- } finally {
1681
- raw.exec('PRAGMA foreign_keys = ON');
1682
- }
1683
- }
1684
-
1685
- /**
1686
- * One-shot migration: rebuild llm_usage_events to drop the assistant_id column.
1687
- *
1688
- * This is a SEPARATE migration from migrateRemoveAssistantIdColumns so that installs
1689
- * where the 4-table version of that migration already ran (checkpoint already set)
1690
- * still get the llm_usage_events column removed. Without a separate checkpoint key,
1691
- * those installs would skip the llm_usage_events rebuild entirely.
1692
- *
1693
- * Safe on fresh installs (DDL guard exits early) and idempotent via checkpoint.
1694
- */
1695
- function migrateLlmUsageEventsDropAssistantId(database: ReturnType<typeof drizzle<typeof schema>>): void {
1696
- const raw = (database as unknown as { $client: Database }).$client;
1697
- const checkpointKey = 'migration_remove_assistant_id_lue_v1';
1698
- const checkpoint = raw.query(
1699
- `SELECT 1 FROM memory_checkpoints WHERE key = ?`,
1700
- ).get(checkpointKey);
1701
- if (checkpoint) return;
1702
-
1703
- // DDL guard: if the column was already removed (fresh install or migrateRemoveAssistantIdColumns
1704
- // ran with the llm_usage_events block), just record the checkpoint and exit.
1705
- const lueDdl = raw.query(
1706
- `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'llm_usage_events'`,
1707
- ).get() as { sql: string } | null;
1708
-
1709
- if (!lueDdl?.sql.includes('assistant_id')) {
1710
- raw.query(
1711
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1712
- ).run(checkpointKey, Date.now());
1713
- return;
1714
- }
1715
-
1716
- raw.exec('PRAGMA foreign_keys = OFF');
1717
- try {
1718
- raw.exec('BEGIN');
1719
-
1720
- raw.exec(/*sql*/ `
1721
- CREATE TABLE llm_usage_events_new (
1722
- id TEXT PRIMARY KEY,
1723
- created_at INTEGER NOT NULL,
1724
- conversation_id TEXT,
1725
- run_id TEXT,
1726
- request_id TEXT,
1727
- actor TEXT NOT NULL,
1728
- provider TEXT NOT NULL,
1729
- model TEXT NOT NULL,
1730
- input_tokens INTEGER NOT NULL,
1731
- output_tokens INTEGER NOT NULL,
1732
- cache_creation_input_tokens INTEGER,
1733
- cache_read_input_tokens INTEGER,
1734
- estimated_cost_usd REAL,
1735
- pricing_status TEXT NOT NULL,
1736
- metadata_json TEXT
1737
- )
1738
- `);
1739
- raw.exec(/*sql*/ `
1740
- INSERT INTO llm_usage_events_new (
1741
- id, created_at, conversation_id, run_id, request_id, actor, provider, model,
1742
- input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens,
1743
- estimated_cost_usd, pricing_status, metadata_json
1744
- )
1745
- SELECT
1746
- id, created_at, conversation_id, run_id, request_id, actor, provider, model,
1747
- input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens,
1748
- estimated_cost_usd, pricing_status, metadata_json
1749
- FROM llm_usage_events
1750
- `);
1751
- raw.exec(/*sql*/ `DROP TABLE llm_usage_events`);
1752
- raw.exec(/*sql*/ `ALTER TABLE llm_usage_events_new RENAME TO llm_usage_events`);
1753
-
1754
- raw.query(
1755
- `INSERT OR IGNORE INTO memory_checkpoints (key, value, updated_at) VALUES (?, '1', ?)`,
1756
- ).run(checkpointKey, Date.now());
1757
-
1758
- raw.exec('COMMIT');
1759
- } catch (e) {
1760
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
1761
- throw e;
1762
- } finally {
1763
- raw.exec('PRAGMA foreign_keys = ON');
1764
- }
1765
- }
1766
-
1767
- /**
1768
- * One-shot migration: remove duplicate (provider, provider_call_sid) rows from
1769
- * call_sessions so that the unique index can be created safely on upgraded databases
1770
- * that pre-date the constraint.
1771
- *
1772
- * For each set of duplicates, the most recently updated row is kept.
1773
- */
1774
- function migrateCallSessionsProviderSidDedup(database: ReturnType<typeof drizzle<typeof schema>>): void {
1775
- const raw = (database as unknown as { $client: Database }).$client;
1776
-
1777
- // Quick check: if the unique index already exists, no dedup is needed.
1778
- const idxExists = raw.query(
1779
- `SELECT 1 FROM sqlite_master WHERE type = 'index' AND name = 'idx_call_sessions_provider_sid_unique'`,
1780
- ).get();
1781
- if (idxExists) return;
1782
-
1783
- // Check if the table even exists yet (first boot).
1784
- const tableExists = raw.query(
1785
- `SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'call_sessions'`,
1786
- ).get();
1787
- if (!tableExists) return;
1788
-
1789
- // Count duplicates before doing any work.
1790
- const dupCount = raw.query(/*sql*/ `
1791
- SELECT COUNT(*) AS c FROM (
1792
- SELECT provider, provider_call_sid
1793
- FROM call_sessions
1794
- WHERE provider_call_sid IS NOT NULL
1795
- GROUP BY provider, provider_call_sid
1796
- HAVING COUNT(*) > 1
1797
- )
1798
- `).get() as { c: number } | null;
1799
-
1800
- if (!dupCount || dupCount.c === 0) return;
1801
-
1802
- log.warn({ duplicateGroups: dupCount.c }, 'Deduplicating call_sessions with duplicate provider_call_sid before creating unique index');
1803
-
1804
- try {
1805
- raw.exec('BEGIN');
1806
-
1807
- // Keep the most recently updated row per (provider, provider_call_sid);
1808
- // delete the rest.
1809
- raw.exec(/*sql*/ `
1810
- DELETE FROM call_sessions
1811
- WHERE provider_call_sid IS NOT NULL
1812
- AND rowid NOT IN (
1813
- SELECT MAX(rowid) FROM call_sessions
1814
- WHERE provider_call_sid IS NOT NULL
1815
- GROUP BY provider, provider_call_sid
1816
- )
1817
- `);
1818
-
1819
- raw.exec('COMMIT');
1820
- } catch (e) {
1821
- try { raw.exec('ROLLBACK'); } catch { /* no active transaction */ }
1822
- throw e;
1823
- }
1824
- }
1825
-