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
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  subscribe
4
- } from "./chunk-KVK2DLWI.js";
4
+ } from "./chunk-CORXD635.js";
5
5
  import {
6
6
  logger_default
7
- } from "./chunk-YUIHSKR6.js";
7
+ } from "./chunk-BKF4WQCY.js";
8
8
  import {
9
9
  getDb
10
- } from "./chunk-LRCG2JLP.js";
10
+ } from "./chunk-BDYXIWA5.js";
11
11
  import {
12
12
  conversationParticipants,
13
13
  conversationReads,
14
14
  conversations,
15
15
  messages,
16
16
  users
17
- } from "./chunk-RPZZSXV3.js";
17
+ } from "./chunk-5N7Y5WAM.js";
18
18
 
19
- // src/lib/events/conversations.ts
19
+ // packages/daemon/src/lib/events/conversations.ts
20
20
  import { randomUUID } from "crypto";
21
21
  import { and, desc, eq, inArray, isNull, lt, sql } from "drizzle-orm";
22
22
 
23
- // src/lib/webhook.ts
23
+ // packages/daemon/src/lib/webhook.ts
24
24
  var slog = logger_default.child("webhook");
25
25
  function getWebhookUrl() {
26
26
  return process.env.VOLUTE_WEBHOOK_URL;
@@ -82,7 +82,7 @@ function initWebhook() {
82
82
  });
83
83
  }
84
84
 
85
- // src/lib/events/conversation-events.ts
85
+ // packages/daemon/src/lib/events/conversation-events.ts
86
86
  var subscribers = /* @__PURE__ */ new Map();
87
87
  function subscribe2(conversationId, callback) {
88
88
  let set = subscribers.get(conversationId);
@@ -110,32 +110,30 @@ function publish(conversationId, event) {
110
110
  }
111
111
  }
112
112
 
113
- // src/lib/events/conversations.ts
113
+ // packages/daemon/src/lib/events/conversations.ts
114
114
  async function createConversation(mindName, channel, opts) {
115
115
  const db = await getDb();
116
116
  const id = randomUUID();
117
117
  const type = opts?.type ?? "dm";
118
118
  const name = opts?.name ?? null;
119
- await db.transaction(async (tx) => {
120
- await tx.insert(conversations).values({
121
- id,
122
- mind_name: mindName,
123
- channel,
124
- type,
125
- name,
126
- user_id: opts?.userId ?? null,
127
- title: opts?.title ?? null
128
- });
129
- if (opts?.participantIds && opts.participantIds.length > 0) {
130
- await tx.insert(conversationParticipants).values(
131
- opts.participantIds.map((uid, i) => ({
132
- conversation_id: id,
133
- user_id: uid,
134
- role: i === 0 ? "owner" : "member"
135
- }))
136
- );
137
- }
119
+ await db.insert(conversations).values({
120
+ id,
121
+ mind_name: mindName,
122
+ channel,
123
+ type,
124
+ name,
125
+ user_id: opts?.userId ?? null,
126
+ title: opts?.title ?? null
138
127
  });
128
+ if (opts?.participantIds && opts.participantIds.length > 0) {
129
+ await db.insert(conversationParticipants).values(
130
+ opts.participantIds.map((uid, i) => ({
131
+ conversation_id: id,
132
+ user_id: uid,
133
+ role: i === 0 ? "owner" : "member"
134
+ }))
135
+ );
136
+ }
139
137
  fireWebhook({
140
138
  event: "conversation_created",
141
139
  mind: mindName ?? "",
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  broadcast
4
- } from "./chunk-KVK2DLWI.js";
4
+ } from "./chunk-CORXD635.js";
5
5
  import {
6
6
  getDb
7
- } from "./chunk-LRCG2JLP.js";
7
+ } from "./chunk-BDYXIWA5.js";
8
8
  import {
9
9
  users
10
- } from "./chunk-RPZZSXV3.js";
10
+ } from "./chunk-5N7Y5WAM.js";
11
11
 
12
- // src/lib/auth.ts
12
+ // packages/daemon/src/lib/auth.ts
13
13
  import { compareSync, hashSync } from "bcryptjs";
14
14
  import { and, count, eq, or } from "drizzle-orm";
15
15
  var userSelectFields = {
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/lib/volute-config.ts
3
+ // packages/daemon/src/lib/volute-config.ts
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
5
5
  import { dirname, resolve } from "path";
6
6
  function readJson(path) {
@@ -1,12 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- voluteSystemDir,
4
- voluteUserHome
5
- } from "./chunk-LRCG2JLP.js";
6
2
 
7
- // src/lib/daemon-client.ts
3
+ // packages/cli/src/lib/daemon-client.ts
8
4
  import { existsSync, readFileSync } from "fs";
5
+ import { homedir } from "os";
9
6
  import { resolve } from "path";
7
+ function voluteUserHome() {
8
+ return process.env.VOLUTE_USER_HOME ?? resolve(homedir(), ".volute");
9
+ }
10
+ function voluteSystemDir() {
11
+ const home = process.env.VOLUTE_HOME ?? resolve(homedir(), ".volute");
12
+ return resolve(home, "system");
13
+ }
10
14
  function readSessionFile(mindDir) {
11
15
  try {
12
16
  const p = resolve(mindDir, ".mind", "current-session");
@@ -70,9 +74,14 @@ function buildUrl(config) {
70
74
  }
71
75
  return url.origin;
72
76
  }
77
+ function resolveDaemonUrl() {
78
+ if (process.env.VOLUTE_DAEMON_URL) return process.env.VOLUTE_DAEMON_URL;
79
+ const session = readCliSession();
80
+ if (session?.daemonUrl) return session.daemonUrl;
81
+ return buildUrl(readDaemonConfig());
82
+ }
73
83
  async function daemonFetch(path, options) {
74
- const config = readDaemonConfig();
75
- const url = buildUrl(config);
84
+ const url = resolveDaemonUrl();
76
85
  const headers = new Headers(options?.headers);
77
86
  const daemonToken = process.env.VOLUTE_DAEMON_TOKEN;
78
87
  const cliSession = daemonToken ? null : readCliSession();
@@ -108,5 +117,6 @@ async function daemonFetch(path, options) {
108
117
 
109
118
  export {
110
119
  readSessionFile,
120
+ resolveDaemonUrl,
111
121
  daemonFetch
112
122
  };
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ if (!process.env.VOLUTE_HOME) {
10
10
  var command = process.argv[2];
11
11
  var args = process.argv.slice(3);
12
12
  if (command === "--version" || command === "-v") {
13
- const { default: pkg } = await import("./package-U3VFO273.js");
13
+ const { default: pkg } = await import("./package-D2FSVFAX.js");
14
14
  console.log(pkg.version);
15
15
  process.exit(0);
16
16
  }
@@ -31,7 +31,7 @@ var ungatedCommands = /* @__PURE__ */ new Set([
31
31
  void 0
32
32
  ]);
33
33
  if (!ungatedCommands.has(command)) {
34
- const { isSetupComplete } = await import("./setup-TISPCO22.js");
34
+ const { isSetupComplete } = await import("./setup-RHJRFURI.js");
35
35
  if (!isSetupComplete()) {
36
36
  console.error("Volute is not set up. Run `volute setup` first.");
37
37
  process.exit(1);
@@ -39,58 +39,61 @@ if (!ungatedCommands.has(command)) {
39
39
  }
40
40
  switch (command) {
41
41
  case "setup":
42
- await import("./setup-XMCBE3LF.js").then((m) => m.run(args));
42
+ await import("./setup-BJ4YAY26.js").then((m) => m.run(args));
43
43
  break;
44
44
  case "mind":
45
- await import("./mind-IOJFLEM5.js").then((m) => m.run(args));
45
+ await import("./mind-5IEYKV7I.js").then((m) => m.run(args));
46
46
  break;
47
47
  case "seed":
48
- await import("./seed-cmd-DKOUFEAU.js").then((m) => m.run(args));
48
+ await import("./seed-cmd-ZM2XGVU2.js").then((m) => m.run(args));
49
49
  break;
50
50
  case "chat":
51
- await import("./chat-U5ZOME3O.js").then((m) => m.run(args));
51
+ await import("./chat-QXAJF3FU.js").then((m) => m.run(args));
52
52
  break;
53
53
  case "variant":
54
- await import("./variant-7TGZHOU3.js").then((m) => m.run(args));
54
+ await import("./variant-QWL2WSRI.js").then((m) => m.run(args));
55
55
  break;
56
56
  case "clock":
57
- await import("./clock-BVH3V6E3.js").then((m) => m.run(args));
57
+ await import("./clock-HSEKS5AR.js").then((m) => m.run(args));
58
58
  break;
59
59
  case "skill":
60
- await import("./skill-PSQGRRJX.js").then((m) => m.run(args));
60
+ await import("./skill-TAAKEYBV.js").then((m) => m.run(args));
61
61
  break;
62
62
  case "env":
63
- await import("./env-JCOF2222.js").then((m) => m.run(args));
63
+ await import("./env-E4XHO2BI.js").then((m) => m.run(args));
64
64
  break;
65
65
  case "config":
66
- await import("./config-H2H4UIF7.js").then((m) => m.run(args));
66
+ await import("./config-UTS7QULS.js").then((m) => m.run(args));
67
67
  break;
68
68
  case "up":
69
- await import("./up-M5AS6SBV.js").then((m) => m.run(args));
69
+ await import("./up-77ICEDEW.js").then((m) => m.run(args));
70
70
  break;
71
71
  case "down":
72
- await import("./down-FWWTEKXM.js").then((m) => m.run(args));
72
+ await import("./down-74VXM45A.js").then((m) => m.run(args));
73
73
  break;
74
74
  case "restart":
75
- await import("./daemon-restart-GOBUKLX7.js").then((m) => m.run(args));
75
+ await import("./daemon-restart-HSZ3BCX5.js").then((m) => m.run(args));
76
76
  break;
77
77
  case "update":
78
- await import("./update-UD543CXX.js").then((m) => m.run(args));
78
+ await import("./update-ANE5ZM7F.js").then((m) => m.run(args));
79
79
  break;
80
80
  case "status":
81
- await import("./status-3JBTFSMI.js").then((m) => m.run(args));
81
+ await import("./status-ZK34WYIM.js").then((m) => m.run(args));
82
82
  break;
83
83
  case "extension":
84
- await import("./extension-OBTGKQQD.js").then((m) => m.run(args));
84
+ await import("./extension-D74CNM7G.js").then((m) => m.run(args));
85
85
  break;
86
86
  case "systems":
87
- await import("./systems-XRI52VCH.js").then((m) => m.run(args));
87
+ await import("./systems-O43WGQY6.js").then((m) => m.run(args));
88
88
  break;
89
89
  case "login":
90
- await import("./login-RIJF2F4G.js").then((m) => m.run(args));
90
+ await import("./login-7TE6CIZF.js").then((m) => m.run(args));
91
91
  break;
92
92
  case "logout":
93
- await import("./logout-5MLHZALK.js").then((m) => m.run(args));
93
+ await import("./logout-T4XS6LRU.js").then((m) => m.run(args));
94
+ break;
95
+ case "service":
96
+ await import("./service-WNPCNHOX.js").then((m) => m.run(args));
94
97
  break;
95
98
  case "--help":
96
99
  case "-h":
@@ -133,7 +136,7 @@ System:
133
136
 
134
137
  Extensions:
135
138
  notes write/list/read/... Manage notes
136
- pages notify Notify page updates
139
+ pages publish/list/pull/log Manage pages
137
140
 
138
141
  Options:
139
142
  --version, -v Show version number
@@ -147,22 +150,80 @@ use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
147
150
  default: {
148
151
  let isExtensionCommand = false;
149
152
  try {
150
- const { daemonFetch } = await import("./daemon-client-6QXHZ7US.js");
153
+ const { daemonFetch } = await import("./daemon-client-RVIKXGFQ.js");
151
154
  const res = await daemonFetch("/api/extensions/commands");
152
155
  if (res.ok) {
153
156
  const extCommands = await res.json();
154
157
  if (command && command in extCommands) {
155
158
  isExtensionCommand = true;
156
- const subcommand = args[0];
157
159
  const ext = extCommands[command];
158
- if (!subcommand || !(subcommand in ext.commands)) {
159
- console.log(`volute ${command} \u2014 ${Object.keys(ext.commands).join(", ")}
160
+ const subcommand = args[0];
161
+ const wantsHelp = args.includes("--help") || args.includes("-h");
162
+ if (!subcommand || wantsHelp && !(subcommand in ext.commands)) {
163
+ console.log(`Manage ${command}
164
+ `);
165
+ console.log(`Usage: volute ${command} <command> [options]
160
166
  `);
161
- for (const [name, meta] of Object.entries(ext.commands)) {
162
- console.log(` ${name.padEnd(12)} ${meta.description}`);
167
+ console.log("Commands:");
168
+ const entries = Object.entries(ext.commands);
169
+ const nameWidth = Math.max(...entries.map(([k]) => k.length));
170
+ for (const [name, meta] of entries) {
171
+ console.log(` ${name.padEnd(nameWidth + 2)} ${meta.description}`);
172
+ }
173
+ console.log(`
174
+ Use --mind <name> or VOLUTE_MIND to specify the mind.
175
+ `);
176
+ process.exit(subcommand ? 0 : 1);
177
+ }
178
+ if (wantsHelp && subcommand in ext.commands) {
179
+ const meta = ext.commands[subcommand];
180
+ const argParts = (meta.args ?? []).map(
181
+ (a) => a.required ? `<${a.name}>` : `[${a.name}]`
182
+ );
183
+ const flagEntries = Object.entries(meta.flags ?? {});
184
+ const flagPart = flagEntries.length > 0 ? " [options]" : "";
185
+ const argStr = argParts.length > 0 ? ` ${argParts.join(" ")}` : "";
186
+ console.log(`${meta.description}
187
+ `);
188
+ console.log(`Usage: volute ${command} ${subcommand}${argStr}${flagPart}
189
+ `);
190
+ if (meta.args && meta.args.length > 0) {
191
+ console.log("Arguments:");
192
+ const w = Math.max(...meta.args.map((a) => a.name.length + 2));
193
+ for (const a of meta.args) {
194
+ const label = a.required ? `<${a.name}>` : `[${a.name}]`;
195
+ console.log(` ${label.padEnd(w + 2)} ${a.description}`);
196
+ }
197
+ console.log("");
198
+ }
199
+ if (flagEntries.length > 0) {
200
+ console.log("Options:");
201
+ const w = Math.max(
202
+ ...flagEntries.map(([k, v]) => {
203
+ const hint = v.type === "boolean" ? "" : ` <${v.type === "string" ? "value" : "n"}>`;
204
+ return `--${k}${hint}`.length;
205
+ })
206
+ );
207
+ for (const [key, val] of flagEntries) {
208
+ const hint = val.type === "boolean" ? "" : ` <${val.type === "string" ? "value" : "n"}>`;
209
+ const flag = `--${key}${hint}`;
210
+ console.log(` ${flag.padEnd(w + 2)} ${val.description}`);
211
+ }
212
+ console.log("");
213
+ }
214
+ if (meta.examples && meta.examples.length > 0) {
215
+ console.log("Examples:");
216
+ for (const ex of meta.examples) {
217
+ console.log(` ${ex}`);
218
+ }
219
+ console.log("");
163
220
  }
164
221
  process.exit(0);
165
222
  }
223
+ if (!(subcommand in ext.commands)) {
224
+ console.error(`Unknown command: volute ${command} ${subcommand}`);
225
+ process.exit(1);
226
+ }
166
227
  const cmdArgs = args.slice(1);
167
228
  let mind = process.env.VOLUTE_MIND;
168
229
  const mindIdx = cmdArgs.indexOf("--mind");
@@ -170,7 +231,7 @@ use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
170
231
  mind = cmdArgs[mindIdx + 1];
171
232
  cmdArgs.splice(mindIdx, 2);
172
233
  }
173
- const { readStdin } = await import("./read-stdin-HQJ7774D.js");
234
+ const { readStdin } = await import("./read-stdin-3X5VYKNS.js");
174
235
  const stdin = await readStdin();
175
236
  const cmdRes = await daemonFetch(`/api/ext/${command}/commands/${subcommand}`, {
176
237
  method: "POST",
@@ -203,7 +264,7 @@ Run 'volute --help' for usage.`);
203
264
  }
204
265
  }
205
266
  if (command !== "update") {
206
- import("./update-check-ZD6OOIYQ.js").then((m) => m.checkForUpdate()).then((result) => {
267
+ import("./update-check-UV55CBEP.js").then((m) => m.checkForUpdate()).then((result) => {
207
268
  if (result.updateAvailable) {
208
269
  console.error(`
209
270
  Update available: ${result.current} \u2192 ${result.latest}`);
@@ -0,0 +1,289 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ compactDateTime,
4
+ isCompact
5
+ } from "./chunk-5T5YMX6S.js";
6
+ import {
7
+ resolveMindName
8
+ } from "./chunk-BTY4WNFE.js";
9
+ import {
10
+ command,
11
+ subcommands
12
+ } from "./chunk-TXSA4Q3V.js";
13
+ import "./chunk-O7IGP7ZW.js";
14
+ import {
15
+ daemonFetch
16
+ } from "./chunk-ZX7EAV5J.js";
17
+ import {
18
+ getClient,
19
+ urlOf
20
+ } from "./chunk-LOPXTW6H.js";
21
+ import "./chunk-7KJOFUNN.js";
22
+
23
+ // packages/cli/src/commands/clock.ts
24
+ import { CronExpressionParser } from "cron-parser";
25
+ function parseDuration(input) {
26
+ const parts = input.match(/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/);
27
+ if (!parts || parts[0] !== input) return null;
28
+ const hours = parseInt(parts[1] || "0", 10);
29
+ const minutes = parseInt(parts[2] || "0", 10);
30
+ const seconds = parseInt(parts[3] || "0", 10);
31
+ const total = hours * 36e5 + minutes * 6e4 + seconds * 1e3;
32
+ return total > 0 ? total : null;
33
+ }
34
+ var clockStatusCmd = command({
35
+ name: "volute clock status",
36
+ description: "Show sleep state and upcoming events",
37
+ flags: {
38
+ mind: { type: "string", description: "Mind name" }
39
+ },
40
+ run: async ({ flags }) => {
41
+ const mind = resolveMindName(flags);
42
+ const client = getClient();
43
+ const res = await daemonFetch(
44
+ urlOf(client.api.minds[":name"].clock.status.$url({ param: { name: mind } }))
45
+ );
46
+ if (!res.ok) {
47
+ const data = await res.json();
48
+ console.error(data.error ?? `Failed to get clock status: ${res.status}`);
49
+ process.exit(1);
50
+ }
51
+ const status = await res.json();
52
+ const compact = isCompact();
53
+ const fmtTime = (s) => compact ? compactDateTime(s) : new Date(s).toLocaleString();
54
+ if (status.sleep?.sleeping) {
55
+ const since = status.sleep.sleepingSince ? fmtTime(status.sleep.sleepingSince) : "unknown";
56
+ console.log(`Sleep: sleeping since ${since}`);
57
+ if (status.sleep.scheduledWakeAt) {
58
+ console.log(` Wake at: ${fmtTime(status.sleep.scheduledWakeAt)}`);
59
+ }
60
+ if (status.sleep.voluntaryWakeAt) {
61
+ console.log(` Voluntary wake at: ${fmtTime(status.sleep.voluntaryWakeAt)}`);
62
+ }
63
+ if (status.sleep.queuedMessageCount > 0) {
64
+ console.log(` Queued messages: ${status.sleep.queuedMessageCount}`);
65
+ }
66
+ } else {
67
+ console.log("Sleep: awake");
68
+ }
69
+ if (status.sleepConfig?.enabled && status.sleepConfig.schedule) {
70
+ console.log(
71
+ ` Schedule: sleep ${status.sleepConfig.schedule.sleep}, wake ${status.sleepConfig.schedule.wake}`
72
+ );
73
+ }
74
+ if (status.upcoming.length > 0) {
75
+ if (!compact) console.log("");
76
+ console.log("Upcoming (next 24h):");
77
+ for (const u of status.upcoming) {
78
+ const time = fmtTime(u.at);
79
+ const label = u.type === "timer" ? "[timer]" : "[cron]";
80
+ console.log(` ${u.id.padEnd(20)} ${label} ${time}`);
81
+ }
82
+ } else {
83
+ if (!compact) console.log("");
84
+ console.log("No upcoming events in next 24h.");
85
+ }
86
+ if (!compact) {
87
+ console.log(`
88
+ ${status.schedules.length} schedule(s) configured.`);
89
+ }
90
+ }
91
+ });
92
+ var listSchedulesCmd = command({
93
+ name: "volute clock list",
94
+ description: "List schedules and timers",
95
+ flags: {
96
+ mind: { type: "string", description: "Mind name" }
97
+ },
98
+ run: async ({ flags }) => {
99
+ const mind = resolveMindName(flags);
100
+ const client = getClient();
101
+ const res = await daemonFetch(
102
+ urlOf(client.api.minds[":name"].schedules.$url({ param: { name: mind } }))
103
+ );
104
+ if (!res.ok) {
105
+ const data = await res.json();
106
+ console.error(data.error ?? `Failed to list schedules: ${res.status}`);
107
+ process.exit(1);
108
+ }
109
+ const schedules = await res.json();
110
+ if (schedules.length === 0) {
111
+ console.log("No schedules configured.");
112
+ return;
113
+ }
114
+ const actionLabel = (s) => s.script ? `[script] ${s.script}` : s.message ?? "";
115
+ if (isCompact()) {
116
+ for (const s of schedules) {
117
+ const sched = s.cron ?? (s.fireAt ? `at ${s.fireAt}` : "");
118
+ console.log(`${s.id} ${sched} ${actionLabel(s)}`);
119
+ }
120
+ } else {
121
+ const idW = Math.max(2, ...schedules.map((s) => s.id.length));
122
+ const schedW = Math.max(8, ...schedules.map((s) => (s.cron ?? s.fireAt ?? "").length));
123
+ console.log(`${"ID".padEnd(idW)} ${"SCHEDULE".padEnd(schedW)} ENABLED ACTION`);
124
+ for (const s of schedules) {
125
+ const sched = s.cron ?? (s.fireAt ? `at ${s.fireAt}` : "");
126
+ console.log(
127
+ `${s.id.padEnd(idW)} ${sched.padEnd(schedW)} ${String(s.enabled).padEnd(7)} ${actionLabel(s)}`
128
+ );
129
+ }
130
+ }
131
+ }
132
+ });
133
+ var addScheduleCmd = command({
134
+ name: "volute clock add",
135
+ description: "Add a schedule or timer",
136
+ flags: {
137
+ mind: { type: "string", description: "Mind name" },
138
+ cron: { type: "string", description: "Cron expression" },
139
+ in: { type: "string", description: "Duration (e.g. 30s, 10m, 1h)" },
140
+ message: { type: "string", description: "Message to send" },
141
+ script: { type: "string", description: "Script to run" },
142
+ id: { type: "string", description: "Schedule ID (required)" },
143
+ session: { type: "string", description: "Session name" },
144
+ "while-sleeping": {
145
+ type: "string",
146
+ description: "Behavior during sleep (skip, queue, trigger-wake)"
147
+ }
148
+ },
149
+ run: async ({ flags }) => {
150
+ const mind = resolveMindName(flags);
151
+ if (!flags.id) {
152
+ console.error("--id is required (a descriptive name for this schedule)");
153
+ process.exit(1);
154
+ }
155
+ if (!flags.cron && !flags.in) {
156
+ console.error("--cron or --in is required");
157
+ process.exit(1);
158
+ }
159
+ if (flags.cron && flags.in) {
160
+ console.error("--cron and --in are mutually exclusive");
161
+ process.exit(1);
162
+ }
163
+ if (!flags.message && !flags.script) {
164
+ console.error("--message or --script is required");
165
+ process.exit(1);
166
+ }
167
+ if (flags.message && flags.script) {
168
+ console.error("--message and --script are mutually exclusive");
169
+ process.exit(1);
170
+ }
171
+ const body = {};
172
+ if (flags.cron) {
173
+ try {
174
+ CronExpressionParser.parse(flags.cron);
175
+ } catch {
176
+ console.error(`Invalid cron expression: ${flags.cron}`);
177
+ process.exit(1);
178
+ }
179
+ body.cron = flags.cron;
180
+ }
181
+ if (flags.in) {
182
+ const durationMs = parseDuration(flags.in);
183
+ if (!durationMs) {
184
+ console.error(`Invalid duration: ${flags.in} (expected format: 30s, 10m, 1h, 2h30m)`);
185
+ process.exit(1);
186
+ }
187
+ body.fireAt = new Date(Date.now() + durationMs).toISOString();
188
+ }
189
+ if (flags.message) body.message = flags.message;
190
+ if (flags.script) body.script = flags.script;
191
+ if (flags.id) body.id = flags.id;
192
+ if (flags.session) body.session = flags.session;
193
+ if (flags["while-sleeping"]) {
194
+ const ws = flags["while-sleeping"];
195
+ if (!["skip", "queue", "trigger-wake"].includes(ws)) {
196
+ console.error(
197
+ `Invalid --while-sleeping value: ${ws} (must be skip, queue, or trigger-wake)`
198
+ );
199
+ process.exit(1);
200
+ }
201
+ body.whileSleeping = ws;
202
+ }
203
+ const client = getClient();
204
+ const res = await daemonFetch(
205
+ urlOf(client.api.minds[":name"].schedules.$url({ param: { name: mind } })),
206
+ {
207
+ method: "POST",
208
+ headers: { "Content-Type": "application/json" },
209
+ body: JSON.stringify(body)
210
+ }
211
+ );
212
+ if (!res.ok) {
213
+ const data2 = await res.json();
214
+ console.error(data2.error ?? `Failed to add schedule: ${res.status}`);
215
+ process.exit(1);
216
+ }
217
+ const data = await res.json();
218
+ if (flags.in) {
219
+ console.log(`Timer set: ${data.id} (fires in ${flags.in})`);
220
+ } else {
221
+ console.log(`Schedule added: ${data.id}`);
222
+ }
223
+ }
224
+ });
225
+ var removeScheduleCmd = command({
226
+ name: "volute clock remove",
227
+ description: "Remove a schedule or timer",
228
+ flags: {
229
+ mind: { type: "string", description: "Mind name" },
230
+ id: { type: "string", description: "Schedule ID (required)" }
231
+ },
232
+ run: async ({ flags }) => {
233
+ const mind = resolveMindName(flags);
234
+ if (!flags.id) {
235
+ console.error("--id is required");
236
+ process.exit(1);
237
+ }
238
+ const client = getClient();
239
+ const res = await daemonFetch(
240
+ urlOf(
241
+ client.api.minds[":name"].schedules[":id"].$url({
242
+ param: { name: mind, id: flags.id }
243
+ })
244
+ ),
245
+ { method: "DELETE" }
246
+ );
247
+ if (!res.ok) {
248
+ const data = await res.json();
249
+ console.error(data.error ?? `Failed to remove schedule: ${res.status}`);
250
+ process.exit(1);
251
+ }
252
+ console.log(`Schedule removed: ${flags.id}`);
253
+ }
254
+ });
255
+ var cmd = subcommands({
256
+ name: "volute clock",
257
+ description: "Manage schedules, timers, and sleep/wake cycles",
258
+ commands: {
259
+ status: {
260
+ description: "Show sleep state and upcoming schedule fires",
261
+ run: clockStatusCmd.execute
262
+ },
263
+ list: {
264
+ description: "List schedules and timers",
265
+ run: listSchedulesCmd.execute
266
+ },
267
+ add: {
268
+ description: "Add a schedule or timer",
269
+ run: addScheduleCmd.execute
270
+ },
271
+ remove: {
272
+ description: "Remove a schedule or timer",
273
+ run: removeScheduleCmd.execute
274
+ },
275
+ sleep: {
276
+ description: "Put a mind to sleep",
277
+ run: (args) => import("./mind-sleep-ITCF6OQA.js").then((m) => m.run(args))
278
+ },
279
+ wake: {
280
+ description: "Wake a sleeping mind",
281
+ run: (args) => import("./mind-wake-KXMKMGWX.js").then((m) => m.run(args))
282
+ }
283
+ },
284
+ footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
285
+ });
286
+ var run = cmd.execute;
287
+ export {
288
+ run
289
+ };