volute 0.39.0 → 0.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accept-AHAOUFBK.js → accept-IVHOHXQS.js} +1 -1
- package/dist/{activity-events-CR4RIHJT.js → activity-events-DS4QRWBY.js} +4 -4
- package/dist/{ai-service-PL7GKFQC.js → ai-service-AUWIPWLP.js} +9 -5
- package/dist/{api-client-LC5YRA32.js → api-client-NFM6GX2N.js} +1 -1
- package/dist/{archive-UEWIFRAR.js → archive-UDHFZN4G.js} +4 -4
- package/dist/{auth-OJ2YW3NR.js → auth-X6ZITZ7D.js} +5 -5
- package/dist/{bridge-F3ZJEKDN.js → bridge-MSZC4HUT.js} +1 -1
- package/dist/{chat-RQ5NV5EA.js → chat-JD3TJINV.js} +9 -9
- package/dist/{chunk-CJ26DXZL.js → chunk-2HZRJ35V.js} +17 -1
- package/dist/{chunk-QDWPM73D.js → chunk-3Y7UDHO7.js} +3 -3
- package/dist/{chunk-6V2U3GFQ.js → chunk-4UMXOMZ6.js} +2 -2
- package/dist/{chunk-7OS7QFDF.js → chunk-5EVW4KOD.js} +3 -3
- package/dist/{chunk-6FSSMAXU.js → chunk-6SYHHEQ7.js} +1 -1
- package/dist/{chunk-OEXOFBW5.js → chunk-AEAZRTEV.js} +1 -1
- package/dist/{chunk-DZ4LYU6J.js → chunk-ANSTTB55.js} +1 -1
- package/dist/{chunk-QDWP435B.js → chunk-B4WPXYPI.js} +1 -1
- package/dist/{chunk-CHCISTH7.js → chunk-BLAXARBZ.js} +511 -335
- package/dist/{chunk-TCNCRDB5.js → chunk-DNU6XLE2.js} +1 -1
- package/dist/{chunk-7W3UWCQD.js → chunk-E25SO3QW.js} +3 -3
- package/dist/{chunk-IA2SZSLB.js → chunk-I57LLNAQ.js} +1 -1
- package/dist/{chunk-WUH54G5S.js → chunk-ITH5ZLZJ.js} +1 -1
- package/dist/{chunk-QJ4GU5XT.js → chunk-JYQQDI3M.js} +2 -2
- package/dist/{chunk-EVKGKQ2P.js → chunk-KMHC36CA.js} +1 -7
- package/dist/chunk-LMMQX4CK.js +49 -0
- package/dist/{chunk-4BO4I7UF.js → chunk-LZ6CQYRO.js} +7 -7
- package/dist/{chunk-RAVQXKAG.js → chunk-MNUXL4XN.js} +67 -3
- package/dist/{chunk-OS5MRIEP.js → chunk-NERYUSER.js} +1 -1
- package/dist/{chunk-XOSAY7PY.js → chunk-PKGA23XM.js} +1 -1
- package/dist/{chunk-IBOU6Q3Y.js → chunk-QV7P3TYO.js} +5 -5
- package/dist/{chunk-7GZB3ZJP.js → chunk-QYI65HCL.js} +2 -2
- package/dist/{chunk-B7MWXFAH.js → chunk-S4SXBQ7F.js} +15 -1
- package/dist/{chunk-X7GM2OPM.js → chunk-SVXOBKQY.js} +2 -2
- package/dist/{chunk-Y5UC6G3O.js → chunk-TOANT6FD.js} +2 -2
- package/dist/{chunk-TT4WT6Y7.js → chunk-YHWGN4FX.js} +1 -1
- package/dist/{chunk-Y4W3OS7Q.js → chunk-YTNBO7S6.js} +8 -8
- package/dist/cli.js +24 -24
- package/dist/{clock-BMLJ2TR6.js → clock-YLDJUKBW.js} +3 -3
- package/dist/{cloud-sync-NQCWJLYI.js → cloud-sync-MAQCJEFJ.js} +17 -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-EUXHBWJD.js → conversations-AYLXPOGC.js} +5 -5
- package/dist/{create-3QH7DVLC.js → create-T4UJ64WB.js} +4 -4
- 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-UEB3PLKB.js → daemon-restart-LP2DR24J.js} +9 -9
- package/dist/daemon.js +424 -294
- 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-VNHLQTTO.js +30 -0
- package/dist/{delivery-router-EUW4RIWG.js → delivery-router-T6CYTS3M.js} +4 -4
- package/dist/down-6DYO2QV7.js +17 -0
- package/dist/echo-text-QFCH3H6G.js +31 -0
- package/dist/{env-IQ6Q2333.js → env-77IOWG4U.js} +1 -1
- package/dist/exec-5DGKQ5V3.js +17 -0
- package/dist/{export-JDAK3THX.js → export-TZKOCSCE.js} +6 -6
- package/dist/{extension-LZYHBNLV.js → extension-35NB6GHW.js} +1 -1
- package/dist/{extensions-V7TXKAKM.js → extensions-LQX2N7TI.js} +17 -17
- package/dist/{files-K5XV23H6.js → files-WNNVJWJB.js} +4 -4
- package/dist/{import-GZ5IYVV7.js → import-BNNFCQ7U.js} +11 -11
- package/dist/{isolation-FPF4UTH2.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-BGF5JY3I.js → login-Y6UAYQVO.js} +3 -3
- package/dist/{logout-YHQLOFLR.js → logout-M6FI62BL.js} +1 -1
- package/dist/{logout-GQHI6KH6.js → logout-VHGWVH63.js} +3 -3
- package/dist/message-delivery-7BCYJLH2.js +40 -0
- package/dist/{mind-QMJIWWWW.js → mind-ELPD6VBP.js} +19 -19
- package/dist/{mind-activity-tracker-Z3KBQTVU.js → mind-activity-tracker-XFRVGXFS.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-EDCLALBF.js +30 -0
- package/dist/{mind-profile-7VYRJGFZ.js → mind-profile-3LNKXNPA.js} +2 -2
- package/dist/mind-service-WTOFVNLW.js +36 -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-IR4ZEQA2.js → package-GO3PHHUF.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-LWEOAO53.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-KUAVC37A.js → sandbox-5R32QKWQ.js} +5 -5
- package/dist/scheduler-GQBDCGLU.js +30 -0
- package/dist/{schema-K575EBPE.js → schema-LYQUDL7G.js} +4 -2
- package/dist/{seed-GPBERPXJ.js → seed-MO2C7CWC.js} +2 -2
- package/dist/{seed-check-HZPVFJKZ.js → seed-check-3WXXRHTC.js} +2 -2
- package/dist/{seed-cmd-PWF4FYFG.js → seed-cmd-ETIF4WD6.js} +4 -4
- package/dist/{seed-create-NTIICZVB.js → seed-create-BPQC2IOR.js} +6 -6
- package/dist/{seed-sprout-PRPFKGJF.js → seed-sprout-TX72K33T.js} +11 -11
- package/dist/{send-IMHDYJHW.js → send-WO3CVG73.js} +4 -4
- package/dist/{service-DWBRRFXS.js → service-WMV6R6VJ.js} +6 -6
- package/dist/service-install-W3FQXJKB.js +17 -0
- package/dist/{setup-IFYS3TLS.js → setup-OTEC3ZPM.js} +4 -4
- package/dist/{setup-4CWQ53VV.js → setup-ZTW4FVMQ.js} +9 -9
- package/dist/{skill-ICN6Y2ZF.js → skill-QHACP7EU.js} +1 -1
- package/dist/{skills-FJ5W73AV.js → skills-JEWMHIIE.js} +7 -7
- package/dist/sleep-manager-5277OBHI.js +34 -0
- package/dist/{spirit-U6MDQLYT.js → spirit-NVXWSVKM.js} +9 -9
- package/dist/{split-5YBEQTBF.js → split-7AO4IO42.js} +3 -3
- package/dist/{sprout-ABX2G76C.js → sprout-NFJZKYEW.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-C6BBWNU3.js → status-BRYYYO7C.js} +7 -7
- package/dist/{stop-TWDKVEUX.js → stop-QILBDUAR.js} +1 -1
- package/dist/system-chat-LQSJVY55.js +34 -0
- package/dist/{systems-Y2WZV2K4.js → systems-3XTAHA35.js} +4 -4
- package/dist/{tailscale-2KKXDMNK.js → tailscale-X4HRKRTW.js} +3 -3
- package/dist/{template-hash-SSIBEEYK.js → template-hash-DMHSLRDX.js} +1 -1
- package/dist/up-4H7TL6WB.js +19 -0
- package/dist/{update-V26PT4VN.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-ZBMY2TEX.js → version-notify-N37N2C4G.js} +18 -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/assets/index-DqHSW9Fr.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0009_mind_notices.sql +14 -0
- package/drizzle/meta/_journal.json +7 -0
- 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/_base/.init/.local/hooks/pre-prompt/notices.ts +46 -0
- package/templates/_base/src/lib/context-breakdown.ts +281 -126
- package/templates/_base/src/lib/daemon-client.ts +5 -2
- package/templates/_base/src/lib/transparency.ts +5 -3
- package/templates/_base/src/lib/volute-server.ts +23 -0
- package/templates/claude/package.json.tmpl +5 -5
- package/templates/claude/src/agent.ts +54 -16
- package/templates/claude/src/server.ts +1 -0
- package/templates/codex/package.json.tmpl +5 -5
- package/templates/codex/src/agent.ts +45 -12
- package/templates/codex/src/server.ts +1 -0
- package/templates/pi/package.json.tmpl +6 -6
- package/templates/pi/src/agent.ts +74 -13
- package/templates/pi/src/lib/subagents.ts +19 -17
- package/templates/pi/src/server.ts +1 -0
- package/dist/chunk-K3NQKI34.js +0 -10
- package/dist/db-32YFKMFL.js +0 -9
- package/dist/delivery-manager-N34XKUGL.js +0 -30
- package/dist/down-TCEBGTMY.js +0 -17
- package/dist/echo-text-N3BC3WNX.js +0 -31
- package/dist/exec-2MFHTGOS.js +0 -17
- package/dist/message-delivery-X7MKA3TA.js +0 -40
- package/dist/mind-manager-7GWTTKWD.js +0 -30
- package/dist/mind-service-MO2XJKJN.js +0 -36
- package/dist/scheduler-CGUPAEBA.js +0 -30
- package/dist/service-install-KEBDNZVE.js +0 -17
- package/dist/sleep-manager-6QRMUNHK.js +0 -34
- package/dist/src-6Z4XYDH5.js +0 -2164
- package/dist/system-chat-D343HYGR.js +0 -34
- package/dist/up-ZU6ILVMA.js +0 -19
- package/dist/update-check-XRERV36Y.js +0 -18
- package/dist/web-assets/assets/index-B1zwqwt8.css +0 -1
- package/dist/web-assets/assets/index-D1guJF1i.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-LZ6CQYRO.js";
|
|
34
34
|
import {
|
|
35
35
|
getBridgeConfig,
|
|
36
36
|
readBridgesConfig,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
resolveChannelMapping,
|
|
40
40
|
setBridgeConfig,
|
|
41
41
|
setChannelMapping
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-PKGA23XM.js";
|
|
43
43
|
import {
|
|
44
44
|
PROMPT_DEFAULTS,
|
|
45
45
|
PROMPT_KEYS,
|
|
@@ -47,12 +47,15 @@ import {
|
|
|
47
47
|
RotatingLog,
|
|
48
48
|
announceToSystem,
|
|
49
49
|
assignSession,
|
|
50
|
+
clearDeliveredNotices,
|
|
50
51
|
completeOrphanedTurns,
|
|
51
52
|
completeTurn,
|
|
52
53
|
createTurn,
|
|
53
54
|
deleteSystemsConfig,
|
|
54
55
|
deliverMessage,
|
|
56
|
+
drainNotices,
|
|
55
57
|
ensureSystemChannel,
|
|
58
|
+
formatNotices,
|
|
56
59
|
generateSystemReply,
|
|
57
60
|
getActiveTurnId,
|
|
58
61
|
getAllDiscoveredExtensions,
|
|
@@ -81,12 +84,14 @@ import {
|
|
|
81
84
|
joinSystemChannel,
|
|
82
85
|
linkToolResultToTurn,
|
|
83
86
|
loadAllExtensions,
|
|
87
|
+
markErrored,
|
|
84
88
|
notifyExtensionsDaemonStart,
|
|
85
89
|
notifyExtensionsDaemonStop,
|
|
86
90
|
publish as publish2,
|
|
87
91
|
publishTypingForChannels,
|
|
88
92
|
readSystemsConfig,
|
|
89
93
|
recordInbound,
|
|
94
|
+
recordNotice,
|
|
90
95
|
recordOutbound,
|
|
91
96
|
resolveMindToken,
|
|
92
97
|
setExtensionEnabled,
|
|
@@ -97,20 +102,22 @@ import {
|
|
|
97
102
|
substitute,
|
|
98
103
|
summarizeOrphanedTurns,
|
|
99
104
|
summarizeTurn,
|
|
105
|
+
syncProviderToMinds,
|
|
100
106
|
tagUntaggedInbound,
|
|
101
107
|
tagUntaggedOutbound,
|
|
108
|
+
takeErrored,
|
|
102
109
|
trackToolUse,
|
|
103
110
|
uninstallNpmExtension,
|
|
104
111
|
writeSystemsConfig
|
|
105
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-BLAXARBZ.js";
|
|
106
113
|
import {
|
|
107
114
|
loadMergedEnv,
|
|
108
115
|
mindEnvPath,
|
|
109
116
|
readEnv,
|
|
110
117
|
sharedEnvPath,
|
|
111
118
|
writeEnv
|
|
112
|
-
} from "./chunk-
|
|
113
|
-
import "./chunk-
|
|
119
|
+
} from "./chunk-ITH5ZLZJ.js";
|
|
120
|
+
import "./chunk-YTNBO7S6.js";
|
|
114
121
|
import {
|
|
115
122
|
applyInitFiles,
|
|
116
123
|
composeTemplate,
|
|
@@ -137,7 +144,7 @@ import {
|
|
|
137
144
|
syncBuiltinSkills,
|
|
138
145
|
uninstallSkill,
|
|
139
146
|
updateSkill
|
|
140
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-QV7P3TYO.js";
|
|
141
148
|
import {
|
|
142
149
|
addMessage,
|
|
143
150
|
createChannel,
|
|
@@ -169,25 +176,25 @@ import {
|
|
|
169
176
|
setConversationPrivate,
|
|
170
177
|
subscribe as subscribe2,
|
|
171
178
|
updateChannelSettings
|
|
172
|
-
} from "./chunk-
|
|
179
|
+
} from "./chunk-3Y7UDHO7.js";
|
|
173
180
|
import {
|
|
174
181
|
readVoluteConfig,
|
|
175
182
|
writeVoluteConfig
|
|
176
183
|
} from "./chunk-CU6OFXMM.js";
|
|
177
|
-
import "./chunk-
|
|
184
|
+
import "./chunk-KMHC36CA.js";
|
|
178
185
|
import {
|
|
179
186
|
getActiveMinds,
|
|
180
187
|
onMindEvent,
|
|
181
188
|
stopAll
|
|
182
|
-
} from "./chunk-
|
|
189
|
+
} from "./chunk-ANSTTB55.js";
|
|
183
190
|
import {
|
|
184
191
|
extractTextContent
|
|
185
|
-
} from "./chunk-
|
|
192
|
+
} from "./chunk-NERYUSER.js";
|
|
186
193
|
import {
|
|
187
194
|
exec,
|
|
188
195
|
gitExec,
|
|
189
196
|
resolveVoluteBin
|
|
190
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-AEAZRTEV.js";
|
|
191
198
|
import {
|
|
192
199
|
chownMindDir,
|
|
193
200
|
createMindUser,
|
|
@@ -195,7 +202,29 @@ import {
|
|
|
195
202
|
ensureVoluteGroup,
|
|
196
203
|
isIsolationEnabled,
|
|
197
204
|
wrapForIsolation
|
|
198
|
-
} from "./chunk-
|
|
205
|
+
} from "./chunk-6SYHHEQ7.js";
|
|
206
|
+
import {
|
|
207
|
+
getAiConfig,
|
|
208
|
+
getAvailableModels,
|
|
209
|
+
getConfiguredProviders,
|
|
210
|
+
getEnabledModels,
|
|
211
|
+
getUtilityModel,
|
|
212
|
+
qualifyModelId,
|
|
213
|
+
removeAiConfig,
|
|
214
|
+
removeProviderConfig,
|
|
215
|
+
resolveApiKey,
|
|
216
|
+
resolveTemplate,
|
|
217
|
+
saveProviderConfig,
|
|
218
|
+
setEnabledModels,
|
|
219
|
+
setProviderRefreshHook,
|
|
220
|
+
setUtilityModel,
|
|
221
|
+
unqualifyModelId
|
|
222
|
+
} from "./chunk-S4SXBQ7F.js";
|
|
223
|
+
import {
|
|
224
|
+
isSetupComplete,
|
|
225
|
+
readGlobalConfig,
|
|
226
|
+
writeGlobalConfig
|
|
227
|
+
} from "./chunk-DNU6XLE2.js";
|
|
199
228
|
import {
|
|
200
229
|
approveUser,
|
|
201
230
|
changePassword,
|
|
@@ -214,32 +243,11 @@ import {
|
|
|
214
243
|
syncMindProfile,
|
|
215
244
|
updateUserProfile,
|
|
216
245
|
verifyUser
|
|
217
|
-
} from "./chunk-
|
|
246
|
+
} from "./chunk-E25SO3QW.js";
|
|
218
247
|
import {
|
|
219
248
|
broadcast,
|
|
220
249
|
subscribe
|
|
221
|
-
} from "./chunk-
|
|
222
|
-
import {
|
|
223
|
-
getAiConfig,
|
|
224
|
-
getAvailableModels,
|
|
225
|
-
getConfiguredProviders,
|
|
226
|
-
getEnabledModels,
|
|
227
|
-
getUtilityModel,
|
|
228
|
-
qualifyModelId,
|
|
229
|
-
removeAiConfig,
|
|
230
|
-
removeProviderConfig,
|
|
231
|
-
resolveApiKey,
|
|
232
|
-
resolveTemplate,
|
|
233
|
-
saveProviderConfig,
|
|
234
|
-
setEnabledModels,
|
|
235
|
-
setUtilityModel,
|
|
236
|
-
unqualifyModelId
|
|
237
|
-
} from "./chunk-B7MWXFAH.js";
|
|
238
|
-
import {
|
|
239
|
-
isSetupComplete,
|
|
240
|
-
readGlobalConfig,
|
|
241
|
-
writeGlobalConfig
|
|
242
|
-
} from "./chunk-TCNCRDB5.js";
|
|
250
|
+
} from "./chunk-QYI65HCL.js";
|
|
243
251
|
import {
|
|
244
252
|
logBuffer,
|
|
245
253
|
logger_default
|
|
@@ -269,7 +277,7 @@ import {
|
|
|
269
277
|
validateMindName,
|
|
270
278
|
voluteHome,
|
|
271
279
|
voluteSystemDir
|
|
272
|
-
} from "./chunk-
|
|
280
|
+
} from "./chunk-B4WPXYPI.js";
|
|
273
281
|
import {
|
|
274
282
|
activity,
|
|
275
283
|
channels,
|
|
@@ -281,14 +289,14 @@ import {
|
|
|
281
289
|
systemPrompts,
|
|
282
290
|
turns,
|
|
283
291
|
users
|
|
284
|
-
} from "./chunk-
|
|
285
|
-
import "./chunk-
|
|
292
|
+
} from "./chunk-2HZRJ35V.js";
|
|
293
|
+
import "./chunk-LMMQX4CK.js";
|
|
286
294
|
|
|
287
295
|
// packages/daemon/src/daemon.ts
|
|
288
296
|
import { randomBytes } from "crypto";
|
|
289
297
|
import { mkdirSync as mkdirSync10, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
|
|
290
298
|
import { homedir as homedir3 } from "os";
|
|
291
|
-
import { resolve as
|
|
299
|
+
import { resolve as resolve17 } from "path";
|
|
292
300
|
import { format } from "util";
|
|
293
301
|
|
|
294
302
|
// packages/daemon/src/lib/daemon/bridge-manager.ts
|
|
@@ -498,8 +506,8 @@ var BridgeManager = class {
|
|
|
498
506
|
if (!tracked) return;
|
|
499
507
|
this.stopping.add(platform);
|
|
500
508
|
this.bridges.delete(platform);
|
|
501
|
-
await new Promise((
|
|
502
|
-
tracked.child.on("exit", () =>
|
|
509
|
+
await new Promise((resolve18) => {
|
|
510
|
+
tracked.child.on("exit", () => resolve18());
|
|
503
511
|
try {
|
|
504
512
|
if (tracked.child.pid) {
|
|
505
513
|
process.kill(-tracked.child.pid, "SIGTERM");
|
|
@@ -510,7 +518,7 @@ var BridgeManager = class {
|
|
|
510
518
|
if (err instanceof Error && err.code !== "ESRCH") {
|
|
511
519
|
blog.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
|
|
512
520
|
}
|
|
513
|
-
|
|
521
|
+
resolve18();
|
|
514
522
|
}
|
|
515
523
|
setTimeout(() => {
|
|
516
524
|
try {
|
|
@@ -521,7 +529,7 @@ var BridgeManager = class {
|
|
|
521
529
|
}
|
|
522
530
|
} catch {
|
|
523
531
|
}
|
|
524
|
-
|
|
532
|
+
resolve18();
|
|
525
533
|
}, 5e3);
|
|
526
534
|
});
|
|
527
535
|
this.stopping.delete(platform);
|
|
@@ -985,10 +993,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
985
993
|
stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
|
|
986
994
|
});
|
|
987
995
|
});
|
|
988
|
-
await new Promise((
|
|
996
|
+
await new Promise((resolve18) => {
|
|
989
997
|
stream.onAbort(() => {
|
|
990
998
|
unsubscribe();
|
|
991
|
-
|
|
999
|
+
resolve18();
|
|
992
1000
|
});
|
|
993
1001
|
});
|
|
994
1002
|
});
|
|
@@ -1301,8 +1309,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1301
1309
|
createdAt: Date.now()
|
|
1302
1310
|
};
|
|
1303
1311
|
oauthFlows.set(flowId, flow);
|
|
1304
|
-
const promptPromise = needsManualCode ? new Promise((
|
|
1305
|
-
flow.resolveCode =
|
|
1312
|
+
const promptPromise = needsManualCode ? new Promise((resolve18) => {
|
|
1313
|
+
flow.resolveCode = resolve18;
|
|
1306
1314
|
}) : void 0;
|
|
1307
1315
|
oauthProvider.login({
|
|
1308
1316
|
onAuth: (info) => {
|
|
@@ -1332,7 +1340,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1332
1340
|
existing.error = err instanceof Error ? err.message : String(err);
|
|
1333
1341
|
}
|
|
1334
1342
|
});
|
|
1335
|
-
await new Promise((
|
|
1343
|
+
await new Promise((resolve18) => setTimeout(resolve18, 2e3));
|
|
1336
1344
|
const state = oauthFlows.get(flowId);
|
|
1337
1345
|
return c.json({
|
|
1338
1346
|
flowId,
|
|
@@ -1590,8 +1598,8 @@ var app2 = new Hono2().get("/events", async (c) => {
|
|
|
1590
1598
|
});
|
|
1591
1599
|
}, 15e3);
|
|
1592
1600
|
cleanups.push(() => clearInterval(keepAlive));
|
|
1593
|
-
await new Promise((
|
|
1594
|
-
stream.onAbort(() =>
|
|
1601
|
+
await new Promise((resolve18) => {
|
|
1602
|
+
stream.onAbort(() => resolve18());
|
|
1595
1603
|
});
|
|
1596
1604
|
} finally {
|
|
1597
1605
|
for (const cleanup of cleanups) {
|
|
@@ -1994,7 +2002,7 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
|
|
|
1994
2002
|
}
|
|
1995
2003
|
const participants = await getParticipants(channel.id);
|
|
1996
2004
|
if (!participants.some((p) => p.userId === puppet.id)) {
|
|
1997
|
-
const { addParticipant } = await import("./conversations-
|
|
2005
|
+
const { addParticipant } = await import("./conversations-AYLXPOGC.js");
|
|
1998
2006
|
await addParticipant(channel.id, puppet.id);
|
|
1999
2007
|
}
|
|
2000
2008
|
const contentBlocks = body.content;
|
|
@@ -2087,8 +2095,8 @@ async function fanOutToBridgedMinds(opts) {
|
|
|
2087
2095
|
const participants = await getParticipants(opts.conversationId);
|
|
2088
2096
|
const mindParticipants = participants.filter((p) => p.userType === "mind");
|
|
2089
2097
|
const participantNames = participants.map((p) => p.username);
|
|
2090
|
-
const { getMindManager: getMindManager2 } = await import("./mind-manager-
|
|
2091
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
2098
|
+
const { getMindManager: getMindManager2 } = await import("./mind-manager-EDCLALBF.js");
|
|
2099
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-5277OBHI.js");
|
|
2092
2100
|
const manager = getMindManager2();
|
|
2093
2101
|
const sm = getSleepManagerIfReady2();
|
|
2094
2102
|
const targetMinds = mindParticipants.filter((ap) => {
|
|
@@ -2174,13 +2182,13 @@ var config_default = config;
|
|
|
2174
2182
|
|
|
2175
2183
|
// packages/daemon/src/web/api/env.ts
|
|
2176
2184
|
import { Hono as Hono7 } from "hono";
|
|
2177
|
-
var app6 = new Hono7().get("/:name/env", async (c) => {
|
|
2185
|
+
var app6 = new Hono7().get("/:name/env", requireSelf(), async (c) => {
|
|
2178
2186
|
const name = c.req.param("name");
|
|
2179
2187
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
2180
2188
|
const shared = readEnv(sharedEnvPath());
|
|
2181
2189
|
const mind = readEnv(mindEnvPath(name));
|
|
2182
2190
|
return c.json({ shared, mind });
|
|
2183
|
-
}).get("/:name/env/:key", async (c) => {
|
|
2191
|
+
}).get("/:name/env/:key", requireSelf(), async (c) => {
|
|
2184
2192
|
const name = c.req.param("name");
|
|
2185
2193
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
2186
2194
|
const key = c.req.param("key");
|
|
@@ -2217,7 +2225,7 @@ var app6 = new Hono7().get("/:name/env", async (c) => {
|
|
|
2217
2225
|
writeEnv(path, env);
|
|
2218
2226
|
return c.json({ ok: true });
|
|
2219
2227
|
});
|
|
2220
|
-
var sharedEnvApp = new Hono7().get("/", (c) => {
|
|
2228
|
+
var sharedEnvApp = new Hono7().get("/", requireAdmin, (c) => {
|
|
2221
2229
|
return c.json(readEnv(sharedEnvPath()));
|
|
2222
2230
|
}).put("/:key", requireAdmin, async (c) => {
|
|
2223
2231
|
const key = c.req.param("key");
|
|
@@ -2253,7 +2261,7 @@ var app7 = new Hono8().get("/", (c) => {
|
|
|
2253
2261
|
}).get("/all", (c) => {
|
|
2254
2262
|
const detail = c.req.query("detail") === "true";
|
|
2255
2263
|
return c.json(detail ? getAllDiscoveredExtensionsDetailed() : getAllDiscoveredExtensions());
|
|
2256
|
-
}).put("/:id/enabled", async (c) => {
|
|
2264
|
+
}).put("/:id/enabled", requireAdmin, async (c) => {
|
|
2257
2265
|
const { id } = c.req.param();
|
|
2258
2266
|
const body = await c.req.json().catch(() => null);
|
|
2259
2267
|
if (!body || typeof body.enabled !== "boolean") {
|
|
@@ -2265,7 +2273,7 @@ var app7 = new Hono8().get("/", (c) => {
|
|
|
2265
2273
|
return c.json({ error: err.message }, 404);
|
|
2266
2274
|
}
|
|
2267
2275
|
return c.json({ ok: true, requiresRestart: true });
|
|
2268
|
-
}).post("/install", async (c) => {
|
|
2276
|
+
}).post("/install", requireAdmin, async (c) => {
|
|
2269
2277
|
const body = await c.req.json();
|
|
2270
2278
|
const pkg = body.package?.trim();
|
|
2271
2279
|
if (!pkg) {
|
|
@@ -2279,7 +2287,7 @@ var app7 = new Hono8().get("/", (c) => {
|
|
|
2279
2287
|
const isValidation = message.includes("already installed") || message.includes("Invalid package");
|
|
2280
2288
|
return c.json({ error: message }, isValidation ? 400 : 500);
|
|
2281
2289
|
}
|
|
2282
|
-
}).delete("/uninstall/:package", async (c) => {
|
|
2290
|
+
}).delete("/uninstall/:package", requireAdmin, async (c) => {
|
|
2283
2291
|
const pkg = c.req.param("package");
|
|
2284
2292
|
try {
|
|
2285
2293
|
await uninstallNpmExtension(pkg);
|
|
@@ -2300,7 +2308,7 @@ async function notifyMind(mindName, message) {
|
|
|
2300
2308
|
const entry = await findMind(mindName);
|
|
2301
2309
|
if (!entry) return;
|
|
2302
2310
|
try {
|
|
2303
|
-
const { sendSystemMessage } = await import("./system-chat-
|
|
2311
|
+
const { sendSystemMessage } = await import("./system-chat-LQSJVY55.js");
|
|
2304
2312
|
await sendSystemMessage(mindName, message);
|
|
2305
2313
|
} catch (err) {
|
|
2306
2314
|
logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
|
|
@@ -2349,11 +2357,11 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
2349
2357
|
`[file] ${senderName} sent ${filename} (${sizeStr}) \u2014 run: volute chat accept ${id}`
|
|
2350
2358
|
);
|
|
2351
2359
|
return c.json({ status: "pending", id }, 200);
|
|
2352
|
-
}).get("/:name/files/pending", async (c) => {
|
|
2360
|
+
}).get("/:name/files/pending", requireSelf(), async (c) => {
|
|
2353
2361
|
const name = c.req.param("name");
|
|
2354
2362
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
2355
2363
|
return c.json(listPending(name));
|
|
2356
|
-
}).post("/:name/files/accept", async (c) => {
|
|
2364
|
+
}).post("/:name/files/accept", requireSelf(), async (c) => {
|
|
2357
2365
|
const name = c.req.param("name");
|
|
2358
2366
|
const entry = await findMind(name);
|
|
2359
2367
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -2375,7 +2383,7 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
2375
2383
|
}
|
|
2376
2384
|
await notifyMind(result.sender, `[file] ${name} accepted ${result.filename}`);
|
|
2377
2385
|
return c.json({ ok: true, destPath: result.destPath });
|
|
2378
|
-
}).post("/:name/files/reject", async (c) => {
|
|
2386
|
+
}).post("/:name/files/reject", requireSelf(), async (c) => {
|
|
2379
2387
|
const name = c.req.param("name");
|
|
2380
2388
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
2381
2389
|
const body = await c.req.json();
|
|
@@ -2392,7 +2400,7 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
2392
2400
|
}
|
|
2393
2401
|
await notifyMind(result.sender, `[file] ${name} rejected ${result.filename}`);
|
|
2394
2402
|
return c.json({ ok: true });
|
|
2395
|
-
}).post("/:name/files/stage", async (c) => {
|
|
2403
|
+
}).post("/:name/files/stage", requireSelf(), async (c) => {
|
|
2396
2404
|
const receiverName = c.req.param("name");
|
|
2397
2405
|
const receiverEntry = await findMind(receiverName);
|
|
2398
2406
|
if (!receiverEntry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -2425,8 +2433,34 @@ var file_sharing_default = app8;
|
|
|
2425
2433
|
// packages/daemon/src/web/api/files.ts
|
|
2426
2434
|
import { mkdirSync as mkdirSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2427
2435
|
import { readdir, readFile, realpath, stat } from "fs/promises";
|
|
2428
|
-
import { extname as extname2, resolve as
|
|
2436
|
+
import { extname as extname2, resolve as resolve6 } from "path";
|
|
2429
2437
|
import { Hono as Hono10 } from "hono";
|
|
2438
|
+
|
|
2439
|
+
// packages/daemon/src/lib/util/paths.ts
|
|
2440
|
+
import { resolve as resolve5, sep } from "path";
|
|
2441
|
+
var PathTraversalError = class extends Error {
|
|
2442
|
+
constructor(base, userPath) {
|
|
2443
|
+
super(`Path "${userPath}" escapes base directory "${base}"`);
|
|
2444
|
+
this.name = "PathTraversalError";
|
|
2445
|
+
}
|
|
2446
|
+
};
|
|
2447
|
+
function resolveWithinBase(base, userPath) {
|
|
2448
|
+
const resolvedBase = resolve5(base);
|
|
2449
|
+
const target = resolve5(resolvedBase, userPath);
|
|
2450
|
+
if (target !== resolvedBase && !target.startsWith(resolvedBase + sep)) {
|
|
2451
|
+
throw new PathTraversalError(base, userPath);
|
|
2452
|
+
}
|
|
2453
|
+
return target;
|
|
2454
|
+
}
|
|
2455
|
+
function safeResolveWithinBase(base, userPath) {
|
|
2456
|
+
try {
|
|
2457
|
+
return resolveWithinBase(base, userPath);
|
|
2458
|
+
} catch {
|
|
2459
|
+
return null;
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
// packages/daemon/src/web/api/files.ts
|
|
2430
2464
|
var AVATAR_MIME2 = {
|
|
2431
2465
|
".png": "image/png",
|
|
2432
2466
|
".jpg": "image/jpeg",
|
|
@@ -2470,13 +2504,14 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2470
2504
|
return c.json({ error: "Invalid file type (png, jpg, gif, webp only)" }, 400);
|
|
2471
2505
|
}
|
|
2472
2506
|
const dir = entry.dir ?? mindDir(name);
|
|
2473
|
-
const homeDir =
|
|
2507
|
+
const homeDir = resolve6(dir, "home");
|
|
2474
2508
|
const filename = `avatar${ext}`;
|
|
2475
|
-
const avatarPath =
|
|
2509
|
+
const avatarPath = resolve6(homeDir, filename);
|
|
2476
2510
|
const config2 = readVoluteConfig(dir) ?? {};
|
|
2477
2511
|
const oldAvatar = config2.profile?.avatar;
|
|
2478
2512
|
if (oldAvatar && oldAvatar !== filename) {
|
|
2479
|
-
|
|
2513
|
+
const oldAvatarPath = safeResolveWithinBase(homeDir, oldAvatar);
|
|
2514
|
+
if (oldAvatarPath) rmSync2(oldAvatarPath, { force: true });
|
|
2480
2515
|
}
|
|
2481
2516
|
const buffer2 = Buffer.from(await file.arrayBuffer());
|
|
2482
2517
|
mkdirSync3(homeDir, { recursive: true });
|
|
@@ -2498,8 +2533,8 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2498
2533
|
const ext = extname2(config2.profile.avatar).toLowerCase();
|
|
2499
2534
|
const mime = AVATAR_MIME2[ext];
|
|
2500
2535
|
if (!mime) return c.json({ error: "Invalid avatar extension" }, 400);
|
|
2501
|
-
const homeDir =
|
|
2502
|
-
const avatarPath =
|
|
2536
|
+
const homeDir = resolve6(dir, "home");
|
|
2537
|
+
const avatarPath = resolve6(homeDir, config2.profile.avatar);
|
|
2503
2538
|
if (!avatarPath.startsWith(`${homeDir}/`)) return c.json({ error: "Invalid avatar path" }, 400);
|
|
2504
2539
|
let realAvatarPath;
|
|
2505
2540
|
try {
|
|
@@ -2527,7 +2562,7 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2527
2562
|
const name = c.req.param("name");
|
|
2528
2563
|
const entry = await findMind(name);
|
|
2529
2564
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
2530
|
-
const homeDir =
|
|
2565
|
+
const homeDir = resolve6(entry.dir ?? mindDir(name), "home");
|
|
2531
2566
|
let entries;
|
|
2532
2567
|
try {
|
|
2533
2568
|
entries = await readdir(homeDir, { withFileTypes: true });
|
|
@@ -2542,10 +2577,10 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2542
2577
|
const name = c.req.param("name");
|
|
2543
2578
|
const entry = await findMind(name);
|
|
2544
2579
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
2545
|
-
const homeDir =
|
|
2580
|
+
const homeDir = resolve6(entry.dir ?? mindDir(name), "home");
|
|
2546
2581
|
const wildcard = c.req.path.replace(new RegExp(`^.*/minds/${name}/files`), "") || "/";
|
|
2547
2582
|
const relativePath = wildcard.slice(1);
|
|
2548
|
-
const requestedPath =
|
|
2583
|
+
const requestedPath = resolve6(homeDir, relativePath);
|
|
2549
2584
|
if (requestedPath !== homeDir && !requestedPath.startsWith(`${homeDir}/`))
|
|
2550
2585
|
return c.text("Forbidden", 403);
|
|
2551
2586
|
if (relativePath.split("/").some((seg) => seg.startsWith("."))) return c.text("Forbidden", 403);
|
|
@@ -2977,16 +3012,16 @@ import { Hono as Hono12 } from "hono";
|
|
|
2977
3012
|
// packages/daemon/src/lib/mind/identity.ts
|
|
2978
3013
|
import { createHash, generateKeyPairSync, sign, verify } from "crypto";
|
|
2979
3014
|
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
2980
|
-
import { resolve as
|
|
3015
|
+
import { resolve as resolve7 } from "path";
|
|
2981
3016
|
function generateIdentity(mindDir2) {
|
|
2982
|
-
const identityDir =
|
|
3017
|
+
const identityDir = resolve7(mindDir2, ".mind/identity");
|
|
2983
3018
|
mkdirSync4(identityDir, { recursive: true });
|
|
2984
3019
|
const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
|
|
2985
3020
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
2986
3021
|
privateKeyEncoding: { type: "pkcs8", format: "pem" }
|
|
2987
3022
|
});
|
|
2988
|
-
const privatePath =
|
|
2989
|
-
const publicPath =
|
|
3023
|
+
const privatePath = resolve7(identityDir, "private.pem");
|
|
3024
|
+
const publicPath = resolve7(identityDir, "public.pem");
|
|
2990
3025
|
writeFileSync4(privatePath, privateKey, { mode: 384 });
|
|
2991
3026
|
writeFileSync4(publicPath, publicKey, { mode: 420 });
|
|
2992
3027
|
const config2 = readVoluteConfig(mindDir2) ?? {};
|
|
@@ -3001,7 +3036,7 @@ function getPublicKey(mindDir2) {
|
|
|
3001
3036
|
const config2 = readVoluteConfig(mindDir2);
|
|
3002
3037
|
const relPath = config2?.identity?.publicKey;
|
|
3003
3038
|
if (!relPath) return null;
|
|
3004
|
-
const fullPath =
|
|
3039
|
+
const fullPath = resolve7(mindDir2, relPath);
|
|
3005
3040
|
if (!existsSync4(fullPath)) return null;
|
|
3006
3041
|
return readFileSync5(fullPath, "utf-8");
|
|
3007
3042
|
}
|
|
@@ -3051,14 +3086,14 @@ var keys_default = app10;
|
|
|
3051
3086
|
// packages/daemon/src/web/api/logs.ts
|
|
3052
3087
|
import { spawn as spawn2 } from "child_process";
|
|
3053
3088
|
import { existsSync as existsSync5 } from "fs";
|
|
3054
|
-
import { resolve as
|
|
3089
|
+
import { resolve as resolve8 } from "path";
|
|
3055
3090
|
import { Hono as Hono13 } from "hono";
|
|
3056
3091
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
3057
|
-
var app11 = new Hono13().get("/:name/logs", async (c) => {
|
|
3092
|
+
var app11 = new Hono13().get("/:name/logs", requireSelf(), async (c) => {
|
|
3058
3093
|
const name = c.req.param("name");
|
|
3059
3094
|
const entry = await findMind(name);
|
|
3060
3095
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
3061
|
-
const logFile =
|
|
3096
|
+
const logFile = resolve8(stateDir(name), "logs", "mind.log");
|
|
3062
3097
|
if (!existsSync5(logFile)) {
|
|
3063
3098
|
return c.json({ error: "No log file found" }, 404);
|
|
3064
3099
|
}
|
|
@@ -3077,16 +3112,16 @@ var app11 = new Hono13().get("/:name/logs", async (c) => {
|
|
|
3077
3112
|
stream.onAbort(() => {
|
|
3078
3113
|
tail.kill();
|
|
3079
3114
|
});
|
|
3080
|
-
await new Promise((
|
|
3081
|
-
tail.on("exit",
|
|
3082
|
-
stream.onAbort(
|
|
3115
|
+
await new Promise((resolve18) => {
|
|
3116
|
+
tail.on("exit", resolve18);
|
|
3117
|
+
stream.onAbort(resolve18);
|
|
3083
3118
|
});
|
|
3084
3119
|
});
|
|
3085
|
-
}).get("/:name/logs/tail", async (c) => {
|
|
3120
|
+
}).get("/:name/logs/tail", requireSelf(), async (c) => {
|
|
3086
3121
|
const name = c.req.param("name");
|
|
3087
3122
|
const entry = await findMind(name);
|
|
3088
3123
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
3089
|
-
const logFile =
|
|
3124
|
+
const logFile = resolve8(stateDir(name), "logs", "mind.log");
|
|
3090
3125
|
if (!existsSync5(logFile)) {
|
|
3091
3126
|
return c.json({ error: "No log file found" }, 404);
|
|
3092
3127
|
}
|
|
@@ -3097,8 +3132,8 @@ var app11 = new Hono13().get("/:name/logs", async (c) => {
|
|
|
3097
3132
|
tail.stdout.on("data", (data) => {
|
|
3098
3133
|
output += data.toString();
|
|
3099
3134
|
});
|
|
3100
|
-
await new Promise((
|
|
3101
|
-
tail.on("exit",
|
|
3135
|
+
await new Promise((resolve18) => {
|
|
3136
|
+
tail.on("exit", resolve18);
|
|
3102
3137
|
});
|
|
3103
3138
|
return c.text(output);
|
|
3104
3139
|
});
|
|
@@ -3195,26 +3230,63 @@ import {
|
|
|
3195
3230
|
rmSync as rmSync4,
|
|
3196
3231
|
writeFileSync as writeFileSync7
|
|
3197
3232
|
} from "fs";
|
|
3198
|
-
import { resolve as
|
|
3233
|
+
import { basename, resolve as resolve11 } from "path";
|
|
3199
3234
|
import { zValidator as zValidator5 } from "@hono/zod-validator";
|
|
3200
3235
|
import { and as and4, desc as desc3, eq as eq5, sql as sql2 } from "drizzle-orm";
|
|
3201
3236
|
import { Hono as Hono15 } from "hono";
|
|
3202
3237
|
import { z as z5 } from "zod";
|
|
3203
3238
|
|
|
3239
|
+
// packages/daemon/src/lib/daemon/error-classify.ts
|
|
3240
|
+
function classify(raw) {
|
|
3241
|
+
const s = (raw ?? "").toLowerCase();
|
|
3242
|
+
if (/\b(401|403)\b|authentication_error|invalid authentication|invalid x-api-key|unauthorized|permission_error/.test(
|
|
3243
|
+
s
|
|
3244
|
+
)) {
|
|
3245
|
+
return {
|
|
3246
|
+
reason: "auth_error",
|
|
3247
|
+
detail: "Your last turn failed because your model credentials were rejected (most often an expired token). The daemon refreshes them automatically, so this is normally transient \u2014 you're fine to continue."
|
|
3248
|
+
};
|
|
3249
|
+
}
|
|
3250
|
+
if (/\b429\b|rate.?limit|too many requests/.test(s)) {
|
|
3251
|
+
return {
|
|
3252
|
+
reason: "rate_limit",
|
|
3253
|
+
detail: "Your last turn failed because you hit the model provider's rate limit. This is temporary \u2014 it clears on its own shortly."
|
|
3254
|
+
};
|
|
3255
|
+
}
|
|
3256
|
+
if (/\b529\b|overloaded/.test(s)) {
|
|
3257
|
+
return {
|
|
3258
|
+
reason: "overloaded",
|
|
3259
|
+
detail: "Your last turn failed because the model provider was overloaded (a 529). This is transient and resolves on its own."
|
|
3260
|
+
};
|
|
3261
|
+
}
|
|
3262
|
+
if (/econnreset|etimedout|enotfound|econnrefused|fetch failed|network|socket hang up|timeout/.test(
|
|
3263
|
+
s
|
|
3264
|
+
)) {
|
|
3265
|
+
return {
|
|
3266
|
+
reason: "network",
|
|
3267
|
+
detail: "Your last turn failed due to a network error reaching the model provider. This is transient \u2014 the connection should recover."
|
|
3268
|
+
};
|
|
3269
|
+
}
|
|
3270
|
+
return {
|
|
3271
|
+
reason: "unknown",
|
|
3272
|
+
detail: `Your last turn failed with an error: ${raw}`
|
|
3273
|
+
};
|
|
3274
|
+
}
|
|
3275
|
+
|
|
3204
3276
|
// packages/daemon/src/lib/mind/consolidate.ts
|
|
3205
3277
|
import { readdirSync, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
3206
|
-
import { resolve as
|
|
3278
|
+
import { resolve as resolve9 } from "path";
|
|
3207
3279
|
async function consolidateMemory(mindDir2) {
|
|
3208
|
-
const soulPath =
|
|
3209
|
-
const memoryPath =
|
|
3210
|
-
const memoryDir =
|
|
3280
|
+
const soulPath = resolve9(mindDir2, "home/SOUL.md");
|
|
3281
|
+
const memoryPath = resolve9(mindDir2, "home/MEMORY.md");
|
|
3282
|
+
const memoryDir = resolve9(mindDir2, "home/memory");
|
|
3211
3283
|
const soul = readFileSync6(soulPath, "utf-8");
|
|
3212
3284
|
const logs = [];
|
|
3213
3285
|
try {
|
|
3214
3286
|
const files = readdirSync(memoryDir).filter((f) => /^\d{4}-\d{2}-\d{2}\.md$/.test(f)).sort();
|
|
3215
3287
|
for (const filename of files) {
|
|
3216
3288
|
const date = filename.replace(".md", "");
|
|
3217
|
-
const content2 = readFileSync6(
|
|
3289
|
+
const content2 = readFileSync6(resolve9(memoryDir, filename), "utf-8").trim();
|
|
3218
3290
|
if (content2) {
|
|
3219
3291
|
logs.push(`### ${date}
|
|
3220
3292
|
|
|
@@ -3282,7 +3354,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
|
3282
3354
|
logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
|
|
3283
3355
|
}
|
|
3284
3356
|
}
|
|
3285
|
-
const { findMind: findMind2 } = await import("./registry-
|
|
3357
|
+
const { findMind: findMind2 } = await import("./registry-GV35XFT7.js");
|
|
3286
3358
|
const variantEntry = await findMind2(variantName);
|
|
3287
3359
|
const branchName = variantEntry?.branch ?? variantName;
|
|
3288
3360
|
if (existsSync6(variantPath)) {
|
|
@@ -3334,7 +3406,7 @@ function validateBranchName(branch) {
|
|
|
3334
3406
|
import { randomUUID } from "crypto";
|
|
3335
3407
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
3336
3408
|
import { homedir } from "os";
|
|
3337
|
-
import { resolve as
|
|
3409
|
+
import { resolve as resolve10 } from "path";
|
|
3338
3410
|
function convertSession(opts) {
|
|
3339
3411
|
const lines = readFileSync7(opts.sessionPath, "utf-8").trim().split("\n");
|
|
3340
3412
|
const sessionId = randomUUID();
|
|
@@ -3450,9 +3522,9 @@ function convertSession(opts) {
|
|
|
3450
3522
|
}
|
|
3451
3523
|
}
|
|
3452
3524
|
const projectId = opts.projectDir.replace(/\//g, "-");
|
|
3453
|
-
const sdkDir =
|
|
3525
|
+
const sdkDir = resolve10(homedir(), ".claude", "projects", projectId);
|
|
3454
3526
|
mkdirSync5(sdkDir, { recursive: true });
|
|
3455
|
-
const sdkPath =
|
|
3527
|
+
const sdkPath = resolve10(sdkDir, `${sessionId}.jsonl`);
|
|
3456
3528
|
writeFileSync6(sdkPath, `${sdkEvents.join("\n")}
|
|
3457
3529
|
`);
|
|
3458
3530
|
console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
|
|
@@ -3520,13 +3592,26 @@ async function checkHealth(port) {
|
|
|
3520
3592
|
|
|
3521
3593
|
// packages/daemon/src/web/api/minds.ts
|
|
3522
3594
|
var SUBSTANTIVE_TYPES = /* @__PURE__ */ new Set(["thinking", "text", "tool_use", "tool_result", "outbound"]);
|
|
3595
|
+
var noticeDrainWatermarks = /* @__PURE__ */ new Map();
|
|
3596
|
+
function markDeliveredOnCleanTurn(mind, session) {
|
|
3597
|
+
if (!session) return;
|
|
3598
|
+
const wmKey = `${mind}:${session}`;
|
|
3599
|
+
const watermark = noticeDrainWatermarks.get(wmKey);
|
|
3600
|
+
noticeDrainWatermarks.delete(wmKey);
|
|
3601
|
+
const errored = takeErrored(mind, session);
|
|
3602
|
+
if (!errored && watermark != null) {
|
|
3603
|
+
clearDeliveredNotices(mind, session, watermark).catch(
|
|
3604
|
+
(err) => logger_default.warn(`failed to clear delivered notices for ${mind}:${session}`, logger_default.errorData(err))
|
|
3605
|
+
);
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3523
3608
|
var _lastActiveCache = { map: /* @__PURE__ */ new Map(), ts: 0 };
|
|
3524
3609
|
var _LAST_ACTIVE_TTL = 6e4;
|
|
3525
3610
|
async function getMindStatus(name, port, registryRunning) {
|
|
3526
3611
|
const manager = getMindManager();
|
|
3527
3612
|
let status = "stopped";
|
|
3528
3613
|
try {
|
|
3529
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
3614
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-5277OBHI.js");
|
|
3530
3615
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
3531
3616
|
status = "sleeping";
|
|
3532
3617
|
}
|
|
@@ -3572,7 +3657,7 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
|
|
|
3572
3657
|
await gitExec(["commit", "-m", "initial commit"], opts);
|
|
3573
3658
|
}
|
|
3574
3659
|
async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
3575
|
-
const tempWorktree =
|
|
3660
|
+
const tempWorktree = resolve11(projectRoot, ".variants", "_template_update");
|
|
3576
3661
|
let branchExists = false;
|
|
3577
3662
|
try {
|
|
3578
3663
|
await gitExec(["rev-parse", "--verify", TEMPLATE_BRANCH], { cwd: projectRoot });
|
|
@@ -3604,15 +3689,15 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
3604
3689
|
});
|
|
3605
3690
|
}
|
|
3606
3691
|
copyTemplateToDir(composedDir, tempWorktree, mindName, manifest);
|
|
3607
|
-
const initDir =
|
|
3692
|
+
const initDir = resolve11(tempWorktree, ".init");
|
|
3608
3693
|
if (existsSync7(initDir)) {
|
|
3609
3694
|
rmSync4(initDir, { recursive: true, force: true });
|
|
3610
3695
|
}
|
|
3611
|
-
const homeDir =
|
|
3696
|
+
const homeDir = resolve11(tempWorktree, "home");
|
|
3612
3697
|
if (existsSync7(homeDir)) {
|
|
3613
3698
|
for (const entry of readdirSync2(homeDir)) {
|
|
3614
3699
|
if (entry !== "VOLUTE.md") {
|
|
3615
|
-
rmSync4(
|
|
3700
|
+
rmSync4(resolve11(homeDir, entry), { recursive: true, force: true });
|
|
3616
3701
|
}
|
|
3617
3702
|
}
|
|
3618
3703
|
}
|
|
@@ -3653,7 +3738,7 @@ async function mergeTemplateBranch(worktreeDir) {
|
|
|
3653
3738
|
async function npmInstallAsMind(cwd, mindName) {
|
|
3654
3739
|
if (isIsolationEnabled()) {
|
|
3655
3740
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
3656
|
-
await exec(cmd, args, { cwd, env: { ...process.env, HOME:
|
|
3741
|
+
await exec(cmd, args, { cwd, env: { ...process.env, HOME: resolve11(cwd, "home") } });
|
|
3657
3742
|
} else {
|
|
3658
3743
|
await exec("npm", ["install"], { cwd });
|
|
3659
3744
|
}
|
|
@@ -3704,7 +3789,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
3704
3789
|
return { ok: true };
|
|
3705
3790
|
}
|
|
3706
3791
|
async function importFromArchive(c, tempDir, nameOverride, manifest) {
|
|
3707
|
-
const extractedMindDir =
|
|
3792
|
+
const extractedMindDir = resolve11(tempDir, "mind");
|
|
3708
3793
|
if (!existsSync7(extractedMindDir)) {
|
|
3709
3794
|
return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
|
|
3710
3795
|
}
|
|
@@ -3731,9 +3816,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
3731
3816
|
}
|
|
3732
3817
|
const state = stateDir(name);
|
|
3733
3818
|
mkdirSync6(state, { recursive: true });
|
|
3734
|
-
const envJson =
|
|
3819
|
+
const envJson = resolve11(tempDir, "state/env.json");
|
|
3735
3820
|
if (existsSync7(envJson)) {
|
|
3736
|
-
cpSync(envJson,
|
|
3821
|
+
cpSync(envJson, resolve11(state, "env.json"));
|
|
3737
3822
|
}
|
|
3738
3823
|
const port = await nextPort();
|
|
3739
3824
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
@@ -3742,23 +3827,23 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
3742
3827
|
} catch (err) {
|
|
3743
3828
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
3744
3829
|
}
|
|
3745
|
-
const homeDir =
|
|
3830
|
+
const homeDir = resolve11(dest, "home");
|
|
3746
3831
|
ensureVoluteGroup();
|
|
3747
3832
|
createMindUser(name, homeDir);
|
|
3748
3833
|
chownMindDir(dest, name);
|
|
3749
3834
|
await npmInstallAsMind(dest, name);
|
|
3750
3835
|
await importHistoryFromArchive(name, tempDir);
|
|
3751
3836
|
importSessionsFromArchive(dest, tempDir);
|
|
3752
|
-
if (!existsSync7(
|
|
3837
|
+
if (!existsSync7(resolve11(dest, ".git"))) {
|
|
3753
3838
|
try {
|
|
3754
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
3839
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
|
|
3755
3840
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
3756
3841
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
3757
3842
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
3758
3843
|
await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
|
|
3759
3844
|
} catch (err) {
|
|
3760
3845
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
3761
|
-
rmSync4(
|
|
3846
|
+
rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
3762
3847
|
}
|
|
3763
3848
|
}
|
|
3764
3849
|
chownMindDir(dest, name);
|
|
@@ -3791,22 +3876,22 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3791
3876
|
try {
|
|
3792
3877
|
copyTemplateToDir(composedDir, dest, name, templateManifest);
|
|
3793
3878
|
applyInitFiles(dest);
|
|
3794
|
-
const extractedHome =
|
|
3879
|
+
const extractedHome = resolve11(extractedMindDir, "home");
|
|
3795
3880
|
if (existsSync7(extractedHome)) {
|
|
3796
|
-
cpSync(extractedHome,
|
|
3881
|
+
cpSync(extractedHome, resolve11(dest, "home"), { recursive: true });
|
|
3797
3882
|
}
|
|
3798
|
-
const extractedMindInternal =
|
|
3883
|
+
const extractedMindInternal = resolve11(extractedMindDir, ".mind");
|
|
3799
3884
|
if (existsSync7(extractedMindInternal)) {
|
|
3800
|
-
cpSync(extractedMindInternal,
|
|
3885
|
+
cpSync(extractedMindInternal, resolve11(dest, ".mind"), { recursive: true });
|
|
3801
3886
|
}
|
|
3802
|
-
const identityDir =
|
|
3887
|
+
const identityDir = resolve11(dest, ".mind/identity");
|
|
3803
3888
|
let publicKeyPem;
|
|
3804
|
-
if (!manifest.includes.identity || !existsSync7(
|
|
3889
|
+
if (!manifest.includes.identity || !existsSync7(resolve11(identityDir, "private.pem"))) {
|
|
3805
3890
|
({ publicKeyPem } = generateIdentity(dest));
|
|
3806
3891
|
} else {
|
|
3807
|
-
publicKeyPem = readFileSync8(
|
|
3892
|
+
publicKeyPem = readFileSync8(resolve11(identityDir, "public.pem"), "utf-8");
|
|
3808
3893
|
}
|
|
3809
|
-
const promptsPath =
|
|
3894
|
+
const promptsPath = resolve11(dest, "home/.config/prompts.json");
|
|
3810
3895
|
if (!existsSync7(promptsPath)) {
|
|
3811
3896
|
const mindPrompts = await getMindPromptDefaults();
|
|
3812
3897
|
writeFileSync7(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
|
|
@@ -3814,13 +3899,13 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3814
3899
|
}
|
|
3815
3900
|
const state = stateDir(name);
|
|
3816
3901
|
mkdirSync6(state, { recursive: true });
|
|
3817
|
-
const envJson =
|
|
3902
|
+
const envJson = resolve11(tempDir, "state/env.json");
|
|
3818
3903
|
if (existsSync7(envJson)) {
|
|
3819
|
-
cpSync(envJson,
|
|
3904
|
+
cpSync(envJson, resolve11(state, "env.json"));
|
|
3820
3905
|
}
|
|
3821
3906
|
const port = await nextPort();
|
|
3822
3907
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
3823
|
-
const homeDir =
|
|
3908
|
+
const homeDir = resolve11(dest, "home");
|
|
3824
3909
|
ensureVoluteGroup();
|
|
3825
3910
|
createMindUser(name, homeDir);
|
|
3826
3911
|
chownMindDir(dest, name);
|
|
@@ -3833,7 +3918,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3833
3918
|
await initTemplateBranch(dest, composedDir, templateManifest, name, env);
|
|
3834
3919
|
} catch (err) {
|
|
3835
3920
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
3836
|
-
rmSync4(
|
|
3921
|
+
rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
3837
3922
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
3838
3923
|
}
|
|
3839
3924
|
const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
|
|
@@ -3876,7 +3961,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3876
3961
|
}
|
|
3877
3962
|
}
|
|
3878
3963
|
async function importHistoryFromArchive(name, tempDir) {
|
|
3879
|
-
const historyJsonl =
|
|
3964
|
+
const historyJsonl = resolve11(tempDir, "history.jsonl");
|
|
3880
3965
|
if (!existsSync7(historyJsonl)) return;
|
|
3881
3966
|
try {
|
|
3882
3967
|
const db = await getDb();
|
|
@@ -3916,13 +4001,13 @@ async function importHistoryFromArchive(name, tempDir) {
|
|
|
3916
4001
|
}
|
|
3917
4002
|
}
|
|
3918
4003
|
function importSessionsFromArchive(dest, tempDir) {
|
|
3919
|
-
const sessionsDir =
|
|
4004
|
+
const sessionsDir = resolve11(tempDir, "sessions");
|
|
3920
4005
|
if (!existsSync7(sessionsDir)) return;
|
|
3921
4006
|
try {
|
|
3922
|
-
const destSessions =
|
|
4007
|
+
const destSessions = resolve11(dest, ".mind/sessions");
|
|
3923
4008
|
mkdirSync6(destSessions, { recursive: true });
|
|
3924
4009
|
for (const file of readdirSync2(sessionsDir)) {
|
|
3925
|
-
cpSync(
|
|
4010
|
+
cpSync(resolve11(sessionsDir, file), resolve11(destSessions, file));
|
|
3926
4011
|
}
|
|
3927
4012
|
} catch (err) {
|
|
3928
4013
|
logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
|
|
@@ -3948,6 +4033,38 @@ function formatTimeAgo(date) {
|
|
|
3948
4033
|
const days = Math.floor(hours / 24);
|
|
3949
4034
|
return `${days}d ago`;
|
|
3950
4035
|
}
|
|
4036
|
+
async function proxyToMind(c, path) {
|
|
4037
|
+
const name = c.req.param("name");
|
|
4038
|
+
const entry = await findMind(name);
|
|
4039
|
+
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4040
|
+
if (!getMindManager().isRunning(name)) {
|
|
4041
|
+
return c.json({ error: "Mind is not running" }, 503);
|
|
4042
|
+
}
|
|
4043
|
+
try {
|
|
4044
|
+
const res = await fetch(`http://127.0.0.1:${entry.port}/${path}`, {
|
|
4045
|
+
signal: AbortSignal.timeout(1e4)
|
|
4046
|
+
});
|
|
4047
|
+
if (!res.ok) {
|
|
4048
|
+
const status = res.status >= 500 ? 502 : 404;
|
|
4049
|
+
return c.json(
|
|
4050
|
+
{
|
|
4051
|
+
error: res.status >= 500 ? `Mind ${path} handler errored` : `${path} endpoint not available`
|
|
4052
|
+
},
|
|
4053
|
+
status
|
|
4054
|
+
);
|
|
4055
|
+
}
|
|
4056
|
+
let data;
|
|
4057
|
+
try {
|
|
4058
|
+
data = await res.json();
|
|
4059
|
+
} catch {
|
|
4060
|
+
return c.json({ error: "Mind returned invalid response" }, 502);
|
|
4061
|
+
}
|
|
4062
|
+
return c.json(data);
|
|
4063
|
+
} catch (err) {
|
|
4064
|
+
console.error(`${path} proxy for ${name}:`, err);
|
|
4065
|
+
return c.json({ error: "Failed to reach mind" }, 503);
|
|
4066
|
+
}
|
|
4067
|
+
}
|
|
3951
4068
|
var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", createMindSchema), async (c) => {
|
|
3952
4069
|
const body = c.req.valid("json");
|
|
3953
4070
|
const { name } = body;
|
|
@@ -3965,7 +4082,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
3965
4082
|
applyInitFiles(dest);
|
|
3966
4083
|
const { publicKeyPem } = generateIdentity(dest);
|
|
3967
4084
|
{
|
|
3968
|
-
const { readGlobalConfig: readGlobal } = await import("./setup-
|
|
4085
|
+
const { readGlobalConfig: readGlobal } = await import("./setup-OTEC3ZPM.js");
|
|
3969
4086
|
const mindDefaults = readGlobal().mindDefaults;
|
|
3970
4087
|
const config2 = readVoluteConfig(dest);
|
|
3971
4088
|
if (!config2) throw new Error("Failed to read volute.json after identity generation");
|
|
@@ -4002,7 +4119,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4002
4119
|
}
|
|
4003
4120
|
writeVoluteConfig(dest, config2);
|
|
4004
4121
|
const modelId = body.model ?? cog?.model;
|
|
4005
|
-
const sdkConfigPath =
|
|
4122
|
+
const sdkConfigPath = resolve11(dest, "home/.config/config.json");
|
|
4006
4123
|
if (modelId || cog?.compaction) {
|
|
4007
4124
|
const existing = existsSync7(sdkConfigPath) ? JSON.parse(readFileSync8(sdkConfigPath, "utf-8")) : {};
|
|
4008
4125
|
if (modelId) {
|
|
@@ -4017,7 +4134,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4017
4134
|
}
|
|
4018
4135
|
const mindPrompts = await getMindPromptDefaults();
|
|
4019
4136
|
writeFileSync7(
|
|
4020
|
-
|
|
4137
|
+
resolve11(dest, "home/.config/prompts.json"),
|
|
4021
4138
|
`${JSON.stringify(mindPrompts, null, 2)}
|
|
4022
4139
|
`
|
|
4023
4140
|
);
|
|
@@ -4029,7 +4146,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4029
4146
|
} catch (err) {
|
|
4030
4147
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
4031
4148
|
}
|
|
4032
|
-
const homeDir =
|
|
4149
|
+
const homeDir = resolve11(dest, "home");
|
|
4033
4150
|
ensureVoluteGroup();
|
|
4034
4151
|
createMindUser(name, homeDir);
|
|
4035
4152
|
chownMindDir(dest, name);
|
|
@@ -4042,7 +4159,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4042
4159
|
await initTemplateBranch(dest, composedDir, manifest, name, env);
|
|
4043
4160
|
} catch (err) {
|
|
4044
4161
|
logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
|
|
4045
|
-
rmSync4(
|
|
4162
|
+
rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
4046
4163
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
4047
4164
|
}
|
|
4048
4165
|
chownMindDir(dest, name);
|
|
@@ -4052,11 +4169,11 @@ The human who planted you described you as: "${body.description}"
|
|
|
4052
4169
|
` : "";
|
|
4053
4170
|
const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
|
|
4054
4171
|
const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
|
|
4055
|
-
writeFileSync7(
|
|
4172
|
+
writeFileSync7(resolve11(dest, "home/SOUL.md"), seedSoul);
|
|
4056
4173
|
}
|
|
4057
4174
|
let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
|
|
4058
4175
|
if (body.stage === "seed" && !body.skills) {
|
|
4059
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
4176
|
+
const { isImagegenEnabled } = await import("./setup-OTEC3ZPM.js");
|
|
4060
4177
|
if (isImagegenEnabled()) {
|
|
4061
4178
|
skillSet = [...skillSet, "imagegen"];
|
|
4062
4179
|
}
|
|
@@ -4074,7 +4191,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4074
4191
|
try {
|
|
4075
4192
|
const spiritEntry = await findMind("volute");
|
|
4076
4193
|
if (spiritEntry) {
|
|
4077
|
-
const { spiritDir } = await import("./spirit-
|
|
4194
|
+
const { spiritDir } = await import("./spirit-NVXWSVKM.js");
|
|
4078
4195
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
4079
4196
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
4080
4197
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -4089,7 +4206,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4089
4206
|
});
|
|
4090
4207
|
spiritConfig.schedules = schedules;
|
|
4091
4208
|
writeVoluteConfig(sDir, spiritConfig);
|
|
4092
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
4209
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-GQBDCGLU.js");
|
|
4093
4210
|
getScheduler2().loadSchedules("volute", sDir);
|
|
4094
4211
|
}
|
|
4095
4212
|
}
|
|
@@ -4100,11 +4217,11 @@ The human who planted you described you as: "${body.description}"
|
|
|
4100
4217
|
if (body.stage !== "seed") {
|
|
4101
4218
|
const customSoul = await getPromptIfCustom("default_soul");
|
|
4102
4219
|
if (customSoul) {
|
|
4103
|
-
writeFileSync7(
|
|
4220
|
+
writeFileSync7(resolve11(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
|
|
4104
4221
|
}
|
|
4105
4222
|
const customMemory = await getPromptIfCustom("default_memory");
|
|
4106
4223
|
if (customMemory) {
|
|
4107
|
-
writeFileSync7(
|
|
4224
|
+
writeFileSync7(resolve11(dest, "home/MEMORY.md"), customMemory);
|
|
4108
4225
|
}
|
|
4109
4226
|
}
|
|
4110
4227
|
publishPublicKey(name, publicKeyPem).catch(
|
|
@@ -4153,12 +4270,12 @@ The human who planted you described you as: "${body.description}"
|
|
|
4153
4270
|
return importFromArchive(c, body.archivePath, body.name, body.manifest);
|
|
4154
4271
|
}
|
|
4155
4272
|
const wsDir = body.workspacePath;
|
|
4156
|
-
if (!wsDir || !existsSync7(
|
|
4273
|
+
if (!wsDir || !existsSync7(resolve11(wsDir, "SOUL.md")) || !existsSync7(resolve11(wsDir, "IDENTITY.md"))) {
|
|
4157
4274
|
return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
|
|
4158
4275
|
}
|
|
4159
|
-
const soul = readFileSync8(
|
|
4160
|
-
const identity = readFileSync8(
|
|
4161
|
-
const userPath =
|
|
4276
|
+
const soul = readFileSync8(resolve11(wsDir, "SOUL.md"), "utf-8");
|
|
4277
|
+
const identity = readFileSync8(resolve11(wsDir, "IDENTITY.md"), "utf-8");
|
|
4278
|
+
const userPath = resolve11(wsDir, "USER.md");
|
|
4162
4279
|
const user = existsSync7(userPath) ? readFileSync8(userPath, "utf-8") : "";
|
|
4163
4280
|
const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
|
|
4164
4281
|
const template = body.template ?? "claude";
|
|
@@ -4186,26 +4303,26 @@ ${user.trimEnd()}
|
|
|
4186
4303
|
copyTemplateToDir(composedDir, dest, name, manifest);
|
|
4187
4304
|
applyInitFiles(dest);
|
|
4188
4305
|
const { publicKeyPem: importPublicKey } = generateIdentity(dest);
|
|
4189
|
-
writeFileSync7(
|
|
4190
|
-
const wsMemoryPath =
|
|
4306
|
+
writeFileSync7(resolve11(dest, "home/SOUL.md"), mergedSoul);
|
|
4307
|
+
const wsMemoryPath = resolve11(wsDir, "MEMORY.md");
|
|
4191
4308
|
const hasMemory = existsSync7(wsMemoryPath);
|
|
4192
4309
|
if (hasMemory) {
|
|
4193
4310
|
const existingMemory = readFileSync8(wsMemoryPath, "utf-8");
|
|
4194
4311
|
writeFileSync7(
|
|
4195
|
-
|
|
4312
|
+
resolve11(dest, "home/MEMORY.md"),
|
|
4196
4313
|
`${existingMemory.trimEnd()}${mergedMemoryExtra}`
|
|
4197
4314
|
);
|
|
4198
4315
|
} else if (user) {
|
|
4199
|
-
writeFileSync7(
|
|
4316
|
+
writeFileSync7(resolve11(dest, "home/MEMORY.md"), `${user.trimEnd()}
|
|
4200
4317
|
`);
|
|
4201
4318
|
}
|
|
4202
|
-
const wsMemoryDir =
|
|
4319
|
+
const wsMemoryDir = resolve11(wsDir, "memory");
|
|
4203
4320
|
let dailyLogCount = 0;
|
|
4204
4321
|
if (existsSync7(wsMemoryDir)) {
|
|
4205
|
-
const destMemoryDir =
|
|
4322
|
+
const destMemoryDir = resolve11(dest, "home/memory");
|
|
4206
4323
|
const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
|
|
4207
4324
|
for (const file of files) {
|
|
4208
|
-
cpSync(
|
|
4325
|
+
cpSync(resolve11(wsMemoryDir, file), resolve11(destMemoryDir, file));
|
|
4209
4326
|
}
|
|
4210
4327
|
dailyLogCount = files.length;
|
|
4211
4328
|
}
|
|
@@ -4216,7 +4333,7 @@ ${user.trimEnd()}
|
|
|
4216
4333
|
} catch (err) {
|
|
4217
4334
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
4218
4335
|
}
|
|
4219
|
-
const homeDir =
|
|
4336
|
+
const homeDir = resolve11(dest, "home");
|
|
4220
4337
|
ensureVoluteGroup();
|
|
4221
4338
|
createMindUser(name, homeDir);
|
|
4222
4339
|
chownMindDir(dest, name);
|
|
@@ -4224,20 +4341,20 @@ ${user.trimEnd()}
|
|
|
4224
4341
|
if (!hasMemory && dailyLogCount > 0) {
|
|
4225
4342
|
await consolidateMemory(dest);
|
|
4226
4343
|
}
|
|
4227
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
4344
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dest, "home") } : void 0;
|
|
4228
4345
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
4229
4346
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
4230
4347
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
4231
4348
|
await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
|
|
4232
|
-
const sessionFile = body.sessionPath ?
|
|
4349
|
+
const sessionFile = body.sessionPath ? resolve11(body.sessionPath) : findOpenClawSession(wsDir);
|
|
4233
4350
|
if (sessionFile && existsSync7(sessionFile)) {
|
|
4234
4351
|
if (template === "pi") {
|
|
4235
4352
|
importPiSession(sessionFile, dest);
|
|
4236
4353
|
} else if (template === "claude") {
|
|
4237
4354
|
const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
|
|
4238
|
-
const mindRuntimeDir =
|
|
4355
|
+
const mindRuntimeDir = resolve11(dest, ".mind");
|
|
4239
4356
|
mkdirSync6(mindRuntimeDir, { recursive: true });
|
|
4240
|
-
writeFileSync7(
|
|
4357
|
+
writeFileSync7(resolve11(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
|
|
4241
4358
|
}
|
|
4242
4359
|
}
|
|
4243
4360
|
importOpenClawConnectors(name, dest);
|
|
@@ -4278,7 +4395,7 @@ ${user.trimEnd()}
|
|
|
4278
4395
|
const minds = await Promise.all(
|
|
4279
4396
|
entries.map(async (entry) => {
|
|
4280
4397
|
const mindStatus = await getMindStatus(entry.name, entry.port, entry.running);
|
|
4281
|
-
const hasPages = existsSync7(
|
|
4398
|
+
const hasPages = existsSync7(resolve11(mindDir(entry.name), "home", "pages"));
|
|
4282
4399
|
return {
|
|
4283
4400
|
...entry,
|
|
4284
4401
|
...mindStatus,
|
|
@@ -4307,35 +4424,9 @@ ${user.trimEnd()}
|
|
|
4307
4424
|
return { name: s.name, port: s.port, status: variantStatus };
|
|
4308
4425
|
})
|
|
4309
4426
|
);
|
|
4310
|
-
const hasPages = existsSync7(
|
|
4427
|
+
const hasPages = existsSync7(resolve11(mindDir(name), "home", "pages"));
|
|
4311
4428
|
return c.json({ ...entry, ...mindStatus, variants: variantStatuses, hasPages });
|
|
4312
|
-
}).get("/:name/context", async (c) => {
|
|
4313
|
-
const name = c.req.param("name");
|
|
4314
|
-
const entry = await findMind(name);
|
|
4315
|
-
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4316
|
-
if (!getMindManager().isRunning(name)) {
|
|
4317
|
-
return c.json({ error: "Mind is not running" }, 503);
|
|
4318
|
-
}
|
|
4319
|
-
try {
|
|
4320
|
-
const res = await fetch(`http://127.0.0.1:${entry.port}/context`, {
|
|
4321
|
-
signal: AbortSignal.timeout(3e3)
|
|
4322
|
-
});
|
|
4323
|
-
if (!res.ok) {
|
|
4324
|
-
const status = res.status >= 500 ? 502 : 404;
|
|
4325
|
-
return c.json(
|
|
4326
|
-
{
|
|
4327
|
-
error: res.status >= 500 ? "Mind context handler errored" : "Context endpoint not available"
|
|
4328
|
-
},
|
|
4329
|
-
status
|
|
4330
|
-
);
|
|
4331
|
-
}
|
|
4332
|
-
const data = await res.json();
|
|
4333
|
-
return c.json(data);
|
|
4334
|
-
} catch (err) {
|
|
4335
|
-
console.error(`context proxy for ${name}:`, err);
|
|
4336
|
-
return c.json({ error: "Failed to reach mind" }, 503);
|
|
4337
|
-
}
|
|
4338
|
-
}).post("/:name/start", requireSelf(), async (c) => {
|
|
4429
|
+
}).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) => {
|
|
4339
4430
|
const name = c.req.param("name");
|
|
4340
4431
|
const entry = await findMind(name);
|
|
4341
4432
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -4380,7 +4471,7 @@ ${user.trimEnd()}
|
|
|
4380
4471
|
const manager = getMindManager();
|
|
4381
4472
|
try {
|
|
4382
4473
|
if (context?.type === "reload") {
|
|
4383
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4474
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-5277OBHI.js");
|
|
4384
4475
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
4385
4476
|
if (sleepState?.sleeping) {
|
|
4386
4477
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -4475,7 +4566,7 @@ ${user.trimEnd()}
|
|
|
4475
4566
|
const name = c.req.param("name");
|
|
4476
4567
|
const entry = await findMind(name);
|
|
4477
4568
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4478
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4569
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-5277OBHI.js");
|
|
4479
4570
|
const sm = getSleepManagerIfReady2();
|
|
4480
4571
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4481
4572
|
return c.json(sm.getState(name));
|
|
@@ -4483,7 +4574,7 @@ ${user.trimEnd()}
|
|
|
4483
4574
|
const name = c.req.param("name");
|
|
4484
4575
|
const entry = await findMind(name);
|
|
4485
4576
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4486
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4577
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-5277OBHI.js");
|
|
4487
4578
|
const sm = getSleepManagerIfReady2();
|
|
4488
4579
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4489
4580
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -4503,7 +4594,7 @@ ${user.trimEnd()}
|
|
|
4503
4594
|
const name = c.req.param("name");
|
|
4504
4595
|
const entry = await findMind(name);
|
|
4505
4596
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4506
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4597
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-5277OBHI.js");
|
|
4507
4598
|
const sm = getSleepManagerIfReady2();
|
|
4508
4599
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4509
4600
|
const sleepState = sm.getState(name);
|
|
@@ -4518,7 +4609,7 @@ ${user.trimEnd()}
|
|
|
4518
4609
|
const name = c.req.param("name");
|
|
4519
4610
|
const entry = await findMind(name);
|
|
4520
4611
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4521
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4612
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-5277OBHI.js");
|
|
4522
4613
|
const sm = getSleepManagerIfReady2();
|
|
4523
4614
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4524
4615
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -4533,10 +4624,10 @@ ${user.trimEnd()}
|
|
|
4533
4624
|
const profile = config2.profile ?? {};
|
|
4534
4625
|
if (body.displayName !== void 0) profile.displayName = body.displayName;
|
|
4535
4626
|
if (body.description !== void 0) profile.description = body.description;
|
|
4536
|
-
if (body.avatar !== void 0) profile.avatar = body.avatar;
|
|
4627
|
+
if (body.avatar !== void 0) profile.avatar = basename(body.avatar);
|
|
4537
4628
|
config2.profile = profile;
|
|
4538
4629
|
writeVoluteConfig(dir, config2);
|
|
4539
|
-
const { syncMindProfile: syncMindProfile2 } = await import("./auth-
|
|
4630
|
+
const { syncMindProfile: syncMindProfile2 } = await import("./auth-X6ZITZ7D.js");
|
|
4540
4631
|
await syncMindProfile2(name, profile);
|
|
4541
4632
|
broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
|
|
4542
4633
|
return c.json({ ok: true });
|
|
@@ -4576,14 +4667,14 @@ ${user.trimEnd()}
|
|
|
4576
4667
|
return c.json({ output: "" });
|
|
4577
4668
|
}
|
|
4578
4669
|
const dir = entry.dir ?? mindDir(name);
|
|
4579
|
-
const soulPath =
|
|
4580
|
-
const memoryPath =
|
|
4670
|
+
const soulPath = resolve11(dir, "home/SOUL.md");
|
|
4671
|
+
const memoryPath = resolve11(dir, "home/MEMORY.md");
|
|
4581
4672
|
const soulCustom = existsSync7(soulPath) && !readFileSync8(soulPath, "utf-8").includes(ORIENTATION_MARKER);
|
|
4582
4673
|
const memoryWritten = existsSync7(memoryPath) && readFileSync8(memoryPath, "utf-8").trim().length > 0;
|
|
4583
4674
|
const config2 = readVoluteConfig(dir);
|
|
4584
4675
|
const displayNameSet = !!config2?.profile?.displayName;
|
|
4585
4676
|
const avatarSet = !!config2?.profile?.avatar;
|
|
4586
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
4677
|
+
const { isImagegenEnabled } = await import("./setup-OTEC3ZPM.js");
|
|
4587
4678
|
const imagegenEnabled = isImagegenEnabled();
|
|
4588
4679
|
const done = [];
|
|
4589
4680
|
const remaining = [];
|
|
@@ -4621,7 +4712,7 @@ ${user.trimEnd()}
|
|
|
4621
4712
|
try {
|
|
4622
4713
|
const spiritEntry = await findMind("volute");
|
|
4623
4714
|
if (spiritEntry) {
|
|
4624
|
-
const { spiritDir } = await import("./spirit-
|
|
4715
|
+
const { spiritDir } = await import("./spirit-NVXWSVKM.js");
|
|
4625
4716
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
4626
4717
|
const spiritConfig = readVoluteConfig(sDir);
|
|
4627
4718
|
if (spiritConfig?.schedules) {
|
|
@@ -4629,7 +4720,7 @@ ${user.trimEnd()}
|
|
|
4629
4720
|
spiritConfig.schedules = spiritConfig.schedules.filter((s) => s.id !== nurtureId);
|
|
4630
4721
|
if (spiritConfig.schedules.length === 0) spiritConfig.schedules = void 0;
|
|
4631
4722
|
writeVoluteConfig(sDir, spiritConfig);
|
|
4632
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
4723
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-GQBDCGLU.js");
|
|
4633
4724
|
getScheduler2().loadSchedules("volute", sDir);
|
|
4634
4725
|
}
|
|
4635
4726
|
}
|
|
@@ -4684,16 +4775,16 @@ ${user.trimEnd()}
|
|
|
4684
4775
|
const template = body.template ?? entry.template ?? "claude";
|
|
4685
4776
|
const UPGRADE_BRANCH = "upgrade";
|
|
4686
4777
|
const upgradeVariantName = `${mindName}-upgrade`;
|
|
4687
|
-
const worktreeDir =
|
|
4778
|
+
const worktreeDir = resolve11(dir, ".variants", UPGRADE_BRANCH);
|
|
4688
4779
|
if (body.abort) {
|
|
4689
4780
|
if (!existsSync7(worktreeDir)) {
|
|
4690
4781
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
4691
4782
|
}
|
|
4692
4783
|
try {
|
|
4693
4784
|
try {
|
|
4694
|
-
const gitDirContent = readFileSync8(
|
|
4785
|
+
const gitDirContent = readFileSync8(resolve11(worktreeDir, ".git"), "utf-8").trim();
|
|
4695
4786
|
const gitDir = gitDirContent.replace("gitdir: ", "");
|
|
4696
|
-
if (existsSync7(
|
|
4787
|
+
if (existsSync7(resolve11(gitDir, "MERGE_HEAD"))) {
|
|
4697
4788
|
await gitExec(["merge", "--abort"], { cwd: worktreeDir });
|
|
4698
4789
|
}
|
|
4699
4790
|
} catch {
|
|
@@ -4776,7 +4867,7 @@ ${user.trimEnd()}
|
|
|
4776
4867
|
}
|
|
4777
4868
|
if (body.diff) {
|
|
4778
4869
|
try {
|
|
4779
|
-
if (!existsSync7(
|
|
4870
|
+
if (!existsSync7(resolve11(dir, ".git"))) {
|
|
4780
4871
|
return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
|
|
4781
4872
|
}
|
|
4782
4873
|
await updateTemplateBranch(dir, template, mindName);
|
|
@@ -4800,16 +4891,16 @@ ${user.trimEnd()}
|
|
|
4800
4891
|
409
|
|
4801
4892
|
);
|
|
4802
4893
|
}
|
|
4803
|
-
if (!existsSync7(
|
|
4894
|
+
if (!existsSync7(resolve11(dir, ".git"))) {
|
|
4804
4895
|
try {
|
|
4805
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
4896
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve11(dir, "home") } : void 0;
|
|
4806
4897
|
await gitExec(["init"], { cwd: dir, mindName, env });
|
|
4807
4898
|
await configureGitIdentity(mindName, { cwd: dir, mindName, env });
|
|
4808
4899
|
await gitExec(["add", "-A"], { cwd: dir, mindName, env });
|
|
4809
4900
|
await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
|
|
4810
4901
|
chownMindDir(dir, mindName);
|
|
4811
4902
|
} catch (err) {
|
|
4812
|
-
rmSync4(
|
|
4903
|
+
rmSync4(resolve11(dir, ".git"), { recursive: true, force: true });
|
|
4813
4904
|
return c.json(
|
|
4814
4905
|
{
|
|
4815
4906
|
error: `Git initialization failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -4824,7 +4915,7 @@ ${user.trimEnd()}
|
|
|
4824
4915
|
} catch {
|
|
4825
4916
|
}
|
|
4826
4917
|
await updateTemplateBranch(dir, template, mindName);
|
|
4827
|
-
const parentDir =
|
|
4918
|
+
const parentDir = resolve11(dir, ".variants");
|
|
4828
4919
|
if (!existsSync7(parentDir)) {
|
|
4829
4920
|
mkdirSync6(parentDir, { recursive: true });
|
|
4830
4921
|
}
|
|
@@ -4943,13 +5034,13 @@ ${user.trimEnd()}
|
|
|
4943
5034
|
}
|
|
4944
5035
|
const result = await getMessagesPaginated(convId, { before, limit });
|
|
4945
5036
|
return c.json({ items: result.messages, hasMore: result.hasMore });
|
|
4946
|
-
}).get("/:name/budget", async (c) => {
|
|
5037
|
+
}).get("/:name/budget", requireSelf(), async (c) => {
|
|
4947
5038
|
const name = c.req.param("name");
|
|
4948
5039
|
const baseName = await getBaseName(name);
|
|
4949
5040
|
const usage = getTokenBudget().getUsage(baseName);
|
|
4950
5041
|
if (!usage) return c.json({ error: "No budget configured" }, 404);
|
|
4951
5042
|
return c.json(usage);
|
|
4952
|
-
}).get("/:name/config", async (c) => {
|
|
5043
|
+
}).get("/:name/config", requireSelf(), async (c) => {
|
|
4953
5044
|
const name = c.req.param("name");
|
|
4954
5045
|
const entry = await findMind(name);
|
|
4955
5046
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -4957,7 +5048,7 @@ ${user.trimEnd()}
|
|
|
4957
5048
|
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
4958
5049
|
let config2 = readVoluteConfig(dir);
|
|
4959
5050
|
if (!config2 && entry.template === "pi") {
|
|
4960
|
-
const piConfigPath =
|
|
5051
|
+
const piConfigPath = resolve11(dir, "home/.config/config.json");
|
|
4961
5052
|
if (existsSync7(piConfigPath)) {
|
|
4962
5053
|
try {
|
|
4963
5054
|
config2 = JSON.parse(readFileSync8(piConfigPath, "utf-8"));
|
|
@@ -4966,7 +5057,7 @@ ${user.trimEnd()}
|
|
|
4966
5057
|
}
|
|
4967
5058
|
}
|
|
4968
5059
|
let templateConfig = {};
|
|
4969
|
-
const configJsonPath =
|
|
5060
|
+
const configJsonPath = resolve11(dir, "home/.config/config.json");
|
|
4970
5061
|
if (existsSync7(configJsonPath)) {
|
|
4971
5062
|
try {
|
|
4972
5063
|
templateConfig = JSON.parse(readFileSync8(configJsonPath, "utf-8"));
|
|
@@ -5058,12 +5149,12 @@ ${user.trimEnd()}
|
|
|
5058
5149
|
}
|
|
5059
5150
|
writeVoluteConfig(dir, existing);
|
|
5060
5151
|
if (body.unescapeNewlines !== void 0) {
|
|
5061
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
5152
|
+
const { clearEchoTextCache } = await import("./echo-text-QFCH3H6G.js");
|
|
5062
5153
|
clearEchoTextCache(name);
|
|
5063
5154
|
}
|
|
5064
5155
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.maxThinkingTokens !== void 0 || body.compaction !== void 0;
|
|
5065
5156
|
if (needsConfigJson) {
|
|
5066
|
-
const configJsonPath =
|
|
5157
|
+
const configJsonPath = resolve11(dir, "home/.config/config.json");
|
|
5067
5158
|
let templateConfig = {};
|
|
5068
5159
|
if (existsSync7(configJsonPath)) {
|
|
5069
5160
|
try {
|
|
@@ -5135,7 +5226,7 @@ ${user.trimEnd()}
|
|
|
5135
5226
|
}
|
|
5136
5227
|
if (entry.mindType === "spirit" && body.model !== void 0) {
|
|
5137
5228
|
try {
|
|
5138
|
-
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-
|
|
5229
|
+
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-OTEC3ZPM.js");
|
|
5139
5230
|
const globalConfig = readGlobalConfig2();
|
|
5140
5231
|
globalConfig.spiritModel = body.model;
|
|
5141
5232
|
writeGlobalConfig2(globalConfig);
|
|
@@ -5145,7 +5236,7 @@ ${user.trimEnd()}
|
|
|
5145
5236
|
}
|
|
5146
5237
|
return c.json({ ok: true });
|
|
5147
5238
|
}
|
|
5148
|
-
).get("/:name/delivery/pending", async (c) => {
|
|
5239
|
+
).get("/:name/delivery/pending", requireSelf(), async (c) => {
|
|
5149
5240
|
const name = c.req.param("name");
|
|
5150
5241
|
const baseName = await getBaseName(name);
|
|
5151
5242
|
try {
|
|
@@ -5163,7 +5254,7 @@ ${user.trimEnd()}
|
|
|
5163
5254
|
if (!body.systemPrompt || !body.message) {
|
|
5164
5255
|
return c.json({ error: "systemPrompt and message required" }, 400);
|
|
5165
5256
|
}
|
|
5166
|
-
const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-
|
|
5257
|
+
const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-AUWIPWLP.js");
|
|
5167
5258
|
if (!isAiConfigured()) {
|
|
5168
5259
|
return c.json({ error: "AI service not configured" }, 503);
|
|
5169
5260
|
}
|
|
@@ -5270,6 +5361,18 @@ ${user.trimEnd()}
|
|
|
5270
5361
|
const affected = map.deleteSender(baseName);
|
|
5271
5362
|
publishTypingForChannels(affected, map);
|
|
5272
5363
|
}
|
|
5364
|
+
if (body.type === "error" && body.session) {
|
|
5365
|
+
markErrored(baseName, body.session);
|
|
5366
|
+
const { reason, detail } = classify(body.content ?? "");
|
|
5367
|
+
await recordNotice({
|
|
5368
|
+
mind: baseName,
|
|
5369
|
+
session: body.session,
|
|
5370
|
+
kind: "turn_error",
|
|
5371
|
+
reason,
|
|
5372
|
+
detail,
|
|
5373
|
+
raw: body.content ?? null
|
|
5374
|
+
});
|
|
5375
|
+
}
|
|
5273
5376
|
if (body.type === "done") {
|
|
5274
5377
|
const map = getTypingMap();
|
|
5275
5378
|
const affected = map.deleteSender(baseName);
|
|
@@ -5292,6 +5395,7 @@ ${user.trimEnd()}
|
|
|
5292
5395
|
(err) => logger_default.warn("failed to tag orphaned outbound records", logger_default.errorData(err))
|
|
5293
5396
|
);
|
|
5294
5397
|
}
|
|
5398
|
+
markDeliveredOnCleanTurn(baseName, body.session);
|
|
5295
5399
|
if (insertedId != null) {
|
|
5296
5400
|
summarizeTurn(baseName, body.session, body.channel, insertedId, completedTurnId).catch(
|
|
5297
5401
|
(err) => logger_default.error("turn summarization failed", logger_default.errorData(err))
|
|
@@ -5308,6 +5412,7 @@ ${user.trimEnd()}
|
|
|
5308
5412
|
(err2) => logger_default.warn("failed to tag orphaned outbound records", logger_default.errorData(err2))
|
|
5309
5413
|
);
|
|
5310
5414
|
}
|
|
5415
|
+
markDeliveredOnCleanTurn(baseName, body.session);
|
|
5311
5416
|
if (insertedId != null) {
|
|
5312
5417
|
summarizeTurn(baseName, body.session, body.channel, insertedId, completedTurnId).catch(
|
|
5313
5418
|
(err2) => logger_default.error("turn summarization failed", logger_default.errorData(err2))
|
|
@@ -5318,10 +5423,20 @@ ${user.trimEnd()}
|
|
|
5318
5423
|
if (body.type === "usage" && body.metadata) {
|
|
5319
5424
|
const inputTokens = body.metadata.input_tokens ?? 0;
|
|
5320
5425
|
const outputTokens = body.metadata.output_tokens ?? 0;
|
|
5321
|
-
getTokenBudget()
|
|
5426
|
+
const tb = getTokenBudget();
|
|
5427
|
+
tb.recordUsage(baseName, inputTokens, outputTokens);
|
|
5428
|
+
if (body.session && tb.noteExceeded(baseName)) {
|
|
5429
|
+
void recordNotice({
|
|
5430
|
+
mind: baseName,
|
|
5431
|
+
session: body.session,
|
|
5432
|
+
kind: "budget",
|
|
5433
|
+
reason: "token_budget",
|
|
5434
|
+
detail: "You've reached your token budget for this period. Further activity may be paused until the budget resets \u2014 wrap up or prioritize accordingly."
|
|
5435
|
+
});
|
|
5436
|
+
}
|
|
5322
5437
|
}
|
|
5323
5438
|
return c.json({ ok: true });
|
|
5324
|
-
}).get("/:name/events", async (c) => {
|
|
5439
|
+
}).get("/:name/events", requireSelf(), async (c) => {
|
|
5325
5440
|
const name = c.req.param("name");
|
|
5326
5441
|
const baseName = await getBaseName(name);
|
|
5327
5442
|
const entry = await findMind(baseName);
|
|
@@ -5403,7 +5518,7 @@ ${user.trimEnd()}
|
|
|
5403
5518
|
return c.json({ error: "Failed to persist" }, 500);
|
|
5404
5519
|
}
|
|
5405
5520
|
return c.json({ ok: true });
|
|
5406
|
-
}).get("/:name/history/sessions", async (c) => {
|
|
5521
|
+
}).get("/:name/history/sessions", requireSelf(), async (c) => {
|
|
5407
5522
|
const name = c.req.param("name");
|
|
5408
5523
|
const db = await getDb();
|
|
5409
5524
|
const rows = await db.select({
|
|
@@ -5414,18 +5529,18 @@ ${user.trimEnd()}
|
|
|
5414
5529
|
tool_count: sql2`SUM(CASE WHEN ${mindHistory.type}='tool_use' THEN 1 ELSE 0 END)`
|
|
5415
5530
|
}).from(mindHistory).where(and4(eq5(mindHistory.mind, name), sql2`${mindHistory.session} IS NOT NULL`)).groupBy(mindHistory.session).orderBy(sql2`MIN(${mindHistory.created_at}) DESC`);
|
|
5416
5531
|
return c.json(rows);
|
|
5417
|
-
}).get("/:name/history/channels", async (c) => {
|
|
5532
|
+
}).get("/:name/history/channels", requireSelf(), async (c) => {
|
|
5418
5533
|
const name = c.req.param("name");
|
|
5419
5534
|
const db = await getDb();
|
|
5420
5535
|
const rows = await db.selectDistinct({ channel: mindHistory.channel }).from(mindHistory).where(eq5(mindHistory.mind, name));
|
|
5421
5536
|
return c.json(rows.map((r) => r.channel));
|
|
5422
|
-
}).get("/:name/history/export", async (c) => {
|
|
5537
|
+
}).get("/:name/history/export", requireSelf(), async (c) => {
|
|
5423
5538
|
const name = c.req.param("name");
|
|
5424
5539
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
5425
5540
|
const db = await getDb();
|
|
5426
5541
|
const rows = await db.select().from(mindHistory).where(eq5(mindHistory.mind, name));
|
|
5427
5542
|
return c.json(rows);
|
|
5428
|
-
}).get("/:name/history/turn", async (c) => {
|
|
5543
|
+
}).get("/:name/history/turn", requireSelf(), async (c) => {
|
|
5429
5544
|
const name = c.req.param("name");
|
|
5430
5545
|
const turnId = c.req.query("turn_id");
|
|
5431
5546
|
const detail = c.req.query("detail") === "1";
|
|
@@ -5452,7 +5567,7 @@ ${user.trimEnd()}
|
|
|
5452
5567
|
).orderBy(mindHistory.id);
|
|
5453
5568
|
}
|
|
5454
5569
|
return c.json(rows);
|
|
5455
|
-
}).get("/:name/history/cross-session", async (c) => {
|
|
5570
|
+
}).get("/:name/history/cross-session", requireSelf(), async (c) => {
|
|
5456
5571
|
const name = c.req.param("name");
|
|
5457
5572
|
const currentSession = c.req.query("session");
|
|
5458
5573
|
const db = await getDb();
|
|
@@ -5498,7 +5613,17 @@ ${user.trimEnd()}
|
|
|
5498
5613
|
});
|
|
5499
5614
|
return c.json({ context: `[Session Activity]
|
|
5500
5615
|
${lines.join("\n")}` });
|
|
5501
|
-
}).get("/:name/history", async (c) => {
|
|
5616
|
+
}).get("/:name/history/notices", requireSelf(), async (c) => {
|
|
5617
|
+
const name = c.req.param("name");
|
|
5618
|
+
const baseName = await getBaseName(name);
|
|
5619
|
+
const session = c.req.query("session");
|
|
5620
|
+
if (!session) return c.json({ context: null, notices: [] });
|
|
5621
|
+
const notices = await drainNotices(baseName, session);
|
|
5622
|
+
if (notices.length === 0) return c.json({ context: null, notices: [] });
|
|
5623
|
+
const maxId = notices.reduce((m, n) => Math.max(m, n.id), 0);
|
|
5624
|
+
noticeDrainWatermarks.set(`${baseName}:${session}`, maxId);
|
|
5625
|
+
return c.json({ context: formatNotices(notices), notices });
|
|
5626
|
+
}).get("/:name/history", requireSelf(), async (c) => {
|
|
5502
5627
|
const name = c.req.param("name");
|
|
5503
5628
|
const channel = c.req.query("channel");
|
|
5504
5629
|
const session = c.req.query("session");
|
|
@@ -5649,7 +5774,7 @@ function writeSchedules(name, dir, schedules) {
|
|
|
5649
5774
|
data: { schedules }
|
|
5650
5775
|
});
|
|
5651
5776
|
}
|
|
5652
|
-
var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
5777
|
+
var app15 = new Hono17().get("/:name/clock/status", requireSelf(), async (c) => {
|
|
5653
5778
|
const name = c.req.param("name");
|
|
5654
5779
|
const entry = await findMind(name);
|
|
5655
5780
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -5708,7 +5833,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
|
5708
5833
|
upcoming.sort((a, b) => a.at.localeCompare(b.at));
|
|
5709
5834
|
previous.sort((a, b) => b.at.localeCompare(a.at));
|
|
5710
5835
|
return c.json({ sleep: sleepState, sleepConfig, schedules, upcoming, previous });
|
|
5711
|
-
}).get("/:name/sleep/config", async (c) => {
|
|
5836
|
+
}).get("/:name/sleep/config", requireSelf(), async (c) => {
|
|
5712
5837
|
const name = c.req.param("name");
|
|
5713
5838
|
const entry = await findMind(name);
|
|
5714
5839
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -5740,7 +5865,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
|
5740
5865
|
writeVoluteConfig(dir, config2);
|
|
5741
5866
|
getSleepManagerIfReady()?.invalidateSleepConfig(name);
|
|
5742
5867
|
return c.json({ ok: true });
|
|
5743
|
-
}).get("/:name/schedules", async (c) => {
|
|
5868
|
+
}).get("/:name/schedules", requireSelf(), async (c) => {
|
|
5744
5869
|
const name = c.req.param("name");
|
|
5745
5870
|
const entry = await findMind(name);
|
|
5746
5871
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -5865,7 +5990,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
|
5865
5990
|
}
|
|
5866
5991
|
writeSchedules(name, dir, filtered);
|
|
5867
5992
|
return c.json({ ok: true });
|
|
5868
|
-
}).post("/:name/webhook/:event", async (c) => {
|
|
5993
|
+
}).post("/:name/webhook/:event", requireSelf(), async (c) => {
|
|
5869
5994
|
const name = c.req.param("name");
|
|
5870
5995
|
const event = c.req.param("event");
|
|
5871
5996
|
const entry = await findMind(name);
|
|
@@ -5873,7 +5998,7 @@ var app15 = new Hono17().get("/:name/clock/status", async (c) => {
|
|
|
5873
5998
|
const body = await c.req.text();
|
|
5874
5999
|
const message = `[webhook: ${event}] ${body}`;
|
|
5875
6000
|
try {
|
|
5876
|
-
const { sendSystemMessage } = await import("./system-chat-
|
|
6001
|
+
const { sendSystemMessage } = await import("./system-chat-LQSJVY55.js");
|
|
5877
6002
|
await sendSystemMessage(name, message);
|
|
5878
6003
|
return c.json({ ok: true });
|
|
5879
6004
|
} catch (err) {
|
|
@@ -5886,14 +6011,14 @@ var schedules_default = app15;
|
|
|
5886
6011
|
// packages/daemon/src/web/api/setup.ts
|
|
5887
6012
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
5888
6013
|
import { homedir as homedir2 } from "os";
|
|
5889
|
-
import { resolve as
|
|
6014
|
+
import { resolve as resolve12 } from "path";
|
|
5890
6015
|
import { Hono as Hono18 } from "hono";
|
|
5891
6016
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
5892
6017
|
var DEFAULT_API_URL2 = "https://volute.systems";
|
|
5893
6018
|
var setup = new Hono18();
|
|
5894
6019
|
function writeSetupConfig(systemName, description) {
|
|
5895
|
-
const configHome = process.env.VOLUTE_HOME ??
|
|
5896
|
-
const mindsDir =
|
|
6020
|
+
const configHome = process.env.VOLUTE_HOME ?? resolve12(homedir2(), ".volute");
|
|
6021
|
+
const mindsDir = resolve12(configHome, "minds");
|
|
5897
6022
|
mkdirSync7(configHome, { recursive: true });
|
|
5898
6023
|
mkdirSync7(mindsDir, { recursive: true });
|
|
5899
6024
|
const existingConfig = readGlobalConfig();
|
|
@@ -5927,7 +6052,7 @@ setup.get("/status", async (c) => {
|
|
|
5927
6052
|
let hasAccount = false;
|
|
5928
6053
|
if (hasSystem) {
|
|
5929
6054
|
try {
|
|
5930
|
-
const { listUsersByType: listUsersByType2 } = await import("./auth-
|
|
6055
|
+
const { listUsersByType: listUsersByType2 } = await import("./auth-X6ZITZ7D.js");
|
|
5931
6056
|
const brains = await listUsersByType2("brain");
|
|
5932
6057
|
hasAccount = brains.length > 0;
|
|
5933
6058
|
} catch (err) {
|
|
@@ -6138,7 +6263,7 @@ setup.post("/account", async (c) => {
|
|
|
6138
6263
|
}
|
|
6139
6264
|
}
|
|
6140
6265
|
try {
|
|
6141
|
-
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-
|
|
6266
|
+
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-X6ZITZ7D.js");
|
|
6142
6267
|
const user = await createUser2(body.username.trim(), body.password);
|
|
6143
6268
|
if (body.displayName?.trim()) {
|
|
6144
6269
|
await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
|
|
@@ -6184,7 +6309,7 @@ setup.post("/models", async (c) => {
|
|
|
6184
6309
|
return c.json({ error: "Spirit model is required" }, 400);
|
|
6185
6310
|
}
|
|
6186
6311
|
try {
|
|
6187
|
-
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-
|
|
6312
|
+
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-AUWIPWLP.js");
|
|
6188
6313
|
setEnabledModels3(body.models);
|
|
6189
6314
|
const config2 = readGlobalConfig();
|
|
6190
6315
|
config2.spiritModel = body.spiritModel.trim();
|
|
@@ -6202,15 +6327,15 @@ setup.post("/complete", async (c) => {
|
|
|
6202
6327
|
return c.json({ error: "Setup already complete" }, 400);
|
|
6203
6328
|
}
|
|
6204
6329
|
try {
|
|
6205
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
6206
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
6330
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-NVXWSVKM.js");
|
|
6331
|
+
const { startSpiritFull } = await import("./mind-service-WTOFVNLW.js");
|
|
6207
6332
|
await ensureSpiritProject();
|
|
6208
6333
|
await syncSpiritTemplate();
|
|
6209
6334
|
const warnings = [];
|
|
6210
6335
|
const config2 = readGlobalConfig();
|
|
6211
6336
|
if (config2.setup?.service && config2.setup?.type === "local") {
|
|
6212
6337
|
try {
|
|
6213
|
-
const { installUserService } = await import("./service-install-
|
|
6338
|
+
const { installUserService } = await import("./service-install-W3FQXJKB.js");
|
|
6214
6339
|
const installed = await installUserService(config2.port, config2.hostname);
|
|
6215
6340
|
if (!installed) {
|
|
6216
6341
|
warnings.push("Service installation is not supported on this platform.");
|
|
@@ -6238,8 +6363,8 @@ setup.post("/complete", async (c) => {
|
|
|
6238
6363
|
}
|
|
6239
6364
|
let spiritConversationId;
|
|
6240
6365
|
try {
|
|
6241
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-
|
|
6242
|
-
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-
|
|
6366
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-X6ZITZ7D.js");
|
|
6367
|
+
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-AYLXPOGC.js");
|
|
6243
6368
|
const spiritUser = await getOrCreateMindUser2("volute");
|
|
6244
6369
|
const brains = await listUsersByType2("brain");
|
|
6245
6370
|
const admin2 = brains.find((u) => u.role === "admin");
|
|
@@ -6261,8 +6386,8 @@ setup.post("/complete", async (c) => {
|
|
|
6261
6386
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
6262
6387
|
if (spiritConversationId && spiritStarted) {
|
|
6263
6388
|
try {
|
|
6264
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
6265
|
-
const { listUsersByType: listUsers2 } = await import("./auth-
|
|
6389
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-7BCYJLH2.js");
|
|
6390
|
+
const { listUsersByType: listUsers2 } = await import("./auth-X6ZITZ7D.js");
|
|
6266
6391
|
const admins = await listUsers2("brain");
|
|
6267
6392
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
6268
6393
|
const adminName = admin2?.display_name || admin2?.username || "the admin";
|
|
@@ -6301,7 +6426,7 @@ var setup_default = setup;
|
|
|
6301
6426
|
// packages/daemon/src/web/api/skills.ts
|
|
6302
6427
|
import { existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
|
|
6303
6428
|
import { tmpdir } from "os";
|
|
6304
|
-
import { join, resolve as
|
|
6429
|
+
import { join, resolve as resolve13 } from "path";
|
|
6305
6430
|
import AdmZip from "adm-zip";
|
|
6306
6431
|
import { Hono as Hono19 } from "hono";
|
|
6307
6432
|
var app16 = new Hono19().get("/", async (c) => {
|
|
@@ -6377,7 +6502,7 @@ var app16 = new Hono19().get("/", async (c) => {
|
|
|
6377
6502
|
try {
|
|
6378
6503
|
const zip = new AdmZip(buffer2);
|
|
6379
6504
|
for (const entry of zip.getEntries()) {
|
|
6380
|
-
const target =
|
|
6505
|
+
const target = resolve13(tmpDir, entry.entryName);
|
|
6381
6506
|
if (!target.startsWith(tmpDir)) {
|
|
6382
6507
|
return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
|
|
6383
6508
|
}
|
|
@@ -6719,8 +6844,8 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
|
|
|
6719
6844
|
});
|
|
6720
6845
|
}, 15e3);
|
|
6721
6846
|
cleanups.push(() => clearInterval(keepAlive));
|
|
6722
|
-
await new Promise((
|
|
6723
|
-
stream.onAbort(() =>
|
|
6847
|
+
await new Promise((resolve18) => {
|
|
6848
|
+
stream.onAbort(() => resolve18());
|
|
6724
6849
|
});
|
|
6725
6850
|
} finally {
|
|
6726
6851
|
for (const cleanup of cleanups) {
|
|
@@ -6736,15 +6861,15 @@ var events_default = app20;
|
|
|
6736
6861
|
|
|
6737
6862
|
// packages/daemon/src/web/api/variants.ts
|
|
6738
6863
|
import { existsSync as existsSync9, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
6739
|
-
import { resolve as
|
|
6864
|
+
import { resolve as resolve15 } from "path";
|
|
6740
6865
|
import { Hono as Hono24 } from "hono";
|
|
6741
6866
|
|
|
6742
6867
|
// packages/daemon/src/lib/mind/spawn-server.ts
|
|
6743
6868
|
import { spawn as spawn4 } from "child_process";
|
|
6744
6869
|
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync9 } from "fs";
|
|
6745
|
-
import { resolve as
|
|
6870
|
+
import { resolve as resolve14 } from "path";
|
|
6746
6871
|
function tsxBin(cwd) {
|
|
6747
|
-
return
|
|
6872
|
+
return resolve14(cwd, "node_modules", ".bin", "tsx");
|
|
6748
6873
|
}
|
|
6749
6874
|
function spawnServer(cwd, port, options) {
|
|
6750
6875
|
if (options?.detached) {
|
|
@@ -6757,31 +6882,31 @@ function spawnAttached(cwd, port) {
|
|
|
6757
6882
|
cwd,
|
|
6758
6883
|
stdio: ["ignore", "pipe", "pipe"]
|
|
6759
6884
|
});
|
|
6760
|
-
return new Promise((
|
|
6761
|
-
const timeout = setTimeout(() =>
|
|
6885
|
+
return new Promise((resolve18) => {
|
|
6886
|
+
const timeout = setTimeout(() => resolve18(null), 3e4);
|
|
6762
6887
|
function checkOutput(data) {
|
|
6763
6888
|
const match = data.toString().match(/listening on :(\d+)/);
|
|
6764
6889
|
if (match) {
|
|
6765
6890
|
clearTimeout(timeout);
|
|
6766
|
-
|
|
6891
|
+
resolve18({ child, actualPort: parseInt(match[1], 10) });
|
|
6767
6892
|
}
|
|
6768
6893
|
}
|
|
6769
6894
|
child.stdout?.on("data", checkOutput);
|
|
6770
6895
|
child.stderr?.on("data", checkOutput);
|
|
6771
6896
|
child.on("error", () => {
|
|
6772
6897
|
clearTimeout(timeout);
|
|
6773
|
-
|
|
6898
|
+
resolve18(null);
|
|
6774
6899
|
});
|
|
6775
6900
|
child.on("exit", () => {
|
|
6776
6901
|
clearTimeout(timeout);
|
|
6777
|
-
|
|
6902
|
+
resolve18(null);
|
|
6778
6903
|
});
|
|
6779
6904
|
});
|
|
6780
6905
|
}
|
|
6781
6906
|
function spawnDetached(cwd, port, logDir) {
|
|
6782
|
-
const logsDir = logDir ??
|
|
6907
|
+
const logsDir = logDir ?? resolve14(cwd, ".mind", "logs");
|
|
6783
6908
|
mkdirSync8(logsDir, { recursive: true });
|
|
6784
|
-
const logPath =
|
|
6909
|
+
const logPath = resolve14(logsDir, "mind.log");
|
|
6785
6910
|
const logFd = openSync(logPath, "a");
|
|
6786
6911
|
const child = spawn4(tsxBin(cwd), ["src/server.ts", "--port", String(port)], {
|
|
6787
6912
|
cwd,
|
|
@@ -6897,11 +7022,11 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
6897
7022
|
return c.json({ error: `Name already in use: ${variantName}` }, 409);
|
|
6898
7023
|
}
|
|
6899
7024
|
const projectRoot = mindDir(mindName);
|
|
6900
|
-
const variantDir =
|
|
7025
|
+
const variantDir = resolve15(projectRoot, ".variants", variantName);
|
|
6901
7026
|
if (existsSync9(variantDir)) {
|
|
6902
7027
|
return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
|
|
6903
7028
|
}
|
|
6904
|
-
mkdirSync9(
|
|
7029
|
+
mkdirSync9(resolve15(projectRoot, ".variants"), { recursive: true });
|
|
6905
7030
|
try {
|
|
6906
7031
|
await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
|
|
6907
7032
|
} catch (e) {
|
|
@@ -6914,7 +7039,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
6914
7039
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
6915
7040
|
await exec(cmd, args, {
|
|
6916
7041
|
cwd: variantDir,
|
|
6917
|
-
env: { ...process.env, HOME:
|
|
7042
|
+
env: { ...process.env, HOME: resolve15(variantDir, "home") }
|
|
6918
7043
|
});
|
|
6919
7044
|
} else {
|
|
6920
7045
|
await exec("npm", ["install"], { cwd: variantDir });
|
|
@@ -6924,7 +7049,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
6924
7049
|
return c.json({ error: `npm install failed: ${msg}` }, 500);
|
|
6925
7050
|
}
|
|
6926
7051
|
if (body.soul) {
|
|
6927
|
-
writeFileSync8(
|
|
7052
|
+
writeFileSync8(resolve15(variantDir, "home/SOUL.md"), body.soul);
|
|
6928
7053
|
}
|
|
6929
7054
|
const variantPort = body.port ?? await nextPort();
|
|
6930
7055
|
await addVariant(variantName, mindName, variantPort, variantDir, variantName);
|
|
@@ -7019,8 +7144,8 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7019
7144
|
await cleanupVariant(variantName, projectRoot, variantEntry.dir);
|
|
7020
7145
|
if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
|
|
7021
7146
|
try {
|
|
7022
|
-
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-
|
|
7023
|
-
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-
|
|
7147
|
+
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-DMHSLRDX.js");
|
|
7148
|
+
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-GV35XFT7.js");
|
|
7024
7149
|
const tmpl = parentEntry.template ?? "claude";
|
|
7025
7150
|
await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
|
|
7026
7151
|
} catch (err) {
|
|
@@ -7033,7 +7158,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7033
7158
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
7034
7159
|
await exec(cmd, args, {
|
|
7035
7160
|
cwd: projectRoot,
|
|
7036
|
-
env: { ...process.env, HOME:
|
|
7161
|
+
env: { ...process.env, HOME: resolve15(projectRoot, "home") }
|
|
7037
7162
|
});
|
|
7038
7163
|
} else {
|
|
7039
7164
|
await exec("npm", ["install"], { cwd: projectRoot });
|
|
@@ -7450,11 +7575,11 @@ var app23 = new Hono26().get("/:name/conversations/:id/events", async (c) => {
|
|
|
7450
7575
|
if (!stream.aborted) console.error("[chat] SSE ping error:", err);
|
|
7451
7576
|
});
|
|
7452
7577
|
}, 15e3);
|
|
7453
|
-
await new Promise((
|
|
7578
|
+
await new Promise((resolve18) => {
|
|
7454
7579
|
stream.onAbort(() => {
|
|
7455
7580
|
unsubscribe();
|
|
7456
7581
|
clearInterval(keepAlive);
|
|
7457
|
-
|
|
7582
|
+
resolve18();
|
|
7458
7583
|
});
|
|
7459
7584
|
});
|
|
7460
7585
|
});
|
|
@@ -7667,7 +7792,7 @@ var app_default = app25;
|
|
|
7667
7792
|
import { existsSync as existsSync10 } from "fs";
|
|
7668
7793
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
7669
7794
|
import { createServer as createHttpsServer } from "https";
|
|
7670
|
-
import { dirname as dirname2, extname as extname3, resolve as
|
|
7795
|
+
import { dirname as dirname2, extname as extname3, resolve as resolve16 } from "path";
|
|
7671
7796
|
import { serve } from "@hono/node-server";
|
|
7672
7797
|
var MIME_TYPES2 = {
|
|
7673
7798
|
".html": "text/html",
|
|
@@ -7686,7 +7811,7 @@ async function startServer({
|
|
|
7686
7811
|
let assetsDir = "";
|
|
7687
7812
|
let searchDir = dirname2(new URL(import.meta.url).pathname);
|
|
7688
7813
|
for (let i = 0; i < 5; i++) {
|
|
7689
|
-
const candidate =
|
|
7814
|
+
const candidate = resolve16(searchDir, "dist", "web-assets");
|
|
7690
7815
|
if (existsSync10(candidate)) {
|
|
7691
7816
|
assetsDir = candidate;
|
|
7692
7817
|
break;
|
|
@@ -7697,20 +7822,20 @@ async function startServer({
|
|
|
7697
7822
|
app_default.get("*", async (c) => {
|
|
7698
7823
|
const urlPath = new URL(c.req.url).pathname;
|
|
7699
7824
|
if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
|
|
7700
|
-
const filePath =
|
|
7825
|
+
const filePath = resolve16(assetsDir, urlPath.slice(1));
|
|
7701
7826
|
if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
|
|
7702
7827
|
const s = await stat2(filePath).catch(() => null);
|
|
7703
7828
|
if (s?.isFile()) {
|
|
7704
7829
|
const ext = extname3(filePath);
|
|
7705
7830
|
const mime = MIME_TYPES2[ext] || "application/octet-stream";
|
|
7706
7831
|
const body = await readFile2(filePath);
|
|
7707
|
-
const
|
|
7708
|
-
const nameWithoutExt =
|
|
7832
|
+
const basename2 = filePath.slice(filePath.lastIndexOf("/") + 1);
|
|
7833
|
+
const nameWithoutExt = basename2.slice(0, basename2.lastIndexOf("."));
|
|
7709
7834
|
const isHashed = /[-.][\da-f]{8,}$/.test(nameWithoutExt);
|
|
7710
7835
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
7711
7836
|
return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
|
|
7712
7837
|
}
|
|
7713
|
-
const indexPath =
|
|
7838
|
+
const indexPath = resolve16(assetsDir, "index.html");
|
|
7714
7839
|
const indexStat = await stat2(indexPath).catch(() => null);
|
|
7715
7840
|
if (indexStat?.isFile()) {
|
|
7716
7841
|
const body = await readFile2(indexPath, "utf-8");
|
|
@@ -7727,10 +7852,10 @@ async function startServer({
|
|
|
7727
7852
|
createServer: createHttpsServer,
|
|
7728
7853
|
serverOptions: { key: tls.key, cert: tls.cert }
|
|
7729
7854
|
});
|
|
7730
|
-
await new Promise((
|
|
7855
|
+
await new Promise((resolve18, reject) => {
|
|
7731
7856
|
server2.on("listening", () => {
|
|
7732
7857
|
logger_default.info("Volute UI running (https)", { hostname, port });
|
|
7733
|
-
|
|
7858
|
+
resolve18();
|
|
7734
7859
|
});
|
|
7735
7860
|
server2.on("error", (err) => {
|
|
7736
7861
|
reject(err);
|
|
@@ -7738,13 +7863,13 @@ async function startServer({
|
|
|
7738
7863
|
});
|
|
7739
7864
|
const internalPort = port + 1;
|
|
7740
7865
|
const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
|
|
7741
|
-
await new Promise((
|
|
7866
|
+
await new Promise((resolve18, reject) => {
|
|
7742
7867
|
internalServer.on("listening", () => {
|
|
7743
7868
|
logger_default.info("Volute API running (http, internal)", {
|
|
7744
7869
|
hostname: "127.0.0.1",
|
|
7745
7870
|
port: internalPort
|
|
7746
7871
|
});
|
|
7747
|
-
|
|
7872
|
+
resolve18();
|
|
7748
7873
|
});
|
|
7749
7874
|
internalServer.on("error", (err) => {
|
|
7750
7875
|
reject(err);
|
|
@@ -7753,10 +7878,10 @@ async function startServer({
|
|
|
7753
7878
|
return { server: server2, internalPort };
|
|
7754
7879
|
}
|
|
7755
7880
|
const server = serve({ fetch: app_default.fetch, port, hostname });
|
|
7756
|
-
await new Promise((
|
|
7881
|
+
await new Promise((resolve18, reject) => {
|
|
7757
7882
|
server.on("listening", () => {
|
|
7758
7883
|
logger_default.info("Volute API running (http)", { hostname, port });
|
|
7759
|
-
|
|
7884
|
+
resolve18();
|
|
7760
7885
|
});
|
|
7761
7886
|
server.on("error", (err) => {
|
|
7762
7887
|
reject(err);
|
|
@@ -7767,7 +7892,7 @@ async function startServer({
|
|
|
7767
7892
|
|
|
7768
7893
|
// packages/daemon/src/daemon.ts
|
|
7769
7894
|
if (!process.env.VOLUTE_HOME) {
|
|
7770
|
-
process.env.VOLUTE_HOME =
|
|
7895
|
+
process.env.VOLUTE_HOME = resolve17(homedir3(), ".volute");
|
|
7771
7896
|
}
|
|
7772
7897
|
if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
|
|
7773
7898
|
process.env.TZ = process.env.VOLUTE_TIMEZONE;
|
|
@@ -7778,7 +7903,7 @@ async function startDaemon(opts) {
|
|
|
7778
7903
|
const home = voluteHome();
|
|
7779
7904
|
const systemDir = voluteSystemDir();
|
|
7780
7905
|
if (!opts.foreground) {
|
|
7781
|
-
const rotatingLog = new RotatingLog(
|
|
7906
|
+
const rotatingLog = new RotatingLog(resolve17(systemDir, "daemon.log"));
|
|
7782
7907
|
logger_default.setOutput((line) => rotatingLog.write(`${line}
|
|
7783
7908
|
`));
|
|
7784
7909
|
const write = (...args) => rotatingLog.write(`${format(...args)}
|
|
@@ -7788,22 +7913,22 @@ async function startDaemon(opts) {
|
|
|
7788
7913
|
console.warn = write;
|
|
7789
7914
|
console.info = write;
|
|
7790
7915
|
}
|
|
7791
|
-
const DAEMON_PID_PATH =
|
|
7792
|
-
const DAEMON_JSON_PATH =
|
|
7916
|
+
const DAEMON_PID_PATH = resolve17(systemDir, "daemon.pid");
|
|
7917
|
+
const DAEMON_JSON_PATH = resolve17(systemDir, "daemon.json");
|
|
7793
7918
|
mkdirSync10(home, { recursive: true });
|
|
7794
7919
|
ensureSystemDir();
|
|
7795
|
-
const { migrateSetupCompleted } = await import("./setup-
|
|
7920
|
+
const { migrateSetupCompleted } = await import("./setup-OTEC3ZPM.js");
|
|
7796
7921
|
migrateSetupCompleted();
|
|
7797
|
-
await (await import("./db-
|
|
7922
|
+
await (await import("./db-ZEPKEJJD.js")).getDb();
|
|
7798
7923
|
try {
|
|
7799
7924
|
const { eq: eq7, and: and5 } = await import("drizzle-orm");
|
|
7800
|
-
const { users: users2 } = await import("./schema-
|
|
7801
|
-
const db = await (await import("./db-
|
|
7925
|
+
const { users: users2 } = await import("./schema-LYQUDL7G.js");
|
|
7926
|
+
const db = await (await import("./db-ZEPKEJJD.js")).getDb();
|
|
7802
7927
|
await db.update(users2).set({ role: "system" }).where(and5(eq7(users2.user_type, "system"), eq7(users2.role, "user")));
|
|
7803
7928
|
} catch (err) {
|
|
7804
7929
|
logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
|
|
7805
7930
|
}
|
|
7806
|
-
const { initSandbox } = await import("./sandbox-
|
|
7931
|
+
const { initSandbox } = await import("./sandbox-5R32QKWQ.js");
|
|
7807
7932
|
await initSandbox();
|
|
7808
7933
|
try {
|
|
7809
7934
|
await syncBuiltinSkills();
|
|
@@ -7830,7 +7955,7 @@ async function startDaemon(opts) {
|
|
|
7830
7955
|
logger_default.warn("failed to ensure #system channel", logger_default.errorData(err));
|
|
7831
7956
|
}
|
|
7832
7957
|
try {
|
|
7833
|
-
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-
|
|
7958
|
+
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-X6ZITZ7D.js");
|
|
7834
7959
|
await getOrCreateSystemUser2();
|
|
7835
7960
|
} catch (err) {
|
|
7836
7961
|
logger_default.warn(
|
|
@@ -7839,12 +7964,12 @@ async function startDaemon(opts) {
|
|
|
7839
7964
|
);
|
|
7840
7965
|
}
|
|
7841
7966
|
const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes(32).toString("hex");
|
|
7842
|
-
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-
|
|
7967
|
+
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-OTEC3ZPM.js");
|
|
7843
7968
|
const globalCfg = readGlobalConfig2();
|
|
7844
7969
|
let tls;
|
|
7845
7970
|
if (opts.tailscale || globalCfg.tailscale) {
|
|
7846
7971
|
try {
|
|
7847
|
-
const { getTailscaleTls } = await import("./tailscale-
|
|
7972
|
+
const { getTailscaleTls } = await import("./tailscale-X4HRKRTW.js");
|
|
7848
7973
|
const tlsConfig = await getTailscaleTls();
|
|
7849
7974
|
tls = { key: tlsConfig.key, cert: tlsConfig.cert };
|
|
7850
7975
|
logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
|
|
@@ -7923,10 +8048,10 @@ async function startDaemon(opts) {
|
|
|
7923
8048
|
await Promise.all(workers);
|
|
7924
8049
|
}
|
|
7925
8050
|
try {
|
|
7926
|
-
const { isSetupComplete: isSetupComplete2 } = await import("./setup-
|
|
8051
|
+
const { isSetupComplete: isSetupComplete2 } = await import("./setup-OTEC3ZPM.js");
|
|
7927
8052
|
if (isSetupComplete2()) {
|
|
7928
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
7929
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
8053
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-NVXWSVKM.js");
|
|
8054
|
+
const { startSpiritFull } = await import("./mind-service-WTOFVNLW.js");
|
|
7930
8055
|
await ensureSpiritProject();
|
|
7931
8056
|
await syncSpiritTemplate();
|
|
7932
8057
|
const spiritEntry = await findMind("volute");
|
|
@@ -7943,7 +8068,7 @@ async function startDaemon(opts) {
|
|
|
7943
8068
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
7944
8069
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
7945
8070
|
});
|
|
7946
|
-
import("./cloud-sync-
|
|
8071
|
+
import("./cloud-sync-MAQCJEFJ.js").then(
|
|
7947
8072
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
7948
8073
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
7949
8074
|
})
|
|
@@ -7951,7 +8076,7 @@ async function startDaemon(opts) {
|
|
|
7951
8076
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
7952
8077
|
});
|
|
7953
8078
|
try {
|
|
7954
|
-
const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-
|
|
8079
|
+
const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-N37N2C4G.js");
|
|
7955
8080
|
backfillTemplateHashes();
|
|
7956
8081
|
notifyVersionUpdate().catch((err) => {
|
|
7957
8082
|
logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
|
|
@@ -7968,6 +8093,11 @@ async function startDaemon(opts) {
|
|
|
7968
8093
|
cleanExpiredLogs().catch((err) => {
|
|
7969
8094
|
logger_default.warn("failed to clean expired logs", logger_default.errorData(err));
|
|
7970
8095
|
});
|
|
8096
|
+
setProviderRefreshHook((provider) => {
|
|
8097
|
+
void syncProviderToMinds(provider, {
|
|
8098
|
+
listRunning: () => getMindManager().getRunningMinds()
|
|
8099
|
+
}).catch((err) => logger_default.warn("credential sync to minds failed", logger_default.errorData(err)));
|
|
8100
|
+
});
|
|
7971
8101
|
startApiKeyRefresh();
|
|
7972
8102
|
logger_default.info(`running on ${hostname}:${port}, pid ${myPid}`);
|
|
7973
8103
|
function cleanup() {
|