volute 0.46.0 → 0.47.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 (136) hide show
  1. package/README.md +1 -1
  2. package/dist/{activity-events-NF6VWTJQ.js → activity-events-MIOK3IOU.js} +3 -3
  3. package/dist/{ai-service-UODCCE4O.js → ai-service-CVZEYKTK.js} +4 -4
  4. package/dist/{archive-WS2L2VIQ.js → archive-6Z4GFQPH.js} +3 -3
  5. package/dist/{auth-CCFAU4GQ.js → auth-A4VGHADI.js} +4 -4
  6. package/dist/avatar-image-7S3WA77A.js +22 -0
  7. package/dist/{backup-TST5C2YN.js → backup-IIAFOW2L.js} +13 -13
  8. package/dist/channels-ITE4YC57.js +89 -0
  9. package/dist/{chat-ZIQQS25U.js → chat-AJLJCQ3M.js} +12 -8
  10. package/dist/{chunk-ZV7MFISX.js → chunk-2MJ7EOMT.js} +20 -2
  11. package/dist/{chunk-R77O2WMK.js → chunk-2OIYNHWO.js} +1 -1
  12. package/dist/{chunk-QCN24XEN.js → chunk-3YUBFTDN.js} +1 -1
  13. package/dist/{chunk-E3DA4HYV.js → chunk-4I72V3E5.js} +10 -10
  14. package/dist/{chunk-K6T43YBD.js → chunk-5IERLDUS.js} +3 -3
  15. package/dist/{chunk-FXORA5JG.js → chunk-5NN2VHJV.js} +3 -3
  16. package/dist/chunk-7KRIHYLR.js +124 -0
  17. package/dist/{chunk-RRNXJOKB.js → chunk-BGYHLR54.js} +2 -2
  18. package/dist/{chunk-QMJCNZ6C.js → chunk-C3KLHJDB.js} +1 -1
  19. package/dist/{chunk-TQJ6ZYVY.js → chunk-CBOIHNMR.js} +2 -2
  20. package/dist/{chunk-H2X54EHC.js → chunk-DGGZVZTM.js} +1 -1
  21. package/dist/{chunk-4JOQZPCE.js → chunk-EIQDZC43.js} +1 -1
  22. package/dist/{chunk-JO5IO4FH.js → chunk-F55GRIEK.js} +243 -121
  23. package/dist/{chunk-5ZQZDDIK.js → chunk-HPGN6XRT.js} +3 -3
  24. package/dist/{chunk-KGIXX4NM.js → chunk-IWJSNMSY.js} +5 -5
  25. package/dist/{chunk-ZDZISKCL.js → chunk-IYG4FBMP.js} +1 -1
  26. package/dist/{chunk-4YU7HF4L.js → chunk-JCMGDCGX.js} +4 -4
  27. package/dist/{chunk-PJ45FQPT.js → chunk-JSVHH32K.js} +6 -6
  28. package/dist/{chunk-YXSUMLTC.js → chunk-K23P5Q5N.js} +301 -77
  29. package/dist/{chunk-ZNMCCHCP.js → chunk-LTLFOSA4.js} +2 -2
  30. package/dist/{chunk-IHKGWTGT.js → chunk-LWDTP6DH.js} +1 -1
  31. package/dist/{chunk-JZ62SYWR.js → chunk-M3XDVS5Q.js} +1 -1
  32. package/dist/{chunk-BJZ4PV7R.js → chunk-M6TTZRGH.js} +9 -9
  33. package/dist/{chunk-KQSFTPIM.js → chunk-MTRMQFCQ.js} +1 -1
  34. package/dist/{chunk-OV7ZQ2GH.js → chunk-ODDGGLM6.js} +3 -3
  35. package/dist/{chunk-QLWG3C2Z.js → chunk-RRZ4RQQU.js} +2 -2
  36. package/dist/{chunk-CDPBTTZO.js → chunk-RUFLGTOT.js} +2 -2
  37. package/dist/{chunk-F7H6ATM4.js → chunk-SKNXMUIU.js} +1 -1
  38. package/dist/{chunk-RXEEYDIB.js → chunk-SZJCJVXV.js} +1 -1
  39. package/dist/{chunk-DRJ24GXK.js → chunk-VMCZBXF2.js} +52 -8
  40. package/dist/{chunk-ALKYQULU.js → chunk-WW6C3PLV.js} +1 -1
  41. package/dist/{chunk-A7WQZKOU.js → chunk-XHN6XBWV.js} +2 -2
  42. package/dist/{chunk-6EMWJZBK.js → chunk-YKA7DCVW.js} +1 -1
  43. package/dist/cli.js +21 -21
  44. package/dist/{clock-RHS2JEDL.js → clock-E6N5Y3YW.js} +3 -3
  45. package/dist/{cloud-sync-46RS4SDA.js → cloud-sync-LQTVDTQ3.js} +19 -18
  46. package/dist/{conversations-CJOOCGNW.js → conversations-C7IKYSHD.js} +4 -4
  47. package/dist/{create-IOV4GCRX.js → create-PQQXKTJK.js} +1 -1
  48. package/dist/{daemon-restart-VFEI57UO.js → daemon-restart-5F3YTLZK.js} +7 -7
  49. package/dist/daemon.js +217 -151
  50. package/dist/{db-MF2JNRUW.js → db-FO6LXYCW.js} +2 -2
  51. package/dist/delivery-manager-TN5KK2AP.js +34 -0
  52. package/dist/{delivery-router-N4A7ZC5T.js → delivery-router-3QFG2ZEX.js} +3 -3
  53. package/dist/{down-U2CZ23M4.js → down-ZI4S6265.js} +5 -5
  54. package/dist/echo-text-SEQCLGAT.js +34 -0
  55. package/dist/{exec-G3ZRST4Z.js → exec-QIFYZG4C.js} +3 -3
  56. package/dist/{export-LY723I3Z.js → export-4GVGNW54.js} +3 -3
  57. package/dist/{extensions-ZELQLTSR.js → extensions-PIMIQ7J3.js} +21 -18
  58. package/dist/{files-4LN3EN7Q.js → files-FEFZKMNM.js} +6 -6
  59. package/dist/{import-42YNQBF4.js → import-7MO3YTRE.js} +6 -6
  60. package/dist/{isolation-YMGZZ4E5.js → isolation-MCT4ZYLT.js} +3 -3
  61. package/dist/{login-M6OJUPQ2.js → login-OF4WXDAN.js} +5 -5
  62. package/dist/{logout-WQBWO77G.js → logout-ERE2BGA3.js} +5 -5
  63. package/dist/message-delivery-ZE3YGJDD.js +38 -0
  64. package/dist/{mind-LHKS55DI.js → mind-POOHFZHP.js} +13 -13
  65. package/dist/{mind-activity-tracker-3QRNJVR4.js → mind-activity-tracker-YVZPC4A5.js} +4 -4
  66. package/dist/{mind-list-4D7J4CHD.js → mind-list-KEGRGQEQ.js} +5 -4
  67. package/dist/mind-service-JFY7UG5E.js +40 -0
  68. package/dist/{mind-sleep-74TGOQBC.js → mind-sleep-IN3WPA76.js} +5 -5
  69. package/dist/{mind-status-UO34ASXZ.js → mind-status-SMUWJKGV.js} +20 -3
  70. package/dist/{package-DOD6CPO6.js → package-WPEE2HVJ.js} +2 -2
  71. package/dist/{registry-OUZBZ3Q4.js → registry-UMMDRPRM.js} +2 -2
  72. package/dist/{sandbox-ZJ7QA6Z6.js → sandbox-G4X4K3UN.js} +4 -4
  73. package/dist/scheduler-HQSDYJFY.js +32 -0
  74. package/dist/{schema-PVNG3PQM.js → schema-VEVO7HG6.js} +3 -1
  75. package/dist/{seed-CNYIHPOH.js → seed-VANPU43L.js} +1 -1
  76. package/dist/{seed-cmd-AVNUNLZV.js → seed-cmd-SYVDZKM4.js} +2 -2
  77. package/dist/{seed-create-ANXGYSCC.js → seed-create-3FGZPS6C.js} +3 -3
  78. package/dist/{seed-sprout-NIUFTX32.js → seed-sprout-H7QLFPFM.js} +12 -12
  79. package/dist/{send-SPE6DVNJ.js → send-HYDFGC6G.js} +7 -7
  80. package/dist/{service-UOCLXDWR.js → service-SYJ5G6LP.js} +4 -4
  81. package/dist/{service-install-4HHFDDWY.js → service-install-FQ43Z4DF.js} +5 -5
  82. package/dist/{setup-Y2EJI3GG.js → setup-KFYVWTXG.js} +3 -3
  83. package/dist/{setup-QT2A25SY.js → setup-QJHGMGSN.js} +7 -7
  84. package/dist/{skills-AKCFA7BN.js → skills-L2CMTW7A.js} +5 -5
  85. package/dist/sleep-manager-3NA7ZJP3.js +36 -0
  86. package/dist/{spirit-RPBLLUQ5.js → spirit-WXN4IDBF.js} +8 -8
  87. package/dist/{sprout-SMX42ZBP.js → sprout-LTL5P36T.js} +1 -1
  88. package/dist/{status-SWRVGXBI.js → status-V4RJMHJ4.js} +19 -9
  89. package/dist/system-chat-N2F7HVY3.js +38 -0
  90. package/dist/{systems-VNB5WKSS.js → systems-B5YJKMW4.js} +6 -6
  91. package/dist/{tailscale-3XOKOW7T.js → tailscale-MCLY5GYE.js} +2 -2
  92. package/dist/{template-hash-446HHH5V.js → template-hash-GSOUARW4.js} +2 -2
  93. package/dist/template-staleness-EMQORSGG.js +15 -0
  94. package/dist/{turn-tracker-FOIBNUUA.js → turn-tracker-JZRZDFWV.js} +6 -6
  95. package/dist/{up-PS6PFS75.js → up-J2PBPOZL.js} +6 -6
  96. package/dist/{update-SWAYZRWJ.js → update-ACV4SAY3.js} +5 -5
  97. package/dist/{update-check-PQ2MZ47K.js → update-check-266R4ZSY.js} +3 -3
  98. package/dist/{version-notify-C5CH7CVP.js → version-notify-XRGTEEDK.js} +37 -23
  99. package/dist/web-assets/assets/index-DtctoDXY.css +1 -0
  100. package/dist/web-assets/assets/index-Wpyb2CML.js +86 -0
  101. package/dist/web-assets/index.html +2 -2
  102. package/drizzle/0011_drop_turn_summary_event_id.sql +3 -0
  103. package/drizzle/0012_channel_gates.sql +17 -0
  104. package/drizzle/meta/_journal.json +14 -0
  105. package/package.json +2 -2
  106. package/templates/_base/src/lib/startup.ts +43 -2
  107. package/templates/claude/src/agent.ts +28 -2
  108. package/templates/claude/src/lib/session-reaper.ts +32 -0
  109. package/templates/claude/src/server.ts +10 -1
  110. package/dist/avatar-image-6KY6UU4D.js +0 -16
  111. package/dist/delivery-manager-JINZRG2W.js +0 -33
  112. package/dist/echo-text-VQPB5L2X.js +0 -33
  113. package/dist/message-delivery-R7JSQGYX.js +0 -37
  114. package/dist/mind-service-NB2JMWQZ.js +0 -39
  115. package/dist/scheduler-WVKII3LA.js +0 -31
  116. package/dist/sleep-manager-G6TXSDP7.js +0 -35
  117. package/dist/system-chat-NDAW6YP7.js +0 -37
  118. package/dist/web-assets/assets/index-B1JBQv2m.css +0 -1
  119. package/dist/web-assets/assets/index-CU6XWICM.js +0 -86
  120. package/dist/{accept-N5XULCXK.js → accept-YAFP5JFJ.js} +3 -3
  121. package/dist/{bridge-2PO3AI5D.js → bridge-TIZGSXOD.js} +3 -3
  122. package/dist/{create-DF3KISTW.js → create-A7PDHIIL.js} +3 -3
  123. package/dist/{env-VZ4MLFQW.js → env-HRL2PWAT.js} +5 -5
  124. package/dist/{extension-SEID47SR.js → extension-QBY4C44L.js} +3 -3
  125. package/dist/{list-OXIAY3W7.js → list-LQO2DCIK.js} +3 -3
  126. package/dist/{login-MY6ETFYB.js → login-6TLMI2TQ.js} +3 -3
  127. package/dist/{logout-NCG3TMDL.js → logout-BK53HXNY.js} +3 -3
  128. package/dist/{mind-history-VRO5A76U.js → mind-history-47DN6ILW.js} +4 -4
  129. package/dist/{mind-wake-LCLGTXA2.js → mind-wake-R54BPESY.js} +3 -3
  130. package/dist/{read-QVAXMTPV.js → read-PWAJOQIQ.js} +3 -3
  131. package/dist/{register-Y2H4PY5R.js → register-7SZJFHU6.js} +3 -3
  132. package/dist/{reject-EV35X64Y.js → reject-6VH7N2A4.js} +3 -3
  133. package/dist/{restart-FJQ662XJ.js → restart-H5WJDMA7.js} +4 -4
  134. package/dist/{skill-FKFHIJRR.js → skill-GUKG2YVH.js} +5 -5
  135. package/dist/{start-5JE3TV66.js → start-X46I3GXB.js} +4 -4
  136. package/dist/{stop-AAMTG3TU.js → stop-HJQV4YSM.js} +4 -4
package/README.md CHANGED
@@ -373,7 +373,7 @@ Set the model via `home/.config/config.json` (SDK config) or `home/.config/volut
373
373
 
374
374
  ```sh
375
375
  docker build -t volute .
376
- docker run -d -p 1618:1618 -v volute-data:/data -v volute-minds:/minds volute
376
+ docker run -d --init -p 1618:1618 -v volute-data:/data -v volute-minds:/minds volute
377
377
  ```
378
378
 
379
379
  Or with docker-compose:
@@ -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,
@@ -25,11 +25,11 @@ import {
25
25
  setProviderRefreshHook,
26
26
  setUtilityModel,
27
27
  unqualifyModelId
28
- } from "./chunk-IHKGWTGT.js";
29
- import "./chunk-F7H6ATM4.js";
28
+ } from "./chunk-LWDTP6DH.js";
29
+ import "./chunk-SKNXMUIU.js";
30
30
  import "./chunk-T2TP6ZC6.js";
31
- import "./chunk-ALKYQULU.js";
32
- import "./chunk-ZV7MFISX.js";
31
+ import "./chunk-WW6C3PLV.js";
32
+ import "./chunk-2MJ7EOMT.js";
33
33
  import "./chunk-K3NQKI34.js";
34
34
  export {
35
35
  addCustomModel,
@@ -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,22 @@
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-VMCZBXF2.js";
10
+ import "./chunk-PFZBNKUH.js";
11
+ import "./chunk-T2TP6ZC6.js";
12
+ import "./chunk-WW6C3PLV.js";
13
+ import "./chunk-2MJ7EOMT.js";
14
+ import "./chunk-K3NQKI34.js";
15
+ export {
16
+ AVATAR_CONTEXT_DIM,
17
+ AVATAR_DIM,
18
+ MAX_AVATAR_BLOCK_BYTES,
19
+ migrateAvatarSizes,
20
+ normalizeAvatar,
21
+ renderAvatarBlock
22
+ };
@@ -1,11 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stopDaemon
4
- } from "./chunk-RRNXJOKB.js";
4
+ } from "./chunk-BGYHLR54.js";
5
5
  import {
6
6
  promptLine,
7
7
  promptPassword
8
8
  } from "./chunk-VHWGEJ4V.js";
9
+ import {
10
+ command,
11
+ subcommands
12
+ } from "./chunk-TXSA4Q3V.js";
13
+ import "./chunk-O7IGP7ZW.js";
9
14
  import {
10
15
  daemonFetch
11
16
  } from "./chunk-RBNMDAKB.js";
@@ -13,37 +18,32 @@ import {
13
18
  getClient,
14
19
  urlOf
15
20
  } from "./chunk-LOPXTW6H.js";
16
- import {
17
- command,
18
- subcommands
19
- } from "./chunk-TXSA4Q3V.js";
20
- import "./chunk-O7IGP7ZW.js";
21
21
  import {
22
22
  RESTIC_INSTALL_HINT,
23
23
  resticVersion,
24
24
  restoreStagedDb
25
- } from "./chunk-FXORA5JG.js";
25
+ } from "./chunk-5NN2VHJV.js";
26
26
  import {
27
27
  getServiceMode,
28
28
  modeLabel,
29
29
  stopService
30
- } from "./chunk-TQJ6ZYVY.js";
30
+ } from "./chunk-CBOIHNMR.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-SKNXMUIU.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);
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveMindName
4
+ } from "./chunk-BTY4WNFE.js";
5
+ import {
6
+ command,
7
+ subcommands
8
+ } from "./chunk-TXSA4Q3V.js";
9
+ import "./chunk-O7IGP7ZW.js";
10
+ import {
11
+ daemonFetch
12
+ } from "./chunk-RBNMDAKB.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-HYDFGC6G.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-LQO2DCIK.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-PWAJOQIQ.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-A7PDHIIL.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-TIZGSXOD.js").then((m) => m.run(args))
32
+ },
33
+ channels: {
34
+ description: "Manage unrouted (gated) channels",
35
+ run: (args) => import("./channels-ITE4YC57.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-FEFZKMNM.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-YAFP5JFJ.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-6VH7N2A4.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";
@@ -2,14 +2,17 @@
2
2
  import {
3
3
  findBridgeForChannel,
4
4
  getBridgeConfig
5
- } from "./chunk-RXEEYDIB.js";
5
+ } from "./chunk-SZJCJVXV.js";
6
6
  import {
7
7
  recordOutbound
8
- } from "./chunk-JO5IO4FH.js";
8
+ } from "./chunk-F55GRIEK.js";
9
9
  import {
10
10
  readEnv,
11
11
  sharedEnvPath
12
- } from "./chunk-ZDZISKCL.js";
12
+ } from "./chunk-IYG4FBMP.js";
13
+ import {
14
+ publish
15
+ } from "./chunk-K23P5Q5N.js";
13
16
  import {
14
17
  addMessage,
15
18
  findDMConversation,
@@ -17,21 +20,18 @@ import {
17
20
  getChannelName,
18
21
  getConversation,
19
22
  getParticipants
20
- } from "./chunk-5ZQZDDIK.js";
23
+ } from "./chunk-HPGN6XRT.js";
21
24
  import {
22
25
  readVoluteConfig
23
26
  } from "./chunk-PFZBNKUH.js";
24
- import {
25
- publish
26
- } from "./chunk-YXSUMLTC.js";
27
27
  import {
28
28
  daemonConfigPath,
29
29
  readDaemonToken
30
- } from "./chunk-TQJ6ZYVY.js";
30
+ } from "./chunk-CBOIHNMR.js";
31
31
  import {
32
32
  getOrCreateMindUser,
33
33
  getUserByUsername
34
- } from "./chunk-OV7ZQ2GH.js";
34
+ } from "./chunk-ODDGGLM6.js";
35
35
  import {
36
36
  logger_default
37
37
  } from "./chunk-T2TP6ZC6.js";
@@ -40,7 +40,7 @@ import {
40
40
  } from "./chunk-LGNUFVMR.js";
41
41
  import {
42
42
  mindDir
43
- } from "./chunk-ALKYQULU.js";
43
+ } from "./chunk-WW6C3PLV.js";
44
44
  import {
45
45
  __export
46
46
  } from "./chunk-K3NQKI34.js";
@@ -7,14 +7,14 @@ import {
7
7
  modeLabel,
8
8
  pollHealth,
9
9
  startService
10
- } from "./chunk-TQJ6ZYVY.js";
10
+ } from "./chunk-CBOIHNMR.js";
11
11
  import {
12
12
  readGlobalConfig
13
- } from "./chunk-F7H6ATM4.js";
13
+ } from "./chunk-SKNXMUIU.js";
14
14
  import {
15
15
  voluteHome,
16
16
  voluteSystemDir
17
- } from "./chunk-ALKYQULU.js";
17
+ } from "./chunk-WW6C3PLV.js";
18
18
 
19
19
  // src/commands/up.ts
20
20
  import { spawn } from "child_process";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exec
4
- } from "./chunk-H2X54EHC.js";
4
+ } from "./chunk-DGGZVZTM.js";
5
5
  import {
6
6
  readGlobalConfig
7
- } from "./chunk-F7H6ATM4.js";
7
+ } from "./chunk-SKNXMUIU.js";
8
8
  import {
9
9
  logger_default
10
10
  } from "./chunk-T2TP6ZC6.js";
@@ -13,7 +13,7 @@ import {
13
13
  readAllMinds,
14
14
  voluteHome,
15
15
  voluteSystemDir
16
- } from "./chunk-ALKYQULU.js";
16
+ } from "./chunk-WW6C3PLV.js";
17
17
 
18
18
  // packages/daemon/src/lib/backup/restic.ts
19
19
  import { writeFileSync } from "fs";
@@ -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
+ };
@@ -8,10 +8,10 @@ import {
8
8
  pollHealthDown,
9
9
  readDaemonConfig,
10
10
  stopService
11
- } from "./chunk-TQJ6ZYVY.js";
11
+ } from "./chunk-CBOIHNMR.js";
12
12
  import {
13
13
  voluteSystemDir
14
- } from "./chunk-ALKYQULU.js";
14
+ } from "./chunk-WW6C3PLV.js";
15
15
 
16
16
  // src/commands/down.ts
17
17
  import { existsSync, readFileSync, unlinkSync } from "fs";
@@ -3,7 +3,7 @@ import {
3
3
  composeTemplate,
4
4
  findTemplatesRoot,
5
5
  listFiles
6
- } from "./chunk-QLWG3C2Z.js";
6
+ } from "./chunk-RRZ4RQQU.js";
7
7
 
8
8
  // packages/daemon/src/lib/template/template-hash.ts
9
9
  import { createHash } from "crypto";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  exec,
4
4
  execInherit
5
- } from "./chunk-H2X54EHC.js";
5
+ } from "./chunk-DGGZVZTM.js";
6
6
  import {
7
7
  voluteSystemDir
8
- } from "./chunk-ALKYQULU.js";
8
+ } from "./chunk-WW6C3PLV.js";
9
9
 
10
10
  // packages/daemon/src/lib/config/service-mode.ts
11
11
  import { execFileSync } from "child_process";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getBaseName,
4
4
  validateMindName
5
- } from "./chunk-ALKYQULU.js";
5
+ } from "./chunk-WW6C3PLV.js";
6
6
 
7
7
  // packages/daemon/src/lib/mind/isolation.ts
8
8
  import { execFileSync as execFileSync2 } from "child_process";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-T2TP6ZC6.js";
5
5
  import {
6
6
  mindDir
7
- } from "./chunk-ALKYQULU.js";
7
+ } from "./chunk-WW6C3PLV.js";
8
8
 
9
9
  // packages/daemon/src/lib/delivery/delivery-router.ts
10
10
  import { readFileSync, statSync } from "fs";