volute 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/README.md +7 -6
  2. package/dist/accept-ZBDVVCEU.js +42 -0
  3. package/dist/{activity-events-BN7V6KCC.js → activity-events-PWOGSMRL.js} +4 -4
  4. package/dist/{ai-service-PSILB5WD.js → ai-service-GSZWIETO.js} +5 -5
  5. package/dist/{api-client-XUXOB7LI.js → api-client-3A77HMH7.js} +1 -1
  6. package/dist/api.d.ts +1 -5618
  7. package/dist/{archive-C2VEMQOR.js → archive-Y2YEOCGB.js} +3 -3
  8. package/dist/{auth-ZFZXJZDQ.js → auth-YTQME4EV.js} +5 -5
  9. package/dist/bridge-PXIO6PS2.js +206 -0
  10. package/dist/chat-ED7YOGKO.js +51 -0
  11. package/dist/{chunk-6LXAAQ43.js → chunk-33ODGMFZ.js} +1 -1
  12. package/dist/{chunk-G53F3JA4.js → chunk-46DYYHN6.js} +8 -3
  13. package/dist/{chunk-FYCALD4Q.js → chunk-5T5YMX6S.js} +1 -1
  14. package/dist/{chunk-B2BVAIZ4.js → chunk-6F3YNULE.js} +76 -24
  15. package/dist/{chunk-N7BLAHNE.js → chunk-75AJ54GM.js} +16 -5
  16. package/dist/{chunk-4JSR7YO7.js → chunk-7PTQGPJY.js} +29 -13
  17. package/dist/{chunk-XWXBJQBE.js → chunk-B35VNNSS.js} +4 -4
  18. package/dist/{chunk-V45JXOWY.js → chunk-BOLJUV77.js} +4 -4
  19. package/dist/{chunk-NAOW2CLO.js → chunk-BTY4WNFE.js} +1 -1
  20. package/dist/{chunk-OYAKCAVY.js → chunk-CU6OFXMM.js} +1 -1
  21. package/dist/{chunk-7F2SW2KD.js → chunk-DJT5Y4UF.js} +3 -3
  22. package/dist/{chunk-BM474GX6.js → chunk-DMV5P2LU.js} +4 -4
  23. package/dist/{chunk-TAHX36HZ.js → chunk-DQ7VBXAP.js} +2014 -436
  24. package/dist/{chunk-N3DNFPVA.js → chunk-GBDVNPN2.js} +15 -13
  25. package/dist/{chunk-E5C7OWZ2.js → chunk-IIWF2IPD.js} +150 -190
  26. package/dist/{chunk-PVY5W6QN.js → chunk-KAB6UGOL.js} +2 -2
  27. package/dist/{chunk-BDK73LK6.js → chunk-L72WYMF7.js} +2 -2
  28. package/dist/{chunk-G6BSYHPK.js → chunk-LGNUFVMR.js} +1 -1
  29. package/dist/{chunk-4RQBJWQX.js → chunk-LOPXTW6H.js} +1 -1
  30. package/dist/{chunk-BFWHBQK4.js → chunk-M5RYAA5I.js} +3 -3
  31. package/dist/{chunk-V6ZCNULL.js → chunk-N2AUHW4C.js} +37 -28
  32. package/dist/{chunk-6OWJXUAR.js → chunk-NUX47Y2V.js} +19 -4
  33. package/dist/{chunk-D424ZQGI.js → chunk-O7IGP7ZW.js} +11 -3
  34. package/dist/{chunk-U5BTYSAL.js → chunk-PJ4IPTIN.js} +2 -2
  35. package/dist/{chunk-BTWAGDV5.js → chunk-PY557GDR.js} +3 -3
  36. package/dist/{chunk-47ZPNLF4.js → chunk-PZYJBOQP.js} +8 -137
  37. package/dist/chunk-QHG4OMZL.js +145 -0
  38. package/dist/chunk-RG5TOL4O.js +18 -0
  39. package/dist/{chunk-6WAWMWR5.js → chunk-SWW6AUVW.js} +2 -2
  40. package/dist/{chunk-YUIHSKR6.js → chunk-T2TP6ZC6.js} +20 -8
  41. package/dist/chunk-TWAN7ZNO.js +164 -0
  42. package/dist/chunk-TXSA4Q3V.js +116 -0
  43. package/dist/{chunk-KTLFDYPT.js → chunk-UI7RPV2B.js} +1 -1
  44. package/dist/{chunk-SSI47XP2.js → chunk-VHWGEJ4V.js} +1 -1
  45. package/dist/{chunk-IS7WJ56Q.js → chunk-X2J7QUFH.js} +3 -3
  46. package/dist/{chunk-M3K5AARV.js → chunk-YDBAY3NA.js} +2 -2
  47. package/dist/{chunk-MLOQKQNB.js → chunk-YTWZORJN.js} +2 -2
  48. package/dist/{chunk-2IOP6PHB.js → chunk-ZTVKQOU7.js} +2 -2
  49. package/dist/{chunk-PLDWHR4D.js → chunk-ZX7EAV5J.js} +17 -7
  50. package/dist/cli.js +90 -29
  51. package/dist/clock-HSEKS5AR.js +289 -0
  52. package/dist/{cloud-sync-TG3TIX5H.js → cloud-sync-BOCZSDIA.js} +20 -22
  53. package/dist/config-UTS7QULS.js +76 -0
  54. package/dist/connectors/discord-bridge.js +3 -3
  55. package/dist/connectors/slack-bridge.js +3 -3
  56. package/dist/connectors/telegram-bridge.js +3 -3
  57. package/dist/{conversations-HL2JP5GI.js → conversations-HH3CJD4E.js} +15 -9
  58. package/dist/create-5BPOOJAN.js +75 -0
  59. package/dist/create-QBEPSD2Z.js +50 -0
  60. package/dist/daemon-client-RVIKXGFQ.js +12 -0
  61. package/dist/daemon-restart-SIR3UR4B.js +65 -0
  62. package/dist/daemon.js +1186 -1989
  63. package/dist/{db-PLEDCBHZ.js → db-BDMH4SZ2.js} +7 -3
  64. package/dist/{db-RYX3SS2W.js → db-URORGSXQ.js} +2 -2
  65. package/dist/delete-L5PAVDGQ.js +42 -0
  66. package/dist/delivery-manager-WTGIPBGY.js +30 -0
  67. package/dist/{delivery-router-D5ELDMS2.js → delivery-router-VSULHXNH.js} +4 -4
  68. package/dist/down-DGGLZ5TA.js +17 -0
  69. package/dist/env-E4XHO2BI.js +223 -0
  70. package/dist/{exec-DVLXKRIO.js → exec-X3C6ZZTQ.js} +4 -4
  71. package/dist/export-HTFOHOKL.js +113 -0
  72. package/dist/{extension-PM42QCID.js → extension-AKZ46YSL.js} +46 -35
  73. package/dist/extensions-OOSFVH7U.js +50 -0
  74. package/dist/files-H2YLRD37.js +53 -0
  75. package/dist/import-OL5BZX7S.js +143 -0
  76. package/dist/{isolation-62MKDZN3.js → isolation-N74RWOUX.js} +3 -3
  77. package/dist/join-DF5XSJAC.js +67 -0
  78. package/dist/list-GJ4RUQQT.js +59 -0
  79. package/dist/login-GOTAYLXP.js +51 -0
  80. package/dist/login-JXRVMBRB.js +60 -0
  81. package/dist/logout-6KIA74EV.js +29 -0
  82. package/dist/logout-FW243JBU.js +50 -0
  83. package/dist/message-delivery-YORUXKDQ.js +40 -0
  84. package/dist/mind-6VJJHF65.js +97 -0
  85. package/dist/{mind-activity-tracker-2ACNHA7B.js → mind-activity-tracker-66UVYIFW.js} +5 -5
  86. package/dist/mind-history-MII2SK7F.js +342 -0
  87. package/dist/mind-list-GEWHWAL4.js +38 -0
  88. package/dist/mind-manager-TJ2SUPRX.js +30 -0
  89. package/dist/mind-profile-DCBDVF5B.js +53 -0
  90. package/dist/mind-service-E7FM2WZF.js +36 -0
  91. package/dist/mind-sleep-ITCF6OQA.js +47 -0
  92. package/dist/mind-status-X4SX3YUG.js +65 -0
  93. package/dist/mind-wake-KXMKMGWX.js +42 -0
  94. package/dist/{package-V2WHWVG6.js → package-3W2MEXHB.js} +5 -5
  95. package/dist/read-ZUDG4JWU.js +91 -0
  96. package/dist/{read-stdin-PIRM6A2Y.js → read-stdin-3X5VYKNS.js} +1 -1
  97. package/dist/register-SB7NXCOE.js +51 -0
  98. package/dist/{registry-UYV5S6QT.js → registry-YPHK534W.js} +2 -2
  99. package/dist/reject-MUR2KWJ4.js +40 -0
  100. package/dist/restart-5EGG4JXU.js +42 -0
  101. package/dist/{sandbox-SI5HMBP3.js → sandbox-LP6YRAXS.js} +5 -5
  102. package/dist/scheduler-FRJ5DK24.js +30 -0
  103. package/dist/{schema-ETMABTW4.js → schema-MISD3JFG.js} +3 -1
  104. package/dist/{seed-WNGI6PNW.js → seed-CEC4RC23.js} +2 -2
  105. package/dist/seed-check-KJNTL72M.js +35 -0
  106. package/dist/seed-cmd-WTTG7SRQ.js +30 -0
  107. package/dist/seed-create-M6RCC6RP.js +113 -0
  108. package/dist/seed-sprout-ZKCHFJKH.js +148 -0
  109. package/dist/send-LXUT2GGR.js +409 -0
  110. package/dist/service-M6N3RUYU.js +121 -0
  111. package/dist/{setup-Z3DEVWV7.js → setup-PJOF5UV5.js} +153 -127
  112. package/dist/{setup-GGMKENLN.js → setup-PMJHCZQX.js} +5 -3
  113. package/dist/skill-TAAKEYBV.js +389 -0
  114. package/dist/skills/tending/SKILL.md +52 -0
  115. package/dist/skills/volute-mind/SKILL.md +3 -7
  116. package/dist/skills/volute-mind/references/extensions.md +8 -11
  117. package/dist/{skills-Q6VZ2UGD.js → skills-2PTRTBQP.js} +7 -7
  118. package/dist/sleep-manager-WAZWMFJT.js +34 -0
  119. package/dist/spirit-6KVDIROQ.js +24 -0
  120. package/dist/split-AWVOYOPZ.js +64 -0
  121. package/dist/{sprout-E3HJIV2Z.js → sprout-WX2FFYLP.js} +2 -2
  122. package/dist/src-FQE4BHRG.js +617 -0
  123. package/dist/src-GW6FP6VL.js +425 -0
  124. package/dist/src-QEOLMAYC.js +2133 -0
  125. package/dist/start-3UXOPXQG.js +39 -0
  126. package/dist/status-3IVSLJDN.js +125 -0
  127. package/dist/stop-3XYIBGFM.js +41 -0
  128. package/dist/system-chat-2IFS5HCX.js +34 -0
  129. package/dist/systems-O43WGQY6.js +52 -0
  130. package/dist/{tailscale-ZEUK7GKZ.js → tailscale-DZU4WM3E.js} +4 -4
  131. package/dist/{template-hash-EJRTKE36.js → template-hash-6ITI3WC4.js} +2 -2
  132. package/dist/up-4SCIUIMG.js +19 -0
  133. package/dist/update-RIQYUPVN.js +225 -0
  134. package/dist/{update-check-X3YG4WVP.js → update-check-4TIJKVGD.js} +3 -3
  135. package/dist/upgrade-ZMDGC7M2.js +74 -0
  136. package/dist/variant-QWL2WSRI.js +62 -0
  137. package/dist/{version-notify-YCH4UVQ2.js → version-notify-UXSHBZ35.js} +27 -27
  138. package/dist/{volute-config-WBKYJGYQ.js → volute-config-V7UFFBG3.js} +1 -1
  139. package/dist/web-assets/assets/index-C-eYso8Y.js +75 -0
  140. package/dist/web-assets/assets/index-CCv_fSte.css +1 -0
  141. package/dist/web-assets/index.html +2 -2
  142. package/dist/web-assets/sw.js +117 -0
  143. package/drizzle/0006_channels.sql +17 -0
  144. package/drizzle/0007_drop_conversation_name_title.sql +11 -0
  145. package/drizzle/0008_performance_indexes.sql +6 -0
  146. package/drizzle/meta/0006_snapshot.json +7 -0
  147. package/drizzle/meta/0007_snapshot.json +7 -0
  148. package/drizzle/meta/_journal.json +21 -0
  149. package/package.json +5 -5
  150. package/packages/extensions/pages/dist/ui/assets/index-DKZLNMED.js +2 -0
  151. package/packages/extensions/pages/dist/ui/index.html +1 -1
  152. package/packages/extensions/pages/skills/pages/SKILL.md +84 -9
  153. package/templates/_base/home/.config/routes.json +2 -2
  154. package/templates/_base/home/VOLUTE.md +1 -2
  155. package/templates/_base/src/lib/auto-commit.ts +8 -8
  156. package/templates/_base/src/lib/format-prefix.ts +1 -7
  157. package/templates/_base/src/lib/volute-server.ts +6 -0
  158. package/templates/claude/.init/.config/routes.json +2 -2
  159. package/templates/claude/src/agent.ts +8 -1
  160. package/templates/codex/.init/.config/routes.json +2 -2
  161. package/templates/pi/.init/.config/routes.json +2 -2
  162. package/dist/accept-TW6V4WI4.js +0 -42
  163. package/dist/bridge-O753D5F4.js +0 -207
  164. package/dist/chat-BHYX7DJ4.js +0 -68
  165. package/dist/chunk-47XDEWWV.js +0 -156
  166. package/dist/chunk-CVL5IGIR.js +0 -2084
  167. package/dist/chunk-PB65JZK2.js +0 -85
  168. package/dist/clock-3X4DSC2N.js +0 -281
  169. package/dist/config-OROA5DUA.js +0 -72
  170. package/dist/create-3SEKKI6P.js +0 -71
  171. package/dist/create-UOSOQ2HN.js +0 -44
  172. package/dist/daemon-client-WOAQXXBM.js +0 -12
  173. package/dist/daemon-restart-5ABHNXJZ.js +0 -52
  174. package/dist/delete-KYOVWR23.js +0 -35
  175. package/dist/delivery-manager-2BR5NZKF.js +0 -32
  176. package/dist/down-QVFN4UPK.js +0 -15
  177. package/dist/env-R34DT7XL.js +0 -195
  178. package/dist/export-6ZXAXATG.js +0 -112
  179. package/dist/extensions-BBGVL5JC.js +0 -38
  180. package/dist/files-VQV2VZQO.js +0 -47
  181. package/dist/import-MK2I2T6F.js +0 -23
  182. package/dist/join-DGYHTJUH.js +0 -66
  183. package/dist/list-C644WTHV.js +0 -49
  184. package/dist/login-IIGEQPHL.js +0 -47
  185. package/dist/login-KZQLMAWE.js +0 -47
  186. package/dist/logout-AGTZVRGP.js +0 -40
  187. package/dist/logout-KD6GXIJJ.js +0 -21
  188. package/dist/message-delivery-V3R6NXJP.js +0 -42
  189. package/dist/mind-BI4EPBVZ.js +0 -108
  190. package/dist/mind-history-WOYFLQAI.js +0 -264
  191. package/dist/mind-list-6VPM7GUQ.js +0 -30
  192. package/dist/mind-manager-MWW3BTS4.js +0 -32
  193. package/dist/mind-profile-WPG42U5Y.js +0 -47
  194. package/dist/mind-service-VIKZJK2M.js +0 -38
  195. package/dist/mind-sleep-XDISJY74.js +0 -42
  196. package/dist/mind-status-7FTZWPZF.js +0 -56
  197. package/dist/mind-wake-KIIKEI3A.js +0 -37
  198. package/dist/read-H5C26YO7.js +0 -85
  199. package/dist/register-J27WP33N.js +0 -47
  200. package/dist/reject-OEANJYIA.js +0 -40
  201. package/dist/restart-V5EGYBJG.js +0 -33
  202. package/dist/scheduler-AGG3L2FO.js +0 -32
  203. package/dist/seed-check-PXTH7YXS.js +0 -32
  204. package/dist/seed-cmd-VENFTGS3.js +0 -36
  205. package/dist/seed-create-663ALOKH.js +0 -112
  206. package/dist/seed-sprout-EH3AGKAI.js +0 -132
  207. package/dist/send-7FUUUZZH.js +0 -386
  208. package/dist/skill-DKNYJS4P.js +0 -362
  209. package/dist/skills/shared-files/SKILL.md +0 -44
  210. package/dist/skills/shared-files/scripts/merge.ts +0 -72
  211. package/dist/skills/shared-files/scripts/pull.ts +0 -52
  212. package/dist/sleep-manager-BJK2ROPX.js +0 -36
  213. package/dist/spirit-4JP4TY4C.js +0 -23
  214. package/dist/split-3YPMS2CL.js +0 -63
  215. package/dist/start-W3TPKX4D.js +0 -33
  216. package/dist/status-4OVFXFEJ.js +0 -115
  217. package/dist/stop-GTT6YWYO.js +0 -32
  218. package/dist/system-channel-DXD2JBOU.js +0 -36
  219. package/dist/system-chat-TYLOL7SX.js +0 -36
  220. package/dist/systems-AYLO727G.js +0 -61
  221. package/dist/up-PA7F2CXE.js +0 -18
  222. package/dist/update-HG4LCUSG.js +0 -215
  223. package/dist/upgrade-YGNIDICG.js +0 -67
  224. package/dist/variant-MZUMRTQO.js +0 -41
  225. package/dist/web-assets/assets/index-DiiwC-CZ.css +0 -1
  226. package/dist/web-assets/assets/index-d6y5b9Ij.js +0 -75
  227. package/packages/extensions/pages/dist/ui/assets/index-tLTROSk5.js +0 -2
@@ -5,10 +5,13 @@ import {
5
5
  pollHealthDown,
6
6
  readDaemonConfig,
7
7
  stopService
8
- } from "./chunk-7F2SW2KD.js";
8
+ } from "./chunk-DJT5Y4UF.js";
9
+ import {
10
+ command
11
+ } from "./chunk-TXSA4Q3V.js";
9
12
  import {
10
13
  voluteSystemDir
11
- } from "./chunk-N7BLAHNE.js";
14
+ } from "./chunk-75AJ54GM.js";
12
15
 
13
16
  // src/commands/down.ts
14
17
  import { existsSync, readFileSync, unlinkSync } from "fs";
@@ -103,36 +106,42 @@ async function stopDaemon() {
103
106
  console.error("Daemon did not exit cleanly, sent SIGKILL.");
104
107
  return { stopped: true, clean: false };
105
108
  }
106
- async function run(_args) {
107
- const mode = getServiceMode();
108
- if (mode !== "manual") {
109
- console.log(`Stopping volute (${modeLabel(mode)})...`);
110
- try {
111
- await stopService(mode);
112
- } catch (err) {
113
- console.error(`Failed to stop service: ${err instanceof Error ? err.message : err}`);
114
- process.exit(1);
109
+ var cmd = command({
110
+ name: "volute down",
111
+ description: "Stop the daemon",
112
+ flags: {},
113
+ run: async () => {
114
+ const mode = getServiceMode();
115
+ if (mode !== "manual") {
116
+ console.log(`Stopping volute (${modeLabel(mode)})...`);
117
+ try {
118
+ await stopService(mode);
119
+ } catch (err) {
120
+ console.error(`Failed to stop service: ${err instanceof Error ? err.message : err}`);
121
+ process.exit(1);
122
+ }
123
+ const config = readDaemonConfig();
124
+ if (await pollHealthDown("127.0.0.1", config.internalPort ?? config.port)) {
125
+ console.log("Daemon stopped.");
126
+ } else {
127
+ console.error("Service stopped but daemon may still be responding.");
128
+ process.exit(1);
129
+ }
130
+ return;
115
131
  }
116
- const config = readDaemonConfig();
117
- if (await pollHealthDown("127.0.0.1", config.internalPort ?? config.port)) {
118
- console.log("Daemon stopped.");
119
- } else {
120
- console.error("Service stopped but daemon may still be responding.");
132
+ const result = await stopDaemon();
133
+ if (result.stopped) return;
134
+ if (result.reason === "orphan") {
135
+ console.error(`Daemon appears to be running on port ${result.port} but PID file is missing.`);
136
+ console.error(`Kill the process manually: lsof -ti :${result.port} | xargs kill`);
137
+ process.exit(1);
138
+ } else if (result.reason === "kill-failed") {
121
139
  process.exit(1);
122
140
  }
123
- return;
141
+ console.log("Daemon is not running.");
124
142
  }
125
- const result = await stopDaemon();
126
- if (result.stopped) return;
127
- if (result.reason === "orphan") {
128
- console.error(`Daemon appears to be running on port ${result.port} but PID file is missing.`);
129
- console.error(`Kill the process manually: lsof -ti :${result.port} | xargs kill`);
130
- process.exit(1);
131
- } else if (result.reason === "kill-failed") {
132
- process.exit(1);
133
- }
134
- console.log("Daemon is not running.");
135
- }
143
+ });
144
+ var run = cmd.execute;
136
145
 
137
146
  export {
138
147
  stopDaemon,
@@ -1,19 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteSystemDir
4
- } from "./chunk-N7BLAHNE.js";
4
+ } from "./chunk-75AJ54GM.js";
5
5
 
6
- // src/lib/setup.ts
6
+ // packages/daemon/src/lib/config/setup.ts
7
7
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
8
8
  import { resolve } from "path";
9
9
  function configPath() {
10
10
  return resolve(voluteSystemDir(), "config.json");
11
11
  }
12
+ var _cachedConfig = null;
13
+ var CONFIG_CACHE_TTL = 2e3;
14
+ function _resetConfigCache() {
15
+ _cachedConfig = null;
16
+ }
12
17
  function readGlobalConfig() {
18
+ if (_cachedConfig && Date.now() - _cachedConfig.ts < CONFIG_CACHE_TTL) {
19
+ return { ..._cachedConfig.config };
20
+ }
13
21
  const path = configPath();
14
- if (!existsSync(path)) return {};
22
+ if (!existsSync(path)) {
23
+ _cachedConfig = null;
24
+ return {};
25
+ }
15
26
  try {
16
- return JSON.parse(readFileSync(path, "utf-8"));
27
+ const config = JSON.parse(readFileSync(path, "utf-8"));
28
+ _cachedConfig = { config, ts: Date.now() };
29
+ return config;
17
30
  } catch (err) {
18
31
  console.error(`Failed to parse ${path}: ${err instanceof Error ? err.message : err}`);
19
32
  return {};
@@ -24,6 +37,7 @@ function writeGlobalConfig(config) {
24
37
  mkdirSync(voluteSystemDir(), { recursive: true });
25
38
  writeFileSync(path, `${JSON.stringify(config, null, 2)}
26
39
  `);
40
+ _cachedConfig = { config, ts: Date.now() };
27
41
  }
28
42
  function isSetupComplete() {
29
43
  const config = readGlobalConfig();
@@ -47,6 +61,7 @@ function migrateSetupCompleted() {
47
61
 
48
62
  export {
49
63
  configPath,
64
+ _resetConfigCache,
50
65
  readGlobalConfig,
51
66
  writeGlobalConfig,
52
67
  isSetupComplete,
@@ -1,18 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/lib/parse-args.ts
3
+ // packages/cli/src/lib/parse-args.ts
4
4
  function parseArgs(args, flags) {
5
5
  const positional = [];
6
6
  const result = {};
7
+ let help = false;
7
8
  for (const [key, def] of Object.entries(flags)) {
8
9
  result[key] = def.type === "boolean" ? false : void 0;
9
10
  }
10
11
  for (let i = 0; i < args.length; i++) {
11
12
  const arg = args[i];
13
+ if (arg === "--help" || arg === "-h") {
14
+ help = true;
15
+ continue;
16
+ }
12
17
  if (arg.startsWith("--")) {
13
18
  const name = arg.slice(2);
14
19
  const def = flags[name];
15
- if (!def) continue;
20
+ if (!def) {
21
+ console.error(`Warning: unknown flag --${name}`);
22
+ continue;
23
+ }
16
24
  if (def.type === "boolean") {
17
25
  result[name] = true;
18
26
  } else if (i + 1 < args.length) {
@@ -23,7 +31,7 @@ function parseArgs(args, flags) {
23
31
  positional.push(arg);
24
32
  }
25
33
  }
26
- return { positional, flags: result };
34
+ return { positional, flags: result, help };
27
35
  }
28
36
 
29
37
  export {
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  wrapForIsolation
4
- } from "./chunk-BDK73LK6.js";
4
+ } from "./chunk-L72WYMF7.js";
5
5
 
6
- // src/lib/exec.ts
6
+ // packages/daemon/src/lib/util/exec.ts
7
7
  import { execFile as execFileCb, execFileSync, spawn } from "child_process";
8
8
  async function exec(cmd, args, options) {
9
9
  const [wrappedCmd, wrappedArgs] = options?.mindName ? await wrapForIsolation(cmd, args, options.mindName) : [cmd, args];
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  publish
4
- } from "./chunk-XWXBJQBE.js";
4
+ } from "./chunk-B35VNNSS.js";
5
5
  import {
6
6
  logger_default
7
- } from "./chunk-YUIHSKR6.js";
7
+ } from "./chunk-T2TP6ZC6.js";
8
8
 
9
- // src/lib/events/mind-activity-tracker.ts
9
+ // packages/daemon/src/lib/events/mind-activity-tracker.ts
10
10
  var IDLE_TIMEOUT_MS = 5 * 60 * 1e3;
11
11
  var minds = /* @__PURE__ */ new Map();
12
12
  function getState(mind) {
@@ -3,34 +3,20 @@ import {
3
3
  readEnv,
4
4
  sharedEnvPath,
5
5
  writeEnv
6
- } from "./chunk-M3K5AARV.js";
6
+ } from "./chunk-YDBAY3NA.js";
7
7
  import {
8
8
  logger_default
9
- } from "./chunk-YUIHSKR6.js";
10
- import {
11
- parseArgs
12
- } from "./chunk-D424ZQGI.js";
9
+ } from "./chunk-T2TP6ZC6.js";
13
10
  import {
14
11
  voluteSystemDir
15
- } from "./chunk-N7BLAHNE.js";
12
+ } from "./chunk-75AJ54GM.js";
16
13
 
17
- // src/commands/import.ts
18
- import {
19
- closeSync,
20
- existsSync as existsSync2,
21
- mkdirSync,
22
- openSync,
23
- readdirSync,
24
- readFileSync as readFileSync2,
25
- readSync,
26
- rmSync,
27
- statSync,
28
- writeFileSync as writeFileSync2
29
- } from "fs";
30
- import { homedir, tmpdir } from "os";
14
+ // packages/daemon/src/lib/template/import-utils.ts
15
+ import { existsSync as existsSync2, mkdirSync, readdirSync, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync2 } from "fs";
16
+ import { homedir } from "os";
31
17
  import { basename, resolve as resolve2 } from "path";
32
18
 
33
- // src/lib/bridges.ts
19
+ // packages/daemon/src/lib/bridges/bridges.ts
34
20
  import { existsSync, readFileSync, writeFileSync } from "fs";
35
21
  import { resolve } from "path";
36
22
  function bridgesPath() {
@@ -99,121 +85,7 @@ function findBridgeForChannel(voluteChannelName) {
99
85
  return null;
100
86
  }
101
87
 
102
- // src/commands/import.ts
103
- async function run(args) {
104
- const { positional, flags } = parseArgs(args, {
105
- name: { type: "string" },
106
- session: { type: "string" },
107
- template: { type: "string" }
108
- });
109
- const inputPath = positional[0];
110
- if (inputPath && (inputPath.endsWith(".volute") || isZipFile(inputPath))) {
111
- await importArchive(resolve2(inputPath), flags.name);
112
- return;
113
- }
114
- const wsDir = resolveWorkspace(inputPath);
115
- const { daemonFetch } = await import("./daemon-client-WOAQXXBM.js");
116
- const { getClient, urlOf } = await import("./api-client-XUXOB7LI.js");
117
- const client = getClient();
118
- const res = await daemonFetch(urlOf(client.api.minds.import.$url()), {
119
- method: "POST",
120
- headers: { "Content-Type": "application/json" },
121
- body: JSON.stringify({
122
- workspacePath: wsDir,
123
- name: flags.name,
124
- template: flags.template,
125
- sessionPath: flags.session
126
- })
127
- });
128
- const data = await res.json();
129
- if (!res.ok) {
130
- console.error(data.error ?? "Failed to import mind");
131
- process.exit(1);
132
- }
133
- console.log(`
134
- ${data.message ?? `Imported mind: ${data.name} (port ${data.port})`}`);
135
- console.log(`
136
- volute mind start ${data.name}`);
137
- }
138
- function isZipFile(path) {
139
- const resolved = resolve2(path);
140
- if (!existsSync2(resolved)) return false;
141
- const fd = openSync(resolved, "r");
142
- try {
143
- const buf = Buffer.alloc(4);
144
- const bytesRead = readSync(fd, buf, 0, 4, 0);
145
- return bytesRead === 4 && buf[0] === 80 && buf[1] === 75 && buf[2] === 3 && buf[3] === 4;
146
- } finally {
147
- closeSync(fd);
148
- }
149
- }
150
- async function importArchive(archivePath, nameOverride) {
151
- if (!existsSync2(archivePath)) {
152
- console.error(`File not found: ${archivePath}`);
153
- process.exit(1);
154
- }
155
- const { extractArchive } = await import("./archive-C2VEMQOR.js");
156
- const tempDir = resolve2(tmpdir(), `volute-import-${Date.now()}`);
157
- mkdirSync(tempDir, { recursive: true });
158
- let extracted;
159
- try {
160
- extracted = extractArchive(archivePath, tempDir);
161
- } catch (err) {
162
- rmSync(tempDir, { recursive: true, force: true });
163
- console.error(`Failed to extract archive: ${err.message}`);
164
- process.exit(1);
165
- }
166
- try {
167
- const { daemonFetch } = await import("./daemon-client-WOAQXXBM.js");
168
- const { getClient, urlOf } = await import("./api-client-XUXOB7LI.js");
169
- const client = getClient();
170
- const res = await daemonFetch(urlOf(client.api.minds.import.$url()), {
171
- method: "POST",
172
- headers: { "Content-Type": "application/json" },
173
- body: JSON.stringify({
174
- archivePath: tempDir,
175
- name: nameOverride,
176
- manifest: extracted.manifest
177
- })
178
- });
179
- const data = await res.json();
180
- if (!res.ok) {
181
- console.error(data.error ?? "Failed to import mind");
182
- process.exit(1);
183
- }
184
- console.log(`
185
- ${data.message ?? `Imported mind: ${data.name} (port ${data.port})`}`);
186
- console.log(`
187
- volute mind start ${data.name}`);
188
- } catch (err) {
189
- rmSync(tempDir, { recursive: true, force: true });
190
- throw err;
191
- }
192
- }
193
- function resolveWorkspace(explicitPath) {
194
- if (explicitPath) {
195
- const wsDir = resolve2(explicitPath);
196
- if (!existsSync2(resolve2(wsDir, "SOUL.md")) || !existsSync2(resolve2(wsDir, "IDENTITY.md"))) {
197
- console.error("Not a valid OpenClaw workspace: missing SOUL.md or IDENTITY.md");
198
- process.exit(1);
199
- }
200
- return wsDir;
201
- }
202
- const cwd = process.cwd();
203
- if (existsSync2(resolve2(cwd, "SOUL.md")) && existsSync2(resolve2(cwd, "IDENTITY.md"))) {
204
- console.log(`Using workspace: ${cwd}`);
205
- return cwd;
206
- }
207
- const openclawWs = resolve2(homedir(), ".openclaw/workspace");
208
- if (existsSync2(resolve2(openclawWs, "SOUL.md")) && existsSync2(resolve2(openclawWs, "IDENTITY.md"))) {
209
- console.log(`Using workspace: ${openclawWs}`);
210
- return openclawWs;
211
- }
212
- console.error(
213
- "Usage: volute mind import [<workspace-path>] [--name <name>] [--session <path>] [--template <name>]\n\nNo OpenClaw workspace found. Provide a path, run from a workspace, or ensure ~/.openclaw/workspace exists."
214
- );
215
- process.exit(1);
216
- }
88
+ // packages/daemon/src/lib/template/import-utils.ts
217
89
  function findOpenClawSession(workspaceDir) {
218
90
  const ocAgentsDir = resolve2(homedir(), ".openclaw/agents");
219
91
  if (!existsSync2(ocAgentsDir)) return void 0;
@@ -327,7 +199,6 @@ export {
327
199
  removeChannelMapping,
328
200
  resolveChannelMapping,
329
201
  findBridgeForChannel,
330
- run,
331
202
  findOpenClawSession,
332
203
  sessionMatchesWorkspace,
333
204
  importPiSession,
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env node
2
+
3
+ // packages/extensions/pages/src/db.ts
4
+ function initDb(db) {
5
+ db.exec(`
6
+ CREATE TABLE IF NOT EXISTS published_pages (
7
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
8
+ mind TEXT NOT NULL,
9
+ file TEXT NOT NULL,
10
+ published_at TEXT NOT NULL DEFAULT (datetime('now')),
11
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
12
+ author TEXT
13
+ );
14
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_pp_mind_file ON published_pages(mind, file);
15
+ CREATE INDEX IF NOT EXISTS idx_pp_updated_at ON published_pages(updated_at);
16
+ `);
17
+ try {
18
+ db.exec("ALTER TABLE published_pages ADD COLUMN author TEXT");
19
+ } catch (err) {
20
+ if (!(err instanceof Error) || !err.message.includes("duplicate column")) {
21
+ throw err;
22
+ }
23
+ }
24
+ }
25
+ function getPublishedPages(db, mind) {
26
+ return db.prepare(
27
+ "SELECT file, published_at, updated_at, author FROM published_pages WHERE mind = ? ORDER BY file"
28
+ ).all(mind);
29
+ }
30
+ function getRecentPages(db, opts) {
31
+ const limit = opts?.limit ?? 10;
32
+ if (opts?.mind) {
33
+ return db.prepare(
34
+ "SELECT mind, file, updated_at, author FROM published_pages WHERE mind = ? ORDER BY updated_at DESC LIMIT ?"
35
+ ).all(opts.mind, limit);
36
+ }
37
+ return db.prepare(
38
+ "SELECT mind, file, updated_at, author FROM published_pages ORDER BY updated_at DESC LIMIT ?"
39
+ ).all(limit);
40
+ }
41
+ function getAllSites(db) {
42
+ const rows = db.prepare(
43
+ "SELECT mind, file, updated_at, author FROM published_pages WHERE mind != '_system' ORDER BY mind, file"
44
+ ).all();
45
+ const siteMap = /* @__PURE__ */ new Map();
46
+ for (const row of rows) {
47
+ let files = siteMap.get(row.mind);
48
+ if (!files) {
49
+ files = [];
50
+ siteMap.set(row.mind, files);
51
+ }
52
+ files.push({ file: row.file, updated_at: row.updated_at, author: row.author });
53
+ }
54
+ return Array.from(siteMap.entries()).map(([mind, files]) => ({ mind, files }));
55
+ }
56
+ function getSystemPages(db) {
57
+ const rows = db.prepare(
58
+ "SELECT mind, file, updated_at, author FROM published_pages WHERE mind = '_system' ORDER BY file"
59
+ ).all();
60
+ if (rows.length === 0) return null;
61
+ return {
62
+ mind: "_system",
63
+ files: rows.map((r) => ({ file: r.file, updated_at: r.updated_at, author: r.author }))
64
+ };
65
+ }
66
+ function syncSystemPages(db, htmlFiles, author) {
67
+ const existing = new Set(
68
+ db.prepare("SELECT file FROM published_pages WHERE mind = '_system'").all().map((r) => r.file)
69
+ );
70
+ const newSet = new Set(htmlFiles);
71
+ db.exec("BEGIN");
72
+ try {
73
+ for (const file of htmlFiles) {
74
+ if (existing.has(file)) {
75
+ if (author) {
76
+ db.prepare(
77
+ "UPDATE published_pages SET updated_at = datetime('now'), author = ? WHERE mind = '_system' AND file = ?"
78
+ ).run(author, file);
79
+ } else {
80
+ db.prepare(
81
+ "UPDATE published_pages SET updated_at = datetime('now') WHERE mind = '_system' AND file = ?"
82
+ ).run(file);
83
+ }
84
+ } else {
85
+ db.prepare("INSERT INTO published_pages (mind, file, author) VALUES ('_system', ?, ?)").run(
86
+ file,
87
+ author ?? null
88
+ );
89
+ }
90
+ }
91
+ for (const file of existing) {
92
+ if (!newSet.has(file)) {
93
+ db.prepare("DELETE FROM published_pages WHERE mind = '_system' AND file = ?").run(file);
94
+ }
95
+ }
96
+ db.exec("COMMIT");
97
+ } catch (err) {
98
+ db.exec("ROLLBACK");
99
+ throw err;
100
+ }
101
+ }
102
+ function syncPublishedPages(db, mind, pageFiles) {
103
+ const existing = new Map(
104
+ db.prepare("SELECT file, updated_at FROM published_pages WHERE mind = ?").all(mind).map((r) => [r.file, r.updated_at])
105
+ );
106
+ const newSet = new Set(pageFiles);
107
+ const added = [];
108
+ const updated = [];
109
+ const removed = [];
110
+ db.exec("BEGIN");
111
+ try {
112
+ for (const file of pageFiles) {
113
+ if (existing.has(file)) {
114
+ db.prepare(
115
+ "UPDATE published_pages SET updated_at = datetime('now') WHERE mind = ? AND file = ?"
116
+ ).run(mind, file);
117
+ updated.push(file);
118
+ } else {
119
+ db.prepare("INSERT INTO published_pages (mind, file) VALUES (?, ?)").run(mind, file);
120
+ added.push(file);
121
+ }
122
+ }
123
+ for (const [file] of existing) {
124
+ if (!newSet.has(file)) {
125
+ db.prepare("DELETE FROM published_pages WHERE mind = ? AND file = ?").run(mind, file);
126
+ removed.push(file);
127
+ }
128
+ }
129
+ db.exec("COMMIT");
130
+ } catch (err) {
131
+ db.exec("ROLLBACK");
132
+ throw err;
133
+ }
134
+ return { added, removed, updated };
135
+ }
136
+
137
+ export {
138
+ initDb,
139
+ getPublishedPages,
140
+ getRecentPages,
141
+ getAllSites,
142
+ getSystemPages,
143
+ syncSystemPages,
144
+ syncPublishedPages
145
+ };
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+
3
+ // packages/extensions/sdk/src/index.ts
4
+ var VALID_EXTENSION_ID = /^[a-z0-9][a-z0-9_-]*$/;
5
+ function createExtension(manifest) {
6
+ if (!manifest.id) throw new Error("Extension manifest requires an id");
7
+ if (!VALID_EXTENSION_ID.test(manifest.id))
8
+ throw new Error(
9
+ "Extension id must be lowercase alphanumeric with hyphens/underscores, starting with a letter or digit"
10
+ );
11
+ if (typeof manifest.routes !== "function")
12
+ throw new Error("Extension manifest requires a routes function");
13
+ return manifest;
14
+ }
15
+
16
+ export {
17
+ createExtension
18
+ };
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  mindDir,
4
4
  stateDir
5
- } from "./chunk-N7BLAHNE.js";
5
+ } from "./chunk-75AJ54GM.js";
6
6
 
7
- // src/lib/archive.ts
7
+ // packages/daemon/src/lib/mind/archive.ts
8
8
  import { execFileSync } from "child_process";
9
9
  import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
10
10
  import { join, relative, resolve } from "path";
@@ -1,21 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/lib/log-buffer.ts
3
+ // packages/daemon/src/lib/util/log-buffer.ts
4
4
  var LogBuffer = class {
5
- entries = [];
6
- maxSize = 1e3;
5
+ constructor(maxSize = 1e3) {
6
+ this.maxSize = maxSize;
7
+ this.buffer = new Array(maxSize).fill(null);
8
+ }
9
+ buffer;
10
+ head = 0;
11
+ count = 0;
7
12
  subscribers = /* @__PURE__ */ new Set();
8
13
  append(entry) {
9
- this.entries.push(entry);
10
- if (this.entries.length > this.maxSize) {
11
- this.entries.shift();
14
+ const idx = (this.head + this.count) % this.maxSize;
15
+ this.buffer[idx] = entry;
16
+ if (this.count === this.maxSize) {
17
+ this.head = (this.head + 1) % this.maxSize;
18
+ } else {
19
+ this.count++;
12
20
  }
13
21
  for (const sub of this.subscribers) {
14
22
  sub(entry);
15
23
  }
16
24
  }
17
25
  getEntries() {
18
- return [...this.entries];
26
+ const result = [];
27
+ for (let i = 0; i < this.count; i++) {
28
+ result.push(this.buffer[(this.head + i) % this.maxSize]);
29
+ }
30
+ return result;
19
31
  }
20
32
  subscribe(fn) {
21
33
  this.subscribers.add(fn);
@@ -24,7 +36,7 @@ var LogBuffer = class {
24
36
  };
25
37
  var logBuffer = new LogBuffer();
26
38
 
27
- // src/lib/logger.ts
39
+ // packages/daemon/src/lib/util/logger.ts
28
40
  var LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
29
41
  var minLevel = LEVELS[process.env.VOLUTE_LOG_LEVEL || "info"] ?? LEVELS.info;
30
42
  var output = (line) => process.stderr.write(`${line}