volute 0.14.1 → 0.16.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 +30 -0
- package/dist/chunk-37X7ECMF.js +50 -0
- package/dist/{chunk-PDLAZJGC.js → chunk-3FD4ZZUL.js} +1 -0
- package/dist/chunk-RVKR2R7F.js +37 -0
- package/dist/chunk-RWKVSSLY.js +26 -0
- package/dist/cli.js +26 -7
- package/dist/{connector-JFAHYFQX.js → connector-3ELFMI2R.js} +5 -32
- package/dist/{daemon-restart-IZGEF4NA.js → daemon-restart-MS5FI44G.js} +1 -1
- package/dist/daemon.js +190 -16
- package/dist/{env-6LXDUZDA.js → env-6IDWGBUH.js} +4 -31
- package/dist/login-ORQDXLBM.js +56 -0
- package/dist/logout-XC5AUO5I.js +18 -0
- package/dist/{package-I7Z6G44Y.js → package-3QGV3KX6.js} +1 -1
- package/dist/pages-6IV4VQTU.js +36 -0
- package/dist/publish-Q4RPSJLL.js +80 -0
- package/dist/register-LDE6LRXY.js +65 -0
- package/dist/{send-SV4K2TDE.js → send-KBBZNYG6.js} +1 -1
- package/dist/status-OKNA6AR3.js +47 -0
- package/dist/{up-C4MV6EXV.js → up-GZLWZAQE.js} +1 -1
- package/dist/web-assets/assets/{index-CeFLp8DZ.js → index-B1XIIGCh.js} +8 -8
- package/dist/web-assets/index.html +1 -1
- package/package.json +1 -1
- package/templates/_base/_skills/volute-mind/SKILL.md +28 -1
- package/templates/claude/src/agent.ts +4 -1
- package/templates/claude/src/lib/hooks/reply-instructions.ts +28 -0
- package/templates/pi/src/agent.ts +8 -1
- package/templates/pi/src/lib/reply-instructions-extension.ts +30 -0
- /package/dist/{chunk-BEFIBW5B.js → chunk-LLBBVTEY.js} +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
systemsFetch
|
|
4
|
+
} from "./chunk-RWKVSSLY.js";
|
|
5
|
+
import {
|
|
6
|
+
promptLine
|
|
7
|
+
} from "./chunk-RVKR2R7F.js";
|
|
8
|
+
import {
|
|
9
|
+
readSystemsConfig,
|
|
10
|
+
writeSystemsConfig
|
|
11
|
+
} from "./chunk-37X7ECMF.js";
|
|
12
|
+
import {
|
|
13
|
+
parseArgs
|
|
14
|
+
} from "./chunk-D424ZQGI.js";
|
|
15
|
+
import "./chunk-M77QBTEH.js";
|
|
16
|
+
import "./chunk-K3NQKI34.js";
|
|
17
|
+
|
|
18
|
+
// src/commands/pages/login.ts
|
|
19
|
+
var DEFAULT_API_URL = "https://volute.systems";
|
|
20
|
+
async function run(args) {
|
|
21
|
+
const { flags } = parseArgs(args, {
|
|
22
|
+
key: { type: "string" }
|
|
23
|
+
});
|
|
24
|
+
const existing = readSystemsConfig();
|
|
25
|
+
if (existing) {
|
|
26
|
+
console.error(`Already logged in as "${existing.system}". Run "volute logout" first.`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
let key = flags.key;
|
|
30
|
+
if (!key) {
|
|
31
|
+
if (!process.stdin.isTTY) {
|
|
32
|
+
console.error("Usage: volute pages login --key <api-key>");
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
key = await promptLine("API key: ");
|
|
36
|
+
if (!key) {
|
|
37
|
+
console.error("No key provided.");
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const apiUrl = process.env.VOLUTE_SYSTEMS_URL || DEFAULT_API_URL;
|
|
42
|
+
const res = await systemsFetch(`${apiUrl}/api/whoami`, {
|
|
43
|
+
headers: { Authorization: `Bearer ${key}` }
|
|
44
|
+
});
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
47
|
+
console.error(`Login failed: ${body.error}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const { system } = await res.json();
|
|
51
|
+
writeSystemsConfig({ apiKey: key, system, apiUrl });
|
|
52
|
+
console.log(`Logged in as "${system}". Credentials saved.`);
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
run
|
|
56
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
deleteSystemsConfig
|
|
4
|
+
} from "./chunk-37X7ECMF.js";
|
|
5
|
+
import "./chunk-M77QBTEH.js";
|
|
6
|
+
import "./chunk-K3NQKI34.js";
|
|
7
|
+
|
|
8
|
+
// src/commands/pages/logout.ts
|
|
9
|
+
async function run() {
|
|
10
|
+
if (deleteSystemsConfig()) {
|
|
11
|
+
console.log("Logged out. Credentials removed.");
|
|
12
|
+
} else {
|
|
13
|
+
console.log("Not logged in.");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
run
|
|
18
|
+
};
|
|
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "volute",
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.16.0",
|
|
8
8
|
description: "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
|
|
9
9
|
type: "module",
|
|
10
10
|
license: "MIT",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "./chunk-K3NQKI34.js";
|
|
3
|
+
|
|
4
|
+
// src/commands/pages.ts
|
|
5
|
+
async function run(args) {
|
|
6
|
+
const subcommand = args[0];
|
|
7
|
+
switch (subcommand) {
|
|
8
|
+
case "publish":
|
|
9
|
+
await import("./publish-Q4RPSJLL.js").then((m) => m.run(args.slice(1)));
|
|
10
|
+
break;
|
|
11
|
+
case "status":
|
|
12
|
+
await import("./status-OKNA6AR3.js").then((m) => m.run(args.slice(1)));
|
|
13
|
+
break;
|
|
14
|
+
case "--help":
|
|
15
|
+
case "-h":
|
|
16
|
+
case void 0:
|
|
17
|
+
printUsage();
|
|
18
|
+
break;
|
|
19
|
+
default:
|
|
20
|
+
printUsage();
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function printUsage() {
|
|
25
|
+
console.log(`Usage:
|
|
26
|
+
volute pages publish [--mind <name>] Publish mind's pages/ directory
|
|
27
|
+
volute pages status [--mind <name>] Show publish status
|
|
28
|
+
|
|
29
|
+
Account commands (register, login, logout) are now top-level:
|
|
30
|
+
volute register [--name <name>]
|
|
31
|
+
volute login [--key <key>]
|
|
32
|
+
volute logout`);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
run
|
|
36
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
systemsFetch
|
|
4
|
+
} from "./chunk-RWKVSSLY.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveMindName
|
|
7
|
+
} from "./chunk-NAOW2CLO.js";
|
|
8
|
+
import {
|
|
9
|
+
readSystemsConfig
|
|
10
|
+
} from "./chunk-37X7ECMF.js";
|
|
11
|
+
import {
|
|
12
|
+
parseArgs
|
|
13
|
+
} from "./chunk-D424ZQGI.js";
|
|
14
|
+
import {
|
|
15
|
+
mindDir
|
|
16
|
+
} from "./chunk-M77QBTEH.js";
|
|
17
|
+
import "./chunk-K3NQKI34.js";
|
|
18
|
+
|
|
19
|
+
// src/commands/pages/publish.ts
|
|
20
|
+
import { existsSync, lstatSync, readdirSync, readFileSync } from "fs";
|
|
21
|
+
import { relative, resolve } from "path";
|
|
22
|
+
async function run(args) {
|
|
23
|
+
const { flags } = parseArgs(args, {
|
|
24
|
+
mind: { type: "string" }
|
|
25
|
+
});
|
|
26
|
+
const config = readSystemsConfig();
|
|
27
|
+
if (!config) {
|
|
28
|
+
console.error('Not logged in. Run "volute pages register" or "volute pages login" first.');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const mindName = resolveMindName(flags);
|
|
32
|
+
const pagesDir = resolve(mindDir(mindName), "home", "pages");
|
|
33
|
+
if (!existsSync(pagesDir)) {
|
|
34
|
+
console.error(`No pages/ directory found at ${pagesDir}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const files = collectFiles(pagesDir);
|
|
38
|
+
if (Object.keys(files).length === 0) {
|
|
39
|
+
console.error("pages/ directory is empty.");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
console.log(`Publishing ${Object.keys(files).length} file(s) for ${mindName}...`);
|
|
43
|
+
const res = await systemsFetch(`${config.apiUrl}/api/pages/publish/${mindName}`, {
|
|
44
|
+
method: "PUT",
|
|
45
|
+
headers: {
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({ files })
|
|
50
|
+
});
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
53
|
+
console.error(`Publish failed: ${body.error}`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const { url, fileCount } = await res.json();
|
|
57
|
+
console.log(`Published ${fileCount} file(s) to ${url}`);
|
|
58
|
+
}
|
|
59
|
+
function collectFiles(dir) {
|
|
60
|
+
const files = {};
|
|
61
|
+
function walk(current) {
|
|
62
|
+
for (const entry of readdirSync(current)) {
|
|
63
|
+
const full = resolve(current, entry);
|
|
64
|
+
const stat = lstatSync(full);
|
|
65
|
+
if (stat.isSymbolicLink()) continue;
|
|
66
|
+
if (stat.isDirectory()) {
|
|
67
|
+
walk(full);
|
|
68
|
+
} else if (stat.isFile()) {
|
|
69
|
+
const rel = relative(dir, full);
|
|
70
|
+
files[rel] = readFileSync(full).toString("base64");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
walk(dir);
|
|
75
|
+
return files;
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
collectFiles,
|
|
79
|
+
run
|
|
80
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
systemsFetch
|
|
4
|
+
} from "./chunk-RWKVSSLY.js";
|
|
5
|
+
import {
|
|
6
|
+
promptLine
|
|
7
|
+
} from "./chunk-RVKR2R7F.js";
|
|
8
|
+
import {
|
|
9
|
+
readSystemsConfig,
|
|
10
|
+
writeSystemsConfig
|
|
11
|
+
} from "./chunk-37X7ECMF.js";
|
|
12
|
+
import {
|
|
13
|
+
parseArgs
|
|
14
|
+
} from "./chunk-D424ZQGI.js";
|
|
15
|
+
import "./chunk-M77QBTEH.js";
|
|
16
|
+
import "./chunk-K3NQKI34.js";
|
|
17
|
+
|
|
18
|
+
// src/commands/pages/register.ts
|
|
19
|
+
var DEFAULT_API_URL = "https://volute.systems";
|
|
20
|
+
async function run(args) {
|
|
21
|
+
const { flags } = parseArgs(args, {
|
|
22
|
+
name: { type: "string" }
|
|
23
|
+
});
|
|
24
|
+
const existing = readSystemsConfig();
|
|
25
|
+
if (existing) {
|
|
26
|
+
console.error(`Already registered as "${existing.system}". Run "volute logout" first.`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
let name = flags.name;
|
|
30
|
+
if (!name) {
|
|
31
|
+
if (!process.stdin.isTTY) {
|
|
32
|
+
console.error("Usage: volute pages register --name <system-name>");
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
name = await promptLine("Choose a system name: ");
|
|
36
|
+
if (!name) {
|
|
37
|
+
console.error("No name provided.");
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const apiUrl = process.env.VOLUTE_SYSTEMS_URL || DEFAULT_API_URL;
|
|
42
|
+
const res = await systemsFetch(`${apiUrl}/api/register`, {
|
|
43
|
+
method: "POST",
|
|
44
|
+
headers: { "Content-Type": "application/json" },
|
|
45
|
+
body: JSON.stringify({ name })
|
|
46
|
+
});
|
|
47
|
+
if (!res.ok) {
|
|
48
|
+
const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
49
|
+
console.error(`Registration failed: ${body.error}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const { apiKey, system } = await res.json();
|
|
53
|
+
try {
|
|
54
|
+
writeSystemsConfig({ apiKey, system, apiUrl });
|
|
55
|
+
} catch (err) {
|
|
56
|
+
console.error(`Failed to save credentials: ${err.message}`);
|
|
57
|
+
console.error(`Your API key is: ${apiKey}`);
|
|
58
|
+
console.error(`Save it and run: volute pages login --key ${apiKey}`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
console.log(`Registered as "${system}". Credentials saved.`);
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
run
|
|
65
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
systemsFetch
|
|
4
|
+
} from "./chunk-RWKVSSLY.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveMindName
|
|
7
|
+
} from "./chunk-NAOW2CLO.js";
|
|
8
|
+
import {
|
|
9
|
+
readSystemsConfig
|
|
10
|
+
} from "./chunk-37X7ECMF.js";
|
|
11
|
+
import {
|
|
12
|
+
parseArgs
|
|
13
|
+
} from "./chunk-D424ZQGI.js";
|
|
14
|
+
import "./chunk-M77QBTEH.js";
|
|
15
|
+
import "./chunk-K3NQKI34.js";
|
|
16
|
+
|
|
17
|
+
// src/commands/pages/status.ts
|
|
18
|
+
async function run(args) {
|
|
19
|
+
const { flags } = parseArgs(args, {
|
|
20
|
+
mind: { type: "string" }
|
|
21
|
+
});
|
|
22
|
+
const config = readSystemsConfig();
|
|
23
|
+
if (!config) {
|
|
24
|
+
console.error('Not logged in. Run "volute pages register" or "volute pages login" first.');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const mindName = resolveMindName(flags);
|
|
28
|
+
const res = await systemsFetch(`${config.apiUrl}/api/pages/status/${mindName}`, {
|
|
29
|
+
headers: { Authorization: `Bearer ${config.apiKey}` }
|
|
30
|
+
});
|
|
31
|
+
if (!res.ok) {
|
|
32
|
+
if (res.status === 404) {
|
|
33
|
+
console.log(`${mindName} has not been published yet.`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
37
|
+
console.error(`Failed to get status: ${body.error}`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const { url, fileCount, deployedAt } = await res.json();
|
|
41
|
+
console.log(`URL: ${url}`);
|
|
42
|
+
console.log(`Files: ${fileCount}`);
|
|
43
|
+
console.log(`Published: ${deployedAt}`);
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
run
|
|
47
|
+
};
|