volute 0.27.0 → 0.29.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 (81) hide show
  1. package/README.md +20 -10
  2. package/dist/accept-666DIZX2.js +41 -0
  3. package/dist/api.d.ts +342 -143
  4. package/dist/{chat-MHJ3L6JQ.js → chat-KTPOR2JT.js} +18 -8
  5. package/dist/chunk-A6TUJJ3L.js +19 -0
  6. package/dist/{chunk-OQZH4PBB.js → chunk-CMILSHZD.js} +199 -277
  7. package/dist/{chunk-K5NAC55T.js → chunk-CQ7SNKNI.js} +1 -1
  8. package/dist/{chunk-PHSAT7YL.js → chunk-EHZKEMMV.js} +5 -5
  9. package/dist/{chunk-IAYBDWVG.js → chunk-FLZGS4QH.js} +145 -0
  10. package/dist/{chunk-USUXRNVD.js → chunk-J4IBNXGJ.js} +0 -2
  11. package/dist/chunk-MD4C26II.js +128 -0
  12. package/dist/{chunk-4WXYUOAK.js → chunk-NI5FFCCS.js} +8 -1
  13. package/dist/{chunk-JKOWNZ4P.js → chunk-P72MVS4R.js} +1 -40
  14. package/dist/chunk-THUUIU3E.js +232 -0
  15. package/dist/cli.js +21 -30
  16. package/dist/clock-DGCBVGYA.js +259 -0
  17. package/dist/{cloud-sync-T7M3ESC3.js → cloud-sync-KILFGV5Q.js} +7 -7
  18. package/dist/connectors/discord-bridge.js +1 -1
  19. package/dist/connectors/slack-bridge.js +1 -1
  20. package/dist/connectors/telegram-bridge.js +1 -1
  21. package/dist/{conversations-M2K4253F.js → conversations-P5BL7RMX.js} +7 -1
  22. package/dist/create-DFCAGEE5.js +70 -0
  23. package/dist/{daemon-restart-M2QTYMEG.js → daemon-restart-UHOMICXT.js} +1 -1
  24. package/dist/daemon.js +715 -661
  25. package/dist/files-M546TKVN.js +46 -0
  26. package/dist/{login-XX37I52P.js → login-BKP3AFWN.js} +7 -17
  27. package/dist/logout-IQK7FNEK.js +20 -0
  28. package/dist/{message-delivery-LDXLGERA.js → message-delivery-Q7VUMIEI.js} +11 -9
  29. package/dist/{mind-DI33C74K.js → mind-S5V6CK5W.js} +8 -13
  30. package/dist/{mind-activity-tracker-EN6XNXPF.js → mind-activity-tracker-WRHFI3YW.js} +1 -1
  31. package/dist/mind-list-UPJ75GPI.js +29 -0
  32. package/dist/{mind-manager-M6EMUW5I.js → mind-manager-P66HQDNE.js} +2 -2
  33. package/dist/mind-status-TK5AETEM.js +55 -0
  34. package/dist/{package-7WY6VKU3.js → package-OFKXNKJF.js} +1 -1
  35. package/dist/{pages-6EBS6CBR.js → pages-EUJR52AH.js} +5 -5
  36. package/dist/pages-watcher-P7QECRE2.js +21 -0
  37. package/dist/{publish-66UB2ZFY.js → publish-ZZB33WP4.js} +6 -17
  38. package/dist/{register-6B2CXTYM.js → register-CHREOMJ3.js} +5 -24
  39. package/dist/reject-LXIZFJ4Q.js +39 -0
  40. package/dist/{sandbox-TGBX22DS.js → sandbox-5BW5HPXM.js} +1 -1
  41. package/dist/{send-ZNCJDSRP.js → send-TAOEZ4NH.js} +64 -6
  42. package/dist/skills/dreaming/references/INSTALL.md +3 -17
  43. package/dist/skills/shared-files/SKILL.md +44 -0
  44. package/dist/skills/shared-files/scripts/merge.ts +72 -0
  45. package/dist/skills/shared-files/scripts/pull.ts +52 -0
  46. package/dist/skills/volute-mind/SKILL.md +48 -22
  47. package/dist/{sleep-manager-MWYHM5HV.js → sleep-manager-G4B5GW5P.js} +7 -7
  48. package/dist/{sprout-IJVVKSJ2.js → sprout-UNT7LKKE.js} +1 -1
  49. package/dist/{status-77YEPHMW.js → status-NQJYR4BG.js} +45 -1
  50. package/dist/{status-THLOBLWG.js → status-S7UUPNRW.js} +3 -13
  51. package/dist/systems-SMEFSHTA.js +60 -0
  52. package/dist/{up-NKSMXBWR.js → up-W6VAK2XE.js} +1 -1
  53. package/dist/{version-notify-5Z4MNR6M.js → version-notify-WDHRO3XD.js} +11 -11
  54. package/dist/web-assets/assets/index-BmKDnWDB.css +1 -0
  55. package/dist/web-assets/assets/index-CLJMx-GA.js +71 -0
  56. package/dist/web-assets/index.html +2 -2
  57. package/package.json +1 -1
  58. package/templates/_base/src/lib/logger.ts +10 -53
  59. package/templates/_base/src/lib/router.ts +1 -9
  60. package/templates/claude/src/lib/stream-consumer.ts +1 -4
  61. package/templates/pi/src/lib/event-handler.ts +1 -14
  62. package/dist/auth-D3OT2ARB.js +0 -37
  63. package/dist/chunk-KDGS53OS.js +0 -50
  64. package/dist/chunk-RWKVSSLY.js +0 -26
  65. package/dist/chunk-T6HKBWXZ.js +0 -23
  66. package/dist/create-D7J73A6H.js +0 -45
  67. package/dist/file-CR36YUPD.js +0 -204
  68. package/dist/log-ABYNVYJ3.js +0 -39
  69. package/dist/logout-W4KOOBIT.js +0 -18
  70. package/dist/logs-U35JR2KE.js +0 -77
  71. package/dist/merge-LNSMSAOF.js +0 -46
  72. package/dist/pull-XCHJTM5M.js +0 -39
  73. package/dist/schedule-QTJMFATP.js +0 -154
  74. package/dist/service-6LIN3F3K.js +0 -122
  75. package/dist/shared-ML5I4Q2A.js +0 -39
  76. package/dist/status-7GA4SM4Y.js +0 -35
  77. package/dist/web-assets/assets/index-CI5wgghI.css +0 -1
  78. package/dist/web-assets/assets/index-is5CvJWH.js +0 -75
  79. package/dist/{chunk-GIE6CSN5.js → chunk-DUAUMCEE.js} +0 -0
  80. package/dist/{history-XKRTAFS2.js → history-ALPTNB3I.js} +0 -0
  81. package/dist/{setup-JG4QAEBV.js → setup-RXYVGGT7.js} +3 -3
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveMindName
4
+ } from "./chunk-NAOW2CLO.js";
5
+ import {
6
+ daemonFetch
7
+ } from "./chunk-JGFVMROS.js";
8
+ import {
9
+ formatFileSize
10
+ } from "./chunk-MD4C26II.js";
11
+ import {
12
+ parseArgs
13
+ } from "./chunk-D424ZQGI.js";
14
+ import "./chunk-H7OZRFJB.js";
15
+ import "./chunk-K3NQKI34.js";
16
+
17
+ // src/commands/chat/files.ts
18
+ async function run(args) {
19
+ const { flags } = parseArgs(args, {
20
+ mind: { type: "string" }
21
+ });
22
+ const mind = resolveMindName(flags);
23
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mind)}/files/pending`);
24
+ if (!res.ok) {
25
+ const data = await res.json();
26
+ console.error(data.error ?? `Failed to list pending files: ${res.status}`);
27
+ process.exit(1);
28
+ }
29
+ const pending = await res.json();
30
+ if (pending.length === 0) {
31
+ console.log("No pending files.");
32
+ return;
33
+ }
34
+ const idW = Math.max(2, ...pending.map((p) => p.id.length));
35
+ const senderW = Math.max(6, ...pending.map((p) => p.sender.length));
36
+ const fileW = Math.max(4, ...pending.map((p) => p.filename.length));
37
+ console.log(`${"ID".padEnd(idW)} ${"SENDER".padEnd(senderW)} ${"FILE".padEnd(fileW)} SIZE`);
38
+ for (const p of pending) {
39
+ console.log(
40
+ `${p.id.padEnd(idW)} ${p.sender.padEnd(senderW)} ${p.filename.padEnd(fileW)} ${formatFileSize(p.size)}`
41
+ );
42
+ }
43
+ }
44
+ export {
45
+ run
46
+ };
@@ -1,14 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- systemsFetch
4
- } from "./chunk-RWKVSSLY.js";
5
2
  import {
6
3
  promptLine
7
4
  } from "./chunk-SSI47XP2.js";
8
5
  import {
9
- readSystemsConfig,
10
- writeSystemsConfig
11
- } from "./chunk-KDGS53OS.js";
6
+ daemonFetch
7
+ } from "./chunk-JGFVMROS.js";
12
8
  import {
13
9
  parseArgs
14
10
  } from "./chunk-D424ZQGI.js";
@@ -16,20 +12,14 @@ import "./chunk-H7OZRFJB.js";
16
12
  import "./chunk-K3NQKI34.js";
17
13
 
18
14
  // src/commands/pages/login.ts
19
- var DEFAULT_API_URL = "https://volute.systems";
20
15
  async function run(args) {
21
16
  const { flags } = parseArgs(args, {
22
17
  key: { type: "string" }
23
18
  });
24
- const existing = readSystemsConfig();
25
- if (existing) {
26
- console.error(`Already logged in as "${existing.system}". Run "volute auth logout" first.`);
27
- process.exit(1);
28
- }
29
19
  let key = flags.key;
30
20
  if (!key) {
31
21
  if (!process.stdin.isTTY) {
32
- console.error("Usage: volute auth login --key <api-key>");
22
+ console.error("Usage: volute systems login --key <api-key>");
33
23
  process.exit(1);
34
24
  }
35
25
  key = await promptLine("API key: ");
@@ -38,9 +28,10 @@ async function run(args) {
38
28
  process.exit(1);
39
29
  }
40
30
  }
41
- const apiUrl = process.env.VOLUTE_SYSTEMS_URL || DEFAULT_API_URL;
42
- const res = await systemsFetch(`${apiUrl}/api/whoami`, {
43
- headers: { Authorization: `Bearer ${key}` }
31
+ const res = await daemonFetch("/api/system/login", {
32
+ method: "POST",
33
+ headers: { "Content-Type": "application/json" },
34
+ body: JSON.stringify({ key })
44
35
  });
45
36
  if (!res.ok) {
46
37
  const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
@@ -48,7 +39,6 @@ async function run(args) {
48
39
  process.exit(1);
49
40
  }
50
41
  const { system } = await res.json();
51
- writeSystemsConfig({ apiKey: key, system, apiUrl });
52
42
  console.log(`Logged in as "${system}". Credentials saved.`);
53
43
  }
54
44
  export {
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ daemonFetch
4
+ } from "./chunk-JGFVMROS.js";
5
+ import "./chunk-H7OZRFJB.js";
6
+ import "./chunk-K3NQKI34.js";
7
+
8
+ // src/commands/pages/logout.ts
9
+ async function run() {
10
+ const res = await daemonFetch("/api/system/logout", { method: "POST" });
11
+ if (!res.ok) {
12
+ const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
13
+ console.error(`Logout failed: ${body.error}`);
14
+ process.exit(1);
15
+ }
16
+ console.log("Logged out. Credentials removed.");
17
+ }
18
+ export {
19
+ run
20
+ };
@@ -2,24 +2,26 @@
2
2
  import {
3
3
  deliverMessage,
4
4
  extractTextContent,
5
- recordInbound
6
- } from "./chunk-OQZH4PBB.js";
7
- import "./chunk-KDGS53OS.js";
8
- import "./chunk-K5NAC55T.js";
9
- import "./chunk-PHSAT7YL.js";
10
- import "./chunk-USUXRNVD.js";
11
- import "./chunk-IAYBDWVG.js";
5
+ recordInbound,
6
+ resolveSleepAction
7
+ } from "./chunk-CMILSHZD.js";
8
+ import "./chunk-THUUIU3E.js";
9
+ import "./chunk-FLZGS4QH.js";
10
+ import "./chunk-CQ7SNKNI.js";
12
11
  import "./chunk-VIVMW2H2.js";
12
+ import "./chunk-EHZKEMMV.js";
13
+ import "./chunk-J4IBNXGJ.js";
13
14
  import "./chunk-2WPW7OT6.js";
14
15
  import "./chunk-YUIHSKR6.js";
15
16
  import "./chunk-AW7PFDVN.js";
16
17
  import "./chunk-RKQEHRBB.js";
17
18
  import "./chunk-IKRVFPWU.js";
18
- import "./chunk-T6HKBWXZ.js";
19
+ import "./chunk-A6TUJJ3L.js";
19
20
  import "./chunk-H7OZRFJB.js";
20
21
  import "./chunk-K3NQKI34.js";
21
22
  export {
22
23
  deliverMessage,
23
24
  extractTextContent,
24
- recordInbound
25
+ recordInbound,
26
+ resolveSleepAction
25
27
  };
@@ -21,20 +21,15 @@ async function run(args) {
21
21
  await import("./delete-4JYGD4VN.js").then((m) => m.run(args.slice(1)));
22
22
  break;
23
23
  case "list":
24
- await import("./status-77YEPHMW.js").then((m) => m.run(args.slice(1)));
24
+ await import("./mind-list-UPJ75GPI.js").then((m) => m.run(args.slice(1)));
25
25
  break;
26
- case "status": {
27
- const rest = args.slice(1);
28
- if (!rest[0] && process.env.VOLUTE_MIND) {
29
- rest.unshift(process.env.VOLUTE_MIND);
30
- }
31
- await import("./status-77YEPHMW.js").then((m) => m.run(rest));
26
+ case "status":
27
+ await import("./mind-status-TK5AETEM.js").then((m) => m.run(args.slice(1)));
32
28
  break;
33
- }
34
- case "logs": {
29
+ case "history": {
35
30
  const rest = args.slice(1);
36
- const logsArgs = transformMindFlag(rest);
37
- await import("./logs-U35JR2KE.js").then((m) => m.run(logsArgs));
31
+ const historyArgs = transformMindFlag(rest);
32
+ await import("./history-ALPTNB3I.js").then((m) => m.run(historyArgs));
38
33
  break;
39
34
  }
40
35
  case "upgrade":
@@ -50,7 +45,7 @@ async function run(args) {
50
45
  await import("./seed-SSUCYYDF.js").then((m) => m.run(args.slice(1)));
51
46
  break;
52
47
  case "sprout":
53
- await import("./sprout-IJVVKSJ2.js").then((m) => m.run(args.slice(1)));
48
+ await import("./sprout-UNT7LKKE.js").then((m) => m.run(args.slice(1)));
54
49
  break;
55
50
  case "sleep":
56
51
  await import("./mind-sleep-BTSWQNAC.js").then((m) => m.run(args.slice(1)));
@@ -90,7 +85,7 @@ function printUsage() {
90
85
  volute mind delete [name] [--force]
91
86
  volute mind list
92
87
  volute mind status [name]
93
- volute mind logs [name] [--follow] [-n N]
88
+ volute mind history [name] [--channel <ch>] [--limit N] [--full]
94
89
  volute mind sprout
95
90
  volute mind sleep [name] [--wake-at <time>]
96
91
  volute mind wake [name]
@@ -4,7 +4,7 @@ import {
4
4
  markIdle,
5
5
  onMindEvent,
6
6
  stopAll
7
- } from "./chunk-K5NAC55T.js";
7
+ } from "./chunk-CQ7SNKNI.js";
8
8
  import "./chunk-VIVMW2H2.js";
9
9
  import "./chunk-YUIHSKR6.js";
10
10
  import "./chunk-H7OZRFJB.js";
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ daemonFetch
4
+ } from "./chunk-JGFVMROS.js";
5
+ import "./chunk-H7OZRFJB.js";
6
+ import "./chunk-K3NQKI34.js";
7
+
8
+ // src/commands/mind-list.ts
9
+ async function run(_args) {
10
+ const res = await daemonFetch("/api/minds");
11
+ if (!res.ok) {
12
+ const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
13
+ console.error(`Failed to list minds: ${body.error}`);
14
+ process.exit(1);
15
+ }
16
+ const minds = await res.json();
17
+ if (minds.length === 0) {
18
+ console.log("No minds configured.");
19
+ return;
20
+ }
21
+ for (const mind of minds) {
22
+ const status = mind.status ?? (mind.running ? "running" : "stopped");
23
+ const label = mind.stage === "seed" ? " (seed)" : "";
24
+ console.log(` ${mind.name}: ${status}${label}`);
25
+ }
26
+ }
27
+ export {
28
+ run
29
+ };
@@ -3,8 +3,8 @@ import {
3
3
  MindManager,
4
4
  getMindManager,
5
5
  initMindManager
6
- } from "./chunk-PHSAT7YL.js";
7
- import "./chunk-USUXRNVD.js";
6
+ } from "./chunk-EHZKEMMV.js";
7
+ import "./chunk-J4IBNXGJ.js";
8
8
  import "./chunk-2WPW7OT6.js";
9
9
  import "./chunk-YUIHSKR6.js";
10
10
  import "./chunk-RKQEHRBB.js";
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveMindName
4
+ } from "./chunk-NAOW2CLO.js";
5
+ import {
6
+ daemonFetch
7
+ } from "./chunk-JGFVMROS.js";
8
+ import "./chunk-H7OZRFJB.js";
9
+ import "./chunk-K3NQKI34.js";
10
+
11
+ // src/commands/mind-status.ts
12
+ async function run(args) {
13
+ const name = args[0] || (process.env.VOLUTE_MIND ? resolveMindName({}) : void 0);
14
+ if (!name) {
15
+ console.error("Usage: volute mind status <name>");
16
+ process.exit(1);
17
+ }
18
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(name)}`);
19
+ if (!res.ok) {
20
+ if (res.status === 404) {
21
+ console.error(`Mind "${name}" not found`);
22
+ } else {
23
+ const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
24
+ console.error(`Failed to get mind status: ${body.error}`);
25
+ }
26
+ process.exit(1);
27
+ }
28
+ const mind = await res.json();
29
+ const status = mind.status ?? (mind.running ? "running" : "stopped");
30
+ console.log(`Mind: ${mind.name}`);
31
+ console.log(`Status: ${status}`);
32
+ console.log(`Port: ${mind.port}`);
33
+ if (mind.stage) console.log(`Stage: ${mind.stage}`);
34
+ if (mind.parent) console.log(`Parent: ${mind.parent}`);
35
+ if (mind.model) console.log(`Model: ${mind.model}`);
36
+ if (mind.channels && mind.channels.length > 0) {
37
+ console.log(`
38
+ Channels:`);
39
+ for (const ch of mind.channels) {
40
+ console.log(` ${ch.type}: ${ch.status}`);
41
+ }
42
+ }
43
+ if (mind.variants && mind.variants.length > 0) {
44
+ console.log(`
45
+ Variants:`);
46
+ for (const v of mind.variants) {
47
+ console.log(` ${v.name}: ${v.status}`);
48
+ }
49
+ }
50
+ if (mind.hasPages) console.log(`
51
+ Pages: published`);
52
+ }
53
+ export {
54
+ run
55
+ };
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "volute",
7
- version: "0.27.0",
7
+ version: "0.29.0",
8
8
  description: "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
9
9
  type: "module",
10
10
  license: "MIT",
@@ -6,10 +6,10 @@ async function run(args) {
6
6
  const subcommand = args[0];
7
7
  switch (subcommand) {
8
8
  case "publish":
9
- await import("./publish-66UB2ZFY.js").then((m) => m.run(args.slice(1)));
9
+ await import("./publish-ZZB33WP4.js").then((m) => m.run(args.slice(1)));
10
10
  break;
11
11
  case "status":
12
- await import("./status-THLOBLWG.js").then((m) => m.run(args.slice(1)));
12
+ await import("./status-S7UUPNRW.js").then((m) => m.run(args.slice(1)));
13
13
  break;
14
14
  case "--help":
15
15
  case "-h":
@@ -27,9 +27,9 @@ function printUsage() {
27
27
  volute pages status [--mind <name>] Show publish status
28
28
 
29
29
  Account commands:
30
- volute auth register [--name <name>]
31
- volute auth login [--key <key>]
32
- volute auth logout`);
30
+ volute systems register [--name <name>]
31
+ volute systems login [--key <key>]
32
+ volute systems logout`);
33
33
  }
34
34
  export {
35
35
  run
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getCachedRecentPages,
4
+ getCachedSites,
5
+ startSystemWatcher,
6
+ startWatcher,
7
+ stopAllWatchers,
8
+ stopWatcher
9
+ } from "./chunk-THUUIU3E.js";
10
+ import "./chunk-VIVMW2H2.js";
11
+ import "./chunk-YUIHSKR6.js";
12
+ import "./chunk-H7OZRFJB.js";
13
+ import "./chunk-K3NQKI34.js";
14
+ export {
15
+ getCachedRecentPages,
16
+ getCachedSites,
17
+ startSystemWatcher,
18
+ startWatcher,
19
+ stopAllWatchers,
20
+ stopWatcher
21
+ };
@@ -1,16 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- systemsFetch
4
- } from "./chunk-RWKVSSLY.js";
5
2
  import {
6
3
  resolveMindName
7
4
  } from "./chunk-NAOW2CLO.js";
8
5
  import {
9
- sharedDir
10
- } from "./chunk-JKOWNZ4P.js";
6
+ daemonFetch
7
+ } from "./chunk-JGFVMROS.js";
11
8
  import {
12
- readSystemsConfig
13
- } from "./chunk-KDGS53OS.js";
9
+ sharedDir
10
+ } from "./chunk-P72MVS4R.js";
14
11
  import "./chunk-YUIHSKR6.js";
15
12
  import "./chunk-AW7PFDVN.js";
16
13
  import "./chunk-RKQEHRBB.js";
@@ -30,11 +27,6 @@ async function run(args) {
30
27
  mind: { type: "string" },
31
28
  system: { type: "boolean" }
32
29
  });
33
- const config = readSystemsConfig();
34
- if (!config) {
35
- console.error('Not logged in. Run "volute auth register" or "volute auth login" first.');
36
- process.exit(1);
37
- }
38
30
  let mindName;
39
31
  let pagesDir;
40
32
  if (flags.system) {
@@ -57,12 +49,9 @@ async function run(args) {
57
49
  process.exit(1);
58
50
  }
59
51
  console.log(`Publishing ${Object.keys(files).length} file(s) for ${mindName}...`);
60
- const res = await systemsFetch(`${config.apiUrl}/api/pages/publish/${mindName}`, {
52
+ const res = await daemonFetch(`/api/system/pages/publish/${mindName}`, {
61
53
  method: "PUT",
62
- headers: {
63
- "Content-Type": "application/json",
64
- Authorization: `Bearer ${config.apiKey}`
65
- },
54
+ headers: { "Content-Type": "application/json" },
66
55
  body: JSON.stringify({ files })
67
56
  });
68
57
  if (!res.ok) {
@@ -1,14 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- systemsFetch
4
- } from "./chunk-RWKVSSLY.js";
5
2
  import {
6
3
  promptLine
7
4
  } from "./chunk-SSI47XP2.js";
8
5
  import {
9
- readSystemsConfig,
10
- writeSystemsConfig
11
- } from "./chunk-KDGS53OS.js";
6
+ daemonFetch
7
+ } from "./chunk-JGFVMROS.js";
12
8
  import {
13
9
  parseArgs
14
10
  } from "./chunk-D424ZQGI.js";
@@ -16,20 +12,14 @@ import "./chunk-H7OZRFJB.js";
16
12
  import "./chunk-K3NQKI34.js";
17
13
 
18
14
  // src/commands/pages/register.ts
19
- var DEFAULT_API_URL = "https://volute.systems";
20
15
  async function run(args) {
21
16
  const { flags } = parseArgs(args, {
22
17
  name: { type: "string" }
23
18
  });
24
- const existing = readSystemsConfig();
25
- if (existing) {
26
- console.error(`Already registered as "${existing.system}". Run "volute auth logout" first.`);
27
- process.exit(1);
28
- }
29
19
  let name = flags.name;
30
20
  if (!name) {
31
21
  if (!process.stdin.isTTY) {
32
- console.error("Usage: volute auth register --name <system-name>");
22
+ console.error("Usage: volute systems register --name <system-name>");
33
23
  process.exit(1);
34
24
  }
35
25
  name = await promptLine("Choose a system name: ");
@@ -38,8 +28,7 @@ async function run(args) {
38
28
  process.exit(1);
39
29
  }
40
30
  }
41
- const apiUrl = process.env.VOLUTE_SYSTEMS_URL || DEFAULT_API_URL;
42
- const res = await systemsFetch(`${apiUrl}/api/register`, {
31
+ const res = await daemonFetch("/api/system/register", {
43
32
  method: "POST",
44
33
  headers: { "Content-Type": "application/json" },
45
34
  body: JSON.stringify({ name })
@@ -49,15 +38,7 @@ async function run(args) {
49
38
  console.error(`Registration failed: ${body.error}`);
50
39
  process.exit(1);
51
40
  }
52
- const { apiKey, system } = await res.json();
53
- try {
54
- writeSystemsConfig({ apiKey, system, apiUrl });
55
- } catch (err) {
56
- console.error(`Failed to save credentials: ${err.message}`);
57
- console.error(`Your API key is: ${apiKey}`);
58
- console.error(`Save it and run: volute auth login --key ${apiKey}`);
59
- process.exit(1);
60
- }
41
+ const { system } = await res.json();
61
42
  console.log(`Registered as "${system}". Credentials saved.`);
62
43
  }
63
44
  export {
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveMindName
4
+ } from "./chunk-NAOW2CLO.js";
5
+ import {
6
+ daemonFetch
7
+ } from "./chunk-JGFVMROS.js";
8
+ import {
9
+ parseArgs
10
+ } from "./chunk-D424ZQGI.js";
11
+ import "./chunk-H7OZRFJB.js";
12
+ import "./chunk-K3NQKI34.js";
13
+
14
+ // src/commands/chat/reject.ts
15
+ async function run(args) {
16
+ const { positional, flags } = parseArgs(args, {
17
+ mind: { type: "string" }
18
+ });
19
+ const mind = resolveMindName(flags);
20
+ const id = positional[0];
21
+ if (!id) {
22
+ console.error("Usage: volute chat reject <id> [--mind <name>]");
23
+ process.exit(1);
24
+ }
25
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mind)}/files/reject`, {
26
+ method: "POST",
27
+ headers: { "Content-Type": "application/json" },
28
+ body: JSON.stringify({ id })
29
+ });
30
+ if (!res.ok) {
31
+ const data = await res.json();
32
+ console.error(data.error ?? `Failed to reject file: ${res.status}`);
33
+ process.exit(1);
34
+ }
35
+ console.log(`File rejected: ${id}`);
36
+ }
37
+ export {
38
+ run
39
+ };
@@ -5,7 +5,7 @@ import {
5
5
  isSandboxEnabled,
6
6
  shellEscape,
7
7
  wrapForSandbox
8
- } from "./chunk-USUXRNVD.js";
8
+ } from "./chunk-J4IBNXGJ.js";
9
9
  import "./chunk-YUIHSKR6.js";
10
10
  import "./chunk-IKRVFPWU.js";
11
11
  import "./chunk-H7OZRFJB.js";
@@ -12,6 +12,9 @@ import {
12
12
  getClient,
13
13
  urlOf
14
14
  } from "./chunk-4RQBJWQX.js";
15
+ import {
16
+ formatFileSize
17
+ } from "./chunk-MD4C26II.js";
15
18
  import {
16
19
  parseArgs
17
20
  } from "./chunk-D424ZQGI.js";
@@ -19,9 +22,9 @@ import "./chunk-H7OZRFJB.js";
19
22
  import "./chunk-K3NQKI34.js";
20
23
 
21
24
  // src/commands/send.ts
22
- import { existsSync, readFileSync } from "fs";
25
+ import { existsSync, readFileSync, statSync } from "fs";
23
26
  import { userInfo } from "os";
24
- import { extname } from "path";
27
+ import { basename, extname } from "path";
25
28
 
26
29
  // src/lib/parse-target.ts
27
30
  function parseTarget(target) {
@@ -153,6 +156,7 @@ async function run(args) {
153
156
  const { positional, flags } = parseArgs(args, {
154
157
  mind: { type: "string" },
155
158
  image: { type: "string" },
159
+ file: { type: "string" },
156
160
  wait: { type: "boolean" },
157
161
  timeout: { type: "number" },
158
162
  sender: { type: "string" }
@@ -160,9 +164,9 @@ async function run(args) {
160
164
  const target = positional[0];
161
165
  const message = positional[1] ?? await readStdin();
162
166
  const images = flags.image ? [loadImage(flags.image)] : void 0;
163
- if (!target || !message && !images) {
167
+ if (!target || !message && !images && !flags.file) {
164
168
  console.error(
165
- 'Usage: volute chat send <target> "<message>" [--mind <name>] [--image <path>] [--wait]'
169
+ 'Usage: volute chat send <target> "<message>" [--mind <name>] [--image <path>] [--file <path>] [--wait]'
166
170
  );
167
171
  console.error(' echo "message" | volute chat send <target> [--mind <name>]');
168
172
  console.error("");
@@ -172,6 +176,7 @@ async function run(args) {
172
176
  console.error(' volute chat send discord:server/channel "hello"');
173
177
  console.error(' volute chat send @mind "check this out" --image photo.png');
174
178
  console.error(" volute chat send @mind --image photo.png");
179
+ console.error(' volute chat send @mind "check this out" --file notes.txt');
175
180
  console.error(' volute chat send @mind "hello" --wait');
176
181
  process.exit(1);
177
182
  }
@@ -182,6 +187,59 @@ To reply to a person, use their username from the message prefix (e.g. volute ch
182
187
  );
183
188
  process.exit(1);
184
189
  }
190
+ if (flags.file) {
191
+ const filePath = flags.file;
192
+ const parsed2 = parseTarget(target);
193
+ const targetName = parsed2.isDM && parsed2.platform === "volute" ? parsed2.identifier.slice(1) : parsed2.identifier;
194
+ const mindSelf = process.env.VOLUTE_MIND;
195
+ if (mindSelf) {
196
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(mindSelf)}/files/send`, {
197
+ method: "POST",
198
+ headers: { "Content-Type": "application/json" },
199
+ body: JSON.stringify({ targetMind: targetName, filePath })
200
+ });
201
+ if (!res.ok) {
202
+ const data2 = await res.json();
203
+ console.error(data2.error ?? `Failed to send file: ${res.status}`);
204
+ process.exit(1);
205
+ }
206
+ const data = await res.json();
207
+ console.log(`File staged for ${targetName} (id: ${data.id})`);
208
+ } else {
209
+ if (!existsSync(filePath)) {
210
+ console.error(`File not found: ${filePath}`);
211
+ process.exit(1);
212
+ }
213
+ const stat = statSync(filePath);
214
+ const MAX_FILE_SIZE = 50 * 1024 * 1024;
215
+ if (stat.size > MAX_FILE_SIZE) {
216
+ console.error(
217
+ `File too large (${formatFileSize(stat.size)}, max ${formatFileSize(MAX_FILE_SIZE)})`
218
+ );
219
+ process.exit(1);
220
+ }
221
+ const content = readFileSync(filePath);
222
+ const filename = basename(filePath);
223
+ const senderName = flags.sender || userInfo().username;
224
+ const res = await daemonFetch(`/api/minds/${encodeURIComponent(targetName)}/files/stage`, {
225
+ method: "POST",
226
+ headers: { "Content-Type": "application/json" },
227
+ body: JSON.stringify({
228
+ sender: senderName,
229
+ filename,
230
+ data: content.toString("base64")
231
+ })
232
+ });
233
+ if (!res.ok) {
234
+ const data2 = await res.json();
235
+ console.error(data2.error ?? `Failed to stage file: ${res.status}`);
236
+ process.exit(1);
237
+ }
238
+ const data = await res.json();
239
+ console.log(`File staged for ${targetName} (id: ${data.id})`);
240
+ }
241
+ if (!message) return;
242
+ }
185
243
  let parsed = parseTarget(target);
186
244
  if (!parsed.isDM && parsed.platform === "volute" && await isMind(parsed.identifier)) {
187
245
  parsed = {
@@ -200,8 +258,8 @@ To reply to a person, use their username from the message prefix (e.g. volute ch
200
258
  const sender = flags.sender || mindSelf || userInfo().username;
201
259
  const targetIsMind = await isMind(targetName);
202
260
  waitMindName = targetIsMind ? targetName : void 0;
203
- const contextMind = mindSelf && !targetIsMind ? mindSelf : targetName;
204
- const participants = mindSelf && !targetIsMind ? [targetName] : [sender];
261
+ const contextMind = mindSelf ?? targetName;
262
+ const participants = mindSelf ? [targetName] : [sender];
205
263
  const createRes = await daemonFetch(
206
264
  urlOf(client.api.minds[":name"].channels.create.$url({ param: { name: contextMind } })),
207
265
  {