volute 0.42.1 → 0.43.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/{activity-events-KFKVRZE3.js → activity-events-UISXY4Y5.js} +3 -3
- package/dist/{ai-service-3GBOJGUA.js → ai-service-FBCCEYF5.js} +8 -4
- package/dist/{archive-4PPYF7LL.js → archive-I32WHCJB.js} +3 -3
- package/dist/{auth-EAASQPTN.js → auth-3RIG6GKN.js} +4 -4
- package/dist/{chat-LYL5CWJV.js → chat-SDSX5TVV.js} +2 -2
- package/dist/{chunk-M2YMNTHK.js → chunk-2HIVYZDB.js} +1 -1
- package/dist/{chunk-BWZHX46O.js → chunk-3WLWKOGM.js} +21 -6
- package/dist/{chunk-QPTQKGGF.js → chunk-57LBQ7JX.js} +1 -1
- package/dist/{chunk-43K5UWF7.js → chunk-65OLHBCL.js} +13 -12
- package/dist/{chunk-K547QOCM.js → chunk-7G2EEYXX.js} +2 -2
- package/dist/{chunk-E7XWFDZL.js → chunk-AD46AYZQ.js} +1 -1
- package/dist/{chunk-P6DPB33N.js → chunk-ATEX3ZPG.js} +2 -2
- package/dist/{chunk-WR7CSHQ4.js → chunk-C6ESRQZ7.js} +1 -1
- package/dist/{chunk-BR6KFHVT.js → chunk-EE7SZJON.js} +2 -2
- package/dist/{chunk-5QG36RV7.js → chunk-EFL5UOY4.js} +3 -3
- package/dist/{chunk-M3T3Y6FT.js → chunk-FSSUANZJ.js} +5 -5
- package/dist/{chunk-JPDN6ZRJ.js → chunk-FZ5TH5PF.js} +8 -8
- package/dist/{chunk-OEJFZHZZ.js → chunk-GZJFC76M.js} +1 -1
- package/dist/{chunk-KUJVCDWT.js → chunk-JVK6QQIC.js} +2 -2
- package/dist/{chunk-YLTIEEVL.js → chunk-K4EHBHPE.js} +3 -3
- package/dist/{chunk-MHFAWJCC.js → chunk-L3IV23ZG.js} +12 -1
- package/dist/{chunk-VBKRZCR7.js → chunk-M3PGGSBH.js} +1 -1
- package/dist/{chunk-NSGIVS5T.js → chunk-O3DXAR44.js} +2 -2
- package/dist/{chunk-KZAL7HEQ.js → chunk-ONM2AZFL.js} +1 -1
- package/dist/{chunk-6G7R2LPI.js → chunk-PF2AB7VJ.js} +568 -378
- package/dist/chunk-PGPLCJPK.js +272 -0
- package/dist/{chunk-62ICA2FF.js → chunk-SPLPKBES.js} +17 -1
- package/dist/{chunk-BLOAJLGI.js → chunk-XDTKJNW5.js} +1 -1
- package/dist/{chunk-IUZ3EV2D.js → chunk-YAMO2U3N.js} +1 -1
- package/dist/{chunk-4ZSUUBG5.js → chunk-YSV3VJQK.js} +55 -2
- package/dist/{chunk-JU5GWO77.js → chunk-ZO7IQJKO.js} +3 -3
- package/dist/cli.js +15 -15
- package/dist/{cloud-sync-E3ZL5SZ4.js → cloud-sync-FRYNWKCR.js} +16 -17
- package/dist/{conversations-FSZCUUYO.js → conversations-67WWW25C.js} +4 -4
- package/dist/{create-ERNQYOCK.js → create-7W3LV3J7.js} +1 -1
- package/dist/{daemon-restart-QBZOMILO.js → daemon-restart-5GVZ5V3X.js} +7 -8
- package/dist/daemon.js +524 -433
- package/dist/{db-ZJJJYJBU.js → db-CZV62BOQ.js} +2 -2
- package/dist/delivery-manager-5J2BE22P.js +32 -0
- package/dist/{delivery-router-FDBZJQOY.js → delivery-router-HXBHYHJM.js} +7 -5
- package/dist/down-RRNYIGCU.js +16 -0
- package/dist/echo-text-XKBJM6RV.js +32 -0
- package/dist/{exec-ZDD7NEB4.js → exec-SJK7VUTC.js} +3 -4
- package/dist/{export-WYI3E3TB.js → export-7LPCIB5J.js} +3 -3
- package/dist/{extensions-X6MKBJLB.js → extensions-76EGTMFY.js} +16 -17
- package/dist/{files-COTCVBGO.js → files-LV7VAKPC.js} +3 -3
- package/dist/{import-EPK6WCYS.js → import-XPECCRQ7.js} +6 -6
- package/dist/{isolation-F7ABZMDA.js → isolation-5AYEY55P.js} +5 -3
- package/dist/{login-GPBXOU4D.js → login-KJSN4JDA.js} +2 -2
- package/dist/{logout-DNNTIYE2.js → logout-TMJGUQV2.js} +2 -2
- package/dist/message-delivery-WJBZFALY.js +34 -0
- package/dist/{mind-K5PZHPBR.js → mind-QEWCR7FA.js} +5 -5
- package/dist/{mind-activity-tracker-HWVFE533.js → mind-activity-tracker-JHAT6456.js} +4 -4
- package/dist/mind-service-ZBVUMJ5H.js +36 -0
- package/dist/{package-G4AM2IDZ.js → package-ZOI2KAYC.js} +1 -1
- package/dist/{registry-MDLNPTTI.js → registry-7LQHTRUX.js} +2 -2
- package/dist/{sandbox-E7RWZDVG.js → sandbox-SJH3XOPZ.js} +4 -4
- package/dist/scheduler-BR6C6B3E.js +30 -0
- package/dist/{schema-HHYJDG7B.js → schema-LRUTFOER.js} +1 -1
- package/dist/{seed-SKVSWF7S.js → seed-KOG6KJAO.js} +1 -1
- package/dist/{seed-cmd-D2H5VLB4.js → seed-cmd-GJFENEJH.js} +2 -2
- package/dist/{seed-create-BUSKQ5II.js → seed-create-YXO6R4KE.js} +3 -3
- package/dist/{seed-sprout-R2IZPITD.js → seed-sprout-BBU64QXP.js} +7 -8
- package/dist/{send-SLDFRSTL.js → send-ZBZWIH5V.js} +3 -3
- package/dist/{service-ZDOSEQCE.js → service-4EVZKGSA.js} +4 -5
- package/dist/{service-install-2HZPDHEY.js → service-install-SHRM6NHK.js} +5 -6
- package/dist/{setup-IYOUPCIK.js → setup-25MMJ3J4.js} +3 -3
- package/dist/{setup-IU3ID7II.js → setup-354PDHUF.js} +8 -10
- package/dist/{skills-P6RGGASV.js → skills-DPI3WZPQ.js} +5 -6
- package/dist/sleep-manager-BVU5D2AE.js +34 -0
- package/dist/{spirit-XLD6QXSS.js → spirit-JQQHUVWR.js} +7 -8
- package/dist/{sprout-QV2RJM5W.js → sprout-4WAYBUVV.js} +1 -1
- package/dist/{status-QAKAPDYW.js → status-WTU2WHXY.js} +5 -6
- package/dist/system-chat-KMQIP7VH.js +34 -0
- package/dist/{tailscale-TIRTGM6E.js → tailscale-Q7ZJL7S7.js} +2 -2
- package/dist/{turn-tracker-Z5UJC4BY.js → turn-tracker-2GMKJQTN.js} +7 -5
- package/dist/up-7RSBEKW6.js +18 -0
- package/dist/{update-NY3XBVAJ.js → update-EJ7Q77ZX.js} +5 -6
- package/dist/{update-check-OG27AL4Z.js → update-check-ACYYNKTW.js} +3 -3
- package/dist/{version-notify-P7UAR7HZ.js → version-notify-DCAIXXZB.js} +17 -18
- package/dist/web-assets/assets/{index-CrFAsfiE.js → index-DTDmEfPU.js} +2 -2
- package/dist/web-assets/index.html +1 -1
- package/drizzle/0010_delivery_queue_redrive.sql +10 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/templates/codex/src/server.ts +2 -8
- package/dist/chunk-GN52E2DP.js +0 -59
- package/dist/chunk-TFBQESH7.js +0 -179
- package/dist/delivery-manager-J3BRHXUF.js +0 -33
- package/dist/down-DSRWSCXY.js +0 -17
- package/dist/echo-text-3HBQUWPX.js +0 -33
- package/dist/message-delivery-4ZWFDBAY.js +0 -41
- package/dist/mind-manager-6DSY5IJW.js +0 -33
- package/dist/mind-service-R2FM53KD.js +0 -37
- package/dist/scheduler-2FKQCRCM.js +0 -31
- package/dist/sleep-manager-F5KWIFOX.js +0 -35
- package/dist/system-chat-EQIH6JVL.js +0 -35
- package/dist/up-ZTPGC7HB.js +0 -19
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getBaseName,
|
|
4
|
+
validateMindName
|
|
5
|
+
} from "./chunk-YAMO2U3N.js";
|
|
6
|
+
|
|
7
|
+
// packages/daemon/src/lib/mind/isolation.ts
|
|
8
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
9
|
+
import { existsSync, readdirSync, statSync } from "fs";
|
|
10
|
+
import { resolve } from "path";
|
|
11
|
+
|
|
12
|
+
// packages/daemon/src/lib/util/exec.ts
|
|
13
|
+
import { execFile as execFileCb, execFileSync, spawn } from "child_process";
|
|
14
|
+
async function exec(cmd, args, options) {
|
|
15
|
+
const [wrappedCmd, wrappedArgs] = options?.mindName ? await wrapForIsolation(cmd, args, options.mindName) : [cmd, args];
|
|
16
|
+
return new Promise((resolve2, reject) => {
|
|
17
|
+
execFileCb(
|
|
18
|
+
wrappedCmd,
|
|
19
|
+
wrappedArgs,
|
|
20
|
+
{ cwd: options?.cwd, env: options?.env },
|
|
21
|
+
(err, stdout, stderr) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
err.stderr = stderr;
|
|
24
|
+
err.stdout = stdout;
|
|
25
|
+
reject(err);
|
|
26
|
+
} else {
|
|
27
|
+
resolve2(stdout);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function gitExec(args, options) {
|
|
34
|
+
const fullArgs = process.env.VOLUTE_ISOLATION === "user" ? ["-c", "safe.directory=*", ...args] : args;
|
|
35
|
+
return exec("git", fullArgs, options);
|
|
36
|
+
}
|
|
37
|
+
function resolveVoluteBin() {
|
|
38
|
+
try {
|
|
39
|
+
return execFileSync("which", ["volute"], { encoding: "utf-8" }).trim();
|
|
40
|
+
} catch {
|
|
41
|
+
throw new Error("Could not find volute binary on PATH");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function execInherit(cmd, args, options) {
|
|
45
|
+
const [wrappedCmd, wrappedArgs] = options?.mindName ? await wrapForIsolation(cmd, args, options.mindName) : [cmd, args];
|
|
46
|
+
return new Promise((resolve2, reject) => {
|
|
47
|
+
const child = spawn(wrappedCmd, wrappedArgs, {
|
|
48
|
+
cwd: options?.cwd,
|
|
49
|
+
env: options?.env,
|
|
50
|
+
stdio: "inherit"
|
|
51
|
+
});
|
|
52
|
+
child.on("error", reject);
|
|
53
|
+
child.on("close", (code) => {
|
|
54
|
+
if (code === 0) resolve2();
|
|
55
|
+
else reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code}`));
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// packages/daemon/src/lib/mind/isolation.ts
|
|
61
|
+
function isIsolationEnabled() {
|
|
62
|
+
return process.env.VOLUTE_ISOLATION === "user";
|
|
63
|
+
}
|
|
64
|
+
function mindUserName(mindName) {
|
|
65
|
+
const err = validateMindName(mindName);
|
|
66
|
+
if (err && mindName !== "volute") {
|
|
67
|
+
throw new Error(`Invalid mind name for isolation: ${err}`);
|
|
68
|
+
}
|
|
69
|
+
const prefix = process.env.VOLUTE_USER_PREFIX ?? "mind-";
|
|
70
|
+
return `${prefix}${mindName}`;
|
|
71
|
+
}
|
|
72
|
+
function findNextMacId(type) {
|
|
73
|
+
const idField = type === "Users" ? "UniqueID" : "PrimaryGroupID";
|
|
74
|
+
let output;
|
|
75
|
+
try {
|
|
76
|
+
output = execFileSync2("dscl", [".", "-list", `/${type}`, idField], { encoding: "utf-8" });
|
|
77
|
+
} catch (err) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`Failed to query ${type} via dscl: ${err instanceof Error ? err.message : err}`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
const ids = /* @__PURE__ */ new Set();
|
|
83
|
+
for (const line of output.split("\n")) {
|
|
84
|
+
const parts = line.trim().split(/\s+/);
|
|
85
|
+
const id = parseInt(parts[parts.length - 1], 10);
|
|
86
|
+
if (!Number.isNaN(id)) ids.add(id);
|
|
87
|
+
}
|
|
88
|
+
let next = 401;
|
|
89
|
+
while (ids.has(next)) next++;
|
|
90
|
+
return next;
|
|
91
|
+
}
|
|
92
|
+
function getVoluteGroupGid() {
|
|
93
|
+
if (process.platform === "darwin") {
|
|
94
|
+
const output2 = execFileSync2("dscl", [".", "-read", "/Groups/volute", "PrimaryGroupID"], {
|
|
95
|
+
encoding: "utf-8"
|
|
96
|
+
});
|
|
97
|
+
const match = output2.match(/PrimaryGroupID:\s*(\d+)/);
|
|
98
|
+
if (!match) throw new Error("Could not read volute group GID");
|
|
99
|
+
return parseInt(match[1], 10);
|
|
100
|
+
}
|
|
101
|
+
const output = execFileSync2("getent", ["group", "volute"], { encoding: "utf-8" });
|
|
102
|
+
const gid = parseInt(output.split(":")[2], 10);
|
|
103
|
+
if (Number.isNaN(gid)) throw new Error("Could not read volute group GID");
|
|
104
|
+
return gid;
|
|
105
|
+
}
|
|
106
|
+
function ensureVoluteGroup(opts) {
|
|
107
|
+
if (!opts?.force && !isIsolationEnabled()) return;
|
|
108
|
+
if (process.platform === "darwin") {
|
|
109
|
+
try {
|
|
110
|
+
execFileSync2("dscl", [".", "-read", "/Groups/volute"], { stdio: "ignore" });
|
|
111
|
+
return;
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
const gid = findNextMacId("Groups");
|
|
115
|
+
try {
|
|
116
|
+
execFileSync2("dscl", [".", "-create", "/Groups/volute"]);
|
|
117
|
+
execFileSync2("dscl", [".", "-create", "/Groups/volute", "PrimaryGroupID", String(gid)]);
|
|
118
|
+
execFileSync2("dscl", [".", "-create", "/Groups/volute", "Password", "*"]);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
121
|
+
throw new Error(`Failed to create volute group on macOS: ${msg}`);
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
execFileSync2("getent", ["group", "volute"], { stdio: "ignore" });
|
|
127
|
+
} catch {
|
|
128
|
+
try {
|
|
129
|
+
execFileSync2("groupadd", ["volute"], { stdio: ["ignore", "ignore", "pipe"] });
|
|
130
|
+
} catch (err) {
|
|
131
|
+
const stderr = err?.stderr?.toString().trim();
|
|
132
|
+
throw new Error(`Failed to create volute group${stderr ? `: ${stderr}` : ""}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function createMindUser(name, homeDir) {
|
|
137
|
+
if (!isIsolationEnabled()) return;
|
|
138
|
+
const user = mindUserName(name);
|
|
139
|
+
try {
|
|
140
|
+
execFileSync2("id", [user], { stdio: "ignore" });
|
|
141
|
+
return;
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
if (process.platform === "darwin") {
|
|
145
|
+
const uid = findNextMacId("Users");
|
|
146
|
+
const gid = getVoluteGroupGid();
|
|
147
|
+
const home = homeDir ?? "/var/empty";
|
|
148
|
+
try {
|
|
149
|
+
execFileSync2("dscl", [".", "-create", `/Users/${user}`]);
|
|
150
|
+
execFileSync2("dscl", [".", "-create", `/Users/${user}`, "UniqueID", String(uid)]);
|
|
151
|
+
execFileSync2("dscl", [".", "-create", `/Users/${user}`, "PrimaryGroupID", String(gid)]);
|
|
152
|
+
execFileSync2("dscl", [".", "-create", `/Users/${user}`, "UserShell", "/usr/bin/false"]);
|
|
153
|
+
execFileSync2("dscl", [".", "-create", `/Users/${user}`, "NFSHomeDirectory", home]);
|
|
154
|
+
execFileSync2("dscl", [".", "-create", `/Users/${user}`, "RealName", `Volute Mind: ${name}`]);
|
|
155
|
+
execFileSync2("dscl", [".", "-create", `/Users/${user}`, "IsHidden", "1"]);
|
|
156
|
+
execFileSync2("dscl", [".", "-append", "/Groups/volute", "GroupMembership", user]);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
159
|
+
throw new Error(`Failed to create user ${user} on macOS: ${msg}`);
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const args = ["-r", "-M", "-G", "volute", "-s", "/usr/sbin/nologin"];
|
|
165
|
+
if (homeDir) args.push("-d", homeDir);
|
|
166
|
+
args.push(user);
|
|
167
|
+
execFileSync2("useradd", args, {
|
|
168
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
169
|
+
});
|
|
170
|
+
} catch (err) {
|
|
171
|
+
const stderr = err?.stderr?.toString().trim();
|
|
172
|
+
throw new Error(`Failed to create user ${user}${stderr ? `: ${stderr}` : ""}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function deleteMindUser(name) {
|
|
176
|
+
if (!isIsolationEnabled()) return;
|
|
177
|
+
const user = mindUserName(name);
|
|
178
|
+
if (process.platform === "darwin") {
|
|
179
|
+
try {
|
|
180
|
+
execFileSync2("dscl", [".", "-delete", `/Users/${user}`], { stdio: "ignore" });
|
|
181
|
+
} catch {
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
execFileSync2("dscl", [".", "-delete", "/Groups/volute", "GroupMembership", user], {
|
|
185
|
+
stdio: "ignore"
|
|
186
|
+
});
|
|
187
|
+
} catch {
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
execFileSync2("userdel", [user], { stdio: "ignore" });
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async function wrapForIsolation(cmd, args, mindName) {
|
|
197
|
+
if (!isIsolationEnabled()) return [cmd, args];
|
|
198
|
+
const baseName = await getBaseName(mindName);
|
|
199
|
+
const user = mindUserName(baseName);
|
|
200
|
+
if (process.platform === "darwin") {
|
|
201
|
+
return ["sudo", ["-u", user, "--", cmd, ...args]];
|
|
202
|
+
}
|
|
203
|
+
return ["runuser", ["-u", user, "--", cmd, ...args]];
|
|
204
|
+
}
|
|
205
|
+
async function userUid(user) {
|
|
206
|
+
try {
|
|
207
|
+
const uid = parseInt((await exec("id", ["-u", user])).trim(), 10);
|
|
208
|
+
return Number.isNaN(uid) ? null : uid;
|
|
209
|
+
} catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function ownedBy(path, uid) {
|
|
214
|
+
try {
|
|
215
|
+
return statSync(path).uid === uid;
|
|
216
|
+
} catch {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async function chownTargets(dir, user) {
|
|
221
|
+
const nodeModules = resolve(dir, "node_modules");
|
|
222
|
+
const home = resolve(dir, "home");
|
|
223
|
+
if (existsSync(nodeModules) && existsSync(home)) {
|
|
224
|
+
const uid = await userUid(user);
|
|
225
|
+
if (uid !== null && ownedBy(nodeModules, uid)) {
|
|
226
|
+
return readdirSync(dir).filter((entry) => entry !== "node_modules").map((entry) => resolve(dir, entry));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return [dir];
|
|
230
|
+
}
|
|
231
|
+
async function chownMindDir(dir, name) {
|
|
232
|
+
if (!isIsolationEnabled()) return;
|
|
233
|
+
const user = mindUserName(name);
|
|
234
|
+
const group = process.platform === "darwin" ? "volute" : user;
|
|
235
|
+
for (const target of await chownTargets(dir, user)) {
|
|
236
|
+
try {
|
|
237
|
+
await exec("chown", ["-R", `${user}:${group}`, target]);
|
|
238
|
+
} catch (err) {
|
|
239
|
+
const stderr = String(err?.stderr ?? "").trim();
|
|
240
|
+
throw new Error(
|
|
241
|
+
`Failed to chown ${target} to ${user}:${group}${stderr ? `: ${stderr}` : ""}`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
await exec("chown", [`${user}:${group}`, dir]);
|
|
247
|
+
} catch (err) {
|
|
248
|
+
const stderr = String(err?.stderr ?? "").trim();
|
|
249
|
+
throw new Error(`Failed to chown ${dir} to ${user}:${group}${stderr ? `: ${stderr}` : ""}`);
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
await exec("chmod", ["700", dir]);
|
|
253
|
+
} catch (err) {
|
|
254
|
+
const stderr = String(err?.stderr ?? "").trim();
|
|
255
|
+
throw new Error(`Failed to chmod ${dir}${stderr ? `: ${stderr}` : ""}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export {
|
|
260
|
+
isIsolationEnabled,
|
|
261
|
+
mindUserName,
|
|
262
|
+
ensureVoluteGroup,
|
|
263
|
+
createMindUser,
|
|
264
|
+
deleteMindUser,
|
|
265
|
+
wrapForIsolation,
|
|
266
|
+
chownTargets,
|
|
267
|
+
chownMindDir,
|
|
268
|
+
exec,
|
|
269
|
+
gitExec,
|
|
270
|
+
resolveVoluteBin,
|
|
271
|
+
execInherit
|
|
272
|
+
};
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-T2TP6ZC6.js";
|
|
5
5
|
import {
|
|
6
6
|
mindDir
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YAMO2U3N.js";
|
|
8
8
|
|
|
9
9
|
// packages/daemon/src/lib/delivery/delivery-router.ts
|
|
10
10
|
import { readFileSync, statSync } from "fs";
|
|
@@ -20,6 +20,18 @@ var configCache = /* @__PURE__ */ new Map();
|
|
|
20
20
|
var statCheckCache = /* @__PURE__ */ new Map();
|
|
21
21
|
var STAT_TTL_MS = 5e3;
|
|
22
22
|
var dlog = logger_default.child("delivery-router");
|
|
23
|
+
var routesChangeListener;
|
|
24
|
+
function setRoutesChangeListener(fn) {
|
|
25
|
+
routesChangeListener = fn;
|
|
26
|
+
}
|
|
27
|
+
function notifyRoutesChanged(mind) {
|
|
28
|
+
if (!routesChangeListener) return;
|
|
29
|
+
try {
|
|
30
|
+
routesChangeListener(mind);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
dlog.warn(`routes change listener failed for ${mind}`, logger_default.errorData(err));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
23
35
|
var dirOverrides = /* @__PURE__ */ new Map();
|
|
24
36
|
function registerMindDir(name, dir) {
|
|
25
37
|
dirOverrides.set(name, dir);
|
|
@@ -50,7 +62,9 @@ function getRoutingConfig(mindName) {
|
|
|
50
62
|
}
|
|
51
63
|
try {
|
|
52
64
|
const config = JSON.parse(readFileSync(path, "utf-8"));
|
|
65
|
+
const changed = cached != null && cached.mtime !== mtime;
|
|
53
66
|
configCache.set(mindName, { config, mtime });
|
|
67
|
+
if (changed) notifyRoutesChanged(mindName);
|
|
54
68
|
return config;
|
|
55
69
|
} catch (err) {
|
|
56
70
|
dlog.warn(`failed to load routes.json for ${mindName}`, logger_default.errorData(err));
|
|
@@ -63,6 +77,7 @@ function clearConfigCache(mindName) {
|
|
|
63
77
|
if (mindName) {
|
|
64
78
|
configCache.delete(mindName);
|
|
65
79
|
statCheckCache.delete(mindName);
|
|
80
|
+
notifyRoutesChanged(mindName);
|
|
66
81
|
} else {
|
|
67
82
|
configCache.clear();
|
|
68
83
|
statCheckCache.clear();
|
|
@@ -200,6 +215,7 @@ function resolveDeliveryMode(config, sessionName, rule) {
|
|
|
200
215
|
|
|
201
216
|
export {
|
|
202
217
|
extractTextContent,
|
|
218
|
+
setRoutesChangeListener,
|
|
203
219
|
registerMindDir,
|
|
204
220
|
getRoutingConfig,
|
|
205
221
|
clearConfigCache,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
readGlobalConfig,
|
|
4
4
|
writeGlobalConfig
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ONM2AZFL.js";
|
|
6
6
|
import {
|
|
7
7
|
logger_default
|
|
8
8
|
} from "./chunk-T2TP6ZC6.js";
|
|
@@ -141,6 +141,42 @@ function setEnabledModels(modelIds) {
|
|
|
141
141
|
const config = readGlobalConfig();
|
|
142
142
|
writeGlobalConfig({ ...config, ai });
|
|
143
143
|
}
|
|
144
|
+
function migrateAiModelQualification() {
|
|
145
|
+
const config = readGlobalConfig();
|
|
146
|
+
const ai = config.ai;
|
|
147
|
+
const isBare = (id) => id != null && !id.includes(":");
|
|
148
|
+
const hasBareInList = (ai?.models ?? []).some(isBare);
|
|
149
|
+
if (!hasBareInList && !isBare(config.spiritModel) && !isBare(ai?.utilityModel)) return;
|
|
150
|
+
const providers = ai ? Object.keys(ai.providers) : [];
|
|
151
|
+
const customModels = ai?.customModels ?? [];
|
|
152
|
+
const providersServing = (bareId) => providers.filter(
|
|
153
|
+
(p) => getBuiltinModel(p, bareId) != null || customModels.some((cm) => cm.provider === p && cm.id === bareId)
|
|
154
|
+
);
|
|
155
|
+
let changed = false;
|
|
156
|
+
if (ai?.models) {
|
|
157
|
+
const expanded = [];
|
|
158
|
+
for (const id of ai.models) {
|
|
159
|
+
if (!isBare(id)) {
|
|
160
|
+
expanded.push(id);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
changed = true;
|
|
164
|
+
for (const p of providersServing(id)) expanded.push(`${p}:${id}`);
|
|
165
|
+
}
|
|
166
|
+
ai.models = expanded.length > 0 ? [...new Set(expanded)] : void 0;
|
|
167
|
+
if (!ai.models) delete ai.models;
|
|
168
|
+
}
|
|
169
|
+
const qualifyOne = (id) => {
|
|
170
|
+
if (!isBare(id)) return id;
|
|
171
|
+
const [provider] = providersServing(id);
|
|
172
|
+
if (!provider) return id;
|
|
173
|
+
changed = true;
|
|
174
|
+
return `${provider}:${id}`;
|
|
175
|
+
};
|
|
176
|
+
config.spiritModel = qualifyOne(config.spiritModel);
|
|
177
|
+
if (ai) ai.utilityModel = qualifyOne(ai.utilityModel);
|
|
178
|
+
if (changed) writeGlobalConfig(config);
|
|
179
|
+
}
|
|
144
180
|
function getCustomModels() {
|
|
145
181
|
return getAiConfig()?.customModels ?? [];
|
|
146
182
|
}
|
|
@@ -163,7 +199,8 @@ function removeCustomModel(provider, id) {
|
|
|
163
199
|
ai.customModels = customModels.length > 0 ? customModels : void 0;
|
|
164
200
|
if (!ai.customModels) delete ai.customModels;
|
|
165
201
|
if (ai.models) {
|
|
166
|
-
|
|
202
|
+
const qualified = `${provider}:${id}`;
|
|
203
|
+
ai.models = ai.models.filter((mid) => mid !== qualified);
|
|
167
204
|
if (ai.models.length === 0) delete ai.models;
|
|
168
205
|
}
|
|
169
206
|
const config = readGlobalConfig();
|
|
@@ -266,6 +303,20 @@ function unqualifyModelId(modelId) {
|
|
|
266
303
|
return idx >= 0 ? modelId.slice(idx + 1) : modelId;
|
|
267
304
|
}
|
|
268
305
|
function findModel(modelId) {
|
|
306
|
+
const colon = modelId.indexOf(":");
|
|
307
|
+
if (colon >= 0) {
|
|
308
|
+
const provider = modelId.slice(0, colon);
|
|
309
|
+
const bareId = modelId.slice(colon + 1);
|
|
310
|
+
const built = getBuiltinModel(provider, bareId);
|
|
311
|
+
if (built) return built;
|
|
312
|
+
for (const cm of getCustomModels()) {
|
|
313
|
+
if (cm.provider === provider && cm.id === bareId) {
|
|
314
|
+
const model = buildCustomModel(cm.provider, cm.id, cm.name);
|
|
315
|
+
if (model) return model;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return void 0;
|
|
319
|
+
}
|
|
269
320
|
for (const provider of getBuiltinProviders()) {
|
|
270
321
|
const model = getBuiltinModel(provider, modelId);
|
|
271
322
|
if (model) return model;
|
|
@@ -331,6 +382,7 @@ export {
|
|
|
331
382
|
resolveTemplate,
|
|
332
383
|
getEnabledModels,
|
|
333
384
|
setEnabledModels,
|
|
385
|
+
migrateAiModelQualification,
|
|
334
386
|
getCustomModels,
|
|
335
387
|
addCustomModel,
|
|
336
388
|
removeCustomModel,
|
|
@@ -339,5 +391,6 @@ export {
|
|
|
339
391
|
resolveApiKey,
|
|
340
392
|
qualifyModelId,
|
|
341
393
|
unqualifyModelId,
|
|
394
|
+
findModel,
|
|
342
395
|
aiComplete
|
|
343
396
|
};
|
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
modeLabel,
|
|
8
8
|
pollHealth,
|
|
9
9
|
startService
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ATEX3ZPG.js";
|
|
11
11
|
import {
|
|
12
12
|
readGlobalConfig
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ONM2AZFL.js";
|
|
14
14
|
import {
|
|
15
15
|
voluteHome,
|
|
16
16
|
voluteSystemDir
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-YAMO2U3N.js";
|
|
18
18
|
|
|
19
19
|
// src/commands/up.ts
|
|
20
20
|
import { spawn } from "child_process";
|
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ if (!process.env.VOLUTE_HOME) {
|
|
|
10
10
|
var command = process.argv[2];
|
|
11
11
|
var args = process.argv.slice(3);
|
|
12
12
|
if (command === "--version" || command === "-v") {
|
|
13
|
-
const { default: pkg } = await import("./package-
|
|
13
|
+
const { default: pkg } = await import("./package-ZOI2KAYC.js");
|
|
14
14
|
console.log(pkg.version);
|
|
15
15
|
process.exit(0);
|
|
16
16
|
}
|
|
@@ -31,7 +31,7 @@ var ungatedCommands = /* @__PURE__ */ new Set([
|
|
|
31
31
|
void 0
|
|
32
32
|
]);
|
|
33
33
|
if (!ungatedCommands.has(command)) {
|
|
34
|
-
const { isSetupComplete } = await import("./setup-
|
|
34
|
+
const { isSetupComplete } = await import("./setup-25MMJ3J4.js");
|
|
35
35
|
if (!isSetupComplete()) {
|
|
36
36
|
console.error("Volute is not set up. Run `volute setup` first.");
|
|
37
37
|
process.exit(1);
|
|
@@ -39,16 +39,16 @@ if (!ungatedCommands.has(command)) {
|
|
|
39
39
|
}
|
|
40
40
|
switch (command) {
|
|
41
41
|
case "setup":
|
|
42
|
-
await import("./setup-
|
|
42
|
+
await import("./setup-354PDHUF.js").then((m) => m.run(args));
|
|
43
43
|
break;
|
|
44
44
|
case "mind":
|
|
45
|
-
await import("./mind-
|
|
45
|
+
await import("./mind-QEWCR7FA.js").then((m) => m.run(args));
|
|
46
46
|
break;
|
|
47
47
|
case "seed":
|
|
48
|
-
await import("./seed-cmd-
|
|
48
|
+
await import("./seed-cmd-GJFENEJH.js").then((m) => m.run(args));
|
|
49
49
|
break;
|
|
50
50
|
case "chat":
|
|
51
|
-
await import("./chat-
|
|
51
|
+
await import("./chat-SDSX5TVV.js").then((m) => m.run(args));
|
|
52
52
|
break;
|
|
53
53
|
case "variant":
|
|
54
54
|
await import("./variant-HHDTW74J.js").then((m) => m.run(args));
|
|
@@ -66,19 +66,19 @@ switch (command) {
|
|
|
66
66
|
await import("./config-TJLYUV3U.js").then((m) => m.run(args));
|
|
67
67
|
break;
|
|
68
68
|
case "up":
|
|
69
|
-
await import("./up-
|
|
69
|
+
await import("./up-7RSBEKW6.js").then((m) => m.run(args));
|
|
70
70
|
break;
|
|
71
71
|
case "down":
|
|
72
|
-
await import("./down-
|
|
72
|
+
await import("./down-RRNYIGCU.js").then((m) => m.run(args));
|
|
73
73
|
break;
|
|
74
74
|
case "restart":
|
|
75
|
-
await import("./daemon-restart-
|
|
75
|
+
await import("./daemon-restart-5GVZ5V3X.js").then((m) => m.run(args));
|
|
76
76
|
break;
|
|
77
77
|
case "update":
|
|
78
|
-
await import("./update-
|
|
78
|
+
await import("./update-EJ7Q77ZX.js").then((m) => m.run(args));
|
|
79
79
|
break;
|
|
80
80
|
case "status":
|
|
81
|
-
await import("./status-
|
|
81
|
+
await import("./status-WTU2WHXY.js").then((m) => m.run(args));
|
|
82
82
|
break;
|
|
83
83
|
case "extension":
|
|
84
84
|
await import("./extension-SEID47SR.js").then((m) => m.run(args));
|
|
@@ -87,13 +87,13 @@ switch (command) {
|
|
|
87
87
|
await import("./systems-VNB5WKSS.js").then((m) => m.run(args));
|
|
88
88
|
break;
|
|
89
89
|
case "login":
|
|
90
|
-
await import("./login-
|
|
90
|
+
await import("./login-KJSN4JDA.js").then((m) => m.run(args));
|
|
91
91
|
break;
|
|
92
92
|
case "logout":
|
|
93
|
-
await import("./logout-
|
|
93
|
+
await import("./logout-TMJGUQV2.js").then((m) => m.run(args));
|
|
94
94
|
break;
|
|
95
95
|
case "service":
|
|
96
|
-
await import("./service-
|
|
96
|
+
await import("./service-4EVZKGSA.js").then((m) => m.run(args));
|
|
97
97
|
break;
|
|
98
98
|
case "--help":
|
|
99
99
|
case "-h":
|
|
@@ -264,7 +264,7 @@ Run 'volute --help' for usage.`);
|
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
if (command !== "update") {
|
|
267
|
-
import("./update-check-
|
|
267
|
+
import("./update-check-ACYYNKTW.js").then((m) => m.checkForUpdate()).then((result) => {
|
|
268
268
|
if (result.updateAvailable) {
|
|
269
269
|
console.error(`
|
|
270
270
|
Update available: ${result.current} \u2192 ${result.latest}`);
|
|
@@ -1,31 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
deliverMessage
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-PF2AB7VJ.js";
|
|
5
|
+
import "./chunk-XDTKJNW5.js";
|
|
6
|
+
import "./chunk-65OLHBCL.js";
|
|
7
7
|
import "./chunk-QLWG3C2Z.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-FSSUANZJ.js";
|
|
9
9
|
import {
|
|
10
10
|
getAuthHeaders,
|
|
11
11
|
getWebhookUrl
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-K4EHBHPE.js";
|
|
13
13
|
import "./chunk-CU6OFXMM.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-K547QOCM.js";
|
|
14
|
+
import "./chunk-C6ESRQZ7.js";
|
|
15
|
+
import "./chunk-M3PGGSBH.js";
|
|
16
|
+
import "./chunk-SPLPKBES.js";
|
|
17
|
+
import "./chunk-3WLWKOGM.js";
|
|
18
|
+
import "./chunk-PGPLCJPK.js";
|
|
19
|
+
import "./chunk-YSV3VJQK.js";
|
|
20
|
+
import "./chunk-ONM2AZFL.js";
|
|
21
|
+
import "./chunk-EFL5UOY4.js";
|
|
22
|
+
import "./chunk-7G2EEYXX.js";
|
|
24
23
|
import {
|
|
25
24
|
logger_default
|
|
26
25
|
} from "./chunk-T2TP6ZC6.js";
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-YAMO2U3N.js";
|
|
27
|
+
import "./chunk-L3IV23ZG.js";
|
|
29
28
|
import "./chunk-K3NQKI34.js";
|
|
30
29
|
|
|
31
30
|
// packages/daemon/src/lib/cloud-sync.ts
|
|
@@ -29,11 +29,11 @@ import {
|
|
|
29
29
|
removeParticipant,
|
|
30
30
|
setConversationPrivate,
|
|
31
31
|
updateChannelSettings
|
|
32
|
-
} from "./chunk-
|
|
33
|
-
import "./chunk-
|
|
32
|
+
} from "./chunk-K4EHBHPE.js";
|
|
33
|
+
import "./chunk-7G2EEYXX.js";
|
|
34
34
|
import "./chunk-T2TP6ZC6.js";
|
|
35
|
-
import "./chunk-
|
|
36
|
-
import "./chunk-
|
|
35
|
+
import "./chunk-YAMO2U3N.js";
|
|
36
|
+
import "./chunk-L3IV23ZG.js";
|
|
37
37
|
import "./chunk-K3NQKI34.js";
|
|
38
38
|
export {
|
|
39
39
|
addMessage,
|
|
@@ -21,7 +21,7 @@ var cmd = command({
|
|
|
21
21
|
const name = args.name;
|
|
22
22
|
let template = flags.template;
|
|
23
23
|
if (!template) {
|
|
24
|
-
const { resolveTemplate } = await import("./ai-service-
|
|
24
|
+
const { resolveTemplate } = await import("./ai-service-FBCCEYF5.js");
|
|
25
25
|
template = await resolveTemplate();
|
|
26
26
|
}
|
|
27
27
|
const skills = flags.skills === "none" ? [] : flags.skills ? flags.skills.split(",") : void 0;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
stopDaemon
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-O3DXAR44.js";
|
|
5
5
|
import {
|
|
6
6
|
run
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZO7IQJKO.js";
|
|
8
8
|
import {
|
|
9
9
|
command
|
|
10
10
|
} from "./chunk-TXSA4Q3V.js";
|
|
@@ -15,12 +15,11 @@ import {
|
|
|
15
15
|
pollHealth,
|
|
16
16
|
readDaemonConfig,
|
|
17
17
|
restartService
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-MHFAWJCC.js";
|
|
18
|
+
} from "./chunk-ATEX3ZPG.js";
|
|
19
|
+
import "./chunk-PGPLCJPK.js";
|
|
20
|
+
import "./chunk-ONM2AZFL.js";
|
|
21
|
+
import "./chunk-YAMO2U3N.js";
|
|
22
|
+
import "./chunk-L3IV23ZG.js";
|
|
24
23
|
import "./chunk-K3NQKI34.js";
|
|
25
24
|
|
|
26
25
|
// src/commands/daemon-restart.ts
|