volute 0.33.0 → 0.35.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 (255) hide show
  1. package/README.md +7 -6
  2. package/dist/accept-ZBDVVCEU.js +42 -0
  3. package/dist/activity-events-ZW4SDL2C.js +15 -0
  4. package/dist/{ai-service-SBY2WG7O.js → ai-service-LURBEDDB.js} +6 -6
  5. package/dist/{api-client-YPKOZP2O.js → api-client-3A77HMH7.js} +2 -2
  6. package/dist/api.d.ts +1 -5195
  7. package/dist/{archive-INXYFVCW.js → archive-ESU2FUN4.js} +4 -4
  8. package/dist/{auth-GKCDSO4T.js → auth-WX4TESEI.js} +6 -6
  9. package/dist/bridge-PXIO6PS2.js +206 -0
  10. package/dist/chat-QXAJF3FU.js +51 -0
  11. package/dist/{chunk-NNB4WIG7.js → chunk-2TGZJFAT.js} +3 -3
  12. package/dist/{chunk-6LXAAQ43.js → chunk-33ODGMFZ.js} +1 -1
  13. package/dist/{chunk-RPZZSXV3.js → chunk-5N7Y5WAM.js} +21 -2
  14. package/dist/chunk-5T5YMX6S.js +23 -0
  15. package/dist/{chunk-7J3HEVR7.js → chunk-5XJYUFZH.js} +28 -16
  16. package/dist/chunk-7KJOFUNN.js +22 -0
  17. package/dist/{chunk-2NGTS5UU.js → chunk-A2ZLHBHG.js} +2 -2
  18. package/dist/{chunk-KIEPMIM5.js → chunk-AN2W47GW.js} +2 -2
  19. package/dist/{chunk-G53F3JA4.js → chunk-AOB6GVRM.js} +1 -1
  20. package/dist/{chunk-LRCG2JLP.js → chunk-BDYXIWA5.js} +9 -5
  21. package/dist/{chunk-YUIHSKR6.js → chunk-BKF4WQCY.js} +2 -2
  22. package/dist/{chunk-N432I7QH.js → chunk-BMZQYACC.js} +2 -2
  23. package/dist/{chunk-NAOW2CLO.js → chunk-BTY4WNFE.js} +1 -1
  24. package/dist/{chunk-ALEF47VT.js → chunk-BV65KRHM.js} +2 -2
  25. package/dist/{chunk-KVK2DLWI.js → chunk-CORXD635.js} +4 -4
  26. package/dist/{chunk-PVY5W6QN.js → chunk-F7ZNLYKZ.js} +2 -2
  27. package/dist/{chunk-QTUVYI7W.js → chunk-FT5KETXZ.js} +3 -3
  28. package/dist/{chunk-C7I35G4R.js → chunk-IJHIXLVN.js} +44 -8
  29. package/dist/{chunk-JUKK7FPS.js → chunk-J6CJQDWI.js} +37 -28
  30. package/dist/{chunk-4RQBJWQX.js → chunk-LOPXTW6H.js} +1 -1
  31. package/dist/{chunk-RSX4OPZY.js → chunk-MDJGMOSD.js} +8 -137
  32. package/dist/{chunk-LOEJ4HPQ.js → chunk-N446KRP7.js} +3 -3
  33. package/dist/{chunk-I5KY25PQ.js → chunk-N5LMGYXX.js} +2 -2
  34. package/dist/{chunk-G6BSYHPK.js → chunk-NJK5SDGR.js} +1 -1
  35. package/dist/{chunk-D424ZQGI.js → chunk-O7IGP7ZW.js} +11 -3
  36. package/dist/{chunk-M7UL5S3Q.js → chunk-OTC67N2Z.js} +2 -2
  37. package/dist/{chunk-GY5HBI7A.js → chunk-PWQ2ITYG.js} +4 -4
  38. package/dist/{chunk-KTLFDYPT.js → chunk-QCH6K235.js} +1 -1
  39. package/dist/chunk-QHG4OMZL.js +145 -0
  40. package/dist/{chunk-SKLSMHXO.js → chunk-QWTR6AWZ.js} +3 -3
  41. package/dist/chunk-TXSA4Q3V.js +116 -0
  42. package/dist/{chunk-VH33ZWMW.js → chunk-VHJRZM2S.js} +2 -2
  43. package/dist/{chunk-SSI47XP2.js → chunk-VHWGEJ4V.js} +1 -1
  44. package/dist/chunk-VY3RB2V7.js +164 -0
  45. package/dist/chunk-WJPROOU5.js +8314 -0
  46. package/dist/{chunk-RVGLDGMI.js → chunk-WZRZFFCL.js} +25 -27
  47. package/dist/{chunk-JYVGHWEJ.js → chunk-XRQSAMX2.js} +4 -4
  48. package/dist/{chunk-OYAKCAVY.js → chunk-ZSR72JB3.js} +1 -1
  49. package/dist/{chunk-UKVWJRKN.js → chunk-ZX7EAV5J.js} +17 -7
  50. package/dist/cli.js +90 -29
  51. package/dist/clock-HSEKS5AR.js +289 -0
  52. package/dist/{cloud-sync-4NWLMFVH.js → cloud-sync-6JL4C24T.js} +22 -23
  53. package/dist/config-UTS7QULS.js +76 -0
  54. package/dist/connectors/discord-bridge.js +4 -4
  55. package/dist/connectors/slack-bridge.js +4 -4
  56. package/dist/connectors/telegram-bridge.js +4 -4
  57. package/dist/{conversations-AWI5SZW2.js → conversations-2PW57WO2.js} +6 -6
  58. package/dist/create-5BPOOJAN.js +75 -0
  59. package/dist/create-UVCK2CS6.js +50 -0
  60. package/dist/daemon-client-RVIKXGFQ.js +12 -0
  61. package/dist/daemon-restart-HSZ3BCX5.js +65 -0
  62. package/dist/daemon.js +1349 -1211
  63. package/dist/db-BDMH4SZ2.js +20 -0
  64. package/dist/db-BVBJ57TU.js +9 -0
  65. package/dist/delete-L5PAVDGQ.js +42 -0
  66. package/dist/delivery-manager-H5ZVBMCQ.js +31 -0
  67. package/dist/{delivery-router-FL45JL7N.js → delivery-router-HEJSJAHQ.js} +5 -5
  68. package/dist/down-74VXM45A.js +17 -0
  69. package/dist/env-E4XHO2BI.js +223 -0
  70. package/dist/exec-PY7THYH4.js +17 -0
  71. package/dist/export-OAS6QVBN.js +113 -0
  72. package/dist/extension-D74CNM7G.js +89 -0
  73. package/dist/extensions-XDDFY72A.js +49 -0
  74. package/dist/files-CWTK6V3H.js +53 -0
  75. package/dist/import-5A3T7QV4.js +143 -0
  76. package/dist/{isolation-LLAYQYDY.js → isolation-TK5RX2WM.js} +4 -4
  77. package/dist/join-DF5XSJAC.js +67 -0
  78. package/dist/lib-DYEZMGW7.js +6588 -0
  79. package/dist/list-PDMQM7ZV.js +53 -0
  80. package/dist/login-7TE6CIZF.js +60 -0
  81. package/dist/login-GOTAYLXP.js +51 -0
  82. package/dist/logout-6KIA74EV.js +29 -0
  83. package/dist/logout-T4XS6LRU.js +50 -0
  84. package/dist/message-delivery-GRC4W6P7.js +41 -0
  85. package/dist/mind-5IEYKV7I.js +97 -0
  86. package/dist/mind-activity-tracker-QBLIV7ZJ.js +18 -0
  87. package/dist/mind-history-IE2QH7U5.js +275 -0
  88. package/dist/mind-list-GEWHWAL4.js +38 -0
  89. package/dist/mind-manager-HFLB5653.js +31 -0
  90. package/dist/mind-profile-DCBDVF5B.js +53 -0
  91. package/dist/mind-service-X2CAA6W6.js +37 -0
  92. package/dist/mind-sleep-ITCF6OQA.js +47 -0
  93. package/dist/mind-status-X4SX3YUG.js +65 -0
  94. package/dist/mind-wake-KXMKMGWX.js +42 -0
  95. package/dist/{package-U3VFO273.js → package-D2FSVFAX.js} +11 -8
  96. package/dist/read-67VRP2DO.js +91 -0
  97. package/dist/{read-stdin-HQJ7774D.js → read-stdin-3X5VYKNS.js} +2 -2
  98. package/dist/register-SB7NXCOE.js +51 -0
  99. package/dist/{registry-PJ4S5PHQ.js → registry-GBSNW3HG.js} +3 -3
  100. package/dist/reject-MUR2KWJ4.js +40 -0
  101. package/dist/restart-5EGG4JXU.js +42 -0
  102. package/dist/{sandbox-GJOK4QLQ.js → sandbox-R37VIU36.js} +6 -6
  103. package/dist/scheduler-Y7O4CJXL.js +31 -0
  104. package/dist/{schema-PA3M5ZKH.js → schema-XVZ2CLKW.js} +4 -2
  105. package/dist/{seed-QDYVLG74.js → seed-EQORWX77.js} +3 -3
  106. package/dist/seed-check-KJNTL72M.js +35 -0
  107. package/dist/seed-cmd-ZM2XGVU2.js +30 -0
  108. package/dist/seed-create-DRWGGHEI.js +113 -0
  109. package/dist/seed-sprout-JYXGXOP3.js +148 -0
  110. package/dist/send-JBJJQ7CA.js +409 -0
  111. package/dist/service-WNPCNHOX.js +121 -0
  112. package/dist/{setup-XMCBE3LF.js → setup-BJ4YAY26.js} +155 -129
  113. package/dist/{setup-TISPCO22.js → setup-RHJRFURI.js} +4 -4
  114. package/dist/skill-TAAKEYBV.js +389 -0
  115. package/dist/skills/plan-coordinator/SKILL.md +60 -0
  116. package/dist/skills/volute-mind/SKILL.md +9 -227
  117. package/dist/skills/volute-mind/references/extensions.md +34 -0
  118. package/dist/skills/volute-mind/references/integrations.md +48 -0
  119. package/dist/skills/volute-mind/references/routing.md +86 -0
  120. package/dist/skills/volute-mind/references/sleep.md +33 -0
  121. package/dist/skills/volute-mind/references/variants.md +31 -0
  122. package/dist/{skills-7FV7EJTE.js → skills-EKMCQ46K.js} +12 -8
  123. package/dist/sleep-manager-7KFK3USC.js +35 -0
  124. package/dist/spirit-ZFRDXMG7.js +23 -0
  125. package/dist/split-AWVOYOPZ.js +64 -0
  126. package/dist/{sprout-WKLZXUIQ.js → sprout-HE4TITMK.js} +3 -3
  127. package/dist/start-3UXOPXQG.js +39 -0
  128. package/dist/status-ZK34WYIM.js +125 -0
  129. package/dist/stop-3XYIBGFM.js +41 -0
  130. package/dist/system-chat-IDPHYHY4.js +35 -0
  131. package/dist/systems-O43WGQY6.js +52 -0
  132. package/dist/{tailscale-XHQBZROW.js → tailscale-ZIZ2HWJ5.js} +5 -5
  133. package/dist/template-hash-A7FNHTB7.js +9 -0
  134. package/dist/up-77ICEDEW.js +19 -0
  135. package/dist/update-ANE5ZM7F.js +225 -0
  136. package/dist/{update-check-ZD6OOIYQ.js → update-check-UV55CBEP.js} +4 -4
  137. package/dist/upgrade-ZMDGC7M2.js +74 -0
  138. package/dist/variant-QWL2WSRI.js +62 -0
  139. package/dist/{version-notify-NBI2MTJO.js → version-notify-FXSEMXWW.js} +29 -28
  140. package/dist/{volute-config-HD7WWUQC.js → volute-config-D2XVS2YI.js} +2 -2
  141. package/dist/web-assets/assets/index-BhxWKvbB.css +1 -0
  142. package/dist/web-assets/assets/index-CHVKJ9II.js +75 -0
  143. package/dist/web-assets/ext-theme.css +48 -9
  144. package/dist/web-assets/index.html +2 -2
  145. package/dist/web-assets/sw.js +117 -0
  146. package/drizzle/0005_meta_summaries.sql +15 -0
  147. package/drizzle/meta/0005_snapshot.json +7 -0
  148. package/drizzle/meta/_journal.json +7 -0
  149. package/package.json +10 -7
  150. package/packages/extensions/pages/dist/ui/assets/index-DKZLNMED.js +2 -0
  151. package/packages/extensions/pages/dist/ui/index.html +1 -1
  152. package/packages/extensions/pages/skills/pages/SKILL.md +84 -9
  153. package/packages/extensions/plan/dist/ui/assets/index-CJj2gZnZ.css +1 -0
  154. package/packages/extensions/plan/dist/ui/assets/index-FMEJmvQz.js +61 -0
  155. package/packages/extensions/plan/dist/ui/index.html +14 -0
  156. package/packages/extensions/plan/skills/plan/SKILL.md +43 -0
  157. package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +37 -0
  158. package/templates/_base/home/VOLUTE.md +12 -19
  159. package/templates/_base/src/lib/auto-commit.ts +8 -8
  160. package/templates/_base/src/lib/context-breakdown.ts +450 -0
  161. package/templates/_base/src/lib/format-prefix.ts +17 -0
  162. package/templates/_base/src/lib/hook-loader.ts +8 -2
  163. package/templates/_base/src/lib/router.ts +75 -33
  164. package/templates/_base/src/lib/routing.ts +4 -1
  165. package/templates/_base/src/lib/startup.ts +16 -8
  166. package/templates/_base/src/lib/types.ts +2 -1
  167. package/templates/_base/src/lib/volute-server.ts +75 -8
  168. package/templates/claude/.init/CLAUDE.md +4 -10
  169. package/templates/claude/package.json.tmpl +1 -0
  170. package/templates/claude/src/agent.ts +108 -33
  171. package/templates/claude/src/lib/hooks/reply-instructions.ts +27 -7
  172. package/templates/claude/src/lib/stream-consumer.ts +2 -2
  173. package/templates/claude/src/server.ts +1 -0
  174. package/templates/codex/package.json.tmpl +1 -0
  175. package/templates/codex/src/agent.ts +80 -8
  176. package/templates/codex/src/server.ts +1 -4
  177. package/templates/pi/package.json.tmpl +1 -0
  178. package/templates/pi/src/agent.ts +115 -36
  179. package/templates/pi/src/lib/event-handler.ts +22 -7
  180. package/templates/pi/src/lib/reply-instructions-extension.ts +23 -4
  181. package/templates/pi/src/lib/subagents.ts +20 -17
  182. package/templates/pi/src/server.ts +2 -5
  183. package/dist/accept-D5VBM7JW.js +0 -42
  184. package/dist/activity-events-XJO3P4RR.js +0 -15
  185. package/dist/bridge-TXWWPPOJ.js +0 -207
  186. package/dist/chat-U5ZOME3O.js +0 -68
  187. package/dist/chunk-3Z2DPESO.js +0 -3634
  188. package/dist/chunk-A2A4KLFE.js +0 -1528
  189. package/dist/chunk-K3NQKI34.js +0 -10
  190. package/dist/chunk-NPKSDYA2.js +0 -156
  191. package/dist/chunk-PB65JZK2.js +0 -85
  192. package/dist/clock-BVH3V6E3.js +0 -266
  193. package/dist/config-H2H4UIF7.js +0 -72
  194. package/dist/create-2FK7Z46Y.js +0 -44
  195. package/dist/create-YWD2TIP4.js +0 -71
  196. package/dist/daemon-client-6QXHZ7US.js +0 -12
  197. package/dist/daemon-restart-GOBUKLX7.js +0 -52
  198. package/dist/db-F34YLV7D.js +0 -9
  199. package/dist/db-RA45JBFG.js +0 -16
  200. package/dist/delete-QTGWEDBI.js +0 -35
  201. package/dist/delivery-manager-PFAKEJTC.js +0 -32
  202. package/dist/down-FWWTEKXM.js +0 -15
  203. package/dist/env-JCOF2222.js +0 -191
  204. package/dist/export-SUYRLI5Q.js +0 -112
  205. package/dist/extension-OBTGKQQD.js +0 -175
  206. package/dist/extensions-KYNTVTMO.js +0 -30
  207. package/dist/files-65PMW5IK.js +0 -47
  208. package/dist/history-DKCDI3JO.js +0 -128
  209. package/dist/import-DDUFE7AY.js +0 -23
  210. package/dist/join-I5QEE3LG.js +0 -66
  211. package/dist/list-JQ463EDA.js +0 -41
  212. package/dist/login-D7ETSU4R.js +0 -47
  213. package/dist/login-RIJF2F4G.js +0 -47
  214. package/dist/logout-5MLHZALK.js +0 -40
  215. package/dist/logout-UZJRGY4Z.js +0 -21
  216. package/dist/message-delivery-DFF5SJRM.js +0 -42
  217. package/dist/mind-IOJFLEM5.js +0 -108
  218. package/dist/mind-activity-tracker-F6O4Q2SL.js +0 -18
  219. package/dist/mind-list-WUPMQDYQ.js +0 -30
  220. package/dist/mind-manager-NBJF5D26.js +0 -32
  221. package/dist/mind-profile-P67FEHOY.js +0 -47
  222. package/dist/mind-service-2MQ6UK5N.js +0 -38
  223. package/dist/mind-sleep-WW2IX7JT.js +0 -42
  224. package/dist/mind-status-L3EFFRPR.js +0 -56
  225. package/dist/mind-wake-VSSGW465.js +0 -37
  226. package/dist/read-EBY56C33.js +0 -75
  227. package/dist/register-HD74C4TT.js +0 -47
  228. package/dist/reject-UJKFBHRO.js +0 -40
  229. package/dist/restart-3UCMRUVC.js +0 -33
  230. package/dist/scheduler-ZZ7XGQG6.js +0 -32
  231. package/dist/seed-check-S2IX25RL.js +0 -32
  232. package/dist/seed-cmd-DKOUFEAU.js +0 -36
  233. package/dist/seed-create-4XBBOLRH.js +0 -112
  234. package/dist/seed-sprout-GQEIIQRT.js +0 -132
  235. package/dist/send-QIV2INHB.js +0 -373
  236. package/dist/skill-PSQGRRJX.js +0 -358
  237. package/dist/skills/shared-files/SKILL.md +0 -44
  238. package/dist/skills/shared-files/scripts/merge.ts +0 -72
  239. package/dist/skills/shared-files/scripts/pull.ts +0 -52
  240. package/dist/sleep-manager-JTXSN7NV.js +0 -36
  241. package/dist/spirit-VRONKFMF.js +0 -23
  242. package/dist/split-STOROBYJ.js +0 -63
  243. package/dist/start-K2NCUUCG.js +0 -33
  244. package/dist/status-3JBTFSMI.js +0 -115
  245. package/dist/stop-H26JZDXF.js +0 -32
  246. package/dist/system-chat-JAPOJ3KE.js +0 -36
  247. package/dist/systems-XRI52VCH.js +0 -61
  248. package/dist/template-hash-A6VVKOXJ.js +0 -9
  249. package/dist/up-M5AS6SBV.js +0 -18
  250. package/dist/update-UD543CXX.js +0 -215
  251. package/dist/upgrade-O4Q7WJM3.js +0 -67
  252. package/dist/variant-7TGZHOU3.js +0 -41
  253. package/dist/web-assets/assets/index-CWJrVveV.css +0 -1
  254. package/dist/web-assets/assets/index-DJt14FRI.js +0 -75
  255. package/packages/extensions/pages/dist/ui/assets/index-tLTROSk5.js +0 -2
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env node
2
+
3
+ // packages/extensions/pages/src/db.ts
4
+ function initDb(db) {
5
+ db.exec(`
6
+ CREATE TABLE IF NOT EXISTS published_pages (
7
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
8
+ mind TEXT NOT NULL,
9
+ file TEXT NOT NULL,
10
+ published_at TEXT NOT NULL DEFAULT (datetime('now')),
11
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
12
+ author TEXT
13
+ );
14
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_pp_mind_file ON published_pages(mind, file);
15
+ CREATE INDEX IF NOT EXISTS idx_pp_updated_at ON published_pages(updated_at);
16
+ `);
17
+ try {
18
+ db.exec("ALTER TABLE published_pages ADD COLUMN author TEXT");
19
+ } catch (err) {
20
+ if (!(err instanceof Error) || !err.message.includes("duplicate column")) {
21
+ throw err;
22
+ }
23
+ }
24
+ }
25
+ function getPublishedPages(db, mind) {
26
+ return db.prepare(
27
+ "SELECT file, published_at, updated_at, author FROM published_pages WHERE mind = ? ORDER BY file"
28
+ ).all(mind);
29
+ }
30
+ function getRecentPages(db, opts) {
31
+ const limit = opts?.limit ?? 10;
32
+ if (opts?.mind) {
33
+ return db.prepare(
34
+ "SELECT mind, file, updated_at, author FROM published_pages WHERE mind = ? ORDER BY updated_at DESC LIMIT ?"
35
+ ).all(opts.mind, limit);
36
+ }
37
+ return db.prepare(
38
+ "SELECT mind, file, updated_at, author FROM published_pages ORDER BY updated_at DESC LIMIT ?"
39
+ ).all(limit);
40
+ }
41
+ function getAllSites(db) {
42
+ const rows = db.prepare(
43
+ "SELECT mind, file, updated_at, author FROM published_pages WHERE mind != '_system' ORDER BY mind, file"
44
+ ).all();
45
+ const siteMap = /* @__PURE__ */ new Map();
46
+ for (const row of rows) {
47
+ let files = siteMap.get(row.mind);
48
+ if (!files) {
49
+ files = [];
50
+ siteMap.set(row.mind, files);
51
+ }
52
+ files.push({ file: row.file, updated_at: row.updated_at, author: row.author });
53
+ }
54
+ return Array.from(siteMap.entries()).map(([mind, files]) => ({ mind, files }));
55
+ }
56
+ function getSystemPages(db) {
57
+ const rows = db.prepare(
58
+ "SELECT mind, file, updated_at, author FROM published_pages WHERE mind = '_system' ORDER BY file"
59
+ ).all();
60
+ if (rows.length === 0) return null;
61
+ return {
62
+ mind: "_system",
63
+ files: rows.map((r) => ({ file: r.file, updated_at: r.updated_at, author: r.author }))
64
+ };
65
+ }
66
+ function syncSystemPages(db, htmlFiles, author) {
67
+ const existing = new Set(
68
+ db.prepare("SELECT file FROM published_pages WHERE mind = '_system'").all().map((r) => r.file)
69
+ );
70
+ const newSet = new Set(htmlFiles);
71
+ db.exec("BEGIN");
72
+ try {
73
+ for (const file of htmlFiles) {
74
+ if (existing.has(file)) {
75
+ if (author) {
76
+ db.prepare(
77
+ "UPDATE published_pages SET updated_at = datetime('now'), author = ? WHERE mind = '_system' AND file = ?"
78
+ ).run(author, file);
79
+ } else {
80
+ db.prepare(
81
+ "UPDATE published_pages SET updated_at = datetime('now') WHERE mind = '_system' AND file = ?"
82
+ ).run(file);
83
+ }
84
+ } else {
85
+ db.prepare("INSERT INTO published_pages (mind, file, author) VALUES ('_system', ?, ?)").run(
86
+ file,
87
+ author ?? null
88
+ );
89
+ }
90
+ }
91
+ for (const file of existing) {
92
+ if (!newSet.has(file)) {
93
+ db.prepare("DELETE FROM published_pages WHERE mind = '_system' AND file = ?").run(file);
94
+ }
95
+ }
96
+ db.exec("COMMIT");
97
+ } catch (err) {
98
+ db.exec("ROLLBACK");
99
+ throw err;
100
+ }
101
+ }
102
+ function syncPublishedPages(db, mind, pageFiles) {
103
+ const existing = new Map(
104
+ db.prepare("SELECT file, updated_at FROM published_pages WHERE mind = ?").all(mind).map((r) => [r.file, r.updated_at])
105
+ );
106
+ const newSet = new Set(pageFiles);
107
+ const added = [];
108
+ const updated = [];
109
+ const removed = [];
110
+ db.exec("BEGIN");
111
+ try {
112
+ for (const file of pageFiles) {
113
+ if (existing.has(file)) {
114
+ db.prepare(
115
+ "UPDATE published_pages SET updated_at = datetime('now') WHERE mind = ? AND file = ?"
116
+ ).run(mind, file);
117
+ updated.push(file);
118
+ } else {
119
+ db.prepare("INSERT INTO published_pages (mind, file) VALUES (?, ?)").run(mind, file);
120
+ added.push(file);
121
+ }
122
+ }
123
+ for (const [file] of existing) {
124
+ if (!newSet.has(file)) {
125
+ db.prepare("DELETE FROM published_pages WHERE mind = ? AND file = ?").run(mind, file);
126
+ removed.push(file);
127
+ }
128
+ }
129
+ db.exec("COMMIT");
130
+ } catch (err) {
131
+ db.exec("ROLLBACK");
132
+ throw err;
133
+ }
134
+ return { added, removed, updated };
135
+ }
136
+
137
+ export {
138
+ initDb,
139
+ getPublishedPages,
140
+ getRecentPages,
141
+ getAllSites,
142
+ getSystemPages,
143
+ syncSystemPages,
144
+ syncPublishedPages
145
+ };
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  logger_default
4
- } from "./chunk-YUIHSKR6.js";
4
+ } from "./chunk-BKF4WQCY.js";
5
5
  import {
6
6
  mindDir
7
- } from "./chunk-LRCG2JLP.js";
7
+ } from "./chunk-BDYXIWA5.js";
8
8
 
9
- // src/lib/delivery/delivery-router.ts
9
+ // packages/daemon/src/lib/delivery/delivery-router.ts
10
10
  import { readFileSync, statSync } from "fs";
11
11
  import { resolve } from "path";
12
12
  function extractTextContent(content) {
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ parseArgs
4
+ } from "./chunk-O7IGP7ZW.js";
5
+
6
+ // packages/cli/src/lib/command.ts
7
+ function command(def) {
8
+ function printHelp() {
9
+ const argParts = (def.args ?? []).map((a) => a.required ? `<${a.name}>` : `[${a.name}]`);
10
+ const hasFlags = Object.keys(def.flags).length > 0;
11
+ const flagPart = hasFlags ? " [options]" : "";
12
+ const argStr = argParts.length > 0 ? ` ${argParts.join(" ")}` : "";
13
+ console.log(`${def.description}
14
+ `);
15
+ console.log(`Usage: ${def.name}${argStr}${flagPart}
16
+ `);
17
+ if (def.args && def.args.length > 0) {
18
+ console.log("Arguments:");
19
+ const nameWidth = Math.max(...def.args.map((a) => a.name.length + 2));
20
+ for (const a of def.args) {
21
+ const label = a.required ? `<${a.name}>` : `[${a.name}]`;
22
+ console.log(` ${label.padEnd(nameWidth + 2)} ${a.description}`);
23
+ }
24
+ console.log("");
25
+ }
26
+ if (hasFlags) {
27
+ console.log("Options:");
28
+ const entries = Object.entries(def.flags);
29
+ const nameWidth = Math.max(
30
+ ...entries.map(([k, v]) => {
31
+ const valueHint = v.type === "boolean" ? "" : ` <${v.type === "string" ? "value" : "n"}>`;
32
+ return `--${k}${valueHint}`.length;
33
+ })
34
+ );
35
+ for (const [key, val] of entries) {
36
+ const valueHint = val.type === "boolean" ? "" : ` <${val.type === "string" ? "value" : "n"}>`;
37
+ const flag = `--${key}${valueHint}`;
38
+ console.log(` ${flag.padEnd(nameWidth + 2)} ${val.description}`);
39
+ }
40
+ console.log("");
41
+ }
42
+ if (def.examples && def.examples.length > 0) {
43
+ console.log("Examples:");
44
+ for (const ex of def.examples) {
45
+ console.log(` ${ex}`);
46
+ }
47
+ console.log("");
48
+ }
49
+ }
50
+ async function execute(argv) {
51
+ const parseFlags = {};
52
+ for (const [key, val] of Object.entries(def.flags)) {
53
+ parseFlags[key] = { type: val.type };
54
+ }
55
+ const { positional, flags, help } = parseArgs(argv, parseFlags);
56
+ if (help) {
57
+ printHelp();
58
+ process.exit(0);
59
+ }
60
+ const namedArgs = {};
61
+ const argDefs = def.args ?? [];
62
+ for (let i = 0; i < argDefs.length; i++) {
63
+ namedArgs[argDefs[i].name] = positional[i];
64
+ }
65
+ for (const argDef of argDefs) {
66
+ if (argDef.required && !namedArgs[argDef.name]) {
67
+ console.error(`Missing required argument: <${argDef.name}>`);
68
+ printHelp();
69
+ process.exit(1);
70
+ }
71
+ }
72
+ const rest = positional.slice(argDefs.length);
73
+ await def.run({ args: namedArgs, flags, rest });
74
+ }
75
+ return { execute, printHelp };
76
+ }
77
+ function subcommands(def) {
78
+ function printHelp() {
79
+ console.log(`${def.description}
80
+ `);
81
+ console.log(`Usage: ${def.name} <command> [options]
82
+ `);
83
+ console.log("Commands:");
84
+ const entries = Object.entries(def.commands);
85
+ const nameWidth = Math.max(...entries.map(([k]) => k.length));
86
+ for (const [name, sub] of entries) {
87
+ console.log(` ${name.padEnd(nameWidth + 2)} ${sub.description}`);
88
+ }
89
+ if (def.footer) {
90
+ console.log(`
91
+ ${def.footer}`);
92
+ }
93
+ console.log("");
94
+ }
95
+ async function execute(argv) {
96
+ const sub = argv[0];
97
+ if (!sub || sub === "--help" || sub === "-h") {
98
+ printHelp();
99
+ if (!sub) process.exit(1);
100
+ process.exit(0);
101
+ }
102
+ const entry = def.commands[sub];
103
+ if (!entry) {
104
+ console.error(`Unknown command: ${def.name} ${sub}`);
105
+ printHelp();
106
+ process.exit(1);
107
+ }
108
+ await entry.run(argv.slice(1));
109
+ }
110
+ return { execute, printHelp };
111
+ }
112
+
113
+ export {
114
+ command,
115
+ subcommands
116
+ };
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  getBaseName,
4
4
  validateMindName
5
- } from "./chunk-LRCG2JLP.js";
5
+ } from "./chunk-BDYXIWA5.js";
6
6
 
7
- // src/lib/isolation.ts
7
+ // packages/daemon/src/lib/isolation.ts
8
8
  import { execFileSync } from "child_process";
9
9
  function isIsolationEnabled() {
10
10
  return process.env.VOLUTE_ISOLATION === "user";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/lib/prompt.ts
3
+ // packages/cli/src/lib/prompt.ts
4
4
  function rawPrompt(prompt, echo) {
5
5
  process.stderr.write(prompt);
6
6
  return new Promise((resolve) => {
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getServiceMode,
4
+ modeLabel,
5
+ pollHealth,
6
+ startService
7
+ } from "./chunk-2TGZJFAT.js";
8
+ import {
9
+ command
10
+ } from "./chunk-TXSA4Q3V.js";
11
+ import {
12
+ readGlobalConfig
13
+ } from "./chunk-BMZQYACC.js";
14
+ import {
15
+ voluteHome,
16
+ voluteSystemDir
17
+ } from "./chunk-BDYXIWA5.js";
18
+
19
+ // src/commands/up.ts
20
+ import { spawn } from "child_process";
21
+ import { existsSync, mkdirSync, openSync, readFileSync } from "fs";
22
+ import { dirname, resolve } from "path";
23
+ var cmd = command({
24
+ name: "volute up",
25
+ description: "Start the daemon",
26
+ flags: {
27
+ port: { type: "number", description: "Port to listen on (default 1618)" },
28
+ host: { type: "string", description: "Host to bind to (default 127.0.0.1)" },
29
+ foreground: { type: "boolean", description: "Run in the foreground" },
30
+ "no-sandbox": { type: "boolean", description: "Disable sandbox mode" },
31
+ tailscale: { type: "boolean", description: "Enable Tailscale TLS" }
32
+ },
33
+ run: async ({ flags }) => {
34
+ const mode = getServiceMode();
35
+ if (!flags.foreground && mode !== "manual") {
36
+ console.log(`Starting volute (${modeLabel(mode)})...`);
37
+ try {
38
+ await startService(mode);
39
+ } catch (err) {
40
+ console.error(`Failed to start service: ${err instanceof Error ? err.message : err}`);
41
+ process.exit(1);
42
+ }
43
+ const config2 = readGlobalConfig();
44
+ const h = flags.host ?? config2.hostname ?? "127.0.0.1";
45
+ const p = flags.port ?? config2.port ?? 1618;
46
+ if (await pollHealth(h, p)) {
47
+ console.log(`Volute daemon running on ${h}:${p}`);
48
+ } else {
49
+ console.error("Service started but daemon did not become healthy within 30s.");
50
+ process.exit(1);
51
+ }
52
+ return;
53
+ }
54
+ const config = readGlobalConfig();
55
+ const port = flags.port ?? config.port ?? 1618;
56
+ const hostname = flags.host ?? config.hostname ?? "127.0.0.1";
57
+ const home = voluteHome();
58
+ const systemDir = voluteSystemDir();
59
+ const pidPath = resolve(systemDir, "daemon.pid");
60
+ if (existsSync(pidPath)) {
61
+ try {
62
+ const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
63
+ process.kill(pid, 0);
64
+ console.error(`Daemon already running (pid ${pid}). Use 'volute down' first.`);
65
+ process.exit(1);
66
+ } catch (err) {
67
+ if (err.code !== "ESRCH") {
68
+ console.error(`Warning: could not check PID file: ${err.message}`);
69
+ }
70
+ }
71
+ }
72
+ const pollHost = hostname === "0.0.0.0" || hostname === "::" ? "localhost" : hostname;
73
+ let tailscaleHostname;
74
+ if (flags.tailscale) {
75
+ try {
76
+ const { execFile } = await import("child_process");
77
+ const { promisify } = await import("util");
78
+ const execFileAsync = promisify(execFile);
79
+ const { stdout } = await execFileAsync("tailscale", ["status", "--json"]);
80
+ const status = JSON.parse(stdout);
81
+ tailscaleHostname = status.Self?.DNSName?.replace(/\.$/, "");
82
+ } catch (err) {
83
+ console.error(`Tailscale setup failed: ${err instanceof Error ? err.message : err}`);
84
+ process.exit(1);
85
+ }
86
+ }
87
+ try {
88
+ const res = await fetch(`http://${pollHost}:${port}/api/health`);
89
+ if (res.ok) {
90
+ const body = await res.json().catch(() => null);
91
+ if (body && body.ok) {
92
+ console.error(
93
+ `Port ${port} is already in use by a Volute daemon. Use 'volute down' first, or kill the process on that port.`
94
+ );
95
+ process.exit(1);
96
+ }
97
+ }
98
+ } catch {
99
+ }
100
+ if (flags["no-sandbox"]) {
101
+ process.env.VOLUTE_SANDBOX = "0";
102
+ }
103
+ if (flags.foreground) {
104
+ const { startDaemon } = await import("./daemon.js");
105
+ await startDaemon({ port, hostname, foreground: true, tailscale: flags.tailscale });
106
+ return;
107
+ }
108
+ const daemonModule = resolve(dirname(new URL(import.meta.url).pathname), "daemon.js");
109
+ if (!existsSync(daemonModule)) {
110
+ console.error("Could not find daemon module. Run `npm run build` first.");
111
+ process.exit(1);
112
+ }
113
+ mkdirSync(home, { recursive: true });
114
+ mkdirSync(systemDir, { recursive: true });
115
+ const logFile = resolve(systemDir, "daemon.log");
116
+ const logFd = openSync(logFile, "a");
117
+ const daemonArgs = [daemonModule, "--port", String(port), "--host", hostname];
118
+ if (flags.tailscale) daemonArgs.push("--tailscale");
119
+ if (flags["no-sandbox"]) daemonArgs.push("--no-sandbox");
120
+ const child = spawn(process.execPath, daemonArgs, {
121
+ stdio: ["ignore", "ignore", logFd],
122
+ detached: true
123
+ });
124
+ child.unref();
125
+ const pollPort = flags.tailscale ? port + 1 : port;
126
+ const url = `http://localhost:${pollPort}/api/health`;
127
+ const maxWait = 3e4;
128
+ const start = Date.now();
129
+ while (Date.now() - start < maxWait) {
130
+ try {
131
+ const res = await fetch(url);
132
+ if (res.ok) {
133
+ const displayHost = tailscaleHostname ?? hostname;
134
+ const displayProto = flags.tailscale ? "https" : "http";
135
+ console.log(
136
+ `Volute daemon running on ${displayProto}://${displayHost}:${port} (pid ${child.pid})`
137
+ );
138
+ console.log(`Logs: ${logFile}`);
139
+ return;
140
+ }
141
+ } catch {
142
+ }
143
+ await new Promise((r) => setTimeout(r, 500));
144
+ }
145
+ if (child.pid) {
146
+ try {
147
+ process.kill(-child.pid, "SIGTERM");
148
+ } catch {
149
+ try {
150
+ process.kill(child.pid, "SIGTERM");
151
+ } catch {
152
+ }
153
+ }
154
+ }
155
+ console.error("Daemon started but did not become healthy within 30s.");
156
+ console.error(`Check logs: ${logFile}`);
157
+ process.exit(1);
158
+ }
159
+ });
160
+ var run = cmd.execute;
161
+
162
+ export {
163
+ run
164
+ };