volute 0.26.0 → 0.28.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 +18 -18
- package/dist/accept-666DIZX2.js +41 -0
- package/dist/{activity-events-ZMBAKLUF.js → activity-events-BBIEA2F4.js} +2 -3
- package/dist/api.d.ts +510 -299
- package/dist/{archive-4ZQYK5MN.js → archive-UA4BDFXQ.js} +2 -2
- package/dist/bridge-FQHZL3MC.js +206 -0
- package/dist/chat-M4SX42JD.js +68 -0
- package/dist/{chunk-PHU4DEAJ.js → chunk-2WPW7OT6.js} +3 -3
- package/dist/{chunk-5Y3PBKW6.js → chunk-2YP2TVDT.js} +138 -56
- package/dist/{chunk-3CFRE2VC.js → chunk-AAPXKR5V.js} +435 -1090
- package/dist/{chunk-YJA7P64S.js → chunk-AW7PFDVN.js} +5 -5
- package/dist/{chunk-OZFKBXD6.js → chunk-EHYDTZTF.js} +6 -6
- package/dist/{chunk-WBHMQ5OZ.js → chunk-H7OZRFJB.js} +192 -12
- package/dist/{chunk-ON3FF5JA.js → chunk-HDN7MNGD.js} +3 -3
- package/dist/chunk-IAYBDWVG.js +477 -0
- package/dist/{chunk-TZKJLDQN.js → chunk-IKRVFPWU.js} +14 -9
- package/dist/{chunk-UTL75LP6.js → chunk-J4IBNXGJ.js} +20 -22
- package/dist/{chunk-WGOGUMPO.js → chunk-JGFVMROS.js} +13 -6
- package/dist/{chunk-NWI2425I.js → chunk-K5NAC55T.js} +1 -1
- package/dist/chunk-KTLFDYPT.js +61 -0
- package/dist/{chunk-V63B7DX3.js → chunk-LAC664WU.js} +7 -4
- package/dist/chunk-MD4C26II.js +128 -0
- package/dist/{chunk-USNBKHYG.js → chunk-NI5FFCCS.js} +12 -7
- package/dist/{chunk-3TV4GLFO.js → chunk-P72MVS4R.js} +4 -43
- package/dist/{chunk-2VO7453N.js → chunk-POSXWWTA.js} +30 -54
- package/dist/{chunk-XOXLRRR2.js → chunk-RKQEHRBB.js} +4 -3
- package/dist/{chunk-LX22GRG7.js → chunk-SGVNFZHW.js} +11 -8
- package/dist/chunk-T6HKBWXZ.js +23 -0
- package/dist/{chunk-J2CO4WEV.js → chunk-VIVMW2H2.js} +4 -4
- package/dist/{chunk-KTJGZ7M7.js → chunk-XBLSAVJF.js} +1 -1
- package/dist/cli.js +32 -49
- package/dist/{cloud-sync-NI2K3C7G.js → cloud-sync-HDL6PHZI.js} +14 -14
- package/dist/connectors/discord-bridge.js +158 -0
- package/dist/connectors/slack-bridge.js +119 -0
- package/dist/connectors/telegram-bridge.js +133 -0
- package/dist/conversations-M2K4253F.js +55 -0
- package/dist/create-D7J73A6H.js +45 -0
- package/dist/{create-4YBRTTJS.js → create-QWV73WXD.js} +1 -1
- package/dist/{daemon-client-Z7FAJ6JW.js → daemon-client-I42FK2BF.js} +2 -2
- package/dist/{daemon-restart-BJZ3O4U4.js → daemon-restart-G4B2OYAB.js} +7 -7
- package/dist/daemon.js +1889 -1216
- package/dist/db-IC4J52XQ.js +8 -0
- package/dist/{delete-27OYNK25.js → delete-4JYGD4VN.js} +1 -1
- package/dist/down-LVBXEULC.js +14 -0
- package/dist/{env-M336ONDP.js → env-YJMUMFIY.js} +2 -2
- package/dist/{export-HP4G5DQC.js → export-BOJQWBMA.js} +4 -4
- package/dist/files-M546TKVN.js +46 -0
- package/dist/{history-B64GTFTD.js → history-ALPTNB3I.js} +5 -5
- package/dist/{import-XIB7UV4S.js → import-SRTQXBGH.js} +4 -4
- package/dist/join-J4QU42DL.js +66 -0
- package/dist/list-R73GENNL.js +40 -0
- package/dist/{login-B5E7N7MY.js → login-3QZNR2DF.js} +4 -4
- package/dist/{login-6U7U6BNG.js → login-BKP3AFWN.js} +8 -18
- package/dist/logout-IQK7FNEK.js +20 -0
- package/dist/{logout-XSJRYS3U.js → logout-T53VKCPU.js} +4 -4
- package/dist/message-delivery-HV3S6HZV.js +24 -0
- package/dist/migrate-registry-to-db-XC7T5B7P.js +110 -0
- package/dist/{mind-HZ3QSDDJ.js → mind-S5V6CK5W.js} +29 -34
- package/dist/{mind-activity-tracker-4G6FURY2.js → mind-activity-tracker-EN6XNXPF.js} +3 -4
- package/dist/mind-list-UPJ75GPI.js +29 -0
- package/dist/mind-manager-S6ILZVX3.js +18 -0
- package/dist/{mind-sleep-DTV7L44D.js → mind-sleep-BTSWQNAC.js} +4 -4
- package/dist/mind-status-TK5AETEM.js +55 -0
- package/dist/{mind-wake-PFN4FN3T.js → mind-wake-SBAKIDVP.js} +4 -4
- package/dist/{notes-37FW2UR2.js → notes-XCER3I7M.js} +11 -21
- package/dist/{package-VZWLXPHV.js → package-CG4RWUGP.js} +1 -1
- package/dist/{pages-DIIT5HMQ.js → pages-KJDJX4TA.js} +5 -5
- package/dist/{publish-HQV7YREB.js → publish-ZZB33WP4.js} +9 -20
- package/dist/read-36UFXN3G.js +46 -0
- package/dist/{register-EFND67FQ.js → register-CHREOMJ3.js} +6 -25
- package/dist/{registry-D2BSQ2X5.js → registry-NDNOOYG4.js} +15 -9
- package/dist/reject-LXIZFJ4Q.js +39 -0
- package/dist/{restart-CCK7D6TV.js → restart-6ESL3NBO.js} +5 -5
- package/dist/{sandbox-EHGFF52K.js → sandbox-5BW5HPXM.js} +3 -3
- package/dist/{schedule-6F7ELB2M.js → schedule-QTJMFATP.js} +5 -5
- package/dist/{seed-E5OQGWX3.js → seed-SSUCYYDF.js} +2 -2
- package/dist/{send-IH6XZKPC.js → send-TAOEZ4NH.js} +87 -23
- package/dist/{setup-YGAAIKKZ.js → setup-JHL5ZEST.js} +2 -2
- package/dist/{setup-F6TWFYGQ.js → setup-RXYVGGT7.js} +9 -9
- package/dist/{skill-42LGFBQC.js → skill-AUAQTSP5.js} +5 -5
- package/dist/skills/dreaming/references/INSTALL.md +2 -2
- package/dist/skills/orientation/SKILL.md +3 -3
- 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 +35 -34
- package/dist/sleep-manager-WMVG2VCL.js +28 -0
- package/dist/split-TKJ5OT3P.js +63 -0
- package/dist/{sprout-QL74KR2X.js → sprout-UNT7LKKE.js} +6 -7
- package/dist/{start-O5JQASRC.js → start-EUJSS5R4.js} +2 -2
- package/dist/status-NQJYR4BG.js +114 -0
- package/dist/{status-LV34BG6G.js → status-S7UUPNRW.js} +4 -14
- package/dist/{stop-2SOG5NYF.js → stop-3XAITBBF.js} +5 -5
- package/dist/systems-SMEFSHTA.js +60 -0
- package/dist/{tailscale-AJ4VL5XK.js → tailscale-NY5MUMY3.js} +1 -1
- package/dist/up-GM2JOH2Y.js +17 -0
- package/dist/{update-5VUDAI3D.js → update-PTSH22AZ.js} +9 -9
- package/dist/{update-check-F5Z3ALXX.js → update-check-64FWC4Y2.js} +2 -2
- package/dist/{upgrade-QCCO33BK.js → upgrade-HA47CS4C.js} +12 -5
- package/dist/variant-7TGZHOU3.js +41 -0
- package/dist/{version-notify-USFZBWMG.js → version-notify-JDUF4HQJ.js} +24 -29
- package/dist/web-assets/assets/index-BZGvToHi.css +1 -0
- package/dist/web-assets/assets/index-Cz4TrpzB.js +75 -0
- package/dist/web-assets/favicon.png +0 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0017_minds.sql +16 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/templates/_base/.init/.config/prompts.json +2 -2
- package/templates/_base/home/VOLUTE.md +5 -5
- package/templates/_base/src/lib/logger.ts +0 -4
- package/templates/_base/src/lib/startup.ts +2 -2
- package/dist/auth-4TV573WE.js +0 -37
- package/dist/channel-ZVZV42UD.js +0 -260
- package/dist/chunk-B2CPS4QU.js +0 -283
- package/dist/chunk-HFCBO2GL.js +0 -50
- package/dist/chunk-RWKVSSLY.js +0 -26
- package/dist/chunk-SIAG3QMM.js +0 -42
- package/dist/chunk-WSLPZF72.js +0 -173
- package/dist/connector-G722WXAU.js +0 -147
- package/dist/connectors/discord.js +0 -177
- package/dist/connectors/slack.js +0 -181
- package/dist/connectors/telegram.js +0 -187
- package/dist/down-7UKFMJJZ.js +0 -14
- package/dist/file-HUDKTRAS.js +0 -204
- package/dist/log-PBFNILJ4.js +0 -39
- package/dist/logout-UKD5LA37.js +0 -18
- package/dist/logs-3CART7O7.js +0 -77
- package/dist/merge-VK2HSKMA.js +0 -46
- package/dist/message-delivery-MS5JYPZX.js +0 -25
- package/dist/mind-manager-VVK67AY3.js +0 -19
- package/dist/pull-2MB4SK3C.js +0 -39
- package/dist/service-LLBV3R7M.js +0 -122
- package/dist/shared-UMO4S7CC.js +0 -39
- package/dist/sleep-manager-EE4NRN2Q.js +0 -29
- package/dist/status-FZBEBM7Q.js +0 -70
- package/dist/status-WXD4HXRL.js +0 -35
- package/dist/up-SDMCSVI3.js +0 -17
- package/dist/variant-WWLDY6D5.js +0 -207
- package/dist/web-assets/assets/index-CUQ31ieL.js +0 -69
- package/dist/web-assets/assets/index-CW8NSl1o.css +0 -1
package/dist/chunk-B2CPS4QU.js
DELETED
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/lib/registry.ts
|
|
4
|
-
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "fs";
|
|
5
|
-
import { homedir } from "os";
|
|
6
|
-
import { dirname, resolve as resolve2 } from "path";
|
|
7
|
-
import { fileURLToPath } from "url";
|
|
8
|
-
|
|
9
|
-
// src/lib/variants.ts
|
|
10
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
11
|
-
import { resolve } from "path";
|
|
12
|
-
function variantsPath() {
|
|
13
|
-
return resolve(voluteHome(), "variants.json");
|
|
14
|
-
}
|
|
15
|
-
function readAllVariants() {
|
|
16
|
-
const path = variantsPath();
|
|
17
|
-
if (!existsSync(path)) return {};
|
|
18
|
-
try {
|
|
19
|
-
return JSON.parse(readFileSync(path, "utf-8"));
|
|
20
|
-
} catch {
|
|
21
|
-
return {};
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function writeAllVariants(all) {
|
|
25
|
-
mkdirSync(voluteHome(), { recursive: true });
|
|
26
|
-
writeFileSync(variantsPath(), `${JSON.stringify(all, null, 2)}
|
|
27
|
-
`);
|
|
28
|
-
}
|
|
29
|
-
function readVariants(mindName) {
|
|
30
|
-
return readAllVariants()[mindName] ?? [];
|
|
31
|
-
}
|
|
32
|
-
function writeVariants(mindName, variants) {
|
|
33
|
-
const all = readAllVariants();
|
|
34
|
-
if (variants.length === 0) {
|
|
35
|
-
delete all[mindName];
|
|
36
|
-
} else {
|
|
37
|
-
all[mindName] = variants;
|
|
38
|
-
}
|
|
39
|
-
writeAllVariants(all);
|
|
40
|
-
}
|
|
41
|
-
function addVariant(mindName, variant) {
|
|
42
|
-
const variants = readVariants(mindName);
|
|
43
|
-
const filtered = variants.filter((v) => v.name !== variant.name);
|
|
44
|
-
filtered.push(variant);
|
|
45
|
-
writeVariants(mindName, filtered);
|
|
46
|
-
}
|
|
47
|
-
function removeVariant(mindName, name) {
|
|
48
|
-
const variants = readVariants(mindName);
|
|
49
|
-
writeVariants(
|
|
50
|
-
mindName,
|
|
51
|
-
variants.filter((v) => v.name !== name)
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
function findVariant(mindName, name) {
|
|
55
|
-
return readVariants(mindName).find((v) => v.name === name);
|
|
56
|
-
}
|
|
57
|
-
function setVariantRunning(mindName, variantName, running) {
|
|
58
|
-
const all = readAllVariants();
|
|
59
|
-
const variants = all[mindName] ?? [];
|
|
60
|
-
const variant = variants.find((v) => v.name === variantName);
|
|
61
|
-
if (variant) {
|
|
62
|
-
variant.running = running;
|
|
63
|
-
all[mindName] = variants;
|
|
64
|
-
writeAllVariants(all);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
function getAllRunningVariants() {
|
|
68
|
-
const all = readAllVariants();
|
|
69
|
-
const result = [];
|
|
70
|
-
for (const [mindName, variants] of Object.entries(all)) {
|
|
71
|
-
for (const variant of variants) {
|
|
72
|
-
if (variant.running) {
|
|
73
|
-
result.push({ mindName, variant });
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return result;
|
|
78
|
-
}
|
|
79
|
-
function removeAllVariants(mindName) {
|
|
80
|
-
const all = readAllVariants();
|
|
81
|
-
delete all[mindName];
|
|
82
|
-
writeAllVariants(all);
|
|
83
|
-
}
|
|
84
|
-
async function checkHealth(port) {
|
|
85
|
-
try {
|
|
86
|
-
const res = await fetch(`http://127.0.0.1:${port}/health`, {
|
|
87
|
-
signal: AbortSignal.timeout(2e3)
|
|
88
|
-
});
|
|
89
|
-
if (!res.ok) return { ok: false };
|
|
90
|
-
const data = await res.json();
|
|
91
|
-
return { ok: true, name: data.name };
|
|
92
|
-
} catch {
|
|
93
|
-
return { ok: false };
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
var SAFE_BRANCH_RE = /^[a-zA-Z0-9._\-/]+$/;
|
|
97
|
-
function validateBranchName(branch) {
|
|
98
|
-
if (!SAFE_BRANCH_RE.test(branch)) {
|
|
99
|
-
return `Invalid branch name: ${branch}. Only alphanumeric, '.', '_', '-', '/' allowed.`;
|
|
100
|
-
}
|
|
101
|
-
if (branch.includes("..")) {
|
|
102
|
-
return `Invalid branch name: ${branch}. '..' not allowed.`;
|
|
103
|
-
}
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// src/lib/registry.ts
|
|
108
|
-
var registryCache = null;
|
|
109
|
-
function initRegistryCache() {
|
|
110
|
-
registryCache = readRegistryFromDisk();
|
|
111
|
-
}
|
|
112
|
-
function getRegistryCache() {
|
|
113
|
-
return registryCache;
|
|
114
|
-
}
|
|
115
|
-
function readRegistryFromDisk() {
|
|
116
|
-
const registryPath = resolve2(voluteHome(), "minds.json");
|
|
117
|
-
if (!existsSync2(registryPath)) return [];
|
|
118
|
-
try {
|
|
119
|
-
const entries = JSON.parse(readFileSync2(registryPath, "utf-8"));
|
|
120
|
-
return entries.map((e) => ({
|
|
121
|
-
...e,
|
|
122
|
-
running: e.running ?? false,
|
|
123
|
-
stage: e.stage ?? "sprouted"
|
|
124
|
-
}));
|
|
125
|
-
} catch {
|
|
126
|
-
return [];
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
function voluteHome() {
|
|
130
|
-
if (process.env.VOLUTE_HOME) return process.env.VOLUTE_HOME;
|
|
131
|
-
const dir = dirname(fileURLToPath(import.meta.url));
|
|
132
|
-
if (dir.endsWith("/src/lib")) {
|
|
133
|
-
throw new Error(
|
|
134
|
-
'VOLUTE_HOME must be set when running from source. For tests, run via "npm test" or add "--import ./test/setup.ts".'
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
return resolve2(homedir(), ".volute");
|
|
138
|
-
}
|
|
139
|
-
function ensureVoluteHome() {
|
|
140
|
-
const mindsBase = process.env.VOLUTE_MINDS_DIR ?? resolve2(voluteHome(), "minds");
|
|
141
|
-
mkdirSync2(mindsBase, { recursive: true });
|
|
142
|
-
}
|
|
143
|
-
function readRegistry() {
|
|
144
|
-
if (registryCache) return registryCache;
|
|
145
|
-
return readRegistryFromDisk();
|
|
146
|
-
}
|
|
147
|
-
function writeRegistry(entries) {
|
|
148
|
-
if (registryCache) registryCache = entries;
|
|
149
|
-
ensureVoluteHome();
|
|
150
|
-
const registryPath = resolve2(voluteHome(), "minds.json");
|
|
151
|
-
const tmpPath = `${registryPath}.tmp`;
|
|
152
|
-
writeFileSync2(tmpPath, `${JSON.stringify(entries, null, 2)}
|
|
153
|
-
`);
|
|
154
|
-
renameSync(tmpPath, registryPath);
|
|
155
|
-
}
|
|
156
|
-
var MIND_NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
157
|
-
var MIND_NAME_MAX = 64;
|
|
158
|
-
function validateMindName(name) {
|
|
159
|
-
if (!name) return "Mind name is required";
|
|
160
|
-
if (name.length > MIND_NAME_MAX) return `Mind name must be at most ${MIND_NAME_MAX} characters`;
|
|
161
|
-
if (!MIND_NAME_RE.test(name)) {
|
|
162
|
-
return "Mind name must start with alphanumeric and contain only alphanumeric, dots, dashes, or underscores";
|
|
163
|
-
}
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
function addMind(name, port, stage, template) {
|
|
167
|
-
const err = validateMindName(name);
|
|
168
|
-
if (err) throw new Error(err);
|
|
169
|
-
const entries = readRegistry();
|
|
170
|
-
const filtered = entries.filter((e) => e.name !== name);
|
|
171
|
-
filtered.push({ name, port, created: (/* @__PURE__ */ new Date()).toISOString(), running: false, stage, template });
|
|
172
|
-
writeRegistry(filtered);
|
|
173
|
-
}
|
|
174
|
-
function removeMind(name) {
|
|
175
|
-
const entries = readRegistry();
|
|
176
|
-
writeRegistry(entries.filter((e) => e.name !== name));
|
|
177
|
-
}
|
|
178
|
-
function setMindRunning(name, running) {
|
|
179
|
-
const entries = readRegistry();
|
|
180
|
-
const entry = entries.find((e) => e.name === name);
|
|
181
|
-
if (entry) {
|
|
182
|
-
entry.running = running;
|
|
183
|
-
writeRegistry(entries);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function setMindStage(name, stage) {
|
|
187
|
-
const entries = readRegistry();
|
|
188
|
-
const entry = entries.find((e) => e.name === name);
|
|
189
|
-
if (entry) {
|
|
190
|
-
entry.stage = stage;
|
|
191
|
-
writeRegistry(entries);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
function setMindTemplateHash(name, hash) {
|
|
195
|
-
const entries = readRegistry();
|
|
196
|
-
const entry = entries.find((e) => e.name === name);
|
|
197
|
-
if (entry) {
|
|
198
|
-
entry.templateHash = hash;
|
|
199
|
-
writeRegistry(entries);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function findMind(name) {
|
|
203
|
-
return readRegistry().find((e) => e.name === name);
|
|
204
|
-
}
|
|
205
|
-
function mindDir(name) {
|
|
206
|
-
if (process.env.VOLUTE_MINDS_DIR) {
|
|
207
|
-
return resolve2(process.env.VOLUTE_MINDS_DIR, name);
|
|
208
|
-
}
|
|
209
|
-
return resolve2(voluteHome(), "minds", name);
|
|
210
|
-
}
|
|
211
|
-
function stateDir(name) {
|
|
212
|
-
return resolve2(voluteHome(), "state", name);
|
|
213
|
-
}
|
|
214
|
-
function nextPort() {
|
|
215
|
-
const entries = readRegistry();
|
|
216
|
-
const usedPorts = new Set(entries.map((e) => e.port));
|
|
217
|
-
for (const entry of entries) {
|
|
218
|
-
for (const v of readVariants(entry.name)) {
|
|
219
|
-
if (v.port) usedPorts.add(v.port);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
const basePort = parseInt(process.env.VOLUTE_BASE_PORT || "4100", 10);
|
|
223
|
-
let port = basePort;
|
|
224
|
-
while (usedPorts.has(port)) port++;
|
|
225
|
-
if (port > 65535) throw new Error("No available ports \u2014 all ports 4100-65535 are allocated");
|
|
226
|
-
return port;
|
|
227
|
-
}
|
|
228
|
-
function daemonLoopback() {
|
|
229
|
-
const host = process.env.VOLUTE_DAEMON_HOSTNAME || "127.0.0.1";
|
|
230
|
-
if (host === "0.0.0.0") return "127.0.0.1";
|
|
231
|
-
if (host === "::") return "[::1]";
|
|
232
|
-
return host;
|
|
233
|
-
}
|
|
234
|
-
function resolveMind(name) {
|
|
235
|
-
const [baseName, variantName] = name.split("@", 2);
|
|
236
|
-
const entry = findMind(baseName);
|
|
237
|
-
if (!entry) {
|
|
238
|
-
throw new Error(`Unknown mind: ${baseName}`);
|
|
239
|
-
}
|
|
240
|
-
const dir = mindDir(baseName);
|
|
241
|
-
if (!existsSync2(dir)) {
|
|
242
|
-
throw new Error(`Mind directory missing: ${dir}`);
|
|
243
|
-
}
|
|
244
|
-
if (variantName) {
|
|
245
|
-
const variant = findVariant(baseName, variantName);
|
|
246
|
-
if (!variant) {
|
|
247
|
-
throw new Error(`Unknown variant: ${variantName} (mind: ${baseName})`);
|
|
248
|
-
}
|
|
249
|
-
return { entry: { ...entry, port: variant.port }, dir: variant.path };
|
|
250
|
-
}
|
|
251
|
-
return { entry, dir };
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
export {
|
|
255
|
-
readVariants,
|
|
256
|
-
writeVariants,
|
|
257
|
-
addVariant,
|
|
258
|
-
removeVariant,
|
|
259
|
-
findVariant,
|
|
260
|
-
setVariantRunning,
|
|
261
|
-
getAllRunningVariants,
|
|
262
|
-
removeAllVariants,
|
|
263
|
-
checkHealth,
|
|
264
|
-
validateBranchName,
|
|
265
|
-
initRegistryCache,
|
|
266
|
-
getRegistryCache,
|
|
267
|
-
voluteHome,
|
|
268
|
-
ensureVoluteHome,
|
|
269
|
-
readRegistry,
|
|
270
|
-
writeRegistry,
|
|
271
|
-
validateMindName,
|
|
272
|
-
addMind,
|
|
273
|
-
removeMind,
|
|
274
|
-
setMindRunning,
|
|
275
|
-
setMindStage,
|
|
276
|
-
setMindTemplateHash,
|
|
277
|
-
findMind,
|
|
278
|
-
mindDir,
|
|
279
|
-
stateDir,
|
|
280
|
-
nextPort,
|
|
281
|
-
daemonLoopback,
|
|
282
|
-
resolveMind
|
|
283
|
-
};
|
package/dist/chunk-HFCBO2GL.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
voluteHome
|
|
4
|
-
} from "./chunk-B2CPS4QU.js";
|
|
5
|
-
|
|
6
|
-
// src/lib/systems-config.ts
|
|
7
|
-
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
8
|
-
import { resolve } from "path";
|
|
9
|
-
var DEFAULT_API_URL = "https://volute.systems";
|
|
10
|
-
function configPath() {
|
|
11
|
-
return resolve(voluteHome(), "systems.json");
|
|
12
|
-
}
|
|
13
|
-
function readSystemsConfig() {
|
|
14
|
-
const path = configPath();
|
|
15
|
-
if (!existsSync(path)) return null;
|
|
16
|
-
const raw = readFileSync(path, "utf-8");
|
|
17
|
-
let data;
|
|
18
|
-
try {
|
|
19
|
-
data = JSON.parse(raw);
|
|
20
|
-
} catch {
|
|
21
|
-
console.error(`Warning: ${path} contains invalid JSON. Run "volute auth logout" and re-login.`);
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
if (!data.apiKey || !data.system) return null;
|
|
25
|
-
return {
|
|
26
|
-
apiKey: data.apiKey,
|
|
27
|
-
system: data.system,
|
|
28
|
-
apiUrl: data.apiUrl || DEFAULT_API_URL
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function writeSystemsConfig(config) {
|
|
32
|
-
mkdirSync(voluteHome(), { recursive: true });
|
|
33
|
-
writeFileSync(configPath(), `${JSON.stringify(config, null, 2)}
|
|
34
|
-
`, { mode: 384 });
|
|
35
|
-
}
|
|
36
|
-
function deleteSystemsConfig() {
|
|
37
|
-
try {
|
|
38
|
-
unlinkSync(configPath());
|
|
39
|
-
return true;
|
|
40
|
-
} catch (err) {
|
|
41
|
-
if (err.code === "ENOENT") return false;
|
|
42
|
-
throw err;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export {
|
|
47
|
-
readSystemsConfig,
|
|
48
|
-
writeSystemsConfig,
|
|
49
|
-
deleteSystemsConfig
|
|
50
|
-
};
|
package/dist/chunk-RWKVSSLY.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/lib/systems-fetch.ts
|
|
4
|
-
async function systemsFetch(url, init) {
|
|
5
|
-
try {
|
|
6
|
-
return await fetch(url, init);
|
|
7
|
-
} catch (err) {
|
|
8
|
-
const cause = err.cause;
|
|
9
|
-
const code = cause?.code;
|
|
10
|
-
const host = new URL(url).host;
|
|
11
|
-
if (code === "ENOTFOUND") {
|
|
12
|
-
console.error(`Could not resolve ${host}. Check your internet connection.`);
|
|
13
|
-
} else if (code === "ECONNREFUSED") {
|
|
14
|
-
console.error(`Connection refused by ${host}. The service may be down.`);
|
|
15
|
-
} else {
|
|
16
|
-
console.error(
|
|
17
|
-
`Network error connecting to ${host}: ${cause?.message ?? err.message}`
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
systemsFetch
|
|
26
|
-
};
|
package/dist/chunk-SIAG3QMM.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/lib/volute-config.ts
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
5
|
-
import { dirname, resolve } from "path";
|
|
6
|
-
function readJson(path) {
|
|
7
|
-
if (!existsSync(path)) return null;
|
|
8
|
-
try {
|
|
9
|
-
return JSON.parse(readFileSync(path, "utf-8"));
|
|
10
|
-
} catch (err) {
|
|
11
|
-
console.error(`[volute-config] failed to parse ${path}: ${err}`);
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
function readVoluteConfig(mindDir) {
|
|
16
|
-
const path = resolve(mindDir, "home/.config/volute.json");
|
|
17
|
-
const config = readJson(path);
|
|
18
|
-
if (!config) return null;
|
|
19
|
-
const legacy = config;
|
|
20
|
-
if (!config.profile && ("displayName" in config || "description" in config || "avatar" in config)) {
|
|
21
|
-
config.profile = {
|
|
22
|
-
displayName: legacy.displayName,
|
|
23
|
-
description: legacy.description,
|
|
24
|
-
avatar: legacy.avatar
|
|
25
|
-
};
|
|
26
|
-
delete legacy.displayName;
|
|
27
|
-
delete legacy.description;
|
|
28
|
-
delete legacy.avatar;
|
|
29
|
-
}
|
|
30
|
-
return config;
|
|
31
|
-
}
|
|
32
|
-
function writeVoluteConfig(mindDir, config) {
|
|
33
|
-
const path = resolve(mindDir, "home/.config/volute.json");
|
|
34
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
35
|
-
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
36
|
-
`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export {
|
|
40
|
-
readVoluteConfig,
|
|
41
|
-
writeVoluteConfig
|
|
42
|
-
};
|
package/dist/chunk-WSLPZF72.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
stateDir
|
|
4
|
-
} from "./chunk-B2CPS4QU.js";
|
|
5
|
-
|
|
6
|
-
// src/lib/slugify.ts
|
|
7
|
-
function slugify(text) {
|
|
8
|
-
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
9
|
-
}
|
|
10
|
-
function buildVoluteSlug(opts) {
|
|
11
|
-
if (opts.convType === "channel" && opts.convName) {
|
|
12
|
-
return `volute:#${opts.convName}`;
|
|
13
|
-
}
|
|
14
|
-
const isDM = opts.participants.length === 2;
|
|
15
|
-
if (isDM) {
|
|
16
|
-
const other = opts.participants.find((p) => p.username !== opts.mindUsername);
|
|
17
|
-
const otherSlug = other ? slugify(other.username) : "";
|
|
18
|
-
return otherSlug ? `volute:@${otherSlug}` : `volute:${opts.conversationId}`;
|
|
19
|
-
}
|
|
20
|
-
return opts.convTitle ? `volute:${slugify(opts.convTitle)}` : `volute:${opts.conversationId}`;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// src/connectors/sdk.ts
|
|
24
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
25
|
-
import { join, resolve } from "path";
|
|
26
|
-
function loadEnv() {
|
|
27
|
-
const mindPort = process.env.VOLUTE_MIND_PORT;
|
|
28
|
-
const mindName = process.env.VOLUTE_MIND_NAME;
|
|
29
|
-
if (!mindPort || !mindName) {
|
|
30
|
-
console.error("Missing required env vars: VOLUTE_MIND_PORT, VOLUTE_MIND_NAME");
|
|
31
|
-
process.exit(1);
|
|
32
|
-
}
|
|
33
|
-
const mindDir = process.env.VOLUTE_MIND_DIR;
|
|
34
|
-
const daemonUrl = process.env.VOLUTE_DAEMON_URL;
|
|
35
|
-
const daemonToken = process.env.VOLUTE_DAEMON_TOKEN;
|
|
36
|
-
const baseUrl = daemonUrl ? `${daemonUrl}/api/minds/${encodeURIComponent(mindName)}` : `http://127.0.0.1:${mindPort}`;
|
|
37
|
-
return { mindPort, mindName, mindDir, baseUrl, daemonUrl, daemonToken };
|
|
38
|
-
}
|
|
39
|
-
function loadFollowedChannels(env, platform) {
|
|
40
|
-
if (!env.mindDir) return [];
|
|
41
|
-
const configPath = resolve(env.mindDir, "home/.config/volute.json");
|
|
42
|
-
if (!existsSync(configPath)) return [];
|
|
43
|
-
try {
|
|
44
|
-
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
45
|
-
const platformConfig = config[platform];
|
|
46
|
-
return platformConfig?.channels ?? platformConfig?.chats ?? [];
|
|
47
|
-
} catch (err) {
|
|
48
|
-
console.warn(`Failed to load mind config: ${err}`);
|
|
49
|
-
return [];
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function splitMessage(text, maxLength) {
|
|
53
|
-
const chunks = [];
|
|
54
|
-
while (text.length > maxLength) {
|
|
55
|
-
let splitAt = text.lastIndexOf("\n", maxLength);
|
|
56
|
-
if (splitAt < maxLength / 2) splitAt = maxLength;
|
|
57
|
-
chunks.push(text.slice(0, splitAt));
|
|
58
|
-
text = text.slice(splitAt).replace(/^\n/, "");
|
|
59
|
-
}
|
|
60
|
-
if (text) chunks.push(text);
|
|
61
|
-
return chunks;
|
|
62
|
-
}
|
|
63
|
-
function getHeaders(env) {
|
|
64
|
-
const headers = { "Content-Type": "application/json" };
|
|
65
|
-
if (env.daemonUrl && env.daemonToken) {
|
|
66
|
-
headers.Authorization = `Bearer ${env.daemonToken}`;
|
|
67
|
-
headers.Origin = env.daemonUrl;
|
|
68
|
-
}
|
|
69
|
-
return headers;
|
|
70
|
-
}
|
|
71
|
-
function onShutdown(cleanup) {
|
|
72
|
-
const handler = () => {
|
|
73
|
-
Promise.resolve(cleanup()).then(
|
|
74
|
-
() => process.exit(0),
|
|
75
|
-
(err) => {
|
|
76
|
-
console.error(`Shutdown error: ${err}`);
|
|
77
|
-
process.exit(1);
|
|
78
|
-
}
|
|
79
|
-
);
|
|
80
|
-
};
|
|
81
|
-
process.on("SIGINT", handler);
|
|
82
|
-
process.on("SIGTERM", handler);
|
|
83
|
-
}
|
|
84
|
-
function reportTyping(env, channel, sender, active) {
|
|
85
|
-
fetch(`${env.baseUrl}/typing`, {
|
|
86
|
-
method: "POST",
|
|
87
|
-
headers: getHeaders(env),
|
|
88
|
-
body: JSON.stringify({ channel, sender, active })
|
|
89
|
-
}).catch((err) => {
|
|
90
|
-
console.warn(`[typing] failed to report for ${sender} on ${channel}: ${err}`);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
async function sendToMind(env, payload) {
|
|
94
|
-
const url = `${env.baseUrl}/message`;
|
|
95
|
-
try {
|
|
96
|
-
const res = await fetch(url, {
|
|
97
|
-
method: "POST",
|
|
98
|
-
headers: getHeaders(env),
|
|
99
|
-
body: JSON.stringify(payload)
|
|
100
|
-
});
|
|
101
|
-
if (!res.ok) {
|
|
102
|
-
const body = await res.text().catch(() => "");
|
|
103
|
-
console.error(`Mind returned ${res.status}: ${body}`);
|
|
104
|
-
return { ok: false, error: `Mind returned ${res.status}` };
|
|
105
|
-
}
|
|
106
|
-
return { ok: true };
|
|
107
|
-
} catch (err) {
|
|
108
|
-
console.error(`Failed to forward message: ${err}`);
|
|
109
|
-
const isConnRefused = err instanceof TypeError && err.cause?.code === "ECONNREFUSED";
|
|
110
|
-
return { ok: false, error: isConnRefused ? "Mind is not running" : "Failed to reach mind" };
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
function buildChannelSlug(platform, meta) {
|
|
114
|
-
if (meta.isDM) {
|
|
115
|
-
if (meta.recipients && meta.recipients.length > 0) {
|
|
116
|
-
const sorted = meta.recipients.map(slugify).sort();
|
|
117
|
-
return `${platform}:@${sorted.join(",")}`;
|
|
118
|
-
}
|
|
119
|
-
if (meta.senderName) {
|
|
120
|
-
return `${platform}:@${slugify(meta.senderName)}`;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
if (meta.channelName && meta.serverName) {
|
|
124
|
-
return `${platform}:${slugify(meta.serverName)}/${slugify(meta.channelName)}`;
|
|
125
|
-
}
|
|
126
|
-
if (meta.channelName) {
|
|
127
|
-
return `${platform}:${slugify(meta.channelName)}`;
|
|
128
|
-
}
|
|
129
|
-
if (meta.platformId) {
|
|
130
|
-
return `${platform}:${meta.platformId}`;
|
|
131
|
-
}
|
|
132
|
-
return `${platform}:unknown`;
|
|
133
|
-
}
|
|
134
|
-
function readChannelMap(mindName) {
|
|
135
|
-
const filePath = join(stateDir(mindName), "channels.json");
|
|
136
|
-
if (!existsSync(filePath)) return {};
|
|
137
|
-
try {
|
|
138
|
-
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
139
|
-
} catch (err) {
|
|
140
|
-
console.error(`[sdk] failed to parse ${filePath}:`, err);
|
|
141
|
-
return {};
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function writeChannelEntry(mindName, slug, entry) {
|
|
145
|
-
const dir = stateDir(mindName);
|
|
146
|
-
mkdirSync(dir, { recursive: true });
|
|
147
|
-
const filePath = join(dir, "channels.json");
|
|
148
|
-
const map = readChannelMap(mindName);
|
|
149
|
-
map[slug] = entry;
|
|
150
|
-
writeFileSync(filePath, JSON.stringify(map, null, 2) + "\n");
|
|
151
|
-
}
|
|
152
|
-
function resolveChannelId(mindName, slug) {
|
|
153
|
-
const map = readChannelMap(mindName);
|
|
154
|
-
if (map[slug]) {
|
|
155
|
-
return map[slug].platformId;
|
|
156
|
-
}
|
|
157
|
-
const colonIndex = slug.indexOf(":");
|
|
158
|
-
return colonIndex >= 0 ? slug.slice(colonIndex + 1) : slug;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export {
|
|
162
|
-
slugify,
|
|
163
|
-
buildVoluteSlug,
|
|
164
|
-
loadEnv,
|
|
165
|
-
loadFollowedChannels,
|
|
166
|
-
splitMessage,
|
|
167
|
-
onShutdown,
|
|
168
|
-
reportTyping,
|
|
169
|
-
sendToMind,
|
|
170
|
-
buildChannelSlug,
|
|
171
|
-
writeChannelEntry,
|
|
172
|
-
resolveChannelId
|
|
173
|
-
};
|