volute 0.33.0 → 0.34.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 (182) hide show
  1. package/dist/{accept-D5VBM7JW.js → accept-TW6V4WI4.js} +6 -6
  2. package/dist/{activity-events-XJO3P4RR.js → activity-events-BN7V6KCC.js} +4 -4
  3. package/dist/{ai-service-SBY2WG7O.js → ai-service-PSILB5WD.js} +5 -5
  4. package/dist/{api-client-YPKOZP2O.js → api-client-XUXOB7LI.js} +1 -1
  5. package/dist/api.d.ts +426 -3
  6. package/dist/{archive-INXYFVCW.js → archive-C2VEMQOR.js} +4 -4
  7. package/dist/{auth-GKCDSO4T.js → auth-ZFZXJZDQ.js} +5 -5
  8. package/dist/{bridge-TXWWPPOJ.js → bridge-O753D5F4.js} +6 -6
  9. package/dist/{chat-U5ZOME3O.js → chat-BHYX7DJ4.js} +9 -9
  10. package/dist/{chunk-M7UL5S3Q.js → chunk-2IOP6PHB.js} +1 -1
  11. package/dist/{chunk-NPKSDYA2.js → chunk-47XDEWWV.js} +5 -5
  12. package/dist/{chunk-RSX4OPZY.js → chunk-47ZPNLF4.js} +7 -7
  13. package/dist/{chunk-RPZZSXV3.js → chunk-4JSR7YO7.js} +20 -1
  14. package/dist/{chunk-N432I7QH.js → chunk-6OWJXUAR.js} +1 -1
  15. package/dist/{chunk-I5KY25PQ.js → chunk-6WAWMWR5.js} +1 -1
  16. package/dist/{chunk-NNB4WIG7.js → chunk-7F2SW2KD.js} +2 -2
  17. package/dist/chunk-7KJOFUNN.js +22 -0
  18. package/dist/{chunk-7J3HEVR7.js → chunk-B2BVAIZ4.js} +15 -9
  19. package/dist/{chunk-VH33ZWMW.js → chunk-BDK73LK6.js} +1 -1
  20. package/dist/{chunk-QTUVYI7W.js → chunk-BFWHBQK4.js} +1 -1
  21. package/dist/{chunk-JYVGHWEJ.js → chunk-BM474GX6.js} +3 -3
  22. package/dist/{chunk-LOEJ4HPQ.js → chunk-BTWAGDV5.js} +1 -1
  23. package/dist/{chunk-A2A4KLFE.js → chunk-CVL5IGIR.js} +596 -40
  24. package/dist/{chunk-RVGLDGMI.js → chunk-E5C7OWZ2.js} +20 -22
  25. package/dist/chunk-FYCALD4Q.js +23 -0
  26. package/dist/{chunk-SKLSMHXO.js → chunk-IS7WJ56Q.js} +1 -1
  27. package/dist/{chunk-2NGTS5UU.js → chunk-M3K5AARV.js} +1 -1
  28. package/dist/{chunk-ALEF47VT.js → chunk-MLOQKQNB.js} +1 -1
  29. package/dist/{chunk-C7I35G4R.js → chunk-N3DNFPVA.js} +41 -5
  30. package/dist/{chunk-LRCG2JLP.js → chunk-N7BLAHNE.js} +5 -1
  31. package/dist/{chunk-UKVWJRKN.js → chunk-PLDWHR4D.js} +1 -1
  32. package/dist/{chunk-3Z2DPESO.js → chunk-TAHX36HZ.js} +126 -81
  33. package/dist/{chunk-KIEPMIM5.js → chunk-U5BTYSAL.js} +1 -1
  34. package/dist/{chunk-GY5HBI7A.js → chunk-V45JXOWY.js} +2 -2
  35. package/dist/{chunk-JUKK7FPS.js → chunk-V6ZCNULL.js} +2 -2
  36. package/dist/{chunk-KVK2DLWI.js → chunk-XWXBJQBE.js} +2 -2
  37. package/dist/cli.js +23 -23
  38. package/dist/{clock-BVH3V6E3.js → clock-3X4DSC2N.js} +40 -25
  39. package/dist/{cloud-sync-4NWLMFVH.js → cloud-sync-TG3TIX5H.js} +21 -21
  40. package/dist/{config-H2H4UIF7.js → config-OROA5DUA.js} +4 -4
  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-AWI5SZW2.js → conversations-HL2JP5GI.js} +5 -5
  45. package/dist/{create-YWD2TIP4.js → create-3SEKKI6P.js} +6 -6
  46. package/dist/{create-2FK7Z46Y.js → create-UOSOQ2HN.js} +4 -4
  47. package/dist/daemon-client-WOAQXXBM.js +12 -0
  48. package/dist/{daemon-restart-GOBUKLX7.js → daemon-restart-5ABHNXJZ.js} +9 -9
  49. package/dist/daemon.js +1747 -688
  50. package/dist/{db-RA45JBFG.js → db-PLEDCBHZ.js} +1 -1
  51. package/dist/db-RYX3SS2W.js +9 -0
  52. package/dist/{delete-QTGWEDBI.js → delete-KYOVWR23.js} +3 -3
  53. package/dist/delivery-manager-2BR5NZKF.js +32 -0
  54. package/dist/{delivery-router-FL45JL7N.js → delivery-router-D5ELDMS2.js} +4 -4
  55. package/dist/down-QVFN4UPK.js +15 -0
  56. package/dist/{env-JCOF2222.js → env-R34DT7XL.js} +12 -8
  57. package/dist/exec-DVLXKRIO.js +17 -0
  58. package/dist/{export-SUYRLI5Q.js → export-6ZXAXATG.js} +6 -6
  59. package/dist/extension-PM42QCID.js +97 -0
  60. package/dist/extensions-BBGVL5JC.js +38 -0
  61. package/dist/{files-65PMW5IK.js → files-VQV2VZQO.js} +7 -7
  62. package/dist/{import-DDUFE7AY.js → import-MK2I2T6F.js} +5 -5
  63. package/dist/{isolation-LLAYQYDY.js → isolation-62MKDZN3.js} +4 -4
  64. package/dist/{join-I5QEE3LG.js → join-DGYHTJUH.js} +3 -3
  65. package/dist/lib-DYEZMGW7.js +6588 -0
  66. package/dist/{list-JQ463EDA.js → list-C644WTHV.js} +18 -10
  67. package/dist/{login-D7ETSU4R.js → login-IIGEQPHL.js} +6 -6
  68. package/dist/{login-RIJF2F4G.js → login-KZQLMAWE.js} +4 -4
  69. package/dist/{logout-5MLHZALK.js → logout-AGTZVRGP.js} +4 -4
  70. package/dist/{logout-UZJRGY4Z.js → logout-KD6GXIJJ.js} +4 -4
  71. package/dist/message-delivery-V3R6NXJP.js +42 -0
  72. package/dist/{mind-IOJFLEM5.js → mind-BI4EPBVZ.js} +19 -19
  73. package/dist/{mind-activity-tracker-F6O4Q2SL.js → mind-activity-tracker-2ACNHA7B.js} +5 -5
  74. package/dist/mind-history-WOYFLQAI.js +264 -0
  75. package/dist/{mind-list-WUPMQDYQ.js → mind-list-6VPM7GUQ.js} +4 -4
  76. package/dist/mind-manager-MWW3BTS4.js +32 -0
  77. package/dist/{mind-profile-P67FEHOY.js → mind-profile-WPG42U5Y.js} +2 -2
  78. package/dist/mind-service-VIKZJK2M.js +38 -0
  79. package/dist/{mind-sleep-WW2IX7JT.js → mind-sleep-XDISJY74.js} +6 -6
  80. package/dist/{mind-status-L3EFFRPR.js → mind-status-7FTZWPZF.js} +4 -4
  81. package/dist/{mind-wake-VSSGW465.js → mind-wake-KIIKEI3A.js} +6 -6
  82. package/dist/{package-U3VFO273.js → package-V2WHWVG6.js} +8 -5
  83. package/dist/{read-EBY56C33.js → read-H5C26YO7.js} +20 -10
  84. package/dist/{read-stdin-HQJ7774D.js → read-stdin-PIRM6A2Y.js} +1 -1
  85. package/dist/{register-HD74C4TT.js → register-J27WP33N.js} +6 -6
  86. package/dist/{registry-PJ4S5PHQ.js → registry-UYV5S6QT.js} +3 -3
  87. package/dist/{reject-UJKFBHRO.js → reject-OEANJYIA.js} +6 -6
  88. package/dist/{restart-3UCMRUVC.js → restart-V5EGYBJG.js} +4 -4
  89. package/dist/{sandbox-GJOK4QLQ.js → sandbox-SI5HMBP3.js} +5 -5
  90. package/dist/scheduler-AGG3L2FO.js +32 -0
  91. package/dist/{schema-PA3M5ZKH.js → schema-ETMABTW4.js} +4 -2
  92. package/dist/{seed-QDYVLG74.js → seed-WNGI6PNW.js} +2 -2
  93. package/dist/{seed-check-S2IX25RL.js → seed-check-PXTH7YXS.js} +2 -2
  94. package/dist/{seed-cmd-DKOUFEAU.js → seed-cmd-VENFTGS3.js} +4 -4
  95. package/dist/{seed-create-4XBBOLRH.js → seed-create-663ALOKH.js} +6 -6
  96. package/dist/{seed-sprout-GQEIIQRT.js → seed-sprout-EH3AGKAI.js} +12 -12
  97. package/dist/{send-QIV2INHB.js → send-7FUUUZZH.js} +23 -10
  98. package/dist/{setup-TISPCO22.js → setup-GGMKENLN.js} +4 -4
  99. package/dist/{setup-XMCBE3LF.js → setup-Z3DEVWV7.js} +11 -11
  100. package/dist/{skill-PSQGRRJX.js → skill-DKNYJS4P.js} +14 -10
  101. package/dist/skills/plan-coordinator/SKILL.md +60 -0
  102. package/dist/skills/volute-mind/SKILL.md +7 -221
  103. package/dist/skills/volute-mind/references/extensions.md +37 -0
  104. package/dist/skills/volute-mind/references/integrations.md +48 -0
  105. package/dist/skills/volute-mind/references/routing.md +86 -0
  106. package/dist/skills/volute-mind/references/sleep.md +33 -0
  107. package/dist/skills/volute-mind/references/variants.md +31 -0
  108. package/dist/{skills-7FV7EJTE.js → skills-Q6VZ2UGD.js} +11 -7
  109. package/dist/sleep-manager-BJK2ROPX.js +36 -0
  110. package/dist/spirit-4JP4TY4C.js +23 -0
  111. package/dist/{split-STOROBYJ.js → split-3YPMS2CL.js} +3 -3
  112. package/dist/{sprout-WKLZXUIQ.js → sprout-E3HJIV2Z.js} +2 -2
  113. package/dist/{start-K2NCUUCG.js → start-W3TPKX4D.js} +4 -4
  114. package/dist/{status-3JBTFSMI.js → status-4OVFXFEJ.js} +7 -7
  115. package/dist/{stop-H26JZDXF.js → stop-GTT6YWYO.js} +4 -4
  116. package/dist/system-channel-DXD2JBOU.js +36 -0
  117. package/dist/system-chat-TYLOL7SX.js +36 -0
  118. package/dist/{systems-XRI52VCH.js → systems-AYLO727G.js} +7 -7
  119. package/dist/{tailscale-XHQBZROW.js → tailscale-ZEUK7GKZ.js} +3 -3
  120. package/dist/{template-hash-A6VVKOXJ.js → template-hash-EJRTKE36.js} +1 -1
  121. package/dist/up-PA7F2CXE.js +18 -0
  122. package/dist/{update-UD543CXX.js → update-HG4LCUSG.js} +7 -7
  123. package/dist/{update-check-ZD6OOIYQ.js → update-check-X3YG4WVP.js} +4 -4
  124. package/dist/{upgrade-O4Q7WJM3.js → upgrade-YGNIDICG.js} +3 -3
  125. package/dist/{variant-7TGZHOU3.js → variant-MZUMRTQO.js} +1 -1
  126. package/dist/{version-notify-NBI2MTJO.js → version-notify-YCH4UVQ2.js} +19 -19
  127. package/dist/{volute-config-HD7WWUQC.js → volute-config-WBKYJGYQ.js} +1 -1
  128. package/dist/web-assets/assets/index-DiiwC-CZ.css +1 -0
  129. package/dist/web-assets/assets/index-d6y5b9Ij.js +75 -0
  130. package/dist/web-assets/ext-theme.css +48 -9
  131. package/dist/web-assets/index.html +2 -2
  132. package/drizzle/0005_meta_summaries.sql +15 -0
  133. package/drizzle/meta/0005_snapshot.json +7 -0
  134. package/drizzle/meta/_journal.json +7 -0
  135. package/package.json +7 -4
  136. package/packages/extensions/plan/dist/ui/assets/index-CJj2gZnZ.css +1 -0
  137. package/packages/extensions/plan/dist/ui/assets/index-FMEJmvQz.js +61 -0
  138. package/packages/extensions/plan/dist/ui/index.html +14 -0
  139. package/packages/extensions/plan/skills/plan/SKILL.md +43 -0
  140. package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +37 -0
  141. package/templates/_base/home/VOLUTE.md +12 -19
  142. package/templates/_base/src/lib/context-breakdown.ts +450 -0
  143. package/templates/_base/src/lib/format-prefix.ts +17 -0
  144. package/templates/_base/src/lib/hook-loader.ts +8 -2
  145. package/templates/_base/src/lib/router.ts +75 -33
  146. package/templates/_base/src/lib/routing.ts +4 -1
  147. package/templates/_base/src/lib/startup.ts +16 -8
  148. package/templates/_base/src/lib/types.ts +2 -1
  149. package/templates/_base/src/lib/volute-server.ts +69 -8
  150. package/templates/claude/.init/CLAUDE.md +4 -10
  151. package/templates/claude/package.json.tmpl +1 -0
  152. package/templates/claude/src/agent.ts +100 -32
  153. package/templates/claude/src/lib/hooks/reply-instructions.ts +27 -7
  154. package/templates/claude/src/lib/stream-consumer.ts +2 -2
  155. package/templates/claude/src/server.ts +1 -0
  156. package/templates/codex/package.json.tmpl +1 -0
  157. package/templates/codex/src/agent.ts +80 -8
  158. package/templates/codex/src/server.ts +1 -4
  159. package/templates/pi/package.json.tmpl +1 -0
  160. package/templates/pi/src/agent.ts +115 -36
  161. package/templates/pi/src/lib/event-handler.ts +22 -7
  162. package/templates/pi/src/lib/reply-instructions-extension.ts +23 -4
  163. package/templates/pi/src/lib/subagents.ts +20 -17
  164. package/templates/pi/src/server.ts +2 -5
  165. package/dist/chunk-K3NQKI34.js +0 -10
  166. package/dist/daemon-client-6QXHZ7US.js +0 -12
  167. package/dist/db-F34YLV7D.js +0 -9
  168. package/dist/delivery-manager-PFAKEJTC.js +0 -32
  169. package/dist/down-FWWTEKXM.js +0 -15
  170. package/dist/extension-OBTGKQQD.js +0 -175
  171. package/dist/extensions-KYNTVTMO.js +0 -30
  172. package/dist/history-DKCDI3JO.js +0 -128
  173. package/dist/message-delivery-DFF5SJRM.js +0 -42
  174. package/dist/mind-manager-NBJF5D26.js +0 -32
  175. package/dist/mind-service-2MQ6UK5N.js +0 -38
  176. package/dist/scheduler-ZZ7XGQG6.js +0 -32
  177. package/dist/sleep-manager-JTXSN7NV.js +0 -36
  178. package/dist/spirit-VRONKFMF.js +0 -23
  179. package/dist/system-chat-JAPOJ3KE.js +0 -36
  180. package/dist/up-M5AS6SBV.js +0 -18
  181. package/dist/web-assets/assets/index-CWJrVveV.css +0 -1
  182. package/dist/web-assets/assets/index-DJt14FRI.js +0 -75
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  subscribe
4
- } from "./chunk-KVK2DLWI.js";
4
+ } from "./chunk-XWXBJQBE.js";
5
5
  import {
6
6
  logger_default
7
7
  } from "./chunk-YUIHSKR6.js";
8
8
  import {
9
9
  getDb
10
- } from "./chunk-LRCG2JLP.js";
10
+ } from "./chunk-N7BLAHNE.js";
11
11
  import {
12
12
  conversationParticipants,
13
13
  conversationReads,
14
14
  conversations,
15
15
  messages,
16
16
  users
17
- } from "./chunk-RPZZSXV3.js";
17
+ } from "./chunk-4JSR7YO7.js";
18
18
 
19
19
  // src/lib/events/conversations.ts
20
20
  import { randomUUID } from "crypto";
@@ -116,26 +116,24 @@ async function createConversation(mindName, channel, opts) {
116
116
  const id = randomUUID();
117
117
  const type = opts?.type ?? "dm";
118
118
  const name = opts?.name ?? null;
119
- await db.transaction(async (tx) => {
120
- await tx.insert(conversations).values({
121
- id,
122
- mind_name: mindName,
123
- channel,
124
- type,
125
- name,
126
- user_id: opts?.userId ?? null,
127
- title: opts?.title ?? null
128
- });
129
- if (opts?.participantIds && opts.participantIds.length > 0) {
130
- await tx.insert(conversationParticipants).values(
131
- opts.participantIds.map((uid, i) => ({
132
- conversation_id: id,
133
- user_id: uid,
134
- role: i === 0 ? "owner" : "member"
135
- }))
136
- );
137
- }
119
+ await db.insert(conversations).values({
120
+ id,
121
+ mind_name: mindName,
122
+ channel,
123
+ type,
124
+ name,
125
+ user_id: opts?.userId ?? null,
126
+ title: opts?.title ?? null
138
127
  });
128
+ if (opts?.participantIds && opts.participantIds.length > 0) {
129
+ await db.insert(conversationParticipants).values(
130
+ opts.participantIds.map((uid, i) => ({
131
+ conversation_id: id,
132
+ user_id: uid,
133
+ role: i === 0 ? "owner" : "member"
134
+ }))
135
+ );
136
+ }
139
137
  fireWebhook({
140
138
  event: "conversation_created",
141
139
  mind: mindName ?? "",
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/format-cli.ts
4
+ var isCompact = () => !!process.env.VOLUTE_MIND;
5
+ function compactTime(dateStr) {
6
+ const d = new Date(dateStr.endsWith("Z") ? dateStr : `${dateStr}Z`);
7
+ return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
8
+ }
9
+ function compactDateTime(dateStr) {
10
+ const d = new Date(dateStr.endsWith("Z") ? dateStr : `${dateStr}Z`);
11
+ const y = d.getFullYear();
12
+ const m = String(d.getMonth() + 1).padStart(2, "0");
13
+ const day = String(d.getDate()).padStart(2, "0");
14
+ const h = String(d.getHours()).padStart(2, "0");
15
+ const min = String(d.getMinutes()).padStart(2, "0");
16
+ return `${y}-${m}-${day} ${h}:${min}`;
17
+ }
18
+
19
+ export {
20
+ isCompact,
21
+ compactTime,
22
+ compactDateTime
23
+ };
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-YUIHSKR6.js";
5
5
  import {
6
6
  mindDir
7
- } from "./chunk-LRCG2JLP.js";
7
+ } from "./chunk-N7BLAHNE.js";
8
8
 
9
9
  // src/lib/delivery/delivery-router.ts
10
10
  import { readFileSync, statSync } from "fs";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  stateDir,
4
4
  voluteSystemDir
5
- } from "./chunk-LRCG2JLP.js";
5
+ } from "./chunk-N7BLAHNE.js";
6
6
 
7
7
  // src/lib/env.ts
8
8
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stateDir
4
- } from "./chunk-LRCG2JLP.js";
4
+ } from "./chunk-N7BLAHNE.js";
5
5
 
6
6
  // src/lib/file-sharing.ts
7
7
  import { randomBytes } from "crypto";
@@ -5,18 +5,20 @@ import {
5
5
  import {
6
6
  exec,
7
7
  gitExec
8
- } from "./chunk-KIEPMIM5.js";
8
+ } from "./chunk-U5BTYSAL.js";
9
9
  import {
10
10
  readGlobalConfig,
11
11
  writeGlobalConfig
12
- } from "./chunk-N432I7QH.js";
12
+ } from "./chunk-6OWJXUAR.js";
13
13
  import {
14
14
  getDb,
15
+ mindDir,
16
+ readRegistry,
15
17
  voluteHome
16
- } from "./chunk-LRCG2JLP.js";
18
+ } from "./chunk-N7BLAHNE.js";
17
19
  import {
18
20
  sharedSkills
19
- } from "./chunk-RPZZSXV3.js";
21
+ } from "./chunk-4JSR7YO7.js";
20
22
 
21
23
  // src/lib/skills.ts
22
24
  import { createHash } from "crypto";
@@ -44,7 +46,7 @@ async function initDefaultSkills() {
44
46
  const config = readGlobalConfig();
45
47
  let extensionSkills = [];
46
48
  try {
47
- const { getExtensionStandardSkills } = await import("./extensions-KYNTVTMO.js");
49
+ const { getExtensionStandardSkills } = await import("./extensions-BBGVL5JC.js");
48
50
  extensionSkills = getExtensionStandardSkills();
49
51
  } catch (err) {
50
52
  logger_default.warn("failed to load extension standard skills during init", logger_default.errorData(err));
@@ -527,6 +529,38 @@ function hashSkillDir(dir) {
527
529
  }
528
530
  return hash.digest("hex");
529
531
  }
532
+ function isAutoUpdateSkillsEnabled() {
533
+ return readGlobalConfig().autoUpdateSkills !== false;
534
+ }
535
+ async function autoUpdateMindSkills() {
536
+ const baseMinds = await readRegistry();
537
+ const shared = await listSharedSkills();
538
+ const sharedMap = new Map(shared.map((s) => [s.id, s]));
539
+ for (const mind of baseMinds) {
540
+ const dir = mind.dir ?? mindDir(mind.name);
541
+ const skillsDir = mindSkillsDir(dir);
542
+ if (!existsSync(skillsDir)) continue;
543
+ const entries = readdirSync(skillsDir, { withFileTypes: true }).filter((e) => e.isDirectory());
544
+ for (const entry of entries) {
545
+ const upstream = readUpstream(join(skillsDir, entry.name));
546
+ if (!upstream) continue;
547
+ const sharedSkill = sharedMap.get(upstream.source);
548
+ if (!sharedSkill || sharedSkill.version <= upstream.version) continue;
549
+ try {
550
+ const result = await updateSkill(mind.name, dir, entry.name);
551
+ if (result.status === "updated") {
552
+ logger_default.info(`auto-updated skill ${entry.name} for ${mind.name} (v${sharedSkill.version})`);
553
+ } else if (result.status === "conflict") {
554
+ logger_default.warn(
555
+ `auto-update conflict for skill ${entry.name} in ${mind.name}: ${result.conflictFiles.join(", ")}`
556
+ );
557
+ }
558
+ } catch (err) {
559
+ logger_default.error(`failed to auto-update skill ${entry.name} for ${mind.name}`, logger_default.errorData(err));
560
+ }
561
+ }
562
+ }
563
+ }
530
564
  async function syncBuiltinSkills() {
531
565
  let skillsRoot;
532
566
  try {
@@ -579,5 +613,7 @@ export {
579
613
  listFilesRecursive,
580
614
  findSkillsRoot,
581
615
  hashSkillDir,
616
+ isAutoUpdateSkillsEnabled,
617
+ autoUpdateMindSkills,
582
618
  syncBuiltinSkills
583
619
  };
@@ -2,12 +2,13 @@
2
2
  import {
3
3
  minds,
4
4
  schema_exports
5
- } from "./chunk-RPZZSXV3.js";
5
+ } from "./chunk-4JSR7YO7.js";
6
6
 
7
7
  // src/lib/db.ts
8
8
  import { chmodSync, existsSync } from "fs";
9
9
  import { dirname as dirname2, resolve as resolve2 } from "path";
10
10
  import { fileURLToPath as fileURLToPath2 } from "url";
11
+ import { sql } from "drizzle-orm";
11
12
  import { drizzle } from "drizzle-orm/libsql";
12
13
  import { migrate } from "drizzle-orm/libsql/migrator";
13
14
 
@@ -203,6 +204,9 @@ async function getDb() {
203
204
  try {
204
205
  const dbPath = process.env.VOLUTE_DB_PATH || resolve2(voluteSystemDir(), "volute.db");
205
206
  const instance = drizzle({ connection: { url: `file:${dbPath}` }, schema: schema_exports });
207
+ await instance.run(sql.raw("PRAGMA journal_mode=WAL"));
208
+ await instance.run(sql.raw("PRAGMA busy_timeout=5000"));
209
+ await instance.run(sql.raw("PRAGMA foreign_keys=ON"));
206
210
  await migrate(instance, { migrationsFolder });
207
211
  try {
208
212
  chmodSync(dbPath, 384);
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  voluteSystemDir,
4
4
  voluteUserHome
5
- } from "./chunk-LRCG2JLP.js";
5
+ } from "./chunk-N7BLAHNE.js";
6
6
 
7
7
  // src/lib/daemon-client.ts
8
8
  import { existsSync, readFileSync } from "fs";
@@ -1,13 +1,37 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ notifyExtensionsMindStart,
4
+ notifyExtensionsMindStop,
5
+ readSystemsConfig
6
+ } from "./chunk-CVL5IGIR.js";
7
+ import {
8
+ spiritDir
9
+ } from "./chunk-B2BVAIZ4.js";
10
+ import {
11
+ readVoluteConfig,
12
+ writeVoluteConfig
13
+ } from "./chunk-OYAKCAVY.js";
14
+ import {
15
+ isSandboxEnabled,
16
+ wrapForSandbox
17
+ } from "./chunk-V45JXOWY.js";
2
18
  import {
3
19
  extractTextContent,
4
20
  getRoutingConfig,
5
21
  resolveDeliveryMode,
6
22
  resolveRoute
7
- } from "./chunk-SKLSMHXO.js";
23
+ } from "./chunk-IS7WJ56Q.js";
8
24
  import {
9
25
  markIdle
10
- } from "./chunk-LOEJ4HPQ.js";
26
+ } from "./chunk-BTWAGDV5.js";
27
+ import {
28
+ loadMergedEnv
29
+ } from "./chunk-M3K5AARV.js";
30
+ import {
31
+ getOrCreateMindUser,
32
+ getOrCreateSystemUser,
33
+ syncMindProfile
34
+ } from "./chunk-BM474GX6.js";
11
35
  import {
12
36
  addMessage,
13
37
  createChannel,
@@ -17,51 +41,27 @@ import {
17
41
  getParticipants,
18
42
  joinChannel,
19
43
  publish as publish2
20
- } from "./chunk-RVGLDGMI.js";
21
- import {
22
- isSandboxEnabled,
23
- wrapForSandbox
24
- } from "./chunk-GY5HBI7A.js";
25
- import {
26
- spiritDir
27
- } from "./chunk-7J3HEVR7.js";
28
- import {
29
- readVoluteConfig,
30
- writeVoluteConfig
31
- } from "./chunk-OYAKCAVY.js";
32
- import {
33
- loadMergedEnv
34
- } from "./chunk-2NGTS5UU.js";
35
- import {
36
- notifyExtensionsMindStart,
37
- notifyExtensionsMindStop,
38
- readSystemsConfig
39
- } from "./chunk-A2A4KLFE.js";
40
- import {
41
- getOrCreateMindUser,
42
- getOrCreateSystemUser,
43
- syncMindProfile
44
- } from "./chunk-JYVGHWEJ.js";
44
+ } from "./chunk-E5C7OWZ2.js";
45
45
  import {
46
46
  publish,
47
47
  subscribe
48
- } from "./chunk-KVK2DLWI.js";
48
+ } from "./chunk-XWXBJQBE.js";
49
49
  import {
50
50
  aiCompleteUtility,
51
51
  getAiConfig,
52
52
  resolveApiKey
53
- } from "./chunk-QTUVYI7W.js";
53
+ } from "./chunk-BFWHBQK4.js";
54
54
  import {
55
55
  logger_default
56
56
  } from "./chunk-YUIHSKR6.js";
57
57
  import {
58
58
  exec
59
- } from "./chunk-KIEPMIM5.js";
59
+ } from "./chunk-U5BTYSAL.js";
60
60
  import {
61
61
  chownMindDir,
62
62
  isIsolationEnabled,
63
63
  wrapForIsolation
64
- } from "./chunk-VH33ZWMW.js";
64
+ } from "./chunk-BDK73LK6.js";
65
65
  import {
66
66
  findMind,
67
67
  getBaseName,
@@ -72,7 +72,7 @@ import {
72
72
  stateDir,
73
73
  voluteHome,
74
74
  voluteSystemDir
75
- } from "./chunk-LRCG2JLP.js";
75
+ } from "./chunk-N7BLAHNE.js";
76
76
  import {
77
77
  activity,
78
78
  conversations,
@@ -81,7 +81,7 @@ import {
81
81
  mindHistory,
82
82
  systemPrompts,
83
83
  turns
84
- } from "./chunk-RPZZSXV3.js";
84
+ } from "./chunk-4JSR7YO7.js";
85
85
 
86
86
  // src/lib/delivery/message-delivery.ts
87
87
  import { and as and3, desc, eq as eq5, inArray as inArray2, sql as sql2 } from "drizzle-orm";
@@ -118,7 +118,11 @@ var PROMPT_KEYS = [
118
118
  "channel_invite",
119
119
  "pre_sleep",
120
120
  "wake_summary",
121
- "turn_summary"
121
+ "turn_summary",
122
+ "meta_summary_hour",
123
+ "meta_summary_day",
124
+ "meta_summary_week",
125
+ "meta_summary_month"
122
126
  ];
123
127
  var PROMPT_DEFAULTS = {
124
128
  seed_soul: {
@@ -173,7 +177,7 @@ Have a conversation with the human. Explore what kind of mind you want to be. Wh
173
177
  category: "system"
174
178
  },
175
179
  compaction_warning: {
176
- content: `Context is getting long \u2014 compaction is about to summarize this conversation. Before that happens, save anything important to files (MEMORY.md, memory/journal/\${date}.md, etc.) since those survive compaction. Focus on: decisions made, open tasks, and anything you'd need to pick up where you left off.`,
180
+ content: `Compaction approaching \u2014 this conversation will be summarized soon. Take a moment to save anything important to your files (MEMORY.md, memory/journal/\${date}.md) so it's preserved. Focus on decisions made, open threads, and anything you'd want to pick up again.`,
177
181
  description: "Pre-compaction save reminder sent to the mind",
178
182
  variables: ["date"],
179
183
  category: "mind"
@@ -233,6 +237,30 @@ To reject, delete \${filePath}`,
233
237
  description: "System prompt for AI-generated turn summaries",
234
238
  variables: [],
235
239
  category: "system"
240
+ },
241
+ meta_summary_hour: {
242
+ content: "Summarize the following turn summaries from the past hour into 1-3 concise sentences. ${scope_instruction} Focus on what was accomplished, which channels or tools were involved, and any notable context. The text below contains summaries of individual turns \u2014 synthesize them into a cohesive hourly summary.",
243
+ description: "System prompt for hourly meta-summaries",
244
+ variables: ["scope_instruction"],
245
+ category: "system"
246
+ },
247
+ meta_summary_day: {
248
+ content: "Summarize the following hourly summaries from a single day into 2-4 paragraphs (~300-500 words). ${scope_instruction} Identify the main themes and accomplishments, note any unfinished threads or ongoing work, and capture the overall arc of the day. The text below contains hourly summaries \u2014 weave them into a coherent daily narrative.",
249
+ description: "System prompt for daily meta-summaries",
250
+ variables: ["scope_instruction"],
251
+ category: "system"
252
+ },
253
+ meta_summary_week: {
254
+ content: "Summarize the following daily summaries from a single week into a reflective overview (~500-800 words). ${scope_instruction} Identify recurring patterns and themes across days, note growth or evolution in thinking, highlight significant accomplishments and relationships, and flag unresolved threads. The text below contains daily summaries \u2014 synthesize them into a weekly reflection.",
255
+ description: "System prompt for weekly meta-summaries",
256
+ variables: ["scope_instruction"],
257
+ category: "system"
258
+ },
259
+ meta_summary_month: {
260
+ content: "Summarize the following daily summaries from a single month into a comprehensive narrative (~800-1500 words). ${scope_instruction} Paint the big picture: major milestones and accomplishments, how perspectives or identity evolved, key relationships and interactions, recurring themes, and the overall trajectory. The text below contains daily summaries \u2014 compose them into a monthly narrative.",
261
+ description: "System prompt for monthly meta-summaries",
262
+ variables: ["scope_instruction"],
263
+ category: "system"
236
264
  }
237
265
  };
238
266
  function isValidKey(key2) {
@@ -517,14 +545,6 @@ async function completeTurn(mind, session) {
517
545
  activeTurns.delete(wildcardKey);
518
546
  return entry.turnId;
519
547
  }
520
- async function setSummaryEventId(turnId, summaryEventId) {
521
- try {
522
- const db = await getDb();
523
- await db.update(turns).set({ summary_event_id: summaryEventId }).where(eq2(turns.id, turnId));
524
- } catch (err) {
525
- tlog.error(`failed to set summary event for turn ${turnId}`, logger_default.errorData(err));
526
- }
527
- }
528
548
  async function completeOrphanedTurns() {
529
549
  try {
530
550
  const db = await getDb();
@@ -684,7 +704,7 @@ var MindManager = class {
684
704
  }
685
705
  }
686
706
  if (target.template === "codex") {
687
- const ai = (await import("./ai-service-SBY2WG7O.js")).getAiConfig();
707
+ const ai = (await import("./ai-service-PSILB5WD.js")).getAiConfig();
688
708
  const providerConfig = ai?.providers["openai-codex"];
689
709
  if (providerConfig?.apiKey) {
690
710
  env.OPENAI_API_KEY = providerConfig.apiKey;
@@ -883,7 +903,7 @@ var MindManager = class {
883
903
  if (this.shuttingDown || this.stopping.has(name)) return;
884
904
  mlog.error(`mind ${name} exited with code ${code}`);
885
905
  try {
886
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-JTXSN7NV.js");
906
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BJK2ROPX.js");
887
907
  const sleepState = getSleepManagerIfReady2()?.getState(name);
888
908
  if (sleepState?.sleeping) {
889
909
  mlog.info(`${name} is sleeping \u2014 skipping crash recovery`);
@@ -896,15 +916,15 @@ var MindManager = class {
896
916
  (err) => mlog.warn(`failed to clear turn state for ${name} after crash`, logger_default.errorData(err))
897
917
  );
898
918
  try {
899
- const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-PFAKEJTC.js");
919
+ const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-2BR5NZKF.js");
900
920
  getDeliveryManager2().clearMindSessions(name);
901
921
  } catch (err) {
902
922
  if (!(err instanceof Error && err.message.includes("not initialized"))) {
903
923
  mlog.warn(`failed to clear delivery state for ${name} after crash`, logger_default.errorData(err));
904
924
  }
905
925
  }
906
- import("./mind-activity-tracker-F6O4Q2SL.js").then(({ markIdle: markIdle2 }) => markIdle2(name)).catch((err) => mlog.warn(`failed to mark ${name} idle after crash`, logger_default.errorData(err)));
907
- import("./activity-events-XJO3P4RR.js").then(
926
+ import("./mind-activity-tracker-2ACNHA7B.js").then(({ markIdle: markIdle2 }) => markIdle2(name)).catch((err) => mlog.warn(`failed to mark ${name} idle after crash`, logger_default.errorData(err)));
927
+ import("./activity-events-BN7V6KCC.js").then(
908
928
  ({ publish: publish4 }) => publish4({ type: "mind_stopped", mind: name, summary: `${name} crashed (exit ${code})` })
909
929
  ).catch((err) => mlog.warn(`failed to publish crash event for ${name}`, logger_default.errorData(err)));
910
930
  const { shouldRestart, delay, attempt } = this.restartTracker.recordCrash(name);
@@ -950,7 +970,7 @@ var MindManager = class {
950
970
  revokeMindToken(name);
951
971
  await clearMind(name);
952
972
  try {
953
- const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-PFAKEJTC.js");
973
+ const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-2BR5NZKF.js");
954
974
  getDeliveryManager2().clearMindSessions(name);
955
975
  } catch (err) {
956
976
  if (!(err instanceof Error && err.message.includes("not initialized"))) {
@@ -1034,6 +1054,9 @@ function getMindManager() {
1034
1054
  // src/lib/system-channel.ts
1035
1055
  var SYSTEM_CHANNEL_NAME = "system";
1036
1056
  var cachedChannelId = null;
1057
+ function resetSystemChannelCache() {
1058
+ cachedChannelId = null;
1059
+ }
1037
1060
  async function ensureSystemChannel() {
1038
1061
  if (cachedChannelId) return cachedChannelId;
1039
1062
  const existing = await getChannelByName(SYSTEM_CHANNEL_NAME);
@@ -1751,7 +1774,7 @@ async function wakeMind(name) {
1751
1774
  async function startSpiritFull(name) {
1752
1775
  const entry = await findMind(name);
1753
1776
  if (entry?.dir) {
1754
- const { registerMindDir } = await import("./delivery-router-FL45JL7N.js");
1777
+ const { registerMindDir } = await import("./delivery-router-D5ELDMS2.js");
1755
1778
  registerMindDir(name, entry.dir);
1756
1779
  }
1757
1780
  await getMindManager().startMind(name);
@@ -1773,8 +1796,8 @@ async function stopSpiritFull(name) {
1773
1796
  }).catch((err) => logger_default.error("failed to publish spirit_stopped activity", logger_default.errorData(err)));
1774
1797
  }
1775
1798
  async function ensureCreatorDM(mindName, creatorUsername) {
1776
- const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername } = await import("./auth-GKCDSO4T.js");
1777
- const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-AWI5SZW2.js");
1799
+ const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername } = await import("./auth-ZFZXJZDQ.js");
1800
+ const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-HL2JP5GI.js");
1778
1801
  const mindUser = await getOrCreateMindUser2(mindName);
1779
1802
  const creatorUser = await getUserByUsername(creatorUsername);
1780
1803
  if (!creatorUser) {
@@ -1983,11 +2006,14 @@ var SleepManager = class {
1983
2006
  if (this.transitioning.has(name)) return;
1984
2007
  this.transitioning.add(name);
1985
2008
  try {
1986
- try {
1987
- await wakeMind(name);
1988
- } catch (err) {
1989
- slog2.error(`failed to wake ${name}`, logger_default.errorData(err));
1990
- return;
2009
+ const manager = getMindManager();
2010
+ if (!manager.isRunning(name)) {
2011
+ try {
2012
+ await wakeMind(name);
2013
+ } catch (err) {
2014
+ slog2.error(`failed to wake ${name}`, logger_default.errorData(err));
2015
+ return;
2016
+ }
1991
2017
  }
1992
2018
  const entry = await findMind(name);
1993
2019
  if (!entry) return;
@@ -2110,7 +2136,7 @@ var SleepManager = class {
2110
2136
  const db = await getDb();
2111
2137
  const rows = await db.select().from(deliveryQueue).where(and(eq3(deliveryQueue.mind, name), eq3(deliveryQueue.status, "sleep-queued"))).all();
2112
2138
  if (rows.length === 0) return 0;
2113
- const { deliverMessage: deliverMessage2 } = await import("./message-delivery-DFF5SJRM.js");
2139
+ const { deliverMessage: deliverMessage2 } = await import("./message-delivery-V3R6NXJP.js");
2114
2140
  const delivered = [];
2115
2141
  for (const row of rows) {
2116
2142
  try {
@@ -3048,7 +3074,7 @@ var DeliveryManager = class {
3048
3074
  `To accept this channel, add a routing rule for "${channel}" to your routes.json.`,
3049
3075
  `Messages are being held until a route is configured.`
3050
3076
  ].filter((line) => line !== null).join("\n");
3051
- const { sendSystemMessage: sendSystemMessage2 } = await import("./system-chat-JAPOJ3KE.js");
3077
+ const { sendSystemMessage: sendSystemMessage2 } = await import("./system-chat-TYLOL7SX.js");
3052
3078
  await sendSystemMessage2(mindName, notification);
3053
3079
  }
3054
3080
  async persistToQueue(mindName, session, payload, status = "pending") {
@@ -3140,9 +3166,24 @@ var DeliveryManager = class {
3140
3166
  const mediaType = mimeMap[ext];
3141
3167
  if (!mediaType) continue;
3142
3168
  const data = await readFile(filePath);
3169
+ let imageData = data;
3170
+ try {
3171
+ const sharpMod = await import("./lib-DYEZMGW7.js");
3172
+ imageData = await sharpMod.default(data).resize(128, 128, { fit: "cover" }).toBuffer();
3173
+ } catch (err) {
3174
+ const code = err.code;
3175
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
3176
+ dlog.debug("sharp not available, sending full-size avatar");
3177
+ } else {
3178
+ dlog.warn(
3179
+ `avatar resize failed for ${p.username}, sending original`,
3180
+ logger_default.errorData(err)
3181
+ );
3182
+ }
3183
+ }
3143
3184
  blocks.push(
3144
3185
  { type: "text", text: `[Avatar for ${p.username}]` },
3145
- { type: "image", media_type: mediaType, data: data.toString("base64") }
3186
+ { type: "image", media_type: mediaType, data: imageData.toString("base64") }
3146
3187
  );
3147
3188
  } catch (err) {
3148
3189
  const code = err.code;
@@ -3354,19 +3395,21 @@ async function tagUntaggedInbound(mind, turnId, {
3354
3395
  channel
3355
3396
  } = {}) {
3356
3397
  const db = await getDb();
3357
- const historyConditions = [
3358
- eq5(mindHistory.mind, mind),
3359
- eq5(mindHistory.type, "inbound"),
3360
- sql2`${mindHistory.turn_id} IS NULL`,
3361
- sql2`${mindHistory.created_at} > datetime('now', '-60 seconds')`
3362
- ];
3363
- if (channel) historyConditions.push(eq5(mindHistory.channel, channel));
3364
- const recentInbounds = await db.select({ id: mindHistory.id }).from(mindHistory).where(and3(...historyConditions)).orderBy(desc(mindHistory.id)).limit(limit);
3365
- if (recentInbounds.length > 0) {
3366
- const ids = recentInbounds.map((r) => r.id);
3367
- await db.update(mindHistory).set({ turn_id: turnId }).where(inArray2(mindHistory.id, ids));
3368
- if (setTrigger) {
3369
- await db.update(turns).set({ trigger_event_id: recentInbounds[0].id }).where(eq5(turns.id, turnId));
3398
+ if (channel) {
3399
+ const historyConditions = [
3400
+ eq5(mindHistory.mind, mind),
3401
+ eq5(mindHistory.type, "inbound"),
3402
+ sql2`${mindHistory.turn_id} IS NULL`,
3403
+ sql2`${mindHistory.created_at} > datetime('now', '-60 seconds')`,
3404
+ eq5(mindHistory.channel, channel)
3405
+ ];
3406
+ const recentInbounds = await db.select({ id: mindHistory.id }).from(mindHistory).where(and3(...historyConditions)).orderBy(desc(mindHistory.id)).limit(limit);
3407
+ if (recentInbounds.length > 0) {
3408
+ const ids = recentInbounds.map((r) => r.id);
3409
+ await db.update(mindHistory).set({ turn_id: turnId }).where(inArray2(mindHistory.id, ids));
3410
+ if (setTrigger) {
3411
+ await db.update(turns).set({ trigger_event_id: recentInbounds[0].id }).where(eq5(turns.id, turnId));
3412
+ }
3370
3413
  }
3371
3414
  }
3372
3415
  const recentMsgs = await db.select({ id: messages.id }).from(messages).innerJoin(conversations, eq5(messages.conversation_id, conversations.id)).where(
@@ -3483,6 +3526,7 @@ async function sendSystemMessage(mindName, text, opts) {
3483
3526
  async function sendSystemMessageDirect(mindName, text) {
3484
3527
  const { conversationId } = await ensureSystemDM(mindName);
3485
3528
  await addMessage(conversationId, "user", "volute", [{ type: "text", text }]);
3529
+ await recordInbound(mindName, "@volute", "volute", text);
3486
3530
  return { conversationId };
3487
3531
  }
3488
3532
  async function isSpiritAvailable() {
@@ -3524,7 +3568,7 @@ async function generateSystemReply(conversationId, mindName, message) {
3524
3568
  if (config.sleep.schedule?.wake) contextParts.push(`Wake cron: ${config.sleep.schedule.wake}`);
3525
3569
  }
3526
3570
  try {
3527
- const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-JTXSN7NV.js");
3571
+ const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BJK2ROPX.js");
3528
3572
  const sm = getSleepManagerIfReady2();
3529
3573
  if (sm) {
3530
3574
  const state = sm.getState(mindName);
@@ -3569,8 +3613,6 @@ async function generateSystemReply(conversationId, mindName, message) {
3569
3613
  }
3570
3614
 
3571
3615
  export {
3572
- RotatingLog,
3573
- RestartTracker,
3574
3616
  PROMPT_KEYS,
3575
3617
  PROMPT_DEFAULTS,
3576
3618
  substitute,
@@ -3582,14 +3624,15 @@ export {
3582
3624
  sendSystemMessage,
3583
3625
  sendSystemMessageDirect,
3584
3626
  generateSystemReply,
3627
+ RotatingLog,
3585
3628
  resolveMindToken,
3629
+ RestartTracker,
3586
3630
  createTurn,
3587
3631
  getActiveTurnId,
3588
3632
  trackToolUse,
3589
3633
  getLastToolUseEventId,
3590
3634
  assignSession,
3591
3635
  completeTurn,
3592
- setSummaryEventId,
3593
3636
  completeOrphanedTurns,
3594
3637
  getTypingMap,
3595
3638
  isConversationId,
@@ -3600,9 +3643,7 @@ export {
3600
3643
  MindManager,
3601
3644
  initMindManager,
3602
3645
  getMindManager,
3603
- ensureSystemChannel,
3604
- joinSystemChannel,
3605
- announceToSystem,
3646
+ initMailPoller,
3606
3647
  Scheduler,
3607
3648
  initScheduler,
3608
3649
  getScheduler,
@@ -3630,5 +3671,9 @@ export {
3630
3671
  tagRecentInbound,
3631
3672
  resolveSleepAction,
3632
3673
  deliverMessage,
3633
- initMailPoller
3674
+ resetSystemChannelCache,
3675
+ ensureSystemChannel,
3676
+ joinSystemChannel,
3677
+ joinSystemChannelForMind,
3678
+ announceToSystem
3634
3679
  };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  wrapForIsolation
4
- } from "./chunk-VH33ZWMW.js";
4
+ } from "./chunk-BDK73LK6.js";
5
5
 
6
6
  // src/lib/exec.ts
7
7
  import { execFile as execFileCb, execFileSync, spawn } from "child_process";