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
|
@@ -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
|
|
@@ -46,27 +46,27 @@ async function run(args) {
|
|
|
46
46
|
}
|
|
47
47
|
function printUsage() {
|
|
48
48
|
console.log(`Usage:
|
|
49
|
-
volute channel read <channel-uri> [--limit N] [--
|
|
50
|
-
volute channel list [<platform>] [--
|
|
51
|
-
volute channel users <platform> [--
|
|
52
|
-
volute channel create <platform> --participants user1,user2 [--name "..."] [--
|
|
53
|
-
volute channel typing <channel-uri> [--
|
|
49
|
+
volute channel read <channel-uri> [--limit N] [--mind <name>]
|
|
50
|
+
volute channel list [<platform>] [--mind <name>]
|
|
51
|
+
volute channel users <platform> [--mind <name>]
|
|
52
|
+
volute channel create <platform> --participants user1,user2 [--name "..."] [--mind <name>]
|
|
53
|
+
volute channel typing <channel-uri> [--mind <name>]`);
|
|
54
54
|
}
|
|
55
55
|
async function readChannel(args) {
|
|
56
56
|
const { positional, flags } = parseArgs(args, {
|
|
57
|
-
|
|
57
|
+
mind: { type: "string" },
|
|
58
58
|
limit: { type: "number" }
|
|
59
59
|
});
|
|
60
60
|
const uri = positional[0];
|
|
61
61
|
if (!uri) {
|
|
62
|
-
console.error("Usage: volute channel read <channel-uri> [--limit N] [--
|
|
62
|
+
console.error("Usage: volute channel read <channel-uri> [--limit N] [--mind <name>]");
|
|
63
63
|
process.exit(1);
|
|
64
64
|
}
|
|
65
|
-
const
|
|
65
|
+
const mindName = resolveMindName(flags);
|
|
66
66
|
const { platform } = parseUri(uri);
|
|
67
67
|
const limit = flags.limit ?? 20;
|
|
68
68
|
const client = getClient();
|
|
69
|
-
const url = client.api.
|
|
69
|
+
const url = client.api.minds[":name"].channels.read.$url({ param: { name: mindName } });
|
|
70
70
|
url.searchParams.set("platform", platform);
|
|
71
71
|
url.searchParams.set("uri", uri);
|
|
72
72
|
url.searchParams.set("limit", String(limit));
|
|
@@ -81,12 +81,12 @@ async function readChannel(args) {
|
|
|
81
81
|
}
|
|
82
82
|
async function listChannels(args) {
|
|
83
83
|
const { positional, flags } = parseArgs(args, {
|
|
84
|
-
|
|
84
|
+
mind: { type: "string" }
|
|
85
85
|
});
|
|
86
86
|
const platform = positional[0];
|
|
87
|
-
const
|
|
87
|
+
const mindName = resolveMindName(flags);
|
|
88
88
|
const client = getClient();
|
|
89
|
-
const url = client.api.
|
|
89
|
+
const url = client.api.minds[":name"].channels.list.$url({ param: { name: mindName } });
|
|
90
90
|
if (platform) url.searchParams.set("platform", platform);
|
|
91
91
|
const res = await daemonFetch(urlOf(url));
|
|
92
92
|
if (!res.ok) {
|
|
@@ -111,16 +111,16 @@ async function listChannels(args) {
|
|
|
111
111
|
}
|
|
112
112
|
async function listUsers(args) {
|
|
113
113
|
const { positional, flags } = parseArgs(args, {
|
|
114
|
-
|
|
114
|
+
mind: { type: "string" }
|
|
115
115
|
});
|
|
116
116
|
const platform = positional[0];
|
|
117
117
|
if (!platform) {
|
|
118
|
-
console.error("Usage: volute channel users <platform> [--
|
|
118
|
+
console.error("Usage: volute channel users <platform> [--mind <name>]");
|
|
119
119
|
process.exit(1);
|
|
120
120
|
}
|
|
121
|
-
const
|
|
121
|
+
const mindName = resolveMindName(flags);
|
|
122
122
|
const client = getClient();
|
|
123
|
-
const url = client.api.
|
|
123
|
+
const url = client.api.minds[":name"].channels.users.$url({ param: { name: mindName } });
|
|
124
124
|
url.searchParams.set("platform", platform);
|
|
125
125
|
const res = await daemonFetch(urlOf(url));
|
|
126
126
|
if (!res.ok) {
|
|
@@ -135,22 +135,22 @@ async function listUsers(args) {
|
|
|
135
135
|
}
|
|
136
136
|
async function createChannel(args) {
|
|
137
137
|
const { positional, flags } = parseArgs(args, {
|
|
138
|
-
|
|
138
|
+
mind: { type: "string" },
|
|
139
139
|
participants: { type: "string" },
|
|
140
140
|
name: { type: "string" }
|
|
141
141
|
});
|
|
142
142
|
const platform = positional[0];
|
|
143
143
|
if (!platform || !flags.participants) {
|
|
144
144
|
console.error(
|
|
145
|
-
'Usage: volute channel create <platform> --participants user1,user2 [--name "..."] [--
|
|
145
|
+
'Usage: volute channel create <platform> --participants user1,user2 [--name "..."] [--mind <name>]'
|
|
146
146
|
);
|
|
147
147
|
process.exit(1);
|
|
148
148
|
}
|
|
149
|
-
const
|
|
149
|
+
const mindName = resolveMindName(flags);
|
|
150
150
|
const participants = flags.participants.split(",").map((s) => s.trim());
|
|
151
151
|
const client = getClient();
|
|
152
152
|
const res = await daemonFetch(
|
|
153
|
-
urlOf(client.api.
|
|
153
|
+
urlOf(client.api.minds[":name"].channels.create.$url({ param: { name: mindName } })),
|
|
154
154
|
{
|
|
155
155
|
method: "POST",
|
|
156
156
|
headers: { "Content-Type": "application/json" },
|
|
@@ -167,17 +167,17 @@ async function createChannel(args) {
|
|
|
167
167
|
}
|
|
168
168
|
async function typingChannel(args) {
|
|
169
169
|
const { positional, flags } = parseArgs(args, {
|
|
170
|
-
|
|
170
|
+
mind: { type: "string" }
|
|
171
171
|
});
|
|
172
172
|
const uri = positional[0];
|
|
173
173
|
if (!uri) {
|
|
174
|
-
console.error("Usage: volute channel typing <channel-uri> [--
|
|
174
|
+
console.error("Usage: volute channel typing <channel-uri> [--mind <name>]");
|
|
175
175
|
process.exit(1);
|
|
176
176
|
}
|
|
177
|
-
const
|
|
177
|
+
const mindName = resolveMindName(flags);
|
|
178
178
|
try {
|
|
179
179
|
const client = getClient();
|
|
180
|
-
const url = client.api.
|
|
180
|
+
const url = client.api.minds[":name"].typing.$url({ param: { name: mindName } });
|
|
181
181
|
url.searchParams.set("channel", uri);
|
|
182
182
|
const res = await daemonFetch(urlOf(url));
|
|
183
183
|
if (!res.ok) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
wrapForIsolation
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZCEYUUID.js";
|
|
5
5
|
|
|
6
6
|
// src/lib/exec.ts
|
|
7
7
|
import { execFile as execFileCb, execFileSync, spawn } from "child_process";
|
|
8
8
|
function exec(cmd, args, options) {
|
|
9
|
-
const [wrappedCmd, wrappedArgs] = options?.
|
|
9
|
+
const [wrappedCmd, wrappedArgs] = options?.mindName ? wrapForIsolation(cmd, args, options.mindName) : [cmd, args];
|
|
10
10
|
return new Promise((resolve, reject) => {
|
|
11
11
|
execFileCb(
|
|
12
12
|
wrappedCmd,
|
|
@@ -35,7 +35,7 @@ function resolveVoluteBin() {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
function execInherit(cmd, args, options) {
|
|
38
|
-
const [wrappedCmd, wrappedArgs] = options?.
|
|
38
|
+
const [wrappedCmd, wrappedArgs] = options?.mindName ? wrapForIsolation(cmd, args, options.mindName) : [cmd, args];
|
|
39
39
|
return new Promise((resolve, reject) => {
|
|
40
40
|
const child = spawn(wrappedCmd, wrappedArgs, {
|
|
41
41
|
cwd: options?.cwd,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
stateDir
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-M77QBTEH.js";
|
|
5
5
|
|
|
6
6
|
// src/lib/slugify.ts
|
|
7
7
|
function slugify(text) {
|
|
@@ -10,7 +10,7 @@ function slugify(text) {
|
|
|
10
10
|
function buildVoluteSlug(opts) {
|
|
11
11
|
const isDM = opts.participants.length === 2;
|
|
12
12
|
if (isDM) {
|
|
13
|
-
const other = opts.participants.find((p) => p.username !== opts.
|
|
13
|
+
const other = opts.participants.find((p) => p.username !== opts.mindUsername);
|
|
14
14
|
const otherSlug = other ? slugify(other.username) : "";
|
|
15
15
|
return otherSlug ? `volute:@${otherSlug}` : `volute:${opts.conversationId}`;
|
|
16
16
|
}
|
|
@@ -21,28 +21,28 @@ function buildVoluteSlug(opts) {
|
|
|
21
21
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
22
22
|
import { join, resolve } from "path";
|
|
23
23
|
function loadEnv() {
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
if (!
|
|
27
|
-
console.error("Missing required env vars:
|
|
24
|
+
const mindPort = process.env.VOLUTE_MIND_PORT;
|
|
25
|
+
const mindName = process.env.VOLUTE_MIND_NAME;
|
|
26
|
+
if (!mindPort || !mindName) {
|
|
27
|
+
console.error("Missing required env vars: VOLUTE_MIND_PORT, VOLUTE_MIND_NAME");
|
|
28
28
|
process.exit(1);
|
|
29
29
|
}
|
|
30
|
-
const
|
|
30
|
+
const mindDir = process.env.VOLUTE_MIND_DIR;
|
|
31
31
|
const daemonUrl = process.env.VOLUTE_DAEMON_URL;
|
|
32
32
|
const daemonToken = process.env.VOLUTE_DAEMON_TOKEN;
|
|
33
|
-
const baseUrl = daemonUrl ? `${daemonUrl}/api/
|
|
34
|
-
return {
|
|
33
|
+
const baseUrl = daemonUrl ? `${daemonUrl}/api/minds/${encodeURIComponent(mindName)}` : `http://127.0.0.1:${mindPort}`;
|
|
34
|
+
return { mindPort, mindName, mindDir, baseUrl, daemonUrl, daemonToken };
|
|
35
35
|
}
|
|
36
36
|
function loadFollowedChannels(env, platform) {
|
|
37
|
-
if (!env.
|
|
38
|
-
const configPath = resolve(env.
|
|
37
|
+
if (!env.mindDir) return [];
|
|
38
|
+
const configPath = resolve(env.mindDir, "home/.config/volute.json");
|
|
39
39
|
if (!existsSync(configPath)) return [];
|
|
40
40
|
try {
|
|
41
41
|
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
42
42
|
const platformConfig = config[platform];
|
|
43
43
|
return platformConfig?.channels ?? platformConfig?.chats ?? [];
|
|
44
44
|
} catch (err) {
|
|
45
|
-
console.warn(`Failed to load
|
|
45
|
+
console.warn(`Failed to load mind config: ${err}`);
|
|
46
46
|
return [];
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -87,7 +87,7 @@ function reportTyping(env, channel, sender, active) {
|
|
|
87
87
|
console.warn(`[typing] failed to report for ${sender} on ${channel}: ${err}`);
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
|
-
async function
|
|
90
|
+
async function sendToMind(env, payload) {
|
|
91
91
|
const url = `${env.baseUrl}/message`;
|
|
92
92
|
try {
|
|
93
93
|
const res = await fetch(url, {
|
|
@@ -97,14 +97,14 @@ async function sendToAgent(env, payload) {
|
|
|
97
97
|
});
|
|
98
98
|
if (!res.ok) {
|
|
99
99
|
const body = await res.text().catch(() => "");
|
|
100
|
-
console.error(`
|
|
101
|
-
return { ok: false, error: `
|
|
100
|
+
console.error(`Mind returned ${res.status}: ${body}`);
|
|
101
|
+
return { ok: false, error: `Mind returned ${res.status}` };
|
|
102
102
|
}
|
|
103
103
|
return { ok: true };
|
|
104
104
|
} catch (err) {
|
|
105
105
|
console.error(`Failed to forward message: ${err}`);
|
|
106
106
|
const isConnRefused = err instanceof TypeError && err.cause?.code === "ECONNREFUSED";
|
|
107
|
-
return { ok: false, error: isConnRefused ? "
|
|
107
|
+
return { ok: false, error: isConnRefused ? "Mind is not running" : "Failed to reach mind" };
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
function buildChannelSlug(platform, meta) {
|
|
@@ -128,8 +128,8 @@ function buildChannelSlug(platform, meta) {
|
|
|
128
128
|
}
|
|
129
129
|
return `${platform}:unknown`;
|
|
130
130
|
}
|
|
131
|
-
function readChannelMap(
|
|
132
|
-
const filePath = join(stateDir(
|
|
131
|
+
function readChannelMap(mindName) {
|
|
132
|
+
const filePath = join(stateDir(mindName), "channels.json");
|
|
133
133
|
if (!existsSync(filePath)) return {};
|
|
134
134
|
try {
|
|
135
135
|
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
@@ -138,16 +138,16 @@ function readChannelMap(agentName) {
|
|
|
138
138
|
return {};
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
function writeChannelEntry(
|
|
142
|
-
const dir = stateDir(
|
|
141
|
+
function writeChannelEntry(mindName, slug, entry) {
|
|
142
|
+
const dir = stateDir(mindName);
|
|
143
143
|
mkdirSync(dir, { recursive: true });
|
|
144
144
|
const filePath = join(dir, "channels.json");
|
|
145
|
-
const map = readChannelMap(
|
|
145
|
+
const map = readChannelMap(mindName);
|
|
146
146
|
map[slug] = entry;
|
|
147
147
|
writeFileSync(filePath, JSON.stringify(map, null, 2) + "\n");
|
|
148
148
|
}
|
|
149
|
-
function resolveChannelId(
|
|
150
|
-
const map = readChannelMap(
|
|
149
|
+
function resolveChannelId(mindName, slug) {
|
|
150
|
+
const map = readChannelMap(mindName);
|
|
151
151
|
if (map[slug]) {
|
|
152
152
|
return map[slug].platformId;
|
|
153
153
|
}
|
|
@@ -163,7 +163,7 @@ export {
|
|
|
163
163
|
splitMessage,
|
|
164
164
|
onShutdown,
|
|
165
165
|
reportTyping,
|
|
166
|
-
|
|
166
|
+
sendToMind,
|
|
167
167
|
buildChannelSlug,
|
|
168
168
|
writeChannelEntry,
|
|
169
169
|
resolveChannelId
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
execInherit
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2Y77MCFG.js";
|
|
5
5
|
import {
|
|
6
6
|
voluteHome
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-M77QBTEH.js";
|
|
8
8
|
|
|
9
9
|
// src/lib/service-mode.ts
|
|
10
10
|
import { execFileSync } from "child_process";
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
modeLabel,
|
|
5
5
|
pollHealth,
|
|
6
6
|
startService
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6BDNWYKG.js";
|
|
8
8
|
import {
|
|
9
9
|
parseArgs
|
|
10
10
|
} from "./chunk-D424ZQGI.js";
|
|
11
11
|
import {
|
|
12
12
|
voluteHome
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-M77QBTEH.js";
|
|
14
14
|
|
|
15
15
|
// src/commands/up.ts
|
|
16
16
|
import { spawn } from "child_process";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
mindEnvPath,
|
|
4
4
|
readEnv,
|
|
5
5
|
writeEnv
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OYSZNX5I.js";
|
|
7
7
|
import {
|
|
8
8
|
parseArgs
|
|
9
9
|
} from "./chunk-D424ZQGI.js";
|
|
@@ -24,12 +24,12 @@ function readJson(path) {
|
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
function readVoluteConfig(
|
|
28
|
-
const path = resolve(
|
|
27
|
+
function readVoluteConfig(mindDir) {
|
|
28
|
+
const path = resolve(mindDir, "home/.config/volute.json");
|
|
29
29
|
return readJson(path);
|
|
30
30
|
}
|
|
31
|
-
function writeVoluteConfig(
|
|
32
|
-
const path = resolve(
|
|
31
|
+
function writeVoluteConfig(mindDir, config) {
|
|
32
|
+
const path = resolve(mindDir, "home/.config/volute.json");
|
|
33
33
|
mkdirSync(dirname(path), { recursive: true });
|
|
34
34
|
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
35
35
|
`);
|
|
@@ -43,10 +43,10 @@ async function run(args) {
|
|
|
43
43
|
template: { type: "string" }
|
|
44
44
|
});
|
|
45
45
|
const wsDir = resolveWorkspace(positional[0]);
|
|
46
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
46
|
+
const { daemonFetch } = await import("./daemon-client-ODKDUYDE.js");
|
|
47
47
|
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
48
48
|
const client = getClient();
|
|
49
|
-
const res = await daemonFetch(urlOf(client.api.
|
|
49
|
+
const res = await daemonFetch(urlOf(client.api.minds.import.$url()), {
|
|
50
50
|
method: "POST",
|
|
51
51
|
headers: { "Content-Type": "application/json" },
|
|
52
52
|
body: JSON.stringify({
|
|
@@ -58,13 +58,13 @@ async function run(args) {
|
|
|
58
58
|
});
|
|
59
59
|
const data = await res.json();
|
|
60
60
|
if (!res.ok) {
|
|
61
|
-
console.error(data.error ?? "Failed to import
|
|
61
|
+
console.error(data.error ?? "Failed to import mind");
|
|
62
62
|
process.exit(1);
|
|
63
63
|
}
|
|
64
64
|
console.log(`
|
|
65
|
-
${data.message ?? `Imported
|
|
65
|
+
${data.message ?? `Imported mind: ${data.name} (port ${data.port})`}`);
|
|
66
66
|
console.log(`
|
|
67
|
-
volute
|
|
67
|
+
volute mind start ${data.name}`);
|
|
68
68
|
}
|
|
69
69
|
function resolveWorkspace(explicitPath) {
|
|
70
70
|
if (explicitPath) {
|
|
@@ -86,17 +86,17 @@ function resolveWorkspace(explicitPath) {
|
|
|
86
86
|
return openclawWs;
|
|
87
87
|
}
|
|
88
88
|
console.error(
|
|
89
|
-
"Usage: volute
|
|
89
|
+
"Usage: volute mind 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."
|
|
90
90
|
);
|
|
91
91
|
process.exit(1);
|
|
92
92
|
}
|
|
93
93
|
function findOpenClawSession(workspaceDir) {
|
|
94
|
-
const
|
|
95
|
-
if (!existsSync2(
|
|
94
|
+
const ocAgentsDir = resolve2(homedir(), ".openclaw/agents");
|
|
95
|
+
if (!existsSync2(ocAgentsDir)) return void 0;
|
|
96
96
|
const matches = [];
|
|
97
97
|
try {
|
|
98
|
-
for (const
|
|
99
|
-
const sessionsDir = resolve2(
|
|
98
|
+
for (const entry of readdirSync(ocAgentsDir)) {
|
|
99
|
+
const sessionsDir = resolve2(ocAgentsDir, entry, "sessions");
|
|
100
100
|
if (!existsSync2(sessionsDir)) continue;
|
|
101
101
|
for (const file of readdirSync(sessionsDir)) {
|
|
102
102
|
if (!file.endsWith(".jsonl")) continue;
|
|
@@ -125,9 +125,9 @@ function sessionMatchesWorkspace(sessionPath, workspaceDir) {
|
|
|
125
125
|
return false;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
function importPiSession(sessionFile,
|
|
129
|
-
const homeDir = resolve2(
|
|
130
|
-
const piSessionDir = resolve2(
|
|
128
|
+
function importPiSession(sessionFile, mindDirPath) {
|
|
129
|
+
const homeDir = resolve2(mindDirPath, "home");
|
|
130
|
+
const piSessionDir = resolve2(mindDirPath, ".volute/pi-sessions/main");
|
|
131
131
|
mkdirSync2(piSessionDir, { recursive: true });
|
|
132
132
|
const content = readFileSync2(sessionFile, "utf-8");
|
|
133
133
|
const lines = content.trim().split("\n");
|
|
@@ -145,7 +145,7 @@ function importPiSession(sessionFile, agentDirPath) {
|
|
|
145
145
|
`);
|
|
146
146
|
console.log(`Imported session (${lines.length} entries)`);
|
|
147
147
|
}
|
|
148
|
-
function importOpenClawConnectors(
|
|
148
|
+
function importOpenClawConnectors(name, mindDirPath) {
|
|
149
149
|
const configPath = resolve2(homedir(), ".openclaw/openclaw.json");
|
|
150
150
|
if (!existsSync2(configPath)) return;
|
|
151
151
|
let config;
|
|
@@ -157,7 +157,7 @@ function importOpenClawConnectors(agentName, agentDirPath) {
|
|
|
157
157
|
}
|
|
158
158
|
const discord = config.channels?.discord;
|
|
159
159
|
if (!discord?.enabled || !discord.token) return;
|
|
160
|
-
const envPath =
|
|
160
|
+
const envPath = mindEnvPath(name);
|
|
161
161
|
const env = readEnv(envPath);
|
|
162
162
|
env.DISCORD_TOKEN = discord.token;
|
|
163
163
|
writeEnv(envPath, env);
|
|
@@ -165,19 +165,19 @@ function importOpenClawConnectors(agentName, agentDirPath) {
|
|
|
165
165
|
if (discord.guilds) {
|
|
166
166
|
for (const guild of Object.values(discord.guilds)) {
|
|
167
167
|
if (!guild.channels) continue;
|
|
168
|
-
for (const [
|
|
169
|
-
if (ch.allow) channelNames.add(
|
|
168
|
+
for (const [name2, ch] of Object.entries(guild.channels)) {
|
|
169
|
+
if (ch.allow) channelNames.add(name2);
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
-
const voluteConfig = readVoluteConfig(
|
|
173
|
+
const voluteConfig = readVoluteConfig(mindDirPath) ?? {};
|
|
174
174
|
const connectors = new Set(voluteConfig.connectors ?? []);
|
|
175
175
|
connectors.add("discord");
|
|
176
176
|
voluteConfig.connectors = [...connectors];
|
|
177
177
|
if (channelNames.size > 0) {
|
|
178
178
|
voluteConfig.discord = { channels: [...channelNames] };
|
|
179
179
|
}
|
|
180
|
-
writeVoluteConfig(
|
|
180
|
+
writeVoluteConfig(mindDirPath, voluteConfig);
|
|
181
181
|
console.log("Imported Discord connector config");
|
|
182
182
|
if (channelNames.size > 0) {
|
|
183
183
|
console.log(`Imported followed channels: ${[...channelNames].join(", ")}`);
|