volute 0.20.0 → 0.22.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 +7 -7
- package/dist/{activity-events-OMXKXD5N.js → activity-events-3WHHCOBB.js} +3 -4
- package/dist/api.d.ts +4294 -0
- package/dist/{archive-ZCFOSTKB.js → archive-4ZQYK5MN.js} +4 -2
- package/dist/auth-HM2RSPY7.js +37 -0
- package/dist/{channel-PUQKGSQM.js → channel-BOOMFULW.js} +2 -2
- package/dist/{chunk-UU7A7KLB.js → chunk-A4S7H6G6.js} +5 -7
- package/dist/chunk-AKPFNL7L.js +148 -0
- package/dist/{chunk-EBGCNDMM.js → chunk-B2CPS4QU.js} +128 -114
- package/dist/chunk-G5KRTU2F.js +76 -0
- package/dist/{chunk-FCDU5BFX.js → chunk-HFCBO2GL.js} +2 -2
- package/dist/{chunk-GZ7DW4YL.js → chunk-HGCDWKSP.js} +2 -2
- package/dist/{chunk-7UFKREVW.js → chunk-JNFRY2WU.js} +2 -2
- package/dist/{chunk-DYZGP3EW.js → chunk-JTDFJWI2.js} +2 -1
- package/dist/{chunk-WC6ZHVRL.js → chunk-KFI7TQJ6.js} +2 -2
- package/dist/{chunk-AW7P4EVV.js → chunk-KTJGZ7M7.js} +55 -7
- package/dist/{chunk-OGXOMR65.js → chunk-NWPT4ASZ.js} +1 -1
- package/dist/{chunk-SCUDS4US.js → chunk-ON3FF5JA.js} +1 -1
- package/dist/chunk-OSFGKF2T.js +2651 -0
- package/dist/{chunk-TIWH32HP.js → chunk-PHHKNGA3.js} +3 -3
- package/dist/{chunk-VDWCHYTS.js → chunk-PHU4DEAJ.js} +1 -1
- package/dist/{chunk-7NO7EV5Z.js → chunk-QIXPN3OO.js} +2 -2
- package/dist/{chunk-O6ASDHFO.js → chunk-RK627D57.js} +40 -63
- package/dist/{chunk-NSE7VJQA.js → chunk-SGPEZ32F.js} +29 -1
- package/dist/{chunk-IKMY5X76.js → chunk-TFS25FIM.js} +12 -9
- package/dist/{chunk-PUVXOZ6T.js → chunk-VNVCRVYI.js} +118 -69
- package/dist/{chunk-32VR2EOH.js → chunk-VT5QODNE.js} +2 -2
- package/dist/{chunk-RHEGSQFJ.js → chunk-WSLPZF72.js} +1 -1
- package/dist/chunk-XLC342FO.js +29 -0
- package/dist/cli.js +57 -119
- package/dist/cloud-sync-C6WRYRVR.js +96 -0
- package/dist/{connector-JBVNZ7VK.js → connector-PYT5UOTZ.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-HP4OVVHF.js → create-WIDA3M4C.js} +1 -1
- package/dist/{daemon-client-ITWUCNFO.js → daemon-client-ZHCDL4RS.js} +2 -2
- package/dist/{daemon-restart-KPSWNYTH.js → daemon-restart-TPQ2XBRZ.js} +6 -6
- package/dist/daemon.js +2250 -1985
- package/dist/{delete-BSU7K3RY.js → delete-LOIANQGD.js} +1 -1
- package/dist/down-WSUASL5E.js +14 -0
- package/dist/{env-A3LMO777.js → env-4PHIHTF4.js} +2 -2
- package/dist/{export-6QBUOQGC.js → export-XD6PJBQP.js} +19 -8
- package/dist/{file-C57SK5DK.js → file-X4L5TTOL.js} +2 -2
- package/dist/{history-WNK3DFUM.js → history-HTEKRNID.js} +2 -2
- package/dist/{import-XEC34Y4Z.js → import-EAXTHHXL.js} +4 -3
- package/dist/{log-PPPZDVEF.js → log-SRO5Q6AD.js} +2 -2
- package/dist/{login-HNH3EUQV.js → login-UO6AOVEA.js} +4 -4
- package/dist/{logout-I5CB5UZS.js → logout-UKD5LA37.js} +2 -2
- package/dist/{logs-SF2IMJN4.js → logs-HNTNNBDW.js} +2 -2
- package/dist/{merge-33C237A4.js → merge-B6SYTGI7.js} +2 -2
- package/dist/message-delivery-WUS4K4ZC.js +21 -0
- package/dist/{mind-Z7CKD6DG.js → mind-BTXR5B3C.js} +35 -11
- package/dist/{mind-activity-tracker-624QLQLC.js → mind-activity-tracker-PGC3DBJ7.js} +4 -5
- package/dist/{mind-manager-3DMYKZPB.js → mind-manager-P5OBDUKI.js} +5 -6
- package/dist/mind-sleep-FWRBIFBS.js +41 -0
- package/dist/mind-wake-LJK2YU5X.js +36 -0
- package/dist/{package-4NHAVUUI.js → package-A7PEYJI2.js} +10 -1
- package/dist/{pages-4DGQT7ZA.js → pages-YSTRWJR4.js} +6 -6
- package/dist/{publish-TAJUET4I.js → publish-BZNHKUUK.js} +6 -6
- package/dist/{pull-XAEWQJ47.js → pull-GRQAXM2E.js} +2 -2
- package/dist/{register-VSPCMHKX.js → register-U2UO6TC4.js} +5 -5
- package/dist/registry-D2BSQ2X5.js +42 -0
- package/dist/{restart-IQKMCK5M.js → restart-CIDAKGG2.js} +3 -6
- package/dist/{schedule-FFZG23IW.js → schedule-NLR3LZLY.js} +2 -2
- package/dist/{seed-J43YDKXG.js → seed-3H2MRREW.js} +2 -2
- package/dist/{send-KVIZIGCE.js → send-RP2TA7SG.js} +132 -36
- package/dist/{service-LUR7WDO7.js → service-7BFXDI6J.js} +31 -13
- package/dist/{setup-52YRV7VP.js → setup-SSIIXQMI.js} +9 -34
- package/dist/{shared-KO35ZM44.js → shared-2OGT3NSL.js} +4 -4
- package/dist/{skill-BCVNI6TV.js → skill-Q2Y6PQ3L.js} +2 -2
- package/dist/skills/orientation/SKILL.md +2 -2
- package/dist/skills/volute-mind/SKILL.md +5 -5
- package/dist/sleep-manager-3RWUX2ZR.js +27 -0
- package/dist/{sprout-QN7Y4VVO.js → sprout-UKCYBGHK.js} +34 -30
- package/dist/{start-I5JYB65M.js → start-JR6CUUWF.js} +3 -6
- package/dist/{status-D7E5HHBV.js → status-5XDGYHKP.js} +2 -2
- package/dist/{status-4ESFLGH4.js → status-H2MKDN6L.js} +5 -5
- package/dist/{status-FU2PFVVF.js → status-LV34BG6G.js} +3 -3
- package/dist/{stop-NBVKEFQQ.js → stop-VKPGK25U.js} +2 -5
- package/dist/template-hash-BIMA4ILT.js +8 -0
- package/dist/{up-FS7CKM6V.js → up-JKGC7PPF.js} +5 -5
- package/dist/{update-FJIHDJKM.js → update-ELC6MEUT.js} +5 -5
- package/dist/{update-check-MWE5AH4U.js → update-check-F5Z3ALXX.js} +2 -2
- package/dist/{upgrade-AIT24B5I.js → upgrade-GXW2EQY3.js} +12 -3
- package/dist/{variant-63ZWO2W7.js → variant-A4I7PHXS.js} +16 -24
- package/dist/version-notify-5FGUAVSF.js +181 -0
- package/dist/web-assets/assets/index-DWBxl4LO.js +69 -0
- package/dist/web-assets/assets/index-ZqMd1mx1.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +10 -1
- package/templates/_base/.init/.config/prompts.json +1 -0
- package/templates/_base/home/.config/config.json.tmpl +4 -1
- package/templates/_base/src/lib/logger.ts +68 -23
- package/templates/_base/src/lib/startup.ts +12 -3
- package/templates/claude/src/agent.ts +150 -29
- package/templates/claude/src/lib/hooks/pre-compact.ts +18 -4
- package/templates/claude/src/lib/message-channel.ts +6 -0
- package/templates/claude/src/lib/stream-consumer.ts +7 -0
- package/templates/claude/src/server.ts +3 -1
- package/templates/pi/home/.config/config.json.tmpl +4 -1
- package/templates/pi/src/agent.ts +87 -0
- package/templates/pi/src/lib/event-handler.ts +13 -1
- package/templates/pi/src/server.ts +3 -1
- package/dist/chunk-5XNT2472.js +0 -36
- package/dist/chunk-FGSYHIS3.js +0 -891
- package/dist/chunk-UJ6GHNR7.js +0 -675
- package/dist/db-C2CJ46ZU.js +0 -10
- package/dist/delivery-manager-CSG7LXA4.js +0 -16
- package/dist/down-ZY35KMHR.js +0 -14
- package/dist/schema-GFH6RV3W.js +0 -26
- package/dist/variants-JAGWGBXG.js +0 -26
- package/dist/web-assets/assets/index-CUZTZzaW.js +0 -64
- package/dist/web-assets/assets/index-adVuCkqy.css +0 -1
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
STANDARD_SKILLS
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
uninstallSkill
|
|
7
|
-
} from "./chunk-IKMY5X76.js";
|
|
3
|
+
STANDARD_SKILLS
|
|
4
|
+
} from "./chunk-TFS25FIM.js";
|
|
5
|
+
import "./chunk-SGPEZ32F.js";
|
|
8
6
|
import "./chunk-YUIHSKR6.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-DYZGP3EW.js";
|
|
12
|
-
import "./chunk-OGXOMR65.js";
|
|
7
|
+
import "./chunk-JTDFJWI2.js";
|
|
8
|
+
import "./chunk-NWPT4ASZ.js";
|
|
13
9
|
import {
|
|
14
10
|
findMind,
|
|
15
11
|
mindDir
|
|
16
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-B2CPS4QU.js";
|
|
17
13
|
import "./chunk-K3NQKI34.js";
|
|
18
14
|
|
|
19
15
|
// src/commands/sprout.ts
|
|
@@ -23,7 +19,7 @@ var ORIENTATION_MARKER = "You don't have a soul yet";
|
|
|
23
19
|
async function run(_args) {
|
|
24
20
|
const mindName = process.env.VOLUTE_MIND;
|
|
25
21
|
if (!mindName) {
|
|
26
|
-
console.error("volute sprout must be run by a mind (VOLUTE_MIND not set)");
|
|
22
|
+
console.error("volute mind sprout must be run by a mind (VOLUTE_MIND not set)");
|
|
27
23
|
process.exit(1);
|
|
28
24
|
}
|
|
29
25
|
const entry = findMind(mindName);
|
|
@@ -53,44 +49,52 @@ async function run(_args) {
|
|
|
53
49
|
console.error("Write your MEMORY.md before sprouting.");
|
|
54
50
|
process.exit(1);
|
|
55
51
|
}
|
|
52
|
+
const { daemonFetch } = await import("./daemon-client-ZHCDL4RS.js");
|
|
53
|
+
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
54
|
+
const client = getClient();
|
|
56
55
|
const failedSkills = [];
|
|
57
56
|
for (const skillId of STANDARD_SKILLS) {
|
|
58
|
-
const shared = await getSharedSkill(skillId);
|
|
59
|
-
if (!shared) {
|
|
60
|
-
console.error(`Shared skill not found: ${skillId} \u2014 run 'volute up' to sync built-in skills`);
|
|
61
|
-
failedSkills.push(skillId);
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
57
|
const skillDir = resolve(dir, "home", ".claude", "skills", skillId);
|
|
65
58
|
if (!existsSync(skillDir)) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
const installRes = await daemonFetch(
|
|
60
|
+
urlOf(client.api.minds[":name"].skills.install.$url({ param: { name: mindName } })),
|
|
61
|
+
{
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: { "Content-Type": "application/json" },
|
|
64
|
+
body: JSON.stringify({ skillId })
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
if (!installRes.ok) {
|
|
68
|
+
const data = await installRes.json().catch(() => ({ error: `HTTP ${installRes.status}` }));
|
|
69
|
+
console.error(`Failed to install skill ${skillId}: ${data.error}`);
|
|
70
70
|
failedSkills.push(skillId);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
const orientationDir = resolve(dir, "home", ".claude", "skills", "orientation");
|
|
75
75
|
if (existsSync(orientationDir)) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
const delRes = await daemonFetch(
|
|
77
|
+
urlOf(
|
|
78
|
+
client.api.minds[":name"].skills[":skill"].$url({
|
|
79
|
+
param: { name: mindName, skill: "orientation" }
|
|
80
|
+
})
|
|
81
|
+
),
|
|
82
|
+
{ method: "DELETE" }
|
|
83
|
+
);
|
|
84
|
+
if (!delRes.ok) {
|
|
85
|
+
const data = await delRes.json().catch(() => ({ error: `HTTP ${delRes.status}` }));
|
|
86
|
+
console.error(`Failed to uninstall orientation skill: ${data.error}`);
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
89
|
if (failedSkills.length > 0) {
|
|
83
90
|
console.error(`Warning: failed to install skills: ${failedSkills.join(", ")}`);
|
|
84
91
|
}
|
|
85
|
-
const { daemonFetch } = await import("./daemon-client-ITWUCNFO.js");
|
|
86
|
-
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
87
|
-
const client = getClient();
|
|
88
92
|
const sproutRes = await daemonFetch(
|
|
89
93
|
urlOf(client.api.minds[":name"].sprout.$url({ param: { name: mindName } })),
|
|
90
94
|
{ method: "POST" }
|
|
91
95
|
);
|
|
92
96
|
if (!sproutRes.ok) {
|
|
93
|
-
const data = await sproutRes.json();
|
|
97
|
+
const data = await sproutRes.json().catch(() => ({ error: `HTTP ${sproutRes.status}` }));
|
|
94
98
|
console.error(data.error ?? "Failed to update stage");
|
|
95
99
|
process.exit(1);
|
|
96
100
|
}
|
|
@@ -103,7 +107,7 @@ async function run(_args) {
|
|
|
103
107
|
}
|
|
104
108
|
);
|
|
105
109
|
if (!res.ok) {
|
|
106
|
-
const data = await res.json();
|
|
110
|
+
const data = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
107
111
|
console.error(data.error ?? "Failed to restart after sprouting");
|
|
108
112
|
process.exit(1);
|
|
109
113
|
}
|
|
@@ -5,10 +5,8 @@ import {
|
|
|
5
5
|
} from "./chunk-4RQBJWQX.js";
|
|
6
6
|
import {
|
|
7
7
|
daemonFetch
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import
|
|
10
|
-
resolveMind
|
|
11
|
-
} from "./chunk-EBGCNDMM.js";
|
|
8
|
+
} from "./chunk-KFI7TQJ6.js";
|
|
9
|
+
import "./chunk-B2CPS4QU.js";
|
|
12
10
|
import "./chunk-K3NQKI34.js";
|
|
13
11
|
|
|
14
12
|
// src/commands/start.ts
|
|
@@ -18,7 +16,6 @@ async function run(args) {
|
|
|
18
16
|
console.error("Usage: volute mind start <name>");
|
|
19
17
|
process.exit(1);
|
|
20
18
|
}
|
|
21
|
-
const { entry } = resolveMind(name);
|
|
22
19
|
const client = getClient();
|
|
23
20
|
const res = await daemonFetch(urlOf(client.api.minds[":name"].start.$url({ param: { name } })), {
|
|
24
21
|
method: "POST"
|
|
@@ -28,7 +25,7 @@ async function run(args) {
|
|
|
28
25
|
console.error(data.error || "Failed to start mind");
|
|
29
26
|
process.exit(1);
|
|
30
27
|
}
|
|
31
|
-
console.log(`${name} started on port ${
|
|
28
|
+
console.log(`${name} started on port ${data.port}`);
|
|
32
29
|
}
|
|
33
30
|
export {
|
|
34
31
|
run
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
} from "./chunk-D424ZQGI.js";
|
|
8
8
|
import {
|
|
9
9
|
daemonFetch
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-KFI7TQJ6.js";
|
|
11
|
+
import "./chunk-B2CPS4QU.js";
|
|
12
12
|
import "./chunk-K3NQKI34.js";
|
|
13
13
|
|
|
14
14
|
// src/commands/shared/status.ts
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
getServiceMode,
|
|
5
5
|
modeLabel,
|
|
6
6
|
readDaemonConfig
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-VT5QODNE.js";
|
|
8
|
+
import "./chunk-JTDFJWI2.js";
|
|
9
|
+
import "./chunk-NWPT4ASZ.js";
|
|
10
10
|
import {
|
|
11
11
|
checkForUpdate
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-ON3FF5JA.js";
|
|
13
|
+
import "./chunk-B2CPS4QU.js";
|
|
14
14
|
import "./chunk-K3NQKI34.js";
|
|
15
15
|
|
|
16
16
|
// src/commands/status.ts
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
} from "./chunk-NAOW2CLO.js";
|
|
8
8
|
import {
|
|
9
9
|
readSystemsConfig
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-HFCBO2GL.js";
|
|
11
11
|
import {
|
|
12
12
|
parseArgs
|
|
13
13
|
} from "./chunk-D424ZQGI.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-B2CPS4QU.js";
|
|
15
15
|
import "./chunk-K3NQKI34.js";
|
|
16
16
|
|
|
17
17
|
// src/commands/pages/status.ts
|
|
@@ -22,7 +22,7 @@ async function run(args) {
|
|
|
22
22
|
});
|
|
23
23
|
const config = readSystemsConfig();
|
|
24
24
|
if (!config) {
|
|
25
|
-
console.error('Not logged in. Run "volute
|
|
25
|
+
console.error('Not logged in. Run "volute auth register" or "volute auth login" first.');
|
|
26
26
|
process.exit(1);
|
|
27
27
|
}
|
|
28
28
|
const mindName = flags.mind || process.env.VOLUTE_MIND ? resolveMindName(flags) : "system";
|
|
@@ -8,16 +8,13 @@ import {
|
|
|
8
8
|
} from "./chunk-NAOW2CLO.js";
|
|
9
9
|
import {
|
|
10
10
|
daemonFetch
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import
|
|
13
|
-
resolveMind
|
|
14
|
-
} from "./chunk-EBGCNDMM.js";
|
|
11
|
+
} from "./chunk-KFI7TQJ6.js";
|
|
12
|
+
import "./chunk-B2CPS4QU.js";
|
|
15
13
|
import "./chunk-K3NQKI34.js";
|
|
16
14
|
|
|
17
15
|
// src/commands/stop.ts
|
|
18
16
|
async function run(args) {
|
|
19
17
|
const name = resolveMindName({ mind: args[0] });
|
|
20
|
-
resolveMind(name);
|
|
21
18
|
const client = getClient();
|
|
22
19
|
const res = await daemonFetch(urlOf(client.api.minds[":name"].stop.$url({ param: { name } })), {
|
|
23
20
|
method: "POST"
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
readGlobalConfig,
|
|
4
4
|
run
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-JNFRY2WU.js";
|
|
6
|
+
import "./chunk-VT5QODNE.js";
|
|
7
7
|
import "./chunk-D424ZQGI.js";
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-JTDFJWI2.js";
|
|
9
|
+
import "./chunk-NWPT4ASZ.js";
|
|
10
|
+
import "./chunk-B2CPS4QU.js";
|
|
11
11
|
import "./chunk-K3NQKI34.js";
|
|
12
12
|
export {
|
|
13
13
|
readGlobalConfig,
|
|
@@ -5,19 +5,19 @@ import {
|
|
|
5
5
|
pollHealth,
|
|
6
6
|
readDaemonConfig,
|
|
7
7
|
restartService
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-VT5QODNE.js";
|
|
9
9
|
import {
|
|
10
10
|
exec,
|
|
11
11
|
execInherit,
|
|
12
12
|
resolveVoluteBin
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-JTDFJWI2.js";
|
|
14
|
+
import "./chunk-NWPT4ASZ.js";
|
|
15
15
|
import {
|
|
16
16
|
checkForUpdate
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ON3FF5JA.js";
|
|
18
18
|
import {
|
|
19
19
|
voluteHome
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-B2CPS4QU.js";
|
|
21
21
|
import "./chunk-K3NQKI34.js";
|
|
22
22
|
|
|
23
23
|
// src/commands/update.ts
|
|
@@ -11,10 +11,11 @@ import "./chunk-K3NQKI34.js";
|
|
|
11
11
|
async function run(args) {
|
|
12
12
|
const { positional, flags } = parseArgs(args, {
|
|
13
13
|
template: { type: "string" },
|
|
14
|
-
continue: { type: "boolean" }
|
|
14
|
+
continue: { type: "boolean" },
|
|
15
|
+
abort: { type: "boolean" }
|
|
15
16
|
});
|
|
16
17
|
const mindName = resolveMindName({ mind: positional[0] });
|
|
17
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
18
|
+
const { daemonFetch } = await import("./daemon-client-ZHCDL4RS.js");
|
|
18
19
|
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
19
20
|
const client = getClient();
|
|
20
21
|
const res = await daemonFetch(
|
|
@@ -24,7 +25,8 @@ async function run(args) {
|
|
|
24
25
|
headers: { "Content-Type": "application/json" },
|
|
25
26
|
body: JSON.stringify({
|
|
26
27
|
template: flags.template,
|
|
27
|
-
continue: flags.continue
|
|
28
|
+
continue: flags.continue,
|
|
29
|
+
abort: flags.abort
|
|
28
30
|
})
|
|
29
31
|
}
|
|
30
32
|
);
|
|
@@ -33,12 +35,19 @@ async function run(args) {
|
|
|
33
35
|
console.error(data.error ?? "Failed to upgrade mind");
|
|
34
36
|
process.exit(1);
|
|
35
37
|
}
|
|
38
|
+
if (flags.abort) {
|
|
39
|
+
console.log(`Upgrade aborted for ${mindName}.`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
36
42
|
if (data.conflicts) {
|
|
37
43
|
console.log("\nMerge conflicts detected. Resolve them in:");
|
|
38
44
|
console.log(` ${data.worktreeDir}`);
|
|
39
45
|
console.log(`
|
|
40
46
|
Then run:`);
|
|
41
47
|
console.log(` volute mind upgrade ${mindName} --continue`);
|
|
48
|
+
console.log(`
|
|
49
|
+
Or abort:`);
|
|
50
|
+
console.log(` volute mind upgrade ${mindName} --abort`);
|
|
42
51
|
return;
|
|
43
52
|
}
|
|
44
53
|
console.log(`
|
|
@@ -5,12 +5,6 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
parseArgs
|
|
7
7
|
} from "./chunk-D424ZQGI.js";
|
|
8
|
-
import {
|
|
9
|
-
checkHealth,
|
|
10
|
-
readVariants,
|
|
11
|
-
resolveMind,
|
|
12
|
-
writeVariants
|
|
13
|
-
} from "./chunk-EBGCNDMM.js";
|
|
14
8
|
import "./chunk-K3NQKI34.js";
|
|
15
9
|
|
|
16
10
|
// src/commands/variant.ts
|
|
@@ -65,7 +59,7 @@ async function createVariant(args) {
|
|
|
65
59
|
process.exit(1);
|
|
66
60
|
}
|
|
67
61
|
if (!json) console.log("Creating variant via daemon...");
|
|
68
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
62
|
+
const { daemonFetch } = await import("./daemon-client-ZHCDL4RS.js");
|
|
69
63
|
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
70
64
|
const client = getClient();
|
|
71
65
|
const res = await daemonFetch(
|
|
@@ -103,9 +97,19 @@ async function listVariants(args) {
|
|
|
103
97
|
});
|
|
104
98
|
const mindName = resolveMindName(flags);
|
|
105
99
|
const { json } = flags;
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
100
|
+
const { daemonFetch } = await import("./daemon-client-ZHCDL4RS.js");
|
|
101
|
+
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
102
|
+
const client = getClient();
|
|
103
|
+
const res = await daemonFetch(
|
|
104
|
+
urlOf(client.api.minds[":name"].variants.$url({ param: { name: mindName } }))
|
|
105
|
+
);
|
|
106
|
+
if (!res.ok) {
|
|
107
|
+
const data = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
108
|
+
console.error(data.error ?? "Failed to list variants");
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
const results = await res.json();
|
|
112
|
+
if (results.length === 0) {
|
|
109
113
|
if (json) {
|
|
110
114
|
console.log("[]");
|
|
111
115
|
} else {
|
|
@@ -113,18 +117,6 @@ async function listVariants(args) {
|
|
|
113
117
|
}
|
|
114
118
|
return;
|
|
115
119
|
}
|
|
116
|
-
const results = await Promise.all(
|
|
117
|
-
variants.map(async (v) => {
|
|
118
|
-
if (!v.port) return { ...v, status: "no-server" };
|
|
119
|
-
const health = await checkHealth(v.port);
|
|
120
|
-
return { ...v, status: health.ok ? "running" : "dead" };
|
|
121
|
-
})
|
|
122
|
-
);
|
|
123
|
-
const updated = results.map(({ status, ...v }) => ({
|
|
124
|
-
...v,
|
|
125
|
-
running: status === "running"
|
|
126
|
-
}));
|
|
127
|
-
writeVariants(mindName, updated);
|
|
128
120
|
if (json) {
|
|
129
121
|
console.log(JSON.stringify(results, null, 2));
|
|
130
122
|
return;
|
|
@@ -155,7 +147,7 @@ async function mergeVariant(args) {
|
|
|
155
147
|
process.exit(1);
|
|
156
148
|
}
|
|
157
149
|
console.log(`Merging variant ${variantName}...`);
|
|
158
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
150
|
+
const { daemonFetch } = await import("./daemon-client-ZHCDL4RS.js");
|
|
159
151
|
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
160
152
|
const client = getClient();
|
|
161
153
|
const res = await daemonFetch(
|
|
@@ -192,7 +184,7 @@ async function deleteVariant(args) {
|
|
|
192
184
|
console.error("Usage: volute variant delete <variant> [--mind <name>]");
|
|
193
185
|
process.exit(1);
|
|
194
186
|
}
|
|
195
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
187
|
+
const { daemonFetch } = await import("./daemon-client-ZHCDL4RS.js");
|
|
196
188
|
const { getClient, urlOf } = await import("./api-client-YPKOZP2O.js");
|
|
197
189
|
const client = getClient();
|
|
198
190
|
const res = await daemonFetch(
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
computeTemplateHash
|
|
4
|
+
} from "./chunk-AKPFNL7L.js";
|
|
5
|
+
import {
|
|
6
|
+
deliverMessage
|
|
7
|
+
} from "./chunk-OSFGKF2T.js";
|
|
8
|
+
import "./chunk-HFCBO2GL.js";
|
|
9
|
+
import "./chunk-HGCDWKSP.js";
|
|
10
|
+
import "./chunk-A4S7H6G6.js";
|
|
11
|
+
import "./chunk-VNVCRVYI.js";
|
|
12
|
+
import "./chunk-XLC342FO.js";
|
|
13
|
+
import "./chunk-PHU4DEAJ.js";
|
|
14
|
+
import "./chunk-SGPEZ32F.js";
|
|
15
|
+
import {
|
|
16
|
+
logger_default
|
|
17
|
+
} from "./chunk-YUIHSKR6.js";
|
|
18
|
+
import "./chunk-JTDFJWI2.js";
|
|
19
|
+
import "./chunk-NWPT4ASZ.js";
|
|
20
|
+
import {
|
|
21
|
+
getCurrentVersion
|
|
22
|
+
} from "./chunk-ON3FF5JA.js";
|
|
23
|
+
import {
|
|
24
|
+
readRegistry,
|
|
25
|
+
voluteHome,
|
|
26
|
+
writeRegistry
|
|
27
|
+
} from "./chunk-B2CPS4QU.js";
|
|
28
|
+
import "./chunk-K3NQKI34.js";
|
|
29
|
+
|
|
30
|
+
// src/lib/version-notify.ts
|
|
31
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
32
|
+
import { resolve as resolve2 } from "path";
|
|
33
|
+
|
|
34
|
+
// src/lib/release-notes.ts
|
|
35
|
+
import { existsSync, readFileSync } from "fs";
|
|
36
|
+
import { resolve } from "path";
|
|
37
|
+
function parseReleaseNotes(version) {
|
|
38
|
+
const changelog = findChangelog();
|
|
39
|
+
if (!changelog) return null;
|
|
40
|
+
const v = version.replace(/^v/, "");
|
|
41
|
+
const lines = changelog.split("\n");
|
|
42
|
+
let startIdx = -1;
|
|
43
|
+
let endIdx = lines.length;
|
|
44
|
+
for (let i = 0; i < lines.length; i++) {
|
|
45
|
+
const line = lines[i];
|
|
46
|
+
if (line.startsWith("## ")) {
|
|
47
|
+
if (startIdx === -1 && line.includes(`[${v}]`)) {
|
|
48
|
+
startIdx = i + 1;
|
|
49
|
+
} else if (startIdx !== -1) {
|
|
50
|
+
endIdx = i;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (startIdx === -1) return null;
|
|
56
|
+
const content = lines.slice(startIdx, endIdx).join("\n").trim();
|
|
57
|
+
if (!content) return null;
|
|
58
|
+
return stripGitHubLinks(content);
|
|
59
|
+
}
|
|
60
|
+
function stripGitHubLinks(text) {
|
|
61
|
+
return text.replace(/ \(\[#\d+\]\([^)]*\)\)/g, "").replace(/ \(\[[a-f0-9]+\]\([^)]*\)\)/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
62
|
+
}
|
|
63
|
+
function findChangelog() {
|
|
64
|
+
const thisDir = new URL(".", import.meta.url).pathname;
|
|
65
|
+
const candidates = [
|
|
66
|
+
resolve(thisDir, "../CHANGELOG.md"),
|
|
67
|
+
resolve(thisDir, "../../CHANGELOG.md"),
|
|
68
|
+
resolve(thisDir, "../../../CHANGELOG.md")
|
|
69
|
+
];
|
|
70
|
+
for (const p of candidates) {
|
|
71
|
+
if (existsSync(p)) {
|
|
72
|
+
try {
|
|
73
|
+
return readFileSync(p, "utf-8");
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/lib/version-notify.ts
|
|
83
|
+
function statePath() {
|
|
84
|
+
return resolve2(voluteHome(), "version-notify.json");
|
|
85
|
+
}
|
|
86
|
+
function readState() {
|
|
87
|
+
try {
|
|
88
|
+
if (!existsSync2(statePath())) return null;
|
|
89
|
+
return JSON.parse(readFileSync2(statePath(), "utf-8"));
|
|
90
|
+
} catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function writeState(state) {
|
|
95
|
+
writeFileSync(statePath(), `${JSON.stringify(state, null, 2)}
|
|
96
|
+
`);
|
|
97
|
+
}
|
|
98
|
+
function backfillTemplateHashes() {
|
|
99
|
+
const entries = readRegistry();
|
|
100
|
+
let changed = false;
|
|
101
|
+
for (const entry of entries) {
|
|
102
|
+
if (entry.templateHash != null) continue;
|
|
103
|
+
if (entry.stage === "seed") continue;
|
|
104
|
+
const tmpl = entry.template ?? "claude";
|
|
105
|
+
try {
|
|
106
|
+
entry.templateHash = computeTemplateHash(tmpl);
|
|
107
|
+
changed = true;
|
|
108
|
+
} catch (err) {
|
|
109
|
+
logger_default.warn(`failed to compute template hash for ${entry.name}`, logger_default.errorData(err));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (changed) {
|
|
113
|
+
writeRegistry(entries);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async function notifyVersionUpdate() {
|
|
117
|
+
const currentVersion = getCurrentVersion();
|
|
118
|
+
const state = readState();
|
|
119
|
+
if (!state) {
|
|
120
|
+
writeState({ lastNotifiedVersion: currentVersion });
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (state.lastNotifiedVersion === currentVersion) return;
|
|
124
|
+
const entries = readRegistry();
|
|
125
|
+
const runningMinds = entries.filter((e) => e.running && e.stage !== "seed");
|
|
126
|
+
if (runningMinds.length === 0) {
|
|
127
|
+
writeState({ lastNotifiedVersion: currentVersion });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const releaseNotes = parseReleaseNotes(currentVersion);
|
|
131
|
+
const templateHashes = /* @__PURE__ */ new Map();
|
|
132
|
+
for (const entry of runningMinds) {
|
|
133
|
+
const tmpl = entry.template ?? "claude";
|
|
134
|
+
if (!templateHashes.has(tmpl)) {
|
|
135
|
+
try {
|
|
136
|
+
templateHashes.set(tmpl, computeTemplateHash(tmpl));
|
|
137
|
+
} catch (err) {
|
|
138
|
+
logger_default.warn(`failed to compute template hash for ${tmpl}`, logger_default.errorData(err));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const promises = runningMinds.map(async (entry) => {
|
|
143
|
+
const tmpl = entry.template ?? "claude";
|
|
144
|
+
const currentHash = templateHashes.get(tmpl);
|
|
145
|
+
const needsUpgrade = entry.templateHash != null && currentHash != null && entry.templateHash !== currentHash;
|
|
146
|
+
const message = formatNotification(currentVersion, releaseNotes, needsUpgrade, entry.name);
|
|
147
|
+
await deliverMessage(entry.name, {
|
|
148
|
+
channel: "system:version",
|
|
149
|
+
sender: "volute",
|
|
150
|
+
content: message
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
const results = await Promise.allSettled(promises);
|
|
154
|
+
for (const result of results) {
|
|
155
|
+
if (result.status === "rejected") {
|
|
156
|
+
logger_default.warn("failed to notify mind about version update", logger_default.errorData(result.reason));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
writeState({ lastNotifiedVersion: currentVersion });
|
|
160
|
+
}
|
|
161
|
+
function formatNotification(version, releaseNotes, needsUpgrade, mindName) {
|
|
162
|
+
let message = `Volute has been updated to v${version}.`;
|
|
163
|
+
if (releaseNotes) {
|
|
164
|
+
message += `
|
|
165
|
+
|
|
166
|
+
${releaseNotes}`;
|
|
167
|
+
}
|
|
168
|
+
if (needsUpgrade) {
|
|
169
|
+
message += `
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
A template update is available for you. To upgrade, your operator can run:
|
|
174
|
+
volute mind upgrade ${mindName}`;
|
|
175
|
+
}
|
|
176
|
+
return message;
|
|
177
|
+
}
|
|
178
|
+
export {
|
|
179
|
+
backfillTemplateHashes,
|
|
180
|
+
notifyVersionUpdate
|
|
181
|
+
};
|