volute 0.39.0 → 0.40.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-CR4RIHJT.js → activity-events-OJZ7G5CG.js} +3 -3
  2. package/dist/{ai-service-PL7GKFQC.js → ai-service-JMV4KZN4.js} +8 -4
  3. package/dist/{archive-UEWIFRAR.js → archive-BC2MTNPV.js} +3 -3
  4. package/dist/{auth-OJ2YW3NR.js → auth-2IMZ6N5G.js} +4 -4
  5. package/dist/{chat-RQ5NV5EA.js → chat-O5QCGCUG.js} +2 -2
  6. package/dist/{chunk-TCNCRDB5.js → chunk-2AQCEQYN.js} +1 -1
  7. package/dist/{chunk-OEXOFBW5.js → chunk-3XSFMN3H.js} +1 -1
  8. package/dist/{chunk-7OS7QFDF.js → chunk-43PVCF4V.js} +3 -3
  9. package/dist/{chunk-7GZB3ZJP.js → chunk-5VBXKFPO.js} +2 -2
  10. package/dist/{chunk-IA2SZSLB.js → chunk-76Q6YLJL.js} +1 -1
  11. package/dist/{chunk-QDWPM73D.js → chunk-B7YJUWMM.js} +3 -3
  12. package/dist/{chunk-TT4WT6Y7.js → chunk-DNQPHLGM.js} +1 -1
  13. package/dist/{chunk-6FSSMAXU.js → chunk-FBV22PFY.js} +1 -1
  14. package/dist/{chunk-RAVQXKAG.js → chunk-FRJ73IWR.js} +1 -1
  15. package/dist/{chunk-WUH54G5S.js → chunk-HAJHDGBV.js} +1 -1
  16. package/dist/{chunk-X7GM2OPM.js → chunk-HEZM5GCV.js} +2 -2
  17. package/dist/{chunk-4BO4I7UF.js → chunk-JSITYTIL.js} +6 -6
  18. package/dist/{chunk-CJ26DXZL.js → chunk-MHFAWJCC.js} +16 -0
  19. package/dist/{chunk-OS5MRIEP.js → chunk-PC55DGNX.js} +1 -1
  20. package/dist/{chunk-QDWP435B.js → chunk-PDSA3ILI.js} +1 -1
  21. package/dist/{chunk-B7MWXFAH.js → chunk-PGX52NFO.js} +15 -1
  22. package/dist/{chunk-7W3UWCQD.js → chunk-PHR4XQPL.js} +3 -3
  23. package/dist/{chunk-EVKGKQ2P.js → chunk-PIRL2HAO.js} +1 -7
  24. package/dist/{chunk-Y5UC6G3O.js → chunk-PZTVQL3J.js} +2 -2
  25. package/dist/{chunk-DZ4LYU6J.js → chunk-RMZSICLS.js} +1 -1
  26. package/dist/{chunk-XOSAY7PY.js → chunk-S4YO5OWV.js} +1 -1
  27. package/dist/{chunk-6V2U3GFQ.js → chunk-SGC6CDXB.js} +2 -2
  28. package/dist/{chunk-QJ4GU5XT.js → chunk-SOPMVTTW.js} +2 -2
  29. package/dist/{chunk-IBOU6Q3Y.js → chunk-T26YLQPU.js} +5 -5
  30. package/dist/{chunk-Y4W3OS7Q.js → chunk-WGRMLXTH.js} +8 -8
  31. package/dist/{chunk-CHCISTH7.js → chunk-XUJR6NZW.js} +508 -332
  32. package/dist/cli.js +15 -15
  33. package/dist/{cloud-sync-NQCWJLYI.js → cloud-sync-5JF2Z7VM.js} +16 -16
  34. package/dist/{conversations-EUXHBWJD.js → conversations-LUVHGQSS.js} +4 -4
  35. package/dist/{create-3QH7DVLC.js → create-TDQM3SHV.js} +1 -1
  36. package/dist/{daemon-restart-UEB3PLKB.js → daemon-restart-XHDJDOPQ.js} +8 -8
  37. package/dist/daemon.js +219 -116
  38. package/dist/{db-32YFKMFL.js → db-2GIS7HSG.js} +2 -2
  39. package/dist/delivery-manager-L5WFP2ND.js +30 -0
  40. package/dist/{delivery-router-EUW4RIWG.js → delivery-router-IU4OMVKZ.js} +3 -3
  41. package/dist/down-KIJVZ3OC.js +17 -0
  42. package/dist/echo-text-TJWCUBPB.js +31 -0
  43. package/dist/{exec-2MFHTGOS.js → exec-BGMU7VXR.js} +4 -4
  44. package/dist/{export-JDAK3THX.js → export-RKUWSQSG.js} +3 -3
  45. package/dist/{extensions-V7TXKAKM.js → extensions-VN5SEVRP.js} +16 -16
  46. package/dist/{files-K5XV23H6.js → files-J2CKZ6PK.js} +3 -3
  47. package/dist/{import-GZ5IYVV7.js → import-KVY6BYXG.js} +6 -6
  48. package/dist/{isolation-FPF4UTH2.js → isolation-MM7YHK6J.js} +3 -3
  49. package/dist/{login-BGF5JY3I.js → login-OHM32QVD.js} +2 -2
  50. package/dist/{logout-GQHI6KH6.js → logout-74WBDMOE.js} +2 -2
  51. package/dist/{message-delivery-X7MKA3TA.js → message-delivery-VBBAJX3J.js} +16 -16
  52. package/dist/{mind-QMJIWWWW.js → mind-PUPXDIYQ.js} +5 -5
  53. package/dist/{mind-activity-tracker-Z3KBQTVU.js → mind-activity-tracker-7GE24YZE.js} +4 -4
  54. package/dist/mind-manager-4Q6KGZHL.js +30 -0
  55. package/dist/mind-service-7OD4PRO5.js +36 -0
  56. package/dist/{package-IR4ZEQA2.js → package-6YPVWGD3.js} +1 -1
  57. package/dist/{registry-LWEOAO53.js → registry-L272BZJR.js} +2 -2
  58. package/dist/{sandbox-KUAVC37A.js → sandbox-BQAFYHLE.js} +4 -4
  59. package/dist/scheduler-7E22Q7IC.js +30 -0
  60. package/dist/{schema-K575EBPE.js → schema-HHYJDG7B.js} +3 -1
  61. package/dist/{seed-GPBERPXJ.js → seed-4V2O7FQE.js} +1 -1
  62. package/dist/{seed-cmd-PWF4FYFG.js → seed-cmd-JKDEW4MP.js} +2 -2
  63. package/dist/{seed-create-NTIICZVB.js → seed-create-EPAO3H5F.js} +3 -3
  64. package/dist/{seed-sprout-PRPFKGJF.js → seed-sprout-EONCL4DU.js} +8 -8
  65. package/dist/{send-IMHDYJHW.js → send-232RAHPX.js} +3 -3
  66. package/dist/{service-DWBRRFXS.js → service-AG5BKRUV.js} +5 -5
  67. package/dist/{service-install-KEBDNZVE.js → service-install-HVAEUBAH.js} +6 -6
  68. package/dist/{setup-IFYS3TLS.js → setup-IL7QJZN4.js} +3 -3
  69. package/dist/{setup-4CWQ53VV.js → setup-PSA7LJ5U.js} +8 -8
  70. package/dist/{skills-FJ5W73AV.js → skills-SLEY5X6W.js} +6 -6
  71. package/dist/sleep-manager-27S7MKJO.js +34 -0
  72. package/dist/{spirit-U6MDQLYT.js → spirit-7BUHSEO2.js} +8 -8
  73. package/dist/{sprout-ABX2G76C.js → sprout-JWQ57KF3.js} +1 -1
  74. package/dist/{status-C6BBWNU3.js → status-6GSOSYOD.js} +6 -6
  75. package/dist/system-chat-EIINIHFB.js +34 -0
  76. package/dist/{tailscale-2KKXDMNK.js → tailscale-6MHNLBAX.js} +2 -2
  77. package/dist/up-4XS3RCPP.js +19 -0
  78. package/dist/{update-V26PT4VN.js → update-BT2PY73H.js} +6 -6
  79. package/dist/{update-check-XRERV36Y.js → update-check-Y3HBEMF2.js} +3 -3
  80. package/dist/{version-notify-ZBMY2TEX.js → version-notify-NFQMI5IY.js} +17 -17
  81. package/dist/web-assets/assets/index-DqHSW9Fr.css +1 -0
  82. package/dist/web-assets/assets/index-Jluza4c-.js +73 -0
  83. package/dist/web-assets/index.html +2 -2
  84. package/drizzle/0009_mind_notices.sql +14 -0
  85. package/drizzle/meta/_journal.json +7 -0
  86. package/package.json +1 -1
  87. package/templates/_base/.init/.local/hooks/pre-prompt/notices.ts +46 -0
  88. package/templates/_base/src/lib/context-breakdown.ts +281 -126
  89. package/templates/_base/src/lib/daemon-client.ts +5 -2
  90. package/templates/_base/src/lib/transparency.ts +5 -3
  91. package/templates/_base/src/lib/volute-server.ts +23 -0
  92. package/templates/claude/src/agent.ts +54 -16
  93. package/templates/claude/src/server.ts +1 -0
  94. package/templates/codex/src/agent.ts +45 -12
  95. package/templates/codex/src/server.ts +1 -0
  96. package/templates/pi/src/agent.ts +72 -13
  97. package/templates/pi/src/server.ts +1 -0
  98. package/dist/delivery-manager-N34XKUGL.js +0 -30
  99. package/dist/down-TCEBGTMY.js +0 -17
  100. package/dist/echo-text-N3BC3WNX.js +0 -31
  101. package/dist/mind-manager-7GWTTKWD.js +0 -30
  102. package/dist/mind-service-MO2XJKJN.js +0 -36
  103. package/dist/scheduler-CGUPAEBA.js +0 -30
  104. package/dist/sleep-manager-6QRMUNHK.js +0 -34
  105. package/dist/system-chat-D343HYGR.js +0 -34
  106. package/dist/up-ZU6ILVMA.js +0 -19
  107. package/dist/web-assets/assets/index-B1zwqwt8.css +0 -1
  108. package/dist/web-assets/assets/index-D1guJF1i.js +0 -73
package/dist/daemon.js CHANGED
@@ -6,21 +6,21 @@ import {
6
6
  rejectPending,
7
7
  stageFile,
8
8
  validateFilePath
9
- } from "./chunk-TT4WT6Y7.js";
9
+ } from "./chunk-DNQPHLGM.js";
10
10
  import {
11
11
  findOpenClawSession,
12
12
  importOpenClawConnectors,
13
13
  importPiSession,
14
14
  parseNameFromIdentity
15
- } from "./chunk-X7GM2OPM.js";
15
+ } from "./chunk-HEZM5GCV.js";
16
16
  import {
17
17
  checkForUpdate,
18
18
  checkForUpdateCached,
19
19
  getCurrentVersion
20
- } from "./chunk-RAVQXKAG.js";
20
+ } from "./chunk-FRJ73IWR.js";
21
21
  import {
22
22
  isHomeOnlyArchive
23
- } from "./chunk-IA2SZSLB.js";
23
+ } from "./chunk-76Q6YLJL.js";
24
24
  import {
25
25
  computeTemplateHash
26
26
  } from "./chunk-KAB6UGOL.js";
@@ -30,7 +30,7 @@ import {
30
30
  fixModelEscapes,
31
31
  getPlatformDriver,
32
32
  routeOutboundBridge
33
- } from "./chunk-4BO4I7UF.js";
33
+ } from "./chunk-JSITYTIL.js";
34
34
  import {
35
35
  getBridgeConfig,
36
36
  readBridgesConfig,
@@ -39,7 +39,7 @@ import {
39
39
  resolveChannelMapping,
40
40
  setBridgeConfig,
41
41
  setChannelMapping
42
- } from "./chunk-XOSAY7PY.js";
42
+ } from "./chunk-S4YO5OWV.js";
43
43
  import {
44
44
  PROMPT_DEFAULTS,
45
45
  PROMPT_KEYS,
@@ -47,12 +47,15 @@ import {
47
47
  RotatingLog,
48
48
  announceToSystem,
49
49
  assignSession,
50
+ clearDeliveredNotices,
50
51
  completeOrphanedTurns,
51
52
  completeTurn,
52
53
  createTurn,
53
54
  deleteSystemsConfig,
54
55
  deliverMessage,
56
+ drainNotices,
55
57
  ensureSystemChannel,
58
+ formatNotices,
56
59
  generateSystemReply,
57
60
  getActiveTurnId,
58
61
  getAllDiscoveredExtensions,
@@ -81,12 +84,14 @@ import {
81
84
  joinSystemChannel,
82
85
  linkToolResultToTurn,
83
86
  loadAllExtensions,
87
+ markErrored,
84
88
  notifyExtensionsDaemonStart,
85
89
  notifyExtensionsDaemonStop,
86
90
  publish as publish2,
87
91
  publishTypingForChannels,
88
92
  readSystemsConfig,
89
93
  recordInbound,
94
+ recordNotice,
90
95
  recordOutbound,
91
96
  resolveMindToken,
92
97
  setExtensionEnabled,
@@ -97,20 +102,22 @@ import {
97
102
  substitute,
98
103
  summarizeOrphanedTurns,
99
104
  summarizeTurn,
105
+ syncProviderToMinds,
100
106
  tagUntaggedInbound,
101
107
  tagUntaggedOutbound,
108
+ takeErrored,
102
109
  trackToolUse,
103
110
  uninstallNpmExtension,
104
111
  writeSystemsConfig
105
- } from "./chunk-CHCISTH7.js";
112
+ } from "./chunk-XUJR6NZW.js";
106
113
  import {
107
114
  loadMergedEnv,
108
115
  mindEnvPath,
109
116
  readEnv,
110
117
  sharedEnvPath,
111
118
  writeEnv
112
- } from "./chunk-WUH54G5S.js";
113
- import "./chunk-Y4W3OS7Q.js";
119
+ } from "./chunk-HAJHDGBV.js";
120
+ import "./chunk-WGRMLXTH.js";
114
121
  import {
115
122
  applyInitFiles,
116
123
  composeTemplate,
@@ -137,7 +144,7 @@ import {
137
144
  syncBuiltinSkills,
138
145
  uninstallSkill,
139
146
  updateSkill
140
- } from "./chunk-IBOU6Q3Y.js";
147
+ } from "./chunk-T26YLQPU.js";
141
148
  import {
142
149
  addMessage,
143
150
  createChannel,
@@ -169,25 +176,25 @@ import {
169
176
  setConversationPrivate,
170
177
  subscribe as subscribe2,
171
178
  updateChannelSettings
172
- } from "./chunk-QDWPM73D.js";
179
+ } from "./chunk-B7YJUWMM.js";
173
180
  import {
174
181
  readVoluteConfig,
175
182
  writeVoluteConfig
176
183
  } from "./chunk-CU6OFXMM.js";
177
- import "./chunk-EVKGKQ2P.js";
184
+ import "./chunk-PIRL2HAO.js";
178
185
  import {
179
186
  getActiveMinds,
180
187
  onMindEvent,
181
188
  stopAll
182
- } from "./chunk-DZ4LYU6J.js";
189
+ } from "./chunk-RMZSICLS.js";
183
190
  import {
184
191
  extractTextContent
185
- } from "./chunk-OS5MRIEP.js";
192
+ } from "./chunk-PC55DGNX.js";
186
193
  import {
187
194
  exec,
188
195
  gitExec,
189
196
  resolveVoluteBin
190
- } from "./chunk-OEXOFBW5.js";
197
+ } from "./chunk-3XSFMN3H.js";
191
198
  import {
192
199
  chownMindDir,
193
200
  createMindUser,
@@ -195,7 +202,29 @@ import {
195
202
  ensureVoluteGroup,
196
203
  isIsolationEnabled,
197
204
  wrapForIsolation
198
- } from "./chunk-6FSSMAXU.js";
205
+ } from "./chunk-FBV22PFY.js";
206
+ import {
207
+ getAiConfig,
208
+ getAvailableModels,
209
+ getConfiguredProviders,
210
+ getEnabledModels,
211
+ getUtilityModel,
212
+ qualifyModelId,
213
+ removeAiConfig,
214
+ removeProviderConfig,
215
+ resolveApiKey,
216
+ resolveTemplate,
217
+ saveProviderConfig,
218
+ setEnabledModels,
219
+ setProviderRefreshHook,
220
+ setUtilityModel,
221
+ unqualifyModelId
222
+ } from "./chunk-PGX52NFO.js";
223
+ import {
224
+ isSetupComplete,
225
+ readGlobalConfig,
226
+ writeGlobalConfig
227
+ } from "./chunk-2AQCEQYN.js";
199
228
  import {
200
229
  approveUser,
201
230
  changePassword,
@@ -214,32 +243,11 @@ import {
214
243
  syncMindProfile,
215
244
  updateUserProfile,
216
245
  verifyUser
217
- } from "./chunk-7W3UWCQD.js";
246
+ } from "./chunk-PHR4XQPL.js";
218
247
  import {
219
248
  broadcast,
220
249
  subscribe
221
- } from "./chunk-7GZB3ZJP.js";
222
- import {
223
- getAiConfig,
224
- getAvailableModels,
225
- getConfiguredProviders,
226
- getEnabledModels,
227
- getUtilityModel,
228
- qualifyModelId,
229
- removeAiConfig,
230
- removeProviderConfig,
231
- resolveApiKey,
232
- resolveTemplate,
233
- saveProviderConfig,
234
- setEnabledModels,
235
- setUtilityModel,
236
- unqualifyModelId
237
- } from "./chunk-B7MWXFAH.js";
238
- import {
239
- isSetupComplete,
240
- readGlobalConfig,
241
- writeGlobalConfig
242
- } from "./chunk-TCNCRDB5.js";
250
+ } from "./chunk-5VBXKFPO.js";
243
251
  import {
244
252
  logBuffer,
245
253
  logger_default
@@ -269,7 +277,7 @@ import {
269
277
  validateMindName,
270
278
  voluteHome,
271
279
  voluteSystemDir
272
- } from "./chunk-QDWP435B.js";
280
+ } from "./chunk-PDSA3ILI.js";
273
281
  import {
274
282
  activity,
275
283
  channels,
@@ -281,7 +289,7 @@ import {
281
289
  systemPrompts,
282
290
  turns,
283
291
  users
284
- } from "./chunk-CJ26DXZL.js";
292
+ } from "./chunk-MHFAWJCC.js";
285
293
  import "./chunk-K3NQKI34.js";
286
294
 
287
295
  // packages/daemon/src/daemon.ts
@@ -1994,7 +2002,7 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
1994
2002
  }
1995
2003
  const participants = await getParticipants(channel.id);
1996
2004
  if (!participants.some((p) => p.userId === puppet.id)) {
1997
- const { addParticipant } = await import("./conversations-EUXHBWJD.js");
2005
+ const { addParticipant } = await import("./conversations-LUVHGQSS.js");
1998
2006
  await addParticipant(channel.id, puppet.id);
1999
2007
  }
2000
2008
  const contentBlocks = body.content;
@@ -2087,8 +2095,8 @@ async function fanOutToBridgedMinds(opts) {
2087
2095
  const participants = await getParticipants(opts.conversationId);
2088
2096
  const mindParticipants = participants.filter((p) => p.userType === "mind");
2089
2097
  const participantNames = participants.map((p) => p.username);
2090
- const { getMindManager: getMindManager2 } = await import("./mind-manager-7GWTTKWD.js");
2091
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-6QRMUNHK.js");
2098
+ const { getMindManager: getMindManager2 } = await import("./mind-manager-4Q6KGZHL.js");
2099
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-27S7MKJO.js");
2092
2100
  const manager = getMindManager2();
2093
2101
  const sm = getSleepManagerIfReady2();
2094
2102
  const targetMinds = mindParticipants.filter((ap) => {
@@ -2300,7 +2308,7 @@ async function notifyMind(mindName, message) {
2300
2308
  const entry = await findMind(mindName);
2301
2309
  if (!entry) return;
2302
2310
  try {
2303
- const { sendSystemMessage } = await import("./system-chat-D343HYGR.js");
2311
+ const { sendSystemMessage } = await import("./system-chat-EIINIHFB.js");
2304
2312
  await sendSystemMessage(mindName, message);
2305
2313
  } catch (err) {
2306
2314
  logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
@@ -3201,6 +3209,43 @@ import { and as and4, desc as desc3, eq as eq5, sql as sql2 } from "drizzle-orm"
3201
3209
  import { Hono as Hono15 } from "hono";
3202
3210
  import { z as z5 } from "zod";
3203
3211
 
3212
+ // packages/daemon/src/lib/daemon/error-classify.ts
3213
+ function classify(raw) {
3214
+ const s = (raw ?? "").toLowerCase();
3215
+ if (/\b(401|403)\b|authentication_error|invalid authentication|invalid x-api-key|unauthorized|permission_error/.test(
3216
+ s
3217
+ )) {
3218
+ return {
3219
+ reason: "auth_error",
3220
+ detail: "Your last turn failed because your model credentials were rejected (most often an expired token). The daemon refreshes them automatically, so this is normally transient \u2014 you're fine to continue."
3221
+ };
3222
+ }
3223
+ if (/\b429\b|rate.?limit|too many requests/.test(s)) {
3224
+ return {
3225
+ reason: "rate_limit",
3226
+ detail: "Your last turn failed because you hit the model provider's rate limit. This is temporary \u2014 it clears on its own shortly."
3227
+ };
3228
+ }
3229
+ if (/\b529\b|overloaded/.test(s)) {
3230
+ return {
3231
+ reason: "overloaded",
3232
+ detail: "Your last turn failed because the model provider was overloaded (a 529). This is transient and resolves on its own."
3233
+ };
3234
+ }
3235
+ if (/econnreset|etimedout|enotfound|econnrefused|fetch failed|network|socket hang up|timeout/.test(
3236
+ s
3237
+ )) {
3238
+ return {
3239
+ reason: "network",
3240
+ detail: "Your last turn failed due to a network error reaching the model provider. This is transient \u2014 the connection should recover."
3241
+ };
3242
+ }
3243
+ return {
3244
+ reason: "unknown",
3245
+ detail: `Your last turn failed with an error: ${raw}`
3246
+ };
3247
+ }
3248
+
3204
3249
  // packages/daemon/src/lib/mind/consolidate.ts
3205
3250
  import { readdirSync, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
3206
3251
  import { resolve as resolve8 } from "path";
@@ -3282,7 +3327,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
3282
3327
  logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
3283
3328
  }
3284
3329
  }
3285
- const { findMind: findMind2 } = await import("./registry-LWEOAO53.js");
3330
+ const { findMind: findMind2 } = await import("./registry-L272BZJR.js");
3286
3331
  const variantEntry = await findMind2(variantName);
3287
3332
  const branchName = variantEntry?.branch ?? variantName;
3288
3333
  if (existsSync6(variantPath)) {
@@ -3520,13 +3565,26 @@ async function checkHealth(port) {
3520
3565
 
3521
3566
  // packages/daemon/src/web/api/minds.ts
3522
3567
  var SUBSTANTIVE_TYPES = /* @__PURE__ */ new Set(["thinking", "text", "tool_use", "tool_result", "outbound"]);
3568
+ var noticeDrainWatermarks = /* @__PURE__ */ new Map();
3569
+ function markDeliveredOnCleanTurn(mind, session) {
3570
+ if (!session) return;
3571
+ const wmKey = `${mind}:${session}`;
3572
+ const watermark = noticeDrainWatermarks.get(wmKey);
3573
+ noticeDrainWatermarks.delete(wmKey);
3574
+ const errored = takeErrored(mind, session);
3575
+ if (!errored && watermark != null) {
3576
+ clearDeliveredNotices(mind, session, watermark).catch(
3577
+ (err) => logger_default.warn(`failed to clear delivered notices for ${mind}:${session}`, logger_default.errorData(err))
3578
+ );
3579
+ }
3580
+ }
3523
3581
  var _lastActiveCache = { map: /* @__PURE__ */ new Map(), ts: 0 };
3524
3582
  var _LAST_ACTIVE_TTL = 6e4;
3525
3583
  async function getMindStatus(name, port, registryRunning) {
3526
3584
  const manager = getMindManager();
3527
3585
  let status = "stopped";
3528
3586
  try {
3529
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-6QRMUNHK.js");
3587
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-27S7MKJO.js");
3530
3588
  if (getSleepManagerIfReady2()?.isSleeping(name)) {
3531
3589
  status = "sleeping";
3532
3590
  }
@@ -3948,6 +4006,38 @@ function formatTimeAgo(date) {
3948
4006
  const days = Math.floor(hours / 24);
3949
4007
  return `${days}d ago`;
3950
4008
  }
4009
+ async function proxyToMind(c, path) {
4010
+ const name = c.req.param("name");
4011
+ const entry = await findMind(name);
4012
+ if (!entry) return c.json({ error: "Mind not found" }, 404);
4013
+ if (!getMindManager().isRunning(name)) {
4014
+ return c.json({ error: "Mind is not running" }, 503);
4015
+ }
4016
+ try {
4017
+ const res = await fetch(`http://127.0.0.1:${entry.port}/${path}`, {
4018
+ signal: AbortSignal.timeout(1e4)
4019
+ });
4020
+ if (!res.ok) {
4021
+ const status = res.status >= 500 ? 502 : 404;
4022
+ return c.json(
4023
+ {
4024
+ error: res.status >= 500 ? `Mind ${path} handler errored` : `${path} endpoint not available`
4025
+ },
4026
+ status
4027
+ );
4028
+ }
4029
+ let data;
4030
+ try {
4031
+ data = await res.json();
4032
+ } catch {
4033
+ return c.json({ error: "Mind returned invalid response" }, 502);
4034
+ }
4035
+ return c.json(data);
4036
+ } catch (err) {
4037
+ console.error(`${path} proxy for ${name}:`, err);
4038
+ return c.json({ error: "Failed to reach mind" }, 503);
4039
+ }
4040
+ }
3951
4041
  var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", createMindSchema), async (c) => {
3952
4042
  const body = c.req.valid("json");
3953
4043
  const { name } = body;
@@ -3965,7 +4055,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
3965
4055
  applyInitFiles(dest);
3966
4056
  const { publicKeyPem } = generateIdentity(dest);
3967
4057
  {
3968
- const { readGlobalConfig: readGlobal } = await import("./setup-IFYS3TLS.js");
4058
+ const { readGlobalConfig: readGlobal } = await import("./setup-IL7QJZN4.js");
3969
4059
  const mindDefaults = readGlobal().mindDefaults;
3970
4060
  const config2 = readVoluteConfig(dest);
3971
4061
  if (!config2) throw new Error("Failed to read volute.json after identity generation");
@@ -4056,7 +4146,7 @@ The human who planted you described you as: "${body.description}"
4056
4146
  }
4057
4147
  let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
4058
4148
  if (body.stage === "seed" && !body.skills) {
4059
- const { isImagegenEnabled } = await import("./setup-IFYS3TLS.js");
4149
+ const { isImagegenEnabled } = await import("./setup-IL7QJZN4.js");
4060
4150
  if (isImagegenEnabled()) {
4061
4151
  skillSet = [...skillSet, "imagegen"];
4062
4152
  }
@@ -4074,7 +4164,7 @@ The human who planted you described you as: "${body.description}"
4074
4164
  try {
4075
4165
  const spiritEntry = await findMind("volute");
4076
4166
  if (spiritEntry) {
4077
- const { spiritDir } = await import("./spirit-U6MDQLYT.js");
4167
+ const { spiritDir } = await import("./spirit-7BUHSEO2.js");
4078
4168
  const sDir = spiritEntry.dir ?? spiritDir();
4079
4169
  const spiritConfig = readVoluteConfig(sDir) ?? {};
4080
4170
  const schedules = spiritConfig.schedules ?? [];
@@ -4089,7 +4179,7 @@ The human who planted you described you as: "${body.description}"
4089
4179
  });
4090
4180
  spiritConfig.schedules = schedules;
4091
4181
  writeVoluteConfig(sDir, spiritConfig);
4092
- const { getScheduler: getScheduler2 } = await import("./scheduler-CGUPAEBA.js");
4182
+ const { getScheduler: getScheduler2 } = await import("./scheduler-7E22Q7IC.js");
4093
4183
  getScheduler2().loadSchedules("volute", sDir);
4094
4184
  }
4095
4185
  }
@@ -4309,33 +4399,7 @@ ${user.trimEnd()}
4309
4399
  );
4310
4400
  const hasPages = existsSync7(resolve10(mindDir(name), "home", "pages"));
4311
4401
  return c.json({ ...entry, ...mindStatus, variants: variantStatuses, hasPages });
4312
- }).get("/:name/context", async (c) => {
4313
- const name = c.req.param("name");
4314
- const entry = await findMind(name);
4315
- if (!entry) return c.json({ error: "Mind not found" }, 404);
4316
- if (!getMindManager().isRunning(name)) {
4317
- return c.json({ error: "Mind is not running" }, 503);
4318
- }
4319
- try {
4320
- const res = await fetch(`http://127.0.0.1:${entry.port}/context`, {
4321
- signal: AbortSignal.timeout(3e3)
4322
- });
4323
- if (!res.ok) {
4324
- const status = res.status >= 500 ? 502 : 404;
4325
- return c.json(
4326
- {
4327
- error: res.status >= 500 ? "Mind context handler errored" : "Context endpoint not available"
4328
- },
4329
- status
4330
- );
4331
- }
4332
- const data = await res.json();
4333
- return c.json(data);
4334
- } catch (err) {
4335
- console.error(`context proxy for ${name}:`, err);
4336
- return c.json({ error: "Failed to reach mind" }, 503);
4337
- }
4338
- }).post("/:name/start", requireSelf(), async (c) => {
4402
+ }).get("/:name/context", async (c) => proxyToMind(c, "context")).get("/:name/context/messages", async (c) => proxyToMind(c, "context/messages")).post("/:name/start", requireSelf(), async (c) => {
4339
4403
  const name = c.req.param("name");
4340
4404
  const entry = await findMind(name);
4341
4405
  if (!entry) return c.json({ error: "Mind not found" }, 404);
@@ -4380,7 +4444,7 @@ ${user.trimEnd()}
4380
4444
  const manager = getMindManager();
4381
4445
  try {
4382
4446
  if (context?.type === "reload") {
4383
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-6QRMUNHK.js");
4447
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-27S7MKJO.js");
4384
4448
  const sleepState = getSleepManagerIfReady2()?.getState(name);
4385
4449
  if (sleepState?.sleeping) {
4386
4450
  logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
@@ -4475,7 +4539,7 @@ ${user.trimEnd()}
4475
4539
  const name = c.req.param("name");
4476
4540
  const entry = await findMind(name);
4477
4541
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4478
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-6QRMUNHK.js");
4542
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-27S7MKJO.js");
4479
4543
  const sm = getSleepManagerIfReady2();
4480
4544
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4481
4545
  return c.json(sm.getState(name));
@@ -4483,7 +4547,7 @@ ${user.trimEnd()}
4483
4547
  const name = c.req.param("name");
4484
4548
  const entry = await findMind(name);
4485
4549
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4486
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-6QRMUNHK.js");
4550
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-27S7MKJO.js");
4487
4551
  const sm = getSleepManagerIfReady2();
4488
4552
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4489
4553
  if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
@@ -4503,7 +4567,7 @@ ${user.trimEnd()}
4503
4567
  const name = c.req.param("name");
4504
4568
  const entry = await findMind(name);
4505
4569
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4506
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-6QRMUNHK.js");
4570
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-27S7MKJO.js");
4507
4571
  const sm = getSleepManagerIfReady2();
4508
4572
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4509
4573
  const sleepState = sm.getState(name);
@@ -4518,7 +4582,7 @@ ${user.trimEnd()}
4518
4582
  const name = c.req.param("name");
4519
4583
  const entry = await findMind(name);
4520
4584
  if (!entry) return c.json({ error: "Mind not found" }, 404);
4521
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-6QRMUNHK.js");
4585
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-27S7MKJO.js");
4522
4586
  const sm = getSleepManagerIfReady2();
4523
4587
  if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
4524
4588
  const flushed = await sm.flushQueuedMessages(name);
@@ -4536,7 +4600,7 @@ ${user.trimEnd()}
4536
4600
  if (body.avatar !== void 0) profile.avatar = body.avatar;
4537
4601
  config2.profile = profile;
4538
4602
  writeVoluteConfig(dir, config2);
4539
- const { syncMindProfile: syncMindProfile2 } = await import("./auth-OJ2YW3NR.js");
4603
+ const { syncMindProfile: syncMindProfile2 } = await import("./auth-2IMZ6N5G.js");
4540
4604
  await syncMindProfile2(name, profile);
4541
4605
  broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
4542
4606
  return c.json({ ok: true });
@@ -4583,7 +4647,7 @@ ${user.trimEnd()}
4583
4647
  const config2 = readVoluteConfig(dir);
4584
4648
  const displayNameSet = !!config2?.profile?.displayName;
4585
4649
  const avatarSet = !!config2?.profile?.avatar;
4586
- const { isImagegenEnabled } = await import("./setup-IFYS3TLS.js");
4650
+ const { isImagegenEnabled } = await import("./setup-IL7QJZN4.js");
4587
4651
  const imagegenEnabled = isImagegenEnabled();
4588
4652
  const done = [];
4589
4653
  const remaining = [];
@@ -4621,7 +4685,7 @@ ${user.trimEnd()}
4621
4685
  try {
4622
4686
  const spiritEntry = await findMind("volute");
4623
4687
  if (spiritEntry) {
4624
- const { spiritDir } = await import("./spirit-U6MDQLYT.js");
4688
+ const { spiritDir } = await import("./spirit-7BUHSEO2.js");
4625
4689
  const sDir = spiritEntry.dir ?? spiritDir();
4626
4690
  const spiritConfig = readVoluteConfig(sDir);
4627
4691
  if (spiritConfig?.schedules) {
@@ -4629,7 +4693,7 @@ ${user.trimEnd()}
4629
4693
  spiritConfig.schedules = spiritConfig.schedules.filter((s) => s.id !== nurtureId);
4630
4694
  if (spiritConfig.schedules.length === 0) spiritConfig.schedules = void 0;
4631
4695
  writeVoluteConfig(sDir, spiritConfig);
4632
- const { getScheduler: getScheduler2 } = await import("./scheduler-CGUPAEBA.js");
4696
+ const { getScheduler: getScheduler2 } = await import("./scheduler-7E22Q7IC.js");
4633
4697
  getScheduler2().loadSchedules("volute", sDir);
4634
4698
  }
4635
4699
  }
@@ -5058,7 +5122,7 @@ ${user.trimEnd()}
5058
5122
  }
5059
5123
  writeVoluteConfig(dir, existing);
5060
5124
  if (body.unescapeNewlines !== void 0) {
5061
- const { clearEchoTextCache } = await import("./echo-text-N3BC3WNX.js");
5125
+ const { clearEchoTextCache } = await import("./echo-text-TJWCUBPB.js");
5062
5126
  clearEchoTextCache(name);
5063
5127
  }
5064
5128
  const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.maxThinkingTokens !== void 0 || body.compaction !== void 0;
@@ -5135,7 +5199,7 @@ ${user.trimEnd()}
5135
5199
  }
5136
5200
  if (entry.mindType === "spirit" && body.model !== void 0) {
5137
5201
  try {
5138
- const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-IFYS3TLS.js");
5202
+ const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-IL7QJZN4.js");
5139
5203
  const globalConfig = readGlobalConfig2();
5140
5204
  globalConfig.spiritModel = body.model;
5141
5205
  writeGlobalConfig2(globalConfig);
@@ -5163,7 +5227,7 @@ ${user.trimEnd()}
5163
5227
  if (!body.systemPrompt || !body.message) {
5164
5228
  return c.json({ error: "systemPrompt and message required" }, 400);
5165
5229
  }
5166
- const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-PL7GKFQC.js");
5230
+ const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-JMV4KZN4.js");
5167
5231
  if (!isAiConfigured()) {
5168
5232
  return c.json({ error: "AI service not configured" }, 503);
5169
5233
  }
@@ -5270,6 +5334,18 @@ ${user.trimEnd()}
5270
5334
  const affected = map.deleteSender(baseName);
5271
5335
  publishTypingForChannels(affected, map);
5272
5336
  }
5337
+ if (body.type === "error" && body.session) {
5338
+ markErrored(baseName, body.session);
5339
+ const { reason, detail } = classify(body.content ?? "");
5340
+ await recordNotice({
5341
+ mind: baseName,
5342
+ session: body.session,
5343
+ kind: "turn_error",
5344
+ reason,
5345
+ detail,
5346
+ raw: body.content ?? null
5347
+ });
5348
+ }
5273
5349
  if (body.type === "done") {
5274
5350
  const map = getTypingMap();
5275
5351
  const affected = map.deleteSender(baseName);
@@ -5292,6 +5368,7 @@ ${user.trimEnd()}
5292
5368
  (err) => logger_default.warn("failed to tag orphaned outbound records", logger_default.errorData(err))
5293
5369
  );
5294
5370
  }
5371
+ markDeliveredOnCleanTurn(baseName, body.session);
5295
5372
  if (insertedId != null) {
5296
5373
  summarizeTurn(baseName, body.session, body.channel, insertedId, completedTurnId).catch(
5297
5374
  (err) => logger_default.error("turn summarization failed", logger_default.errorData(err))
@@ -5308,6 +5385,7 @@ ${user.trimEnd()}
5308
5385
  (err2) => logger_default.warn("failed to tag orphaned outbound records", logger_default.errorData(err2))
5309
5386
  );
5310
5387
  }
5388
+ markDeliveredOnCleanTurn(baseName, body.session);
5311
5389
  if (insertedId != null) {
5312
5390
  summarizeTurn(baseName, body.session, body.channel, insertedId, completedTurnId).catch(
5313
5391
  (err2) => logger_default.error("turn summarization failed", logger_default.errorData(err2))
@@ -5318,7 +5396,17 @@ ${user.trimEnd()}
5318
5396
  if (body.type === "usage" && body.metadata) {
5319
5397
  const inputTokens = body.metadata.input_tokens ?? 0;
5320
5398
  const outputTokens = body.metadata.output_tokens ?? 0;
5321
- getTokenBudget().recordUsage(baseName, inputTokens, outputTokens);
5399
+ const tb = getTokenBudget();
5400
+ tb.recordUsage(baseName, inputTokens, outputTokens);
5401
+ if (body.session && tb.noteExceeded(baseName)) {
5402
+ void recordNotice({
5403
+ mind: baseName,
5404
+ session: body.session,
5405
+ kind: "budget",
5406
+ reason: "token_budget",
5407
+ detail: "You've reached your token budget for this period. Further activity may be paused until the budget resets \u2014 wrap up or prioritize accordingly."
5408
+ });
5409
+ }
5322
5410
  }
5323
5411
  return c.json({ ok: true });
5324
5412
  }).get("/:name/events", async (c) => {
@@ -5498,6 +5586,16 @@ ${user.trimEnd()}
5498
5586
  });
5499
5587
  return c.json({ context: `[Session Activity]
5500
5588
  ${lines.join("\n")}` });
5589
+ }).get("/:name/history/notices", requireSelf(), async (c) => {
5590
+ const name = c.req.param("name");
5591
+ const baseName = await getBaseName(name);
5592
+ const session = c.req.query("session");
5593
+ if (!session) return c.json({ context: null, notices: [] });
5594
+ const notices = await drainNotices(baseName, session);
5595
+ if (notices.length === 0) return c.json({ context: null, notices: [] });
5596
+ const maxId = notices.reduce((m, n) => Math.max(m, n.id), 0);
5597
+ noticeDrainWatermarks.set(`${baseName}:${session}`, maxId);
5598
+ return c.json({ context: formatNotices(notices), notices });
5501
5599
  }).get("/:name/history", async (c) => {
5502
5600
  const name = c.req.param("name");
5503
5601
  const channel = c.req.query("channel");
@@ -5873,7 +5971,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
5873
5971
  const body = await c.req.text();
5874
5972
  const message = `[webhook: ${event}] ${body}`;
5875
5973
  try {
5876
- const { sendSystemMessage } = await import("./system-chat-D343HYGR.js");
5974
+ const { sendSystemMessage } = await import("./system-chat-EIINIHFB.js");
5877
5975
  await sendSystemMessage(name, message);
5878
5976
  return c.json({ ok: true });
5879
5977
  } catch (err) {
@@ -5927,7 +6025,7 @@ setup.get("/status", async (c) => {
5927
6025
  let hasAccount = false;
5928
6026
  if (hasSystem) {
5929
6027
  try {
5930
- const { listUsersByType: listUsersByType2 } = await import("./auth-OJ2YW3NR.js");
6028
+ const { listUsersByType: listUsersByType2 } = await import("./auth-2IMZ6N5G.js");
5931
6029
  const brains = await listUsersByType2("brain");
5932
6030
  hasAccount = brains.length > 0;
5933
6031
  } catch (err) {
@@ -6138,7 +6236,7 @@ setup.post("/account", async (c) => {
6138
6236
  }
6139
6237
  }
6140
6238
  try {
6141
- const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-OJ2YW3NR.js");
6239
+ const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-2IMZ6N5G.js");
6142
6240
  const user = await createUser2(body.username.trim(), body.password);
6143
6241
  if (body.displayName?.trim()) {
6144
6242
  await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
@@ -6184,7 +6282,7 @@ setup.post("/models", async (c) => {
6184
6282
  return c.json({ error: "Spirit model is required" }, 400);
6185
6283
  }
6186
6284
  try {
6187
- const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-PL7GKFQC.js");
6285
+ const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-JMV4KZN4.js");
6188
6286
  setEnabledModels3(body.models);
6189
6287
  const config2 = readGlobalConfig();
6190
6288
  config2.spiritModel = body.spiritModel.trim();
@@ -6202,15 +6300,15 @@ setup.post("/complete", async (c) => {
6202
6300
  return c.json({ error: "Setup already complete" }, 400);
6203
6301
  }
6204
6302
  try {
6205
- const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-U6MDQLYT.js");
6206
- const { startSpiritFull } = await import("./mind-service-MO2XJKJN.js");
6303
+ const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-7BUHSEO2.js");
6304
+ const { startSpiritFull } = await import("./mind-service-7OD4PRO5.js");
6207
6305
  await ensureSpiritProject();
6208
6306
  await syncSpiritTemplate();
6209
6307
  const warnings = [];
6210
6308
  const config2 = readGlobalConfig();
6211
6309
  if (config2.setup?.service && config2.setup?.type === "local") {
6212
6310
  try {
6213
- const { installUserService } = await import("./service-install-KEBDNZVE.js");
6311
+ const { installUserService } = await import("./service-install-HVAEUBAH.js");
6214
6312
  const installed = await installUserService(config2.port, config2.hostname);
6215
6313
  if (!installed) {
6216
6314
  warnings.push("Service installation is not supported on this platform.");
@@ -6238,8 +6336,8 @@ setup.post("/complete", async (c) => {
6238
6336
  }
6239
6337
  let spiritConversationId;
6240
6338
  try {
6241
- const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-OJ2YW3NR.js");
6242
- const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-EUXHBWJD.js");
6339
+ const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-2IMZ6N5G.js");
6340
+ const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-LUVHGQSS.js");
6243
6341
  const spiritUser = await getOrCreateMindUser2("volute");
6244
6342
  const brains = await listUsersByType2("brain");
6245
6343
  const admin2 = brains.find((u) => u.role === "admin");
@@ -6261,8 +6359,8 @@ setup.post("/complete", async (c) => {
6261
6359
  logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
6262
6360
  if (spiritConversationId && spiritStarted) {
6263
6361
  try {
6264
- const { deliverMessage: deliverMessage2 } = await import("./message-delivery-X7MKA3TA.js");
6265
- const { listUsersByType: listUsers2 } = await import("./auth-OJ2YW3NR.js");
6362
+ const { deliverMessage: deliverMessage2 } = await import("./message-delivery-VBBAJX3J.js");
6363
+ const { listUsersByType: listUsers2 } = await import("./auth-2IMZ6N5G.js");
6266
6364
  const admins = await listUsers2("brain");
6267
6365
  const admin2 = admins.find((u) => u.role === "admin");
6268
6366
  const adminName = admin2?.display_name || admin2?.username || "the admin";
@@ -7020,7 +7118,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
7020
7118
  if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
7021
7119
  try {
7022
7120
  const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-SSIBEEYK.js");
7023
- const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-LWEOAO53.js");
7121
+ const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-L272BZJR.js");
7024
7122
  const tmpl = parentEntry.template ?? "claude";
7025
7123
  await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
7026
7124
  } catch (err) {
@@ -7792,18 +7890,18 @@ async function startDaemon(opts) {
7792
7890
  const DAEMON_JSON_PATH = resolve16(systemDir, "daemon.json");
7793
7891
  mkdirSync10(home, { recursive: true });
7794
7892
  ensureSystemDir();
7795
- const { migrateSetupCompleted } = await import("./setup-IFYS3TLS.js");
7893
+ const { migrateSetupCompleted } = await import("./setup-IL7QJZN4.js");
7796
7894
  migrateSetupCompleted();
7797
- await (await import("./db-32YFKMFL.js")).getDb();
7895
+ await (await import("./db-2GIS7HSG.js")).getDb();
7798
7896
  try {
7799
7897
  const { eq: eq7, and: and5 } = await import("drizzle-orm");
7800
- const { users: users2 } = await import("./schema-K575EBPE.js");
7801
- const db = await (await import("./db-32YFKMFL.js")).getDb();
7898
+ const { users: users2 } = await import("./schema-HHYJDG7B.js");
7899
+ const db = await (await import("./db-2GIS7HSG.js")).getDb();
7802
7900
  await db.update(users2).set({ role: "system" }).where(and5(eq7(users2.user_type, "system"), eq7(users2.role, "user")));
7803
7901
  } catch (err) {
7804
7902
  logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
7805
7903
  }
7806
- const { initSandbox } = await import("./sandbox-KUAVC37A.js");
7904
+ const { initSandbox } = await import("./sandbox-BQAFYHLE.js");
7807
7905
  await initSandbox();
7808
7906
  try {
7809
7907
  await syncBuiltinSkills();
@@ -7830,7 +7928,7 @@ async function startDaemon(opts) {
7830
7928
  logger_default.warn("failed to ensure #system channel", logger_default.errorData(err));
7831
7929
  }
7832
7930
  try {
7833
- const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-OJ2YW3NR.js");
7931
+ const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-2IMZ6N5G.js");
7834
7932
  await getOrCreateSystemUser2();
7835
7933
  } catch (err) {
7836
7934
  logger_default.warn(
@@ -7839,12 +7937,12 @@ async function startDaemon(opts) {
7839
7937
  );
7840
7938
  }
7841
7939
  const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes(32).toString("hex");
7842
- const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-IFYS3TLS.js");
7940
+ const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-IL7QJZN4.js");
7843
7941
  const globalCfg = readGlobalConfig2();
7844
7942
  let tls;
7845
7943
  if (opts.tailscale || globalCfg.tailscale) {
7846
7944
  try {
7847
- const { getTailscaleTls } = await import("./tailscale-2KKXDMNK.js");
7945
+ const { getTailscaleTls } = await import("./tailscale-6MHNLBAX.js");
7848
7946
  const tlsConfig = await getTailscaleTls();
7849
7947
  tls = { key: tlsConfig.key, cert: tlsConfig.cert };
7850
7948
  logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
@@ -7923,10 +8021,10 @@ async function startDaemon(opts) {
7923
8021
  await Promise.all(workers);
7924
8022
  }
7925
8023
  try {
7926
- const { isSetupComplete: isSetupComplete2 } = await import("./setup-IFYS3TLS.js");
8024
+ const { isSetupComplete: isSetupComplete2 } = await import("./setup-IL7QJZN4.js");
7927
8025
  if (isSetupComplete2()) {
7928
- const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-U6MDQLYT.js");
7929
- const { startSpiritFull } = await import("./mind-service-MO2XJKJN.js");
8026
+ const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-7BUHSEO2.js");
8027
+ const { startSpiritFull } = await import("./mind-service-7OD4PRO5.js");
7930
8028
  await ensureSpiritProject();
7931
8029
  await syncSpiritTemplate();
7932
8030
  const spiritEntry = await findMind("volute");
@@ -7943,7 +8041,7 @@ async function startDaemon(opts) {
7943
8041
  bridgeManager.startBridges(daemonPort).catch((err) => {
7944
8042
  logger_default.warn("failed to start bridges", logger_default.errorData(err));
7945
8043
  });
7946
- import("./cloud-sync-NQCWJLYI.js").then(
8044
+ import("./cloud-sync-5JF2Z7VM.js").then(
7947
8045
  ({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
7948
8046
  logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
7949
8047
  })
@@ -7951,7 +8049,7 @@ async function startDaemon(opts) {
7951
8049
  logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
7952
8050
  });
7953
8051
  try {
7954
- const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-ZBMY2TEX.js");
8052
+ const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-NFQMI5IY.js");
7955
8053
  backfillTemplateHashes();
7956
8054
  notifyVersionUpdate().catch((err) => {
7957
8055
  logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
@@ -7968,6 +8066,11 @@ async function startDaemon(opts) {
7968
8066
  cleanExpiredLogs().catch((err) => {
7969
8067
  logger_default.warn("failed to clean expired logs", logger_default.errorData(err));
7970
8068
  });
8069
+ setProviderRefreshHook((provider) => {
8070
+ void syncProviderToMinds(provider, {
8071
+ listRunning: () => getMindManager().getRunningMinds()
8072
+ }).catch((err) => logger_default.warn("credential sync to minds failed", logger_default.errorData(err)));
8073
+ });
7971
8074
  startApiKeyRefresh();
7972
8075
  logger_default.info(`running on ${hostname}:${port}, pid ${myPid}`);
7973
8076
  function cleanup() {