volute 0.13.2 → 0.14.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/{channel-JZJJRRWT.js → channel-SLURLIRV.js} +28 -28
- package/dist/{chunk-KRJ6KCBI.js → chunk-2Y77MCFG.js} +3 -3
- package/dist/{chunk-AA5TDLXB.js → chunk-3FC42ZBM.js} +24 -24
- package/dist/{chunk-YYUSXARD.js → chunk-6BDNWYKG.js} +2 -2
- package/dist/{chunk-KN4WBLH2.js → chunk-GR3OG4QK.js} +2 -2
- package/dist/{chunk-FE5O5RSL.js → chunk-GSPWIM5E.js} +25 -25
- package/dist/{chunk-QRRXD2V7.js → chunk-J52CJCVI.js} +71 -69
- package/dist/{chunk-LGSW7T7K.js → chunk-M77QBTEH.js} +60 -57
- package/dist/{chunk-KXOFPDO6.js → chunk-MVSXRMJJ.js} +1 -1
- package/dist/chunk-NAOW2CLO.js +15 -0
- package/dist/{chunk-VQIJUR43.js → chunk-OJQ47SCA.js} +1 -1
- package/dist/{chunk-O4BN3ZIY.js → chunk-OYSZNX5I.js} +7 -7
- package/dist/{chunk-AOSGW3MX.js → chunk-PDLAZJGC.js} +28 -28
- package/dist/{chunk-XUA3JUFK.js → chunk-PO5Q2AYN.js} +2 -2
- package/dist/{chunk-6BQHEIDO.js → chunk-QJIIHU32.js} +2 -2
- package/dist/{chunk-NXT67PPK.js → chunk-ZCEYUUID.js} +19 -19
- package/dist/cli.js +42 -42
- package/dist/{connector-WFT5KK67.js → connector-JFAHYFQX.js} +21 -21
- package/dist/connectors/discord.js +7 -7
- package/dist/connectors/slack.js +7 -7
- package/dist/connectors/telegram.js +9 -9
- package/dist/{create-HT47ZH5T.js → create-ZWHCRT5F.js} +7 -7
- package/dist/{daemon-client-DEF7IFEJ.js → daemon-client-ODKDUYDE.js} +2 -2
- package/dist/{daemon-restart-P3FEE3QJ.js → daemon-restart-KNJHZ7FP.js} +6 -6
- package/dist/daemon.js +2281 -1998
- package/dist/{delete-YG3RVURA.js → delete-6G6WEX4F.js} +8 -8
- package/dist/down-A56B5JLK.js +14 -0
- package/dist/{env-BQYYF4YL.js → env-6LXDUZDA.js} +25 -25
- package/dist/{history-I4KIKIUX.js → history-LKCJJMUV.js} +7 -7
- package/dist/{import-UHCK6PRC.js → import-EDGRLIGO.js} +3 -3
- package/dist/{logs-2DWFES6A.js → logs-GYOR3L2L.js} +8 -8
- package/dist/mind-OJN6RBZW.js +79 -0
- package/dist/mind-manager-PN5SUDJ4.js +15 -0
- package/dist/{package-MMTPOMUN.js → package-EYUA3AMC.js} +4 -4
- package/dist/{restart-6PE3GWYZ.js → restart-YFAWFS5T.js} +9 -9
- package/dist/{schedule-5AYTQM3N.js → schedule-AGYLDMNS.js} +17 -17
- package/dist/{seed-3QQVFMBU.js → seed-AP4Q7RZ7.js} +9 -9
- package/dist/{send-FPFW7J5Q.js → send-SV4K2TDE.js} +32 -24
- package/dist/{service-5X5EKPVM.js → service-U7MZ2H7F.js} +4 -4
- package/dist/{setup-5NXV25ZS.js → setup-DJKIZKGW.js} +21 -16
- package/dist/{sprout-VOUJ4Y3I.js → sprout-2V3MWONK.js} +18 -18
- package/dist/{start-ICPSQ2ZK.js → start-3YYRXBKP.js} +7 -7
- package/dist/{status-JBT7ENQN.js → status-VSFZYX7S.js} +14 -14
- package/dist/{stop-IXJGAG4T.js → stop-AA5K5LYG.js} +9 -9
- package/dist/{up-ROC7LJ7G.js → up-SUZ6C5PY.js} +5 -5
- package/dist/{update-GU6JYDSN.js → update-YAGN5ODG.js} +5 -5
- package/dist/{update-check-MUPZYTW4.js → update-check-APLTH4IN.js} +2 -2
- package/dist/{upgrade-275LKIEG.js → upgrade-KXZCQSZN.js} +8 -10
- package/dist/{variant-RE45F2IY.js → variant-X5QFG6KK.js} +30 -30
- package/dist/web-assets/assets/index-CeFLp8DZ.js +307 -0
- package/dist/web-assets/index.html +1 -1
- package/drizzle/0005_rename_agents_to_minds.sql +11 -0
- package/drizzle/meta/0005_snapshot.json +410 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +4 -4
- package/templates/_base/.init/.config/scripts/session-reader.ts +1 -1
- package/templates/_base/.init/SOUL.md +1 -1
- package/templates/_base/_skills/memory/SKILL.md +1 -1
- package/templates/_base/_skills/orientation/SKILL.md +6 -6
- package/templates/_base/_skills/sessions/SKILL.md +1 -1
- package/templates/_base/_skills/{volute-agent → volute-mind}/SKILL.md +21 -21
- package/templates/_base/home/VOLUTE.md +7 -7
- package/templates/_base/src/lib/auto-commit.ts +1 -1
- package/templates/_base/src/lib/auto-reply.ts +1 -1
- package/templates/_base/src/lib/daemon-client.ts +8 -8
- package/templates/_base/src/lib/router.ts +6 -6
- package/templates/_base/src/lib/routing.ts +9 -6
- package/templates/_base/src/lib/startup.ts +1 -1
- package/templates/_base/src/lib/volute-server.ts +1 -1
- package/templates/{agent-sdk → claude}/.init/CLAUDE.md +3 -3
- package/templates/{agent-sdk → claude}/src/agent.ts +10 -10
- package/templates/{agent-sdk → claude}/src/lib/hooks/pre-compact.ts +2 -2
- package/templates/{agent-sdk → claude}/src/lib/session-store.ts +2 -2
- package/templates/{agent-sdk → claude}/src/lib/stream-consumer.ts +1 -1
- package/templates/{agent-sdk → claude}/src/server.ts +4 -4
- package/templates/pi/.init/{AGENTS.md → MINDS.md} +3 -3
- package/templates/pi/home/.config/config.json.tmpl +1 -1
- package/templates/pi/src/agent.ts +12 -12
- package/templates/pi/src/lib/event-handler.ts +39 -4
- package/templates/pi/src/server.ts +3 -3
- package/dist/agent-IUSETOXJ.js +0 -79
- package/dist/agent-manager-4O4AC2S6.js +0 -15
- package/dist/chunk-AZEL2IEK.js +0 -15
- package/dist/down-36YCOZ7V.js +0 -14
- package/dist/web-assets/assets/index-TqXd1QOX.js +0 -307
- /package/templates/{agent-sdk → claude}/.init/.claude/settings.json +0 -0
- /package/templates/{agent-sdk → claude}/.init/.config/routes.json +0 -0
- /package/templates/{agent-sdk → claude}/package.json.tmpl +0 -0
- /package/templates/{agent-sdk → claude}/src/lib/content.ts +0 -0
- /package/templates/{agent-sdk → claude}/src/lib/hooks/auto-commit.ts +0 -0
- /package/templates/{agent-sdk → claude}/src/lib/hooks/identity-reload.ts +0 -0
- /package/templates/{agent-sdk → claude}/src/lib/hooks/session-context.ts +0 -0
- /package/templates/{agent-sdk → claude}/src/lib/message-channel.ts +0 -0
- /package/templates/{agent-sdk → claude}/volute-template.json +0 -0
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
slugify,
|
|
6
6
|
splitMessage,
|
|
7
7
|
writeChannelEntry
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3FC42ZBM.js";
|
|
9
9
|
import {
|
|
10
10
|
voluteHome
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-M77QBTEH.js";
|
|
12
12
|
import {
|
|
13
13
|
__export
|
|
14
14
|
} from "./chunk-K3NQKI34.js";
|
|
@@ -141,9 +141,9 @@ async function createConversation(env, participants, _name) {
|
|
|
141
141
|
}
|
|
142
142
|
const dm = await res.json();
|
|
143
143
|
const slug = `discord:@${slugify(participants[0])}`;
|
|
144
|
-
const
|
|
145
|
-
if (
|
|
146
|
-
writeChannelEntry(
|
|
144
|
+
const mindName = env.VOLUTE_MIND;
|
|
145
|
+
if (mindName) {
|
|
146
|
+
writeChannelEntry(mindName, slug, {
|
|
147
147
|
platformId: dm.id,
|
|
148
148
|
platform: "discord",
|
|
149
149
|
name: participants[0],
|
|
@@ -272,7 +272,7 @@ async function createConversation2(env, participants, name) {
|
|
|
272
272
|
if (!user) throw new Error(`User not found: ${p}`);
|
|
273
273
|
ids.push(user.id);
|
|
274
274
|
}
|
|
275
|
-
const
|
|
275
|
+
const mindName = env.VOLUTE_MIND;
|
|
276
276
|
if (name) {
|
|
277
277
|
const createData = await slackApi(token, "conversations.create", {
|
|
278
278
|
name,
|
|
@@ -288,8 +288,8 @@ async function createConversation2(env, participants, name) {
|
|
|
288
288
|
const authData = await slackApi(token, "auth.test", {});
|
|
289
289
|
const teamName = authData.team ?? "workspace";
|
|
290
290
|
const slug2 = `slack:${slugify(teamName)}/${slugify(name)}`;
|
|
291
|
-
if (
|
|
292
|
-
writeChannelEntry(
|
|
291
|
+
if (mindName) {
|
|
292
|
+
writeChannelEntry(mindName, slug2, {
|
|
293
293
|
platformId: channelId,
|
|
294
294
|
platform: "slack",
|
|
295
295
|
name,
|
|
@@ -303,8 +303,8 @@ async function createConversation2(env, participants, name) {
|
|
|
303
303
|
});
|
|
304
304
|
const platformId = openData.channel.id;
|
|
305
305
|
const slug = participants.length === 1 ? `slack:@${slugify(participants[0])}` : `slack:@${participants.map(slugify).sort().join(",")}`;
|
|
306
|
-
if (
|
|
307
|
-
writeChannelEntry(
|
|
306
|
+
if (mindName) {
|
|
307
|
+
writeChannelEntry(mindName, slug, {
|
|
308
308
|
platformId,
|
|
309
309
|
platform: "slack",
|
|
310
310
|
name: participants.join(", "),
|
|
@@ -399,14 +399,14 @@ function getDaemonConfig() {
|
|
|
399
399
|
return { url: url.origin, token: config.token };
|
|
400
400
|
}
|
|
401
401
|
async function read4(env, channelSlug, limit) {
|
|
402
|
-
const
|
|
403
|
-
if (!
|
|
402
|
+
const mindName = env.VOLUTE_MIND;
|
|
403
|
+
if (!mindName) throw new Error("VOLUTE_MIND not set");
|
|
404
404
|
const conversationId = resolveChannelId2(env, channelSlug);
|
|
405
405
|
const { url, token } = getDaemonConfig();
|
|
406
406
|
const headers = { Origin: url };
|
|
407
407
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
408
408
|
const res = await fetch(
|
|
409
|
-
`${url}/api/
|
|
409
|
+
`${url}/api/minds/${encodeURIComponent(mindName)}/conversations/${encodeURIComponent(conversationId)}/messages`,
|
|
410
410
|
{ headers }
|
|
411
411
|
);
|
|
412
412
|
if (!res.ok) {
|
|
@@ -419,8 +419,8 @@ async function read4(env, channelSlug, limit) {
|
|
|
419
419
|
}).join("\n");
|
|
420
420
|
}
|
|
421
421
|
async function send4(env, channelSlug, message) {
|
|
422
|
-
const
|
|
423
|
-
if (!
|
|
422
|
+
const mindName = env.VOLUTE_MIND;
|
|
423
|
+
if (!mindName) throw new Error("VOLUTE_MIND not set");
|
|
424
424
|
const conversationId = resolveChannelId2(env, channelSlug);
|
|
425
425
|
const { url, token } = getDaemonConfig();
|
|
426
426
|
const headers = {
|
|
@@ -428,10 +428,10 @@ async function send4(env, channelSlug, message) {
|
|
|
428
428
|
Origin: url
|
|
429
429
|
};
|
|
430
430
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
431
|
-
const res = await fetch(`${url}/api/
|
|
431
|
+
const res = await fetch(`${url}/api/minds/${encodeURIComponent(mindName)}/chat`, {
|
|
432
432
|
method: "POST",
|
|
433
433
|
headers,
|
|
434
|
-
body: JSON.stringify({ message, conversationId, sender: env.VOLUTE_SENDER ??
|
|
434
|
+
body: JSON.stringify({ message, conversationId, sender: env.VOLUTE_SENDER ?? mindName })
|
|
435
435
|
});
|
|
436
436
|
if (!res.ok) {
|
|
437
437
|
const data = await res.json().catch(() => ({}));
|
|
@@ -439,12 +439,12 @@ async function send4(env, channelSlug, message) {
|
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
441
|
async function listConversations4(env) {
|
|
442
|
-
const
|
|
443
|
-
if (!
|
|
442
|
+
const mindName = env.VOLUTE_MIND;
|
|
443
|
+
if (!mindName) throw new Error("VOLUTE_MIND not set");
|
|
444
444
|
const { url, token } = getDaemonConfig();
|
|
445
445
|
const headers = { Origin: url };
|
|
446
446
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
447
|
-
const res = await fetch(`${url}/api/
|
|
447
|
+
const res = await fetch(`${url}/api/minds/${encodeURIComponent(mindName)}/conversations`, {
|
|
448
448
|
headers
|
|
449
449
|
});
|
|
450
450
|
if (!res.ok) {
|
|
@@ -456,7 +456,7 @@ async function listConversations4(env) {
|
|
|
456
456
|
let participants = [];
|
|
457
457
|
try {
|
|
458
458
|
const pRes = await fetch(
|
|
459
|
-
`${url}/api/
|
|
459
|
+
`${url}/api/minds/${encodeURIComponent(mindName)}/conversations/${encodeURIComponent(conv.id)}/participants`,
|
|
460
460
|
{ headers }
|
|
461
461
|
);
|
|
462
462
|
if (pRes.ok) {
|
|
@@ -470,7 +470,7 @@ async function listConversations4(env) {
|
|
|
470
470
|
const isDM = participants.length === 2;
|
|
471
471
|
const slug = buildVoluteSlug({
|
|
472
472
|
participants,
|
|
473
|
-
|
|
473
|
+
mindUsername: mindName,
|
|
474
474
|
convTitle: conv.title,
|
|
475
475
|
conversationId: conv.id
|
|
476
476
|
});
|
|
@@ -500,15 +500,15 @@ async function listUsers4(_env) {
|
|
|
500
500
|
}));
|
|
501
501
|
}
|
|
502
502
|
async function createConversation4(env, participants, name) {
|
|
503
|
-
const
|
|
504
|
-
if (!
|
|
503
|
+
const mindName = env.VOLUTE_MIND;
|
|
504
|
+
if (!mindName) throw new Error("VOLUTE_MIND not set");
|
|
505
505
|
const { url, token } = getDaemonConfig();
|
|
506
506
|
const headers = {
|
|
507
507
|
"Content-Type": "application/json",
|
|
508
508
|
Origin: url
|
|
509
509
|
};
|
|
510
510
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
511
|
-
const res = await fetch(`${url}/api/
|
|
511
|
+
const res = await fetch(`${url}/api/minds/${encodeURIComponent(mindName)}/conversations`, {
|
|
512
512
|
method: "POST",
|
|
513
513
|
headers,
|
|
514
514
|
body: JSON.stringify({ participantNames: participants, title: name })
|
|
@@ -554,12 +554,12 @@ function getChannelDriver(platform) {
|
|
|
554
554
|
return CHANNELS[platform]?.driver ?? null;
|
|
555
555
|
}
|
|
556
556
|
function resolveChannelId2(env, slug) {
|
|
557
|
-
const
|
|
558
|
-
if (!
|
|
557
|
+
const mindName = env.VOLUTE_MIND;
|
|
558
|
+
if (!mindName) {
|
|
559
559
|
const colonIdx = slug.indexOf(":");
|
|
560
560
|
return colonIdx !== -1 ? slug.slice(colonIdx + 1) : slug;
|
|
561
561
|
}
|
|
562
|
-
return resolveChannelId(
|
|
562
|
+
return resolveChannelId(mindName, slug);
|
|
563
563
|
}
|
|
564
564
|
|
|
565
565
|
export {
|
|
@@ -64,7 +64,7 @@ function composeTemplate(templatesRoot, templateName) {
|
|
|
64
64
|
rmSync(manifestPath);
|
|
65
65
|
return { composedDir, manifest };
|
|
66
66
|
}
|
|
67
|
-
function copyTemplateToDir(composedDir, destDir,
|
|
67
|
+
function copyTemplateToDir(composedDir, destDir, mindName, manifest) {
|
|
68
68
|
cpSync(composedDir, destDir, { recursive: true });
|
|
69
69
|
for (const [from, to] of Object.entries(manifest.rename)) {
|
|
70
70
|
const fromPath = resolve(destDir, from);
|
|
@@ -76,7 +76,7 @@ function copyTemplateToDir(composedDir, destDir, agentName, manifest) {
|
|
|
76
76
|
const path = resolve(destDir, file);
|
|
77
77
|
if (existsSync(path)) {
|
|
78
78
|
const content = readFileSync(path, "utf-8");
|
|
79
|
-
writeFileSync(path, content.replaceAll("{{name}}",
|
|
79
|
+
writeFileSync(path, content.replaceAll("{{name}}", mindName));
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
}
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
pollHealthDown,
|
|
6
6
|
readDaemonConfig,
|
|
7
7
|
stopService
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6BDNWYKG.js";
|
|
9
9
|
import {
|
|
10
10
|
voluteHome
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-M77QBTEH.js";
|
|
12
12
|
|
|
13
13
|
// src/commands/down.ts
|
|
14
14
|
import { existsSync, readFileSync, unlinkSync } from "fs";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
validateMindName
|
|
4
|
+
} from "./chunk-M77QBTEH.js";
|
|
5
5
|
|
|
6
6
|
// src/lib/isolation.ts
|
|
7
7
|
import { execFileSync } from "child_process";
|
|
8
8
|
function isIsolationEnabled() {
|
|
9
9
|
return process.env.VOLUTE_ISOLATION === "user";
|
|
10
10
|
}
|
|
11
|
-
function
|
|
12
|
-
const err =
|
|
13
|
-
if (err) throw new Error(`Invalid
|
|
14
|
-
const prefix = process.env.VOLUTE_USER_PREFIX ?? "
|
|
15
|
-
return `${prefix}${
|
|
11
|
+
function mindUserName(mindName) {
|
|
12
|
+
const err = validateMindName(mindName);
|
|
13
|
+
if (err) throw new Error(`Invalid mind name for isolation: ${err}`);
|
|
14
|
+
const prefix = process.env.VOLUTE_USER_PREFIX ?? "mind-";
|
|
15
|
+
return `${prefix}${mindName}`;
|
|
16
16
|
}
|
|
17
17
|
function ensureVoluteGroup(opts) {
|
|
18
18
|
if (!opts?.force && !isIsolationEnabled()) return;
|
|
@@ -27,9 +27,9 @@ function ensureVoluteGroup(opts) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
function
|
|
30
|
+
function createMindUser(name, homeDir) {
|
|
31
31
|
if (!isIsolationEnabled()) return;
|
|
32
|
-
const user =
|
|
32
|
+
const user = mindUserName(name);
|
|
33
33
|
try {
|
|
34
34
|
execFileSync("id", [user], { stdio: "ignore" });
|
|
35
35
|
return;
|
|
@@ -47,23 +47,23 @@ function createAgentUser(name, homeDir) {
|
|
|
47
47
|
throw new Error(`Failed to create user ${user}${stderr ? `: ${stderr}` : ""}`);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
function
|
|
50
|
+
function deleteMindUser(name) {
|
|
51
51
|
if (!isIsolationEnabled()) return;
|
|
52
|
-
const user =
|
|
52
|
+
const user = mindUserName(name);
|
|
53
53
|
try {
|
|
54
54
|
execFileSync("userdel", [user], { stdio: "ignore" });
|
|
55
55
|
} catch {
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
-
function wrapForIsolation(cmd, args,
|
|
58
|
+
function wrapForIsolation(cmd, args, mindName) {
|
|
59
59
|
if (!isIsolationEnabled()) return [cmd, args];
|
|
60
|
-
const baseName =
|
|
61
|
-
const user =
|
|
60
|
+
const baseName = mindName.split("@", 2)[0];
|
|
61
|
+
const user = mindUserName(baseName);
|
|
62
62
|
return ["runuser", ["-u", user, "--", cmd, ...args]];
|
|
63
63
|
}
|
|
64
|
-
function
|
|
64
|
+
function chownMindDir(dir, name) {
|
|
65
65
|
if (!isIsolationEnabled()) return;
|
|
66
|
-
const user =
|
|
66
|
+
const user = mindUserName(name);
|
|
67
67
|
try {
|
|
68
68
|
execFileSync("chown", ["-R", `${user}:${user}`, dir], { stdio: ["ignore", "ignore", "pipe"] });
|
|
69
69
|
} catch (err) {
|
|
@@ -81,8 +81,8 @@ function chownAgentDir(dir, name) {
|
|
|
81
81
|
export {
|
|
82
82
|
isIsolationEnabled,
|
|
83
83
|
ensureVoluteGroup,
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
createMindUser,
|
|
85
|
+
deleteMindUser,
|
|
86
86
|
wrapForIsolation,
|
|
87
|
-
|
|
87
|
+
chownMindDir
|
|
88
88
|
};
|
package/dist/cli.js
CHANGED
|
@@ -9,96 +9,96 @@ 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-EYUA3AMC.js");
|
|
13
13
|
console.log(pkg.version);
|
|
14
14
|
process.exit(0);
|
|
15
15
|
}
|
|
16
16
|
switch (command) {
|
|
17
|
-
case "
|
|
18
|
-
await import("./
|
|
17
|
+
case "mind":
|
|
18
|
+
await import("./mind-OJN6RBZW.js").then((m) => m.run(args));
|
|
19
19
|
break;
|
|
20
20
|
case "send":
|
|
21
|
-
await import("./send-
|
|
21
|
+
await import("./send-SV4K2TDE.js").then((m) => m.run(args));
|
|
22
22
|
break;
|
|
23
23
|
case "history":
|
|
24
|
-
await import("./history-
|
|
24
|
+
await import("./history-LKCJJMUV.js").then((m) => m.run(args));
|
|
25
25
|
break;
|
|
26
26
|
case "variant":
|
|
27
|
-
await import("./variant-
|
|
27
|
+
await import("./variant-X5QFG6KK.js").then((m) => m.run(args));
|
|
28
28
|
break;
|
|
29
29
|
case "connector":
|
|
30
|
-
await import("./connector-
|
|
30
|
+
await import("./connector-JFAHYFQX.js").then((m) => m.run(args));
|
|
31
31
|
break;
|
|
32
32
|
case "channel":
|
|
33
|
-
await import("./channel-
|
|
33
|
+
await import("./channel-SLURLIRV.js").then((m) => m.run(args));
|
|
34
34
|
break;
|
|
35
35
|
case "schedule":
|
|
36
|
-
await import("./schedule-
|
|
36
|
+
await import("./schedule-AGYLDMNS.js").then((m) => m.run(args));
|
|
37
37
|
break;
|
|
38
38
|
case "env":
|
|
39
|
-
await import("./env-
|
|
39
|
+
await import("./env-6LXDUZDA.js").then((m) => m.run(args));
|
|
40
40
|
break;
|
|
41
41
|
case "up":
|
|
42
|
-
await import("./up-
|
|
42
|
+
await import("./up-SUZ6C5PY.js").then((m) => m.run(args));
|
|
43
43
|
break;
|
|
44
44
|
case "down":
|
|
45
|
-
await import("./down-
|
|
45
|
+
await import("./down-A56B5JLK.js").then((m) => m.run(args));
|
|
46
46
|
break;
|
|
47
47
|
case "restart":
|
|
48
|
-
await import("./daemon-restart-
|
|
48
|
+
await import("./daemon-restart-KNJHZ7FP.js").then((m) => m.run(args));
|
|
49
49
|
break;
|
|
50
50
|
case "setup":
|
|
51
|
-
await import("./setup-
|
|
51
|
+
await import("./setup-DJKIZKGW.js").then((m) => m.run(args));
|
|
52
52
|
break;
|
|
53
53
|
case "service":
|
|
54
|
-
await import("./service-
|
|
54
|
+
await import("./service-U7MZ2H7F.js").then((m) => m.run(args));
|
|
55
55
|
break;
|
|
56
56
|
case "update":
|
|
57
|
-
await import("./update-
|
|
57
|
+
await import("./update-YAGN5ODG.js").then((m) => m.run(args));
|
|
58
58
|
break;
|
|
59
59
|
case "status":
|
|
60
|
-
await import("./status-
|
|
60
|
+
await import("./status-VSFZYX7S.js").then((m) => m.run(args));
|
|
61
61
|
break;
|
|
62
62
|
case "seed":
|
|
63
|
-
await import("./seed-
|
|
63
|
+
await import("./seed-AP4Q7RZ7.js").then((m) => m.run(args));
|
|
64
64
|
break;
|
|
65
65
|
case "sprout":
|
|
66
|
-
await import("./sprout-
|
|
66
|
+
await import("./sprout-2V3MWONK.js").then((m) => m.run(args));
|
|
67
67
|
break;
|
|
68
68
|
case "--help":
|
|
69
69
|
case "-h":
|
|
70
70
|
case void 0:
|
|
71
|
-
console.log(`volute \u2014 create and manage AI
|
|
71
|
+
console.log(`volute \u2014 create and manage AI minds
|
|
72
72
|
|
|
73
73
|
Commands:
|
|
74
|
-
volute
|
|
75
|
-
volute
|
|
76
|
-
volute
|
|
77
|
-
volute
|
|
78
|
-
volute
|
|
79
|
-
volute
|
|
80
|
-
volute
|
|
81
|
-
volute
|
|
82
|
-
volute
|
|
83
|
-
volute
|
|
74
|
+
volute mind create <name> Create a new mind
|
|
75
|
+
volute mind start <name> Start a mind (daemonized)
|
|
76
|
+
volute mind stop <name> Stop a mind
|
|
77
|
+
volute mind restart <name> Restart a mind
|
|
78
|
+
volute mind delete <name> [--force] Delete a mind (--force removes files)
|
|
79
|
+
volute mind list List all minds
|
|
80
|
+
volute mind status <name> Check mind status
|
|
81
|
+
volute mind logs <name> [--follow] Tail mind logs
|
|
82
|
+
volute mind upgrade <name> Upgrade mind to latest template
|
|
83
|
+
volute mind import <path> Import an OpenClaw workspace
|
|
84
84
|
|
|
85
|
-
volute send <target> "<msg>" Send a message (
|
|
86
|
-
volute history [--
|
|
85
|
+
volute send <target> "<msg>" Send a message (mind DM, channel, etc.)
|
|
86
|
+
volute history [--mind <name>] View message history
|
|
87
87
|
|
|
88
88
|
volute variant create <name> Create a variant (worktree + server)
|
|
89
|
-
volute variant list List variants for
|
|
89
|
+
volute variant list List variants for a mind
|
|
90
90
|
volute variant merge <name> Merge a variant back
|
|
91
91
|
volute variant delete <name> Delete a variant
|
|
92
92
|
|
|
93
|
-
volute connector connect <type> Enable a connector for
|
|
94
|
-
volute connector disconnect <type> Disable a connector for
|
|
93
|
+
volute connector connect <type> Enable a connector for a mind
|
|
94
|
+
volute connector disconnect <type> Disable a connector for a mind
|
|
95
95
|
|
|
96
96
|
volute channel read <uri> Read recent messages from a channel
|
|
97
97
|
volute channel list [<platform>] List conversations on a platform
|
|
98
98
|
volute channel users <platform> List users on a platform
|
|
99
99
|
volute channel create <platform> ... Create a conversation on a platform
|
|
100
100
|
|
|
101
|
-
volute schedule list List schedules for
|
|
101
|
+
volute schedule list List schedules for a mind
|
|
102
102
|
volute schedule add ... Add a cron schedule
|
|
103
103
|
volute schedule remove ... Remove a schedule
|
|
104
104
|
|
|
@@ -114,18 +114,18 @@ Commands:
|
|
|
114
114
|
volute setup [--port N] [--host H] Install system service with user isolation
|
|
115
115
|
volute setup uninstall [--force] Remove system service + isolation
|
|
116
116
|
|
|
117
|
-
volute seed <name> Plant a seed
|
|
118
|
-
volute sprout Complete orientation, become a full
|
|
117
|
+
volute seed <name> Plant a seed mind (orientation mode)
|
|
118
|
+
volute sprout Complete orientation, become a full mind
|
|
119
119
|
|
|
120
120
|
volute update Update to latest version
|
|
121
|
-
volute status Show daemon status and
|
|
121
|
+
volute status Show daemon status and minds
|
|
122
122
|
|
|
123
123
|
Options:
|
|
124
124
|
--version, -v Show version number
|
|
125
125
|
--help, -h Show this help message
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
use --
|
|
127
|
+
Mind-scoped commands (send, history, variant, connector, schedule, channel)
|
|
128
|
+
use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
|
|
129
129
|
break;
|
|
130
130
|
default:
|
|
131
131
|
console.error(`Unknown command: ${command}
|
|
@@ -133,7 +133,7 @@ Run 'volute --help' for usage.`);
|
|
|
133
133
|
process.exit(1);
|
|
134
134
|
}
|
|
135
135
|
if (command !== "update") {
|
|
136
|
-
import("./update-check-
|
|
136
|
+
import("./update-check-APLTH4IN.js").then((m) => m.checkForUpdate()).then((result) => {
|
|
137
137
|
if (result.updateAvailable) {
|
|
138
138
|
console.error(`
|
|
139
139
|
Update available: ${result.current} \u2192 ${result.latest}`);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
resolveMindName
|
|
4
|
+
} from "./chunk-NAOW2CLO.js";
|
|
5
5
|
import {
|
|
6
6
|
parseArgs
|
|
7
7
|
} from "./chunk-D424ZQGI.js";
|
|
8
8
|
import {
|
|
9
9
|
daemonFetch
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-OJQ47SCA.js";
|
|
11
|
+
import "./chunk-M77QBTEH.js";
|
|
12
12
|
import {
|
|
13
13
|
getClient,
|
|
14
14
|
urlOf
|
|
@@ -37,8 +37,8 @@ async function run(args) {
|
|
|
37
37
|
}
|
|
38
38
|
function printUsage() {
|
|
39
39
|
console.log(`Usage:
|
|
40
|
-
volute connector connect <type> [--
|
|
41
|
-
volute connector disconnect <type> [--
|
|
40
|
+
volute connector connect <type> [--mind <name>]
|
|
41
|
+
volute connector disconnect <type> [--mind <name>]`);
|
|
42
42
|
}
|
|
43
43
|
async function promptValue(key, description) {
|
|
44
44
|
process.stderr.write(`${description}
|
|
@@ -73,18 +73,18 @@ Enter value for ${key}: `);
|
|
|
73
73
|
}
|
|
74
74
|
async function connectConnector(args) {
|
|
75
75
|
const { positional, flags } = parseArgs(args, {
|
|
76
|
-
|
|
76
|
+
mind: { type: "string" }
|
|
77
77
|
});
|
|
78
|
-
const
|
|
78
|
+
const mindName = resolveMindName(flags);
|
|
79
79
|
const type = positional[0];
|
|
80
80
|
if (!type) {
|
|
81
|
-
console.error("Usage: volute connector connect <type> [--
|
|
81
|
+
console.error("Usage: volute connector connect <type> [--mind <name>]");
|
|
82
82
|
process.exit(1);
|
|
83
83
|
}
|
|
84
84
|
const client = getClient();
|
|
85
85
|
const connectorUrl = urlOf(
|
|
86
|
-
client.api.
|
|
87
|
-
param: { name:
|
|
86
|
+
client.api.minds[":name"].connectors[":type"].$url({
|
|
87
|
+
param: { name: mindName, type }
|
|
88
88
|
})
|
|
89
89
|
);
|
|
90
90
|
let res = await daemonFetch(connectorUrl, { method: "POST" });
|
|
@@ -98,7 +98,7 @@ async function connectConnector(args) {
|
|
|
98
98
|
console.error(` ${v.name} \u2014 ${v.description}`);
|
|
99
99
|
}
|
|
100
100
|
console.error(`
|
|
101
|
-
Set them with: volute env set <KEY> --
|
|
101
|
+
Set them with: volute env set <KEY> --mind ${mindName}`);
|
|
102
102
|
process.exit(1);
|
|
103
103
|
}
|
|
104
104
|
console.error(`${connectorName} connector requires some environment variables.
|
|
@@ -111,8 +111,8 @@ Set them with: volute env set <KEY> --agent ${agentName}`);
|
|
|
111
111
|
}
|
|
112
112
|
const envRes = await daemonFetch(
|
|
113
113
|
urlOf(
|
|
114
|
-
client.api.
|
|
115
|
-
param: { name:
|
|
114
|
+
client.api.minds[":name"].env[":key"].$url({
|
|
115
|
+
param: { name: mindName, key: v.name }
|
|
116
116
|
})
|
|
117
117
|
),
|
|
118
118
|
{
|
|
@@ -141,23 +141,23 @@ Set them with: volute env set <KEY> --agent ${agentName}`);
|
|
|
141
141
|
process.exit(1);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
console.log(`${type} connector for ${
|
|
144
|
+
console.log(`${type} connector for ${mindName} started.`);
|
|
145
145
|
}
|
|
146
146
|
async function disconnectConnector(args) {
|
|
147
147
|
const { positional, flags } = parseArgs(args, {
|
|
148
|
-
|
|
148
|
+
mind: { type: "string" }
|
|
149
149
|
});
|
|
150
|
-
const
|
|
150
|
+
const mindName = resolveMindName(flags);
|
|
151
151
|
const type = positional[0];
|
|
152
152
|
if (!type) {
|
|
153
|
-
console.error("Usage: volute connector disconnect <type> [--
|
|
153
|
+
console.error("Usage: volute connector disconnect <type> [--mind <name>]");
|
|
154
154
|
process.exit(1);
|
|
155
155
|
}
|
|
156
156
|
const client = getClient();
|
|
157
157
|
const res = await daemonFetch(
|
|
158
158
|
urlOf(
|
|
159
|
-
client.api.
|
|
160
|
-
param: { name:
|
|
159
|
+
client.api.minds[":name"].connectors[":type"].$url({
|
|
160
|
+
param: { name: mindName, type }
|
|
161
161
|
})
|
|
162
162
|
),
|
|
163
163
|
{ method: "DELETE" }
|
|
@@ -167,7 +167,7 @@ async function disconnectConnector(args) {
|
|
|
167
167
|
console.error(`Failed to stop ${type} connector: ${body.error}`);
|
|
168
168
|
process.exit(1);
|
|
169
169
|
}
|
|
170
|
-
console.log(`${type} connector for ${
|
|
170
|
+
console.log(`${type} connector for ${mindName} stopped.`);
|
|
171
171
|
}
|
|
172
172
|
export {
|
|
173
173
|
run
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
loadEnv,
|
|
5
5
|
loadFollowedChannels,
|
|
6
6
|
reportTyping,
|
|
7
|
-
|
|
7
|
+
sendToMind,
|
|
8
8
|
slugify,
|
|
9
9
|
writeChannelEntry
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import "../chunk-
|
|
10
|
+
} from "../chunk-3FC42ZBM.js";
|
|
11
|
+
import "../chunk-M77QBTEH.js";
|
|
12
12
|
import "../chunk-K3NQKI34.js";
|
|
13
13
|
|
|
14
14
|
// src/connectors/discord.ts
|
|
@@ -41,7 +41,7 @@ process.on("SIGINT", shutdown);
|
|
|
41
41
|
process.on("SIGTERM", shutdown);
|
|
42
42
|
client.once(Events.ClientReady, (c) => {
|
|
43
43
|
console.log(`Connected to Discord as ${c.user.tag}`);
|
|
44
|
-
console.log(`Bridging to
|
|
44
|
+
console.log(`Bridging to mind: ${env.mindName} via ${env.baseUrl}/message`);
|
|
45
45
|
if (followedChannelNames.length > 0) {
|
|
46
46
|
for (const guild of c.guilds.cache.values()) {
|
|
47
47
|
for (const ch of guild.channels.cache.values()) {
|
|
@@ -94,7 +94,7 @@ client.on(Events.MessageCreate, async (message) => {
|
|
|
94
94
|
serverName: message.guild?.name
|
|
95
95
|
});
|
|
96
96
|
try {
|
|
97
|
-
writeChannelEntry(env.
|
|
97
|
+
writeChannelEntry(env.mindName, channelKey, {
|
|
98
98
|
platformId: message.channelId,
|
|
99
99
|
platform: "discord",
|
|
100
100
|
name: channelName ? `#${channelName}` : void 0,
|
|
@@ -117,7 +117,7 @@ client.on(Events.MessageCreate, async (message) => {
|
|
|
117
117
|
};
|
|
118
118
|
reportTyping(env, channelKey, senderName, false);
|
|
119
119
|
if (isFollowedChannel && !isMentioned) {
|
|
120
|
-
const result = await
|
|
120
|
+
const result = await sendToMind(env, payload);
|
|
121
121
|
if (!result.ok)
|
|
122
122
|
message.reply(result.error ?? "Failed to process message").catch((err) => {
|
|
123
123
|
console.warn(`[discord] failed to send error reply: ${err}`);
|
|
@@ -144,7 +144,7 @@ async function handleDiscordMessage(message, payload) {
|
|
|
144
144
|
console.warn(`[discord] sendTyping failed: ${err}`);
|
|
145
145
|
});
|
|
146
146
|
try {
|
|
147
|
-
const result = await
|
|
147
|
+
const result = await sendToMind(env, payload);
|
|
148
148
|
if (!result.ok)
|
|
149
149
|
message.reply(result.error ?? "Failed to process message").catch((err) => {
|
|
150
150
|
console.warn(`[discord] failed to send error reply: ${err}`);
|
package/dist/connectors/slack.js
CHANGED
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
loadEnv,
|
|
5
5
|
loadFollowedChannels,
|
|
6
6
|
onShutdown,
|
|
7
|
-
|
|
7
|
+
sendToMind,
|
|
8
8
|
writeChannelEntry
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
9
|
+
} from "../chunk-3FC42ZBM.js";
|
|
10
|
+
import "../chunk-M77QBTEH.js";
|
|
11
11
|
import "../chunk-K3NQKI34.js";
|
|
12
12
|
|
|
13
13
|
// src/connectors/slack.ts
|
|
@@ -97,7 +97,7 @@ app.message(async ({ message }) => {
|
|
|
97
97
|
serverName
|
|
98
98
|
});
|
|
99
99
|
try {
|
|
100
|
-
writeChannelEntry(env.
|
|
100
|
+
writeChannelEntry(env.mindName, channelKey, {
|
|
101
101
|
platformId: message.channel,
|
|
102
102
|
platform: "slack",
|
|
103
103
|
name: channelName ? `#${channelName}` : void 0,
|
|
@@ -119,7 +119,7 @@ app.message(async ({ message }) => {
|
|
|
119
119
|
...participantCount ? { participantCount } : {}
|
|
120
120
|
};
|
|
121
121
|
if (isFollowedChannel && !isMentioned) {
|
|
122
|
-
const result2 = await
|
|
122
|
+
const result2 = await sendToMind(env, payload);
|
|
123
123
|
if (!result2.ok)
|
|
124
124
|
app.client.chat.postMessage({
|
|
125
125
|
channel: message.channel,
|
|
@@ -129,7 +129,7 @@ app.message(async ({ message }) => {
|
|
|
129
129
|
});
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
|
-
const result = await
|
|
132
|
+
const result = await sendToMind(env, payload);
|
|
133
133
|
if (!result.ok)
|
|
134
134
|
app.client.chat.postMessage({ channel: message.channel, text: result.error ?? "Failed to process message" }).catch((err) => {
|
|
135
135
|
console.warn(`[slack] failed to send error reply: ${err}`);
|
|
@@ -146,7 +146,7 @@ async function start() {
|
|
|
146
146
|
console.log(
|
|
147
147
|
`Connected to Slack as bot user ${botUserId}${serverName ? ` in ${serverName}` : ""}`
|
|
148
148
|
);
|
|
149
|
-
console.log(`Bridging to
|
|
149
|
+
console.log(`Bridging to mind: ${env.mindName} via ${env.baseUrl}/message`);
|
|
150
150
|
if (followedChannelNames.length > 0) {
|
|
151
151
|
try {
|
|
152
152
|
let cursor;
|