volute 0.6.0 → 0.8.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 (77) hide show
  1. package/README.md +13 -13
  2. package/dist/{agent-X7GJLBLW.js → agent-YORVRB6I.js} +10 -10
  3. package/dist/{agent-manager-JDVXU3ON.js → agent-manager-CMMH5KQQ.js} +4 -4
  4. package/dist/{channel-SMCNOIVQ.js → channel-RDGHBFSI.js} +16 -56
  5. package/dist/{chunk-JR4UXCTO.js → chunk-23L3MKEV.js} +1 -1
  6. package/dist/{chunk-5SKQ6J7T.js → chunk-5C5JWR2L.js} +15 -7
  7. package/dist/{chunk-UWHWAPGO.js → chunk-DP2DX4WV.js} +9 -1
  8. package/dist/chunk-ECPQXRLB.js +264 -0
  9. package/dist/{down-FXWAN66A.js → chunk-HZ5LTOEJ.js} +48 -13
  10. package/dist/{chunk-W76KWE23.js → chunk-IQXBMFZG.js} +6 -4
  11. package/dist/{chunk-ZZOOTYXK.js → chunk-LIPPXNIE.js} +60 -74
  12. package/dist/{chunk-BX7KI4S3.js → chunk-N6MLQ26B.js} +23 -96
  13. package/dist/{chunk-H7AMDUIA.js → chunk-QF22MYDJ.js} +6 -5
  14. package/dist/{chunk-AOKAQGO4.js → chunk-RT6Y7AR3.js} +2 -1
  15. package/dist/{chunk-G6ZNGLUX.js → chunk-W6TMWYU3.js} +133 -78
  16. package/dist/{up-CSX3ZUIU.js → chunk-XSJ27WEM.js} +2 -2
  17. package/dist/cli.js +25 -19
  18. package/dist/{connector-Y7JPNROO.js → connector-ZP6MEFF4.js} +3 -3
  19. package/dist/connectors/discord.js +24 -61
  20. package/dist/connectors/slack.js +21 -38
  21. package/dist/connectors/telegram.js +31 -49
  22. package/dist/{create-G525LWEA.js → create-HGJHLABX.js} +22 -17
  23. package/dist/{daemon-client-442IV43D.js → daemon-client-54J3EIZD.js} +2 -2
  24. package/dist/daemon-restart-CPBLMMRI.js +23 -0
  25. package/dist/daemon.js +397 -661
  26. package/dist/{delete-2PH2CGDY.js → delete-45TGQC4N.js} +13 -4
  27. package/dist/down-O4EWZTVA.js +11 -0
  28. package/dist/{env-7GLUJCWS.js → env-KMNYGVZ2.js} +7 -9
  29. package/dist/{history-H72ZUIBN.js → history-PXJVYLVY.js} +2 -2
  30. package/dist/{import-AVKQJDYC.js → import-CNEDF3TD.js} +6 -6
  31. package/dist/{logs-EDGK26AK.js → logs-TZB3MTLZ.js} +5 -4
  32. package/dist/{package-4DP4Y4UO.js → package-5UCKNK6J.js} +1 -1
  33. package/dist/{restart-O4ETYLJF.js → restart-KVH3TK5N.js} +2 -2
  34. package/dist/{schedule-S6QVC5ON.js → schedule-HCUCBNQI.js} +2 -2
  35. package/dist/send-BNC2S5BY.js +162 -0
  36. package/dist/{service-HZNIDNJF.js → service-R4MCNBOA.js} +1 -1
  37. package/dist/{setup-F4TCWVSP.js → setup-JXDCJX7W.js} +25 -6
  38. package/dist/{start-VHQ7LNWM.js → start-QU73YTJW.js} +2 -2
  39. package/dist/{status-QAJWXKMZ.js → status-Q6ZQJXNI.js} +2 -2
  40. package/dist/{stop-CAGCT5NI.js → stop-N7U5N6A7.js} +2 -2
  41. package/dist/up-V6EAA7OZ.js +12 -0
  42. package/dist/{update-XSIX3GGP.js → update-EUCZ7XGG.js} +3 -3
  43. package/dist/{update-check-5ZADDHCK.js → update-check-SM4244SU.js} +2 -2
  44. package/dist/{upgrade-YXKPWDRU.js → upgrade-CZF6PN7Y.js} +4 -4
  45. package/dist/{variant-4Z6W3PP6.js → variant-RKXPN5DH.js} +20 -46
  46. package/dist/web-assets/assets/index-D-3zx6vs.js +307 -0
  47. package/dist/web-assets/index.html +1 -1
  48. package/drizzle/0004_magical_silverclaw.sql +1 -0
  49. package/drizzle/meta/0004_snapshot.json +410 -0
  50. package/drizzle/meta/_journal.json +7 -0
  51. package/package.json +1 -1
  52. package/templates/_base/_skills/volute-agent/SKILL.md +32 -16
  53. package/templates/_base/home/.config/routes.json +4 -8
  54. package/templates/_base/home/VOLUTE.md +16 -14
  55. package/templates/_base/src/lib/auto-reply.ts +38 -0
  56. package/templates/_base/src/lib/daemon-client.ts +53 -0
  57. package/templates/_base/src/lib/router.ts +66 -14
  58. package/templates/_base/src/lib/routing.ts +48 -9
  59. package/templates/_base/src/lib/startup.ts +1 -25
  60. package/templates/_base/src/lib/types.ts +2 -1
  61. package/templates/_base/src/lib/volute-server.ts +29 -14
  62. package/templates/agent-sdk/src/agent.ts +53 -111
  63. package/templates/agent-sdk/src/lib/content.ts +41 -0
  64. package/templates/agent-sdk/src/lib/session-store.ts +43 -0
  65. package/templates/agent-sdk/src/lib/stream-consumer.ts +66 -0
  66. package/templates/agent-sdk/src/server.ts +5 -13
  67. package/templates/pi/.init/AGENTS.md +5 -5
  68. package/templates/pi/src/agent.ts +32 -84
  69. package/templates/pi/src/lib/content.ts +15 -0
  70. package/templates/pi/src/lib/event-handler.ts +74 -0
  71. package/templates/pi/src/lib/resolve-model.ts +21 -0
  72. package/templates/pi/src/server.ts +3 -7
  73. package/dist/chunk-B3R6L2GW.js +0 -24
  74. package/dist/chunk-ZYGKG6VC.js +0 -22
  75. package/dist/message-SCOQDR3P.js +0 -32
  76. package/dist/send-G7PE4DOJ.js +0 -72
  77. package/dist/web-assets/assets/index-D5PzIndO.js +0 -308
@@ -2,18 +2,22 @@
2
2
  import {
3
3
  resolveAgentName
4
4
  } from "./chunk-AZEL2IEK.js";
5
+ import {
6
+ deleteAgentUser as deleteAgentUser2
7
+ } from "./chunk-ECPQXRLB.js";
5
8
  import {
6
9
  parseArgs
7
10
  } from "./chunk-D424ZQGI.js";
8
11
  import {
9
12
  deleteAgentUser
10
- } from "./chunk-W76KWE23.js";
13
+ } from "./chunk-IQXBMFZG.js";
11
14
  import {
12
15
  agentDir,
13
16
  findAgent,
14
17
  removeAgent,
15
- removeAllVariants
16
- } from "./chunk-UWHWAPGO.js";
18
+ removeAllVariants,
19
+ stateDir
20
+ } from "./chunk-DP2DX4WV.js";
17
21
  import "./chunk-K3NQKI34.js";
18
22
 
19
23
  // src/commands/delete.ts
@@ -29,7 +33,7 @@ async function run(args) {
29
33
  process.exit(1);
30
34
  }
31
35
  try {
32
- const { daemonFetch } = await import("./daemon-client-442IV43D.js");
36
+ const { daemonFetch } = await import("./daemon-client-54J3EIZD.js");
33
37
  const res = await daemonFetch(`/api/agents/${encodeURIComponent(name)}/stop`, {
34
38
  method: "POST"
35
39
  });
@@ -41,7 +45,12 @@ async function run(args) {
41
45
  const dir = agentDir(name);
42
46
  removeAllVariants(name);
43
47
  removeAgent(name);
48
+ await deleteAgentUser2(name);
44
49
  console.log(`Removed ${name} from registry.`);
50
+ const state = stateDir(name);
51
+ if (existsSync(state)) {
52
+ rmSync(state, { recursive: true, force: true });
53
+ }
45
54
  if (existsSync(dir)) {
46
55
  if (!flags.force) {
47
56
  console.log(`Directory: ${dir}`);
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ run,
4
+ stopDaemon
5
+ } from "./chunk-HZ5LTOEJ.js";
6
+ import "./chunk-DP2DX4WV.js";
7
+ import "./chunk-K3NQKI34.js";
8
+ export {
9
+ run,
10
+ stopDaemon
11
+ };
@@ -5,20 +5,20 @@ import {
5
5
  readEnv,
6
6
  sharedEnvPath,
7
7
  writeEnv
8
- } from "./chunk-H7AMDUIA.js";
8
+ } from "./chunk-QF22MYDJ.js";
9
9
  import {
10
10
  parseArgs
11
11
  } from "./chunk-D424ZQGI.js";
12
12
  import {
13
- resolveAgent
14
- } from "./chunk-UWHWAPGO.js";
13
+ findAgent
14
+ } from "./chunk-DP2DX4WV.js";
15
15
  import "./chunk-K3NQKI34.js";
16
16
 
17
17
  // src/commands/env.ts
18
18
  function getEnvPath(agentName) {
19
19
  if (agentName) {
20
- const { dir } = resolveAgent(agentName);
21
- return agentEnvPath(dir);
20
+ if (!findAgent(agentName)) throw new Error(`Unknown agent: ${agentName}`);
21
+ return agentEnvPath(agentName);
22
22
  }
23
23
  return sharedEnvPath();
24
24
  }
@@ -85,8 +85,7 @@ async function run(args) {
85
85
  process.exit(1);
86
86
  }
87
87
  if (flags.agent) {
88
- const { dir } = resolveAgent(flags.agent);
89
- const merged = loadMergedEnv(dir);
88
+ const merged = loadMergedEnv(flags.agent);
90
89
  if (key in merged) {
91
90
  console.log(merged[key]);
92
91
  } else {
@@ -106,9 +105,8 @@ async function run(args) {
106
105
  }
107
106
  case "list": {
108
107
  if (flags.agent) {
109
- const { dir } = resolveAgent(flags.agent);
110
108
  const shared = readEnv(sharedEnvPath());
111
- const agent = readEnv(agentEnvPath(dir));
109
+ const agent = readEnv(agentEnvPath(flags.agent));
112
110
  const allKeys = /* @__PURE__ */ new Set([...Object.keys(shared), ...Object.keys(agent)]);
113
111
  if (allKeys.size === 0) {
114
112
  console.log("No environment variables set.");
@@ -7,8 +7,8 @@ import {
7
7
  } from "./chunk-D424ZQGI.js";
8
8
  import {
9
9
  daemonFetch
10
- } from "./chunk-JR4UXCTO.js";
11
- import "./chunk-UWHWAPGO.js";
10
+ } from "./chunk-23L3MKEV.js";
11
+ import "./chunk-DP2DX4WV.js";
12
12
  import "./chunk-K3NQKI34.js";
13
13
 
14
14
  // src/commands/history.ts
@@ -7,7 +7,7 @@ import {
7
7
  agentEnvPath,
8
8
  readEnv,
9
9
  writeEnv
10
- } from "./chunk-H7AMDUIA.js";
10
+ } from "./chunk-QF22MYDJ.js";
11
11
  import {
12
12
  composeTemplate,
13
13
  copyTemplateToDir,
@@ -19,13 +19,13 @@ import {
19
19
  import {
20
20
  exec,
21
21
  execInherit
22
- } from "./chunk-5SKQ6J7T.js";
22
+ } from "./chunk-5C5JWR2L.js";
23
23
  import {
24
24
  addAgent,
25
25
  agentDir,
26
26
  ensureVoluteHome,
27
27
  nextPort
28
- } from "./chunk-UWHWAPGO.js";
28
+ } from "./chunk-DP2DX4WV.js";
29
29
  import "./chunk-K3NQKI34.js";
30
30
 
31
31
  // src/commands/import.ts
@@ -390,7 +390,7 @@ ${user.trimEnd()}
390
390
  console.warn(`Session import not supported for template: ${template}`);
391
391
  }
392
392
  }
393
- importOpenClawConnectors(dest);
393
+ importOpenClawConnectors(name, dest);
394
394
  console.log(`
395
395
  Imported agent: ${name} (port ${port})`);
396
396
  console.log(`
@@ -475,7 +475,7 @@ function importPiSession(sessionFile, agentDirPath) {
475
475
  `);
476
476
  console.log(`Imported session (${lines.length} entries)`);
477
477
  }
478
- function importOpenClawConnectors(agentDirPath) {
478
+ function importOpenClawConnectors(agentName, agentDirPath) {
479
479
  const configPath = resolve3(homedir2(), ".openclaw/openclaw.json");
480
480
  if (!existsSync(configPath)) return;
481
481
  let config;
@@ -487,7 +487,7 @@ function importOpenClawConnectors(agentDirPath) {
487
487
  }
488
488
  const discord = config.channels?.discord;
489
489
  if (!discord?.enabled || !discord.token) return;
490
- const envPath = agentEnvPath(agentDirPath);
490
+ const envPath = agentEnvPath(agentName);
491
491
  const env = readEnv(envPath);
492
492
  env.DISCORD_TOKEN = discord.token;
493
493
  writeEnv(envPath, env);
@@ -6,8 +6,9 @@ import {
6
6
  parseArgs
7
7
  } from "./chunk-D424ZQGI.js";
8
8
  import {
9
- resolveAgent
10
- } from "./chunk-UWHWAPGO.js";
9
+ resolveAgent,
10
+ stateDir
11
+ } from "./chunk-DP2DX4WV.js";
11
12
  import "./chunk-K3NQKI34.js";
12
13
 
13
14
  // src/commands/logs.ts
@@ -21,8 +22,8 @@ async function run(args) {
21
22
  n: { type: "number" }
22
23
  });
23
24
  const name = resolveAgentName(flags);
24
- const { dir } = resolveAgent(name);
25
- const logFile = resolve(dir, ".volute", "logs", "agent.log");
25
+ resolveAgent(name);
26
+ const logFile = resolve(stateDir(name), "logs", "agent.log");
26
27
  if (!existsSync(logFile)) {
27
28
  console.error(`No log file found. Has ${name} been started?`);
28
29
  process.exit(1);
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "volute",
7
- version: "0.6.0",
7
+ version: "0.8.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",
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-AZEL2IEK.js";
5
5
  import {
6
6
  daemonFetch
7
- } from "./chunk-JR4UXCTO.js";
7
+ } from "./chunk-23L3MKEV.js";
8
8
  import {
9
9
  resolveAgent
10
- } from "./chunk-UWHWAPGO.js";
10
+ } from "./chunk-DP2DX4WV.js";
11
11
  import "./chunk-K3NQKI34.js";
12
12
 
13
13
  // src/commands/restart.ts
@@ -7,8 +7,8 @@ import {
7
7
  } from "./chunk-D424ZQGI.js";
8
8
  import {
9
9
  daemonFetch
10
- } from "./chunk-JR4UXCTO.js";
11
- import "./chunk-UWHWAPGO.js";
10
+ } from "./chunk-23L3MKEV.js";
11
+ import "./chunk-DP2DX4WV.js";
12
12
  import "./chunk-K3NQKI34.js";
13
13
 
14
14
  // src/commands/schedule.ts
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveAgentName
4
+ } from "./chunk-AZEL2IEK.js";
5
+ import {
6
+ getChannelDriver
7
+ } from "./chunk-LIPPXNIE.js";
8
+ import {
9
+ loadMergedEnv
10
+ } from "./chunk-QF22MYDJ.js";
11
+ import "./chunk-N6MLQ26B.js";
12
+ import {
13
+ parseArgs
14
+ } from "./chunk-D424ZQGI.js";
15
+ import {
16
+ daemonFetch
17
+ } from "./chunk-23L3MKEV.js";
18
+ import {
19
+ resolveAgent
20
+ } from "./chunk-DP2DX4WV.js";
21
+ import "./chunk-K3NQKI34.js";
22
+
23
+ // src/commands/send.ts
24
+ import { userInfo } from "os";
25
+
26
+ // src/lib/parse-target.ts
27
+ function parseTarget(target) {
28
+ const colonIdx = target.indexOf(":");
29
+ if (colonIdx !== -1) {
30
+ const platform = target.slice(0, colonIdx);
31
+ const identifier = target.slice(colonIdx + 1);
32
+ return {
33
+ platform,
34
+ identifier,
35
+ uri: target,
36
+ isDM: identifier.startsWith("@")
37
+ };
38
+ }
39
+ if (target.startsWith("@")) {
40
+ return {
41
+ platform: "volute",
42
+ identifier: target,
43
+ uri: `volute:${target}`,
44
+ isDM: true
45
+ };
46
+ }
47
+ return {
48
+ platform: "volute",
49
+ identifier: target,
50
+ uri: `volute:${target}`,
51
+ isDM: false
52
+ };
53
+ }
54
+
55
+ // src/lib/read-stdin.ts
56
+ import { isatty } from "tty";
57
+ async function readStdin() {
58
+ if (isatty(0)) return void 0;
59
+ const chunks = [];
60
+ try {
61
+ for await (const chunk of process.stdin) {
62
+ chunks.push(chunk);
63
+ }
64
+ } catch (err) {
65
+ console.error(`Failed to read from stdin: ${err instanceof Error ? err.message : String(err)}`);
66
+ process.exit(1);
67
+ }
68
+ const text = Buffer.concat(chunks).toString().replace(/\r?\n$/, "");
69
+ return text || void 0;
70
+ }
71
+
72
+ // src/commands/send.ts
73
+ async function run(args) {
74
+ const { positional, flags } = parseArgs(args, {
75
+ agent: { type: "string" }
76
+ });
77
+ const target = positional[0];
78
+ const message = positional[1] ?? await readStdin();
79
+ if (!target || !message) {
80
+ console.error('Usage: volute send <target> "<message>" [--agent <name>]');
81
+ console.error(' echo "message" | volute send <target> [--agent <name>]');
82
+ console.error("");
83
+ console.error("Examples:");
84
+ console.error(' volute send @other-agent "hello"');
85
+ console.error(' volute send animal-chat "hello everyone"');
86
+ console.error(' volute send discord:server/channel "hello"');
87
+ process.exit(1);
88
+ }
89
+ const parsed = parseTarget(target);
90
+ const driver = getChannelDriver(parsed.platform);
91
+ if (!driver) {
92
+ console.error(`No driver for platform: ${parsed.platform}`);
93
+ process.exit(1);
94
+ }
95
+ let channelUri = parsed.uri;
96
+ if (parsed.isDM && parsed.platform === "volute") {
97
+ const targetName = parsed.identifier.slice(1);
98
+ const agentSelf = process.env.VOLUTE_AGENT;
99
+ const sender = agentSelf || userInfo().username;
100
+ if (!driver.createConversation) {
101
+ console.error("Volute driver does not support creating conversations");
102
+ process.exit(1);
103
+ }
104
+ const env = {
105
+ VOLUTE_AGENT: targetName,
106
+ VOLUTE_SENDER: sender
107
+ };
108
+ try {
109
+ channelUri = await driver.createConversation(env, [sender]);
110
+ } catch (err) {
111
+ console.error(err instanceof Error ? err.message : String(err));
112
+ process.exit(1);
113
+ }
114
+ try {
115
+ await driver.send(env, channelUri, message);
116
+ console.log("Message sent.");
117
+ } catch (err) {
118
+ console.error(err instanceof Error ? err.message : String(err));
119
+ process.exit(1);
120
+ }
121
+ if (agentSelf) {
122
+ try {
123
+ await daemonFetch(`/api/agents/${encodeURIComponent(agentSelf)}/history`, {
124
+ method: "POST",
125
+ headers: { "Content-Type": "application/json" },
126
+ body: JSON.stringify({ channel: channelUri, content: message })
127
+ });
128
+ } catch (err) {
129
+ console.error(`Failed to persist to history: ${err instanceof Error ? err.message : err}`);
130
+ }
131
+ }
132
+ } else {
133
+ const agentName = resolveAgentName(flags);
134
+ const { dir } = resolveAgent(agentName);
135
+ const env = {
136
+ ...loadMergedEnv(agentName),
137
+ VOLUTE_AGENT: agentName,
138
+ VOLUTE_AGENT_DIR: dir
139
+ };
140
+ try {
141
+ await driver.send(env, channelUri, message);
142
+ console.log("Message sent.");
143
+ } catch (err) {
144
+ console.error(err instanceof Error ? err.message : String(err));
145
+ process.exit(1);
146
+ }
147
+ if (process.env.VOLUTE_AGENT) {
148
+ try {
149
+ await daemonFetch(`/api/agents/${encodeURIComponent(agentName)}/history`, {
150
+ method: "POST",
151
+ headers: { "Content-Type": "application/json" },
152
+ body: JSON.stringify({ channel: channelUri, content: message })
153
+ });
154
+ } catch (err) {
155
+ console.error(`Failed to persist to history: ${err instanceof Error ? err.message : err}`);
156
+ }
157
+ }
158
+ }
159
+ }
160
+ export {
161
+ run
162
+ };
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-D424ZQGI.js";
5
5
  import {
6
6
  resolveVoluteBin
7
- } from "./chunk-5SKQ6J7T.js";
7
+ } from "./chunk-5C5JWR2L.js";
8
8
  import "./chunk-K3NQKI34.js";
9
9
 
10
10
  // src/commands/service.ts
@@ -4,11 +4,11 @@ import {
4
4
  } from "./chunk-D424ZQGI.js";
5
5
  import {
6
6
  ensureVoluteGroup
7
- } from "./chunk-W76KWE23.js";
7
+ } from "./chunk-IQXBMFZG.js";
8
8
  import {
9
9
  resolveVoluteBin
10
- } from "./chunk-5SKQ6J7T.js";
11
- import "./chunk-UWHWAPGO.js";
10
+ } from "./chunk-5C5JWR2L.js";
11
+ import "./chunk-DP2DX4WV.js";
12
12
  import "./chunk-K3NQKI34.js";
13
13
 
14
14
  // src/commands/setup.ts
@@ -17,6 +17,7 @@ import { existsSync, mkdirSync, rmSync, unlinkSync, writeFileSync } from "fs";
17
17
  var SERVICE_NAME = "volute.service";
18
18
  var SERVICE_PATH = `/etc/systemd/system/${SERVICE_NAME}`;
19
19
  var DATA_DIR = "/var/lib/volute";
20
+ var AGENTS_DIR = "/agents";
20
21
  var HOST_RE = /^[a-zA-Z0-9.:_-]+$/;
21
22
  function validateHost(host) {
22
23
  if (!HOST_RE.test(host)) {
@@ -35,9 +36,15 @@ After=network.target
35
36
  Type=exec
36
37
  ExecStart=${voluteBin} ${args.join(" ")}
37
38
  Environment=VOLUTE_HOME=${DATA_DIR}
39
+ Environment=VOLUTE_AGENTS_DIR=${AGENTS_DIR}
38
40
  Environment=VOLUTE_ISOLATION=user
39
41
  Restart=on-failure
40
42
  RestartSec=5
43
+ ProtectSystem=strict
44
+ ReadWritePaths=${DATA_DIR} ${AGENTS_DIR}
45
+ PrivateTmp=yes
46
+ ProtectHome=yes
47
+ RestrictSUIDSGID=yes
41
48
 
42
49
  [Install]
43
50
  WantedBy=multi-user.target
@@ -57,10 +64,13 @@ function install(port, host) {
57
64
  const voluteBin = resolveVoluteBin();
58
65
  mkdirSync(DATA_DIR, { recursive: true });
59
66
  console.log(`Created ${DATA_DIR}`);
67
+ mkdirSync(AGENTS_DIR, { recursive: true });
68
+ console.log(`Created ${AGENTS_DIR}`);
60
69
  ensureVoluteGroup({ force: true });
61
70
  console.log("Ensured volute group exists");
62
71
  execFileSync("chmod", ["755", DATA_DIR]);
63
- console.log("Set permissions on data directory");
72
+ execFileSync("chmod", ["755", AGENTS_DIR]);
73
+ console.log("Set permissions on directories");
64
74
  writeFileSync(SERVICE_PATH, generateUnit(voluteBin, port, host ?? "0.0.0.0"));
65
75
  console.log(`Wrote ${SERVICE_PATH}`);
66
76
  execFileSync("systemctl", ["daemon-reload"]);
@@ -97,10 +107,15 @@ function uninstall(force) {
97
107
  const members = output.split(":")[3]?.trim();
98
108
  if (members) {
99
109
  for (const user of members.split(",")) {
110
+ const u = user.trim();
100
111
  try {
101
- execFileSync("userdel", [user.trim()], { stdio: "ignore" });
112
+ execFileSync("userdel", [u], { stdio: "ignore" });
113
+ } catch {
114
+ console.warn(`Warning: failed to remove user ${u}`);
115
+ }
116
+ try {
117
+ execFileSync("groupdel", [u], { stdio: "ignore" });
102
118
  } catch {
103
- console.warn(`Warning: failed to remove user ${user.trim()}`);
104
119
  }
105
120
  }
106
121
  }
@@ -110,6 +125,10 @@ function uninstall(force) {
110
125
  rmSync(DATA_DIR, { recursive: true, force: true });
111
126
  console.log(`Deleted ${DATA_DIR}`);
112
127
  }
128
+ if (existsSync(AGENTS_DIR)) {
129
+ rmSync(AGENTS_DIR, { recursive: true, force: true });
130
+ console.log(`Deleted ${AGENTS_DIR}`);
131
+ }
113
132
  try {
114
133
  execFileSync("groupdel", ["volute"], { stdio: "ignore" });
115
134
  console.log("Removed volute group");
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  daemonFetch
4
- } from "./chunk-JR4UXCTO.js";
4
+ } from "./chunk-23L3MKEV.js";
5
5
  import {
6
6
  resolveAgent
7
- } from "./chunk-UWHWAPGO.js";
7
+ } from "./chunk-DP2DX4WV.js";
8
8
  import "./chunk-K3NQKI34.js";
9
9
 
10
10
  // src/commands/start.ts
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  daemonFetch
4
- } from "./chunk-JR4UXCTO.js";
5
- import "./chunk-UWHWAPGO.js";
4
+ } from "./chunk-23L3MKEV.js";
5
+ import "./chunk-DP2DX4WV.js";
6
6
  import "./chunk-K3NQKI34.js";
7
7
 
8
8
  // src/commands/status.ts
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-AZEL2IEK.js";
5
5
  import {
6
6
  daemonFetch
7
- } from "./chunk-JR4UXCTO.js";
7
+ } from "./chunk-23L3MKEV.js";
8
8
  import {
9
9
  resolveAgent
10
- } from "./chunk-UWHWAPGO.js";
10
+ } from "./chunk-DP2DX4WV.js";
11
11
  import "./chunk-K3NQKI34.js";
12
12
 
13
13
  // src/commands/stop.ts
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ readGlobalConfig,
4
+ run
5
+ } from "./chunk-XSJ27WEM.js";
6
+ import "./chunk-D424ZQGI.js";
7
+ import "./chunk-DP2DX4WV.js";
8
+ import "./chunk-K3NQKI34.js";
9
+ export {
10
+ readGlobalConfig,
11
+ run
12
+ };
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  checkForUpdate
4
- } from "./chunk-AOKAQGO4.js";
4
+ } from "./chunk-RT6Y7AR3.js";
5
5
  import {
6
6
  execInherit,
7
7
  resolveVoluteBin
8
- } from "./chunk-5SKQ6J7T.js";
8
+ } from "./chunk-5C5JWR2L.js";
9
9
  import {
10
10
  voluteHome
11
- } from "./chunk-UWHWAPGO.js";
11
+ } from "./chunk-DP2DX4WV.js";
12
12
  import "./chunk-K3NQKI34.js";
13
13
 
14
14
  // src/commands/update.ts
@@ -5,8 +5,8 @@ import {
5
5
  fetchLatestVersion,
6
6
  getCurrentVersion,
7
7
  isNewer
8
- } from "./chunk-AOKAQGO4.js";
9
- import "./chunk-UWHWAPGO.js";
8
+ } from "./chunk-RT6Y7AR3.js";
9
+ import "./chunk-DP2DX4WV.js";
10
10
  import "./chunk-K3NQKI34.js";
11
11
  export {
12
12
  checkForUpdate,
@@ -13,15 +13,15 @@ import {
13
13
  import {
14
14
  exec,
15
15
  execInherit
16
- } from "./chunk-5SKQ6J7T.js";
16
+ } from "./chunk-5C5JWR2L.js";
17
17
  import {
18
18
  daemonFetch
19
- } from "./chunk-JR4UXCTO.js";
19
+ } from "./chunk-23L3MKEV.js";
20
20
  import {
21
21
  addVariant,
22
22
  nextPort,
23
23
  resolveAgent
24
- } from "./chunk-UWHWAPGO.js";
24
+ } from "./chunk-DP2DX4WV.js";
25
25
  import "./chunk-K3NQKI34.js";
26
26
 
27
27
  // src/commands/upgrade.ts
@@ -215,7 +215,7 @@ Upgrade variant running on port ${variantPort}`);
215
215
  console.log(`
216
216
  Next steps:`);
217
217
  console.log(
218
- ` volute message send ${agentName}@${VARIANT_NAME} "hello" # chat with upgraded variant`
218
+ ` volute send @${agentName}@${VARIANT_NAME} "hello" # chat with upgraded variant`
219
219
  );
220
220
  console.log(` volute variant merge ${VARIANT_NAME} # merge back when satisfied`);
221
221
  }