volute 0.49.0 → 0.51.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-LQII6PZS.js} +3 -3
- package/dist/{ai-service-A7FS7EC3.js → ai-service-YW5SWCSB.js} +9 -4
- package/dist/{archive-7E3YE6VF.js → archive-FOHGXHPT.js} +3 -3
- package/dist/{auth-ABYLOEZ7.js → auth-X6EMNEGB.js} +10 -6
- package/dist/{avatar-image-6ATV2IOZ.js → avatar-image-52WGXLHV.js} +3 -3
- package/dist/{backup-XYAMT4CU.js → backup-YVGV2ZNM.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-VAZ25KVT.js} +9 -9
- package/dist/{chunk-P4LHVRNE.js → chunk-2RNMBXD2.js} +43 -19
- package/dist/{chunk-6HGEZJDH.js → chunk-5N32EN4O.js} +2 -2
- package/dist/{chunk-JCWB2ITW.js → chunk-5Y54AE3L.js} +35 -5
- package/dist/{chunk-HCYQRME2.js → chunk-6NLW72HP.js} +2 -2
- package/dist/chunk-7HN63Q7J.js +1317 -0
- package/dist/chunk-7YJY3F2R.js +38 -0
- package/dist/{chunk-EADX54RG.js → chunk-AI47FDGL.js} +6 -7
- package/dist/{chunk-IH5TKXX6.js → chunk-BSHZ23MS.js} +12 -11
- package/dist/{chunk-K3JOLGWF.js → chunk-CDKQJWGK.js} +76 -63
- package/dist/{chunk-L27YYONJ.js → chunk-CV6BNGFK.js} +3 -3
- package/dist/{chunk-NOIAHMJB.js → chunk-DMK5ASKV.js} +1 -1
- package/dist/chunk-DN3LKLYR.js +109 -0
- package/dist/{chunk-JBIFXB6I.js → chunk-EDR47UE2.js} +3 -5
- package/dist/{chunk-SHKM5RGD.js → chunk-EEOMA4DX.js} +1 -1
- package/dist/{chunk-YIJGKHIS.js → chunk-EGV6R6UF.js} +43 -20
- package/dist/{chunk-KHCKZ36O.js → chunk-FLIEXG2T.js} +1 -1
- package/dist/chunk-FNJCBRD3.js +31 -0
- package/dist/{chunk-JPGHSXSV.js → chunk-FXWBFDQR.js} +23 -9
- package/dist/{chunk-JCBPU57A.js → chunk-G7A5LEVI.js} +6 -6
- package/dist/{chunk-PY24ZL62.js → chunk-GLM7TVWP.js} +1 -1
- package/dist/{chunk-RSBL3FAD.js → chunk-H6X6CKDN.js} +235 -24
- package/dist/{chunk-4DSGN4FL.js → chunk-HKP6OAJP.js} +43 -13
- package/dist/{chunk-C3KLHJDB.js → chunk-HTRSSOHY.js} +1 -1
- package/dist/{chunk-EG5LSKHU.js → chunk-I7U5EEZC.js} +2 -2
- package/dist/chunk-ICL6T4SN.js +562 -0
- package/dist/{chunk-FBBS4BVR.js → chunk-ICXY54ZC.js} +1 -1
- package/dist/{chunk-DAIIMBLB.js → chunk-IWAVIJO2.js} +3 -5
- package/dist/{chunk-TXJL36ZQ.js → chunk-JHKBALS2.js} +2 -2
- package/dist/{chunk-MG3Z34YE.js → chunk-L7BKTZ5U.js} +1 -1
- package/dist/{chunk-SX72DOO3.js → chunk-LAUCO2HC.js} +1 -1
- package/dist/chunk-LNNI3MS4.js +54 -0
- package/dist/{chunk-BCG45AQB.js → chunk-M74I3HHF.js} +15 -5
- package/dist/{chunk-DVN6DNMI.js → chunk-M77B73VV.js} +17 -2
- package/dist/{chunk-4B62E4CG.js → chunk-OXWUEU5V.js} +2 -2
- package/dist/chunk-Q7XQLKZB.js +289 -0
- package/dist/{chunk-GWVFDUNB.js → chunk-QT4D5XCI.js} +8 -10
- package/dist/{chunk-VNRSXEBF.js → chunk-TPX6E6PL.js} +38 -5
- package/dist/{chunk-3B427GUK.js → chunk-U54PJPTB.js} +2 -2
- package/dist/{chunk-EFT2OALG.js → chunk-UDZLPR34.js} +20 -5
- package/dist/{chunk-ZX46PGCC.js → chunk-UFTDRTCP.js} +1 -1
- package/dist/chunk-VAEZCIJC.js +1058 -0
- package/dist/chunk-VP5PFNZO.js +2905 -0
- package/dist/{chunk-VIUH5CHQ.js → chunk-VSBMLB2W.js} +51 -34
- package/dist/{chunk-RRZ4RQQU.js → chunk-X67BDDZR.js} +5 -7
- package/dist/cli.js +34 -27
- package/dist/{clock-6JZL2FS6.js → clock-ZT5YT6HA.js} +4 -3
- package/dist/{cloud-sync-VFDTNNCA.js → cloud-sync-GPXYPTIC.js} +23 -20
- package/dist/{config-RPSLA2HX.js → config-UGJS57VT.js} +3 -3
- package/dist/{conversations-TUM5PJJ4.js → conversations-ZL6PHROD.js} +8 -4
- package/dist/{create-Z5FSDNVZ.js → create-G2RIKQYK.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-2EWBRTN5.js} +6 -7
- package/dist/daemon.js +2005 -762
- package/dist/{db-F6UMFRYD.js → db-BONH4SUG.js} +2 -2
- package/dist/{delete-ESEP7NGQ.js → delete-O7PEFQDF.js} +1 -1
- package/dist/delivery-manager-HGVZSEES.js +35 -0
- package/dist/{delivery-router-VUOL5YSA.js → delivery-router-RHANNTAC.js} +7 -5
- package/dist/{down-6X7KX7BZ.js → down-QSNEMTTX.js} +5 -5
- package/dist/echo-text-6ANI5HHN.js +39 -0
- package/dist/{env-ZYMSCB7B.js → env-IBW2QI6K.js} +3 -2
- package/dist/{env-KUL4XKN2.js → env-SQFCWW52.js} +3 -3
- package/dist/{exec-FBXA3CM4.js → exec-ABD3DYA2.js} +3 -3
- package/dist/{export-TNBPDH77.js → export-VBNWM7I4.js} +4 -4
- package/dist/{extension-J4ZQ2GHV.js → extension-MRYJWSMV.js} +2 -1
- package/dist/{extensions-AWNO3SZF.js → extensions-NY6WST33.js} +23 -20
- package/dist/{files-BVBRJJ2P.js → files-BRY5RRIM.js} +5 -4
- package/dist/{import-ZUNKMCKC.js → import-DB2KULRO.js} +8 -8
- package/dist/{isolation-OPCZQRTH.js → isolation-GVV2IBAU.js} +5 -3
- package/dist/{join-34TR2GXQ.js → join-PYA36HEC.js} +1 -1
- package/dist/{list-PMUXZNAM.js → list-UQGIW7OF.js} +8 -3
- package/dist/{login-LKNLCJPA.js → login-RJJTCVR3.js} +2 -1
- package/dist/{login-KAKNFCW5.js → login-SB5OENMV.js} +4 -3
- package/dist/{logout-YZRMZ3O2.js → logout-BYV433X6.js} +2 -1
- package/dist/{logout-RLT62RQP.js → logout-YFZAJRPY.js} +4 -3
- package/dist/message-delivery-JHMAJ2GU.js +43 -0
- package/dist/migrate-thread-config-EQSEP2XG.js +90 -0
- package/dist/{mind-IF6CGMFW.js → mind-WF6QIXWV.js} +19 -19
- package/dist/{mind-activity-tracker-YMMERB6B.js → mind-activity-tracker-QF6DCX2X.js} +4 -4
- package/dist/{mind-contacts-BKUFPUCU.js → mind-contacts-QYU4TPEA.js} +3 -2
- package/dist/{mind-history-WI5OI3BW.js → mind-history-OGNR4L7W.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-DZCUUC7J.js +47 -0
- package/dist/{mind-sleep-VBV7YRSU.js → mind-sleep-LZAFBDZD.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-B6O5APCZ.js} +23 -23
- package/dist/{prompts-MDHDLWEX.js → prompts-NBO3HRK3.js} +3 -3
- package/dist/{read-YSWUXYL7.js → read-RJ5NAW5J.js} +5 -14
- package/dist/{register-TWQDKQRT.js → register-OX4HRSGC.js} +2 -1
- package/dist/{registry-3ELJPUGJ.js → registry-TRC2HJXR.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-NNWCTHRI.js} +7 -4
- package/dist/scheduler-TNBN54ZK.js +25 -0
- package/dist/{schema-6YONVTKZ.js → schema-ZZQVM4GR.js} +5 -3
- package/dist/{seed-NQED7PSX.js → seed-K2LYODIH.js} +1 -1
- package/dist/{seed-check-TYD7RRZY.js → seed-check-NRJEQZST.js} +14 -5
- package/dist/{seed-cmd-QF3F2G4S.js → seed-cmd-2EWBTR6P.js} +3 -3
- package/dist/{seed-create-XOO4N2OE.js → seed-create-VGTLU5FD.js} +4 -4
- package/dist/{seed-readiness-3LRYASA4.js → seed-readiness-DYOVCYHN.js} +4 -5
- package/dist/{seed-sprout-HSBBGSS2.js → seed-sprout-PILHJ3YS.js} +9 -9
- package/dist/{send-IHRJYNXA.js → send-2YKOZJJ5.js} +108 -54
- package/dist/{service-YCOPCTSZ.js → service-XQPMZAGI.js} +4 -4
- package/dist/{service-install-Y46OTF55.js → service-install-2EWD7KXD.js} +5 -5
- package/dist/{setup-F4TE64YI.js → setup-MDPSK2XG.js} +6 -7
- package/dist/{setup-TCN7VH5U.js → setup-WZSXHHRJ.js} +10 -3
- package/dist/{skill-4CYJLYVY.js → skill-B5OJEQUA.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-NH2GQKAF.js} +4 -5
- package/dist/sleep-manager-7JXEQQ2P.js +41 -0
- package/dist/{spirit-SSJMYC6A.js → spirit-25JVAL3M.js} +11 -8
- package/dist/spirit-availability-PJDWZJ3J.js +42 -0
- package/dist/{split-JF2VWTXA.js → split-BU5VWX6P.js} +1 -1
- package/dist/{sprout-AXA2SECQ.js → sprout-EXUZMIOR.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-MWLE3RVC.js} +7 -6
- package/dist/{stop-YORESK4U.js → stop-EKERNYTX.js} +2 -1
- package/dist/system-events-ZPSH63QX.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-KHNZFC7L.js} +2 -2
- package/dist/{template-hash-GSOUARW4.js → template-hash-YKWMVYMM.js} +2 -2
- package/dist/{template-staleness-HKGCTS3H.js → template-staleness-PY2CULH6.js} +5 -5
- package/dist/{turn-tracker-JQ2YUUY2.js → turn-tracker-TAT2HGK6.js} +6 -6
- package/dist/{up-SDLTLPAO.js → up-J7XCAH7P.js} +5 -6
- package/dist/{update-WEA4N2TR.js → update-CIWI2JYA.js} +5 -5
- package/dist/{update-check-DZOTONII.js → update-check-SZ7B5IFI.js} +3 -3
- package/dist/{upgrade-K5FIQPQD.js → upgrade-LIE46UBB.js} +1 -1
- package/dist/variant-cleanup-YXN25ZVW.js +22 -0
- package/dist/{version-notify-WFA5XB5A.js → version-notify-EN3KJ7HH.js} +11 -28
- package/dist/web-assets/assets/index-BOyJ4Gqs.css +1 -0
- package/dist/web-assets/assets/index-CrxBwnzp.js +95 -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/0018_api_tokens.sql +20 -0
- package/drizzle/meta/_journal.json +35 -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/{biome.json.tmpl → biome.json} +2 -1
- package/templates/_base/gitignore +44 -0
- package/templates/_base/home/.config/routes.json +2 -2
- package/templates/_base/home/VOLUTE.md +18 -5
- package/templates/_base/home/public/.gitkeep +0 -0
- 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 +36 -10
- package/templates/_base/src/lib/router.ts +19 -10
- 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 → package.json} +4 -4
- package/templates/claude/src/agent.ts +4 -1
- package/templates/claude/src/lib/hooks/reply-instructions.ts +26 -1
- package/templates/claude/volute-template.json +1 -3
- package/templates/codex/.init/.config/routes.json +3 -3
- package/templates/codex/.init/AGENTS.md +1 -1
- package/templates/codex/{package.json.tmpl → package.json} +4 -4
- package/templates/codex/src/agent.ts +11 -11
- package/templates/codex/src/lib/turn-context.ts +51 -0
- package/templates/codex/volute-template.json +1 -3
- package/templates/pi/.init/.config/routes.json +3 -3
- package/templates/pi/.init/MINDS.md +1 -1
- package/templates/pi/{package.json.tmpl → package.json} +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/templates/pi/volute-template.json +1 -3
- package/dist/chunk-5T5YMX6S.js +0 -23
- 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
- /package/templates/_base/home/.config/{config.json.tmpl → config.json} +0 -0
- /package/templates/codex/home/.config/{config.json.tmpl → config.json} +0 -0
- /package/templates/pi/home/.config/{config.json.tmpl → config.json} +0 -0
|
@@ -147,7 +147,7 @@ export function createEventHandler(session: EventSession, options: EventHandlerO
|
|
|
147
147
|
const channel = messageId ? session.messageChannels.get(messageId)?.channel : undefined;
|
|
148
148
|
log("mind", `session "${session.name}": turn done`);
|
|
149
149
|
// Collect any agent-level errors (e.g. a provider 401 reported inside agent_end).
|
|
150
|
-
// Warn-logging alone left the failure invisible at every
|
|
150
|
+
// Warn-logging alone left the failure invisible at every host surface (#619);
|
|
151
151
|
// we emit a turn_error to the daemon too — mirroring the dispatch-rejection path in
|
|
152
152
|
// agent.ts — so classify() tags it and chat status + lastError surface it. Dedupe
|
|
153
153
|
// identical messages so a turn with several failed messages records one notice.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import type { EventSession } from "./event-handler.js";
|
|
3
|
+
import { firstReplyableEntry, isEventTurn } from "./event-turn.js";
|
|
3
4
|
import { log } from "./logger.js";
|
|
4
5
|
import { loadPrompts } from "./startup.js";
|
|
5
6
|
|
|
@@ -14,11 +15,37 @@ export function createReplyInstructionsExtension(
|
|
|
14
15
|
const prompts = loadPrompts();
|
|
15
16
|
return (pi) => {
|
|
16
17
|
let fired = false;
|
|
18
|
+
let eventNoteFired = false;
|
|
17
19
|
pi.on("before_agent_start", () => {
|
|
18
20
|
try {
|
|
21
|
+
const entries = [...messageChannels.values()];
|
|
22
|
+
|
|
23
|
+
// System-event turn: ambient, from the environment, with no channel to reply to.
|
|
24
|
+
// The note fires once per session (see event-turn.ts for why).
|
|
25
|
+
if (isEventTurn(entries)) {
|
|
26
|
+
if (eventNoteFired) return {};
|
|
27
|
+
eventNoteFired = true;
|
|
28
|
+
const content = prompts.event_instructions;
|
|
29
|
+
if (emitContext && session) {
|
|
30
|
+
emitContext(session, {
|
|
31
|
+
type: "context",
|
|
32
|
+
content,
|
|
33
|
+
metadata: { source: "event-instructions" },
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
message: {
|
|
38
|
+
customType: "event-instructions",
|
|
39
|
+
content,
|
|
40
|
+
display: true,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
19
45
|
if (fired) return {};
|
|
20
46
|
|
|
21
|
-
|
|
47
|
+
// Reply instructions must name a channel the mind can actually send to.
|
|
48
|
+
const entry = firstReplyableEntry(entries);
|
|
22
49
|
if (!entry) return {};
|
|
23
50
|
|
|
24
51
|
fired = true;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"rename": {
|
|
3
|
-
"
|
|
4
|
-
"biome.json.tmpl": "biome.json",
|
|
5
|
-
"home/.config/config.json.tmpl": "home/.config/config.json"
|
|
3
|
+
"gitignore": ".gitignore"
|
|
6
4
|
},
|
|
7
5
|
"substitute": ["package.json", ".init/SOUL.md", "home/.config/routes.json"]
|
|
8
6
|
}
|
package/dist/chunk-5T5YMX6S.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// packages/cli/src/lib/format-cli.ts
|
|
4
|
-
var isCompact = () => !!process.env.VOLUTE_MIND;
|
|
5
|
-
function compactTime(dateStr) {
|
|
6
|
-
const d = new Date(dateStr.endsWith("Z") ? dateStr : `${dateStr}Z`);
|
|
7
|
-
return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
8
|
-
}
|
|
9
|
-
function compactDateTime(dateStr) {
|
|
10
|
-
const d = new Date(dateStr.endsWith("Z") ? dateStr : `${dateStr}Z`);
|
|
11
|
-
const y = d.getFullYear();
|
|
12
|
-
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
13
|
-
const day = String(d.getDate()).padStart(2, "0");
|
|
14
|
-
const h = String(d.getHours()).padStart(2, "0");
|
|
15
|
-
const min = String(d.getMinutes()).padStart(2, "0");
|
|
16
|
-
return `${y}-${m}-${day} ${h}:${min}`;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export {
|
|
20
|
-
isCompact,
|
|
21
|
-
compactTime,
|
|
22
|
-
compactDateTime
|
|
23
|
-
};
|
package/dist/chunk-NJHN6IRB.js
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
voluteSystemDir
|
|
4
|
-
} from "./chunk-RSBL3FAD.js";
|
|
5
|
-
|
|
6
|
-
// packages/daemon/src/lib/config/setup.ts
|
|
7
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
8
|
-
import { resolve } from "path";
|
|
9
|
-
function configPath() {
|
|
10
|
-
return resolve(voluteSystemDir(), "config.json");
|
|
11
|
-
}
|
|
12
|
-
function secretsPath() {
|
|
13
|
-
return resolve(voluteSystemDir(), "secrets.json");
|
|
14
|
-
}
|
|
15
|
-
function hasEntries(obj) {
|
|
16
|
-
return !!obj && Object.keys(obj).length > 0;
|
|
17
|
-
}
|
|
18
|
-
function splitConfig(config) {
|
|
19
|
-
const publicConfig = { ...config };
|
|
20
|
-
const secrets = {};
|
|
21
|
-
if (config.ai) {
|
|
22
|
-
const { providers, ...rest } = config.ai;
|
|
23
|
-
publicConfig.ai = { ...rest, providers: {} };
|
|
24
|
-
if (hasEntries(providers)) secrets.ai = { providers };
|
|
25
|
-
}
|
|
26
|
-
if (config.imagegen) {
|
|
27
|
-
const { providers, ...rest } = config.imagegen;
|
|
28
|
-
publicConfig.imagegen = { ...rest };
|
|
29
|
-
if (providers && Object.keys(providers).length > 0) secrets.imagegen = { providers };
|
|
30
|
-
}
|
|
31
|
-
if (config.backup) {
|
|
32
|
-
const { password, env, ...rest } = config.backup;
|
|
33
|
-
publicConfig.backup = { ...rest };
|
|
34
|
-
if (password || hasEntries(env)) {
|
|
35
|
-
secrets.backup = {};
|
|
36
|
-
if (password) secrets.backup.password = password;
|
|
37
|
-
if (hasEntries(env)) secrets.backup.env = env;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return { publicConfig, secrets };
|
|
41
|
-
}
|
|
42
|
-
function mergeSecrets(publicConfig, secrets) {
|
|
43
|
-
const merged = { ...publicConfig };
|
|
44
|
-
if (secrets.ai?.providers) {
|
|
45
|
-
merged.ai = { ...merged.ai ?? { providers: {} }, providers: secrets.ai.providers };
|
|
46
|
-
}
|
|
47
|
-
if (secrets.imagegen?.providers) {
|
|
48
|
-
merged.imagegen = { ...merged.imagegen ?? {}, providers: secrets.imagegen.providers };
|
|
49
|
-
}
|
|
50
|
-
if (secrets.backup) {
|
|
51
|
-
merged.backup = { ...merged.backup ?? {}, ...secrets.backup };
|
|
52
|
-
}
|
|
53
|
-
return merged;
|
|
54
|
-
}
|
|
55
|
-
function readSecrets() {
|
|
56
|
-
const path = secretsPath();
|
|
57
|
-
if (!existsSync(path)) return {};
|
|
58
|
-
try {
|
|
59
|
-
return JSON.parse(readFileSync(path, "utf-8"));
|
|
60
|
-
} catch {
|
|
61
|
-
return {};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
var _cachedConfig = null;
|
|
65
|
-
var CONFIG_CACHE_TTL = 2e3;
|
|
66
|
-
function _resetConfigCache() {
|
|
67
|
-
_cachedConfig = null;
|
|
68
|
-
}
|
|
69
|
-
function readGlobalConfig() {
|
|
70
|
-
if (_cachedConfig && Date.now() - _cachedConfig.ts < CONFIG_CACHE_TTL) {
|
|
71
|
-
return { ..._cachedConfig.config };
|
|
72
|
-
}
|
|
73
|
-
const path = configPath();
|
|
74
|
-
if (!existsSync(path)) {
|
|
75
|
-
_cachedConfig = null;
|
|
76
|
-
return {};
|
|
77
|
-
}
|
|
78
|
-
let publicConfig;
|
|
79
|
-
try {
|
|
80
|
-
publicConfig = JSON.parse(readFileSync(path, "utf-8"));
|
|
81
|
-
} catch (err) {
|
|
82
|
-
console.error(`Failed to parse ${path}: ${err instanceof Error ? err.message : err}`);
|
|
83
|
-
return {};
|
|
84
|
-
}
|
|
85
|
-
const config = mergeSecrets(publicConfig, readSecrets());
|
|
86
|
-
_cachedConfig = { config, ts: Date.now() };
|
|
87
|
-
return config;
|
|
88
|
-
}
|
|
89
|
-
function writeGlobalConfig(config) {
|
|
90
|
-
mkdirSync(voluteSystemDir(), { recursive: true });
|
|
91
|
-
const { publicConfig, secrets } = splitConfig(config);
|
|
92
|
-
const cfgPath = configPath();
|
|
93
|
-
writeFileSync(cfgPath, `${JSON.stringify(publicConfig, null, 2)}
|
|
94
|
-
`, { mode: 420 });
|
|
95
|
-
chmodSync(cfgPath, 420);
|
|
96
|
-
const secPath = secretsPath();
|
|
97
|
-
writeFileSync(secPath, `${JSON.stringify(secrets, null, 2)}
|
|
98
|
-
`, { mode: 384 });
|
|
99
|
-
chmodSync(secPath, 384);
|
|
100
|
-
_cachedConfig = { config, ts: Date.now() };
|
|
101
|
-
}
|
|
102
|
-
function migrateConfigSecrets() {
|
|
103
|
-
const path = configPath();
|
|
104
|
-
if (!existsSync(path)) return;
|
|
105
|
-
let raw;
|
|
106
|
-
try {
|
|
107
|
-
raw = readFileSync(path, "utf-8");
|
|
108
|
-
} catch {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
let parsed;
|
|
112
|
-
try {
|
|
113
|
-
parsed = JSON.parse(raw);
|
|
114
|
-
} catch {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const embedsSecrets = hasEntries(parsed.ai?.providers) || hasEntries(parsed.imagegen?.providers) || !!parsed.backup?.password || hasEntries(parsed.backup?.env);
|
|
118
|
-
const mode = statSync(path).mode & 511;
|
|
119
|
-
if (!embedsSecrets && mode === 420) return;
|
|
120
|
-
_resetConfigCache();
|
|
121
|
-
writeGlobalConfig(readGlobalConfig());
|
|
122
|
-
}
|
|
123
|
-
function setupStatus() {
|
|
124
|
-
const config = readGlobalConfig();
|
|
125
|
-
if (config.setupCompleted === true) return "complete";
|
|
126
|
-
if (config.setup != null && config.setupCompleted == null) return "complete";
|
|
127
|
-
if (config.setup != null) return "in-progress";
|
|
128
|
-
return "none";
|
|
129
|
-
}
|
|
130
|
-
function isSetupComplete() {
|
|
131
|
-
return setupStatus() === "complete";
|
|
132
|
-
}
|
|
133
|
-
function setupUrl() {
|
|
134
|
-
const config = readGlobalConfig();
|
|
135
|
-
const port = config.port || 1618;
|
|
136
|
-
let host = config.hostname || "127.0.0.1";
|
|
137
|
-
if (host === "0.0.0.0" || host === "::") host = "localhost";
|
|
138
|
-
if (host.includes(":") && !host.startsWith("[")) host = `[${host}]`;
|
|
139
|
-
return `http://${host}:${port}`;
|
|
140
|
-
}
|
|
141
|
-
function isImagegenEnabled() {
|
|
142
|
-
const config = readGlobalConfig();
|
|
143
|
-
const ig = config.imagegen;
|
|
144
|
-
if (!ig) return false;
|
|
145
|
-
if (ig.enabled === true) return true;
|
|
146
|
-
if (ig.providers && Object.keys(ig.providers).length > 0) return true;
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
function mindLimitError(count, limit) {
|
|
150
|
-
if (limit == null) return null;
|
|
151
|
-
if (count >= limit) {
|
|
152
|
-
return `Mind limit reached (${count}/${limit}). An admin can raise maxMinds in Settings.`;
|
|
153
|
-
}
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
function migrateSetupCompleted() {
|
|
157
|
-
const config = readGlobalConfig();
|
|
158
|
-
if (config.setup != null && config.setupCompleted == null) {
|
|
159
|
-
config.setupCompleted = true;
|
|
160
|
-
writeGlobalConfig(config);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export {
|
|
165
|
-
configPath,
|
|
166
|
-
secretsPath,
|
|
167
|
-
_resetConfigCache,
|
|
168
|
-
readGlobalConfig,
|
|
169
|
-
writeGlobalConfig,
|
|
170
|
-
migrateConfigSecrets,
|
|
171
|
-
setupStatus,
|
|
172
|
-
isSetupComplete,
|
|
173
|
-
setupUrl,
|
|
174
|
-
isImagegenEnabled,
|
|
175
|
-
mindLimitError,
|
|
176
|
-
migrateSetupCompleted
|
|
177
|
-
};
|