volute 0.8.2 → 0.9.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.
- package/dist/{agent-YORVRB6I.js → agent-MB3OTRRK.js} +8 -8
- package/dist/api-client-YPKOZP2O.js +10 -0
- package/dist/{channel-RDGHBFSI.js → channel-G5D4VBXY.js} +67 -82
- package/dist/chunk-4RQBJWQX.js +17 -0
- package/dist/{chunk-XSJ27WEM.js → chunk-AWHQZDB4.js} +16 -1
- package/dist/{chunk-23L3MKEV.js → chunk-STOEJOJO.js} +18 -4
- package/dist/{chunk-HZ5LTOEJ.js → chunk-YNNK4QN2.js} +16 -1
- package/dist/cli.js +15 -15
- package/dist/{connector-ZP6MEFF4.js → connector-PK7D5GTN.js} +38 -21
- package/dist/{daemon-client-54J3EIZD.js → daemon-client-P44NU3KU.js} +1 -1
- package/dist/{daemon-restart-CPBLMMRI.js → daemon-restart-EKDXXHKH.js} +7 -2
- package/dist/daemon.js +252 -56
- package/dist/{delete-45TGQC4N.js → delete-WKQKE3FT.js} +7 -4
- package/dist/{down-O4EWZTVA.js → down-4DGRZRJU.js} +1 -1
- package/dist/{env-KMNYGVZ2.js → env-HZMZSWWD.js} +85 -36
- package/dist/{history-PXJVYLVY.js → history-SH25BAA5.js} +13 -10
- package/dist/logs-V54B6QSG.js +77 -0
- package/dist/{package-TWWKVRRL.js → package-WPX6LCYE.js} +1 -1
- package/dist/{restart-KVH3TK5N.js → restart-CCYM3MEC.js} +10 -4
- package/dist/{schedule-HCUCBNQI.js → schedule-XGBUF7NU.js} +26 -10
- package/dist/{send-BNC2S5BY.js → send-TFZ62XPZ.js} +37 -29
- package/dist/{service-XCADRKIS.js → service-56CY4S6Z.js} +24 -0
- package/dist/{setup-2JDBGU7Y.js → setup-7SPMWF2O.js} +5 -3
- package/dist/{start-QU73YTJW.js → start-6YRS6FF6.js} +7 -2
- package/dist/{status-Q6ZQJXNI.js → status-SIMKH3ZE.js} +8 -3
- package/dist/{stop-N7U5N6A7.js → stop-UQSNF4CG.js} +7 -2
- package/dist/{up-V6EAA7OZ.js → up-J7AHQHIM.js} +1 -1
- package/dist/{update-EUCZ7XGG.js → update-3TGXUTO2.js} +10 -0
- package/dist/{upgrade-CZF6PN7Y.js → upgrade-BRNMSQBX.js} +13 -4
- package/dist/{variant-RKXPN5DH.js → variant-AQRAN6FR.js} +32 -15
- package/package.json +1 -1
- package/dist/logs-TZB3MTLZ.js +0 -37
|
@@ -9,36 +9,36 @@ async function run(args) {
|
|
|
9
9
|
await import("./create-HGJHLABX.js").then((m) => m.run(args.slice(1)));
|
|
10
10
|
break;
|
|
11
11
|
case "start":
|
|
12
|
-
await import("./start-
|
|
12
|
+
await import("./start-6YRS6FF6.js").then((m) => m.run(args.slice(1)));
|
|
13
13
|
break;
|
|
14
14
|
case "stop":
|
|
15
|
-
await import("./stop-
|
|
15
|
+
await import("./stop-UQSNF4CG.js").then((m) => m.run(args.slice(1)));
|
|
16
16
|
break;
|
|
17
17
|
case "restart":
|
|
18
|
-
await import("./restart-
|
|
18
|
+
await import("./restart-CCYM3MEC.js").then((m) => m.run(args.slice(1)));
|
|
19
19
|
break;
|
|
20
20
|
case "delete":
|
|
21
|
-
await import("./delete-
|
|
21
|
+
await import("./delete-WKQKE3FT.js").then((m) => m.run(args.slice(1)));
|
|
22
22
|
break;
|
|
23
23
|
case "list":
|
|
24
|
-
await import("./status-
|
|
24
|
+
await import("./status-SIMKH3ZE.js").then((m) => m.run(args.slice(1)));
|
|
25
25
|
break;
|
|
26
26
|
case "status": {
|
|
27
27
|
const rest = args.slice(1);
|
|
28
28
|
if (!rest[0] && process.env.VOLUTE_AGENT) {
|
|
29
29
|
rest.unshift(process.env.VOLUTE_AGENT);
|
|
30
30
|
}
|
|
31
|
-
await import("./status-
|
|
31
|
+
await import("./status-SIMKH3ZE.js").then((m) => m.run(rest));
|
|
32
32
|
break;
|
|
33
33
|
}
|
|
34
34
|
case "logs": {
|
|
35
35
|
const rest = args.slice(1);
|
|
36
36
|
const logsArgs = transformAgentFlag(rest);
|
|
37
|
-
await import("./logs-
|
|
37
|
+
await import("./logs-V54B6QSG.js").then((m) => m.run(logsArgs));
|
|
38
38
|
break;
|
|
39
39
|
}
|
|
40
40
|
case "upgrade":
|
|
41
|
-
await import("./upgrade-
|
|
41
|
+
await import("./upgrade-BRNMSQBX.js").then((m) => m.run(args.slice(1)));
|
|
42
42
|
break;
|
|
43
43
|
case "import":
|
|
44
44
|
await import("./import-CNEDF3TD.js").then((m) => m.run(args.slice(1)));
|
|
@@ -3,24 +3,16 @@ import {
|
|
|
3
3
|
resolveAgentName
|
|
4
4
|
} from "./chunk-AZEL2IEK.js";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "./chunk-LIPPXNIE.js";
|
|
9
|
-
import {
|
|
10
|
-
loadMergedEnv
|
|
11
|
-
} from "./chunk-QF22MYDJ.js";
|
|
12
|
-
import {
|
|
13
|
-
writeChannelEntry
|
|
14
|
-
} from "./chunk-N6MLQ26B.js";
|
|
6
|
+
daemonFetch
|
|
7
|
+
} from "./chunk-STOEJOJO.js";
|
|
15
8
|
import {
|
|
16
9
|
parseArgs
|
|
17
10
|
} from "./chunk-D424ZQGI.js";
|
|
11
|
+
import "./chunk-DP2DX4WV.js";
|
|
18
12
|
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
agentDir
|
|
23
|
-
} from "./chunk-DP2DX4WV.js";
|
|
13
|
+
getClient,
|
|
14
|
+
urlOf
|
|
15
|
+
} from "./chunk-4RQBJWQX.js";
|
|
24
16
|
import "./chunk-K3NQKI34.js";
|
|
25
17
|
|
|
26
18
|
// src/commands/channel.ts
|
|
@@ -72,17 +64,20 @@ async function readChannel(args) {
|
|
|
72
64
|
}
|
|
73
65
|
const agentName = resolveAgentName(flags);
|
|
74
66
|
const { platform } = parseUri(uri);
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
67
|
+
const limit = flags.limit ?? 20;
|
|
68
|
+
const client = getClient();
|
|
69
|
+
const url = client.api.agents[":name"].channels.read.$url({ param: { name: agentName } });
|
|
70
|
+
url.searchParams.set("platform", platform);
|
|
71
|
+
url.searchParams.set("uri", uri);
|
|
72
|
+
url.searchParams.set("limit", String(limit));
|
|
73
|
+
const res = await daemonFetch(urlOf(url));
|
|
74
|
+
if (!res.ok) {
|
|
75
|
+
const body = await res.json().catch(() => ({}));
|
|
76
|
+
console.error(body.error ?? `Server responded with ${res.status}`);
|
|
84
77
|
process.exit(1);
|
|
85
78
|
}
|
|
79
|
+
const output = await res.text();
|
|
80
|
+
console.log(output);
|
|
86
81
|
}
|
|
87
82
|
async function listChannels(args) {
|
|
88
83
|
const { positional, flags } = parseArgs(args, {
|
|
@@ -90,29 +85,27 @@ async function listChannels(args) {
|
|
|
90
85
|
});
|
|
91
86
|
const platform = positional[0];
|
|
92
87
|
const agentName = resolveAgentName(flags);
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
console.log(parts.join(" "));
|
|
88
|
+
const client = getClient();
|
|
89
|
+
const url = client.api.agents[":name"].channels.list.$url({ param: { name: agentName } });
|
|
90
|
+
if (platform) url.searchParams.set("platform", platform);
|
|
91
|
+
const res = await daemonFetch(urlOf(url));
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
const body = await res.json().catch(() => ({}));
|
|
94
|
+
console.error(body.error ?? `Server responded with ${res.status}`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
const results = await res.json();
|
|
98
|
+
for (const [p, convs] of Object.entries(results)) {
|
|
99
|
+
for (const conv of convs) {
|
|
100
|
+
if (conv.error) {
|
|
101
|
+
console.error(`${p}: ${conv.error}`);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const parts = [conv.id.padEnd(24), conv.name.padEnd(28), conv.type];
|
|
105
|
+
if (conv.participantCount != null) {
|
|
106
|
+
parts.push(String(conv.participantCount));
|
|
113
107
|
}
|
|
114
|
-
|
|
115
|
-
console.error(`${p}: ${err instanceof Error ? err.message : String(err)}`);
|
|
108
|
+
console.log(parts.join(" "));
|
|
116
109
|
}
|
|
117
110
|
}
|
|
118
111
|
}
|
|
@@ -125,23 +118,20 @@ async function listUsers(args) {
|
|
|
125
118
|
console.error("Usage: volute channel users <platform> [--agent <name>]");
|
|
126
119
|
process.exit(1);
|
|
127
120
|
}
|
|
128
|
-
const driver = requireDriver(platform);
|
|
129
|
-
if (!driver.listUsers) {
|
|
130
|
-
console.error(`Platform ${platform} does not support listing users`);
|
|
131
|
-
process.exit(1);
|
|
132
|
-
}
|
|
133
121
|
const agentName = resolveAgentName(flags);
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
} catch (err) {
|
|
142
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
122
|
+
const client = getClient();
|
|
123
|
+
const url = client.api.agents[":name"].channels.users.$url({ param: { name: agentName } });
|
|
124
|
+
url.searchParams.set("platform", platform);
|
|
125
|
+
const res = await daemonFetch(urlOf(url));
|
|
126
|
+
if (!res.ok) {
|
|
127
|
+
const body = await res.json().catch(() => ({}));
|
|
128
|
+
console.error(body.error ?? `Server responded with ${res.status}`);
|
|
143
129
|
process.exit(1);
|
|
144
130
|
}
|
|
131
|
+
const users = await res.json();
|
|
132
|
+
for (const user of users) {
|
|
133
|
+
console.log(`${user.username.padEnd(20)} ${user.id.padEnd(20)} ${user.type ?? ""}`);
|
|
134
|
+
}
|
|
145
135
|
}
|
|
146
136
|
async function createChannel(args) {
|
|
147
137
|
const { positional, flags } = parseArgs(args, {
|
|
@@ -156,22 +146,24 @@ async function createChannel(args) {
|
|
|
156
146
|
);
|
|
157
147
|
process.exit(1);
|
|
158
148
|
}
|
|
159
|
-
const driver = requireDriver(platform);
|
|
160
|
-
if (!driver.createConversation) {
|
|
161
|
-
console.error(`Platform ${platform} does not support creating conversations`);
|
|
162
|
-
process.exit(1);
|
|
163
|
-
}
|
|
164
149
|
const agentName = resolveAgentName(flags);
|
|
165
|
-
const dir = agentDir(agentName);
|
|
166
|
-
const env = { ...loadMergedEnv(agentName), VOLUTE_AGENT: agentName, VOLUTE_AGENT_DIR: dir };
|
|
167
150
|
const participants = flags.participants.split(",").map((s) => s.trim());
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
151
|
+
const client = getClient();
|
|
152
|
+
const res = await daemonFetch(
|
|
153
|
+
urlOf(client.api.agents[":name"].channels.create.$url({ param: { name: agentName } })),
|
|
154
|
+
{
|
|
155
|
+
method: "POST",
|
|
156
|
+
headers: { "Content-Type": "application/json" },
|
|
157
|
+
body: JSON.stringify({ platform, participants, name: flags.name })
|
|
158
|
+
}
|
|
159
|
+
);
|
|
160
|
+
if (!res.ok) {
|
|
161
|
+
const body = await res.json().catch(() => ({}));
|
|
162
|
+
console.error(body.error ?? `Server responded with ${res.status}`);
|
|
173
163
|
process.exit(1);
|
|
174
164
|
}
|
|
165
|
+
const data = await res.json();
|
|
166
|
+
console.log(data.slug);
|
|
175
167
|
}
|
|
176
168
|
async function typingChannel(args) {
|
|
177
169
|
const { positional, flags } = parseArgs(args, {
|
|
@@ -184,9 +176,10 @@ async function typingChannel(args) {
|
|
|
184
176
|
}
|
|
185
177
|
const agentName = resolveAgentName(flags);
|
|
186
178
|
try {
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
);
|
|
179
|
+
const client = getClient();
|
|
180
|
+
const url = client.api.agents[":name"].typing.$url({ param: { name: agentName } });
|
|
181
|
+
url.searchParams.set("channel", uri);
|
|
182
|
+
const res = await daemonFetch(urlOf(url));
|
|
190
183
|
if (!res.ok) {
|
|
191
184
|
const body = await res.json().catch(() => ({}));
|
|
192
185
|
console.error(body.error ?? `Server responded with ${res.status}`);
|
|
@@ -209,14 +202,6 @@ function parseUri(uri) {
|
|
|
209
202
|
}
|
|
210
203
|
return { platform: uri.slice(0, colonIdx), channelId: uri.slice(colonIdx + 1) };
|
|
211
204
|
}
|
|
212
|
-
function requireDriver(platform) {
|
|
213
|
-
const driver = getChannelDriver(platform);
|
|
214
|
-
if (!driver) {
|
|
215
|
-
console.error(`No channel driver for platform: ${platform}`);
|
|
216
|
-
process.exit(1);
|
|
217
|
-
}
|
|
218
|
-
return driver;
|
|
219
|
-
}
|
|
220
205
|
export {
|
|
221
206
|
run
|
|
222
207
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/lib/api-client.ts
|
|
4
|
+
import { hc } from "hono/client";
|
|
5
|
+
var _client;
|
|
6
|
+
function getClient() {
|
|
7
|
+
_client ??= hc("http://localhost");
|
|
8
|
+
return _client;
|
|
9
|
+
}
|
|
10
|
+
function urlOf(url) {
|
|
11
|
+
return url.pathname + url.search;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
getClient,
|
|
16
|
+
urlOf
|
|
17
|
+
};
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-DP2DX4WV.js";
|
|
8
8
|
|
|
9
9
|
// src/commands/up.ts
|
|
10
|
-
import { spawn } from "child_process";
|
|
10
|
+
import { execFileSync, spawn } from "child_process";
|
|
11
11
|
import { existsSync, mkdirSync, openSync, readFileSync } from "fs";
|
|
12
12
|
import { dirname, resolve } from "path";
|
|
13
13
|
function readGlobalConfig() {
|
|
@@ -20,12 +20,27 @@ function readGlobalConfig() {
|
|
|
20
20
|
process.exit(1);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
function isSystemdServiceEnabled() {
|
|
24
|
+
try {
|
|
25
|
+
execFileSync("systemctl", ["is-enabled", "--quiet", "volute"]);
|
|
26
|
+
return true;
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
23
31
|
async function run(args) {
|
|
24
32
|
const { flags } = parseArgs(args, {
|
|
25
33
|
port: { type: "number" },
|
|
26
34
|
host: { type: "string" },
|
|
27
35
|
foreground: { type: "boolean" }
|
|
28
36
|
});
|
|
37
|
+
if (!flags.foreground && isSystemdServiceEnabled()) {
|
|
38
|
+
console.error("Volute is managed by a systemd service.");
|
|
39
|
+
console.error("Use: sudo systemctl start volute");
|
|
40
|
+
console.error(" sudo systemctl restart volute");
|
|
41
|
+
console.error(" systemctl status volute");
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
29
44
|
const config = readGlobalConfig();
|
|
30
45
|
const port = flags.port ?? config.port ?? 4200;
|
|
31
46
|
const hostname = flags.host ?? config.hostname ?? "127.0.0.1";
|
|
@@ -9,19 +9,33 @@ import { resolve } from "path";
|
|
|
9
9
|
function readDaemonConfig() {
|
|
10
10
|
const configPath = resolve(voluteHome(), "daemon.json");
|
|
11
11
|
if (!existsSync(configPath)) {
|
|
12
|
-
|
|
12
|
+
if (existsSync("/etc/systemd/system/volute.service") && !process.env.VOLUTE_HOME) {
|
|
13
|
+
console.error("Volute is running as a system service but VOLUTE_HOME is not set.");
|
|
14
|
+
console.error("Re-run setup to update the CLI wrapper: sudo volute setup");
|
|
15
|
+
console.error("Then start a new shell or run: source /etc/profile.d/volute.sh");
|
|
16
|
+
} else {
|
|
17
|
+
console.error("Volute is not running. Start with: volute up");
|
|
18
|
+
}
|
|
13
19
|
process.exit(1);
|
|
14
20
|
}
|
|
15
21
|
try {
|
|
16
22
|
return JSON.parse(readFileSync(configPath, "utf-8"));
|
|
17
|
-
} catch {
|
|
18
|
-
|
|
23
|
+
} catch (err) {
|
|
24
|
+
const code = err.code;
|
|
25
|
+
if (code === "EACCES") {
|
|
26
|
+
console.error(`Permission denied reading ${configPath}. Try: sudo volute ...`);
|
|
27
|
+
} else {
|
|
28
|
+
console.error("Volute is not running. Start with: volute up");
|
|
29
|
+
}
|
|
19
30
|
process.exit(1);
|
|
20
31
|
}
|
|
21
32
|
}
|
|
22
33
|
function buildUrl(config) {
|
|
23
34
|
const url = new URL("http://localhost");
|
|
24
|
-
|
|
35
|
+
let hostname = config.hostname || "localhost";
|
|
36
|
+
if (hostname === "0.0.0.0") hostname = "127.0.0.1";
|
|
37
|
+
if (hostname === "::") hostname = "[::1]";
|
|
38
|
+
url.hostname = hostname;
|
|
25
39
|
url.port = String(config.port);
|
|
26
40
|
return url.origin;
|
|
27
41
|
}
|
|
@@ -4,9 +4,21 @@ import {
|
|
|
4
4
|
} from "./chunk-DP2DX4WV.js";
|
|
5
5
|
|
|
6
6
|
// src/commands/down.ts
|
|
7
|
+
import { execFileSync } from "child_process";
|
|
7
8
|
import { existsSync, readFileSync, unlinkSync } from "fs";
|
|
8
9
|
import { resolve } from "path";
|
|
10
|
+
function isSystemdServiceEnabled() {
|
|
11
|
+
try {
|
|
12
|
+
execFileSync("systemctl", ["is-enabled", "--quiet", "volute"]);
|
|
13
|
+
return true;
|
|
14
|
+
} catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
9
18
|
async function stopDaemon() {
|
|
19
|
+
if (isSystemdServiceEnabled()) {
|
|
20
|
+
return { stopped: false, reason: "systemd" };
|
|
21
|
+
}
|
|
10
22
|
const home = voluteHome();
|
|
11
23
|
const pidPath = resolve(home, "daemon.pid");
|
|
12
24
|
if (!existsSync(pidPath)) {
|
|
@@ -99,7 +111,10 @@ async function stopDaemon() {
|
|
|
99
111
|
async function run(_args) {
|
|
100
112
|
const result = await stopDaemon();
|
|
101
113
|
if (result.stopped) return;
|
|
102
|
-
if (result.reason === "
|
|
114
|
+
if (result.reason === "systemd") {
|
|
115
|
+
console.error("Volute is managed by a systemd service.");
|
|
116
|
+
console.error("Use: sudo systemctl stop volute");
|
|
117
|
+
} else if (result.reason === "orphan") {
|
|
103
118
|
console.error(`Daemon appears to be running on port ${result.port} but PID file is missing.`);
|
|
104
119
|
console.error(`Kill the process manually: lsof -ti :${result.port} | xargs kill`);
|
|
105
120
|
} else if (result.reason === "not-running") {
|
package/dist/cli.js
CHANGED
|
@@ -9,52 +9,52 @@ if (!process.env.VOLUTE_HOME) {
|
|
|
9
9
|
var command = process.argv[2];
|
|
10
10
|
var args = process.argv.slice(3);
|
|
11
11
|
if (command === "--version" || command === "-v") {
|
|
12
|
-
const { default: pkg } = await import("./package-
|
|
12
|
+
const { default: pkg } = await import("./package-WPX6LCYE.js");
|
|
13
13
|
console.log(pkg.version);
|
|
14
14
|
process.exit(0);
|
|
15
15
|
}
|
|
16
16
|
switch (command) {
|
|
17
17
|
case "agent":
|
|
18
|
-
await import("./agent-
|
|
18
|
+
await import("./agent-MB3OTRRK.js").then((m) => m.run(args));
|
|
19
19
|
break;
|
|
20
20
|
case "send":
|
|
21
|
-
await import("./send-
|
|
21
|
+
await import("./send-TFZ62XPZ.js").then((m) => m.run(args));
|
|
22
22
|
break;
|
|
23
23
|
case "history":
|
|
24
|
-
await import("./history-
|
|
24
|
+
await import("./history-SH25BAA5.js").then((m) => m.run(args));
|
|
25
25
|
break;
|
|
26
26
|
case "variant":
|
|
27
|
-
await import("./variant-
|
|
27
|
+
await import("./variant-AQRAN6FR.js").then((m) => m.run(args));
|
|
28
28
|
break;
|
|
29
29
|
case "connector":
|
|
30
|
-
await import("./connector-
|
|
30
|
+
await import("./connector-PK7D5GTN.js").then((m) => m.run(args));
|
|
31
31
|
break;
|
|
32
32
|
case "channel":
|
|
33
|
-
await import("./channel-
|
|
33
|
+
await import("./channel-G5D4VBXY.js").then((m) => m.run(args));
|
|
34
34
|
break;
|
|
35
35
|
case "schedule":
|
|
36
|
-
await import("./schedule-
|
|
36
|
+
await import("./schedule-XGBUF7NU.js").then((m) => m.run(args));
|
|
37
37
|
break;
|
|
38
38
|
case "env":
|
|
39
|
-
await import("./env-
|
|
39
|
+
await import("./env-HZMZSWWD.js").then((m) => m.run(args));
|
|
40
40
|
break;
|
|
41
41
|
case "up":
|
|
42
|
-
await import("./up-
|
|
42
|
+
await import("./up-J7AHQHIM.js").then((m) => m.run(args));
|
|
43
43
|
break;
|
|
44
44
|
case "down":
|
|
45
|
-
await import("./down-
|
|
45
|
+
await import("./down-4DGRZRJU.js").then((m) => m.run(args));
|
|
46
46
|
break;
|
|
47
47
|
case "restart":
|
|
48
|
-
await import("./daemon-restart-
|
|
48
|
+
await import("./daemon-restart-EKDXXHKH.js").then((m) => m.run(args));
|
|
49
49
|
break;
|
|
50
50
|
case "setup":
|
|
51
|
-
await import("./setup-
|
|
51
|
+
await import("./setup-7SPMWF2O.js").then((m) => m.run(args));
|
|
52
52
|
break;
|
|
53
53
|
case "service":
|
|
54
|
-
await import("./service-
|
|
54
|
+
await import("./service-56CY4S6Z.js").then((m) => m.run(args));
|
|
55
55
|
break;
|
|
56
56
|
case "update":
|
|
57
|
-
await import("./update-
|
|
57
|
+
await import("./update-3TGXUTO2.js").then((m) => m.run(args));
|
|
58
58
|
break;
|
|
59
59
|
case "--help":
|
|
60
60
|
case "-h":
|
|
@@ -3,19 +3,16 @@ import {
|
|
|
3
3
|
resolveAgentName
|
|
4
4
|
} from "./chunk-AZEL2IEK.js";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
writeEnv
|
|
9
|
-
} from "./chunk-QF22MYDJ.js";
|
|
6
|
+
daemonFetch
|
|
7
|
+
} from "./chunk-STOEJOJO.js";
|
|
10
8
|
import {
|
|
11
9
|
parseArgs
|
|
12
10
|
} from "./chunk-D424ZQGI.js";
|
|
11
|
+
import "./chunk-DP2DX4WV.js";
|
|
13
12
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
agentDir
|
|
18
|
-
} from "./chunk-DP2DX4WV.js";
|
|
13
|
+
getClient,
|
|
14
|
+
urlOf
|
|
15
|
+
} from "./chunk-4RQBJWQX.js";
|
|
19
16
|
import "./chunk-K3NQKI34.js";
|
|
20
17
|
|
|
21
18
|
// src/commands/connector.ts
|
|
@@ -84,8 +81,13 @@ async function connectConnector(args) {
|
|
|
84
81
|
console.error("Usage: volute connector connect <type> [--agent <name>]");
|
|
85
82
|
process.exit(1);
|
|
86
83
|
}
|
|
87
|
-
const
|
|
88
|
-
|
|
84
|
+
const client = getClient();
|
|
85
|
+
const connectorUrl = urlOf(
|
|
86
|
+
client.api.agents[":name"].connectors[":type"].$url({
|
|
87
|
+
param: { name: agentName, type }
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
let res = await daemonFetch(connectorUrl, { method: "POST" });
|
|
89
91
|
if (!res.ok) {
|
|
90
92
|
const body = await res.json().catch(() => ({ error: "Unknown error" }));
|
|
91
93
|
if (body.error === "missing_env" && "missing" in body) {
|
|
@@ -101,20 +103,32 @@ Set them with: volute env set <KEY> --agent ${agentName}`);
|
|
|
101
103
|
}
|
|
102
104
|
console.error(`${connectorName} connector requires some environment variables.
|
|
103
105
|
`);
|
|
104
|
-
const dir = agentDir(agentName);
|
|
105
|
-
const envPath = agentEnvPath(dir);
|
|
106
|
-
const env = readEnv(envPath);
|
|
107
106
|
for (const v of missing) {
|
|
108
107
|
const value = await promptValue(v.name, v.description);
|
|
109
108
|
if (!value) {
|
|
110
109
|
console.error(`No value provided for ${v.name}. Aborting.`);
|
|
111
110
|
process.exit(1);
|
|
112
111
|
}
|
|
113
|
-
|
|
112
|
+
const envRes = await daemonFetch(
|
|
113
|
+
urlOf(
|
|
114
|
+
client.api.agents[":name"].env[":key"].$url({
|
|
115
|
+
param: { name: agentName, key: v.name }
|
|
116
|
+
})
|
|
117
|
+
),
|
|
118
|
+
{
|
|
119
|
+
method: "PUT",
|
|
120
|
+
headers: { "Content-Type": "application/json" },
|
|
121
|
+
body: JSON.stringify({ value })
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
if (!envRes.ok) {
|
|
125
|
+
const errBody = await envRes.json().catch(() => ({}));
|
|
126
|
+
console.error(`Failed to set ${v.name}: ${errBody.error ?? `HTTP ${envRes.status}`}`);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
114
129
|
}
|
|
115
|
-
writeEnv(envPath, env);
|
|
116
130
|
console.log("Environment variables saved.\n");
|
|
117
|
-
res = await daemonFetch(
|
|
131
|
+
res = await daemonFetch(connectorUrl, { method: "POST" });
|
|
118
132
|
if (!res.ok) {
|
|
119
133
|
const retryBody = await res.json().catch(() => ({ error: "Unknown error" }));
|
|
120
134
|
console.error(
|
|
@@ -139,11 +153,14 @@ async function disconnectConnector(args) {
|
|
|
139
153
|
console.error("Usage: volute connector disconnect <type> [--agent <name>]");
|
|
140
154
|
process.exit(1);
|
|
141
155
|
}
|
|
156
|
+
const client = getClient();
|
|
142
157
|
const res = await daemonFetch(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
158
|
+
urlOf(
|
|
159
|
+
client.api.agents[":name"].connectors[":type"].$url({
|
|
160
|
+
param: { name: agentName, type }
|
|
161
|
+
})
|
|
162
|
+
),
|
|
163
|
+
{ method: "DELETE" }
|
|
147
164
|
);
|
|
148
165
|
if (!res.ok) {
|
|
149
166
|
const body = await res.json().catch(() => ({ error: "Unknown error" }));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
run
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AWHQZDB4.js";
|
|
5
5
|
import {
|
|
6
6
|
stopDaemon
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YNNK4QN2.js";
|
|
8
8
|
import "./chunk-D424ZQGI.js";
|
|
9
9
|
import "./chunk-DP2DX4WV.js";
|
|
10
10
|
import "./chunk-K3NQKI34.js";
|
|
@@ -12,6 +12,11 @@ import "./chunk-K3NQKI34.js";
|
|
|
12
12
|
// src/commands/daemon-restart.ts
|
|
13
13
|
async function run2(args) {
|
|
14
14
|
const result = await stopDaemon();
|
|
15
|
+
if (!result.stopped && result.reason === "systemd") {
|
|
16
|
+
console.error("Volute is managed by a systemd service.");
|
|
17
|
+
console.error("Use: sudo systemctl restart volute");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
15
20
|
if (!result.stopped && result.reason === "kill-failed") {
|
|
16
21
|
console.error("Cannot restart: failed to stop the running daemon.");
|
|
17
22
|
process.exit(1);
|