volute 0.4.0 → 0.5.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 (75) hide show
  1. package/README.md +22 -22
  2. package/dist/agent-Z2B6EFEQ.js +75 -0
  3. package/dist/{agent-manager-AUCKMGPR.js → agent-manager-PXBKA2GK.js} +4 -4
  4. package/dist/channel-MK5OK2SI.js +113 -0
  5. package/dist/chunk-5X7HGB6L.js +107 -0
  6. package/dist/{chunk-YGFIWIOF.js → chunk-7L4AN5D4.js} +1 -1
  7. package/dist/{chunk-VRVVQIYY.js → chunk-AZEL2IEK.js} +1 -1
  8. package/dist/chunk-B3R6L2GW.js +24 -0
  9. package/dist/{chunk-DNOXHLE5.js → chunk-HE67X4T6.js} +1 -1
  10. package/dist/{chunk-I6OHXCMV.js → chunk-MW2KFO3B.js} +47 -9
  11. package/dist/{chunk-5OCWMTVS.js → chunk-SMISE4SV.js} +77 -3
  12. package/dist/{chunk-SOZA2TLP.js → chunk-UAVD2AHX.js} +1 -1
  13. package/dist/{chunk-3C2XR4IY.js → chunk-UX25Z2ND.js} +113 -107
  14. package/dist/{chunk-GSPKUPKU.js → chunk-XUA3JUFK.js} +2 -1
  15. package/dist/chunk-ZYGKG6VC.js +22 -0
  16. package/dist/cli.js +86 -74
  17. package/dist/{connector-DKDJTLYZ.js → connector-LYEMXQEV.js} +11 -6
  18. package/dist/connectors/discord.js +3 -1
  19. package/dist/connectors/slack.js +14 -5
  20. package/dist/connectors/telegram.js +21 -2
  21. package/dist/conversation-ERXEQZTY.js +163 -0
  22. package/dist/create-RVCZN6HE.js +91 -0
  23. package/dist/{daemon-client-XR24PUJF.js → daemon-client-ZY6UUN2M.js} +2 -2
  24. package/dist/daemon.js +629 -177
  25. package/dist/{delete-55MXCEY5.js → delete-3QH7VYIN.js} +7 -8
  26. package/dist/{down-3OB6UVAJ.js → down-O7IFZLVJ.js} +1 -1
  27. package/dist/{env-JB27UAC3.js → env-4D4REPJF.js} +8 -5
  28. package/dist/{history-BKG74I43.js → history-OEONB53Z.js} +3 -3
  29. package/dist/{import-4CI2ZUTJ.js → import-MXJB2EII.js} +8 -8
  30. package/dist/{logs-NXFFGUKY.js → logs-DF342W4M.js} +2 -2
  31. package/dist/message-ADHWFHSI.js +32 -0
  32. package/dist/{package-Z2SFO2SV.js → package-VQOE7JNH.js} +1 -1
  33. package/dist/{schedule-A35SH4HT.js → schedule-NAG6F463.js} +10 -5
  34. package/dist/send-66QMKRUH.js +75 -0
  35. package/dist/{setup-2FDVN7OF.js → setup-RPRRGG2F.js} +5 -5
  36. package/dist/{start-LDPMCMYT.js → start-TUOXDSFL.js} +3 -3
  37. package/dist/{status-MVSQG54T.js → status-A36EHRO4.js} +3 -3
  38. package/dist/{stop-5PZTZCLL.js → stop-AOJZLQ5X.js} +6 -7
  39. package/dist/{up-F7TMTLRE.js → up-7ILD7GU7.js} +2 -2
  40. package/dist/update-LPSIAWQ2.js +140 -0
  41. package/dist/update-check-Y33QDCFL.js +17 -0
  42. package/dist/{upgrade-6ZW2RD64.js → upgrade-FX2TKJ2S.js} +16 -15
  43. package/dist/{variant-T64BKARF.js → variant-LAB67OC2.js} +15 -10
  44. package/dist/web-assets/assets/index-BbRmoxoA.js +308 -0
  45. package/dist/web-assets/index.html +2 -2
  46. package/drizzle/0003_clean_ego.sql +12 -0
  47. package/drizzle/meta/0003_snapshot.json +417 -0
  48. package/drizzle/meta/_journal.json +7 -0
  49. package/package.json +1 -1
  50. package/templates/_base/.init/.config/hooks/startup-context.sh +19 -1
  51. package/templates/_base/_skills/volute-agent/SKILL.md +110 -14
  52. package/templates/_base/home/.config/routes.json +10 -0
  53. package/templates/_base/home/VOLUTE.md +14 -35
  54. package/templates/_base/src/lib/format-prefix.ts +1 -1
  55. package/templates/_base/src/lib/router.ts +163 -16
  56. package/templates/_base/src/lib/routing.ts +55 -18
  57. package/templates/_base/src/lib/types.ts +3 -1
  58. package/templates/agent-sdk/.init/.config/routes.json +5 -0
  59. package/templates/agent-sdk/.init/CLAUDE.md +2 -2
  60. package/templates/agent-sdk/src/agent.ts +2 -1
  61. package/templates/agent-sdk/src/server.ts +8 -2
  62. package/templates/agent-sdk/volute-template.json +1 -1
  63. package/templates/pi/.init/.config/routes.json +5 -0
  64. package/templates/pi/.init/AGENTS.md +1 -1
  65. package/templates/pi/src/agent.ts +5 -3
  66. package/templates/pi/src/server.ts +1 -1
  67. package/templates/pi/volute-template.json +1 -1
  68. package/dist/channel-DQ6UY7QB.js +0 -67
  69. package/dist/chunk-ZHCE4DPY.js +0 -110
  70. package/dist/create-ILVOG75A.js +0 -79
  71. package/dist/send-3U6OTKG7.js +0 -57
  72. package/dist/web-assets/assets/index-NS621maO.js +0 -296
  73. package/templates/agent-sdk/.init/.config/sessions.json +0 -4
  74. package/templates/pi/.init/.config/sessions.json +0 -1
  75. package/dist/{service-SA4TTMDU.js → service-HZNIDNJF.js} +3 -3
@@ -1,16 +1,19 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ resolveAgentName
4
+ } from "./chunk-AZEL2IEK.js";
2
5
  import {
3
6
  parseArgs
4
7
  } from "./chunk-D424ZQGI.js";
5
8
  import {
6
9
  deleteAgentUser
7
- } from "./chunk-SOZA2TLP.js";
10
+ } from "./chunk-UAVD2AHX.js";
8
11
  import {
9
12
  agentDir,
10
13
  findAgent,
11
14
  removeAgent,
12
15
  removeAllVariants
13
- } from "./chunk-3C2XR4IY.js";
16
+ } from "./chunk-UX25Z2ND.js";
14
17
  import "./chunk-K3NQKI34.js";
15
18
 
16
19
  // src/commands/delete.ts
@@ -19,18 +22,14 @@ async function run(args) {
19
22
  const { positional, flags } = parseArgs(args, {
20
23
  force: { type: "boolean" }
21
24
  });
22
- const name = positional[0];
23
- if (!name) {
24
- console.error("Usage: volute delete <name> [--force]");
25
- process.exit(1);
26
- }
25
+ const name = resolveAgentName({ agent: positional[0] });
27
26
  const entry = findAgent(name);
28
27
  if (!entry) {
29
28
  console.error(`Unknown agent: ${name}`);
30
29
  process.exit(1);
31
30
  }
32
31
  try {
33
- const { daemonFetch } = await import("./daemon-client-XR24PUJF.js");
32
+ const { daemonFetch } = await import("./daemon-client-ZY6UUN2M.js");
34
33
  const res = await daemonFetch(`/api/agents/${encodeURIComponent(name)}/stop`, {
35
34
  method: "POST"
36
35
  });
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteHome
4
- } from "./chunk-3C2XR4IY.js";
4
+ } from "./chunk-UX25Z2ND.js";
5
5
  import "./chunk-K3NQKI34.js";
6
6
 
7
7
  // src/commands/down.ts
@@ -5,13 +5,13 @@ import {
5
5
  readEnv,
6
6
  sharedEnvPath,
7
7
  writeEnv
8
- } from "./chunk-DNOXHLE5.js";
8
+ } from "./chunk-HE67X4T6.js";
9
9
  import {
10
10
  parseArgs
11
11
  } from "./chunk-D424ZQGI.js";
12
12
  import {
13
13
  resolveAgent
14
- } from "./chunk-3C2XR4IY.js";
14
+ } from "./chunk-UX25Z2ND.js";
15
15
  import "./chunk-K3NQKI34.js";
16
16
 
17
17
  // src/commands/env.ts
@@ -153,12 +153,15 @@ async function run(args) {
153
153
  console.log(`Removed ${key} [${scope}]`);
154
154
  break;
155
155
  }
156
+ case "--help":
157
+ case "-h":
158
+ case void 0:
159
+ console.log(`Usage: volute env <set|get|list|remove> [--agent <name>]`);
160
+ break;
156
161
  default:
157
162
  console.error(`Usage: volute env <set|get|list|remove> [--agent <name>]`);
158
- if (subcommand) {
159
- console.error(`
163
+ console.error(`
160
164
  Unknown subcommand: ${subcommand}`);
161
- }
162
165
  process.exit(1);
163
166
  }
164
167
  }
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolveAgentName
4
- } from "./chunk-VRVVQIYY.js";
4
+ } from "./chunk-AZEL2IEK.js";
5
5
  import {
6
6
  parseArgs
7
7
  } from "./chunk-D424ZQGI.js";
8
8
  import {
9
9
  daemonFetch
10
- } from "./chunk-YGFIWIOF.js";
11
- import "./chunk-3C2XR4IY.js";
10
+ } from "./chunk-7L4AN5D4.js";
11
+ import "./chunk-UX25Z2ND.js";
12
12
  import "./chunk-K3NQKI34.js";
13
13
 
14
14
  // src/commands/history.ts
@@ -7,25 +7,25 @@ import {
7
7
  agentEnvPath,
8
8
  readEnv,
9
9
  writeEnv
10
- } from "./chunk-DNOXHLE5.js";
10
+ } from "./chunk-HE67X4T6.js";
11
11
  import {
12
12
  composeTemplate,
13
13
  copyTemplateToDir,
14
14
  findTemplatesRoot
15
- } from "./chunk-GSPKUPKU.js";
15
+ } from "./chunk-XUA3JUFK.js";
16
+ import {
17
+ parseArgs
18
+ } from "./chunk-D424ZQGI.js";
16
19
  import {
17
20
  exec,
18
21
  execInherit
19
22
  } from "./chunk-5SKQ6J7T.js";
20
- import {
21
- parseArgs
22
- } from "./chunk-D424ZQGI.js";
23
23
  import {
24
24
  addAgent,
25
25
  agentDir,
26
26
  ensureVoluteHome,
27
27
  nextPort
28
- } from "./chunk-3C2XR4IY.js";
28
+ } from "./chunk-UX25Z2ND.js";
29
29
  import "./chunk-K3NQKI34.js";
30
30
 
31
31
  // src/commands/import.ts
@@ -394,7 +394,7 @@ ${user.trimEnd()}
394
394
  console.log(`
395
395
  Imported agent: ${name} (port ${port})`);
396
396
  console.log(`
397
- volute start ${name}`);
397
+ volute agent start ${name}`);
398
398
  }
399
399
  function resolveWorkspace(explicitPath) {
400
400
  if (explicitPath) {
@@ -416,7 +416,7 @@ function resolveWorkspace(explicitPath) {
416
416
  return openclawWs;
417
417
  }
418
418
  console.error(
419
- "Usage: volute 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."
419
+ "Usage: volute agent 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."
420
420
  );
421
421
  process.exit(1);
422
422
  }
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolveAgentName
4
- } from "./chunk-VRVVQIYY.js";
4
+ } from "./chunk-AZEL2IEK.js";
5
5
  import {
6
6
  parseArgs
7
7
  } from "./chunk-D424ZQGI.js";
8
8
  import {
9
9
  resolveAgent
10
- } from "./chunk-3C2XR4IY.js";
10
+ } from "./chunk-UX25Z2ND.js";
11
11
  import "./chunk-K3NQKI34.js";
12
12
 
13
13
  // src/commands/logs.ts
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ import "./chunk-K3NQKI34.js";
3
+
4
+ // src/commands/message.ts
5
+ async function run(args) {
6
+ const subcommand = args[0];
7
+ switch (subcommand) {
8
+ case "send":
9
+ await import("./send-66QMKRUH.js").then((m) => m.run(args.slice(1)));
10
+ break;
11
+ case "history":
12
+ await import("./history-OEONB53Z.js").then((m) => m.run(args.slice(1)));
13
+ break;
14
+ case "--help":
15
+ case "-h":
16
+ case void 0:
17
+ printUsage();
18
+ break;
19
+ default:
20
+ printUsage();
21
+ process.exit(1);
22
+ }
23
+ }
24
+ function printUsage() {
25
+ console.log(`Usage:
26
+ volute message send <name> "<msg>"
27
+ echo "msg" | volute message send <name>
28
+ volute message history [--agent <name>] [--channel <ch>] [--limit N]`);
29
+ }
30
+ export {
31
+ run
32
+ };
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "volute",
7
- version: "0.4.0",
7
+ version: "0.5.0",
8
8
  description: "CLI for creating and managing self-modifying AI agents powered by the Claude Agent SDK",
9
9
  type: "module",
10
10
  license: "MIT",
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolveAgentName
4
- } from "./chunk-VRVVQIYY.js";
4
+ } from "./chunk-AZEL2IEK.js";
5
5
  import {
6
6
  parseArgs
7
7
  } from "./chunk-D424ZQGI.js";
8
8
  import {
9
9
  daemonFetch
10
- } from "./chunk-YGFIWIOF.js";
11
- import "./chunk-3C2XR4IY.js";
10
+ } from "./chunk-7L4AN5D4.js";
11
+ import "./chunk-UX25Z2ND.js";
12
12
  import "./chunk-K3NQKI34.js";
13
13
 
14
14
  // src/commands/schedule.ts
@@ -24,13 +24,18 @@ async function run(args) {
24
24
  case "remove":
25
25
  await removeSchedule(args.slice(1));
26
26
  break;
27
+ case "--help":
28
+ case "-h":
29
+ case void 0:
30
+ printUsage();
31
+ break;
27
32
  default:
28
33
  printUsage();
29
- process.exit(subcommand ? 1 : 0);
34
+ process.exit(1);
30
35
  }
31
36
  }
32
37
  function printUsage() {
33
- console.error(`Usage:
38
+ console.log(`Usage:
34
39
  volute schedule list [--agent <name>]
35
40
  volute schedule add [--agent <name>] --cron "..." --message "..." [--id name]
36
41
  volute schedule remove [--agent <name>] --id <id>`);
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ readStdin
4
+ } from "./chunk-ZYGKG6VC.js";
5
+ import {
6
+ summarizeTool
7
+ } from "./chunk-B3R6L2GW.js";
8
+ import {
9
+ daemonFetch
10
+ } from "./chunk-7L4AN5D4.js";
11
+ import "./chunk-UX25Z2ND.js";
12
+ import "./chunk-K3NQKI34.js";
13
+
14
+ // src/commands/send.ts
15
+ import { userInfo } from "os";
16
+ async function run(args) {
17
+ const name = args[0];
18
+ const message = args[1] ?? await readStdin();
19
+ if (!name || !message) {
20
+ console.error('Usage: volute message send <name> "<message>"');
21
+ console.error(' echo "message" | volute message send <name>');
22
+ process.exit(1);
23
+ }
24
+ const agentSelf = process.env.VOLUTE_AGENT;
25
+ const sender = agentSelf || userInfo().username;
26
+ const res = await daemonFetch(`/api/agents/${encodeURIComponent(name)}/chat`, {
27
+ method: "POST",
28
+ headers: { "Content-Type": "application/json" },
29
+ body: JSON.stringify({ message, sender })
30
+ });
31
+ if (!res.ok) {
32
+ const data = await res.json();
33
+ console.error(data.error ?? `Failed to send message: ${res.status}`);
34
+ process.exit(1);
35
+ }
36
+ if (!res.body) {
37
+ console.error("No response body");
38
+ process.exit(1);
39
+ }
40
+ const reader = res.body.getReader();
41
+ const decoder = new TextDecoder();
42
+ let buffer = "";
43
+ while (true) {
44
+ const { done, value } = await reader.read();
45
+ if (done) break;
46
+ buffer += decoder.decode(value, { stream: true });
47
+ const lines = buffer.split("\n");
48
+ buffer = lines.pop() ?? "";
49
+ for (const line of lines) {
50
+ if (!line.startsWith("data:")) continue;
51
+ const data = line.slice(5).trim();
52
+ if (!data) continue;
53
+ let event;
54
+ try {
55
+ event = JSON.parse(data);
56
+ } catch {
57
+ continue;
58
+ }
59
+ if (event.type === "text") {
60
+ process.stdout.write(event.content);
61
+ } else if (event.type === "tool_use") {
62
+ process.stderr.write(`${summarizeTool(event.name, event.input)}
63
+ `);
64
+ }
65
+ if (event.type === "done") {
66
+ process.stdout.write("\n");
67
+ return;
68
+ }
69
+ }
70
+ }
71
+ process.stdout.write("\n");
72
+ }
73
+ export {
74
+ run
75
+ };
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- resolveVoluteBin
4
- } from "./chunk-5SKQ6J7T.js";
5
2
  import {
6
3
  parseArgs
7
4
  } from "./chunk-D424ZQGI.js";
8
5
  import {
9
6
  ensureVoluteGroup
10
- } from "./chunk-SOZA2TLP.js";
11
- import "./chunk-3C2XR4IY.js";
7
+ } from "./chunk-UAVD2AHX.js";
8
+ import {
9
+ resolveVoluteBin
10
+ } from "./chunk-5SKQ6J7T.js";
11
+ import "./chunk-UX25Z2ND.js";
12
12
  import "./chunk-K3NQKI34.js";
13
13
 
14
14
  // src/commands/setup.ts
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  daemonFetch
4
- } from "./chunk-YGFIWIOF.js";
4
+ } from "./chunk-7L4AN5D4.js";
5
5
  import {
6
6
  resolveAgent
7
- } from "./chunk-3C2XR4IY.js";
7
+ } from "./chunk-UX25Z2ND.js";
8
8
  import "./chunk-K3NQKI34.js";
9
9
 
10
10
  // src/commands/start.ts
11
11
  async function run(args) {
12
12
  const name = args[0];
13
13
  if (!name) {
14
- console.error("Usage: volute start <name>");
14
+ console.error("Usage: volute agent start <name>");
15
15
  process.exit(1);
16
16
  }
17
17
  const { entry } = resolveAgent(name);
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  daemonFetch
4
- } from "./chunk-YGFIWIOF.js";
5
- import "./chunk-3C2XR4IY.js";
4
+ } from "./chunk-7L4AN5D4.js";
5
+ import "./chunk-UX25Z2ND.js";
6
6
  import "./chunk-K3NQKI34.js";
7
7
 
8
8
  // src/commands/status.ts
@@ -17,7 +17,7 @@ async function run(args) {
17
17
  }
18
18
  const agents = await res2.json();
19
19
  if (agents.length === 0) {
20
- console.log("No agents registered. Create one with: volute create <name>");
20
+ console.log("No agents registered. Create one with: volute agent create <name>");
21
21
  return;
22
22
  }
23
23
  const nameW = Math.max(4, ...agents.map((a) => a.name.length));
@@ -1,19 +1,18 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ resolveAgentName
4
+ } from "./chunk-AZEL2IEK.js";
2
5
  import {
3
6
  daemonFetch
4
- } from "./chunk-YGFIWIOF.js";
7
+ } from "./chunk-7L4AN5D4.js";
5
8
  import {
6
9
  resolveAgent
7
- } from "./chunk-3C2XR4IY.js";
10
+ } from "./chunk-UX25Z2ND.js";
8
11
  import "./chunk-K3NQKI34.js";
9
12
 
10
13
  // src/commands/stop.ts
11
14
  async function run(args) {
12
- const name = args[0];
13
- if (!name) {
14
- console.error("Usage: volute stop <name>");
15
- process.exit(1);
16
- }
15
+ const name = resolveAgentName({ agent: args[0] });
17
16
  resolveAgent(name);
18
17
  const res = await daemonFetch(`/api/agents/${encodeURIComponent(name)}/stop`, {
19
18
  method: "POST"
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-D424ZQGI.js";
5
5
  import {
6
6
  voluteHome
7
- } from "./chunk-3C2XR4IY.js";
7
+ } from "./chunk-UX25Z2ND.js";
8
8
  import "./chunk-K3NQKI34.js";
9
9
 
10
10
  // src/commands/up.ts
@@ -58,7 +58,7 @@ async function run(args) {
58
58
  process.execPath,
59
59
  [daemonModule, "--port", String(port), "--host", hostname],
60
60
  {
61
- stdio: ["ignore", logFd, logFd],
61
+ stdio: ["ignore", "ignore", logFd],
62
62
  detached: true
63
63
  }
64
64
  );
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ checkForUpdate
4
+ } from "./chunk-5X7HGB6L.js";
5
+ import {
6
+ execInherit,
7
+ resolveVoluteBin
8
+ } from "./chunk-5SKQ6J7T.js";
9
+ import {
10
+ voluteHome
11
+ } from "./chunk-UX25Z2ND.js";
12
+ import "./chunk-K3NQKI34.js";
13
+
14
+ // src/commands/update.ts
15
+ import { existsSync, readFileSync, unlinkSync } from "fs";
16
+ import { resolve } from "path";
17
+ async function run(_args) {
18
+ const result = await checkForUpdate();
19
+ if (result.checkFailed) {
20
+ console.error("Could not reach npm registry. Check your network connection and try again.");
21
+ process.exit(1);
22
+ }
23
+ console.log(`Current version: ${result.current}`);
24
+ console.log(`Latest version: ${result.latest}`);
25
+ if (!result.updateAvailable) {
26
+ console.log("\nAlready up to date.");
27
+ return;
28
+ }
29
+ console.log(`
30
+ Updating volute ${result.current} \u2192 ${result.latest}...`);
31
+ const home = voluteHome();
32
+ const pidPath = resolve(home, "daemon.pid");
33
+ const configPath = resolve(home, "daemon.json");
34
+ let daemonWasRunning = false;
35
+ let daemonPort = 4200;
36
+ let daemonHost = "127.0.0.1";
37
+ if (existsSync(pidPath)) {
38
+ const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
39
+ try {
40
+ process.kill(pid, 0);
41
+ daemonWasRunning = true;
42
+ } catch {
43
+ try {
44
+ unlinkSync(pidPath);
45
+ } catch {
46
+ }
47
+ }
48
+ }
49
+ if (daemonWasRunning && existsSync(configPath)) {
50
+ try {
51
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
52
+ daemonPort = config.port ?? 4200;
53
+ daemonHost = config.hostname || "127.0.0.1";
54
+ } catch {
55
+ console.error("Warning: could not read daemon config, using default port/host");
56
+ }
57
+ }
58
+ if (daemonWasRunning) {
59
+ console.log("Stopping daemon...");
60
+ const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
61
+ try {
62
+ process.kill(-pid, "SIGTERM");
63
+ } catch {
64
+ try {
65
+ process.kill(pid, "SIGTERM");
66
+ } catch {
67
+ }
68
+ }
69
+ const maxWait = 1e4;
70
+ const start = Date.now();
71
+ while (Date.now() - start < maxWait) {
72
+ if (!existsSync(pidPath)) break;
73
+ await new Promise((r) => setTimeout(r, 200));
74
+ }
75
+ if (existsSync(pidPath)) {
76
+ try {
77
+ process.kill(-pid, "SIGKILL");
78
+ } catch {
79
+ try {
80
+ process.kill(pid, "SIGKILL");
81
+ } catch {
82
+ }
83
+ }
84
+ }
85
+ if (existsSync(pidPath)) {
86
+ try {
87
+ const stalePid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
88
+ process.kill(stalePid, 0);
89
+ console.error("Warning: daemon process may still be running. Aborting update.");
90
+ process.exit(1);
91
+ } catch {
92
+ try {
93
+ unlinkSync(pidPath);
94
+ } catch {
95
+ }
96
+ }
97
+ }
98
+ console.log("Daemon stopped.");
99
+ }
100
+ try {
101
+ await execInherit("npm", ["install", "-g", "volute@latest"]);
102
+ } catch (err) {
103
+ console.error(`
104
+ Update failed: ${err.message}`);
105
+ if (daemonWasRunning) {
106
+ console.log("Restarting daemon with current version...");
107
+ try {
108
+ await execInherit(resolveVoluteBin(), [
109
+ "up",
110
+ "--port",
111
+ String(daemonPort),
112
+ "--host",
113
+ daemonHost
114
+ ]);
115
+ } catch {
116
+ console.error("Failed to restart daemon. Run `volute up` manually.");
117
+ }
118
+ }
119
+ process.exit(1);
120
+ }
121
+ if (daemonWasRunning) {
122
+ console.log("Restarting daemon...");
123
+ try {
124
+ await execInherit(resolveVoluteBin(), [
125
+ "up",
126
+ "--port",
127
+ String(daemonPort),
128
+ "--host",
129
+ daemonHost
130
+ ]);
131
+ } catch {
132
+ console.error("Failed to restart daemon. Run `volute up` manually.");
133
+ }
134
+ }
135
+ console.log(`
136
+ Updated to volute v${result.latest}`);
137
+ }
138
+ export {
139
+ run
140
+ };
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ checkForUpdate,
4
+ checkForUpdateCached,
5
+ fetchLatestVersion,
6
+ getCurrentVersion,
7
+ isNewer
8
+ } from "./chunk-5X7HGB6L.js";
9
+ import "./chunk-UX25Z2ND.js";
10
+ import "./chunk-K3NQKI34.js";
11
+ export {
12
+ checkForUpdate,
13
+ checkForUpdateCached,
14
+ fetchLatestVersion,
15
+ getCurrentVersion,
16
+ isNewer
17
+ };
@@ -1,24 +1,27 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ resolveAgentName
4
+ } from "./chunk-AZEL2IEK.js";
2
5
  import {
3
6
  composeTemplate,
4
7
  copyTemplateToDir,
5
8
  findTemplatesRoot
6
- } from "./chunk-GSPKUPKU.js";
9
+ } from "./chunk-XUA3JUFK.js";
10
+ import {
11
+ parseArgs
12
+ } from "./chunk-D424ZQGI.js";
7
13
  import {
8
14
  exec,
9
15
  execInherit
10
16
  } from "./chunk-5SKQ6J7T.js";
11
- import {
12
- parseArgs
13
- } from "./chunk-D424ZQGI.js";
14
17
  import {
15
18
  daemonFetch
16
- } from "./chunk-YGFIWIOF.js";
19
+ } from "./chunk-7L4AN5D4.js";
17
20
  import {
18
21
  addVariant,
19
22
  nextPort,
20
23
  resolveAgent
21
- } from "./chunk-3C2XR4IY.js";
24
+ } from "./chunk-UX25Z2ND.js";
22
25
  import "./chunk-K3NQKI34.js";
23
26
 
24
27
  // src/commands/upgrade.ts
@@ -31,11 +34,7 @@ async function run(args) {
31
34
  template: { type: "string" },
32
35
  continue: { type: "boolean" }
33
36
  });
34
- const agentName = positional[0];
35
- if (!agentName) {
36
- console.error("Usage: volute upgrade <name> [--template <name>] [--continue]");
37
- process.exit(1);
38
- }
37
+ const agentName = resolveAgentName({ agent: positional[0] });
39
38
  const { dir: projectRoot } = resolveAgent(agentName);
40
39
  const template = flags.template ?? "agent-sdk";
41
40
  if (flags.continue) {
@@ -73,7 +72,7 @@ Otherwise, remove it with: volute variant delete ${VARIANT_NAME} --agent ${agent
73
72
  console.log(` ${worktreeDir}`);
74
73
  console.log(`
75
74
  Then run:`);
76
- console.log(` volute upgrade ${agentName} --continue`);
75
+ console.log(` volute agent upgrade ${agentName} --continue`);
77
76
  return;
78
77
  }
79
78
  await installAndVerify(agentName, worktreeDir);
@@ -164,7 +163,7 @@ async function mergeTemplateBranch(worktreeDir) {
164
163
  async function continueUpgrade(agentName, projectRoot) {
165
164
  const worktreeDir = resolve(projectRoot, ".variants", VARIANT_NAME);
166
165
  if (!existsSync(worktreeDir)) {
167
- console.error("No upgrade in progress. Run `volute upgrade` first.");
166
+ console.error("No upgrade in progress. Run `volute agent upgrade` first.");
168
167
  process.exit(1);
169
168
  }
170
169
  const status = await exec("git", ["status", "--porcelain"], {
@@ -207,7 +206,7 @@ async function installAndVerify(agentName, worktreeDir) {
207
206
  } catch {
208
207
  console.error("Failed to start variant. Is the daemon running? (volute up)");
209
208
  console.error(
210
- `The variant was created but not started. Use: volute start ${agentName}@${VARIANT_NAME}`
209
+ `The variant was created but not started. Use: volute agent start ${agentName}@${VARIANT_NAME}`
211
210
  );
212
211
  process.exit(1);
213
212
  }
@@ -215,7 +214,9 @@ async function installAndVerify(agentName, worktreeDir) {
215
214
  Upgrade variant running on port ${variantPort}`);
216
215
  console.log(`
217
216
  Next steps:`);
218
- console.log(` volute send ${agentName}@${VARIANT_NAME} "hello" # chat with upgraded variant`);
217
+ console.log(
218
+ ` volute message send ${agentName}@${VARIANT_NAME} "hello" # chat with upgraded variant`
219
+ );
219
220
  console.log(` volute variant merge ${VARIANT_NAME} # merge back when satisfied`);
220
221
  }
221
222
  export {