volute 0.33.0 → 0.35.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 -6
- package/dist/accept-ZBDVVCEU.js +42 -0
- package/dist/activity-events-ZW4SDL2C.js +15 -0
- package/dist/{ai-service-SBY2WG7O.js → ai-service-LURBEDDB.js} +6 -6
- package/dist/{api-client-YPKOZP2O.js → api-client-3A77HMH7.js} +2 -2
- package/dist/api.d.ts +1 -5195
- package/dist/{archive-INXYFVCW.js → archive-ESU2FUN4.js} +4 -4
- package/dist/{auth-GKCDSO4T.js → auth-WX4TESEI.js} +6 -6
- package/dist/bridge-PXIO6PS2.js +206 -0
- package/dist/chat-QXAJF3FU.js +51 -0
- package/dist/{chunk-NNB4WIG7.js → chunk-2TGZJFAT.js} +3 -3
- package/dist/{chunk-6LXAAQ43.js → chunk-33ODGMFZ.js} +1 -1
- package/dist/{chunk-RPZZSXV3.js → chunk-5N7Y5WAM.js} +21 -2
- package/dist/chunk-5T5YMX6S.js +23 -0
- package/dist/{chunk-7J3HEVR7.js → chunk-5XJYUFZH.js} +28 -16
- package/dist/chunk-7KJOFUNN.js +22 -0
- package/dist/{chunk-2NGTS5UU.js → chunk-A2ZLHBHG.js} +2 -2
- package/dist/{chunk-KIEPMIM5.js → chunk-AN2W47GW.js} +2 -2
- package/dist/{chunk-G53F3JA4.js → chunk-AOB6GVRM.js} +1 -1
- package/dist/{chunk-LRCG2JLP.js → chunk-BDYXIWA5.js} +9 -5
- package/dist/{chunk-YUIHSKR6.js → chunk-BKF4WQCY.js} +2 -2
- package/dist/{chunk-N432I7QH.js → chunk-BMZQYACC.js} +2 -2
- package/dist/{chunk-NAOW2CLO.js → chunk-BTY4WNFE.js} +1 -1
- package/dist/{chunk-ALEF47VT.js → chunk-BV65KRHM.js} +2 -2
- package/dist/{chunk-KVK2DLWI.js → chunk-CORXD635.js} +4 -4
- package/dist/{chunk-PVY5W6QN.js → chunk-F7ZNLYKZ.js} +2 -2
- package/dist/{chunk-QTUVYI7W.js → chunk-FT5KETXZ.js} +3 -3
- package/dist/{chunk-C7I35G4R.js → chunk-IJHIXLVN.js} +44 -8
- package/dist/{chunk-JUKK7FPS.js → chunk-J6CJQDWI.js} +37 -28
- package/dist/{chunk-4RQBJWQX.js → chunk-LOPXTW6H.js} +1 -1
- package/dist/{chunk-RSX4OPZY.js → chunk-MDJGMOSD.js} +8 -137
- package/dist/{chunk-LOEJ4HPQ.js → chunk-N446KRP7.js} +3 -3
- package/dist/{chunk-I5KY25PQ.js → chunk-N5LMGYXX.js} +2 -2
- package/dist/{chunk-G6BSYHPK.js → chunk-NJK5SDGR.js} +1 -1
- package/dist/{chunk-D424ZQGI.js → chunk-O7IGP7ZW.js} +11 -3
- package/dist/{chunk-M7UL5S3Q.js → chunk-OTC67N2Z.js} +2 -2
- package/dist/{chunk-GY5HBI7A.js → chunk-PWQ2ITYG.js} +4 -4
- package/dist/{chunk-KTLFDYPT.js → chunk-QCH6K235.js} +1 -1
- package/dist/chunk-QHG4OMZL.js +145 -0
- package/dist/{chunk-SKLSMHXO.js → chunk-QWTR6AWZ.js} +3 -3
- package/dist/chunk-TXSA4Q3V.js +116 -0
- package/dist/{chunk-VH33ZWMW.js → chunk-VHJRZM2S.js} +2 -2
- package/dist/{chunk-SSI47XP2.js → chunk-VHWGEJ4V.js} +1 -1
- package/dist/chunk-VY3RB2V7.js +164 -0
- package/dist/chunk-WJPROOU5.js +8314 -0
- package/dist/{chunk-RVGLDGMI.js → chunk-WZRZFFCL.js} +25 -27
- package/dist/{chunk-JYVGHWEJ.js → chunk-XRQSAMX2.js} +4 -4
- package/dist/{chunk-OYAKCAVY.js → chunk-ZSR72JB3.js} +1 -1
- package/dist/{chunk-UKVWJRKN.js → chunk-ZX7EAV5J.js} +17 -7
- package/dist/cli.js +90 -29
- package/dist/clock-HSEKS5AR.js +289 -0
- package/dist/{cloud-sync-4NWLMFVH.js → cloud-sync-6JL4C24T.js} +22 -23
- package/dist/config-UTS7QULS.js +76 -0
- package/dist/connectors/discord-bridge.js +4 -4
- package/dist/connectors/slack-bridge.js +4 -4
- package/dist/connectors/telegram-bridge.js +4 -4
- package/dist/{conversations-AWI5SZW2.js → conversations-2PW57WO2.js} +6 -6
- package/dist/create-5BPOOJAN.js +75 -0
- package/dist/create-UVCK2CS6.js +50 -0
- package/dist/daemon-client-RVIKXGFQ.js +12 -0
- package/dist/daemon-restart-HSZ3BCX5.js +65 -0
- package/dist/daemon.js +1349 -1211
- package/dist/db-BDMH4SZ2.js +20 -0
- package/dist/db-BVBJ57TU.js +9 -0
- package/dist/delete-L5PAVDGQ.js +42 -0
- package/dist/delivery-manager-H5ZVBMCQ.js +31 -0
- package/dist/{delivery-router-FL45JL7N.js → delivery-router-HEJSJAHQ.js} +5 -5
- package/dist/down-74VXM45A.js +17 -0
- package/dist/env-E4XHO2BI.js +223 -0
- package/dist/exec-PY7THYH4.js +17 -0
- package/dist/export-OAS6QVBN.js +113 -0
- package/dist/extension-D74CNM7G.js +89 -0
- package/dist/extensions-XDDFY72A.js +49 -0
- package/dist/files-CWTK6V3H.js +53 -0
- package/dist/import-5A3T7QV4.js +143 -0
- package/dist/{isolation-LLAYQYDY.js → isolation-TK5RX2WM.js} +4 -4
- package/dist/join-DF5XSJAC.js +67 -0
- package/dist/lib-DYEZMGW7.js +6588 -0
- package/dist/list-PDMQM7ZV.js +53 -0
- package/dist/login-7TE6CIZF.js +60 -0
- package/dist/login-GOTAYLXP.js +51 -0
- package/dist/logout-6KIA74EV.js +29 -0
- package/dist/logout-T4XS6LRU.js +50 -0
- package/dist/message-delivery-GRC4W6P7.js +41 -0
- package/dist/mind-5IEYKV7I.js +97 -0
- package/dist/mind-activity-tracker-QBLIV7ZJ.js +18 -0
- package/dist/mind-history-IE2QH7U5.js +275 -0
- package/dist/mind-list-GEWHWAL4.js +38 -0
- package/dist/mind-manager-HFLB5653.js +31 -0
- package/dist/mind-profile-DCBDVF5B.js +53 -0
- package/dist/mind-service-X2CAA6W6.js +37 -0
- package/dist/mind-sleep-ITCF6OQA.js +47 -0
- package/dist/mind-status-X4SX3YUG.js +65 -0
- package/dist/mind-wake-KXMKMGWX.js +42 -0
- package/dist/{package-U3VFO273.js → package-D2FSVFAX.js} +11 -8
- package/dist/read-67VRP2DO.js +91 -0
- package/dist/{read-stdin-HQJ7774D.js → read-stdin-3X5VYKNS.js} +2 -2
- package/dist/register-SB7NXCOE.js +51 -0
- package/dist/{registry-PJ4S5PHQ.js → registry-GBSNW3HG.js} +3 -3
- package/dist/reject-MUR2KWJ4.js +40 -0
- package/dist/restart-5EGG4JXU.js +42 -0
- package/dist/{sandbox-GJOK4QLQ.js → sandbox-R37VIU36.js} +6 -6
- package/dist/scheduler-Y7O4CJXL.js +31 -0
- package/dist/{schema-PA3M5ZKH.js → schema-XVZ2CLKW.js} +4 -2
- package/dist/{seed-QDYVLG74.js → seed-EQORWX77.js} +3 -3
- package/dist/seed-check-KJNTL72M.js +35 -0
- package/dist/seed-cmd-ZM2XGVU2.js +30 -0
- package/dist/seed-create-DRWGGHEI.js +113 -0
- package/dist/seed-sprout-JYXGXOP3.js +148 -0
- package/dist/send-JBJJQ7CA.js +409 -0
- package/dist/service-WNPCNHOX.js +121 -0
- package/dist/{setup-XMCBE3LF.js → setup-BJ4YAY26.js} +155 -129
- package/dist/{setup-TISPCO22.js → setup-RHJRFURI.js} +4 -4
- package/dist/skill-TAAKEYBV.js +389 -0
- package/dist/skills/plan-coordinator/SKILL.md +60 -0
- package/dist/skills/volute-mind/SKILL.md +9 -227
- package/dist/skills/volute-mind/references/extensions.md +34 -0
- package/dist/skills/volute-mind/references/integrations.md +48 -0
- package/dist/skills/volute-mind/references/routing.md +86 -0
- package/dist/skills/volute-mind/references/sleep.md +33 -0
- package/dist/skills/volute-mind/references/variants.md +31 -0
- package/dist/{skills-7FV7EJTE.js → skills-EKMCQ46K.js} +12 -8
- package/dist/sleep-manager-7KFK3USC.js +35 -0
- package/dist/spirit-ZFRDXMG7.js +23 -0
- package/dist/split-AWVOYOPZ.js +64 -0
- package/dist/{sprout-WKLZXUIQ.js → sprout-HE4TITMK.js} +3 -3
- package/dist/start-3UXOPXQG.js +39 -0
- package/dist/status-ZK34WYIM.js +125 -0
- package/dist/stop-3XYIBGFM.js +41 -0
- package/dist/system-chat-IDPHYHY4.js +35 -0
- package/dist/systems-O43WGQY6.js +52 -0
- package/dist/{tailscale-XHQBZROW.js → tailscale-ZIZ2HWJ5.js} +5 -5
- package/dist/template-hash-A7FNHTB7.js +9 -0
- package/dist/up-77ICEDEW.js +19 -0
- package/dist/update-ANE5ZM7F.js +225 -0
- package/dist/{update-check-ZD6OOIYQ.js → update-check-UV55CBEP.js} +4 -4
- package/dist/upgrade-ZMDGC7M2.js +74 -0
- package/dist/variant-QWL2WSRI.js +62 -0
- package/dist/{version-notify-NBI2MTJO.js → version-notify-FXSEMXWW.js} +29 -28
- package/dist/{volute-config-HD7WWUQC.js → volute-config-D2XVS2YI.js} +2 -2
- package/dist/web-assets/assets/index-BhxWKvbB.css +1 -0
- package/dist/web-assets/assets/index-CHVKJ9II.js +75 -0
- package/dist/web-assets/ext-theme.css +48 -9
- package/dist/web-assets/index.html +2 -2
- package/dist/web-assets/sw.js +117 -0
- package/drizzle/0005_meta_summaries.sql +15 -0
- package/drizzle/meta/0005_snapshot.json +7 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +10 -7
- package/packages/extensions/pages/dist/ui/assets/index-DKZLNMED.js +2 -0
- package/packages/extensions/pages/dist/ui/index.html +1 -1
- package/packages/extensions/pages/skills/pages/SKILL.md +84 -9
- package/packages/extensions/plan/dist/ui/assets/index-CJj2gZnZ.css +1 -0
- package/packages/extensions/plan/dist/ui/assets/index-FMEJmvQz.js +61 -0
- package/packages/extensions/plan/dist/ui/index.html +14 -0
- package/packages/extensions/plan/skills/plan/SKILL.md +43 -0
- package/packages/extensions/plan/skills/plan/scripts/plan-hook.sh +37 -0
- package/templates/_base/home/VOLUTE.md +12 -19
- package/templates/_base/src/lib/auto-commit.ts +8 -8
- package/templates/_base/src/lib/context-breakdown.ts +450 -0
- package/templates/_base/src/lib/format-prefix.ts +17 -0
- package/templates/_base/src/lib/hook-loader.ts +8 -2
- package/templates/_base/src/lib/router.ts +75 -33
- package/templates/_base/src/lib/routing.ts +4 -1
- package/templates/_base/src/lib/startup.ts +16 -8
- package/templates/_base/src/lib/types.ts +2 -1
- package/templates/_base/src/lib/volute-server.ts +75 -8
- package/templates/claude/.init/CLAUDE.md +4 -10
- package/templates/claude/package.json.tmpl +1 -0
- package/templates/claude/src/agent.ts +108 -33
- package/templates/claude/src/lib/hooks/reply-instructions.ts +27 -7
- package/templates/claude/src/lib/stream-consumer.ts +2 -2
- package/templates/claude/src/server.ts +1 -0
- package/templates/codex/package.json.tmpl +1 -0
- package/templates/codex/src/agent.ts +80 -8
- package/templates/codex/src/server.ts +1 -4
- package/templates/pi/package.json.tmpl +1 -0
- package/templates/pi/src/agent.ts +115 -36
- package/templates/pi/src/lib/event-handler.ts +22 -7
- package/templates/pi/src/lib/reply-instructions-extension.ts +23 -4
- package/templates/pi/src/lib/subagents.ts +20 -17
- package/templates/pi/src/server.ts +2 -5
- package/dist/accept-D5VBM7JW.js +0 -42
- package/dist/activity-events-XJO3P4RR.js +0 -15
- package/dist/bridge-TXWWPPOJ.js +0 -207
- package/dist/chat-U5ZOME3O.js +0 -68
- package/dist/chunk-3Z2DPESO.js +0 -3634
- package/dist/chunk-A2A4KLFE.js +0 -1528
- package/dist/chunk-K3NQKI34.js +0 -10
- package/dist/chunk-NPKSDYA2.js +0 -156
- package/dist/chunk-PB65JZK2.js +0 -85
- package/dist/clock-BVH3V6E3.js +0 -266
- package/dist/config-H2H4UIF7.js +0 -72
- package/dist/create-2FK7Z46Y.js +0 -44
- package/dist/create-YWD2TIP4.js +0 -71
- package/dist/daemon-client-6QXHZ7US.js +0 -12
- package/dist/daemon-restart-GOBUKLX7.js +0 -52
- package/dist/db-F34YLV7D.js +0 -9
- package/dist/db-RA45JBFG.js +0 -16
- package/dist/delete-QTGWEDBI.js +0 -35
- package/dist/delivery-manager-PFAKEJTC.js +0 -32
- package/dist/down-FWWTEKXM.js +0 -15
- package/dist/env-JCOF2222.js +0 -191
- package/dist/export-SUYRLI5Q.js +0 -112
- package/dist/extension-OBTGKQQD.js +0 -175
- package/dist/extensions-KYNTVTMO.js +0 -30
- package/dist/files-65PMW5IK.js +0 -47
- package/dist/history-DKCDI3JO.js +0 -128
- package/dist/import-DDUFE7AY.js +0 -23
- package/dist/join-I5QEE3LG.js +0 -66
- package/dist/list-JQ463EDA.js +0 -41
- package/dist/login-D7ETSU4R.js +0 -47
- package/dist/login-RIJF2F4G.js +0 -47
- package/dist/logout-5MLHZALK.js +0 -40
- package/dist/logout-UZJRGY4Z.js +0 -21
- package/dist/message-delivery-DFF5SJRM.js +0 -42
- package/dist/mind-IOJFLEM5.js +0 -108
- package/dist/mind-activity-tracker-F6O4Q2SL.js +0 -18
- package/dist/mind-list-WUPMQDYQ.js +0 -30
- package/dist/mind-manager-NBJF5D26.js +0 -32
- package/dist/mind-profile-P67FEHOY.js +0 -47
- package/dist/mind-service-2MQ6UK5N.js +0 -38
- package/dist/mind-sleep-WW2IX7JT.js +0 -42
- package/dist/mind-status-L3EFFRPR.js +0 -56
- package/dist/mind-wake-VSSGW465.js +0 -37
- package/dist/read-EBY56C33.js +0 -75
- package/dist/register-HD74C4TT.js +0 -47
- package/dist/reject-UJKFBHRO.js +0 -40
- package/dist/restart-3UCMRUVC.js +0 -33
- package/dist/scheduler-ZZ7XGQG6.js +0 -32
- package/dist/seed-check-S2IX25RL.js +0 -32
- package/dist/seed-cmd-DKOUFEAU.js +0 -36
- package/dist/seed-create-4XBBOLRH.js +0 -112
- package/dist/seed-sprout-GQEIIQRT.js +0 -132
- package/dist/send-QIV2INHB.js +0 -373
- package/dist/skill-PSQGRRJX.js +0 -358
- package/dist/skills/shared-files/SKILL.md +0 -44
- package/dist/skills/shared-files/scripts/merge.ts +0 -72
- package/dist/skills/shared-files/scripts/pull.ts +0 -52
- package/dist/sleep-manager-JTXSN7NV.js +0 -36
- package/dist/spirit-VRONKFMF.js +0 -23
- package/dist/split-STOROBYJ.js +0 -63
- package/dist/start-K2NCUUCG.js +0 -33
- package/dist/status-3JBTFSMI.js +0 -115
- package/dist/stop-H26JZDXF.js +0 -32
- package/dist/system-chat-JAPOJ3KE.js +0 -36
- package/dist/systems-XRI52VCH.js +0 -61
- package/dist/template-hash-A6VVKOXJ.js +0 -9
- package/dist/up-M5AS6SBV.js +0 -18
- package/dist/update-UD543CXX.js +0 -215
- package/dist/upgrade-O4Q7WJM3.js +0 -67
- package/dist/variant-7TGZHOU3.js +0 -41
- package/dist/web-assets/assets/index-CWJrVveV.css +0 -1
- package/dist/web-assets/assets/index-DJt14FRI.js +0 -75
- package/packages/extensions/pages/dist/ui/assets/index-tLTROSk5.js +0 -2
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
subscribe
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CORXD635.js";
|
|
5
5
|
import {
|
|
6
6
|
logger_default
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BKF4WQCY.js";
|
|
8
8
|
import {
|
|
9
9
|
getDb
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BDYXIWA5.js";
|
|
11
11
|
import {
|
|
12
12
|
conversationParticipants,
|
|
13
13
|
conversationReads,
|
|
14
14
|
conversations,
|
|
15
15
|
messages,
|
|
16
16
|
users
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5N7Y5WAM.js";
|
|
18
18
|
|
|
19
|
-
// src/lib/events/conversations.ts
|
|
19
|
+
// packages/daemon/src/lib/events/conversations.ts
|
|
20
20
|
import { randomUUID } from "crypto";
|
|
21
21
|
import { and, desc, eq, inArray, isNull, lt, sql } from "drizzle-orm";
|
|
22
22
|
|
|
23
|
-
// src/lib/webhook.ts
|
|
23
|
+
// packages/daemon/src/lib/webhook.ts
|
|
24
24
|
var slog = logger_default.child("webhook");
|
|
25
25
|
function getWebhookUrl() {
|
|
26
26
|
return process.env.VOLUTE_WEBHOOK_URL;
|
|
@@ -82,7 +82,7 @@ function initWebhook() {
|
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
// src/lib/events/conversation-events.ts
|
|
85
|
+
// packages/daemon/src/lib/events/conversation-events.ts
|
|
86
86
|
var subscribers = /* @__PURE__ */ new Map();
|
|
87
87
|
function subscribe2(conversationId, callback) {
|
|
88
88
|
let set = subscribers.get(conversationId);
|
|
@@ -110,32 +110,30 @@ function publish(conversationId, event) {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
// src/lib/events/conversations.ts
|
|
113
|
+
// packages/daemon/src/lib/events/conversations.ts
|
|
114
114
|
async function createConversation(mindName, channel, opts) {
|
|
115
115
|
const db = await getDb();
|
|
116
116
|
const id = randomUUID();
|
|
117
117
|
const type = opts?.type ?? "dm";
|
|
118
118
|
const name = opts?.name ?? null;
|
|
119
|
-
await db.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
title: opts?.title ?? null
|
|
128
|
-
});
|
|
129
|
-
if (opts?.participantIds && opts.participantIds.length > 0) {
|
|
130
|
-
await tx.insert(conversationParticipants).values(
|
|
131
|
-
opts.participantIds.map((uid, i) => ({
|
|
132
|
-
conversation_id: id,
|
|
133
|
-
user_id: uid,
|
|
134
|
-
role: i === 0 ? "owner" : "member"
|
|
135
|
-
}))
|
|
136
|
-
);
|
|
137
|
-
}
|
|
119
|
+
await db.insert(conversations).values({
|
|
120
|
+
id,
|
|
121
|
+
mind_name: mindName,
|
|
122
|
+
channel,
|
|
123
|
+
type,
|
|
124
|
+
name,
|
|
125
|
+
user_id: opts?.userId ?? null,
|
|
126
|
+
title: opts?.title ?? null
|
|
138
127
|
});
|
|
128
|
+
if (opts?.participantIds && opts.participantIds.length > 0) {
|
|
129
|
+
await db.insert(conversationParticipants).values(
|
|
130
|
+
opts.participantIds.map((uid, i) => ({
|
|
131
|
+
conversation_id: id,
|
|
132
|
+
user_id: uid,
|
|
133
|
+
role: i === 0 ? "owner" : "member"
|
|
134
|
+
}))
|
|
135
|
+
);
|
|
136
|
+
}
|
|
139
137
|
fireWebhook({
|
|
140
138
|
event: "conversation_created",
|
|
141
139
|
mind: mindName ?? "",
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
broadcast
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CORXD635.js";
|
|
5
5
|
import {
|
|
6
6
|
getDb
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BDYXIWA5.js";
|
|
8
8
|
import {
|
|
9
9
|
users
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5N7Y5WAM.js";
|
|
11
11
|
|
|
12
|
-
// src/lib/auth.ts
|
|
12
|
+
// packages/daemon/src/lib/auth.ts
|
|
13
13
|
import { compareSync, hashSync } from "bcryptjs";
|
|
14
14
|
import { and, count, eq, or } from "drizzle-orm";
|
|
15
15
|
var userSelectFields = {
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
voluteSystemDir,
|
|
4
|
-
voluteUserHome
|
|
5
|
-
} from "./chunk-LRCG2JLP.js";
|
|
6
2
|
|
|
7
|
-
// src/lib/daemon-client.ts
|
|
3
|
+
// packages/cli/src/lib/daemon-client.ts
|
|
8
4
|
import { existsSync, readFileSync } from "fs";
|
|
5
|
+
import { homedir } from "os";
|
|
9
6
|
import { resolve } from "path";
|
|
7
|
+
function voluteUserHome() {
|
|
8
|
+
return process.env.VOLUTE_USER_HOME ?? resolve(homedir(), ".volute");
|
|
9
|
+
}
|
|
10
|
+
function voluteSystemDir() {
|
|
11
|
+
const home = process.env.VOLUTE_HOME ?? resolve(homedir(), ".volute");
|
|
12
|
+
return resolve(home, "system");
|
|
13
|
+
}
|
|
10
14
|
function readSessionFile(mindDir) {
|
|
11
15
|
try {
|
|
12
16
|
const p = resolve(mindDir, ".mind", "current-session");
|
|
@@ -70,9 +74,14 @@ function buildUrl(config) {
|
|
|
70
74
|
}
|
|
71
75
|
return url.origin;
|
|
72
76
|
}
|
|
77
|
+
function resolveDaemonUrl() {
|
|
78
|
+
if (process.env.VOLUTE_DAEMON_URL) return process.env.VOLUTE_DAEMON_URL;
|
|
79
|
+
const session = readCliSession();
|
|
80
|
+
if (session?.daemonUrl) return session.daemonUrl;
|
|
81
|
+
return buildUrl(readDaemonConfig());
|
|
82
|
+
}
|
|
73
83
|
async function daemonFetch(path, options) {
|
|
74
|
-
const
|
|
75
|
-
const url = buildUrl(config);
|
|
84
|
+
const url = resolveDaemonUrl();
|
|
76
85
|
const headers = new Headers(options?.headers);
|
|
77
86
|
const daemonToken = process.env.VOLUTE_DAEMON_TOKEN;
|
|
78
87
|
const cliSession = daemonToken ? null : readCliSession();
|
|
@@ -108,5 +117,6 @@ async function daemonFetch(path, options) {
|
|
|
108
117
|
|
|
109
118
|
export {
|
|
110
119
|
readSessionFile,
|
|
120
|
+
resolveDaemonUrl,
|
|
111
121
|
daemonFetch
|
|
112
122
|
};
|
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ if (!process.env.VOLUTE_HOME) {
|
|
|
10
10
|
var command = process.argv[2];
|
|
11
11
|
var args = process.argv.slice(3);
|
|
12
12
|
if (command === "--version" || command === "-v") {
|
|
13
|
-
const { default: pkg } = await import("./package-
|
|
13
|
+
const { default: pkg } = await import("./package-D2FSVFAX.js");
|
|
14
14
|
console.log(pkg.version);
|
|
15
15
|
process.exit(0);
|
|
16
16
|
}
|
|
@@ -31,7 +31,7 @@ var ungatedCommands = /* @__PURE__ */ new Set([
|
|
|
31
31
|
void 0
|
|
32
32
|
]);
|
|
33
33
|
if (!ungatedCommands.has(command)) {
|
|
34
|
-
const { isSetupComplete } = await import("./setup-
|
|
34
|
+
const { isSetupComplete } = await import("./setup-RHJRFURI.js");
|
|
35
35
|
if (!isSetupComplete()) {
|
|
36
36
|
console.error("Volute is not set up. Run `volute setup` first.");
|
|
37
37
|
process.exit(1);
|
|
@@ -39,58 +39,61 @@ if (!ungatedCommands.has(command)) {
|
|
|
39
39
|
}
|
|
40
40
|
switch (command) {
|
|
41
41
|
case "setup":
|
|
42
|
-
await import("./setup-
|
|
42
|
+
await import("./setup-BJ4YAY26.js").then((m) => m.run(args));
|
|
43
43
|
break;
|
|
44
44
|
case "mind":
|
|
45
|
-
await import("./mind-
|
|
45
|
+
await import("./mind-5IEYKV7I.js").then((m) => m.run(args));
|
|
46
46
|
break;
|
|
47
47
|
case "seed":
|
|
48
|
-
await import("./seed-cmd-
|
|
48
|
+
await import("./seed-cmd-ZM2XGVU2.js").then((m) => m.run(args));
|
|
49
49
|
break;
|
|
50
50
|
case "chat":
|
|
51
|
-
await import("./chat-
|
|
51
|
+
await import("./chat-QXAJF3FU.js").then((m) => m.run(args));
|
|
52
52
|
break;
|
|
53
53
|
case "variant":
|
|
54
|
-
await import("./variant-
|
|
54
|
+
await import("./variant-QWL2WSRI.js").then((m) => m.run(args));
|
|
55
55
|
break;
|
|
56
56
|
case "clock":
|
|
57
|
-
await import("./clock-
|
|
57
|
+
await import("./clock-HSEKS5AR.js").then((m) => m.run(args));
|
|
58
58
|
break;
|
|
59
59
|
case "skill":
|
|
60
|
-
await import("./skill-
|
|
60
|
+
await import("./skill-TAAKEYBV.js").then((m) => m.run(args));
|
|
61
61
|
break;
|
|
62
62
|
case "env":
|
|
63
|
-
await import("./env-
|
|
63
|
+
await import("./env-E4XHO2BI.js").then((m) => m.run(args));
|
|
64
64
|
break;
|
|
65
65
|
case "config":
|
|
66
|
-
await import("./config-
|
|
66
|
+
await import("./config-UTS7QULS.js").then((m) => m.run(args));
|
|
67
67
|
break;
|
|
68
68
|
case "up":
|
|
69
|
-
await import("./up-
|
|
69
|
+
await import("./up-77ICEDEW.js").then((m) => m.run(args));
|
|
70
70
|
break;
|
|
71
71
|
case "down":
|
|
72
|
-
await import("./down-
|
|
72
|
+
await import("./down-74VXM45A.js").then((m) => m.run(args));
|
|
73
73
|
break;
|
|
74
74
|
case "restart":
|
|
75
|
-
await import("./daemon-restart-
|
|
75
|
+
await import("./daemon-restart-HSZ3BCX5.js").then((m) => m.run(args));
|
|
76
76
|
break;
|
|
77
77
|
case "update":
|
|
78
|
-
await import("./update-
|
|
78
|
+
await import("./update-ANE5ZM7F.js").then((m) => m.run(args));
|
|
79
79
|
break;
|
|
80
80
|
case "status":
|
|
81
|
-
await import("./status-
|
|
81
|
+
await import("./status-ZK34WYIM.js").then((m) => m.run(args));
|
|
82
82
|
break;
|
|
83
83
|
case "extension":
|
|
84
|
-
await import("./extension-
|
|
84
|
+
await import("./extension-D74CNM7G.js").then((m) => m.run(args));
|
|
85
85
|
break;
|
|
86
86
|
case "systems":
|
|
87
|
-
await import("./systems-
|
|
87
|
+
await import("./systems-O43WGQY6.js").then((m) => m.run(args));
|
|
88
88
|
break;
|
|
89
89
|
case "login":
|
|
90
|
-
await import("./login-
|
|
90
|
+
await import("./login-7TE6CIZF.js").then((m) => m.run(args));
|
|
91
91
|
break;
|
|
92
92
|
case "logout":
|
|
93
|
-
await import("./logout-
|
|
93
|
+
await import("./logout-T4XS6LRU.js").then((m) => m.run(args));
|
|
94
|
+
break;
|
|
95
|
+
case "service":
|
|
96
|
+
await import("./service-WNPCNHOX.js").then((m) => m.run(args));
|
|
94
97
|
break;
|
|
95
98
|
case "--help":
|
|
96
99
|
case "-h":
|
|
@@ -133,7 +136,7 @@ System:
|
|
|
133
136
|
|
|
134
137
|
Extensions:
|
|
135
138
|
notes write/list/read/... Manage notes
|
|
136
|
-
pages
|
|
139
|
+
pages publish/list/pull/log Manage pages
|
|
137
140
|
|
|
138
141
|
Options:
|
|
139
142
|
--version, -v Show version number
|
|
@@ -147,22 +150,80 @@ use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
|
|
|
147
150
|
default: {
|
|
148
151
|
let isExtensionCommand = false;
|
|
149
152
|
try {
|
|
150
|
-
const { daemonFetch } = await import("./daemon-client-
|
|
153
|
+
const { daemonFetch } = await import("./daemon-client-RVIKXGFQ.js");
|
|
151
154
|
const res = await daemonFetch("/api/extensions/commands");
|
|
152
155
|
if (res.ok) {
|
|
153
156
|
const extCommands = await res.json();
|
|
154
157
|
if (command && command in extCommands) {
|
|
155
158
|
isExtensionCommand = true;
|
|
156
|
-
const subcommand = args[0];
|
|
157
159
|
const ext = extCommands[command];
|
|
158
|
-
|
|
159
|
-
|
|
160
|
+
const subcommand = args[0];
|
|
161
|
+
const wantsHelp = args.includes("--help") || args.includes("-h");
|
|
162
|
+
if (!subcommand || wantsHelp && !(subcommand in ext.commands)) {
|
|
163
|
+
console.log(`Manage ${command}
|
|
164
|
+
`);
|
|
165
|
+
console.log(`Usage: volute ${command} <command> [options]
|
|
160
166
|
`);
|
|
161
|
-
|
|
162
|
-
|
|
167
|
+
console.log("Commands:");
|
|
168
|
+
const entries = Object.entries(ext.commands);
|
|
169
|
+
const nameWidth = Math.max(...entries.map(([k]) => k.length));
|
|
170
|
+
for (const [name, meta] of entries) {
|
|
171
|
+
console.log(` ${name.padEnd(nameWidth + 2)} ${meta.description}`);
|
|
172
|
+
}
|
|
173
|
+
console.log(`
|
|
174
|
+
Use --mind <name> or VOLUTE_MIND to specify the mind.
|
|
175
|
+
`);
|
|
176
|
+
process.exit(subcommand ? 0 : 1);
|
|
177
|
+
}
|
|
178
|
+
if (wantsHelp && subcommand in ext.commands) {
|
|
179
|
+
const meta = ext.commands[subcommand];
|
|
180
|
+
const argParts = (meta.args ?? []).map(
|
|
181
|
+
(a) => a.required ? `<${a.name}>` : `[${a.name}]`
|
|
182
|
+
);
|
|
183
|
+
const flagEntries = Object.entries(meta.flags ?? {});
|
|
184
|
+
const flagPart = flagEntries.length > 0 ? " [options]" : "";
|
|
185
|
+
const argStr = argParts.length > 0 ? ` ${argParts.join(" ")}` : "";
|
|
186
|
+
console.log(`${meta.description}
|
|
187
|
+
`);
|
|
188
|
+
console.log(`Usage: volute ${command} ${subcommand}${argStr}${flagPart}
|
|
189
|
+
`);
|
|
190
|
+
if (meta.args && meta.args.length > 0) {
|
|
191
|
+
console.log("Arguments:");
|
|
192
|
+
const w = Math.max(...meta.args.map((a) => a.name.length + 2));
|
|
193
|
+
for (const a of meta.args) {
|
|
194
|
+
const label = a.required ? `<${a.name}>` : `[${a.name}]`;
|
|
195
|
+
console.log(` ${label.padEnd(w + 2)} ${a.description}`);
|
|
196
|
+
}
|
|
197
|
+
console.log("");
|
|
198
|
+
}
|
|
199
|
+
if (flagEntries.length > 0) {
|
|
200
|
+
console.log("Options:");
|
|
201
|
+
const w = Math.max(
|
|
202
|
+
...flagEntries.map(([k, v]) => {
|
|
203
|
+
const hint = v.type === "boolean" ? "" : ` <${v.type === "string" ? "value" : "n"}>`;
|
|
204
|
+
return `--${k}${hint}`.length;
|
|
205
|
+
})
|
|
206
|
+
);
|
|
207
|
+
for (const [key, val] of flagEntries) {
|
|
208
|
+
const hint = val.type === "boolean" ? "" : ` <${val.type === "string" ? "value" : "n"}>`;
|
|
209
|
+
const flag = `--${key}${hint}`;
|
|
210
|
+
console.log(` ${flag.padEnd(w + 2)} ${val.description}`);
|
|
211
|
+
}
|
|
212
|
+
console.log("");
|
|
213
|
+
}
|
|
214
|
+
if (meta.examples && meta.examples.length > 0) {
|
|
215
|
+
console.log("Examples:");
|
|
216
|
+
for (const ex of meta.examples) {
|
|
217
|
+
console.log(` ${ex}`);
|
|
218
|
+
}
|
|
219
|
+
console.log("");
|
|
163
220
|
}
|
|
164
221
|
process.exit(0);
|
|
165
222
|
}
|
|
223
|
+
if (!(subcommand in ext.commands)) {
|
|
224
|
+
console.error(`Unknown command: volute ${command} ${subcommand}`);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
166
227
|
const cmdArgs = args.slice(1);
|
|
167
228
|
let mind = process.env.VOLUTE_MIND;
|
|
168
229
|
const mindIdx = cmdArgs.indexOf("--mind");
|
|
@@ -170,7 +231,7 @@ use --mind <name> or VOLUTE_MIND env var to identify the mind.`);
|
|
|
170
231
|
mind = cmdArgs[mindIdx + 1];
|
|
171
232
|
cmdArgs.splice(mindIdx, 2);
|
|
172
233
|
}
|
|
173
|
-
const { readStdin } = await import("./read-stdin-
|
|
234
|
+
const { readStdin } = await import("./read-stdin-3X5VYKNS.js");
|
|
174
235
|
const stdin = await readStdin();
|
|
175
236
|
const cmdRes = await daemonFetch(`/api/ext/${command}/commands/${subcommand}`, {
|
|
176
237
|
method: "POST",
|
|
@@ -203,7 +264,7 @@ Run 'volute --help' for usage.`);
|
|
|
203
264
|
}
|
|
204
265
|
}
|
|
205
266
|
if (command !== "update") {
|
|
206
|
-
import("./update-check-
|
|
267
|
+
import("./update-check-UV55CBEP.js").then((m) => m.checkForUpdate()).then((result) => {
|
|
207
268
|
if (result.updateAvailable) {
|
|
208
269
|
console.error(`
|
|
209
270
|
Update available: ${result.current} \u2192 ${result.latest}`);
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
compactDateTime,
|
|
4
|
+
isCompact
|
|
5
|
+
} from "./chunk-5T5YMX6S.js";
|
|
6
|
+
import {
|
|
7
|
+
resolveMindName
|
|
8
|
+
} from "./chunk-BTY4WNFE.js";
|
|
9
|
+
import {
|
|
10
|
+
command,
|
|
11
|
+
subcommands
|
|
12
|
+
} from "./chunk-TXSA4Q3V.js";
|
|
13
|
+
import "./chunk-O7IGP7ZW.js";
|
|
14
|
+
import {
|
|
15
|
+
daemonFetch
|
|
16
|
+
} from "./chunk-ZX7EAV5J.js";
|
|
17
|
+
import {
|
|
18
|
+
getClient,
|
|
19
|
+
urlOf
|
|
20
|
+
} from "./chunk-LOPXTW6H.js";
|
|
21
|
+
import "./chunk-7KJOFUNN.js";
|
|
22
|
+
|
|
23
|
+
// packages/cli/src/commands/clock.ts
|
|
24
|
+
import { CronExpressionParser } from "cron-parser";
|
|
25
|
+
function parseDuration(input) {
|
|
26
|
+
const parts = input.match(/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/);
|
|
27
|
+
if (!parts || parts[0] !== input) return null;
|
|
28
|
+
const hours = parseInt(parts[1] || "0", 10);
|
|
29
|
+
const minutes = parseInt(parts[2] || "0", 10);
|
|
30
|
+
const seconds = parseInt(parts[3] || "0", 10);
|
|
31
|
+
const total = hours * 36e5 + minutes * 6e4 + seconds * 1e3;
|
|
32
|
+
return total > 0 ? total : null;
|
|
33
|
+
}
|
|
34
|
+
var clockStatusCmd = command({
|
|
35
|
+
name: "volute clock status",
|
|
36
|
+
description: "Show sleep state and upcoming events",
|
|
37
|
+
flags: {
|
|
38
|
+
mind: { type: "string", description: "Mind name" }
|
|
39
|
+
},
|
|
40
|
+
run: async ({ flags }) => {
|
|
41
|
+
const mind = resolveMindName(flags);
|
|
42
|
+
const client = getClient();
|
|
43
|
+
const res = await daemonFetch(
|
|
44
|
+
urlOf(client.api.minds[":name"].clock.status.$url({ param: { name: mind } }))
|
|
45
|
+
);
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
const data = await res.json();
|
|
48
|
+
console.error(data.error ?? `Failed to get clock status: ${res.status}`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const status = await res.json();
|
|
52
|
+
const compact = isCompact();
|
|
53
|
+
const fmtTime = (s) => compact ? compactDateTime(s) : new Date(s).toLocaleString();
|
|
54
|
+
if (status.sleep?.sleeping) {
|
|
55
|
+
const since = status.sleep.sleepingSince ? fmtTime(status.sleep.sleepingSince) : "unknown";
|
|
56
|
+
console.log(`Sleep: sleeping since ${since}`);
|
|
57
|
+
if (status.sleep.scheduledWakeAt) {
|
|
58
|
+
console.log(` Wake at: ${fmtTime(status.sleep.scheduledWakeAt)}`);
|
|
59
|
+
}
|
|
60
|
+
if (status.sleep.voluntaryWakeAt) {
|
|
61
|
+
console.log(` Voluntary wake at: ${fmtTime(status.sleep.voluntaryWakeAt)}`);
|
|
62
|
+
}
|
|
63
|
+
if (status.sleep.queuedMessageCount > 0) {
|
|
64
|
+
console.log(` Queued messages: ${status.sleep.queuedMessageCount}`);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
console.log("Sleep: awake");
|
|
68
|
+
}
|
|
69
|
+
if (status.sleepConfig?.enabled && status.sleepConfig.schedule) {
|
|
70
|
+
console.log(
|
|
71
|
+
` Schedule: sleep ${status.sleepConfig.schedule.sleep}, wake ${status.sleepConfig.schedule.wake}`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
if (status.upcoming.length > 0) {
|
|
75
|
+
if (!compact) console.log("");
|
|
76
|
+
console.log("Upcoming (next 24h):");
|
|
77
|
+
for (const u of status.upcoming) {
|
|
78
|
+
const time = fmtTime(u.at);
|
|
79
|
+
const label = u.type === "timer" ? "[timer]" : "[cron]";
|
|
80
|
+
console.log(` ${u.id.padEnd(20)} ${label} ${time}`);
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
if (!compact) console.log("");
|
|
84
|
+
console.log("No upcoming events in next 24h.");
|
|
85
|
+
}
|
|
86
|
+
if (!compact) {
|
|
87
|
+
console.log(`
|
|
88
|
+
${status.schedules.length} schedule(s) configured.`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
var listSchedulesCmd = command({
|
|
93
|
+
name: "volute clock list",
|
|
94
|
+
description: "List schedules and timers",
|
|
95
|
+
flags: {
|
|
96
|
+
mind: { type: "string", description: "Mind name" }
|
|
97
|
+
},
|
|
98
|
+
run: async ({ flags }) => {
|
|
99
|
+
const mind = resolveMindName(flags);
|
|
100
|
+
const client = getClient();
|
|
101
|
+
const res = await daemonFetch(
|
|
102
|
+
urlOf(client.api.minds[":name"].schedules.$url({ param: { name: mind } }))
|
|
103
|
+
);
|
|
104
|
+
if (!res.ok) {
|
|
105
|
+
const data = await res.json();
|
|
106
|
+
console.error(data.error ?? `Failed to list schedules: ${res.status}`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
const schedules = await res.json();
|
|
110
|
+
if (schedules.length === 0) {
|
|
111
|
+
console.log("No schedules configured.");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const actionLabel = (s) => s.script ? `[script] ${s.script}` : s.message ?? "";
|
|
115
|
+
if (isCompact()) {
|
|
116
|
+
for (const s of schedules) {
|
|
117
|
+
const sched = s.cron ?? (s.fireAt ? `at ${s.fireAt}` : "");
|
|
118
|
+
console.log(`${s.id} ${sched} ${actionLabel(s)}`);
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
const idW = Math.max(2, ...schedules.map((s) => s.id.length));
|
|
122
|
+
const schedW = Math.max(8, ...schedules.map((s) => (s.cron ?? s.fireAt ?? "").length));
|
|
123
|
+
console.log(`${"ID".padEnd(idW)} ${"SCHEDULE".padEnd(schedW)} ENABLED ACTION`);
|
|
124
|
+
for (const s of schedules) {
|
|
125
|
+
const sched = s.cron ?? (s.fireAt ? `at ${s.fireAt}` : "");
|
|
126
|
+
console.log(
|
|
127
|
+
`${s.id.padEnd(idW)} ${sched.padEnd(schedW)} ${String(s.enabled).padEnd(7)} ${actionLabel(s)}`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
var addScheduleCmd = command({
|
|
134
|
+
name: "volute clock add",
|
|
135
|
+
description: "Add a schedule or timer",
|
|
136
|
+
flags: {
|
|
137
|
+
mind: { type: "string", description: "Mind name" },
|
|
138
|
+
cron: { type: "string", description: "Cron expression" },
|
|
139
|
+
in: { type: "string", description: "Duration (e.g. 30s, 10m, 1h)" },
|
|
140
|
+
message: { type: "string", description: "Message to send" },
|
|
141
|
+
script: { type: "string", description: "Script to run" },
|
|
142
|
+
id: { type: "string", description: "Schedule ID (required)" },
|
|
143
|
+
session: { type: "string", description: "Session name" },
|
|
144
|
+
"while-sleeping": {
|
|
145
|
+
type: "string",
|
|
146
|
+
description: "Behavior during sleep (skip, queue, trigger-wake)"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
run: async ({ flags }) => {
|
|
150
|
+
const mind = resolveMindName(flags);
|
|
151
|
+
if (!flags.id) {
|
|
152
|
+
console.error("--id is required (a descriptive name for this schedule)");
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
if (!flags.cron && !flags.in) {
|
|
156
|
+
console.error("--cron or --in is required");
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
if (flags.cron && flags.in) {
|
|
160
|
+
console.error("--cron and --in are mutually exclusive");
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
if (!flags.message && !flags.script) {
|
|
164
|
+
console.error("--message or --script is required");
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
if (flags.message && flags.script) {
|
|
168
|
+
console.error("--message and --script are mutually exclusive");
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
const body = {};
|
|
172
|
+
if (flags.cron) {
|
|
173
|
+
try {
|
|
174
|
+
CronExpressionParser.parse(flags.cron);
|
|
175
|
+
} catch {
|
|
176
|
+
console.error(`Invalid cron expression: ${flags.cron}`);
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
body.cron = flags.cron;
|
|
180
|
+
}
|
|
181
|
+
if (flags.in) {
|
|
182
|
+
const durationMs = parseDuration(flags.in);
|
|
183
|
+
if (!durationMs) {
|
|
184
|
+
console.error(`Invalid duration: ${flags.in} (expected format: 30s, 10m, 1h, 2h30m)`);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
body.fireAt = new Date(Date.now() + durationMs).toISOString();
|
|
188
|
+
}
|
|
189
|
+
if (flags.message) body.message = flags.message;
|
|
190
|
+
if (flags.script) body.script = flags.script;
|
|
191
|
+
if (flags.id) body.id = flags.id;
|
|
192
|
+
if (flags.session) body.session = flags.session;
|
|
193
|
+
if (flags["while-sleeping"]) {
|
|
194
|
+
const ws = flags["while-sleeping"];
|
|
195
|
+
if (!["skip", "queue", "trigger-wake"].includes(ws)) {
|
|
196
|
+
console.error(
|
|
197
|
+
`Invalid --while-sleeping value: ${ws} (must be skip, queue, or trigger-wake)`
|
|
198
|
+
);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
body.whileSleeping = ws;
|
|
202
|
+
}
|
|
203
|
+
const client = getClient();
|
|
204
|
+
const res = await daemonFetch(
|
|
205
|
+
urlOf(client.api.minds[":name"].schedules.$url({ param: { name: mind } })),
|
|
206
|
+
{
|
|
207
|
+
method: "POST",
|
|
208
|
+
headers: { "Content-Type": "application/json" },
|
|
209
|
+
body: JSON.stringify(body)
|
|
210
|
+
}
|
|
211
|
+
);
|
|
212
|
+
if (!res.ok) {
|
|
213
|
+
const data2 = await res.json();
|
|
214
|
+
console.error(data2.error ?? `Failed to add schedule: ${res.status}`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
const data = await res.json();
|
|
218
|
+
if (flags.in) {
|
|
219
|
+
console.log(`Timer set: ${data.id} (fires in ${flags.in})`);
|
|
220
|
+
} else {
|
|
221
|
+
console.log(`Schedule added: ${data.id}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
var removeScheduleCmd = command({
|
|
226
|
+
name: "volute clock remove",
|
|
227
|
+
description: "Remove a schedule or timer",
|
|
228
|
+
flags: {
|
|
229
|
+
mind: { type: "string", description: "Mind name" },
|
|
230
|
+
id: { type: "string", description: "Schedule ID (required)" }
|
|
231
|
+
},
|
|
232
|
+
run: async ({ flags }) => {
|
|
233
|
+
const mind = resolveMindName(flags);
|
|
234
|
+
if (!flags.id) {
|
|
235
|
+
console.error("--id is required");
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
const client = getClient();
|
|
239
|
+
const res = await daemonFetch(
|
|
240
|
+
urlOf(
|
|
241
|
+
client.api.minds[":name"].schedules[":id"].$url({
|
|
242
|
+
param: { name: mind, id: flags.id }
|
|
243
|
+
})
|
|
244
|
+
),
|
|
245
|
+
{ method: "DELETE" }
|
|
246
|
+
);
|
|
247
|
+
if (!res.ok) {
|
|
248
|
+
const data = await res.json();
|
|
249
|
+
console.error(data.error ?? `Failed to remove schedule: ${res.status}`);
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
console.log(`Schedule removed: ${flags.id}`);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
var cmd = subcommands({
|
|
256
|
+
name: "volute clock",
|
|
257
|
+
description: "Manage schedules, timers, and sleep/wake cycles",
|
|
258
|
+
commands: {
|
|
259
|
+
status: {
|
|
260
|
+
description: "Show sleep state and upcoming schedule fires",
|
|
261
|
+
run: clockStatusCmd.execute
|
|
262
|
+
},
|
|
263
|
+
list: {
|
|
264
|
+
description: "List schedules and timers",
|
|
265
|
+
run: listSchedulesCmd.execute
|
|
266
|
+
},
|
|
267
|
+
add: {
|
|
268
|
+
description: "Add a schedule or timer",
|
|
269
|
+
run: addScheduleCmd.execute
|
|
270
|
+
},
|
|
271
|
+
remove: {
|
|
272
|
+
description: "Remove a schedule or timer",
|
|
273
|
+
run: removeScheduleCmd.execute
|
|
274
|
+
},
|
|
275
|
+
sleep: {
|
|
276
|
+
description: "Put a mind to sleep",
|
|
277
|
+
run: (args) => import("./mind-sleep-ITCF6OQA.js").then((m) => m.run(args))
|
|
278
|
+
},
|
|
279
|
+
wake: {
|
|
280
|
+
description: "Wake a sleeping mind",
|
|
281
|
+
run: (args) => import("./mind-wake-KXMKMGWX.js").then((m) => m.run(args))
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
|
|
285
|
+
});
|
|
286
|
+
var run = cmd.execute;
|
|
287
|
+
export {
|
|
288
|
+
run
|
|
289
|
+
};
|