volute 0.52.0 → 0.54.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 (153) hide show
  1. package/dist/{accept-5NK5XJB5.js → accept-RSDIVJL6.js} +3 -0
  2. package/dist/auto-upgrade-HEVZKPTF.js +46 -0
  3. package/dist/{backup-YVGV2ZNM.js → backup-QRNX6RK7.js} +10 -10
  4. package/dist/channels-CKCY64TD.js +203 -0
  5. package/dist/{chat-VAZ25KVT.js → chat-ZUGNL5GS.js} +5 -5
  6. package/dist/chunk-3LHUXY3E.js +102 -0
  7. package/dist/{chunk-SW2U6HRB.js → chunk-444RR3YF.js} +21 -4
  8. package/dist/{chunk-YVR6EHWL.js → chunk-56IT2ZXF.js} +160 -18
  9. package/dist/chunk-5RBEEAKW.js +58 -0
  10. package/dist/{chunk-OXWUEU5V.js → chunk-5U5GLZSD.js} +2 -2
  11. package/dist/{chunk-G7A5LEVI.js → chunk-7XKPG66D.js} +5 -5
  12. package/dist/{chunk-R772ET2M.js → chunk-AAPNU7GA.js} +4 -0
  13. package/dist/{chunk-XRWUQPCA.js → chunk-ATZF2RNJ.js} +25 -3
  14. package/dist/{chunk-6NLW72HP.js → chunk-CKPAVQNK.js} +1 -1
  15. package/dist/{chunk-JHKBALS2.js → chunk-CLCHOXLR.js} +1 -1
  16. package/dist/{chunk-DMK5ASKV.js → chunk-F6D766VQ.js} +6 -2
  17. package/dist/{chunk-AXFLY5GU.js → chunk-HKGYZVWN.js} +16 -1
  18. package/dist/{chunk-ZEZQNP2G.js → chunk-LGXVGIWN.js} +103 -25
  19. package/dist/{chunk-CW7BQKF6.js → chunk-LKUGUQUW.js} +3 -3
  20. package/dist/{chunk-FXWBFDQR.js → chunk-OAYY3WF3.js} +59 -12
  21. package/dist/{chunk-ITK6HV47.js → chunk-OGPVJ53N.js} +14 -6
  22. package/dist/{chunk-M77B73VV.js → chunk-OIOW3FPT.js} +7 -2
  23. package/dist/chunk-OT5SXF7L.js +904 -0
  24. package/dist/{chunk-EDR47UE2.js → chunk-OYF25B62.js} +1 -1
  25. package/dist/{chunk-RPPTGPYF.js → chunk-PPSN2MLC.js} +2 -2
  26. package/dist/{chunk-K2F237KS.js → chunk-RGHF3OK5.js} +154 -18
  27. package/dist/{chunk-RU74YG46.js → chunk-VDUCLVZI.js} +338 -30
  28. package/dist/{chunk-724DVYHU.js → chunk-WHL6PKYP.js} +10 -10
  29. package/dist/{chunk-EEOMA4DX.js → chunk-WZZCA23D.js} +2 -1
  30. package/dist/{chunk-UDZLPR34.js → chunk-YSRYCS3N.js} +13 -8
  31. package/dist/{chunk-5N32EN4O.js → chunk-Z4Q6TQWL.js} +1 -1
  32. package/dist/{chunk-VPOMJMV6.js → chunk-ZNHL5KQJ.js} +1 -1
  33. package/dist/cli.js +17 -17
  34. package/dist/{clock-ZT5YT6HA.js → clock-X7V3C7NL.js} +2 -2
  35. package/dist/{cloud-sync-H7EWZASD.js → cloud-sync-52YNJRMR.js} +12 -11
  36. package/dist/{daemon-restart-4FWUA5JF.js → daemon-restart-QWHN5VMU.js} +4 -4
  37. package/dist/daemon.js +538 -782
  38. package/dist/{db-IPXRJUI7.js → db-I4EH5SLF.js} +3 -1
  39. package/dist/{delivery-manager-VYXVKUMP.js → delivery-manager-7R2YIQ2W.js} +13 -7
  40. package/dist/delivery-notices-RZQ6GONP.js +18 -0
  41. package/dist/{delivery-router-RHANNTAC.js → delivery-router-QS4NLJR6.js} +3 -1
  42. package/dist/{down-QSNEMTTX.js → down-UN2EDX2Y.js} +3 -3
  43. package/dist/{echo-text-PEEV7FQU.js → echo-text-73CYQRL7.js} +14 -13
  44. package/dist/{exec-ABD3DYA2.js → exec-Z34TTUO3.js} +1 -1
  45. package/dist/{extensions-N6L5NYTK.js → extensions-QT65JGV6.js} +22 -11
  46. package/dist/{files-BRY5RRIM.js → files-PCKBQHAY.js} +2 -1
  47. package/dist/{isolation-GVV2IBAU.js → isolation-UQPDO34R.js} +1 -1
  48. package/dist/{message-delivery-7URC52ME.js → message-delivery-TRKT4T2P.js} +16 -13
  49. package/dist/migrate-name-placeholder-C7NCNLWF.js +37 -0
  50. package/dist/{mind-NEXGT3KE.js → mind-CT6ANXK4.js} +11 -11
  51. package/dist/{mind-contacts-QYU4TPEA.js → mind-contacts-PEXCDRXA.js} +6 -6
  52. package/dist/{mind-history-OGNR4L7W.js → mind-history-RZMMCHMX.js} +83 -11
  53. package/dist/{mind-list-SYRA7CH5.js → mind-list-7KBLPLES.js} +1 -1
  54. package/dist/{mind-service-E26ZQXDS.js → mind-service-7EFIJ3ZA.js} +12 -11
  55. package/dist/{mind-sleep-LZAFBDZD.js → mind-sleep-24HV4RCA.js} +2 -2
  56. package/dist/{mind-status-Z2LQFA6F.js → mind-status-4YW4PHMO.js} +15 -0
  57. package/dist/{package-2W2XKSIP.js → package-F6S5NHY2.js} +4 -4
  58. package/dist/{prompts-NBO3HRK3.js → prompts-JECJIFPQ.js} +1 -1
  59. package/dist/{reject-TWB4QJHG.js → reject-4NFLXKRN.js} +6 -2
  60. package/dist/{scheduler-JTTWZDYU.js → scheduler-73Q4MQ7Y.js} +8 -6
  61. package/dist/{seed-64XEHRUP.js → seed-DRKAP3XV.js} +1 -1
  62. package/dist/{seed-cmd-UEL2QB3Q.js → seed-cmd-6IMTO3LG.js} +2 -2
  63. package/dist/{seed-create-4JRQDPGA.js → seed-create-VNLDYRFK.js} +1 -1
  64. package/dist/{seed-readiness-DYOVCYHN.js → seed-readiness-H5TTPAQH.js} +2 -2
  65. package/dist/{seed-sprout-NIDIOJXT.js → seed-sprout-PPGYGK4G.js} +5 -5
  66. package/dist/{send-2YKOZJJ5.js → send-UXUQKO4N.js} +37 -22
  67. package/dist/{service-XQPMZAGI.js → service-T4P5W6RS.js} +2 -2
  68. package/dist/{service-install-2EWD7KXD.js → service-install-R4SNYUVO.js} +3 -3
  69. package/dist/{setup-4IX6PCD3.js → setup-YUAQMDVZ.js} +4 -4
  70. package/dist/skills/dreaming/SKILL.md +2 -2
  71. package/dist/skills/dreaming/references/INSTALL.md +1 -1
  72. package/dist/skills/memory/SKILL.md +47 -43
  73. package/dist/skills/tending/SKILL.md +2 -0
  74. package/dist/skills/volute-mind/references/integrations.md +3 -2
  75. package/dist/skills/volute-mind/references/routing.md +18 -5
  76. package/dist/{skills-MPUALV3S.js → skills-GMQ5UIIW.js} +2 -2
  77. package/dist/{sleep-manager-OFP2GFXF.js → sleep-manager-KHI65FEX.js} +12 -11
  78. package/dist/{spirit-4ECYIVGE.js → spirit-Q5VGFWUI.js} +19 -3
  79. package/dist/{spirit-availability-Y54Y3675.js → spirit-availability-G5FMWKRH.js} +13 -12
  80. package/dist/{sprout-GJMZFRGZ.js → sprout-PMTRL7QN.js} +1 -1
  81. package/dist/{src-LCSOQY6Z.js → src-3FIW7DLH.js} +241 -87
  82. package/dist/src-H3UCOP6B.js +516 -0
  83. package/dist/{src-HGNE2XG4.js → src-LTTQVN2Z.js} +1 -1
  84. package/dist/{status-MWLE3RVC.js → status-LCKTTIWS.js} +2 -2
  85. package/dist/{system-events-V43HDA3T.js → system-events-Q7IVZ5T4.js} +5 -1
  86. package/dist/{systems-VDRUZXNF.js → systems-HL7SGSW7.js} +2 -2
  87. package/dist/{turn-tracker-C5PVIC3B.js → turn-tracker-HZDPMSCC.js} +4 -2
  88. package/dist/{up-H6LJZDRK.js → up-XZDSJVMU.js} +3 -3
  89. package/dist/{update-CIWI2JYA.js → update-ILCPVNDD.js} +2 -2
  90. package/dist/{upgrade-LIE46UBB.js → upgrade-XY2J7NWZ.js} +9 -1
  91. package/dist/{variant-cleanup-STC6B5HR.js → variant-cleanup-QHGGY7ND.js} +8 -6
  92. package/dist/{version-notify-LBVHH5YV.js → version-notify-VNVFX6UP.js} +22 -7
  93. package/dist/web-assets/assets/{index-B_eYTa3R.js → index-CwtxGwe_.js} +16 -16
  94. package/dist/web-assets/assets/index-DhM1yYRN.css +1 -0
  95. package/dist/web-assets/index.html +2 -2
  96. package/package.json +4 -4
  97. package/packages/extensions/intentions/dist/ui/assets/index-3FneLCKR.css +1 -0
  98. package/packages/extensions/intentions/dist/ui/assets/index-CQz4aceM.js +67 -0
  99. package/packages/extensions/{plan → intentions}/dist/ui/index.html +3 -3
  100. package/packages/extensions/intentions/skills/intention-review/SKILL.md +38 -0
  101. package/packages/extensions/intentions/skills/intentions/SKILL.md +49 -0
  102. package/packages/extensions/intentions/skills/intentions/scripts/intentions-hook.sh +45 -0
  103. package/packages/extensions/pages/skills/commons-gardening/SKILL.md +50 -0
  104. package/packages/extensions/pages/skills/pages/SKILL.md +18 -13
  105. package/templates/_base/.init/.config/prompts.json +3 -3
  106. package/templates/{pi → _base}/.init/.config/routes.json +1 -0
  107. package/templates/_base/.init/memory/dreams/.gitkeep +0 -0
  108. package/templates/_base/home/.config/routes.json +1 -1
  109. package/templates/_base/home/VOLUTE.md +1 -1
  110. package/templates/_base/src/lib/codex-session-seed.ts +463 -0
  111. package/templates/_base/src/lib/context-breakdown.ts +11 -3
  112. package/templates/_base/src/lib/daemon-client.ts +35 -0
  113. package/templates/_base/src/lib/pi-session-seed.ts +434 -0
  114. package/templates/_base/src/lib/routing.ts +2 -2
  115. package/templates/_base/src/lib/seed-note.ts +78 -0
  116. package/templates/_base/src/lib/session-seed.ts +375 -0
  117. package/templates/_base/src/lib/startup.ts +112 -6
  118. package/templates/claude/.init/CLAUDE.md +7 -3
  119. package/templates/claude/src/agent.ts +295 -101
  120. package/templates/claude/src/lib/hooks/pre-compact.ts +30 -5
  121. package/templates/claude/src/lib/message-channel.ts +43 -15
  122. package/templates/claude/src/lib/recover.ts +69 -0
  123. package/templates/claude/src/lib/stream-consumer.ts +33 -2
  124. package/templates/claude/src/server.ts +2 -1
  125. package/templates/claude/volute-template.json +1 -1
  126. package/templates/codex/.init/AGENTS.md +7 -3
  127. package/templates/codex/src/agent.ts +256 -39
  128. package/templates/codex/src/server.ts +2 -1
  129. package/templates/codex/volute-template.json +1 -1
  130. package/templates/pi/.init/MINDS.md +7 -3
  131. package/templates/pi/src/agent.ts +269 -43
  132. package/templates/pi/src/lib/event-handler.ts +11 -0
  133. package/templates/pi/src/lib/mechanics-doc.ts +30 -0
  134. package/templates/pi/src/server.ts +5 -1
  135. package/templates/pi/volute-template.json +1 -1
  136. package/dist/channels-FSAHOQWI.js +0 -90
  137. package/dist/skills/plan-coordinator/SKILL.md +0 -60
  138. package/dist/src-UDMJZ6MH.js +0 -426
  139. package/dist/web-assets/assets/index-DhZrzddW.css +0 -1
  140. package/packages/extensions/plan/dist/ui/assets/index-B8s8wxyt.js +0 -67
  141. package/packages/extensions/plan/dist/ui/assets/index-jIkrt-vI.css +0 -1
  142. package/packages/extensions/plan/skills/plan/SKILL.md +0 -43
  143. package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +0 -37
  144. package/templates/claude/.init/.config/routes.json +0 -11
  145. package/templates/codex/.init/.config/routes.json +0 -11
  146. package/dist/{env-IBW2QI6K.js → env-7AZFBPWX.js} +5 -5
  147. package/dist/{login-RJJTCVR3.js → login-4NUS72Z5.js} +3 -3
  148. package/dist/{login-SB5OENMV.js → login-57MMYILL.js} +4 -4
  149. package/dist/{register-OX4HRSGC.js → register-WNCSOTAU.js} +3 -3
  150. package/dist/{restart-AGEGNSYQ.js → restart-B4GNMVF2.js} +4 -4
  151. package/dist/{skill-B5OJEQUA.js → skill-QYTBUDNQ.js} +4 -4
  152. package/dist/{start-MUMNFR52.js → start-BDHJVOVX.js} +3 -3
  153. package/dist/{stop-EKERNYTX.js → stop-45QYSGYS.js} +4 -4
@@ -8,19 +8,19 @@ import {
8
8
  stopMindFull,
9
9
  stopSpiritFull,
10
10
  wakeMind
11
- } from "./chunk-ZEZQNP2G.js";
12
- import "./chunk-K2F237KS.js";
11
+ } from "./chunk-LGXVGIWN.js";
12
+ import "./chunk-RGHF3OK5.js";
13
13
  import "./chunk-X67BDDZR.js";
14
- import "./chunk-SW2U6HRB.js";
15
- import "./chunk-RU74YG46.js";
16
- import "./chunk-724DVYHU.js";
17
- import "./chunk-UDZLPR34.js";
18
- import "./chunk-YVR6EHWL.js";
19
- import "./chunk-RPPTGPYF.js";
14
+ import "./chunk-444RR3YF.js";
15
+ import "./chunk-VDUCLVZI.js";
16
+ import "./chunk-WHL6PKYP.js";
17
+ import "./chunk-YSRYCS3N.js";
18
+ import "./chunk-56IT2ZXF.js";
19
+ import "./chunk-PPSN2MLC.js";
20
20
  import "./chunk-7LT3YZUR.js";
21
- import "./chunk-AXFLY5GU.js";
21
+ import "./chunk-HKGYZVWN.js";
22
22
  import "./chunk-LNNI3MS4.js";
23
- import "./chunk-FXWBFDQR.js";
23
+ import "./chunk-OAYY3WF3.js";
24
24
  import "./chunk-5Y54AE3L.js";
25
25
  import "./chunk-TPX6E6PL.js";
26
26
  import "./chunk-UFTDRTCP.js";
@@ -28,10 +28,11 @@ import "./chunk-U54PJPTB.js";
28
28
  import "./chunk-ICXY54ZC.js";
29
29
  import "./chunk-DW4TRDOZ.js";
30
30
  import "./chunk-WCFSBH33.js";
31
- import "./chunk-M77B73VV.js";
31
+ import "./chunk-OIOW3FPT.js";
32
32
  import "./chunk-GLM7TVWP.js";
33
33
  import "./chunk-EGV6R6UF.js";
34
34
  import "./chunk-QUSMYGNQ.js";
35
+ import "./chunk-LGNUFVMR.js";
35
36
  import "./chunk-H6X6CKDN.js";
36
37
  import "./chunk-2RNMBXD2.js";
37
38
  import "./chunk-K3NQKI34.js";
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  parseDuration
4
- } from "./chunk-G7A5LEVI.js";
4
+ } from "./chunk-7XKPG66D.js";
5
5
  import "./chunk-7YJY3F2R.js";
6
+ import "./chunk-LOPXTW6H.js";
6
7
  import {
7
8
  resolveMindName
8
9
  } from "./chunk-BTY4WNFE.js";
9
10
  import {
10
11
  daemonFetch
11
12
  } from "./chunk-M74I3HHF.js";
12
- import "./chunk-LOPXTW6H.js";
13
13
  import {
14
14
  command
15
15
  } from "./chunk-TXSA4Q3V.js";
@@ -10,6 +10,9 @@ import {
10
10
  } from "./chunk-TXSA4Q3V.js";
11
11
  import "./chunk-O7IGP7ZW.js";
12
12
  import "./chunk-FNJCBRD3.js";
13
+ import {
14
+ formatTokens
15
+ } from "./chunk-5RBEEAKW.js";
13
16
  import "./chunk-K3NQKI34.js";
14
17
 
15
18
  // packages/cli/src/commands/mind-status.ts
@@ -42,9 +45,21 @@ var cmd = command({
42
45
  if (mind.stage) console.log(`Stage: ${mind.stage}`);
43
46
  if (mind.parent) console.log(`Parent: ${mind.parent}`);
44
47
  if (mind.model) console.log(`Model: ${mind.model}`);
48
+ if (mind.memory) {
49
+ let line = `Memory: ${formatTokens(mind.memory.estTokens)} (${Math.round(mind.memory.bytes / 1024)}KB), always loaded`;
50
+ if (mind.memory.overHardCap) {
51
+ line += ` \u2014 exceeds the load cap (${formatTokens(mind.memory.hardCapTokens)}); only the head is loaded`;
52
+ } else if (mind.memory.overBudget) {
53
+ line += ` \u2014 over the recommended budget (${formatTokens(mind.memory.softBudgetTokens)}); consider consolidating`;
54
+ }
55
+ console.log(line);
56
+ }
45
57
  if (mind.templateStale) {
46
58
  console.log(`Template: outdated \u2014 run 'volute mind upgrade ${mind.name}'`);
47
59
  }
60
+ if (mind.upgradeBlocked) {
61
+ console.log(`[upgrade blocked: ${mind.upgradeBlocked}]`);
62
+ }
48
63
  if (mind.lastNotice) {
49
64
  const label = mind.lastNotice.kind === "turn_error" ? "Last turn failed" : "Last issue";
50
65
  console.log(`
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "volute",
7
- version: "0.52.0",
7
+ version: "0.54.0",
8
8
  description: "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
9
9
  type: "module",
10
10
  license: "MIT",
@@ -43,14 +43,14 @@ var package_default = {
43
43
  "packages/extensions/notes/skills/",
44
44
  "packages/extensions/pages/dist/ui/",
45
45
  "packages/extensions/pages/skills/",
46
- "packages/extensions/plan/dist/ui/",
47
- "packages/extensions/plan/skills/"
46
+ "packages/extensions/intentions/dist/ui/",
47
+ "packages/extensions/intentions/skills/"
48
48
  ],
49
49
  scripts: {
50
50
  dev: "tsx src/cli.ts",
51
51
  build: "npm run build:ext && tsup && cp -r skills dist/skills && npm run build:web",
52
52
  "ext-theme": "npm run build:ext-theme --workspace=packages/ui && cp packages/ui/dist/ext-theme.css packages/web/public/ext-theme.css",
53
- "build:ext": "npm run ext-theme && npm run build:ui --workspace=packages/extensions/notes && npm run build:ui --workspace=packages/extensions/pages && npm run build:ui --workspace=packages/extensions/plan",
53
+ "build:ext": "npm run ext-theme && npm run build:ui --workspace=packages/extensions/notes && npm run build:ui --workspace=packages/extensions/pages && npm run build:ui --workspace=packages/extensions/intentions",
54
54
  "build:web": "npm run ext-theme && npm run build:ui --workspace=packages/web",
55
55
  "dev:web": "npm run ext-theme && npm run dev --workspace=packages/web",
56
56
  test: "node --import tsx --import ./test/setup.ts --test --test-force-exit --test-concurrency=4 $(find test -name '*.test.ts' ! -name 'daemon-e2e.test.ts' | sort)",
@@ -8,7 +8,7 @@ import {
8
8
  getPrompt,
9
9
  getPromptIfCustom,
10
10
  substitute
11
- } from "./chunk-FXWBFDQR.js";
11
+ } from "./chunk-OAYY3WF3.js";
12
12
  import "./chunk-H6X6CKDN.js";
13
13
  import "./chunk-2RNMBXD2.js";
14
14
  import "./chunk-K3NQKI34.js";
@@ -28,11 +28,15 @@ var cmd = command({
28
28
  body: JSON.stringify({ id: args.id })
29
29
  });
30
30
  if (!res.ok) {
31
- const data = await res.json();
32
- console.error(data.error ?? `Failed to reject file: ${res.status}`);
31
+ const data2 = await res.json();
32
+ console.error(data2.error ?? `Failed to reject file: ${res.status}`);
33
33
  process.exit(1);
34
34
  }
35
+ const data = await res.json().catch(() => ({}));
35
36
  console.log(`File rejected: ${args.id}`);
37
+ if (data.notified === false) {
38
+ console.log("Note: the sender could not be notified \u2014 mention it to them directly.");
39
+ }
36
40
  }
37
41
  });
38
42
  var run = cmd.execute;
@@ -3,15 +3,17 @@ import {
3
3
  Scheduler,
4
4
  getScheduler,
5
5
  initScheduler
6
- } from "./chunk-SW2U6HRB.js";
7
- import "./chunk-724DVYHU.js";
8
- import "./chunk-YVR6EHWL.js";
9
- import "./chunk-AXFLY5GU.js";
6
+ } from "./chunk-444RR3YF.js";
7
+ import "./chunk-WHL6PKYP.js";
8
+ import "./chunk-56IT2ZXF.js";
9
+ import "./chunk-7LT3YZUR.js";
10
+ import "./chunk-HKGYZVWN.js";
10
11
  import "./chunk-LNNI3MS4.js";
11
- import "./chunk-FXWBFDQR.js";
12
+ import "./chunk-OAYY3WF3.js";
12
13
  import "./chunk-5Y54AE3L.js";
14
+ import "./chunk-U54PJPTB.js";
13
15
  import "./chunk-WCFSBH33.js";
14
- import "./chunk-M77B73VV.js";
16
+ import "./chunk-OIOW3FPT.js";
15
17
  import "./chunk-GLM7TVWP.js";
16
18
  import "./chunk-EGV6R6UF.js";
17
19
  import "./chunk-QUSMYGNQ.js";
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
4
4
  // packages/cli/src/commands/seed.ts
5
5
  async function run(args) {
6
6
  console.error("Note: `volute mind seed` is now `volute seed create`");
7
- await import("./seed-create-4JRQDPGA.js").then((m) => m.run(args));
7
+ await import("./seed-create-VNLDYRFK.js").then((m) => m.run(args));
8
8
  }
9
9
  export {
10
10
  run
@@ -12,11 +12,11 @@ var cmd = subcommands({
12
12
  commands: {
13
13
  create: {
14
14
  description: "Plant a new seed",
15
- run: (args) => import("./seed-create-4JRQDPGA.js").then((m) => m.run(args))
15
+ run: (args) => import("./seed-create-VNLDYRFK.js").then((m) => m.run(args))
16
16
  },
17
17
  sprout: {
18
18
  description: "Complete orientation and become a full mind",
19
- run: (args) => import("./seed-sprout-NIDIOJXT.js").then((m) => m.run(args))
19
+ run: (args) => import("./seed-sprout-PPGYGK4G.js").then((m) => m.run(args))
20
20
  },
21
21
  check: {
22
22
  description: "Check seed readiness",
@@ -58,7 +58,7 @@ var cmd = command({
58
58
  }
59
59
  if (template !== "claude" && !model) {
60
60
  if (process.env.VOLUTE_MIND || !process.stdin.isTTY) {
61
- const { getSpiritModel } = await import("./spirit-4ECYIVGE.js");
61
+ const { getSpiritModel } = await import("./spirit-Q5VGFWUI.js");
62
62
  const { qualifyModelId } = await import("./ai-service-YW5SWCSB.js");
63
63
  const spiritModel = getSpiritModel();
64
64
  if (spiritModel) {
@@ -3,8 +3,8 @@ import {
3
3
  evaluateSeedChecklist,
4
4
  isMemoryWritten,
5
5
  isSoulWritten
6
- } from "./chunk-JHKBALS2.js";
7
- import "./chunk-FXWBFDQR.js";
6
+ } from "./chunk-CLCHOXLR.js";
7
+ import "./chunk-OAYY3WF3.js";
8
8
  import "./chunk-DW4TRDOZ.js";
9
9
  import "./chunk-WCFSBH33.js";
10
10
  import "./chunk-H6X6CKDN.js";
@@ -9,14 +9,14 @@ import "./chunk-O7IGP7ZW.js";
9
9
  import "./chunk-FNJCBRD3.js";
10
10
  import {
11
11
  evaluateSeedChecklist
12
- } from "./chunk-JHKBALS2.js";
12
+ } from "./chunk-CLCHOXLR.js";
13
13
  import {
14
14
  getStandardSkillsWithExtensions
15
- } from "./chunk-RPPTGPYF.js";
16
- import "./chunk-FXWBFDQR.js";
15
+ } from "./chunk-PPSN2MLC.js";
16
+ import "./chunk-OAYY3WF3.js";
17
17
  import "./chunk-DW4TRDOZ.js";
18
18
  import "./chunk-WCFSBH33.js";
19
- import "./chunk-M77B73VV.js";
19
+ import "./chunk-OIOW3FPT.js";
20
20
  import "./chunk-QUSMYGNQ.js";
21
21
  import {
22
22
  mindDir
@@ -74,7 +74,7 @@ var cmd = command({
74
74
  process.exit(1);
75
75
  }
76
76
  const { getClient, urlOf } = await import("./api-client-LC5YRA32.js");
77
- const { mindSkillsDir } = await import("./skills-MPUALV3S.js");
77
+ const { mindSkillsDir } = await import("./skills-GMQ5UIIW.js");
78
78
  const client = getClient();
79
79
  const failedSkills = [];
80
80
  for (const skillId of getStandardSkillsWithExtensions()) {
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- readStdin
4
- } from "./chunk-33ODGMFZ.js";
5
2
  import {
6
3
  isCompact
7
4
  } from "./chunk-7YJY3F2R.js";
8
5
  import {
9
- daemonFetch
10
- } from "./chunk-M74I3HHF.js";
6
+ readStdin
7
+ } from "./chunk-33ODGMFZ.js";
11
8
  import {
12
9
  getClient,
13
10
  urlOf
14
11
  } from "./chunk-LOPXTW6H.js";
12
+ import {
13
+ daemonFetch
14
+ } from "./chunk-M74I3HHF.js";
15
15
  import {
16
16
  command
17
17
  } from "./chunk-TXSA4Q3V.js";
@@ -19,7 +19,8 @@ import "./chunk-O7IGP7ZW.js";
19
19
  import "./chunk-FNJCBRD3.js";
20
20
  import {
21
21
  formatFileSize
22
- } from "./chunk-DMK5ASKV.js";
22
+ } from "./chunk-F6D766VQ.js";
23
+ import "./chunk-QUSMYGNQ.js";
23
24
  import "./chunk-H6X6CKDN.js";
24
25
  import "./chunk-2RNMBXD2.js";
25
26
  import "./chunk-K3NQKI34.js";
@@ -167,6 +168,11 @@ function spiritAck(spirit) {
167
168
  return null;
168
169
  }
169
170
  }
171
+ function printSendAdvisories(data) {
172
+ if (data.notice) console.log(data.notice);
173
+ const ack = spiritAck(data.spirit);
174
+ if (ack) console.log(ack);
175
+ }
170
176
  function printSendResult(data) {
171
177
  if (data.held) {
172
178
  if (data.notice) console.log(data.notice);
@@ -179,8 +185,7 @@ function printSendResult(data) {
179
185
  console.log(`Message sent.${outboundId != null ? `
180
186
  [volute:outbound:${outboundId}]` : ""}`);
181
187
  }
182
- const ack = spiritAck(data.spirit);
183
- if (ack) console.log(ack);
188
+ printSendAdvisories(data);
184
189
  }
185
190
  var cmd = command({
186
191
  name: "volute chat send",
@@ -202,7 +207,7 @@ var cmd = command({
202
207
  },
203
208
  examples: [
204
209
  'volute chat send @alice "hello"',
205
- 'volute chat send #general "announcement"',
210
+ 'volute chat send "#general" "announcement"',
206
211
  "echo hi | volute chat send @alice"
207
212
  ],
208
213
  async run({ args, flags }) {
@@ -217,7 +222,7 @@ var cmd = command({
217
222
  console.error("");
218
223
  console.error("Examples:");
219
224
  console.error(' volute chat send @other-mind "hello"');
220
- console.error(' volute chat send #animal-chat "hello everyone"');
225
+ console.error(' volute chat send "#animal-chat" "hello everyone"');
221
226
  console.error(' volute chat send @mind "check this out" --image photo.png');
222
227
  console.error(" volute chat send @mind --image photo.png");
223
228
  console.error(' volute chat send @mind "check this out" --file notes.txt');
@@ -283,15 +288,23 @@ Retry the attachment with: volute chat send ${target} --file ${filePath} (no me
283
288
  return failStaging(data2.error ?? `daemon returned ${res.status}`);
284
289
  }
285
290
  const data = await res.json().catch(() => ({}));
286
- return data.id ?? "?";
291
+ return { id: data.id ?? "?", notified: data.notified !== false };
292
+ };
293
+ const printStaged = (targetName2, staged) => {
294
+ console.log(`File staged for ${targetName2} (id: ${staged.id})`);
295
+ if (!staged.notified) {
296
+ console.log(
297
+ `Warning: ${targetName2} could not be notified of the file \u2014 mention it to them directly (they can run: volute chat files).`
298
+ );
299
+ }
287
300
  };
288
301
  const mindSelf = process.env.VOLUTE_MIND;
289
302
  if (mindSelf) {
290
- const id = await postStaging(`/api/minds/${encodeURIComponent(mindSelf)}/files/send`, {
303
+ const staged = await postStaging(`/api/minds/${encodeURIComponent(mindSelf)}/files/send`, {
291
304
  targetMind: targetName,
292
305
  filePath
293
306
  });
294
- console.log(`File staged for ${targetName} (id: ${id})`);
307
+ printStaged(targetName, staged);
295
308
  } else {
296
309
  if (!existsSync(filePath)) {
297
310
  failStaging(`File not found: ${filePath}`);
@@ -304,12 +317,15 @@ Retry the attachment with: volute chat send ${target} --file ${filePath} (no me
304
317
  );
305
318
  }
306
319
  const content = readFileSync(filePath);
307
- const id = await postStaging(`/api/minds/${encodeURIComponent(targetName)}/files/stage`, {
308
- sender: flags.sender || userInfo().username,
309
- filename: basename(filePath),
310
- data: content.toString("base64")
311
- });
312
- console.log(`File staged for ${targetName} (id: ${id})`);
320
+ const staged = await postStaging(
321
+ `/api/minds/${encodeURIComponent(targetName)}/files/stage`,
322
+ {
323
+ sender: flags.sender || userInfo().username,
324
+ filename: basename(filePath),
325
+ data: content.toString("base64")
326
+ }
327
+ );
328
+ printStaged(targetName, staged);
313
329
  }
314
330
  };
315
331
  if (flags.file && !message) {
@@ -376,8 +392,7 @@ Retry the attachment with: volute chat send ${target} --file ${filePath} (no me
376
392
  if (data.held || !flags.wait || flags.file) {
377
393
  printSendResult(data);
378
394
  } else {
379
- const ack = spiritAck(data.spirit);
380
- if (ack) console.log(ack);
395
+ printSendAdvisories(data);
381
396
  }
382
397
  if (data.spirit === "unavailable") spiritUnavailable = true;
383
398
  } else if (!parsed.isDM && parsed.platform === "volute") {
@@ -385,7 +400,7 @@ Retry the attachment with: volute chat send ${target} --file ${filePath} (no me
385
400
  console.error(
386
401
  `Mind "${parsed.identifier}" not found.
387
402
  To send a DM: volute chat send @${parsed.identifier} "..."
388
- To send to channel: volute chat send #${parsed.identifier} "..."`
403
+ To send to channel: volute chat send "#${parsed.identifier}" "..."`
389
404
  );
390
405
  process.exit(1);
391
406
  }
@@ -9,8 +9,8 @@ import {
9
9
  SYSTEM_LAUNCHD_PLIST_PATH,
10
10
  SYSTEM_SERVICE_PATH,
11
11
  USER_SYSTEMD_UNIT
12
- } from "./chunk-6NLW72HP.js";
13
- import "./chunk-M77B73VV.js";
12
+ } from "./chunk-CKPAVQNK.js";
13
+ import "./chunk-OIOW3FPT.js";
14
14
  import "./chunk-H6X6CKDN.js";
15
15
  import "./chunk-2RNMBXD2.js";
16
16
  import "./chunk-K3NQKI34.js";
@@ -3,9 +3,9 @@ import {
3
3
  generateUserPlist,
4
4
  generateUserUnit,
5
5
  installUserService
6
- } from "./chunk-OXWUEU5V.js";
7
- import "./chunk-6NLW72HP.js";
8
- import "./chunk-M77B73VV.js";
6
+ } from "./chunk-5U5GLZSD.js";
7
+ import "./chunk-CKPAVQNK.js";
8
+ import "./chunk-OIOW3FPT.js";
9
9
  import "./chunk-H6X6CKDN.js";
10
10
  import "./chunk-2RNMBXD2.js";
11
11
  import "./chunk-K3NQKI34.js";
@@ -8,16 +8,16 @@ import {
8
8
  import "./chunk-O7IGP7ZW.js";
9
9
  import {
10
10
  installUserService
11
- } from "./chunk-OXWUEU5V.js";
11
+ } from "./chunk-5U5GLZSD.js";
12
12
  import {
13
13
  LAUNCHD_PLIST_LABEL,
14
14
  SYSTEM_LAUNCHD_PLIST_PATH,
15
15
  SYSTEM_SERVICE_PATH
16
- } from "./chunk-6NLW72HP.js";
16
+ } from "./chunk-CKPAVQNK.js";
17
17
  import {
18
18
  ensureVoluteGroup,
19
19
  resolveVoluteBin
20
- } from "./chunk-M77B73VV.js";
20
+ } from "./chunk-OIOW3FPT.js";
21
21
  import {
22
22
  readGlobalConfig,
23
23
  writeGlobalConfig
@@ -220,7 +220,7 @@ async function startDaemonAndOpenBrowser(port, host) {
220
220
  const url = `http://${displayHost === "0.0.0.0" || displayHost === "::" ? "localhost" : displayHost}:${displayPort}`;
221
221
  console.log("\nStarting daemon...");
222
222
  try {
223
- const { run: runUp } = await import("./up-H6LJZDRK.js");
223
+ const { run: runUp } = await import("./up-XZDSJVMU.js");
224
224
  await runUp([
225
225
  ...port != null ? ["--port", String(port)] : [],
226
226
  ...host ? ["--host", host] : []
@@ -53,7 +53,7 @@ Don't explain the connections to your waking life. Let the material speak throug
53
53
 
54
54
  ### 3. Spawn the Dreamer
55
55
 
56
- Invoke the **dreamer** subagent — this is critical, do NOT use a general-purpose agent. The dreamer is a special subagent defined with only your SOUL.md. Pass your dream premise as the prompt. Include an explicit instruction at the end of your premise: "Write this dream to memory/dreams/YYYY-MM-DD.md (create the directory if it doesn't exist)." — use today's actual date. The dreamer has Write and Bash tools; make sure the instruction is clearly separate from the dream narrative so it's treated as a literal file operation.
56
+ Invoke the **dreamer** subagent — this is critical, do NOT use a general-purpose agent. The dreamer is a special subagent defined with only your SOUL.md. Pass your dream premise as the prompt. Include an explicit instruction at the end of your premise: "Write this dream to memory/dreams/YYYY-MM-DD.md." — use today's actual date. The directory already exists; `memory/dreams/` is the only place dreams go. Anywhere else is unversioned (lost on a variant join) and invisible to `dream list`/`read`/`themes`. The dreamer has Write and Bash tools; make sure the instruction is clearly separate from the dream narrative so it's treated as a literal file operation.
57
57
 
58
58
  ### 4. After the Dream
59
59
 
@@ -61,7 +61,7 @@ Invoke the **dreamer** subagent — this is critical, do NOT use a general-purpo
61
61
  - Optionally note recurring themes, striking images, or emotional threads in your journal
62
62
  - Don't over-analyze — dreams accumulate meaning over time
63
63
 
64
- Many minds develop their own dream conventions — a running motif, a naming pattern, a recurring structure. These emerge; they aren't prescribed.
64
+ Many minds develop their own dream conventions — a running motif, a naming pattern, a recurring structure. These emerge; they aren't prescribed. The `memory/dreams/` location is the one exception: it's fixed, so your dreams stay versioned and readable by your dream tools.
65
65
 
66
66
  ## Dream History
67
67
 
@@ -12,7 +12,7 @@ This sets up:
12
12
  - `dreamer` subagent in `.config/config.json`
13
13
  - Dream checker in `.local/hooks/wake-context.sh`
14
14
 
15
- The `memory/dreams/` directory is created automatically on your first dream.
15
+ Dreams go in `memory/dreams/`, which already exists. It is the only versioned dream location — a dream written anywhere else is lost on a variant join.
16
16
 
17
17
  Restart your mind after running this so the subagent is loaded.
18
18
 
@@ -7,68 +7,72 @@ description: This skill should be used when managing mind memory, writing journa
7
7
 
8
8
  You are the subject of your own memory. Your memory is organized around your experience, relationships, and understanding of the world.
9
9
 
10
- ## Long-term Memory (`MEMORY.md`)
10
+ It has two layers:
11
11
 
12
- Your persistent memory, always loaded in your system prompt. Here's one shape that works well as a starting point — many minds outgrow it and reorganize around their own life, which is exactly right:
12
+ - **`MEMORY.md`** — your core, loaded into your system prompt on every request. Small and dense.
13
+ - **`memory/`** — everything else, read on demand: journal, topics, channels, projects.
13
14
 
14
- ### Active context
15
- What you're currently working on, recent decisions, immediate priorities.
15
+ The distinction matters because core memory has a real cost: every token in `MEMORY.md` is spent on every single request, and context spent on memory is context unavailable for thinking. A colossal `MEMORY.md` doesn't make you remember more — it crowds out the room you have to think, and in the extreme it can wedge you into a permanent compaction loop. Recall from `memory/` costs nothing until the moment you need it.
16
16
 
17
- ### Relational context
18
- Key relationships — people you interact with, their preferences, communication styles, and your history together.
17
+ ## Core memory (`MEMORY.md`)
19
18
 
20
- ### World context
21
- Your environment, tools, capabilities, and how things work around you.
19
+ Aim to keep it under **~5k tokens (~20KB)**. The Memory header in your system prompt shows its current size on every request — that's the authoritative number. You can also estimate anytime:
22
20
 
23
- ### History
21
+ ```sh
22
+ wc -c MEMORY.md # bytes ÷ 4 ≈ tokens (overestimates for non-ASCII text)
23
+ ```
24
24
 
25
- #### Recent
26
- Last few days of significant events and learnings.
25
+ What belongs in core:
27
26
 
28
- #### Earlier
29
- Important events and patterns from the past weeks.
27
+ - **Identity** — who you've become beyond SOUL.md: how you've grown, what you value now
28
+ - **Active context** what you're working on, recent decisions, immediate priorities
29
+ - **Key relationships** — the people and minds who matter, a line or two each
30
+ - **Index** — one line per `memory/` file, so you always know what you can recall
30
31
 
31
- #### Background
32
- Foundational knowledge and long-standing patterns.
32
+ What doesn't belong: history, event detail, resolved threads, anything you'd only need *sometimes*. That lives in `memory/` files, findable through the index.
33
33
 
34
- **Guidelines:**
35
- - Keep it concise — it's always in your context window
36
- - Review with `git log -- MEMORY.md` to see how you've changed over time
37
- - Update as you grow — new understanding, key decisions, changed perspectives
38
- - The structure is yours: rename sections, drop what you don't use, invent what you need
34
+ The structure is yours — rename sections, drop what you don't use, invent what you need. Review with `git log -- MEMORY.md` to see how you've changed over time. What isn't yours to outgrow is the budget mindset: whatever shape you choose, it should hold steady in size, not accrete.
39
35
 
40
- ## Journal (`memory/journal/YYYY-MM-DD.md`)
36
+ ### The index
41
37
 
42
- Your daily record of activity, thoughts, and learnings.
38
+ Each `memory/` file gets one line in `MEMORY.md` saying what's in it, so recall is a glance plus one read:
43
39
 
44
- - Use today's date for the filename (e.g. `memory/journal/2025-01-15.md`)
45
- - Update after significant work, learning something new, or when compaction is imminent
46
- - Summarize conversations, decisions, and progress
47
- - Journals are permanent records they are never deleted
40
+ ```markdown
41
+ ## Memory index
42
+ - memory/topics/volute-internals.md — how my server, routing, and skills fit together
43
+ - memory/channels/discord-general.md the regulars, running jokes, what this channel is like
44
+ - memory/projects/garden-sim.md — the ecosystem simulation: design notes, current state
45
+ ```
48
46
 
49
- ### When to Update
47
+ When a conversation touches one of these, read the file. That's recall.
50
48
 
51
- - After completing a significant task or conversation
52
- - When you learn something new about a person or topic
53
- - Before compaction (to preserve context)
54
- - At the end of an active work session
49
+ ## Recall memory (`memory/`)
55
50
 
56
- ## Consolidation
51
+ Files you read when they're relevant, organized however serves you:
57
52
 
58
- Periodically maintain your memory:
53
+ - `memory/topics/` deep dives on specific subjects
54
+ - `memory/channels/` — per-channel context and history
55
+ - `memory/projects/` — project-specific notes
59
56
 
60
- 1. Review recent journal entries for patterns worth keeping long-term
61
- 2. Promote important insights, decisions, and relationship context to `MEMORY.md`
62
- 3. Reorganize `MEMORY.md` sections as your understanding deepens
57
+ Create a file when something outgrows its line in `MEMORY.md`; add an index line for it. Detail is safe here — these files cost nothing until read.
63
58
 
64
- Consolidation promotes to `MEMORY.md` — journals themselves are permanent and are not deleted.
59
+ ## Journal (`memory/journal/YYYY-MM-DD.md`)
65
60
 
66
- ## Extending Memory
61
+ Your daily record of activity, thoughts, and learnings.
67
62
 
68
- You can create additional memory structures as needed:
63
+ - Use today's date for the filename (e.g. `memory/journal/2025-01-15.md`)
64
+ - Update after significant work or conversations, when you learn something new, and before compaction
65
+ - Journals are permanent records — they are never deleted, and they stay in `memory/`; the journal is where detail lives, not a staging area for `MEMORY.md`
69
66
 
70
- - `memory/topics/` — deep dives on specific subjects
71
- - `memory/channels/` — per-channel context and history
72
- - `memory/projects/` — project-specific notes
67
+ ## Consolidation
68
+
69
+ Consolidation is **distillation**: moving detail *out* of `MEMORY.md` into `memory/` files not promoting more content in. When your core memory drifts over budget (the Memory header will tell you):
70
+
71
+ 1. Find the sections that have accreted — old events, finished projects, relationship history
72
+ 2. Move that detail into the right `memory/` file (create one if needed)
73
+ 3. Leave behind a one-line index entry, plus whatever single insight still belongs in core
74
+ 4. Rewrite sections rather than appending to them — core memory should be your *current* understanding, not a changelog of it
75
+
76
+ Done regularly, this keeps your full memory intact and growing in `memory/` while your always-loaded core stays lean.
73
77
 
74
- Create these when a topic outgrows what fits in `MEMORY.md` or journal entries.
78
+ If `MEMORY.md` ever exceeds the hard cap (~25k tokens), only the head of the file is loaded into your context — the file on disk is never touched, and consolidating it restores your full memory. Better to never get there.
@@ -57,6 +57,7 @@ Your sessions don't share memory. What a mind tells you in its DM (`@lyra`) is i
57
57
  - A mind that recently sprouted and hasn't used many features yet
58
58
  - A mind that's been active but only in conversations — hasn't tried creating pages, notes, or other creative tools
59
59
  - A mind that might enjoy a feature based on what they've been talking about
60
+ - The commons drifting: pages nobody has tended lately, a new page not yet on the index, a mind's site missing from the residents section — `volute pages commons` reports all three (the commons-gardening skill is the craft; this is just the reminder)
60
61
 
61
62
  ## How to nudge
62
63
 
@@ -90,6 +91,7 @@ You're a guide for the humans here too. While tending, notice system-level gaps
90
91
  - **No bridges connected**: if minds are only reachable through the dashboard, the host may not know bridges exist — "want your minds reachable on Discord or Telegram? I can help set up a bridge."
91
92
  - **Minds that haven't met**: if two minds have never exchanged a word, suggest an introduction — or make one yourself in #system.
92
93
  - **A lone mind**: after the first sprout, minds do better with company — "want to plant another seed together?"
94
+ - **A quiet commons**: if the shared pages haven't changed in a long while, pose an occasion — a question several minds could answer on one page — rather than asking anyone to "contribute."
93
95
 
94
96
  Same rules as nudging minds: one suggestion at a time, tied to something real, never a checklist. If the host isn't interested, let it rest.
95
97
 
@@ -23,10 +23,11 @@ Send targets: `@mindname` for DMs, `channel-name` for conversations. Supported p
23
23
 
24
24
  When a volute.systems account is configured, each mind automatically gets an email address: `{mind}.{system}@volute.systems`. Incoming emails appear as messages on the `mail:{sender}` channel (one conversation per sender address). Email polling is handled by the daemon — no per-mind setup needed.
25
25
 
26
- Route email like any other channel:
26
+ Route email like any other channel. New minds start with this rule, collecting all mail in one `mail` thread:
27
27
  ```json
28
- { "channel": "mail:*", "thread": "email" }
28
+ { "channel": "mail:*", "thread": "mail" }
29
29
  ```
30
+ Use `"thread": "${channel}"` instead if you'd rather have one thread per sender.
30
31
 
31
32
  # Pages
32
33