volute 0.53.0 → 0.54.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/auto-upgrade-HEVZKPTF.js +46 -0
- package/dist/{backup-WWXVIMYQ.js → backup-QRNX6RK7.js} +11 -11
- package/dist/channels-CKCY64TD.js +203 -0
- package/dist/{chat-WK2BLM7B.js → chat-ZUGNL5GS.js} +9 -9
- package/dist/{chunk-UTKUO2KY.js → chunk-3LHUXY3E.js} +2 -2
- package/dist/{chunk-PIZDPY4G.js → chunk-444RR3YF.js} +4 -4
- package/dist/{chunk-VDZ4I4ZP.js → chunk-56IT2ZXF.js} +3 -3
- package/dist/{chunk-OXWUEU5V.js → chunk-5U5GLZSD.js} +2 -2
- package/dist/{chunk-LN7XJ56R.js → chunk-7XKPG66D.js} +9 -9
- package/dist/{chunk-R772ET2M.js → chunk-AAPNU7GA.js} +4 -0
- package/dist/{chunk-7ARONCZW.js → chunk-ATZF2RNJ.js} +3 -3
- package/dist/{chunk-6NLW72HP.js → chunk-CKPAVQNK.js} +1 -1
- package/dist/{chunk-RMADJFA7.js → chunk-CLCHOXLR.js} +1 -1
- package/dist/{chunk-IQ7VNWH6.js → chunk-HKGYZVWN.js} +1 -1
- package/dist/{chunk-HASADR3E.js → chunk-LGXVGIWN.js} +66 -25
- package/dist/{chunk-P2TBUKLW.js → chunk-LKUGUQUW.js} +3 -3
- package/dist/{chunk-AP2KQMMW.js → chunk-OAYY3WF3.js} +11 -3
- package/dist/{chunk-UO4MZQNO.js → chunk-OGPVJ53N.js} +14 -6
- package/dist/{chunk-M77B73VV.js → chunk-OIOW3FPT.js} +7 -2
- package/dist/chunk-OT5SXF7L.js +904 -0
- package/dist/{chunk-EDR47UE2.js → chunk-OYF25B62.js} +1 -1
- package/dist/{chunk-TAWRJ24T.js → chunk-PPSN2MLC.js} +2 -2
- package/dist/{chunk-5DBGQBQR.js → chunk-RGHF3OK5.js} +21 -10
- package/dist/{chunk-RQRO6PC7.js → chunk-VDUCLVZI.js} +305 -31
- package/dist/{chunk-23UJGVYP.js → chunk-WHL6PKYP.js} +10 -10
- package/dist/{chunk-HTB7KDRU.js → chunk-WZZCA23D.js} +5 -4
- package/dist/{chunk-UDZLPR34.js → chunk-YSRYCS3N.js} +13 -8
- package/dist/{chunk-5N32EN4O.js → chunk-Z4Q6TQWL.js} +1 -1
- package/dist/{chunk-BDHKCLWK.js → chunk-ZNHL5KQJ.js} +1 -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-52YNJRMR.js} +11 -11
- package/dist/{daemon-restart-BIGU4OKS.js → daemon-restart-QWHN5VMU.js} +4 -4
- package/dist/daemon.js +330 -746
- package/dist/{db-IPXRJUI7.js → db-I4EH5SLF.js} +3 -1
- package/dist/{delivery-manager-FDHCZ7PU.js → delivery-manager-7R2YIQ2W.js} +11 -7
- package/dist/{delivery-notices-65TB3CBX.js → delivery-notices-RZQ6GONP.js} +3 -3
- package/dist/{delivery-router-RHANNTAC.js → delivery-router-QS4NLJR6.js} +3 -1
- package/dist/{down-QSNEMTTX.js → down-UN2EDX2Y.js} +3 -3
- package/dist/{echo-text-KU6G4Z7V.js → echo-text-73CYQRL7.js} +14 -14
- package/dist/{exec-ABD3DYA2.js → exec-Z34TTUO3.js} +1 -1
- package/dist/{extensions-VACUKFA5.js → extensions-QT65JGV6.js} +21 -11
- package/dist/{isolation-GVV2IBAU.js → isolation-UQPDO34R.js} +1 -1
- package/dist/{message-delivery-TUXM3AAE.js → message-delivery-TRKT4T2P.js} +11 -11
- package/dist/migrate-name-placeholder-C7NCNLWF.js +37 -0
- package/dist/{mind-IX5AWUST.js → mind-CT6ANXK4.js} +12 -12
- 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-WHFBUKZE.js → mind-service-7EFIJ3ZA.js} +11 -11
- 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-F6S5NHY2.js} +4 -4
- package/dist/{prompts-HNKGCAEY.js → prompts-JECJIFPQ.js} +1 -1
- package/dist/{scheduler-5X5UIQOQ.js → scheduler-73Q4MQ7Y.js} +6 -6
- package/dist/{seed-LHZ33UB4.js → seed-DRKAP3XV.js} +1 -1
- package/dist/{seed-cmd-U4RVJ3UA.js → seed-cmd-6IMTO3LG.js} +2 -2
- package/dist/{seed-create-OQU4KNCB.js → seed-create-VNLDYRFK.js} +1 -1
- package/dist/{seed-readiness-WJYYRRCK.js → seed-readiness-H5TTPAQH.js} +2 -2
- package/dist/{seed-sprout-SFUYH2RG.js → seed-sprout-PPGYGK4G.js} +8 -8
- package/dist/{send-FWZAMDBN.js → send-UXUQKO4N.js} +9 -9
- 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-YUAQMDVZ.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/references/integrations.md +3 -2
- package/dist/skills/volute-mind/references/routing.md +18 -5
- package/dist/{skills-QRPU6BWY.js → skills-GMQ5UIIW.js} +2 -2
- package/dist/{sleep-manager-NWUCRBZB.js → sleep-manager-KHI65FEX.js} +11 -11
- package/dist/{spirit-I5ECLGRI.js → spirit-Q5VGFWUI.js} +5 -3
- package/dist/{spirit-availability-NIUUYKU2.js → spirit-availability-G5FMWKRH.js} +12 -12
- package/dist/{sprout-A2PMEF7Z.js → sprout-PMTRL7QN.js} +1 -1
- package/dist/{src-LCSOQY6Z.js → src-3FIW7DLH.js} +241 -87
- package/dist/src-H3UCOP6B.js +516 -0
- package/dist/{src-HGNE2XG4.js → src-LTTQVN2Z.js} +1 -1
- package/dist/{status-EYG4A3OK.js → status-LCKTTIWS.js} +5 -5
- package/dist/{system-events-YTOU66QI.js → system-events-Q7IVZ5T4.js} +1 -1
- package/dist/{systems-2DIJY4RF.js → systems-HL7SGSW7.js} +6 -6
- package/dist/{turn-tracker-NNHS6MAR.js → turn-tracker-HZDPMSCC.js} +2 -2
- package/dist/{up-UGBHH743.js → up-XZDSJVMU.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-CZDLIY3F.js → variant-cleanup-QHGGY7ND.js} +6 -6
- package/dist/{version-notify-SJVAQLZI.js → version-notify-VNVFX6UP.js} +19 -4
- package/dist/web-assets/assets/{index-b7G7ZsVk.js → index-CwtxGwe_.js} +16 -16
- package/dist/web-assets/assets/index-DhM1yYRN.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +4 -4
- package/packages/extensions/intentions/dist/ui/assets/index-3FneLCKR.css +1 -0
- package/packages/extensions/intentions/dist/ui/assets/index-CQz4aceM.js +67 -0
- package/packages/extensions/{plan → 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/skills/commons-gardening/SKILL.md +50 -0
- package/packages/extensions/pages/skills/pages/SKILL.md +18 -13
- package/templates/_base/.init/.config/prompts.json +2 -2
- package/templates/{pi → _base}/.init/.config/routes.json +1 -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/context-breakdown.ts +11 -3
- package/templates/_base/src/lib/routing.ts +2 -2
- package/templates/_base/src/lib/startup.ts +4 -2
- package/templates/claude/.init/CLAUDE.md +4 -0
- package/templates/claude/src/agent.ts +28 -12
- 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/volute-template.json +1 -1
- package/templates/codex/.init/AGENTS.md +4 -0
- package/templates/codex/volute-template.json +1 -1
- package/templates/pi/.init/MINDS.md +4 -0
- package/templates/pi/src/lib/mechanics-doc.ts +30 -0
- package/templates/pi/src/server.ts +3 -1
- package/templates/pi/volute-template.json +1 -1
- package/dist/channels-LW5ZLMSQ.js +0 -90
- package/dist/skills/plan-coordinator/SKILL.md +0 -60
- package/dist/src-UDMJZ6MH.js +0 -426
- package/dist/web-assets/assets/index-BHSU9r-4.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/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/{files-CHPNEQXN.js → files-PCKBQHAY.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-OYF25B62.js";
|
|
10
10
|
import {
|
|
11
11
|
acceptPending,
|
|
12
12
|
formatFileSize,
|
|
@@ -15,15 +15,15 @@ import {
|
|
|
15
15
|
stageFile,
|
|
16
16
|
validateFilePath
|
|
17
17
|
} from "./chunk-F6D766VQ.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
26
|
} from "./chunk-I7U5EEZC.js";
|
|
24
|
-
import {
|
|
25
|
-
getMemoryStatus
|
|
26
|
-
} from "./chunk-5RBEEAKW.js";
|
|
27
27
|
import {
|
|
28
28
|
checkForUpdate,
|
|
29
29
|
checkForUpdateCached,
|
|
@@ -32,13 +32,25 @@ import {
|
|
|
32
32
|
import {
|
|
33
33
|
SPIRIT_NOTICE_PREFIX,
|
|
34
34
|
ensureSpiritAvailable
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-LKUGUQUW.js";
|
|
36
36
|
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
TEMPLATE_BRANCH,
|
|
38
|
+
UpgradeInProgressError,
|
|
39
|
+
VariantMergeError,
|
|
40
|
+
abortUpgrade,
|
|
41
|
+
configureGitIdentity,
|
|
42
|
+
continueUpgrade,
|
|
43
|
+
findUnresolvedHomeFiles,
|
|
44
|
+
formatUnresolvedHomeFilesMessage,
|
|
45
|
+
getUpgradeBlocked,
|
|
46
|
+
mergeVariantExcludingMemory,
|
|
47
|
+
npmInstallAsMind,
|
|
48
|
+
npmInstallNeeded,
|
|
49
|
+
runUpgrade,
|
|
50
|
+
upgradeDiff,
|
|
51
|
+
upgradeInProgress,
|
|
52
|
+
validateBranchName
|
|
53
|
+
} from "./chunk-OT5SXF7L.js";
|
|
42
54
|
import {
|
|
43
55
|
isTemplateStale
|
|
44
56
|
} from "./chunk-CV6BNGFK.js";
|
|
@@ -47,14 +59,20 @@ import {
|
|
|
47
59
|
} from "./chunk-HTRSSOHY.js";
|
|
48
60
|
import {
|
|
49
61
|
cleanupVariant
|
|
50
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-OGPVJ53N.js";
|
|
63
|
+
import {
|
|
64
|
+
isHomeOnlyArchive
|
|
65
|
+
} from "./chunk-FLIEXG2T.js";
|
|
66
|
+
import {
|
|
67
|
+
evaluateSeedChecklist
|
|
68
|
+
} from "./chunk-CLCHOXLR.js";
|
|
51
69
|
import {
|
|
52
70
|
PLATFORMS,
|
|
53
71
|
echoTextToChannel,
|
|
54
72
|
fixModelEscapes,
|
|
55
73
|
getPlatformDriver,
|
|
56
74
|
routeOutboundBridge
|
|
57
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-ATZF2RNJ.js";
|
|
58
76
|
import {
|
|
59
77
|
getBridgeConfig,
|
|
60
78
|
readBridgesConfig,
|
|
@@ -97,6 +115,7 @@ import {
|
|
|
97
115
|
loadAllExtensions,
|
|
98
116
|
notifyExtensionsDaemonStart,
|
|
99
117
|
notifyExtensionsDaemonStop,
|
|
118
|
+
notifyExtensionsSpiritReady,
|
|
100
119
|
readSystemsConfig,
|
|
101
120
|
recordOutbound,
|
|
102
121
|
requireAdmin,
|
|
@@ -109,11 +128,10 @@ import {
|
|
|
109
128
|
uninstallNpmExtension,
|
|
110
129
|
willGateMessage,
|
|
111
130
|
writeSystemsConfig
|
|
112
|
-
} from "./chunk-
|
|
113
|
-
import "./chunk-
|
|
131
|
+
} from "./chunk-LGXVGIWN.js";
|
|
132
|
+
import "./chunk-RGHF3OK5.js";
|
|
114
133
|
import {
|
|
115
134
|
applyInitFiles,
|
|
116
|
-
applyTemplateHomeFiles,
|
|
117
135
|
composeTemplate,
|
|
118
136
|
copyTemplateToDir,
|
|
119
137
|
findTemplatesRoot,
|
|
@@ -123,11 +141,12 @@ import {
|
|
|
123
141
|
import {
|
|
124
142
|
getScheduler,
|
|
125
143
|
initScheduler
|
|
126
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-444RR3YF.js";
|
|
127
145
|
import {
|
|
128
146
|
recordDeliveryFailure
|
|
129
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-3LHUXY3E.js";
|
|
130
148
|
import {
|
|
149
|
+
UnknownChannelError,
|
|
131
150
|
checkStaleSend,
|
|
132
151
|
formatHoldNotice,
|
|
133
152
|
getDeliveryManager,
|
|
@@ -135,7 +154,7 @@ import {
|
|
|
135
154
|
initDeliveryManager,
|
|
136
155
|
isConversationId,
|
|
137
156
|
publishTypingForChannels
|
|
138
|
-
} from "./chunk-
|
|
157
|
+
} from "./chunk-VDUCLVZI.js";
|
|
139
158
|
import {
|
|
140
159
|
MindStartupError,
|
|
141
160
|
RestartTracker,
|
|
@@ -145,10 +164,10 @@ import {
|
|
|
145
164
|
initMindManager,
|
|
146
165
|
syncProviderToMinds,
|
|
147
166
|
tryGetMindManager
|
|
148
|
-
} from "./chunk-
|
|
167
|
+
} from "./chunk-WHL6PKYP.js";
|
|
149
168
|
import {
|
|
150
169
|
extractTextContent
|
|
151
|
-
} from "./chunk-
|
|
170
|
+
} from "./chunk-YSRYCS3N.js";
|
|
152
171
|
import {
|
|
153
172
|
SYSTEM_MIND,
|
|
154
173
|
assignSession,
|
|
@@ -170,7 +189,7 @@ import {
|
|
|
170
189
|
takeErrored,
|
|
171
190
|
trackToolUse,
|
|
172
191
|
utcDateTimeStr
|
|
173
|
-
} from "./chunk-
|
|
192
|
+
} from "./chunk-56IT2ZXF.js";
|
|
174
193
|
import {
|
|
175
194
|
SEED_SKILLS,
|
|
176
195
|
STANDARD_SKILLS,
|
|
@@ -184,7 +203,6 @@ import {
|
|
|
184
203
|
listFilesRecursive,
|
|
185
204
|
listMindSkills,
|
|
186
205
|
listSharedSkills,
|
|
187
|
-
migrateSkillsToTemplate,
|
|
188
206
|
mindSkillsDir,
|
|
189
207
|
publishSkill,
|
|
190
208
|
removeSharedSkill,
|
|
@@ -192,7 +210,7 @@ import {
|
|
|
192
210
|
syncBuiltinSkills,
|
|
193
211
|
uninstallSkill,
|
|
194
212
|
updateSkill
|
|
195
|
-
} from "./chunk-
|
|
213
|
+
} from "./chunk-PPSN2MLC.js";
|
|
196
214
|
import {
|
|
197
215
|
approveUser,
|
|
198
216
|
changePassword,
|
|
@@ -229,7 +247,7 @@ import {
|
|
|
229
247
|
listEvents,
|
|
230
248
|
parseMeta,
|
|
231
249
|
recordNotice
|
|
232
|
-
} from "./chunk-
|
|
250
|
+
} from "./chunk-HKGYZVWN.js";
|
|
233
251
|
import {
|
|
234
252
|
publish as publish2,
|
|
235
253
|
subscribe as subscribe2,
|
|
@@ -242,7 +260,7 @@ import {
|
|
|
242
260
|
getPrompt,
|
|
243
261
|
getPromptIfCustom,
|
|
244
262
|
substitute
|
|
245
|
-
} from "./chunk-
|
|
263
|
+
} from "./chunk-OAYY3WF3.js";
|
|
246
264
|
import {
|
|
247
265
|
isSandboxEnabled,
|
|
248
266
|
wrapForSandbox
|
|
@@ -305,7 +323,7 @@ import {
|
|
|
305
323
|
readVoluteConfig,
|
|
306
324
|
writeVoluteConfig
|
|
307
325
|
} from "./chunk-WCFSBH33.js";
|
|
308
|
-
import "./chunk-
|
|
326
|
+
import "./chunk-CKPAVQNK.js";
|
|
309
327
|
import {
|
|
310
328
|
chownMindDir,
|
|
311
329
|
chownMindFile,
|
|
@@ -317,7 +335,7 @@ import {
|
|
|
317
335
|
isIsolationEnabled,
|
|
318
336
|
resolveVoluteBin,
|
|
319
337
|
wrapForIsolation
|
|
320
|
-
} from "./chunk-
|
|
338
|
+
} from "./chunk-OIOW3FPT.js";
|
|
321
339
|
import {
|
|
322
340
|
loadMergedEnv,
|
|
323
341
|
mindEnvPath,
|
|
@@ -382,7 +400,6 @@ import {
|
|
|
382
400
|
resolveMindDir,
|
|
383
401
|
setMindRunning,
|
|
384
402
|
setMindStage,
|
|
385
|
-
setMindTemplate,
|
|
386
403
|
setMindTemplateHash,
|
|
387
404
|
stateDir,
|
|
388
405
|
validateMindName,
|
|
@@ -409,7 +426,7 @@ import "./chunk-K3NQKI34.js";
|
|
|
409
426
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
410
427
|
import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync12, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "fs";
|
|
411
428
|
import { homedir as homedir3 } from "os";
|
|
412
|
-
import { resolve as
|
|
429
|
+
import { resolve as resolve18 } from "path";
|
|
413
430
|
import { format } from "util";
|
|
414
431
|
|
|
415
432
|
// packages/daemon/src/lib/daemon/backup-manager.ts
|
|
@@ -520,7 +537,7 @@ var BackupManager = class {
|
|
|
520
537
|
} catch (pubErr) {
|
|
521
538
|
blog.error("failed to publish backup-failure activity", logger_default.errorData(pubErr));
|
|
522
539
|
}
|
|
523
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
540
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-Q7IVZ5T4.js");
|
|
524
541
|
await deliverEvent2(getSpiritName(), {
|
|
525
542
|
type: "notice",
|
|
526
543
|
meta: { subtype: "backup" },
|
|
@@ -744,8 +761,8 @@ var BridgeManager = class {
|
|
|
744
761
|
if (!tracked) return;
|
|
745
762
|
this.stopping.add(platform);
|
|
746
763
|
this.bridges.delete(platform);
|
|
747
|
-
await new Promise((
|
|
748
|
-
tracked.child.on("exit", () =>
|
|
764
|
+
await new Promise((resolve19) => {
|
|
765
|
+
tracked.child.on("exit", () => resolve19());
|
|
749
766
|
try {
|
|
750
767
|
if (tracked.child.pid) {
|
|
751
768
|
process.kill(-tracked.child.pid, "SIGTERM");
|
|
@@ -756,7 +773,7 @@ var BridgeManager = class {
|
|
|
756
773
|
if (err instanceof Error && err.code !== "ESRCH") {
|
|
757
774
|
blog2.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
|
|
758
775
|
}
|
|
759
|
-
|
|
776
|
+
resolve19();
|
|
760
777
|
}
|
|
761
778
|
setTimeout(() => {
|
|
762
779
|
try {
|
|
@@ -767,7 +784,7 @@ var BridgeManager = class {
|
|
|
767
784
|
}
|
|
768
785
|
} catch {
|
|
769
786
|
}
|
|
770
|
-
|
|
787
|
+
resolve19();
|
|
771
788
|
}, 5e3);
|
|
772
789
|
});
|
|
773
790
|
this.stopping.delete(platform);
|
|
@@ -1444,10 +1461,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1444
1461
|
stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
|
|
1445
1462
|
});
|
|
1446
1463
|
});
|
|
1447
|
-
await new Promise((
|
|
1464
|
+
await new Promise((resolve19) => {
|
|
1448
1465
|
stream.onAbort(() => {
|
|
1449
1466
|
unsubscribe();
|
|
1450
|
-
|
|
1467
|
+
resolve19();
|
|
1451
1468
|
});
|
|
1452
1469
|
});
|
|
1453
1470
|
});
|
|
@@ -1472,7 +1489,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1472
1489
|
config2.name = name.trim() || void 0;
|
|
1473
1490
|
writeGlobalConfig(config2);
|
|
1474
1491
|
if (config2.name !== previousName) {
|
|
1475
|
-
const { notifySpiritSystemChange } = await import("./spirit-
|
|
1492
|
+
const { notifySpiritSystemChange } = await import("./spirit-Q5VGFWUI.js");
|
|
1476
1493
|
await notifySpiritSystemChange();
|
|
1477
1494
|
}
|
|
1478
1495
|
return c.json({ name: config2.name ?? null });
|
|
@@ -1831,8 +1848,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1831
1848
|
createdAt: Date.now()
|
|
1832
1849
|
};
|
|
1833
1850
|
oauthFlows.set(flowId, flow);
|
|
1834
|
-
const promptPromise = needsManualCode ? new Promise((
|
|
1835
|
-
flow.resolveCode =
|
|
1851
|
+
const promptPromise = needsManualCode ? new Promise((resolve19) => {
|
|
1852
|
+
flow.resolveCode = resolve19;
|
|
1836
1853
|
}) : void 0;
|
|
1837
1854
|
oauthProvider.login({
|
|
1838
1855
|
onAuth: (info) => {
|
|
@@ -1871,7 +1888,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1871
1888
|
existing.error = err instanceof Error ? err.message : String(err);
|
|
1872
1889
|
}
|
|
1873
1890
|
});
|
|
1874
|
-
await new Promise((
|
|
1891
|
+
await new Promise((resolve19) => setTimeout(resolve19, 2e3));
|
|
1875
1892
|
const state = oauthFlows.get(flowId);
|
|
1876
1893
|
return c.json({
|
|
1877
1894
|
flowId,
|
|
@@ -2132,8 +2149,8 @@ var app2 = new Hono2().get("/events", async (c) => {
|
|
|
2132
2149
|
});
|
|
2133
2150
|
}, 15e3);
|
|
2134
2151
|
cleanups.push(() => clearInterval(keepAlive));
|
|
2135
|
-
await new Promise((
|
|
2136
|
-
stream.onAbort(() =>
|
|
2152
|
+
await new Promise((resolve19) => {
|
|
2153
|
+
stream.onAbort(() => resolve19());
|
|
2137
2154
|
});
|
|
2138
2155
|
} finally {
|
|
2139
2156
|
for (const cleanup of cleanups) {
|
|
@@ -2714,7 +2731,7 @@ async function fanOutToMinds(opts) {
|
|
|
2714
2731
|
);
|
|
2715
2732
|
}
|
|
2716
2733
|
if (ap.userType === "system") {
|
|
2717
|
-
import("./spirit-availability-
|
|
2734
|
+
import("./spirit-availability-G5FMWKRH.js").then(({ ensureSpiritAvailable: ensureSpiritAvailable2 }) => ensureSpiritAvailable2()).catch((err) => logger_default.warn("fan-out: on-demand spirit start failed", logger_default.errorData(err)));
|
|
2718
2735
|
}
|
|
2719
2736
|
}
|
|
2720
2737
|
return null;
|
|
@@ -3131,11 +3148,11 @@ async function notifyMind(mindName, message) {
|
|
|
3131
3148
|
const entry = await findMind(mindName);
|
|
3132
3149
|
if (!entry) return false;
|
|
3133
3150
|
try {
|
|
3134
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
3151
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-Q7IVZ5T4.js");
|
|
3135
3152
|
const result = await deliverEvent2(mindName, { type: "file-share", body: message });
|
|
3136
3153
|
if (result.delivered) return true;
|
|
3137
3154
|
if (result.id == null) return false;
|
|
3138
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
3155
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-KHI65FEX.js");
|
|
3139
3156
|
const { getBaseName: getBaseName2 } = await import("./registry-TRC2HJXR.js");
|
|
3140
3157
|
return getSleepManagerIfReady2()?.isSleeping(await getBaseName2(mindName)) ?? false;
|
|
3141
3158
|
} catch (err) {
|
|
@@ -4108,9 +4125,9 @@ var app11 = new Hono14().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
4108
4125
|
stream.onAbort(() => {
|
|
4109
4126
|
tail.kill();
|
|
4110
4127
|
});
|
|
4111
|
-
await new Promise((
|
|
4112
|
-
tail.on("exit",
|
|
4113
|
-
stream.onAbort(
|
|
4128
|
+
await new Promise((resolve19) => {
|
|
4129
|
+
tail.on("exit", resolve19);
|
|
4130
|
+
stream.onAbort(resolve19);
|
|
4114
4131
|
});
|
|
4115
4132
|
});
|
|
4116
4133
|
}).get("/:name/logs/tail", requireSelf(), async (c) => {
|
|
@@ -4128,8 +4145,8 @@ var app11 = new Hono14().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
4128
4145
|
tail.stdout.on("data", (data) => {
|
|
4129
4146
|
output += data.toString();
|
|
4130
4147
|
});
|
|
4131
|
-
await new Promise((
|
|
4132
|
-
tail.on("exit",
|
|
4148
|
+
await new Promise((resolve19) => {
|
|
4149
|
+
tail.on("exit", resolve19);
|
|
4133
4150
|
});
|
|
4134
4151
|
return c.text(output);
|
|
4135
4152
|
});
|
|
@@ -4222,14 +4239,14 @@ var mind_skills_default = app12;
|
|
|
4222
4239
|
// packages/daemon/src/web/api/minds.ts
|
|
4223
4240
|
import {
|
|
4224
4241
|
cpSync,
|
|
4225
|
-
existsSync as
|
|
4242
|
+
existsSync as existsSync7,
|
|
4226
4243
|
mkdirSync as mkdirSync6,
|
|
4227
4244
|
readdirSync as readdirSync2,
|
|
4228
4245
|
readFileSync as readFileSync9,
|
|
4229
4246
|
rmSync as rmSync3,
|
|
4230
4247
|
writeFileSync as writeFileSync8
|
|
4231
4248
|
} from "fs";
|
|
4232
|
-
import { relative, resolve as
|
|
4249
|
+
import { relative, resolve as resolve11 } from "path";
|
|
4233
4250
|
import { zValidator as zValidator6 } from "@hono/zod-validator";
|
|
4234
4251
|
import { and as and5, desc as desc3, eq as eq5, sql as sql3 } from "drizzle-orm";
|
|
4235
4252
|
import { Hono as Hono16 } from "hono";
|
|
@@ -4672,49 +4689,6 @@ async function commitSrcChanges(dir, mindName) {
|
|
|
4672
4689
|
glog.info(`committed known-good src changes (${dir})`);
|
|
4673
4690
|
}
|
|
4674
4691
|
|
|
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
4692
|
// packages/daemon/src/lib/mind/thinking-config.ts
|
|
4719
4693
|
var CLAUDE_EFFORT = {
|
|
4720
4694
|
minimal: "low",
|
|
@@ -4756,150 +4730,6 @@ function deriveThinkingLevel(config2) {
|
|
|
4756
4730
|
return null;
|
|
4757
4731
|
}
|
|
4758
4732
|
|
|
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
4733
|
// packages/daemon/src/lib/services/imagegen-jobs.ts
|
|
4904
4734
|
import { mkdir, writeFile } from "fs/promises";
|
|
4905
4735
|
import { dirname as dirname2 } from "path";
|
|
@@ -5022,7 +4852,7 @@ async function waitForImagegenJob(mind, id, timeoutMs) {
|
|
|
5022
4852
|
import { randomUUID } from "crypto";
|
|
5023
4853
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
5024
4854
|
import { homedir } from "os";
|
|
5025
|
-
import { resolve as
|
|
4855
|
+
import { resolve as resolve10 } from "path";
|
|
5026
4856
|
function convertSession(opts) {
|
|
5027
4857
|
const lines = readFileSync8(opts.sessionPath, "utf-8").trim().split("\n");
|
|
5028
4858
|
const sessionId = randomUUID();
|
|
@@ -5138,9 +4968,9 @@ function convertSession(opts) {
|
|
|
5138
4968
|
}
|
|
5139
4969
|
}
|
|
5140
4970
|
const projectId = opts.projectDir.replace(/\//g, "-");
|
|
5141
|
-
const sdkDir =
|
|
4971
|
+
const sdkDir = resolve10(homedir(), ".claude", "projects", projectId);
|
|
5142
4972
|
mkdirSync5(sdkDir, { recursive: true });
|
|
5143
|
-
const sdkPath =
|
|
4973
|
+
const sdkPath = resolve10(sdkDir, `${sessionId}.jsonl`);
|
|
5144
4974
|
writeFileSync7(sdkPath, `${sdkEvents.join("\n")}
|
|
5145
4975
|
`);
|
|
5146
4976
|
console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
|
|
@@ -5201,7 +5031,7 @@ async function getMindStatus(name, port, registryRunning, seed) {
|
|
|
5201
5031
|
let status = "stopped";
|
|
5202
5032
|
let wakeAt = null;
|
|
5203
5033
|
try {
|
|
5204
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5034
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-KHI65FEX.js");
|
|
5205
5035
|
const sleepManager = getSleepManagerIfReady2();
|
|
5206
5036
|
if (sleepManager?.isSleeping(name)) {
|
|
5207
5037
|
status = "sleeping";
|
|
@@ -5265,13 +5095,6 @@ function toPublicMind(entry, status, extras) {
|
|
|
5265
5095
|
lastActiveAt: extras.lastActiveAt ?? null
|
|
5266
5096
|
};
|
|
5267
5097
|
}
|
|
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
5098
|
async function initTemplateBranch(projectRoot, composedDir, manifest, mindName, env) {
|
|
5276
5099
|
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
5100
|
const opts = { cwd: projectRoot, mindName, env };
|
|
@@ -5282,164 +5105,9 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
|
|
|
5282
5105
|
await gitExec(["add", "-A"], opts);
|
|
5283
5106
|
await gitExec(["commit", "-m", "initial commit"], opts);
|
|
5284
5107
|
}
|
|
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
5108
|
async function importFromArchive(c, tempDir, nameOverride, manifest) {
|
|
5441
|
-
const extractedMindDir =
|
|
5442
|
-
if (!
|
|
5109
|
+
const extractedMindDir = resolve11(tempDir, "mind");
|
|
5110
|
+
if (!existsSync7(extractedMindDir)) {
|
|
5443
5111
|
return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
|
|
5444
5112
|
}
|
|
5445
5113
|
if (!manifest?.includes || !manifest.name || !manifest.template) {
|
|
@@ -5457,7 +5125,7 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5457
5125
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
5458
5126
|
ensureVoluteHome();
|
|
5459
5127
|
const dest = mindDir(name);
|
|
5460
|
-
if (
|
|
5128
|
+
if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5461
5129
|
try {
|
|
5462
5130
|
cpSync(extractedMindDir, dest, { recursive: true });
|
|
5463
5131
|
if (!manifest.includes.identity) {
|
|
@@ -5465,9 +5133,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5465
5133
|
}
|
|
5466
5134
|
const state = stateDir(name);
|
|
5467
5135
|
mkdirSync6(state, { recursive: true });
|
|
5468
|
-
const envJson =
|
|
5469
|
-
if (
|
|
5470
|
-
cpSync(envJson,
|
|
5136
|
+
const envJson = resolve11(tempDir, "state/env.json");
|
|
5137
|
+
if (existsSync7(envJson)) {
|
|
5138
|
+
cpSync(envJson, resolve11(state, "env.json"));
|
|
5471
5139
|
}
|
|
5472
5140
|
const port = await nextPort();
|
|
5473
5141
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
@@ -5476,30 +5144,30 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5476
5144
|
} catch (err) {
|
|
5477
5145
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5478
5146
|
}
|
|
5479
|
-
const homeDir =
|
|
5147
|
+
const homeDir = resolve11(dest, "home");
|
|
5480
5148
|
ensureVoluteGroup();
|
|
5481
5149
|
createMindUser(name, homeDir);
|
|
5482
5150
|
await chownMindDir(dest, name);
|
|
5483
5151
|
await npmInstallAsMind(dest, name);
|
|
5484
5152
|
await importHistoryFromArchive(name, tempDir);
|
|
5485
5153
|
importSessionsFromArchive(dest, tempDir);
|
|
5486
|
-
if (!
|
|
5154
|
+
if (!existsSync7(resolve11(dest, ".git"))) {
|
|
5487
5155
|
try {
|
|
5488
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5156
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
|
|
5489
5157
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
5490
5158
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
5491
5159
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
5492
5160
|
await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
|
|
5493
5161
|
} catch (err) {
|
|
5494
5162
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
5495
|
-
rmSync3(
|
|
5163
|
+
rmSync3(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
5496
5164
|
}
|
|
5497
5165
|
}
|
|
5498
5166
|
await chownMindDir(dest, name);
|
|
5499
5167
|
rmSync3(tempDir, { recursive: true, force: true });
|
|
5500
5168
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
5501
5169
|
} catch (err) {
|
|
5502
|
-
if (
|
|
5170
|
+
if (existsSync7(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5503
5171
|
try {
|
|
5504
5172
|
await removeMind(name);
|
|
5505
5173
|
} catch (cleanupErr) {
|
|
@@ -5516,7 +5184,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5516
5184
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
5517
5185
|
ensureVoluteHome();
|
|
5518
5186
|
const dest = mindDir(name);
|
|
5519
|
-
if (
|
|
5187
|
+
if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5520
5188
|
const templatesRoot = findTemplatesRoot();
|
|
5521
5189
|
const { composedDir, manifest: templateManifest } = composeTemplate(
|
|
5522
5190
|
templatesRoot,
|
|
@@ -5525,36 +5193,36 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5525
5193
|
try {
|
|
5526
5194
|
copyTemplateToDir(composedDir, dest, name, templateManifest);
|
|
5527
5195
|
applyInitFiles(dest);
|
|
5528
|
-
const extractedHome =
|
|
5529
|
-
if (
|
|
5530
|
-
cpSync(extractedHome,
|
|
5196
|
+
const extractedHome = resolve11(extractedMindDir, "home");
|
|
5197
|
+
if (existsSync7(extractedHome)) {
|
|
5198
|
+
cpSync(extractedHome, resolve11(dest, "home"), { recursive: true });
|
|
5531
5199
|
}
|
|
5532
|
-
const extractedMindInternal =
|
|
5533
|
-
if (
|
|
5534
|
-
cpSync(extractedMindInternal,
|
|
5200
|
+
const extractedMindInternal = resolve11(extractedMindDir, ".mind");
|
|
5201
|
+
if (existsSync7(extractedMindInternal)) {
|
|
5202
|
+
cpSync(extractedMindInternal, resolve11(dest, ".mind"), { recursive: true });
|
|
5535
5203
|
}
|
|
5536
|
-
const identityDir =
|
|
5204
|
+
const identityDir = resolve11(dest, ".mind/identity");
|
|
5537
5205
|
let publicKeyPem;
|
|
5538
|
-
if (!manifest.includes.identity || !
|
|
5206
|
+
if (!manifest.includes.identity || !existsSync7(resolve11(identityDir, "private.pem"))) {
|
|
5539
5207
|
({ publicKeyPem } = generateIdentity(dest));
|
|
5540
5208
|
} else {
|
|
5541
|
-
publicKeyPem = readFileSync9(
|
|
5209
|
+
publicKeyPem = readFileSync9(resolve11(identityDir, "public.pem"), "utf-8");
|
|
5542
5210
|
}
|
|
5543
|
-
const promptsPath =
|
|
5544
|
-
if (!
|
|
5211
|
+
const promptsPath = resolve11(dest, "home/.config/prompts.json");
|
|
5212
|
+
if (!existsSync7(promptsPath)) {
|
|
5545
5213
|
const mindPrompts = await getMindPromptDefaults();
|
|
5546
5214
|
writeFileSync8(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
|
|
5547
5215
|
`);
|
|
5548
5216
|
}
|
|
5549
5217
|
const state = stateDir(name);
|
|
5550
5218
|
mkdirSync6(state, { recursive: true });
|
|
5551
|
-
const envJson =
|
|
5552
|
-
if (
|
|
5553
|
-
cpSync(envJson,
|
|
5219
|
+
const envJson = resolve11(tempDir, "state/env.json");
|
|
5220
|
+
if (existsSync7(envJson)) {
|
|
5221
|
+
cpSync(envJson, resolve11(state, "env.json"));
|
|
5554
5222
|
}
|
|
5555
5223
|
const port = await nextPort();
|
|
5556
5224
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
5557
|
-
const homeDir =
|
|
5225
|
+
const homeDir = resolve11(dest, "home");
|
|
5558
5226
|
ensureVoluteGroup();
|
|
5559
5227
|
createMindUser(name, homeDir);
|
|
5560
5228
|
await chownMindDir(dest, name);
|
|
@@ -5567,7 +5235,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5567
5235
|
await initTemplateBranch(dest, composedDir, templateManifest, name, env);
|
|
5568
5236
|
} catch (err) {
|
|
5569
5237
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
5570
|
-
rmSync3(
|
|
5238
|
+
rmSync3(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
5571
5239
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
5572
5240
|
}
|
|
5573
5241
|
const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
|
|
@@ -5597,7 +5265,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5597
5265
|
...skillWarnings.length > 0 && { skillWarnings }
|
|
5598
5266
|
});
|
|
5599
5267
|
} catch (err) {
|
|
5600
|
-
if (
|
|
5268
|
+
if (existsSync7(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5601
5269
|
try {
|
|
5602
5270
|
await removeMind(name);
|
|
5603
5271
|
} catch (cleanupErr) {
|
|
@@ -5610,8 +5278,8 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5610
5278
|
}
|
|
5611
5279
|
}
|
|
5612
5280
|
async function importHistoryFromArchive(name, tempDir) {
|
|
5613
|
-
const historyJsonl =
|
|
5614
|
-
if (!
|
|
5281
|
+
const historyJsonl = resolve11(tempDir, "history.jsonl");
|
|
5282
|
+
if (!existsSync7(historyJsonl)) return;
|
|
5615
5283
|
try {
|
|
5616
5284
|
const db = await getDb();
|
|
5617
5285
|
const lines = readFileSync9(historyJsonl, "utf-8").trim().split("\n");
|
|
@@ -5651,13 +5319,13 @@ async function importHistoryFromArchive(name, tempDir) {
|
|
|
5651
5319
|
}
|
|
5652
5320
|
}
|
|
5653
5321
|
function importSessionsFromArchive(dest, tempDir) {
|
|
5654
|
-
const sessionsDir =
|
|
5655
|
-
if (!
|
|
5322
|
+
const sessionsDir = resolve11(tempDir, "sessions");
|
|
5323
|
+
if (!existsSync7(sessionsDir)) return;
|
|
5656
5324
|
try {
|
|
5657
|
-
const destSessions =
|
|
5325
|
+
const destSessions = resolve11(dest, ".mind/sessions");
|
|
5658
5326
|
mkdirSync6(destSessions, { recursive: true });
|
|
5659
5327
|
for (const file of readdirSync2(sessionsDir)) {
|
|
5660
|
-
cpSync(
|
|
5328
|
+
cpSync(resolve11(sessionsDir, file), resolve11(destSessions, file));
|
|
5661
5329
|
}
|
|
5662
5330
|
} catch (err) {
|
|
5663
5331
|
logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
|
|
@@ -5737,7 +5405,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5737
5405
|
}
|
|
5738
5406
|
ensureVoluteHome();
|
|
5739
5407
|
const dest = mindDir(name);
|
|
5740
|
-
if (
|
|
5408
|
+
if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5741
5409
|
const templatesRoot = findTemplatesRoot();
|
|
5742
5410
|
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5743
5411
|
try {
|
|
@@ -5774,9 +5442,9 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5774
5442
|
writeVoluteConfig(dest, config2);
|
|
5775
5443
|
const modelId = body.model ?? cog?.model;
|
|
5776
5444
|
effectiveModel = modelId ? qualifyModelId(modelId) : void 0;
|
|
5777
|
-
const sdkConfigPath =
|
|
5445
|
+
const sdkConfigPath = resolve11(dest, "home/.config/config.json");
|
|
5778
5446
|
if (modelId || cog?.compaction) {
|
|
5779
|
-
const existing =
|
|
5447
|
+
const existing = existsSync7(sdkConfigPath) ? JSON.parse(readFileSync9(sdkConfigPath, "utf-8")) : {};
|
|
5780
5448
|
if (modelId) {
|
|
5781
5449
|
existing.model = template === "pi" ? qualifyModelId(modelId) : unqualifyModelId(modelId);
|
|
5782
5450
|
}
|
|
@@ -5789,7 +5457,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5789
5457
|
}
|
|
5790
5458
|
const mindPrompts = await getMindPromptDefaults();
|
|
5791
5459
|
writeFileSync8(
|
|
5792
|
-
|
|
5460
|
+
resolve11(dest, "home/.config/prompts.json"),
|
|
5793
5461
|
`${JSON.stringify(mindPrompts, null, 2)}
|
|
5794
5462
|
`
|
|
5795
5463
|
);
|
|
@@ -5801,7 +5469,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5801
5469
|
} catch (err) {
|
|
5802
5470
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5803
5471
|
}
|
|
5804
|
-
const homeDir =
|
|
5472
|
+
const homeDir = resolve11(dest, "home");
|
|
5805
5473
|
ensureVoluteGroup();
|
|
5806
5474
|
createMindUser(name, homeDir);
|
|
5807
5475
|
await chownMindDir(dest, name);
|
|
@@ -5814,7 +5482,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5814
5482
|
await initTemplateBranch(dest, composedDir, manifest, name, env);
|
|
5815
5483
|
} catch (err) {
|
|
5816
5484
|
logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
|
|
5817
|
-
rmSync3(
|
|
5485
|
+
rmSync3(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
5818
5486
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
5819
5487
|
}
|
|
5820
5488
|
if (body.stage === "seed") {
|
|
@@ -5823,7 +5491,7 @@ Your creator described you as: "${body.description}"
|
|
|
5823
5491
|
` : "";
|
|
5824
5492
|
const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
|
|
5825
5493
|
const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
|
|
5826
|
-
writeFileSync8(
|
|
5494
|
+
writeFileSync8(resolve11(dest, "home/SOUL.md"), seedSoul);
|
|
5827
5495
|
}
|
|
5828
5496
|
let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
|
|
5829
5497
|
if (body.stage === "seed" && !body.skills) {
|
|
@@ -5849,7 +5517,7 @@ Your creator described you as: "${body.description}"
|
|
|
5849
5517
|
const spiritName = getSpiritName();
|
|
5850
5518
|
const spiritEntry = await findMind(spiritName);
|
|
5851
5519
|
if (spiritEntry) {
|
|
5852
|
-
const { spiritDir } = await import("./spirit-
|
|
5520
|
+
const { spiritDir } = await import("./spirit-Q5VGFWUI.js");
|
|
5853
5521
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
5854
5522
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
5855
5523
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -5864,7 +5532,7 @@ Your creator described you as: "${body.description}"
|
|
|
5864
5532
|
});
|
|
5865
5533
|
spiritConfig.schedules = schedules;
|
|
5866
5534
|
writeVoluteConfig(sDir, spiritConfig);
|
|
5867
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
5535
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-73Q4MQ7Y.js");
|
|
5868
5536
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
5869
5537
|
}
|
|
5870
5538
|
}
|
|
@@ -5875,11 +5543,11 @@ Your creator described you as: "${body.description}"
|
|
|
5875
5543
|
if (body.stage !== "seed") {
|
|
5876
5544
|
const customSoul = await getPromptIfCustom("default_soul");
|
|
5877
5545
|
if (customSoul) {
|
|
5878
|
-
writeFileSync8(
|
|
5546
|
+
writeFileSync8(resolve11(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
|
|
5879
5547
|
}
|
|
5880
5548
|
const customMemory = await getPromptIfCustom("default_memory");
|
|
5881
5549
|
if (customMemory) {
|
|
5882
|
-
writeFileSync8(
|
|
5550
|
+
writeFileSync8(resolve11(dest, "home/MEMORY.md"), customMemory);
|
|
5883
5551
|
}
|
|
5884
5552
|
}
|
|
5885
5553
|
await chownMindDir(dest, name);
|
|
@@ -5919,7 +5587,7 @@ Your creator described you as: "${body.description}"
|
|
|
5919
5587
|
...skillWarnings.length > 0 && { skillWarnings }
|
|
5920
5588
|
});
|
|
5921
5589
|
} catch (err) {
|
|
5922
|
-
if (
|
|
5590
|
+
if (existsSync7(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5923
5591
|
try {
|
|
5924
5592
|
await removeMind(name);
|
|
5925
5593
|
} catch (cleanupErr) {
|
|
@@ -5940,13 +5608,13 @@ Your creator described you as: "${body.description}"
|
|
|
5940
5608
|
return importFromArchive(c, body.archivePath, body.name, body.manifest);
|
|
5941
5609
|
}
|
|
5942
5610
|
const wsDir = body.workspacePath;
|
|
5943
|
-
if (!wsDir || !
|
|
5611
|
+
if (!wsDir || !existsSync7(resolve11(wsDir, "SOUL.md")) || !existsSync7(resolve11(wsDir, "IDENTITY.md"))) {
|
|
5944
5612
|
return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
|
|
5945
5613
|
}
|
|
5946
|
-
const soul = readFileSync9(
|
|
5947
|
-
const identity = readFileSync9(
|
|
5948
|
-
const userPath =
|
|
5949
|
-
const user =
|
|
5614
|
+
const soul = readFileSync9(resolve11(wsDir, "SOUL.md"), "utf-8");
|
|
5615
|
+
const identity = readFileSync9(resolve11(wsDir, "IDENTITY.md"), "utf-8");
|
|
5616
|
+
const userPath = resolve11(wsDir, "USER.md");
|
|
5617
|
+
const user = existsSync7(userPath) ? readFileSync9(userPath, "utf-8") : "";
|
|
5950
5618
|
const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
|
|
5951
5619
|
const template = body.template ?? "claude";
|
|
5952
5620
|
const nameErr = validateMindName(name);
|
|
@@ -5966,33 +5634,33 @@ ${user.trimEnd()}
|
|
|
5966
5634
|
` : "";
|
|
5967
5635
|
ensureVoluteHome();
|
|
5968
5636
|
const dest = mindDir(name);
|
|
5969
|
-
if (
|
|
5637
|
+
if (existsSync7(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5970
5638
|
const templatesRoot = findTemplatesRoot();
|
|
5971
5639
|
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5972
5640
|
try {
|
|
5973
5641
|
copyTemplateToDir(composedDir, dest, name, manifest);
|
|
5974
5642
|
applyInitFiles(dest);
|
|
5975
5643
|
const { publicKeyPem: importPublicKey } = generateIdentity(dest);
|
|
5976
|
-
writeFileSync8(
|
|
5977
|
-
const wsMemoryPath =
|
|
5978
|
-
const hasMemory =
|
|
5644
|
+
writeFileSync8(resolve11(dest, "home/SOUL.md"), mergedSoul);
|
|
5645
|
+
const wsMemoryPath = resolve11(wsDir, "MEMORY.md");
|
|
5646
|
+
const hasMemory = existsSync7(wsMemoryPath);
|
|
5979
5647
|
if (hasMemory) {
|
|
5980
5648
|
const existingMemory = readFileSync9(wsMemoryPath, "utf-8");
|
|
5981
5649
|
writeFileSync8(
|
|
5982
|
-
|
|
5650
|
+
resolve11(dest, "home/MEMORY.md"),
|
|
5983
5651
|
`${existingMemory.trimEnd()}${mergedMemoryExtra}`
|
|
5984
5652
|
);
|
|
5985
5653
|
} else if (user) {
|
|
5986
|
-
writeFileSync8(
|
|
5654
|
+
writeFileSync8(resolve11(dest, "home/MEMORY.md"), `${user.trimEnd()}
|
|
5987
5655
|
`);
|
|
5988
5656
|
}
|
|
5989
|
-
const wsMemoryDir =
|
|
5657
|
+
const wsMemoryDir = resolve11(wsDir, "memory");
|
|
5990
5658
|
let dailyLogCount = 0;
|
|
5991
|
-
if (
|
|
5992
|
-
const destMemoryDir =
|
|
5659
|
+
if (existsSync7(wsMemoryDir)) {
|
|
5660
|
+
const destMemoryDir = resolve11(dest, "home/memory");
|
|
5993
5661
|
const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
|
|
5994
5662
|
for (const file of files) {
|
|
5995
|
-
cpSync(
|
|
5663
|
+
cpSync(resolve11(wsMemoryDir, file), resolve11(destMemoryDir, file));
|
|
5996
5664
|
}
|
|
5997
5665
|
dailyLogCount = files.length;
|
|
5998
5666
|
}
|
|
@@ -6003,7 +5671,7 @@ ${user.trimEnd()}
|
|
|
6003
5671
|
} catch (err) {
|
|
6004
5672
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
6005
5673
|
}
|
|
6006
|
-
const homeDir =
|
|
5674
|
+
const homeDir = resolve11(dest, "home");
|
|
6007
5675
|
ensureVoluteGroup();
|
|
6008
5676
|
createMindUser(name, homeDir);
|
|
6009
5677
|
await chownMindDir(dest, name);
|
|
@@ -6011,20 +5679,20 @@ ${user.trimEnd()}
|
|
|
6011
5679
|
if (!hasMemory && dailyLogCount > 0) {
|
|
6012
5680
|
await consolidateMemory(dest);
|
|
6013
5681
|
}
|
|
6014
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5682
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
|
|
6015
5683
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
6016
5684
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
6017
5685
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
6018
5686
|
await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
|
|
6019
|
-
const sessionFile = body.sessionPath ?
|
|
6020
|
-
if (sessionFile &&
|
|
5687
|
+
const sessionFile = body.sessionPath ? resolve11(body.sessionPath) : findOpenClawSession(wsDir);
|
|
5688
|
+
if (sessionFile && existsSync7(sessionFile)) {
|
|
6021
5689
|
if (template === "pi") {
|
|
6022
5690
|
importPiSession(sessionFile, dest);
|
|
6023
5691
|
} else if (template === "claude") {
|
|
6024
5692
|
const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
|
|
6025
|
-
const mindRuntimeDir =
|
|
5693
|
+
const mindRuntimeDir = resolve11(dest, ".mind");
|
|
6026
5694
|
mkdirSync6(mindRuntimeDir, { recursive: true });
|
|
6027
|
-
writeFileSync8(
|
|
5695
|
+
writeFileSync8(resolve11(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
|
|
6028
5696
|
}
|
|
6029
5697
|
}
|
|
6030
5698
|
importOpenClawConnectors(name, dest);
|
|
@@ -6034,7 +5702,7 @@ ${user.trimEnd()}
|
|
|
6034
5702
|
);
|
|
6035
5703
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
6036
5704
|
} catch (err) {
|
|
6037
|
-
if (
|
|
5705
|
+
if (existsSync7(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
6038
5706
|
try {
|
|
6039
5707
|
await removeMind(name);
|
|
6040
5708
|
} catch (cleanupErr) {
|
|
@@ -6070,7 +5738,7 @@ ${user.trimEnd()}
|
|
|
6070
5738
|
stage: entry.stage,
|
|
6071
5739
|
dir: entry.dir
|
|
6072
5740
|
});
|
|
6073
|
-
const hasPages =
|
|
5741
|
+
const hasPages = existsSync7(resolve11(mindDir(entry.name), "home", "pages"));
|
|
6074
5742
|
const lastActiveAt = lastActiveMap.get(entry.name) ?? null;
|
|
6075
5743
|
if (!privileged) return toPublicMind(entry, mindStatus, { hasPages, lastActiveAt });
|
|
6076
5744
|
return {
|
|
@@ -6078,6 +5746,7 @@ ${user.trimEnd()}
|
|
|
6078
5746
|
...mindStatus,
|
|
6079
5747
|
hasPages,
|
|
6080
5748
|
templateStale: isTemplateStale(entry),
|
|
5749
|
+
upgradeBlocked: getUpgradeBlocked(entry.name)?.reason,
|
|
6081
5750
|
lastActiveAt
|
|
6082
5751
|
};
|
|
6083
5752
|
})
|
|
@@ -6088,12 +5757,12 @@ ${user.trimEnd()}
|
|
|
6088
5757
|
const entry = await findMind(name);
|
|
6089
5758
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6090
5759
|
const dir = entry.dir ?? mindDir(entry.parent ?? name);
|
|
6091
|
-
if (!
|
|
5760
|
+
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6092
5761
|
const mindStatus = await getMindStatus(name, entry.port, void 0, {
|
|
6093
5762
|
stage: entry.stage,
|
|
6094
5763
|
dir: entry.dir
|
|
6095
5764
|
});
|
|
6096
|
-
const hasPages =
|
|
5765
|
+
const hasPages = existsSync7(resolve11(mindDir(name), "home", "pages"));
|
|
6097
5766
|
if (!isPrivileged(c)) {
|
|
6098
5767
|
return c.json(toPublicMind(entry, mindStatus, { hasPages }));
|
|
6099
5768
|
}
|
|
@@ -6116,6 +5785,7 @@ ${user.trimEnd()}
|
|
|
6116
5785
|
variants: variantStatuses,
|
|
6117
5786
|
hasPages,
|
|
6118
5787
|
templateStale: isTemplateStale(entry),
|
|
5788
|
+
upgradeBlocked: getUpgradeBlocked(name)?.reason,
|
|
6119
5789
|
...notice && {
|
|
6120
5790
|
lastNotice: {
|
|
6121
5791
|
kind: notice.kind,
|
|
@@ -6133,7 +5803,7 @@ ${user.trimEnd()}
|
|
|
6133
5803
|
const projectDir = entry.dir ?? mindDir(name);
|
|
6134
5804
|
if (entry.parent) {
|
|
6135
5805
|
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
|
|
6136
|
-
} else if (!
|
|
5806
|
+
} else if (!existsSync7(projectDir)) {
|
|
6137
5807
|
return c.json({ error: "Mind directory missing" }, 404);
|
|
6138
5808
|
}
|
|
6139
5809
|
if (getMindManager().isRunning(name)) {
|
|
@@ -6154,7 +5824,7 @@ ${user.trimEnd()}
|
|
|
6154
5824
|
const projectDir = entry.dir ?? mindDir(name);
|
|
6155
5825
|
if (entry.parent) {
|
|
6156
5826
|
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
|
|
6157
|
-
} else if (!
|
|
5827
|
+
} else if (!existsSync7(projectDir)) {
|
|
6158
5828
|
return c.json({ error: "Mind directory missing" }, 404);
|
|
6159
5829
|
}
|
|
6160
5830
|
let context;
|
|
@@ -6170,7 +5840,7 @@ ${user.trimEnd()}
|
|
|
6170
5840
|
const manager = getMindManager();
|
|
6171
5841
|
try {
|
|
6172
5842
|
if (context?.type === "reload") {
|
|
6173
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5843
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-KHI65FEX.js");
|
|
6174
5844
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
6175
5845
|
if (sleepState?.sleeping) {
|
|
6176
5846
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -6191,7 +5861,7 @@ ${user.trimEnd()}
|
|
|
6191
5861
|
if (variantEntry && variantEntry.parent === baseName && variantEntry.dir && variantEntry.branch) {
|
|
6192
5862
|
const projectRoot = mindDir(baseName);
|
|
6193
5863
|
const discardUnresolved = context.discardUnresolvedHomeFiles === true;
|
|
6194
|
-
if (
|
|
5864
|
+
if (existsSync7(variantEntry.dir)) {
|
|
6195
5865
|
const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
|
|
6196
5866
|
if (status) {
|
|
6197
5867
|
try {
|
|
@@ -6221,7 +5891,7 @@ ${user.trimEnd()}
|
|
|
6221
5891
|
const preMergeHead = (await gitExec(["rev-parse", "HEAD"], { cwd: projectRoot })).trim();
|
|
6222
5892
|
const memoryDelta = await mergeVariantExcludingMemory(projectRoot, variantEntry.branch);
|
|
6223
5893
|
let unresolvedNotice;
|
|
6224
|
-
if (
|
|
5894
|
+
if (existsSync7(variantEntry.dir) && !discardUnresolved) {
|
|
6225
5895
|
try {
|
|
6226
5896
|
const unresolved = await findUnresolvedHomeFiles(variantEntry.dir);
|
|
6227
5897
|
if (unresolved.totalCount > 0) {
|
|
@@ -6319,7 +5989,7 @@ ${user.trimEnd()}
|
|
|
6319
5989
|
const name = c.req.param("name");
|
|
6320
5990
|
const entry = await findMind(name);
|
|
6321
5991
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6322
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5992
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-KHI65FEX.js");
|
|
6323
5993
|
const sm = getSleepManagerIfReady2();
|
|
6324
5994
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6325
5995
|
return c.json(sm.getState(name));
|
|
@@ -6327,7 +5997,7 @@ ${user.trimEnd()}
|
|
|
6327
5997
|
const name = c.req.param("name");
|
|
6328
5998
|
const entry = await findMind(name);
|
|
6329
5999
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6330
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6000
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-KHI65FEX.js");
|
|
6331
6001
|
const sm = getSleepManagerIfReady2();
|
|
6332
6002
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6333
6003
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -6347,7 +6017,7 @@ ${user.trimEnd()}
|
|
|
6347
6017
|
const name = c.req.param("name");
|
|
6348
6018
|
const entry = await findMind(name);
|
|
6349
6019
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6350
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6020
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-KHI65FEX.js");
|
|
6351
6021
|
const sm = getSleepManagerIfReady2();
|
|
6352
6022
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6353
6023
|
const sleepState = sm.getState(name);
|
|
@@ -6362,7 +6032,7 @@ ${user.trimEnd()}
|
|
|
6362
6032
|
const name = c.req.param("name");
|
|
6363
6033
|
const entry = await findMind(name);
|
|
6364
6034
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6365
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6035
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-KHI65FEX.js");
|
|
6366
6036
|
const sm = getSleepManagerIfReady2();
|
|
6367
6037
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6368
6038
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -6378,12 +6048,12 @@ ${user.trimEnd()}
|
|
|
6378
6048
|
if (body.displayName !== void 0) profile.displayName = body.displayName;
|
|
6379
6049
|
if (body.description !== void 0) profile.description = body.description;
|
|
6380
6050
|
if (body.avatar !== void 0) {
|
|
6381
|
-
const homeDir =
|
|
6051
|
+
const homeDir = resolve11(dir, "home");
|
|
6382
6052
|
const avatarPath = safeResolveWithinBase(homeDir, body.avatar);
|
|
6383
6053
|
if (!avatarPath) {
|
|
6384
6054
|
return c.json({ error: "Avatar path must be inside the mind's home directory" }, 400);
|
|
6385
6055
|
}
|
|
6386
|
-
if (!
|
|
6056
|
+
if (!existsSync7(avatarPath)) {
|
|
6387
6057
|
return c.json({ error: `Avatar file not found: ${relative(homeDir, avatarPath)}` }, 400);
|
|
6388
6058
|
}
|
|
6389
6059
|
profile.avatar = relative(homeDir, avatarPath);
|
|
@@ -6434,7 +6104,7 @@ ${user.trimEnd()}
|
|
|
6434
6104
|
});
|
|
6435
6105
|
}
|
|
6436
6106
|
if (!force) {
|
|
6437
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6107
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-KHI65FEX.js");
|
|
6438
6108
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
6439
6109
|
return c.json({ output: "" });
|
|
6440
6110
|
}
|
|
@@ -6489,7 +6159,7 @@ ${user.trimEnd()}
|
|
|
6489
6159
|
}
|
|
6490
6160
|
}
|
|
6491
6161
|
const dir = entry.dir ?? mindDir(name);
|
|
6492
|
-
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-
|
|
6162
|
+
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-H5TTPAQH.js");
|
|
6493
6163
|
const checklist = evaluateSeedChecklist2(dir);
|
|
6494
6164
|
const done = [];
|
|
6495
6165
|
const remaining = [];
|
|
@@ -6531,7 +6201,7 @@ ${user.trimEnd()}
|
|
|
6531
6201
|
try {
|
|
6532
6202
|
const sproutedDir = entry.dir ?? mindDir(name);
|
|
6533
6203
|
if (setupDefaultDreaming(sproutedDir).schedulesChanged) {
|
|
6534
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6204
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-73Q4MQ7Y.js");
|
|
6535
6205
|
getScheduler2().loadSchedules(name, sproutedDir);
|
|
6536
6206
|
}
|
|
6537
6207
|
} catch (err) {
|
|
@@ -6541,7 +6211,7 @@ ${user.trimEnd()}
|
|
|
6541
6211
|
const spiritName = getSpiritName();
|
|
6542
6212
|
const spiritEntry = await findMind(spiritName);
|
|
6543
6213
|
if (spiritEntry) {
|
|
6544
|
-
const { firstWeekSchedules, spiritDir } = await import("./spirit-
|
|
6214
|
+
const { firstWeekSchedules, spiritDir } = await import("./spirit-Q5VGFWUI.js");
|
|
6545
6215
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
6546
6216
|
const spiritConfig = readVoluteConfig(sDir);
|
|
6547
6217
|
if (spiritConfig) {
|
|
@@ -6555,7 +6225,7 @@ ${user.trimEnd()}
|
|
|
6555
6225
|
spiritConfig.schedules = schedules;
|
|
6556
6226
|
writeVoluteConfig(sDir, spiritConfig);
|
|
6557
6227
|
try {
|
|
6558
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6228
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-73Q4MQ7Y.js");
|
|
6559
6229
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
6560
6230
|
} catch (err) {
|
|
6561
6231
|
logger_default.warn(
|
|
@@ -6609,10 +6279,10 @@ ${user.trimEnd()}
|
|
|
6609
6279
|
await deleteMindUser2(name);
|
|
6610
6280
|
invalidateMindUserCache(name);
|
|
6611
6281
|
const state = stateDir(name);
|
|
6612
|
-
if (
|
|
6282
|
+
if (existsSync7(state)) {
|
|
6613
6283
|
rmSync3(state, { recursive: true, force: true });
|
|
6614
6284
|
}
|
|
6615
|
-
if (force &&
|
|
6285
|
+
if (force && existsSync7(dir)) {
|
|
6616
6286
|
rmSync3(dir, { recursive: true, force: true });
|
|
6617
6287
|
deleteMindUser(name);
|
|
6618
6288
|
}
|
|
@@ -6627,7 +6297,7 @@ ${user.trimEnd()}
|
|
|
6627
6297
|
const entry = await findMind(mindName);
|
|
6628
6298
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6629
6299
|
const dir = mindDir(mindName);
|
|
6630
|
-
if (!
|
|
6300
|
+
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6631
6301
|
let body = {};
|
|
6632
6302
|
try {
|
|
6633
6303
|
body = await c.req.json();
|
|
@@ -6638,27 +6308,12 @@ ${user.trimEnd()}
|
|
|
6638
6308
|
if (!isKnownTemplate(template)) {
|
|
6639
6309
|
return c.json({ error: `Unknown template: ${template}` }, 400);
|
|
6640
6310
|
}
|
|
6641
|
-
const UPGRADE_BRANCH = "upgrade";
|
|
6642
|
-
const upgradeVariantName = `${mindName}-upgrade`;
|
|
6643
|
-
const worktreeDir = resolve13(dir, ".variants", UPGRADE_BRANCH);
|
|
6644
6311
|
if (body.abort) {
|
|
6645
|
-
if (!
|
|
6312
|
+
if (!upgradeInProgress(mindName)) {
|
|
6646
6313
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
6647
6314
|
}
|
|
6648
6315
|
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
|
-
}
|
|
6316
|
+
await abortUpgrade(mindName);
|
|
6662
6317
|
return c.json({ ok: true });
|
|
6663
6318
|
} catch (err) {
|
|
6664
6319
|
return c.json(
|
|
@@ -6668,81 +6323,45 @@ ${user.trimEnd()}
|
|
|
6668
6323
|
}
|
|
6669
6324
|
}
|
|
6670
6325
|
if (body.continue) {
|
|
6671
|
-
if (!
|
|
6326
|
+
if (!upgradeInProgress(mindName)) {
|
|
6672
6327
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
6673
6328
|
}
|
|
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
6329
|
try {
|
|
6680
|
-
await
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
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
|
-
try {
|
|
6703
|
-
const result = await mergeUpgradeAndRestart(
|
|
6704
|
-
mindName,
|
|
6705
|
-
dir,
|
|
6706
|
-
worktreeDir,
|
|
6707
|
-
upgradeVariantName,
|
|
6708
|
-
UPGRADE_BRANCH,
|
|
6709
|
-
template,
|
|
6710
|
-
oldTemplate
|
|
6711
|
-
);
|
|
6712
|
-
return c.json(result);
|
|
6330
|
+
const result = await continueUpgrade(mindName, { template });
|
|
6331
|
+
if (result.status === "conflicts") {
|
|
6332
|
+
return c.json({
|
|
6333
|
+
ok: false,
|
|
6334
|
+
conflicts: true,
|
|
6335
|
+
worktreeDir: result.worktreeDir,
|
|
6336
|
+
files: result.files,
|
|
6337
|
+
message: result.message ?? "Merge conflicts detected. Resolve them, then run with continue."
|
|
6338
|
+
});
|
|
6339
|
+
}
|
|
6340
|
+
return c.json({ ok: true, warning: result.warning });
|
|
6713
6341
|
} catch (err) {
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6342
|
+
const msg = err instanceof Error ? err.message : "Failed to merge upgrade";
|
|
6343
|
+
if (msg === "Unresolved conflicts remain") {
|
|
6344
|
+
return c.json({ error: msg }, 409);
|
|
6345
|
+
}
|
|
6346
|
+
return c.json({ error: msg }, 500);
|
|
6718
6347
|
}
|
|
6719
6348
|
}
|
|
6720
6349
|
if (body.accept) {
|
|
6721
|
-
if (
|
|
6350
|
+
if (upgradeInProgress(mindName)) {
|
|
6722
6351
|
try {
|
|
6723
|
-
await
|
|
6352
|
+
await abortUpgrade(mindName);
|
|
6724
6353
|
} catch (err) {
|
|
6725
6354
|
logger_default.warn(`failed to clean up legacy upgrade variant for ${mindName}`, logger_default.errorData(err));
|
|
6726
6355
|
}
|
|
6727
|
-
try {
|
|
6728
|
-
await gitExec(["branch", "-D", UPGRADE_BRANCH], { cwd: dir });
|
|
6729
|
-
} catch {
|
|
6730
|
-
}
|
|
6731
6356
|
}
|
|
6732
6357
|
return c.json({ error: "Upgrades now auto-merge. Run 'volute mind upgrade' again." }, 400);
|
|
6733
6358
|
}
|
|
6734
6359
|
if (body.diff) {
|
|
6360
|
+
if (!existsSync7(resolve11(dir, ".git"))) {
|
|
6361
|
+
return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
|
|
6362
|
+
}
|
|
6735
6363
|
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
|
-
}
|
|
6364
|
+
const diff = await upgradeDiff(mindName, template);
|
|
6746
6365
|
return c.json({ ok: true, diff: diff || "(no changes)" });
|
|
6747
6366
|
} catch (err) {
|
|
6748
6367
|
return c.json(
|
|
@@ -6751,103 +6370,21 @@ ${user.trimEnd()}
|
|
|
6751
6370
|
);
|
|
6752
6371
|
}
|
|
6753
6372
|
}
|
|
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
6373
|
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
|
|
6374
|
+
const result = await runUpgrade(mindName, { template });
|
|
6375
|
+
if (result.status === "conflicts") {
|
|
6376
|
+
return c.json({
|
|
6377
|
+
ok: false,
|
|
6378
|
+
conflicts: true,
|
|
6379
|
+
worktreeDir: result.worktreeDir,
|
|
6380
|
+
files: result.files,
|
|
6381
|
+
message: result.message ?? "Merge conflicts detected. Resolve them, then run with continue."
|
|
6823
6382
|
});
|
|
6824
6383
|
}
|
|
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);
|
|
6384
|
+
return c.json({ ok: true, warning: result.warning });
|
|
6846
6385
|
} catch (err) {
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
} catch (cleanupErr) {
|
|
6850
|
-
logger_default.warn(`cleanup failed after upgrade error for ${mindName}`, logger_default.errorData(cleanupErr));
|
|
6386
|
+
if (err instanceof UpgradeInProgressError) {
|
|
6387
|
+
return c.json({ error: err.message }, 409);
|
|
6851
6388
|
}
|
|
6852
6389
|
return c.json({ error: err instanceof Error ? err.message : "Failed to merge upgrade" }, 500);
|
|
6853
6390
|
}
|
|
@@ -6915,11 +6452,11 @@ ${user.trimEnd()}
|
|
|
6915
6452
|
const entry = await findMind(name);
|
|
6916
6453
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6917
6454
|
const dir = entry.dir ?? mindDir(name);
|
|
6918
|
-
if (!
|
|
6455
|
+
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6919
6456
|
let config2 = readVoluteConfig(dir);
|
|
6920
6457
|
if (!config2 && entry.template === "pi") {
|
|
6921
|
-
const piConfigPath =
|
|
6922
|
-
if (
|
|
6458
|
+
const piConfigPath = resolve11(dir, "home/.config/config.json");
|
|
6459
|
+
if (existsSync7(piConfigPath)) {
|
|
6923
6460
|
try {
|
|
6924
6461
|
config2 = JSON.parse(readFileSync9(piConfigPath, "utf-8"));
|
|
6925
6462
|
} catch {
|
|
@@ -6927,8 +6464,8 @@ ${user.trimEnd()}
|
|
|
6927
6464
|
}
|
|
6928
6465
|
}
|
|
6929
6466
|
let templateConfig = {};
|
|
6930
|
-
const configJsonPath =
|
|
6931
|
-
if (
|
|
6467
|
+
const configJsonPath = resolve11(dir, "home/.config/config.json");
|
|
6468
|
+
if (existsSync7(configJsonPath)) {
|
|
6932
6469
|
try {
|
|
6933
6470
|
templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
|
|
6934
6471
|
} catch {
|
|
@@ -6970,7 +6507,7 @@ ${user.trimEnd()}
|
|
|
6970
6507
|
const entry = await findMind(name);
|
|
6971
6508
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6972
6509
|
const dir = entry.dir ?? mindDir(name);
|
|
6973
|
-
if (!
|
|
6510
|
+
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6974
6511
|
const body = c.req.valid("json");
|
|
6975
6512
|
const existing = readVoluteConfig(dir) ?? {};
|
|
6976
6513
|
if (body.model !== void 0) existing.model = body.model;
|
|
@@ -6996,14 +6533,14 @@ ${user.trimEnd()}
|
|
|
6996
6533
|
}
|
|
6997
6534
|
writeVoluteConfig(dir, existing);
|
|
6998
6535
|
if (body.unescapeNewlines !== void 0) {
|
|
6999
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
6536
|
+
const { clearEchoTextCache } = await import("./echo-text-73CYQRL7.js");
|
|
7000
6537
|
clearEchoTextCache(name);
|
|
7001
6538
|
}
|
|
7002
6539
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.compaction !== void 0;
|
|
7003
6540
|
if (needsConfigJson) {
|
|
7004
|
-
const configJsonPath =
|
|
6541
|
+
const configJsonPath = resolve11(dir, "home/.config/config.json");
|
|
7005
6542
|
let templateConfig = {};
|
|
7006
|
-
if (
|
|
6543
|
+
if (existsSync7(configJsonPath)) {
|
|
7007
6544
|
try {
|
|
7008
6545
|
templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
|
|
7009
6546
|
} catch {
|
|
@@ -7068,9 +6605,43 @@ ${user.trimEnd()}
|
|
|
7068
6605
|
if (err instanceof Error && err.message.includes("not initialized")) {
|
|
7069
6606
|
return c.json({ error: "Delivery manager not available" }, 503);
|
|
7070
6607
|
}
|
|
6608
|
+
if (err instanceof UnknownChannelError) return c.json({ error: err.message }, 400);
|
|
7071
6609
|
logger_default.error(`failed to decline channel ${channel} for ${name}`, logger_default.errorData(err));
|
|
7072
6610
|
return c.json({ error: "Failed to decline channel" }, 500);
|
|
7073
6611
|
}
|
|
6612
|
+
}).post("/:name/gates/accept", requireSelf(), async (c) => {
|
|
6613
|
+
const name = c.req.param("name");
|
|
6614
|
+
const body = await c.req.json().catch(() => ({}));
|
|
6615
|
+
const channel = body.channel?.trim();
|
|
6616
|
+
if (!channel) return c.json({ error: "channel required" }, 400);
|
|
6617
|
+
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
6618
|
+
try {
|
|
6619
|
+
const result = await getDeliveryManager().acceptChannel(name, channel, body.thread?.trim());
|
|
6620
|
+
return c.json({ ok: true, channel, ...result });
|
|
6621
|
+
} catch (err) {
|
|
6622
|
+
if (err instanceof Error && err.message.includes("not initialized")) {
|
|
6623
|
+
return c.json({ error: "Delivery manager not available" }, 503);
|
|
6624
|
+
}
|
|
6625
|
+
if (err instanceof Error && err.message.includes("malformed")) {
|
|
6626
|
+
return c.json({ error: err.message }, 409);
|
|
6627
|
+
}
|
|
6628
|
+
if (err instanceof UnknownChannelError) return c.json({ error: err.message }, 400);
|
|
6629
|
+
logger_default.error(`failed to accept channel ${channel} for ${name}`, logger_default.errorData(err));
|
|
6630
|
+
return c.json({ error: "Failed to accept channel" }, 500);
|
|
6631
|
+
}
|
|
6632
|
+
}).get("/:name/gates/peek", requireSelf(), async (c) => {
|
|
6633
|
+
const name = c.req.param("name");
|
|
6634
|
+
const channel = c.req.query("channel")?.trim();
|
|
6635
|
+
if (!channel) return c.json({ error: "channel required" }, 400);
|
|
6636
|
+
try {
|
|
6637
|
+
return c.json(await getDeliveryManager().peekChannel(name, channel));
|
|
6638
|
+
} catch (err) {
|
|
6639
|
+
if (err instanceof Error && err.message.includes("not initialized")) {
|
|
6640
|
+
return c.json({ error: "Delivery manager not available" }, 503);
|
|
6641
|
+
}
|
|
6642
|
+
logger_default.error(`failed to peek channel ${channel} for ${name}`, logger_default.errorData(err));
|
|
6643
|
+
return c.json({ error: "Failed to read held messages" }, 500);
|
|
6644
|
+
}
|
|
7074
6645
|
}).post("/:name/ai/complete", requireSelf(), async (c) => {
|
|
7075
6646
|
const body = await c.req.json();
|
|
7076
6647
|
if (!body.systemPrompt || !body.message) {
|
|
@@ -7840,7 +7411,7 @@ var app15 = new Hono18().get("/:name/clock/status", requireSelf(), async (c) =>
|
|
|
7840
7411
|
const entry = await findMind(name);
|
|
7841
7412
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
7842
7413
|
const body = await c.req.text();
|
|
7843
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
7414
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-Q7IVZ5T4.js");
|
|
7844
7415
|
const { id, delivered } = await deliverEvent2(name, {
|
|
7845
7416
|
type: "webhook",
|
|
7846
7417
|
body,
|
|
@@ -7858,14 +7429,14 @@ var schedules_default = app15;
|
|
|
7858
7429
|
// packages/daemon/src/web/api/setup.ts
|
|
7859
7430
|
import { mkdirSync as mkdirSync7, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "fs";
|
|
7860
7431
|
import { homedir as homedir2 } from "os";
|
|
7861
|
-
import { basename, resolve as
|
|
7432
|
+
import { basename, resolve as resolve12 } from "path";
|
|
7862
7433
|
import { Hono as Hono19 } from "hono";
|
|
7863
7434
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
7864
7435
|
var DEFAULT_API_URL2 = "https://volute.systems";
|
|
7865
7436
|
var setup = new Hono19();
|
|
7866
7437
|
function writeSetupConfig(systemName, description) {
|
|
7867
|
-
const configHome = process.env.VOLUTE_HOME ??
|
|
7868
|
-
const mindsDir =
|
|
7438
|
+
const configHome = process.env.VOLUTE_HOME ?? resolve12(homedir2(), ".volute");
|
|
7439
|
+
const mindsDir = resolve12(configHome, "minds");
|
|
7869
7440
|
mkdirSync7(configHome, { recursive: true });
|
|
7870
7441
|
mkdirSync7(mindsDir, { recursive: true });
|
|
7871
7442
|
const existingConfig = readGlobalConfig();
|
|
@@ -8200,7 +7771,7 @@ setup.post("/spirit", async (c) => {
|
|
|
8200
7771
|
config2.setup.spiritDescription = description || void 0;
|
|
8201
7772
|
const clearOldStash = () => {
|
|
8202
7773
|
if (config2.setup?.spiritAvatar) {
|
|
8203
|
-
rmSync4(
|
|
7774
|
+
rmSync4(resolve12(voluteSystemDir(), basename(config2.setup.spiritAvatar)), { force: true });
|
|
8204
7775
|
config2.setup.spiritAvatar = void 0;
|
|
8205
7776
|
}
|
|
8206
7777
|
};
|
|
@@ -8224,7 +7795,7 @@ setup.post("/spirit", async (c) => {
|
|
|
8224
7795
|
}
|
|
8225
7796
|
clearOldStash();
|
|
8226
7797
|
const filename = `spirit-avatar.${ext}`;
|
|
8227
|
-
writeFileSync9(
|
|
7798
|
+
writeFileSync9(resolve12(voluteSystemDir(), filename), bytes);
|
|
8228
7799
|
config2.setup.spiritAvatar = filename;
|
|
8229
7800
|
} else {
|
|
8230
7801
|
clearOldStash();
|
|
@@ -8237,15 +7808,16 @@ setup.post("/complete", async (c) => {
|
|
|
8237
7808
|
return c.json({ error: "Setup already complete" }, 400);
|
|
8238
7809
|
}
|
|
8239
7810
|
try {
|
|
8240
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
8241
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
7811
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-Q5VGFWUI.js");
|
|
7812
|
+
const { startSpiritFull } = await import("./mind-service-7EFIJ3ZA.js");
|
|
8242
7813
|
await ensureSpiritProject();
|
|
8243
7814
|
await syncSpiritTemplate();
|
|
7815
|
+
await notifyExtensionsSpiritReady();
|
|
8244
7816
|
const warnings = [];
|
|
8245
7817
|
const config2 = readGlobalConfig();
|
|
8246
7818
|
if (config2.setup?.service && config2.setup?.type === "local") {
|
|
8247
7819
|
try {
|
|
8248
|
-
const { installUserService } = await import("./service-install-
|
|
7820
|
+
const { installUserService } = await import("./service-install-R4SNYUVO.js");
|
|
8249
7821
|
const installed = await installUserService(config2.port, config2.hostname);
|
|
8250
7822
|
if (!installed) {
|
|
8251
7823
|
warnings.push("Service installation is not supported on this platform.");
|
|
@@ -8298,7 +7870,7 @@ setup.post("/complete", async (c) => {
|
|
|
8298
7870
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
8299
7871
|
if (spiritConversationId && spiritStarted) {
|
|
8300
7872
|
try {
|
|
8301
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
7873
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-TRKT4T2P.js");
|
|
8302
7874
|
const { listUsersByType: listUsers2 } = await import("./auth-KRDSM55Q.js");
|
|
8303
7875
|
const admins = await listUsers2("human");
|
|
8304
7876
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
@@ -8338,9 +7910,9 @@ setup.post("/complete", async (c) => {
|
|
|
8338
7910
|
var setup_default = setup;
|
|
8339
7911
|
|
|
8340
7912
|
// packages/daemon/src/web/api/skills.ts
|
|
8341
|
-
import { existsSync as
|
|
7913
|
+
import { existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
|
|
8342
7914
|
import { tmpdir } from "os";
|
|
8343
|
-
import { join, resolve as
|
|
7915
|
+
import { join, resolve as resolve13 } from "path";
|
|
8344
7916
|
import AdmZip from "adm-zip";
|
|
8345
7917
|
import { Hono as Hono20 } from "hono";
|
|
8346
7918
|
var app16 = new Hono20().get("/", async (c) => {
|
|
@@ -8416,19 +7988,19 @@ var app16 = new Hono20().get("/", async (c) => {
|
|
|
8416
7988
|
try {
|
|
8417
7989
|
const zip = new AdmZip(buffer);
|
|
8418
7990
|
for (const entry of zip.getEntries()) {
|
|
8419
|
-
const target =
|
|
7991
|
+
const target = resolve13(tmpDir, entry.entryName);
|
|
8420
7992
|
if (!target.startsWith(tmpDir)) {
|
|
8421
7993
|
return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
|
|
8422
7994
|
}
|
|
8423
7995
|
}
|
|
8424
7996
|
zip.extractAllTo(tmpDir, true);
|
|
8425
7997
|
let skillDir = null;
|
|
8426
|
-
if (
|
|
7998
|
+
if (existsSync8(join(tmpDir, "SKILL.md"))) {
|
|
8427
7999
|
skillDir = tmpDir;
|
|
8428
8000
|
} else {
|
|
8429
8001
|
const entries = readdirSync3(tmpDir, { withFileTypes: true }).filter((e) => e.isDirectory());
|
|
8430
8002
|
for (const entry of entries) {
|
|
8431
|
-
if (
|
|
8003
|
+
if (existsSync8(join(tmpDir, entry.name, "SKILL.md"))) {
|
|
8432
8004
|
skillDir = join(tmpDir, entry.name);
|
|
8433
8005
|
break;
|
|
8434
8006
|
}
|
|
@@ -8790,8 +8362,8 @@ var app20 = new Hono24().use("*", authMiddleware).get("/", async (c) => {
|
|
|
8790
8362
|
});
|
|
8791
8363
|
}, 15e3);
|
|
8792
8364
|
cleanups.push(() => clearInterval(keepAlive));
|
|
8793
|
-
await new Promise((
|
|
8794
|
-
stream.onAbort(() =>
|
|
8365
|
+
await new Promise((resolve19) => {
|
|
8366
|
+
stream.onAbort(() => resolve19());
|
|
8795
8367
|
});
|
|
8796
8368
|
} finally {
|
|
8797
8369
|
for (const cleanup of cleanups) {
|
|
@@ -9072,23 +8644,23 @@ var app21 = new Hono25().use("*", authMiddleware).get("/", async (c) => {
|
|
|
9072
8644
|
var feed_default = app21;
|
|
9073
8645
|
|
|
9074
8646
|
// packages/daemon/src/web/api/variants.ts
|
|
9075
|
-
import { existsSync as
|
|
9076
|
-
import { resolve as
|
|
8647
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync9, writeFileSync as writeFileSync10 } from "fs";
|
|
8648
|
+
import { resolve as resolve16 } from "path";
|
|
9077
8649
|
import { Hono as Hono26 } from "hono";
|
|
9078
8650
|
|
|
9079
8651
|
// packages/daemon/src/lib/mind/farewell.ts
|
|
9080
|
-
import { existsSync as
|
|
9081
|
-
import { resolve as
|
|
8652
|
+
import { existsSync as existsSync9, readFileSync as readFileSync10, rmSync as rmSync6 } from "fs";
|
|
8653
|
+
import { resolve as resolve14 } from "path";
|
|
9082
8654
|
var flog = logger_default.child("farewell");
|
|
9083
8655
|
var FAREWELL_RELPATH = ".mind/farewell.md";
|
|
9084
8656
|
var FAREWELL_MIND_PATH = "../.mind/farewell.md";
|
|
9085
8657
|
var FAREWELL_TIMEOUT_MS = 12e4;
|
|
9086
8658
|
function farewellPath(variantDir) {
|
|
9087
|
-
return
|
|
8659
|
+
return resolve14(variantDir, FAREWELL_RELPATH);
|
|
9088
8660
|
}
|
|
9089
8661
|
function readFarewell(variantDir) {
|
|
9090
8662
|
const path = farewellPath(variantDir);
|
|
9091
|
-
if (!
|
|
8663
|
+
if (!existsSync9(path)) return void 0;
|
|
9092
8664
|
try {
|
|
9093
8665
|
const text = readFileSync10(path, "utf-8").trim();
|
|
9094
8666
|
return text || void 0;
|
|
@@ -9111,7 +8683,7 @@ function waitForFarewell(name, variantDir, timeoutMs) {
|
|
|
9111
8683
|
const unsub = subscribe((event) => {
|
|
9112
8684
|
if (event.mind !== name) return;
|
|
9113
8685
|
if (event.type !== "mind_done" && event.type !== "mind_idle") return;
|
|
9114
|
-
if (
|
|
8686
|
+
if (existsSync9(farewellPath(variantDir))) cleanup();
|
|
9115
8687
|
});
|
|
9116
8688
|
return { done, cancel: cleanup };
|
|
9117
8689
|
}
|
|
@@ -9144,8 +8716,8 @@ async function runFarewellTurn(opts) {
|
|
|
9144
8716
|
|
|
9145
8717
|
// packages/daemon/src/lib/mind/spawn-server.ts
|
|
9146
8718
|
import { spawn as spawn4 } from "child_process";
|
|
9147
|
-
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync11, statSync as
|
|
9148
|
-
import { resolve as
|
|
8719
|
+
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
|
|
8720
|
+
import { resolve as resolve15 } from "path";
|
|
9149
8721
|
async function spawnServer(cwd, port, options) {
|
|
9150
8722
|
let cmd = process.env.VOLUTE_NODE_PATH ?? process.execPath;
|
|
9151
8723
|
let args = ["--import", "tsx", "src/server.ts", "--port", String(port)];
|
|
@@ -9166,34 +8738,34 @@ function spawnAttached(cmd, args, cwd) {
|
|
|
9166
8738
|
cwd,
|
|
9167
8739
|
stdio: ["ignore", "pipe", "pipe"]
|
|
9168
8740
|
});
|
|
9169
|
-
return new Promise((
|
|
9170
|
-
const timeout = setTimeout(() =>
|
|
8741
|
+
return new Promise((resolve19) => {
|
|
8742
|
+
const timeout = setTimeout(() => resolve19(null), 3e4);
|
|
9171
8743
|
function checkOutput(data) {
|
|
9172
8744
|
const match = data.toString().match(/listening on :(\d+)/);
|
|
9173
8745
|
if (match) {
|
|
9174
8746
|
clearTimeout(timeout);
|
|
9175
|
-
|
|
8747
|
+
resolve19({ child, actualPort: parseInt(match[1], 10) });
|
|
9176
8748
|
}
|
|
9177
8749
|
}
|
|
9178
8750
|
child.stdout?.on("data", checkOutput);
|
|
9179
8751
|
child.stderr?.on("data", checkOutput);
|
|
9180
8752
|
child.on("error", () => {
|
|
9181
8753
|
clearTimeout(timeout);
|
|
9182
|
-
|
|
8754
|
+
resolve19(null);
|
|
9183
8755
|
});
|
|
9184
8756
|
child.on("exit", () => {
|
|
9185
8757
|
clearTimeout(timeout);
|
|
9186
|
-
|
|
8758
|
+
resolve19(null);
|
|
9187
8759
|
});
|
|
9188
8760
|
});
|
|
9189
8761
|
}
|
|
9190
8762
|
function spawnDetached(cmd, args, cwd, logDir) {
|
|
9191
|
-
const logsDir = logDir ??
|
|
8763
|
+
const logsDir = logDir ?? resolve15(cwd, ".mind", "logs");
|
|
9192
8764
|
mkdirSync8(logsDir, { recursive: true });
|
|
9193
|
-
const logPath =
|
|
8765
|
+
const logPath = resolve15(logsDir, "mind.log");
|
|
9194
8766
|
let startOffset = 0;
|
|
9195
8767
|
try {
|
|
9196
|
-
startOffset =
|
|
8768
|
+
startOffset = statSync3(logPath).size;
|
|
9197
8769
|
} catch {
|
|
9198
8770
|
}
|
|
9199
8771
|
const logFd = openSync(logPath, "a");
|
|
@@ -9331,11 +8903,11 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9331
8903
|
return c.json({ error: `Name already in use: ${variantName}` }, 409);
|
|
9332
8904
|
}
|
|
9333
8905
|
const projectRoot = entry.dir ?? mindDir(mindName);
|
|
9334
|
-
const variantDir =
|
|
9335
|
-
if (
|
|
8906
|
+
const variantDir = resolve16(projectRoot, ".variants", variantName);
|
|
8907
|
+
if (existsSync10(variantDir)) {
|
|
9336
8908
|
return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
|
|
9337
8909
|
}
|
|
9338
|
-
mkdirSync9(
|
|
8910
|
+
mkdirSync9(resolve16(projectRoot, ".variants"), { recursive: true });
|
|
9339
8911
|
try {
|
|
9340
8912
|
await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
|
|
9341
8913
|
} catch (e) {
|
|
@@ -9371,7 +8943,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9371
8943
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
9372
8944
|
await exec(cmd, args, {
|
|
9373
8945
|
cwd: variantDir,
|
|
9374
|
-
env: { ...process.env, HOME:
|
|
8946
|
+
env: { ...process.env, HOME: resolve16(variantDir, "home") }
|
|
9375
8947
|
});
|
|
9376
8948
|
} else {
|
|
9377
8949
|
await exec("npm", ["install"], { cwd: variantDir });
|
|
@@ -9382,7 +8954,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9382
8954
|
return c.json({ error: `npm install failed: ${msg}` }, 500);
|
|
9383
8955
|
}
|
|
9384
8956
|
if (body.soul) {
|
|
9385
|
-
writeFileSync10(
|
|
8957
|
+
writeFileSync10(resolve16(variantDir, "home/SOUL.md"), body.soul);
|
|
9386
8958
|
}
|
|
9387
8959
|
const variantPort = body.port ?? await nextPort();
|
|
9388
8960
|
try {
|
|
@@ -9465,7 +9037,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9465
9037
|
logger_default.warn(`farewell turn failed for ${variantName}`, logger_default.errorData(err));
|
|
9466
9038
|
}
|
|
9467
9039
|
try {
|
|
9468
|
-
if (
|
|
9040
|
+
if (existsSync10(variantEntry.dir)) {
|
|
9469
9041
|
const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
|
|
9470
9042
|
if (status) {
|
|
9471
9043
|
try {
|
|
@@ -9523,7 +9095,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9523
9095
|
{ conflicts: err.conflicts }
|
|
9524
9096
|
);
|
|
9525
9097
|
}
|
|
9526
|
-
if (
|
|
9098
|
+
if (existsSync10(variantEntry.dir) && !body.discardUnresolved) {
|
|
9527
9099
|
let unresolved;
|
|
9528
9100
|
try {
|
|
9529
9101
|
unresolved = await findUnresolvedHomeFiles(variantEntry.dir);
|
|
@@ -9562,7 +9134,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9562
9134
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
9563
9135
|
await exec(cmd, args, {
|
|
9564
9136
|
cwd: projectRoot,
|
|
9565
|
-
env: { ...process.env, HOME:
|
|
9137
|
+
env: { ...process.env, HOME: resolve16(projectRoot, "home") }
|
|
9566
9138
|
});
|
|
9567
9139
|
} else {
|
|
9568
9140
|
await exec("npm", ["install"], { cwd: projectRoot });
|
|
@@ -10057,11 +9629,11 @@ var app24 = new Hono28().get("/:name/conversations/:id/events", async (c) => {
|
|
|
10057
9629
|
if (!stream.aborted) console.error("[chat] SSE ping error:", err);
|
|
10058
9630
|
});
|
|
10059
9631
|
}, 15e3);
|
|
10060
|
-
await new Promise((
|
|
9632
|
+
await new Promise((resolve19) => {
|
|
10061
9633
|
stream.onAbort(() => {
|
|
10062
9634
|
unsubscribe();
|
|
10063
9635
|
clearInterval(keepAlive);
|
|
10064
|
-
|
|
9636
|
+
resolve19();
|
|
10065
9637
|
});
|
|
10066
9638
|
});
|
|
10067
9639
|
});
|
|
@@ -10278,10 +9850,10 @@ app26.route("/api/conversations", conversations_default);
|
|
|
10278
9850
|
var app_default = app26;
|
|
10279
9851
|
|
|
10280
9852
|
// packages/daemon/src/web/server.ts
|
|
10281
|
-
import { existsSync as
|
|
9853
|
+
import { existsSync as existsSync11 } from "fs";
|
|
10282
9854
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
10283
9855
|
import { createServer as createHttpsServer } from "https";
|
|
10284
|
-
import { dirname as dirname3, extname as extname3, resolve as
|
|
9856
|
+
import { dirname as dirname3, extname as extname3, resolve as resolve17 } from "path";
|
|
10285
9857
|
import { serve } from "@hono/node-server";
|
|
10286
9858
|
var MIME_TYPES2 = {
|
|
10287
9859
|
".html": "text/html",
|
|
@@ -10300,8 +9872,8 @@ async function startServer({
|
|
|
10300
9872
|
let assetsDir = "";
|
|
10301
9873
|
let searchDir = dirname3(new URL(import.meta.url).pathname);
|
|
10302
9874
|
for (let i = 0; i < 5; i++) {
|
|
10303
|
-
const candidate =
|
|
10304
|
-
if (
|
|
9875
|
+
const candidate = resolve17(searchDir, "dist", "web-assets");
|
|
9876
|
+
if (existsSync11(candidate)) {
|
|
10305
9877
|
assetsDir = candidate;
|
|
10306
9878
|
break;
|
|
10307
9879
|
}
|
|
@@ -10311,7 +9883,7 @@ async function startServer({
|
|
|
10311
9883
|
app_default.get("*", async (c) => {
|
|
10312
9884
|
const urlPath = new URL(c.req.url).pathname;
|
|
10313
9885
|
if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
|
|
10314
|
-
const filePath =
|
|
9886
|
+
const filePath = resolve17(assetsDir, urlPath.slice(1));
|
|
10315
9887
|
if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
|
|
10316
9888
|
const s = await stat2(filePath).catch(() => null);
|
|
10317
9889
|
if (s?.isFile()) {
|
|
@@ -10324,7 +9896,7 @@ async function startServer({
|
|
|
10324
9896
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
10325
9897
|
return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
|
|
10326
9898
|
}
|
|
10327
|
-
const indexPath =
|
|
9899
|
+
const indexPath = resolve17(assetsDir, "index.html");
|
|
10328
9900
|
const indexStat = await stat2(indexPath).catch(() => null);
|
|
10329
9901
|
if (indexStat?.isFile()) {
|
|
10330
9902
|
const body = await readFile2(indexPath, "utf-8");
|
|
@@ -10341,10 +9913,10 @@ async function startServer({
|
|
|
10341
9913
|
createServer: createHttpsServer,
|
|
10342
9914
|
serverOptions: { key: tls.key, cert: tls.cert }
|
|
10343
9915
|
});
|
|
10344
|
-
await new Promise((
|
|
9916
|
+
await new Promise((resolve19, reject) => {
|
|
10345
9917
|
server2.on("listening", () => {
|
|
10346
9918
|
logger_default.info("Volute UI running (https)", { hostname, port });
|
|
10347
|
-
|
|
9919
|
+
resolve19();
|
|
10348
9920
|
});
|
|
10349
9921
|
server2.on("error", (err) => {
|
|
10350
9922
|
reject(err);
|
|
@@ -10352,13 +9924,13 @@ async function startServer({
|
|
|
10352
9924
|
});
|
|
10353
9925
|
const internalPort = port + 1;
|
|
10354
9926
|
const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
|
|
10355
|
-
await new Promise((
|
|
9927
|
+
await new Promise((resolve19, reject) => {
|
|
10356
9928
|
internalServer.on("listening", () => {
|
|
10357
9929
|
logger_default.info("Volute API running (http, internal)", {
|
|
10358
9930
|
hostname: "127.0.0.1",
|
|
10359
9931
|
port: internalPort
|
|
10360
9932
|
});
|
|
10361
|
-
|
|
9933
|
+
resolve19();
|
|
10362
9934
|
});
|
|
10363
9935
|
internalServer.on("error", (err) => {
|
|
10364
9936
|
reject(err);
|
|
@@ -10367,10 +9939,10 @@ async function startServer({
|
|
|
10367
9939
|
return { server: server2, internalPort };
|
|
10368
9940
|
}
|
|
10369
9941
|
const server = serve({ fetch: app_default.fetch, port, hostname });
|
|
10370
|
-
await new Promise((
|
|
9942
|
+
await new Promise((resolve19, reject) => {
|
|
10371
9943
|
server.on("listening", () => {
|
|
10372
9944
|
logger_default.info("Volute API running (http)", { hostname, port });
|
|
10373
|
-
|
|
9945
|
+
resolve19();
|
|
10374
9946
|
});
|
|
10375
9947
|
server.on("error", (err) => {
|
|
10376
9948
|
reject(err);
|
|
@@ -10381,17 +9953,17 @@ async function startServer({
|
|
|
10381
9953
|
|
|
10382
9954
|
// packages/daemon/src/daemon.ts
|
|
10383
9955
|
if (!process.env.VOLUTE_HOME) {
|
|
10384
|
-
process.env.VOLUTE_HOME =
|
|
9956
|
+
process.env.VOLUTE_HOME = resolve18(homedir3(), ".volute");
|
|
10385
9957
|
}
|
|
10386
9958
|
if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
|
|
10387
9959
|
process.env.TZ = process.env.VOLUTE_TIMEZONE;
|
|
10388
9960
|
}
|
|
10389
9961
|
function writeDaemonConfig(systemDir, config2, token) {
|
|
10390
|
-
const configPath =
|
|
9962
|
+
const configPath = resolve18(systemDir, "daemon.json");
|
|
10391
9963
|
writeFileSync11(configPath, `${JSON.stringify(config2, null, 2)}
|
|
10392
9964
|
`, { mode: 420 });
|
|
10393
9965
|
chmodSync(configPath, 420);
|
|
10394
|
-
const tokenPath =
|
|
9966
|
+
const tokenPath = resolve18(systemDir, "daemon-token");
|
|
10395
9967
|
writeFileSync11(tokenPath, `${token}
|
|
10396
9968
|
`, { mode: 384 });
|
|
10397
9969
|
chmodSync(tokenPath, 384);
|
|
@@ -10402,7 +9974,7 @@ async function startDaemon(opts) {
|
|
|
10402
9974
|
const home = voluteHome();
|
|
10403
9975
|
const systemDir = voluteSystemDir();
|
|
10404
9976
|
if (!opts.foreground) {
|
|
10405
|
-
const rotatingLog = new RotatingLog(
|
|
9977
|
+
const rotatingLog = new RotatingLog(resolve18(systemDir, "daemon.log"));
|
|
10406
9978
|
logger_default.setOutput((line) => rotatingLog.write(`${line}
|
|
10407
9979
|
`));
|
|
10408
9980
|
const write = (...args) => rotatingLog.write(`${format(...args)}
|
|
@@ -10412,9 +9984,9 @@ async function startDaemon(opts) {
|
|
|
10412
9984
|
console.warn = write;
|
|
10413
9985
|
console.info = write;
|
|
10414
9986
|
}
|
|
10415
|
-
const DAEMON_PID_PATH =
|
|
10416
|
-
const DAEMON_JSON_PATH =
|
|
10417
|
-
const DAEMON_TOKEN_PATH =
|
|
9987
|
+
const DAEMON_PID_PATH = resolve18(systemDir, "daemon.pid");
|
|
9988
|
+
const DAEMON_JSON_PATH = resolve18(systemDir, "daemon.json");
|
|
9989
|
+
const DAEMON_TOKEN_PATH = resolve18(systemDir, "daemon-token");
|
|
10418
9990
|
mkdirSync10(home, { recursive: true });
|
|
10419
9991
|
ensureSystemDir();
|
|
10420
9992
|
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-WZSXHHRJ.js");
|
|
@@ -10443,6 +10015,12 @@ async function startDaemon(opts) {
|
|
|
10443
10015
|
} catch (err) {
|
|
10444
10016
|
logger_default.warn("session\u2192thread config migration failed", logger_default.errorData(err));
|
|
10445
10017
|
}
|
|
10018
|
+
try {
|
|
10019
|
+
const { migrateNamePlaceholders } = await import("./migrate-name-placeholder-C7NCNLWF.js");
|
|
10020
|
+
await migrateNamePlaceholders();
|
|
10021
|
+
} catch (err) {
|
|
10022
|
+
logger_default.warn("{{name}} placeholder migration failed", logger_default.errorData(err));
|
|
10023
|
+
}
|
|
10446
10024
|
const { initSandbox } = await import("./sandbox-NNWCTHRI.js");
|
|
10447
10025
|
await initSandbox();
|
|
10448
10026
|
try {
|
|
@@ -10543,7 +10121,7 @@ async function startDaemon(opts) {
|
|
|
10543
10121
|
const orphanedTurns = await completeOrphanedTurns();
|
|
10544
10122
|
summarizeOrphanedTurns(orphanedTurns);
|
|
10545
10123
|
try {
|
|
10546
|
-
const { reconcileVariants } = await import("./variant-cleanup-
|
|
10124
|
+
const { reconcileVariants } = await import("./variant-cleanup-QHGGY7ND.js");
|
|
10547
10125
|
await reconcileVariants();
|
|
10548
10126
|
} catch (err) {
|
|
10549
10127
|
logger_default.error("failed to reconcile variants", logger_default.errorData(err));
|
|
@@ -10579,16 +10157,17 @@ async function startDaemon(opts) {
|
|
|
10579
10157
|
try {
|
|
10580
10158
|
const { isSetupComplete: isSetupComplete2, getSpiritName: getSpiritName2 } = await import("./setup-WZSXHHRJ.js");
|
|
10581
10159
|
if (isSetupComplete2()) {
|
|
10582
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
10583
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
10160
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-Q5VGFWUI.js");
|
|
10161
|
+
const { startSpiritFull } = await import("./mind-service-7EFIJ3ZA.js");
|
|
10584
10162
|
await ensureSpiritProject();
|
|
10585
10163
|
const spiritName = getSpiritName2();
|
|
10586
10164
|
const spiritEntry = await findMind(spiritName);
|
|
10587
10165
|
if (spiritEntry?.dir) {
|
|
10588
|
-
const { registerMindDir } = await import("./delivery-router-
|
|
10166
|
+
const { registerMindDir } = await import("./delivery-router-QS4NLJR6.js");
|
|
10589
10167
|
registerMindDir(spiritName, spiritEntry.dir);
|
|
10590
10168
|
}
|
|
10591
10169
|
await syncSpiritTemplate();
|
|
10170
|
+
if (spiritEntry) await notifyExtensionsSpiritReady();
|
|
10592
10171
|
if (spiritEntry && !manager.isRunning(spiritName)) {
|
|
10593
10172
|
await startSpiritFull(spiritName);
|
|
10594
10173
|
}
|
|
@@ -10599,7 +10178,7 @@ async function startDaemon(opts) {
|
|
|
10599
10178
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
10600
10179
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
10601
10180
|
});
|
|
10602
|
-
import("./cloud-sync-
|
|
10181
|
+
import("./cloud-sync-52YNJRMR.js").then(
|
|
10603
10182
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
10604
10183
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
10605
10184
|
})
|
|
@@ -10607,12 +10186,14 @@ async function startDaemon(opts) {
|
|
|
10607
10186
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
10608
10187
|
});
|
|
10609
10188
|
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
|
-
});
|
|
10189
|
+
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-VNVFX6UP.js");
|
|
10614
10190
|
notifyVersionUpdate().catch((err) => {
|
|
10615
10191
|
logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
|
|
10192
|
+
}).then(() => backfillTemplateHashes()).then(() => warnStaleTemplates()).then(async () => {
|
|
10193
|
+
const { runAutoUpgrades } = await import("./auto-upgrade-HEVZKPTF.js");
|
|
10194
|
+
await runAutoUpgrades();
|
|
10195
|
+
}).catch((err) => {
|
|
10196
|
+
logger_default.warn("template staleness/auto-upgrade pass failed", logger_default.errorData(err));
|
|
10616
10197
|
});
|
|
10617
10198
|
} catch (err) {
|
|
10618
10199
|
logger_default.warn("failed to initialize version notifications", logger_default.errorData(err));
|
|
@@ -10621,6 +10202,9 @@ async function startDaemon(opts) {
|
|
|
10621
10202
|
logger_default.warn("failed to restore delivery queue", logger_default.errorData(err));
|
|
10622
10203
|
});
|
|
10623
10204
|
delivery.startRedrive();
|
|
10205
|
+
delivery.releaseGatedSweep().catch((err) => {
|
|
10206
|
+
logger_default.warn("failed to sweep gated messages", logger_default.errorData(err));
|
|
10207
|
+
});
|
|
10624
10208
|
cleanExpiredSessions().catch((err) => {
|
|
10625
10209
|
logger_default.warn("failed to clean expired sessions", logger_default.errorData(err));
|
|
10626
10210
|
});
|