volute 0.49.0 → 0.51.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 (224) hide show
  1. package/README.md +2 -2
  2. package/dist/{accept-KYNC5X3U.js → accept-5NK5XJB5.js} +2 -1
  3. package/dist/{activity-events-GJJAI2WT.js → activity-events-LQII6PZS.js} +3 -3
  4. package/dist/{ai-service-A7FS7EC3.js → ai-service-YW5SWCSB.js} +9 -4
  5. package/dist/{archive-7E3YE6VF.js → archive-FOHGXHPT.js} +3 -3
  6. package/dist/{auth-ABYLOEZ7.js → auth-X6EMNEGB.js} +10 -6
  7. package/dist/{avatar-image-6ATV2IOZ.js → avatar-image-52WGXLHV.js} +3 -3
  8. package/dist/{backup-XYAMT4CU.js → backup-YVGV2ZNM.js} +11 -12
  9. package/dist/{bridge-3FNSWLNQ.js → bridge-YK7NTRU5.js} +2 -1
  10. package/dist/{channels-SGQZHNQJ.js → channels-FSAHOQWI.js} +2 -1
  11. package/dist/{chat-OGXAEXMV.js → chat-VAZ25KVT.js} +9 -9
  12. package/dist/{chunk-P4LHVRNE.js → chunk-2RNMBXD2.js} +43 -19
  13. package/dist/{chunk-6HGEZJDH.js → chunk-5N32EN4O.js} +2 -2
  14. package/dist/{chunk-JCWB2ITW.js → chunk-5Y54AE3L.js} +35 -5
  15. package/dist/{chunk-HCYQRME2.js → chunk-6NLW72HP.js} +2 -2
  16. package/dist/chunk-7HN63Q7J.js +1317 -0
  17. package/dist/chunk-7YJY3F2R.js +38 -0
  18. package/dist/{chunk-EADX54RG.js → chunk-AI47FDGL.js} +6 -7
  19. package/dist/{chunk-IH5TKXX6.js → chunk-BSHZ23MS.js} +12 -11
  20. package/dist/{chunk-K3JOLGWF.js → chunk-CDKQJWGK.js} +76 -63
  21. package/dist/{chunk-L27YYONJ.js → chunk-CV6BNGFK.js} +3 -3
  22. package/dist/{chunk-NOIAHMJB.js → chunk-DMK5ASKV.js} +1 -1
  23. package/dist/chunk-DN3LKLYR.js +109 -0
  24. package/dist/{chunk-JBIFXB6I.js → chunk-EDR47UE2.js} +3 -5
  25. package/dist/{chunk-SHKM5RGD.js → chunk-EEOMA4DX.js} +1 -1
  26. package/dist/{chunk-YIJGKHIS.js → chunk-EGV6R6UF.js} +43 -20
  27. package/dist/{chunk-KHCKZ36O.js → chunk-FLIEXG2T.js} +1 -1
  28. package/dist/chunk-FNJCBRD3.js +31 -0
  29. package/dist/{chunk-JPGHSXSV.js → chunk-FXWBFDQR.js} +23 -9
  30. package/dist/{chunk-JCBPU57A.js → chunk-G7A5LEVI.js} +6 -6
  31. package/dist/{chunk-PY24ZL62.js → chunk-GLM7TVWP.js} +1 -1
  32. package/dist/{chunk-RSBL3FAD.js → chunk-H6X6CKDN.js} +235 -24
  33. package/dist/{chunk-4DSGN4FL.js → chunk-HKP6OAJP.js} +43 -13
  34. package/dist/{chunk-C3KLHJDB.js → chunk-HTRSSOHY.js} +1 -1
  35. package/dist/{chunk-EG5LSKHU.js → chunk-I7U5EEZC.js} +2 -2
  36. package/dist/chunk-ICL6T4SN.js +562 -0
  37. package/dist/{chunk-FBBS4BVR.js → chunk-ICXY54ZC.js} +1 -1
  38. package/dist/{chunk-DAIIMBLB.js → chunk-IWAVIJO2.js} +3 -5
  39. package/dist/{chunk-TXJL36ZQ.js → chunk-JHKBALS2.js} +2 -2
  40. package/dist/{chunk-MG3Z34YE.js → chunk-L7BKTZ5U.js} +1 -1
  41. package/dist/{chunk-SX72DOO3.js → chunk-LAUCO2HC.js} +1 -1
  42. package/dist/chunk-LNNI3MS4.js +54 -0
  43. package/dist/{chunk-BCG45AQB.js → chunk-M74I3HHF.js} +15 -5
  44. package/dist/{chunk-DVN6DNMI.js → chunk-M77B73VV.js} +17 -2
  45. package/dist/{chunk-4B62E4CG.js → chunk-OXWUEU5V.js} +2 -2
  46. package/dist/chunk-Q7XQLKZB.js +289 -0
  47. package/dist/{chunk-GWVFDUNB.js → chunk-QT4D5XCI.js} +8 -10
  48. package/dist/{chunk-VNRSXEBF.js → chunk-TPX6E6PL.js} +38 -5
  49. package/dist/{chunk-3B427GUK.js → chunk-U54PJPTB.js} +2 -2
  50. package/dist/{chunk-EFT2OALG.js → chunk-UDZLPR34.js} +20 -5
  51. package/dist/{chunk-ZX46PGCC.js → chunk-UFTDRTCP.js} +1 -1
  52. package/dist/chunk-VAEZCIJC.js +1058 -0
  53. package/dist/chunk-VP5PFNZO.js +2905 -0
  54. package/dist/{chunk-VIUH5CHQ.js → chunk-VSBMLB2W.js} +51 -34
  55. package/dist/{chunk-RRZ4RQQU.js → chunk-X67BDDZR.js} +5 -7
  56. package/dist/cli.js +34 -27
  57. package/dist/{clock-6JZL2FS6.js → clock-ZT5YT6HA.js} +4 -3
  58. package/dist/{cloud-sync-VFDTNNCA.js → cloud-sync-GPXYPTIC.js} +23 -20
  59. package/dist/{config-RPSLA2HX.js → config-UGJS57VT.js} +3 -3
  60. package/dist/{conversations-TUM5PJJ4.js → conversations-ZL6PHROD.js} +8 -4
  61. package/dist/{create-Z5FSDNVZ.js → create-G2RIKQYK.js} +2 -2
  62. package/dist/{create-VIQVP3QB.js → create-M727VUDF.js} +2 -1
  63. package/dist/{daemon-client-ZFY5MOAL.js → daemon-client-VVYFZI2D.js} +2 -1
  64. package/dist/{daemon-restart-54L4B6AQ.js → daemon-restart-2EWBRTN5.js} +6 -7
  65. package/dist/daemon.js +2005 -762
  66. package/dist/{db-F6UMFRYD.js → db-BONH4SUG.js} +2 -2
  67. package/dist/{delete-ESEP7NGQ.js → delete-O7PEFQDF.js} +1 -1
  68. package/dist/delivery-manager-HGVZSEES.js +35 -0
  69. package/dist/{delivery-router-VUOL5YSA.js → delivery-router-RHANNTAC.js} +7 -5
  70. package/dist/{down-6X7KX7BZ.js → down-QSNEMTTX.js} +5 -5
  71. package/dist/echo-text-6ANI5HHN.js +39 -0
  72. package/dist/{env-ZYMSCB7B.js → env-IBW2QI6K.js} +3 -2
  73. package/dist/{env-KUL4XKN2.js → env-SQFCWW52.js} +3 -3
  74. package/dist/{exec-FBXA3CM4.js → exec-ABD3DYA2.js} +3 -3
  75. package/dist/{export-TNBPDH77.js → export-VBNWM7I4.js} +4 -4
  76. package/dist/{extension-J4ZQ2GHV.js → extension-MRYJWSMV.js} +2 -1
  77. package/dist/{extensions-AWNO3SZF.js → extensions-NY6WST33.js} +23 -20
  78. package/dist/{files-BVBRJJ2P.js → files-BRY5RRIM.js} +5 -4
  79. package/dist/{import-ZUNKMCKC.js → import-DB2KULRO.js} +8 -8
  80. package/dist/{isolation-OPCZQRTH.js → isolation-GVV2IBAU.js} +5 -3
  81. package/dist/{join-34TR2GXQ.js → join-PYA36HEC.js} +1 -1
  82. package/dist/{list-PMUXZNAM.js → list-UQGIW7OF.js} +8 -3
  83. package/dist/{login-LKNLCJPA.js → login-RJJTCVR3.js} +2 -1
  84. package/dist/{login-KAKNFCW5.js → login-SB5OENMV.js} +4 -3
  85. package/dist/{logout-YZRMZ3O2.js → logout-BYV433X6.js} +2 -1
  86. package/dist/{logout-RLT62RQP.js → logout-YFZAJRPY.js} +4 -3
  87. package/dist/message-delivery-JHMAJ2GU.js +43 -0
  88. package/dist/migrate-thread-config-EQSEP2XG.js +90 -0
  89. package/dist/{mind-IF6CGMFW.js → mind-WF6QIXWV.js} +19 -19
  90. package/dist/{mind-activity-tracker-YMMERB6B.js → mind-activity-tracker-QF6DCX2X.js} +4 -4
  91. package/dist/{mind-contacts-BKUFPUCU.js → mind-contacts-QYU4TPEA.js} +3 -2
  92. package/dist/{mind-history-WI5OI3BW.js → mind-history-OGNR4L7W.js} +30 -7
  93. package/dist/{mind-list-OTHV4ZO4.js → mind-list-SYRA7CH5.js} +3 -2
  94. package/dist/{mind-profile-LUG353ZT.js → mind-profile-MRCVZPYT.js} +1 -1
  95. package/dist/mind-service-DZCUUC7J.js +47 -0
  96. package/dist/{mind-sleep-VBV7YRSU.js → mind-sleep-LZAFBDZD.js} +4 -3
  97. package/dist/{mind-status-BJNPGXKC.js → mind-status-Z2LQFA6F.js} +3 -2
  98. package/dist/{mind-wake-LVTZ55EZ.js → mind-wake-LDGPRA42.js} +2 -1
  99. package/dist/{package-PD67VPHB.js → package-B6O5APCZ.js} +23 -23
  100. package/dist/{prompts-MDHDLWEX.js → prompts-NBO3HRK3.js} +3 -3
  101. package/dist/{read-YSWUXYL7.js → read-RJ5NAW5J.js} +5 -14
  102. package/dist/{register-TWQDKQRT.js → register-OX4HRSGC.js} +2 -1
  103. package/dist/{registry-3ELJPUGJ.js → registry-TRC2HJXR.js} +6 -4
  104. package/dist/{reject-SXGCYN4A.js → reject-TWB4QJHG.js} +2 -1
  105. package/dist/{restart-5F5QDBOG.js → restart-AGEGNSYQ.js} +2 -1
  106. package/dist/{sandbox-XPYA7UIF.js → sandbox-NNWCTHRI.js} +7 -4
  107. package/dist/scheduler-TNBN54ZK.js +25 -0
  108. package/dist/{schema-6YONVTKZ.js → schema-ZZQVM4GR.js} +5 -3
  109. package/dist/{seed-NQED7PSX.js → seed-K2LYODIH.js} +1 -1
  110. package/dist/{seed-check-TYD7RRZY.js → seed-check-NRJEQZST.js} +14 -5
  111. package/dist/{seed-cmd-QF3F2G4S.js → seed-cmd-2EWBTR6P.js} +3 -3
  112. package/dist/{seed-create-XOO4N2OE.js → seed-create-VGTLU5FD.js} +4 -4
  113. package/dist/{seed-readiness-3LRYASA4.js → seed-readiness-DYOVCYHN.js} +4 -5
  114. package/dist/{seed-sprout-HSBBGSS2.js → seed-sprout-PILHJ3YS.js} +9 -9
  115. package/dist/{send-IHRJYNXA.js → send-2YKOZJJ5.js} +108 -54
  116. package/dist/{service-YCOPCTSZ.js → service-XQPMZAGI.js} +4 -4
  117. package/dist/{service-install-Y46OTF55.js → service-install-2EWD7KXD.js} +5 -5
  118. package/dist/{setup-F4TE64YI.js → setup-MDPSK2XG.js} +6 -7
  119. package/dist/{setup-TCN7VH5U.js → setup-WZSXHHRJ.js} +10 -3
  120. package/dist/{skill-4CYJLYVY.js → skill-B5OJEQUA.js} +3 -2
  121. package/dist/skills/dreaming/references/INSTALL.md +2 -2
  122. package/dist/skills/imagegen/SKILL.md +21 -4
  123. package/dist/skills/imagegen/scripts/imagegen.ts +124 -21
  124. package/dist/skills/tending/SKILL.md +7 -7
  125. package/dist/skills/volute-mind/SKILL.md +3 -3
  126. package/dist/skills/volute-mind/references/integrations.md +2 -2
  127. package/dist/skills/volute-mind/references/routing.md +15 -15
  128. package/dist/{skills-NN5UZCUU.js → skills-NH2GQKAF.js} +4 -5
  129. package/dist/sleep-manager-7JXEQQ2P.js +41 -0
  130. package/dist/{spirit-SSJMYC6A.js → spirit-25JVAL3M.js} +11 -8
  131. package/dist/spirit-availability-PJDWZJ3J.js +42 -0
  132. package/dist/{split-JF2VWTXA.js → split-BU5VWX6P.js} +1 -1
  133. package/dist/{sprout-AXA2SECQ.js → sprout-EXUZMIOR.js} +1 -1
  134. package/dist/{src-YH6PQ7LJ.js → src-HGNE2XG4.js} +7 -1
  135. package/dist/{src-ZN4LXMPI.js → src-LCSOQY6Z.js} +57 -51
  136. package/dist/{src-JAOVXO5W.js → src-UDMJZ6MH.js} +8 -8
  137. package/dist/{start-BTVMTP3K.js → start-MUMNFR52.js} +2 -1
  138. package/dist/{status-VJGXMQ4L.js → status-MWLE3RVC.js} +7 -6
  139. package/dist/{stop-YORESK4U.js → stop-EKERNYTX.js} +2 -1
  140. package/dist/system-events-ZPSH63QX.js +46 -0
  141. package/dist/system-install-YZSWCPDK.js +8 -0
  142. package/dist/{systems-5MH2ELQE.js → systems-VDRUZXNF.js} +5 -4
  143. package/dist/{tailscale-AMMVKDXB.js → tailscale-KHNZFC7L.js} +2 -2
  144. package/dist/{template-hash-GSOUARW4.js → template-hash-YKWMVYMM.js} +2 -2
  145. package/dist/{template-staleness-HKGCTS3H.js → template-staleness-PY2CULH6.js} +5 -5
  146. package/dist/{turn-tracker-JQ2YUUY2.js → turn-tracker-TAT2HGK6.js} +6 -6
  147. package/dist/{up-SDLTLPAO.js → up-J7XCAH7P.js} +5 -6
  148. package/dist/{update-WEA4N2TR.js → update-CIWI2JYA.js} +5 -5
  149. package/dist/{update-check-DZOTONII.js → update-check-SZ7B5IFI.js} +3 -3
  150. package/dist/{upgrade-K5FIQPQD.js → upgrade-LIE46UBB.js} +1 -1
  151. package/dist/variant-cleanup-YXN25ZVW.js +22 -0
  152. package/dist/{version-notify-WFA5XB5A.js → version-notify-EN3KJ7HH.js} +11 -28
  153. package/dist/web-assets/assets/index-BOyJ4Gqs.css +1 -0
  154. package/dist/web-assets/assets/index-CrxBwnzp.js +95 -0
  155. package/dist/web-assets/index.html +2 -2
  156. package/dist/xai-P42CRCZA.js +129 -0
  157. package/drizzle/0014_system_events.sql +26 -0
  158. package/drizzle/0015_rename_session_to_thread.sql +12 -0
  159. package/drizzle/0016_brain_to_human.sql +4 -0
  160. package/drizzle/0017_event_history_rows.sql +9 -0
  161. package/drizzle/0018_api_tokens.sql +20 -0
  162. package/drizzle/meta/_journal.json +35 -0
  163. package/package.json +23 -23
  164. package/packages/extensions/notes/dist/ui/assets/index-BBs8pyel.js +67 -0
  165. package/packages/extensions/notes/dist/ui/index.html +1 -1
  166. package/packages/extensions/pages/dist/ui/assets/index-B589e8Xe.js +2 -0
  167. package/packages/extensions/pages/dist/ui/index.html +1 -1
  168. package/packages/extensions/plan/dist/ui/assets/index-B8s8wxyt.js +67 -0
  169. package/packages/extensions/plan/dist/ui/index.html +1 -1
  170. package/templates/_base/.init/.config/prompts.json +1 -0
  171. package/templates/_base/.init/.local/hooks/startup-context.ts +24 -9
  172. package/templates/_base/{biome.json.tmpl → biome.json} +2 -1
  173. package/templates/_base/gitignore +44 -0
  174. package/templates/_base/home/.config/routes.json +2 -2
  175. package/templates/_base/home/VOLUTE.md +18 -5
  176. package/templates/_base/home/public/.gitkeep +0 -0
  177. package/templates/_base/src/lib/daemon-client.ts +1 -1
  178. package/templates/_base/src/lib/event-turn.ts +39 -0
  179. package/templates/_base/src/lib/format-prefix.ts +36 -10
  180. package/templates/_base/src/lib/router.ts +19 -10
  181. package/templates/_base/src/lib/routing.ts +8 -8
  182. package/templates/_base/src/lib/startup.ts +9 -1
  183. package/templates/_base/src/lib/types.ts +7 -1
  184. package/templates/_base/src/lib/volute-server.ts +30 -1
  185. package/templates/claude/.init/.config/routes.json +3 -3
  186. package/templates/claude/.init/CLAUDE.md +1 -1
  187. package/templates/claude/{package.json.tmpl → package.json} +4 -4
  188. package/templates/claude/src/agent.ts +4 -1
  189. package/templates/claude/src/lib/hooks/reply-instructions.ts +26 -1
  190. package/templates/claude/volute-template.json +1 -3
  191. package/templates/codex/.init/.config/routes.json +3 -3
  192. package/templates/codex/.init/AGENTS.md +1 -1
  193. package/templates/codex/{package.json.tmpl → package.json} +4 -4
  194. package/templates/codex/src/agent.ts +11 -11
  195. package/templates/codex/src/lib/turn-context.ts +51 -0
  196. package/templates/codex/volute-template.json +1 -3
  197. package/templates/pi/.init/.config/routes.json +3 -3
  198. package/templates/pi/.init/MINDS.md +1 -1
  199. package/templates/pi/{package.json.tmpl → package.json} +6 -6
  200. package/templates/pi/src/agent.ts +9 -1
  201. package/templates/pi/src/lib/event-handler.ts +1 -1
  202. package/templates/pi/src/lib/reply-instructions-extension.ts +28 -1
  203. package/templates/pi/volute-template.json +1 -3
  204. package/dist/chunk-5T5YMX6S.js +0 -23
  205. package/dist/chunk-NJHN6IRB.js +0 -177
  206. package/dist/chunk-QQBOI3QA.js +0 -5345
  207. package/dist/chunk-XTEKINWG.js +0 -158
  208. package/dist/delivery-manager-RBXBPVWM.js +0 -36
  209. package/dist/echo-text-B6NZ5FGE.js +0 -36
  210. package/dist/message-delivery-ABPV76EA.js +0 -42
  211. package/dist/mind-service-42GDO4KH.js +0 -44
  212. package/dist/notices-N6BCGHFV.js +0 -25
  213. package/dist/scheduler-K7Y7Z7FQ.js +0 -34
  214. package/dist/sleep-manager-DSPXFHGX.js +0 -38
  215. package/dist/system-chat-M2XOBKEM.js +0 -40
  216. package/dist/variant-cleanup-P4MBNLJD.js +0 -33
  217. package/dist/web-assets/assets/index-BostMFoR.css +0 -1
  218. package/dist/web-assets/assets/index-CKlqUkyG.js +0 -92
  219. package/packages/extensions/notes/dist/ui/assets/index-D0-DgYyj.js +0 -67
  220. package/packages/extensions/pages/dist/ui/assets/index-DtzftuPA.js +0 -2
  221. package/packages/extensions/plan/dist/ui/assets/index-Cfzs-0G9.js +0 -67
  222. /package/templates/_base/home/.config/{config.json.tmpl → config.json} +0 -0
  223. /package/templates/codex/home/.config/{config.json.tmpl → config.json} +0 -0
  224. /package/templates/pi/home/.config/{config.json.tmpl → config.json} +0 -0
@@ -8,8 +8,8 @@
8
8
  <link rel="preconnect" href="https://fonts.googleapis.com" />
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
10
  <link href="https://fonts.googleapis.com/css2?family=Averia+Serif+Libre:wght@300;400;700&family=Fira+Code:wght@300;400;500;600&family=Averia+Sans+Libre:ital,wght@0,300;0,400;0,500;0,600;1,400&display=swap" rel="stylesheet" />
11
- <script type="module" crossorigin src="/assets/index-CKlqUkyG.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-BostMFoR.css">
11
+ <script type="module" crossorigin src="/assets/index-CrxBwnzp.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-BOyJ4Gqs.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ import "./chunk-K3NQKI34.js";
3
+
4
+ // packages/daemon/src/lib/oauth/xai.ts
5
+ import {
6
+ pollOAuthDeviceCodeFlow,
7
+ registerOAuthProvider
8
+ } from "@earendil-works/pi-ai/oauth";
9
+ var XAI_OAUTH_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
10
+ var XAI_OAUTH_SCOPE = "openid profile email offline_access grok-cli:access api:access";
11
+ var XAI_ISSUER = "https://auth.x.ai";
12
+ var XAI_DISCOVERY_URL = `${XAI_ISSUER}/.well-known/openid-configuration`;
13
+ var FALLBACK_DEVICE_ENDPOINT = `${XAI_ISSUER}/oauth2/device/code`;
14
+ var FALLBACK_TOKEN_ENDPOINT = `${XAI_ISSUER}/oauth2/token`;
15
+ function validateXaiUrl(url) {
16
+ const u = new URL(url);
17
+ if (u.hostname !== "auth.x.ai" || u.protocol !== "https:") {
18
+ throw new Error(`Refusing non-xAI OAuth endpoint: ${url}`);
19
+ }
20
+ return u.toString();
21
+ }
22
+ async function discoverEndpoints(signal) {
23
+ try {
24
+ const res = await fetch(XAI_DISCOVERY_URL, { signal });
25
+ if (res.ok) {
26
+ const doc = await res.json();
27
+ if (doc.device_authorization_endpoint && doc.token_endpoint) {
28
+ return {
29
+ deviceEndpoint: validateXaiUrl(doc.device_authorization_endpoint),
30
+ tokenEndpoint: validateXaiUrl(doc.token_endpoint)
31
+ };
32
+ }
33
+ }
34
+ } catch {
35
+ }
36
+ return { deviceEndpoint: FALLBACK_DEVICE_ENDPOINT, tokenEndpoint: FALLBACK_TOKEN_ENDPOINT };
37
+ }
38
+ function credentialsFromTokenResponse(raw) {
39
+ const json = raw ?? {};
40
+ if (!json.access_token || typeof json.expires_in !== "number") {
41
+ throw new Error("xAI token response missing access_token/expires_in");
42
+ }
43
+ return {
44
+ access: json.access_token,
45
+ // A refresh grant may omit refresh_token; the caller merges the old one.
46
+ refresh: json.refresh_token ?? "",
47
+ expires: Date.now() + json.expires_in * 1e3
48
+ };
49
+ }
50
+ async function login(callbacks) {
51
+ const { deviceEndpoint, tokenEndpoint } = await discoverEndpoints(callbacks.signal);
52
+ const deviceRes = await fetch(deviceEndpoint, {
53
+ method: "POST",
54
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
55
+ body: new URLSearchParams({ client_id: XAI_OAUTH_CLIENT_ID, scope: XAI_OAUTH_SCOPE }),
56
+ signal: callbacks.signal
57
+ });
58
+ if (!deviceRes.ok) {
59
+ throw new Error(`xAI device authorization failed: HTTP ${deviceRes.status}`);
60
+ }
61
+ const device = await deviceRes.json();
62
+ callbacks.onDeviceCode({
63
+ userCode: device.user_code,
64
+ verificationUri: device.verification_uri_complete ?? device.verification_uri,
65
+ intervalSeconds: device.interval,
66
+ expiresInSeconds: device.expires_in
67
+ });
68
+ return pollOAuthDeviceCodeFlow({
69
+ intervalSeconds: device.interval,
70
+ expiresInSeconds: device.expires_in,
71
+ signal: callbacks.signal,
72
+ poll: async () => {
73
+ const res = await fetch(tokenEndpoint, {
74
+ method: "POST",
75
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
76
+ body: new URLSearchParams({
77
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
78
+ device_code: device.device_code,
79
+ client_id: XAI_OAUTH_CLIENT_ID
80
+ }),
81
+ signal: callbacks.signal
82
+ });
83
+ if (res.ok) {
84
+ return { status: "complete", value: credentialsFromTokenResponse(await res.json()) };
85
+ }
86
+ const body = await res.json().catch(() => ({}));
87
+ if (body.error === "authorization_pending") return { status: "pending" };
88
+ if (body.error === "slow_down") return { status: "slow_down" };
89
+ return { status: "failed", message: body.error ?? `HTTP ${res.status}` };
90
+ }
91
+ });
92
+ }
93
+ async function refreshToken(credentials) {
94
+ const { tokenEndpoint } = await discoverEndpoints();
95
+ const res = await fetch(tokenEndpoint, {
96
+ method: "POST",
97
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
98
+ body: new URLSearchParams({
99
+ grant_type: "refresh_token",
100
+ refresh_token: credentials.refresh,
101
+ client_id: XAI_OAUTH_CLIENT_ID
102
+ })
103
+ });
104
+ if (!res.ok) throw new Error(`xAI token refresh failed: HTTP ${res.status}`);
105
+ const next = credentialsFromTokenResponse(await res.json());
106
+ if (!next.refresh) next.refresh = credentials.refresh;
107
+ return next;
108
+ }
109
+ var xaiOAuthProvider = {
110
+ id: "xai",
111
+ name: "xAI (Grok)",
112
+ usesCallbackServer: false,
113
+ login,
114
+ refreshToken,
115
+ getApiKey: (credentials) => credentials.access
116
+ };
117
+ var registered = false;
118
+ function registerXaiOAuthProvider() {
119
+ if (registered) return;
120
+ registerOAuthProvider(xaiOAuthProvider);
121
+ registered = true;
122
+ }
123
+ export {
124
+ XAI_OAUTH_CLIENT_ID,
125
+ XAI_OAUTH_SCOPE,
126
+ registerXaiOAuthProvider,
127
+ validateXaiUrl,
128
+ xaiOAuthProvider
129
+ };
@@ -0,0 +1,26 @@
1
+ -- System events: environment → mind traffic (replaces mind_notices).
2
+ -- No sender, no reply target; a separate stream from chat.
3
+
4
+ CREATE TABLE IF NOT EXISTS `system_events` (
5
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
6
+ `mind` text NOT NULL,
7
+ `type` text NOT NULL,
8
+ `body` text NOT NULL,
9
+ `meta` text,
10
+ `delivery` text NOT NULL DEFAULT 'immediate',
11
+ `session` text NOT NULL DEFAULT 'main',
12
+ `created_at` text NOT NULL DEFAULT (datetime('now')),
13
+ `delivered_at` text,
14
+ `reflection` text
15
+ );
16
+ --> statement-breakpoint
17
+ CREATE INDEX IF NOT EXISTS `idx_system_events_mind` ON `system_events` (`mind`);
18
+ --> statement-breakpoint
19
+ CREATE INDEX IF NOT EXISTS `idx_system_events_mind_delivery` ON `system_events` (`mind`, `delivery`, `delivered_at`);
20
+ --> statement-breakpoint
21
+ CREATE INDEX IF NOT EXISTS `idx_system_events_mind_type` ON `system_events` (`mind`, `type`);
22
+ --> statement-breakpoint
23
+ -- Deliberately discards any pending mind_notices rows at upgrade: notice rows were
24
+ -- transient (deleted after delivery), so losing an undelivered failure notice across
25
+ -- an upgrade is acceptable — no data migration is performed.
26
+ DROP TABLE IF EXISTS `mind_notices`;
@@ -0,0 +1,12 @@
1
+ -- Rename the routing "session" column to "thread" on turns, mind_history,
2
+ -- delivery_queue, and system_events. The routing sense of "session" is renamed
3
+ -- to "thread" (issue #493); auth sessions and SDK transcript files keep "session".
4
+ ALTER TABLE `turns` RENAME COLUMN `session` TO `thread`;--> statement-breakpoint
5
+ ALTER TABLE `mind_history` RENAME COLUMN `session` TO `thread`;--> statement-breakpoint
6
+ DROP INDEX IF EXISTS `idx_mind_history_session`;--> statement-breakpoint
7
+ CREATE INDEX IF NOT EXISTS `idx_mind_history_thread` ON `mind_history` (`thread`);--> statement-breakpoint
8
+ ALTER TABLE `delivery_queue` RENAME COLUMN `session` TO `thread`;--> statement-breakpoint
9
+ DROP INDEX IF EXISTS `idx_delivery_queue_mind_session`;--> statement-breakpoint
10
+ CREATE INDEX IF NOT EXISTS `idx_delivery_queue_mind_thread` ON `delivery_queue` (`mind`, `thread`);--> statement-breakpoint
11
+ -- system_events is created by 0014 on this same train, so the rename is always valid.
12
+ ALTER TABLE `system_events` RENAME COLUMN `session` TO `thread`;
@@ -0,0 +1,4 @@
1
+ -- Retire the "brain" user_type in favour of "human" (issue #493). Human users
2
+ -- were stored as user_type = 'brain'; migrate live rows so prefixes and profile
3
+ -- cards render [human]. Mind, system, and puppet types are unchanged.
4
+ UPDATE `users` SET `user_type` = 'human' WHERE `user_type` = 'brain';
@@ -0,0 +1,9 @@
1
+ -- System events are not messages. They were recorded in mind_history as `inbound` rows,
2
+ -- so every history surface rendered them as chat with a phantom sender ("user"), and minds
3
+ -- read them as messages they were expected to reply to. Retype the delivered-event rows so
4
+ -- the timeline and `volute mind history` can render them as system markers instead.
5
+ --
6
+ -- The `event:<type>:<id>` channel is written only by recordEventRow, so it identifies
7
+ -- these rows exactly. Turn linkage (turn_id / trigger_event_id) is untouched — the linkers
8
+ -- match both types, so reflection capture keeps working for historical turns.
9
+ UPDATE `mind_history` SET `type` = 'event' WHERE `type` = 'inbound' AND `channel` LIKE 'event:%';
@@ -0,0 +1,20 @@
1
+ -- Durable, hashed, revocable per-user API credentials.
2
+ --
3
+ -- Keyed to a `users` row rather than a mind name, so the same token type serves
4
+ -- external minds (users rows with user_type "mind" and no minds registry row)
5
+ -- and, later, external humans. Only the SHA-256 hash is stored; revocation is a
6
+ -- row DELETE, and the FK cascade drops a user's tokens along with the user.
7
+ --
8
+ -- Orthogonal to the in-memory native-mind token map: these survive a restart.
9
+
10
+ CREATE TABLE IF NOT EXISTS `api_tokens` (
11
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
12
+ `user_id` integer NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
13
+ `token_hash` text NOT NULL,
14
+ `label` text,
15
+ `created_at` text NOT NULL DEFAULT (datetime('now'))
16
+ );
17
+ --> statement-breakpoint
18
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_api_tokens_hash` ON `api_tokens` (`token_hash`);
19
+ --> statement-breakpoint
20
+ CREATE INDEX IF NOT EXISTS `idx_api_tokens_user` ON `api_tokens` (`user_id`);
@@ -99,6 +99,41 @@
99
99
  "when": 1775800000000,
100
100
  "tag": "0013_variant_purpose",
101
101
  "breakpoints": true
102
+ },
103
+ {
104
+ "idx": 14,
105
+ "version": "6",
106
+ "when": 1775900000000,
107
+ "tag": "0014_system_events",
108
+ "breakpoints": true
109
+ },
110
+ {
111
+ "idx": 15,
112
+ "version": "6",
113
+ "when": 1776000000000,
114
+ "tag": "0015_rename_session_to_thread",
115
+ "breakpoints": true
116
+ },
117
+ {
118
+ "idx": 16,
119
+ "version": "6",
120
+ "when": 1776100000000,
121
+ "tag": "0016_brain_to_human",
122
+ "breakpoints": true
123
+ },
124
+ {
125
+ "idx": 17,
126
+ "version": "6",
127
+ "when": 1776200000000,
128
+ "tag": "0017_event_history_rows",
129
+ "breakpoints": true
130
+ },
131
+ {
132
+ "idx": 18,
133
+ "version": "6",
134
+ "when": 1776300000000,
135
+ "tag": "0018_api_tokens",
136
+ "breakpoints": true
102
137
  }
103
138
  ]
104
139
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volute",
3
- "version": "0.49.0",
3
+ "version": "0.51.0",
4
4
  "description": "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -66,44 +66,44 @@
66
66
  "db:migrate": "drizzle-kit migrate"
67
67
  },
68
68
  "dependencies": {
69
- "@anthropic-ai/sandbox-runtime": "^0.0.56",
70
- "@earendil-works/pi-ai": "^0.80.3",
71
- "@hono/node-server": "^2.0.6",
69
+ "@anthropic-ai/sandbox-runtime": "^0.0.65",
70
+ "@earendil-works/pi-ai": "^0.80.6",
71
+ "@hono/node-server": "^2.0.8",
72
72
  "@hono/zod-validator": "^0.8.0",
73
73
  "@libsql/client": "^0.17.4",
74
74
  "@slack/bolt": "^4.7.3",
75
- "adm-zip": "^0.5.17",
75
+ "adm-zip": "^0.6.0",
76
76
  "bcryptjs": "^3.0.3",
77
- "cron-parser": "^5.6.0",
78
- "discord.js": "^14.26.4",
77
+ "cron-parser": "^5.6.2",
78
+ "discord.js": "^14.26.5",
79
79
  "drizzle-orm": "^0.45.2",
80
- "hono": "^4.12.26",
81
- "isomorphic-dompurify": "^2.36.0",
80
+ "hono": "^4.12.30",
81
+ "isomorphic-dompurify": "^3.18.0",
82
82
  "libsql": "^0.5.29",
83
83
  "replicate": "^1.4.0",
84
- "sharp": "^0.35.2",
84
+ "sharp": "^0.35.3",
85
85
  "telegraf": "^4.16.3",
86
- "undici": "^6.24.1",
86
+ "undici": "^7.28.0",
87
87
  "zod": "^4.4.3"
88
88
  },
89
89
  "devDependencies": {
90
- "@anthropic-ai/claude-agent-sdk": "^0.3.197",
91
- "@biomejs/biome": "2.5.0",
92
- "@earendil-works/pi-coding-agent": "^0.80.3",
93
- "@sveltejs/vite-plugin-svelte": "^7.1.2",
90
+ "@anthropic-ai/claude-agent-sdk": "^0.3.207",
91
+ "@biomejs/biome": "2.5.3",
92
+ "@earendil-works/pi-coding-agent": "^0.80.6",
93
+ "@sveltejs/vite-plugin-svelte": "^7.2.0",
94
94
  "@types/adm-zip": "^0.5.8",
95
- "@types/node": "^26.0.0",
96
- "dompurify": "^3.4.11",
95
+ "@types/node": "^26.1.1",
96
+ "dompurify": "3.4.11",
97
97
  "drizzle-kit": "^0.31.10",
98
98
  "knip": "^6.26.0",
99
- "lefthook": "^2.1.9",
100
- "marked": "^18.0.5",
101
- "svelte": "^5.56.3",
102
- "svelte-check": "4.7.1",
99
+ "lefthook": "^2.1.10",
100
+ "marked": "^18.0.6",
101
+ "svelte": "^5.56.4",
102
+ "svelte-check": "4.7.2",
103
103
  "tsup": "^8.5.1",
104
- "tsx": "^4.22.4",
104
+ "tsx": "^4.23.1",
105
105
  "typescript": "^6.0.3",
106
- "vite": "^8.0.16"
106
+ "vite": "^8.1.4"
107
107
  },
108
108
  "overrides": {
109
109
  "esrap": "2.2.11"