@chvor/cli 0.1.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/bin/chvor.js +2 -0
- package/dist/cli.js +226 -0
- package/dist/commands/auth.js +50 -0
- package/dist/commands/docker.js +17 -0
- package/dist/commands/init.js +221 -0
- package/dist/commands/instances.js +126 -0
- package/dist/commands/onboard.js +84 -0
- package/dist/commands/skill.js +340 -0
- package/dist/commands/start.js +19 -0
- package/dist/commands/stop.js +4 -0
- package/dist/commands/update.js +23 -0
- package/dist/lib/config.js +26 -0
- package/dist/lib/download.js +145 -0
- package/dist/lib/paths.js +45 -0
- package/dist/lib/platform.js +28 -0
- package/dist/lib/process.js +220 -0
- package/dist/lib/registry-auth.js +130 -0
- package/dist/lib/template-loader.js +190 -0
- package/dist/lib/template-provisioner.js +120 -0
- package/dist/lib/validate.js +7 -0
- package/package.json +44 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { readdirSync, copyFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { getSkillsDir, getToolsDir, ensureDir } from "./paths.js";
|
|
4
|
+
import { getTemplateSkillsDir, getTemplateToolsDir } from "./template-loader.js";
|
|
5
|
+
function apiUrl(port, path) {
|
|
6
|
+
return `http://localhost:${port}${path}`;
|
|
7
|
+
}
|
|
8
|
+
function authHeaders(token) {
|
|
9
|
+
return {
|
|
10
|
+
"Content-Type": "application/json",
|
|
11
|
+
Authorization: `Bearer ${token}`,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async function applyPersona(ctx) {
|
|
15
|
+
if (!ctx.manifest.persona)
|
|
16
|
+
return;
|
|
17
|
+
const res = await fetch(apiUrl(ctx.port, "/api/persona"), {
|
|
18
|
+
method: "PATCH",
|
|
19
|
+
headers: authHeaders(ctx.token),
|
|
20
|
+
body: JSON.stringify(ctx.manifest.persona),
|
|
21
|
+
});
|
|
22
|
+
if (!res.ok) {
|
|
23
|
+
console.warn(`Warning: failed to apply persona (${res.status}).`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function createSchedules(ctx) {
|
|
27
|
+
if (!ctx.manifest.schedules?.length)
|
|
28
|
+
return;
|
|
29
|
+
// Get default workspace ID for schedule association
|
|
30
|
+
const wsRes = await fetch(apiUrl(ctx.port, "/api/workspaces"), {
|
|
31
|
+
headers: authHeaders(ctx.token),
|
|
32
|
+
});
|
|
33
|
+
let workspaceId = "default";
|
|
34
|
+
if (wsRes.ok) {
|
|
35
|
+
const workspaces = (await wsRes.json());
|
|
36
|
+
if (workspaces.length > 0) {
|
|
37
|
+
workspaceId = workspaces[0].id;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (const schedule of ctx.manifest.schedules) {
|
|
41
|
+
const res = await fetch(apiUrl(ctx.port, "/api/schedules"), {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: authHeaders(ctx.token),
|
|
44
|
+
body: JSON.stringify({
|
|
45
|
+
...schedule,
|
|
46
|
+
workspaceId,
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
if (!res.ok) {
|
|
50
|
+
console.warn(`Warning: failed to create schedule "${schedule.name}" (${res.status}).`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function createPipeline(ctx) {
|
|
55
|
+
if (!ctx.manifest.pipeline)
|
|
56
|
+
return;
|
|
57
|
+
const res = await fetch(apiUrl(ctx.port, "/api/workspaces"), {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: authHeaders(ctx.token),
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
name: `${ctx.manifest.name} Pipeline`,
|
|
62
|
+
mode: "pipeline",
|
|
63
|
+
nodes: ctx.manifest.pipeline.nodes,
|
|
64
|
+
edges: ctx.manifest.pipeline.edges,
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
if (!res.ok) {
|
|
68
|
+
console.warn(`Warning: failed to create pipeline (${res.status}).`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function copyTemplateFiles(ctx) {
|
|
72
|
+
const skillsSrc = getTemplateSkillsDir(ctx.templatePath);
|
|
73
|
+
if (skillsSrc) {
|
|
74
|
+
const destDir = getSkillsDir();
|
|
75
|
+
ensureDir(destDir);
|
|
76
|
+
const files = readdirSync(skillsSrc).filter((f) => f.endsWith(".md"));
|
|
77
|
+
for (const file of files) {
|
|
78
|
+
copyFileSync(join(skillsSrc, file), join(destDir, file));
|
|
79
|
+
}
|
|
80
|
+
if (files.length > 0) {
|
|
81
|
+
console.log(` Copied ${files.length} custom skill(s).`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const toolsSrc = getTemplateToolsDir(ctx.templatePath);
|
|
85
|
+
if (toolsSrc) {
|
|
86
|
+
const destDir = getToolsDir();
|
|
87
|
+
ensureDir(destDir);
|
|
88
|
+
const files = readdirSync(toolsSrc).filter((f) => f.endsWith(".md"));
|
|
89
|
+
for (const file of files) {
|
|
90
|
+
copyFileSync(join(toolsSrc, file), join(destDir, file));
|
|
91
|
+
}
|
|
92
|
+
if (files.length > 0) {
|
|
93
|
+
console.log(` Copied ${files.length} custom tool(s).`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export async function provision(ctx) {
|
|
98
|
+
console.log(`\n Provisioning "${ctx.manifest.name}" template...`);
|
|
99
|
+
// Copy template skill/tool files first (before server loads them)
|
|
100
|
+
copyTemplateFiles(ctx);
|
|
101
|
+
// Reload capabilities so server picks up new files
|
|
102
|
+
const skillsRes = await fetch(apiUrl(ctx.port, "/api/skills/reload"), {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: authHeaders(ctx.token),
|
|
105
|
+
});
|
|
106
|
+
if (!skillsRes.ok) {
|
|
107
|
+
console.warn(` Warning: failed to reload skills (${skillsRes.status}).`);
|
|
108
|
+
}
|
|
109
|
+
const toolsRes = await fetch(apiUrl(ctx.port, "/api/tools/reload"), {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: authHeaders(ctx.token),
|
|
112
|
+
});
|
|
113
|
+
if (!toolsRes.ok) {
|
|
114
|
+
console.warn(` Warning: failed to reload tools (${toolsRes.status}).`);
|
|
115
|
+
}
|
|
116
|
+
await applyPersona(ctx);
|
|
117
|
+
await createSchedules(ctx);
|
|
118
|
+
await createPipeline(ctx);
|
|
119
|
+
console.log(" Template provisioned successfully.");
|
|
120
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chvor/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Your own AI — install and run chvor.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"chvor": "./bin/chvor.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=22"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"prepublishOnly": "tsc",
|
|
20
|
+
"typecheck": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@chvor/shared": "workspace:*",
|
|
24
|
+
"commander": "^13",
|
|
25
|
+
"@inquirer/prompts": "^7",
|
|
26
|
+
"yaml": "^2"
|
|
27
|
+
},
|
|
28
|
+
"optionalDependencies": {
|
|
29
|
+
"better-sqlite3": "^11"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/luka-zivkovic/chvor.git",
|
|
34
|
+
"directory": "packages/cli"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/luka-zivkovic/chvor",
|
|
37
|
+
"keywords": [
|
|
38
|
+
"ai",
|
|
39
|
+
"assistant",
|
|
40
|
+
"personal-ai",
|
|
41
|
+
"mcp",
|
|
42
|
+
"chvor"
|
|
43
|
+
]
|
|
44
|
+
}
|