volute 0.2.1 → 0.3.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/README.md +46 -0
- package/dist/agent-manager-2LU6KULR.js +15 -0
- package/dist/{channel-2WJRM7PE.js → channel-H7N4SGR2.js} +7 -7
- package/dist/{chunk-XZN4WPNC.js → chunk-5SKQ6J7T.js} +9 -1
- package/dist/chunk-DEUAVGSA.js +81 -0
- package/dist/{chunk-L3BQEZ4Z.js → chunk-IPIPLGME.js} +74 -13
- package/dist/chunk-K3NQKI34.js +10 -0
- package/dist/chunk-NETNFBA5.js +28 -0
- package/dist/{chunk-6UCG6MIX.js → chunk-RALYNMHR.js} +1 -6
- package/dist/chunk-VRVVQIYY.js +15 -0
- package/dist/{chunk-4YXYAMFT.js → chunk-VVD3XO3E.js} +7 -6
- package/dist/{chunk-KFNNHQK7.js → chunk-YEIHRP2J.js} +1 -1
- package/dist/cli.js +56 -51
- package/dist/connector-6LWB5PRU.js +96 -0
- package/dist/connectors/discord.js +22 -1
- package/dist/{create-23AM7H5B.js → create-RSWWMGKT.js} +22 -5
- package/dist/daemon-client-27KMQQKX.js +9 -0
- package/dist/daemon.js +162 -132
- package/dist/{delete-GDMSOW3U.js → delete-4ERL2QHH.js} +7 -2
- package/dist/{down-WTF73FE7.js → down-HRC4MQCT.js} +10 -3
- package/dist/{env-YKUJOFHE.js → env-DBWDTIP6.js} +3 -2
- package/dist/{history-7WVVKMUY.js → history-W7BD2H74.js} +9 -8
- package/dist/{import-42DOLBDT.js → import-6HTSSDFW.js} +143 -36
- package/dist/{logs-SYRQOL6B.js → logs-NHWGHNBF.js} +8 -7
- package/dist/{schedule-J37XQM6E.js → schedule-DKZ2E2CL.js} +41 -41
- package/dist/{send-PLOYEYER.js → send-5LEJXPYV.js} +3 -2
- package/dist/service-SA4TTMDU.js +195 -0
- package/dist/setup-ZMNTOJAV.js +148 -0
- package/dist/{start-AG7QLULK.js → start-2BSXX6BS.js} +3 -2
- package/dist/{status-GCNU4M3K.js → status-N23CV27T.js} +3 -2
- package/dist/{stop-IL5Q6NER.js → stop-DSKBIJ2D.js} +3 -2
- package/dist/{up-ZC6G6K4K.js → up-4UGID4DM.js} +5 -3
- package/dist/{upgrade-DD5TNJWU.js → upgrade-BGFVRCVP.js} +4 -3
- package/dist/{merge-CSAVLSLY.js → variant-JPLJTS2P.js} +179 -10
- package/dist/web-assets/assets/index-BC5eSqbY.js +296 -0
- package/dist/web-assets/index.html +1 -1
- package/drizzle/0002_wealthy_the_call.sql +6 -0
- package/drizzle/meta/0002_snapshot.json +339 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +4 -1
- package/templates/_base/.init/SOUL.md +5 -1
- package/templates/_base/_skills/memory/SKILL.md +2 -2
- package/templates/_base/_skills/volute-agent/SKILL.md +28 -11
- package/templates/_base/home/VOLUTE.md +4 -2
- package/templates/_base/src/lib/auto-commit.ts +8 -3
- package/templates/_base/src/lib/types.ts +6 -2
- package/templates/_base/src/lib/volute-server.ts +5 -0
- package/templates/agent-sdk/.init/CLAUDE.md +15 -13
- package/templates/agent-sdk/src/agent.ts +12 -1
- package/templates/agent-sdk/src/lib/agent-sessions.ts +28 -4
- package/templates/pi/.init/AGENTS.md +11 -9
- package/templates/pi/src/agent.ts +16 -3
- package/templates/pi/src/lib/agent-sessions.ts +26 -4
- package/dist/agent-manager-SSJUZWOV.js +0 -13
- package/dist/connect-X5V5IMRW.js +0 -48
- package/dist/daemon-client-VN24HM5T.js +0 -10
- package/dist/disconnect-5JWFZ6RV.js +0 -30
- package/dist/fork-GRSVMBKI.js +0 -119
- package/dist/variants-QQIEKT6M.js +0 -60
- package/dist/web-assets/assets/index-DNNPoxMn.js +0 -158
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
deleteAgentUser
|
|
4
|
+
} from "./chunk-DEUAVGSA.js";
|
|
2
5
|
import {
|
|
3
6
|
parseArgs
|
|
4
7
|
} from "./chunk-D424ZQGI.js";
|
|
@@ -7,7 +10,8 @@ import {
|
|
|
7
10
|
findAgent,
|
|
8
11
|
removeAgent,
|
|
9
12
|
removeAllVariants
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-RALYNMHR.js";
|
|
14
|
+
import "./chunk-K3NQKI34.js";
|
|
11
15
|
|
|
12
16
|
// src/commands/delete.ts
|
|
13
17
|
import { existsSync, rmSync } from "fs";
|
|
@@ -26,7 +30,7 @@ async function run(args) {
|
|
|
26
30
|
process.exit(1);
|
|
27
31
|
}
|
|
28
32
|
try {
|
|
29
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
33
|
+
const { daemonFetch } = await import("./daemon-client-27KMQQKX.js");
|
|
30
34
|
const res = await daemonFetch(`/api/agents/${encodeURIComponent(name)}/stop`, {
|
|
31
35
|
method: "POST"
|
|
32
36
|
});
|
|
@@ -45,6 +49,7 @@ async function run(args) {
|
|
|
45
49
|
console.log("Use --force to also delete the agent directory.");
|
|
46
50
|
} else {
|
|
47
51
|
rmSync(dir, { recursive: true, force: true });
|
|
52
|
+
deleteAgentUser(name);
|
|
48
53
|
console.log(`Deleted ${dir}`);
|
|
49
54
|
}
|
|
50
55
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
voluteHome
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RALYNMHR.js";
|
|
5
|
+
import "./chunk-K3NQKI34.js";
|
|
5
6
|
|
|
6
7
|
// src/commands/down.ts
|
|
7
8
|
import { existsSync, readFileSync, unlinkSync } from "fs";
|
|
@@ -12,14 +13,20 @@ async function run(_args) {
|
|
|
12
13
|
if (!existsSync(pidPath)) {
|
|
13
14
|
const configPath = resolve(home, "daemon.json");
|
|
14
15
|
let port = 4200;
|
|
16
|
+
let hostname = "localhost";
|
|
15
17
|
if (existsSync(configPath)) {
|
|
16
18
|
try {
|
|
17
|
-
|
|
19
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
20
|
+
port = config.port ?? 4200;
|
|
21
|
+
hostname = config.hostname || "localhost";
|
|
18
22
|
} catch {
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
25
|
try {
|
|
22
|
-
const
|
|
26
|
+
const url = new URL("http://localhost");
|
|
27
|
+
url.hostname = hostname;
|
|
28
|
+
url.port = String(port);
|
|
29
|
+
const res = await fetch(`${url.origin}/api/health`);
|
|
23
30
|
if (res.ok) {
|
|
24
31
|
console.error(`Daemon appears to be running on port ${port} but PID file is missing.`);
|
|
25
32
|
console.error(`Kill the process manually: lsof -ti :${port} | xargs kill`);
|
|
@@ -5,13 +5,14 @@ import {
|
|
|
5
5
|
readEnv,
|
|
6
6
|
sharedEnvPath,
|
|
7
7
|
writeEnv
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-YEIHRP2J.js";
|
|
9
9
|
import {
|
|
10
10
|
parseArgs
|
|
11
11
|
} from "./chunk-D424ZQGI.js";
|
|
12
12
|
import {
|
|
13
13
|
resolveAgent
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-RALYNMHR.js";
|
|
15
|
+
import "./chunk-K3NQKI34.js";
|
|
15
16
|
|
|
16
17
|
// src/commands/env.ts
|
|
17
18
|
function getEnvPath(agentName) {
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
daemonFetch
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VVD3XO3E.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveAgentName
|
|
7
|
+
} from "./chunk-VRVVQIYY.js";
|
|
5
8
|
import {
|
|
6
9
|
parseArgs
|
|
7
10
|
} from "./chunk-D424ZQGI.js";
|
|
8
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-RALYNMHR.js";
|
|
12
|
+
import "./chunk-K3NQKI34.js";
|
|
9
13
|
|
|
10
14
|
// src/commands/history.ts
|
|
11
15
|
async function run(args) {
|
|
12
|
-
const {
|
|
16
|
+
const { flags } = parseArgs(args, {
|
|
17
|
+
agent: { type: "string" },
|
|
13
18
|
channel: { type: "string" },
|
|
14
19
|
limit: { type: "string" }
|
|
15
20
|
});
|
|
16
|
-
const name =
|
|
17
|
-
if (!name) {
|
|
18
|
-
console.error("Usage: volute history [<agent>] [--channel <ch>] [--limit N]");
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
+
const name = resolveAgentName(flags);
|
|
21
22
|
const params = new URLSearchParams();
|
|
22
23
|
if (flags.channel) params.set("channel", flags.channel);
|
|
23
24
|
if (flags.limit) params.set("limit", flags.limit);
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
readVoluteConfig,
|
|
4
|
+
writeVoluteConfig
|
|
5
|
+
} from "./chunk-NETNFBA5.js";
|
|
6
|
+
import {
|
|
7
|
+
agentEnvPath,
|
|
8
|
+
readEnv,
|
|
9
|
+
writeEnv
|
|
10
|
+
} from "./chunk-YEIHRP2J.js";
|
|
2
11
|
import {
|
|
3
12
|
composeTemplate,
|
|
4
13
|
copyTemplateToDir,
|
|
@@ -7,7 +16,7 @@ import {
|
|
|
7
16
|
import {
|
|
8
17
|
exec,
|
|
9
18
|
execInherit
|
|
10
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-5SKQ6J7T.js";
|
|
11
20
|
import {
|
|
12
21
|
parseArgs
|
|
13
22
|
} from "./chunk-D424ZQGI.js";
|
|
@@ -16,7 +25,8 @@ import {
|
|
|
16
25
|
agentDir,
|
|
17
26
|
ensureVoluteHome,
|
|
18
27
|
nextPort
|
|
19
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-RALYNMHR.js";
|
|
29
|
+
import "./chunk-K3NQKI34.js";
|
|
20
30
|
|
|
21
31
|
// src/commands/import.ts
|
|
22
32
|
import {
|
|
@@ -26,9 +36,11 @@ import {
|
|
|
26
36
|
readdirSync as readdirSync2,
|
|
27
37
|
readFileSync as readFileSync3,
|
|
28
38
|
rmSync,
|
|
39
|
+
statSync,
|
|
29
40
|
writeFileSync as writeFileSync3
|
|
30
41
|
} from "fs";
|
|
31
|
-
import {
|
|
42
|
+
import { homedir as homedir2 } from "os";
|
|
43
|
+
import { basename, resolve as resolve3 } from "path";
|
|
32
44
|
|
|
33
45
|
// src/lib/consolidate.ts
|
|
34
46
|
import { readdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -282,22 +294,9 @@ async function run(args) {
|
|
|
282
294
|
session: { type: "string" },
|
|
283
295
|
template: { type: "string" }
|
|
284
296
|
});
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
"Usage: volute import <openclaw-workspace-path> [--name <name>] [--session <session-jsonl-path>] [--template <name>]"
|
|
289
|
-
);
|
|
290
|
-
process.exit(1);
|
|
291
|
-
}
|
|
292
|
-
const wsDir = resolve3(workspacePath);
|
|
293
|
-
const soulPath = resolve3(wsDir, "SOUL.md");
|
|
294
|
-
const identityPath = resolve3(wsDir, "IDENTITY.md");
|
|
295
|
-
if (!existsSync(soulPath) || !existsSync(identityPath)) {
|
|
296
|
-
console.error("Not a valid OpenClaw workspace: missing SOUL.md or IDENTITY.md");
|
|
297
|
-
process.exit(1);
|
|
298
|
-
}
|
|
299
|
-
const soul = readFileSync3(soulPath, "utf-8");
|
|
300
|
-
const identity = readFileSync3(identityPath, "utf-8");
|
|
297
|
+
const wsDir = resolveWorkspace(positional[0]);
|
|
298
|
+
const soul = readFileSync3(resolve3(wsDir, "SOUL.md"), "utf-8");
|
|
299
|
+
const identity = readFileSync3(resolve3(wsDir, "IDENTITY.md"), "utf-8");
|
|
301
300
|
const userPath = resolve3(wsDir, "USER.md");
|
|
302
301
|
const user = existsSync(userPath) ? readFileSync3(userPath, "utf-8") : "";
|
|
303
302
|
const name = flags.name ?? parseNameFromIdentity(identity) ?? "imported-agent";
|
|
@@ -373,38 +372,146 @@ ${user.trimEnd()}
|
|
|
373
372
|
await exec("git", ["init"], { cwd: dest });
|
|
374
373
|
await exec("git", ["add", "-A"], { cwd: dest });
|
|
375
374
|
await exec("git", ["commit", "-m", "import from OpenClaw"], { cwd: dest });
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
"Warning: --session is only supported with the agent-sdk template, skipping session import"
|
|
379
|
-
);
|
|
380
|
-
}
|
|
381
|
-
if (flags.session && template === "agent-sdk") {
|
|
382
|
-
const sessionFile = resolve3(flags.session);
|
|
375
|
+
const sessionFile = flags.session ? resolve3(flags.session) : findOpenClawSession(wsDir);
|
|
376
|
+
if (sessionFile) {
|
|
383
377
|
if (!existsSync(sessionFile)) {
|
|
384
378
|
console.error(`Session file not found: ${sessionFile}`);
|
|
385
379
|
process.exit(1);
|
|
386
380
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
381
|
+
if (template === "pi") {
|
|
382
|
+
importPiSession(sessionFile, dest);
|
|
383
|
+
} else if (template === "agent-sdk") {
|
|
384
|
+
console.log("Converting session...");
|
|
385
|
+
const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
|
|
386
|
+
const voluteDir = resolve3(dest, ".volute");
|
|
387
|
+
mkdirSync2(voluteDir, { recursive: true });
|
|
388
|
+
writeFileSync3(resolve3(voluteDir, "session.json"), JSON.stringify({ sessionId }));
|
|
389
|
+
} else {
|
|
390
|
+
console.warn(`Session import not supported for template: ${template}`);
|
|
391
|
+
}
|
|
395
392
|
}
|
|
393
|
+
importOpenClawConnectors(dest);
|
|
396
394
|
console.log(`
|
|
397
395
|
Imported agent: ${name} (port ${port})`);
|
|
398
396
|
console.log(`
|
|
399
397
|
volute start ${name}`);
|
|
400
398
|
}
|
|
399
|
+
function resolveWorkspace(explicitPath) {
|
|
400
|
+
if (explicitPath) {
|
|
401
|
+
const wsDir = resolve3(explicitPath);
|
|
402
|
+
if (!existsSync(resolve3(wsDir, "SOUL.md")) || !existsSync(resolve3(wsDir, "IDENTITY.md"))) {
|
|
403
|
+
console.error("Not a valid OpenClaw workspace: missing SOUL.md or IDENTITY.md");
|
|
404
|
+
process.exit(1);
|
|
405
|
+
}
|
|
406
|
+
return wsDir;
|
|
407
|
+
}
|
|
408
|
+
const cwd = process.cwd();
|
|
409
|
+
if (existsSync(resolve3(cwd, "SOUL.md")) && existsSync(resolve3(cwd, "IDENTITY.md"))) {
|
|
410
|
+
console.log(`Using workspace: ${cwd}`);
|
|
411
|
+
return cwd;
|
|
412
|
+
}
|
|
413
|
+
const openclawWs = resolve3(homedir2(), ".openclaw/workspace");
|
|
414
|
+
if (existsSync(resolve3(openclawWs, "SOUL.md")) && existsSync(resolve3(openclawWs, "IDENTITY.md"))) {
|
|
415
|
+
console.log(`Using workspace: ${openclawWs}`);
|
|
416
|
+
return openclawWs;
|
|
417
|
+
}
|
|
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."
|
|
420
|
+
);
|
|
421
|
+
process.exit(1);
|
|
422
|
+
}
|
|
423
|
+
function findOpenClawSession(workspaceDir) {
|
|
424
|
+
const agentsDir = resolve3(homedir2(), ".openclaw/agents");
|
|
425
|
+
if (!existsSync(agentsDir)) return void 0;
|
|
426
|
+
const matches = [];
|
|
427
|
+
try {
|
|
428
|
+
for (const agent of readdirSync2(agentsDir)) {
|
|
429
|
+
const sessionsDir = resolve3(agentsDir, agent, "sessions");
|
|
430
|
+
if (!existsSync(sessionsDir)) continue;
|
|
431
|
+
for (const file of readdirSync2(sessionsDir)) {
|
|
432
|
+
if (!file.endsWith(".jsonl")) continue;
|
|
433
|
+
const fullPath = resolve3(sessionsDir, file);
|
|
434
|
+
if (sessionMatchesWorkspace(fullPath, workspaceDir)) {
|
|
435
|
+
matches.push({ path: fullPath, mtime: statSync(fullPath).mtimeMs });
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
} catch (err) {
|
|
440
|
+
console.warn("Warning: error scanning OpenClaw sessions:", err);
|
|
441
|
+
return void 0;
|
|
442
|
+
}
|
|
443
|
+
if (matches.length === 0) return void 0;
|
|
444
|
+
matches.sort((a, b) => b.mtime - a.mtime);
|
|
445
|
+
console.log(`Found session: ${matches[0].path}`);
|
|
446
|
+
return matches[0].path;
|
|
447
|
+
}
|
|
448
|
+
function sessionMatchesWorkspace(sessionPath, workspaceDir) {
|
|
449
|
+
try {
|
|
450
|
+
const fd = readFileSync3(sessionPath, "utf-8");
|
|
451
|
+
const firstLine = fd.slice(0, fd.indexOf("\n"));
|
|
452
|
+
const header = JSON.parse(firstLine);
|
|
453
|
+
return header.type === "session" && resolve3(header.cwd) === resolve3(workspaceDir);
|
|
454
|
+
} catch {
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function importPiSession(sessionFile, agentDirPath) {
|
|
459
|
+
const homeDir = resolve3(agentDirPath, "home");
|
|
460
|
+
const piSessionDir = resolve3(agentDirPath, ".volute/pi-sessions/main");
|
|
461
|
+
mkdirSync2(piSessionDir, { recursive: true });
|
|
462
|
+
const content = readFileSync3(sessionFile, "utf-8");
|
|
463
|
+
const lines = content.trim().split("\n");
|
|
464
|
+
try {
|
|
465
|
+
const header = JSON.parse(lines[0]);
|
|
466
|
+
if (header.type === "session") {
|
|
467
|
+
header.cwd = homeDir;
|
|
468
|
+
lines[0] = JSON.stringify(header);
|
|
469
|
+
}
|
|
470
|
+
} catch {
|
|
471
|
+
}
|
|
472
|
+
const filename = basename(sessionFile);
|
|
473
|
+
const destPath = resolve3(piSessionDir, filename);
|
|
474
|
+
writeFileSync3(destPath, `${lines.join("\n")}
|
|
475
|
+
`);
|
|
476
|
+
console.log(`Imported session (${lines.length} entries)`);
|
|
477
|
+
}
|
|
478
|
+
function importOpenClawConnectors(agentDirPath) {
|
|
479
|
+
const configPath = resolve3(homedir2(), ".openclaw/openclaw.json");
|
|
480
|
+
if (!existsSync(configPath)) return;
|
|
481
|
+
let config;
|
|
482
|
+
try {
|
|
483
|
+
config = JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
484
|
+
} catch (err) {
|
|
485
|
+
console.warn("Warning: failed to parse openclaw.json:", err);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
const discord = config.channels?.discord;
|
|
489
|
+
if (!discord?.enabled || !discord.token) return;
|
|
490
|
+
const envPath = agentEnvPath(agentDirPath);
|
|
491
|
+
const env = readEnv(envPath);
|
|
492
|
+
env.DISCORD_TOKEN = discord.token;
|
|
493
|
+
writeEnv(envPath, env);
|
|
494
|
+
const voluteConfig = readVoluteConfig(agentDirPath) ?? {};
|
|
495
|
+
const connectors = new Set(voluteConfig.connectors ?? []);
|
|
496
|
+
connectors.add("discord");
|
|
497
|
+
voluteConfig.connectors = [...connectors];
|
|
498
|
+
writeVoluteConfig(agentDirPath, voluteConfig);
|
|
499
|
+
console.log("Imported Discord connector config");
|
|
500
|
+
}
|
|
401
501
|
function parseNameFromIdentity(identity) {
|
|
402
502
|
const match = identity.match(/\*\*Name:\*\*\s*(.+)/);
|
|
403
503
|
if (match) {
|
|
404
|
-
|
|
504
|
+
const raw = match[1].trim();
|
|
505
|
+
if (!raw || raw.startsWith("*") || raw.startsWith("(")) return void 0;
|
|
506
|
+
return raw.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9.-]/g, "");
|
|
405
507
|
}
|
|
406
508
|
return void 0;
|
|
407
509
|
}
|
|
408
510
|
export {
|
|
409
|
-
|
|
511
|
+
findOpenClawSession,
|
|
512
|
+
importOpenClawConnectors,
|
|
513
|
+
importPiSession,
|
|
514
|
+
parseNameFromIdentity,
|
|
515
|
+
run,
|
|
516
|
+
sessionMatchesWorkspace
|
|
410
517
|
};
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveAgentName
|
|
4
|
+
} from "./chunk-VRVVQIYY.js";
|
|
2
5
|
import {
|
|
3
6
|
parseArgs
|
|
4
7
|
} from "./chunk-D424ZQGI.js";
|
|
5
8
|
import {
|
|
6
9
|
resolveAgent
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RALYNMHR.js";
|
|
11
|
+
import "./chunk-K3NQKI34.js";
|
|
8
12
|
|
|
9
13
|
// src/commands/logs.ts
|
|
10
14
|
import { spawn } from "child_process";
|
|
11
15
|
import { existsSync } from "fs";
|
|
12
16
|
import { resolve } from "path";
|
|
13
17
|
async function run(args) {
|
|
14
|
-
const {
|
|
18
|
+
const { flags } = parseArgs(args, {
|
|
19
|
+
agent: { type: "string" },
|
|
15
20
|
follow: { type: "boolean" },
|
|
16
21
|
n: { type: "number" }
|
|
17
22
|
});
|
|
18
|
-
const name =
|
|
19
|
-
if (!name) {
|
|
20
|
-
console.error("Usage: volute logs <name> [--follow] [-n N]");
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
+
const name = resolveAgentName(flags);
|
|
23
24
|
const { dir } = resolveAgent(name);
|
|
24
25
|
const logFile = resolve(dir, ".volute", "logs", "agent.log");
|
|
25
26
|
if (!existsSync(logFile)) {
|
|
@@ -1,39 +1,45 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
daemonFetch
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import
|
|
4
|
+
} from "./chunk-VVD3XO3E.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveAgentName
|
|
7
|
+
} from "./chunk-VRVVQIYY.js";
|
|
8
|
+
import {
|
|
9
|
+
parseArgs
|
|
10
|
+
} from "./chunk-D424ZQGI.js";
|
|
11
|
+
import "./chunk-RALYNMHR.js";
|
|
12
|
+
import "./chunk-K3NQKI34.js";
|
|
6
13
|
|
|
7
14
|
// src/commands/schedule.ts
|
|
8
15
|
async function run(args) {
|
|
9
16
|
const subcommand = args[0];
|
|
10
|
-
const agentName = args[1];
|
|
11
|
-
if (!subcommand || !agentName) {
|
|
12
|
-
printUsage();
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
17
|
switch (subcommand) {
|
|
16
18
|
case "list":
|
|
17
|
-
await listSchedules(
|
|
19
|
+
await listSchedules(args.slice(1));
|
|
18
20
|
break;
|
|
19
21
|
case "add":
|
|
20
|
-
await addSchedule(
|
|
22
|
+
await addSchedule(args.slice(1));
|
|
21
23
|
break;
|
|
22
24
|
case "remove":
|
|
23
|
-
await removeSchedule(
|
|
25
|
+
await removeSchedule(args.slice(1));
|
|
24
26
|
break;
|
|
25
27
|
default:
|
|
26
28
|
printUsage();
|
|
27
|
-
process.exit(1);
|
|
29
|
+
process.exit(subcommand ? 1 : 0);
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
32
|
function printUsage() {
|
|
31
33
|
console.error(`Usage:
|
|
32
|
-
volute schedule list <
|
|
33
|
-
volute schedule add <
|
|
34
|
-
volute schedule remove <
|
|
34
|
+
volute schedule list [--agent <name>]
|
|
35
|
+
volute schedule add [--agent <name>] --cron "..." --message "..." [--id name]
|
|
36
|
+
volute schedule remove [--agent <name>] --id <id>`);
|
|
35
37
|
}
|
|
36
|
-
async function listSchedules(
|
|
38
|
+
async function listSchedules(args) {
|
|
39
|
+
const { flags } = parseArgs(args, {
|
|
40
|
+
agent: { type: "string" }
|
|
41
|
+
});
|
|
42
|
+
const agent = resolveAgentName(flags);
|
|
37
43
|
const res = await daemonFetch(`/api/agents/${encodeURIComponent(agent)}/schedules`);
|
|
38
44
|
if (!res.ok) {
|
|
39
45
|
const data = await res.json();
|
|
@@ -54,25 +60,20 @@ async function listSchedules(agent) {
|
|
|
54
60
|
);
|
|
55
61
|
}
|
|
56
62
|
}
|
|
57
|
-
async function addSchedule(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} else if (args[i] === "--id" && args[i + 1]) {
|
|
67
|
-
id = args[++i];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
if (!cron || !message) {
|
|
63
|
+
async function addSchedule(args) {
|
|
64
|
+
const { flags } = parseArgs(args, {
|
|
65
|
+
agent: { type: "string" },
|
|
66
|
+
cron: { type: "string" },
|
|
67
|
+
message: { type: "string" },
|
|
68
|
+
id: { type: "string" }
|
|
69
|
+
});
|
|
70
|
+
const agent = resolveAgentName(flags);
|
|
71
|
+
if (!flags.cron || !flags.message) {
|
|
71
72
|
console.error("--cron and --message are required");
|
|
72
73
|
process.exit(1);
|
|
73
74
|
}
|
|
74
|
-
const body = { cron, message };
|
|
75
|
-
if (id) body.id = id;
|
|
75
|
+
const body = { cron: flags.cron, message: flags.message };
|
|
76
|
+
if (flags.id) body.id = flags.id;
|
|
76
77
|
const res = await daemonFetch(`/api/agents/${encodeURIComponent(agent)}/schedules`, {
|
|
77
78
|
method: "POST",
|
|
78
79
|
headers: { "Content-Type": "application/json" },
|
|
@@ -86,19 +87,18 @@ async function addSchedule(agent, args) {
|
|
|
86
87
|
const data = await res.json();
|
|
87
88
|
console.log(`Schedule added: ${data.id}`);
|
|
88
89
|
}
|
|
89
|
-
async function removeSchedule(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (!id) {
|
|
90
|
+
async function removeSchedule(args) {
|
|
91
|
+
const { flags } = parseArgs(args, {
|
|
92
|
+
agent: { type: "string" },
|
|
93
|
+
id: { type: "string" }
|
|
94
|
+
});
|
|
95
|
+
const agent = resolveAgentName(flags);
|
|
96
|
+
if (!flags.id) {
|
|
97
97
|
console.error("--id is required");
|
|
98
98
|
process.exit(1);
|
|
99
99
|
}
|
|
100
100
|
const res = await daemonFetch(
|
|
101
|
-
`/api/agents/${encodeURIComponent(agent)}/schedules/${encodeURIComponent(id)}`,
|
|
101
|
+
`/api/agents/${encodeURIComponent(agent)}/schedules/${encodeURIComponent(flags.id)}`,
|
|
102
102
|
{ method: "DELETE" }
|
|
103
103
|
);
|
|
104
104
|
if (!res.ok) {
|
|
@@ -106,7 +106,7 @@ async function removeSchedule(agent, args) {
|
|
|
106
106
|
console.error(data.error ?? `Failed to remove schedule: ${res.status}`);
|
|
107
107
|
process.exit(1);
|
|
108
108
|
}
|
|
109
|
-
console.log(`Schedule removed: ${id}`);
|
|
109
|
+
console.log(`Schedule removed: ${flags.id}`);
|
|
110
110
|
}
|
|
111
111
|
export {
|
|
112
112
|
run
|
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
} from "./chunk-N4YNKR3Q.js";
|
|
5
5
|
import {
|
|
6
6
|
daemonFetch
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-VVD3XO3E.js";
|
|
8
|
+
import "./chunk-RALYNMHR.js";
|
|
9
|
+
import "./chunk-K3NQKI34.js";
|
|
9
10
|
|
|
10
11
|
// src/commands/send.ts
|
|
11
12
|
import { userInfo } from "os";
|