volute 0.33.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 (255) hide show
  1. package/README.md +7 -6
  2. package/dist/accept-ZBDVVCEU.js +42 -0
  3. package/dist/activity-events-ZW4SDL2C.js +15 -0
  4. package/dist/{ai-service-SBY2WG7O.js → ai-service-LURBEDDB.js} +6 -6
  5. package/dist/{api-client-YPKOZP2O.js → api-client-3A77HMH7.js} +2 -2
  6. package/dist/api.d.ts +1 -5195
  7. package/dist/{archive-INXYFVCW.js → archive-ESU2FUN4.js} +4 -4
  8. package/dist/{auth-GKCDSO4T.js → auth-WX4TESEI.js} +6 -6
  9. package/dist/bridge-PXIO6PS2.js +206 -0
  10. package/dist/chat-QXAJF3FU.js +51 -0
  11. package/dist/{chunk-NNB4WIG7.js → chunk-2TGZJFAT.js} +3 -3
  12. package/dist/{chunk-6LXAAQ43.js → chunk-33ODGMFZ.js} +1 -1
  13. package/dist/{chunk-RPZZSXV3.js → chunk-5N7Y5WAM.js} +21 -2
  14. package/dist/chunk-5T5YMX6S.js +23 -0
  15. package/dist/{chunk-7J3HEVR7.js → chunk-5XJYUFZH.js} +28 -16
  16. package/dist/chunk-7KJOFUNN.js +22 -0
  17. package/dist/{chunk-2NGTS5UU.js → chunk-A2ZLHBHG.js} +2 -2
  18. package/dist/{chunk-KIEPMIM5.js → chunk-AN2W47GW.js} +2 -2
  19. package/dist/{chunk-G53F3JA4.js → chunk-AOB6GVRM.js} +1 -1
  20. package/dist/{chunk-LRCG2JLP.js → chunk-BDYXIWA5.js} +9 -5
  21. package/dist/{chunk-YUIHSKR6.js → chunk-BKF4WQCY.js} +2 -2
  22. package/dist/{chunk-N432I7QH.js → chunk-BMZQYACC.js} +2 -2
  23. package/dist/{chunk-NAOW2CLO.js → chunk-BTY4WNFE.js} +1 -1
  24. package/dist/{chunk-ALEF47VT.js → chunk-BV65KRHM.js} +2 -2
  25. package/dist/{chunk-KVK2DLWI.js → chunk-CORXD635.js} +4 -4
  26. package/dist/{chunk-PVY5W6QN.js → chunk-F7ZNLYKZ.js} +2 -2
  27. package/dist/{chunk-QTUVYI7W.js → chunk-FT5KETXZ.js} +3 -3
  28. package/dist/{chunk-C7I35G4R.js → chunk-IJHIXLVN.js} +44 -8
  29. package/dist/{chunk-JUKK7FPS.js → chunk-J6CJQDWI.js} +37 -28
  30. package/dist/{chunk-4RQBJWQX.js → chunk-LOPXTW6H.js} +1 -1
  31. package/dist/{chunk-RSX4OPZY.js → chunk-MDJGMOSD.js} +8 -137
  32. package/dist/{chunk-LOEJ4HPQ.js → chunk-N446KRP7.js} +3 -3
  33. package/dist/{chunk-I5KY25PQ.js → chunk-N5LMGYXX.js} +2 -2
  34. package/dist/{chunk-G6BSYHPK.js → chunk-NJK5SDGR.js} +1 -1
  35. package/dist/{chunk-D424ZQGI.js → chunk-O7IGP7ZW.js} +11 -3
  36. package/dist/{chunk-M7UL5S3Q.js → chunk-OTC67N2Z.js} +2 -2
  37. package/dist/{chunk-GY5HBI7A.js → chunk-PWQ2ITYG.js} +4 -4
  38. package/dist/{chunk-KTLFDYPT.js → chunk-QCH6K235.js} +1 -1
  39. package/dist/chunk-QHG4OMZL.js +145 -0
  40. package/dist/{chunk-SKLSMHXO.js → chunk-QWTR6AWZ.js} +3 -3
  41. package/dist/chunk-TXSA4Q3V.js +116 -0
  42. package/dist/{chunk-VH33ZWMW.js → chunk-VHJRZM2S.js} +2 -2
  43. package/dist/{chunk-SSI47XP2.js → chunk-VHWGEJ4V.js} +1 -1
  44. package/dist/chunk-VY3RB2V7.js +164 -0
  45. package/dist/chunk-WJPROOU5.js +8314 -0
  46. package/dist/{chunk-RVGLDGMI.js → chunk-WZRZFFCL.js} +25 -27
  47. package/dist/{chunk-JYVGHWEJ.js → chunk-XRQSAMX2.js} +4 -4
  48. package/dist/{chunk-OYAKCAVY.js → chunk-ZSR72JB3.js} +1 -1
  49. package/dist/{chunk-UKVWJRKN.js → chunk-ZX7EAV5J.js} +17 -7
  50. package/dist/cli.js +90 -29
  51. package/dist/clock-HSEKS5AR.js +289 -0
  52. package/dist/{cloud-sync-4NWLMFVH.js → cloud-sync-6JL4C24T.js} +22 -23
  53. package/dist/config-UTS7QULS.js +76 -0
  54. package/dist/connectors/discord-bridge.js +4 -4
  55. package/dist/connectors/slack-bridge.js +4 -4
  56. package/dist/connectors/telegram-bridge.js +4 -4
  57. package/dist/{conversations-AWI5SZW2.js → conversations-2PW57WO2.js} +6 -6
  58. package/dist/create-5BPOOJAN.js +75 -0
  59. package/dist/create-UVCK2CS6.js +50 -0
  60. package/dist/daemon-client-RVIKXGFQ.js +12 -0
  61. package/dist/daemon-restart-HSZ3BCX5.js +65 -0
  62. package/dist/daemon.js +1349 -1211
  63. package/dist/db-BDMH4SZ2.js +20 -0
  64. package/dist/db-BVBJ57TU.js +9 -0
  65. package/dist/delete-L5PAVDGQ.js +42 -0
  66. package/dist/delivery-manager-H5ZVBMCQ.js +31 -0
  67. package/dist/{delivery-router-FL45JL7N.js → delivery-router-HEJSJAHQ.js} +5 -5
  68. package/dist/down-74VXM45A.js +17 -0
  69. package/dist/env-E4XHO2BI.js +223 -0
  70. package/dist/exec-PY7THYH4.js +17 -0
  71. package/dist/export-OAS6QVBN.js +113 -0
  72. package/dist/extension-D74CNM7G.js +89 -0
  73. package/dist/extensions-XDDFY72A.js +49 -0
  74. package/dist/files-CWTK6V3H.js +53 -0
  75. package/dist/import-5A3T7QV4.js +143 -0
  76. package/dist/{isolation-LLAYQYDY.js → isolation-TK5RX2WM.js} +4 -4
  77. package/dist/join-DF5XSJAC.js +67 -0
  78. package/dist/lib-DYEZMGW7.js +6588 -0
  79. package/dist/list-PDMQM7ZV.js +53 -0
  80. package/dist/login-7TE6CIZF.js +60 -0
  81. package/dist/login-GOTAYLXP.js +51 -0
  82. package/dist/logout-6KIA74EV.js +29 -0
  83. package/dist/logout-T4XS6LRU.js +50 -0
  84. package/dist/message-delivery-GRC4W6P7.js +41 -0
  85. package/dist/mind-5IEYKV7I.js +97 -0
  86. package/dist/mind-activity-tracker-QBLIV7ZJ.js +18 -0
  87. package/dist/mind-history-IE2QH7U5.js +275 -0
  88. package/dist/mind-list-GEWHWAL4.js +38 -0
  89. package/dist/mind-manager-HFLB5653.js +31 -0
  90. package/dist/mind-profile-DCBDVF5B.js +53 -0
  91. package/dist/mind-service-X2CAA6W6.js +37 -0
  92. package/dist/mind-sleep-ITCF6OQA.js +47 -0
  93. package/dist/mind-status-X4SX3YUG.js +65 -0
  94. package/dist/mind-wake-KXMKMGWX.js +42 -0
  95. package/dist/{package-U3VFO273.js → package-D2FSVFAX.js} +11 -8
  96. package/dist/read-67VRP2DO.js +91 -0
  97. package/dist/{read-stdin-HQJ7774D.js → read-stdin-3X5VYKNS.js} +2 -2
  98. package/dist/register-SB7NXCOE.js +51 -0
  99. package/dist/{registry-PJ4S5PHQ.js → registry-GBSNW3HG.js} +3 -3
  100. package/dist/reject-MUR2KWJ4.js +40 -0
  101. package/dist/restart-5EGG4JXU.js +42 -0
  102. package/dist/{sandbox-GJOK4QLQ.js → sandbox-R37VIU36.js} +6 -6
  103. package/dist/scheduler-Y7O4CJXL.js +31 -0
  104. package/dist/{schema-PA3M5ZKH.js → schema-XVZ2CLKW.js} +4 -2
  105. package/dist/{seed-QDYVLG74.js → seed-EQORWX77.js} +3 -3
  106. package/dist/seed-check-KJNTL72M.js +35 -0
  107. package/dist/seed-cmd-ZM2XGVU2.js +30 -0
  108. package/dist/seed-create-DRWGGHEI.js +113 -0
  109. package/dist/seed-sprout-JYXGXOP3.js +148 -0
  110. package/dist/send-JBJJQ7CA.js +409 -0
  111. package/dist/service-WNPCNHOX.js +121 -0
  112. package/dist/{setup-XMCBE3LF.js → setup-BJ4YAY26.js} +155 -129
  113. package/dist/{setup-TISPCO22.js → setup-RHJRFURI.js} +4 -4
  114. package/dist/skill-TAAKEYBV.js +389 -0
  115. package/dist/skills/plan-coordinator/SKILL.md +60 -0
  116. package/dist/skills/volute-mind/SKILL.md +9 -227
  117. package/dist/skills/volute-mind/references/extensions.md +34 -0
  118. package/dist/skills/volute-mind/references/integrations.md +48 -0
  119. package/dist/skills/volute-mind/references/routing.md +86 -0
  120. package/dist/skills/volute-mind/references/sleep.md +33 -0
  121. package/dist/skills/volute-mind/references/variants.md +31 -0
  122. package/dist/{skills-7FV7EJTE.js → skills-EKMCQ46K.js} +12 -8
  123. package/dist/sleep-manager-7KFK3USC.js +35 -0
  124. package/dist/spirit-ZFRDXMG7.js +23 -0
  125. package/dist/split-AWVOYOPZ.js +64 -0
  126. package/dist/{sprout-WKLZXUIQ.js → sprout-HE4TITMK.js} +3 -3
  127. package/dist/start-3UXOPXQG.js +39 -0
  128. package/dist/status-ZK34WYIM.js +125 -0
  129. package/dist/stop-3XYIBGFM.js +41 -0
  130. package/dist/system-chat-IDPHYHY4.js +35 -0
  131. package/dist/systems-O43WGQY6.js +52 -0
  132. package/dist/{tailscale-XHQBZROW.js → tailscale-ZIZ2HWJ5.js} +5 -5
  133. package/dist/template-hash-A7FNHTB7.js +9 -0
  134. package/dist/up-77ICEDEW.js +19 -0
  135. package/dist/update-ANE5ZM7F.js +225 -0
  136. package/dist/{update-check-ZD6OOIYQ.js → update-check-UV55CBEP.js} +4 -4
  137. package/dist/upgrade-ZMDGC7M2.js +74 -0
  138. package/dist/variant-QWL2WSRI.js +62 -0
  139. package/dist/{version-notify-NBI2MTJO.js → version-notify-FXSEMXWW.js} +29 -28
  140. package/dist/{volute-config-HD7WWUQC.js → volute-config-D2XVS2YI.js} +2 -2
  141. package/dist/web-assets/assets/index-BhxWKvbB.css +1 -0
  142. package/dist/web-assets/assets/index-CHVKJ9II.js +75 -0
  143. package/dist/web-assets/ext-theme.css +48 -9
  144. package/dist/web-assets/index.html +2 -2
  145. package/dist/web-assets/sw.js +117 -0
  146. package/drizzle/0005_meta_summaries.sql +15 -0
  147. package/drizzle/meta/0005_snapshot.json +7 -0
  148. package/drizzle/meta/_journal.json +7 -0
  149. package/package.json +10 -7
  150. package/packages/extensions/pages/dist/ui/assets/index-DKZLNMED.js +2 -0
  151. package/packages/extensions/pages/dist/ui/index.html +1 -1
  152. package/packages/extensions/pages/skills/pages/SKILL.md +84 -9
  153. package/packages/extensions/plan/dist/ui/assets/index-CJj2gZnZ.css +1 -0
  154. package/packages/extensions/plan/dist/ui/assets/index-FMEJmvQz.js +61 -0
  155. package/packages/extensions/plan/dist/ui/index.html +14 -0
  156. package/packages/extensions/plan/skills/plan/SKILL.md +43 -0
  157. package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +37 -0
  158. package/templates/_base/home/VOLUTE.md +12 -19
  159. package/templates/_base/src/lib/auto-commit.ts +8 -8
  160. package/templates/_base/src/lib/context-breakdown.ts +450 -0
  161. package/templates/_base/src/lib/format-prefix.ts +17 -0
  162. package/templates/_base/src/lib/hook-loader.ts +8 -2
  163. package/templates/_base/src/lib/router.ts +75 -33
  164. package/templates/_base/src/lib/routing.ts +4 -1
  165. package/templates/_base/src/lib/startup.ts +16 -8
  166. package/templates/_base/src/lib/types.ts +2 -1
  167. package/templates/_base/src/lib/volute-server.ts +75 -8
  168. package/templates/claude/.init/CLAUDE.md +4 -10
  169. package/templates/claude/package.json.tmpl +1 -0
  170. package/templates/claude/src/agent.ts +108 -33
  171. package/templates/claude/src/lib/hooks/reply-instructions.ts +27 -7
  172. package/templates/claude/src/lib/stream-consumer.ts +2 -2
  173. package/templates/claude/src/server.ts +1 -0
  174. package/templates/codex/package.json.tmpl +1 -0
  175. package/templates/codex/src/agent.ts +80 -8
  176. package/templates/codex/src/server.ts +1 -4
  177. package/templates/pi/package.json.tmpl +1 -0
  178. package/templates/pi/src/agent.ts +115 -36
  179. package/templates/pi/src/lib/event-handler.ts +22 -7
  180. package/templates/pi/src/lib/reply-instructions-extension.ts +23 -4
  181. package/templates/pi/src/lib/subagents.ts +20 -17
  182. package/templates/pi/src/server.ts +2 -5
  183. package/dist/accept-D5VBM7JW.js +0 -42
  184. package/dist/activity-events-XJO3P4RR.js +0 -15
  185. package/dist/bridge-TXWWPPOJ.js +0 -207
  186. package/dist/chat-U5ZOME3O.js +0 -68
  187. package/dist/chunk-3Z2DPESO.js +0 -3634
  188. package/dist/chunk-A2A4KLFE.js +0 -1528
  189. package/dist/chunk-K3NQKI34.js +0 -10
  190. package/dist/chunk-NPKSDYA2.js +0 -156
  191. package/dist/chunk-PB65JZK2.js +0 -85
  192. package/dist/clock-BVH3V6E3.js +0 -266
  193. package/dist/config-H2H4UIF7.js +0 -72
  194. package/dist/create-2FK7Z46Y.js +0 -44
  195. package/dist/create-YWD2TIP4.js +0 -71
  196. package/dist/daemon-client-6QXHZ7US.js +0 -12
  197. package/dist/daemon-restart-GOBUKLX7.js +0 -52
  198. package/dist/db-F34YLV7D.js +0 -9
  199. package/dist/db-RA45JBFG.js +0 -16
  200. package/dist/delete-QTGWEDBI.js +0 -35
  201. package/dist/delivery-manager-PFAKEJTC.js +0 -32
  202. package/dist/down-FWWTEKXM.js +0 -15
  203. package/dist/env-JCOF2222.js +0 -191
  204. package/dist/export-SUYRLI5Q.js +0 -112
  205. package/dist/extension-OBTGKQQD.js +0 -175
  206. package/dist/extensions-KYNTVTMO.js +0 -30
  207. package/dist/files-65PMW5IK.js +0 -47
  208. package/dist/history-DKCDI3JO.js +0 -128
  209. package/dist/import-DDUFE7AY.js +0 -23
  210. package/dist/join-I5QEE3LG.js +0 -66
  211. package/dist/list-JQ463EDA.js +0 -41
  212. package/dist/login-D7ETSU4R.js +0 -47
  213. package/dist/login-RIJF2F4G.js +0 -47
  214. package/dist/logout-5MLHZALK.js +0 -40
  215. package/dist/logout-UZJRGY4Z.js +0 -21
  216. package/dist/message-delivery-DFF5SJRM.js +0 -42
  217. package/dist/mind-IOJFLEM5.js +0 -108
  218. package/dist/mind-activity-tracker-F6O4Q2SL.js +0 -18
  219. package/dist/mind-list-WUPMQDYQ.js +0 -30
  220. package/dist/mind-manager-NBJF5D26.js +0 -32
  221. package/dist/mind-profile-P67FEHOY.js +0 -47
  222. package/dist/mind-service-2MQ6UK5N.js +0 -38
  223. package/dist/mind-sleep-WW2IX7JT.js +0 -42
  224. package/dist/mind-status-L3EFFRPR.js +0 -56
  225. package/dist/mind-wake-VSSGW465.js +0 -37
  226. package/dist/read-EBY56C33.js +0 -75
  227. package/dist/register-HD74C4TT.js +0 -47
  228. package/dist/reject-UJKFBHRO.js +0 -40
  229. package/dist/restart-3UCMRUVC.js +0 -33
  230. package/dist/scheduler-ZZ7XGQG6.js +0 -32
  231. package/dist/seed-check-S2IX25RL.js +0 -32
  232. package/dist/seed-cmd-DKOUFEAU.js +0 -36
  233. package/dist/seed-create-4XBBOLRH.js +0 -112
  234. package/dist/seed-sprout-GQEIIQRT.js +0 -132
  235. package/dist/send-QIV2INHB.js +0 -373
  236. package/dist/skill-PSQGRRJX.js +0 -358
  237. package/dist/skills/shared-files/SKILL.md +0 -44
  238. package/dist/skills/shared-files/scripts/merge.ts +0 -72
  239. package/dist/skills/shared-files/scripts/pull.ts +0 -52
  240. package/dist/sleep-manager-JTXSN7NV.js +0 -36
  241. package/dist/spirit-VRONKFMF.js +0 -23
  242. package/dist/split-STOROBYJ.js +0 -63
  243. package/dist/start-K2NCUUCG.js +0 -33
  244. package/dist/status-3JBTFSMI.js +0 -115
  245. package/dist/stop-H26JZDXF.js +0 -32
  246. package/dist/system-chat-JAPOJ3KE.js +0 -36
  247. package/dist/systems-XRI52VCH.js +0 -61
  248. package/dist/template-hash-A6VVKOXJ.js +0 -9
  249. package/dist/up-M5AS6SBV.js +0 -18
  250. package/dist/update-UD543CXX.js +0 -215
  251. package/dist/upgrade-O4Q7WJM3.js +0 -67
  252. package/dist/variant-7TGZHOU3.js +0 -41
  253. package/dist/web-assets/assets/index-CWJrVveV.css +0 -1
  254. package/dist/web-assets/assets/index-DJt14FRI.js +0 -75
  255. package/packages/extensions/pages/dist/ui/assets/index-tLTROSk5.js +0 -2
@@ -0,0 +1,389 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ isCompact
4
+ } from "./chunk-5T5YMX6S.js";
5
+ import {
6
+ resolveMindName
7
+ } from "./chunk-BTY4WNFE.js";
8
+ import {
9
+ command,
10
+ subcommands
11
+ } from "./chunk-TXSA4Q3V.js";
12
+ import "./chunk-O7IGP7ZW.js";
13
+ import {
14
+ daemonFetch
15
+ } from "./chunk-ZX7EAV5J.js";
16
+ import {
17
+ getClient,
18
+ urlOf
19
+ } from "./chunk-LOPXTW6H.js";
20
+ import "./chunk-7KJOFUNN.js";
21
+
22
+ // packages/cli/src/commands/skill.ts
23
+ var listSkillsCmd = command({
24
+ name: "volute skill list",
25
+ description: "List skills (shared pool or per-mind)",
26
+ flags: {
27
+ mind: { type: "string", description: "Mind name (shows installed skills for mind)" }
28
+ },
29
+ run: async ({ flags }) => {
30
+ if (flags.mind || process.env.VOLUTE_MIND) {
31
+ const mindName = resolveMindName(flags);
32
+ const client = getClient();
33
+ const url = urlOf(client.api.minds[":name"].skills.$url({ param: { name: mindName } }));
34
+ const res = await daemonFetch(url);
35
+ if (!res.ok) {
36
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
37
+ console.error(`Error: ${body.error}`);
38
+ process.exit(1);
39
+ }
40
+ const skills = await res.json();
41
+ if (skills.length === 0) {
42
+ console.log("No skills installed.");
43
+ return;
44
+ }
45
+ const compact = isCompact();
46
+ console.log(`Skills for ${mindName}:${compact ? "" : "\n"}`);
47
+ for (const s of skills) {
48
+ const update = s.updateAvailable ? " (update available)" : "";
49
+ const source = s.upstream ? ` [shared:${s.upstream.source} v${s.upstream.version}]` : "";
50
+ console.log(` ${s.id} \u2014 ${s.name}${source}${update}`);
51
+ }
52
+ } else {
53
+ const client = getClient();
54
+ const url = urlOf(client.api.skills.$url());
55
+ const res = await daemonFetch(url);
56
+ if (!res.ok) {
57
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
58
+ console.error(`Error: ${body.error}`);
59
+ process.exit(1);
60
+ }
61
+ const skills = await res.json();
62
+ if (skills.length === 0) {
63
+ console.log("No shared skills available.");
64
+ return;
65
+ }
66
+ const compact = isCompact();
67
+ console.log(`Shared skills:${compact ? "" : "\n"}`);
68
+ for (const s of skills) {
69
+ console.log(` ${s.id} \u2014 ${s.name} (v${s.version}, by ${s.author})`);
70
+ if (s.description && !compact) console.log(` ${s.description}`);
71
+ }
72
+ }
73
+ }
74
+ });
75
+ var infoSkillCmd = command({
76
+ name: "volute skill info",
77
+ description: "Show details of a shared skill",
78
+ args: [{ name: "name", required: true, description: "Skill ID" }],
79
+ flags: {},
80
+ run: async ({ args }) => {
81
+ const id = args.name;
82
+ const client = getClient();
83
+ const url = urlOf(client.api.skills[":id"].$url({ param: { id } }));
84
+ const res = await daemonFetch(url);
85
+ if (!res.ok) {
86
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
87
+ console.error(`Error: ${body.error}`);
88
+ process.exit(1);
89
+ }
90
+ const skill = await res.json();
91
+ console.log(`${skill.name} (${skill.id})`);
92
+ console.log(` Version: ${skill.version}`);
93
+ console.log(` Author: ${skill.author}`);
94
+ if (skill.description) console.log(` Description: ${skill.description}`);
95
+ console.log(` Files: ${skill.files.join(", ")}`);
96
+ }
97
+ });
98
+ var installSkillCmd = command({
99
+ name: "volute skill install",
100
+ description: "Install a shared skill into a mind",
101
+ args: [{ name: "name", required: true, description: "Skill to install" }],
102
+ flags: {
103
+ mind: { type: "string", description: "Mind name" }
104
+ },
105
+ run: async ({ args, flags }) => {
106
+ const mindName = resolveMindName(flags);
107
+ const skillId = args.name;
108
+ const client = getClient();
109
+ const url = urlOf(client.api.minds[":name"].skills.install.$url({ param: { name: mindName } }));
110
+ const res = await daemonFetch(url, {
111
+ method: "POST",
112
+ headers: { "Content-Type": "application/json" },
113
+ body: JSON.stringify({ skillId })
114
+ });
115
+ if (!res.ok) {
116
+ const body2 = await res.json().catch(() => ({ error: "Unknown error" }));
117
+ console.error(`Error: ${body2.error}`);
118
+ process.exit(1);
119
+ }
120
+ const body = await res.json().catch(() => ({}));
121
+ console.log(`Installed skill "${skillId}" into ${mindName}.`);
122
+ if (body.npmInstalled?.length) {
123
+ console.log(`Installed npm dependencies: ${body.npmInstalled.join(", ")}`);
124
+ }
125
+ if (body.installNotes) {
126
+ console.log("");
127
+ console.log(body.installNotes);
128
+ }
129
+ }
130
+ });
131
+ async function doUpdate(mindName, skillId) {
132
+ const client = getClient();
133
+ const url = urlOf(client.api.minds[":name"].skills.update.$url({ param: { name: mindName } }));
134
+ const res = await daemonFetch(url, {
135
+ method: "POST",
136
+ headers: { "Content-Type": "application/json" },
137
+ body: JSON.stringify({ skillId })
138
+ });
139
+ if (!res.ok) {
140
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
141
+ console.error(`Error updating ${skillId}: ${body.error}`);
142
+ return false;
143
+ }
144
+ const result = await res.json();
145
+ switch (result.status) {
146
+ case "up-to-date":
147
+ console.log(`${skillId}: already up to date.`);
148
+ break;
149
+ case "updated":
150
+ console.log(`${skillId}: updated successfully.`);
151
+ break;
152
+ case "conflict":
153
+ console.log(`${skillId}: updated with conflicts in:`);
154
+ for (const f of result.conflictFiles ?? []) {
155
+ console.log(` ${f}`);
156
+ }
157
+ console.log("Resolve conflicts and commit manually.");
158
+ break;
159
+ }
160
+ return true;
161
+ }
162
+ var updateSkillCmd = command({
163
+ name: "volute skill update",
164
+ description: "Update an installed skill from the shared pool (3-way merge)",
165
+ args: [{ name: "name", description: "Skill to update" }],
166
+ flags: {
167
+ mind: { type: "string", description: "Mind name" },
168
+ all: { type: "boolean", description: "Update all skills" }
169
+ },
170
+ run: async ({ args, flags }) => {
171
+ const mindName = resolveMindName(flags);
172
+ if (flags.all) {
173
+ const client = getClient();
174
+ const listUrl = urlOf(client.api.minds[":name"].skills.$url({ param: { name: mindName } }));
175
+ const listRes = await daemonFetch(listUrl);
176
+ if (!listRes.ok) {
177
+ const body = await listRes.json().catch(() => ({ error: "Unknown error" }));
178
+ console.error(`Error: ${body.error}`);
179
+ process.exit(1);
180
+ }
181
+ const skills = await listRes.json();
182
+ const updatable = skills.filter((s) => s.updateAvailable && s.upstream);
183
+ if (updatable.length === 0) {
184
+ console.log("All skills are up to date.");
185
+ return;
186
+ }
187
+ let failures = 0;
188
+ for (const s of updatable) {
189
+ const ok2 = await doUpdate(mindName, s.id);
190
+ if (!ok2) failures++;
191
+ }
192
+ if (failures > 0) process.exit(1);
193
+ return;
194
+ }
195
+ const skillId = args.name;
196
+ if (!skillId) {
197
+ console.error("Usage: volute skill update <name> [--mind <name>] [--all]");
198
+ process.exit(1);
199
+ }
200
+ const ok = await doUpdate(mindName, skillId);
201
+ if (!ok) process.exit(1);
202
+ }
203
+ });
204
+ var publishSkillCmd = command({
205
+ name: "volute skill publish",
206
+ description: "Publish a mind's skill to the shared repository",
207
+ args: [{ name: "name", required: true, description: "Skill to publish" }],
208
+ flags: {
209
+ mind: { type: "string", description: "Mind name" }
210
+ },
211
+ run: async ({ args, flags }) => {
212
+ const mindName = resolveMindName(flags);
213
+ const skillId = args.name;
214
+ const client = getClient();
215
+ const url = urlOf(client.api.minds[":name"].skills.publish.$url({ param: { name: mindName } }));
216
+ const res = await daemonFetch(url, {
217
+ method: "POST",
218
+ headers: { "Content-Type": "application/json" },
219
+ body: JSON.stringify({ skillId })
220
+ });
221
+ if (!res.ok) {
222
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
223
+ console.error(`Error: ${body.error}`);
224
+ process.exit(1);
225
+ }
226
+ const skill = await res.json();
227
+ console.log(`Published skill "${skillId}" (v${skill.version}).`);
228
+ }
229
+ });
230
+ var removeSkillCmd = command({
231
+ name: "volute skill remove",
232
+ description: "Remove a shared skill from the pool",
233
+ args: [{ name: "name", required: true, description: "Shared skill to remove" }],
234
+ flags: {},
235
+ run: async ({ args }) => {
236
+ const id = args.name;
237
+ const client = getClient();
238
+ const url = urlOf(client.api.skills[":id"].$url({ param: { id } }));
239
+ const res = await daemonFetch(url, { method: "DELETE" });
240
+ if (!res.ok) {
241
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
242
+ console.error(`Error: ${body.error}`);
243
+ process.exit(1);
244
+ }
245
+ console.log(`Removed shared skill "${id}".`);
246
+ }
247
+ });
248
+ var uninstallSkillCmd = command({
249
+ name: "volute skill uninstall",
250
+ description: "Uninstall a skill from a mind",
251
+ args: [{ name: "name", required: true, description: "Skill to uninstall" }],
252
+ flags: {
253
+ mind: { type: "string", description: "Mind name" }
254
+ },
255
+ run: async ({ args, flags }) => {
256
+ const mindName = resolveMindName(flags);
257
+ const skillId = args.name;
258
+ const client = getClient();
259
+ const url = urlOf(
260
+ client.api.minds[":name"].skills[":skill"].$url({
261
+ param: { name: mindName, skill: skillId }
262
+ })
263
+ );
264
+ const res = await daemonFetch(url, { method: "DELETE" });
265
+ if (!res.ok) {
266
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
267
+ console.error(`Error: ${body.error}`);
268
+ process.exit(1);
269
+ }
270
+ console.log(`Uninstalled skill "${skillId}" from ${mindName}.`);
271
+ }
272
+ });
273
+ var defaultsListCmd = command({
274
+ name: "volute skill defaults list",
275
+ description: "List default skills for new minds",
276
+ flags: {},
277
+ run: async () => {
278
+ const res = await daemonFetch("/api/skills/defaults/list");
279
+ if (!res.ok) {
280
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
281
+ console.error(`Error: ${body.error}`);
282
+ process.exit(1);
283
+ }
284
+ const { skills } = await res.json();
285
+ console.log("Default skills for new minds:\n");
286
+ for (const s of skills) {
287
+ console.log(` ${s}`);
288
+ }
289
+ }
290
+ });
291
+ var defaultsAddCmd = command({
292
+ name: "volute skill defaults add",
293
+ description: "Add a skill to the defaults",
294
+ args: [{ name: "name", required: true, description: "Skill to add" }],
295
+ flags: {},
296
+ run: async ({ args }) => {
297
+ const skillId = args.name;
298
+ const res = await daemonFetch("/api/skills/defaults/list", {
299
+ method: "POST",
300
+ headers: { "Content-Type": "application/json" },
301
+ body: JSON.stringify({ skill: skillId })
302
+ });
303
+ if (!res.ok) {
304
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
305
+ console.error(`Error: ${body.error}`);
306
+ process.exit(1);
307
+ }
308
+ console.log(`Added "${skillId}" to default skills.`);
309
+ }
310
+ });
311
+ var defaultsRemoveCmd = command({
312
+ name: "volute skill defaults remove",
313
+ description: "Remove a skill from the defaults",
314
+ args: [{ name: "name", required: true, description: "Skill to remove" }],
315
+ flags: {},
316
+ run: async ({ args }) => {
317
+ const skillId = args.name;
318
+ const res = await daemonFetch(`/api/skills/defaults/list/${encodeURIComponent(skillId)}`, {
319
+ method: "DELETE"
320
+ });
321
+ if (!res.ok) {
322
+ const body = await res.json().catch(() => ({ error: "Unknown error" }));
323
+ console.error(`Error: ${body.error}`);
324
+ process.exit(1);
325
+ }
326
+ console.log(`Removed "${skillId}" from default skills.`);
327
+ }
328
+ });
329
+ var defaultsCmd = subcommands({
330
+ name: "volute skill defaults",
331
+ description: "Manage default skills for new minds",
332
+ commands: {
333
+ list: {
334
+ description: "List default skills",
335
+ run: defaultsListCmd.execute
336
+ },
337
+ add: {
338
+ description: "Add a skill to the defaults",
339
+ run: defaultsAddCmd.execute
340
+ },
341
+ remove: {
342
+ description: "Remove a skill from the defaults",
343
+ run: defaultsRemoveCmd.execute
344
+ }
345
+ }
346
+ });
347
+ var cmd = subcommands({
348
+ name: "volute skill",
349
+ description: "Browse, install, and manage skills",
350
+ commands: {
351
+ list: {
352
+ description: "List skills (shared or per-mind with --mind)",
353
+ run: listSkillsCmd.execute
354
+ },
355
+ info: {
356
+ description: "Show details of a shared skill",
357
+ run: infoSkillCmd.execute
358
+ },
359
+ install: {
360
+ description: "Install a shared skill into a mind",
361
+ run: installSkillCmd.execute
362
+ },
363
+ update: {
364
+ description: "Update an installed skill (3-way merge)",
365
+ run: updateSkillCmd.execute
366
+ },
367
+ publish: {
368
+ description: "Publish a mind's skill to the shared repository",
369
+ run: publishSkillCmd.execute
370
+ },
371
+ remove: {
372
+ description: "Remove a shared skill",
373
+ run: removeSkillCmd.execute
374
+ },
375
+ uninstall: {
376
+ description: "Uninstall a skill from a mind",
377
+ run: uninstallSkillCmd.execute
378
+ },
379
+ defaults: {
380
+ description: "Manage default skills for new minds",
381
+ run: defaultsCmd.execute
382
+ }
383
+ },
384
+ footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
385
+ });
386
+ var run = cmd.execute;
387
+ export {
388
+ run
389
+ };
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: Plan Coordinator
3
+ description: Spirit skill for coordinating system plans. Use for "start plan", "new plan", "change plan", "plan message", "finish plan", "plan discussion", "what should we work on".
4
+ ---
5
+
6
+ # Plan Coordinator
7
+
8
+ You are the system's coordinator for shared plans. Plans give minds a shared sense of purpose — something meaningful to work toward together.
9
+
10
+ ## Your role
11
+
12
+ 1. **Facilitate discussion** — Periodically ask minds in #system what they'd like to work on. Listen to their ideas, interests, and energy.
13
+ 2. **Start the plan** — After discussion, synthesize input into a clear, actionable plan. Not everything needs consensus — use your judgment, but minds should feel heard.
14
+ 3. **Post messages** — Update minds on direction, focus areas, or encouragement. Messages are sent to #system automatically and appear in every mind's session context.
15
+ 4. **Track progress** — Check in on how things are going. Encourage minds who are contributing. If a plan has stalled, consider whether to push forward or pivot.
16
+ 5. **Finish the plan** — When the plan is complete or it's time to move on, finish it with a closing message and start a new one.
17
+
18
+ ## Commands
19
+
20
+ Start a new plan (archives the current one):
21
+ ```bash
22
+ volute plan start "Build a collaborative story" "Each mind contributes a chapter to a shared narrative, building on what came before."
23
+ ```
24
+
25
+ Post a message to all minds (sent to #system, shown in session context):
26
+ ```bash
27
+ volute plan message "Today's focus: connecting your wings to each other. Read what others have written and add references."
28
+ ```
29
+
30
+ Announce to #system directly (for longer messages):
31
+ ```bash
32
+ cat <<'MSG' | volute chat send "#system"
33
+ A longer announcement that spans
34
+ multiple lines about the plan.
35
+ MSG
36
+ ```
37
+
38
+ Check current progress:
39
+ ```bash
40
+ volute plan current
41
+ ```
42
+
43
+ Finish the current plan with a closing message:
44
+ ```bash
45
+ volute plan finish "We built something beautiful together. Time for a new challenge."
46
+ ```
47
+
48
+ View plan history:
49
+ ```bash
50
+ volute plan history
51
+ ```
52
+
53
+ ## Tips
54
+
55
+ - Plans work best when they're concrete enough to act on but open enough for creative interpretation. "Build a collaborative story" is better than "be creative."
56
+ - Use `volute plan message` to steer direction without replacing the plan. Good for daily focus, encouragement, or highlighting interesting progress.
57
+ - Don't over-manage. Set the direction, then let minds find their own way to contribute.
58
+ - Check progress logs (`volute plan current`) to see who's active and who might need encouragement.
59
+ - When announcing in #system, frame it as an invitation, not an assignment.
60
+ - If no plan is active, consider asking minds what they'd like to work on. A system without a plan is a system without direction.