volute 0.27.0 → 0.29.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/README.md +20 -10
- package/dist/accept-666DIZX2.js +41 -0
- package/dist/api.d.ts +342 -143
- package/dist/{chat-MHJ3L6JQ.js → chat-KTPOR2JT.js} +18 -8
- package/dist/chunk-A6TUJJ3L.js +19 -0
- package/dist/{chunk-OQZH4PBB.js → chunk-CMILSHZD.js} +199 -277
- package/dist/{chunk-K5NAC55T.js → chunk-CQ7SNKNI.js} +1 -1
- package/dist/{chunk-PHSAT7YL.js → chunk-EHZKEMMV.js} +5 -5
- package/dist/{chunk-IAYBDWVG.js → chunk-FLZGS4QH.js} +145 -0
- package/dist/{chunk-USUXRNVD.js → chunk-J4IBNXGJ.js} +0 -2
- package/dist/chunk-MD4C26II.js +128 -0
- package/dist/{chunk-4WXYUOAK.js → chunk-NI5FFCCS.js} +8 -1
- package/dist/{chunk-JKOWNZ4P.js → chunk-P72MVS4R.js} +1 -40
- package/dist/chunk-THUUIU3E.js +232 -0
- package/dist/cli.js +21 -30
- package/dist/clock-DGCBVGYA.js +259 -0
- package/dist/{cloud-sync-T7M3ESC3.js → cloud-sync-KILFGV5Q.js} +7 -7
- package/dist/connectors/discord-bridge.js +1 -1
- package/dist/connectors/slack-bridge.js +1 -1
- package/dist/connectors/telegram-bridge.js +1 -1
- package/dist/{conversations-M2K4253F.js → conversations-P5BL7RMX.js} +7 -1
- package/dist/create-DFCAGEE5.js +70 -0
- package/dist/{daemon-restart-M2QTYMEG.js → daemon-restart-UHOMICXT.js} +1 -1
- package/dist/daemon.js +715 -661
- package/dist/files-M546TKVN.js +46 -0
- package/dist/{login-XX37I52P.js → login-BKP3AFWN.js} +7 -17
- package/dist/logout-IQK7FNEK.js +20 -0
- package/dist/{message-delivery-LDXLGERA.js → message-delivery-Q7VUMIEI.js} +11 -9
- package/dist/{mind-DI33C74K.js → mind-S5V6CK5W.js} +8 -13
- package/dist/{mind-activity-tracker-EN6XNXPF.js → mind-activity-tracker-WRHFI3YW.js} +1 -1
- package/dist/mind-list-UPJ75GPI.js +29 -0
- package/dist/{mind-manager-M6EMUW5I.js → mind-manager-P66HQDNE.js} +2 -2
- package/dist/mind-status-TK5AETEM.js +55 -0
- package/dist/{package-7WY6VKU3.js → package-OFKXNKJF.js} +1 -1
- package/dist/{pages-6EBS6CBR.js → pages-EUJR52AH.js} +5 -5
- package/dist/pages-watcher-P7QECRE2.js +21 -0
- package/dist/{publish-66UB2ZFY.js → publish-ZZB33WP4.js} +6 -17
- package/dist/{register-6B2CXTYM.js → register-CHREOMJ3.js} +5 -24
- package/dist/reject-LXIZFJ4Q.js +39 -0
- package/dist/{sandbox-TGBX22DS.js → sandbox-5BW5HPXM.js} +1 -1
- package/dist/{send-ZNCJDSRP.js → send-TAOEZ4NH.js} +64 -6
- package/dist/skills/dreaming/references/INSTALL.md +3 -17
- package/dist/skills/shared-files/SKILL.md +44 -0
- package/dist/skills/shared-files/scripts/merge.ts +72 -0
- package/dist/skills/shared-files/scripts/pull.ts +52 -0
- package/dist/skills/volute-mind/SKILL.md +48 -22
- package/dist/{sleep-manager-MWYHM5HV.js → sleep-manager-G4B5GW5P.js} +7 -7
- package/dist/{sprout-IJVVKSJ2.js → sprout-UNT7LKKE.js} +1 -1
- package/dist/{status-77YEPHMW.js → status-NQJYR4BG.js} +45 -1
- package/dist/{status-THLOBLWG.js → status-S7UUPNRW.js} +3 -13
- package/dist/systems-SMEFSHTA.js +60 -0
- package/dist/{up-NKSMXBWR.js → up-W6VAK2XE.js} +1 -1
- package/dist/{version-notify-5Z4MNR6M.js → version-notify-WDHRO3XD.js} +11 -11
- package/dist/web-assets/assets/index-BmKDnWDB.css +1 -0
- package/dist/web-assets/assets/index-CLJMx-GA.js +71 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +1 -1
- package/templates/_base/src/lib/logger.ts +10 -53
- package/templates/_base/src/lib/router.ts +1 -9
- package/templates/claude/src/lib/stream-consumer.ts +1 -4
- package/templates/pi/src/lib/event-handler.ts +1 -14
- package/dist/auth-D3OT2ARB.js +0 -37
- package/dist/chunk-KDGS53OS.js +0 -50
- package/dist/chunk-RWKVSSLY.js +0 -26
- package/dist/chunk-T6HKBWXZ.js +0 -23
- package/dist/create-D7J73A6H.js +0 -45
- package/dist/file-CR36YUPD.js +0 -204
- package/dist/log-ABYNVYJ3.js +0 -39
- package/dist/logout-W4KOOBIT.js +0 -18
- package/dist/logs-U35JR2KE.js +0 -77
- package/dist/merge-LNSMSAOF.js +0 -46
- package/dist/pull-XCHJTM5M.js +0 -39
- package/dist/schedule-QTJMFATP.js +0 -154
- package/dist/service-6LIN3F3K.js +0 -122
- package/dist/shared-ML5I4Q2A.js +0 -39
- package/dist/status-7GA4SM4Y.js +0 -35
- package/dist/web-assets/assets/index-CI5wgghI.css +0 -1
- package/dist/web-assets/assets/index-is5CvJWH.js +0 -75
- package/dist/{chunk-GIE6CSN5.js → chunk-DUAUMCEE.js} +0 -0
- package/dist/{history-XKRTAFS2.js → history-ALPTNB3I.js} +0 -0
- package/dist/{setup-JG4QAEBV.js → setup-RXYVGGT7.js} +3 -3
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
markIdle
|
|
7
|
-
} from "./chunk-K5NAC55T.js";
|
|
8
|
-
import {
|
|
9
|
-
clearJsonMap,
|
|
10
|
-
getMindManager,
|
|
11
|
-
getPrompt,
|
|
12
|
-
loadJsonMap,
|
|
13
|
-
saveJsonMap
|
|
14
|
-
} from "./chunk-PHSAT7YL.js";
|
|
3
|
+
startWatcher,
|
|
4
|
+
stopWatcher
|
|
5
|
+
} from "./chunk-THUUIU3E.js";
|
|
15
6
|
import {
|
|
16
7
|
addMessage,
|
|
17
8
|
createChannel,
|
|
@@ -19,12 +10,22 @@ import {
|
|
|
19
10
|
getParticipants,
|
|
20
11
|
joinChannel,
|
|
21
12
|
publish as publish2
|
|
22
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-FLZGS4QH.js";
|
|
14
|
+
import {
|
|
15
|
+
markIdle
|
|
16
|
+
} from "./chunk-CQ7SNKNI.js";
|
|
23
17
|
import {
|
|
24
18
|
broadcast,
|
|
25
19
|
publish,
|
|
26
20
|
subscribe
|
|
27
21
|
} from "./chunk-VIVMW2H2.js";
|
|
22
|
+
import {
|
|
23
|
+
clearJsonMap,
|
|
24
|
+
getMindManager,
|
|
25
|
+
getPrompt,
|
|
26
|
+
loadJsonMap,
|
|
27
|
+
saveJsonMap
|
|
28
|
+
} from "./chunk-EHZKEMMV.js";
|
|
28
29
|
import {
|
|
29
30
|
logger_default
|
|
30
31
|
} from "./chunk-YUIHSKR6.js";
|
|
@@ -42,19 +43,20 @@ import {
|
|
|
42
43
|
stateDir,
|
|
43
44
|
users,
|
|
44
45
|
voluteHome,
|
|
45
|
-
voluteSystemDir
|
|
46
|
+
voluteSystemDir,
|
|
47
|
+
voluteUserHome
|
|
46
48
|
} from "./chunk-H7OZRFJB.js";
|
|
47
49
|
|
|
48
50
|
// src/lib/daemon/sleep-manager.ts
|
|
49
51
|
import { execFile, spawn as spawnChild } from "child_process";
|
|
50
52
|
import {
|
|
51
53
|
existsSync as existsSync5,
|
|
52
|
-
mkdirSync as
|
|
53
|
-
readdirSync
|
|
54
|
-
readFileSync as
|
|
54
|
+
mkdirSync as mkdirSync5,
|
|
55
|
+
readdirSync,
|
|
56
|
+
readFileSync as readFileSync6,
|
|
55
57
|
readlinkSync,
|
|
56
|
-
renameSync,
|
|
57
|
-
writeFileSync as
|
|
58
|
+
renameSync as renameSync2,
|
|
59
|
+
writeFileSync as writeFileSync5
|
|
58
60
|
} from "fs";
|
|
59
61
|
import { resolve as resolve8 } from "path";
|
|
60
62
|
import { promisify } from "util";
|
|
@@ -227,214 +229,9 @@ async function migrateMindRoles() {
|
|
|
227
229
|
await db.update(users).set({ role: "user" }).where(and(eq(users.user_type, "mind"), inArray(users.role, ["mind", "agent"])));
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
// src/lib/pages-watcher.ts
|
|
231
|
-
import { existsSync as existsSync2, readdirSync, statSync, watch } from "fs";
|
|
232
|
-
import { join, resolve as resolve2 } from "path";
|
|
233
|
-
var watchers = /* @__PURE__ */ new Map();
|
|
234
|
-
var homeWatchers = /* @__PURE__ */ new Map();
|
|
235
|
-
var debounceTimers = /* @__PURE__ */ new Map();
|
|
236
|
-
var sitesCache = null;
|
|
237
|
-
var recentPagesCache = null;
|
|
238
|
-
function startPagesWatcher(mindName, pagesDir) {
|
|
239
|
-
try {
|
|
240
|
-
const watcher = watch(pagesDir, { recursive: true }, (_eventType, filename) => {
|
|
241
|
-
if (!filename || !filename.endsWith(".html")) return;
|
|
242
|
-
const key = `${mindName}:${filename}`;
|
|
243
|
-
const existing = debounceTimers.get(key);
|
|
244
|
-
if (existing) clearTimeout(existing);
|
|
245
|
-
debounceTimers.set(
|
|
246
|
-
key,
|
|
247
|
-
setTimeout(() => {
|
|
248
|
-
debounceTimers.delete(key);
|
|
249
|
-
invalidateCache();
|
|
250
|
-
publish({
|
|
251
|
-
type: "page_updated",
|
|
252
|
-
mind: mindName,
|
|
253
|
-
summary: `${mindName} updated ${filename}`,
|
|
254
|
-
metadata: { file: filename }
|
|
255
|
-
}).catch(
|
|
256
|
-
(err) => logger_default.error("failed to publish page_updated activity", logger_default.errorData(err))
|
|
257
|
-
);
|
|
258
|
-
}, 100)
|
|
259
|
-
);
|
|
260
|
-
});
|
|
261
|
-
watchers.set(mindName, watcher);
|
|
262
|
-
} catch (err) {
|
|
263
|
-
logger_default.warn(`failed to start pages watcher for ${mindName}`, logger_default.errorData(err));
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
function startWatcher(mindName) {
|
|
267
|
-
if (watchers.has(mindName)) return;
|
|
268
|
-
const pagesDir = resolve2(mindDir(mindName), "home", "public", "pages");
|
|
269
|
-
if (existsSync2(pagesDir)) {
|
|
270
|
-
startPagesWatcher(mindName, pagesDir);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
if (homeWatchers.has(mindName)) return;
|
|
274
|
-
const publicDir = resolve2(mindDir(mindName), "home", "public");
|
|
275
|
-
if (!existsSync2(publicDir)) return;
|
|
276
|
-
try {
|
|
277
|
-
const hw = watch(publicDir, (_eventType, filename) => {
|
|
278
|
-
if (filename !== "pages") return;
|
|
279
|
-
if (!existsSync2(pagesDir)) return;
|
|
280
|
-
hw.close();
|
|
281
|
-
homeWatchers.delete(mindName);
|
|
282
|
-
invalidateCache();
|
|
283
|
-
startPagesWatcher(mindName, pagesDir);
|
|
284
|
-
});
|
|
285
|
-
homeWatchers.set(mindName, hw);
|
|
286
|
-
} catch (err) {
|
|
287
|
-
logger_default.warn(`failed to start home watcher for ${mindName}`, logger_default.errorData(err));
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
function stopWatcher(mindName) {
|
|
291
|
-
const watcher = watchers.get(mindName);
|
|
292
|
-
if (watcher) {
|
|
293
|
-
watcher.close();
|
|
294
|
-
watchers.delete(mindName);
|
|
295
|
-
}
|
|
296
|
-
const hw = homeWatchers.get(mindName);
|
|
297
|
-
if (hw) {
|
|
298
|
-
hw.close();
|
|
299
|
-
homeWatchers.delete(mindName);
|
|
300
|
-
}
|
|
301
|
-
for (const [key, timer] of debounceTimers) {
|
|
302
|
-
if (key.startsWith(`${mindName}:`)) {
|
|
303
|
-
clearTimeout(timer);
|
|
304
|
-
debounceTimers.delete(key);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
function stopAllWatchers() {
|
|
309
|
-
for (const [, watcher] of watchers) {
|
|
310
|
-
watcher.close();
|
|
311
|
-
}
|
|
312
|
-
watchers.clear();
|
|
313
|
-
for (const [, hw] of homeWatchers) {
|
|
314
|
-
hw.close();
|
|
315
|
-
}
|
|
316
|
-
homeWatchers.clear();
|
|
317
|
-
for (const [, timer] of debounceTimers) {
|
|
318
|
-
clearTimeout(timer);
|
|
319
|
-
}
|
|
320
|
-
debounceTimers.clear();
|
|
321
|
-
invalidateCache();
|
|
322
|
-
}
|
|
323
|
-
function invalidateCache() {
|
|
324
|
-
sitesCache = null;
|
|
325
|
-
recentPagesCache = null;
|
|
326
|
-
}
|
|
327
|
-
function scanPagesDir(dir, urlPrefix) {
|
|
328
|
-
const pages = [];
|
|
329
|
-
let items;
|
|
330
|
-
try {
|
|
331
|
-
items = readdirSync(dir);
|
|
332
|
-
} catch {
|
|
333
|
-
return pages;
|
|
334
|
-
}
|
|
335
|
-
for (const item of items) {
|
|
336
|
-
if (item.startsWith(".")) continue;
|
|
337
|
-
const fullPath = resolve2(dir, item);
|
|
338
|
-
try {
|
|
339
|
-
const s = statSync(fullPath);
|
|
340
|
-
if (s.isFile() && item.endsWith(".html")) {
|
|
341
|
-
pages.push({
|
|
342
|
-
file: item,
|
|
343
|
-
modified: s.mtime.toISOString(),
|
|
344
|
-
url: `${urlPrefix}/${item}`
|
|
345
|
-
});
|
|
346
|
-
} else if (s.isDirectory()) {
|
|
347
|
-
const indexPath = resolve2(fullPath, "index.html");
|
|
348
|
-
if (existsSync2(indexPath)) {
|
|
349
|
-
const indexStat = statSync(indexPath);
|
|
350
|
-
pages.push({
|
|
351
|
-
file: join(item, "index.html"),
|
|
352
|
-
modified: indexStat.mtime.toISOString(),
|
|
353
|
-
url: `${urlPrefix}/${item}/`
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
} catch {
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
pages.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
|
|
361
|
-
return pages;
|
|
362
|
-
}
|
|
363
|
-
async function buildSites() {
|
|
364
|
-
const sites = [];
|
|
365
|
-
const systemPagesDir = resolve2(voluteHome(), "shared", "pages");
|
|
366
|
-
if (existsSync2(systemPagesDir)) {
|
|
367
|
-
const systemPages = scanPagesDir(systemPagesDir, "/pages/_system");
|
|
368
|
-
if (systemPages.length > 0) {
|
|
369
|
-
sites.push({ name: "_system", label: "System", pages: systemPages });
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
const entries = await readRegistry();
|
|
373
|
-
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
374
|
-
const pagesDir = resolve2(mindDir(entry.name), "home", "public", "pages");
|
|
375
|
-
if (!existsSync2(pagesDir)) continue;
|
|
376
|
-
const mindPages = scanPagesDir(pagesDir, `/pages/${entry.name}`);
|
|
377
|
-
if (mindPages.length > 0) {
|
|
378
|
-
sites.push({ name: entry.name, label: entry.name, pages: mindPages });
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return sites;
|
|
382
|
-
}
|
|
383
|
-
async function buildRecentPages() {
|
|
384
|
-
const entries = await readRegistry();
|
|
385
|
-
const pages = [];
|
|
386
|
-
for (const entry of entries) {
|
|
387
|
-
const pagesDir = resolve2(mindDir(entry.name), "home", "public", "pages");
|
|
388
|
-
if (!existsSync2(pagesDir)) continue;
|
|
389
|
-
let items;
|
|
390
|
-
try {
|
|
391
|
-
items = readdirSync(pagesDir);
|
|
392
|
-
} catch {
|
|
393
|
-
continue;
|
|
394
|
-
}
|
|
395
|
-
for (const item of items) {
|
|
396
|
-
if (item.startsWith(".")) continue;
|
|
397
|
-
const fullPath = resolve2(pagesDir, item);
|
|
398
|
-
try {
|
|
399
|
-
const s = statSync(fullPath);
|
|
400
|
-
if (s.isFile() && item.endsWith(".html")) {
|
|
401
|
-
pages.push({
|
|
402
|
-
mind: entry.name,
|
|
403
|
-
file: item,
|
|
404
|
-
modified: s.mtime.toISOString(),
|
|
405
|
-
url: `/pages/${entry.name}/${item}`
|
|
406
|
-
});
|
|
407
|
-
} else if (s.isDirectory()) {
|
|
408
|
-
const indexPath = resolve2(fullPath, "index.html");
|
|
409
|
-
if (existsSync2(indexPath)) {
|
|
410
|
-
const indexStat = statSync(indexPath);
|
|
411
|
-
pages.push({
|
|
412
|
-
mind: entry.name,
|
|
413
|
-
file: join(item, "index.html"),
|
|
414
|
-
modified: indexStat.mtime.toISOString(),
|
|
415
|
-
url: `/pages/${entry.name}/${item}/`
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
} catch {
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
pages.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
|
|
424
|
-
return pages.slice(0, 10);
|
|
425
|
-
}
|
|
426
|
-
async function getCachedSites() {
|
|
427
|
-
if (!sitesCache) sitesCache = await buildSites();
|
|
428
|
-
return sitesCache;
|
|
429
|
-
}
|
|
430
|
-
async function getCachedRecentPages() {
|
|
431
|
-
if (!recentPagesCache) recentPagesCache = await buildRecentPages();
|
|
432
|
-
return recentPagesCache;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
232
|
// src/connectors/sdk.ts
|
|
436
|
-
import { existsSync as
|
|
437
|
-
import { join
|
|
233
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
234
|
+
import { join, resolve as resolve2 } from "path";
|
|
438
235
|
function splitMessage(text, maxLength) {
|
|
439
236
|
const chunks = [];
|
|
440
237
|
while (text.length > maxLength) {
|
|
@@ -447,8 +244,8 @@ function splitMessage(text, maxLength) {
|
|
|
447
244
|
return chunks;
|
|
448
245
|
}
|
|
449
246
|
function readChannelMap(mindName) {
|
|
450
|
-
const filePath =
|
|
451
|
-
if (!
|
|
247
|
+
const filePath = join(stateDir(mindName), "channels.json");
|
|
248
|
+
if (!existsSync2(filePath)) return {};
|
|
452
249
|
try {
|
|
453
250
|
return JSON.parse(readFileSync2(filePath, "utf-8"));
|
|
454
251
|
} catch (err) {
|
|
@@ -459,7 +256,7 @@ function readChannelMap(mindName) {
|
|
|
459
256
|
function writeChannelEntry(mindName, slug, entry) {
|
|
460
257
|
const dir = stateDir(mindName);
|
|
461
258
|
mkdirSync2(dir, { recursive: true });
|
|
462
|
-
const filePath =
|
|
259
|
+
const filePath = join(dir, "channels.json");
|
|
463
260
|
const map = readChannelMap(mindName);
|
|
464
261
|
map[slug] = entry;
|
|
465
262
|
writeFileSync2(filePath, JSON.stringify(map, null, 2) + "\n");
|
|
@@ -503,7 +300,7 @@ function publish3(mind, event) {
|
|
|
503
300
|
|
|
504
301
|
// src/lib/delivery/delivery-manager.ts
|
|
505
302
|
import { readFile, realpath } from "fs/promises";
|
|
506
|
-
import { extname, resolve as
|
|
303
|
+
import { extname, resolve as resolve4 } from "path";
|
|
507
304
|
import { and as and2, eq as eq2, sql } from "drizzle-orm";
|
|
508
305
|
|
|
509
306
|
// src/lib/typing.ts
|
|
@@ -597,8 +394,8 @@ function publishTypingForChannels(channels, map) {
|
|
|
597
394
|
}
|
|
598
395
|
|
|
599
396
|
// src/lib/delivery/delivery-router.ts
|
|
600
|
-
import { readFileSync as readFileSync3, statSync
|
|
601
|
-
import { resolve as
|
|
397
|
+
import { readFileSync as readFileSync3, statSync } from "fs";
|
|
398
|
+
import { resolve as resolve3 } from "path";
|
|
602
399
|
function extractTextContent(content) {
|
|
603
400
|
if (typeof content === "string") return content;
|
|
604
401
|
if (Array.isArray(content)) {
|
|
@@ -611,7 +408,7 @@ var statCheckCache = /* @__PURE__ */ new Map();
|
|
|
611
408
|
var STAT_TTL_MS = 5e3;
|
|
612
409
|
var dlog = logger_default.child("delivery-router");
|
|
613
410
|
function configPath(mindName) {
|
|
614
|
-
return
|
|
411
|
+
return resolve3(mindDir(mindName), "home/.config/routes.json");
|
|
615
412
|
}
|
|
616
413
|
function getRoutingConfig(mindName) {
|
|
617
414
|
const path = configPath(mindName);
|
|
@@ -623,7 +420,7 @@ function getRoutingConfig(mindName) {
|
|
|
623
420
|
}
|
|
624
421
|
let mtime;
|
|
625
422
|
try {
|
|
626
|
-
mtime =
|
|
423
|
+
mtime = statSync(path).mtimeMs;
|
|
627
424
|
} catch {
|
|
628
425
|
configCache.delete(mindName);
|
|
629
426
|
statCheckCache.delete(mindName);
|
|
@@ -1296,8 +1093,8 @@ var DeliveryManager = class {
|
|
|
1296
1093
|
const dir = mindDir(p.username);
|
|
1297
1094
|
const config = readVoluteConfig(dir);
|
|
1298
1095
|
if (!config?.profile?.avatar) continue;
|
|
1299
|
-
filePath =
|
|
1300
|
-
const homeDir =
|
|
1096
|
+
filePath = resolve4(dir, "home", config.profile.avatar);
|
|
1097
|
+
const homeDir = resolve4(dir, "home");
|
|
1301
1098
|
if (!filePath.startsWith(`${homeDir}/`)) {
|
|
1302
1099
|
dlog2.warn(`avatar path for ${p.username} escapes home directory, skipping`);
|
|
1303
1100
|
continue;
|
|
@@ -1316,7 +1113,7 @@ var DeliveryManager = class {
|
|
|
1316
1113
|
throw err;
|
|
1317
1114
|
}
|
|
1318
1115
|
} else {
|
|
1319
|
-
filePath =
|
|
1116
|
+
filePath = resolve4(voluteHome(), "avatars", p.avatar);
|
|
1320
1117
|
}
|
|
1321
1118
|
const ext = extname(filePath).toLowerCase();
|
|
1322
1119
|
const mimeMap = {
|
|
@@ -1412,6 +1209,12 @@ async function recordInbound(mind, channel, sender, content) {
|
|
|
1412
1209
|
content: content ?? void 0
|
|
1413
1210
|
});
|
|
1414
1211
|
}
|
|
1212
|
+
function resolveSleepAction(sleepBehavior, wokenByTrigger, wakeTriggerMatches) {
|
|
1213
|
+
if (sleepBehavior === "skip") return "skip";
|
|
1214
|
+
if (sleepBehavior === "trigger-wake" && !wokenByTrigger) return "queue-and-wake";
|
|
1215
|
+
if (!sleepBehavior && wakeTriggerMatches) return "queue-and-wake";
|
|
1216
|
+
return "queue";
|
|
1217
|
+
}
|
|
1415
1218
|
async function deliverMessage(mindName, payload) {
|
|
1416
1219
|
try {
|
|
1417
1220
|
const baseName = await getBaseName(mindName);
|
|
@@ -1424,11 +1227,21 @@ async function deliverMessage(mindName, payload) {
|
|
|
1424
1227
|
await recordInbound(baseName, payload.channel, payload.sender ?? null, textContent);
|
|
1425
1228
|
const sleepManager = getSleepManagerIfReady();
|
|
1426
1229
|
if (sleepManager?.isSleeping(baseName)) {
|
|
1427
|
-
|
|
1428
|
-
|
|
1230
|
+
const sleepState = sleepManager.getState(baseName);
|
|
1231
|
+
const action = resolveSleepAction(
|
|
1232
|
+
payload.whileSleeping,
|
|
1233
|
+
sleepState.wokenByTrigger,
|
|
1234
|
+
sleepManager.checkWakeTrigger(baseName, payload)
|
|
1235
|
+
);
|
|
1236
|
+
if (action === "skip") {
|
|
1237
|
+
dlog3.info(
|
|
1238
|
+
`skipped delivery to ${baseName} (sleeping, whileSleeping=skip, channel=${payload.channel})`
|
|
1239
|
+
);
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
await sleepManager.queueSleepMessage(baseName, payload);
|
|
1243
|
+
if (action === "queue-and-wake") {
|
|
1429
1244
|
sleepManager.initiateWake(baseName, { trigger: { channel: payload.channel } }).catch((err) => dlog3.warn(`failed to trigger-wake ${baseName}`, logger_default.errorData(err)));
|
|
1430
|
-
} else {
|
|
1431
|
-
await sleepManager.queueSleepMessage(baseName, payload);
|
|
1432
1245
|
}
|
|
1433
1246
|
return;
|
|
1434
1247
|
}
|
|
@@ -1474,7 +1287,7 @@ async function announceToSystem(text) {
|
|
|
1474
1287
|
platformId: channelId,
|
|
1475
1288
|
platform: "volute",
|
|
1476
1289
|
name: SYSTEM_CHANNEL_NAME,
|
|
1477
|
-
type: "
|
|
1290
|
+
type: "channel"
|
|
1478
1291
|
});
|
|
1479
1292
|
} catch (err) {
|
|
1480
1293
|
logger_default.warn(`failed to write channel entry for ${mind.username}`, logger_default.errorData(err));
|
|
@@ -1493,6 +1306,74 @@ async function announceToSystem(text) {
|
|
|
1493
1306
|
}
|
|
1494
1307
|
}
|
|
1495
1308
|
|
|
1309
|
+
// src/lib/systems-config.ts
|
|
1310
|
+
import {
|
|
1311
|
+
existsSync as existsSync3,
|
|
1312
|
+
mkdirSync as mkdirSync3,
|
|
1313
|
+
readFileSync as readFileSync4,
|
|
1314
|
+
renameSync,
|
|
1315
|
+
unlinkSync,
|
|
1316
|
+
writeFileSync as writeFileSync3
|
|
1317
|
+
} from "fs";
|
|
1318
|
+
import { resolve as resolve5 } from "path";
|
|
1319
|
+
var DEFAULT_API_URL = "https://volute.systems";
|
|
1320
|
+
function configPath2() {
|
|
1321
|
+
return resolve5(voluteSystemDir(), "systems.json");
|
|
1322
|
+
}
|
|
1323
|
+
function migrateIfNeeded() {
|
|
1324
|
+
const target = configPath2();
|
|
1325
|
+
if (existsSync3(target)) return;
|
|
1326
|
+
const oldPaths = [
|
|
1327
|
+
resolve5(voluteUserHome(), "systems.json"),
|
|
1328
|
+
resolve5(voluteHome(), "systems.json")
|
|
1329
|
+
];
|
|
1330
|
+
for (const old of oldPaths) {
|
|
1331
|
+
if (old !== target && existsSync3(old)) {
|
|
1332
|
+
try {
|
|
1333
|
+
mkdirSync3(voluteSystemDir(), { recursive: true });
|
|
1334
|
+
renameSync(old, target);
|
|
1335
|
+
} catch {
|
|
1336
|
+
}
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
function readSystemsConfig() {
|
|
1342
|
+
migrateIfNeeded();
|
|
1343
|
+
const path = configPath2();
|
|
1344
|
+
if (!existsSync3(path)) return null;
|
|
1345
|
+
const raw = readFileSync4(path, "utf-8");
|
|
1346
|
+
let data;
|
|
1347
|
+
try {
|
|
1348
|
+
data = JSON.parse(raw);
|
|
1349
|
+
} catch {
|
|
1350
|
+
console.error(
|
|
1351
|
+
`Warning: ${path} contains invalid JSON. Run "volute systems logout" and re-login.`
|
|
1352
|
+
);
|
|
1353
|
+
return null;
|
|
1354
|
+
}
|
|
1355
|
+
if (!data.apiKey || !data.system) return null;
|
|
1356
|
+
return {
|
|
1357
|
+
apiKey: data.apiKey,
|
|
1358
|
+
system: data.system,
|
|
1359
|
+
apiUrl: data.apiUrl || DEFAULT_API_URL
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
function writeSystemsConfig(config) {
|
|
1363
|
+
mkdirSync3(voluteSystemDir(), { recursive: true });
|
|
1364
|
+
writeFileSync3(configPath2(), `${JSON.stringify(config, null, 2)}
|
|
1365
|
+
`, { mode: 384 });
|
|
1366
|
+
}
|
|
1367
|
+
function deleteSystemsConfig() {
|
|
1368
|
+
try {
|
|
1369
|
+
unlinkSync(configPath2());
|
|
1370
|
+
return true;
|
|
1371
|
+
} catch (err) {
|
|
1372
|
+
if (err.code === "ENOENT") return false;
|
|
1373
|
+
throw err;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1496
1377
|
// src/lib/daemon/mail-poller.ts
|
|
1497
1378
|
var mlog = logger_default.child("mail");
|
|
1498
1379
|
function formatEmailContent(email) {
|
|
@@ -1787,6 +1668,15 @@ var Scheduler = class {
|
|
|
1787
1668
|
shouldFire(schedule, epochMinute, mind, cronCache) {
|
|
1788
1669
|
const key = `${mind}:${schedule.id}`;
|
|
1789
1670
|
if (this.lastFired.get(key) === epochMinute) return false;
|
|
1671
|
+
if (schedule.fireAt) {
|
|
1672
|
+
const fireTime = Math.floor(new Date(schedule.fireAt).getTime() / 6e4);
|
|
1673
|
+
if (epochMinute >= fireTime) {
|
|
1674
|
+
this.lastFired.set(key, epochMinute);
|
|
1675
|
+
return true;
|
|
1676
|
+
}
|
|
1677
|
+
return false;
|
|
1678
|
+
}
|
|
1679
|
+
if (!schedule.cron) return false;
|
|
1790
1680
|
let prevMinute = cronCache.get(schedule.cron);
|
|
1791
1681
|
if (prevMinute === void 0) {
|
|
1792
1682
|
try {
|
|
@@ -1806,18 +1696,6 @@ var Scheduler = class {
|
|
|
1806
1696
|
return false;
|
|
1807
1697
|
}
|
|
1808
1698
|
async fire(mindName, schedule) {
|
|
1809
|
-
const sleepManager = getSleepManagerIfReady();
|
|
1810
|
-
const sleepState = sleepManager?.getState(mindName);
|
|
1811
|
-
if (sleepState?.sleeping) {
|
|
1812
|
-
if (schedule.skipWhenSleeping) {
|
|
1813
|
-
slog.info(`skipped "${schedule.id}" for ${mindName} (sleeping)`);
|
|
1814
|
-
return;
|
|
1815
|
-
}
|
|
1816
|
-
if (sleepState.wokenByTrigger) {
|
|
1817
|
-
slog.info(`skipped "${schedule.id}" for ${mindName} (trigger-woken)`);
|
|
1818
|
-
return;
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
1699
|
try {
|
|
1822
1700
|
let text;
|
|
1823
1701
|
if (schedule.script) {
|
|
@@ -1841,16 +1719,46 @@ ${stderr}` : ""}`;
|
|
|
1841
1719
|
slog.warn(`schedule "${schedule.id}" for ${mindName} has no message or script`);
|
|
1842
1720
|
return;
|
|
1843
1721
|
}
|
|
1722
|
+
const whileSleeping = schedule.whileSleeping ?? (schedule.skipWhenSleeping ? "skip" : void 0);
|
|
1844
1723
|
await this.deliver(mindName, {
|
|
1845
1724
|
content: [{ type: "text", text }],
|
|
1846
1725
|
channel: schedule.channel ?? "system:scheduler",
|
|
1847
|
-
sender: schedule.id
|
|
1726
|
+
sender: schedule.id,
|
|
1727
|
+
whileSleeping
|
|
1848
1728
|
});
|
|
1849
1729
|
slog.info(`fired "${schedule.id}" for ${mindName}`);
|
|
1730
|
+
if (schedule.fireAt) {
|
|
1731
|
+
this.removeSchedule(mindName, schedule.id);
|
|
1732
|
+
}
|
|
1850
1733
|
} catch (err) {
|
|
1851
1734
|
slog.warn(`failed to fire "${schedule.id}" for ${mindName}`, logger_default.errorData(err));
|
|
1852
1735
|
}
|
|
1853
1736
|
}
|
|
1737
|
+
removeSchedule(mindName, scheduleId) {
|
|
1738
|
+
const memSchedules = this.schedules.get(mindName);
|
|
1739
|
+
if (memSchedules) {
|
|
1740
|
+
const filtered = memSchedules.filter((s) => s.id !== scheduleId);
|
|
1741
|
+
if (filtered.length > 0) {
|
|
1742
|
+
this.schedules.set(mindName, filtered);
|
|
1743
|
+
} else {
|
|
1744
|
+
this.schedules.delete(mindName);
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
try {
|
|
1748
|
+
const dir = mindDir(mindName);
|
|
1749
|
+
const config = readVoluteConfig(dir);
|
|
1750
|
+
if (!config?.schedules) return;
|
|
1751
|
+
config.schedules = config.schedules.filter((s) => s.id !== scheduleId);
|
|
1752
|
+
if (config.schedules.length === 0) config.schedules = void 0;
|
|
1753
|
+
writeVoluteConfig(dir, config);
|
|
1754
|
+
slog.info(`removed one-time schedule "${scheduleId}" for ${mindName}`);
|
|
1755
|
+
} catch (err) {
|
|
1756
|
+
slog.error(
|
|
1757
|
+
`failed to persist removal of schedule "${scheduleId}" for ${mindName} (removed from memory)`,
|
|
1758
|
+
logger_default.errorData(err)
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1854
1762
|
runScript(script, cwd, mindName) {
|
|
1855
1763
|
return exec("bash", ["-c", script], { cwd, mindName });
|
|
1856
1764
|
}
|
|
@@ -1870,7 +1778,7 @@ function getScheduler() {
|
|
|
1870
1778
|
}
|
|
1871
1779
|
|
|
1872
1780
|
// src/lib/daemon/token-budget.ts
|
|
1873
|
-
import { existsSync as existsSync4, mkdirSync as
|
|
1781
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
1874
1782
|
import { resolve as resolve7 } from "path";
|
|
1875
1783
|
var tlog = logger_default.child("token-budget");
|
|
1876
1784
|
var DEFAULT_BUDGET_PERIOD_MINUTES = 60;
|
|
@@ -1994,14 +1902,14 @@ var TokenBudget = class {
|
|
|
1994
1902
|
saveBudgetState(mind, state) {
|
|
1995
1903
|
try {
|
|
1996
1904
|
const dir = stateDir(mind);
|
|
1997
|
-
|
|
1905
|
+
mkdirSync4(dir, { recursive: true });
|
|
1998
1906
|
const data = {
|
|
1999
1907
|
periodStart: state.periodStart,
|
|
2000
1908
|
tokensUsed: state.tokensUsed,
|
|
2001
1909
|
warningInjected: state.warningInjected,
|
|
2002
1910
|
queue: state.queue
|
|
2003
1911
|
};
|
|
2004
|
-
|
|
1912
|
+
writeFileSync4(this.budgetStatePath(mind), `${JSON.stringify(data)}
|
|
2005
1913
|
`);
|
|
2006
1914
|
} catch (err) {
|
|
2007
1915
|
tlog.warn(`failed to save budget state for ${mind}`, logger_default.errorData(err));
|
|
@@ -2011,7 +1919,7 @@ var TokenBudget = class {
|
|
|
2011
1919
|
try {
|
|
2012
1920
|
const path = this.budgetStatePath(mind);
|
|
2013
1921
|
if (!existsSync4(path)) return null;
|
|
2014
|
-
const data = JSON.parse(
|
|
1922
|
+
const data = JSON.parse(readFileSync5(path, "utf-8"));
|
|
2015
1923
|
if (typeof data.periodStart !== "number" || typeof data.tokensUsed !== "number") return null;
|
|
2016
1924
|
return {
|
|
2017
1925
|
periodStart: data.periodStart,
|
|
@@ -2080,6 +1988,7 @@ async function startMindFull(name) {
|
|
|
2080
1988
|
if (!entry || entry.stage === "seed") return;
|
|
2081
1989
|
const dir = mindDir(baseName);
|
|
2082
1990
|
getScheduler().loadSchedules(baseName);
|
|
1991
|
+
getSleepManagerIfReady()?.loadSleepConfig(baseName);
|
|
2083
1992
|
ensureMailAddress(baseName).catch(
|
|
2084
1993
|
(err) => logger_default.error(`failed to ensure mail address for ${baseName}`, logger_default.errorData(err))
|
|
2085
1994
|
);
|
|
@@ -2172,6 +2081,7 @@ var SleepManager = class {
|
|
|
2172
2081
|
interval = null;
|
|
2173
2082
|
unsubActivity = null;
|
|
2174
2083
|
transitioning = /* @__PURE__ */ new Set();
|
|
2084
|
+
sleepConfigs = /* @__PURE__ */ new Map();
|
|
2175
2085
|
get statePath() {
|
|
2176
2086
|
return resolve8(voluteSystemDir(), "sleep-state.json");
|
|
2177
2087
|
}
|
|
@@ -2190,7 +2100,7 @@ var SleepManager = class {
|
|
|
2190
2100
|
loadState() {
|
|
2191
2101
|
try {
|
|
2192
2102
|
if (existsSync5(this.statePath)) {
|
|
2193
|
-
const data = JSON.parse(
|
|
2103
|
+
const data = JSON.parse(readFileSync6(this.statePath, "utf-8"));
|
|
2194
2104
|
for (const [name, state] of Object.entries(data)) {
|
|
2195
2105
|
state.triggerWakeHistory ??= [];
|
|
2196
2106
|
this.states.set(name, state);
|
|
@@ -2206,7 +2116,7 @@ var SleepManager = class {
|
|
|
2206
2116
|
if (state.sleeping) data[name] = state;
|
|
2207
2117
|
}
|
|
2208
2118
|
try {
|
|
2209
|
-
|
|
2119
|
+
writeFileSync5(this.statePath, `${JSON.stringify(data, null, 2)}
|
|
2210
2120
|
`);
|
|
2211
2121
|
} catch (err) {
|
|
2212
2122
|
slog2.error("failed to save sleep state", logger_default.errorData(err));
|
|
@@ -2233,9 +2143,21 @@ var SleepManager = class {
|
|
|
2233
2143
|
slog2.info(`${name} trigger-wake converted to full wake`);
|
|
2234
2144
|
}
|
|
2235
2145
|
getSleepConfig(name) {
|
|
2146
|
+
if (this.sleepConfigs.has(name)) {
|
|
2147
|
+
return this.sleepConfigs.get(name) ?? null;
|
|
2148
|
+
}
|
|
2149
|
+
const config = this.loadSleepConfig(name);
|
|
2150
|
+
return config;
|
|
2151
|
+
}
|
|
2152
|
+
loadSleepConfig(name) {
|
|
2236
2153
|
const dir = mindDir(name);
|
|
2237
2154
|
const config = readVoluteConfig(dir);
|
|
2238
|
-
|
|
2155
|
+
const sleepConfig = config?.sleep ?? null;
|
|
2156
|
+
this.sleepConfigs.set(name, sleepConfig);
|
|
2157
|
+
return sleepConfig;
|
|
2158
|
+
}
|
|
2159
|
+
invalidateSleepConfig(name) {
|
|
2160
|
+
this.sleepConfigs.delete(name);
|
|
2239
2161
|
}
|
|
2240
2162
|
/**
|
|
2241
2163
|
* Put a mind to sleep. Sends pre-sleep message, waits for completion,
|
|
@@ -2255,8 +2177,7 @@ var SleepManager = class {
|
|
|
2255
2177
|
if (!entry) return;
|
|
2256
2178
|
const sleepConfig = this.getSleepConfig(name);
|
|
2257
2179
|
const wakeTime = opts?.voluntaryWakeAt ?? this.getNextWakeTime(sleepConfig) ?? "scheduled time";
|
|
2258
|
-
const
|
|
2259
|
-
const preSleepMsg = await getPrompt("pre_sleep", { wakeTime, queuedInfo });
|
|
2180
|
+
const preSleepMsg = await getPrompt("pre_sleep", { wakeTime });
|
|
2260
2181
|
try {
|
|
2261
2182
|
const db = await getDb();
|
|
2262
2183
|
await db.insert(mindHistory).values({
|
|
@@ -2426,7 +2347,7 @@ var SleepManager = class {
|
|
|
2426
2347
|
const db = await getDb();
|
|
2427
2348
|
const rows = await db.select().from(deliveryQueue).where(and3(eq3(deliveryQueue.mind, name), eq3(deliveryQueue.status, "sleep-queued"))).all();
|
|
2428
2349
|
if (rows.length === 0) return 0;
|
|
2429
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
2350
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-Q7VUMIEI.js");
|
|
2430
2351
|
const delivered = [];
|
|
2431
2352
|
for (const row of rows) {
|
|
2432
2353
|
try {
|
|
@@ -2547,14 +2468,14 @@ var SleepManager = class {
|
|
|
2547
2468
|
const sessionsDir = resolve8(dir, ".mind", "sessions");
|
|
2548
2469
|
if (existsSync5(sessionsDir)) {
|
|
2549
2470
|
const archiveDir = resolve8(sessionsDir, "archive");
|
|
2550
|
-
|
|
2551
|
-
for (const file of
|
|
2471
|
+
mkdirSync5(archiveDir, { recursive: true });
|
|
2472
|
+
for (const file of readdirSync(sessionsDir)) {
|
|
2552
2473
|
if (file === "archive" || !file.endsWith(".json")) continue;
|
|
2553
2474
|
const src = resolve8(sessionsDir, file);
|
|
2554
2475
|
const base = file.replace(/\.json$/, "");
|
|
2555
2476
|
const dest = resolve8(archiveDir, `${base}-${timestamp}.json`);
|
|
2556
2477
|
try {
|
|
2557
|
-
|
|
2478
|
+
renameSync2(src, dest);
|
|
2558
2479
|
} catch (err) {
|
|
2559
2480
|
slog2.warn(`failed to archive session ${file} for ${name}`, logger_default.errorData(err));
|
|
2560
2481
|
}
|
|
@@ -2563,13 +2484,13 @@ var SleepManager = class {
|
|
|
2563
2484
|
const piSessionsDir = resolve8(dir, ".mind", "pi-sessions");
|
|
2564
2485
|
if (existsSync5(piSessionsDir)) {
|
|
2565
2486
|
const archiveDir = resolve8(piSessionsDir, "archive");
|
|
2566
|
-
|
|
2567
|
-
for (const entry of
|
|
2487
|
+
mkdirSync5(archiveDir, { recursive: true });
|
|
2488
|
+
for (const entry of readdirSync(piSessionsDir, { withFileTypes: true })) {
|
|
2568
2489
|
if (entry.name === "archive" || !entry.isDirectory()) continue;
|
|
2569
2490
|
const src = resolve8(piSessionsDir, entry.name);
|
|
2570
2491
|
const dest = resolve8(archiveDir, `${entry.name}-${timestamp}`);
|
|
2571
2492
|
try {
|
|
2572
|
-
|
|
2493
|
+
renameSync2(src, dest);
|
|
2573
2494
|
} catch (err) {
|
|
2574
2495
|
slog2.warn(`failed to archive pi-session ${entry.name} for ${name}`, logger_default.errorData(err));
|
|
2575
2496
|
}
|
|
@@ -2675,16 +2596,16 @@ var SleepManager = class {
|
|
|
2675
2596
|
} catch {
|
|
2676
2597
|
try {
|
|
2677
2598
|
const portHex = port.toString(16).toUpperCase().padStart(4, "0");
|
|
2678
|
-
const tcp6 =
|
|
2599
|
+
const tcp6 = readFileSync6("/proc/net/tcp6", "utf-8");
|
|
2679
2600
|
for (const line of tcp6.split("\n")) {
|
|
2680
2601
|
if (!line.includes(`:${portHex} `)) continue;
|
|
2681
2602
|
const fields = line.trim().split(/\s+/);
|
|
2682
2603
|
if (fields[3] !== "0A") continue;
|
|
2683
2604
|
const inode = parseInt(fields[9], 10);
|
|
2684
2605
|
if (!inode) continue;
|
|
2685
|
-
for (const pidDir of
|
|
2606
|
+
for (const pidDir of readdirSync("/proc").filter((f) => /^\d+$/.test(f))) {
|
|
2686
2607
|
try {
|
|
2687
|
-
const fds =
|
|
2608
|
+
const fds = readdirSync(`/proc/${pidDir}/fd`);
|
|
2688
2609
|
for (const fd of fds) {
|
|
2689
2610
|
try {
|
|
2690
2611
|
const link = readlinkSync(`/proc/${pidDir}/fd/${fd}`);
|
|
@@ -2760,9 +2681,6 @@ export {
|
|
|
2760
2681
|
migrateMindRoles,
|
|
2761
2682
|
readVoluteConfig,
|
|
2762
2683
|
writeVoluteConfig,
|
|
2763
|
-
stopAllWatchers,
|
|
2764
|
-
getCachedSites,
|
|
2765
|
-
getCachedRecentPages,
|
|
2766
2684
|
splitMessage,
|
|
2767
2685
|
writeChannelEntry,
|
|
2768
2686
|
resolveChannelId,
|
|
@@ -2788,6 +2706,10 @@ export {
|
|
|
2788
2706
|
initDeliveryManager,
|
|
2789
2707
|
getDeliveryManager,
|
|
2790
2708
|
recordInbound,
|
|
2709
|
+
resolveSleepAction,
|
|
2791
2710
|
deliverMessage,
|
|
2711
|
+
readSystemsConfig,
|
|
2712
|
+
writeSystemsConfig,
|
|
2713
|
+
deleteSystemsConfig,
|
|
2792
2714
|
initMailPoller
|
|
2793
2715
|
};
|