volute 0.41.0 → 0.41.1

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 (132) hide show
  1. package/dist/{accept-AHAOUFBK.js → accept-7YVHZKRD.js} +1 -1
  2. package/dist/{activity-events-EQGBUEZ7.js → activity-events-KFKVRZE3.js} +2 -2
  3. package/dist/{ai-service-ZHEPFC3U.js → ai-service-XCLE3MQP.js} +3 -3
  4. package/dist/{archive-LJAXDDEY.js → archive-4PPYF7LL.js} +2 -2
  5. package/dist/{auth-VYW2ECCE.js → auth-EAASQPTN.js} +3 -3
  6. package/dist/{bridge-F3ZJEKDN.js → bridge-WPYSOQKR.js} +1 -1
  7. package/dist/{chat-FO722GU2.js → chat-7DOENBY2.js} +8 -8
  8. package/dist/{chunk-6TPRURK5.js → chunk-5QG36RV7.js} +2 -2
  9. package/dist/{chunk-GMFCSXWB.js → chunk-62ICA2FF.js} +1 -1
  10. package/dist/{chunk-U7UASV36.js → chunk-763WUVJQ.js} +43 -10
  11. package/dist/{chunk-6ZAT5PYV.js → chunk-BLOAJLGI.js} +1 -1
  12. package/dist/{chunk-2I7OKOYV.js → chunk-CGPESELY.js} +2 -2
  13. package/dist/{chunk-FEQPNCXB.js → chunk-E7XWFDZL.js} +1 -1
  14. package/dist/{chunk-FU5YDH6Q.js → chunk-EKLRS2SX.js} +3 -3
  15. package/dist/{chunk-W5Z2H3LU.js → chunk-F44AEQAW.js} +290 -71
  16. package/dist/{chunk-V67XMNGP.js → chunk-G777ME4L.js} +2 -2
  17. package/dist/{chunk-YATR5BXD.js → chunk-GCS64EAD.js} +4 -4
  18. package/dist/{chunk-Y2XLASFJ.js → chunk-GN52E2DP.js} +1 -1
  19. package/dist/{chunk-ZX7EAV5J.js → chunk-IFNSAOA4.js} +9 -2
  20. package/dist/{chunk-VK2YD7VJ.js → chunk-IJCZAYGT.js} +1 -1
  21. package/dist/{chunk-VDODEQSJ.js → chunk-IUZ3EV2D.js} +4 -0
  22. package/dist/{chunk-2RQIIKFC.js → chunk-K547QOCM.js} +1 -1
  23. package/dist/{chunk-OQ7UEW67.js → chunk-KUJVCDWT.js} +2 -2
  24. package/dist/{chunk-GSOEUMVO.js → chunk-M2YMNTHK.js} +1 -1
  25. package/dist/{chunk-N64Q7FMP.js → chunk-MA7MYEOK.js} +4 -3
  26. package/dist/{chunk-JIGVTFIR.js → chunk-MJIJFCAH.js} +43 -14
  27. package/dist/{chunk-YN6ISG7A.js → chunk-MYJSKXGH.js} +14 -13
  28. package/dist/{chunk-MU2B7A3L.js → chunk-OEJFZHZZ.js} +1 -1
  29. package/dist/{chunk-SWY4DJ67.js → chunk-OSUF75I7.js} +2 -2
  30. package/dist/{chunk-WSRGS4XP.js → chunk-QLWG3C2Z.js} +10 -0
  31. package/dist/{chunk-UU3Q65US.js → chunk-QMJCNZ6C.js} +1 -1
  32. package/dist/{chunk-CYUNO4BM.js → chunk-QPTQKGGF.js} +1 -1
  33. package/dist/{chunk-4ED2DBNC.js → chunk-TFBQESH7.js} +1 -1
  34. package/dist/{chunk-AXNAK3HT.js → chunk-ULNQ6OC4.js} +7 -7
  35. package/dist/{chunk-PP5CGT2P.js → chunk-VBKRZCR7.js} +1 -1
  36. package/dist/{chunk-2R4JIZCB.js → chunk-YLTIEEVL.js} +2 -2
  37. package/dist/cli.js +22 -22
  38. package/dist/{clock-BMLJ2TR6.js → clock-HP2TGMG5.js} +3 -3
  39. package/dist/{cloud-sync-GV6O2HN2.js → cloud-sync-2XVXEOSU.js} +17 -17
  40. package/dist/{config-QB7W3Z7P.js → config-W7MS3PWY.js} +3 -3
  41. package/dist/{conversations-KW7IYESK.js → conversations-FSZCUUYO.js} +3 -3
  42. package/dist/{create-C3BBFYV7.js → create-CJ2SR4EU.js} +1 -1
  43. package/dist/{create-CTPXWFTL.js → create-OTM46ZUM.js} +2 -2
  44. package/dist/{daemon-client-2MIPKY3E.js → daemon-client-EWDPOOHC.js} +3 -1
  45. package/dist/{daemon-restart-W47YDE5E.js → daemon-restart-HDVGTYH7.js} +7 -7
  46. package/dist/daemon.js +218 -300
  47. package/dist/{db-D4FVCA5I.js → db-ZJJJYJBU.js} +1 -1
  48. package/dist/{delete-NLXES2C7.js → delete-4ND5PLE7.js} +1 -1
  49. package/dist/delivery-manager-CPADWRV2.js +33 -0
  50. package/dist/{delivery-router-Y66OXJPM.js → delivery-router-FDBZJQOY.js} +2 -2
  51. package/dist/{down-JVHNXOFU.js → down-DS6WCT34.js} +5 -5
  52. package/dist/echo-text-GEDEEY7M.js +32 -0
  53. package/dist/{env-IQ6Q2333.js → env-XX2MBZCZ.js} +1 -1
  54. package/dist/{exec-R2WWZ6FH.js → exec-ZDD7NEB4.js} +3 -3
  55. package/dist/{export-ZZ5WWBUH.js → export-5DOQV2WM.js} +3 -3
  56. package/dist/{extension-LZYHBNLV.js → extension-BCFYXI7A.js} +4 -1
  57. package/dist/{extensions-AGANCIQA.js → extensions-SU3N4COT.js} +17 -17
  58. package/dist/{files-Q2Z4LQZP.js → files-K2MEMV3W.js} +3 -3
  59. package/dist/{import-MFYCBS4K.js → import-V6QEHMPQ.js} +7 -7
  60. package/dist/{isolation-7F3MA4G7.js → isolation-F7ABZMDA.js} +2 -2
  61. package/dist/{join-6SZCA5FX.js → join-4S3KT7NE.js} +1 -1
  62. package/dist/{list-KHJZJPEJ.js → list-XJB5WII6.js} +1 -1
  63. package/dist/{login-WY3DADVB.js → login-PHMTLNUF.js} +2 -2
  64. package/dist/{login-GYTH67ES.js → login-YWD6PUOT.js} +1 -1
  65. package/dist/{logout-TFZHWNVL.js → logout-BP3R3CAA.js} +2 -2
  66. package/dist/{logout-YHQLOFLR.js → logout-Q2WICH4V.js} +1 -1
  67. package/dist/message-delivery-HPMELC4Q.js +41 -0
  68. package/dist/{mind-XIKEPJNS.js → mind-APS4URT7.js} +18 -18
  69. package/dist/{mind-activity-tracker-RSIWUUJK.js → mind-activity-tracker-HWVFE533.js} +3 -3
  70. package/dist/{mind-history-WHCNZ6I5.js → mind-history-TDUQFYAG.js} +1 -1
  71. package/dist/{mind-list-H3HC2ZRG.js → mind-list-2T353Q5G.js} +1 -1
  72. package/dist/mind-manager-74XQZEGX.js +33 -0
  73. package/dist/{mind-profile-7VYRJGFZ.js → mind-profile-2HHR7LZ7.js} +1 -1
  74. package/dist/mind-service-XGXSMQP6.js +37 -0
  75. package/dist/{mind-sleep-ZL5ZXFTM.js → mind-sleep-4NXV4J4U.js} +1 -1
  76. package/dist/{mind-status-ZWULKOUO.js → mind-status-CG66OXDK.js} +1 -1
  77. package/dist/{mind-wake-HK5ORGUK.js → mind-wake-TNB54DBR.js} +1 -1
  78. package/dist/{package-2X7UNSTQ.js → package-MVFX22K5.js} +2 -1
  79. package/dist/{read-CP7MYMJQ.js → read-JLR4NQXU.js} +1 -1
  80. package/dist/{register-XOBFEMI4.js → register-IQ2M4UO6.js} +1 -1
  81. package/dist/{registry-RAXNFN7K.js → registry-MDLNPTTI.js} +3 -1
  82. package/dist/{reject-43AGXB6B.js → reject-N2D4CZND.js} +1 -1
  83. package/dist/{restart-O5QIYQJT.js → restart-43A5MBGV.js} +1 -1
  84. package/dist/{sandbox-O3GZTS7J.js → sandbox-ND53WZVU.js} +7 -3
  85. package/dist/scheduler-MEBQF5MW.js +31 -0
  86. package/dist/{seed-I4CNKTKZ.js → seed-L4XFZ3VX.js} +1 -1
  87. package/dist/{seed-check-HZPVFJKZ.js → seed-check-N5ALJBT6.js} +1 -1
  88. package/dist/{seed-cmd-YTQYWCZF.js → seed-cmd-NSTPYJFC.js} +3 -3
  89. package/dist/{seed-create-MDBTVADS.js → seed-create-ZYCZC46W.js} +4 -4
  90. package/dist/{seed-sprout-N6O5FBPY.js → seed-sprout-YXHU73XA.js} +8 -8
  91. package/dist/{send-5XA7LRNB.js → send-KQECN2EL.js} +3 -3
  92. package/dist/{service-AY5TGWJX.js → service-Q5OVY5AK.js} +4 -4
  93. package/dist/{service-install-NLGAVTQS.js → service-install-GTDUHP6R.js} +5 -5
  94. package/dist/{setup-3434PQ5Q.js → setup-FPFWDMXD.js} +2 -2
  95. package/dist/{setup-47NBOCZL.js → setup-RMR3TKCR.js} +7 -7
  96. package/dist/{skill-ICN6Y2ZF.js → skill-E43BI34Y.js} +1 -1
  97. package/dist/skills/imagegen/scripts/imagegen.ts +1 -1
  98. package/dist/{skills-YTLBAF32.js → skills-AOZF6U2B.js} +5 -5
  99. package/dist/sleep-manager-OHM3TO62.js +35 -0
  100. package/dist/{spirit-KTBHLULO.js → spirit-ONLRFATY.js} +8 -8
  101. package/dist/{split-5YBEQTBF.js → split-5IBUODEE.js} +1 -1
  102. package/dist/{sprout-4ZUJUNDQ.js → sprout-2KJOQZCL.js} +1 -1
  103. package/dist/{src-OYWRPLC6.js → src-L2Z7X5UT.js} +5 -8
  104. package/dist/{src-4LFGGNW7.js → src-TJ7RBU5H.js} +2 -12
  105. package/dist/{start-LMXXRR3X.js → start-5AYFGNS7.js} +1 -1
  106. package/dist/{status-VMOZUIZ2.js → status-ECZHHSY5.js} +5 -5
  107. package/dist/{stop-TWDKVEUX.js → stop-WJ6IG6OK.js} +1 -1
  108. package/dist/system-chat-HZUKBIKJ.js +35 -0
  109. package/dist/{systems-Y2WZV2K4.js → systems-5MA57Q7G.js} +4 -4
  110. package/dist/{tailscale-PK3AI5EV.js → tailscale-TIRTGM6E.js} +1 -1
  111. package/dist/{template-hash-JARTCRGS.js → template-hash-446HHH5V.js} +2 -2
  112. package/dist/{turn-tracker-SZBSL7LK.js → turn-tracker-TIX4DY2W.js} +4 -4
  113. package/dist/{up-VGVPOB6J.js → up-7KVNER6V.js} +6 -6
  114. package/dist/{update-3ANTQO54.js → update-OPR4KU4M.js} +5 -5
  115. package/dist/{update-check-4O6DKUOF.js → update-check-OG27AL4Z.js} +2 -2
  116. package/dist/{upgrade-RXFZR5FI.js → upgrade-QB7AHIKX.js} +1 -1
  117. package/dist/{version-notify-SSNAWZMX.js → version-notify-UFFDUPCX.js} +19 -19
  118. package/package.json +2 -1
  119. package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +2 -2
  120. package/templates/_base/.init/.config/hooks/pre-prompt/session-activity.ts +3 -3
  121. package/templates/_base/.init/.local/hooks/pre-prompt/notices.ts +3 -3
  122. package/templates/_base/.init/.local/hooks/pre-prompt/session-activity.ts +3 -3
  123. package/templates/_base/src/lib/daemon-client.ts +1 -1
  124. package/templates/_base/src/lib/volute-server.ts +1 -1
  125. package/dist/delivery-manager-EB52CQ5X.js +0 -33
  126. package/dist/echo-text-QVPS6QDM.js +0 -32
  127. package/dist/message-delivery-X4CZE2L6.js +0 -41
  128. package/dist/mind-manager-VU3RGCXD.js +0 -31
  129. package/dist/mind-service-L7LMMDYJ.js +0 -37
  130. package/dist/scheduler-SXELVRWO.js +0 -31
  131. package/dist/sleep-manager-T3AXQB3R.js +0 -35
  132. package/dist/system-chat-HCPHUQGI.js +0 -35
package/dist/daemon.js CHANGED
@@ -6,31 +6,31 @@ import {
6
6
  rejectPending,
7
7
  stageFile,
8
8
  validateFilePath
9
- } from "./chunk-GSOEUMVO.js";
9
+ } from "./chunk-M2YMNTHK.js";
10
10
  import {
11
11
  findOpenClawSession,
12
12
  importOpenClawConnectors,
13
13
  importPiSession,
14
14
  parseNameFromIdentity
15
- } from "./chunk-OQ7UEW67.js";
15
+ } from "./chunk-KUJVCDWT.js";
16
16
  import {
17
17
  checkForUpdate,
18
18
  checkForUpdateCached,
19
19
  getCurrentVersion
20
- } from "./chunk-FEQPNCXB.js";
20
+ } from "./chunk-E7XWFDZL.js";
21
21
  import {
22
22
  isHomeOnlyArchive
23
- } from "./chunk-MU2B7A3L.js";
23
+ } from "./chunk-OEJFZHZZ.js";
24
24
  import {
25
25
  computeTemplateHash
26
- } from "./chunk-UU3Q65US.js";
26
+ } from "./chunk-QMJCNZ6C.js";
27
27
  import {
28
28
  PLATFORMS,
29
29
  echoTextToChannel,
30
30
  fixModelEscapes,
31
31
  getPlatformDriver,
32
32
  routeOutboundBridge
33
- } from "./chunk-AXNAK3HT.js";
33
+ } from "./chunk-ULNQ6OC4.js";
34
34
  import {
35
35
  getBridgeConfig,
36
36
  readBridgesConfig,
@@ -39,12 +39,17 @@ import {
39
39
  resolveChannelMapping,
40
40
  setBridgeConfig,
41
41
  setChannelMapping
42
- } from "./chunk-CYUNO4BM.js";
42
+ } from "./chunk-QPTQKGGF.js";
43
43
  import {
44
44
  RestartTracker,
45
45
  RotatingLog,
46
+ SESSION_MAX_AGE,
46
47
  announceToSystem,
48
+ authMiddleware,
49
+ cleanExpiredSessions,
47
50
  clearDeliveredNotices,
51
+ createSession,
52
+ deleteSession,
48
53
  deleteSystemsConfig,
49
54
  deliverMessage,
50
55
  drainNotices,
@@ -58,6 +63,7 @@ import {
58
63
  getLoadedExtensions,
59
64
  getMindManager,
60
65
  getScheduler,
66
+ getSessionUserId,
61
67
  getSleepManagerIfReady,
62
68
  getTokenBudget,
63
69
  getTypingMap,
@@ -68,6 +74,8 @@ import {
68
74
  initSleepManager,
69
75
  initTokenBudget,
70
76
  installNpmExtension,
77
+ invalidateMindUserCache,
78
+ invalidateSessionCache,
71
79
  isConversationId,
72
80
  joinSystemChannel,
73
81
  linkToolResultToTurn,
@@ -79,7 +87,9 @@ import {
79
87
  recordInbound,
80
88
  recordNotice,
81
89
  recordOutbound,
82
- resolveMindToken,
90
+ requireAdmin,
91
+ requireAdminOrSystem,
92
+ requireSelf,
83
93
  setExtensionEnabled,
84
94
  startMindFull,
85
95
  stopMindFull,
@@ -88,15 +98,15 @@ import {
88
98
  tagUntaggedOutbound,
89
99
  uninstallNpmExtension,
90
100
  writeSystemsConfig
91
- } from "./chunk-W5Z2H3LU.js";
101
+ } from "./chunk-F44AEQAW.js";
92
102
  import {
93
103
  loadMergedEnv,
94
104
  mindEnvPath,
95
105
  readEnv,
96
106
  sharedEnvPath,
97
107
  writeEnv
98
- } from "./chunk-6ZAT5PYV.js";
99
- import "./chunk-YN6ISG7A.js";
108
+ } from "./chunk-BLOAJLGI.js";
109
+ import "./chunk-MYJSKXGH.js";
100
110
  import {
101
111
  applyInitFiles,
102
112
  applyTemplateHomeFiles,
@@ -105,7 +115,7 @@ import {
105
115
  findTemplatesRoot,
106
116
  isKnownTemplate,
107
117
  listFiles
108
- } from "./chunk-WSRGS4XP.js";
118
+ } from "./chunk-QLWG3C2Z.js";
109
119
  import {
110
120
  SEED_SKILLS,
111
121
  STANDARD_SKILLS,
@@ -125,7 +135,7 @@ import {
125
135
  syncBuiltinSkills,
126
136
  uninstallSkill,
127
137
  updateSkill
128
- } from "./chunk-JIGVTFIR.js";
138
+ } from "./chunk-MJIJFCAH.js";
129
139
  import {
130
140
  addMessage,
131
141
  createChannel,
@@ -157,20 +167,23 @@ import {
157
167
  setConversationPrivate,
158
168
  subscribe as subscribe2,
159
169
  updateChannelSettings
160
- } from "./chunk-2R4JIZCB.js";
170
+ } from "./chunk-YLTIEEVL.js";
161
171
  import {
162
172
  readVoluteConfig,
163
173
  writeVoluteConfig
164
174
  } from "./chunk-CU6OFXMM.js";
165
- import "./chunk-U7UASV36.js";
175
+ import {
176
+ isSandboxEnabled,
177
+ wrapForSandbox
178
+ } from "./chunk-763WUVJQ.js";
166
179
  import {
167
180
  getActiveMinds,
168
181
  onMindEvent,
169
182
  stopAll
170
- } from "./chunk-PP5CGT2P.js";
183
+ } from "./chunk-VBKRZCR7.js";
171
184
  import {
172
185
  extractTextContent
173
- } from "./chunk-GMFCSXWB.js";
186
+ } from "./chunk-62ICA2FF.js";
174
187
  import {
175
188
  PROMPT_DEFAULTS,
176
189
  PROMPT_KEYS,
@@ -193,12 +206,12 @@ import {
193
206
  summarizeTurn,
194
207
  takeErrored,
195
208
  trackToolUse
196
- } from "./chunk-YATR5BXD.js";
209
+ } from "./chunk-GCS64EAD.js";
197
210
  import {
198
211
  exec,
199
212
  gitExec,
200
213
  resolveVoluteBin
201
- } from "./chunk-Y2XLASFJ.js";
214
+ } from "./chunk-GN52E2DP.js";
202
215
  import {
203
216
  chownMindDir,
204
217
  createMindUser,
@@ -206,7 +219,7 @@ import {
206
219
  ensureVoluteGroup,
207
220
  isIsolationEnabled,
208
221
  wrapForIsolation
209
- } from "./chunk-4ED2DBNC.js";
222
+ } from "./chunk-TFBQESH7.js";
210
223
  import {
211
224
  getAiConfig,
212
225
  getAvailableModels,
@@ -223,12 +236,12 @@ import {
223
236
  setProviderRefreshHook,
224
237
  setUtilityModel,
225
238
  unqualifyModelId
226
- } from "./chunk-VK2YD7VJ.js";
239
+ } from "./chunk-IJCZAYGT.js";
227
240
  import {
228
241
  isSetupComplete,
229
242
  readGlobalConfig,
230
243
  writeGlobalConfig
231
- } from "./chunk-N64Q7FMP.js";
244
+ } from "./chunk-MA7MYEOK.js";
232
245
  import {
233
246
  approveUser,
234
247
  changePassword,
@@ -247,11 +260,11 @@ import {
247
260
  syncMindProfile,
248
261
  updateUserProfile,
249
262
  verifyUser
250
- } from "./chunk-6TPRURK5.js";
263
+ } from "./chunk-5QG36RV7.js";
251
264
  import {
252
265
  broadcast,
253
266
  subscribe
254
- } from "./chunk-2RQIIKFC.js";
267
+ } from "./chunk-K547QOCM.js";
255
268
  import {
256
269
  logBuffer,
257
270
  logger_default
@@ -270,6 +283,7 @@ import {
270
283
  getBaseName,
271
284
  getDb,
272
285
  mindDir,
286
+ mindTmpDir,
273
287
  nextPort,
274
288
  readAllMinds,
275
289
  readRegistry,
@@ -282,14 +296,13 @@ import {
282
296
  validateMindName,
283
297
  voluteHome,
284
298
  voluteSystemDir
285
- } from "./chunk-VDODEQSJ.js";
299
+ } from "./chunk-IUZ3EV2D.js";
286
300
  import {
287
301
  activity,
288
302
  channels,
289
303
  conversationParticipants,
290
304
  conversations,
291
305
  mindHistory,
292
- sessions,
293
306
  summaries,
294
307
  systemPrompts,
295
308
  turns,
@@ -299,7 +312,7 @@ import "./chunk-K3NQKI34.js";
299
312
 
300
313
  // packages/daemon/src/daemon.ts
301
314
  import { randomBytes } from "crypto";
302
- import { mkdirSync as mkdirSync10, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
315
+ import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
303
316
  import { homedir as homedir3 } from "os";
304
317
  import { resolve as resolve17 } from "path";
305
318
  import { format } from "util";
@@ -834,150 +847,6 @@ async function generateImage(model, prompt) {
834
847
  return PROVIDERS[providerId].generate(modelId, prompt, apiKey);
835
848
  }
836
849
 
837
- // packages/daemon/src/web/middleware/auth.ts
838
- import { timingSafeEqual } from "crypto";
839
- import { eq as eq2, lt as lt2 } from "drizzle-orm";
840
- import { getCookie } from "hono/cookie";
841
- import { createMiddleware } from "hono/factory";
842
- var MIND_USER_CACHE_TTL = 5 * 60 * 1e3;
843
- var mindUserCache = /* @__PURE__ */ new Map();
844
- function invalidateMindUserCache(mindName) {
845
- mindUserCache.delete(mindName);
846
- }
847
- function isValidDaemonToken(token) {
848
- const expected = process.env.VOLUTE_DAEMON_TOKEN;
849
- if (!expected || token.length !== expected.length) return false;
850
- return timingSafeEqual(Buffer.from(token), Buffer.from(expected));
851
- }
852
- var SESSION_MAX_AGE = 365 * 24 * 60 * 60 * 1e3;
853
- var SESSION_CACHE_TTL = 5 * 60 * 1e3;
854
- var sessionCache = /* @__PURE__ */ new Map();
855
- function invalidateSessionCache(sessionId) {
856
- sessionCache.delete(sessionId);
857
- }
858
- async function createSession(userId) {
859
- const db = await getDb();
860
- const sessionId = crypto.randomUUID();
861
- await db.insert(sessions).values({ id: sessionId, userId, createdAt: Date.now() });
862
- return sessionId;
863
- }
864
- async function deleteSession(sessionId) {
865
- sessionCache.delete(sessionId);
866
- const db = await getDb();
867
- await db.delete(sessions).where(eq2(sessions.id, sessionId));
868
- }
869
- async function getSessionUserId(sessionId) {
870
- const db = await getDb();
871
- const row = await db.select().from(sessions).where(eq2(sessions.id, sessionId)).get();
872
- if (!row) return void 0;
873
- if (Date.now() - row.createdAt > SESSION_MAX_AGE) {
874
- await db.delete(sessions).where(eq2(sessions.id, sessionId));
875
- return void 0;
876
- }
877
- return row.userId;
878
- }
879
- async function cleanExpiredSessions() {
880
- const db = await getDb();
881
- const cutoff = Date.now() - SESSION_MAX_AGE;
882
- await db.delete(sessions).where(lt2(sessions.createdAt, cutoff));
883
- }
884
- var requireAdmin = createMiddleware(async (c, next) => {
885
- const user = c.get("user");
886
- if (user.role !== "admin") {
887
- return c.json({ error: "Forbidden" }, 403);
888
- }
889
- await next();
890
- });
891
- var requireAdminOrSystem = createMiddleware(async (c, next) => {
892
- const user = c.get("user");
893
- if (user.role !== "admin" && user.role !== "system") {
894
- return c.json({ error: "Forbidden" }, 403);
895
- }
896
- await next();
897
- });
898
- async function resolveSession(sessionId) {
899
- const cached = sessionCache.get(sessionId);
900
- if (cached && cached.expires > Date.now()) {
901
- return cached.user;
902
- }
903
- const userId = await getSessionUserId(sessionId);
904
- if (userId == null) {
905
- sessionCache.delete(sessionId);
906
- return null;
907
- }
908
- const user = await getUser(userId);
909
- if (!user) {
910
- sessionCache.delete(sessionId);
911
- return null;
912
- }
913
- sessionCache.set(sessionId, { userId, user, expires: Date.now() + SESSION_CACHE_TTL });
914
- return user;
915
- }
916
- var authMiddleware = createMiddleware(async (c, next) => {
917
- const authHeader = c.req.header("Authorization");
918
- if (authHeader?.startsWith("Bearer ")) {
919
- const token = authHeader.slice(7);
920
- if (token && isValidDaemonToken(token)) {
921
- c.set("user", {
922
- id: 0,
923
- username: "daemon",
924
- role: "admin",
925
- user_type: "brain",
926
- display_name: null,
927
- description: null,
928
- avatar: null
929
- });
930
- const mindSessionHeader = c.req.header("X-Volute-Session");
931
- if (mindSessionHeader) c.set("mindSession", mindSessionHeader);
932
- await next();
933
- return;
934
- }
935
- const mindName = resolveMindToken(token);
936
- if (mindName) {
937
- const cached = mindUserCache.get(mindName);
938
- let mindUser;
939
- if (cached && Date.now() - cached.ts < MIND_USER_CACHE_TTL) {
940
- mindUser = cached.user;
941
- } else {
942
- mindUser = await getOrCreateMindUser(mindName);
943
- mindUserCache.set(mindName, { user: mindUser, ts: Date.now() });
944
- }
945
- c.set("user", mindUser);
946
- const mindSessionHeader = c.req.header("X-Volute-Session");
947
- if (mindSessionHeader) c.set("mindSession", mindSessionHeader);
948
- await next();
949
- return;
950
- }
951
- if (token) {
952
- const user2 = await resolveSession(token);
953
- if (user2) {
954
- if (user2.role === "pending") return c.json({ error: "Account pending approval" }, 403);
955
- c.set("user", user2);
956
- await next();
957
- return;
958
- }
959
- }
960
- }
961
- const sessionId = getCookie(c, "volute_session");
962
- if (!sessionId) return c.json({ error: "Unauthorized" }, 401);
963
- const user = await resolveSession(sessionId);
964
- if (!user) return c.json({ error: "Unauthorized" }, 401);
965
- if (user.role === "pending") return c.json({ error: "Account pending approval" }, 403);
966
- c.set("user", user);
967
- await next();
968
- });
969
- var requireSelf = (paramName = "name") => createMiddleware(async (c, next) => {
970
- const user = c.get("user");
971
- if (user.role !== "admin" && user.role !== "system") {
972
- const target = c.req.param(paramName) ?? "";
973
- const baseName = await getBaseName(target);
974
- if (user.username !== baseName) {
975
- return c.json({ error: "Forbidden" }, 403);
976
- }
977
- }
978
- await next();
979
- });
980
-
981
850
  // packages/daemon/src/web/api/system.ts
982
851
  var DEFAULT_API_URL = "https://volute.systems";
983
852
  var igLog = logger_default.child("imagegen");
@@ -1632,7 +1501,7 @@ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as rea
1632
1501
  import { extname, resolve as resolve3 } from "path";
1633
1502
  import { zValidator as zValidator2 } from "@hono/zod-validator";
1634
1503
  import { Hono as Hono3 } from "hono";
1635
- import { deleteCookie, getCookie as getCookie2, setCookie } from "hono/cookie";
1504
+ import { deleteCookie, getCookie, setCookie } from "hono/cookie";
1636
1505
  import { z as z2 } from "zod";
1637
1506
  function tryJoinSystem(userId) {
1638
1507
  if (!process.env.VOLUTE_DAEMON_TOKEN) return;
@@ -1678,7 +1547,7 @@ var authenticated = new Hono3().use(authMiddleware).post("/change-password", zVa
1678
1547
  const user = c.get("user");
1679
1548
  const body = c.req.valid("json");
1680
1549
  await updateUserProfile(user.id, body);
1681
- const sessionId = getCookie2(c, "volute_session");
1550
+ const sessionId = getCookie(c, "volute_session");
1682
1551
  if (sessionId) invalidateSessionCache(sessionId);
1683
1552
  broadcast({
1684
1553
  type: "profile_updated",
@@ -1710,7 +1579,7 @@ var authenticated = new Hono3().use(authMiddleware).post("/change-password", zVa
1710
1579
  rmSync(oldPath, { force: true });
1711
1580
  }
1712
1581
  await updateUserProfile(user.id, { avatar: filename });
1713
- const sessionId = getCookie2(c, "volute_session");
1582
+ const sessionId = getCookie(c, "volute_session");
1714
1583
  if (sessionId) invalidateSessionCache(sessionId);
1715
1584
  broadcast({
1716
1585
  type: "profile_updated",
@@ -1725,7 +1594,7 @@ var authenticated = new Hono3().use(authMiddleware).post("/change-password", zVa
1725
1594
  rmSync(path, { force: true });
1726
1595
  }
1727
1596
  await updateUserProfile(user.id, { avatar: null });
1728
- const sessionId = getCookie2(c, "volute_session");
1597
+ const sessionId = getCookie(c, "volute_session");
1729
1598
  if (sessionId) invalidateSessionCache(sessionId);
1730
1599
  broadcast({
1731
1600
  type: "profile_updated",
@@ -1836,7 +1705,7 @@ var app3 = new Hono3().post("/register", zValidator2("json", credentialsSchema),
1836
1705
  tryJoinSystem(user.id);
1837
1706
  return c.json({ id: user.id, username: user.username, role: user.role, sessionId });
1838
1707
  }).post("/logout", async (c) => {
1839
- const cookieSession = getCookie2(c, "volute_session");
1708
+ const cookieSession = getCookie(c, "volute_session");
1840
1709
  if (cookieSession) {
1841
1710
  await deleteSession(cookieSession);
1842
1711
  deleteCookie(c, "volute_session", { path: "/" });
@@ -1851,7 +1720,7 @@ var app3 = new Hono3().post("/register", zValidator2("json", credentialsSchema),
1851
1720
  }
1852
1721
  return c.json({ ok: true });
1853
1722
  }).get("/me", async (c) => {
1854
- let sessionId = getCookie2(c, "volute_session");
1723
+ let sessionId = getCookie(c, "volute_session");
1855
1724
  if (!sessionId) {
1856
1725
  const authHeader = c.req.header("Authorization");
1857
1726
  if (authHeader?.startsWith("Bearer ")) {
@@ -1898,7 +1767,7 @@ import { Hono as Hono4 } from "hono";
1898
1767
  import { z as z3 } from "zod";
1899
1768
 
1900
1769
  // packages/daemon/src/lib/chat/puppets.ts
1901
- import { and as and2, eq as eq3 } from "drizzle-orm";
1770
+ import { and as and2, eq as eq2 } from "drizzle-orm";
1902
1771
  async function findOrCreatePuppet(platform, platformId, displayName) {
1903
1772
  const username = `${platform}:${platformId}`;
1904
1773
  const db = await getDb();
@@ -1907,10 +1776,10 @@ async function findOrCreatePuppet(platform, platformId, displayName) {
1907
1776
  username: users.username,
1908
1777
  display_name: users.display_name,
1909
1778
  avatar: users.avatar
1910
- }).from(users).where(and2(eq3(users.username, username), eq3(users.user_type, "puppet"))).get();
1779
+ }).from(users).where(and2(eq2(users.username, username), eq2(users.user_type, "puppet"))).get();
1911
1780
  if (existing) {
1912
1781
  if (existing.display_name !== displayName) {
1913
- await db.update(users).set({ display_name: displayName }).where(eq3(users.id, existing.id));
1782
+ await db.update(users).set({ display_name: displayName }).where(eq2(users.id, existing.id));
1914
1783
  existing.display_name = displayName;
1915
1784
  }
1916
1785
  return existing;
@@ -1936,7 +1805,7 @@ async function findOrCreatePuppet(platform, platformId, displayName) {
1936
1805
  username: users.username,
1937
1806
  display_name: users.display_name,
1938
1807
  avatar: users.avatar
1939
- }).from(users).where(and2(eq3(users.username, username), eq3(users.user_type, "puppet"))).get();
1808
+ }).from(users).where(and2(eq2(users.username, username), eq2(users.user_type, "puppet"))).get();
1940
1809
  if (retried) return retried;
1941
1810
  }
1942
1811
  throw err;
@@ -2016,7 +1885,7 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
2016
1885
  }
2017
1886
  const participants = await getParticipants(channel.id);
2018
1887
  if (!participants.some((p) => p.userId === puppet.id)) {
2019
- const { addParticipant } = await import("./conversations-KW7IYESK.js");
1888
+ const { addParticipant } = await import("./conversations-FSZCUUYO.js");
2020
1889
  await addParticipant(channel.id, puppet.id);
2021
1890
  }
2022
1891
  const contentBlocks = body.content;
@@ -2109,8 +1978,8 @@ async function fanOutToBridgedMinds(opts) {
2109
1978
  const participants = await getParticipants(opts.conversationId);
2110
1979
  const mindParticipants = participants.filter((p) => p.userType === "mind");
2111
1980
  const participantNames = participants.map((p) => p.username);
2112
- const { getMindManager: getMindManager2 } = await import("./mind-manager-VU3RGCXD.js");
2113
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
1981
+ const { getMindManager: getMindManager2 } = await import("./mind-manager-74XQZEGX.js");
1982
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
2114
1983
  const manager = getMindManager2();
2115
1984
  const sm = getSleepManagerIfReady2();
2116
1985
  const targetMinds = mindParticipants.filter((ap) => {
@@ -2322,7 +2191,7 @@ async function notifyMind(mindName, message) {
2322
2191
  const entry = await findMind(mindName);
2323
2192
  if (!entry) return;
2324
2193
  try {
2325
- const { sendSystemMessage } = await import("./system-chat-HCPHUQGI.js");
2194
+ const { sendSystemMessage } = await import("./system-chat-HZUKBIKJ.js");
2326
2195
  await sendSystemMessage(mindName, message);
2327
2196
  } catch (err) {
2328
2197
  logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
@@ -2632,18 +2501,25 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
2632
2501
  var files_default = app9;
2633
2502
 
2634
2503
  // packages/daemon/src/web/api/history.ts
2635
- import { and as and3, desc as desc2, eq as eq4, gte, inArray, sql } from "drizzle-orm";
2504
+ import { and as and3, desc as desc2, eq as eq3, gte, inArray, sql } from "drizzle-orm";
2636
2505
  import { Hono as Hono11 } from "hono";
2506
+ async function resolveMindFilter(c) {
2507
+ const user = c.get("user");
2508
+ if (user.role === "admin" || user.role === "system") {
2509
+ return c.req.query("mind") ?? void 0;
2510
+ }
2511
+ return getBaseName(user.username);
2512
+ }
2637
2513
  var history = new Hono11().get("/turns", async (c) => {
2638
- const mindFilter = c.req.query("mind");
2514
+ const mindFilter = await resolveMindFilter(c);
2639
2515
  const turnIdFilter = c.req.query("turnId");
2640
2516
  const turnIdsFilter = c.req.query("turnIds");
2641
2517
  const limit = Math.min(Math.max(parseInt(c.req.query("limit") ?? "50", 10) || 50, 1), 200);
2642
2518
  const offset = Math.max(parseInt(c.req.query("offset") ?? "0", 10) || 0, 0);
2643
2519
  const db = await getDb();
2644
2520
  const conditions = [];
2645
- if (mindFilter) conditions.push(eq4(turns.mind, mindFilter));
2646
- if (turnIdFilter) conditions.push(eq4(turns.id, turnIdFilter));
2521
+ if (mindFilter) conditions.push(eq3(turns.mind, mindFilter));
2522
+ if (turnIdFilter) conditions.push(eq3(turns.id, turnIdFilter));
2647
2523
  if (turnIdsFilter) {
2648
2524
  const ids = turnIdsFilter.split(",").filter(Boolean);
2649
2525
  if (ids.length > 0) conditions.push(inArray(turns.id, ids));
@@ -2651,7 +2527,7 @@ var history = new Hono11().get("/turns", async (c) => {
2651
2527
  const turnRows = await db.select().from(turns).where(conditions.length > 0 ? and3(...conditions) : void 0).orderBy(desc2(turns.created_at)).limit(limit).offset(offset);
2652
2528
  if (turnRows.length === 0) return c.json([]);
2653
2529
  const turnIds = turnRows.map((t) => t.id);
2654
- const summaryRows = await db.select().from(summaries).where(and3(eq4(summaries.period, "turn"), inArray(summaries.period_key, turnIds)));
2530
+ const summaryRows = await db.select().from(summaries).where(and3(eq3(summaries.period, "turn"), inArray(summaries.period_key, turnIds)));
2655
2531
  const summaryByTurn = /* @__PURE__ */ new Map();
2656
2532
  for (const s of summaryRows) {
2657
2533
  summaryByTurn.set(s.period_key, { content: s.content, metadata: s.metadata });
@@ -2776,15 +2652,15 @@ var history = new Hono11().get("/turns", async (c) => {
2776
2652
  db.select({
2777
2653
  conversation_id: conversationParticipants.conversation_id,
2778
2654
  username: users.username
2779
- }).from(conversationParticipants).innerJoin(users, eq4(conversationParticipants.user_id, users.id))
2655
+ }).from(conversationParticipants).innerJoin(users, eq3(conversationParticipants.user_id, users.id))
2780
2656
  );
2781
2657
  const dmRows = await db.with(cp2).select({
2782
2658
  id: conversations.id,
2783
2659
  targetUsername: users.username
2784
2660
  }).from(conversations).innerJoin(
2785
2661
  conversationParticipants,
2786
- eq4(conversations.id, conversationParticipants.conversation_id)
2787
- ).innerJoin(users, eq4(conversationParticipants.user_id, users.id)).where(and3(eq4(conversations.type, "dm"), inArray(users.username, targetNames)));
2662
+ eq3(conversations.id, conversationParticipants.conversation_id)
2663
+ ).innerJoin(users, eq3(conversationParticipants.user_id, users.id)).where(and3(eq3(conversations.type, "dm"), inArray(users.username, targetNames)));
2788
2664
  const dmCandidates = [];
2789
2665
  for (const row of dmRows) {
2790
2666
  const slug = `@${row.targetUsername}`;
@@ -2799,7 +2675,7 @@ var history = new Hono11().get("/turns", async (c) => {
2799
2675
  const verifyRows = await db.select({
2800
2676
  conversation_id: conversationParticipants.conversation_id,
2801
2677
  username: users.username
2802
- }).from(conversationParticipants).innerJoin(users, eq4(conversationParticipants.user_id, users.id)).where(
2678
+ }).from(conversationParticipants).innerJoin(users, eq3(conversationParticipants.user_id, users.id)).where(
2803
2679
  and3(
2804
2680
  inArray(conversationParticipants.conversation_id, candidateConvIds),
2805
2681
  inArray(users.username, allMindNames)
@@ -2877,7 +2753,7 @@ var history = new Hono11().get("/turns", async (c) => {
2877
2753
  });
2878
2754
  return c.json(result);
2879
2755
  }).get("/events", async (c) => {
2880
- const mindFilter = c.req.query("mind");
2756
+ const mindFilter = await resolveMindFilter(c);
2881
2757
  const stream = new ReadableStream({
2882
2758
  start(controller) {
2883
2759
  const encoder = new TextEncoder();
@@ -2932,7 +2808,9 @@ var history = new Hono11().get("/turns", async (c) => {
2932
2808
  }
2933
2809
  });
2934
2810
  }).get("/summaries", async (c) => {
2935
- const mind = c.req.query("mind") ?? "_system";
2811
+ const user = c.get("user");
2812
+ const privileged = user.role === "admin" || user.role === "system";
2813
+ const mind = privileged ? c.req.query("mind") ?? "_system" : await getBaseName(user.username);
2936
2814
  const period = c.req.query("period");
2937
2815
  const ids = c.req.query("ids");
2938
2816
  const from = c.req.query("from");
@@ -2942,7 +2820,9 @@ var history = new Hono11().get("/turns", async (c) => {
2942
2820
  const db2 = await getDb();
2943
2821
  const idList = ids.split(",").map((s) => parseInt(s, 10)).filter((n) => !Number.isNaN(n));
2944
2822
  if (idList.length === 0) return c.json([]);
2945
- const rows2 = await db2.select().from(summaries).where(inArray(summaries.id, idList));
2823
+ const idConditions = [inArray(summaries.id, idList)];
2824
+ if (!privileged) idConditions.push(eq3(summaries.mind, mind));
2825
+ const rows2 = await db2.select().from(summaries).where(and3(...idConditions));
2946
2826
  const result2 = rows2.map((r) => {
2947
2827
  let metadata = null;
2948
2828
  if (r.metadata) {
@@ -2960,7 +2840,7 @@ var history = new Hono11().get("/turns", async (c) => {
2960
2840
  return c.json({ error: "period is required (turn, hour, day, week, month)" }, 400);
2961
2841
  }
2962
2842
  const db = await getDb();
2963
- const conditions = [eq4(summaries.mind, mind), eq4(summaries.period, period)];
2843
+ const conditions = [eq3(summaries.mind, mind), eq3(summaries.period, period)];
2964
2844
  if (from) conditions.push(gte(summaries.period_key, from));
2965
2845
  if (to) conditions.push(sql`${summaries.period_key} <= ${to}`);
2966
2846
  const rows = await db.select({
@@ -2985,13 +2865,13 @@ var history = new Hono11().get("/turns", async (c) => {
2985
2865
  });
2986
2866
  return c.json(result);
2987
2867
  }).get("/activity", async (c) => {
2988
- const mind = c.req.query("mind");
2868
+ const mind = await resolveMindFilter(c);
2989
2869
  const from = c.req.query("from");
2990
2870
  const to = c.req.query("to");
2991
2871
  const limit = Math.min(Math.max(parseInt(c.req.query("limit") ?? "100", 10) || 100, 1), 500);
2992
2872
  const db = await getDb();
2993
2873
  const conditions = [];
2994
- if (mind) conditions.push(eq4(activity.mind, mind));
2874
+ if (mind) conditions.push(eq3(activity.mind, mind));
2995
2875
  if (from) conditions.push(gte(activity.created_at, from));
2996
2876
  if (to) conditions.push(sql`${activity.created_at} <= ${to}`);
2997
2877
  conditions.push(
@@ -3246,7 +3126,7 @@ import {
3246
3126
  } from "fs";
3247
3127
  import { basename, resolve as resolve11 } from "path";
3248
3128
  import { zValidator as zValidator5 } from "@hono/zod-validator";
3249
- import { and as and4, desc as desc3, eq as eq5, sql as sql2 } from "drizzle-orm";
3129
+ import { and as and4, desc as desc3, eq as eq4, sql as sql2 } from "drizzle-orm";
3250
3130
  import { Hono as Hono15 } from "hono";
3251
3131
  import { z as z5 } from "zod";
3252
3132
 
@@ -3368,7 +3248,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
3368
3248
  logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
3369
3249
  }
3370
3250
  }
3371
- const { findMind: findMind2 } = await import("./registry-RAXNFN7K.js");
3251
+ const { findMind: findMind2 } = await import("./registry-MDLNPTTI.js");
3372
3252
  const variantEntry = await findMind2(variantName);
3373
3253
  const branchName = variantEntry?.branch ?? variantName;
3374
3254
  if (existsSync6(variantPath)) {
@@ -3625,7 +3505,7 @@ async function getMindStatus(name, port, registryRunning) {
3625
3505
  const manager = getMindManager();
3626
3506
  let status = "stopped";
3627
3507
  try {
3628
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
3508
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
3629
3509
  if (getSleepManagerIfReady2()?.isSleeping(name)) {
3630
3510
  status = "sleeping";
3631
3511
  }
@@ -4120,7 +4000,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4120
4000
  applyInitFiles(dest);
4121
4001
  const { publicKeyPem } = generateIdentity(dest);
4122
4002
  {
4123
- const { readGlobalConfig: readGlobal } = await import("./setup-3434PQ5Q.js");
4003
+ const { readGlobalConfig: readGlobal } = await import("./setup-FPFWDMXD.js");
4124
4004
  const mindDefaults = readGlobal().mindDefaults;
4125
4005
  const config2 = readVoluteConfig(dest);
4126
4006
  if (!config2) throw new Error("Failed to read volute.json after identity generation");
@@ -4211,7 +4091,7 @@ The human who planted you described you as: "${body.description}"
4211
4091
  }
4212
4092
  let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
4213
4093
  if (body.stage === "seed" && !body.skills) {
4214
- const { isImagegenEnabled } = await import("./setup-3434PQ5Q.js");
4094
+ const { isImagegenEnabled } = await import("./setup-FPFWDMXD.js");
4215
4095
  if (isImagegenEnabled()) {
4216
4096
  skillSet = [...skillSet, "imagegen"];
4217
4097
  }
@@ -4229,7 +4109,7 @@ The human who planted you described you as: "${body.description}"
4229
4109
  try {
4230
4110
  const spiritEntry = await findMind("volute");
4231
4111
  if (spiritEntry) {
4232
- const { spiritDir } = await import("./spirit-KTBHLULO.js");
4112
+ const { spiritDir } = await import("./spirit-ONLRFATY.js");
4233
4113
  const sDir = spiritEntry.dir ?? spiritDir();
4234
4114
  const spiritConfig = readVoluteConfig(sDir) ?? {};
4235
4115
  const schedules = spiritConfig.schedules ?? [];
@@ -4244,7 +4124,7 @@ The human who planted you described you as: "${body.description}"
4244
4124
  });
4245
4125
  spiritConfig.schedules = schedules;
4246
4126
  writeVoluteConfig(sDir, spiritConfig);
4247
- const { getScheduler: getScheduler2 } = await import("./scheduler-SXELVRWO.js");
4127
+ const { getScheduler: getScheduler2 } = await import("./scheduler-MEBQF5MW.js");
4248
4128
  getScheduler2().loadSchedules("volute", sDir);
4249
4129
  }
4250
4130
  }
@@ -4509,7 +4389,7 @@ ${user.trimEnd()}
4509
4389
  const manager = getMindManager();
4510
4390
  try {
4511
4391
  if (context?.type === "reload") {
4512
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
4392
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
4513
4393
  const sleepState = getSleepManagerIfReady2()?.getState(name);
4514
4394
  if (sleepState?.sleeping) {
4515
4395
  logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
@@ -4604,7 +4484,7 @@ ${user.trimEnd()}
4604
4484
  const name = c.req.param("name");
4605
4485
  const entry = await findMind(name);
4606
4486
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4607
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
4487
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
4608
4488
  const sm = getSleepManagerIfReady2();
4609
4489
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4610
4490
  return c.json(sm.getState(name));
@@ -4612,7 +4492,7 @@ ${user.trimEnd()}
4612
4492
  const name = c.req.param("name");
4613
4493
  const entry = await findMind(name);
4614
4494
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4615
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
4495
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
4616
4496
  const sm = getSleepManagerIfReady2();
4617
4497
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4618
4498
  if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
@@ -4632,7 +4512,7 @@ ${user.trimEnd()}
4632
4512
  const name = c.req.param("name");
4633
4513
  const entry = await findMind(name);
4634
4514
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4635
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
4515
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
4636
4516
  const sm = getSleepManagerIfReady2();
4637
4517
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4638
4518
  const sleepState = sm.getState(name);
@@ -4647,7 +4527,7 @@ ${user.trimEnd()}
4647
4527
  const name = c.req.param("name");
4648
4528
  const entry = await findMind(name);
4649
4529
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4650
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
4530
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
4651
4531
  const sm = getSleepManagerIfReady2();
4652
4532
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4653
4533
  const flushed = await sm.flushQueuedMessages(name);
@@ -4665,7 +4545,7 @@ ${user.trimEnd()}
4665
4545
  if (body.avatar !== void 0) profile.avatar = basename(body.avatar);
4666
4546
  config2.profile = profile;
4667
4547
  writeVoluteConfig(dir, config2);
4668
- const { syncMindProfile: syncMindProfile2 } = await import("./auth-VYW2ECCE.js");
4548
+ const { syncMindProfile: syncMindProfile2 } = await import("./auth-EAASQPTN.js");
4669
4549
  await syncMindProfile2(name, profile);
4670
4550
  broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
4671
4551
  return c.json({ ok: true });
@@ -4682,8 +4562,8 @@ ${user.trimEnd()}
4682
4562
  const spiritThreshold = Number.isNaN(rawSpirit) ? 15 : rawSpirit;
4683
4563
  const lastCreatorMsg = await db.select({ created_at: mindHistory.created_at }).from(mindHistory).where(
4684
4564
  and4(
4685
- eq5(mindHistory.mind, name),
4686
- eq5(mindHistory.type, "inbound"),
4565
+ eq4(mindHistory.mind, name),
4566
+ eq4(mindHistory.type, "inbound"),
4687
4567
  sql2`${mindHistory.sender} != 'volute'`,
4688
4568
  sql2`${mindHistory.sender} != ${name}`,
4689
4569
  sql2`${mindHistory.sender} IS NOT NULL`
@@ -4691,9 +4571,9 @@ ${user.trimEnd()}
4691
4571
  ).orderBy(desc3(mindHistory.created_at)).limit(1);
4692
4572
  const lastSpiritMsg = await db.select({ created_at: mindHistory.created_at }).from(mindHistory).where(
4693
4573
  and4(
4694
- eq5(mindHistory.mind, name),
4695
- eq5(mindHistory.type, "inbound"),
4696
- eq5(mindHistory.sender, "volute")
4574
+ eq4(mindHistory.mind, name),
4575
+ eq4(mindHistory.type, "inbound"),
4576
+ eq4(mindHistory.sender, "volute")
4697
4577
  )
4698
4578
  ).orderBy(desc3(mindHistory.created_at)).limit(1);
4699
4579
  const now = Date.now();
@@ -4712,7 +4592,7 @@ ${user.trimEnd()}
4712
4592
  const config2 = readVoluteConfig(dir);
4713
4593
  const displayNameSet = !!config2?.profile?.displayName;
4714
4594
  const avatarSet = !!config2?.profile?.avatar;
4715
- const { isImagegenEnabled } = await import("./setup-3434PQ5Q.js");
4595
+ const { isImagegenEnabled } = await import("./setup-FPFWDMXD.js");
4716
4596
  const imagegenEnabled = isImagegenEnabled();
4717
4597
  const done = [];
4718
4598
  const remaining = [];
@@ -4750,7 +4630,7 @@ ${user.trimEnd()}
4750
4630
  try {
4751
4631
  const spiritEntry = await findMind("volute");
4752
4632
  if (spiritEntry) {
4753
- const { spiritDir } = await import("./spirit-KTBHLULO.js");
4633
+ const { spiritDir } = await import("./spirit-ONLRFATY.js");
4754
4634
  const sDir = spiritEntry.dir ?? spiritDir();
4755
4635
  const spiritConfig = readVoluteConfig(sDir);
4756
4636
  if (spiritConfig?.schedules) {
@@ -4758,7 +4638,7 @@ ${user.trimEnd()}
4758
4638
  spiritConfig.schedules = spiritConfig.schedules.filter((s) => s.id !== nurtureId);
4759
4639
  if (spiritConfig.schedules.length === 0) spiritConfig.schedules = void 0;
4760
4640
  writeVoluteConfig(sDir, spiritConfig);
4761
- const { getScheduler: getScheduler2 } = await import("./scheduler-SXELVRWO.js");
4641
+ const { getScheduler: getScheduler2 } = await import("./scheduler-MEBQF5MW.js");
4762
4642
  getScheduler2().loadSchedules("volute", sDir);
4763
4643
  }
4764
4644
  }
@@ -5193,7 +5073,7 @@ ${user.trimEnd()}
5193
5073
  }
5194
5074
  writeVoluteConfig(dir, existing);
5195
5075
  if (body.unescapeNewlines !== void 0) {
5196
- const { clearEchoTextCache } = await import("./echo-text-QVPS6QDM.js");
5076
+ const { clearEchoTextCache } = await import("./echo-text-GEDEEY7M.js");
5197
5077
  clearEchoTextCache(name);
5198
5078
  }
5199
5079
  const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.maxThinkingTokens !== void 0 || body.compaction !== void 0;
@@ -5270,7 +5150,7 @@ ${user.trimEnd()}
5270
5150
  }
5271
5151
  if (entry.mindType === "spirit" && body.model !== void 0) {
5272
5152
  try {
5273
- const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-3434PQ5Q.js");
5153
+ const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-FPFWDMXD.js");
5274
5154
  const globalConfig = readGlobalConfig2();
5275
5155
  globalConfig.spiritModel = body.model;
5276
5156
  writeGlobalConfig2(globalConfig);
@@ -5298,7 +5178,7 @@ ${user.trimEnd()}
5298
5178
  if (!body.systemPrompt || !body.message) {
5299
5179
  return c.json({ error: "systemPrompt and message required" }, 400);
5300
5180
  }
5301
- const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-ZHEPFC3U.js");
5181
+ const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-XCLE3MQP.js");
5302
5182
  if (!isAiConfigured()) {
5303
5183
  return c.json({ error: "AI service not configured" }, 503);
5304
5184
  }
@@ -5571,18 +5451,18 @@ ${user.trimEnd()}
5571
5451
  event_count: sql2`COUNT(*)`,
5572
5452
  message_count: sql2`SUM(CASE WHEN ${mindHistory.type} IN ('inbound','outbound') THEN 1 ELSE 0 END)`,
5573
5453
  tool_count: sql2`SUM(CASE WHEN ${mindHistory.type}='tool_use' THEN 1 ELSE 0 END)`
5574
- }).from(mindHistory).where(and4(eq5(mindHistory.mind, name), sql2`${mindHistory.session} IS NOT NULL`)).groupBy(mindHistory.session).orderBy(sql2`MIN(${mindHistory.created_at}) DESC`);
5454
+ }).from(mindHistory).where(and4(eq4(mindHistory.mind, name), sql2`${mindHistory.session} IS NOT NULL`)).groupBy(mindHistory.session).orderBy(sql2`MIN(${mindHistory.created_at}) DESC`);
5575
5455
  return c.json(rows);
5576
5456
  }).get("/:name/history/channels", requireSelf(), async (c) => {
5577
5457
  const name = c.req.param("name");
5578
5458
  const db = await getDb();
5579
- const rows = await db.selectDistinct({ channel: mindHistory.channel }).from(mindHistory).where(eq5(mindHistory.mind, name));
5459
+ const rows = await db.selectDistinct({ channel: mindHistory.channel }).from(mindHistory).where(eq4(mindHistory.mind, name));
5580
5460
  return c.json(rows.map((r) => r.channel));
5581
5461
  }).get("/:name/history/export", requireSelf(), async (c) => {
5582
5462
  const name = c.req.param("name");
5583
5463
  if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
5584
5464
  const db = await getDb();
5585
- const rows = await db.select().from(mindHistory).where(eq5(mindHistory.mind, name));
5465
+ const rows = await db.select().from(mindHistory).where(eq4(mindHistory.mind, name));
5586
5466
  return c.json(rows);
5587
5467
  }).get("/:name/history/turn", requireSelf(), async (c) => {
5588
5468
  const name = c.req.param("name");
@@ -5592,7 +5472,7 @@ ${user.trimEnd()}
5592
5472
  const typeFilter = detail ? void 0 : sql2`${mindHistory.type} IN ('inbound','outbound','tool_use','tool_result','text','thinking','activity')`;
5593
5473
  let rows;
5594
5474
  if (turnId) {
5595
- rows = await db.select().from(mindHistory).where(and4(eq5(mindHistory.mind, name), eq5(mindHistory.turn_id, turnId), typeFilter)).orderBy(mindHistory.id);
5475
+ rows = await db.select().from(mindHistory).where(and4(eq4(mindHistory.mind, name), eq4(mindHistory.turn_id, turnId), typeFilter)).orderBy(mindHistory.id);
5596
5476
  } else {
5597
5477
  const session = c.req.query("session");
5598
5478
  const fromId = parseInt(c.req.query("from_id") ?? "", 10);
@@ -5602,8 +5482,8 @@ ${user.trimEnd()}
5602
5482
  }
5603
5483
  rows = await db.select().from(mindHistory).where(
5604
5484
  and4(
5605
- eq5(mindHistory.mind, name),
5606
- eq5(mindHistory.session, session),
5485
+ eq4(mindHistory.mind, name),
5486
+ eq4(mindHistory.session, session),
5607
5487
  sql2`${mindHistory.id} >= ${fromId}`,
5608
5488
  sql2`${mindHistory.id} <= ${toId}`,
5609
5489
  typeFilter
@@ -5619,13 +5499,13 @@ ${user.trimEnd()}
5619
5499
  if (currentSession) {
5620
5500
  const lastTurn = await db.select({ turn_id: mindHistory.turn_id }).from(mindHistory).where(
5621
5501
  and4(
5622
- eq5(mindHistory.mind, name),
5623
- eq5(mindHistory.session, currentSession),
5502
+ eq4(mindHistory.mind, name),
5503
+ eq4(mindHistory.session, currentSession),
5624
5504
  sql2`${mindHistory.turn_id} IS NOT NULL`
5625
5505
  )
5626
5506
  ).orderBy(desc3(mindHistory.created_at)).limit(1);
5627
5507
  if (lastTurn.length > 0 && lastTurn[0].turn_id) {
5628
- const firstEvent = await db.select({ created_at: mindHistory.created_at }).from(mindHistory).where(eq5(mindHistory.turn_id, lastTurn[0].turn_id)).orderBy(mindHistory.created_at).limit(1);
5508
+ const firstEvent = await db.select({ created_at: mindHistory.created_at }).from(mindHistory).where(eq4(mindHistory.turn_id, lastTurn[0].turn_id)).orderBy(mindHistory.created_at).limit(1);
5629
5509
  if (firstEvent.length > 0) {
5630
5510
  sinceTimestamp = firstEvent[0].created_at;
5631
5511
  }
@@ -5635,8 +5515,8 @@ ${user.trimEnd()}
5635
5515
  sinceTimestamp = new Date(Date.now() - 36e5).toISOString().replace("T", " ").slice(0, 19);
5636
5516
  }
5637
5517
  const conditions = [
5638
- eq5(summaries.mind, name),
5639
- eq5(summaries.period, "turn"),
5518
+ eq4(summaries.mind, name),
5519
+ eq4(summaries.period, "turn"),
5640
5520
  sql2`${summaries.created_at} > ${sinceTimestamp}`
5641
5521
  ];
5642
5522
  if (currentSession) {
@@ -5646,7 +5526,7 @@ ${user.trimEnd()}
5646
5526
  session: turns.session,
5647
5527
  content: summaries.content,
5648
5528
  created_at: summaries.created_at
5649
- }).from(summaries).innerJoin(turns, eq5(turns.id, summaries.period_key)).where(and4(...conditions)).orderBy(desc3(summaries.created_at)).limit(50);
5529
+ }).from(summaries).innerJoin(turns, eq4(turns.id, summaries.period_key)).where(and4(...conditions)).orderBy(desc3(summaries.created_at)).limit(50);
5650
5530
  if (rows.length === 0) {
5651
5531
  return c.json({ context: null });
5652
5532
  }
@@ -5676,18 +5556,18 @@ ${lines.join("\n")}` });
5676
5556
  const limit = Math.min(Math.max(parseInt(c.req.query("limit") ?? "50", 10) || 50, 1), 200);
5677
5557
  const offset = Math.max(parseInt(c.req.query("offset") ?? "0", 10) || 0, 0);
5678
5558
  const db = await getDb();
5679
- const conditions = [eq5(mindHistory.mind, name)];
5559
+ const conditions = [eq4(mindHistory.mind, name)];
5680
5560
  if (channel) {
5681
- conditions.push(eq5(mindHistory.channel, channel));
5561
+ conditions.push(eq4(mindHistory.channel, channel));
5682
5562
  }
5683
5563
  if (session) {
5684
- conditions.push(eq5(mindHistory.session, session));
5564
+ conditions.push(eq4(mindHistory.session, session));
5685
5565
  }
5686
5566
  const effectivePreset = full ? "all" : preset;
5687
5567
  if (!effectivePreset || effectivePreset === "summary") {
5688
- const sumConditions = [eq5(summaries.mind, name), eq5(summaries.period, "turn")];
5568
+ const sumConditions = [eq4(summaries.mind, name), eq4(summaries.period, "turn")];
5689
5569
  if (session) {
5690
- sumConditions.push(eq5(turns.session, session));
5570
+ sumConditions.push(eq4(turns.session, session));
5691
5571
  const sumRows2 = await db.select({
5692
5572
  id: summaries.id,
5693
5573
  mind: summaries.mind,
@@ -5697,7 +5577,7 @@ ${lines.join("\n")}` });
5697
5577
  metadata: summaries.metadata,
5698
5578
  created_at: summaries.created_at,
5699
5579
  session: turns.session
5700
- }).from(summaries).innerJoin(turns, eq5(turns.id, summaries.period_key)).where(and4(...sumConditions)).orderBy(desc3(summaries.created_at)).limit(limit).offset(offset);
5580
+ }).from(summaries).innerJoin(turns, eq4(turns.id, summaries.period_key)).where(and4(...sumConditions)).orderBy(desc3(summaries.created_at)).limit(limit).offset(offset);
5701
5581
  return c.json(
5702
5582
  sumRows2.map((r) => ({
5703
5583
  id: r.id,
@@ -5750,7 +5630,7 @@ var minds_default = app13;
5750
5630
 
5751
5631
  // packages/daemon/src/web/api/prompts.ts
5752
5632
  import { zValidator as zValidator6 } from "@hono/zod-validator";
5753
- import { eq as eq6, sql as sql3 } from "drizzle-orm";
5633
+ import { eq as eq5, sql as sql3 } from "drizzle-orm";
5754
5634
  import { Hono as Hono16 } from "hono";
5755
5635
  import { z as z6 } from "zod";
5756
5636
  var app14 = new Hono16().get("/", async (c) => {
@@ -5794,7 +5674,7 @@ var app14 = new Hono16().get("/", async (c) => {
5794
5674
  return c.json({ error: "Unknown prompt key" }, 404);
5795
5675
  }
5796
5676
  const db = await getDb();
5797
- await db.delete(systemPrompts).where(eq6(systemPrompts.key, key));
5677
+ await db.delete(systemPrompts).where(eq5(systemPrompts.key, key));
5798
5678
  return c.json({ ok: true });
5799
5679
  });
5800
5680
  var prompts_default = app14;
@@ -6042,7 +5922,7 @@ var app15 = new Hono17().get("/:name/clock/status", requireSelf(), async (c) =>
6042
5922
  const body = await c.req.text();
6043
5923
  const message = `[webhook: ${event}] ${body}`;
6044
5924
  try {
6045
- const { sendSystemMessage } = await import("./system-chat-HCPHUQGI.js");
5925
+ const { sendSystemMessage } = await import("./system-chat-HZUKBIKJ.js");
6046
5926
  await sendSystemMessage(name, message);
6047
5927
  return c.json({ ok: true });
6048
5928
  } catch (err) {
@@ -6096,7 +5976,7 @@ setup.get("/status", async (c) => {
6096
5976
  let hasAccount = false;
6097
5977
  if (hasSystem) {
6098
5978
  try {
6099
- const { listUsersByType: listUsersByType2 } = await import("./auth-VYW2ECCE.js");
5979
+ const { listUsersByType: listUsersByType2 } = await import("./auth-EAASQPTN.js");
6100
5980
  const brains = await listUsersByType2("brain");
6101
5981
  hasAccount = brains.length > 0;
6102
5982
  } catch (err) {
@@ -6307,7 +6187,7 @@ setup.post("/account", async (c) => {
6307
6187
  }
6308
6188
  }
6309
6189
  try {
6310
- const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-VYW2ECCE.js");
6190
+ const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-EAASQPTN.js");
6311
6191
  const user = await createUser2(body.username.trim(), body.password);
6312
6192
  if (body.displayName?.trim()) {
6313
6193
  await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
@@ -6353,7 +6233,7 @@ setup.post("/models", async (c) => {
6353
6233
  return c.json({ error: "Spirit model is required" }, 400);
6354
6234
  }
6355
6235
  try {
6356
- const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-ZHEPFC3U.js");
6236
+ const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-XCLE3MQP.js");
6357
6237
  setEnabledModels3(body.models);
6358
6238
  const config2 = readGlobalConfig();
6359
6239
  config2.spiritModel = body.spiritModel.trim();
@@ -6371,15 +6251,15 @@ setup.post("/complete", async (c) => {
6371
6251
  return c.json({ error: "Setup already complete" }, 400);
6372
6252
  }
6373
6253
  try {
6374
- const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-KTBHLULO.js");
6375
- const { startSpiritFull } = await import("./mind-service-L7LMMDYJ.js");
6254
+ const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-ONLRFATY.js");
6255
+ const { startSpiritFull } = await import("./mind-service-XGXSMQP6.js");
6376
6256
  await ensureSpiritProject();
6377
6257
  await syncSpiritTemplate();
6378
6258
  const warnings = [];
6379
6259
  const config2 = readGlobalConfig();
6380
6260
  if (config2.setup?.service && config2.setup?.type === "local") {
6381
6261
  try {
6382
- const { installUserService } = await import("./service-install-NLGAVTQS.js");
6262
+ const { installUserService } = await import("./service-install-GTDUHP6R.js");
6383
6263
  const installed = await installUserService(config2.port, config2.hostname);
6384
6264
  if (!installed) {
6385
6265
  warnings.push("Service installation is not supported on this platform.");
@@ -6407,8 +6287,8 @@ setup.post("/complete", async (c) => {
6407
6287
  }
6408
6288
  let spiritConversationId;
6409
6289
  try {
6410
- const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-VYW2ECCE.js");
6411
- const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-KW7IYESK.js");
6290
+ const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-EAASQPTN.js");
6291
+ const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-FSZCUUYO.js");
6412
6292
  const spiritUser = await getOrCreateMindUser2("volute");
6413
6293
  const brains = await listUsersByType2("brain");
6414
6294
  const admin2 = brains.find((u) => u.role === "admin");
@@ -6430,8 +6310,8 @@ setup.post("/complete", async (c) => {
6430
6310
  logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
6431
6311
  if (spiritConversationId && spiritStarted) {
6432
6312
  try {
6433
- const { deliverMessage: deliverMessage2 } = await import("./message-delivery-X4CZE2L6.js");
6434
- const { listUsersByType: listUsers2 } = await import("./auth-VYW2ECCE.js");
6313
+ const { deliverMessage: deliverMessage2 } = await import("./message-delivery-HPMELC4Q.js");
6314
+ const { listUsersByType: listUsers2 } = await import("./auth-EAASQPTN.js");
6435
6315
  const admins = await listUsers2("brain");
6436
6316
  const admin2 = admins.find((u) => u.role === "admin");
6437
6317
  const adminName = admin2?.display_name || admin2?.username || "the admin";
@@ -6790,11 +6670,20 @@ function bufferEvent(data) {
6790
6670
  }
6791
6671
  return id;
6792
6672
  }
6793
- function getEventsSince(sinceId) {
6673
+ function nextEventId() {
6674
+ return nextId++;
6675
+ }
6676
+ function getEventsSince(sinceId, allowedConversationIds) {
6794
6677
  const now = Date.now();
6795
6678
  const startIdx = buffer.findIndex((e) => e.id > sinceId);
6796
6679
  if (startIdx === -1) return [];
6797
- return buffer.slice(startIdx).filter((e) => now - e.timestamp < MAX_AGE_MS);
6680
+ return buffer.slice(startIdx).filter((e) => {
6681
+ if (now - e.timestamp >= MAX_AGE_MS) return false;
6682
+ const data = e.data;
6683
+ if (data.event === "snapshot") return false;
6684
+ if (data.event === "conversation") return allowedConversationIds.has(data.conversationId);
6685
+ return true;
6686
+ });
6798
6687
  }
6799
6688
 
6800
6689
  // packages/daemon/src/web/api/v1/events.ts
@@ -6809,8 +6698,22 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
6809
6698
  cleanups.push(() => removeConnection(user.username));
6810
6699
  }
6811
6700
  try {
6701
+ let conversations2 = [];
6702
+ try {
6703
+ conversations2 = await listConversationsWithParticipants(user.id);
6704
+ if (conversations2.length > 0) {
6705
+ const convIds = conversations2.map((c2) => c2.id);
6706
+ const unreads = await getUnreadCounts(user.id, convIds);
6707
+ for (const conv of conversations2) {
6708
+ conv.unreadCount = unreads[conv.id] ?? 0;
6709
+ }
6710
+ }
6711
+ } catch (err) {
6712
+ logger_default.error("[v1-events] failed to fetch conversations", logger_default.errorData(err));
6713
+ }
6714
+ const allowedConversationIds = new Set(conversations2.map((c2) => c2.id));
6812
6715
  if (sinceId > 0) {
6813
- const missed = getEventsSince(sinceId);
6716
+ const missed = getEventsSince(sinceId, allowedConversationIds);
6814
6717
  for (const event of missed) {
6815
6718
  await stream.writeSSE({
6816
6719
  id: String(event.id),
@@ -6829,19 +6732,6 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
6829
6732
  } catch (err) {
6830
6733
  logger_default.error("[v1-events] failed to fetch recent activity", logger_default.errorData(err));
6831
6734
  }
6832
- let conversations2 = [];
6833
- try {
6834
- conversations2 = await listConversationsWithParticipants(user.id);
6835
- if (conversations2.length > 0) {
6836
- const convIds = conversations2.map((c2) => c2.id);
6837
- const unreads = await getUnreadCounts(user.id, convIds);
6838
- for (const conv of conversations2) {
6839
- conv.unreadCount = unreads[conv.id] ?? 0;
6840
- }
6841
- }
6842
- } catch (err) {
6843
- logger_default.error("[v1-events] failed to fetch conversations", logger_default.errorData(err));
6844
- }
6845
6735
  const snapshotData = {
6846
6736
  event: "snapshot",
6847
6737
  activity: recentActivity,
@@ -6849,7 +6739,7 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
6849
6739
  activeMinds: getActiveMinds(),
6850
6740
  onlineBrains: getOnlineBrains()
6851
6741
  };
6852
- const snapshotId = bufferEvent(snapshotData);
6742
+ const snapshotId = nextEventId();
6853
6743
  await stream.writeSSE({
6854
6744
  id: String(snapshotId),
6855
6745
  data: JSON.stringify(snapshotData)
@@ -6915,14 +6805,23 @@ import { resolve as resolve14 } from "path";
6915
6805
  function tsxBin(cwd) {
6916
6806
  return resolve14(cwd, "node_modules", ".bin", "tsx");
6917
6807
  }
6918
- function spawnServer(cwd, port, options) {
6808
+ async function spawnServer(cwd, port, options) {
6809
+ let cmd = tsxBin(cwd);
6810
+ let args = ["src/server.ts", "--port", String(port)];
6811
+ if (options?.mindName) {
6812
+ if (isIsolationEnabled()) {
6813
+ [cmd, args] = await wrapForIsolation(cmd, args, options.mindName);
6814
+ } else if (isSandboxEnabled() && options.template !== "codex") {
6815
+ [cmd, args] = await wrapForSandbox(cmd, args, cwd, options.mindName, [cwd, mindTmpDir(cwd)]);
6816
+ }
6817
+ }
6919
6818
  if (options?.detached) {
6920
- return spawnDetached(cwd, port, options.logDir);
6819
+ return spawnDetached(cmd, args, cwd, options.logDir);
6921
6820
  }
6922
- return spawnAttached(cwd, port);
6821
+ return spawnAttached(cmd, args, cwd);
6923
6822
  }
6924
- function spawnAttached(cwd, port) {
6925
- const child = spawn4(tsxBin(cwd), ["src/server.ts", "--port", String(port)], {
6823
+ function spawnAttached(cmd, args, cwd) {
6824
+ const child = spawn4(cmd, args, {
6926
6825
  cwd,
6927
6826
  stdio: ["ignore", "pipe", "pipe"]
6928
6827
  });
@@ -6947,12 +6846,12 @@ function spawnAttached(cwd, port) {
6947
6846
  });
6948
6847
  });
6949
6848
  }
6950
- function spawnDetached(cwd, port, logDir) {
6849
+ function spawnDetached(cmd, args, cwd, logDir) {
6951
6850
  const logsDir = logDir ?? resolve14(cwd, ".mind", "logs");
6952
6851
  mkdirSync8(logsDir, { recursive: true });
6953
6852
  const logPath = resolve14(logsDir, "mind.log");
6954
6853
  const logFd = openSync(logPath, "a");
6955
- const child = spawn4(tsxBin(cwd), ["src/server.ts", "--port", String(port)], {
6854
+ const child = spawn4(cmd, args, {
6956
6855
  cwd,
6957
6856
  stdio: ["ignore", logFd, logFd],
6958
6857
  detached: true
@@ -7147,7 +7046,11 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7147
7046
  }
7148
7047
  }
7149
7048
  if (!body.skipVerify) {
7150
- const result = await spawnServer(variantEntry.dir, 0, { detached: true });
7049
+ const result = await spawnServer(variantEntry.dir, 0, {
7050
+ detached: true,
7051
+ mindName: variantName,
7052
+ template: variantEntry.template
7053
+ });
7151
7054
  if (!result) {
7152
7055
  return c.json(
7153
7056
  { error: "Failed to start server for verification. Use skipVerify to skip." },
@@ -7188,8 +7091,8 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7188
7091
  await cleanupVariant(variantName, projectRoot, variantEntry.dir);
7189
7092
  if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
7190
7093
  try {
7191
- const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-JARTCRGS.js");
7192
- const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-RAXNFN7K.js");
7094
+ const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-446HHH5V.js");
7095
+ const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-MDLNPTTI.js");
7193
7096
  const tmpl = parentEntry.template ?? "claude";
7194
7097
  await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
7195
7098
  } catch (err) {
@@ -7303,9 +7206,13 @@ var app22 = new Hono25().get("/", async (c) => {
7303
7206
  });
7304
7207
  }).patch("/:name", zValidator9("json", channelSettingsSchema), async (c) => {
7305
7208
  const name = c.req.param("name");
7209
+ const user = c.get("user");
7306
7210
  const body = c.req.valid("json");
7307
7211
  const ch = await getChannelByName(name);
7308
7212
  if (!ch) return c.json({ error: "Channel not found" }, 404);
7213
+ if (user.role !== "admin" && user.role !== "system" && !await isParticipant(ch.id, user.id)) {
7214
+ return c.json({ error: "Forbidden" }, 403);
7215
+ }
7309
7216
  await updateChannelSettings(name, body);
7310
7217
  const settings = await getChannelSettings(name);
7311
7218
  return c.json({ ...ch, channel_name: name, settings: formatChannelSettings(settings) });
@@ -7335,6 +7242,9 @@ var app22 = new Hono25().get("/", async (c) => {
7335
7242
  const { username } = c.req.valid("json");
7336
7243
  const ch = await getChannelByName(name);
7337
7244
  if (!ch) return c.json({ error: "Channel not found" }, 404);
7245
+ if (inviter.role !== "admin" && inviter.role !== "system" && !await isParticipant(ch.id, inviter.id)) {
7246
+ return c.json({ error: "Forbidden" }, 403);
7247
+ }
7338
7248
  let user = await getUserByUsername(username);
7339
7249
  if (!user && await findMind(username)) {
7340
7250
  user = await getOrCreateMindUser(username);
@@ -7941,6 +7851,11 @@ if (!process.env.VOLUTE_HOME) {
7941
7851
  if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
7942
7852
  process.env.TZ = process.env.VOLUTE_TIMEZONE;
7943
7853
  }
7854
+ function writeDaemonConfig(path, config2) {
7855
+ writeFileSync9(path, `${JSON.stringify(config2, null, 2)}
7856
+ `, { mode: 384 });
7857
+ chmodSync(path, 384);
7858
+ }
7944
7859
  async function startDaemon(opts) {
7945
7860
  const { port, hostname } = opts;
7946
7861
  const myPid = String(process.pid);
@@ -7961,18 +7876,18 @@ async function startDaemon(opts) {
7961
7876
  const DAEMON_JSON_PATH = resolve17(systemDir, "daemon.json");
7962
7877
  mkdirSync10(home, { recursive: true });
7963
7878
  ensureSystemDir();
7964
- const { migrateSetupCompleted } = await import("./setup-3434PQ5Q.js");
7879
+ const { migrateSetupCompleted } = await import("./setup-FPFWDMXD.js");
7965
7880
  migrateSetupCompleted();
7966
- await (await import("./db-D4FVCA5I.js")).getDb();
7881
+ await (await import("./db-ZJJJYJBU.js")).getDb();
7967
7882
  try {
7968
- const { eq: eq7, and: and5 } = await import("drizzle-orm");
7883
+ const { eq: eq6, and: and5 } = await import("drizzle-orm");
7969
7884
  const { users: users2 } = await import("./schema-HHYJDG7B.js");
7970
- const db = await (await import("./db-D4FVCA5I.js")).getDb();
7971
- await db.update(users2).set({ role: "system" }).where(and5(eq7(users2.user_type, "system"), eq7(users2.role, "user")));
7885
+ const db = await (await import("./db-ZJJJYJBU.js")).getDb();
7886
+ await db.update(users2).set({ role: "system" }).where(and5(eq6(users2.user_type, "system"), eq6(users2.role, "user")));
7972
7887
  } catch (err) {
7973
7888
  logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
7974
7889
  }
7975
- const { initSandbox } = await import("./sandbox-O3GZTS7J.js");
7890
+ const { initSandbox } = await import("./sandbox-ND53WZVU.js");
7976
7891
  await initSandbox();
7977
7892
  try {
7978
7893
  await syncBuiltinSkills();
@@ -7999,7 +7914,7 @@ async function startDaemon(opts) {
7999
7914
  logger_default.warn("failed to ensure #system channel", logger_default.errorData(err));
8000
7915
  }
8001
7916
  try {
8002
- const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-VYW2ECCE.js");
7917
+ const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-EAASQPTN.js");
8003
7918
  await getOrCreateSystemUser2();
8004
7919
  } catch (err) {
8005
7920
  logger_default.warn(
@@ -8008,12 +7923,12 @@ async function startDaemon(opts) {
8008
7923
  );
8009
7924
  }
8010
7925
  const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes(32).toString("hex");
8011
- const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-3434PQ5Q.js");
7926
+ const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-FPFWDMXD.js");
8012
7927
  const globalCfg = readGlobalConfig2();
8013
7928
  let tls;
8014
7929
  if (opts.tailscale || globalCfg.tailscale) {
8015
7930
  try {
8016
- const { getTailscaleTls } = await import("./tailscale-PK3AI5EV.js");
7931
+ const { getTailscaleTls } = await import("./tailscale-TIRTGM6E.js");
8017
7932
  const tlsConfig = await getTailscaleTls();
8018
7933
  tls = { key: tlsConfig.key, cert: tlsConfig.cert };
8019
7934
  logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
@@ -8044,8 +7959,7 @@ async function startDaemon(opts) {
8044
7959
  const daemonConfig = { port, hostname, token };
8045
7960
  if (internalPort) daemonConfig.internalPort = internalPort;
8046
7961
  if (tls) daemonConfig.tls = true;
8047
- writeFileSync9(DAEMON_JSON_PATH, `${JSON.stringify(daemonConfig, null, 2)}
8048
- `, { mode: 420 });
7962
+ writeDaemonConfig(DAEMON_JSON_PATH, daemonConfig);
8049
7963
  const delivery = initDeliveryManager();
8050
7964
  const manager = initMindManager();
8051
7965
  manager.loadCrashAttempts();
@@ -8092,10 +8006,10 @@ async function startDaemon(opts) {
8092
8006
  await Promise.all(workers);
8093
8007
  }
8094
8008
  try {
8095
- const { isSetupComplete: isSetupComplete2 } = await import("./setup-3434PQ5Q.js");
8009
+ const { isSetupComplete: isSetupComplete2 } = await import("./setup-FPFWDMXD.js");
8096
8010
  if (isSetupComplete2()) {
8097
- const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-KTBHLULO.js");
8098
- const { startSpiritFull } = await import("./mind-service-L7LMMDYJ.js");
8011
+ const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-ONLRFATY.js");
8012
+ const { startSpiritFull } = await import("./mind-service-XGXSMQP6.js");
8099
8013
  await ensureSpiritProject();
8100
8014
  await syncSpiritTemplate();
8101
8015
  const spiritEntry = await findMind("volute");
@@ -8112,7 +8026,7 @@ async function startDaemon(opts) {
8112
8026
  bridgeManager.startBridges(daemonPort).catch((err) => {
8113
8027
  logger_default.warn("failed to start bridges", logger_default.errorData(err));
8114
8028
  });
8115
- import("./cloud-sync-GV6O2HN2.js").then(
8029
+ import("./cloud-sync-2XVXEOSU.js").then(
8116
8030
  ({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
8117
8031
  logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
8118
8032
  })
@@ -8120,7 +8034,7 @@ async function startDaemon(opts) {
8120
8034
  logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
8121
8035
  });
8122
8036
  try {
8123
- const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-SSNAWZMX.js");
8037
+ const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-UFFDUPCX.js");
8124
8038
  backfillTemplateHashes();
8125
8039
  notifyVersionUpdate().catch((err) => {
8126
8040
  logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
@@ -8225,8 +8139,12 @@ if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith
8225
8139
  if (noSandbox) {
8226
8140
  process.env.VOLUTE_SANDBOX = "0";
8227
8141
  }
8228
- startDaemon({ port, hostname, foreground, tailscale });
8142
+ startDaemon({ port, hostname, foreground, tailscale }).catch((err) => {
8143
+ logger_default.error("daemon failed to start", logger_default.errorData(err));
8144
+ process.exit(1);
8145
+ });
8229
8146
  }
8230
8147
  export {
8231
- startDaemon
8148
+ startDaemon,
8149
+ writeDaemonConfig
8232
8150
  };