@verycloud/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/dist/commands/apps.d.ts +1 -0
- package/dist/commands/apps.js +71 -0
- package/dist/commands/deploy.d.ts +4 -0
- package/dist/commands/deploy.js +129 -0
- package/dist/commands/login.d.ts +4 -0
- package/dist/commands/login.js +168 -0
- package/dist/commands/logs.d.ts +1 -0
- package/dist/commands/logs.js +75 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +72 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +46 -0
- package/dist/lib/api.d.ts +8 -0
- package/dist/lib/api.js +74 -0
- package/dist/lib/app.d.ts +14 -0
- package/dist/lib/app.js +48 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.js +94 -0
- package/dist/lib/deploy.d.ts +5 -0
- package/dist/lib/deploy.js +24 -0
- package/dist/lib/detector.d.ts +10 -0
- package/dist/lib/detector.js +180 -0
- package/dist/lib/logger.d.ts +12 -0
- package/dist/lib/logger.js +74 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +275 -0
- package/package.json +40 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.startMCPServer = startMCPServer;
|
|
37
|
+
const readline = __importStar(require("node:readline"));
|
|
38
|
+
const config_js_1 = require("../lib/config.js");
|
|
39
|
+
const api_js_1 = require("../lib/api.js");
|
|
40
|
+
const detector_js_1 = require("../lib/detector.js");
|
|
41
|
+
const app_js_1 = require("../lib/app.js");
|
|
42
|
+
const deploy_js_1 = require("../lib/deploy.js");
|
|
43
|
+
const TOOLS = [
|
|
44
|
+
{
|
|
45
|
+
name: "verycloud_deploy",
|
|
46
|
+
description: "Deploy a project to VeryCloud. Analyzes the current directory, creates an app, provisions databases, and deploys. Returns the live URL.",
|
|
47
|
+
inputSchema: {
|
|
48
|
+
type: "object",
|
|
49
|
+
properties: {
|
|
50
|
+
name: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "App name (optional, defaults to directory name)",
|
|
53
|
+
},
|
|
54
|
+
git_url: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "Git repository URL (optional, auto-detected from git remote)",
|
|
57
|
+
},
|
|
58
|
+
framework: {
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "Framework (optional, auto-detected). One of: nextjs, nuxt, express, nestjs, go, django, fastapi, flask, rails, docker",
|
|
61
|
+
},
|
|
62
|
+
database: {
|
|
63
|
+
type: "string",
|
|
64
|
+
description: "Database type to provision (optional, auto-detected). One of: postgres, mysql, redis, mongodb",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "verycloud_status",
|
|
71
|
+
description: "Get the status of a VeryCloud app",
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {
|
|
75
|
+
name: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "App name (optional, defaults to current directory name)",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "verycloud_logs",
|
|
84
|
+
description: "Get deployment logs for a VeryCloud app",
|
|
85
|
+
inputSchema: {
|
|
86
|
+
type: "object",
|
|
87
|
+
properties: {
|
|
88
|
+
name: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "App name (optional, defaults to current directory name)",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "verycloud_apps",
|
|
97
|
+
description: "List all VeryCloud apps",
|
|
98
|
+
inputSchema: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: {},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
function send(msg) {
|
|
105
|
+
const json = JSON.stringify(msg);
|
|
106
|
+
process.stdout.write(json + "\n");
|
|
107
|
+
}
|
|
108
|
+
function sendResult(id, result) {
|
|
109
|
+
send({ jsonrpc: "2.0", id, result });
|
|
110
|
+
}
|
|
111
|
+
function sendError(id, code, message) {
|
|
112
|
+
send({ jsonrpc: "2.0", id, error: { code, message } });
|
|
113
|
+
}
|
|
114
|
+
async function handleToolCall(name, args) {
|
|
115
|
+
const config = (0, config_js_1.loadConfig)();
|
|
116
|
+
if (!config) {
|
|
117
|
+
throw new Error("Not logged in. Run 'vc login' first.");
|
|
118
|
+
}
|
|
119
|
+
switch (name) {
|
|
120
|
+
case "verycloud_deploy": {
|
|
121
|
+
const project = (0, detector_js_1.detectProject)();
|
|
122
|
+
const body = {
|
|
123
|
+
name: args.name || project.name,
|
|
124
|
+
git_url: args.git_url || project.gitURL,
|
|
125
|
+
git_branch: project.gitBranch,
|
|
126
|
+
framework: args.framework || project.framework,
|
|
127
|
+
};
|
|
128
|
+
if (!body.git_url) {
|
|
129
|
+
throw new Error("No git remote found. Initialize a git repo with a remote first.");
|
|
130
|
+
}
|
|
131
|
+
const dbType = args.database || project.database?.type;
|
|
132
|
+
if (dbType) {
|
|
133
|
+
body.database = { type: dbType };
|
|
134
|
+
}
|
|
135
|
+
const result = await (0, api_js_1.apiRequest)("/api/deploy/oneshot", {
|
|
136
|
+
method: "POST",
|
|
137
|
+
body,
|
|
138
|
+
});
|
|
139
|
+
// Poll for completion
|
|
140
|
+
const status = await (0, deploy_js_1.waitForDeployment)(result.app.id, result.deployment.id);
|
|
141
|
+
return {
|
|
142
|
+
content: [
|
|
143
|
+
{
|
|
144
|
+
type: "text",
|
|
145
|
+
text: status === "running"
|
|
146
|
+
? `Successfully deployed! App URL: ${result.url}\n` +
|
|
147
|
+
(result.service
|
|
148
|
+
? `Database: ${result.service.type} (${result.service.name})\n`
|
|
149
|
+
: "") +
|
|
150
|
+
(result.database_url ? `DATABASE_URL has been set automatically.` : "")
|
|
151
|
+
: `Deployment failed. Check logs with 'vc logs ${body.name}'.`,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
case "verycloud_status": {
|
|
157
|
+
const app = await (0, app_js_1.getAppByName)(args.name);
|
|
158
|
+
if (!app) {
|
|
159
|
+
return {
|
|
160
|
+
content: [{ type: "text", text: `App '${args.name || "current directory"}' not found.` }],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: "text",
|
|
167
|
+
text: `App: ${app.name}\nStatus: ${app.status}\nFramework: ${app.framework}\nDomain: ${app.domain}\nGit: ${app.git_url || "(none)"}\nBranch: ${app.git_branch}`,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
case "verycloud_logs": {
|
|
173
|
+
const app = await (0, app_js_1.getAppByName)(args.name);
|
|
174
|
+
if (!app) {
|
|
175
|
+
return {
|
|
176
|
+
content: [{ type: "text", text: `App '${args.name || "current directory"}' not found.` }],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const deployments = await (0, api_js_1.apiRequest)(`/api/apps/${app.id}/deployments`);
|
|
180
|
+
if (!deployments || deployments.length === 0) {
|
|
181
|
+
return {
|
|
182
|
+
content: [{ type: "text", text: "No deployments found." }],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const latest = deployments[0];
|
|
186
|
+
const logData = await (0, api_js_1.apiRequest)(`/api/apps/${app.id}/deployments/${latest.id}/log`);
|
|
187
|
+
return {
|
|
188
|
+
content: [
|
|
189
|
+
{
|
|
190
|
+
type: "text",
|
|
191
|
+
text: `Deployment v${latest.version} (${latest.status}):\n\n${logData.log || "No logs available yet."}`,
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
case "verycloud_apps": {
|
|
197
|
+
const apps = await (0, api_js_1.apiRequest)("/api/apps");
|
|
198
|
+
if (!apps || apps.length === 0) {
|
|
199
|
+
return {
|
|
200
|
+
content: [{ type: "text", text: "No apps found." }],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const lines = apps.map((a) => `${a.name} | ${a.status} | ${a.framework} | ${a.domain}`);
|
|
204
|
+
return {
|
|
205
|
+
content: [
|
|
206
|
+
{
|
|
207
|
+
type: "text",
|
|
208
|
+
text: `NAME | STATUS | FRAMEWORK | DOMAIN\n${"-".repeat(60)}\n${lines.join("\n")}`,
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
default:
|
|
214
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async function handleMessage(msg) {
|
|
218
|
+
try {
|
|
219
|
+
switch (msg.method) {
|
|
220
|
+
case "initialize":
|
|
221
|
+
sendResult(msg.id, {
|
|
222
|
+
protocolVersion: "2024-11-05",
|
|
223
|
+
capabilities: {
|
|
224
|
+
tools: {},
|
|
225
|
+
},
|
|
226
|
+
serverInfo: {
|
|
227
|
+
name: "verycloud",
|
|
228
|
+
version: "0.1.0",
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
break;
|
|
232
|
+
case "notifications/initialized":
|
|
233
|
+
// Client acknowledged initialization — no response needed
|
|
234
|
+
break;
|
|
235
|
+
case "tools/list":
|
|
236
|
+
sendResult(msg.id, { tools: TOOLS });
|
|
237
|
+
break;
|
|
238
|
+
case "tools/call": {
|
|
239
|
+
const params = msg.params;
|
|
240
|
+
const result = await handleToolCall(params.name, params.arguments || {});
|
|
241
|
+
sendResult(msg.id, result);
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
default:
|
|
245
|
+
sendError(msg.id, -32601, `Method not found: ${msg.method}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
// Sanitize error message to avoid leaking sensitive info
|
|
250
|
+
let errMsg = err.message || "Unknown error";
|
|
251
|
+
errMsg = errMsg.replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]");
|
|
252
|
+
errMsg = errMsg.replace(/X-API-Key:\s*\S+/gi, "X-API-Key: [REDACTED]");
|
|
253
|
+
errMsg = errMsg.replace(/\/Users\/[^\s]+/g, "[PATH]");
|
|
254
|
+
errMsg = errMsg.replace(/\/home\/[^\s]+/g, "[PATH]");
|
|
255
|
+
sendError(msg.id, -32000, errMsg);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function startMCPServer() {
|
|
259
|
+
const rl = readline.createInterface({
|
|
260
|
+
input: process.stdin,
|
|
261
|
+
terminal: false,
|
|
262
|
+
});
|
|
263
|
+
rl.on("line", async (line) => {
|
|
264
|
+
try {
|
|
265
|
+
const msg = JSON.parse(line);
|
|
266
|
+
await handleMessage(msg);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// Ignore unparseable lines
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
rl.on("close", () => {
|
|
273
|
+
process.exit(0);
|
|
274
|
+
});
|
|
275
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@verycloud/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "VeryCloud CLI - Deploy apps with one command",
|
|
5
|
+
"author": "VeryWorks",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/veryworks/verycloud"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://verycloud.io",
|
|
12
|
+
"bin": {
|
|
13
|
+
"vc": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"start": "node dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18.0.0"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"verycloud",
|
|
28
|
+
"paas",
|
|
29
|
+
"deploy",
|
|
30
|
+
"cli",
|
|
31
|
+
"cloud"
|
|
32
|
+
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"commander": "^12.1.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.0.0",
|
|
38
|
+
"typescript": "^5.7.0"
|
|
39
|
+
}
|
|
40
|
+
}
|