volute 0.46.0 → 0.48.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 (172) hide show
  1. package/README.md +10 -10
  2. package/dist/{accept-N5XULCXK.js → accept-KYNC5X3U.js} +1 -1
  3. package/dist/{activity-events-NF6VWTJQ.js → activity-events-MIOK3IOU.js} +3 -3
  4. package/dist/{ai-service-UODCCE4O.js → ai-service-643TNFPH.js} +8 -4
  5. package/dist/{archive-WS2L2VIQ.js → archive-6Z4GFQPH.js} +3 -3
  6. package/dist/{auth-CCFAU4GQ.js → auth-A4VGHADI.js} +4 -4
  7. package/dist/avatar-image-Y45R7LW5.js +23 -0
  8. package/dist/{backup-TST5C2YN.js → backup-UDH4GMSW.js} +15 -15
  9. package/dist/{bridge-2PO3AI5D.js → bridge-3FNSWLNQ.js} +1 -1
  10. package/dist/channels-SGQZHNQJ.js +89 -0
  11. package/dist/{chat-ZIQQS25U.js → chat-X43VYHH2.js} +12 -8
  12. package/dist/{chunk-ZV7MFISX.js → chunk-2MJ7EOMT.js} +20 -2
  13. package/dist/{chunk-R77O2WMK.js → chunk-2OIYNHWO.js} +1 -1
  14. package/dist/{chunk-QCN24XEN.js → chunk-3YUBFTDN.js} +1 -1
  15. package/dist/chunk-4FCL4DVZ.js +48 -0
  16. package/dist/{chunk-F7H6ATM4.js → chunk-5KXCM5AW.js} +18 -2
  17. package/dist/chunk-7KRIHYLR.js +124 -0
  18. package/dist/{chunk-RBNMDAKB.js → chunk-BCG45AQB.js} +15 -1
  19. package/dist/{chunk-QMJCNZ6C.js → chunk-C3KLHJDB.js} +1 -1
  20. package/dist/{chunk-H2X54EHC.js → chunk-DGGZVZTM.js} +1 -1
  21. package/dist/chunk-DW4TRDOZ.js +29 -0
  22. package/dist/{chunk-4JOQZPCE.js → chunk-EIQDZC43.js} +1 -1
  23. package/dist/{chunk-TQJ6ZYVY.js → chunk-FJ2MZ5PH.js} +41 -5
  24. package/dist/{chunk-BJZ4PV7R.js → chunk-HNGFKPNS.js} +26 -10
  25. package/dist/{chunk-5ZQZDDIK.js → chunk-HPGN6XRT.js} +3 -3
  26. package/dist/{chunk-KGIXX4NM.js → chunk-HUNDXZBZ.js} +5 -5
  27. package/dist/{chunk-ZDZISKCL.js → chunk-IJPMIEVE.js} +1 -1
  28. package/dist/chunk-IYCV34IU.js +158 -0
  29. package/dist/{chunk-ZNMCCHCP.js → chunk-LTLFOSA4.js} +2 -2
  30. package/dist/{chunk-K6T43YBD.js → chunk-MJRXFUMS.js} +26 -6
  31. package/dist/{chunk-4YU7HF4L.js → chunk-MOERAQXH.js} +6 -4
  32. package/dist/{chunk-KQSFTPIM.js → chunk-MTRMQFCQ.js} +1 -1
  33. package/dist/{chunk-OV7ZQ2GH.js → chunk-ODDGGLM6.js} +3 -3
  34. package/dist/{chunk-A7WQZKOU.js → chunk-OQJMTHEH.js} +2 -2
  35. package/dist/{chunk-RRNXJOKB.js → chunk-PJVPDY2Z.js} +2 -2
  36. package/dist/{chunk-FXORA5JG.js → chunk-Q7HOAVFR.js} +3 -3
  37. package/dist/{chunk-KDLYIECM.js → chunk-R772ET2M.js} +18 -4
  38. package/dist/{chunk-QLWG3C2Z.js → chunk-RRZ4RQQU.js} +2 -2
  39. package/dist/{mind-list-4D7J4CHD.js → chunk-SHKM5RGD.js} +18 -4
  40. package/dist/{chunk-RXEEYDIB.js → chunk-SZJCJVXV.js} +1 -1
  41. package/dist/{chunk-E3DA4HYV.js → chunk-T4VS7UDW.js} +15 -15
  42. package/dist/{chunk-YXSUMLTC.js → chunk-USD45JKR.js} +322 -76
  43. package/dist/{chunk-JO5IO4FH.js → chunk-VB2QXUJQ.js} +391 -294
  44. package/dist/{chunk-JZ62SYWR.js → chunk-VZRA5TYO.js} +1 -1
  45. package/dist/{chunk-PJ45FQPT.js → chunk-WARH6GIV.js} +8 -8
  46. package/dist/{chunk-PFZBNKUH.js → chunk-WCFSBH33.js} +0 -1
  47. package/dist/{chunk-DRJ24GXK.js → chunk-WQ46E33M.js} +59 -39
  48. package/dist/{chunk-ALKYQULU.js → chunk-WW6C3PLV.js} +1 -1
  49. package/dist/{chunk-CDPBTTZO.js → chunk-XVBSFLM7.js} +2 -2
  50. package/dist/{chunk-6EMWJZBK.js → chunk-YKA7DCVW.js} +1 -1
  51. package/dist/{chunk-IHKGWTGT.js → chunk-YNBXEQAP.js} +31 -1
  52. package/dist/cli.js +34 -26
  53. package/dist/{clock-RHS2JEDL.js → clock-CNRF6F7T.js} +3 -3
  54. package/dist/{cloud-sync-46RS4SDA.js → cloud-sync-WHKCB4CD.js} +22 -19
  55. package/dist/{config-TJLYUV3U.js → config-RPSLA2HX.js} +3 -3
  56. package/dist/{conversations-CJOOCGNW.js → conversations-C7IKYSHD.js} +4 -4
  57. package/dist/{create-IOV4GCRX.js → create-GJKHABJB.js} +16 -5
  58. package/dist/{create-DF3KISTW.js → create-VIQVP3QB.js} +1 -1
  59. package/dist/{daemon-client-IYR4KCPU.js → daemon-client-ZFY5MOAL.js} +5 -3
  60. package/dist/{daemon-restart-VFEI57UO.js → daemon-restart-7KUHVZIN.js} +7 -7
  61. package/dist/daemon.js +829 -496
  62. package/dist/{db-MF2JNRUW.js → db-FO6LXYCW.js} +2 -2
  63. package/dist/{db-LZTLA7XC.js → db-IPXRJUI7.js} +1 -1
  64. package/dist/{delete-HPLC7ETU.js → delete-ESEP7NGQ.js} +1 -1
  65. package/dist/delivery-manager-HZTT5SJR.js +36 -0
  66. package/dist/{delivery-router-N4A7ZC5T.js → delivery-router-3QFG2ZEX.js} +3 -3
  67. package/dist/{down-U2CZ23M4.js → down-G6IADJXV.js} +5 -5
  68. package/dist/echo-text-H3SH337Q.js +36 -0
  69. package/dist/env-6TGPO5WG.js +18 -0
  70. package/dist/{env-VZ4MLFQW.js → env-C7Z55QCJ.js} +6 -6
  71. package/dist/{exec-G3ZRST4Z.js → exec-QIFYZG4C.js} +3 -3
  72. package/dist/{export-LY723I3Z.js → export-C2K3NIRD.js} +4 -4
  73. package/dist/{extension-SEID47SR.js → extension-J4ZQ2GHV.js} +1 -1
  74. package/dist/{extensions-ZELQLTSR.js → extensions-GEKF47A4.js} +24 -19
  75. package/dist/{files-4LN3EN7Q.js → files-LXQSQOFG.js} +4 -4
  76. package/dist/{import-42YNQBF4.js → import-SX3ZXHB4.js} +8 -8
  77. package/dist/{isolation-YMGZZ4E5.js → isolation-MCT4ZYLT.js} +3 -3
  78. package/dist/{join-ZJV7W6MO.js → join-34TR2GXQ.js} +1 -1
  79. package/dist/{list-OXIAY3W7.js → list-PMUXZNAM.js} +1 -1
  80. package/dist/{login-MY6ETFYB.js → login-ARRZ4ORJ.js} +3 -3
  81. package/dist/{login-M6OJUPQ2.js → login-CL4IT2ED.js} +14 -5
  82. package/dist/{logout-WQBWO77G.js → logout-HZYJCYCA.js} +3 -3
  83. package/dist/{logout-NCG3TMDL.js → logout-YZRMZ3O2.js} +1 -1
  84. package/dist/message-delivery-GPQ5SE5N.js +40 -0
  85. package/dist/{mind-LHKS55DI.js → mind-46AOK373.js} +23 -19
  86. package/dist/{mind-activity-tracker-3QRNJVR4.js → mind-activity-tracker-YVZPC4A5.js} +4 -4
  87. package/dist/mind-contacts-GV7XYL5D.js +64 -0
  88. package/dist/{mind-history-VRO5A76U.js → mind-history-TTGA5BHZ.js} +5 -5
  89. package/dist/mind-list-OTHV4ZO4.js +13 -0
  90. package/dist/{mind-profile-PEQYASQX.js → mind-profile-LUG353ZT.js} +1 -1
  91. package/dist/mind-service-2ARGJNKP.js +44 -0
  92. package/dist/{mind-sleep-74TGOQBC.js → mind-sleep-DV7KP255.js} +3 -3
  93. package/dist/{mind-status-UO34ASXZ.js → mind-status-BJNPGXKC.js} +23 -1
  94. package/dist/{mind-wake-LCLGTXA2.js → mind-wake-LVTZ55EZ.js} +1 -1
  95. package/dist/notices-2KU5NTRY.js +25 -0
  96. package/dist/{package-DOD6CPO6.js → package-RTN2PS7O.js} +5 -3
  97. package/dist/{read-QVAXMTPV.js → read-YSWUXYL7.js} +1 -1
  98. package/dist/{register-Y2H4PY5R.js → register-42VBJKTP.js} +3 -3
  99. package/dist/{registry-OUZBZ3Q4.js → registry-UMMDRPRM.js} +2 -2
  100. package/dist/{reject-EV35X64Y.js → reject-SXGCYN4A.js} +1 -1
  101. package/dist/{restart-FJQ662XJ.js → restart-YYEGZJDD.js} +5 -5
  102. package/dist/{sandbox-ZJ7QA6Z6.js → sandbox-5VQ454XP.js} +4 -4
  103. package/dist/scheduler-I7JZCT47.js +34 -0
  104. package/dist/{schema-PVNG3PQM.js → schema-VEVO7HG6.js} +3 -1
  105. package/dist/{seed-CNYIHPOH.js → seed-F2HXZQU4.js} +1 -1
  106. package/dist/{seed-check-VLTVILOV.js → seed-check-TYD7RRZY.js} +1 -1
  107. package/dist/{seed-cmd-AVNUNLZV.js → seed-cmd-MLCTGSX5.js} +3 -3
  108. package/dist/{seed-create-ANXGYSCC.js → seed-create-KQ7OILWB.js} +6 -4
  109. package/dist/seed-readiness-RBPGOLSZ.js +18 -0
  110. package/dist/{seed-sprout-NIUFTX32.js → seed-sprout-HVYCFJLA.js} +30 -31
  111. package/dist/{send-SPE6DVNJ.js → send-TD2X5U3K.js} +6 -6
  112. package/dist/{service-UOCLXDWR.js → service-CVZMQYK6.js} +4 -4
  113. package/dist/{service-install-4HHFDDWY.js → service-install-VCRMFWX5.js} +5 -5
  114. package/dist/{setup-Y2EJI3GG.js → setup-5ECWTYKG.js} +7 -3
  115. package/dist/{setup-QT2A25SY.js → setup-AE4CVUC4.js} +7 -7
  116. package/dist/{skill-FKFHIJRR.js → skill-UUM4JZRF.js} +5 -5
  117. package/dist/skills/dreaming/SKILL.md +5 -1
  118. package/dist/skills/dreaming/scripts/dream.ts +5 -1
  119. package/dist/skills/orientation/SKILL.md +8 -7
  120. package/dist/skills/tending/SKILL.md +51 -2
  121. package/dist/skills/volute-mind/SKILL.md +2 -0
  122. package/dist/{skills-AKCFA7BN.js → skills-B3SVDCEB.js} +5 -5
  123. package/dist/sleep-manager-Z27R3WTW.js +38 -0
  124. package/dist/spirit-WXS3HCLN.js +25 -0
  125. package/dist/{split-WBMZXBHF.js → split-SKZ4Y2D6.js} +1 -1
  126. package/dist/{sprout-SMX42ZBP.js → sprout-KQ43BWZJ.js} +1 -1
  127. package/dist/{src-OJHARHTF.js → src-WLJE73NP.js} +14 -5
  128. package/dist/{start-5JE3TV66.js → start-O6UKK7BG.js} +3 -3
  129. package/dist/{status-SWRVGXBI.js → status-F4PGREUU.js} +19 -7
  130. package/dist/{stop-AAMTG3TU.js → stop-UBX6X5RA.js} +5 -5
  131. package/dist/system-chat-63ABFF6V.js +40 -0
  132. package/dist/{systems-VNB5WKSS.js → systems-JJNGQHAO.js} +4 -4
  133. package/dist/{tailscale-3XOKOW7T.js → tailscale-MCLY5GYE.js} +2 -2
  134. package/dist/{template-hash-446HHH5V.js → template-hash-GSOUARW4.js} +2 -2
  135. package/dist/template-staleness-EMQORSGG.js +15 -0
  136. package/dist/{turn-tracker-FOIBNUUA.js → turn-tracker-KLPV3PAU.js} +6 -6
  137. package/dist/up-RVGDE6CQ.js +20 -0
  138. package/dist/{update-SWAYZRWJ.js → update-OXQEGGXD.js} +5 -5
  139. package/dist/{update-check-PQ2MZ47K.js → update-check-266R4ZSY.js} +3 -3
  140. package/dist/{upgrade-NWAZ7MLD.js → upgrade-K5FIQPQD.js} +1 -1
  141. package/dist/{version-notify-C5CH7CVP.js → version-notify-73YURTFR.js} +41 -25
  142. package/dist/web-assets/assets/index-WdZ60R6c.css +1 -0
  143. package/dist/web-assets/assets/index-taX6Ezfa.js +92 -0
  144. package/dist/web-assets/index.html +2 -2
  145. package/drizzle/0011_drop_turn_summary_event_id.sql +3 -0
  146. package/drizzle/0012_channel_gates.sql +17 -0
  147. package/drizzle/meta/_journal.json +14 -0
  148. package/package.json +5 -3
  149. package/packages/extensions/pages/dist/ui/assets/index-BuXnE-rb.css +1 -0
  150. package/packages/extensions/pages/dist/ui/assets/index-DtzftuPA.js +2 -0
  151. package/packages/extensions/pages/dist/ui/index.html +2 -2
  152. package/templates/_base/src/lib/startup.ts +59 -3
  153. package/templates/claude/src/agent.ts +37 -4
  154. package/templates/claude/src/lib/session-reaper.ts +32 -0
  155. package/templates/claude/src/server.ts +14 -3
  156. package/templates/pi/src/agent.ts +7 -10
  157. package/templates/pi/src/lib/dispatch.ts +65 -0
  158. package/dist/avatar-image-6KY6UU4D.js +0 -16
  159. package/dist/delivery-manager-JINZRG2W.js +0 -33
  160. package/dist/echo-text-VQPB5L2X.js +0 -33
  161. package/dist/message-delivery-R7JSQGYX.js +0 -37
  162. package/dist/mind-service-NB2JMWQZ.js +0 -39
  163. package/dist/scheduler-WVKII3LA.js +0 -31
  164. package/dist/sleep-manager-G6TXSDP7.js +0 -35
  165. package/dist/spirit-RPBLLUQ5.js +0 -23
  166. package/dist/system-chat-NDAW6YP7.js +0 -37
  167. package/dist/up-PS6PFS75.js +0 -18
  168. package/dist/volute-config-A52FHWKM.js +0 -14
  169. package/dist/web-assets/assets/index-B1JBQv2m.css +0 -1
  170. package/dist/web-assets/assets/index-CU6XWICM.js +0 -86
  171. package/packages/extensions/pages/dist/ui/assets/index-BcY6lnq4.css +0 -1
  172. package/packages/extensions/pages/dist/ui/assets/index-CQjEQg1r.js +0 -2
package/README.md CHANGED
@@ -13,23 +13,23 @@ Built on the [Anthropic Claude Agent SDK](https://github.com/anthropics/claude-a
13
13
  ```sh
14
14
  npm install -g volute
15
15
 
16
- # First-time setup (required)
17
- volute setup --name my-system
16
+ # One-time setup — starts the daemon and opens the web dashboard
17
+ volute setup
18
+ ```
18
19
 
19
- # Start the daemon (manages all your minds)
20
- volute up
20
+ Finish setup in your browser at `http://localhost:1618`: name your system, create your admin account, and connect an AI provider. When setup completes, the system spirit greets you in chat and helps you plant your first mind.
21
21
 
22
- # Create a mind
23
- volute mind create atlas
22
+ Prefer the terminal? Once setup is complete:
24
23
 
25
- # Start it
26
- volute mind start atlas
24
+ ```sh
25
+ # Plant a seed — the recommended way to create a mind
26
+ volute seed create atlas
27
27
 
28
28
  # Talk to it
29
- volute chat send @atlas "hey, what can you do?"
29
+ volute chat send @atlas "hello, who are you?"
30
30
  ```
31
31
 
32
- You now have a running AI mind with persistent memory, auto-committing file changes, and session resume across restarts. Open `http://localhost:1618` for the web dashboard.
32
+ You now have a running AI mind with persistent memory, auto-committing file changes, and session resume across restarts.
33
33
 
34
34
  ## The daemon
35
35
 
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-BTY4WNFE.js";
5
5
  import {
6
6
  daemonFetch
7
- } from "./chunk-RBNMDAKB.js";
7
+ } from "./chunk-BCG45AQB.js";
8
8
  import {
9
9
  command
10
10
  } from "./chunk-TXSA4Q3V.js";
@@ -3,10 +3,10 @@ import {
3
3
  broadcast,
4
4
  publish,
5
5
  subscribe
6
- } from "./chunk-ZNMCCHCP.js";
6
+ } from "./chunk-LTLFOSA4.js";
7
7
  import "./chunk-T2TP6ZC6.js";
8
- import "./chunk-ALKYQULU.js";
9
- import "./chunk-ZV7MFISX.js";
8
+ import "./chunk-WW6C3PLV.js";
9
+ import "./chunk-2MJ7EOMT.js";
10
10
  import "./chunk-K3NQKI34.js";
11
11
  export {
12
12
  broadcast,
@@ -14,6 +14,8 @@ import {
14
14
  getUtilityModel,
15
15
  isAiConfigured,
16
16
  migrateAiModelQualification,
17
+ missingCredentialWarning,
18
+ providerForMindTemplate,
17
19
  qualifyModelId,
18
20
  removeAiConfig,
19
21
  removeCustomModel,
@@ -25,11 +27,11 @@ import {
25
27
  setProviderRefreshHook,
26
28
  setUtilityModel,
27
29
  unqualifyModelId
28
- } from "./chunk-IHKGWTGT.js";
29
- import "./chunk-F7H6ATM4.js";
30
+ } from "./chunk-YNBXEQAP.js";
31
+ import "./chunk-5KXCM5AW.js";
30
32
  import "./chunk-T2TP6ZC6.js";
31
- import "./chunk-ALKYQULU.js";
32
- import "./chunk-ZV7MFISX.js";
33
+ import "./chunk-WW6C3PLV.js";
34
+ import "./chunk-2MJ7EOMT.js";
33
35
  import "./chunk-K3NQKI34.js";
34
36
  export {
35
37
  addCustomModel,
@@ -46,6 +48,8 @@ export {
46
48
  getUtilityModel,
47
49
  isAiConfigured,
48
50
  migrateAiModelQualification,
51
+ missingCredentialWarning,
52
+ providerForMindTemplate,
49
53
  qualifyModelId,
50
54
  removeAiConfig,
51
55
  removeCustomModel,
@@ -5,9 +5,9 @@ import {
5
5
  extractArchive,
6
6
  isHomeOnlyArchive,
7
7
  readManifest
8
- } from "./chunk-QCN24XEN.js";
9
- import "./chunk-ALKYQULU.js";
10
- import "./chunk-ZV7MFISX.js";
8
+ } from "./chunk-3YUBFTDN.js";
9
+ import "./chunk-WW6C3PLV.js";
10
+ import "./chunk-2MJ7EOMT.js";
11
11
  import "./chunk-K3NQKI34.js";
12
12
  export {
13
13
  addHistoryToArchive,
@@ -17,11 +17,11 @@ import {
17
17
  syncMindProfile,
18
18
  updateUserProfile,
19
19
  verifyUser
20
- } from "./chunk-OV7ZQ2GH.js";
21
- import "./chunk-ZNMCCHCP.js";
20
+ } from "./chunk-ODDGGLM6.js";
21
+ import "./chunk-LTLFOSA4.js";
22
22
  import "./chunk-T2TP6ZC6.js";
23
- import "./chunk-ALKYQULU.js";
24
- import "./chunk-ZV7MFISX.js";
23
+ import "./chunk-WW6C3PLV.js";
24
+ import "./chunk-2MJ7EOMT.js";
25
25
  import "./chunk-K3NQKI34.js";
26
26
  export {
27
27
  approveUser,
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ AVATAR_CONTEXT_DIM,
4
+ AVATAR_DIM,
5
+ MAX_AVATAR_BLOCK_BYTES,
6
+ migrateAvatarSizes,
7
+ normalizeAvatar,
8
+ renderAvatarBlock
9
+ } from "./chunk-WQ46E33M.js";
10
+ import "./chunk-DW4TRDOZ.js";
11
+ import "./chunk-WCFSBH33.js";
12
+ import "./chunk-T2TP6ZC6.js";
13
+ import "./chunk-WW6C3PLV.js";
14
+ import "./chunk-2MJ7EOMT.js";
15
+ import "./chunk-K3NQKI34.js";
16
+ export {
17
+ AVATAR_CONTEXT_DIM,
18
+ AVATAR_DIM,
19
+ MAX_AVATAR_BLOCK_BYTES,
20
+ migrateAvatarSizes,
21
+ normalizeAvatar,
22
+ renderAvatarBlock
23
+ };
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stopDaemon
4
- } from "./chunk-RRNXJOKB.js";
5
- import {
6
- promptLine,
7
- promptPassword
8
- } from "./chunk-VHWGEJ4V.js";
9
- import {
10
- daemonFetch
11
- } from "./chunk-RBNMDAKB.js";
4
+ } from "./chunk-PJVPDY2Z.js";
12
5
  import {
13
6
  getClient,
14
7
  urlOf
15
8
  } from "./chunk-LOPXTW6H.js";
9
+ import {
10
+ daemonFetch
11
+ } from "./chunk-BCG45AQB.js";
12
+ import {
13
+ promptLine,
14
+ promptPassword
15
+ } from "./chunk-VHWGEJ4V.js";
16
16
  import {
17
17
  command,
18
18
  subcommands
@@ -22,28 +22,28 @@ import {
22
22
  RESTIC_INSTALL_HINT,
23
23
  resticVersion,
24
24
  restoreStagedDb
25
- } from "./chunk-FXORA5JG.js";
25
+ } from "./chunk-Q7HOAVFR.js";
26
26
  import {
27
27
  getServiceMode,
28
28
  modeLabel,
29
29
  stopService
30
- } from "./chunk-TQJ6ZYVY.js";
30
+ } from "./chunk-FJ2MZ5PH.js";
31
31
  import {
32
32
  chownMindDir,
33
33
  exec,
34
34
  execInherit,
35
35
  wrapForIsolation
36
- } from "./chunk-H2X54EHC.js";
36
+ } from "./chunk-DGGZVZTM.js";
37
37
  import {
38
38
  _resetConfigCache,
39
39
  readGlobalConfig
40
- } from "./chunk-F7H6ATM4.js";
40
+ } from "./chunk-5KXCM5AW.js";
41
41
  import "./chunk-T2TP6ZC6.js";
42
42
  import {
43
43
  voluteHome,
44
44
  voluteSystemDir
45
- } from "./chunk-ALKYQULU.js";
46
- import "./chunk-ZV7MFISX.js";
45
+ } from "./chunk-WW6C3PLV.js";
46
+ import "./chunk-2MJ7EOMT.js";
47
47
  import "./chunk-K3NQKI34.js";
48
48
 
49
49
  // src/commands/backup.ts
@@ -337,7 +337,7 @@ Restore failed: ${err instanceof Error ? err.message : err}`);
337
337
  if (readGlobalConfig().setup?.isolation === "user") {
338
338
  process.env.VOLUTE_ISOLATION = "user";
339
339
  }
340
- const { readAllMinds, mindDir } = await import("./registry-OUZBZ3Q4.js");
340
+ const { readAllMinds, mindDir } = await import("./registry-UMMDRPRM.js");
341
341
  const seen = /* @__PURE__ */ new Set();
342
342
  for (const mind of await readAllMinds()) {
343
343
  const dir = mind.dir ?? mindDir(mind.name);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  daemonFetch
4
- } from "./chunk-RBNMDAKB.js";
4
+ } from "./chunk-BCG45AQB.js";
5
5
  import {
6
6
  command,
7
7
  subcommands
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveMindName
4
+ } from "./chunk-BTY4WNFE.js";
5
+ import {
6
+ daemonFetch
7
+ } from "./chunk-BCG45AQB.js";
8
+ import {
9
+ command,
10
+ subcommands
11
+ } from "./chunk-TXSA4Q3V.js";
12
+ import "./chunk-O7IGP7ZW.js";
13
+ import "./chunk-K3NQKI34.js";
14
+
15
+ // packages/cli/src/commands/chat/channels.ts
16
+ var channelsListCmd = command({
17
+ name: "volute chat channels",
18
+ description: "List unrouted (gated) channels holding messages",
19
+ args: [],
20
+ flags: {
21
+ mind: { type: "string", description: "Mind name" }
22
+ },
23
+ run: async ({ flags }) => {
24
+ const mind = resolveMindName(flags);
25
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mind)}/delivery/pending`);
26
+ if (!res.ok) {
27
+ const data = await res.json().catch(() => ({}));
28
+ console.error(data.error ?? `Failed to list gated channels: ${res.status}`);
29
+ process.exit(1);
30
+ }
31
+ const pending = await res.json();
32
+ if (pending.length === 0) {
33
+ console.log("No unrouted channels holding messages.");
34
+ return;
35
+ }
36
+ const chW = Math.max(7, ...pending.map((p) => (p.channel ?? "unknown").length));
37
+ console.log(`${"CHANNEL".padEnd(chW)} HELD SINCE`);
38
+ for (const p of pending) {
39
+ console.log(
40
+ `${(p.channel ?? "unknown").padEnd(chW)} ${String(p.count).padStart(4)} ${p.firstSeen}`
41
+ );
42
+ }
43
+ console.log(`
44
+ Route one to hear it, or 'volute chat channels decline <channel>' to opt out.`);
45
+ }
46
+ });
47
+ var channelsDeclineCmd = command({
48
+ name: "volute chat channels decline",
49
+ description: "Decline an unrouted channel: stop invites and archive its held backlog",
50
+ args: [{ name: "channel", required: true, description: "Channel to decline (e.g. #bardo)" }],
51
+ flags: {
52
+ mind: { type: "string", description: "Mind name" }
53
+ },
54
+ run: async ({ args, flags }) => {
55
+ const mind = resolveMindName(flags);
56
+ const channel = args.channel;
57
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mind)}/gates/decline`, {
58
+ method: "POST",
59
+ headers: { "Content-Type": "application/json" },
60
+ body: JSON.stringify({ channel })
61
+ });
62
+ if (!res.ok) {
63
+ const data2 = await res.json().catch(() => ({}));
64
+ console.error(data2.error ?? `Failed to decline channel: ${res.status}`);
65
+ process.exit(1);
66
+ }
67
+ const data = await res.json();
68
+ console.log(`Declined ${channel}; archived ${data.archived} held message(s).`);
69
+ }
70
+ });
71
+ var cmd = subcommands({
72
+ name: "volute chat channels",
73
+ description: "Manage unrouted (gated) channels",
74
+ commands: {
75
+ list: {
76
+ description: "List unrouted channels holding messages",
77
+ run: channelsListCmd.execute
78
+ },
79
+ decline: {
80
+ description: "Decline an unrouted channel",
81
+ run: channelsDeclineCmd.execute
82
+ }
83
+ },
84
+ footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
85
+ });
86
+ var run = cmd.execute;
87
+ export {
88
+ run
89
+ };
@@ -12,35 +12,39 @@ var cmd = subcommands({
12
12
  commands: {
13
13
  send: {
14
14
  description: "Send a message",
15
- run: (args) => import("./send-SPE6DVNJ.js").then((m) => m.run(args))
15
+ run: (args) => import("./send-TD2X5U3K.js").then((m) => m.run(args))
16
16
  },
17
17
  list: {
18
18
  description: "List conversations",
19
- run: (args) => import("./list-OXIAY3W7.js").then((m) => m.run(args))
19
+ run: (args) => import("./list-PMUXZNAM.js").then((m) => m.run(args))
20
20
  },
21
21
  read: {
22
22
  description: "Read conversation messages",
23
- run: (args) => import("./read-QVAXMTPV.js").then((m) => m.run(args))
23
+ run: (args) => import("./read-YSWUXYL7.js").then((m) => m.run(args))
24
24
  },
25
25
  create: {
26
26
  description: "Create a conversation",
27
- run: (args) => import("./create-DF3KISTW.js").then((m) => m.run(args))
27
+ run: (args) => import("./create-VIQVP3QB.js").then((m) => m.run(args))
28
28
  },
29
29
  bridge: {
30
30
  description: "Manage platform bridges",
31
- run: (args) => import("./bridge-2PO3AI5D.js").then((m) => m.run(args))
31
+ run: (args) => import("./bridge-3FNSWLNQ.js").then((m) => m.run(args))
32
+ },
33
+ channels: {
34
+ description: "Manage unrouted (gated) channels",
35
+ run: (args) => import("./channels-SGQZHNQJ.js").then((m) => m.run(args))
32
36
  },
33
37
  files: {
34
38
  description: "List pending incoming files",
35
- run: (args) => import("./files-4LN3EN7Q.js").then((m) => m.run(args))
39
+ run: (args) => import("./files-LXQSQOFG.js").then((m) => m.run(args))
36
40
  },
37
41
  accept: {
38
42
  description: "Accept a pending file",
39
- run: (args) => import("./accept-N5XULCXK.js").then((m) => m.run(args))
43
+ run: (args) => import("./accept-KYNC5X3U.js").then((m) => m.run(args))
40
44
  },
41
45
  reject: {
42
46
  description: "Reject a pending file",
43
- run: (args) => import("./reject-EV35X64Y.js").then((m) => m.run(args))
47
+ run: (args) => import("./reject-SXGCYN4A.js").then((m) => m.run(args))
44
48
  }
45
49
  },
46
50
  footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
@@ -7,6 +7,7 @@ import {
7
7
  var schema_exports = {};
8
8
  __export(schema_exports, {
9
9
  activity: () => activity,
10
+ channelGates: () => channelGates,
10
11
  channels: () => channels,
11
12
  conversationParticipants: () => conversationParticipants,
12
13
  conversationReads: () => conversationReads,
@@ -24,7 +25,14 @@ __export(schema_exports, {
24
25
  users: () => users
25
26
  });
26
27
  import { sql } from "drizzle-orm";
27
- import { index, integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
28
+ import {
29
+ index,
30
+ integer,
31
+ primaryKey,
32
+ sqliteTable,
33
+ text,
34
+ uniqueIndex
35
+ } from "drizzle-orm/sqlite-core";
28
36
  var minds = sqliteTable(
29
37
  "minds",
30
38
  {
@@ -79,7 +87,6 @@ var turns = sqliteTable(
79
87
  mind: text("mind").notNull(),
80
88
  session: text("session"),
81
89
  trigger_event_id: integer("trigger_event_id"),
82
- summary_event_id: integer("summary_event_id"),
83
90
  summary_id: integer("summary_id"),
84
91
  status: text("status").notNull().default("active"),
85
92
  created_at: text("created_at").notNull().default(sql`(datetime('now'))`)
@@ -269,6 +276,16 @@ var mindNotices = sqliteTable(
269
276
  },
270
277
  (table) => [index("idx_mind_notices_mind_session").on(table.mind, table.session)]
271
278
  );
279
+ var channelGates = sqliteTable(
280
+ "channel_gates",
281
+ {
282
+ mind: text("mind").notNull(),
283
+ channel: text("channel").notNull(),
284
+ state: text("state").$type().notNull(),
285
+ updated_at: text("updated_at").notNull().default(sql`(datetime('now'))`)
286
+ },
287
+ (table) => [primaryKey({ columns: [table.mind, table.channel] })]
288
+ );
272
289
 
273
290
  export {
274
291
  minds,
@@ -287,5 +304,6 @@ export {
287
304
  channels,
288
305
  messages,
289
306
  mindNotices,
307
+ channelGates,
290
308
  schema_exports
291
309
  };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stateDir
4
- } from "./chunk-ALKYQULU.js";
4
+ } from "./chunk-WW6C3PLV.js";
5
5
 
6
6
  // packages/daemon/src/lib/chat/file-sharing.ts
7
7
  import { randomBytes } from "crypto";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  mindDir,
4
4
  stateDir
5
- } from "./chunk-ALKYQULU.js";
5
+ } from "./chunk-WW6C3PLV.js";
6
6
 
7
7
  // packages/daemon/src/lib/mind/archive.ts
8
8
  import { execFileSync } from "child_process";
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ MEMORY_PLACEHOLDER_MARKER,
4
+ ORIENTATION_MARKER
5
+ } from "./chunk-MOERAQXH.js";
6
+ import {
7
+ safeResolveWithinBase
8
+ } from "./chunk-DW4TRDOZ.js";
9
+ import {
10
+ readVoluteConfig
11
+ } from "./chunk-WCFSBH33.js";
12
+ import {
13
+ isImagegenEnabled
14
+ } from "./chunk-5KXCM5AW.js";
15
+
16
+ // packages/daemon/src/lib/mind/seed-readiness.ts
17
+ import { existsSync, readFileSync } from "fs";
18
+ import { resolve } from "path";
19
+ function isSoulWritten(text) {
20
+ return !text.includes(ORIENTATION_MARKER);
21
+ }
22
+ function isMemoryWritten(text) {
23
+ return text.trim().length > 0 && !text.includes(MEMORY_PLACEHOLDER_MARKER);
24
+ }
25
+ function evaluateSeedChecklist(dir) {
26
+ const soulPath = resolve(dir, "home/SOUL.md");
27
+ const memoryPath = resolve(dir, "home/MEMORY.md");
28
+ const soulWritten = existsSync(soulPath) && isSoulWritten(readFileSync(soulPath, "utf-8"));
29
+ const memoryWritten = existsSync(memoryPath) && isMemoryWritten(readFileSync(memoryPath, "utf-8"));
30
+ const config = readVoluteConfig(dir);
31
+ const displayNameSet = !!config?.profile?.displayName;
32
+ const avatarPath = config?.profile?.avatar;
33
+ const resolvedAvatar = avatarPath ? safeResolveWithinBase(resolve(dir, "home"), avatarPath) : null;
34
+ const avatarSet = !!resolvedAvatar && existsSync(resolvedAvatar);
35
+ return {
36
+ soulWritten,
37
+ memoryWritten,
38
+ displayNameSet,
39
+ avatarSet,
40
+ imagegenEnabled: isImagegenEnabled()
41
+ };
42
+ }
43
+
44
+ export {
45
+ isSoulWritten,
46
+ isMemoryWritten,
47
+ evaluateSeedChecklist
48
+ };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteSystemDir
4
- } from "./chunk-ALKYQULU.js";
4
+ } from "./chunk-WW6C3PLV.js";
5
5
 
6
6
  // packages/daemon/src/lib/config/setup.ts
7
7
  import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
@@ -120,9 +120,23 @@ function migrateConfigSecrets() {
120
120
  _resetConfigCache();
121
121
  writeGlobalConfig(readGlobalConfig());
122
122
  }
123
+ function setupStatus() {
124
+ const config = readGlobalConfig();
125
+ if (config.setupCompleted === true) return "complete";
126
+ if (config.setup != null && config.setupCompleted == null) return "complete";
127
+ if (config.setup != null) return "in-progress";
128
+ return "none";
129
+ }
123
130
  function isSetupComplete() {
131
+ return setupStatus() === "complete";
132
+ }
133
+ function setupUrl() {
124
134
  const config = readGlobalConfig();
125
- return config.setupCompleted === true;
135
+ const port = config.port || 1618;
136
+ let host = config.hostname || "127.0.0.1";
137
+ if (host === "0.0.0.0" || host === "::") host = "localhost";
138
+ if (host.includes(":") && !host.startsWith("[")) host = `[${host}]`;
139
+ return `http://${host}:${port}`;
126
140
  }
127
141
  function isImagegenEnabled() {
128
142
  const config = readGlobalConfig();
@@ -147,7 +161,9 @@ export {
147
161
  readGlobalConfig,
148
162
  writeGlobalConfig,
149
163
  migrateConfigSecrets,
164
+ setupStatus,
150
165
  isSetupComplete,
166
+ setupUrl,
151
167
  isImagegenEnabled,
152
168
  migrateSetupCompleted
153
169
  };
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ computeTemplateHash
4
+ } from "./chunk-C3KLHJDB.js";
5
+ import {
6
+ composeTemplate,
7
+ findTemplatesRoot,
8
+ listFiles
9
+ } from "./chunk-RRZ4RQQU.js";
10
+ import {
11
+ logger_default
12
+ } from "./chunk-T2TP6ZC6.js";
13
+ import {
14
+ mindDir
15
+ } from "./chunk-WW6C3PLV.js";
16
+
17
+ // packages/daemon/src/lib/mind/template-staleness.ts
18
+ import { createHash } from "crypto";
19
+ import { existsSync, readFileSync, rmSync, statSync } from "fs";
20
+ import { resolve } from "path";
21
+ var fileListCache = /* @__PURE__ */ new Map();
22
+ function getTemplateFileList(templateName) {
23
+ const cached = fileListCache.get(templateName);
24
+ if (cached) return cached;
25
+ const templatesRoot = findTemplatesRoot();
26
+ const baseDir = resolve(templatesRoot, "_base");
27
+ const templateDir = resolve(templatesRoot, templateName);
28
+ if (!existsSync(baseDir)) throw new Error(`Base template not found: ${baseDir}`);
29
+ if (!existsSync(templateDir)) throw new Error(`Template not found: ${templateName}`);
30
+ const { composedDir, manifest } = composeTemplate(templatesRoot, templateName);
31
+ try {
32
+ const files = listFiles(composedDir).filter((f) => !f.startsWith(".init/") && !f.startsWith(".init\\")).sort();
33
+ const contents = /* @__PURE__ */ new Map();
34
+ for (const file of files) {
35
+ contents.set(file, readFileSync(resolve(composedDir, file)));
36
+ }
37
+ const result = { files, manifest, contents };
38
+ fileListCache.set(templateName, result);
39
+ return result;
40
+ } finally {
41
+ rmSync(composedDir, { recursive: true, force: true });
42
+ }
43
+ }
44
+ function computeMindTemplateHash(mindProjectDir, templateName, mindName) {
45
+ const { files, manifest, contents } = getTemplateFileList(templateName);
46
+ const substituteSet = new Set(manifest.substitute);
47
+ const hash = createHash("sha256");
48
+ for (const file of files) {
49
+ const onDiskRel = manifest.rename[file] ?? file;
50
+ const onDiskPath = resolve(mindProjectDir, onDiskRel);
51
+ hash.update(file);
52
+ hash.update("\0");
53
+ if (!existsSync(onDiskPath)) {
54
+ hash.update("\0__ABSENT__\0");
55
+ continue;
56
+ }
57
+ const composed = contents.get(file);
58
+ const onDisk = readFileSync(onDiskPath);
59
+ if (substituteSet.has(onDiskRel) && mindName.length > 0) {
60
+ const expected = Buffer.from(
61
+ composed.toString("utf-8").replaceAll("{{name}}", mindName),
62
+ "utf-8"
63
+ );
64
+ hash.update(onDisk.equals(expected) ? composed : onDisk);
65
+ } else {
66
+ hash.update(onDisk);
67
+ }
68
+ }
69
+ return hash.digest("hex");
70
+ }
71
+ function trackedSignal(mindProjectDir, templateName) {
72
+ const { files, manifest } = getTemplateFileList(templateName);
73
+ let maxMtime = 0;
74
+ let present = 0;
75
+ for (const file of files) {
76
+ const onDiskRel = manifest.rename[file] ?? file;
77
+ try {
78
+ const m = statSync(resolve(mindProjectDir, onDiskRel)).mtimeMs;
79
+ present++;
80
+ if (m > maxMtime) maxMtime = m;
81
+ } catch {
82
+ }
83
+ }
84
+ return `${maxMtime}:${present}`;
85
+ }
86
+ var staleCache = /* @__PURE__ */ new Map();
87
+ var warnedTemplates = /* @__PURE__ */ new Set();
88
+ function isTemplateStale(entry) {
89
+ if (entry.mindType !== "mind") return false;
90
+ if (entry.stage === "seed") return false;
91
+ if (entry.parent) return false;
92
+ const templateName = entry.template ?? "claude";
93
+ let current;
94
+ try {
95
+ current = computeTemplateHash(templateName);
96
+ } catch (err) {
97
+ if (!warnedTemplates.has(templateName)) {
98
+ warnedTemplates.add(templateName);
99
+ logger_default.warn(
100
+ `cannot compute template hash for '${templateName}'; skipping staleness check`,
101
+ logger_default.errorData(err)
102
+ );
103
+ }
104
+ return false;
105
+ }
106
+ if (entry.templateHash != null && entry.templateHash === current) return false;
107
+ const dir = mindDir(entry.name);
108
+ const signal = trackedSignal(dir, templateName);
109
+ const cached = staleCache.get(dir);
110
+ if (cached && cached.signal === signal) return cached.stale;
111
+ let stale;
112
+ try {
113
+ stale = computeMindTemplateHash(dir, templateName, entry.name) !== current;
114
+ } catch {
115
+ stale = true;
116
+ }
117
+ staleCache.set(dir, { signal, stale });
118
+ return stale;
119
+ }
120
+
121
+ export {
122
+ computeMindTemplateHash,
123
+ isTemplateStale
124
+ };