volute 0.43.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/{activity-events-UISXY4Y5.js → activity-events-OMCSM7XW.js} +3 -3
  2. package/dist/{ai-service-FBCCEYF5.js → ai-service-7PHSRDMO.js} +4 -4
  3. package/dist/{archive-I32WHCJB.js → archive-6R4TZMYI.js} +3 -3
  4. package/dist/{auth-3RIG6GKN.js → auth-FRZJVQCS.js} +4 -4
  5. package/dist/avatar-image-BNWEXSA2.js +16 -0
  6. package/dist/{chat-SDSX5TVV.js → chat-I4EDDIQC.js} +2 -2
  7. package/dist/{chunk-AD46AYZQ.js → chunk-2BONPXAF.js} +1 -1
  8. package/dist/{chunk-PGPLCJPK.js → chunk-3ERIL673.js} +1 -1
  9. package/dist/{chunk-C6ESRQZ7.js → chunk-3GYVW2X3.js} +1 -1
  10. package/dist/{chunk-SPLPKBES.js → chunk-5AHYQHNT.js} +4 -8
  11. package/dist/{chunk-XDTKJNW5.js → chunk-5GT7URXJ.js} +1 -1
  12. package/dist/{chunk-65OLHBCL.js → chunk-7FT24JBQ.js} +8 -8
  13. package/dist/{chunk-ZO7IQJKO.js → chunk-7KWANSLX.js} +3 -3
  14. package/dist/{chunk-EFL5UOY4.js → chunk-CYI534DJ.js} +3 -3
  15. package/dist/{chunk-FZ5TH5PF.js → chunk-EQZD4YU3.js} +8 -8
  16. package/dist/{chunk-57LBQ7JX.js → chunk-FHWUQZXE.js} +1 -1
  17. package/dist/{chunk-K4EHBHPE.js → chunk-FZMEVCWC.js} +3 -3
  18. package/dist/{chunk-YAMO2U3N.js → chunk-H7IYFRAL.js} +1 -1
  19. package/dist/{chunk-M3PGGSBH.js → chunk-HVU45COX.js} +1 -1
  20. package/dist/{chunk-FSSUANZJ.js → chunk-I2Y2YHIO.js} +5 -5
  21. package/dist/{chunk-O3DXAR44.js → chunk-IEWZ7VD7.js} +2 -2
  22. package/dist/{chunk-YSV3VJQK.js → chunk-J47TIYHA.js} +1 -1
  23. package/dist/{chunk-QHG4OMZL.js → chunk-KDLYIECM.js} +37 -32
  24. package/dist/{chunk-EE7SZJON.js → chunk-KP3KWNG6.js} +2 -2
  25. package/dist/{chunk-JVK6QQIC.js → chunk-LAXUUY7O.js} +2 -2
  26. package/dist/{chunk-3WLWKOGM.js → chunk-NF75HPNR.js} +5 -5
  27. package/dist/{chunk-PF2AB7VJ.js → chunk-OMETFX5H.js} +321 -204
  28. package/dist/{chunk-ONM2AZFL.js → chunk-PNV24SEP.js} +1 -1
  29. package/dist/{chunk-ATEX3ZPG.js → chunk-Q2XBKQ2D.js} +2 -2
  30. package/dist/{chunk-GZJFC76M.js → chunk-QMJJWTNL.js} +1 -1
  31. package/dist/chunk-SQL7M4HJ.js +120 -0
  32. package/dist/{chunk-2HIVYZDB.js → chunk-UMI4UIJG.js} +1 -1
  33. package/dist/{chunk-7G2EEYXX.js → chunk-ZMIMSIIT.js} +2 -2
  34. package/dist/{chunk-L3IV23ZG.js → chunk-ZV7MFISX.js} +2 -0
  35. package/dist/cli.js +47 -22
  36. package/dist/{cloud-sync-FRYNWKCR.js → cloud-sync-6WJ7WFYD.js} +16 -16
  37. package/dist/{conversations-67WWW25C.js → conversations-WAJYZKOC.js} +4 -4
  38. package/dist/{create-7W3LV3J7.js → create-YZIV5OJC.js} +1 -1
  39. package/dist/{daemon-restart-5GVZ5V3X.js → daemon-restart-OUJVINXV.js} +7 -7
  40. package/dist/daemon.js +297 -294
  41. package/dist/{db-CZV62BOQ.js → db-JFLCJCUG.js} +2 -2
  42. package/dist/{db-IJL6B26S.js → db-LZTLA7XC.js} +1 -1
  43. package/dist/delivery-manager-TEVOHX5W.js +32 -0
  44. package/dist/{delivery-router-HXBHYHJM.js → delivery-router-GODSIS62.js} +3 -3
  45. package/dist/{down-RRNYIGCU.js → down-XCAZXWLB.js} +5 -5
  46. package/dist/echo-text-T7ZA5EYD.js +32 -0
  47. package/dist/{exec-SJK7VUTC.js → exec-4GWHAHS3.js} +3 -3
  48. package/dist/{export-7LPCIB5J.js → export-ID7YUSLZ.js} +3 -3
  49. package/dist/{extensions-76EGTMFY.js → extensions-3QNDGW5E.js} +16 -16
  50. package/dist/{files-LV7VAKPC.js → files-BQ2WB5KC.js} +3 -3
  51. package/dist/{import-XPECCRQ7.js → import-SKID37QX.js} +6 -6
  52. package/dist/{isolation-5AYEY55P.js → isolation-5MB3J73F.js} +3 -3
  53. package/dist/{login-KJSN4JDA.js → login-LM4NF4ZB.js} +2 -2
  54. package/dist/{logout-TMJGUQV2.js → logout-CTJVIZGA.js} +2 -2
  55. package/dist/message-delivery-2EA5LLMD.js +34 -0
  56. package/dist/{mind-QEWCR7FA.js → mind-MI7Z6KM2.js} +5 -5
  57. package/dist/{mind-activity-tracker-JHAT6456.js → mind-activity-tracker-BGHJE7XA.js} +4 -4
  58. package/dist/mind-service-S3SY7HAM.js +36 -0
  59. package/dist/{package-ZOI2KAYC.js → package-5B4XDTJH.js} +1 -1
  60. package/dist/{registry-7LQHTRUX.js → registry-NUJAGLQJ.js} +2 -2
  61. package/dist/{sandbox-SJH3XOPZ.js → sandbox-IOPWWILM.js} +4 -4
  62. package/dist/scheduler-CXWQ6Z4E.js +30 -0
  63. package/dist/{schema-LRUTFOER.js → schema-PVNG3PQM.js} +1 -1
  64. package/dist/{seed-KOG6KJAO.js → seed-UUPVQWFB.js} +1 -1
  65. package/dist/{seed-cmd-GJFENEJH.js → seed-cmd-7XPKDQUC.js} +2 -2
  66. package/dist/{seed-create-YXO6R4KE.js → seed-create-IZ4M5ESO.js} +3 -3
  67. package/dist/{seed-sprout-BBU64QXP.js → seed-sprout-POJXHJWV.js} +7 -7
  68. package/dist/{send-ZBZWIH5V.js → send-O6W53VBM.js} +37 -42
  69. package/dist/{service-4EVZKGSA.js → service-AQVPUANO.js} +4 -4
  70. package/dist/{service-install-SHRM6NHK.js → service-install-4QNUDKLM.js} +5 -5
  71. package/dist/{setup-354PDHUF.js → setup-5GCO3CUB.js} +7 -7
  72. package/dist/{setup-25MMJ3J4.js → setup-MLRKNP7Y.js} +3 -3
  73. package/dist/{skills-DPI3WZPQ.js → skills-775C7QFF.js} +5 -5
  74. package/dist/sleep-manager-HINI6Y46.js +34 -0
  75. package/dist/{spirit-JQQHUVWR.js → spirit-IK5OYWMV.js} +7 -7
  76. package/dist/{sprout-4WAYBUVV.js → sprout-ZY5QGOEL.js} +1 -1
  77. package/dist/{src-O4PRLMKM.js → src-JAOVXO5W.js} +1 -0
  78. package/dist/{src-TJ7RBU5H.js → src-XFY3XDD6.js} +24 -19
  79. package/dist/{src-L2Z7X5UT.js → src-YH6PQ7LJ.js} +264 -52
  80. package/dist/{status-WTU2WHXY.js → status-E5DQNCAO.js} +5 -5
  81. package/dist/system-chat-4DQZOEZI.js +34 -0
  82. package/dist/{tailscale-Q7ZJL7S7.js → tailscale-QAWVKQKU.js} +2 -2
  83. package/dist/{turn-tracker-2GMKJQTN.js → turn-tracker-RWZMY7M6.js} +5 -5
  84. package/dist/{up-7RSBEKW6.js → up-FLCDR2UB.js} +6 -6
  85. package/dist/{update-EJ7Q77ZX.js → update-7TYVH5FM.js} +5 -5
  86. package/dist/{update-check-ACYYNKTW.js → update-check-VSCSJ7KX.js} +3 -3
  87. package/dist/{version-notify-DCAIXXZB.js → version-notify-B67N35A3.js} +17 -17
  88. package/dist/web-assets/assets/{index-DTDmEfPU.js → index-Domoz5Cg.js} +8 -8
  89. package/dist/web-assets/assets/index-dJdNzAPn.css +1 -0
  90. package/dist/web-assets/ext-theme.css +5 -0
  91. package/dist/web-assets/index.html +2 -2
  92. package/package.json +1 -1
  93. package/packages/extensions/notes/dist/ui/assets/{index-BbgANhFm.js → index-D0-DgYyj.js} +1 -1
  94. package/packages/extensions/notes/dist/ui/index.html +1 -1
  95. package/packages/extensions/notes/skills/notes/SKILL.md +31 -3
  96. package/packages/extensions/pages/dist/ui/assets/{index-Dxk-DYrf.js → index-CQjEQg1r.js} +1 -1
  97. package/packages/extensions/pages/dist/ui/index.html +1 -1
  98. package/templates/_base/.init/.local/hooks/startup-context.ts +25 -0
  99. package/templates/claude/src/agent.ts +16 -2
  100. package/templates/claude/src/lib/message-channel.ts +28 -6
  101. package/dist/delivery-manager-5J2BE22P.js +0 -32
  102. package/dist/echo-text-XKBJM6RV.js +0 -32
  103. package/dist/message-delivery-WJBZFALY.js +0 -34
  104. package/dist/mind-service-ZBVUMJ5H.js +0 -36
  105. package/dist/scheduler-BR6C6B3E.js +0 -30
  106. package/dist/sleep-manager-BVU5D2AE.js +0 -34
  107. package/dist/system-chat-KMQIP7VH.js +0 -34
  108. package/dist/web-assets/assets/index-D7udpBCx.css +0 -1
package/dist/daemon.js CHANGED
@@ -6,21 +6,25 @@ import {
6
6
  rejectPending,
7
7
  stageFile,
8
8
  validateFilePath
9
- } from "./chunk-2HIVYZDB.js";
9
+ } from "./chunk-UMI4UIJG.js";
10
10
  import {
11
11
  findOpenClawSession,
12
12
  importOpenClawConnectors,
13
13
  importPiSession,
14
14
  parseNameFromIdentity
15
- } from "./chunk-JVK6QQIC.js";
15
+ } from "./chunk-LAXUUY7O.js";
16
16
  import {
17
17
  checkForUpdate,
18
18
  checkForUpdateCached,
19
19
  getCurrentVersion
20
- } from "./chunk-AD46AYZQ.js";
20
+ } from "./chunk-2BONPXAF.js";
21
+ import {
22
+ normalizeAvatar,
23
+ safeResolveWithinBase
24
+ } from "./chunk-SQL7M4HJ.js";
21
25
  import {
22
26
  isHomeOnlyArchive
23
- } from "./chunk-GZJFC76M.js";
27
+ } from "./chunk-QMJJWTNL.js";
24
28
  import {
25
29
  computeTemplateHash
26
30
  } from "./chunk-QMJCNZ6C.js";
@@ -30,7 +34,7 @@ import {
30
34
  fixModelEscapes,
31
35
  getPlatformDriver,
32
36
  routeOutboundBridge
33
- } from "./chunk-FZ5TH5PF.js";
37
+ } from "./chunk-EQZD4YU3.js";
34
38
  import {
35
39
  getBridgeConfig,
36
40
  readBridgesConfig,
@@ -39,7 +43,7 @@ import {
39
43
  resolveChannelMapping,
40
44
  setBridgeConfig,
41
45
  setChannelMapping
42
- } from "./chunk-57LBQ7JX.js";
46
+ } from "./chunk-FHWUQZXE.js";
43
47
  import {
44
48
  MindStartupError,
45
49
  RestartTracker,
@@ -48,6 +52,7 @@ import {
48
52
  announceToSystem,
49
53
  authMiddleware,
50
54
  checkHealth,
55
+ checkStaleSend,
51
56
  cleanExpiredSessions,
52
57
  clearDeliveredNotices,
53
58
  createSession,
@@ -56,6 +61,7 @@ import {
56
61
  deliverMessage,
57
62
  drainNotices,
58
63
  ensureSystemChannel,
64
+ formatHoldNotice,
59
65
  formatNotices,
60
66
  generateSystemReply,
61
67
  getAllDiscoveredExtensions,
@@ -98,15 +104,15 @@ import {
98
104
  syncProviderToMinds,
99
105
  uninstallNpmExtension,
100
106
  writeSystemsConfig
101
- } from "./chunk-PF2AB7VJ.js";
107
+ } from "./chunk-OMETFX5H.js";
102
108
  import {
103
109
  loadMergedEnv,
104
110
  mindEnvPath,
105
111
  readEnv,
106
112
  sharedEnvPath,
107
113
  writeEnv
108
- } from "./chunk-XDTKJNW5.js";
109
- import "./chunk-65OLHBCL.js";
114
+ } from "./chunk-5GT7URXJ.js";
115
+ import "./chunk-7FT24JBQ.js";
110
116
  import {
111
117
  applyInitFiles,
112
118
  applyTemplateHomeFiles,
@@ -135,7 +141,7 @@ import {
135
141
  syncBuiltinSkills,
136
142
  uninstallSkill,
137
143
  updateSkill
138
- } from "./chunk-FSSUANZJ.js";
144
+ } from "./chunk-I2Y2YHIO.js";
139
145
  import {
140
146
  addMessage,
141
147
  createChannel,
@@ -167,7 +173,7 @@ import {
167
173
  setConversationPrivate,
168
174
  subscribe as subscribe2,
169
175
  updateChannelSettings
170
- } from "./chunk-K4EHBHPE.js";
176
+ } from "./chunk-FZMEVCWC.js";
171
177
  import {
172
178
  readVoluteConfig,
173
179
  writeVoluteConfig
@@ -175,15 +181,15 @@ import {
175
181
  import {
176
182
  isSandboxEnabled,
177
183
  wrapForSandbox
178
- } from "./chunk-C6ESRQZ7.js";
184
+ } from "./chunk-3GYVW2X3.js";
179
185
  import {
180
186
  getActiveMinds,
181
187
  onMindEvent,
182
188
  stopAll
183
- } from "./chunk-M3PGGSBH.js";
189
+ } from "./chunk-HVU45COX.js";
184
190
  import {
185
191
  extractTextContent
186
- } from "./chunk-SPLPKBES.js";
192
+ } from "./chunk-5AHYQHNT.js";
187
193
  import {
188
194
  PROMPT_DEFAULTS,
189
195
  PROMPT_KEYS,
@@ -206,8 +212,8 @@ import {
206
212
  summarizeTurn,
207
213
  takeErrored,
208
214
  trackToolUse
209
- } from "./chunk-3WLWKOGM.js";
210
- import "./chunk-ATEX3ZPG.js";
215
+ } from "./chunk-NF75HPNR.js";
216
+ import "./chunk-Q2XBKQ2D.js";
211
217
  import {
212
218
  chownMindDir,
213
219
  createMindUser,
@@ -218,7 +224,7 @@ import {
218
224
  isIsolationEnabled,
219
225
  resolveVoluteBin,
220
226
  wrapForIsolation
221
- } from "./chunk-PGPLCJPK.js";
227
+ } from "./chunk-3ERIL673.js";
222
228
  import {
223
229
  addCustomModel,
224
230
  buildCustomModel,
@@ -239,12 +245,12 @@ import {
239
245
  setProviderRefreshHook,
240
246
  setUtilityModel,
241
247
  unqualifyModelId
242
- } from "./chunk-YSV3VJQK.js";
248
+ } from "./chunk-J47TIYHA.js";
243
249
  import {
244
250
  isSetupComplete,
245
251
  readGlobalConfig,
246
252
  writeGlobalConfig
247
- } from "./chunk-ONM2AZFL.js";
253
+ } from "./chunk-PNV24SEP.js";
248
254
  import {
249
255
  approveUser,
250
256
  changePassword,
@@ -263,11 +269,11 @@ import {
263
269
  syncMindProfile,
264
270
  updateUserProfile,
265
271
  verifyUser
266
- } from "./chunk-EFL5UOY4.js";
272
+ } from "./chunk-CYI534DJ.js";
267
273
  import {
268
274
  broadcast,
269
275
  subscribe
270
- } from "./chunk-7G2EEYXX.js";
276
+ } from "./chunk-ZMIMSIIT.js";
271
277
  import {
272
278
  logBuffer,
273
279
  logger_default
@@ -299,7 +305,7 @@ import {
299
305
  validateMindName,
300
306
  voluteHome,
301
307
  voluteSystemDir
302
- } from "./chunk-YAMO2U3N.js";
308
+ } from "./chunk-H7IYFRAL.js";
303
309
  import {
304
310
  activity,
305
311
  channels,
@@ -310,14 +316,14 @@ import {
310
316
  systemPrompts,
311
317
  turns,
312
318
  users
313
- } from "./chunk-L3IV23ZG.js";
319
+ } from "./chunk-ZV7MFISX.js";
314
320
  import "./chunk-K3NQKI34.js";
315
321
 
316
322
  // packages/daemon/src/daemon.ts
317
323
  import { randomBytes as randomBytes2 } from "crypto";
318
324
  import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
319
325
  import { homedir as homedir3 } from "os";
320
- import { resolve as resolve17 } from "path";
326
+ import { resolve as resolve16 } from "path";
321
327
  import { format } from "util";
322
328
 
323
329
  // packages/daemon/src/lib/daemon/bridge-manager.ts
@@ -527,8 +533,8 @@ var BridgeManager = class {
527
533
  if (!tracked) return;
528
534
  this.stopping.add(platform);
529
535
  this.bridges.delete(platform);
530
- await new Promise((resolve18) => {
531
- tracked.child.on("exit", () => resolve18());
536
+ await new Promise((resolve17) => {
537
+ tracked.child.on("exit", () => resolve17());
532
538
  try {
533
539
  if (tracked.child.pid) {
534
540
  process.kill(-tracked.child.pid, "SIGTERM");
@@ -539,7 +545,7 @@ var BridgeManager = class {
539
545
  if (err instanceof Error && err.code !== "ESRCH") {
540
546
  blog.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
541
547
  }
542
- resolve18();
548
+ resolve17();
543
549
  }
544
550
  setTimeout(() => {
545
551
  try {
@@ -550,7 +556,7 @@ var BridgeManager = class {
550
556
  }
551
557
  } catch {
552
558
  }
553
- resolve18();
559
+ resolve17();
554
560
  }, 5e3);
555
561
  });
556
562
  this.stopping.delete(platform);
@@ -870,10 +876,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
870
876
  stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
871
877
  });
872
878
  });
873
- await new Promise((resolve18) => {
879
+ await new Promise((resolve17) => {
874
880
  stream.onAbort(() => {
875
881
  unsubscribe();
876
- resolve18();
882
+ resolve17();
877
883
  });
878
884
  });
879
885
  });
@@ -1217,8 +1223,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
1217
1223
  createdAt: Date.now()
1218
1224
  };
1219
1225
  oauthFlows.set(flowId, flow);
1220
- const promptPromise = needsManualCode ? new Promise((resolve18) => {
1221
- flow.resolveCode = resolve18;
1226
+ const promptPromise = needsManualCode ? new Promise((resolve17) => {
1227
+ flow.resolveCode = resolve17;
1222
1228
  }) : void 0;
1223
1229
  oauthProvider.login({
1224
1230
  onAuth: (info) => {
@@ -1257,7 +1263,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
1257
1263
  existing.error = err instanceof Error ? err.message : String(err);
1258
1264
  }
1259
1265
  });
1260
- await new Promise((resolve18) => setTimeout(resolve18, 2e3));
1266
+ await new Promise((resolve17) => setTimeout(resolve17, 2e3));
1261
1267
  const state = oauthFlows.get(flowId);
1262
1268
  return c.json({
1263
1269
  flowId,
@@ -1515,8 +1521,8 @@ var app2 = new Hono2().get("/events", async (c) => {
1515
1521
  });
1516
1522
  }, 15e3);
1517
1523
  cleanups.push(() => clearInterval(keepAlive));
1518
- await new Promise((resolve18) => {
1519
- stream.onAbort(() => resolve18());
1524
+ await new Promise((resolve17) => {
1525
+ stream.onAbort(() => resolve17());
1520
1526
  });
1521
1527
  } finally {
1522
1528
  for (const cleanup of cleanups) {
@@ -1531,12 +1537,24 @@ var app2 = new Hono2().get("/events", async (c) => {
1531
1537
  var activity_default = app2;
1532
1538
 
1533
1539
  // packages/daemon/src/web/api/auth.ts
1534
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync2 } from "fs";
1540
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync, statSync, writeFileSync as writeFileSync2 } from "fs";
1535
1541
  import { extname, resolve as resolve3 } from "path";
1536
1542
  import { zValidator as zValidator2 } from "@hono/zod-validator";
1537
1543
  import { Hono as Hono3 } from "hono";
1538
1544
  import { deleteCookie, getCookie, setCookie } from "hono/cookie";
1539
1545
  import { z as z2 } from "zod";
1546
+
1547
+ // packages/daemon/src/lib/util/http-cache.ts
1548
+ function fileEtag(stat3) {
1549
+ return `W/"${stat3.mtimeMs.toString(36)}-${stat3.size.toString(36)}"`;
1550
+ }
1551
+ function isNotModified(c, etag) {
1552
+ const inm = c.req.header("if-none-match");
1553
+ if (!inm) return false;
1554
+ return inm.split(",").some((t) => t.trim() === etag);
1555
+ }
1556
+
1557
+ // packages/daemon/src/web/api/auth.ts
1540
1558
  function tryJoinSystem(userId) {
1541
1559
  if (!process.env.VOLUTE_DAEMON_TOKEN) return;
1542
1560
  joinSystemChannel(userId).catch(() => {
@@ -1603,10 +1621,16 @@ var authenticated = new Hono3().use(authMiddleware).post("/change-password", zVa
1603
1621
  if (!AVATAR_MIME[ext]) {
1604
1622
  return c.json({ error: "Invalid file type (png, jpg, gif, webp only)" }, 400);
1605
1623
  }
1624
+ let buffer2 = Buffer.from(await file.arrayBuffer());
1625
+ let finalExt = ext;
1626
+ const normalized = await normalizeAvatar(buffer2);
1627
+ if (normalized) {
1628
+ buffer2 = normalized.buffer;
1629
+ finalExt = normalized.ext;
1630
+ }
1606
1631
  const dir = avatarsDir();
1607
1632
  mkdirSync2(dir, { recursive: true });
1608
- const filename = `avatar-${user.id}${ext}`;
1609
- const buffer2 = Buffer.from(await file.arrayBuffer());
1633
+ const filename = `avatar-${user.id}${finalExt}`;
1610
1634
  writeFileSync2(resolve3(dir, filename), buffer2);
1611
1635
  if (user.avatar && user.avatar !== filename) {
1612
1636
  const oldPath = resolve3(dir, user.avatar);
@@ -1786,12 +1810,17 @@ var app3 = new Hono3().post("/register", zValidator2("json", credentialsSchema),
1786
1810
  const ext = extname(filename).toLowerCase();
1787
1811
  const mime = AVATAR_MIME[ext];
1788
1812
  if (!mime) return c.json({ error: "Invalid file type" }, 400);
1789
- const data = readFileSync3(filePath);
1790
- return c.body(data, 200, {
1813
+ const fileStat = statSync(filePath);
1814
+ const etag = fileEtag(fileStat);
1815
+ const headers = {
1791
1816
  "Content-Type": mime,
1792
1817
  "Cache-Control": "public, max-age=3600",
1793
- "X-Content-Type-Options": "nosniff"
1794
- });
1818
+ "X-Content-Type-Options": "nosniff",
1819
+ ETag: etag
1820
+ };
1821
+ if (isNotModified(c, etag)) return c.body(null, 304, headers);
1822
+ const data = readFileSync3(filePath);
1823
+ return c.body(data, 200, headers);
1795
1824
  }).route("/", admin).route("/", authenticated);
1796
1825
  var auth_default = app3;
1797
1826
 
@@ -1847,17 +1876,6 @@ async function findOrCreatePuppet(platform, platformId, displayName) {
1847
1876
  }
1848
1877
 
1849
1878
  // packages/daemon/src/lib/delivery/fan-out.ts
1850
- var MAX_CONSECUTIVE_MIND_TURNS = 6;
1851
- var consecutiveMindTurns = /* @__PURE__ */ new Map();
1852
- async function emitLoopNotice(conversationId) {
1853
- const systemUser = await getOrCreateSystemUser();
1854
- await addMessage(conversationId, "user", systemUser.username, [
1855
- {
1856
- type: "text",
1857
- text: `[System] This exchange has continued for ${MAX_CONSECUTIVE_MIND_TURNS} consecutive automated turns without human input, so automatic delivery between minds has been paused. Send a message to resume.`
1858
- }
1859
- ]);
1860
- }
1861
1879
  async function fanOutToMinds(opts) {
1862
1880
  const participants = opts.participants ?? await getParticipants(opts.conversationId);
1863
1881
  const mindParticipants = participants.filter(
@@ -1865,25 +1883,6 @@ async function fanOutToMinds(opts) {
1865
1883
  );
1866
1884
  const participantNames = participants.map((p) => p.username);
1867
1885
  const isDM = opts.isDM ?? participants.length === 2;
1868
- if (mindParticipants.length > 1) {
1869
- if (opts.senderIsMind) {
1870
- const count = (consecutiveMindTurns.get(opts.conversationId) ?? 0) + 1;
1871
- consecutiveMindTurns.set(opts.conversationId, count);
1872
- if (count > MAX_CONSECUTIVE_MIND_TURNS) {
1873
- if (count === MAX_CONSECUTIVE_MIND_TURNS + 1) {
1874
- await emitLoopNotice(opts.conversationId).catch(
1875
- (err) => logger_default.warn(`failed to emit loop notice for ${opts.conversationId}`, logger_default.errorData(err))
1876
- );
1877
- }
1878
- logger_default.warn(
1879
- `loop protection: paused mind fan-out for ${opts.conversationId} after ${count} consecutive mind turns`
1880
- );
1881
- return;
1882
- }
1883
- } else {
1884
- consecutiveMindTurns.delete(opts.conversationId);
1885
- }
1886
- }
1887
1886
  const manager = getMindManager();
1888
1887
  const sm = getSleepManagerIfReady();
1889
1888
  const targetMinds = mindParticipants.map((ap) => {
@@ -1989,7 +1988,7 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
1989
1988
  }
1990
1989
  const participants = await getParticipants(channel.id);
1991
1990
  if (!participants.some((p) => p.userId === puppet.id)) {
1992
- const { addParticipant } = await import("./conversations-67WWW25C.js");
1991
+ const { addParticipant } = await import("./conversations-WAJYZKOC.js");
1993
1992
  await addParticipant(channel.id, puppet.id);
1994
1993
  }
1995
1994
  const contentBlocks = body.content;
@@ -2083,7 +2082,6 @@ async function fanOutToBridgedMinds(opts) {
2083
2082
  conversationId: opts.conversationId,
2084
2083
  contentBlocks: opts.contentBlocks,
2085
2084
  senderName: opts.senderName,
2086
- senderIsMind: false,
2087
2085
  isDM: opts.isDM
2088
2086
  });
2089
2087
  }
@@ -2267,14 +2265,14 @@ var app7 = new Hono8().get("/", (c) => {
2267
2265
  var extensions_default = app7;
2268
2266
 
2269
2267
  // packages/daemon/src/web/api/file-sharing.ts
2270
- import { readFileSync as readFileSync4, statSync } from "fs";
2268
+ import { readFileSync as readFileSync4, statSync as statSync2 } from "fs";
2271
2269
  import { resolve as resolve4 } from "path";
2272
2270
  import { Hono as Hono9 } from "hono";
2273
2271
  async function notifyMind(mindName, message) {
2274
2272
  const entry = await findMind(mindName);
2275
2273
  if (!entry) return;
2276
2274
  try {
2277
- const { sendSystemMessage } = await import("./system-chat-KMQIP7VH.js");
2275
+ const { sendSystemMessage } = await import("./system-chat-4DQZOEZI.js");
2278
2276
  await sendSystemMessage(mindName, message);
2279
2277
  } catch (err) {
2280
2278
  logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
@@ -2295,7 +2293,7 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
2295
2293
  const senderDir = mindDir(senderName);
2296
2294
  const filePath = resolve4(senderDir, "home", body.filePath);
2297
2295
  const MAX_FILE_SIZE3 = 50 * 1024 * 1024;
2298
- const stat3 = statSync(filePath, { throwIfNoEntry: false });
2296
+ const stat3 = statSync2(filePath, { throwIfNoEntry: false });
2299
2297
  if (!stat3) return c.json({ error: `File not found: ${body.filePath}` }, 404);
2300
2298
  if (stat3.size > MAX_FILE_SIZE3) {
2301
2299
  return c.json(
@@ -2399,34 +2397,8 @@ var file_sharing_default = app8;
2399
2397
  // packages/daemon/src/web/api/files.ts
2400
2398
  import { mkdirSync as mkdirSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
2401
2399
  import { readdir, readFile, realpath, stat } from "fs/promises";
2402
- import { extname as extname2, resolve as resolve6 } from "path";
2400
+ import { extname as extname2, resolve as resolve5 } from "path";
2403
2401
  import { Hono as Hono10 } from "hono";
2404
-
2405
- // packages/daemon/src/lib/util/paths.ts
2406
- import { resolve as resolve5, sep } from "path";
2407
- var PathTraversalError = class extends Error {
2408
- constructor(base, userPath) {
2409
- super(`Path "${userPath}" escapes base directory "${base}"`);
2410
- this.name = "PathTraversalError";
2411
- }
2412
- };
2413
- function resolveWithinBase(base, userPath) {
2414
- const resolvedBase = resolve5(base);
2415
- const target = resolve5(resolvedBase, userPath);
2416
- if (target !== resolvedBase && !target.startsWith(resolvedBase + sep)) {
2417
- throw new PathTraversalError(base, userPath);
2418
- }
2419
- return target;
2420
- }
2421
- function safeResolveWithinBase(base, userPath) {
2422
- try {
2423
- return resolveWithinBase(base, userPath);
2424
- } catch {
2425
- return null;
2426
- }
2427
- }
2428
-
2429
- // packages/daemon/src/web/api/files.ts
2430
2402
  var AVATAR_MIME2 = {
2431
2403
  ".png": "image/png",
2432
2404
  ".jpg": "image/jpeg",
@@ -2469,17 +2441,23 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
2469
2441
  if (!AVATAR_MIME2[ext]) {
2470
2442
  return c.json({ error: "Invalid file type (png, jpg, gif, webp only)" }, 400);
2471
2443
  }
2444
+ let buffer2 = Buffer.from(await file.arrayBuffer());
2445
+ let finalExt = ext;
2446
+ const normalized = await normalizeAvatar(buffer2);
2447
+ if (normalized) {
2448
+ buffer2 = normalized.buffer;
2449
+ finalExt = normalized.ext;
2450
+ }
2472
2451
  const dir = entry.dir ?? mindDir(name);
2473
- const homeDir = resolve6(dir, "home");
2474
- const filename = `avatar${ext}`;
2475
- const avatarPath = resolve6(homeDir, filename);
2452
+ const homeDir = resolve5(dir, "home");
2453
+ const filename = `avatar${finalExt}`;
2454
+ const avatarPath = resolve5(homeDir, filename);
2476
2455
  const config2 = readVoluteConfig(dir) ?? {};
2477
2456
  const oldAvatar = config2.profile?.avatar;
2478
2457
  if (oldAvatar && oldAvatar !== filename) {
2479
2458
  const oldAvatarPath = safeResolveWithinBase(homeDir, oldAvatar);
2480
2459
  if (oldAvatarPath) rmSync2(oldAvatarPath, { force: true });
2481
2460
  }
2482
- const buffer2 = Buffer.from(await file.arrayBuffer());
2483
2461
  mkdirSync3(homeDir, { recursive: true });
2484
2462
  writeFileSync3(avatarPath, buffer2);
2485
2463
  const profile = config2.profile ?? {};
@@ -2499,8 +2477,8 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
2499
2477
  const ext = extname2(config2.profile.avatar).toLowerCase();
2500
2478
  const mime = AVATAR_MIME2[ext];
2501
2479
  if (!mime) return c.json({ error: "Invalid avatar extension" }, 400);
2502
- const homeDir = resolve6(dir, "home");
2503
- const avatarPath = resolve6(homeDir, config2.profile.avatar);
2480
+ const homeDir = resolve5(dir, "home");
2481
+ const avatarPath = resolve5(homeDir, config2.profile.avatar);
2504
2482
  if (!avatarPath.startsWith(`${homeDir}/`)) return c.json({ error: "Invalid avatar path" }, 400);
2505
2483
  let realAvatarPath;
2506
2484
  try {
@@ -2516,11 +2494,15 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
2516
2494
  try {
2517
2495
  const fileStat = await stat(realAvatarPath);
2518
2496
  if (fileStat.size > MAX_AVATAR_SIZE2) return c.json({ error: "Avatar file too large" }, 400);
2519
- const body = await readFile(realAvatarPath);
2520
- return c.body(body, 200, {
2497
+ const etag = fileEtag(fileStat);
2498
+ const headers = {
2521
2499
  "Content-Type": mime,
2522
- "Cache-Control": "public, max-age=300"
2523
- });
2500
+ "Cache-Control": "public, max-age=300",
2501
+ ETag: etag
2502
+ };
2503
+ if (isNotModified(c, etag)) return c.body(null, 304, headers);
2504
+ const body = await readFile(realAvatarPath);
2505
+ return c.body(body, 200, headers);
2524
2506
  } catch {
2525
2507
  return c.json({ error: "Failed to read avatar file" }, 500);
2526
2508
  }
@@ -2528,7 +2510,7 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
2528
2510
  const name = c.req.param("name");
2529
2511
  const entry = await findMind(name);
2530
2512
  if (!entry) return c.json({ error: "Mind not found" }, 404);
2531
- const homeDir = resolve6(entry.dir ?? mindDir(name), "home");
2513
+ const homeDir = resolve5(entry.dir ?? mindDir(name), "home");
2532
2514
  let entries;
2533
2515
  try {
2534
2516
  entries = await readdir(homeDir, { withFileTypes: true });
@@ -2543,10 +2525,10 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
2543
2525
  const name = c.req.param("name");
2544
2526
  const entry = await findMind(name);
2545
2527
  if (!entry) return c.json({ error: "Mind not found" }, 404);
2546
- const homeDir = resolve6(entry.dir ?? mindDir(name), "home");
2528
+ const homeDir = resolve5(entry.dir ?? mindDir(name), "home");
2547
2529
  const wildcard = c.req.path.replace(new RegExp(`^.*/minds/${name}/files`), "") || "/";
2548
2530
  const relativePath = wildcard.slice(1);
2549
- const requestedPath = resolve6(homeDir, relativePath);
2531
+ const requestedPath = resolve5(homeDir, relativePath);
2550
2532
  if (requestedPath !== homeDir && !requestedPath.startsWith(`${homeDir}/`))
2551
2533
  return c.text("Forbidden", 403);
2552
2534
  if (relativePath.split("/").some((seg) => seg.startsWith("."))) return c.text("Forbidden", 403);
@@ -2577,9 +2559,12 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
2577
2559
  return c.json(items);
2578
2560
  }
2579
2561
  if (fileStat.size > MAX_FILE_SIZE) return c.text("File too large", 413);
2580
- const body = await readFile(resolvedPath);
2581
2562
  const mime = MIME_TYPES[extname2(resolvedPath).toLowerCase()] || "application/octet-stream";
2582
- return c.body(body, 200, { "Content-Type": mime });
2563
+ const etag = fileEtag(fileStat);
2564
+ const headers = { "Content-Type": mime, "Cache-Control": "no-cache", ETag: etag };
2565
+ if (isNotModified(c, etag)) return c.body(null, 304, headers);
2566
+ const body = await readFile(resolvedPath);
2567
+ return c.body(body, 200, headers);
2583
2568
  });
2584
2569
  var files_default = app9;
2585
2570
 
@@ -2989,16 +2974,16 @@ import { Hono as Hono12 } from "hono";
2989
2974
  // packages/daemon/src/lib/mind/identity.ts
2990
2975
  import { createHash, generateKeyPairSync, sign, verify } from "crypto";
2991
2976
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
2992
- import { resolve as resolve7 } from "path";
2977
+ import { resolve as resolve6 } from "path";
2993
2978
  function generateIdentity(mindDir2) {
2994
- const identityDir = resolve7(mindDir2, ".mind/identity");
2979
+ const identityDir = resolve6(mindDir2, ".mind/identity");
2995
2980
  mkdirSync4(identityDir, { recursive: true });
2996
2981
  const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
2997
2982
  publicKeyEncoding: { type: "spki", format: "pem" },
2998
2983
  privateKeyEncoding: { type: "pkcs8", format: "pem" }
2999
2984
  });
3000
- const privatePath = resolve7(identityDir, "private.pem");
3001
- const publicPath = resolve7(identityDir, "public.pem");
2985
+ const privatePath = resolve6(identityDir, "private.pem");
2986
+ const publicPath = resolve6(identityDir, "public.pem");
3002
2987
  writeFileSync4(privatePath, privateKey, { mode: 384 });
3003
2988
  writeFileSync4(publicPath, publicKey, { mode: 420 });
3004
2989
  const config2 = readVoluteConfig(mindDir2) ?? {};
@@ -3013,7 +2998,7 @@ function getPublicKey(mindDir2) {
3013
2998
  const config2 = readVoluteConfig(mindDir2);
3014
2999
  const relPath = config2?.identity?.publicKey;
3015
3000
  if (!relPath) return null;
3016
- const fullPath = resolve7(mindDir2, relPath);
3001
+ const fullPath = resolve6(mindDir2, relPath);
3017
3002
  if (!existsSync4(fullPath)) return null;
3018
3003
  return readFileSync5(fullPath, "utf-8");
3019
3004
  }
@@ -3063,14 +3048,14 @@ var keys_default = app10;
3063
3048
  // packages/daemon/src/web/api/logs.ts
3064
3049
  import { spawn as spawn2 } from "child_process";
3065
3050
  import { existsSync as existsSync5 } from "fs";
3066
- import { resolve as resolve8 } from "path";
3051
+ import { resolve as resolve7 } from "path";
3067
3052
  import { Hono as Hono13 } from "hono";
3068
3053
  import { streamSSE as streamSSE3 } from "hono/streaming";
3069
3054
  var app11 = new Hono13().get("/:name/logs", requireSelf(), async (c) => {
3070
3055
  const name = c.req.param("name");
3071
3056
  const entry = await findMind(name);
3072
3057
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3073
- const logFile = resolve8(stateDir(name), "logs", "mind.log");
3058
+ const logFile = resolve7(stateDir(name), "logs", "mind.log");
3074
3059
  if (!existsSync5(logFile)) {
3075
3060
  return c.json({ error: "No log file found" }, 404);
3076
3061
  }
@@ -3089,16 +3074,16 @@ var app11 = new Hono13().get("/:name/logs", requireSelf(), async (c) => {
3089
3074
  stream.onAbort(() => {
3090
3075
  tail.kill();
3091
3076
  });
3092
- await new Promise((resolve18) => {
3093
- tail.on("exit", resolve18);
3094
- stream.onAbort(resolve18);
3077
+ await new Promise((resolve17) => {
3078
+ tail.on("exit", resolve17);
3079
+ stream.onAbort(resolve17);
3095
3080
  });
3096
3081
  });
3097
3082
  }).get("/:name/logs/tail", requireSelf(), async (c) => {
3098
3083
  const name = c.req.param("name");
3099
3084
  const entry = await findMind(name);
3100
3085
  if (!entry) return c.json({ error: "Mind not found" }, 404);
3101
- const logFile = resolve8(stateDir(name), "logs", "mind.log");
3086
+ const logFile = resolve7(stateDir(name), "logs", "mind.log");
3102
3087
  if (!existsSync5(logFile)) {
3103
3088
  return c.json({ error: "No log file found" }, 404);
3104
3089
  }
@@ -3109,8 +3094,8 @@ var app11 = new Hono13().get("/:name/logs", requireSelf(), async (c) => {
3109
3094
  tail.stdout.on("data", (data) => {
3110
3095
  output += data.toString();
3111
3096
  });
3112
- await new Promise((resolve18) => {
3113
- tail.on("exit", resolve18);
3097
+ await new Promise((resolve17) => {
3098
+ tail.on("exit", resolve17);
3114
3099
  });
3115
3100
  return c.text(output);
3116
3101
  });
@@ -3207,7 +3192,7 @@ import {
3207
3192
  rmSync as rmSync4,
3208
3193
  writeFileSync as writeFileSync7
3209
3194
  } from "fs";
3210
- import { basename, resolve as resolve11 } from "path";
3195
+ import { basename, resolve as resolve10 } from "path";
3211
3196
  import { zValidator as zValidator5 } from "@hono/zod-validator";
3212
3197
  import { and as and5, desc as desc4, eq as eq5, sql as sql3 } from "drizzle-orm";
3213
3198
  import { Hono as Hono15 } from "hono";
@@ -3427,18 +3412,18 @@ async function completeTurnAndSummarize(mind, event, insertedId) {
3427
3412
 
3428
3413
  // packages/daemon/src/lib/mind/consolidate.ts
3429
3414
  import { readdirSync, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
3430
- import { resolve as resolve9 } from "path";
3415
+ import { resolve as resolve8 } from "path";
3431
3416
  async function consolidateMemory(mindDir2) {
3432
- const soulPath = resolve9(mindDir2, "home/SOUL.md");
3433
- const memoryPath = resolve9(mindDir2, "home/MEMORY.md");
3434
- const memoryDir = resolve9(mindDir2, "home/memory");
3417
+ const soulPath = resolve8(mindDir2, "home/SOUL.md");
3418
+ const memoryPath = resolve8(mindDir2, "home/MEMORY.md");
3419
+ const memoryDir = resolve8(mindDir2, "home/memory");
3435
3420
  const soul = readFileSync6(soulPath, "utf-8");
3436
3421
  const logs = [];
3437
3422
  try {
3438
3423
  const files = readdirSync(memoryDir).filter((f) => /^\d{4}-\d{2}-\d{2}\.md$/.test(f)).sort();
3439
3424
  for (const filename of files) {
3440
3425
  const date = filename.replace(".md", "");
3441
- const content2 = readFileSync6(resolve9(memoryDir, filename), "utf-8").trim();
3426
+ const content2 = readFileSync6(resolve8(memoryDir, filename), "utf-8").trim();
3442
3427
  if (content2) {
3443
3428
  logs.push(`### ${date}
3444
3429
 
@@ -3539,7 +3524,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
3539
3524
  logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
3540
3525
  }
3541
3526
  }
3542
- const { findMind: findMind2 } = await import("./registry-7LQHTRUX.js");
3527
+ const { findMind: findMind2 } = await import("./registry-NUJAGLQJ.js");
3543
3528
  const variantEntry = await findMind2(variantName);
3544
3529
  const branchName = variantEntry?.branch ?? variantName;
3545
3530
  if (existsSync6(variantPath)) {
@@ -3591,7 +3576,7 @@ function validateBranchName(branch) {
3591
3576
  import { randomUUID } from "crypto";
3592
3577
  import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
3593
3578
  import { homedir } from "os";
3594
- import { resolve as resolve10 } from "path";
3579
+ import { resolve as resolve9 } from "path";
3595
3580
  function convertSession(opts) {
3596
3581
  const lines = readFileSync7(opts.sessionPath, "utf-8").trim().split("\n");
3597
3582
  const sessionId = randomUUID();
@@ -3707,9 +3692,9 @@ function convertSession(opts) {
3707
3692
  }
3708
3693
  }
3709
3694
  const projectId = opts.projectDir.replace(/\//g, "-");
3710
- const sdkDir = resolve10(homedir(), ".claude", "projects", projectId);
3695
+ const sdkDir = resolve9(homedir(), ".claude", "projects", projectId);
3711
3696
  mkdirSync5(sdkDir, { recursive: true });
3712
- const sdkPath = resolve10(sdkDir, `${sessionId}.jsonl`);
3697
+ const sdkPath = resolve9(sdkDir, `${sessionId}.jsonl`);
3713
3698
  writeFileSync6(sdkPath, `${sdkEvents.join("\n")}
3714
3699
  `);
3715
3700
  console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
@@ -3768,7 +3753,7 @@ async function getMindStatus(name, port, registryRunning) {
3768
3753
  const manager = getMindManager();
3769
3754
  let status = "stopped";
3770
3755
  try {
3771
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
3756
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
3772
3757
  if (getSleepManagerIfReady2()?.isSleeping(name)) {
3773
3758
  status = "sleeping";
3774
3759
  }
@@ -3814,7 +3799,7 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
3814
3799
  await gitExec(["commit", "-m", "initial commit"], opts);
3815
3800
  }
3816
3801
  async function updateTemplateBranch(projectRoot, template, mindName) {
3817
- const tempWorktree = resolve11(projectRoot, ".variants", "_template_update");
3802
+ const tempWorktree = resolve10(projectRoot, ".variants", "_template_update");
3818
3803
  let branchExists = false;
3819
3804
  try {
3820
3805
  await gitExec(["rev-parse", "--verify", TEMPLATE_BRANCH], { cwd: projectRoot });
@@ -3846,15 +3831,15 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
3846
3831
  });
3847
3832
  }
3848
3833
  copyTemplateToDir(composedDir, tempWorktree, mindName, manifest);
3849
- const initDir = resolve11(tempWorktree, ".init");
3834
+ const initDir = resolve10(tempWorktree, ".init");
3850
3835
  if (existsSync7(initDir)) {
3851
3836
  rmSync4(initDir, { recursive: true, force: true });
3852
3837
  }
3853
- const homeDir = resolve11(tempWorktree, "home");
3838
+ const homeDir = resolve10(tempWorktree, "home");
3854
3839
  if (existsSync7(homeDir)) {
3855
3840
  for (const entry of readdirSync2(homeDir)) {
3856
3841
  if (entry !== "VOLUTE.md") {
3857
- rmSync4(resolve11(homeDir, entry), { recursive: true, force: true });
3842
+ rmSync4(resolve10(homeDir, entry), { recursive: true, force: true });
3858
3843
  }
3859
3844
  }
3860
3845
  }
@@ -3895,7 +3880,7 @@ async function mergeTemplateBranch(worktreeDir) {
3895
3880
  async function npmInstallAsMind(cwd, mindName) {
3896
3881
  if (isIsolationEnabled()) {
3897
3882
  const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
3898
- await exec(cmd, args, { cwd, env: { ...process.env, HOME: resolve11(cwd, "home") } });
3883
+ await exec(cmd, args, { cwd, env: { ...process.env, HOME: resolve10(cwd, "home") } });
3899
3884
  } else {
3900
3885
  await exec("npm", ["install"], { cwd });
3901
3886
  }
@@ -3920,7 +3905,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
3920
3905
  let switchWarning;
3921
3906
  if (templateChanged) {
3922
3907
  try {
3923
- applyTemplateHomeFiles(resolve11(dir, "home"), template);
3908
+ applyTemplateHomeFiles(resolve10(dir, "home"), template);
3924
3909
  await gitExec(["add", "home/"], { cwd: dir });
3925
3910
  try {
3926
3911
  await gitExec(["diff", "--cached", "--quiet"], { cwd: dir });
@@ -3970,7 +3955,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
3970
3955
  return { ok: true, warning: switchWarning };
3971
3956
  }
3972
3957
  async function importFromArchive(c, tempDir, nameOverride, manifest) {
3973
- const extractedMindDir = resolve11(tempDir, "mind");
3958
+ const extractedMindDir = resolve10(tempDir, "mind");
3974
3959
  if (!existsSync7(extractedMindDir)) {
3975
3960
  return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
3976
3961
  }
@@ -3997,9 +3982,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
3997
3982
  }
3998
3983
  const state = stateDir(name);
3999
3984
  mkdirSync6(state, { recursive: true });
4000
- const envJson = resolve11(tempDir, "state/env.json");
3985
+ const envJson = resolve10(tempDir, "state/env.json");
4001
3986
  if (existsSync7(envJson)) {
4002
- cpSync(envJson, resolve11(state, "env.json"));
3987
+ cpSync(envJson, resolve10(state, "env.json"));
4003
3988
  }
4004
3989
  const port = await nextPort();
4005
3990
  await addMind(name, port, manifest.stage, manifest.template);
@@ -4008,23 +3993,23 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
4008
3993
  } catch (err) {
4009
3994
  logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
4010
3995
  }
4011
- const homeDir = resolve11(dest, "home");
3996
+ const homeDir = resolve10(dest, "home");
4012
3997
  ensureVoluteGroup();
4013
3998
  createMindUser(name, homeDir);
4014
3999
  await chownMindDir(dest, name);
4015
4000
  await npmInstallAsMind(dest, name);
4016
4001
  await importHistoryFromArchive(name, tempDir);
4017
4002
  importSessionsFromArchive(dest, tempDir);
4018
- if (!existsSync7(resolve11(dest, ".git"))) {
4003
+ if (!existsSync7(resolve10(dest, ".git"))) {
4019
4004
  try {
4020
- const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
4005
+ const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dest, "home") } : void 0;
4021
4006
  await gitExec(["init"], { cwd: dest, mindName: name, env });
4022
4007
  await configureGitIdentity(name, { cwd: dest, mindName: name, env });
4023
4008
  await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
4024
4009
  await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
4025
4010
  } catch (err) {
4026
4011
  logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
4027
- rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
4012
+ rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
4028
4013
  }
4029
4014
  }
4030
4015
  await chownMindDir(dest, name);
@@ -4057,22 +4042,22 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4057
4042
  try {
4058
4043
  copyTemplateToDir(composedDir, dest, name, templateManifest);
4059
4044
  applyInitFiles(dest);
4060
- const extractedHome = resolve11(extractedMindDir, "home");
4045
+ const extractedHome = resolve10(extractedMindDir, "home");
4061
4046
  if (existsSync7(extractedHome)) {
4062
- cpSync(extractedHome, resolve11(dest, "home"), { recursive: true });
4047
+ cpSync(extractedHome, resolve10(dest, "home"), { recursive: true });
4063
4048
  }
4064
- const extractedMindInternal = resolve11(extractedMindDir, ".mind");
4049
+ const extractedMindInternal = resolve10(extractedMindDir, ".mind");
4065
4050
  if (existsSync7(extractedMindInternal)) {
4066
- cpSync(extractedMindInternal, resolve11(dest, ".mind"), { recursive: true });
4051
+ cpSync(extractedMindInternal, resolve10(dest, ".mind"), { recursive: true });
4067
4052
  }
4068
- const identityDir = resolve11(dest, ".mind/identity");
4053
+ const identityDir = resolve10(dest, ".mind/identity");
4069
4054
  let publicKeyPem;
4070
- if (!manifest.includes.identity || !existsSync7(resolve11(identityDir, "private.pem"))) {
4055
+ if (!manifest.includes.identity || !existsSync7(resolve10(identityDir, "private.pem"))) {
4071
4056
  ({ publicKeyPem } = generateIdentity(dest));
4072
4057
  } else {
4073
- publicKeyPem = readFileSync8(resolve11(identityDir, "public.pem"), "utf-8");
4058
+ publicKeyPem = readFileSync8(resolve10(identityDir, "public.pem"), "utf-8");
4074
4059
  }
4075
- const promptsPath = resolve11(dest, "home/.config/prompts.json");
4060
+ const promptsPath = resolve10(dest, "home/.config/prompts.json");
4076
4061
  if (!existsSync7(promptsPath)) {
4077
4062
  const mindPrompts = await getMindPromptDefaults();
4078
4063
  writeFileSync7(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
@@ -4080,13 +4065,13 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4080
4065
  }
4081
4066
  const state = stateDir(name);
4082
4067
  mkdirSync6(state, { recursive: true });
4083
- const envJson = resolve11(tempDir, "state/env.json");
4068
+ const envJson = resolve10(tempDir, "state/env.json");
4084
4069
  if (existsSync7(envJson)) {
4085
- cpSync(envJson, resolve11(state, "env.json"));
4070
+ cpSync(envJson, resolve10(state, "env.json"));
4086
4071
  }
4087
4072
  const port = await nextPort();
4088
4073
  await addMind(name, port, manifest.stage, manifest.template);
4089
- const homeDir = resolve11(dest, "home");
4074
+ const homeDir = resolve10(dest, "home");
4090
4075
  ensureVoluteGroup();
4091
4076
  createMindUser(name, homeDir);
4092
4077
  await chownMindDir(dest, name);
@@ -4099,7 +4084,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4099
4084
  await initTemplateBranch(dest, composedDir, templateManifest, name, env);
4100
4085
  } catch (err) {
4101
4086
  logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
4102
- rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
4087
+ rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
4103
4088
  gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
4104
4089
  }
4105
4090
  const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
@@ -4142,7 +4127,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
4142
4127
  }
4143
4128
  }
4144
4129
  async function importHistoryFromArchive(name, tempDir) {
4145
- const historyJsonl = resolve11(tempDir, "history.jsonl");
4130
+ const historyJsonl = resolve10(tempDir, "history.jsonl");
4146
4131
  if (!existsSync7(historyJsonl)) return;
4147
4132
  try {
4148
4133
  const db = await getDb();
@@ -4182,13 +4167,13 @@ async function importHistoryFromArchive(name, tempDir) {
4182
4167
  }
4183
4168
  }
4184
4169
  function importSessionsFromArchive(dest, tempDir) {
4185
- const sessionsDir = resolve11(tempDir, "sessions");
4170
+ const sessionsDir = resolve10(tempDir, "sessions");
4186
4171
  if (!existsSync7(sessionsDir)) return;
4187
4172
  try {
4188
- const destSessions = resolve11(dest, ".mind/sessions");
4173
+ const destSessions = resolve10(dest, ".mind/sessions");
4189
4174
  mkdirSync6(destSessions, { recursive: true });
4190
4175
  for (const file of readdirSync2(sessionsDir)) {
4191
- cpSync(resolve11(sessionsDir, file), resolve11(destSessions, file));
4176
+ cpSync(resolve10(sessionsDir, file), resolve10(destSessions, file));
4192
4177
  }
4193
4178
  } catch (err) {
4194
4179
  logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
@@ -4263,7 +4248,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4263
4248
  applyInitFiles(dest);
4264
4249
  const { publicKeyPem } = generateIdentity(dest);
4265
4250
  {
4266
- const { readGlobalConfig: readGlobal } = await import("./setup-25MMJ3J4.js");
4251
+ const { readGlobalConfig: readGlobal } = await import("./setup-MLRKNP7Y.js");
4267
4252
  const mindDefaults = readGlobal().mindDefaults;
4268
4253
  const config2 = readVoluteConfig(dest);
4269
4254
  if (!config2) throw new Error("Failed to read volute.json after identity generation");
@@ -4300,7 +4285,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4300
4285
  }
4301
4286
  writeVoluteConfig(dest, config2);
4302
4287
  const modelId = body.model ?? cog?.model;
4303
- const sdkConfigPath = resolve11(dest, "home/.config/config.json");
4288
+ const sdkConfigPath = resolve10(dest, "home/.config/config.json");
4304
4289
  if (modelId || cog?.compaction) {
4305
4290
  const existing = existsSync7(sdkConfigPath) ? JSON.parse(readFileSync8(sdkConfigPath, "utf-8")) : {};
4306
4291
  if (modelId) {
@@ -4315,7 +4300,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4315
4300
  }
4316
4301
  const mindPrompts = await getMindPromptDefaults();
4317
4302
  writeFileSync7(
4318
- resolve11(dest, "home/.config/prompts.json"),
4303
+ resolve10(dest, "home/.config/prompts.json"),
4319
4304
  `${JSON.stringify(mindPrompts, null, 2)}
4320
4305
  `
4321
4306
  );
@@ -4327,7 +4312,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4327
4312
  } catch (err) {
4328
4313
  logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
4329
4314
  }
4330
- const homeDir = resolve11(dest, "home");
4315
+ const homeDir = resolve10(dest, "home");
4331
4316
  ensureVoluteGroup();
4332
4317
  createMindUser(name, homeDir);
4333
4318
  await chownMindDir(dest, name);
@@ -4340,7 +4325,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
4340
4325
  await initTemplateBranch(dest, composedDir, manifest, name, env);
4341
4326
  } catch (err) {
4342
4327
  logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
4343
- rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
4328
+ rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
4344
4329
  gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
4345
4330
  }
4346
4331
  await chownMindDir(dest, name);
@@ -4350,11 +4335,11 @@ The human who planted you described you as: "${body.description}"
4350
4335
  ` : "";
4351
4336
  const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
4352
4337
  const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
4353
- writeFileSync7(resolve11(dest, "home/SOUL.md"), seedSoul);
4338
+ writeFileSync7(resolve10(dest, "home/SOUL.md"), seedSoul);
4354
4339
  }
4355
4340
  let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
4356
4341
  if (body.stage === "seed" && !body.skills) {
4357
- const { isImagegenEnabled } = await import("./setup-25MMJ3J4.js");
4342
+ const { isImagegenEnabled } = await import("./setup-MLRKNP7Y.js");
4358
4343
  if (isImagegenEnabled()) {
4359
4344
  skillSet = [...skillSet, "imagegen"];
4360
4345
  }
@@ -4372,7 +4357,7 @@ The human who planted you described you as: "${body.description}"
4372
4357
  try {
4373
4358
  const spiritEntry = await findMind("volute");
4374
4359
  if (spiritEntry) {
4375
- const { spiritDir } = await import("./spirit-JQQHUVWR.js");
4360
+ const { spiritDir } = await import("./spirit-IK5OYWMV.js");
4376
4361
  const sDir = spiritEntry.dir ?? spiritDir();
4377
4362
  const spiritConfig = readVoluteConfig(sDir) ?? {};
4378
4363
  const schedules = spiritConfig.schedules ?? [];
@@ -4387,7 +4372,7 @@ The human who planted you described you as: "${body.description}"
4387
4372
  });
4388
4373
  spiritConfig.schedules = schedules;
4389
4374
  writeVoluteConfig(sDir, spiritConfig);
4390
- const { getScheduler: getScheduler2 } = await import("./scheduler-BR6C6B3E.js");
4375
+ const { getScheduler: getScheduler2 } = await import("./scheduler-CXWQ6Z4E.js");
4391
4376
  getScheduler2().loadSchedules("volute", sDir);
4392
4377
  }
4393
4378
  }
@@ -4398,11 +4383,11 @@ The human who planted you described you as: "${body.description}"
4398
4383
  if (body.stage !== "seed") {
4399
4384
  const customSoul = await getPromptIfCustom("default_soul");
4400
4385
  if (customSoul) {
4401
- writeFileSync7(resolve11(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
4386
+ writeFileSync7(resolve10(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
4402
4387
  }
4403
4388
  const customMemory = await getPromptIfCustom("default_memory");
4404
4389
  if (customMemory) {
4405
- writeFileSync7(resolve11(dest, "home/MEMORY.md"), customMemory);
4390
+ writeFileSync7(resolve10(dest, "home/MEMORY.md"), customMemory);
4406
4391
  }
4407
4392
  }
4408
4393
  publishPublicKey(name, publicKeyPem).catch(
@@ -4451,12 +4436,12 @@ The human who planted you described you as: "${body.description}"
4451
4436
  return importFromArchive(c, body.archivePath, body.name, body.manifest);
4452
4437
  }
4453
4438
  const wsDir = body.workspacePath;
4454
- if (!wsDir || !existsSync7(resolve11(wsDir, "SOUL.md")) || !existsSync7(resolve11(wsDir, "IDENTITY.md"))) {
4439
+ if (!wsDir || !existsSync7(resolve10(wsDir, "SOUL.md")) || !existsSync7(resolve10(wsDir, "IDENTITY.md"))) {
4455
4440
  return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
4456
4441
  }
4457
- const soul = readFileSync8(resolve11(wsDir, "SOUL.md"), "utf-8");
4458
- const identity = readFileSync8(resolve11(wsDir, "IDENTITY.md"), "utf-8");
4459
- const userPath = resolve11(wsDir, "USER.md");
4442
+ const soul = readFileSync8(resolve10(wsDir, "SOUL.md"), "utf-8");
4443
+ const identity = readFileSync8(resolve10(wsDir, "IDENTITY.md"), "utf-8");
4444
+ const userPath = resolve10(wsDir, "USER.md");
4460
4445
  const user = existsSync7(userPath) ? readFileSync8(userPath, "utf-8") : "";
4461
4446
  const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
4462
4447
  const template = body.template ?? "claude";
@@ -4484,26 +4469,26 @@ ${user.trimEnd()}
4484
4469
  copyTemplateToDir(composedDir, dest, name, manifest);
4485
4470
  applyInitFiles(dest);
4486
4471
  const { publicKeyPem: importPublicKey } = generateIdentity(dest);
4487
- writeFileSync7(resolve11(dest, "home/SOUL.md"), mergedSoul);
4488
- const wsMemoryPath = resolve11(wsDir, "MEMORY.md");
4472
+ writeFileSync7(resolve10(dest, "home/SOUL.md"), mergedSoul);
4473
+ const wsMemoryPath = resolve10(wsDir, "MEMORY.md");
4489
4474
  const hasMemory = existsSync7(wsMemoryPath);
4490
4475
  if (hasMemory) {
4491
4476
  const existingMemory = readFileSync8(wsMemoryPath, "utf-8");
4492
4477
  writeFileSync7(
4493
- resolve11(dest, "home/MEMORY.md"),
4478
+ resolve10(dest, "home/MEMORY.md"),
4494
4479
  `${existingMemory.trimEnd()}${mergedMemoryExtra}`
4495
4480
  );
4496
4481
  } else if (user) {
4497
- writeFileSync7(resolve11(dest, "home/MEMORY.md"), `${user.trimEnd()}
4482
+ writeFileSync7(resolve10(dest, "home/MEMORY.md"), `${user.trimEnd()}
4498
4483
  `);
4499
4484
  }
4500
- const wsMemoryDir = resolve11(wsDir, "memory");
4485
+ const wsMemoryDir = resolve10(wsDir, "memory");
4501
4486
  let dailyLogCount = 0;
4502
4487
  if (existsSync7(wsMemoryDir)) {
4503
- const destMemoryDir = resolve11(dest, "home/memory");
4488
+ const destMemoryDir = resolve10(dest, "home/memory");
4504
4489
  const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
4505
4490
  for (const file of files) {
4506
- cpSync(resolve11(wsMemoryDir, file), resolve11(destMemoryDir, file));
4491
+ cpSync(resolve10(wsMemoryDir, file), resolve10(destMemoryDir, file));
4507
4492
  }
4508
4493
  dailyLogCount = files.length;
4509
4494
  }
@@ -4514,7 +4499,7 @@ ${user.trimEnd()}
4514
4499
  } catch (err) {
4515
4500
  logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
4516
4501
  }
4517
- const homeDir = resolve11(dest, "home");
4502
+ const homeDir = resolve10(dest, "home");
4518
4503
  ensureVoluteGroup();
4519
4504
  createMindUser(name, homeDir);
4520
4505
  await chownMindDir(dest, name);
@@ -4522,20 +4507,20 @@ ${user.trimEnd()}
4522
4507
  if (!hasMemory && dailyLogCount > 0) {
4523
4508
  await consolidateMemory(dest);
4524
4509
  }
4525
- const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
4510
+ const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dest, "home") } : void 0;
4526
4511
  await gitExec(["init"], { cwd: dest, mindName: name, env });
4527
4512
  await configureGitIdentity(name, { cwd: dest, mindName: name, env });
4528
4513
  await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
4529
4514
  await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
4530
- const sessionFile = body.sessionPath ? resolve11(body.sessionPath) : findOpenClawSession(wsDir);
4515
+ const sessionFile = body.sessionPath ? resolve10(body.sessionPath) : findOpenClawSession(wsDir);
4531
4516
  if (sessionFile && existsSync7(sessionFile)) {
4532
4517
  if (template === "pi") {
4533
4518
  importPiSession(sessionFile, dest);
4534
4519
  } else if (template === "claude") {
4535
4520
  const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
4536
- const mindRuntimeDir = resolve11(dest, ".mind");
4521
+ const mindRuntimeDir = resolve10(dest, ".mind");
4537
4522
  mkdirSync6(mindRuntimeDir, { recursive: true });
4538
- writeFileSync7(resolve11(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
4523
+ writeFileSync7(resolve10(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
4539
4524
  }
4540
4525
  }
4541
4526
  importOpenClawConnectors(name, dest);
@@ -4576,7 +4561,7 @@ ${user.trimEnd()}
4576
4561
  const minds = await Promise.all(
4577
4562
  entries.map(async (entry) => {
4578
4563
  const mindStatus = await getMindStatus(entry.name, entry.port, entry.running);
4579
- const hasPages = existsSync7(resolve11(mindDir(entry.name), "home", "pages"));
4564
+ const hasPages = existsSync7(resolve10(mindDir(entry.name), "home", "pages"));
4580
4565
  return {
4581
4566
  ...entry,
4582
4567
  ...mindStatus,
@@ -4605,7 +4590,7 @@ ${user.trimEnd()}
4605
4590
  return { name: s.name, port: s.port, status: variantStatus };
4606
4591
  })
4607
4592
  );
4608
- const hasPages = existsSync7(resolve11(mindDir(name), "home", "pages"));
4593
+ const hasPages = existsSync7(resolve10(mindDir(name), "home", "pages"));
4609
4594
  return c.json({ ...entry, ...mindStatus, variants: variantStatuses, hasPages });
4610
4595
  }).get("/:name/context", requireSelf(), async (c) => proxyToMind(c, "context")).get("/:name/context/messages", requireSelf(), async (c) => proxyToMind(c, "context/messages")).post("/:name/start", requireSelf(), async (c) => {
4611
4596
  const name = c.req.param("name");
@@ -4652,7 +4637,7 @@ ${user.trimEnd()}
4652
4637
  const manager = getMindManager();
4653
4638
  try {
4654
4639
  if (context?.type === "reload") {
4655
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
4640
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
4656
4641
  const sleepState = getSleepManagerIfReady2()?.getState(name);
4657
4642
  if (sleepState?.sleeping) {
4658
4643
  logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
@@ -4779,7 +4764,7 @@ ${user.trimEnd()}
4779
4764
  const name = c.req.param("name");
4780
4765
  const entry = await findMind(name);
4781
4766
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4782
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
4767
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
4783
4768
  const sm = getSleepManagerIfReady2();
4784
4769
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4785
4770
  return c.json(sm.getState(name));
@@ -4787,7 +4772,7 @@ ${user.trimEnd()}
4787
4772
  const name = c.req.param("name");
4788
4773
  const entry = await findMind(name);
4789
4774
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4790
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
4775
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
4791
4776
  const sm = getSleepManagerIfReady2();
4792
4777
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4793
4778
  if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
@@ -4807,7 +4792,7 @@ ${user.trimEnd()}
4807
4792
  const name = c.req.param("name");
4808
4793
  const entry = await findMind(name);
4809
4794
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4810
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
4795
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
4811
4796
  const sm = getSleepManagerIfReady2();
4812
4797
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4813
4798
  const sleepState = sm.getState(name);
@@ -4822,7 +4807,7 @@ ${user.trimEnd()}
4822
4807
  const name = c.req.param("name");
4823
4808
  const entry = await findMind(name);
4824
4809
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4825
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
4810
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
4826
4811
  const sm = getSleepManagerIfReady2();
4827
4812
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4828
4813
  const flushed = await sm.flushQueuedMessages(name);
@@ -4840,7 +4825,7 @@ ${user.trimEnd()}
4840
4825
  if (body.avatar !== void 0) profile.avatar = basename(body.avatar);
4841
4826
  config2.profile = profile;
4842
4827
  writeVoluteConfig(dir, config2);
4843
- const { syncMindProfile: syncMindProfile2 } = await import("./auth-3RIG6GKN.js");
4828
+ const { syncMindProfile: syncMindProfile2 } = await import("./auth-FRZJVQCS.js");
4844
4829
  await syncMindProfile2(name, profile);
4845
4830
  broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
4846
4831
  return c.json({ ok: true });
@@ -4880,14 +4865,14 @@ ${user.trimEnd()}
4880
4865
  return c.json({ output: "" });
4881
4866
  }
4882
4867
  const dir = entry.dir ?? mindDir(name);
4883
- const soulPath = resolve11(dir, "home/SOUL.md");
4884
- const memoryPath = resolve11(dir, "home/MEMORY.md");
4868
+ const soulPath = resolve10(dir, "home/SOUL.md");
4869
+ const memoryPath = resolve10(dir, "home/MEMORY.md");
4885
4870
  const soulCustom = existsSync7(soulPath) && !readFileSync8(soulPath, "utf-8").includes(ORIENTATION_MARKER);
4886
4871
  const memoryWritten = existsSync7(memoryPath) && readFileSync8(memoryPath, "utf-8").trim().length > 0;
4887
4872
  const config2 = readVoluteConfig(dir);
4888
4873
  const displayNameSet = !!config2?.profile?.displayName;
4889
4874
  const avatarSet = !!config2?.profile?.avatar;
4890
- const { isImagegenEnabled } = await import("./setup-25MMJ3J4.js");
4875
+ const { isImagegenEnabled } = await import("./setup-MLRKNP7Y.js");
4891
4876
  const imagegenEnabled = isImagegenEnabled();
4892
4877
  const done = [];
4893
4878
  const remaining = [];
@@ -4925,7 +4910,7 @@ ${user.trimEnd()}
4925
4910
  try {
4926
4911
  const spiritEntry = await findMind("volute");
4927
4912
  if (spiritEntry) {
4928
- const { spiritDir } = await import("./spirit-JQQHUVWR.js");
4913
+ const { spiritDir } = await import("./spirit-IK5OYWMV.js");
4929
4914
  const sDir = spiritEntry.dir ?? spiritDir();
4930
4915
  const spiritConfig = readVoluteConfig(sDir);
4931
4916
  if (spiritConfig?.schedules) {
@@ -4933,7 +4918,7 @@ ${user.trimEnd()}
4933
4918
  spiritConfig.schedules = spiritConfig.schedules.filter((s) => s.id !== nurtureId);
4934
4919
  if (spiritConfig.schedules.length === 0) spiritConfig.schedules = void 0;
4935
4920
  writeVoluteConfig(sDir, spiritConfig);
4936
- const { getScheduler: getScheduler2 } = await import("./scheduler-BR6C6B3E.js");
4921
+ const { getScheduler: getScheduler2 } = await import("./scheduler-CXWQ6Z4E.js");
4937
4922
  getScheduler2().loadSchedules("volute", sDir);
4938
4923
  }
4939
4924
  }
@@ -4992,16 +4977,16 @@ ${user.trimEnd()}
4992
4977
  }
4993
4978
  const UPGRADE_BRANCH = "upgrade";
4994
4979
  const upgradeVariantName = `${mindName}-upgrade`;
4995
- const worktreeDir = resolve11(dir, ".variants", UPGRADE_BRANCH);
4980
+ const worktreeDir = resolve10(dir, ".variants", UPGRADE_BRANCH);
4996
4981
  if (body.abort) {
4997
4982
  if (!existsSync7(worktreeDir)) {
4998
4983
  return c.json({ error: "No upgrade in progress" }, 400);
4999
4984
  }
5000
4985
  try {
5001
4986
  try {
5002
- const gitDirContent = readFileSync8(resolve11(worktreeDir, ".git"), "utf-8").trim();
4987
+ const gitDirContent = readFileSync8(resolve10(worktreeDir, ".git"), "utf-8").trim();
5003
4988
  const gitDir = gitDirContent.replace("gitdir: ", "");
5004
- if (existsSync7(resolve11(gitDir, "MERGE_HEAD"))) {
4989
+ if (existsSync7(resolve10(gitDir, "MERGE_HEAD"))) {
5005
4990
  await gitExec(["merge", "--abort"], { cwd: worktreeDir });
5006
4991
  }
5007
4992
  } catch {
@@ -5085,7 +5070,7 @@ ${user.trimEnd()}
5085
5070
  }
5086
5071
  if (body.diff) {
5087
5072
  try {
5088
- if (!existsSync7(resolve11(dir, ".git"))) {
5073
+ if (!existsSync7(resolve10(dir, ".git"))) {
5089
5074
  return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
5090
5075
  }
5091
5076
  await updateTemplateBranch(dir, template, mindName);
@@ -5109,16 +5094,16 @@ ${user.trimEnd()}
5109
5094
  409
5110
5095
  );
5111
5096
  }
5112
- if (!existsSync7(resolve11(dir, ".git"))) {
5097
+ if (!existsSync7(resolve10(dir, ".git"))) {
5113
5098
  try {
5114
- const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dir, "home") } : void 0;
5099
+ const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dir, "home") } : void 0;
5115
5100
  await gitExec(["init"], { cwd: dir, mindName, env });
5116
5101
  await configureGitIdentity(mindName, { cwd: dir, mindName, env });
5117
5102
  await gitExec(["add", "-A"], { cwd: dir, mindName, env });
5118
5103
  await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
5119
5104
  await chownMindDir(dir, mindName);
5120
5105
  } catch (err) {
5121
- rmSync4(resolve11(dir, ".git"), { recursive: true, force: true });
5106
+ rmSync4(resolve10(dir, ".git"), { recursive: true, force: true });
5122
5107
  return c.json(
5123
5108
  {
5124
5109
  error: `Git initialization failed: ${err instanceof Error ? err.message : String(err)}`
@@ -5133,7 +5118,7 @@ ${user.trimEnd()}
5133
5118
  } catch {
5134
5119
  }
5135
5120
  await updateTemplateBranch(dir, template, mindName);
5136
- const parentDir = resolve11(dir, ".variants");
5121
+ const parentDir = resolve10(dir, ".variants");
5137
5122
  if (!existsSync7(parentDir)) {
5138
5123
  mkdirSync6(parentDir, { recursive: true });
5139
5124
  }
@@ -5267,7 +5252,7 @@ ${user.trimEnd()}
5267
5252
  if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
5268
5253
  let config2 = readVoluteConfig(dir);
5269
5254
  if (!config2 && entry.template === "pi") {
5270
- const piConfigPath = resolve11(dir, "home/.config/config.json");
5255
+ const piConfigPath = resolve10(dir, "home/.config/config.json");
5271
5256
  if (existsSync7(piConfigPath)) {
5272
5257
  try {
5273
5258
  config2 = JSON.parse(readFileSync8(piConfigPath, "utf-8"));
@@ -5276,7 +5261,7 @@ ${user.trimEnd()}
5276
5261
  }
5277
5262
  }
5278
5263
  let templateConfig = {};
5279
- const configJsonPath = resolve11(dir, "home/.config/config.json");
5264
+ const configJsonPath = resolve10(dir, "home/.config/config.json");
5280
5265
  if (existsSync7(configJsonPath)) {
5281
5266
  try {
5282
5267
  templateConfig = JSON.parse(readFileSync8(configJsonPath, "utf-8"));
@@ -5368,12 +5353,12 @@ ${user.trimEnd()}
5368
5353
  }
5369
5354
  writeVoluteConfig(dir, existing);
5370
5355
  if (body.unescapeNewlines !== void 0) {
5371
- const { clearEchoTextCache } = await import("./echo-text-XKBJM6RV.js");
5356
+ const { clearEchoTextCache } = await import("./echo-text-T7ZA5EYD.js");
5372
5357
  clearEchoTextCache(name);
5373
5358
  }
5374
5359
  const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.maxThinkingTokens !== void 0 || body.compaction !== void 0;
5375
5360
  if (needsConfigJson) {
5376
- const configJsonPath = resolve11(dir, "home/.config/config.json");
5361
+ const configJsonPath = resolve10(dir, "home/.config/config.json");
5377
5362
  let templateConfig = {};
5378
5363
  if (existsSync7(configJsonPath)) {
5379
5364
  try {
@@ -5445,7 +5430,7 @@ ${user.trimEnd()}
5445
5430
  }
5446
5431
  if (entry.mindType === "spirit" && body.model !== void 0) {
5447
5432
  try {
5448
- const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-25MMJ3J4.js");
5433
+ const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-MLRKNP7Y.js");
5449
5434
  const globalConfig = readGlobalConfig2();
5450
5435
  globalConfig.spiritModel = body.model;
5451
5436
  writeGlobalConfig2(globalConfig);
@@ -5473,7 +5458,7 @@ ${user.trimEnd()}
5473
5458
  if (!body.systemPrompt || !body.message) {
5474
5459
  return c.json({ error: "systemPrompt and message required" }, 400);
5475
5460
  }
5476
- const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-FBCCEYF5.js");
5461
+ const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-7PHSRDMO.js");
5477
5462
  if (!isAiConfigured()) {
5478
5463
  return c.json({ error: "AI service not configured" }, 503);
5479
5464
  }
@@ -6058,7 +6043,7 @@ var app15 = new Hono17().get("/:name/clock/status", requireSelf(), async (c) =>
6058
6043
  const body = await c.req.text();
6059
6044
  const message = `[webhook: ${event}] ${body}`;
6060
6045
  try {
6061
- const { sendSystemMessage } = await import("./system-chat-KMQIP7VH.js");
6046
+ const { sendSystemMessage } = await import("./system-chat-4DQZOEZI.js");
6062
6047
  await sendSystemMessage(name, message);
6063
6048
  return c.json({ ok: true });
6064
6049
  } catch (err) {
@@ -6071,14 +6056,14 @@ var schedules_default = app15;
6071
6056
  // packages/daemon/src/web/api/setup.ts
6072
6057
  import { mkdirSync as mkdirSync7 } from "fs";
6073
6058
  import { homedir as homedir2 } from "os";
6074
- import { resolve as resolve12 } from "path";
6059
+ import { resolve as resolve11 } from "path";
6075
6060
  import { Hono as Hono18 } from "hono";
6076
6061
  import { setCookie as setCookie2 } from "hono/cookie";
6077
6062
  var DEFAULT_API_URL2 = "https://volute.systems";
6078
6063
  var setup = new Hono18();
6079
6064
  function writeSetupConfig(systemName, description) {
6080
- const configHome = process.env.VOLUTE_HOME ?? resolve12(homedir2(), ".volute");
6081
- const mindsDir = resolve12(configHome, "minds");
6065
+ const configHome = process.env.VOLUTE_HOME ?? resolve11(homedir2(), ".volute");
6066
+ const mindsDir = resolve11(configHome, "minds");
6082
6067
  mkdirSync7(configHome, { recursive: true });
6083
6068
  mkdirSync7(mindsDir, { recursive: true });
6084
6069
  const existingConfig = readGlobalConfig();
@@ -6112,7 +6097,7 @@ setup.get("/status", async (c) => {
6112
6097
  let hasAccount = false;
6113
6098
  if (hasSystem) {
6114
6099
  try {
6115
- const { listUsersByType: listUsersByType2 } = await import("./auth-3RIG6GKN.js");
6100
+ const { listUsersByType: listUsersByType2 } = await import("./auth-FRZJVQCS.js");
6116
6101
  const brains = await listUsersByType2("brain");
6117
6102
  hasAccount = brains.length > 0;
6118
6103
  } catch (err) {
@@ -6323,7 +6308,7 @@ setup.post("/account", async (c) => {
6323
6308
  }
6324
6309
  }
6325
6310
  try {
6326
- const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-3RIG6GKN.js");
6311
+ const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-FRZJVQCS.js");
6327
6312
  const user = await createUser2(body.username.trim(), body.password);
6328
6313
  if (body.displayName?.trim()) {
6329
6314
  await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
@@ -6369,7 +6354,7 @@ setup.post("/models", async (c) => {
6369
6354
  return c.json({ error: "Spirit model is required" }, 400);
6370
6355
  }
6371
6356
  try {
6372
- const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-FBCCEYF5.js");
6357
+ const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-7PHSRDMO.js");
6373
6358
  setEnabledModels3(body.models);
6374
6359
  const config2 = readGlobalConfig();
6375
6360
  config2.spiritModel = body.spiritModel.trim();
@@ -6387,15 +6372,15 @@ setup.post("/complete", async (c) => {
6387
6372
  return c.json({ error: "Setup already complete" }, 400);
6388
6373
  }
6389
6374
  try {
6390
- const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-JQQHUVWR.js");
6391
- const { startSpiritFull } = await import("./mind-service-ZBVUMJ5H.js");
6375
+ const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-IK5OYWMV.js");
6376
+ const { startSpiritFull } = await import("./mind-service-S3SY7HAM.js");
6392
6377
  await ensureSpiritProject();
6393
6378
  await syncSpiritTemplate();
6394
6379
  const warnings = [];
6395
6380
  const config2 = readGlobalConfig();
6396
6381
  if (config2.setup?.service && config2.setup?.type === "local") {
6397
6382
  try {
6398
- const { installUserService } = await import("./service-install-SHRM6NHK.js");
6383
+ const { installUserService } = await import("./service-install-4QNUDKLM.js");
6399
6384
  const installed = await installUserService(config2.port, config2.hostname);
6400
6385
  if (!installed) {
6401
6386
  warnings.push("Service installation is not supported on this platform.");
@@ -6423,8 +6408,8 @@ setup.post("/complete", async (c) => {
6423
6408
  }
6424
6409
  let spiritConversationId;
6425
6410
  try {
6426
- const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-3RIG6GKN.js");
6427
- const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-67WWW25C.js");
6411
+ const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-FRZJVQCS.js");
6412
+ const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-WAJYZKOC.js");
6428
6413
  const spiritUser = await getOrCreateMindUser2("volute");
6429
6414
  const brains = await listUsersByType2("brain");
6430
6415
  const admin2 = brains.find((u) => u.role === "admin");
@@ -6446,8 +6431,8 @@ setup.post("/complete", async (c) => {
6446
6431
  logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
6447
6432
  if (spiritConversationId && spiritStarted) {
6448
6433
  try {
6449
- const { deliverMessage: deliverMessage2 } = await import("./message-delivery-WJBZFALY.js");
6450
- const { listUsersByType: listUsers2 } = await import("./auth-3RIG6GKN.js");
6434
+ const { deliverMessage: deliverMessage2 } = await import("./message-delivery-2EA5LLMD.js");
6435
+ const { listUsersByType: listUsers2 } = await import("./auth-FRZJVQCS.js");
6451
6436
  const admins = await listUsers2("brain");
6452
6437
  const admin2 = admins.find((u) => u.role === "admin");
6453
6438
  const adminName = admin2?.display_name || admin2?.username || "the admin";
@@ -6486,7 +6471,7 @@ var setup_default = setup;
6486
6471
  // packages/daemon/src/web/api/skills.ts
6487
6472
  import { existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
6488
6473
  import { tmpdir } from "os";
6489
- import { join, resolve as resolve13 } from "path";
6474
+ import { join, resolve as resolve12 } from "path";
6490
6475
  import AdmZip from "adm-zip";
6491
6476
  import { Hono as Hono19 } from "hono";
6492
6477
  var app16 = new Hono19().get("/", async (c) => {
@@ -6562,7 +6547,7 @@ var app16 = new Hono19().get("/", async (c) => {
6562
6547
  try {
6563
6548
  const zip = new AdmZip(buffer2);
6564
6549
  for (const entry of zip.getEntries()) {
6565
- const target = resolve13(tmpDir, entry.entryName);
6550
+ const target = resolve12(tmpDir, entry.entryName);
6566
6551
  if (!target.startsWith(tmpDir)) {
6567
6552
  return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
6568
6553
  }
@@ -6924,8 +6909,8 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
6924
6909
  });
6925
6910
  }, 15e3);
6926
6911
  cleanups.push(() => clearInterval(keepAlive));
6927
- await new Promise((resolve18) => {
6928
- stream.onAbort(() => resolve18());
6912
+ await new Promise((resolve17) => {
6913
+ stream.onAbort(() => resolve17());
6929
6914
  });
6930
6915
  } finally {
6931
6916
  for (const cleanup of cleanups) {
@@ -6941,15 +6926,15 @@ var events_default = app20;
6941
6926
 
6942
6927
  // packages/daemon/src/web/api/variants.ts
6943
6928
  import { existsSync as existsSync9, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
6944
- import { resolve as resolve15 } from "path";
6929
+ import { resolve as resolve14 } from "path";
6945
6930
  import { Hono as Hono24 } from "hono";
6946
6931
 
6947
6932
  // packages/daemon/src/lib/mind/spawn-server.ts
6948
6933
  import { spawn as spawn4 } from "child_process";
6949
6934
  import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync9 } from "fs";
6950
- import { resolve as resolve14 } from "path";
6935
+ import { resolve as resolve13 } from "path";
6951
6936
  function tsxBin(cwd) {
6952
- return resolve14(cwd, "node_modules", ".bin", "tsx");
6937
+ return resolve13(cwd, "node_modules", ".bin", "tsx");
6953
6938
  }
6954
6939
  async function spawnServer(cwd, port, options) {
6955
6940
  let cmd = tsxBin(cwd);
@@ -6971,31 +6956,31 @@ function spawnAttached(cmd, args, cwd) {
6971
6956
  cwd,
6972
6957
  stdio: ["ignore", "pipe", "pipe"]
6973
6958
  });
6974
- return new Promise((resolve18) => {
6975
- const timeout = setTimeout(() => resolve18(null), 3e4);
6959
+ return new Promise((resolve17) => {
6960
+ const timeout = setTimeout(() => resolve17(null), 3e4);
6976
6961
  function checkOutput(data) {
6977
6962
  const match = data.toString().match(/listening on :(\d+)/);
6978
6963
  if (match) {
6979
6964
  clearTimeout(timeout);
6980
- resolve18({ child, actualPort: parseInt(match[1], 10) });
6965
+ resolve17({ child, actualPort: parseInt(match[1], 10) });
6981
6966
  }
6982
6967
  }
6983
6968
  child.stdout?.on("data", checkOutput);
6984
6969
  child.stderr?.on("data", checkOutput);
6985
6970
  child.on("error", () => {
6986
6971
  clearTimeout(timeout);
6987
- resolve18(null);
6972
+ resolve17(null);
6988
6973
  });
6989
6974
  child.on("exit", () => {
6990
6975
  clearTimeout(timeout);
6991
- resolve18(null);
6976
+ resolve17(null);
6992
6977
  });
6993
6978
  });
6994
6979
  }
6995
6980
  function spawnDetached(cmd, args, cwd, logDir) {
6996
- const logsDir = logDir ?? resolve14(cwd, ".mind", "logs");
6981
+ const logsDir = logDir ?? resolve13(cwd, ".mind", "logs");
6997
6982
  mkdirSync8(logsDir, { recursive: true });
6998
- const logPath = resolve14(logsDir, "mind.log");
6983
+ const logPath = resolve13(logsDir, "mind.log");
6999
6984
  const logFd = openSync(logPath, "a");
7000
6985
  const child = spawn4(cmd, args, {
7001
6986
  cwd,
@@ -7111,11 +7096,11 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7111
7096
  return c.json({ error: `Name already in use: ${variantName}` }, 409);
7112
7097
  }
7113
7098
  const projectRoot = mindDir(mindName);
7114
- const variantDir = resolve15(projectRoot, ".variants", variantName);
7099
+ const variantDir = resolve14(projectRoot, ".variants", variantName);
7115
7100
  if (existsSync9(variantDir)) {
7116
7101
  return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
7117
7102
  }
7118
- mkdirSync9(resolve15(projectRoot, ".variants"), { recursive: true });
7103
+ mkdirSync9(resolve14(projectRoot, ".variants"), { recursive: true });
7119
7104
  try {
7120
7105
  await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
7121
7106
  } catch (e) {
@@ -7128,7 +7113,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7128
7113
  const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
7129
7114
  await exec(cmd, args, {
7130
7115
  cwd: variantDir,
7131
- env: { ...process.env, HOME: resolve15(variantDir, "home") }
7116
+ env: { ...process.env, HOME: resolve14(variantDir, "home") }
7132
7117
  });
7133
7118
  } else {
7134
7119
  await exec("npm", ["install"], { cwd: variantDir });
@@ -7138,7 +7123,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7138
7123
  return c.json({ error: `npm install failed: ${msg}` }, 500);
7139
7124
  }
7140
7125
  if (body.soul) {
7141
- writeFileSync8(resolve15(variantDir, "home/SOUL.md"), body.soul);
7126
+ writeFileSync8(resolve14(variantDir, "home/SOUL.md"), body.soul);
7142
7127
  }
7143
7128
  const variantPort = body.port ?? await nextPort();
7144
7129
  await addVariant(variantName, mindName, variantPort, variantDir, variantName);
@@ -7238,7 +7223,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7238
7223
  if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
7239
7224
  try {
7240
7225
  const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-446HHH5V.js");
7241
- const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-7LQHTRUX.js");
7226
+ const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-NUJAGLQJ.js");
7242
7227
  const tmpl = parentEntry.template ?? "claude";
7243
7228
  await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
7244
7229
  } catch (err) {
@@ -7251,7 +7236,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7251
7236
  const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
7252
7237
  await exec(cmd, args, {
7253
7238
  cwd: projectRoot,
7254
- env: { ...process.env, HOME: resolve15(projectRoot, "home") }
7239
+ env: { ...process.env, HOME: resolve14(projectRoot, "home") }
7255
7240
  });
7256
7241
  } else {
7257
7242
  await exec("npm", ["install"], { cwd: projectRoot });
@@ -7579,6 +7564,19 @@ var unifiedChatApp = new Hono26().post(
7579
7564
  senderBase = await getBaseName(senderName);
7580
7565
  outboundTurnId = getActiveTurnId(senderBase, c.get("mindSession"));
7581
7566
  }
7567
+ if (senderIsMind && senderBase) {
7568
+ const gate = await checkStaleSend(senderBase, conversationId, [senderName, senderBase]);
7569
+ if (gate.held && gate.unseen) {
7570
+ const label = buildVoluteSlug({
7571
+ participants,
7572
+ mindUsername: senderName,
7573
+ conversationId,
7574
+ convType: conv.type,
7575
+ convName
7576
+ });
7577
+ return c.json({ ok: true, held: true, notice: formatHoldNotice(label, gate.unseen) });
7578
+ }
7579
+ }
7582
7580
  const message = await addMessage(conversationId, "user", senderName, contentBlocks, {
7583
7581
  turnId: outboundTurnId
7584
7582
  });
@@ -7619,7 +7617,6 @@ var unifiedChatApp = new Hono26().post(
7619
7617
  conversationId,
7620
7618
  contentBlocks,
7621
7619
  senderName,
7622
- senderIsMind: !!senderIsMind,
7623
7620
  participants,
7624
7621
  isDM,
7625
7622
  slugExtra: { convType: conv.type, convName },
@@ -7655,11 +7652,11 @@ var app23 = new Hono26().get("/:name/conversations/:id/events", async (c) => {
7655
7652
  if (!stream.aborted) console.error("[chat] SSE ping error:", err);
7656
7653
  });
7657
7654
  }, 15e3);
7658
- await new Promise((resolve18) => {
7655
+ await new Promise((resolve17) => {
7659
7656
  stream.onAbort(() => {
7660
7657
  unsubscribe();
7661
7658
  clearInterval(keepAlive);
7662
- resolve18();
7659
+ resolve17();
7663
7660
  });
7664
7661
  });
7665
7662
  });
@@ -7872,7 +7869,7 @@ var app_default = app25;
7872
7869
  import { existsSync as existsSync10 } from "fs";
7873
7870
  import { readFile as readFile2, stat as stat2 } from "fs/promises";
7874
7871
  import { createServer as createHttpsServer } from "https";
7875
- import { dirname as dirname2, extname as extname3, resolve as resolve16 } from "path";
7872
+ import { dirname as dirname2, extname as extname3, resolve as resolve15 } from "path";
7876
7873
  import { serve } from "@hono/node-server";
7877
7874
  var MIME_TYPES2 = {
7878
7875
  ".html": "text/html",
@@ -7891,7 +7888,7 @@ async function startServer({
7891
7888
  let assetsDir = "";
7892
7889
  let searchDir = dirname2(new URL(import.meta.url).pathname);
7893
7890
  for (let i = 0; i < 5; i++) {
7894
- const candidate = resolve16(searchDir, "dist", "web-assets");
7891
+ const candidate = resolve15(searchDir, "dist", "web-assets");
7895
7892
  if (existsSync10(candidate)) {
7896
7893
  assetsDir = candidate;
7897
7894
  break;
@@ -7902,7 +7899,7 @@ async function startServer({
7902
7899
  app_default.get("*", async (c) => {
7903
7900
  const urlPath = new URL(c.req.url).pathname;
7904
7901
  if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
7905
- const filePath = resolve16(assetsDir, urlPath.slice(1));
7902
+ const filePath = resolve15(assetsDir, urlPath.slice(1));
7906
7903
  if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
7907
7904
  const s = await stat2(filePath).catch(() => null);
7908
7905
  if (s?.isFile()) {
@@ -7915,7 +7912,7 @@ async function startServer({
7915
7912
  const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
7916
7913
  return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
7917
7914
  }
7918
- const indexPath = resolve16(assetsDir, "index.html");
7915
+ const indexPath = resolve15(assetsDir, "index.html");
7919
7916
  const indexStat = await stat2(indexPath).catch(() => null);
7920
7917
  if (indexStat?.isFile()) {
7921
7918
  const body = await readFile2(indexPath, "utf-8");
@@ -7932,10 +7929,10 @@ async function startServer({
7932
7929
  createServer: createHttpsServer,
7933
7930
  serverOptions: { key: tls.key, cert: tls.cert }
7934
7931
  });
7935
- await new Promise((resolve18, reject) => {
7932
+ await new Promise((resolve17, reject) => {
7936
7933
  server2.on("listening", () => {
7937
7934
  logger_default.info("Volute UI running (https)", { hostname, port });
7938
- resolve18();
7935
+ resolve17();
7939
7936
  });
7940
7937
  server2.on("error", (err) => {
7941
7938
  reject(err);
@@ -7943,13 +7940,13 @@ async function startServer({
7943
7940
  });
7944
7941
  const internalPort = port + 1;
7945
7942
  const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
7946
- await new Promise((resolve18, reject) => {
7943
+ await new Promise((resolve17, reject) => {
7947
7944
  internalServer.on("listening", () => {
7948
7945
  logger_default.info("Volute API running (http, internal)", {
7949
7946
  hostname: "127.0.0.1",
7950
7947
  port: internalPort
7951
7948
  });
7952
- resolve18();
7949
+ resolve17();
7953
7950
  });
7954
7951
  internalServer.on("error", (err) => {
7955
7952
  reject(err);
@@ -7958,10 +7955,10 @@ async function startServer({
7958
7955
  return { server: server2, internalPort };
7959
7956
  }
7960
7957
  const server = serve({ fetch: app_default.fetch, port, hostname });
7961
- await new Promise((resolve18, reject) => {
7958
+ await new Promise((resolve17, reject) => {
7962
7959
  server.on("listening", () => {
7963
7960
  logger_default.info("Volute API running (http)", { hostname, port });
7964
- resolve18();
7961
+ resolve17();
7965
7962
  });
7966
7963
  server.on("error", (err) => {
7967
7964
  reject(err);
@@ -7972,17 +7969,17 @@ async function startServer({
7972
7969
 
7973
7970
  // packages/daemon/src/daemon.ts
7974
7971
  if (!process.env.VOLUTE_HOME) {
7975
- process.env.VOLUTE_HOME = resolve17(homedir3(), ".volute");
7972
+ process.env.VOLUTE_HOME = resolve16(homedir3(), ".volute");
7976
7973
  }
7977
7974
  if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
7978
7975
  process.env.TZ = process.env.VOLUTE_TIMEZONE;
7979
7976
  }
7980
7977
  function writeDaemonConfig(systemDir, config2, token) {
7981
- const configPath = resolve17(systemDir, "daemon.json");
7978
+ const configPath = resolve16(systemDir, "daemon.json");
7982
7979
  writeFileSync9(configPath, `${JSON.stringify(config2, null, 2)}
7983
7980
  `, { mode: 420 });
7984
7981
  chmodSync(configPath, 420);
7985
- const tokenPath = resolve17(systemDir, "daemon-token");
7982
+ const tokenPath = resolve16(systemDir, "daemon-token");
7986
7983
  writeFileSync9(tokenPath, `${token}
7987
7984
  `, { mode: 384 });
7988
7985
  chmodSync(tokenPath, 384);
@@ -7993,7 +7990,7 @@ async function startDaemon(opts) {
7993
7990
  const home = voluteHome();
7994
7991
  const systemDir = voluteSystemDir();
7995
7992
  if (!opts.foreground) {
7996
- const rotatingLog = new RotatingLog(resolve17(systemDir, "daemon.log"));
7993
+ const rotatingLog = new RotatingLog(resolve16(systemDir, "daemon.log"));
7997
7994
  logger_default.setOutput((line) => rotatingLog.write(`${line}
7998
7995
  `));
7999
7996
  const write = (...args) => rotatingLog.write(`${format(...args)}
@@ -8003,26 +8000,32 @@ async function startDaemon(opts) {
8003
8000
  console.warn = write;
8004
8001
  console.info = write;
8005
8002
  }
8006
- const DAEMON_PID_PATH = resolve17(systemDir, "daemon.pid");
8007
- const DAEMON_JSON_PATH = resolve17(systemDir, "daemon.json");
8008
- const DAEMON_TOKEN_PATH = resolve17(systemDir, "daemon-token");
8003
+ const DAEMON_PID_PATH = resolve16(systemDir, "daemon.pid");
8004
+ const DAEMON_JSON_PATH = resolve16(systemDir, "daemon.json");
8005
+ const DAEMON_TOKEN_PATH = resolve16(systemDir, "daemon-token");
8009
8006
  mkdirSync10(home, { recursive: true });
8010
8007
  ensureSystemDir();
8011
- const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-25MMJ3J4.js");
8008
+ const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-MLRKNP7Y.js");
8012
8009
  migrateConfigSecrets();
8013
8010
  migrateSetupCompleted();
8014
- const { migrateAiModelQualification } = await import("./ai-service-FBCCEYF5.js");
8011
+ const { migrateAiModelQualification } = await import("./ai-service-7PHSRDMO.js");
8015
8012
  migrateAiModelQualification();
8016
- await (await import("./db-CZV62BOQ.js")).getDb();
8013
+ await (await import("./db-JFLCJCUG.js")).getDb();
8017
8014
  try {
8018
8015
  const { eq: eq8, and: and6 } = await import("drizzle-orm");
8019
- const { users: users2 } = await import("./schema-LRUTFOER.js");
8020
- const db = await (await import("./db-CZV62BOQ.js")).getDb();
8016
+ const { users: users2 } = await import("./schema-PVNG3PQM.js");
8017
+ const db = await (await import("./db-JFLCJCUG.js")).getDb();
8021
8018
  await db.update(users2).set({ role: "system" }).where(and6(eq8(users2.user_type, "system"), eq8(users2.role, "user")));
8022
8019
  } catch (err) {
8023
8020
  logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
8024
8021
  }
8025
- const { initSandbox } = await import("./sandbox-SJH3XOPZ.js");
8022
+ try {
8023
+ const { migrateAvatarSizes } = await import("./avatar-image-BNWEXSA2.js");
8024
+ await migrateAvatarSizes();
8025
+ } catch (err) {
8026
+ logger_default.warn("avatar size migration failed", logger_default.errorData(err));
8027
+ }
8028
+ const { initSandbox } = await import("./sandbox-IOPWWILM.js");
8026
8029
  await initSandbox();
8027
8030
  try {
8028
8031
  await syncBuiltinSkills();
@@ -8049,7 +8052,7 @@ async function startDaemon(opts) {
8049
8052
  logger_default.warn("failed to ensure #system channel", logger_default.errorData(err));
8050
8053
  }
8051
8054
  try {
8052
- const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-3RIG6GKN.js");
8055
+ const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-FRZJVQCS.js");
8053
8056
  await getOrCreateSystemUser2();
8054
8057
  } catch (err) {
8055
8058
  logger_default.warn(
@@ -8058,12 +8061,12 @@ async function startDaemon(opts) {
8058
8061
  );
8059
8062
  }
8060
8063
  const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes2(32).toString("hex");
8061
- const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-25MMJ3J4.js");
8064
+ const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-MLRKNP7Y.js");
8062
8065
  const globalCfg = readGlobalConfig2();
8063
8066
  let tls;
8064
8067
  if (opts.tailscale || globalCfg.tailscale) {
8065
8068
  try {
8066
- const { getTailscaleTls } = await import("./tailscale-Q7ZJL7S7.js");
8069
+ const { getTailscaleTls } = await import("./tailscale-QAWVKQKU.js");
8067
8070
  const tlsConfig = await getTailscaleTls();
8068
8071
  tls = { key: tlsConfig.key, cert: tlsConfig.cert };
8069
8072
  logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
@@ -8141,10 +8144,10 @@ async function startDaemon(opts) {
8141
8144
  await Promise.all(workers);
8142
8145
  }
8143
8146
  try {
8144
- const { isSetupComplete: isSetupComplete2 } = await import("./setup-25MMJ3J4.js");
8147
+ const { isSetupComplete: isSetupComplete2 } = await import("./setup-MLRKNP7Y.js");
8145
8148
  if (isSetupComplete2()) {
8146
- const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-JQQHUVWR.js");
8147
- const { startSpiritFull } = await import("./mind-service-ZBVUMJ5H.js");
8149
+ const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-IK5OYWMV.js");
8150
+ const { startSpiritFull } = await import("./mind-service-S3SY7HAM.js");
8148
8151
  await ensureSpiritProject();
8149
8152
  await syncSpiritTemplate();
8150
8153
  const spiritEntry = await findMind("volute");
@@ -8161,7 +8164,7 @@ async function startDaemon(opts) {
8161
8164
  bridgeManager.startBridges(daemonPort).catch((err) => {
8162
8165
  logger_default.warn("failed to start bridges", logger_default.errorData(err));
8163
8166
  });
8164
- import("./cloud-sync-FRYNWKCR.js").then(
8167
+ import("./cloud-sync-6WJ7WFYD.js").then(
8165
8168
  ({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
8166
8169
  logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
8167
8170
  })
@@ -8169,7 +8172,7 @@ async function startDaemon(opts) {
8169
8172
  logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
8170
8173
  });
8171
8174
  try {
8172
- const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-DCAIXXZB.js");
8175
+ const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-B67N35A3.js");
8173
8176
  backfillTemplateHashes();
8174
8177
  notifyVersionUpdate().catch((err) => {
8175
8178
  logger_default.warn("failed to send version update notifications", logger_default.errorData(err));