volute 0.19.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 +66 -66
- package/dist/activity-events-OMXKXD5N.js +16 -0
- package/dist/{chunk-Z524RFCJ.js → chunk-5XNT2472.js} +1 -1
- package/dist/{chunk-FGV2H4TX.js → chunk-FGSYHIS3.js} +112 -24
- package/dist/chunk-GZ7DW4YL.js +97 -0
- package/dist/{chunk-OTWLI7F4.js → chunk-IKMY5X76.js} +2 -2
- package/dist/{chunk-VQWDC6UK.js → chunk-NSE7VJQA.js} +17 -0
- package/dist/{chunk-EMQSAY3B.js → chunk-O6ASDHFO.js} +2 -1
- package/dist/{chunk-2TJGRJ4O.js → chunk-PUVXOZ6T.js} +8 -2
- package/dist/{chunk-4KPUF5JD.js → chunk-TIWH32HP.js} +15 -2
- package/dist/chunk-UU7A7KLB.js +58 -0
- package/dist/cli.js +19 -9
- package/dist/{daemon-restart-JMZM3QY4.js → daemon-restart-KPSWNYTH.js} +3 -3
- package/dist/daemon.js +1802 -1082
- package/dist/{db-5ZVC6MQF.js → db-C2CJ46ZU.js} +2 -2
- package/dist/{delivery-manager-ISTJMZDW.js → delivery-manager-CSG7LXA4.js} +3 -3
- package/dist/{export-GCDNQCF3.js → export-6QBUOQGC.js} +2 -2
- package/dist/file-C57SK5DK.js +204 -0
- package/dist/{import-M63VIUJ5.js → import-XEC34Y4Z.js} +1 -1
- package/dist/{mind-PQ5NCPSU.js → mind-Z7CKD6DG.js} +2 -2
- package/dist/mind-activity-tracker-624QLQLC.js +19 -0
- package/dist/{mind-manager-RVCFROAY.js → mind-manager-3DMYKZPB.js} +3 -3
- package/dist/{package-MYE2ZJLV.js → package-4NHAVUUI.js} +1 -1
- package/dist/{pages-AXCOSY3P.js → pages-4DGQT7ZA.js} +2 -2
- package/dist/{publish-YB377JB7.js → publish-TAJUET4I.js} +7 -4
- package/dist/{schedule-LMX7GAQZ.js → schedule-FFZG23IW.js} +25 -5
- package/dist/{schema-5BW7DFZI.js → schema-GFH6RV3W.js} +3 -1
- package/dist/{setup-OH3PJUJO.js → setup-52YRV7VP.js} +16 -0
- package/dist/skills/volute-mind/SKILL.md +33 -3
- package/dist/{sprout-VBEX63LX.js → sprout-QN7Y4VVO.js} +3 -3
- package/dist/{status-JCJAOXTW.js → status-FU2PFVVF.js} +3 -2
- package/dist/{up-WG65SWJU.js → up-FS7CKM6V.js} +1 -1
- 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/0012_activity.sql +11 -0
- package/drizzle/meta/0012_snapshot.json +7 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/templates/_base/home/.config/routes.json +2 -2
- package/templates/_base/home/VOLUTE.md +1 -1
- package/templates/_base/src/lib/daemon-client.ts +22 -0
- package/templates/_base/src/lib/transparency.ts +1 -1
- package/templates/claude/.init/.config/routes.json +7 -1
- package/templates/pi/.init/.config/routes.json +7 -1
- package/templates/pi/src/agent.ts +11 -5
- package/templates/pi/src/lib/session-context-extension.ts +6 -4
- package/templates/pi/src/server.ts +2 -0
- package/dist/web-assets/assets/index-BAbuRsVF.css +0 -1
- package/dist/web-assets/assets/index-CiQhSKi_.js +0 -63
- /package/dist/{chunk-VE4D3GOP.js → chunk-7UFKREVW.js} +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
publish
|
|
4
|
+
} from "./chunk-UU7A7KLB.js";
|
|
5
|
+
import {
|
|
6
|
+
logger_default
|
|
7
|
+
} from "./chunk-YUIHSKR6.js";
|
|
8
|
+
|
|
9
|
+
// src/lib/mind-activity-tracker.ts
|
|
10
|
+
var IDLE_TIMEOUT_MS = 2 * 60 * 1e3;
|
|
11
|
+
var minds = /* @__PURE__ */ new Map();
|
|
12
|
+
function getState(mind) {
|
|
13
|
+
let state = minds.get(mind);
|
|
14
|
+
if (!state) {
|
|
15
|
+
state = { active: false, idleTimer: null };
|
|
16
|
+
minds.set(mind, state);
|
|
17
|
+
}
|
|
18
|
+
return state;
|
|
19
|
+
}
|
|
20
|
+
var IGNORED_EVENTS = /* @__PURE__ */ new Set(["done", "usage", "log"]);
|
|
21
|
+
function onMindEvent(mind, type, channel) {
|
|
22
|
+
const state = getState(mind);
|
|
23
|
+
if (type === "done") {
|
|
24
|
+
state.active = false;
|
|
25
|
+
if (state.idleTimer) {
|
|
26
|
+
clearTimeout(state.idleTimer);
|
|
27
|
+
}
|
|
28
|
+
state.idleTimer = setTimeout(() => {
|
|
29
|
+
state.idleTimer = null;
|
|
30
|
+
if (!state.active) {
|
|
31
|
+
publish({
|
|
32
|
+
type: "mind_idle",
|
|
33
|
+
mind,
|
|
34
|
+
summary: `${mind} is idle`
|
|
35
|
+
}).catch((err) => {
|
|
36
|
+
logger_default.error("[mind-activity] failed to publish mind_idle", logger_default.errorData(err));
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}, IDLE_TIMEOUT_MS);
|
|
40
|
+
} else if (!IGNORED_EVENTS.has(type)) {
|
|
41
|
+
if (state.idleTimer) {
|
|
42
|
+
clearTimeout(state.idleTimer);
|
|
43
|
+
state.idleTimer = null;
|
|
44
|
+
}
|
|
45
|
+
if (!state.active) {
|
|
46
|
+
state.active = true;
|
|
47
|
+
state.channel = channel;
|
|
48
|
+
publish({
|
|
49
|
+
type: "mind_active",
|
|
50
|
+
mind,
|
|
51
|
+
summary: `${mind} is active`,
|
|
52
|
+
metadata: channel ? { channel } : void 0
|
|
53
|
+
}).catch((err) => {
|
|
54
|
+
logger_default.error("[mind-activity] failed to publish mind_active", logger_default.errorData(err));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function markIdle(mind) {
|
|
60
|
+
const state = minds.get(mind);
|
|
61
|
+
if (!state) return;
|
|
62
|
+
if (state.idleTimer) {
|
|
63
|
+
clearTimeout(state.idleTimer);
|
|
64
|
+
state.idleTimer = null;
|
|
65
|
+
}
|
|
66
|
+
if (state.active) {
|
|
67
|
+
state.active = false;
|
|
68
|
+
publish({
|
|
69
|
+
type: "mind_idle",
|
|
70
|
+
mind,
|
|
71
|
+
summary: `${mind} is idle`
|
|
72
|
+
}).catch((err) => {
|
|
73
|
+
logger_default.error("[mind-activity] failed to publish mind_idle", logger_default.errorData(err));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
minds.delete(mind);
|
|
77
|
+
}
|
|
78
|
+
function getActiveMinds() {
|
|
79
|
+
const result = [];
|
|
80
|
+
for (const [mind, state] of minds) {
|
|
81
|
+
if (state.active) result.push(mind);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
function stopAll() {
|
|
86
|
+
for (const [, state] of minds) {
|
|
87
|
+
if (state.idleTimer) clearTimeout(state.idleTimer);
|
|
88
|
+
}
|
|
89
|
+
minds.clear();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export {
|
|
93
|
+
onMindEvent,
|
|
94
|
+
markIdle,
|
|
95
|
+
getActiveMinds,
|
|
96
|
+
stopAll
|
|
97
|
+
};
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
// src/lib/schema.ts
|
|
7
7
|
var schema_exports = {};
|
|
8
8
|
__export(schema_exports, {
|
|
9
|
+
activity: () => activity,
|
|
9
10
|
conversationParticipants: () => conversationParticipants,
|
|
10
11
|
conversations: () => conversations,
|
|
11
12
|
deliveryQueue: () => deliveryQueue,
|
|
@@ -115,6 +116,21 @@ var deliveryQueue = sqliteTable(
|
|
|
115
116
|
index("idx_delivery_queue_mind_status").on(table.mind, table.status)
|
|
116
117
|
]
|
|
117
118
|
);
|
|
119
|
+
var activity = sqliteTable(
|
|
120
|
+
"activity",
|
|
121
|
+
{
|
|
122
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
123
|
+
type: text("type").notNull(),
|
|
124
|
+
mind: text("mind").notNull(),
|
|
125
|
+
summary: text("summary").notNull(),
|
|
126
|
+
metadata: text("metadata"),
|
|
127
|
+
created_at: text("created_at").notNull().default(sql`(datetime('now'))`)
|
|
128
|
+
},
|
|
129
|
+
(table) => [
|
|
130
|
+
index("idx_activity_created_at").on(table.created_at),
|
|
131
|
+
index("idx_activity_mind").on(table.mind)
|
|
132
|
+
]
|
|
133
|
+
);
|
|
118
134
|
var messages = sqliteTable(
|
|
119
135
|
"messages",
|
|
120
136
|
{
|
|
@@ -137,6 +153,7 @@ export {
|
|
|
137
153
|
systemPrompts,
|
|
138
154
|
sharedSkills,
|
|
139
155
|
deliveryQueue,
|
|
156
|
+
activity,
|
|
140
157
|
messages,
|
|
141
158
|
schema_exports
|
|
142
159
|
};
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
} from "./chunk-VDWCHYTS.js";
|
|
8
8
|
import {
|
|
9
9
|
getDb
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5XNT2472.js";
|
|
11
11
|
import {
|
|
12
12
|
systemPrompts
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NSE7VJQA.js";
|
|
14
14
|
import {
|
|
15
15
|
chownMindDir,
|
|
16
16
|
isIsolationEnabled,
|
|
@@ -505,6 +505,12 @@ var MindManager = class {
|
|
|
505
505
|
this.minds.delete(name);
|
|
506
506
|
if (this.shuttingDown || this.stopping.has(name)) return;
|
|
507
507
|
mlog.error(`mind ${name} exited with code ${code}`);
|
|
508
|
+
import("./mind-activity-tracker-624QLQLC.js").then(({ markIdle }) => markIdle(name)).catch(() => {
|
|
509
|
+
});
|
|
510
|
+
import("./activity-events-OMXKXD5N.js").then(
|
|
511
|
+
({ publish }) => publish({ type: "mind_stopped", mind: name, summary: `${name} crashed (exit ${code})` })
|
|
512
|
+
).catch(() => {
|
|
513
|
+
});
|
|
508
514
|
const { shouldRestart, delay, attempt } = this.restartTracker.recordCrash(name);
|
|
509
515
|
this.saveCrashAttempts();
|
|
510
516
|
if (!shouldRestart) {
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
|
|
16
16
|
// src/lib/shared.ts
|
|
17
17
|
import { execFileSync } from "child_process";
|
|
18
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
18
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
19
19
|
import { resolve } from "path";
|
|
20
20
|
function readWorktreeGitDir(worktreePath) {
|
|
21
21
|
const dotGit = resolve(worktreePath, ".git");
|
|
@@ -34,7 +34,20 @@ function sharedDir() {
|
|
|
34
34
|
async function ensureSharedRepo() {
|
|
35
35
|
const dir = sharedDir();
|
|
36
36
|
mkdirSync(dir, { recursive: true });
|
|
37
|
-
if (existsSync(resolve(dir, ".git")))
|
|
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
|
+
}
|
|
38
51
|
const initArgs = isIsolationEnabled() ? ["init", "--shared=group"] : ["init"];
|
|
39
52
|
await gitExec(initArgs, { cwd: dir });
|
|
40
53
|
await gitExec(["checkout", "-b", "main"], { cwd: dir });
|
|
@@ -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
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -9,13 +9,13 @@ 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
21
|
await import("./send-KVIZIGCE.js").then((m) => m.run(args));
|
|
@@ -33,7 +33,7 @@ switch (command) {
|
|
|
33
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
39
|
await import("./skill-BCVNI6TV.js").then((m) => m.run(args));
|
|
@@ -41,20 +41,23 @@ switch (command) {
|
|
|
41
41
|
case "shared":
|
|
42
42
|
await import("./shared-KO35ZM44.js").then((m) => m.run(args));
|
|
43
43
|
break;
|
|
44
|
+
case "file":
|
|
45
|
+
await import("./file-C57SK5DK.js").then((m) => m.run(args));
|
|
46
|
+
break;
|
|
44
47
|
case "env":
|
|
45
48
|
await import("./env-A3LMO777.js").then((m) => m.run(args));
|
|
46
49
|
break;
|
|
47
50
|
case "up":
|
|
48
|
-
await import("./up-
|
|
51
|
+
await import("./up-FS7CKM6V.js").then((m) => m.run(args));
|
|
49
52
|
break;
|
|
50
53
|
case "down":
|
|
51
54
|
await import("./down-ZY35KMHR.js").then((m) => m.run(args));
|
|
52
55
|
break;
|
|
53
56
|
case "restart":
|
|
54
|
-
await import("./daemon-restart-
|
|
57
|
+
await import("./daemon-restart-KPSWNYTH.js").then((m) => m.run(args));
|
|
55
58
|
break;
|
|
56
59
|
case "setup":
|
|
57
|
-
await import("./setup-
|
|
60
|
+
await import("./setup-52YRV7VP.js").then((m) => m.run(args));
|
|
58
61
|
break;
|
|
59
62
|
case "service":
|
|
60
63
|
await import("./service-LUR7WDO7.js").then((m) => m.run(args));
|
|
@@ -69,10 +72,10 @@ switch (command) {
|
|
|
69
72
|
await import("./seed-J43YDKXG.js").then((m) => m.run(args));
|
|
70
73
|
break;
|
|
71
74
|
case "sprout":
|
|
72
|
-
await import("./sprout-
|
|
75
|
+
await import("./sprout-QN7Y4VVO.js").then((m) => m.run(args));
|
|
73
76
|
break;
|
|
74
77
|
case "pages":
|
|
75
|
-
await import("./pages-
|
|
78
|
+
await import("./pages-4DGQT7ZA.js").then((m) => m.run(args));
|
|
76
79
|
break;
|
|
77
80
|
case "register":
|
|
78
81
|
await import("./register-VSPCMHKX.js").then((m) => m.run(args));
|
|
@@ -129,6 +132,13 @@ Commands:
|
|
|
129
132
|
volute skill remove <name> Remove a shared skill
|
|
130
133
|
volute skill uninstall <name> --mind Uninstall a skill from a mind
|
|
131
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
|
+
|
|
132
142
|
volute shared merge "<msg>" Merge shared changes to main
|
|
133
143
|
volute shared pull Pull latest shared changes
|
|
134
144
|
volute shared log Show shared repo history
|
|
@@ -163,7 +173,7 @@ Options:
|
|
|
163
173
|
--version, -v Show version number
|
|
164
174
|
--help, -h Show this help message
|
|
165
175
|
|
|
166
|
-
Mind-scoped commands (send, history, variant, connector, schedule, channel, skill, shared, pages)
|
|
176
|
+
Mind-scoped commands (send, history, variant, connector, schedule, channel, file, skill, shared, pages)
|
|
167
177
|
use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
|
|
168
178
|
break;
|
|
169
179
|
default:
|