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
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// packages/cli/src/lib/format-cli.ts
|
|
4
|
+
var isCompact = () => !!process.env.VOLUTE_MIND;
|
|
5
|
+
function formatSender(name, displayName) {
|
|
6
|
+
if (displayName && displayName !== name) return `${displayName} (@${name})`;
|
|
7
|
+
return name;
|
|
8
|
+
}
|
|
9
|
+
function compactTime(dateStr) {
|
|
10
|
+
const d = new Date(dateStr.endsWith("Z") ? dateStr : `${dateStr}Z`);
|
|
11
|
+
return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
12
|
+
}
|
|
13
|
+
function compactDateTime(dateStr) {
|
|
14
|
+
const d = new Date(dateStr.endsWith("Z") ? dateStr : `${dateStr}Z`);
|
|
15
|
+
const y = d.getFullYear();
|
|
16
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
17
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
18
|
+
const h = String(d.getHours()).padStart(2, "0");
|
|
19
|
+
const min = String(d.getMinutes()).padStart(2, "0");
|
|
20
|
+
return `${y}-${m}-${day} ${h}:${min}`;
|
|
21
|
+
}
|
|
22
|
+
function formatMessageLine(msg, compact) {
|
|
23
|
+
const text = Array.isArray(msg.content) ? msg.content.filter((b) => b.type === "text").map((b) => b.text).join("") : msg.content;
|
|
24
|
+
const time = compact ? compactTime(msg.created_at) : new Date(
|
|
25
|
+
msg.created_at.endsWith("Z") ? msg.created_at : `${msg.created_at}Z`
|
|
26
|
+
).toLocaleString();
|
|
27
|
+
if (msg.role === "event") return `[${time}] \xB7 ${text}`;
|
|
28
|
+
const sender = compact ? msg.sender_name ?? msg.role : formatSender(msg.sender_name ?? msg.role, msg.sender_display_name);
|
|
29
|
+
return `[${time}] ${sender}: ${text}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
isCompact,
|
|
34
|
+
formatSender,
|
|
35
|
+
compactTime,
|
|
36
|
+
compactDateTime,
|
|
37
|
+
formatMessageLine
|
|
38
|
+
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getMindManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VAEZCIJC.js";
|
|
5
5
|
import {
|
|
6
6
|
chownMindDir,
|
|
7
7
|
gitExec
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-M77B73VV.js";
|
|
9
9
|
import {
|
|
10
10
|
logger_default
|
|
11
11
|
} from "./chunk-QUSMYGNQ.js";
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
mindDir,
|
|
15
15
|
readAllMinds,
|
|
16
16
|
removeMind
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-H6X6CKDN.js";
|
|
18
18
|
|
|
19
19
|
// packages/daemon/src/lib/mind/variant-cleanup.ts
|
|
20
20
|
import { existsSync, readdirSync, rmSync, statSync } from "fs";
|
|
21
21
|
import { resolve } from "path";
|
|
22
|
-
async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
22
|
+
async function cleanupVariant(variantName, baseName, projectRoot, variantPath, opts) {
|
|
23
23
|
if (opts?.stop) {
|
|
24
24
|
try {
|
|
25
25
|
await getMindManager().stopMind(variantName);
|
|
@@ -27,7 +27,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
|
27
27
|
logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
const { findMind } = await import("./registry-
|
|
30
|
+
const { findMind } = await import("./registry-TRC2HJXR.js");
|
|
31
31
|
const variantEntry = await findMind(variantName);
|
|
32
32
|
const branchName = variantEntry?.branch ?? variantName;
|
|
33
33
|
if (existsSync(variantPath)) {
|
|
@@ -47,7 +47,6 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
|
47
47
|
} catch (err) {
|
|
48
48
|
logger_default.warn(`failed to delete branch ${branchName} for ${variantName}`, logger_default.errorData(err));
|
|
49
49
|
}
|
|
50
|
-
const baseName = variantEntry?.parent ?? variantName;
|
|
51
50
|
try {
|
|
52
51
|
await removeMind(variantName);
|
|
53
52
|
} catch (err) {
|
|
@@ -78,7 +77,7 @@ async function reconcileVariants() {
|
|
|
78
77
|
`reconcile: dropping stale variant row ${v.name} (worktree ${v.dir ?? "<none>"} missing)`
|
|
79
78
|
);
|
|
80
79
|
try {
|
|
81
|
-
await cleanupVariant(v.name, baseDir(v.parent), v.dir ?? "");
|
|
80
|
+
await cleanupVariant(v.name, v.parent, baseDir(v.parent), v.dir ?? "");
|
|
82
81
|
} catch (err) {
|
|
83
82
|
logger_default.warn(`reconcile: failed to drop stale variant ${v.name}`, logger_default.errorData(err));
|
|
84
83
|
}
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
findBridgeForChannel,
|
|
4
4
|
getBridgeConfig
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-L7BKTZ5U.js";
|
|
6
6
|
import {
|
|
7
7
|
recordOutbound
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import {
|
|
10
|
-
publish
|
|
11
|
-
} from "./chunk-K3JOLGWF.js";
|
|
8
|
+
} from "./chunk-VP5PFNZO.js";
|
|
12
9
|
import {
|
|
13
10
|
getOrCreateMindUser,
|
|
14
11
|
getUserByUsername
|
|
15
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HKP6OAJP.js";
|
|
13
|
+
import {
|
|
14
|
+
publish
|
|
15
|
+
} from "./chunk-LNNI3MS4.js";
|
|
16
16
|
import {
|
|
17
17
|
addMessage,
|
|
18
18
|
findDMConversation,
|
|
@@ -20,18 +20,18 @@ import {
|
|
|
20
20
|
getChannelName,
|
|
21
21
|
getConversation,
|
|
22
22
|
getParticipants
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-TPX6E6PL.js";
|
|
24
24
|
import {
|
|
25
25
|
readVoluteConfig
|
|
26
26
|
} from "./chunk-WCFSBH33.js";
|
|
27
27
|
import {
|
|
28
28
|
daemonConfigPath,
|
|
29
29
|
readDaemonToken
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-6NLW72HP.js";
|
|
31
31
|
import {
|
|
32
32
|
readEnv,
|
|
33
33
|
sharedEnvPath
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-GLM7TVWP.js";
|
|
35
35
|
import {
|
|
36
36
|
logger_default
|
|
37
37
|
} from "./chunk-QUSMYGNQ.js";
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
} from "./chunk-LGNUFVMR.js";
|
|
41
41
|
import {
|
|
42
42
|
mindDir
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-H6X6CKDN.js";
|
|
44
44
|
import {
|
|
45
45
|
__export
|
|
46
46
|
} from "./chunk-K3NQKI34.js";
|
|
@@ -581,6 +581,7 @@ async function read4(env, channelSlug, limit) {
|
|
|
581
581
|
}
|
|
582
582
|
return data.items.slice(-limit).map((m) => {
|
|
583
583
|
const text = Array.isArray(m.content) ? m.content.filter((b) => b.type === "text").map((b) => b.text).join("") : m.content;
|
|
584
|
+
if (m.role === "event") return `\xB7 ${text}`;
|
|
584
585
|
return `${m.sender_name ?? m.role}: ${text}`;
|
|
585
586
|
}).join("\n");
|
|
586
587
|
}
|
|
@@ -595,7 +596,7 @@ async function send4(env, channelSlug, message, images) {
|
|
|
595
596
|
};
|
|
596
597
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
597
598
|
const voluteSession = env.VOLUTE_SESSION || (env.VOLUTE_MIND_DIR ? readSessionFile(env.VOLUTE_MIND_DIR) : void 0);
|
|
598
|
-
if (voluteSession) headers["X-Volute-
|
|
599
|
+
if (voluteSession) headers["X-Volute-Thread"] = voluteSession;
|
|
599
600
|
const res = await fetch(`${url}/api/v1/chat`, {
|
|
600
601
|
method: "POST",
|
|
601
602
|
headers,
|
|
@@ -1,74 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
publish
|
|
4
|
+
} from "./chunk-LNNI3MS4.js";
|
|
2
5
|
import {
|
|
3
6
|
getPrompt
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FXWBFDQR.js";
|
|
5
8
|
import {
|
|
6
9
|
aiCompleteUtility
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-EGV6R6UF.js";
|
|
8
11
|
import {
|
|
9
12
|
logger_default
|
|
10
13
|
} from "./chunk-QUSMYGNQ.js";
|
|
11
14
|
import {
|
|
12
15
|
getDb
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-H6X6CKDN.js";
|
|
14
17
|
import {
|
|
15
18
|
messages,
|
|
16
19
|
mindHistory,
|
|
17
20
|
summaries,
|
|
18
21
|
turns
|
|
19
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-2RNMBXD2.js";
|
|
20
23
|
|
|
21
24
|
// packages/daemon/src/lib/daemon/turn-tracker.ts
|
|
22
25
|
import { randomUUID } from "crypto";
|
|
23
|
-
import { and as and2, eq as eq2, sql as sql2 } from "drizzle-orm";
|
|
26
|
+
import { and as and2, eq as eq2, inArray as inArray2, sql as sql2 } from "drizzle-orm";
|
|
24
27
|
|
|
25
28
|
// packages/daemon/src/lib/daemon/summarizer.ts
|
|
26
29
|
import { and, desc, eq, gte, inArray, like, lt, sql } from "drizzle-orm";
|
|
27
30
|
|
|
28
|
-
// packages/daemon/src/lib/events/mind-events.ts
|
|
29
|
-
var subscribers = /* @__PURE__ */ new Map();
|
|
30
|
-
var globalSubscribers = /* @__PURE__ */ new Set();
|
|
31
|
-
function subscribe(mind, callback) {
|
|
32
|
-
let set = subscribers.get(mind);
|
|
33
|
-
if (!set) {
|
|
34
|
-
set = /* @__PURE__ */ new Set();
|
|
35
|
-
subscribers.set(mind, set);
|
|
36
|
-
}
|
|
37
|
-
set.add(callback);
|
|
38
|
-
return () => {
|
|
39
|
-
set.delete(callback);
|
|
40
|
-
if (set.size === 0) subscribers.delete(mind);
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
function subscribeAll(callback) {
|
|
44
|
-
globalSubscribers.add(callback);
|
|
45
|
-
return () => {
|
|
46
|
-
globalSubscribers.delete(callback);
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
function publish(mind, event) {
|
|
50
|
-
const set = subscribers.get(mind);
|
|
51
|
-
if (set) {
|
|
52
|
-
for (const cb of set) {
|
|
53
|
-
try {
|
|
54
|
-
cb(event);
|
|
55
|
-
} catch (err) {
|
|
56
|
-
logger_default.error(`[mind-events] subscriber threw for ${mind}`, logger_default.errorData(err));
|
|
57
|
-
set.delete(cb);
|
|
58
|
-
if (set.size === 0) subscribers.delete(mind);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
for (const cb of globalSubscribers) {
|
|
63
|
-
try {
|
|
64
|
-
cb(event);
|
|
65
|
-
} catch (err) {
|
|
66
|
-
logger_default.error("[mind-events] global subscriber threw", logger_default.errorData(err));
|
|
67
|
-
globalSubscribers.delete(cb);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
31
|
// packages/daemon/src/lib/util/format-tool.ts
|
|
73
32
|
function summarizeTool(name, input) {
|
|
74
33
|
if (input && typeof input === "object") {
|
|
@@ -166,6 +125,33 @@ function utcDateTimeStr(d) {
|
|
|
166
125
|
function parseUtcDateTime(s) {
|
|
167
126
|
return /* @__PURE__ */ new Date(`${s.replace(" ", "T")}Z`);
|
|
168
127
|
}
|
|
128
|
+
function getUtcTimeRange(periodKey, period) {
|
|
129
|
+
switch (period) {
|
|
130
|
+
case "hour": {
|
|
131
|
+
const d = /* @__PURE__ */ new Date(`${periodKey.slice(0, 10)}T${periodKey.slice(11)}:00:00`);
|
|
132
|
+
return { start: utcDateTimeStr(d), end: utcDateTimeStr(new Date(d.getTime() + 36e5)) };
|
|
133
|
+
}
|
|
134
|
+
case "day": {
|
|
135
|
+
const d = /* @__PURE__ */ new Date(`${periodKey}T00:00:00`);
|
|
136
|
+
const dEnd = new Date(d);
|
|
137
|
+
dEnd.setDate(d.getDate() + 1);
|
|
138
|
+
return { start: utcDateTimeStr(d), end: utcDateTimeStr(dEnd) };
|
|
139
|
+
}
|
|
140
|
+
case "week": {
|
|
141
|
+
const monday = isoWeekToDate(periodKey);
|
|
142
|
+
const nextMonday = new Date(monday);
|
|
143
|
+
nextMonday.setDate(monday.getDate() + 7);
|
|
144
|
+
return { start: utcDateTimeStr(monday), end: utcDateTimeStr(nextMonday) };
|
|
145
|
+
}
|
|
146
|
+
case "month": {
|
|
147
|
+
const [y, m] = periodKey.split("-").map(Number);
|
|
148
|
+
return {
|
|
149
|
+
start: utcDateTimeStr(new Date(y, m - 1, 1)),
|
|
150
|
+
end: utcDateTimeStr(new Date(y, m, 1))
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
169
155
|
function getTimeRange(periodKey, period) {
|
|
170
156
|
switch (period) {
|
|
171
157
|
case "hour": {
|
|
@@ -206,19 +192,19 @@ async function gatherTurnEvents(mind, session, doneId) {
|
|
|
206
192
|
eq(mindHistory.type, "done"),
|
|
207
193
|
lt(mindHistory.id, doneId)
|
|
208
194
|
];
|
|
209
|
-
if (session) subConditions.push(eq(mindHistory.
|
|
195
|
+
if (session) subConditions.push(eq(mindHistory.thread, session));
|
|
210
196
|
const prevDoneSubquery = db.select({ id: mindHistory.id }).from(mindHistory).where(and(...subConditions)).orderBy(desc(mindHistory.id)).limit(1);
|
|
211
197
|
const turnConditions = [
|
|
212
198
|
eq(mindHistory.mind, mind),
|
|
213
199
|
sql`${mindHistory.id} > COALESCE((${prevDoneSubquery}), 0)`,
|
|
214
200
|
sql`${mindHistory.id} <= ${doneId}`
|
|
215
201
|
];
|
|
216
|
-
if (session) turnConditions.push(eq(mindHistory.
|
|
202
|
+
if (session) turnConditions.push(eq(mindHistory.thread, session));
|
|
217
203
|
const events = await db.select({
|
|
218
204
|
id: mindHistory.id,
|
|
219
205
|
type: mindHistory.type,
|
|
220
206
|
channel: mindHistory.channel,
|
|
221
|
-
session: mindHistory.
|
|
207
|
+
session: mindHistory.thread,
|
|
222
208
|
content: mindHistory.content,
|
|
223
209
|
metadata: mindHistory.metadata,
|
|
224
210
|
turn_id: mindHistory.turn_id,
|
|
@@ -236,7 +222,7 @@ async function gatherTurnEventsByTurnId(turnId) {
|
|
|
236
222
|
id: mindHistory.id,
|
|
237
223
|
type: mindHistory.type,
|
|
238
224
|
channel: mindHistory.channel,
|
|
239
|
-
session: mindHistory.
|
|
225
|
+
session: mindHistory.thread,
|
|
240
226
|
content: mindHistory.content,
|
|
241
227
|
metadata: mindHistory.metadata,
|
|
242
228
|
turn_id: mindHistory.turn_id,
|
|
@@ -266,11 +252,16 @@ function buildTurnDeterministicSummary(events, parsedMeta) {
|
|
|
266
252
|
const tools = [];
|
|
267
253
|
let hasInbound = false;
|
|
268
254
|
let hasOutbound = false;
|
|
255
|
+
let eventLabel;
|
|
269
256
|
for (const ev of events) {
|
|
270
257
|
if (ev.type === "inbound") {
|
|
271
258
|
hasInbound = true;
|
|
272
259
|
if (ev.channel) channels.add(ev.channel);
|
|
273
260
|
}
|
|
261
|
+
if (ev.type === "event") {
|
|
262
|
+
const label = parsedMeta.get(ev.id)?.label;
|
|
263
|
+
eventLabel = typeof label === "string" && label ? label : "System event";
|
|
264
|
+
}
|
|
274
265
|
if (ev.type === "outbound" || ev.type === "text") {
|
|
275
266
|
hasOutbound = true;
|
|
276
267
|
}
|
|
@@ -280,6 +271,9 @@ function buildTurnDeterministicSummary(events, parsedMeta) {
|
|
|
280
271
|
}
|
|
281
272
|
}
|
|
282
273
|
const parts = [];
|
|
274
|
+
if (eventLabel) {
|
|
275
|
+
parts.push(`System event: ${eventLabel}`);
|
|
276
|
+
}
|
|
283
277
|
if (hasInbound) {
|
|
284
278
|
const channelList = [...channels];
|
|
285
279
|
parts.push(
|
|
@@ -302,6 +296,16 @@ function buildTranscript(events, parsedMeta) {
|
|
|
302
296
|
case "inbound":
|
|
303
297
|
lines.push(`[inbound${ev.channel ? ` ${ev.channel}` : ""}] ${ev.content ?? ""}`);
|
|
304
298
|
break;
|
|
299
|
+
// A system event is what triggered the turn — the summarizer needs to see it, or a
|
|
300
|
+
// schedule/orientation/wake turn gets summarized from its tool calls alone, with no
|
|
301
|
+
// idea what prompted them. Framed as an event, not an inbound message: it has no
|
|
302
|
+
// sender, and the summary shouldn't imply someone spoke to the mind.
|
|
303
|
+
case "event": {
|
|
304
|
+
const label = parsedMeta.get(ev.id)?.label;
|
|
305
|
+
const named = typeof label === "string" && label ? `: ${label}` : "";
|
|
306
|
+
lines.push(`[system event${named}] ${ev.content ?? ""}`);
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
305
309
|
case "outbound":
|
|
306
310
|
case "text":
|
|
307
311
|
lines.push(`[response] ${(ev.content ?? "").slice(0, 500)}`);
|
|
@@ -345,7 +349,14 @@ async function summarizeTurn(mind, session, channel, doneId, turnId) {
|
|
|
345
349
|
if (effectiveTurnId) {
|
|
346
350
|
try {
|
|
347
351
|
const db2 = await getDb();
|
|
348
|
-
await db2.update(mindHistory).set({ turn_id: null }).where(
|
|
352
|
+
await db2.update(mindHistory).set({ turn_id: null }).where(
|
|
353
|
+
and(
|
|
354
|
+
eq(mindHistory.turn_id, effectiveTurnId),
|
|
355
|
+
// Release system-event rows too, so an interrupted event turn's row can be
|
|
356
|
+
// re-linked to the turn that actually processes it.
|
|
357
|
+
inArray(mindHistory.type, ["inbound", "event"])
|
|
358
|
+
)
|
|
359
|
+
);
|
|
349
360
|
await db2.update(messages).set({ turn_id: null }).where(eq(messages.turn_id, effectiveTurnId));
|
|
350
361
|
await db2.delete(turns).where(eq(turns.id, effectiveTurnId));
|
|
351
362
|
} catch (err) {
|
|
@@ -1049,11 +1060,11 @@ var Summarizer = class {
|
|
|
1049
1060
|
}
|
|
1050
1061
|
};
|
|
1051
1062
|
async function reconcileWedgedTurns(idleMs) {
|
|
1052
|
-
const { sweepWedgedTurns: sweepWedgedTurns2, summarizeOrphanedTurns: summarizeOrphanedTurns2 } = await import("./turn-tracker-
|
|
1063
|
+
const { sweepWedgedTurns: sweepWedgedTurns2, summarizeOrphanedTurns: summarizeOrphanedTurns2 } = await import("./turn-tracker-TAT2HGK6.js");
|
|
1053
1064
|
const wedged = await sweepWedgedTurns2(idleMs);
|
|
1054
1065
|
if (wedged.length === 0) return;
|
|
1055
1066
|
summarizeOrphanedTurns2(wedged);
|
|
1056
|
-
const { tryGetDeliveryManager } = await import("./delivery-manager-
|
|
1067
|
+
const { tryGetDeliveryManager } = await import("./delivery-manager-HGVZSEES.js");
|
|
1057
1068
|
const dm = tryGetDeliveryManager();
|
|
1058
1069
|
if (!dm) return;
|
|
1059
1070
|
for (const t of wedged) {
|
|
@@ -1112,7 +1123,8 @@ async function linkInboundToActiveTurn(mind, session, channel) {
|
|
|
1112
1123
|
await db.update(mindHistory).set({ turn_id: turnId }).where(
|
|
1113
1124
|
and2(
|
|
1114
1125
|
eq2(mindHistory.mind, mind),
|
|
1115
|
-
|
|
1126
|
+
// System events ("event") arrive mid-turn too and need the same attribution.
|
|
1127
|
+
inArray2(mindHistory.type, ["inbound", "event"]),
|
|
1116
1128
|
sql2`${mindHistory.turn_id} IS NULL`,
|
|
1117
1129
|
eq2(mindHistory.channel, channel)
|
|
1118
1130
|
)
|
|
@@ -1145,7 +1157,7 @@ async function assignSession(mind, turnId, session) {
|
|
|
1145
1157
|
}
|
|
1146
1158
|
try {
|
|
1147
1159
|
const db = await getDb();
|
|
1148
|
-
await db.update(turns).set({ session }).where(eq2(turns.id, turnId));
|
|
1160
|
+
await db.update(turns).set({ thread: session }).where(eq2(turns.id, turnId));
|
|
1149
1161
|
} catch (err) {
|
|
1150
1162
|
tlog.error(`failed to assign session to turn ${turnId}`, logger_default.errorData(err));
|
|
1151
1163
|
return;
|
|
@@ -1171,7 +1183,7 @@ async function completeTurn(mind, session) {
|
|
|
1171
1183
|
}
|
|
1172
1184
|
async function completeOrphanedTurns() {
|
|
1173
1185
|
const db = await getDb();
|
|
1174
|
-
const active = await db.select({ id: turns.id, mind: turns.mind, session: turns.
|
|
1186
|
+
const active = await db.select({ id: turns.id, mind: turns.mind, session: turns.thread }).from(turns).where(eq2(turns.status, "active"));
|
|
1175
1187
|
if (active.length === 0) return [];
|
|
1176
1188
|
try {
|
|
1177
1189
|
await db.update(turns).set({ status: "complete" }).where(eq2(turns.status, "active"));
|
|
@@ -1220,7 +1232,7 @@ async function sweepWedgedTurns(idleMs) {
|
|
|
1220
1232
|
const cutoff = new Date(Date.now() - idleMs).toISOString().slice(0, 19).replace("T", " ");
|
|
1221
1233
|
let rows;
|
|
1222
1234
|
try {
|
|
1223
|
-
rows = await db.select({ id: turns.id, mind: turns.mind, session: turns.
|
|
1235
|
+
rows = await db.select({ id: turns.id, mind: turns.mind, session: turns.thread }).from(turns).innerJoin(mindHistory, eq2(mindHistory.turn_id, turns.id)).where(eq2(turns.status, "active")).groupBy(turns.id).having(
|
|
1224
1236
|
sql2`max(${mindHistory.created_at}) < ${cutoff} and sum(case when ${mindHistory.type} = 'done' then 1 else 0 end) > 0`
|
|
1225
1237
|
);
|
|
1226
1238
|
} catch (err) {
|
|
@@ -1251,11 +1263,12 @@ function summarizeOrphanedTurns(orphanedTurns) {
|
|
|
1251
1263
|
}
|
|
1252
1264
|
|
|
1253
1265
|
export {
|
|
1254
|
-
|
|
1255
|
-
subscribeAll,
|
|
1256
|
-
publish,
|
|
1266
|
+
getPeriodKey,
|
|
1257
1267
|
isoWeekKeyForDateStr,
|
|
1258
1268
|
utcDateTimeStr,
|
|
1269
|
+
parseUtcDateTime,
|
|
1270
|
+
getUtcTimeRange,
|
|
1271
|
+
SYSTEM_MIND,
|
|
1259
1272
|
summarizeTurn,
|
|
1260
1273
|
initSummarizer,
|
|
1261
1274
|
markErrored,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
computeTemplateHash
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HTRSSOHY.js";
|
|
5
5
|
import {
|
|
6
6
|
composeTemplate,
|
|
7
7
|
findTemplatesRoot,
|
|
8
8
|
listFiles
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-X67BDDZR.js";
|
|
10
10
|
import {
|
|
11
11
|
logger_default
|
|
12
12
|
} from "./chunk-QUSMYGNQ.js";
|
|
13
13
|
import {
|
|
14
14
|
mindDir
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-H6X6CKDN.js";
|
|
16
16
|
|
|
17
17
|
// packages/daemon/src/lib/mind/template-staleness.ts
|
|
18
18
|
import { createHash } from "crypto";
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getSleepManagerIfReady,
|
|
4
|
+
startSpiritFull
|
|
5
|
+
} from "./chunk-VP5PFNZO.js";
|
|
6
|
+
import {
|
|
7
|
+
spiritCreationInProgress
|
|
8
|
+
} from "./chunk-VSBMLB2W.js";
|
|
9
|
+
import {
|
|
10
|
+
MindStartupError,
|
|
11
|
+
tryGetMindManager
|
|
12
|
+
} from "./chunk-VAEZCIJC.js";
|
|
13
|
+
import {
|
|
14
|
+
logger_default
|
|
15
|
+
} from "./chunk-QUSMYGNQ.js";
|
|
16
|
+
import {
|
|
17
|
+
computeSetupStatus,
|
|
18
|
+
findMind,
|
|
19
|
+
readGlobalConfigStrict
|
|
20
|
+
} from "./chunk-H6X6CKDN.js";
|
|
21
|
+
|
|
22
|
+
// packages/daemon/src/lib/chat/spirit-availability.ts
|
|
23
|
+
var slog = logger_default.child("spirit-availability");
|
|
24
|
+
var SPIRIT_NOTICE_PREFIX = "The system spirit isn't available";
|
|
25
|
+
var SETUP_INCOMPLETE_NOTICE = `${SPIRIT_NOTICE_PREFIX} (setup is incomplete). An admin can finish setup in Settings.`;
|
|
26
|
+
var CREATION_FAILED_NOTICE = `${SPIRIT_NOTICE_PREFIX} (it failed to start). An admin can check the daemon logs and Settings.`;
|
|
27
|
+
function classifySpiritState(i) {
|
|
28
|
+
if (!i.setupComplete || !i.spiritExists) return "cannot-exist";
|
|
29
|
+
if (i.sleeping) return "sleeping";
|
|
30
|
+
if (i.running) return "running";
|
|
31
|
+
if (i.recentlyFailed) return "cannot-exist";
|
|
32
|
+
return "stopped";
|
|
33
|
+
}
|
|
34
|
+
function spiritUnavailableNotice(setupComplete) {
|
|
35
|
+
return setupComplete ? CREATION_FAILED_NOTICE : SETUP_INCOMPLETE_NOTICE;
|
|
36
|
+
}
|
|
37
|
+
var lastOnDemandStartAt = 0;
|
|
38
|
+
var ON_DEMAND_RETRY_COOLDOWN_MS = 6e4;
|
|
39
|
+
function _resetSpiritAvailabilityState() {
|
|
40
|
+
lastOnDemandStartAt = 0;
|
|
41
|
+
}
|
|
42
|
+
async function ensureSpiritAvailable() {
|
|
43
|
+
try {
|
|
44
|
+
const manager = tryGetMindManager();
|
|
45
|
+
const sleepManager = getSleepManagerIfReady();
|
|
46
|
+
if (!manager || !sleepManager) return null;
|
|
47
|
+
let config;
|
|
48
|
+
try {
|
|
49
|
+
config = readGlobalConfigStrict();
|
|
50
|
+
} catch (err) {
|
|
51
|
+
slog.warn("global config unreadable \u2014 spirit availability indeterminate", {
|
|
52
|
+
...logger_default.errorData(err)
|
|
53
|
+
});
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const setupComplete = computeSetupStatus(config) === "complete";
|
|
57
|
+
const spiritName = config.setup?.spiritName ?? "volute";
|
|
58
|
+
const entry = setupComplete ? await findMind(spiritName) : void 0;
|
|
59
|
+
if (setupComplete && !entry && spiritCreationInProgress()) return null;
|
|
60
|
+
const recentlyFailed = manager.hasExhaustedRestarts(spiritName) || lastOnDemandStartAt > 0 && Date.now() - lastOnDemandStartAt < ON_DEMAND_RETRY_COOLDOWN_MS;
|
|
61
|
+
const state = classifySpiritState({
|
|
62
|
+
setupComplete,
|
|
63
|
+
spiritExists: !!entry,
|
|
64
|
+
sleeping: sleepManager.isSleeping(spiritName),
|
|
65
|
+
running: manager.isRunning(spiritName),
|
|
66
|
+
recentlyFailed
|
|
67
|
+
});
|
|
68
|
+
switch (state) {
|
|
69
|
+
case "cannot-exist":
|
|
70
|
+
return { status: "unavailable", notice: spiritUnavailableNotice(setupComplete) };
|
|
71
|
+
case "sleeping":
|
|
72
|
+
return { status: "sleeping" };
|
|
73
|
+
case "running":
|
|
74
|
+
return { status: "running" };
|
|
75
|
+
case "stopped":
|
|
76
|
+
try {
|
|
77
|
+
lastOnDemandStartAt = Date.now();
|
|
78
|
+
await startSpiritFull(spiritName);
|
|
79
|
+
return { status: "waking" };
|
|
80
|
+
} catch (err) {
|
|
81
|
+
if (err instanceof Error && err.message.includes("already running")) {
|
|
82
|
+
return { status: "running" };
|
|
83
|
+
}
|
|
84
|
+
if (manager.isRunning(spiritName)) {
|
|
85
|
+
slog.error("spirit started on demand but post-start setup failed", {
|
|
86
|
+
...logger_default.errorData(err)
|
|
87
|
+
});
|
|
88
|
+
return { status: "waking" };
|
|
89
|
+
}
|
|
90
|
+
slog.error("failed to start spirit on demand", {
|
|
91
|
+
...logger_default.errorData(err),
|
|
92
|
+
...err instanceof MindStartupError ? { stderr: err.stderr } : {}
|
|
93
|
+
});
|
|
94
|
+
return { status: "unavailable", notice: spiritUnavailableNotice(setupComplete) };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} catch (err) {
|
|
98
|
+
slog.error("spirit availability check failed", { ...logger_default.errorData(err) });
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
SPIRIT_NOTICE_PREFIX,
|
|
105
|
+
classifySpiritState,
|
|
106
|
+
spiritUnavailableNotice,
|
|
107
|
+
_resetSpiritAvailabilityState,
|
|
108
|
+
ensureSpiritAvailable
|
|
109
|
+
};
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
exec
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
readGlobalConfig
|
|
7
|
-
} from "./chunk-NJHN6IRB.js";
|
|
4
|
+
} from "./chunk-M77B73VV.js";
|
|
8
5
|
import {
|
|
9
6
|
logger_default
|
|
10
7
|
} from "./chunk-QUSMYGNQ.js";
|
|
11
8
|
import {
|
|
12
9
|
getDb,
|
|
13
10
|
readAllMinds,
|
|
11
|
+
readGlobalConfig,
|
|
14
12
|
voluteHome,
|
|
15
13
|
voluteSystemDir
|
|
16
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-H6X6CKDN.js";
|
|
17
15
|
|
|
18
16
|
// packages/daemon/src/lib/backup/restic.ts
|
|
19
17
|
import { writeFileSync } from "fs";
|