volute 0.45.2 → 0.47.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 (146) hide show
  1. package/README.md +4 -4
  2. package/dist/{activity-events-BUR2RYTJ.js → activity-events-MIOK3IOU.js} +3 -3
  3. package/dist/{ai-service-UODCCE4O.js → ai-service-CVZEYKTK.js} +4 -4
  4. package/dist/{archive-WS2L2VIQ.js → archive-6Z4GFQPH.js} +3 -3
  5. package/dist/{auth-FLAEXXZK.js → auth-A4VGHADI.js} +4 -4
  6. package/dist/avatar-image-7S3WA77A.js +22 -0
  7. package/dist/{backup-TST5C2YN.js → backup-IIAFOW2L.js} +13 -13
  8. package/dist/channels-ITE4YC57.js +89 -0
  9. package/dist/{chat-76MRWWQX.js → chat-AJLJCQ3M.js} +12 -8
  10. package/dist/{chunk-ZV7MFISX.js → chunk-2MJ7EOMT.js} +20 -2
  11. package/dist/{chunk-R77O2WMK.js → chunk-2OIYNHWO.js} +1 -1
  12. package/dist/{chunk-QCN24XEN.js → chunk-3YUBFTDN.js} +1 -1
  13. package/dist/{chunk-NYC5U6K7.js → chunk-4I72V3E5.js} +10 -10
  14. package/dist/{chunk-QNQMSWZE.js → chunk-5IERLDUS.js} +3 -3
  15. package/dist/{chunk-FXORA5JG.js → chunk-5NN2VHJV.js} +3 -3
  16. package/dist/chunk-7KRIHYLR.js +124 -0
  17. package/dist/{chunk-RRNXJOKB.js → chunk-BGYHLR54.js} +2 -2
  18. package/dist/{chunk-QMJCNZ6C.js → chunk-C3KLHJDB.js} +1 -1
  19. package/dist/{chunk-TQJ6ZYVY.js → chunk-CBOIHNMR.js} +2 -2
  20. package/dist/{chunk-H2X54EHC.js → chunk-DGGZVZTM.js} +1 -1
  21. package/dist/{chunk-4JOQZPCE.js → chunk-EIQDZC43.js} +1 -1
  22. package/dist/{chunk-YT7PEESJ.js → chunk-F55GRIEK.js} +464 -221
  23. package/dist/{chunk-OP4JG2BS.js → chunk-HPGN6XRT.js} +8 -4
  24. package/dist/{chunk-7ZUB63PS.js → chunk-IWJSNMSY.js} +5 -5
  25. package/dist/{chunk-ZDZISKCL.js → chunk-IYG4FBMP.js} +1 -1
  26. package/dist/chunk-JCMGDCGX.js +237 -0
  27. package/dist/{clock-K43IMROX.js → chunk-JSVHH32K.js} +26 -21
  28. package/dist/{chunk-UYLGEDVD.js → chunk-K23P5Q5N.js} +340 -339
  29. package/dist/{chunk-7C44R625.js → chunk-LTLFOSA4.js} +49 -3
  30. package/dist/{chunk-IHKGWTGT.js → chunk-LWDTP6DH.js} +1 -1
  31. package/dist/{chunk-JZ62SYWR.js → chunk-M3XDVS5Q.js} +1 -1
  32. package/dist/{chunk-FR6S2KNN.js → chunk-M6TTZRGH.js} +9 -9
  33. package/dist/{chunk-EJVPTVTI.js → chunk-MTRMQFCQ.js} +1 -1
  34. package/dist/{chunk-T6HYVHPG.js → chunk-ODDGGLM6.js} +3 -3
  35. package/dist/{chunk-QLWG3C2Z.js → chunk-RRZ4RQQU.js} +2 -2
  36. package/dist/{chunk-CDPBTTZO.js → chunk-RUFLGTOT.js} +2 -2
  37. package/dist/{chunk-F7H6ATM4.js → chunk-SKNXMUIU.js} +1 -1
  38. package/dist/{chunk-RXEEYDIB.js → chunk-SZJCJVXV.js} +1 -1
  39. package/dist/{chunk-DRJ24GXK.js → chunk-VMCZBXF2.js} +52 -8
  40. package/dist/{chunk-ALKYQULU.js → chunk-WW6C3PLV.js} +1 -1
  41. package/dist/{chunk-A7WQZKOU.js → chunk-XHN6XBWV.js} +2 -2
  42. package/dist/{chunk-6EMWJZBK.js → chunk-YKA7DCVW.js} +1 -1
  43. package/dist/cli.js +24 -24
  44. package/dist/clock-E6N5Y3YW.js +16 -0
  45. package/dist/{cloud-sync-3OJOPZRT.js → cloud-sync-LQTVDTQ3.js} +19 -17
  46. package/dist/{conversations-JZTD6KLR.js → conversations-C7IKYSHD.js} +4 -4
  47. package/dist/{create-IOV4GCRX.js → create-PQQXKTJK.js} +1 -1
  48. package/dist/{daemon-restart-TIHKVVVA.js → daemon-restart-5F3YTLZK.js} +7 -7
  49. package/dist/daemon.js +418 -273
  50. package/dist/{db-MF2JNRUW.js → db-FO6LXYCW.js} +2 -2
  51. package/dist/{delete-BFMIGAIB.js → delete-HPLC7ETU.js} +1 -1
  52. package/dist/delivery-manager-TN5KK2AP.js +34 -0
  53. package/dist/{delivery-router-N4A7ZC5T.js → delivery-router-3QFG2ZEX.js} +3 -3
  54. package/dist/{down-U2CZ23M4.js → down-ZI4S6265.js} +5 -5
  55. package/dist/echo-text-SEQCLGAT.js +34 -0
  56. package/dist/{exec-G3ZRST4Z.js → exec-QIFYZG4C.js} +3 -3
  57. package/dist/{export-GGIVO76O.js → export-4GVGNW54.js} +6 -6
  58. package/dist/{extensions-JONTW2HF.js → extensions-PIMIQ7J3.js} +21 -17
  59. package/dist/{files-4LN3EN7Q.js → files-FEFZKMNM.js} +6 -6
  60. package/dist/{import-42YNQBF4.js → import-7MO3YTRE.js} +6 -6
  61. package/dist/{isolation-YMGZZ4E5.js → isolation-MCT4ZYLT.js} +3 -3
  62. package/dist/{login-M6OJUPQ2.js → login-OF4WXDAN.js} +5 -5
  63. package/dist/{logout-WQBWO77G.js → logout-ERE2BGA3.js} +5 -5
  64. package/dist/message-delivery-ZE3YGJDD.js +38 -0
  65. package/dist/{mind-DWB6XYCH.js → mind-POOHFZHP.js} +18 -18
  66. package/dist/{mind-activity-tracker-POBLU3LC.js → mind-activity-tracker-YVZPC4A5.js} +4 -4
  67. package/dist/{mind-list-4D7J4CHD.js → mind-list-KEGRGQEQ.js} +5 -4
  68. package/dist/mind-service-JFY7UG5E.js +40 -0
  69. package/dist/mind-sleep-IN3WPA76.js +83 -0
  70. package/dist/{mind-status-UO34ASXZ.js → mind-status-SMUWJKGV.js} +20 -3
  71. package/dist/{package-A7KXT67Q.js → package-WPEE2HVJ.js} +3 -2
  72. package/dist/{registry-OUZBZ3Q4.js → registry-UMMDRPRM.js} +2 -2
  73. package/dist/{sandbox-ZJ7QA6Z6.js → sandbox-G4X4K3UN.js} +4 -4
  74. package/dist/scheduler-HQSDYJFY.js +32 -0
  75. package/dist/{schema-PVNG3PQM.js → schema-VEVO7HG6.js} +3 -1
  76. package/dist/{seed-HCP5NYKH.js → seed-VANPU43L.js} +1 -1
  77. package/dist/{seed-cmd-ILOGNIFB.js → seed-cmd-SYVDZKM4.js} +2 -2
  78. package/dist/{seed-create-OURS2LS4.js → seed-create-3FGZPS6C.js} +5 -5
  79. package/dist/{seed-sprout-ELDFDAN6.js → seed-sprout-H7QLFPFM.js} +13 -11
  80. package/dist/{send-AAIOPJAV.js → send-HYDFGC6G.js} +13 -7
  81. package/dist/{service-UOCLXDWR.js → service-SYJ5G6LP.js} +4 -4
  82. package/dist/{service-install-4HHFDDWY.js → service-install-FQ43Z4DF.js} +5 -5
  83. package/dist/{setup-Y2EJI3GG.js → setup-KFYVWTXG.js} +3 -3
  84. package/dist/{setup-DQM5VPY4.js → setup-QJHGMGSN.js} +7 -7
  85. package/dist/skills/orientation/SKILL.md +1 -1
  86. package/dist/skills/volute-mind/SKILL.md +8 -8
  87. package/dist/skills/volute-mind/references/sleep.md +8 -1
  88. package/dist/{skills-BKINFL7W.js → skills-L2CMTW7A.js} +5 -5
  89. package/dist/sleep-manager-3NA7ZJP3.js +36 -0
  90. package/dist/{spirit-DBTIW7P4.js → spirit-WXN4IDBF.js} +8 -8
  91. package/dist/{sprout-W3KC7UGK.js → sprout-LTL5P36T.js} +1 -1
  92. package/dist/{status-SWRVGXBI.js → status-V4RJMHJ4.js} +19 -9
  93. package/dist/system-chat-N2F7HVY3.js +38 -0
  94. package/dist/{systems-VNB5WKSS.js → systems-B5YJKMW4.js} +6 -6
  95. package/dist/{tailscale-3XOKOW7T.js → tailscale-MCLY5GYE.js} +2 -2
  96. package/dist/{template-hash-446HHH5V.js → template-hash-GSOUARW4.js} +2 -2
  97. package/dist/template-staleness-EMQORSGG.js +15 -0
  98. package/dist/{turn-tracker-2W6Q2NSR.js → turn-tracker-JZRZDFWV.js} +6 -5
  99. package/dist/{up-FTK7CTO3.js → up-J2PBPOZL.js} +6 -6
  100. package/dist/{update-SWAYZRWJ.js → update-ACV4SAY3.js} +5 -5
  101. package/dist/{update-check-PQ2MZ47K.js → update-check-266R4ZSY.js} +3 -3
  102. package/dist/{version-notify-3XMAIQTE.js → version-notify-XRGTEEDK.js} +42 -23
  103. package/dist/web-assets/assets/index-DtctoDXY.css +1 -0
  104. package/dist/web-assets/assets/index-Wpyb2CML.js +86 -0
  105. package/dist/web-assets/index.html +2 -2
  106. package/drizzle/0011_drop_turn_summary_event_id.sql +3 -0
  107. package/drizzle/0012_channel_gates.sql +17 -0
  108. package/drizzle/meta/_journal.json +14 -0
  109. package/package.json +3 -2
  110. package/templates/_base/home/VOLUTE.md +6 -2
  111. package/templates/_base/src/lib/context-breakdown.ts +57 -67
  112. package/templates/_base/src/lib/startup.ts +43 -2
  113. package/templates/_base/src/lib/volute-server.ts +2 -2
  114. package/templates/claude/src/agent.ts +105 -43
  115. package/templates/claude/src/lib/session-reaper.ts +63 -0
  116. package/templates/claude/src/server.ts +10 -1
  117. package/templates/codex/src/agent.ts +62 -40
  118. package/templates/pi/src/agent.ts +55 -38
  119. package/dist/avatar-image-6KY6UU4D.js +0 -16
  120. package/dist/delivery-manager-VDVKVA46.js +0 -32
  121. package/dist/echo-text-6JJOPUD4.js +0 -32
  122. package/dist/message-delivery-3C65ZI6L.js +0 -34
  123. package/dist/mind-service-3F4I46CI.js +0 -36
  124. package/dist/mind-sleep-YMBR3I35.js +0 -47
  125. package/dist/scheduler-P6DXLLXI.js +0 -30
  126. package/dist/sleep-manager-HCUH4PM4.js +0 -34
  127. package/dist/system-chat-XOALE2RD.js +0 -36
  128. package/dist/web-assets/assets/index-B1JBQv2m.css +0 -1
  129. package/dist/web-assets/assets/index-Bc2m8gRC.js +0 -86
  130. package/dist/{accept-N5XULCXK.js → accept-YAFP5JFJ.js} +3 -3
  131. package/dist/{bridge-2PO3AI5D.js → bridge-TIZGSXOD.js} +3 -3
  132. package/dist/{create-DF3KISTW.js → create-A7PDHIIL.js} +3 -3
  133. package/dist/{env-VZ4MLFQW.js → env-HRL2PWAT.js} +5 -5
  134. package/dist/{extension-SEID47SR.js → extension-QBY4C44L.js} +3 -3
  135. package/dist/{list-OXIAY3W7.js → list-LQO2DCIK.js} +3 -3
  136. package/dist/{login-MY6ETFYB.js → login-6TLMI2TQ.js} +3 -3
  137. package/dist/{logout-NCG3TMDL.js → logout-BK53HXNY.js} +3 -3
  138. package/dist/{mind-history-VRO5A76U.js → mind-history-47DN6ILW.js} +4 -4
  139. package/dist/{mind-wake-LCLGTXA2.js → mind-wake-R54BPESY.js} +3 -3
  140. package/dist/{read-QVAXMTPV.js → read-PWAJOQIQ.js} +3 -3
  141. package/dist/{register-Y2H4PY5R.js → register-7SZJFHU6.js} +3 -3
  142. package/dist/{reject-EV35X64Y.js → reject-6VH7N2A4.js} +3 -3
  143. package/dist/{restart-FJQ662XJ.js → restart-H5WJDMA7.js} +4 -4
  144. package/dist/{skill-FKFHIJRR.js → skill-GUKG2YVH.js} +5 -5
  145. package/dist/{start-5JE3TV66.js → start-X46I3GXB.js} +4 -4
  146. package/dist/{stop-AAMTG3TU.js → stop-HJQV4YSM.js} +4 -4
@@ -4,10 +4,46 @@ import {
4
4
  } from "./chunk-T2TP6ZC6.js";
5
5
  import {
6
6
  getDb
7
- } from "./chunk-ALKYQULU.js";
7
+ } from "./chunk-WW6C3PLV.js";
8
8
  import {
9
9
  activity
10
- } from "./chunk-ZV7MFISX.js";
10
+ } from "./chunk-2MJ7EOMT.js";
11
+
12
+ // packages/daemon/src/lib/events/event-sequencer.ts
13
+ var BUFFER_SIZE = 1e3;
14
+ var MAX_AGE_MS = 5 * 60 * 1e3;
15
+ var nextId = 1;
16
+ var buffer = [];
17
+ function bufferEvent(data) {
18
+ const id = nextId++;
19
+ buffer.push({ id, data, timestamp: Date.now() });
20
+ while (buffer.length > BUFFER_SIZE) {
21
+ buffer.shift();
22
+ }
23
+ return id;
24
+ }
25
+ function nextEventId() {
26
+ return nextId++;
27
+ }
28
+ function getEventsSince(sinceId, allowedConversationIds, allowedActivityMind) {
29
+ const now = Date.now();
30
+ const startIdx = buffer.findIndex((e) => e.id > sinceId);
31
+ if (startIdx === -1) return [];
32
+ return buffer.slice(startIdx).filter((e) => {
33
+ if (now - e.timestamp >= MAX_AGE_MS) return false;
34
+ const data = e.data;
35
+ switch (data.event) {
36
+ case "snapshot":
37
+ return false;
38
+ case "conversation":
39
+ return allowedConversationIds.has(data.conversationId);
40
+ case "activity":
41
+ return allowedActivityMind === void 0 || data.mind === allowedActivityMind;
42
+ default:
43
+ return false;
44
+ }
45
+ });
46
+ }
11
47
 
12
48
  // packages/daemon/src/lib/events/activity-events.ts
13
49
  var subscribers = /* @__PURE__ */ new Set();
@@ -44,9 +80,16 @@ function broadcast(event) {
44
80
  notify({ ...event, id: 0, created_at });
45
81
  }
46
82
  function notify(event) {
83
+ const data = {
84
+ event: "activity",
85
+ ...event,
86
+ metadata: event.metadata ?? null
87
+ };
88
+ const seq = bufferEvent(data);
89
+ const delivered = { ...event, seq };
47
90
  for (const cb of subscribers) {
48
91
  try {
49
- cb(event);
92
+ cb(delivered);
50
93
  } catch (err) {
51
94
  logger_default.error("[activity-events] subscriber threw:", logger_default.errorData(err));
52
95
  subscribers.delete(cb);
@@ -55,6 +98,9 @@ function notify(event) {
55
98
  }
56
99
 
57
100
  export {
101
+ bufferEvent,
102
+ nextEventId,
103
+ getEventsSince,
58
104
  subscribe,
59
105
  publish,
60
106
  broadcast
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  readGlobalConfig,
4
4
  writeGlobalConfig
5
- } from "./chunk-F7H6ATM4.js";
5
+ } from "./chunk-SKNXMUIU.js";
6
6
  import {
7
7
  logger_default
8
8
  } from "./chunk-T2TP6ZC6.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readGlobalConfig
4
- } from "./chunk-F7H6ATM4.js";
4
+ } from "./chunk-SKNXMUIU.js";
5
5
  import {
6
6
  logger_default
7
7
  } from "./chunk-T2TP6ZC6.js";
@@ -5,27 +5,27 @@ import {
5
5
  copyTemplateToDir,
6
6
  findTemplatesRoot,
7
7
  renderComposedPackageJson
8
- } from "./chunk-QLWG3C2Z.js";
8
+ } from "./chunk-RRZ4RQQU.js";
9
9
  import {
10
10
  getSharedSkill,
11
11
  installSkill,
12
12
  mindSkillsDir
13
- } from "./chunk-7ZUB63PS.js";
13
+ } from "./chunk-IWJSNMSY.js";
14
14
  import {
15
15
  readVoluteConfig,
16
16
  writeVoluteConfig
17
17
  } from "./chunk-PFZBNKUH.js";
18
18
  import {
19
19
  exec
20
- } from "./chunk-H2X54EHC.js";
20
+ } from "./chunk-DGGZVZTM.js";
21
21
  import {
22
22
  qualifyModelId,
23
23
  resolveTemplate,
24
24
  unqualifyModelId
25
- } from "./chunk-IHKGWTGT.js";
25
+ } from "./chunk-LWDTP6DH.js";
26
26
  import {
27
27
  readGlobalConfig
28
- } from "./chunk-F7H6ATM4.js";
28
+ } from "./chunk-SKNXMUIU.js";
29
29
  import {
30
30
  logger_default
31
31
  } from "./chunk-T2TP6ZC6.js";
@@ -34,7 +34,7 @@ import {
34
34
  findMind,
35
35
  nextPort,
36
36
  voluteSystemDir
37
- } from "./chunk-ALKYQULU.js";
37
+ } from "./chunk-WW6C3PLV.js";
38
38
 
39
39
  // packages/daemon/src/lib/mind/spirit.ts
40
40
  import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
@@ -130,7 +130,7 @@ async function ensureSpiritProject() {
130
130
  } catch (err) {
131
131
  slog.warn("failed to add tending schedule to spirit config", logger_default.errorData(err));
132
132
  }
133
- const { createMindUser, chownMindDir, ensureVoluteGroup } = await import("./isolation-YMGZZ4E5.js");
133
+ const { createMindUser, chownMindDir, ensureVoluteGroup } = await import("./isolation-MCT4ZYLT.js");
134
134
  ensureVoluteGroup();
135
135
  createMindUser("volute", resolve(dir, "home"));
136
136
  await chownMindDir(dir, "volute");
@@ -164,8 +164,8 @@ async function syncSpiritTemplate() {
164
164
  cpSync(newPkg, resolve(dir, "package.json"));
165
165
  await exec("npm", ["install"], { cwd: dir, env: npmEnv() });
166
166
  }
167
- const db = await (await import("./db-MF2JNRUW.js")).getDb();
168
- const { minds } = await import("./schema-PVNG3PQM.js");
167
+ const db = await (await import("./db-FO6LXYCW.js")).getDb();
168
+ const { minds } = await import("./schema-VEVO7HG6.js");
169
169
  const { eq } = await import("drizzle-orm");
170
170
  await db.update(minds).set({ template: expectedTemplate }).where(eq(minds.name, "volute"));
171
171
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  publish
4
- } from "./chunk-7C44R625.js";
4
+ } from "./chunk-LTLFOSA4.js";
5
5
  import {
6
6
  logger_default
7
7
  } from "./chunk-T2TP6ZC6.js";
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  broadcast
4
- } from "./chunk-7C44R625.js";
4
+ } from "./chunk-LTLFOSA4.js";
5
5
  import {
6
6
  getDb
7
- } from "./chunk-ALKYQULU.js";
7
+ } from "./chunk-WW6C3PLV.js";
8
8
  import {
9
9
  users
10
- } from "./chunk-ZV7MFISX.js";
10
+ } from "./chunk-2MJ7EOMT.js";
11
11
 
12
12
  // packages/daemon/src/lib/auth.ts
13
13
  import { compareSync, hashSync } from "bcryptjs";
@@ -5,6 +5,7 @@ import {
5
5
  cpSync,
6
6
  existsSync,
7
7
  mkdirSync,
8
+ mkdtempSync,
8
9
  readdirSync,
9
10
  readFileSync,
10
11
  renameSync,
@@ -43,8 +44,7 @@ function composeTemplate(templatesRoot, templateName) {
43
44
  console.error(`Template not found: ${templateName}`);
44
45
  process.exit(1);
45
46
  }
46
- const composedDir = resolve(tmpdir(), `volute-template-${templateName}-${Date.now()}`);
47
- mkdirSync(composedDir, { recursive: true });
47
+ const composedDir = mkdtempSync(resolve(tmpdir(), `volute-template-${templateName}-`));
48
48
  cpSync(baseDir, composedDir, { recursive: true });
49
49
  for (const file of listFiles(templateDir)) {
50
50
  const src = resolve(templateDir, file);
@@ -3,10 +3,10 @@ import {
3
3
  LAUNCHD_PLIST_LABEL,
4
4
  LAUNCHD_PLIST_PATH,
5
5
  USER_SYSTEMD_UNIT
6
- } from "./chunk-TQJ6ZYVY.js";
6
+ } from "./chunk-CBOIHNMR.js";
7
7
  import {
8
8
  resolveVoluteBin
9
- } from "./chunk-H2X54EHC.js";
9
+ } from "./chunk-DGGZVZTM.js";
10
10
 
11
11
  // packages/daemon/src/lib/config/service-install.ts
12
12
  import { execFile } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteSystemDir
4
- } from "./chunk-ALKYQULU.js";
4
+ } from "./chunk-WW6C3PLV.js";
5
5
 
6
6
  // packages/daemon/src/lib/config/setup.ts
7
7
  import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-T2TP6ZC6.js";
5
5
  import {
6
6
  voluteSystemDir
7
- } from "./chunk-ALKYQULU.js";
7
+ } from "./chunk-WW6C3PLV.js";
8
8
 
9
9
  // packages/daemon/src/lib/bridges/bridges.ts
10
10
  import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -9,11 +9,11 @@ import {
9
9
  mindDir,
10
10
  readAllMinds,
11
11
  voluteHome
12
- } from "./chunk-ALKYQULU.js";
12
+ } from "./chunk-WW6C3PLV.js";
13
13
 
14
14
  // packages/daemon/src/lib/util/avatar-image.ts
15
15
  import { readdir, readFile, writeFile } from "fs/promises";
16
- import { resolve as resolve2 } from "path";
16
+ import { extname, resolve as resolve2 } from "path";
17
17
 
18
18
  // packages/daemon/src/lib/util/paths.ts
19
19
  import { resolve, sep } from "path";
@@ -42,16 +42,31 @@ function safeResolveWithinBase(base, userPath) {
42
42
  // packages/daemon/src/lib/util/avatar-image.ts
43
43
  var alog = logger_default.child("avatar-image");
44
44
  var AVATAR_DIM = 256;
45
+ var AVATAR_CONTEXT_DIM = 128;
46
+ var MAX_AVATAR_BLOCK_BYTES = 64 * 1024;
47
+ var MIME_BY_EXT = {
48
+ ".png": "image/png",
49
+ ".jpg": "image/jpeg",
50
+ ".jpeg": "image/jpeg",
51
+ ".gif": "image/gif",
52
+ ".webp": "image/webp"
53
+ };
54
+ var warnedSharpUnavailable = false;
45
55
  async function loadSharp() {
46
56
  try {
47
57
  const mod = await import("sharp");
48
58
  return mod.default ?? mod;
49
59
  } catch (err) {
50
- const code = err.code;
51
- if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
52
- alog.debug("sharp not available, keeping original avatars");
53
- } else {
54
- alog.warn("sharp import failed, keeping original avatars", logger_default.errorData(err));
60
+ if (!warnedSharpUnavailable) {
61
+ warnedSharpUnavailable = true;
62
+ const code = err.code;
63
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
64
+ alog.warn(
65
+ "sharp is not installed \u2014 avatars will not be downscaled or inlined into mind context. Install the 'sharp' dependency to restore avatar image support."
66
+ );
67
+ } else {
68
+ alog.warn("sharp import failed, avatar image support disabled", logger_default.errorData(err));
69
+ }
55
70
  }
56
71
  return null;
57
72
  }
@@ -111,10 +126,39 @@ async function migrateAvatarSizes() {
111
126
  }
112
127
  }
113
128
  }
129
+ async function renderAvatarBlock(filePath, label) {
130
+ const ext = extname(filePath).toLowerCase();
131
+ const mediaType = MIME_BY_EXT[ext];
132
+ if (!mediaType) return null;
133
+ const sharp = await loadSharp();
134
+ if (!sharp) return null;
135
+ const data = await readFile(filePath);
136
+ let imageData;
137
+ try {
138
+ imageData = await sharp(data, { animated: true }).resize(AVATAR_CONTEXT_DIM, AVATAR_CONTEXT_DIM, { fit: "cover" }).toBuffer();
139
+ } catch (err) {
140
+ alog.warn(`avatar resize failed for ${label}, omitting image`, logger_default.errorData(err));
141
+ return null;
142
+ }
143
+ const base64 = imageData.toString("base64");
144
+ if (base64.length > MAX_AVATAR_BLOCK_BYTES) {
145
+ alog.warn(
146
+ `avatar for ${label} is ${base64.length} bytes after resize (> ${MAX_AVATAR_BLOCK_BYTES}), omitting image`
147
+ );
148
+ return null;
149
+ }
150
+ return [
151
+ { type: "text", text: `[Avatar for ${label}]` },
152
+ { type: "image", media_type: mediaType, data: base64 }
153
+ ];
154
+ }
114
155
 
115
156
  export {
116
157
  safeResolveWithinBase,
117
158
  AVATAR_DIM,
159
+ AVATAR_CONTEXT_DIM,
160
+ MAX_AVATAR_BLOCK_BYTES,
118
161
  normalizeAvatar,
119
- migrateAvatarSizes
162
+ migrateAvatarSizes,
163
+ renderAvatarBlock
120
164
  };
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  minds,
4
4
  schema_exports
5
- } from "./chunk-ZV7MFISX.js";
5
+ } from "./chunk-2MJ7EOMT.js";
6
6
 
7
7
  // packages/daemon/src/lib/db.ts
8
8
  import { chmodSync, existsSync } from "fs";
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  setBridgeConfig
4
- } from "./chunk-RXEEYDIB.js";
4
+ } from "./chunk-SZJCJVXV.js";
5
5
  import {
6
6
  readEnv,
7
7
  sharedEnvPath,
8
8
  writeEnv
9
- } from "./chunk-ZDZISKCL.js";
9
+ } from "./chunk-IYG4FBMP.js";
10
10
 
11
11
  // packages/daemon/src/lib/template/import-utils.ts
12
12
  import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteSystemDir
4
- } from "./chunk-ALKYQULU.js";
4
+ } from "./chunk-WW6C3PLV.js";
5
5
 
6
6
  // packages/daemon/src/lib/update-check.ts
7
7
  import { execFile as execFileCb, execFileSync } from "child_process";
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ if (!process.env.VOLUTE_HOME) {
10
10
  var command = process.argv[2];
11
11
  var args = process.argv.slice(3);
12
12
  if (command === "--version" || command === "-v") {
13
- const { default: pkg } = await import("./package-A7KXT67Q.js");
13
+ const { default: pkg } = await import("./package-WPEE2HVJ.js");
14
14
  console.log(pkg.version);
15
15
  process.exit(0);
16
16
  }
@@ -33,7 +33,7 @@ var ungatedCommands = /* @__PURE__ */ new Set([
33
33
  void 0
34
34
  ]);
35
35
  if (!ungatedCommands.has(command)) {
36
- const { isSetupComplete } = await import("./setup-Y2EJI3GG.js");
36
+ const { isSetupComplete } = await import("./setup-KFYVWTXG.js");
37
37
  if (!isSetupComplete()) {
38
38
  console.error("Volute is not set up. Run `volute setup` first.");
39
39
  process.exit(1);
@@ -41,64 +41,64 @@ if (!ungatedCommands.has(command)) {
41
41
  }
42
42
  switch (command) {
43
43
  case "setup":
44
- await import("./setup-DQM5VPY4.js").then((m) => m.run(args));
44
+ await import("./setup-QJHGMGSN.js").then((m) => m.run(args));
45
45
  break;
46
46
  case "mind":
47
- await import("./mind-DWB6XYCH.js").then((m) => m.run(args));
47
+ await import("./mind-POOHFZHP.js").then((m) => m.run(args));
48
48
  break;
49
49
  case "seed":
50
- await import("./seed-cmd-ILOGNIFB.js").then((m) => m.run(args));
50
+ await import("./seed-cmd-SYVDZKM4.js").then((m) => m.run(args));
51
51
  break;
52
52
  case "chat":
53
- await import("./chat-76MRWWQX.js").then((m) => m.run(args));
53
+ await import("./chat-AJLJCQ3M.js").then((m) => m.run(args));
54
54
  break;
55
55
  case "variant":
56
56
  await import("./variant-HHDTW74J.js").then((m) => m.run(args));
57
57
  break;
58
58
  case "clock":
59
- await import("./clock-K43IMROX.js").then((m) => m.run(args));
59
+ await import("./clock-E6N5Y3YW.js").then((m) => m.run(args));
60
60
  break;
61
61
  case "skill":
62
- await import("./skill-FKFHIJRR.js").then((m) => m.run(args));
62
+ await import("./skill-GUKG2YVH.js").then((m) => m.run(args));
63
63
  break;
64
64
  case "env":
65
- await import("./env-VZ4MLFQW.js").then((m) => m.run(args));
65
+ await import("./env-HRL2PWAT.js").then((m) => m.run(args));
66
66
  break;
67
67
  case "config":
68
68
  await import("./config-TJLYUV3U.js").then((m) => m.run(args));
69
69
  break;
70
70
  case "up":
71
- await import("./up-FTK7CTO3.js").then((m) => m.run(args));
71
+ await import("./up-J2PBPOZL.js").then((m) => m.run(args));
72
72
  break;
73
73
  case "backup":
74
- await import("./backup-TST5C2YN.js").then((m) => m.run(args));
74
+ await import("./backup-IIAFOW2L.js").then((m) => m.run(args));
75
75
  break;
76
76
  case "down":
77
- await import("./down-U2CZ23M4.js").then((m) => m.run(args));
77
+ await import("./down-ZI4S6265.js").then((m) => m.run(args));
78
78
  break;
79
79
  case "restart":
80
- await import("./daemon-restart-TIHKVVVA.js").then((m) => m.run(args));
80
+ await import("./daemon-restart-5F3YTLZK.js").then((m) => m.run(args));
81
81
  break;
82
82
  case "update":
83
- await import("./update-SWAYZRWJ.js").then((m) => m.run(args));
83
+ await import("./update-ACV4SAY3.js").then((m) => m.run(args));
84
84
  break;
85
85
  case "status":
86
- await import("./status-SWRVGXBI.js").then((m) => m.run(args));
86
+ await import("./status-V4RJMHJ4.js").then((m) => m.run(args));
87
87
  break;
88
88
  case "extension":
89
- await import("./extension-SEID47SR.js").then((m) => m.run(args));
89
+ await import("./extension-QBY4C44L.js").then((m) => m.run(args));
90
90
  break;
91
91
  case "systems":
92
- await import("./systems-VNB5WKSS.js").then((m) => m.run(args));
92
+ await import("./systems-B5YJKMW4.js").then((m) => m.run(args));
93
93
  break;
94
94
  case "login":
95
- await import("./login-M6OJUPQ2.js").then((m) => m.run(args));
95
+ await import("./login-OF4WXDAN.js").then((m) => m.run(args));
96
96
  break;
97
97
  case "logout":
98
- await import("./logout-WQBWO77G.js").then((m) => m.run(args));
98
+ await import("./logout-ERE2BGA3.js").then((m) => m.run(args));
99
99
  break;
100
100
  case "service":
101
- await import("./service-UOCLXDWR.js").then((m) => m.run(args));
101
+ await import("./service-SYJ5G6LP.js").then((m) => m.run(args));
102
102
  break;
103
103
  case "--help":
104
104
  case "-h":
@@ -117,16 +117,16 @@ Mind:
117
117
  mind status [name] Check a mind's status
118
118
  mind history [name] [--full] View mind activity history
119
119
  mind profile [--mind] [...] Set display name, description, avatar
120
- mind split/join Create and merge experimental splits
120
+ mind split/join Split off and rejoin variants
121
121
  mind upgrade/import/export Lifecycle operations
122
122
 
123
123
  Seed:
124
- seed create <name> Plant a new seed mind
124
+ seed create <name> Plant a new seed
125
125
  seed sprout Complete orientation and become a full mind
126
126
 
127
127
  Configuration:
128
128
  chat Conversations, messages, files, and platform bridges
129
- clock Schedules, timers, and sleep/wake cycles
129
+ clock Schedules and sleep/wake cycles
130
130
  skill Browse and install skills
131
131
  env Manage environment variables
132
132
 
@@ -295,7 +295,7 @@ Run 'volute --help' for usage.`);
295
295
  }
296
296
  }
297
297
  if (command !== "update") {
298
- import("./update-check-PQ2MZ47K.js").then((m) => m.checkForUpdate()).then((result) => {
298
+ import("./update-check-266R4ZSY.js").then((m) => m.checkForUpdate()).then((result) => {
299
299
  if (result.updateAvailable) {
300
300
  console.error(`
301
301
  Update available: ${result.current} \u2192 ${result.latest}`);
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ parseDuration,
4
+ run
5
+ } from "./chunk-JSVHH32K.js";
6
+ import "./chunk-5T5YMX6S.js";
7
+ import "./chunk-BTY4WNFE.js";
8
+ import "./chunk-TXSA4Q3V.js";
9
+ import "./chunk-O7IGP7ZW.js";
10
+ import "./chunk-RBNMDAKB.js";
11
+ import "./chunk-LOPXTW6H.js";
12
+ import "./chunk-K3NQKI34.js";
13
+ export {
14
+ parseDuration,
15
+ run
16
+ };
@@ -1,30 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  deliverMessage
4
- } from "./chunk-YT7PEESJ.js";
5
- import "./chunk-ZDZISKCL.js";
6
- import "./chunk-FR6S2KNN.js";
7
- import "./chunk-QLWG3C2Z.js";
8
- import "./chunk-7ZUB63PS.js";
4
+ } from "./chunk-F55GRIEK.js";
5
+ import "./chunk-IYG4FBMP.js";
6
+ import "./chunk-M6TTZRGH.js";
7
+ import "./chunk-RRZ4RQQU.js";
8
+ import "./chunk-K23P5Q5N.js";
9
+ import "./chunk-JCMGDCGX.js";
10
+ import "./chunk-IWJSNMSY.js";
9
11
  import {
10
12
  getAuthHeaders,
11
13
  getWebhookUrl
12
- } from "./chunk-OP4JG2BS.js";
14
+ } from "./chunk-HPGN6XRT.js";
15
+ import "./chunk-M3XDVS5Q.js";
16
+ import "./chunk-MTRMQFCQ.js";
17
+ import "./chunk-VMCZBXF2.js";
13
18
  import "./chunk-PFZBNKUH.js";
14
- import "./chunk-JZ62SYWR.js";
15
- import "./chunk-EJVPTVTI.js";
16
- import "./chunk-4JOQZPCE.js";
17
- import "./chunk-UYLGEDVD.js";
18
- import "./chunk-H2X54EHC.js";
19
- import "./chunk-IHKGWTGT.js";
20
- import "./chunk-F7H6ATM4.js";
21
- import "./chunk-T6HYVHPG.js";
22
- import "./chunk-7C44R625.js";
19
+ import "./chunk-EIQDZC43.js";
20
+ import "./chunk-DGGZVZTM.js";
21
+ import "./chunk-LWDTP6DH.js";
22
+ import "./chunk-SKNXMUIU.js";
23
+ import "./chunk-ODDGGLM6.js";
24
+ import "./chunk-LTLFOSA4.js";
23
25
  import {
24
26
  logger_default
25
27
  } from "./chunk-T2TP6ZC6.js";
26
- import "./chunk-ALKYQULU.js";
27
- import "./chunk-ZV7MFISX.js";
28
+ import "./chunk-WW6C3PLV.js";
29
+ import "./chunk-2MJ7EOMT.js";
28
30
  import "./chunk-K3NQKI34.js";
29
31
 
30
32
  // packages/daemon/src/lib/cloud-sync.ts
@@ -29,11 +29,11 @@ import {
29
29
  removeParticipant,
30
30
  setConversationPrivate,
31
31
  updateChannelSettings
32
- } from "./chunk-OP4JG2BS.js";
33
- import "./chunk-7C44R625.js";
32
+ } from "./chunk-HPGN6XRT.js";
33
+ import "./chunk-LTLFOSA4.js";
34
34
  import "./chunk-T2TP6ZC6.js";
35
- import "./chunk-ALKYQULU.js";
36
- import "./chunk-ZV7MFISX.js";
35
+ import "./chunk-WW6C3PLV.js";
36
+ import "./chunk-2MJ7EOMT.js";
37
37
  import "./chunk-K3NQKI34.js";
38
38
  export {
39
39
  addMessage,
@@ -21,7 +21,7 @@ var cmd = command({
21
21
  const name = args.name;
22
22
  let template = flags.template;
23
23
  if (!template) {
24
- const { resolveTemplate } = await import("./ai-service-UODCCE4O.js");
24
+ const { resolveTemplate } = await import("./ai-service-CVZEYKTK.js");
25
25
  template = await resolveTemplate();
26
26
  }
27
27
  const skills = flags.skills === "none" ? [] : flags.skills ? flags.skills.split(",") : void 0;
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stopDaemon
4
- } from "./chunk-RRNXJOKB.js";
4
+ } from "./chunk-BGYHLR54.js";
5
5
  import {
6
6
  run
7
- } from "./chunk-QNQMSWZE.js";
7
+ } from "./chunk-5IERLDUS.js";
8
8
  import {
9
9
  command
10
10
  } from "./chunk-TXSA4Q3V.js";
@@ -15,11 +15,11 @@ import {
15
15
  pollHealth,
16
16
  readDaemonConfig,
17
17
  restartService
18
- } from "./chunk-TQJ6ZYVY.js";
19
- import "./chunk-H2X54EHC.js";
20
- import "./chunk-F7H6ATM4.js";
21
- import "./chunk-ALKYQULU.js";
22
- import "./chunk-ZV7MFISX.js";
18
+ } from "./chunk-CBOIHNMR.js";
19
+ import "./chunk-DGGZVZTM.js";
20
+ import "./chunk-SKNXMUIU.js";
21
+ import "./chunk-WW6C3PLV.js";
22
+ import "./chunk-2MJ7EOMT.js";
23
23
  import "./chunk-K3NQKI34.js";
24
24
 
25
25
  // src/commands/daemon-restart.ts