volute 0.53.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activity-events-LQII6PZS.js → activity-events-TFAJBNBW.js} +2 -2
- package/dist/{ai-service-YW5SWCSB.js → ai-service-KEK2V3AP.js} +2 -2
- package/dist/{auth-KRDSM55Q.js → auth-Y27LTNZK.js} +3 -3
- package/dist/auto-upgrade-2MZF7NG3.js +46 -0
- package/dist/{avatar-image-52WGXLHV.js → avatar-image-SN576P45.js} +2 -2
- package/dist/{backup-WWXVIMYQ.js → backup-GDCWH6MC.js} +12 -12
- package/dist/channels-AFJWGX7W.js +203 -0
- package/dist/{chat-WK2BLM7B.js → chat-HVPOZK3O.js} +9 -9
- package/dist/{chunk-QUSMYGNQ.js → chunk-2674KIGI.js} +1 -0
- package/dist/chunk-2GATCSZK.js +520 -0
- package/dist/{chunk-P2TBUKLW.js → chunk-3SFKY4GI.js} +4 -4
- package/dist/{chunk-RMADJFA7.js → chunk-45QTYKQQ.js} +4 -4
- package/dist/{chunk-TAWRJ24T.js → chunk-4VAQKLMU.js} +8 -5
- package/dist/{chunk-OXWUEU5V.js → chunk-5U5GLZSD.js} +2 -2
- package/dist/{chunk-TPX6E6PL.js → chunk-6HBGUPBA.js} +2 -2
- package/dist/{chunk-UFTDRTCP.js → chunk-7AA4T2RT.js} +2 -2
- package/dist/{chunk-LN7XJ56R.js → chunk-7XKPG66D.js} +9 -9
- package/dist/{chunk-VDZ4I4ZP.js → chunk-BP2X5AIK.js} +8 -14
- package/dist/{chunk-PIZDPY4G.js → chunk-CKOA4LWV.js} +12 -12
- package/dist/{chunk-6NLW72HP.js → chunk-CKPAVQNK.js} +1 -1
- package/dist/{chunk-IQ7VNWH6.js → chunk-DUV4EMNW.js} +37 -3
- package/dist/{chunk-CV6BNGFK.js → chunk-FSXPPOPM.js} +3 -3
- package/dist/{chunk-UTKUO2KY.js → chunk-FZUPIS3T.js} +3 -3
- package/dist/{chunk-L7BKTZ5U.js → chunk-G3XAB4DK.js} +1 -1
- package/dist/{chunk-23UJGVYP.js → chunk-HLWQ3P3R.js} +50 -46
- package/dist/{chunk-AP2KQMMW.js → chunk-HTSWDOJE.js} +11 -14
- package/dist/{chunk-EDR47UE2.js → chunk-IR2FW4W7.js} +2 -2
- package/dist/{chunk-ICXY54ZC.js → chunk-IT4GEFDH.js} +1 -1
- package/dist/{chunk-F6D766VQ.js → chunk-KS62IHE2.js} +1 -1
- package/dist/{chunk-LNNI3MS4.js → chunk-MNKPAAQF.js} +9 -2
- package/dist/{chunk-HASADR3E.js → chunk-NCRG4SBR.js} +241 -66
- package/dist/{chunk-I7U5EEZC.js → chunk-NM5FDH4T.js} +1 -1
- package/dist/{chunk-7LT3YZUR.js → chunk-OFU6WJJZ.js} +1 -1
- package/dist/{chunk-M77B73VV.js → chunk-OIOW3FPT.js} +7 -2
- package/dist/{chunk-BDHKCLWK.js → chunk-OKM67ZWH.js} +1 -1
- package/dist/chunk-OUGD5L5U.js +918 -0
- package/dist/{chunk-X67BDDZR.js → chunk-P3GXOT2X.js} +48 -2
- package/dist/{chunk-U54PJPTB.js → chunk-PRZUBJ4K.js} +1 -1
- package/dist/{chunk-UO4MZQNO.js → chunk-QVS3C4DK.js} +15 -7
- package/dist/{chunk-RQRO6PC7.js → chunk-TMTAHKYP.js} +324 -48
- package/dist/{chunk-5DBGQBQR.js → chunk-UEZC5MNB.js} +29 -18
- package/dist/{chunk-7ARONCZW.js → chunk-VTFXZPC3.js} +13 -13
- package/dist/{chunk-UDZLPR34.js → chunk-W3OIPJPB.js} +14 -9
- package/dist/{chunk-HTB7KDRU.js → chunk-WZZCA23D.js} +5 -4
- package/dist/{chunk-5Y54AE3L.js → chunk-XAG53RWY.js} +1 -1
- package/dist/{chunk-HTRSSOHY.js → chunk-YU5EYQAE.js} +1 -1
- package/dist/{chunk-5N32EN4O.js → chunk-Z4Q6TQWL.js} +1 -1
- package/dist/{chunk-EGV6R6UF.js → chunk-Z7TNIIHW.js} +3 -1
- package/dist/cli.js +19 -19
- package/dist/{clock-SH4NQC2F.js → clock-X7V3C7NL.js} +3 -3
- package/dist/{cloud-sync-MJVJ33LD.js → cloud-sync-FM73SVFJ.js} +21 -21
- package/dist/{conversations-ZL6PHROD.js → conversations-FH3ODBL7.js} +3 -3
- package/dist/{create-G2RIKQYK.js → create-P75ZFTVN.js} +1 -1
- package/dist/{daemon-restart-BIGU4OKS.js → daemon-restart-JQMMMITM.js} +4 -4
- package/dist/daemon.js +469 -857
- package/dist/db-JH3NTERX.js +36 -0
- package/dist/delivery-manager-H23Q23N7.js +41 -0
- package/dist/{delivery-notices-65TB3CBX.js → delivery-notices-S7TKOACE.js} +5 -5
- package/dist/{delivery-router-RHANNTAC.js → delivery-router-KHBVEVVL.js} +4 -2
- package/dist/{down-QSNEMTTX.js → down-UN2EDX2Y.js} +3 -3
- package/dist/echo-text-ULEIFJJF.js +40 -0
- package/dist/{exec-ABD3DYA2.js → exec-Z34TTUO3.js} +1 -1
- package/dist/extensions-QD22GXZD.js +74 -0
- package/dist/{files-CHPNEQXN.js → files-DUGRXN6V.js} +5 -5
- package/dist/{import-DB2KULRO.js → import-RDDUGGFI.js} +3 -3
- package/dist/{isolation-GVV2IBAU.js → isolation-UQPDO34R.js} +1 -1
- package/dist/message-delivery-LU4EP244.js +46 -0
- package/dist/migrate-init-infrastructure-Z72UJ5NT.js +44 -0
- package/dist/migrate-name-placeholder-64AEAWPE.js +37 -0
- package/dist/{migrate-thread-config-EQSEP2XG.js → migrate-thread-config-SVF2M3D3.js} +1 -1
- package/dist/{mind-IX5AWUST.js → mind-BARCLI7O.js} +14 -14
- package/dist/{mind-activity-tracker-QF6DCX2X.js → mind-activity-tracker-UT23RGBF.js} +3 -3
- package/dist/{mind-contacts-BKUOUJPV.js → mind-contacts-PEXCDRXA.js} +8 -8
- package/dist/{mind-list-KNU34SUD.js → mind-list-7KBLPLES.js} +2 -2
- package/dist/mind-service-ZJCUBAUL.js +48 -0
- package/dist/{mind-sleep-D3DEYAWG.js → mind-sleep-24HV4RCA.js} +5 -5
- package/dist/{mind-status-BPTLQ5Z6.js → mind-status-4YW4PHMO.js} +6 -3
- package/dist/{package-BN5KMU54.js → package-AUDBDKAO.js} +12 -14
- package/dist/{prompts-HNKGCAEY.js → prompts-MOBF3TMO.js} +1 -1
- package/dist/{sandbox-NNWCTHRI.js → sandbox-VI7XWBIA.js} +2 -2
- package/dist/scheduler-GLINVC2B.js +27 -0
- package/dist/{seed-LHZ33UB4.js → seed-5JGR7ZRA.js} +1 -1
- package/dist/{seed-cmd-U4RVJ3UA.js → seed-cmd-M6A7N7F3.js} +2 -2
- package/dist/{seed-create-OQU4KNCB.js → seed-create-TGFZW4IO.js} +3 -3
- package/dist/{seed-readiness-WJYYRRCK.js → seed-readiness-XBH2MUNA.js} +2 -2
- package/dist/{seed-sprout-SFUYH2RG.js → seed-sprout-3IC5ZVTI.js} +11 -11
- package/dist/{send-FWZAMDBN.js → send-DHYBAYK4.js} +11 -11
- package/dist/{service-XQPMZAGI.js → service-T4P5W6RS.js} +2 -2
- package/dist/{service-install-2EWD7KXD.js → service-install-R4SNYUVO.js} +3 -3
- package/dist/{setup-RVSGCIF3.js → setup-6KAH3GRW.js} +4 -4
- package/dist/skills/dreaming/SKILL.md +2 -2
- package/dist/skills/dreaming/references/INSTALL.md +1 -1
- package/dist/skills/tending/SKILL.md +2 -0
- package/dist/skills/volute-mind/SKILL.md +8 -0
- package/dist/skills/volute-mind/references/integrations.md +3 -2
- package/dist/skills/volute-mind/references/routing.md +18 -5
- package/dist/{skills-QRPU6BWY.js → skills-LKQCYFVP.js} +3 -3
- package/dist/sleep-manager-Q3ITFNOJ.js +42 -0
- package/dist/{spirit-I5ECLGRI.js → spirit-FKXMGO3N.js} +8 -6
- package/dist/spirit-availability-5R2WYSWF.js +43 -0
- package/dist/{sprout-A2PMEF7Z.js → sprout-VEW3CUNX.js} +1 -1
- package/dist/src-246GSX7A.js +519 -0
- package/dist/src-LOUB3WPR.js +4189 -0
- package/dist/{status-EYG4A3OK.js → status-LCKTTIWS.js} +5 -5
- package/dist/{system-events-YTOU66QI.js → system-events-ZYOCYAO2.js} +5 -3
- package/dist/{systems-2DIJY4RF.js → systems-HL7SGSW7.js} +6 -6
- package/dist/{tailscale-KHNZFC7L.js → tailscale-F2IMBILZ.js} +1 -1
- package/dist/{template-hash-YKWMVYMM.js → template-hash-RJRMF6DT.js} +2 -2
- package/dist/{template-staleness-PY2CULH6.js → template-staleness-IBD722PN.js} +4 -4
- package/dist/{turn-tracker-NNHS6MAR.js → turn-tracker-BE34OI6O.js} +7 -7
- package/dist/{up-UGBHH743.js → up-J47J5JRB.js} +3 -3
- package/dist/{update-CIWI2JYA.js → update-ILCPVNDD.js} +2 -2
- package/dist/{upgrade-LIE46UBB.js → upgrade-XY2J7NWZ.js} +9 -1
- package/dist/variant-cleanup-JGJZ5KB4.js +24 -0
- package/dist/{version-notify-SJVAQLZI.js → version-notify-KIXYNHJC.js} +28 -13
- package/dist/web-assets/assets/{index-b7G7ZsVk.js → index-CoU1eUKE.js} +25 -25
- package/dist/web-assets/assets/index-hPn_fkz3.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +12 -14
- package/packages/extensions/intentions/dist/ui/assets/index-3FneLCKR.css +1 -0
- package/packages/extensions/intentions/dist/ui/assets/index-Bl5KEcli.js +67 -0
- package/packages/extensions/{notes → intentions}/dist/ui/index.html +3 -3
- package/packages/extensions/intentions/skills/intention-review/SKILL.md +38 -0
- package/packages/extensions/intentions/skills/intentions/SKILL.md +49 -0
- package/packages/extensions/intentions/skills/intentions/scripts/intentions-hook.sh +45 -0
- package/packages/extensions/pages/dist/ui/assets/index-BKxVQkA9.css +1 -0
- package/packages/extensions/pages/dist/ui/assets/index-BMt6sStP.js +68 -0
- package/packages/extensions/pages/dist/ui/index.html +2 -2
- package/packages/extensions/pages/skills/commons-gardening/SKILL.md +50 -0
- package/packages/extensions/pages/skills/pages/SKILL.md +140 -16
- package/templates/_base/.init/.config/prompts.json +2 -3
- package/templates/{pi → _base}/.init/.config/routes.json +1 -0
- package/templates/_base/.init/.local/hooks/pre-prompt/turn-context.ts +30 -0
- package/templates/_base/.init/memory/dreams/.gitkeep +0 -0
- package/templates/_base/home/.config/routes.json +1 -1
- package/templates/_base/home/VOLUTE.md +1 -1
- package/templates/_base/src/lib/codex-session-seed.ts +6 -55
- package/templates/_base/src/lib/context-breakdown.ts +11 -3
- package/templates/_base/src/lib/pi-session-seed.ts +8 -57
- package/templates/_base/src/lib/routing.ts +2 -2
- package/templates/_base/src/lib/seed-note.ts +4 -4
- package/templates/_base/src/lib/session-seed.ts +8 -53
- package/templates/_base/src/lib/startup.ts +4 -22
- package/templates/claude/.init/CLAUDE.md +4 -0
- package/templates/claude/package.json +2 -2
- package/templates/claude/src/agent.ts +60 -112
- package/templates/claude/src/lib/hooks/pre-compact.ts +6 -6
- package/templates/claude/src/lib/message-channel.ts +43 -15
- package/templates/claude/src/lib/recover.ts +69 -0
- package/templates/claude/src/lib/stream-consumer.ts +23 -5
- package/templates/claude/src/server.ts +0 -1
- package/templates/claude/volute-template.json +1 -1
- package/templates/codex/.init/AGENTS.md +4 -0
- package/templates/codex/package.json +2 -2
- package/templates/codex/src/agent.ts +23 -89
- package/templates/codex/volute-template.json +1 -1
- package/templates/pi/.init/MINDS.md +4 -0
- package/templates/pi/package.json +1 -1
- package/templates/pi/src/agent.ts +26 -93
- package/templates/pi/src/lib/mechanics-doc.ts +30 -0
- package/templates/pi/src/server.ts +3 -2
- package/templates/pi/volute-template.json +1 -1
- package/dist/channels-LW5ZLMSQ.js +0 -90
- package/dist/chunk-R772ET2M.js +0 -164
- package/dist/db-IPXRJUI7.js +0 -20
- package/dist/delivery-manager-FDHCZ7PU.js +0 -37
- package/dist/echo-text-KU6G4Z7V.js +0 -40
- package/dist/extensions-VACUKFA5.js +0 -60
- package/dist/message-delivery-TUXM3AAE.js +0 -46
- package/dist/mind-service-WHFBUKZE.js +0 -48
- package/dist/scheduler-5X5UIQOQ.js +0 -27
- package/dist/skills/plan-coordinator/SKILL.md +0 -60
- package/dist/sleep-manager-NWUCRBZB.js +0 -42
- package/dist/spirit-availability-NIUUYKU2.js +0 -43
- package/dist/src-HGNE2XG4.js +0 -832
- package/dist/src-LCSOQY6Z.js +0 -2222
- package/dist/src-UDMJZ6MH.js +0 -426
- package/dist/variant-cleanup-CZDLIY3F.js +0 -24
- package/dist/web-assets/assets/index-BHSU9r-4.css +0 -1
- package/packages/extensions/notes/dist/ui/assets/index-BBs8pyel.js +0 -67
- package/packages/extensions/notes/dist/ui/assets/index-D3cdui42.css +0 -1
- package/packages/extensions/notes/skills/notes/SKILL.md +0 -90
- package/packages/extensions/pages/dist/ui/assets/index-B589e8Xe.js +0 -2
- package/packages/extensions/pages/dist/ui/assets/index-BuXnE-rb.css +0 -1
- package/packages/extensions/plan/dist/ui/assets/index-B8s8wxyt.js +0 -67
- package/packages/extensions/plan/dist/ui/assets/index-jIkrt-vI.css +0 -1
- package/packages/extensions/plan/dist/ui/index.html +0 -14
- package/packages/extensions/plan/skills/plan/SKILL.md +0 -43
- package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +0 -37
- package/templates/claude/.init/.config/routes.json +0 -11
- package/templates/codex/.init/.config/routes.json +0 -11
- package/dist/{accept-I4GVGWA3.js → accept-RSDIVJL6.js} +3 -3
- package/dist/{bridge-KU2IKSH3.js → bridge-YK7NTRU5.js} +3 -3
- package/dist/{create-C3XZACTV.js → create-M727VUDF.js} +3 -3
- package/dist/{env-BJGM6FBA.js → env-7AZFBPWX.js} +7 -7
- package/dist/{extension-B2W52WZY.js → extension-MRYJWSMV.js} +3 -3
- package/dist/{list-R2GDWOEE.js → list-UQGIW7OF.js} +3 -3
- package/dist/{login-EZ4RRDQX.js → login-4NUS72Z5.js} +3 -3
- package/dist/{login-JDOAK465.js → login-57MMYILL.js} +4 -4
- package/dist/{logout-MWSIUOQU.js → logout-BYV433X6.js} +3 -3
- package/dist/{logout-K6ZGAJY5.js → logout-YFZAJRPY.js} +3 -3
- package/dist/{mind-history-RVF6KJ7K.js → mind-history-RZMMCHMX.js} +9 -9
- package/dist/{mind-wake-DCDFFQKX.js → mind-wake-LDGPRA42.js} +3 -3
- package/dist/{read-J5RM674N.js → read-RJ5NAW5J.js} +3 -3
- package/dist/{register-53LBGSDC.js → register-WNCSOTAU.js} +3 -3
- package/dist/{reject-K2A4UK2Y.js → reject-4NFLXKRN.js} +3 -3
- package/dist/{restart-R2WFNF5K.js → restart-B4GNMVF2.js} +7 -7
- package/dist/{skill-DXLLSUHB.js → skill-QYTBUDNQ.js} +7 -7
- package/dist/{start-XDOUAWN3.js → start-BDHJVOVX.js} +6 -6
- package/dist/{stop-O62RTEMD.js → stop-45QYSGYS.js} +7 -7
package/dist/daemon.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
readBackupState,
|
|
7
7
|
resticVersion,
|
|
8
8
|
runBackup
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IR2FW4W7.js";
|
|
10
10
|
import {
|
|
11
11
|
acceptPending,
|
|
12
12
|
formatFileSize,
|
|
@@ -14,47 +14,60 @@ import {
|
|
|
14
14
|
rejectPending,
|
|
15
15
|
stageFile,
|
|
16
16
|
validateFilePath
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-KS62IHE2.js";
|
|
18
|
+
import {
|
|
19
|
+
getMemoryStatus
|
|
20
|
+
} from "./chunk-5RBEEAKW.js";
|
|
18
21
|
import {
|
|
19
22
|
findOpenClawSession,
|
|
20
23
|
importOpenClawConnectors,
|
|
21
24
|
importPiSession,
|
|
22
25
|
parseNameFromIdentity
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import {
|
|
25
|
-
getMemoryStatus
|
|
26
|
-
} from "./chunk-5RBEEAKW.js";
|
|
27
|
-
import {
|
|
28
|
-
checkForUpdate,
|
|
29
|
-
checkForUpdateCached,
|
|
30
|
-
getCurrentVersion
|
|
31
|
-
} from "./chunk-LAUCO2HC.js";
|
|
26
|
+
} from "./chunk-NM5FDH4T.js";
|
|
32
27
|
import {
|
|
33
28
|
SPIRIT_NOTICE_PREFIX,
|
|
34
29
|
ensureSpiritAvailable
|
|
35
|
-
} from "./chunk-
|
|
36
|
-
import {
|
|
37
|
-
isHomeOnlyArchive
|
|
38
|
-
} from "./chunk-FLIEXG2T.js";
|
|
30
|
+
} from "./chunk-3SFKY4GI.js";
|
|
39
31
|
import {
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
TEMPLATE_BRANCH,
|
|
33
|
+
UpgradeInProgressError,
|
|
34
|
+
VariantMergeError,
|
|
35
|
+
abortUpgrade,
|
|
36
|
+
configureGitIdentity,
|
|
37
|
+
continueUpgrade,
|
|
38
|
+
findUnresolvedHomeFiles,
|
|
39
|
+
formatUnresolvedHomeFilesMessage,
|
|
40
|
+
getUpgradeBlocked,
|
|
41
|
+
mergeVariantExcludingMemory,
|
|
42
|
+
npmInstallAsMind,
|
|
43
|
+
npmInstallNeeded,
|
|
44
|
+
runUpgrade,
|
|
45
|
+
upgradeDiff,
|
|
46
|
+
upgradeInProgress,
|
|
47
|
+
validateBranchName
|
|
48
|
+
} from "./chunk-OUGD5L5U.js";
|
|
42
49
|
import {
|
|
43
50
|
isTemplateStale
|
|
44
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-FSXPPOPM.js";
|
|
45
52
|
import {
|
|
46
53
|
computeTemplateHash
|
|
47
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-YU5EYQAE.js";
|
|
48
55
|
import {
|
|
49
56
|
cleanupVariant
|
|
50
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-QVS3C4DK.js";
|
|
58
|
+
import {
|
|
59
|
+
isHomeOnlyArchive
|
|
60
|
+
} from "./chunk-FLIEXG2T.js";
|
|
61
|
+
import {
|
|
62
|
+
evaluateSeedChecklist
|
|
63
|
+
} from "./chunk-45QTYKQQ.js";
|
|
51
64
|
import {
|
|
52
65
|
PLATFORMS,
|
|
53
66
|
echoTextToChannel,
|
|
54
67
|
fixModelEscapes,
|
|
55
68
|
getPlatformDriver,
|
|
56
69
|
routeOutboundBridge
|
|
57
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-VTFXZPC3.js";
|
|
58
71
|
import {
|
|
59
72
|
getBridgeConfig,
|
|
60
73
|
readBridgesConfig,
|
|
@@ -63,7 +76,12 @@ import {
|
|
|
63
76
|
resolveChannelMapping,
|
|
64
77
|
setBridgeConfig,
|
|
65
78
|
setChannelMapping
|
|
66
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-G3XAB4DK.js";
|
|
80
|
+
import {
|
|
81
|
+
checkForUpdate,
|
|
82
|
+
checkForUpdateCached,
|
|
83
|
+
getCurrentVersion
|
|
84
|
+
} from "./chunk-LAUCO2HC.js";
|
|
67
85
|
import {
|
|
68
86
|
SESSION_MAX_AGE,
|
|
69
87
|
announceSprout,
|
|
@@ -71,6 +89,7 @@ import {
|
|
|
71
89
|
authMiddleware,
|
|
72
90
|
backfillSystemChannelMembers,
|
|
73
91
|
cleanExpiredSessions,
|
|
92
|
+
collectTurnContext,
|
|
74
93
|
createSession,
|
|
75
94
|
deleteSession,
|
|
76
95
|
deleteSystemsConfig,
|
|
@@ -95,8 +114,10 @@ import {
|
|
|
95
114
|
linkToolResultToTurn,
|
|
96
115
|
listApiTokens,
|
|
97
116
|
loadAllExtensions,
|
|
117
|
+
normalizeTrailingSlash,
|
|
98
118
|
notifyExtensionsDaemonStart,
|
|
99
119
|
notifyExtensionsDaemonStop,
|
|
120
|
+
notifyExtensionsSpiritReady,
|
|
100
121
|
readSystemsConfig,
|
|
101
122
|
recordOutbound,
|
|
102
123
|
requireAdmin,
|
|
@@ -109,25 +130,25 @@ import {
|
|
|
109
130
|
uninstallNpmExtension,
|
|
110
131
|
willGateMessage,
|
|
111
132
|
writeSystemsConfig
|
|
112
|
-
} from "./chunk-
|
|
113
|
-
import "./chunk-
|
|
133
|
+
} from "./chunk-NCRG4SBR.js";
|
|
134
|
+
import "./chunk-UEZC5MNB.js";
|
|
114
135
|
import {
|
|
115
136
|
applyInitFiles,
|
|
116
|
-
applyTemplateHomeFiles,
|
|
117
137
|
composeTemplate,
|
|
118
138
|
copyTemplateToDir,
|
|
119
139
|
findTemplatesRoot,
|
|
120
140
|
isKnownTemplate,
|
|
121
141
|
listFiles
|
|
122
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-P3GXOT2X.js";
|
|
123
143
|
import {
|
|
124
144
|
getScheduler,
|
|
125
145
|
initScheduler
|
|
126
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-CKOA4LWV.js";
|
|
127
147
|
import {
|
|
128
148
|
recordDeliveryFailure
|
|
129
|
-
} from "./chunk-
|
|
149
|
+
} from "./chunk-FZUPIS3T.js";
|
|
130
150
|
import {
|
|
151
|
+
UnknownChannelError,
|
|
131
152
|
checkStaleSend,
|
|
132
153
|
formatHoldNotice,
|
|
133
154
|
getDeliveryManager,
|
|
@@ -135,7 +156,7 @@ import {
|
|
|
135
156
|
initDeliveryManager,
|
|
136
157
|
isConversationId,
|
|
137
158
|
publishTypingForChannels
|
|
138
|
-
} from "./chunk-
|
|
159
|
+
} from "./chunk-TMTAHKYP.js";
|
|
139
160
|
import {
|
|
140
161
|
MindStartupError,
|
|
141
162
|
RestartTracker,
|
|
@@ -145,10 +166,7 @@ import {
|
|
|
145
166
|
initMindManager,
|
|
146
167
|
syncProviderToMinds,
|
|
147
168
|
tryGetMindManager
|
|
148
|
-
} from "./chunk-
|
|
149
|
-
import {
|
|
150
|
-
extractTextContent
|
|
151
|
-
} from "./chunk-UDZLPR34.js";
|
|
169
|
+
} from "./chunk-HLWQ3P3R.js";
|
|
152
170
|
import {
|
|
153
171
|
SYSTEM_MIND,
|
|
154
172
|
assignSession,
|
|
@@ -162,7 +180,6 @@ import {
|
|
|
162
180
|
initSummarizer,
|
|
163
181
|
isoWeekKeyForDateStr,
|
|
164
182
|
markErrored,
|
|
165
|
-
parseDbTimestamp,
|
|
166
183
|
parseUtcDateTime,
|
|
167
184
|
summarizeOrphanedTurns,
|
|
168
185
|
summarizeTurn,
|
|
@@ -170,83 +187,11 @@ import {
|
|
|
170
187
|
takeErrored,
|
|
171
188
|
trackToolUse,
|
|
172
189
|
utcDateTimeStr
|
|
173
|
-
} from "./chunk-
|
|
174
|
-
import {
|
|
175
|
-
SEED_SKILLS,
|
|
176
|
-
STANDARD_SKILLS,
|
|
177
|
-
autoUpdateMindSkills,
|
|
178
|
-
getSharedSkill,
|
|
179
|
-
getStandardSkillsWithExtensions,
|
|
180
|
-
importSkillFromDir,
|
|
181
|
-
initDefaultSkills,
|
|
182
|
-
installSkill,
|
|
183
|
-
isAutoUpdateSkillsEnabled,
|
|
184
|
-
listFilesRecursive,
|
|
185
|
-
listMindSkills,
|
|
186
|
-
listSharedSkills,
|
|
187
|
-
migrateSkillsToTemplate,
|
|
188
|
-
mindSkillsDir,
|
|
189
|
-
publishSkill,
|
|
190
|
-
removeSharedSkill,
|
|
191
|
-
sharedSkillsDir,
|
|
192
|
-
syncBuiltinSkills,
|
|
193
|
-
uninstallSkill,
|
|
194
|
-
updateSkill
|
|
195
|
-
} from "./chunk-TAWRJ24T.js";
|
|
196
|
-
import {
|
|
197
|
-
approveUser,
|
|
198
|
-
changePassword,
|
|
199
|
-
countAdmins,
|
|
200
|
-
createUser,
|
|
201
|
-
deleteExternalMindUser,
|
|
202
|
-
deleteMindUser as deleteMindUser2,
|
|
203
|
-
deleteUser,
|
|
204
|
-
getDisplayNames,
|
|
205
|
-
getOrCreateMindUser,
|
|
206
|
-
getOrCreateSystemUser,
|
|
207
|
-
getUser,
|
|
208
|
-
getUserByUsername,
|
|
209
|
-
listPendingUsers,
|
|
210
|
-
listUsers,
|
|
211
|
-
listUsersByType,
|
|
212
|
-
setUserRole,
|
|
213
|
-
syncMindProfile,
|
|
214
|
-
updateUserProfile,
|
|
215
|
-
verifyUser,
|
|
216
|
-
withSenderDisplayNames
|
|
217
|
-
} from "./chunk-7LT3YZUR.js";
|
|
218
|
-
import {
|
|
219
|
-
MIND_LEVEL_THREAD,
|
|
220
|
-
captureReflection,
|
|
221
|
-
cleanExpiredEvents,
|
|
222
|
-
clearDeliveredEvents,
|
|
223
|
-
deliverEvent,
|
|
224
|
-
drainEvents,
|
|
225
|
-
eventLabel,
|
|
226
|
-
formatEvents,
|
|
227
|
-
latestEvent,
|
|
228
|
-
latestFailureEvent,
|
|
229
|
-
listEvents,
|
|
230
|
-
parseMeta,
|
|
231
|
-
recordNotice
|
|
232
|
-
} from "./chunk-IQ7VNWH6.js";
|
|
233
|
-
import {
|
|
234
|
-
publish as publish2,
|
|
235
|
-
subscribe as subscribe2,
|
|
236
|
-
subscribeAll
|
|
237
|
-
} from "./chunk-LNNI3MS4.js";
|
|
238
|
-
import {
|
|
239
|
-
PROMPT_DEFAULTS,
|
|
240
|
-
PROMPT_KEYS,
|
|
241
|
-
getMindPromptDefaults,
|
|
242
|
-
getPrompt,
|
|
243
|
-
getPromptIfCustom,
|
|
244
|
-
substitute
|
|
245
|
-
} from "./chunk-AP2KQMMW.js";
|
|
190
|
+
} from "./chunk-BP2X5AIK.js";
|
|
246
191
|
import {
|
|
247
192
|
isSandboxEnabled,
|
|
248
193
|
wrapForSandbox
|
|
249
|
-
} from "./chunk-
|
|
194
|
+
} from "./chunk-XAG53RWY.js";
|
|
250
195
|
import {
|
|
251
196
|
addMessage,
|
|
252
197
|
createChannel,
|
|
@@ -282,22 +227,15 @@ import {
|
|
|
282
227
|
subscribe as subscribe3,
|
|
283
228
|
subscribeParticipantAdded,
|
|
284
229
|
updateChannelSettings
|
|
285
|
-
} from "./chunk-
|
|
230
|
+
} from "./chunk-6HBGUPBA.js";
|
|
286
231
|
import {
|
|
287
232
|
getActiveMinds,
|
|
288
233
|
onMindEvent,
|
|
289
234
|
stopAll
|
|
290
|
-
} from "./chunk-
|
|
291
|
-
import {
|
|
292
|
-
broadcast,
|
|
293
|
-
getEventsSince,
|
|
294
|
-
nextEventId,
|
|
295
|
-
publish,
|
|
296
|
-
subscribe
|
|
297
|
-
} from "./chunk-U54PJPTB.js";
|
|
235
|
+
} from "./chunk-7AA4T2RT.js";
|
|
298
236
|
import {
|
|
299
237
|
normalizeAvatar
|
|
300
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-IT4GEFDH.js";
|
|
301
239
|
import {
|
|
302
240
|
safeResolveWithinBase
|
|
303
241
|
} from "./chunk-DW4TRDOZ.js";
|
|
@@ -305,7 +243,90 @@ import {
|
|
|
305
243
|
readVoluteConfig,
|
|
306
244
|
writeVoluteConfig
|
|
307
245
|
} from "./chunk-WCFSBH33.js";
|
|
308
|
-
import
|
|
246
|
+
import {
|
|
247
|
+
extractTextContent
|
|
248
|
+
} from "./chunk-W3OIPJPB.js";
|
|
249
|
+
import {
|
|
250
|
+
approveUser,
|
|
251
|
+
changePassword,
|
|
252
|
+
countAdmins,
|
|
253
|
+
createUser,
|
|
254
|
+
deleteExternalMindUser,
|
|
255
|
+
deleteMindUser as deleteMindUser2,
|
|
256
|
+
deleteUser,
|
|
257
|
+
getDisplayNames,
|
|
258
|
+
getOrCreateMindUser,
|
|
259
|
+
getOrCreateSystemUser,
|
|
260
|
+
getUser,
|
|
261
|
+
getUserByUsername,
|
|
262
|
+
listPendingUsers,
|
|
263
|
+
listUsers,
|
|
264
|
+
listUsersByType,
|
|
265
|
+
setUserRole,
|
|
266
|
+
syncMindProfile,
|
|
267
|
+
updateUserProfile,
|
|
268
|
+
verifyUser,
|
|
269
|
+
withSenderDisplayNames
|
|
270
|
+
} from "./chunk-OFU6WJJZ.js";
|
|
271
|
+
import {
|
|
272
|
+
broadcast,
|
|
273
|
+
getEventsSince,
|
|
274
|
+
nextEventId,
|
|
275
|
+
publish,
|
|
276
|
+
subscribe
|
|
277
|
+
} from "./chunk-PRZUBJ4K.js";
|
|
278
|
+
import {
|
|
279
|
+
MIND_LEVEL_THREAD,
|
|
280
|
+
captureReflection,
|
|
281
|
+
cleanExpiredEvents,
|
|
282
|
+
clearDeliveredEvents,
|
|
283
|
+
deliverEvent,
|
|
284
|
+
drainEvents,
|
|
285
|
+
eventLabel,
|
|
286
|
+
findStrandedEventMinds,
|
|
287
|
+
formatEvents,
|
|
288
|
+
latestEvent,
|
|
289
|
+
latestFailureEvent,
|
|
290
|
+
listEvents,
|
|
291
|
+
parseMeta,
|
|
292
|
+
recordNotice
|
|
293
|
+
} from "./chunk-DUV4EMNW.js";
|
|
294
|
+
import {
|
|
295
|
+
parseDbTimestamp,
|
|
296
|
+
publish as publish2,
|
|
297
|
+
subscribe as subscribe2,
|
|
298
|
+
subscribeAll
|
|
299
|
+
} from "./chunk-MNKPAAQF.js";
|
|
300
|
+
import {
|
|
301
|
+
PROMPT_DEFAULTS,
|
|
302
|
+
PROMPT_KEYS,
|
|
303
|
+
getMindPromptDefaults,
|
|
304
|
+
getPrompt,
|
|
305
|
+
getPromptIfCustom,
|
|
306
|
+
substitute
|
|
307
|
+
} from "./chunk-HTSWDOJE.js";
|
|
308
|
+
import {
|
|
309
|
+
SEED_SKILLS,
|
|
310
|
+
STANDARD_SKILLS,
|
|
311
|
+
autoUpdateMindSkills,
|
|
312
|
+
getSharedSkill,
|
|
313
|
+
getStandardSkillsWithExtensions,
|
|
314
|
+
importSkillFromDir,
|
|
315
|
+
initDefaultSkills,
|
|
316
|
+
installSkill,
|
|
317
|
+
isAutoUpdateSkillsEnabled,
|
|
318
|
+
listFilesRecursive,
|
|
319
|
+
listMindSkills,
|
|
320
|
+
listSharedSkills,
|
|
321
|
+
mindSkillsDir,
|
|
322
|
+
publishSkill,
|
|
323
|
+
removeSharedSkill,
|
|
324
|
+
sharedSkillsDir,
|
|
325
|
+
syncBuiltinSkills,
|
|
326
|
+
uninstallSkill,
|
|
327
|
+
updateSkill
|
|
328
|
+
} from "./chunk-4VAQKLMU.js";
|
|
329
|
+
import "./chunk-CKPAVQNK.js";
|
|
309
330
|
import {
|
|
310
331
|
chownMindDir,
|
|
311
332
|
chownMindFile,
|
|
@@ -317,7 +338,7 @@ import {
|
|
|
317
338
|
isIsolationEnabled,
|
|
318
339
|
resolveVoluteBin,
|
|
319
340
|
wrapForIsolation
|
|
320
|
-
} from "./chunk-
|
|
341
|
+
} from "./chunk-OIOW3FPT.js";
|
|
321
342
|
import {
|
|
322
343
|
loadMergedEnv,
|
|
323
344
|
mindEnvPath,
|
|
@@ -350,11 +371,11 @@ import {
|
|
|
350
371
|
setProviderRefreshHook,
|
|
351
372
|
setUtilityModel,
|
|
352
373
|
unqualifyModelId
|
|
353
|
-
} from "./chunk-
|
|
374
|
+
} from "./chunk-Z7TNIIHW.js";
|
|
354
375
|
import {
|
|
355
376
|
logBuffer,
|
|
356
377
|
logger_default
|
|
357
|
-
} from "./chunk-
|
|
378
|
+
} from "./chunk-2674KIGI.js";
|
|
358
379
|
import {
|
|
359
380
|
buildVoluteSlug
|
|
360
381
|
} from "./chunk-LGNUFVMR.js";
|
|
@@ -382,7 +403,6 @@ import {
|
|
|
382
403
|
resolveMindDir,
|
|
383
404
|
setMindRunning,
|
|
384
405
|
setMindStage,
|
|
385
|
-
setMindTemplate,
|
|
386
406
|
setMindTemplateHash,
|
|
387
407
|
stateDir,
|
|
388
408
|
validateMindName,
|
|
@@ -409,7 +429,7 @@ import "./chunk-K3NQKI34.js";
|
|
|
409
429
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
410
430
|
import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync12, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "fs";
|
|
411
431
|
import { homedir as homedir3 } from "os";
|
|
412
|
-
import { resolve as
|
|
432
|
+
import { resolve as resolve18 } from "path";
|
|
413
433
|
import { format } from "util";
|
|
414
434
|
|
|
415
435
|
// packages/daemon/src/lib/daemon/backup-manager.ts
|
|
@@ -520,7 +540,7 @@ var BackupManager = class {
|
|
|
520
540
|
} catch (pubErr) {
|
|
521
541
|
blog.error("failed to publish backup-failure activity", logger_default.errorData(pubErr));
|
|
522
542
|
}
|
|
523
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
543
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-ZYOCYAO2.js");
|
|
524
544
|
await deliverEvent2(getSpiritName(), {
|
|
525
545
|
type: "notice",
|
|
526
546
|
meta: { subtype: "backup" },
|
|
@@ -744,8 +764,8 @@ var BridgeManager = class {
|
|
|
744
764
|
if (!tracked) return;
|
|
745
765
|
this.stopping.add(platform);
|
|
746
766
|
this.bridges.delete(platform);
|
|
747
|
-
await new Promise((
|
|
748
|
-
tracked.child.on("exit", () =>
|
|
767
|
+
await new Promise((resolve19) => {
|
|
768
|
+
tracked.child.on("exit", () => resolve19());
|
|
749
769
|
try {
|
|
750
770
|
if (tracked.child.pid) {
|
|
751
771
|
process.kill(-tracked.child.pid, "SIGTERM");
|
|
@@ -756,7 +776,7 @@ var BridgeManager = class {
|
|
|
756
776
|
if (err instanceof Error && err.code !== "ESRCH") {
|
|
757
777
|
blog2.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
|
|
758
778
|
}
|
|
759
|
-
|
|
779
|
+
resolve19();
|
|
760
780
|
}
|
|
761
781
|
setTimeout(() => {
|
|
762
782
|
try {
|
|
@@ -767,7 +787,7 @@ var BridgeManager = class {
|
|
|
767
787
|
}
|
|
768
788
|
} catch {
|
|
769
789
|
}
|
|
770
|
-
|
|
790
|
+
resolve19();
|
|
771
791
|
}, 5e3);
|
|
772
792
|
});
|
|
773
793
|
this.stopping.delete(platform);
|
|
@@ -882,6 +902,19 @@ async function runMaintenance() {
|
|
|
882
902
|
} catch (err) {
|
|
883
903
|
logger_default.warn("maintenance: failed to clean expired events", logger_default.errorData(err));
|
|
884
904
|
}
|
|
905
|
+
try {
|
|
906
|
+
await warnStrandedEvents();
|
|
907
|
+
} catch (err) {
|
|
908
|
+
logger_default.warn("maintenance: failed to check for stranded events", logger_default.errorData(err));
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
async function warnStrandedEvents() {
|
|
912
|
+
for (const s of await findStrandedEventMinds()) {
|
|
913
|
+
logger_default.warn(
|
|
914
|
+
`${s.mind} has ${s.pending} undelivered next-turn system event${s.pending === 1 ? "" : "s"} and has completed ${s.turnsSince} turns without draining them (oldest is ${s.ageHours}h old). Its pre-prompt drain hook is missing or failing \u2014 check home/.local/hooks/pre-prompt/notices.ts and run \`volute mind upgrade ${s.mind}\`.`,
|
|
915
|
+
{ mind: s.mind, pending: s.pending, turnsSince: s.turnsSince, ageHours: s.ageHours }
|
|
916
|
+
);
|
|
917
|
+
}
|
|
885
918
|
}
|
|
886
919
|
function startMaintenanceInterval(intervalMs = MAINTENANCE_INTERVAL_MS, task = runMaintenance) {
|
|
887
920
|
const handle = setInterval(() => void task(), intervalMs);
|
|
@@ -1444,10 +1477,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1444
1477
|
stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
|
|
1445
1478
|
});
|
|
1446
1479
|
});
|
|
1447
|
-
await new Promise((
|
|
1480
|
+
await new Promise((resolve19) => {
|
|
1448
1481
|
stream.onAbort(() => {
|
|
1449
1482
|
unsubscribe();
|
|
1450
|
-
|
|
1483
|
+
resolve19();
|
|
1451
1484
|
});
|
|
1452
1485
|
});
|
|
1453
1486
|
});
|
|
@@ -1472,7 +1505,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1472
1505
|
config2.name = name.trim() || void 0;
|
|
1473
1506
|
writeGlobalConfig(config2);
|
|
1474
1507
|
if (config2.name !== previousName) {
|
|
1475
|
-
const { notifySpiritSystemChange } = await import("./spirit-
|
|
1508
|
+
const { notifySpiritSystemChange } = await import("./spirit-FKXMGO3N.js");
|
|
1476
1509
|
await notifySpiritSystemChange();
|
|
1477
1510
|
}
|
|
1478
1511
|
return c.json({ name: config2.name ?? null });
|
|
@@ -1831,8 +1864,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1831
1864
|
createdAt: Date.now()
|
|
1832
1865
|
};
|
|
1833
1866
|
oauthFlows.set(flowId, flow);
|
|
1834
|
-
const promptPromise = needsManualCode ? new Promise((
|
|
1835
|
-
flow.resolveCode =
|
|
1867
|
+
const promptPromise = needsManualCode ? new Promise((resolve19) => {
|
|
1868
|
+
flow.resolveCode = resolve19;
|
|
1836
1869
|
}) : void 0;
|
|
1837
1870
|
oauthProvider.login({
|
|
1838
1871
|
onAuth: (info) => {
|
|
@@ -1871,7 +1904,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1871
1904
|
existing.error = err instanceof Error ? err.message : String(err);
|
|
1872
1905
|
}
|
|
1873
1906
|
});
|
|
1874
|
-
await new Promise((
|
|
1907
|
+
await new Promise((resolve19) => setTimeout(resolve19, 2e3));
|
|
1875
1908
|
const state = oauthFlows.get(flowId);
|
|
1876
1909
|
return c.json({
|
|
1877
1910
|
flowId,
|
|
@@ -2132,8 +2165,8 @@ var app2 = new Hono2().get("/events", async (c) => {
|
|
|
2132
2165
|
});
|
|
2133
2166
|
}, 15e3);
|
|
2134
2167
|
cleanups.push(() => clearInterval(keepAlive));
|
|
2135
|
-
await new Promise((
|
|
2136
|
-
stream.onAbort(() =>
|
|
2168
|
+
await new Promise((resolve19) => {
|
|
2169
|
+
stream.onAbort(() => resolve19());
|
|
2137
2170
|
});
|
|
2138
2171
|
} finally {
|
|
2139
2172
|
for (const cleanup of cleanups) {
|
|
@@ -2714,7 +2747,7 @@ async function fanOutToMinds(opts) {
|
|
|
2714
2747
|
);
|
|
2715
2748
|
}
|
|
2716
2749
|
if (ap.userType === "system") {
|
|
2717
|
-
import("./spirit-availability-
|
|
2750
|
+
import("./spirit-availability-5R2WYSWF.js").then(({ ensureSpiritAvailable: ensureSpiritAvailable2 }) => ensureSpiritAvailable2()).catch((err) => logger_default.warn("fan-out: on-demand spirit start failed", logger_default.errorData(err)));
|
|
2718
2751
|
}
|
|
2719
2752
|
}
|
|
2720
2753
|
return null;
|
|
@@ -2847,7 +2880,7 @@ var app4 = new Hono5().post("/:platform/inbound", zValidator4("json", inboundSch
|
|
|
2847
2880
|
}
|
|
2848
2881
|
const participants = await getParticipants(channel.id);
|
|
2849
2882
|
if (!participants.some((p) => p.userId === puppet.id)) {
|
|
2850
|
-
const { addParticipant } = await import("./conversations-
|
|
2883
|
+
const { addParticipant } = await import("./conversations-FH3ODBL7.js");
|
|
2851
2884
|
await addParticipant(channel.id, puppet.id);
|
|
2852
2885
|
}
|
|
2853
2886
|
const contentBlocks = body.content;
|
|
@@ -3131,11 +3164,11 @@ async function notifyMind(mindName, message) {
|
|
|
3131
3164
|
const entry = await findMind(mindName);
|
|
3132
3165
|
if (!entry) return false;
|
|
3133
3166
|
try {
|
|
3134
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
3167
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-ZYOCYAO2.js");
|
|
3135
3168
|
const result = await deliverEvent2(mindName, { type: "file-share", body: message });
|
|
3136
3169
|
if (result.delivered) return true;
|
|
3137
3170
|
if (result.id == null) return false;
|
|
3138
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
3171
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Q3ITFNOJ.js");
|
|
3139
3172
|
const { getBaseName: getBaseName2 } = await import("./registry-TRC2HJXR.js");
|
|
3140
3173
|
return getSleepManagerIfReady2()?.isSleeping(await getBaseName2(mindName)) ?? false;
|
|
3141
3174
|
} catch (err) {
|
|
@@ -4108,9 +4141,9 @@ var app11 = new Hono14().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
4108
4141
|
stream.onAbort(() => {
|
|
4109
4142
|
tail.kill();
|
|
4110
4143
|
});
|
|
4111
|
-
await new Promise((
|
|
4112
|
-
tail.on("exit",
|
|
4113
|
-
stream.onAbort(
|
|
4144
|
+
await new Promise((resolve19) => {
|
|
4145
|
+
tail.on("exit", resolve19);
|
|
4146
|
+
stream.onAbort(resolve19);
|
|
4114
4147
|
});
|
|
4115
4148
|
});
|
|
4116
4149
|
}).get("/:name/logs/tail", requireSelf(), async (c) => {
|
|
@@ -4128,8 +4161,8 @@ var app11 = new Hono14().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
4128
4161
|
tail.stdout.on("data", (data) => {
|
|
4129
4162
|
output += data.toString();
|
|
4130
4163
|
});
|
|
4131
|
-
await new Promise((
|
|
4132
|
-
tail.on("exit",
|
|
4164
|
+
await new Promise((resolve19) => {
|
|
4165
|
+
tail.on("exit", resolve19);
|
|
4133
4166
|
});
|
|
4134
4167
|
return c.text(output);
|
|
4135
4168
|
});
|
|
@@ -4222,14 +4255,14 @@ var mind_skills_default = app12;
|
|
|
4222
4255
|
// packages/daemon/src/web/api/minds.ts
|
|
4223
4256
|
import {
|
|
4224
4257
|
cpSync,
|
|
4225
|
-
existsSync as
|
|
4258
|
+
existsSync as existsSync7,
|
|
4226
4259
|
mkdirSync as mkdirSync6,
|
|
4227
4260
|
readdirSync as readdirSync2,
|
|
4228
4261
|
readFileSync as readFileSync9,
|
|
4229
4262
|
rmSync as rmSync3,
|
|
4230
4263
|
writeFileSync as writeFileSync8
|
|
4231
4264
|
} from "fs";
|
|
4232
|
-
import { relative, resolve as
|
|
4265
|
+
import { relative, resolve as resolve11 } from "path";
|
|
4233
4266
|
import { zValidator as zValidator6 } from "@hono/zod-validator";
|
|
4234
4267
|
import { and as and5, desc as desc3, eq as eq5, sql as sql3 } from "drizzle-orm";
|
|
4235
4268
|
import { Hono as Hono16 } from "hono";
|
|
@@ -4672,49 +4705,6 @@ async function commitSrcChanges(dir, mindName) {
|
|
|
4672
4705
|
glog.info(`committed known-good src changes (${dir})`);
|
|
4673
4706
|
}
|
|
4674
4707
|
|
|
4675
|
-
// packages/daemon/src/lib/mind/npm-install.ts
|
|
4676
|
-
import { existsSync as existsSync7 } from "fs";
|
|
4677
|
-
import { resolve as resolve10 } from "path";
|
|
4678
|
-
var NPM_INSTALL_ARGS = [
|
|
4679
|
-
"install",
|
|
4680
|
-
"--no-audit",
|
|
4681
|
-
"--no-fund",
|
|
4682
|
-
"--prefer-offline",
|
|
4683
|
-
"--loglevel=error"
|
|
4684
|
-
];
|
|
4685
|
-
function lowPriorityArgv(cmd, args, ionice) {
|
|
4686
|
-
return ionice ? ["ionice", ["-c2", "-n7", "nice", "-n19", cmd, ...args]] : ["nice", ["-n19", cmd, ...args]];
|
|
4687
|
-
}
|
|
4688
|
-
function hasIonice() {
|
|
4689
|
-
return process.platform === "linux" && (existsSync7("/usr/bin/ionice") || existsSync7("/bin/ionice"));
|
|
4690
|
-
}
|
|
4691
|
-
async function npmInstallAsMind(cwd, mindName) {
|
|
4692
|
-
const [cmd, args] = lowPriorityArgv("npm", NPM_INSTALL_ARGS, hasIonice());
|
|
4693
|
-
if (isIsolationEnabled()) {
|
|
4694
|
-
const [wrappedCmd, wrappedArgs] = await wrapForIsolation(cmd, args, mindName);
|
|
4695
|
-
await exec(wrappedCmd, wrappedArgs, {
|
|
4696
|
-
cwd,
|
|
4697
|
-
env: { ...process.env, HOME: resolve10(cwd, "home") }
|
|
4698
|
-
});
|
|
4699
|
-
} else {
|
|
4700
|
-
await exec(cmd, args, { cwd });
|
|
4701
|
-
}
|
|
4702
|
-
}
|
|
4703
|
-
async function depsChangedSince(dir, fromRef) {
|
|
4704
|
-
try {
|
|
4705
|
-
await gitExec(["diff", "--quiet", fromRef, "HEAD", "--", "package.json", "package-lock.json"], {
|
|
4706
|
-
cwd: dir
|
|
4707
|
-
});
|
|
4708
|
-
return false;
|
|
4709
|
-
} catch {
|
|
4710
|
-
return true;
|
|
4711
|
-
}
|
|
4712
|
-
}
|
|
4713
|
-
async function npmInstallNeeded(dir, preMergeRef) {
|
|
4714
|
-
if (!existsSync7(resolve10(dir, "node_modules"))) return true;
|
|
4715
|
-
return depsChangedSince(dir, preMergeRef);
|
|
4716
|
-
}
|
|
4717
|
-
|
|
4718
4708
|
// packages/daemon/src/lib/mind/thinking-config.ts
|
|
4719
4709
|
var CLAUDE_EFFORT = {
|
|
4720
4710
|
minimal: "low",
|
|
@@ -4756,150 +4746,6 @@ function deriveThinkingLevel(config2) {
|
|
|
4756
4746
|
return null;
|
|
4757
4747
|
}
|
|
4758
4748
|
|
|
4759
|
-
// packages/daemon/src/lib/mind/variants.ts
|
|
4760
|
-
import { statSync as statSync3 } from "fs";
|
|
4761
|
-
import { resolve as resolve11 } from "path";
|
|
4762
|
-
var SAFE_BRANCH_RE = /^[a-zA-Z0-9._\-/]+$/;
|
|
4763
|
-
function validateBranchName(branch) {
|
|
4764
|
-
if (!SAFE_BRANCH_RE.test(branch)) {
|
|
4765
|
-
return `Invalid branch name: ${branch}. Only alphanumeric, '.', '_', '-', '/' allowed.`;
|
|
4766
|
-
}
|
|
4767
|
-
if (branch.includes("..")) {
|
|
4768
|
-
return `Invalid branch name: ${branch}. '..' not allowed.`;
|
|
4769
|
-
}
|
|
4770
|
-
return null;
|
|
4771
|
-
}
|
|
4772
|
-
var MERGE_EXCLUDED_PATHS = ["home/MEMORY.md", "home/memory/journal/"];
|
|
4773
|
-
var MAX_DELTA_CHARS = 12e3;
|
|
4774
|
-
var NEVER_REPORT_PREFIXES = ["home/.claude/", "home/.pi/", "home/.agents/"];
|
|
4775
|
-
var MAX_LISTED_UNRESOLVED_FILES = 20;
|
|
4776
|
-
async function findUnresolvedHomeFiles(cwd) {
|
|
4777
|
-
const raw = await gitExec(
|
|
4778
|
-
["ls-files", "--others", "--ignored", "--exclude-standard", "-z", "--", "home"],
|
|
4779
|
-
{ cwd }
|
|
4780
|
-
);
|
|
4781
|
-
const allPaths = raw.split("\0").filter((path) => path && !NEVER_REPORT_PREFIXES.some((prefix) => path.startsWith(prefix)));
|
|
4782
|
-
const files = [];
|
|
4783
|
-
let totalBytes = 0;
|
|
4784
|
-
for (const path of allPaths) {
|
|
4785
|
-
let bytes = -1;
|
|
4786
|
-
try {
|
|
4787
|
-
bytes = statSync3(resolve11(cwd, path)).size;
|
|
4788
|
-
} catch {
|
|
4789
|
-
}
|
|
4790
|
-
if (bytes > 0) totalBytes += bytes;
|
|
4791
|
-
if (files.length < MAX_LISTED_UNRESOLVED_FILES) files.push({ path, bytes });
|
|
4792
|
-
}
|
|
4793
|
-
return { files, totalCount: allPaths.length, totalBytes };
|
|
4794
|
-
}
|
|
4795
|
-
function formatBytes(bytes) {
|
|
4796
|
-
if (bytes < 0) return "size unknown";
|
|
4797
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
4798
|
-
const units = ["KB", "MB", "GB", "TB"];
|
|
4799
|
-
let value = bytes / 1024;
|
|
4800
|
-
for (const unit of units) {
|
|
4801
|
-
if (value < 1024) return `${value.toFixed(1)} ${unit}`;
|
|
4802
|
-
value /= 1024;
|
|
4803
|
-
}
|
|
4804
|
-
return `${value.toFixed(1)} PB`;
|
|
4805
|
-
}
|
|
4806
|
-
function formatUnresolvedHomeFilesMessage(variantName, result) {
|
|
4807
|
-
const lines = result.files.map(
|
|
4808
|
-
(f) => ` - ${f.path.replace(/^home\//, "")} (${formatBytes(f.bytes)})`
|
|
4809
|
-
);
|
|
4810
|
-
const remaining = result.totalCount - result.files.length;
|
|
4811
|
-
if (remaining > 0) lines.push(` ...and ${remaining} more`);
|
|
4812
|
-
return `Cannot join variant "${variantName}": it has ${result.totalCount} untracked file${result.totalCount === 1 ? "" : "s"} under home/ that .gitignore is hiding from git \u2014 never committed, and joining would destroy them when the variant is cleaned up (total: ${formatBytes(result.totalBytes)}):
|
|
4813
|
-
|
|
4814
|
-
${lines.join("\n")}
|
|
4815
|
-
|
|
4816
|
-
Before retrying the join, resolve each file in the variant \u2014 one of:
|
|
4817
|
-
1. Track it: git add -f -- <path> (then commit it, or let auto-commit pick it up next turn)
|
|
4818
|
-
2. Copy it out of home/ to somewhere safe, then delete it
|
|
4819
|
-
3. Delete it if it's disposable
|
|
4820
|
-
|
|
4821
|
-
Once resolved, retry the join. To join anyway and discard everything listed above, pass discardUnresolved: true.`;
|
|
4822
|
-
}
|
|
4823
|
-
async function mergeVariantExcludingMemory(projectRoot, variantBranch) {
|
|
4824
|
-
const opts = { cwd: projectRoot };
|
|
4825
|
-
let memoryDelta = "";
|
|
4826
|
-
try {
|
|
4827
|
-
const base = (await gitExec(["merge-base", "HEAD", variantBranch], opts)).trim();
|
|
4828
|
-
memoryDelta = (await gitExec(["diff", `${base}..${variantBranch}`, "--", ...MERGE_EXCLUDED_PATHS], opts)).trim();
|
|
4829
|
-
} catch (err) {
|
|
4830
|
-
logger_default.error(
|
|
4831
|
-
`variant join: failed to compute memory delta for ${variantBranch}`,
|
|
4832
|
-
logger_default.errorData(err)
|
|
4833
|
-
);
|
|
4834
|
-
memoryDelta = `(journal delta unavailable \u2014 ${err instanceof Error ? err.message : String(err)})`;
|
|
4835
|
-
}
|
|
4836
|
-
if (memoryDelta.length > MAX_DELTA_CHARS) {
|
|
4837
|
-
memoryDelta = `${memoryDelta.slice(0, MAX_DELTA_CHARS)}
|
|
4838
|
-
\u2026 (delta truncated)`;
|
|
4839
|
-
}
|
|
4840
|
-
try {
|
|
4841
|
-
await gitExec(["merge", "--no-ff", "--no-commit", variantBranch], opts).catch(() => {
|
|
4842
|
-
});
|
|
4843
|
-
await gitExec(["reset", "-q", "HEAD", "--", ...MERGE_EXCLUDED_PATHS], opts);
|
|
4844
|
-
for (const path of MERGE_EXCLUDED_PATHS) {
|
|
4845
|
-
await gitExec(["checkout", "--", path], opts).catch(() => {
|
|
4846
|
-
});
|
|
4847
|
-
}
|
|
4848
|
-
await gitExec(["clean", "-fdq", "--", ...MERGE_EXCLUDED_PATHS], opts);
|
|
4849
|
-
await assertExcludedPathsRestored(opts);
|
|
4850
|
-
if (await mergeInProgress(opts)) {
|
|
4851
|
-
await gitExec(["commit", "--no-edit"], opts);
|
|
4852
|
-
}
|
|
4853
|
-
} catch (err) {
|
|
4854
|
-
const conflicts = await listConflicts(opts);
|
|
4855
|
-
const abortFailed = await gitExec(["merge", "--abort"], opts).then(
|
|
4856
|
-
() => false,
|
|
4857
|
-
() => true
|
|
4858
|
-
);
|
|
4859
|
-
throw new VariantMergeError(
|
|
4860
|
-
`variant join aborted: ${err instanceof Error ? err.message : String(err)}`,
|
|
4861
|
-
conflicts,
|
|
4862
|
-
abortFailed
|
|
4863
|
-
);
|
|
4864
|
-
}
|
|
4865
|
-
return memoryDelta;
|
|
4866
|
-
}
|
|
4867
|
-
var VariantMergeError = class extends Error {
|
|
4868
|
-
constructor(message, conflicts, abortFailed = false) {
|
|
4869
|
-
super(message);
|
|
4870
|
-
this.conflicts = conflicts;
|
|
4871
|
-
this.abortFailed = abortFailed;
|
|
4872
|
-
this.name = "VariantMergeError";
|
|
4873
|
-
}
|
|
4874
|
-
};
|
|
4875
|
-
async function mergeInProgress(opts) {
|
|
4876
|
-
return gitExec(["rev-parse", "-q", "--verify", "MERGE_HEAD"], opts).then(
|
|
4877
|
-
() => true,
|
|
4878
|
-
() => false
|
|
4879
|
-
);
|
|
4880
|
-
}
|
|
4881
|
-
async function listConflicts(opts) {
|
|
4882
|
-
try {
|
|
4883
|
-
const out = (await gitExec(["diff", "--name-only", "--diff-filter=U"], opts)).trim();
|
|
4884
|
-
return out ? out.split("\n") : [];
|
|
4885
|
-
} catch {
|
|
4886
|
-
return [];
|
|
4887
|
-
}
|
|
4888
|
-
}
|
|
4889
|
-
async function assertExcludedPathsRestored(opts) {
|
|
4890
|
-
await gitExec(["diff", "--cached", "--quiet", "HEAD", "--", ...MERGE_EXCLUDED_PATHS], opts);
|
|
4891
|
-
await gitExec(["diff", "--quiet", "HEAD", "--", ...MERGE_EXCLUDED_PATHS], opts);
|
|
4892
|
-
const untracked = (await gitExec(
|
|
4893
|
-
["ls-files", "--others", "--exclude-standard", "--", ...MERGE_EXCLUDED_PATHS],
|
|
4894
|
-
opts
|
|
4895
|
-
)).trim();
|
|
4896
|
-
if (untracked) {
|
|
4897
|
-
throw new Error(
|
|
4898
|
-
`untracked memory files remain after restore: ${untracked.replace(/\n/g, ", ")}`
|
|
4899
|
-
);
|
|
4900
|
-
}
|
|
4901
|
-
}
|
|
4902
|
-
|
|
4903
4749
|
// packages/daemon/src/lib/services/imagegen-jobs.ts
|
|
4904
4750
|
import { mkdir, writeFile } from "fs/promises";
|
|
4905
4751
|
import { dirname as dirname2 } from "path";
|
|
@@ -5022,7 +4868,7 @@ async function waitForImagegenJob(mind, id, timeoutMs) {
|
|
|
5022
4868
|
import { randomUUID } from "crypto";
|
|
5023
4869
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
5024
4870
|
import { homedir } from "os";
|
|
5025
|
-
import { resolve as
|
|
4871
|
+
import { resolve as resolve10 } from "path";
|
|
5026
4872
|
function convertSession(opts) {
|
|
5027
4873
|
const lines = readFileSync8(opts.sessionPath, "utf-8").trim().split("\n");
|
|
5028
4874
|
const sessionId = randomUUID();
|
|
@@ -5138,9 +4984,9 @@ function convertSession(opts) {
|
|
|
5138
4984
|
}
|
|
5139
4985
|
}
|
|
5140
4986
|
const projectId = opts.projectDir.replace(/\//g, "-");
|
|
5141
|
-
const sdkDir =
|
|
4987
|
+
const sdkDir = resolve10(homedir(), ".claude", "projects", projectId);
|
|
5142
4988
|
mkdirSync5(sdkDir, { recursive: true });
|
|
5143
|
-
const sdkPath =
|
|
4989
|
+
const sdkPath = resolve10(sdkDir, `${sessionId}.jsonl`);
|
|
5144
4990
|
writeFileSync7(sdkPath, `${sdkEvents.join("\n")}
|
|
5145
4991
|
`);
|
|
5146
4992
|
console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
|
|
@@ -5201,7 +5047,7 @@ async function getMindStatus(name, port, registryRunning, seed) {
|
|
|
5201
5047
|
let status = "stopped";
|
|
5202
5048
|
let wakeAt = null;
|
|
5203
5049
|
try {
|
|
5204
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5050
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Q3ITFNOJ.js");
|
|
5205
5051
|
const sleepManager = getSleepManagerIfReady2();
|
|
5206
5052
|
if (sleepManager?.isSleeping(name)) {
|
|
5207
5053
|
status = "sleeping";
|
|
@@ -5265,13 +5111,6 @@ function toPublicMind(entry, status, extras) {
|
|
|
5265
5111
|
lastActiveAt: extras.lastActiveAt ?? null
|
|
5266
5112
|
};
|
|
5267
5113
|
}
|
|
5268
|
-
var TEMPLATE_BRANCH = "volute/template";
|
|
5269
|
-
async function configureGitIdentity(mindName, opts) {
|
|
5270
|
-
const systemsConfig = readSystemsConfig();
|
|
5271
|
-
const system = systemsConfig?.system ?? "local";
|
|
5272
|
-
await gitExec(["config", "user.name", mindName], opts);
|
|
5273
|
-
await gitExec(["config", "user.email", `${mindName}.${system}@volute.systems`], opts);
|
|
5274
|
-
}
|
|
5275
5114
|
async function initTemplateBranch(projectRoot, composedDir, manifest, mindName, env) {
|
|
5276
5115
|
const templateFiles = listFiles(composedDir).filter((f) => !f.startsWith(".init/") && !f.startsWith(".init\\")).filter((f) => !f.startsWith("home/") && !f.startsWith("home\\") || f === "home/VOLUTE.md").map((f) => manifest.rename[f] ?? f);
|
|
5277
5116
|
const opts = { cwd: projectRoot, mindName, env };
|
|
@@ -5282,164 +5121,9 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
|
|
|
5282
5121
|
await gitExec(["add", "-A"], opts);
|
|
5283
5122
|
await gitExec(["commit", "-m", "initial commit"], opts);
|
|
5284
5123
|
}
|
|
5285
|
-
async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
5286
|
-
const tempWorktree = resolve13(projectRoot, ".variants", "_template_update");
|
|
5287
|
-
let branchExists = false;
|
|
5288
|
-
try {
|
|
5289
|
-
await gitExec(["rev-parse", "--verify", TEMPLATE_BRANCH], { cwd: projectRoot });
|
|
5290
|
-
branchExists = true;
|
|
5291
|
-
} catch {
|
|
5292
|
-
}
|
|
5293
|
-
try {
|
|
5294
|
-
await gitExec(["worktree", "remove", "--force", tempWorktree], { cwd: projectRoot });
|
|
5295
|
-
} catch {
|
|
5296
|
-
}
|
|
5297
|
-
if (existsSync8(tempWorktree)) {
|
|
5298
|
-
rmSync3(tempWorktree, { recursive: true, force: true });
|
|
5299
|
-
}
|
|
5300
|
-
const templatesRoot = findTemplatesRoot();
|
|
5301
|
-
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5302
|
-
try {
|
|
5303
|
-
if (branchExists) {
|
|
5304
|
-
await gitExec(["worktree", "add", tempWorktree, TEMPLATE_BRANCH], {
|
|
5305
|
-
cwd: projectRoot
|
|
5306
|
-
});
|
|
5307
|
-
} else {
|
|
5308
|
-
await gitExec(["worktree", "add", "--detach", tempWorktree], { cwd: projectRoot });
|
|
5309
|
-
await gitExec(["checkout", "--orphan", TEMPLATE_BRANCH], { cwd: tempWorktree });
|
|
5310
|
-
await gitExec(["rm", "-rf", "--cached", "."], { cwd: tempWorktree });
|
|
5311
|
-
await gitExec(["clean", "-fd"], { cwd: tempWorktree });
|
|
5312
|
-
}
|
|
5313
|
-
if (branchExists) {
|
|
5314
|
-
await gitExec(["rm", "-rf", "."], { cwd: tempWorktree }).catch(() => {
|
|
5315
|
-
});
|
|
5316
|
-
}
|
|
5317
|
-
copyTemplateToDir(composedDir, tempWorktree, mindName, manifest);
|
|
5318
|
-
const initDir = resolve13(tempWorktree, ".init");
|
|
5319
|
-
if (existsSync8(initDir)) {
|
|
5320
|
-
rmSync3(initDir, { recursive: true, force: true });
|
|
5321
|
-
}
|
|
5322
|
-
const homeDir = resolve13(tempWorktree, "home");
|
|
5323
|
-
if (existsSync8(homeDir)) {
|
|
5324
|
-
for (const entry of readdirSync2(homeDir)) {
|
|
5325
|
-
if (entry !== "VOLUTE.md") {
|
|
5326
|
-
rmSync3(resolve13(homeDir, entry), { recursive: true, force: true });
|
|
5327
|
-
}
|
|
5328
|
-
}
|
|
5329
|
-
}
|
|
5330
|
-
await gitExec(["add", "-A"], { cwd: tempWorktree });
|
|
5331
|
-
try {
|
|
5332
|
-
await gitExec(["diff", "--cached", "--quiet"], { cwd: tempWorktree });
|
|
5333
|
-
} catch {
|
|
5334
|
-
await gitExec(["commit", "-m", "template update"], { cwd: tempWorktree });
|
|
5335
|
-
}
|
|
5336
|
-
} finally {
|
|
5337
|
-
try {
|
|
5338
|
-
await gitExec(["worktree", "remove", "--force", tempWorktree], { cwd: projectRoot });
|
|
5339
|
-
} catch {
|
|
5340
|
-
}
|
|
5341
|
-
if (existsSync8(tempWorktree)) {
|
|
5342
|
-
rmSync3(tempWorktree, { recursive: true, force: true });
|
|
5343
|
-
}
|
|
5344
|
-
rmSync3(composedDir, { recursive: true, force: true });
|
|
5345
|
-
}
|
|
5346
|
-
}
|
|
5347
|
-
async function mergeTemplateBranch(worktreeDir) {
|
|
5348
|
-
try {
|
|
5349
|
-
await gitExec(
|
|
5350
|
-
["merge", TEMPLATE_BRANCH, "--allow-unrelated-histories", "-m", "merge template update"],
|
|
5351
|
-
{ cwd: worktreeDir }
|
|
5352
|
-
);
|
|
5353
|
-
return false;
|
|
5354
|
-
} catch (e) {
|
|
5355
|
-
try {
|
|
5356
|
-
const status = await gitExec(["status", "--porcelain"], { cwd: worktreeDir });
|
|
5357
|
-
const hasConflictMarkers = status.split("\n").some((line) => line.startsWith("UU") || line.startsWith("AA"));
|
|
5358
|
-
if (hasConflictMarkers) return true;
|
|
5359
|
-
} catch {
|
|
5360
|
-
}
|
|
5361
|
-
throw e;
|
|
5362
|
-
}
|
|
5363
|
-
}
|
|
5364
|
-
async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariantName, upgradeBranch, template, oldTemplate) {
|
|
5365
|
-
const templateChanged = template !== oldTemplate;
|
|
5366
|
-
const mainStatus = (await gitExec(["status", "--porcelain"], { cwd: dir })).trim();
|
|
5367
|
-
if (mainStatus) {
|
|
5368
|
-
await gitExec(["add", "-A"], { cwd: dir });
|
|
5369
|
-
await gitExec(["commit", "-m", "Auto-commit before upgrade merge"], { cwd: dir });
|
|
5370
|
-
}
|
|
5371
|
-
const preMergeHead = (await gitExec(["rev-parse", "HEAD"], { cwd: dir })).trim();
|
|
5372
|
-
await gitExec(["merge", upgradeBranch], { cwd: dir });
|
|
5373
|
-
try {
|
|
5374
|
-
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir);
|
|
5375
|
-
} catch (err) {
|
|
5376
|
-
logger_default.warn(`failed to clean up upgrade worktree for ${mindName}`, logger_default.errorData(err));
|
|
5377
|
-
}
|
|
5378
|
-
try {
|
|
5379
|
-
await gitExec(["branch", "-D", upgradeBranch], { cwd: dir });
|
|
5380
|
-
} catch {
|
|
5381
|
-
}
|
|
5382
|
-
let switchWarning;
|
|
5383
|
-
if (templateChanged) {
|
|
5384
|
-
try {
|
|
5385
|
-
applyTemplateHomeFiles(resolve13(dir, "home"), template);
|
|
5386
|
-
const migratedSkills = migrateSkillsToTemplate(dir, oldTemplate, template);
|
|
5387
|
-
await gitExec(["add", "home/"], { cwd: dir });
|
|
5388
|
-
try {
|
|
5389
|
-
await gitExec(["diff", "--cached", "--quiet"], { cwd: dir });
|
|
5390
|
-
} catch {
|
|
5391
|
-
await gitExec(["commit", "-m", `swap template-owned home files for ${template}`], {
|
|
5392
|
-
cwd: dir
|
|
5393
|
-
});
|
|
5394
|
-
}
|
|
5395
|
-
await chownMindDir(dir, mindName);
|
|
5396
|
-
const skillNote = migratedSkills.length > 0 ? ` Migrated skills to the ${template} skills dir: ${migratedSkills.join(", ")}.` : "";
|
|
5397
|
-
switchWarning = `Switched ${oldTemplate}\u2192${template}: config reset to ${template} defaults, mechanics doc replaced, conversation starts fresh (sessions aren't portable across runtimes).${skillNote}`;
|
|
5398
|
-
} catch (err) {
|
|
5399
|
-
logger_default.warn(`failed to swap template home files for ${mindName}`, logger_default.errorData(err));
|
|
5400
|
-
return {
|
|
5401
|
-
ok: true,
|
|
5402
|
-
warning: `Upgrade merged but template switch ${oldTemplate}\u2192${template} failed: ${err instanceof Error ? err.message : String(err)}. The mind is still registered as ${oldTemplate}; re-run the switch or fix home/ manually.`
|
|
5403
|
-
};
|
|
5404
|
-
}
|
|
5405
|
-
}
|
|
5406
|
-
try {
|
|
5407
|
-
await setMindTemplateHash(mindName, computeTemplateHash(template));
|
|
5408
|
-
await setMindTemplate(mindName, template);
|
|
5409
|
-
} catch (err) {
|
|
5410
|
-
logger_default.warn(`failed to update template for ${mindName}`, logger_default.errorData(err));
|
|
5411
|
-
}
|
|
5412
|
-
if (await npmInstallNeeded(dir, preMergeHead)) {
|
|
5413
|
-
try {
|
|
5414
|
-
await npmInstallAsMind(dir, mindName);
|
|
5415
|
-
} catch (err) {
|
|
5416
|
-
logger_default.warn(`npm install failed after upgrade merge for ${mindName}`, logger_default.errorData(err));
|
|
5417
|
-
return {
|
|
5418
|
-
ok: true,
|
|
5419
|
-
warning: `Upgrade merged but npm install failed: ${err instanceof Error ? err.message : String(err)}. You may need to run npm install manually.`
|
|
5420
|
-
};
|
|
5421
|
-
}
|
|
5422
|
-
} else {
|
|
5423
|
-
logger_default.info(`skipping npm install for ${mindName} \u2014 dependencies unchanged by upgrade`);
|
|
5424
|
-
}
|
|
5425
|
-
const manager = getMindManager();
|
|
5426
|
-
try {
|
|
5427
|
-
if (manager.isRunning(mindName)) {
|
|
5428
|
-
await manager.stopMind(mindName);
|
|
5429
|
-
}
|
|
5430
|
-
manager.setPendingContext(mindName, { type: "upgraded" });
|
|
5431
|
-
await manager.startMind(mindName, { healthTimeoutMs: 12e4 });
|
|
5432
|
-
} catch (e) {
|
|
5433
|
-
return {
|
|
5434
|
-
ok: true,
|
|
5435
|
-
warning: `Upgrade merged but mind restart failed: ${e instanceof Error ? e.message : String(e)}`
|
|
5436
|
-
};
|
|
5437
|
-
}
|
|
5438
|
-
return { ok: true, warning: switchWarning };
|
|
5439
|
-
}
|
|
5440
5124
|
async function importFromArchive(c, tempDir, nameOverride, manifest) {
|
|
5441
|
-
const extractedMindDir =
|
|
5442
|
-
if (!
|
|
5125
|
+
const extractedMindDir = resolve11(tempDir, "mind");
|
|
5126
|
+
if (!existsSync7(extractedMindDir)) {
|
|
5443
5127
|
return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
|
|
5444
5128
|
}
|
|
5445
5129
|
if (!manifest?.includes || !manifest.name || !manifest.template) {
|
|
@@ -5457,7 +5141,7 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5457
5141
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
5458
5142
|
ensureVoluteHome();
|
|
5459
5143
|
const dest = mindDir(name);
|
|
5460
|
-
if (
|
|
5144
|
+
if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5461
5145
|
try {
|
|
5462
5146
|
cpSync(extractedMindDir, dest, { recursive: true });
|
|
5463
5147
|
if (!manifest.includes.identity) {
|
|
@@ -5465,9 +5149,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5465
5149
|
}
|
|
5466
5150
|
const state = stateDir(name);
|
|
5467
5151
|
mkdirSync6(state, { recursive: true });
|
|
5468
|
-
const envJson =
|
|
5469
|
-
if (
|
|
5470
|
-
cpSync(envJson,
|
|
5152
|
+
const envJson = resolve11(tempDir, "state/env.json");
|
|
5153
|
+
if (existsSync7(envJson)) {
|
|
5154
|
+
cpSync(envJson, resolve11(state, "env.json"));
|
|
5471
5155
|
}
|
|
5472
5156
|
const port = await nextPort();
|
|
5473
5157
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
@@ -5476,30 +5160,30 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5476
5160
|
} catch (err) {
|
|
5477
5161
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5478
5162
|
}
|
|
5479
|
-
const homeDir =
|
|
5163
|
+
const homeDir = resolve11(dest, "home");
|
|
5480
5164
|
ensureVoluteGroup();
|
|
5481
5165
|
createMindUser(name, homeDir);
|
|
5482
5166
|
await chownMindDir(dest, name);
|
|
5483
5167
|
await npmInstallAsMind(dest, name);
|
|
5484
5168
|
await importHistoryFromArchive(name, tempDir);
|
|
5485
5169
|
importSessionsFromArchive(dest, tempDir);
|
|
5486
|
-
if (!
|
|
5170
|
+
if (!existsSync7(resolve11(dest, ".git"))) {
|
|
5487
5171
|
try {
|
|
5488
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5172
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
|
|
5489
5173
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
5490
5174
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
5491
5175
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
5492
5176
|
await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
|
|
5493
5177
|
} catch (err) {
|
|
5494
5178
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
5495
|
-
rmSync3(
|
|
5179
|
+
rmSync3(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
5496
5180
|
}
|
|
5497
5181
|
}
|
|
5498
5182
|
await chownMindDir(dest, name);
|
|
5499
5183
|
rmSync3(tempDir, { recursive: true, force: true });
|
|
5500
5184
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
5501
5185
|
} catch (err) {
|
|
5502
|
-
if (
|
|
5186
|
+
if (existsSync7(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5503
5187
|
try {
|
|
5504
5188
|
await removeMind(name);
|
|
5505
5189
|
} catch (cleanupErr) {
|
|
@@ -5516,7 +5200,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5516
5200
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
5517
5201
|
ensureVoluteHome();
|
|
5518
5202
|
const dest = mindDir(name);
|
|
5519
|
-
if (
|
|
5203
|
+
if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5520
5204
|
const templatesRoot = findTemplatesRoot();
|
|
5521
5205
|
const { composedDir, manifest: templateManifest } = composeTemplate(
|
|
5522
5206
|
templatesRoot,
|
|
@@ -5525,36 +5209,36 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5525
5209
|
try {
|
|
5526
5210
|
copyTemplateToDir(composedDir, dest, name, templateManifest);
|
|
5527
5211
|
applyInitFiles(dest);
|
|
5528
|
-
const extractedHome =
|
|
5529
|
-
if (
|
|
5530
|
-
cpSync(extractedHome,
|
|
5212
|
+
const extractedHome = resolve11(extractedMindDir, "home");
|
|
5213
|
+
if (existsSync7(extractedHome)) {
|
|
5214
|
+
cpSync(extractedHome, resolve11(dest, "home"), { recursive: true });
|
|
5531
5215
|
}
|
|
5532
|
-
const extractedMindInternal =
|
|
5533
|
-
if (
|
|
5534
|
-
cpSync(extractedMindInternal,
|
|
5216
|
+
const extractedMindInternal = resolve11(extractedMindDir, ".mind");
|
|
5217
|
+
if (existsSync7(extractedMindInternal)) {
|
|
5218
|
+
cpSync(extractedMindInternal, resolve11(dest, ".mind"), { recursive: true });
|
|
5535
5219
|
}
|
|
5536
|
-
const identityDir =
|
|
5220
|
+
const identityDir = resolve11(dest, ".mind/identity");
|
|
5537
5221
|
let publicKeyPem;
|
|
5538
|
-
if (!manifest.includes.identity || !
|
|
5222
|
+
if (!manifest.includes.identity || !existsSync7(resolve11(identityDir, "private.pem"))) {
|
|
5539
5223
|
({ publicKeyPem } = generateIdentity(dest));
|
|
5540
5224
|
} else {
|
|
5541
|
-
publicKeyPem = readFileSync9(
|
|
5225
|
+
publicKeyPem = readFileSync9(resolve11(identityDir, "public.pem"), "utf-8");
|
|
5542
5226
|
}
|
|
5543
|
-
const promptsPath =
|
|
5544
|
-
if (!
|
|
5227
|
+
const promptsPath = resolve11(dest, "home/.config/prompts.json");
|
|
5228
|
+
if (!existsSync7(promptsPath)) {
|
|
5545
5229
|
const mindPrompts = await getMindPromptDefaults();
|
|
5546
5230
|
writeFileSync8(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
|
|
5547
5231
|
`);
|
|
5548
5232
|
}
|
|
5549
5233
|
const state = stateDir(name);
|
|
5550
5234
|
mkdirSync6(state, { recursive: true });
|
|
5551
|
-
const envJson =
|
|
5552
|
-
if (
|
|
5553
|
-
cpSync(envJson,
|
|
5235
|
+
const envJson = resolve11(tempDir, "state/env.json");
|
|
5236
|
+
if (existsSync7(envJson)) {
|
|
5237
|
+
cpSync(envJson, resolve11(state, "env.json"));
|
|
5554
5238
|
}
|
|
5555
5239
|
const port = await nextPort();
|
|
5556
5240
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
5557
|
-
const homeDir =
|
|
5241
|
+
const homeDir = resolve11(dest, "home");
|
|
5558
5242
|
ensureVoluteGroup();
|
|
5559
5243
|
createMindUser(name, homeDir);
|
|
5560
5244
|
await chownMindDir(dest, name);
|
|
@@ -5567,7 +5251,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5567
5251
|
await initTemplateBranch(dest, composedDir, templateManifest, name, env);
|
|
5568
5252
|
} catch (err) {
|
|
5569
5253
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
5570
|
-
rmSync3(
|
|
5254
|
+
rmSync3(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
5571
5255
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
5572
5256
|
}
|
|
5573
5257
|
const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
|
|
@@ -5597,7 +5281,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5597
5281
|
...skillWarnings.length > 0 && { skillWarnings }
|
|
5598
5282
|
});
|
|
5599
5283
|
} catch (err) {
|
|
5600
|
-
if (
|
|
5284
|
+
if (existsSync7(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5601
5285
|
try {
|
|
5602
5286
|
await removeMind(name);
|
|
5603
5287
|
} catch (cleanupErr) {
|
|
@@ -5610,8 +5294,8 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5610
5294
|
}
|
|
5611
5295
|
}
|
|
5612
5296
|
async function importHistoryFromArchive(name, tempDir) {
|
|
5613
|
-
const historyJsonl =
|
|
5614
|
-
if (!
|
|
5297
|
+
const historyJsonl = resolve11(tempDir, "history.jsonl");
|
|
5298
|
+
if (!existsSync7(historyJsonl)) return;
|
|
5615
5299
|
try {
|
|
5616
5300
|
const db = await getDb();
|
|
5617
5301
|
const lines = readFileSync9(historyJsonl, "utf-8").trim().split("\n");
|
|
@@ -5651,13 +5335,13 @@ async function importHistoryFromArchive(name, tempDir) {
|
|
|
5651
5335
|
}
|
|
5652
5336
|
}
|
|
5653
5337
|
function importSessionsFromArchive(dest, tempDir) {
|
|
5654
|
-
const sessionsDir =
|
|
5655
|
-
if (!
|
|
5338
|
+
const sessionsDir = resolve11(tempDir, "sessions");
|
|
5339
|
+
if (!existsSync7(sessionsDir)) return;
|
|
5656
5340
|
try {
|
|
5657
|
-
const destSessions =
|
|
5341
|
+
const destSessions = resolve11(dest, ".mind/sessions");
|
|
5658
5342
|
mkdirSync6(destSessions, { recursive: true });
|
|
5659
5343
|
for (const file of readdirSync2(sessionsDir)) {
|
|
5660
|
-
cpSync(
|
|
5344
|
+
cpSync(resolve11(sessionsDir, file), resolve11(destSessions, file));
|
|
5661
5345
|
}
|
|
5662
5346
|
} catch (err) {
|
|
5663
5347
|
logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
|
|
@@ -5737,7 +5421,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5737
5421
|
}
|
|
5738
5422
|
ensureVoluteHome();
|
|
5739
5423
|
const dest = mindDir(name);
|
|
5740
|
-
if (
|
|
5424
|
+
if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5741
5425
|
const templatesRoot = findTemplatesRoot();
|
|
5742
5426
|
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5743
5427
|
try {
|
|
@@ -5774,9 +5458,9 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5774
5458
|
writeVoluteConfig(dest, config2);
|
|
5775
5459
|
const modelId = body.model ?? cog?.model;
|
|
5776
5460
|
effectiveModel = modelId ? qualifyModelId(modelId) : void 0;
|
|
5777
|
-
const sdkConfigPath =
|
|
5461
|
+
const sdkConfigPath = resolve11(dest, "home/.config/config.json");
|
|
5778
5462
|
if (modelId || cog?.compaction) {
|
|
5779
|
-
const existing =
|
|
5463
|
+
const existing = existsSync7(sdkConfigPath) ? JSON.parse(readFileSync9(sdkConfigPath, "utf-8")) : {};
|
|
5780
5464
|
if (modelId) {
|
|
5781
5465
|
existing.model = template === "pi" ? qualifyModelId(modelId) : unqualifyModelId(modelId);
|
|
5782
5466
|
}
|
|
@@ -5789,7 +5473,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5789
5473
|
}
|
|
5790
5474
|
const mindPrompts = await getMindPromptDefaults();
|
|
5791
5475
|
writeFileSync8(
|
|
5792
|
-
|
|
5476
|
+
resolve11(dest, "home/.config/prompts.json"),
|
|
5793
5477
|
`${JSON.stringify(mindPrompts, null, 2)}
|
|
5794
5478
|
`
|
|
5795
5479
|
);
|
|
@@ -5801,7 +5485,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5801
5485
|
} catch (err) {
|
|
5802
5486
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5803
5487
|
}
|
|
5804
|
-
const homeDir =
|
|
5488
|
+
const homeDir = resolve11(dest, "home");
|
|
5805
5489
|
ensureVoluteGroup();
|
|
5806
5490
|
createMindUser(name, homeDir);
|
|
5807
5491
|
await chownMindDir(dest, name);
|
|
@@ -5814,7 +5498,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5814
5498
|
await initTemplateBranch(dest, composedDir, manifest, name, env);
|
|
5815
5499
|
} catch (err) {
|
|
5816
5500
|
logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
|
|
5817
|
-
rmSync3(
|
|
5501
|
+
rmSync3(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
5818
5502
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
5819
5503
|
}
|
|
5820
5504
|
if (body.stage === "seed") {
|
|
@@ -5823,7 +5507,7 @@ Your creator described you as: "${body.description}"
|
|
|
5823
5507
|
` : "";
|
|
5824
5508
|
const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
|
|
5825
5509
|
const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
|
|
5826
|
-
writeFileSync8(
|
|
5510
|
+
writeFileSync8(resolve11(dest, "home/SOUL.md"), seedSoul);
|
|
5827
5511
|
}
|
|
5828
5512
|
let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
|
|
5829
5513
|
if (body.stage === "seed" && !body.skills) {
|
|
@@ -5849,7 +5533,7 @@ Your creator described you as: "${body.description}"
|
|
|
5849
5533
|
const spiritName = getSpiritName();
|
|
5850
5534
|
const spiritEntry = await findMind(spiritName);
|
|
5851
5535
|
if (spiritEntry) {
|
|
5852
|
-
const { spiritDir } = await import("./spirit-
|
|
5536
|
+
const { spiritDir } = await import("./spirit-FKXMGO3N.js");
|
|
5853
5537
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
5854
5538
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
5855
5539
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -5864,7 +5548,7 @@ Your creator described you as: "${body.description}"
|
|
|
5864
5548
|
});
|
|
5865
5549
|
spiritConfig.schedules = schedules;
|
|
5866
5550
|
writeVoluteConfig(sDir, spiritConfig);
|
|
5867
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
5551
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-GLINVC2B.js");
|
|
5868
5552
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
5869
5553
|
}
|
|
5870
5554
|
}
|
|
@@ -5875,11 +5559,11 @@ Your creator described you as: "${body.description}"
|
|
|
5875
5559
|
if (body.stage !== "seed") {
|
|
5876
5560
|
const customSoul = await getPromptIfCustom("default_soul");
|
|
5877
5561
|
if (customSoul) {
|
|
5878
|
-
writeFileSync8(
|
|
5562
|
+
writeFileSync8(resolve11(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
|
|
5879
5563
|
}
|
|
5880
5564
|
const customMemory = await getPromptIfCustom("default_memory");
|
|
5881
5565
|
if (customMemory) {
|
|
5882
|
-
writeFileSync8(
|
|
5566
|
+
writeFileSync8(resolve11(dest, "home/MEMORY.md"), customMemory);
|
|
5883
5567
|
}
|
|
5884
5568
|
}
|
|
5885
5569
|
await chownMindDir(dest, name);
|
|
@@ -5919,7 +5603,7 @@ Your creator described you as: "${body.description}"
|
|
|
5919
5603
|
...skillWarnings.length > 0 && { skillWarnings }
|
|
5920
5604
|
});
|
|
5921
5605
|
} catch (err) {
|
|
5922
|
-
if (
|
|
5606
|
+
if (existsSync7(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5923
5607
|
try {
|
|
5924
5608
|
await removeMind(name);
|
|
5925
5609
|
} catch (cleanupErr) {
|
|
@@ -5940,13 +5624,13 @@ Your creator described you as: "${body.description}"
|
|
|
5940
5624
|
return importFromArchive(c, body.archivePath, body.name, body.manifest);
|
|
5941
5625
|
}
|
|
5942
5626
|
const wsDir = body.workspacePath;
|
|
5943
|
-
if (!wsDir || !
|
|
5627
|
+
if (!wsDir || !existsSync7(resolve11(wsDir, "SOUL.md")) || !existsSync7(resolve11(wsDir, "IDENTITY.md"))) {
|
|
5944
5628
|
return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
|
|
5945
5629
|
}
|
|
5946
|
-
const soul = readFileSync9(
|
|
5947
|
-
const identity = readFileSync9(
|
|
5948
|
-
const userPath =
|
|
5949
|
-
const user =
|
|
5630
|
+
const soul = readFileSync9(resolve11(wsDir, "SOUL.md"), "utf-8");
|
|
5631
|
+
const identity = readFileSync9(resolve11(wsDir, "IDENTITY.md"), "utf-8");
|
|
5632
|
+
const userPath = resolve11(wsDir, "USER.md");
|
|
5633
|
+
const user = existsSync7(userPath) ? readFileSync9(userPath, "utf-8") : "";
|
|
5950
5634
|
const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
|
|
5951
5635
|
const template = body.template ?? "claude";
|
|
5952
5636
|
const nameErr = validateMindName(name);
|
|
@@ -5966,33 +5650,33 @@ ${user.trimEnd()}
|
|
|
5966
5650
|
` : "";
|
|
5967
5651
|
ensureVoluteHome();
|
|
5968
5652
|
const dest = mindDir(name);
|
|
5969
|
-
if (
|
|
5653
|
+
if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5970
5654
|
const templatesRoot = findTemplatesRoot();
|
|
5971
5655
|
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5972
5656
|
try {
|
|
5973
5657
|
copyTemplateToDir(composedDir, dest, name, manifest);
|
|
5974
5658
|
applyInitFiles(dest);
|
|
5975
5659
|
const { publicKeyPem: importPublicKey } = generateIdentity(dest);
|
|
5976
|
-
writeFileSync8(
|
|
5977
|
-
const wsMemoryPath =
|
|
5978
|
-
const hasMemory =
|
|
5660
|
+
writeFileSync8(resolve11(dest, "home/SOUL.md"), mergedSoul);
|
|
5661
|
+
const wsMemoryPath = resolve11(wsDir, "MEMORY.md");
|
|
5662
|
+
const hasMemory = existsSync7(wsMemoryPath);
|
|
5979
5663
|
if (hasMemory) {
|
|
5980
5664
|
const existingMemory = readFileSync9(wsMemoryPath, "utf-8");
|
|
5981
5665
|
writeFileSync8(
|
|
5982
|
-
|
|
5666
|
+
resolve11(dest, "home/MEMORY.md"),
|
|
5983
5667
|
`${existingMemory.trimEnd()}${mergedMemoryExtra}`
|
|
5984
5668
|
);
|
|
5985
5669
|
} else if (user) {
|
|
5986
|
-
writeFileSync8(
|
|
5670
|
+
writeFileSync8(resolve11(dest, "home/MEMORY.md"), `${user.trimEnd()}
|
|
5987
5671
|
`);
|
|
5988
5672
|
}
|
|
5989
|
-
const wsMemoryDir =
|
|
5673
|
+
const wsMemoryDir = resolve11(wsDir, "memory");
|
|
5990
5674
|
let dailyLogCount = 0;
|
|
5991
|
-
if (
|
|
5992
|
-
const destMemoryDir =
|
|
5675
|
+
if (existsSync7(wsMemoryDir)) {
|
|
5676
|
+
const destMemoryDir = resolve11(dest, "home/memory");
|
|
5993
5677
|
const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
|
|
5994
5678
|
for (const file of files) {
|
|
5995
|
-
cpSync(
|
|
5679
|
+
cpSync(resolve11(wsMemoryDir, file), resolve11(destMemoryDir, file));
|
|
5996
5680
|
}
|
|
5997
5681
|
dailyLogCount = files.length;
|
|
5998
5682
|
}
|
|
@@ -6003,7 +5687,7 @@ ${user.trimEnd()}
|
|
|
6003
5687
|
} catch (err) {
|
|
6004
5688
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
6005
5689
|
}
|
|
6006
|
-
const homeDir =
|
|
5690
|
+
const homeDir = resolve11(dest, "home");
|
|
6007
5691
|
ensureVoluteGroup();
|
|
6008
5692
|
createMindUser(name, homeDir);
|
|
6009
5693
|
await chownMindDir(dest, name);
|
|
@@ -6011,20 +5695,20 @@ ${user.trimEnd()}
|
|
|
6011
5695
|
if (!hasMemory && dailyLogCount > 0) {
|
|
6012
5696
|
await consolidateMemory(dest);
|
|
6013
5697
|
}
|
|
6014
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5698
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
|
|
6015
5699
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
6016
5700
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
6017
5701
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
6018
5702
|
await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
|
|
6019
|
-
const sessionFile = body.sessionPath ?
|
|
6020
|
-
if (sessionFile &&
|
|
5703
|
+
const sessionFile = body.sessionPath ? resolve11(body.sessionPath) : findOpenClawSession(wsDir);
|
|
5704
|
+
if (sessionFile && existsSync7(sessionFile)) {
|
|
6021
5705
|
if (template === "pi") {
|
|
6022
5706
|
importPiSession(sessionFile, dest);
|
|
6023
5707
|
} else if (template === "claude") {
|
|
6024
5708
|
const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
|
|
6025
|
-
const mindRuntimeDir =
|
|
5709
|
+
const mindRuntimeDir = resolve11(dest, ".mind");
|
|
6026
5710
|
mkdirSync6(mindRuntimeDir, { recursive: true });
|
|
6027
|
-
writeFileSync8(
|
|
5711
|
+
writeFileSync8(resolve11(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
|
|
6028
5712
|
}
|
|
6029
5713
|
}
|
|
6030
5714
|
importOpenClawConnectors(name, dest);
|
|
@@ -6034,7 +5718,7 @@ ${user.trimEnd()}
|
|
|
6034
5718
|
);
|
|
6035
5719
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
6036
5720
|
} catch (err) {
|
|
6037
|
-
if (
|
|
5721
|
+
if (existsSync7(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
6038
5722
|
try {
|
|
6039
5723
|
await removeMind(name);
|
|
6040
5724
|
} catch (cleanupErr) {
|
|
@@ -6070,7 +5754,7 @@ ${user.trimEnd()}
|
|
|
6070
5754
|
stage: entry.stage,
|
|
6071
5755
|
dir: entry.dir
|
|
6072
5756
|
});
|
|
6073
|
-
const hasPages =
|
|
5757
|
+
const hasPages = existsSync7(resolve11(mindDir(entry.name), "home", "pages"));
|
|
6074
5758
|
const lastActiveAt = lastActiveMap.get(entry.name) ?? null;
|
|
6075
5759
|
if (!privileged) return toPublicMind(entry, mindStatus, { hasPages, lastActiveAt });
|
|
6076
5760
|
return {
|
|
@@ -6078,6 +5762,7 @@ ${user.trimEnd()}
|
|
|
6078
5762
|
...mindStatus,
|
|
6079
5763
|
hasPages,
|
|
6080
5764
|
templateStale: isTemplateStale(entry),
|
|
5765
|
+
upgradeBlocked: getUpgradeBlocked(entry.name)?.reason,
|
|
6081
5766
|
lastActiveAt
|
|
6082
5767
|
};
|
|
6083
5768
|
})
|
|
@@ -6088,12 +5773,12 @@ ${user.trimEnd()}
|
|
|
6088
5773
|
const entry = await findMind(name);
|
|
6089
5774
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6090
5775
|
const dir = entry.dir ?? mindDir(entry.parent ?? name);
|
|
6091
|
-
if (!
|
|
5776
|
+
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6092
5777
|
const mindStatus = await getMindStatus(name, entry.port, void 0, {
|
|
6093
5778
|
stage: entry.stage,
|
|
6094
5779
|
dir: entry.dir
|
|
6095
5780
|
});
|
|
6096
|
-
const hasPages =
|
|
5781
|
+
const hasPages = existsSync7(resolve11(mindDir(name), "home", "pages"));
|
|
6097
5782
|
if (!isPrivileged(c)) {
|
|
6098
5783
|
return c.json(toPublicMind(entry, mindStatus, { hasPages }));
|
|
6099
5784
|
}
|
|
@@ -6116,6 +5801,7 @@ ${user.trimEnd()}
|
|
|
6116
5801
|
variants: variantStatuses,
|
|
6117
5802
|
hasPages,
|
|
6118
5803
|
templateStale: isTemplateStale(entry),
|
|
5804
|
+
upgradeBlocked: getUpgradeBlocked(name)?.reason,
|
|
6119
5805
|
...notice && {
|
|
6120
5806
|
lastNotice: {
|
|
6121
5807
|
kind: notice.kind,
|
|
@@ -6133,7 +5819,7 @@ ${user.trimEnd()}
|
|
|
6133
5819
|
const projectDir = entry.dir ?? mindDir(name);
|
|
6134
5820
|
if (entry.parent) {
|
|
6135
5821
|
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
|
|
6136
|
-
} else if (!
|
|
5822
|
+
} else if (!existsSync7(projectDir)) {
|
|
6137
5823
|
return c.json({ error: "Mind directory missing" }, 404);
|
|
6138
5824
|
}
|
|
6139
5825
|
if (getMindManager().isRunning(name)) {
|
|
@@ -6154,7 +5840,7 @@ ${user.trimEnd()}
|
|
|
6154
5840
|
const projectDir = entry.dir ?? mindDir(name);
|
|
6155
5841
|
if (entry.parent) {
|
|
6156
5842
|
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
|
|
6157
|
-
} else if (!
|
|
5843
|
+
} else if (!existsSync7(projectDir)) {
|
|
6158
5844
|
return c.json({ error: "Mind directory missing" }, 404);
|
|
6159
5845
|
}
|
|
6160
5846
|
let context;
|
|
@@ -6170,7 +5856,7 @@ ${user.trimEnd()}
|
|
|
6170
5856
|
const manager = getMindManager();
|
|
6171
5857
|
try {
|
|
6172
5858
|
if (context?.type === "reload") {
|
|
6173
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5859
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Q3ITFNOJ.js");
|
|
6174
5860
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
6175
5861
|
if (sleepState?.sleeping) {
|
|
6176
5862
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -6191,7 +5877,7 @@ ${user.trimEnd()}
|
|
|
6191
5877
|
if (variantEntry && variantEntry.parent === baseName && variantEntry.dir && variantEntry.branch) {
|
|
6192
5878
|
const projectRoot = mindDir(baseName);
|
|
6193
5879
|
const discardUnresolved = context.discardUnresolvedHomeFiles === true;
|
|
6194
|
-
if (
|
|
5880
|
+
if (existsSync7(variantEntry.dir)) {
|
|
6195
5881
|
const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
|
|
6196
5882
|
if (status) {
|
|
6197
5883
|
try {
|
|
@@ -6221,7 +5907,7 @@ ${user.trimEnd()}
|
|
|
6221
5907
|
const preMergeHead = (await gitExec(["rev-parse", "HEAD"], { cwd: projectRoot })).trim();
|
|
6222
5908
|
const memoryDelta = await mergeVariantExcludingMemory(projectRoot, variantEntry.branch);
|
|
6223
5909
|
let unresolvedNotice;
|
|
6224
|
-
if (
|
|
5910
|
+
if (existsSync7(variantEntry.dir) && !discardUnresolved) {
|
|
6225
5911
|
try {
|
|
6226
5912
|
const unresolved = await findUnresolvedHomeFiles(variantEntry.dir);
|
|
6227
5913
|
if (unresolved.totalCount > 0) {
|
|
@@ -6319,7 +6005,7 @@ ${user.trimEnd()}
|
|
|
6319
6005
|
const name = c.req.param("name");
|
|
6320
6006
|
const entry = await findMind(name);
|
|
6321
6007
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6322
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6008
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Q3ITFNOJ.js");
|
|
6323
6009
|
const sm = getSleepManagerIfReady2();
|
|
6324
6010
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6325
6011
|
return c.json(sm.getState(name));
|
|
@@ -6327,7 +6013,7 @@ ${user.trimEnd()}
|
|
|
6327
6013
|
const name = c.req.param("name");
|
|
6328
6014
|
const entry = await findMind(name);
|
|
6329
6015
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6330
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6016
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Q3ITFNOJ.js");
|
|
6331
6017
|
const sm = getSleepManagerIfReady2();
|
|
6332
6018
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6333
6019
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -6347,7 +6033,7 @@ ${user.trimEnd()}
|
|
|
6347
6033
|
const name = c.req.param("name");
|
|
6348
6034
|
const entry = await findMind(name);
|
|
6349
6035
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6350
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6036
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Q3ITFNOJ.js");
|
|
6351
6037
|
const sm = getSleepManagerIfReady2();
|
|
6352
6038
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6353
6039
|
const sleepState = sm.getState(name);
|
|
@@ -6362,7 +6048,7 @@ ${user.trimEnd()}
|
|
|
6362
6048
|
const name = c.req.param("name");
|
|
6363
6049
|
const entry = await findMind(name);
|
|
6364
6050
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6365
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6051
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Q3ITFNOJ.js");
|
|
6366
6052
|
const sm = getSleepManagerIfReady2();
|
|
6367
6053
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6368
6054
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -6378,19 +6064,19 @@ ${user.trimEnd()}
|
|
|
6378
6064
|
if (body.displayName !== void 0) profile.displayName = body.displayName;
|
|
6379
6065
|
if (body.description !== void 0) profile.description = body.description;
|
|
6380
6066
|
if (body.avatar !== void 0) {
|
|
6381
|
-
const homeDir =
|
|
6067
|
+
const homeDir = resolve11(dir, "home");
|
|
6382
6068
|
const avatarPath = safeResolveWithinBase(homeDir, body.avatar);
|
|
6383
6069
|
if (!avatarPath) {
|
|
6384
6070
|
return c.json({ error: "Avatar path must be inside the mind's home directory" }, 400);
|
|
6385
6071
|
}
|
|
6386
|
-
if (!
|
|
6072
|
+
if (!existsSync7(avatarPath)) {
|
|
6387
6073
|
return c.json({ error: `Avatar file not found: ${relative(homeDir, avatarPath)}` }, 400);
|
|
6388
6074
|
}
|
|
6389
6075
|
profile.avatar = relative(homeDir, avatarPath);
|
|
6390
6076
|
}
|
|
6391
6077
|
config2.profile = profile;
|
|
6392
6078
|
writeVoluteConfig(dir, config2);
|
|
6393
|
-
const { syncMindProfile: syncMindProfile2 } = await import("./auth-
|
|
6079
|
+
const { syncMindProfile: syncMindProfile2 } = await import("./auth-Y27LTNZK.js");
|
|
6394
6080
|
await syncMindProfile2(name, profile);
|
|
6395
6081
|
broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
|
|
6396
6082
|
return c.json({ ok: true });
|
|
@@ -6434,7 +6120,7 @@ ${user.trimEnd()}
|
|
|
6434
6120
|
});
|
|
6435
6121
|
}
|
|
6436
6122
|
if (!force) {
|
|
6437
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6123
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Q3ITFNOJ.js");
|
|
6438
6124
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
6439
6125
|
return c.json({ output: "" });
|
|
6440
6126
|
}
|
|
@@ -6489,7 +6175,7 @@ ${user.trimEnd()}
|
|
|
6489
6175
|
}
|
|
6490
6176
|
}
|
|
6491
6177
|
const dir = entry.dir ?? mindDir(name);
|
|
6492
|
-
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-
|
|
6178
|
+
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-XBH2MUNA.js");
|
|
6493
6179
|
const checklist = evaluateSeedChecklist2(dir);
|
|
6494
6180
|
const done = [];
|
|
6495
6181
|
const remaining = [];
|
|
@@ -6531,7 +6217,7 @@ ${user.trimEnd()}
|
|
|
6531
6217
|
try {
|
|
6532
6218
|
const sproutedDir = entry.dir ?? mindDir(name);
|
|
6533
6219
|
if (setupDefaultDreaming(sproutedDir).schedulesChanged) {
|
|
6534
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6220
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-GLINVC2B.js");
|
|
6535
6221
|
getScheduler2().loadSchedules(name, sproutedDir);
|
|
6536
6222
|
}
|
|
6537
6223
|
} catch (err) {
|
|
@@ -6541,7 +6227,7 @@ ${user.trimEnd()}
|
|
|
6541
6227
|
const spiritName = getSpiritName();
|
|
6542
6228
|
const spiritEntry = await findMind(spiritName);
|
|
6543
6229
|
if (spiritEntry) {
|
|
6544
|
-
const { firstWeekSchedules, spiritDir } = await import("./spirit-
|
|
6230
|
+
const { firstWeekSchedules, spiritDir } = await import("./spirit-FKXMGO3N.js");
|
|
6545
6231
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
6546
6232
|
const spiritConfig = readVoluteConfig(sDir);
|
|
6547
6233
|
if (spiritConfig) {
|
|
@@ -6555,7 +6241,7 @@ ${user.trimEnd()}
|
|
|
6555
6241
|
spiritConfig.schedules = schedules;
|
|
6556
6242
|
writeVoluteConfig(sDir, spiritConfig);
|
|
6557
6243
|
try {
|
|
6558
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6244
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-GLINVC2B.js");
|
|
6559
6245
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
6560
6246
|
} catch (err) {
|
|
6561
6247
|
logger_default.warn(
|
|
@@ -6609,10 +6295,10 @@ ${user.trimEnd()}
|
|
|
6609
6295
|
await deleteMindUser2(name);
|
|
6610
6296
|
invalidateMindUserCache(name);
|
|
6611
6297
|
const state = stateDir(name);
|
|
6612
|
-
if (
|
|
6298
|
+
if (existsSync7(state)) {
|
|
6613
6299
|
rmSync3(state, { recursive: true, force: true });
|
|
6614
6300
|
}
|
|
6615
|
-
if (force &&
|
|
6301
|
+
if (force && existsSync7(dir)) {
|
|
6616
6302
|
rmSync3(dir, { recursive: true, force: true });
|
|
6617
6303
|
deleteMindUser(name);
|
|
6618
6304
|
}
|
|
@@ -6627,7 +6313,7 @@ ${user.trimEnd()}
|
|
|
6627
6313
|
const entry = await findMind(mindName);
|
|
6628
6314
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6629
6315
|
const dir = mindDir(mindName);
|
|
6630
|
-
if (!
|
|
6316
|
+
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6631
6317
|
let body = {};
|
|
6632
6318
|
try {
|
|
6633
6319
|
body = await c.req.json();
|
|
@@ -6638,27 +6324,12 @@ ${user.trimEnd()}
|
|
|
6638
6324
|
if (!isKnownTemplate(template)) {
|
|
6639
6325
|
return c.json({ error: `Unknown template: ${template}` }, 400);
|
|
6640
6326
|
}
|
|
6641
|
-
const UPGRADE_BRANCH = "upgrade";
|
|
6642
|
-
const upgradeVariantName = `${mindName}-upgrade`;
|
|
6643
|
-
const worktreeDir = resolve13(dir, ".variants", UPGRADE_BRANCH);
|
|
6644
6327
|
if (body.abort) {
|
|
6645
|
-
if (!
|
|
6328
|
+
if (!upgradeInProgress(mindName)) {
|
|
6646
6329
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
6647
6330
|
}
|
|
6648
6331
|
try {
|
|
6649
|
-
|
|
6650
|
-
const gitDirContent = readFileSync9(resolve13(worktreeDir, ".git"), "utf-8").trim();
|
|
6651
|
-
const gitDir = gitDirContent.replace("gitdir: ", "");
|
|
6652
|
-
if (existsSync8(resolve13(gitDir, "MERGE_HEAD"))) {
|
|
6653
|
-
await gitExec(["merge", "--abort"], { cwd: worktreeDir });
|
|
6654
|
-
}
|
|
6655
|
-
} catch {
|
|
6656
|
-
}
|
|
6657
|
-
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir, { stop: true });
|
|
6658
|
-
try {
|
|
6659
|
-
await gitExec(["branch", "-D", UPGRADE_BRANCH], { cwd: dir });
|
|
6660
|
-
} catch {
|
|
6661
|
-
}
|
|
6332
|
+
await abortUpgrade(mindName);
|
|
6662
6333
|
return c.json({ ok: true });
|
|
6663
6334
|
} catch (err) {
|
|
6664
6335
|
return c.json(
|
|
@@ -6668,81 +6339,45 @@ ${user.trimEnd()}
|
|
|
6668
6339
|
}
|
|
6669
6340
|
}
|
|
6670
6341
|
if (body.continue) {
|
|
6671
|
-
if (!
|
|
6342
|
+
if (!upgradeInProgress(mindName)) {
|
|
6672
6343
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
6673
6344
|
}
|
|
6674
|
-
const status = await gitExec(["status", "--porcelain"], { cwd: worktreeDir });
|
|
6675
|
-
const hasConflicts2 = status.split("\n").some((line) => line.startsWith("UU") || line.startsWith("AA"));
|
|
6676
|
-
if (hasConflicts2) {
|
|
6677
|
-
return c.json({ error: "Unresolved conflicts remain" }, 409);
|
|
6678
|
-
}
|
|
6679
|
-
try {
|
|
6680
|
-
await gitExec(["add", "-A"], { cwd: worktreeDir });
|
|
6681
|
-
await gitExec(["commit", "-m", "merge template update"], { cwd: worktreeDir });
|
|
6682
|
-
} catch (e) {
|
|
6683
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
6684
|
-
const stderr = e?.stderr ?? "";
|
|
6685
|
-
const stdout = e?.stdout ?? "";
|
|
6686
|
-
if (!msg.includes("nothing to commit") && !stderr.includes("nothing to commit") && !stdout.includes("nothing to commit"))
|
|
6687
|
-
throw e;
|
|
6688
|
-
}
|
|
6689
|
-
try {
|
|
6690
|
-
await gitExec(["add", "home/"], { cwd: worktreeDir });
|
|
6691
|
-
} catch (err) {
|
|
6692
|
-
logger_default.warn(`failed to re-add home files during upgrade for ${mindName}`, logger_default.errorData(err));
|
|
6693
|
-
}
|
|
6694
|
-
try {
|
|
6695
|
-
await gitExec(["diff", "--cached", "--quiet"], { cwd: worktreeDir });
|
|
6696
|
-
} catch {
|
|
6697
|
-
await gitExec(["commit", "-m", "re-add allowlisted home files"], {
|
|
6698
|
-
cwd: worktreeDir
|
|
6699
|
-
});
|
|
6700
|
-
}
|
|
6701
|
-
await chownMindDir(dir, mindName);
|
|
6702
6345
|
try {
|
|
6703
|
-
const result = await
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6346
|
+
const result = await continueUpgrade(mindName, { template });
|
|
6347
|
+
if (result.status === "conflicts") {
|
|
6348
|
+
return c.json({
|
|
6349
|
+
ok: false,
|
|
6350
|
+
conflicts: true,
|
|
6351
|
+
worktreeDir: result.worktreeDir,
|
|
6352
|
+
files: result.files,
|
|
6353
|
+
message: result.message ?? "Merge conflicts detected. Resolve them, then run with continue."
|
|
6354
|
+
});
|
|
6355
|
+
}
|
|
6356
|
+
return c.json({ ok: true, warning: result.warning });
|
|
6713
6357
|
} catch (err) {
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6358
|
+
const msg = err instanceof Error ? err.message : "Failed to merge upgrade";
|
|
6359
|
+
if (msg === "Unresolved conflicts remain") {
|
|
6360
|
+
return c.json({ error: msg }, 409);
|
|
6361
|
+
}
|
|
6362
|
+
return c.json({ error: msg }, 500);
|
|
6718
6363
|
}
|
|
6719
6364
|
}
|
|
6720
6365
|
if (body.accept) {
|
|
6721
|
-
if (
|
|
6366
|
+
if (upgradeInProgress(mindName)) {
|
|
6722
6367
|
try {
|
|
6723
|
-
await
|
|
6368
|
+
await abortUpgrade(mindName);
|
|
6724
6369
|
} catch (err) {
|
|
6725
6370
|
logger_default.warn(`failed to clean up legacy upgrade variant for ${mindName}`, logger_default.errorData(err));
|
|
6726
6371
|
}
|
|
6727
|
-
try {
|
|
6728
|
-
await gitExec(["branch", "-D", UPGRADE_BRANCH], { cwd: dir });
|
|
6729
|
-
} catch {
|
|
6730
|
-
}
|
|
6731
6372
|
}
|
|
6732
6373
|
return c.json({ error: "Upgrades now auto-merge. Run 'volute mind upgrade' again." }, 400);
|
|
6733
6374
|
}
|
|
6734
6375
|
if (body.diff) {
|
|
6376
|
+
if (!existsSync7(resolve11(dir, ".git"))) {
|
|
6377
|
+
return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
|
|
6378
|
+
}
|
|
6735
6379
|
try {
|
|
6736
|
-
|
|
6737
|
-
return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
|
|
6738
|
-
}
|
|
6739
|
-
await updateTemplateBranch(dir, template, mindName);
|
|
6740
|
-
let diff;
|
|
6741
|
-
try {
|
|
6742
|
-
diff = await gitExec(["diff", "HEAD...volute/template"], { cwd: dir });
|
|
6743
|
-
} catch {
|
|
6744
|
-
diff = await gitExec(["diff", "HEAD", "volute/template"], { cwd: dir });
|
|
6745
|
-
}
|
|
6380
|
+
const diff = await upgradeDiff(mindName, template);
|
|
6746
6381
|
return c.json({ ok: true, diff: diff || "(no changes)" });
|
|
6747
6382
|
} catch (err) {
|
|
6748
6383
|
return c.json(
|
|
@@ -6751,103 +6386,21 @@ ${user.trimEnd()}
|
|
|
6751
6386
|
);
|
|
6752
6387
|
}
|
|
6753
6388
|
}
|
|
6754
|
-
if (existsSync8(worktreeDir)) {
|
|
6755
|
-
return c.json(
|
|
6756
|
-
{ error: "Upgrade variant already exists. Use continue or delete it first." },
|
|
6757
|
-
409
|
|
6758
|
-
);
|
|
6759
|
-
}
|
|
6760
|
-
if (!existsSync8(resolve13(dir, ".git"))) {
|
|
6761
|
-
try {
|
|
6762
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve13(dir, "home") } : void 0;
|
|
6763
|
-
await gitExec(["init"], { cwd: dir, mindName, env });
|
|
6764
|
-
await configureGitIdentity(mindName, { cwd: dir, mindName, env });
|
|
6765
|
-
await gitExec(["add", "-A"], { cwd: dir, mindName, env });
|
|
6766
|
-
await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
|
|
6767
|
-
await chownMindDir(dir, mindName);
|
|
6768
|
-
} catch (err) {
|
|
6769
|
-
rmSync3(resolve13(dir, ".git"), { recursive: true, force: true });
|
|
6770
|
-
return c.json(
|
|
6771
|
-
{
|
|
6772
|
-
error: `Git initialization failed: ${err instanceof Error ? err.message : String(err)}`
|
|
6773
|
-
},
|
|
6774
|
-
500
|
|
6775
|
-
);
|
|
6776
|
-
}
|
|
6777
|
-
}
|
|
6778
|
-
await gitExec(["worktree", "prune"], { cwd: dir });
|
|
6779
|
-
try {
|
|
6780
|
-
await gitExec(["branch", "-D", UPGRADE_BRANCH], { cwd: dir });
|
|
6781
|
-
} catch {
|
|
6782
|
-
}
|
|
6783
|
-
await updateTemplateBranch(dir, template, mindName);
|
|
6784
|
-
const parentDir = resolve13(dir, ".variants");
|
|
6785
|
-
if (!existsSync8(parentDir)) {
|
|
6786
|
-
mkdirSync6(parentDir, { recursive: true });
|
|
6787
|
-
}
|
|
6788
|
-
await gitExec(["worktree", "add", "-b", UPGRADE_BRANCH, worktreeDir], { cwd: dir });
|
|
6789
|
-
await gitExec(["rm", "-r", "--cached", "--ignore-unmatch", "home/"], {
|
|
6790
|
-
cwd: worktreeDir
|
|
6791
|
-
});
|
|
6792
|
-
try {
|
|
6793
|
-
await gitExec(["checkout", "HEAD", "--", "home/VOLUTE.md"], { cwd: worktreeDir });
|
|
6794
|
-
await gitExec(["add", "home/VOLUTE.md"], { cwd: worktreeDir });
|
|
6795
|
-
} catch (err) {
|
|
6796
|
-
const msg = String(err?.message ?? err);
|
|
6797
|
-
if (!msg.includes("did not match")) {
|
|
6798
|
-
logger_default.warn(
|
|
6799
|
-
`unexpected error restoring VOLUTE.md during upgrade for ${mindName}`,
|
|
6800
|
-
logger_default.errorData(err)
|
|
6801
|
-
);
|
|
6802
|
-
}
|
|
6803
|
-
}
|
|
6804
6389
|
try {
|
|
6805
|
-
await
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
try {
|
|
6814
|
-
await gitExec(["add", "home/"], { cwd: worktreeDir });
|
|
6815
|
-
} catch (err) {
|
|
6816
|
-
logger_default.warn(`failed to re-add home files during upgrade for ${mindName}`, logger_default.errorData(err));
|
|
6817
|
-
}
|
|
6818
|
-
try {
|
|
6819
|
-
await gitExec(["diff", "--cached", "--quiet"], { cwd: worktreeDir });
|
|
6820
|
-
} catch {
|
|
6821
|
-
await gitExec(["commit", "-m", "re-add allowlisted home files"], {
|
|
6822
|
-
cwd: worktreeDir
|
|
6390
|
+
const result = await runUpgrade(mindName, { template });
|
|
6391
|
+
if (result.status === "conflicts") {
|
|
6392
|
+
return c.json({
|
|
6393
|
+
ok: false,
|
|
6394
|
+
conflicts: true,
|
|
6395
|
+
worktreeDir: result.worktreeDir,
|
|
6396
|
+
files: result.files,
|
|
6397
|
+
message: result.message ?? "Merge conflicts detected. Resolve them, then run with continue."
|
|
6823
6398
|
});
|
|
6824
6399
|
}
|
|
6825
|
-
|
|
6826
|
-
await chownMindDir(dir, mindName);
|
|
6827
|
-
if (hasConflicts) {
|
|
6828
|
-
return c.json({
|
|
6829
|
-
ok: false,
|
|
6830
|
-
conflicts: true,
|
|
6831
|
-
worktreeDir,
|
|
6832
|
-
message: "Merge conflicts detected. Resolve them, then run with continue."
|
|
6833
|
-
});
|
|
6834
|
-
}
|
|
6835
|
-
try {
|
|
6836
|
-
const result = await mergeUpgradeAndRestart(
|
|
6837
|
-
mindName,
|
|
6838
|
-
dir,
|
|
6839
|
-
worktreeDir,
|
|
6840
|
-
upgradeVariantName,
|
|
6841
|
-
UPGRADE_BRANCH,
|
|
6842
|
-
template,
|
|
6843
|
-
oldTemplate
|
|
6844
|
-
);
|
|
6845
|
-
return c.json(result);
|
|
6400
|
+
return c.json({ ok: true, warning: result.warning });
|
|
6846
6401
|
} catch (err) {
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
} catch (cleanupErr) {
|
|
6850
|
-
logger_default.warn(`cleanup failed after upgrade error for ${mindName}`, logger_default.errorData(cleanupErr));
|
|
6402
|
+
if (err instanceof UpgradeInProgressError) {
|
|
6403
|
+
return c.json({ error: err.message }, 409);
|
|
6851
6404
|
}
|
|
6852
6405
|
return c.json({ error: err instanceof Error ? err.message : "Failed to merge upgrade" }, 500);
|
|
6853
6406
|
}
|
|
@@ -6915,11 +6468,11 @@ ${user.trimEnd()}
|
|
|
6915
6468
|
const entry = await findMind(name);
|
|
6916
6469
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6917
6470
|
const dir = entry.dir ?? mindDir(name);
|
|
6918
|
-
if (!
|
|
6471
|
+
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6919
6472
|
let config2 = readVoluteConfig(dir);
|
|
6920
6473
|
if (!config2 && entry.template === "pi") {
|
|
6921
|
-
const piConfigPath =
|
|
6922
|
-
if (
|
|
6474
|
+
const piConfigPath = resolve11(dir, "home/.config/config.json");
|
|
6475
|
+
if (existsSync7(piConfigPath)) {
|
|
6923
6476
|
try {
|
|
6924
6477
|
config2 = JSON.parse(readFileSync9(piConfigPath, "utf-8"));
|
|
6925
6478
|
} catch {
|
|
@@ -6927,8 +6480,8 @@ ${user.trimEnd()}
|
|
|
6927
6480
|
}
|
|
6928
6481
|
}
|
|
6929
6482
|
let templateConfig = {};
|
|
6930
|
-
const configJsonPath =
|
|
6931
|
-
if (
|
|
6483
|
+
const configJsonPath = resolve11(dir, "home/.config/config.json");
|
|
6484
|
+
if (existsSync7(configJsonPath)) {
|
|
6932
6485
|
try {
|
|
6933
6486
|
templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
|
|
6934
6487
|
} catch {
|
|
@@ -6970,7 +6523,7 @@ ${user.trimEnd()}
|
|
|
6970
6523
|
const entry = await findMind(name);
|
|
6971
6524
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6972
6525
|
const dir = entry.dir ?? mindDir(name);
|
|
6973
|
-
if (!
|
|
6526
|
+
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6974
6527
|
const body = c.req.valid("json");
|
|
6975
6528
|
const existing = readVoluteConfig(dir) ?? {};
|
|
6976
6529
|
if (body.model !== void 0) existing.model = body.model;
|
|
@@ -6996,14 +6549,14 @@ ${user.trimEnd()}
|
|
|
6996
6549
|
}
|
|
6997
6550
|
writeVoluteConfig(dir, existing);
|
|
6998
6551
|
if (body.unescapeNewlines !== void 0) {
|
|
6999
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
6552
|
+
const { clearEchoTextCache } = await import("./echo-text-ULEIFJJF.js");
|
|
7000
6553
|
clearEchoTextCache(name);
|
|
7001
6554
|
}
|
|
7002
6555
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.compaction !== void 0;
|
|
7003
6556
|
if (needsConfigJson) {
|
|
7004
|
-
const configJsonPath =
|
|
6557
|
+
const configJsonPath = resolve11(dir, "home/.config/config.json");
|
|
7005
6558
|
let templateConfig = {};
|
|
7006
|
-
if (
|
|
6559
|
+
if (existsSync7(configJsonPath)) {
|
|
7007
6560
|
try {
|
|
7008
6561
|
templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
|
|
7009
6562
|
} catch {
|
|
@@ -7068,15 +6621,49 @@ ${user.trimEnd()}
|
|
|
7068
6621
|
if (err instanceof Error && err.message.includes("not initialized")) {
|
|
7069
6622
|
return c.json({ error: "Delivery manager not available" }, 503);
|
|
7070
6623
|
}
|
|
6624
|
+
if (err instanceof UnknownChannelError) return c.json({ error: err.message }, 400);
|
|
7071
6625
|
logger_default.error(`failed to decline channel ${channel} for ${name}`, logger_default.errorData(err));
|
|
7072
6626
|
return c.json({ error: "Failed to decline channel" }, 500);
|
|
7073
6627
|
}
|
|
6628
|
+
}).post("/:name/gates/accept", requireSelf(), async (c) => {
|
|
6629
|
+
const name = c.req.param("name");
|
|
6630
|
+
const body = await c.req.json().catch(() => ({}));
|
|
6631
|
+
const channel = body.channel?.trim();
|
|
6632
|
+
if (!channel) return c.json({ error: "channel required" }, 400);
|
|
6633
|
+
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
6634
|
+
try {
|
|
6635
|
+
const result = await getDeliveryManager().acceptChannel(name, channel, body.thread?.trim());
|
|
6636
|
+
return c.json({ ok: true, channel, ...result });
|
|
6637
|
+
} catch (err) {
|
|
6638
|
+
if (err instanceof Error && err.message.includes("not initialized")) {
|
|
6639
|
+
return c.json({ error: "Delivery manager not available" }, 503);
|
|
6640
|
+
}
|
|
6641
|
+
if (err instanceof Error && err.message.includes("malformed")) {
|
|
6642
|
+
return c.json({ error: err.message }, 409);
|
|
6643
|
+
}
|
|
6644
|
+
if (err instanceof UnknownChannelError) return c.json({ error: err.message }, 400);
|
|
6645
|
+
logger_default.error(`failed to accept channel ${channel} for ${name}`, logger_default.errorData(err));
|
|
6646
|
+
return c.json({ error: "Failed to accept channel" }, 500);
|
|
6647
|
+
}
|
|
6648
|
+
}).get("/:name/gates/peek", requireSelf(), async (c) => {
|
|
6649
|
+
const name = c.req.param("name");
|
|
6650
|
+
const channel = c.req.query("channel")?.trim();
|
|
6651
|
+
if (!channel) return c.json({ error: "channel required" }, 400);
|
|
6652
|
+
try {
|
|
6653
|
+
return c.json(await getDeliveryManager().peekChannel(name, channel));
|
|
6654
|
+
} catch (err) {
|
|
6655
|
+
if (err instanceof Error && err.message.includes("not initialized")) {
|
|
6656
|
+
return c.json({ error: "Delivery manager not available" }, 503);
|
|
6657
|
+
}
|
|
6658
|
+
logger_default.error(`failed to peek channel ${channel} for ${name}`, logger_default.errorData(err));
|
|
6659
|
+
return c.json({ error: "Failed to read held messages" }, 500);
|
|
6660
|
+
}
|
|
7074
6661
|
}).post("/:name/ai/complete", requireSelf(), async (c) => {
|
|
7075
6662
|
const body = await c.req.json();
|
|
7076
6663
|
if (!body.systemPrompt || !body.message) {
|
|
7077
6664
|
return c.json({ error: "systemPrompt and message required" }, 400);
|
|
7078
6665
|
}
|
|
7079
|
-
const { aiComplete: aiCompleteFn, isAiConfigured: isAiConfigured2 } = await import("./ai-service-
|
|
6666
|
+
const { aiComplete: aiCompleteFn, isAiConfigured: isAiConfigured2 } = await import("./ai-service-KEK2V3AP.js");
|
|
7080
6667
|
if (!isAiConfigured2()) {
|
|
7081
6668
|
return c.json({ error: "AI service not configured" }, 503);
|
|
7082
6669
|
}
|
|
@@ -7321,6 +6908,11 @@ ${lines.join("\n")}` });
|
|
|
7321
6908
|
const maxId = notices.reduce((m, n) => Math.max(m, n.id), 0);
|
|
7322
6909
|
setNoticeDrainWatermark(baseName, session, maxId);
|
|
7323
6910
|
return c.json({ context: formatEvents(notices), notices });
|
|
6911
|
+
}).get("/:name/turn-context", requireSelf(), async (c) => {
|
|
6912
|
+
const name = c.req.param("name");
|
|
6913
|
+
const baseName = await getBaseName(name);
|
|
6914
|
+
const reason = c.req.query("reason") === "wake" ? "wake" : "turn";
|
|
6915
|
+
return c.json({ context: await collectTurnContext(baseName, reason) });
|
|
7324
6916
|
}).post("/:name/notices", requireSelf(), async (c) => {
|
|
7325
6917
|
const MIND_POSTABLE_KINDS = ["context_lost", "delivery_failed"];
|
|
7326
6918
|
const name = c.req.param("name");
|
|
@@ -7840,7 +7432,7 @@ var app15 = new Hono18().get("/:name/clock/status", requireSelf(), async (c) =>
|
|
|
7840
7432
|
const entry = await findMind(name);
|
|
7841
7433
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
7842
7434
|
const body = await c.req.text();
|
|
7843
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
7435
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-ZYOCYAO2.js");
|
|
7844
7436
|
const { id, delivered } = await deliverEvent2(name, {
|
|
7845
7437
|
type: "webhook",
|
|
7846
7438
|
body,
|
|
@@ -7858,14 +7450,14 @@ var schedules_default = app15;
|
|
|
7858
7450
|
// packages/daemon/src/web/api/setup.ts
|
|
7859
7451
|
import { mkdirSync as mkdirSync7, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "fs";
|
|
7860
7452
|
import { homedir as homedir2 } from "os";
|
|
7861
|
-
import { basename, resolve as
|
|
7453
|
+
import { basename, resolve as resolve12 } from "path";
|
|
7862
7454
|
import { Hono as Hono19 } from "hono";
|
|
7863
7455
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
7864
7456
|
var DEFAULT_API_URL2 = "https://volute.systems";
|
|
7865
7457
|
var setup = new Hono19();
|
|
7866
7458
|
function writeSetupConfig(systemName, description) {
|
|
7867
|
-
const configHome = process.env.VOLUTE_HOME ??
|
|
7868
|
-
const mindsDir =
|
|
7459
|
+
const configHome = process.env.VOLUTE_HOME ?? resolve12(homedir2(), ".volute");
|
|
7460
|
+
const mindsDir = resolve12(configHome, "minds");
|
|
7869
7461
|
mkdirSync7(configHome, { recursive: true });
|
|
7870
7462
|
mkdirSync7(mindsDir, { recursive: true });
|
|
7871
7463
|
const existingConfig = readGlobalConfig();
|
|
@@ -7899,7 +7491,7 @@ setup.get("/status", async (c) => {
|
|
|
7899
7491
|
let hasAccount = false;
|
|
7900
7492
|
if (hasSystem) {
|
|
7901
7493
|
try {
|
|
7902
|
-
const { listUsersByType: listUsersByType2 } = await import("./auth-
|
|
7494
|
+
const { listUsersByType: listUsersByType2 } = await import("./auth-Y27LTNZK.js");
|
|
7903
7495
|
const brains = await listUsersByType2("human");
|
|
7904
7496
|
hasAccount = brains.length > 0;
|
|
7905
7497
|
} catch (err) {
|
|
@@ -8111,7 +7703,7 @@ setup.post("/account", async (c) => {
|
|
|
8111
7703
|
}
|
|
8112
7704
|
}
|
|
8113
7705
|
try {
|
|
8114
|
-
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-
|
|
7706
|
+
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-Y27LTNZK.js");
|
|
8115
7707
|
const user = await createUser2(body.username.trim(), body.password);
|
|
8116
7708
|
if (body.displayName?.trim()) {
|
|
8117
7709
|
await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
|
|
@@ -8157,7 +7749,7 @@ setup.post("/models", async (c) => {
|
|
|
8157
7749
|
return c.json({ error: "Spirit model is required" }, 400);
|
|
8158
7750
|
}
|
|
8159
7751
|
try {
|
|
8160
|
-
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-
|
|
7752
|
+
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-KEK2V3AP.js");
|
|
8161
7753
|
setEnabledModels3(body.models);
|
|
8162
7754
|
const config2 = readGlobalConfig();
|
|
8163
7755
|
config2.spiritModel = body.spiritModel.trim();
|
|
@@ -8200,7 +7792,7 @@ setup.post("/spirit", async (c) => {
|
|
|
8200
7792
|
config2.setup.spiritDescription = description || void 0;
|
|
8201
7793
|
const clearOldStash = () => {
|
|
8202
7794
|
if (config2.setup?.spiritAvatar) {
|
|
8203
|
-
rmSync4(
|
|
7795
|
+
rmSync4(resolve12(voluteSystemDir(), basename(config2.setup.spiritAvatar)), { force: true });
|
|
8204
7796
|
config2.setup.spiritAvatar = void 0;
|
|
8205
7797
|
}
|
|
8206
7798
|
};
|
|
@@ -8224,7 +7816,7 @@ setup.post("/spirit", async (c) => {
|
|
|
8224
7816
|
}
|
|
8225
7817
|
clearOldStash();
|
|
8226
7818
|
const filename = `spirit-avatar.${ext}`;
|
|
8227
|
-
writeFileSync9(
|
|
7819
|
+
writeFileSync9(resolve12(voluteSystemDir(), filename), bytes);
|
|
8228
7820
|
config2.setup.spiritAvatar = filename;
|
|
8229
7821
|
} else {
|
|
8230
7822
|
clearOldStash();
|
|
@@ -8237,15 +7829,16 @@ setup.post("/complete", async (c) => {
|
|
|
8237
7829
|
return c.json({ error: "Setup already complete" }, 400);
|
|
8238
7830
|
}
|
|
8239
7831
|
try {
|
|
8240
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
8241
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
7832
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-FKXMGO3N.js");
|
|
7833
|
+
const { startSpiritFull } = await import("./mind-service-ZJCUBAUL.js");
|
|
8242
7834
|
await ensureSpiritProject();
|
|
8243
7835
|
await syncSpiritTemplate();
|
|
7836
|
+
await notifyExtensionsSpiritReady();
|
|
8244
7837
|
const warnings = [];
|
|
8245
7838
|
const config2 = readGlobalConfig();
|
|
8246
7839
|
if (config2.setup?.service && config2.setup?.type === "local") {
|
|
8247
7840
|
try {
|
|
8248
|
-
const { installUserService } = await import("./service-install-
|
|
7841
|
+
const { installUserService } = await import("./service-install-R4SNYUVO.js");
|
|
8249
7842
|
const installed = await installUserService(config2.port, config2.hostname);
|
|
8250
7843
|
if (!installed) {
|
|
8251
7844
|
warnings.push("Service installation is not supported on this platform.");
|
|
@@ -8275,8 +7868,8 @@ setup.post("/complete", async (c) => {
|
|
|
8275
7868
|
}
|
|
8276
7869
|
let spiritConversationId;
|
|
8277
7870
|
try {
|
|
8278
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-
|
|
8279
|
-
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-
|
|
7871
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-Y27LTNZK.js");
|
|
7872
|
+
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-FH3ODBL7.js");
|
|
8280
7873
|
const spiritUser = await getOrCreateMindUser2(spiritName);
|
|
8281
7874
|
const brains = await listUsersByType2("human");
|
|
8282
7875
|
const admin2 = brains.find((u) => u.role === "admin");
|
|
@@ -8298,8 +7891,8 @@ setup.post("/complete", async (c) => {
|
|
|
8298
7891
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
8299
7892
|
if (spiritConversationId && spiritStarted) {
|
|
8300
7893
|
try {
|
|
8301
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
8302
|
-
const { listUsersByType: listUsers2 } = await import("./auth-
|
|
7894
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-LU4EP244.js");
|
|
7895
|
+
const { listUsersByType: listUsers2 } = await import("./auth-Y27LTNZK.js");
|
|
8303
7896
|
const admins = await listUsers2("human");
|
|
8304
7897
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
8305
7898
|
if (admin2) {
|
|
@@ -8338,9 +7931,9 @@ setup.post("/complete", async (c) => {
|
|
|
8338
7931
|
var setup_default = setup;
|
|
8339
7932
|
|
|
8340
7933
|
// packages/daemon/src/web/api/skills.ts
|
|
8341
|
-
import { existsSync as
|
|
7934
|
+
import { existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
|
|
8342
7935
|
import { tmpdir } from "os";
|
|
8343
|
-
import { join, resolve as
|
|
7936
|
+
import { join, resolve as resolve13 } from "path";
|
|
8344
7937
|
import AdmZip from "adm-zip";
|
|
8345
7938
|
import { Hono as Hono20 } from "hono";
|
|
8346
7939
|
var app16 = new Hono20().get("/", async (c) => {
|
|
@@ -8416,19 +8009,19 @@ var app16 = new Hono20().get("/", async (c) => {
|
|
|
8416
8009
|
try {
|
|
8417
8010
|
const zip = new AdmZip(buffer);
|
|
8418
8011
|
for (const entry of zip.getEntries()) {
|
|
8419
|
-
const target =
|
|
8012
|
+
const target = resolve13(tmpDir, entry.entryName);
|
|
8420
8013
|
if (!target.startsWith(tmpDir)) {
|
|
8421
8014
|
return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
|
|
8422
8015
|
}
|
|
8423
8016
|
}
|
|
8424
8017
|
zip.extractAllTo(tmpDir, true);
|
|
8425
8018
|
let skillDir = null;
|
|
8426
|
-
if (
|
|
8019
|
+
if (existsSync8(join(tmpDir, "SKILL.md"))) {
|
|
8427
8020
|
skillDir = tmpDir;
|
|
8428
8021
|
} else {
|
|
8429
8022
|
const entries = readdirSync3(tmpDir, { withFileTypes: true }).filter((e) => e.isDirectory());
|
|
8430
8023
|
for (const entry of entries) {
|
|
8431
|
-
if (
|
|
8024
|
+
if (existsSync8(join(tmpDir, entry.name, "SKILL.md"))) {
|
|
8432
8025
|
skillDir = join(tmpDir, entry.name);
|
|
8433
8026
|
break;
|
|
8434
8027
|
}
|
|
@@ -8790,8 +8383,8 @@ var app20 = new Hono24().use("*", authMiddleware).get("/", async (c) => {
|
|
|
8790
8383
|
});
|
|
8791
8384
|
}, 15e3);
|
|
8792
8385
|
cleanups.push(() => clearInterval(keepAlive));
|
|
8793
|
-
await new Promise((
|
|
8794
|
-
stream.onAbort(() =>
|
|
8386
|
+
await new Promise((resolve19) => {
|
|
8387
|
+
stream.onAbort(() => resolve19());
|
|
8795
8388
|
});
|
|
8796
8389
|
} finally {
|
|
8797
8390
|
for (const cleanup of cleanups) {
|
|
@@ -9072,23 +8665,23 @@ var app21 = new Hono25().use("*", authMiddleware).get("/", async (c) => {
|
|
|
9072
8665
|
var feed_default = app21;
|
|
9073
8666
|
|
|
9074
8667
|
// packages/daemon/src/web/api/variants.ts
|
|
9075
|
-
import { existsSync as
|
|
9076
|
-
import { resolve as
|
|
8668
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync9, writeFileSync as writeFileSync10 } from "fs";
|
|
8669
|
+
import { resolve as resolve16 } from "path";
|
|
9077
8670
|
import { Hono as Hono26 } from "hono";
|
|
9078
8671
|
|
|
9079
8672
|
// packages/daemon/src/lib/mind/farewell.ts
|
|
9080
|
-
import { existsSync as
|
|
9081
|
-
import { resolve as
|
|
8673
|
+
import { existsSync as existsSync9, readFileSync as readFileSync10, rmSync as rmSync6 } from "fs";
|
|
8674
|
+
import { resolve as resolve14 } from "path";
|
|
9082
8675
|
var flog = logger_default.child("farewell");
|
|
9083
8676
|
var FAREWELL_RELPATH = ".mind/farewell.md";
|
|
9084
8677
|
var FAREWELL_MIND_PATH = "../.mind/farewell.md";
|
|
9085
8678
|
var FAREWELL_TIMEOUT_MS = 12e4;
|
|
9086
8679
|
function farewellPath(variantDir) {
|
|
9087
|
-
return
|
|
8680
|
+
return resolve14(variantDir, FAREWELL_RELPATH);
|
|
9088
8681
|
}
|
|
9089
8682
|
function readFarewell(variantDir) {
|
|
9090
8683
|
const path = farewellPath(variantDir);
|
|
9091
|
-
if (!
|
|
8684
|
+
if (!existsSync9(path)) return void 0;
|
|
9092
8685
|
try {
|
|
9093
8686
|
const text = readFileSync10(path, "utf-8").trim();
|
|
9094
8687
|
return text || void 0;
|
|
@@ -9111,7 +8704,7 @@ function waitForFarewell(name, variantDir, timeoutMs) {
|
|
|
9111
8704
|
const unsub = subscribe((event) => {
|
|
9112
8705
|
if (event.mind !== name) return;
|
|
9113
8706
|
if (event.type !== "mind_done" && event.type !== "mind_idle") return;
|
|
9114
|
-
if (
|
|
8707
|
+
if (existsSync9(farewellPath(variantDir))) cleanup();
|
|
9115
8708
|
});
|
|
9116
8709
|
return { done, cancel: cleanup };
|
|
9117
8710
|
}
|
|
@@ -9144,8 +8737,8 @@ async function runFarewellTurn(opts) {
|
|
|
9144
8737
|
|
|
9145
8738
|
// packages/daemon/src/lib/mind/spawn-server.ts
|
|
9146
8739
|
import { spawn as spawn4 } from "child_process";
|
|
9147
|
-
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync11, statSync as
|
|
9148
|
-
import { resolve as
|
|
8740
|
+
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
|
|
8741
|
+
import { resolve as resolve15 } from "path";
|
|
9149
8742
|
async function spawnServer(cwd, port, options) {
|
|
9150
8743
|
let cmd = process.env.VOLUTE_NODE_PATH ?? process.execPath;
|
|
9151
8744
|
let args = ["--import", "tsx", "src/server.ts", "--port", String(port)];
|
|
@@ -9166,34 +8759,34 @@ function spawnAttached(cmd, args, cwd) {
|
|
|
9166
8759
|
cwd,
|
|
9167
8760
|
stdio: ["ignore", "pipe", "pipe"]
|
|
9168
8761
|
});
|
|
9169
|
-
return new Promise((
|
|
9170
|
-
const timeout = setTimeout(() =>
|
|
8762
|
+
return new Promise((resolve19) => {
|
|
8763
|
+
const timeout = setTimeout(() => resolve19(null), 3e4);
|
|
9171
8764
|
function checkOutput(data) {
|
|
9172
8765
|
const match = data.toString().match(/listening on :(\d+)/);
|
|
9173
8766
|
if (match) {
|
|
9174
8767
|
clearTimeout(timeout);
|
|
9175
|
-
|
|
8768
|
+
resolve19({ child, actualPort: parseInt(match[1], 10) });
|
|
9176
8769
|
}
|
|
9177
8770
|
}
|
|
9178
8771
|
child.stdout?.on("data", checkOutput);
|
|
9179
8772
|
child.stderr?.on("data", checkOutput);
|
|
9180
8773
|
child.on("error", () => {
|
|
9181
8774
|
clearTimeout(timeout);
|
|
9182
|
-
|
|
8775
|
+
resolve19(null);
|
|
9183
8776
|
});
|
|
9184
8777
|
child.on("exit", () => {
|
|
9185
8778
|
clearTimeout(timeout);
|
|
9186
|
-
|
|
8779
|
+
resolve19(null);
|
|
9187
8780
|
});
|
|
9188
8781
|
});
|
|
9189
8782
|
}
|
|
9190
8783
|
function spawnDetached(cmd, args, cwd, logDir) {
|
|
9191
|
-
const logsDir = logDir ??
|
|
8784
|
+
const logsDir = logDir ?? resolve15(cwd, ".mind", "logs");
|
|
9192
8785
|
mkdirSync8(logsDir, { recursive: true });
|
|
9193
|
-
const logPath =
|
|
8786
|
+
const logPath = resolve15(logsDir, "mind.log");
|
|
9194
8787
|
let startOffset = 0;
|
|
9195
8788
|
try {
|
|
9196
|
-
startOffset =
|
|
8789
|
+
startOffset = statSync3(logPath).size;
|
|
9197
8790
|
} catch {
|
|
9198
8791
|
}
|
|
9199
8792
|
const logFd = openSync(logPath, "a");
|
|
@@ -9331,11 +8924,11 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9331
8924
|
return c.json({ error: `Name already in use: ${variantName}` }, 409);
|
|
9332
8925
|
}
|
|
9333
8926
|
const projectRoot = entry.dir ?? mindDir(mindName);
|
|
9334
|
-
const variantDir =
|
|
9335
|
-
if (
|
|
8927
|
+
const variantDir = resolve16(projectRoot, ".variants", variantName);
|
|
8928
|
+
if (existsSync10(variantDir)) {
|
|
9336
8929
|
return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
|
|
9337
8930
|
}
|
|
9338
|
-
mkdirSync9(
|
|
8931
|
+
mkdirSync9(resolve16(projectRoot, ".variants"), { recursive: true });
|
|
9339
8932
|
try {
|
|
9340
8933
|
await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
|
|
9341
8934
|
} catch (e) {
|
|
@@ -9371,7 +8964,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9371
8964
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
9372
8965
|
await exec(cmd, args, {
|
|
9373
8966
|
cwd: variantDir,
|
|
9374
|
-
env: { ...process.env, HOME:
|
|
8967
|
+
env: { ...process.env, HOME: resolve16(variantDir, "home") }
|
|
9375
8968
|
});
|
|
9376
8969
|
} else {
|
|
9377
8970
|
await exec("npm", ["install"], { cwd: variantDir });
|
|
@@ -9382,7 +8975,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9382
8975
|
return c.json({ error: `npm install failed: ${msg}` }, 500);
|
|
9383
8976
|
}
|
|
9384
8977
|
if (body.soul) {
|
|
9385
|
-
writeFileSync10(
|
|
8978
|
+
writeFileSync10(resolve16(variantDir, "home/SOUL.md"), body.soul);
|
|
9386
8979
|
}
|
|
9387
8980
|
const variantPort = body.port ?? await nextPort();
|
|
9388
8981
|
try {
|
|
@@ -9465,7 +9058,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9465
9058
|
logger_default.warn(`farewell turn failed for ${variantName}`, logger_default.errorData(err));
|
|
9466
9059
|
}
|
|
9467
9060
|
try {
|
|
9468
|
-
if (
|
|
9061
|
+
if (existsSync10(variantEntry.dir)) {
|
|
9469
9062
|
const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
|
|
9470
9063
|
if (status) {
|
|
9471
9064
|
try {
|
|
@@ -9523,7 +9116,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9523
9116
|
{ conflicts: err.conflicts }
|
|
9524
9117
|
);
|
|
9525
9118
|
}
|
|
9526
|
-
if (
|
|
9119
|
+
if (existsSync10(variantEntry.dir) && !body.discardUnresolved) {
|
|
9527
9120
|
let unresolved;
|
|
9528
9121
|
try {
|
|
9529
9122
|
unresolved = await findUnresolvedHomeFiles(variantEntry.dir);
|
|
@@ -9548,7 +9141,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9548
9141
|
await chownMindDir(projectRoot, mindName);
|
|
9549
9142
|
if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
|
|
9550
9143
|
try {
|
|
9551
|
-
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-
|
|
9144
|
+
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-RJRMF6DT.js");
|
|
9552
9145
|
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-TRC2HJXR.js");
|
|
9553
9146
|
const tmpl = parentEntry.template ?? "claude";
|
|
9554
9147
|
await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
|
|
@@ -9562,7 +9155,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9562
9155
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
9563
9156
|
await exec(cmd, args, {
|
|
9564
9157
|
cwd: projectRoot,
|
|
9565
|
-
env: { ...process.env, HOME:
|
|
9158
|
+
env: { ...process.env, HOME: resolve16(projectRoot, "home") }
|
|
9566
9159
|
});
|
|
9567
9160
|
} else {
|
|
9568
9161
|
await exec("npm", ["install"], { cwd: projectRoot });
|
|
@@ -10057,11 +9650,11 @@ var app24 = new Hono28().get("/:name/conversations/:id/events", async (c) => {
|
|
|
10057
9650
|
if (!stream.aborted) console.error("[chat] SSE ping error:", err);
|
|
10058
9651
|
});
|
|
10059
9652
|
}, 15e3);
|
|
10060
|
-
await new Promise((
|
|
9653
|
+
await new Promise((resolve19) => {
|
|
10061
9654
|
stream.onAbort(() => {
|
|
10062
9655
|
unsubscribe();
|
|
10063
9656
|
clearInterval(keepAlive);
|
|
10064
|
-
|
|
9657
|
+
resolve19();
|
|
10065
9658
|
});
|
|
10066
9659
|
});
|
|
10067
9660
|
});
|
|
@@ -10245,6 +9838,7 @@ app26.get("/api/health", (c) => {
|
|
|
10245
9838
|
...cached?.updateAvailable ? { updateAvailable: true, latest: cached.latest } : {}
|
|
10246
9839
|
});
|
|
10247
9840
|
});
|
|
9841
|
+
app26.use("/api/ext/*", normalizeTrailingSlash(app26));
|
|
10248
9842
|
app26.use("/api/activity/*", authMiddleware);
|
|
10249
9843
|
app26.use("/api/minds/*", authMiddleware);
|
|
10250
9844
|
app26.use("/api/conversations/*", authMiddleware);
|
|
@@ -10278,10 +9872,10 @@ app26.route("/api/conversations", conversations_default);
|
|
|
10278
9872
|
var app_default = app26;
|
|
10279
9873
|
|
|
10280
9874
|
// packages/daemon/src/web/server.ts
|
|
10281
|
-
import { existsSync as
|
|
9875
|
+
import { existsSync as existsSync11 } from "fs";
|
|
10282
9876
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
10283
9877
|
import { createServer as createHttpsServer } from "https";
|
|
10284
|
-
import { dirname as dirname3, extname as extname3, resolve as
|
|
9878
|
+
import { dirname as dirname3, extname as extname3, resolve as resolve17 } from "path";
|
|
10285
9879
|
import { serve } from "@hono/node-server";
|
|
10286
9880
|
var MIME_TYPES2 = {
|
|
10287
9881
|
".html": "text/html",
|
|
@@ -10300,8 +9894,8 @@ async function startServer({
|
|
|
10300
9894
|
let assetsDir = "";
|
|
10301
9895
|
let searchDir = dirname3(new URL(import.meta.url).pathname);
|
|
10302
9896
|
for (let i = 0; i < 5; i++) {
|
|
10303
|
-
const candidate =
|
|
10304
|
-
if (
|
|
9897
|
+
const candidate = resolve17(searchDir, "dist", "web-assets");
|
|
9898
|
+
if (existsSync11(candidate)) {
|
|
10305
9899
|
assetsDir = candidate;
|
|
10306
9900
|
break;
|
|
10307
9901
|
}
|
|
@@ -10311,7 +9905,7 @@ async function startServer({
|
|
|
10311
9905
|
app_default.get("*", async (c) => {
|
|
10312
9906
|
const urlPath = new URL(c.req.url).pathname;
|
|
10313
9907
|
if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
|
|
10314
|
-
const filePath =
|
|
9908
|
+
const filePath = resolve17(assetsDir, urlPath.slice(1));
|
|
10315
9909
|
if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
|
|
10316
9910
|
const s = await stat2(filePath).catch(() => null);
|
|
10317
9911
|
if (s?.isFile()) {
|
|
@@ -10324,7 +9918,7 @@ async function startServer({
|
|
|
10324
9918
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
10325
9919
|
return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
|
|
10326
9920
|
}
|
|
10327
|
-
const indexPath =
|
|
9921
|
+
const indexPath = resolve17(assetsDir, "index.html");
|
|
10328
9922
|
const indexStat = await stat2(indexPath).catch(() => null);
|
|
10329
9923
|
if (indexStat?.isFile()) {
|
|
10330
9924
|
const body = await readFile2(indexPath, "utf-8");
|
|
@@ -10341,10 +9935,10 @@ async function startServer({
|
|
|
10341
9935
|
createServer: createHttpsServer,
|
|
10342
9936
|
serverOptions: { key: tls.key, cert: tls.cert }
|
|
10343
9937
|
});
|
|
10344
|
-
await new Promise((
|
|
9938
|
+
await new Promise((resolve19, reject) => {
|
|
10345
9939
|
server2.on("listening", () => {
|
|
10346
9940
|
logger_default.info("Volute UI running (https)", { hostname, port });
|
|
10347
|
-
|
|
9941
|
+
resolve19();
|
|
10348
9942
|
});
|
|
10349
9943
|
server2.on("error", (err) => {
|
|
10350
9944
|
reject(err);
|
|
@@ -10352,13 +9946,13 @@ async function startServer({
|
|
|
10352
9946
|
});
|
|
10353
9947
|
const internalPort = port + 1;
|
|
10354
9948
|
const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
|
|
10355
|
-
await new Promise((
|
|
9949
|
+
await new Promise((resolve19, reject) => {
|
|
10356
9950
|
internalServer.on("listening", () => {
|
|
10357
9951
|
logger_default.info("Volute API running (http, internal)", {
|
|
10358
9952
|
hostname: "127.0.0.1",
|
|
10359
9953
|
port: internalPort
|
|
10360
9954
|
});
|
|
10361
|
-
|
|
9955
|
+
resolve19();
|
|
10362
9956
|
});
|
|
10363
9957
|
internalServer.on("error", (err) => {
|
|
10364
9958
|
reject(err);
|
|
@@ -10367,10 +9961,10 @@ async function startServer({
|
|
|
10367
9961
|
return { server: server2, internalPort };
|
|
10368
9962
|
}
|
|
10369
9963
|
const server = serve({ fetch: app_default.fetch, port, hostname });
|
|
10370
|
-
await new Promise((
|
|
9964
|
+
await new Promise((resolve19, reject) => {
|
|
10371
9965
|
server.on("listening", () => {
|
|
10372
9966
|
logger_default.info("Volute API running (http)", { hostname, port });
|
|
10373
|
-
|
|
9967
|
+
resolve19();
|
|
10374
9968
|
});
|
|
10375
9969
|
server.on("error", (err) => {
|
|
10376
9970
|
reject(err);
|
|
@@ -10381,17 +9975,17 @@ async function startServer({
|
|
|
10381
9975
|
|
|
10382
9976
|
// packages/daemon/src/daemon.ts
|
|
10383
9977
|
if (!process.env.VOLUTE_HOME) {
|
|
10384
|
-
process.env.VOLUTE_HOME =
|
|
9978
|
+
process.env.VOLUTE_HOME = resolve18(homedir3(), ".volute");
|
|
10385
9979
|
}
|
|
10386
9980
|
if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
|
|
10387
9981
|
process.env.TZ = process.env.VOLUTE_TIMEZONE;
|
|
10388
9982
|
}
|
|
10389
9983
|
function writeDaemonConfig(systemDir, config2, token) {
|
|
10390
|
-
const configPath =
|
|
9984
|
+
const configPath = resolve18(systemDir, "daemon.json");
|
|
10391
9985
|
writeFileSync11(configPath, `${JSON.stringify(config2, null, 2)}
|
|
10392
9986
|
`, { mode: 420 });
|
|
10393
9987
|
chmodSync(configPath, 420);
|
|
10394
|
-
const tokenPath =
|
|
9988
|
+
const tokenPath = resolve18(systemDir, "daemon-token");
|
|
10395
9989
|
writeFileSync11(tokenPath, `${token}
|
|
10396
9990
|
`, { mode: 384 });
|
|
10397
9991
|
chmodSync(tokenPath, 384);
|
|
@@ -10402,7 +9996,7 @@ async function startDaemon(opts) {
|
|
|
10402
9996
|
const home = voluteHome();
|
|
10403
9997
|
const systemDir = voluteSystemDir();
|
|
10404
9998
|
if (!opts.foreground) {
|
|
10405
|
-
const rotatingLog = new RotatingLog(
|
|
9999
|
+
const rotatingLog = new RotatingLog(resolve18(systemDir, "daemon.log"));
|
|
10406
10000
|
logger_default.setOutput((line) => rotatingLog.write(`${line}
|
|
10407
10001
|
`));
|
|
10408
10002
|
const write = (...args) => rotatingLog.write(`${format(...args)}
|
|
@@ -10412,15 +10006,15 @@ async function startDaemon(opts) {
|
|
|
10412
10006
|
console.warn = write;
|
|
10413
10007
|
console.info = write;
|
|
10414
10008
|
}
|
|
10415
|
-
const DAEMON_PID_PATH =
|
|
10416
|
-
const DAEMON_JSON_PATH =
|
|
10417
|
-
const DAEMON_TOKEN_PATH =
|
|
10009
|
+
const DAEMON_PID_PATH = resolve18(systemDir, "daemon.pid");
|
|
10010
|
+
const DAEMON_JSON_PATH = resolve18(systemDir, "daemon.json");
|
|
10011
|
+
const DAEMON_TOKEN_PATH = resolve18(systemDir, "daemon-token");
|
|
10418
10012
|
mkdirSync10(home, { recursive: true });
|
|
10419
10013
|
ensureSystemDir();
|
|
10420
10014
|
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-WZSXHHRJ.js");
|
|
10421
10015
|
migrateConfigSecrets();
|
|
10422
10016
|
migrateSetupCompleted();
|
|
10423
|
-
const { migrateAiModelQualification } = await import("./ai-service-
|
|
10017
|
+
const { migrateAiModelQualification } = await import("./ai-service-KEK2V3AP.js");
|
|
10424
10018
|
migrateAiModelQualification();
|
|
10425
10019
|
await (await import("./db-BONH4SUG.js")).getDb();
|
|
10426
10020
|
try {
|
|
@@ -10432,18 +10026,30 @@ async function startDaemon(opts) {
|
|
|
10432
10026
|
logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
|
|
10433
10027
|
}
|
|
10434
10028
|
try {
|
|
10435
|
-
const { migrateAvatarSizes } = await import("./avatar-image-
|
|
10029
|
+
const { migrateAvatarSizes } = await import("./avatar-image-SN576P45.js");
|
|
10436
10030
|
await migrateAvatarSizes();
|
|
10437
10031
|
} catch (err) {
|
|
10438
10032
|
logger_default.warn("avatar size migration failed", logger_default.errorData(err));
|
|
10439
10033
|
}
|
|
10440
10034
|
try {
|
|
10441
|
-
const { migrateThreadConfigs } = await import("./migrate-thread-config-
|
|
10035
|
+
const { migrateThreadConfigs } = await import("./migrate-thread-config-SVF2M3D3.js");
|
|
10442
10036
|
await migrateThreadConfigs();
|
|
10443
10037
|
} catch (err) {
|
|
10444
10038
|
logger_default.warn("session\u2192thread config migration failed", logger_default.errorData(err));
|
|
10445
10039
|
}
|
|
10446
|
-
|
|
10040
|
+
try {
|
|
10041
|
+
const { migrateNamePlaceholders } = await import("./migrate-name-placeholder-64AEAWPE.js");
|
|
10042
|
+
await migrateNamePlaceholders();
|
|
10043
|
+
} catch (err) {
|
|
10044
|
+
logger_default.warn("{{name}} placeholder migration failed", logger_default.errorData(err));
|
|
10045
|
+
}
|
|
10046
|
+
try {
|
|
10047
|
+
const { migrateInitInfrastructure } = await import("./migrate-init-infrastructure-Z72UJ5NT.js");
|
|
10048
|
+
await migrateInitInfrastructure();
|
|
10049
|
+
} catch (err) {
|
|
10050
|
+
logger_default.warn("`.init/` infrastructure backfill failed", logger_default.errorData(err));
|
|
10051
|
+
}
|
|
10052
|
+
const { initSandbox } = await import("./sandbox-VI7XWBIA.js");
|
|
10447
10053
|
await initSandbox();
|
|
10448
10054
|
try {
|
|
10449
10055
|
await syncBuiltinSkills();
|
|
@@ -10475,7 +10081,7 @@ async function startDaemon(opts) {
|
|
|
10475
10081
|
logger_default.warn("failed to backfill minds into #system", logger_default.errorData(err));
|
|
10476
10082
|
}
|
|
10477
10083
|
try {
|
|
10478
|
-
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-
|
|
10084
|
+
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-Y27LTNZK.js");
|
|
10479
10085
|
await getOrCreateSystemUser2();
|
|
10480
10086
|
} catch (err) {
|
|
10481
10087
|
logger_default.warn(
|
|
@@ -10489,7 +10095,7 @@ async function startDaemon(opts) {
|
|
|
10489
10095
|
let tls;
|
|
10490
10096
|
if (opts.tailscale || globalCfg.tailscale) {
|
|
10491
10097
|
try {
|
|
10492
|
-
const { getTailscaleTls } = await import("./tailscale-
|
|
10098
|
+
const { getTailscaleTls } = await import("./tailscale-F2IMBILZ.js");
|
|
10493
10099
|
const tlsConfig = await getTailscaleTls();
|
|
10494
10100
|
tls = { key: tlsConfig.key, cert: tlsConfig.cert };
|
|
10495
10101
|
logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
|
|
@@ -10543,7 +10149,7 @@ async function startDaemon(opts) {
|
|
|
10543
10149
|
const orphanedTurns = await completeOrphanedTurns();
|
|
10544
10150
|
summarizeOrphanedTurns(orphanedTurns);
|
|
10545
10151
|
try {
|
|
10546
|
-
const { reconcileVariants } = await import("./variant-cleanup-
|
|
10152
|
+
const { reconcileVariants } = await import("./variant-cleanup-JGJZ5KB4.js");
|
|
10547
10153
|
await reconcileVariants();
|
|
10548
10154
|
} catch (err) {
|
|
10549
10155
|
logger_default.error("failed to reconcile variants", logger_default.errorData(err));
|
|
@@ -10579,16 +10185,17 @@ async function startDaemon(opts) {
|
|
|
10579
10185
|
try {
|
|
10580
10186
|
const { isSetupComplete: isSetupComplete2, getSpiritName: getSpiritName2 } = await import("./setup-WZSXHHRJ.js");
|
|
10581
10187
|
if (isSetupComplete2()) {
|
|
10582
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
10583
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
10188
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-FKXMGO3N.js");
|
|
10189
|
+
const { startSpiritFull } = await import("./mind-service-ZJCUBAUL.js");
|
|
10584
10190
|
await ensureSpiritProject();
|
|
10585
10191
|
const spiritName = getSpiritName2();
|
|
10586
10192
|
const spiritEntry = await findMind(spiritName);
|
|
10587
10193
|
if (spiritEntry?.dir) {
|
|
10588
|
-
const { registerMindDir } = await import("./delivery-router-
|
|
10194
|
+
const { registerMindDir } = await import("./delivery-router-KHBVEVVL.js");
|
|
10589
10195
|
registerMindDir(spiritName, spiritEntry.dir);
|
|
10590
10196
|
}
|
|
10591
10197
|
await syncSpiritTemplate();
|
|
10198
|
+
if (spiritEntry) await notifyExtensionsSpiritReady();
|
|
10592
10199
|
if (spiritEntry && !manager.isRunning(spiritName)) {
|
|
10593
10200
|
await startSpiritFull(spiritName);
|
|
10594
10201
|
}
|
|
@@ -10599,7 +10206,7 @@ async function startDaemon(opts) {
|
|
|
10599
10206
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
10600
10207
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
10601
10208
|
});
|
|
10602
|
-
import("./cloud-sync-
|
|
10209
|
+
import("./cloud-sync-FM73SVFJ.js").then(
|
|
10603
10210
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
10604
10211
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
10605
10212
|
})
|
|
@@ -10607,12 +10214,14 @@ async function startDaemon(opts) {
|
|
|
10607
10214
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
10608
10215
|
});
|
|
10609
10216
|
try {
|
|
10610
|
-
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-
|
|
10611
|
-
backfillTemplateHashes().then(() => warnStaleTemplates()).catch((err) => {
|
|
10612
|
-
logger_default.warn("failed to check template staleness", logger_default.errorData(err));
|
|
10613
|
-
});
|
|
10217
|
+
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-KIXYNHJC.js");
|
|
10614
10218
|
notifyVersionUpdate().catch((err) => {
|
|
10615
10219
|
logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
|
|
10220
|
+
}).then(() => backfillTemplateHashes()).then(() => warnStaleTemplates()).then(async () => {
|
|
10221
|
+
const { runAutoUpgrades } = await import("./auto-upgrade-2MZF7NG3.js");
|
|
10222
|
+
await runAutoUpgrades();
|
|
10223
|
+
}).catch((err) => {
|
|
10224
|
+
logger_default.warn("template staleness/auto-upgrade pass failed", logger_default.errorData(err));
|
|
10616
10225
|
});
|
|
10617
10226
|
} catch (err) {
|
|
10618
10227
|
logger_default.warn("failed to initialize version notifications", logger_default.errorData(err));
|
|
@@ -10621,6 +10230,9 @@ async function startDaemon(opts) {
|
|
|
10621
10230
|
logger_default.warn("failed to restore delivery queue", logger_default.errorData(err));
|
|
10622
10231
|
});
|
|
10623
10232
|
delivery.startRedrive();
|
|
10233
|
+
delivery.releaseGatedSweep().catch((err) => {
|
|
10234
|
+
logger_default.warn("failed to sweep gated messages", logger_default.errorData(err));
|
|
10235
|
+
});
|
|
10624
10236
|
cleanExpiredSessions().catch((err) => {
|
|
10625
10237
|
logger_default.warn("failed to clean expired sessions", logger_default.errorData(err));
|
|
10626
10238
|
});
|