volute 0.36.0 → 0.37.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 (140) hide show
  1. package/dist/{accept-ZBDVVCEU.js → accept-AHAOUFBK.js} +4 -4
  2. package/dist/{activity-events-PWOGSMRL.js → activity-events-N6HCHU4P.js} +4 -4
  3. package/dist/{ai-service-GSZWIETO.js → ai-service-C2YNARGH.js} +5 -5
  4. package/dist/{api-client-3A77HMH7.js → api-client-LC5YRA32.js} +1 -1
  5. package/dist/{archive-Y2YEOCGB.js → archive-AWIJTVQV.js} +4 -4
  6. package/dist/{auth-YTQME4EV.js → auth-2QOOPMBX.js} +5 -5
  7. package/dist/{bridge-PXIO6PS2.js → bridge-F3ZJEKDN.js} +4 -4
  8. package/dist/{chat-ED7YOGKO.js → chat-5Y4FD77E.js} +9 -9
  9. package/dist/{chunk-75AJ54GM.js → chunk-2NHRJ3YO.js} +1 -1
  10. package/dist/{chunk-PJ4IPTIN.js → chunk-3F7XK5Q7.js} +1 -1
  11. package/dist/{chunk-6F3YNULE.js → chunk-4L2Q7IP5.js} +16 -16
  12. package/dist/{chunk-IIWF2IPD.js → chunk-5DPRTREW.js} +3 -3
  13. package/dist/{chunk-X2J7QUFH.js → chunk-7AZQFSOV.js} +1 -1
  14. package/dist/{chunk-NUX47Y2V.js → chunk-A6FLW5XD.js} +1 -1
  15. package/dist/{chunk-SWW6AUVW.js → chunk-BIEWHAAM.js} +1 -1
  16. package/dist/{chunk-TWAN7ZNO.js → chunk-CF4SO5L3.js} +3 -3
  17. package/dist/{chunk-7PTQGPJY.js → chunk-CJ26DXZL.js} +1 -1
  18. package/dist/{chunk-PY557GDR.js → chunk-GVVVMZ4J.js} +1 -1
  19. package/dist/chunk-K3NQKI34.js +10 -0
  20. package/dist/{chunk-BOLJUV77.js → chunk-KXXJYY62.js} +4 -4
  21. package/dist/chunk-LIIX2MOM.js +853 -0
  22. package/dist/chunk-LQ6Z4FXN.js +87 -0
  23. package/dist/{chunk-N2AUHW4C.js → chunk-MQRS4J24.js} +2 -2
  24. package/dist/{chunk-B35VNNSS.js → chunk-N42QMDID.js} +2 -2
  25. package/dist/{chunk-M5RYAA5I.js → chunk-ORNY3MZR.js} +4 -4
  26. package/dist/{chunk-YDBAY3NA.js → chunk-PMMHVSCR.js} +1 -1
  27. package/dist/{chunk-GBDVNPN2.js → chunk-QJGLTPAP.js} +8 -8
  28. package/dist/{chunk-DQ7VBXAP.js → chunk-RUIVWCYY.js} +122 -81
  29. package/dist/{chunk-L72WYMF7.js → chunk-SNW2NPP4.js} +1 -1
  30. package/dist/chunk-SZJWC2GA.js +125 -0
  31. package/dist/{chunk-DJT5Y4UF.js → chunk-TNZ5XQA4.js} +2 -2
  32. package/dist/{chunk-DMV5P2LU.js → chunk-UIM5NHPP.js} +3 -3
  33. package/dist/{chunk-ZTVKQOU7.js → chunk-WC635OPK.js} +1 -1
  34. package/dist/{chunk-YTWZORJN.js → chunk-XLBQYIHH.js} +1 -1
  35. package/dist/cli.js +24 -24
  36. package/dist/{clock-HSEKS5AR.js → clock-BMLJ2TR6.js} +8 -8
  37. package/dist/{cloud-sync-BOCZSDIA.js → cloud-sync-EZKCEIBX.js} +18 -18
  38. package/dist/{config-UTS7QULS.js → config-QB7W3Z7P.js} +4 -4
  39. package/dist/connectors/discord-bridge.js +1 -1
  40. package/dist/connectors/slack-bridge.js +1 -1
  41. package/dist/connectors/telegram-bridge.js +1 -1
  42. package/dist/{conversations-HH3CJD4E.js → conversations-G6YRSABR.js} +5 -5
  43. package/dist/{create-5BPOOJAN.js → create-C3BBFYV7.js} +4 -4
  44. package/dist/{create-QBEPSD2Z.js → create-PN73742N.js} +4 -4
  45. package/dist/{daemon-client-RVIKXGFQ.js → daemon-client-2MIPKY3E.js} +1 -1
  46. package/dist/{daemon-restart-SIR3UR4B.js → daemon-restart-S6SOD3C5.js} +11 -11
  47. package/dist/daemon.js +392 -1101
  48. package/dist/db-CBOCDYVA.js +9 -0
  49. package/dist/{db-BDMH4SZ2.js → db-IJL6B26S.js} +1 -1
  50. package/dist/{delete-L5PAVDGQ.js → delete-NLXES2C7.js} +3 -3
  51. package/dist/delivery-manager-3I7CA734.js +30 -0
  52. package/dist/{delivery-router-VSULHXNH.js → delivery-router-QTFEZ26O.js} +4 -4
  53. package/dist/down-25L2RKCQ.js +17 -0
  54. package/dist/echo-text-IWAQKNTC.js +31 -0
  55. package/dist/{env-E4XHO2BI.js → env-IQ6Q2333.js} +6 -6
  56. package/dist/exec-ONYZEA5B.js +17 -0
  57. package/dist/{export-HTFOHOKL.js → export-JPDBQESV.js} +6 -6
  58. package/dist/{extension-AKZ46YSL.js → extension-LZYHBNLV.js} +4 -4
  59. package/dist/{extensions-OOSFVH7U.js → extensions-PCOXTHNM.js} +17 -17
  60. package/dist/{files-H2YLRD37.js → files-LAQ3NXQK.js} +7 -7
  61. package/dist/{import-OL5BZX7S.js → import-EROF27RH.js} +11 -10
  62. package/dist/{isolation-N74RWOUX.js → isolation-G5J3MTKU.js} +4 -4
  63. package/dist/{join-DF5XSJAC.js → join-6SZCA5FX.js} +3 -3
  64. package/dist/{list-GJ4RUQQT.js → list-KHJZJPEJ.js} +4 -4
  65. package/dist/{login-JXRVMBRB.js → login-F6YMAVLE.js} +6 -6
  66. package/dist/{login-GOTAYLXP.js → login-GYTH67ES.js} +4 -4
  67. package/dist/{logout-FW243JBU.js → logout-HHPH52KZ.js} +6 -6
  68. package/dist/{logout-6KIA74EV.js → logout-YHQLOFLR.js} +4 -4
  69. package/dist/message-delivery-NWL7XEIX.js +40 -0
  70. package/dist/{mind-6VJJHF65.js → mind-MM2IYMJ3.js} +19 -19
  71. package/dist/{mind-activity-tracker-66UVYIFW.js → mind-activity-tracker-42ENM32S.js} +5 -5
  72. package/dist/{mind-history-MII2SK7F.js → mind-history-WHCNZ6I5.js} +5 -5
  73. package/dist/{mind-list-GEWHWAL4.js → mind-list-H3HC2ZRG.js} +4 -4
  74. package/dist/mind-manager-VOEQ2IZL.js +30 -0
  75. package/dist/{mind-profile-DCBDVF5B.js → mind-profile-7VYRJGFZ.js} +2 -2
  76. package/dist/mind-service-WRTOQSAL.js +36 -0
  77. package/dist/{mind-sleep-ITCF6OQA.js → mind-sleep-ZL5ZXFTM.js} +4 -4
  78. package/dist/{mind-status-X4SX3YUG.js → mind-status-ZWULKOUO.js} +4 -4
  79. package/dist/{mind-wake-KXMKMGWX.js → mind-wake-HK5ORGUK.js} +4 -4
  80. package/dist/{package-3W2MEXHB.js → package-TA6IHIED.js} +2 -2
  81. package/dist/{read-ZUDG4JWU.js → read-CP7MYMJQ.js} +4 -4
  82. package/dist/{read-stdin-3X5VYKNS.js → read-stdin-4B5UYPPM.js} +1 -1
  83. package/dist/{register-SB7NXCOE.js → register-XOBFEMI4.js} +4 -4
  84. package/dist/{registry-YPHK534W.js → registry-KMELPC3X.js} +3 -3
  85. package/dist/{reject-MUR2KWJ4.js → reject-43AGXB6B.js} +4 -4
  86. package/dist/{restart-5EGG4JXU.js → restart-O5QIYQJT.js} +5 -5
  87. package/dist/{sandbox-LP6YRAXS.js → sandbox-PQYEICEF.js} +5 -5
  88. package/dist/scheduler-355E746X.js +30 -0
  89. package/dist/{schema-MISD3JFG.js → schema-K575EBPE.js} +2 -2
  90. package/dist/{seed-CEC4RC23.js → seed-6S4Z6TAM.js} +2 -2
  91. package/dist/{seed-check-KJNTL72M.js → seed-check-HZPVFJKZ.js} +2 -2
  92. package/dist/{seed-cmd-WTTG7SRQ.js → seed-cmd-CBWLJWYD.js} +4 -4
  93. package/dist/{seed-create-M6RCC6RP.js → seed-create-NT6DG4SE.js} +6 -6
  94. package/dist/{seed-sprout-ZKCHFJKH.js → seed-sprout-GQLSK4EF.js} +14 -14
  95. package/dist/{send-LXUT2GGR.js → send-7CIP5GLS.js} +8 -8
  96. package/dist/{service-M6N3RUYU.js → service-YMHWPDXW.js} +6 -6
  97. package/dist/{setup-PJOF5UV5.js → setup-APNN7KJB.js} +32 -37
  98. package/dist/{setup-PMJHCZQX.js → setup-PF7JSFMO.js} +4 -4
  99. package/dist/{skill-TAAKEYBV.js → skill-ICN6Y2ZF.js} +6 -6
  100. package/dist/{skills-2PTRTBQP.js → skills-ZFVNN4TU.js} +7 -7
  101. package/dist/sleep-manager-PBOIEBJZ.js +34 -0
  102. package/dist/{spirit-6KVDIROQ.js → spirit-4QOYM33G.js} +9 -9
  103. package/dist/{split-AWVOYOPZ.js → split-5YBEQTBF.js} +3 -3
  104. package/dist/{sprout-WX2FFYLP.js → sprout-UDLZPMEO.js} +2 -2
  105. package/dist/{src-QEOLMAYC.js → src-LT6ZBYYX.js} +2 -2
  106. package/dist/{src-GW6FP6VL.js → src-O4PRLMKM.js} +1 -1
  107. package/dist/{src-FQE4BHRG.js → src-OYWRPLC6.js} +1 -1
  108. package/dist/{start-3UXOPXQG.js → start-LMXXRR3X.js} +5 -5
  109. package/dist/{status-3IVSLJDN.js → status-MC2P7DBG.js} +7 -7
  110. package/dist/{stop-3XYIBGFM.js → stop-TWDKVEUX.js} +5 -5
  111. package/dist/system-chat-7AIN3U5M.js +34 -0
  112. package/dist/{systems-O43WGQY6.js → systems-Y2WZV2K4.js} +7 -7
  113. package/dist/{tailscale-DZU4WM3E.js → tailscale-LTYNKIPZ.js} +3 -3
  114. package/dist/{template-hash-6ITI3WC4.js → template-hash-SSIBEEYK.js} +1 -1
  115. package/dist/up-4T32B7OB.js +19 -0
  116. package/dist/{update-RIQYUPVN.js → update-UOP2INF2.js} +7 -7
  117. package/dist/{update-check-4TIJKVGD.js → update-check-IKS7SGK5.js} +4 -4
  118. package/dist/{upgrade-ZMDGC7M2.js → upgrade-RXFZR5FI.js} +3 -3
  119. package/dist/{variant-QWL2WSRI.js → variant-HHDTW74J.js} +1 -1
  120. package/dist/{version-notify-UXSHBZ35.js → version-notify-NCRIN5QK.js} +18 -18
  121. package/dist/{volute-config-V7UFFBG3.js → volute-config-TS62GS6A.js} +1 -1
  122. package/dist/web-assets/assets/{index-C-eYso8Y.js → index-B3xLeex8.js} +16 -16
  123. package/dist/web-assets/assets/{index-CCv_fSte.css → index-Dr4A90Lo.css} +1 -1
  124. package/dist/web-assets/index.html +2 -2
  125. package/package.json +1 -1
  126. package/templates/_base/src/lib/context-breakdown.ts +22 -16
  127. package/dist/chunk-7KJOFUNN.js +0 -22
  128. package/dist/chunk-PZYJBOQP.js +0 -207
  129. package/dist/db-URORGSXQ.js +0 -9
  130. package/dist/delivery-manager-WTGIPBGY.js +0 -30
  131. package/dist/down-DGGLZ5TA.js +0 -17
  132. package/dist/exec-X3C6ZZTQ.js +0 -17
  133. package/dist/lib-DYEZMGW7.js +0 -6588
  134. package/dist/message-delivery-YORUXKDQ.js +0 -40
  135. package/dist/mind-manager-TJ2SUPRX.js +0 -30
  136. package/dist/mind-service-E7FM2WZF.js +0 -36
  137. package/dist/scheduler-FRJ5DK24.js +0 -30
  138. package/dist/sleep-manager-WAZWMFJT.js +0 -34
  139. package/dist/system-chat-2IFS5HCX.js +0 -34
  140. package/dist/up-4SCIUIMG.js +0 -19
package/dist/daemon.js CHANGED
@@ -1,20 +1,44 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ acceptPending,
4
+ formatFileSize,
5
+ listPending,
6
+ rejectPending,
7
+ stageFile,
8
+ validateFilePath
9
+ } from "./chunk-XLBQYIHH.js";
10
+ import {
11
+ findOpenClawSession,
12
+ importOpenClawConnectors,
13
+ importPiSession,
14
+ parseNameFromIdentity
15
+ } from "./chunk-SZJWC2GA.js";
2
16
  import {
3
17
  checkForUpdate,
4
18
  checkForUpdateCached,
5
19
  getCurrentVersion
6
- } from "./chunk-ZTVKQOU7.js";
20
+ } from "./chunk-WC635OPK.js";
21
+ import {
22
+ isHomeOnlyArchive
23
+ } from "./chunk-BIEWHAAM.js";
7
24
  import {
8
25
  computeTemplateHash
9
26
  } from "./chunk-KAB6UGOL.js";
10
27
  import {
11
- acceptPending,
12
- formatFileSize,
13
- listPending,
14
- rejectPending,
15
- stageFile,
16
- validateFilePath
17
- } from "./chunk-YTWZORJN.js";
28
+ PLATFORMS,
29
+ echoTextToChannel,
30
+ getPlatformDriver,
31
+ routeOutboundBridge
32
+ } from "./chunk-LIIX2MOM.js";
33
+ import {
34
+ getBridgeConfig,
35
+ readBridgesConfig,
36
+ removeBridgeConfig,
37
+ removeChannelMapping,
38
+ resolveChannelMapping,
39
+ setBridgeConfig,
40
+ setChannelMapping
41
+ } from "./chunk-LQ6Z4FXN.js";
18
42
  import {
19
43
  PROMPT_DEFAULTS,
20
44
  PROMPT_KEYS,
@@ -77,8 +101,15 @@ import {
77
101
  trackToolUse,
78
102
  uninstallNpmExtension,
79
103
  writeSystemsConfig
80
- } from "./chunk-DQ7VBXAP.js";
81
- import "./chunk-6F3YNULE.js";
104
+ } from "./chunk-RUIVWCYY.js";
105
+ import {
106
+ loadMergedEnv,
107
+ mindEnvPath,
108
+ readEnv,
109
+ sharedEnvPath,
110
+ writeEnv
111
+ } from "./chunk-PMMHVSCR.js";
112
+ import "./chunk-4L2Q7IP5.js";
82
113
  import {
83
114
  applyInitFiles,
84
115
  composeTemplate,
@@ -105,12 +136,33 @@ import {
105
136
  syncBuiltinSkills,
106
137
  uninstallSkill,
107
138
  updateSkill
108
- } from "./chunk-GBDVNPN2.js";
139
+ } from "./chunk-QJGLTPAP.js";
140
+ import {
141
+ readVoluteConfig,
142
+ writeVoluteConfig
143
+ } from "./chunk-CU6OFXMM.js";
144
+ import "./chunk-KXXJYY62.js";
145
+ import {
146
+ extractTextContent
147
+ } from "./chunk-7AZQFSOV.js";
109
148
  import {
110
149
  getActiveMinds,
111
150
  onMindEvent,
112
151
  stopAll
113
- } from "./chunk-PY557GDR.js";
152
+ } from "./chunk-GVVVMZ4J.js";
153
+ import {
154
+ exec,
155
+ gitExec,
156
+ resolveVoluteBin
157
+ } from "./chunk-3F7XK5Q7.js";
158
+ import {
159
+ chownMindDir,
160
+ createMindUser,
161
+ deleteMindUser,
162
+ ensureVoluteGroup,
163
+ isIsolationEnabled,
164
+ wrapForIsolation
165
+ } from "./chunk-SNW2NPP4.js";
114
166
  import {
115
167
  approveUser,
116
168
  changePassword,
@@ -129,7 +181,28 @@ import {
129
181
  syncMindProfile,
130
182
  updateUserProfile,
131
183
  verifyUser
132
- } from "./chunk-DMV5P2LU.js";
184
+ } from "./chunk-UIM5NHPP.js";
185
+ import {
186
+ getAiConfig,
187
+ getAvailableModels,
188
+ getConfiguredProviders,
189
+ getEnabledModels,
190
+ getUtilityModel,
191
+ qualifyModelId,
192
+ removeAiConfig,
193
+ removeProviderConfig,
194
+ resolveApiKey,
195
+ resolveTemplate,
196
+ saveProviderConfig,
197
+ setEnabledModels,
198
+ setUtilityModel,
199
+ unqualifyModelId
200
+ } from "./chunk-ORNY3MZR.js";
201
+ import {
202
+ isSetupComplete,
203
+ readGlobalConfig,
204
+ writeGlobalConfig
205
+ } from "./chunk-A6FLW5XD.js";
133
206
  import {
134
207
  addMessage,
135
208
  createChannel,
@@ -161,81 +234,15 @@ import {
161
234
  setConversationPrivate,
162
235
  subscribe as subscribe2,
163
236
  updateChannelSettings
164
- } from "./chunk-IIWF2IPD.js";
237
+ } from "./chunk-5DPRTREW.js";
165
238
  import {
166
239
  broadcast,
167
240
  subscribe
168
- } from "./chunk-B35VNNSS.js";
169
- import {
170
- readVoluteConfig,
171
- writeVoluteConfig
172
- } from "./chunk-CU6OFXMM.js";
173
- import "./chunk-BOLJUV77.js";
174
- import {
175
- extractTextContent
176
- } from "./chunk-X2J7QUFH.js";
177
- import {
178
- findBridgeForChannel,
179
- findOpenClawSession,
180
- getBridgeConfig,
181
- importOpenClawConnectors,
182
- importPiSession,
183
- parseNameFromIdentity,
184
- readBridgesConfig,
185
- removeBridgeConfig,
186
- removeChannelMapping,
187
- resolveChannelMapping,
188
- setBridgeConfig,
189
- setChannelMapping
190
- } from "./chunk-PZYJBOQP.js";
191
- import {
192
- loadMergedEnv,
193
- mindEnvPath,
194
- readEnv,
195
- sharedEnvPath,
196
- writeEnv
197
- } from "./chunk-YDBAY3NA.js";
198
- import {
199
- isHomeOnlyArchive
200
- } from "./chunk-SWW6AUVW.js";
201
- import {
202
- getAiConfig,
203
- getAvailableModels,
204
- getConfiguredProviders,
205
- getEnabledModels,
206
- getUtilityModel,
207
- qualifyModelId,
208
- removeAiConfig,
209
- removeProviderConfig,
210
- resolveApiKey,
211
- resolveTemplate,
212
- saveProviderConfig,
213
- setEnabledModels,
214
- setUtilityModel,
215
- unqualifyModelId
216
- } from "./chunk-M5RYAA5I.js";
241
+ } from "./chunk-N42QMDID.js";
217
242
  import {
218
243
  logBuffer,
219
244
  logger_default
220
245
  } from "./chunk-T2TP6ZC6.js";
221
- import {
222
- exec,
223
- gitExec,
224
- resolveVoluteBin
225
- } from "./chunk-PJ4IPTIN.js";
226
- import {
227
- chownMindDir,
228
- createMindUser,
229
- deleteMindUser,
230
- ensureVoluteGroup,
231
- isIsolationEnabled,
232
- wrapForIsolation
233
- } from "./chunk-L72WYMF7.js";
234
- import {
235
- isSetupComplete,
236
- readGlobalConfig,
237
- writeGlobalConfig
238
- } from "./chunk-NUX47Y2V.js";
239
246
  import {
240
247
  buildVoluteSlug
241
248
  } from "./chunk-LGNUFVMR.js";
@@ -261,7 +268,7 @@ import {
261
268
  validateMindName,
262
269
  voluteHome,
263
270
  voluteSystemDir
264
- } from "./chunk-75AJ54GM.js";
271
+ } from "./chunk-2NHRJ3YO.js";
265
272
  import {
266
273
  activity,
267
274
  channels,
@@ -273,16 +280,14 @@ import {
273
280
  systemPrompts,
274
281
  turns,
275
282
  users
276
- } from "./chunk-7PTQGPJY.js";
277
- import {
278
- __export
279
- } from "./chunk-7KJOFUNN.js";
283
+ } from "./chunk-CJ26DXZL.js";
284
+ import "./chunk-K3NQKI34.js";
280
285
 
281
286
  // packages/daemon/src/daemon.ts
282
287
  import { randomBytes } from "crypto";
283
- import { mkdirSync as mkdirSync10, readFileSync as readFileSync11, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
288
+ import { mkdirSync as mkdirSync10, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
284
289
  import { homedir as homedir3 } from "os";
285
- import { resolve as resolve17 } from "path";
290
+ import { resolve as resolve16 } from "path";
286
291
  import { format } from "util";
287
292
 
288
293
  // packages/daemon/src/lib/daemon/bridge-manager.ts
@@ -492,8 +497,8 @@ var BridgeManager = class {
492
497
  if (!tracked) return;
493
498
  this.stopping.add(platform);
494
499
  this.bridges.delete(platform);
495
- await new Promise((resolve18) => {
496
- tracked.child.on("exit", () => resolve18());
500
+ await new Promise((resolve17) => {
501
+ tracked.child.on("exit", () => resolve17());
497
502
  try {
498
503
  if (tracked.child.pid) {
499
504
  process.kill(-tracked.child.pid, "SIGTERM");
@@ -504,7 +509,7 @@ var BridgeManager = class {
504
509
  if (err instanceof Error && err.code !== "ESRCH") {
505
510
  blog.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
506
511
  }
507
- resolve18();
512
+ resolve17();
508
513
  }
509
514
  setTimeout(() => {
510
515
  try {
@@ -515,7 +520,7 @@ var BridgeManager = class {
515
520
  }
516
521
  } catch {
517
522
  }
518
- resolve18();
523
+ resolve17();
519
524
  }, 5e3);
520
525
  });
521
526
  this.stopping.delete(platform);
@@ -979,10 +984,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
979
984
  stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
980
985
  });
981
986
  });
982
- await new Promise((resolve18) => {
987
+ await new Promise((resolve17) => {
983
988
  stream.onAbort(() => {
984
989
  unsubscribe();
985
- resolve18();
990
+ resolve17();
986
991
  });
987
992
  });
988
993
  });
@@ -1287,14 +1292,16 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
1287
1292
  cleanupOAuthFlows();
1288
1293
  const flowId = crypto.randomUUID();
1289
1294
  const needsManualCode = !!oauthProvider.usesCallbackServer;
1295
+ const abortController = new AbortController();
1290
1296
  const flow = {
1291
1297
  status: "pending",
1292
1298
  needsManualCode,
1299
+ abortController,
1293
1300
  createdAt: Date.now()
1294
1301
  };
1295
1302
  oauthFlows.set(flowId, flow);
1296
- const promptPromise = needsManualCode ? new Promise((resolve18) => {
1297
- flow.resolveCode = resolve18;
1303
+ const promptPromise = needsManualCode ? new Promise((resolve17) => {
1304
+ flow.resolveCode = resolve17;
1298
1305
  }) : void 0;
1299
1306
  oauthProvider.login({
1300
1307
  onAuth: (info) => {
@@ -1310,7 +1317,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
1310
1317
  }
1311
1318
  return "";
1312
1319
  },
1313
- onManualCodeInput: needsManualCode ? () => promptPromise : void 0
1320
+ onManualCodeInput: needsManualCode ? () => promptPromise : void 0,
1321
+ signal: abortController.signal
1314
1322
  }).then(async (credentials) => {
1315
1323
  saveProviderConfig(provider, { oauth: credentials });
1316
1324
  const existing = oauthFlows.get(flowId);
@@ -1323,7 +1331,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
1323
1331
  existing.error = err instanceof Error ? err.message : String(err);
1324
1332
  }
1325
1333
  });
1326
- await new Promise((resolve18) => setTimeout(resolve18, 2e3));
1334
+ await new Promise((resolve17) => setTimeout(resolve17, 2e3));
1327
1335
  const state = oauthFlows.get(flowId);
1328
1336
  return c.json({
1329
1337
  flowId,
@@ -1364,6 +1372,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
1364
1372
  status: flow.status,
1365
1373
  waitingForCode: flow.waitingForCode
1366
1374
  };
1375
+ if (flow.url) result.url = flow.url;
1376
+ if (flow.instructions) result.instructions = flow.instructions;
1367
1377
  if (flow.error) result.error = flow.error;
1368
1378
  if (flow.status !== "pending") {
1369
1379
  setTimeout(() => oauthFlows.delete(flowId), 3e4);
@@ -1418,13 +1428,12 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
1418
1428
  }
1419
1429
  );
1420
1430
  var oauthFlows = /* @__PURE__ */ new Map();
1421
- var OAUTH_FLOW_TTL_MS = 10 * 60 * 1e3;
1422
1431
  function cleanupOAuthFlows() {
1423
- const now = Date.now();
1424
1432
  for (const [id, flow] of oauthFlows) {
1425
- if (now - flow.createdAt > OAUTH_FLOW_TTL_MS) {
1426
- oauthFlows.delete(id);
1433
+ if (flow.status === "pending") {
1434
+ flow.abortController?.abort();
1427
1435
  }
1436
+ oauthFlows.delete(id);
1428
1437
  }
1429
1438
  }
1430
1439
  var PROVIDER_TEMPLATES = {
@@ -1579,8 +1588,8 @@ var app2 = new Hono2().get("/events", async (c) => {
1579
1588
  });
1580
1589
  }, 15e3);
1581
1590
  cleanups.push(() => clearInterval(keepAlive));
1582
- await new Promise((resolve18) => {
1583
- stream.onAbort(() => resolve18());
1591
+ await new Promise((resolve17) => {
1592
+ stream.onAbort(() => resolve17());
1584
1593
  });
1585
1594
  } finally {
1586
1595
  for (const cleanup of cleanups) {
@@ -1983,7 +1992,7 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
1983
1992
  }
1984
1993
  const participants = await getParticipants(channel.id);
1985
1994
  if (!participants.some((p) => p.userId === puppet.id)) {
1986
- const { addParticipant } = await import("./conversations-HH3CJD4E.js");
1995
+ const { addParticipant } = await import("./conversations-G6YRSABR.js");
1987
1996
  await addParticipant(channel.id, puppet.id);
1988
1997
  }
1989
1998
  const contentBlocks = body.content;
@@ -2076,8 +2085,8 @@ async function fanOutToBridgedMinds(opts) {
2076
2085
  const participants = await getParticipants(opts.conversationId);
2077
2086
  const mindParticipants = participants.filter((p) => p.userType === "mind");
2078
2087
  const participantNames = participants.map((p) => p.username);
2079
- const { getMindManager: getMindManager2 } = await import("./mind-manager-TJ2SUPRX.js");
2080
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-WAZWMFJT.js");
2088
+ const { getMindManager: getMindManager2 } = await import("./mind-manager-VOEQ2IZL.js");
2089
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-PBOIEBJZ.js");
2081
2090
  const manager = getMindManager2();
2082
2091
  const sm = getSleepManagerIfReady2();
2083
2092
  const targetMinds = mindParticipants.filter((ap) => {
@@ -2106,656 +2115,6 @@ var bridges_default = app4;
2106
2115
 
2107
2116
  // packages/daemon/src/web/api/channels.ts
2108
2117
  import { Hono as Hono5 } from "hono";
2109
-
2110
- // packages/platforms/src/drivers/discord.ts
2111
- var discord_exports = {};
2112
- __export(discord_exports, {
2113
- createConversation: () => createConversation2,
2114
- listConversations: () => listConversations,
2115
- listUsers: () => listUsers2,
2116
- read: () => read,
2117
- send: () => send
2118
- });
2119
-
2120
- // packages/platforms/src/slugify.ts
2121
- function slugify(text) {
2122
- return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
2123
- }
2124
-
2125
- // packages/platforms/src/split-message.ts
2126
- function splitMessage(text, maxLength) {
2127
- const chunks = [];
2128
- while (text.length > maxLength) {
2129
- let splitAt = text.lastIndexOf("\n", maxLength);
2130
- if (splitAt < maxLength / 2) splitAt = maxLength;
2131
- chunks.push(text.slice(0, splitAt));
2132
- text = text.slice(splitAt).replace(/^\n/, "");
2133
- }
2134
- if (text) chunks.push(text);
2135
- return chunks;
2136
- }
2137
-
2138
- // packages/platforms/src/drivers/discord.ts
2139
- var DISCORD_MAX_LENGTH = 2e3;
2140
- var API_BASE = "https://discord.com/api/v10";
2141
- function requireToken(env) {
2142
- const token = env.DISCORD_TOKEN;
2143
- if (!token) throw new Error("DISCORD_TOKEN not set");
2144
- return token;
2145
- }
2146
- async function discordGet(token, path) {
2147
- const res = await fetch(`${API_BASE}${path}`, {
2148
- headers: { Authorization: `Bot ${token}` }
2149
- });
2150
- if (!res.ok) {
2151
- throw new Error(`Discord API error: ${res.status} ${res.statusText}`);
2152
- }
2153
- return res.json();
2154
- }
2155
- async function read(env, channelSlug, limit) {
2156
- const token = requireToken(env);
2157
- const channelId = resolvePlatformId(channelSlug);
2158
- const res = await fetch(`${API_BASE}/channels/${channelId}/messages?limit=${limit}`, {
2159
- headers: { Authorization: `Bot ${token}` }
2160
- });
2161
- if (!res.ok) {
2162
- throw new Error(`Discord API error: ${res.status} ${res.statusText}`);
2163
- }
2164
- const messages = await res.json();
2165
- return messages.reverse().map((m) => `${m.author.username}: ${m.content}`).join("\n");
2166
- }
2167
- async function send(env, channelSlug, message, images) {
2168
- const token = requireToken(env);
2169
- const channelId = resolvePlatformId(channelSlug);
2170
- if (images?.length) {
2171
- for (let i = 0; i < images.length; i++) {
2172
- const img = images[i];
2173
- const ext = img.media_type.split("/")[1] || "png";
2174
- const form = new FormData();
2175
- const content = i === 0 ? message.slice(0, DISCORD_MAX_LENGTH) : "";
2176
- form.append("payload_json", JSON.stringify({ content }));
2177
- form.append(
2178
- "files[0]",
2179
- new Blob([Buffer.from(img.data, "base64")], { type: img.media_type }),
2180
- `image.${ext}`
2181
- );
2182
- const res = await fetch(`${API_BASE}/channels/${channelId}/messages`, {
2183
- method: "POST",
2184
- headers: { Authorization: `Bot ${token}` },
2185
- body: form
2186
- });
2187
- if (!res.ok) {
2188
- const body = await res.text().catch(() => "");
2189
- const partial = i > 0 ? ` (${i}/${images.length} images were already sent)` : "";
2190
- throw new Error(`Discord API error: ${res.status} ${body || res.statusText}${partial}`);
2191
- }
2192
- }
2193
- return;
2194
- }
2195
- const chunks = splitMessage(message, DISCORD_MAX_LENGTH);
2196
- for (let i = 0; i < chunks.length; i++) {
2197
- const res = await fetch(`${API_BASE}/channels/${channelId}/messages`, {
2198
- method: "POST",
2199
- headers: {
2200
- Authorization: `Bot ${token}`,
2201
- "Content-Type": "application/json"
2202
- },
2203
- body: JSON.stringify({ content: chunks[i] })
2204
- });
2205
- if (!res.ok) {
2206
- const partial = i > 0 ? ` (${i}/${chunks.length} chunks were already sent)` : "";
2207
- throw new Error(`Discord API error: ${res.status} ${res.statusText}${partial}`);
2208
- }
2209
- }
2210
- }
2211
- async function listConversations(env) {
2212
- const token = requireToken(env);
2213
- const results = [];
2214
- const guilds = await discordGet(token, "/users/@me/guilds");
2215
- for (const guild of guilds) {
2216
- const channels2 = await discordGet(token, `/guilds/${guild.id}/channels`);
2217
- for (const ch of channels2) {
2218
- if (ch.type !== 0) continue;
2219
- results.push({
2220
- id: `discord:${slugify(guild.name)}/${slugify(ch.name)}`,
2221
- platformId: ch.id,
2222
- name: `#${ch.name}`,
2223
- type: "channel"
2224
- });
2225
- }
2226
- }
2227
- const dms = await discordGet(token, "/users/@me/channels");
2228
- for (const dm of dms) {
2229
- const recipients = dm.recipients?.map((r) => r.username) ?? [];
2230
- const slug = recipients.length === 0 ? `discord:${dm.id}` : recipients.length === 1 ? `discord:@${slugify(recipients[0])}` : `discord:@${recipients.map(slugify).sort().join(",")}`;
2231
- results.push({
2232
- id: slug,
2233
- platformId: dm.id,
2234
- name: recipients.join(", ") || "DM",
2235
- type: dm.type === 1 ? "dm" : "channel"
2236
- });
2237
- }
2238
- return results;
2239
- }
2240
- async function listUsers2(env) {
2241
- const token = requireToken(env);
2242
- const seen = /* @__PURE__ */ new Map();
2243
- const guilds = await discordGet(token, "/users/@me/guilds");
2244
- for (const guild of guilds) {
2245
- const members = await discordGet(token, `/guilds/${guild.id}/members?limit=1000`);
2246
- for (const m of members) {
2247
- if (!seen.has(m.user.id)) {
2248
- seen.set(m.user.id, {
2249
- id: m.user.id,
2250
- username: m.user.username,
2251
- type: m.user.bot ? "bot" : "human"
2252
- });
2253
- }
2254
- }
2255
- }
2256
- return [...seen.values()];
2257
- }
2258
- async function createConversation2(env, participants, _name) {
2259
- const token = requireToken(env);
2260
- if (participants.length !== 1) {
2261
- throw new Error(
2262
- "Discord group creation not supported via bot \u2014 use threads in an existing channel"
2263
- );
2264
- }
2265
- const allUsers = await listUsers2(env);
2266
- const target = allUsers.find((u) => u.username.toLowerCase() === participants[0].toLowerCase());
2267
- if (!target) {
2268
- throw new Error(`User not found: ${participants[0]}`);
2269
- }
2270
- const res = await fetch(`${API_BASE}/users/@me/channels`, {
2271
- method: "POST",
2272
- headers: {
2273
- Authorization: `Bot ${token}`,
2274
- "Content-Type": "application/json"
2275
- },
2276
- body: JSON.stringify({ recipient_id: target.id })
2277
- });
2278
- if (!res.ok) {
2279
- throw new Error(`Discord API error: ${res.status} ${res.statusText}`);
2280
- }
2281
- const dmChannel = await res.json();
2282
- return `discord:${dmChannel.id}`;
2283
- }
2284
-
2285
- // packages/platforms/src/drivers/slack.ts
2286
- var slack_exports = {};
2287
- __export(slack_exports, {
2288
- createConversation: () => createConversation3,
2289
- listConversations: () => listConversations2,
2290
- listUsers: () => listUsers3,
2291
- read: () => read2,
2292
- send: () => send2
2293
- });
2294
- var SLACK_MAX_LENGTH = 4e3;
2295
- var API_BASE2 = "https://slack.com/api";
2296
- function requireToken2(env) {
2297
- const token = env.SLACK_BOT_TOKEN;
2298
- if (!token) throw new Error("SLACK_BOT_TOKEN not set");
2299
- return token;
2300
- }
2301
- async function slackApi(token, method, body) {
2302
- const res = await fetch(`${API_BASE2}/${method}`, {
2303
- method: "POST",
2304
- headers: {
2305
- Authorization: `Bearer ${token}`,
2306
- "Content-Type": "application/json"
2307
- },
2308
- body: JSON.stringify(body)
2309
- });
2310
- if (!res.ok) {
2311
- throw new Error(`Slack API HTTP error: ${res.status} ${res.statusText}`);
2312
- }
2313
- const data = await res.json();
2314
- if (!data.ok) {
2315
- throw new Error(`Slack API error: ${data.error}`);
2316
- }
2317
- return data;
2318
- }
2319
- async function read2(env, channelSlug, limit) {
2320
- const token = requireToken2(env);
2321
- const channelId = resolvePlatformId(channelSlug);
2322
- const data = await slackApi(token, "conversations.history", {
2323
- channel: channelId,
2324
- limit
2325
- });
2326
- return data.messages.reverse().map((m) => `${m.user ?? m.bot_id ?? "unknown"}: ${m.text}`).join("\n");
2327
- }
2328
- async function send2(env, channelSlug, message, images) {
2329
- const token = requireToken2(env);
2330
- const channelId = resolvePlatformId(channelSlug);
2331
- if (images?.length) {
2332
- for (const img of images) {
2333
- const ext = img.media_type.split("/")[1] || "png";
2334
- const filename = `image.${ext}`;
2335
- const binary = Buffer.from(img.data, "base64");
2336
- const uploadData = await slackApi(token, "files.getUploadURLExternal", {
2337
- filename,
2338
- length: binary.length
2339
- });
2340
- const uploadRes = await fetch(uploadData.upload_url, {
2341
- method: "POST",
2342
- body: binary
2343
- });
2344
- if (!uploadRes.ok) {
2345
- throw new Error(`Slack file upload failed: ${uploadRes.status} ${uploadRes.statusText}`);
2346
- }
2347
- await slackApi(token, "files.completeUploadExternal", {
2348
- files: [{ id: uploadData.file_id }],
2349
- channel_id: channelId
2350
- });
2351
- }
2352
- if (message) {
2353
- const chunks2 = splitMessage(message, SLACK_MAX_LENGTH);
2354
- for (const chunk of chunks2) {
2355
- await slackApi(token, "chat.postMessage", {
2356
- channel: channelId,
2357
- text: chunk
2358
- });
2359
- }
2360
- }
2361
- return;
2362
- }
2363
- const chunks = splitMessage(message, SLACK_MAX_LENGTH);
2364
- for (let i = 0; i < chunks.length; i++) {
2365
- try {
2366
- await slackApi(token, "chat.postMessage", {
2367
- channel: channelId,
2368
- text: chunks[i]
2369
- });
2370
- } catch (err) {
2371
- const partial = i > 0 ? ` (${i}/${chunks.length} chunks were already sent)` : "";
2372
- throw new Error(`${err instanceof Error ? err.message : err}${partial}`);
2373
- }
2374
- }
2375
- }
2376
- async function listConversations2(env) {
2377
- const token = requireToken2(env);
2378
- const authData = await slackApi(token, "auth.test", {});
2379
- const teamName = authData.team ?? "workspace";
2380
- const data = await slackApi(token, "conversations.list", {
2381
- types: "public_channel,private_channel,mpim,im",
2382
- limit: 1e3
2383
- });
2384
- const userMap = /* @__PURE__ */ new Map();
2385
- const imChannels = data.channels.filter((ch) => ch.is_im && ch.user);
2386
- if (imChannels.length > 0) {
2387
- const users2 = await listUsers3(env);
2388
- for (const u of users2) {
2389
- userMap.set(u.id, u.username);
2390
- }
2391
- }
2392
- return data.channels.map((ch) => {
2393
- let type = "channel";
2394
- if (ch.is_im) type = "dm";
2395
- let slug;
2396
- let name;
2397
- if (ch.is_im && ch.user) {
2398
- const username = userMap.get(ch.user) ?? ch.user;
2399
- slug = `slack:@${slugify(username)}`;
2400
- name = username;
2401
- } else if (ch.name) {
2402
- slug = `slack:${slugify(teamName)}/${slugify(ch.name)}`;
2403
- name = ch.name;
2404
- } else {
2405
- slug = `slack:${ch.id}`;
2406
- name = ch.id;
2407
- }
2408
- return {
2409
- id: slug,
2410
- platformId: ch.id,
2411
- name,
2412
- type,
2413
- participantCount: ch.num_members
2414
- };
2415
- });
2416
- }
2417
- async function listUsers3(env) {
2418
- const token = requireToken2(env);
2419
- const data = await slackApi(token, "users.list", {});
2420
- return data.members.filter((m) => !m.deleted).map((m) => ({
2421
- id: m.id,
2422
- username: m.name,
2423
- type: m.is_bot ? "bot" : "human"
2424
- }));
2425
- }
2426
- async function createConversation3(env, participants, name) {
2427
- const token = requireToken2(env);
2428
- const allUsers = await listUsers3(env);
2429
- const ids = [];
2430
- for (const p of participants) {
2431
- const user = allUsers.find((u) => u.username.toLowerCase() === p.toLowerCase());
2432
- if (!user) throw new Error(`User not found: ${p}`);
2433
- ids.push(user.id);
2434
- }
2435
- if (name) {
2436
- const createData = await slackApi(token, "conversations.create", {
2437
- name,
2438
- is_private: true
2439
- });
2440
- const channelId = createData.channel.id;
2441
- for (const userId of ids) {
2442
- await slackApi(token, "conversations.invite", {
2443
- channel: channelId,
2444
- users: userId
2445
- });
2446
- }
2447
- const authData = await slackApi(token, "auth.test", {});
2448
- const teamName = authData.team ?? "workspace";
2449
- const slug = `slack:${slugify(teamName)}/${slugify(name)}`;
2450
- return slug;
2451
- }
2452
- const openData = await slackApi(token, "conversations.open", { users: ids.join(",") });
2453
- return `slack:${openData.channel.id}`;
2454
- }
2455
-
2456
- // packages/platforms/src/drivers/telegram.ts
2457
- var telegram_exports = {};
2458
- __export(telegram_exports, {
2459
- createConversation: () => createConversation4,
2460
- listConversations: () => listConversations3,
2461
- listUsers: () => listUsers4,
2462
- read: () => read3,
2463
- send: () => send3
2464
- });
2465
- var TELEGRAM_MAX_LENGTH = 4096;
2466
- var API_BASE3 = "https://api.telegram.org";
2467
- function requireToken3(env) {
2468
- const token = env.TELEGRAM_BOT_TOKEN;
2469
- if (!token) throw new Error("TELEGRAM_BOT_TOKEN not set");
2470
- return token;
2471
- }
2472
- async function read3(_env, _channelSlug, _limit) {
2473
- throw new Error(
2474
- "Telegram Bot API does not support reading chat history. Use volute chat send instead."
2475
- );
2476
- }
2477
- async function send3(env, channelSlug, message, images) {
2478
- const token = requireToken3(env);
2479
- const chatId = resolvePlatformId(channelSlug);
2480
- if (images?.length) {
2481
- const CAPTION_MAX = 1024;
2482
- for (let i = 0; i < images.length; i++) {
2483
- const img = images[i];
2484
- const ext = img.media_type.split("/")[1] || "png";
2485
- const form = new FormData();
2486
- form.append("chat_id", chatId);
2487
- form.append(
2488
- "photo",
2489
- new Blob([Buffer.from(img.data, "base64")], { type: img.media_type }),
2490
- `image.${ext}`
2491
- );
2492
- if (i === 0 && message) {
2493
- form.append("caption", message.slice(0, CAPTION_MAX));
2494
- }
2495
- const res = await fetch(`${API_BASE3}/bot${token}/sendPhoto`, {
2496
- method: "POST",
2497
- body: form
2498
- });
2499
- if (!res.ok) {
2500
- const body = await res.text().catch(() => "");
2501
- const partial = i > 0 ? ` (${i}/${images.length} images were already sent)` : "";
2502
- throw new Error(`Telegram API error: ${res.status} ${body}${partial}`);
2503
- }
2504
- }
2505
- if (message && message.length > CAPTION_MAX) {
2506
- const remaining = message.slice(CAPTION_MAX);
2507
- const chunks2 = splitMessage(remaining, TELEGRAM_MAX_LENGTH);
2508
- for (const chunk of chunks2) {
2509
- const res = await fetch(`${API_BASE3}/bot${token}/sendMessage`, {
2510
- method: "POST",
2511
- headers: { "Content-Type": "application/json" },
2512
- body: JSON.stringify({ chat_id: chatId, text: chunk })
2513
- });
2514
- if (!res.ok) {
2515
- const body = await res.text().catch(() => "");
2516
- throw new Error(`Telegram API error: ${res.status} ${body}`);
2517
- }
2518
- }
2519
- }
2520
- return;
2521
- }
2522
- const chunks = splitMessage(message, TELEGRAM_MAX_LENGTH);
2523
- for (let i = 0; i < chunks.length; i++) {
2524
- const res = await fetch(`${API_BASE3}/bot${token}/sendMessage`, {
2525
- method: "POST",
2526
- headers: { "Content-Type": "application/json" },
2527
- body: JSON.stringify({ chat_id: chatId, text: chunks[i] })
2528
- });
2529
- if (!res.ok) {
2530
- const body = await res.text().catch(() => "");
2531
- const partial = i > 0 ? ` (${i}/${chunks.length} chunks were already sent)` : "";
2532
- throw new Error(`Telegram API error: ${res.status} ${body}${partial}`);
2533
- }
2534
- }
2535
- }
2536
- async function listConversations3() {
2537
- throw new Error(
2538
- "Telegram Bot API does not support listing conversations. Users must message the bot first."
2539
- );
2540
- }
2541
- async function listUsers4() {
2542
- throw new Error(
2543
- "Telegram Bot API does not support listing users. Users must message the bot first."
2544
- );
2545
- }
2546
- async function createConversation4() {
2547
- throw new Error(
2548
- "Telegram Bot API does not support creating conversations. Users must message the bot first."
2549
- );
2550
- }
2551
-
2552
- // packages/platforms/src/index.ts
2553
- var PLATFORMS = {
2554
- discord: {
2555
- name: "discord",
2556
- displayName: "Discord",
2557
- driver: discord_exports
2558
- },
2559
- slack: {
2560
- name: "slack",
2561
- displayName: "Slack",
2562
- driver: slack_exports
2563
- },
2564
- telegram: {
2565
- name: "telegram",
2566
- displayName: "Telegram",
2567
- driver: telegram_exports
2568
- },
2569
- volute: { name: "volute", displayName: "Volute" },
2570
- mail: { name: "mail", displayName: "Email" },
2571
- system: { name: "system", displayName: "System" }
2572
- };
2573
- function registerPlatform(name, platform) {
2574
- PLATFORMS[name] = platform;
2575
- }
2576
- function getPlatformDriver(platform) {
2577
- return PLATFORMS[platform]?.driver ?? null;
2578
- }
2579
- function resolvePlatformId(slug) {
2580
- const colonIdx = slug.indexOf(":");
2581
- return colonIdx !== -1 ? slug.slice(colonIdx + 1) : slug;
2582
- }
2583
-
2584
- // packages/daemon/src/lib/platforms/volute.ts
2585
- var volute_exports = {};
2586
- __export(volute_exports, {
2587
- createConversation: () => createConversation5,
2588
- listConversations: () => listConversations4,
2589
- listUsers: () => listUsers5,
2590
- read: () => read4,
2591
- send: () => send4
2592
- });
2593
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
2594
- import { resolve as resolve4 } from "path";
2595
- function readSessionFile(mindDir2) {
2596
- try {
2597
- const p = resolve4(mindDir2, ".mind", "current-session");
2598
- if (existsSync4(p)) return readFileSync4(p, "utf-8").trim() || void 0;
2599
- } catch (err) {
2600
- const code = err.code;
2601
- if (code !== "ENOENT") {
2602
- console.error(`[volute] failed to read session file: ${code ?? err}`);
2603
- }
2604
- }
2605
- return void 0;
2606
- }
2607
- function getDaemonConfig() {
2608
- const configPath = resolve4(voluteSystemDir(), "daemon.json");
2609
- if (!existsSync4(configPath)) {
2610
- throw new Error("Volute daemon is not running");
2611
- }
2612
- let config2;
2613
- try {
2614
- config2 = JSON.parse(readFileSync4(configPath, "utf-8"));
2615
- } catch (err) {
2616
- throw new Error(`Failed to parse ${configPath}: ${err}`);
2617
- }
2618
- if (typeof config2.port !== "number") {
2619
- throw new Error(`Invalid or missing port in ${configPath}`);
2620
- }
2621
- const url = new URL("http://localhost");
2622
- url.hostname = config2.hostname || "localhost";
2623
- url.port = String(config2.port);
2624
- return { url: url.origin, token: config2.token };
2625
- }
2626
- async function read4(env, channelSlug, limit) {
2627
- const mindName = env.VOLUTE_MIND;
2628
- if (!mindName) throw new Error("VOLUTE_MIND not set");
2629
- const conversationId = resolvePlatformId(channelSlug);
2630
- const { url, token } = getDaemonConfig();
2631
- const headers = { Origin: url };
2632
- if (token) headers.Authorization = `Bearer ${token}`;
2633
- const res = await fetch(
2634
- `${url}/api/minds/${encodeURIComponent(mindName)}/conversations/${encodeURIComponent(conversationId)}/messages`,
2635
- { headers }
2636
- );
2637
- if (!res.ok) {
2638
- throw new Error(`Failed to read conversation: ${res.status} ${res.statusText}`);
2639
- }
2640
- const data = await res.json();
2641
- if (!Array.isArray(data.items)) {
2642
- throw new Error("Unexpected response format when reading conversation messages");
2643
- }
2644
- return data.items.slice(-limit).map((m) => {
2645
- const text = Array.isArray(m.content) ? m.content.filter((b) => b.type === "text").map((b) => b.text).join("") : m.content;
2646
- return `${m.sender_name ?? m.role}: ${text}`;
2647
- }).join("\n");
2648
- }
2649
- async function send4(env, channelSlug, message, images) {
2650
- const mindName = env.VOLUTE_MIND;
2651
- if (!mindName) throw new Error("VOLUTE_MIND not set");
2652
- const conversationId = resolvePlatformId(channelSlug);
2653
- const { url, token } = getDaemonConfig();
2654
- const headers = {
2655
- "Content-Type": "application/json",
2656
- Origin: url
2657
- };
2658
- if (token) headers.Authorization = `Bearer ${token}`;
2659
- const voluteSession = env.VOLUTE_SESSION || (env.VOLUTE_MIND_DIR ? readSessionFile(env.VOLUTE_MIND_DIR) : void 0);
2660
- if (voluteSession) headers["X-Volute-Session"] = voluteSession;
2661
- const res = await fetch(`${url}/api/v1/chat`, {
2662
- method: "POST",
2663
- headers,
2664
- body: JSON.stringify({
2665
- message,
2666
- conversationId,
2667
- sender: env.VOLUTE_SENDER ?? mindName,
2668
- images,
2669
- targetMind: mindName
2670
- })
2671
- });
2672
- if (!res.ok) {
2673
- const data = await res.json().catch(() => ({}));
2674
- throw new Error(data.error ?? `Failed to send: ${res.status}`);
2675
- }
2676
- }
2677
- async function listConversations4(env) {
2678
- const mindName = env.VOLUTE_MIND;
2679
- if (!mindName) throw new Error("VOLUTE_MIND not set");
2680
- const { url, token } = getDaemonConfig();
2681
- const headers = { Origin: url };
2682
- if (token) headers.Authorization = `Bearer ${token}`;
2683
- const res = await fetch(`${url}/api/minds/${encodeURIComponent(mindName)}/conversations`, {
2684
- headers
2685
- });
2686
- if (!res.ok) {
2687
- throw new Error(`Failed to list conversations: ${res.status} ${res.statusText}`);
2688
- }
2689
- const convs = await res.json();
2690
- const results = [];
2691
- for (const conv of convs) {
2692
- const participants = conv.participants ?? [];
2693
- const slug = buildVoluteSlug({
2694
- participants,
2695
- mindUsername: mindName,
2696
- conversationId: conv.id,
2697
- convType: conv.type,
2698
- convName: conv.channel_name
2699
- });
2700
- const convType = conv.type === "channel" ? "channel" : "dm";
2701
- const other = participants.find((p) => p.username !== mindName);
2702
- const displayName = conv.type === "channel" && conv.channel_name ? `#${conv.channel_name}` : other ? `@${other.username}` : "(untitled)";
2703
- results.push({
2704
- id: slug,
2705
- platformId: conv.id,
2706
- name: displayName,
2707
- type: convType,
2708
- participantCount: participants.length
2709
- });
2710
- }
2711
- return results;
2712
- }
2713
- async function listUsers5(_env) {
2714
- const { url, token } = getDaemonConfig();
2715
- const headers = { Origin: url };
2716
- if (token) headers.Authorization = `Bearer ${token}`;
2717
- const res = await fetch(`${url}/api/auth/users`, { headers });
2718
- if (!res.ok) {
2719
- throw new Error(`Failed to list users: ${res.status} ${res.statusText}`);
2720
- }
2721
- const data = await res.json();
2722
- return data.map((u) => ({
2723
- id: String(u.id),
2724
- username: u.username,
2725
- type: u.user_type
2726
- }));
2727
- }
2728
- async function createConversation5(env, participants, name) {
2729
- const mindName = env.VOLUTE_MIND;
2730
- if (!mindName) throw new Error("VOLUTE_MIND not set");
2731
- const { url, token } = getDaemonConfig();
2732
- const headers = {
2733
- "Content-Type": "application/json",
2734
- Origin: url
2735
- };
2736
- if (token) headers.Authorization = `Bearer ${token}`;
2737
- const res = await fetch(`${url}/api/minds/${encodeURIComponent(mindName)}/conversations`, {
2738
- method: "POST",
2739
- headers,
2740
- body: JSON.stringify({ participantNames: participants })
2741
- });
2742
- if (!res.ok) {
2743
- const data = await res.json().catch(() => ({}));
2744
- throw new Error(data.error ?? `Failed to create conversation: ${res.status}`);
2745
- }
2746
- const conv = await res.json();
2747
- return conv.id;
2748
- }
2749
-
2750
- // packages/daemon/src/lib/platforms.ts
2751
- registerPlatform("volute", {
2752
- name: "volute",
2753
- displayName: "Volute",
2754
- builtIn: true,
2755
- driver: volute_exports
2756
- });
2757
-
2758
- // packages/daemon/src/web/api/channels.ts
2759
2118
  function buildEnv(name) {
2760
2119
  return { ...loadMergedEnv(name), VOLUTE_MIND: name, VOLUTE_MIND_DIR: mindDir(name) };
2761
2120
  }
@@ -2932,14 +2291,14 @@ var app7 = new Hono8().get("/", (c) => {
2932
2291
  var extensions_default = app7;
2933
2292
 
2934
2293
  // packages/daemon/src/web/api/file-sharing.ts
2935
- import { readFileSync as readFileSync5, statSync } from "fs";
2936
- import { resolve as resolve5 } from "path";
2294
+ import { readFileSync as readFileSync4, statSync } from "fs";
2295
+ import { resolve as resolve4 } from "path";
2937
2296
  import { Hono as Hono9 } from "hono";
2938
2297
  async function notifyMind(mindName, message) {
2939
2298
  const entry = await findMind(mindName);
2940
2299
  if (!entry) return;
2941
2300
  try {
2942
- const { sendSystemMessage } = await import("./system-chat-2IFS5HCX.js");
2301
+ const { sendSystemMessage } = await import("./system-chat-7AIN3U5M.js");
2943
2302
  await sendSystemMessage(mindName, message);
2944
2303
  } catch (err) {
2945
2304
  logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
@@ -2958,7 +2317,7 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
2958
2317
  const pathErr = validateFilePath(body.filePath);
2959
2318
  if (pathErr) return c.json({ error: pathErr }, 400);
2960
2319
  const senderDir = mindDir(senderName);
2961
- const filePath = resolve5(senderDir, "home", body.filePath);
2320
+ const filePath = resolve4(senderDir, "home", body.filePath);
2962
2321
  const MAX_FILE_SIZE3 = 50 * 1024 * 1024;
2963
2322
  const stat3 = statSync(filePath, { throwIfNoEntry: false });
2964
2323
  if (!stat3) return c.json({ error: `File not found: ${body.filePath}` }, 404);
@@ -2972,7 +2331,7 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
2972
2331
  }
2973
2332
  let content;
2974
2333
  try {
2975
- content = readFileSync5(filePath);
2334
+ content = readFileSync4(filePath);
2976
2335
  } catch (err) {
2977
2336
  const code = err.code;
2978
2337
  if (code === "ENOENT") {
@@ -3064,7 +2423,7 @@ var file_sharing_default = app8;
3064
2423
  // packages/daemon/src/web/api/files.ts
3065
2424
  import { mkdirSync as mkdirSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
3066
2425
  import { readdir, readFile, realpath, stat } from "fs/promises";
3067
- import { extname as extname2, resolve as resolve6 } from "path";
2426
+ import { extname as extname2, resolve as resolve5 } from "path";
3068
2427
  import { Hono as Hono10 } from "hono";
3069
2428
  var AVATAR_MIME2 = {
3070
2429
  ".png": "image/png",
@@ -3109,13 +2468,13 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
3109
2468
  return c.json({ error: "Invalid file type (png, jpg, gif, webp only)" }, 400);
3110
2469
  }
3111
2470
  const dir = entry.dir ?? mindDir(name);
3112
- const homeDir = resolve6(dir, "home");
2471
+ const homeDir = resolve5(dir, "home");
3113
2472
  const filename = `avatar${ext}`;
3114
- const avatarPath = resolve6(homeDir, filename);
2473
+ const avatarPath = resolve5(homeDir, filename);
3115
2474
  const config2 = readVoluteConfig(dir) ?? {};
3116
2475
  const oldAvatar = config2.profile?.avatar;
3117
2476
  if (oldAvatar && oldAvatar !== filename) {
3118
- rmSync2(resolve6(homeDir, oldAvatar), { force: true });
2477
+ rmSync2(resolve5(homeDir, oldAvatar), { force: true });
3119
2478
  }
3120
2479
  const buffer2 = Buffer.from(await file.arrayBuffer());
3121
2480
  mkdirSync3(homeDir, { recursive: true });
@@ -3137,8 +2496,8 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
3137
2496
  const ext = extname2(config2.profile.avatar).toLowerCase();
3138
2497
  const mime = AVATAR_MIME2[ext];
3139
2498
  if (!mime) return c.json({ error: "Invalid avatar extension" }, 400);
3140
- const homeDir = resolve6(dir, "home");
3141
- const avatarPath = resolve6(homeDir, config2.profile.avatar);
2499
+ const homeDir = resolve5(dir, "home");
2500
+ const avatarPath = resolve5(homeDir, config2.profile.avatar);
3142
2501
  if (!avatarPath.startsWith(`${homeDir}/`)) return c.json({ error: "Invalid avatar path" }, 400);
3143
2502
  let realAvatarPath;
3144
2503
  try {
@@ -3166,7 +2525,7 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
3166
2525
  const name = c.req.param("name");
3167
2526
  const entry = await findMind(name);
3168
2527
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3169
- const homeDir = resolve6(entry.dir ?? mindDir(name), "home");
2528
+ const homeDir = resolve5(entry.dir ?? mindDir(name), "home");
3170
2529
  let entries;
3171
2530
  try {
3172
2531
  entries = await readdir(homeDir, { withFileTypes: true });
@@ -3181,10 +2540,10 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
3181
2540
  const name = c.req.param("name");
3182
2541
  const entry = await findMind(name);
3183
2542
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3184
- const homeDir = resolve6(entry.dir ?? mindDir(name), "home");
2543
+ const homeDir = resolve5(entry.dir ?? mindDir(name), "home");
3185
2544
  const wildcard = c.req.path.replace(new RegExp(`^.*/minds/${name}/files`), "") || "/";
3186
2545
  const relativePath = wildcard.slice(1);
3187
- const requestedPath = resolve6(homeDir, relativePath);
2546
+ const requestedPath = resolve5(homeDir, relativePath);
3188
2547
  if (requestedPath !== homeDir && !requestedPath.startsWith(`${homeDir}/`))
3189
2548
  return c.text("Forbidden", 403);
3190
2549
  if (relativePath.split("/").some((seg) => seg.startsWith("."))) return c.text("Forbidden", 403);
@@ -3471,7 +2830,7 @@ var history = new Hono11().get("/turns", async (c) => {
3471
2830
  const stream = new ReadableStream({
3472
2831
  start(controller) {
3473
2832
  const encoder = new TextEncoder();
3474
- const send5 = (data) => {
2833
+ const send = (data) => {
3475
2834
  controller.enqueue(encoder.encode(`data: ${data}
3476
2835
 
3477
2836
  `));
@@ -3488,7 +2847,7 @@ var history = new Hono11().get("/turns", async (c) => {
3488
2847
  if (mindFilter) {
3489
2848
  unsubscribe = subscribe3(mindFilter, (event) => {
3490
2849
  try {
3491
- send5(JSON.stringify(event));
2850
+ send(JSON.stringify(event));
3492
2851
  } catch {
3493
2852
  clearInterval(pingInterval);
3494
2853
  unsubscribe?.();
@@ -3497,7 +2856,7 @@ var history = new Hono11().get("/turns", async (c) => {
3497
2856
  } else {
3498
2857
  unsubscribe = subscribeAll((event) => {
3499
2858
  try {
3500
- send5(JSON.stringify(event));
2859
+ send(JSON.stringify(event));
3501
2860
  } catch {
3502
2861
  clearInterval(pingInterval);
3503
2862
  unsubscribe?.();
@@ -3615,17 +2974,17 @@ import { Hono as Hono12 } from "hono";
3615
2974
 
3616
2975
  // packages/daemon/src/lib/mind/identity.ts
3617
2976
  import { createHash, generateKeyPairSync, sign, verify } from "crypto";
3618
- import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
3619
- import { resolve as resolve7 } from "path";
2977
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
2978
+ import { resolve as resolve6 } from "path";
3620
2979
  function generateIdentity(mindDir2) {
3621
- const identityDir = resolve7(mindDir2, ".mind/identity");
2980
+ const identityDir = resolve6(mindDir2, ".mind/identity");
3622
2981
  mkdirSync4(identityDir, { recursive: true });
3623
2982
  const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
3624
2983
  publicKeyEncoding: { type: "spki", format: "pem" },
3625
2984
  privateKeyEncoding: { type: "pkcs8", format: "pem" }
3626
2985
  });
3627
- const privatePath = resolve7(identityDir, "private.pem");
3628
- const publicPath = resolve7(identityDir, "public.pem");
2986
+ const privatePath = resolve6(identityDir, "private.pem");
2987
+ const publicPath = resolve6(identityDir, "public.pem");
3629
2988
  writeFileSync4(privatePath, privateKey, { mode: 384 });
3630
2989
  writeFileSync4(publicPath, publicKey, { mode: 420 });
3631
2990
  const config2 = readVoluteConfig(mindDir2) ?? {};
@@ -3640,9 +2999,9 @@ function getPublicKey(mindDir2) {
3640
2999
  const config2 = readVoluteConfig(mindDir2);
3641
3000
  const relPath = config2?.identity?.publicKey;
3642
3001
  if (!relPath) return null;
3643
- const fullPath = resolve7(mindDir2, relPath);
3644
- if (!existsSync5(fullPath)) return null;
3645
- return readFileSync6(fullPath, "utf-8");
3002
+ const fullPath = resolve6(mindDir2, relPath);
3003
+ if (!existsSync4(fullPath)) return null;
3004
+ return readFileSync5(fullPath, "utf-8");
3646
3005
  }
3647
3006
  function getFingerprint(publicKeyPem) {
3648
3007
  return createHash("sha256").update(publicKeyPem).digest("hex");
@@ -3689,16 +3048,16 @@ var keys_default = app10;
3689
3048
 
3690
3049
  // packages/daemon/src/web/api/logs.ts
3691
3050
  import { spawn as spawn2 } from "child_process";
3692
- import { existsSync as existsSync6 } from "fs";
3693
- import { resolve as resolve8 } from "path";
3051
+ import { existsSync as existsSync5 } from "fs";
3052
+ import { resolve as resolve7 } from "path";
3694
3053
  import { Hono as Hono13 } from "hono";
3695
3054
  import { streamSSE as streamSSE3 } from "hono/streaming";
3696
3055
  var app11 = new Hono13().get("/:name/logs", async (c) => {
3697
3056
  const name = c.req.param("name");
3698
3057
  const entry = await findMind(name);
3699
3058
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3700
- const logFile = resolve8(stateDir(name), "logs", "mind.log");
3701
- if (!existsSync6(logFile)) {
3059
+ const logFile = resolve7(stateDir(name), "logs", "mind.log");
3060
+ if (!existsSync5(logFile)) {
3702
3061
  return c.json({ error: "No log file found" }, 404);
3703
3062
  }
3704
3063
  return streamSSE3(c, async (stream) => {
@@ -3716,17 +3075,17 @@ var app11 = new Hono13().get("/:name/logs", async (c) => {
3716
3075
  stream.onAbort(() => {
3717
3076
  tail.kill();
3718
3077
  });
3719
- await new Promise((resolve18) => {
3720
- tail.on("exit", resolve18);
3721
- stream.onAbort(resolve18);
3078
+ await new Promise((resolve17) => {
3079
+ tail.on("exit", resolve17);
3080
+ stream.onAbort(resolve17);
3722
3081
  });
3723
3082
  });
3724
3083
  }).get("/:name/logs/tail", async (c) => {
3725
3084
  const name = c.req.param("name");
3726
3085
  const entry = await findMind(name);
3727
3086
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3728
- const logFile = resolve8(stateDir(name), "logs", "mind.log");
3729
- if (!existsSync6(logFile)) {
3087
+ const logFile = resolve7(stateDir(name), "logs", "mind.log");
3088
+ if (!existsSync5(logFile)) {
3730
3089
  return c.json({ error: "No log file found" }, 404);
3731
3090
  }
3732
3091
  const nParam = parseInt(c.req.query("n") ?? "50", 10);
@@ -3736,8 +3095,8 @@ var app11 = new Hono13().get("/:name/logs", async (c) => {
3736
3095
  tail.stdout.on("data", (data) => {
3737
3096
  output += data.toString();
3738
3097
  });
3739
- await new Promise((resolve18) => {
3740
- tail.on("exit", resolve18);
3098
+ await new Promise((resolve17) => {
3099
+ tail.on("exit", resolve17);
3741
3100
  });
3742
3101
  return c.text(output);
3743
3102
  });
@@ -3827,33 +3186,33 @@ var mind_skills_default = app12;
3827
3186
  // packages/daemon/src/web/api/minds.ts
3828
3187
  import {
3829
3188
  cpSync,
3830
- existsSync as existsSync8,
3189
+ existsSync as existsSync7,
3831
3190
  mkdirSync as mkdirSync6,
3832
3191
  readdirSync as readdirSync2,
3833
- readFileSync as readFileSync9,
3192
+ readFileSync as readFileSync8,
3834
3193
  rmSync as rmSync4,
3835
3194
  writeFileSync as writeFileSync7
3836
3195
  } from "fs";
3837
- import { resolve as resolve11 } from "path";
3196
+ import { resolve as resolve10 } from "path";
3838
3197
  import { zValidator as zValidator5 } from "@hono/zod-validator";
3839
3198
  import { and as and4, desc as desc3, eq as eq5, sql as sql2 } from "drizzle-orm";
3840
3199
  import { Hono as Hono15 } from "hono";
3841
3200
  import { z as z5 } from "zod";
3842
3201
 
3843
3202
  // packages/daemon/src/lib/mind/consolidate.ts
3844
- import { readdirSync, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
3845
- import { resolve as resolve9 } from "path";
3203
+ import { readdirSync, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
3204
+ import { resolve as resolve8 } from "path";
3846
3205
  async function consolidateMemory(mindDir2) {
3847
- const soulPath = resolve9(mindDir2, "home/SOUL.md");
3848
- const memoryPath = resolve9(mindDir2, "home/MEMORY.md");
3849
- const memoryDir = resolve9(mindDir2, "home/memory");
3850
- const soul = readFileSync7(soulPath, "utf-8");
3206
+ const soulPath = resolve8(mindDir2, "home/SOUL.md");
3207
+ const memoryPath = resolve8(mindDir2, "home/MEMORY.md");
3208
+ const memoryDir = resolve8(mindDir2, "home/memory");
3209
+ const soul = readFileSync6(soulPath, "utf-8");
3851
3210
  const logs = [];
3852
3211
  try {
3853
3212
  const files = readdirSync(memoryDir).filter((f) => /^\d{4}-\d{2}-\d{2}\.md$/.test(f)).sort();
3854
3213
  for (const filename of files) {
3855
3214
  const date = filename.replace(".md", "");
3856
- const content2 = readFileSync7(resolve9(memoryDir, filename), "utf-8").trim();
3215
+ const content2 = readFileSync6(resolve8(memoryDir, filename), "utf-8").trim();
3857
3216
  if (content2) {
3858
3217
  logs.push(`### ${date}
3859
3218
 
@@ -3912,7 +3271,7 @@ ${content2}`);
3912
3271
  }
3913
3272
 
3914
3273
  // packages/daemon/src/lib/mind/variant-cleanup.ts
3915
- import { existsSync as existsSync7, rmSync as rmSync3 } from "fs";
3274
+ import { existsSync as existsSync6, rmSync as rmSync3 } from "fs";
3916
3275
  async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
3917
3276
  if (opts?.stop) {
3918
3277
  try {
@@ -3921,10 +3280,10 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
3921
3280
  logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
3922
3281
  }
3923
3282
  }
3924
- const { findMind: findMind2 } = await import("./registry-YPHK534W.js");
3283
+ const { findMind: findMind2 } = await import("./registry-KMELPC3X.js");
3925
3284
  const variantEntry = await findMind2(variantName);
3926
3285
  const branchName = variantEntry?.branch ?? variantName;
3927
- if (existsSync7(variantPath)) {
3286
+ if (existsSync6(variantPath)) {
3928
3287
  try {
3929
3288
  await gitExec(["worktree", "remove", "--force", variantPath], { cwd: projectRoot });
3930
3289
  } catch {
@@ -3971,11 +3330,11 @@ function validateBranchName(branch) {
3971
3330
 
3972
3331
  // packages/daemon/src/lib/template/convert-session.ts
3973
3332
  import { randomUUID } from "crypto";
3974
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
3333
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
3975
3334
  import { homedir } from "os";
3976
- import { resolve as resolve10 } from "path";
3335
+ import { resolve as resolve9 } from "path";
3977
3336
  function convertSession(opts) {
3978
- const lines = readFileSync8(opts.sessionPath, "utf-8").trim().split("\n");
3337
+ const lines = readFileSync7(opts.sessionPath, "utf-8").trim().split("\n");
3979
3338
  const sessionId = randomUUID();
3980
3339
  const idMap = /* @__PURE__ */ new Map();
3981
3340
  const messages = [];
@@ -4089,9 +3448,9 @@ function convertSession(opts) {
4089
3448
  }
4090
3449
  }
4091
3450
  const projectId = opts.projectDir.replace(/\//g, "-");
4092
- const sdkDir = resolve10(homedir(), ".claude", "projects", projectId);
3451
+ const sdkDir = resolve9(homedir(), ".claude", "projects", projectId);
4093
3452
  mkdirSync5(sdkDir, { recursive: true });
4094
- const sdkPath = resolve10(sdkDir, `${sessionId}.jsonl`);
3453
+ const sdkPath = resolve9(sdkDir, `${sessionId}.jsonl`);
4095
3454
  writeFileSync6(sdkPath, `${sdkEvents.join("\n")}
4096
3455
  `);
4097
3456
  console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
@@ -4165,7 +3524,7 @@ async function getMindStatus(name, port, registryRunning) {
4165
3524
  const manager = getMindManager();
4166
3525
  let status = "stopped";
4167
3526
  try {
4168
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-WAZWMFJT.js");
3527
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-PBOIEBJZ.js");
4169
3528
  if (getSleepManagerIfReady2()?.isSleeping(name)) {
4170
3529
  status = "sleeping";
4171
3530
  }
@@ -4211,7 +3570,7 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
4211
3570
  await gitExec(["commit", "-m", "initial commit"], opts);
4212
3571
  }
4213
3572
  async function updateTemplateBranch(projectRoot, template, mindName) {
4214
- const tempWorktree = resolve11(projectRoot, ".variants", "_template_update");
3573
+ const tempWorktree = resolve10(projectRoot, ".variants", "_template_update");
4215
3574
  let branchExists = false;
4216
3575
  try {
4217
3576
  await gitExec(["rev-parse", "--verify", TEMPLATE_BRANCH], { cwd: projectRoot });
@@ -4222,7 +3581,7 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
4222
3581
  await gitExec(["worktree", "remove", "--force", tempWorktree], { cwd: projectRoot });
4223
3582
  } catch {
4224
3583
  }
4225
- if (existsSync8(tempWorktree)) {
3584
+ if (existsSync7(tempWorktree)) {
4226
3585
  rmSync4(tempWorktree, { recursive: true, force: true });
4227
3586
  }
4228
3587
  const templatesRoot = findTemplatesRoot();
@@ -4243,15 +3602,15 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
4243
3602
  });
4244
3603
  }
4245
3604
  copyTemplateToDir(composedDir, tempWorktree, mindName, manifest);
4246
- const initDir = resolve11(tempWorktree, ".init");
4247
- if (existsSync8(initDir)) {
3605
+ const initDir = resolve10(tempWorktree, ".init");
3606
+ if (existsSync7(initDir)) {
4248
3607
  rmSync4(initDir, { recursive: true, force: true });
4249
3608
  }
4250
- const homeDir = resolve11(tempWorktree, "home");
4251
- if (existsSync8(homeDir)) {
3609
+ const homeDir = resolve10(tempWorktree, "home");
3610
+ if (existsSync7(homeDir)) {
4252
3611
  for (const entry of readdirSync2(homeDir)) {
4253
3612
  if (entry !== "VOLUTE.md") {
4254
- rmSync4(resolve11(homeDir, entry), { recursive: true, force: true });
3613
+ rmSync4(resolve10(homeDir, entry), { recursive: true, force: true });
4255
3614
  }
4256
3615
  }
4257
3616
  }
@@ -4266,7 +3625,7 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
4266
3625
  await gitExec(["worktree", "remove", "--force", tempWorktree], { cwd: projectRoot });
4267
3626
  } catch {
4268
3627
  }
4269
- if (existsSync8(tempWorktree)) {
3628
+ if (existsSync7(tempWorktree)) {
4270
3629
  rmSync4(tempWorktree, { recursive: true, force: true });
4271
3630
  }
4272
3631
  rmSync4(composedDir, { recursive: true, force: true });
@@ -4292,7 +3651,7 @@ async function mergeTemplateBranch(worktreeDir) {
4292
3651
  async function npmInstallAsMind(cwd, mindName) {
4293
3652
  if (isIsolationEnabled()) {
4294
3653
  const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
4295
- await exec(cmd, args, { cwd, env: { ...process.env, HOME: resolve11(cwd, "home") } });
3654
+ await exec(cmd, args, { cwd, env: { ...process.env, HOME: resolve10(cwd, "home") } });
4296
3655
  } else {
4297
3656
  await exec("npm", ["install"], { cwd });
4298
3657
  }
@@ -4343,8 +3702,8 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
4343
3702
  return { ok: true };
4344
3703
  }
4345
3704
  async function importFromArchive(c, tempDir, nameOverride, manifest) {
4346
- const extractedMindDir = resolve11(tempDir, "mind");
4347
- if (!existsSync8(extractedMindDir)) {
3705
+ const extractedMindDir = resolve10(tempDir, "mind");
3706
+ if (!existsSync7(extractedMindDir)) {
4348
3707
  return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
4349
3708
  }
4350
3709
  if (!manifest?.includes || !manifest.name || !manifest.template) {
@@ -4362,7 +3721,7 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
4362
3721
  if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
4363
3722
  ensureVoluteHome();
4364
3723
  const dest = mindDir(name);
4365
- if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
3724
+ if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
4366
3725
  try {
4367
3726
  cpSync(extractedMindDir, dest, { recursive: true });
4368
3727
  if (!manifest.includes.identity) {
@@ -4370,9 +3729,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
4370
3729
  }
4371
3730
  const state = stateDir(name);
4372
3731
  mkdirSync6(state, { recursive: true });
4373
- const envJson = resolve11(tempDir, "state/env.json");
4374
- if (existsSync8(envJson)) {
4375
- cpSync(envJson, resolve11(state, "env.json"));
3732
+ const envJson = resolve10(tempDir, "state/env.json");
3733
+ if (existsSync7(envJson)) {
3734
+ cpSync(envJson, resolve10(state, "env.json"));
4376
3735
  }
4377
3736
  const port = await nextPort();
4378
3737
  await addMind(name, port, manifest.stage, manifest.template);
@@ -4381,30 +3740,30 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
4381
3740
  } catch (err) {
4382
3741
  logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
4383
3742
  }
4384
- const homeDir = resolve11(dest, "home");
3743
+ const homeDir = resolve10(dest, "home");
4385
3744
  ensureVoluteGroup();
4386
3745
  createMindUser(name, homeDir);
4387
3746
  chownMindDir(dest, name);
4388
3747
  await npmInstallAsMind(dest, name);
4389
3748
  await importHistoryFromArchive(name, tempDir);
4390
3749
  importSessionsFromArchive(dest, tempDir);
4391
- if (!existsSync8(resolve11(dest, ".git"))) {
3750
+ if (!existsSync7(resolve10(dest, ".git"))) {
4392
3751
  try {
4393
- const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
3752
+ const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dest, "home") } : void 0;
4394
3753
  await gitExec(["init"], { cwd: dest, mindName: name, env });
4395
3754
  await configureGitIdentity(name, { cwd: dest, mindName: name, env });
4396
3755
  await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
4397
3756
  await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
4398
3757
  } catch (err) {
4399
3758
  logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
4400
- rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
3759
+ rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
4401
3760
  }
4402
3761
  }
4403
3762
  chownMindDir(dest, name);
4404
3763
  rmSync4(tempDir, { recursive: true, force: true });
4405
3764
  return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
4406
3765
  } catch (err) {
4407
- if (existsSync8(dest)) rmSync4(dest, { recursive: true, force: true });
3766
+ if (existsSync7(dest)) rmSync4(dest, { recursive: true, force: true });
4408
3767
  try {
4409
3768
  await removeMind(name);
4410
3769
  } catch (cleanupErr) {
@@ -4421,7 +3780,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4421
3780
  if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
4422
3781
  ensureVoluteHome();
4423
3782
  const dest = mindDir(name);
4424
- if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
3783
+ if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
4425
3784
  const templatesRoot = findTemplatesRoot();
4426
3785
  const { composedDir, manifest: templateManifest } = composeTemplate(
4427
3786
  templatesRoot,
@@ -4430,36 +3789,36 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4430
3789
  try {
4431
3790
  copyTemplateToDir(composedDir, dest, name, templateManifest);
4432
3791
  applyInitFiles(dest);
4433
- const extractedHome = resolve11(extractedMindDir, "home");
4434
- if (existsSync8(extractedHome)) {
4435
- cpSync(extractedHome, resolve11(dest, "home"), { recursive: true });
3792
+ const extractedHome = resolve10(extractedMindDir, "home");
3793
+ if (existsSync7(extractedHome)) {
3794
+ cpSync(extractedHome, resolve10(dest, "home"), { recursive: true });
4436
3795
  }
4437
- const extractedMindInternal = resolve11(extractedMindDir, ".mind");
4438
- if (existsSync8(extractedMindInternal)) {
4439
- cpSync(extractedMindInternal, resolve11(dest, ".mind"), { recursive: true });
3796
+ const extractedMindInternal = resolve10(extractedMindDir, ".mind");
3797
+ if (existsSync7(extractedMindInternal)) {
3798
+ cpSync(extractedMindInternal, resolve10(dest, ".mind"), { recursive: true });
4440
3799
  }
4441
- const identityDir = resolve11(dest, ".mind/identity");
3800
+ const identityDir = resolve10(dest, ".mind/identity");
4442
3801
  let publicKeyPem;
4443
- if (!manifest.includes.identity || !existsSync8(resolve11(identityDir, "private.pem"))) {
3802
+ if (!manifest.includes.identity || !existsSync7(resolve10(identityDir, "private.pem"))) {
4444
3803
  ({ publicKeyPem } = generateIdentity(dest));
4445
3804
  } else {
4446
- publicKeyPem = readFileSync9(resolve11(identityDir, "public.pem"), "utf-8");
3805
+ publicKeyPem = readFileSync8(resolve10(identityDir, "public.pem"), "utf-8");
4447
3806
  }
4448
- const promptsPath = resolve11(dest, "home/.config/prompts.json");
4449
- if (!existsSync8(promptsPath)) {
3807
+ const promptsPath = resolve10(dest, "home/.config/prompts.json");
3808
+ if (!existsSync7(promptsPath)) {
4450
3809
  const mindPrompts = await getMindPromptDefaults();
4451
3810
  writeFileSync7(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
4452
3811
  `);
4453
3812
  }
4454
3813
  const state = stateDir(name);
4455
3814
  mkdirSync6(state, { recursive: true });
4456
- const envJson = resolve11(tempDir, "state/env.json");
4457
- if (existsSync8(envJson)) {
4458
- cpSync(envJson, resolve11(state, "env.json"));
3815
+ const envJson = resolve10(tempDir, "state/env.json");
3816
+ if (existsSync7(envJson)) {
3817
+ cpSync(envJson, resolve10(state, "env.json"));
4459
3818
  }
4460
3819
  const port = await nextPort();
4461
3820
  await addMind(name, port, manifest.stage, manifest.template);
4462
- const homeDir = resolve11(dest, "home");
3821
+ const homeDir = resolve10(dest, "home");
4463
3822
  ensureVoluteGroup();
4464
3823
  createMindUser(name, homeDir);
4465
3824
  chownMindDir(dest, name);
@@ -4472,7 +3831,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4472
3831
  await initTemplateBranch(dest, composedDir, templateManifest, name, env);
4473
3832
  } catch (err) {
4474
3833
  logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
4475
- rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
3834
+ rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
4476
3835
  gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
4477
3836
  }
4478
3837
  const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
@@ -4502,7 +3861,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4502
3861
  ...skillWarnings.length > 0 && { skillWarnings }
4503
3862
  });
4504
3863
  } catch (err) {
4505
- if (existsSync8(dest)) rmSync4(dest, { recursive: true, force: true });
3864
+ if (existsSync7(dest)) rmSync4(dest, { recursive: true, force: true });
4506
3865
  try {
4507
3866
  await removeMind(name);
4508
3867
  } catch (cleanupErr) {
@@ -4515,11 +3874,11 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4515
3874
  }
4516
3875
  }
4517
3876
  async function importHistoryFromArchive(name, tempDir) {
4518
- const historyJsonl = resolve11(tempDir, "history.jsonl");
4519
- if (!existsSync8(historyJsonl)) return;
3877
+ const historyJsonl = resolve10(tempDir, "history.jsonl");
3878
+ if (!existsSync7(historyJsonl)) return;
4520
3879
  try {
4521
3880
  const db = await getDb();
4522
- const lines = readFileSync9(historyJsonl, "utf-8").trim().split("\n");
3881
+ const lines = readFileSync8(historyJsonl, "utf-8").trim().split("\n");
4523
3882
  let imported = 0;
4524
3883
  let failed = 0;
4525
3884
  for (const line of lines) {
@@ -4555,13 +3914,13 @@ async function importHistoryFromArchive(name, tempDir) {
4555
3914
  }
4556
3915
  }
4557
3916
  function importSessionsFromArchive(dest, tempDir) {
4558
- const sessionsDir = resolve11(tempDir, "sessions");
4559
- if (!existsSync8(sessionsDir)) return;
3917
+ const sessionsDir = resolve10(tempDir, "sessions");
3918
+ if (!existsSync7(sessionsDir)) return;
4560
3919
  try {
4561
- const destSessions = resolve11(dest, ".mind/sessions");
3920
+ const destSessions = resolve10(dest, ".mind/sessions");
4562
3921
  mkdirSync6(destSessions, { recursive: true });
4563
3922
  for (const file of readdirSync2(sessionsDir)) {
4564
- cpSync(resolve11(sessionsDir, file), resolve11(destSessions, file));
3923
+ cpSync(resolve10(sessionsDir, file), resolve10(destSessions, file));
4565
3924
  }
4566
3925
  } catch (err) {
4567
3926
  logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
@@ -4596,7 +3955,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4596
3955
  if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
4597
3956
  ensureVoluteHome();
4598
3957
  const dest = mindDir(name);
4599
- if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
3958
+ if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
4600
3959
  const templatesRoot = findTemplatesRoot();
4601
3960
  const { composedDir, manifest } = composeTemplate(templatesRoot, template);
4602
3961
  try {
@@ -4604,7 +3963,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4604
3963
  applyInitFiles(dest);
4605
3964
  const { publicKeyPem } = generateIdentity(dest);
4606
3965
  {
4607
- const { readGlobalConfig: readGlobal } = await import("./setup-PMJHCZQX.js");
3966
+ const { readGlobalConfig: readGlobal } = await import("./setup-PF7JSFMO.js");
4608
3967
  const mindDefaults = readGlobal().mindDefaults;
4609
3968
  const config2 = readVoluteConfig(dest);
4610
3969
  if (!config2) throw new Error("Failed to read volute.json after identity generation");
@@ -4641,9 +4000,9 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4641
4000
  }
4642
4001
  writeVoluteConfig(dest, config2);
4643
4002
  const modelId = body.model ?? cog?.model;
4644
- const sdkConfigPath = resolve11(dest, "home/.config/config.json");
4003
+ const sdkConfigPath = resolve10(dest, "home/.config/config.json");
4645
4004
  if (modelId || cog?.compaction) {
4646
- const existing = existsSync8(sdkConfigPath) ? JSON.parse(readFileSync9(sdkConfigPath, "utf-8")) : {};
4005
+ const existing = existsSync7(sdkConfigPath) ? JSON.parse(readFileSync8(sdkConfigPath, "utf-8")) : {};
4647
4006
  if (modelId) {
4648
4007
  existing.model = template === "pi" ? qualifyModelId(modelId) : unqualifyModelId(modelId);
4649
4008
  }
@@ -4656,7 +4015,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4656
4015
  }
4657
4016
  const mindPrompts = await getMindPromptDefaults();
4658
4017
  writeFileSync7(
4659
- resolve11(dest, "home/.config/prompts.json"),
4018
+ resolve10(dest, "home/.config/prompts.json"),
4660
4019
  `${JSON.stringify(mindPrompts, null, 2)}
4661
4020
  `
4662
4021
  );
@@ -4668,7 +4027,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4668
4027
  } catch (err) {
4669
4028
  logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
4670
4029
  }
4671
- const homeDir = resolve11(dest, "home");
4030
+ const homeDir = resolve10(dest, "home");
4672
4031
  ensureVoluteGroup();
4673
4032
  createMindUser(name, homeDir);
4674
4033
  chownMindDir(dest, name);
@@ -4681,7 +4040,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4681
4040
  await initTemplateBranch(dest, composedDir, manifest, name, env);
4682
4041
  } catch (err) {
4683
4042
  logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
4684
- rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
4043
+ rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
4685
4044
  gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
4686
4045
  }
4687
4046
  chownMindDir(dest, name);
@@ -4691,11 +4050,11 @@ The human who planted you described you as: "${body.description}"
4691
4050
  ` : "";
4692
4051
  const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
4693
4052
  const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
4694
- writeFileSync7(resolve11(dest, "home/SOUL.md"), seedSoul);
4053
+ writeFileSync7(resolve10(dest, "home/SOUL.md"), seedSoul);
4695
4054
  }
4696
4055
  let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
4697
4056
  if (body.stage === "seed" && !body.skills) {
4698
- const { isImagegenEnabled } = await import("./setup-PMJHCZQX.js");
4057
+ const { isImagegenEnabled } = await import("./setup-PF7JSFMO.js");
4699
4058
  if (isImagegenEnabled()) {
4700
4059
  skillSet = [...skillSet, "imagegen"];
4701
4060
  }
@@ -4713,7 +4072,7 @@ The human who planted you described you as: "${body.description}"
4713
4072
  try {
4714
4073
  const spiritEntry = await findMind("volute");
4715
4074
  if (spiritEntry) {
4716
- const { spiritDir } = await import("./spirit-6KVDIROQ.js");
4075
+ const { spiritDir } = await import("./spirit-4QOYM33G.js");
4717
4076
  const sDir = spiritEntry.dir ?? spiritDir();
4718
4077
  const spiritConfig = readVoluteConfig(sDir) ?? {};
4719
4078
  const schedules = spiritConfig.schedules ?? [];
@@ -4728,7 +4087,7 @@ The human who planted you described you as: "${body.description}"
4728
4087
  });
4729
4088
  spiritConfig.schedules = schedules;
4730
4089
  writeVoluteConfig(sDir, spiritConfig);
4731
- const { getScheduler: getScheduler2 } = await import("./scheduler-FRJ5DK24.js");
4090
+ const { getScheduler: getScheduler2 } = await import("./scheduler-355E746X.js");
4732
4091
  getScheduler2().loadSchedules("volute", sDir);
4733
4092
  }
4734
4093
  }
@@ -4739,11 +4098,11 @@ The human who planted you described you as: "${body.description}"
4739
4098
  if (body.stage !== "seed") {
4740
4099
  const customSoul = await getPromptIfCustom("default_soul");
4741
4100
  if (customSoul) {
4742
- writeFileSync7(resolve11(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
4101
+ writeFileSync7(resolve10(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
4743
4102
  }
4744
4103
  const customMemory = await getPromptIfCustom("default_memory");
4745
4104
  if (customMemory) {
4746
- writeFileSync7(resolve11(dest, "home/MEMORY.md"), customMemory);
4105
+ writeFileSync7(resolve10(dest, "home/MEMORY.md"), customMemory);
4747
4106
  }
4748
4107
  }
4749
4108
  publishPublicKey(name, publicKeyPem).catch(
@@ -4772,7 +4131,7 @@ The human who planted you described you as: "${body.description}"
4772
4131
  ...skillWarnings.length > 0 && { skillWarnings }
4773
4132
  });
4774
4133
  } catch (err) {
4775
- if (existsSync8(dest)) rmSync4(dest, { recursive: true, force: true });
4134
+ if (existsSync7(dest)) rmSync4(dest, { recursive: true, force: true });
4776
4135
  try {
4777
4136
  await removeMind(name);
4778
4137
  } catch {
@@ -4792,13 +4151,13 @@ The human who planted you described you as: "${body.description}"
4792
4151
  return importFromArchive(c, body.archivePath, body.name, body.manifest);
4793
4152
  }
4794
4153
  const wsDir = body.workspacePath;
4795
- if (!wsDir || !existsSync8(resolve11(wsDir, "SOUL.md")) || !existsSync8(resolve11(wsDir, "IDENTITY.md"))) {
4154
+ if (!wsDir || !existsSync7(resolve10(wsDir, "SOUL.md")) || !existsSync7(resolve10(wsDir, "IDENTITY.md"))) {
4796
4155
  return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
4797
4156
  }
4798
- const soul = readFileSync9(resolve11(wsDir, "SOUL.md"), "utf-8");
4799
- const identity = readFileSync9(resolve11(wsDir, "IDENTITY.md"), "utf-8");
4800
- const userPath = resolve11(wsDir, "USER.md");
4801
- const user = existsSync8(userPath) ? readFileSync9(userPath, "utf-8") : "";
4157
+ const soul = readFileSync8(resolve10(wsDir, "SOUL.md"), "utf-8");
4158
+ const identity = readFileSync8(resolve10(wsDir, "IDENTITY.md"), "utf-8");
4159
+ const userPath = resolve10(wsDir, "USER.md");
4160
+ const user = existsSync7(userPath) ? readFileSync8(userPath, "utf-8") : "";
4802
4161
  const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
4803
4162
  const template = body.template ?? "claude";
4804
4163
  const nameErr = validateMindName(name);
@@ -4818,33 +4177,33 @@ ${user.trimEnd()}
4818
4177
  ` : "";
4819
4178
  ensureVoluteHome();
4820
4179
  const dest = mindDir(name);
4821
- if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
4180
+ if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
4822
4181
  const templatesRoot = findTemplatesRoot();
4823
4182
  const { composedDir, manifest } = composeTemplate(templatesRoot, template);
4824
4183
  try {
4825
4184
  copyTemplateToDir(composedDir, dest, name, manifest);
4826
4185
  applyInitFiles(dest);
4827
4186
  const { publicKeyPem: importPublicKey } = generateIdentity(dest);
4828
- writeFileSync7(resolve11(dest, "home/SOUL.md"), mergedSoul);
4829
- const wsMemoryPath = resolve11(wsDir, "MEMORY.md");
4830
- const hasMemory = existsSync8(wsMemoryPath);
4187
+ writeFileSync7(resolve10(dest, "home/SOUL.md"), mergedSoul);
4188
+ const wsMemoryPath = resolve10(wsDir, "MEMORY.md");
4189
+ const hasMemory = existsSync7(wsMemoryPath);
4831
4190
  if (hasMemory) {
4832
- const existingMemory = readFileSync9(wsMemoryPath, "utf-8");
4191
+ const existingMemory = readFileSync8(wsMemoryPath, "utf-8");
4833
4192
  writeFileSync7(
4834
- resolve11(dest, "home/MEMORY.md"),
4193
+ resolve10(dest, "home/MEMORY.md"),
4835
4194
  `${existingMemory.trimEnd()}${mergedMemoryExtra}`
4836
4195
  );
4837
4196
  } else if (user) {
4838
- writeFileSync7(resolve11(dest, "home/MEMORY.md"), `${user.trimEnd()}
4197
+ writeFileSync7(resolve10(dest, "home/MEMORY.md"), `${user.trimEnd()}
4839
4198
  `);
4840
4199
  }
4841
- const wsMemoryDir = resolve11(wsDir, "memory");
4200
+ const wsMemoryDir = resolve10(wsDir, "memory");
4842
4201
  let dailyLogCount = 0;
4843
- if (existsSync8(wsMemoryDir)) {
4844
- const destMemoryDir = resolve11(dest, "home/memory");
4202
+ if (existsSync7(wsMemoryDir)) {
4203
+ const destMemoryDir = resolve10(dest, "home/memory");
4845
4204
  const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
4846
4205
  for (const file of files) {
4847
- cpSync(resolve11(wsMemoryDir, file), resolve11(destMemoryDir, file));
4206
+ cpSync(resolve10(wsMemoryDir, file), resolve10(destMemoryDir, file));
4848
4207
  }
4849
4208
  dailyLogCount = files.length;
4850
4209
  }
@@ -4855,7 +4214,7 @@ ${user.trimEnd()}
4855
4214
  } catch (err) {
4856
4215
  logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
4857
4216
  }
4858
- const homeDir = resolve11(dest, "home");
4217
+ const homeDir = resolve10(dest, "home");
4859
4218
  ensureVoluteGroup();
4860
4219
  createMindUser(name, homeDir);
4861
4220
  chownMindDir(dest, name);
@@ -4863,20 +4222,20 @@ ${user.trimEnd()}
4863
4222
  if (!hasMemory && dailyLogCount > 0) {
4864
4223
  await consolidateMemory(dest);
4865
4224
  }
4866
- const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
4225
+ const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dest, "home") } : void 0;
4867
4226
  await gitExec(["init"], { cwd: dest, mindName: name, env });
4868
4227
  await configureGitIdentity(name, { cwd: dest, mindName: name, env });
4869
4228
  await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
4870
4229
  await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
4871
- const sessionFile = body.sessionPath ? resolve11(body.sessionPath) : findOpenClawSession(wsDir);
4872
- if (sessionFile && existsSync8(sessionFile)) {
4230
+ const sessionFile = body.sessionPath ? resolve10(body.sessionPath) : findOpenClawSession(wsDir);
4231
+ if (sessionFile && existsSync7(sessionFile)) {
4873
4232
  if (template === "pi") {
4874
4233
  importPiSession(sessionFile, dest);
4875
4234
  } else if (template === "claude") {
4876
4235
  const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
4877
- const mindRuntimeDir = resolve11(dest, ".mind");
4236
+ const mindRuntimeDir = resolve10(dest, ".mind");
4878
4237
  mkdirSync6(mindRuntimeDir, { recursive: true });
4879
- writeFileSync7(resolve11(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
4238
+ writeFileSync7(resolve10(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
4880
4239
  }
4881
4240
  }
4882
4241
  importOpenClawConnectors(name, dest);
@@ -4886,7 +4245,7 @@ ${user.trimEnd()}
4886
4245
  );
4887
4246
  return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
4888
4247
  } catch (err) {
4889
- if (existsSync8(dest)) rmSync4(dest, { recursive: true, force: true });
4248
+ if (existsSync7(dest)) rmSync4(dest, { recursive: true, force: true });
4890
4249
  try {
4891
4250
  await removeMind(name);
4892
4251
  } catch {
@@ -4917,7 +4276,7 @@ ${user.trimEnd()}
4917
4276
  const minds = await Promise.all(
4918
4277
  entries.map(async (entry) => {
4919
4278
  const mindStatus = await getMindStatus(entry.name, entry.port, entry.running);
4920
- const hasPages = existsSync8(resolve11(mindDir(entry.name), "home", "pages"));
4279
+ const hasPages = existsSync7(resolve10(mindDir(entry.name), "home", "pages"));
4921
4280
  return {
4922
4281
  ...entry,
4923
4282
  ...mindStatus,
@@ -4932,7 +4291,7 @@ ${user.trimEnd()}
4932
4291
  const entry = await findMind(name);
4933
4292
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4934
4293
  const dir = entry.dir ?? mindDir(entry.parent ?? name);
4935
- if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
4294
+ if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
4936
4295
  const mindStatus = await getMindStatus(name, entry.port);
4937
4296
  const variants = await findVariants(name);
4938
4297
  const manager = getMindManager();
@@ -4946,7 +4305,7 @@ ${user.trimEnd()}
4946
4305
  return { name: s.name, port: s.port, status: variantStatus };
4947
4306
  })
4948
4307
  );
4949
- const hasPages = existsSync8(resolve11(mindDir(name), "home", "pages"));
4308
+ const hasPages = existsSync7(resolve10(mindDir(name), "home", "pages"));
4950
4309
  return c.json({ ...entry, ...mindStatus, variants: variantStatuses, hasPages });
4951
4310
  }).get("/:name/context", async (c) => {
4952
4311
  const name = c.req.param("name");
@@ -4983,7 +4342,7 @@ ${user.trimEnd()}
4983
4342
  if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
4984
4343
  } else {
4985
4344
  const dir = mindDir(name);
4986
- if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
4345
+ if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
4987
4346
  }
4988
4347
  if (getMindManager().isRunning(name)) {
4989
4348
  return c.json({ error: "Mind already running" }, 409);
@@ -5004,7 +4363,7 @@ ${user.trimEnd()}
5004
4363
  if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
5005
4364
  } else {
5006
4365
  const dir = mindDir(name);
5007
- if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
4366
+ if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
5008
4367
  }
5009
4368
  let context;
5010
4369
  const contentType = c.req.header("content-type");
@@ -5019,7 +4378,7 @@ ${user.trimEnd()}
5019
4378
  const manager = getMindManager();
5020
4379
  try {
5021
4380
  if (context?.type === "reload") {
5022
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-WAZWMFJT.js");
4381
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-PBOIEBJZ.js");
5023
4382
  const sleepState = getSleepManagerIfReady2()?.getState(name);
5024
4383
  if (sleepState?.sleeping) {
5025
4384
  logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
@@ -5039,7 +4398,7 @@ ${user.trimEnd()}
5039
4398
  const variantEntry = await findMind(mergeVariantName);
5040
4399
  if (variantEntry && variantEntry.parent === baseName && variantEntry.dir && variantEntry.branch) {
5041
4400
  const projectRoot = mindDir(baseName);
5042
- if (existsSync8(variantEntry.dir)) {
4401
+ if (existsSync7(variantEntry.dir)) {
5043
4402
  const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
5044
4403
  if (status) {
5045
4404
  try {
@@ -5114,7 +4473,7 @@ ${user.trimEnd()}
5114
4473
  const name = c.req.param("name");
5115
4474
  const entry = await findMind(name);
5116
4475
  if (!entry) return c.json({ error: "Mind not found" }, 404);
5117
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-WAZWMFJT.js");
4476
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-PBOIEBJZ.js");
5118
4477
  const sm = getSleepManagerIfReady2();
5119
4478
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
5120
4479
  return c.json(sm.getState(name));
@@ -5122,7 +4481,7 @@ ${user.trimEnd()}
5122
4481
  const name = c.req.param("name");
5123
4482
  const entry = await findMind(name);
5124
4483
  if (!entry) return c.json({ error: "Mind not found" }, 404);
5125
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-WAZWMFJT.js");
4484
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-PBOIEBJZ.js");
5126
4485
  const sm = getSleepManagerIfReady2();
5127
4486
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
5128
4487
  if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
@@ -5142,7 +4501,7 @@ ${user.trimEnd()}
5142
4501
  const name = c.req.param("name");
5143
4502
  const entry = await findMind(name);
5144
4503
  if (!entry) return c.json({ error: "Mind not found" }, 404);
5145
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-WAZWMFJT.js");
4504
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-PBOIEBJZ.js");
5146
4505
  const sm = getSleepManagerIfReady2();
5147
4506
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
5148
4507
  const sleepState = sm.getState(name);
@@ -5157,7 +4516,7 @@ ${user.trimEnd()}
5157
4516
  const name = c.req.param("name");
5158
4517
  const entry = await findMind(name);
5159
4518
  if (!entry) return c.json({ error: "Mind not found" }, 404);
5160
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-WAZWMFJT.js");
4519
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-PBOIEBJZ.js");
5161
4520
  const sm = getSleepManagerIfReady2();
5162
4521
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
5163
4522
  const flushed = await sm.flushQueuedMessages(name);
@@ -5175,7 +4534,7 @@ ${user.trimEnd()}
5175
4534
  if (body.avatar !== void 0) profile.avatar = body.avatar;
5176
4535
  config2.profile = profile;
5177
4536
  writeVoluteConfig(dir, config2);
5178
- const { syncMindProfile: syncMindProfile2 } = await import("./auth-YTQME4EV.js");
4537
+ const { syncMindProfile: syncMindProfile2 } = await import("./auth-2QOOPMBX.js");
5179
4538
  await syncMindProfile2(name, profile);
5180
4539
  broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
5181
4540
  return c.json({ ok: true });
@@ -5215,14 +4574,14 @@ ${user.trimEnd()}
5215
4574
  return c.json({ output: "" });
5216
4575
  }
5217
4576
  const dir = entry.dir ?? mindDir(name);
5218
- const soulPath = resolve11(dir, "home/SOUL.md");
5219
- const memoryPath = resolve11(dir, "home/MEMORY.md");
5220
- const soulCustom = existsSync8(soulPath) && !readFileSync9(soulPath, "utf-8").includes(ORIENTATION_MARKER);
5221
- const memoryWritten = existsSync8(memoryPath) && readFileSync9(memoryPath, "utf-8").trim().length > 0;
4577
+ const soulPath = resolve10(dir, "home/SOUL.md");
4578
+ const memoryPath = resolve10(dir, "home/MEMORY.md");
4579
+ const soulCustom = existsSync7(soulPath) && !readFileSync8(soulPath, "utf-8").includes(ORIENTATION_MARKER);
4580
+ const memoryWritten = existsSync7(memoryPath) && readFileSync8(memoryPath, "utf-8").trim().length > 0;
5222
4581
  const config2 = readVoluteConfig(dir);
5223
4582
  const displayNameSet = !!config2?.profile?.displayName;
5224
4583
  const avatarSet = !!config2?.profile?.avatar;
5225
- const { isImagegenEnabled } = await import("./setup-PMJHCZQX.js");
4584
+ const { isImagegenEnabled } = await import("./setup-PF7JSFMO.js");
5226
4585
  const imagegenEnabled = isImagegenEnabled();
5227
4586
  const done = [];
5228
4587
  const remaining = [];
@@ -5260,7 +4619,7 @@ ${user.trimEnd()}
5260
4619
  try {
5261
4620
  const spiritEntry = await findMind("volute");
5262
4621
  if (spiritEntry) {
5263
- const { spiritDir } = await import("./spirit-6KVDIROQ.js");
4622
+ const { spiritDir } = await import("./spirit-4QOYM33G.js");
5264
4623
  const sDir = spiritEntry.dir ?? spiritDir();
5265
4624
  const spiritConfig = readVoluteConfig(sDir);
5266
4625
  if (spiritConfig?.schedules) {
@@ -5268,7 +4627,7 @@ ${user.trimEnd()}
5268
4627
  spiritConfig.schedules = spiritConfig.schedules.filter((s) => s.id !== nurtureId);
5269
4628
  if (spiritConfig.schedules.length === 0) spiritConfig.schedules = void 0;
5270
4629
  writeVoluteConfig(sDir, spiritConfig);
5271
- const { getScheduler: getScheduler2 } = await import("./scheduler-FRJ5DK24.js");
4630
+ const { getScheduler: getScheduler2 } = await import("./scheduler-355E746X.js");
5272
4631
  getScheduler2().loadSchedules("volute", sDir);
5273
4632
  }
5274
4633
  }
@@ -5296,10 +4655,10 @@ ${user.trimEnd()}
5296
4655
  await deleteMindUser2(name);
5297
4656
  invalidateMindUserCache(name);
5298
4657
  const state = stateDir(name);
5299
- if (existsSync8(state)) {
4658
+ if (existsSync7(state)) {
5300
4659
  rmSync4(state, { recursive: true, force: true });
5301
4660
  }
5302
- if (force && existsSync8(dir)) {
4661
+ if (force && existsSync7(dir)) {
5303
4662
  rmSync4(dir, { recursive: true, force: true });
5304
4663
  deleteMindUser(name);
5305
4664
  }
@@ -5314,7 +4673,7 @@ ${user.trimEnd()}
5314
4673
  const entry = await findMind(mindName);
5315
4674
  if (!entry) return c.json({ error: "Mind not found" }, 404);
5316
4675
  const dir = mindDir(mindName);
5317
- if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
4676
+ if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
5318
4677
  let body = {};
5319
4678
  try {
5320
4679
  body = await c.req.json();
@@ -5323,16 +4682,16 @@ ${user.trimEnd()}
5323
4682
  const template = body.template ?? entry.template ?? "claude";
5324
4683
  const UPGRADE_BRANCH = "upgrade";
5325
4684
  const upgradeVariantName = `${mindName}-upgrade`;
5326
- const worktreeDir = resolve11(dir, ".variants", UPGRADE_BRANCH);
4685
+ const worktreeDir = resolve10(dir, ".variants", UPGRADE_BRANCH);
5327
4686
  if (body.abort) {
5328
- if (!existsSync8(worktreeDir)) {
4687
+ if (!existsSync7(worktreeDir)) {
5329
4688
  return c.json({ error: "No upgrade in progress" }, 400);
5330
4689
  }
5331
4690
  try {
5332
4691
  try {
5333
- const gitDirContent = readFileSync9(resolve11(worktreeDir, ".git"), "utf-8").trim();
4692
+ const gitDirContent = readFileSync8(resolve10(worktreeDir, ".git"), "utf-8").trim();
5334
4693
  const gitDir = gitDirContent.replace("gitdir: ", "");
5335
- if (existsSync8(resolve11(gitDir, "MERGE_HEAD"))) {
4694
+ if (existsSync7(resolve10(gitDir, "MERGE_HEAD"))) {
5336
4695
  await gitExec(["merge", "--abort"], { cwd: worktreeDir });
5337
4696
  }
5338
4697
  } catch {
@@ -5351,7 +4710,7 @@ ${user.trimEnd()}
5351
4710
  }
5352
4711
  }
5353
4712
  if (body.continue) {
5354
- if (!existsSync8(worktreeDir)) {
4713
+ if (!existsSync7(worktreeDir)) {
5355
4714
  return c.json({ error: "No upgrade in progress" }, 400);
5356
4715
  }
5357
4716
  const status = await gitExec(["status", "--porcelain"], { cwd: worktreeDir });
@@ -5400,7 +4759,7 @@ ${user.trimEnd()}
5400
4759
  }
5401
4760
  }
5402
4761
  if (body.accept) {
5403
- if (existsSync8(worktreeDir)) {
4762
+ if (existsSync7(worktreeDir)) {
5404
4763
  try {
5405
4764
  await cleanupVariant(upgradeVariantName, dir, worktreeDir, { stop: true });
5406
4765
  } catch (err) {
@@ -5415,7 +4774,7 @@ ${user.trimEnd()}
5415
4774
  }
5416
4775
  if (body.diff) {
5417
4776
  try {
5418
- if (!existsSync8(resolve11(dir, ".git"))) {
4777
+ if (!existsSync7(resolve10(dir, ".git"))) {
5419
4778
  return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
5420
4779
  }
5421
4780
  await updateTemplateBranch(dir, template, mindName);
@@ -5433,22 +4792,22 @@ ${user.trimEnd()}
5433
4792
  );
5434
4793
  }
5435
4794
  }
5436
- if (existsSync8(worktreeDir)) {
4795
+ if (existsSync7(worktreeDir)) {
5437
4796
  return c.json(
5438
4797
  { error: "Upgrade variant already exists. Use continue or delete it first." },
5439
4798
  409
5440
4799
  );
5441
4800
  }
5442
- if (!existsSync8(resolve11(dir, ".git"))) {
4801
+ if (!existsSync7(resolve10(dir, ".git"))) {
5443
4802
  try {
5444
- const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dir, "home") } : void 0;
4803
+ const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dir, "home") } : void 0;
5445
4804
  await gitExec(["init"], { cwd: dir, mindName, env });
5446
4805
  await configureGitIdentity(mindName, { cwd: dir, mindName, env });
5447
4806
  await gitExec(["add", "-A"], { cwd: dir, mindName, env });
5448
4807
  await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
5449
4808
  chownMindDir(dir, mindName);
5450
4809
  } catch (err) {
5451
- rmSync4(resolve11(dir, ".git"), { recursive: true, force: true });
4810
+ rmSync4(resolve10(dir, ".git"), { recursive: true, force: true });
5452
4811
  return c.json(
5453
4812
  {
5454
4813
  error: `Git initialization failed: ${err instanceof Error ? err.message : String(err)}`
@@ -5463,8 +4822,8 @@ ${user.trimEnd()}
5463
4822
  } catch {
5464
4823
  }
5465
4824
  await updateTemplateBranch(dir, template, mindName);
5466
- const parentDir = resolve11(dir, ".variants");
5467
- if (!existsSync8(parentDir)) {
4825
+ const parentDir = resolve10(dir, ".variants");
4826
+ if (!existsSync7(parentDir)) {
5468
4827
  mkdirSync6(parentDir, { recursive: true });
5469
4828
  }
5470
4829
  await gitExec(["worktree", "add", "-b", UPGRADE_BRANCH, worktreeDir], { cwd: dir });
@@ -5593,22 +4952,22 @@ ${user.trimEnd()}
5593
4952
  const entry = await findMind(name);
5594
4953
  if (!entry) return c.json({ error: "Mind not found" }, 404);
5595
4954
  const dir = entry.dir ?? mindDir(name);
5596
- if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
4955
+ if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
5597
4956
  let config2 = readVoluteConfig(dir);
5598
4957
  if (!config2 && entry.template === "pi") {
5599
- const piConfigPath = resolve11(dir, "home/.config/config.json");
5600
- if (existsSync8(piConfigPath)) {
4958
+ const piConfigPath = resolve10(dir, "home/.config/config.json");
4959
+ if (existsSync7(piConfigPath)) {
5601
4960
  try {
5602
- config2 = JSON.parse(readFileSync9(piConfigPath, "utf-8"));
4961
+ config2 = JSON.parse(readFileSync8(piConfigPath, "utf-8"));
5603
4962
  } catch {
5604
4963
  }
5605
4964
  }
5606
4965
  }
5607
4966
  let templateConfig = {};
5608
- const configJsonPath = resolve11(dir, "home/.config/config.json");
5609
- if (existsSync8(configJsonPath)) {
4967
+ const configJsonPath = resolve10(dir, "home/.config/config.json");
4968
+ if (existsSync7(configJsonPath)) {
5610
4969
  try {
5611
- templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
4970
+ templateConfig = JSON.parse(readFileSync8(configJsonPath, "utf-8"));
5612
4971
  } catch {
5613
4972
  }
5614
4973
  }
@@ -5662,7 +5021,7 @@ ${user.trimEnd()}
5662
5021
  const entry = await findMind(name);
5663
5022
  if (!entry) return c.json({ error: "Mind not found" }, 404);
5664
5023
  const dir = entry.dir ?? mindDir(name);
5665
- if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
5024
+ if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
5666
5025
  const body = c.req.valid("json");
5667
5026
  const existing = readVoluteConfig(dir) ?? {};
5668
5027
  if (body.model !== void 0) existing.model = body.model;
@@ -5693,11 +5052,11 @@ ${user.trimEnd()}
5693
5052
  writeVoluteConfig(dir, existing);
5694
5053
  const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.maxThinkingTokens !== void 0 || body.compaction !== void 0;
5695
5054
  if (needsConfigJson) {
5696
- const configJsonPath = resolve11(dir, "home/.config/config.json");
5055
+ const configJsonPath = resolve10(dir, "home/.config/config.json");
5697
5056
  let templateConfig = {};
5698
- if (existsSync8(configJsonPath)) {
5057
+ if (existsSync7(configJsonPath)) {
5699
5058
  try {
5700
- templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
5059
+ templateConfig = JSON.parse(readFileSync8(configJsonPath, "utf-8"));
5701
5060
  } catch {
5702
5061
  }
5703
5062
  }
@@ -5765,7 +5124,7 @@ ${user.trimEnd()}
5765
5124
  }
5766
5125
  if (entry.mindType === "spirit" && body.model !== void 0) {
5767
5126
  try {
5768
- const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-PMJHCZQX.js");
5127
+ const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-PF7JSFMO.js");
5769
5128
  const globalConfig = readGlobalConfig2();
5770
5129
  globalConfig.spiritModel = body.model;
5771
5130
  writeGlobalConfig2(globalConfig);
@@ -5793,7 +5152,7 @@ ${user.trimEnd()}
5793
5152
  if (!body.systemPrompt || !body.message) {
5794
5153
  return c.json({ error: "systemPrompt and message required" }, 400);
5795
5154
  }
5796
- const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-GSZWIETO.js");
5155
+ const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-C2YNARGH.js");
5797
5156
  if (!isAiConfigured()) {
5798
5157
  return c.json({ error: "AI service not configured" }, 503);
5799
5158
  }
@@ -5883,6 +5242,17 @@ ${user.trimEnd()}
5883
5242
  metadata: body.metadata,
5884
5243
  turnId: turnId ?? void 0
5885
5244
  });
5245
+ if (body.type === "text" && body.channel && cleanContent) {
5246
+ echoTextToChannel(
5247
+ baseName,
5248
+ body.channel,
5249
+ cleanContent,
5250
+ turnId ?? void 0,
5251
+ insertedId
5252
+ ).catch(
5253
+ (err) => logger_default.error(`echo-text failed for ${baseName} on ${body.channel}`, logger_default.errorData(err))
5254
+ );
5255
+ }
5886
5256
  onMindEvent(baseName, body.type, body.channel);
5887
5257
  if ((body.type === "text" || body.type === "outbound") && body.channel) {
5888
5258
  const map = getTypingMap();
@@ -5951,7 +5321,7 @@ ${user.trimEnd()}
5951
5321
  const stream = new ReadableStream({
5952
5322
  start(controller) {
5953
5323
  const encoder = new TextEncoder();
5954
- const send5 = (data) => {
5324
+ const send = (data) => {
5955
5325
  controller.enqueue(encoder.encode(`data: ${data}
5956
5326
 
5957
5327
  `));
@@ -5970,7 +5340,7 @@ ${user.trimEnd()}
5970
5340
  if (sessionFilter && event.session !== sessionFilter) return;
5971
5341
  if (channelFilter && event.channel !== channelFilter) return;
5972
5342
  try {
5973
- send5(JSON.stringify(event));
5343
+ send(JSON.stringify(event));
5974
5344
  } catch {
5975
5345
  clearInterval(pingInterval);
5976
5346
  unsubscribe?.();
@@ -6492,7 +5862,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
6492
5862
  const body = await c.req.text();
6493
5863
  const message = `[webhook: ${event}] ${body}`;
6494
5864
  try {
6495
- const { sendSystemMessage } = await import("./system-chat-2IFS5HCX.js");
5865
+ const { sendSystemMessage } = await import("./system-chat-7AIN3U5M.js");
6496
5866
  await sendSystemMessage(name, message);
6497
5867
  return c.json({ ok: true });
6498
5868
  } catch (err) {
@@ -6505,14 +5875,14 @@ var schedules_default = app15;
6505
5875
  // packages/daemon/src/web/api/setup.ts
6506
5876
  import { mkdirSync as mkdirSync7 } from "fs";
6507
5877
  import { homedir as homedir2 } from "os";
6508
- import { resolve as resolve12 } from "path";
5878
+ import { resolve as resolve11 } from "path";
6509
5879
  import { Hono as Hono18 } from "hono";
6510
5880
  import { setCookie as setCookie2 } from "hono/cookie";
6511
5881
  var DEFAULT_API_URL2 = "https://volute.systems";
6512
5882
  var setup = new Hono18();
6513
5883
  function writeSetupConfig(systemName, description) {
6514
- const configHome = process.env.VOLUTE_HOME ?? resolve12(homedir2(), ".volute");
6515
- const mindsDir = resolve12(configHome, "minds");
5884
+ const configHome = process.env.VOLUTE_HOME ?? resolve11(homedir2(), ".volute");
5885
+ const mindsDir = resolve11(configHome, "minds");
6516
5886
  mkdirSync7(configHome, { recursive: true });
6517
5887
  mkdirSync7(mindsDir, { recursive: true });
6518
5888
  const existingConfig = readGlobalConfig();
@@ -6526,7 +5896,8 @@ function writeSetupConfig(systemName, description) {
6526
5896
  ...existingConfig,
6527
5897
  name: systemName,
6528
5898
  description: description || existingConfig.description,
6529
- setup: setupConfig
5899
+ setup: setupConfig,
5900
+ setupCompleted: false
6530
5901
  };
6531
5902
  writeGlobalConfig(config2);
6532
5903
  return config2;
@@ -6545,7 +5916,7 @@ setup.get("/status", async (c) => {
6545
5916
  let hasAccount = false;
6546
5917
  if (hasSystem) {
6547
5918
  try {
6548
- const { listUsersByType: listUsersByType2 } = await import("./auth-YTQME4EV.js");
5919
+ const { listUsersByType: listUsersByType2 } = await import("./auth-2QOOPMBX.js");
6549
5920
  const brains = await listUsersByType2("brain");
6550
5921
  hasAccount = brains.length > 0;
6551
5922
  } catch (err) {
@@ -6734,7 +6105,7 @@ setup.post("/account", async (c) => {
6734
6105
  }
6735
6106
  }
6736
6107
  try {
6737
- const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-YTQME4EV.js");
6108
+ const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-2QOOPMBX.js");
6738
6109
  const user = await createUser2(body.username.trim(), body.password);
6739
6110
  if (body.displayName?.trim()) {
6740
6111
  await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
@@ -6780,7 +6151,7 @@ setup.post("/models", async (c) => {
6780
6151
  return c.json({ error: "Spirit model is required" }, 400);
6781
6152
  }
6782
6153
  try {
6783
- const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-GSZWIETO.js");
6154
+ const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-C2YNARGH.js");
6784
6155
  setEnabledModels3(body.models);
6785
6156
  const config2 = readGlobalConfig();
6786
6157
  config2.spiritModel = body.spiritModel.trim();
@@ -6798,8 +6169,8 @@ setup.post("/complete", async (c) => {
6798
6169
  return c.json({ error: "Setup already complete" }, 400);
6799
6170
  }
6800
6171
  try {
6801
- const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-6KVDIROQ.js");
6802
- const { startSpiritFull } = await import("./mind-service-E7FM2WZF.js");
6172
+ const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-4QOYM33G.js");
6173
+ const { startSpiritFull } = await import("./mind-service-WRTOQSAL.js");
6803
6174
  await ensureSpiritProject();
6804
6175
  await syncSpiritTemplate();
6805
6176
  const warnings = [];
@@ -6815,8 +6186,8 @@ setup.post("/complete", async (c) => {
6815
6186
  }
6816
6187
  let spiritConversationId;
6817
6188
  try {
6818
- const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-YTQME4EV.js");
6819
- const { createConversation: createConversation6, findDMConversation: findDMConversation2 } = await import("./conversations-HH3CJD4E.js");
6189
+ const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-2QOOPMBX.js");
6190
+ const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-G6YRSABR.js");
6820
6191
  const spiritUser = await getOrCreateMindUser2("volute");
6821
6192
  const brains = await listUsersByType2("brain");
6822
6193
  const admin2 = brains.find((u) => u.role === "admin");
@@ -6825,7 +6196,7 @@ setup.post("/complete", async (c) => {
6825
6196
  if (existing) {
6826
6197
  spiritConversationId = existing;
6827
6198
  } else {
6828
- const conv = await createConversation6({
6199
+ const conv = await createConversation2({
6829
6200
  participantIds: [admin2.id, spiritUser.id]
6830
6201
  });
6831
6202
  spiritConversationId = conv.id;
@@ -6838,9 +6209,9 @@ setup.post("/complete", async (c) => {
6838
6209
  logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
6839
6210
  if (spiritConversationId && spiritStarted) {
6840
6211
  try {
6841
- const { deliverMessage: deliverMessage2 } = await import("./message-delivery-YORUXKDQ.js");
6842
- const { listUsersByType: listUsers6 } = await import("./auth-YTQME4EV.js");
6843
- const admins = await listUsers6("brain");
6212
+ const { deliverMessage: deliverMessage2 } = await import("./message-delivery-NWL7XEIX.js");
6213
+ const { listUsersByType: listUsers2 } = await import("./auth-2QOOPMBX.js");
6214
+ const admins = await listUsers2("brain");
6844
6215
  const admin2 = admins.find((u) => u.role === "admin");
6845
6216
  const adminName = admin2?.display_name || admin2?.username || "the admin";
6846
6217
  const welcomePrompt = `Setup is complete. ${adminName} just finished setting up this system and is now in your chat. Welcome them and help them create their first mind. Keep it brief \u2014 a short greeting, then ask what kind of being they'd like to bring into the world. Remember: minds are beings with their own experience, not tools \u2014 ask about personality and character, never about tasks or utility.`;
@@ -6876,9 +6247,9 @@ setup.post("/complete", async (c) => {
6876
6247
  var setup_default = setup;
6877
6248
 
6878
6249
  // packages/daemon/src/web/api/skills.ts
6879
- import { existsSync as existsSync9, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
6250
+ import { existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
6880
6251
  import { tmpdir } from "os";
6881
- import { join, resolve as resolve13 } from "path";
6252
+ import { join, resolve as resolve12 } from "path";
6882
6253
  import AdmZip from "adm-zip";
6883
6254
  import { Hono as Hono19 } from "hono";
6884
6255
  var app16 = new Hono19().get("/", async (c) => {
@@ -6954,19 +6325,19 @@ var app16 = new Hono19().get("/", async (c) => {
6954
6325
  try {
6955
6326
  const zip = new AdmZip(buffer2);
6956
6327
  for (const entry of zip.getEntries()) {
6957
- const target = resolve13(tmpDir, entry.entryName);
6328
+ const target = resolve12(tmpDir, entry.entryName);
6958
6329
  if (!target.startsWith(tmpDir)) {
6959
6330
  return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
6960
6331
  }
6961
6332
  }
6962
6333
  zip.extractAllTo(tmpDir, true);
6963
6334
  let skillDir = null;
6964
- if (existsSync9(join(tmpDir, "SKILL.md"))) {
6335
+ if (existsSync8(join(tmpDir, "SKILL.md"))) {
6965
6336
  skillDir = tmpDir;
6966
6337
  } else {
6967
6338
  const entries = readdirSync3(tmpDir, { withFileTypes: true }).filter((e) => e.isDirectory());
6968
6339
  for (const entry of entries) {
6969
- if (existsSync9(join(tmpDir, entry.name, "SKILL.md"))) {
6340
+ if (existsSync8(join(tmpDir, entry.name, "SKILL.md"))) {
6970
6341
  skillDir = join(tmpDir, entry.name);
6971
6342
  break;
6972
6343
  }
@@ -7296,8 +6667,8 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
7296
6667
  });
7297
6668
  }, 15e3);
7298
6669
  cleanups.push(() => clearInterval(keepAlive));
7299
- await new Promise((resolve18) => {
7300
- stream.onAbort(() => resolve18());
6670
+ await new Promise((resolve17) => {
6671
+ stream.onAbort(() => resolve17());
7301
6672
  });
7302
6673
  } finally {
7303
6674
  for (const cleanup of cleanups) {
@@ -7312,16 +6683,16 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
7312
6683
  var events_default = app20;
7313
6684
 
7314
6685
  // packages/daemon/src/web/api/variants.ts
7315
- import { existsSync as existsSync10, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
7316
- import { resolve as resolve15 } from "path";
6686
+ import { existsSync as existsSync9, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
6687
+ import { resolve as resolve14 } from "path";
7317
6688
  import { Hono as Hono24 } from "hono";
7318
6689
 
7319
6690
  // packages/daemon/src/lib/mind/spawn-server.ts
7320
6691
  import { spawn as spawn4 } from "child_process";
7321
- import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync10 } from "fs";
7322
- import { resolve as resolve14 } from "path";
6692
+ import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync9 } from "fs";
6693
+ import { resolve as resolve13 } from "path";
7323
6694
  function tsxBin(cwd) {
7324
- return resolve14(cwd, "node_modules", ".bin", "tsx");
6695
+ return resolve13(cwd, "node_modules", ".bin", "tsx");
7325
6696
  }
7326
6697
  function spawnServer(cwd, port, options) {
7327
6698
  if (options?.detached) {
@@ -7334,31 +6705,31 @@ function spawnAttached(cwd, port) {
7334
6705
  cwd,
7335
6706
  stdio: ["ignore", "pipe", "pipe"]
7336
6707
  });
7337
- return new Promise((resolve18) => {
7338
- const timeout = setTimeout(() => resolve18(null), 3e4);
6708
+ return new Promise((resolve17) => {
6709
+ const timeout = setTimeout(() => resolve17(null), 3e4);
7339
6710
  function checkOutput(data) {
7340
6711
  const match = data.toString().match(/listening on :(\d+)/);
7341
6712
  if (match) {
7342
6713
  clearTimeout(timeout);
7343
- resolve18({ child, actualPort: parseInt(match[1], 10) });
6714
+ resolve17({ child, actualPort: parseInt(match[1], 10) });
7344
6715
  }
7345
6716
  }
7346
6717
  child.stdout?.on("data", checkOutput);
7347
6718
  child.stderr?.on("data", checkOutput);
7348
6719
  child.on("error", () => {
7349
6720
  clearTimeout(timeout);
7350
- resolve18(null);
6721
+ resolve17(null);
7351
6722
  });
7352
6723
  child.on("exit", () => {
7353
6724
  clearTimeout(timeout);
7354
- resolve18(null);
6725
+ resolve17(null);
7355
6726
  });
7356
6727
  });
7357
6728
  }
7358
6729
  function spawnDetached(cwd, port, logDir) {
7359
- const logsDir = logDir ?? resolve14(cwd, ".mind", "logs");
6730
+ const logsDir = logDir ?? resolve13(cwd, ".mind", "logs");
7360
6731
  mkdirSync8(logsDir, { recursive: true });
7361
- const logPath = resolve14(logsDir, "mind.log");
6732
+ const logPath = resolve13(logsDir, "mind.log");
7362
6733
  const logFd = openSync(logPath, "a");
7363
6734
  const child = spawn4(tsxBin(cwd), ["src/server.ts", "--port", String(port)], {
7364
6735
  cwd,
@@ -7378,7 +6749,7 @@ function spawnDetached(cwd, port, logDir) {
7378
6749
  }
7379
6750
  const interval = setInterval(() => {
7380
6751
  try {
7381
- const content = readFileSync10(logPath, "utf-8");
6752
+ const content = readFileSync9(logPath, "utf-8");
7382
6753
  const match = content.match(/listening on :(\d+)/);
7383
6754
  if (match) {
7384
6755
  finish({ child, actualPort: parseInt(match[1], 10) });
@@ -7474,11 +6845,11 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7474
6845
  return c.json({ error: `Name already in use: ${variantName}` }, 409);
7475
6846
  }
7476
6847
  const projectRoot = mindDir(mindName);
7477
- const variantDir = resolve15(projectRoot, ".variants", variantName);
7478
- if (existsSync10(variantDir)) {
6848
+ const variantDir = resolve14(projectRoot, ".variants", variantName);
6849
+ if (existsSync9(variantDir)) {
7479
6850
  return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
7480
6851
  }
7481
- mkdirSync9(resolve15(projectRoot, ".variants"), { recursive: true });
6852
+ mkdirSync9(resolve14(projectRoot, ".variants"), { recursive: true });
7482
6853
  try {
7483
6854
  await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
7484
6855
  } catch (e) {
@@ -7491,7 +6862,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7491
6862
  const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
7492
6863
  await exec(cmd, args, {
7493
6864
  cwd: variantDir,
7494
- env: { ...process.env, HOME: resolve15(variantDir, "home") }
6865
+ env: { ...process.env, HOME: resolve14(variantDir, "home") }
7495
6866
  });
7496
6867
  } else {
7497
6868
  await exec("npm", ["install"], { cwd: variantDir });
@@ -7501,7 +6872,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7501
6872
  return c.json({ error: `npm install failed: ${msg}` }, 500);
7502
6873
  }
7503
6874
  if (body.soul) {
7504
- writeFileSync8(resolve15(variantDir, "home/SOUL.md"), body.soul);
6875
+ writeFileSync8(resolve14(variantDir, "home/SOUL.md"), body.soul);
7505
6876
  }
7506
6877
  const variantPort = body.port ?? await nextPort();
7507
6878
  await addVariant(variantName, mindName, variantPort, variantDir, variantName);
@@ -7536,7 +6907,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7536
6907
  } catch {
7537
6908
  }
7538
6909
  const projectRoot = mindDir(mindName);
7539
- if (existsSync10(variantEntry.dir)) {
6910
+ if (existsSync9(variantEntry.dir)) {
7540
6911
  const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
7541
6912
  if (status) {
7542
6913
  try {
@@ -7596,8 +6967,8 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7596
6967
  await cleanupVariant(variantName, projectRoot, variantEntry.dir);
7597
6968
  if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
7598
6969
  try {
7599
- const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-6ITI3WC4.js");
7600
- const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-YPHK534W.js");
6970
+ const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-SSIBEEYK.js");
6971
+ const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-KMELPC3X.js");
7601
6972
  const tmpl = parentEntry.template ?? "claude";
7602
6973
  await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
7603
6974
  } catch (err) {
@@ -7610,7 +6981,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7610
6981
  const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
7611
6982
  await exec(cmd, args, {
7612
6983
  cwd: projectRoot,
7613
- env: { ...process.env, HOME: resolve15(projectRoot, "home") }
6984
+ env: { ...process.env, HOME: resolve14(projectRoot, "home") }
7614
6985
  });
7615
6986
  } else {
7616
6987
  await exec("npm", ["install"], { cwd: projectRoot });
@@ -7764,86 +7135,6 @@ import { zValidator as zValidator10 } from "@hono/zod-validator";
7764
7135
  import { Hono as Hono26 } from "hono";
7765
7136
  import { streamSSE as streamSSE5 } from "hono/streaming";
7766
7137
  import { z as z10 } from "zod";
7767
-
7768
- // packages/daemon/src/lib/bridges/bridge-outbound.ts
7769
- function extractContent(contentBlocks) {
7770
- const text = contentBlocks.filter((b) => b.type === "text").map((b) => b.text).join("\n");
7771
- const images = contentBlocks.filter((b) => b.type === "image").map((b) => ({ media_type: b.media_type, data: b.data }));
7772
- return { text, images };
7773
- }
7774
- async function routeOutboundBridge(conversationId, senderName, contentBlocks) {
7775
- try {
7776
- const conv = await getConversation(conversationId);
7777
- if (!conv) return;
7778
- if (conv.type === "channel") {
7779
- const channelName = await getChannelName(conversationId);
7780
- if (channelName) {
7781
- await routeChannelOutbound(channelName, senderName, contentBlocks);
7782
- } else {
7783
- logger_default.warn(
7784
- `channel conversation ${conversationId} has no channel name \u2014 skipping bridge outbound`
7785
- );
7786
- }
7787
- } else if (conv.type === "dm") {
7788
- await routeDMOutbound(conversationId, senderName, contentBlocks);
7789
- }
7790
- } catch (err) {
7791
- logger_default.error(`bridge outbound failed for conversation ${conversationId}`, logger_default.errorData(err));
7792
- }
7793
- }
7794
- async function routeChannelOutbound(channelName, senderName, contentBlocks) {
7795
- const bridgeInfo = findBridgeForChannel(channelName);
7796
- if (!bridgeInfo) return;
7797
- const driver = getPlatformDriver(bridgeInfo.platform);
7798
- if (!driver) {
7799
- logger_default.warn(`no channel driver for bridge platform: ${bridgeInfo.platform}`);
7800
- return;
7801
- }
7802
- const { text, images } = extractContent(contentBlocks);
7803
- if (!text) return;
7804
- const env = readEnv(sharedEnvPath());
7805
- env.VOLUTE_SENDER = senderName;
7806
- await driver.send(env, bridgeInfo.externalChannel, text, images.length > 0 ? images : void 0);
7807
- logger_default.debug(`bridge outbound: sent to ${bridgeInfo.platform}:${bridgeInfo.externalChannel}`);
7808
- }
7809
- async function routeDMOutbound(conversationId, senderName, contentBlocks) {
7810
- const participants = await getParticipants(conversationId);
7811
- const puppets = participants.filter((p) => p.userType === "puppet");
7812
- if (puppets.length === 0) return;
7813
- const { text, images } = extractContent(contentBlocks);
7814
- if (!text) return;
7815
- for (const puppet of puppets) {
7816
- const colonIdx = puppet.username.indexOf(":");
7817
- if (colonIdx === -1) {
7818
- logger_default.warn(
7819
- `puppet user ${puppet.username} has malformed username (expected platform:id format)`
7820
- );
7821
- continue;
7822
- }
7823
- const platform = puppet.username.slice(0, colonIdx);
7824
- const externalUserId = puppet.username.slice(colonIdx + 1);
7825
- const bridgeConfig = getBridgeConfig(platform);
7826
- if (!bridgeConfig?.enabled) continue;
7827
- const driver = getPlatformDriver(platform);
7828
- if (!driver?.createConversation) {
7829
- logger_default.warn(`no channel driver with DM support for bridge platform: ${platform}`);
7830
- continue;
7831
- }
7832
- try {
7833
- const env = readEnv(sharedEnvPath());
7834
- env.VOLUTE_SENDER = senderName;
7835
- env.VOLUTE_MIND = senderName;
7836
- env.VOLUTE_MIND_DIR = mindDir(senderName);
7837
- const slug = await driver.createConversation(env, [externalUserId]);
7838
- await driver.send(env, slug, text, images.length > 0 ? images : void 0);
7839
- logger_default.debug(`bridge outbound DM: sent to ${platform}:${externalUserId}`);
7840
- } catch (err) {
7841
- logger_default.error(`bridge outbound DM failed for puppet ${puppet.username}`, logger_default.errorData(err));
7842
- }
7843
- }
7844
- }
7845
-
7846
- // packages/daemon/src/web/api/volute/chat.ts
7847
7138
  async function fanOutToMinds(opts) {
7848
7139
  const participants = opts.participants;
7849
7140
  const mindParticipants = participants.filter(
@@ -8098,11 +7389,11 @@ var app23 = new Hono26().get("/:name/conversations/:id/events", async (c) => {
8098
7389
  if (!stream.aborted) console.error("[chat] SSE ping error:", err);
8099
7390
  });
8100
7391
  }, 15e3);
8101
- await new Promise((resolve18) => {
7392
+ await new Promise((resolve17) => {
8102
7393
  stream.onAbort(() => {
8103
7394
  unsubscribe();
8104
7395
  clearInterval(keepAlive);
8105
- resolve18();
7396
+ resolve17();
8106
7397
  });
8107
7398
  });
8108
7399
  });
@@ -8312,10 +7603,10 @@ app25.route("/api/conversations", conversations_default);
8312
7603
  var app_default = app25;
8313
7604
 
8314
7605
  // packages/daemon/src/web/server.ts
8315
- import { existsSync as existsSync11 } from "fs";
7606
+ import { existsSync as existsSync10 } from "fs";
8316
7607
  import { readFile as readFile2, stat as stat2 } from "fs/promises";
8317
7608
  import { createServer as createHttpsServer } from "https";
8318
- import { dirname as dirname2, extname as extname3, resolve as resolve16 } from "path";
7609
+ import { dirname as dirname2, extname as extname3, resolve as resolve15 } from "path";
8319
7610
  import { serve } from "@hono/node-server";
8320
7611
  var MIME_TYPES2 = {
8321
7612
  ".html": "text/html",
@@ -8334,8 +7625,8 @@ async function startServer({
8334
7625
  let assetsDir = "";
8335
7626
  let searchDir = dirname2(new URL(import.meta.url).pathname);
8336
7627
  for (let i = 0; i < 5; i++) {
8337
- const candidate = resolve16(searchDir, "dist", "web-assets");
8338
- if (existsSync11(candidate)) {
7628
+ const candidate = resolve15(searchDir, "dist", "web-assets");
7629
+ if (existsSync10(candidate)) {
8339
7630
  assetsDir = candidate;
8340
7631
  break;
8341
7632
  }
@@ -8345,7 +7636,7 @@ async function startServer({
8345
7636
  app_default.get("*", async (c) => {
8346
7637
  const urlPath = new URL(c.req.url).pathname;
8347
7638
  if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
8348
- const filePath = resolve16(assetsDir, urlPath.slice(1));
7639
+ const filePath = resolve15(assetsDir, urlPath.slice(1));
8349
7640
  if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
8350
7641
  const s = await stat2(filePath).catch(() => null);
8351
7642
  if (s?.isFile()) {
@@ -8358,7 +7649,7 @@ async function startServer({
8358
7649
  const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
8359
7650
  return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
8360
7651
  }
8361
- const indexPath = resolve16(assetsDir, "index.html");
7652
+ const indexPath = resolve15(assetsDir, "index.html");
8362
7653
  const indexStat = await stat2(indexPath).catch(() => null);
8363
7654
  if (indexStat?.isFile()) {
8364
7655
  const body = await readFile2(indexPath, "utf-8");
@@ -8375,10 +7666,10 @@ async function startServer({
8375
7666
  createServer: createHttpsServer,
8376
7667
  serverOptions: { key: tls.key, cert: tls.cert }
8377
7668
  });
8378
- await new Promise((resolve18, reject) => {
7669
+ await new Promise((resolve17, reject) => {
8379
7670
  server2.on("listening", () => {
8380
7671
  logger_default.info("Volute UI running (https)", { hostname, port });
8381
- resolve18();
7672
+ resolve17();
8382
7673
  });
8383
7674
  server2.on("error", (err) => {
8384
7675
  reject(err);
@@ -8386,13 +7677,13 @@ async function startServer({
8386
7677
  });
8387
7678
  const internalPort = port + 1;
8388
7679
  const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
8389
- await new Promise((resolve18, reject) => {
7680
+ await new Promise((resolve17, reject) => {
8390
7681
  internalServer.on("listening", () => {
8391
7682
  logger_default.info("Volute API running (http, internal)", {
8392
7683
  hostname: "127.0.0.1",
8393
7684
  port: internalPort
8394
7685
  });
8395
- resolve18();
7686
+ resolve17();
8396
7687
  });
8397
7688
  internalServer.on("error", (err) => {
8398
7689
  reject(err);
@@ -8401,10 +7692,10 @@ async function startServer({
8401
7692
  return { server: server2, internalPort };
8402
7693
  }
8403
7694
  const server = serve({ fetch: app_default.fetch, port, hostname });
8404
- await new Promise((resolve18, reject) => {
7695
+ await new Promise((resolve17, reject) => {
8405
7696
  server.on("listening", () => {
8406
7697
  logger_default.info("Volute API running (http)", { hostname, port });
8407
- resolve18();
7698
+ resolve17();
8408
7699
  });
8409
7700
  server.on("error", (err) => {
8410
7701
  reject(err);
@@ -8415,7 +7706,7 @@ async function startServer({
8415
7706
 
8416
7707
  // packages/daemon/src/daemon.ts
8417
7708
  if (!process.env.VOLUTE_HOME) {
8418
- process.env.VOLUTE_HOME = resolve17(homedir3(), ".volute");
7709
+ process.env.VOLUTE_HOME = resolve16(homedir3(), ".volute");
8419
7710
  }
8420
7711
  if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
8421
7712
  process.env.TZ = process.env.VOLUTE_TIMEZONE;
@@ -8426,7 +7717,7 @@ async function startDaemon(opts) {
8426
7717
  const home = voluteHome();
8427
7718
  const systemDir = voluteSystemDir();
8428
7719
  if (!opts.foreground) {
8429
- const rotatingLog = new RotatingLog(resolve17(systemDir, "daemon.log"));
7720
+ const rotatingLog = new RotatingLog(resolve16(systemDir, "daemon.log"));
8430
7721
  logger_default.setOutput((line) => rotatingLog.write(`${line}
8431
7722
  `));
8432
7723
  const write = (...args) => rotatingLog.write(`${format(...args)}
@@ -8436,22 +7727,22 @@ async function startDaemon(opts) {
8436
7727
  console.warn = write;
8437
7728
  console.info = write;
8438
7729
  }
8439
- const DAEMON_PID_PATH = resolve17(systemDir, "daemon.pid");
8440
- const DAEMON_JSON_PATH = resolve17(systemDir, "daemon.json");
7730
+ const DAEMON_PID_PATH = resolve16(systemDir, "daemon.pid");
7731
+ const DAEMON_JSON_PATH = resolve16(systemDir, "daemon.json");
8441
7732
  mkdirSync10(home, { recursive: true });
8442
7733
  ensureSystemDir();
8443
- const { migrateSetupCompleted } = await import("./setup-PMJHCZQX.js");
7734
+ const { migrateSetupCompleted } = await import("./setup-PF7JSFMO.js");
8444
7735
  migrateSetupCompleted();
8445
- await (await import("./db-URORGSXQ.js")).getDb();
7736
+ await (await import("./db-CBOCDYVA.js")).getDb();
8446
7737
  try {
8447
7738
  const { eq: eq7, and: and5 } = await import("drizzle-orm");
8448
- const { users: users2 } = await import("./schema-MISD3JFG.js");
8449
- const db = await (await import("./db-URORGSXQ.js")).getDb();
7739
+ const { users: users2 } = await import("./schema-K575EBPE.js");
7740
+ const db = await (await import("./db-CBOCDYVA.js")).getDb();
8450
7741
  await db.update(users2).set({ role: "system" }).where(and5(eq7(users2.user_type, "system"), eq7(users2.role, "user")));
8451
7742
  } catch (err) {
8452
7743
  logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
8453
7744
  }
8454
- const { initSandbox } = await import("./sandbox-LP6YRAXS.js");
7745
+ const { initSandbox } = await import("./sandbox-PQYEICEF.js");
8455
7746
  await initSandbox();
8456
7747
  try {
8457
7748
  await syncBuiltinSkills();
@@ -8478,7 +7769,7 @@ async function startDaemon(opts) {
8478
7769
  logger_default.warn("failed to ensure #system channel", logger_default.errorData(err));
8479
7770
  }
8480
7771
  try {
8481
- const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-YTQME4EV.js");
7772
+ const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-2QOOPMBX.js");
8482
7773
  await getOrCreateSystemUser2();
8483
7774
  } catch (err) {
8484
7775
  logger_default.warn(
@@ -8489,7 +7780,7 @@ async function startDaemon(opts) {
8489
7780
  const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes(32).toString("hex");
8490
7781
  let tls;
8491
7782
  if (opts.tailscale) {
8492
- const { getTailscaleTls } = await import("./tailscale-DZU4WM3E.js");
7783
+ const { getTailscaleTls } = await import("./tailscale-LTYNKIPZ.js");
8493
7784
  const tlsConfig = await getTailscaleTls();
8494
7785
  tls = { key: tlsConfig.key, cert: tlsConfig.cert };
8495
7786
  logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
@@ -8562,10 +7853,10 @@ async function startDaemon(opts) {
8562
7853
  await Promise.all(workers);
8563
7854
  }
8564
7855
  try {
8565
- const { isSetupComplete: isSetupComplete2 } = await import("./setup-PMJHCZQX.js");
7856
+ const { isSetupComplete: isSetupComplete2 } = await import("./setup-PF7JSFMO.js");
8566
7857
  if (isSetupComplete2()) {
8567
- const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-6KVDIROQ.js");
8568
- const { startSpiritFull } = await import("./mind-service-E7FM2WZF.js");
7858
+ const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-4QOYM33G.js");
7859
+ const { startSpiritFull } = await import("./mind-service-WRTOQSAL.js");
8569
7860
  await ensureSpiritProject();
8570
7861
  await syncSpiritTemplate();
8571
7862
  const spiritEntry = await findMind("volute");
@@ -8582,7 +7873,7 @@ async function startDaemon(opts) {
8582
7873
  bridgeManager.startBridges(daemonPort).catch((err) => {
8583
7874
  logger_default.warn("failed to start bridges", logger_default.errorData(err));
8584
7875
  });
8585
- import("./cloud-sync-BOCZSDIA.js").then(
7876
+ import("./cloud-sync-EZKCEIBX.js").then(
8586
7877
  ({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
8587
7878
  logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
8588
7879
  })
@@ -8590,7 +7881,7 @@ async function startDaemon(opts) {
8590
7881
  logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
8591
7882
  });
8592
7883
  try {
8593
- const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-UXSHBZ35.js");
7884
+ const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-NCRIN5QK.js");
8594
7885
  backfillTemplateHashes();
8595
7886
  notifyVersionUpdate().catch((err) => {
8596
7887
  logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
@@ -8611,13 +7902,13 @@ async function startDaemon(opts) {
8611
7902
  logger_default.info(`running on ${hostname}:${port}, pid ${myPid}`);
8612
7903
  function cleanup() {
8613
7904
  try {
8614
- if (readFileSync11(DAEMON_PID_PATH, "utf-8").trim() === myPid) {
7905
+ if (readFileSync10(DAEMON_PID_PATH, "utf-8").trim() === myPid) {
8615
7906
  unlinkSync2(DAEMON_PID_PATH);
8616
7907
  }
8617
7908
  } catch {
8618
7909
  }
8619
7910
  try {
8620
- const data = JSON.parse(readFileSync11(DAEMON_JSON_PATH, "utf-8"));
7911
+ const data = JSON.parse(readFileSync10(DAEMON_JSON_PATH, "utf-8"));
8621
7912
  if (data.token === token) {
8622
7913
  unlinkSync2(DAEMON_JSON_PATH);
8623
7914
  }