volute 0.28.0 → 0.30.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 (134) hide show
  1. package/README.md +127 -18
  2. package/dist/{accept-666DIZX2.js → accept-E3PAH3QJ.js} +2 -2
  3. package/dist/{activity-events-BBIEA2F4.js → activity-events-BKBPPUBP.js} +2 -2
  4. package/dist/ai-service-VAJT5UBS.js +29 -0
  5. package/dist/api.d.ts +586 -529
  6. package/dist/{archive-UA4BDFXQ.js → archive-WWDBWYN2.js} +2 -2
  7. package/dist/{bridge-FQHZL3MC.js → bridge-RO37CUFM.js} +2 -2
  8. package/dist/{chat-M4SX42JD.js → chat-TCUNPFGO.js} +8 -8
  9. package/dist/{chunk-IAYBDWVG.js → chunk-2C2VXEBB.js} +147 -2
  10. package/dist/chunk-2NDZC3S7.js +1330 -0
  11. package/dist/{chunk-IKRVFPWU.js → chunk-7D47T4RB.js} +3 -2
  12. package/dist/chunk-A6TUJJ3L.js +19 -0
  13. package/dist/{chunk-AW7PFDVN.js → chunk-CVH6Y2YG.js} +1 -1
  14. package/dist/{chunk-XBLSAVJF.js → chunk-DTC6EH5I.js} +1 -1
  15. package/dist/chunk-EFP3PE6C.js +232 -0
  16. package/dist/{chunk-JGFVMROS.js → chunk-EFVHR7KH.js} +1 -1
  17. package/dist/{chunk-K5NAC55T.js → chunk-FSM45XD5.js} +2 -2
  18. package/dist/{chunk-LAC664WU.js → chunk-FXHXHI2A.js} +42 -24
  19. package/dist/{chunk-RKQEHRBB.js → chunk-G3GBKZGG.js} +1 -1
  20. package/dist/{chunk-H7OZRFJB.js → chunk-HHTXM4JT.js} +0 -49
  21. package/dist/{chunk-J4IBNXGJ.js → chunk-IKHDUZRH.js} +4 -3
  22. package/dist/{chunk-MD4C26II.js → chunk-JGFRDMR6.js} +1 -1
  23. package/dist/{chunk-POSXWWTA.js → chunk-LIRWLNAK.js} +26 -12
  24. package/dist/{chunk-NI5FFCCS.js → chunk-MDPCSXZ4.js} +35 -11
  25. package/dist/chunk-NSBFETWP.js +188 -0
  26. package/dist/{chunk-VIVMW2H2.js → chunk-P27RV5WM.js} +1 -1
  27. package/dist/{chunk-EHYDTZTF.js → chunk-P7VFDSSG.js} +2 -2
  28. package/dist/{chunk-AAPXKR5V.js → chunk-QVAQ5454.js} +181 -544
  29. package/dist/{chunk-HDN7MNGD.js → chunk-S5LR3XYJ.js} +1 -1
  30. package/dist/{chunk-2YP2TVDT.js → chunk-UPA6COHU.js} +5 -5
  31. package/dist/{chunk-AKPFNL7L.js → chunk-VGWJSNHS.js} +1 -1
  32. package/dist/{chunk-SGVNFZHW.js → chunk-W5OOPLNP.js} +3 -3
  33. package/dist/{chunk-2WPW7OT6.js → chunk-ZWKTUQEL.js} +1 -1
  34. package/dist/cli.js +25 -26
  35. package/dist/clock-G3ALCMLJ.js +263 -0
  36. package/dist/{cloud-sync-HDL6PHZI.js → cloud-sync-JV4LJOK3.js} +14 -12
  37. package/dist/connectors/discord-bridge.js +1 -1
  38. package/dist/connectors/slack-bridge.js +1 -1
  39. package/dist/connectors/telegram-bridge.js +1 -1
  40. package/dist/{conversations-M2K4253F.js → conversations-7KVQV7EZ.js} +9 -3
  41. package/dist/create-JTLS7GX3.js +70 -0
  42. package/dist/{create-QWV73WXD.js → create-VQSQHJQW.js} +1 -1
  43. package/dist/{daemon-client-I42FK2BF.js → daemon-client-BCTFGVCZ.js} +2 -2
  44. package/dist/{daemon-restart-G4B2OYAB.js → daemon-restart-4JGBHEJ4.js} +7 -7
  45. package/dist/daemon.js +1474 -1124
  46. package/dist/{db-IC4J52XQ.js → db-HMFPIRO2.js} +1 -1
  47. package/dist/{delete-4JYGD4VN.js → delete-JESHKE7F.js} +1 -1
  48. package/dist/down-NGBMGORS.js +14 -0
  49. package/dist/{env-YJMUMFIY.js → env-CLXXT7M2.js} +2 -2
  50. package/dist/{export-BOJQWBMA.js → export-EGA5M5PB.js} +3 -3
  51. package/dist/extension-WZ4SUPJB.js +174 -0
  52. package/dist/extensions-ECO4RPFQ.js +27 -0
  53. package/dist/{files-M546TKVN.js → files-4VEJDASH.js} +3 -3
  54. package/dist/{history-ALPTNB3I.js → history-EJMMLXDO.js} +17 -2
  55. package/dist/{import-SRTQXBGH.js → import-YCGPMBSI.js} +3 -3
  56. package/dist/{join-J4QU42DL.js → join-2GBJKZEN.js} +1 -1
  57. package/dist/{list-R73GENNL.js → list-Q6O7FGAN.js} +2 -2
  58. package/dist/{login-3QZNR2DF.js → login-RET5WESK.js} +2 -2
  59. package/dist/{login-BKP3AFWN.js → login-RL6AU2SM.js} +3 -3
  60. package/dist/{logout-T53VKCPU.js → logout-CGAGJN3L.js} +2 -2
  61. package/dist/{logout-IQK7FNEK.js → logout-JRPBEMMR.js} +3 -3
  62. package/dist/message-delivery-6YMVNOEC.js +28 -0
  63. package/dist/{migrate-registry-to-db-XC7T5B7P.js → migrate-registry-to-db-FK35IPEH.js} +1 -1
  64. package/dist/{mind-S5V6CK5W.js → mind-LUWRQUQ5.js} +17 -17
  65. package/dist/{mind-activity-tracker-EN6XNXPF.js → mind-activity-tracker-VYN2ZZ2M.js} +3 -3
  66. package/dist/{mind-list-UPJ75GPI.js → mind-list-V5WW5DUA.js} +2 -2
  67. package/dist/{mind-manager-S6ILZVX3.js → mind-manager-YFCOIAAX.js} +6 -6
  68. package/dist/{mind-sleep-BTSWQNAC.js → mind-sleep-R6PTNNW4.js} +2 -2
  69. package/dist/{mind-status-TK5AETEM.js → mind-status-I4ISFJ6I.js} +2 -2
  70. package/dist/{mind-wake-SBAKIDVP.js → mind-wake-67ZQEWAV.js} +2 -2
  71. package/dist/{package-CG4RWUGP.js → package-S2OAA5ZA.js} +11 -5
  72. package/dist/pages-watcher-Z3PKNROC.js +21 -0
  73. package/dist/{read-36UFXN3G.js → read-WQMPTSN2.js} +2 -2
  74. package/dist/{register-CHREOMJ3.js → register-NZDSTLP3.js} +3 -3
  75. package/dist/{registry-NDNOOYG4.js → registry-ODSALQQL.js} +1 -1
  76. package/dist/{reject-LXIZFJ4Q.js → reject-2HZOJEIJ.js} +2 -2
  77. package/dist/{restart-6ESL3NBO.js → restart-QHS3NT64.js} +2 -2
  78. package/dist/{sandbox-5BW5HPXM.js → sandbox-O5FUSF43.js} +3 -3
  79. package/dist/{seed-SSUCYYDF.js → seed-WUQMPLDM.js} +1 -1
  80. package/dist/{send-TAOEZ4NH.js → send-OAN3RYYY.js} +20 -6
  81. package/dist/{setup-JHL5ZEST.js → setup-QMDK5RZX.js} +2 -2
  82. package/dist/{setup-RXYVGGT7.js → setup-XJH3E7YM.js} +45 -14
  83. package/dist/{skill-AUAQTSP5.js → skill-FZIN4W4Q.js} +65 -3
  84. package/dist/skills/dreaming/references/INSTALL.md +3 -17
  85. package/dist/skills/volute-mind/SKILL.md +45 -27
  86. package/dist/sleep-manager-O7YQFCV5.js +30 -0
  87. package/dist/{split-TKJ5OT3P.js → split-EXYGGGQN.js} +1 -1
  88. package/dist/{sprout-UNT7LKKE.js → sprout-AXQ6H5DB.js} +8 -7
  89. package/dist/{start-EUJSS5R4.js → start-MTOVL6SY.js} +2 -2
  90. package/dist/{status-NQJYR4BG.js → status-ZRO37MWR.js} +5 -5
  91. package/dist/{stop-3XAITBBF.js → stop-OK5WEPVC.js} +2 -2
  92. package/dist/{systems-SMEFSHTA.js → systems-W3BBMSOZ.js} +5 -5
  93. package/dist/{tailscale-NY5MUMY3.js → tailscale-BM72RXCJ.js} +1 -1
  94. package/dist/{template-hash-BIMA4ILT.js → template-hash-3HOR4UAJ.js} +1 -1
  95. package/dist/up-BXUAIDXB.js +17 -0
  96. package/dist/{update-PTSH22AZ.js → update-PLPHMMZ2.js} +5 -5
  97. package/dist/{update-check-64FWC4Y2.js → update-check-CVCN7MF6.js} +2 -2
  98. package/dist/{upgrade-HA47CS4C.js → upgrade-I6NPCYUU.js} +1 -1
  99. package/dist/{version-notify-JDUF4HQJ.js → version-notify-2NTWVEHL.js} +18 -16
  100. package/dist/web-assets/assets/index--kREqKl9.js +72 -0
  101. package/dist/web-assets/assets/index-BXYTG0nJ.css +1 -0
  102. package/dist/web-assets/ext-theme.css +111 -0
  103. package/dist/web-assets/index.html +2 -2
  104. package/package.json +11 -5
  105. package/packages/extensions/notes/dist/ui/assets/index-DgawVO5g.css +1 -0
  106. package/packages/extensions/notes/dist/ui/assets/index-qUWoeC4c.js +2 -0
  107. package/packages/extensions/notes/dist/ui/index.html +14 -0
  108. package/packages/extensions/notes/skills/notes/SKILL.md +62 -0
  109. package/packages/extensions/notes/skills/notes/scripts/notes.mjs +185 -0
  110. package/packages/extensions/pages/dist/ui/assets/index-D0HyS-xQ.css +1 -0
  111. package/packages/extensions/pages/dist/ui/assets/index-tLTROSk5.js +2 -0
  112. package/packages/extensions/pages/dist/ui/index.html +14 -0
  113. package/packages/extensions/pages/skills/pages/SKILL.md +58 -0
  114. package/templates/_base/home/VOLUTE.md +1 -1
  115. package/templates/_base/src/lib/logger.ts +10 -49
  116. package/templates/_base/src/lib/router.ts +1 -9
  117. package/templates/claude/src/lib/stream-consumer.ts +1 -4
  118. package/templates/pi/src/lib/event-handler.ts +1 -14
  119. package/dist/chunk-P72MVS4R.js +0 -188
  120. package/dist/chunk-T6HKBWXZ.js +0 -23
  121. package/dist/chunk-ZYGKG6VC.js +0 -22
  122. package/dist/create-D7J73A6H.js +0 -45
  123. package/dist/down-LVBXEULC.js +0 -14
  124. package/dist/message-delivery-HV3S6HZV.js +0 -24
  125. package/dist/notes-XCER3I7M.js +0 -220
  126. package/dist/pages-KJDJX4TA.js +0 -36
  127. package/dist/publish-ZZB33WP4.js +0 -86
  128. package/dist/schedule-QTJMFATP.js +0 -154
  129. package/dist/skills/notes/SKILL.md +0 -34
  130. package/dist/sleep-manager-WMVG2VCL.js +0 -28
  131. package/dist/status-S7UUPNRW.js +0 -38
  132. package/dist/up-GM2JOH2Y.js +0 -17
  133. package/dist/web-assets/assets/index-BZGvToHi.css +0 -1
  134. package/dist/web-assets/assets/index-Cz4TrpzB.js +0 -75
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteSystemDir
4
- } from "./chunk-H7OZRFJB.js";
4
+ } from "./chunk-HHTXM4JT.js";
5
5
 
6
6
  // src/lib/update-check.ts
7
7
  import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -3,7 +3,7 @@ import {
3
3
  readEnv,
4
4
  sharedEnvPath,
5
5
  writeEnv
6
- } from "./chunk-2WPW7OT6.js";
6
+ } from "./chunk-ZWKTUQEL.js";
7
7
  import {
8
8
  logger_default
9
9
  } from "./chunk-YUIHSKR6.js";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-D424ZQGI.js";
13
13
  import {
14
14
  voluteSystemDir
15
- } from "./chunk-H7OZRFJB.js";
15
+ } from "./chunk-HHTXM4JT.js";
16
16
 
17
17
  // src/commands/import.ts
18
18
  import {
@@ -112,7 +112,7 @@ async function run(args) {
112
112
  return;
113
113
  }
114
114
  const wsDir = resolveWorkspace(inputPath);
115
- const { daemonFetch } = await import("./daemon-client-I42FK2BF.js");
115
+ const { daemonFetch } = await import("./daemon-client-BCTFGVCZ.js");
116
116
  const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
117
117
  const client = getClient();
118
118
  const res = await daemonFetch(urlOf(client.api.minds.import.$url()), {
@@ -152,7 +152,7 @@ async function importArchive(archivePath, nameOverride) {
152
152
  console.error(`File not found: ${archivePath}`);
153
153
  process.exit(1);
154
154
  }
155
- const { extractArchive } = await import("./archive-UA4BDFXQ.js");
155
+ const { extractArchive } = await import("./archive-WWDBWYN2.js");
156
156
  const tempDir = resolve2(tmpdir(), `volute-import-${Date.now()}`);
157
157
  mkdirSync(tempDir, { recursive: true });
158
158
  let extracted;
@@ -164,7 +164,7 @@ async function importArchive(archivePath, nameOverride) {
164
164
  process.exit(1);
165
165
  }
166
166
  try {
167
- const { daemonFetch } = await import("./daemon-client-I42FK2BF.js");
167
+ const { daemonFetch } = await import("./daemon-client-BCTFGVCZ.js");
168
168
  const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
169
169
  const client = getClient();
170
170
  const res = await daemonFetch(urlOf(client.api.minds.import.$url()), {
@@ -43,7 +43,7 @@ function composeTemplate(templatesRoot, templateName) {
43
43
  console.error(`Template not found: ${templateName}`);
44
44
  process.exit(1);
45
45
  }
46
- const composedDir = resolve(tmpdir(), `volute-template-${Date.now()}`);
46
+ const composedDir = resolve(tmpdir(), `volute-template-${templateName}-${Date.now()}`);
47
47
  mkdirSync(composedDir, { recursive: true });
48
48
  cpSync(baseDir, composedDir, { recursive: true });
49
49
  for (const file of listFiles(templateDir)) {
@@ -4,17 +4,17 @@ import {
4
4
  modeLabel,
5
5
  pollHealth,
6
6
  startService
7
- } from "./chunk-LAC664WU.js";
7
+ } from "./chunk-FXHXHI2A.js";
8
8
  import {
9
9
  readGlobalConfig
10
- } from "./chunk-IKRVFPWU.js";
10
+ } from "./chunk-7D47T4RB.js";
11
11
  import {
12
12
  parseArgs
13
13
  } from "./chunk-D424ZQGI.js";
14
14
  import {
15
15
  voluteHome,
16
16
  voluteSystemDir
17
- } from "./chunk-H7OZRFJB.js";
17
+ } from "./chunk-HHTXM4JT.js";
18
18
 
19
19
  // src/commands/up.ts
20
20
  import { spawn } from "child_process";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  stateDir,
4
4
  voluteSystemDir
5
- } from "./chunk-H7OZRFJB.js";
5
+ } from "./chunk-HHTXM4JT.js";
6
6
 
7
7
  // src/lib/env.ts
8
8
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
package/dist/cli.js CHANGED
@@ -10,13 +10,13 @@ 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-CG4RWUGP.js");
13
+ const { default: pkg } = await import("./package-S2OAA5ZA.js");
14
14
  console.log(pkg.version);
15
15
  process.exit(0);
16
16
  }
17
17
  var ungatedCommands = /* @__PURE__ */ new Set(["setup", "--help", "-h", "--version", "-v", "update", void 0]);
18
18
  if (!ungatedCommands.has(command)) {
19
- const { isSetupComplete, migrateSetupConfig } = await import("./setup-JHL5ZEST.js");
19
+ const { isSetupComplete, migrateSetupConfig } = await import("./setup-QMDK5RZX.js");
20
20
  migrateSetupConfig();
21
21
  if (!isSetupComplete()) {
22
22
  console.error("Volute is not set up. Run `volute setup` first.");
@@ -25,55 +25,55 @@ if (!ungatedCommands.has(command)) {
25
25
  }
26
26
  switch (command) {
27
27
  case "setup":
28
- await import("./setup-RXYVGGT7.js").then((m) => m.run(args));
28
+ await import("./setup-XJH3E7YM.js").then((m) => m.run(args));
29
29
  break;
30
30
  case "mind":
31
- await import("./mind-S5V6CK5W.js").then((m) => m.run(args));
31
+ await import("./mind-LUWRQUQ5.js").then((m) => m.run(args));
32
32
  break;
33
33
  case "chat":
34
- await import("./chat-M4SX42JD.js").then((m) => m.run(args));
34
+ await import("./chat-TCUNPFGO.js").then((m) => m.run(args));
35
35
  break;
36
36
  case "variant":
37
37
  await import("./variant-7TGZHOU3.js").then((m) => m.run(args));
38
38
  break;
39
+ case "clock":
40
+ await import("./clock-G3ALCMLJ.js").then((m) => m.run(args));
41
+ break;
39
42
  case "schedule":
40
- await import("./schedule-QTJMFATP.js").then((m) => m.run(args));
43
+ await import("./clock-G3ALCMLJ.js").then((m) => m.run(args));
41
44
  break;
42
45
  case "skill":
43
- await import("./skill-AUAQTSP5.js").then((m) => m.run(args));
46
+ await import("./skill-FZIN4W4Q.js").then((m) => m.run(args));
44
47
  break;
45
48
  case "env":
46
- await import("./env-YJMUMFIY.js").then((m) => m.run(args));
49
+ await import("./env-CLXXT7M2.js").then((m) => m.run(args));
47
50
  break;
48
51
  case "up":
49
- await import("./up-GM2JOH2Y.js").then((m) => m.run(args));
52
+ await import("./up-BXUAIDXB.js").then((m) => m.run(args));
50
53
  break;
51
54
  case "down":
52
- await import("./down-LVBXEULC.js").then((m) => m.run(args));
55
+ await import("./down-NGBMGORS.js").then((m) => m.run(args));
53
56
  break;
54
57
  case "restart":
55
- await import("./daemon-restart-G4B2OYAB.js").then((m) => m.run(args));
58
+ await import("./daemon-restart-4JGBHEJ4.js").then((m) => m.run(args));
56
59
  break;
57
60
  case "update":
58
- await import("./update-PTSH22AZ.js").then((m) => m.run(args));
61
+ await import("./update-PLPHMMZ2.js").then((m) => m.run(args));
59
62
  break;
60
63
  case "status":
61
- await import("./status-NQJYR4BG.js").then((m) => m.run(args));
62
- break;
63
- case "notes":
64
- await import("./notes-XCER3I7M.js").then((m) => m.run(args));
64
+ await import("./status-ZRO37MWR.js").then((m) => m.run(args));
65
65
  break;
66
- case "pages":
67
- await import("./pages-KJDJX4TA.js").then((m) => m.run(args));
66
+ case "extension":
67
+ await import("./extension-WZ4SUPJB.js").then((m) => m.run(args));
68
68
  break;
69
69
  case "systems":
70
- await import("./systems-SMEFSHTA.js").then((m) => m.run(args));
70
+ await import("./systems-W3BBMSOZ.js").then((m) => m.run(args));
71
71
  break;
72
72
  case "login":
73
- await import("./login-3QZNR2DF.js").then((m) => m.run(args));
73
+ await import("./login-RET5WESK.js").then((m) => m.run(args));
74
74
  break;
75
75
  case "logout":
76
- await import("./logout-T53VKCPU.js").then((m) => m.run(args));
76
+ await import("./logout-CGAGJN3L.js").then((m) => m.run(args));
77
77
  break;
78
78
  case "--help":
79
79
  case "-h":
@@ -98,16 +98,15 @@ Mind:
98
98
 
99
99
  Configuration:
100
100
  chat Conversations, messages, files, and platform bridges
101
- schedule Manage cron schedules
101
+ clock Schedules, timers, and sleep/wake cycles
102
102
  skill Browse and install skills
103
103
  env Manage environment variables
104
- notes Read and write notes
105
- pages Publish web pages
106
104
 
107
105
  System:
108
106
  setup First-time setup
109
107
  up / down / restart Daemon control
110
108
  status Show daemon & service status
109
+ extension list/install/uninstall Manage extensions
111
110
  login / logout CLI authentication
112
111
  update Update volute
113
112
  systems register/login/logout volute.systems account
@@ -118,7 +117,7 @@ Options:
118
117
 
119
118
  Run 'volute <command> --help' for details.
120
119
 
121
- Mind-scoped commands (chat, schedule, skill, pages)
120
+ Mind-scoped commands (chat, clock, skill)
122
121
  use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
123
122
  break;
124
123
  default:
@@ -127,7 +126,7 @@ Run 'volute --help' for usage.`);
127
126
  process.exit(1);
128
127
  }
129
128
  if (command !== "update") {
130
- import("./update-check-64FWC4Y2.js").then((m) => m.checkForUpdate()).then((result) => {
129
+ import("./update-check-CVCN7MF6.js").then((m) => m.checkForUpdate()).then((result) => {
131
130
  if (result.updateAvailable) {
132
131
  console.error(`
133
132
  Update available: ${result.current} \u2192 ${result.latest}`);
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveMindName
4
+ } from "./chunk-NAOW2CLO.js";
5
+ import {
6
+ daemonFetch
7
+ } from "./chunk-EFVHR7KH.js";
8
+ import {
9
+ getClient,
10
+ urlOf
11
+ } from "./chunk-4RQBJWQX.js";
12
+ import {
13
+ parseArgs
14
+ } from "./chunk-D424ZQGI.js";
15
+ import "./chunk-HHTXM4JT.js";
16
+ import "./chunk-K3NQKI34.js";
17
+
18
+ // src/commands/clock.ts
19
+ import { CronExpressionParser } from "cron-parser";
20
+ async function run(args) {
21
+ const subcommand = args[0];
22
+ switch (subcommand) {
23
+ case "status":
24
+ await clockStatus(args.slice(1));
25
+ break;
26
+ case "list":
27
+ await listSchedules(args.slice(1));
28
+ break;
29
+ case "add":
30
+ await addSchedule(args.slice(1));
31
+ break;
32
+ case "remove":
33
+ await removeSchedule(args.slice(1));
34
+ break;
35
+ case "sleep":
36
+ await import("./mind-sleep-R6PTNNW4.js").then((m) => m.run(args.slice(1)));
37
+ break;
38
+ case "wake":
39
+ await import("./mind-wake-67ZQEWAV.js").then((m) => m.run(args.slice(1)));
40
+ break;
41
+ case "--help":
42
+ case "-h":
43
+ case void 0:
44
+ printUsage();
45
+ break;
46
+ default:
47
+ printUsage();
48
+ process.exit(1);
49
+ }
50
+ }
51
+ function printUsage() {
52
+ console.log(`Usage:
53
+ volute clock status [--mind <name>]
54
+ volute clock list [--mind <name>]
55
+ volute clock add [--mind <name>] --id <name> --cron "..." --message/--script "..." [--channel ch] [--while-sleeping skip|queue|trigger-wake]
56
+ volute clock add [--mind <name>] --id <name> --in <duration> --message/--script "..." [--channel ch] [--while-sleeping skip|queue|trigger-wake]
57
+ volute clock remove [--mind <name>] --id <id>
58
+ volute clock sleep [name] [--wake-at <time>]
59
+ volute clock wake [name]
60
+
61
+ Duration format for --in: 30s, 10m, 1h, 2h30m`);
62
+ }
63
+ function parseDuration(input) {
64
+ const parts = input.match(/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/);
65
+ if (!parts || parts[0] !== input) return null;
66
+ const hours = parseInt(parts[1] || "0", 10);
67
+ const minutes = parseInt(parts[2] || "0", 10);
68
+ const seconds = parseInt(parts[3] || "0", 10);
69
+ const total = hours * 36e5 + minutes * 6e4 + seconds * 1e3;
70
+ return total > 0 ? total : null;
71
+ }
72
+ async function clockStatus(args) {
73
+ const { flags } = parseArgs(args, {
74
+ mind: { type: "string" }
75
+ });
76
+ const mind = resolveMindName(flags);
77
+ const client = getClient();
78
+ const res = await daemonFetch(
79
+ urlOf(client.api.minds[":name"].clock.status.$url({ param: { name: mind } }))
80
+ );
81
+ if (!res.ok) {
82
+ const data = await res.json();
83
+ console.error(data.error ?? `Failed to get clock status: ${res.status}`);
84
+ process.exit(1);
85
+ }
86
+ const status = await res.json();
87
+ if (status.sleep?.sleeping) {
88
+ const since = status.sleep.sleepingSince ? new Date(status.sleep.sleepingSince).toLocaleString() : "unknown";
89
+ console.log(`Sleep: sleeping since ${since}`);
90
+ if (status.sleep.scheduledWakeAt) {
91
+ console.log(` Wake at: ${new Date(status.sleep.scheduledWakeAt).toLocaleString()}`);
92
+ }
93
+ if (status.sleep.voluntaryWakeAt) {
94
+ console.log(
95
+ ` Voluntary wake at: ${new Date(status.sleep.voluntaryWakeAt).toLocaleString()}`
96
+ );
97
+ }
98
+ if (status.sleep.queuedMessageCount > 0) {
99
+ console.log(` Queued messages: ${status.sleep.queuedMessageCount}`);
100
+ }
101
+ } else {
102
+ console.log("Sleep: awake");
103
+ }
104
+ if (status.sleepConfig?.enabled && status.sleepConfig.schedule) {
105
+ console.log(
106
+ ` Schedule: sleep ${status.sleepConfig.schedule.sleep}, wake ${status.sleepConfig.schedule.wake}`
107
+ );
108
+ }
109
+ if (status.upcoming.length > 0) {
110
+ console.log("\nUpcoming (next 24h):");
111
+ for (const u of status.upcoming) {
112
+ const time = new Date(u.at).toLocaleString();
113
+ const label = u.type === "timer" ? "[timer]" : "[cron]";
114
+ console.log(` ${u.id.padEnd(20)} ${label} ${time}`);
115
+ }
116
+ } else {
117
+ console.log("\nNo upcoming events in next 24h.");
118
+ }
119
+ console.log(`
120
+ ${status.schedules.length} schedule(s) configured.`);
121
+ }
122
+ async function listSchedules(args) {
123
+ const { flags } = parseArgs(args, {
124
+ mind: { type: "string" }
125
+ });
126
+ const mind = resolveMindName(flags);
127
+ const client = getClient();
128
+ const res = await daemonFetch(
129
+ urlOf(client.api.minds[":name"].schedules.$url({ param: { name: mind } }))
130
+ );
131
+ if (!res.ok) {
132
+ const data = await res.json();
133
+ console.error(data.error ?? `Failed to list schedules: ${res.status}`);
134
+ process.exit(1);
135
+ }
136
+ const schedules = await res.json();
137
+ if (schedules.length === 0) {
138
+ console.log("No schedules configured.");
139
+ return;
140
+ }
141
+ const idW = Math.max(2, ...schedules.map((s) => s.id.length));
142
+ const schedW = Math.max(8, ...schedules.map((s) => (s.cron ?? s.fireAt ?? "").length));
143
+ const actionLabel = (s) => s.script ? `[script] ${s.script}` : s.message ?? "";
144
+ console.log(`${"ID".padEnd(idW)} ${"SCHEDULE".padEnd(schedW)} ENABLED ACTION`);
145
+ for (const s of schedules) {
146
+ const sched = s.cron ?? (s.fireAt ? `at ${s.fireAt}` : "");
147
+ console.log(
148
+ `${s.id.padEnd(idW)} ${sched.padEnd(schedW)} ${String(s.enabled).padEnd(7)} ${actionLabel(s)}`
149
+ );
150
+ }
151
+ }
152
+ async function addSchedule(args) {
153
+ const { flags } = parseArgs(args, {
154
+ mind: { type: "string" },
155
+ cron: { type: "string" },
156
+ in: { type: "string" },
157
+ message: { type: "string" },
158
+ script: { type: "string" },
159
+ id: { type: "string" },
160
+ channel: { type: "string" },
161
+ "while-sleeping": { type: "string" }
162
+ });
163
+ const mind = resolveMindName(flags);
164
+ if (!flags.id) {
165
+ console.error("--id is required (a descriptive name for this schedule)");
166
+ process.exit(1);
167
+ }
168
+ if (!flags.cron && !flags.in) {
169
+ console.error("--cron or --in is required");
170
+ process.exit(1);
171
+ }
172
+ if (flags.cron && flags.in) {
173
+ console.error("--cron and --in are mutually exclusive");
174
+ process.exit(1);
175
+ }
176
+ if (!flags.message && !flags.script) {
177
+ console.error("--message or --script is required");
178
+ process.exit(1);
179
+ }
180
+ if (flags.message && flags.script) {
181
+ console.error("--message and --script are mutually exclusive");
182
+ process.exit(1);
183
+ }
184
+ const body = {};
185
+ if (flags.cron) {
186
+ try {
187
+ CronExpressionParser.parse(flags.cron);
188
+ } catch {
189
+ console.error(`Invalid cron expression: ${flags.cron}`);
190
+ process.exit(1);
191
+ }
192
+ body.cron = flags.cron;
193
+ }
194
+ if (flags.in) {
195
+ const durationMs = parseDuration(flags.in);
196
+ if (!durationMs) {
197
+ console.error(`Invalid duration: ${flags.in} (expected format: 30s, 10m, 1h, 2h30m)`);
198
+ process.exit(1);
199
+ }
200
+ body.fireAt = new Date(Date.now() + durationMs).toISOString();
201
+ }
202
+ if (flags.message) body.message = flags.message;
203
+ if (flags.script) body.script = flags.script;
204
+ if (flags.id) body.id = flags.id;
205
+ if (flags.channel) body.channel = flags.channel;
206
+ if (flags["while-sleeping"]) {
207
+ const ws = flags["while-sleeping"];
208
+ if (!["skip", "queue", "trigger-wake"].includes(ws)) {
209
+ console.error(`Invalid --while-sleeping value: ${ws} (must be skip, queue, or trigger-wake)`);
210
+ process.exit(1);
211
+ }
212
+ body.whileSleeping = ws;
213
+ }
214
+ const client = getClient();
215
+ const res = await daemonFetch(
216
+ urlOf(client.api.minds[":name"].schedules.$url({ param: { name: mind } })),
217
+ {
218
+ method: "POST",
219
+ headers: { "Content-Type": "application/json" },
220
+ body: JSON.stringify(body)
221
+ }
222
+ );
223
+ if (!res.ok) {
224
+ const data2 = await res.json();
225
+ console.error(data2.error ?? `Failed to add schedule: ${res.status}`);
226
+ process.exit(1);
227
+ }
228
+ const data = await res.json();
229
+ if (flags.in) {
230
+ console.log(`Timer set: ${data.id} (fires in ${flags.in})`);
231
+ } else {
232
+ console.log(`Schedule added: ${data.id}`);
233
+ }
234
+ }
235
+ async function removeSchedule(args) {
236
+ const { flags } = parseArgs(args, {
237
+ mind: { type: "string" },
238
+ id: { type: "string" }
239
+ });
240
+ const mind = resolveMindName(flags);
241
+ if (!flags.id) {
242
+ console.error("--id is required");
243
+ process.exit(1);
244
+ }
245
+ const client = getClient();
246
+ const res = await daemonFetch(
247
+ urlOf(
248
+ client.api.minds[":name"].schedules[":id"].$url({
249
+ param: { name: mind, id: flags.id }
250
+ })
251
+ ),
252
+ { method: "DELETE" }
253
+ );
254
+ if (!res.ok) {
255
+ const data = await res.json();
256
+ console.error(data.error ?? `Failed to remove schedule: ${res.status}`);
257
+ process.exit(1);
258
+ }
259
+ console.log(`Schedule removed: ${flags.id}`);
260
+ }
261
+ export {
262
+ run
263
+ };
@@ -1,24 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  deliverMessage
4
- } from "./chunk-AAPXKR5V.js";
4
+ } from "./chunk-QVAQ5454.js";
5
+ import "./chunk-FSM45XD5.js";
6
+ import "./chunk-LIRWLNAK.js";
7
+ import "./chunk-IKHDUZRH.js";
5
8
  import {
6
9
  getAuthHeaders,
7
10
  getWebhookUrl
8
- } from "./chunk-IAYBDWVG.js";
9
- import "./chunk-K5NAC55T.js";
10
- import "./chunk-VIVMW2H2.js";
11
- import "./chunk-POSXWWTA.js";
12
- import "./chunk-J4IBNXGJ.js";
13
- import "./chunk-2WPW7OT6.js";
11
+ } from "./chunk-2C2VXEBB.js";
12
+ import "./chunk-2NDZC3S7.js";
13
+ import "./chunk-P27RV5WM.js";
14
+ import "./chunk-MDPCSXZ4.js";
15
+ import "./chunk-ZWKTUQEL.js";
14
16
  import {
15
17
  logger_default
16
18
  } from "./chunk-YUIHSKR6.js";
17
- import "./chunk-AW7PFDVN.js";
18
- import "./chunk-RKQEHRBB.js";
19
- import "./chunk-IKRVFPWU.js";
20
- import "./chunk-T6HKBWXZ.js";
21
- import "./chunk-H7OZRFJB.js";
19
+ import "./chunk-CVH6Y2YG.js";
20
+ import "./chunk-G3GBKZGG.js";
21
+ import "./chunk-7D47T4RB.js";
22
+ import "./chunk-A6TUJJ3L.js";
23
+ import "./chunk-HHTXM4JT.js";
22
24
  import "./chunk-K3NQKI34.js";
23
25
 
24
26
  // src/lib/cloud-sync.ts
@@ -6,7 +6,7 @@ import {
6
6
  } from "../chunk-KTLFDYPT.js";
7
7
  import {
8
8
  slugify
9
- } from "../chunk-T6HKBWXZ.js";
9
+ } from "../chunk-A6TUJJ3L.js";
10
10
  import "../chunk-K3NQKI34.js";
11
11
 
12
12
  // src/connectors/discord-bridge.ts
@@ -6,7 +6,7 @@ import {
6
6
  } from "../chunk-KTLFDYPT.js";
7
7
  import {
8
8
  slugify
9
- } from "../chunk-T6HKBWXZ.js";
9
+ } from "../chunk-A6TUJJ3L.js";
10
10
  import "../chunk-K3NQKI34.js";
11
11
 
12
12
  // src/connectors/slack-bridge.ts
@@ -6,7 +6,7 @@ import {
6
6
  } from "../chunk-KTLFDYPT.js";
7
7
  import {
8
8
  slugify
9
- } from "../chunk-T6HKBWXZ.js";
9
+ } from "../chunk-A6TUJJ3L.js";
10
10
  import "../chunk-K3NQKI34.js";
11
11
 
12
12
  // src/connectors/telegram-bridge.ts
@@ -14,19 +14,22 @@ import {
14
14
  getOrCreateConversation,
15
15
  getParticipants,
16
16
  getUnreadCounts,
17
+ isConversationForMind,
17
18
  isParticipant,
18
19
  isParticipantOrOwner,
19
20
  joinChannel,
20
21
  leaveChannel,
21
22
  listChannels,
23
+ listConversationsForMind,
22
24
  listConversationsForUser,
23
25
  listConversationsWithParticipants,
24
26
  markConversationRead,
27
+ migrateGroupDMsToChannels,
25
28
  removeParticipant
26
- } from "./chunk-IAYBDWVG.js";
27
- import "./chunk-VIVMW2H2.js";
29
+ } from "./chunk-2C2VXEBB.js";
30
+ import "./chunk-P27RV5WM.js";
28
31
  import "./chunk-YUIHSKR6.js";
29
- import "./chunk-H7OZRFJB.js";
32
+ import "./chunk-HHTXM4JT.js";
30
33
  import "./chunk-K3NQKI34.js";
31
34
  export {
32
35
  addMessage,
@@ -43,13 +46,16 @@ export {
43
46
  getOrCreateConversation,
44
47
  getParticipants,
45
48
  getUnreadCounts,
49
+ isConversationForMind,
46
50
  isParticipant,
47
51
  isParticipantOrOwner,
48
52
  joinChannel,
49
53
  leaveChannel,
50
54
  listChannels,
55
+ listConversationsForMind,
51
56
  listConversationsForUser,
52
57
  listConversationsWithParticipants,
53
58
  markConversationRead,
59
+ migrateGroupDMsToChannels,
54
60
  removeParticipant
55
61
  };
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveMindName
4
+ } from "./chunk-NAOW2CLO.js";
5
+ import {
6
+ daemonFetch
7
+ } from "./chunk-EFVHR7KH.js";
8
+ import {
9
+ parseArgs
10
+ } from "./chunk-D424ZQGI.js";
11
+ import "./chunk-HHTXM4JT.js";
12
+ import "./chunk-K3NQKI34.js";
13
+
14
+ // src/commands/chat/create.ts
15
+ async function run(args) {
16
+ const { flags } = parseArgs(args, {
17
+ mind: { type: "string" },
18
+ participants: { type: "string" },
19
+ name: { type: "string" },
20
+ channel: { type: "string" }
21
+ });
22
+ if (!flags.participants) {
23
+ console.error(
24
+ 'Usage: volute chat create --participants u1,u2 [--name "..."] [--channel <name>] [--mind <name>]'
25
+ );
26
+ process.exit(1);
27
+ }
28
+ const mindName = resolveMindName(flags);
29
+ const participants = flags.participants.split(",").map((p) => p.trim());
30
+ if (participants.length > 2 && !flags.channel) {
31
+ console.error("Use --channel <name> for multi-participant conversations");
32
+ process.exit(1);
33
+ }
34
+ if (flags.channel) {
35
+ const res = await daemonFetch("/api/volute/channels", {
36
+ method: "POST",
37
+ headers: { "Content-Type": "application/json" },
38
+ body: JSON.stringify({
39
+ name: flags.channel,
40
+ participantNames: participants
41
+ })
42
+ });
43
+ if (!res.ok) {
44
+ const data = await res.json().catch(() => ({}));
45
+ console.error(data.error ?? `Failed to create channel: ${res.status}`);
46
+ process.exit(1);
47
+ }
48
+ const conv = await res.json();
49
+ console.log(`Created channel #${flags.channel}: ${conv.id}`);
50
+ } else {
51
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mindName)}/conversations`, {
52
+ method: "POST",
53
+ headers: { "Content-Type": "application/json" },
54
+ body: JSON.stringify({
55
+ participantNames: participants,
56
+ title: flags.name
57
+ })
58
+ });
59
+ if (!res.ok) {
60
+ const data = await res.json().catch(() => ({}));
61
+ console.error(data.error ?? `Failed to create conversation: ${res.status}`);
62
+ process.exit(1);
63
+ }
64
+ const conv = await res.json();
65
+ console.log(`Created conversation: ${conv.id}`);
66
+ }
67
+ }
68
+ export {
69
+ run
70
+ };
@@ -17,7 +17,7 @@ async function run(args) {
17
17
  process.exit(1);
18
18
  }
19
19
  const skills = flags.skills === "none" ? [] : flags.skills ? flags.skills.split(",") : void 0;
20
- const { daemonFetch } = await import("./daemon-client-I42FK2BF.js");
20
+ const { daemonFetch } = await import("./daemon-client-BCTFGVCZ.js");
21
21
  const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
22
22
  const client = getClient();
23
23
  const res = await daemonFetch(urlOf(client.api.minds.$url()), {