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
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  activity,
4
+ apiTokens,
4
5
  channelGates,
5
6
  channels,
6
7
  conversationParticipants,
@@ -9,18 +10,19 @@ import {
9
10
  deliveryQueue,
10
11
  messages,
11
12
  mindHistory,
12
- mindNotices,
13
13
  minds,
14
14
  sessions,
15
15
  sharedSkills,
16
16
  summaries,
17
+ systemEvents,
17
18
  systemPrompts,
18
19
  turns,
19
20
  users
20
- } from "./chunk-P4LHVRNE.js";
21
+ } from "./chunk-2RNMBXD2.js";
21
22
  import "./chunk-K3NQKI34.js";
22
23
  export {
23
24
  activity,
25
+ apiTokens,
24
26
  channelGates,
25
27
  channels,
26
28
  conversationParticipants,
@@ -29,11 +31,11 @@ export {
29
31
  deliveryQueue,
30
32
  messages,
31
33
  mindHistory,
32
- mindNotices,
33
34
  minds,
34
35
  sessions,
35
36
  sharedSkills,
36
37
  summaries,
38
+ systemEvents,
37
39
  systemPrompts,
38
40
  turns,
39
41
  users
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
4
4
  // packages/cli/src/commands/seed.ts
5
5
  async function run(args) {
6
6
  console.error("Note: `volute mind seed` is now `volute seed create`");
7
- await import("./seed-create-XOO4N2OE.js").then((m) => m.run(args));
7
+ await import("./seed-create-VGTLU5FD.js").then((m) => m.run(args));
8
8
  }
9
9
  export {
10
10
  run
@@ -10,14 +10,21 @@ var cmd = command({
10
10
  name: "volute seed check",
11
11
  description: "Check seed readiness",
12
12
  args: [{ name: "name", required: true, description: "Seed mind to check" }],
13
- flags: {},
14
- run: async ({ args }) => {
13
+ flags: {
14
+ nurture: {
15
+ type: "boolean",
16
+ description: "Apply the nurture gate (used by the spirit's schedule): stay silent when no nudge is needed"
17
+ }
18
+ },
19
+ run: async ({ args, flags }) => {
15
20
  const name = args.name;
16
- const { daemonFetch } = await import("./daemon-client-ZFY5MOAL.js");
17
- const res = await daemonFetch(`/api/minds/${encodeURIComponent(name)}/seed-check`);
21
+ const query = flags.nurture ? "" : "?force=1";
22
+ const { daemonFetch } = await import("./daemon-client-VVYFZI2D.js");
23
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(name)}/seed-check${query}`);
18
24
  if (!res.ok) {
25
+ process.exitCode = 1;
19
26
  if (res.status === 404) {
20
- console.log(`Seed "${name}" not found \u2014 it may have been deleted or already sprouted.`);
27
+ console.error(`Seed "${name}" not found \u2014 it may have been deleted.`);
21
28
  } else {
22
29
  console.error(`seed check failed for ${name}: HTTP ${res.status}`);
23
30
  }
@@ -26,6 +33,8 @@ var cmd = command({
26
33
  const data = await res.json();
27
34
  if (data.output) {
28
35
  console.log(data.output);
36
+ } else if (!flags.nurture) {
37
+ console.log(`No readiness output returned for ${name}.`);
29
38
  }
30
39
  }
31
40
  });
@@ -12,15 +12,15 @@ var cmd = subcommands({
12
12
  commands: {
13
13
  create: {
14
14
  description: "Plant a new seed",
15
- run: (args) => import("./seed-create-XOO4N2OE.js").then((m) => m.run(args))
15
+ run: (args) => import("./seed-create-VGTLU5FD.js").then((m) => m.run(args))
16
16
  },
17
17
  sprout: {
18
18
  description: "Complete orientation and become a full mind",
19
- run: (args) => import("./seed-sprout-HSBBGSS2.js").then((m) => m.run(args))
19
+ run: (args) => import("./seed-sprout-PILHJ3YS.js").then((m) => m.run(args))
20
20
  },
21
21
  check: {
22
22
  description: "Check seed readiness",
23
- run: (args) => import("./seed-check-TYD7RRZY.js").then((m) => m.run(args))
23
+ run: (args) => import("./seed-check-NRJEQZST.js").then((m) => m.run(args))
24
24
  }
25
25
  }
26
26
  });
@@ -47,19 +47,19 @@ var cmd = command({
47
47
  const name = args.name;
48
48
  const skills = flags.skills === "none" ? [] : flags.skills ? flags.skills.split(",") : void 0;
49
49
  const createdBy = flags["created-by"];
50
- const { daemonFetch } = await import("./daemon-client-ZFY5MOAL.js");
50
+ const { daemonFetch } = await import("./daemon-client-VVYFZI2D.js");
51
51
  const { getClient, urlOf } = await import("./api-client-LC5YRA32.js");
52
52
  const client = getClient();
53
53
  let model = flags.model;
54
54
  let template = flags.template;
55
55
  if (!template) {
56
- const { resolveTemplate } = await import("./ai-service-A7FS7EC3.js");
56
+ const { resolveTemplate } = await import("./ai-service-YW5SWCSB.js");
57
57
  template = await resolveTemplate(model);
58
58
  }
59
59
  if (template !== "claude" && !model) {
60
60
  if (process.env.VOLUTE_MIND || !process.stdin.isTTY) {
61
- const { getSpiritModel } = await import("./spirit-SSJMYC6A.js");
62
- const { qualifyModelId } = await import("./ai-service-A7FS7EC3.js");
61
+ const { getSpiritModel } = await import("./spirit-25JVAL3M.js");
62
+ const { qualifyModelId } = await import("./ai-service-YW5SWCSB.js");
63
63
  const spiritModel = getSpiritModel();
64
64
  if (spiritModel) {
65
65
  model = template === "pi" ? qualifyModelId(spiritModel) : spiritModel;
@@ -3,13 +3,12 @@ import {
3
3
  evaluateSeedChecklist,
4
4
  isMemoryWritten,
5
5
  isSoulWritten
6
- } from "./chunk-TXJL36ZQ.js";
7
- import "./chunk-JPGHSXSV.js";
6
+ } from "./chunk-JHKBALS2.js";
7
+ import "./chunk-FXWBFDQR.js";
8
8
  import "./chunk-DW4TRDOZ.js";
9
9
  import "./chunk-WCFSBH33.js";
10
- import "./chunk-NJHN6IRB.js";
11
- import "./chunk-RSBL3FAD.js";
12
- import "./chunk-P4LHVRNE.js";
10
+ import "./chunk-H6X6CKDN.js";
11
+ import "./chunk-2RNMBXD2.js";
13
12
  import "./chunk-K3NQKI34.js";
14
13
  export {
15
14
  evaluateSeedChecklist,
@@ -1,27 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  daemonFetch
4
- } from "./chunk-BCG45AQB.js";
4
+ } from "./chunk-M74I3HHF.js";
5
5
  import {
6
6
  command
7
7
  } from "./chunk-TXSA4Q3V.js";
8
8
  import "./chunk-O7IGP7ZW.js";
9
+ import "./chunk-FNJCBRD3.js";
9
10
  import {
10
11
  evaluateSeedChecklist
11
- } from "./chunk-TXJL36ZQ.js";
12
+ } from "./chunk-JHKBALS2.js";
12
13
  import {
13
14
  getStandardSkillsWithExtensions
14
- } from "./chunk-GWVFDUNB.js";
15
- import "./chunk-JPGHSXSV.js";
15
+ } from "./chunk-QT4D5XCI.js";
16
+ import "./chunk-FXWBFDQR.js";
16
17
  import "./chunk-DW4TRDOZ.js";
17
18
  import "./chunk-WCFSBH33.js";
18
- import "./chunk-DVN6DNMI.js";
19
- import "./chunk-NJHN6IRB.js";
19
+ import "./chunk-M77B73VV.js";
20
20
  import "./chunk-QUSMYGNQ.js";
21
21
  import {
22
22
  mindDir
23
- } from "./chunk-RSBL3FAD.js";
24
- import "./chunk-P4LHVRNE.js";
23
+ } from "./chunk-H6X6CKDN.js";
24
+ import "./chunk-2RNMBXD2.js";
25
25
  import "./chunk-K3NQKI34.js";
26
26
 
27
27
  // packages/cli/src/commands/seed-sprout.ts
@@ -74,7 +74,7 @@ var cmd = command({
74
74
  process.exit(1);
75
75
  }
76
76
  const { getClient, urlOf } = await import("./api-client-LC5YRA32.js");
77
- const { mindSkillsDir } = await import("./skills-NN5UZCUU.js");
77
+ const { mindSkillsDir } = await import("./skills-NH2GQKAF.js");
78
78
  const client = getClient();
79
79
  const failedSkills = [];
80
80
  for (const skillId of getStandardSkillsWithExtensions()) {
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-33ODGMFZ.js";
5
5
  import {
6
6
  isCompact
7
- } from "./chunk-5T5YMX6S.js";
7
+ } from "./chunk-7YJY3F2R.js";
8
8
  import {
9
9
  daemonFetch
10
- } from "./chunk-BCG45AQB.js";
10
+ } from "./chunk-M74I3HHF.js";
11
11
  import {
12
12
  getClient,
13
13
  urlOf
@@ -16,11 +16,12 @@ import {
16
16
  command
17
17
  } from "./chunk-TXSA4Q3V.js";
18
18
  import "./chunk-O7IGP7ZW.js";
19
+ import "./chunk-FNJCBRD3.js";
19
20
  import {
20
21
  formatFileSize
21
- } from "./chunk-NOIAHMJB.js";
22
- import "./chunk-RSBL3FAD.js";
23
- import "./chunk-P4LHVRNE.js";
22
+ } from "./chunk-DMK5ASKV.js";
23
+ import "./chunk-H6X6CKDN.js";
24
+ import "./chunk-2RNMBXD2.js";
24
25
  import "./chunk-K3NQKI34.js";
25
26
 
26
27
  // packages/cli/src/commands/send.ts
@@ -154,6 +155,18 @@ async function waitForResponse(mindName, conversationId, timeoutMs) {
154
155
  });
155
156
  }
156
157
  }
158
+ function spiritAck(spirit) {
159
+ switch (spirit) {
160
+ case "waking":
161
+ return "The system spirit is waking \u2014 a reply is on its way.";
162
+ case "sleeping":
163
+ return "The system spirit is sleeping \u2014 it will reply when it wakes.";
164
+ case "unavailable":
165
+ return "The system spirit is unavailable \u2014 an admin can fix this in Settings.";
166
+ default:
167
+ return null;
168
+ }
169
+ }
157
170
  function printSendResult(data) {
158
171
  if (data.held) {
159
172
  if (data.notice) console.log(data.notice);
@@ -166,6 +179,8 @@ function printSendResult(data) {
166
179
  console.log(`Message sent.${outboundId != null ? `
167
180
  [volute:outbound:${outboundId}]` : ""}`);
168
181
  }
182
+ const ack = spiritAck(data.spirit);
183
+ if (ack) console.log(ack);
169
184
  }
170
185
  var cmd = command({
171
186
  name: "volute chat send",
@@ -211,84 +226,108 @@ var cmd = command({
211
226
  }
212
227
  if (target === "system" || target === "@system") {
213
228
  console.error(
214
- `Can't send to system \u2014 system messages are automated.
215
- To reply to a person, use their username from the message prefix (e.g. volute chat send @username "msg").`
229
+ `Can't send to system \u2014 system events come from your environment, not a person, and nothing is waiting on a reply.
230
+ To reach a person, use their username from the message prefix (e.g. volute chat send @username "msg").`
216
231
  );
217
232
  process.exit(1);
218
233
  }
234
+ let parsed = parseTarget(target);
235
+ if (!parsed.isDM && parsed.platform === "volute" && await isMind(parsed.identifier)) {
236
+ parsed = {
237
+ platform: "volute",
238
+ identifier: `@${parsed.identifier}`,
239
+ uri: `@${parsed.identifier}`,
240
+ isDM: true
241
+ };
242
+ }
243
+ const dmTargetName = parsed.isDM && parsed.platform === "volute" ? parsed.identifier.slice(1) : void 0;
219
244
  if (flags.file) {
245
+ if (!dmTargetName || !await isMind(dmTargetName)) {
246
+ console.error(
247
+ `--file can only attach to a direct message to a mind \u2014 e.g.
248
+ volute chat send @mind "here you go" --file <path>
249
+ Channels and non-mind recipients can't receive a file share.`
250
+ );
251
+ process.exit(1);
252
+ }
253
+ if (!message && images) {
254
+ console.error(
255
+ "Can't attach an image and a file without a message. Send the image with a message, or send the file on its own."
256
+ );
257
+ process.exit(1);
258
+ }
259
+ }
260
+ const stageAttachedFile = async (afterSend) => {
220
261
  const filePath = flags.file;
221
- const parsed2 = parseTarget(target);
222
- const targetName = parsed2.isDM && parsed2.platform === "volute" ? parsed2.identifier.slice(1) : parsed2.identifier;
262
+ const targetName = dmTargetName;
263
+ const failStaging = (reason) => {
264
+ console.error(
265
+ afterSend ? `Your message was delivered. Only the file failed: ${reason}
266
+ Retry the attachment with: volute chat send ${target} --file ${filePath} (no message) \u2014 sending the whole command again would duplicate the message.` : reason
267
+ );
268
+ process.exit(1);
269
+ };
270
+ const postStaging = async (path, body) => {
271
+ let res;
272
+ try {
273
+ res = await daemonFetch(path, {
274
+ method: "POST",
275
+ headers: { "Content-Type": "application/json" },
276
+ body: JSON.stringify(body)
277
+ });
278
+ } catch (err) {
279
+ return failStaging(`couldn't reach the daemon (${err.message})`);
280
+ }
281
+ if (!res.ok) {
282
+ const data2 = await res.json().catch(() => ({}));
283
+ return failStaging(data2.error ?? `daemon returned ${res.status}`);
284
+ }
285
+ const data = await res.json().catch(() => ({}));
286
+ return data.id ?? "?";
287
+ };
223
288
  const mindSelf = process.env.VOLUTE_MIND;
224
289
  if (mindSelf) {
225
- const res = await daemonFetch(`/api/minds/${encodeURIComponent(mindSelf)}/files/send`, {
226
- method: "POST",
227
- headers: { "Content-Type": "application/json" },
228
- body: JSON.stringify({ targetMind: targetName, filePath })
290
+ const id = await postStaging(`/api/minds/${encodeURIComponent(mindSelf)}/files/send`, {
291
+ targetMind: targetName,
292
+ filePath
229
293
  });
230
- if (!res.ok) {
231
- const data2 = await res.json();
232
- console.error(data2.error ?? `Failed to send file: ${res.status}`);
233
- process.exit(1);
234
- }
235
- const data = await res.json();
236
- console.log(`File staged for ${targetName} (id: ${data.id})`);
294
+ console.log(`File staged for ${targetName} (id: ${id})`);
237
295
  } else {
238
296
  if (!existsSync(filePath)) {
239
- console.error(`File not found: ${filePath}`);
240
- process.exit(1);
297
+ failStaging(`File not found: ${filePath}`);
241
298
  }
242
299
  const stat = statSync(filePath);
243
300
  const MAX_FILE_SIZE = 50 * 1024 * 1024;
244
301
  if (stat.size > MAX_FILE_SIZE) {
245
- console.error(
302
+ failStaging(
246
303
  `File too large (${formatFileSize(stat.size)}, max ${formatFileSize(MAX_FILE_SIZE)})`
247
304
  );
248
- process.exit(1);
249
305
  }
250
306
  const content = readFileSync(filePath);
251
- const filename = basename(filePath);
252
- const senderName = flags.sender || userInfo().username;
253
- const res = await daemonFetch(`/api/minds/${encodeURIComponent(targetName)}/files/stage`, {
254
- method: "POST",
255
- headers: { "Content-Type": "application/json" },
256
- body: JSON.stringify({
257
- sender: senderName,
258
- filename,
259
- data: content.toString("base64")
260
- })
307
+ const id = await postStaging(`/api/minds/${encodeURIComponent(targetName)}/files/stage`, {
308
+ sender: flags.sender || userInfo().username,
309
+ filename: basename(filePath),
310
+ data: content.toString("base64")
261
311
  });
262
- if (!res.ok) {
263
- const data2 = await res.json();
264
- console.error(data2.error ?? `Failed to stage file: ${res.status}`);
265
- process.exit(1);
266
- }
267
- const data = await res.json();
268
- console.log(`File staged for ${targetName} (id: ${data.id})`);
312
+ console.log(`File staged for ${targetName} (id: ${id})`);
269
313
  }
270
- if (!message) return;
271
- }
272
- let parsed = parseTarget(target);
273
- if (!parsed.isDM && parsed.platform === "volute" && await isMind(parsed.identifier)) {
274
- parsed = {
275
- platform: "volute",
276
- identifier: `@${parsed.identifier}`,
277
- uri: `@${parsed.identifier}`,
278
- isDM: true
279
- };
314
+ };
315
+ if (flags.file && !message) {
316
+ await stageAttachedFile(false);
317
+ return;
280
318
  }
281
319
  const client = getClient();
282
320
  let waitMindName;
283
321
  let waitConversationId;
284
322
  let heldResponse = false;
323
+ let spiritUnavailable = false;
285
324
  if (parsed.isDM && parsed.platform === "volute") {
286
325
  const targetName = parsed.identifier.slice(1);
287
326
  const mindSelf = process.env.VOLUTE_MIND;
288
327
  const sender = flags.sender || mindSelf || userInfo().username;
289
328
  if (mindSelf && targetName === mindSelf) {
290
329
  console.error(
291
- `Can't send to @${targetName} \u2014 that's your own system channel. System messages there are automated notices; they don't need a reply.`
330
+ `Can't send to @${targetName} \u2014 that's yourself. System events arrive from your environment and don't need a reply.`
292
331
  );
293
332
  process.exit(1);
294
333
  }
@@ -334,7 +373,13 @@ To reply to a person, use their username from the message prefix (e.g. volute ch
334
373
  console.error(`Warning: could not read send response: ${err.message}`);
335
374
  }
336
375
  if (data.held) heldResponse = true;
337
- if (data.held || !flags.wait) printSendResult(data);
376
+ if (data.held || !flags.wait || flags.file) {
377
+ printSendResult(data);
378
+ } else {
379
+ const ack = spiritAck(data.spirit);
380
+ if (ack) console.log(ack);
381
+ }
382
+ if (data.spirit === "unavailable") spiritUnavailable = true;
338
383
  } else if (!parsed.isDM && parsed.platform === "volute") {
339
384
  if (!parsed.identifier.startsWith("#")) {
340
385
  console.error(
@@ -391,7 +436,16 @@ See: volute chat bridge --help`
391
436
  );
392
437
  process.exit(1);
393
438
  }
394
- if (heldResponse) {
439
+ if (flags.file) {
440
+ if (heldResponse) {
441
+ console.log(
442
+ "Your attached file was not staged \u2014 include --file <path> again when you re-send."
443
+ );
444
+ } else {
445
+ await stageAttachedFile(true);
446
+ }
447
+ }
448
+ if (heldResponse || spiritUnavailable) {
395
449
  } else if (flags.wait && waitMindName) {
396
450
  if (!waitConversationId) {
397
451
  console.error("--wait requires a volute conversation (DM to a mind)");
@@ -9,10 +9,10 @@ import {
9
9
  SYSTEM_LAUNCHD_PLIST_PATH,
10
10
  SYSTEM_SERVICE_PATH,
11
11
  USER_SYSTEMD_UNIT
12
- } from "./chunk-HCYQRME2.js";
13
- import "./chunk-DVN6DNMI.js";
14
- import "./chunk-RSBL3FAD.js";
15
- import "./chunk-P4LHVRNE.js";
12
+ } from "./chunk-6NLW72HP.js";
13
+ import "./chunk-M77B73VV.js";
14
+ import "./chunk-H6X6CKDN.js";
15
+ import "./chunk-2RNMBXD2.js";
16
16
  import "./chunk-K3NQKI34.js";
17
17
 
18
18
  // packages/cli/src/commands/service.ts
@@ -3,11 +3,11 @@ import {
3
3
  generateUserPlist,
4
4
  generateUserUnit,
5
5
  installUserService
6
- } from "./chunk-4B62E4CG.js";
7
- import "./chunk-HCYQRME2.js";
8
- import "./chunk-DVN6DNMI.js";
9
- import "./chunk-RSBL3FAD.js";
10
- import "./chunk-P4LHVRNE.js";
6
+ } from "./chunk-OXWUEU5V.js";
7
+ import "./chunk-6NLW72HP.js";
8
+ import "./chunk-M77B73VV.js";
9
+ import "./chunk-H6X6CKDN.js";
10
+ import "./chunk-2RNMBXD2.js";
11
11
  import "./chunk-K3NQKI34.js";
12
12
  export {
13
13
  generateUserPlist,
@@ -8,22 +8,21 @@ import {
8
8
  import "./chunk-O7IGP7ZW.js";
9
9
  import {
10
10
  installUserService
11
- } from "./chunk-4B62E4CG.js";
11
+ } from "./chunk-OXWUEU5V.js";
12
12
  import {
13
13
  LAUNCHD_PLIST_LABEL,
14
14
  SYSTEM_LAUNCHD_PLIST_PATH,
15
15
  SYSTEM_SERVICE_PATH
16
- } from "./chunk-HCYQRME2.js";
16
+ } from "./chunk-6NLW72HP.js";
17
17
  import {
18
18
  ensureVoluteGroup,
19
19
  resolveVoluteBin
20
- } from "./chunk-DVN6DNMI.js";
20
+ } from "./chunk-M77B73VV.js";
21
21
  import {
22
22
  readGlobalConfig,
23
23
  writeGlobalConfig
24
- } from "./chunk-NJHN6IRB.js";
25
- import "./chunk-RSBL3FAD.js";
26
- import "./chunk-P4LHVRNE.js";
24
+ } from "./chunk-H6X6CKDN.js";
25
+ import "./chunk-2RNMBXD2.js";
27
26
  import "./chunk-K3NQKI34.js";
28
27
 
29
28
  // src/commands/setup.ts
@@ -221,7 +220,7 @@ async function startDaemonAndOpenBrowser(port, host) {
221
220
  const url = `http://${displayHost === "0.0.0.0" || displayHost === "::" ? "localhost" : displayHost}:${displayPort}`;
222
221
  console.log("\nStarting daemon...");
223
222
  try {
224
- const { run: runUp } = await import("./up-SDLTLPAO.js");
223
+ const { run: runUp } = await import("./up-J7XCAH7P.js");
225
224
  await runUp([
226
225
  ...port != null ? ["--port", String(port)] : [],
227
226
  ...host ? ["--host", host] : []
@@ -1,30 +1,37 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  _resetConfigCache,
4
+ computeSetupStatus,
4
5
  configPath,
6
+ getSpiritName,
7
+ getSystemName,
5
8
  isImagegenEnabled,
6
9
  isSetupComplete,
7
10
  migrateConfigSecrets,
8
11
  migrateSetupCompleted,
9
12
  mindLimitError,
10
13
  readGlobalConfig,
14
+ readGlobalConfigStrict,
11
15
  secretsPath,
12
16
  setupStatus,
13
17
  setupUrl,
14
18
  writeGlobalConfig
15
- } from "./chunk-NJHN6IRB.js";
16
- import "./chunk-RSBL3FAD.js";
17
- import "./chunk-P4LHVRNE.js";
19
+ } from "./chunk-H6X6CKDN.js";
20
+ import "./chunk-2RNMBXD2.js";
18
21
  import "./chunk-K3NQKI34.js";
19
22
  export {
20
23
  _resetConfigCache,
24
+ computeSetupStatus,
21
25
  configPath,
26
+ getSpiritName,
27
+ getSystemName,
22
28
  isImagegenEnabled,
23
29
  isSetupComplete,
24
30
  migrateConfigSecrets,
25
31
  migrateSetupCompleted,
26
32
  mindLimitError,
27
33
  readGlobalConfig,
34
+ readGlobalConfigStrict,
28
35
  secretsPath,
29
36
  setupStatus,
30
37
  setupUrl,
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  isCompact
4
- } from "./chunk-5T5YMX6S.js";
4
+ } from "./chunk-7YJY3F2R.js";
5
5
  import {
6
6
  resolveMindName
7
7
  } from "./chunk-BTY4WNFE.js";
8
8
  import {
9
9
  daemonFetch
10
- } from "./chunk-BCG45AQB.js";
10
+ } from "./chunk-M74I3HHF.js";
11
11
  import {
12
12
  getClient,
13
13
  urlOf
@@ -17,6 +17,7 @@ import {
17
17
  subcommands
18
18
  } from "./chunk-TXSA4Q3V.js";
19
19
  import "./chunk-O7IGP7ZW.js";
20
+ import "./chunk-FNJCBRD3.js";
20
21
  import "./chunk-K3NQKI34.js";
21
22
 
22
23
  // packages/cli/src/commands/skill.ts
@@ -26,14 +26,14 @@ Add to `.config/volute.json` under `schedules`:
26
26
  "cron": "0 3 * * *",
27
27
  "message": "it's 3am. you are dreaming.\n\ngather your material — read your latest journal entry, read MEMORY.md, surface random memories if you have a way to. then construct a dream premise from that material and invoke the dreamer subagent to experience the dream.",
28
28
  "enabled": true,
29
- "session": "$new"
29
+ "thread": "$new"
30
30
  }
31
31
  ```
32
32
 
33
33
  Or via CLI:
34
34
 
35
35
  ```bash
36
- volute clock add --mind <name> --id dream --cron "0 3 * * *" --session "$new" --while-sleeping trigger-wake --message "it's 3am. you are dreaming...."
36
+ volute clock add --mind <name> --id dream --cron "0 3 * * *" --thread "$new" --while-sleeping trigger-wake --message "it's 3am. you are dreaming...."
37
37
  ```
38
38
 
39
39
  ## 3. Sleep integration
@@ -1,15 +1,25 @@
1
1
  ---
2
2
  name: Image Generation
3
- description: Generate images via Replicate or OpenRouter. Use for "generate image", "create image", "image generation", "text to image", "search image models".
3
+ description: Generate images via Replicate, OpenRouter, a ChatGPT subscription (openai-codex), or xAI Grok. Use for "generate image", "create image", "image generation", "text to image", "search image models".
4
4
  metadata:
5
5
  bin: scripts/imagegen.ts
6
6
  ---
7
7
 
8
8
  # Image Generation
9
9
 
10
- Generate images from text prompts using models on Replicate or OpenRouter. Images are saved to `home/images/`.
10
+ Generate images from text prompts. Images are saved to `home/images/`.
11
11
 
12
- Model IDs are provider-prefixed: `replicate:owner/model` or `openrouter:owner/model`.
12
+ Model IDs are provider-prefixed, e.g. `replicate:owner/model`, `openrouter:owner/model`, `openai-codex:gpt-image-2`, or `xai:grok-imagine-image`. Which providers are available depends on what your host has configured.
13
+
14
+ ## Generation is asynchronous
15
+
16
+ `generate` waits up to ~30 seconds for the image. Fast models finish in that window and print `saved: <path>` right away. Slower models (e.g. `gpt-image-2`) keep going **in the background**: the command returns immediately with
17
+
18
+ ```
19
+ still generating (job <id>) — I'll be notified when it's done. Check anytime: imagegen status <id>
20
+ ```
21
+
22
+ You don't have to wait or poll — when a background image finishes, you're notified automatically with an `image ready: <path>` event. You can also run `imagegen status <id>` yourself to check.
13
23
 
14
24
  ## Commands
15
25
 
@@ -19,7 +29,8 @@ imagegen <command>
19
29
 
20
30
  | Command | Description |
21
31
  |---------|-------------|
22
- | `generate "prompt" [--model M] [--filename F]` | Generate an image from a text prompt. Default model: `replicate:prunaai/z-image-turbo`. |
32
+ | `generate "prompt" [--model M] [--filename F]` | Generate an image. Returns `saved: <path>` if it finishes quickly, otherwise a job id to check later. Default model: `replicate:prunaai/z-image-turbo`. |
33
+ | `status <jobId>` | Check a background generation job. Prints `saved: <path>`, `still generating`, or `failed: <reason>`. |
23
34
  | `models "query"` | Search configured providers for text-to-image models. |
24
35
 
25
36
  ## Examples
@@ -37,6 +48,12 @@ imagegen generate "a mountain landscape" --model openrouter:openai/gpt-image-1
37
48
  # Specify a filename
38
49
  imagegen generate "mountain landscape" --filename mountains
39
50
 
51
+ # Generate with a ChatGPT subscription (if your host configured openai-codex)
52
+ imagegen generate "a friendly robot mascot" --model openai-codex:gpt-image-2
53
+
54
+ # Check a background job you started earlier
55
+ imagegen status 6f1e2c34-...
56
+
40
57
  # Search for models
41
58
  imagegen models "text to image"
42
59
  ```