negotium 0.1.9 → 0.1.11

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 (244) hide show
  1. package/README.md +42 -0
  2. package/dist/{chunk-e9b2xpff.js → chunk-01xcc856.js} +25 -23
  3. package/dist/{chunk-e9b2xpff.js.map → chunk-01xcc856.js.map} +2 -2
  4. package/dist/chunk-1a6kv9vt.js +118 -0
  5. package/dist/chunk-1a6kv9vt.js.map +10 -0
  6. package/dist/{chunk-f1pzh3xh.js → chunk-1b62d730.js} +24 -22
  7. package/dist/{chunk-f1pzh3xh.js.map → chunk-1b62d730.js.map} +2 -2
  8. package/dist/{chunk-10ct8814.js → chunk-28apmz4r.js} +66 -64
  9. package/dist/{chunk-10ct8814.js.map → chunk-28apmz4r.js.map} +2 -2
  10. package/dist/{chunk-ns2m25dz.js → chunk-2fvydfkx.js} +27 -25
  11. package/dist/{chunk-ns2m25dz.js.map → chunk-2fvydfkx.js.map} +2 -2
  12. package/dist/{chunk-n0kk5xbq.js → chunk-41ygvg5k.js} +73 -44
  13. package/dist/{chunk-n0kk5xbq.js.map → chunk-41ygvg5k.js.map} +7 -7
  14. package/dist/{chunk-eexqsee7.js → chunk-4q966ttx.js} +27 -24
  15. package/dist/{chunk-eexqsee7.js.map → chunk-4q966ttx.js.map} +2 -2
  16. package/dist/{chunk-m4veth0c.js → chunk-51rcsavw.js} +109 -46
  17. package/dist/chunk-51rcsavw.js.map +18 -0
  18. package/dist/{chunk-z2xy5n2q.js → chunk-59d0shyj.js} +12 -12
  19. package/dist/{chunk-z2xy5n2q.js.map → chunk-59d0shyj.js.map} +2 -2
  20. package/dist/{chunk-epqxwkvh.js → chunk-5fzgvn79.js} +28 -26
  21. package/dist/{chunk-epqxwkvh.js.map → chunk-5fzgvn79.js.map} +2 -2
  22. package/dist/{chunk-mhty3nna.js → chunk-61px0717.js} +8 -5
  23. package/dist/chunk-61px0717.js.map +11 -0
  24. package/dist/{chunk-6hknphtc.js → chunk-66y0hr8c.js} +306 -224
  25. package/dist/chunk-66y0hr8c.js.map +29 -0
  26. package/dist/{chunk-mmgh670x.js → chunk-69k45zg8.js} +27 -25
  27. package/dist/{chunk-mmgh670x.js.map → chunk-69k45zg8.js.map} +2 -2
  28. package/dist/{chunk-hsq7j9jk.js → chunk-6ah5farg.js} +38 -34
  29. package/dist/chunk-6ah5farg.js.map +10 -0
  30. package/dist/{chunk-nqdp52aj.js → chunk-6d4fmea5.js} +10 -6
  31. package/dist/{chunk-nqdp52aj.js.map → chunk-6d4fmea5.js.map} +2 -2
  32. package/dist/{chunk-hgw7n8cm.js → chunk-8cahx7xc.js} +9 -6
  33. package/dist/{chunk-hgw7n8cm.js.map → chunk-8cahx7xc.js.map} +2 -2
  34. package/dist/{chunk-fvc7ncxd.js → chunk-8f20fk4n.js} +2 -2
  35. package/dist/{chunk-h8vmb9gf.js → chunk-91ckrvk8.js} +21 -18
  36. package/dist/{chunk-h8vmb9gf.js.map → chunk-91ckrvk8.js.map} +2 -2
  37. package/dist/{chunk-sn51wnf1.js → chunk-93krf6ng.js} +141 -92
  38. package/dist/{chunk-sn51wnf1.js.map → chunk-93krf6ng.js.map} +3 -3
  39. package/dist/{chunk-18fzftjf.js → chunk-9qx1t77a.js} +9 -9
  40. package/dist/{chunk-sqhr1a7e.js → chunk-beqhdr9w.js} +33 -31
  41. package/dist/{chunk-sqhr1a7e.js.map → chunk-beqhdr9w.js.map} +2 -2
  42. package/dist/{chunk-rmyfmrrr.js → chunk-bftftsgq.js} +34 -31
  43. package/dist/{chunk-rmyfmrrr.js.map → chunk-bftftsgq.js.map} +2 -2
  44. package/dist/{chunk-8g0c4as0.js → chunk-cjsnkvq2.js} +3 -3
  45. package/dist/{chunk-g7pvfj5e.js → chunk-cxa7yghg.js} +43 -40
  46. package/dist/{chunk-g7pvfj5e.js.map → chunk-cxa7yghg.js.map} +2 -2
  47. package/dist/{chunk-f97qybwk.js → chunk-f361dwba.js} +173 -168
  48. package/dist/chunk-f361dwba.js.map +11 -0
  49. package/dist/chunk-ffefbd3r.js +17 -0
  50. package/dist/chunk-ffefbd3r.js.map +10 -0
  51. package/dist/{chunk-x1arr7ze.js → chunk-fswhzdf5.js} +3 -2
  52. package/dist/{chunk-x1arr7ze.js.map → chunk-fswhzdf5.js.map} +2 -2
  53. package/dist/{chunk-nmv41qx9.js → chunk-g144wdrs.js} +114 -54
  54. package/dist/chunk-g144wdrs.js.map +24 -0
  55. package/dist/chunk-gz12qcf0.js +981 -0
  56. package/dist/chunk-gz12qcf0.js.map +16 -0
  57. package/dist/{chunk-efyxk97v.js → chunk-h980hb2n.js} +44 -32
  58. package/dist/chunk-h980hb2n.js.map +13 -0
  59. package/dist/{chunk-kbm35t7w.js → chunk-h9vbhhgr.js} +77 -71
  60. package/dist/{chunk-kbm35t7w.js.map → chunk-h9vbhhgr.js.map} +3 -3
  61. package/dist/{chunk-wry79q55.js → chunk-jtrk0khr.js} +6 -6
  62. package/dist/{chunk-2dgkah1z.js → chunk-m9e3tbr8.js} +8 -6
  63. package/dist/{chunk-2dgkah1z.js.map → chunk-m9e3tbr8.js.map} +3 -3
  64. package/dist/{chunk-pkdmypdd.js → chunk-mh5mexsf.js} +1 -1
  65. package/dist/{chunk-6tfzpcvk.js → chunk-npd8n03v.js} +29 -26
  66. package/dist/{chunk-6tfzpcvk.js.map → chunk-npd8n03v.js.map} +2 -2
  67. package/dist/chunk-pg1azh6n.js +2 -0
  68. package/dist/chunk-pg1azh6n.js.map +9 -0
  69. package/dist/{chunk-k9z47mab.js → chunk-qwy57177.js} +5 -15
  70. package/dist/{chunk-k9z47mab.js.map → chunk-qwy57177.js.map} +3 -4
  71. package/dist/{chunk-3vn2vnj1.js → chunk-r31q21h5.js} +24 -22
  72. package/dist/{chunk-3vn2vnj1.js.map → chunk-r31q21h5.js.map} +2 -2
  73. package/dist/{chunk-sgsz2fpq.js → chunk-rbvctv1n.js} +125 -48
  74. package/dist/chunk-rbvctv1n.js.map +10 -0
  75. package/dist/{chunk-9spx3h9n.js → chunk-sctcs5zb.js} +27 -25
  76. package/dist/{chunk-9spx3h9n.js.map → chunk-sctcs5zb.js.map} +2 -2
  77. package/dist/{chunk-vp2db42d.js → chunk-tsstrcfc.js} +3 -2
  78. package/dist/{chunk-vp2db42d.js.map → chunk-tsstrcfc.js.map} +2 -2
  79. package/dist/{chunk-vefj3880.js → chunk-wk2qf31s.js} +26 -24
  80. package/dist/{chunk-vefj3880.js.map → chunk-wk2qf31s.js.map} +2 -2
  81. package/dist/{chunk-tmj5r2zv.js → chunk-wx7ag4dd.js} +41 -38
  82. package/dist/{chunk-tmj5r2zv.js.map → chunk-wx7ag4dd.js.map} +2 -2
  83. package/dist/{chunk-3t4dtm26.js → chunk-znx1fpfd.js} +1 -1
  84. package/dist/cron.js +13184 -0
  85. package/dist/cron.js.map +135 -0
  86. package/dist/hosted-agent.js +25 -14
  87. package/dist/hosted-agent.js.map +3 -3
  88. package/dist/main.js +11 -11
  89. package/dist/mcp-servers.js +47 -0
  90. package/dist/mcp-servers.js.map +10 -0
  91. package/dist/prompts.js +451 -0
  92. package/dist/prompts.js.map +13 -0
  93. package/dist/registry.js +395 -0
  94. package/dist/registry.js.map +19 -0
  95. package/dist/rollout.js +43 -0
  96. package/dist/rollout.js.map +10 -0
  97. package/dist/runtime/cron/background-sessions.ts +91 -0
  98. package/dist/runtime/cron/context.ts +123 -0
  99. package/dist/runtime/cron/host.ts +67 -0
  100. package/dist/runtime/cron/index.ts +92 -0
  101. package/dist/runtime/cron/mcp-server.ts +517 -0
  102. package/dist/runtime/cron/module.ts +169 -0
  103. package/dist/runtime/cron/schedule.ts +211 -0
  104. package/dist/runtime/cron/scheduler.ts +444 -0
  105. package/dist/runtime/cron/scripts.ts +181 -0
  106. package/dist/runtime/cron/store.ts +1043 -0
  107. package/dist/runtime/cron/summarize.ts +115 -0
  108. package/dist/runtime/src/agents/execution-host.ts +20 -0
  109. package/dist/runtime/src/agents/hosted-agent.ts +22 -8
  110. package/dist/runtime/src/agents/mcp-tools/spawn-subagent.ts +75 -1
  111. package/dist/runtime/src/agents/rollout/index.ts +20 -0
  112. package/dist/runtime/src/agents/rollout/shared.ts +36 -3
  113. package/dist/runtime/src/prompts/builders.ts +1 -1
  114. package/dist/runtime/src/query/active-rooms.ts +31 -11
  115. package/dist/runtime/src/runtime/inbox.ts +146 -49
  116. package/dist/runtime/src/runtime/public-helpers.ts +11 -0
  117. package/dist/runtime/src/runtime/task-format.ts +18 -0
  118. package/dist/runtime/src/runtime/tasks.ts +2 -16
  119. package/dist/runtime/src/runtime/turn-runner.ts +65 -15
  120. package/dist/runtime/src/storage/activity-log.ts +21 -12
  121. package/dist/runtime/src/storage/api-messages.ts +58 -51
  122. package/dist/runtime/src/storage/api-topic-brief.ts +12 -9
  123. package/dist/runtime/src/storage/api-topic-config.ts +59 -54
  124. package/dist/runtime/src/storage/api-topics.ts +232 -227
  125. package/dist/runtime/src/storage/app-settings.ts +27 -15
  126. package/dist/runtime/src/storage/conversations.ts +2 -2
  127. package/dist/runtime/src/storage/forum/repository.ts +12 -2
  128. package/dist/runtime/src/storage/forum/schema.ts +178 -171
  129. package/dist/runtime/src/storage/forum-db.ts +1 -23
  130. package/dist/runtime/src/storage/session-asks.ts +145 -46
  131. package/dist/runtime/src/storage/storage-host.ts +185 -0
  132. package/dist/runtime/src/storage/storage-public.ts +80 -0
  133. package/dist/runtime/src/storage/tasks.ts +7 -2
  134. package/dist/runtime/src/storage/token-stats.ts +10 -6
  135. package/dist/runtime/src/storage/topic-archive-state.ts +11 -8
  136. package/dist/runtime/src/storage/vault-crypto.ts +11 -5
  137. package/dist/runtime/src/storage/vault-public.ts +27 -0
  138. package/dist/runtime/src/storage/vault.ts +95 -42
  139. package/dist/runtime/src/storage/wiki.ts +7 -5
  140. package/dist/runtime/src/types/api.ts +2 -0
  141. package/dist/runtime/src/version.ts +1 -1
  142. package/dist/runtime-helpers.js +540 -0
  143. package/dist/runtime-helpers.js.map +18 -0
  144. package/dist/storage.js +3156 -0
  145. package/dist/storage.js.map +37 -0
  146. package/dist/types/apps/negotium/src/mcp-servers.d.ts +7 -0
  147. package/dist/types/packages/core/src/agents/claude-provider.d.ts +23 -0
  148. package/dist/types/packages/core/src/agents/claude-registry.d.ts +2 -0
  149. package/dist/types/packages/core/src/agents/codex-native-multi-agent.d.ts +8 -0
  150. package/dist/types/packages/core/src/agents/codex-provider.d.ts +45 -0
  151. package/dist/types/packages/core/src/agents/codex-registry.d.ts +2 -0
  152. package/dist/types/packages/core/src/agents/codex-tree-kill.d.ts +78 -0
  153. package/dist/types/packages/core/src/agents/contracts.d.ts +63 -0
  154. package/dist/types/packages/core/src/agents/deep-map.d.ts +2 -0
  155. package/dist/types/packages/core/src/agents/execution-host.d.ts +31 -0
  156. package/dist/types/packages/core/src/agents/hosted-agent.d.ts +11 -0
  157. package/dist/types/packages/core/src/agents/maestro-provider.d.ts +67 -0
  158. package/dist/types/packages/core/src/agents/maestro-registry.d.ts +17 -0
  159. package/dist/types/packages/core/src/agents/registry.d.ts +4 -0
  160. package/dist/types/packages/core/src/agents/rollout/claude.d.ts +72 -0
  161. package/dist/types/packages/core/src/agents/rollout/codex.d.ts +70 -0
  162. package/dist/types/packages/core/src/agents/rollout/index.d.ts +6 -0
  163. package/dist/types/packages/core/src/agents/rollout/shared.d.ts +50 -0
  164. package/dist/types/packages/core/src/agents/vault-tool-policy.d.ts +4 -0
  165. package/dist/types/packages/core/src/mcp/canonical-bridge-config.d.ts +21 -0
  166. package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +36 -0
  167. package/dist/types/packages/core/src/mcp/session-comm/bridge-ipc-config.d.ts +6 -0
  168. package/dist/types/packages/core/src/media/file-events.d.ts +14 -0
  169. package/dist/types/packages/core/src/platform/config.d.ts +95 -0
  170. package/dist/types/packages/core/src/platform/constants.d.ts +10 -0
  171. package/dist/types/packages/core/src/platform/error.d.ts +6 -0
  172. package/dist/types/packages/core/src/platform/file-utils.d.ts +6 -0
  173. package/dist/types/packages/core/src/platform/jsonl.d.ts +33 -0
  174. package/dist/types/packages/core/src/platform/logger.d.ts +14 -0
  175. package/dist/types/packages/core/src/platform/maestro-bootstrap-env.d.ts +0 -0
  176. package/dist/types/packages/core/src/platform/mcp-config.d.ts +227 -0
  177. package/dist/types/packages/core/src/prompts/builders.d.ts +32 -0
  178. package/dist/types/packages/core/src/runtime/attachments.d.ts +36 -0
  179. package/dist/types/packages/core/src/runtime/channel-context.d.ts +13 -0
  180. package/dist/types/packages/core/src/runtime/file-hooks.d.ts +38 -0
  181. package/dist/types/packages/core/src/runtime/public-helpers.d.ts +3 -0
  182. package/dist/types/packages/core/src/runtime/task-format.d.ts +4 -0
  183. package/dist/types/packages/core/src/runtime/visual-html.d.ts +13 -0
  184. package/dist/types/packages/core/src/security/sanitize.d.ts +16 -0
  185. package/dist/types/packages/core/src/security/sensitive-path.d.ts +1 -0
  186. package/dist/types/packages/core/src/storage/activity-log.d.ts +25 -0
  187. package/dist/types/packages/core/src/storage/api-messages.d.ts +111 -0
  188. package/dist/types/packages/core/src/storage/api-topic-brief.d.ts +39 -0
  189. package/dist/types/packages/core/src/storage/api-topic-config.d.ts +23 -0
  190. package/dist/types/packages/core/src/storage/api-topics.d.ts +86 -0
  191. package/dist/types/packages/core/src/storage/app-settings.d.ts +4 -0
  192. package/dist/types/packages/core/src/storage/conversations.d.ts +123 -0
  193. package/dist/types/packages/core/src/storage/forum/agent-settings.d.ts +3 -0
  194. package/dist/types/packages/core/src/storage/forum/index.d.ts +4 -0
  195. package/dist/types/packages/core/src/storage/forum/repository.d.ts +42 -0
  196. package/dist/types/packages/core/src/storage/forum/schema.d.ts +38 -0
  197. package/dist/types/packages/core/src/storage/forum-db.d.ts +1 -0
  198. package/dist/types/packages/core/src/storage/session-asks.d.ts +66 -0
  199. package/dist/types/packages/core/src/storage/sqlite.d.ts +4 -0
  200. package/dist/types/packages/core/src/storage/storage-host.d.ts +37 -0
  201. package/dist/types/packages/core/src/storage/storage-public.d.ts +38 -0
  202. package/dist/types/packages/core/src/storage/tasks.d.ts +49 -0
  203. package/dist/types/packages/core/src/storage/token-stats.d.ts +30 -0
  204. package/dist/types/packages/core/src/storage/topic-archive-state.d.ts +10 -0
  205. package/dist/types/packages/core/src/storage/topic-archive.d.ts +26 -0
  206. package/dist/types/packages/core/src/storage/topic-settings.d.ts +19 -0
  207. package/dist/types/packages/core/src/storage/topic-transcript.d.ts +38 -0
  208. package/dist/types/packages/core/src/storage/vault-crypto.d.ts +11 -0
  209. package/dist/types/packages/core/src/storage/vault-public.d.ts +3 -0
  210. package/dist/types/packages/core/src/storage/vault.d.ts +39 -0
  211. package/dist/types/packages/core/src/storage/wiki-summary-names.d.ts +6 -0
  212. package/dist/types/packages/core/src/storage/wiki.d.ts +15 -0
  213. package/dist/types/packages/core/src/types/api.d.ts +472 -0
  214. package/dist/types/packages/core/src/types.d.ts +249 -0
  215. package/dist/types/packages/core/src/version.d.ts +1 -0
  216. package/dist/types/packages/module-cron/src/background-sessions.d.ts +2 -0
  217. package/dist/types/packages/module-cron/src/context.d.ts +15 -0
  218. package/dist/types/packages/module-cron/src/host.d.ts +23 -0
  219. package/dist/types/packages/module-cron/src/index.d.ts +14 -0
  220. package/dist/types/packages/module-cron/src/module.d.ts +13 -0
  221. package/dist/types/packages/module-cron/src/schedule.d.ts +23 -0
  222. package/dist/types/packages/module-cron/src/scheduler.d.ts +46 -0
  223. package/dist/types/packages/module-cron/src/scripts.d.ts +23 -0
  224. package/dist/types/packages/module-cron/src/store.d.ts +127 -0
  225. package/dist/types/packages/module-cron/src/summarize.d.ts +4 -0
  226. package/dist/vault.js +533 -0
  227. package/dist/vault.js.map +15 -0
  228. package/package.json +47 -4
  229. package/dist/chunk-1msje2zf.js +0 -23
  230. package/dist/chunk-1msje2zf.js.map +0 -10
  231. package/dist/chunk-6hknphtc.js.map +0 -29
  232. package/dist/chunk-efyxk97v.js.map +0 -13
  233. package/dist/chunk-f97qybwk.js.map +0 -11
  234. package/dist/chunk-hsq7j9jk.js.map +0 -10
  235. package/dist/chunk-m4veth0c.js.map +0 -17
  236. package/dist/chunk-mhty3nna.js.map +0 -11
  237. package/dist/chunk-nmv41qx9.js.map +0 -23
  238. package/dist/chunk-sgsz2fpq.js.map +0 -10
  239. /package/dist/{chunk-fvc7ncxd.js.map → chunk-8f20fk4n.js.map} +0 -0
  240. /package/dist/{chunk-18fzftjf.js.map → chunk-9qx1t77a.js.map} +0 -0
  241. /package/dist/{chunk-8g0c4as0.js.map → chunk-cjsnkvq2.js.map} +0 -0
  242. /package/dist/{chunk-wry79q55.js.map → chunk-jtrk0khr.js.map} +0 -0
  243. /package/dist/{chunk-pkdmypdd.js.map → chunk-mh5mexsf.js.map} +0 -0
  244. /package/dist/{chunk-3t4dtm26.js.map → chunk-znx1fpfd.js.map} +0 -0
@@ -9,10 +9,12 @@
9
9
  // pagination resolves the cursor id → its rowid and returns rows after it.
10
10
 
11
11
  import { db } from "#storage/forum-db";
12
+ import { registerStorageSchemaInitializer } from "#storage/storage-host";
12
13
  import type { AgentKind } from "#types";
13
14
  import type { MessageDto } from "#types/api";
14
15
 
15
- db.exec(`
16
+ function initializeApiMessagesSchema(): void {
17
+ db.exec(`
16
18
  CREATE TABLE IF NOT EXISTS api_messages (
17
19
  id TEXT PRIMARY KEY,
18
20
  topic_id TEXT NOT NULL,
@@ -35,57 +37,62 @@ db.exec(`
35
37
  created_at TEXT NOT NULL
36
38
  )
37
39
  `);
38
- try {
39
- db.exec("ALTER TABLE api_messages ADD COLUMN source_adapter TEXT");
40
- } catch {
41
- // Column already exists.
42
- }
43
- try {
44
- db.exec("ALTER TABLE api_messages ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0");
45
- } catch {
46
- // Column already exists.
47
- }
48
- try {
49
- db.exec("ALTER TABLE api_messages ADD COLUMN edited_at TEXT");
50
- } catch {
51
- // Column already exists.
52
- }
53
- try {
54
- db.exec("ALTER TABLE api_messages ADD COLUMN reactions TEXT");
55
- } catch {
56
- // Column already exists.
57
- }
58
- try {
59
- db.exec("ALTER TABLE api_messages ADD COLUMN kind TEXT");
60
- } catch {
61
- // Column already exists.
62
- }
63
- try {
64
- db.exec("ALTER TABLE api_messages ADD COLUMN ask_user_question TEXT");
65
- } catch {
66
- // Column already exists.
67
- }
68
- try {
69
- db.exec("ALTER TABLE api_messages ADD COLUMN mentions TEXT");
70
- } catch {
71
- // Column already exists.
72
- }
73
- try {
74
- // Slack-style threads: a reply carries the ROOT message id (flat, no nesting).
75
- // Distinct from parent_id (which is a Telegram-style inline quote-reply).
76
- db.exec("ALTER TABLE api_messages ADD COLUMN thread_root_id TEXT");
77
- } catch {
78
- // Column already exists.
79
- }
80
- try {
81
- db.exec("ALTER TABLE api_messages ADD COLUMN subagent_card TEXT");
82
- } catch {
83
- // Column already exists.
40
+ try {
41
+ db.exec("ALTER TABLE api_messages ADD COLUMN source_adapter TEXT");
42
+ } catch {
43
+ // Column already exists.
44
+ }
45
+ try {
46
+ db.exec("ALTER TABLE api_messages ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0");
47
+ } catch {
48
+ // Column already exists.
49
+ }
50
+ try {
51
+ db.exec("ALTER TABLE api_messages ADD COLUMN edited_at TEXT");
52
+ } catch {
53
+ // Column already exists.
54
+ }
55
+ try {
56
+ db.exec("ALTER TABLE api_messages ADD COLUMN reactions TEXT");
57
+ } catch {
58
+ // Column already exists.
59
+ }
60
+ try {
61
+ db.exec("ALTER TABLE api_messages ADD COLUMN kind TEXT");
62
+ } catch {
63
+ // Column already exists.
64
+ }
65
+ try {
66
+ db.exec("ALTER TABLE api_messages ADD COLUMN ask_user_question TEXT");
67
+ } catch {
68
+ // Column already exists.
69
+ }
70
+ try {
71
+ db.exec("ALTER TABLE api_messages ADD COLUMN mentions TEXT");
72
+ } catch {
73
+ // Column already exists.
74
+ }
75
+ try {
76
+ // Slack-style threads: a reply carries the ROOT message id (flat, no nesting).
77
+ // Distinct from parent_id (which is a Telegram-style inline quote-reply).
78
+ db.exec("ALTER TABLE api_messages ADD COLUMN thread_root_id TEXT");
79
+ } catch {
80
+ // Column already exists.
81
+ }
82
+ try {
83
+ db.exec("ALTER TABLE api_messages ADD COLUMN subagent_card TEXT");
84
+ } catch {
85
+ // Column already exists.
86
+ }
87
+ // Index on topic_id; SQLite appends the implicit rowid to every index entry,
88
+ // so `WHERE topic_id=? AND rowid>? ORDER BY rowid` stays index-driven.
89
+ db.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_topic ON api_messages(topic_id)");
90
+ db.exec(
91
+ "CREATE INDEX IF NOT EXISTS idx_api_messages_thread_root ON api_messages(thread_root_id)",
92
+ );
84
93
  }
85
- // Index on topic_id; SQLite appends the implicit rowid to every index entry,
86
- // so `WHERE topic_id=? AND rowid>? ORDER BY rowid` stays index-driven.
87
- db.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_topic ON api_messages(topic_id)");
88
- db.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_thread_root ON api_messages(thread_root_id)");
94
+
95
+ registerStorageSchemaInitializer(initializeApiMessagesSchema, 30);
89
96
 
90
97
  export interface ApiMessageRow {
91
98
  id: string;
@@ -4,16 +4,19 @@
4
4
  // Briefs are injected into AI-invited topic turns at session start. The
5
5
  // wiki-archiver updates them post-session.
6
6
  import { db } from "#storage/forum-db";
7
+ import { registerStorageSchemaInitializer } from "#storage/storage-host";
7
8
 
8
- db.exec(`
9
- CREATE TABLE IF NOT EXISTS api_topic_brief (
10
- topic_id TEXT PRIMARY KEY,
11
- brief_md TEXT NOT NULL DEFAULT '',
12
- latest_summary_md TEXT,
13
- summary_date TEXT,
14
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
15
- )
16
- `);
9
+ registerStorageSchemaInitializer((database) => {
10
+ database.exec(`
11
+ CREATE TABLE IF NOT EXISTS api_topic_brief (
12
+ topic_id TEXT PRIMARY KEY,
13
+ brief_md TEXT NOT NULL DEFAULT '',
14
+ latest_summary_md TEXT,
15
+ summary_date TEXT,
16
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
17
+ )
18
+ `);
19
+ }, 30);
17
20
 
18
21
  export interface TopicBrief {
19
22
  topicId: string;
@@ -4,6 +4,7 @@
4
4
  // regression now that topic config is the canonical path for model/effort
5
5
  // switching (the MCP-based direction), not just a transient convenience.
6
6
  import { db } from "#storage/forum-db";
7
+ import { registerStorageSchemaInitializer } from "#storage/storage-host";
7
8
  import type { EffortLevel } from "#types";
8
9
 
9
10
  function tableColumns(table: string): Set<string> {
@@ -25,28 +26,29 @@ function createCanonicalConfigTable(name = "api_topic_config"): void {
25
26
  `);
26
27
  }
27
28
 
28
- const existingConfigColumns = tableColumns("api_topic_config");
29
- if (existingConfigColumns.size === 0) {
30
- createCanonicalConfigTable();
31
- } else if (
32
- existingConfigColumns.has("agent") ||
33
- existingConfigColumns.has("agent_pinned") ||
34
- existingConfigColumns.has("runtime_locked") ||
35
- existingConfigColumns.has("model_pinned") ||
36
- existingConfigColumns.has("effort_pinned") ||
37
- existingConfigColumns.has("last_shown_agent")
38
- ) {
39
- // Complete the old agent-override migration before dropping the column. The
40
- // selected agent itself belongs to api_topics; only its user lock belongs here.
41
- const topicColumns = tableColumns("api_topics");
42
- const agentColumn = topicColumns.has("agent")
43
- ? "agent"
44
- : topicColumns.has("runtime_agent")
45
- ? "runtime_agent"
46
- : null;
47
- if (agentColumn && existingConfigColumns.has("agent")) {
48
- db.exec(
49
- `UPDATE api_topics
29
+ function initializeApiTopicConfigSchema(): void {
30
+ const existingConfigColumns = tableColumns("api_topic_config");
31
+ if (existingConfigColumns.size === 0) {
32
+ createCanonicalConfigTable();
33
+ } else if (
34
+ existingConfigColumns.has("agent") ||
35
+ existingConfigColumns.has("agent_pinned") ||
36
+ existingConfigColumns.has("runtime_locked") ||
37
+ existingConfigColumns.has("model_pinned") ||
38
+ existingConfigColumns.has("effort_pinned") ||
39
+ existingConfigColumns.has("last_shown_agent")
40
+ ) {
41
+ // Complete the old agent-override migration before dropping the column. The
42
+ // selected agent itself belongs to api_topics; only its user lock belongs here.
43
+ const topicColumns = tableColumns("api_topics");
44
+ const agentColumn = topicColumns.has("agent")
45
+ ? "agent"
46
+ : topicColumns.has("runtime_agent")
47
+ ? "runtime_agent"
48
+ : null;
49
+ if (agentColumn && existingConfigColumns.has("agent")) {
50
+ db.exec(
51
+ `UPDATE api_topics
50
52
  SET ${agentColumn} = (
51
53
  SELECT c.agent FROM api_topic_config c WHERE c.topic_id = api_topics.id
52
54
  )
@@ -55,32 +57,32 @@ if (existingConfigColumns.size === 0) {
55
57
  SELECT 1 FROM api_topic_config c
56
58
  WHERE c.topic_id = api_topics.id AND c.agent IS NOT NULL
57
59
  )`,
58
- );
59
- }
60
+ );
61
+ }
60
62
 
61
- const previousForeignKeys = db
62
- .query<{ foreign_keys: number }, []>("PRAGMA foreign_keys")
63
- .get()?.foreign_keys;
64
- db.exec("PRAGMA foreign_keys = OFF");
65
- try {
66
- const agentLockSource = existingConfigColumns.has("runtime_locked")
67
- ? "runtime_locked"
68
- : existingConfigColumns.has("agent_pinned")
69
- ? "agent_pinned"
70
- : "0";
71
- const modelLockSource = existingConfigColumns.has("model_locked")
72
- ? "model_locked"
73
- : existingConfigColumns.has("model_pinned")
74
- ? "model_pinned"
75
- : "0";
76
- const effortLockSource = existingConfigColumns.has("effort_locked")
77
- ? "effort_locked"
78
- : existingConfigColumns.has("effort_pinned")
79
- ? "effort_pinned"
80
- : "0";
81
- db.transaction(() => {
82
- createCanonicalConfigTable("api_topic_config_next");
83
- db.exec(`
63
+ const previousForeignKeys = db
64
+ .query<{ foreign_keys: number }, []>("PRAGMA foreign_keys")
65
+ .get()?.foreign_keys;
66
+ db.exec("PRAGMA foreign_keys = OFF");
67
+ try {
68
+ const agentLockSource = existingConfigColumns.has("runtime_locked")
69
+ ? "runtime_locked"
70
+ : existingConfigColumns.has("agent_pinned")
71
+ ? "agent_pinned"
72
+ : "0";
73
+ const modelLockSource = existingConfigColumns.has("model_locked")
74
+ ? "model_locked"
75
+ : existingConfigColumns.has("model_pinned")
76
+ ? "model_pinned"
77
+ : "0";
78
+ const effortLockSource = existingConfigColumns.has("effort_locked")
79
+ ? "effort_locked"
80
+ : existingConfigColumns.has("effort_pinned")
81
+ ? "effort_pinned"
82
+ : "0";
83
+ db.transaction(() => {
84
+ createCanonicalConfigTable("api_topic_config_next");
85
+ db.exec(`
84
86
  INSERT INTO api_topic_config_next
85
87
  (topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
86
88
  SELECT
@@ -94,16 +96,19 @@ if (existingConfigColumns.size === 0) {
94
96
  FROM api_topic_config
95
97
  WHERE EXISTS (SELECT 1 FROM api_topics t WHERE t.id = api_topic_config.topic_id)
96
98
  `);
97
- db.exec("DROP TABLE api_topic_config");
98
- db.exec("ALTER TABLE api_topic_config_next RENAME TO api_topic_config");
99
- })();
100
- } finally {
101
- db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
99
+ db.exec("DROP TABLE api_topic_config");
100
+ db.exec("ALTER TABLE api_topic_config_next RENAME TO api_topic_config");
101
+ })();
102
+ } finally {
103
+ db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
104
+ }
105
+ } else {
106
+ createCanonicalConfigTable();
102
107
  }
103
- } else {
104
- createCanonicalConfigTable();
105
108
  }
106
109
 
110
+ registerStorageSchemaInitializer(initializeApiTopicConfigSchema, 40);
111
+
107
112
  export interface TopicConfig {
108
113
  model?: string;
109
114
  effort?: EffortLevel;