volute 0.49.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{accept-KYNC5X3U.js → accept-5NK5XJB5.js} +2 -1
- package/dist/{activity-events-GJJAI2WT.js → activity-events-H7YI3BTF.js} +3 -3
- package/dist/{ai-service-A7FS7EC3.js → ai-service-V4CTNGI3.js} +5 -4
- package/dist/{archive-7E3YE6VF.js → archive-ORM3ENHI.js} +3 -3
- package/dist/{auth-ABYLOEZ7.js → auth-DT7GY7EZ.js} +10 -6
- package/dist/{avatar-image-6ATV2IOZ.js → avatar-image-QEPAP3A5.js} +3 -3
- package/dist/{backup-XYAMT4CU.js → backup-IE6PMXJO.js} +11 -12
- package/dist/{bridge-3FNSWLNQ.js → bridge-YK7NTRU5.js} +2 -1
- package/dist/{channels-SGQZHNQJ.js → channels-FSAHOQWI.js} +2 -1
- package/dist/{chat-OGXAEXMV.js → chat-W5K6HCBE.js} +9 -9
- package/dist/{chunk-3B427GUK.js → chunk-3BAFMGCJ.js} +2 -2
- package/dist/{chunk-4B62E4CG.js → chunk-4CN7OCJE.js} +2 -2
- package/dist/{chunk-VNRSXEBF.js → chunk-574M6I7F.js} +38 -5
- package/dist/{chunk-HCYQRME2.js → chunk-5FVANDON.js} +2 -2
- package/dist/{chunk-P4LHVRNE.js → chunk-5IIVOWSP.js} +27 -19
- package/dist/{chunk-TXJL36ZQ.js → chunk-5PKFJHCR.js} +2 -2
- package/dist/{chunk-JPGHSXSV.js → chunk-5TPC4KCV.js} +23 -9
- package/dist/{chunk-YIJGKHIS.js → chunk-632FJ23O.js} +24 -20
- package/dist/{chunk-IH5TKXX6.js → chunk-636GFQNE.js} +11 -11
- package/dist/{chunk-EFT2OALG.js → chunk-6BM2I736.js} +20 -5
- package/dist/{chunk-JCBPU57A.js → chunk-74T3CEXK.js} +6 -6
- package/dist/{chunk-EG5LSKHU.js → chunk-77IZUVBB.js} +2 -2
- package/dist/{chunk-K3JOLGWF.js → chunk-7DXLIYPY.js} +76 -63
- package/dist/chunk-7FDWPQCU.js +289 -0
- package/dist/chunk-7OZWKHA3.js +548 -0
- package/dist/{chunk-PY24ZL62.js → chunk-7UWXAJMK.js} +1 -1
- package/dist/{chunk-MG3Z34YE.js → chunk-7XDOTN4R.js} +1 -1
- package/dist/{chunk-SX72DOO3.js → chunk-AFSLNUTT.js} +1 -1
- package/dist/{chunk-DVN6DNMI.js → chunk-AJWFDIEY.js} +17 -2
- package/dist/chunk-ALIVXDM4.js +1014 -0
- package/dist/{chunk-RSBL3FAD.js → chunk-CAIYV33P.js} +234 -24
- package/dist/{chunk-ZX46PGCC.js → chunk-E5S3ILVA.js} +1 -1
- package/dist/{chunk-SHKM5RGD.js → chunk-EEOMA4DX.js} +1 -1
- package/dist/chunk-EQKSRVDE.js +2857 -0
- package/dist/chunk-FNJCBRD3.js +31 -0
- package/dist/{chunk-EADX54RG.js → chunk-HW6Q7AMB.js} +4 -4
- package/dist/chunk-JI67D7O2.js +1222 -0
- package/dist/{chunk-KHCKZ36O.js → chunk-KAEZOVP6.js} +1 -1
- package/dist/chunk-LNNI3MS4.js +54 -0
- package/dist/{chunk-BCG45AQB.js → chunk-M74I3HHF.js} +15 -5
- package/dist/chunk-MLZBBLMT.js +109 -0
- package/dist/{chunk-5T5YMX6S.js → chunk-PW65BXY5.js} +5 -0
- package/dist/{chunk-NOIAHMJB.js → chunk-QFVGPKJI.js} +1 -1
- package/dist/{chunk-VIUH5CHQ.js → chunk-SFRYRW37.js} +50 -33
- package/dist/{chunk-L27YYONJ.js → chunk-SSNZ6ZNN.js} +1 -1
- package/dist/{chunk-GWVFDUNB.js → chunk-TGJHGVBZ.js} +8 -10
- package/dist/{chunk-6HGEZJDH.js → chunk-U3EJJ7JN.js} +2 -2
- package/dist/{chunk-4DSGN4FL.js → chunk-UC6BNMGT.js} +43 -13
- package/dist/{chunk-JBIFXB6I.js → chunk-WBBKYUGF.js} +3 -5
- package/dist/{chunk-FBBS4BVR.js → chunk-X67VT4QO.js} +1 -1
- package/dist/{chunk-DAIIMBLB.js → chunk-YQOYZ6G7.js} +3 -5
- package/dist/{chunk-JCWB2ITW.js → chunk-ZUG76D3P.js} +35 -5
- package/dist/cli.js +34 -27
- package/dist/{clock-6JZL2FS6.js → clock-LH7UFNLJ.js} +4 -3
- package/dist/{cloud-sync-VFDTNNCA.js → cloud-sync-IDJFVDEP.js} +22 -19
- package/dist/{config-RPSLA2HX.js → config-UGJS57VT.js} +3 -3
- package/dist/{conversations-TUM5PJJ4.js → conversations-S2232Y5I.js} +8 -4
- package/dist/{create-Z5FSDNVZ.js → create-2M7DAHQX.js} +2 -2
- package/dist/{create-VIQVP3QB.js → create-M727VUDF.js} +2 -1
- package/dist/{daemon-client-ZFY5MOAL.js → daemon-client-VVYFZI2D.js} +2 -1
- package/dist/{daemon-restart-54L4B6AQ.js → daemon-restart-2AAGYFHE.js} +6 -7
- package/dist/daemon.js +1625 -529
- package/dist/{db-F6UMFRYD.js → db-QAY45Z56.js} +2 -2
- package/dist/{delete-ESEP7NGQ.js → delete-O7PEFQDF.js} +1 -1
- package/dist/delivery-manager-B4OKWD2P.js +33 -0
- package/dist/{delivery-router-VUOL5YSA.js → delivery-router-JE7SHYNU.js} +7 -5
- package/dist/{down-6X7KX7BZ.js → down-D4IRNEMJ.js} +5 -5
- package/dist/echo-text-WYAAODBV.js +39 -0
- package/dist/{env-ZYMSCB7B.js → env-ABM5IMA7.js} +3 -2
- package/dist/{env-KUL4XKN2.js → env-AZK5X4W7.js} +3 -3
- package/dist/{exec-FBXA3CM4.js → exec-2H65LMTA.js} +3 -3
- package/dist/{export-TNBPDH77.js → export-3E3EL6W3.js} +4 -4
- package/dist/{extension-J4ZQ2GHV.js → extension-MRYJWSMV.js} +2 -1
- package/dist/{extensions-AWNO3SZF.js → extensions-7KP3X6G7.js} +22 -19
- package/dist/{files-BVBRJJ2P.js → files-6BMKVG5G.js} +5 -4
- package/dist/{import-ZUNKMCKC.js → import-UPNTEBBT.js} +8 -8
- package/dist/{isolation-OPCZQRTH.js → isolation-OKDFM6WA.js} +5 -3
- package/dist/{join-34TR2GXQ.js → join-PYA36HEC.js} +1 -1
- package/dist/{list-PMUXZNAM.js → list-4BVGH7AN.js} +8 -3
- package/dist/{login-KAKNFCW5.js → login-MOXVLULE.js} +4 -3
- package/dist/{login-LKNLCJPA.js → login-RJJTCVR3.js} +2 -1
- package/dist/{logout-YZRMZ3O2.js → logout-BYV433X6.js} +2 -1
- package/dist/{logout-RLT62RQP.js → logout-DWD3OQVT.js} +4 -3
- package/dist/message-delivery-3456PXB7.js +43 -0
- package/dist/migrate-thread-config-4A5LW36Z.js +90 -0
- package/dist/{mind-IF6CGMFW.js → mind-NYRALSV2.js} +19 -19
- package/dist/{mind-activity-tracker-YMMERB6B.js → mind-activity-tracker-L7GCYXQR.js} +4 -4
- package/dist/{mind-contacts-BKUFPUCU.js → mind-contacts-QYU4TPEA.js} +3 -2
- package/dist/{mind-history-WI5OI3BW.js → mind-history-NXXOOTX6.js} +30 -7
- package/dist/{mind-list-OTHV4ZO4.js → mind-list-SYRA7CH5.js} +3 -2
- package/dist/{mind-profile-LUG353ZT.js → mind-profile-MRCVZPYT.js} +1 -1
- package/dist/mind-service-5TA7UJAT.js +47 -0
- package/dist/{mind-sleep-VBV7YRSU.js → mind-sleep-TH6BRQ5X.js} +4 -3
- package/dist/{mind-status-BJNPGXKC.js → mind-status-Z2LQFA6F.js} +3 -2
- package/dist/{mind-wake-LVTZ55EZ.js → mind-wake-LDGPRA42.js} +2 -1
- package/dist/{package-PD67VPHB.js → package-XYSV7NUT.js} +23 -23
- package/dist/{prompts-MDHDLWEX.js → prompts-QKFPX6DQ.js} +3 -3
- package/dist/{read-YSWUXYL7.js → read-ZXGUT4QC.js} +5 -3
- package/dist/{register-TWQDKQRT.js → register-OX4HRSGC.js} +2 -1
- package/dist/{registry-3ELJPUGJ.js → registry-4UF6OCOE.js} +6 -4
- package/dist/{reject-SXGCYN4A.js → reject-TWB4QJHG.js} +2 -1
- package/dist/{restart-5F5QDBOG.js → restart-AGEGNSYQ.js} +2 -1
- package/dist/{sandbox-XPYA7UIF.js → sandbox-EGEU5GGE.js} +7 -4
- package/dist/scheduler-UV6RUJ7P.js +25 -0
- package/dist/{schema-6YONVTKZ.js → schema-C2GIPD4V.js} +3 -3
- package/dist/{seed-NQED7PSX.js → seed-3IMBOAGK.js} +1 -1
- package/dist/{seed-check-TYD7RRZY.js → seed-check-NRJEQZST.js} +14 -5
- package/dist/{seed-cmd-QF3F2G4S.js → seed-cmd-U73XVQMI.js} +3 -3
- package/dist/{seed-create-XOO4N2OE.js → seed-create-FBLNVSUP.js} +4 -4
- package/dist/{seed-readiness-3LRYASA4.js → seed-readiness-QRA46ZJQ.js} +4 -5
- package/dist/{seed-sprout-HSBBGSS2.js → seed-sprout-3B4SZX7J.js} +9 -9
- package/dist/{send-IHRJYNXA.js → send-NBRZJXKX.js} +32 -10
- package/dist/{service-YCOPCTSZ.js → service-XMXAXGJD.js} +4 -4
- package/dist/{service-install-Y46OTF55.js → service-install-MOKTEG7B.js} +5 -5
- package/dist/{setup-TCN7VH5U.js → setup-CAJFOR2N.js} +10 -3
- package/dist/{setup-F4TE64YI.js → setup-JGYAXXW7.js} +6 -7
- package/dist/{skill-4CYJLYVY.js → skill-NXIHDQCG.js} +3 -2
- package/dist/skills/dreaming/references/INSTALL.md +2 -2
- package/dist/skills/imagegen/SKILL.md +21 -4
- package/dist/skills/imagegen/scripts/imagegen.ts +124 -21
- package/dist/skills/tending/SKILL.md +7 -7
- package/dist/skills/volute-mind/SKILL.md +3 -3
- package/dist/skills/volute-mind/references/integrations.md +2 -2
- package/dist/skills/volute-mind/references/routing.md +15 -15
- package/dist/{skills-NN5UZCUU.js → skills-5MSMT7PT.js} +4 -5
- package/dist/sleep-manager-LIEPO6WG.js +41 -0
- package/dist/{spirit-SSJMYC6A.js → spirit-IL5EMWYZ.js} +10 -7
- package/dist/spirit-availability-YFEGJNJ2.js +42 -0
- package/dist/{split-JF2VWTXA.js → split-BU5VWX6P.js} +1 -1
- package/dist/{sprout-AXA2SECQ.js → sprout-UPXGJ5HX.js} +1 -1
- package/dist/{src-YH6PQ7LJ.js → src-HGNE2XG4.js} +7 -1
- package/dist/{src-ZN4LXMPI.js → src-LCSOQY6Z.js} +57 -51
- package/dist/{src-JAOVXO5W.js → src-UDMJZ6MH.js} +8 -8
- package/dist/{start-BTVMTP3K.js → start-MUMNFR52.js} +2 -1
- package/dist/{status-VJGXMQ4L.js → status-IL67CYM4.js} +7 -6
- package/dist/{stop-YORESK4U.js → stop-EKERNYTX.js} +2 -1
- package/dist/system-events-A6IGCEC3.js +46 -0
- package/dist/system-install-YZSWCPDK.js +8 -0
- package/dist/{systems-5MH2ELQE.js → systems-VDRUZXNF.js} +5 -4
- package/dist/{tailscale-AMMVKDXB.js → tailscale-SJUW2ETR.js} +2 -2
- package/dist/{template-staleness-HKGCTS3H.js → template-staleness-T27VCGYA.js} +3 -3
- package/dist/{turn-tracker-JQ2YUUY2.js → turn-tracker-6EI2EL7G.js} +6 -6
- package/dist/{up-SDLTLPAO.js → up-CLL4665A.js} +5 -6
- package/dist/{update-WEA4N2TR.js → update-HVAUCQPN.js} +5 -5
- package/dist/{update-check-DZOTONII.js → update-check-2MGBBAFF.js} +3 -3
- package/dist/{upgrade-K5FIQPQD.js → upgrade-LIE46UBB.js} +1 -1
- package/dist/variant-cleanup-HJ7Z75R6.js +22 -0
- package/dist/{version-notify-WFA5XB5A.js → version-notify-7BUHWZNT.js} +10 -27
- package/dist/web-assets/assets/index-ClsUcXiW.js +95 -0
- package/dist/web-assets/assets/index-Dz3wTbtR.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/dist/xai-P42CRCZA.js +129 -0
- package/drizzle/0014_system_events.sql +26 -0
- package/drizzle/0015_rename_session_to_thread.sql +12 -0
- package/drizzle/0016_brain_to_human.sql +4 -0
- package/drizzle/0017_event_history_rows.sql +9 -0
- package/drizzle/meta/_journal.json +28 -0
- package/package.json +23 -23
- package/packages/extensions/notes/dist/ui/assets/index-BBs8pyel.js +67 -0
- package/packages/extensions/notes/dist/ui/index.html +1 -1
- package/packages/extensions/pages/dist/ui/assets/index-B589e8Xe.js +2 -0
- package/packages/extensions/pages/dist/ui/index.html +1 -1
- package/packages/extensions/plan/dist/ui/assets/index-B8s8wxyt.js +67 -0
- package/packages/extensions/plan/dist/ui/index.html +1 -1
- package/templates/_base/.init/.config/prompts.json +1 -0
- package/templates/_base/.init/.local/hooks/startup-context.ts +24 -9
- package/templates/_base/home/.config/routes.json +2 -2
- package/templates/_base/home/VOLUTE.md +18 -5
- package/templates/_base/src/lib/daemon-client.ts +1 -1
- package/templates/_base/src/lib/event-turn.ts +39 -0
- package/templates/_base/src/lib/format-prefix.ts +21 -2
- package/templates/_base/src/lib/router.ts +6 -2
- package/templates/_base/src/lib/routing.ts +8 -8
- package/templates/_base/src/lib/startup.ts +9 -1
- package/templates/_base/src/lib/types.ts +7 -1
- package/templates/_base/src/lib/volute-server.ts +30 -1
- package/templates/claude/.init/.config/routes.json +3 -3
- package/templates/claude/.init/CLAUDE.md +1 -1
- package/templates/claude/package.json.tmpl +4 -4
- package/templates/claude/src/agent.ts +4 -1
- package/templates/claude/src/lib/hooks/reply-instructions.ts +26 -1
- package/templates/codex/.init/.config/routes.json +3 -3
- package/templates/codex/.init/AGENTS.md +1 -1
- package/templates/codex/package.json.tmpl +4 -4
- package/templates/codex/src/agent.ts +11 -11
- package/templates/codex/src/lib/turn-context.ts +51 -0
- package/templates/pi/.init/.config/routes.json +3 -3
- package/templates/pi/.init/MINDS.md +1 -1
- package/templates/pi/package.json.tmpl +6 -6
- package/templates/pi/src/agent.ts +9 -1
- package/templates/pi/src/lib/event-handler.ts +1 -1
- package/templates/pi/src/lib/reply-instructions-extension.ts +28 -1
- package/dist/chunk-NJHN6IRB.js +0 -177
- package/dist/chunk-QQBOI3QA.js +0 -5345
- package/dist/chunk-XTEKINWG.js +0 -158
- package/dist/delivery-manager-RBXBPVWM.js +0 -36
- package/dist/echo-text-B6NZ5FGE.js +0 -36
- package/dist/message-delivery-ABPV76EA.js +0 -42
- package/dist/mind-service-42GDO4KH.js +0 -44
- package/dist/notices-N6BCGHFV.js +0 -25
- package/dist/scheduler-K7Y7Z7FQ.js +0 -34
- package/dist/sleep-manager-DSPXFHGX.js +0 -38
- package/dist/system-chat-M2XOBKEM.js +0 -40
- package/dist/variant-cleanup-P4MBNLJD.js +0 -33
- package/dist/web-assets/assets/index-BostMFoR.css +0 -1
- package/dist/web-assets/assets/index-CKlqUkyG.js +0 -92
- package/packages/extensions/notes/dist/ui/assets/index-D0-DgYyj.js +0 -67
- package/packages/extensions/pages/dist/ui/assets/index-DtzftuPA.js +0 -2
- package/packages/extensions/plan/dist/ui/assets/index-Cfzs-0G9.js +0 -67
|
@@ -5,31 +5,208 @@ import {
|
|
|
5
5
|
conversations,
|
|
6
6
|
deliveryQueue,
|
|
7
7
|
mindHistory,
|
|
8
|
-
mindNotices,
|
|
9
8
|
minds,
|
|
10
9
|
schema_exports,
|
|
11
10
|
summaries,
|
|
11
|
+
systemEvents,
|
|
12
12
|
turns,
|
|
13
13
|
users
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-5IIVOWSP.js";
|
|
15
15
|
|
|
16
16
|
// packages/daemon/src/lib/db.ts
|
|
17
|
-
import { chmodSync, existsSync } from "fs";
|
|
18
|
-
import { dirname, resolve as
|
|
17
|
+
import { chmodSync as chmodSync2, existsSync as existsSync2 } from "fs";
|
|
18
|
+
import { dirname, resolve as resolve3 } from "path";
|
|
19
19
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
20
20
|
import { sql } from "drizzle-orm";
|
|
21
21
|
import { drizzle } from "drizzle-orm/libsql";
|
|
22
22
|
import { migrate } from "drizzle-orm/libsql/migrator";
|
|
23
23
|
|
|
24
24
|
// packages/daemon/src/lib/mind/registry.ts
|
|
25
|
-
import { mkdirSync } from "fs";
|
|
25
|
+
import { mkdirSync as mkdirSync2 } from "fs";
|
|
26
26
|
import { homedir } from "os";
|
|
27
|
-
import { resolve } from "path";
|
|
27
|
+
import { resolve as resolve2 } from "path";
|
|
28
28
|
import { fileURLToPath } from "url";
|
|
29
29
|
import { and, eq, inArray, isNull, or } from "drizzle-orm";
|
|
30
|
-
|
|
30
|
+
|
|
31
|
+
// packages/daemon/src/lib/config/setup.ts
|
|
32
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
33
|
+
import { resolve } from "path";
|
|
34
|
+
function configPath() {
|
|
35
|
+
return resolve(voluteSystemDir(), "config.json");
|
|
36
|
+
}
|
|
37
|
+
function secretsPath() {
|
|
38
|
+
return resolve(voluteSystemDir(), "secrets.json");
|
|
39
|
+
}
|
|
40
|
+
function hasEntries(obj) {
|
|
41
|
+
return !!obj && Object.keys(obj).length > 0;
|
|
42
|
+
}
|
|
43
|
+
function splitConfig(config) {
|
|
44
|
+
const publicConfig = { ...config };
|
|
45
|
+
const secrets = {};
|
|
46
|
+
if (config.ai) {
|
|
47
|
+
const { providers, ...rest } = config.ai;
|
|
48
|
+
publicConfig.ai = { ...rest, providers: {} };
|
|
49
|
+
if (hasEntries(providers)) secrets.ai = { providers };
|
|
50
|
+
}
|
|
51
|
+
if (config.imagegen) {
|
|
52
|
+
const { providers, ...rest } = config.imagegen;
|
|
53
|
+
publicConfig.imagegen = { ...rest };
|
|
54
|
+
if (providers && Object.keys(providers).length > 0) secrets.imagegen = { providers };
|
|
55
|
+
}
|
|
56
|
+
if (config.backup) {
|
|
57
|
+
const { password, env, ...rest } = config.backup;
|
|
58
|
+
publicConfig.backup = { ...rest };
|
|
59
|
+
if (password || hasEntries(env)) {
|
|
60
|
+
secrets.backup = {};
|
|
61
|
+
if (password) secrets.backup.password = password;
|
|
62
|
+
if (hasEntries(env)) secrets.backup.env = env;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { publicConfig, secrets };
|
|
66
|
+
}
|
|
67
|
+
function mergeSecrets(publicConfig, secrets) {
|
|
68
|
+
const merged = { ...publicConfig };
|
|
69
|
+
if (secrets.ai?.providers) {
|
|
70
|
+
merged.ai = { ...merged.ai ?? { providers: {} }, providers: secrets.ai.providers };
|
|
71
|
+
}
|
|
72
|
+
if (secrets.imagegen?.providers) {
|
|
73
|
+
merged.imagegen = { ...merged.imagegen ?? {}, providers: secrets.imagegen.providers };
|
|
74
|
+
}
|
|
75
|
+
if (secrets.backup) {
|
|
76
|
+
merged.backup = { ...merged.backup ?? {}, ...secrets.backup };
|
|
77
|
+
}
|
|
78
|
+
return merged;
|
|
79
|
+
}
|
|
80
|
+
function readSecrets() {
|
|
81
|
+
const path = secretsPath();
|
|
82
|
+
if (!existsSync(path)) return {};
|
|
83
|
+
try {
|
|
84
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
85
|
+
} catch {
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
var _cachedConfig = null;
|
|
90
|
+
var CONFIG_CACHE_TTL = 2e3;
|
|
91
|
+
function _resetConfigCache() {
|
|
92
|
+
_cachedConfig = null;
|
|
93
|
+
}
|
|
94
|
+
function readGlobalConfig() {
|
|
95
|
+
if (_cachedConfig && Date.now() - _cachedConfig.ts < CONFIG_CACHE_TTL) {
|
|
96
|
+
return { ..._cachedConfig.config };
|
|
97
|
+
}
|
|
98
|
+
const path = configPath();
|
|
99
|
+
if (!existsSync(path)) {
|
|
100
|
+
_cachedConfig = null;
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
103
|
+
let publicConfig;
|
|
104
|
+
try {
|
|
105
|
+
publicConfig = JSON.parse(readFileSync(path, "utf-8"));
|
|
106
|
+
} catch (err) {
|
|
107
|
+
console.error(`Failed to parse ${path}: ${err instanceof Error ? err.message : err}`);
|
|
108
|
+
return {};
|
|
109
|
+
}
|
|
110
|
+
const config = mergeSecrets(publicConfig, readSecrets());
|
|
111
|
+
_cachedConfig = { config, ts: Date.now() };
|
|
112
|
+
return config;
|
|
113
|
+
}
|
|
114
|
+
function writeGlobalConfig(config) {
|
|
115
|
+
mkdirSync(voluteSystemDir(), { recursive: true });
|
|
116
|
+
const { publicConfig, secrets } = splitConfig(config);
|
|
117
|
+
const cfgPath = configPath();
|
|
118
|
+
writeFileSync(cfgPath, `${JSON.stringify(publicConfig, null, 2)}
|
|
119
|
+
`, { mode: 420 });
|
|
120
|
+
chmodSync(cfgPath, 420);
|
|
121
|
+
const secPath = secretsPath();
|
|
122
|
+
writeFileSync(secPath, `${JSON.stringify(secrets, null, 2)}
|
|
123
|
+
`, { mode: 384 });
|
|
124
|
+
chmodSync(secPath, 384);
|
|
125
|
+
_cachedConfig = { config, ts: Date.now() };
|
|
126
|
+
}
|
|
127
|
+
function migrateConfigSecrets() {
|
|
128
|
+
const path = configPath();
|
|
129
|
+
if (!existsSync(path)) return;
|
|
130
|
+
let raw;
|
|
131
|
+
try {
|
|
132
|
+
raw = readFileSync(path, "utf-8");
|
|
133
|
+
} catch {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
let parsed;
|
|
137
|
+
try {
|
|
138
|
+
parsed = JSON.parse(raw);
|
|
139
|
+
} catch {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const embedsSecrets = hasEntries(parsed.ai?.providers) || hasEntries(parsed.imagegen?.providers) || !!parsed.backup?.password || hasEntries(parsed.backup?.env);
|
|
143
|
+
const mode = statSync(path).mode & 511;
|
|
144
|
+
if (!embedsSecrets && mode === 420) return;
|
|
145
|
+
_resetConfigCache();
|
|
146
|
+
writeGlobalConfig(readGlobalConfig());
|
|
147
|
+
}
|
|
148
|
+
function computeSetupStatus(config) {
|
|
149
|
+
if (config.setupCompleted === true) return "complete";
|
|
150
|
+
if (config.setup != null && config.setupCompleted == null) return "complete";
|
|
151
|
+
if (config.setup != null) return "in-progress";
|
|
152
|
+
return "none";
|
|
153
|
+
}
|
|
154
|
+
function setupStatus() {
|
|
155
|
+
return computeSetupStatus(readGlobalConfig());
|
|
156
|
+
}
|
|
157
|
+
function readGlobalConfigStrict() {
|
|
158
|
+
const path = configPath();
|
|
159
|
+
if (!existsSync(path)) return {};
|
|
160
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
161
|
+
}
|
|
162
|
+
function isSetupComplete() {
|
|
163
|
+
return setupStatus() === "complete";
|
|
164
|
+
}
|
|
165
|
+
function setupUrl() {
|
|
166
|
+
const config = readGlobalConfig();
|
|
167
|
+
const port = config.port || 1618;
|
|
168
|
+
let host = config.hostname || "127.0.0.1";
|
|
169
|
+
if (host === "0.0.0.0" || host === "::") host = "localhost";
|
|
170
|
+
if (host.includes(":") && !host.startsWith("[")) host = `[${host}]`;
|
|
171
|
+
return `http://${host}:${port}`;
|
|
172
|
+
}
|
|
173
|
+
function getSpiritName() {
|
|
174
|
+
return readGlobalConfig().setup?.spiritName ?? "volute";
|
|
175
|
+
}
|
|
176
|
+
function getSystemName() {
|
|
177
|
+
return readGlobalConfig().name ?? "this system";
|
|
178
|
+
}
|
|
179
|
+
var IMAGEGEN_AI_PROVIDERS = ["openai-codex", "xai"];
|
|
180
|
+
function isImagegenEnabled() {
|
|
181
|
+
const config = readGlobalConfig();
|
|
182
|
+
const ig = config.imagegen;
|
|
183
|
+
if (ig?.enabled === true) return true;
|
|
184
|
+
if (ig?.providers && Object.keys(ig.providers).length > 0) return true;
|
|
185
|
+
const aiProviders = config.ai?.providers;
|
|
186
|
+
for (const id of IMAGEGEN_AI_PROVIDERS) {
|
|
187
|
+
const p = aiProviders?.[id];
|
|
188
|
+
if (p?.oauth || p?.apiKey) return true;
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
function mindLimitError(count, limit) {
|
|
193
|
+
if (limit == null) return null;
|
|
194
|
+
if (count >= limit) {
|
|
195
|
+
return `Mind limit reached (${count}/${limit}). An admin can raise maxMinds in Settings.`;
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
function migrateSetupCompleted() {
|
|
200
|
+
const config = readGlobalConfig();
|
|
201
|
+
if (config.setup != null && config.setupCompleted == null) {
|
|
202
|
+
config.setupCompleted = true;
|
|
203
|
+
writeGlobalConfig(config);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// packages/daemon/src/lib/mind/registry.ts
|
|
31
208
|
function isSpiritName(name) {
|
|
32
|
-
return name ===
|
|
209
|
+
return name === getSpiritName();
|
|
33
210
|
}
|
|
34
211
|
function voluteHome() {
|
|
35
212
|
if (process.env.VOLUTE_HOME) return process.env.VOLUTE_HOME;
|
|
@@ -38,21 +215,21 @@ function voluteHome() {
|
|
|
38
215
|
'VOLUTE_HOME must be set when running from source. For tests, run via "npm test" or add "--import ./test/setup.ts".'
|
|
39
216
|
);
|
|
40
217
|
}
|
|
41
|
-
return
|
|
218
|
+
return resolve2(homedir(), ".volute");
|
|
42
219
|
}
|
|
43
220
|
function voluteUserHome() {
|
|
44
221
|
if (process.env.VOLUTE_USER_HOME) return process.env.VOLUTE_USER_HOME;
|
|
45
|
-
return
|
|
222
|
+
return resolve2(homedir(), ".volute");
|
|
46
223
|
}
|
|
47
224
|
function voluteSystemDir() {
|
|
48
|
-
return
|
|
225
|
+
return resolve2(voluteHome(), "system");
|
|
49
226
|
}
|
|
50
227
|
function ensureSystemDir() {
|
|
51
|
-
|
|
228
|
+
mkdirSync2(voluteSystemDir(), { recursive: true });
|
|
52
229
|
}
|
|
53
230
|
function ensureVoluteHome() {
|
|
54
|
-
const mindsBase = process.env.VOLUTE_MINDS_DIR ??
|
|
55
|
-
|
|
231
|
+
const mindsBase = process.env.VOLUTE_MINDS_DIR ?? resolve2(voluteHome(), "minds");
|
|
232
|
+
mkdirSync2(mindsBase, { recursive: true });
|
|
56
233
|
ensureSystemDir();
|
|
57
234
|
}
|
|
58
235
|
function rowToEntry(row) {
|
|
@@ -98,6 +275,18 @@ function validateMindName(name) {
|
|
|
98
275
|
if (RESERVED_NAMES.has(name.toLowerCase())) {
|
|
99
276
|
return `"${name}" is a reserved name`;
|
|
100
277
|
}
|
|
278
|
+
if (isSpiritName(name)) {
|
|
279
|
+
return `"${name}" is the spirit's name`;
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
function validateSpiritName(name) {
|
|
284
|
+
if (!name) return "Spirit name is required";
|
|
285
|
+
if (name.length > MIND_NAME_MAX) return `Spirit name must be at most ${MIND_NAME_MAX} characters`;
|
|
286
|
+
if (!MIND_NAME_RE.test(name)) {
|
|
287
|
+
return "Spirit name must start with alphanumeric and contain only alphanumeric, dots, dashes, or underscores";
|
|
288
|
+
}
|
|
289
|
+
if (name.toLowerCase() === "system") return `"${name}" is a reserved name`;
|
|
101
290
|
return null;
|
|
102
291
|
}
|
|
103
292
|
async function addMind(name, port, stage, template, createdBy) {
|
|
@@ -165,7 +354,7 @@ async function deleteMindDbFootprint(name) {
|
|
|
165
354
|
await tx.delete(turns).where(eq(turns.mind, name));
|
|
166
355
|
await tx.delete(mindHistory).where(eq(mindHistory.mind, name));
|
|
167
356
|
await tx.delete(summaries).where(eq(summaries.mind, name));
|
|
168
|
-
await tx.delete(
|
|
357
|
+
await tx.delete(systemEvents).where(eq(systemEvents.mind, name));
|
|
169
358
|
await tx.delete(channelGates).where(eq(channelGates.mind, name));
|
|
170
359
|
});
|
|
171
360
|
}
|
|
@@ -202,19 +391,23 @@ async function getBaseName(name) {
|
|
|
202
391
|
}
|
|
203
392
|
function mindDir(name) {
|
|
204
393
|
if (process.env.VOLUTE_MINDS_DIR) {
|
|
205
|
-
return
|
|
394
|
+
return resolve2(process.env.VOLUTE_MINDS_DIR, name);
|
|
206
395
|
}
|
|
207
|
-
return
|
|
396
|
+
return resolve2(voluteHome(), "minds", name);
|
|
208
397
|
}
|
|
209
398
|
async function resolveMindDir(name) {
|
|
210
399
|
const entry = await findMind(name);
|
|
211
400
|
return entry?.dir ?? mindDir(name);
|
|
212
401
|
}
|
|
213
402
|
function stateDir(name) {
|
|
214
|
-
return
|
|
403
|
+
return resolve2(voluteSystemDir(), "state", name);
|
|
404
|
+
}
|
|
405
|
+
function mindTmpEnv(dir) {
|
|
406
|
+
const tmp = mindTmpDir(dir);
|
|
407
|
+
return { TMPDIR: tmp, CLAUDE_CODE_TMPDIR: tmp };
|
|
215
408
|
}
|
|
216
409
|
function mindTmpDir(dir) {
|
|
217
|
-
return
|
|
410
|
+
return resolve2(dir, ".mind", "tmp");
|
|
218
411
|
}
|
|
219
412
|
async function nextPort() {
|
|
220
413
|
const db2 = await getDb();
|
|
@@ -235,7 +428,7 @@ function daemonLoopback() {
|
|
|
235
428
|
|
|
236
429
|
// packages/daemon/src/lib/db.ts
|
|
237
430
|
var __dirname = dirname(fileURLToPath2(import.meta.url));
|
|
238
|
-
var migrationsFolder =
|
|
431
|
+
var migrationsFolder = existsSync2(resolve3(__dirname, "../drizzle")) ? resolve3(__dirname, "../drizzle") : existsSync2(resolve3(__dirname, "../../drizzle")) ? resolve3(__dirname, "../../drizzle") : resolve3(__dirname, "../../../../drizzle");
|
|
239
432
|
var db = null;
|
|
240
433
|
var dbPromise = null;
|
|
241
434
|
async function cleanupConversationColumns(db2) {
|
|
@@ -253,7 +446,7 @@ async function getDb() {
|
|
|
253
446
|
if (dbPromise) return dbPromise;
|
|
254
447
|
dbPromise = (async () => {
|
|
255
448
|
try {
|
|
256
|
-
const dbPath = process.env.VOLUTE_DB_PATH ||
|
|
449
|
+
const dbPath = process.env.VOLUTE_DB_PATH || resolve3(voluteSystemDir(), "volute.db");
|
|
257
450
|
const instance = drizzle({ connection: { url: `file:${dbPath}` }, schema: schema_exports });
|
|
258
451
|
await instance.run(sql.raw("PRAGMA journal_mode=WAL"));
|
|
259
452
|
await instance.run(sql.raw("PRAGMA busy_timeout=5000"));
|
|
@@ -261,7 +454,7 @@ async function getDb() {
|
|
|
261
454
|
await migrate(instance, { migrationsFolder });
|
|
262
455
|
await cleanupConversationColumns(instance);
|
|
263
456
|
try {
|
|
264
|
-
|
|
457
|
+
chmodSync2(dbPath, 384);
|
|
265
458
|
} catch (err) {
|
|
266
459
|
console.error(
|
|
267
460
|
`[volute] WARNING: Failed to restrict database file permissions on ${dbPath}:`,
|
|
@@ -280,7 +473,6 @@ async function getDb() {
|
|
|
280
473
|
|
|
281
474
|
export {
|
|
282
475
|
getDb,
|
|
283
|
-
SPIRIT_NAME,
|
|
284
476
|
isSpiritName,
|
|
285
477
|
voluteHome,
|
|
286
478
|
voluteUserHome,
|
|
@@ -291,6 +483,7 @@ export {
|
|
|
291
483
|
countCappedMinds,
|
|
292
484
|
readAllMinds,
|
|
293
485
|
validateMindName,
|
|
486
|
+
validateSpiritName,
|
|
294
487
|
addMind,
|
|
295
488
|
addSpirit,
|
|
296
489
|
readSpirits,
|
|
@@ -307,7 +500,24 @@ export {
|
|
|
307
500
|
mindDir,
|
|
308
501
|
resolveMindDir,
|
|
309
502
|
stateDir,
|
|
503
|
+
mindTmpEnv,
|
|
310
504
|
mindTmpDir,
|
|
311
505
|
nextPort,
|
|
312
|
-
daemonLoopback
|
|
506
|
+
daemonLoopback,
|
|
507
|
+
configPath,
|
|
508
|
+
secretsPath,
|
|
509
|
+
_resetConfigCache,
|
|
510
|
+
readGlobalConfig,
|
|
511
|
+
writeGlobalConfig,
|
|
512
|
+
migrateConfigSecrets,
|
|
513
|
+
computeSetupStatus,
|
|
514
|
+
setupStatus,
|
|
515
|
+
readGlobalConfigStrict,
|
|
516
|
+
isSetupComplete,
|
|
517
|
+
setupUrl,
|
|
518
|
+
getSpiritName,
|
|
519
|
+
getSystemName,
|
|
520
|
+
isImagegenEnabled,
|
|
521
|
+
mindLimitError,
|
|
522
|
+
migrateSetupCompleted
|
|
313
523
|
};
|