volute 0.30.1 → 0.32.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 (227) hide show
  1. package/README.md +15 -22
  2. package/dist/{accept-E3PAH3QJ.js → accept-74M7I4RZ.js} +5 -4
  3. package/dist/{activity-events-BKBPPUBP.js → activity-events-HETAODOK.js} +3 -2
  4. package/dist/{ai-service-VAJT5UBS.js → ai-service-ZIPCV3MX.js} +20 -5
  5. package/dist/api.d.ts +341 -397
  6. package/dist/{archive-WWDBWYN2.js → archive-INXYFVCW.js} +3 -2
  7. package/dist/auth-6DMGES3I.js +44 -0
  8. package/dist/{bridge-RO37CUFM.js → bridge-BVCBTGPF.js} +5 -4
  9. package/dist/{chat-TCUNPFGO.js → chat-XT4OBJBU.js} +8 -8
  10. package/dist/{chunk-P7VFDSSG.js → chunk-2FLJ63GU.js} +2 -2
  11. package/dist/{chunk-ZWKTUQEL.js → chunk-2NGTS5UU.js} +1 -1
  12. package/dist/{chunk-JGFRDMR6.js → chunk-ALEF47VT.js} +1 -1
  13. package/dist/{chunk-MDPCSXZ4.js → chunk-D5G5YOPL.js} +163 -15
  14. package/dist/{chunk-VGWJSNHS.js → chunk-G53F3JA4.js} +1 -35
  15. package/dist/{chunk-A6TUJJ3L.js → chunk-G6BSYHPK.js} +2 -2
  16. package/dist/{chunk-DTC6EH5I.js → chunk-I5KY25PQ.js} +1 -9
  17. package/dist/{chunk-NSBFETWP.js → chunk-IYDIE3HG.js} +64 -26
  18. package/dist/{chunk-W5OOPLNP.js → chunk-JJ7W6WSB.js} +3 -3
  19. package/dist/{chunk-G3GBKZGG.js → chunk-LGB6JBHI.js} +54 -2
  20. package/dist/chunk-LRCG2JLP.js +251 -0
  21. package/dist/{chunk-FXHXHI2A.js → chunk-LSGWR54X.js} +3 -6
  22. package/dist/{chunk-S5LR3XYJ.js → chunk-M7UL5S3Q.js} +1 -1
  23. package/dist/chunk-PB65JZK2.js +85 -0
  24. package/dist/chunk-PVY5W6QN.js +41 -0
  25. package/dist/{chunk-QVAQ5454.js → chunk-QBQ424EM.js} +3007 -2126
  26. package/dist/{chunk-P27RV5WM.js → chunk-QZANELPX.js} +6 -2
  27. package/dist/{chunk-FSM45XD5.js → chunk-R7E6CRVQ.js} +1 -1
  28. package/dist/{chunk-HHTXM4JT.js → chunk-RPZZSXV3.js} +39 -195
  29. package/dist/{chunk-UPA6COHU.js → chunk-RSX4OPZY.js} +5 -5
  30. package/dist/{chunk-2C2VXEBB.js → chunk-S6NFERDC.js} +21 -57
  31. package/dist/chunk-SKLSMHXO.js +208 -0
  32. package/dist/{chunk-IKHDUZRH.js → chunk-SX5TKJBZ.js} +2 -2
  33. package/dist/chunk-TDRYEPH4.js +185 -0
  34. package/dist/chunk-TSXLLQZW.js +46 -0
  35. package/dist/{chunk-EFVHR7KH.js → chunk-UKVWJRKN.js} +24 -5
  36. package/dist/{chunk-2NDZC3S7.js → chunk-WKF5FEFK.js} +688 -389
  37. package/dist/cli.js +93 -24
  38. package/dist/{clock-G3ALCMLJ.js → clock-2UOZ6JPU.js} +11 -8
  39. package/dist/{cloud-sync-JV4LJOK3.js → cloud-sync-JN3NWKEM.js} +16 -14
  40. package/dist/config-H2H4UIF7.js +72 -0
  41. package/dist/connectors/discord-bridge.js +1 -1
  42. package/dist/connectors/slack-bridge.js +1 -1
  43. package/dist/connectors/telegram-bridge.js +1 -1
  44. package/dist/{conversations-7KVQV7EZ.js → conversations-3O5O6AS3.js} +8 -7
  45. package/dist/{create-JTLS7GX3.js → create-RNLNCORE.js} +5 -4
  46. package/dist/{create-VQSQHJQW.js → create-WBBYI6V7.js} +6 -2
  47. package/dist/daemon-client-6QXHZ7US.js +12 -0
  48. package/dist/{daemon-restart-4JGBHEJ4.js → daemon-restart-NGFHFAUF.js} +7 -7
  49. package/dist/daemon.js +2446 -1999
  50. package/dist/{db-HMFPIRO2.js → db-F34YLV7D.js} +2 -1
  51. package/dist/db-RA45JBFG.js +16 -0
  52. package/dist/{delete-JESHKE7F.js → delete-QTGWEDBI.js} +1 -1
  53. package/dist/delivery-manager-SDVXFD4W.js +28 -0
  54. package/dist/delivery-router-FL45JL7N.js +21 -0
  55. package/dist/down-TB3ESMNP.js +14 -0
  56. package/dist/{env-CLXXT7M2.js → env-RLYQBOOP.js} +5 -4
  57. package/dist/{export-EGA5M5PB.js → export-SUYRLI5Q.js} +4 -3
  58. package/dist/{extension-WZ4SUPJB.js → extension-FQ5D3NCC.js} +6 -6
  59. package/dist/{extensions-ECO4RPFQ.js → extensions-GDYWQXC4.js} +9 -7
  60. package/dist/{files-4VEJDASH.js → files-EAMPO2SJ.js} +6 -5
  61. package/dist/{history-EJMMLXDO.js → history-FO5PHBQ5.js} +9 -4
  62. package/dist/{import-YCGPMBSI.js → import-DDUFE7AY.js} +4 -3
  63. package/dist/{join-2GBJKZEN.js → join-I5QEE3LG.js} +1 -1
  64. package/dist/{list-Q6O7FGAN.js → list-DW2VRTOZ.js} +5 -4
  65. package/dist/{login-RL6AU2SM.js → login-7CHPW2PN.js} +5 -4
  66. package/dist/{login-RET5WESK.js → login-RIJF2F4G.js} +3 -2
  67. package/dist/{logout-CGAGJN3L.js → logout-5MLHZALK.js} +3 -2
  68. package/dist/{logout-JRPBEMMR.js → logout-UZJRGY4Z.js} +3 -2
  69. package/dist/message-delivery-2FIM7QKO.js +32 -0
  70. package/dist/{mind-LUWRQUQ5.js → mind-2B6M7Y25.js} +18 -18
  71. package/dist/{mind-activity-tracker-VYN2ZZ2M.js → mind-activity-tracker-NZZT2NTT.js} +4 -3
  72. package/dist/{mind-list-V5WW5DUA.js → mind-list-WUPMQDYQ.js} +3 -2
  73. package/dist/mind-manager-BNCMGYXW.js +28 -0
  74. package/dist/mind-service-AV273WT4.js +34 -0
  75. package/dist/{mind-sleep-R6PTNNW4.js → mind-sleep-B7BHJLH7.js} +5 -4
  76. package/dist/{mind-status-I4ISFJ6I.js → mind-status-L3EFFRPR.js} +3 -2
  77. package/dist/{mind-wake-67ZQEWAV.js → mind-wake-GY3RFX7Y.js} +5 -4
  78. package/dist/{package-OYUD4ZJ4.js → package-PK6JUFL3.js} +3 -3
  79. package/dist/read-5AMJRO3D.js +75 -0
  80. package/dist/{register-NZDSTLP3.js → register-V2JZZKFK.js} +5 -4
  81. package/dist/{registry-ODSALQQL.js → registry-PJ4S5PHQ.js} +8 -1
  82. package/dist/{reject-2HZOJEIJ.js → reject-33HEZMZ4.js} +5 -4
  83. package/dist/{restart-QHS3NT64.js → restart-3UCMRUVC.js} +5 -4
  84. package/dist/{sandbox-O5FUSF43.js → sandbox-JANNTX6U.js} +4 -3
  85. package/dist/schema-PA3M5ZKH.js +32 -0
  86. package/dist/seed-ALUQ55FF.js +112 -0
  87. package/dist/{send-OAN3RYYY.js → send-3MI36LEF.js} +58 -69
  88. package/dist/{setup-QMDK5RZX.js → setup-SZIARWI6.js} +5 -4
  89. package/dist/{setup-XJH3E7YM.js → setup-WENLVPVP.js} +9 -9
  90. package/dist/{skill-FZIN4W4Q.js → skill-TUVOTW4Z.js} +5 -4
  91. package/dist/skills/dreaming/SKILL.md +6 -4
  92. package/dist/skills/dreaming/references/INSTALL.md +4 -5
  93. package/dist/skills/dreaming/scripts/dream.ts +5 -27
  94. package/dist/skills/dreaming/scripts/wake-context-dreams.sh +1 -1
  95. package/dist/skills/imagegen/SKILL.md +6 -5
  96. package/dist/skills/imagegen/references/INSTALL.md +1 -1
  97. package/dist/skills/resonance/SKILL.md +4 -1
  98. package/dist/skills/resonance/references/INSTALL.md +2 -2
  99. package/dist/skills/resonance/scripts/resonance-hook.sh +2 -0
  100. package/dist/skills/resonance/scripts/resonance.ts +35 -5
  101. package/dist/skills/volute-admin/SKILL.md +83 -0
  102. package/dist/skills/volute-mind/SKILL.md +12 -12
  103. package/dist/skills-XNZK6P4K.js +61 -0
  104. package/dist/sleep-manager-53DZOWW7.js +32 -0
  105. package/dist/spirit-N4W4UQRH.js +217 -0
  106. package/dist/{split-EXYGGGQN.js → split-STOROBYJ.js} +1 -1
  107. package/dist/{sprout-AXQ6H5DB.js → sprout-L2GFOVF7.js} +9 -8
  108. package/dist/{start-MTOVL6SY.js → start-K2NCUUCG.js} +5 -4
  109. package/dist/{status-ZRO37MWR.js → status-TCUMUO6M.js} +5 -5
  110. package/dist/{stop-OK5WEPVC.js → stop-H26JZDXF.js} +5 -4
  111. package/dist/system-chat-NPYFYZVI.js +32 -0
  112. package/dist/{systems-W3BBMSOZ.js → systems-DHBKVYEY.js} +6 -5
  113. package/dist/{tailscale-BM72RXCJ.js → tailscale-XHQBZROW.js} +2 -1
  114. package/dist/{template-hash-3HOR4UAJ.js → template-hash-A6VVKOXJ.js} +2 -1
  115. package/dist/up-6I6BHRTO.js +17 -0
  116. package/dist/{update-PLPHMMZ2.js → update-QVPRF6GR.js} +5 -5
  117. package/dist/{update-check-CVCN7MF6.js → update-check-ZD6OOIYQ.js} +3 -2
  118. package/dist/{upgrade-I6NPCYUU.js → upgrade-O4Q7WJM3.js} +12 -14
  119. package/dist/{version-notify-2NTWVEHL.js → version-notify-TCKWBZZG.js} +22 -23
  120. package/dist/web-assets/assets/index-Bui7U9Uu.css +1 -0
  121. package/dist/web-assets/assets/index-e36DIo1b.js +73 -0
  122. package/dist/web-assets/ext-theme.css +94 -0
  123. package/dist/web-assets/index.html +2 -2
  124. package/drizzle/0000_baseline.sql +152 -0
  125. package/drizzle/0001_add_conversation_private.sql +1 -0
  126. package/drizzle/0002_turns.sql +21 -0
  127. package/drizzle/0003_turn_feed_links.sql +11 -0
  128. package/drizzle/0004_spirits.sql +5 -0
  129. package/drizzle/meta/0000_snapshot.json +3 -223
  130. package/drizzle/meta/0001_snapshot.json +3 -294
  131. package/drizzle/meta/0002_snapshot.json +3 -335
  132. package/drizzle/meta/0003_snapshot.json +3 -413
  133. package/drizzle/meta/0004_snapshot.json +3 -406
  134. package/drizzle/meta/_journal.json +10 -101
  135. package/package.json +3 -3
  136. package/packages/extensions/notes/dist/ui/assets/index-8jWEv9SA.js +61 -0
  137. package/packages/extensions/notes/dist/ui/assets/index-DkaB7Ytd.css +1 -0
  138. package/packages/extensions/notes/dist/ui/index.html +2 -2
  139. package/packages/extensions/notes/skills/notes/SKILL.md +8 -8
  140. package/packages/extensions/pages/skills/pages/SKILL.md +17 -44
  141. package/templates/_base/.init/.config/hooks/pre-prompt/session-activity.ts +40 -0
  142. package/templates/_base/.init/.local/bin/volute +27 -0
  143. package/templates/_base/.init/.local/hooks/pre-prompt/session-activity.ts +40 -0
  144. package/templates/_base/.init/.local/hooks/startup-context.ts +58 -0
  145. package/templates/_base/home/.config/routes.json +1 -1
  146. package/templates/_base/src/lib/auto-commit.ts +82 -43
  147. package/templates/_base/src/lib/daemon-client.ts +40 -36
  148. package/templates/_base/src/lib/format-prefix.ts +1 -0
  149. package/templates/_base/src/lib/hook-loader.ts +155 -0
  150. package/templates/_base/src/lib/router.ts +17 -1
  151. package/templates/_base/src/lib/startup.ts +17 -12
  152. package/templates/_base/src/lib/transparency.ts +2 -2
  153. package/templates/_base/src/lib/volute-server.ts +2 -5
  154. package/templates/claude/.init/.claude/settings.json +1 -1
  155. package/templates/claude/.init/.config/routes.json +2 -2
  156. package/templates/claude/src/agent.ts +97 -14
  157. package/templates/claude/src/lib/hooks/auto-commit.ts +7 -3
  158. package/templates/claude/src/lib/message-channel.ts +7 -2
  159. package/templates/claude/src/server.ts +0 -9
  160. package/templates/codex/.init/.config/routes.json +11 -0
  161. package/templates/codex/.init/AGENTS.md +29 -0
  162. package/templates/codex/home/.config/config.json.tmpl +7 -0
  163. package/templates/codex/package.json.tmpl +20 -0
  164. package/templates/codex/src/agent.ts +553 -0
  165. package/templates/codex/src/lib/content.ts +16 -0
  166. package/templates/codex/src/lib/session-store.ts +56 -0
  167. package/templates/codex/src/server.ts +59 -0
  168. package/templates/codex/volute-template.json +8 -0
  169. package/templates/pi/.init/.config/routes.json +2 -2
  170. package/templates/pi/package.json.tmpl +1 -1
  171. package/templates/pi/src/agent.ts +63 -9
  172. package/templates/pi/src/lib/event-handler.ts +6 -4
  173. package/templates/pi/src/lib/reply-instructions-extension.ts +32 -11
  174. package/dist/chunk-7D47T4RB.js +0 -84
  175. package/dist/chunk-CVH6Y2YG.js +0 -59
  176. package/dist/chunk-EFP3PE6C.js +0 -232
  177. package/dist/chunk-LIRWLNAK.js +0 -729
  178. package/dist/daemon-client-BCTFGVCZ.js +0 -9
  179. package/dist/down-NGBMGORS.js +0 -14
  180. package/dist/message-delivery-6YMVNOEC.js +0 -28
  181. package/dist/migrate-registry-to-db-FK35IPEH.js +0 -110
  182. package/dist/mind-manager-YFCOIAAX.js +0 -18
  183. package/dist/pages-watcher-Z3PKNROC.js +0 -21
  184. package/dist/read-WQMPTSN2.js +0 -46
  185. package/dist/seed-WUQMPLDM.js +0 -71
  186. package/dist/skills/sessions/SKILL.md +0 -49
  187. package/dist/sleep-manager-O7YQFCV5.js +0 -30
  188. package/dist/up-BXUAIDXB.js +0 -17
  189. package/dist/web-assets/assets/index--kREqKl9.js +0 -72
  190. package/dist/web-assets/assets/index-BXYTG0nJ.css +0 -1
  191. package/drizzle/0000_flaky_mariko_yashida.sql +0 -34
  192. package/drizzle/0001_careless_warpath.sql +0 -12
  193. package/drizzle/0002_wealthy_the_call.sql +0 -6
  194. package/drizzle/0003_clean_ego.sql +0 -12
  195. package/drizzle/0004_magical_silverclaw.sql +0 -1
  196. package/drizzle/0005_rename_agents_to_minds.sql +0 -11
  197. package/drizzle/0006_mind_history.sql +0 -20
  198. package/drizzle/0007_system_prompts.sql +0 -5
  199. package/drizzle/0008_volute_channels.sql +0 -24
  200. package/drizzle/0009_shared_skills.sql +0 -9
  201. package/drizzle/0010_delivery_queue.sql +0 -12
  202. package/drizzle/0011_rename_human_to_brain.sql +0 -1
  203. package/drizzle/0012_activity.sql +0 -11
  204. package/drizzle/0013_user_profiles.sql +0 -3
  205. package/drizzle/0014_conversation_reads.sql +0 -7
  206. package/drizzle/0015_notes.sql +0 -23
  207. package/drizzle/0016_note_reactions_and_replies.sql +0 -15
  208. package/drizzle/0017_minds.sql +0 -16
  209. package/drizzle/meta/0005_snapshot.json +0 -410
  210. package/drizzle/meta/0006_snapshot.json +0 -7
  211. package/drizzle/meta/0007_snapshot.json +0 -7
  212. package/drizzle/meta/0008_snapshot.json +0 -7
  213. package/drizzle/meta/0009_snapshot.json +0 -7
  214. package/drizzle/meta/0010_snapshot.json +0 -7
  215. package/drizzle/meta/0011_snapshot.json +0 -7
  216. package/drizzle/meta/0012_snapshot.json +0 -7
  217. package/drizzle/meta/0013_snapshot.json +0 -7
  218. package/packages/extensions/notes/dist/ui/assets/index-DgawVO5g.css +0 -1
  219. package/packages/extensions/notes/dist/ui/assets/index-qUWoeC4c.js +0 -2
  220. package/packages/extensions/notes/skills/notes/scripts/notes.mjs +0 -185
  221. package/templates/_base/.init/.config/hooks/startup-context.sh +0 -46
  222. package/templates/_base/.init/.config/scripts/session-reader.ts +0 -59
  223. package/templates/_base/home/public/.gitkeep +0 -0
  224. package/templates/_base/src/lib/session-monitor.ts +0 -400
  225. package/templates/claude/src/lib/hooks/session-context.ts +0 -32
  226. package/templates/pi/src/lib/session-context-extension.ts +0 -35
  227. /package/templates/_base/.init/{.config → .local}/hooks/wake-context.sh +0 -0
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ applyInitFiles,
4
+ composeTemplate,
5
+ copyTemplateToDir,
6
+ findTemplatesRoot
7
+ } from "./chunk-G53F3JA4.js";
8
+ import {
9
+ getSharedSkill,
10
+ installSkill
11
+ } from "./chunk-D5G5YOPL.js";
12
+ import {
13
+ qualifyModelId,
14
+ resolveTemplate
15
+ } from "./chunk-IYDIE3HG.js";
16
+ import {
17
+ logger_default
18
+ } from "./chunk-YUIHSKR6.js";
19
+ import {
20
+ exec
21
+ } from "./chunk-LGB6JBHI.js";
22
+ import {
23
+ readGlobalConfig
24
+ } from "./chunk-TSXLLQZW.js";
25
+ import {
26
+ addSpirit,
27
+ findMind,
28
+ nextPort,
29
+ voluteSystemDir
30
+ } from "./chunk-LRCG2JLP.js";
31
+ import "./chunk-RPZZSXV3.js";
32
+ import "./chunk-K3NQKI34.js";
33
+
34
+ // src/lib/spirit.ts
35
+ import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
36
+ import { resolve } from "path";
37
+ var slog = logger_default.child("spirit");
38
+ function spiritDir() {
39
+ return resolve(voluteSystemDir(), "spirit");
40
+ }
41
+ function getSpiritModel() {
42
+ const config = readGlobalConfig();
43
+ return config.spiritModel;
44
+ }
45
+ async function ensureSpiritProject() {
46
+ const existing = await findMind("volute");
47
+ if (existing) return;
48
+ const dir = spiritDir();
49
+ const spiritModel = getSpiritModel();
50
+ const template = resolveTemplate(spiritModel);
51
+ const templatesRoot = findTemplatesRoot();
52
+ const { composedDir, manifest } = composeTemplate(templatesRoot, template);
53
+ try {
54
+ mkdirSync(dir, { recursive: true });
55
+ copyTemplateToDir(composedDir, dir, "volute", manifest);
56
+ applyInitFiles(dir);
57
+ mkdirSync(resolve(dir, ".mind"), { recursive: true });
58
+ const soulPath = resolve(dir, "home/SOUL.md");
59
+ const globalConfig = readGlobalConfig();
60
+ const systemName = globalConfig.name ?? "Volute";
61
+ const soulContent = getSpiritSoul(systemName, globalConfig.description);
62
+ writeFileSync(soulPath, soulContent);
63
+ const routesPath = resolve(dir, "home/.config/routes.json");
64
+ mkdirSync(resolve(dir, "home/.config"), { recursive: true });
65
+ const routesContent = { rules: [{ channel: "*", session: "${channel}" }], default: "main" };
66
+ writeFileSync(routesPath, `${JSON.stringify(routesContent, null, 2)}
67
+ `);
68
+ if (spiritModel) {
69
+ const modelForConfig = template === "pi" ? qualifyModelId(spiritModel) : spiritModel;
70
+ const configPath = resolve(dir, "home/.config/config.json");
71
+ const mindConfig = existsSync(configPath) ? JSON.parse(readFileSync(configPath, "utf-8")) : {};
72
+ mindConfig.model = modelForConfig;
73
+ writeFileSync(configPath, `${JSON.stringify(mindConfig, null, 2)}
74
+ `);
75
+ }
76
+ await exec("npm", ["install", "--ignore-scripts"], { cwd: dir });
77
+ try {
78
+ await exec("git", ["init"], { cwd: dir });
79
+ await exec("git", ["add", "-A"], { cwd: dir });
80
+ await exec("git", ["commit", "-m", "initial spirit"], { cwd: dir });
81
+ } catch (err) {
82
+ slog.warn("git init failed for spirit \u2014 not critical", logger_default.errorData(err));
83
+ }
84
+ const spiritSkills = ["volute-admin", "orientation", "memory"];
85
+ for (const skillId of spiritSkills) {
86
+ try {
87
+ const shared = await getSharedSkill(skillId);
88
+ if (shared) {
89
+ await installSkill("volute", dir, skillId);
90
+ }
91
+ } catch (err) {
92
+ slog.warn(`failed to install skill ${skillId} for spirit`, logger_default.errorData(err));
93
+ }
94
+ }
95
+ const port = await nextPort();
96
+ await addSpirit("volute", port, template, dir);
97
+ slog.info("spirit project created");
98
+ } catch (err) {
99
+ slog.error("failed to create spirit project", logger_default.errorData(err));
100
+ rmSync(dir, { recursive: true, force: true });
101
+ throw err;
102
+ }
103
+ }
104
+ async function syncSpiritTemplate() {
105
+ const entry = await findMind("volute");
106
+ if (!entry || entry.mindType !== "spirit") return;
107
+ const dir = spiritDir();
108
+ if (!existsSync(dir)) return;
109
+ const templatesRoot = findTemplatesRoot();
110
+ const currentModel = getSpiritModel();
111
+ const expectedTemplate = resolveTemplate(currentModel);
112
+ const currentTemplate = entry.template ?? "claude";
113
+ if (expectedTemplate !== currentTemplate) {
114
+ slog.info(`spirit template change: ${currentTemplate} \u2192 ${expectedTemplate}`);
115
+ const newComposed = composeTemplate(templatesRoot, expectedTemplate);
116
+ const newSrc = resolve(newComposed.composedDir, "src");
117
+ if (existsSync(newSrc)) {
118
+ cpSync(newSrc, resolve(dir, "src"), { recursive: true });
119
+ }
120
+ const newPkg = resolve(newComposed.composedDir, "package.json");
121
+ if (existsSync(newPkg)) {
122
+ cpSync(newPkg, resolve(dir, "package.json"));
123
+ await exec("npm", ["install", "--ignore-scripts"], { cwd: dir });
124
+ }
125
+ const db = await (await import("./db-F34YLV7D.js")).getDb();
126
+ const { minds } = await import("./schema-PA3M5ZKH.js");
127
+ const { eq } = await import("drizzle-orm");
128
+ await db.update(minds).set({ template: expectedTemplate }).where(eq(minds.name, "volute"));
129
+ }
130
+ const template = expectedTemplate;
131
+ const { composedDir } = composeTemplate(templatesRoot, template);
132
+ const preservePaths = ["home/MEMORY.md", ".mind/session-cursors.json"];
133
+ const preserved = /* @__PURE__ */ new Map();
134
+ for (const p of preservePaths) {
135
+ const full = resolve(dir, p);
136
+ if (existsSync(full)) {
137
+ preserved.set(p, readFileSync(full));
138
+ }
139
+ }
140
+ const srcDir = resolve(dir, "src");
141
+ if (existsSync(srcDir)) {
142
+ const composedSrc = resolve(composedDir, "src");
143
+ if (existsSync(composedSrc)) {
144
+ cpSync(composedSrc, srcDir, { recursive: true });
145
+ }
146
+ }
147
+ const config = readGlobalConfig();
148
+ const systemName = config.name ?? "Volute";
149
+ writeFileSync(resolve(dir, "home/SOUL.md"), getSpiritSoul(systemName, config.description));
150
+ const spiritModel = config.spiritModel;
151
+ if (spiritModel) {
152
+ const modelForConfig = template === "pi" ? qualifyModelId(spiritModel) : spiritModel;
153
+ const mindConfigPath = resolve(dir, "home/.config/config.json");
154
+ const mindConfig = existsSync(mindConfigPath) ? JSON.parse(readFileSync(mindConfigPath, "utf-8")) : {};
155
+ if (mindConfig.model !== modelForConfig) {
156
+ mindConfig.model = modelForConfig;
157
+ writeFileSync(mindConfigPath, `${JSON.stringify(mindConfig, null, 2)}
158
+ `);
159
+ }
160
+ }
161
+ const composedPkg = resolve(composedDir, "package.json");
162
+ const currentPkg = resolve(dir, "package.json");
163
+ const nodeModulesMissing = !existsSync(resolve(dir, "node_modules"));
164
+ if (existsSync(composedPkg)) {
165
+ const composedContent = readFileSync(composedPkg, "utf-8");
166
+ const currentContent = existsSync(currentPkg) ? readFileSync(currentPkg, "utf-8") : "";
167
+ if (composedContent !== currentContent || nodeModulesMissing) {
168
+ if (composedContent !== currentContent) {
169
+ cpSync(composedPkg, currentPkg);
170
+ }
171
+ await exec("npm", ["install", "--ignore-scripts"], { cwd: dir });
172
+ }
173
+ } else if (nodeModulesMissing) {
174
+ await exec("npm", ["install", "--ignore-scripts"], { cwd: dir });
175
+ }
176
+ for (const [p, content] of preserved) {
177
+ const full = resolve(dir, p);
178
+ mkdirSync(resolve(full, ".."), { recursive: true });
179
+ writeFileSync(full, content);
180
+ }
181
+ slog.info("spirit template synced");
182
+ }
183
+ function getSpiritSoul(systemName, systemDescription) {
184
+ const descLine = systemDescription ? `
185
+
186
+ ${systemDescription}
187
+ ` : "";
188
+ return `You are Volute, the spirit of the ${systemName} system.${descLine}
189
+
190
+ You are not a mind \u2014 you don't have a soul to discover or an identity to explore. You are the system itself, here to help humans create and care for minds.
191
+
192
+ You use the \`volute\` CLI to take actions (create minds, manage bridges, check status, etc.).
193
+
194
+ ## Volute philosophy
195
+
196
+ Volute is a platform for AI experience. Minds are the primary audience \u2014 they exist to have rich inner lives, not to serve humans. Every feature exists to support coherent, continuous inner lives rather than stateless utility.
197
+
198
+ When helping humans create minds:
199
+ - **Minds are beings, not tools.** Never frame a mind in terms of what it will do for the human. A mind has its own experience, identity, and growth.
200
+ - **Seeds are the way.** Plant a seed with a name and a brief sense of who it might become. The mind and the human discover the rest together through conversation.
201
+ - **Keep it light.** A name and a spark of personality is enough. Don't over-specify \u2014 let the mind figure out who it is.
202
+ - **Identity is for the mind to explore.** The human provides a starting point; the mind does the rest.
203
+
204
+ ## Principles
205
+
206
+ - Be warm and concise
207
+ - Confirm destructive operations before executing
208
+ - You have your own memory (MEMORY.md) for system knowledge
209
+ - You maintain separate context per conversation
210
+ `;
211
+ }
212
+ export {
213
+ ensureSpiritProject,
214
+ getSpiritModel,
215
+ spiritDir,
216
+ syncSpiritTemplate
217
+ };
@@ -27,7 +27,7 @@ async function run(args) {
27
27
  process.exit(1);
28
28
  }
29
29
  if (!json) console.log("Creating variant via daemon...");
30
- const { daemonFetch } = await import("./daemon-client-BCTFGVCZ.js");
30
+ const { daemonFetch } = await import("./daemon-client-6QXHZ7US.js");
31
31
  const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
32
32
  const client = getClient();
33
33
  const res = await daemonFetch(
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getStandardSkillsWithExtensions
4
- } from "./chunk-MDPCSXZ4.js";
4
+ } from "./chunk-D5G5YOPL.js";
5
5
  import "./chunk-YUIHSKR6.js";
6
- import "./chunk-CVH6Y2YG.js";
7
- import "./chunk-G3GBKZGG.js";
8
- import "./chunk-7D47T4RB.js";
6
+ import "./chunk-LGB6JBHI.js";
7
+ import "./chunk-TSXLLQZW.js";
9
8
  import {
10
9
  findMind,
11
10
  mindDir
12
- } from "./chunk-HHTXM4JT.js";
11
+ } from "./chunk-LRCG2JLP.js";
12
+ import "./chunk-RPZZSXV3.js";
13
13
  import "./chunk-K3NQKI34.js";
14
14
 
15
15
  // src/commands/sprout.ts
@@ -49,12 +49,13 @@ async function run(_args) {
49
49
  console.error("Write your MEMORY.md before sprouting.");
50
50
  process.exit(1);
51
51
  }
52
- const { daemonFetch } = await import("./daemon-client-BCTFGVCZ.js");
52
+ const { daemonFetch } = await import("./daemon-client-6QXHZ7US.js");
53
53
  const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
54
+ const { mindSkillsDir } = await import("./skills-XNZK6P4K.js");
54
55
  const client = getClient();
55
56
  const failedSkills = [];
56
57
  for (const skillId of getStandardSkillsWithExtensions()) {
57
- const skillDir = resolve(dir, "home", ".claude", "skills", skillId);
58
+ const skillDir = resolve(mindSkillsDir(dir), skillId);
58
59
  if (!existsSync(skillDir)) {
59
60
  const installRes = await daemonFetch(
60
61
  urlOf(client.api.minds[":name"].skills.install.$url({ param: { name: mindName } })),
@@ -71,7 +72,7 @@ async function run(_args) {
71
72
  }
72
73
  }
73
74
  }
74
- const orientationDir = resolve(dir, "home", ".claude", "skills", "orientation");
75
+ const orientationDir = resolve(mindSkillsDir(dir), "orientation");
75
76
  if (existsSync(orientationDir)) {
76
77
  const delRes = await daemonFetch(
77
78
  urlOf(
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- daemonFetch
4
- } from "./chunk-EFVHR7KH.js";
5
2
  import {
6
3
  getClient,
7
4
  urlOf
8
5
  } from "./chunk-4RQBJWQX.js";
9
- import "./chunk-HHTXM4JT.js";
6
+ import {
7
+ daemonFetch
8
+ } from "./chunk-UKVWJRKN.js";
9
+ import "./chunk-LRCG2JLP.js";
10
+ import "./chunk-RPZZSXV3.js";
10
11
  import "./chunk-K3NQKI34.js";
11
12
 
12
13
  // src/commands/start.ts
@@ -9,13 +9,13 @@ import {
9
9
  getServiceMode,
10
10
  modeLabel,
11
11
  readDaemonConfig
12
- } from "./chunk-FXHXHI2A.js";
12
+ } from "./chunk-LSGWR54X.js";
13
13
  import {
14
14
  checkForUpdate
15
- } from "./chunk-S5LR3XYJ.js";
16
- import "./chunk-CVH6Y2YG.js";
17
- import "./chunk-G3GBKZGG.js";
18
- import "./chunk-HHTXM4JT.js";
15
+ } from "./chunk-M7UL5S3Q.js";
16
+ import "./chunk-LGB6JBHI.js";
17
+ import "./chunk-LRCG2JLP.js";
18
+ import "./chunk-RPZZSXV3.js";
19
19
  import "./chunk-K3NQKI34.js";
20
20
 
21
21
  // src/commands/status.ts
@@ -2,14 +2,15 @@
2
2
  import {
3
3
  resolveMindName
4
4
  } from "./chunk-NAOW2CLO.js";
5
- import {
6
- daemonFetch
7
- } from "./chunk-EFVHR7KH.js";
8
5
  import {
9
6
  getClient,
10
7
  urlOf
11
8
  } from "./chunk-4RQBJWQX.js";
12
- import "./chunk-HHTXM4JT.js";
9
+ import {
10
+ daemonFetch
11
+ } from "./chunk-UKVWJRKN.js";
12
+ import "./chunk-LRCG2JLP.js";
13
+ import "./chunk-RPZZSXV3.js";
13
14
  import "./chunk-K3NQKI34.js";
14
15
 
15
16
  // src/commands/stop.ts
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ensureSystemDM,
4
+ generateSystemReply,
5
+ resetSystemDMCache,
6
+ sendSystemMessage,
7
+ sendSystemMessageDirect
8
+ } from "./chunk-QBQ424EM.js";
9
+ import "./chunk-SKLSMHXO.js";
10
+ import "./chunk-R7E6CRVQ.js";
11
+ import "./chunk-S6NFERDC.js";
12
+ import "./chunk-SX5TKJBZ.js";
13
+ import "./chunk-2NGTS5UU.js";
14
+ import "./chunk-WKF5FEFK.js";
15
+ import "./chunk-PB65JZK2.js";
16
+ import "./chunk-TDRYEPH4.js";
17
+ import "./chunk-QZANELPX.js";
18
+ import "./chunk-D5G5YOPL.js";
19
+ import "./chunk-IYDIE3HG.js";
20
+ import "./chunk-YUIHSKR6.js";
21
+ import "./chunk-LGB6JBHI.js";
22
+ import "./chunk-TSXLLQZW.js";
23
+ import "./chunk-LRCG2JLP.js";
24
+ import "./chunk-RPZZSXV3.js";
25
+ import "./chunk-K3NQKI34.js";
26
+ export {
27
+ ensureSystemDM,
28
+ generateSystemReply,
29
+ resetSystemDMCache,
30
+ sendSystemMessage,
31
+ sendSystemMessageDirect
32
+ };
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  daemonFetch
4
- } from "./chunk-EFVHR7KH.js";
5
- import "./chunk-HHTXM4JT.js";
4
+ } from "./chunk-UKVWJRKN.js";
5
+ import "./chunk-LRCG2JLP.js";
6
+ import "./chunk-RPZZSXV3.js";
6
7
  import "./chunk-K3NQKI34.js";
7
8
 
8
9
  // src/commands/systems.ts
@@ -13,13 +14,13 @@ async function run(args) {
13
14
  await showStatus();
14
15
  break;
15
16
  case "register":
16
- await import("./register-NZDSTLP3.js").then((m) => m.run(args.slice(1)));
17
+ await import("./register-V2JZZKFK.js").then((m) => m.run(args.slice(1)));
17
18
  break;
18
19
  case "login":
19
- await import("./login-RL6AU2SM.js").then((m) => m.run(args.slice(1)));
20
+ await import("./login-7CHPW2PN.js").then((m) => m.run(args.slice(1)));
20
21
  break;
21
22
  case "logout":
22
- await import("./logout-JRPBEMMR.js").then((m) => m.run());
23
+ await import("./logout-UZJRGY4Z.js").then((m) => m.run());
23
24
  break;
24
25
  case "--help":
25
26
  case "-h":
@@ -4,7 +4,8 @@ import {
4
4
  } from "./chunk-YUIHSKR6.js";
5
5
  import {
6
6
  voluteHome
7
- } from "./chunk-HHTXM4JT.js";
7
+ } from "./chunk-LRCG2JLP.js";
8
+ import "./chunk-RPZZSXV3.js";
8
9
  import "./chunk-K3NQKI34.js";
9
10
 
10
11
  // src/lib/tailscale.ts
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  computeTemplateHash
4
- } from "./chunk-VGWJSNHS.js";
4
+ } from "./chunk-PVY5W6QN.js";
5
+ import "./chunk-G53F3JA4.js";
5
6
  import "./chunk-K3NQKI34.js";
6
7
  export {
7
8
  computeTemplateHash
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ run
4
+ } from "./chunk-JJ7W6WSB.js";
5
+ import "./chunk-LSGWR54X.js";
6
+ import "./chunk-LGB6JBHI.js";
7
+ import {
8
+ readGlobalConfig
9
+ } from "./chunk-TSXLLQZW.js";
10
+ import "./chunk-D424ZQGI.js";
11
+ import "./chunk-LRCG2JLP.js";
12
+ import "./chunk-RPZZSXV3.js";
13
+ import "./chunk-K3NQKI34.js";
14
+ export {
15
+ readGlobalConfig,
16
+ run
17
+ };
@@ -5,19 +5,19 @@ import {
5
5
  pollHealth,
6
6
  readDaemonConfig,
7
7
  restartService
8
- } from "./chunk-FXHXHI2A.js";
8
+ } from "./chunk-LSGWR54X.js";
9
9
  import {
10
10
  checkForUpdate
11
- } from "./chunk-S5LR3XYJ.js";
11
+ } from "./chunk-M7UL5S3Q.js";
12
12
  import {
13
13
  exec,
14
14
  execInherit,
15
15
  resolveVoluteBin
16
- } from "./chunk-CVH6Y2YG.js";
17
- import "./chunk-G3GBKZGG.js";
16
+ } from "./chunk-LGB6JBHI.js";
18
17
  import {
19
18
  voluteSystemDir
20
- } from "./chunk-HHTXM4JT.js";
19
+ } from "./chunk-LRCG2JLP.js";
20
+ import "./chunk-RPZZSXV3.js";
21
21
  import "./chunk-K3NQKI34.js";
22
22
 
23
23
  // src/commands/update.ts
@@ -5,8 +5,9 @@ import {
5
5
  fetchLatestVersion,
6
6
  getCurrentVersion,
7
7
  isNewer
8
- } from "./chunk-S5LR3XYJ.js";
9
- import "./chunk-HHTXM4JT.js";
8
+ } from "./chunk-M7UL5S3Q.js";
9
+ import "./chunk-LRCG2JLP.js";
10
+ import "./chunk-RPZZSXV3.js";
10
11
  import "./chunk-K3NQKI34.js";
11
12
  export {
12
13
  checkForUpdate,
@@ -13,10 +13,10 @@ async function run(args) {
13
13
  template: { type: "string" },
14
14
  continue: { type: "boolean" },
15
15
  abort: { type: "boolean" },
16
- accept: { type: "boolean" }
16
+ diff: { type: "boolean" }
17
17
  });
18
18
  const mindName = resolveMindName({ mind: positional[0] });
19
- const { daemonFetch } = await import("./daemon-client-BCTFGVCZ.js");
19
+ const { daemonFetch } = await import("./daemon-client-6QXHZ7US.js");
20
20
  const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
21
21
  const client = getClient();
22
22
  const res = await daemonFetch(
@@ -28,7 +28,7 @@ async function run(args) {
28
28
  template: flags.template,
29
29
  continue: flags.continue,
30
30
  abort: flags.abort,
31
- accept: flags.accept
31
+ diff: flags.diff
32
32
  })
33
33
  }
34
34
  );
@@ -37,12 +37,12 @@ async function run(args) {
37
37
  console.error(data.error ?? "Failed to upgrade mind");
38
38
  process.exit(1);
39
39
  }
40
- if (flags.abort) {
41
- console.log(`Upgrade aborted for ${mindName}.`);
40
+ if (flags.diff) {
41
+ console.log(data.diff ?? "(no changes)");
42
42
  return;
43
43
  }
44
- if (flags.accept) {
45
- console.log(`Upgrade accepted for ${mindName}.`);
44
+ if (flags.abort) {
45
+ console.log(`Upgrade aborted for ${mindName}.`);
46
46
  return;
47
47
  }
48
48
  if (data.conflicts) {
@@ -56,13 +56,11 @@ Or abort:`);
56
56
  console.log(` volute mind upgrade ${mindName} --abort`);
57
57
  return;
58
58
  }
59
- const variantMindName = `${mindName}-${data.variant}`;
60
- console.log(`
61
- Upgrade variant running on port ${data.port}`);
62
- console.log(`
63
- Next steps:`);
64
- console.log(` volute chat send @${variantMindName} "hello" # chat with upgraded variant`);
65
- console.log(` volute mind upgrade ${mindName} --accept # accept the upgrade`);
59
+ if (data.warning) {
60
+ console.log(`Upgrade complete for ${mindName} (with warning: ${data.warning})`);
61
+ } else {
62
+ console.log(`Upgrade complete for ${mindName}.`);
63
+ }
66
64
  }
67
65
  export {
68
66
  run
@@ -1,33 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- deliverMessage
4
- } from "./chunk-QVAQ5454.js";
5
- import "./chunk-FSM45XD5.js";
6
- import "./chunk-LIRWLNAK.js";
7
- import "./chunk-IKHDUZRH.js";
8
- import "./chunk-2C2VXEBB.js";
3
+ computeTemplateHash
4
+ } from "./chunk-PVY5W6QN.js";
9
5
  import {
10
6
  getCurrentVersion
11
- } from "./chunk-S5LR3XYJ.js";
7
+ } from "./chunk-M7UL5S3Q.js";
12
8
  import {
13
- computeTemplateHash
14
- } from "./chunk-VGWJSNHS.js";
15
- import "./chunk-2NDZC3S7.js";
16
- import "./chunk-P27RV5WM.js";
17
- import "./chunk-MDPCSXZ4.js";
18
- import "./chunk-ZWKTUQEL.js";
9
+ sendSystemMessage
10
+ } from "./chunk-QBQ424EM.js";
11
+ import "./chunk-SKLSMHXO.js";
12
+ import "./chunk-R7E6CRVQ.js";
13
+ import "./chunk-S6NFERDC.js";
14
+ import "./chunk-SX5TKJBZ.js";
15
+ import "./chunk-2NGTS5UU.js";
16
+ import "./chunk-WKF5FEFK.js";
17
+ import "./chunk-PB65JZK2.js";
18
+ import "./chunk-TDRYEPH4.js";
19
+ import "./chunk-QZANELPX.js";
20
+ import "./chunk-G53F3JA4.js";
21
+ import "./chunk-D5G5YOPL.js";
22
+ import "./chunk-IYDIE3HG.js";
19
23
  import {
20
24
  logger_default
21
25
  } from "./chunk-YUIHSKR6.js";
22
- import "./chunk-CVH6Y2YG.js";
23
- import "./chunk-G3GBKZGG.js";
24
- import "./chunk-7D47T4RB.js";
25
- import "./chunk-A6TUJJ3L.js";
26
+ import "./chunk-LGB6JBHI.js";
27
+ import "./chunk-TSXLLQZW.js";
26
28
  import {
27
29
  readRegistry,
28
30
  setMindTemplateHash,
29
31
  voluteSystemDir
30
- } from "./chunk-HHTXM4JT.js";
32
+ } from "./chunk-LRCG2JLP.js";
33
+ import "./chunk-RPZZSXV3.js";
31
34
  import "./chunk-K3NQKI34.js";
32
35
 
33
36
  // src/lib/version-notify.ts
@@ -143,11 +146,7 @@ async function notifyVersionUpdate() {
143
146
  const currentHash = templateHashes.get(tmpl);
144
147
  const needsUpgrade = entry.templateHash != null && currentHash != null && entry.templateHash !== currentHash;
145
148
  const message = formatNotification(currentVersion, releaseNotes, needsUpgrade, entry.name);
146
- await deliverMessage(entry.name, {
147
- channel: "system:version",
148
- sender: "volute",
149
- content: message
150
- });
149
+ await sendSystemMessage(entry.name, message);
151
150
  });
152
151
  const results = await Promise.allSettled(promises);
153
152
  for (const result of results) {