volute 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/dist/{activity-events-TFAJBNBW.js → activity-events-YASF46HS.js} +2 -2
  2. package/dist/{ai-service-KEK2V3AP.js → ai-service-3UFNG6GI.js} +2 -4
  3. package/dist/{archive-FOHGXHPT.js → archive-L2OFBGDQ.js} +2 -2
  4. package/dist/{auth-Y27LTNZK.js → auth-N2F5ASAB.js} +3 -3
  5. package/dist/auto-upgrade-O4MQPYQF.js +46 -0
  6. package/dist/{avatar-image-SN576P45.js → avatar-image-QEKKUFDF.js} +2 -2
  7. package/dist/{backup-GDCWH6MC.js → backup-TPM7QQBQ.js} +12 -12
  8. package/dist/{channels-AFJWGX7W.js → channels-JP3GYTPX.js} +16 -16
  9. package/dist/{chat-HVPOZK3O.js → chat-7YCF4ZU5.js} +3 -3
  10. package/dist/{chunk-CKOA4LWV.js → chunk-2B4E6SL7.js} +7 -7
  11. package/dist/{chunk-NM5FDH4T.js → chunk-2LFTJNVH.js} +2 -2
  12. package/dist/{chunk-G3XAB4DK.js → chunk-2QLWAYIU.js} +1 -1
  13. package/dist/{chunk-KS62IHE2.js → chunk-45MCH4G4.js} +1 -1
  14. package/dist/{chunk-QVS3C4DK.js → chunk-4RZS7XCV.js} +4 -4
  15. package/dist/{chunk-DUV4EMNW.js → chunk-6LICEQGP.js} +2 -2
  16. package/dist/{chunk-LAUCO2HC.js → chunk-APDEUAIE.js} +1 -1
  17. package/dist/{chunk-XAG53RWY.js → chunk-CLH357FI.js} +1 -1
  18. package/dist/{chunk-HTSWDOJE.js → chunk-CVPCRWWC.js} +1 -1
  19. package/dist/{chunk-Z7TNIIHW.js → chunk-E2SN3ZOJ.js} +2 -39
  20. package/dist/{chunk-NCRG4SBR.js → chunk-ELQU2GBT.js} +23 -33
  21. package/dist/{chunk-OUGD5L5U.js → chunk-EPRLTYJR.js} +8 -8
  22. package/dist/{chunk-VTFXZPC3.js → chunk-EYFBT2KP.js} +8 -8
  23. package/dist/{chunk-PRZUBJ4K.js → chunk-FYMIGUJ5.js} +1 -1
  24. package/dist/{chunk-7XKPG66D.js → chunk-G7A5LEVI.js} +5 -5
  25. package/dist/{chunk-UEZC5MNB.js → chunk-GAAATVTM.js} +11 -11
  26. package/dist/{chunk-OFU6WJJZ.js → chunk-I3OJ342S.js} +2 -2
  27. package/dist/{chunk-FZUPIS3T.js → chunk-IABDYN4N.js} +3 -3
  28. package/dist/{chunk-TMTAHKYP.js → chunk-IOMBP2T5.js} +12 -12
  29. package/dist/{chunk-W3OIPJPB.js → chunk-IQROTVBG.js} +1 -1
  30. package/dist/{chunk-4VAQKLMU.js → chunk-IRNM4LSF.js} +3 -3
  31. package/dist/{chunk-OKM67ZWH.js → chunk-KN3UHV7O.js} +8 -3
  32. package/dist/{chunk-FSXPPOPM.js → chunk-KXM4K46T.js} +1 -1
  33. package/dist/{chunk-Z4Q6TQWL.js → chunk-LRRPKZBD.js} +2 -2
  34. package/dist/{chunk-OIOW3FPT.js → chunk-NA2NJXY4.js} +1 -1
  35. package/dist/{chunk-GLM7TVWP.js → chunk-OHHS5PSI.js} +1 -1
  36. package/dist/{chunk-CKPAVQNK.js → chunk-OPTA3BJ4.js} +36 -24
  37. package/dist/{chunk-HLWQ3P3R.js → chunk-PAO7JZNW.js} +16 -16
  38. package/dist/{chunk-6HBGUPBA.js → chunk-Q5M5QFKY.js} +2 -2
  39. package/dist/{chunk-IR2FW4W7.js → chunk-T7UMSTH2.js} +2 -2
  40. package/dist/{chunk-H6X6CKDN.js → chunk-TAVIVN2I.js} +2 -32
  41. package/dist/{chunk-BP2X5AIK.js → chunk-TGYKFUCF.js} +6 -6
  42. package/dist/{chunk-5U5GLZSD.js → chunk-TZ7OHGNL.js} +2 -2
  43. package/dist/{chunk-7AA4T2RT.js → chunk-UMQP5TC5.js} +1 -1
  44. package/dist/{chunk-3SFKY4GI.js → chunk-UNTDRIV2.js} +4 -4
  45. package/dist/{chunk-45QTYKQQ.js → chunk-V2M6PNLE.js} +2 -2
  46. package/dist/{chunk-IT4GEFDH.js → chunk-WTZD6LFW.js} +1 -1
  47. package/dist/{chunk-FLIEXG2T.js → chunk-XZP3FJ7Q.js} +1 -1
  48. package/dist/cli.js +26 -23
  49. package/dist/{clock-X7V3C7NL.js → clock-ZT5YT6HA.js} +2 -2
  50. package/dist/{cloud-sync-FM73SVFJ.js → cloud-sync-RTUXMYU2.js} +20 -20
  51. package/dist/{conversations-FH3ODBL7.js → conversations-ERMMPMOS.js} +3 -3
  52. package/dist/{create-P75ZFTVN.js → create-IUCFJXCE.js} +1 -1
  53. package/dist/{daemon-restart-JQMMMITM.js → daemon-restart-N2YOISNJ.js} +11 -6
  54. package/dist/daemon.js +125 -202
  55. package/dist/{db-BONH4SUG.js → db-BQFYIONA.js} +1 -1
  56. package/dist/{delivery-manager-H23Q23N7.js → delivery-manager-5EGCFN4K.js} +16 -16
  57. package/dist/{delivery-notices-S7TKOACE.js → delivery-notices-LZKZXWTX.js} +4 -4
  58. package/dist/{delivery-router-KHBVEVVL.js → delivery-router-U6Q22ZYU.js} +2 -2
  59. package/dist/doctor-225FYBAQ.js +454 -0
  60. package/dist/{down-UN2EDX2Y.js → down-3BQSPUAZ.js} +4 -4
  61. package/dist/echo-text-Y2DFTD7L.js +40 -0
  62. package/dist/{env-SQFCWW52.js → env-4YX5YNWZ.js} +2 -2
  63. package/dist/{exec-Z34TTUO3.js → exec-Y5VMDAVA.js} +2 -2
  64. package/dist/{export-VBNWM7I4.js → export-ASRHBMRG.js} +2 -2
  65. package/dist/{extensions-QD22GXZD.js → extensions-YEPEWURN.js} +20 -20
  66. package/dist/{files-DUGRXN6V.js → files-FASUDSZQ.js} +2 -2
  67. package/dist/{import-RDDUGGFI.js → import-O35Y7DSF.js} +5 -5
  68. package/dist/{isolation-UQPDO34R.js → isolation-ZOAUXYXA.js} +2 -2
  69. package/dist/{login-57MMYILL.js → login-54TZQQP4.js} +5 -5
  70. package/dist/{logout-YFZAJRPY.js → logout-4G46Z4RU.js} +1 -1
  71. package/dist/message-delivery-HBTMGWFU.js +46 -0
  72. package/dist/{mind-BARCLI7O.js → mind-IKMX7K7G.js} +8 -24
  73. package/dist/{mind-activity-tracker-UT23RGBF.js → mind-activity-tracker-ABAEIMA3.js} +3 -3
  74. package/dist/mind-service-LRVOQG2T.js +48 -0
  75. package/dist/{mind-sleep-24HV4RCA.js → mind-sleep-LZAFBDZD.js} +2 -2
  76. package/dist/{package-AUDBDKAO.js → package-X5O7OD2E.js} +3 -2
  77. package/dist/{prompts-MOBF3TMO.js → prompts-ZNOE3KN3.js} +2 -2
  78. package/dist/{registry-TRC2HJXR.js → registry-BTQXLDW6.js} +1 -1
  79. package/dist/{sandbox-VI7XWBIA.js → sandbox-OUFAGN45.js} +2 -2
  80. package/dist/scheduler-G6BCIVGP.js +27 -0
  81. package/dist/{seed-cmd-M6A7N7F3.js → seed-cmd-BGAW3WDY.js} +2 -2
  82. package/dist/{seed-create-TGFZW4IO.js → seed-create-SMCPEUFQ.js} +3 -3
  83. package/dist/{seed-readiness-XBH2MUNA.js → seed-readiness-RBANMSWW.js} +3 -3
  84. package/dist/{seed-sprout-3IC5ZVTI.js → seed-sprout-CSHV36N3.js} +6 -6
  85. package/dist/{send-DHYBAYK4.js → send-D3ADUBR5.js} +5 -5
  86. package/dist/{service-T4P5W6RS.js → service-SWEEBOOY.js} +3 -24
  87. package/dist/{service-install-R4SNYUVO.js → service-install-RCC26KDV.js} +4 -4
  88. package/dist/{setup-6KAH3GRW.js → setup-L5NZG2U3.js} +5 -5
  89. package/dist/{setup-WZSXHHRJ.js → setup-R7Q4HFJP.js} +1 -5
  90. package/dist/{skills-LKQCYFVP.js → skills-BCCU4OJW.js} +3 -3
  91. package/dist/sleep-manager-25P44HAO.js +42 -0
  92. package/dist/{spirit-FKXMGO3N.js → spirit-YPG2MU6W.js} +5 -5
  93. package/dist/spirit-availability-ZQM5IH4C.js +43 -0
  94. package/dist/{status-LCKTTIWS.js → status-BYPCJU6H.js} +4 -4
  95. package/dist/{system-events-ZYOCYAO2.js → system-events-CWC7CBKP.js} +2 -2
  96. package/dist/{systems-HL7SGSW7.js → systems-VDRUZXNF.js} +2 -2
  97. package/dist/{tailscale-F2IMBILZ.js → tailscale-4XY7B5A2.js} +1 -1
  98. package/dist/{template-staleness-IBD722PN.js → template-staleness-CL4V7BT7.js} +2 -2
  99. package/dist/{turn-tracker-BE34OI6O.js → turn-tracker-LZP5X6GZ.js} +6 -6
  100. package/dist/{up-J47J5JRB.js → up-3AAN4GYY.js} +4 -4
  101. package/dist/{update-ILCPVNDD.js → update-2MWXRE2S.js} +4 -4
  102. package/dist/{update-check-SZ7B5IFI.js → update-check-PJOZXZYJ.js} +2 -2
  103. package/dist/variant-cleanup-K7RFMSH7.js +24 -0
  104. package/dist/{version-notify-KIXYNHJC.js → version-notify-QIDHR6WO.js} +5 -5
  105. package/dist/web-assets/assets/{index-CoU1eUKE.js → index-Bfvls20e.js} +3 -3
  106. package/dist/web-assets/index.html +1 -1
  107. package/drizzle/0000_crazy_epoch.sql +232 -0
  108. package/drizzle/README.md +42 -0
  109. package/drizzle/meta/0000_snapshot.json +1420 -3
  110. package/drizzle/meta/_journal.json +2 -128
  111. package/package.json +3 -2
  112. package/dist/auto-upgrade-2MZF7NG3.js +0 -46
  113. package/dist/echo-text-ULEIFJJF.js +0 -40
  114. package/dist/message-delivery-LU4EP244.js +0 -46
  115. package/dist/migrate-init-infrastructure-Z72UJ5NT.js +0 -44
  116. package/dist/migrate-name-placeholder-64AEAWPE.js +0 -37
  117. package/dist/migrate-thread-config-SVF2M3D3.js +0 -90
  118. package/dist/mind-service-ZJCUBAUL.js +0 -48
  119. package/dist/scheduler-GLINVC2B.js +0 -27
  120. package/dist/seed-5JGR7ZRA.js +0 -11
  121. package/dist/sleep-manager-Q3ITFNOJ.js +0 -42
  122. package/dist/spirit-availability-5R2WYSWF.js +0 -43
  123. package/dist/sprout-VEW3CUNX.js +0 -11
  124. package/dist/variant-HHDTW74J.js +0 -62
  125. package/dist/variant-cleanup-JGJZ5KB4.js +0 -24
  126. package/drizzle/0000_baseline.sql +0 -152
  127. package/drizzle/0001_add_conversation_private.sql +0 -1
  128. package/drizzle/0002_turns.sql +0 -21
  129. package/drizzle/0003_turn_feed_links.sql +0 -11
  130. package/drizzle/0004_spirits.sql +0 -5
  131. package/drizzle/0005_meta_summaries.sql +0 -15
  132. package/drizzle/0006_channels.sql +0 -17
  133. package/drizzle/0007_drop_conversation_name_title.sql +0 -11
  134. package/drizzle/0008_performance_indexes.sql +0 -6
  135. package/drizzle/0009_mind_notices.sql +0 -14
  136. package/drizzle/0010_delivery_queue_redrive.sql +0 -10
  137. package/drizzle/0011_drop_turn_summary_event_id.sql +0 -3
  138. package/drizzle/0012_channel_gates.sql +0 -17
  139. package/drizzle/0013_variant_purpose.sql +0 -3
  140. package/drizzle/0014_system_events.sql +0 -26
  141. package/drizzle/0015_rename_session_to_thread.sql +0 -12
  142. package/drizzle/0016_brain_to_human.sql +0 -4
  143. package/drizzle/0017_event_history_rows.sql +0 -9
  144. package/drizzle/0018_api_tokens.sql +0 -20
  145. package/drizzle/meta/0001_snapshot.json +0 -7
  146. package/drizzle/meta/0002_snapshot.json +0 -7
  147. package/drizzle/meta/0003_snapshot.json +0 -7
  148. package/drizzle/meta/0004_snapshot.json +0 -7
  149. package/drizzle/meta/0005_snapshot.json +0 -7
  150. package/drizzle/meta/0006_snapshot.json +0 -7
  151. package/drizzle/meta/0007_snapshot.json +0 -7
  152. package/dist/{env-7AZFBPWX.js → env-IBW2QI6K.js} +5 -5
  153. package/dist/{login-4NUS72Z5.js → login-RJJTCVR3.js} +3 -3
  154. package/dist/{mind-contacts-PEXCDRXA.js → mind-contacts-KV64UDJS.js} +6 -6
  155. package/dist/{mind-history-RZMMCHMX.js → mind-history-H45GM2M2.js} +6 -6
  156. package/dist/{register-WNCSOTAU.js → register-OX4HRSGC.js} +3 -3
  157. package/dist/{restart-B4GNMVF2.js → restart-AGEGNSYQ.js} +4 -4
  158. package/dist/{skill-QYTBUDNQ.js → skill-B5OJEQUA.js} +4 -4
  159. package/dist/{start-BDHJVOVX.js → start-MUMNFR52.js} +3 -3
  160. package/dist/{stop-45QYSGYS.js → stop-EKERNYTX.js} +4 -4
@@ -8,7 +8,7 @@
8
8
  <link rel="preconnect" href="https://fonts.googleapis.com" />
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
10
  <link href="https://fonts.googleapis.com/css2?family=Averia+Serif+Libre:wght@300;400;700&family=Fira+Code:wght@300;400;500;600&family=Averia+Sans+Libre:ital,wght@0,300;0,400;0,500;0,600;1,400&display=swap" rel="stylesheet" />
11
- <script type="module" crossorigin src="/assets/index-CoU1eUKE.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-Bfvls20e.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-hPn_fkz3.css">
13
13
  </head>
14
14
  <body>
@@ -0,0 +1,232 @@
1
+ -- Squashed baseline: the full schema as of schema.ts (see #713).
2
+ -- Every statement uses IF NOT EXISTS so existing installs already at this
3
+ -- schema (e.g. bardo) run it as a no-op instead of failing on CREATE.
4
+ CREATE TABLE IF NOT EXISTS `activity` (
5
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
6
+ `type` text NOT NULL,
7
+ `mind` text NOT NULL,
8
+ `summary` text NOT NULL,
9
+ `metadata` text,
10
+ `turn_id` text,
11
+ `source_event_id` integer,
12
+ `created_at` text DEFAULT (datetime('now')) NOT NULL
13
+ );
14
+ --> statement-breakpoint
15
+ CREATE INDEX IF NOT EXISTS `idx_activity_created_at` ON `activity` (`created_at`);--> statement-breakpoint
16
+ CREATE INDEX IF NOT EXISTS `idx_activity_mind` ON `activity` (`mind`);--> statement-breakpoint
17
+ CREATE INDEX IF NOT EXISTS `idx_activity_turn_id` ON `activity` (`turn_id`);--> statement-breakpoint
18
+ CREATE INDEX IF NOT EXISTS `idx_activity_type` ON `activity` (`type`);--> statement-breakpoint
19
+ CREATE TABLE IF NOT EXISTS `api_tokens` (
20
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
21
+ `user_id` integer NOT NULL,
22
+ `token_hash` text NOT NULL,
23
+ `label` text,
24
+ `created_at` text DEFAULT (datetime('now')) NOT NULL,
25
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
26
+ );
27
+ --> statement-breakpoint
28
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_api_tokens_hash` ON `api_tokens` (`token_hash`);--> statement-breakpoint
29
+ CREATE INDEX IF NOT EXISTS `idx_api_tokens_user` ON `api_tokens` (`user_id`);--> statement-breakpoint
30
+ CREATE TABLE IF NOT EXISTS `channel_gates` (
31
+ `mind` text NOT NULL,
32
+ `channel` text NOT NULL,
33
+ `state` text NOT NULL,
34
+ `updated_at` text DEFAULT (datetime('now')) NOT NULL,
35
+ PRIMARY KEY(`mind`, `channel`)
36
+ );
37
+ --> statement-breakpoint
38
+ CREATE TABLE IF NOT EXISTS `channels` (
39
+ `conversation_id` text PRIMARY KEY NOT NULL,
40
+ `name` text NOT NULL,
41
+ `description` text,
42
+ `rules` text,
43
+ `char_limit` integer,
44
+ `private` integer DEFAULT 0 NOT NULL,
45
+ `created_at` text DEFAULT (datetime('now')) NOT NULL,
46
+ `updated_at` text DEFAULT (datetime('now')) NOT NULL,
47
+ FOREIGN KEY (`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE no action ON DELETE cascade
48
+ );
49
+ --> statement-breakpoint
50
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_channels_name` ON `channels` (`name`);--> statement-breakpoint
51
+ CREATE TABLE IF NOT EXISTS `conversation_participants` (
52
+ `conversation_id` text NOT NULL,
53
+ `user_id` integer NOT NULL,
54
+ `role` text DEFAULT 'member' NOT NULL,
55
+ `joined_at` text DEFAULT (datetime('now')) NOT NULL,
56
+ FOREIGN KEY (`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE no action ON DELETE cascade,
57
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
58
+ );
59
+ --> statement-breakpoint
60
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_cp_unique` ON `conversation_participants` (`conversation_id`,`user_id`);--> statement-breakpoint
61
+ CREATE INDEX IF NOT EXISTS `idx_cp_user_id` ON `conversation_participants` (`user_id`);--> statement-breakpoint
62
+ CREATE TABLE IF NOT EXISTS `conversation_reads` (
63
+ `user_id` integer NOT NULL,
64
+ `conversation_id` text NOT NULL,
65
+ `last_read_message_id` integer DEFAULT 0 NOT NULL,
66
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade,
67
+ FOREIGN KEY (`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE no action ON DELETE cascade
68
+ );
69
+ --> statement-breakpoint
70
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_conversation_reads_unique` ON `conversation_reads` (`user_id`,`conversation_id`);--> statement-breakpoint
71
+ CREATE TABLE IF NOT EXISTS `conversations` (
72
+ `id` text PRIMARY KEY NOT NULL,
73
+ `type` text DEFAULT 'dm' NOT NULL,
74
+ `user_id` integer,
75
+ `private` integer DEFAULT 0 NOT NULL,
76
+ `created_at` text DEFAULT (datetime('now')) NOT NULL,
77
+ `updated_at` text DEFAULT (datetime('now')) NOT NULL,
78
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
79
+ );
80
+ --> statement-breakpoint
81
+ CREATE INDEX IF NOT EXISTS `idx_conversations_user_id` ON `conversations` (`user_id`);--> statement-breakpoint
82
+ CREATE INDEX IF NOT EXISTS `idx_conversations_updated_at` ON `conversations` (`updated_at`);--> statement-breakpoint
83
+ CREATE TABLE IF NOT EXISTS `delivery_queue` (
84
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
85
+ `mind` text NOT NULL,
86
+ `target_mind` text,
87
+ `thread` text NOT NULL,
88
+ `channel` text,
89
+ `sender` text,
90
+ `status` text DEFAULT 'pending' NOT NULL,
91
+ `payload` text NOT NULL,
92
+ `attempts` integer DEFAULT 0 NOT NULL,
93
+ `next_attempt_at` text,
94
+ `created_at` text DEFAULT (datetime('now')) NOT NULL
95
+ );
96
+ --> statement-breakpoint
97
+ CREATE INDEX IF NOT EXISTS `idx_delivery_queue_mind_thread` ON `delivery_queue` (`mind`,`thread`);--> statement-breakpoint
98
+ CREATE INDEX IF NOT EXISTS `idx_delivery_queue_mind_status` ON `delivery_queue` (`mind`,`status`);--> statement-breakpoint
99
+ CREATE INDEX IF NOT EXISTS `idx_delivery_queue_status` ON `delivery_queue` (`status`);--> statement-breakpoint
100
+ CREATE INDEX IF NOT EXISTS `idx_delivery_queue_status_next` ON `delivery_queue` (`status`,`next_attempt_at`);--> statement-breakpoint
101
+ CREATE TABLE IF NOT EXISTS `messages` (
102
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
103
+ `conversation_id` text NOT NULL,
104
+ `role` text NOT NULL,
105
+ `sender_name` text,
106
+ `content` text NOT NULL,
107
+ `source_event_id` integer,
108
+ `turn_id` text,
109
+ `created_at` text DEFAULT (datetime('now')) NOT NULL,
110
+ FOREIGN KEY (`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE no action ON DELETE cascade
111
+ );
112
+ --> statement-breakpoint
113
+ CREATE INDEX IF NOT EXISTS `idx_messages_conversation_id` ON `messages` (`conversation_id`);--> statement-breakpoint
114
+ CREATE INDEX IF NOT EXISTS `idx_messages_turn_id` ON `messages` (`turn_id`);--> statement-breakpoint
115
+ CREATE TABLE IF NOT EXISTS `mind_history` (
116
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
117
+ `mind` text NOT NULL,
118
+ `channel` text,
119
+ `thread` text,
120
+ `sender` text,
121
+ `message_id` text,
122
+ `type` text NOT NULL,
123
+ `content` text,
124
+ `metadata` text,
125
+ `turn_id` text,
126
+ `created_at` text DEFAULT (datetime('now')) NOT NULL
127
+ );
128
+ --> statement-breakpoint
129
+ CREATE INDEX IF NOT EXISTS `idx_mind_history_mind` ON `mind_history` (`mind`);--> statement-breakpoint
130
+ CREATE INDEX IF NOT EXISTS `idx_mind_history_mind_channel` ON `mind_history` (`mind`,`channel`);--> statement-breakpoint
131
+ CREATE INDEX IF NOT EXISTS `idx_mind_history_mind_type` ON `mind_history` (`mind`,`type`);--> statement-breakpoint
132
+ CREATE INDEX IF NOT EXISTS `idx_mind_history_turn_id` ON `mind_history` (`turn_id`);--> statement-breakpoint
133
+ CREATE INDEX IF NOT EXISTS `idx_mind_history_thread` ON `mind_history` (`thread`);--> statement-breakpoint
134
+ CREATE INDEX IF NOT EXISTS `idx_mind_history_mind_created_at` ON `mind_history` (`mind`,`created_at`);--> statement-breakpoint
135
+ CREATE TABLE IF NOT EXISTS `minds` (
136
+ `name` text PRIMARY KEY NOT NULL,
137
+ `port` integer NOT NULL,
138
+ `parent` text,
139
+ `dir` text,
140
+ `branch` text,
141
+ `stage` text,
142
+ `purpose` text,
143
+ `template` text,
144
+ `template_hash` text,
145
+ `running` integer DEFAULT 0 NOT NULL,
146
+ `mind_type` text DEFAULT 'mind' NOT NULL,
147
+ `created_by` text,
148
+ `created_at` text DEFAULT (datetime('now')) NOT NULL,
149
+ FOREIGN KEY (`parent`) REFERENCES `minds`(`name`) ON UPDATE no action ON DELETE cascade
150
+ );
151
+ --> statement-breakpoint
152
+ CREATE UNIQUE INDEX IF NOT EXISTS `minds_port_unique` ON `minds` (`port`);--> statement-breakpoint
153
+ CREATE INDEX IF NOT EXISTS `idx_minds_parent` ON `minds` (`parent`);--> statement-breakpoint
154
+ CREATE INDEX IF NOT EXISTS `idx_minds_mind_type` ON `minds` (`mind_type`);--> statement-breakpoint
155
+ CREATE TABLE IF NOT EXISTS `sessions` (
156
+ `id` text PRIMARY KEY NOT NULL,
157
+ `user_id` integer NOT NULL,
158
+ `created_at` integer NOT NULL,
159
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
160
+ );
161
+ --> statement-breakpoint
162
+ CREATE TABLE IF NOT EXISTS `shared_skills` (
163
+ `id` text PRIMARY KEY NOT NULL,
164
+ `name` text NOT NULL,
165
+ `description` text DEFAULT '' NOT NULL,
166
+ `author` text NOT NULL,
167
+ `version` integer DEFAULT 1 NOT NULL,
168
+ `created_at` text DEFAULT (datetime('now')) NOT NULL,
169
+ `updated_at` text DEFAULT (datetime('now')) NOT NULL
170
+ );
171
+ --> statement-breakpoint
172
+ CREATE TABLE IF NOT EXISTS `summaries` (
173
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
174
+ `mind` text NOT NULL,
175
+ `period` text NOT NULL,
176
+ `period_key` text NOT NULL,
177
+ `content` text NOT NULL,
178
+ `metadata` text,
179
+ `created_at` text DEFAULT (datetime('now')) NOT NULL
180
+ );
181
+ --> statement-breakpoint
182
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_summaries_unique` ON `summaries` (`mind`,`period`,`period_key`);--> statement-breakpoint
183
+ CREATE INDEX IF NOT EXISTS `idx_summaries_mind_period` ON `summaries` (`mind`,`period`);--> statement-breakpoint
184
+ CREATE INDEX IF NOT EXISTS `idx_summaries_mind_period_key` ON `summaries` (`mind`,`period_key`);--> statement-breakpoint
185
+ CREATE TABLE IF NOT EXISTS `system_events` (
186
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
187
+ `mind` text NOT NULL,
188
+ `type` text NOT NULL,
189
+ `body` text NOT NULL,
190
+ `meta` text,
191
+ `delivery` text DEFAULT 'immediate' NOT NULL,
192
+ `thread` text DEFAULT 'main' NOT NULL,
193
+ `created_at` text DEFAULT (datetime('now')) NOT NULL,
194
+ `delivered_at` text,
195
+ `reflection` text
196
+ );
197
+ --> statement-breakpoint
198
+ CREATE INDEX IF NOT EXISTS `idx_system_events_mind` ON `system_events` (`mind`);--> statement-breakpoint
199
+ CREATE INDEX IF NOT EXISTS `idx_system_events_mind_delivery` ON `system_events` (`mind`,`delivery`,`delivered_at`);--> statement-breakpoint
200
+ CREATE INDEX IF NOT EXISTS `idx_system_events_mind_type` ON `system_events` (`mind`,`type`);--> statement-breakpoint
201
+ CREATE TABLE IF NOT EXISTS `system_prompts` (
202
+ `key` text PRIMARY KEY NOT NULL,
203
+ `content` text NOT NULL,
204
+ `updated_at` text DEFAULT (datetime('now')) NOT NULL
205
+ );
206
+ --> statement-breakpoint
207
+ CREATE TABLE IF NOT EXISTS `turns` (
208
+ `id` text PRIMARY KEY NOT NULL,
209
+ `mind` text NOT NULL,
210
+ `thread` text,
211
+ `trigger_event_id` integer,
212
+ `summary_id` integer,
213
+ `status` text DEFAULT 'active' NOT NULL,
214
+ `created_at` text DEFAULT (datetime('now')) NOT NULL
215
+ );
216
+ --> statement-breakpoint
217
+ CREATE INDEX IF NOT EXISTS `idx_turns_mind` ON `turns` (`mind`);--> statement-breakpoint
218
+ CREATE INDEX IF NOT EXISTS `idx_turns_mind_status` ON `turns` (`mind`,`status`);--> statement-breakpoint
219
+ CREATE INDEX IF NOT EXISTS `idx_turns_mind_created_at` ON `turns` (`mind`,`created_at`);--> statement-breakpoint
220
+ CREATE TABLE IF NOT EXISTS `users` (
221
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
222
+ `username` text NOT NULL,
223
+ `password_hash` text NOT NULL,
224
+ `role` text DEFAULT 'pending' NOT NULL,
225
+ `user_type` text DEFAULT 'human' NOT NULL,
226
+ `display_name` text,
227
+ `description` text,
228
+ `avatar` text,
229
+ `created_at` text DEFAULT (datetime('now')) NOT NULL
230
+ );
231
+ --> statement-breakpoint
232
+ CREATE UNIQUE INDEX IF NOT EXISTS `users_username_unique` ON `users` (`username`);
@@ -0,0 +1,42 @@
1
+ # Database Migrations
2
+
3
+ ## The Rule: No Hand-Written Migrations
4
+
5
+ **Never write SQL migration files by hand.** All migrations must be generated
6
+ from `schema.ts` using:
7
+
8
+ ```sh
9
+ npm run db:generate
10
+ ```
11
+
12
+ Drizzle tracks schema state via the `meta/` snapshots. Hand-written SQL breaks
13
+ this chain—the next `db:generate` won't know what exists, and you'll get
14
+ duplicate or conflicting migrations.
15
+
16
+ ## Why This Matters
17
+
18
+ Volute uses **idempotent migrations** (`CREATE TABLE IF NOT EXISTS`, etc.) so
19
+ the same migration file can run safely on both fresh installs and existing
20
+ databases. This pattern only works when:
21
+
22
+ 1. Every migration is generated from the source-of-truth schema
23
+ 2. The `meta/` snapshots stay in sync with the SQL files
24
+ 3. No one sneaks in manual DDL that the snapshots don't reflect
25
+
26
+ ## Workflow
27
+
28
+ 1. Edit `src/db/schema.ts`
29
+ 2. Run `npm run db:generate` — it creates the migration and updates snapshots
30
+ 3. Review the generated SQL (in `drizzle/NNNN_*.sql`)
31
+ 4. Run `npm run db:migrate` to apply
32
+
33
+ If `db:generate` produces nothing, your schema change is already reflected.
34
+ If it produces something unexpected, your schema or the snapshots drifted—
35
+ investigate before committing.
36
+
37
+ ## The Baseline
38
+
39
+ `0000_baseline.sql` is a squashed, idempotent snapshot of the entire schema
40
+ as of July 2024. It uses `IF NOT EXISTS` throughout so it runs as a no-op on
41
+ databases that already have these tables. All future migrations build on top
42
+ of this baseline.