volute 0.50.0 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activity-events-H7YI3BTF.js → activity-events-LQII6PZS.js} +3 -3
- package/dist/{ai-service-V4CTNGI3.js → ai-service-YW5SWCSB.js} +7 -3
- package/dist/{archive-ORM3ENHI.js → archive-FOHGXHPT.js} +3 -3
- package/dist/{auth-DT7GY7EZ.js → auth-KRDSM55Q.js} +6 -4
- package/dist/{avatar-image-QEPAP3A5.js → avatar-image-52WGXLHV.js} +3 -3
- package/dist/{backup-IE6PMXJO.js → backup-YVGV2ZNM.js} +7 -7
- package/dist/{chat-W5K6HCBE.js → chat-VAZ25KVT.js} +4 -4
- package/dist/{chunk-5IIVOWSP.js → chunk-2RNMBXD2.js} +16 -0
- package/dist/{chunk-U3EJJ7JN.js → chunk-5N32EN4O.js} +2 -2
- package/dist/{chunk-ZUG76D3P.js → chunk-5Y54AE3L.js} +1 -1
- package/dist/{chunk-5FVANDON.js → chunk-6NLW72HP.js} +2 -2
- package/dist/{chunk-ALIVXDM4.js → chunk-724DVYHU.js} +95 -51
- package/dist/{chunk-UC6BNMGT.js → chunk-7LT3YZUR.js} +15 -3
- package/dist/{chunk-PW65BXY5.js → chunk-7YJY3F2R.js} +11 -1
- package/dist/{chunk-7OZWKHA3.js → chunk-AXFLY5GU.js} +28 -5
- package/dist/{chunk-SSNZ6ZNN.js → chunk-CV6BNGFK.js} +3 -3
- package/dist/{chunk-MLZBBLMT.js → chunk-CW7BQKF6.js} +4 -4
- package/dist/{chunk-QFVGPKJI.js → chunk-DMK5ASKV.js} +1 -1
- package/dist/{chunk-WBBKYUGF.js → chunk-EDR47UE2.js} +2 -2
- package/dist/{chunk-632FJ23O.js → chunk-EGV6R6UF.js} +26 -7
- package/dist/{chunk-KAEZOVP6.js → chunk-FLIEXG2T.js} +1 -1
- package/dist/{chunk-5TPC4KCV.js → chunk-FXWBFDQR.js} +2 -2
- package/dist/{chunk-74T3CEXK.js → chunk-G7A5LEVI.js} +2 -2
- package/dist/{chunk-7UWXAJMK.js → chunk-GLM7TVWP.js} +1 -1
- package/dist/{chunk-CAIYV33P.js → chunk-H6X6CKDN.js} +2 -1
- package/dist/{chunk-C3KLHJDB.js → chunk-HTRSSOHY.js} +1 -1
- package/dist/{chunk-77IZUVBB.js → chunk-I7U5EEZC.js} +2 -2
- package/dist/{chunk-X67VT4QO.js → chunk-ICXY54ZC.js} +1 -1
- package/dist/{chunk-HW6Q7AMB.js → chunk-ITK6HV47.js} +6 -7
- package/dist/{chunk-5PKFJHCR.js → chunk-JHKBALS2.js} +2 -2
- package/dist/{chunk-SFRYRW37.js → chunk-K2F237KS.js} +9 -9
- package/dist/{chunk-7XDOTN4R.js → chunk-L7BKTZ5U.js} +1 -1
- package/dist/{chunk-AFSLNUTT.js → chunk-LAUCO2HC.js} +1 -1
- package/dist/{chunk-AJWFDIEY.js → chunk-M77B73VV.js} +1 -1
- package/dist/{chunk-4CN7OCJE.js → chunk-OXWUEU5V.js} +2 -2
- package/dist/{chunk-TGJHGVBZ.js → chunk-RPPTGPYF.js} +4 -4
- package/dist/{chunk-JI67D7O2.js → chunk-RU74YG46.js} +120 -25
- package/dist/{chunk-7FDWPQCU.js → chunk-SW2U6HRB.js} +6 -6
- package/dist/{chunk-574M6I7F.js → chunk-TPX6E6PL.js} +3 -3
- package/dist/{chunk-3BAFMGCJ.js → chunk-U54PJPTB.js} +2 -2
- package/dist/{chunk-6BM2I736.js → chunk-UDZLPR34.js} +1 -1
- package/dist/{chunk-E5S3ILVA.js → chunk-UFTDRTCP.js} +1 -1
- package/dist/{chunk-YQOYZ6G7.js → chunk-VPOMJMV6.js} +2 -2
- package/dist/{chunk-RRZ4RQQU.js → chunk-X67BDDZR.js} +5 -7
- package/dist/{chunk-636GFQNE.js → chunk-XRWUQPCA.js} +8 -7
- package/dist/{chunk-7DXLIYPY.js → chunk-YVR6EHWL.js} +6 -6
- package/dist/{chunk-EQKSRVDE.js → chunk-ZEZQNP2G.js} +113 -49
- package/dist/cli.js +19 -19
- package/dist/{clock-LH7UFNLJ.js → clock-ZT5YT6HA.js} +2 -2
- package/dist/{cloud-sync-IDJFVDEP.js → cloud-sync-H7EWZASD.js} +22 -22
- package/dist/{conversations-S2232Y5I.js → conversations-ZL6PHROD.js} +4 -4
- package/dist/{create-2M7DAHQX.js → create-G2RIKQYK.js} +1 -1
- package/dist/{daemon-restart-2AAGYFHE.js → daemon-restart-4FWUA5JF.js} +6 -6
- package/dist/daemon.js +622 -340
- package/dist/{db-QAY45Z56.js → db-BONH4SUG.js} +2 -2
- package/dist/{delete-O7PEFQDF.js → delete-CYVZUAV2.js} +4 -0
- package/dist/delivery-manager-VYXVKUMP.js +35 -0
- package/dist/{delivery-router-JE7SHYNU.js → delivery-router-RHANNTAC.js} +3 -3
- package/dist/{down-D4IRNEMJ.js → down-QSNEMTTX.js} +5 -5
- package/dist/echo-text-PEEV7FQU.js +39 -0
- package/dist/{env-ABM5IMA7.js → env-IBW2QI6K.js} +1 -1
- package/dist/{env-AZK5X4W7.js → env-SQFCWW52.js} +3 -3
- package/dist/{exec-2H65LMTA.js → exec-ABD3DYA2.js} +3 -3
- package/dist/{export-3E3EL6W3.js → export-VBNWM7I4.js} +3 -3
- package/dist/{extensions-7KP3X6G7.js → extensions-N6L5NYTK.js} +22 -22
- package/dist/{files-6BMKVG5G.js → files-BRY5RRIM.js} +3 -3
- package/dist/{import-UPNTEBBT.js → import-DB2KULRO.js} +6 -6
- package/dist/{isolation-OKDFM6WA.js → isolation-GVV2IBAU.js} +3 -3
- package/dist/{join-PYA36HEC.js → join-KLRU72JJ.js} +10 -2
- package/dist/{list-4BVGH7AN.js → list-UQGIW7OF.js} +1 -1
- package/dist/{login-MOXVLULE.js → login-SB5OENMV.js} +2 -2
- package/dist/{logout-DWD3OQVT.js → logout-YFZAJRPY.js} +2 -2
- package/dist/message-delivery-7URC52ME.js +43 -0
- package/dist/{migrate-thread-config-4A5LW36Z.js → migrate-thread-config-EQSEP2XG.js} +2 -2
- package/dist/{mind-NYRALSV2.js → mind-NEXGT3KE.js} +9 -9
- package/dist/{mind-activity-tracker-L7GCYXQR.js → mind-activity-tracker-QF6DCX2X.js} +4 -4
- package/dist/{mind-history-NXXOOTX6.js → mind-history-OGNR4L7W.js} +1 -1
- package/dist/mind-service-E26ZQXDS.js +47 -0
- package/dist/{mind-sleep-TH6BRQ5X.js → mind-sleep-LZAFBDZD.js} +2 -2
- package/dist/{package-XYSV7NUT.js → package-2W2XKSIP.js} +2 -2
- package/dist/{prompts-QKFPX6DQ.js → prompts-NBO3HRK3.js} +3 -3
- package/dist/{read-ZXGUT4QC.js → read-RJ5NAW5J.js} +3 -14
- package/dist/{registry-4UF6OCOE.js → registry-TRC2HJXR.js} +2 -2
- package/dist/{sandbox-EGEU5GGE.js → sandbox-NNWCTHRI.js} +3 -3
- package/dist/scheduler-JTTWZDYU.js +25 -0
- package/dist/{schema-C2GIPD4V.js → schema-ZZQVM4GR.js} +3 -1
- package/dist/{seed-3IMBOAGK.js → seed-64XEHRUP.js} +1 -1
- package/dist/{seed-cmd-U73XVQMI.js → seed-cmd-UEL2QB3Q.js} +2 -2
- package/dist/{seed-create-FBLNVSUP.js → seed-create-4JRQDPGA.js} +3 -3
- package/dist/{seed-readiness-QRA46ZJQ.js → seed-readiness-DYOVCYHN.js} +4 -4
- package/dist/{seed-sprout-3B4SZX7J.js → seed-sprout-NIDIOJXT.js} +7 -7
- package/dist/{send-NBRZJXKX.js → send-2YKOZJJ5.js} +81 -49
- package/dist/{service-XMXAXGJD.js → service-XQPMZAGI.js} +4 -4
- package/dist/{service-install-MOKTEG7B.js → service-install-2EWD7KXD.js} +5 -5
- package/dist/{setup-JGYAXXW7.js → setup-4IX6PCD3.js} +6 -6
- package/dist/{setup-CAJFOR2N.js → setup-WZSXHHRJ.js} +2 -2
- package/dist/{skill-NXIHDQCG.js → skill-B5OJEQUA.js} +1 -1
- package/dist/skills/volute-mind/references/variants.md +1 -1
- package/dist/{skills-5MSMT7PT.js → skills-MPUALV3S.js} +4 -4
- package/dist/sleep-manager-OFP2GFXF.js +41 -0
- package/dist/{spirit-IL5EMWYZ.js → spirit-4ECYIVGE.js} +7 -7
- package/dist/spirit-availability-Y54Y3675.js +42 -0
- package/dist/{sprout-UPXGJ5HX.js → sprout-GJMZFRGZ.js} +1 -1
- package/dist/{status-IL67CYM4.js → status-MWLE3RVC.js} +5 -5
- package/dist/{system-events-A6IGCEC3.js → system-events-V43HDA3T.js} +5 -3
- package/dist/{tailscale-SJUW2ETR.js → tailscale-KHNZFC7L.js} +2 -2
- package/dist/{template-hash-GSOUARW4.js → template-hash-YKWMVYMM.js} +2 -2
- package/dist/{template-staleness-T27VCGYA.js → template-staleness-PY2CULH6.js} +5 -5
- package/dist/{turn-tracker-6EI2EL7G.js → turn-tracker-C5PVIC3B.js} +5 -5
- package/dist/{up-CLL4665A.js → up-H6LJZDRK.js} +5 -5
- package/dist/{update-HVAUCQPN.js → update-CIWI2JYA.js} +5 -5
- package/dist/{update-check-2MGBBAFF.js → update-check-SZ7B5IFI.js} +3 -3
- package/dist/variant-cleanup-STC6B5HR.js +22 -0
- package/dist/{version-notify-7BUHWZNT.js → version-notify-LBVHH5YV.js} +8 -8
- package/dist/web-assets/assets/index-B_eYTa3R.js +97 -0
- package/dist/web-assets/assets/index-DhZrzddW.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0018_api_tokens.sql +20 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +2 -2
- package/templates/_base/{biome.json.tmpl → biome.json} +2 -1
- package/templates/_base/gitignore +44 -0
- package/templates/_base/home/public/.gitkeep +0 -0
- package/templates/_base/src/lib/auto-commit.ts +49 -11
- package/templates/_base/src/lib/format-prefix.ts +15 -8
- package/templates/_base/src/lib/router.ts +13 -8
- package/templates/claude/volute-template.json +1 -3
- package/templates/codex/volute-template.json +1 -3
- package/templates/pi/{package.json.tmpl → package.json} +2 -2
- package/templates/pi/volute-template.json +1 -3
- package/dist/delivery-manager-B4OKWD2P.js +0 -33
- package/dist/echo-text-WYAAODBV.js +0 -39
- package/dist/message-delivery-3456PXB7.js +0 -43
- package/dist/mind-service-5TA7UJAT.js +0 -47
- package/dist/scheduler-UV6RUJ7P.js +0 -25
- package/dist/sleep-manager-LIEPO6WG.js +0 -41
- package/dist/spirit-availability-YFEGJNJ2.js +0 -42
- package/dist/variant-cleanup-HJ7Z75R6.js +0 -22
- package/dist/web-assets/assets/index-ClsUcXiW.js +0 -95
- package/dist/web-assets/assets/index-Dz3wTbtR.css +0 -1
- /package/templates/_base/home/.config/{config.json.tmpl → config.json} +0 -0
- /package/templates/claude/{package.json.tmpl → package.json} +0 -0
- /package/templates/codex/home/.config/{config.json.tmpl → config.json} +0 -0
- /package/templates/codex/{package.json.tmpl → package.json} +0 -0
- /package/templates/pi/home/.config/{config.json.tmpl → config.json} +0 -0
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-EDR47UE2.js";
|
|
10
10
|
import {
|
|
11
11
|
acceptPending,
|
|
12
12
|
formatFileSize,
|
|
@@ -14,44 +14,44 @@ import {
|
|
|
14
14
|
rejectPending,
|
|
15
15
|
stageFile,
|
|
16
16
|
validateFilePath
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-DMK5ASKV.js";
|
|
18
18
|
import {
|
|
19
19
|
findOpenClawSession,
|
|
20
20
|
importOpenClawConnectors,
|
|
21
21
|
importPiSession,
|
|
22
22
|
parseNameFromIdentity
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-I7U5EEZC.js";
|
|
24
24
|
import {
|
|
25
25
|
SPIRIT_NOTICE_PREFIX,
|
|
26
26
|
ensureSpiritAvailable
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-CW7BQKF6.js";
|
|
28
28
|
import {
|
|
29
29
|
isHomeOnlyArchive
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-FLIEXG2T.js";
|
|
31
31
|
import {
|
|
32
32
|
evaluateSeedChecklist
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-JHKBALS2.js";
|
|
34
34
|
import {
|
|
35
35
|
isTemplateStale
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-CV6BNGFK.js";
|
|
37
37
|
import {
|
|
38
38
|
computeTemplateHash
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-HTRSSOHY.js";
|
|
40
40
|
import {
|
|
41
41
|
cleanupVariant
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-ITK6HV47.js";
|
|
43
43
|
import {
|
|
44
44
|
checkForUpdate,
|
|
45
45
|
checkForUpdateCached,
|
|
46
46
|
getCurrentVersion
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-LAUCO2HC.js";
|
|
48
48
|
import {
|
|
49
49
|
PLATFORMS,
|
|
50
50
|
echoTextToChannel,
|
|
51
51
|
fixModelEscapes,
|
|
52
52
|
getPlatformDriver,
|
|
53
53
|
routeOutboundBridge
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-XRWUQPCA.js";
|
|
55
55
|
import {
|
|
56
56
|
getBridgeConfig,
|
|
57
57
|
readBridgesConfig,
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
resolveChannelMapping,
|
|
61
61
|
setBridgeConfig,
|
|
62
62
|
setChannelMapping
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-L7BKTZ5U.js";
|
|
64
64
|
import {
|
|
65
65
|
SESSION_MAX_AGE,
|
|
66
66
|
announceSprout,
|
|
@@ -86,9 +86,11 @@ import {
|
|
|
86
86
|
installNpmExtension,
|
|
87
87
|
invalidateMindUserCache,
|
|
88
88
|
invalidateSessionCache,
|
|
89
|
+
issueApiToken,
|
|
89
90
|
joinSystemChannel,
|
|
90
91
|
joinSystemChannelForMind,
|
|
91
92
|
linkToolResultToTurn,
|
|
93
|
+
listApiTokens,
|
|
92
94
|
loadAllExtensions,
|
|
93
95
|
notifyExtensionsDaemonStart,
|
|
94
96
|
notifyExtensionsDaemonStop,
|
|
@@ -97,13 +99,14 @@ import {
|
|
|
97
99
|
requireAdmin,
|
|
98
100
|
requireAdminOrSystem,
|
|
99
101
|
requireSelf,
|
|
102
|
+
revokeApiToken,
|
|
100
103
|
setExtensionEnabled,
|
|
101
104
|
startMindFull,
|
|
102
105
|
stopMindFull,
|
|
103
106
|
uninstallNpmExtension,
|
|
104
107
|
writeSystemsConfig
|
|
105
|
-
} from "./chunk-
|
|
106
|
-
import "./chunk-
|
|
108
|
+
} from "./chunk-ZEZQNP2G.js";
|
|
109
|
+
import "./chunk-K2F237KS.js";
|
|
107
110
|
import {
|
|
108
111
|
applyInitFiles,
|
|
109
112
|
applyTemplateHomeFiles,
|
|
@@ -112,11 +115,11 @@ import {
|
|
|
112
115
|
findTemplatesRoot,
|
|
113
116
|
isKnownTemplate,
|
|
114
117
|
listFiles
|
|
115
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-X67BDDZR.js";
|
|
116
119
|
import {
|
|
117
120
|
getScheduler,
|
|
118
121
|
initScheduler
|
|
119
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-SW2U6HRB.js";
|
|
120
123
|
import {
|
|
121
124
|
checkStaleSend,
|
|
122
125
|
formatHoldNotice,
|
|
@@ -125,7 +128,7 @@ import {
|
|
|
125
128
|
initDeliveryManager,
|
|
126
129
|
isConversationId,
|
|
127
130
|
publishTypingForChannels
|
|
128
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-RU74YG46.js";
|
|
129
132
|
import {
|
|
130
133
|
MindStartupError,
|
|
131
134
|
RestartTracker,
|
|
@@ -135,10 +138,10 @@ import {
|
|
|
135
138
|
initMindManager,
|
|
136
139
|
syncProviderToMinds,
|
|
137
140
|
tryGetMindManager
|
|
138
|
-
} from "./chunk-
|
|
141
|
+
} from "./chunk-724DVYHU.js";
|
|
139
142
|
import {
|
|
140
143
|
extractTextContent
|
|
141
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-UDZLPR34.js";
|
|
142
145
|
import {
|
|
143
146
|
SYSTEM_MIND,
|
|
144
147
|
assignSession,
|
|
@@ -158,7 +161,7 @@ import {
|
|
|
158
161
|
takeErrored,
|
|
159
162
|
trackToolUse,
|
|
160
163
|
utcDateTimeStr
|
|
161
|
-
} from "./chunk-
|
|
164
|
+
} from "./chunk-YVR6EHWL.js";
|
|
162
165
|
import {
|
|
163
166
|
SEED_SKILLS,
|
|
164
167
|
STANDARD_SKILLS,
|
|
@@ -180,12 +183,13 @@ import {
|
|
|
180
183
|
syncBuiltinSkills,
|
|
181
184
|
uninstallSkill,
|
|
182
185
|
updateSkill
|
|
183
|
-
} from "./chunk-
|
|
186
|
+
} from "./chunk-RPPTGPYF.js";
|
|
184
187
|
import {
|
|
185
188
|
approveUser,
|
|
186
189
|
changePassword,
|
|
187
190
|
countAdmins,
|
|
188
191
|
createUser,
|
|
192
|
+
deleteExternalMindUser,
|
|
189
193
|
deleteMindUser as deleteMindUser2,
|
|
190
194
|
deleteUser,
|
|
191
195
|
getDisplayNames,
|
|
@@ -201,9 +205,10 @@ import {
|
|
|
201
205
|
updateUserProfile,
|
|
202
206
|
verifyUser,
|
|
203
207
|
withSenderDisplayNames
|
|
204
|
-
} from "./chunk-
|
|
208
|
+
} from "./chunk-7LT3YZUR.js";
|
|
205
209
|
import {
|
|
206
210
|
captureReflection,
|
|
211
|
+
cleanExpiredEvents,
|
|
207
212
|
clearDeliveredEvents,
|
|
208
213
|
deliverEvent,
|
|
209
214
|
drainEvents,
|
|
@@ -214,7 +219,7 @@ import {
|
|
|
214
219
|
listEvents,
|
|
215
220
|
parseMeta,
|
|
216
221
|
recordNotice
|
|
217
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-AXFLY5GU.js";
|
|
218
223
|
import {
|
|
219
224
|
publish as publish2,
|
|
220
225
|
subscribe as subscribe2,
|
|
@@ -227,11 +232,11 @@ import {
|
|
|
227
232
|
getPrompt,
|
|
228
233
|
getPromptIfCustom,
|
|
229
234
|
substitute
|
|
230
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-FXWBFDQR.js";
|
|
231
236
|
import {
|
|
232
237
|
isSandboxEnabled,
|
|
233
238
|
wrapForSandbox
|
|
234
|
-
} from "./chunk-
|
|
239
|
+
} from "./chunk-5Y54AE3L.js";
|
|
235
240
|
import {
|
|
236
241
|
addMessage,
|
|
237
242
|
createChannel,
|
|
@@ -267,22 +272,22 @@ import {
|
|
|
267
272
|
subscribe as subscribe3,
|
|
268
273
|
subscribeParticipantAdded,
|
|
269
274
|
updateChannelSettings
|
|
270
|
-
} from "./chunk-
|
|
275
|
+
} from "./chunk-TPX6E6PL.js";
|
|
271
276
|
import {
|
|
272
277
|
getActiveMinds,
|
|
273
278
|
onMindEvent,
|
|
274
279
|
stopAll
|
|
275
|
-
} from "./chunk-
|
|
280
|
+
} from "./chunk-UFTDRTCP.js";
|
|
276
281
|
import {
|
|
277
282
|
broadcast,
|
|
278
283
|
getEventsSince,
|
|
279
284
|
nextEventId,
|
|
280
285
|
publish,
|
|
281
286
|
subscribe
|
|
282
|
-
} from "./chunk-
|
|
287
|
+
} from "./chunk-U54PJPTB.js";
|
|
283
288
|
import {
|
|
284
289
|
normalizeAvatar
|
|
285
|
-
} from "./chunk-
|
|
290
|
+
} from "./chunk-ICXY54ZC.js";
|
|
286
291
|
import {
|
|
287
292
|
safeResolveWithinBase
|
|
288
293
|
} from "./chunk-DW4TRDOZ.js";
|
|
@@ -290,7 +295,7 @@ import {
|
|
|
290
295
|
readVoluteConfig,
|
|
291
296
|
writeVoluteConfig
|
|
292
297
|
} from "./chunk-WCFSBH33.js";
|
|
293
|
-
import "./chunk-
|
|
298
|
+
import "./chunk-6NLW72HP.js";
|
|
294
299
|
import {
|
|
295
300
|
chownMindDir,
|
|
296
301
|
chownMindFile,
|
|
@@ -302,15 +307,16 @@ import {
|
|
|
302
307
|
isIsolationEnabled,
|
|
303
308
|
resolveVoluteBin,
|
|
304
309
|
wrapForIsolation
|
|
305
|
-
} from "./chunk-
|
|
310
|
+
} from "./chunk-M77B73VV.js";
|
|
306
311
|
import {
|
|
307
312
|
loadMergedEnv,
|
|
308
313
|
mindEnvPath,
|
|
309
314
|
readEnv,
|
|
310
315
|
sharedEnvPath,
|
|
311
316
|
writeEnv
|
|
312
|
-
} from "./chunk-
|
|
317
|
+
} from "./chunk-GLM7TVWP.js";
|
|
313
318
|
import {
|
|
319
|
+
OAuthRefreshError,
|
|
314
320
|
addCustomModel,
|
|
315
321
|
aiCompleteUtility,
|
|
316
322
|
buildCustomModel,
|
|
@@ -334,7 +340,7 @@ import {
|
|
|
334
340
|
setProviderRefreshHook,
|
|
335
341
|
setUtilityModel,
|
|
336
342
|
unqualifyModelId
|
|
337
|
-
} from "./chunk-
|
|
343
|
+
} from "./chunk-EGV6R6UF.js";
|
|
338
344
|
import {
|
|
339
345
|
logBuffer,
|
|
340
346
|
logger_default
|
|
@@ -374,7 +380,7 @@ import {
|
|
|
374
380
|
voluteHome,
|
|
375
381
|
voluteSystemDir,
|
|
376
382
|
writeGlobalConfig
|
|
377
|
-
} from "./chunk-
|
|
383
|
+
} from "./chunk-H6X6CKDN.js";
|
|
378
384
|
import {
|
|
379
385
|
activity,
|
|
380
386
|
channels,
|
|
@@ -386,14 +392,14 @@ import {
|
|
|
386
392
|
systemPrompts,
|
|
387
393
|
turns,
|
|
388
394
|
users
|
|
389
|
-
} from "./chunk-
|
|
395
|
+
} from "./chunk-2RNMBXD2.js";
|
|
390
396
|
import "./chunk-K3NQKI34.js";
|
|
391
397
|
|
|
392
398
|
// packages/daemon/src/daemon.ts
|
|
393
399
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
394
400
|
import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync12, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
|
|
395
401
|
import { homedir as homedir3 } from "os";
|
|
396
|
-
import { resolve as
|
|
402
|
+
import { resolve as resolve20 } from "path";
|
|
397
403
|
import { format } from "util";
|
|
398
404
|
|
|
399
405
|
// packages/daemon/src/lib/daemon/backup-manager.ts
|
|
@@ -504,7 +510,7 @@ var BackupManager = class {
|
|
|
504
510
|
} catch (pubErr) {
|
|
505
511
|
blog.error("failed to publish backup-failure activity", logger_default.errorData(pubErr));
|
|
506
512
|
}
|
|
507
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
513
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-V43HDA3T.js");
|
|
508
514
|
await deliverEvent2(getSpiritName(), {
|
|
509
515
|
type: "notice",
|
|
510
516
|
meta: { subtype: "backup" },
|
|
@@ -728,8 +734,8 @@ var BridgeManager = class {
|
|
|
728
734
|
if (!tracked) return;
|
|
729
735
|
this.stopping.add(platform);
|
|
730
736
|
this.bridges.delete(platform);
|
|
731
|
-
await new Promise((
|
|
732
|
-
tracked.child.on("exit", () =>
|
|
737
|
+
await new Promise((resolve21) => {
|
|
738
|
+
tracked.child.on("exit", () => resolve21());
|
|
733
739
|
try {
|
|
734
740
|
if (tracked.child.pid) {
|
|
735
741
|
process.kill(-tracked.child.pid, "SIGTERM");
|
|
@@ -740,7 +746,7 @@ var BridgeManager = class {
|
|
|
740
746
|
if (err instanceof Error && err.code !== "ESRCH") {
|
|
741
747
|
blog2.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
|
|
742
748
|
}
|
|
743
|
-
|
|
749
|
+
resolve21();
|
|
744
750
|
}
|
|
745
751
|
setTimeout(() => {
|
|
746
752
|
try {
|
|
@@ -751,7 +757,7 @@ var BridgeManager = class {
|
|
|
751
757
|
}
|
|
752
758
|
} catch {
|
|
753
759
|
}
|
|
754
|
-
|
|
760
|
+
resolve21();
|
|
755
761
|
}, 5e3);
|
|
756
762
|
});
|
|
757
763
|
this.stopping.delete(platform);
|
|
@@ -861,6 +867,11 @@ async function runMaintenance() {
|
|
|
861
867
|
} catch (err) {
|
|
862
868
|
logger_default.warn("maintenance: failed to clean expired logs", logger_default.errorData(err));
|
|
863
869
|
}
|
|
870
|
+
try {
|
|
871
|
+
await cleanExpiredEvents();
|
|
872
|
+
} catch (err) {
|
|
873
|
+
logger_default.warn("maintenance: failed to clean expired events", logger_default.errorData(err));
|
|
874
|
+
}
|
|
864
875
|
}
|
|
865
876
|
function startMaintenanceInterval(intervalMs = MAINTENANCE_INTERVAL_MS, task = runMaintenance) {
|
|
866
877
|
const handle = setInterval(() => void task(), intervalMs);
|
|
@@ -1112,6 +1123,7 @@ async function xaiSearch(_query, _cred) {
|
|
|
1112
1123
|
}
|
|
1113
1124
|
|
|
1114
1125
|
// packages/daemon/src/lib/services/imagegen.ts
|
|
1126
|
+
var igLog = logger_default.child("imagegen");
|
|
1115
1127
|
var PROVIDERS = {
|
|
1116
1128
|
replicate: {
|
|
1117
1129
|
envVar: "REPLICATE_API_TOKEN",
|
|
@@ -1275,12 +1287,19 @@ async function resolveCredential(providerId) {
|
|
|
1275
1287
|
const config2 = readGlobalConfig();
|
|
1276
1288
|
const configKey = config2.imagegen?.providers?.[providerId]?.apiKey;
|
|
1277
1289
|
if (configKey) return { kind: "api_key", token: configKey };
|
|
1278
|
-
|
|
1279
|
-
|
|
1290
|
+
let oauthError;
|
|
1291
|
+
try {
|
|
1292
|
+
const oauth = await resolveOAuthCredentials(aiProviderId);
|
|
1293
|
+
if (oauth) return { kind: "oauth", token: oauth.access };
|
|
1294
|
+
} catch (err) {
|
|
1295
|
+
if (!(err instanceof OAuthRefreshError)) throw err;
|
|
1296
|
+
oauthError = err;
|
|
1297
|
+
}
|
|
1280
1298
|
const aiKey = config2.ai?.providers?.[aiProviderId]?.apiKey;
|
|
1281
1299
|
if (aiKey) return { kind: "api_key", token: aiKey };
|
|
1282
1300
|
const envKey = provider.envVar ? process.env[provider.envVar] : void 0;
|
|
1283
1301
|
if (envKey) return { kind: "api_key", token: envKey };
|
|
1302
|
+
if (oauthError) throw oauthError;
|
|
1284
1303
|
return void 0;
|
|
1285
1304
|
}
|
|
1286
1305
|
function getEnabledModels2() {
|
|
@@ -1315,12 +1334,27 @@ async function searchModels(query, provider) {
|
|
|
1315
1334
|
return providerDef.search(query || "text to image", cred);
|
|
1316
1335
|
}
|
|
1317
1336
|
const searches = [];
|
|
1337
|
+
let transientError;
|
|
1318
1338
|
for (const [id, def] of Object.entries(PROVIDERS)) {
|
|
1319
|
-
|
|
1339
|
+
let cred;
|
|
1340
|
+
try {
|
|
1341
|
+
cred = await resolveCredential(id);
|
|
1342
|
+
} catch (err) {
|
|
1343
|
+
if (!(err instanceof OAuthRefreshError)) throw err;
|
|
1344
|
+
igLog.warn(`skipping ${id} in model search: OAuth temporarily unavailable`);
|
|
1345
|
+
transientError = err;
|
|
1346
|
+
continue;
|
|
1347
|
+
}
|
|
1320
1348
|
if (!cred) continue;
|
|
1321
|
-
searches.push(
|
|
1349
|
+
searches.push(
|
|
1350
|
+
def.search(query || "text to image", cred).catch((err) => {
|
|
1351
|
+
igLog.warn(`model search failed for ${id}`, logger_default.errorData(err));
|
|
1352
|
+
return [];
|
|
1353
|
+
})
|
|
1354
|
+
);
|
|
1322
1355
|
}
|
|
1323
1356
|
if (searches.length === 0) {
|
|
1357
|
+
if (transientError) throw transientError;
|
|
1324
1358
|
throw new Error("No imagegen providers configured");
|
|
1325
1359
|
}
|
|
1326
1360
|
return (await Promise.all(searches)).flat();
|
|
@@ -1382,7 +1416,7 @@ async function generateImage(model, prompt, signal) {
|
|
|
1382
1416
|
|
|
1383
1417
|
// packages/daemon/src/web/api/system.ts
|
|
1384
1418
|
var DEFAULT_API_URL = "https://volute.systems";
|
|
1385
|
-
var
|
|
1419
|
+
var igLog2 = logger_default.child("imagegen");
|
|
1386
1420
|
var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
1387
1421
|
setTimeout(() => process.exit(1), 200);
|
|
1388
1422
|
return c.json({ ok: true });
|
|
@@ -1400,10 +1434,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1400
1434
|
stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
|
|
1401
1435
|
});
|
|
1402
1436
|
});
|
|
1403
|
-
await new Promise((
|
|
1437
|
+
await new Promise((resolve21) => {
|
|
1404
1438
|
stream.onAbort(() => {
|
|
1405
1439
|
unsubscribe();
|
|
1406
|
-
|
|
1440
|
+
resolve21();
|
|
1407
1441
|
});
|
|
1408
1442
|
});
|
|
1409
1443
|
});
|
|
@@ -1428,7 +1462,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1428
1462
|
config2.name = name.trim() || void 0;
|
|
1429
1463
|
writeGlobalConfig(config2);
|
|
1430
1464
|
if (config2.name !== previousName) {
|
|
1431
|
-
const { notifySpiritSystemChange } = await import("./spirit-
|
|
1465
|
+
const { notifySpiritSystemChange } = await import("./spirit-4ECYIVGE.js");
|
|
1432
1466
|
await notifySpiritSystemChange();
|
|
1433
1467
|
}
|
|
1434
1468
|
return c.json({ name: config2.name ?? null });
|
|
@@ -1621,7 +1655,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1621
1655
|
const results = await searchModels(q || void 0, provider || void 0);
|
|
1622
1656
|
return c.json(results);
|
|
1623
1657
|
} catch (err) {
|
|
1624
|
-
|
|
1658
|
+
igLog2.error("model search failed", logger_default.errorData(err));
|
|
1625
1659
|
return c.json({ error: err instanceof Error ? err.message : "Search failed" }, 500);
|
|
1626
1660
|
}
|
|
1627
1661
|
}).post(
|
|
@@ -1638,7 +1672,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1638
1672
|
}
|
|
1639
1673
|
});
|
|
1640
1674
|
} catch (err) {
|
|
1641
|
-
|
|
1675
|
+
igLog2.error("image generation failed", logger_default.errorData(err));
|
|
1642
1676
|
return c.json({ error: err instanceof Error ? err.message : "Generation failed" }, 500);
|
|
1643
1677
|
}
|
|
1644
1678
|
}
|
|
@@ -1787,8 +1821,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1787
1821
|
createdAt: Date.now()
|
|
1788
1822
|
};
|
|
1789
1823
|
oauthFlows.set(flowId, flow);
|
|
1790
|
-
const promptPromise = needsManualCode ? new Promise((
|
|
1791
|
-
flow.resolveCode =
|
|
1824
|
+
const promptPromise = needsManualCode ? new Promise((resolve21) => {
|
|
1825
|
+
flow.resolveCode = resolve21;
|
|
1792
1826
|
}) : void 0;
|
|
1793
1827
|
oauthProvider.login({
|
|
1794
1828
|
onAuth: (info) => {
|
|
@@ -1827,7 +1861,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1827
1861
|
existing.error = err instanceof Error ? err.message : String(err);
|
|
1828
1862
|
}
|
|
1829
1863
|
});
|
|
1830
|
-
await new Promise((
|
|
1864
|
+
await new Promise((resolve21) => setTimeout(resolve21, 2e3));
|
|
1831
1865
|
const state = oauthFlows.get(flowId);
|
|
1832
1866
|
return c.json({
|
|
1833
1867
|
flowId,
|
|
@@ -2088,8 +2122,8 @@ var app2 = new Hono2().get("/events", async (c) => {
|
|
|
2088
2122
|
});
|
|
2089
2123
|
}, 15e3);
|
|
2090
2124
|
cleanups.push(() => clearInterval(keepAlive));
|
|
2091
|
-
await new Promise((
|
|
2092
|
-
stream.onAbort(() =>
|
|
2125
|
+
await new Promise((resolve21) => {
|
|
2126
|
+
stream.onAbort(() => resolve21());
|
|
2093
2127
|
});
|
|
2094
2128
|
} finally {
|
|
2095
2129
|
for (const cleanup of cleanups) {
|
|
@@ -2122,6 +2156,11 @@ function isNotModified(c, etag) {
|
|
|
2122
2156
|
}
|
|
2123
2157
|
|
|
2124
2158
|
// packages/daemon/src/web/api/auth.ts
|
|
2159
|
+
async function withExternalFlag(list) {
|
|
2160
|
+
if (!list.some((u) => u.user_type === "mind")) return list;
|
|
2161
|
+
const local = new Set((await readAllMinds()).map((m) => m.name));
|
|
2162
|
+
return list.map((u) => u.user_type === "mind" ? { ...u, external: !local.has(u.username) } : u);
|
|
2163
|
+
}
|
|
2125
2164
|
function tryJoinSystem(userId) {
|
|
2126
2165
|
if (!process.env.VOLUTE_DAEMON_TOKEN) return;
|
|
2127
2166
|
joinSystemChannel(userId).catch(() => {
|
|
@@ -2145,6 +2184,12 @@ var profileSchema = z2.object({
|
|
|
2145
2184
|
display_name: z2.string().max(100).nullable().optional(),
|
|
2146
2185
|
description: z2.string().max(500).nullable().optional()
|
|
2147
2186
|
});
|
|
2187
|
+
var registerMindSchema = z2.object({
|
|
2188
|
+
name: z2.string().min(1),
|
|
2189
|
+
displayName: z2.string().max(100).optional(),
|
|
2190
|
+
description: z2.string().max(500).optional(),
|
|
2191
|
+
tokenLabel: z2.string().max(100).optional()
|
|
2192
|
+
});
|
|
2148
2193
|
var AVATAR_MIME = {
|
|
2149
2194
|
".png": "image/png",
|
|
2150
2195
|
".jpg": "image/jpeg",
|
|
@@ -2156,7 +2201,39 @@ var MAX_AVATAR_SIZE = 2 * 1024 * 1024;
|
|
|
2156
2201
|
function avatarsDir() {
|
|
2157
2202
|
return resolve3(voluteHome(), "avatars");
|
|
2158
2203
|
}
|
|
2159
|
-
var authenticated = new Hono3().use(authMiddleware).post("/
|
|
2204
|
+
var authenticated = new Hono3().use(authMiddleware).post("/minds", requireAdmin, zValidator2("json", registerMindSchema), async (c) => {
|
|
2205
|
+
const { name, displayName, description, tokenLabel } = c.req.valid("json");
|
|
2206
|
+
const invalid = validateMindName(name);
|
|
2207
|
+
if (invalid) return c.json({ error: invalid }, 400);
|
|
2208
|
+
if (await getUserByUsername(name)) {
|
|
2209
|
+
return c.json({ error: `"${name}" is already taken` }, 409);
|
|
2210
|
+
}
|
|
2211
|
+
const db = await getDb();
|
|
2212
|
+
let user;
|
|
2213
|
+
try {
|
|
2214
|
+
[user] = await db.insert(users).values({
|
|
2215
|
+
username: name,
|
|
2216
|
+
password_hash: "!mind",
|
|
2217
|
+
role: "user",
|
|
2218
|
+
user_type: "mind",
|
|
2219
|
+
display_name: displayName ?? null,
|
|
2220
|
+
description: description ?? null
|
|
2221
|
+
}).returning({
|
|
2222
|
+
id: users.id,
|
|
2223
|
+
username: users.username,
|
|
2224
|
+
user_type: users.user_type,
|
|
2225
|
+
role: users.role,
|
|
2226
|
+
display_name: users.display_name
|
|
2227
|
+
});
|
|
2228
|
+
} catch (err) {
|
|
2229
|
+
if (await getUserByUsername(name)) {
|
|
2230
|
+
return c.json({ error: `"${name}" is already taken` }, 409);
|
|
2231
|
+
}
|
|
2232
|
+
throw err;
|
|
2233
|
+
}
|
|
2234
|
+
const { id: tokenId, token } = await issueApiToken(user.id, tokenLabel);
|
|
2235
|
+
return c.json({ name, user, token, tokenId }, 201);
|
|
2236
|
+
}).post("/change-password", zValidator2("json", changePasswordSchema), async (c) => {
|
|
2160
2237
|
const user = c.get("user");
|
|
2161
2238
|
const { currentPassword, newPassword } = c.req.valid("json");
|
|
2162
2239
|
const ok = await changePassword(user.id, currentPassword, newPassword);
|
|
@@ -2237,9 +2314,9 @@ var admin = new Hono3().use(authMiddleware).get("/users", async (c) => {
|
|
|
2237
2314
|
}
|
|
2238
2315
|
const type = c.req.query("type");
|
|
2239
2316
|
if (type === "human" || type === "mind") {
|
|
2240
|
-
return c.json(await listUsersByType(type));
|
|
2317
|
+
return c.json(await withExternalFlag(await listUsersByType(type)));
|
|
2241
2318
|
}
|
|
2242
|
-
return c.json(await listUsers());
|
|
2319
|
+
return c.json(await withExternalFlag(await listUsers()));
|
|
2243
2320
|
}).get("/users/pending", async (c) => {
|
|
2244
2321
|
const user = c.get("user");
|
|
2245
2322
|
if (user.role !== "admin") return c.json({ error: "Forbidden" }, 403);
|
|
@@ -2272,7 +2349,42 @@ var admin = new Hono3().use(authMiddleware).get("/users", async (c) => {
|
|
|
2272
2349
|
await setUserRole(id, role);
|
|
2273
2350
|
return c.json({ ok: true });
|
|
2274
2351
|
}
|
|
2275
|
-
).
|
|
2352
|
+
).post(
|
|
2353
|
+
"/users/:id/tokens",
|
|
2354
|
+
requireAdmin,
|
|
2355
|
+
zValidator2("json", z2.object({ label: z2.string().max(200).optional() })),
|
|
2356
|
+
async (c) => {
|
|
2357
|
+
const id = parseInt(c.req.param("id"), 10);
|
|
2358
|
+
if (Number.isNaN(id)) return c.json({ error: "Invalid user ID" }, 400);
|
|
2359
|
+
const target = await getUser(id);
|
|
2360
|
+
if (!target) return c.json({ error: "User not found" }, 404);
|
|
2361
|
+
const { label } = c.req.valid("json");
|
|
2362
|
+
const issued = await issueApiToken(id, label);
|
|
2363
|
+
return c.json(
|
|
2364
|
+
{
|
|
2365
|
+
id: issued.id,
|
|
2366
|
+
token: issued.token,
|
|
2367
|
+
label: issued.label,
|
|
2368
|
+
createdAt: issued.created_at
|
|
2369
|
+
},
|
|
2370
|
+
201
|
|
2371
|
+
);
|
|
2372
|
+
}
|
|
2373
|
+
).get("/users/:id/tokens", requireAdmin, async (c) => {
|
|
2374
|
+
const id = parseInt(c.req.param("id"), 10);
|
|
2375
|
+
if (Number.isNaN(id)) return c.json({ error: "Invalid user ID" }, 400);
|
|
2376
|
+
const target = await getUser(id);
|
|
2377
|
+
if (!target) return c.json({ error: "User not found" }, 404);
|
|
2378
|
+
const tokens = await listApiTokens(id);
|
|
2379
|
+
return c.json(tokens.map((t) => ({ id: t.id, label: t.label, createdAt: t.created_at })));
|
|
2380
|
+
}).delete("/users/:id/tokens/:tokenId", requireAdmin, async (c) => {
|
|
2381
|
+
const id = parseInt(c.req.param("id"), 10);
|
|
2382
|
+
const tokenId = parseInt(c.req.param("tokenId"), 10);
|
|
2383
|
+
if (Number.isNaN(id) || Number.isNaN(tokenId)) return c.json({ error: "Invalid ID" }, 400);
|
|
2384
|
+
const revoked = await revokeApiToken(id, tokenId);
|
|
2385
|
+
if (!revoked) return c.json({ error: "Token not found" }, 404);
|
|
2386
|
+
return c.json({ ok: true });
|
|
2387
|
+
}).put("/users/:id/profile", zValidator2("json", profileSchema), async (c) => {
|
|
2276
2388
|
const user = c.get("user");
|
|
2277
2389
|
if (user.role !== "admin") return c.json({ error: "Forbidden" }, 403);
|
|
2278
2390
|
const id = parseInt(c.req.param("id"), 10);
|
|
@@ -2301,7 +2413,11 @@ var admin = new Hono3().use(authMiddleware).get("/users", async (c) => {
|
|
|
2301
2413
|
if (adminCount <= 1) return c.json({ error: "Cannot delete the last admin" }, 400);
|
|
2302
2414
|
}
|
|
2303
2415
|
if (target.user_type === "mind") {
|
|
2304
|
-
|
|
2416
|
+
if (await findMind(target.username)) {
|
|
2417
|
+
return c.json({ error: "Use the mind deletion API to delete minds" }, 400);
|
|
2418
|
+
}
|
|
2419
|
+
await deleteExternalMindUser(id);
|
|
2420
|
+
return c.json({ ok: true });
|
|
2305
2421
|
}
|
|
2306
2422
|
await deleteUser(id);
|
|
2307
2423
|
return c.json({ ok: true });
|
|
@@ -2557,15 +2673,18 @@ async function fanOutToMinds(opts) {
|
|
|
2557
2673
|
const isDM = opts.isDM ?? participants.length === 2;
|
|
2558
2674
|
const manager = getMindManager();
|
|
2559
2675
|
const sm = getSleepManagerIfReady();
|
|
2676
|
+
const registeredMinds = new Set((await readAllMinds()).map((m) => m.name));
|
|
2560
2677
|
const targetMinds = mindParticipants.map((ap) => {
|
|
2561
2678
|
const key = opts.targetName ? opts.targetName(ap.username) : ap.username;
|
|
2562
2679
|
if (manager.isRunning(key) || sm?.isSleeping(ap.username)) return ap.username;
|
|
2563
2680
|
if (ap.username !== opts.senderName) {
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2681
|
+
if (registeredMinds.has(ap.username)) {
|
|
2682
|
+
logger_default.warn(
|
|
2683
|
+
`fan-out: skipping ${ap.username} (not running) for conversation ${opts.conversationId}`
|
|
2684
|
+
);
|
|
2685
|
+
}
|
|
2567
2686
|
if (ap.userType === "system") {
|
|
2568
|
-
import("./spirit-availability-
|
|
2687
|
+
import("./spirit-availability-Y54Y3675.js").then(({ ensureSpiritAvailable: ensureSpiritAvailable2 }) => ensureSpiritAvailable2()).catch((err) => logger_default.warn("fan-out: on-demand spirit start failed", logger_default.errorData(err)));
|
|
2569
2688
|
}
|
|
2570
2689
|
}
|
|
2571
2690
|
return null;
|
|
@@ -2668,7 +2787,7 @@ var app4 = new Hono5().post("/:platform/inbound", zValidator4("json", inboundSch
|
|
|
2668
2787
|
}
|
|
2669
2788
|
const participants = await getParticipants(channel.id);
|
|
2670
2789
|
if (!participants.some((p) => p.userId === puppet.id)) {
|
|
2671
|
-
const { addParticipant } = await import("./conversations-
|
|
2790
|
+
const { addParticipant } = await import("./conversations-ZL6PHROD.js");
|
|
2672
2791
|
await addParticipant(channel.id, puppet.id);
|
|
2673
2792
|
}
|
|
2674
2793
|
const contentBlocks = body.content;
|
|
@@ -2952,7 +3071,7 @@ async function notifyMind(mindName, message) {
|
|
|
2952
3071
|
const entry = await findMind(mindName);
|
|
2953
3072
|
if (!entry) return;
|
|
2954
3073
|
try {
|
|
2955
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
3074
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-V43HDA3T.js");
|
|
2956
3075
|
await deliverEvent2(mindName, { type: "file-share", body: message });
|
|
2957
3076
|
} catch (err) {
|
|
2958
3077
|
logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
|
|
@@ -3923,9 +4042,9 @@ var app11 = new Hono14().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
3923
4042
|
stream.onAbort(() => {
|
|
3924
4043
|
tail.kill();
|
|
3925
4044
|
});
|
|
3926
|
-
await new Promise((
|
|
3927
|
-
tail.on("exit",
|
|
3928
|
-
stream.onAbort(
|
|
4045
|
+
await new Promise((resolve21) => {
|
|
4046
|
+
tail.on("exit", resolve21);
|
|
4047
|
+
stream.onAbort(resolve21);
|
|
3929
4048
|
});
|
|
3930
4049
|
});
|
|
3931
4050
|
}).get("/:name/logs/tail", requireSelf(), async (c) => {
|
|
@@ -3943,8 +4062,8 @@ var app11 = new Hono14().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
3943
4062
|
tail.stdout.on("data", (data) => {
|
|
3944
4063
|
output += data.toString();
|
|
3945
4064
|
});
|
|
3946
|
-
await new Promise((
|
|
3947
|
-
tail.on("exit",
|
|
4065
|
+
await new Promise((resolve21) => {
|
|
4066
|
+
tail.on("exit", resolve21);
|
|
3948
4067
|
});
|
|
3949
4068
|
return c.text(output);
|
|
3950
4069
|
});
|
|
@@ -4037,14 +4156,14 @@ var mind_skills_default = app12;
|
|
|
4037
4156
|
// packages/daemon/src/web/api/minds.ts
|
|
4038
4157
|
import {
|
|
4039
4158
|
cpSync,
|
|
4040
|
-
existsSync as
|
|
4159
|
+
existsSync as existsSync8,
|
|
4041
4160
|
mkdirSync as mkdirSync6,
|
|
4042
4161
|
readdirSync as readdirSync2,
|
|
4043
4162
|
readFileSync as readFileSync9,
|
|
4044
4163
|
rmSync as rmSync3,
|
|
4045
4164
|
writeFileSync as writeFileSync8
|
|
4046
4165
|
} from "fs";
|
|
4047
|
-
import { relative, resolve as
|
|
4166
|
+
import { relative, resolve as resolve13 } from "path";
|
|
4048
4167
|
import { zValidator as zValidator6 } from "@hono/zod-validator";
|
|
4049
4168
|
import { and as and5, desc as desc3, eq as eq5, sql as sql3 } from "drizzle-orm";
|
|
4050
4169
|
import { Hono as Hono16 } from "hono";
|
|
@@ -4487,6 +4606,49 @@ async function commitSrcChanges(dir, mindName) {
|
|
|
4487
4606
|
glog.info(`committed known-good src changes (${dir})`);
|
|
4488
4607
|
}
|
|
4489
4608
|
|
|
4609
|
+
// packages/daemon/src/lib/mind/npm-install.ts
|
|
4610
|
+
import { existsSync as existsSync7 } from "fs";
|
|
4611
|
+
import { resolve as resolve10 } from "path";
|
|
4612
|
+
var NPM_INSTALL_ARGS = [
|
|
4613
|
+
"install",
|
|
4614
|
+
"--no-audit",
|
|
4615
|
+
"--no-fund",
|
|
4616
|
+
"--prefer-offline",
|
|
4617
|
+
"--loglevel=error"
|
|
4618
|
+
];
|
|
4619
|
+
function lowPriorityArgv(cmd, args, ionice) {
|
|
4620
|
+
return ionice ? ["ionice", ["-c2", "-n7", "nice", "-n19", cmd, ...args]] : ["nice", ["-n19", cmd, ...args]];
|
|
4621
|
+
}
|
|
4622
|
+
function hasIonice() {
|
|
4623
|
+
return process.platform === "linux" && (existsSync7("/usr/bin/ionice") || existsSync7("/bin/ionice"));
|
|
4624
|
+
}
|
|
4625
|
+
async function npmInstallAsMind(cwd, mindName) {
|
|
4626
|
+
const [cmd, args] = lowPriorityArgv("npm", NPM_INSTALL_ARGS, hasIonice());
|
|
4627
|
+
if (isIsolationEnabled()) {
|
|
4628
|
+
const [wrappedCmd, wrappedArgs] = await wrapForIsolation(cmd, args, mindName);
|
|
4629
|
+
await exec(wrappedCmd, wrappedArgs, {
|
|
4630
|
+
cwd,
|
|
4631
|
+
env: { ...process.env, HOME: resolve10(cwd, "home") }
|
|
4632
|
+
});
|
|
4633
|
+
} else {
|
|
4634
|
+
await exec(cmd, args, { cwd });
|
|
4635
|
+
}
|
|
4636
|
+
}
|
|
4637
|
+
async function depsChangedSince(dir, fromRef) {
|
|
4638
|
+
try {
|
|
4639
|
+
await gitExec(["diff", "--quiet", fromRef, "HEAD", "--", "package.json", "package-lock.json"], {
|
|
4640
|
+
cwd: dir
|
|
4641
|
+
});
|
|
4642
|
+
return false;
|
|
4643
|
+
} catch {
|
|
4644
|
+
return true;
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4647
|
+
async function npmInstallNeeded(dir, preMergeRef) {
|
|
4648
|
+
if (!existsSync7(resolve10(dir, "node_modules"))) return true;
|
|
4649
|
+
return depsChangedSince(dir, preMergeRef);
|
|
4650
|
+
}
|
|
4651
|
+
|
|
4490
4652
|
// packages/daemon/src/lib/mind/thinking-config.ts
|
|
4491
4653
|
var CLAUDE_EFFORT = {
|
|
4492
4654
|
minimal: "low",
|
|
@@ -4529,6 +4691,8 @@ function deriveThinkingLevel(config2) {
|
|
|
4529
4691
|
}
|
|
4530
4692
|
|
|
4531
4693
|
// packages/daemon/src/lib/mind/variants.ts
|
|
4694
|
+
import { statSync as statSync3 } from "fs";
|
|
4695
|
+
import { resolve as resolve11 } from "path";
|
|
4532
4696
|
var SAFE_BRANCH_RE = /^[a-zA-Z0-9._\-/]+$/;
|
|
4533
4697
|
function validateBranchName(branch) {
|
|
4534
4698
|
if (!SAFE_BRANCH_RE.test(branch)) {
|
|
@@ -4541,6 +4705,55 @@ function validateBranchName(branch) {
|
|
|
4541
4705
|
}
|
|
4542
4706
|
var MERGE_EXCLUDED_PATHS = ["home/MEMORY.md", "home/memory/journal/"];
|
|
4543
4707
|
var MAX_DELTA_CHARS = 12e3;
|
|
4708
|
+
var NEVER_REPORT_PREFIXES = ["home/.claude/", "home/.pi/", "home/.agents/"];
|
|
4709
|
+
var MAX_LISTED_UNRESOLVED_FILES = 20;
|
|
4710
|
+
async function findUnresolvedHomeFiles(cwd) {
|
|
4711
|
+
const raw = await gitExec(
|
|
4712
|
+
["ls-files", "--others", "--ignored", "--exclude-standard", "-z", "--", "home"],
|
|
4713
|
+
{ cwd }
|
|
4714
|
+
);
|
|
4715
|
+
const allPaths = raw.split("\0").filter((path) => path && !NEVER_REPORT_PREFIXES.some((prefix) => path.startsWith(prefix)));
|
|
4716
|
+
const files = [];
|
|
4717
|
+
let totalBytes = 0;
|
|
4718
|
+
for (const path of allPaths) {
|
|
4719
|
+
let bytes = -1;
|
|
4720
|
+
try {
|
|
4721
|
+
bytes = statSync3(resolve11(cwd, path)).size;
|
|
4722
|
+
} catch {
|
|
4723
|
+
}
|
|
4724
|
+
if (bytes > 0) totalBytes += bytes;
|
|
4725
|
+
if (files.length < MAX_LISTED_UNRESOLVED_FILES) files.push({ path, bytes });
|
|
4726
|
+
}
|
|
4727
|
+
return { files, totalCount: allPaths.length, totalBytes };
|
|
4728
|
+
}
|
|
4729
|
+
function formatBytes(bytes) {
|
|
4730
|
+
if (bytes < 0) return "size unknown";
|
|
4731
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
4732
|
+
const units = ["KB", "MB", "GB", "TB"];
|
|
4733
|
+
let value = bytes / 1024;
|
|
4734
|
+
for (const unit of units) {
|
|
4735
|
+
if (value < 1024) return `${value.toFixed(1)} ${unit}`;
|
|
4736
|
+
value /= 1024;
|
|
4737
|
+
}
|
|
4738
|
+
return `${value.toFixed(1)} PB`;
|
|
4739
|
+
}
|
|
4740
|
+
function formatUnresolvedHomeFilesMessage(variantName, result) {
|
|
4741
|
+
const lines = result.files.map(
|
|
4742
|
+
(f) => ` - ${f.path.replace(/^home\//, "")} (${formatBytes(f.bytes)})`
|
|
4743
|
+
);
|
|
4744
|
+
const remaining = result.totalCount - result.files.length;
|
|
4745
|
+
if (remaining > 0) lines.push(` ...and ${remaining} more`);
|
|
4746
|
+
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)}):
|
|
4747
|
+
|
|
4748
|
+
${lines.join("\n")}
|
|
4749
|
+
|
|
4750
|
+
Before retrying the join, resolve each file in the variant \u2014 one of:
|
|
4751
|
+
1. Track it: git add -f -- <path> (then commit it, or let auto-commit pick it up next turn)
|
|
4752
|
+
2. Copy it out of home/ to somewhere safe, then delete it
|
|
4753
|
+
3. Delete it if it's disposable
|
|
4754
|
+
|
|
4755
|
+
Once resolved, retry the join. To join anyway and discard everything listed above, pass discardUnresolved: true.`;
|
|
4756
|
+
}
|
|
4544
4757
|
async function mergeVariantExcludingMemory(projectRoot, variantBranch) {
|
|
4545
4758
|
const opts = { cwd: projectRoot };
|
|
4546
4759
|
let memoryDelta = "";
|
|
@@ -4743,7 +4956,7 @@ async function waitForImagegenJob(mind, id, timeoutMs) {
|
|
|
4743
4956
|
import { randomUUID } from "crypto";
|
|
4744
4957
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
4745
4958
|
import { homedir } from "os";
|
|
4746
|
-
import { resolve as
|
|
4959
|
+
import { resolve as resolve12 } from "path";
|
|
4747
4960
|
function convertSession(opts) {
|
|
4748
4961
|
const lines = readFileSync8(opts.sessionPath, "utf-8").trim().split("\n");
|
|
4749
4962
|
const sessionId = randomUUID();
|
|
@@ -4859,9 +5072,9 @@ function convertSession(opts) {
|
|
|
4859
5072
|
}
|
|
4860
5073
|
}
|
|
4861
5074
|
const projectId = opts.projectDir.replace(/\//g, "-");
|
|
4862
|
-
const sdkDir =
|
|
5075
|
+
const sdkDir = resolve12(homedir(), ".claude", "projects", projectId);
|
|
4863
5076
|
mkdirSync5(sdkDir, { recursive: true });
|
|
4864
|
-
const sdkPath =
|
|
5077
|
+
const sdkPath = resolve12(sdkDir, `${sessionId}.jsonl`);
|
|
4865
5078
|
writeFileSync7(sdkPath, `${sdkEvents.join("\n")}
|
|
4866
5079
|
`);
|
|
4867
5080
|
console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
|
|
@@ -4928,7 +5141,7 @@ async function getMindStatus(name, port, registryRunning, seed) {
|
|
|
4928
5141
|
let status = "stopped";
|
|
4929
5142
|
let wakeAt = null;
|
|
4930
5143
|
try {
|
|
4931
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5144
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OFP2GFXF.js");
|
|
4932
5145
|
const sleepManager = getSleepManagerIfReady2();
|
|
4933
5146
|
if (sleepManager?.isSleeping(name)) {
|
|
4934
5147
|
status = "sleeping";
|
|
@@ -5007,7 +5220,7 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
|
|
|
5007
5220
|
await gitExec(["commit", "-m", "initial commit"], opts);
|
|
5008
5221
|
}
|
|
5009
5222
|
async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
5010
|
-
const tempWorktree =
|
|
5223
|
+
const tempWorktree = resolve13(projectRoot, ".variants", "_template_update");
|
|
5011
5224
|
let branchExists = false;
|
|
5012
5225
|
try {
|
|
5013
5226
|
await gitExec(["rev-parse", "--verify", TEMPLATE_BRANCH], { cwd: projectRoot });
|
|
@@ -5018,7 +5231,7 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
5018
5231
|
await gitExec(["worktree", "remove", "--force", tempWorktree], { cwd: projectRoot });
|
|
5019
5232
|
} catch {
|
|
5020
5233
|
}
|
|
5021
|
-
if (
|
|
5234
|
+
if (existsSync8(tempWorktree)) {
|
|
5022
5235
|
rmSync3(tempWorktree, { recursive: true, force: true });
|
|
5023
5236
|
}
|
|
5024
5237
|
const templatesRoot = findTemplatesRoot();
|
|
@@ -5039,15 +5252,15 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
5039
5252
|
});
|
|
5040
5253
|
}
|
|
5041
5254
|
copyTemplateToDir(composedDir, tempWorktree, mindName, manifest);
|
|
5042
|
-
const initDir =
|
|
5043
|
-
if (
|
|
5255
|
+
const initDir = resolve13(tempWorktree, ".init");
|
|
5256
|
+
if (existsSync8(initDir)) {
|
|
5044
5257
|
rmSync3(initDir, { recursive: true, force: true });
|
|
5045
5258
|
}
|
|
5046
|
-
const homeDir =
|
|
5047
|
-
if (
|
|
5259
|
+
const homeDir = resolve13(tempWorktree, "home");
|
|
5260
|
+
if (existsSync8(homeDir)) {
|
|
5048
5261
|
for (const entry of readdirSync2(homeDir)) {
|
|
5049
5262
|
if (entry !== "VOLUTE.md") {
|
|
5050
|
-
rmSync3(
|
|
5263
|
+
rmSync3(resolve13(homeDir, entry), { recursive: true, force: true });
|
|
5051
5264
|
}
|
|
5052
5265
|
}
|
|
5053
5266
|
}
|
|
@@ -5062,7 +5275,7 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
5062
5275
|
await gitExec(["worktree", "remove", "--force", tempWorktree], { cwd: projectRoot });
|
|
5063
5276
|
} catch {
|
|
5064
5277
|
}
|
|
5065
|
-
if (
|
|
5278
|
+
if (existsSync8(tempWorktree)) {
|
|
5066
5279
|
rmSync3(tempWorktree, { recursive: true, force: true });
|
|
5067
5280
|
}
|
|
5068
5281
|
rmSync3(composedDir, { recursive: true, force: true });
|
|
@@ -5085,14 +5298,6 @@ async function mergeTemplateBranch(worktreeDir) {
|
|
|
5085
5298
|
throw e;
|
|
5086
5299
|
}
|
|
5087
5300
|
}
|
|
5088
|
-
async function npmInstallAsMind(cwd, mindName) {
|
|
5089
|
-
if (isIsolationEnabled()) {
|
|
5090
|
-
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
5091
|
-
await exec(cmd, args, { cwd, env: { ...process.env, HOME: resolve11(cwd, "home") } });
|
|
5092
|
-
} else {
|
|
5093
|
-
await exec("npm", ["install"], { cwd });
|
|
5094
|
-
}
|
|
5095
|
-
}
|
|
5096
5301
|
async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariantName, upgradeBranch, template, oldTemplate) {
|
|
5097
5302
|
const templateChanged = template !== oldTemplate;
|
|
5098
5303
|
const mainStatus = (await gitExec(["status", "--porcelain"], { cwd: dir })).trim();
|
|
@@ -5100,9 +5305,10 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5100
5305
|
await gitExec(["add", "-A"], { cwd: dir });
|
|
5101
5306
|
await gitExec(["commit", "-m", "Auto-commit before upgrade merge"], { cwd: dir });
|
|
5102
5307
|
}
|
|
5308
|
+
const preMergeHead = (await gitExec(["rev-parse", "HEAD"], { cwd: dir })).trim();
|
|
5103
5309
|
await gitExec(["merge", upgradeBranch], { cwd: dir });
|
|
5104
5310
|
try {
|
|
5105
|
-
await cleanupVariant(upgradeVariantName, dir, worktreeDir);
|
|
5311
|
+
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir);
|
|
5106
5312
|
} catch (err) {
|
|
5107
5313
|
logger_default.warn(`failed to clean up upgrade worktree for ${mindName}`, logger_default.errorData(err));
|
|
5108
5314
|
}
|
|
@@ -5113,7 +5319,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5113
5319
|
let switchWarning;
|
|
5114
5320
|
if (templateChanged) {
|
|
5115
5321
|
try {
|
|
5116
|
-
applyTemplateHomeFiles(
|
|
5322
|
+
applyTemplateHomeFiles(resolve13(dir, "home"), template);
|
|
5117
5323
|
const migratedSkills = migrateSkillsToTemplate(dir, oldTemplate, template);
|
|
5118
5324
|
await gitExec(["add", "home/"], { cwd: dir });
|
|
5119
5325
|
try {
|
|
@@ -5140,14 +5346,18 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5140
5346
|
} catch (err) {
|
|
5141
5347
|
logger_default.warn(`failed to update template for ${mindName}`, logger_default.errorData(err));
|
|
5142
5348
|
}
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5349
|
+
if (await npmInstallNeeded(dir, preMergeHead)) {
|
|
5350
|
+
try {
|
|
5351
|
+
await npmInstallAsMind(dir, mindName);
|
|
5352
|
+
} catch (err) {
|
|
5353
|
+
logger_default.warn(`npm install failed after upgrade merge for ${mindName}`, logger_default.errorData(err));
|
|
5354
|
+
return {
|
|
5355
|
+
ok: true,
|
|
5356
|
+
warning: `Upgrade merged but npm install failed: ${err instanceof Error ? err.message : String(err)}. You may need to run npm install manually.`
|
|
5357
|
+
};
|
|
5358
|
+
}
|
|
5359
|
+
} else {
|
|
5360
|
+
logger_default.info(`skipping npm install for ${mindName} \u2014 dependencies unchanged by upgrade`);
|
|
5151
5361
|
}
|
|
5152
5362
|
const manager = getMindManager();
|
|
5153
5363
|
try {
|
|
@@ -5155,7 +5365,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5155
5365
|
await manager.stopMind(mindName);
|
|
5156
5366
|
}
|
|
5157
5367
|
manager.setPendingContext(mindName, { type: "upgraded" });
|
|
5158
|
-
await manager.startMind(mindName);
|
|
5368
|
+
await manager.startMind(mindName, { healthTimeoutMs: 12e4 });
|
|
5159
5369
|
} catch (e) {
|
|
5160
5370
|
return {
|
|
5161
5371
|
ok: true,
|
|
@@ -5165,8 +5375,8 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5165
5375
|
return { ok: true, warning: switchWarning };
|
|
5166
5376
|
}
|
|
5167
5377
|
async function importFromArchive(c, tempDir, nameOverride, manifest) {
|
|
5168
|
-
const extractedMindDir =
|
|
5169
|
-
if (!
|
|
5378
|
+
const extractedMindDir = resolve13(tempDir, "mind");
|
|
5379
|
+
if (!existsSync8(extractedMindDir)) {
|
|
5170
5380
|
return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
|
|
5171
5381
|
}
|
|
5172
5382
|
if (!manifest?.includes || !manifest.name || !manifest.template) {
|
|
@@ -5184,7 +5394,7 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5184
5394
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
5185
5395
|
ensureVoluteHome();
|
|
5186
5396
|
const dest = mindDir(name);
|
|
5187
|
-
if (
|
|
5397
|
+
if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5188
5398
|
try {
|
|
5189
5399
|
cpSync(extractedMindDir, dest, { recursive: true });
|
|
5190
5400
|
if (!manifest.includes.identity) {
|
|
@@ -5192,9 +5402,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5192
5402
|
}
|
|
5193
5403
|
const state = stateDir(name);
|
|
5194
5404
|
mkdirSync6(state, { recursive: true });
|
|
5195
|
-
const envJson =
|
|
5196
|
-
if (
|
|
5197
|
-
cpSync(envJson,
|
|
5405
|
+
const envJson = resolve13(tempDir, "state/env.json");
|
|
5406
|
+
if (existsSync8(envJson)) {
|
|
5407
|
+
cpSync(envJson, resolve13(state, "env.json"));
|
|
5198
5408
|
}
|
|
5199
5409
|
const port = await nextPort();
|
|
5200
5410
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
@@ -5203,30 +5413,30 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5203
5413
|
} catch (err) {
|
|
5204
5414
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5205
5415
|
}
|
|
5206
|
-
const homeDir =
|
|
5416
|
+
const homeDir = resolve13(dest, "home");
|
|
5207
5417
|
ensureVoluteGroup();
|
|
5208
5418
|
createMindUser(name, homeDir);
|
|
5209
5419
|
await chownMindDir(dest, name);
|
|
5210
5420
|
await npmInstallAsMind(dest, name);
|
|
5211
5421
|
await importHistoryFromArchive(name, tempDir);
|
|
5212
5422
|
importSessionsFromArchive(dest, tempDir);
|
|
5213
|
-
if (!
|
|
5423
|
+
if (!existsSync8(resolve13(dest, ".git"))) {
|
|
5214
5424
|
try {
|
|
5215
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5425
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve13(dest, "home") } : void 0;
|
|
5216
5426
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
5217
5427
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
5218
5428
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
5219
5429
|
await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
|
|
5220
5430
|
} catch (err) {
|
|
5221
5431
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
5222
|
-
rmSync3(
|
|
5432
|
+
rmSync3(resolve13(dest, ".git"), { recursive: true, force: true });
|
|
5223
5433
|
}
|
|
5224
5434
|
}
|
|
5225
5435
|
await chownMindDir(dest, name);
|
|
5226
5436
|
rmSync3(tempDir, { recursive: true, force: true });
|
|
5227
5437
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
5228
5438
|
} catch (err) {
|
|
5229
|
-
if (
|
|
5439
|
+
if (existsSync8(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5230
5440
|
try {
|
|
5231
5441
|
await removeMind(name);
|
|
5232
5442
|
} catch (cleanupErr) {
|
|
@@ -5243,7 +5453,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5243
5453
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
5244
5454
|
ensureVoluteHome();
|
|
5245
5455
|
const dest = mindDir(name);
|
|
5246
|
-
if (
|
|
5456
|
+
if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5247
5457
|
const templatesRoot = findTemplatesRoot();
|
|
5248
5458
|
const { composedDir, manifest: templateManifest } = composeTemplate(
|
|
5249
5459
|
templatesRoot,
|
|
@@ -5252,36 +5462,36 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5252
5462
|
try {
|
|
5253
5463
|
copyTemplateToDir(composedDir, dest, name, templateManifest);
|
|
5254
5464
|
applyInitFiles(dest);
|
|
5255
|
-
const extractedHome =
|
|
5256
|
-
if (
|
|
5257
|
-
cpSync(extractedHome,
|
|
5465
|
+
const extractedHome = resolve13(extractedMindDir, "home");
|
|
5466
|
+
if (existsSync8(extractedHome)) {
|
|
5467
|
+
cpSync(extractedHome, resolve13(dest, "home"), { recursive: true });
|
|
5258
5468
|
}
|
|
5259
|
-
const extractedMindInternal =
|
|
5260
|
-
if (
|
|
5261
|
-
cpSync(extractedMindInternal,
|
|
5469
|
+
const extractedMindInternal = resolve13(extractedMindDir, ".mind");
|
|
5470
|
+
if (existsSync8(extractedMindInternal)) {
|
|
5471
|
+
cpSync(extractedMindInternal, resolve13(dest, ".mind"), { recursive: true });
|
|
5262
5472
|
}
|
|
5263
|
-
const identityDir =
|
|
5473
|
+
const identityDir = resolve13(dest, ".mind/identity");
|
|
5264
5474
|
let publicKeyPem;
|
|
5265
|
-
if (!manifest.includes.identity || !
|
|
5475
|
+
if (!manifest.includes.identity || !existsSync8(resolve13(identityDir, "private.pem"))) {
|
|
5266
5476
|
({ publicKeyPem } = generateIdentity(dest));
|
|
5267
5477
|
} else {
|
|
5268
|
-
publicKeyPem = readFileSync9(
|
|
5478
|
+
publicKeyPem = readFileSync9(resolve13(identityDir, "public.pem"), "utf-8");
|
|
5269
5479
|
}
|
|
5270
|
-
const promptsPath =
|
|
5271
|
-
if (!
|
|
5480
|
+
const promptsPath = resolve13(dest, "home/.config/prompts.json");
|
|
5481
|
+
if (!existsSync8(promptsPath)) {
|
|
5272
5482
|
const mindPrompts = await getMindPromptDefaults();
|
|
5273
5483
|
writeFileSync8(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
|
|
5274
5484
|
`);
|
|
5275
5485
|
}
|
|
5276
5486
|
const state = stateDir(name);
|
|
5277
5487
|
mkdirSync6(state, { recursive: true });
|
|
5278
|
-
const envJson =
|
|
5279
|
-
if (
|
|
5280
|
-
cpSync(envJson,
|
|
5488
|
+
const envJson = resolve13(tempDir, "state/env.json");
|
|
5489
|
+
if (existsSync8(envJson)) {
|
|
5490
|
+
cpSync(envJson, resolve13(state, "env.json"));
|
|
5281
5491
|
}
|
|
5282
5492
|
const port = await nextPort();
|
|
5283
5493
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
5284
|
-
const homeDir =
|
|
5494
|
+
const homeDir = resolve13(dest, "home");
|
|
5285
5495
|
ensureVoluteGroup();
|
|
5286
5496
|
createMindUser(name, homeDir);
|
|
5287
5497
|
await chownMindDir(dest, name);
|
|
@@ -5294,7 +5504,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5294
5504
|
await initTemplateBranch(dest, composedDir, templateManifest, name, env);
|
|
5295
5505
|
} catch (err) {
|
|
5296
5506
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
5297
|
-
rmSync3(
|
|
5507
|
+
rmSync3(resolve13(dest, ".git"), { recursive: true, force: true });
|
|
5298
5508
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
5299
5509
|
}
|
|
5300
5510
|
const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
|
|
@@ -5324,7 +5534,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5324
5534
|
...skillWarnings.length > 0 && { skillWarnings }
|
|
5325
5535
|
});
|
|
5326
5536
|
} catch (err) {
|
|
5327
|
-
if (
|
|
5537
|
+
if (existsSync8(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5328
5538
|
try {
|
|
5329
5539
|
await removeMind(name);
|
|
5330
5540
|
} catch (cleanupErr) {
|
|
@@ -5337,8 +5547,8 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5337
5547
|
}
|
|
5338
5548
|
}
|
|
5339
5549
|
async function importHistoryFromArchive(name, tempDir) {
|
|
5340
|
-
const historyJsonl =
|
|
5341
|
-
if (!
|
|
5550
|
+
const historyJsonl = resolve13(tempDir, "history.jsonl");
|
|
5551
|
+
if (!existsSync8(historyJsonl)) return;
|
|
5342
5552
|
try {
|
|
5343
5553
|
const db = await getDb();
|
|
5344
5554
|
const lines = readFileSync9(historyJsonl, "utf-8").trim().split("\n");
|
|
@@ -5378,13 +5588,13 @@ async function importHistoryFromArchive(name, tempDir) {
|
|
|
5378
5588
|
}
|
|
5379
5589
|
}
|
|
5380
5590
|
function importSessionsFromArchive(dest, tempDir) {
|
|
5381
|
-
const sessionsDir =
|
|
5382
|
-
if (!
|
|
5591
|
+
const sessionsDir = resolve13(tempDir, "sessions");
|
|
5592
|
+
if (!existsSync8(sessionsDir)) return;
|
|
5383
5593
|
try {
|
|
5384
|
-
const destSessions =
|
|
5594
|
+
const destSessions = resolve13(dest, ".mind/sessions");
|
|
5385
5595
|
mkdirSync6(destSessions, { recursive: true });
|
|
5386
5596
|
for (const file of readdirSync2(sessionsDir)) {
|
|
5387
|
-
cpSync(
|
|
5597
|
+
cpSync(resolve13(sessionsDir, file), resolve13(destSessions, file));
|
|
5388
5598
|
}
|
|
5389
5599
|
} catch (err) {
|
|
5390
5600
|
logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
|
|
@@ -5458,13 +5668,13 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5458
5668
|
);
|
|
5459
5669
|
}
|
|
5460
5670
|
{
|
|
5461
|
-
const { mindLimitError, readGlobalConfig: readGlobalConfig2 } = await import("./setup-
|
|
5671
|
+
const { mindLimitError, readGlobalConfig: readGlobalConfig2 } = await import("./setup-WZSXHHRJ.js");
|
|
5462
5672
|
const limitError = mindLimitError(await countCappedMinds(), readGlobalConfig2().maxMinds);
|
|
5463
5673
|
if (limitError) return c.json({ error: limitError }, 409);
|
|
5464
5674
|
}
|
|
5465
5675
|
ensureVoluteHome();
|
|
5466
5676
|
const dest = mindDir(name);
|
|
5467
|
-
if (
|
|
5677
|
+
if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5468
5678
|
const templatesRoot = findTemplatesRoot();
|
|
5469
5679
|
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5470
5680
|
try {
|
|
@@ -5473,7 +5683,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5473
5683
|
const { publicKeyPem } = generateIdentity(dest);
|
|
5474
5684
|
let effectiveModel = body.model;
|
|
5475
5685
|
{
|
|
5476
|
-
const { readGlobalConfig: readGlobal } = await import("./setup-
|
|
5686
|
+
const { readGlobalConfig: readGlobal } = await import("./setup-WZSXHHRJ.js");
|
|
5477
5687
|
const mindDefaults = readGlobal().mindDefaults;
|
|
5478
5688
|
const config2 = readVoluteConfig(dest);
|
|
5479
5689
|
if (!config2) throw new Error("Failed to read volute.json after identity generation");
|
|
@@ -5501,9 +5711,9 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5501
5711
|
writeVoluteConfig(dest, config2);
|
|
5502
5712
|
const modelId = body.model ?? cog?.model;
|
|
5503
5713
|
effectiveModel = modelId ? qualifyModelId(modelId) : void 0;
|
|
5504
|
-
const sdkConfigPath =
|
|
5714
|
+
const sdkConfigPath = resolve13(dest, "home/.config/config.json");
|
|
5505
5715
|
if (modelId || cog?.compaction) {
|
|
5506
|
-
const existing =
|
|
5716
|
+
const existing = existsSync8(sdkConfigPath) ? JSON.parse(readFileSync9(sdkConfigPath, "utf-8")) : {};
|
|
5507
5717
|
if (modelId) {
|
|
5508
5718
|
existing.model = template === "pi" ? qualifyModelId(modelId) : unqualifyModelId(modelId);
|
|
5509
5719
|
}
|
|
@@ -5516,7 +5726,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5516
5726
|
}
|
|
5517
5727
|
const mindPrompts = await getMindPromptDefaults();
|
|
5518
5728
|
writeFileSync8(
|
|
5519
|
-
|
|
5729
|
+
resolve13(dest, "home/.config/prompts.json"),
|
|
5520
5730
|
`${JSON.stringify(mindPrompts, null, 2)}
|
|
5521
5731
|
`
|
|
5522
5732
|
);
|
|
@@ -5528,7 +5738,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5528
5738
|
} catch (err) {
|
|
5529
5739
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5530
5740
|
}
|
|
5531
|
-
const homeDir =
|
|
5741
|
+
const homeDir = resolve13(dest, "home");
|
|
5532
5742
|
ensureVoluteGroup();
|
|
5533
5743
|
createMindUser(name, homeDir);
|
|
5534
5744
|
await chownMindDir(dest, name);
|
|
@@ -5541,7 +5751,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5541
5751
|
await initTemplateBranch(dest, composedDir, manifest, name, env);
|
|
5542
5752
|
} catch (err) {
|
|
5543
5753
|
logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
|
|
5544
|
-
rmSync3(
|
|
5754
|
+
rmSync3(resolve13(dest, ".git"), { recursive: true, force: true });
|
|
5545
5755
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
5546
5756
|
}
|
|
5547
5757
|
if (body.stage === "seed") {
|
|
@@ -5550,11 +5760,11 @@ Your creator described you as: "${body.description}"
|
|
|
5550
5760
|
` : "";
|
|
5551
5761
|
const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
|
|
5552
5762
|
const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
|
|
5553
|
-
writeFileSync8(
|
|
5763
|
+
writeFileSync8(resolve13(dest, "home/SOUL.md"), seedSoul);
|
|
5554
5764
|
}
|
|
5555
5765
|
let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
|
|
5556
5766
|
if (body.stage === "seed" && !body.skills) {
|
|
5557
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
5767
|
+
const { isImagegenEnabled } = await import("./setup-WZSXHHRJ.js");
|
|
5558
5768
|
if (isImagegenEnabled()) {
|
|
5559
5769
|
skillSet = [...skillSet, "imagegen"];
|
|
5560
5770
|
}
|
|
@@ -5576,7 +5786,7 @@ Your creator described you as: "${body.description}"
|
|
|
5576
5786
|
const spiritName = getSpiritName();
|
|
5577
5787
|
const spiritEntry = await findMind(spiritName);
|
|
5578
5788
|
if (spiritEntry) {
|
|
5579
|
-
const { spiritDir } = await import("./spirit-
|
|
5789
|
+
const { spiritDir } = await import("./spirit-4ECYIVGE.js");
|
|
5580
5790
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
5581
5791
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
5582
5792
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -5591,7 +5801,7 @@ Your creator described you as: "${body.description}"
|
|
|
5591
5801
|
});
|
|
5592
5802
|
spiritConfig.schedules = schedules;
|
|
5593
5803
|
writeVoluteConfig(sDir, spiritConfig);
|
|
5594
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
5804
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-JTTWZDYU.js");
|
|
5595
5805
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
5596
5806
|
}
|
|
5597
5807
|
}
|
|
@@ -5602,11 +5812,11 @@ Your creator described you as: "${body.description}"
|
|
|
5602
5812
|
if (body.stage !== "seed") {
|
|
5603
5813
|
const customSoul = await getPromptIfCustom("default_soul");
|
|
5604
5814
|
if (customSoul) {
|
|
5605
|
-
writeFileSync8(
|
|
5815
|
+
writeFileSync8(resolve13(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
|
|
5606
5816
|
}
|
|
5607
5817
|
const customMemory = await getPromptIfCustom("default_memory");
|
|
5608
5818
|
if (customMemory) {
|
|
5609
|
-
writeFileSync8(
|
|
5819
|
+
writeFileSync8(resolve13(dest, "home/MEMORY.md"), customMemory);
|
|
5610
5820
|
}
|
|
5611
5821
|
}
|
|
5612
5822
|
await chownMindDir(dest, name);
|
|
@@ -5624,8 +5834,9 @@ Your creator described you as: "${body.description}"
|
|
|
5624
5834
|
description: body.description
|
|
5625
5835
|
}
|
|
5626
5836
|
});
|
|
5627
|
-
announceToSystem(`${name} has joined`).catch(
|
|
5628
|
-
|
|
5837
|
+
announceToSystem(`${name} has joined`).catch(
|
|
5838
|
+
(err) => logger_default.warn(`failed to announce ${name} joining #system`, logger_default.errorData(err))
|
|
5839
|
+
);
|
|
5629
5840
|
const credentialWarning = await missingCredentialWarning(
|
|
5630
5841
|
template,
|
|
5631
5842
|
effectiveModel,
|
|
@@ -5645,10 +5856,11 @@ Your creator described you as: "${body.description}"
|
|
|
5645
5856
|
...skillWarnings.length > 0 && { skillWarnings }
|
|
5646
5857
|
});
|
|
5647
5858
|
} catch (err) {
|
|
5648
|
-
if (
|
|
5859
|
+
if (existsSync8(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5649
5860
|
try {
|
|
5650
5861
|
await removeMind(name);
|
|
5651
|
-
} catch {
|
|
5862
|
+
} catch (cleanupErr) {
|
|
5863
|
+
logger_default.warn(`failed to clean up registry for ${name}`, logger_default.errorData(cleanupErr));
|
|
5652
5864
|
}
|
|
5653
5865
|
return c.json({ error: err instanceof Error ? err.message : "Failed to create mind" }, 500);
|
|
5654
5866
|
} finally {
|
|
@@ -5665,13 +5877,13 @@ Your creator described you as: "${body.description}"
|
|
|
5665
5877
|
return importFromArchive(c, body.archivePath, body.name, body.manifest);
|
|
5666
5878
|
}
|
|
5667
5879
|
const wsDir = body.workspacePath;
|
|
5668
|
-
if (!wsDir || !
|
|
5880
|
+
if (!wsDir || !existsSync8(resolve13(wsDir, "SOUL.md")) || !existsSync8(resolve13(wsDir, "IDENTITY.md"))) {
|
|
5669
5881
|
return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
|
|
5670
5882
|
}
|
|
5671
|
-
const soul = readFileSync9(
|
|
5672
|
-
const identity = readFileSync9(
|
|
5673
|
-
const userPath =
|
|
5674
|
-
const user =
|
|
5883
|
+
const soul = readFileSync9(resolve13(wsDir, "SOUL.md"), "utf-8");
|
|
5884
|
+
const identity = readFileSync9(resolve13(wsDir, "IDENTITY.md"), "utf-8");
|
|
5885
|
+
const userPath = resolve13(wsDir, "USER.md");
|
|
5886
|
+
const user = existsSync8(userPath) ? readFileSync9(userPath, "utf-8") : "";
|
|
5675
5887
|
const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
|
|
5676
5888
|
const template = body.template ?? "claude";
|
|
5677
5889
|
const nameErr = validateMindName(name);
|
|
@@ -5691,33 +5903,33 @@ ${user.trimEnd()}
|
|
|
5691
5903
|
` : "";
|
|
5692
5904
|
ensureVoluteHome();
|
|
5693
5905
|
const dest = mindDir(name);
|
|
5694
|
-
if (
|
|
5906
|
+
if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5695
5907
|
const templatesRoot = findTemplatesRoot();
|
|
5696
5908
|
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5697
5909
|
try {
|
|
5698
5910
|
copyTemplateToDir(composedDir, dest, name, manifest);
|
|
5699
5911
|
applyInitFiles(dest);
|
|
5700
5912
|
const { publicKeyPem: importPublicKey } = generateIdentity(dest);
|
|
5701
|
-
writeFileSync8(
|
|
5702
|
-
const wsMemoryPath =
|
|
5703
|
-
const hasMemory =
|
|
5913
|
+
writeFileSync8(resolve13(dest, "home/SOUL.md"), mergedSoul);
|
|
5914
|
+
const wsMemoryPath = resolve13(wsDir, "MEMORY.md");
|
|
5915
|
+
const hasMemory = existsSync8(wsMemoryPath);
|
|
5704
5916
|
if (hasMemory) {
|
|
5705
5917
|
const existingMemory = readFileSync9(wsMemoryPath, "utf-8");
|
|
5706
5918
|
writeFileSync8(
|
|
5707
|
-
|
|
5919
|
+
resolve13(dest, "home/MEMORY.md"),
|
|
5708
5920
|
`${existingMemory.trimEnd()}${mergedMemoryExtra}`
|
|
5709
5921
|
);
|
|
5710
5922
|
} else if (user) {
|
|
5711
|
-
writeFileSync8(
|
|
5923
|
+
writeFileSync8(resolve13(dest, "home/MEMORY.md"), `${user.trimEnd()}
|
|
5712
5924
|
`);
|
|
5713
5925
|
}
|
|
5714
|
-
const wsMemoryDir =
|
|
5926
|
+
const wsMemoryDir = resolve13(wsDir, "memory");
|
|
5715
5927
|
let dailyLogCount = 0;
|
|
5716
|
-
if (
|
|
5717
|
-
const destMemoryDir =
|
|
5928
|
+
if (existsSync8(wsMemoryDir)) {
|
|
5929
|
+
const destMemoryDir = resolve13(dest, "home/memory");
|
|
5718
5930
|
const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
|
|
5719
5931
|
for (const file of files) {
|
|
5720
|
-
cpSync(
|
|
5932
|
+
cpSync(resolve13(wsMemoryDir, file), resolve13(destMemoryDir, file));
|
|
5721
5933
|
}
|
|
5722
5934
|
dailyLogCount = files.length;
|
|
5723
5935
|
}
|
|
@@ -5728,7 +5940,7 @@ ${user.trimEnd()}
|
|
|
5728
5940
|
} catch (err) {
|
|
5729
5941
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5730
5942
|
}
|
|
5731
|
-
const homeDir =
|
|
5943
|
+
const homeDir = resolve13(dest, "home");
|
|
5732
5944
|
ensureVoluteGroup();
|
|
5733
5945
|
createMindUser(name, homeDir);
|
|
5734
5946
|
await chownMindDir(dest, name);
|
|
@@ -5736,20 +5948,20 @@ ${user.trimEnd()}
|
|
|
5736
5948
|
if (!hasMemory && dailyLogCount > 0) {
|
|
5737
5949
|
await consolidateMemory(dest);
|
|
5738
5950
|
}
|
|
5739
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5951
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve13(dest, "home") } : void 0;
|
|
5740
5952
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
5741
5953
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
5742
5954
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
5743
5955
|
await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
|
|
5744
|
-
const sessionFile = body.sessionPath ?
|
|
5745
|
-
if (sessionFile &&
|
|
5956
|
+
const sessionFile = body.sessionPath ? resolve13(body.sessionPath) : findOpenClawSession(wsDir);
|
|
5957
|
+
if (sessionFile && existsSync8(sessionFile)) {
|
|
5746
5958
|
if (template === "pi") {
|
|
5747
5959
|
importPiSession(sessionFile, dest);
|
|
5748
5960
|
} else if (template === "claude") {
|
|
5749
5961
|
const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
|
|
5750
|
-
const mindRuntimeDir =
|
|
5962
|
+
const mindRuntimeDir = resolve13(dest, ".mind");
|
|
5751
5963
|
mkdirSync6(mindRuntimeDir, { recursive: true });
|
|
5752
|
-
writeFileSync8(
|
|
5964
|
+
writeFileSync8(resolve13(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
|
|
5753
5965
|
}
|
|
5754
5966
|
}
|
|
5755
5967
|
importOpenClawConnectors(name, dest);
|
|
@@ -5759,10 +5971,11 @@ ${user.trimEnd()}
|
|
|
5759
5971
|
);
|
|
5760
5972
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
5761
5973
|
} catch (err) {
|
|
5762
|
-
if (
|
|
5974
|
+
if (existsSync8(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5763
5975
|
try {
|
|
5764
5976
|
await removeMind(name);
|
|
5765
|
-
} catch {
|
|
5977
|
+
} catch (cleanupErr) {
|
|
5978
|
+
logger_default.warn(`failed to clean up registry for ${name}`, logger_default.errorData(cleanupErr));
|
|
5766
5979
|
}
|
|
5767
5980
|
return c.json({ error: err instanceof Error ? err.message : "Failed to import mind" }, 500);
|
|
5768
5981
|
} finally {
|
|
@@ -5794,7 +6007,7 @@ ${user.trimEnd()}
|
|
|
5794
6007
|
stage: entry.stage,
|
|
5795
6008
|
dir: entry.dir
|
|
5796
6009
|
});
|
|
5797
|
-
const hasPages =
|
|
6010
|
+
const hasPages = existsSync8(resolve13(mindDir(entry.name), "home", "pages"));
|
|
5798
6011
|
const lastActiveAt = lastActiveMap.get(entry.name) ?? null;
|
|
5799
6012
|
if (!privileged) return toPublicMind(entry, mindStatus, { hasPages, lastActiveAt });
|
|
5800
6013
|
return {
|
|
@@ -5812,12 +6025,12 @@ ${user.trimEnd()}
|
|
|
5812
6025
|
const entry = await findMind(name);
|
|
5813
6026
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
5814
6027
|
const dir = entry.dir ?? mindDir(entry.parent ?? name);
|
|
5815
|
-
if (!
|
|
6028
|
+
if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
5816
6029
|
const mindStatus = await getMindStatus(name, entry.port, void 0, {
|
|
5817
6030
|
stage: entry.stage,
|
|
5818
6031
|
dir: entry.dir
|
|
5819
6032
|
});
|
|
5820
|
-
const hasPages =
|
|
6033
|
+
const hasPages = existsSync8(resolve13(mindDir(name), "home", "pages"));
|
|
5821
6034
|
if (!isPrivileged(c)) {
|
|
5822
6035
|
return c.json(toPublicMind(entry, mindStatus, { hasPages }));
|
|
5823
6036
|
}
|
|
@@ -5857,7 +6070,7 @@ ${user.trimEnd()}
|
|
|
5857
6070
|
const projectDir = entry.dir ?? mindDir(name);
|
|
5858
6071
|
if (entry.parent) {
|
|
5859
6072
|
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
|
|
5860
|
-
} else if (!
|
|
6073
|
+
} else if (!existsSync8(projectDir)) {
|
|
5861
6074
|
return c.json({ error: "Mind directory missing" }, 404);
|
|
5862
6075
|
}
|
|
5863
6076
|
if (getMindManager().isRunning(name)) {
|
|
@@ -5878,7 +6091,7 @@ ${user.trimEnd()}
|
|
|
5878
6091
|
const projectDir = entry.dir ?? mindDir(name);
|
|
5879
6092
|
if (entry.parent) {
|
|
5880
6093
|
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
|
|
5881
|
-
} else if (!
|
|
6094
|
+
} else if (!existsSync8(projectDir)) {
|
|
5882
6095
|
return c.json({ error: "Mind directory missing" }, 404);
|
|
5883
6096
|
}
|
|
5884
6097
|
let context;
|
|
@@ -5894,7 +6107,7 @@ ${user.trimEnd()}
|
|
|
5894
6107
|
const manager = getMindManager();
|
|
5895
6108
|
try {
|
|
5896
6109
|
if (context?.type === "reload") {
|
|
5897
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6110
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OFP2GFXF.js");
|
|
5898
6111
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
5899
6112
|
if (sleepState?.sleeping) {
|
|
5900
6113
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -5914,7 +6127,8 @@ ${user.trimEnd()}
|
|
|
5914
6127
|
const variantEntry = await findMind(mergeVariantName);
|
|
5915
6128
|
if (variantEntry && variantEntry.parent === baseName && variantEntry.dir && variantEntry.branch) {
|
|
5916
6129
|
const projectRoot = mindDir(baseName);
|
|
5917
|
-
|
|
6130
|
+
const discardUnresolved = context.discardUnresolvedHomeFiles === true;
|
|
6131
|
+
if (existsSync8(variantEntry.dir)) {
|
|
5918
6132
|
const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
|
|
5919
6133
|
if (status) {
|
|
5920
6134
|
try {
|
|
@@ -5941,13 +6155,44 @@ ${user.trimEnd()}
|
|
|
5941
6155
|
logger_default.error(`failed to auto-commit main worktree for ${baseName}`, logger_default.errorData(e));
|
|
5942
6156
|
}
|
|
5943
6157
|
}
|
|
6158
|
+
const preMergeHead = (await gitExec(["rev-parse", "HEAD"], { cwd: projectRoot })).trim();
|
|
5944
6159
|
const memoryDelta = await mergeVariantExcludingMemory(projectRoot, variantEntry.branch);
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
6160
|
+
let unresolvedNotice;
|
|
6161
|
+
if (existsSync8(variantEntry.dir) && !discardUnresolved) {
|
|
6162
|
+
try {
|
|
6163
|
+
const unresolved = await findUnresolvedHomeFiles(variantEntry.dir);
|
|
6164
|
+
if (unresolved.totalCount > 0) {
|
|
6165
|
+
unresolvedNotice = formatUnresolvedHomeFilesMessage(mergeVariantName, unresolved);
|
|
6166
|
+
}
|
|
6167
|
+
} catch (err) {
|
|
6168
|
+
unresolvedNotice = `Could not verify variant ${mergeVariantName} has no unresolved home/ files: ${err instanceof Error ? err.message : String(err)}. Variant left intact \u2014 retry the join.`;
|
|
6169
|
+
}
|
|
6170
|
+
}
|
|
6171
|
+
if (unresolvedNotice) {
|
|
6172
|
+
logger_default.warn(
|
|
6173
|
+
`variant join blocked for ${baseName}: ${mergeVariantName} \u2014 ${unresolvedNotice}`
|
|
6174
|
+
);
|
|
6175
|
+
await recordNotice({
|
|
6176
|
+
mind: baseName,
|
|
6177
|
+
thread: "main",
|
|
6178
|
+
kind: "join_blocked",
|
|
6179
|
+
reason: "unresolved_variant_files",
|
|
6180
|
+
detail: unresolvedNotice
|
|
6181
|
+
});
|
|
6182
|
+
if (context) {
|
|
6183
|
+
context.type = "restart";
|
|
6184
|
+
context.name = void 0;
|
|
6185
|
+
}
|
|
6186
|
+
} else {
|
|
6187
|
+
if (memoryDelta && context) context.memoryDelta = memoryDelta;
|
|
6188
|
+
await cleanupVariant(mergeVariantName, baseName, projectRoot, variantEntry.dir);
|
|
6189
|
+
if (await npmInstallNeeded(projectRoot, preMergeHead)) {
|
|
6190
|
+
try {
|
|
6191
|
+
await npmInstallAsMind(projectRoot, baseName);
|
|
6192
|
+
} catch (e) {
|
|
6193
|
+
logger_default.error(`npm install failed after merge for ${baseName}`, logger_default.errorData(e));
|
|
6194
|
+
}
|
|
6195
|
+
}
|
|
5951
6196
|
}
|
|
5952
6197
|
}
|
|
5953
6198
|
}
|
|
@@ -5989,6 +6234,7 @@ ${user.trimEnd()}
|
|
|
5989
6234
|
);
|
|
5990
6235
|
return c.json({ ok: true, port: targetPort });
|
|
5991
6236
|
} catch (err) {
|
|
6237
|
+
logger_default.error(`failed to restart mind ${name}`, logger_default.errorData(err));
|
|
5992
6238
|
return c.json({ error: err instanceof Error ? err.message : "Failed to restart mind" }, 500);
|
|
5993
6239
|
}
|
|
5994
6240
|
}).post("/:name/stop", requireSelf(), async (c) => {
|
|
@@ -6003,13 +6249,14 @@ ${user.trimEnd()}
|
|
|
6003
6249
|
await stopMindFull(name);
|
|
6004
6250
|
return c.json({ ok: true });
|
|
6005
6251
|
} catch (err) {
|
|
6252
|
+
logger_default.error(`failed to stop mind ${name}`, logger_default.errorData(err));
|
|
6006
6253
|
return c.json({ error: err instanceof Error ? err.message : "Failed to stop mind" }, 500);
|
|
6007
6254
|
}
|
|
6008
6255
|
}).get("/:name/sleep", requireSelf(), async (c) => {
|
|
6009
6256
|
const name = c.req.param("name");
|
|
6010
6257
|
const entry = await findMind(name);
|
|
6011
6258
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6012
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6259
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OFP2GFXF.js");
|
|
6013
6260
|
const sm = getSleepManagerIfReady2();
|
|
6014
6261
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6015
6262
|
return c.json(sm.getState(name));
|
|
@@ -6017,7 +6264,7 @@ ${user.trimEnd()}
|
|
|
6017
6264
|
const name = c.req.param("name");
|
|
6018
6265
|
const entry = await findMind(name);
|
|
6019
6266
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6020
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6267
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OFP2GFXF.js");
|
|
6021
6268
|
const sm = getSleepManagerIfReady2();
|
|
6022
6269
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6023
6270
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -6037,7 +6284,7 @@ ${user.trimEnd()}
|
|
|
6037
6284
|
const name = c.req.param("name");
|
|
6038
6285
|
const entry = await findMind(name);
|
|
6039
6286
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6040
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6287
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OFP2GFXF.js");
|
|
6041
6288
|
const sm = getSleepManagerIfReady2();
|
|
6042
6289
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6043
6290
|
const sleepState = sm.getState(name);
|
|
@@ -6052,7 +6299,7 @@ ${user.trimEnd()}
|
|
|
6052
6299
|
const name = c.req.param("name");
|
|
6053
6300
|
const entry = await findMind(name);
|
|
6054
6301
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6055
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6302
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OFP2GFXF.js");
|
|
6056
6303
|
const sm = getSleepManagerIfReady2();
|
|
6057
6304
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6058
6305
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -6068,19 +6315,19 @@ ${user.trimEnd()}
|
|
|
6068
6315
|
if (body.displayName !== void 0) profile.displayName = body.displayName;
|
|
6069
6316
|
if (body.description !== void 0) profile.description = body.description;
|
|
6070
6317
|
if (body.avatar !== void 0) {
|
|
6071
|
-
const homeDir =
|
|
6318
|
+
const homeDir = resolve13(dir, "home");
|
|
6072
6319
|
const avatarPath = safeResolveWithinBase(homeDir, body.avatar);
|
|
6073
6320
|
if (!avatarPath) {
|
|
6074
6321
|
return c.json({ error: "Avatar path must be inside the mind's home directory" }, 400);
|
|
6075
6322
|
}
|
|
6076
|
-
if (!
|
|
6323
|
+
if (!existsSync8(avatarPath)) {
|
|
6077
6324
|
return c.json({ error: `Avatar file not found: ${relative(homeDir, avatarPath)}` }, 400);
|
|
6078
6325
|
}
|
|
6079
6326
|
profile.avatar = relative(homeDir, avatarPath);
|
|
6080
6327
|
}
|
|
6081
6328
|
config2.profile = profile;
|
|
6082
6329
|
writeVoluteConfig(dir, config2);
|
|
6083
|
-
const { syncMindProfile: syncMindProfile2 } = await import("./auth-
|
|
6330
|
+
const { syncMindProfile: syncMindProfile2 } = await import("./auth-KRDSM55Q.js");
|
|
6084
6331
|
await syncMindProfile2(name, profile);
|
|
6085
6332
|
broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
|
|
6086
6333
|
return c.json({ ok: true });
|
|
@@ -6124,7 +6371,7 @@ ${user.trimEnd()}
|
|
|
6124
6371
|
});
|
|
6125
6372
|
}
|
|
6126
6373
|
if (!force) {
|
|
6127
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6374
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-OFP2GFXF.js");
|
|
6128
6375
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
6129
6376
|
return c.json({ output: "" });
|
|
6130
6377
|
}
|
|
@@ -6179,7 +6426,7 @@ ${user.trimEnd()}
|
|
|
6179
6426
|
}
|
|
6180
6427
|
}
|
|
6181
6428
|
const dir = entry.dir ?? mindDir(name);
|
|
6182
|
-
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-
|
|
6429
|
+
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-DYOVCYHN.js");
|
|
6183
6430
|
const checklist = evaluateSeedChecklist2(dir);
|
|
6184
6431
|
const done = [];
|
|
6185
6432
|
const remaining = [];
|
|
@@ -6221,7 +6468,7 @@ ${user.trimEnd()}
|
|
|
6221
6468
|
try {
|
|
6222
6469
|
const sproutedDir = entry.dir ?? mindDir(name);
|
|
6223
6470
|
if (setupDefaultDreaming(sproutedDir).schedulesChanged) {
|
|
6224
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6471
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-JTTWZDYU.js");
|
|
6225
6472
|
getScheduler2().loadSchedules(name, sproutedDir);
|
|
6226
6473
|
}
|
|
6227
6474
|
} catch (err) {
|
|
@@ -6231,7 +6478,7 @@ ${user.trimEnd()}
|
|
|
6231
6478
|
const spiritName = getSpiritName();
|
|
6232
6479
|
const spiritEntry = await findMind(spiritName);
|
|
6233
6480
|
if (spiritEntry) {
|
|
6234
|
-
const { firstWeekSchedules, spiritDir } = await import("./spirit-
|
|
6481
|
+
const { firstWeekSchedules, spiritDir } = await import("./spirit-4ECYIVGE.js");
|
|
6235
6482
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
6236
6483
|
const spiritConfig = readVoluteConfig(sDir);
|
|
6237
6484
|
if (spiritConfig) {
|
|
@@ -6245,7 +6492,7 @@ ${user.trimEnd()}
|
|
|
6245
6492
|
spiritConfig.schedules = schedules;
|
|
6246
6493
|
writeVoluteConfig(sDir, spiritConfig);
|
|
6247
6494
|
try {
|
|
6248
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6495
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-JTTWZDYU.js");
|
|
6249
6496
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
6250
6497
|
} catch (err) {
|
|
6251
6498
|
logger_default.warn(
|
|
@@ -6267,26 +6514,42 @@ ${user.trimEnd()}
|
|
|
6267
6514
|
const name = c.req.param("name");
|
|
6268
6515
|
const entry = await findMind(name);
|
|
6269
6516
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6517
|
+
const manager = getMindManager();
|
|
6518
|
+
if (entry.parent) {
|
|
6519
|
+
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 500);
|
|
6520
|
+
const parentEntry = await findMind(entry.parent);
|
|
6521
|
+
if (!parentEntry) return c.json({ error: `Parent mind ${entry.parent} not found` }, 404);
|
|
6522
|
+
if (manager.isRunning(name)) {
|
|
6523
|
+
await stopMindFull(name);
|
|
6524
|
+
}
|
|
6525
|
+
await cleanupVariant(name, entry.parent, parentEntry.dir ?? mindDir(entry.parent), entry.dir);
|
|
6526
|
+
invalidateMindUserCache(name);
|
|
6527
|
+
fireWebhook({
|
|
6528
|
+
event: "mind_deleted",
|
|
6529
|
+
mind: name,
|
|
6530
|
+
data: { port: entry.port, stage: entry.stage, template: entry.template }
|
|
6531
|
+
});
|
|
6532
|
+
return c.json({ ok: true, variant: true });
|
|
6533
|
+
}
|
|
6270
6534
|
const dir = mindDir(name);
|
|
6271
6535
|
const force = c.req.query("force") === "true";
|
|
6272
|
-
const manager = getMindManager();
|
|
6273
6536
|
if (manager.isRunning(name)) {
|
|
6274
6537
|
await stopMindFull(name);
|
|
6275
6538
|
}
|
|
6276
6539
|
const variants = await findVariants(name);
|
|
6277
6540
|
for (const s of variants) {
|
|
6278
6541
|
if (s.dir) {
|
|
6279
|
-
await cleanupVariant(s.name, dir, s.dir, { stop: true });
|
|
6542
|
+
await cleanupVariant(s.name, name, dir, s.dir, { stop: true });
|
|
6280
6543
|
}
|
|
6281
6544
|
}
|
|
6282
6545
|
await removeMind(name);
|
|
6283
6546
|
await deleteMindUser2(name);
|
|
6284
6547
|
invalidateMindUserCache(name);
|
|
6285
6548
|
const state = stateDir(name);
|
|
6286
|
-
if (
|
|
6549
|
+
if (existsSync8(state)) {
|
|
6287
6550
|
rmSync3(state, { recursive: true, force: true });
|
|
6288
6551
|
}
|
|
6289
|
-
if (force &&
|
|
6552
|
+
if (force && existsSync8(dir)) {
|
|
6290
6553
|
rmSync3(dir, { recursive: true, force: true });
|
|
6291
6554
|
deleteMindUser(name);
|
|
6292
6555
|
}
|
|
@@ -6301,7 +6564,7 @@ ${user.trimEnd()}
|
|
|
6301
6564
|
const entry = await findMind(mindName);
|
|
6302
6565
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6303
6566
|
const dir = mindDir(mindName);
|
|
6304
|
-
if (!
|
|
6567
|
+
if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6305
6568
|
let body = {};
|
|
6306
6569
|
try {
|
|
6307
6570
|
body = await c.req.json();
|
|
@@ -6314,21 +6577,21 @@ ${user.trimEnd()}
|
|
|
6314
6577
|
}
|
|
6315
6578
|
const UPGRADE_BRANCH = "upgrade";
|
|
6316
6579
|
const upgradeVariantName = `${mindName}-upgrade`;
|
|
6317
|
-
const worktreeDir =
|
|
6580
|
+
const worktreeDir = resolve13(dir, ".variants", UPGRADE_BRANCH);
|
|
6318
6581
|
if (body.abort) {
|
|
6319
|
-
if (!
|
|
6582
|
+
if (!existsSync8(worktreeDir)) {
|
|
6320
6583
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
6321
6584
|
}
|
|
6322
6585
|
try {
|
|
6323
6586
|
try {
|
|
6324
|
-
const gitDirContent = readFileSync9(
|
|
6587
|
+
const gitDirContent = readFileSync9(resolve13(worktreeDir, ".git"), "utf-8").trim();
|
|
6325
6588
|
const gitDir = gitDirContent.replace("gitdir: ", "");
|
|
6326
|
-
if (
|
|
6589
|
+
if (existsSync8(resolve13(gitDir, "MERGE_HEAD"))) {
|
|
6327
6590
|
await gitExec(["merge", "--abort"], { cwd: worktreeDir });
|
|
6328
6591
|
}
|
|
6329
6592
|
} catch {
|
|
6330
6593
|
}
|
|
6331
|
-
await cleanupVariant(upgradeVariantName, dir, worktreeDir, { stop: true });
|
|
6594
|
+
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir, { stop: true });
|
|
6332
6595
|
try {
|
|
6333
6596
|
await gitExec(["branch", "-D", UPGRADE_BRANCH], { cwd: dir });
|
|
6334
6597
|
} catch {
|
|
@@ -6342,7 +6605,7 @@ ${user.trimEnd()}
|
|
|
6342
6605
|
}
|
|
6343
6606
|
}
|
|
6344
6607
|
if (body.continue) {
|
|
6345
|
-
if (!
|
|
6608
|
+
if (!existsSync8(worktreeDir)) {
|
|
6346
6609
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
6347
6610
|
}
|
|
6348
6611
|
const status = await gitExec(["status", "--porcelain"], { cwd: worktreeDir });
|
|
@@ -6392,9 +6655,9 @@ ${user.trimEnd()}
|
|
|
6392
6655
|
}
|
|
6393
6656
|
}
|
|
6394
6657
|
if (body.accept) {
|
|
6395
|
-
if (
|
|
6658
|
+
if (existsSync8(worktreeDir)) {
|
|
6396
6659
|
try {
|
|
6397
|
-
await cleanupVariant(upgradeVariantName, dir, worktreeDir, { stop: true });
|
|
6660
|
+
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir, { stop: true });
|
|
6398
6661
|
} catch (err) {
|
|
6399
6662
|
logger_default.warn(`failed to clean up legacy upgrade variant for ${mindName}`, logger_default.errorData(err));
|
|
6400
6663
|
}
|
|
@@ -6407,7 +6670,7 @@ ${user.trimEnd()}
|
|
|
6407
6670
|
}
|
|
6408
6671
|
if (body.diff) {
|
|
6409
6672
|
try {
|
|
6410
|
-
if (!
|
|
6673
|
+
if (!existsSync8(resolve13(dir, ".git"))) {
|
|
6411
6674
|
return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
|
|
6412
6675
|
}
|
|
6413
6676
|
await updateTemplateBranch(dir, template, mindName);
|
|
@@ -6425,22 +6688,22 @@ ${user.trimEnd()}
|
|
|
6425
6688
|
);
|
|
6426
6689
|
}
|
|
6427
6690
|
}
|
|
6428
|
-
if (
|
|
6691
|
+
if (existsSync8(worktreeDir)) {
|
|
6429
6692
|
return c.json(
|
|
6430
6693
|
{ error: "Upgrade variant already exists. Use continue or delete it first." },
|
|
6431
6694
|
409
|
|
6432
6695
|
);
|
|
6433
6696
|
}
|
|
6434
|
-
if (!
|
|
6697
|
+
if (!existsSync8(resolve13(dir, ".git"))) {
|
|
6435
6698
|
try {
|
|
6436
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
6699
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve13(dir, "home") } : void 0;
|
|
6437
6700
|
await gitExec(["init"], { cwd: dir, mindName, env });
|
|
6438
6701
|
await configureGitIdentity(mindName, { cwd: dir, mindName, env });
|
|
6439
6702
|
await gitExec(["add", "-A"], { cwd: dir, mindName, env });
|
|
6440
6703
|
await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
|
|
6441
6704
|
await chownMindDir(dir, mindName);
|
|
6442
6705
|
} catch (err) {
|
|
6443
|
-
rmSync3(
|
|
6706
|
+
rmSync3(resolve13(dir, ".git"), { recursive: true, force: true });
|
|
6444
6707
|
return c.json(
|
|
6445
6708
|
{
|
|
6446
6709
|
error: `Git initialization failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -6455,8 +6718,8 @@ ${user.trimEnd()}
|
|
|
6455
6718
|
} catch {
|
|
6456
6719
|
}
|
|
6457
6720
|
await updateTemplateBranch(dir, template, mindName);
|
|
6458
|
-
const parentDir =
|
|
6459
|
-
if (!
|
|
6721
|
+
const parentDir = resolve13(dir, ".variants");
|
|
6722
|
+
if (!existsSync8(parentDir)) {
|
|
6460
6723
|
mkdirSync6(parentDir, { recursive: true });
|
|
6461
6724
|
}
|
|
6462
6725
|
await gitExec(["worktree", "add", "-b", UPGRADE_BRANCH, worktreeDir], { cwd: dir });
|
|
@@ -6519,7 +6782,7 @@ ${user.trimEnd()}
|
|
|
6519
6782
|
return c.json(result);
|
|
6520
6783
|
} catch (err) {
|
|
6521
6784
|
try {
|
|
6522
|
-
await cleanupVariant(upgradeVariantName, dir, worktreeDir);
|
|
6785
|
+
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir);
|
|
6523
6786
|
} catch (cleanupErr) {
|
|
6524
6787
|
logger_default.warn(`cleanup failed after upgrade error for ${mindName}`, logger_default.errorData(cleanupErr));
|
|
6525
6788
|
}
|
|
@@ -6589,11 +6852,11 @@ ${user.trimEnd()}
|
|
|
6589
6852
|
const entry = await findMind(name);
|
|
6590
6853
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6591
6854
|
const dir = entry.dir ?? mindDir(name);
|
|
6592
|
-
if (!
|
|
6855
|
+
if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6593
6856
|
let config2 = readVoluteConfig(dir);
|
|
6594
6857
|
if (!config2 && entry.template === "pi") {
|
|
6595
|
-
const piConfigPath =
|
|
6596
|
-
if (
|
|
6858
|
+
const piConfigPath = resolve13(dir, "home/.config/config.json");
|
|
6859
|
+
if (existsSync8(piConfigPath)) {
|
|
6597
6860
|
try {
|
|
6598
6861
|
config2 = JSON.parse(readFileSync9(piConfigPath, "utf-8"));
|
|
6599
6862
|
} catch {
|
|
@@ -6601,8 +6864,8 @@ ${user.trimEnd()}
|
|
|
6601
6864
|
}
|
|
6602
6865
|
}
|
|
6603
6866
|
let templateConfig = {};
|
|
6604
|
-
const configJsonPath =
|
|
6605
|
-
if (
|
|
6867
|
+
const configJsonPath = resolve13(dir, "home/.config/config.json");
|
|
6868
|
+
if (existsSync8(configJsonPath)) {
|
|
6606
6869
|
try {
|
|
6607
6870
|
templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
|
|
6608
6871
|
} catch {
|
|
@@ -6644,7 +6907,7 @@ ${user.trimEnd()}
|
|
|
6644
6907
|
const entry = await findMind(name);
|
|
6645
6908
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6646
6909
|
const dir = entry.dir ?? mindDir(name);
|
|
6647
|
-
if (!
|
|
6910
|
+
if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6648
6911
|
const body = c.req.valid("json");
|
|
6649
6912
|
const existing = readVoluteConfig(dir) ?? {};
|
|
6650
6913
|
if (body.model !== void 0) existing.model = body.model;
|
|
@@ -6670,14 +6933,14 @@ ${user.trimEnd()}
|
|
|
6670
6933
|
}
|
|
6671
6934
|
writeVoluteConfig(dir, existing);
|
|
6672
6935
|
if (body.unescapeNewlines !== void 0) {
|
|
6673
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
6936
|
+
const { clearEchoTextCache } = await import("./echo-text-PEEV7FQU.js");
|
|
6674
6937
|
clearEchoTextCache(name);
|
|
6675
6938
|
}
|
|
6676
6939
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.compaction !== void 0;
|
|
6677
6940
|
if (needsConfigJson) {
|
|
6678
|
-
const configJsonPath =
|
|
6941
|
+
const configJsonPath = resolve13(dir, "home/.config/config.json");
|
|
6679
6942
|
let templateConfig = {};
|
|
6680
|
-
if (
|
|
6943
|
+
if (existsSync8(configJsonPath)) {
|
|
6681
6944
|
try {
|
|
6682
6945
|
templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
|
|
6683
6946
|
} catch {
|
|
@@ -6707,7 +6970,7 @@ ${user.trimEnd()}
|
|
|
6707
6970
|
}
|
|
6708
6971
|
if (entry.mindType === "spirit" && body.model !== void 0) {
|
|
6709
6972
|
try {
|
|
6710
|
-
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-
|
|
6973
|
+
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-WZSXHHRJ.js");
|
|
6711
6974
|
const globalConfig = readGlobalConfig2();
|
|
6712
6975
|
globalConfig.spiritModel = body.model;
|
|
6713
6976
|
writeGlobalConfig2(globalConfig);
|
|
@@ -6750,7 +7013,7 @@ ${user.trimEnd()}
|
|
|
6750
7013
|
if (!body.systemPrompt || !body.message) {
|
|
6751
7014
|
return c.json({ error: "systemPrompt and message required" }, 400);
|
|
6752
7015
|
}
|
|
6753
|
-
const { aiComplete: aiCompleteFn, isAiConfigured: isAiConfigured2 } = await import("./ai-service-
|
|
7016
|
+
const { aiComplete: aiCompleteFn, isAiConfigured: isAiConfigured2 } = await import("./ai-service-YW5SWCSB.js");
|
|
6754
7017
|
if (!isAiConfigured2()) {
|
|
6755
7018
|
return c.json({ error: "AI service not configured" }, 503);
|
|
6756
7019
|
}
|
|
@@ -7444,7 +7707,7 @@ var app15 = new Hono18().get("/:name/clock/status", requireSelf(), async (c) =>
|
|
|
7444
7707
|
const entry = await findMind(name);
|
|
7445
7708
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
7446
7709
|
const body = await c.req.text();
|
|
7447
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
7710
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-V43HDA3T.js");
|
|
7448
7711
|
const { id, delivered } = await deliverEvent2(name, {
|
|
7449
7712
|
type: "webhook",
|
|
7450
7713
|
body,
|
|
@@ -7462,14 +7725,14 @@ var schedules_default = app15;
|
|
|
7462
7725
|
// packages/daemon/src/web/api/setup.ts
|
|
7463
7726
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
7464
7727
|
import { homedir as homedir2 } from "os";
|
|
7465
|
-
import { resolve as
|
|
7728
|
+
import { resolve as resolve14 } from "path";
|
|
7466
7729
|
import { Hono as Hono19 } from "hono";
|
|
7467
7730
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
7468
7731
|
var DEFAULT_API_URL2 = "https://volute.systems";
|
|
7469
7732
|
var setup = new Hono19();
|
|
7470
7733
|
function writeSetupConfig(systemName, description) {
|
|
7471
|
-
const configHome = process.env.VOLUTE_HOME ??
|
|
7472
|
-
const mindsDir =
|
|
7734
|
+
const configHome = process.env.VOLUTE_HOME ?? resolve14(homedir2(), ".volute");
|
|
7735
|
+
const mindsDir = resolve14(configHome, "minds");
|
|
7473
7736
|
mkdirSync7(configHome, { recursive: true });
|
|
7474
7737
|
mkdirSync7(mindsDir, { recursive: true });
|
|
7475
7738
|
const existingConfig = readGlobalConfig();
|
|
@@ -7503,11 +7766,11 @@ setup.get("/status", async (c) => {
|
|
|
7503
7766
|
let hasAccount = false;
|
|
7504
7767
|
if (hasSystem) {
|
|
7505
7768
|
try {
|
|
7506
|
-
const { listUsersByType: listUsersByType2 } = await import("./auth-
|
|
7769
|
+
const { listUsersByType: listUsersByType2 } = await import("./auth-KRDSM55Q.js");
|
|
7507
7770
|
const brains = await listUsersByType2("human");
|
|
7508
7771
|
hasAccount = brains.length > 0;
|
|
7509
7772
|
} catch (err) {
|
|
7510
|
-
logger_default.
|
|
7773
|
+
logger_default.error("could not check for existing accounts during setup status", logger_default.errorData(err));
|
|
7511
7774
|
}
|
|
7512
7775
|
}
|
|
7513
7776
|
return c.json({
|
|
@@ -7715,7 +7978,7 @@ setup.post("/account", async (c) => {
|
|
|
7715
7978
|
}
|
|
7716
7979
|
}
|
|
7717
7980
|
try {
|
|
7718
|
-
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-
|
|
7981
|
+
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-KRDSM55Q.js");
|
|
7719
7982
|
const user = await createUser2(body.username.trim(), body.password);
|
|
7720
7983
|
if (body.displayName?.trim()) {
|
|
7721
7984
|
await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
|
|
@@ -7761,7 +8024,7 @@ setup.post("/models", async (c) => {
|
|
|
7761
8024
|
return c.json({ error: "Spirit model is required" }, 400);
|
|
7762
8025
|
}
|
|
7763
8026
|
try {
|
|
7764
|
-
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-
|
|
8027
|
+
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-YW5SWCSB.js");
|
|
7765
8028
|
setEnabledModels3(body.models);
|
|
7766
8029
|
const config2 = readGlobalConfig();
|
|
7767
8030
|
config2.spiritModel = body.spiritModel.trim();
|
|
@@ -7808,15 +8071,15 @@ setup.post("/complete", async (c) => {
|
|
|
7808
8071
|
return c.json({ error: "Setup already complete" }, 400);
|
|
7809
8072
|
}
|
|
7810
8073
|
try {
|
|
7811
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
7812
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
8074
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-4ECYIVGE.js");
|
|
8075
|
+
const { startSpiritFull } = await import("./mind-service-E26ZQXDS.js");
|
|
7813
8076
|
await ensureSpiritProject();
|
|
7814
8077
|
await syncSpiritTemplate();
|
|
7815
8078
|
const warnings = [];
|
|
7816
8079
|
const config2 = readGlobalConfig();
|
|
7817
8080
|
if (config2.setup?.service && config2.setup?.type === "local") {
|
|
7818
8081
|
try {
|
|
7819
|
-
const { installUserService } = await import("./service-install-
|
|
8082
|
+
const { installUserService } = await import("./service-install-2EWD7KXD.js");
|
|
7820
8083
|
const installed = await installUserService(config2.port, config2.hostname);
|
|
7821
8084
|
if (!installed) {
|
|
7822
8085
|
warnings.push("Service installation is not supported on this platform.");
|
|
@@ -7846,8 +8109,8 @@ setup.post("/complete", async (c) => {
|
|
|
7846
8109
|
}
|
|
7847
8110
|
let spiritConversationId;
|
|
7848
8111
|
try {
|
|
7849
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-
|
|
7850
|
-
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-
|
|
8112
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-KRDSM55Q.js");
|
|
8113
|
+
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-ZL6PHROD.js");
|
|
7851
8114
|
const spiritUser = await getOrCreateMindUser2(spiritName);
|
|
7852
8115
|
const brains = await listUsersByType2("human");
|
|
7853
8116
|
const admin2 = brains.find((u) => u.role === "admin");
|
|
@@ -7869,8 +8132,8 @@ setup.post("/complete", async (c) => {
|
|
|
7869
8132
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
7870
8133
|
if (spiritConversationId && spiritStarted) {
|
|
7871
8134
|
try {
|
|
7872
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
7873
|
-
const { listUsersByType: listUsers2 } = await import("./auth-
|
|
8135
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-7URC52ME.js");
|
|
8136
|
+
const { listUsersByType: listUsers2 } = await import("./auth-KRDSM55Q.js");
|
|
7874
8137
|
const admins = await listUsers2("human");
|
|
7875
8138
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
7876
8139
|
if (admin2) {
|
|
@@ -7911,9 +8174,9 @@ setup.post("/complete", async (c) => {
|
|
|
7911
8174
|
var setup_default = setup;
|
|
7912
8175
|
|
|
7913
8176
|
// packages/daemon/src/web/api/skills.ts
|
|
7914
|
-
import { existsSync as
|
|
8177
|
+
import { existsSync as existsSync9, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync4 } from "fs";
|
|
7915
8178
|
import { tmpdir } from "os";
|
|
7916
|
-
import { join, resolve as
|
|
8179
|
+
import { join, resolve as resolve15 } from "path";
|
|
7917
8180
|
import AdmZip from "adm-zip";
|
|
7918
8181
|
import { Hono as Hono20 } from "hono";
|
|
7919
8182
|
var app16 = new Hono20().get("/", async (c) => {
|
|
@@ -7989,19 +8252,19 @@ var app16 = new Hono20().get("/", async (c) => {
|
|
|
7989
8252
|
try {
|
|
7990
8253
|
const zip = new AdmZip(buffer);
|
|
7991
8254
|
for (const entry of zip.getEntries()) {
|
|
7992
|
-
const target =
|
|
8255
|
+
const target = resolve15(tmpDir, entry.entryName);
|
|
7993
8256
|
if (!target.startsWith(tmpDir)) {
|
|
7994
8257
|
return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
|
|
7995
8258
|
}
|
|
7996
8259
|
}
|
|
7997
8260
|
zip.extractAllTo(tmpDir, true);
|
|
7998
8261
|
let skillDir = null;
|
|
7999
|
-
if (
|
|
8262
|
+
if (existsSync9(join(tmpDir, "SKILL.md"))) {
|
|
8000
8263
|
skillDir = tmpDir;
|
|
8001
8264
|
} else {
|
|
8002
8265
|
const entries = readdirSync3(tmpDir, { withFileTypes: true }).filter((e) => e.isDirectory());
|
|
8003
8266
|
for (const entry of entries) {
|
|
8004
|
-
if (
|
|
8267
|
+
if (existsSync9(join(tmpDir, entry.name, "SKILL.md"))) {
|
|
8005
8268
|
skillDir = join(tmpDir, entry.name);
|
|
8006
8269
|
break;
|
|
8007
8270
|
}
|
|
@@ -8363,8 +8626,8 @@ var app20 = new Hono24().use("*", authMiddleware).get("/", async (c) => {
|
|
|
8363
8626
|
});
|
|
8364
8627
|
}, 15e3);
|
|
8365
8628
|
cleanups.push(() => clearInterval(keepAlive));
|
|
8366
|
-
await new Promise((
|
|
8367
|
-
stream.onAbort(() =>
|
|
8629
|
+
await new Promise((resolve21) => {
|
|
8630
|
+
stream.onAbort(() => resolve21());
|
|
8368
8631
|
});
|
|
8369
8632
|
} finally {
|
|
8370
8633
|
for (const cleanup of cleanups) {
|
|
@@ -8382,7 +8645,7 @@ var events_default = app20;
|
|
|
8382
8645
|
import { Hono as Hono25 } from "hono";
|
|
8383
8646
|
|
|
8384
8647
|
// packages/daemon/src/lib/events/feed.ts
|
|
8385
|
-
import { and as and6, desc as desc5, eq as eq8, gte as gte3, inArray as inArray3, sql as sql5 } from "drizzle-orm";
|
|
8648
|
+
import { and as and6, desc as desc5, eq as eq8, gte as gte3, inArray as inArray3, ne, sql as sql5 } from "drizzle-orm";
|
|
8386
8649
|
var BURST_GAP_MS = 45 * 6e4;
|
|
8387
8650
|
var FEED_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
8388
8651
|
var LIFECYCLE_TYPES = [
|
|
@@ -8459,7 +8722,13 @@ async function getChatFeedEvents(opts) {
|
|
|
8459
8722
|
content: messages.content,
|
|
8460
8723
|
created_at: messages.created_at,
|
|
8461
8724
|
conversation_type: conversations.type
|
|
8462
|
-
}).from(messages).innerJoin(conversations, eq8(conversations.id, messages.conversation_id)).where(
|
|
8725
|
+
}).from(messages).innerJoin(conversations, eq8(conversations.id, messages.conversation_id)).where(
|
|
8726
|
+
and6(
|
|
8727
|
+
gte3(messages.created_at, cutoff),
|
|
8728
|
+
eq8(conversations.private, 0),
|
|
8729
|
+
ne(messages.role, "event")
|
|
8730
|
+
)
|
|
8731
|
+
).orderBy(desc5(messages.id)).limit(5e3);
|
|
8463
8732
|
const ascending = rows.reverse();
|
|
8464
8733
|
const bursts = splitIntoBursts(ascending);
|
|
8465
8734
|
bursts.sort((a, b) => {
|
|
@@ -8639,23 +8908,23 @@ var app21 = new Hono25().use("*", authMiddleware).get("/", async (c) => {
|
|
|
8639
8908
|
var feed_default = app21;
|
|
8640
8909
|
|
|
8641
8910
|
// packages/daemon/src/web/api/variants.ts
|
|
8642
|
-
import { existsSync as
|
|
8643
|
-
import { resolve as
|
|
8911
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
8912
|
+
import { resolve as resolve18 } from "path";
|
|
8644
8913
|
import { Hono as Hono26 } from "hono";
|
|
8645
8914
|
|
|
8646
8915
|
// packages/daemon/src/lib/mind/farewell.ts
|
|
8647
|
-
import { existsSync as
|
|
8648
|
-
import { resolve as
|
|
8916
|
+
import { existsSync as existsSync10, readFileSync as readFileSync10, rmSync as rmSync5 } from "fs";
|
|
8917
|
+
import { resolve as resolve16 } from "path";
|
|
8649
8918
|
var flog = logger_default.child("farewell");
|
|
8650
8919
|
var FAREWELL_RELPATH = ".mind/farewell.md";
|
|
8651
8920
|
var FAREWELL_MIND_PATH = "../.mind/farewell.md";
|
|
8652
8921
|
var FAREWELL_TIMEOUT_MS = 12e4;
|
|
8653
8922
|
function farewellPath(variantDir) {
|
|
8654
|
-
return
|
|
8923
|
+
return resolve16(variantDir, FAREWELL_RELPATH);
|
|
8655
8924
|
}
|
|
8656
8925
|
function readFarewell(variantDir) {
|
|
8657
8926
|
const path = farewellPath(variantDir);
|
|
8658
|
-
if (!
|
|
8927
|
+
if (!existsSync10(path)) return void 0;
|
|
8659
8928
|
try {
|
|
8660
8929
|
const text = readFileSync10(path, "utf-8").trim();
|
|
8661
8930
|
return text || void 0;
|
|
@@ -8678,7 +8947,7 @@ function waitForFarewell(name, variantDir, timeoutMs) {
|
|
|
8678
8947
|
const unsub = subscribe((event) => {
|
|
8679
8948
|
if (event.mind !== name) return;
|
|
8680
8949
|
if (event.type !== "mind_done" && event.type !== "mind_idle") return;
|
|
8681
|
-
if (
|
|
8950
|
+
if (existsSync10(farewellPath(variantDir))) cleanup();
|
|
8682
8951
|
});
|
|
8683
8952
|
return { done, cancel: cleanup };
|
|
8684
8953
|
}
|
|
@@ -8711,8 +8980,8 @@ async function runFarewellTurn(opts) {
|
|
|
8711
8980
|
|
|
8712
8981
|
// packages/daemon/src/lib/mind/spawn-server.ts
|
|
8713
8982
|
import { spawn as spawn4 } from "child_process";
|
|
8714
|
-
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync11, statSync as
|
|
8715
|
-
import { resolve as
|
|
8983
|
+
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
|
|
8984
|
+
import { resolve as resolve17 } from "path";
|
|
8716
8985
|
async function spawnServer(cwd, port, options) {
|
|
8717
8986
|
let cmd = process.env.VOLUTE_NODE_PATH ?? process.execPath;
|
|
8718
8987
|
let args = ["--import", "tsx", "src/server.ts", "--port", String(port)];
|
|
@@ -8733,34 +9002,34 @@ function spawnAttached(cmd, args, cwd) {
|
|
|
8733
9002
|
cwd,
|
|
8734
9003
|
stdio: ["ignore", "pipe", "pipe"]
|
|
8735
9004
|
});
|
|
8736
|
-
return new Promise((
|
|
8737
|
-
const timeout = setTimeout(() =>
|
|
9005
|
+
return new Promise((resolve21) => {
|
|
9006
|
+
const timeout = setTimeout(() => resolve21(null), 3e4);
|
|
8738
9007
|
function checkOutput(data) {
|
|
8739
9008
|
const match = data.toString().match(/listening on :(\d+)/);
|
|
8740
9009
|
if (match) {
|
|
8741
9010
|
clearTimeout(timeout);
|
|
8742
|
-
|
|
9011
|
+
resolve21({ child, actualPort: parseInt(match[1], 10) });
|
|
8743
9012
|
}
|
|
8744
9013
|
}
|
|
8745
9014
|
child.stdout?.on("data", checkOutput);
|
|
8746
9015
|
child.stderr?.on("data", checkOutput);
|
|
8747
9016
|
child.on("error", () => {
|
|
8748
9017
|
clearTimeout(timeout);
|
|
8749
|
-
|
|
9018
|
+
resolve21(null);
|
|
8750
9019
|
});
|
|
8751
9020
|
child.on("exit", () => {
|
|
8752
9021
|
clearTimeout(timeout);
|
|
8753
|
-
|
|
9022
|
+
resolve21(null);
|
|
8754
9023
|
});
|
|
8755
9024
|
});
|
|
8756
9025
|
}
|
|
8757
9026
|
function spawnDetached(cmd, args, cwd, logDir) {
|
|
8758
|
-
const logsDir = logDir ??
|
|
9027
|
+
const logsDir = logDir ?? resolve17(cwd, ".mind", "logs");
|
|
8759
9028
|
mkdirSync8(logsDir, { recursive: true });
|
|
8760
|
-
const logPath =
|
|
9029
|
+
const logPath = resolve17(logsDir, "mind.log");
|
|
8761
9030
|
let startOffset = 0;
|
|
8762
9031
|
try {
|
|
8763
|
-
startOffset =
|
|
9032
|
+
startOffset = statSync4(logPath).size;
|
|
8764
9033
|
} catch {
|
|
8765
9034
|
}
|
|
8766
9035
|
const logFd = openSync(logPath, "a");
|
|
@@ -8898,11 +9167,11 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
8898
9167
|
return c.json({ error: `Name already in use: ${variantName}` }, 409);
|
|
8899
9168
|
}
|
|
8900
9169
|
const projectRoot = entry.dir ?? mindDir(mindName);
|
|
8901
|
-
const variantDir =
|
|
8902
|
-
if (
|
|
9170
|
+
const variantDir = resolve18(projectRoot, ".variants", variantName);
|
|
9171
|
+
if (existsSync11(variantDir)) {
|
|
8903
9172
|
return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
|
|
8904
9173
|
}
|
|
8905
|
-
mkdirSync9(
|
|
9174
|
+
mkdirSync9(resolve18(projectRoot, ".variants"), { recursive: true });
|
|
8906
9175
|
try {
|
|
8907
9176
|
await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
|
|
8908
9177
|
} catch (e) {
|
|
@@ -8921,18 +9190,10 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
8921
9190
|
}
|
|
8922
9191
|
const rollbackSplit = async () => {
|
|
8923
9192
|
try {
|
|
8924
|
-
await cleanupVariant(variantName, projectRoot, variantDir, { stop: true });
|
|
9193
|
+
await cleanupVariant(variantName, mindName, projectRoot, variantDir, { stop: true });
|
|
8925
9194
|
} catch (err2) {
|
|
8926
9195
|
logger_default.warn(`failed to roll back split of ${variantName}`, logger_default.errorData(err2));
|
|
8927
9196
|
}
|
|
8928
|
-
try {
|
|
8929
|
-
await chownMindDir(projectRoot, mindName);
|
|
8930
|
-
} catch (err2) {
|
|
8931
|
-
logger_default.warn(
|
|
8932
|
-
`failed to restore ${mindName} ownership after split rollback`,
|
|
8933
|
-
logger_default.errorData(err2)
|
|
8934
|
-
);
|
|
8935
|
-
}
|
|
8936
9197
|
};
|
|
8937
9198
|
try {
|
|
8938
9199
|
await chownMindDir(projectRoot, mindName);
|
|
@@ -8946,7 +9207,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
8946
9207
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
8947
9208
|
await exec(cmd, args, {
|
|
8948
9209
|
cwd: variantDir,
|
|
8949
|
-
env: { ...process.env, HOME:
|
|
9210
|
+
env: { ...process.env, HOME: resolve18(variantDir, "home") }
|
|
8950
9211
|
});
|
|
8951
9212
|
} else {
|
|
8952
9213
|
await exec("npm", ["install"], { cwd: variantDir });
|
|
@@ -8957,7 +9218,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
8957
9218
|
return c.json({ error: `npm install failed: ${msg}` }, 500);
|
|
8958
9219
|
}
|
|
8959
9220
|
if (body.soul) {
|
|
8960
|
-
writeFileSync9(
|
|
9221
|
+
writeFileSync9(resolve18(variantDir, "home/SOUL.md"), body.soul);
|
|
8961
9222
|
}
|
|
8962
9223
|
const variantPort = body.port ?? await nextPort();
|
|
8963
9224
|
try {
|
|
@@ -9010,7 +9271,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9010
9271
|
} catch {
|
|
9011
9272
|
}
|
|
9012
9273
|
const projectRoot = parentEntry.dir ?? mindDir(mindName);
|
|
9013
|
-
const failAfterGitWrite = async (message, extra) => {
|
|
9274
|
+
const failAfterGitWrite = async (message, extra, status = 500) => {
|
|
9014
9275
|
try {
|
|
9015
9276
|
await chownMindDir(projectRoot, mindName);
|
|
9016
9277
|
} catch (err) {
|
|
@@ -9026,7 +9287,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9026
9287
|
500
|
|
9027
9288
|
);
|
|
9028
9289
|
}
|
|
9029
|
-
return c.json({ error: message, ...extra },
|
|
9290
|
+
return c.json({ error: message, ...extra }, status);
|
|
9030
9291
|
};
|
|
9031
9292
|
let farewell;
|
|
9032
9293
|
try {
|
|
@@ -9040,7 +9301,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9040
9301
|
logger_default.warn(`farewell turn failed for ${variantName}`, logger_default.errorData(err));
|
|
9041
9302
|
}
|
|
9042
9303
|
try {
|
|
9043
|
-
if (
|
|
9304
|
+
if (existsSync11(variantEntry.dir)) {
|
|
9044
9305
|
const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
|
|
9045
9306
|
if (status) {
|
|
9046
9307
|
try {
|
|
@@ -9098,12 +9359,33 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9098
9359
|
{ conflicts: err.conflicts }
|
|
9099
9360
|
);
|
|
9100
9361
|
}
|
|
9101
|
-
|
|
9362
|
+
if (existsSync11(variantEntry.dir) && !body.discardUnresolved) {
|
|
9363
|
+
let unresolved;
|
|
9364
|
+
try {
|
|
9365
|
+
unresolved = await findUnresolvedHomeFiles(variantEntry.dir);
|
|
9366
|
+
} catch (err) {
|
|
9367
|
+
return failAfterGitWrite(
|
|
9368
|
+
`Could not verify variant ${variantName} has no unresolved home/ files: ${err instanceof Error ? err.message : String(err)}. Variant left intact \u2014 retry the join.`
|
|
9369
|
+
);
|
|
9370
|
+
}
|
|
9371
|
+
if (unresolved.totalCount > 0) {
|
|
9372
|
+
return failAfterGitWrite(
|
|
9373
|
+
formatUnresolvedHomeFilesMessage(variantName, unresolved),
|
|
9374
|
+
{
|
|
9375
|
+
unresolvedFiles: unresolved.files,
|
|
9376
|
+
unresolvedCount: unresolved.totalCount,
|
|
9377
|
+
unresolvedBytes: unresolved.totalBytes
|
|
9378
|
+
},
|
|
9379
|
+
409
|
|
9380
|
+
);
|
|
9381
|
+
}
|
|
9382
|
+
}
|
|
9383
|
+
await cleanupVariant(variantName, mindName, projectRoot, variantEntry.dir, { stop: true });
|
|
9102
9384
|
await chownMindDir(projectRoot, mindName);
|
|
9103
9385
|
if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
|
|
9104
9386
|
try {
|
|
9105
|
-
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-
|
|
9106
|
-
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-
|
|
9387
|
+
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-YKWMVYMM.js");
|
|
9388
|
+
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-TRC2HJXR.js");
|
|
9107
9389
|
const tmpl = parentEntry.template ?? "claude";
|
|
9108
9390
|
await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
|
|
9109
9391
|
} catch (err) {
|
|
@@ -9116,7 +9398,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9116
9398
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
9117
9399
|
await exec(cmd, args, {
|
|
9118
9400
|
cwd: projectRoot,
|
|
9119
|
-
env: { ...process.env, HOME:
|
|
9401
|
+
env: { ...process.env, HOME: resolve18(projectRoot, "home") }
|
|
9120
9402
|
});
|
|
9121
9403
|
} else {
|
|
9122
9404
|
await exec("npm", ["install"], { cwd: projectRoot });
|
|
@@ -9164,7 +9446,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9164
9446
|
}
|
|
9165
9447
|
if (!variantEntry.dir) return c.json({ error: `Variant ${variantName} has no directory` }, 500);
|
|
9166
9448
|
const projectRoot = parentEntry.dir ?? mindDir(mindName);
|
|
9167
|
-
await cleanupVariant(variantName, projectRoot, variantEntry.dir, { stop: true });
|
|
9449
|
+
await cleanupVariant(variantName, mindName, projectRoot, variantEntry.dir, { stop: true });
|
|
9168
9450
|
return c.json({ ok: true });
|
|
9169
9451
|
});
|
|
9170
9452
|
var variants_default = app22;
|
|
@@ -9603,11 +9885,11 @@ var app24 = new Hono28().get("/:name/conversations/:id/events", async (c) => {
|
|
|
9603
9885
|
if (!stream.aborted) console.error("[chat] SSE ping error:", err);
|
|
9604
9886
|
});
|
|
9605
9887
|
}, 15e3);
|
|
9606
|
-
await new Promise((
|
|
9888
|
+
await new Promise((resolve21) => {
|
|
9607
9889
|
stream.onAbort(() => {
|
|
9608
9890
|
unsubscribe();
|
|
9609
9891
|
clearInterval(keepAlive);
|
|
9610
|
-
|
|
9892
|
+
resolve21();
|
|
9611
9893
|
});
|
|
9612
9894
|
});
|
|
9613
9895
|
});
|
|
@@ -9824,10 +10106,10 @@ app26.route("/api/conversations", conversations_default);
|
|
|
9824
10106
|
var app_default = app26;
|
|
9825
10107
|
|
|
9826
10108
|
// packages/daemon/src/web/server.ts
|
|
9827
|
-
import { existsSync as
|
|
10109
|
+
import { existsSync as existsSync12 } from "fs";
|
|
9828
10110
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
9829
10111
|
import { createServer as createHttpsServer } from "https";
|
|
9830
|
-
import { dirname as dirname3, extname as extname3, resolve as
|
|
10112
|
+
import { dirname as dirname3, extname as extname3, resolve as resolve19 } from "path";
|
|
9831
10113
|
import { serve } from "@hono/node-server";
|
|
9832
10114
|
var MIME_TYPES2 = {
|
|
9833
10115
|
".html": "text/html",
|
|
@@ -9846,8 +10128,8 @@ async function startServer({
|
|
|
9846
10128
|
let assetsDir = "";
|
|
9847
10129
|
let searchDir = dirname3(new URL(import.meta.url).pathname);
|
|
9848
10130
|
for (let i = 0; i < 5; i++) {
|
|
9849
|
-
const candidate =
|
|
9850
|
-
if (
|
|
10131
|
+
const candidate = resolve19(searchDir, "dist", "web-assets");
|
|
10132
|
+
if (existsSync12(candidate)) {
|
|
9851
10133
|
assetsDir = candidate;
|
|
9852
10134
|
break;
|
|
9853
10135
|
}
|
|
@@ -9857,7 +10139,7 @@ async function startServer({
|
|
|
9857
10139
|
app_default.get("*", async (c) => {
|
|
9858
10140
|
const urlPath = new URL(c.req.url).pathname;
|
|
9859
10141
|
if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
|
|
9860
|
-
const filePath =
|
|
10142
|
+
const filePath = resolve19(assetsDir, urlPath.slice(1));
|
|
9861
10143
|
if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
|
|
9862
10144
|
const s = await stat2(filePath).catch(() => null);
|
|
9863
10145
|
if (s?.isFile()) {
|
|
@@ -9870,7 +10152,7 @@ async function startServer({
|
|
|
9870
10152
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
9871
10153
|
return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
|
|
9872
10154
|
}
|
|
9873
|
-
const indexPath =
|
|
10155
|
+
const indexPath = resolve19(assetsDir, "index.html");
|
|
9874
10156
|
const indexStat = await stat2(indexPath).catch(() => null);
|
|
9875
10157
|
if (indexStat?.isFile()) {
|
|
9876
10158
|
const body = await readFile2(indexPath, "utf-8");
|
|
@@ -9887,10 +10169,10 @@ async function startServer({
|
|
|
9887
10169
|
createServer: createHttpsServer,
|
|
9888
10170
|
serverOptions: { key: tls.key, cert: tls.cert }
|
|
9889
10171
|
});
|
|
9890
|
-
await new Promise((
|
|
10172
|
+
await new Promise((resolve21, reject) => {
|
|
9891
10173
|
server2.on("listening", () => {
|
|
9892
10174
|
logger_default.info("Volute UI running (https)", { hostname, port });
|
|
9893
|
-
|
|
10175
|
+
resolve21();
|
|
9894
10176
|
});
|
|
9895
10177
|
server2.on("error", (err) => {
|
|
9896
10178
|
reject(err);
|
|
@@ -9898,13 +10180,13 @@ async function startServer({
|
|
|
9898
10180
|
});
|
|
9899
10181
|
const internalPort = port + 1;
|
|
9900
10182
|
const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
|
|
9901
|
-
await new Promise((
|
|
10183
|
+
await new Promise((resolve21, reject) => {
|
|
9902
10184
|
internalServer.on("listening", () => {
|
|
9903
10185
|
logger_default.info("Volute API running (http, internal)", {
|
|
9904
10186
|
hostname: "127.0.0.1",
|
|
9905
10187
|
port: internalPort
|
|
9906
10188
|
});
|
|
9907
|
-
|
|
10189
|
+
resolve21();
|
|
9908
10190
|
});
|
|
9909
10191
|
internalServer.on("error", (err) => {
|
|
9910
10192
|
reject(err);
|
|
@@ -9913,10 +10195,10 @@ async function startServer({
|
|
|
9913
10195
|
return { server: server2, internalPort };
|
|
9914
10196
|
}
|
|
9915
10197
|
const server = serve({ fetch: app_default.fetch, port, hostname });
|
|
9916
|
-
await new Promise((
|
|
10198
|
+
await new Promise((resolve21, reject) => {
|
|
9917
10199
|
server.on("listening", () => {
|
|
9918
10200
|
logger_default.info("Volute API running (http)", { hostname, port });
|
|
9919
|
-
|
|
10201
|
+
resolve21();
|
|
9920
10202
|
});
|
|
9921
10203
|
server.on("error", (err) => {
|
|
9922
10204
|
reject(err);
|
|
@@ -9927,17 +10209,17 @@ async function startServer({
|
|
|
9927
10209
|
|
|
9928
10210
|
// packages/daemon/src/daemon.ts
|
|
9929
10211
|
if (!process.env.VOLUTE_HOME) {
|
|
9930
|
-
process.env.VOLUTE_HOME =
|
|
10212
|
+
process.env.VOLUTE_HOME = resolve20(homedir3(), ".volute");
|
|
9931
10213
|
}
|
|
9932
10214
|
if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
|
|
9933
10215
|
process.env.TZ = process.env.VOLUTE_TIMEZONE;
|
|
9934
10216
|
}
|
|
9935
10217
|
function writeDaemonConfig(systemDir, config2, token) {
|
|
9936
|
-
const configPath =
|
|
10218
|
+
const configPath = resolve20(systemDir, "daemon.json");
|
|
9937
10219
|
writeFileSync10(configPath, `${JSON.stringify(config2, null, 2)}
|
|
9938
10220
|
`, { mode: 420 });
|
|
9939
10221
|
chmodSync(configPath, 420);
|
|
9940
|
-
const tokenPath =
|
|
10222
|
+
const tokenPath = resolve20(systemDir, "daemon-token");
|
|
9941
10223
|
writeFileSync10(tokenPath, `${token}
|
|
9942
10224
|
`, { mode: 384 });
|
|
9943
10225
|
chmodSync(tokenPath, 384);
|
|
@@ -9948,7 +10230,7 @@ async function startDaemon(opts) {
|
|
|
9948
10230
|
const home = voluteHome();
|
|
9949
10231
|
const systemDir = voluteSystemDir();
|
|
9950
10232
|
if (!opts.foreground) {
|
|
9951
|
-
const rotatingLog = new RotatingLog(
|
|
10233
|
+
const rotatingLog = new RotatingLog(resolve20(systemDir, "daemon.log"));
|
|
9952
10234
|
logger_default.setOutput((line) => rotatingLog.write(`${line}
|
|
9953
10235
|
`));
|
|
9954
10236
|
const write = (...args) => rotatingLog.write(`${format(...args)}
|
|
@@ -9958,38 +10240,38 @@ async function startDaemon(opts) {
|
|
|
9958
10240
|
console.warn = write;
|
|
9959
10241
|
console.info = write;
|
|
9960
10242
|
}
|
|
9961
|
-
const DAEMON_PID_PATH =
|
|
9962
|
-
const DAEMON_JSON_PATH =
|
|
9963
|
-
const DAEMON_TOKEN_PATH =
|
|
10243
|
+
const DAEMON_PID_PATH = resolve20(systemDir, "daemon.pid");
|
|
10244
|
+
const DAEMON_JSON_PATH = resolve20(systemDir, "daemon.json");
|
|
10245
|
+
const DAEMON_TOKEN_PATH = resolve20(systemDir, "daemon-token");
|
|
9964
10246
|
mkdirSync10(home, { recursive: true });
|
|
9965
10247
|
ensureSystemDir();
|
|
9966
|
-
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-
|
|
10248
|
+
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-WZSXHHRJ.js");
|
|
9967
10249
|
migrateConfigSecrets();
|
|
9968
10250
|
migrateSetupCompleted();
|
|
9969
|
-
const { migrateAiModelQualification } = await import("./ai-service-
|
|
10251
|
+
const { migrateAiModelQualification } = await import("./ai-service-YW5SWCSB.js");
|
|
9970
10252
|
migrateAiModelQualification();
|
|
9971
|
-
await (await import("./db-
|
|
10253
|
+
await (await import("./db-BONH4SUG.js")).getDb();
|
|
9972
10254
|
try {
|
|
9973
10255
|
const { eq: eq9, and: and7 } = await import("drizzle-orm");
|
|
9974
|
-
const { users: users2 } = await import("./schema-
|
|
9975
|
-
const db = await (await import("./db-
|
|
10256
|
+
const { users: users2 } = await import("./schema-ZZQVM4GR.js");
|
|
10257
|
+
const db = await (await import("./db-BONH4SUG.js")).getDb();
|
|
9976
10258
|
await db.update(users2).set({ role: "system" }).where(and7(eq9(users2.user_type, "system"), eq9(users2.role, "user")));
|
|
9977
10259
|
} catch (err) {
|
|
9978
10260
|
logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
|
|
9979
10261
|
}
|
|
9980
10262
|
try {
|
|
9981
|
-
const { migrateAvatarSizes } = await import("./avatar-image-
|
|
10263
|
+
const { migrateAvatarSizes } = await import("./avatar-image-52WGXLHV.js");
|
|
9982
10264
|
await migrateAvatarSizes();
|
|
9983
10265
|
} catch (err) {
|
|
9984
10266
|
logger_default.warn("avatar size migration failed", logger_default.errorData(err));
|
|
9985
10267
|
}
|
|
9986
10268
|
try {
|
|
9987
|
-
const { migrateThreadConfigs } = await import("./migrate-thread-config-
|
|
10269
|
+
const { migrateThreadConfigs } = await import("./migrate-thread-config-EQSEP2XG.js");
|
|
9988
10270
|
await migrateThreadConfigs();
|
|
9989
10271
|
} catch (err) {
|
|
9990
10272
|
logger_default.warn("session\u2192thread config migration failed", logger_default.errorData(err));
|
|
9991
10273
|
}
|
|
9992
|
-
const { initSandbox } = await import("./sandbox-
|
|
10274
|
+
const { initSandbox } = await import("./sandbox-NNWCTHRI.js");
|
|
9993
10275
|
await initSandbox();
|
|
9994
10276
|
try {
|
|
9995
10277
|
await syncBuiltinSkills();
|
|
@@ -10021,7 +10303,7 @@ async function startDaemon(opts) {
|
|
|
10021
10303
|
logger_default.warn("failed to backfill minds into #system", logger_default.errorData(err));
|
|
10022
10304
|
}
|
|
10023
10305
|
try {
|
|
10024
|
-
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-
|
|
10306
|
+
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-KRDSM55Q.js");
|
|
10025
10307
|
await getOrCreateSystemUser2();
|
|
10026
10308
|
} catch (err) {
|
|
10027
10309
|
logger_default.warn(
|
|
@@ -10030,12 +10312,12 @@ async function startDaemon(opts) {
|
|
|
10030
10312
|
);
|
|
10031
10313
|
}
|
|
10032
10314
|
const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes3(32).toString("hex");
|
|
10033
|
-
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-
|
|
10315
|
+
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-WZSXHHRJ.js");
|
|
10034
10316
|
const globalCfg = readGlobalConfig2();
|
|
10035
10317
|
let tls;
|
|
10036
10318
|
if (opts.tailscale || globalCfg.tailscale) {
|
|
10037
10319
|
try {
|
|
10038
|
-
const { getTailscaleTls } = await import("./tailscale-
|
|
10320
|
+
const { getTailscaleTls } = await import("./tailscale-KHNZFC7L.js");
|
|
10039
10321
|
const tlsConfig = await getTailscaleTls();
|
|
10040
10322
|
tls = { key: tlsConfig.key, cert: tlsConfig.cert };
|
|
10041
10323
|
logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
|
|
@@ -10089,7 +10371,7 @@ async function startDaemon(opts) {
|
|
|
10089
10371
|
const orphanedTurns = await completeOrphanedTurns();
|
|
10090
10372
|
summarizeOrphanedTurns(orphanedTurns);
|
|
10091
10373
|
try {
|
|
10092
|
-
const { reconcileVariants } = await import("./variant-cleanup-
|
|
10374
|
+
const { reconcileVariants } = await import("./variant-cleanup-STC6B5HR.js");
|
|
10093
10375
|
await reconcileVariants();
|
|
10094
10376
|
} catch (err) {
|
|
10095
10377
|
logger_default.error("failed to reconcile variants", logger_default.errorData(err));
|
|
@@ -10123,15 +10405,15 @@ async function startDaemon(opts) {
|
|
|
10123
10405
|
await Promise.all(workers);
|
|
10124
10406
|
}
|
|
10125
10407
|
try {
|
|
10126
|
-
const { isSetupComplete: isSetupComplete2, getSpiritName: getSpiritName2 } = await import("./setup-
|
|
10408
|
+
const { isSetupComplete: isSetupComplete2, getSpiritName: getSpiritName2 } = await import("./setup-WZSXHHRJ.js");
|
|
10127
10409
|
if (isSetupComplete2()) {
|
|
10128
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
10129
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
10410
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-4ECYIVGE.js");
|
|
10411
|
+
const { startSpiritFull } = await import("./mind-service-E26ZQXDS.js");
|
|
10130
10412
|
await ensureSpiritProject();
|
|
10131
10413
|
const spiritName = getSpiritName2();
|
|
10132
10414
|
const spiritEntry = await findMind(spiritName);
|
|
10133
10415
|
if (spiritEntry?.dir) {
|
|
10134
|
-
const { registerMindDir } = await import("./delivery-router-
|
|
10416
|
+
const { registerMindDir } = await import("./delivery-router-RHANNTAC.js");
|
|
10135
10417
|
registerMindDir(spiritName, spiritEntry.dir);
|
|
10136
10418
|
}
|
|
10137
10419
|
await syncSpiritTemplate();
|
|
@@ -10145,7 +10427,7 @@ async function startDaemon(opts) {
|
|
|
10145
10427
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
10146
10428
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
10147
10429
|
});
|
|
10148
|
-
import("./cloud-sync-
|
|
10430
|
+
import("./cloud-sync-H7EWZASD.js").then(
|
|
10149
10431
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
10150
10432
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
10151
10433
|
})
|
|
@@ -10153,7 +10435,7 @@ async function startDaemon(opts) {
|
|
|
10153
10435
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
10154
10436
|
});
|
|
10155
10437
|
try {
|
|
10156
|
-
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-
|
|
10438
|
+
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-LBVHH5YV.js");
|
|
10157
10439
|
backfillTemplateHashes().then(() => warnStaleTemplates()).catch((err) => {
|
|
10158
10440
|
logger_default.warn("failed to check template staleness", logger_default.errorData(err));
|
|
10159
10441
|
});
|