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
@@ -9,19 +9,27 @@ import {
9
9
  findMind,
10
10
  getBaseName,
11
11
  getDb
12
- } from "./chunk-CAIYV33P.js";
12
+ } from "./chunk-H6X6CKDN.js";
13
13
  import {
14
14
  mindHistory,
15
15
  systemEvents,
16
16
  turns
17
- } from "./chunk-5IIVOWSP.js";
17
+ } from "./chunk-2RNMBXD2.js";
18
+
19
+ // packages/daemon/src/lib/chat/system-events.ts
20
+ import { and, asc, desc, eq, gt, isNotNull, isNull, lt, lte, or, sql } from "drizzle-orm";
21
+
22
+ // packages/daemon/src/lib/util/session-name.ts
23
+ function newEphemeralSession() {
24
+ return `new-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
25
+ }
18
26
 
19
27
  // packages/daemon/src/lib/chat/system-events.ts
20
- import { and, asc, desc, eq, gt, isNull, lte, or, sql } from "drizzle-orm";
21
28
  var elog = logger_default.child("system-events");
22
29
  var MIND_LEVEL_THREAD = "";
23
30
  var MAX_NEXT_TURN_EVENTS = 100;
24
31
  var FLUSH_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
32
+ var EVENT_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
25
33
  function parseMeta(meta, context) {
26
34
  if (!meta) return {};
27
35
  try {
@@ -84,6 +92,10 @@ function eventLabel(type, meta) {
84
92
  return "Startup notice";
85
93
  case "extension":
86
94
  return s("reason") ? `Notice: ${s("reason")}` : "Notice";
95
+ case "delivery_failed":
96
+ return "Delivery failed";
97
+ case "join_blocked":
98
+ return "Variant join blocked";
87
99
  default:
88
100
  return "Notice";
89
101
  }
@@ -202,9 +214,13 @@ async function markDelivered(id, extraMeta) {
202
214
  );
203
215
  }
204
216
  }
217
+ function resolveEventThread(thread, delivery) {
218
+ if (thread !== "$new") return thread;
219
+ return delivery === "immediate" ? newEphemeralSession() : MIND_LEVEL_THREAD;
220
+ }
205
221
  async function deliverEvent(mind, input) {
206
- const thread = input.thread ?? "main";
207
222
  const delivery = input.delivery ?? "immediate";
223
+ const thread = resolveEventThread(input.thread ?? "main", delivery);
208
224
  let eventId;
209
225
  try {
210
226
  const db = await getDb();
@@ -228,7 +244,7 @@ async function deliverEvent(mind, input) {
228
244
  return { id: eventId, delivered: false };
229
245
  }
230
246
  const baseName = await getBaseName(mind);
231
- const { getSleepManagerIfReady } = await import("./sleep-manager-LIEPO6WG.js");
247
+ const { getSleepManagerIfReady } = await import("./sleep-manager-OFP2GFXF.js");
232
248
  const sleepManager = getSleepManagerIfReady();
233
249
  const sleeping = !input.force && sleepManager?.isSleeping(baseName);
234
250
  const behavior = input.whileSleeping ?? "queue";
@@ -312,6 +328,11 @@ async function pendingEventCount(mind) {
312
328
  return 0;
313
329
  }
314
330
  }
331
+ async function cleanExpiredEvents() {
332
+ const db = await getDb();
333
+ const cutoff = new Date(Date.now() - EVENT_RETENTION_MS).toISOString().replace("T", " ").slice(0, 19);
334
+ await db.delete(systemEvents).where(and(isNotNull(systemEvents.delivered_at), lt(systemEvents.created_at, cutoff)));
335
+ }
315
336
  function pendingEventsLine(count) {
316
337
  if (count <= 0) return "";
317
338
  return `${count} system event${count === 1 ? "" : "s"} arrived while you slept and will follow shortly.`;
@@ -527,6 +548,7 @@ async function captureReflection(mind, turnId) {
527
548
  }
528
549
 
529
550
  export {
551
+ newEphemeralSession,
530
552
  MIND_LEVEL_THREAD,
531
553
  parseMeta,
532
554
  eventLabel,
@@ -535,6 +557,7 @@ export {
535
557
  deliverEvent,
536
558
  flushQueuedEvents,
537
559
  pendingEventCount,
560
+ cleanExpiredEvents,
538
561
  pendingEventsLine,
539
562
  drainEvents,
540
563
  formatEvents,
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  computeTemplateHash
4
- } from "./chunk-C3KLHJDB.js";
4
+ } from "./chunk-HTRSSOHY.js";
5
5
  import {
6
6
  composeTemplate,
7
7
  findTemplatesRoot,
8
8
  listFiles
9
- } from "./chunk-RRZ4RQQU.js";
9
+ } from "./chunk-X67BDDZR.js";
10
10
  import {
11
11
  logger_default
12
12
  } from "./chunk-QUSMYGNQ.js";
13
13
  import {
14
14
  mindDir
15
- } from "./chunk-CAIYV33P.js";
15
+ } from "./chunk-H6X6CKDN.js";
16
16
 
17
17
  // packages/daemon/src/lib/mind/template-staleness.ts
18
18
  import { createHash } from "crypto";
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  getSleepManagerIfReady,
4
4
  startSpiritFull
5
- } from "./chunk-EQKSRVDE.js";
5
+ } from "./chunk-ZEZQNP2G.js";
6
6
  import {
7
7
  spiritCreationInProgress
8
- } from "./chunk-SFRYRW37.js";
8
+ } from "./chunk-K2F237KS.js";
9
9
  import {
10
10
  MindStartupError,
11
11
  tryGetMindManager
12
- } from "./chunk-ALIVXDM4.js";
12
+ } from "./chunk-724DVYHU.js";
13
13
  import {
14
14
  logger_default
15
15
  } from "./chunk-QUSMYGNQ.js";
@@ -17,7 +17,7 @@ import {
17
17
  computeSetupStatus,
18
18
  findMind,
19
19
  readGlobalConfigStrict
20
- } from "./chunk-CAIYV33P.js";
20
+ } from "./chunk-H6X6CKDN.js";
21
21
 
22
22
  // packages/daemon/src/lib/chat/spirit-availability.ts
23
23
  var slog = logger_default.child("spirit-availability");
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stateDir
4
- } from "./chunk-CAIYV33P.js";
4
+ } from "./chunk-H6X6CKDN.js";
5
5
 
6
6
  // packages/daemon/src/lib/chat/file-sharing.ts
7
7
  import { randomBytes } from "crypto";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exec
4
- } from "./chunk-AJWFDIEY.js";
4
+ } from "./chunk-M77B73VV.js";
5
5
  import {
6
6
  logger_default
7
7
  } from "./chunk-QUSMYGNQ.js";
@@ -11,7 +11,7 @@ import {
11
11
  readGlobalConfig,
12
12
  voluteHome,
13
13
  voluteSystemDir
14
- } from "./chunk-CAIYV33P.js";
14
+ } from "./chunk-H6X6CKDN.js";
15
15
 
16
16
  // packages/daemon/src/lib/backup/restic.ts
17
17
  import { writeFileSync } from "fs";
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  readGlobalConfig,
7
7
  writeGlobalConfig
8
- } from "./chunk-CAIYV33P.js";
8
+ } from "./chunk-H6X6CKDN.js";
9
9
 
10
10
  // packages/daemon/src/lib/ai-service.ts
11
11
  import { defaultProviderAuthContext } from "@earendil-works/pi-ai";
@@ -133,8 +133,11 @@ async function missingCredentialWarning(template, model, mindName) {
133
133
  const envVar = PROVIDER_ENV_VAR[provider] ?? `${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`;
134
134
  if (await resolveApiKey(provider)) return null;
135
135
  if (provider === "openai-codex" && process.env.OPENAI_API_KEY) return null;
136
- const { loadMergedEnv } = await import("./env-AZK5X4W7.js");
136
+ const { loadMergedEnv } = await import("./env-SQFCWW52.js");
137
137
  if (loadMergedEnv(mindName)[envVar]) return null;
138
+ if (getAiConfig()?.providers[provider]?.oauth) {
139
+ return `${provider} authentication is temporarily unavailable, so ${mindName} will start but may stay silent until it recovers (OAuth token refresh is failing \u2014 usually transient). If it persists, re-check the ${provider} provider in the web dashboard (Settings \u2192 Providers).`;
140
+ }
138
141
  return `No ${provider} credentials are configured, so ${mindName} will start but stay silent until a key is available. Set one with \`volute env set ${envVar} <key> --mind ${mindName}\`, or configure the ${provider} provider in the web dashboard (Settings \u2192 Providers).`;
139
142
  }
140
143
  async function resolveTemplate(modelId) {
@@ -299,28 +302,42 @@ async function getAvailableModels() {
299
302
  }
300
303
  return result;
301
304
  }
305
+ var OAuthRefreshError = class extends Error {
306
+ constructor(providerId, cause) {
307
+ super(
308
+ `${providerId} authentication is temporarily unavailable (OAuth token refresh failed). This is usually transient \u2014 try again shortly. If it keeps failing, ask your admin to re-check the ${providerId} provider.`
309
+ );
310
+ this.providerId = providerId;
311
+ this.cause = cause;
312
+ this.name = "OAuthRefreshError";
313
+ }
314
+ };
302
315
  async function resolveOAuthCredentials(providerId) {
303
316
  const ai = getAiConfig();
304
317
  const providerConfig = ai?.providers[providerId];
305
318
  if (!providerConfig?.oauth) return void 0;
306
319
  try {
307
320
  const result = await getOAuthApiKey(providerId, { [providerId]: providerConfig.oauth });
308
- if (!result) return void 0;
321
+ if (!result) throw new Error(`OAuth resolution returned no credential for ${providerId}`);
309
322
  if (result.newCredentials.access !== providerConfig.oauth.access) {
310
323
  saveProviderConfig(providerId, { ...providerConfig, oauth: result.newCredentials });
311
324
  fireProviderRefreshHook(providerId);
312
325
  }
313
326
  return result.newCredentials;
314
327
  } catch (err) {
315
- aiLog.warn(`OAuth credential resolution failed for ${providerId}`, logger_default.errorData(err));
316
- return void 0;
328
+ aiLog.error(`OAuth credential resolution failed for ${providerId}`, logger_default.errorData(err));
329
+ throw new OAuthRefreshError(providerId, err);
317
330
  }
318
331
  }
319
332
  async function resolveApiKey(providerId) {
320
333
  const ai = getAiConfig();
321
334
  const providerConfig = ai?.providers[providerId];
322
- const oauthCreds = await resolveOAuthCredentials(providerId);
323
- if (oauthCreds) return oauthCreds.access;
335
+ try {
336
+ const oauthCreds = await resolveOAuthCredentials(providerId);
337
+ if (oauthCreds) return oauthCreds.access;
338
+ } catch (err) {
339
+ if (!(err instanceof OAuthRefreshError)) throw err;
340
+ }
324
341
  return resolveProviderKey(providerId, providerConfig?.apiKey);
325
342
  }
326
343
  function qualifyModelId(modelId) {
@@ -399,6 +416,7 @@ async function aiComplete(systemPrompt, userMessage, modelId) {
399
416
  }
400
417
 
401
418
  export {
419
+ resolveProviderKey,
402
420
  setProviderRefreshHook,
403
421
  fireProviderRefreshHook,
404
422
  getAiConfig,
@@ -421,6 +439,7 @@ export {
421
439
  removeCustomModel,
422
440
  buildCustomModel,
423
441
  getAvailableModels,
442
+ OAuthRefreshError,
424
443
  resolveOAuthCredentials,
425
444
  resolveApiKey,
426
445
  qualifyModelId,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  mindDir,
4
4
  stateDir
5
- } from "./chunk-CAIYV33P.js";
5
+ } from "./chunk-H6X6CKDN.js";
6
6
 
7
7
  // packages/daemon/src/lib/mind/archive.ts
8
8
  import { execFileSync } from "child_process";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getDb
4
- } from "./chunk-CAIYV33P.js";
4
+ } from "./chunk-H6X6CKDN.js";
5
5
  import {
6
6
  systemPrompts
7
- } from "./chunk-5IIVOWSP.js";
7
+ } from "./chunk-2RNMBXD2.js";
8
8
 
9
9
  // packages/daemon/src/lib/prompts.ts
10
10
  import { eq } from "drizzle-orm";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  compactDateTime,
4
4
  isCompact
5
- } from "./chunk-PW65BXY5.js";
5
+ } from "./chunk-7YJY3F2R.js";
6
6
  import {
7
7
  resolveMindName
8
8
  } from "./chunk-BTY4WNFE.js";
@@ -279,7 +279,7 @@ var cmd = subcommands({
279
279
  },
280
280
  sleep: {
281
281
  description: "Put a mind to sleep",
282
- run: (args) => import("./mind-sleep-TH6BRQ5X.js").then((m) => m.run(args))
282
+ run: (args) => import("./mind-sleep-LZAFBDZD.js").then((m) => m.run(args))
283
283
  },
284
284
  wake: {
285
285
  description: "Wake a sleeping mind",
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  stateDir,
4
4
  voluteSystemDir
5
- } from "./chunk-CAIYV33P.js";
5
+ } from "./chunk-H6X6CKDN.js";
6
6
 
7
7
  // packages/daemon/src/lib/config/env.ts
8
8
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -11,7 +11,7 @@ import {
11
11
  systemEvents,
12
12
  turns,
13
13
  users
14
- } from "./chunk-5IIVOWSP.js";
14
+ } from "./chunk-2RNMBXD2.js";
15
15
 
16
16
  // packages/daemon/src/lib/db.ts
17
17
  import { chmodSync as chmodSync2, existsSync as existsSync2 } from "fs";
@@ -340,6 +340,7 @@ async function addVariant(name, parent, port, dir, branch, purpose) {
340
340
  async function removeMind(name) {
341
341
  const db2 = await getDb();
342
342
  await db2.delete(minds).where(eq(minds.name, name));
343
+ await db2.delete(deliveryQueue).where(or(eq(deliveryQueue.mind, name), eq(deliveryQueue.target_mind, name)));
343
344
  }
344
345
  async function deleteMindDbFootprint(name) {
345
346
  const db2 = await getDb();
@@ -3,7 +3,7 @@ import {
3
3
  composeTemplate,
4
4
  findTemplatesRoot,
5
5
  listFiles
6
- } from "./chunk-RRZ4RQQU.js";
6
+ } from "./chunk-X67BDDZR.js";
7
7
 
8
8
  // packages/daemon/src/lib/template/template-hash.ts
9
9
  import { createHash } from "crypto";
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  setBridgeConfig
4
- } from "./chunk-7XDOTN4R.js";
4
+ } from "./chunk-L7BKTZ5U.js";
5
5
  import {
6
6
  readEnv,
7
7
  sharedEnvPath,
8
8
  writeEnv
9
- } from "./chunk-7UWXAJMK.js";
9
+ } from "./chunk-GLM7TVWP.js";
10
10
 
11
11
  // packages/daemon/src/lib/template/import-utils.ts
12
12
  import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
@@ -12,7 +12,7 @@ import {
12
12
  mindDir,
13
13
  readAllMinds,
14
14
  voluteHome
15
- } from "./chunk-CAIYV33P.js";
15
+ } from "./chunk-H6X6CKDN.js";
16
16
 
17
17
  // packages/daemon/src/lib/util/avatar-image.ts
18
18
  import { readdir, readFile, writeFile } from "fs/promises";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getMindManager
4
- } from "./chunk-ALIVXDM4.js";
4
+ } from "./chunk-724DVYHU.js";
5
5
  import {
6
6
  chownMindDir,
7
7
  gitExec
8
- } from "./chunk-AJWFDIEY.js";
8
+ } from "./chunk-M77B73VV.js";
9
9
  import {
10
10
  logger_default
11
11
  } from "./chunk-QUSMYGNQ.js";
@@ -14,12 +14,12 @@ import {
14
14
  mindDir,
15
15
  readAllMinds,
16
16
  removeMind
17
- } from "./chunk-CAIYV33P.js";
17
+ } from "./chunk-H6X6CKDN.js";
18
18
 
19
19
  // packages/daemon/src/lib/mind/variant-cleanup.ts
20
20
  import { existsSync, readdirSync, rmSync, statSync } from "fs";
21
21
  import { resolve } from "path";
22
- async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
22
+ async function cleanupVariant(variantName, baseName, projectRoot, variantPath, opts) {
23
23
  if (opts?.stop) {
24
24
  try {
25
25
  await getMindManager().stopMind(variantName);
@@ -27,7 +27,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
27
27
  logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
28
28
  }
29
29
  }
30
- const { findMind } = await import("./registry-4UF6OCOE.js");
30
+ const { findMind } = await import("./registry-TRC2HJXR.js");
31
31
  const variantEntry = await findMind(variantName);
32
32
  const branchName = variantEntry?.branch ?? variantName;
33
33
  if (existsSync(variantPath)) {
@@ -47,7 +47,6 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
47
47
  } catch (err) {
48
48
  logger_default.warn(`failed to delete branch ${branchName} for ${variantName}`, logger_default.errorData(err));
49
49
  }
50
- const baseName = variantEntry?.parent ?? variantName;
51
50
  try {
52
51
  await removeMind(variantName);
53
52
  } catch (err) {
@@ -78,7 +77,7 @@ async function reconcileVariants() {
78
77
  `reconcile: dropping stale variant row ${v.name} (worktree ${v.dir ?? "<none>"} missing)`
79
78
  );
80
79
  try {
81
- await cleanupVariant(v.name, baseDir(v.parent), v.dir ?? "");
80
+ await cleanupVariant(v.name, v.parent, baseDir(v.parent), v.dir ?? "");
82
81
  } catch (err) {
83
82
  logger_default.warn(`reconcile: failed to drop stale variant ${v.name}`, logger_default.errorData(err));
84
83
  }
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  MEMORY_PLACEHOLDER_MARKER,
4
4
  ORIENTATION_MARKER
5
- } from "./chunk-5TPC4KCV.js";
5
+ } from "./chunk-FXWBFDQR.js";
6
6
  import {
7
7
  safeResolveWithinBase
8
8
  } from "./chunk-DW4TRDOZ.js";
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-WCFSBH33.js";
12
12
  import {
13
13
  isImagegenEnabled
14
- } from "./chunk-CAIYV33P.js";
14
+ } from "./chunk-H6X6CKDN.js";
15
15
 
16
16
  // packages/daemon/src/lib/mind/seed-readiness.ts
17
17
  import { existsSync, readFileSync } from "fs";
@@ -5,24 +5,24 @@ import {
5
5
  copyTemplateToDir,
6
6
  findTemplatesRoot,
7
7
  renderComposedPackageJson
8
- } from "./chunk-RRZ4RQQU.js";
8
+ } from "./chunk-X67BDDZR.js";
9
9
  import {
10
10
  getSharedSkill,
11
11
  installSkill,
12
12
  mindSkillsDir
13
- } from "./chunk-TGJHGVBZ.js";
13
+ } from "./chunk-RPPTGPYF.js";
14
14
  import {
15
15
  readVoluteConfig,
16
16
  writeVoluteConfig
17
17
  } from "./chunk-WCFSBH33.js";
18
18
  import {
19
19
  exec
20
- } from "./chunk-AJWFDIEY.js";
20
+ } from "./chunk-M77B73VV.js";
21
21
  import {
22
22
  qualifyModelId,
23
23
  resolveTemplate,
24
24
  unqualifyModelId
25
- } from "./chunk-632FJ23O.js";
25
+ } from "./chunk-EGV6R6UF.js";
26
26
  import {
27
27
  logger_default
28
28
  } from "./chunk-QUSMYGNQ.js";
@@ -33,7 +33,7 @@ import {
33
33
  nextPort,
34
34
  readGlobalConfig,
35
35
  voluteSystemDir
36
- } from "./chunk-CAIYV33P.js";
36
+ } from "./chunk-H6X6CKDN.js";
37
37
 
38
38
  // packages/daemon/src/lib/mind/spirit.ts
39
39
  import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
@@ -150,7 +150,7 @@ async function ensureSpiritProject() {
150
150
  } catch (err) {
151
151
  slog.warn("failed to add tending schedule to spirit config", logger_default.errorData(err));
152
152
  }
153
- const { createMindUser, chownMindDir, ensureVoluteGroup } = await import("./isolation-OKDFM6WA.js");
153
+ const { createMindUser, chownMindDir, ensureVoluteGroup } = await import("./isolation-GVV2IBAU.js");
154
154
  ensureVoluteGroup();
155
155
  createMindUser(spiritName, resolve(dir, "home"));
156
156
  await chownMindDir(dir, spiritName);
@@ -192,7 +192,7 @@ async function notifySpiritSystemChange() {
192
192
  const config = readGlobalConfig();
193
193
  const name = config.name ?? "Volute";
194
194
  const desc = config.description ? ` \u2014 ${config.description}` : "";
195
- const { deliverEvent } = await import("./system-events-A6IGCEC3.js");
195
+ const { deliverEvent } = await import("./system-events-V43HDA3T.js");
196
196
  await deliverEvent(spiritName, {
197
197
  type: "notice",
198
198
  meta: { subtype: "identity-change" },
@@ -221,8 +221,8 @@ async function syncSpiritTemplate() {
221
221
  cpSync(newPkg, resolve(dir, "package.json"));
222
222
  await exec("npm", ["install"], { cwd: dir, env: npmEnv() });
223
223
  }
224
- const db = await (await import("./db-QAY45Z56.js")).getDb();
225
- const { minds } = await import("./schema-C2GIPD4V.js");
224
+ const db = await (await import("./db-BONH4SUG.js")).getDb();
225
+ const { minds } = await import("./schema-ZZQVM4GR.js");
226
226
  const { eq } = await import("drizzle-orm");
227
227
  await db.update(minds).set({ template: expectedTemplate }).where(eq(minds.name, spiritName));
228
228
  }
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-QUSMYGNQ.js";
5
5
  import {
6
6
  voluteSystemDir
7
- } from "./chunk-CAIYV33P.js";
7
+ } from "./chunk-H6X6CKDN.js";
8
8
 
9
9
  // packages/daemon/src/lib/bridges/bridges.ts
10
10
  import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteSystemDir
4
- } from "./chunk-CAIYV33P.js";
4
+ } from "./chunk-H6X6CKDN.js";
5
5
 
6
6
  // packages/daemon/src/lib/update-check.ts
7
7
  import { execFile as execFileCb, execFileSync } from "child_process";
@@ -3,7 +3,7 @@ import {
3
3
  getBaseName,
4
4
  isSpiritName,
5
5
  validateMindName
6
- } from "./chunk-CAIYV33P.js";
6
+ } from "./chunk-H6X6CKDN.js";
7
7
 
8
8
  // packages/daemon/src/lib/mind/isolation.ts
9
9
  import { execFileSync as execFileSync2 } from "child_process";
@@ -3,10 +3,10 @@ import {
3
3
  LAUNCHD_PLIST_LABEL,
4
4
  LAUNCHD_PLIST_PATH,
5
5
  USER_SYSTEMD_UNIT
6
- } from "./chunk-5FVANDON.js";
6
+ } from "./chunk-6NLW72HP.js";
7
7
  import {
8
8
  resolveVoluteBin
9
- } from "./chunk-AJWFDIEY.js";
9
+ } from "./chunk-M77B73VV.js";
10
10
 
11
11
  // packages/daemon/src/lib/config/service-install.ts
12
12
  import { execFile } from "child_process";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  exec,
4
4
  gitExec
5
- } from "./chunk-AJWFDIEY.js";
5
+ } from "./chunk-M77B73VV.js";
6
6
  import {
7
7
  logger_default
8
8
  } from "./chunk-QUSMYGNQ.js";
@@ -13,10 +13,10 @@ import {
13
13
  readRegistry,
14
14
  voluteHome,
15
15
  writeGlobalConfig
16
- } from "./chunk-CAIYV33P.js";
16
+ } from "./chunk-H6X6CKDN.js";
17
17
  import {
18
18
  sharedSkills
19
- } from "./chunk-5IIVOWSP.js";
19
+ } from "./chunk-2RNMBXD2.js";
20
20
 
21
21
  // packages/daemon/src/lib/skills.ts
22
22
  import { createHash } from "crypto";
@@ -45,7 +45,7 @@ async function initDefaultSkills() {
45
45
  const config = readGlobalConfig();
46
46
  let extensionSkills = [];
47
47
  try {
48
- const { getExtensionStandardSkills } = await import("./extensions-7KP3X6G7.js");
48
+ const { getExtensionStandardSkills } = await import("./extensions-N6L5NYTK.js");
49
49
  extensionSkills = getExtensionStandardSkills();
50
50
  } catch (err) {
51
51
  logger_default.warn("failed to load extension standard skills during init", logger_default.errorData(err));