volute 0.31.0 → 0.33.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 +31 -22
- package/dist/{accept-GAKQ3MEH.js → accept-D5VBM7JW.js} +5 -4
- package/dist/{activity-events-T5ZRCVAL.js → activity-events-XJO3P4RR.js} +3 -2
- package/dist/{ai-service-UWUPM4T6.js → ai-service-SBY2WG7O.js} +18 -5
- package/dist/api.d.ts +703 -1068
- package/dist/{archive-YBNSJYZZ.js → archive-INXYFVCW.js} +3 -2
- package/dist/{auth-T5AW2USD.js → auth-GKCDSO4T.js} +4 -3
- package/dist/{bridge-4AJ3EY26.js → bridge-TXWWPPOJ.js} +5 -4
- package/dist/{chat-7YLT7FI3.js → chat-U5ZOME3O.js} +8 -8
- package/dist/{chunk-NV3TYNWX.js → chunk-2NGTS5UU.js} +1 -1
- package/dist/{chunk-BWKIHH7B.js → chunk-3Z2DPESO.js} +662 -508
- package/dist/chunk-6LXAAQ43.js +22 -0
- package/dist/chunk-7J3HEVR7.js +220 -0
- package/dist/{chunk-NOWVQ7AL.js → chunk-A2A4KLFE.js} +351 -301
- package/dist/{chunk-LX6T3GKQ.js → chunk-ALEF47VT.js} +1 -1
- package/dist/{chunk-S2TZLSDH.js → chunk-C7I35G4R.js} +163 -15
- package/dist/{chunk-VGWJSNHS.js → chunk-G53F3JA4.js} +1 -35
- package/dist/{chunk-A6TUJJ3L.js → chunk-G6BSYHPK.js} +2 -2
- package/dist/{chunk-DAXJKPHZ.js → chunk-GY5HBI7A.js} +2 -2
- package/dist/{chunk-BC3P3QCK.js → chunk-I5KY25PQ.js} +1 -9
- package/dist/{chunk-BNC43CSY.js → chunk-JUKK7FPS.js} +2 -2
- package/dist/{chunk-R5QJBZZG.js → chunk-JYVGHWEJ.js} +21 -11
- package/dist/chunk-KIEPMIM5.js +59 -0
- package/dist/{chunk-EKDWA7E4.js → chunk-KVK2DLWI.js} +5 -2
- package/dist/{chunk-AAO77TZX.js → chunk-LOEJ4HPQ.js} +1 -1
- package/dist/chunk-LRCG2JLP.js +251 -0
- package/dist/{chunk-EMPFLFTG.js → chunk-M7UL5S3Q.js} +1 -1
- package/dist/{chunk-6QIUN46C.js → chunk-N432I7QH.js} +20 -3
- package/dist/{chunk-SNVPRRT7.js → chunk-NNB4WIG7.js} +2 -2
- package/dist/{chunk-HDKY4TWU.js → chunk-NPKSDYA2.js} +3 -3
- package/dist/chunk-OYAKCAVY.js +29 -0
- package/dist/chunk-PB65JZK2.js +85 -0
- package/dist/chunk-PVY5W6QN.js +41 -0
- package/dist/{chunk-PNQCXLSV.js → chunk-QTUVYI7W.js} +58 -1
- package/dist/{chunk-X62AXPR7.js → chunk-RPZZSXV3.js} +8 -196
- package/dist/{chunk-WRS3B556.js → chunk-RSX4OPZY.js} +5 -5
- package/dist/{chunk-FAHDKPEH.js → chunk-RVGLDGMI.js} +5 -3
- package/dist/chunk-SKLSMHXO.js +208 -0
- package/dist/{chunk-4OUOFS23.js → chunk-UKVWJRKN.js} +1 -1
- package/dist/{chunk-57OKQMP3.js → chunk-VH33ZWMW.js} +5 -55
- package/dist/cli.js +49 -23
- package/dist/{clock-LJCG426D.js → clock-BVH3V6E3.js} +7 -6
- package/dist/{cloud-sync-O3LXIRN6.js → cloud-sync-4NWLMFVH.js} +20 -14
- package/dist/config-H2H4UIF7.js +72 -0
- 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-RKKGP5IA.js → conversations-AWI5SZW2.js} +4 -3
- package/dist/{create-TL623TFC.js → create-2FK7Z46Y.js} +6 -2
- package/dist/{create-WUTIIRI2.js → create-YWD2TIP4.js} +6 -5
- package/dist/{daemon-client-CVGM25DM.js → daemon-client-6QXHZ7US.js} +3 -2
- package/dist/{daemon-restart-EZP7XH3V.js → daemon-restart-GOBUKLX7.js} +8 -6
- package/dist/daemon.js +1918 -1472
- package/dist/{db-SW5PL6QA.js → db-F34YLV7D.js} +2 -1
- package/dist/db-RA45JBFG.js +16 -0
- package/dist/{delete-Z6HAG35F.js → delete-QTGWEDBI.js} +1 -1
- package/dist/delivery-manager-PFAKEJTC.js +32 -0
- package/dist/delivery-router-FL45JL7N.js +21 -0
- package/dist/down-FWWTEKXM.js +15 -0
- package/dist/{env-NHESNNSP.js → env-JCOF2222.js} +5 -4
- package/dist/{export-EVMP7GWY.js → export-SUYRLI5Q.js} +4 -3
- package/dist/{extension-LR7EW3JF.js → extension-OBTGKQQD.js} +5 -3
- package/dist/{extensions-NGEJI7JH.js → extensions-KYNTVTMO.js} +10 -7
- package/dist/{files-3SM7V33S.js → files-65PMW5IK.js} +6 -5
- package/dist/{history-PQD3LXEP.js → history-DKCDI3JO.js} +9 -4
- package/dist/{import-PR2OCGQJ.js → import-DDUFE7AY.js} +4 -3
- package/dist/isolation-LLAYQYDY.js +22 -0
- package/dist/{join-R4EN5CWQ.js → join-I5QEE3LG.js} +1 -1
- package/dist/{list-B4XNUOFO.js → list-JQ463EDA.js} +5 -4
- package/dist/{login-62JVY6A2.js → login-D7ETSU4R.js} +5 -4
- package/dist/{login-URWP6S2N.js → login-RIJF2F4G.js} +3 -2
- package/dist/{logout-NXJQJDLI.js → logout-5MLHZALK.js} +3 -2
- package/dist/{logout-ZK2N62T3.js → logout-UZJRGY4Z.js} +3 -2
- package/dist/message-delivery-DFF5SJRM.js +42 -0
- package/dist/{mind-E2ZV2WRX.js → mind-IOJFLEM5.js} +25 -19
- package/dist/{mind-activity-tracker-ASNZBMLC.js → mind-activity-tracker-F6O4Q2SL.js} +4 -3
- package/dist/{mind-list-BEI7E5WY.js → mind-list-WUPMQDYQ.js} +3 -2
- package/dist/mind-manager-NBJF5D26.js +32 -0
- package/dist/mind-profile-P67FEHOY.js +47 -0
- package/dist/mind-service-2MQ6UK5N.js +38 -0
- package/dist/{mind-sleep-CANABWJI.js → mind-sleep-WW2IX7JT.js} +5 -4
- package/dist/{mind-status-6WKZVUOP.js → mind-status-L3EFFRPR.js} +3 -2
- package/dist/{mind-wake-RZKLH2IN.js → mind-wake-VSSGW465.js} +5 -4
- package/dist/{package-NU4CA7OU.js → package-U3VFO273.js} +2 -1
- package/dist/{read-THL362EI.js → read-EBY56C33.js} +5 -4
- package/dist/read-stdin-HQJ7774D.js +8 -0
- package/dist/{register-QAQELAS6.js → register-HD74C4TT.js} +5 -4
- package/dist/{registry-ASXCQCNH.js → registry-PJ4S5PHQ.js} +8 -1
- package/dist/{reject-AYPBNPNL.js → reject-UJKFBHRO.js} +5 -4
- package/dist/{restart-6SKPV3T2.js → restart-3UCMRUVC.js} +3 -2
- package/dist/{sandbox-6ZEWQDVU.js → sandbox-GJOK4QLQ.js} +4 -3
- package/dist/scheduler-ZZ7XGQG6.js +32 -0
- package/dist/schema-PA3M5ZKH.js +32 -0
- package/dist/seed-QDYVLG74.js +11 -0
- package/dist/seed-check-S2IX25RL.js +32 -0
- package/dist/seed-cmd-DKOUFEAU.js +36 -0
- package/dist/{seed-OWX2AW75.js → seed-create-4XBBOLRH.js} +27 -10
- package/dist/{sprout-FDVI2CGN.js → seed-sprout-GQEIIQRT.js} +24 -9
- package/dist/{send-ZO4BTWXK.js → send-QIV2INHB.js} +92 -101
- package/dist/{setup-7CFITEQN.js → setup-TISPCO22.js} +7 -2
- package/dist/{setup-ZXBXG7E4.js → setup-XMCBE3LF.js} +11 -7
- package/dist/{skill-YFXP67A2.js → skill-PSQGRRJX.js} +5 -4
- package/dist/skills/dreaming/SKILL.md +6 -4
- package/dist/skills/dreaming/references/INSTALL.md +2 -2
- package/dist/skills/dreaming/scripts/dream.ts +2 -2
- package/dist/skills/dreaming/scripts/wake-context-dreams.sh +1 -1
- package/dist/skills/imagegen/SKILL.md +16 -11
- package/dist/skills/imagegen/references/INSTALL.md +1 -1
- package/dist/skills/imagegen/scripts/imagegen.ts +146 -25
- package/dist/skills/orientation/SKILL.md +9 -2
- package/dist/skills/resonance/SKILL.md +4 -1
- package/dist/skills/resonance/references/INSTALL.md +2 -2
- package/dist/skills/resonance/scripts/resonance-hook.sh +2 -0
- package/dist/skills/resonance/scripts/resonance.ts +35 -5
- package/dist/skills/seed-nurture/SKILL.md +42 -0
- package/dist/skills/volute-admin/SKILL.md +83 -0
- package/dist/skills/volute-mind/SKILL.md +15 -11
- package/dist/skills-7FV7EJTE.js +62 -0
- package/dist/sleep-manager-JTXSN7NV.js +36 -0
- package/dist/spirit-VRONKFMF.js +23 -0
- package/dist/{split-MI62KJUU.js → split-STOROBYJ.js} +1 -1
- package/dist/sprout-WKLZXUIQ.js +11 -0
- package/dist/{start-D64BRKPH.js → start-K2NCUUCG.js} +3 -2
- package/dist/{status-ZZWBYFGE.js → status-3JBTFSMI.js} +6 -4
- package/dist/{stop-OP2CTXCO.js → stop-H26JZDXF.js} +3 -2
- package/dist/system-chat-JAPOJ3KE.js +36 -0
- package/dist/{systems-EQPPT4B7.js → systems-XRI52VCH.js} +6 -5
- package/dist/{tailscale-6DJKUMNF.js → tailscale-XHQBZROW.js} +2 -1
- package/dist/{template-hash-3HOR4UAJ.js → template-hash-A6VVKOXJ.js} +2 -1
- package/dist/up-M5AS6SBV.js +18 -0
- package/dist/{update-KUJXATRS.js → update-UD543CXX.js} +6 -4
- package/dist/{update-check-5WVSU37T.js → update-check-ZD6OOIYQ.js} +3 -2
- package/dist/{upgrade-KBHCWX6T.js → upgrade-O4Q7WJM3.js} +12 -14
- package/dist/{version-notify-75ELVKPV.js → version-notify-NBI2MTJO.js} +22 -16
- package/dist/volute-config-HD7WWUQC.js +10 -0
- package/dist/web-assets/assets/index-CWJrVveV.css +1 -0
- package/dist/web-assets/assets/index-DJt14FRI.js +75 -0
- package/dist/web-assets/ext-theme.css +93 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0004_spirits.sql +5 -0
- package/drizzle/meta/0004_snapshot.json +7 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +2 -1
- package/packages/extensions/notes/dist/ui/assets/index-8jWEv9SA.js +61 -0
- package/packages/extensions/notes/dist/ui/assets/index-DkaB7Ytd.css +1 -0
- package/packages/extensions/notes/dist/ui/index.html +2 -2
- package/packages/extensions/pages/skills/pages/SKILL.md +16 -46
- package/templates/_base/.init/.config/hooks/pre-prompt/session-activity.ts +40 -0
- package/templates/_base/.init/{.config → .local}/bin/volute +1 -1
- package/templates/_base/.init/.local/hooks/pre-prompt/session-activity.ts +40 -0
- package/templates/_base/.init/.local/hooks/startup-context.ts +58 -0
- package/templates/_base/home/.config/routes.json +1 -1
- package/templates/_base/src/lib/daemon-client.ts +21 -13
- package/templates/_base/src/lib/format-prefix.ts +1 -0
- package/templates/_base/src/lib/hook-loader.ts +155 -0
- package/templates/_base/src/lib/startup.ts +11 -4
- package/templates/_base/src/lib/transparency.ts +2 -2
- package/templates/claude/.init/.claude/settings.json +1 -1
- package/templates/claude/.init/.config/routes.json +2 -2
- package/templates/claude/src/agent.ts +95 -13
- package/templates/claude/src/lib/message-channel.ts +7 -2
- package/templates/claude/src/lib/stream-consumer.ts +38 -0
- package/templates/codex/.init/.config/routes.json +11 -0
- package/templates/codex/.init/AGENTS.md +29 -0
- package/templates/codex/home/.config/config.json.tmpl +7 -0
- package/templates/codex/package.json.tmpl +20 -0
- package/templates/codex/src/agent.ts +554 -0
- package/templates/codex/src/lib/content.ts +16 -0
- package/templates/codex/src/lib/session-store.ts +56 -0
- package/templates/codex/src/server.ts +59 -0
- package/templates/codex/volute-template.json +8 -0
- package/templates/pi/.init/.config/routes.json +2 -2
- package/templates/pi/src/agent.ts +62 -8
- package/templates/pi/src/lib/event-handler.ts +1 -1
- package/templates/pi/src/lib/reply-instructions-extension.ts +32 -11
- package/dist/chunk-HR5JKIDG.js +0 -222
- package/dist/down-TS4XQBA4.js +0 -13
- package/dist/message-delivery-UJHCLVU4.js +0 -30
- package/dist/mind-manager-IPA6DZXD.js +0 -26
- package/dist/pages-watcher-72OVPRMH.js +0 -22
- package/dist/skills/sessions/SKILL.md +0 -49
- package/dist/sleep-manager-TPS6OGCA.js +0 -30
- package/dist/system-chat-B43GIXQU.js +0 -30
- package/dist/up-TDXEP3VA.js +0 -16
- package/dist/web-assets/assets/index-BM1cTzBg.js +0 -72
- package/dist/web-assets/assets/index-BfJkKTPF.css +0 -1
- package/packages/extensions/notes/dist/ui/assets/index-B8GdTnXs.css +0 -1
- package/packages/extensions/notes/dist/ui/assets/index-CDpGTCWb.js +0 -2
- package/packages/extensions/pages/skills/pages/scripts/pages.mjs +0 -58
- package/templates/_base/.init/.config/hooks/startup-context.sh +0 -46
- package/templates/_base/.init/.config/scripts/session-reader.ts +0 -59
- package/templates/_base/src/lib/session-monitor.ts +0 -400
- package/templates/claude/src/lib/hooks/session-context.ts +0 -32
- package/templates/pi/src/lib/session-context-extension.ts +0 -35
- /package/templates/_base/.init/{.config → .local}/hooks/wake-context.sh +0 -0
|
@@ -3,20 +3,6 @@ import {
|
|
|
3
3
|
__export
|
|
4
4
|
} from "./chunk-K3NQKI34.js";
|
|
5
5
|
|
|
6
|
-
// src/lib/db.ts
|
|
7
|
-
import { chmodSync, existsSync } from "fs";
|
|
8
|
-
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
9
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
10
|
-
import { drizzle } from "drizzle-orm/libsql";
|
|
11
|
-
import { migrate } from "drizzle-orm/libsql/migrator";
|
|
12
|
-
|
|
13
|
-
// src/lib/registry.ts
|
|
14
|
-
import { mkdirSync } from "fs";
|
|
15
|
-
import { homedir } from "os";
|
|
16
|
-
import { dirname, resolve } from "path";
|
|
17
|
-
import { fileURLToPath } from "url";
|
|
18
|
-
import { eq, isNull } from "drizzle-orm";
|
|
19
|
-
|
|
20
6
|
// src/lib/schema.ts
|
|
21
7
|
var schema_exports = {};
|
|
22
8
|
__export(schema_exports, {
|
|
@@ -48,9 +34,14 @@ var minds = sqliteTable(
|
|
|
48
34
|
template: text("template"),
|
|
49
35
|
template_hash: text("template_hash"),
|
|
50
36
|
running: integer("running").notNull().default(0),
|
|
37
|
+
mind_type: text("mind_type").notNull().default("mind"),
|
|
38
|
+
created_by: text("created_by"),
|
|
51
39
|
created_at: text("created_at").notNull().default(sql`(datetime('now'))`)
|
|
52
40
|
},
|
|
53
|
-
(table) => [
|
|
41
|
+
(table) => [
|
|
42
|
+
index("idx_minds_parent").on(table.parent),
|
|
43
|
+
index("idx_minds_mind_type").on(table.mind_type)
|
|
44
|
+
]
|
|
54
45
|
);
|
|
55
46
|
var users = sqliteTable("users", {
|
|
56
47
|
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
@@ -218,166 +209,8 @@ var messages = sqliteTable(
|
|
|
218
209
|
]
|
|
219
210
|
);
|
|
220
211
|
|
|
221
|
-
// src/lib/registry.ts
|
|
222
|
-
function voluteHome() {
|
|
223
|
-
if (process.env.VOLUTE_HOME) return process.env.VOLUTE_HOME;
|
|
224
|
-
const dir = dirname(fileURLToPath(import.meta.url));
|
|
225
|
-
if (dir.endsWith("/src/lib")) {
|
|
226
|
-
throw new Error(
|
|
227
|
-
'VOLUTE_HOME must be set when running from source. For tests, run via "npm test" or add "--import ./test/setup.ts".'
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
return resolve(homedir(), ".volute");
|
|
231
|
-
}
|
|
232
|
-
function voluteUserHome() {
|
|
233
|
-
if (process.env.VOLUTE_USER_HOME) return process.env.VOLUTE_USER_HOME;
|
|
234
|
-
return resolve(homedir(), ".volute");
|
|
235
|
-
}
|
|
236
|
-
function voluteSystemDir() {
|
|
237
|
-
return resolve(voluteHome(), "system");
|
|
238
|
-
}
|
|
239
|
-
function ensureSystemDir() {
|
|
240
|
-
mkdirSync(voluteSystemDir(), { recursive: true });
|
|
241
|
-
}
|
|
242
|
-
function ensureVoluteHome() {
|
|
243
|
-
const mindsBase = process.env.VOLUTE_MINDS_DIR ?? resolve(voluteHome(), "minds");
|
|
244
|
-
mkdirSync(mindsBase, { recursive: true });
|
|
245
|
-
ensureSystemDir();
|
|
246
|
-
}
|
|
247
|
-
function rowToEntry(row) {
|
|
248
|
-
return {
|
|
249
|
-
name: row.name,
|
|
250
|
-
port: row.port,
|
|
251
|
-
created: row.created_at,
|
|
252
|
-
running: row.running === 1,
|
|
253
|
-
stage: row.stage ?? (row.parent ? void 0 : "sprouted"),
|
|
254
|
-
template: row.template ?? void 0,
|
|
255
|
-
templateHash: row.template_hash ?? void 0,
|
|
256
|
-
parent: row.parent ?? void 0,
|
|
257
|
-
dir: row.dir ?? void 0,
|
|
258
|
-
branch: row.branch ?? void 0
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
async function readRegistry() {
|
|
262
|
-
const db2 = await getDb();
|
|
263
|
-
const rows = await db2.select().from(minds).where(isNull(minds.parent));
|
|
264
|
-
return rows.map(rowToEntry);
|
|
265
|
-
}
|
|
266
|
-
async function readAllMinds() {
|
|
267
|
-
const db2 = await getDb();
|
|
268
|
-
const rows = await db2.select().from(minds);
|
|
269
|
-
return rows.map(rowToEntry);
|
|
270
|
-
}
|
|
271
|
-
var MIND_NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
272
|
-
var MIND_NAME_MAX = 64;
|
|
273
|
-
var RESERVED_NAMES = /* @__PURE__ */ new Set(["volute", "system"]);
|
|
274
|
-
function validateMindName(name) {
|
|
275
|
-
if (!name) return "Mind name is required";
|
|
276
|
-
if (name.length > MIND_NAME_MAX) return `Mind name must be at most ${MIND_NAME_MAX} characters`;
|
|
277
|
-
if (!MIND_NAME_RE.test(name)) {
|
|
278
|
-
return "Mind name must start with alphanumeric and contain only alphanumeric, dots, dashes, or underscores";
|
|
279
|
-
}
|
|
280
|
-
if (RESERVED_NAMES.has(name.toLowerCase())) {
|
|
281
|
-
return `"${name}" is a reserved name`;
|
|
282
|
-
}
|
|
283
|
-
return null;
|
|
284
|
-
}
|
|
285
|
-
async function addMind(name, port, stage, template) {
|
|
286
|
-
const err = validateMindName(name);
|
|
287
|
-
if (err) throw new Error(err);
|
|
288
|
-
const db2 = await getDb();
|
|
289
|
-
await db2.insert(minds).values({ name, port, stage: stage ?? null, template: template ?? null }).onConflictDoUpdate({
|
|
290
|
-
target: minds.name,
|
|
291
|
-
set: { port, stage: stage ?? null, template: template ?? null }
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
async function addVariant(name, parent, port, dir, branch) {
|
|
295
|
-
const err = validateMindName(name);
|
|
296
|
-
if (err) throw new Error(err);
|
|
297
|
-
const db2 = await getDb();
|
|
298
|
-
await db2.insert(minds).values({ name, port, parent, dir, branch }).onConflictDoUpdate({
|
|
299
|
-
target: minds.name,
|
|
300
|
-
set: { port, parent, dir, branch }
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
async function removeMind(name) {
|
|
304
|
-
const db2 = await getDb();
|
|
305
|
-
await db2.delete(minds).where(eq(minds.name, name));
|
|
306
|
-
}
|
|
307
|
-
async function setMindRunning(name, running) {
|
|
308
|
-
const db2 = await getDb();
|
|
309
|
-
await db2.update(minds).set({ running: running ? 1 : 0 }).where(eq(minds.name, name));
|
|
310
|
-
}
|
|
311
|
-
async function setMindStage(name, stage) {
|
|
312
|
-
const db2 = await getDb();
|
|
313
|
-
await db2.update(minds).set({ stage }).where(eq(minds.name, name));
|
|
314
|
-
}
|
|
315
|
-
async function setMindTemplateHash(name, hash) {
|
|
316
|
-
const db2 = await getDb();
|
|
317
|
-
await db2.update(minds).set({ template_hash: hash }).where(eq(minds.name, name));
|
|
318
|
-
}
|
|
319
|
-
async function findMind(name) {
|
|
320
|
-
const db2 = await getDb();
|
|
321
|
-
const rows = await db2.select().from(minds).where(eq(minds.name, name));
|
|
322
|
-
if (rows.length === 0) return void 0;
|
|
323
|
-
return rowToEntry(rows[0]);
|
|
324
|
-
}
|
|
325
|
-
async function findVariants(parent) {
|
|
326
|
-
const db2 = await getDb();
|
|
327
|
-
const rows = await db2.select().from(minds).where(eq(minds.parent, parent));
|
|
328
|
-
return rows.map(rowToEntry);
|
|
329
|
-
}
|
|
330
|
-
async function getBaseName(name) {
|
|
331
|
-
const entry = await findMind(name);
|
|
332
|
-
return entry?.parent ?? name;
|
|
333
|
-
}
|
|
334
|
-
function mindDir(name) {
|
|
335
|
-
if (process.env.VOLUTE_MINDS_DIR) {
|
|
336
|
-
return resolve(process.env.VOLUTE_MINDS_DIR, name);
|
|
337
|
-
}
|
|
338
|
-
return resolve(voluteHome(), "minds", name);
|
|
339
|
-
}
|
|
340
|
-
function stateDir(name) {
|
|
341
|
-
return resolve(voluteSystemDir(), "state", name);
|
|
342
|
-
}
|
|
343
|
-
async function nextPort() {
|
|
344
|
-
const db2 = await getDb();
|
|
345
|
-
const rows = await db2.select({ port: minds.port }).from(minds);
|
|
346
|
-
const usedPorts = new Set(rows.map((r) => r.port));
|
|
347
|
-
const basePort = parseInt(process.env.VOLUTE_BASE_PORT || "4100", 10);
|
|
348
|
-
let port = basePort;
|
|
349
|
-
while (usedPorts.has(port)) port++;
|
|
350
|
-
if (port > 65535) throw new Error("No available ports \u2014 all ports 4100-65535 are allocated");
|
|
351
|
-
return port;
|
|
352
|
-
}
|
|
353
|
-
function daemonLoopback() {
|
|
354
|
-
const host = process.env.VOLUTE_DAEMON_HOSTNAME || "127.0.0.1";
|
|
355
|
-
if (host === "0.0.0.0") return "127.0.0.1";
|
|
356
|
-
if (host === "::") return "[::1]";
|
|
357
|
-
return host;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// src/lib/db.ts
|
|
361
|
-
var __dirname = dirname2(fileURLToPath2(import.meta.url));
|
|
362
|
-
var migrationsFolder = existsSync(resolve2(__dirname, "../drizzle")) ? resolve2(__dirname, "../drizzle") : resolve2(__dirname, "../../drizzle");
|
|
363
|
-
var db = null;
|
|
364
|
-
async function getDb() {
|
|
365
|
-
if (db) return db;
|
|
366
|
-
const dbPath = process.env.VOLUTE_DB_PATH || resolve2(voluteSystemDir(), "volute.db");
|
|
367
|
-
db = drizzle({ connection: { url: `file:${dbPath}` }, schema: schema_exports });
|
|
368
|
-
await migrate(db, { migrationsFolder });
|
|
369
|
-
try {
|
|
370
|
-
chmodSync(dbPath, 384);
|
|
371
|
-
} catch (err) {
|
|
372
|
-
console.error(
|
|
373
|
-
`[volute] WARNING: Failed to restrict database file permissions on ${dbPath}:`,
|
|
374
|
-
err
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
return db;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
212
|
export {
|
|
213
|
+
minds,
|
|
381
214
|
users,
|
|
382
215
|
conversations,
|
|
383
216
|
turns,
|
|
@@ -390,26 +223,5 @@ export {
|
|
|
390
223
|
activity,
|
|
391
224
|
conversationReads,
|
|
392
225
|
messages,
|
|
393
|
-
|
|
394
|
-
voluteHome,
|
|
395
|
-
voluteUserHome,
|
|
396
|
-
voluteSystemDir,
|
|
397
|
-
ensureSystemDir,
|
|
398
|
-
ensureVoluteHome,
|
|
399
|
-
readRegistry,
|
|
400
|
-
readAllMinds,
|
|
401
|
-
validateMindName,
|
|
402
|
-
addMind,
|
|
403
|
-
addVariant,
|
|
404
|
-
removeMind,
|
|
405
|
-
setMindRunning,
|
|
406
|
-
setMindStage,
|
|
407
|
-
setMindTemplateHash,
|
|
408
|
-
findMind,
|
|
409
|
-
findVariants,
|
|
410
|
-
getBaseName,
|
|
411
|
-
mindDir,
|
|
412
|
-
stateDir,
|
|
413
|
-
nextPort,
|
|
414
|
-
daemonLoopback
|
|
226
|
+
schema_exports
|
|
415
227
|
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
readEnv,
|
|
4
4
|
sharedEnvPath,
|
|
5
5
|
writeEnv
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2NGTS5UU.js";
|
|
7
7
|
import {
|
|
8
8
|
logger_default
|
|
9
9
|
} from "./chunk-YUIHSKR6.js";
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./chunk-D424ZQGI.js";
|
|
13
13
|
import {
|
|
14
14
|
voluteSystemDir
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-LRCG2JLP.js";
|
|
16
16
|
|
|
17
17
|
// src/commands/import.ts
|
|
18
18
|
import {
|
|
@@ -112,7 +112,7 @@ async function run(args) {
|
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
const wsDir = resolveWorkspace(inputPath);
|
|
115
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
115
|
+
const { daemonFetch } = await import("./daemon-client-6QXHZ7US.js");
|
|
116
116
|
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
117
117
|
const client = getClient();
|
|
118
118
|
const res = await daemonFetch(urlOf(client.api.minds.import.$url()), {
|
|
@@ -152,7 +152,7 @@ async function importArchive(archivePath, nameOverride) {
|
|
|
152
152
|
console.error(`File not found: ${archivePath}`);
|
|
153
153
|
process.exit(1);
|
|
154
154
|
}
|
|
155
|
-
const { extractArchive } = await import("./archive-
|
|
155
|
+
const { extractArchive } = await import("./archive-INXYFVCW.js");
|
|
156
156
|
const tempDir = resolve2(tmpdir(), `volute-import-${Date.now()}`);
|
|
157
157
|
mkdirSync(tempDir, { recursive: true });
|
|
158
158
|
let extracted;
|
|
@@ -164,7 +164,7 @@ async function importArchive(archivePath, nameOverride) {
|
|
|
164
164
|
process.exit(1);
|
|
165
165
|
}
|
|
166
166
|
try {
|
|
167
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
167
|
+
const { daemonFetch } = await import("./daemon-client-6QXHZ7US.js");
|
|
168
168
|
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
169
169
|
const client = getClient();
|
|
170
170
|
const res = await daemonFetch(urlOf(client.api.minds.import.$url()), {
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
subscribe
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KVK2DLWI.js";
|
|
5
5
|
import {
|
|
6
6
|
logger_default
|
|
7
7
|
} from "./chunk-YUIHSKR6.js";
|
|
8
|
+
import {
|
|
9
|
+
getDb
|
|
10
|
+
} from "./chunk-LRCG2JLP.js";
|
|
8
11
|
import {
|
|
9
12
|
conversationParticipants,
|
|
10
13
|
conversationReads,
|
|
11
14
|
conversations,
|
|
12
|
-
getDb,
|
|
13
15
|
messages,
|
|
14
16
|
users
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-RPZZSXV3.js";
|
|
16
18
|
|
|
17
19
|
// src/lib/events/conversations.ts
|
|
18
20
|
import { randomUUID } from "crypto";
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
logger_default
|
|
4
|
+
} from "./chunk-YUIHSKR6.js";
|
|
5
|
+
import {
|
|
6
|
+
mindDir
|
|
7
|
+
} from "./chunk-LRCG2JLP.js";
|
|
8
|
+
|
|
9
|
+
// src/lib/delivery/delivery-router.ts
|
|
10
|
+
import { readFileSync, statSync } from "fs";
|
|
11
|
+
import { resolve } from "path";
|
|
12
|
+
function extractTextContent(content) {
|
|
13
|
+
if (typeof content === "string") return content;
|
|
14
|
+
if (Array.isArray(content)) {
|
|
15
|
+
return content.filter((p) => p.type === "text" && p.text).map((p) => p.text).join("\n");
|
|
16
|
+
}
|
|
17
|
+
return JSON.stringify(content);
|
|
18
|
+
}
|
|
19
|
+
var configCache = /* @__PURE__ */ new Map();
|
|
20
|
+
var statCheckCache = /* @__PURE__ */ new Map();
|
|
21
|
+
var STAT_TTL_MS = 5e3;
|
|
22
|
+
var dlog = logger_default.child("delivery-router");
|
|
23
|
+
var dirOverrides = /* @__PURE__ */ new Map();
|
|
24
|
+
function registerMindDir(name, dir) {
|
|
25
|
+
dirOverrides.set(name, dir);
|
|
26
|
+
}
|
|
27
|
+
function configPath(mindName) {
|
|
28
|
+
const dir = dirOverrides.get(mindName) ?? mindDir(mindName);
|
|
29
|
+
return resolve(dir, "home/.config/routes.json");
|
|
30
|
+
}
|
|
31
|
+
function getRoutingConfig(mindName) {
|
|
32
|
+
const path = configPath(mindName);
|
|
33
|
+
const now = Date.now();
|
|
34
|
+
const statCached = statCheckCache.get(mindName);
|
|
35
|
+
const cached = configCache.get(mindName);
|
|
36
|
+
if (statCached && cached && now - statCached.checkedAt < STAT_TTL_MS) {
|
|
37
|
+
return cached.config;
|
|
38
|
+
}
|
|
39
|
+
let mtime;
|
|
40
|
+
try {
|
|
41
|
+
mtime = statSync(path).mtimeMs;
|
|
42
|
+
} catch {
|
|
43
|
+
configCache.delete(mindName);
|
|
44
|
+
statCheckCache.delete(mindName);
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
statCheckCache.set(mindName, { mtime, checkedAt: now });
|
|
48
|
+
if (cached && cached.mtime === mtime) {
|
|
49
|
+
return cached.config;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const config = JSON.parse(readFileSync(path, "utf-8"));
|
|
53
|
+
configCache.set(mindName, { config, mtime });
|
|
54
|
+
return config;
|
|
55
|
+
} catch (err) {
|
|
56
|
+
dlog.warn(`failed to load routes.json for ${mindName}`, logger_default.errorData(err));
|
|
57
|
+
configCache.delete(mindName);
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
var globRegexCache = /* @__PURE__ */ new Map();
|
|
62
|
+
function clearConfigCache(mindName) {
|
|
63
|
+
if (mindName) {
|
|
64
|
+
configCache.delete(mindName);
|
|
65
|
+
statCheckCache.delete(mindName);
|
|
66
|
+
} else {
|
|
67
|
+
configCache.clear();
|
|
68
|
+
statCheckCache.clear();
|
|
69
|
+
globRegexCache.clear();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function globMatch(pattern, value) {
|
|
73
|
+
let regex = globRegexCache.get(pattern);
|
|
74
|
+
if (!regex) {
|
|
75
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
76
|
+
regex = new RegExp(`^${escaped}$`);
|
|
77
|
+
globRegexCache.set(pattern, regex);
|
|
78
|
+
}
|
|
79
|
+
return regex.test(value);
|
|
80
|
+
}
|
|
81
|
+
var GLOB_MATCH_KEYS = /* @__PURE__ */ new Set(["channel", "sender"]);
|
|
82
|
+
var NON_MATCH_KEYS = /* @__PURE__ */ new Set(["session", "destination", "path", "mode", "batch"]);
|
|
83
|
+
function ruleMatches(rule, meta) {
|
|
84
|
+
for (const [key, pattern] of Object.entries(rule)) {
|
|
85
|
+
if (NON_MATCH_KEYS.has(key)) continue;
|
|
86
|
+
if (key === "isDM") {
|
|
87
|
+
if (typeof pattern !== "boolean") return false;
|
|
88
|
+
if ((meta.isDM ?? false) !== pattern) return false;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (key === "participants") {
|
|
92
|
+
if (typeof pattern !== "number") return false;
|
|
93
|
+
if ((meta.participantCount ?? 0) !== pattern) return false;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (typeof pattern !== "string") return false;
|
|
97
|
+
if (!GLOB_MATCH_KEYS.has(key)) return false;
|
|
98
|
+
const value = meta[key] ?? "";
|
|
99
|
+
if (!globMatch(pattern, value)) return false;
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
function expandTemplate(template, meta) {
|
|
104
|
+
return template.replace(/\$\{sender\}/g, meta.sender ?? "unknown").replace(/\$\{channel\}/g, meta.channel ?? "unknown");
|
|
105
|
+
}
|
|
106
|
+
function sanitizeSessionName(name) {
|
|
107
|
+
return name.replace(/\0/g, "").replace(/[/\\]/g, "-").replace(/\.\./g, "-").slice(0, 100);
|
|
108
|
+
}
|
|
109
|
+
function resolveRoute(config, meta) {
|
|
110
|
+
const fallback = config.default ?? "main";
|
|
111
|
+
if (!config.rules) {
|
|
112
|
+
return { destination: "mind", session: fallback, matched: false };
|
|
113
|
+
}
|
|
114
|
+
for (const rule of config.rules) {
|
|
115
|
+
if (ruleMatches(rule, meta)) {
|
|
116
|
+
if (rule.destination === "file") {
|
|
117
|
+
if (!rule.path) {
|
|
118
|
+
dlog.warn("file destination rule missing path \u2014 falling through");
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
return { destination: "file", path: rule.path, matched: true };
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
destination: "mind",
|
|
125
|
+
session: sanitizeSessionName(expandTemplate(rule.session ?? fallback, meta)),
|
|
126
|
+
matched: true,
|
|
127
|
+
mode: rule.mode,
|
|
128
|
+
rule
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return { destination: "mind", session: fallback, matched: false };
|
|
133
|
+
}
|
|
134
|
+
var DEFAULT_BATCH_DEBOUNCE = 5;
|
|
135
|
+
var DEFAULT_BATCH_MAX_WAIT = 120;
|
|
136
|
+
function normalizeBatchConfig(batch) {
|
|
137
|
+
if (typeof batch === "number") return { maxWait: batch * 60 };
|
|
138
|
+
return batch;
|
|
139
|
+
}
|
|
140
|
+
function resolveDeliveryMode(config, sessionName, rule) {
|
|
141
|
+
const ruleBatch = rule?.batch;
|
|
142
|
+
const defaults = {
|
|
143
|
+
delivery: { mode: "immediate" },
|
|
144
|
+
interrupt: true
|
|
145
|
+
};
|
|
146
|
+
if (!config.sessions) {
|
|
147
|
+
if (ruleBatch != null) {
|
|
148
|
+
const batch = normalizeBatchConfig(ruleBatch);
|
|
149
|
+
return {
|
|
150
|
+
delivery: {
|
|
151
|
+
mode: "batch",
|
|
152
|
+
debounce: batch.debounce ?? DEFAULT_BATCH_DEBOUNCE,
|
|
153
|
+
maxWait: batch.maxWait ?? DEFAULT_BATCH_MAX_WAIT,
|
|
154
|
+
triggers: batch.triggers
|
|
155
|
+
},
|
|
156
|
+
interrupt: true
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return defaults;
|
|
160
|
+
}
|
|
161
|
+
for (const [pattern, sessionConfig] of Object.entries(config.sessions)) {
|
|
162
|
+
if (globMatch(pattern, sessionName)) {
|
|
163
|
+
let delivery;
|
|
164
|
+
if (sessionConfig.delivery == null || sessionConfig.delivery === "immediate") {
|
|
165
|
+
delivery = { mode: "immediate" };
|
|
166
|
+
} else if (sessionConfig.delivery === "batch") {
|
|
167
|
+
delivery = {
|
|
168
|
+
mode: "batch",
|
|
169
|
+
debounce: DEFAULT_BATCH_DEBOUNCE,
|
|
170
|
+
maxWait: DEFAULT_BATCH_MAX_WAIT
|
|
171
|
+
};
|
|
172
|
+
} else {
|
|
173
|
+
delivery = {
|
|
174
|
+
mode: "batch",
|
|
175
|
+
debounce: sessionConfig.delivery.debounce ?? DEFAULT_BATCH_DEBOUNCE,
|
|
176
|
+
maxWait: sessionConfig.delivery.maxWait ?? DEFAULT_BATCH_MAX_WAIT
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
delivery,
|
|
181
|
+
interrupt: true,
|
|
182
|
+
instructions: sessionConfig.instructions
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (ruleBatch != null) {
|
|
187
|
+
const batch = normalizeBatchConfig(ruleBatch);
|
|
188
|
+
return {
|
|
189
|
+
delivery: {
|
|
190
|
+
mode: "batch",
|
|
191
|
+
debounce: batch.debounce ?? DEFAULT_BATCH_DEBOUNCE,
|
|
192
|
+
maxWait: batch.maxWait ?? DEFAULT_BATCH_MAX_WAIT,
|
|
193
|
+
triggers: batch.triggers
|
|
194
|
+
},
|
|
195
|
+
interrupt: true
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return defaults;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export {
|
|
202
|
+
extractTextContent,
|
|
203
|
+
registerMindDir,
|
|
204
|
+
getRoutingConfig,
|
|
205
|
+
clearConfigCache,
|
|
206
|
+
resolveRoute,
|
|
207
|
+
resolveDeliveryMode
|
|
208
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getBaseName,
|
|
4
4
|
validateMindName
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-LRCG2JLP.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/isolation.ts
|
|
8
8
|
import { execFileSync } from "child_process";
|
|
@@ -11,7 +11,9 @@ function isIsolationEnabled() {
|
|
|
11
11
|
}
|
|
12
12
|
function mindUserName(mindName) {
|
|
13
13
|
const err = validateMindName(mindName);
|
|
14
|
-
if (err
|
|
14
|
+
if (err && mindName !== "volute") {
|
|
15
|
+
throw new Error(`Invalid mind name for isolation: ${err}`);
|
|
16
|
+
}
|
|
15
17
|
const prefix = process.env.VOLUTE_USER_PREFIX ?? "mind-";
|
|
16
18
|
return `${prefix}${mindName}`;
|
|
17
19
|
}
|
|
@@ -166,54 +168,6 @@ function chownMindDir(dir, name) {
|
|
|
166
168
|
}
|
|
167
169
|
}
|
|
168
170
|
|
|
169
|
-
// src/lib/exec.ts
|
|
170
|
-
import { execFile as execFileCb, execFileSync as execFileSync2, spawn } from "child_process";
|
|
171
|
-
async function exec(cmd, args, options) {
|
|
172
|
-
const [wrappedCmd, wrappedArgs] = options?.mindName ? await wrapForIsolation(cmd, args, options.mindName) : [cmd, args];
|
|
173
|
-
return new Promise((resolve, reject) => {
|
|
174
|
-
execFileCb(
|
|
175
|
-
wrappedCmd,
|
|
176
|
-
wrappedArgs,
|
|
177
|
-
{ cwd: options?.cwd, env: options?.env },
|
|
178
|
-
(err, stdout, stderr) => {
|
|
179
|
-
if (err) {
|
|
180
|
-
err.stderr = stderr;
|
|
181
|
-
err.stdout = stdout;
|
|
182
|
-
reject(err);
|
|
183
|
-
} else {
|
|
184
|
-
resolve(stdout);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
);
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
function gitExec(args, options) {
|
|
191
|
-
const fullArgs = process.env.VOLUTE_ISOLATION === "user" ? ["-c", "safe.directory=*", ...args] : args;
|
|
192
|
-
return exec("git", fullArgs, options);
|
|
193
|
-
}
|
|
194
|
-
function resolveVoluteBin() {
|
|
195
|
-
try {
|
|
196
|
-
return execFileSync2("which", ["volute"], { encoding: "utf-8" }).trim();
|
|
197
|
-
} catch {
|
|
198
|
-
throw new Error("Could not find volute binary on PATH");
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
async function execInherit(cmd, args, options) {
|
|
202
|
-
const [wrappedCmd, wrappedArgs] = options?.mindName ? await wrapForIsolation(cmd, args, options.mindName) : [cmd, args];
|
|
203
|
-
return new Promise((resolve, reject) => {
|
|
204
|
-
const child = spawn(wrappedCmd, wrappedArgs, {
|
|
205
|
-
cwd: options?.cwd,
|
|
206
|
-
env: options?.env,
|
|
207
|
-
stdio: "inherit"
|
|
208
|
-
});
|
|
209
|
-
child.on("error", reject);
|
|
210
|
-
child.on("close", (code) => {
|
|
211
|
-
if (code === 0) resolve();
|
|
212
|
-
else reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code}`));
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
171
|
export {
|
|
218
172
|
isIsolationEnabled,
|
|
219
173
|
mindUserName,
|
|
@@ -221,9 +175,5 @@ export {
|
|
|
221
175
|
createMindUser,
|
|
222
176
|
deleteMindUser,
|
|
223
177
|
wrapForIsolation,
|
|
224
|
-
chownMindDir
|
|
225
|
-
exec,
|
|
226
|
-
gitExec,
|
|
227
|
-
resolveVoluteBin,
|
|
228
|
-
execInherit
|
|
178
|
+
chownMindDir
|
|
229
179
|
};
|