volute 0.50.0 → 0.52.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 (145) hide show
  1. package/dist/{activity-events-H7YI3BTF.js → activity-events-LQII6PZS.js} +3 -3
  2. package/dist/{ai-service-V4CTNGI3.js → ai-service-YW5SWCSB.js} +7 -3
  3. package/dist/{archive-ORM3ENHI.js → archive-FOHGXHPT.js} +3 -3
  4. package/dist/{auth-DT7GY7EZ.js → auth-KRDSM55Q.js} +6 -4
  5. package/dist/{avatar-image-QEPAP3A5.js → avatar-image-52WGXLHV.js} +3 -3
  6. package/dist/{backup-IE6PMXJO.js → backup-YVGV2ZNM.js} +7 -7
  7. package/dist/{chat-W5K6HCBE.js → chat-VAZ25KVT.js} +4 -4
  8. package/dist/{chunk-5IIVOWSP.js → chunk-2RNMBXD2.js} +16 -0
  9. package/dist/{chunk-U3EJJ7JN.js → chunk-5N32EN4O.js} +2 -2
  10. package/dist/{chunk-ZUG76D3P.js → chunk-5Y54AE3L.js} +1 -1
  11. package/dist/{chunk-5FVANDON.js → chunk-6NLW72HP.js} +2 -2
  12. package/dist/{chunk-ALIVXDM4.js → chunk-724DVYHU.js} +95 -51
  13. package/dist/{chunk-UC6BNMGT.js → chunk-7LT3YZUR.js} +15 -3
  14. package/dist/{chunk-PW65BXY5.js → chunk-7YJY3F2R.js} +11 -1
  15. package/dist/{chunk-7OZWKHA3.js → chunk-AXFLY5GU.js} +28 -5
  16. package/dist/{chunk-SSNZ6ZNN.js → chunk-CV6BNGFK.js} +3 -3
  17. package/dist/{chunk-MLZBBLMT.js → chunk-CW7BQKF6.js} +4 -4
  18. package/dist/{chunk-QFVGPKJI.js → chunk-DMK5ASKV.js} +1 -1
  19. package/dist/{chunk-WBBKYUGF.js → chunk-EDR47UE2.js} +2 -2
  20. package/dist/{chunk-632FJ23O.js → chunk-EGV6R6UF.js} +26 -7
  21. package/dist/{chunk-KAEZOVP6.js → chunk-FLIEXG2T.js} +1 -1
  22. package/dist/{chunk-5TPC4KCV.js → chunk-FXWBFDQR.js} +2 -2
  23. package/dist/{chunk-74T3CEXK.js → chunk-G7A5LEVI.js} +2 -2
  24. package/dist/{chunk-7UWXAJMK.js → chunk-GLM7TVWP.js} +1 -1
  25. package/dist/{chunk-CAIYV33P.js → chunk-H6X6CKDN.js} +2 -1
  26. package/dist/{chunk-C3KLHJDB.js → chunk-HTRSSOHY.js} +1 -1
  27. package/dist/{chunk-77IZUVBB.js → chunk-I7U5EEZC.js} +2 -2
  28. package/dist/{chunk-X67VT4QO.js → chunk-ICXY54ZC.js} +1 -1
  29. package/dist/{chunk-HW6Q7AMB.js → chunk-ITK6HV47.js} +6 -7
  30. package/dist/{chunk-5PKFJHCR.js → chunk-JHKBALS2.js} +2 -2
  31. package/dist/{chunk-SFRYRW37.js → chunk-K2F237KS.js} +9 -9
  32. package/dist/{chunk-7XDOTN4R.js → chunk-L7BKTZ5U.js} +1 -1
  33. package/dist/{chunk-AFSLNUTT.js → chunk-LAUCO2HC.js} +1 -1
  34. package/dist/{chunk-AJWFDIEY.js → chunk-M77B73VV.js} +1 -1
  35. package/dist/{chunk-4CN7OCJE.js → chunk-OXWUEU5V.js} +2 -2
  36. package/dist/{chunk-TGJHGVBZ.js → chunk-RPPTGPYF.js} +4 -4
  37. package/dist/{chunk-JI67D7O2.js → chunk-RU74YG46.js} +120 -25
  38. package/dist/{chunk-7FDWPQCU.js → chunk-SW2U6HRB.js} +6 -6
  39. package/dist/{chunk-574M6I7F.js → chunk-TPX6E6PL.js} +3 -3
  40. package/dist/{chunk-3BAFMGCJ.js → chunk-U54PJPTB.js} +2 -2
  41. package/dist/{chunk-6BM2I736.js → chunk-UDZLPR34.js} +1 -1
  42. package/dist/{chunk-E5S3ILVA.js → chunk-UFTDRTCP.js} +1 -1
  43. package/dist/{chunk-YQOYZ6G7.js → chunk-VPOMJMV6.js} +2 -2
  44. package/dist/{chunk-RRZ4RQQU.js → chunk-X67BDDZR.js} +5 -7
  45. package/dist/{chunk-636GFQNE.js → chunk-XRWUQPCA.js} +8 -7
  46. package/dist/{chunk-7DXLIYPY.js → chunk-YVR6EHWL.js} +6 -6
  47. package/dist/{chunk-EQKSRVDE.js → chunk-ZEZQNP2G.js} +113 -49
  48. package/dist/cli.js +19 -19
  49. package/dist/{clock-LH7UFNLJ.js → clock-ZT5YT6HA.js} +2 -2
  50. package/dist/{cloud-sync-IDJFVDEP.js → cloud-sync-H7EWZASD.js} +22 -22
  51. package/dist/{conversations-S2232Y5I.js → conversations-ZL6PHROD.js} +4 -4
  52. package/dist/{create-2M7DAHQX.js → create-G2RIKQYK.js} +1 -1
  53. package/dist/{daemon-restart-2AAGYFHE.js → daemon-restart-4FWUA5JF.js} +6 -6
  54. package/dist/daemon.js +622 -340
  55. package/dist/{db-QAY45Z56.js → db-BONH4SUG.js} +2 -2
  56. package/dist/{delete-O7PEFQDF.js → delete-CYVZUAV2.js} +4 -0
  57. package/dist/delivery-manager-VYXVKUMP.js +35 -0
  58. package/dist/{delivery-router-JE7SHYNU.js → delivery-router-RHANNTAC.js} +3 -3
  59. package/dist/{down-D4IRNEMJ.js → down-QSNEMTTX.js} +5 -5
  60. package/dist/echo-text-PEEV7FQU.js +39 -0
  61. package/dist/{env-ABM5IMA7.js → env-IBW2QI6K.js} +1 -1
  62. package/dist/{env-AZK5X4W7.js → env-SQFCWW52.js} +3 -3
  63. package/dist/{exec-2H65LMTA.js → exec-ABD3DYA2.js} +3 -3
  64. package/dist/{export-3E3EL6W3.js → export-VBNWM7I4.js} +3 -3
  65. package/dist/{extensions-7KP3X6G7.js → extensions-N6L5NYTK.js} +22 -22
  66. package/dist/{files-6BMKVG5G.js → files-BRY5RRIM.js} +3 -3
  67. package/dist/{import-UPNTEBBT.js → import-DB2KULRO.js} +6 -6
  68. package/dist/{isolation-OKDFM6WA.js → isolation-GVV2IBAU.js} +3 -3
  69. package/dist/{join-PYA36HEC.js → join-KLRU72JJ.js} +10 -2
  70. package/dist/{list-4BVGH7AN.js → list-UQGIW7OF.js} +1 -1
  71. package/dist/{login-MOXVLULE.js → login-SB5OENMV.js} +2 -2
  72. package/dist/{logout-DWD3OQVT.js → logout-YFZAJRPY.js} +2 -2
  73. package/dist/message-delivery-7URC52ME.js +43 -0
  74. package/dist/{migrate-thread-config-4A5LW36Z.js → migrate-thread-config-EQSEP2XG.js} +2 -2
  75. package/dist/{mind-NYRALSV2.js → mind-NEXGT3KE.js} +9 -9
  76. package/dist/{mind-activity-tracker-L7GCYXQR.js → mind-activity-tracker-QF6DCX2X.js} +4 -4
  77. package/dist/{mind-history-NXXOOTX6.js → mind-history-OGNR4L7W.js} +1 -1
  78. package/dist/mind-service-E26ZQXDS.js +47 -0
  79. package/dist/{mind-sleep-TH6BRQ5X.js → mind-sleep-LZAFBDZD.js} +2 -2
  80. package/dist/{package-XYSV7NUT.js → package-2W2XKSIP.js} +2 -2
  81. package/dist/{prompts-QKFPX6DQ.js → prompts-NBO3HRK3.js} +3 -3
  82. package/dist/{read-ZXGUT4QC.js → read-RJ5NAW5J.js} +3 -14
  83. package/dist/{registry-4UF6OCOE.js → registry-TRC2HJXR.js} +2 -2
  84. package/dist/{sandbox-EGEU5GGE.js → sandbox-NNWCTHRI.js} +3 -3
  85. package/dist/scheduler-JTTWZDYU.js +25 -0
  86. package/dist/{schema-C2GIPD4V.js → schema-ZZQVM4GR.js} +3 -1
  87. package/dist/{seed-3IMBOAGK.js → seed-64XEHRUP.js} +1 -1
  88. package/dist/{seed-cmd-U73XVQMI.js → seed-cmd-UEL2QB3Q.js} +2 -2
  89. package/dist/{seed-create-FBLNVSUP.js → seed-create-4JRQDPGA.js} +3 -3
  90. package/dist/{seed-readiness-QRA46ZJQ.js → seed-readiness-DYOVCYHN.js} +4 -4
  91. package/dist/{seed-sprout-3B4SZX7J.js → seed-sprout-NIDIOJXT.js} +7 -7
  92. package/dist/{send-NBRZJXKX.js → send-2YKOZJJ5.js} +81 -49
  93. package/dist/{service-XMXAXGJD.js → service-XQPMZAGI.js} +4 -4
  94. package/dist/{service-install-MOKTEG7B.js → service-install-2EWD7KXD.js} +5 -5
  95. package/dist/{setup-JGYAXXW7.js → setup-4IX6PCD3.js} +6 -6
  96. package/dist/{setup-CAJFOR2N.js → setup-WZSXHHRJ.js} +2 -2
  97. package/dist/{skill-NXIHDQCG.js → skill-B5OJEQUA.js} +1 -1
  98. package/dist/skills/volute-mind/references/variants.md +1 -1
  99. package/dist/{skills-5MSMT7PT.js → skills-MPUALV3S.js} +4 -4
  100. package/dist/sleep-manager-OFP2GFXF.js +41 -0
  101. package/dist/{spirit-IL5EMWYZ.js → spirit-4ECYIVGE.js} +7 -7
  102. package/dist/spirit-availability-Y54Y3675.js +42 -0
  103. package/dist/{sprout-UPXGJ5HX.js → sprout-GJMZFRGZ.js} +1 -1
  104. package/dist/{status-IL67CYM4.js → status-MWLE3RVC.js} +5 -5
  105. package/dist/{system-events-A6IGCEC3.js → system-events-V43HDA3T.js} +5 -3
  106. package/dist/{tailscale-SJUW2ETR.js → tailscale-KHNZFC7L.js} +2 -2
  107. package/dist/{template-hash-GSOUARW4.js → template-hash-YKWMVYMM.js} +2 -2
  108. package/dist/{template-staleness-T27VCGYA.js → template-staleness-PY2CULH6.js} +5 -5
  109. package/dist/{turn-tracker-6EI2EL7G.js → turn-tracker-C5PVIC3B.js} +5 -5
  110. package/dist/{up-CLL4665A.js → up-H6LJZDRK.js} +5 -5
  111. package/dist/{update-HVAUCQPN.js → update-CIWI2JYA.js} +5 -5
  112. package/dist/{update-check-2MGBBAFF.js → update-check-SZ7B5IFI.js} +3 -3
  113. package/dist/variant-cleanup-STC6B5HR.js +22 -0
  114. package/dist/{version-notify-7BUHWZNT.js → version-notify-LBVHH5YV.js} +8 -8
  115. package/dist/web-assets/assets/index-B_eYTa3R.js +97 -0
  116. package/dist/web-assets/assets/index-DhZrzddW.css +1 -0
  117. package/dist/web-assets/index.html +2 -2
  118. package/drizzle/0018_api_tokens.sql +20 -0
  119. package/drizzle/meta/_journal.json +7 -0
  120. package/package.json +2 -2
  121. package/templates/_base/{biome.json.tmpl → biome.json} +2 -1
  122. package/templates/_base/gitignore +44 -0
  123. package/templates/_base/home/public/.gitkeep +0 -0
  124. package/templates/_base/src/lib/auto-commit.ts +49 -11
  125. package/templates/_base/src/lib/format-prefix.ts +15 -8
  126. package/templates/_base/src/lib/router.ts +13 -8
  127. package/templates/claude/volute-template.json +1 -3
  128. package/templates/codex/volute-template.json +1 -3
  129. package/templates/pi/{package.json.tmpl → package.json} +2 -2
  130. package/templates/pi/volute-template.json +1 -3
  131. package/dist/delivery-manager-B4OKWD2P.js +0 -33
  132. package/dist/echo-text-WYAAODBV.js +0 -39
  133. package/dist/message-delivery-3456PXB7.js +0 -43
  134. package/dist/mind-service-5TA7UJAT.js +0 -47
  135. package/dist/scheduler-UV6RUJ7P.js +0 -25
  136. package/dist/sleep-manager-LIEPO6WG.js +0 -41
  137. package/dist/spirit-availability-YFEGJNJ2.js +0 -42
  138. package/dist/variant-cleanup-HJ7Z75R6.js +0 -22
  139. package/dist/web-assets/assets/index-ClsUcXiW.js +0 -95
  140. package/dist/web-assets/assets/index-Dz3wTbtR.css +0 -1
  141. /package/templates/_base/home/.config/{config.json.tmpl → config.json} +0 -0
  142. /package/templates/claude/{package.json.tmpl → package.json} +0 -0
  143. /package/templates/codex/home/.config/{config.json.tmpl → config.json} +0 -0
  144. /package/templates/codex/{package.json.tmpl → package.json} +0 -0
  145. /package/templates/pi/home/.config/{config.json.tmpl → config.json} +0 -0
@@ -1,36 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  spiritDir
4
- } from "./chunk-SFRYRW37.js";
4
+ } from "./chunk-K2F237KS.js";
5
5
  import {
6
6
  getScheduler
7
- } from "./chunk-7FDWPQCU.js";
7
+ } from "./chunk-SW2U6HRB.js";
8
8
  import {
9
9
  getDeliveryManager
10
- } from "./chunk-JI67D7O2.js";
10
+ } from "./chunk-RU74YG46.js";
11
11
  import {
12
12
  getMindManager,
13
13
  resolveMindToken
14
- } from "./chunk-ALIVXDM4.js";
14
+ } from "./chunk-724DVYHU.js";
15
15
  import {
16
16
  extractTextContent,
17
17
  getRoutingConfig,
18
18
  resolveRoute,
19
19
  shouldGate
20
- } from "./chunk-6BM2I736.js";
20
+ } from "./chunk-UDZLPR34.js";
21
21
  import {
22
22
  hashSkillDir,
23
23
  importSkillFromDir,
24
24
  removeSharedSkill,
25
25
  sharedSkillsDir
26
- } from "./chunk-TGJHGVBZ.js";
26
+ } from "./chunk-RPPTGPYF.js";
27
27
  import {
28
28
  getOrCreateMindUser,
29
29
  getOrCreateSystemUser,
30
30
  getUser,
31
31
  getUserByUsername,
32
32
  syncMindProfile
33
- } from "./chunk-UC6BNMGT.js";
33
+ } from "./chunk-7LT3YZUR.js";
34
34
  import {
35
35
  MIND_LEVEL_THREAD,
36
36
  deliverEvent,
@@ -38,13 +38,13 @@ import {
38
38
  pendingEventCount,
39
39
  pendingEventsLine,
40
40
  recordNotice
41
- } from "./chunk-7OZWKHA3.js";
41
+ } from "./chunk-AXFLY5GU.js";
42
42
  import {
43
43
  publish as publish2
44
44
  } from "./chunk-LNNI3MS4.js";
45
45
  import {
46
46
  getPrompt
47
- } from "./chunk-5TPC4KCV.js";
47
+ } from "./chunk-FXWBFDQR.js";
48
48
  import {
49
49
  addMessage,
50
50
  createChannel,
@@ -55,14 +55,14 @@ import {
55
55
  getParticipants,
56
56
  joinChannel,
57
57
  updateChannelSettings
58
- } from "./chunk-574M6I7F.js";
58
+ } from "./chunk-TPX6E6PL.js";
59
59
  import {
60
60
  markIdle
61
- } from "./chunk-E5S3ILVA.js";
61
+ } from "./chunk-UFTDRTCP.js";
62
62
  import {
63
63
  publish,
64
64
  subscribe
65
- } from "./chunk-3BAFMGCJ.js";
65
+ } from "./chunk-U54PJPTB.js";
66
66
  import {
67
67
  readVoluteConfig,
68
68
  resolveWakeTriggers
@@ -70,10 +70,10 @@ import {
70
70
  import {
71
71
  isIsolationEnabled,
72
72
  mindUserName
73
- } from "./chunk-AJWFDIEY.js";
73
+ } from "./chunk-M77B73VV.js";
74
74
  import {
75
75
  missingCredentialWarning
76
- } from "./chunk-632FJ23O.js";
76
+ } from "./chunk-EGV6R6UF.js";
77
77
  import {
78
78
  logger_default
79
79
  } from "./chunk-QUSMYGNQ.js";
@@ -90,14 +90,15 @@ import {
90
90
  voluteHome,
91
91
  voluteSystemDir,
92
92
  writeGlobalConfig
93
- } from "./chunk-CAIYV33P.js";
93
+ } from "./chunk-H6X6CKDN.js";
94
94
  import {
95
95
  activity,
96
+ apiTokens,
96
97
  deliveryQueue,
97
98
  messages,
98
99
  mindHistory,
99
100
  sessions
100
- } from "./chunk-5IIVOWSP.js";
101
+ } from "./chunk-2RNMBXD2.js";
101
102
 
102
103
  // packages/daemon/src/lib/extensions.ts
103
104
  import { existsSync as existsSync5, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
@@ -105,9 +106,43 @@ import { dirname, resolve as resolve5 } from "path";
105
106
 
106
107
  // packages/daemon/src/web/middleware/auth.ts
107
108
  import { timingSafeEqual } from "crypto";
108
- import { eq, lt } from "drizzle-orm";
109
+ import { eq as eq2, lt } from "drizzle-orm";
109
110
  import { getCookie } from "hono/cookie";
110
111
  import { createMiddleware } from "hono/factory";
112
+
113
+ // packages/daemon/src/lib/api-tokens.ts
114
+ import { createHash, randomBytes } from "crypto";
115
+ import { and, eq } from "drizzle-orm";
116
+ var API_TOKEN_PREFIX = "vmt_";
117
+ function generateToken() {
118
+ return API_TOKEN_PREFIX + randomBytes(32).toString("base64url");
119
+ }
120
+ function hashToken(token) {
121
+ return createHash("sha256").update(token).digest("hex");
122
+ }
123
+ async function issueApiToken(userId, label) {
124
+ const db = await getDb();
125
+ const token = generateToken();
126
+ const [row] = await db.insert(apiTokens).values({ user_id: userId, token_hash: hashToken(token), label: label ?? null }).returning({ id: apiTokens.id, label: apiTokens.label, created_at: apiTokens.created_at });
127
+ return { id: row.id, token, label: row.label, created_at: row.created_at };
128
+ }
129
+ async function resolveApiToken(token) {
130
+ if (!token.startsWith(API_TOKEN_PREFIX)) return null;
131
+ const db = await getDb();
132
+ const row = await db.select({ user_id: apiTokens.user_id }).from(apiTokens).where(eq(apiTokens.token_hash, hashToken(token))).get();
133
+ return row?.user_id ?? null;
134
+ }
135
+ async function revokeApiToken(userId, id) {
136
+ const db = await getDb();
137
+ const rows = await db.delete(apiTokens).where(and(eq(apiTokens.id, id), eq(apiTokens.user_id, userId))).returning({ id: apiTokens.id });
138
+ return rows.length > 0;
139
+ }
140
+ async function listApiTokens(userId) {
141
+ const db = await getDb();
142
+ return db.select({ id: apiTokens.id, label: apiTokens.label, created_at: apiTokens.created_at }).from(apiTokens).where(eq(apiTokens.user_id, userId)).orderBy(apiTokens.id).all();
143
+ }
144
+
145
+ // packages/daemon/src/web/middleware/auth.ts
111
146
  var MIND_USER_CACHE_TTL = 5 * 60 * 1e3;
112
147
  var mindUserCache = /* @__PURE__ */ new Map();
113
148
  var alog = logger_default.child("auth");
@@ -142,14 +177,14 @@ async function createSession(userId) {
142
177
  async function deleteSession(sessionId) {
143
178
  sessionCache.delete(sessionId);
144
179
  const db = await getDb();
145
- await db.delete(sessions).where(eq(sessions.id, sessionId));
180
+ await db.delete(sessions).where(eq2(sessions.id, sessionId));
146
181
  }
147
182
  async function getSessionUserId(sessionId) {
148
183
  const db = await getDb();
149
- const row = await db.select().from(sessions).where(eq(sessions.id, sessionId)).get();
184
+ const row = await db.select().from(sessions).where(eq2(sessions.id, sessionId)).get();
150
185
  if (!row) return void 0;
151
186
  if (Date.now() - row.createdAt > SESSION_MAX_AGE) {
152
- await db.delete(sessions).where(eq(sessions.id, sessionId));
187
+ await db.delete(sessions).where(eq2(sessions.id, sessionId));
153
188
  return void 0;
154
189
  }
155
190
  return row.userId;
@@ -231,6 +266,18 @@ var authMiddleware = createMiddleware(async (c, next) => {
231
266
  await next();
232
267
  return;
233
268
  }
269
+ if (token.startsWith(API_TOKEN_PREFIX)) {
270
+ const userId = await resolveApiToken(token);
271
+ if (userId != null) {
272
+ const user2 = await getUser(userId);
273
+ if (user2) {
274
+ if (user2.role === "pending") return c.json({ error: "Account pending approval" }, 403);
275
+ c.set("user", user2);
276
+ await next();
277
+ return;
278
+ }
279
+ }
280
+ }
234
281
  if (token) {
235
282
  const user2 = await resolveSession(token);
236
283
  if (user2) {
@@ -262,7 +309,7 @@ var requireSelf = (paramName = "name") => createMiddleware(async (c, next) => {
262
309
  });
263
310
 
264
311
  // packages/daemon/src/lib/delivery/message-delivery.ts
265
- import { and as and2, eq as eq3, inArray as inArray2 } from "drizzle-orm";
312
+ import { and as and3, eq as eq4, inArray as inArray2 } from "drizzle-orm";
266
313
 
267
314
  // packages/daemon/src/lib/daemon/sleep-manager.ts
268
315
  import { execFile, spawn as spawnChild } from "child_process";
@@ -278,7 +325,7 @@ import {
278
325
  import { resolve as resolve4 } from "path";
279
326
  import { promisify } from "util";
280
327
  import { CronExpressionParser } from "cron-parser";
281
- import { and, eq as eq2, inArray } from "drizzle-orm";
328
+ import { and as and2, eq as eq3, inArray } from "drizzle-orm";
282
329
 
283
330
  // packages/daemon/src/lib/daemon/mind-service.ts
284
331
  import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
@@ -292,7 +339,7 @@ async function ensureSystemDM(mindName) {
292
339
  const systemUser = await getOrCreateSystemUser();
293
340
  const mindUser = await getOrCreateMindUser(mindName);
294
341
  if (systemUser.id === mindUser.id) {
295
- throw new Error(`Cannot create system DM: mind "${mindName}" is the system user`);
342
+ return null;
296
343
  }
297
344
  const existing = await findDMConversation([systemUser.id, mindUser.id]);
298
345
  if (existing) {
@@ -844,8 +891,16 @@ async function startMindFull(name) {
844
891
  (err) => logger_default.error(`failed to ensure system DM for ${baseName}`, logger_default.errorData(err))
845
892
  );
846
893
  const dir = mindDir(baseName);
847
- getScheduler().loadSchedules(baseName);
848
- getSleepManagerIfReady()?.loadSleepConfig(baseName);
894
+ try {
895
+ getScheduler().loadSchedules(baseName);
896
+ } catch (err) {
897
+ logger_default.error(`failed to load schedules for ${baseName}`, logger_default.errorData(err));
898
+ }
899
+ try {
900
+ getSleepManagerIfReady()?.loadSleepConfig(baseName);
901
+ } catch (err) {
902
+ logger_default.error(`failed to load sleep config for ${baseName}`, logger_default.errorData(err));
903
+ }
849
904
  ensureMailAddress(baseName).catch(
850
905
  (err) => logger_default.error(`failed to ensure mail address for ${baseName}`, logger_default.errorData(err))
851
906
  );
@@ -859,16 +914,24 @@ async function startMindFull(name) {
859
914
  (err) => logger_default.warn(`failed to join #system for ${baseName}`, logger_default.errorData(err))
860
915
  );
861
916
  if (config?.tokenBudget) {
862
- getTokenBudget().setBudget(
863
- baseName,
864
- config.tokenBudget,
865
- config.tokenBudgetPeriodMinutes ?? DEFAULT_BUDGET_PERIOD_MINUTES
866
- );
917
+ try {
918
+ getTokenBudget().setBudget(
919
+ baseName,
920
+ config.tokenBudget,
921
+ config.tokenBudgetPeriodMinutes ?? DEFAULT_BUDGET_PERIOD_MINUTES
922
+ );
923
+ } catch (err) {
924
+ logger_default.error(`failed to set token budget for ${baseName}`, logger_default.errorData(err));
925
+ }
926
+ }
927
+ try {
928
+ notifyExtensionsMindStart(baseName);
929
+ } catch (err) {
930
+ logger_default.error(`failed to notify extensions of mind start for ${baseName}`, logger_default.errorData(err));
867
931
  }
868
- notifyExtensionsMindStart(baseName);
869
932
  }
870
933
  async function recordMissingCredentialsNotice(mind, template) {
871
- const { hasUndeliveredEvent, recordNotice: recordNotice2, MIND_LEVEL_THREAD: MIND_LEVEL_THREAD2 } = await import("./system-events-A6IGCEC3.js");
934
+ const { hasUndeliveredEvent, recordNotice: recordNotice2, MIND_LEVEL_THREAD: MIND_LEVEL_THREAD2 } = await import("./system-events-V43HDA3T.js");
872
935
  const warning = await missingCredentialWarning(template, readMindModel(mind, template), mind);
873
936
  if (!warning) return;
874
937
  if (await hasUndeliveredEvent(mind, "no_credentials")) return;
@@ -912,7 +975,7 @@ async function wakeMind(name) {
912
975
  async function startSpiritFull(name) {
913
976
  const entry = await findMind(name);
914
977
  if (entry?.dir) {
915
- const { registerMindDir } = await import("./delivery-router-JE7SHYNU.js");
978
+ const { registerMindDir } = await import("./delivery-router-RHANNTAC.js");
916
979
  registerMindDir(name, entry.dir);
917
980
  }
918
981
  await getMindManager().startMind(name);
@@ -945,7 +1008,7 @@ function buildSeedOrientation(createdBy, creatorType) {
945
1008
  async function sendSeedOrientation(mindName, createdBy) {
946
1009
  let creatorType;
947
1010
  if (createdBy) {
948
- const { getUserByUsername: getUserByUsername2 } = await import("./auth-DT7GY7EZ.js");
1011
+ const { getUserByUsername: getUserByUsername2 } = await import("./auth-KRDSM55Q.js");
949
1012
  creatorType = (await getUserByUsername2(createdBy))?.user_type;
950
1013
  }
951
1014
  await deliverEvent(mindName, {
@@ -954,8 +1017,8 @@ async function sendSeedOrientation(mindName, createdBy) {
954
1017
  });
955
1018
  }
956
1019
  async function ensureCreatorDM(mindName, creatorUsername) {
957
- const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername: getUserByUsername2 } = await import("./auth-DT7GY7EZ.js");
958
- const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-S2232Y5I.js");
1020
+ const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername: getUserByUsername2 } = await import("./auth-KRDSM55Q.js");
1021
+ const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-ZL6PHROD.js");
959
1022
  const mindUser = await getOrCreateMindUser2(mindName);
960
1023
  const creatorUser = await getUserByUsername2(creatorUsername);
961
1024
  if (!creatorUser) {
@@ -1318,7 +1381,7 @@ var SleepManager = class {
1318
1381
  async flushQueuedMessages(name) {
1319
1382
  try {
1320
1383
  const db = await getDb();
1321
- const rows = await db.select().from(deliveryQueue).where(and(eq2(deliveryQueue.mind, name), eq2(deliveryQueue.status, "sleep-queued"))).all();
1384
+ const rows = await db.select().from(deliveryQueue).where(and2(eq3(deliveryQueue.mind, name), eq3(deliveryQueue.status, "sleep-queued"))).all();
1322
1385
  if (rows.length === 0) return 0;
1323
1386
  const groups = /* @__PURE__ */ new Map();
1324
1387
  for (const row of rows) {
@@ -1330,7 +1393,7 @@ var SleepManager = class {
1330
1393
  `dropping unparseable queued message ${row.id} for ${name}`,
1331
1394
  logger_default.errorData(err)
1332
1395
  );
1333
- await db.delete(deliveryQueue).where(eq2(deliveryQueue.id, row.id));
1396
+ await db.delete(deliveryQueue).where(eq3(deliveryQueue.id, row.id));
1334
1397
  continue;
1335
1398
  }
1336
1399
  const channel = payload.channel ?? "unknown";
@@ -1373,7 +1436,7 @@ var SleepManager = class {
1373
1436
  * the real delivery stack. Returns whether the batch was handed off to the mind.
1374
1437
  */
1375
1438
  async deliverQueuedBatch(name, payloads) {
1376
- const { deliverBatch: deliverBatch2 } = await import("./message-delivery-3456PXB7.js");
1439
+ const { deliverBatch: deliverBatch2 } = await import("./message-delivery-7URC52ME.js");
1377
1440
  return deliverBatch2(name, payloads);
1378
1441
  }
1379
1442
  // --- Wake failure handling (#419) ---
@@ -1653,7 +1716,7 @@ var SleepManager = class {
1653
1716
  async buildQueuedSummary(name) {
1654
1717
  try {
1655
1718
  const db = await getDb();
1656
- const rows = await db.select({ channel: deliveryQueue.channel, sender: deliveryQueue.sender }).from(deliveryQueue).where(and(eq2(deliveryQueue.mind, name), eq2(deliveryQueue.status, "sleep-queued"))).all();
1719
+ 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();
1657
1720
  if (rows.length === 0) return "No messages arrived while you slept.";
1658
1721
  const channelCounts = /* @__PURE__ */ new Map();
1659
1722
  const senders = /* @__PURE__ */ new Set();
@@ -1824,7 +1887,7 @@ async function linkToolResultToTurn(mind, turnId, toolResultContent, toolUseEven
1824
1887
  content: mindHistory.content,
1825
1888
  message_id: mindHistory.message_id,
1826
1889
  turn_id: mindHistory.turn_id
1827
- }).from(mindHistory).where(and2(eq3(mindHistory.id, outboundId), eq3(mindHistory.mind, mind))).limit(1);
1890
+ }).from(mindHistory).where(and3(eq4(mindHistory.id, outboundId), eq4(mindHistory.mind, mind))).limit(1);
1828
1891
  const row = rows[0];
1829
1892
  if (!row) {
1830
1893
  dlog.warn(`outbound marker references missing record: mind=${mind} id=${outboundId}`);
@@ -1832,13 +1895,13 @@ async function linkToolResultToTurn(mind, turnId, toolResultContent, toolUseEven
1832
1895
  }
1833
1896
  const alreadyTagged = row.turn_id != null;
1834
1897
  if (!alreadyTagged) {
1835
- await db.update(mindHistory).set({ turn_id: turnId }).where(eq3(mindHistory.id, outboundId));
1898
+ await db.update(mindHistory).set({ turn_id: turnId }).where(eq4(mindHistory.id, outboundId));
1836
1899
  }
1837
1900
  if (row.message_id) {
1838
1901
  await db.update(messages).set({
1839
1902
  turn_id: turnId,
1840
1903
  ...toolUseEventId != null ? { source_event_id: toolUseEventId } : {}
1841
- }).where(eq3(messages.id, Number(row.message_id)));
1904
+ }).where(eq4(messages.id, Number(row.message_id)));
1842
1905
  }
1843
1906
  if (!alreadyTagged) {
1844
1907
  publish2(mind, {
@@ -2029,9 +2092,7 @@ async function backfillSystemChannelMembers() {
2029
2092
  }
2030
2093
  async function announceToSystem(text) {
2031
2094
  const channelId = await ensureSystemChannel();
2032
- const systemUser = await getOrCreateSystemUser();
2033
- await joinChannel(channelId, systemUser.id);
2034
- await addMessage(channelId, "user", systemUser.username, [{ type: "text", text }]);
2095
+ await addMessage(channelId, "event", null, [{ type: "text", text }]);
2035
2096
  const participants = await getParticipants(channelId);
2036
2097
  const mindParticipants = participants.filter((p) => p.userType === "mind");
2037
2098
  const channel = "#system";
@@ -2040,7 +2101,7 @@ async function announceToSystem(text) {
2040
2101
  content: [{ type: "text", text }],
2041
2102
  channel,
2042
2103
  conversationId: channelId,
2043
- sender: systemUser.username,
2104
+ sender: null,
2044
2105
  participants: participants.map((p) => p.username),
2045
2106
  participantCount: participants.length,
2046
2107
  isDM: false
@@ -2683,7 +2744,7 @@ async function installNpmExtension(pkg) {
2683
2744
  throw new Error(`Extension "${pkg}" is already installed`);
2684
2745
  }
2685
2746
  const dir = ensureExtensionsNpmDir();
2686
- const { exec } = await import("./exec-2H65LMTA.js");
2747
+ const { exec } = await import("./exec-ABD3DYA2.js");
2687
2748
  try {
2688
2749
  await exec("npm", ["install", "--ignore-scripts", pkg], { cwd: dir });
2689
2750
  } catch (err) {
@@ -2704,7 +2765,7 @@ async function uninstallNpmExtension(pkg) {
2704
2765
  packages.splice(idx, 1);
2705
2766
  writeExtensionsConfig(packages);
2706
2767
  try {
2707
- const { exec } = await import("./exec-2H65LMTA.js");
2768
+ const { exec } = await import("./exec-ABD3DYA2.js");
2708
2769
  await exec("npm", ["uninstall", "--ignore-scripts", pkg], { cwd: extensionsNpmDir() });
2709
2770
  } catch (err) {
2710
2771
  logger_default.warn(
@@ -2798,6 +2859,9 @@ function notifyExtensionsMindStop(mindName) {
2798
2859
  }
2799
2860
 
2800
2861
  export {
2862
+ issueApiToken,
2863
+ revokeApiToken,
2864
+ listApiTokens,
2801
2865
  invalidateMindUserCache,
2802
2866
  SESSION_MAX_AGE,
2803
2867
  invalidateSessionCache,
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ if (!process.env.VOLUTE_HOME) {
10
10
  var command = process.argv[2];
11
11
  var args = process.argv.slice(3);
12
12
  if (command === "--version" || command === "-v") {
13
- const { default: pkg } = await import("./package-XYSV7NUT.js");
13
+ const { default: pkg } = await import("./package-2W2XKSIP.js");
14
14
  console.log(pkg.version);
15
15
  process.exit(0);
16
16
  }
@@ -34,7 +34,7 @@ var ungatedCommands = /* @__PURE__ */ new Set([
34
34
  ]);
35
35
  var isMind = !!process.env.VOLUTE_MIND_TOKEN;
36
36
  if (!isMind && !ungatedCommands.has(command)) {
37
- const { setupStatus, setupUrl } = await import("./setup-CAJFOR2N.js");
37
+ const { setupStatus, setupUrl } = await import("./setup-WZSXHHRJ.js");
38
38
  const status = setupStatus();
39
39
  if (status !== "complete") {
40
40
  if (status === "in-progress") {
@@ -56,49 +56,49 @@ if (!isMind && !ungatedCommands.has(command)) {
56
56
  }
57
57
  switch (command) {
58
58
  case "setup":
59
- await import("./setup-JGYAXXW7.js").then((m) => m.run(args));
59
+ await import("./setup-4IX6PCD3.js").then((m) => m.run(args));
60
60
  break;
61
61
  case "mind":
62
- await import("./mind-NYRALSV2.js").then((m) => m.run(args));
62
+ await import("./mind-NEXGT3KE.js").then((m) => m.run(args));
63
63
  break;
64
64
  case "seed":
65
- await import("./seed-cmd-U73XVQMI.js").then((m) => m.run(args));
65
+ await import("./seed-cmd-UEL2QB3Q.js").then((m) => m.run(args));
66
66
  break;
67
67
  case "chat":
68
- await import("./chat-W5K6HCBE.js").then((m) => m.run(args));
68
+ await import("./chat-VAZ25KVT.js").then((m) => m.run(args));
69
69
  break;
70
70
  case "variant":
71
71
  await import("./variant-HHDTW74J.js").then((m) => m.run(args));
72
72
  break;
73
73
  case "clock":
74
- await import("./clock-LH7UFNLJ.js").then((m) => m.run(args));
74
+ await import("./clock-ZT5YT6HA.js").then((m) => m.run(args));
75
75
  break;
76
76
  case "skill":
77
- await import("./skill-NXIHDQCG.js").then((m) => m.run(args));
77
+ await import("./skill-B5OJEQUA.js").then((m) => m.run(args));
78
78
  break;
79
79
  case "env":
80
- await import("./env-ABM5IMA7.js").then((m) => m.run(args));
80
+ await import("./env-IBW2QI6K.js").then((m) => m.run(args));
81
81
  break;
82
82
  case "config":
83
83
  await import("./config-UGJS57VT.js").then((m) => m.run(args));
84
84
  break;
85
85
  case "up":
86
- await import("./up-CLL4665A.js").then((m) => m.run(args));
86
+ await import("./up-H6LJZDRK.js").then((m) => m.run(args));
87
87
  break;
88
88
  case "backup":
89
- await import("./backup-IE6PMXJO.js").then((m) => m.run(args));
89
+ await import("./backup-YVGV2ZNM.js").then((m) => m.run(args));
90
90
  break;
91
91
  case "down":
92
- await import("./down-D4IRNEMJ.js").then((m) => m.run(args));
92
+ await import("./down-QSNEMTTX.js").then((m) => m.run(args));
93
93
  break;
94
94
  case "restart":
95
- await import("./daemon-restart-2AAGYFHE.js").then((m) => m.run(args));
95
+ await import("./daemon-restart-4FWUA5JF.js").then((m) => m.run(args));
96
96
  break;
97
97
  case "update":
98
- await import("./update-HVAUCQPN.js").then((m) => m.run(args));
98
+ await import("./update-CIWI2JYA.js").then((m) => m.run(args));
99
99
  break;
100
100
  case "status":
101
- await import("./status-IL67CYM4.js").then((m) => m.run(args));
101
+ await import("./status-MWLE3RVC.js").then((m) => m.run(args));
102
102
  break;
103
103
  case "extension":
104
104
  await import("./extension-MRYJWSMV.js").then((m) => m.run(args));
@@ -107,13 +107,13 @@ switch (command) {
107
107
  await import("./systems-VDRUZXNF.js").then((m) => m.run(args));
108
108
  break;
109
109
  case "login":
110
- await import("./login-MOXVLULE.js").then((m) => m.run(args));
110
+ await import("./login-SB5OENMV.js").then((m) => m.run(args));
111
111
  break;
112
112
  case "logout":
113
- await import("./logout-DWD3OQVT.js").then((m) => m.run(args));
113
+ await import("./logout-YFZAJRPY.js").then((m) => m.run(args));
114
114
  break;
115
115
  case "service":
116
- await import("./service-XMXAXGJD.js").then((m) => m.run(args));
116
+ await import("./service-XQPMZAGI.js").then((m) => m.run(args));
117
117
  break;
118
118
  case "--help":
119
119
  case "-h":
@@ -310,7 +310,7 @@ Run 'volute --help' for usage.`);
310
310
  }
311
311
  }
312
312
  if (command !== "update") {
313
- import("./update-check-2MGBBAFF.js").then((m) => m.checkForUpdate()).then((result) => {
313
+ import("./update-check-SZ7B5IFI.js").then((m) => m.checkForUpdate()).then((result) => {
314
314
  if (result.updateAvailable) {
315
315
  console.error(`
316
316
  Update available: ${result.current} \u2192 ${result.latest}`);
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  parseDuration,
4
4
  run
5
- } from "./chunk-74T3CEXK.js";
6
- import "./chunk-PW65BXY5.js";
5
+ } from "./chunk-G7A5LEVI.js";
6
+ import "./chunk-7YJY3F2R.js";
7
7
  import "./chunk-BTY4WNFE.js";
8
8
  import "./chunk-M74I3HHF.js";
9
9
  import "./chunk-LOPXTW6H.js";
@@ -1,37 +1,37 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  deliverMessage
4
- } from "./chunk-EQKSRVDE.js";
5
- import "./chunk-SFRYRW37.js";
6
- import "./chunk-RRZ4RQQU.js";
7
- import "./chunk-7FDWPQCU.js";
8
- import "./chunk-JI67D7O2.js";
9
- import "./chunk-ALIVXDM4.js";
10
- import "./chunk-6BM2I736.js";
11
- import "./chunk-7DXLIYPY.js";
12
- import "./chunk-TGJHGVBZ.js";
13
- import "./chunk-UC6BNMGT.js";
14
- import "./chunk-7OZWKHA3.js";
4
+ } from "./chunk-ZEZQNP2G.js";
5
+ import "./chunk-K2F237KS.js";
6
+ import "./chunk-X67BDDZR.js";
7
+ import "./chunk-SW2U6HRB.js";
8
+ import "./chunk-RU74YG46.js";
9
+ import "./chunk-724DVYHU.js";
10
+ import "./chunk-UDZLPR34.js";
11
+ import "./chunk-YVR6EHWL.js";
12
+ import "./chunk-RPPTGPYF.js";
13
+ import "./chunk-7LT3YZUR.js";
14
+ import "./chunk-AXFLY5GU.js";
15
15
  import "./chunk-LNNI3MS4.js";
16
- import "./chunk-5TPC4KCV.js";
17
- import "./chunk-ZUG76D3P.js";
16
+ import "./chunk-FXWBFDQR.js";
17
+ import "./chunk-5Y54AE3L.js";
18
18
  import {
19
19
  getAuthHeaders,
20
20
  getWebhookUrl
21
- } from "./chunk-574M6I7F.js";
22
- import "./chunk-E5S3ILVA.js";
23
- import "./chunk-3BAFMGCJ.js";
24
- import "./chunk-X67VT4QO.js";
21
+ } from "./chunk-TPX6E6PL.js";
22
+ import "./chunk-UFTDRTCP.js";
23
+ import "./chunk-U54PJPTB.js";
24
+ import "./chunk-ICXY54ZC.js";
25
25
  import "./chunk-DW4TRDOZ.js";
26
26
  import "./chunk-WCFSBH33.js";
27
- import "./chunk-AJWFDIEY.js";
28
- import "./chunk-7UWXAJMK.js";
29
- import "./chunk-632FJ23O.js";
27
+ import "./chunk-M77B73VV.js";
28
+ import "./chunk-GLM7TVWP.js";
29
+ import "./chunk-EGV6R6UF.js";
30
30
  import {
31
31
  logger_default
32
32
  } from "./chunk-QUSMYGNQ.js";
33
- import "./chunk-CAIYV33P.js";
34
- import "./chunk-5IIVOWSP.js";
33
+ import "./chunk-H6X6CKDN.js";
34
+ import "./chunk-2RNMBXD2.js";
35
35
  import "./chunk-K3NQKI34.js";
36
36
 
37
37
  // packages/daemon/src/lib/cloud-sync.ts
@@ -31,11 +31,11 @@ import {
31
31
  removeParticipant,
32
32
  setConversationPrivate,
33
33
  updateChannelSettings
34
- } from "./chunk-574M6I7F.js";
35
- import "./chunk-3BAFMGCJ.js";
34
+ } from "./chunk-TPX6E6PL.js";
35
+ import "./chunk-U54PJPTB.js";
36
36
  import "./chunk-QUSMYGNQ.js";
37
- import "./chunk-CAIYV33P.js";
38
- import "./chunk-5IIVOWSP.js";
37
+ import "./chunk-H6X6CKDN.js";
38
+ import "./chunk-2RNMBXD2.js";
39
39
  import "./chunk-K3NQKI34.js";
40
40
  export {
41
41
  addMessage,
@@ -21,7 +21,7 @@ var cmd = command({
21
21
  const name = args.name;
22
22
  let template = flags.template;
23
23
  if (!template) {
24
- const { resolveTemplate } = await import("./ai-service-V4CTNGI3.js");
24
+ const { resolveTemplate } = await import("./ai-service-YW5SWCSB.js");
25
25
  template = await resolveTemplate();
26
26
  }
27
27
  const skills = flags.skills === "none" ? [] : flags.skills ? flags.skills.split(",") : void 0;
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stopDaemon
4
- } from "./chunk-U3EJJ7JN.js";
4
+ } from "./chunk-5N32EN4O.js";
5
5
  import {
6
6
  run
7
- } from "./chunk-YQOYZ6G7.js";
7
+ } from "./chunk-VPOMJMV6.js";
8
8
  import {
9
9
  command
10
10
  } from "./chunk-TXSA4Q3V.js";
@@ -15,10 +15,10 @@ import {
15
15
  pollHealth,
16
16
  readDaemonConfig,
17
17
  restartService
18
- } from "./chunk-5FVANDON.js";
19
- import "./chunk-AJWFDIEY.js";
20
- import "./chunk-CAIYV33P.js";
21
- import "./chunk-5IIVOWSP.js";
18
+ } from "./chunk-6NLW72HP.js";
19
+ import "./chunk-M77B73VV.js";
20
+ import "./chunk-H6X6CKDN.js";
21
+ import "./chunk-2RNMBXD2.js";
22
22
  import "./chunk-K3NQKI34.js";
23
23
 
24
24
  // src/commands/daemon-restart.ts