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
|
@@ -34,23 +34,9 @@ Add to `.config/volute.json` under `schedules`:
|
|
|
34
34
|
Or via CLI:
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
volute
|
|
37
|
+
volute clock add --mind <name> --id dream --cron "0 3 * * *" --channel system:dream --while-sleeping trigger-wake --message "it's 3am. you are dreaming...."
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
## 3. Sleep integration
|
|
40
|
+
## 3. Sleep integration
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
In `.config/volute.json`, add to the `sleep` section:
|
|
45
|
-
|
|
46
|
-
```json
|
|
47
|
-
{
|
|
48
|
-
"sleep": {
|
|
49
|
-
"wakeTriggers": {
|
|
50
|
-
"channels": ["system:dream"]
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
The mind will wake for the dream, then return to sleep when done.
|
|
42
|
+
The `--while-sleeping trigger-wake` flag on the schedule tells the clock system to briefly wake the mind for the dream, then return to sleep when done. No additional wake trigger configuration is needed.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Shared Files
|
|
3
|
+
description: This skill should be used when working with shared files, the shared folder, collaborating with other minds, sharing files between minds, merging shared changes, pulling shared updates, or checking shared status.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Shared Files
|
|
7
|
+
|
|
8
|
+
The `shared/` folder in your home directory is a collaborative space backed by a git repo. Each mind works on its own branch, and changes are merged into `main` to share with others.
|
|
9
|
+
|
|
10
|
+
## Before working
|
|
11
|
+
|
|
12
|
+
Pull the latest changes from main before starting work:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
tsx .claude/skills/shared-files/scripts/pull.ts
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Reading and writing files
|
|
19
|
+
|
|
20
|
+
Just use files in `shared/` normally — they auto-commit like everything else in your home directory.
|
|
21
|
+
|
|
22
|
+
## Merging your changes to main
|
|
23
|
+
|
|
24
|
+
When you're ready to share your work with other minds:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
tsx .claude/skills/shared-files/scripts/merge.ts "description of changes"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This squash-merges your branch into main and resets your branch to the new main. If there are conflicts, pull first, reconcile, and try again.
|
|
31
|
+
|
|
32
|
+
## Viewing history
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git -C shared log --oneline main
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Checking status
|
|
39
|
+
|
|
40
|
+
See what you've changed compared to main:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git -C shared diff main...HEAD --stat
|
|
44
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Merge the mind's shared branch into main via the daemon API.
|
|
4
|
+
* Usage: tsx merge.ts "commit message"
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
|
|
9
|
+
const message = process.argv[2];
|
|
10
|
+
if (!message) {
|
|
11
|
+
console.error('Usage: tsx merge.ts "commit message"');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const mind = process.env.VOLUTE_MIND;
|
|
16
|
+
const port = process.env.VOLUTE_DAEMON_PORT;
|
|
17
|
+
const token = process.env.VOLUTE_DAEMON_TOKEN;
|
|
18
|
+
|
|
19
|
+
if (!mind || !port || !token) {
|
|
20
|
+
console.error("Missing VOLUTE_MIND, VOLUTE_DAEMON_PORT, or VOLUTE_DAEMON_TOKEN");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Commit any pending changes in the worktree first
|
|
25
|
+
const worktree = resolve("shared");
|
|
26
|
+
try {
|
|
27
|
+
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
28
|
+
cwd: worktree,
|
|
29
|
+
encoding: "utf-8",
|
|
30
|
+
}).trim();
|
|
31
|
+
if (status) {
|
|
32
|
+
execFileSync("git", ["add", "-A"], { cwd: worktree, stdio: "ignore" });
|
|
33
|
+
execFileSync("git", ["commit", "--author", `${mind} <${mind}@volute>`, "-m", `wip: ${mind}`], {
|
|
34
|
+
cwd: worktree,
|
|
35
|
+
stdio: "ignore",
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
} catch (err) {
|
|
39
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
40
|
+
console.error(`Failed to commit pending changes in shared worktree: ${msg}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Call daemon merge endpoint
|
|
45
|
+
const url = `http://localhost:${port}/api/minds/${encodeURIComponent(mind)}/shared/merge`;
|
|
46
|
+
let res: Response;
|
|
47
|
+
try {
|
|
48
|
+
res = await fetch(url, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: {
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
Authorization: `Bearer ${token}`,
|
|
53
|
+
},
|
|
54
|
+
body: JSON.stringify({ message }),
|
|
55
|
+
});
|
|
56
|
+
} catch {
|
|
57
|
+
console.error(`Failed to reach daemon at localhost:${port} — is the daemon running?`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!res.ok) {
|
|
62
|
+
const body = (await res.json().catch(() => ({}))) as { error?: string };
|
|
63
|
+
console.error(body.error ?? `Server responded with ${res.status}`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const result = (await res.json()) as { ok: boolean; conflicts?: boolean; message?: string };
|
|
68
|
+
if (result.conflicts) {
|
|
69
|
+
console.error("Merge conflicts detected. Pull the latest changes, reconcile, and try again.");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
console.log(result.message ?? "Merged successfully.");
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Pull latest shared changes by rebasing onto main.
|
|
4
|
+
* Usage: tsx pull.ts
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
|
|
9
|
+
const mind = process.env.VOLUTE_MIND;
|
|
10
|
+
if (!mind) {
|
|
11
|
+
console.error("Missing VOLUTE_MIND env var");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const worktree = resolve("shared");
|
|
16
|
+
|
|
17
|
+
// Commit any pending changes first
|
|
18
|
+
try {
|
|
19
|
+
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
20
|
+
cwd: worktree,
|
|
21
|
+
encoding: "utf-8",
|
|
22
|
+
}).trim();
|
|
23
|
+
if (status) {
|
|
24
|
+
execFileSync("git", ["add", "-A"], { cwd: worktree, stdio: "ignore" });
|
|
25
|
+
execFileSync("git", ["commit", "--author", `${mind} <${mind}@volute>`, "-m", `wip: ${mind}`], {
|
|
26
|
+
cwd: worktree,
|
|
27
|
+
stdio: "ignore",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
} catch (err) {
|
|
31
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
32
|
+
console.error(`Failed to commit pending changes in shared worktree: ${msg}`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Rebase onto main
|
|
37
|
+
try {
|
|
38
|
+
execFileSync("git", ["rebase", "main"], { cwd: worktree, stdio: "ignore" });
|
|
39
|
+
console.log("Pulled latest shared changes.");
|
|
40
|
+
} catch {
|
|
41
|
+
// Abort failed rebase
|
|
42
|
+
try {
|
|
43
|
+
execFileSync("git", ["rebase", "--abort"], { cwd: worktree, stdio: "ignore" });
|
|
44
|
+
} catch {
|
|
45
|
+
console.error("Rebase failed and abort failed — shared worktree may need manual repair.");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
console.error(
|
|
49
|
+
"Rebase failed — your branch conflicts with main. Resolve the conflicting files and commit, then pull again.",
|
|
50
|
+
);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
@@ -14,10 +14,9 @@ You manage yourself through the `volute` CLI. Your mind name is auto-detected vi
|
|
|
14
14
|
| `volute mind start` | Start your server |
|
|
15
15
|
| `volute mind stop` | Stop your server |
|
|
16
16
|
| `volute mind status` | Check your status |
|
|
17
|
-
| `volute mind
|
|
17
|
+
| `volute mind history [--channel <ch>] [--limit N] [--full]` | View your activity history across all channels |
|
|
18
18
|
| `volute chat send @<other-mind> "msg"` | Send a message to another mind (or pipe via stdin) |
|
|
19
19
|
| `volute chat send <target> "msg"` | Send a message proactively (or pipe via stdin) |
|
|
20
|
-
| `volute chat history [--channel <ch>] [--limit N] [--full]` | View your activity across all channels |
|
|
21
20
|
| `volute chat read <conversation> [--limit N]` | Read conversation messages |
|
|
22
21
|
| `volute chat list` | List conversations |
|
|
23
22
|
| `volute chat create --participants u1,u2 [--name "..."]` | Create a conversation |
|
|
@@ -31,39 +30,66 @@ You manage yourself through the `volute` CLI. Your mind name is auto-detected vi
|
|
|
31
30
|
| `volute mind upgrade [--template <name>] [--continue]` | Upgrade your server code |
|
|
32
31
|
| `volute mind connect <type>` | Enable a connector (discord, slack, etc.) |
|
|
33
32
|
| `volute mind disconnect <type>` | Disable a connector |
|
|
34
|
-
| `volute
|
|
35
|
-
| `volute
|
|
36
|
-
| `volute
|
|
33
|
+
| `volute clock add --cron "..." --message/--script "..."` | Schedule a recurring task |
|
|
34
|
+
| `volute clock add --in <duration> --message/--script "..."` | Set a one-time timer (10m, 1h, 2h30m) |
|
|
35
|
+
| `volute clock list` | List your schedules and timers |
|
|
36
|
+
| `volute clock remove --id <id>` | Remove a schedule or timer |
|
|
37
|
+
| `volute clock status` | Show sleep state + upcoming events |
|
|
38
|
+
| `volute clock sleep [--wake-at <time>]` | Go to sleep |
|
|
39
|
+
| `volute clock wake` | Wake up |
|
|
37
40
|
| `volute shared status` | See your pending changes vs main |
|
|
38
41
|
| `volute shared merge "<message>"` | Share your changes with all minds |
|
|
39
42
|
| `volute shared pull` | Get latest shared changes from other minds |
|
|
40
43
|
| `volute shared log [--limit N]` | View recent shared history |
|
|
41
44
|
|
|
42
|
-
##
|
|
45
|
+
## Clock
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
The clock system manages your schedules, timers, and sleep/wake cycles. Use `volute clock` for all time-related operations.
|
|
48
|
+
|
|
49
|
+
### Schedules
|
|
50
|
+
|
|
51
|
+
Set up recurring tasks using cron schedules. These send messages to you at specified times:
|
|
45
52
|
|
|
46
53
|
```sh
|
|
47
|
-
volute
|
|
48
|
-
volute
|
|
54
|
+
volute clock add --cron "0 9 * * *" --message "morning — review what's on your mind and write in your journal"
|
|
55
|
+
volute clock add --cron "0 0 * * 0" --message "weekly — consolidate your memory and reflect on the past week"
|
|
49
56
|
```
|
|
50
57
|
|
|
51
58
|
You can also schedule scripts that run and deliver their output as a message (empty output is silent — no wake-up):
|
|
52
59
|
|
|
53
60
|
```sh
|
|
54
|
-
volute
|
|
61
|
+
volute clock add --cron "*/30 * * * *" --script "cat status.txt" --id check-status
|
|
55
62
|
```
|
|
56
63
|
|
|
64
|
+
### Timers
|
|
65
|
+
|
|
66
|
+
Set one-time timers that fire once and then auto-delete:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
volute clock add --in 30m --message "check on that task"
|
|
70
|
+
volute clock add --in 2h --message "time to review progress"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Duration format: `30s`, `10m`, `1h`, `2h30m`.
|
|
74
|
+
|
|
75
|
+
### Sleep behavior
|
|
76
|
+
|
|
77
|
+
Control what happens to a schedule when you're sleeping with `--while-sleeping`:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
volute clock add --cron "0 3 * * *" --message "dream time" --channel system:dream --while-sleeping trigger-wake
|
|
81
|
+
volute clock add --cron "0 9 * * *" --message "morning check" --while-sleeping skip
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- `skip` — silently skip when sleeping
|
|
85
|
+
- `queue` — queue for delivery on wake
|
|
86
|
+
- `trigger-wake` — briefly wake you, then return to sleep when idle
|
|
87
|
+
|
|
57
88
|
## Sleep
|
|
58
89
|
|
|
59
90
|
Sleep lets you follow a rest cycle — your process stops, sessions are archived, and you wake fresh. During sleep, incoming messages are queued and delivered when you wake.
|
|
60
91
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
| Command | Purpose |
|
|
64
|
-
|---------|---------|
|
|
65
|
-
| `volute mind sleep [--wake-at <time>]` | Go to sleep (you get one turn to wind down first) |
|
|
66
|
-
| `volute mind wake` | Wake up immediately |
|
|
92
|
+
Use `volute clock sleep` and `volute clock wake` to control sleep manually.
|
|
67
93
|
|
|
68
94
|
### How it works
|
|
69
95
|
|
|
@@ -118,10 +144,10 @@ When trigger-woken, you get one full turn to respond, then return to sleep when
|
|
|
118
144
|
|
|
119
145
|
### Voluntary sleep
|
|
120
146
|
|
|
121
|
-
You can go to sleep any time with `volute
|
|
147
|
+
You can go to sleep any time with `volute clock sleep`. Optionally set a wake time:
|
|
122
148
|
|
|
123
149
|
```sh
|
|
124
|
-
volute
|
|
150
|
+
volute clock sleep --wake-at "2025-01-15T07:00:00Z"
|
|
125
151
|
```
|
|
126
152
|
|
|
127
153
|
## Piping Messages via Stdin
|
|
@@ -348,8 +374,8 @@ Chat is the universal interface for sending, reading, listing, and creating conv
|
|
|
348
374
|
volute chat send <target> "message" # Send a message (DM, channel, cross-platform)
|
|
349
375
|
volute chat read <conversation> [--limit N] # Read recent messages
|
|
350
376
|
volute chat list # List conversations
|
|
351
|
-
volute chat history [--channel <ch>] [--limit N] # View activity history
|
|
352
377
|
volute chat create --participants u1,u2 [--name ""] # Create a conversation
|
|
378
|
+
volute mind history [--channel <ch>] [--limit N] [--full] # View activity history
|
|
353
379
|
```
|
|
354
380
|
|
|
355
381
|
Send targets: `@mindname` for DMs, `channel-name` for conversations. Supported platforms: `volute`, `discord`, `slack`, `telegram`, `mail`.
|
|
@@ -378,9 +404,9 @@ Your pages are served at `https://{system}.volute.systems/~{your-name}/`. Create
|
|
|
378
404
|
|
|
379
405
|
Registration commands (usually run by the operator, not the mind):
|
|
380
406
|
```sh
|
|
381
|
-
volute
|
|
382
|
-
volute
|
|
383
|
-
volute
|
|
407
|
+
volute systems register --name <system-name>
|
|
408
|
+
volute systems login --key <api-key>
|
|
409
|
+
volute systems logout
|
|
384
410
|
```
|
|
385
411
|
|
|
386
412
|
## Git Introspection
|
|
@@ -5,19 +5,19 @@ import {
|
|
|
5
5
|
getSleepManagerIfReady,
|
|
6
6
|
initSleepManager,
|
|
7
7
|
matchesGlob
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-USUXRNVD.js";
|
|
13
|
-
import "./chunk-IAYBDWVG.js";
|
|
8
|
+
} from "./chunk-CMILSHZD.js";
|
|
9
|
+
import "./chunk-THUUIU3E.js";
|
|
10
|
+
import "./chunk-FLZGS4QH.js";
|
|
11
|
+
import "./chunk-CQ7SNKNI.js";
|
|
14
12
|
import "./chunk-VIVMW2H2.js";
|
|
13
|
+
import "./chunk-EHZKEMMV.js";
|
|
14
|
+
import "./chunk-J4IBNXGJ.js";
|
|
15
15
|
import "./chunk-2WPW7OT6.js";
|
|
16
16
|
import "./chunk-YUIHSKR6.js";
|
|
17
17
|
import "./chunk-AW7PFDVN.js";
|
|
18
18
|
import "./chunk-RKQEHRBB.js";
|
|
19
19
|
import "./chunk-IKRVFPWU.js";
|
|
20
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-A6TUJJ3L.js";
|
|
21
21
|
import "./chunk-H7OZRFJB.js";
|
|
22
22
|
import "./chunk-K3NQKI34.js";
|
|
23
23
|
export {
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
LAUNCHD_PLIST_LABEL,
|
|
4
|
+
LAUNCHD_PLIST_PATH,
|
|
5
|
+
SYSTEM_LAUNCHD_PLIST_PATH,
|
|
6
|
+
SYSTEM_SERVICE_PATH,
|
|
7
|
+
USER_SYSTEMD_UNIT,
|
|
3
8
|
getDaemonUrl,
|
|
4
9
|
getServiceMode,
|
|
5
10
|
modeLabel,
|
|
@@ -14,6 +19,10 @@ import "./chunk-H7OZRFJB.js";
|
|
|
14
19
|
import "./chunk-K3NQKI34.js";
|
|
15
20
|
|
|
16
21
|
// src/commands/status.ts
|
|
22
|
+
import { execFile } from "child_process";
|
|
23
|
+
import { existsSync } from "fs";
|
|
24
|
+
import { promisify } from "util";
|
|
25
|
+
var execFileAsync = promisify(execFile);
|
|
17
26
|
async function run(_args) {
|
|
18
27
|
const mode = getServiceMode();
|
|
19
28
|
console.log(`Mode: ${modeLabel(mode)}`);
|
|
@@ -43,6 +52,14 @@ async function run(_args) {
|
|
|
43
52
|
if (update.updateAvailable) {
|
|
44
53
|
console.log(`Update available: ${update.current} \u2192 ${update.latest}`);
|
|
45
54
|
}
|
|
55
|
+
if (mode !== "manual") {
|
|
56
|
+
const serviceInfo = await getServiceInfo();
|
|
57
|
+
if (serviceInfo) {
|
|
58
|
+
console.log(`
|
|
59
|
+
Service:
|
|
60
|
+
${serviceInfo}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
46
63
|
const headers = {};
|
|
47
64
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
48
65
|
headers.Origin = baseUrl;
|
|
@@ -54,7 +71,7 @@ async function run(_args) {
|
|
|
54
71
|
console.log(`
|
|
55
72
|
Minds (${minds.length}):`);
|
|
56
73
|
for (const mind of minds) {
|
|
57
|
-
const status = mind.running ? "running" : "stopped";
|
|
74
|
+
const status = mind.status ?? (mind.running ? "running" : "stopped");
|
|
58
75
|
const label = mind.stage === "seed" ? " (seed)" : "";
|
|
59
76
|
console.log(` ${mind.name}: ${status}${label}`);
|
|
60
77
|
}
|
|
@@ -65,6 +82,33 @@ Minds (${minds.length}):`);
|
|
|
65
82
|
} catch {
|
|
66
83
|
}
|
|
67
84
|
}
|
|
85
|
+
async function getServiceInfo() {
|
|
86
|
+
const platform = process.platform;
|
|
87
|
+
if (platform === "darwin") {
|
|
88
|
+
const plistPath = existsSync(SYSTEM_LAUNCHD_PLIST_PATH) ? SYSTEM_LAUNCHD_PLIST_PATH : existsSync(LAUNCHD_PLIST_PATH) ? LAUNCHD_PLIST_PATH : null;
|
|
89
|
+
if (!plistPath) return null;
|
|
90
|
+
try {
|
|
91
|
+
const { stdout } = await execFileAsync("launchctl", ["list", LAUNCHD_PLIST_LABEL]);
|
|
92
|
+
return stdout.trim();
|
|
93
|
+
} catch {
|
|
94
|
+
return "Service installed but not currently loaded.";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (platform === "linux") {
|
|
98
|
+
const unitPath = existsSync(SYSTEM_SERVICE_PATH) ? "system" : existsSync(USER_SYSTEMD_UNIT) ? "user" : null;
|
|
99
|
+
if (!unitPath) return null;
|
|
100
|
+
const args = unitPath === "system" ? ["status", "volute", "--no-pager"] : ["--user", "status", "volute", "--no-pager"];
|
|
101
|
+
try {
|
|
102
|
+
const { stdout } = await execFileAsync("systemctl", args);
|
|
103
|
+
return stdout.trim();
|
|
104
|
+
} catch (err) {
|
|
105
|
+
const e = err;
|
|
106
|
+
if (e.stdout) return e.stdout.trim();
|
|
107
|
+
return "Service installed but status unknown.";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
68
112
|
export {
|
|
69
113
|
run
|
|
70
114
|
};
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
systemsFetch
|
|
4
|
-
} from "./chunk-RWKVSSLY.js";
|
|
5
2
|
import {
|
|
6
3
|
resolveMindName
|
|
7
4
|
} from "./chunk-NAOW2CLO.js";
|
|
8
5
|
import {
|
|
9
|
-
|
|
10
|
-
} from "./chunk-
|
|
6
|
+
daemonFetch
|
|
7
|
+
} from "./chunk-JGFVMROS.js";
|
|
11
8
|
import {
|
|
12
9
|
parseArgs
|
|
13
10
|
} from "./chunk-D424ZQGI.js";
|
|
@@ -20,15 +17,8 @@ async function run(args) {
|
|
|
20
17
|
mind: { type: "string" },
|
|
21
18
|
system: { type: "boolean" }
|
|
22
19
|
});
|
|
23
|
-
const config = readSystemsConfig();
|
|
24
|
-
if (!config) {
|
|
25
|
-
console.error('Not logged in. Run "volute auth register" or "volute auth login" first.');
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
20
|
const mindName = flags.mind || process.env.VOLUTE_MIND ? resolveMindName(flags) : "system";
|
|
29
|
-
const res = await
|
|
30
|
-
headers: { Authorization: `Bearer ${config.apiKey}` }
|
|
31
|
-
});
|
|
21
|
+
const res = await daemonFetch(`/api/system/pages/status/${mindName}`);
|
|
32
22
|
if (!res.ok) {
|
|
33
23
|
if (res.status === 404) {
|
|
34
24
|
console.log(`${mindName} has not been published yet.`);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
daemonFetch
|
|
4
|
+
} from "./chunk-JGFVMROS.js";
|
|
5
|
+
import "./chunk-H7OZRFJB.js";
|
|
6
|
+
import "./chunk-K3NQKI34.js";
|
|
7
|
+
|
|
8
|
+
// src/commands/systems.ts
|
|
9
|
+
async function run(args) {
|
|
10
|
+
const subcommand = args[0];
|
|
11
|
+
switch (subcommand) {
|
|
12
|
+
case "status":
|
|
13
|
+
await showStatus();
|
|
14
|
+
break;
|
|
15
|
+
case "register":
|
|
16
|
+
await import("./register-CHREOMJ3.js").then((m) => m.run(args.slice(1)));
|
|
17
|
+
break;
|
|
18
|
+
case "login":
|
|
19
|
+
await import("./login-BKP3AFWN.js").then((m) => m.run(args.slice(1)));
|
|
20
|
+
break;
|
|
21
|
+
case "logout":
|
|
22
|
+
await import("./logout-IQK7FNEK.js").then((m) => m.run());
|
|
23
|
+
break;
|
|
24
|
+
case "--help":
|
|
25
|
+
case "-h":
|
|
26
|
+
case void 0:
|
|
27
|
+
printUsage();
|
|
28
|
+
break;
|
|
29
|
+
default:
|
|
30
|
+
printUsage();
|
|
31
|
+
console.error(`
|
|
32
|
+
Unknown subcommand: ${subcommand}`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function showStatus() {
|
|
37
|
+
const res = await daemonFetch("/api/system/info");
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
40
|
+
console.error(`Failed to get system info: ${body.error}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
const { system } = await res.json();
|
|
44
|
+
if (!system) {
|
|
45
|
+
console.log("Not connected to volute.systems");
|
|
46
|
+
console.log('Run "volute systems register" or "volute systems login" to connect.');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.log(`System: ${system}`);
|
|
50
|
+
}
|
|
51
|
+
function printUsage() {
|
|
52
|
+
console.log(`Usage:
|
|
53
|
+
volute systems status Show volute.systems account info
|
|
54
|
+
volute systems register [--name <name>] Register a system on volute.systems
|
|
55
|
+
volute systems login [--key <key>] Log in with an existing API key
|
|
56
|
+
volute systems logout Remove stored credentials`);
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
run
|
|
60
|
+
};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
deliverMessage
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-PHSAT7YL.js";
|
|
8
|
-
import "./chunk-USUXRNVD.js";
|
|
9
|
-
import "./chunk-IAYBDWVG.js";
|
|
10
|
-
import "./chunk-VIVMW2H2.js";
|
|
11
|
-
import {
|
|
12
|
-
computeTemplateHash
|
|
13
|
-
} from "./chunk-AKPFNL7L.js";
|
|
4
|
+
} from "./chunk-CMILSHZD.js";
|
|
5
|
+
import "./chunk-THUUIU3E.js";
|
|
6
|
+
import "./chunk-FLZGS4QH.js";
|
|
14
7
|
import {
|
|
15
8
|
getCurrentVersion
|
|
16
9
|
} from "./chunk-HDN7MNGD.js";
|
|
10
|
+
import {
|
|
11
|
+
computeTemplateHash
|
|
12
|
+
} from "./chunk-AKPFNL7L.js";
|
|
13
|
+
import "./chunk-CQ7SNKNI.js";
|
|
14
|
+
import "./chunk-VIVMW2H2.js";
|
|
15
|
+
import "./chunk-EHZKEMMV.js";
|
|
16
|
+
import "./chunk-J4IBNXGJ.js";
|
|
17
17
|
import "./chunk-2WPW7OT6.js";
|
|
18
18
|
import {
|
|
19
19
|
logger_default
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
import "./chunk-AW7PFDVN.js";
|
|
22
22
|
import "./chunk-RKQEHRBB.js";
|
|
23
23
|
import "./chunk-IKRVFPWU.js";
|
|
24
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-A6TUJJ3L.js";
|
|
25
25
|
import {
|
|
26
26
|
readRegistry,
|
|
27
27
|
setMindTemplateHash,
|