@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.
@@ -0,0 +1,14 @@
1
+ interface App {
2
+ id: string;
3
+ name: string;
4
+ status: string;
5
+ framework: string;
6
+ domain: string;
7
+ git_url: string;
8
+ git_branch: string;
9
+ }
10
+ /**
11
+ * Resolve an app name (defaults to current directory name) and find the matching app.
12
+ */
13
+ export declare function getAppByName(appName?: string): Promise<App | null>;
14
+ export {};
@@ -0,0 +1,48 @@
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.getAppByName = getAppByName;
37
+ const path = __importStar(require("node:path"));
38
+ const api_js_1 = require("./api.js");
39
+ /**
40
+ * Resolve an app name (defaults to current directory name) and find the matching app.
41
+ */
42
+ async function getAppByName(appName) {
43
+ if (!appName) {
44
+ appName = path.basename(process.cwd()).toLowerCase().replace(/_/g, "-");
45
+ }
46
+ const apps = await (0, api_js_1.apiRequest)("/api/apps");
47
+ return apps.find((a) => a.name === appName) || null;
48
+ }
@@ -0,0 +1,13 @@
1
+ export declare const DEFAULT_SERVER_URL = "https://verycloud.io";
2
+ export interface VCConfig {
3
+ server_url: string;
4
+ api_key: string;
5
+ user_email: string;
6
+ }
7
+ export declare function loadConfig(): VCConfig | null;
8
+ export declare function saveConfig(config: VCConfig): void;
9
+ /**
10
+ * Register VeryCloud MCP server in ~/.claude.json.
11
+ * Creates the file if it doesn't exist, merges if it does.
12
+ */
13
+ export declare function registerMCP(): boolean;
@@ -0,0 +1,94 @@
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.DEFAULT_SERVER_URL = void 0;
37
+ exports.loadConfig = loadConfig;
38
+ exports.saveConfig = saveConfig;
39
+ exports.registerMCP = registerMCP;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const os = __importStar(require("node:os"));
43
+ exports.DEFAULT_SERVER_URL = "https://verycloud.io";
44
+ const CONFIG_DIR = path.join(os.homedir(), ".verycloud");
45
+ const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
46
+ const CLAUDE_CONFIG = path.join(os.homedir(), ".claude.json");
47
+ function loadConfig() {
48
+ try {
49
+ const data = fs.readFileSync(CONFIG_FILE, "utf-8");
50
+ return JSON.parse(data);
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ function saveConfig(config) {
57
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
58
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", {
59
+ mode: 0o600,
60
+ });
61
+ }
62
+ /**
63
+ * Register VeryCloud MCP server in ~/.claude.json.
64
+ * Creates the file if it doesn't exist, merges if it does.
65
+ */
66
+ function registerMCP() {
67
+ const mcpEntry = {
68
+ command: "vc",
69
+ args: ["mcp"],
70
+ };
71
+ try {
72
+ let config = {};
73
+ if (fs.existsSync(CLAUDE_CONFIG)) {
74
+ const data = fs.readFileSync(CLAUDE_CONFIG, "utf-8");
75
+ config = JSON.parse(data);
76
+ }
77
+ // Ensure mcpServers object exists
78
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
79
+ config.mcpServers = {};
80
+ }
81
+ const servers = config.mcpServers;
82
+ // Skip if already registered
83
+ if (servers.verycloud) {
84
+ return false;
85
+ }
86
+ servers.verycloud = mcpEntry;
87
+ config.mcpServers = servers;
88
+ fs.writeFileSync(CLAUDE_CONFIG, JSON.stringify(config, null, 2) + "\n", { mode: 0o600 });
89
+ return true;
90
+ }
91
+ catch {
92
+ return false;
93
+ }
94
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Poll deployment status until it reaches "running" or "failed".
3
+ * Returns the final status string.
4
+ */
5
+ export declare function waitForDeployment(appId: string, depId: string, maxAttempts?: number, intervalMs?: number): Promise<string>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.waitForDeployment = waitForDeployment;
4
+ const api_js_1 = require("./api.js");
5
+ /**
6
+ * Poll deployment status until it reaches "running" or "failed".
7
+ * Returns the final status string.
8
+ */
9
+ async function waitForDeployment(appId, depId, maxAttempts = 60, intervalMs = 2000) {
10
+ let status = "pending";
11
+ let attempts = 0;
12
+ while (status !== "running" && status !== "failed" && attempts < maxAttempts) {
13
+ await new Promise((r) => setTimeout(r, intervalMs));
14
+ try {
15
+ const dep = await (0, api_js_1.apiRequest)(`/api/apps/${appId}/deployments/${depId}`);
16
+ status = dep.status;
17
+ }
18
+ catch {
19
+ // Retry on error
20
+ }
21
+ attempts++;
22
+ }
23
+ return status;
24
+ }
@@ -0,0 +1,10 @@
1
+ export interface ProjectInfo {
2
+ name: string;
3
+ gitURL: string;
4
+ gitBranch: string;
5
+ framework: string;
6
+ database: {
7
+ type: string;
8
+ } | null;
9
+ }
10
+ export declare function detectProject(dir?: string): ProjectInfo;
@@ -0,0 +1,180 @@
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.detectProject = detectProject;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const node_child_process_1 = require("node:child_process");
40
+ function detectProject(dir = process.cwd()) {
41
+ const name = path.basename(dir).toLowerCase().replace(/_/g, "-");
42
+ const gitURL = getGitRemote(dir);
43
+ const gitBranch = getGitBranch(dir);
44
+ const framework = detectFramework(dir);
45
+ const database = detectDatabase(dir);
46
+ return { name, gitURL, gitBranch, framework, database };
47
+ }
48
+ function getGitRemote(dir) {
49
+ try {
50
+ const result = (0, node_child_process_1.spawnSync)("git", ["remote", "get-url", "origin"], { cwd: dir, encoding: "utf-8" });
51
+ return result.status === 0 ? result.stdout.trim() : "";
52
+ }
53
+ catch {
54
+ return "";
55
+ }
56
+ }
57
+ function getGitBranch(dir) {
58
+ try {
59
+ const result = (0, node_child_process_1.spawnSync)("git", ["branch", "--show-current"], { cwd: dir, encoding: "utf-8" });
60
+ return result.status === 0 && result.stdout.trim() ? result.stdout.trim() : "main";
61
+ }
62
+ catch {
63
+ return "main";
64
+ }
65
+ }
66
+ function detectFramework(dir) {
67
+ // Check package.json
68
+ const pkgPath = path.join(dir, "package.json");
69
+ if (fs.existsSync(pkgPath)) {
70
+ try {
71
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
72
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
73
+ if (allDeps["next"])
74
+ return "nextjs";
75
+ if (allDeps["nuxt"])
76
+ return "nuxt";
77
+ if (allDeps["@nestjs/core"])
78
+ return "nestjs";
79
+ if (allDeps["express"])
80
+ return "express";
81
+ }
82
+ catch {
83
+ // ignore
84
+ }
85
+ }
86
+ // Go
87
+ if (fs.existsSync(path.join(dir, "go.mod")))
88
+ return "go";
89
+ // Python
90
+ const reqPath = path.join(dir, "requirements.txt");
91
+ if (fs.existsSync(reqPath)) {
92
+ try {
93
+ const content = fs.readFileSync(reqPath, "utf-8").toLowerCase();
94
+ if (content.includes("django"))
95
+ return "django";
96
+ if (content.includes("fastapi"))
97
+ return "fastapi";
98
+ if (content.includes("flask"))
99
+ return "flask";
100
+ }
101
+ catch {
102
+ // ignore
103
+ }
104
+ }
105
+ // Ruby
106
+ if (fs.existsSync(path.join(dir, "Gemfile"))) {
107
+ try {
108
+ const content = fs.readFileSync(path.join(dir, "Gemfile"), "utf-8");
109
+ if (content.includes("rails"))
110
+ return "rails";
111
+ if (content.includes("sinatra"))
112
+ return "sinatra";
113
+ }
114
+ catch {
115
+ // ignore
116
+ }
117
+ }
118
+ // Dockerfile
119
+ if (fs.existsSync(path.join(dir, "Dockerfile")))
120
+ return "docker";
121
+ return "docker";
122
+ }
123
+ function detectDatabase(dir) {
124
+ // Check package.json deps
125
+ const pkgPath = path.join(dir, "package.json");
126
+ if (fs.existsSync(pkgPath)) {
127
+ try {
128
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
129
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
130
+ if (allDeps["prisma"] || allDeps["@prisma/client"])
131
+ return { type: "postgres" };
132
+ if (allDeps["pg"] || allDeps["pgx"])
133
+ return { type: "postgres" };
134
+ if (allDeps["mysql2"] || allDeps["mysql"])
135
+ return { type: "mysql" };
136
+ if (allDeps["mongoose"] || allDeps["mongodb"])
137
+ return { type: "mongodb" };
138
+ if (allDeps["redis"] || allDeps["ioredis"])
139
+ return { type: "redis" };
140
+ }
141
+ catch {
142
+ // ignore
143
+ }
144
+ }
145
+ // Check requirements.txt
146
+ const reqPath = path.join(dir, "requirements.txt");
147
+ if (fs.existsSync(reqPath)) {
148
+ try {
149
+ const content = fs.readFileSync(reqPath, "utf-8").toLowerCase();
150
+ if (content.includes("psycopg") || content.includes("sqlalchemy"))
151
+ return { type: "postgres" };
152
+ if (content.includes("pymysql") || content.includes("mysqlclient"))
153
+ return { type: "mysql" };
154
+ if (content.includes("pymongo"))
155
+ return { type: "mongodb" };
156
+ if (content.includes("redis"))
157
+ return { type: "redis" };
158
+ }
159
+ catch {
160
+ // ignore
161
+ }
162
+ }
163
+ // Check Prisma schema
164
+ const prismaPath = path.join(dir, "prisma", "schema.prisma");
165
+ if (fs.existsSync(prismaPath)) {
166
+ try {
167
+ const content = fs.readFileSync(prismaPath, "utf-8").toLowerCase();
168
+ if (content.includes("postgresql"))
169
+ return { type: "postgres" };
170
+ if (content.includes("mysql"))
171
+ return { type: "mysql" };
172
+ if (content.includes("mongodb"))
173
+ return { type: "mongodb" };
174
+ }
175
+ catch {
176
+ // ignore
177
+ }
178
+ }
179
+ return null;
180
+ }
@@ -0,0 +1,12 @@
1
+ export declare function success(msg: string): void;
2
+ export declare function error(msg: string): void;
3
+ export declare function info(msg: string): void;
4
+ export declare function dim(msg: string): void;
5
+ export declare function bold(msg: string): string;
6
+ export declare function cyan(msg: string): string;
7
+ export declare function green(msg: string): string;
8
+ export declare function yellow(msg: string): string;
9
+ export declare function box(lines: Record<string, string>): void;
10
+ export declare function spinner(msg: string): {
11
+ stop: (finalMsg?: string) => void;
12
+ };
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.success = success;
4
+ exports.error = error;
5
+ exports.info = info;
6
+ exports.dim = dim;
7
+ exports.bold = bold;
8
+ exports.cyan = cyan;
9
+ exports.green = green;
10
+ exports.yellow = yellow;
11
+ exports.box = box;
12
+ exports.spinner = spinner;
13
+ const RESET = "\x1b[0m";
14
+ const BOLD = "\x1b[1m";
15
+ const DIM = "\x1b[2m";
16
+ const RED = "\x1b[31m";
17
+ const GREEN = "\x1b[32m";
18
+ const YELLOW = "\x1b[33m";
19
+ const BLUE = "\x1b[34m";
20
+ const CYAN = "\x1b[36m";
21
+ function success(msg) {
22
+ console.log(`${GREEN}✓${RESET} ${msg}`);
23
+ }
24
+ function error(msg) {
25
+ console.error(`${RED}✗${RESET} ${msg}`);
26
+ }
27
+ function info(msg) {
28
+ console.log(`${BLUE}ℹ${RESET} ${msg}`);
29
+ }
30
+ function dim(msg) {
31
+ console.log(`${DIM}${msg}${RESET}`);
32
+ }
33
+ function bold(msg) {
34
+ return `${BOLD}${msg}${RESET}`;
35
+ }
36
+ function cyan(msg) {
37
+ return `${CYAN}${msg}${RESET}`;
38
+ }
39
+ function green(msg) {
40
+ return `${GREEN}${msg}${RESET}`;
41
+ }
42
+ function yellow(msg) {
43
+ return `${YELLOW}${msg}${RESET}`;
44
+ }
45
+ function box(lines) {
46
+ const entries = Object.entries(lines);
47
+ const maxKey = Math.max(...entries.map(([k]) => k.length));
48
+ const maxVal = Math.max(...entries.map(([, v]) => v.length));
49
+ const width = maxKey + maxVal + 5;
50
+ console.log(`┌${"─".repeat(width)}┐`);
51
+ for (const [key, val] of entries) {
52
+ const paddedKey = key.padEnd(maxKey);
53
+ const paddedVal = val.padEnd(maxVal);
54
+ console.log(`│ ${BOLD}${paddedKey}${RESET} ${paddedVal} │`);
55
+ }
56
+ console.log(`└${"─".repeat(width)}┘`);
57
+ }
58
+ function spinner(msg) {
59
+ const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
60
+ let i = 0;
61
+ const id = setInterval(() => {
62
+ process.stdout.write(`\r${CYAN}${frames[i]}${RESET} ${msg}`);
63
+ i = (i + 1) % frames.length;
64
+ }, 80);
65
+ return {
66
+ stop(finalMsg) {
67
+ clearInterval(id);
68
+ process.stdout.write("\r" + " ".repeat(msg.length + 4) + "\r");
69
+ if (finalMsg) {
70
+ success(finalMsg);
71
+ }
72
+ },
73
+ };
74
+ }
@@ -0,0 +1 @@
1
+ export declare function startMCPServer(): void;