volute 0.41.0 → 0.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/{accept-AHAOUFBK.js → accept-7YVHZKRD.js} +1 -1
  2. package/dist/{activity-events-EQGBUEZ7.js → activity-events-KFKVRZE3.js} +2 -2
  3. package/dist/{ai-service-ZHEPFC3U.js → ai-service-XCLE3MQP.js} +3 -3
  4. package/dist/{archive-LJAXDDEY.js → archive-4PPYF7LL.js} +2 -2
  5. package/dist/{auth-VYW2ECCE.js → auth-EAASQPTN.js} +3 -3
  6. package/dist/{bridge-F3ZJEKDN.js → bridge-WPYSOQKR.js} +1 -1
  7. package/dist/{chat-FO722GU2.js → chat-7DOENBY2.js} +8 -8
  8. package/dist/{chunk-6TPRURK5.js → chunk-5QG36RV7.js} +2 -2
  9. package/dist/{chunk-GMFCSXWB.js → chunk-62ICA2FF.js} +1 -1
  10. package/dist/{chunk-U7UASV36.js → chunk-763WUVJQ.js} +43 -10
  11. package/dist/{chunk-6ZAT5PYV.js → chunk-BLOAJLGI.js} +1 -1
  12. package/dist/{chunk-2I7OKOYV.js → chunk-CGPESELY.js} +2 -2
  13. package/dist/{chunk-FEQPNCXB.js → chunk-E7XWFDZL.js} +1 -1
  14. package/dist/{chunk-FU5YDH6Q.js → chunk-EKLRS2SX.js} +3 -3
  15. package/dist/{chunk-W5Z2H3LU.js → chunk-F44AEQAW.js} +290 -71
  16. package/dist/{chunk-V67XMNGP.js → chunk-G777ME4L.js} +2 -2
  17. package/dist/{chunk-YATR5BXD.js → chunk-GCS64EAD.js} +4 -4
  18. package/dist/{chunk-Y2XLASFJ.js → chunk-GN52E2DP.js} +1 -1
  19. package/dist/{chunk-ZX7EAV5J.js → chunk-IFNSAOA4.js} +9 -2
  20. package/dist/{chunk-VK2YD7VJ.js → chunk-IJCZAYGT.js} +1 -1
  21. package/dist/{chunk-VDODEQSJ.js → chunk-IUZ3EV2D.js} +4 -0
  22. package/dist/{chunk-2RQIIKFC.js → chunk-K547QOCM.js} +1 -1
  23. package/dist/{chunk-OQ7UEW67.js → chunk-KUJVCDWT.js} +2 -2
  24. package/dist/{chunk-GSOEUMVO.js → chunk-M2YMNTHK.js} +1 -1
  25. package/dist/{chunk-N64Q7FMP.js → chunk-MA7MYEOK.js} +4 -3
  26. package/dist/{chunk-JIGVTFIR.js → chunk-MJIJFCAH.js} +43 -14
  27. package/dist/{chunk-YN6ISG7A.js → chunk-MYJSKXGH.js} +14 -13
  28. package/dist/{chunk-MU2B7A3L.js → chunk-OEJFZHZZ.js} +1 -1
  29. package/dist/{chunk-SWY4DJ67.js → chunk-OSUF75I7.js} +2 -2
  30. package/dist/{chunk-WSRGS4XP.js → chunk-QLWG3C2Z.js} +10 -0
  31. package/dist/{chunk-UU3Q65US.js → chunk-QMJCNZ6C.js} +1 -1
  32. package/dist/{chunk-CYUNO4BM.js → chunk-QPTQKGGF.js} +1 -1
  33. package/dist/{chunk-4ED2DBNC.js → chunk-TFBQESH7.js} +1 -1
  34. package/dist/{chunk-AXNAK3HT.js → chunk-ULNQ6OC4.js} +7 -7
  35. package/dist/{chunk-PP5CGT2P.js → chunk-VBKRZCR7.js} +1 -1
  36. package/dist/{chunk-2R4JIZCB.js → chunk-YLTIEEVL.js} +2 -2
  37. package/dist/cli.js +22 -22
  38. package/dist/{clock-BMLJ2TR6.js → clock-HP2TGMG5.js} +3 -3
  39. package/dist/{cloud-sync-GV6O2HN2.js → cloud-sync-2XVXEOSU.js} +17 -17
  40. package/dist/{config-QB7W3Z7P.js → config-W7MS3PWY.js} +3 -3
  41. package/dist/{conversations-KW7IYESK.js → conversations-FSZCUUYO.js} +3 -3
  42. package/dist/{create-C3BBFYV7.js → create-CJ2SR4EU.js} +1 -1
  43. package/dist/{create-CTPXWFTL.js → create-OTM46ZUM.js} +2 -2
  44. package/dist/{daemon-client-2MIPKY3E.js → daemon-client-EWDPOOHC.js} +3 -1
  45. package/dist/{daemon-restart-W47YDE5E.js → daemon-restart-HDVGTYH7.js} +7 -7
  46. package/dist/daemon.js +218 -300
  47. package/dist/{db-D4FVCA5I.js → db-ZJJJYJBU.js} +1 -1
  48. package/dist/{delete-NLXES2C7.js → delete-4ND5PLE7.js} +1 -1
  49. package/dist/delivery-manager-CPADWRV2.js +33 -0
  50. package/dist/{delivery-router-Y66OXJPM.js → delivery-router-FDBZJQOY.js} +2 -2
  51. package/dist/{down-JVHNXOFU.js → down-DS6WCT34.js} +5 -5
  52. package/dist/echo-text-GEDEEY7M.js +32 -0
  53. package/dist/{env-IQ6Q2333.js → env-XX2MBZCZ.js} +1 -1
  54. package/dist/{exec-R2WWZ6FH.js → exec-ZDD7NEB4.js} +3 -3
  55. package/dist/{export-ZZ5WWBUH.js → export-5DOQV2WM.js} +3 -3
  56. package/dist/{extension-LZYHBNLV.js → extension-BCFYXI7A.js} +4 -1
  57. package/dist/{extensions-AGANCIQA.js → extensions-SU3N4COT.js} +17 -17
  58. package/dist/{files-Q2Z4LQZP.js → files-K2MEMV3W.js} +3 -3
  59. package/dist/{import-MFYCBS4K.js → import-V6QEHMPQ.js} +7 -7
  60. package/dist/{isolation-7F3MA4G7.js → isolation-F7ABZMDA.js} +2 -2
  61. package/dist/{join-6SZCA5FX.js → join-4S3KT7NE.js} +1 -1
  62. package/dist/{list-KHJZJPEJ.js → list-XJB5WII6.js} +1 -1
  63. package/dist/{login-WY3DADVB.js → login-PHMTLNUF.js} +2 -2
  64. package/dist/{login-GYTH67ES.js → login-YWD6PUOT.js} +1 -1
  65. package/dist/{logout-TFZHWNVL.js → logout-BP3R3CAA.js} +2 -2
  66. package/dist/{logout-YHQLOFLR.js → logout-Q2WICH4V.js} +1 -1
  67. package/dist/message-delivery-HPMELC4Q.js +41 -0
  68. package/dist/{mind-XIKEPJNS.js → mind-APS4URT7.js} +18 -18
  69. package/dist/{mind-activity-tracker-RSIWUUJK.js → mind-activity-tracker-HWVFE533.js} +3 -3
  70. package/dist/{mind-history-WHCNZ6I5.js → mind-history-TDUQFYAG.js} +1 -1
  71. package/dist/{mind-list-H3HC2ZRG.js → mind-list-2T353Q5G.js} +1 -1
  72. package/dist/mind-manager-74XQZEGX.js +33 -0
  73. package/dist/{mind-profile-7VYRJGFZ.js → mind-profile-2HHR7LZ7.js} +1 -1
  74. package/dist/mind-service-XGXSMQP6.js +37 -0
  75. package/dist/{mind-sleep-ZL5ZXFTM.js → mind-sleep-4NXV4J4U.js} +1 -1
  76. package/dist/{mind-status-ZWULKOUO.js → mind-status-CG66OXDK.js} +1 -1
  77. package/dist/{mind-wake-HK5ORGUK.js → mind-wake-TNB54DBR.js} +1 -1
  78. package/dist/{package-2X7UNSTQ.js → package-MVFX22K5.js} +2 -1
  79. package/dist/{read-CP7MYMJQ.js → read-JLR4NQXU.js} +1 -1
  80. package/dist/{register-XOBFEMI4.js → register-IQ2M4UO6.js} +1 -1
  81. package/dist/{registry-RAXNFN7K.js → registry-MDLNPTTI.js} +3 -1
  82. package/dist/{reject-43AGXB6B.js → reject-N2D4CZND.js} +1 -1
  83. package/dist/{restart-O5QIYQJT.js → restart-43A5MBGV.js} +1 -1
  84. package/dist/{sandbox-O3GZTS7J.js → sandbox-ND53WZVU.js} +7 -3
  85. package/dist/scheduler-MEBQF5MW.js +31 -0
  86. package/dist/{seed-I4CNKTKZ.js → seed-L4XFZ3VX.js} +1 -1
  87. package/dist/{seed-check-HZPVFJKZ.js → seed-check-N5ALJBT6.js} +1 -1
  88. package/dist/{seed-cmd-YTQYWCZF.js → seed-cmd-NSTPYJFC.js} +3 -3
  89. package/dist/{seed-create-MDBTVADS.js → seed-create-ZYCZC46W.js} +4 -4
  90. package/dist/{seed-sprout-N6O5FBPY.js → seed-sprout-YXHU73XA.js} +8 -8
  91. package/dist/{send-5XA7LRNB.js → send-KQECN2EL.js} +3 -3
  92. package/dist/{service-AY5TGWJX.js → service-Q5OVY5AK.js} +4 -4
  93. package/dist/{service-install-NLGAVTQS.js → service-install-GTDUHP6R.js} +5 -5
  94. package/dist/{setup-3434PQ5Q.js → setup-FPFWDMXD.js} +2 -2
  95. package/dist/{setup-47NBOCZL.js → setup-RMR3TKCR.js} +7 -7
  96. package/dist/{skill-ICN6Y2ZF.js → skill-E43BI34Y.js} +1 -1
  97. package/dist/skills/imagegen/scripts/imagegen.ts +1 -1
  98. package/dist/{skills-YTLBAF32.js → skills-AOZF6U2B.js} +5 -5
  99. package/dist/sleep-manager-OHM3TO62.js +35 -0
  100. package/dist/{spirit-KTBHLULO.js → spirit-ONLRFATY.js} +8 -8
  101. package/dist/{split-5YBEQTBF.js → split-5IBUODEE.js} +1 -1
  102. package/dist/{sprout-4ZUJUNDQ.js → sprout-2KJOQZCL.js} +1 -1
  103. package/dist/{src-OYWRPLC6.js → src-L2Z7X5UT.js} +5 -8
  104. package/dist/{src-4LFGGNW7.js → src-TJ7RBU5H.js} +2 -12
  105. package/dist/{start-LMXXRR3X.js → start-5AYFGNS7.js} +1 -1
  106. package/dist/{status-VMOZUIZ2.js → status-ECZHHSY5.js} +5 -5
  107. package/dist/{stop-TWDKVEUX.js → stop-WJ6IG6OK.js} +1 -1
  108. package/dist/system-chat-HZUKBIKJ.js +35 -0
  109. package/dist/{systems-Y2WZV2K4.js → systems-5MA57Q7G.js} +4 -4
  110. package/dist/{tailscale-PK3AI5EV.js → tailscale-TIRTGM6E.js} +1 -1
  111. package/dist/{template-hash-JARTCRGS.js → template-hash-446HHH5V.js} +2 -2
  112. package/dist/{turn-tracker-SZBSL7LK.js → turn-tracker-TIX4DY2W.js} +4 -4
  113. package/dist/{up-VGVPOB6J.js → up-7KVNER6V.js} +6 -6
  114. package/dist/{update-3ANTQO54.js → update-OPR4KU4M.js} +5 -5
  115. package/dist/{update-check-4O6DKUOF.js → update-check-OG27AL4Z.js} +2 -2
  116. package/dist/{upgrade-RXFZR5FI.js → upgrade-QB7AHIKX.js} +1 -1
  117. package/dist/{version-notify-SSNAWZMX.js → version-notify-UFFDUPCX.js} +19 -19
  118. package/package.json +2 -1
  119. package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +2 -2
  120. package/templates/_base/.init/.config/hooks/pre-prompt/session-activity.ts +3 -3
  121. package/templates/_base/.init/.local/hooks/pre-prompt/notices.ts +3 -3
  122. package/templates/_base/.init/.local/hooks/pre-prompt/session-activity.ts +3 -3
  123. package/templates/_base/src/lib/daemon-client.ts +1 -1
  124. package/templates/_base/src/lib/volute-server.ts +1 -1
  125. package/dist/delivery-manager-EB52CQ5X.js +0 -33
  126. package/dist/echo-text-QVPS6QDM.js +0 -32
  127. package/dist/message-delivery-X4CZE2L6.js +0 -41
  128. package/dist/mind-manager-VU3RGCXD.js +0 -31
  129. package/dist/mind-service-L7LMMDYJ.js +0 -37
  130. package/dist/scheduler-SXELVRWO.js +0 -31
  131. package/dist/sleep-manager-T3AXQB3R.js +0 -35
  132. package/dist/system-chat-HCPHUQGI.js +0 -35
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  loadMergedEnv
4
- } from "./chunk-6ZAT5PYV.js";
4
+ } from "./chunk-BLOAJLGI.js";
5
5
  import {
6
6
  spiritDir
7
- } from "./chunk-YN6ISG7A.js";
7
+ } from "./chunk-MYJSKXGH.js";
8
8
  import {
9
9
  hashSkillDir,
10
10
  importSkillFromDir,
11
11
  removeSharedSkill,
12
12
  sharedSkillsDir
13
- } from "./chunk-JIGVTFIR.js";
13
+ } from "./chunk-MJIJFCAH.js";
14
14
  import {
15
15
  addMessage,
16
16
  createChannel,
@@ -20,7 +20,7 @@ import {
20
20
  getParticipants,
21
21
  joinChannel,
22
22
  publish as publish2
23
- } from "./chunk-2R4JIZCB.js";
23
+ } from "./chunk-YLTIEEVL.js";
24
24
  import {
25
25
  readVoluteConfig,
26
26
  writeVoluteConfig
@@ -28,53 +28,53 @@ import {
28
28
  import {
29
29
  isSandboxEnabled,
30
30
  wrapForSandbox
31
- } from "./chunk-U7UASV36.js";
31
+ } from "./chunk-763WUVJQ.js";
32
32
  import {
33
33
  markIdle,
34
34
  onMindEvent
35
- } from "./chunk-PP5CGT2P.js";
35
+ } from "./chunk-VBKRZCR7.js";
36
36
  import {
37
37
  extractTextContent,
38
38
  getRoutingConfig,
39
39
  resolveDeliveryMode,
40
40
  resolveRoute
41
- } from "./chunk-GMFCSXWB.js";
41
+ } from "./chunk-62ICA2FF.js";
42
42
  import {
43
43
  clearMind,
44
44
  getActiveTurnId,
45
45
  getPrompt,
46
46
  publish as publish3,
47
47
  summarizeOrphanedTurns
48
- } from "./chunk-YATR5BXD.js";
48
+ } from "./chunk-GCS64EAD.js";
49
49
  import {
50
50
  exec
51
- } from "./chunk-Y2XLASFJ.js";
51
+ } from "./chunk-GN52E2DP.js";
52
52
  import {
53
53
  chownMindDir,
54
54
  isIsolationEnabled,
55
55
  mindUserName,
56
56
  wrapForIsolation
57
- } from "./chunk-4ED2DBNC.js";
57
+ } from "./chunk-TFBQESH7.js";
58
58
  import {
59
59
  aiCompleteUtility,
60
60
  getAiConfig,
61
61
  resolveApiKey
62
- } from "./chunk-VK2YD7VJ.js";
62
+ } from "./chunk-IJCZAYGT.js";
63
63
  import {
64
64
  readGlobalConfig,
65
65
  writeGlobalConfig
66
- } from "./chunk-N64Q7FMP.js";
66
+ } from "./chunk-MA7MYEOK.js";
67
67
  import {
68
68
  getOrCreateMindUser,
69
69
  getOrCreateSystemUser,
70
70
  getUser,
71
71
  getUserByUsername,
72
72
  syncMindProfile
73
- } from "./chunk-6TPRURK5.js";
73
+ } from "./chunk-5QG36RV7.js";
74
74
  import {
75
75
  publish,
76
76
  subscribe
77
- } from "./chunk-2RQIIKFC.js";
77
+ } from "./chunk-K547QOCM.js";
78
78
  import {
79
79
  logger_default
80
80
  } from "./chunk-T2TP6ZC6.js";
@@ -83,11 +83,12 @@ import {
83
83
  getBaseName,
84
84
  getDb,
85
85
  mindDir,
86
+ mindTmpDir,
86
87
  setMindRunning,
87
88
  stateDir,
88
89
  voluteHome,
89
90
  voluteSystemDir
90
- } from "./chunk-VDODEQSJ.js";
91
+ } from "./chunk-IUZ3EV2D.js";
91
92
  import {
92
93
  activity,
93
94
  conversationParticipants,
@@ -95,12 +96,13 @@ import {
95
96
  messages,
96
97
  mindHistory,
97
98
  mindNotices,
99
+ sessions,
98
100
  turns,
99
101
  users
100
102
  } from "./chunk-MHFAWJCC.js";
101
103
 
102
104
  // packages/daemon/src/lib/delivery/message-delivery.ts
103
- import { and as and4, desc, eq as eq4, inArray as inArray2, sql as sql3 } from "drizzle-orm";
105
+ import { and as and4, desc, eq as eq5, inArray as inArray2, sql as sql3 } from "drizzle-orm";
104
106
 
105
107
  // packages/daemon/src/lib/daemon/sleep-manager.ts
106
108
  import { execFile as execFile2, spawn as spawnChild } from "child_process";
@@ -116,7 +118,7 @@ import {
116
118
  import { resolve as resolve7 } from "path";
117
119
  import { promisify as promisify2 } from "util";
118
120
  import { CronExpressionParser as CronExpressionParser2 } from "cron-parser";
119
- import { and as and2, eq as eq2, inArray } from "drizzle-orm";
121
+ import { and as and2, eq as eq3, inArray } from "drizzle-orm";
120
122
 
121
123
  // packages/daemon/src/lib/daemon/mind-manager.ts
122
124
  import { execFile, spawn } from "child_process";
@@ -440,6 +442,50 @@ var RestartTracker = class {
440
442
  // packages/daemon/src/lib/daemon/mind-manager.ts
441
443
  var mlog = logger_default.child("minds");
442
444
  var execFileAsync = promisify(execFile);
445
+ var MIND_ENV_ALLOWLIST = [
446
+ "PATH",
447
+ "HOME",
448
+ "USER",
449
+ "LOGNAME",
450
+ "SHELL",
451
+ "LANG",
452
+ "LANGUAGE",
453
+ "LC_ALL",
454
+ "LC_CTYPE",
455
+ "LC_MESSAGES",
456
+ "TERM",
457
+ "TERMINFO",
458
+ "COLORTERM",
459
+ "TMPDIR",
460
+ "TMP",
461
+ "TEMP",
462
+ "TZ",
463
+ "NODE_ENV",
464
+ "__CF_USER_TEXT_ENCODING",
465
+ // Outbound proxy / custom-CA config — required for minds' HTTPS calls (incl.
466
+ // the Anthropic API) to succeed on hosts that reach the internet only via a
467
+ // corporate proxy or custom CA bundle. Previously inherited via ...process.env.
468
+ "HTTP_PROXY",
469
+ "HTTPS_PROXY",
470
+ "NO_PROXY",
471
+ "http_proxy",
472
+ "https_proxy",
473
+ "no_proxy",
474
+ "NODE_EXTRA_CA_CERTS",
475
+ "SSL_CERT_FILE",
476
+ "SSL_CERT_DIR"
477
+ ];
478
+ function buildMindBaseEnv(source = process.env) {
479
+ const base = {};
480
+ for (const key of MIND_ENV_ALLOWLIST) {
481
+ if (source[key] !== void 0) base[key] = source[key];
482
+ }
483
+ for (const [key, value] of Object.entries(source)) {
484
+ if (key === "VOLUTE_DAEMON_TOKEN") continue;
485
+ if (key.startsWith("VOLUTE_")) base[key] = value;
486
+ }
487
+ return base;
488
+ }
443
489
  function mindPidPath(name) {
444
490
  return resolve2(stateDir(name), "mind.pid");
445
491
  }
@@ -505,9 +551,12 @@ var MindManager = class {
505
551
  const mindStateDir = stateDir(name);
506
552
  const logsDir = resolve2(mindStateDir, "logs");
507
553
  mkdirSync2(logsDir, { recursive: true });
554
+ const mindTmp = mindTmpDir(dir);
555
+ mkdirSync2(mindTmp, { recursive: true });
508
556
  if (isIsolationEnabled()) {
509
557
  try {
510
558
  chownMindDir(mindStateDir, baseName);
559
+ chownMindDir(mindTmp, baseName);
511
560
  } catch (err) {
512
561
  throw new Error(
513
562
  `Cannot start mind ${name}: failed to set ownership on state directory ${mindStateDir}: ${err instanceof Error ? err.message : err}`
@@ -520,13 +569,14 @@ var MindManager = class {
520
569
  const mindLocalBin = resolve2(dir, "home", ".local", "bin");
521
570
  const currentPath = process.env.PATH ?? "";
522
571
  const env = {
523
- ...process.env,
572
+ ...buildMindBaseEnv(),
524
573
  ...mindEnv,
525
574
  VOLUTE_MIND: name,
526
575
  VOLUTE_STATE_DIR: stateDir(name),
527
576
  VOLUTE_MIND_DIR: dir,
528
577
  VOLUTE_MIND_PORT: String(port),
529
- VOLUTE_DAEMON_TOKEN: mindToken,
578
+ VOLUTE_MIND_TOKEN: mindToken,
579
+ TMPDIR: mindTmp,
530
580
  PATH: `${mindLocalBin}:${currentPath}`,
531
581
  // Strip CLAUDECODE so the Agent SDK can spawn Claude Code subprocesses
532
582
  CLAUDECODE: void 0
@@ -628,8 +678,9 @@ var MindManager = class {
628
678
  const claudeDir = writeClaudeCredentials(resolve2(dir, "home"), baseName, oauth);
629
679
  env.CLAUDE_CONFIG_DIR = claudeDir;
630
680
  }
631
- } else if (anthropicConfig?.apiKey) {
632
- env.ANTHROPIC_API_KEY = anthropicConfig.apiKey;
681
+ } else {
682
+ const apiKey = await resolveApiKey("anthropic");
683
+ if (apiKey) env.ANTHROPIC_API_KEY = apiKey;
633
684
  }
634
685
  } catch (err) {
635
686
  mlog.error(`failed to inject Anthropic credentials for ${name}`, logger_default.errorData(err));
@@ -661,7 +712,7 @@ var MindManager = class {
661
712
  [spawnCmd, spawnArgs] = await wrapForSandbox(baseBin, baseArgs, dir, name, [
662
713
  dir,
663
714
  mindStateDir,
664
- "/tmp"
715
+ mindTmp
665
716
  ]);
666
717
  } else {
667
718
  spawnCmd = baseBin;
@@ -787,7 +838,7 @@ var MindManager = class {
787
838
  if (this.shuttingDown || this.stopping.has(name)) return;
788
839
  mlog.error(`mind ${name} exited with code ${code}`);
789
840
  try {
790
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
841
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
791
842
  const sleepState = getSleepManagerIfReady2()?.getState(name);
792
843
  if (sleepState?.sleeping) {
793
844
  mlog.info(`${name} is sleeping \u2014 skipping crash recovery`);
@@ -811,15 +862,15 @@ var MindManager = class {
811
862
  (err) => mlog.warn(`failed to clear turn state for ${name} after crash`, logger_default.errorData(err))
812
863
  );
813
864
  try {
814
- const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-EB52CQ5X.js");
865
+ const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-CPADWRV2.js");
815
866
  getDeliveryManager2().clearMindSessions(name);
816
867
  } catch (err) {
817
868
  if (!(err instanceof Error && err.message.includes("not initialized"))) {
818
869
  mlog.warn(`failed to clear delivery state for ${name} after crash`, logger_default.errorData(err));
819
870
  }
820
871
  }
821
- import("./mind-activity-tracker-RSIWUUJK.js").then(({ markIdle: markIdle2 }) => markIdle2(name)).catch((err) => mlog.warn(`failed to mark ${name} idle after crash`, logger_default.errorData(err)));
822
- import("./activity-events-EQGBUEZ7.js").then(
872
+ import("./mind-activity-tracker-HWVFE533.js").then(({ markIdle: markIdle2 }) => markIdle2(name)).catch((err) => mlog.warn(`failed to mark ${name} idle after crash`, logger_default.errorData(err)));
873
+ import("./activity-events-KFKVRZE3.js").then(
823
874
  ({ publish: publish4 }) => publish4({ type: "mind_stopped", mind: name, summary: `${name} crashed (exit ${code})` })
824
875
  ).catch((err) => mlog.warn(`failed to publish crash event for ${name}`, logger_default.errorData(err)));
825
876
  const { shouldRestart, delay, attempt } = this.restartTracker.recordCrash(name);
@@ -870,7 +921,7 @@ var MindManager = class {
870
921
  mlog.warn(`failed to clear turn state for ${name} on stop`, logger_default.errorData(err));
871
922
  }
872
923
  try {
873
- const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-EB52CQ5X.js");
924
+ const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-CPADWRV2.js");
874
925
  getDeliveryManager2().clearMindSessions(name);
875
926
  } catch (err) {
876
927
  if (!(err instanceof Error && err.message.includes("not initialized"))) {
@@ -878,7 +929,7 @@ var MindManager = class {
878
929
  }
879
930
  }
880
931
  try {
881
- const { clearEchoTextCache } = await import("./echo-text-QVPS6QDM.js");
932
+ const { clearEchoTextCache } = await import("./echo-text-GEDEEY7M.js");
882
933
  clearEchoTextCache(name);
883
934
  } catch (err) {
884
935
  mlog.debug(`failed to clear echo-text cache for ${name}`, logger_default.errorData(err));
@@ -1007,6 +1058,150 @@ async function announceToSystem(text) {
1007
1058
  import { existsSync as existsSync6, mkdirSync as mkdirSync4, readdirSync, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
1008
1059
  import { dirname, resolve as resolve4 } from "path";
1009
1060
 
1061
+ // packages/daemon/src/web/middleware/auth.ts
1062
+ import { timingSafeEqual } from "crypto";
1063
+ import { eq as eq2, lt } from "drizzle-orm";
1064
+ import { getCookie } from "hono/cookie";
1065
+ import { createMiddleware } from "hono/factory";
1066
+ var MIND_USER_CACHE_TTL = 5 * 60 * 1e3;
1067
+ var mindUserCache = /* @__PURE__ */ new Map();
1068
+ function invalidateMindUserCache(mindName) {
1069
+ mindUserCache.delete(mindName);
1070
+ }
1071
+ function isValidDaemonToken(token) {
1072
+ const expected = process.env.VOLUTE_DAEMON_TOKEN;
1073
+ if (!expected || token.length !== expected.length) return false;
1074
+ return timingSafeEqual(Buffer.from(token), Buffer.from(expected));
1075
+ }
1076
+ var SESSION_MAX_AGE = 365 * 24 * 60 * 60 * 1e3;
1077
+ var SESSION_CACHE_TTL = 5 * 60 * 1e3;
1078
+ var sessionCache = /* @__PURE__ */ new Map();
1079
+ function invalidateSessionCache(sessionId) {
1080
+ sessionCache.delete(sessionId);
1081
+ }
1082
+ async function createSession(userId) {
1083
+ const db = await getDb();
1084
+ const sessionId = crypto.randomUUID();
1085
+ await db.insert(sessions).values({ id: sessionId, userId, createdAt: Date.now() });
1086
+ return sessionId;
1087
+ }
1088
+ async function deleteSession(sessionId) {
1089
+ sessionCache.delete(sessionId);
1090
+ const db = await getDb();
1091
+ await db.delete(sessions).where(eq2(sessions.id, sessionId));
1092
+ }
1093
+ async function getSessionUserId(sessionId) {
1094
+ const db = await getDb();
1095
+ const row = await db.select().from(sessions).where(eq2(sessions.id, sessionId)).get();
1096
+ if (!row) return void 0;
1097
+ if (Date.now() - row.createdAt > SESSION_MAX_AGE) {
1098
+ await db.delete(sessions).where(eq2(sessions.id, sessionId));
1099
+ return void 0;
1100
+ }
1101
+ return row.userId;
1102
+ }
1103
+ async function cleanExpiredSessions() {
1104
+ const db = await getDb();
1105
+ const cutoff = Date.now() - SESSION_MAX_AGE;
1106
+ await db.delete(sessions).where(lt(sessions.createdAt, cutoff));
1107
+ }
1108
+ var requireAdmin = createMiddleware(async (c, next) => {
1109
+ const user = c.get("user");
1110
+ if (user.role !== "admin") {
1111
+ return c.json({ error: "Forbidden" }, 403);
1112
+ }
1113
+ await next();
1114
+ });
1115
+ var requireAdminOrSystem = createMiddleware(async (c, next) => {
1116
+ const user = c.get("user");
1117
+ if (user.role !== "admin" && user.role !== "system") {
1118
+ return c.json({ error: "Forbidden" }, 403);
1119
+ }
1120
+ await next();
1121
+ });
1122
+ async function resolveSession(sessionId) {
1123
+ const cached = sessionCache.get(sessionId);
1124
+ if (cached && cached.expires > Date.now()) {
1125
+ return cached.user;
1126
+ }
1127
+ const userId = await getSessionUserId(sessionId);
1128
+ if (userId == null) {
1129
+ sessionCache.delete(sessionId);
1130
+ return null;
1131
+ }
1132
+ const user = await getUser(userId);
1133
+ if (!user) {
1134
+ sessionCache.delete(sessionId);
1135
+ return null;
1136
+ }
1137
+ sessionCache.set(sessionId, { userId, user, expires: Date.now() + SESSION_CACHE_TTL });
1138
+ return user;
1139
+ }
1140
+ var authMiddleware = createMiddleware(async (c, next) => {
1141
+ const authHeader = c.req.header("Authorization");
1142
+ if (authHeader?.startsWith("Bearer ")) {
1143
+ const token = authHeader.slice(7);
1144
+ if (token && isValidDaemonToken(token)) {
1145
+ c.set("user", {
1146
+ id: 0,
1147
+ username: "daemon",
1148
+ role: "admin",
1149
+ user_type: "brain",
1150
+ display_name: null,
1151
+ description: null,
1152
+ avatar: null
1153
+ });
1154
+ const mindSessionHeader = c.req.header("X-Volute-Session");
1155
+ if (mindSessionHeader) c.set("mindSession", mindSessionHeader);
1156
+ await next();
1157
+ return;
1158
+ }
1159
+ const mindName = resolveMindToken(token);
1160
+ if (mindName) {
1161
+ const cached = mindUserCache.get(mindName);
1162
+ let mindUser;
1163
+ if (cached && Date.now() - cached.ts < MIND_USER_CACHE_TTL) {
1164
+ mindUser = cached.user;
1165
+ } else {
1166
+ mindUser = await getOrCreateMindUser(mindName);
1167
+ mindUserCache.set(mindName, { user: mindUser, ts: Date.now() });
1168
+ }
1169
+ c.set("user", mindUser);
1170
+ const mindSessionHeader = c.req.header("X-Volute-Session");
1171
+ if (mindSessionHeader) c.set("mindSession", mindSessionHeader);
1172
+ await next();
1173
+ return;
1174
+ }
1175
+ if (token) {
1176
+ const user2 = await resolveSession(token);
1177
+ if (user2) {
1178
+ if (user2.role === "pending") return c.json({ error: "Account pending approval" }, 403);
1179
+ c.set("user", user2);
1180
+ await next();
1181
+ return;
1182
+ }
1183
+ }
1184
+ }
1185
+ const sessionId = getCookie(c, "volute_session");
1186
+ if (!sessionId) return c.json({ error: "Unauthorized" }, 401);
1187
+ const user = await resolveSession(sessionId);
1188
+ if (!user) return c.json({ error: "Unauthorized" }, 401);
1189
+ if (user.role === "pending") return c.json({ error: "Account pending approval" }, 403);
1190
+ c.set("user", user);
1191
+ await next();
1192
+ });
1193
+ var requireSelf = (paramName = "name") => createMiddleware(async (c, next) => {
1194
+ const user = c.get("user");
1195
+ if (user.role !== "admin" && user.role !== "system") {
1196
+ const target = c.req.param(paramName) ?? "";
1197
+ const baseName = await getBaseName(target);
1198
+ if (user.username !== baseName) {
1199
+ return c.json({ error: "Forbidden" }, 403);
1200
+ }
1201
+ }
1202
+ await next();
1203
+ });
1204
+
1010
1205
  // packages/daemon/src/lib/config/systems-config.ts
1011
1206
  import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "fs";
1012
1207
  import { resolve as resolve3 } from "path";
@@ -1144,6 +1339,10 @@ async function buildContext(manifest, dataDir, authMw) {
1144
1339
  return {
1145
1340
  db,
1146
1341
  authMiddleware: authMw,
1342
+ // Reuse the daemon's canonical guard so extension routes authorize the same
1343
+ // way core routes do (admin/system or the mind whose base name matches the
1344
+ // route param). Its type is compatible with the SDK MiddlewareHandler.
1345
+ requireSelf: (paramName) => requireSelf(paramName),
1147
1346
  resolveUser: (c) => {
1148
1347
  const user = c.get("user");
1149
1348
  if (!user || typeof user !== "object") return null;
@@ -1210,7 +1409,8 @@ async function loadExtension(manifest, app, authMw) {
1210
1409
  return c.json({ error: "Invalid JSON in request body" }, 400);
1211
1410
  }
1212
1411
  const user = c.get("user");
1213
- const mindName = body.mind || user?.username;
1412
+ const privileged = user?.role === "admin" || user?.role === "system";
1413
+ const mindName = privileged ? body.mind || user?.username : user?.username;
1214
1414
  const session = c.get("mindSession");
1215
1415
  try {
1216
1416
  const activityPromises = [];
@@ -1361,8 +1561,8 @@ function resolveSkillsDir(manifest) {
1361
1561
  }
1362
1562
  async function discoverBuiltinExtensions(disabledIds) {
1363
1563
  const builtins = [
1364
- { id: "notes", load: async () => (await import("./src-OYWRPLC6.js")).default },
1365
- { id: "pages", load: async () => (await import("./src-4LFGGNW7.js")).default },
1564
+ { id: "notes", load: async () => (await import("./src-L2Z7X5UT.js")).default },
1565
+ { id: "pages", load: async () => (await import("./src-TJ7RBU5H.js")).default },
1366
1566
  { id: "plan", load: async () => (await import("./src-O4PRLMKM.js")).default }
1367
1567
  ];
1368
1568
  const results = [];
@@ -1603,9 +1803,9 @@ async function installNpmExtension(pkg) {
1603
1803
  throw new Error(`Extension "${pkg}" is already installed`);
1604
1804
  }
1605
1805
  const dir = ensureExtensionsNpmDir();
1606
- const { exec: exec2 } = await import("./exec-R2WWZ6FH.js");
1806
+ const { exec: exec2 } = await import("./exec-ZDD7NEB4.js");
1607
1807
  try {
1608
- await exec2("npm", ["install", pkg], { cwd: dir });
1808
+ await exec2("npm", ["install", "--ignore-scripts", pkg], { cwd: dir });
1609
1809
  } catch (err) {
1610
1810
  logger_default.error(`npm install failed for "${pkg}"`, logger_default.errorData(err));
1611
1811
  throw new Error(`Failed to install "${pkg}". Check daemon logs for details.`);
@@ -1624,8 +1824,8 @@ async function uninstallNpmExtension(pkg) {
1624
1824
  packages.splice(idx, 1);
1625
1825
  writeExtensionsConfig(packages);
1626
1826
  try {
1627
- const { exec: exec2 } = await import("./exec-R2WWZ6FH.js");
1628
- await exec2("npm", ["uninstall", pkg], { cwd: extensionsNpmDir() });
1827
+ const { exec: exec2 } = await import("./exec-ZDD7NEB4.js");
1828
+ await exec2("npm", ["uninstall", "--ignore-scripts", pkg], { cwd: extensionsNpmDir() });
1629
1829
  } catch (err) {
1630
1830
  logger_default.warn(
1631
1831
  `npm uninstall failed for "${pkg}" (may have been manually removed)`,
@@ -2105,7 +2305,15 @@ ${stderr}` : ""}`;
2105
2305
  );
2106
2306
  }
2107
2307
  }
2108
- runScript(script, cwd, mindName) {
2308
+ async runScript(script, cwd, mindName) {
2309
+ if (isSandboxEnabled()) {
2310
+ const dir = this.mindDirs.get(mindName) ?? mindDir(mindName);
2311
+ const [cmd, args] = await wrapForSandbox("bash", ["-c", script], dir, mindName, [
2312
+ dir,
2313
+ mindTmpDir(dir)
2314
+ ]);
2315
+ return exec(cmd, args, { cwd });
2316
+ }
2109
2317
  return exec("bash", ["-c", script], { cwd, mindName });
2110
2318
  }
2111
2319
  deliverSystem(mindName, text, opts) {
@@ -2417,7 +2625,7 @@ async function wakeMind(name) {
2417
2625
  async function startSpiritFull(name) {
2418
2626
  const entry = await findMind(name);
2419
2627
  if (entry?.dir) {
2420
- const { registerMindDir } = await import("./delivery-router-Y66OXJPM.js");
2628
+ const { registerMindDir } = await import("./delivery-router-FDBZJQOY.js");
2421
2629
  registerMindDir(name, entry.dir);
2422
2630
  }
2423
2631
  await getMindManager().startMind(name);
@@ -2439,8 +2647,8 @@ async function stopSpiritFull(name) {
2439
2647
  }).catch((err) => logger_default.error("failed to publish spirit_stopped activity", logger_default.errorData(err)));
2440
2648
  }
2441
2649
  async function ensureCreatorDM(mindName, creatorUsername) {
2442
- const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername: getUserByUsername2 } = await import("./auth-VYW2ECCE.js");
2443
- const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-KW7IYESK.js");
2650
+ const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername: getUserByUsername2 } = await import("./auth-EAASQPTN.js");
2651
+ const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-FSZCUUYO.js");
2444
2652
  const mindUser = await getOrCreateMindUser2(mindName);
2445
2653
  const creatorUser = await getUserByUsername2(creatorUsername);
2446
2654
  if (!creatorUser) {
@@ -2782,9 +2990,9 @@ var SleepManager = class {
2782
2990
  async flushQueuedMessages(name) {
2783
2991
  try {
2784
2992
  const db = await getDb();
2785
- const rows = await db.select().from(deliveryQueue).where(and2(eq2(deliveryQueue.mind, name), eq2(deliveryQueue.status, "sleep-queued"))).all();
2993
+ const rows = await db.select().from(deliveryQueue).where(and2(eq3(deliveryQueue.mind, name), eq3(deliveryQueue.status, "sleep-queued"))).all();
2786
2994
  if (rows.length === 0) return 0;
2787
- const { deliverMessage: deliverMessage2 } = await import("./message-delivery-X4CZE2L6.js");
2995
+ const { deliverMessage: deliverMessage2 } = await import("./message-delivery-HPMELC4Q.js");
2788
2996
  const delivered = [];
2789
2997
  for (const row of rows) {
2790
2998
  try {
@@ -2989,7 +3197,7 @@ var SleepManager = class {
2989
3197
  async buildQueuedSummary(name) {
2990
3198
  try {
2991
3199
  const db = await getDb();
2992
- const rows = await db.select({ channel: deliveryQueue.channel, sender: deliveryQueue.sender }).from(deliveryQueue).where(and2(eq2(deliveryQueue.mind, name), eq2(deliveryQueue.status, "sleep-queued"))).all();
3200
+ const rows = await db.select({ channel: deliveryQueue.channel, sender: deliveryQueue.sender }).from(deliveryQueue).where(and2(eq3(deliveryQueue.mind, name), eq3(deliveryQueue.status, "sleep-queued"))).all();
2993
3201
  if (rows.length === 0) return "No messages arrived while you slept.";
2994
3202
  const channelCounts = /* @__PURE__ */ new Map();
2995
3203
  const senders = /* @__PURE__ */ new Set();
@@ -3105,7 +3313,7 @@ function getSleepManagerIfReady() {
3105
3313
  // packages/daemon/src/lib/delivery/delivery-manager.ts
3106
3314
  import { readFile, realpath } from "fs/promises";
3107
3315
  import { extname, resolve as resolve8 } from "path";
3108
- import { and as and3, eq as eq3, sql as sql2 } from "drizzle-orm";
3316
+ import { and as and3, eq as eq4, sql as sql2 } from "drizzle-orm";
3109
3317
 
3110
3318
  // packages/daemon/src/lib/chat/typing.ts
3111
3319
  var DEFAULT_TTL_MS = 1e4;
@@ -3303,7 +3511,7 @@ var DeliveryManager = class {
3303
3511
  async restoreFromDb() {
3304
3512
  try {
3305
3513
  const db = await getDb();
3306
- const rows = await db.select().from(deliveryQueue).where(eq3(deliveryQueue.status, "pending"));
3514
+ const rows = await db.select().from(deliveryQueue).where(eq4(deliveryQueue.status, "pending"));
3307
3515
  for (const row of rows) {
3308
3516
  let payload;
3309
3517
  try {
@@ -3321,7 +3529,7 @@ var DeliveryManager = class {
3321
3529
  this.addToBatchBuffer(row.mind, row.session, payload, sessionConfig);
3322
3530
  } else {
3323
3531
  try {
3324
- await db.delete(deliveryQueue).where(eq3(deliveryQueue.id, row.id));
3532
+ await db.delete(deliveryQueue).where(eq4(deliveryQueue.id, row.id));
3325
3533
  } catch (err) {
3326
3534
  dlog.warn(`failed to delete queue row ${row.id} for ${row.mind}`, logger_default.errorData(err));
3327
3535
  }
@@ -3342,7 +3550,7 @@ var DeliveryManager = class {
3342
3550
  */
3343
3551
  async getPending(mindName) {
3344
3552
  const db = await getDb();
3345
- const rows = await db.select().from(deliveryQueue).where(and3(eq3(deliveryQueue.mind, mindName), eq3(deliveryQueue.status, "gated")));
3553
+ const rows = await db.select().from(deliveryQueue).where(and3(eq4(deliveryQueue.mind, mindName), eq4(deliveryQueue.status, "gated")));
3346
3554
  const byChannel = /* @__PURE__ */ new Map();
3347
3555
  for (const row of rows) {
3348
3556
  const ch = row.channel ?? "unknown";
@@ -3559,9 +3767,9 @@ var DeliveryManager = class {
3559
3767
  const db = await getDb();
3560
3768
  await db.delete(deliveryQueue).where(
3561
3769
  and3(
3562
- eq3(deliveryQueue.mind, baseName),
3563
- eq3(deliveryQueue.session, session),
3564
- eq3(deliveryQueue.status, "pending")
3770
+ eq4(deliveryQueue.mind, baseName),
3771
+ eq4(deliveryQueue.session, session),
3772
+ eq4(deliveryQueue.status, "pending")
3565
3773
  )
3566
3774
  );
3567
3775
  } catch (err) {
@@ -3689,9 +3897,9 @@ var DeliveryManager = class {
3689
3897
  const db = await getDb();
3690
3898
  const count = await db.select({ count: sql2`count(*)` }).from(deliveryQueue).where(
3691
3899
  and3(
3692
- eq3(deliveryQueue.mind, baseName),
3693
- eq3(deliveryQueue.channel, payload.channel),
3694
- eq3(deliveryQueue.status, "gated")
3900
+ eq4(deliveryQueue.mind, baseName),
3901
+ eq4(deliveryQueue.channel, payload.channel),
3902
+ eq4(deliveryQueue.status, "gated")
3695
3903
  )
3696
3904
  );
3697
3905
  if ((count[0]?.count ?? 0) <= 1) {
@@ -3716,7 +3924,7 @@ var DeliveryManager = class {
3716
3924
  `To accept this channel, add a routing rule for "${channel}" to your routes.json.`,
3717
3925
  `Messages are being held until a route is configured.`
3718
3926
  ].filter((line) => line !== null).join("\n");
3719
- const { sendSystemMessage: sendSystemMessage2 } = await import("./system-chat-HCPHUQGI.js");
3927
+ const { sendSystemMessage: sendSystemMessage2 } = await import("./system-chat-HZUKBIKJ.js");
3720
3928
  await sendSystemMessage2(mindName, notification);
3721
3929
  }
3722
3930
  async persistToQueue(mindName, session, payload, status = "pending") {
@@ -3955,18 +4163,18 @@ async function linkToolResultToTurn(mind, turnId, toolResultContent, toolUseEven
3955
4163
  channel: mindHistory.channel,
3956
4164
  content: mindHistory.content,
3957
4165
  message_id: mindHistory.message_id
3958
- }).from(mindHistory).where(and4(eq4(mindHistory.id, outboundId), eq4(mindHistory.mind, mind))).limit(1);
4166
+ }).from(mindHistory).where(and4(eq5(mindHistory.id, outboundId), eq5(mindHistory.mind, mind))).limit(1);
3959
4167
  const row = rows[0];
3960
4168
  if (!row) {
3961
4169
  dlog2.warn(`outbound marker references missing record: mind=${mind} id=${outboundId}`);
3962
4170
  continue;
3963
4171
  }
3964
- await db.update(mindHistory).set({ turn_id: turnId }).where(eq4(mindHistory.id, outboundId));
4172
+ await db.update(mindHistory).set({ turn_id: turnId }).where(eq5(mindHistory.id, outboundId));
3965
4173
  if (row.message_id) {
3966
4174
  await db.update(messages).set({
3967
4175
  turn_id: turnId,
3968
4176
  ...toolUseEventId != null ? { source_event_id: toolUseEventId } : {}
3969
- }).where(eq4(messages.id, Number(row.message_id)));
4177
+ }).where(eq5(messages.id, Number(row.message_id)));
3970
4178
  }
3971
4179
  publish3(mind, {
3972
4180
  mind,
@@ -4012,14 +4220,14 @@ async function tagUntaggedOutbound(mind, turnId) {
4012
4220
  const range = await db.select({
4013
4221
  minId: sql3`MIN(${mindHistory.id})`,
4014
4222
  maxId: sql3`MAX(${mindHistory.id})`
4015
- }).from(mindHistory).where(and4(eq4(mindHistory.mind, mind), eq4(mindHistory.turn_id, turnId)));
4223
+ }).from(mindHistory).where(and4(eq5(mindHistory.mind, mind), eq5(mindHistory.turn_id, turnId)));
4016
4224
  const minId = range[0]?.minId;
4017
4225
  const maxId = range[0]?.maxId;
4018
4226
  if (minId == null || maxId == null) return;
4019
4227
  const orphans = await db.select({ id: mindHistory.id, message_id: mindHistory.message_id }).from(mindHistory).where(
4020
4228
  and4(
4021
- eq4(mindHistory.mind, mind),
4022
- eq4(mindHistory.type, "outbound"),
4229
+ eq5(mindHistory.mind, mind),
4230
+ eq5(mindHistory.type, "outbound"),
4023
4231
  sql3`${mindHistory.turn_id} IS NULL`,
4024
4232
  sql3`${mindHistory.id} >= ${minId}`,
4025
4233
  sql3`${mindHistory.id} <= ${maxId}`
@@ -4032,9 +4240,9 @@ async function tagUntaggedOutbound(mind, turnId) {
4032
4240
  if (orphansWithMessages.length > 0) {
4033
4241
  const toolUseEvents = await db.select({ id: mindHistory.id }).from(mindHistory).where(
4034
4242
  and4(
4035
- eq4(mindHistory.mind, mind),
4036
- eq4(mindHistory.turn_id, turnId),
4037
- eq4(mindHistory.type, "tool_use")
4243
+ eq5(mindHistory.mind, mind),
4244
+ eq5(mindHistory.turn_id, turnId),
4245
+ eq5(mindHistory.type, "tool_use")
4038
4246
  )
4039
4247
  ).orderBy(mindHistory.id);
4040
4248
  for (const orphan of orphansWithMessages) {
@@ -4048,7 +4256,7 @@ async function tagUntaggedOutbound(mind, turnId) {
4048
4256
  await db.update(messages).set({
4049
4257
  turn_id: turnId,
4050
4258
  ...sourceEventId != null ? { source_event_id: sourceEventId } : {}
4051
- }).where(eq4(messages.id, Number(orphan.message_id)));
4259
+ }).where(eq5(messages.id, Number(orphan.message_id)));
4052
4260
  }
4053
4261
  }
4054
4262
  dlog2.info(`tagged ${orphans.length} orphaned outbound record(s) for ${mind} with turn ${turnId}`);
@@ -4062,22 +4270,22 @@ async function tagUntaggedInbound(mind, turnId, {
4062
4270
  const tagHistoryPromise = (async () => {
4063
4271
  if (!channel) return;
4064
4272
  const historyConditions = [
4065
- eq4(mindHistory.mind, mind),
4066
- eq4(mindHistory.type, "inbound"),
4273
+ eq5(mindHistory.mind, mind),
4274
+ eq5(mindHistory.type, "inbound"),
4067
4275
  sql3`${mindHistory.turn_id} IS NULL`,
4068
4276
  sql3`${mindHistory.created_at} > datetime('now', '-60 seconds')`,
4069
- eq4(mindHistory.channel, channel)
4277
+ eq5(mindHistory.channel, channel)
4070
4278
  ];
4071
4279
  const recentInbounds = await db.select({ id: mindHistory.id }).from(mindHistory).where(and4(...historyConditions)).orderBy(desc(mindHistory.id)).limit(limit);
4072
4280
  if (recentInbounds.length > 0) {
4073
4281
  const ids = recentInbounds.map((r) => r.id);
4074
4282
  await db.update(mindHistory).set({ turn_id: turnId }).where(inArray2(mindHistory.id, ids));
4075
4283
  if (setTrigger) {
4076
- await db.update(turns).set({ trigger_event_id: recentInbounds[0].id }).where(eq4(turns.id, turnId));
4284
+ await db.update(turns).set({ trigger_event_id: recentInbounds[0].id }).where(eq5(turns.id, turnId));
4077
4285
  }
4078
4286
  }
4079
4287
  })();
4080
- const mindUserPromise = db.select({ id: users.id }).from(users).where(and4(eq4(users.username, mind), eq4(users.user_type, "mind"))).get();
4288
+ const mindUserPromise = db.select({ id: users.id }).from(users).where(and4(eq5(users.username, mind), eq5(users.user_type, "mind"))).get();
4081
4289
  const [tagResult, mindUserResult] = await Promise.allSettled([
4082
4290
  tagHistoryPromise,
4083
4291
  mindUserPromise
@@ -4086,7 +4294,7 @@ async function tagUntaggedInbound(mind, turnId, {
4086
4294
  dlog2.error("failed to tag history inbound", logger_default.errorData(tagResult.reason));
4087
4295
  }
4088
4296
  const mindUser = mindUserResult.status === "fulfilled" ? mindUserResult.value : void 0;
4089
- const mindConvIds = mindUser ? (await db.select({ conversation_id: conversationParticipants.conversation_id }).from(conversationParticipants).where(eq4(conversationParticipants.user_id, mindUser.id))).map((r) => r.conversation_id) : [];
4297
+ const mindConvIds = mindUser ? (await db.select({ conversation_id: conversationParticipants.conversation_id }).from(conversationParticipants).where(eq5(conversationParticipants.user_id, mindUser.id))).map((r) => r.conversation_id) : [];
4090
4298
  const recentMsgs = mindConvIds.length > 0 ? await db.select({ id: messages.id }).from(messages).where(
4091
4299
  and4(
4092
4300
  inArray2(messages.conversation_id, mindConvIds),
@@ -4242,7 +4450,7 @@ async function generateSystemReply(conversationId, mindName, message) {
4242
4450
  if (config.sleep.schedule?.wake) contextParts.push(`Wake cron: ${config.sleep.schedule.wake}`);
4243
4451
  }
4244
4452
  try {
4245
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-T3AXQB3R.js");
4453
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OHM3TO62.js");
4246
4454
  const sm = getSleepManagerIfReady2();
4247
4455
  if (sm) {
4248
4456
  const state = sm.getState(mindName);
@@ -4294,7 +4502,6 @@ export {
4294
4502
  generateSystemReply,
4295
4503
  RotatingLog,
4296
4504
  syncProviderToMinds,
4297
- resolveMindToken,
4298
4505
  recordNotice,
4299
4506
  drainNotices,
4300
4507
  clearDeliveredNotices,
@@ -4307,9 +4514,21 @@ export {
4307
4514
  initDeliveryManager,
4308
4515
  getDeliveryManager,
4309
4516
  tryGetDeliveryManager,
4517
+ buildMindBaseEnv,
4310
4518
  MindManager,
4311
4519
  initMindManager,
4312
4520
  getMindManager,
4521
+ invalidateMindUserCache,
4522
+ SESSION_MAX_AGE,
4523
+ invalidateSessionCache,
4524
+ createSession,
4525
+ deleteSession,
4526
+ getSessionUserId,
4527
+ cleanExpiredSessions,
4528
+ requireAdmin,
4529
+ requireAdminOrSystem,
4530
+ authMiddleware,
4531
+ requireSelf,
4313
4532
  readSystemsConfig,
4314
4533
  writeSystemsConfig,
4315
4534
  deleteSystemsConfig,