volute 0.34.0 → 0.35.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 (209) hide show
  1. package/README.md +7 -6
  2. package/dist/accept-ZBDVVCEU.js +42 -0
  3. package/dist/{activity-events-BN7V6KCC.js → activity-events-ZW4SDL2C.js} +4 -4
  4. package/dist/{ai-service-PSILB5WD.js → ai-service-LURBEDDB.js} +5 -5
  5. package/dist/{api-client-XUXOB7LI.js → api-client-3A77HMH7.js} +1 -1
  6. package/dist/api.d.ts +1 -5618
  7. package/dist/{archive-C2VEMQOR.js → archive-ESU2FUN4.js} +3 -3
  8. package/dist/{auth-ZFZXJZDQ.js → auth-WX4TESEI.js} +5 -5
  9. package/dist/bridge-PXIO6PS2.js +206 -0
  10. package/dist/chat-QXAJF3FU.js +51 -0
  11. package/dist/{chunk-7F2SW2KD.js → chunk-2TGZJFAT.js} +3 -3
  12. package/dist/{chunk-6LXAAQ43.js → chunk-33ODGMFZ.js} +1 -1
  13. package/dist/{chunk-4JSR7YO7.js → chunk-5N7Y5WAM.js} +1 -1
  14. package/dist/{chunk-FYCALD4Q.js → chunk-5T5YMX6S.js} +1 -1
  15. package/dist/{chunk-B2BVAIZ4.js → chunk-5XJYUFZH.js} +21 -15
  16. package/dist/{chunk-M3K5AARV.js → chunk-A2ZLHBHG.js} +2 -2
  17. package/dist/{chunk-U5BTYSAL.js → chunk-AN2W47GW.js} +2 -2
  18. package/dist/{chunk-G53F3JA4.js → chunk-AOB6GVRM.js} +1 -1
  19. package/dist/{chunk-N7BLAHNE.js → chunk-BDYXIWA5.js} +5 -5
  20. package/dist/{chunk-YUIHSKR6.js → chunk-BKF4WQCY.js} +2 -2
  21. package/dist/{chunk-6OWJXUAR.js → chunk-BMZQYACC.js} +2 -2
  22. package/dist/{chunk-NAOW2CLO.js → chunk-BTY4WNFE.js} +1 -1
  23. package/dist/{chunk-MLOQKQNB.js → chunk-BV65KRHM.js} +2 -2
  24. package/dist/{chunk-XWXBJQBE.js → chunk-CORXD635.js} +4 -4
  25. package/dist/{chunk-PVY5W6QN.js → chunk-F7ZNLYKZ.js} +2 -2
  26. package/dist/{chunk-BFWHBQK4.js → chunk-FT5KETXZ.js} +3 -3
  27. package/dist/{chunk-N3DNFPVA.js → chunk-IJHIXLVN.js} +8 -8
  28. package/dist/{chunk-V6ZCNULL.js → chunk-J6CJQDWI.js} +37 -28
  29. package/dist/{chunk-4RQBJWQX.js → chunk-LOPXTW6H.js} +1 -1
  30. package/dist/{chunk-47ZPNLF4.js → chunk-MDJGMOSD.js} +8 -137
  31. package/dist/{chunk-BTWAGDV5.js → chunk-N446KRP7.js} +3 -3
  32. package/dist/{chunk-6WAWMWR5.js → chunk-N5LMGYXX.js} +2 -2
  33. package/dist/{chunk-G6BSYHPK.js → chunk-NJK5SDGR.js} +1 -1
  34. package/dist/{chunk-D424ZQGI.js → chunk-O7IGP7ZW.js} +11 -3
  35. package/dist/{chunk-2IOP6PHB.js → chunk-OTC67N2Z.js} +2 -2
  36. package/dist/{chunk-V45JXOWY.js → chunk-PWQ2ITYG.js} +4 -4
  37. package/dist/{chunk-KTLFDYPT.js → chunk-QCH6K235.js} +1 -1
  38. package/dist/chunk-QHG4OMZL.js +145 -0
  39. package/dist/{chunk-IS7WJ56Q.js → chunk-QWTR6AWZ.js} +3 -3
  40. package/dist/chunk-TXSA4Q3V.js +116 -0
  41. package/dist/{chunk-BDK73LK6.js → chunk-VHJRZM2S.js} +2 -2
  42. package/dist/{chunk-SSI47XP2.js → chunk-VHWGEJ4V.js} +1 -1
  43. package/dist/chunk-VY3RB2V7.js +164 -0
  44. package/dist/chunk-WJPROOU5.js +8314 -0
  45. package/dist/{chunk-E5C7OWZ2.js → chunk-WZRZFFCL.js} +8 -8
  46. package/dist/{chunk-BM474GX6.js → chunk-XRQSAMX2.js} +4 -4
  47. package/dist/{chunk-OYAKCAVY.js → chunk-ZSR72JB3.js} +1 -1
  48. package/dist/{chunk-PLDWHR4D.js → chunk-ZX7EAV5J.js} +17 -7
  49. package/dist/cli.js +90 -29
  50. package/dist/clock-HSEKS5AR.js +289 -0
  51. package/dist/{cloud-sync-TG3TIX5H.js → cloud-sync-6JL4C24T.js} +21 -22
  52. package/dist/config-UTS7QULS.js +76 -0
  53. package/dist/connectors/discord-bridge.js +3 -3
  54. package/dist/connectors/slack-bridge.js +3 -3
  55. package/dist/connectors/telegram-bridge.js +3 -3
  56. package/dist/{conversations-HL2JP5GI.js → conversations-2PW57WO2.js} +5 -5
  57. package/dist/create-5BPOOJAN.js +75 -0
  58. package/dist/create-UVCK2CS6.js +50 -0
  59. package/dist/daemon-client-RVIKXGFQ.js +12 -0
  60. package/dist/daemon-restart-HSZ3BCX5.js +65 -0
  61. package/dist/daemon.js +845 -1766
  62. package/dist/{db-PLEDCBHZ.js → db-BDMH4SZ2.js} +7 -3
  63. package/dist/{db-RYX3SS2W.js → db-BVBJ57TU.js} +2 -2
  64. package/dist/delete-L5PAVDGQ.js +42 -0
  65. package/dist/delivery-manager-H5ZVBMCQ.js +31 -0
  66. package/dist/{delivery-router-D5ELDMS2.js → delivery-router-HEJSJAHQ.js} +4 -4
  67. package/dist/down-74VXM45A.js +17 -0
  68. package/dist/env-E4XHO2BI.js +223 -0
  69. package/dist/{exec-DVLXKRIO.js → exec-PY7THYH4.js} +4 -4
  70. package/dist/export-OAS6QVBN.js +113 -0
  71. package/dist/{extension-PM42QCID.js → extension-D74CNM7G.js} +25 -33
  72. package/dist/{extensions-BBGVL5JC.js → extensions-XDDFY72A.js} +22 -11
  73. package/dist/files-CWTK6V3H.js +53 -0
  74. package/dist/import-5A3T7QV4.js +143 -0
  75. package/dist/{isolation-62MKDZN3.js → isolation-TK5RX2WM.js} +3 -3
  76. package/dist/join-DF5XSJAC.js +67 -0
  77. package/dist/list-PDMQM7ZV.js +53 -0
  78. package/dist/login-7TE6CIZF.js +60 -0
  79. package/dist/login-GOTAYLXP.js +51 -0
  80. package/dist/logout-6KIA74EV.js +29 -0
  81. package/dist/logout-T4XS6LRU.js +50 -0
  82. package/dist/message-delivery-GRC4W6P7.js +41 -0
  83. package/dist/mind-5IEYKV7I.js +97 -0
  84. package/dist/{mind-activity-tracker-2ACNHA7B.js → mind-activity-tracker-QBLIV7ZJ.js} +5 -5
  85. package/dist/{mind-history-WOYFLQAI.js → mind-history-IE2QH7U5.js} +82 -71
  86. package/dist/mind-list-GEWHWAL4.js +38 -0
  87. package/dist/mind-manager-HFLB5653.js +31 -0
  88. package/dist/mind-profile-DCBDVF5B.js +53 -0
  89. package/dist/mind-service-X2CAA6W6.js +37 -0
  90. package/dist/mind-sleep-ITCF6OQA.js +47 -0
  91. package/dist/mind-status-X4SX3YUG.js +65 -0
  92. package/dist/mind-wake-KXMKMGWX.js +42 -0
  93. package/dist/{package-V2WHWVG6.js → package-D2FSVFAX.js} +5 -5
  94. package/dist/read-67VRP2DO.js +91 -0
  95. package/dist/{read-stdin-PIRM6A2Y.js → read-stdin-3X5VYKNS.js} +1 -1
  96. package/dist/register-SB7NXCOE.js +51 -0
  97. package/dist/{registry-UYV5S6QT.js → registry-GBSNW3HG.js} +2 -2
  98. package/dist/reject-MUR2KWJ4.js +40 -0
  99. package/dist/restart-5EGG4JXU.js +42 -0
  100. package/dist/{sandbox-SI5HMBP3.js → sandbox-R37VIU36.js} +5 -5
  101. package/dist/scheduler-Y7O4CJXL.js +31 -0
  102. package/dist/{schema-ETMABTW4.js → schema-XVZ2CLKW.js} +1 -1
  103. package/dist/{seed-WNGI6PNW.js → seed-EQORWX77.js} +2 -2
  104. package/dist/seed-check-KJNTL72M.js +35 -0
  105. package/dist/seed-cmd-ZM2XGVU2.js +30 -0
  106. package/dist/seed-create-DRWGGHEI.js +113 -0
  107. package/dist/seed-sprout-JYXGXOP3.js +148 -0
  108. package/dist/send-JBJJQ7CA.js +409 -0
  109. package/dist/service-WNPCNHOX.js +121 -0
  110. package/dist/{setup-Z3DEVWV7.js → setup-BJ4YAY26.js} +153 -127
  111. package/dist/{setup-GGMKENLN.js → setup-RHJRFURI.js} +3 -3
  112. package/dist/skill-TAAKEYBV.js +389 -0
  113. package/dist/skills/volute-mind/SKILL.md +3 -7
  114. package/dist/skills/volute-mind/references/extensions.md +8 -11
  115. package/dist/{skills-Q6VZ2UGD.js → skills-EKMCQ46K.js} +7 -7
  116. package/dist/sleep-manager-7KFK3USC.js +35 -0
  117. package/dist/spirit-ZFRDXMG7.js +23 -0
  118. package/dist/split-AWVOYOPZ.js +64 -0
  119. package/dist/{sprout-E3HJIV2Z.js → sprout-HE4TITMK.js} +2 -2
  120. package/dist/start-3UXOPXQG.js +39 -0
  121. package/dist/status-ZK34WYIM.js +125 -0
  122. package/dist/stop-3XYIBGFM.js +41 -0
  123. package/dist/system-chat-IDPHYHY4.js +35 -0
  124. package/dist/systems-O43WGQY6.js +52 -0
  125. package/dist/{tailscale-ZEUK7GKZ.js → tailscale-ZIZ2HWJ5.js} +4 -4
  126. package/dist/{template-hash-EJRTKE36.js → template-hash-A7FNHTB7.js} +2 -2
  127. package/dist/up-77ICEDEW.js +19 -0
  128. package/dist/update-ANE5ZM7F.js +225 -0
  129. package/dist/{update-check-X3YG4WVP.js → update-check-UV55CBEP.js} +3 -3
  130. package/dist/upgrade-ZMDGC7M2.js +74 -0
  131. package/dist/variant-QWL2WSRI.js +62 -0
  132. package/dist/{version-notify-YCH4UVQ2.js → version-notify-FXSEMXWW.js} +28 -27
  133. package/dist/{volute-config-WBKYJGYQ.js → volute-config-D2XVS2YI.js} +1 -1
  134. package/dist/web-assets/assets/index-BhxWKvbB.css +1 -0
  135. package/dist/web-assets/assets/index-CHVKJ9II.js +75 -0
  136. package/dist/web-assets/index.html +2 -2
  137. package/dist/web-assets/sw.js +117 -0
  138. package/package.json +5 -5
  139. package/packages/extensions/pages/dist/ui/assets/index-DKZLNMED.js +2 -0
  140. package/packages/extensions/pages/dist/ui/index.html +1 -1
  141. package/packages/extensions/pages/skills/pages/SKILL.md +84 -9
  142. package/templates/_base/src/lib/auto-commit.ts +8 -8
  143. package/templates/_base/src/lib/volute-server.ts +6 -0
  144. package/templates/claude/src/agent.ts +8 -1
  145. package/dist/accept-TW6V4WI4.js +0 -42
  146. package/dist/bridge-O753D5F4.js +0 -207
  147. package/dist/chat-BHYX7DJ4.js +0 -68
  148. package/dist/chunk-47XDEWWV.js +0 -156
  149. package/dist/chunk-CVL5IGIR.js +0 -2084
  150. package/dist/chunk-PB65JZK2.js +0 -85
  151. package/dist/chunk-TAHX36HZ.js +0 -3679
  152. package/dist/clock-3X4DSC2N.js +0 -281
  153. package/dist/config-OROA5DUA.js +0 -72
  154. package/dist/create-3SEKKI6P.js +0 -71
  155. package/dist/create-UOSOQ2HN.js +0 -44
  156. package/dist/daemon-client-WOAQXXBM.js +0 -12
  157. package/dist/daemon-restart-5ABHNXJZ.js +0 -52
  158. package/dist/delete-KYOVWR23.js +0 -35
  159. package/dist/delivery-manager-2BR5NZKF.js +0 -32
  160. package/dist/down-QVFN4UPK.js +0 -15
  161. package/dist/env-R34DT7XL.js +0 -195
  162. package/dist/export-6ZXAXATG.js +0 -112
  163. package/dist/files-VQV2VZQO.js +0 -47
  164. package/dist/import-MK2I2T6F.js +0 -23
  165. package/dist/join-DGYHTJUH.js +0 -66
  166. package/dist/list-C644WTHV.js +0 -49
  167. package/dist/login-IIGEQPHL.js +0 -47
  168. package/dist/login-KZQLMAWE.js +0 -47
  169. package/dist/logout-AGTZVRGP.js +0 -40
  170. package/dist/logout-KD6GXIJJ.js +0 -21
  171. package/dist/message-delivery-V3R6NXJP.js +0 -42
  172. package/dist/mind-BI4EPBVZ.js +0 -108
  173. package/dist/mind-list-6VPM7GUQ.js +0 -30
  174. package/dist/mind-manager-MWW3BTS4.js +0 -32
  175. package/dist/mind-profile-WPG42U5Y.js +0 -47
  176. package/dist/mind-service-VIKZJK2M.js +0 -38
  177. package/dist/mind-sleep-XDISJY74.js +0 -42
  178. package/dist/mind-status-7FTZWPZF.js +0 -56
  179. package/dist/mind-wake-KIIKEI3A.js +0 -37
  180. package/dist/read-H5C26YO7.js +0 -85
  181. package/dist/register-J27WP33N.js +0 -47
  182. package/dist/reject-OEANJYIA.js +0 -40
  183. package/dist/restart-V5EGYBJG.js +0 -33
  184. package/dist/scheduler-AGG3L2FO.js +0 -32
  185. package/dist/seed-check-PXTH7YXS.js +0 -32
  186. package/dist/seed-cmd-VENFTGS3.js +0 -36
  187. package/dist/seed-create-663ALOKH.js +0 -112
  188. package/dist/seed-sprout-EH3AGKAI.js +0 -132
  189. package/dist/send-7FUUUZZH.js +0 -386
  190. package/dist/skill-DKNYJS4P.js +0 -362
  191. package/dist/skills/shared-files/SKILL.md +0 -44
  192. package/dist/skills/shared-files/scripts/merge.ts +0 -72
  193. package/dist/skills/shared-files/scripts/pull.ts +0 -52
  194. package/dist/sleep-manager-BJK2ROPX.js +0 -36
  195. package/dist/spirit-4JP4TY4C.js +0 -23
  196. package/dist/split-3YPMS2CL.js +0 -63
  197. package/dist/start-W3TPKX4D.js +0 -33
  198. package/dist/status-4OVFXFEJ.js +0 -115
  199. package/dist/stop-GTT6YWYO.js +0 -32
  200. package/dist/system-channel-DXD2JBOU.js +0 -36
  201. package/dist/system-chat-TYLOL7SX.js +0 -36
  202. package/dist/systems-AYLO727G.js +0 -61
  203. package/dist/up-PA7F2CXE.js +0 -18
  204. package/dist/update-HG4LCUSG.js +0 -215
  205. package/dist/upgrade-YGNIDICG.js +0 -67
  206. package/dist/variant-MZUMRTQO.js +0 -41
  207. package/dist/web-assets/assets/index-DiiwC-CZ.css +0 -1
  208. package/dist/web-assets/assets/index-d6y5b9Ij.js +0 -75
  209. package/packages/extensions/pages/dist/ui/assets/index-tLTROSk5.js +0 -2
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./chunk-7KJOFUNN.js";
3
-
4
- // src/commands/seed-cmd.ts
5
- async function run(args) {
6
- const subcommand = args[0];
7
- switch (subcommand) {
8
- case "create":
9
- await import("./seed-create-663ALOKH.js").then((m) => m.run(args.slice(1)));
10
- break;
11
- case "sprout":
12
- await import("./seed-sprout-EH3AGKAI.js").then((m) => m.run(args.slice(1)));
13
- break;
14
- case "check":
15
- await import("./seed-check-PXTH7YXS.js").then((m) => m.run(args.slice(1)));
16
- break;
17
- case "--help":
18
- case "-h":
19
- case void 0:
20
- printUsage();
21
- break;
22
- default:
23
- printUsage();
24
- process.exit(1);
25
- }
26
- }
27
- function printUsage() {
28
- console.log(`volute seed \u2014 seed lifecycle
29
-
30
- volute seed create <name> Plant a new seed
31
- volute seed sprout Complete orientation and become a full mind
32
- volute seed check <name> Check seed readiness (used by spirit scheduler)`);
33
- }
34
- export {
35
- run
36
- };
@@ -1,112 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- promptLine
4
- } from "./chunk-SSI47XP2.js";
5
- import {
6
- parseArgs
7
- } from "./chunk-D424ZQGI.js";
8
- import "./chunk-7KJOFUNN.js";
9
-
10
- // src/commands/seed-create.ts
11
- async function chooseModel(daemonFetch) {
12
- const res = await daemonFetch("/api/system/ai/models");
13
- if (!res.ok) {
14
- console.error(`Failed to fetch AI models (HTTP ${res.status}). Is the daemon running?`);
15
- process.exit(1);
16
- }
17
- const models = await res.json();
18
- const enabled = models.filter((m) => m.enabled);
19
- if (enabled.length === 0) return void 0;
20
- console.log("\nAvailable models:");
21
- for (let i = 0; i < enabled.length; i++) {
22
- console.log(` ${i + 1}) ${enabled[i].name} (${enabled[i].provider})`);
23
- }
24
- const answer = await promptLine(`
25
- Choose a model [1-${enabled.length}]: `);
26
- const idx = parseInt(answer, 10) - 1;
27
- if (Number.isNaN(idx) || idx < 0 || idx >= enabled.length) {
28
- console.error("Invalid selection");
29
- process.exit(1);
30
- }
31
- const chosen = enabled[idx];
32
- return `${chosen.provider}:${chosen.id}`;
33
- }
34
- async function run(args) {
35
- const { positional, flags } = parseArgs(args, {
36
- template: { type: "string" },
37
- model: { type: "string" },
38
- description: { type: "string" },
39
- skills: { type: "string" },
40
- "created-by": { type: "string" }
41
- });
42
- const name = positional[0];
43
- if (!name) {
44
- console.error(
45
- "Usage: volute seed create <name> [--template <name>] [--model <model>] [--description <text>] [--skills <list|none>] [--created-by <username>]"
46
- );
47
- process.exit(1);
48
- }
49
- const skills = flags.skills === "none" ? [] : flags.skills ? flags.skills.split(",") : void 0;
50
- const createdBy = flags["created-by"];
51
- const { daemonFetch } = await import("./daemon-client-WOAQXXBM.js");
52
- const { getClient, urlOf } = await import("./api-client-XUXOB7LI.js");
53
- const client = getClient();
54
- let model = flags.model;
55
- let template = flags.template;
56
- if (!template) {
57
- const { resolveTemplate } = await import("./ai-service-PSILB5WD.js");
58
- template = resolveTemplate(model);
59
- }
60
- if (template !== "claude" && !model) {
61
- if (process.env.VOLUTE_MIND || !process.stdin.isTTY) {
62
- const { getSpiritModel } = await import("./spirit-4JP4TY4C.js");
63
- const { qualifyModelId } = await import("./ai-service-PSILB5WD.js");
64
- const spiritModel = getSpiritModel();
65
- if (spiritModel) {
66
- model = template === "pi" ? qualifyModelId(spiritModel) : spiritModel;
67
- }
68
- }
69
- if (!model) {
70
- model = await chooseModel(daemonFetch);
71
- if (!model) {
72
- console.error("No AI models configured. Set up providers in the web dashboard first.");
73
- process.exit(1);
74
- }
75
- }
76
- }
77
- const createRes = await daemonFetch(urlOf(client.api.minds.$url()), {
78
- method: "POST",
79
- headers: { "Content-Type": "application/json" },
80
- body: JSON.stringify({
81
- name,
82
- template,
83
- stage: "seed",
84
- description: flags.description,
85
- model,
86
- skills,
87
- createdBy
88
- })
89
- });
90
- const createData = await createRes.json();
91
- if (!createRes.ok) {
92
- console.error(createData.error ?? "Failed to create mind");
93
- process.exit(1);
94
- }
95
- const startRes = await daemonFetch(
96
- urlOf(client.api.minds[":name"].start.$url({ param: { name } })),
97
- { method: "POST" }
98
- );
99
- if (!startRes.ok) {
100
- const startData = await startRes.json();
101
- console.error(startData.error ?? "Failed to start mind");
102
- process.exit(1);
103
- }
104
- console.log(`
105
- Seeded mind: ${name} (port ${createData.port})`);
106
- console.log(`
107
- Talk to your new mind:`);
108
- console.log(` volute chat send @${name} "hello"`);
109
- }
110
- export {
111
- run
112
- };
@@ -1,132 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- getStandardSkillsWithExtensions
4
- } from "./chunk-N3DNFPVA.js";
5
- import "./chunk-YUIHSKR6.js";
6
- import "./chunk-U5BTYSAL.js";
7
- import "./chunk-BDK73LK6.js";
8
- import "./chunk-6OWJXUAR.js";
9
- import {
10
- findMind,
11
- mindDir
12
- } from "./chunk-N7BLAHNE.js";
13
- import "./chunk-4JSR7YO7.js";
14
- import "./chunk-7KJOFUNN.js";
15
-
16
- // src/commands/seed-sprout.ts
17
- import { existsSync, readFileSync } from "fs";
18
- import { resolve } from "path";
19
- var ORIENTATION_MARKER = "You don't have a soul yet";
20
- async function run(_args) {
21
- const mindName = process.env.VOLUTE_MIND;
22
- if (!mindName) {
23
- console.error("volute seed sprout must be run by a mind (VOLUTE_MIND not set)");
24
- process.exit(1);
25
- }
26
- const entry = await findMind(mindName);
27
- if (!entry) {
28
- console.error(`Unknown mind: ${mindName}`);
29
- process.exit(1);
30
- }
31
- if (entry.stage !== "seed") {
32
- console.error(`${mindName} is not a seed \u2014 already at stage "${entry.stage}"`);
33
- process.exit(1);
34
- }
35
- const dir = mindDir(mindName);
36
- const soulPath = resolve(dir, "home/SOUL.md");
37
- const memoryPath = resolve(dir, "home/MEMORY.md");
38
- if (!existsSync(soulPath)) {
39
- console.error("Write your SOUL.md before sprouting.");
40
- process.exit(1);
41
- }
42
- const soul = readFileSync(soulPath, "utf-8");
43
- if (soul.includes(ORIENTATION_MARKER)) {
44
- console.error(
45
- "Your SOUL.md still contains the orientation template. Write your own identity first."
46
- );
47
- process.exit(1);
48
- }
49
- if (!existsSync(memoryPath)) {
50
- console.error("Write your MEMORY.md before sprouting.");
51
- process.exit(1);
52
- }
53
- const { isImagegenEnabled } = await import("./setup-GGMKENLN.js");
54
- if (isImagegenEnabled()) {
55
- const { readVoluteConfig } = await import("./volute-config-WBKYJGYQ.js");
56
- const config = readVoluteConfig(dir);
57
- const avatarPath = config?.profile?.avatar;
58
- if (!avatarPath || !existsSync(resolve(dir, "home", avatarPath))) {
59
- console.error(
60
- "Generate an avatar before sprouting. Use `imagegen generate` to create one, then `volute mind profile --avatar <path>` to set it."
61
- );
62
- process.exit(1);
63
- }
64
- }
65
- const { daemonFetch } = await import("./daemon-client-WOAQXXBM.js");
66
- const { getClient, urlOf } = await import("./api-client-XUXOB7LI.js");
67
- const { mindSkillsDir } = await import("./skills-Q6VZ2UGD.js");
68
- const client = getClient();
69
- const failedSkills = [];
70
- for (const skillId of getStandardSkillsWithExtensions()) {
71
- const skillDir = resolve(mindSkillsDir(dir), skillId);
72
- if (!existsSync(skillDir)) {
73
- const installRes = await daemonFetch(
74
- urlOf(client.api.minds[":name"].skills.install.$url({ param: { name: mindName } })),
75
- {
76
- method: "POST",
77
- headers: { "Content-Type": "application/json" },
78
- body: JSON.stringify({ skillId })
79
- }
80
- );
81
- if (!installRes.ok) {
82
- const data = await installRes.json().catch(() => ({ error: `HTTP ${installRes.status}` }));
83
- console.error(`Failed to install skill ${skillId}: ${data.error}`);
84
- failedSkills.push(skillId);
85
- }
86
- }
87
- }
88
- const orientationDir = resolve(mindSkillsDir(dir), "orientation");
89
- if (existsSync(orientationDir)) {
90
- const delRes = await daemonFetch(
91
- urlOf(
92
- client.api.minds[":name"].skills[":skill"].$url({
93
- param: { name: mindName, skill: "orientation" }
94
- })
95
- ),
96
- { method: "DELETE" }
97
- );
98
- if (!delRes.ok) {
99
- const data = await delRes.json().catch(() => ({ error: `HTTP ${delRes.status}` }));
100
- console.error(`Failed to uninstall orientation skill: ${data.error}`);
101
- }
102
- }
103
- if (failedSkills.length > 0) {
104
- console.error(`Warning: failed to install skills: ${failedSkills.join(", ")}`);
105
- }
106
- const sproutRes = await daemonFetch(
107
- urlOf(client.api.minds[":name"].sprout.$url({ param: { name: mindName } })),
108
- { method: "POST" }
109
- );
110
- if (!sproutRes.ok) {
111
- const data = await sproutRes.json().catch(() => ({ error: `HTTP ${sproutRes.status}` }));
112
- console.error(data.error ?? "Failed to update stage");
113
- process.exit(1);
114
- }
115
- const res = await daemonFetch(
116
- urlOf(client.api.minds[":name"].restart.$url({ param: { name: mindName } })),
117
- {
118
- method: "POST",
119
- headers: { "Content-Type": "application/json" },
120
- body: JSON.stringify({ context: { type: "sprouted" } })
121
- }
122
- );
123
- if (!res.ok) {
124
- const data = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
125
- console.error(data.error ?? "Failed to restart after sprouting");
126
- process.exit(1);
127
- }
128
- console.log("Sprouted! You now have full mind capabilities.");
129
- }
130
- export {
131
- run
132
- };
@@ -1,386 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- readStdin
4
- } from "./chunk-6LXAAQ43.js";
5
- import {
6
- isCompact
7
- } from "./chunk-FYCALD4Q.js";
8
- import {
9
- getClient,
10
- urlOf
11
- } from "./chunk-4RQBJWQX.js";
12
- import {
13
- formatFileSize
14
- } from "./chunk-MLOQKQNB.js";
15
- import {
16
- parseArgs
17
- } from "./chunk-D424ZQGI.js";
18
- import {
19
- daemonFetch
20
- } from "./chunk-PLDWHR4D.js";
21
- import "./chunk-N7BLAHNE.js";
22
- import "./chunk-4JSR7YO7.js";
23
- import "./chunk-7KJOFUNN.js";
24
-
25
- // src/commands/send.ts
26
- import { existsSync, readFileSync, statSync } from "fs";
27
- import { userInfo } from "os";
28
- import { basename, extname } from "path";
29
-
30
- // src/lib/parse-target.ts
31
- function parseTarget(target) {
32
- const colonIdx = target.indexOf(":");
33
- if (colonIdx !== -1) {
34
- const platform = target.slice(0, colonIdx);
35
- const identifier = target.slice(colonIdx + 1);
36
- return {
37
- platform,
38
- identifier,
39
- uri: target,
40
- isDM: identifier.startsWith("@")
41
- };
42
- }
43
- if (target.startsWith("@")) {
44
- return {
45
- platform: "volute",
46
- identifier: target,
47
- uri: target,
48
- isDM: true
49
- };
50
- }
51
- return {
52
- platform: "volute",
53
- identifier: target,
54
- uri: target,
55
- isDM: false
56
- };
57
- }
58
-
59
- // src/commands/send.ts
60
- async function isMind(name) {
61
- try {
62
- const res = await daemonFetch(`/api/minds/${encodeURIComponent(name)}`);
63
- return res.ok;
64
- } catch {
65
- return false;
66
- }
67
- }
68
- var IMAGE_MEDIA_TYPES = {
69
- ".png": "image/png",
70
- ".jpg": "image/jpeg",
71
- ".jpeg": "image/jpeg",
72
- ".gif": "image/gif",
73
- ".webp": "image/webp"
74
- };
75
- function loadImage(imagePath) {
76
- if (!existsSync(imagePath)) {
77
- console.error(`Image file not found: ${imagePath}`);
78
- process.exit(1);
79
- }
80
- const ext = extname(imagePath).toLowerCase();
81
- const mediaType = IMAGE_MEDIA_TYPES[ext];
82
- if (!mediaType) {
83
- console.error(`Unsupported image format: ${ext} (supported: png, jpg, jpeg, gif, webp)`);
84
- process.exit(1);
85
- }
86
- const data = readFileSync(imagePath).toString("base64");
87
- return { media_type: mediaType, data };
88
- }
89
- async function waitForResponse(mindName, conversationId, timeoutMs) {
90
- const client = getClient();
91
- const eventPath = urlOf(
92
- client.api.minds[":name"].conversations[":id"].events.$url({
93
- param: { name: mindName, id: conversationId }
94
- })
95
- );
96
- const controller = new AbortController();
97
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
98
- let response;
99
- try {
100
- response = await daemonFetch(eventPath, {
101
- signal: controller.signal
102
- });
103
- } catch {
104
- clearTimeout(timeout);
105
- console.error("Could not connect to event stream. Is the mind running?");
106
- process.exit(1);
107
- }
108
- if (!response.body) {
109
- clearTimeout(timeout);
110
- return;
111
- }
112
- const reader = response.body.getReader();
113
- const decoder = new TextDecoder();
114
- let buffer = "";
115
- try {
116
- while (true) {
117
- const { done, value } = await reader.read();
118
- if (done) break;
119
- buffer += decoder.decode(value, { stream: true });
120
- const chunks = buffer.split("\n\n");
121
- buffer = chunks.pop();
122
- for (const chunk of chunks) {
123
- for (const line of chunk.split("\n")) {
124
- if (!line.startsWith("data: ")) continue;
125
- const data = line.slice(6).trim();
126
- if (!data) continue;
127
- let event;
128
- try {
129
- event = JSON.parse(data);
130
- } catch {
131
- continue;
132
- }
133
- if (event.type === "message" && event.senderName === mindName && event.content) {
134
- const text = event.content.filter((b) => b.type === "text" && !!b.text).map((b) => b.text).join("");
135
- if (text) {
136
- process.stdout.write(`${text}
137
- `);
138
- }
139
- return;
140
- }
141
- }
142
- }
143
- }
144
- } catch (err) {
145
- if (err.name === "AbortError") {
146
- console.error(`(timed out after ${timeoutMs / 1e3}s)`);
147
- } else {
148
- throw err;
149
- }
150
- } finally {
151
- clearTimeout(timeout);
152
- reader.cancel().catch(() => {
153
- });
154
- }
155
- }
156
- async function run(args) {
157
- const { positional, flags } = parseArgs(args, {
158
- image: { type: "string" },
159
- file: { type: "string" },
160
- wait: { type: "boolean" },
161
- timeout: { type: "number" },
162
- sender: { type: "string" }
163
- });
164
- const target = positional[0];
165
- const message = positional[1] ?? await readStdin();
166
- const images = flags.image ? [loadImage(flags.image)] : void 0;
167
- if (!target || !message && !images && !flags.file) {
168
- console.error(
169
- 'Usage: volute chat send <target> "<message>" [--image <path>] [--file <path>] [--wait]'
170
- );
171
- console.error(' echo "message" | volute chat send <target>');
172
- console.error("");
173
- console.error("Examples:");
174
- console.error(' volute chat send @other-mind "hello"');
175
- console.error(' volute chat send #animal-chat "hello everyone"');
176
- console.error(' volute chat send @mind "check this out" --image photo.png');
177
- console.error(" volute chat send @mind --image photo.png");
178
- console.error(' volute chat send @mind "check this out" --file notes.txt');
179
- console.error(' volute chat send @mind "hello" --wait');
180
- process.exit(1);
181
- }
182
- if (target === "system" || target === "@system") {
183
- console.error(
184
- `Can't send to system \u2014 system messages are automated.
185
- To reply to a person, use their username from the message prefix (e.g. volute chat send @username "msg").`
186
- );
187
- process.exit(1);
188
- }
189
- if (flags.file) {
190
- const filePath = flags.file;
191
- const parsed2 = parseTarget(target);
192
- const targetName = parsed2.isDM && parsed2.platform === "volute" ? parsed2.identifier.slice(1) : parsed2.identifier;
193
- const mindSelf = process.env.VOLUTE_MIND;
194
- if (mindSelf) {
195
- const res = await daemonFetch(`/api/minds/${encodeURIComponent(mindSelf)}/files/send`, {
196
- method: "POST",
197
- headers: { "Content-Type": "application/json" },
198
- body: JSON.stringify({ targetMind: targetName, filePath })
199
- });
200
- if (!res.ok) {
201
- const data2 = await res.json();
202
- console.error(data2.error ?? `Failed to send file: ${res.status}`);
203
- process.exit(1);
204
- }
205
- const data = await res.json();
206
- console.log(`File staged for ${targetName} (id: ${data.id})`);
207
- } else {
208
- if (!existsSync(filePath)) {
209
- console.error(`File not found: ${filePath}`);
210
- process.exit(1);
211
- }
212
- const stat = statSync(filePath);
213
- const MAX_FILE_SIZE = 50 * 1024 * 1024;
214
- if (stat.size > MAX_FILE_SIZE) {
215
- console.error(
216
- `File too large (${formatFileSize(stat.size)}, max ${formatFileSize(MAX_FILE_SIZE)})`
217
- );
218
- process.exit(1);
219
- }
220
- const content = readFileSync(filePath);
221
- const filename = basename(filePath);
222
- const senderName = flags.sender || userInfo().username;
223
- const res = await daemonFetch(`/api/minds/${encodeURIComponent(targetName)}/files/stage`, {
224
- method: "POST",
225
- headers: { "Content-Type": "application/json" },
226
- body: JSON.stringify({
227
- sender: senderName,
228
- filename,
229
- data: content.toString("base64")
230
- })
231
- });
232
- if (!res.ok) {
233
- const data2 = await res.json();
234
- console.error(data2.error ?? `Failed to stage file: ${res.status}`);
235
- process.exit(1);
236
- }
237
- const data = await res.json();
238
- console.log(`File staged for ${targetName} (id: ${data.id})`);
239
- }
240
- if (!message) return;
241
- }
242
- let parsed = parseTarget(target);
243
- if (!parsed.isDM && parsed.platform === "volute" && await isMind(parsed.identifier)) {
244
- parsed = {
245
- platform: "volute",
246
- identifier: `@${parsed.identifier}`,
247
- uri: `@${parsed.identifier}`,
248
- isDM: true
249
- };
250
- }
251
- const client = getClient();
252
- let waitMindName;
253
- let waitConversationId;
254
- if (parsed.isDM && parsed.platform === "volute") {
255
- const targetName = parsed.identifier.slice(1);
256
- const mindSelf = process.env.VOLUTE_MIND;
257
- const sender = flags.sender || mindSelf || userInfo().username;
258
- const targetIsMind = await isMind(targetName);
259
- waitMindName = targetIsMind ? targetName : void 0;
260
- const contextMind = mindSelf ?? targetName;
261
- const participants = mindSelf ? [targetName] : [sender];
262
- const createRes = await daemonFetch(
263
- urlOf(client.api.minds[":name"].channels.create.$url({ param: { name: contextMind } })),
264
- {
265
- method: "POST",
266
- headers: { "Content-Type": "application/json" },
267
- body: JSON.stringify({ platform: "volute", participants, sender })
268
- }
269
- );
270
- if (!createRes.ok) {
271
- const data = await createRes.json().catch(() => ({ error: "Unknown error" }));
272
- console.error(data.error);
273
- process.exit(1);
274
- }
275
- const { conversationId: convId } = await createRes.json();
276
- if (convId) waitConversationId = convId;
277
- const sendRes = await daemonFetch("/api/v1/chat", {
278
- method: "POST",
279
- headers: { "Content-Type": "application/json" },
280
- body: JSON.stringify({
281
- message: message ?? "",
282
- conversationId: convId,
283
- images,
284
- sender,
285
- targetMind: contextMind
286
- })
287
- });
288
- if (!sendRes.ok) {
289
- const data = await sendRes.json().catch(() => ({ error: "Unknown error" }));
290
- console.error(data.error);
291
- process.exit(1);
292
- }
293
- if (!flags.wait) {
294
- let outboundId;
295
- try {
296
- const resData = await sendRes.json();
297
- outboundId = resData.outboundId;
298
- } catch (err) {
299
- console.error(
300
- `Warning: could not read outboundId from response: ${err.message}`
301
- );
302
- }
303
- if (isCompact()) {
304
- if (outboundId != null) console.log(`[volute:outbound:${outboundId}]`);
305
- } else {
306
- console.log(
307
- `Message sent.${outboundId != null ? `
308
- [volute:outbound:${outboundId}]` : ""}`
309
- );
310
- }
311
- }
312
- } else if (!parsed.isDM && parsed.platform === "volute") {
313
- if (!parsed.identifier.startsWith("#")) {
314
- console.error(
315
- `Mind "${parsed.identifier}" not found.
316
- To send a DM: volute chat send @${parsed.identifier} "..."
317
- To send to channel: volute chat send #${parsed.identifier} "..."`
318
- );
319
- process.exit(1);
320
- }
321
- const channelName = parsed.identifier.slice(1);
322
- const mindSelf = process.env.VOLUTE_MIND;
323
- const sender = flags.sender || mindSelf || userInfo().username;
324
- const channelRes = await daemonFetch(`/api/v1/channels/${encodeURIComponent(channelName)}`);
325
- if (!channelRes.ok) {
326
- console.error(`Channel "${channelName}" not found. Create it first or check the name.`);
327
- process.exit(1);
328
- }
329
- const channelData = await channelRes.json();
330
- const mindParticipant = channelData.participants?.find((p) => p.userType === "mind");
331
- const contextMind = mindSelf ?? mindParticipant?.username;
332
- if (!contextMind) {
333
- console.error("No mind is a member of this channel. A mind must join the channel first.");
334
- process.exit(1);
335
- }
336
- const sendRes = await daemonFetch("/api/v1/chat", {
337
- method: "POST",
338
- headers: { "Content-Type": "application/json" },
339
- body: JSON.stringify({
340
- message: message ?? "",
341
- conversationId: channelData.id,
342
- images,
343
- sender,
344
- targetMind: contextMind
345
- })
346
- });
347
- if (!sendRes.ok) {
348
- const data = await sendRes.json().catch(() => ({ error: "Unknown error" }));
349
- console.error(data.error);
350
- process.exit(1);
351
- }
352
- let outboundId;
353
- try {
354
- const resData = await sendRes.json();
355
- outboundId = resData.outboundId;
356
- } catch (err) {
357
- console.error(`Warning: could not read outboundId from response: ${err.message}`);
358
- }
359
- if (isCompact()) {
360
- if (outboundId != null) console.log(`[volute:outbound:${outboundId}]`);
361
- } else {
362
- console.log(`Message sent.${outboundId != null ? `
363
- [volute:outbound:${outboundId}]` : ""}`);
364
- }
365
- } else {
366
- console.error(
367
- `Direct sends to ${parsed.platform} channels are no longer supported.
368
- Use bridge channel names instead (e.g. volute chat send @mind-name or #channel-name).
369
- See: volute chat bridge --help`
370
- );
371
- process.exit(1);
372
- }
373
- if (flags.wait && waitMindName) {
374
- if (!waitConversationId) {
375
- console.error("--wait requires a volute conversation (DM to a mind)");
376
- process.exit(1);
377
- }
378
- await waitForResponse(waitMindName, waitConversationId, flags.timeout ?? 12e4);
379
- } else if (flags.wait && !waitMindName) {
380
- console.error("--wait is only supported when sending to a mind");
381
- process.exit(1);
382
- }
383
- }
384
- export {
385
- run
386
- };