volute 0.43.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activity-events-UISXY4Y5.js → activity-events-OMCSM7XW.js} +3 -3
- package/dist/{ai-service-FBCCEYF5.js → ai-service-7PHSRDMO.js} +4 -4
- package/dist/{archive-I32WHCJB.js → archive-6R4TZMYI.js} +3 -3
- package/dist/{auth-3RIG6GKN.js → auth-FRZJVQCS.js} +4 -4
- package/dist/avatar-image-BNWEXSA2.js +16 -0
- package/dist/{chat-SDSX5TVV.js → chat-I4EDDIQC.js} +2 -2
- package/dist/{chunk-AD46AYZQ.js → chunk-2BONPXAF.js} +1 -1
- package/dist/{chunk-PGPLCJPK.js → chunk-3ERIL673.js} +1 -1
- package/dist/{chunk-C6ESRQZ7.js → chunk-3GYVW2X3.js} +1 -1
- package/dist/{chunk-SPLPKBES.js → chunk-5AHYQHNT.js} +4 -8
- package/dist/{chunk-XDTKJNW5.js → chunk-5GT7URXJ.js} +1 -1
- package/dist/{chunk-65OLHBCL.js → chunk-7FT24JBQ.js} +8 -8
- package/dist/{chunk-ZO7IQJKO.js → chunk-7KWANSLX.js} +3 -3
- package/dist/{chunk-EFL5UOY4.js → chunk-CYI534DJ.js} +3 -3
- package/dist/{chunk-FZ5TH5PF.js → chunk-EQZD4YU3.js} +8 -8
- package/dist/{chunk-57LBQ7JX.js → chunk-FHWUQZXE.js} +1 -1
- package/dist/{chunk-K4EHBHPE.js → chunk-FZMEVCWC.js} +3 -3
- package/dist/{chunk-YAMO2U3N.js → chunk-H7IYFRAL.js} +1 -1
- package/dist/{chunk-M3PGGSBH.js → chunk-HVU45COX.js} +1 -1
- package/dist/{chunk-FSSUANZJ.js → chunk-I2Y2YHIO.js} +5 -5
- package/dist/{chunk-O3DXAR44.js → chunk-IEWZ7VD7.js} +2 -2
- package/dist/{chunk-YSV3VJQK.js → chunk-J47TIYHA.js} +1 -1
- package/dist/{chunk-QHG4OMZL.js → chunk-KDLYIECM.js} +37 -32
- package/dist/{chunk-EE7SZJON.js → chunk-KP3KWNG6.js} +2 -2
- package/dist/{chunk-JVK6QQIC.js → chunk-LAXUUY7O.js} +2 -2
- package/dist/{chunk-3WLWKOGM.js → chunk-NF75HPNR.js} +5 -5
- package/dist/{chunk-PF2AB7VJ.js → chunk-OMETFX5H.js} +321 -204
- package/dist/{chunk-ONM2AZFL.js → chunk-PNV24SEP.js} +1 -1
- package/dist/{chunk-ATEX3ZPG.js → chunk-Q2XBKQ2D.js} +2 -2
- package/dist/{chunk-GZJFC76M.js → chunk-QMJJWTNL.js} +1 -1
- package/dist/chunk-SQL7M4HJ.js +120 -0
- package/dist/{chunk-2HIVYZDB.js → chunk-UMI4UIJG.js} +1 -1
- package/dist/{chunk-7G2EEYXX.js → chunk-ZMIMSIIT.js} +2 -2
- package/dist/{chunk-L3IV23ZG.js → chunk-ZV7MFISX.js} +2 -0
- package/dist/cli.js +47 -22
- package/dist/{cloud-sync-FRYNWKCR.js → cloud-sync-6WJ7WFYD.js} +16 -16
- package/dist/{conversations-67WWW25C.js → conversations-WAJYZKOC.js} +4 -4
- package/dist/{create-7W3LV3J7.js → create-YZIV5OJC.js} +1 -1
- package/dist/{daemon-restart-5GVZ5V3X.js → daemon-restart-OUJVINXV.js} +7 -7
- package/dist/daemon.js +297 -294
- package/dist/{db-CZV62BOQ.js → db-JFLCJCUG.js} +2 -2
- package/dist/{db-IJL6B26S.js → db-LZTLA7XC.js} +1 -1
- package/dist/delivery-manager-TEVOHX5W.js +32 -0
- package/dist/{delivery-router-HXBHYHJM.js → delivery-router-GODSIS62.js} +3 -3
- package/dist/{down-RRNYIGCU.js → down-XCAZXWLB.js} +5 -5
- package/dist/echo-text-T7ZA5EYD.js +32 -0
- package/dist/{exec-SJK7VUTC.js → exec-4GWHAHS3.js} +3 -3
- package/dist/{export-7LPCIB5J.js → export-ID7YUSLZ.js} +3 -3
- package/dist/{extensions-76EGTMFY.js → extensions-3QNDGW5E.js} +16 -16
- package/dist/{files-LV7VAKPC.js → files-BQ2WB5KC.js} +3 -3
- package/dist/{import-XPECCRQ7.js → import-SKID37QX.js} +6 -6
- package/dist/{isolation-5AYEY55P.js → isolation-5MB3J73F.js} +3 -3
- package/dist/{login-KJSN4JDA.js → login-LM4NF4ZB.js} +2 -2
- package/dist/{logout-TMJGUQV2.js → logout-CTJVIZGA.js} +2 -2
- package/dist/message-delivery-2EA5LLMD.js +34 -0
- package/dist/{mind-QEWCR7FA.js → mind-MI7Z6KM2.js} +5 -5
- package/dist/{mind-activity-tracker-JHAT6456.js → mind-activity-tracker-BGHJE7XA.js} +4 -4
- package/dist/mind-service-S3SY7HAM.js +36 -0
- package/dist/{package-ZOI2KAYC.js → package-5B4XDTJH.js} +1 -1
- package/dist/{registry-7LQHTRUX.js → registry-NUJAGLQJ.js} +2 -2
- package/dist/{sandbox-SJH3XOPZ.js → sandbox-IOPWWILM.js} +4 -4
- package/dist/scheduler-CXWQ6Z4E.js +30 -0
- package/dist/{schema-LRUTFOER.js → schema-PVNG3PQM.js} +1 -1
- package/dist/{seed-KOG6KJAO.js → seed-UUPVQWFB.js} +1 -1
- package/dist/{seed-cmd-GJFENEJH.js → seed-cmd-7XPKDQUC.js} +2 -2
- package/dist/{seed-create-YXO6R4KE.js → seed-create-IZ4M5ESO.js} +3 -3
- package/dist/{seed-sprout-BBU64QXP.js → seed-sprout-POJXHJWV.js} +7 -7
- package/dist/{send-ZBZWIH5V.js → send-O6W53VBM.js} +37 -42
- package/dist/{service-4EVZKGSA.js → service-AQVPUANO.js} +4 -4
- package/dist/{service-install-SHRM6NHK.js → service-install-4QNUDKLM.js} +5 -5
- package/dist/{setup-354PDHUF.js → setup-5GCO3CUB.js} +7 -7
- package/dist/{setup-25MMJ3J4.js → setup-MLRKNP7Y.js} +3 -3
- package/dist/{skills-DPI3WZPQ.js → skills-775C7QFF.js} +5 -5
- package/dist/sleep-manager-HINI6Y46.js +34 -0
- package/dist/{spirit-JQQHUVWR.js → spirit-IK5OYWMV.js} +7 -7
- package/dist/{sprout-4WAYBUVV.js → sprout-ZY5QGOEL.js} +1 -1
- package/dist/{src-O4PRLMKM.js → src-JAOVXO5W.js} +1 -0
- package/dist/{src-TJ7RBU5H.js → src-XFY3XDD6.js} +24 -19
- package/dist/{src-L2Z7X5UT.js → src-YH6PQ7LJ.js} +264 -52
- package/dist/{status-WTU2WHXY.js → status-E5DQNCAO.js} +5 -5
- package/dist/system-chat-4DQZOEZI.js +34 -0
- package/dist/{tailscale-Q7ZJL7S7.js → tailscale-QAWVKQKU.js} +2 -2
- package/dist/{turn-tracker-2GMKJQTN.js → turn-tracker-RWZMY7M6.js} +5 -5
- package/dist/{up-7RSBEKW6.js → up-FLCDR2UB.js} +6 -6
- package/dist/{update-EJ7Q77ZX.js → update-7TYVH5FM.js} +5 -5
- package/dist/{update-check-ACYYNKTW.js → update-check-VSCSJ7KX.js} +3 -3
- package/dist/{version-notify-DCAIXXZB.js → version-notify-B67N35A3.js} +17 -17
- package/dist/web-assets/assets/{index-DTDmEfPU.js → index-Domoz5Cg.js} +8 -8
- package/dist/web-assets/assets/index-dJdNzAPn.css +1 -0
- package/dist/web-assets/ext-theme.css +5 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +1 -1
- package/packages/extensions/notes/dist/ui/assets/{index-BbgANhFm.js → index-D0-DgYyj.js} +1 -1
- package/packages/extensions/notes/dist/ui/index.html +1 -1
- package/packages/extensions/notes/skills/notes/SKILL.md +31 -3
- package/packages/extensions/pages/dist/ui/assets/{index-Dxk-DYrf.js → index-CQjEQg1r.js} +1 -1
- package/packages/extensions/pages/dist/ui/index.html +1 -1
- package/templates/_base/.init/.local/hooks/startup-context.ts +25 -0
- package/templates/claude/src/agent.ts +16 -2
- package/templates/claude/src/lib/message-channel.ts +28 -6
- package/dist/delivery-manager-5J2BE22P.js +0 -32
- package/dist/echo-text-XKBJM6RV.js +0 -32
- package/dist/message-delivery-WJBZFALY.js +0 -34
- package/dist/mind-service-ZBVUMJ5H.js +0 -36
- package/dist/scheduler-BR6C6B3E.js +0 -30
- package/dist/sleep-manager-BVU5D2AE.js +0 -34
- package/dist/system-chat-KMQIP7VH.js +0 -34
- package/dist/web-assets/assets/index-D7udpBCx.css +0 -1
package/dist/daemon.js
CHANGED
|
@@ -6,21 +6,25 @@ import {
|
|
|
6
6
|
rejectPending,
|
|
7
7
|
stageFile,
|
|
8
8
|
validateFilePath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-UMI4UIJG.js";
|
|
10
10
|
import {
|
|
11
11
|
findOpenClawSession,
|
|
12
12
|
importOpenClawConnectors,
|
|
13
13
|
importPiSession,
|
|
14
14
|
parseNameFromIdentity
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-LAXUUY7O.js";
|
|
16
16
|
import {
|
|
17
17
|
checkForUpdate,
|
|
18
18
|
checkForUpdateCached,
|
|
19
19
|
getCurrentVersion
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-2BONPXAF.js";
|
|
21
|
+
import {
|
|
22
|
+
normalizeAvatar,
|
|
23
|
+
safeResolveWithinBase
|
|
24
|
+
} from "./chunk-SQL7M4HJ.js";
|
|
21
25
|
import {
|
|
22
26
|
isHomeOnlyArchive
|
|
23
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-QMJJWTNL.js";
|
|
24
28
|
import {
|
|
25
29
|
computeTemplateHash
|
|
26
30
|
} from "./chunk-QMJCNZ6C.js";
|
|
@@ -30,7 +34,7 @@ import {
|
|
|
30
34
|
fixModelEscapes,
|
|
31
35
|
getPlatformDriver,
|
|
32
36
|
routeOutboundBridge
|
|
33
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-EQZD4YU3.js";
|
|
34
38
|
import {
|
|
35
39
|
getBridgeConfig,
|
|
36
40
|
readBridgesConfig,
|
|
@@ -39,7 +43,7 @@ import {
|
|
|
39
43
|
resolveChannelMapping,
|
|
40
44
|
setBridgeConfig,
|
|
41
45
|
setChannelMapping
|
|
42
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-FHWUQZXE.js";
|
|
43
47
|
import {
|
|
44
48
|
MindStartupError,
|
|
45
49
|
RestartTracker,
|
|
@@ -48,6 +52,7 @@ import {
|
|
|
48
52
|
announceToSystem,
|
|
49
53
|
authMiddleware,
|
|
50
54
|
checkHealth,
|
|
55
|
+
checkStaleSend,
|
|
51
56
|
cleanExpiredSessions,
|
|
52
57
|
clearDeliveredNotices,
|
|
53
58
|
createSession,
|
|
@@ -56,6 +61,7 @@ import {
|
|
|
56
61
|
deliverMessage,
|
|
57
62
|
drainNotices,
|
|
58
63
|
ensureSystemChannel,
|
|
64
|
+
formatHoldNotice,
|
|
59
65
|
formatNotices,
|
|
60
66
|
generateSystemReply,
|
|
61
67
|
getAllDiscoveredExtensions,
|
|
@@ -98,15 +104,15 @@ import {
|
|
|
98
104
|
syncProviderToMinds,
|
|
99
105
|
uninstallNpmExtension,
|
|
100
106
|
writeSystemsConfig
|
|
101
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-OMETFX5H.js";
|
|
102
108
|
import {
|
|
103
109
|
loadMergedEnv,
|
|
104
110
|
mindEnvPath,
|
|
105
111
|
readEnv,
|
|
106
112
|
sharedEnvPath,
|
|
107
113
|
writeEnv
|
|
108
|
-
} from "./chunk-
|
|
109
|
-
import "./chunk-
|
|
114
|
+
} from "./chunk-5GT7URXJ.js";
|
|
115
|
+
import "./chunk-7FT24JBQ.js";
|
|
110
116
|
import {
|
|
111
117
|
applyInitFiles,
|
|
112
118
|
applyTemplateHomeFiles,
|
|
@@ -135,7 +141,7 @@ import {
|
|
|
135
141
|
syncBuiltinSkills,
|
|
136
142
|
uninstallSkill,
|
|
137
143
|
updateSkill
|
|
138
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-I2Y2YHIO.js";
|
|
139
145
|
import {
|
|
140
146
|
addMessage,
|
|
141
147
|
createChannel,
|
|
@@ -167,7 +173,7 @@ import {
|
|
|
167
173
|
setConversationPrivate,
|
|
168
174
|
subscribe as subscribe2,
|
|
169
175
|
updateChannelSettings
|
|
170
|
-
} from "./chunk-
|
|
176
|
+
} from "./chunk-FZMEVCWC.js";
|
|
171
177
|
import {
|
|
172
178
|
readVoluteConfig,
|
|
173
179
|
writeVoluteConfig
|
|
@@ -175,15 +181,15 @@ import {
|
|
|
175
181
|
import {
|
|
176
182
|
isSandboxEnabled,
|
|
177
183
|
wrapForSandbox
|
|
178
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-3GYVW2X3.js";
|
|
179
185
|
import {
|
|
180
186
|
getActiveMinds,
|
|
181
187
|
onMindEvent,
|
|
182
188
|
stopAll
|
|
183
|
-
} from "./chunk-
|
|
189
|
+
} from "./chunk-HVU45COX.js";
|
|
184
190
|
import {
|
|
185
191
|
extractTextContent
|
|
186
|
-
} from "./chunk-
|
|
192
|
+
} from "./chunk-5AHYQHNT.js";
|
|
187
193
|
import {
|
|
188
194
|
PROMPT_DEFAULTS,
|
|
189
195
|
PROMPT_KEYS,
|
|
@@ -206,8 +212,8 @@ import {
|
|
|
206
212
|
summarizeTurn,
|
|
207
213
|
takeErrored,
|
|
208
214
|
trackToolUse
|
|
209
|
-
} from "./chunk-
|
|
210
|
-
import "./chunk-
|
|
215
|
+
} from "./chunk-NF75HPNR.js";
|
|
216
|
+
import "./chunk-Q2XBKQ2D.js";
|
|
211
217
|
import {
|
|
212
218
|
chownMindDir,
|
|
213
219
|
createMindUser,
|
|
@@ -218,7 +224,7 @@ import {
|
|
|
218
224
|
isIsolationEnabled,
|
|
219
225
|
resolveVoluteBin,
|
|
220
226
|
wrapForIsolation
|
|
221
|
-
} from "./chunk-
|
|
227
|
+
} from "./chunk-3ERIL673.js";
|
|
222
228
|
import {
|
|
223
229
|
addCustomModel,
|
|
224
230
|
buildCustomModel,
|
|
@@ -239,12 +245,12 @@ import {
|
|
|
239
245
|
setProviderRefreshHook,
|
|
240
246
|
setUtilityModel,
|
|
241
247
|
unqualifyModelId
|
|
242
|
-
} from "./chunk-
|
|
248
|
+
} from "./chunk-J47TIYHA.js";
|
|
243
249
|
import {
|
|
244
250
|
isSetupComplete,
|
|
245
251
|
readGlobalConfig,
|
|
246
252
|
writeGlobalConfig
|
|
247
|
-
} from "./chunk-
|
|
253
|
+
} from "./chunk-PNV24SEP.js";
|
|
248
254
|
import {
|
|
249
255
|
approveUser,
|
|
250
256
|
changePassword,
|
|
@@ -263,11 +269,11 @@ import {
|
|
|
263
269
|
syncMindProfile,
|
|
264
270
|
updateUserProfile,
|
|
265
271
|
verifyUser
|
|
266
|
-
} from "./chunk-
|
|
272
|
+
} from "./chunk-CYI534DJ.js";
|
|
267
273
|
import {
|
|
268
274
|
broadcast,
|
|
269
275
|
subscribe
|
|
270
|
-
} from "./chunk-
|
|
276
|
+
} from "./chunk-ZMIMSIIT.js";
|
|
271
277
|
import {
|
|
272
278
|
logBuffer,
|
|
273
279
|
logger_default
|
|
@@ -299,7 +305,7 @@ import {
|
|
|
299
305
|
validateMindName,
|
|
300
306
|
voluteHome,
|
|
301
307
|
voluteSystemDir
|
|
302
|
-
} from "./chunk-
|
|
308
|
+
} from "./chunk-H7IYFRAL.js";
|
|
303
309
|
import {
|
|
304
310
|
activity,
|
|
305
311
|
channels,
|
|
@@ -310,14 +316,14 @@ import {
|
|
|
310
316
|
systemPrompts,
|
|
311
317
|
turns,
|
|
312
318
|
users
|
|
313
|
-
} from "./chunk-
|
|
319
|
+
} from "./chunk-ZV7MFISX.js";
|
|
314
320
|
import "./chunk-K3NQKI34.js";
|
|
315
321
|
|
|
316
322
|
// packages/daemon/src/daemon.ts
|
|
317
323
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
318
324
|
import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
|
|
319
325
|
import { homedir as homedir3 } from "os";
|
|
320
|
-
import { resolve as
|
|
326
|
+
import { resolve as resolve16 } from "path";
|
|
321
327
|
import { format } from "util";
|
|
322
328
|
|
|
323
329
|
// packages/daemon/src/lib/daemon/bridge-manager.ts
|
|
@@ -527,8 +533,8 @@ var BridgeManager = class {
|
|
|
527
533
|
if (!tracked) return;
|
|
528
534
|
this.stopping.add(platform);
|
|
529
535
|
this.bridges.delete(platform);
|
|
530
|
-
await new Promise((
|
|
531
|
-
tracked.child.on("exit", () =>
|
|
536
|
+
await new Promise((resolve17) => {
|
|
537
|
+
tracked.child.on("exit", () => resolve17());
|
|
532
538
|
try {
|
|
533
539
|
if (tracked.child.pid) {
|
|
534
540
|
process.kill(-tracked.child.pid, "SIGTERM");
|
|
@@ -539,7 +545,7 @@ var BridgeManager = class {
|
|
|
539
545
|
if (err instanceof Error && err.code !== "ESRCH") {
|
|
540
546
|
blog.warn(`failed to stop bridge ${platform}`, logger_default.errorData(err));
|
|
541
547
|
}
|
|
542
|
-
|
|
548
|
+
resolve17();
|
|
543
549
|
}
|
|
544
550
|
setTimeout(() => {
|
|
545
551
|
try {
|
|
@@ -550,7 +556,7 @@ var BridgeManager = class {
|
|
|
550
556
|
}
|
|
551
557
|
} catch {
|
|
552
558
|
}
|
|
553
|
-
|
|
559
|
+
resolve17();
|
|
554
560
|
}, 5e3);
|
|
555
561
|
});
|
|
556
562
|
this.stopping.delete(platform);
|
|
@@ -870,10 +876,10 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
870
876
|
stream.writeSSE({ data: JSON.stringify(entry) }).catch(() => {
|
|
871
877
|
});
|
|
872
878
|
});
|
|
873
|
-
await new Promise((
|
|
879
|
+
await new Promise((resolve17) => {
|
|
874
880
|
stream.onAbort(() => {
|
|
875
881
|
unsubscribe();
|
|
876
|
-
|
|
882
|
+
resolve17();
|
|
877
883
|
});
|
|
878
884
|
});
|
|
879
885
|
});
|
|
@@ -1217,8 +1223,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1217
1223
|
createdAt: Date.now()
|
|
1218
1224
|
};
|
|
1219
1225
|
oauthFlows.set(flowId, flow);
|
|
1220
|
-
const promptPromise = needsManualCode ? new Promise((
|
|
1221
|
-
flow.resolveCode =
|
|
1226
|
+
const promptPromise = needsManualCode ? new Promise((resolve17) => {
|
|
1227
|
+
flow.resolveCode = resolve17;
|
|
1222
1228
|
}) : void 0;
|
|
1223
1229
|
oauthProvider.login({
|
|
1224
1230
|
onAuth: (info) => {
|
|
@@ -1257,7 +1263,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1257
1263
|
existing.error = err instanceof Error ? err.message : String(err);
|
|
1258
1264
|
}
|
|
1259
1265
|
});
|
|
1260
|
-
await new Promise((
|
|
1266
|
+
await new Promise((resolve17) => setTimeout(resolve17, 2e3));
|
|
1261
1267
|
const state = oauthFlows.get(flowId);
|
|
1262
1268
|
return c.json({
|
|
1263
1269
|
flowId,
|
|
@@ -1515,8 +1521,8 @@ var app2 = new Hono2().get("/events", async (c) => {
|
|
|
1515
1521
|
});
|
|
1516
1522
|
}, 15e3);
|
|
1517
1523
|
cleanups.push(() => clearInterval(keepAlive));
|
|
1518
|
-
await new Promise((
|
|
1519
|
-
stream.onAbort(() =>
|
|
1524
|
+
await new Promise((resolve17) => {
|
|
1525
|
+
stream.onAbort(() => resolve17());
|
|
1520
1526
|
});
|
|
1521
1527
|
} finally {
|
|
1522
1528
|
for (const cleanup of cleanups) {
|
|
@@ -1531,12 +1537,24 @@ var app2 = new Hono2().get("/events", async (c) => {
|
|
|
1531
1537
|
var activity_default = app2;
|
|
1532
1538
|
|
|
1533
1539
|
// packages/daemon/src/web/api/auth.ts
|
|
1534
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
1540
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
1535
1541
|
import { extname, resolve as resolve3 } from "path";
|
|
1536
1542
|
import { zValidator as zValidator2 } from "@hono/zod-validator";
|
|
1537
1543
|
import { Hono as Hono3 } from "hono";
|
|
1538
1544
|
import { deleteCookie, getCookie, setCookie } from "hono/cookie";
|
|
1539
1545
|
import { z as z2 } from "zod";
|
|
1546
|
+
|
|
1547
|
+
// packages/daemon/src/lib/util/http-cache.ts
|
|
1548
|
+
function fileEtag(stat3) {
|
|
1549
|
+
return `W/"${stat3.mtimeMs.toString(36)}-${stat3.size.toString(36)}"`;
|
|
1550
|
+
}
|
|
1551
|
+
function isNotModified(c, etag) {
|
|
1552
|
+
const inm = c.req.header("if-none-match");
|
|
1553
|
+
if (!inm) return false;
|
|
1554
|
+
return inm.split(",").some((t) => t.trim() === etag);
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
// packages/daemon/src/web/api/auth.ts
|
|
1540
1558
|
function tryJoinSystem(userId) {
|
|
1541
1559
|
if (!process.env.VOLUTE_DAEMON_TOKEN) return;
|
|
1542
1560
|
joinSystemChannel(userId).catch(() => {
|
|
@@ -1603,10 +1621,16 @@ var authenticated = new Hono3().use(authMiddleware).post("/change-password", zVa
|
|
|
1603
1621
|
if (!AVATAR_MIME[ext]) {
|
|
1604
1622
|
return c.json({ error: "Invalid file type (png, jpg, gif, webp only)" }, 400);
|
|
1605
1623
|
}
|
|
1624
|
+
let buffer2 = Buffer.from(await file.arrayBuffer());
|
|
1625
|
+
let finalExt = ext;
|
|
1626
|
+
const normalized = await normalizeAvatar(buffer2);
|
|
1627
|
+
if (normalized) {
|
|
1628
|
+
buffer2 = normalized.buffer;
|
|
1629
|
+
finalExt = normalized.ext;
|
|
1630
|
+
}
|
|
1606
1631
|
const dir = avatarsDir();
|
|
1607
1632
|
mkdirSync2(dir, { recursive: true });
|
|
1608
|
-
const filename = `avatar-${user.id}${
|
|
1609
|
-
const buffer2 = Buffer.from(await file.arrayBuffer());
|
|
1633
|
+
const filename = `avatar-${user.id}${finalExt}`;
|
|
1610
1634
|
writeFileSync2(resolve3(dir, filename), buffer2);
|
|
1611
1635
|
if (user.avatar && user.avatar !== filename) {
|
|
1612
1636
|
const oldPath = resolve3(dir, user.avatar);
|
|
@@ -1786,12 +1810,17 @@ var app3 = new Hono3().post("/register", zValidator2("json", credentialsSchema),
|
|
|
1786
1810
|
const ext = extname(filename).toLowerCase();
|
|
1787
1811
|
const mime = AVATAR_MIME[ext];
|
|
1788
1812
|
if (!mime) return c.json({ error: "Invalid file type" }, 400);
|
|
1789
|
-
const
|
|
1790
|
-
|
|
1813
|
+
const fileStat = statSync(filePath);
|
|
1814
|
+
const etag = fileEtag(fileStat);
|
|
1815
|
+
const headers = {
|
|
1791
1816
|
"Content-Type": mime,
|
|
1792
1817
|
"Cache-Control": "public, max-age=3600",
|
|
1793
|
-
"X-Content-Type-Options": "nosniff"
|
|
1794
|
-
|
|
1818
|
+
"X-Content-Type-Options": "nosniff",
|
|
1819
|
+
ETag: etag
|
|
1820
|
+
};
|
|
1821
|
+
if (isNotModified(c, etag)) return c.body(null, 304, headers);
|
|
1822
|
+
const data = readFileSync3(filePath);
|
|
1823
|
+
return c.body(data, 200, headers);
|
|
1795
1824
|
}).route("/", admin).route("/", authenticated);
|
|
1796
1825
|
var auth_default = app3;
|
|
1797
1826
|
|
|
@@ -1847,17 +1876,6 @@ async function findOrCreatePuppet(platform, platformId, displayName) {
|
|
|
1847
1876
|
}
|
|
1848
1877
|
|
|
1849
1878
|
// packages/daemon/src/lib/delivery/fan-out.ts
|
|
1850
|
-
var MAX_CONSECUTIVE_MIND_TURNS = 6;
|
|
1851
|
-
var consecutiveMindTurns = /* @__PURE__ */ new Map();
|
|
1852
|
-
async function emitLoopNotice(conversationId) {
|
|
1853
|
-
const systemUser = await getOrCreateSystemUser();
|
|
1854
|
-
await addMessage(conversationId, "user", systemUser.username, [
|
|
1855
|
-
{
|
|
1856
|
-
type: "text",
|
|
1857
|
-
text: `[System] This exchange has continued for ${MAX_CONSECUTIVE_MIND_TURNS} consecutive automated turns without human input, so automatic delivery between minds has been paused. Send a message to resume.`
|
|
1858
|
-
}
|
|
1859
|
-
]);
|
|
1860
|
-
}
|
|
1861
1879
|
async function fanOutToMinds(opts) {
|
|
1862
1880
|
const participants = opts.participants ?? await getParticipants(opts.conversationId);
|
|
1863
1881
|
const mindParticipants = participants.filter(
|
|
@@ -1865,25 +1883,6 @@ async function fanOutToMinds(opts) {
|
|
|
1865
1883
|
);
|
|
1866
1884
|
const participantNames = participants.map((p) => p.username);
|
|
1867
1885
|
const isDM = opts.isDM ?? participants.length === 2;
|
|
1868
|
-
if (mindParticipants.length > 1) {
|
|
1869
|
-
if (opts.senderIsMind) {
|
|
1870
|
-
const count = (consecutiveMindTurns.get(opts.conversationId) ?? 0) + 1;
|
|
1871
|
-
consecutiveMindTurns.set(opts.conversationId, count);
|
|
1872
|
-
if (count > MAX_CONSECUTIVE_MIND_TURNS) {
|
|
1873
|
-
if (count === MAX_CONSECUTIVE_MIND_TURNS + 1) {
|
|
1874
|
-
await emitLoopNotice(opts.conversationId).catch(
|
|
1875
|
-
(err) => logger_default.warn(`failed to emit loop notice for ${opts.conversationId}`, logger_default.errorData(err))
|
|
1876
|
-
);
|
|
1877
|
-
}
|
|
1878
|
-
logger_default.warn(
|
|
1879
|
-
`loop protection: paused mind fan-out for ${opts.conversationId} after ${count} consecutive mind turns`
|
|
1880
|
-
);
|
|
1881
|
-
return;
|
|
1882
|
-
}
|
|
1883
|
-
} else {
|
|
1884
|
-
consecutiveMindTurns.delete(opts.conversationId);
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
1886
|
const manager = getMindManager();
|
|
1888
1887
|
const sm = getSleepManagerIfReady();
|
|
1889
1888
|
const targetMinds = mindParticipants.map((ap) => {
|
|
@@ -1989,7 +1988,7 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
|
|
|
1989
1988
|
}
|
|
1990
1989
|
const participants = await getParticipants(channel.id);
|
|
1991
1990
|
if (!participants.some((p) => p.userId === puppet.id)) {
|
|
1992
|
-
const { addParticipant } = await import("./conversations-
|
|
1991
|
+
const { addParticipant } = await import("./conversations-WAJYZKOC.js");
|
|
1993
1992
|
await addParticipant(channel.id, puppet.id);
|
|
1994
1993
|
}
|
|
1995
1994
|
const contentBlocks = body.content;
|
|
@@ -2083,7 +2082,6 @@ async function fanOutToBridgedMinds(opts) {
|
|
|
2083
2082
|
conversationId: opts.conversationId,
|
|
2084
2083
|
contentBlocks: opts.contentBlocks,
|
|
2085
2084
|
senderName: opts.senderName,
|
|
2086
|
-
senderIsMind: false,
|
|
2087
2085
|
isDM: opts.isDM
|
|
2088
2086
|
});
|
|
2089
2087
|
}
|
|
@@ -2267,14 +2265,14 @@ var app7 = new Hono8().get("/", (c) => {
|
|
|
2267
2265
|
var extensions_default = app7;
|
|
2268
2266
|
|
|
2269
2267
|
// packages/daemon/src/web/api/file-sharing.ts
|
|
2270
|
-
import { readFileSync as readFileSync4, statSync } from "fs";
|
|
2268
|
+
import { readFileSync as readFileSync4, statSync as statSync2 } from "fs";
|
|
2271
2269
|
import { resolve as resolve4 } from "path";
|
|
2272
2270
|
import { Hono as Hono9 } from "hono";
|
|
2273
2271
|
async function notifyMind(mindName, message) {
|
|
2274
2272
|
const entry = await findMind(mindName);
|
|
2275
2273
|
if (!entry) return;
|
|
2276
2274
|
try {
|
|
2277
|
-
const { sendSystemMessage } = await import("./system-chat-
|
|
2275
|
+
const { sendSystemMessage } = await import("./system-chat-4DQZOEZI.js");
|
|
2278
2276
|
await sendSystemMessage(mindName, message);
|
|
2279
2277
|
} catch (err) {
|
|
2280
2278
|
logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
|
|
@@ -2295,7 +2293,7 @@ var app8 = new Hono9().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
2295
2293
|
const senderDir = mindDir(senderName);
|
|
2296
2294
|
const filePath = resolve4(senderDir, "home", body.filePath);
|
|
2297
2295
|
const MAX_FILE_SIZE3 = 50 * 1024 * 1024;
|
|
2298
|
-
const stat3 =
|
|
2296
|
+
const stat3 = statSync2(filePath, { throwIfNoEntry: false });
|
|
2299
2297
|
if (!stat3) return c.json({ error: `File not found: ${body.filePath}` }, 404);
|
|
2300
2298
|
if (stat3.size > MAX_FILE_SIZE3) {
|
|
2301
2299
|
return c.json(
|
|
@@ -2399,34 +2397,8 @@ var file_sharing_default = app8;
|
|
|
2399
2397
|
// packages/daemon/src/web/api/files.ts
|
|
2400
2398
|
import { mkdirSync as mkdirSync3, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2401
2399
|
import { readdir, readFile, realpath, stat } from "fs/promises";
|
|
2402
|
-
import { extname as extname2, resolve as
|
|
2400
|
+
import { extname as extname2, resolve as resolve5 } from "path";
|
|
2403
2401
|
import { Hono as Hono10 } from "hono";
|
|
2404
|
-
|
|
2405
|
-
// packages/daemon/src/lib/util/paths.ts
|
|
2406
|
-
import { resolve as resolve5, sep } from "path";
|
|
2407
|
-
var PathTraversalError = class extends Error {
|
|
2408
|
-
constructor(base, userPath) {
|
|
2409
|
-
super(`Path "${userPath}" escapes base directory "${base}"`);
|
|
2410
|
-
this.name = "PathTraversalError";
|
|
2411
|
-
}
|
|
2412
|
-
};
|
|
2413
|
-
function resolveWithinBase(base, userPath) {
|
|
2414
|
-
const resolvedBase = resolve5(base);
|
|
2415
|
-
const target = resolve5(resolvedBase, userPath);
|
|
2416
|
-
if (target !== resolvedBase && !target.startsWith(resolvedBase + sep)) {
|
|
2417
|
-
throw new PathTraversalError(base, userPath);
|
|
2418
|
-
}
|
|
2419
|
-
return target;
|
|
2420
|
-
}
|
|
2421
|
-
function safeResolveWithinBase(base, userPath) {
|
|
2422
|
-
try {
|
|
2423
|
-
return resolveWithinBase(base, userPath);
|
|
2424
|
-
} catch {
|
|
2425
|
-
return null;
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
|
|
2429
|
-
// packages/daemon/src/web/api/files.ts
|
|
2430
2402
|
var AVATAR_MIME2 = {
|
|
2431
2403
|
".png": "image/png",
|
|
2432
2404
|
".jpg": "image/jpeg",
|
|
@@ -2469,17 +2441,23 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2469
2441
|
if (!AVATAR_MIME2[ext]) {
|
|
2470
2442
|
return c.json({ error: "Invalid file type (png, jpg, gif, webp only)" }, 400);
|
|
2471
2443
|
}
|
|
2444
|
+
let buffer2 = Buffer.from(await file.arrayBuffer());
|
|
2445
|
+
let finalExt = ext;
|
|
2446
|
+
const normalized = await normalizeAvatar(buffer2);
|
|
2447
|
+
if (normalized) {
|
|
2448
|
+
buffer2 = normalized.buffer;
|
|
2449
|
+
finalExt = normalized.ext;
|
|
2450
|
+
}
|
|
2472
2451
|
const dir = entry.dir ?? mindDir(name);
|
|
2473
|
-
const homeDir =
|
|
2474
|
-
const filename = `avatar${
|
|
2475
|
-
const avatarPath =
|
|
2452
|
+
const homeDir = resolve5(dir, "home");
|
|
2453
|
+
const filename = `avatar${finalExt}`;
|
|
2454
|
+
const avatarPath = resolve5(homeDir, filename);
|
|
2476
2455
|
const config2 = readVoluteConfig(dir) ?? {};
|
|
2477
2456
|
const oldAvatar = config2.profile?.avatar;
|
|
2478
2457
|
if (oldAvatar && oldAvatar !== filename) {
|
|
2479
2458
|
const oldAvatarPath = safeResolveWithinBase(homeDir, oldAvatar);
|
|
2480
2459
|
if (oldAvatarPath) rmSync2(oldAvatarPath, { force: true });
|
|
2481
2460
|
}
|
|
2482
|
-
const buffer2 = Buffer.from(await file.arrayBuffer());
|
|
2483
2461
|
mkdirSync3(homeDir, { recursive: true });
|
|
2484
2462
|
writeFileSync3(avatarPath, buffer2);
|
|
2485
2463
|
const profile = config2.profile ?? {};
|
|
@@ -2499,8 +2477,8 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2499
2477
|
const ext = extname2(config2.profile.avatar).toLowerCase();
|
|
2500
2478
|
const mime = AVATAR_MIME2[ext];
|
|
2501
2479
|
if (!mime) return c.json({ error: "Invalid avatar extension" }, 400);
|
|
2502
|
-
const homeDir =
|
|
2503
|
-
const avatarPath =
|
|
2480
|
+
const homeDir = resolve5(dir, "home");
|
|
2481
|
+
const avatarPath = resolve5(homeDir, config2.profile.avatar);
|
|
2504
2482
|
if (!avatarPath.startsWith(`${homeDir}/`)) return c.json({ error: "Invalid avatar path" }, 400);
|
|
2505
2483
|
let realAvatarPath;
|
|
2506
2484
|
try {
|
|
@@ -2516,11 +2494,15 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2516
2494
|
try {
|
|
2517
2495
|
const fileStat = await stat(realAvatarPath);
|
|
2518
2496
|
if (fileStat.size > MAX_AVATAR_SIZE2) return c.json({ error: "Avatar file too large" }, 400);
|
|
2519
|
-
const
|
|
2520
|
-
|
|
2497
|
+
const etag = fileEtag(fileStat);
|
|
2498
|
+
const headers = {
|
|
2521
2499
|
"Content-Type": mime,
|
|
2522
|
-
"Cache-Control": "public, max-age=300"
|
|
2523
|
-
|
|
2500
|
+
"Cache-Control": "public, max-age=300",
|
|
2501
|
+
ETag: etag
|
|
2502
|
+
};
|
|
2503
|
+
if (isNotModified(c, etag)) return c.body(null, 304, headers);
|
|
2504
|
+
const body = await readFile(realAvatarPath);
|
|
2505
|
+
return c.body(body, 200, headers);
|
|
2524
2506
|
} catch {
|
|
2525
2507
|
return c.json({ error: "Failed to read avatar file" }, 500);
|
|
2526
2508
|
}
|
|
@@ -2528,7 +2510,7 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2528
2510
|
const name = c.req.param("name");
|
|
2529
2511
|
const entry = await findMind(name);
|
|
2530
2512
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
2531
|
-
const homeDir =
|
|
2513
|
+
const homeDir = resolve5(entry.dir ?? mindDir(name), "home");
|
|
2532
2514
|
let entries;
|
|
2533
2515
|
try {
|
|
2534
2516
|
entries = await readdir(homeDir, { withFileTypes: true });
|
|
@@ -2543,10 +2525,10 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2543
2525
|
const name = c.req.param("name");
|
|
2544
2526
|
const entry = await findMind(name);
|
|
2545
2527
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
2546
|
-
const homeDir =
|
|
2528
|
+
const homeDir = resolve5(entry.dir ?? mindDir(name), "home");
|
|
2547
2529
|
const wildcard = c.req.path.replace(new RegExp(`^.*/minds/${name}/files`), "") || "/";
|
|
2548
2530
|
const relativePath = wildcard.slice(1);
|
|
2549
|
-
const requestedPath =
|
|
2531
|
+
const requestedPath = resolve5(homeDir, relativePath);
|
|
2550
2532
|
if (requestedPath !== homeDir && !requestedPath.startsWith(`${homeDir}/`))
|
|
2551
2533
|
return c.text("Forbidden", 403);
|
|
2552
2534
|
if (relativePath.split("/").some((seg) => seg.startsWith("."))) return c.text("Forbidden", 403);
|
|
@@ -2577,9 +2559,12 @@ var app9 = new Hono10().post("/:name/avatar", requireSelf(), async (c) => {
|
|
|
2577
2559
|
return c.json(items);
|
|
2578
2560
|
}
|
|
2579
2561
|
if (fileStat.size > MAX_FILE_SIZE) return c.text("File too large", 413);
|
|
2580
|
-
const body = await readFile(resolvedPath);
|
|
2581
2562
|
const mime = MIME_TYPES[extname2(resolvedPath).toLowerCase()] || "application/octet-stream";
|
|
2582
|
-
|
|
2563
|
+
const etag = fileEtag(fileStat);
|
|
2564
|
+
const headers = { "Content-Type": mime, "Cache-Control": "no-cache", ETag: etag };
|
|
2565
|
+
if (isNotModified(c, etag)) return c.body(null, 304, headers);
|
|
2566
|
+
const body = await readFile(resolvedPath);
|
|
2567
|
+
return c.body(body, 200, headers);
|
|
2583
2568
|
});
|
|
2584
2569
|
var files_default = app9;
|
|
2585
2570
|
|
|
@@ -2989,16 +2974,16 @@ import { Hono as Hono12 } from "hono";
|
|
|
2989
2974
|
// packages/daemon/src/lib/mind/identity.ts
|
|
2990
2975
|
import { createHash, generateKeyPairSync, sign, verify } from "crypto";
|
|
2991
2976
|
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
2992
|
-
import { resolve as
|
|
2977
|
+
import { resolve as resolve6 } from "path";
|
|
2993
2978
|
function generateIdentity(mindDir2) {
|
|
2994
|
-
const identityDir =
|
|
2979
|
+
const identityDir = resolve6(mindDir2, ".mind/identity");
|
|
2995
2980
|
mkdirSync4(identityDir, { recursive: true });
|
|
2996
2981
|
const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
|
|
2997
2982
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
2998
2983
|
privateKeyEncoding: { type: "pkcs8", format: "pem" }
|
|
2999
2984
|
});
|
|
3000
|
-
const privatePath =
|
|
3001
|
-
const publicPath =
|
|
2985
|
+
const privatePath = resolve6(identityDir, "private.pem");
|
|
2986
|
+
const publicPath = resolve6(identityDir, "public.pem");
|
|
3002
2987
|
writeFileSync4(privatePath, privateKey, { mode: 384 });
|
|
3003
2988
|
writeFileSync4(publicPath, publicKey, { mode: 420 });
|
|
3004
2989
|
const config2 = readVoluteConfig(mindDir2) ?? {};
|
|
@@ -3013,7 +2998,7 @@ function getPublicKey(mindDir2) {
|
|
|
3013
2998
|
const config2 = readVoluteConfig(mindDir2);
|
|
3014
2999
|
const relPath = config2?.identity?.publicKey;
|
|
3015
3000
|
if (!relPath) return null;
|
|
3016
|
-
const fullPath =
|
|
3001
|
+
const fullPath = resolve6(mindDir2, relPath);
|
|
3017
3002
|
if (!existsSync4(fullPath)) return null;
|
|
3018
3003
|
return readFileSync5(fullPath, "utf-8");
|
|
3019
3004
|
}
|
|
@@ -3063,14 +3048,14 @@ var keys_default = app10;
|
|
|
3063
3048
|
// packages/daemon/src/web/api/logs.ts
|
|
3064
3049
|
import { spawn as spawn2 } from "child_process";
|
|
3065
3050
|
import { existsSync as existsSync5 } from "fs";
|
|
3066
|
-
import { resolve as
|
|
3051
|
+
import { resolve as resolve7 } from "path";
|
|
3067
3052
|
import { Hono as Hono13 } from "hono";
|
|
3068
3053
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
3069
3054
|
var app11 = new Hono13().get("/:name/logs", requireSelf(), async (c) => {
|
|
3070
3055
|
const name = c.req.param("name");
|
|
3071
3056
|
const entry = await findMind(name);
|
|
3072
3057
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
3073
|
-
const logFile =
|
|
3058
|
+
const logFile = resolve7(stateDir(name), "logs", "mind.log");
|
|
3074
3059
|
if (!existsSync5(logFile)) {
|
|
3075
3060
|
return c.json({ error: "No log file found" }, 404);
|
|
3076
3061
|
}
|
|
@@ -3089,16 +3074,16 @@ var app11 = new Hono13().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
3089
3074
|
stream.onAbort(() => {
|
|
3090
3075
|
tail.kill();
|
|
3091
3076
|
});
|
|
3092
|
-
await new Promise((
|
|
3093
|
-
tail.on("exit",
|
|
3094
|
-
stream.onAbort(
|
|
3077
|
+
await new Promise((resolve17) => {
|
|
3078
|
+
tail.on("exit", resolve17);
|
|
3079
|
+
stream.onAbort(resolve17);
|
|
3095
3080
|
});
|
|
3096
3081
|
});
|
|
3097
3082
|
}).get("/:name/logs/tail", requireSelf(), async (c) => {
|
|
3098
3083
|
const name = c.req.param("name");
|
|
3099
3084
|
const entry = await findMind(name);
|
|
3100
3085
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
3101
|
-
const logFile =
|
|
3086
|
+
const logFile = resolve7(stateDir(name), "logs", "mind.log");
|
|
3102
3087
|
if (!existsSync5(logFile)) {
|
|
3103
3088
|
return c.json({ error: "No log file found" }, 404);
|
|
3104
3089
|
}
|
|
@@ -3109,8 +3094,8 @@ var app11 = new Hono13().get("/:name/logs", requireSelf(), async (c) => {
|
|
|
3109
3094
|
tail.stdout.on("data", (data) => {
|
|
3110
3095
|
output += data.toString();
|
|
3111
3096
|
});
|
|
3112
|
-
await new Promise((
|
|
3113
|
-
tail.on("exit",
|
|
3097
|
+
await new Promise((resolve17) => {
|
|
3098
|
+
tail.on("exit", resolve17);
|
|
3114
3099
|
});
|
|
3115
3100
|
return c.text(output);
|
|
3116
3101
|
});
|
|
@@ -3207,7 +3192,7 @@ import {
|
|
|
3207
3192
|
rmSync as rmSync4,
|
|
3208
3193
|
writeFileSync as writeFileSync7
|
|
3209
3194
|
} from "fs";
|
|
3210
|
-
import { basename, resolve as
|
|
3195
|
+
import { basename, resolve as resolve10 } from "path";
|
|
3211
3196
|
import { zValidator as zValidator5 } from "@hono/zod-validator";
|
|
3212
3197
|
import { and as and5, desc as desc4, eq as eq5, sql as sql3 } from "drizzle-orm";
|
|
3213
3198
|
import { Hono as Hono15 } from "hono";
|
|
@@ -3427,18 +3412,18 @@ async function completeTurnAndSummarize(mind, event, insertedId) {
|
|
|
3427
3412
|
|
|
3428
3413
|
// packages/daemon/src/lib/mind/consolidate.ts
|
|
3429
3414
|
import { readdirSync, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
3430
|
-
import { resolve as
|
|
3415
|
+
import { resolve as resolve8 } from "path";
|
|
3431
3416
|
async function consolidateMemory(mindDir2) {
|
|
3432
|
-
const soulPath =
|
|
3433
|
-
const memoryPath =
|
|
3434
|
-
const memoryDir =
|
|
3417
|
+
const soulPath = resolve8(mindDir2, "home/SOUL.md");
|
|
3418
|
+
const memoryPath = resolve8(mindDir2, "home/MEMORY.md");
|
|
3419
|
+
const memoryDir = resolve8(mindDir2, "home/memory");
|
|
3435
3420
|
const soul = readFileSync6(soulPath, "utf-8");
|
|
3436
3421
|
const logs = [];
|
|
3437
3422
|
try {
|
|
3438
3423
|
const files = readdirSync(memoryDir).filter((f) => /^\d{4}-\d{2}-\d{2}\.md$/.test(f)).sort();
|
|
3439
3424
|
for (const filename of files) {
|
|
3440
3425
|
const date = filename.replace(".md", "");
|
|
3441
|
-
const content2 = readFileSync6(
|
|
3426
|
+
const content2 = readFileSync6(resolve8(memoryDir, filename), "utf-8").trim();
|
|
3442
3427
|
if (content2) {
|
|
3443
3428
|
logs.push(`### ${date}
|
|
3444
3429
|
|
|
@@ -3539,7 +3524,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
|
3539
3524
|
logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
|
|
3540
3525
|
}
|
|
3541
3526
|
}
|
|
3542
|
-
const { findMind: findMind2 } = await import("./registry-
|
|
3527
|
+
const { findMind: findMind2 } = await import("./registry-NUJAGLQJ.js");
|
|
3543
3528
|
const variantEntry = await findMind2(variantName);
|
|
3544
3529
|
const branchName = variantEntry?.branch ?? variantName;
|
|
3545
3530
|
if (existsSync6(variantPath)) {
|
|
@@ -3591,7 +3576,7 @@ function validateBranchName(branch) {
|
|
|
3591
3576
|
import { randomUUID } from "crypto";
|
|
3592
3577
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
3593
3578
|
import { homedir } from "os";
|
|
3594
|
-
import { resolve as
|
|
3579
|
+
import { resolve as resolve9 } from "path";
|
|
3595
3580
|
function convertSession(opts) {
|
|
3596
3581
|
const lines = readFileSync7(opts.sessionPath, "utf-8").trim().split("\n");
|
|
3597
3582
|
const sessionId = randomUUID();
|
|
@@ -3707,9 +3692,9 @@ function convertSession(opts) {
|
|
|
3707
3692
|
}
|
|
3708
3693
|
}
|
|
3709
3694
|
const projectId = opts.projectDir.replace(/\//g, "-");
|
|
3710
|
-
const sdkDir =
|
|
3695
|
+
const sdkDir = resolve9(homedir(), ".claude", "projects", projectId);
|
|
3711
3696
|
mkdirSync5(sdkDir, { recursive: true });
|
|
3712
|
-
const sdkPath =
|
|
3697
|
+
const sdkPath = resolve9(sdkDir, `${sessionId}.jsonl`);
|
|
3713
3698
|
writeFileSync6(sdkPath, `${sdkEvents.join("\n")}
|
|
3714
3699
|
`);
|
|
3715
3700
|
console.log(`Converted ${sdkEvents.length} messages \u2192 ${sdkPath}`);
|
|
@@ -3768,7 +3753,7 @@ async function getMindStatus(name, port, registryRunning) {
|
|
|
3768
3753
|
const manager = getMindManager();
|
|
3769
3754
|
let status = "stopped";
|
|
3770
3755
|
try {
|
|
3771
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
3756
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
|
|
3772
3757
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
3773
3758
|
status = "sleeping";
|
|
3774
3759
|
}
|
|
@@ -3814,7 +3799,7 @@ async function initTemplateBranch(projectRoot, composedDir, manifest, mindName,
|
|
|
3814
3799
|
await gitExec(["commit", "-m", "initial commit"], opts);
|
|
3815
3800
|
}
|
|
3816
3801
|
async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
3817
|
-
const tempWorktree =
|
|
3802
|
+
const tempWorktree = resolve10(projectRoot, ".variants", "_template_update");
|
|
3818
3803
|
let branchExists = false;
|
|
3819
3804
|
try {
|
|
3820
3805
|
await gitExec(["rev-parse", "--verify", TEMPLATE_BRANCH], { cwd: projectRoot });
|
|
@@ -3846,15 +3831,15 @@ async function updateTemplateBranch(projectRoot, template, mindName) {
|
|
|
3846
3831
|
});
|
|
3847
3832
|
}
|
|
3848
3833
|
copyTemplateToDir(composedDir, tempWorktree, mindName, manifest);
|
|
3849
|
-
const initDir =
|
|
3834
|
+
const initDir = resolve10(tempWorktree, ".init");
|
|
3850
3835
|
if (existsSync7(initDir)) {
|
|
3851
3836
|
rmSync4(initDir, { recursive: true, force: true });
|
|
3852
3837
|
}
|
|
3853
|
-
const homeDir =
|
|
3838
|
+
const homeDir = resolve10(tempWorktree, "home");
|
|
3854
3839
|
if (existsSync7(homeDir)) {
|
|
3855
3840
|
for (const entry of readdirSync2(homeDir)) {
|
|
3856
3841
|
if (entry !== "VOLUTE.md") {
|
|
3857
|
-
rmSync4(
|
|
3842
|
+
rmSync4(resolve10(homeDir, entry), { recursive: true, force: true });
|
|
3858
3843
|
}
|
|
3859
3844
|
}
|
|
3860
3845
|
}
|
|
@@ -3895,7 +3880,7 @@ async function mergeTemplateBranch(worktreeDir) {
|
|
|
3895
3880
|
async function npmInstallAsMind(cwd, mindName) {
|
|
3896
3881
|
if (isIsolationEnabled()) {
|
|
3897
3882
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
3898
|
-
await exec(cmd, args, { cwd, env: { ...process.env, HOME:
|
|
3883
|
+
await exec(cmd, args, { cwd, env: { ...process.env, HOME: resolve10(cwd, "home") } });
|
|
3899
3884
|
} else {
|
|
3900
3885
|
await exec("npm", ["install"], { cwd });
|
|
3901
3886
|
}
|
|
@@ -3920,7 +3905,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
3920
3905
|
let switchWarning;
|
|
3921
3906
|
if (templateChanged) {
|
|
3922
3907
|
try {
|
|
3923
|
-
applyTemplateHomeFiles(
|
|
3908
|
+
applyTemplateHomeFiles(resolve10(dir, "home"), template);
|
|
3924
3909
|
await gitExec(["add", "home/"], { cwd: dir });
|
|
3925
3910
|
try {
|
|
3926
3911
|
await gitExec(["diff", "--cached", "--quiet"], { cwd: dir });
|
|
@@ -3970,7 +3955,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
3970
3955
|
return { ok: true, warning: switchWarning };
|
|
3971
3956
|
}
|
|
3972
3957
|
async function importFromArchive(c, tempDir, nameOverride, manifest) {
|
|
3973
|
-
const extractedMindDir =
|
|
3958
|
+
const extractedMindDir = resolve10(tempDir, "mind");
|
|
3974
3959
|
if (!existsSync7(extractedMindDir)) {
|
|
3975
3960
|
return c.json({ error: "Invalid archive: missing mind/ directory" }, 400);
|
|
3976
3961
|
}
|
|
@@ -3997,9 +3982,9 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
3997
3982
|
}
|
|
3998
3983
|
const state = stateDir(name);
|
|
3999
3984
|
mkdirSync6(state, { recursive: true });
|
|
4000
|
-
const envJson =
|
|
3985
|
+
const envJson = resolve10(tempDir, "state/env.json");
|
|
4001
3986
|
if (existsSync7(envJson)) {
|
|
4002
|
-
cpSync(envJson,
|
|
3987
|
+
cpSync(envJson, resolve10(state, "env.json"));
|
|
4003
3988
|
}
|
|
4004
3989
|
const port = await nextPort();
|
|
4005
3990
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
@@ -4008,23 +3993,23 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
4008
3993
|
} catch (err) {
|
|
4009
3994
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
4010
3995
|
}
|
|
4011
|
-
const homeDir =
|
|
3996
|
+
const homeDir = resolve10(dest, "home");
|
|
4012
3997
|
ensureVoluteGroup();
|
|
4013
3998
|
createMindUser(name, homeDir);
|
|
4014
3999
|
await chownMindDir(dest, name);
|
|
4015
4000
|
await npmInstallAsMind(dest, name);
|
|
4016
4001
|
await importHistoryFromArchive(name, tempDir);
|
|
4017
4002
|
importSessionsFromArchive(dest, tempDir);
|
|
4018
|
-
if (!existsSync7(
|
|
4003
|
+
if (!existsSync7(resolve10(dest, ".git"))) {
|
|
4019
4004
|
try {
|
|
4020
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
4005
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dest, "home") } : void 0;
|
|
4021
4006
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
4022
4007
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
4023
4008
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
4024
4009
|
await gitExec(["commit", "-m", "import from archive"], { cwd: dest, mindName: name, env });
|
|
4025
4010
|
} catch (err) {
|
|
4026
4011
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
4027
|
-
rmSync4(
|
|
4012
|
+
rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
|
|
4028
4013
|
}
|
|
4029
4014
|
}
|
|
4030
4015
|
await chownMindDir(dest, name);
|
|
@@ -4057,22 +4042,22 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
4057
4042
|
try {
|
|
4058
4043
|
copyTemplateToDir(composedDir, dest, name, templateManifest);
|
|
4059
4044
|
applyInitFiles(dest);
|
|
4060
|
-
const extractedHome =
|
|
4045
|
+
const extractedHome = resolve10(extractedMindDir, "home");
|
|
4061
4046
|
if (existsSync7(extractedHome)) {
|
|
4062
|
-
cpSync(extractedHome,
|
|
4047
|
+
cpSync(extractedHome, resolve10(dest, "home"), { recursive: true });
|
|
4063
4048
|
}
|
|
4064
|
-
const extractedMindInternal =
|
|
4049
|
+
const extractedMindInternal = resolve10(extractedMindDir, ".mind");
|
|
4065
4050
|
if (existsSync7(extractedMindInternal)) {
|
|
4066
|
-
cpSync(extractedMindInternal,
|
|
4051
|
+
cpSync(extractedMindInternal, resolve10(dest, ".mind"), { recursive: true });
|
|
4067
4052
|
}
|
|
4068
|
-
const identityDir =
|
|
4053
|
+
const identityDir = resolve10(dest, ".mind/identity");
|
|
4069
4054
|
let publicKeyPem;
|
|
4070
|
-
if (!manifest.includes.identity || !existsSync7(
|
|
4055
|
+
if (!manifest.includes.identity || !existsSync7(resolve10(identityDir, "private.pem"))) {
|
|
4071
4056
|
({ publicKeyPem } = generateIdentity(dest));
|
|
4072
4057
|
} else {
|
|
4073
|
-
publicKeyPem = readFileSync8(
|
|
4058
|
+
publicKeyPem = readFileSync8(resolve10(identityDir, "public.pem"), "utf-8");
|
|
4074
4059
|
}
|
|
4075
|
-
const promptsPath =
|
|
4060
|
+
const promptsPath = resolve10(dest, "home/.config/prompts.json");
|
|
4076
4061
|
if (!existsSync7(promptsPath)) {
|
|
4077
4062
|
const mindPrompts = await getMindPromptDefaults();
|
|
4078
4063
|
writeFileSync7(promptsPath, `${JSON.stringify(mindPrompts, null, 2)}
|
|
@@ -4080,13 +4065,13 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
4080
4065
|
}
|
|
4081
4066
|
const state = stateDir(name);
|
|
4082
4067
|
mkdirSync6(state, { recursive: true });
|
|
4083
|
-
const envJson =
|
|
4068
|
+
const envJson = resolve10(tempDir, "state/env.json");
|
|
4084
4069
|
if (existsSync7(envJson)) {
|
|
4085
|
-
cpSync(envJson,
|
|
4070
|
+
cpSync(envJson, resolve10(state, "env.json"));
|
|
4086
4071
|
}
|
|
4087
4072
|
const port = await nextPort();
|
|
4088
4073
|
await addMind(name, port, manifest.stage, manifest.template);
|
|
4089
|
-
const homeDir =
|
|
4074
|
+
const homeDir = resolve10(dest, "home");
|
|
4090
4075
|
ensureVoluteGroup();
|
|
4091
4076
|
createMindUser(name, homeDir);
|
|
4092
4077
|
await chownMindDir(dest, name);
|
|
@@ -4099,7 +4084,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
4099
4084
|
await initTemplateBranch(dest, composedDir, templateManifest, name, env);
|
|
4100
4085
|
} catch (err) {
|
|
4101
4086
|
logger_default.error(`git setup failed for imported mind ${name}`, logger_default.errorData(err));
|
|
4102
|
-
rmSync4(
|
|
4087
|
+
rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
|
|
4103
4088
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
4104
4089
|
}
|
|
4105
4090
|
const skillSet = manifest.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions();
|
|
@@ -4142,7 +4127,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
4142
4127
|
}
|
|
4143
4128
|
}
|
|
4144
4129
|
async function importHistoryFromArchive(name, tempDir) {
|
|
4145
|
-
const historyJsonl =
|
|
4130
|
+
const historyJsonl = resolve10(tempDir, "history.jsonl");
|
|
4146
4131
|
if (!existsSync7(historyJsonl)) return;
|
|
4147
4132
|
try {
|
|
4148
4133
|
const db = await getDb();
|
|
@@ -4182,13 +4167,13 @@ async function importHistoryFromArchive(name, tempDir) {
|
|
|
4182
4167
|
}
|
|
4183
4168
|
}
|
|
4184
4169
|
function importSessionsFromArchive(dest, tempDir) {
|
|
4185
|
-
const sessionsDir =
|
|
4170
|
+
const sessionsDir = resolve10(tempDir, "sessions");
|
|
4186
4171
|
if (!existsSync7(sessionsDir)) return;
|
|
4187
4172
|
try {
|
|
4188
|
-
const destSessions =
|
|
4173
|
+
const destSessions = resolve10(dest, ".mind/sessions");
|
|
4189
4174
|
mkdirSync6(destSessions, { recursive: true });
|
|
4190
4175
|
for (const file of readdirSync2(sessionsDir)) {
|
|
4191
|
-
cpSync(
|
|
4176
|
+
cpSync(resolve10(sessionsDir, file), resolve10(destSessions, file));
|
|
4192
4177
|
}
|
|
4193
4178
|
} catch (err) {
|
|
4194
4179
|
logger_default.error("Failed to import sessions from archive", logger_default.errorData(err));
|
|
@@ -4263,7 +4248,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4263
4248
|
applyInitFiles(dest);
|
|
4264
4249
|
const { publicKeyPem } = generateIdentity(dest);
|
|
4265
4250
|
{
|
|
4266
|
-
const { readGlobalConfig: readGlobal } = await import("./setup-
|
|
4251
|
+
const { readGlobalConfig: readGlobal } = await import("./setup-MLRKNP7Y.js");
|
|
4267
4252
|
const mindDefaults = readGlobal().mindDefaults;
|
|
4268
4253
|
const config2 = readVoluteConfig(dest);
|
|
4269
4254
|
if (!config2) throw new Error("Failed to read volute.json after identity generation");
|
|
@@ -4300,7 +4285,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4300
4285
|
}
|
|
4301
4286
|
writeVoluteConfig(dest, config2);
|
|
4302
4287
|
const modelId = body.model ?? cog?.model;
|
|
4303
|
-
const sdkConfigPath =
|
|
4288
|
+
const sdkConfigPath = resolve10(dest, "home/.config/config.json");
|
|
4304
4289
|
if (modelId || cog?.compaction) {
|
|
4305
4290
|
const existing = existsSync7(sdkConfigPath) ? JSON.parse(readFileSync8(sdkConfigPath, "utf-8")) : {};
|
|
4306
4291
|
if (modelId) {
|
|
@@ -4315,7 +4300,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4315
4300
|
}
|
|
4316
4301
|
const mindPrompts = await getMindPromptDefaults();
|
|
4317
4302
|
writeFileSync7(
|
|
4318
|
-
|
|
4303
|
+
resolve10(dest, "home/.config/prompts.json"),
|
|
4319
4304
|
`${JSON.stringify(mindPrompts, null, 2)}
|
|
4320
4305
|
`
|
|
4321
4306
|
);
|
|
@@ -4327,7 +4312,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4327
4312
|
} catch (err) {
|
|
4328
4313
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
4329
4314
|
}
|
|
4330
|
-
const homeDir =
|
|
4315
|
+
const homeDir = resolve10(dest, "home");
|
|
4331
4316
|
ensureVoluteGroup();
|
|
4332
4317
|
createMindUser(name, homeDir);
|
|
4333
4318
|
await chownMindDir(dest, name);
|
|
@@ -4340,7 +4325,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4340
4325
|
await initTemplateBranch(dest, composedDir, manifest, name, env);
|
|
4341
4326
|
} catch (err) {
|
|
4342
4327
|
logger_default.error(`git setup failed for ${name}`, logger_default.errorData(err));
|
|
4343
|
-
rmSync4(
|
|
4328
|
+
rmSync4(resolve10(dest, ".git"), { recursive: true, force: true });
|
|
4344
4329
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
4345
4330
|
}
|
|
4346
4331
|
await chownMindDir(dest, name);
|
|
@@ -4350,11 +4335,11 @@ The human who planted you described you as: "${body.description}"
|
|
|
4350
4335
|
` : "";
|
|
4351
4336
|
const seedSoulRaw = body.seedSoul ?? await getPrompt("seed_soul", { name, description: descLine });
|
|
4352
4337
|
const seedSoul = body.seedSoul ? substitute(seedSoulRaw, { name, description: descLine }) : seedSoulRaw;
|
|
4353
|
-
writeFileSync7(
|
|
4338
|
+
writeFileSync7(resolve10(dest, "home/SOUL.md"), seedSoul);
|
|
4354
4339
|
}
|
|
4355
4340
|
let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
|
|
4356
4341
|
if (body.stage === "seed" && !body.skills) {
|
|
4357
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
4342
|
+
const { isImagegenEnabled } = await import("./setup-MLRKNP7Y.js");
|
|
4358
4343
|
if (isImagegenEnabled()) {
|
|
4359
4344
|
skillSet = [...skillSet, "imagegen"];
|
|
4360
4345
|
}
|
|
@@ -4372,7 +4357,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4372
4357
|
try {
|
|
4373
4358
|
const spiritEntry = await findMind("volute");
|
|
4374
4359
|
if (spiritEntry) {
|
|
4375
|
-
const { spiritDir } = await import("./spirit-
|
|
4360
|
+
const { spiritDir } = await import("./spirit-IK5OYWMV.js");
|
|
4376
4361
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
4377
4362
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
4378
4363
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -4387,7 +4372,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4387
4372
|
});
|
|
4388
4373
|
spiritConfig.schedules = schedules;
|
|
4389
4374
|
writeVoluteConfig(sDir, spiritConfig);
|
|
4390
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
4375
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-CXWQ6Z4E.js");
|
|
4391
4376
|
getScheduler2().loadSchedules("volute", sDir);
|
|
4392
4377
|
}
|
|
4393
4378
|
}
|
|
@@ -4398,11 +4383,11 @@ The human who planted you described you as: "${body.description}"
|
|
|
4398
4383
|
if (body.stage !== "seed") {
|
|
4399
4384
|
const customSoul = await getPromptIfCustom("default_soul");
|
|
4400
4385
|
if (customSoul) {
|
|
4401
|
-
writeFileSync7(
|
|
4386
|
+
writeFileSync7(resolve10(dest, "home/SOUL.md"), customSoul.replace(/\{\{name\}\}/g, name));
|
|
4402
4387
|
}
|
|
4403
4388
|
const customMemory = await getPromptIfCustom("default_memory");
|
|
4404
4389
|
if (customMemory) {
|
|
4405
|
-
writeFileSync7(
|
|
4390
|
+
writeFileSync7(resolve10(dest, "home/MEMORY.md"), customMemory);
|
|
4406
4391
|
}
|
|
4407
4392
|
}
|
|
4408
4393
|
publishPublicKey(name, publicKeyPem).catch(
|
|
@@ -4451,12 +4436,12 @@ The human who planted you described you as: "${body.description}"
|
|
|
4451
4436
|
return importFromArchive(c, body.archivePath, body.name, body.manifest);
|
|
4452
4437
|
}
|
|
4453
4438
|
const wsDir = body.workspacePath;
|
|
4454
|
-
if (!wsDir || !existsSync7(
|
|
4439
|
+
if (!wsDir || !existsSync7(resolve10(wsDir, "SOUL.md")) || !existsSync7(resolve10(wsDir, "IDENTITY.md"))) {
|
|
4455
4440
|
return c.json({ error: "Invalid workspace: missing SOUL.md or IDENTITY.md" }, 400);
|
|
4456
4441
|
}
|
|
4457
|
-
const soul = readFileSync8(
|
|
4458
|
-
const identity = readFileSync8(
|
|
4459
|
-
const userPath =
|
|
4442
|
+
const soul = readFileSync8(resolve10(wsDir, "SOUL.md"), "utf-8");
|
|
4443
|
+
const identity = readFileSync8(resolve10(wsDir, "IDENTITY.md"), "utf-8");
|
|
4444
|
+
const userPath = resolve10(wsDir, "USER.md");
|
|
4460
4445
|
const user = existsSync7(userPath) ? readFileSync8(userPath, "utf-8") : "";
|
|
4461
4446
|
const name = body.name ?? parseNameFromIdentity(identity) ?? "imported-mind";
|
|
4462
4447
|
const template = body.template ?? "claude";
|
|
@@ -4484,26 +4469,26 @@ ${user.trimEnd()}
|
|
|
4484
4469
|
copyTemplateToDir(composedDir, dest, name, manifest);
|
|
4485
4470
|
applyInitFiles(dest);
|
|
4486
4471
|
const { publicKeyPem: importPublicKey } = generateIdentity(dest);
|
|
4487
|
-
writeFileSync7(
|
|
4488
|
-
const wsMemoryPath =
|
|
4472
|
+
writeFileSync7(resolve10(dest, "home/SOUL.md"), mergedSoul);
|
|
4473
|
+
const wsMemoryPath = resolve10(wsDir, "MEMORY.md");
|
|
4489
4474
|
const hasMemory = existsSync7(wsMemoryPath);
|
|
4490
4475
|
if (hasMemory) {
|
|
4491
4476
|
const existingMemory = readFileSync8(wsMemoryPath, "utf-8");
|
|
4492
4477
|
writeFileSync7(
|
|
4493
|
-
|
|
4478
|
+
resolve10(dest, "home/MEMORY.md"),
|
|
4494
4479
|
`${existingMemory.trimEnd()}${mergedMemoryExtra}`
|
|
4495
4480
|
);
|
|
4496
4481
|
} else if (user) {
|
|
4497
|
-
writeFileSync7(
|
|
4482
|
+
writeFileSync7(resolve10(dest, "home/MEMORY.md"), `${user.trimEnd()}
|
|
4498
4483
|
`);
|
|
4499
4484
|
}
|
|
4500
|
-
const wsMemoryDir =
|
|
4485
|
+
const wsMemoryDir = resolve10(wsDir, "memory");
|
|
4501
4486
|
let dailyLogCount = 0;
|
|
4502
4487
|
if (existsSync7(wsMemoryDir)) {
|
|
4503
|
-
const destMemoryDir =
|
|
4488
|
+
const destMemoryDir = resolve10(dest, "home/memory");
|
|
4504
4489
|
const files = readdirSync2(wsMemoryDir).filter((f) => f.endsWith(".md"));
|
|
4505
4490
|
for (const file of files) {
|
|
4506
|
-
cpSync(
|
|
4491
|
+
cpSync(resolve10(wsMemoryDir, file), resolve10(destMemoryDir, file));
|
|
4507
4492
|
}
|
|
4508
4493
|
dailyLogCount = files.length;
|
|
4509
4494
|
}
|
|
@@ -4514,7 +4499,7 @@ ${user.trimEnd()}
|
|
|
4514
4499
|
} catch (err) {
|
|
4515
4500
|
logger_default.warn(`failed to set template hash for ${name}`, logger_default.errorData(err));
|
|
4516
4501
|
}
|
|
4517
|
-
const homeDir =
|
|
4502
|
+
const homeDir = resolve10(dest, "home");
|
|
4518
4503
|
ensureVoluteGroup();
|
|
4519
4504
|
createMindUser(name, homeDir);
|
|
4520
4505
|
await chownMindDir(dest, name);
|
|
@@ -4522,20 +4507,20 @@ ${user.trimEnd()}
|
|
|
4522
4507
|
if (!hasMemory && dailyLogCount > 0) {
|
|
4523
4508
|
await consolidateMemory(dest);
|
|
4524
4509
|
}
|
|
4525
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
4510
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dest, "home") } : void 0;
|
|
4526
4511
|
await gitExec(["init"], { cwd: dest, mindName: name, env });
|
|
4527
4512
|
await configureGitIdentity(name, { cwd: dest, mindName: name, env });
|
|
4528
4513
|
await gitExec(["add", "-A"], { cwd: dest, mindName: name, env });
|
|
4529
4514
|
await gitExec(["commit", "-m", "import from OpenClaw"], { cwd: dest, mindName: name, env });
|
|
4530
|
-
const sessionFile = body.sessionPath ?
|
|
4515
|
+
const sessionFile = body.sessionPath ? resolve10(body.sessionPath) : findOpenClawSession(wsDir);
|
|
4531
4516
|
if (sessionFile && existsSync7(sessionFile)) {
|
|
4532
4517
|
if (template === "pi") {
|
|
4533
4518
|
importPiSession(sessionFile, dest);
|
|
4534
4519
|
} else if (template === "claude") {
|
|
4535
4520
|
const sessionId = convertSession({ sessionPath: sessionFile, projectDir: dest });
|
|
4536
|
-
const mindRuntimeDir =
|
|
4521
|
+
const mindRuntimeDir = resolve10(dest, ".mind");
|
|
4537
4522
|
mkdirSync6(mindRuntimeDir, { recursive: true });
|
|
4538
|
-
writeFileSync7(
|
|
4523
|
+
writeFileSync7(resolve10(mindRuntimeDir, "session.json"), JSON.stringify({ sessionId }));
|
|
4539
4524
|
}
|
|
4540
4525
|
}
|
|
4541
4526
|
importOpenClawConnectors(name, dest);
|
|
@@ -4576,7 +4561,7 @@ ${user.trimEnd()}
|
|
|
4576
4561
|
const minds = await Promise.all(
|
|
4577
4562
|
entries.map(async (entry) => {
|
|
4578
4563
|
const mindStatus = await getMindStatus(entry.name, entry.port, entry.running);
|
|
4579
|
-
const hasPages = existsSync7(
|
|
4564
|
+
const hasPages = existsSync7(resolve10(mindDir(entry.name), "home", "pages"));
|
|
4580
4565
|
return {
|
|
4581
4566
|
...entry,
|
|
4582
4567
|
...mindStatus,
|
|
@@ -4605,7 +4590,7 @@ ${user.trimEnd()}
|
|
|
4605
4590
|
return { name: s.name, port: s.port, status: variantStatus };
|
|
4606
4591
|
})
|
|
4607
4592
|
);
|
|
4608
|
-
const hasPages = existsSync7(
|
|
4593
|
+
const hasPages = existsSync7(resolve10(mindDir(name), "home", "pages"));
|
|
4609
4594
|
return c.json({ ...entry, ...mindStatus, variants: variantStatuses, hasPages });
|
|
4610
4595
|
}).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) => {
|
|
4611
4596
|
const name = c.req.param("name");
|
|
@@ -4652,7 +4637,7 @@ ${user.trimEnd()}
|
|
|
4652
4637
|
const manager = getMindManager();
|
|
4653
4638
|
try {
|
|
4654
4639
|
if (context?.type === "reload") {
|
|
4655
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4640
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
|
|
4656
4641
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
4657
4642
|
if (sleepState?.sleeping) {
|
|
4658
4643
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -4779,7 +4764,7 @@ ${user.trimEnd()}
|
|
|
4779
4764
|
const name = c.req.param("name");
|
|
4780
4765
|
const entry = await findMind(name);
|
|
4781
4766
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4782
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4767
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
|
|
4783
4768
|
const sm = getSleepManagerIfReady2();
|
|
4784
4769
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4785
4770
|
return c.json(sm.getState(name));
|
|
@@ -4787,7 +4772,7 @@ ${user.trimEnd()}
|
|
|
4787
4772
|
const name = c.req.param("name");
|
|
4788
4773
|
const entry = await findMind(name);
|
|
4789
4774
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4790
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4775
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
|
|
4791
4776
|
const sm = getSleepManagerIfReady2();
|
|
4792
4777
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4793
4778
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -4807,7 +4792,7 @@ ${user.trimEnd()}
|
|
|
4807
4792
|
const name = c.req.param("name");
|
|
4808
4793
|
const entry = await findMind(name);
|
|
4809
4794
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4810
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4795
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
|
|
4811
4796
|
const sm = getSleepManagerIfReady2();
|
|
4812
4797
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4813
4798
|
const sleepState = sm.getState(name);
|
|
@@ -4822,7 +4807,7 @@ ${user.trimEnd()}
|
|
|
4822
4807
|
const name = c.req.param("name");
|
|
4823
4808
|
const entry = await findMind(name);
|
|
4824
4809
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4825
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4810
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-HINI6Y46.js");
|
|
4826
4811
|
const sm = getSleepManagerIfReady2();
|
|
4827
4812
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4828
4813
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -4840,7 +4825,7 @@ ${user.trimEnd()}
|
|
|
4840
4825
|
if (body.avatar !== void 0) profile.avatar = basename(body.avatar);
|
|
4841
4826
|
config2.profile = profile;
|
|
4842
4827
|
writeVoluteConfig(dir, config2);
|
|
4843
|
-
const { syncMindProfile: syncMindProfile2 } = await import("./auth-
|
|
4828
|
+
const { syncMindProfile: syncMindProfile2 } = await import("./auth-FRZJVQCS.js");
|
|
4844
4829
|
await syncMindProfile2(name, profile);
|
|
4845
4830
|
broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
|
|
4846
4831
|
return c.json({ ok: true });
|
|
@@ -4880,14 +4865,14 @@ ${user.trimEnd()}
|
|
|
4880
4865
|
return c.json({ output: "" });
|
|
4881
4866
|
}
|
|
4882
4867
|
const dir = entry.dir ?? mindDir(name);
|
|
4883
|
-
const soulPath =
|
|
4884
|
-
const memoryPath =
|
|
4868
|
+
const soulPath = resolve10(dir, "home/SOUL.md");
|
|
4869
|
+
const memoryPath = resolve10(dir, "home/MEMORY.md");
|
|
4885
4870
|
const soulCustom = existsSync7(soulPath) && !readFileSync8(soulPath, "utf-8").includes(ORIENTATION_MARKER);
|
|
4886
4871
|
const memoryWritten = existsSync7(memoryPath) && readFileSync8(memoryPath, "utf-8").trim().length > 0;
|
|
4887
4872
|
const config2 = readVoluteConfig(dir);
|
|
4888
4873
|
const displayNameSet = !!config2?.profile?.displayName;
|
|
4889
4874
|
const avatarSet = !!config2?.profile?.avatar;
|
|
4890
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
4875
|
+
const { isImagegenEnabled } = await import("./setup-MLRKNP7Y.js");
|
|
4891
4876
|
const imagegenEnabled = isImagegenEnabled();
|
|
4892
4877
|
const done = [];
|
|
4893
4878
|
const remaining = [];
|
|
@@ -4925,7 +4910,7 @@ ${user.trimEnd()}
|
|
|
4925
4910
|
try {
|
|
4926
4911
|
const spiritEntry = await findMind("volute");
|
|
4927
4912
|
if (spiritEntry) {
|
|
4928
|
-
const { spiritDir } = await import("./spirit-
|
|
4913
|
+
const { spiritDir } = await import("./spirit-IK5OYWMV.js");
|
|
4929
4914
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
4930
4915
|
const spiritConfig = readVoluteConfig(sDir);
|
|
4931
4916
|
if (spiritConfig?.schedules) {
|
|
@@ -4933,7 +4918,7 @@ ${user.trimEnd()}
|
|
|
4933
4918
|
spiritConfig.schedules = spiritConfig.schedules.filter((s) => s.id !== nurtureId);
|
|
4934
4919
|
if (spiritConfig.schedules.length === 0) spiritConfig.schedules = void 0;
|
|
4935
4920
|
writeVoluteConfig(sDir, spiritConfig);
|
|
4936
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
4921
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-CXWQ6Z4E.js");
|
|
4937
4922
|
getScheduler2().loadSchedules("volute", sDir);
|
|
4938
4923
|
}
|
|
4939
4924
|
}
|
|
@@ -4992,16 +4977,16 @@ ${user.trimEnd()}
|
|
|
4992
4977
|
}
|
|
4993
4978
|
const UPGRADE_BRANCH = "upgrade";
|
|
4994
4979
|
const upgradeVariantName = `${mindName}-upgrade`;
|
|
4995
|
-
const worktreeDir =
|
|
4980
|
+
const worktreeDir = resolve10(dir, ".variants", UPGRADE_BRANCH);
|
|
4996
4981
|
if (body.abort) {
|
|
4997
4982
|
if (!existsSync7(worktreeDir)) {
|
|
4998
4983
|
return c.json({ error: "No upgrade in progress" }, 400);
|
|
4999
4984
|
}
|
|
5000
4985
|
try {
|
|
5001
4986
|
try {
|
|
5002
|
-
const gitDirContent = readFileSync8(
|
|
4987
|
+
const gitDirContent = readFileSync8(resolve10(worktreeDir, ".git"), "utf-8").trim();
|
|
5003
4988
|
const gitDir = gitDirContent.replace("gitdir: ", "");
|
|
5004
|
-
if (existsSync7(
|
|
4989
|
+
if (existsSync7(resolve10(gitDir, "MERGE_HEAD"))) {
|
|
5005
4990
|
await gitExec(["merge", "--abort"], { cwd: worktreeDir });
|
|
5006
4991
|
}
|
|
5007
4992
|
} catch {
|
|
@@ -5085,7 +5070,7 @@ ${user.trimEnd()}
|
|
|
5085
5070
|
}
|
|
5086
5071
|
if (body.diff) {
|
|
5087
5072
|
try {
|
|
5088
|
-
if (!existsSync7(
|
|
5073
|
+
if (!existsSync7(resolve10(dir, ".git"))) {
|
|
5089
5074
|
return c.json({ error: "Mind has no git history \u2014 nothing to diff against" }, 400);
|
|
5090
5075
|
}
|
|
5091
5076
|
await updateTemplateBranch(dir, template, mindName);
|
|
@@ -5109,16 +5094,16 @@ ${user.trimEnd()}
|
|
|
5109
5094
|
409
|
|
5110
5095
|
);
|
|
5111
5096
|
}
|
|
5112
|
-
if (!existsSync7(
|
|
5097
|
+
if (!existsSync7(resolve10(dir, ".git"))) {
|
|
5113
5098
|
try {
|
|
5114
|
-
const env = isIsolationEnabled() ? { ...process.env, HOME:
|
|
5099
|
+
const env = isIsolationEnabled() ? { ...process.env, HOME: resolve10(dir, "home") } : void 0;
|
|
5115
5100
|
await gitExec(["init"], { cwd: dir, mindName, env });
|
|
5116
5101
|
await configureGitIdentity(mindName, { cwd: dir, mindName, env });
|
|
5117
5102
|
await gitExec(["add", "-A"], { cwd: dir, mindName, env });
|
|
5118
5103
|
await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
|
|
5119
5104
|
await chownMindDir(dir, mindName);
|
|
5120
5105
|
} catch (err) {
|
|
5121
|
-
rmSync4(
|
|
5106
|
+
rmSync4(resolve10(dir, ".git"), { recursive: true, force: true });
|
|
5122
5107
|
return c.json(
|
|
5123
5108
|
{
|
|
5124
5109
|
error: `Git initialization failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -5133,7 +5118,7 @@ ${user.trimEnd()}
|
|
|
5133
5118
|
} catch {
|
|
5134
5119
|
}
|
|
5135
5120
|
await updateTemplateBranch(dir, template, mindName);
|
|
5136
|
-
const parentDir =
|
|
5121
|
+
const parentDir = resolve10(dir, ".variants");
|
|
5137
5122
|
if (!existsSync7(parentDir)) {
|
|
5138
5123
|
mkdirSync6(parentDir, { recursive: true });
|
|
5139
5124
|
}
|
|
@@ -5267,7 +5252,7 @@ ${user.trimEnd()}
|
|
|
5267
5252
|
if (!existsSync7(dir)) return c.json({ error: "Mind directory missing" }, 404);
|
|
5268
5253
|
let config2 = readVoluteConfig(dir);
|
|
5269
5254
|
if (!config2 && entry.template === "pi") {
|
|
5270
|
-
const piConfigPath =
|
|
5255
|
+
const piConfigPath = resolve10(dir, "home/.config/config.json");
|
|
5271
5256
|
if (existsSync7(piConfigPath)) {
|
|
5272
5257
|
try {
|
|
5273
5258
|
config2 = JSON.parse(readFileSync8(piConfigPath, "utf-8"));
|
|
@@ -5276,7 +5261,7 @@ ${user.trimEnd()}
|
|
|
5276
5261
|
}
|
|
5277
5262
|
}
|
|
5278
5263
|
let templateConfig = {};
|
|
5279
|
-
const configJsonPath =
|
|
5264
|
+
const configJsonPath = resolve10(dir, "home/.config/config.json");
|
|
5280
5265
|
if (existsSync7(configJsonPath)) {
|
|
5281
5266
|
try {
|
|
5282
5267
|
templateConfig = JSON.parse(readFileSync8(configJsonPath, "utf-8"));
|
|
@@ -5368,12 +5353,12 @@ ${user.trimEnd()}
|
|
|
5368
5353
|
}
|
|
5369
5354
|
writeVoluteConfig(dir, existing);
|
|
5370
5355
|
if (body.unescapeNewlines !== void 0) {
|
|
5371
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
5356
|
+
const { clearEchoTextCache } = await import("./echo-text-T7ZA5EYD.js");
|
|
5372
5357
|
clearEchoTextCache(name);
|
|
5373
5358
|
}
|
|
5374
5359
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.maxThinkingTokens !== void 0 || body.compaction !== void 0;
|
|
5375
5360
|
if (needsConfigJson) {
|
|
5376
|
-
const configJsonPath =
|
|
5361
|
+
const configJsonPath = resolve10(dir, "home/.config/config.json");
|
|
5377
5362
|
let templateConfig = {};
|
|
5378
5363
|
if (existsSync7(configJsonPath)) {
|
|
5379
5364
|
try {
|
|
@@ -5445,7 +5430,7 @@ ${user.trimEnd()}
|
|
|
5445
5430
|
}
|
|
5446
5431
|
if (entry.mindType === "spirit" && body.model !== void 0) {
|
|
5447
5432
|
try {
|
|
5448
|
-
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-
|
|
5433
|
+
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-MLRKNP7Y.js");
|
|
5449
5434
|
const globalConfig = readGlobalConfig2();
|
|
5450
5435
|
globalConfig.spiritModel = body.model;
|
|
5451
5436
|
writeGlobalConfig2(globalConfig);
|
|
@@ -5473,7 +5458,7 @@ ${user.trimEnd()}
|
|
|
5473
5458
|
if (!body.systemPrompt || !body.message) {
|
|
5474
5459
|
return c.json({ error: "systemPrompt and message required" }, 400);
|
|
5475
5460
|
}
|
|
5476
|
-
const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-
|
|
5461
|
+
const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-7PHSRDMO.js");
|
|
5477
5462
|
if (!isAiConfigured()) {
|
|
5478
5463
|
return c.json({ error: "AI service not configured" }, 503);
|
|
5479
5464
|
}
|
|
@@ -6058,7 +6043,7 @@ var app15 = new Hono17().get("/:name/clock/status", requireSelf(), async (c) =>
|
|
|
6058
6043
|
const body = await c.req.text();
|
|
6059
6044
|
const message = `[webhook: ${event}] ${body}`;
|
|
6060
6045
|
try {
|
|
6061
|
-
const { sendSystemMessage } = await import("./system-chat-
|
|
6046
|
+
const { sendSystemMessage } = await import("./system-chat-4DQZOEZI.js");
|
|
6062
6047
|
await sendSystemMessage(name, message);
|
|
6063
6048
|
return c.json({ ok: true });
|
|
6064
6049
|
} catch (err) {
|
|
@@ -6071,14 +6056,14 @@ var schedules_default = app15;
|
|
|
6071
6056
|
// packages/daemon/src/web/api/setup.ts
|
|
6072
6057
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
6073
6058
|
import { homedir as homedir2 } from "os";
|
|
6074
|
-
import { resolve as
|
|
6059
|
+
import { resolve as resolve11 } from "path";
|
|
6075
6060
|
import { Hono as Hono18 } from "hono";
|
|
6076
6061
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
6077
6062
|
var DEFAULT_API_URL2 = "https://volute.systems";
|
|
6078
6063
|
var setup = new Hono18();
|
|
6079
6064
|
function writeSetupConfig(systemName, description) {
|
|
6080
|
-
const configHome = process.env.VOLUTE_HOME ??
|
|
6081
|
-
const mindsDir =
|
|
6065
|
+
const configHome = process.env.VOLUTE_HOME ?? resolve11(homedir2(), ".volute");
|
|
6066
|
+
const mindsDir = resolve11(configHome, "minds");
|
|
6082
6067
|
mkdirSync7(configHome, { recursive: true });
|
|
6083
6068
|
mkdirSync7(mindsDir, { recursive: true });
|
|
6084
6069
|
const existingConfig = readGlobalConfig();
|
|
@@ -6112,7 +6097,7 @@ setup.get("/status", async (c) => {
|
|
|
6112
6097
|
let hasAccount = false;
|
|
6113
6098
|
if (hasSystem) {
|
|
6114
6099
|
try {
|
|
6115
|
-
const { listUsersByType: listUsersByType2 } = await import("./auth-
|
|
6100
|
+
const { listUsersByType: listUsersByType2 } = await import("./auth-FRZJVQCS.js");
|
|
6116
6101
|
const brains = await listUsersByType2("brain");
|
|
6117
6102
|
hasAccount = brains.length > 0;
|
|
6118
6103
|
} catch (err) {
|
|
@@ -6323,7 +6308,7 @@ setup.post("/account", async (c) => {
|
|
|
6323
6308
|
}
|
|
6324
6309
|
}
|
|
6325
6310
|
try {
|
|
6326
|
-
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-
|
|
6311
|
+
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-FRZJVQCS.js");
|
|
6327
6312
|
const user = await createUser2(body.username.trim(), body.password);
|
|
6328
6313
|
if (body.displayName?.trim()) {
|
|
6329
6314
|
await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
|
|
@@ -6369,7 +6354,7 @@ setup.post("/models", async (c) => {
|
|
|
6369
6354
|
return c.json({ error: "Spirit model is required" }, 400);
|
|
6370
6355
|
}
|
|
6371
6356
|
try {
|
|
6372
|
-
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-
|
|
6357
|
+
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-7PHSRDMO.js");
|
|
6373
6358
|
setEnabledModels3(body.models);
|
|
6374
6359
|
const config2 = readGlobalConfig();
|
|
6375
6360
|
config2.spiritModel = body.spiritModel.trim();
|
|
@@ -6387,15 +6372,15 @@ setup.post("/complete", async (c) => {
|
|
|
6387
6372
|
return c.json({ error: "Setup already complete" }, 400);
|
|
6388
6373
|
}
|
|
6389
6374
|
try {
|
|
6390
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
6391
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
6375
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-IK5OYWMV.js");
|
|
6376
|
+
const { startSpiritFull } = await import("./mind-service-S3SY7HAM.js");
|
|
6392
6377
|
await ensureSpiritProject();
|
|
6393
6378
|
await syncSpiritTemplate();
|
|
6394
6379
|
const warnings = [];
|
|
6395
6380
|
const config2 = readGlobalConfig();
|
|
6396
6381
|
if (config2.setup?.service && config2.setup?.type === "local") {
|
|
6397
6382
|
try {
|
|
6398
|
-
const { installUserService } = await import("./service-install-
|
|
6383
|
+
const { installUserService } = await import("./service-install-4QNUDKLM.js");
|
|
6399
6384
|
const installed = await installUserService(config2.port, config2.hostname);
|
|
6400
6385
|
if (!installed) {
|
|
6401
6386
|
warnings.push("Service installation is not supported on this platform.");
|
|
@@ -6423,8 +6408,8 @@ setup.post("/complete", async (c) => {
|
|
|
6423
6408
|
}
|
|
6424
6409
|
let spiritConversationId;
|
|
6425
6410
|
try {
|
|
6426
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-
|
|
6427
|
-
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-
|
|
6411
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-FRZJVQCS.js");
|
|
6412
|
+
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-WAJYZKOC.js");
|
|
6428
6413
|
const spiritUser = await getOrCreateMindUser2("volute");
|
|
6429
6414
|
const brains = await listUsersByType2("brain");
|
|
6430
6415
|
const admin2 = brains.find((u) => u.role === "admin");
|
|
@@ -6446,8 +6431,8 @@ setup.post("/complete", async (c) => {
|
|
|
6446
6431
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
6447
6432
|
if (spiritConversationId && spiritStarted) {
|
|
6448
6433
|
try {
|
|
6449
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
6450
|
-
const { listUsersByType: listUsers2 } = await import("./auth-
|
|
6434
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-2EA5LLMD.js");
|
|
6435
|
+
const { listUsersByType: listUsers2 } = await import("./auth-FRZJVQCS.js");
|
|
6451
6436
|
const admins = await listUsers2("brain");
|
|
6452
6437
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
6453
6438
|
const adminName = admin2?.display_name || admin2?.username || "the admin";
|
|
@@ -6486,7 +6471,7 @@ var setup_default = setup;
|
|
|
6486
6471
|
// packages/daemon/src/web/api/skills.ts
|
|
6487
6472
|
import { existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
|
|
6488
6473
|
import { tmpdir } from "os";
|
|
6489
|
-
import { join, resolve as
|
|
6474
|
+
import { join, resolve as resolve12 } from "path";
|
|
6490
6475
|
import AdmZip from "adm-zip";
|
|
6491
6476
|
import { Hono as Hono19 } from "hono";
|
|
6492
6477
|
var app16 = new Hono19().get("/", async (c) => {
|
|
@@ -6562,7 +6547,7 @@ var app16 = new Hono19().get("/", async (c) => {
|
|
|
6562
6547
|
try {
|
|
6563
6548
|
const zip = new AdmZip(buffer2);
|
|
6564
6549
|
for (const entry of zip.getEntries()) {
|
|
6565
|
-
const target =
|
|
6550
|
+
const target = resolve12(tmpDir, entry.entryName);
|
|
6566
6551
|
if (!target.startsWith(tmpDir)) {
|
|
6567
6552
|
return c.json({ error: "Invalid zip: paths must not escape archive" }, 400);
|
|
6568
6553
|
}
|
|
@@ -6924,8 +6909,8 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
|
|
|
6924
6909
|
});
|
|
6925
6910
|
}, 15e3);
|
|
6926
6911
|
cleanups.push(() => clearInterval(keepAlive));
|
|
6927
|
-
await new Promise((
|
|
6928
|
-
stream.onAbort(() =>
|
|
6912
|
+
await new Promise((resolve17) => {
|
|
6913
|
+
stream.onAbort(() => resolve17());
|
|
6929
6914
|
});
|
|
6930
6915
|
} finally {
|
|
6931
6916
|
for (const cleanup of cleanups) {
|
|
@@ -6941,15 +6926,15 @@ var events_default = app20;
|
|
|
6941
6926
|
|
|
6942
6927
|
// packages/daemon/src/web/api/variants.ts
|
|
6943
6928
|
import { existsSync as existsSync9, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
6944
|
-
import { resolve as
|
|
6929
|
+
import { resolve as resolve14 } from "path";
|
|
6945
6930
|
import { Hono as Hono24 } from "hono";
|
|
6946
6931
|
|
|
6947
6932
|
// packages/daemon/src/lib/mind/spawn-server.ts
|
|
6948
6933
|
import { spawn as spawn4 } from "child_process";
|
|
6949
6934
|
import { closeSync, mkdirSync as mkdirSync8, openSync, readFileSync as readFileSync9 } from "fs";
|
|
6950
|
-
import { resolve as
|
|
6935
|
+
import { resolve as resolve13 } from "path";
|
|
6951
6936
|
function tsxBin(cwd) {
|
|
6952
|
-
return
|
|
6937
|
+
return resolve13(cwd, "node_modules", ".bin", "tsx");
|
|
6953
6938
|
}
|
|
6954
6939
|
async function spawnServer(cwd, port, options) {
|
|
6955
6940
|
let cmd = tsxBin(cwd);
|
|
@@ -6971,31 +6956,31 @@ function spawnAttached(cmd, args, cwd) {
|
|
|
6971
6956
|
cwd,
|
|
6972
6957
|
stdio: ["ignore", "pipe", "pipe"]
|
|
6973
6958
|
});
|
|
6974
|
-
return new Promise((
|
|
6975
|
-
const timeout = setTimeout(() =>
|
|
6959
|
+
return new Promise((resolve17) => {
|
|
6960
|
+
const timeout = setTimeout(() => resolve17(null), 3e4);
|
|
6976
6961
|
function checkOutput(data) {
|
|
6977
6962
|
const match = data.toString().match(/listening on :(\d+)/);
|
|
6978
6963
|
if (match) {
|
|
6979
6964
|
clearTimeout(timeout);
|
|
6980
|
-
|
|
6965
|
+
resolve17({ child, actualPort: parseInt(match[1], 10) });
|
|
6981
6966
|
}
|
|
6982
6967
|
}
|
|
6983
6968
|
child.stdout?.on("data", checkOutput);
|
|
6984
6969
|
child.stderr?.on("data", checkOutput);
|
|
6985
6970
|
child.on("error", () => {
|
|
6986
6971
|
clearTimeout(timeout);
|
|
6987
|
-
|
|
6972
|
+
resolve17(null);
|
|
6988
6973
|
});
|
|
6989
6974
|
child.on("exit", () => {
|
|
6990
6975
|
clearTimeout(timeout);
|
|
6991
|
-
|
|
6976
|
+
resolve17(null);
|
|
6992
6977
|
});
|
|
6993
6978
|
});
|
|
6994
6979
|
}
|
|
6995
6980
|
function spawnDetached(cmd, args, cwd, logDir) {
|
|
6996
|
-
const logsDir = logDir ??
|
|
6981
|
+
const logsDir = logDir ?? resolve13(cwd, ".mind", "logs");
|
|
6997
6982
|
mkdirSync8(logsDir, { recursive: true });
|
|
6998
|
-
const logPath =
|
|
6983
|
+
const logPath = resolve13(logsDir, "mind.log");
|
|
6999
6984
|
const logFd = openSync(logPath, "a");
|
|
7000
6985
|
const child = spawn4(cmd, args, {
|
|
7001
6986
|
cwd,
|
|
@@ -7111,11 +7096,11 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7111
7096
|
return c.json({ error: `Name already in use: ${variantName}` }, 409);
|
|
7112
7097
|
}
|
|
7113
7098
|
const projectRoot = mindDir(mindName);
|
|
7114
|
-
const variantDir =
|
|
7099
|
+
const variantDir = resolve14(projectRoot, ".variants", variantName);
|
|
7115
7100
|
if (existsSync9(variantDir)) {
|
|
7116
7101
|
return c.json({ error: `Variant directory already exists: ${variantDir}` }, 409);
|
|
7117
7102
|
}
|
|
7118
|
-
mkdirSync9(
|
|
7103
|
+
mkdirSync9(resolve14(projectRoot, ".variants"), { recursive: true });
|
|
7119
7104
|
try {
|
|
7120
7105
|
await gitExec(["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
|
|
7121
7106
|
} catch (e) {
|
|
@@ -7128,7 +7113,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7128
7113
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
7129
7114
|
await exec(cmd, args, {
|
|
7130
7115
|
cwd: variantDir,
|
|
7131
|
-
env: { ...process.env, HOME:
|
|
7116
|
+
env: { ...process.env, HOME: resolve14(variantDir, "home") }
|
|
7132
7117
|
});
|
|
7133
7118
|
} else {
|
|
7134
7119
|
await exec("npm", ["install"], { cwd: variantDir });
|
|
@@ -7138,7 +7123,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7138
7123
|
return c.json({ error: `npm install failed: ${msg}` }, 500);
|
|
7139
7124
|
}
|
|
7140
7125
|
if (body.soul) {
|
|
7141
|
-
writeFileSync8(
|
|
7126
|
+
writeFileSync8(resolve14(variantDir, "home/SOUL.md"), body.soul);
|
|
7142
7127
|
}
|
|
7143
7128
|
const variantPort = body.port ?? await nextPort();
|
|
7144
7129
|
await addVariant(variantName, mindName, variantPort, variantDir, variantName);
|
|
@@ -7238,7 +7223,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7238
7223
|
if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
|
|
7239
7224
|
try {
|
|
7240
7225
|
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-446HHH5V.js");
|
|
7241
|
-
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-
|
|
7226
|
+
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-NUJAGLQJ.js");
|
|
7242
7227
|
const tmpl = parentEntry.template ?? "claude";
|
|
7243
7228
|
await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
|
|
7244
7229
|
} catch (err) {
|
|
@@ -7251,7 +7236,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7251
7236
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
7252
7237
|
await exec(cmd, args, {
|
|
7253
7238
|
cwd: projectRoot,
|
|
7254
|
-
env: { ...process.env, HOME:
|
|
7239
|
+
env: { ...process.env, HOME: resolve14(projectRoot, "home") }
|
|
7255
7240
|
});
|
|
7256
7241
|
} else {
|
|
7257
7242
|
await exec("npm", ["install"], { cwd: projectRoot });
|
|
@@ -7579,6 +7564,19 @@ var unifiedChatApp = new Hono26().post(
|
|
|
7579
7564
|
senderBase = await getBaseName(senderName);
|
|
7580
7565
|
outboundTurnId = getActiveTurnId(senderBase, c.get("mindSession"));
|
|
7581
7566
|
}
|
|
7567
|
+
if (senderIsMind && senderBase) {
|
|
7568
|
+
const gate = await checkStaleSend(senderBase, conversationId, [senderName, senderBase]);
|
|
7569
|
+
if (gate.held && gate.unseen) {
|
|
7570
|
+
const label = buildVoluteSlug({
|
|
7571
|
+
participants,
|
|
7572
|
+
mindUsername: senderName,
|
|
7573
|
+
conversationId,
|
|
7574
|
+
convType: conv.type,
|
|
7575
|
+
convName
|
|
7576
|
+
});
|
|
7577
|
+
return c.json({ ok: true, held: true, notice: formatHoldNotice(label, gate.unseen) });
|
|
7578
|
+
}
|
|
7579
|
+
}
|
|
7582
7580
|
const message = await addMessage(conversationId, "user", senderName, contentBlocks, {
|
|
7583
7581
|
turnId: outboundTurnId
|
|
7584
7582
|
});
|
|
@@ -7619,7 +7617,6 @@ var unifiedChatApp = new Hono26().post(
|
|
|
7619
7617
|
conversationId,
|
|
7620
7618
|
contentBlocks,
|
|
7621
7619
|
senderName,
|
|
7622
|
-
senderIsMind: !!senderIsMind,
|
|
7623
7620
|
participants,
|
|
7624
7621
|
isDM,
|
|
7625
7622
|
slugExtra: { convType: conv.type, convName },
|
|
@@ -7655,11 +7652,11 @@ var app23 = new Hono26().get("/:name/conversations/:id/events", async (c) => {
|
|
|
7655
7652
|
if (!stream.aborted) console.error("[chat] SSE ping error:", err);
|
|
7656
7653
|
});
|
|
7657
7654
|
}, 15e3);
|
|
7658
|
-
await new Promise((
|
|
7655
|
+
await new Promise((resolve17) => {
|
|
7659
7656
|
stream.onAbort(() => {
|
|
7660
7657
|
unsubscribe();
|
|
7661
7658
|
clearInterval(keepAlive);
|
|
7662
|
-
|
|
7659
|
+
resolve17();
|
|
7663
7660
|
});
|
|
7664
7661
|
});
|
|
7665
7662
|
});
|
|
@@ -7872,7 +7869,7 @@ var app_default = app25;
|
|
|
7872
7869
|
import { existsSync as existsSync10 } from "fs";
|
|
7873
7870
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
7874
7871
|
import { createServer as createHttpsServer } from "https";
|
|
7875
|
-
import { dirname as dirname2, extname as extname3, resolve as
|
|
7872
|
+
import { dirname as dirname2, extname as extname3, resolve as resolve15 } from "path";
|
|
7876
7873
|
import { serve } from "@hono/node-server";
|
|
7877
7874
|
var MIME_TYPES2 = {
|
|
7878
7875
|
".html": "text/html",
|
|
@@ -7891,7 +7888,7 @@ async function startServer({
|
|
|
7891
7888
|
let assetsDir = "";
|
|
7892
7889
|
let searchDir = dirname2(new URL(import.meta.url).pathname);
|
|
7893
7890
|
for (let i = 0; i < 5; i++) {
|
|
7894
|
-
const candidate =
|
|
7891
|
+
const candidate = resolve15(searchDir, "dist", "web-assets");
|
|
7895
7892
|
if (existsSync10(candidate)) {
|
|
7896
7893
|
assetsDir = candidate;
|
|
7897
7894
|
break;
|
|
@@ -7902,7 +7899,7 @@ async function startServer({
|
|
|
7902
7899
|
app_default.get("*", async (c) => {
|
|
7903
7900
|
const urlPath = new URL(c.req.url).pathname;
|
|
7904
7901
|
if (urlPath.startsWith("/api/") || urlPath.startsWith("/ext/")) return c.notFound();
|
|
7905
|
-
const filePath =
|
|
7902
|
+
const filePath = resolve15(assetsDir, urlPath.slice(1));
|
|
7906
7903
|
if (!filePath.startsWith(assetsDir)) return c.text("Forbidden", 403);
|
|
7907
7904
|
const s = await stat2(filePath).catch(() => null);
|
|
7908
7905
|
if (s?.isFile()) {
|
|
@@ -7915,7 +7912,7 @@ async function startServer({
|
|
|
7915
7912
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
7916
7913
|
return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
|
|
7917
7914
|
}
|
|
7918
|
-
const indexPath =
|
|
7915
|
+
const indexPath = resolve15(assetsDir, "index.html");
|
|
7919
7916
|
const indexStat = await stat2(indexPath).catch(() => null);
|
|
7920
7917
|
if (indexStat?.isFile()) {
|
|
7921
7918
|
const body = await readFile2(indexPath, "utf-8");
|
|
@@ -7932,10 +7929,10 @@ async function startServer({
|
|
|
7932
7929
|
createServer: createHttpsServer,
|
|
7933
7930
|
serverOptions: { key: tls.key, cert: tls.cert }
|
|
7934
7931
|
});
|
|
7935
|
-
await new Promise((
|
|
7932
|
+
await new Promise((resolve17, reject) => {
|
|
7936
7933
|
server2.on("listening", () => {
|
|
7937
7934
|
logger_default.info("Volute UI running (https)", { hostname, port });
|
|
7938
|
-
|
|
7935
|
+
resolve17();
|
|
7939
7936
|
});
|
|
7940
7937
|
server2.on("error", (err) => {
|
|
7941
7938
|
reject(err);
|
|
@@ -7943,13 +7940,13 @@ async function startServer({
|
|
|
7943
7940
|
});
|
|
7944
7941
|
const internalPort = port + 1;
|
|
7945
7942
|
const internalServer = serve({ fetch: app_default.fetch, port: internalPort, hostname: "127.0.0.1" });
|
|
7946
|
-
await new Promise((
|
|
7943
|
+
await new Promise((resolve17, reject) => {
|
|
7947
7944
|
internalServer.on("listening", () => {
|
|
7948
7945
|
logger_default.info("Volute API running (http, internal)", {
|
|
7949
7946
|
hostname: "127.0.0.1",
|
|
7950
7947
|
port: internalPort
|
|
7951
7948
|
});
|
|
7952
|
-
|
|
7949
|
+
resolve17();
|
|
7953
7950
|
});
|
|
7954
7951
|
internalServer.on("error", (err) => {
|
|
7955
7952
|
reject(err);
|
|
@@ -7958,10 +7955,10 @@ async function startServer({
|
|
|
7958
7955
|
return { server: server2, internalPort };
|
|
7959
7956
|
}
|
|
7960
7957
|
const server = serve({ fetch: app_default.fetch, port, hostname });
|
|
7961
|
-
await new Promise((
|
|
7958
|
+
await new Promise((resolve17, reject) => {
|
|
7962
7959
|
server.on("listening", () => {
|
|
7963
7960
|
logger_default.info("Volute API running (http)", { hostname, port });
|
|
7964
|
-
|
|
7961
|
+
resolve17();
|
|
7965
7962
|
});
|
|
7966
7963
|
server.on("error", (err) => {
|
|
7967
7964
|
reject(err);
|
|
@@ -7972,17 +7969,17 @@ async function startServer({
|
|
|
7972
7969
|
|
|
7973
7970
|
// packages/daemon/src/daemon.ts
|
|
7974
7971
|
if (!process.env.VOLUTE_HOME) {
|
|
7975
|
-
process.env.VOLUTE_HOME =
|
|
7972
|
+
process.env.VOLUTE_HOME = resolve16(homedir3(), ".volute");
|
|
7976
7973
|
}
|
|
7977
7974
|
if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
|
|
7978
7975
|
process.env.TZ = process.env.VOLUTE_TIMEZONE;
|
|
7979
7976
|
}
|
|
7980
7977
|
function writeDaemonConfig(systemDir, config2, token) {
|
|
7981
|
-
const configPath =
|
|
7978
|
+
const configPath = resolve16(systemDir, "daemon.json");
|
|
7982
7979
|
writeFileSync9(configPath, `${JSON.stringify(config2, null, 2)}
|
|
7983
7980
|
`, { mode: 420 });
|
|
7984
7981
|
chmodSync(configPath, 420);
|
|
7985
|
-
const tokenPath =
|
|
7982
|
+
const tokenPath = resolve16(systemDir, "daemon-token");
|
|
7986
7983
|
writeFileSync9(tokenPath, `${token}
|
|
7987
7984
|
`, { mode: 384 });
|
|
7988
7985
|
chmodSync(tokenPath, 384);
|
|
@@ -7993,7 +7990,7 @@ async function startDaemon(opts) {
|
|
|
7993
7990
|
const home = voluteHome();
|
|
7994
7991
|
const systemDir = voluteSystemDir();
|
|
7995
7992
|
if (!opts.foreground) {
|
|
7996
|
-
const rotatingLog = new RotatingLog(
|
|
7993
|
+
const rotatingLog = new RotatingLog(resolve16(systemDir, "daemon.log"));
|
|
7997
7994
|
logger_default.setOutput((line) => rotatingLog.write(`${line}
|
|
7998
7995
|
`));
|
|
7999
7996
|
const write = (...args) => rotatingLog.write(`${format(...args)}
|
|
@@ -8003,26 +8000,32 @@ async function startDaemon(opts) {
|
|
|
8003
8000
|
console.warn = write;
|
|
8004
8001
|
console.info = write;
|
|
8005
8002
|
}
|
|
8006
|
-
const DAEMON_PID_PATH =
|
|
8007
|
-
const DAEMON_JSON_PATH =
|
|
8008
|
-
const DAEMON_TOKEN_PATH =
|
|
8003
|
+
const DAEMON_PID_PATH = resolve16(systemDir, "daemon.pid");
|
|
8004
|
+
const DAEMON_JSON_PATH = resolve16(systemDir, "daemon.json");
|
|
8005
|
+
const DAEMON_TOKEN_PATH = resolve16(systemDir, "daemon-token");
|
|
8009
8006
|
mkdirSync10(home, { recursive: true });
|
|
8010
8007
|
ensureSystemDir();
|
|
8011
|
-
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-
|
|
8008
|
+
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-MLRKNP7Y.js");
|
|
8012
8009
|
migrateConfigSecrets();
|
|
8013
8010
|
migrateSetupCompleted();
|
|
8014
|
-
const { migrateAiModelQualification } = await import("./ai-service-
|
|
8011
|
+
const { migrateAiModelQualification } = await import("./ai-service-7PHSRDMO.js");
|
|
8015
8012
|
migrateAiModelQualification();
|
|
8016
|
-
await (await import("./db-
|
|
8013
|
+
await (await import("./db-JFLCJCUG.js")).getDb();
|
|
8017
8014
|
try {
|
|
8018
8015
|
const { eq: eq8, and: and6 } = await import("drizzle-orm");
|
|
8019
|
-
const { users: users2 } = await import("./schema-
|
|
8020
|
-
const db = await (await import("./db-
|
|
8016
|
+
const { users: users2 } = await import("./schema-PVNG3PQM.js");
|
|
8017
|
+
const db = await (await import("./db-JFLCJCUG.js")).getDb();
|
|
8021
8018
|
await db.update(users2).set({ role: "system" }).where(and6(eq8(users2.user_type, "system"), eq8(users2.role, "user")));
|
|
8022
8019
|
} catch (err) {
|
|
8023
8020
|
logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
|
|
8024
8021
|
}
|
|
8025
|
-
|
|
8022
|
+
try {
|
|
8023
|
+
const { migrateAvatarSizes } = await import("./avatar-image-BNWEXSA2.js");
|
|
8024
|
+
await migrateAvatarSizes();
|
|
8025
|
+
} catch (err) {
|
|
8026
|
+
logger_default.warn("avatar size migration failed", logger_default.errorData(err));
|
|
8027
|
+
}
|
|
8028
|
+
const { initSandbox } = await import("./sandbox-IOPWWILM.js");
|
|
8026
8029
|
await initSandbox();
|
|
8027
8030
|
try {
|
|
8028
8031
|
await syncBuiltinSkills();
|
|
@@ -8049,7 +8052,7 @@ async function startDaemon(opts) {
|
|
|
8049
8052
|
logger_default.warn("failed to ensure #system channel", logger_default.errorData(err));
|
|
8050
8053
|
}
|
|
8051
8054
|
try {
|
|
8052
|
-
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-
|
|
8055
|
+
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-FRZJVQCS.js");
|
|
8053
8056
|
await getOrCreateSystemUser2();
|
|
8054
8057
|
} catch (err) {
|
|
8055
8058
|
logger_default.warn(
|
|
@@ -8058,12 +8061,12 @@ async function startDaemon(opts) {
|
|
|
8058
8061
|
);
|
|
8059
8062
|
}
|
|
8060
8063
|
const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes2(32).toString("hex");
|
|
8061
|
-
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-
|
|
8064
|
+
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-MLRKNP7Y.js");
|
|
8062
8065
|
const globalCfg = readGlobalConfig2();
|
|
8063
8066
|
let tls;
|
|
8064
8067
|
if (opts.tailscale || globalCfg.tailscale) {
|
|
8065
8068
|
try {
|
|
8066
|
-
const { getTailscaleTls } = await import("./tailscale-
|
|
8069
|
+
const { getTailscaleTls } = await import("./tailscale-QAWVKQKU.js");
|
|
8067
8070
|
const tlsConfig = await getTailscaleTls();
|
|
8068
8071
|
tls = { key: tlsConfig.key, cert: tlsConfig.cert };
|
|
8069
8072
|
logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
|
|
@@ -8141,10 +8144,10 @@ async function startDaemon(opts) {
|
|
|
8141
8144
|
await Promise.all(workers);
|
|
8142
8145
|
}
|
|
8143
8146
|
try {
|
|
8144
|
-
const { isSetupComplete: isSetupComplete2 } = await import("./setup-
|
|
8147
|
+
const { isSetupComplete: isSetupComplete2 } = await import("./setup-MLRKNP7Y.js");
|
|
8145
8148
|
if (isSetupComplete2()) {
|
|
8146
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
8147
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
8149
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-IK5OYWMV.js");
|
|
8150
|
+
const { startSpiritFull } = await import("./mind-service-S3SY7HAM.js");
|
|
8148
8151
|
await ensureSpiritProject();
|
|
8149
8152
|
await syncSpiritTemplate();
|
|
8150
8153
|
const spiritEntry = await findMind("volute");
|
|
@@ -8161,7 +8164,7 @@ async function startDaemon(opts) {
|
|
|
8161
8164
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
8162
8165
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
8163
8166
|
});
|
|
8164
|
-
import("./cloud-sync-
|
|
8167
|
+
import("./cloud-sync-6WJ7WFYD.js").then(
|
|
8165
8168
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
8166
8169
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
8167
8170
|
})
|
|
@@ -8169,7 +8172,7 @@ async function startDaemon(opts) {
|
|
|
8169
8172
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
8170
8173
|
});
|
|
8171
8174
|
try {
|
|
8172
|
-
const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-
|
|
8175
|
+
const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-B67N35A3.js");
|
|
8173
8176
|
backfillTemplateHashes();
|
|
8174
8177
|
notifyVersionUpdate().catch((err) => {
|
|
8175
8178
|
logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
|