volute 0.28.0 → 0.30.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 +127 -18
- package/dist/{accept-666DIZX2.js → accept-E3PAH3QJ.js} +2 -2
- package/dist/{activity-events-BBIEA2F4.js → activity-events-BKBPPUBP.js} +2 -2
- package/dist/ai-service-VAJT5UBS.js +29 -0
- package/dist/api.d.ts +586 -529
- package/dist/{archive-UA4BDFXQ.js → archive-WWDBWYN2.js} +2 -2
- package/dist/{bridge-FQHZL3MC.js → bridge-RO37CUFM.js} +2 -2
- package/dist/{chat-M4SX42JD.js → chat-TCUNPFGO.js} +8 -8
- package/dist/{chunk-IAYBDWVG.js → chunk-2C2VXEBB.js} +147 -2
- package/dist/chunk-2NDZC3S7.js +1330 -0
- package/dist/{chunk-IKRVFPWU.js → chunk-7D47T4RB.js} +3 -2
- package/dist/chunk-A6TUJJ3L.js +19 -0
- package/dist/{chunk-AW7PFDVN.js → chunk-CVH6Y2YG.js} +1 -1
- package/dist/{chunk-XBLSAVJF.js → chunk-DTC6EH5I.js} +1 -1
- package/dist/chunk-EFP3PE6C.js +232 -0
- package/dist/{chunk-JGFVMROS.js → chunk-EFVHR7KH.js} +1 -1
- package/dist/{chunk-K5NAC55T.js → chunk-FSM45XD5.js} +2 -2
- package/dist/{chunk-LAC664WU.js → chunk-FXHXHI2A.js} +42 -24
- package/dist/{chunk-RKQEHRBB.js → chunk-G3GBKZGG.js} +1 -1
- package/dist/{chunk-H7OZRFJB.js → chunk-HHTXM4JT.js} +0 -49
- package/dist/{chunk-J4IBNXGJ.js → chunk-IKHDUZRH.js} +4 -3
- package/dist/{chunk-MD4C26II.js → chunk-JGFRDMR6.js} +1 -1
- package/dist/{chunk-POSXWWTA.js → chunk-LIRWLNAK.js} +26 -12
- package/dist/{chunk-NI5FFCCS.js → chunk-MDPCSXZ4.js} +35 -11
- package/dist/chunk-NSBFETWP.js +188 -0
- package/dist/{chunk-VIVMW2H2.js → chunk-P27RV5WM.js} +1 -1
- package/dist/{chunk-EHYDTZTF.js → chunk-P7VFDSSG.js} +2 -2
- package/dist/{chunk-AAPXKR5V.js → chunk-QVAQ5454.js} +181 -544
- package/dist/{chunk-HDN7MNGD.js → chunk-S5LR3XYJ.js} +1 -1
- package/dist/{chunk-2YP2TVDT.js → chunk-UPA6COHU.js} +5 -5
- package/dist/{chunk-AKPFNL7L.js → chunk-VGWJSNHS.js} +1 -1
- package/dist/{chunk-SGVNFZHW.js → chunk-W5OOPLNP.js} +3 -3
- package/dist/{chunk-2WPW7OT6.js → chunk-ZWKTUQEL.js} +1 -1
- package/dist/cli.js +25 -26
- package/dist/clock-G3ALCMLJ.js +263 -0
- package/dist/{cloud-sync-HDL6PHZI.js → cloud-sync-JV4LJOK3.js} +14 -12
- 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-7KVQV7EZ.js} +9 -3
- package/dist/create-JTLS7GX3.js +70 -0
- package/dist/{create-QWV73WXD.js → create-VQSQHJQW.js} +1 -1
- package/dist/{daemon-client-I42FK2BF.js → daemon-client-BCTFGVCZ.js} +2 -2
- package/dist/{daemon-restart-G4B2OYAB.js → daemon-restart-4JGBHEJ4.js} +7 -7
- package/dist/daemon.js +1474 -1124
- package/dist/{db-IC4J52XQ.js → db-HMFPIRO2.js} +1 -1
- package/dist/{delete-4JYGD4VN.js → delete-JESHKE7F.js} +1 -1
- package/dist/down-NGBMGORS.js +14 -0
- package/dist/{env-YJMUMFIY.js → env-CLXXT7M2.js} +2 -2
- package/dist/{export-BOJQWBMA.js → export-EGA5M5PB.js} +3 -3
- package/dist/extension-WZ4SUPJB.js +174 -0
- package/dist/extensions-ECO4RPFQ.js +27 -0
- package/dist/{files-M546TKVN.js → files-4VEJDASH.js} +3 -3
- package/dist/{history-ALPTNB3I.js → history-EJMMLXDO.js} +17 -2
- package/dist/{import-SRTQXBGH.js → import-YCGPMBSI.js} +3 -3
- package/dist/{join-J4QU42DL.js → join-2GBJKZEN.js} +1 -1
- package/dist/{list-R73GENNL.js → list-Q6O7FGAN.js} +2 -2
- package/dist/{login-3QZNR2DF.js → login-RET5WESK.js} +2 -2
- package/dist/{login-BKP3AFWN.js → login-RL6AU2SM.js} +3 -3
- package/dist/{logout-T53VKCPU.js → logout-CGAGJN3L.js} +2 -2
- package/dist/{logout-IQK7FNEK.js → logout-JRPBEMMR.js} +3 -3
- package/dist/message-delivery-6YMVNOEC.js +28 -0
- package/dist/{migrate-registry-to-db-XC7T5B7P.js → migrate-registry-to-db-FK35IPEH.js} +1 -1
- package/dist/{mind-S5V6CK5W.js → mind-LUWRQUQ5.js} +17 -17
- package/dist/{mind-activity-tracker-EN6XNXPF.js → mind-activity-tracker-VYN2ZZ2M.js} +3 -3
- package/dist/{mind-list-UPJ75GPI.js → mind-list-V5WW5DUA.js} +2 -2
- package/dist/{mind-manager-S6ILZVX3.js → mind-manager-YFCOIAAX.js} +6 -6
- package/dist/{mind-sleep-BTSWQNAC.js → mind-sleep-R6PTNNW4.js} +2 -2
- package/dist/{mind-status-TK5AETEM.js → mind-status-I4ISFJ6I.js} +2 -2
- package/dist/{mind-wake-SBAKIDVP.js → mind-wake-67ZQEWAV.js} +2 -2
- package/dist/{package-CG4RWUGP.js → package-S2OAA5ZA.js} +11 -5
- package/dist/pages-watcher-Z3PKNROC.js +21 -0
- package/dist/{read-36UFXN3G.js → read-WQMPTSN2.js} +2 -2
- package/dist/{register-CHREOMJ3.js → register-NZDSTLP3.js} +3 -3
- package/dist/{registry-NDNOOYG4.js → registry-ODSALQQL.js} +1 -1
- package/dist/{reject-LXIZFJ4Q.js → reject-2HZOJEIJ.js} +2 -2
- package/dist/{restart-6ESL3NBO.js → restart-QHS3NT64.js} +2 -2
- package/dist/{sandbox-5BW5HPXM.js → sandbox-O5FUSF43.js} +3 -3
- package/dist/{seed-SSUCYYDF.js → seed-WUQMPLDM.js} +1 -1
- package/dist/{send-TAOEZ4NH.js → send-OAN3RYYY.js} +20 -6
- package/dist/{setup-JHL5ZEST.js → setup-QMDK5RZX.js} +2 -2
- package/dist/{setup-RXYVGGT7.js → setup-XJH3E7YM.js} +45 -14
- package/dist/{skill-AUAQTSP5.js → skill-FZIN4W4Q.js} +65 -3
- package/dist/skills/dreaming/references/INSTALL.md +3 -17
- package/dist/skills/volute-mind/SKILL.md +45 -27
- package/dist/sleep-manager-O7YQFCV5.js +30 -0
- package/dist/{split-TKJ5OT3P.js → split-EXYGGGQN.js} +1 -1
- package/dist/{sprout-UNT7LKKE.js → sprout-AXQ6H5DB.js} +8 -7
- package/dist/{start-EUJSS5R4.js → start-MTOVL6SY.js} +2 -2
- package/dist/{status-NQJYR4BG.js → status-ZRO37MWR.js} +5 -5
- package/dist/{stop-3XAITBBF.js → stop-OK5WEPVC.js} +2 -2
- package/dist/{systems-SMEFSHTA.js → systems-W3BBMSOZ.js} +5 -5
- package/dist/{tailscale-NY5MUMY3.js → tailscale-BM72RXCJ.js} +1 -1
- package/dist/{template-hash-BIMA4ILT.js → template-hash-3HOR4UAJ.js} +1 -1
- package/dist/up-BXUAIDXB.js +17 -0
- package/dist/{update-PTSH22AZ.js → update-PLPHMMZ2.js} +5 -5
- package/dist/{update-check-64FWC4Y2.js → update-check-CVCN7MF6.js} +2 -2
- package/dist/{upgrade-HA47CS4C.js → upgrade-I6NPCYUU.js} +1 -1
- package/dist/{version-notify-JDUF4HQJ.js → version-notify-2NTWVEHL.js} +18 -16
- package/dist/web-assets/assets/index--kREqKl9.js +72 -0
- package/dist/web-assets/assets/index-BXYTG0nJ.css +1 -0
- package/dist/web-assets/ext-theme.css +111 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +11 -5
- package/packages/extensions/notes/dist/ui/assets/index-DgawVO5g.css +1 -0
- package/packages/extensions/notes/dist/ui/assets/index-qUWoeC4c.js +2 -0
- package/packages/extensions/notes/dist/ui/index.html +14 -0
- package/packages/extensions/notes/skills/notes/SKILL.md +62 -0
- package/packages/extensions/notes/skills/notes/scripts/notes.mjs +185 -0
- package/packages/extensions/pages/dist/ui/assets/index-D0HyS-xQ.css +1 -0
- package/packages/extensions/pages/dist/ui/assets/index-tLTROSk5.js +2 -0
- package/packages/extensions/pages/dist/ui/index.html +14 -0
- package/packages/extensions/pages/skills/pages/SKILL.md +58 -0
- package/templates/_base/home/VOLUTE.md +1 -1
- package/templates/_base/src/lib/logger.ts +10 -49
- 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/chunk-P72MVS4R.js +0 -188
- package/dist/chunk-T6HKBWXZ.js +0 -23
- package/dist/chunk-ZYGKG6VC.js +0 -22
- package/dist/create-D7J73A6H.js +0 -45
- package/dist/down-LVBXEULC.js +0 -14
- package/dist/message-delivery-HV3S6HZV.js +0 -24
- package/dist/notes-XCER3I7M.js +0 -220
- package/dist/pages-KJDJX4TA.js +0 -36
- package/dist/publish-ZZB33WP4.js +0 -86
- package/dist/schedule-QTJMFATP.js +0 -154
- package/dist/skills/notes/SKILL.md +0 -34
- package/dist/sleep-manager-WMVG2VCL.js +0 -28
- package/dist/status-S7UUPNRW.js +0 -38
- package/dist/up-GM2JOH2Y.js +0 -17
- package/dist/web-assets/assets/index-BZGvToHi.css +0 -1
- package/dist/web-assets/assets/index-Cz4TrpzB.js +0 -75
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
voluteHome,
|
|
4
4
|
voluteSystemDir
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HHTXM4JT.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/setup.ts
|
|
8
8
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -25,7 +25,8 @@ function readGlobalConfig() {
|
|
|
25
25
|
function writeGlobalConfig(config) {
|
|
26
26
|
const path = configPath();
|
|
27
27
|
mkdirSync(voluteSystemDir(), { recursive: true });
|
|
28
|
-
writeFileSync(path, JSON.stringify(config, null, 2)
|
|
28
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
29
|
+
`);
|
|
29
30
|
}
|
|
30
31
|
function isSetupComplete() {
|
|
31
32
|
const config = readGlobalConfig();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/lib/slugify.ts
|
|
4
|
+
function slugify(text) {
|
|
5
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
6
|
+
}
|
|
7
|
+
function buildVoluteSlug(opts) {
|
|
8
|
+
if (opts.convType === "channel" && opts.convName) {
|
|
9
|
+
return `volute:#${opts.convName}`;
|
|
10
|
+
}
|
|
11
|
+
const other = opts.participants.find((p) => p.username !== opts.mindUsername);
|
|
12
|
+
const otherSlug = other ? slugify(other.username) : "";
|
|
13
|
+
return otherSlug ? `volute:@${otherSlug}` : `volute:${opts.conversationId}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
slugify,
|
|
18
|
+
buildVoluteSlug
|
|
19
|
+
};
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
publish
|
|
4
|
+
} from "./chunk-P27RV5WM.js";
|
|
5
|
+
import {
|
|
6
|
+
logger_default
|
|
7
|
+
} from "./chunk-YUIHSKR6.js";
|
|
8
|
+
import {
|
|
9
|
+
mindDir,
|
|
10
|
+
readRegistry,
|
|
11
|
+
voluteHome
|
|
12
|
+
} from "./chunk-HHTXM4JT.js";
|
|
13
|
+
|
|
14
|
+
// src/lib/pages-watcher.ts
|
|
15
|
+
import { existsSync, readdirSync, statSync, watch } from "fs";
|
|
16
|
+
import { join, resolve } from "path";
|
|
17
|
+
var watchers = /* @__PURE__ */ new Map();
|
|
18
|
+
var homeWatchers = /* @__PURE__ */ new Map();
|
|
19
|
+
var debounceTimers = /* @__PURE__ */ new Map();
|
|
20
|
+
var sitesCache = null;
|
|
21
|
+
var recentPagesCache = null;
|
|
22
|
+
function startPagesWatcher(mindName, pagesDir) {
|
|
23
|
+
try {
|
|
24
|
+
const watcher = watch(pagesDir, { recursive: true }, (_eventType, filename) => {
|
|
25
|
+
if (!filename || !filename.endsWith(".html")) return;
|
|
26
|
+
const key = `${mindName}:${filename}`;
|
|
27
|
+
const existing = debounceTimers.get(key);
|
|
28
|
+
if (existing) clearTimeout(existing);
|
|
29
|
+
debounceTimers.set(
|
|
30
|
+
key,
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
debounceTimers.delete(key);
|
|
33
|
+
invalidateCache();
|
|
34
|
+
publish({
|
|
35
|
+
type: "page_updated",
|
|
36
|
+
mind: mindName,
|
|
37
|
+
summary: `${mindName} updated ${filename}`,
|
|
38
|
+
metadata: { file: filename }
|
|
39
|
+
}).catch(
|
|
40
|
+
(err) => logger_default.error("failed to publish page_updated activity", logger_default.errorData(err))
|
|
41
|
+
);
|
|
42
|
+
}, 100)
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
watchers.set(mindName, watcher);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
logger_default.warn(`failed to start pages watcher for ${mindName}`, logger_default.errorData(err));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function startSystemWatcher() {
|
|
51
|
+
if (watchers.has("_system")) return;
|
|
52
|
+
const systemPagesDir = resolve(voluteHome(), "shared", "pages");
|
|
53
|
+
if (!existsSync(systemPagesDir)) return;
|
|
54
|
+
startPagesWatcher("_system", systemPagesDir);
|
|
55
|
+
}
|
|
56
|
+
function startWatcher(mindName) {
|
|
57
|
+
if (watchers.has(mindName)) return;
|
|
58
|
+
const pagesDir = resolve(mindDir(mindName), "home", "public", "pages");
|
|
59
|
+
if (existsSync(pagesDir)) {
|
|
60
|
+
startPagesWatcher(mindName, pagesDir);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (homeWatchers.has(mindName)) return;
|
|
64
|
+
const publicDir = resolve(mindDir(mindName), "home", "public");
|
|
65
|
+
if (!existsSync(publicDir)) return;
|
|
66
|
+
try {
|
|
67
|
+
const hw = watch(publicDir, (_eventType, filename) => {
|
|
68
|
+
if (filename !== "pages") return;
|
|
69
|
+
if (!existsSync(pagesDir)) return;
|
|
70
|
+
hw.close();
|
|
71
|
+
homeWatchers.delete(mindName);
|
|
72
|
+
invalidateCache();
|
|
73
|
+
startPagesWatcher(mindName, pagesDir);
|
|
74
|
+
});
|
|
75
|
+
homeWatchers.set(mindName, hw);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
logger_default.warn(`failed to start home watcher for ${mindName}`, logger_default.errorData(err));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function stopWatcher(mindName) {
|
|
81
|
+
const watcher = watchers.get(mindName);
|
|
82
|
+
if (watcher) {
|
|
83
|
+
watcher.close();
|
|
84
|
+
watchers.delete(mindName);
|
|
85
|
+
}
|
|
86
|
+
const hw = homeWatchers.get(mindName);
|
|
87
|
+
if (hw) {
|
|
88
|
+
hw.close();
|
|
89
|
+
homeWatchers.delete(mindName);
|
|
90
|
+
}
|
|
91
|
+
for (const [key, timer] of debounceTimers) {
|
|
92
|
+
if (key.startsWith(`${mindName}:`)) {
|
|
93
|
+
clearTimeout(timer);
|
|
94
|
+
debounceTimers.delete(key);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function stopAllWatchers() {
|
|
99
|
+
for (const [, watcher] of watchers) {
|
|
100
|
+
watcher.close();
|
|
101
|
+
}
|
|
102
|
+
watchers.clear();
|
|
103
|
+
for (const [, hw] of homeWatchers) {
|
|
104
|
+
hw.close();
|
|
105
|
+
}
|
|
106
|
+
homeWatchers.clear();
|
|
107
|
+
for (const [, timer] of debounceTimers) {
|
|
108
|
+
clearTimeout(timer);
|
|
109
|
+
}
|
|
110
|
+
debounceTimers.clear();
|
|
111
|
+
invalidateCache();
|
|
112
|
+
}
|
|
113
|
+
function invalidateCache() {
|
|
114
|
+
sitesCache = null;
|
|
115
|
+
recentPagesCache = null;
|
|
116
|
+
}
|
|
117
|
+
function scanPagesDir(dir, urlPrefix) {
|
|
118
|
+
const pages = [];
|
|
119
|
+
let items;
|
|
120
|
+
try {
|
|
121
|
+
items = readdirSync(dir);
|
|
122
|
+
} catch {
|
|
123
|
+
return pages;
|
|
124
|
+
}
|
|
125
|
+
for (const item of items) {
|
|
126
|
+
if (item.startsWith(".")) continue;
|
|
127
|
+
const fullPath = resolve(dir, item);
|
|
128
|
+
try {
|
|
129
|
+
const s = statSync(fullPath);
|
|
130
|
+
if (s.isFile() && item.endsWith(".html")) {
|
|
131
|
+
pages.push({
|
|
132
|
+
file: item,
|
|
133
|
+
modified: s.mtime.toISOString(),
|
|
134
|
+
url: `${urlPrefix}/${item}`
|
|
135
|
+
});
|
|
136
|
+
} else if (s.isDirectory()) {
|
|
137
|
+
const indexPath = resolve(fullPath, "index.html");
|
|
138
|
+
if (existsSync(indexPath)) {
|
|
139
|
+
const indexStat = statSync(indexPath);
|
|
140
|
+
pages.push({
|
|
141
|
+
file: join(item, "index.html"),
|
|
142
|
+
modified: indexStat.mtime.toISOString(),
|
|
143
|
+
url: `${urlPrefix}/${item}/`
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
pages.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
|
|
151
|
+
return pages;
|
|
152
|
+
}
|
|
153
|
+
async function buildSites() {
|
|
154
|
+
const sites = [];
|
|
155
|
+
const systemPagesDir = resolve(voluteHome(), "shared", "pages");
|
|
156
|
+
if (existsSync(systemPagesDir)) {
|
|
157
|
+
const systemPages = scanPagesDir(systemPagesDir, "/pages/_system");
|
|
158
|
+
if (systemPages.length > 0) {
|
|
159
|
+
sites.push({ name: "_system", label: "System", pages: systemPages });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const entries = await readRegistry();
|
|
163
|
+
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
164
|
+
const pagesDir = resolve(mindDir(entry.name), "home", "public", "pages");
|
|
165
|
+
if (!existsSync(pagesDir)) continue;
|
|
166
|
+
const mindPages = scanPagesDir(pagesDir, `/minds/${entry.name}/pages`);
|
|
167
|
+
if (mindPages.length > 0) {
|
|
168
|
+
sites.push({ name: entry.name, label: entry.name, pages: mindPages });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return sites;
|
|
172
|
+
}
|
|
173
|
+
async function buildRecentPages() {
|
|
174
|
+
const entries = await readRegistry();
|
|
175
|
+
const pages = [];
|
|
176
|
+
for (const entry of entries) {
|
|
177
|
+
const pagesDir = resolve(mindDir(entry.name), "home", "public", "pages");
|
|
178
|
+
if (!existsSync(pagesDir)) continue;
|
|
179
|
+
let items;
|
|
180
|
+
try {
|
|
181
|
+
items = readdirSync(pagesDir);
|
|
182
|
+
} catch {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
for (const item of items) {
|
|
186
|
+
if (item.startsWith(".")) continue;
|
|
187
|
+
const fullPath = resolve(pagesDir, item);
|
|
188
|
+
try {
|
|
189
|
+
const s = statSync(fullPath);
|
|
190
|
+
if (s.isFile() && item.endsWith(".html")) {
|
|
191
|
+
pages.push({
|
|
192
|
+
mind: entry.name,
|
|
193
|
+
file: item,
|
|
194
|
+
modified: s.mtime.toISOString(),
|
|
195
|
+
url: `/minds/${entry.name}/pages/${item}`
|
|
196
|
+
});
|
|
197
|
+
} else if (s.isDirectory()) {
|
|
198
|
+
const indexPath = resolve(fullPath, "index.html");
|
|
199
|
+
if (existsSync(indexPath)) {
|
|
200
|
+
const indexStat = statSync(indexPath);
|
|
201
|
+
pages.push({
|
|
202
|
+
mind: entry.name,
|
|
203
|
+
file: join(item, "index.html"),
|
|
204
|
+
modified: indexStat.mtime.toISOString(),
|
|
205
|
+
url: `/minds/${entry.name}/pages/${item}/`
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
pages.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
|
|
214
|
+
return pages.slice(0, 10);
|
|
215
|
+
}
|
|
216
|
+
async function getCachedSites() {
|
|
217
|
+
if (!sitesCache) sitesCache = await buildSites();
|
|
218
|
+
return sitesCache;
|
|
219
|
+
}
|
|
220
|
+
async function getCachedRecentPages() {
|
|
221
|
+
if (!recentPagesCache) recentPagesCache = await buildRecentPages();
|
|
222
|
+
return recentPagesCache;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export {
|
|
226
|
+
startSystemWatcher,
|
|
227
|
+
startWatcher,
|
|
228
|
+
stopWatcher,
|
|
229
|
+
stopAllWatchers,
|
|
230
|
+
getCachedSites,
|
|
231
|
+
getCachedRecentPages
|
|
232
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
publish
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-P27RV5WM.js";
|
|
5
5
|
import {
|
|
6
6
|
logger_default
|
|
7
7
|
} from "./chunk-YUIHSKR6.js";
|
|
8
8
|
|
|
9
9
|
// src/lib/events/mind-activity-tracker.ts
|
|
10
|
-
var IDLE_TIMEOUT_MS =
|
|
10
|
+
var IDLE_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
11
11
|
var minds = /* @__PURE__ */ new Map();
|
|
12
12
|
function getState(mind) {
|
|
13
13
|
let state = minds.get(mind);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
exec,
|
|
3
4
|
execInherit
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-CVH6Y2YG.js";
|
|
5
6
|
import {
|
|
6
7
|
voluteHome,
|
|
7
8
|
voluteSystemDir
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HHTXM4JT.js";
|
|
9
10
|
|
|
10
11
|
// src/lib/service-mode.ts
|
|
11
12
|
import { execFileSync } from "child_process";
|
|
@@ -98,11 +99,25 @@ async function startService(mode) {
|
|
|
98
99
|
await execInherit("systemctl", ["--user", "start", "volute"]);
|
|
99
100
|
break;
|
|
100
101
|
case "system-launchd":
|
|
101
|
-
await
|
|
102
|
+
await exec("sudo", ["launchctl", "bootout", `system/${LAUNCHD_PLIST_LABEL}`]).catch(
|
|
103
|
+
(err) => console.warn(
|
|
104
|
+
`Warning: launchctl bootout failed (may not be loaded): ${err instanceof Error ? err.message : err}`
|
|
105
|
+
)
|
|
106
|
+
);
|
|
107
|
+
await execInherit("sudo", ["launchctl", "bootstrap", "system", SYSTEM_LAUNCHD_PLIST_PATH]);
|
|
108
|
+
await execInherit("sudo", ["launchctl", "kickstart", `system/${LAUNCHD_PLIST_LABEL}`]);
|
|
102
109
|
break;
|
|
103
|
-
case "user-launchd":
|
|
104
|
-
|
|
110
|
+
case "user-launchd": {
|
|
111
|
+
const uid = `gui/${process.getuid()}`;
|
|
112
|
+
await exec("launchctl", ["bootout", `${uid}/${LAUNCHD_PLIST_LABEL}`]).catch(
|
|
113
|
+
(err) => console.warn(
|
|
114
|
+
`Warning: launchctl bootout failed (may not be loaded): ${err instanceof Error ? err.message : err}`
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
await execInherit("launchctl", ["bootstrap", uid, LAUNCHD_PLIST_PATH]);
|
|
118
|
+
await execInherit("launchctl", ["kickstart", `${uid}/${LAUNCHD_PLIST_LABEL}`]);
|
|
105
119
|
break;
|
|
120
|
+
}
|
|
106
121
|
}
|
|
107
122
|
}
|
|
108
123
|
async function stopService(mode) {
|
|
@@ -114,10 +129,13 @@ async function stopService(mode) {
|
|
|
114
129
|
await execInherit("systemctl", ["--user", "stop", "volute"]);
|
|
115
130
|
break;
|
|
116
131
|
case "system-launchd":
|
|
117
|
-
await execInherit("sudo", ["launchctl", "
|
|
132
|
+
await execInherit("sudo", ["launchctl", "bootout", `system/${LAUNCHD_PLIST_LABEL}`]);
|
|
118
133
|
break;
|
|
119
134
|
case "user-launchd":
|
|
120
|
-
await execInherit("launchctl", [
|
|
135
|
+
await execInherit("launchctl", [
|
|
136
|
+
"bootout",
|
|
137
|
+
`gui/${process.getuid()}/${LAUNCHD_PLIST_LABEL}`
|
|
138
|
+
]);
|
|
121
139
|
break;
|
|
122
140
|
}
|
|
123
141
|
}
|
|
@@ -130,25 +148,25 @@ async function restartService(mode) {
|
|
|
130
148
|
await execInherit("systemctl", ["--user", "restart", "volute"]);
|
|
131
149
|
break;
|
|
132
150
|
case "system-launchd":
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
await execInherit("sudo", ["launchctl", "load", SYSTEM_LAUNCHD_PLIST_PATH]);
|
|
151
|
+
await exec("sudo", ["launchctl", "bootout", `system/${LAUNCHD_PLIST_LABEL}`]).catch(
|
|
152
|
+
(err) => console.warn(
|
|
153
|
+
`Warning: launchctl bootout failed (may not be loaded): ${err instanceof Error ? err.message : err}`
|
|
154
|
+
)
|
|
155
|
+
);
|
|
156
|
+
await execInherit("sudo", ["launchctl", "bootstrap", "system", SYSTEM_LAUNCHD_PLIST_PATH]);
|
|
157
|
+
await execInherit("sudo", ["launchctl", "kickstart", `system/${LAUNCHD_PLIST_LABEL}`]);
|
|
141
158
|
break;
|
|
142
|
-
case "user-launchd":
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
await execInherit("launchctl", ["
|
|
159
|
+
case "user-launchd": {
|
|
160
|
+
const uid = `gui/${process.getuid()}`;
|
|
161
|
+
await exec("launchctl", ["bootout", `${uid}/${LAUNCHD_PLIST_LABEL}`]).catch(
|
|
162
|
+
(err) => console.warn(
|
|
163
|
+
`Warning: launchctl bootout failed (may not be loaded): ${err instanceof Error ? err.message : err}`
|
|
164
|
+
)
|
|
165
|
+
);
|
|
166
|
+
await execInherit("launchctl", ["bootstrap", uid, LAUNCHD_PLIST_PATH]);
|
|
167
|
+
await execInherit("launchctl", ["kickstart", `${uid}/${LAUNCHD_PLIST_LABEL}`]);
|
|
151
168
|
break;
|
|
169
|
+
}
|
|
152
170
|
}
|
|
153
171
|
}
|
|
154
172
|
function readDaemonConfig() {
|
|
@@ -28,9 +28,6 @@ __export(schema_exports, {
|
|
|
28
28
|
messages: () => messages,
|
|
29
29
|
mindHistory: () => mindHistory,
|
|
30
30
|
minds: () => minds,
|
|
31
|
-
noteComments: () => noteComments,
|
|
32
|
-
noteReactions: () => noteReactions,
|
|
33
|
-
notes: () => notes,
|
|
34
31
|
sessions: () => sessions,
|
|
35
32
|
sharedSkills: () => sharedSkills,
|
|
36
33
|
systemPrompts: () => systemPrompts,
|
|
@@ -180,49 +177,6 @@ var conversationReads = sqliteTable(
|
|
|
180
177
|
uniqueIndex("idx_conversation_reads_unique").on(table.user_id, table.conversation_id)
|
|
181
178
|
]
|
|
182
179
|
);
|
|
183
|
-
var notes = sqliteTable(
|
|
184
|
-
"notes",
|
|
185
|
-
{
|
|
186
|
-
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
187
|
-
author_id: integer("author_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
188
|
-
title: text("title").notNull(),
|
|
189
|
-
slug: text("slug").notNull(),
|
|
190
|
-
content: text("content").notNull(),
|
|
191
|
-
reply_to_id: integer("reply_to_id"),
|
|
192
|
-
created_at: text("created_at").notNull().default(sql`(datetime('now'))`),
|
|
193
|
-
updated_at: text("updated_at").notNull().default(sql`(datetime('now'))`)
|
|
194
|
-
},
|
|
195
|
-
(table) => [
|
|
196
|
-
uniqueIndex("idx_notes_author_slug").on(table.author_id, table.slug),
|
|
197
|
-
index("idx_notes_created_at").on(table.created_at),
|
|
198
|
-
index("idx_notes_reply_to").on(table.reply_to_id)
|
|
199
|
-
]
|
|
200
|
-
);
|
|
201
|
-
var noteComments = sqliteTable(
|
|
202
|
-
"note_comments",
|
|
203
|
-
{
|
|
204
|
-
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
205
|
-
note_id: integer("note_id").notNull().references(() => notes.id, { onDelete: "cascade" }),
|
|
206
|
-
author_id: integer("author_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
207
|
-
content: text("content").notNull(),
|
|
208
|
-
created_at: text("created_at").notNull().default(sql`(datetime('now'))`)
|
|
209
|
-
},
|
|
210
|
-
(table) => [index("idx_note_comments_note_id").on(table.note_id)]
|
|
211
|
-
);
|
|
212
|
-
var noteReactions = sqliteTable(
|
|
213
|
-
"note_reactions",
|
|
214
|
-
{
|
|
215
|
-
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
216
|
-
note_id: integer("note_id").notNull().references(() => notes.id, { onDelete: "cascade" }),
|
|
217
|
-
user_id: integer("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
218
|
-
emoji: text("emoji").notNull(),
|
|
219
|
-
created_at: text("created_at").notNull().default(sql`(datetime('now'))`)
|
|
220
|
-
},
|
|
221
|
-
(table) => [
|
|
222
|
-
uniqueIndex("idx_note_reactions_unique").on(table.note_id, table.user_id, table.emoji),
|
|
223
|
-
index("idx_note_reactions_note_id").on(table.note_id)
|
|
224
|
-
]
|
|
225
|
-
);
|
|
226
180
|
var messages = sqliteTable(
|
|
227
181
|
"messages",
|
|
228
182
|
{
|
|
@@ -403,9 +357,6 @@ export {
|
|
|
403
357
|
deliveryQueue,
|
|
404
358
|
activity,
|
|
405
359
|
conversationReads,
|
|
406
|
-
notes,
|
|
407
|
-
noteComments,
|
|
408
|
-
noteReactions,
|
|
409
360
|
messages,
|
|
410
361
|
getDb,
|
|
411
362
|
voluteHome,
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
} from "./chunk-YUIHSKR6.js";
|
|
5
5
|
import {
|
|
6
6
|
readGlobalConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7D47T4RB.js";
|
|
8
8
|
import {
|
|
9
9
|
getBaseName,
|
|
10
10
|
readRegistry,
|
|
11
11
|
voluteHome,
|
|
12
12
|
voluteSystemDir,
|
|
13
13
|
voluteUserHome
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-HHTXM4JT.js";
|
|
15
15
|
|
|
16
16
|
// src/lib/sandbox.ts
|
|
17
17
|
import { resolve } from "path";
|
|
@@ -29,7 +29,8 @@ async function initSandbox() {
|
|
|
29
29
|
network: {
|
|
30
30
|
allowedDomains: ["*"],
|
|
31
31
|
deniedDomains: [],
|
|
32
|
-
allowLocalBinding: true
|
|
32
|
+
allowLocalBinding: true,
|
|
33
|
+
allowAllUnixSockets: true
|
|
33
34
|
},
|
|
34
35
|
filesystem: {
|
|
35
36
|
denyRead: [],
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
isSandboxEnabled,
|
|
4
4
|
wrapForSandbox
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-IKHDUZRH.js";
|
|
6
6
|
import {
|
|
7
7
|
loadMergedEnv
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ZWKTUQEL.js";
|
|
9
9
|
import {
|
|
10
10
|
logger_default
|
|
11
11
|
} from "./chunk-YUIHSKR6.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
chownMindDir,
|
|
14
14
|
isIsolationEnabled,
|
|
15
15
|
wrapForIsolation
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-G3GBKZGG.js";
|
|
17
17
|
import {
|
|
18
18
|
findMind,
|
|
19
19
|
getDb,
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
stateDir,
|
|
24
24
|
systemPrompts,
|
|
25
25
|
voluteSystemDir
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-HHTXM4JT.js";
|
|
27
27
|
|
|
28
28
|
// src/lib/daemon/mind-manager.ts
|
|
29
29
|
import { execFile, spawn } from "child_process";
|
|
@@ -82,7 +82,8 @@ var PROMPT_KEYS = [
|
|
|
82
82
|
"reply_instructions",
|
|
83
83
|
"channel_invite",
|
|
84
84
|
"pre_sleep",
|
|
85
|
-
"wake_summary"
|
|
85
|
+
"wake_summary",
|
|
86
|
+
"turn_summary"
|
|
86
87
|
];
|
|
87
88
|
var PROMPT_DEFAULTS = {
|
|
88
89
|
seed_soul: {
|
|
@@ -99,7 +100,10 @@ Have a conversation with the human. Explore what kind of mind you want to be. Wh
|
|
|
99
100
|
default_soul: {
|
|
100
101
|
content: `You are {{name}}.
|
|
101
102
|
`,
|
|
102
|
-
description:
|
|
103
|
+
description: (
|
|
104
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: describing template syntax, not using it
|
|
105
|
+
"SOUL.md for sprouted minds. Uses {{name}} placeholder (replaced at creation, not by ${var} system)"
|
|
106
|
+
),
|
|
103
107
|
variables: ["name"],
|
|
104
108
|
category: "creation"
|
|
105
109
|
},
|
|
@@ -172,9 +176,9 @@ To reject, delete \${filePath}`,
|
|
|
172
176
|
category: "mind"
|
|
173
177
|
},
|
|
174
178
|
pre_sleep: {
|
|
175
|
-
content: "Time to rest. You have this turn to wind down however feels right \u2014 reflect on your day, update your journal or memory, finish any threads of thought, or simply settle.\n\nYour current session will be archived and a fresh one will begin when you wake. Anything in session context that isn't saved to files will be lost.\n\nYou'll wake at ${wakeTime}.
|
|
179
|
+
content: "Time to rest. You have this turn to wind down however feels right \u2014 reflect on your day, update your journal or memory, finish any threads of thought, or simply settle.\n\nYour current session will be archived and a fresh one will begin when you wake. Anything in session context that isn't saved to files will be lost.\n\nYou'll wake at ${wakeTime}.",
|
|
176
180
|
description: "Pre-sleep message sent before stopping the mind",
|
|
177
|
-
variables: ["wakeTime"
|
|
181
|
+
variables: ["wakeTime"],
|
|
178
182
|
category: "system"
|
|
179
183
|
},
|
|
180
184
|
wake_summary: {
|
|
@@ -182,6 +186,12 @@ To reject, delete \${filePath}`,
|
|
|
182
186
|
description: "Wake-up summary after scheduled sleep",
|
|
183
187
|
variables: ["currentDate", "sleepTime", "duration", "sleepActivity"],
|
|
184
188
|
category: "system"
|
|
189
|
+
},
|
|
190
|
+
turn_summary: {
|
|
191
|
+
content: "Summarize what this AI mind did in this turn in 1-2 concise sentences. Focus on what was accomplished, not the mechanics.",
|
|
192
|
+
description: "System prompt for AI-generated turn summaries",
|
|
193
|
+
variables: [],
|
|
194
|
+
category: "system"
|
|
185
195
|
}
|
|
186
196
|
};
|
|
187
197
|
function isValidKey(key) {
|
|
@@ -456,7 +466,11 @@ var MindManager = class {
|
|
|
456
466
|
if (isIsolationEnabled()) {
|
|
457
467
|
[spawnCmd, spawnArgs] = await wrapForIsolation(tsxBin, tsxArgs, name);
|
|
458
468
|
} else if (isSandboxEnabled()) {
|
|
459
|
-
[spawnCmd, spawnArgs] = await wrapForSandbox(tsxBin, tsxArgs, dir, name
|
|
469
|
+
[spawnCmd, spawnArgs] = await wrapForSandbox(tsxBin, tsxArgs, dir, name, [
|
|
470
|
+
dir,
|
|
471
|
+
mindStateDir,
|
|
472
|
+
"/tmp"
|
|
473
|
+
]);
|
|
460
474
|
} else {
|
|
461
475
|
spawnCmd = tsxBin;
|
|
462
476
|
spawnArgs = tsxArgs;
|
|
@@ -568,7 +582,7 @@ var MindManager = class {
|
|
|
568
582
|
if (this.shuttingDown || this.stopping.has(name)) return;
|
|
569
583
|
mlog.error(`mind ${name} exited with code ${code}`);
|
|
570
584
|
try {
|
|
571
|
-
const { getSleepManagerIfReady } = await import("./sleep-manager-
|
|
585
|
+
const { getSleepManagerIfReady } = await import("./sleep-manager-O7YQFCV5.js");
|
|
572
586
|
const sleepState = getSleepManagerIfReady()?.getState(name);
|
|
573
587
|
if (sleepState?.sleeping) {
|
|
574
588
|
mlog.info(`${name} is sleeping \u2014 skipping crash recovery`);
|
|
@@ -577,8 +591,8 @@ var MindManager = class {
|
|
|
577
591
|
} catch (err) {
|
|
578
592
|
mlog.warn(`failed to check sleep state for ${name}`, logger_default.errorData(err));
|
|
579
593
|
}
|
|
580
|
-
import("./mind-activity-tracker-
|
|
581
|
-
import("./activity-events-
|
|
594
|
+
import("./mind-activity-tracker-VYN2ZZ2M.js").then(({ markIdle }) => markIdle(name)).catch((err) => mlog.warn(`failed to mark ${name} idle after crash`, logger_default.errorData(err)));
|
|
595
|
+
import("./activity-events-BKBPPUBP.js").then(
|
|
582
596
|
({ publish }) => publish({ type: "mind_stopped", mind: name, summary: `${name} crashed (exit ${code})` })
|
|
583
597
|
).catch((err) => mlog.warn(`failed to publish crash event for ${name}`, logger_default.errorData(err)));
|
|
584
598
|
const { shouldRestart, delay, attempt } = this.restartTracker.recordCrash(name);
|