volute 0.18.0 → 0.20.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 +67 -67
- package/dist/activity-events-OMXKXD5N.js +16 -0
- package/dist/archive-ZCFOSTKB.js +15 -0
- package/dist/{channel-SLURLIRV.js → channel-PUQKGSQM.js} +60 -7
- package/dist/{chunk-6BDNWYKG.js → chunk-32VR2EOH.js} +2 -2
- package/dist/chunk-5XNT2472.js +36 -0
- package/dist/{chunk-QJIIHU32.js → chunk-7NO7EV5Z.js} +2 -2
- package/dist/{chunk-6DVBMLVN.js → chunk-7UFKREVW.js} +2 -2
- package/dist/chunk-AW7P4EVV.js +159 -0
- package/dist/{chunk-2Y77MCFG.js → chunk-DYZGP3EW.js} +2 -2
- package/dist/{chunk-M77QBTEH.js → chunk-EBGCNDMM.js} +24 -14
- package/dist/{chunk-37X7ECMF.js → chunk-FCDU5BFX.js} +1 -1
- package/dist/chunk-FGSYHIS3.js +891 -0
- package/dist/chunk-GZ7DW4YL.js +97 -0
- package/dist/chunk-IKMY5X76.js +375 -0
- package/dist/chunk-NSE7VJQA.js +159 -0
- package/dist/{chunk-GSPWIM5E.js → chunk-O6ASDHFO.js} +79 -7
- package/dist/{chunk-ZCEYUUID.js → chunk-OGXOMR65.js} +2 -1
- package/dist/{chunk-AYB7XAWO.js → chunk-PUVXOZ6T.js} +120 -279
- package/dist/{chunk-GK4E7LM7.js → chunk-RHEGSQFJ.js} +1 -1
- package/dist/{chunk-MVSXRMJJ.js → chunk-SCUDS4US.js} +1 -1
- package/dist/chunk-TIWH32HP.js +227 -0
- package/dist/{chunk-FW5API7X.js → chunk-UJ6GHNR7.js} +2 -2
- package/dist/chunk-UU7A7KLB.js +58 -0
- package/dist/{chunk-OYSZNX5I.js → chunk-VDWCHYTS.js} +1 -1
- package/dist/{chunk-OJQ47SCA.js → chunk-WC6ZHVRL.js} +1 -1
- package/dist/chunk-YUIHSKR6.js +72 -0
- package/dist/cli.js +43 -25
- package/dist/{connector-3ELFMI2R.js → connector-JBVNZ7VK.js} +6 -6
- package/dist/connectors/discord.js +2 -2
- package/dist/connectors/slack.js +2 -2
- package/dist/connectors/telegram.js +2 -2
- package/dist/{create-ZWHCRT5F.js → create-HP4OVVHF.js} +6 -4
- package/dist/{daemon-client-ODKDUYDE.js → daemon-client-ITWUCNFO.js} +2 -2
- package/dist/{daemon-restart-2HVTHZAT.js → daemon-restart-KPSWNYTH.js} +6 -6
- package/dist/daemon.js +2463 -1707
- package/dist/db-C2CJ46ZU.js +10 -0
- package/dist/{delete-6G6WEX4F.js → delete-BSU7K3RY.js} +1 -1
- package/dist/delivery-manager-CSG7LXA4.js +16 -0
- package/dist/down-ZY35KMHR.js +14 -0
- package/dist/{env-6IDWGBUH.js → env-A3LMO777.js} +6 -6
- package/dist/export-6QBUOQGC.js +100 -0
- package/dist/file-C57SK5DK.js +204 -0
- package/dist/{history-YUEKTJ2N.js → history-WNK3DFUM.js} +6 -6
- package/dist/{import-EDGRLIGO.js → import-XEC34Y4Z.js} +3 -3
- package/dist/log-PPPZDVEF.js +39 -0
- package/dist/{login-ORQDXLBM.js → login-HNH3EUQV.js} +2 -2
- package/dist/{logout-XC5AUO5I.js → logout-I5CB5UZS.js} +2 -2
- package/dist/{logs-GYOR3L2L.js → logs-SF2IMJN4.js} +6 -6
- package/dist/merge-33C237A4.js +46 -0
- package/dist/{mind-OJN6RBZW.js → mind-Z7CKD6DG.js} +14 -10
- package/dist/mind-activity-tracker-624QLQLC.js +19 -0
- package/dist/mind-manager-3DMYKZPB.js +18 -0
- package/dist/{package-OKLFO7UY.js → package-4NHAVUUI.js} +5 -3
- package/dist/{pages-6IV4VQTU.js → pages-4DGQT7ZA.js} +2 -2
- package/dist/{publish-Q4RPSJLL.js → publish-TAJUET4I.js} +22 -5
- package/dist/pull-XAEWQJ47.js +39 -0
- package/dist/{register-LDE6LRXY.js → register-VSPCMHKX.js} +2 -2
- package/dist/{restart-YFAWFS5T.js → restart-IQKMCK5M.js} +6 -6
- package/dist/{schedule-AGYLDMNS.js → schedule-FFZG23IW.js} +31 -11
- package/dist/schema-GFH6RV3W.js +26 -0
- package/dist/{seed-AP4Q7RZ7.js → seed-J43YDKXG.js} +7 -4
- package/dist/{send-BNDTLUPM.js → send-KVIZIGCE.js} +8 -8
- package/dist/{service-U7MZ2H7F.js → service-LUR7WDO7.js} +6 -6
- package/dist/{setup-DJKIZKGW.js → setup-52YRV7VP.js} +23 -7
- package/dist/shared-KO35ZM44.js +39 -0
- package/dist/{skill-2Y42P4JY.js → skill-BCVNI6TV.js} +6 -6
- package/{templates/_base/_skills → dist/skills}/orientation/SKILL.md +1 -1
- package/{templates/_base/_skills → dist/skills}/sessions/SKILL.md +2 -2
- package/{templates/_base/_skills → dist/skills}/volute-mind/SKILL.md +51 -3
- package/dist/{sprout-TJ3BHVOG.js → sprout-QN7Y4VVO.js} +38 -20
- package/dist/{start-3YYRXBKP.js → start-I5JYB65M.js} +6 -6
- package/dist/{status-VSFZYX7S.js → status-4ESFLGH4.js} +5 -5
- package/dist/status-D7E5HHBV.js +35 -0
- package/dist/{status-OKNA6AR3.js → status-FU2PFVVF.js} +5 -4
- package/dist/{stop-AA5K5LYG.js → stop-NBVKEFQQ.js} +6 -6
- package/dist/{up-7B3BWF2U.js → up-FS7CKM6V.js} +5 -5
- package/dist/{update-YAGN5ODG.js → update-FJIHDJKM.js} +5 -5
- package/dist/{update-check-APLTH4IN.js → update-check-MWE5AH4U.js} +2 -2
- package/dist/{upgrade-KXZCQSZN.js → upgrade-AIT24B5I.js} +1 -1
- package/dist/{variant-X5QFG6KK.js → variant-63ZWO2W7.js} +4 -4
- package/dist/variants-JAGWGBXG.js +26 -0
- package/dist/web-assets/assets/index-CUZTZzaW.js +64 -0
- package/dist/web-assets/assets/index-adVuCkqy.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0010_delivery_queue.sql +12 -0
- package/drizzle/0011_rename_human_to_brain.sql +1 -0
- package/drizzle/0012_activity.sql +11 -0
- package/drizzle/meta/0010_snapshot.json +7 -0
- package/drizzle/meta/0011_snapshot.json +7 -0
- package/drizzle/meta/0012_snapshot.json +7 -0
- package/drizzle/meta/_journal.json +21 -0
- package/package.json +5 -3
- package/templates/_base/.init/.config/hooks/startup-context.sh +1 -1
- package/templates/_base/.init/.config/scripts/session-reader.ts +3 -3
- package/templates/_base/home/.config/routes.json +2 -2
- package/templates/_base/home/VOLUTE.md +16 -1
- package/templates/_base/src/lib/auto-commit.ts +51 -14
- package/templates/_base/src/lib/daemon-client.ts +22 -0
- package/templates/_base/src/lib/router.ts +123 -1
- package/templates/_base/src/lib/transparency.ts +1 -1
- package/templates/_base/src/lib/types.ts +4 -0
- package/templates/_base/src/lib/volute-server.ts +91 -2
- package/templates/claude/.init/.config/routes.json +7 -1
- package/templates/claude/src/server.ts +2 -2
- package/templates/claude/volute-template.json +1 -2
- package/templates/pi/.init/.config/routes.json +7 -1
- package/templates/pi/src/agent.ts +12 -6
- package/templates/pi/src/lib/session-context-extension.ts +6 -4
- package/templates/pi/src/server.ts +2 -0
- package/templates/pi/volute-template.json +1 -2
- package/dist/chunk-PO5Q2AYN.js +0 -121
- package/dist/down-A56B5JLK.js +0 -14
- package/dist/mind-manager-Z7O7PN2O.js +0 -15
- package/dist/web-assets/assets/index-CtiimdWK.css +0 -1
- package/dist/web-assets/assets/index-kt1_EcuO.js +0 -63
- /package/{templates/_base/_skills → dist/skills}/memory/SKILL.md +0 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
logger_default
|
|
4
|
+
} from "./chunk-YUIHSKR6.js";
|
|
5
|
+
import {
|
|
6
|
+
gitExec
|
|
7
|
+
} from "./chunk-DYZGP3EW.js";
|
|
8
|
+
import {
|
|
9
|
+
isIsolationEnabled,
|
|
10
|
+
mindUserName
|
|
11
|
+
} from "./chunk-OGXOMR65.js";
|
|
12
|
+
import {
|
|
13
|
+
voluteHome
|
|
14
|
+
} from "./chunk-EBGCNDMM.js";
|
|
15
|
+
|
|
16
|
+
// src/lib/shared.ts
|
|
17
|
+
import { execFileSync } from "child_process";
|
|
18
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
19
|
+
import { resolve } from "path";
|
|
20
|
+
function readWorktreeGitDir(worktreePath) {
|
|
21
|
+
const dotGit = resolve(worktreePath, ".git");
|
|
22
|
+
if (!existsSync(dotGit)) return null;
|
|
23
|
+
try {
|
|
24
|
+
const content = readFileSync(dotGit, "utf-8").trim();
|
|
25
|
+
const match = content.match(/^gitdir:\s*(.+)$/);
|
|
26
|
+
return match ? match[1] : null;
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function sharedDir() {
|
|
32
|
+
return resolve(voluteHome(), "shared");
|
|
33
|
+
}
|
|
34
|
+
async function ensureSharedRepo() {
|
|
35
|
+
const dir = sharedDir();
|
|
36
|
+
mkdirSync(dir, { recursive: true });
|
|
37
|
+
if (existsSync(resolve(dir, ".git"))) {
|
|
38
|
+
try {
|
|
39
|
+
await gitExec(["rev-parse", "HEAD"], { cwd: dir });
|
|
40
|
+
return;
|
|
41
|
+
} catch (err) {
|
|
42
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
43
|
+
if (msg.includes("unknown revision") || msg.includes("bad default revision")) {
|
|
44
|
+
logger_default.warn("shared repo has no commits, re-initializing");
|
|
45
|
+
rmSync(resolve(dir, ".git"), { recursive: true, force: true });
|
|
46
|
+
} else {
|
|
47
|
+
throw err;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const initArgs = isIsolationEnabled() ? ["init", "--shared=group"] : ["init"];
|
|
52
|
+
await gitExec(initArgs, { cwd: dir });
|
|
53
|
+
await gitExec(["checkout", "-b", "main"], { cwd: dir });
|
|
54
|
+
const pagesDir = resolve(dir, "pages");
|
|
55
|
+
mkdirSync(pagesDir, { recursive: true });
|
|
56
|
+
writeFileSync(resolve(pagesDir, ".gitkeep"), "");
|
|
57
|
+
await gitExec(["add", "-A"], { cwd: dir });
|
|
58
|
+
await gitExec(["commit", "-m", "init shared repo"], { cwd: dir });
|
|
59
|
+
if (isIsolationEnabled()) {
|
|
60
|
+
try {
|
|
61
|
+
execFileSync("chgrp", ["-R", "volute", dir], { stdio: "ignore" });
|
|
62
|
+
} catch (err) {
|
|
63
|
+
logger_default.warn("failed to chgrp shared repo to volute group", logger_default.errorData(err));
|
|
64
|
+
}
|
|
65
|
+
chmodSync(dir, 1533);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function addSharedWorktree(mindName, mindDir) {
|
|
69
|
+
const dir = sharedDir();
|
|
70
|
+
if (!existsSync(resolve(dir, ".git"))) return;
|
|
71
|
+
const worktreePath = resolve(mindDir, "home", "shared");
|
|
72
|
+
if (existsSync(worktreePath)) return;
|
|
73
|
+
let branchExists = false;
|
|
74
|
+
try {
|
|
75
|
+
await gitExec(["rev-parse", "--verify", mindName], { cwd: dir });
|
|
76
|
+
branchExists = true;
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
if (branchExists) {
|
|
80
|
+
await gitExec(["worktree", "add", worktreePath, mindName], { cwd: dir });
|
|
81
|
+
} else {
|
|
82
|
+
await gitExec(["worktree", "add", "-b", mindName, worktreePath], { cwd: dir });
|
|
83
|
+
}
|
|
84
|
+
if (isIsolationEnabled()) {
|
|
85
|
+
const worktreeGitDir = readWorktreeGitDir(worktreePath);
|
|
86
|
+
if (worktreeGitDir) {
|
|
87
|
+
try {
|
|
88
|
+
const user = mindUserName(mindName);
|
|
89
|
+
execFileSync("chown", ["-R", `${user}:volute`, worktreeGitDir], { stdio: "ignore" });
|
|
90
|
+
} catch (err) {
|
|
91
|
+
logger_default.warn(`failed to chown worktree git dir for ${mindName}`, logger_default.errorData(err));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function removeSharedWorktree(mindName, mindDir) {
|
|
97
|
+
const dir = sharedDir();
|
|
98
|
+
if (!existsSync(resolve(dir, ".git"))) return;
|
|
99
|
+
const worktreePath = resolve(mindDir, "home", "shared");
|
|
100
|
+
if (existsSync(worktreePath)) {
|
|
101
|
+
try {
|
|
102
|
+
await gitExec(["worktree", "remove", "--force", worktreePath], { cwd: dir });
|
|
103
|
+
} catch (err) {
|
|
104
|
+
logger_default.debug(`worktree remove failed for ${mindName}`, logger_default.errorData(err));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
await gitExec(["worktree", "prune"], { cwd: dir });
|
|
109
|
+
} catch (err) {
|
|
110
|
+
logger_default.debug(`worktree prune failed for ${mindName}`, logger_default.errorData(err));
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
await gitExec(["branch", "-D", mindName], { cwd: dir });
|
|
114
|
+
} catch {
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
var sharedLock = Promise.resolve();
|
|
118
|
+
function rechownWorktree(worktreePath, mindName) {
|
|
119
|
+
if (!isIsolationEnabled()) return;
|
|
120
|
+
try {
|
|
121
|
+
const user = mindUserName(mindName);
|
|
122
|
+
execFileSync("chown", ["-R", `${user}:volute`, worktreePath], { stdio: "ignore" });
|
|
123
|
+
} catch (err) {
|
|
124
|
+
logger_default.warn(`failed to rechown worktree for ${mindName}`, logger_default.errorData(err));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function withSharedLock(fn) {
|
|
128
|
+
const prev = sharedLock;
|
|
129
|
+
let resolve_;
|
|
130
|
+
sharedLock = new Promise((r) => {
|
|
131
|
+
resolve_ = r;
|
|
132
|
+
});
|
|
133
|
+
await prev;
|
|
134
|
+
try {
|
|
135
|
+
return await fn();
|
|
136
|
+
} finally {
|
|
137
|
+
resolve_();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async function sharedMerge(mindName, mindDir, message) {
|
|
141
|
+
return withSharedLock(async () => {
|
|
142
|
+
const dir = sharedDir();
|
|
143
|
+
const worktreePath = resolve(mindDir, "home", "shared");
|
|
144
|
+
const status = (await gitExec(["status", "--porcelain"], { cwd: worktreePath })).trim();
|
|
145
|
+
if (status) {
|
|
146
|
+
await gitExec(["add", "-A"], { cwd: worktreePath });
|
|
147
|
+
await gitExec(
|
|
148
|
+
["commit", "--author", `${mindName} <${mindName}@volute>`, "-m", `wip: ${mindName}`],
|
|
149
|
+
{ cwd: worktreePath }
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const diff = (await gitExec(["diff", `main...${mindName}`, "--stat"], { cwd: dir })).trim();
|
|
153
|
+
if (!diff) {
|
|
154
|
+
return { ok: true, message: "Nothing to merge" };
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
await gitExec(["merge", "--squash", mindName], { cwd: dir });
|
|
158
|
+
} catch {
|
|
159
|
+
try {
|
|
160
|
+
await gitExec(["reset", "--hard", "HEAD"], { cwd: dir });
|
|
161
|
+
} catch (resetErr) {
|
|
162
|
+
logger_default.error("reset after squash conflict failed in shared repo", logger_default.errorData(resetErr));
|
|
163
|
+
}
|
|
164
|
+
return { ok: false, conflicts: true, message: "Merge conflicts detected" };
|
|
165
|
+
}
|
|
166
|
+
await gitExec(["commit", "--author", `${mindName} <${mindName}@volute>`, "-m", message], {
|
|
167
|
+
cwd: dir
|
|
168
|
+
});
|
|
169
|
+
try {
|
|
170
|
+
await gitExec(["reset", "--hard", "main"], { cwd: worktreePath });
|
|
171
|
+
} catch {
|
|
172
|
+
return {
|
|
173
|
+
ok: true,
|
|
174
|
+
message: "Merged to main, but branch reset failed \u2014 run 'volute shared pull' to sync"
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
rechownWorktree(worktreePath, mindName);
|
|
178
|
+
return { ok: true };
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async function sharedPull(mindName, mindDir) {
|
|
182
|
+
return withSharedLock(async () => {
|
|
183
|
+
const worktreePath = resolve(mindDir, "home", "shared");
|
|
184
|
+
const status = (await gitExec(["status", "--porcelain"], { cwd: worktreePath })).trim();
|
|
185
|
+
if (status) {
|
|
186
|
+
await gitExec(["add", "-A"], { cwd: worktreePath });
|
|
187
|
+
await gitExec(
|
|
188
|
+
["commit", "--author", `${mindName} <${mindName}@volute>`, "-m", `wip: ${mindName}`],
|
|
189
|
+
{ cwd: worktreePath }
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
await gitExec(["rebase", "main"], { cwd: worktreePath });
|
|
194
|
+
rechownWorktree(worktreePath, mindName);
|
|
195
|
+
return { ok: true };
|
|
196
|
+
} catch {
|
|
197
|
+
try {
|
|
198
|
+
await gitExec(["rebase", "--abort"], { cwd: worktreePath });
|
|
199
|
+
} catch {
|
|
200
|
+
return {
|
|
201
|
+
ok: false,
|
|
202
|
+
message: "Rebase failed and abort failed \u2014 shared worktree may need manual repair"
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return { ok: false, message: "Rebase failed \u2014 conflicts with main" };
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
async function sharedLog(limit = 20) {
|
|
210
|
+
const dir = sharedDir();
|
|
211
|
+
return gitExec(["log", "--oneline", "-n", String(limit), "main"], { cwd: dir });
|
|
212
|
+
}
|
|
213
|
+
async function sharedStatus(mindName) {
|
|
214
|
+
const dir = sharedDir();
|
|
215
|
+
return gitExec(["diff", `main...${mindName}`, "--stat"], { cwd: dir });
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export {
|
|
219
|
+
sharedDir,
|
|
220
|
+
ensureSharedRepo,
|
|
221
|
+
addSharedWorktree,
|
|
222
|
+
removeSharedWorktree,
|
|
223
|
+
sharedMerge,
|
|
224
|
+
sharedPull,
|
|
225
|
+
sharedLog,
|
|
226
|
+
sharedStatus
|
|
227
|
+
};
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
slugify,
|
|
6
6
|
splitMessage,
|
|
7
7
|
writeChannelEntry
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RHEGSQFJ.js";
|
|
9
9
|
import {
|
|
10
10
|
voluteHome
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-EBGCNDMM.js";
|
|
12
12
|
import {
|
|
13
13
|
__export
|
|
14
14
|
} from "./chunk-K3NQKI34.js";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
logger_default
|
|
4
|
+
} from "./chunk-YUIHSKR6.js";
|
|
5
|
+
import {
|
|
6
|
+
getDb
|
|
7
|
+
} from "./chunk-5XNT2472.js";
|
|
8
|
+
import {
|
|
9
|
+
activity
|
|
10
|
+
} from "./chunk-NSE7VJQA.js";
|
|
11
|
+
|
|
12
|
+
// src/lib/activity-events.ts
|
|
13
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
14
|
+
function subscribe(callback) {
|
|
15
|
+
subscribers.add(callback);
|
|
16
|
+
return () => {
|
|
17
|
+
subscribers.delete(callback);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async function publish(event) {
|
|
21
|
+
const created_at = event.created_at ?? (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
22
|
+
let id = 0;
|
|
23
|
+
try {
|
|
24
|
+
const db = await getDb();
|
|
25
|
+
const result = await db.insert(activity).values({
|
|
26
|
+
type: event.type,
|
|
27
|
+
mind: event.mind,
|
|
28
|
+
summary: event.summary,
|
|
29
|
+
metadata: event.metadata ? JSON.stringify(event.metadata) : null,
|
|
30
|
+
created_at
|
|
31
|
+
});
|
|
32
|
+
id = Number(result.lastInsertRowid);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
logger_default.error("[activity-events] failed to persist activity", logger_default.errorData(err));
|
|
35
|
+
}
|
|
36
|
+
const full = { ...event, id, created_at };
|
|
37
|
+
notify(full);
|
|
38
|
+
}
|
|
39
|
+
function broadcast(event) {
|
|
40
|
+
const created_at = event.created_at ?? (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
41
|
+
notify({ ...event, id: 0, created_at });
|
|
42
|
+
}
|
|
43
|
+
function notify(event) {
|
|
44
|
+
for (const cb of subscribers) {
|
|
45
|
+
try {
|
|
46
|
+
cb(event);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
logger_default.error("[activity-events] subscriber threw:", logger_default.errorData(err));
|
|
49
|
+
subscribers.delete(cb);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export {
|
|
55
|
+
subscribe,
|
|
56
|
+
publish,
|
|
57
|
+
broadcast
|
|
58
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/lib/log-buffer.ts
|
|
4
|
+
var LogBuffer = class {
|
|
5
|
+
entries = [];
|
|
6
|
+
maxSize = 1e3;
|
|
7
|
+
subscribers = /* @__PURE__ */ new Set();
|
|
8
|
+
append(entry) {
|
|
9
|
+
this.entries.push(entry);
|
|
10
|
+
if (this.entries.length > this.maxSize) {
|
|
11
|
+
this.entries.shift();
|
|
12
|
+
}
|
|
13
|
+
for (const sub of this.subscribers) {
|
|
14
|
+
sub(entry);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
getEntries() {
|
|
18
|
+
return [...this.entries];
|
|
19
|
+
}
|
|
20
|
+
subscribe(fn) {
|
|
21
|
+
this.subscribers.add(fn);
|
|
22
|
+
return () => this.subscribers.delete(fn);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var logBuffer = new LogBuffer();
|
|
26
|
+
|
|
27
|
+
// src/lib/logger.ts
|
|
28
|
+
var LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
29
|
+
var minLevel = LEVELS[process.env.VOLUTE_LOG_LEVEL || "info"] ?? LEVELS.info;
|
|
30
|
+
var output = (line) => process.stderr.write(`${line}
|
|
31
|
+
`);
|
|
32
|
+
function write(level, cat, msg, data) {
|
|
33
|
+
if (LEVELS[level] < minLevel) return;
|
|
34
|
+
const entry = {
|
|
35
|
+
level,
|
|
36
|
+
cat,
|
|
37
|
+
msg,
|
|
38
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
39
|
+
...data ? { data } : {}
|
|
40
|
+
};
|
|
41
|
+
output(JSON.stringify(entry));
|
|
42
|
+
logBuffer.append(entry);
|
|
43
|
+
}
|
|
44
|
+
function child(cat) {
|
|
45
|
+
return {
|
|
46
|
+
debug: (msg, data) => write("debug", cat, msg, data),
|
|
47
|
+
info: (msg, data) => write("info", cat, msg, data),
|
|
48
|
+
warn: (msg, data) => write("warn", cat, msg, data),
|
|
49
|
+
error: (msg, data) => write("error", cat, msg, data)
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function errorData(err) {
|
|
53
|
+
if (err instanceof Error) return { error: err.stack ?? err.message };
|
|
54
|
+
return { error: String(err) };
|
|
55
|
+
}
|
|
56
|
+
var log = {
|
|
57
|
+
...child("system"),
|
|
58
|
+
child,
|
|
59
|
+
errorData,
|
|
60
|
+
setLevel(level) {
|
|
61
|
+
minLevel = LEVELS[level];
|
|
62
|
+
},
|
|
63
|
+
setOutput(fn) {
|
|
64
|
+
output = fn;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var logger_default = log;
|
|
68
|
+
|
|
69
|
+
export {
|
|
70
|
+
logBuffer,
|
|
71
|
+
logger_default
|
|
72
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -9,76 +9,82 @@ if (!process.env.VOLUTE_HOME) {
|
|
|
9
9
|
var command = process.argv[2];
|
|
10
10
|
var args = process.argv.slice(3);
|
|
11
11
|
if (command === "--version" || command === "-v") {
|
|
12
|
-
const { default: pkg } = await import("./package-
|
|
12
|
+
const { default: pkg } = await import("./package-4NHAVUUI.js");
|
|
13
13
|
console.log(pkg.version);
|
|
14
14
|
process.exit(0);
|
|
15
15
|
}
|
|
16
16
|
switch (command) {
|
|
17
17
|
case "mind":
|
|
18
|
-
await import("./mind-
|
|
18
|
+
await import("./mind-Z7CKD6DG.js").then((m) => m.run(args));
|
|
19
19
|
break;
|
|
20
20
|
case "send":
|
|
21
|
-
await import("./send-
|
|
21
|
+
await import("./send-KVIZIGCE.js").then((m) => m.run(args));
|
|
22
22
|
break;
|
|
23
23
|
case "history":
|
|
24
|
-
await import("./history-
|
|
24
|
+
await import("./history-WNK3DFUM.js").then((m) => m.run(args));
|
|
25
25
|
break;
|
|
26
26
|
case "variant":
|
|
27
|
-
await import("./variant-
|
|
27
|
+
await import("./variant-63ZWO2W7.js").then((m) => m.run(args));
|
|
28
28
|
break;
|
|
29
29
|
case "connector":
|
|
30
|
-
await import("./connector-
|
|
30
|
+
await import("./connector-JBVNZ7VK.js").then((m) => m.run(args));
|
|
31
31
|
break;
|
|
32
32
|
case "channel":
|
|
33
|
-
await import("./channel-
|
|
33
|
+
await import("./channel-PUQKGSQM.js").then((m) => m.run(args));
|
|
34
34
|
break;
|
|
35
35
|
case "schedule":
|
|
36
|
-
await import("./schedule-
|
|
36
|
+
await import("./schedule-FFZG23IW.js").then((m) => m.run(args));
|
|
37
37
|
break;
|
|
38
38
|
case "skill":
|
|
39
|
-
await import("./skill-
|
|
39
|
+
await import("./skill-BCVNI6TV.js").then((m) => m.run(args));
|
|
40
|
+
break;
|
|
41
|
+
case "shared":
|
|
42
|
+
await import("./shared-KO35ZM44.js").then((m) => m.run(args));
|
|
43
|
+
break;
|
|
44
|
+
case "file":
|
|
45
|
+
await import("./file-C57SK5DK.js").then((m) => m.run(args));
|
|
40
46
|
break;
|
|
41
47
|
case "env":
|
|
42
|
-
await import("./env-
|
|
48
|
+
await import("./env-A3LMO777.js").then((m) => m.run(args));
|
|
43
49
|
break;
|
|
44
50
|
case "up":
|
|
45
|
-
await import("./up-
|
|
51
|
+
await import("./up-FS7CKM6V.js").then((m) => m.run(args));
|
|
46
52
|
break;
|
|
47
53
|
case "down":
|
|
48
|
-
await import("./down-
|
|
54
|
+
await import("./down-ZY35KMHR.js").then((m) => m.run(args));
|
|
49
55
|
break;
|
|
50
56
|
case "restart":
|
|
51
|
-
await import("./daemon-restart-
|
|
57
|
+
await import("./daemon-restart-KPSWNYTH.js").then((m) => m.run(args));
|
|
52
58
|
break;
|
|
53
59
|
case "setup":
|
|
54
|
-
await import("./setup-
|
|
60
|
+
await import("./setup-52YRV7VP.js").then((m) => m.run(args));
|
|
55
61
|
break;
|
|
56
62
|
case "service":
|
|
57
|
-
await import("./service-
|
|
63
|
+
await import("./service-LUR7WDO7.js").then((m) => m.run(args));
|
|
58
64
|
break;
|
|
59
65
|
case "update":
|
|
60
|
-
await import("./update-
|
|
66
|
+
await import("./update-FJIHDJKM.js").then((m) => m.run(args));
|
|
61
67
|
break;
|
|
62
68
|
case "status":
|
|
63
|
-
await import("./status-
|
|
69
|
+
await import("./status-4ESFLGH4.js").then((m) => m.run(args));
|
|
64
70
|
break;
|
|
65
71
|
case "seed":
|
|
66
|
-
await import("./seed-
|
|
72
|
+
await import("./seed-J43YDKXG.js").then((m) => m.run(args));
|
|
67
73
|
break;
|
|
68
74
|
case "sprout":
|
|
69
|
-
await import("./sprout-
|
|
75
|
+
await import("./sprout-QN7Y4VVO.js").then((m) => m.run(args));
|
|
70
76
|
break;
|
|
71
77
|
case "pages":
|
|
72
|
-
await import("./pages-
|
|
78
|
+
await import("./pages-4DGQT7ZA.js").then((m) => m.run(args));
|
|
73
79
|
break;
|
|
74
80
|
case "register":
|
|
75
|
-
await import("./register-
|
|
81
|
+
await import("./register-VSPCMHKX.js").then((m) => m.run(args));
|
|
76
82
|
break;
|
|
77
83
|
case "login":
|
|
78
|
-
await import("./login-
|
|
84
|
+
await import("./login-HNH3EUQV.js").then((m) => m.run(args));
|
|
79
85
|
break;
|
|
80
86
|
case "logout":
|
|
81
|
-
await import("./logout-
|
|
87
|
+
await import("./logout-I5CB5UZS.js").then((m) => m.run());
|
|
82
88
|
break;
|
|
83
89
|
case "--help":
|
|
84
90
|
case "-h":
|
|
@@ -126,6 +132,18 @@ Commands:
|
|
|
126
132
|
volute skill remove <name> Remove a shared skill
|
|
127
133
|
volute skill uninstall <name> --mind Uninstall a skill from a mind
|
|
128
134
|
|
|
135
|
+
volute file send <path> <mind> Send a file to another mind
|
|
136
|
+
volute file list List pending incoming files
|
|
137
|
+
volute file accept <id> Accept a pending file
|
|
138
|
+
volute file reject <id> Reject a pending file
|
|
139
|
+
volute file trust <sender> Trust a sender (auto-deliver)
|
|
140
|
+
volute file untrust <sender> Remove sender trust
|
|
141
|
+
|
|
142
|
+
volute shared merge "<msg>" Merge shared changes to main
|
|
143
|
+
volute shared pull Pull latest shared changes
|
|
144
|
+
volute shared log Show shared repo history
|
|
145
|
+
volute shared status Show pending changes diff
|
|
146
|
+
|
|
129
147
|
volute env <set|get|list|remove> Manage environment variables
|
|
130
148
|
|
|
131
149
|
volute up [--port N] Start the daemon (default: 4200)
|
|
@@ -155,7 +173,7 @@ Options:
|
|
|
155
173
|
--version, -v Show version number
|
|
156
174
|
--help, -h Show this help message
|
|
157
175
|
|
|
158
|
-
Mind-scoped commands (send, history, variant, connector, schedule, channel, skill, pages)
|
|
176
|
+
Mind-scoped commands (send, history, variant, connector, schedule, channel, file, skill, shared, pages)
|
|
159
177
|
use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
|
|
160
178
|
break;
|
|
161
179
|
default:
|
|
@@ -164,7 +182,7 @@ Run 'volute --help' for usage.`);
|
|
|
164
182
|
process.exit(1);
|
|
165
183
|
}
|
|
166
184
|
if (command !== "update") {
|
|
167
|
-
import("./update-check-
|
|
185
|
+
import("./update-check-MWE5AH4U.js").then((m) => m.checkForUpdate()).then((result) => {
|
|
168
186
|
if (result.updateAvailable) {
|
|
169
187
|
console.error(`
|
|
170
188
|
Update available: ${result.current} \u2192 ${result.latest}`);
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
promptLine
|
|
4
4
|
} from "./chunk-RVKR2R7F.js";
|
|
5
|
+
import {
|
|
6
|
+
getClient,
|
|
7
|
+
urlOf
|
|
8
|
+
} from "./chunk-4RQBJWQX.js";
|
|
5
9
|
import {
|
|
6
10
|
resolveMindName
|
|
7
11
|
} from "./chunk-NAOW2CLO.js";
|
|
@@ -10,12 +14,8 @@ import {
|
|
|
10
14
|
} from "./chunk-D424ZQGI.js";
|
|
11
15
|
import {
|
|
12
16
|
daemonFetch
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import {
|
|
16
|
-
getClient,
|
|
17
|
-
urlOf
|
|
18
|
-
} from "./chunk-4RQBJWQX.js";
|
|
17
|
+
} from "./chunk-WC6ZHVRL.js";
|
|
18
|
+
import "./chunk-EBGCNDMM.js";
|
|
19
19
|
import "./chunk-K3NQKI34.js";
|
|
20
20
|
|
|
21
21
|
// src/commands/connector.ts
|
package/dist/connectors/slack.js
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
loadFollowedChannels,
|
|
6
6
|
sendToMind,
|
|
7
7
|
writeChannelEntry
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-RHEGSQFJ.js";
|
|
9
|
+
import "../chunk-EBGCNDMM.js";
|
|
10
10
|
import "../chunk-K3NQKI34.js";
|
|
11
11
|
|
|
12
12
|
// src/connectors/telegram.ts
|
|
@@ -7,21 +7,23 @@ import "./chunk-K3NQKI34.js";
|
|
|
7
7
|
// src/commands/create.ts
|
|
8
8
|
async function run(args) {
|
|
9
9
|
const { positional, flags } = parseArgs(args, {
|
|
10
|
-
template: { type: "string" }
|
|
10
|
+
template: { type: "string" },
|
|
11
|
+
skills: { type: "string" }
|
|
11
12
|
});
|
|
12
13
|
const name = positional[0];
|
|
13
14
|
const template = flags.template ?? "claude";
|
|
14
15
|
if (!name) {
|
|
15
|
-
console.error("Usage: volute mind create <name> [--template <name>]");
|
|
16
|
+
console.error("Usage: volute mind create <name> [--template <name>] [--skills <list|none>]");
|
|
16
17
|
process.exit(1);
|
|
17
18
|
}
|
|
18
|
-
const
|
|
19
|
+
const skills = flags.skills === "none" ? [] : flags.skills ? flags.skills.split(",") : void 0;
|
|
20
|
+
const { daemonFetch } = await import("./daemon-client-ITWUCNFO.js");
|
|
19
21
|
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
20
22
|
const client = getClient();
|
|
21
23
|
const res = await daemonFetch(urlOf(client.api.minds.$url()), {
|
|
22
24
|
method: "POST",
|
|
23
25
|
headers: { "Content-Type": "application/json" },
|
|
24
|
-
body: JSON.stringify({ name, template })
|
|
26
|
+
body: JSON.stringify({ name, template, skills })
|
|
25
27
|
});
|
|
26
28
|
const data = await res.json();
|
|
27
29
|
if (!res.ok) {
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
run
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7UFKREVW.js";
|
|
5
5
|
import {
|
|
6
6
|
stopDaemon
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7NO7EV5Z.js";
|
|
8
8
|
import {
|
|
9
9
|
getServiceMode,
|
|
10
10
|
modeLabel,
|
|
11
11
|
pollHealth,
|
|
12
12
|
readDaemonConfig,
|
|
13
13
|
restartService
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-2Y77MCFG.js";
|
|
16
|
-
import "./chunk-ZCEYUUID.js";
|
|
14
|
+
} from "./chunk-32VR2EOH.js";
|
|
17
15
|
import "./chunk-D424ZQGI.js";
|
|
18
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-DYZGP3EW.js";
|
|
17
|
+
import "./chunk-OGXOMR65.js";
|
|
18
|
+
import "./chunk-EBGCNDMM.js";
|
|
19
19
|
import "./chunk-K3NQKI34.js";
|
|
20
20
|
|
|
21
21
|
// src/commands/daemon-restart.ts
|