volute 0.37.0 → 0.38.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/{chunk-UQFYNZKT.js → chunk-2TR2OPVA.js} +1 -1
- package/dist/chunk-JOJT34M2.js +109 -0
- package/dist/{chunk-Z6TIXE77.js → chunk-NGXQ2ESO.js} +9 -8
- package/dist/{chunk-QQQI6ISK.js → chunk-PLL2FM7A.js} +35 -20
- package/dist/{chunk-KBRGHKVU.js → chunk-TEZRVSSB.js} +58 -29
- package/dist/{chunk-NYP3LBIV.js → chunk-VUM2K6EN.js} +1 -1
- package/dist/cli.js +12 -12
- package/dist/{cloud-sync-OIX576NA.js → cloud-sync-PEM3IVI4.js} +8 -8
- package/dist/{daemon-restart-L2O6L7NR.js → daemon-restart-6QONRBTK.js} +6 -6
- package/dist/daemon.js +146 -76
- package/dist/{delivery-manager-4PVBUZJB.js → delivery-manager-IMCRV6A3.js} +5 -5
- package/dist/{down-25L2RKCQ.js → down-5XZWH4ZP.js} +2 -2
- package/dist/{echo-text-T5ZLGMA7.js → echo-text-ADKLNTIA.js} +6 -6
- package/dist/{extensions-CLYXNGYB.js → extensions-P477XR46.js} +5 -5
- package/dist/{message-delivery-N2V5APCS.js → message-delivery-54IXVE5H.js} +5 -5
- package/dist/{mind-M57ET546.js → mind-G5HDKBKL.js} +2 -2
- package/dist/{mind-manager-LS2AIXHQ.js → mind-manager-5G6P2EAT.js} +5 -5
- package/dist/{mind-service-UDXF5WC2.js → mind-service-FDATHL6X.js} +5 -5
- package/dist/{package-5FGU5QNP.js → package-LYQHSDPG.js} +27 -27
- package/dist/{scheduler-NTC74JYH.js → scheduler-ZRUZNQI5.js} +5 -5
- package/dist/{seed-55VC3A57.js → seed-3KH4ZRJL.js} +1 -1
- package/dist/{seed-cmd-2KOEQZK6.js → seed-cmd-6A76SSAA.js} +2 -2
- package/dist/{seed-create-Y2Z5JWBB.js → seed-create-XXRRGZCO.js} +1 -1
- package/dist/{seed-sprout-OLSIWXZN.js → seed-sprout-HLMUH2AI.js} +2 -2
- package/dist/service-install-AIQBLE6P.js +17 -0
- package/dist/setup-NPAZXBIJ.js +454 -0
- package/dist/{skills-FDMLJGZ3.js → skills-NVOWS5NY.js} +1 -1
- package/dist/{sleep-manager-TQP5ZJI5.js → sleep-manager-VPPQXBPH.js} +5 -5
- package/dist/{spirit-SM6ARJ2N.js → spirit-ZFYG4JOH.js} +2 -2
- package/dist/{sprout-G6G57IOY.js → sprout-FLBCETYG.js} +1 -1
- package/dist/{src-LT6ZBYYX.js → src-6Z4XYDH5.js} +200 -169
- package/dist/{system-chat-NNXYCSVL.js → system-chat-YUIT7RA6.js} +5 -5
- package/dist/{up-5JXV6BZS.js → up-YRZAEZ3Z.js} +2 -2
- package/dist/{version-notify-CSE4NBYM.js → version-notify-764EXVQQ.js} +5 -5
- package/dist/web-assets/assets/index-BI7hUTBr.js +73 -0
- package/dist/web-assets/assets/index-BJifO9h_.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +27 -27
- package/packages/extensions/notes/dist/ui/assets/index-D3cdui42.css +1 -0
- package/packages/extensions/notes/dist/ui/assets/index-Dsua7alJ.js +61 -0
- package/packages/extensions/notes/dist/ui/index.html +2 -2
- package/packages/extensions/pages/dist/ui/assets/index-BM7gRdg7.js +2 -0
- package/packages/extensions/pages/dist/ui/assets/index-BcY6lnq4.css +1 -0
- package/packages/extensions/pages/dist/ui/index.html +2 -2
- package/packages/extensions/plan/dist/ui/assets/index-DWiqtzBv.js +61 -0
- package/packages/extensions/plan/dist/ui/assets/index-jIkrt-vI.css +1 -0
- package/packages/extensions/plan/dist/ui/index.html +2 -2
- package/templates/_base/src/lib/startup.ts +2 -0
- package/templates/_base/tsconfig.json +3 -1
- package/templates/claude/package.json.tmpl +5 -5
- package/templates/claude/src/agent.ts +1 -0
- package/templates/codex/package.json.tmpl +4 -4
- package/templates/pi/package.json.tmpl +5 -5
- package/templates/pi/src/agent.ts +2 -1
- package/dist/setup-6Z34JJEB.js +0 -425
- package/dist/web-assets/assets/index-B3xLeex8.js +0 -75
- package/dist/web-assets/assets/index-Dr4A90Lo.css +0 -1
- package/packages/extensions/notes/dist/ui/assets/index-8jWEv9SA.js +0 -61
- package/packages/extensions/notes/dist/ui/assets/index-DkaB7Ytd.css +0 -1
- package/packages/extensions/pages/dist/ui/assets/index-D0HyS-xQ.css +0 -1
- package/packages/extensions/pages/dist/ui/assets/index-DKZLNMED.js +0 -2
- package/packages/extensions/plan/dist/ui/assets/index-CJj2gZnZ.css +0 -1
- package/packages/extensions/plan/dist/ui/assets/index-FMEJmvQz.js +0 -61
- package/dist/{chat-5Y4FD77E.js → chat-XL7CVWVJ.js} +0 -0
- package/dist/{chunk-MQRS4J24.js → chunk-LN67VPZJ.js} +3 -3
- package/dist/{service-YMHWPDXW.js → service-RH6Q2XWR.js} +4 -4
- package/dist/{status-MC2P7DBG.js → status-TGOKAFW3.js} +4 -4
- package/dist/{update-UOP2INF2.js → update-ZCTQ6UGY.js} +4 -4
|
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "volute",
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.38.0",
|
|
8
8
|
description: "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
|
|
9
9
|
type: "module",
|
|
10
10
|
license: "MIT",
|
|
@@ -68,42 +68,42 @@ var package_default = {
|
|
|
68
68
|
"db:migrate": "drizzle-kit migrate"
|
|
69
69
|
},
|
|
70
70
|
dependencies: {
|
|
71
|
-
"@anthropic-ai/sandbox-runtime": "^0.0.
|
|
72
|
-
"@hono/node-server": "^1.19.
|
|
71
|
+
"@anthropic-ai/sandbox-runtime": "^0.0.46",
|
|
72
|
+
"@hono/node-server": "^1.19.12",
|
|
73
73
|
"@hono/zod-validator": "^0.7.6",
|
|
74
|
-
"@libsql/client": "^0.17.
|
|
75
|
-
"@mariozechner/pi-ai": "^0.
|
|
74
|
+
"@libsql/client": "^0.17.2",
|
|
75
|
+
"@mariozechner/pi-ai": "^0.64.0",
|
|
76
76
|
"@slack/bolt": "^4.6.0",
|
|
77
|
-
"adm-zip": "^0.5.
|
|
77
|
+
"adm-zip": "^0.5.17",
|
|
78
78
|
bcryptjs: "^3.0.3",
|
|
79
79
|
"cron-parser": "^5.5.0",
|
|
80
|
-
"discord.js": "^14.
|
|
81
|
-
"drizzle-orm": "^0.45.
|
|
82
|
-
hono: "^4.
|
|
83
|
-
libsql: "^0.5.
|
|
80
|
+
"discord.js": "^14.26.0",
|
|
81
|
+
"drizzle-orm": "^0.45.2",
|
|
82
|
+
hono: "^4.12.9",
|
|
83
|
+
libsql: "^0.5.29",
|
|
84
84
|
replicate: "^1.4.0",
|
|
85
85
|
telegraf: "^4.16.3",
|
|
86
86
|
zod: "^4.3.6"
|
|
87
87
|
},
|
|
88
88
|
devDependencies: {
|
|
89
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.
|
|
90
|
-
"@biomejs/biome": "2.
|
|
91
|
-
"@mariozechner/pi-coding-agent": "^0.
|
|
92
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
93
|
-
"@types/adm-zip": "^0.5.
|
|
94
|
-
"@types/bcryptjs": "^
|
|
95
|
-
"@types/dompurify": "^3.0
|
|
96
|
-
"@types/node": "^25.
|
|
97
|
-
dompurify: "^3.3.
|
|
98
|
-
"drizzle-kit": "^0.31.
|
|
99
|
-
lefthook: "^2.1.
|
|
100
|
-
marked: "^17.0.
|
|
89
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.89",
|
|
90
|
+
"@biomejs/biome": "2.4.10",
|
|
91
|
+
"@mariozechner/pi-coding-agent": "^0.64.0",
|
|
92
|
+
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
93
|
+
"@types/adm-zip": "^0.5.8",
|
|
94
|
+
"@types/bcryptjs": "^3.0.0",
|
|
95
|
+
"@types/dompurify": "^3.2.0",
|
|
96
|
+
"@types/node": "^25.5.0",
|
|
97
|
+
dompurify: "^3.3.3",
|
|
98
|
+
"drizzle-kit": "^0.31.10",
|
|
99
|
+
lefthook: "^2.1.4",
|
|
100
|
+
marked: "^17.0.5",
|
|
101
101
|
sharp: "^0.34.5",
|
|
102
|
-
svelte: "^5.
|
|
103
|
-
tsup: "^8.
|
|
104
|
-
tsx: "^4.
|
|
105
|
-
typescript: "^
|
|
106
|
-
vite: "^
|
|
102
|
+
svelte: "^5.55.1",
|
|
103
|
+
tsup: "^8.5.1",
|
|
104
|
+
tsx: "^4.21.0",
|
|
105
|
+
typescript: "^6.0.2",
|
|
106
|
+
vite: "^8.0.3"
|
|
107
107
|
}
|
|
108
108
|
};
|
|
109
109
|
export {
|
|
@@ -3,11 +3,12 @@ import {
|
|
|
3
3
|
Scheduler,
|
|
4
4
|
getScheduler,
|
|
5
5
|
initScheduler
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TEZRVSSB.js";
|
|
7
7
|
import "./chunk-PMMHVSCR.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-2TR2OPVA.js";
|
|
9
9
|
import "./chunk-46DYYHN6.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-VUM2K6EN.js";
|
|
11
|
+
import "./chunk-5DPRTREW.js";
|
|
11
12
|
import "./chunk-CU6OFXMM.js";
|
|
12
13
|
import "./chunk-KXXJYY62.js";
|
|
13
14
|
import "./chunk-7AZQFSOV.js";
|
|
@@ -15,10 +16,9 @@ import "./chunk-GVVVMZ4J.js";
|
|
|
15
16
|
import "./chunk-3F7XK5Q7.js";
|
|
16
17
|
import "./chunk-SNW2NPP4.js";
|
|
17
18
|
import "./chunk-UIM5NHPP.js";
|
|
19
|
+
import "./chunk-N42QMDID.js";
|
|
18
20
|
import "./chunk-ORNY3MZR.js";
|
|
19
21
|
import "./chunk-A6FLW5XD.js";
|
|
20
|
-
import "./chunk-5DPRTREW.js";
|
|
21
|
-
import "./chunk-N42QMDID.js";
|
|
22
22
|
import "./chunk-T2TP6ZC6.js";
|
|
23
23
|
import "./chunk-2NHRJ3YO.js";
|
|
24
24
|
import "./chunk-CJ26DXZL.js";
|
|
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
|
|
|
4
4
|
// packages/cli/src/commands/seed.ts
|
|
5
5
|
async function run(args) {
|
|
6
6
|
console.error("Note: `volute mind seed` is now `volute seed create`");
|
|
7
|
-
await import("./seed-create-
|
|
7
|
+
await import("./seed-create-XXRRGZCO.js").then((m) => m.run(args));
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
10
10
|
run
|
|
@@ -12,11 +12,11 @@ var cmd = subcommands({
|
|
|
12
12
|
commands: {
|
|
13
13
|
create: {
|
|
14
14
|
description: "Plant a new seed",
|
|
15
|
-
run: (args) => import("./seed-create-
|
|
15
|
+
run: (args) => import("./seed-create-XXRRGZCO.js").then((m) => m.run(args))
|
|
16
16
|
},
|
|
17
17
|
sprout: {
|
|
18
18
|
description: "Complete orientation and become a full mind",
|
|
19
|
-
run: (args) => import("./seed-sprout-
|
|
19
|
+
run: (args) => import("./seed-sprout-HLMUH2AI.js").then((m) => m.run(args))
|
|
20
20
|
},
|
|
21
21
|
check: {
|
|
22
22
|
description: "Check seed readiness",
|
|
@@ -58,7 +58,7 @@ var cmd = command({
|
|
|
58
58
|
}
|
|
59
59
|
if (template !== "claude" && !model) {
|
|
60
60
|
if (process.env.VOLUTE_MIND || !process.stdin.isTTY) {
|
|
61
|
-
const { getSpiritModel } = await import("./spirit-
|
|
61
|
+
const { getSpiritModel } = await import("./spirit-ZFYG4JOH.js");
|
|
62
62
|
const { qualifyModelId } = await import("./ai-service-C2YNARGH.js");
|
|
63
63
|
const spiritModel = getSpiritModel();
|
|
64
64
|
if (spiritModel) {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import "./chunk-O7IGP7ZW.js";
|
|
9
9
|
import {
|
|
10
10
|
getStandardSkillsWithExtensions
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-VUM2K6EN.js";
|
|
12
12
|
import "./chunk-3F7XK5Q7.js";
|
|
13
13
|
import "./chunk-SNW2NPP4.js";
|
|
14
14
|
import "./chunk-A6FLW5XD.js";
|
|
@@ -74,7 +74,7 @@ var cmd = command({
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
const { getClient, urlOf } = await import("./api-client-LC5YRA32.js");
|
|
77
|
-
const { mindSkillsDir } = await import("./skills-
|
|
77
|
+
const { mindSkillsDir } = await import("./skills-NVOWS5NY.js");
|
|
78
78
|
const client = getClient();
|
|
79
79
|
const failedSkills = [];
|
|
80
80
|
for (const skillId of getStandardSkillsWithExtensions()) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
generateUserPlist,
|
|
4
|
+
generateUserUnit,
|
|
5
|
+
installUserService
|
|
6
|
+
} from "./chunk-JOJT34M2.js";
|
|
7
|
+
import "./chunk-TNZ5XQA4.js";
|
|
8
|
+
import "./chunk-3F7XK5Q7.js";
|
|
9
|
+
import "./chunk-SNW2NPP4.js";
|
|
10
|
+
import "./chunk-2NHRJ3YO.js";
|
|
11
|
+
import "./chunk-CJ26DXZL.js";
|
|
12
|
+
import "./chunk-K3NQKI34.js";
|
|
13
|
+
export {
|
|
14
|
+
generateUserPlist,
|
|
15
|
+
generateUserUnit,
|
|
16
|
+
installUserService
|
|
17
|
+
};
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
promptLine
|
|
4
|
+
} from "./chunk-VHWGEJ4V.js";
|
|
5
|
+
import {
|
|
6
|
+
command
|
|
7
|
+
} from "./chunk-TXSA4Q3V.js";
|
|
8
|
+
import "./chunk-O7IGP7ZW.js";
|
|
9
|
+
import {
|
|
10
|
+
installUserService
|
|
11
|
+
} from "./chunk-JOJT34M2.js";
|
|
12
|
+
import {
|
|
13
|
+
LAUNCHD_PLIST_LABEL,
|
|
14
|
+
SYSTEM_LAUNCHD_PLIST_PATH,
|
|
15
|
+
SYSTEM_SERVICE_PATH
|
|
16
|
+
} from "./chunk-TNZ5XQA4.js";
|
|
17
|
+
import {
|
|
18
|
+
resolveVoluteBin
|
|
19
|
+
} from "./chunk-3F7XK5Q7.js";
|
|
20
|
+
import {
|
|
21
|
+
ensureVoluteGroup
|
|
22
|
+
} from "./chunk-SNW2NPP4.js";
|
|
23
|
+
import {
|
|
24
|
+
readGlobalConfig,
|
|
25
|
+
writeGlobalConfig
|
|
26
|
+
} from "./chunk-A6FLW5XD.js";
|
|
27
|
+
import "./chunk-2NHRJ3YO.js";
|
|
28
|
+
import "./chunk-CJ26DXZL.js";
|
|
29
|
+
import "./chunk-K3NQKI34.js";
|
|
30
|
+
|
|
31
|
+
// src/commands/setup.ts
|
|
32
|
+
import { execFileSync, spawn } from "child_process";
|
|
33
|
+
import { mkdirSync, writeFileSync } from "fs";
|
|
34
|
+
import { homedir } from "os";
|
|
35
|
+
import { dirname, resolve } from "path";
|
|
36
|
+
var HOST_RE = /^[a-zA-Z0-9.:_-]+$/;
|
|
37
|
+
function validateHost(host) {
|
|
38
|
+
if (!HOST_RE.test(host)) {
|
|
39
|
+
throw new Error(`Invalid host: ${host}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function escapeXml(s) {
|
|
43
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
44
|
+
}
|
|
45
|
+
function buildServicePath(voluteBin) {
|
|
46
|
+
const binDir = dirname(voluteBin);
|
|
47
|
+
const standardPaths = [
|
|
48
|
+
"/usr/local/sbin",
|
|
49
|
+
"/usr/local/bin",
|
|
50
|
+
"/usr/sbin",
|
|
51
|
+
"/usr/bin",
|
|
52
|
+
"/sbin",
|
|
53
|
+
"/bin"
|
|
54
|
+
];
|
|
55
|
+
const parts = standardPaths.includes(binDir) ? standardPaths : [binDir, ...standardPaths];
|
|
56
|
+
return parts.join(":");
|
|
57
|
+
}
|
|
58
|
+
function generateSystemPlist(voluteBin, opts) {
|
|
59
|
+
const args = ["up", "--foreground"];
|
|
60
|
+
if (opts?.port != null) args.push("--port", String(opts.port));
|
|
61
|
+
if (opts?.host) args.push("--host", opts.host);
|
|
62
|
+
const logPath = "/var/lib/volute/system/daemon.log";
|
|
63
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
64
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
65
|
+
<plist version="1.0">
|
|
66
|
+
<dict>
|
|
67
|
+
<key>Label</key>
|
|
68
|
+
<string>${LAUNCHD_PLIST_LABEL}</string>
|
|
69
|
+
<key>ProgramArguments</key>
|
|
70
|
+
<array>
|
|
71
|
+
${[voluteBin, ...args].map((a) => `<string>${escapeXml(a)}</string>`).join("\n ")}
|
|
72
|
+
</array>
|
|
73
|
+
<key>EnvironmentVariables</key>
|
|
74
|
+
<dict>
|
|
75
|
+
<key>PATH</key>
|
|
76
|
+
<string>${escapeXml(buildServicePath(voluteBin))}</string>
|
|
77
|
+
<key>VOLUTE_HOME</key>
|
|
78
|
+
<string>/var/lib/volute</string>
|
|
79
|
+
<key>VOLUTE_MINDS_DIR</key>
|
|
80
|
+
<string>${MINDS_DIR}</string>
|
|
81
|
+
<key>VOLUTE_ISOLATION</key>
|
|
82
|
+
<string>user</string>
|
|
83
|
+
</dict>
|
|
84
|
+
<key>RunAtLoad</key>
|
|
85
|
+
<true/>
|
|
86
|
+
<key>KeepAlive</key>
|
|
87
|
+
<true/>
|
|
88
|
+
<key>StandardOutPath</key>
|
|
89
|
+
<string>${logPath}</string>
|
|
90
|
+
<key>StandardErrorPath</key>
|
|
91
|
+
<string>${logPath}</string>
|
|
92
|
+
</dict>
|
|
93
|
+
</plist>`;
|
|
94
|
+
}
|
|
95
|
+
function generateSystemUnit(voluteBin, port, host) {
|
|
96
|
+
const args = ["up", "--foreground"];
|
|
97
|
+
if (port != null) args.push("--port", String(port));
|
|
98
|
+
if (host) args.push("--host", host);
|
|
99
|
+
const home = homedir();
|
|
100
|
+
const binUnderHome = voluteBin.startsWith(`${home}/`);
|
|
101
|
+
const lines = [
|
|
102
|
+
"[Unit]",
|
|
103
|
+
"Description=Volute Mind Manager",
|
|
104
|
+
"After=network.target",
|
|
105
|
+
"",
|
|
106
|
+
"[Service]",
|
|
107
|
+
"Type=exec",
|
|
108
|
+
`ExecStart=${voluteBin} ${args.join(" ")}`,
|
|
109
|
+
`Environment=PATH=${buildServicePath(voluteBin)}`,
|
|
110
|
+
"Environment=VOLUTE_HOME=/var/lib/volute",
|
|
111
|
+
"Environment=VOLUTE_MINDS_DIR=/minds",
|
|
112
|
+
"Environment=VOLUTE_ISOLATION=user",
|
|
113
|
+
"Restart=on-failure",
|
|
114
|
+
"RestartSec=5",
|
|
115
|
+
"ProtectSystem=true",
|
|
116
|
+
"ReadWritePaths=/var/lib/volute /minds",
|
|
117
|
+
"PrivateTmp=yes"
|
|
118
|
+
];
|
|
119
|
+
if (!binUnderHome) {
|
|
120
|
+
lines.push("ProtectHome=yes");
|
|
121
|
+
}
|
|
122
|
+
lines.push("RestrictSUIDSGID=yes", "", "[Install]", "WantedBy=multi-user.target", "");
|
|
123
|
+
return lines.join("\n");
|
|
124
|
+
}
|
|
125
|
+
var DATA_DIR = "/var/lib/volute";
|
|
126
|
+
var MINDS_DIR = process.platform === "darwin" ? "/var/lib/volute/minds" : "/minds";
|
|
127
|
+
var PROFILE_PATH = "/etc/profile.d/volute.sh";
|
|
128
|
+
var WRAPPER_PATH = "/usr/local/bin/volute";
|
|
129
|
+
function installSystemService(voluteBin, port, host) {
|
|
130
|
+
const platform = process.platform;
|
|
131
|
+
if (platform === "darwin") {
|
|
132
|
+
writeFileSync(
|
|
133
|
+
SYSTEM_LAUNCHD_PLIST_PATH,
|
|
134
|
+
generateSystemPlist(voluteBin, { port, host: host ?? "0.0.0.0" })
|
|
135
|
+
);
|
|
136
|
+
console.log(` Wrote ${SYSTEM_LAUNCHD_PLIST_PATH}`);
|
|
137
|
+
try {
|
|
138
|
+
try {
|
|
139
|
+
execFileSync("launchctl", ["bootout", `system/${LAUNCHD_PLIST_LABEL}`]);
|
|
140
|
+
} catch {
|
|
141
|
+
}
|
|
142
|
+
execFileSync("launchctl", ["bootstrap", "system", SYSTEM_LAUNCHD_PLIST_PATH]);
|
|
143
|
+
console.log(" Service installed (LaunchDaemon)");
|
|
144
|
+
return true;
|
|
145
|
+
} catch (err) {
|
|
146
|
+
console.warn(
|
|
147
|
+
` Warning: failed to load LaunchDaemon: ${err instanceof Error ? err.message : err}`
|
|
148
|
+
);
|
|
149
|
+
console.warn(
|
|
150
|
+
" Try: sudo launchctl bootstrap system /Library/LaunchDaemons/com.volute.daemon.plist"
|
|
151
|
+
);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
} else if (platform === "linux") {
|
|
155
|
+
writeFileSync(SYSTEM_SERVICE_PATH, generateSystemUnit(voluteBin, port, host ?? "0.0.0.0"));
|
|
156
|
+
console.log(` Wrote ${SYSTEM_SERVICE_PATH}`);
|
|
157
|
+
try {
|
|
158
|
+
execFileSync("systemctl", ["daemon-reload"]);
|
|
159
|
+
execFileSync("systemctl", ["enable", "--now", "volute"]);
|
|
160
|
+
console.log(" Service installed (systemd)");
|
|
161
|
+
return true;
|
|
162
|
+
} catch (err) {
|
|
163
|
+
console.warn(
|
|
164
|
+
` Warning: failed to enable service: ${err instanceof Error ? err.message : err}`
|
|
165
|
+
);
|
|
166
|
+
console.warn(" Try: systemctl daemon-reload && systemctl enable --now volute");
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
function setupSystemDirectories() {
|
|
173
|
+
mkdirSync(DATA_DIR, { recursive: true });
|
|
174
|
+
console.log(` Created ${DATA_DIR}`);
|
|
175
|
+
mkdirSync(MINDS_DIR, { recursive: true });
|
|
176
|
+
console.log(` Created ${MINDS_DIR}`);
|
|
177
|
+
execFileSync("chmod", ["755", DATA_DIR]);
|
|
178
|
+
execFileSync("chmod", ["755", MINDS_DIR]);
|
|
179
|
+
}
|
|
180
|
+
function setupSystemGitIdentity() {
|
|
181
|
+
try {
|
|
182
|
+
execFileSync("git", ["config", "--system", "user.name"]);
|
|
183
|
+
console.log(" System git identity already configured");
|
|
184
|
+
} catch {
|
|
185
|
+
try {
|
|
186
|
+
execFileSync("git", ["config", "--system", "user.name", "Volute"]);
|
|
187
|
+
execFileSync("git", ["config", "--system", "user.email", "volute@localhost"]);
|
|
188
|
+
console.log(" Configured system git identity");
|
|
189
|
+
} catch (err) {
|
|
190
|
+
console.warn(
|
|
191
|
+
` Warning: failed to set system git config: ${err instanceof Error ? err.message : err}`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function setupSystemWrapper(voluteBin) {
|
|
197
|
+
const binDir = dirname(voluteBin);
|
|
198
|
+
if (voluteBin !== WRAPPER_PATH && !voluteBin.startsWith("/usr/bin")) {
|
|
199
|
+
const wrapper = `#!/bin/sh
|
|
200
|
+
export PATH="${binDir}:$PATH"
|
|
201
|
+
export VOLUTE_HOME="${DATA_DIR}"
|
|
202
|
+
export VOLUTE_MINDS_DIR="${MINDS_DIR}"
|
|
203
|
+
exec "${voluteBin}" "$@"
|
|
204
|
+
`;
|
|
205
|
+
writeFileSync(WRAPPER_PATH, wrapper, { mode: 493 });
|
|
206
|
+
console.log(` Wrote ${WRAPPER_PATH}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function setupSystemEnvProfile() {
|
|
210
|
+
if (process.platform === "linux") {
|
|
211
|
+
writeFileSync(
|
|
212
|
+
PROFILE_PATH,
|
|
213
|
+
`export VOLUTE_HOME=${DATA_DIR}
|
|
214
|
+
export VOLUTE_MINDS_DIR=${MINDS_DIR}
|
|
215
|
+
`
|
|
216
|
+
);
|
|
217
|
+
console.log(` Wrote ${PROFILE_PATH}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async function startDaemonAndOpenBrowser(port, host) {
|
|
221
|
+
const displayPort = port ?? 1618;
|
|
222
|
+
const displayHost = host ?? "127.0.0.1";
|
|
223
|
+
const url = `http://${displayHost === "0.0.0.0" || displayHost === "::" ? "localhost" : displayHost}:${displayPort}`;
|
|
224
|
+
console.log("\nStarting daemon...");
|
|
225
|
+
try {
|
|
226
|
+
const { run: runUp } = await import("./up-YRZAEZ3Z.js");
|
|
227
|
+
await runUp([
|
|
228
|
+
...port != null ? ["--port", String(port)] : [],
|
|
229
|
+
...host ? ["--host", host] : []
|
|
230
|
+
]);
|
|
231
|
+
const openCmd = process.platform === "darwin" ? "open" : "xdg-open";
|
|
232
|
+
spawn(openCmd, [url], { stdio: "ignore", detached: true }).unref();
|
|
233
|
+
} catch (err) {
|
|
234
|
+
console.error(`
|
|
235
|
+
Failed to start daemon: ${err instanceof Error ? err.message : err}`);
|
|
236
|
+
console.error("You can start it manually with: volute up");
|
|
237
|
+
}
|
|
238
|
+
console.log(`
|
|
239
|
+
Open ${url} to continue setup.`);
|
|
240
|
+
}
|
|
241
|
+
var cmd = command({
|
|
242
|
+
name: "volute setup",
|
|
243
|
+
description: "First-time Volute setup",
|
|
244
|
+
flags: {
|
|
245
|
+
cli: { type: "boolean", description: "Use interactive CLI setup" },
|
|
246
|
+
name: { type: "string", description: "System name (implies --cli)" },
|
|
247
|
+
system: { type: "boolean", description: "System-level install (requires sudo)" },
|
|
248
|
+
service: { type: "boolean", description: "Install as service" },
|
|
249
|
+
remote: { type: "boolean", description: "Allow access from other devices" },
|
|
250
|
+
dir: { type: "string", description: "Data directory" },
|
|
251
|
+
port: { type: "number", description: "Daemon port" },
|
|
252
|
+
host: { type: "string", description: "Daemon host" }
|
|
253
|
+
},
|
|
254
|
+
run: async ({ flags }) => {
|
|
255
|
+
const port = flags.port;
|
|
256
|
+
let host = flags.host;
|
|
257
|
+
if (flags.system && !flags.cli && !flags.name) {
|
|
258
|
+
if (process.getuid?.() !== 0) {
|
|
259
|
+
console.error("System install requires root. Re-run with sudo.");
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
262
|
+
if (host) validateHost(host);
|
|
263
|
+
host = host ?? "0.0.0.0";
|
|
264
|
+
console.log("Setting up system directories...");
|
|
265
|
+
process.env.VOLUTE_HOME = DATA_DIR;
|
|
266
|
+
process.env.VOLUTE_MINDS_DIR = MINDS_DIR;
|
|
267
|
+
setupSystemDirectories();
|
|
268
|
+
ensureVoluteGroup({ force: true });
|
|
269
|
+
console.log(" Ensured volute group exists");
|
|
270
|
+
setupSystemGitIdentity();
|
|
271
|
+
const voluteBin = resolveVoluteBin();
|
|
272
|
+
setupSystemWrapper(voluteBin);
|
|
273
|
+
setupSystemEnvProfile();
|
|
274
|
+
let wantService = flags.service ?? true;
|
|
275
|
+
let serviceStartedDaemon = false;
|
|
276
|
+
if (wantService) {
|
|
277
|
+
if (installSystemService(voluteBin, port, host)) {
|
|
278
|
+
serviceStartedDaemon = true;
|
|
279
|
+
} else {
|
|
280
|
+
wantService = false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const existingConfig2 = readGlobalConfig();
|
|
284
|
+
const setup = {
|
|
285
|
+
type: "system",
|
|
286
|
+
mindsDir: MINDS_DIR,
|
|
287
|
+
isolation: "user",
|
|
288
|
+
service: wantService
|
|
289
|
+
};
|
|
290
|
+
const config = { ...existingConfig2, setup, setupCompleted: false };
|
|
291
|
+
if (port != null) config.port = port;
|
|
292
|
+
config.hostname = host;
|
|
293
|
+
writeGlobalConfig(config);
|
|
294
|
+
if (serviceStartedDaemon) {
|
|
295
|
+
const displayPort = port ?? 1618;
|
|
296
|
+
const url = `http://localhost:${displayPort}`;
|
|
297
|
+
const openCmd = process.platform === "darwin" ? "open" : "xdg-open";
|
|
298
|
+
spawn(openCmd, [url], { stdio: "ignore", detached: true }).unref();
|
|
299
|
+
console.log(`
|
|
300
|
+
Open ${url} to continue setup.`);
|
|
301
|
+
} else {
|
|
302
|
+
await startDaemonAndOpenBrowser(port, host);
|
|
303
|
+
}
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (flags.cli || flags.name) {
|
|
307
|
+
const isInteractive = !flags.name && process.stdin.isTTY;
|
|
308
|
+
let systemName;
|
|
309
|
+
let setupType;
|
|
310
|
+
let wantService;
|
|
311
|
+
let wantRemote = flags.remote ?? false;
|
|
312
|
+
if (isInteractive) {
|
|
313
|
+
console.log("Welcome to Volute!\n");
|
|
314
|
+
systemName = await promptLine("System name: ");
|
|
315
|
+
if (!systemName.trim()) {
|
|
316
|
+
console.error("System name is required.");
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
systemName = systemName.trim();
|
|
320
|
+
console.log("\nInstall type:");
|
|
321
|
+
console.log(" 1. Local (minds in ~/.volute/minds/, sandbox isolation)");
|
|
322
|
+
console.log(` 2. System (minds in ${MINDS_DIR}, per-user isolation, requires sudo)`);
|
|
323
|
+
const typeChoice = await promptLine("> ");
|
|
324
|
+
setupType = typeChoice.trim() === "2" ? "system" : "local";
|
|
325
|
+
if (setupType === "system" && process.getuid?.() !== 0) {
|
|
326
|
+
console.error("\nSystem install requires root. Re-run with sudo.");
|
|
327
|
+
process.exit(1);
|
|
328
|
+
}
|
|
329
|
+
if (!host) {
|
|
330
|
+
const remoteAnswer = (await promptLine("\nAllow access from other devices on the network? [y/N]: ")).trim().toLowerCase();
|
|
331
|
+
if (remoteAnswer === "y" || remoteAnswer === "yes") {
|
|
332
|
+
wantRemote = true;
|
|
333
|
+
host = "0.0.0.0";
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const serviceDefault = setupType === "system" ? "Y/n" : "y/N";
|
|
337
|
+
const servicePrompt = `
|
|
338
|
+
Install as a service (auto-start on boot)? [${serviceDefault}]: `;
|
|
339
|
+
const serviceAnswer = (await promptLine(servicePrompt)).trim().toLowerCase();
|
|
340
|
+
if (setupType === "system") {
|
|
341
|
+
wantService = serviceAnswer !== "n";
|
|
342
|
+
} else {
|
|
343
|
+
wantService = serviceAnswer === "y" || serviceAnswer === "yes";
|
|
344
|
+
}
|
|
345
|
+
} else {
|
|
346
|
+
if (!flags.name) {
|
|
347
|
+
console.error("Error: --name is required in non-interactive mode.");
|
|
348
|
+
console.error(
|
|
349
|
+
"Usage: volute setup --name <name> [--system] [--service] [--remote] [--dir <path>]"
|
|
350
|
+
);
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
systemName = flags.name;
|
|
354
|
+
setupType = flags.system ? "system" : "local";
|
|
355
|
+
wantService = flags.service ?? setupType === "system";
|
|
356
|
+
if (wantRemote && !host) {
|
|
357
|
+
host = "0.0.0.0";
|
|
358
|
+
}
|
|
359
|
+
if (setupType === "system" && process.getuid?.() !== 0) {
|
|
360
|
+
console.error("Error: system install requires root (use sudo).");
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (host) validateHost(host);
|
|
365
|
+
console.log("\nSetting up...");
|
|
366
|
+
let isolation;
|
|
367
|
+
let mindsDir2;
|
|
368
|
+
let configHome2;
|
|
369
|
+
if (setupType === "system") {
|
|
370
|
+
configHome2 = DATA_DIR;
|
|
371
|
+
mindsDir2 = MINDS_DIR;
|
|
372
|
+
isolation = "user";
|
|
373
|
+
process.env.VOLUTE_HOME = DATA_DIR;
|
|
374
|
+
process.env.VOLUTE_MINDS_DIR = MINDS_DIR;
|
|
375
|
+
setupSystemDirectories();
|
|
376
|
+
ensureVoluteGroup({ force: true });
|
|
377
|
+
console.log(" Ensured volute group exists");
|
|
378
|
+
setupSystemGitIdentity();
|
|
379
|
+
const voluteBin = resolveVoluteBin();
|
|
380
|
+
setupSystemWrapper(voluteBin);
|
|
381
|
+
setupSystemEnvProfile();
|
|
382
|
+
if (wantService) {
|
|
383
|
+
if (!installSystemService(voluteBin, port, host)) wantService = false;
|
|
384
|
+
}
|
|
385
|
+
} else {
|
|
386
|
+
configHome2 = flags.dir ? resolve(flags.dir) : resolve(homedir(), ".volute");
|
|
387
|
+
if (flags.dir) {
|
|
388
|
+
process.env.VOLUTE_HOME = configHome2;
|
|
389
|
+
}
|
|
390
|
+
mindsDir2 = resolve(configHome2, "minds");
|
|
391
|
+
isolation = "sandbox";
|
|
392
|
+
mkdirSync(configHome2, { recursive: true });
|
|
393
|
+
console.log(` Created ${configHome2}`);
|
|
394
|
+
mkdirSync(mindsDir2, { recursive: true });
|
|
395
|
+
console.log(" Sandbox enabled for mind isolation");
|
|
396
|
+
if (wantService) {
|
|
397
|
+
try {
|
|
398
|
+
await installUserService(port, host);
|
|
399
|
+
} catch (err) {
|
|
400
|
+
console.warn(
|
|
401
|
+
` Warning: failed to install service: ${err instanceof Error ? err.message : err}`
|
|
402
|
+
);
|
|
403
|
+
console.warn(" You can start Volute manually with: volute up");
|
|
404
|
+
wantService = false;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
const existingConfig2 = readGlobalConfig();
|
|
409
|
+
const setup = {
|
|
410
|
+
type: setupType,
|
|
411
|
+
mindsDir: mindsDir2,
|
|
412
|
+
isolation,
|
|
413
|
+
service: wantService
|
|
414
|
+
};
|
|
415
|
+
const config = {
|
|
416
|
+
...existingConfig2,
|
|
417
|
+
name: systemName,
|
|
418
|
+
setup,
|
|
419
|
+
setupCompleted: false
|
|
420
|
+
};
|
|
421
|
+
if (port != null) config.port = port;
|
|
422
|
+
if (host) config.hostname = host;
|
|
423
|
+
writeGlobalConfig(config);
|
|
424
|
+
await startDaemonAndOpenBrowser(port, host);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (host) validateHost(host);
|
|
428
|
+
const configHome = flags.dir ? resolve(flags.dir) : resolve(homedir(), ".volute");
|
|
429
|
+
if (flags.dir) {
|
|
430
|
+
process.env.VOLUTE_HOME = configHome;
|
|
431
|
+
}
|
|
432
|
+
const mindsDir = resolve(configHome, "minds");
|
|
433
|
+
mkdirSync(configHome, { recursive: true });
|
|
434
|
+
mkdirSync(mindsDir, { recursive: true });
|
|
435
|
+
const existingConfig = readGlobalConfig();
|
|
436
|
+
if (!existingConfig.setup) {
|
|
437
|
+
const setup = {
|
|
438
|
+
type: "local",
|
|
439
|
+
mindsDir,
|
|
440
|
+
isolation: "sandbox",
|
|
441
|
+
service: false
|
|
442
|
+
};
|
|
443
|
+
const config = { ...existingConfig, setup, setupCompleted: false };
|
|
444
|
+
if (port != null) config.port = port;
|
|
445
|
+
if (host) config.hostname = host;
|
|
446
|
+
writeGlobalConfig(config);
|
|
447
|
+
}
|
|
448
|
+
await startDaemonAndOpenBrowser(port, host);
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
var run = cmd.execute;
|
|
452
|
+
export {
|
|
453
|
+
run
|
|
454
|
+
};
|
|
@@ -5,11 +5,12 @@ import {
|
|
|
5
5
|
getSleepManagerIfReady,
|
|
6
6
|
initSleepManager,
|
|
7
7
|
matchesGlob
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TEZRVSSB.js";
|
|
9
9
|
import "./chunk-PMMHVSCR.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-2TR2OPVA.js";
|
|
11
11
|
import "./chunk-46DYYHN6.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-VUM2K6EN.js";
|
|
13
|
+
import "./chunk-5DPRTREW.js";
|
|
13
14
|
import "./chunk-CU6OFXMM.js";
|
|
14
15
|
import "./chunk-KXXJYY62.js";
|
|
15
16
|
import "./chunk-7AZQFSOV.js";
|
|
@@ -17,10 +18,9 @@ import "./chunk-GVVVMZ4J.js";
|
|
|
17
18
|
import "./chunk-3F7XK5Q7.js";
|
|
18
19
|
import "./chunk-SNW2NPP4.js";
|
|
19
20
|
import "./chunk-UIM5NHPP.js";
|
|
21
|
+
import "./chunk-N42QMDID.js";
|
|
20
22
|
import "./chunk-ORNY3MZR.js";
|
|
21
23
|
import "./chunk-A6FLW5XD.js";
|
|
22
|
-
import "./chunk-5DPRTREW.js";
|
|
23
|
-
import "./chunk-N42QMDID.js";
|
|
24
24
|
import "./chunk-T2TP6ZC6.js";
|
|
25
25
|
import "./chunk-2NHRJ3YO.js";
|
|
26
26
|
import "./chunk-CJ26DXZL.js";
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
getSpiritModel,
|
|
5
5
|
spiritDir,
|
|
6
6
|
syncSpiritTemplate
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-2TR2OPVA.js";
|
|
8
8
|
import "./chunk-46DYYHN6.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-VUM2K6EN.js";
|
|
10
10
|
import "./chunk-CU6OFXMM.js";
|
|
11
11
|
import "./chunk-3F7XK5Q7.js";
|
|
12
12
|
import "./chunk-SNW2NPP4.js";
|