volute 0.27.0 → 0.29.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 +20 -10
- package/dist/accept-666DIZX2.js +41 -0
- package/dist/api.d.ts +342 -143
- package/dist/{chat-MHJ3L6JQ.js → chat-KTPOR2JT.js} +18 -8
- package/dist/chunk-A6TUJJ3L.js +19 -0
- package/dist/{chunk-OQZH4PBB.js → chunk-CMILSHZD.js} +199 -277
- package/dist/{chunk-K5NAC55T.js → chunk-CQ7SNKNI.js} +1 -1
- package/dist/{chunk-PHSAT7YL.js → chunk-EHZKEMMV.js} +5 -5
- package/dist/{chunk-IAYBDWVG.js → chunk-FLZGS4QH.js} +145 -0
- package/dist/{chunk-USUXRNVD.js → chunk-J4IBNXGJ.js} +0 -2
- package/dist/chunk-MD4C26II.js +128 -0
- package/dist/{chunk-4WXYUOAK.js → chunk-NI5FFCCS.js} +8 -1
- package/dist/{chunk-JKOWNZ4P.js → chunk-P72MVS4R.js} +1 -40
- package/dist/chunk-THUUIU3E.js +232 -0
- package/dist/cli.js +21 -30
- package/dist/clock-DGCBVGYA.js +259 -0
- package/dist/{cloud-sync-T7M3ESC3.js → cloud-sync-KILFGV5Q.js} +7 -7
- package/dist/connectors/discord-bridge.js +1 -1
- package/dist/connectors/slack-bridge.js +1 -1
- package/dist/connectors/telegram-bridge.js +1 -1
- package/dist/{conversations-M2K4253F.js → conversations-P5BL7RMX.js} +7 -1
- package/dist/create-DFCAGEE5.js +70 -0
- package/dist/{daemon-restart-M2QTYMEG.js → daemon-restart-UHOMICXT.js} +1 -1
- package/dist/daemon.js +715 -661
- package/dist/files-M546TKVN.js +46 -0
- package/dist/{login-XX37I52P.js → login-BKP3AFWN.js} +7 -17
- package/dist/logout-IQK7FNEK.js +20 -0
- package/dist/{message-delivery-LDXLGERA.js → message-delivery-Q7VUMIEI.js} +11 -9
- package/dist/{mind-DI33C74K.js → mind-S5V6CK5W.js} +8 -13
- package/dist/{mind-activity-tracker-EN6XNXPF.js → mind-activity-tracker-WRHFI3YW.js} +1 -1
- package/dist/mind-list-UPJ75GPI.js +29 -0
- package/dist/{mind-manager-M6EMUW5I.js → mind-manager-P66HQDNE.js} +2 -2
- package/dist/mind-status-TK5AETEM.js +55 -0
- package/dist/{package-7WY6VKU3.js → package-OFKXNKJF.js} +1 -1
- package/dist/{pages-6EBS6CBR.js → pages-EUJR52AH.js} +5 -5
- package/dist/pages-watcher-P7QECRE2.js +21 -0
- package/dist/{publish-66UB2ZFY.js → publish-ZZB33WP4.js} +6 -17
- package/dist/{register-6B2CXTYM.js → register-CHREOMJ3.js} +5 -24
- package/dist/reject-LXIZFJ4Q.js +39 -0
- package/dist/{sandbox-TGBX22DS.js → sandbox-5BW5HPXM.js} +1 -1
- package/dist/{send-ZNCJDSRP.js → send-TAOEZ4NH.js} +64 -6
- package/dist/skills/dreaming/references/INSTALL.md +3 -17
- 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 +48 -22
- package/dist/{sleep-manager-MWYHM5HV.js → sleep-manager-G4B5GW5P.js} +7 -7
- package/dist/{sprout-IJVVKSJ2.js → sprout-UNT7LKKE.js} +1 -1
- package/dist/{status-77YEPHMW.js → status-NQJYR4BG.js} +45 -1
- package/dist/{status-THLOBLWG.js → status-S7UUPNRW.js} +3 -13
- package/dist/systems-SMEFSHTA.js +60 -0
- package/dist/{up-NKSMXBWR.js → up-W6VAK2XE.js} +1 -1
- package/dist/{version-notify-5Z4MNR6M.js → version-notify-WDHRO3XD.js} +11 -11
- package/dist/web-assets/assets/index-BmKDnWDB.css +1 -0
- package/dist/web-assets/assets/index-CLJMx-GA.js +71 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +1 -1
- package/templates/_base/src/lib/logger.ts +10 -53
- package/templates/_base/src/lib/router.ts +1 -9
- package/templates/claude/src/lib/stream-consumer.ts +1 -4
- package/templates/pi/src/lib/event-handler.ts +1 -14
- package/dist/auth-D3OT2ARB.js +0 -37
- package/dist/chunk-KDGS53OS.js +0 -50
- package/dist/chunk-RWKVSSLY.js +0 -26
- package/dist/chunk-T6HKBWXZ.js +0 -23
- package/dist/create-D7J73A6H.js +0 -45
- package/dist/file-CR36YUPD.js +0 -204
- package/dist/log-ABYNVYJ3.js +0 -39
- package/dist/logout-W4KOOBIT.js +0 -18
- package/dist/logs-U35JR2KE.js +0 -77
- package/dist/merge-LNSMSAOF.js +0 -46
- package/dist/pull-XCHJTM5M.js +0 -39
- package/dist/schedule-QTJMFATP.js +0 -154
- package/dist/service-6LIN3F3K.js +0 -122
- package/dist/shared-ML5I4Q2A.js +0 -39
- package/dist/status-7GA4SM4Y.js +0 -35
- package/dist/web-assets/assets/index-CI5wgghI.css +0 -1
- package/dist/web-assets/assets/index-is5CvJWH.js +0 -75
- package/dist/{chunk-GIE6CSN5.js → chunk-DUAUMCEE.js} +0 -0
- package/dist/{history-XKRTAFS2.js → history-ALPTNB3I.js} +0 -0
- package/dist/{setup-JG4QAEBV.js → setup-RXYVGGT7.js} +3 -3
package/dist/cli.js
CHANGED
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { homedir } from "os";
|
|
5
5
|
import { resolve } from "path";
|
|
6
|
+
process.noDeprecation = true;
|
|
6
7
|
if (!process.env.VOLUTE_HOME) {
|
|
7
8
|
process.env.VOLUTE_HOME = resolve(homedir(), ".volute");
|
|
8
9
|
}
|
|
9
10
|
var command = process.argv[2];
|
|
10
11
|
var args = process.argv.slice(3);
|
|
11
12
|
if (command === "--version" || command === "-v") {
|
|
12
|
-
const { default: pkg } = await import("./package-
|
|
13
|
+
const { default: pkg } = await import("./package-OFKXNKJF.js");
|
|
13
14
|
console.log(pkg.version);
|
|
14
15
|
process.exit(0);
|
|
15
16
|
}
|
|
@@ -24,58 +25,52 @@ if (!ungatedCommands.has(command)) {
|
|
|
24
25
|
}
|
|
25
26
|
switch (command) {
|
|
26
27
|
case "setup":
|
|
27
|
-
await import("./setup-
|
|
28
|
+
await import("./setup-RXYVGGT7.js").then((m) => m.run(args));
|
|
28
29
|
break;
|
|
29
30
|
case "mind":
|
|
30
|
-
await import("./mind-
|
|
31
|
+
await import("./mind-S5V6CK5W.js").then((m) => m.run(args));
|
|
31
32
|
break;
|
|
32
33
|
case "chat":
|
|
33
|
-
await import("./chat-
|
|
34
|
+
await import("./chat-KTPOR2JT.js").then((m) => m.run(args));
|
|
34
35
|
break;
|
|
35
36
|
case "variant":
|
|
36
37
|
await import("./variant-7TGZHOU3.js").then((m) => m.run(args));
|
|
37
38
|
break;
|
|
39
|
+
case "clock":
|
|
40
|
+
await import("./clock-DGCBVGYA.js").then((m) => m.run(args));
|
|
41
|
+
break;
|
|
38
42
|
case "schedule":
|
|
39
|
-
await import("./
|
|
43
|
+
await import("./clock-DGCBVGYA.js").then((m) => m.run(args));
|
|
40
44
|
break;
|
|
41
45
|
case "skill":
|
|
42
46
|
await import("./skill-AUAQTSP5.js").then((m) => m.run(args));
|
|
43
47
|
break;
|
|
44
|
-
case "shared":
|
|
45
|
-
await import("./shared-ML5I4Q2A.js").then((m) => m.run(args));
|
|
46
|
-
break;
|
|
47
|
-
case "file":
|
|
48
|
-
await import("./file-CR36YUPD.js").then((m) => m.run(args));
|
|
49
|
-
break;
|
|
50
48
|
case "env":
|
|
51
49
|
await import("./env-YJMUMFIY.js").then((m) => m.run(args));
|
|
52
50
|
break;
|
|
53
51
|
case "up":
|
|
54
|
-
await import("./up-
|
|
52
|
+
await import("./up-W6VAK2XE.js").then((m) => m.run(args));
|
|
55
53
|
break;
|
|
56
54
|
case "down":
|
|
57
55
|
await import("./down-LVBXEULC.js").then((m) => m.run(args));
|
|
58
56
|
break;
|
|
59
57
|
case "restart":
|
|
60
|
-
await import("./daemon-restart-
|
|
61
|
-
break;
|
|
62
|
-
case "service":
|
|
63
|
-
await import("./service-6LIN3F3K.js").then((m) => m.run(args));
|
|
58
|
+
await import("./daemon-restart-UHOMICXT.js").then((m) => m.run(args));
|
|
64
59
|
break;
|
|
65
60
|
case "update":
|
|
66
61
|
await import("./update-PTSH22AZ.js").then((m) => m.run(args));
|
|
67
62
|
break;
|
|
68
63
|
case "status":
|
|
69
|
-
await import("./status-
|
|
64
|
+
await import("./status-NQJYR4BG.js").then((m) => m.run(args));
|
|
70
65
|
break;
|
|
71
66
|
case "notes":
|
|
72
67
|
await import("./notes-XCER3I7M.js").then((m) => m.run(args));
|
|
73
68
|
break;
|
|
74
69
|
case "pages":
|
|
75
|
-
await import("./pages-
|
|
70
|
+
await import("./pages-EUJR52AH.js").then((m) => m.run(args));
|
|
76
71
|
break;
|
|
77
|
-
case "
|
|
78
|
-
await import("./
|
|
72
|
+
case "systems":
|
|
73
|
+
await import("./systems-SMEFSHTA.js").then((m) => m.run(args));
|
|
79
74
|
break;
|
|
80
75
|
case "login":
|
|
81
76
|
await import("./login-3QZNR2DF.js").then((m) => m.run(args));
|
|
@@ -90,10 +85,8 @@ switch (command) {
|
|
|
90
85
|
|
|
91
86
|
Common:
|
|
92
87
|
chat send <target> "<msg>" Send a message
|
|
93
|
-
chat history [--channel <ch>] View activity history
|
|
94
88
|
chat list / read / create Manage conversations
|
|
95
89
|
chat bridge Manage platform bridges
|
|
96
|
-
status Show system status
|
|
97
90
|
|
|
98
91
|
Mind:
|
|
99
92
|
mind create <name> Create a new mind
|
|
@@ -101,28 +94,26 @@ Mind:
|
|
|
101
94
|
mind start/stop/restart [name] Control a mind
|
|
102
95
|
mind list List all minds
|
|
103
96
|
mind status [name] Check a mind's status
|
|
104
|
-
mind
|
|
97
|
+
mind history [name] [--full] View mind activity history
|
|
105
98
|
mind sprout Complete orientation
|
|
106
99
|
mind split/join Create and merge experimental splits
|
|
107
100
|
mind upgrade/import/export Lifecycle operations
|
|
108
101
|
|
|
109
102
|
Configuration:
|
|
110
|
-
chat Conversations, messages, and platform bridges
|
|
111
|
-
|
|
103
|
+
chat Conversations, messages, files, and platform bridges
|
|
104
|
+
clock Schedules, timers, and sleep/wake cycles
|
|
112
105
|
skill Browse and install skills
|
|
113
106
|
env Manage environment variables
|
|
114
|
-
file Mind-to-mind file sharing
|
|
115
|
-
shared Collaborative shared repository
|
|
116
107
|
notes Read and write notes
|
|
117
108
|
pages Publish web pages
|
|
118
109
|
|
|
119
110
|
System:
|
|
120
111
|
setup First-time setup
|
|
121
112
|
up / down / restart Daemon control
|
|
113
|
+
status Show daemon & service status
|
|
122
114
|
login / logout CLI authentication
|
|
123
115
|
update Update volute
|
|
124
|
-
|
|
125
|
-
auth register/login/logout volute.systems account
|
|
116
|
+
systems register/login/logout volute.systems account
|
|
126
117
|
|
|
127
118
|
Options:
|
|
128
119
|
--version, -v Show version number
|
|
@@ -130,7 +121,7 @@ Options:
|
|
|
130
121
|
|
|
131
122
|
Run 'volute <command> --help' for details.
|
|
132
123
|
|
|
133
|
-
Mind-scoped commands (chat,
|
|
124
|
+
Mind-scoped commands (chat, clock, skill, pages)
|
|
134
125
|
use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
|
|
135
126
|
break;
|
|
136
127
|
default:
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveMindName
|
|
4
|
+
} from "./chunk-NAOW2CLO.js";
|
|
5
|
+
import {
|
|
6
|
+
daemonFetch
|
|
7
|
+
} from "./chunk-JGFVMROS.js";
|
|
8
|
+
import {
|
|
9
|
+
getClient,
|
|
10
|
+
urlOf
|
|
11
|
+
} from "./chunk-4RQBJWQX.js";
|
|
12
|
+
import {
|
|
13
|
+
parseArgs
|
|
14
|
+
} from "./chunk-D424ZQGI.js";
|
|
15
|
+
import "./chunk-H7OZRFJB.js";
|
|
16
|
+
import "./chunk-K3NQKI34.js";
|
|
17
|
+
|
|
18
|
+
// src/commands/clock.ts
|
|
19
|
+
import { CronExpressionParser } from "cron-parser";
|
|
20
|
+
async function run(args) {
|
|
21
|
+
const subcommand = args[0];
|
|
22
|
+
switch (subcommand) {
|
|
23
|
+
case "status":
|
|
24
|
+
await clockStatus(args.slice(1));
|
|
25
|
+
break;
|
|
26
|
+
case "list":
|
|
27
|
+
await listSchedules(args.slice(1));
|
|
28
|
+
break;
|
|
29
|
+
case "add":
|
|
30
|
+
await addSchedule(args.slice(1));
|
|
31
|
+
break;
|
|
32
|
+
case "remove":
|
|
33
|
+
await removeSchedule(args.slice(1));
|
|
34
|
+
break;
|
|
35
|
+
case "sleep":
|
|
36
|
+
await import("./mind-sleep-BTSWQNAC.js").then((m) => m.run(args.slice(1)));
|
|
37
|
+
break;
|
|
38
|
+
case "wake":
|
|
39
|
+
await import("./mind-wake-SBAKIDVP.js").then((m) => m.run(args.slice(1)));
|
|
40
|
+
break;
|
|
41
|
+
case "--help":
|
|
42
|
+
case "-h":
|
|
43
|
+
case void 0:
|
|
44
|
+
printUsage();
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
printUsage();
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function printUsage() {
|
|
52
|
+
console.log(`Usage:
|
|
53
|
+
volute clock status [--mind <name>]
|
|
54
|
+
volute clock list [--mind <name>]
|
|
55
|
+
volute clock add [--mind <name>] --cron "..." --message/--script "..." [--id name] [--channel ch] [--while-sleeping skip|queue|trigger-wake]
|
|
56
|
+
volute clock add [--mind <name>] --in <duration> --message/--script "..." [--id name] [--channel ch] [--while-sleeping skip|queue|trigger-wake]
|
|
57
|
+
volute clock remove [--mind <name>] --id <id>
|
|
58
|
+
volute clock sleep [name] [--wake-at <time>]
|
|
59
|
+
volute clock wake [name]
|
|
60
|
+
|
|
61
|
+
Duration format for --in: 30s, 10m, 1h, 2h30m`);
|
|
62
|
+
}
|
|
63
|
+
function parseDuration(input) {
|
|
64
|
+
const parts = input.match(/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/);
|
|
65
|
+
if (!parts || parts[0] !== input) return null;
|
|
66
|
+
const hours = parseInt(parts[1] || "0", 10);
|
|
67
|
+
const minutes = parseInt(parts[2] || "0", 10);
|
|
68
|
+
const seconds = parseInt(parts[3] || "0", 10);
|
|
69
|
+
const total = hours * 36e5 + minutes * 6e4 + seconds * 1e3;
|
|
70
|
+
return total > 0 ? total : null;
|
|
71
|
+
}
|
|
72
|
+
async function clockStatus(args) {
|
|
73
|
+
const { flags } = parseArgs(args, {
|
|
74
|
+
mind: { type: "string" }
|
|
75
|
+
});
|
|
76
|
+
const mind = resolveMindName(flags);
|
|
77
|
+
const client = getClient();
|
|
78
|
+
const res = await daemonFetch(
|
|
79
|
+
urlOf(client.api.minds[":name"].clock.status.$url({ param: { name: mind } }))
|
|
80
|
+
);
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
const data = await res.json();
|
|
83
|
+
console.error(data.error ?? `Failed to get clock status: ${res.status}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
const status = await res.json();
|
|
87
|
+
if (status.sleep?.sleeping) {
|
|
88
|
+
const since = status.sleep.sleepingSince ? new Date(status.sleep.sleepingSince).toLocaleString() : "unknown";
|
|
89
|
+
console.log(`Sleep: sleeping since ${since}`);
|
|
90
|
+
if (status.sleep.scheduledWakeAt) {
|
|
91
|
+
console.log(` Wake at: ${new Date(status.sleep.scheduledWakeAt).toLocaleString()}`);
|
|
92
|
+
}
|
|
93
|
+
if (status.sleep.voluntaryWakeAt) {
|
|
94
|
+
console.log(
|
|
95
|
+
` Voluntary wake at: ${new Date(status.sleep.voluntaryWakeAt).toLocaleString()}`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
if (status.sleep.queuedMessageCount > 0) {
|
|
99
|
+
console.log(` Queued messages: ${status.sleep.queuedMessageCount}`);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
console.log("Sleep: awake");
|
|
103
|
+
}
|
|
104
|
+
if (status.sleepConfig?.enabled && status.sleepConfig.schedule) {
|
|
105
|
+
console.log(
|
|
106
|
+
` Schedule: sleep ${status.sleepConfig.schedule.sleep}, wake ${status.sleepConfig.schedule.wake}`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
if (status.upcoming.length > 0) {
|
|
110
|
+
console.log("\nUpcoming (next 24h):");
|
|
111
|
+
for (const u of status.upcoming) {
|
|
112
|
+
const time = new Date(u.at).toLocaleString();
|
|
113
|
+
const label = u.type === "timer" ? "[timer]" : "[cron]";
|
|
114
|
+
console.log(` ${u.id.padEnd(20)} ${label} ${time}`);
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
console.log("\nNo upcoming events in next 24h.");
|
|
118
|
+
}
|
|
119
|
+
console.log(`
|
|
120
|
+
${status.schedules.length} schedule(s) configured.`);
|
|
121
|
+
}
|
|
122
|
+
async function listSchedules(args) {
|
|
123
|
+
const { flags } = parseArgs(args, {
|
|
124
|
+
mind: { type: "string" }
|
|
125
|
+
});
|
|
126
|
+
const mind = resolveMindName(flags);
|
|
127
|
+
const client = getClient();
|
|
128
|
+
const res = await daemonFetch(
|
|
129
|
+
urlOf(client.api.minds[":name"].schedules.$url({ param: { name: mind } }))
|
|
130
|
+
);
|
|
131
|
+
if (!res.ok) {
|
|
132
|
+
const data = await res.json();
|
|
133
|
+
console.error(data.error ?? `Failed to list schedules: ${res.status}`);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
const schedules = await res.json();
|
|
137
|
+
if (schedules.length === 0) {
|
|
138
|
+
console.log("No schedules configured.");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const idW = Math.max(2, ...schedules.map((s) => s.id.length));
|
|
142
|
+
const schedW = Math.max(8, ...schedules.map((s) => (s.cron ?? s.fireAt ?? "").length));
|
|
143
|
+
const actionLabel = (s) => s.script ? `[script] ${s.script}` : s.message ?? "";
|
|
144
|
+
console.log(`${"ID".padEnd(idW)} ${"SCHEDULE".padEnd(schedW)} ENABLED ACTION`);
|
|
145
|
+
for (const s of schedules) {
|
|
146
|
+
const sched = s.cron ?? (s.fireAt ? `at ${s.fireAt}` : "");
|
|
147
|
+
console.log(
|
|
148
|
+
`${s.id.padEnd(idW)} ${sched.padEnd(schedW)} ${String(s.enabled).padEnd(7)} ${actionLabel(s)}`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function addSchedule(args) {
|
|
153
|
+
const { flags } = parseArgs(args, {
|
|
154
|
+
mind: { type: "string" },
|
|
155
|
+
cron: { type: "string" },
|
|
156
|
+
in: { type: "string" },
|
|
157
|
+
message: { type: "string" },
|
|
158
|
+
script: { type: "string" },
|
|
159
|
+
id: { type: "string" },
|
|
160
|
+
channel: { type: "string" },
|
|
161
|
+
"while-sleeping": { type: "string" }
|
|
162
|
+
});
|
|
163
|
+
const mind = resolveMindName(flags);
|
|
164
|
+
if (!flags.cron && !flags.in) {
|
|
165
|
+
console.error("--cron or --in is required");
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
if (flags.cron && flags.in) {
|
|
169
|
+
console.error("--cron and --in are mutually exclusive");
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
if (!flags.message && !flags.script) {
|
|
173
|
+
console.error("--message or --script is required");
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
if (flags.message && flags.script) {
|
|
177
|
+
console.error("--message and --script are mutually exclusive");
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
const body = {};
|
|
181
|
+
if (flags.cron) {
|
|
182
|
+
try {
|
|
183
|
+
CronExpressionParser.parse(flags.cron);
|
|
184
|
+
} catch {
|
|
185
|
+
console.error(`Invalid cron expression: ${flags.cron}`);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
body.cron = flags.cron;
|
|
189
|
+
}
|
|
190
|
+
if (flags.in) {
|
|
191
|
+
const durationMs = parseDuration(flags.in);
|
|
192
|
+
if (!durationMs) {
|
|
193
|
+
console.error(`Invalid duration: ${flags.in} (expected format: 30s, 10m, 1h, 2h30m)`);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
body.fireAt = new Date(Date.now() + durationMs).toISOString();
|
|
197
|
+
}
|
|
198
|
+
if (flags.message) body.message = flags.message;
|
|
199
|
+
if (flags.script) body.script = flags.script;
|
|
200
|
+
if (flags.id) body.id = flags.id;
|
|
201
|
+
if (flags.channel) body.channel = flags.channel;
|
|
202
|
+
if (flags["while-sleeping"]) {
|
|
203
|
+
const ws = flags["while-sleeping"];
|
|
204
|
+
if (!["skip", "queue", "trigger-wake"].includes(ws)) {
|
|
205
|
+
console.error(`Invalid --while-sleeping value: ${ws} (must be skip, queue, or trigger-wake)`);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
body.whileSleeping = ws;
|
|
209
|
+
}
|
|
210
|
+
const client = getClient();
|
|
211
|
+
const res = await daemonFetch(
|
|
212
|
+
urlOf(client.api.minds[":name"].schedules.$url({ param: { name: mind } })),
|
|
213
|
+
{
|
|
214
|
+
method: "POST",
|
|
215
|
+
headers: { "Content-Type": "application/json" },
|
|
216
|
+
body: JSON.stringify(body)
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
if (!res.ok) {
|
|
220
|
+
const data2 = await res.json();
|
|
221
|
+
console.error(data2.error ?? `Failed to add schedule: ${res.status}`);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
const data = await res.json();
|
|
225
|
+
if (flags.in) {
|
|
226
|
+
console.log(`Timer set: ${data.id} (fires in ${flags.in})`);
|
|
227
|
+
} else {
|
|
228
|
+
console.log(`Schedule added: ${data.id}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async function removeSchedule(args) {
|
|
232
|
+
const { flags } = parseArgs(args, {
|
|
233
|
+
mind: { type: "string" },
|
|
234
|
+
id: { type: "string" }
|
|
235
|
+
});
|
|
236
|
+
const mind = resolveMindName(flags);
|
|
237
|
+
if (!flags.id) {
|
|
238
|
+
console.error("--id is required");
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
const client = getClient();
|
|
242
|
+
const res = await daemonFetch(
|
|
243
|
+
urlOf(
|
|
244
|
+
client.api.minds[":name"].schedules[":id"].$url({
|
|
245
|
+
param: { name: mind, id: flags.id }
|
|
246
|
+
})
|
|
247
|
+
),
|
|
248
|
+
{ method: "DELETE" }
|
|
249
|
+
);
|
|
250
|
+
if (!res.ok) {
|
|
251
|
+
const data = await res.json();
|
|
252
|
+
console.error(data.error ?? `Failed to remove schedule: ${res.status}`);
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
console.log(`Schedule removed: ${flags.id}`);
|
|
256
|
+
}
|
|
257
|
+
export {
|
|
258
|
+
run
|
|
259
|
+
};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
deliverMessage
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-K5NAC55T.js";
|
|
7
|
-
import "./chunk-PHSAT7YL.js";
|
|
8
|
-
import "./chunk-USUXRNVD.js";
|
|
4
|
+
} from "./chunk-CMILSHZD.js";
|
|
5
|
+
import "./chunk-THUUIU3E.js";
|
|
9
6
|
import {
|
|
10
7
|
getAuthHeaders,
|
|
11
8
|
getWebhookUrl
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FLZGS4QH.js";
|
|
10
|
+
import "./chunk-CQ7SNKNI.js";
|
|
13
11
|
import "./chunk-VIVMW2H2.js";
|
|
12
|
+
import "./chunk-EHZKEMMV.js";
|
|
13
|
+
import "./chunk-J4IBNXGJ.js";
|
|
14
14
|
import "./chunk-2WPW7OT6.js";
|
|
15
15
|
import {
|
|
16
16
|
logger_default
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import "./chunk-AW7PFDVN.js";
|
|
19
19
|
import "./chunk-RKQEHRBB.js";
|
|
20
20
|
import "./chunk-IKRVFPWU.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-A6TUJJ3L.js";
|
|
22
22
|
import "./chunk-H7OZRFJB.js";
|
|
23
23
|
import "./chunk-K3NQKI34.js";
|
|
24
24
|
|
|
@@ -14,16 +14,19 @@ import {
|
|
|
14
14
|
getOrCreateConversation,
|
|
15
15
|
getParticipants,
|
|
16
16
|
getUnreadCounts,
|
|
17
|
+
isConversationForMind,
|
|
17
18
|
isParticipant,
|
|
18
19
|
isParticipantOrOwner,
|
|
19
20
|
joinChannel,
|
|
20
21
|
leaveChannel,
|
|
21
22
|
listChannels,
|
|
23
|
+
listConversationsForMind,
|
|
22
24
|
listConversationsForUser,
|
|
23
25
|
listConversationsWithParticipants,
|
|
24
26
|
markConversationRead,
|
|
27
|
+
migrateGroupDMsToChannels,
|
|
25
28
|
removeParticipant
|
|
26
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-FLZGS4QH.js";
|
|
27
30
|
import "./chunk-VIVMW2H2.js";
|
|
28
31
|
import "./chunk-YUIHSKR6.js";
|
|
29
32
|
import "./chunk-H7OZRFJB.js";
|
|
@@ -43,13 +46,16 @@ export {
|
|
|
43
46
|
getOrCreateConversation,
|
|
44
47
|
getParticipants,
|
|
45
48
|
getUnreadCounts,
|
|
49
|
+
isConversationForMind,
|
|
46
50
|
isParticipant,
|
|
47
51
|
isParticipantOrOwner,
|
|
48
52
|
joinChannel,
|
|
49
53
|
leaveChannel,
|
|
50
54
|
listChannels,
|
|
55
|
+
listConversationsForMind,
|
|
51
56
|
listConversationsForUser,
|
|
52
57
|
listConversationsWithParticipants,
|
|
53
58
|
markConversationRead,
|
|
59
|
+
migrateGroupDMsToChannels,
|
|
54
60
|
removeParticipant
|
|
55
61
|
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveMindName
|
|
4
|
+
} from "./chunk-NAOW2CLO.js";
|
|
5
|
+
import {
|
|
6
|
+
daemonFetch
|
|
7
|
+
} from "./chunk-JGFVMROS.js";
|
|
8
|
+
import {
|
|
9
|
+
parseArgs
|
|
10
|
+
} from "./chunk-D424ZQGI.js";
|
|
11
|
+
import "./chunk-H7OZRFJB.js";
|
|
12
|
+
import "./chunk-K3NQKI34.js";
|
|
13
|
+
|
|
14
|
+
// src/commands/chat/create.ts
|
|
15
|
+
async function run(args) {
|
|
16
|
+
const { flags } = parseArgs(args, {
|
|
17
|
+
mind: { type: "string" },
|
|
18
|
+
participants: { type: "string" },
|
|
19
|
+
name: { type: "string" },
|
|
20
|
+
channel: { type: "string" }
|
|
21
|
+
});
|
|
22
|
+
if (!flags.participants) {
|
|
23
|
+
console.error(
|
|
24
|
+
'Usage: volute chat create --participants u1,u2 [--name "..."] [--channel <name>] [--mind <name>]'
|
|
25
|
+
);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const mindName = resolveMindName(flags);
|
|
29
|
+
const participants = flags.participants.split(",").map((p) => p.trim());
|
|
30
|
+
if (participants.length > 2 && !flags.channel) {
|
|
31
|
+
console.error("Use --channel <name> for multi-participant conversations");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
if (flags.channel) {
|
|
35
|
+
const res = await daemonFetch("/api/volute/channels", {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: { "Content-Type": "application/json" },
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
name: flags.channel,
|
|
40
|
+
participantNames: participants
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
const data = await res.json().catch(() => ({}));
|
|
45
|
+
console.error(data.error ?? `Failed to create channel: ${res.status}`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const conv = await res.json();
|
|
49
|
+
console.log(`Created channel #${flags.channel}: ${conv.id}`);
|
|
50
|
+
} else {
|
|
51
|
+
const res = await daemonFetch(`/api/minds/${encodeURIComponent(mindName)}/conversations`, {
|
|
52
|
+
method: "POST",
|
|
53
|
+
headers: { "Content-Type": "application/json" },
|
|
54
|
+
body: JSON.stringify({
|
|
55
|
+
participantNames: participants,
|
|
56
|
+
title: flags.name
|
|
57
|
+
})
|
|
58
|
+
});
|
|
59
|
+
if (!res.ok) {
|
|
60
|
+
const data = await res.json().catch(() => ({}));
|
|
61
|
+
console.error(data.error ?? `Failed to create conversation: ${res.status}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const conv = await res.json();
|
|
65
|
+
console.log(`Created conversation: ${conv.id}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
run
|
|
70
|
+
};
|