volute 0.50.0 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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-X6EMNEGB.js} +4 -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-JI67D7O2.js → chunk-7HN63Q7J.js} +120 -25
- package/dist/{chunk-PW65BXY5.js → chunk-7YJY3F2R.js} +11 -1
- package/dist/{chunk-HW6Q7AMB.js → chunk-AI47FDGL.js} +6 -7
- package/dist/{chunk-636GFQNE.js → chunk-BSHZ23MS.js} +8 -7
- package/dist/{chunk-7DXLIYPY.js → chunk-CDKQJWGK.js} +6 -6
- package/dist/{chunk-SSNZ6ZNN.js → chunk-CV6BNGFK.js} +3 -3
- package/dist/{chunk-QFVGPKJI.js → chunk-DMK5ASKV.js} +1 -1
- package/dist/{chunk-MLZBBLMT.js → chunk-DN3LKLYR.js} +4 -4
- 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-UC6BNMGT.js → chunk-HKP6OAJP.js} +3 -3
- package/dist/{chunk-C3KLHJDB.js → chunk-HTRSSOHY.js} +1 -1
- package/dist/{chunk-77IZUVBB.js → chunk-I7U5EEZC.js} +2 -2
- package/dist/{chunk-7OZWKHA3.js → chunk-ICL6T4SN.js} +18 -4
- package/dist/{chunk-X67VT4QO.js → chunk-ICXY54ZC.js} +1 -1
- package/dist/{chunk-YQOYZ6G7.js → chunk-IWAVIJO2.js} +2 -2
- package/dist/{chunk-5PKFJHCR.js → chunk-JHKBALS2.js} +2 -2
- 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-7FDWPQCU.js → chunk-Q7XQLKZB.js} +6 -6
- package/dist/{chunk-TGJHGVBZ.js → chunk-QT4D5XCI.js} +4 -4
- 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-ALIVXDM4.js → chunk-VAEZCIJC.js} +95 -51
- package/dist/{chunk-EQKSRVDE.js → chunk-VP5PFNZO.js} +89 -41
- package/dist/{chunk-SFRYRW37.js → chunk-VSBMLB2W.js} +9 -9
- package/dist/{chunk-RRZ4RQQU.js → chunk-X67BDDZR.js} +5 -7
- package/dist/cli.js +19 -19
- package/dist/{clock-LH7UFNLJ.js → clock-ZT5YT6HA.js} +2 -2
- package/dist/{cloud-sync-IDJFVDEP.js → cloud-sync-GPXYPTIC.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-2EWBRTN5.js} +6 -6
- package/dist/daemon.js +478 -331
- package/dist/{db-QAY45Z56.js → db-BONH4SUG.js} +2 -2
- package/dist/delivery-manager-HGVZSEES.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-6ANI5HHN.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-NY6WST33.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/{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-JHMAJ2GU.js +43 -0
- package/dist/{migrate-thread-config-4A5LW36Z.js → migrate-thread-config-EQSEP2XG.js} +2 -2
- package/dist/{mind-NYRALSV2.js → mind-WF6QIXWV.js} +7 -7
- 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-DZCUUC7J.js +47 -0
- package/dist/{mind-sleep-TH6BRQ5X.js → mind-sleep-LZAFBDZD.js} +2 -2
- package/dist/{package-XYSV7NUT.js → package-B6O5APCZ.js} +1 -1
- 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-TNBN54ZK.js +25 -0
- package/dist/{schema-C2GIPD4V.js → schema-ZZQVM4GR.js} +3 -1
- package/dist/{seed-3IMBOAGK.js → seed-K2LYODIH.js} +1 -1
- package/dist/{seed-cmd-U73XVQMI.js → seed-cmd-2EWBTR6P.js} +2 -2
- package/dist/{seed-create-FBLNVSUP.js → seed-create-VGTLU5FD.js} +3 -3
- package/dist/{seed-readiness-QRA46ZJQ.js → seed-readiness-DYOVCYHN.js} +4 -4
- package/dist/{seed-sprout-3B4SZX7J.js → seed-sprout-PILHJ3YS.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-MDPSK2XG.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-5MSMT7PT.js → skills-NH2GQKAF.js} +4 -4
- package/dist/sleep-manager-7JXEQQ2P.js +41 -0
- package/dist/{spirit-IL5EMWYZ.js → spirit-25JVAL3M.js} +7 -7
- package/dist/spirit-availability-PJDWZJ3J.js +42 -0
- package/dist/{sprout-UPXGJ5HX.js → sprout-EXUZMIOR.js} +1 -1
- package/dist/{status-IL67CYM4.js → status-MWLE3RVC.js} +5 -5
- package/dist/{system-events-A6IGCEC3.js → system-events-ZPSH63QX.js} +3 -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-TAT2HGK6.js} +5 -5
- package/dist/{up-CLL4665A.js → up-J7XCAH7P.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-YXN25ZVW.js +22 -0
- package/dist/{version-notify-7BUHWZNT.js → version-notify-EN3KJ7HH.js} +8 -8
- package/dist/web-assets/assets/index-BOyJ4Gqs.css +1 -0
- package/dist/web-assets/assets/{index-ClsUcXiW.js → index-CrxBwnzp.js} +19 -19
- 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 +1 -1
- 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/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-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-DN3LKLYR.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-AI47FDGL.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-BSHZ23MS.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-VP5PFNZO.js";
|
|
109
|
+
import "./chunk-VSBMLB2W.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-Q7XQLKZB.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-7HN63Q7J.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-VAEZCIJC.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-CDKQJWGK.js";
|
|
162
165
|
import {
|
|
163
166
|
SEED_SKILLS,
|
|
164
167
|
STANDARD_SKILLS,
|
|
@@ -180,7 +183,7 @@ import {
|
|
|
180
183
|
syncBuiltinSkills,
|
|
181
184
|
uninstallSkill,
|
|
182
185
|
updateSkill
|
|
183
|
-
} from "./chunk-
|
|
186
|
+
} from "./chunk-QT4D5XCI.js";
|
|
184
187
|
import {
|
|
185
188
|
approveUser,
|
|
186
189
|
changePassword,
|
|
@@ -201,7 +204,7 @@ import {
|
|
|
201
204
|
updateUserProfile,
|
|
202
205
|
verifyUser,
|
|
203
206
|
withSenderDisplayNames
|
|
204
|
-
} from "./chunk-
|
|
207
|
+
} from "./chunk-HKP6OAJP.js";
|
|
205
208
|
import {
|
|
206
209
|
captureReflection,
|
|
207
210
|
clearDeliveredEvents,
|
|
@@ -214,7 +217,7 @@ import {
|
|
|
214
217
|
listEvents,
|
|
215
218
|
parseMeta,
|
|
216
219
|
recordNotice
|
|
217
|
-
} from "./chunk-
|
|
220
|
+
} from "./chunk-ICL6T4SN.js";
|
|
218
221
|
import {
|
|
219
222
|
publish as publish2,
|
|
220
223
|
subscribe as subscribe2,
|
|
@@ -227,11 +230,11 @@ import {
|
|
|
227
230
|
getPrompt,
|
|
228
231
|
getPromptIfCustom,
|
|
229
232
|
substitute
|
|
230
|
-
} from "./chunk-
|
|
233
|
+
} from "./chunk-FXWBFDQR.js";
|
|
231
234
|
import {
|
|
232
235
|
isSandboxEnabled,
|
|
233
236
|
wrapForSandbox
|
|
234
|
-
} from "./chunk-
|
|
237
|
+
} from "./chunk-5Y54AE3L.js";
|
|
235
238
|
import {
|
|
236
239
|
addMessage,
|
|
237
240
|
createChannel,
|
|
@@ -267,22 +270,22 @@ import {
|
|
|
267
270
|
subscribe as subscribe3,
|
|
268
271
|
subscribeParticipantAdded,
|
|
269
272
|
updateChannelSettings
|
|
270
|
-
} from "./chunk-
|
|
273
|
+
} from "./chunk-TPX6E6PL.js";
|
|
271
274
|
import {
|
|
272
275
|
getActiveMinds,
|
|
273
276
|
onMindEvent,
|
|
274
277
|
stopAll
|
|
275
|
-
} from "./chunk-
|
|
278
|
+
} from "./chunk-UFTDRTCP.js";
|
|
276
279
|
import {
|
|
277
280
|
broadcast,
|
|
278
281
|
getEventsSince,
|
|
279
282
|
nextEventId,
|
|
280
283
|
publish,
|
|
281
284
|
subscribe
|
|
282
|
-
} from "./chunk-
|
|
285
|
+
} from "./chunk-U54PJPTB.js";
|
|
283
286
|
import {
|
|
284
287
|
normalizeAvatar
|
|
285
|
-
} from "./chunk-
|
|
288
|
+
} from "./chunk-ICXY54ZC.js";
|
|
286
289
|
import {
|
|
287
290
|
safeResolveWithinBase
|
|
288
291
|
} from "./chunk-DW4TRDOZ.js";
|
|
@@ -290,7 +293,7 @@ import {
|
|
|
290
293
|
readVoluteConfig,
|
|
291
294
|
writeVoluteConfig
|
|
292
295
|
} from "./chunk-WCFSBH33.js";
|
|
293
|
-
import "./chunk-
|
|
296
|
+
import "./chunk-6NLW72HP.js";
|
|
294
297
|
import {
|
|
295
298
|
chownMindDir,
|
|
296
299
|
chownMindFile,
|
|
@@ -302,15 +305,16 @@ import {
|
|
|
302
305
|
isIsolationEnabled,
|
|
303
306
|
resolveVoluteBin,
|
|
304
307
|
wrapForIsolation
|
|
305
|
-
} from "./chunk-
|
|
308
|
+
} from "./chunk-M77B73VV.js";
|
|
306
309
|
import {
|
|
307
310
|
loadMergedEnv,
|
|
308
311
|
mindEnvPath,
|
|
309
312
|
readEnv,
|
|
310
313
|
sharedEnvPath,
|
|
311
314
|
writeEnv
|
|
312
|
-
} from "./chunk-
|
|
315
|
+
} from "./chunk-GLM7TVWP.js";
|
|
313
316
|
import {
|
|
317
|
+
OAuthRefreshError,
|
|
314
318
|
addCustomModel,
|
|
315
319
|
aiCompleteUtility,
|
|
316
320
|
buildCustomModel,
|
|
@@ -334,7 +338,7 @@ import {
|
|
|
334
338
|
setProviderRefreshHook,
|
|
335
339
|
setUtilityModel,
|
|
336
340
|
unqualifyModelId
|
|
337
|
-
} from "./chunk-
|
|
341
|
+
} from "./chunk-EGV6R6UF.js";
|
|
338
342
|
import {
|
|
339
343
|
logBuffer,
|
|
340
344
|
logger_default
|
|
@@ -374,7 +378,7 @@ import {
|
|
|
374
378
|
voluteHome,
|
|
375
379
|
voluteSystemDir,
|
|
376
380
|
writeGlobalConfig
|
|
377
|
-
} from "./chunk-
|
|
381
|
+
} from "./chunk-H6X6CKDN.js";
|
|
378
382
|
import {
|
|
379
383
|
activity,
|
|
380
384
|
channels,
|
|
@@ -386,14 +390,14 @@ import {
|
|
|
386
390
|
systemPrompts,
|
|
387
391
|
turns,
|
|
388
392
|
users
|
|
389
|
-
} from "./chunk-
|
|
393
|
+
} from "./chunk-2RNMBXD2.js";
|
|
390
394
|
import "./chunk-K3NQKI34.js";
|
|
391
395
|
|
|
392
396
|
// packages/daemon/src/daemon.ts
|
|
393
397
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
394
398
|
import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync12, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
|
|
395
399
|
import { homedir as homedir3 } from "os";
|
|
396
|
-
import { resolve as
|
|
400
|
+
import { resolve as resolve19 } from "path";
|
|
397
401
|
import { format } from "util";
|
|
398
402
|
|
|
399
403
|
// packages/daemon/src/lib/daemon/backup-manager.ts
|
|
@@ -504,7 +508,7 @@ var BackupManager = class {
|
|
|
504
508
|
} catch (pubErr) {
|
|
505
509
|
blog.error("failed to publish backup-failure activity", logger_default.errorData(pubErr));
|
|
506
510
|
}
|
|
507
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
511
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-ZPSH63QX.js");
|
|
508
512
|
await deliverEvent2(getSpiritName(), {
|
|
509
513
|
type: "notice",
|
|
510
514
|
meta: { subtype: "backup" },
|
|
@@ -728,8 +732,8 @@ var BridgeManager = class {
|
|
|
728
732
|
if (!tracked) return;
|
|
729
733
|
this.stopping.add(platform);
|
|
730
734
|
this.bridges.delete(platform);
|
|
731
|
-
await new Promise((
|
|
732
|
-
tracked.child.on("exit", () =>
|
|
735
|
+
await new Promise((resolve20) => {
|
|
736
|
+
tracked.child.on("exit", () => resolve20());
|
|
733
737
|
try {
|
|
734
738
|
if (tracked.child.pid) {
|
|
735
739
|
process.kill(-tracked.child.pid, "SIGTERM");
|
|
@@ -740,7 +744,7 @@ var BridgeManager = class {
|
|
|
740
744
|
if (err instanceof Error && err.code !== "ESRCH") {
|
|
741
745
|
blog2.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
|
|
742
746
|
}
|
|
743
|
-
|
|
747
|
+
resolve20();
|
|
744
748
|
}
|
|
745
749
|
setTimeout(() => {
|
|
746
750
|
try {
|
|
@@ -751,7 +755,7 @@ var BridgeManager = class {
|
|
|
751
755
|
}
|
|
752
756
|
} catch {
|
|
753
757
|
}
|
|
754
|
-
|
|
758
|
+
resolve20();
|
|
755
759
|
}, 5e3);
|
|
756
760
|
});
|
|
757
761
|
this.stopping.delete(platform);
|
|
@@ -1112,6 +1116,7 @@ async function xaiSearch(_query, _cred) {
|
|
|
1112
1116
|
}
|
|
1113
1117
|
|
|
1114
1118
|
// packages/daemon/src/lib/services/imagegen.ts
|
|
1119
|
+
var igLog = logger_default.child("imagegen");
|
|
1115
1120
|
var PROVIDERS = {
|
|
1116
1121
|
replicate: {
|
|
1117
1122
|
envVar: "REPLICATE_API_TOKEN",
|
|
@@ -1275,12 +1280,19 @@ async function resolveCredential(providerId) {
|
|
|
1275
1280
|
const config2 = readGlobalConfig();
|
|
1276
1281
|
const configKey = config2.imagegen?.providers?.[providerId]?.apiKey;
|
|
1277
1282
|
if (configKey) return { kind: "api_key", token: configKey };
|
|
1278
|
-
|
|
1279
|
-
|
|
1283
|
+
let oauthError;
|
|
1284
|
+
try {
|
|
1285
|
+
const oauth = await resolveOAuthCredentials(aiProviderId);
|
|
1286
|
+
if (oauth) return { kind: "oauth", token: oauth.access };
|
|
1287
|
+
} catch (err) {
|
|
1288
|
+
if (!(err instanceof OAuthRefreshError)) throw err;
|
|
1289
|
+
oauthError = err;
|
|
1290
|
+
}
|
|
1280
1291
|
const aiKey = config2.ai?.providers?.[aiProviderId]?.apiKey;
|
|
1281
1292
|
if (aiKey) return { kind: "api_key", token: aiKey };
|
|
1282
1293
|
const envKey = provider.envVar ? process.env[provider.envVar] : void 0;
|
|
1283
1294
|
if (envKey) return { kind: "api_key", token: envKey };
|
|
1295
|
+
if (oauthError) throw oauthError;
|
|
1284
1296
|
return void 0;
|
|
1285
1297
|
}
|
|
1286
1298
|
function getEnabledModels2() {
|
|
@@ -1315,12 +1327,27 @@ async function searchModels(query, provider) {
|
|
|
1315
1327
|
return providerDef.search(query || "text to image", cred);
|
|
1316
1328
|
}
|
|
1317
1329
|
const searches = [];
|
|
1330
|
+
let transientError;
|
|
1318
1331
|
for (const [id, def] of Object.entries(PROVIDERS)) {
|
|
1319
|
-
|
|
1332
|
+
let cred;
|
|
1333
|
+
try {
|
|
1334
|
+
cred = await resolveCredential(id);
|
|
1335
|
+
} catch (err) {
|
|
1336
|
+
if (!(err instanceof OAuthRefreshError)) throw err;
|
|
1337
|
+
igLog.warn(`skipping ${id} in model search: OAuth temporarily unavailable`);
|
|
1338
|
+
transientError = err;
|
|
1339
|
+
continue;
|
|
1340
|
+
}
|
|
1320
1341
|
if (!cred) continue;
|
|
1321
|
-
searches.push(
|
|
1342
|
+
searches.push(
|
|
1343
|
+
def.search(query || "text to image", cred).catch((err) => {
|
|
1344
|
+
igLog.warn(`model search failed for ${id}`, logger_default.errorData(err));
|
|
1345
|
+
return [];
|
|
1346
|
+
})
|
|
1347
|
+
);
|
|
1322
1348
|
}
|
|
1323
1349
|
if (searches.length === 0) {
|
|
1350
|
+
if (transientError) throw transientError;
|
|
1324
1351
|
throw new Error("No imagegen providers configured");
|
|
1325
1352
|
}
|
|
1326
1353
|
return (await Promise.all(searches)).flat();
|
|
@@ -1382,7 +1409,7 @@ async function generateImage(model, prompt, signal) {
|
|
|
1382
1409
|
|
|
1383
1410
|
// packages/daemon/src/web/api/system.ts
|
|
1384
1411
|
var DEFAULT_API_URL = "https://volute.systems";
|
|
1385
|
-
var
|
|
1412
|
+
var igLog2 = logger_default.child("imagegen");
|
|
1386
1413
|
var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
1387
1414
|
setTimeout(() => process.exit(1), 200);
|
|
1388
1415
|
return c.json({ ok: true });
|
|
@@ -1400,10 +1427,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1400
1427
|
stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
|
|
1401
1428
|
});
|
|
1402
1429
|
});
|
|
1403
|
-
await new Promise((
|
|
1430
|
+
await new Promise((resolve20) => {
|
|
1404
1431
|
stream.onAbort(() => {
|
|
1405
1432
|
unsubscribe();
|
|
1406
|
-
|
|
1433
|
+
resolve20();
|
|
1407
1434
|
});
|
|
1408
1435
|
});
|
|
1409
1436
|
});
|
|
@@ -1428,7 +1455,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1428
1455
|
config2.name = name.trim() || void 0;
|
|
1429
1456
|
writeGlobalConfig(config2);
|
|
1430
1457
|
if (config2.name !== previousName) {
|
|
1431
|
-
const { notifySpiritSystemChange } = await import("./spirit-
|
|
1458
|
+
const { notifySpiritSystemChange } = await import("./spirit-25JVAL3M.js");
|
|
1432
1459
|
await notifySpiritSystemChange();
|
|
1433
1460
|
}
|
|
1434
1461
|
return c.json({ name: config2.name ?? null });
|
|
@@ -1621,7 +1648,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1621
1648
|
const results = await searchModels(q || void 0, provider || void 0);
|
|
1622
1649
|
return c.json(results);
|
|
1623
1650
|
} catch (err) {
|
|
1624
|
-
|
|
1651
|
+
igLog2.error("model search failed", logger_default.errorData(err));
|
|
1625
1652
|
return c.json({ error: err instanceof Error ? err.message : "Search failed" }, 500);
|
|
1626
1653
|
}
|
|
1627
1654
|
}).post(
|
|
@@ -1638,7 +1665,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1638
1665
|
}
|
|
1639
1666
|
});
|
|
1640
1667
|
} catch (err) {
|
|
1641
|
-
|
|
1668
|
+
igLog2.error("image generation failed", logger_default.errorData(err));
|
|
1642
1669
|
return c.json({ error: err instanceof Error ? err.message : "Generation failed" }, 500);
|
|
1643
1670
|
}
|
|
1644
1671
|
}
|
|
@@ -1787,8 +1814,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1787
1814
|
createdAt: Date.now()
|
|
1788
1815
|
};
|
|
1789
1816
|
oauthFlows.set(flowId, flow);
|
|
1790
|
-
const promptPromise = needsManualCode ? new Promise((
|
|
1791
|
-
flow.resolveCode =
|
|
1817
|
+
const promptPromise = needsManualCode ? new Promise((resolve20) => {
|
|
1818
|
+
flow.resolveCode = resolve20;
|
|
1792
1819
|
}) : void 0;
|
|
1793
1820
|
oauthProvider.login({
|
|
1794
1821
|
onAuth: (info) => {
|
|
@@ -1827,7 +1854,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1827
1854
|
existing.error = err instanceof Error ? err.message : String(err);
|
|
1828
1855
|
}
|
|
1829
1856
|
});
|
|
1830
|
-
await new Promise((
|
|
1857
|
+
await new Promise((resolve20) => setTimeout(resolve20, 2e3));
|
|
1831
1858
|
const state = oauthFlows.get(flowId);
|
|
1832
1859
|
return c.json({
|
|
1833
1860
|
flowId,
|
|
@@ -2088,8 +2115,8 @@ var app2 = new Hono2().get("/events", async (c) => {
|
|
|
2088
2115
|
});
|
|
2089
2116
|
}, 15e3);
|
|
2090
2117
|
cleanups.push(() => clearInterval(keepAlive));
|
|
2091
|
-
await new Promise((
|
|
2092
|
-
stream.onAbort(() =>
|
|
2118
|
+
await new Promise((resolve20) => {
|
|
2119
|
+
stream.onAbort(() => resolve20());
|
|
2093
2120
|
});
|
|
2094
2121
|
} finally {
|
|
2095
2122
|
for (const cleanup of cleanups) {
|
|
@@ -2145,6 +2172,12 @@ var profileSchema = z2.object({
|
|
|
2145
2172
|
display_name: z2.string().max(100).nullable().optional(),
|
|
2146
2173
|
description: z2.string().max(500).nullable().optional()
|
|
2147
2174
|
});
|
|
2175
|
+
var registerMindSchema = z2.object({
|
|
2176
|
+
name: z2.string().min(1),
|
|
2177
|
+
displayName: z2.string().max(100).optional(),
|
|
2178
|
+
description: z2.string().max(500).optional(),
|
|
2179
|
+
tokenLabel: z2.string().max(100).optional()
|
|
2180
|
+
});
|
|
2148
2181
|
var AVATAR_MIME = {
|
|
2149
2182
|
".png": "image/png",
|
|
2150
2183
|
".jpg": "image/jpeg",
|
|
@@ -2156,7 +2189,39 @@ var MAX_AVATAR_SIZE = 2 * 1024 * 1024;
|
|
|
2156
2189
|
function avatarsDir() {
|
|
2157
2190
|
return resolve3(voluteHome(), "avatars");
|
|
2158
2191
|
}
|
|
2159
|
-
var authenticated = new Hono3().use(authMiddleware).post("/
|
|
2192
|
+
var authenticated = new Hono3().use(authMiddleware).post("/minds", requireAdmin, zValidator2("json", registerMindSchema), async (c) => {
|
|
2193
|
+
const { name, displayName, description, tokenLabel } = c.req.valid("json");
|
|
2194
|
+
const invalid = validateMindName(name);
|
|
2195
|
+
if (invalid) return c.json({ error: invalid }, 400);
|
|
2196
|
+
if (await getUserByUsername(name)) {
|
|
2197
|
+
return c.json({ error: `"${name}" is already taken` }, 409);
|
|
2198
|
+
}
|
|
2199
|
+
const db = await getDb();
|
|
2200
|
+
let user;
|
|
2201
|
+
try {
|
|
2202
|
+
[user] = await db.insert(users).values({
|
|
2203
|
+
username: name,
|
|
2204
|
+
password_hash: "!mind",
|
|
2205
|
+
role: "user",
|
|
2206
|
+
user_type: "mind",
|
|
2207
|
+
display_name: displayName ?? null,
|
|
2208
|
+
description: description ?? null
|
|
2209
|
+
}).returning({
|
|
2210
|
+
id: users.id,
|
|
2211
|
+
username: users.username,
|
|
2212
|
+
user_type: users.user_type,
|
|
2213
|
+
role: users.role,
|
|
2214
|
+
display_name: users.display_name
|
|
2215
|
+
});
|
|
2216
|
+
} catch (err) {
|
|
2217
|
+
if (await getUserByUsername(name)) {
|
|
2218
|
+
return c.json({ error: `"${name}" is already taken` }, 409);
|
|
2219
|
+
}
|
|
2220
|
+
throw err;
|
|
2221
|
+
}
|
|
2222
|
+
const { id: tokenId, token } = await issueApiToken(user.id, tokenLabel);
|
|
2223
|
+
return c.json({ name, user, token, tokenId }, 201);
|
|
2224
|
+
}).post("/change-password", zValidator2("json", changePasswordSchema), async (c) => {
|
|
2160
2225
|
const user = c.get("user");
|
|
2161
2226
|
const { currentPassword, newPassword } = c.req.valid("json");
|
|
2162
2227
|
const ok = await changePassword(user.id, currentPassword, newPassword);
|
|
@@ -2272,7 +2337,42 @@ var admin = new Hono3().use(authMiddleware).get("/users", async (c) => {
|
|
|
2272
2337
|
await setUserRole(id, role);
|
|
2273
2338
|
return c.json({ ok: true });
|
|
2274
2339
|
}
|
|
2275
|
-
).
|
|
2340
|
+
).post(
|
|
2341
|
+
"/users/:id/tokens",
|
|
2342
|
+
requireAdmin,
|
|
2343
|
+
zValidator2("json", z2.object({ label: z2.string().max(200).optional() })),
|
|
2344
|
+
async (c) => {
|
|
2345
|
+
const id = parseInt(c.req.param("id"), 10);
|
|
2346
|
+
if (Number.isNaN(id)) return c.json({ error: "Invalid user ID" }, 400);
|
|
2347
|
+
const target = await getUser(id);
|
|
2348
|
+
if (!target) return c.json({ error: "User not found" }, 404);
|
|
2349
|
+
const { label } = c.req.valid("json");
|
|
2350
|
+
const issued = await issueApiToken(id, label);
|
|
2351
|
+
return c.json(
|
|
2352
|
+
{
|
|
2353
|
+
id: issued.id,
|
|
2354
|
+
token: issued.token,
|
|
2355
|
+
label: issued.label,
|
|
2356
|
+
createdAt: issued.created_at
|
|
2357
|
+
},
|
|
2358
|
+
201
|
|
2359
|
+
);
|
|
2360
|
+
}
|
|
2361
|
+
).get("/users/:id/tokens", requireAdmin, async (c) => {
|
|
2362
|
+
const id = parseInt(c.req.param("id"), 10);
|
|
2363
|
+
if (Number.isNaN(id)) return c.json({ error: "Invalid user ID" }, 400);
|
|
2364
|
+
const target = await getUser(id);
|
|
2365
|
+
if (!target) return c.json({ error: "User not found" }, 404);
|
|
2366
|
+
const tokens = await listApiTokens(id);
|
|
2367
|
+
return c.json(tokens.map((t) => ({ id: t.id, label: t.label, createdAt: t.created_at })));
|
|
2368
|
+
}).delete("/users/:id/tokens/:tokenId", requireAdmin, async (c) => {
|
|
2369
|
+
const id = parseInt(c.req.param("id"), 10);
|
|
2370
|
+
const tokenId = parseInt(c.req.param("tokenId"), 10);
|
|
2371
|
+
if (Number.isNaN(id) || Number.isNaN(tokenId)) return c.json({ error: "Invalid ID" }, 400);
|
|
2372
|
+
const revoked = await revokeApiToken(id, tokenId);
|
|
2373
|
+
if (!revoked) return c.json({ error: "Token not found" }, 404);
|
|
2374
|
+
return c.json({ ok: true });
|
|
2375
|
+
}).put("/users/:id/profile", zValidator2("json", profileSchema), async (c) => {
|
|
2276
2376
|
const user = c.get("user");
|
|
2277
2377
|
if (user.role !== "admin") return c.json({ error: "Forbidden" }, 403);
|
|
2278
2378
|
const id = parseInt(c.req.param("id"), 10);
|
|
@@ -2557,15 +2657,18 @@ async function fanOutToMinds(opts) {
|
|
|
2557
2657
|
const isDM = opts.isDM ?? participants.length === 2;
|
|
2558
2658
|
const manager = getMindManager();
|
|
2559
2659
|
const sm = getSleepManagerIfReady();
|
|
2660
|
+
const registeredMinds = new Set((await readAllMinds()).map((m) => m.name));
|
|
2560
2661
|
const targetMinds = mindParticipants.map((ap) => {
|
|
2561
2662
|
const key = opts.targetName ? opts.targetName(ap.username) : ap.username;
|
|
2562
2663
|
if (manager.isRunning(key) || sm?.isSleeping(ap.username)) return ap.username;
|
|
2563
2664
|
if (ap.username !== opts.senderName) {
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2665
|
+
if (registeredMinds.has(ap.username)) {
|
|
2666
|
+
logger_default.warn(
|
|
2667
|
+
`fan-out: skipping ${ap.username} (not running) for conversation ${opts.conversationId}`
|
|
2668
|
+
);
|
|
2669
|
+
}
|
|
2567
2670
|
if (ap.userType === "system") {
|
|
2568
|
-
import("./spirit-availability-
|
|
2671
|
+
import("./spirit-availability-PJDWZJ3J.js").then(({ ensureSpiritAvailable: ensureSpiritAvailable2 }) => ensureSpiritAvailable2()).catch((err) => logger_default.warn("fan-out: on-demand spirit start failed", logger_default.errorData(err)));
|
|
2569
2672
|
}
|
|
2570
2673
|
}
|
|
2571
2674
|
return null;
|
|
@@ -2668,7 +2771,7 @@ var app4 = new Hono5().post("/:platform/inbound", zValidator4("json", inboundSch
|
|
|
2668
2771
|
}
|
|
2669
2772
|
const participants = await getParticipants(channel.id);
|
|
2670
2773
|
if (!participants.some((p) => p.userId === puppet.id)) {
|
|
2671
|
-
const { addParticipant } = await import("./conversations-
|
|
2774
|
+
const { addParticipant } = await import("./conversations-ZL6PHROD.js");
|
|
2672
2775
|
await addParticipant(channel.id, puppet.id);
|
|
2673
2776
|
}
|
|
2674
2777
|
const contentBlocks = body.content;
|
|
@@ -2952,7 +3055,7 @@ async function notifyMind(mindName, message) {
|
|
|
2952
3055
|
const entry = await findMind(mindName);
|
|
2953
3056
|
if (!entry) return;
|
|
2954
3057
|
try {
|
|
2955
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
3058
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-ZPSH63QX.js");
|
|
2956
3059
|
await deliverEvent2(mindName, { type: "file-share", body: message });
|
|
2957
3060
|
} catch (err) {
|
|
2958
3061
|
logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
|
|
@@ -3923,9 +4026,9 @@ var app11 = new Hono14().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
3923
4026
|
stream.onAbort(() => {
|
|
3924
4027
|
tail.kill();
|
|
3925
4028
|
});
|
|
3926
|
-
await new Promise((
|
|
3927
|
-
tail.on("exit",
|
|
3928
|
-
stream.onAbort(
|
|
4029
|
+
await new Promise((resolve20) => {
|
|
4030
|
+
tail.on("exit", resolve20);
|
|
4031
|
+
stream.onAbort(resolve20);
|
|
3929
4032
|
});
|
|
3930
4033
|
});
|
|
3931
4034
|
}).get("/:name/logs/tail", requireSelf(), async (c) => {
|
|
@@ -3943,8 +4046,8 @@ var app11 = new Hono14().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
3943
4046
|
tail.stdout.on("data", (data) => {
|
|
3944
4047
|
output += data.toString();
|
|
3945
4048
|
});
|
|
3946
|
-
await new Promise((
|
|
3947
|
-
tail.on("exit",
|
|
4049
|
+
await new Promise((resolve20) => {
|
|
4050
|
+
tail.on("exit", resolve20);
|
|
3948
4051
|
});
|
|
3949
4052
|
return c.text(output);
|
|
3950
4053
|
});
|
|
@@ -4037,14 +4140,14 @@ var mind_skills_default = app12;
|
|
|
4037
4140
|
// packages/daemon/src/web/api/minds.ts
|
|
4038
4141
|
import {
|
|
4039
4142
|
cpSync,
|
|
4040
|
-
existsSync as
|
|
4143
|
+
existsSync as existsSync8,
|
|
4041
4144
|
mkdirSync as mkdirSync6,
|
|
4042
4145
|
readdirSync as readdirSync2,
|
|
4043
4146
|
readFileSync as readFileSync9,
|
|
4044
4147
|
rmSync as rmSync3,
|
|
4045
4148
|
writeFileSync as writeFileSync8
|
|
4046
4149
|
} from "fs";
|
|
4047
|
-
import { relative, resolve as
|
|
4150
|
+
import { relative, resolve as resolve12 } from "path";
|
|
4048
4151
|
import { zValidator as zValidator6 } from "@hono/zod-validator";
|
|
4049
4152
|
import { and as and5, desc as desc3, eq as eq5, sql as sql3 } from "drizzle-orm";
|
|
4050
4153
|
import { Hono as Hono16 } from "hono";
|
|
@@ -4487,6 +4590,49 @@ async function commitSrcChanges(dir, mindName) {
|
|
|
4487
4590
|
glog.info(`committed known-good src changes (${dir})`);
|
|
4488
4591
|
}
|
|
4489
4592
|
|
|
4593
|
+
// packages/daemon/src/lib/mind/npm-install.ts
|
|
4594
|
+
import { existsSync as existsSync7 } from "fs";
|
|
4595
|
+
import { resolve as resolve10 } from "path";
|
|
4596
|
+
var NPM_INSTALL_ARGS = [
|
|
4597
|
+
"install",
|
|
4598
|
+
"--no-audit",
|
|
4599
|
+
"--no-fund",
|
|
4600
|
+
"--prefer-offline",
|
|
4601
|
+
"--loglevel=error"
|
|
4602
|
+
];
|
|
4603
|
+
function lowPriorityArgv(cmd, args, ionice) {
|
|
4604
|
+
return ionice ? ["ionice", ["-c2", "-n7", "nice", "-n19", cmd, ...args]] : ["nice", ["-n19", cmd, ...args]];
|
|
4605
|
+
}
|
|
4606
|
+
function hasIonice() {
|
|
4607
|
+
return process.platform === "linux" && (existsSync7("/usr/bin/ionice") || existsSync7("/bin/ionice"));
|
|
4608
|
+
}
|
|
4609
|
+
async function npmInstallAsMind(cwd, mindName) {
|
|
4610
|
+
const [cmd, args] = lowPriorityArgv("npm", NPM_INSTALL_ARGS, hasIonice());
|
|
4611
|
+
if (isIsolationEnabled()) {
|
|
4612
|
+
const [wrappedCmd, wrappedArgs] = await wrapForIsolation(cmd, args, mindName);
|
|
4613
|
+
await exec(wrappedCmd, wrappedArgs, {
|
|
4614
|
+
cwd,
|
|
4615
|
+
env: { ...process.env, HOME: resolve10(cwd, "home") }
|
|
4616
|
+
});
|
|
4617
|
+
} else {
|
|
4618
|
+
await exec(cmd, args, { cwd });
|
|
4619
|
+
}
|
|
4620
|
+
}
|
|
4621
|
+
async function depsChangedSince(dir, fromRef) {
|
|
4622
|
+
try {
|
|
4623
|
+
await gitExec(["diff", "--quiet", fromRef, "HEAD", "--", "package.json", "package-lock.json"], {
|
|
4624
|
+
cwd: dir
|
|
4625
|
+
});
|
|
4626
|
+
return false;
|
|
4627
|
+
} catch {
|
|
4628
|
+
return true;
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4631
|
+
async function npmInstallNeeded(dir, preMergeRef) {
|
|
4632
|
+
if (!existsSync7(resolve10(dir, "node_modules"))) return true;
|
|
4633
|
+
return depsChangedSince(dir, preMergeRef);
|
|
4634
|
+
}
|
|
4635
|
+
|
|
4490
4636
|
// packages/daemon/src/lib/mind/thinking-config.ts
|
|
4491
4637
|
var CLAUDE_EFFORT = {
|
|
4492
4638
|
minimal: "low",
|
|
@@ -4743,7 +4889,7 @@ async function waitForImagegenJob(mind, id, timeoutMs) {
|
|
|
4743
4889
|
import { randomUUID } from "crypto";
|
|
4744
4890
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
4745
4891
|
import { homedir } from "os";
|
|
4746
|
-
import { resolve as
|
|
4892
|
+
import { resolve as resolve11 } from "path";
|
|
4747
4893
|
function convertSession(opts) {
|
|
4748
4894
|
const lines = readFileSync8(opts.sessionPath, "utf-8").trim().split("\n");
|
|
4749
4895
|
const sessionId = randomUUID();
|
|
@@ -4859,9 +5005,9 @@ function convertSession(opts) {
|
|
|
4859
5005
|
}
|
|
4860
5006
|
}
|
|
4861
5007
|
const projectId = opts.projectDir.replace(/\//g, "-");
|
|
4862
|
-
const sdkDir =
|
|
5008
|
+
const sdkDir = resolve11(homedir(), ".claude", "projects", projectId);
|
|
4863
5009
|
mkdirSync5(sdkDir, { recursive: true });
|
|
4864
|
-
const sdkPath =
|
|
5010
|
+
const sdkPath = resolve11(sdkDir, `${sessionId}.jsonl`);
|
|
4865
5011
|
writeFileSync7(sdkPath, `${sdkEvents.join("\n")}
|
|
4866
5012
|
`);
|
|
4867
5013
|
console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
|
|
@@ -4928,7 +5074,7 @@ async function getMindStatus(name, port, registryRunning, seed) {
|
|
|
4928
5074
|
let status = "stopped";
|
|
4929
5075
|
let wakeAt = null;
|
|
4930
5076
|
try {
|
|
4931
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5077
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-7JXEQQ2P.js");
|
|
4932
5078
|
const sleepManager = getSleepManagerIfReady2();
|
|
4933
5079
|
if (sleepManager?.isSleeping(name)) {
|
|
4934
5080
|
status = "sleeping";
|
|
@@ -5007,7 +5153,7 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
|
|
|
5007
5153
|
await gitExec(["commit", "-m", "initial commit"], opts);
|
|
5008
5154
|
}
|
|
5009
5155
|
async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
5010
|
-
const tempWorktree =
|
|
5156
|
+
const tempWorktree = resolve12(projectRoot, ".variants", "_template_update");
|
|
5011
5157
|
let branchExists = false;
|
|
5012
5158
|
try {
|
|
5013
5159
|
await gitExec(["rev-parse", "--verify", TEMPLATE_BRANCH], { cwd: projectRoot });
|
|
@@ -5018,7 +5164,7 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
5018
5164
|
await gitExec(["worktree", "remove", "--force", tempWorktree], { cwd: projectRoot });
|
|
5019
5165
|
} catch {
|
|
5020
5166
|
}
|
|
5021
|
-
if (
|
|
5167
|
+
if (existsSync8(tempWorktree)) {
|
|
5022
5168
|
rmSync3(tempWorktree, { recursive: true, force: true });
|
|
5023
5169
|
}
|
|
5024
5170
|
const templatesRoot = findTemplatesRoot();
|
|
@@ -5039,15 +5185,15 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
5039
5185
|
});
|
|
5040
5186
|
}
|
|
5041
5187
|
copyTemplateToDir(composedDir, tempWorktree, mindName, manifest);
|
|
5042
|
-
const initDir =
|
|
5043
|
-
if (
|
|
5188
|
+
const initDir = resolve12(tempWorktree, ".init");
|
|
5189
|
+
if (existsSync8(initDir)) {
|
|
5044
5190
|
rmSync3(initDir, { recursive: true, force: true });
|
|
5045
5191
|
}
|
|
5046
|
-
const homeDir =
|
|
5047
|
-
if (
|
|
5192
|
+
const homeDir = resolve12(tempWorktree, "home");
|
|
5193
|
+
if (existsSync8(homeDir)) {
|
|
5048
5194
|
for (const entry of readdirSync2(homeDir)) {
|
|
5049
5195
|
if (entry !== "VOLUTE.md") {
|
|
5050
|
-
rmSync3(
|
|
5196
|
+
rmSync3(resolve12(homeDir, entry), { recursive: true, force: true });
|
|
5051
5197
|
}
|
|
5052
5198
|
}
|
|
5053
5199
|
}
|
|
@@ -5062,7 +5208,7 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
5062
5208
|
await gitExec(["worktree", "remove", "--force", tempWorktree], { cwd: projectRoot });
|
|
5063
5209
|
} catch {
|
|
5064
5210
|
}
|
|
5065
|
-
if (
|
|
5211
|
+
if (existsSync8(tempWorktree)) {
|
|
5066
5212
|
rmSync3(tempWorktree, { recursive: true, force: true });
|
|
5067
5213
|
}
|
|
5068
5214
|
rmSync3(composedDir, { recursive: true, force: true });
|
|
@@ -5085,14 +5231,6 @@ async function mergeTemplateBranch(worktreeDir) {
|
|
|
5085
5231
|
throw e;
|
|
5086
5232
|
}
|
|
5087
5233
|
}
|
|
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
5234
|
async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariantName, upgradeBranch, template, oldTemplate) {
|
|
5097
5235
|
const templateChanged = template !== oldTemplate;
|
|
5098
5236
|
const mainStatus = (await gitExec(["status", "--porcelain"], { cwd: dir })).trim();
|
|
@@ -5100,9 +5238,10 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5100
5238
|
await gitExec(["add", "-A"], { cwd: dir });
|
|
5101
5239
|
await gitExec(["commit", "-m", "Auto-commit before upgrade merge"], { cwd: dir });
|
|
5102
5240
|
}
|
|
5241
|
+
const preMergeHead = (await gitExec(["rev-parse", "HEAD"], { cwd: dir })).trim();
|
|
5103
5242
|
await gitExec(["merge", upgradeBranch], { cwd: dir });
|
|
5104
5243
|
try {
|
|
5105
|
-
await cleanupVariant(upgradeVariantName, dir, worktreeDir);
|
|
5244
|
+
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir);
|
|
5106
5245
|
} catch (err) {
|
|
5107
5246
|
logger_default.warn(`failed to clean up upgrade worktree for ${mindName}`, logger_default.errorData(err));
|
|
5108
5247
|
}
|
|
@@ -5113,7 +5252,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5113
5252
|
let switchWarning;
|
|
5114
5253
|
if (templateChanged) {
|
|
5115
5254
|
try {
|
|
5116
|
-
applyTemplateHomeFiles(
|
|
5255
|
+
applyTemplateHomeFiles(resolve12(dir, "home"), template);
|
|
5117
5256
|
const migratedSkills = migrateSkillsToTemplate(dir, oldTemplate, template);
|
|
5118
5257
|
await gitExec(["add", "home/"], { cwd: dir });
|
|
5119
5258
|
try {
|
|
@@ -5140,14 +5279,18 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5140
5279
|
} catch (err) {
|
|
5141
5280
|
logger_default.warn(`failed to update template for ${mindName}`, logger_default.errorData(err));
|
|
5142
5281
|
}
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5282
|
+
if (await npmInstallNeeded(dir, preMergeHead)) {
|
|
5283
|
+
try {
|
|
5284
|
+
await npmInstallAsMind(dir, mindName);
|
|
5285
|
+
} catch (err) {
|
|
5286
|
+
logger_default.warn(`npm install failed after upgrade merge for ${mindName}`, logger_default.errorData(err));
|
|
5287
|
+
return {
|
|
5288
|
+
ok: true,
|
|
5289
|
+
warning: `Upgrade merged but npm install failed: ${err instanceof Error ? err.message : String(err)}. You may need to run npm install manually.`
|
|
5290
|
+
};
|
|
5291
|
+
}
|
|
5292
|
+
} else {
|
|
5293
|
+
logger_default.info(`skipping npm install for ${mindName} \u2014 dependencies unchanged by upgrade`);
|
|
5151
5294
|
}
|
|
5152
5295
|
const manager = getMindManager();
|
|
5153
5296
|
try {
|
|
@@ -5155,7 +5298,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5155
5298
|
await manager.stopMind(mindName);
|
|
5156
5299
|
}
|
|
5157
5300
|
manager.setPendingContext(mindName, { type: "upgraded" });
|
|
5158
|
-
await manager.startMind(mindName);
|
|
5301
|
+
await manager.startMind(mindName, { healthTimeoutMs: 12e4 });
|
|
5159
5302
|
} catch (e) {
|
|
5160
5303
|
return {
|
|
5161
5304
|
ok: true,
|
|
@@ -5165,8 +5308,8 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
5165
5308
|
return { ok: true, warning: switchWarning };
|
|
5166
5309
|
}
|
|
5167
5310
|
async function importFromArchive(c, tempDir, nameOverride, manifest) {
|
|
5168
|
-
const extractedMindDir =
|
|
5169
|
-
if (!
|
|
5311
|
+
const extractedMindDir = resolve12(tempDir, "mind");
|
|
5312
|
+
if (!existsSync8(extractedMindDir)) {
|
|
5170
5313
|
return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
|
|
5171
5314
|
}
|
|
5172
5315
|
if (!manifest?.includes || !manifest.name || !manifest.template) {
|
|
@@ -5184,7 +5327,7 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5184
5327
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
5185
5328
|
ensureVoluteHome();
|
|
5186
5329
|
const dest = mindDir(name);
|
|
5187
|
-
if (
|
|
5330
|
+
if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5188
5331
|
try {
|
|
5189
5332
|
cpSync(extractedMindDir, dest, { recursive: true });
|
|
5190
5333
|
if (!manifest.includes.identity) {
|
|
@@ -5192,9 +5335,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5192
5335
|
}
|
|
5193
5336
|
const state = stateDir(name);
|
|
5194
5337
|
mkdirSync6(state, { recursive: true });
|
|
5195
|
-
const envJson =
|
|
5196
|
-
if (
|
|
5197
|
-
cpSync(envJson,
|
|
5338
|
+
const envJson = resolve12(tempDir, "state/env.json");
|
|
5339
|
+
if (existsSync8(envJson)) {
|
|
5340
|
+
cpSync(envJson, resolve12(state, "env.json"));
|
|
5198
5341
|
}
|
|
5199
5342
|
const port = await nextPort();
|
|
5200
5343
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
@@ -5203,30 +5346,30 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
5203
5346
|
} catch (err) {
|
|
5204
5347
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5205
5348
|
}
|
|
5206
|
-
const homeDir =
|
|
5349
|
+
const homeDir = resolve12(dest, "home");
|
|
5207
5350
|
ensureVoluteGroup();
|
|
5208
5351
|
createMindUser(name, homeDir);
|
|
5209
5352
|
await chownMindDir(dest, name);
|
|
5210
5353
|
await npmInstallAsMind(dest, name);
|
|
5211
5354
|
await importHistoryFromArchive(name, tempDir);
|
|
5212
5355
|
importSessionsFromArchive(dest, tempDir);
|
|
5213
|
-
if (!
|
|
5356
|
+
if (!existsSync8(resolve12(dest, ".git"))) {
|
|
5214
5357
|
try {
|
|
5215
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5358
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve12(dest, "home") } : void 0;
|
|
5216
5359
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
5217
5360
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
5218
5361
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
5219
5362
|
await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
|
|
5220
5363
|
} catch (err) {
|
|
5221
5364
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
5222
|
-
rmSync3(
|
|
5365
|
+
rmSync3(resolve12(dest, ".git"), { recursive: true, force: true });
|
|
5223
5366
|
}
|
|
5224
5367
|
}
|
|
5225
5368
|
await chownMindDir(dest, name);
|
|
5226
5369
|
rmSync3(tempDir, { recursive: true, force: true });
|
|
5227
5370
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
5228
5371
|
} catch (err) {
|
|
5229
|
-
if (
|
|
5372
|
+
if (existsSync8(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5230
5373
|
try {
|
|
5231
5374
|
await removeMind(name);
|
|
5232
5375
|
} catch (cleanupErr) {
|
|
@@ -5243,7 +5386,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5243
5386
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
5244
5387
|
ensureVoluteHome();
|
|
5245
5388
|
const dest = mindDir(name);
|
|
5246
|
-
if (
|
|
5389
|
+
if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5247
5390
|
const templatesRoot = findTemplatesRoot();
|
|
5248
5391
|
const { composedDir, manifest: templateManifest } = composeTemplate(
|
|
5249
5392
|
templatesRoot,
|
|
@@ -5252,36 +5395,36 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5252
5395
|
try {
|
|
5253
5396
|
copyTemplateToDir(composedDir, dest, name, templateManifest);
|
|
5254
5397
|
applyInitFiles(dest);
|
|
5255
|
-
const extractedHome =
|
|
5256
|
-
if (
|
|
5257
|
-
cpSync(extractedHome,
|
|
5398
|
+
const extractedHome = resolve12(extractedMindDir, "home");
|
|
5399
|
+
if (existsSync8(extractedHome)) {
|
|
5400
|
+
cpSync(extractedHome, resolve12(dest, "home"), { recursive: true });
|
|
5258
5401
|
}
|
|
5259
|
-
const extractedMindInternal =
|
|
5260
|
-
if (
|
|
5261
|
-
cpSync(extractedMindInternal,
|
|
5402
|
+
const extractedMindInternal = resolve12(extractedMindDir, ".mind");
|
|
5403
|
+
if (existsSync8(extractedMindInternal)) {
|
|
5404
|
+
cpSync(extractedMindInternal, resolve12(dest, ".mind"), { recursive: true });
|
|
5262
5405
|
}
|
|
5263
|
-
const identityDir =
|
|
5406
|
+
const identityDir = resolve12(dest, ".mind/identity");
|
|
5264
5407
|
let publicKeyPem;
|
|
5265
|
-
if (!manifest.includes.identity || !
|
|
5408
|
+
if (!manifest.includes.identity || !existsSync8(resolve12(identityDir, "private.pem"))) {
|
|
5266
5409
|
({ publicKeyPem } = generateIdentity(dest));
|
|
5267
5410
|
} else {
|
|
5268
|
-
publicKeyPem = readFileSync9(
|
|
5411
|
+
publicKeyPem = readFileSync9(resolve12(identityDir, "public.pem"), "utf-8");
|
|
5269
5412
|
}
|
|
5270
|
-
const promptsPath =
|
|
5271
|
-
if (!
|
|
5413
|
+
const promptsPath = resolve12(dest, "home/.config/prompts.json");
|
|
5414
|
+
if (!existsSync8(promptsPath)) {
|
|
5272
5415
|
const mindPrompts = await getMindPromptDefaults();
|
|
5273
5416
|
writeFileSync8(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
|
|
5274
5417
|
`);
|
|
5275
5418
|
}
|
|
5276
5419
|
const state = stateDir(name);
|
|
5277
5420
|
mkdirSync6(state, { recursive: true });
|
|
5278
|
-
const envJson =
|
|
5279
|
-
if (
|
|
5280
|
-
cpSync(envJson,
|
|
5421
|
+
const envJson = resolve12(tempDir, "state/env.json");
|
|
5422
|
+
if (existsSync8(envJson)) {
|
|
5423
|
+
cpSync(envJson, resolve12(state, "env.json"));
|
|
5281
5424
|
}
|
|
5282
5425
|
const port = await nextPort();
|
|
5283
5426
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
5284
|
-
const homeDir =
|
|
5427
|
+
const homeDir = resolve12(dest, "home");
|
|
5285
5428
|
ensureVoluteGroup();
|
|
5286
5429
|
createMindUser(name, homeDir);
|
|
5287
5430
|
await chownMindDir(dest, name);
|
|
@@ -5294,7 +5437,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5294
5437
|
await initTemplateBranch(dest, composedDir, templateManifest, name, env);
|
|
5295
5438
|
} catch (err) {
|
|
5296
5439
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
5297
|
-
rmSync3(
|
|
5440
|
+
rmSync3(resolve12(dest, ".git"), { recursive: true, force: true });
|
|
5298
5441
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
5299
5442
|
}
|
|
5300
5443
|
const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
|
|
@@ -5324,7 +5467,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5324
5467
|
...skillWarnings.length > 0 && { skillWarnings }
|
|
5325
5468
|
});
|
|
5326
5469
|
} catch (err) {
|
|
5327
|
-
if (
|
|
5470
|
+
if (existsSync8(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5328
5471
|
try {
|
|
5329
5472
|
await removeMind(name);
|
|
5330
5473
|
} catch (cleanupErr) {
|
|
@@ -5337,8 +5480,8 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
5337
5480
|
}
|
|
5338
5481
|
}
|
|
5339
5482
|
async function importHistoryFromArchive(name, tempDir) {
|
|
5340
|
-
const historyJsonl =
|
|
5341
|
-
if (!
|
|
5483
|
+
const historyJsonl = resolve12(tempDir, "history.jsonl");
|
|
5484
|
+
if (!existsSync8(historyJsonl)) return;
|
|
5342
5485
|
try {
|
|
5343
5486
|
const db = await getDb();
|
|
5344
5487
|
const lines = readFileSync9(historyJsonl, "utf-8").trim().split("\n");
|
|
@@ -5378,13 +5521,13 @@ async function importHistoryFromArchive(name, tempDir) {
|
|
|
5378
5521
|
}
|
|
5379
5522
|
}
|
|
5380
5523
|
function importSessionsFromArchive(dest, tempDir) {
|
|
5381
|
-
const sessionsDir =
|
|
5382
|
-
if (!
|
|
5524
|
+
const sessionsDir = resolve12(tempDir, "sessions");
|
|
5525
|
+
if (!existsSync8(sessionsDir)) return;
|
|
5383
5526
|
try {
|
|
5384
|
-
const destSessions =
|
|
5527
|
+
const destSessions = resolve12(dest, ".mind/sessions");
|
|
5385
5528
|
mkdirSync6(destSessions, { recursive: true });
|
|
5386
5529
|
for (const file of readdirSync2(sessionsDir)) {
|
|
5387
|
-
cpSync(
|
|
5530
|
+
cpSync(resolve12(sessionsDir, file), resolve12(destSessions, file));
|
|
5388
5531
|
}
|
|
5389
5532
|
} catch (err) {
|
|
5390
5533
|
logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
|
|
@@ -5458,13 +5601,13 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5458
5601
|
);
|
|
5459
5602
|
}
|
|
5460
5603
|
{
|
|
5461
|
-
const { mindLimitError, readGlobalConfig: readGlobalConfig2 } = await import("./setup-
|
|
5604
|
+
const { mindLimitError, readGlobalConfig: readGlobalConfig2 } = await import("./setup-WZSXHHRJ.js");
|
|
5462
5605
|
const limitError = mindLimitError(await countCappedMinds(), readGlobalConfig2().maxMinds);
|
|
5463
5606
|
if (limitError) return c.json({ error: limitError }, 409);
|
|
5464
5607
|
}
|
|
5465
5608
|
ensureVoluteHome();
|
|
5466
5609
|
const dest = mindDir(name);
|
|
5467
|
-
if (
|
|
5610
|
+
if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5468
5611
|
const templatesRoot = findTemplatesRoot();
|
|
5469
5612
|
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5470
5613
|
try {
|
|
@@ -5473,7 +5616,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5473
5616
|
const { publicKeyPem } = generateIdentity(dest);
|
|
5474
5617
|
let effectiveModel = body.model;
|
|
5475
5618
|
{
|
|
5476
|
-
const { readGlobalConfig: readGlobal } = await import("./setup-
|
|
5619
|
+
const { readGlobalConfig: readGlobal } = await import("./setup-WZSXHHRJ.js");
|
|
5477
5620
|
const mindDefaults = readGlobal().mindDefaults;
|
|
5478
5621
|
const config2 = readVoluteConfig(dest);
|
|
5479
5622
|
if (!config2) throw new Error("Failed to read volute.json after identity generation");
|
|
@@ -5501,9 +5644,9 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5501
5644
|
writeVoluteConfig(dest, config2);
|
|
5502
5645
|
const modelId = body.model ?? cog?.model;
|
|
5503
5646
|
effectiveModel = modelId ? qualifyModelId(modelId) : void 0;
|
|
5504
|
-
const sdkConfigPath =
|
|
5647
|
+
const sdkConfigPath = resolve12(dest, "home/.config/config.json");
|
|
5505
5648
|
if (modelId || cog?.compaction) {
|
|
5506
|
-
const existing =
|
|
5649
|
+
const existing = existsSync8(sdkConfigPath) ? JSON.parse(readFileSync9(sdkConfigPath, "utf-8")) : {};
|
|
5507
5650
|
if (modelId) {
|
|
5508
5651
|
existing.model = template === "pi" ? qualifyModelId(modelId) : unqualifyModelId(modelId);
|
|
5509
5652
|
}
|
|
@@ -5516,7 +5659,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5516
5659
|
}
|
|
5517
5660
|
const mindPrompts = await getMindPromptDefaults();
|
|
5518
5661
|
writeFileSync8(
|
|
5519
|
-
|
|
5662
|
+
resolve12(dest, "home/.config/prompts.json"),
|
|
5520
5663
|
`${JSON.stringify(mindPrompts, null, 2)}
|
|
5521
5664
|
`
|
|
5522
5665
|
);
|
|
@@ -5528,7 +5671,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5528
5671
|
} catch (err) {
|
|
5529
5672
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5530
5673
|
}
|
|
5531
|
-
const homeDir =
|
|
5674
|
+
const homeDir = resolve12(dest, "home");
|
|
5532
5675
|
ensureVoluteGroup();
|
|
5533
5676
|
createMindUser(name, homeDir);
|
|
5534
5677
|
await chownMindDir(dest, name);
|
|
@@ -5541,7 +5684,7 @@ var app13 = new Hono16().post("/", requireAdminOrSystem, zValidator6("json", cre
|
|
|
5541
5684
|
await initTemplateBranch(dest, composedDir, manifest, name, env);
|
|
5542
5685
|
} catch (err) {
|
|
5543
5686
|
logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
|
|
5544
|
-
rmSync3(
|
|
5687
|
+
rmSync3(resolve12(dest, ".git"), { recursive: true, force: true });
|
|
5545
5688
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
5546
5689
|
}
|
|
5547
5690
|
if (body.stage === "seed") {
|
|
@@ -5550,11 +5693,11 @@ Your creator described you as: "${body.description}"
|
|
|
5550
5693
|
` : "";
|
|
5551
5694
|
const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
|
|
5552
5695
|
const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
|
|
5553
|
-
writeFileSync8(
|
|
5696
|
+
writeFileSync8(resolve12(dest, "home/SOUL.md"), seedSoul);
|
|
5554
5697
|
}
|
|
5555
5698
|
let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
|
|
5556
5699
|
if (body.stage === "seed" && !body.skills) {
|
|
5557
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
5700
|
+
const { isImagegenEnabled } = await import("./setup-WZSXHHRJ.js");
|
|
5558
5701
|
if (isImagegenEnabled()) {
|
|
5559
5702
|
skillSet = [...skillSet, "imagegen"];
|
|
5560
5703
|
}
|
|
@@ -5576,7 +5719,7 @@ Your creator described you as: "${body.description}"
|
|
|
5576
5719
|
const spiritName = getSpiritName();
|
|
5577
5720
|
const spiritEntry = await findMind(spiritName);
|
|
5578
5721
|
if (spiritEntry) {
|
|
5579
|
-
const { spiritDir } = await import("./spirit-
|
|
5722
|
+
const { spiritDir } = await import("./spirit-25JVAL3M.js");
|
|
5580
5723
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
5581
5724
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
5582
5725
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -5591,7 +5734,7 @@ Your creator described you as: "${body.description}"
|
|
|
5591
5734
|
});
|
|
5592
5735
|
spiritConfig.schedules = schedules;
|
|
5593
5736
|
writeVoluteConfig(sDir, spiritConfig);
|
|
5594
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
5737
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-TNBN54ZK.js");
|
|
5595
5738
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
5596
5739
|
}
|
|
5597
5740
|
}
|
|
@@ -5602,11 +5745,11 @@ Your creator described you as: "${body.description}"
|
|
|
5602
5745
|
if (body.stage !== "seed") {
|
|
5603
5746
|
const customSoul = await getPromptIfCustom("default_soul");
|
|
5604
5747
|
if (customSoul) {
|
|
5605
|
-
writeFileSync8(
|
|
5748
|
+
writeFileSync8(resolve12(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
|
|
5606
5749
|
}
|
|
5607
5750
|
const customMemory = await getPromptIfCustom("default_memory");
|
|
5608
5751
|
if (customMemory) {
|
|
5609
|
-
writeFileSync8(
|
|
5752
|
+
writeFileSync8(resolve12(dest, "home/MEMORY.md"), customMemory);
|
|
5610
5753
|
}
|
|
5611
5754
|
}
|
|
5612
5755
|
await chownMindDir(dest, name);
|
|
@@ -5624,8 +5767,9 @@ Your creator described you as: "${body.description}"
|
|
|
5624
5767
|
description: body.description
|
|
5625
5768
|
}
|
|
5626
5769
|
});
|
|
5627
|
-
announceToSystem(`${name} has joined`).catch(
|
|
5628
|
-
|
|
5770
|
+
announceToSystem(`${name} has joined`).catch(
|
|
5771
|
+
(err) => logger_default.warn(`failed to announce ${name} joining #system`, logger_default.errorData(err))
|
|
5772
|
+
);
|
|
5629
5773
|
const credentialWarning = await missingCredentialWarning(
|
|
5630
5774
|
template,
|
|
5631
5775
|
effectiveModel,
|
|
@@ -5645,10 +5789,11 @@ Your creator described you as: "${body.description}"
|
|
|
5645
5789
|
...skillWarnings.length > 0 && { skillWarnings }
|
|
5646
5790
|
});
|
|
5647
5791
|
} catch (err) {
|
|
5648
|
-
if (
|
|
5792
|
+
if (existsSync8(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5649
5793
|
try {
|
|
5650
5794
|
await removeMind(name);
|
|
5651
|
-
} catch {
|
|
5795
|
+
} catch (cleanupErr) {
|
|
5796
|
+
logger_default.warn(`failed to clean up registry for ${name}`, logger_default.errorData(cleanupErr));
|
|
5652
5797
|
}
|
|
5653
5798
|
return c.json({ error: err instanceof Error ? err.message : "Failed to create mind" }, 500);
|
|
5654
5799
|
} finally {
|
|
@@ -5665,13 +5810,13 @@ Your creator described you as: "${body.description}"
|
|
|
5665
5810
|
return importFromArchive(c, body.archivePath, body.name, body.manifest);
|
|
5666
5811
|
}
|
|
5667
5812
|
const wsDir = body.workspacePath;
|
|
5668
|
-
if (!wsDir || !
|
|
5813
|
+
if (!wsDir || !existsSync8(resolve12(wsDir, "SOUL.md")) || !existsSync8(resolve12(wsDir, "IDENTITY.md"))) {
|
|
5669
5814
|
return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
|
|
5670
5815
|
}
|
|
5671
|
-
const soul = readFileSync9(
|
|
5672
|
-
const identity = readFileSync9(
|
|
5673
|
-
const userPath =
|
|
5674
|
-
const user =
|
|
5816
|
+
const soul = readFileSync9(resolve12(wsDir, "SOUL.md"), "utf-8");
|
|
5817
|
+
const identity = readFileSync9(resolve12(wsDir, "IDENTITY.md"), "utf-8");
|
|
5818
|
+
const userPath = resolve12(wsDir, "USER.md");
|
|
5819
|
+
const user = existsSync8(userPath) ? readFileSync9(userPath, "utf-8") : "";
|
|
5675
5820
|
const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
|
|
5676
5821
|
const template = body.template ?? "claude";
|
|
5677
5822
|
const nameErr = validateMindName(name);
|
|
@@ -5691,33 +5836,33 @@ ${user.trimEnd()}
|
|
|
5691
5836
|
` : "";
|
|
5692
5837
|
ensureVoluteHome();
|
|
5693
5838
|
const dest = mindDir(name);
|
|
5694
|
-
if (
|
|
5839
|
+
if (existsSync8(dest)) return c.json({ error: "Mind directory already exists" }, 409);
|
|
5695
5840
|
const templatesRoot = findTemplatesRoot();
|
|
5696
5841
|
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
5697
5842
|
try {
|
|
5698
5843
|
copyTemplateToDir(composedDir, dest, name, manifest);
|
|
5699
5844
|
applyInitFiles(dest);
|
|
5700
5845
|
const { publicKeyPem: importPublicKey } = generateIdentity(dest);
|
|
5701
|
-
writeFileSync8(
|
|
5702
|
-
const wsMemoryPath =
|
|
5703
|
-
const hasMemory =
|
|
5846
|
+
writeFileSync8(resolve12(dest, "home/SOUL.md"), mergedSoul);
|
|
5847
|
+
const wsMemoryPath = resolve12(wsDir, "MEMORY.md");
|
|
5848
|
+
const hasMemory = existsSync8(wsMemoryPath);
|
|
5704
5849
|
if (hasMemory) {
|
|
5705
5850
|
const existingMemory = readFileSync9(wsMemoryPath, "utf-8");
|
|
5706
5851
|
writeFileSync8(
|
|
5707
|
-
|
|
5852
|
+
resolve12(dest, "home/MEMORY.md"),
|
|
5708
5853
|
`${existingMemory.trimEnd()}${mergedMemoryExtra}`
|
|
5709
5854
|
);
|
|
5710
5855
|
} else if (user) {
|
|
5711
|
-
writeFileSync8(
|
|
5856
|
+
writeFileSync8(resolve12(dest, "home/MEMORY.md"), `${user.trimEnd()}
|
|
5712
5857
|
`);
|
|
5713
5858
|
}
|
|
5714
|
-
const wsMemoryDir =
|
|
5859
|
+
const wsMemoryDir = resolve12(wsDir, "memory");
|
|
5715
5860
|
let dailyLogCount = 0;
|
|
5716
|
-
if (
|
|
5717
|
-
const destMemoryDir =
|
|
5861
|
+
if (existsSync8(wsMemoryDir)) {
|
|
5862
|
+
const destMemoryDir = resolve12(dest, "home/memory");
|
|
5718
5863
|
const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
|
|
5719
5864
|
for (const file of files) {
|
|
5720
|
-
cpSync(
|
|
5865
|
+
cpSync(resolve12(wsMemoryDir, file), resolve12(destMemoryDir, file));
|
|
5721
5866
|
}
|
|
5722
5867
|
dailyLogCount = files.length;
|
|
5723
5868
|
}
|
|
@@ -5728,7 +5873,7 @@ ${user.trimEnd()}
|
|
|
5728
5873
|
} catch (err) {
|
|
5729
5874
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
5730
5875
|
}
|
|
5731
|
-
const homeDir =
|
|
5876
|
+
const homeDir = resolve12(dest, "home");
|
|
5732
5877
|
ensureVoluteGroup();
|
|
5733
5878
|
createMindUser(name, homeDir);
|
|
5734
5879
|
await chownMindDir(dest, name);
|
|
@@ -5736,20 +5881,20 @@ ${user.trimEnd()}
|
|
|
5736
5881
|
if (!hasMemory && dailyLogCount > 0) {
|
|
5737
5882
|
await consolidateMemory(dest);
|
|
5738
5883
|
}
|
|
5739
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5884
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve12(dest, "home") } : void 0;
|
|
5740
5885
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
5741
5886
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
5742
5887
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
5743
5888
|
await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
|
|
5744
|
-
const sessionFile = body.sessionPath ?
|
|
5745
|
-
if (sessionFile &&
|
|
5889
|
+
const sessionFile = body.sessionPath ? resolve12(body.sessionPath) : findOpenClawSession(wsDir);
|
|
5890
|
+
if (sessionFile && existsSync8(sessionFile)) {
|
|
5746
5891
|
if (template === "pi") {
|
|
5747
5892
|
importPiSession(sessionFile, dest);
|
|
5748
5893
|
} else if (template === "claude") {
|
|
5749
5894
|
const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
|
|
5750
|
-
const mindRuntimeDir =
|
|
5895
|
+
const mindRuntimeDir = resolve12(dest, ".mind");
|
|
5751
5896
|
mkdirSync6(mindRuntimeDir, { recursive: true });
|
|
5752
|
-
writeFileSync8(
|
|
5897
|
+
writeFileSync8(resolve12(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
|
|
5753
5898
|
}
|
|
5754
5899
|
}
|
|
5755
5900
|
importOpenClawConnectors(name, dest);
|
|
@@ -5759,10 +5904,11 @@ ${user.trimEnd()}
|
|
|
5759
5904
|
);
|
|
5760
5905
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
5761
5906
|
} catch (err) {
|
|
5762
|
-
if (
|
|
5907
|
+
if (existsSync8(dest)) rmSync3(dest, { recursive: true, force: true });
|
|
5763
5908
|
try {
|
|
5764
5909
|
await removeMind(name);
|
|
5765
|
-
} catch {
|
|
5910
|
+
} catch (cleanupErr) {
|
|
5911
|
+
logger_default.warn(`failed to clean up registry for ${name}`, logger_default.errorData(cleanupErr));
|
|
5766
5912
|
}
|
|
5767
5913
|
return c.json({ error: err instanceof Error ? err.message : "Failed to import mind" }, 500);
|
|
5768
5914
|
} finally {
|
|
@@ -5794,7 +5940,7 @@ ${user.trimEnd()}
|
|
|
5794
5940
|
stage: entry.stage,
|
|
5795
5941
|
dir: entry.dir
|
|
5796
5942
|
});
|
|
5797
|
-
const hasPages =
|
|
5943
|
+
const hasPages = existsSync8(resolve12(mindDir(entry.name), "home", "pages"));
|
|
5798
5944
|
const lastActiveAt = lastActiveMap.get(entry.name) ?? null;
|
|
5799
5945
|
if (!privileged) return toPublicMind(entry, mindStatus, { hasPages, lastActiveAt });
|
|
5800
5946
|
return {
|
|
@@ -5812,12 +5958,12 @@ ${user.trimEnd()}
|
|
|
5812
5958
|
const entry = await findMind(name);
|
|
5813
5959
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
5814
5960
|
const dir = entry.dir ?? mindDir(entry.parent ?? name);
|
|
5815
|
-
if (!
|
|
5961
|
+
if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
5816
5962
|
const mindStatus = await getMindStatus(name, entry.port, void 0, {
|
|
5817
5963
|
stage: entry.stage,
|
|
5818
5964
|
dir: entry.dir
|
|
5819
5965
|
});
|
|
5820
|
-
const hasPages =
|
|
5966
|
+
const hasPages = existsSync8(resolve12(mindDir(name), "home", "pages"));
|
|
5821
5967
|
if (!isPrivileged(c)) {
|
|
5822
5968
|
return c.json(toPublicMind(entry, mindStatus, { hasPages }));
|
|
5823
5969
|
}
|
|
@@ -5857,7 +6003,7 @@ ${user.trimEnd()}
|
|
|
5857
6003
|
const projectDir = entry.dir ?? mindDir(name);
|
|
5858
6004
|
if (entry.parent) {
|
|
5859
6005
|
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
|
|
5860
|
-
} else if (!
|
|
6006
|
+
} else if (!existsSync8(projectDir)) {
|
|
5861
6007
|
return c.json({ error: "Mind directory missing" }, 404);
|
|
5862
6008
|
}
|
|
5863
6009
|
if (getMindManager().isRunning(name)) {
|
|
@@ -5878,7 +6024,7 @@ ${user.trimEnd()}
|
|
|
5878
6024
|
const projectDir = entry.dir ?? mindDir(name);
|
|
5879
6025
|
if (entry.parent) {
|
|
5880
6026
|
if (!entry.dir) return c.json({ error: `Variant ${name} has no directory` }, 404);
|
|
5881
|
-
} else if (!
|
|
6027
|
+
} else if (!existsSync8(projectDir)) {
|
|
5882
6028
|
return c.json({ error: "Mind directory missing" }, 404);
|
|
5883
6029
|
}
|
|
5884
6030
|
let context;
|
|
@@ -5894,7 +6040,7 @@ ${user.trimEnd()}
|
|
|
5894
6040
|
const manager = getMindManager();
|
|
5895
6041
|
try {
|
|
5896
6042
|
if (context?.type === "reload") {
|
|
5897
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6043
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-7JXEQQ2P.js");
|
|
5898
6044
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
5899
6045
|
if (sleepState?.sleeping) {
|
|
5900
6046
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -5914,7 +6060,7 @@ ${user.trimEnd()}
|
|
|
5914
6060
|
const variantEntry = await findMind(mergeVariantName);
|
|
5915
6061
|
if (variantEntry && variantEntry.parent === baseName && variantEntry.dir && variantEntry.branch) {
|
|
5916
6062
|
const projectRoot = mindDir(baseName);
|
|
5917
|
-
if (
|
|
6063
|
+
if (existsSync8(variantEntry.dir)) {
|
|
5918
6064
|
const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
|
|
5919
6065
|
if (status) {
|
|
5920
6066
|
try {
|
|
@@ -5941,13 +6087,16 @@ ${user.trimEnd()}
|
|
|
5941
6087
|
logger_default.error(`failed to auto-commit main worktree for ${baseName}`, logger_default.errorData(e));
|
|
5942
6088
|
}
|
|
5943
6089
|
}
|
|
6090
|
+
const preMergeHead = (await gitExec(["rev-parse", "HEAD"], { cwd: projectRoot })).trim();
|
|
5944
6091
|
const memoryDelta = await mergeVariantExcludingMemory(projectRoot, variantEntry.branch);
|
|
5945
6092
|
if (memoryDelta && context) context.memoryDelta = memoryDelta;
|
|
5946
|
-
await cleanupVariant(mergeVariantName, projectRoot, variantEntry.dir);
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
6093
|
+
await cleanupVariant(mergeVariantName, baseName, projectRoot, variantEntry.dir);
|
|
6094
|
+
if (await npmInstallNeeded(projectRoot, preMergeHead)) {
|
|
6095
|
+
try {
|
|
6096
|
+
await npmInstallAsMind(projectRoot, baseName);
|
|
6097
|
+
} catch (e) {
|
|
6098
|
+
logger_default.error(`npm install failed after merge for ${baseName}`, logger_default.errorData(e));
|
|
6099
|
+
}
|
|
5951
6100
|
}
|
|
5952
6101
|
}
|
|
5953
6102
|
}
|
|
@@ -6009,7 +6158,7 @@ ${user.trimEnd()}
|
|
|
6009
6158
|
const name = c.req.param("name");
|
|
6010
6159
|
const entry = await findMind(name);
|
|
6011
6160
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6012
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6161
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-7JXEQQ2P.js");
|
|
6013
6162
|
const sm = getSleepManagerIfReady2();
|
|
6014
6163
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6015
6164
|
return c.json(sm.getState(name));
|
|
@@ -6017,7 +6166,7 @@ ${user.trimEnd()}
|
|
|
6017
6166
|
const name = c.req.param("name");
|
|
6018
6167
|
const entry = await findMind(name);
|
|
6019
6168
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6020
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6169
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-7JXEQQ2P.js");
|
|
6021
6170
|
const sm = getSleepManagerIfReady2();
|
|
6022
6171
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6023
6172
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -6037,7 +6186,7 @@ ${user.trimEnd()}
|
|
|
6037
6186
|
const name = c.req.param("name");
|
|
6038
6187
|
const entry = await findMind(name);
|
|
6039
6188
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6040
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6189
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-7JXEQQ2P.js");
|
|
6041
6190
|
const sm = getSleepManagerIfReady2();
|
|
6042
6191
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6043
6192
|
const sleepState = sm.getState(name);
|
|
@@ -6052,7 +6201,7 @@ ${user.trimEnd()}
|
|
|
6052
6201
|
const name = c.req.param("name");
|
|
6053
6202
|
const entry = await findMind(name);
|
|
6054
6203
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6055
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6204
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-7JXEQQ2P.js");
|
|
6056
6205
|
const sm = getSleepManagerIfReady2();
|
|
6057
6206
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6058
6207
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -6068,19 +6217,19 @@ ${user.trimEnd()}
|
|
|
6068
6217
|
if (body.displayName !== void 0) profile.displayName = body.displayName;
|
|
6069
6218
|
if (body.description !== void 0) profile.description = body.description;
|
|
6070
6219
|
if (body.avatar !== void 0) {
|
|
6071
|
-
const homeDir =
|
|
6220
|
+
const homeDir = resolve12(dir, "home");
|
|
6072
6221
|
const avatarPath = safeResolveWithinBase(homeDir, body.avatar);
|
|
6073
6222
|
if (!avatarPath) {
|
|
6074
6223
|
return c.json({ error: "Avatar path must be inside the mind's home directory" }, 400);
|
|
6075
6224
|
}
|
|
6076
|
-
if (!
|
|
6225
|
+
if (!existsSync8(avatarPath)) {
|
|
6077
6226
|
return c.json({ error: `Avatar file not found: ${relative(homeDir, avatarPath)}` }, 400);
|
|
6078
6227
|
}
|
|
6079
6228
|
profile.avatar = relative(homeDir, avatarPath);
|
|
6080
6229
|
}
|
|
6081
6230
|
config2.profile = profile;
|
|
6082
6231
|
writeVoluteConfig(dir, config2);
|
|
6083
|
-
const { syncMindProfile: syncMindProfile2 } = await import("./auth-
|
|
6232
|
+
const { syncMindProfile: syncMindProfile2 } = await import("./auth-X6EMNEGB.js");
|
|
6084
6233
|
await syncMindProfile2(name, profile);
|
|
6085
6234
|
broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
|
|
6086
6235
|
return c.json({ ok: true });
|
|
@@ -6124,7 +6273,7 @@ ${user.trimEnd()}
|
|
|
6124
6273
|
});
|
|
6125
6274
|
}
|
|
6126
6275
|
if (!force) {
|
|
6127
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6276
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-7JXEQQ2P.js");
|
|
6128
6277
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
6129
6278
|
return c.json({ output: "" });
|
|
6130
6279
|
}
|
|
@@ -6179,7 +6328,7 @@ ${user.trimEnd()}
|
|
|
6179
6328
|
}
|
|
6180
6329
|
}
|
|
6181
6330
|
const dir = entry.dir ?? mindDir(name);
|
|
6182
|
-
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-
|
|
6331
|
+
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-DYOVCYHN.js");
|
|
6183
6332
|
const checklist = evaluateSeedChecklist2(dir);
|
|
6184
6333
|
const done = [];
|
|
6185
6334
|
const remaining = [];
|
|
@@ -6221,7 +6370,7 @@ ${user.trimEnd()}
|
|
|
6221
6370
|
try {
|
|
6222
6371
|
const sproutedDir = entry.dir ?? mindDir(name);
|
|
6223
6372
|
if (setupDefaultDreaming(sproutedDir).schedulesChanged) {
|
|
6224
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6373
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-TNBN54ZK.js");
|
|
6225
6374
|
getScheduler2().loadSchedules(name, sproutedDir);
|
|
6226
6375
|
}
|
|
6227
6376
|
} catch (err) {
|
|
@@ -6231,7 +6380,7 @@ ${user.trimEnd()}
|
|
|
6231
6380
|
const spiritName = getSpiritName();
|
|
6232
6381
|
const spiritEntry = await findMind(spiritName);
|
|
6233
6382
|
if (spiritEntry) {
|
|
6234
|
-
const { firstWeekSchedules, spiritDir } = await import("./spirit-
|
|
6383
|
+
const { firstWeekSchedules, spiritDir } = await import("./spirit-25JVAL3M.js");
|
|
6235
6384
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
6236
6385
|
const spiritConfig = readVoluteConfig(sDir);
|
|
6237
6386
|
if (spiritConfig) {
|
|
@@ -6245,7 +6394,7 @@ ${user.trimEnd()}
|
|
|
6245
6394
|
spiritConfig.schedules = schedules;
|
|
6246
6395
|
writeVoluteConfig(sDir, spiritConfig);
|
|
6247
6396
|
try {
|
|
6248
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6397
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-TNBN54ZK.js");
|
|
6249
6398
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
6250
6399
|
} catch (err) {
|
|
6251
6400
|
logger_default.warn(
|
|
@@ -6276,17 +6425,17 @@ ${user.trimEnd()}
|
|
|
6276
6425
|
const variants = await findVariants(name);
|
|
6277
6426
|
for (const s of variants) {
|
|
6278
6427
|
if (s.dir) {
|
|
6279
|
-
await cleanupVariant(s.name, dir, s.dir, { stop: true });
|
|
6428
|
+
await cleanupVariant(s.name, name, dir, s.dir, { stop: true });
|
|
6280
6429
|
}
|
|
6281
6430
|
}
|
|
6282
6431
|
await removeMind(name);
|
|
6283
6432
|
await deleteMindUser2(name);
|
|
6284
6433
|
invalidateMindUserCache(name);
|
|
6285
6434
|
const state = stateDir(name);
|
|
6286
|
-
if (
|
|
6435
|
+
if (existsSync8(state)) {
|
|
6287
6436
|
rmSync3(state, { recursive: true, force: true });
|
|
6288
6437
|
}
|
|
6289
|
-
if (force &&
|
|
6438
|
+
if (force && existsSync8(dir)) {
|
|
6290
6439
|
rmSync3(dir, { recursive: true, force: true });
|
|
6291
6440
|
deleteMindUser(name);
|
|
6292
6441
|
}
|
|
@@ -6301,7 +6450,7 @@ ${user.trimEnd()}
|
|
|
6301
6450
|
const entry = await findMind(mindName);
|
|
6302
6451
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6303
6452
|
const dir = mindDir(mindName);
|
|
6304
|
-
if (!
|
|
6453
|
+
if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6305
6454
|
let body = {};
|
|
6306
6455
|
try {
|
|
6307
6456
|
body = await c.req.json();
|
|
@@ -6314,21 +6463,21 @@ ${user.trimEnd()}
|
|
|
6314
6463
|
}
|
|
6315
6464
|
const UPGRADE_BRANCH = "upgrade";
|
|
6316
6465
|
const upgradeVariantName = `${mindName}-upgrade`;
|
|
6317
|
-
const worktreeDir =
|
|
6466
|
+
const worktreeDir = resolve12(dir, ".variants", UPGRADE_BRANCH);
|
|
6318
6467
|
if (body.abort) {
|
|
6319
|
-
if (!
|
|
6468
|
+
if (!existsSync8(worktreeDir)) {
|
|
6320
6469
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
6321
6470
|
}
|
|
6322
6471
|
try {
|
|
6323
6472
|
try {
|
|
6324
|
-
const gitDirContent = readFileSync9(
|
|
6473
|
+
const gitDirContent = readFileSync9(resolve12(worktreeDir, ".git"), "utf-8").trim();
|
|
6325
6474
|
const gitDir = gitDirContent.replace("gitdir: ", "");
|
|
6326
|
-
if (
|
|
6475
|
+
if (existsSync8(resolve12(gitDir, "MERGE_HEAD"))) {
|
|
6327
6476
|
await gitExec(["merge", "--abort"], { cwd: worktreeDir });
|
|
6328
6477
|
}
|
|
6329
6478
|
} catch {
|
|
6330
6479
|
}
|
|
6331
|
-
await cleanupVariant(upgradeVariantName, dir, worktreeDir, { stop: true });
|
|
6480
|
+
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir, { stop: true });
|
|
6332
6481
|
try {
|
|
6333
6482
|
await gitExec(["branch", "-D", UPGRADE_BRANCH], { cwd: dir });
|
|
6334
6483
|
} catch {
|
|
@@ -6342,7 +6491,7 @@ ${user.trimEnd()}
|
|
|
6342
6491
|
}
|
|
6343
6492
|
}
|
|
6344
6493
|
if (body.continue) {
|
|
6345
|
-
if (!
|
|
6494
|
+
if (!existsSync8(worktreeDir)) {
|
|
6346
6495
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
6347
6496
|
}
|
|
6348
6497
|
const status = await gitExec(["status", "--porcelain"], { cwd: worktreeDir });
|
|
@@ -6392,9 +6541,9 @@ ${user.trimEnd()}
|
|
|
6392
6541
|
}
|
|
6393
6542
|
}
|
|
6394
6543
|
if (body.accept) {
|
|
6395
|
-
if (
|
|
6544
|
+
if (existsSync8(worktreeDir)) {
|
|
6396
6545
|
try {
|
|
6397
|
-
await cleanupVariant(upgradeVariantName, dir, worktreeDir, { stop: true });
|
|
6546
|
+
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir, { stop: true });
|
|
6398
6547
|
} catch (err) {
|
|
6399
6548
|
logger_default.warn(`failed to clean up legacy upgrade variant for ${mindName}`, logger_default.errorData(err));
|
|
6400
6549
|
}
|
|
@@ -6407,7 +6556,7 @@ ${user.trimEnd()}
|
|
|
6407
6556
|
}
|
|
6408
6557
|
if (body.diff) {
|
|
6409
6558
|
try {
|
|
6410
|
-
if (!
|
|
6559
|
+
if (!existsSync8(resolve12(dir, ".git"))) {
|
|
6411
6560
|
return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
|
|
6412
6561
|
}
|
|
6413
6562
|
await updateTemplateBranch(dir, template, mindName);
|
|
@@ -6425,22 +6574,22 @@ ${user.trimEnd()}
|
|
|
6425
6574
|
);
|
|
6426
6575
|
}
|
|
6427
6576
|
}
|
|
6428
|
-
if (
|
|
6577
|
+
if (existsSync8(worktreeDir)) {
|
|
6429
6578
|
return c.json(
|
|
6430
6579
|
{ error: "Upgrade variant already exists. Use continue or delete it first." },
|
|
6431
6580
|
409
|
|
6432
6581
|
);
|
|
6433
6582
|
}
|
|
6434
|
-
if (!
|
|
6583
|
+
if (!existsSync8(resolve12(dir, ".git"))) {
|
|
6435
6584
|
try {
|
|
6436
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
6585
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve12(dir, "home") } : void 0;
|
|
6437
6586
|
await gitExec(["init"], { cwd: dir, mindName, env });
|
|
6438
6587
|
await configureGitIdentity(mindName, { cwd: dir, mindName, env });
|
|
6439
6588
|
await gitExec(["add", "-A"], { cwd: dir, mindName, env });
|
|
6440
6589
|
await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
|
|
6441
6590
|
await chownMindDir(dir, mindName);
|
|
6442
6591
|
} catch (err) {
|
|
6443
|
-
rmSync3(
|
|
6592
|
+
rmSync3(resolve12(dir, ".git"), { recursive: true, force: true });
|
|
6444
6593
|
return c.json(
|
|
6445
6594
|
{
|
|
6446
6595
|
error: `Git initialization failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -6455,8 +6604,8 @@ ${user.trimEnd()}
|
|
|
6455
6604
|
} catch {
|
|
6456
6605
|
}
|
|
6457
6606
|
await updateTemplateBranch(dir, template, mindName);
|
|
6458
|
-
const parentDir =
|
|
6459
|
-
if (!
|
|
6607
|
+
const parentDir = resolve12(dir, ".variants");
|
|
6608
|
+
if (!existsSync8(parentDir)) {
|
|
6460
6609
|
mkdirSync6(parentDir, { recursive: true });
|
|
6461
6610
|
}
|
|
6462
6611
|
await gitExec(["worktree", "add", "-b", UPGRADE_BRANCH, worktreeDir], { cwd: dir });
|
|
@@ -6519,7 +6668,7 @@ ${user.trimEnd()}
|
|
|
6519
6668
|
return c.json(result);
|
|
6520
6669
|
} catch (err) {
|
|
6521
6670
|
try {
|
|
6522
|
-
await cleanupVariant(upgradeVariantName, dir, worktreeDir);
|
|
6671
|
+
await cleanupVariant(upgradeVariantName, mindName, dir, worktreeDir);
|
|
6523
6672
|
} catch (cleanupErr) {
|
|
6524
6673
|
logger_default.warn(`cleanup failed after upgrade error for ${mindName}`, logger_default.errorData(cleanupErr));
|
|
6525
6674
|
}
|
|
@@ -6589,11 +6738,11 @@ ${user.trimEnd()}
|
|
|
6589
6738
|
const entry = await findMind(name);
|
|
6590
6739
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6591
6740
|
const dir = entry.dir ?? mindDir(name);
|
|
6592
|
-
if (!
|
|
6741
|
+
if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6593
6742
|
let config2 = readVoluteConfig(dir);
|
|
6594
6743
|
if (!config2 && entry.template === "pi") {
|
|
6595
|
-
const piConfigPath =
|
|
6596
|
-
if (
|
|
6744
|
+
const piConfigPath = resolve12(dir, "home/.config/config.json");
|
|
6745
|
+
if (existsSync8(piConfigPath)) {
|
|
6597
6746
|
try {
|
|
6598
6747
|
config2 = JSON.parse(readFileSync9(piConfigPath, "utf-8"));
|
|
6599
6748
|
} catch {
|
|
@@ -6601,8 +6750,8 @@ ${user.trimEnd()}
|
|
|
6601
6750
|
}
|
|
6602
6751
|
}
|
|
6603
6752
|
let templateConfig = {};
|
|
6604
|
-
const configJsonPath =
|
|
6605
|
-
if (
|
|
6753
|
+
const configJsonPath = resolve12(dir, "home/.config/config.json");
|
|
6754
|
+
if (existsSync8(configJsonPath)) {
|
|
6606
6755
|
try {
|
|
6607
6756
|
templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
|
|
6608
6757
|
} catch {
|
|
@@ -6644,7 +6793,7 @@ ${user.trimEnd()}
|
|
|
6644
6793
|
const entry = await findMind(name);
|
|
6645
6794
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6646
6795
|
const dir = entry.dir ?? mindDir(name);
|
|
6647
|
-
if (!
|
|
6796
|
+
if (!existsSync8(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
6648
6797
|
const body = c.req.valid("json");
|
|
6649
6798
|
const existing = readVoluteConfig(dir) ?? {};
|
|
6650
6799
|
if (body.model !== void 0) existing.model = body.model;
|
|
@@ -6670,14 +6819,14 @@ ${user.trimEnd()}
|
|
|
6670
6819
|
}
|
|
6671
6820
|
writeVoluteConfig(dir, existing);
|
|
6672
6821
|
if (body.unescapeNewlines !== void 0) {
|
|
6673
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
6822
|
+
const { clearEchoTextCache } = await import("./echo-text-6ANI5HHN.js");
|
|
6674
6823
|
clearEchoTextCache(name);
|
|
6675
6824
|
}
|
|
6676
6825
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.compaction !== void 0;
|
|
6677
6826
|
if (needsConfigJson) {
|
|
6678
|
-
const configJsonPath =
|
|
6827
|
+
const configJsonPath = resolve12(dir, "home/.config/config.json");
|
|
6679
6828
|
let templateConfig = {};
|
|
6680
|
-
if (
|
|
6829
|
+
if (existsSync8(configJsonPath)) {
|
|
6681
6830
|
try {
|
|
6682
6831
|
templateConfig = JSON.parse(readFileSync9(configJsonPath, "utf-8"));
|
|
6683
6832
|
} catch {
|
|
@@ -6707,7 +6856,7 @@ ${user.trimEnd()}
|
|
|
6707
6856
|
}
|
|
6708
6857
|
if (entry.mindType === "spirit" && body.model !== void 0) {
|
|
6709
6858
|
try {
|
|
6710
|
-
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-
|
|
6859
|
+
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-WZSXHHRJ.js");
|
|
6711
6860
|
const globalConfig = readGlobalConfig2();
|
|
6712
6861
|
globalConfig.spiritModel = body.model;
|
|
6713
6862
|
writeGlobalConfig2(globalConfig);
|
|
@@ -6750,7 +6899,7 @@ ${user.trimEnd()}
|
|
|
6750
6899
|
if (!body.systemPrompt || !body.message) {
|
|
6751
6900
|
return c.json({ error: "systemPrompt and message required" }, 400);
|
|
6752
6901
|
}
|
|
6753
|
-
const { aiComplete: aiCompleteFn, isAiConfigured: isAiConfigured2 } = await import("./ai-service-
|
|
6902
|
+
const { aiComplete: aiCompleteFn, isAiConfigured: isAiConfigured2 } = await import("./ai-service-YW5SWCSB.js");
|
|
6754
6903
|
if (!isAiConfigured2()) {
|
|
6755
6904
|
return c.json({ error: "AI service not configured" }, 503);
|
|
6756
6905
|
}
|
|
@@ -7444,7 +7593,7 @@ var app15 = new Hono18().get("/:name/clock/status", requireSelf(), async (c) =>
|
|
|
7444
7593
|
const entry = await findMind(name);
|
|
7445
7594
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
7446
7595
|
const body = await c.req.text();
|
|
7447
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
7596
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-ZPSH63QX.js");
|
|
7448
7597
|
const { id, delivered } = await deliverEvent2(name, {
|
|
7449
7598
|
type: "webhook",
|
|
7450
7599
|
body,
|
|
@@ -7462,14 +7611,14 @@ var schedules_default = app15;
|
|
|
7462
7611
|
// packages/daemon/src/web/api/setup.ts
|
|
7463
7612
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
7464
7613
|
import { homedir as homedir2 } from "os";
|
|
7465
|
-
import { resolve as
|
|
7614
|
+
import { resolve as resolve13 } from "path";
|
|
7466
7615
|
import { Hono as Hono19 } from "hono";
|
|
7467
7616
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
7468
7617
|
var DEFAULT_API_URL2 = "https://volute.systems";
|
|
7469
7618
|
var setup = new Hono19();
|
|
7470
7619
|
function writeSetupConfig(systemName, description) {
|
|
7471
|
-
const configHome = process.env.VOLUTE_HOME ??
|
|
7472
|
-
const mindsDir =
|
|
7620
|
+
const configHome = process.env.VOLUTE_HOME ?? resolve13(homedir2(), ".volute");
|
|
7621
|
+
const mindsDir = resolve13(configHome, "minds");
|
|
7473
7622
|
mkdirSync7(configHome, { recursive: true });
|
|
7474
7623
|
mkdirSync7(mindsDir, { recursive: true });
|
|
7475
7624
|
const existingConfig = readGlobalConfig();
|
|
@@ -7503,11 +7652,11 @@ setup.get("/status", async (c) => {
|
|
|
7503
7652
|
let hasAccount = false;
|
|
7504
7653
|
if (hasSystem) {
|
|
7505
7654
|
try {
|
|
7506
|
-
const { listUsersByType: listUsersByType2 } = await import("./auth-
|
|
7655
|
+
const { listUsersByType: listUsersByType2 } = await import("./auth-X6EMNEGB.js");
|
|
7507
7656
|
const brains = await listUsersByType2("human");
|
|
7508
7657
|
hasAccount = brains.length > 0;
|
|
7509
7658
|
} catch (err) {
|
|
7510
|
-
logger_default.
|
|
7659
|
+
logger_default.error("could not check for existing accounts during setup status", logger_default.errorData(err));
|
|
7511
7660
|
}
|
|
7512
7661
|
}
|
|
7513
7662
|
return c.json({
|
|
@@ -7715,7 +7864,7 @@ setup.post("/account", async (c) => {
|
|
|
7715
7864
|
}
|
|
7716
7865
|
}
|
|
7717
7866
|
try {
|
|
7718
|
-
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-
|
|
7867
|
+
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-X6EMNEGB.js");
|
|
7719
7868
|
const user = await createUser2(body.username.trim(), body.password);
|
|
7720
7869
|
if (body.displayName?.trim()) {
|
|
7721
7870
|
await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
|
|
@@ -7761,7 +7910,7 @@ setup.post("/models", async (c) => {
|
|
|
7761
7910
|
return c.json({ error: "Spirit model is required" }, 400);
|
|
7762
7911
|
}
|
|
7763
7912
|
try {
|
|
7764
|
-
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-
|
|
7913
|
+
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-YW5SWCSB.js");
|
|
7765
7914
|
setEnabledModels3(body.models);
|
|
7766
7915
|
const config2 = readGlobalConfig();
|
|
7767
7916
|
config2.spiritModel = body.spiritModel.trim();
|
|
@@ -7808,15 +7957,15 @@ setup.post("/complete", async (c) => {
|
|
|
7808
7957
|
return c.json({ error: "Setup already complete" }, 400);
|
|
7809
7958
|
}
|
|
7810
7959
|
try {
|
|
7811
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
7812
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
7960
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-25JVAL3M.js");
|
|
7961
|
+
const { startSpiritFull } = await import("./mind-service-DZCUUC7J.js");
|
|
7813
7962
|
await ensureSpiritProject();
|
|
7814
7963
|
await syncSpiritTemplate();
|
|
7815
7964
|
const warnings = [];
|
|
7816
7965
|
const config2 = readGlobalConfig();
|
|
7817
7966
|
if (config2.setup?.service && config2.setup?.type === "local") {
|
|
7818
7967
|
try {
|
|
7819
|
-
const { installUserService } = await import("./service-install-
|
|
7968
|
+
const { installUserService } = await import("./service-install-2EWD7KXD.js");
|
|
7820
7969
|
const installed = await installUserService(config2.port, config2.hostname);
|
|
7821
7970
|
if (!installed) {
|
|
7822
7971
|
warnings.push("Service installation is not supported on this platform.");
|
|
@@ -7846,8 +7995,8 @@ setup.post("/complete", async (c) => {
|
|
|
7846
7995
|
}
|
|
7847
7996
|
let spiritConversationId;
|
|
7848
7997
|
try {
|
|
7849
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-
|
|
7850
|
-
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-
|
|
7998
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-X6EMNEGB.js");
|
|
7999
|
+
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-ZL6PHROD.js");
|
|
7851
8000
|
const spiritUser = await getOrCreateMindUser2(spiritName);
|
|
7852
8001
|
const brains = await listUsersByType2("human");
|
|
7853
8002
|
const admin2 = brains.find((u) => u.role === "admin");
|
|
@@ -7869,8 +8018,8 @@ setup.post("/complete", async (c) => {
|
|
|
7869
8018
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
7870
8019
|
if (spiritConversationId && spiritStarted) {
|
|
7871
8020
|
try {
|
|
7872
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
7873
|
-
const { listUsersByType: listUsers2 } = await import("./auth-
|
|
8021
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-JHMAJ2GU.js");
|
|
8022
|
+
const { listUsersByType: listUsers2 } = await import("./auth-X6EMNEGB.js");
|
|
7874
8023
|
const admins = await listUsers2("human");
|
|
7875
8024
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
7876
8025
|
if (admin2) {
|
|
@@ -7911,9 +8060,9 @@ setup.post("/complete", async (c) => {
|
|
|
7911
8060
|
var setup_default = setup;
|
|
7912
8061
|
|
|
7913
8062
|
// packages/daemon/src/web/api/skills.ts
|
|
7914
|
-
import { existsSync as
|
|
8063
|
+
import { existsSync as existsSync9, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync4 } from "fs";
|
|
7915
8064
|
import { tmpdir } from "os";
|
|
7916
|
-
import { join, resolve as
|
|
8065
|
+
import { join, resolve as resolve14 } from "path";
|
|
7917
8066
|
import AdmZip from "adm-zip";
|
|
7918
8067
|
import { Hono as Hono20 } from "hono";
|
|
7919
8068
|
var app16 = new Hono20().get("/", async (c) => {
|
|
@@ -7989,19 +8138,19 @@ var app16 = new Hono20().get("/", async (c) => {
|
|
|
7989
8138
|
try {
|
|
7990
8139
|
const zip = new AdmZip(buffer);
|
|
7991
8140
|
for (const entry of zip.getEntries()) {
|
|
7992
|
-
const target =
|
|
8141
|
+
const target = resolve14(tmpDir, entry.entryName);
|
|
7993
8142
|
if (!target.startsWith(tmpDir)) {
|
|
7994
8143
|
return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
|
|
7995
8144
|
}
|
|
7996
8145
|
}
|
|
7997
8146
|
zip.extractAllTo(tmpDir, true);
|
|
7998
8147
|
let skillDir = null;
|
|
7999
|
-
if (
|
|
8148
|
+
if (existsSync9(join(tmpDir, "SKILL.md"))) {
|
|
8000
8149
|
skillDir = tmpDir;
|
|
8001
8150
|
} else {
|
|
8002
8151
|
const entries = readdirSync3(tmpDir, { withFileTypes: true }).filter((e) => e.isDirectory());
|
|
8003
8152
|
for (const entry of entries) {
|
|
8004
|
-
if (
|
|
8153
|
+
if (existsSync9(join(tmpDir, entry.name, "SKILL.md"))) {
|
|
8005
8154
|
skillDir = join(tmpDir, entry.name);
|
|
8006
8155
|
break;
|
|
8007
8156
|
}
|
|
@@ -8363,8 +8512,8 @@ var app20 = new Hono24().use("*", authMiddleware).get("/", async (c) => {
|
|
|
8363
8512
|
});
|
|
8364
8513
|
}, 15e3);
|
|
8365
8514
|
cleanups.push(() => clearInterval(keepAlive));
|
|
8366
|
-
await new Promise((
|
|
8367
|
-
stream.onAbort(() =>
|
|
8515
|
+
await new Promise((resolve20) => {
|
|
8516
|
+
stream.onAbort(() => resolve20());
|
|
8368
8517
|
});
|
|
8369
8518
|
} finally {
|
|
8370
8519
|
for (const cleanup of cleanups) {
|
|
@@ -8382,7 +8531,7 @@ var events_default = app20;
|
|
|
8382
8531
|
import { Hono as Hono25 } from "hono";
|
|
8383
8532
|
|
|
8384
8533
|
// 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";
|
|
8534
|
+
import { and as and6, desc as desc5, eq as eq8, gte as gte3, inArray as inArray3, ne, sql as sql5 } from "drizzle-orm";
|
|
8386
8535
|
var BURST_GAP_MS = 45 * 6e4;
|
|
8387
8536
|
var FEED_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
8388
8537
|
var LIFECYCLE_TYPES = [
|
|
@@ -8459,7 +8608,13 @@ async function getChatFeedEvents(opts) {
|
|
|
8459
8608
|
content: messages.content,
|
|
8460
8609
|
created_at: messages.created_at,
|
|
8461
8610
|
conversation_type: conversations.type
|
|
8462
|
-
}).from(messages).innerJoin(conversations, eq8(conversations.id, messages.conversation_id)).where(
|
|
8611
|
+
}).from(messages).innerJoin(conversations, eq8(conversations.id, messages.conversation_id)).where(
|
|
8612
|
+
and6(
|
|
8613
|
+
gte3(messages.created_at, cutoff),
|
|
8614
|
+
eq8(conversations.private, 0),
|
|
8615
|
+
ne(messages.role, "event")
|
|
8616
|
+
)
|
|
8617
|
+
).orderBy(desc5(messages.id)).limit(5e3);
|
|
8463
8618
|
const ascending = rows.reverse();
|
|
8464
8619
|
const bursts = splitIntoBursts(ascending);
|
|
8465
8620
|
bursts.sort((a, b) => {
|
|
@@ -8639,23 +8794,23 @@ var app21 = new Hono25().use("*", authMiddleware).get("/", async (c) => {
|
|
|
8639
8794
|
var feed_default = app21;
|
|
8640
8795
|
|
|
8641
8796
|
// packages/daemon/src/web/api/variants.ts
|
|
8642
|
-
import { existsSync as
|
|
8643
|
-
import { resolve as
|
|
8797
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
8798
|
+
import { resolve as resolve17 } from "path";
|
|
8644
8799
|
import { Hono as Hono26 } from "hono";
|
|
8645
8800
|
|
|
8646
8801
|
// packages/daemon/src/lib/mind/farewell.ts
|
|
8647
|
-
import { existsSync as
|
|
8648
|
-
import { resolve as
|
|
8802
|
+
import { existsSync as existsSync10, readFileSync as readFileSync10, rmSync as rmSync5 } from "fs";
|
|
8803
|
+
import { resolve as resolve15 } from "path";
|
|
8649
8804
|
var flog = logger_default.child("farewell");
|
|
8650
8805
|
var FAREWELL_RELPATH = ".mind/farewell.md";
|
|
8651
8806
|
var FAREWELL_MIND_PATH = "../.mind/farewell.md";
|
|
8652
8807
|
var FAREWELL_TIMEOUT_MS = 12e4;
|
|
8653
8808
|
function farewellPath(variantDir) {
|
|
8654
|
-
return
|
|
8809
|
+
return resolve15(variantDir, FAREWELL_RELPATH);
|
|
8655
8810
|
}
|
|
8656
8811
|
function readFarewell(variantDir) {
|
|
8657
8812
|
const path = farewellPath(variantDir);
|
|
8658
|
-
if (!
|
|
8813
|
+
if (!existsSync10(path)) return void 0;
|
|
8659
8814
|
try {
|
|
8660
8815
|
const text = readFileSync10(path, "utf-8").trim();
|
|
8661
8816
|
return text || void 0;
|
|
@@ -8678,7 +8833,7 @@ function waitForFarewell(name, variantDir, timeoutMs) {
|
|
|
8678
8833
|
const unsub = subscribe((event) => {
|
|
8679
8834
|
if (event.mind !== name) return;
|
|
8680
8835
|
if (event.type !== "mind_done" && event.type !== "mind_idle") return;
|
|
8681
|
-
if (
|
|
8836
|
+
if (existsSync10(farewellPath(variantDir))) cleanup();
|
|
8682
8837
|
});
|
|
8683
8838
|
return { done, cancel: cleanup };
|
|
8684
8839
|
}
|
|
@@ -8712,7 +8867,7 @@ async function runFarewellTurn(opts) {
|
|
|
8712
8867
|
// packages/daemon/src/lib/mind/spawn-server.ts
|
|
8713
8868
|
import { spawn as spawn4 } from "child_process";
|
|
8714
8869
|
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
|
|
8715
|
-
import { resolve as
|
|
8870
|
+
import { resolve as resolve16 } from "path";
|
|
8716
8871
|
async function spawnServer(cwd, port, options) {
|
|
8717
8872
|
let cmd = process.env.VOLUTE_NODE_PATH ?? process.execPath;
|
|
8718
8873
|
let args = ["--import", "tsx", "src/server.ts", "--port", String(port)];
|
|
@@ -8733,31 +8888,31 @@ function spawnAttached(cmd, args, cwd) {
|
|
|
8733
8888
|
cwd,
|
|
8734
8889
|
stdio: ["ignore", "pipe", "pipe"]
|
|
8735
8890
|
});
|
|
8736
|
-
return new Promise((
|
|
8737
|
-
const timeout = setTimeout(() =>
|
|
8891
|
+
return new Promise((resolve20) => {
|
|
8892
|
+
const timeout = setTimeout(() => resolve20(null), 3e4);
|
|
8738
8893
|
function checkOutput(data) {
|
|
8739
8894
|
const match = data.toString().match(/listening on :(\d+)/);
|
|
8740
8895
|
if (match) {
|
|
8741
8896
|
clearTimeout(timeout);
|
|
8742
|
-
|
|
8897
|
+
resolve20({ child, actualPort: parseInt(match[1], 10) });
|
|
8743
8898
|
}
|
|
8744
8899
|
}
|
|
8745
8900
|
child.stdout?.on("data", checkOutput);
|
|
8746
8901
|
child.stderr?.on("data", checkOutput);
|
|
8747
8902
|
child.on("error", () => {
|
|
8748
8903
|
clearTimeout(timeout);
|
|
8749
|
-
|
|
8904
|
+
resolve20(null);
|
|
8750
8905
|
});
|
|
8751
8906
|
child.on("exit", () => {
|
|
8752
8907
|
clearTimeout(timeout);
|
|
8753
|
-
|
|
8908
|
+
resolve20(null);
|
|
8754
8909
|
});
|
|
8755
8910
|
});
|
|
8756
8911
|
}
|
|
8757
8912
|
function spawnDetached(cmd, args, cwd, logDir) {
|
|
8758
|
-
const logsDir = logDir ??
|
|
8913
|
+
const logsDir = logDir ?? resolve16(cwd, ".mind", "logs");
|
|
8759
8914
|
mkdirSync8(logsDir, { recursive: true });
|
|
8760
|
-
const logPath =
|
|
8915
|
+
const logPath = resolve16(logsDir, "mind.log");
|
|
8761
8916
|
let startOffset = 0;
|
|
8762
8917
|
try {
|
|
8763
8918
|
startOffset = statSync3(logPath).size;
|
|
@@ -8898,11 +9053,11 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
8898
9053
|
return c.json({ error: `Name already in use: ${variantName}` }, 409);
|
|
8899
9054
|
}
|
|
8900
9055
|
const projectRoot = entry.dir ?? mindDir(mindName);
|
|
8901
|
-
const variantDir =
|
|
8902
|
-
if (
|
|
9056
|
+
const variantDir = resolve17(projectRoot, ".variants", variantName);
|
|
9057
|
+
if (existsSync11(variantDir)) {
|
|
8903
9058
|
return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
|
|
8904
9059
|
}
|
|
8905
|
-
mkdirSync9(
|
|
9060
|
+
mkdirSync9(resolve17(projectRoot, ".variants"), { recursive: true });
|
|
8906
9061
|
try {
|
|
8907
9062
|
await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
|
|
8908
9063
|
} catch (e) {
|
|
@@ -8921,18 +9076,10 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
8921
9076
|
}
|
|
8922
9077
|
const rollbackSplit = async () => {
|
|
8923
9078
|
try {
|
|
8924
|
-
await cleanupVariant(variantName, projectRoot, variantDir, { stop: true });
|
|
9079
|
+
await cleanupVariant(variantName, mindName, projectRoot, variantDir, { stop: true });
|
|
8925
9080
|
} catch (err2) {
|
|
8926
9081
|
logger_default.warn(`failed to roll back split of ${variantName}`, logger_default.errorData(err2));
|
|
8927
9082
|
}
|
|
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
9083
|
};
|
|
8937
9084
|
try {
|
|
8938
9085
|
await chownMindDir(projectRoot, mindName);
|
|
@@ -8946,7 +9093,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
8946
9093
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
8947
9094
|
await exec(cmd, args, {
|
|
8948
9095
|
cwd: variantDir,
|
|
8949
|
-
env: { ...process.env, HOME:
|
|
9096
|
+
env: { ...process.env, HOME: resolve17(variantDir, "home") }
|
|
8950
9097
|
});
|
|
8951
9098
|
} else {
|
|
8952
9099
|
await exec("npm", ["install"], { cwd: variantDir });
|
|
@@ -8957,7 +9104,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
8957
9104
|
return c.json({ error: `npm install failed: ${msg}` }, 500);
|
|
8958
9105
|
}
|
|
8959
9106
|
if (body.soul) {
|
|
8960
|
-
writeFileSync9(
|
|
9107
|
+
writeFileSync9(resolve17(variantDir, "home/SOUL.md"), body.soul);
|
|
8961
9108
|
}
|
|
8962
9109
|
const variantPort = body.port ?? await nextPort();
|
|
8963
9110
|
try {
|
|
@@ -9040,7 +9187,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9040
9187
|
logger_default.warn(`farewell turn failed for ${variantName}`, logger_default.errorData(err));
|
|
9041
9188
|
}
|
|
9042
9189
|
try {
|
|
9043
|
-
if (
|
|
9190
|
+
if (existsSync11(variantEntry.dir)) {
|
|
9044
9191
|
const status = (await gitExec(["status", "--porcelain"], { cwd: variantEntry.dir })).trim();
|
|
9045
9192
|
if (status) {
|
|
9046
9193
|
try {
|
|
@@ -9098,12 +9245,12 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9098
9245
|
{ conflicts: err.conflicts }
|
|
9099
9246
|
);
|
|
9100
9247
|
}
|
|
9101
|
-
await cleanupVariant(variantName, projectRoot, variantEntry.dir, { stop: true });
|
|
9248
|
+
await cleanupVariant(variantName, mindName, projectRoot, variantEntry.dir, { stop: true });
|
|
9102
9249
|
await chownMindDir(projectRoot, mindName);
|
|
9103
9250
|
if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
|
|
9104
9251
|
try {
|
|
9105
|
-
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-
|
|
9106
|
-
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-
|
|
9252
|
+
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-YKWMVYMM.js");
|
|
9253
|
+
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-TRC2HJXR.js");
|
|
9107
9254
|
const tmpl = parentEntry.template ?? "claude";
|
|
9108
9255
|
await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
|
|
9109
9256
|
} catch (err) {
|
|
@@ -9116,7 +9263,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9116
9263
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
9117
9264
|
await exec(cmd, args, {
|
|
9118
9265
|
cwd: projectRoot,
|
|
9119
|
-
env: { ...process.env, HOME:
|
|
9266
|
+
env: { ...process.env, HOME: resolve17(projectRoot, "home") }
|
|
9120
9267
|
});
|
|
9121
9268
|
} else {
|
|
9122
9269
|
await exec("npm", ["install"], { cwd: projectRoot });
|
|
@@ -9164,7 +9311,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9164
9311
|
}
|
|
9165
9312
|
if (!variantEntry.dir) return c.json({ error: `Variant ${variantName} has no directory` }, 500);
|
|
9166
9313
|
const projectRoot = parentEntry.dir ?? mindDir(mindName);
|
|
9167
|
-
await cleanupVariant(variantName, projectRoot, variantEntry.dir, { stop: true });
|
|
9314
|
+
await cleanupVariant(variantName, mindName, projectRoot, variantEntry.dir, { stop: true });
|
|
9168
9315
|
return c.json({ ok: true });
|
|
9169
9316
|
});
|
|
9170
9317
|
var variants_default = app22;
|
|
@@ -9603,11 +9750,11 @@ var app24 = new Hono28().get("/:name/conversations/:id/events", async (c) => {
|
|
|
9603
9750
|
if (!stream.aborted) console.error("[chat] SSE ping error:", err);
|
|
9604
9751
|
});
|
|
9605
9752
|
}, 15e3);
|
|
9606
|
-
await new Promise((
|
|
9753
|
+
await new Promise((resolve20) => {
|
|
9607
9754
|
stream.onAbort(() => {
|
|
9608
9755
|
unsubscribe();
|
|
9609
9756
|
clearInterval(keepAlive);
|
|
9610
|
-
|
|
9757
|
+
resolve20();
|
|
9611
9758
|
});
|
|
9612
9759
|
});
|
|
9613
9760
|
});
|
|
@@ -9824,10 +9971,10 @@ app26.route("/api/conversations", conversations_default);
|
|
|
9824
9971
|
var app_default = app26;
|
|
9825
9972
|
|
|
9826
9973
|
// packages/daemon/src/web/server.ts
|
|
9827
|
-
import { existsSync as
|
|
9974
|
+
import { existsSync as existsSync12 } from "fs";
|
|
9828
9975
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
9829
9976
|
import { createServer as createHttpsServer } from "https";
|
|
9830
|
-
import { dirname as dirname3, extname as extname3, resolve as
|
|
9977
|
+
import { dirname as dirname3, extname as extname3, resolve as resolve18 } from "path";
|
|
9831
9978
|
import { serve } from "@hono/node-server";
|
|
9832
9979
|
var MIME_TYPES2 = {
|
|
9833
9980
|
".html": "text/html",
|
|
@@ -9846,8 +9993,8 @@ async function startServer({
|
|
|
9846
9993
|
let assetsDir = "";
|
|
9847
9994
|
let searchDir = dirname3(new URL(import.meta.url).pathname);
|
|
9848
9995
|
for (let i = 0; i < 5; i++) {
|
|
9849
|
-
const candidate =
|
|
9850
|
-
if (
|
|
9996
|
+
const candidate = resolve18(searchDir, "dist", "web-assets");
|
|
9997
|
+
if (existsSync12(candidate)) {
|
|
9851
9998
|
assetsDir = candidate;
|
|
9852
9999
|
break;
|
|
9853
10000
|
}
|
|
@@ -9857,7 +10004,7 @@ async function startServer({
|
|
|
9857
10004
|
app_default.get("*", async (c) => {
|
|
9858
10005
|
const urlPath = new URL(c.req.url).pathname;
|
|
9859
10006
|
if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
|
|
9860
|
-
const filePath =
|
|
10007
|
+
const filePath = resolve18(assetsDir, urlPath.slice(1));
|
|
9861
10008
|
if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
|
|
9862
10009
|
const s = await stat2(filePath).catch(() => null);
|
|
9863
10010
|
if (s?.isFile()) {
|
|
@@ -9870,7 +10017,7 @@ async function startServer({
|
|
|
9870
10017
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
9871
10018
|
return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
|
|
9872
10019
|
}
|
|
9873
|
-
const indexPath =
|
|
10020
|
+
const indexPath = resolve18(assetsDir, "index.html");
|
|
9874
10021
|
const indexStat = await stat2(indexPath).catch(() => null);
|
|
9875
10022
|
if (indexStat?.isFile()) {
|
|
9876
10023
|
const body = await readFile2(indexPath, "utf-8");
|
|
@@ -9887,10 +10034,10 @@ async function startServer({
|
|
|
9887
10034
|
createServer: createHttpsServer,
|
|
9888
10035
|
serverOptions: { key: tls.key, cert: tls.cert }
|
|
9889
10036
|
});
|
|
9890
|
-
await new Promise((
|
|
10037
|
+
await new Promise((resolve20, reject) => {
|
|
9891
10038
|
server2.on("listening", () => {
|
|
9892
10039
|
logger_default.info("Volute UI running (https)", { hostname, port });
|
|
9893
|
-
|
|
10040
|
+
resolve20();
|
|
9894
10041
|
});
|
|
9895
10042
|
server2.on("error", (err) => {
|
|
9896
10043
|
reject(err);
|
|
@@ -9898,13 +10045,13 @@ async function startServer({
|
|
|
9898
10045
|
});
|
|
9899
10046
|
const internalPort = port + 1;
|
|
9900
10047
|
const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
|
|
9901
|
-
await new Promise((
|
|
10048
|
+
await new Promise((resolve20, reject) => {
|
|
9902
10049
|
internalServer.on("listening", () => {
|
|
9903
10050
|
logger_default.info("Volute API running (http, internal)", {
|
|
9904
10051
|
hostname: "127.0.0.1",
|
|
9905
10052
|
port: internalPort
|
|
9906
10053
|
});
|
|
9907
|
-
|
|
10054
|
+
resolve20();
|
|
9908
10055
|
});
|
|
9909
10056
|
internalServer.on("error", (err) => {
|
|
9910
10057
|
reject(err);
|
|
@@ -9913,10 +10060,10 @@ async function startServer({
|
|
|
9913
10060
|
return { server: server2, internalPort };
|
|
9914
10061
|
}
|
|
9915
10062
|
const server = serve({ fetch: app_default.fetch, port, hostname });
|
|
9916
|
-
await new Promise((
|
|
10063
|
+
await new Promise((resolve20, reject) => {
|
|
9917
10064
|
server.on("listening", () => {
|
|
9918
10065
|
logger_default.info("Volute API running (http)", { hostname, port });
|
|
9919
|
-
|
|
10066
|
+
resolve20();
|
|
9920
10067
|
});
|
|
9921
10068
|
server.on("error", (err) => {
|
|
9922
10069
|
reject(err);
|
|
@@ -9927,17 +10074,17 @@ async function startServer({
|
|
|
9927
10074
|
|
|
9928
10075
|
// packages/daemon/src/daemon.ts
|
|
9929
10076
|
if (!process.env.VOLUTE_HOME) {
|
|
9930
|
-
process.env.VOLUTE_HOME =
|
|
10077
|
+
process.env.VOLUTE_HOME = resolve19(homedir3(), ".volute");
|
|
9931
10078
|
}
|
|
9932
10079
|
if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
|
|
9933
10080
|
process.env.TZ = process.env.VOLUTE_TIMEZONE;
|
|
9934
10081
|
}
|
|
9935
10082
|
function writeDaemonConfig(systemDir, config2, token) {
|
|
9936
|
-
const configPath =
|
|
10083
|
+
const configPath = resolve19(systemDir, "daemon.json");
|
|
9937
10084
|
writeFileSync10(configPath, `${JSON.stringify(config2, null, 2)}
|
|
9938
10085
|
`, { mode: 420 });
|
|
9939
10086
|
chmodSync(configPath, 420);
|
|
9940
|
-
const tokenPath =
|
|
10087
|
+
const tokenPath = resolve19(systemDir, "daemon-token");
|
|
9941
10088
|
writeFileSync10(tokenPath, `${token}
|
|
9942
10089
|
`, { mode: 384 });
|
|
9943
10090
|
chmodSync(tokenPath, 384);
|
|
@@ -9948,7 +10095,7 @@ async function startDaemon(opts) {
|
|
|
9948
10095
|
const home = voluteHome();
|
|
9949
10096
|
const systemDir = voluteSystemDir();
|
|
9950
10097
|
if (!opts.foreground) {
|
|
9951
|
-
const rotatingLog = new RotatingLog(
|
|
10098
|
+
const rotatingLog = new RotatingLog(resolve19(systemDir, "daemon.log"));
|
|
9952
10099
|
logger_default.setOutput((line) => rotatingLog.write(`${line}
|
|
9953
10100
|
`));
|
|
9954
10101
|
const write = (...args) => rotatingLog.write(`${format(...args)}
|
|
@@ -9958,38 +10105,38 @@ async function startDaemon(opts) {
|
|
|
9958
10105
|
console.warn = write;
|
|
9959
10106
|
console.info = write;
|
|
9960
10107
|
}
|
|
9961
|
-
const DAEMON_PID_PATH =
|
|
9962
|
-
const DAEMON_JSON_PATH =
|
|
9963
|
-
const DAEMON_TOKEN_PATH =
|
|
10108
|
+
const DAEMON_PID_PATH = resolve19(systemDir, "daemon.pid");
|
|
10109
|
+
const DAEMON_JSON_PATH = resolve19(systemDir, "daemon.json");
|
|
10110
|
+
const DAEMON_TOKEN_PATH = resolve19(systemDir, "daemon-token");
|
|
9964
10111
|
mkdirSync10(home, { recursive: true });
|
|
9965
10112
|
ensureSystemDir();
|
|
9966
|
-
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-
|
|
10113
|
+
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-WZSXHHRJ.js");
|
|
9967
10114
|
migrateConfigSecrets();
|
|
9968
10115
|
migrateSetupCompleted();
|
|
9969
|
-
const { migrateAiModelQualification } = await import("./ai-service-
|
|
10116
|
+
const { migrateAiModelQualification } = await import("./ai-service-YW5SWCSB.js");
|
|
9970
10117
|
migrateAiModelQualification();
|
|
9971
|
-
await (await import("./db-
|
|
10118
|
+
await (await import("./db-BONH4SUG.js")).getDb();
|
|
9972
10119
|
try {
|
|
9973
10120
|
const { eq: eq9, and: and7 } = await import("drizzle-orm");
|
|
9974
|
-
const { users: users2 } = await import("./schema-
|
|
9975
|
-
const db = await (await import("./db-
|
|
10121
|
+
const { users: users2 } = await import("./schema-ZZQVM4GR.js");
|
|
10122
|
+
const db = await (await import("./db-BONH4SUG.js")).getDb();
|
|
9976
10123
|
await db.update(users2).set({ role: "system" }).where(and7(eq9(users2.user_type, "system"), eq9(users2.role, "user")));
|
|
9977
10124
|
} catch (err) {
|
|
9978
10125
|
logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
|
|
9979
10126
|
}
|
|
9980
10127
|
try {
|
|
9981
|
-
const { migrateAvatarSizes } = await import("./avatar-image-
|
|
10128
|
+
const { migrateAvatarSizes } = await import("./avatar-image-52WGXLHV.js");
|
|
9982
10129
|
await migrateAvatarSizes();
|
|
9983
10130
|
} catch (err) {
|
|
9984
10131
|
logger_default.warn("avatar size migration failed", logger_default.errorData(err));
|
|
9985
10132
|
}
|
|
9986
10133
|
try {
|
|
9987
|
-
const { migrateThreadConfigs } = await import("./migrate-thread-config-
|
|
10134
|
+
const { migrateThreadConfigs } = await import("./migrate-thread-config-EQSEP2XG.js");
|
|
9988
10135
|
await migrateThreadConfigs();
|
|
9989
10136
|
} catch (err) {
|
|
9990
10137
|
logger_default.warn("session\u2192thread config migration failed", logger_default.errorData(err));
|
|
9991
10138
|
}
|
|
9992
|
-
const { initSandbox } = await import("./sandbox-
|
|
10139
|
+
const { initSandbox } = await import("./sandbox-NNWCTHRI.js");
|
|
9993
10140
|
await initSandbox();
|
|
9994
10141
|
try {
|
|
9995
10142
|
await syncBuiltinSkills();
|
|
@@ -10021,7 +10168,7 @@ async function startDaemon(opts) {
|
|
|
10021
10168
|
logger_default.warn("failed to backfill minds into #system", logger_default.errorData(err));
|
|
10022
10169
|
}
|
|
10023
10170
|
try {
|
|
10024
|
-
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-
|
|
10171
|
+
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-X6EMNEGB.js");
|
|
10025
10172
|
await getOrCreateSystemUser2();
|
|
10026
10173
|
} catch (err) {
|
|
10027
10174
|
logger_default.warn(
|
|
@@ -10030,12 +10177,12 @@ async function startDaemon(opts) {
|
|
|
10030
10177
|
);
|
|
10031
10178
|
}
|
|
10032
10179
|
const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes3(32).toString("hex");
|
|
10033
|
-
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-
|
|
10180
|
+
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-WZSXHHRJ.js");
|
|
10034
10181
|
const globalCfg = readGlobalConfig2();
|
|
10035
10182
|
let tls;
|
|
10036
10183
|
if (opts.tailscale || globalCfg.tailscale) {
|
|
10037
10184
|
try {
|
|
10038
|
-
const { getTailscaleTls } = await import("./tailscale-
|
|
10185
|
+
const { getTailscaleTls } = await import("./tailscale-KHNZFC7L.js");
|
|
10039
10186
|
const tlsConfig = await getTailscaleTls();
|
|
10040
10187
|
tls = { key: tlsConfig.key, cert: tlsConfig.cert };
|
|
10041
10188
|
logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
|
|
@@ -10089,7 +10236,7 @@ async function startDaemon(opts) {
|
|
|
10089
10236
|
const orphanedTurns = await completeOrphanedTurns();
|
|
10090
10237
|
summarizeOrphanedTurns(orphanedTurns);
|
|
10091
10238
|
try {
|
|
10092
|
-
const { reconcileVariants } = await import("./variant-cleanup-
|
|
10239
|
+
const { reconcileVariants } = await import("./variant-cleanup-YXN25ZVW.js");
|
|
10093
10240
|
await reconcileVariants();
|
|
10094
10241
|
} catch (err) {
|
|
10095
10242
|
logger_default.error("failed to reconcile variants", logger_default.errorData(err));
|
|
@@ -10123,15 +10270,15 @@ async function startDaemon(opts) {
|
|
|
10123
10270
|
await Promise.all(workers);
|
|
10124
10271
|
}
|
|
10125
10272
|
try {
|
|
10126
|
-
const { isSetupComplete: isSetupComplete2, getSpiritName: getSpiritName2 } = await import("./setup-
|
|
10273
|
+
const { isSetupComplete: isSetupComplete2, getSpiritName: getSpiritName2 } = await import("./setup-WZSXHHRJ.js");
|
|
10127
10274
|
if (isSetupComplete2()) {
|
|
10128
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
10129
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
10275
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-25JVAL3M.js");
|
|
10276
|
+
const { startSpiritFull } = await import("./mind-service-DZCUUC7J.js");
|
|
10130
10277
|
await ensureSpiritProject();
|
|
10131
10278
|
const spiritName = getSpiritName2();
|
|
10132
10279
|
const spiritEntry = await findMind(spiritName);
|
|
10133
10280
|
if (spiritEntry?.dir) {
|
|
10134
|
-
const { registerMindDir } = await import("./delivery-router-
|
|
10281
|
+
const { registerMindDir } = await import("./delivery-router-RHANNTAC.js");
|
|
10135
10282
|
registerMindDir(spiritName, spiritEntry.dir);
|
|
10136
10283
|
}
|
|
10137
10284
|
await syncSpiritTemplate();
|
|
@@ -10145,7 +10292,7 @@ async function startDaemon(opts) {
|
|
|
10145
10292
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
10146
10293
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
10147
10294
|
});
|
|
10148
|
-
import("./cloud-sync-
|
|
10295
|
+
import("./cloud-sync-GPXYPTIC.js").then(
|
|
10149
10296
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
10150
10297
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
10151
10298
|
})
|
|
@@ -10153,7 +10300,7 @@ async function startDaemon(opts) {
|
|
|
10153
10300
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
10154
10301
|
});
|
|
10155
10302
|
try {
|
|
10156
|
-
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-
|
|
10303
|
+
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-EN3KJ7HH.js");
|
|
10157
10304
|
backfillTemplateHashes().then(() => warnStaleTemplates()).catch((err) => {
|
|
10158
10305
|
logger_default.warn("failed to check template staleness", logger_default.errorData(err));
|
|
10159
10306
|
});
|