volute 0.40.0 → 0.40.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{accept-AHAOUFBK.js → accept-IVHOHXQS.js} +1 -1
- package/dist/{activity-events-OJZ7G5CG.js → activity-events-DS4QRWBY.js} +4 -4
- package/dist/{ai-service-JMV4KZN4.js → ai-service-EVLKMAJD.js} +5 -5
- package/dist/{api-client-LC5YRA32.js → api-client-NFM6GX2N.js} +1 -1
- package/dist/{archive-BC2MTNPV.js → archive-UDHFZN4G.js} +4 -4
- package/dist/{auth-2IMZ6N5G.js → auth-X6ZITZ7D.js} +5 -5
- package/dist/{bridge-F3ZJEKDN.js → bridge-MSZC4HUT.js} +1 -1
- package/dist/{chat-O5QCGCUG.js → chat-F2EEN76G.js} +9 -9
- package/dist/{chunk-MHFAWJCC.js → chunk-2HZRJ35V.js} +1 -1
- package/dist/{chunk-B7YJUWMM.js → chunk-3Y7UDHO7.js} +3 -3
- package/dist/{chunk-RMZSICLS.js → chunk-42UMLIQR.js} +20 -21
- package/dist/{chunk-SGC6CDXB.js → chunk-4UMXOMZ6.js} +2 -2
- package/dist/{chunk-FBV22PFY.js → chunk-6SYHHEQ7.js} +1 -1
- package/dist/{chunk-3XSFMN3H.js → chunk-AEAZRTEV.js} +1 -1
- package/dist/{chunk-PDSA3ILI.js → chunk-B4WPXYPI.js} +1 -1
- package/dist/{chunk-2AQCEQYN.js → chunk-DNU6XLE2.js} +1 -1
- package/dist/{chunk-PHR4XQPL.js → chunk-E25SO3QW.js} +3 -3
- package/dist/{chunk-76Q6YLJL.js → chunk-I57LLNAQ.js} +1 -1
- package/dist/{chunk-HAJHDGBV.js → chunk-ITH5ZLZJ.js} +1 -1
- package/dist/{chunk-SOPMVTTW.js → chunk-JYQQDI3M.js} +2 -2
- package/dist/{chunk-PIRL2HAO.js → chunk-KMHC36CA.js} +1 -1
- package/dist/chunk-LMMQX4CK.js +49 -0
- package/dist/{chunk-FRJ73IWR.js → chunk-MNUXL4XN.js} +67 -3
- package/dist/{chunk-PC55DGNX.js → chunk-NERYUSER.js} +1 -1
- package/dist/{chunk-WGRMLXTH.js → chunk-NRJ3ZYFP.js} +10 -10
- package/dist/{chunk-43PVCF4V.js → chunk-PEKG3GNZ.js} +3 -3
- package/dist/{chunk-S4YO5OWV.js → chunk-PKGA23XM.js} +1 -1
- package/dist/{chunk-5VBXKFPO.js → chunk-QYI65HCL.js} +2 -2
- package/dist/{chunk-HEZM5GCV.js → chunk-SVXOBKQY.js} +2 -2
- package/dist/{chunk-PZTVQL3J.js → chunk-TOANT6FD.js} +2 -2
- package/dist/{chunk-T26YLQPU.js → chunk-UX7FPDDO.js} +5 -5
- package/dist/{chunk-JSITYTIL.js → chunk-WOWRLBL2.js} +10 -8
- package/dist/{chunk-DNQPHLGM.js → chunk-YHWGN4FX.js} +1 -1
- package/dist/chunk-YMMYN2V3.js +1212 -0
- package/dist/{chunk-XUJR6NZW.js → chunk-ZOI6D2YH.js} +194 -1313
- package/dist/{chunk-PGX52NFO.js → chunk-ZXPWTH4I.js} +43 -35
- package/dist/cli.js +24 -24
- package/dist/{clock-BMLJ2TR6.js → clock-YLDJUKBW.js} +3 -3
- package/dist/{cloud-sync-5JF2Z7VM.js → cloud-sync-GOSJZIHH.js} +18 -17
- package/dist/{config-QB7W3Z7P.js → config-PO4EZLIK.js} +4 -4
- package/dist/connectors/discord-bridge.js +1 -1
- package/dist/connectors/slack-bridge.js +1 -1
- package/dist/connectors/telegram-bridge.js +1 -1
- package/dist/{conversations-LUVHGQSS.js → conversations-AYLXPOGC.js} +5 -5
- package/dist/{create-TDQM3SHV.js → create-Y3RGU2GI.js} +5 -5
- package/dist/{create-C3BBFYV7.js → create-ZMTGINV3.js} +1 -1
- package/dist/{daemon-client-2MIPKY3E.js → daemon-client-H6MEKK2W.js} +1 -1
- package/dist/{daemon-restart-XHDJDOPQ.js → daemon-restart-FSWVXPUE.js} +9 -9
- package/dist/daemon.js +318 -280
- package/dist/{db-IJL6B26S.js → db-FSYOTHSN.js} +1 -1
- package/dist/db-ZEPKEJJD.js +9 -0
- package/dist/{delete-NLXES2C7.js → delete-TXVOH2OC.js} +3 -3
- package/dist/delivery-manager-3NTCDKHR.js +33 -0
- package/dist/{delivery-router-IU4OMVKZ.js → delivery-router-T6CYTS3M.js} +4 -4
- package/dist/down-6DYO2QV7.js +17 -0
- package/dist/echo-text-JUNRP4ER.js +32 -0
- package/dist/{env-IQ6Q2333.js → env-77IOWG4U.js} +1 -1
- package/dist/exec-5DGKQ5V3.js +17 -0
- package/dist/{export-RKUWSQSG.js → export-TZKOCSCE.js} +6 -6
- package/dist/{extension-LZYHBNLV.js → extension-35NB6GHW.js} +1 -1
- package/dist/{extensions-VN5SEVRP.js → extensions-MD757RFY.js} +18 -17
- package/dist/{files-J2CKZ6PK.js → files-WNNVJWJB.js} +4 -4
- package/dist/{import-KVY6BYXG.js → import-BNNFCQ7U.js} +11 -11
- package/dist/{isolation-MM7YHK6J.js → isolation-4Q4P7HRV.js} +4 -4
- package/dist/{join-6SZCA5FX.js → join-E2EJEXZO.js} +3 -3
- package/dist/{list-KHJZJPEJ.js → list-BYCEDASJ.js} +1 -1
- package/dist/{login-GYTH67ES.js → login-JNSIYFVH.js} +1 -1
- package/dist/{login-OHM32QVD.js → login-Y6UAYQVO.js} +3 -3
- package/dist/{logout-YHQLOFLR.js → logout-M6FI62BL.js} +1 -1
- package/dist/{logout-74WBDMOE.js → logout-VHGWVH63.js} +3 -3
- package/dist/message-delivery-Q7TU24IA.js +41 -0
- package/dist/{mind-PUPXDIYQ.js → mind-OOB2LEVC.js} +19 -19
- package/dist/{mind-activity-tracker-7GE24YZE.js → mind-activity-tracker-GJ5RJS32.js} +5 -5
- package/dist/{mind-history-WHCNZ6I5.js → mind-history-W4JPTPTV.js} +1 -1
- package/dist/{mind-list-H3HC2ZRG.js → mind-list-QROHCLGT.js} +1 -1
- package/dist/mind-manager-4NFK4GEU.js +31 -0
- package/dist/{mind-profile-7VYRJGFZ.js → mind-profile-3LNKXNPA.js} +2 -2
- package/dist/mind-service-X7FH3NA4.js +37 -0
- package/dist/{mind-sleep-ZL5ZXFTM.js → mind-sleep-PVCMLTAH.js} +1 -1
- package/dist/{mind-status-ZWULKOUO.js → mind-status-RAJFLRCN.js} +1 -1
- package/dist/{mind-wake-HK5ORGUK.js → mind-wake-HZUOVE7J.js} +1 -1
- package/dist/{package-6YPVWGD3.js → package-PPA3VWS2.js} +28 -27
- package/dist/{read-CP7MYMJQ.js → read-OOINVR2H.js} +1 -1
- package/dist/{read-stdin-4B5UYPPM.js → read-stdin-P6HCZUAA.js} +1 -1
- package/dist/{register-XOBFEMI4.js → register-ISOH34RF.js} +1 -1
- package/dist/{registry-L272BZJR.js → registry-GV35XFT7.js} +3 -3
- package/dist/{reject-43AGXB6B.js → reject-ZBWP62X5.js} +1 -1
- package/dist/{restart-O5QIYQJT.js → restart-QBJV5455.js} +1 -1
- package/dist/{sandbox-BQAFYHLE.js → sandbox-5R32QKWQ.js} +5 -5
- package/dist/scheduler-PDARH4CE.js +31 -0
- package/dist/{schema-HHYJDG7B.js → schema-LYQUDL7G.js} +2 -2
- package/dist/{seed-4V2O7FQE.js → seed-BTAHXCO5.js} +2 -2
- package/dist/{seed-check-HZPVFJKZ.js → seed-check-3WXXRHTC.js} +2 -2
- package/dist/{seed-cmd-JKDEW4MP.js → seed-cmd-VEJNJBAQ.js} +4 -4
- package/dist/{seed-create-EPAO3H5F.js → seed-create-LOU5RALI.js} +7 -7
- package/dist/{seed-sprout-EONCL4DU.js → seed-sprout-BXF5TBXD.js} +11 -11
- package/dist/{send-232RAHPX.js → send-WO3CVG73.js} +4 -4
- package/dist/{service-AG5BKRUV.js → service-WMV6R6VJ.js} +6 -6
- package/dist/service-install-W3FQXJKB.js +17 -0
- package/dist/{setup-IL7QJZN4.js → setup-OTEC3ZPM.js} +4 -4
- package/dist/{setup-PSA7LJ5U.js → setup-W3545462.js} +9 -9
- package/dist/{skill-ICN6Y2ZF.js → skill-QHACP7EU.js} +1 -1
- package/dist/{skills-SLEY5X6W.js → skills-3P7VQA4U.js} +7 -7
- package/dist/sleep-manager-TTNOLIX5.js +35 -0
- package/dist/{spirit-7BUHSEO2.js → spirit-T6GK5GEP.js} +9 -9
- package/dist/{split-5YBEQTBF.js → split-7AO4IO42.js} +3 -3
- package/dist/{sprout-JWQ57KF3.js → sprout-AQICF7WZ.js} +2 -2
- package/dist/{src-OYWRPLC6.js → src-2IMB3V27.js} +1 -1
- package/dist/src-OS75U2O7.js +241910 -0
- package/dist/{src-O4PRLMKM.js → src-XNUXP2FP.js} +1 -1
- package/dist/{start-LMXXRR3X.js → start-2U57BBK7.js} +1 -1
- package/dist/{status-6GSOSYOD.js → status-BRYYYO7C.js} +7 -7
- package/dist/{stop-TWDKVEUX.js → stop-QILBDUAR.js} +1 -1
- package/dist/system-chat-7CA2PP6A.js +35 -0
- package/dist/{systems-Y2WZV2K4.js → systems-3XTAHA35.js} +4 -4
- package/dist/{tailscale-6MHNLBAX.js → tailscale-X4HRKRTW.js} +3 -3
- package/dist/{template-hash-SSIBEEYK.js → template-hash-DMHSLRDX.js} +1 -1
- package/dist/turn-tracker-AI6WWEBA.js +35 -0
- package/dist/up-PKNNDN6M.js +19 -0
- package/dist/{update-BT2PY73H.js → update-OY2JYXYK.js} +61 -14
- package/dist/update-check-IUB7QHAF.js +24 -0
- package/dist/{upgrade-RXFZR5FI.js → upgrade-25J6AE47.js} +3 -3
- package/dist/{variant-HHDTW74J.js → variant-5LQOPCQA.js} +1 -1
- package/dist/{version-notify-NFQMI5IY.js → version-notify-DK6AHWX7.js} +19 -18
- package/dist/{volute-config-TS62GS6A.js → volute-config-7FO6QKWU.js} +1 -1
- package/dist/web-assets/assets/index-DaUp9iE2.js +79 -0
- package/dist/web-assets/index.html +1 -1
- package/package.json +27 -26
- package/packages/extensions/notes/dist/ui/assets/index-BbgANhFm.js +67 -0
- package/packages/extensions/notes/dist/ui/index.html +1 -1
- package/packages/extensions/pages/dist/ui/assets/index-Dxk-DYrf.js +2 -0
- package/packages/extensions/pages/dist/ui/index.html +1 -1
- package/packages/extensions/plan/dist/ui/assets/index-Cfzs-0G9.js +67 -0
- package/packages/extensions/plan/dist/ui/index.html +1 -1
- package/templates/claude/package.json.tmpl +5 -5
- package/templates/codex/package.json.tmpl +5 -5
- package/templates/pi/package.json.tmpl +7 -6
- package/templates/pi/src/agent.ts +3 -1
- package/templates/pi/src/lib/content.ts +1 -1
- package/templates/pi/src/lib/event-handler.ts +1 -1
- package/templates/pi/src/lib/reply-instructions-extension.ts +1 -1
- package/templates/pi/src/lib/resolve-model.ts +4 -4
- package/templates/pi/src/lib/subagents.ts +21 -19
- package/dist/chunk-K3NQKI34.js +0 -10
- package/dist/db-2GIS7HSG.js +0 -9
- package/dist/delivery-manager-L5WFP2ND.js +0 -30
- package/dist/down-KIJVZ3OC.js +0 -17
- package/dist/echo-text-TJWCUBPB.js +0 -31
- package/dist/exec-BGMU7VXR.js +0 -17
- package/dist/message-delivery-VBBAJX3J.js +0 -40
- package/dist/mind-manager-4Q6KGZHL.js +0 -30
- package/dist/mind-service-7OD4PRO5.js +0 -36
- package/dist/scheduler-7E22Q7IC.js +0 -30
- package/dist/service-install-HVAEUBAH.js +0 -17
- package/dist/sleep-manager-27S7MKJO.js +0 -34
- package/dist/src-6Z4XYDH5.js +0 -2164
- package/dist/system-chat-EIINIHFB.js +0 -34
- package/dist/up-4XS3RCPP.js +0 -19
- package/dist/update-check-Y3HBEMF2.js +0 -18
- package/dist/web-assets/assets/index-Jluza4c-.js +0 -73
- package/packages/extensions/notes/dist/ui/assets/index-Dsua7alJ.js +0 -61
- package/packages/extensions/pages/dist/ui/assets/index-BM7gRdg7.js +0 -2
- package/packages/extensions/plan/dist/ui/assets/index-DWiqtzBv.js +0 -61
package/dist/daemon.js
CHANGED
|
@@ -6,21 +6,21 @@ import {
|
|
|
6
6
|
rejectPending,
|
|
7
7
|
stageFile,
|
|
8
8
|
validateFilePath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-YHWGN4FX.js";
|
|
10
10
|
import {
|
|
11
11
|
findOpenClawSession,
|
|
12
12
|
importOpenClawConnectors,
|
|
13
13
|
importPiSession,
|
|
14
14
|
parseNameFromIdentity
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-SVXOBKQY.js";
|
|
16
16
|
import {
|
|
17
17
|
checkForUpdate,
|
|
18
18
|
checkForUpdateCached,
|
|
19
19
|
getCurrentVersion
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-MNUXL4XN.js";
|
|
21
21
|
import {
|
|
22
22
|
isHomeOnlyArchive
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-I57LLNAQ.js";
|
|
24
24
|
import {
|
|
25
25
|
computeTemplateHash
|
|
26
26
|
} from "./chunk-KAB6UGOL.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
fixModelEscapes,
|
|
31
31
|
getPlatformDriver,
|
|
32
32
|
routeOutboundBridge
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-WOWRLBL2.js";
|
|
34
34
|
import {
|
|
35
35
|
getBridgeConfig,
|
|
36
36
|
readBridgesConfig,
|
|
@@ -39,35 +39,24 @@ import {
|
|
|
39
39
|
resolveChannelMapping,
|
|
40
40
|
setBridgeConfig,
|
|
41
41
|
setChannelMapping
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-PKGA23XM.js";
|
|
43
43
|
import {
|
|
44
|
-
PROMPT_DEFAULTS,
|
|
45
|
-
PROMPT_KEYS,
|
|
46
44
|
RestartTracker,
|
|
47
45
|
RotatingLog,
|
|
48
46
|
announceToSystem,
|
|
49
|
-
assignSession,
|
|
50
47
|
clearDeliveredNotices,
|
|
51
|
-
completeOrphanedTurns,
|
|
52
|
-
completeTurn,
|
|
53
|
-
createTurn,
|
|
54
48
|
deleteSystemsConfig,
|
|
55
49
|
deliverMessage,
|
|
56
50
|
drainNotices,
|
|
57
51
|
ensureSystemChannel,
|
|
58
52
|
formatNotices,
|
|
59
53
|
generateSystemReply,
|
|
60
|
-
getActiveTurnId,
|
|
61
54
|
getAllDiscoveredExtensions,
|
|
62
55
|
getAllDiscoveredExtensionsDetailed,
|
|
63
56
|
getDeliveryManager,
|
|
64
57
|
getExtensionStandardSkills,
|
|
65
|
-
getLastToolUseEventId,
|
|
66
58
|
getLoadedExtensions,
|
|
67
59
|
getMindManager,
|
|
68
|
-
getMindPromptDefaults,
|
|
69
|
-
getPrompt,
|
|
70
|
-
getPromptIfCustom,
|
|
71
60
|
getScheduler,
|
|
72
61
|
getSleepManagerIfReady,
|
|
73
62
|
getTokenBudget,
|
|
@@ -77,17 +66,14 @@ import {
|
|
|
77
66
|
initMindManager,
|
|
78
67
|
initScheduler,
|
|
79
68
|
initSleepManager,
|
|
80
|
-
initSummarizer,
|
|
81
69
|
initTokenBudget,
|
|
82
70
|
installNpmExtension,
|
|
83
71
|
isConversationId,
|
|
84
72
|
joinSystemChannel,
|
|
85
73
|
linkToolResultToTurn,
|
|
86
74
|
loadAllExtensions,
|
|
87
|
-
markErrored,
|
|
88
75
|
notifyExtensionsDaemonStart,
|
|
89
76
|
notifyExtensionsDaemonStop,
|
|
90
|
-
publish as publish2,
|
|
91
77
|
publishTypingForChannels,
|
|
92
78
|
readSystemsConfig,
|
|
93
79
|
recordInbound,
|
|
@@ -97,27 +83,20 @@ import {
|
|
|
97
83
|
setExtensionEnabled,
|
|
98
84
|
startMindFull,
|
|
99
85
|
stopMindFull,
|
|
100
|
-
subscribe as subscribe3,
|
|
101
|
-
subscribeAll,
|
|
102
|
-
substitute,
|
|
103
|
-
summarizeOrphanedTurns,
|
|
104
|
-
summarizeTurn,
|
|
105
86
|
syncProviderToMinds,
|
|
106
87
|
tagUntaggedInbound,
|
|
107
88
|
tagUntaggedOutbound,
|
|
108
|
-
takeErrored,
|
|
109
|
-
trackToolUse,
|
|
110
89
|
uninstallNpmExtension,
|
|
111
90
|
writeSystemsConfig
|
|
112
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-ZOI6D2YH.js";
|
|
113
92
|
import {
|
|
114
93
|
loadMergedEnv,
|
|
115
94
|
mindEnvPath,
|
|
116
95
|
readEnv,
|
|
117
96
|
sharedEnvPath,
|
|
118
97
|
writeEnv
|
|
119
|
-
} from "./chunk-
|
|
120
|
-
import "./chunk-
|
|
98
|
+
} from "./chunk-ITH5ZLZJ.js";
|
|
99
|
+
import "./chunk-NRJ3ZYFP.js";
|
|
121
100
|
import {
|
|
122
101
|
applyInitFiles,
|
|
123
102
|
composeTemplate,
|
|
@@ -144,7 +123,7 @@ import {
|
|
|
144
123
|
syncBuiltinSkills,
|
|
145
124
|
uninstallSkill,
|
|
146
125
|
updateSkill
|
|
147
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-UX7FPDDO.js";
|
|
148
127
|
import {
|
|
149
128
|
addMessage,
|
|
150
129
|
createChannel,
|
|
@@ -176,25 +155,48 @@ import {
|
|
|
176
155
|
setConversationPrivate,
|
|
177
156
|
subscribe as subscribe2,
|
|
178
157
|
updateChannelSettings
|
|
179
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-3Y7UDHO7.js";
|
|
180
159
|
import {
|
|
181
160
|
readVoluteConfig,
|
|
182
161
|
writeVoluteConfig
|
|
183
162
|
} from "./chunk-CU6OFXMM.js";
|
|
184
|
-
import "./chunk-
|
|
163
|
+
import "./chunk-KMHC36CA.js";
|
|
185
164
|
import {
|
|
186
165
|
getActiveMinds,
|
|
187
166
|
onMindEvent,
|
|
188
167
|
stopAll
|
|
189
|
-
} from "./chunk-
|
|
168
|
+
} from "./chunk-42UMLIQR.js";
|
|
190
169
|
import {
|
|
191
170
|
extractTextContent
|
|
192
|
-
} from "./chunk-
|
|
171
|
+
} from "./chunk-NERYUSER.js";
|
|
172
|
+
import {
|
|
173
|
+
PROMPT_DEFAULTS,
|
|
174
|
+
PROMPT_KEYS,
|
|
175
|
+
assignSession,
|
|
176
|
+
completeOrphanedTurns,
|
|
177
|
+
completeTurn,
|
|
178
|
+
createTurn,
|
|
179
|
+
getActiveTurnId,
|
|
180
|
+
getLastToolUseEventId,
|
|
181
|
+
getMindPromptDefaults,
|
|
182
|
+
getPrompt,
|
|
183
|
+
getPromptIfCustom,
|
|
184
|
+
initSummarizer,
|
|
185
|
+
markErrored,
|
|
186
|
+
publish as publish2,
|
|
187
|
+
subscribe as subscribe3,
|
|
188
|
+
subscribeAll,
|
|
189
|
+
substitute,
|
|
190
|
+
summarizeOrphanedTurns,
|
|
191
|
+
summarizeTurn,
|
|
192
|
+
takeErrored,
|
|
193
|
+
trackToolUse
|
|
194
|
+
} from "./chunk-YMMYN2V3.js";
|
|
193
195
|
import {
|
|
194
196
|
exec,
|
|
195
197
|
gitExec,
|
|
196
198
|
resolveVoluteBin
|
|
197
|
-
} from "./chunk-
|
|
199
|
+
} from "./chunk-AEAZRTEV.js";
|
|
198
200
|
import {
|
|
199
201
|
chownMindDir,
|
|
200
202
|
createMindUser,
|
|
@@ -202,7 +204,7 @@ import {
|
|
|
202
204
|
ensureVoluteGroup,
|
|
203
205
|
isIsolationEnabled,
|
|
204
206
|
wrapForIsolation
|
|
205
|
-
} from "./chunk-
|
|
207
|
+
} from "./chunk-6SYHHEQ7.js";
|
|
206
208
|
import {
|
|
207
209
|
getAiConfig,
|
|
208
210
|
getAvailableModels,
|
|
@@ -219,12 +221,12 @@ import {
|
|
|
219
221
|
setProviderRefreshHook,
|
|
220
222
|
setUtilityModel,
|
|
221
223
|
unqualifyModelId
|
|
222
|
-
} from "./chunk-
|
|
224
|
+
} from "./chunk-ZXPWTH4I.js";
|
|
223
225
|
import {
|
|
224
226
|
isSetupComplete,
|
|
225
227
|
readGlobalConfig,
|
|
226
228
|
writeGlobalConfig
|
|
227
|
-
} from "./chunk-
|
|
229
|
+
} from "./chunk-DNU6XLE2.js";
|
|
228
230
|
import {
|
|
229
231
|
approveUser,
|
|
230
232
|
changePassword,
|
|
@@ -243,11 +245,11 @@ import {
|
|
|
243
245
|
syncMindProfile,
|
|
244
246
|
updateUserProfile,
|
|
245
247
|
verifyUser
|
|
246
|
-
} from "./chunk-
|
|
248
|
+
} from "./chunk-E25SO3QW.js";
|
|
247
249
|
import {
|
|
248
250
|
broadcast,
|
|
249
251
|
subscribe
|
|
250
|
-
} from "./chunk-
|
|
252
|
+
} from "./chunk-QYI65HCL.js";
|
|
251
253
|
import {
|
|
252
254
|
logBuffer,
|
|
253
255
|
logger_default
|
|
@@ -277,7 +279,7 @@ import {
|
|
|
277
279
|
validateMindName,
|
|
278
280
|
voluteHome,
|
|
279
281
|
voluteSystemDir
|
|
280
|
-
} from "./chunk-
|
|
282
|
+
} from "./chunk-B4WPXYPI.js";
|
|
281
283
|
import {
|
|
282
284
|
activity,
|
|
283
285
|
channels,
|
|
@@ -289,14 +291,14 @@ import {
|
|
|
289
291
|
systemPrompts,
|
|
290
292
|
turns,
|
|
291
293
|
users
|
|
292
|
-
} from "./chunk-
|
|
293
|
-
import "./chunk-
|
|
294
|
+
} from "./chunk-2HZRJ35V.js";
|
|
295
|
+
import "./chunk-LMMQX4CK.js";
|
|
294
296
|
|
|
295
297
|
// packages/daemon/src/daemon.ts
|
|
296
298
|
import { randomBytes } from "crypto";
|
|
297
299
|
import { mkdirSync as mkdirSync10, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
|
|
298
300
|
import { homedir as homedir3 } from "os";
|
|
299
|
-
import { resolve as
|
|
301
|
+
import { resolve as resolve17 } from "path";
|
|
300
302
|
import { format } from "util";
|
|
301
303
|
|
|
302
304
|
// packages/daemon/src/lib/daemon/bridge-manager.ts
|
|
@@ -506,8 +508,8 @@ var BridgeManager = class {
|
|
|
506
508
|
if (!tracked) return;
|
|
507
509
|
this.stopping.add(platform);
|
|
508
510
|
this.bridges.delete(platform);
|
|
509
|
-
await new Promise((
|
|
510
|
-
tracked.child.on("exit", () =>
|
|
511
|
+
await new Promise((resolve18) => {
|
|
512
|
+
tracked.child.on("exit", () => resolve18());
|
|
511
513
|
try {
|
|
512
514
|
if (tracked.child.pid) {
|
|
513
515
|
process.kill(-tracked.child.pid, "SIGTERM");
|
|
@@ -518,7 +520,7 @@ var BridgeManager = class {
|
|
|
518
520
|
if (err instanceof Error && err.code !== "ESRCH") {
|
|
519
521
|
blog.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
|
|
520
522
|
}
|
|
521
|
-
|
|
523
|
+
resolve18();
|
|
522
524
|
}
|
|
523
525
|
setTimeout(() => {
|
|
524
526
|
try {
|
|
@@ -529,7 +531,7 @@ var BridgeManager = class {
|
|
|
529
531
|
}
|
|
530
532
|
} catch {
|
|
531
533
|
}
|
|
532
|
-
|
|
534
|
+
resolve18();
|
|
533
535
|
}, 5e3);
|
|
534
536
|
});
|
|
535
537
|
this.stopping.delete(platform);
|
|
@@ -627,9 +629,9 @@ async function cleanExpiredLogs() {
|
|
|
627
629
|
}
|
|
628
630
|
|
|
629
631
|
// packages/daemon/src/web/api/system.ts
|
|
632
|
+
import { getOAuthProvider, getOAuthProviders } from "@earendil-works/pi-ai/oauth";
|
|
633
|
+
import { getBuiltinProviders } from "@earendil-works/pi-ai/providers/all";
|
|
630
634
|
import { zValidator } from "@hono/zod-validator";
|
|
631
|
-
import { getProviders } from "@mariozechner/pi-ai";
|
|
632
|
-
import { getOAuthProvider, getOAuthProviders } from "@mariozechner/pi-ai/oauth";
|
|
633
635
|
import { Hono } from "hono";
|
|
634
636
|
import { streamSSE } from "hono/streaming";
|
|
635
637
|
import { z } from "zod";
|
|
@@ -993,10 +995,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
993
995
|
stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
|
|
994
996
|
});
|
|
995
997
|
});
|
|
996
|
-
await new Promise((
|
|
998
|
+
await new Promise((resolve18) => {
|
|
997
999
|
stream.onAbort(() => {
|
|
998
1000
|
unsubscribe();
|
|
999
|
-
|
|
1001
|
+
resolve18();
|
|
1000
1002
|
});
|
|
1001
1003
|
});
|
|
1002
1004
|
});
|
|
@@ -1200,7 +1202,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1200
1202
|
if (!key) return c.json({ error: "No key available" }, 404);
|
|
1201
1203
|
return c.json({ key });
|
|
1202
1204
|
}).get("/ai/providers", requireAdmin, (c) => {
|
|
1203
|
-
const allProviders =
|
|
1205
|
+
const allProviders = getBuiltinProviders();
|
|
1204
1206
|
const oauthProviders = getOAuthProviders();
|
|
1205
1207
|
const oauthMap = new Map(oauthProviders.map((p) => [p.id, p]));
|
|
1206
1208
|
const ai = getAiConfig();
|
|
@@ -1223,8 +1225,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1223
1225
|
};
|
|
1224
1226
|
});
|
|
1225
1227
|
return c.json(result);
|
|
1226
|
-
}).get("/ai/models", requireAdmin, (c) => {
|
|
1227
|
-
const models = getAvailableModels();
|
|
1228
|
+
}).get("/ai/models", requireAdmin, async (c) => {
|
|
1229
|
+
const models = await getAvailableModels();
|
|
1228
1230
|
const enabled = new Set(getEnabledModels());
|
|
1229
1231
|
return c.json(
|
|
1230
1232
|
models.map((m) => ({
|
|
@@ -1309,8 +1311,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1309
1311
|
createdAt: Date.now()
|
|
1310
1312
|
};
|
|
1311
1313
|
oauthFlows.set(flowId, flow);
|
|
1312
|
-
const promptPromise = needsManualCode ? new Promise((
|
|
1313
|
-
flow.resolveCode =
|
|
1314
|
+
const promptPromise = needsManualCode ? new Promise((resolve18) => {
|
|
1315
|
+
flow.resolveCode = resolve18;
|
|
1314
1316
|
}) : void 0;
|
|
1315
1317
|
oauthProvider.login({
|
|
1316
1318
|
onAuth: (info) => {
|
|
@@ -1318,6 +1320,15 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1318
1320
|
if (existing)
|
|
1319
1321
|
Object.assign(existing, { url: info.url, instructions: info.instructions });
|
|
1320
1322
|
},
|
|
1323
|
+
onDeviceCode: (info) => {
|
|
1324
|
+
const existing = oauthFlows.get(flowId);
|
|
1325
|
+
if (existing)
|
|
1326
|
+
Object.assign(existing, {
|
|
1327
|
+
url: info.verificationUri,
|
|
1328
|
+
instructions: `Enter code: ${info.userCode}`
|
|
1329
|
+
});
|
|
1330
|
+
},
|
|
1331
|
+
onSelect: async (_prompt) => void 0,
|
|
1321
1332
|
onPrompt: async (_prompt) => {
|
|
1322
1333
|
if (promptPromise) {
|
|
1323
1334
|
const existing = oauthFlows.get(flowId);
|
|
@@ -1340,7 +1351,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1340
1351
|
existing.error = err instanceof Error ? err.message : String(err);
|
|
1341
1352
|
}
|
|
1342
1353
|
});
|
|
1343
|
-
await new Promise((
|
|
1354
|
+
await new Promise((resolve18) => setTimeout(resolve18, 2e3));
|
|
1344
1355
|
const state = oauthFlows.get(flowId);
|
|
1345
1356
|
return c.json({
|
|
1346
1357
|
flowId,
|
|
@@ -1484,7 +1495,7 @@ function needsRefresh(oauth) {
|
|
|
1484
1495
|
}
|
|
1485
1496
|
async function refreshApiKeyCache() {
|
|
1486
1497
|
const ai = getAiConfig();
|
|
1487
|
-
const providers = getConfiguredProviders();
|
|
1498
|
+
const providers = await getConfiguredProviders();
|
|
1488
1499
|
for (const id of oauthHealth.keys()) {
|
|
1489
1500
|
if (!providers.includes(id)) oauthHealth.delete(id);
|
|
1490
1501
|
}
|
|
@@ -1598,8 +1609,8 @@ var app2 = new Hono2().get("/events", async (c) => {
|
|
|
1598
1609
|
});
|
|
1599
1610
|
}, 15e3);
|
|
1600
1611
|
cleanups.push(() => clearInterval(keepAlive));
|
|
1601
|
-
await new Promise((
|
|
1602
|
-
stream.onAbort(() =>
|
|
1612
|
+
await new Promise((resolve18) => {
|
|
1613
|
+
stream.onAbort(() => resolve18());
|
|
1603
1614
|
});
|
|
1604
1615
|
} finally {
|
|
1605
1616
|
for (const cleanup of cleanups) {
|
|
@@ -2002,7 +2013,7 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
|
|
|
2002
2013
|
}
|
|
2003
2014
|
const participants = await getParticipants(channel.id);
|
|
2004
2015
|
if (!participants.some((p) => p.userId === puppet.id)) {
|
|
2005
|
-
const { addParticipant } = await import("./conversations-
|
|
2016
|
+
const { addParticipant } = await import("./conversations-AYLXPOGC.js");
|
|
2006
2017
|
await addParticipant(channel.id, puppet.id);
|
|
2007
2018
|
}
|
|
2008
2019
|
const contentBlocks = body.content;
|
|
@@ -2095,8 +2106,8 @@ async function fanOutToBridgedMinds(opts) {
|
|
|
2095
2106
|
const participants = await getParticipants(opts.conversationId);
|
|
2096
2107
|
const mindParticipants = participants.filter((p) => p.userType === "mind");
|
|
2097
2108
|
const participantNames = participants.map((p) => p.username);
|
|
2098
|
-
const { getMindManager: getMindManager2 } = await import("./mind-manager-
|
|
2099
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
2109
|
+
const { getMindManager: getMindManager2 } = await import("./mind-manager-4NFK4GEU.js");
|
|
2110
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-TTNOLIX5.js");
|
|
2100
2111
|
const manager = getMindManager2();
|
|
2101
2112
|
const sm = getSleepManagerIfReady2();
|
|
2102
2113
|
const targetMinds = mindParticipants.filter((ap) => {
|
|
@@ -2155,9 +2166,9 @@ var channels_default = app5;
|
|
|
2155
2166
|
// packages/daemon/src/web/api/config.ts
|
|
2156
2167
|
import { Hono as Hono6 } from "hono";
|
|
2157
2168
|
var config = new Hono6();
|
|
2158
|
-
config.get("/models", (c) => {
|
|
2169
|
+
config.get("/models", async (c) => {
|
|
2159
2170
|
const enabled = new Set(getEnabledModels());
|
|
2160
|
-
const all = getAvailableModels();
|
|
2171
|
+
const all = await getAvailableModels();
|
|
2161
2172
|
const models = all.map((m) => ({
|
|
2162
2173
|
id: m.id,
|
|
2163
2174
|
name: m.name,
|
|
@@ -2166,8 +2177,8 @@ config.get("/models", (c) => {
|
|
|
2166
2177
|
}));
|
|
2167
2178
|
return c.json(models);
|
|
2168
2179
|
});
|
|
2169
|
-
config.get("/providers", (c) => {
|
|
2170
|
-
const configured = getConfiguredProviders();
|
|
2180
|
+
config.get("/providers", async (c) => {
|
|
2181
|
+
const configured = await getConfiguredProviders();
|
|
2171
2182
|
return c.json(configured.map((id) => ({ id, configured: true })));
|
|
2172
2183
|
});
|
|
2173
2184
|
config.get("/status", (c) => {
|
|
@@ -2182,13 +2193,13 @@ var config_default = config;
|
|
|
2182
2193
|
|
|
2183
2194
|
// packages/daemon/src/web/api/env.ts
|
|
2184
2195
|
import { Hono as Hono7 } from "hono";
|
|
2185
|
-
var app6 = new Hono7().get("/:name/env", async (c) => {
|
|
2196
|
+
var app6 = new Hono7().get("/:name/env", requireSelf(), async (c) => {
|
|
2186
2197
|
const name = c.req.param("name");
|
|
2187
2198
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
2188
2199
|
const shared = readEnv(sharedEnvPath());
|
|
2189
2200
|
const mind = readEnv(mindEnvPath(name));
|
|
2190
2201
|
return c.json({ shared, mind });
|
|
2191
|
-
}).get("/:name/env/:key", async (c) => {
|
|
2202
|
+
}).get("/:name/env/:key", requireSelf(), async (c) => {
|
|
2192
2203
|
const name = c.req.param("name");
|
|
2193
2204
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
2194
2205
|
const key = c.req.param("key");
|
|
@@ -2225,7 +2236,7 @@ var app6 = new Hono7().get("/:name/env", async (c) => {
|
|
|
2225
2236
|
writeEnv(path, env);
|
|
2226
2237
|
return c.json({ ok: true });
|
|
2227
2238
|
});
|
|
2228
|
-
var sharedEnvApp = new Hono7().get("/", (c) => {
|
|
2239
|
+
var sharedEnvApp = new Hono7().get("/", requireAdmin, (c) => {
|
|
2229
2240
|
return c.json(readEnv(sharedEnvPath()));
|
|
2230
2241
|
}).put("/:key", requireAdmin, async (c) => {
|
|
2231
2242
|
const key = c.req.param("key");
|
|
@@ -2261,7 +2272,7 @@ var app7 = new Hono8().get("/", (c) => {
|
|
|
2261
2272
|
}).get("/all", (c) => {
|
|
2262
2273
|
const detail = c.req.query("detail") === "true";
|
|
2263
2274
|
return c.json(detail ? getAllDiscoveredExtensionsDetailed() : getAllDiscoveredExtensions());
|
|
2264
|
-
}).put("/:id/enabled", async (c) => {
|
|
2275
|
+
}).put("/:id/enabled", requireAdmin, async (c) => {
|
|
2265
2276
|
const { id } = c.req.param();
|
|
2266
2277
|
const body = await c.req.json().catch(() => null);
|
|
2267
2278
|
if (!body || typeof body.enabled !== "boolean") {
|
|
@@ -2273,7 +2284,7 @@ var app7 = new Hono8().get("/", (c) => {
|
|
|
2273
2284
|
return c.json({ error: err.message }, 404);
|
|
2274
2285
|
}
|
|
2275
2286
|
return c.json({ ok: true, requiresRestart: true });
|
|
2276
|
-
}).post("/install", async (c) => {
|
|
2287
|
+
}).post("/install", requireAdmin, async (c) => {
|
|
2277
2288
|
const body = await c.req.json();
|
|
2278
2289
|
const pkg = body.package?.trim();
|
|
2279
2290
|
if (!pkg) {
|
|
@@ -2287,7 +2298,7 @@ var app7 = new Hono8().get("/", (c) => {
|
|
|
2287
2298
|
const isValidation = message.includes("already installed") || message.includes("Invalid package");
|
|
2288
2299
|
return c.json({ error: message }, isValidation ? 400 : 500);
|
|
2289
2300
|
}
|
|
2290
|
-
}).delete("/uninstall/:package", async (c) => {
|
|
2301
|
+
}).delete("/uninstall/:package", requireAdmin, async (c) => {
|
|
2291
2302
|
const pkg = c.req.param("package");
|
|
2292
2303
|
try {
|
|
2293
2304
|
await uninstallNpmExtension(pkg);
|
|
@@ -2308,7 +2319,7 @@ async function notifyMind(mindName, message) {
|
|
|
2308
2319
|
const entry = await findMind(mindName);
|
|
2309
2320
|
if (!entry) return;
|
|
2310
2321
|
try {
|
|
2311
|
-
const { sendSystemMessage } = await import("./system-chat-
|
|
2322
|
+
const { sendSystemMessage } = await import("./system-chat-7CA2PP6A.js");
|
|
2312
2323
|
await sendSystemMessage(mindName, message);
|
|
2313
2324
|
} catch (err) {
|
|
2314
2325
|
logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
|
|
@@ -2357,11 +2368,11 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
2357
2368
|
`[file] ${senderName} sent ${filename} (${sizeStr}) \u2014 run: volute chat accept ${id}`
|
|
2358
2369
|
);
|
|
2359
2370
|
return c.json({ status: "pending", id }, 200);
|
|
2360
|
-
}).get("/:name/files/pending", async (c) => {
|
|
2371
|
+
}).get("/:name/files/pending", requireSelf(), async (c) => {
|
|
2361
2372
|
const name = c.req.param("name");
|
|
2362
2373
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
2363
2374
|
return c.json(listPending(name));
|
|
2364
|
-
}).post("/:name/files/accept", async (c) => {
|
|
2375
|
+
}).post("/:name/files/accept", requireSelf(), async (c) => {
|
|
2365
2376
|
const name = c.req.param("name");
|
|
2366
2377
|
const entry = await findMind(name);
|
|
2367
2378
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -2383,7 +2394,7 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
2383
2394
|
}
|
|
2384
2395
|
await notifyMind(result.sender, `[file] ${name} accepted ${result.filename}`);
|
|
2385
2396
|
return c.json({ ok: true, destPath: result.destPath });
|
|
2386
|
-
}).post("/:name/files/reject", async (c) => {
|
|
2397
|
+
}).post("/:name/files/reject", requireSelf(), async (c) => {
|
|
2387
2398
|
const name = c.req.param("name");
|
|
2388
2399
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
2389
2400
|
const body = await c.req.json();
|
|
@@ -2400,7 +2411,7 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
2400
2411
|
}
|
|
2401
2412
|
await notifyMind(result.sender, `[file] ${name} rejected ${result.filename}`);
|
|
2402
2413
|
return c.json({ ok: true });
|
|
2403
|
-
}).post("/:name/files/stage", async (c) => {
|
|
2414
|
+
}).post("/:name/files/stage", requireSelf(), async (c) => {
|
|
2404
2415
|
const receiverName = c.req.param("name");
|
|
2405
2416
|
const receiverEntry = await findMind(receiverName);
|
|
2406
2417
|
if (!receiverEntry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -2433,8 +2444,34 @@ var file_sharing_default = app8;
|
|
|
2433
2444
|
// packages/daemon/src/web/api/files.ts
|
|
2434
2445
|
import { mkdirSync as mkdirSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2435
2446
|
import { readdir, readFile, realpath, stat } from "fs/promises";
|
|
2436
|
-
import { extname as extname2, resolve as
|
|
2447
|
+
import { extname as extname2, resolve as resolve6 } from "path";
|
|
2437
2448
|
import { Hono as Hono10 } from "hono";
|
|
2449
|
+
|
|
2450
|
+
// packages/daemon/src/lib/util/paths.ts
|
|
2451
|
+
import { resolve as resolve5, sep } from "path";
|
|
2452
|
+
var PathTraversalError = class extends Error {
|
|
2453
|
+
constructor(base, userPath) {
|
|
2454
|
+
super(`Path "${userPath}" escapes base directory "${base}"`);
|
|
2455
|
+
this.name = "PathTraversalError";
|
|
2456
|
+
}
|
|
2457
|
+
};
|
|
2458
|
+
function resolveWithinBase(base, userPath) {
|
|
2459
|
+
const resolvedBase = resolve5(base);
|
|
2460
|
+
const target = resolve5(resolvedBase, userPath);
|
|
2461
|
+
if (target !== resolvedBase && !target.startsWith(resolvedBase + sep)) {
|
|
2462
|
+
throw new PathTraversalError(base, userPath);
|
|
2463
|
+
}
|
|
2464
|
+
return target;
|
|
2465
|
+
}
|
|
2466
|
+
function safeResolveWithinBase(base, userPath) {
|
|
2467
|
+
try {
|
|
2468
|
+
return resolveWithinBase(base, userPath);
|
|
2469
|
+
} catch {
|
|
2470
|
+
return null;
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
// packages/daemon/src/web/api/files.ts
|
|
2438
2475
|
var AVATAR_MIME2 = {
|
|
2439
2476
|
".png": "image/png",
|
|
2440
2477
|
".jpg": "image/jpeg",
|
|
@@ -2478,13 +2515,14 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2478
2515
|
return c.json({ error: "Invalid file type (png, jpg, gif, webp only)" }, 400);
|
|
2479
2516
|
}
|
|
2480
2517
|
const dir = entry.dir ?? mindDir(name);
|
|
2481
|
-
const homeDir =
|
|
2518
|
+
const homeDir = resolve6(dir, "home");
|
|
2482
2519
|
const filename = `avatar${ext}`;
|
|
2483
|
-
const avatarPath =
|
|
2520
|
+
const avatarPath = resolve6(homeDir, filename);
|
|
2484
2521
|
const config2 = readVoluteConfig(dir) ?? {};
|
|
2485
2522
|
const oldAvatar = config2.profile?.avatar;
|
|
2486
2523
|
if (oldAvatar && oldAvatar !== filename) {
|
|
2487
|
-
|
|
2524
|
+
const oldAvatarPath = safeResolveWithinBase(homeDir, oldAvatar);
|
|
2525
|
+
if (oldAvatarPath) rmSync2(oldAvatarPath, { force: true });
|
|
2488
2526
|
}
|
|
2489
2527
|
const buffer2 = Buffer.from(await file.arrayBuffer());
|
|
2490
2528
|
mkdirSync3(homeDir, { recursive: true });
|
|
@@ -2506,8 +2544,8 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2506
2544
|
const ext = extname2(config2.profile.avatar).toLowerCase();
|
|
2507
2545
|
const mime = AVATAR_MIME2[ext];
|
|
2508
2546
|
if (!mime) return c.json({ error: "Invalid avatar extension" }, 400);
|
|
2509
|
-
const homeDir =
|
|
2510
|
-
const avatarPath =
|
|
2547
|
+
const homeDir = resolve6(dir, "home");
|
|
2548
|
+
const avatarPath = resolve6(homeDir, config2.profile.avatar);
|
|
2511
2549
|
if (!avatarPath.startsWith(`${homeDir}/`)) return c.json({ error: "Invalid avatar path" }, 400);
|
|
2512
2550
|
let realAvatarPath;
|
|
2513
2551
|
try {
|
|
@@ -2535,7 +2573,7 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2535
2573
|
const name = c.req.param("name");
|
|
2536
2574
|
const entry = await findMind(name);
|
|
2537
2575
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
2538
|
-
const homeDir =
|
|
2576
|
+
const homeDir = resolve6(entry.dir ?? mindDir(name), "home");
|
|
2539
2577
|
let entries;
|
|
2540
2578
|
try {
|
|
2541
2579
|
entries = await readdir(homeDir, { withFileTypes: true });
|
|
@@ -2550,10 +2588,10 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2550
2588
|
const name = c.req.param("name");
|
|
2551
2589
|
const entry = await findMind(name);
|
|
2552
2590
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
2553
|
-
const homeDir =
|
|
2591
|
+
const homeDir = resolve6(entry.dir ?? mindDir(name), "home");
|
|
2554
2592
|
const wildcard = c.req.path.replace(new RegExp(`^.*/minds/${name}/files`), "") || "/";
|
|
2555
2593
|
const relativePath = wildcard.slice(1);
|
|
2556
|
-
const requestedPath =
|
|
2594
|
+
const requestedPath = resolve6(homeDir, relativePath);
|
|
2557
2595
|
if (requestedPath !== homeDir && !requestedPath.startsWith(`${homeDir}/`))
|
|
2558
2596
|
return c.text("Forbidden", 403);
|
|
2559
2597
|
if (relativePath.split("/").some((seg) => seg.startsWith("."))) return c.text("Forbidden", 403);
|
|
@@ -2985,16 +3023,16 @@ import { Hono as Hono12 } from "hono";
|
|
|
2985
3023
|
// packages/daemon/src/lib/mind/identity.ts
|
|
2986
3024
|
import { createHash, generateKeyPairSync, sign, verify } from "crypto";
|
|
2987
3025
|
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
2988
|
-
import { resolve as
|
|
3026
|
+
import { resolve as resolve7 } from "path";
|
|
2989
3027
|
function generateIdentity(mindDir2) {
|
|
2990
|
-
const identityDir =
|
|
3028
|
+
const identityDir = resolve7(mindDir2, ".mind/identity");
|
|
2991
3029
|
mkdirSync4(identityDir, { recursive: true });
|
|
2992
3030
|
const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
|
|
2993
3031
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
2994
3032
|
privateKeyEncoding: { type: "pkcs8", format: "pem" }
|
|
2995
3033
|
});
|
|
2996
|
-
const privatePath =
|
|
2997
|
-
const publicPath =
|
|
3034
|
+
const privatePath = resolve7(identityDir, "private.pem");
|
|
3035
|
+
const publicPath = resolve7(identityDir, "public.pem");
|
|
2998
3036
|
writeFileSync4(privatePath, privateKey, { mode: 384 });
|
|
2999
3037
|
writeFileSync4(publicPath, publicKey, { mode: 420 });
|
|
3000
3038
|
const config2 = readVoluteConfig(mindDir2) ?? {};
|
|
@@ -3009,7 +3047,7 @@ function getPublicKey(mindDir2) {
|
|
|
3009
3047
|
const config2 = readVoluteConfig(mindDir2);
|
|
3010
3048
|
const relPath = config2?.identity?.publicKey;
|
|
3011
3049
|
if (!relPath) return null;
|
|
3012
|
-
const fullPath =
|
|
3050
|
+
const fullPath = resolve7(mindDir2, relPath);
|
|
3013
3051
|
if (!existsSync4(fullPath)) return null;
|
|
3014
3052
|
return readFileSync5(fullPath, "utf-8");
|
|
3015
3053
|
}
|
|
@@ -3059,14 +3097,14 @@ var keys_default = app10;
|
|
|
3059
3097
|
// packages/daemon/src/web/api/logs.ts
|
|
3060
3098
|
import { spawn as spawn2 } from "child_process";
|
|
3061
3099
|
import { existsSync as existsSync5 } from "fs";
|
|
3062
|
-
import { resolve as
|
|
3100
|
+
import { resolve as resolve8 } from "path";
|
|
3063
3101
|
import { Hono as Hono13 } from "hono";
|
|
3064
3102
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
3065
|
-
var app11 = new Hono13().get("/:name/logs", async (c) => {
|
|
3103
|
+
var app11 = new Hono13().get("/:name/logs", requireSelf(), async (c) => {
|
|
3066
3104
|
const name = c.req.param("name");
|
|
3067
3105
|
const entry = await findMind(name);
|
|
3068
3106
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
3069
|
-
const logFile =
|
|
3107
|
+
const logFile = resolve8(stateDir(name), "logs", "mind.log");
|
|
3070
3108
|
if (!existsSync5(logFile)) {
|
|
3071
3109
|
return c.json({ error: "No log file found" }, 404);
|
|
3072
3110
|
}
|
|
@@ -3085,16 +3123,16 @@ var app11 = new Hono13().get("/:name/logs", async (c) => {
|
|
|
3085
3123
|
stream.onAbort(() => {
|
|
3086
3124
|
tail.kill();
|
|
3087
3125
|
});
|
|
3088
|
-
await new Promise((
|
|
3089
|
-
tail.on("exit",
|
|
3090
|
-
stream.onAbort(
|
|
3126
|
+
await new Promise((resolve18) => {
|
|
3127
|
+
tail.on("exit", resolve18);
|
|
3128
|
+
stream.onAbort(resolve18);
|
|
3091
3129
|
});
|
|
3092
3130
|
});
|
|
3093
|
-
}).get("/:name/logs/tail", async (c) => {
|
|
3131
|
+
}).get("/:name/logs/tail", requireSelf(), async (c) => {
|
|
3094
3132
|
const name = c.req.param("name");
|
|
3095
3133
|
const entry = await findMind(name);
|
|
3096
3134
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
3097
|
-
const logFile =
|
|
3135
|
+
const logFile = resolve8(stateDir(name), "logs", "mind.log");
|
|
3098
3136
|
if (!existsSync5(logFile)) {
|
|
3099
3137
|
return c.json({ error: "No log file found" }, 404);
|
|
3100
3138
|
}
|
|
@@ -3105,8 +3143,8 @@ var app11 = new Hono13().get("/:name/logs", async (c) => {
|
|
|
3105
3143
|
tail.stdout.on("data", (data) => {
|
|
3106
3144
|
output += data.toString();
|
|
3107
3145
|
});
|
|
3108
|
-
await new Promise((
|
|
3109
|
-
tail.on("exit",
|
|
3146
|
+
await new Promise((resolve18) => {
|
|
3147
|
+
tail.on("exit", resolve18);
|
|
3110
3148
|
});
|
|
3111
3149
|
return c.text(output);
|
|
3112
3150
|
});
|
|
@@ -3203,7 +3241,7 @@ import {
|
|
|
3203
3241
|
rmSync as rmSync4,
|
|
3204
3242
|
writeFileSync as writeFileSync7
|
|
3205
3243
|
} from "fs";
|
|
3206
|
-
import { resolve as
|
|
3244
|
+
import { basename, resolve as resolve11 } from "path";
|
|
3207
3245
|
import { zValidator as zValidator5 } from "@hono/zod-validator";
|
|
3208
3246
|
import { and as and4, desc as desc3, eq as eq5, sql as sql2 } from "drizzle-orm";
|
|
3209
3247
|
import { Hono as Hono15 } from "hono";
|
|
@@ -3248,18 +3286,18 @@ function classify(raw) {
|
|
|
3248
3286
|
|
|
3249
3287
|
// packages/daemon/src/lib/mind/consolidate.ts
|
|
3250
3288
|
import { readdirSync, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
3251
|
-
import { resolve as
|
|
3289
|
+
import { resolve as resolve9 } from "path";
|
|
3252
3290
|
async function consolidateMemory(mindDir2) {
|
|
3253
|
-
const soulPath =
|
|
3254
|
-
const memoryPath =
|
|
3255
|
-
const memoryDir =
|
|
3291
|
+
const soulPath = resolve9(mindDir2, "home/SOUL.md");
|
|
3292
|
+
const memoryPath = resolve9(mindDir2, "home/MEMORY.md");
|
|
3293
|
+
const memoryDir = resolve9(mindDir2, "home/memory");
|
|
3256
3294
|
const soul = readFileSync6(soulPath, "utf-8");
|
|
3257
3295
|
const logs = [];
|
|
3258
3296
|
try {
|
|
3259
3297
|
const files = readdirSync(memoryDir).filter((f) => /^\d{4}-\d{2}-\d{2}\.md$/.test(f)).sort();
|
|
3260
3298
|
for (const filename of files) {
|
|
3261
3299
|
const date = filename.replace(".md", "");
|
|
3262
|
-
const content2 = readFileSync6(
|
|
3300
|
+
const content2 = readFileSync6(resolve9(memoryDir, filename), "utf-8").trim();
|
|
3263
3301
|
if (content2) {
|
|
3264
3302
|
logs.push(`### ${date}
|
|
3265
3303
|
|
|
@@ -3327,7 +3365,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
|
3327
3365
|
logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
|
|
3328
3366
|
}
|
|
3329
3367
|
}
|
|
3330
|
-
const { findMind: findMind2 } = await import("./registry-
|
|
3368
|
+
const { findMind: findMind2 } = await import("./registry-GV35XFT7.js");
|
|
3331
3369
|
const variantEntry = await findMind2(variantName);
|
|
3332
3370
|
const branchName = variantEntry?.branch ?? variantName;
|
|
3333
3371
|
if (existsSync6(variantPath)) {
|
|
@@ -3379,7 +3417,7 @@ function validateBranchName(branch) {
|
|
|
3379
3417
|
import { randomUUID } from "crypto";
|
|
3380
3418
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
3381
3419
|
import { homedir } from "os";
|
|
3382
|
-
import { resolve as
|
|
3420
|
+
import { resolve as resolve10 } from "path";
|
|
3383
3421
|
function convertSession(opts) {
|
|
3384
3422
|
const lines = readFileSync7(opts.sessionPath, "utf-8").trim().split("\n");
|
|
3385
3423
|
const sessionId = randomUUID();
|
|
@@ -3495,9 +3533,9 @@ function convertSession(opts) {
|
|
|
3495
3533
|
}
|
|
3496
3534
|
}
|
|
3497
3535
|
const projectId = opts.projectDir.replace(/\//g, "-");
|
|
3498
|
-
const sdkDir =
|
|
3536
|
+
const sdkDir = resolve10(homedir(), ".claude", "projects", projectId);
|
|
3499
3537
|
mkdirSync5(sdkDir, { recursive: true });
|
|
3500
|
-
const sdkPath =
|
|
3538
|
+
const sdkPath = resolve10(sdkDir, `${sessionId}.jsonl`);
|
|
3501
3539
|
writeFileSync6(sdkPath, `${sdkEvents.join("\n")}
|
|
3502
3540
|
`);
|
|
3503
3541
|
console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
|
|
@@ -3584,7 +3622,7 @@ async function getMindStatus(name, port, registryRunning) {
|
|
|
3584
3622
|
const manager = getMindManager();
|
|
3585
3623
|
let status = "stopped";
|
|
3586
3624
|
try {
|
|
3587
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
3625
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-TTNOLIX5.js");
|
|
3588
3626
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
3589
3627
|
status = "sleeping";
|
|
3590
3628
|
}
|
|
@@ -3630,7 +3668,7 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
|
|
|
3630
3668
|
await gitExec(["commit", "-m", "initial commit"], opts);
|
|
3631
3669
|
}
|
|
3632
3670
|
async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
3633
|
-
const tempWorktree =
|
|
3671
|
+
const tempWorktree = resolve11(projectRoot, ".variants", "_template_update");
|
|
3634
3672
|
let branchExists = false;
|
|
3635
3673
|
try {
|
|
3636
3674
|
await gitExec(["rev-parse", "--verify", TEMPLATE_BRANCH], { cwd: projectRoot });
|
|
@@ -3662,15 +3700,15 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
3662
3700
|
});
|
|
3663
3701
|
}
|
|
3664
3702
|
copyTemplateToDir(composedDir, tempWorktree, mindName, manifest);
|
|
3665
|
-
const initDir =
|
|
3703
|
+
const initDir = resolve11(tempWorktree, ".init");
|
|
3666
3704
|
if (existsSync7(initDir)) {
|
|
3667
3705
|
rmSync4(initDir, { recursive: true, force: true });
|
|
3668
3706
|
}
|
|
3669
|
-
const homeDir =
|
|
3707
|
+
const homeDir = resolve11(tempWorktree, "home");
|
|
3670
3708
|
if (existsSync7(homeDir)) {
|
|
3671
3709
|
for (const entry of readdirSync2(homeDir)) {
|
|
3672
3710
|
if (entry !== "VOLUTE.md") {
|
|
3673
|
-
rmSync4(
|
|
3711
|
+
rmSync4(resolve11(homeDir, entry), { recursive: true, force: true });
|
|
3674
3712
|
}
|
|
3675
3713
|
}
|
|
3676
3714
|
}
|
|
@@ -3711,7 +3749,7 @@ async function mergeTemplateBranch(worktreeDir) {
|
|
|
3711
3749
|
async function npmInstallAsMind(cwd, mindName) {
|
|
3712
3750
|
if (isIsolationEnabled()) {
|
|
3713
3751
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
3714
|
-
await exec(cmd, args, { cwd, env: { ...process.env, HOME:
|
|
3752
|
+
await exec(cmd, args, { cwd, env: { ...process.env, HOME: resolve11(cwd, "home") } });
|
|
3715
3753
|
} else {
|
|
3716
3754
|
await exec("npm", ["install"], { cwd });
|
|
3717
3755
|
}
|
|
@@ -3762,7 +3800,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
3762
3800
|
return { ok: true };
|
|
3763
3801
|
}
|
|
3764
3802
|
async function importFromArchive(c, tempDir, nameOverride, manifest) {
|
|
3765
|
-
const extractedMindDir =
|
|
3803
|
+
const extractedMindDir = resolve11(tempDir, "mind");
|
|
3766
3804
|
if (!existsSync7(extractedMindDir)) {
|
|
3767
3805
|
return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
|
|
3768
3806
|
}
|
|
@@ -3789,9 +3827,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
3789
3827
|
}
|
|
3790
3828
|
const state = stateDir(name);
|
|
3791
3829
|
mkdirSync6(state, { recursive: true });
|
|
3792
|
-
const envJson =
|
|
3830
|
+
const envJson = resolve11(tempDir, "state/env.json");
|
|
3793
3831
|
if (existsSync7(envJson)) {
|
|
3794
|
-
cpSync(envJson,
|
|
3832
|
+
cpSync(envJson, resolve11(state, "env.json"));
|
|
3795
3833
|
}
|
|
3796
3834
|
const port = await nextPort();
|
|
3797
3835
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
@@ -3800,23 +3838,23 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
3800
3838
|
} catch (err) {
|
|
3801
3839
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
3802
3840
|
}
|
|
3803
|
-
const homeDir =
|
|
3841
|
+
const homeDir = resolve11(dest, "home");
|
|
3804
3842
|
ensureVoluteGroup();
|
|
3805
3843
|
createMindUser(name, homeDir);
|
|
3806
3844
|
chownMindDir(dest, name);
|
|
3807
3845
|
await npmInstallAsMind(dest, name);
|
|
3808
3846
|
await importHistoryFromArchive(name, tempDir);
|
|
3809
3847
|
importSessionsFromArchive(dest, tempDir);
|
|
3810
|
-
if (!existsSync7(
|
|
3848
|
+
if (!existsSync7(resolve11(dest, ".git"))) {
|
|
3811
3849
|
try {
|
|
3812
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
3850
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
|
|
3813
3851
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
3814
3852
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
3815
3853
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
3816
3854
|
await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
|
|
3817
3855
|
} catch (err) {
|
|
3818
3856
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
3819
|
-
rmSync4(
|
|
3857
|
+
rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
3820
3858
|
}
|
|
3821
3859
|
}
|
|
3822
3860
|
chownMindDir(dest, name);
|
|
@@ -3849,22 +3887,22 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3849
3887
|
try {
|
|
3850
3888
|
copyTemplateToDir(composedDir, dest, name, templateManifest);
|
|
3851
3889
|
applyInitFiles(dest);
|
|
3852
|
-
const extractedHome =
|
|
3890
|
+
const extractedHome = resolve11(extractedMindDir, "home");
|
|
3853
3891
|
if (existsSync7(extractedHome)) {
|
|
3854
|
-
cpSync(extractedHome,
|
|
3892
|
+
cpSync(extractedHome, resolve11(dest, "home"), { recursive: true });
|
|
3855
3893
|
}
|
|
3856
|
-
const extractedMindInternal =
|
|
3894
|
+
const extractedMindInternal = resolve11(extractedMindDir, ".mind");
|
|
3857
3895
|
if (existsSync7(extractedMindInternal)) {
|
|
3858
|
-
cpSync(extractedMindInternal,
|
|
3896
|
+
cpSync(extractedMindInternal, resolve11(dest, ".mind"), { recursive: true });
|
|
3859
3897
|
}
|
|
3860
|
-
const identityDir =
|
|
3898
|
+
const identityDir = resolve11(dest, ".mind/identity");
|
|
3861
3899
|
let publicKeyPem;
|
|
3862
|
-
if (!manifest.includes.identity || !existsSync7(
|
|
3900
|
+
if (!manifest.includes.identity || !existsSync7(resolve11(identityDir, "private.pem"))) {
|
|
3863
3901
|
({ publicKeyPem } = generateIdentity(dest));
|
|
3864
3902
|
} else {
|
|
3865
|
-
publicKeyPem = readFileSync8(
|
|
3903
|
+
publicKeyPem = readFileSync8(resolve11(identityDir, "public.pem"), "utf-8");
|
|
3866
3904
|
}
|
|
3867
|
-
const promptsPath =
|
|
3905
|
+
const promptsPath = resolve11(dest, "home/.config/prompts.json");
|
|
3868
3906
|
if (!existsSync7(promptsPath)) {
|
|
3869
3907
|
const mindPrompts = await getMindPromptDefaults();
|
|
3870
3908
|
writeFileSync7(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
|
|
@@ -3872,13 +3910,13 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3872
3910
|
}
|
|
3873
3911
|
const state = stateDir(name);
|
|
3874
3912
|
mkdirSync6(state, { recursive: true });
|
|
3875
|
-
const envJson =
|
|
3913
|
+
const envJson = resolve11(tempDir, "state/env.json");
|
|
3876
3914
|
if (existsSync7(envJson)) {
|
|
3877
|
-
cpSync(envJson,
|
|
3915
|
+
cpSync(envJson, resolve11(state, "env.json"));
|
|
3878
3916
|
}
|
|
3879
3917
|
const port = await nextPort();
|
|
3880
3918
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
3881
|
-
const homeDir =
|
|
3919
|
+
const homeDir = resolve11(dest, "home");
|
|
3882
3920
|
ensureVoluteGroup();
|
|
3883
3921
|
createMindUser(name, homeDir);
|
|
3884
3922
|
chownMindDir(dest, name);
|
|
@@ -3891,7 +3929,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3891
3929
|
await initTemplateBranch(dest, composedDir, templateManifest, name, env);
|
|
3892
3930
|
} catch (err) {
|
|
3893
3931
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
3894
|
-
rmSync4(
|
|
3932
|
+
rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
3895
3933
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
3896
3934
|
}
|
|
3897
3935
|
const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
|
|
@@ -3934,7 +3972,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3934
3972
|
}
|
|
3935
3973
|
}
|
|
3936
3974
|
async function importHistoryFromArchive(name, tempDir) {
|
|
3937
|
-
const historyJsonl =
|
|
3975
|
+
const historyJsonl = resolve11(tempDir, "history.jsonl");
|
|
3938
3976
|
if (!existsSync7(historyJsonl)) return;
|
|
3939
3977
|
try {
|
|
3940
3978
|
const db = await getDb();
|
|
@@ -3974,13 +4012,13 @@ async function importHistoryFromArchive(name, tempDir) {
|
|
|
3974
4012
|
}
|
|
3975
4013
|
}
|
|
3976
4014
|
function importSessionsFromArchive(dest, tempDir) {
|
|
3977
|
-
const sessionsDir =
|
|
4015
|
+
const sessionsDir = resolve11(tempDir, "sessions");
|
|
3978
4016
|
if (!existsSync7(sessionsDir)) return;
|
|
3979
4017
|
try {
|
|
3980
|
-
const destSessions =
|
|
4018
|
+
const destSessions = resolve11(dest, ".mind/sessions");
|
|
3981
4019
|
mkdirSync6(destSessions, { recursive: true });
|
|
3982
4020
|
for (const file of readdirSync2(sessionsDir)) {
|
|
3983
|
-
cpSync(
|
|
4021
|
+
cpSync(resolve11(sessionsDir, file), resolve11(destSessions, file));
|
|
3984
4022
|
}
|
|
3985
4023
|
} catch (err) {
|
|
3986
4024
|
logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
|
|
@@ -4041,7 +4079,7 @@ async function proxyToMind(c, path) {
|
|
|
4041
4079
|
var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", createMindSchema), async (c) => {
|
|
4042
4080
|
const body = c.req.valid("json");
|
|
4043
4081
|
const { name } = body;
|
|
4044
|
-
const template = body.template ?? resolveTemplate(body.model);
|
|
4082
|
+
const template = body.template ?? await resolveTemplate(body.model);
|
|
4045
4083
|
const nameErr = validateMindName(name);
|
|
4046
4084
|
if (nameErr) return c.json({ error: nameErr }, 400);
|
|
4047
4085
|
if (await findMind(name)) return c.json({ error: `Mind already exists: ${name}` }, 409);
|
|
@@ -4055,7 +4093,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4055
4093
|
applyInitFiles(dest);
|
|
4056
4094
|
const { publicKeyPem } = generateIdentity(dest);
|
|
4057
4095
|
{
|
|
4058
|
-
const { readGlobalConfig: readGlobal } = await import("./setup-
|
|
4096
|
+
const { readGlobalConfig: readGlobal } = await import("./setup-OTEC3ZPM.js");
|
|
4059
4097
|
const mindDefaults = readGlobal().mindDefaults;
|
|
4060
4098
|
const config2 = readVoluteConfig(dest);
|
|
4061
4099
|
if (!config2) throw new Error("Failed to read volute.json after identity generation");
|
|
@@ -4092,7 +4130,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4092
4130
|
}
|
|
4093
4131
|
writeVoluteConfig(dest, config2);
|
|
4094
4132
|
const modelId = body.model ?? cog?.model;
|
|
4095
|
-
const sdkConfigPath =
|
|
4133
|
+
const sdkConfigPath = resolve11(dest, "home/.config/config.json");
|
|
4096
4134
|
if (modelId || cog?.compaction) {
|
|
4097
4135
|
const existing = existsSync7(sdkConfigPath) ? JSON.parse(readFileSync8(sdkConfigPath, "utf-8")) : {};
|
|
4098
4136
|
if (modelId) {
|
|
@@ -4107,7 +4145,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4107
4145
|
}
|
|
4108
4146
|
const mindPrompts = await getMindPromptDefaults();
|
|
4109
4147
|
writeFileSync7(
|
|
4110
|
-
|
|
4148
|
+
resolve11(dest, "home/.config/prompts.json"),
|
|
4111
4149
|
`${JSON.stringify(mindPrompts, null, 2)}
|
|
4112
4150
|
`
|
|
4113
4151
|
);
|
|
@@ -4119,7 +4157,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4119
4157
|
} catch (err) {
|
|
4120
4158
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
4121
4159
|
}
|
|
4122
|
-
const homeDir =
|
|
4160
|
+
const homeDir = resolve11(dest, "home");
|
|
4123
4161
|
ensureVoluteGroup();
|
|
4124
4162
|
createMindUser(name, homeDir);
|
|
4125
4163
|
chownMindDir(dest, name);
|
|
@@ -4132,7 +4170,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4132
4170
|
await initTemplateBranch(dest, composedDir, manifest, name, env);
|
|
4133
4171
|
} catch (err) {
|
|
4134
4172
|
logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
|
|
4135
|
-
rmSync4(
|
|
4173
|
+
rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
4136
4174
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
4137
4175
|
}
|
|
4138
4176
|
chownMindDir(dest, name);
|
|
@@ -4142,11 +4180,11 @@ The human who planted you described you as: "${body.description}"
|
|
|
4142
4180
|
` : "";
|
|
4143
4181
|
const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
|
|
4144
4182
|
const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
|
|
4145
|
-
writeFileSync7(
|
|
4183
|
+
writeFileSync7(resolve11(dest, "home/SOUL.md"), seedSoul);
|
|
4146
4184
|
}
|
|
4147
4185
|
let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
|
|
4148
4186
|
if (body.stage === "seed" && !body.skills) {
|
|
4149
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
4187
|
+
const { isImagegenEnabled } = await import("./setup-OTEC3ZPM.js");
|
|
4150
4188
|
if (isImagegenEnabled()) {
|
|
4151
4189
|
skillSet = [...skillSet, "imagegen"];
|
|
4152
4190
|
}
|
|
@@ -4164,7 +4202,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4164
4202
|
try {
|
|
4165
4203
|
const spiritEntry = await findMind("volute");
|
|
4166
4204
|
if (spiritEntry) {
|
|
4167
|
-
const { spiritDir } = await import("./spirit-
|
|
4205
|
+
const { spiritDir } = await import("./spirit-T6GK5GEP.js");
|
|
4168
4206
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
4169
4207
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
4170
4208
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -4179,7 +4217,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4179
4217
|
});
|
|
4180
4218
|
spiritConfig.schedules = schedules;
|
|
4181
4219
|
writeVoluteConfig(sDir, spiritConfig);
|
|
4182
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
4220
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-PDARH4CE.js");
|
|
4183
4221
|
getScheduler2().loadSchedules("volute", sDir);
|
|
4184
4222
|
}
|
|
4185
4223
|
}
|
|
@@ -4190,11 +4228,11 @@ The human who planted you described you as: "${body.description}"
|
|
|
4190
4228
|
if (body.stage !== "seed") {
|
|
4191
4229
|
const customSoul = await getPromptIfCustom("default_soul");
|
|
4192
4230
|
if (customSoul) {
|
|
4193
|
-
writeFileSync7(
|
|
4231
|
+
writeFileSync7(resolve11(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
|
|
4194
4232
|
}
|
|
4195
4233
|
const customMemory = await getPromptIfCustom("default_memory");
|
|
4196
4234
|
if (customMemory) {
|
|
4197
|
-
writeFileSync7(
|
|
4235
|
+
writeFileSync7(resolve11(dest, "home/MEMORY.md"), customMemory);
|
|
4198
4236
|
}
|
|
4199
4237
|
}
|
|
4200
4238
|
publishPublicKey(name, publicKeyPem).catch(
|
|
@@ -4243,12 +4281,12 @@ The human who planted you described you as: "${body.description}"
|
|
|
4243
4281
|
return importFromArchive(c, body.archivePath, body.name, body.manifest);
|
|
4244
4282
|
}
|
|
4245
4283
|
const wsDir = body.workspacePath;
|
|
4246
|
-
if (!wsDir || !existsSync7(
|
|
4284
|
+
if (!wsDir || !existsSync7(resolve11(wsDir, "SOUL.md")) || !existsSync7(resolve11(wsDir, "IDENTITY.md"))) {
|
|
4247
4285
|
return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
|
|
4248
4286
|
}
|
|
4249
|
-
const soul = readFileSync8(
|
|
4250
|
-
const identity = readFileSync8(
|
|
4251
|
-
const userPath =
|
|
4287
|
+
const soul = readFileSync8(resolve11(wsDir, "SOUL.md"), "utf-8");
|
|
4288
|
+
const identity = readFileSync8(resolve11(wsDir, "IDENTITY.md"), "utf-8");
|
|
4289
|
+
const userPath = resolve11(wsDir, "USER.md");
|
|
4252
4290
|
const user = existsSync7(userPath) ? readFileSync8(userPath, "utf-8") : "";
|
|
4253
4291
|
const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
|
|
4254
4292
|
const template = body.template ?? "claude";
|
|
@@ -4276,26 +4314,26 @@ ${user.trimEnd()}
|
|
|
4276
4314
|
copyTemplateToDir(composedDir, dest, name, manifest);
|
|
4277
4315
|
applyInitFiles(dest);
|
|
4278
4316
|
const { publicKeyPem: importPublicKey } = generateIdentity(dest);
|
|
4279
|
-
writeFileSync7(
|
|
4280
|
-
const wsMemoryPath =
|
|
4317
|
+
writeFileSync7(resolve11(dest, "home/SOUL.md"), mergedSoul);
|
|
4318
|
+
const wsMemoryPath = resolve11(wsDir, "MEMORY.md");
|
|
4281
4319
|
const hasMemory = existsSync7(wsMemoryPath);
|
|
4282
4320
|
if (hasMemory) {
|
|
4283
4321
|
const existingMemory = readFileSync8(wsMemoryPath, "utf-8");
|
|
4284
4322
|
writeFileSync7(
|
|
4285
|
-
|
|
4323
|
+
resolve11(dest, "home/MEMORY.md"),
|
|
4286
4324
|
`${existingMemory.trimEnd()}${mergedMemoryExtra}`
|
|
4287
4325
|
);
|
|
4288
4326
|
} else if (user) {
|
|
4289
|
-
writeFileSync7(
|
|
4327
|
+
writeFileSync7(resolve11(dest, "home/MEMORY.md"), `${user.trimEnd()}
|
|
4290
4328
|
`);
|
|
4291
4329
|
}
|
|
4292
|
-
const wsMemoryDir =
|
|
4330
|
+
const wsMemoryDir = resolve11(wsDir, "memory");
|
|
4293
4331
|
let dailyLogCount = 0;
|
|
4294
4332
|
if (existsSync7(wsMemoryDir)) {
|
|
4295
|
-
const destMemoryDir =
|
|
4333
|
+
const destMemoryDir = resolve11(dest, "home/memory");
|
|
4296
4334
|
const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
|
|
4297
4335
|
for (const file of files) {
|
|
4298
|
-
cpSync(
|
|
4336
|
+
cpSync(resolve11(wsMemoryDir, file), resolve11(destMemoryDir, file));
|
|
4299
4337
|
}
|
|
4300
4338
|
dailyLogCount = files.length;
|
|
4301
4339
|
}
|
|
@@ -4306,7 +4344,7 @@ ${user.trimEnd()}
|
|
|
4306
4344
|
} catch (err) {
|
|
4307
4345
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
4308
4346
|
}
|
|
4309
|
-
const homeDir =
|
|
4347
|
+
const homeDir = resolve11(dest, "home");
|
|
4310
4348
|
ensureVoluteGroup();
|
|
4311
4349
|
createMindUser(name, homeDir);
|
|
4312
4350
|
chownMindDir(dest, name);
|
|
@@ -4314,20 +4352,20 @@ ${user.trimEnd()}
|
|
|
4314
4352
|
if (!hasMemory && dailyLogCount > 0) {
|
|
4315
4353
|
await consolidateMemory(dest);
|
|
4316
4354
|
}
|
|
4317
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
4355
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
|
|
4318
4356
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
4319
4357
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
4320
4358
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
4321
4359
|
await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
|
|
4322
|
-
const sessionFile = body.sessionPath ?
|
|
4360
|
+
const sessionFile = body.sessionPath ? resolve11(body.sessionPath) : findOpenClawSession(wsDir);
|
|
4323
4361
|
if (sessionFile && existsSync7(sessionFile)) {
|
|
4324
4362
|
if (template === "pi") {
|
|
4325
4363
|
importPiSession(sessionFile, dest);
|
|
4326
4364
|
} else if (template === "claude") {
|
|
4327
4365
|
const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
|
|
4328
|
-
const mindRuntimeDir =
|
|
4366
|
+
const mindRuntimeDir = resolve11(dest, ".mind");
|
|
4329
4367
|
mkdirSync6(mindRuntimeDir, { recursive: true });
|
|
4330
|
-
writeFileSync7(
|
|
4368
|
+
writeFileSync7(resolve11(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
|
|
4331
4369
|
}
|
|
4332
4370
|
}
|
|
4333
4371
|
importOpenClawConnectors(name, dest);
|
|
@@ -4368,7 +4406,7 @@ ${user.trimEnd()}
|
|
|
4368
4406
|
const minds = await Promise.all(
|
|
4369
4407
|
entries.map(async (entry) => {
|
|
4370
4408
|
const mindStatus = await getMindStatus(entry.name, entry.port, entry.running);
|
|
4371
|
-
const hasPages = existsSync7(
|
|
4409
|
+
const hasPages = existsSync7(resolve11(mindDir(entry.name), "home", "pages"));
|
|
4372
4410
|
return {
|
|
4373
4411
|
...entry,
|
|
4374
4412
|
...mindStatus,
|
|
@@ -4397,9 +4435,9 @@ ${user.trimEnd()}
|
|
|
4397
4435
|
return { name: s.name, port: s.port, status: variantStatus };
|
|
4398
4436
|
})
|
|
4399
4437
|
);
|
|
4400
|
-
const hasPages = existsSync7(
|
|
4438
|
+
const hasPages = existsSync7(resolve11(mindDir(name), "home", "pages"));
|
|
4401
4439
|
return c.json({ ...entry, ...mindStatus, variants: variantStatuses, hasPages });
|
|
4402
|
-
}).get("/:name/context", async (c) => proxyToMind(c, "context")).get("/:name/context/messages", async (c) => proxyToMind(c, "context/messages")).post("/:name/start", requireSelf(), async (c) => {
|
|
4440
|
+
}).get("/:name/context", requireSelf(), async (c) => proxyToMind(c, "context")).get("/:name/context/messages", requireSelf(), async (c) => proxyToMind(c, "context/messages")).post("/:name/start", requireSelf(), async (c) => {
|
|
4403
4441
|
const name = c.req.param("name");
|
|
4404
4442
|
const entry = await findMind(name);
|
|
4405
4443
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -4444,7 +4482,7 @@ ${user.trimEnd()}
|
|
|
4444
4482
|
const manager = getMindManager();
|
|
4445
4483
|
try {
|
|
4446
4484
|
if (context?.type === "reload") {
|
|
4447
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4485
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-TTNOLIX5.js");
|
|
4448
4486
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
4449
4487
|
if (sleepState?.sleeping) {
|
|
4450
4488
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -4539,7 +4577,7 @@ ${user.trimEnd()}
|
|
|
4539
4577
|
const name = c.req.param("name");
|
|
4540
4578
|
const entry = await findMind(name);
|
|
4541
4579
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4542
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4580
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-TTNOLIX5.js");
|
|
4543
4581
|
const sm = getSleepManagerIfReady2();
|
|
4544
4582
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4545
4583
|
return c.json(sm.getState(name));
|
|
@@ -4547,7 +4585,7 @@ ${user.trimEnd()}
|
|
|
4547
4585
|
const name = c.req.param("name");
|
|
4548
4586
|
const entry = await findMind(name);
|
|
4549
4587
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4550
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4588
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-TTNOLIX5.js");
|
|
4551
4589
|
const sm = getSleepManagerIfReady2();
|
|
4552
4590
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4553
4591
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -4567,7 +4605,7 @@ ${user.trimEnd()}
|
|
|
4567
4605
|
const name = c.req.param("name");
|
|
4568
4606
|
const entry = await findMind(name);
|
|
4569
4607
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4570
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4608
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-TTNOLIX5.js");
|
|
4571
4609
|
const sm = getSleepManagerIfReady2();
|
|
4572
4610
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4573
4611
|
const sleepState = sm.getState(name);
|
|
@@ -4582,7 +4620,7 @@ ${user.trimEnd()}
|
|
|
4582
4620
|
const name = c.req.param("name");
|
|
4583
4621
|
const entry = await findMind(name);
|
|
4584
4622
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4585
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4623
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-TTNOLIX5.js");
|
|
4586
4624
|
const sm = getSleepManagerIfReady2();
|
|
4587
4625
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4588
4626
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -4597,10 +4635,10 @@ ${user.trimEnd()}
|
|
|
4597
4635
|
const profile = config2.profile ?? {};
|
|
4598
4636
|
if (body.displayName !== void 0) profile.displayName = body.displayName;
|
|
4599
4637
|
if (body.description !== void 0) profile.description = body.description;
|
|
4600
|
-
if (body.avatar !== void 0) profile.avatar = body.avatar;
|
|
4638
|
+
if (body.avatar !== void 0) profile.avatar = basename(body.avatar);
|
|
4601
4639
|
config2.profile = profile;
|
|
4602
4640
|
writeVoluteConfig(dir, config2);
|
|
4603
|
-
const { syncMindProfile: syncMindProfile2 } = await import("./auth-
|
|
4641
|
+
const { syncMindProfile: syncMindProfile2 } = await import("./auth-X6ZITZ7D.js");
|
|
4604
4642
|
await syncMindProfile2(name, profile);
|
|
4605
4643
|
broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
|
|
4606
4644
|
return c.json({ ok: true });
|
|
@@ -4640,14 +4678,14 @@ ${user.trimEnd()}
|
|
|
4640
4678
|
return c.json({ output: "" });
|
|
4641
4679
|
}
|
|
4642
4680
|
const dir = entry.dir ?? mindDir(name);
|
|
4643
|
-
const soulPath =
|
|
4644
|
-
const memoryPath =
|
|
4681
|
+
const soulPath = resolve11(dir, "home/SOUL.md");
|
|
4682
|
+
const memoryPath = resolve11(dir, "home/MEMORY.md");
|
|
4645
4683
|
const soulCustom = existsSync7(soulPath) && !readFileSync8(soulPath, "utf-8").includes(ORIENTATION_MARKER);
|
|
4646
4684
|
const memoryWritten = existsSync7(memoryPath) && readFileSync8(memoryPath, "utf-8").trim().length > 0;
|
|
4647
4685
|
const config2 = readVoluteConfig(dir);
|
|
4648
4686
|
const displayNameSet = !!config2?.profile?.displayName;
|
|
4649
4687
|
const avatarSet = !!config2?.profile?.avatar;
|
|
4650
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
4688
|
+
const { isImagegenEnabled } = await import("./setup-OTEC3ZPM.js");
|
|
4651
4689
|
const imagegenEnabled = isImagegenEnabled();
|
|
4652
4690
|
const done = [];
|
|
4653
4691
|
const remaining = [];
|
|
@@ -4685,7 +4723,7 @@ ${user.trimEnd()}
|
|
|
4685
4723
|
try {
|
|
4686
4724
|
const spiritEntry = await findMind("volute");
|
|
4687
4725
|
if (spiritEntry) {
|
|
4688
|
-
const { spiritDir } = await import("./spirit-
|
|
4726
|
+
const { spiritDir } = await import("./spirit-T6GK5GEP.js");
|
|
4689
4727
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
4690
4728
|
const spiritConfig = readVoluteConfig(sDir);
|
|
4691
4729
|
if (spiritConfig?.schedules) {
|
|
@@ -4693,7 +4731,7 @@ ${user.trimEnd()}
|
|
|
4693
4731
|
spiritConfig.schedules = spiritConfig.schedules.filter((s) => s.id !== nurtureId);
|
|
4694
4732
|
if (spiritConfig.schedules.length === 0) spiritConfig.schedules = void 0;
|
|
4695
4733
|
writeVoluteConfig(sDir, spiritConfig);
|
|
4696
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
4734
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-PDARH4CE.js");
|
|
4697
4735
|
getScheduler2().loadSchedules("volute", sDir);
|
|
4698
4736
|
}
|
|
4699
4737
|
}
|
|
@@ -4748,16 +4786,16 @@ ${user.trimEnd()}
|
|
|
4748
4786
|
const template = body.template ?? entry.template ?? "claude";
|
|
4749
4787
|
const UPGRADE_BRANCH = "upgrade";
|
|
4750
4788
|
const upgradeVariantName = `${mindName}-upgrade`;
|
|
4751
|
-
const worktreeDir =
|
|
4789
|
+
const worktreeDir = resolve11(dir, ".variants", UPGRADE_BRANCH);
|
|
4752
4790
|
if (body.abort) {
|
|
4753
4791
|
if (!existsSync7(worktreeDir)) {
|
|
4754
4792
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
4755
4793
|
}
|
|
4756
4794
|
try {
|
|
4757
4795
|
try {
|
|
4758
|
-
const gitDirContent = readFileSync8(
|
|
4796
|
+
const gitDirContent = readFileSync8(resolve11(worktreeDir, ".git"), "utf-8").trim();
|
|
4759
4797
|
const gitDir = gitDirContent.replace("gitdir: ", "");
|
|
4760
|
-
if (existsSync7(
|
|
4798
|
+
if (existsSync7(resolve11(gitDir, "MERGE_HEAD"))) {
|
|
4761
4799
|
await gitExec(["merge", "--abort"], { cwd: worktreeDir });
|
|
4762
4800
|
}
|
|
4763
4801
|
} catch {
|
|
@@ -4840,7 +4878,7 @@ ${user.trimEnd()}
|
|
|
4840
4878
|
}
|
|
4841
4879
|
if (body.diff) {
|
|
4842
4880
|
try {
|
|
4843
|
-
if (!existsSync7(
|
|
4881
|
+
if (!existsSync7(resolve11(dir, ".git"))) {
|
|
4844
4882
|
return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
|
|
4845
4883
|
}
|
|
4846
4884
|
await updateTemplateBranch(dir, template, mindName);
|
|
@@ -4864,16 +4902,16 @@ ${user.trimEnd()}
|
|
|
4864
4902
|
409
|
|
4865
4903
|
);
|
|
4866
4904
|
}
|
|
4867
|
-
if (!existsSync7(
|
|
4905
|
+
if (!existsSync7(resolve11(dir, ".git"))) {
|
|
4868
4906
|
try {
|
|
4869
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
4907
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dir, "home") } : void 0;
|
|
4870
4908
|
await gitExec(["init"], { cwd: dir, mindName, env });
|
|
4871
4909
|
await configureGitIdentity(mindName, { cwd: dir, mindName, env });
|
|
4872
4910
|
await gitExec(["add", "-A"], { cwd: dir, mindName, env });
|
|
4873
4911
|
await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
|
|
4874
4912
|
chownMindDir(dir, mindName);
|
|
4875
4913
|
} catch (err) {
|
|
4876
|
-
rmSync4(
|
|
4914
|
+
rmSync4(resolve11(dir, ".git"), { recursive: true, force: true });
|
|
4877
4915
|
return c.json(
|
|
4878
4916
|
{
|
|
4879
4917
|
error: `Git initialization failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -4888,7 +4926,7 @@ ${user.trimEnd()}
|
|
|
4888
4926
|
} catch {
|
|
4889
4927
|
}
|
|
4890
4928
|
await updateTemplateBranch(dir, template, mindName);
|
|
4891
|
-
const parentDir =
|
|
4929
|
+
const parentDir = resolve11(dir, ".variants");
|
|
4892
4930
|
if (!existsSync7(parentDir)) {
|
|
4893
4931
|
mkdirSync6(parentDir, { recursive: true });
|
|
4894
4932
|
}
|
|
@@ -5007,13 +5045,13 @@ ${user.trimEnd()}
|
|
|
5007
5045
|
}
|
|
5008
5046
|
const result = await getMessagesPaginated(convId, { before, limit });
|
|
5009
5047
|
return c.json({ items: result.messages, hasMore: result.hasMore });
|
|
5010
|
-
}).get("/:name/budget", async (c) => {
|
|
5048
|
+
}).get("/:name/budget", requireSelf(), async (c) => {
|
|
5011
5049
|
const name = c.req.param("name");
|
|
5012
5050
|
const baseName = await getBaseName(name);
|
|
5013
5051
|
const usage = getTokenBudget().getUsage(baseName);
|
|
5014
5052
|
if (!usage) return c.json({ error: "No budget configured" }, 404);
|
|
5015
5053
|
return c.json(usage);
|
|
5016
|
-
}).get("/:name/config", async (c) => {
|
|
5054
|
+
}).get("/:name/config", requireSelf(), async (c) => {
|
|
5017
5055
|
const name = c.req.param("name");
|
|
5018
5056
|
const entry = await findMind(name);
|
|
5019
5057
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -5021,7 +5059,7 @@ ${user.trimEnd()}
|
|
|
5021
5059
|
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
5022
5060
|
let config2 = readVoluteConfig(dir);
|
|
5023
5061
|
if (!config2 && entry.template === "pi") {
|
|
5024
|
-
const piConfigPath =
|
|
5062
|
+
const piConfigPath = resolve11(dir, "home/.config/config.json");
|
|
5025
5063
|
if (existsSync7(piConfigPath)) {
|
|
5026
5064
|
try {
|
|
5027
5065
|
config2 = JSON.parse(readFileSync8(piConfigPath, "utf-8"));
|
|
@@ -5030,7 +5068,7 @@ ${user.trimEnd()}
|
|
|
5030
5068
|
}
|
|
5031
5069
|
}
|
|
5032
5070
|
let templateConfig = {};
|
|
5033
|
-
const configJsonPath =
|
|
5071
|
+
const configJsonPath = resolve11(dir, "home/.config/config.json");
|
|
5034
5072
|
if (existsSync7(configJsonPath)) {
|
|
5035
5073
|
try {
|
|
5036
5074
|
templateConfig = JSON.parse(readFileSync8(configJsonPath, "utf-8"));
|
|
@@ -5122,12 +5160,12 @@ ${user.trimEnd()}
|
|
|
5122
5160
|
}
|
|
5123
5161
|
writeVoluteConfig(dir, existing);
|
|
5124
5162
|
if (body.unescapeNewlines !== void 0) {
|
|
5125
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
5163
|
+
const { clearEchoTextCache } = await import("./echo-text-JUNRP4ER.js");
|
|
5126
5164
|
clearEchoTextCache(name);
|
|
5127
5165
|
}
|
|
5128
5166
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.maxThinkingTokens !== void 0 || body.compaction !== void 0;
|
|
5129
5167
|
if (needsConfigJson) {
|
|
5130
|
-
const configJsonPath =
|
|
5168
|
+
const configJsonPath = resolve11(dir, "home/.config/config.json");
|
|
5131
5169
|
let templateConfig = {};
|
|
5132
5170
|
if (existsSync7(configJsonPath)) {
|
|
5133
5171
|
try {
|
|
@@ -5199,7 +5237,7 @@ ${user.trimEnd()}
|
|
|
5199
5237
|
}
|
|
5200
5238
|
if (entry.mindType === "spirit" && body.model !== void 0) {
|
|
5201
5239
|
try {
|
|
5202
|
-
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-
|
|
5240
|
+
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-OTEC3ZPM.js");
|
|
5203
5241
|
const globalConfig = readGlobalConfig2();
|
|
5204
5242
|
globalConfig.spiritModel = body.model;
|
|
5205
5243
|
writeGlobalConfig2(globalConfig);
|
|
@@ -5209,7 +5247,7 @@ ${user.trimEnd()}
|
|
|
5209
5247
|
}
|
|
5210
5248
|
return c.json({ ok: true });
|
|
5211
5249
|
}
|
|
5212
|
-
).get("/:name/delivery/pending", async (c) => {
|
|
5250
|
+
).get("/:name/delivery/pending", requireSelf(), async (c) => {
|
|
5213
5251
|
const name = c.req.param("name");
|
|
5214
5252
|
const baseName = await getBaseName(name);
|
|
5215
5253
|
try {
|
|
@@ -5227,7 +5265,7 @@ ${user.trimEnd()}
|
|
|
5227
5265
|
if (!body.systemPrompt || !body.message) {
|
|
5228
5266
|
return c.json({ error: "systemPrompt and message required" }, 400);
|
|
5229
5267
|
}
|
|
5230
|
-
const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-
|
|
5268
|
+
const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-EVLKMAJD.js");
|
|
5231
5269
|
if (!isAiConfigured()) {
|
|
5232
5270
|
return c.json({ error: "AI service not configured" }, 503);
|
|
5233
5271
|
}
|
|
@@ -5409,7 +5447,7 @@ ${user.trimEnd()}
|
|
|
5409
5447
|
}
|
|
5410
5448
|
}
|
|
5411
5449
|
return c.json({ ok: true });
|
|
5412
|
-
}).get("/:name/events", async (c) => {
|
|
5450
|
+
}).get("/:name/events", requireSelf(), async (c) => {
|
|
5413
5451
|
const name = c.req.param("name");
|
|
5414
5452
|
const baseName = await getBaseName(name);
|
|
5415
5453
|
const entry = await findMind(baseName);
|
|
@@ -5491,7 +5529,7 @@ ${user.trimEnd()}
|
|
|
5491
5529
|
return c.json({ error: "Failed to persist" }, 500);
|
|
5492
5530
|
}
|
|
5493
5531
|
return c.json({ ok: true });
|
|
5494
|
-
}).get("/:name/history/sessions", async (c) => {
|
|
5532
|
+
}).get("/:name/history/sessions", requireSelf(), async (c) => {
|
|
5495
5533
|
const name = c.req.param("name");
|
|
5496
5534
|
const db = await getDb();
|
|
5497
5535
|
const rows = await db.select({
|
|
@@ -5502,18 +5540,18 @@ ${user.trimEnd()}
|
|
|
5502
5540
|
tool_count: sql2`SUM(CASE WHEN ${mindHistory.type}='tool_use' THEN 1 ELSE 0 END)`
|
|
5503
5541
|
}).from(mindHistory).where(and4(eq5(mindHistory.mind, name), sql2`${mindHistory.session} IS NOT NULL`)).groupBy(mindHistory.session).orderBy(sql2`MIN(${mindHistory.created_at}) DESC`);
|
|
5504
5542
|
return c.json(rows);
|
|
5505
|
-
}).get("/:name/history/channels", async (c) => {
|
|
5543
|
+
}).get("/:name/history/channels", requireSelf(), async (c) => {
|
|
5506
5544
|
const name = c.req.param("name");
|
|
5507
5545
|
const db = await getDb();
|
|
5508
5546
|
const rows = await db.selectDistinct({ channel: mindHistory.channel }).from(mindHistory).where(eq5(mindHistory.mind, name));
|
|
5509
5547
|
return c.json(rows.map((r) => r.channel));
|
|
5510
|
-
}).get("/:name/history/export", async (c) => {
|
|
5548
|
+
}).get("/:name/history/export", requireSelf(), async (c) => {
|
|
5511
5549
|
const name = c.req.param("name");
|
|
5512
5550
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
5513
5551
|
const db = await getDb();
|
|
5514
5552
|
const rows = await db.select().from(mindHistory).where(eq5(mindHistory.mind, name));
|
|
5515
5553
|
return c.json(rows);
|
|
5516
|
-
}).get("/:name/history/turn", async (c) => {
|
|
5554
|
+
}).get("/:name/history/turn", requireSelf(), async (c) => {
|
|
5517
5555
|
const name = c.req.param("name");
|
|
5518
5556
|
const turnId = c.req.query("turn_id");
|
|
5519
5557
|
const detail = c.req.query("detail") === "1";
|
|
@@ -5540,7 +5578,7 @@ ${user.trimEnd()}
|
|
|
5540
5578
|
).orderBy(mindHistory.id);
|
|
5541
5579
|
}
|
|
5542
5580
|
return c.json(rows);
|
|
5543
|
-
}).get("/:name/history/cross-session", async (c) => {
|
|
5581
|
+
}).get("/:name/history/cross-session", requireSelf(), async (c) => {
|
|
5544
5582
|
const name = c.req.param("name");
|
|
5545
5583
|
const currentSession = c.req.query("session");
|
|
5546
5584
|
const db = await getDb();
|
|
@@ -5596,7 +5634,7 @@ ${lines.join("\n")}` });
|
|
|
5596
5634
|
const maxId = notices.reduce((m, n) => Math.max(m, n.id), 0);
|
|
5597
5635
|
noticeDrainWatermarks.set(`${baseName}:${session}`, maxId);
|
|
5598
5636
|
return c.json({ context: formatNotices(notices), notices });
|
|
5599
|
-
}).get("/:name/history", async (c) => {
|
|
5637
|
+
}).get("/:name/history", requireSelf(), async (c) => {
|
|
5600
5638
|
const name = c.req.param("name");
|
|
5601
5639
|
const channel = c.req.query("channel");
|
|
5602
5640
|
const session = c.req.query("session");
|
|
@@ -5747,7 +5785,7 @@ function writeSchedules(name, dir, schedules) {
|
|
|
5747
5785
|
data: { schedules }
|
|
5748
5786
|
});
|
|
5749
5787
|
}
|
|
5750
|
-
var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
5788
|
+
var app15 = new Hono17().get("/:name/clock/status", requireSelf(), async (c) => {
|
|
5751
5789
|
const name = c.req.param("name");
|
|
5752
5790
|
const entry = await findMind(name);
|
|
5753
5791
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -5806,7 +5844,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
|
5806
5844
|
upcoming.sort((a, b) => a.at.localeCompare(b.at));
|
|
5807
5845
|
previous.sort((a, b) => b.at.localeCompare(a.at));
|
|
5808
5846
|
return c.json({ sleep: sleepState, sleepConfig, schedules, upcoming, previous });
|
|
5809
|
-
}).get("/:name/sleep/config", async (c) => {
|
|
5847
|
+
}).get("/:name/sleep/config", requireSelf(), async (c) => {
|
|
5810
5848
|
const name = c.req.param("name");
|
|
5811
5849
|
const entry = await findMind(name);
|
|
5812
5850
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -5838,7 +5876,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
|
5838
5876
|
writeVoluteConfig(dir, config2);
|
|
5839
5877
|
getSleepManagerIfReady()?.invalidateSleepConfig(name);
|
|
5840
5878
|
return c.json({ ok: true });
|
|
5841
|
-
}).get("/:name/schedules", async (c) => {
|
|
5879
|
+
}).get("/:name/schedules", requireSelf(), async (c) => {
|
|
5842
5880
|
const name = c.req.param("name");
|
|
5843
5881
|
const entry = await findMind(name);
|
|
5844
5882
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -5963,7 +6001,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
|
5963
6001
|
}
|
|
5964
6002
|
writeSchedules(name, dir, filtered);
|
|
5965
6003
|
return c.json({ ok: true });
|
|
5966
|
-
}).post("/:name/webhook/:event", async (c) => {
|
|
6004
|
+
}).post("/:name/webhook/:event", requireSelf(), async (c) => {
|
|
5967
6005
|
const name = c.req.param("name");
|
|
5968
6006
|
const event = c.req.param("event");
|
|
5969
6007
|
const entry = await findMind(name);
|
|
@@ -5971,7 +6009,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
|
5971
6009
|
const body = await c.req.text();
|
|
5972
6010
|
const message = `[webhook: ${event}] ${body}`;
|
|
5973
6011
|
try {
|
|
5974
|
-
const { sendSystemMessage } = await import("./system-chat-
|
|
6012
|
+
const { sendSystemMessage } = await import("./system-chat-7CA2PP6A.js");
|
|
5975
6013
|
await sendSystemMessage(name, message);
|
|
5976
6014
|
return c.json({ ok: true });
|
|
5977
6015
|
} catch (err) {
|
|
@@ -5984,14 +6022,14 @@ var schedules_default = app15;
|
|
|
5984
6022
|
// packages/daemon/src/web/api/setup.ts
|
|
5985
6023
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
5986
6024
|
import { homedir as homedir2 } from "os";
|
|
5987
|
-
import { resolve as
|
|
6025
|
+
import { resolve as resolve12 } from "path";
|
|
5988
6026
|
import { Hono as Hono18 } from "hono";
|
|
5989
6027
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
5990
6028
|
var DEFAULT_API_URL2 = "https://volute.systems";
|
|
5991
6029
|
var setup = new Hono18();
|
|
5992
6030
|
function writeSetupConfig(systemName, description) {
|
|
5993
|
-
const configHome = process.env.VOLUTE_HOME ??
|
|
5994
|
-
const mindsDir =
|
|
6031
|
+
const configHome = process.env.VOLUTE_HOME ?? resolve12(homedir2(), ".volute");
|
|
6032
|
+
const mindsDir = resolve12(configHome, "minds");
|
|
5995
6033
|
mkdirSync7(configHome, { recursive: true });
|
|
5996
6034
|
mkdirSync7(mindsDir, { recursive: true });
|
|
5997
6035
|
const existingConfig = readGlobalConfig();
|
|
@@ -6025,7 +6063,7 @@ setup.get("/status", async (c) => {
|
|
|
6025
6063
|
let hasAccount = false;
|
|
6026
6064
|
if (hasSystem) {
|
|
6027
6065
|
try {
|
|
6028
|
-
const { listUsersByType: listUsersByType2 } = await import("./auth-
|
|
6066
|
+
const { listUsersByType: listUsersByType2 } = await import("./auth-X6ZITZ7D.js");
|
|
6029
6067
|
const brains = await listUsersByType2("brain");
|
|
6030
6068
|
hasAccount = brains.length > 0;
|
|
6031
6069
|
} catch (err) {
|
|
@@ -6236,7 +6274,7 @@ setup.post("/account", async (c) => {
|
|
|
6236
6274
|
}
|
|
6237
6275
|
}
|
|
6238
6276
|
try {
|
|
6239
|
-
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-
|
|
6277
|
+
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-X6ZITZ7D.js");
|
|
6240
6278
|
const user = await createUser2(body.username.trim(), body.password);
|
|
6241
6279
|
if (body.displayName?.trim()) {
|
|
6242
6280
|
await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
|
|
@@ -6282,7 +6320,7 @@ setup.post("/models", async (c) => {
|
|
|
6282
6320
|
return c.json({ error: "Spirit model is required" }, 400);
|
|
6283
6321
|
}
|
|
6284
6322
|
try {
|
|
6285
|
-
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-
|
|
6323
|
+
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-EVLKMAJD.js");
|
|
6286
6324
|
setEnabledModels3(body.models);
|
|
6287
6325
|
const config2 = readGlobalConfig();
|
|
6288
6326
|
config2.spiritModel = body.spiritModel.trim();
|
|
@@ -6300,15 +6338,15 @@ setup.post("/complete", async (c) => {
|
|
|
6300
6338
|
return c.json({ error: "Setup already complete" }, 400);
|
|
6301
6339
|
}
|
|
6302
6340
|
try {
|
|
6303
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
6304
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
6341
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-T6GK5GEP.js");
|
|
6342
|
+
const { startSpiritFull } = await import("./mind-service-X7FH3NA4.js");
|
|
6305
6343
|
await ensureSpiritProject();
|
|
6306
6344
|
await syncSpiritTemplate();
|
|
6307
6345
|
const warnings = [];
|
|
6308
6346
|
const config2 = readGlobalConfig();
|
|
6309
6347
|
if (config2.setup?.service && config2.setup?.type === "local") {
|
|
6310
6348
|
try {
|
|
6311
|
-
const { installUserService } = await import("./service-install-
|
|
6349
|
+
const { installUserService } = await import("./service-install-W3FQXJKB.js");
|
|
6312
6350
|
const installed = await installUserService(config2.port, config2.hostname);
|
|
6313
6351
|
if (!installed) {
|
|
6314
6352
|
warnings.push("Service installation is not supported on this platform.");
|
|
@@ -6336,8 +6374,8 @@ setup.post("/complete", async (c) => {
|
|
|
6336
6374
|
}
|
|
6337
6375
|
let spiritConversationId;
|
|
6338
6376
|
try {
|
|
6339
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-
|
|
6340
|
-
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-
|
|
6377
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-X6ZITZ7D.js");
|
|
6378
|
+
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-AYLXPOGC.js");
|
|
6341
6379
|
const spiritUser = await getOrCreateMindUser2("volute");
|
|
6342
6380
|
const brains = await listUsersByType2("brain");
|
|
6343
6381
|
const admin2 = brains.find((u) => u.role === "admin");
|
|
@@ -6359,8 +6397,8 @@ setup.post("/complete", async (c) => {
|
|
|
6359
6397
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
6360
6398
|
if (spiritConversationId && spiritStarted) {
|
|
6361
6399
|
try {
|
|
6362
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
6363
|
-
const { listUsersByType: listUsers2 } = await import("./auth-
|
|
6400
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-Q7TU24IA.js");
|
|
6401
|
+
const { listUsersByType: listUsers2 } = await import("./auth-X6ZITZ7D.js");
|
|
6364
6402
|
const admins = await listUsers2("brain");
|
|
6365
6403
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
6366
6404
|
const adminName = admin2?.display_name || admin2?.username || "the admin";
|
|
@@ -6399,7 +6437,7 @@ var setup_default = setup;
|
|
|
6399
6437
|
// packages/daemon/src/web/api/skills.ts
|
|
6400
6438
|
import { existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
|
|
6401
6439
|
import { tmpdir } from "os";
|
|
6402
|
-
import { join, resolve as
|
|
6440
|
+
import { join, resolve as resolve13 } from "path";
|
|
6403
6441
|
import AdmZip from "adm-zip";
|
|
6404
6442
|
import { Hono as Hono19 } from "hono";
|
|
6405
6443
|
var app16 = new Hono19().get("/", async (c) => {
|
|
@@ -6475,7 +6513,7 @@ var app16 = new Hono19().get("/", async (c) => {
|
|
|
6475
6513
|
try {
|
|
6476
6514
|
const zip = new AdmZip(buffer2);
|
|
6477
6515
|
for (const entry of zip.getEntries()) {
|
|
6478
|
-
const target =
|
|
6516
|
+
const target = resolve13(tmpDir, entry.entryName);
|
|
6479
6517
|
if (!target.startsWith(tmpDir)) {
|
|
6480
6518
|
return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
|
|
6481
6519
|
}
|
|
@@ -6817,8 +6855,8 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
|
|
|
6817
6855
|
});
|
|
6818
6856
|
}, 15e3);
|
|
6819
6857
|
cleanups.push(() => clearInterval(keepAlive));
|
|
6820
|
-
await new Promise((
|
|
6821
|
-
stream.onAbort(() =>
|
|
6858
|
+
await new Promise((resolve18) => {
|
|
6859
|
+
stream.onAbort(() => resolve18());
|
|
6822
6860
|
});
|
|
6823
6861
|
} finally {
|
|
6824
6862
|
for (const cleanup of cleanups) {
|
|
@@ -6834,15 +6872,15 @@ var events_default = app20;
|
|
|
6834
6872
|
|
|
6835
6873
|
// packages/daemon/src/web/api/variants.ts
|
|
6836
6874
|
import { existsSync as existsSync9, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
6837
|
-
import { resolve as
|
|
6875
|
+
import { resolve as resolve15 } from "path";
|
|
6838
6876
|
import { Hono as Hono24 } from "hono";
|
|
6839
6877
|
|
|
6840
6878
|
// packages/daemon/src/lib/mind/spawn-server.ts
|
|
6841
6879
|
import { spawn as spawn4 } from "child_process";
|
|
6842
6880
|
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync9 } from "fs";
|
|
6843
|
-
import { resolve as
|
|
6881
|
+
import { resolve as resolve14 } from "path";
|
|
6844
6882
|
function tsxBin(cwd) {
|
|
6845
|
-
return
|
|
6883
|
+
return resolve14(cwd, "node_modules", ".bin", "tsx");
|
|
6846
6884
|
}
|
|
6847
6885
|
function spawnServer(cwd, port, options) {
|
|
6848
6886
|
if (options?.detached) {
|
|
@@ -6855,31 +6893,31 @@ function spawnAttached(cwd, port) {
|
|
|
6855
6893
|
cwd,
|
|
6856
6894
|
stdio: ["ignore", "pipe", "pipe"]
|
|
6857
6895
|
});
|
|
6858
|
-
return new Promise((
|
|
6859
|
-
const timeout = setTimeout(() =>
|
|
6896
|
+
return new Promise((resolve18) => {
|
|
6897
|
+
const timeout = setTimeout(() => resolve18(null), 3e4);
|
|
6860
6898
|
function checkOutput(data) {
|
|
6861
6899
|
const match = data.toString().match(/listening on :(\d+)/);
|
|
6862
6900
|
if (match) {
|
|
6863
6901
|
clearTimeout(timeout);
|
|
6864
|
-
|
|
6902
|
+
resolve18({ child, actualPort: parseInt(match[1], 10) });
|
|
6865
6903
|
}
|
|
6866
6904
|
}
|
|
6867
6905
|
child.stdout?.on("data", checkOutput);
|
|
6868
6906
|
child.stderr?.on("data", checkOutput);
|
|
6869
6907
|
child.on("error", () => {
|
|
6870
6908
|
clearTimeout(timeout);
|
|
6871
|
-
|
|
6909
|
+
resolve18(null);
|
|
6872
6910
|
});
|
|
6873
6911
|
child.on("exit", () => {
|
|
6874
6912
|
clearTimeout(timeout);
|
|
6875
|
-
|
|
6913
|
+
resolve18(null);
|
|
6876
6914
|
});
|
|
6877
6915
|
});
|
|
6878
6916
|
}
|
|
6879
6917
|
function spawnDetached(cwd, port, logDir) {
|
|
6880
|
-
const logsDir = logDir ??
|
|
6918
|
+
const logsDir = logDir ?? resolve14(cwd, ".mind", "logs");
|
|
6881
6919
|
mkdirSync8(logsDir, { recursive: true });
|
|
6882
|
-
const logPath =
|
|
6920
|
+
const logPath = resolve14(logsDir, "mind.log");
|
|
6883
6921
|
const logFd = openSync(logPath, "a");
|
|
6884
6922
|
const child = spawn4(tsxBin(cwd), ["src/server.ts", "--port", String(port)], {
|
|
6885
6923
|
cwd,
|
|
@@ -6995,11 +7033,11 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
6995
7033
|
return c.json({ error: `Name already in use: ${variantName}` }, 409);
|
|
6996
7034
|
}
|
|
6997
7035
|
const projectRoot = mindDir(mindName);
|
|
6998
|
-
const variantDir =
|
|
7036
|
+
const variantDir = resolve15(projectRoot, ".variants", variantName);
|
|
6999
7037
|
if (existsSync9(variantDir)) {
|
|
7000
7038
|
return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
|
|
7001
7039
|
}
|
|
7002
|
-
mkdirSync9(
|
|
7040
|
+
mkdirSync9(resolve15(projectRoot, ".variants"), { recursive: true });
|
|
7003
7041
|
try {
|
|
7004
7042
|
await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
|
|
7005
7043
|
} catch (e) {
|
|
@@ -7012,7 +7050,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7012
7050
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
7013
7051
|
await exec(cmd, args, {
|
|
7014
7052
|
cwd: variantDir,
|
|
7015
|
-
env: { ...process.env, HOME:
|
|
7053
|
+
env: { ...process.env, HOME: resolve15(variantDir, "home") }
|
|
7016
7054
|
});
|
|
7017
7055
|
} else {
|
|
7018
7056
|
await exec("npm", ["install"], { cwd: variantDir });
|
|
@@ -7022,7 +7060,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7022
7060
|
return c.json({ error: `npm install failed: ${msg}` }, 500);
|
|
7023
7061
|
}
|
|
7024
7062
|
if (body.soul) {
|
|
7025
|
-
writeFileSync8(
|
|
7063
|
+
writeFileSync8(resolve15(variantDir, "home/SOUL.md"), body.soul);
|
|
7026
7064
|
}
|
|
7027
7065
|
const variantPort = body.port ?? await nextPort();
|
|
7028
7066
|
await addVariant(variantName, mindName, variantPort, variantDir, variantName);
|
|
@@ -7117,8 +7155,8 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7117
7155
|
await cleanupVariant(variantName, projectRoot, variantEntry.dir);
|
|
7118
7156
|
if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
|
|
7119
7157
|
try {
|
|
7120
|
-
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-
|
|
7121
|
-
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-
|
|
7158
|
+
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-DMHSLRDX.js");
|
|
7159
|
+
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-GV35XFT7.js");
|
|
7122
7160
|
const tmpl = parentEntry.template ?? "claude";
|
|
7123
7161
|
await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
|
|
7124
7162
|
} catch (err) {
|
|
@@ -7131,7 +7169,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7131
7169
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
7132
7170
|
await exec(cmd, args, {
|
|
7133
7171
|
cwd: projectRoot,
|
|
7134
|
-
env: { ...process.env, HOME:
|
|
7172
|
+
env: { ...process.env, HOME: resolve15(projectRoot, "home") }
|
|
7135
7173
|
});
|
|
7136
7174
|
} else {
|
|
7137
7175
|
await exec("npm", ["install"], { cwd: projectRoot });
|
|
@@ -7548,11 +7586,11 @@ var app23 = new Hono26().get("/:name/conversations/:id/events", async (c) => {
|
|
|
7548
7586
|
if (!stream.aborted) console.error("[chat] SSE ping error:", err);
|
|
7549
7587
|
});
|
|
7550
7588
|
}, 15e3);
|
|
7551
|
-
await new Promise((
|
|
7589
|
+
await new Promise((resolve18) => {
|
|
7552
7590
|
stream.onAbort(() => {
|
|
7553
7591
|
unsubscribe();
|
|
7554
7592
|
clearInterval(keepAlive);
|
|
7555
|
-
|
|
7593
|
+
resolve18();
|
|
7556
7594
|
});
|
|
7557
7595
|
});
|
|
7558
7596
|
});
|
|
@@ -7765,7 +7803,7 @@ var app_default = app25;
|
|
|
7765
7803
|
import { existsSync as existsSync10 } from "fs";
|
|
7766
7804
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
7767
7805
|
import { createServer as createHttpsServer } from "https";
|
|
7768
|
-
import { dirname as dirname2, extname as extname3, resolve as
|
|
7806
|
+
import { dirname as dirname2, extname as extname3, resolve as resolve16 } from "path";
|
|
7769
7807
|
import { serve } from "@hono/node-server";
|
|
7770
7808
|
var MIME_TYPES2 = {
|
|
7771
7809
|
".html": "text/html",
|
|
@@ -7784,7 +7822,7 @@ async function startServer({
|
|
|
7784
7822
|
let assetsDir = "";
|
|
7785
7823
|
let searchDir = dirname2(new URL(import.meta.url).pathname);
|
|
7786
7824
|
for (let i = 0; i < 5; i++) {
|
|
7787
|
-
const candidate =
|
|
7825
|
+
const candidate = resolve16(searchDir, "dist", "web-assets");
|
|
7788
7826
|
if (existsSync10(candidate)) {
|
|
7789
7827
|
assetsDir = candidate;
|
|
7790
7828
|
break;
|
|
@@ -7795,20 +7833,20 @@ async function startServer({
|
|
|
7795
7833
|
app_default.get("*", async (c) => {
|
|
7796
7834
|
const urlPath = new URL(c.req.url).pathname;
|
|
7797
7835
|
if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
|
|
7798
|
-
const filePath =
|
|
7836
|
+
const filePath = resolve16(assetsDir, urlPath.slice(1));
|
|
7799
7837
|
if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
|
|
7800
7838
|
const s = await stat2(filePath).catch(() => null);
|
|
7801
7839
|
if (s?.isFile()) {
|
|
7802
7840
|
const ext = extname3(filePath);
|
|
7803
7841
|
const mime = MIME_TYPES2[ext] || "application/octet-stream";
|
|
7804
7842
|
const body = await readFile2(filePath);
|
|
7805
|
-
const
|
|
7806
|
-
const nameWithoutExt =
|
|
7843
|
+
const basename2 = filePath.slice(filePath.lastIndexOf("/") + 1);
|
|
7844
|
+
const nameWithoutExt = basename2.slice(0, basename2.lastIndexOf("."));
|
|
7807
7845
|
const isHashed = /[-.][\da-f]{8,}$/.test(nameWithoutExt);
|
|
7808
7846
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
7809
7847
|
return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
|
|
7810
7848
|
}
|
|
7811
|
-
const indexPath =
|
|
7849
|
+
const indexPath = resolve16(assetsDir, "index.html");
|
|
7812
7850
|
const indexStat = await stat2(indexPath).catch(() => null);
|
|
7813
7851
|
if (indexStat?.isFile()) {
|
|
7814
7852
|
const body = await readFile2(indexPath, "utf-8");
|
|
@@ -7825,10 +7863,10 @@ async function startServer({
|
|
|
7825
7863
|
createServer: createHttpsServer,
|
|
7826
7864
|
serverOptions: { key: tls.key, cert: tls.cert }
|
|
7827
7865
|
});
|
|
7828
|
-
await new Promise((
|
|
7866
|
+
await new Promise((resolve18, reject) => {
|
|
7829
7867
|
server2.on("listening", () => {
|
|
7830
7868
|
logger_default.info("Volute UI running (https)", { hostname, port });
|
|
7831
|
-
|
|
7869
|
+
resolve18();
|
|
7832
7870
|
});
|
|
7833
7871
|
server2.on("error", (err) => {
|
|
7834
7872
|
reject(err);
|
|
@@ -7836,13 +7874,13 @@ async function startServer({
|
|
|
7836
7874
|
});
|
|
7837
7875
|
const internalPort = port + 1;
|
|
7838
7876
|
const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
|
|
7839
|
-
await new Promise((
|
|
7877
|
+
await new Promise((resolve18, reject) => {
|
|
7840
7878
|
internalServer.on("listening", () => {
|
|
7841
7879
|
logger_default.info("Volute API running (http, internal)", {
|
|
7842
7880
|
hostname: "127.0.0.1",
|
|
7843
7881
|
port: internalPort
|
|
7844
7882
|
});
|
|
7845
|
-
|
|
7883
|
+
resolve18();
|
|
7846
7884
|
});
|
|
7847
7885
|
internalServer.on("error", (err) => {
|
|
7848
7886
|
reject(err);
|
|
@@ -7851,10 +7889,10 @@ async function startServer({
|
|
|
7851
7889
|
return { server: server2, internalPort };
|
|
7852
7890
|
}
|
|
7853
7891
|
const server = serve({ fetch: app_default.fetch, port, hostname });
|
|
7854
|
-
await new Promise((
|
|
7892
|
+
await new Promise((resolve18, reject) => {
|
|
7855
7893
|
server.on("listening", () => {
|
|
7856
7894
|
logger_default.info("Volute API running (http)", { hostname, port });
|
|
7857
|
-
|
|
7895
|
+
resolve18();
|
|
7858
7896
|
});
|
|
7859
7897
|
server.on("error", (err) => {
|
|
7860
7898
|
reject(err);
|
|
@@ -7865,7 +7903,7 @@ async function startServer({
|
|
|
7865
7903
|
|
|
7866
7904
|
// packages/daemon/src/daemon.ts
|
|
7867
7905
|
if (!process.env.VOLUTE_HOME) {
|
|
7868
|
-
process.env.VOLUTE_HOME =
|
|
7906
|
+
process.env.VOLUTE_HOME = resolve17(homedir3(), ".volute");
|
|
7869
7907
|
}
|
|
7870
7908
|
if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
|
|
7871
7909
|
process.env.TZ = process.env.VOLUTE_TIMEZONE;
|
|
@@ -7876,7 +7914,7 @@ async function startDaemon(opts) {
|
|
|
7876
7914
|
const home = voluteHome();
|
|
7877
7915
|
const systemDir = voluteSystemDir();
|
|
7878
7916
|
if (!opts.foreground) {
|
|
7879
|
-
const rotatingLog = new RotatingLog(
|
|
7917
|
+
const rotatingLog = new RotatingLog(resolve17(systemDir, "daemon.log"));
|
|
7880
7918
|
logger_default.setOutput((line) => rotatingLog.write(`${line}
|
|
7881
7919
|
`));
|
|
7882
7920
|
const write = (...args) => rotatingLog.write(`${format(...args)}
|
|
@@ -7886,22 +7924,22 @@ async function startDaemon(opts) {
|
|
|
7886
7924
|
console.warn = write;
|
|
7887
7925
|
console.info = write;
|
|
7888
7926
|
}
|
|
7889
|
-
const DAEMON_PID_PATH =
|
|
7890
|
-
const DAEMON_JSON_PATH =
|
|
7927
|
+
const DAEMON_PID_PATH = resolve17(systemDir, "daemon.pid");
|
|
7928
|
+
const DAEMON_JSON_PATH = resolve17(systemDir, "daemon.json");
|
|
7891
7929
|
mkdirSync10(home, { recursive: true });
|
|
7892
7930
|
ensureSystemDir();
|
|
7893
|
-
const { migrateSetupCompleted } = await import("./setup-
|
|
7931
|
+
const { migrateSetupCompleted } = await import("./setup-OTEC3ZPM.js");
|
|
7894
7932
|
migrateSetupCompleted();
|
|
7895
|
-
await (await import("./db-
|
|
7933
|
+
await (await import("./db-ZEPKEJJD.js")).getDb();
|
|
7896
7934
|
try {
|
|
7897
7935
|
const { eq: eq7, and: and5 } = await import("drizzle-orm");
|
|
7898
|
-
const { users: users2 } = await import("./schema-
|
|
7899
|
-
const db = await (await import("./db-
|
|
7936
|
+
const { users: users2 } = await import("./schema-LYQUDL7G.js");
|
|
7937
|
+
const db = await (await import("./db-ZEPKEJJD.js")).getDb();
|
|
7900
7938
|
await db.update(users2).set({ role: "system" }).where(and5(eq7(users2.user_type, "system"), eq7(users2.role, "user")));
|
|
7901
7939
|
} catch (err) {
|
|
7902
7940
|
logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
|
|
7903
7941
|
}
|
|
7904
|
-
const { initSandbox } = await import("./sandbox-
|
|
7942
|
+
const { initSandbox } = await import("./sandbox-5R32QKWQ.js");
|
|
7905
7943
|
await initSandbox();
|
|
7906
7944
|
try {
|
|
7907
7945
|
await syncBuiltinSkills();
|
|
@@ -7928,7 +7966,7 @@ async function startDaemon(opts) {
|
|
|
7928
7966
|
logger_default.warn("failed to ensure #system channel", logger_default.errorData(err));
|
|
7929
7967
|
}
|
|
7930
7968
|
try {
|
|
7931
|
-
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-
|
|
7969
|
+
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-X6ZITZ7D.js");
|
|
7932
7970
|
await getOrCreateSystemUser2();
|
|
7933
7971
|
} catch (err) {
|
|
7934
7972
|
logger_default.warn(
|
|
@@ -7937,12 +7975,12 @@ async function startDaemon(opts) {
|
|
|
7937
7975
|
);
|
|
7938
7976
|
}
|
|
7939
7977
|
const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes(32).toString("hex");
|
|
7940
|
-
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-
|
|
7978
|
+
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-OTEC3ZPM.js");
|
|
7941
7979
|
const globalCfg = readGlobalConfig2();
|
|
7942
7980
|
let tls;
|
|
7943
7981
|
if (opts.tailscale || globalCfg.tailscale) {
|
|
7944
7982
|
try {
|
|
7945
|
-
const { getTailscaleTls } = await import("./tailscale-
|
|
7983
|
+
const { getTailscaleTls } = await import("./tailscale-X4HRKRTW.js");
|
|
7946
7984
|
const tlsConfig = await getTailscaleTls();
|
|
7947
7985
|
tls = { key: tlsConfig.key, cert: tlsConfig.cert };
|
|
7948
7986
|
logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
|
|
@@ -8021,10 +8059,10 @@ async function startDaemon(opts) {
|
|
|
8021
8059
|
await Promise.all(workers);
|
|
8022
8060
|
}
|
|
8023
8061
|
try {
|
|
8024
|
-
const { isSetupComplete: isSetupComplete2 } = await import("./setup-
|
|
8062
|
+
const { isSetupComplete: isSetupComplete2 } = await import("./setup-OTEC3ZPM.js");
|
|
8025
8063
|
if (isSetupComplete2()) {
|
|
8026
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
8027
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
8064
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-T6GK5GEP.js");
|
|
8065
|
+
const { startSpiritFull } = await import("./mind-service-X7FH3NA4.js");
|
|
8028
8066
|
await ensureSpiritProject();
|
|
8029
8067
|
await syncSpiritTemplate();
|
|
8030
8068
|
const spiritEntry = await findMind("volute");
|
|
@@ -8041,7 +8079,7 @@ async function startDaemon(opts) {
|
|
|
8041
8079
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
8042
8080
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
8043
8081
|
});
|
|
8044
|
-
import("./cloud-sync-
|
|
8082
|
+
import("./cloud-sync-GOSJZIHH.js").then(
|
|
8045
8083
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
8046
8084
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
8047
8085
|
})
|
|
@@ -8049,7 +8087,7 @@ async function startDaemon(opts) {
|
|
|
8049
8087
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
8050
8088
|
});
|
|
8051
8089
|
try {
|
|
8052
|
-
const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-
|
|
8090
|
+
const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-DK6AHWX7.js");
|
|
8053
8091
|
backfillTemplateHashes();
|
|
8054
8092
|
notifyVersionUpdate().catch((err) => {
|
|
8055
8093
|
logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
|