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
@@ -3,10 +3,10 @@ import {
3
3
  broadcast,
4
4
  publish,
5
5
  subscribe
6
- } from "./chunk-3BAFMGCJ.js";
6
+ } from "./chunk-U54PJPTB.js";
7
7
  import "./chunk-QUSMYGNQ.js";
8
- import "./chunk-CAIYV33P.js";
9
- import "./chunk-5IIVOWSP.js";
8
+ import "./chunk-H6X6CKDN.js";
9
+ import "./chunk-2RNMBXD2.js";
10
10
  import "./chunk-K3NQKI34.js";
11
11
  export {
12
12
  broadcast,
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ OAuthRefreshError,
3
4
  addCustomModel,
4
5
  aiComplete,
5
6
  aiCompleteUtility,
@@ -22,18 +23,20 @@ import {
22
23
  removeProviderConfig,
23
24
  resolveApiKey,
24
25
  resolveOAuthCredentials,
26
+ resolveProviderKey,
25
27
  resolveTemplate,
26
28
  saveProviderConfig,
27
29
  setEnabledModels,
28
30
  setProviderRefreshHook,
29
31
  setUtilityModel,
30
32
  unqualifyModelId
31
- } from "./chunk-632FJ23O.js";
33
+ } from "./chunk-EGV6R6UF.js";
32
34
  import "./chunk-QUSMYGNQ.js";
33
- import "./chunk-CAIYV33P.js";
34
- import "./chunk-5IIVOWSP.js";
35
+ import "./chunk-H6X6CKDN.js";
36
+ import "./chunk-2RNMBXD2.js";
35
37
  import "./chunk-K3NQKI34.js";
36
38
  export {
39
+ OAuthRefreshError,
37
40
  addCustomModel,
38
41
  aiComplete,
39
42
  aiCompleteUtility,
@@ -56,6 +59,7 @@ export {
56
59
  removeProviderConfig,
57
60
  resolveApiKey,
58
61
  resolveOAuthCredentials,
62
+ resolveProviderKey,
59
63
  resolveTemplate,
60
64
  saveProviderConfig,
61
65
  setEnabledModels,
@@ -5,9 +5,9 @@ import {
5
5
  extractArchive,
6
6
  isHomeOnlyArchive,
7
7
  readManifest
8
- } from "./chunk-KAEZOVP6.js";
9
- import "./chunk-CAIYV33P.js";
10
- import "./chunk-5IIVOWSP.js";
8
+ } from "./chunk-FLIEXG2T.js";
9
+ import "./chunk-H6X6CKDN.js";
10
+ import "./chunk-2RNMBXD2.js";
11
11
  import "./chunk-K3NQKI34.js";
12
12
  export {
13
13
  addHistoryToArchive,
@@ -4,6 +4,7 @@ import {
4
4
  changePassword,
5
5
  countAdmins,
6
6
  createUser,
7
+ deleteExternalMindUser,
7
8
  deleteMindUser,
8
9
  deleteUser,
9
10
  getDisplayNames,
@@ -19,17 +20,18 @@ import {
19
20
  updateUserProfile,
20
21
  verifyUser,
21
22
  withSenderDisplayNames
22
- } from "./chunk-UC6BNMGT.js";
23
- import "./chunk-3BAFMGCJ.js";
23
+ } from "./chunk-7LT3YZUR.js";
24
+ import "./chunk-U54PJPTB.js";
24
25
  import "./chunk-QUSMYGNQ.js";
25
- import "./chunk-CAIYV33P.js";
26
- import "./chunk-5IIVOWSP.js";
26
+ import "./chunk-H6X6CKDN.js";
27
+ import "./chunk-2RNMBXD2.js";
27
28
  import "./chunk-K3NQKI34.js";
28
29
  export {
29
30
  approveUser,
30
31
  changePassword,
31
32
  countAdmins,
32
33
  createUser,
34
+ deleteExternalMindUser,
33
35
  deleteMindUser,
34
36
  deleteUser,
35
37
  getDisplayNames,
@@ -6,12 +6,12 @@ import {
6
6
  migrateAvatarSizes,
7
7
  normalizeAvatar,
8
8
  renderAvatarBlock
9
- } from "./chunk-X67VT4QO.js";
9
+ } from "./chunk-ICXY54ZC.js";
10
10
  import "./chunk-DW4TRDOZ.js";
11
11
  import "./chunk-WCFSBH33.js";
12
12
  import "./chunk-QUSMYGNQ.js";
13
- import "./chunk-CAIYV33P.js";
14
- import "./chunk-5IIVOWSP.js";
13
+ import "./chunk-H6X6CKDN.js";
14
+ import "./chunk-2RNMBXD2.js";
15
15
  import "./chunk-K3NQKI34.js";
16
16
  export {
17
17
  AVATAR_CONTEXT_DIM,
@@ -1,7 +1,7 @@
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
  promptLine,
7
7
  promptPassword
@@ -23,26 +23,26 @@ import {
23
23
  RESTIC_INSTALL_HINT,
24
24
  resticVersion,
25
25
  restoreStagedDb
26
- } from "./chunk-WBBKYUGF.js";
26
+ } from "./chunk-EDR47UE2.js";
27
27
  import {
28
28
  getServiceMode,
29
29
  modeLabel,
30
30
  stopService
31
- } from "./chunk-5FVANDON.js";
31
+ } from "./chunk-6NLW72HP.js";
32
32
  import {
33
33
  chownMindDir,
34
34
  exec,
35
35
  execInherit,
36
36
  wrapForIsolation
37
- } from "./chunk-AJWFDIEY.js";
37
+ } from "./chunk-M77B73VV.js";
38
38
  import "./chunk-QUSMYGNQ.js";
39
39
  import {
40
40
  _resetConfigCache,
41
41
  readGlobalConfig,
42
42
  voluteHome,
43
43
  voluteSystemDir
44
- } from "./chunk-CAIYV33P.js";
45
- import "./chunk-5IIVOWSP.js";
44
+ } from "./chunk-H6X6CKDN.js";
45
+ import "./chunk-2RNMBXD2.js";
46
46
  import "./chunk-K3NQKI34.js";
47
47
 
48
48
  // src/commands/backup.ts
@@ -336,7 +336,7 @@ Restore failed: ${err instanceof Error ? err.message : err}`);
336
336
  if (readGlobalConfig().setup?.isolation === "user") {
337
337
  process.env.VOLUTE_ISOLATION = "user";
338
338
  }
339
- const { readAllMinds, mindDir } = await import("./registry-4UF6OCOE.js");
339
+ const { readAllMinds, mindDir } = await import("./registry-TRC2HJXR.js");
340
340
  const seen = /* @__PURE__ */ new Set();
341
341
  for (const mind of await readAllMinds()) {
342
342
  const dir = mind.dir ?? mindDir(mind.name);
@@ -12,15 +12,15 @@ var cmd = subcommands({
12
12
  commands: {
13
13
  send: {
14
14
  description: "Send a message",
15
- run: (args) => import("./send-NBRZJXKX.js").then((m) => m.run(args))
15
+ run: (args) => import("./send-2YKOZJJ5.js").then((m) => m.run(args))
16
16
  },
17
17
  list: {
18
18
  description: "List conversations",
19
- run: (args) => import("./list-4BVGH7AN.js").then((m) => m.run(args))
19
+ run: (args) => import("./list-UQGIW7OF.js").then((m) => m.run(args))
20
20
  },
21
21
  read: {
22
22
  description: "Read conversation messages",
23
- run: (args) => import("./read-ZXGUT4QC.js").then((m) => m.run(args))
23
+ run: (args) => import("./read-RJ5NAW5J.js").then((m) => m.run(args))
24
24
  },
25
25
  create: {
26
26
  description: "Create a conversation",
@@ -36,7 +36,7 @@ var cmd = subcommands({
36
36
  },
37
37
  files: {
38
38
  description: "List pending incoming files",
39
- run: (args) => import("./files-6BMKVG5G.js").then((m) => m.run(args))
39
+ run: (args) => import("./files-BRY5RRIM.js").then((m) => m.run(args))
40
40
  },
41
41
  accept: {
42
42
  description: "Accept a pending file",
@@ -7,6 +7,7 @@ import {
7
7
  var schema_exports = {};
8
8
  __export(schema_exports, {
9
9
  activity: () => activity,
10
+ apiTokens: () => apiTokens,
10
11
  channelGates: () => channelGates,
11
12
  channels: () => channels,
12
13
  conversationParticipants: () => conversationParticipants,
@@ -66,6 +67,20 @@ var users = sqliteTable("users", {
66
67
  avatar: text("avatar"),
67
68
  created_at: text("created_at").notNull().default(sql`(datetime('now'))`)
68
69
  });
70
+ var apiTokens = sqliteTable(
71
+ "api_tokens",
72
+ {
73
+ id: integer("id").primaryKey({ autoIncrement: true }),
74
+ user_id: integer("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
75
+ token_hash: text("token_hash").notNull(),
76
+ label: text("label"),
77
+ created_at: text("created_at").notNull().default(sql`(datetime('now'))`)
78
+ },
79
+ (table) => [
80
+ uniqueIndex("idx_api_tokens_hash").on(table.token_hash),
81
+ index("idx_api_tokens_user").on(table.user_id)
82
+ ]
83
+ );
69
84
  var conversations = sqliteTable(
70
85
  "conversations",
71
86
  {
@@ -299,6 +314,7 @@ var channelGates = sqliteTable(
299
314
  export {
300
315
  minds,
301
316
  users,
317
+ apiTokens,
302
318
  conversations,
303
319
  turns,
304
320
  mindHistory,
@@ -8,10 +8,10 @@ import {
8
8
  pollHealthDown,
9
9
  readDaemonConfig,
10
10
  stopService
11
- } from "./chunk-5FVANDON.js";
11
+ } from "./chunk-6NLW72HP.js";
12
12
  import {
13
13
  voluteSystemDir
14
- } from "./chunk-CAIYV33P.js";
14
+ } from "./chunk-H6X6CKDN.js";
15
15
 
16
16
  // src/commands/down.ts
17
17
  import { existsSync, readFileSync, unlinkSync } from "fs";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-QUSMYGNQ.js";
5
5
  import {
6
6
  readGlobalConfig
7
- } from "./chunk-CAIYV33P.js";
7
+ } from "./chunk-H6X6CKDN.js";
8
8
 
9
9
  // packages/daemon/src/lib/mind/sandbox.ts
10
10
  import { execFileSync } from "child_process";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  exec,
4
4
  execInherit
5
- } from "./chunk-AJWFDIEY.js";
5
+ } from "./chunk-M77B73VV.js";
6
6
  import {
7
7
  voluteSystemDir
8
- } from "./chunk-CAIYV33P.js";
8
+ } from "./chunk-H6X6CKDN.js";
9
9
 
10
10
  // packages/daemon/src/lib/config/service-mode.ts
11
11
  import { execFileSync } from "child_process";
@@ -2,31 +2,33 @@
2
2
  import {
3
3
  clearMind,
4
4
  summarizeOrphanedTurns
5
- } from "./chunk-7DXLIYPY.js";
5
+ } from "./chunk-YVR6EHWL.js";
6
6
  import {
7
7
  deliverEvent,
8
8
  recordNotice
9
- } from "./chunk-7OZWKHA3.js";
9
+ } from "./chunk-AXFLY5GU.js";
10
10
  import {
11
11
  getPrompt
12
- } from "./chunk-5TPC4KCV.js";
12
+ } from "./chunk-FXWBFDQR.js";
13
13
  import {
14
14
  isSandboxEnabled,
15
15
  wrapForSandbox
16
- } from "./chunk-ZUG76D3P.js";
16
+ } from "./chunk-5Y54AE3L.js";
17
17
  import {
18
18
  chownMindDir,
19
19
  isIsolationEnabled,
20
20
  wrapForIsolation
21
- } from "./chunk-AJWFDIEY.js";
21
+ } from "./chunk-M77B73VV.js";
22
22
  import {
23
23
  loadMergedEnv
24
- } from "./chunk-7UWXAJMK.js";
24
+ } from "./chunk-GLM7TVWP.js";
25
25
  import {
26
+ OAuthRefreshError,
26
27
  getAiConfig,
27
28
  resolveApiKey,
28
- resolveOAuthCredentials
29
- } from "./chunk-632FJ23O.js";
29
+ resolveOAuthCredentials,
30
+ resolveProviderKey
31
+ } from "./chunk-EGV6R6UF.js";
30
32
  import {
31
33
  logger_default
32
34
  } from "./chunk-QUSMYGNQ.js";
@@ -40,7 +42,7 @@ import {
40
42
  setMindRunning,
41
43
  stateDir,
42
44
  voluteSystemDir
43
- } from "./chunk-CAIYV33P.js";
45
+ } from "./chunk-H6X6CKDN.js";
44
46
 
45
47
  // packages/daemon/src/lib/util/json-state.ts
46
48
  import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs";
@@ -154,6 +156,18 @@ var RotatingLog = class extends Writable {
154
156
  import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
155
157
  import { resolve } from "path";
156
158
  var slog = logger_default.child("cred-sync");
159
+ var DAEMON_ONLY_OAUTH = /* @__PURE__ */ new Set(["xai"]);
160
+ var PI_PROVIDER_ENV_VAR = {
161
+ openrouter: "OPENROUTER_API_KEY",
162
+ openai: "OPENAI_API_KEY",
163
+ anthropic: "ANTHROPIC_API_KEY",
164
+ google: "GEMINI_API_KEY",
165
+ groq: "GROQ_API_KEY",
166
+ cerebras: "CEREBRAS_API_KEY",
167
+ xai: "XAI_API_KEY",
168
+ mistral: "MISTRAL_API_KEY",
169
+ zai: "ZAI_API_KEY"
170
+ };
157
171
  async function writeClaudeCredentials(homeDir, baseName, oauth) {
158
172
  const claudeDir = resolve(homeDir, ".claude");
159
173
  mkdirSync(claudeDir, { recursive: true });
@@ -194,6 +208,46 @@ async function writePiProviderOAuth(piAgentDir, baseName, provider, oauth) {
194
208
  await chownMindDir(piAgentDir, baseName);
195
209
  }
196
210
  }
211
+ async function injectPiProviderCredentials(opts) {
212
+ const { provider, piAgentDir, baseName, mindName, env } = opts;
213
+ let oauthCreds;
214
+ let oauthError;
215
+ try {
216
+ oauthCreds = await resolveOAuthCredentials(provider);
217
+ } catch (err) {
218
+ if (!(err instanceof OAuthRefreshError)) throw err;
219
+ slog.warn(
220
+ `OAuth token refresh failing for provider "${provider}" (mind ${mindName}); falling back to a static key if available`,
221
+ logger_default.errorData(err)
222
+ );
223
+ oauthError = err;
224
+ }
225
+ if (oauthCreds && !DAEMON_ONLY_OAUTH.has(provider)) {
226
+ await writePiProviderOAuth(piAgentDir, baseName, provider, oauthCreds);
227
+ env.PI_CODING_AGENT_DIR = piAgentDir;
228
+ return;
229
+ }
230
+ let apiKey;
231
+ if (oauthCreds) {
232
+ apiKey = oauthCreds.access;
233
+ } else if (oauthError) {
234
+ apiKey = await resolveProviderKey(provider, getAiConfig()?.providers[provider]?.apiKey);
235
+ } else {
236
+ apiKey = await resolveApiKey(provider);
237
+ }
238
+ if (apiKey) {
239
+ await writePiProviderKey(piAgentDir, baseName, provider, apiKey);
240
+ env.PI_CODING_AGENT_DIR = piAgentDir;
241
+ const providerEnv = PI_PROVIDER_ENV_VAR[provider];
242
+ if (providerEnv) env[providerEnv] = apiKey;
243
+ } else if (oauthError) {
244
+ slog.warn(
245
+ `OAuth token refresh is temporarily failing for provider "${provider}" and no static key is available \u2014 mind ${mindName} may start but stay silent until it recovers`
246
+ );
247
+ } else {
248
+ slog.warn(`no API key found for provider "${provider}" \u2014 mind ${mindName} may fail to start`);
249
+ }
250
+ }
197
251
  function piUsesProvider(piAgentDir, provider) {
198
252
  try {
199
253
  const authPath = resolve(piAgentDir, "auth.json");
@@ -325,7 +379,6 @@ var RestartTracker = class {
325
379
  // packages/daemon/src/lib/daemon/mind-manager.ts
326
380
  var mlog = logger_default.child("minds");
327
381
  var execFileAsync = promisify(execFile);
328
- var DAEMON_ONLY_OAUTH = /* @__PURE__ */ new Set(["xai"]);
329
382
  var MIND_ENV_ALLOWLIST = [
330
383
  "PATH",
331
384
  "HOME",
@@ -461,10 +514,10 @@ var MindManager = class {
461
514
  if (!existsSync4(dir)) throw new Error(`Mind directory missing: ${dir}`);
462
515
  return { dir, port: entry.port, baseName: name, template: entry.template };
463
516
  }
464
- async startMind(name) {
465
- return this.withLock(name, () => this._startMind(name));
517
+ async startMind(name, opts) {
518
+ return this.withLock(name, () => this._startMind(name, opts));
466
519
  }
467
- async _startMind(name) {
520
+ async _startMind(name, opts) {
468
521
  if (this.minds.has(name)) {
469
522
  throw new Error(`Mind ${name} is already running`);
470
523
  }
@@ -554,34 +607,13 @@ var MindManager = class {
554
607
  if (modelStr?.includes(":")) {
555
608
  const provider = modelStr.split(":")[0];
556
609
  const piAgentDir = resolve2(dir, ".mind", "pi-agent");
557
- const oauthCreds = await resolveOAuthCredentials(provider);
558
- if (oauthCreds && !DAEMON_ONLY_OAUTH.has(provider)) {
559
- await writePiProviderOAuth(piAgentDir, baseName, provider, oauthCreds);
560
- env.PI_CODING_AGENT_DIR = piAgentDir;
561
- } else {
562
- const apiKey = oauthCreds?.access ?? await resolveApiKey(provider);
563
- if (apiKey) {
564
- await writePiProviderKey(piAgentDir, baseName, provider, apiKey);
565
- env.PI_CODING_AGENT_DIR = piAgentDir;
566
- const providerEnvVars = {
567
- openrouter: "OPENROUTER_API_KEY",
568
- openai: "OPENAI_API_KEY",
569
- anthropic: "ANTHROPIC_API_KEY",
570
- google: "GEMINI_API_KEY",
571
- groq: "GROQ_API_KEY",
572
- cerebras: "CEREBRAS_API_KEY",
573
- xai: "XAI_API_KEY",
574
- mistral: "MISTRAL_API_KEY",
575
- zai: "ZAI_API_KEY"
576
- };
577
- const providerEnv = providerEnvVars[provider];
578
- if (providerEnv) env[providerEnv] = apiKey;
579
- } else {
580
- mlog.warn(
581
- `no API key found for provider "${provider}" \u2014 mind ${name} may fail to start`
582
- );
583
- }
584
- }
610
+ await injectPiProviderCredentials({
611
+ provider,
612
+ piAgentDir,
613
+ baseName,
614
+ mindName: name,
615
+ env
616
+ });
585
617
  }
586
618
  }
587
619
  } catch (err) {
@@ -647,6 +679,17 @@ var MindManager = class {
647
679
  if (key && oauth) {
648
680
  const claudeDir = await writeClaudeCredentials(resolve2(dir, "home"), baseName, oauth);
649
681
  env.CLAUDE_CONFIG_DIR = claudeDir;
682
+ } else {
683
+ mlog.error(
684
+ `Anthropic OAuth token refresh is failing for ${name}; it will spawn without credentials and stay silent until the provider recovers and it is restarted`
685
+ );
686
+ void recordNotice({
687
+ mind: name,
688
+ thread: "main",
689
+ kind: "startup",
690
+ reason: "oauth_refresh_failed",
691
+ detail: "Anthropic authentication is temporarily unavailable (OAuth token refresh is failing), so you started without model credentials and may be unable to respond until it recovers. This is usually transient; if it persists, ask your host to re-check the anthropic provider."
692
+ });
650
693
  }
651
694
  } else {
652
695
  const apiKey = await resolveApiKey("anthropic");
@@ -692,9 +735,10 @@ var MindManager = class {
692
735
  while (recentStderr.length > 20) recentStderr.shift();
693
736
  });
694
737
  try {
738
+ const healthTimeoutMs = opts?.healthTimeoutMs ?? 3e4;
695
739
  await new Promise((resolve3, reject) => {
696
740
  let settled = false;
697
- const deadline = Date.now() + 3e4;
741
+ const deadline = Date.now() + healthTimeoutMs;
698
742
  const onExit = (code) => {
699
743
  const errorLine = recentStderr.find((l) => l.includes("Error:"));
700
744
  const detail = errorLine ? `: ${errorLine.trim()}` : "";
@@ -729,7 +773,7 @@ var MindManager = class {
729
773
  finish(
730
774
  () => reject(
731
775
  new MindStartupError(
732
- `Mind ${name} did not become healthy within 30s`,
776
+ `Mind ${name} did not become healthy within ${Math.round(healthTimeoutMs / 1e3)}s`,
733
777
  recentStderr.join("\n")
734
778
  )
735
779
  )
@@ -761,9 +805,9 @@ var MindManager = class {
761
805
  mlog.info(`started mind ${name} on port ${port}`);
762
806
  await this.deliverPendingContext(name);
763
807
  try {
764
- const { getSleepManagerIfReady } = await import("./sleep-manager-LIEPO6WG.js");
808
+ const { getSleepManagerIfReady } = await import("./sleep-manager-OFP2GFXF.js");
765
809
  if (!getSleepManagerIfReady()?.isSleeping(name)) {
766
- const { flushQueuedEvents } = await import("./system-events-A6IGCEC3.js");
810
+ const { flushQueuedEvents } = await import("./system-events-V43HDA3T.js");
767
811
  const flushed = await flushQueuedEvents(name);
768
812
  if (flushed > 0) mlog.info(`redelivered ${flushed} pending event(s) to ${name}`);
769
813
  }
@@ -799,7 +843,7 @@ var MindManager = class {
799
843
  if (this.shuttingDown || this.stopping.has(name)) return;
800
844
  mlog.error(`mind ${name} exited with code ${code}`);
801
845
  try {
802
- const { getSleepManagerIfReady } = await import("./sleep-manager-LIEPO6WG.js");
846
+ const { getSleepManagerIfReady } = await import("./sleep-manager-OFP2GFXF.js");
803
847
  const sleepMgr = getSleepManagerIfReady();
804
848
  const sleepState = sleepMgr?.getState(name);
805
849
  if (sleepState?.sleeping) {
@@ -829,15 +873,15 @@ var MindManager = class {
829
873
  (err) => mlog.warn(`failed to clear turn state for ${name} after crash`, logger_default.errorData(err))
830
874
  );
831
875
  try {
832
- const { getDeliveryManager } = await import("./delivery-manager-B4OKWD2P.js");
876
+ const { getDeliveryManager } = await import("./delivery-manager-VYXVKUMP.js");
833
877
  getDeliveryManager().clearMindSessions(name);
834
878
  } catch (err) {
835
879
  if (!(err instanceof Error && err.message.includes("not initialized"))) {
836
880
  mlog.warn(`failed to clear delivery state for ${name} after crash`, logger_default.errorData(err));
837
881
  }
838
882
  }
839
- import("./mind-activity-tracker-L7GCYXQR.js").then(({ markIdle }) => markIdle(name)).catch((err) => mlog.warn(`failed to mark ${name} idle after crash`, logger_default.errorData(err)));
840
- import("./activity-events-H7YI3BTF.js").then(
883
+ import("./mind-activity-tracker-QF6DCX2X.js").then(({ markIdle }) => markIdle(name)).catch((err) => mlog.warn(`failed to mark ${name} idle after crash`, logger_default.errorData(err)));
884
+ import("./activity-events-LQII6PZS.js").then(
841
885
  ({ publish }) => publish({ type: "mind_stopped", mind: name, summary: `${name} crashed (exit ${code})` })
842
886
  ).catch((err) => mlog.warn(`failed to publish crash event for ${name}`, logger_default.errorData(err)));
843
887
  const { shouldRestart, delay, attempt } = this.restartTracker.recordCrash(name);
@@ -895,7 +939,7 @@ var MindManager = class {
895
939
  mlog.warn(`failed to clear turn state for ${name} on stop`, logger_default.errorData(err));
896
940
  }
897
941
  try {
898
- const { getDeliveryManager } = await import("./delivery-manager-B4OKWD2P.js");
942
+ const { getDeliveryManager } = await import("./delivery-manager-VYXVKUMP.js");
899
943
  getDeliveryManager().clearMindSessions(name);
900
944
  } catch (err) {
901
945
  if (!(err instanceof Error && err.message.includes("not initialized"))) {
@@ -903,7 +947,7 @@ var MindManager = class {
903
947
  }
904
948
  }
905
949
  try {
906
- const { clearEchoTextCache } = await import("./echo-text-WYAAODBV.js");
950
+ const { clearEchoTextCache } = await import("./echo-text-PEEV7FQU.js");
907
951
  clearEchoTextCache(name);
908
952
  } catch (err) {
909
953
  mlog.debug(`failed to clear echo-text cache for ${name}`, logger_default.errorData(err));
@@ -1,15 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  broadcast
4
- } from "./chunk-3BAFMGCJ.js";
4
+ } from "./chunk-U54PJPTB.js";
5
5
  import {
6
+ findMind,
6
7
  getDb,
7
8
  getSpiritName,
8
9
  isSpiritName
9
- } from "./chunk-CAIYV33P.js";
10
+ } from "./chunk-H6X6CKDN.js";
10
11
  import {
11
12
  users
12
- } from "./chunk-5IIVOWSP.js";
13
+ } from "./chunk-2RNMBXD2.js";
13
14
 
14
15
  // packages/daemon/src/lib/auth.ts
15
16
  import { compareSync, hashSync } from "bcryptjs";
@@ -172,6 +173,16 @@ async function deleteUser(id) {
172
173
  if (!target) throw new Error("User not found");
173
174
  await db.delete(users).where(and(eq(users.id, id), eq(users.user_type, "human")));
174
175
  }
176
+ async function deleteExternalMindUser(id) {
177
+ const db = await getDb();
178
+ const target = await db.select({ id: users.id, username: users.username, user_type: users.user_type }).from(users).where(eq(users.id, id)).get();
179
+ if (!target) throw new Error("User not found");
180
+ if (target.user_type !== "mind") throw new Error("Not a mind account");
181
+ if (await findMind(target.username)) {
182
+ throw new Error("Use the mind deletion API to delete minds");
183
+ }
184
+ await db.delete(users).where(eq(users.id, id));
185
+ }
175
186
  async function updateUserProfile(userId, profile) {
176
187
  const db = await getDb();
177
188
  const target = await db.select({ id: users.id }).from(users).where(eq(users.id, userId)).get();
@@ -210,6 +221,7 @@ export {
210
221
  countAdmins,
211
222
  setUserRole,
212
223
  deleteUser,
224
+ deleteExternalMindUser,
213
225
  updateUserProfile,
214
226
  syncMindProfile
215
227
  };
@@ -19,10 +19,20 @@ function compactDateTime(dateStr) {
19
19
  const min = String(d.getMinutes()).padStart(2, "0");
20
20
  return `${y}-${m}-${day} ${h}:${min}`;
21
21
  }
22
+ function formatMessageLine(msg, compact) {
23
+ const text = Array.isArray(msg.content) ? msg.content.filter((b) => b.type === "text").map((b) => b.text).join("") : msg.content;
24
+ const time = compact ? compactTime(msg.created_at) : new Date(
25
+ msg.created_at.endsWith("Z") ? msg.created_at : `${msg.created_at}Z`
26
+ ).toLocaleString();
27
+ if (msg.role === "event") return `[${time}] \xB7 ${text}`;
28
+ const sender = compact ? msg.sender_name ?? msg.role : formatSender(msg.sender_name ?? msg.role, msg.sender_display_name);
29
+ return `[${time}] ${sender}: ${text}`;
30
+ }
22
31
 
23
32
  export {
24
33
  isCompact,
25
34
  formatSender,
26
35
  compactTime,
27
- compactDateTime
36
+ compactDateTime,
37
+ formatMessageLine
28
38
  };