@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 @@
|
|
|
1
|
+
export declare function appsCommand(): Promise<void>;
|
|
@@ -0,0 +1,71 @@
|
|
|
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.appsCommand = appsCommand;
|
|
37
|
+
const config_js_1 = require("../lib/config.js");
|
|
38
|
+
const api_js_1 = require("../lib/api.js");
|
|
39
|
+
const logger = __importStar(require("../lib/logger.js"));
|
|
40
|
+
async function appsCommand() {
|
|
41
|
+
const config = (0, config_js_1.loadConfig)();
|
|
42
|
+
if (!config) {
|
|
43
|
+
logger.error("Not logged in. Run 'vc login' first.");
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const apps = await (0, api_js_1.apiRequest)("/api/apps");
|
|
48
|
+
if (!apps || apps.length === 0) {
|
|
49
|
+
logger.info("No apps found. Deploy one with 'vc deploy'");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
console.log();
|
|
53
|
+
console.log(` ${logger.bold("NAME".padEnd(25))} ${logger.bold("STATUS".padEnd(12))} ${logger.bold("FRAMEWORK".padEnd(12))} ${logger.bold("DOMAIN")}`);
|
|
54
|
+
console.log(` ${"─".repeat(75)}`);
|
|
55
|
+
for (const app of apps) {
|
|
56
|
+
const statusDisplay = app.status === "running"
|
|
57
|
+
? logger.green(app.status)
|
|
58
|
+
: app.status === "building"
|
|
59
|
+
? logger.yellow(app.status)
|
|
60
|
+
: app.status;
|
|
61
|
+
console.log(` ${app.name.padEnd(25)} ${statusDisplay.padEnd(
|
|
62
|
+
// Account for ANSI escape codes in padding
|
|
63
|
+
12 + (statusDisplay.length - app.status.length))} ${app.framework.padEnd(12)} ${app.domain}`);
|
|
64
|
+
}
|
|
65
|
+
console.log();
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
logger.error(`Failed: ${err.message}`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
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.deployCommand = deployCommand;
|
|
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 deploy_js_1 = require("../lib/deploy.js");
|
|
42
|
+
const logger = __importStar(require("../lib/logger.js"));
|
|
43
|
+
function confirm(question) {
|
|
44
|
+
const rl = readline.createInterface({
|
|
45
|
+
input: process.stdin,
|
|
46
|
+
output: process.stdout,
|
|
47
|
+
});
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
rl.question(question, (answer) => {
|
|
50
|
+
rl.close();
|
|
51
|
+
resolve(answer.toLowerCase() !== "n");
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function deployCommand(options) {
|
|
56
|
+
const config = (0, config_js_1.loadConfig)();
|
|
57
|
+
if (!config) {
|
|
58
|
+
logger.error("Not logged in. Run 'vc login' first.");
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
// Detect project
|
|
62
|
+
const project = (0, detector_js_1.detectProject)();
|
|
63
|
+
if (!project.gitURL) {
|
|
64
|
+
logger.error("No git remote found. Initialize a git repo with a remote first.");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
const appName = options.name || project.name;
|
|
68
|
+
// Show summary
|
|
69
|
+
const summary = {
|
|
70
|
+
App: appName,
|
|
71
|
+
Git: project.gitURL.replace(/https?:\/\//, ""),
|
|
72
|
+
Branch: project.gitBranch,
|
|
73
|
+
Framework: project.framework,
|
|
74
|
+
};
|
|
75
|
+
if (project.database) {
|
|
76
|
+
summary["Database"] = `${project.database.type} (auto-detected)`;
|
|
77
|
+
}
|
|
78
|
+
console.log();
|
|
79
|
+
logger.box(summary);
|
|
80
|
+
console.log();
|
|
81
|
+
// Confirm
|
|
82
|
+
if (!options.yes) {
|
|
83
|
+
const ok = await confirm("Deploy? (Y/n) ");
|
|
84
|
+
if (!ok) {
|
|
85
|
+
logger.info("Cancelled.");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const spin = logger.spinner("Deploying...");
|
|
90
|
+
try {
|
|
91
|
+
const body = {
|
|
92
|
+
name: appName,
|
|
93
|
+
git_url: project.gitURL,
|
|
94
|
+
git_branch: project.gitBranch,
|
|
95
|
+
framework: project.framework,
|
|
96
|
+
};
|
|
97
|
+
if (project.database) {
|
|
98
|
+
body.database = project.database;
|
|
99
|
+
}
|
|
100
|
+
const result = await (0, api_js_1.apiRequest)("/api/deploy/oneshot", {
|
|
101
|
+
method: "POST",
|
|
102
|
+
body,
|
|
103
|
+
});
|
|
104
|
+
// Poll deployment status
|
|
105
|
+
const appId = result.app.id;
|
|
106
|
+
const depId = result.deployment.id;
|
|
107
|
+
const status = await (0, deploy_js_1.waitForDeployment)(appId, depId);
|
|
108
|
+
spin.stop();
|
|
109
|
+
if (status === "running") {
|
|
110
|
+
console.log();
|
|
111
|
+
logger.success(`Deployed! ${logger.cyan(result.url)}`);
|
|
112
|
+
if (result.service) {
|
|
113
|
+
logger.info(`Database: ${result.service.type} (${result.service.name})`);
|
|
114
|
+
}
|
|
115
|
+
if (result.database_url) {
|
|
116
|
+
logger.dim(`DATABASE_URL set automatically`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
logger.error("Deployment failed. Check logs with 'vc logs " + appName + "'");
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
spin.stop();
|
|
126
|
+
logger.error(`Deploy failed: ${err.message}`);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
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.loginCommand = loginCommand;
|
|
37
|
+
const http = __importStar(require("node:http"));
|
|
38
|
+
const url = __importStar(require("node:url"));
|
|
39
|
+
const node_child_process_1 = require("node:child_process");
|
|
40
|
+
const config_js_1 = require("../lib/config.js");
|
|
41
|
+
const logger = __importStar(require("../lib/logger.js"));
|
|
42
|
+
function openBrowser(url) {
|
|
43
|
+
const platform = process.platform;
|
|
44
|
+
const cmd = platform === "darwin"
|
|
45
|
+
? "open"
|
|
46
|
+
: platform === "win32"
|
|
47
|
+
? "start"
|
|
48
|
+
: "xdg-open";
|
|
49
|
+
(0, node_child_process_1.exec)(`${cmd} "${url}"`);
|
|
50
|
+
}
|
|
51
|
+
function findFreePort() {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const server = http.createServer();
|
|
54
|
+
server.listen(0, () => {
|
|
55
|
+
const addr = server.address();
|
|
56
|
+
if (addr && typeof addr === "object") {
|
|
57
|
+
const port = addr.port;
|
|
58
|
+
server.close(() => resolve(port));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
reject(new Error("Failed to find free port"));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
async function loginCommand(options) {
|
|
67
|
+
const serverURL = (options.server || config_js_1.DEFAULT_SERVER_URL).replace(/\/+$/, "");
|
|
68
|
+
const provider = options.github ? "github" : "google";
|
|
69
|
+
const port = await findFreePort();
|
|
70
|
+
const spin = logger.spinner("Waiting for browser authentication...");
|
|
71
|
+
// Start temporary HTTP server to receive OAuth callback
|
|
72
|
+
const tokenPromise = new Promise((resolve, reject) => {
|
|
73
|
+
const timeout = setTimeout(() => {
|
|
74
|
+
server.close();
|
|
75
|
+
reject(new Error("Authentication timed out (30s)"));
|
|
76
|
+
}, 30000);
|
|
77
|
+
const server = http.createServer((req, res) => {
|
|
78
|
+
const parsed = url.parse(req.url || "", true);
|
|
79
|
+
if (parsed.pathname === "/callback") {
|
|
80
|
+
const accessToken = parsed.query.access_token;
|
|
81
|
+
const refreshToken = parsed.query.refresh_token;
|
|
82
|
+
if (accessToken && refreshToken) {
|
|
83
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
84
|
+
res.end(`
|
|
85
|
+
<html>
|
|
86
|
+
<body style="font-family: system-ui, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #0a0a0a; color: #fafafa;">
|
|
87
|
+
<div style="text-align: center;">
|
|
88
|
+
<h2>Authentication Successful</h2>
|
|
89
|
+
<p>You can close this window and return to the terminal.</p>
|
|
90
|
+
</div>
|
|
91
|
+
</body>
|
|
92
|
+
</html>
|
|
93
|
+
`);
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
server.close();
|
|
96
|
+
resolve({ access_token: accessToken, refresh_token: refreshToken });
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
100
|
+
res.end(`
|
|
101
|
+
<html>
|
|
102
|
+
<body style="font-family: system-ui, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #0a0a0a; color: #fafafa;">
|
|
103
|
+
<div style="text-align: center;">
|
|
104
|
+
<h2>Authentication Failed</h2>
|
|
105
|
+
<p>Missing tokens. Please try again.</p>
|
|
106
|
+
</div>
|
|
107
|
+
</body>
|
|
108
|
+
</html>
|
|
109
|
+
`);
|
|
110
|
+
clearTimeout(timeout);
|
|
111
|
+
server.close();
|
|
112
|
+
reject(new Error("Missing tokens in callback"));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
res.writeHead(404);
|
|
117
|
+
res.end("Not Found");
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
server.listen(port, () => {
|
|
121
|
+
const authURL = `${serverURL}/api/auth/${provider}?cli_port=${port}`;
|
|
122
|
+
logger.info(`Opening browser for ${provider} login...`);
|
|
123
|
+
openBrowser(authURL);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
try {
|
|
127
|
+
const tokens = await tokenPromise;
|
|
128
|
+
// Create API key using the access token
|
|
129
|
+
const keyResp = await fetch(`${serverURL}/api/settings/api-keys`, {
|
|
130
|
+
method: "POST",
|
|
131
|
+
headers: {
|
|
132
|
+
"Content-Type": "application/json",
|
|
133
|
+
Authorization: `Bearer ${tokens.access_token}`,
|
|
134
|
+
},
|
|
135
|
+
body: JSON.stringify({ name: "CLI Key" }),
|
|
136
|
+
});
|
|
137
|
+
if (!keyResp.ok) {
|
|
138
|
+
throw new Error("Failed to create API key");
|
|
139
|
+
}
|
|
140
|
+
const keyData = (await keyResp.json());
|
|
141
|
+
const apiKey = keyData.data.key;
|
|
142
|
+
// Get user email
|
|
143
|
+
const meResp = await fetch(`${serverURL}/api/auth/me`, {
|
|
144
|
+
headers: { Authorization: `Bearer ${tokens.access_token}` },
|
|
145
|
+
});
|
|
146
|
+
const meData = (await meResp.json());
|
|
147
|
+
const userEmail = meData.data.email;
|
|
148
|
+
// Save config
|
|
149
|
+
(0, config_js_1.saveConfig)({
|
|
150
|
+
server_url: serverURL,
|
|
151
|
+
api_key: apiKey,
|
|
152
|
+
user_email: userEmail,
|
|
153
|
+
});
|
|
154
|
+
spin.stop();
|
|
155
|
+
logger.success(`Logged in as ${logger.bold(userEmail)}`);
|
|
156
|
+
// Register MCP server
|
|
157
|
+
const mcpRegistered = (0, config_js_1.registerMCP)();
|
|
158
|
+
if (mcpRegistered) {
|
|
159
|
+
logger.success("Claude Code MCP server registered");
|
|
160
|
+
logger.dim('Claude Code를 재시작하면 "배포해줘"로 바로 배포할 수 있습니다.');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
spin.stop();
|
|
165
|
+
logger.error(`Login failed: ${err.message}`);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function logsCommand(appName?: string): Promise<void>;
|
|
@@ -0,0 +1,75 @@
|
|
|
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.logsCommand = logsCommand;
|
|
37
|
+
const config_js_1 = require("../lib/config.js");
|
|
38
|
+
const api_js_1 = require("../lib/api.js");
|
|
39
|
+
const app_js_1 = require("../lib/app.js");
|
|
40
|
+
const logger = __importStar(require("../lib/logger.js"));
|
|
41
|
+
async function logsCommand(appName) {
|
|
42
|
+
const config = (0, config_js_1.loadConfig)();
|
|
43
|
+
if (!config) {
|
|
44
|
+
logger.error("Not logged in. Run 'vc login' first.");
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const app = await (0, app_js_1.getAppByName)(appName);
|
|
49
|
+
if (!app) {
|
|
50
|
+
logger.error(`App '${appName || "current directory"}' not found`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
// Get latest deployment
|
|
54
|
+
const deployments = await (0, api_js_1.apiRequest)(`/api/apps/${app.id}/deployments`);
|
|
55
|
+
if (!deployments || deployments.length === 0) {
|
|
56
|
+
logger.info("No deployments found");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const latest = deployments[0];
|
|
60
|
+
// Get build log
|
|
61
|
+
const logData = await (0, api_js_1.apiRequest)(`/api/apps/${app.id}/deployments/${latest.id}/log`);
|
|
62
|
+
logger.info(`Deployment v${latest.version} (${latest.status})`);
|
|
63
|
+
console.log();
|
|
64
|
+
if (logData.log) {
|
|
65
|
+
console.log(logData.log);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
logger.dim("No logs available yet");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
logger.error(`Failed: ${err.message}`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function statusCommand(appName?: string): Promise<void>;
|
|
@@ -0,0 +1,72 @@
|
|
|
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.statusCommand = statusCommand;
|
|
37
|
+
const config_js_1 = require("../lib/config.js");
|
|
38
|
+
const app_js_1 = require("../lib/app.js");
|
|
39
|
+
const logger = __importStar(require("../lib/logger.js"));
|
|
40
|
+
async function statusCommand(appName) {
|
|
41
|
+
const config = (0, config_js_1.loadConfig)();
|
|
42
|
+
if (!config) {
|
|
43
|
+
logger.error("Not logged in. Run 'vc login' first.");
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const app = await (0, app_js_1.getAppByName)(appName);
|
|
48
|
+
if (!app) {
|
|
49
|
+
logger.error(`App '${appName || "current directory"}' not found`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const statusIcon = app.status === "running"
|
|
53
|
+
? logger.green("● running")
|
|
54
|
+
: app.status === "building"
|
|
55
|
+
? logger.yellow("◐ building")
|
|
56
|
+
: "○ " + app.status;
|
|
57
|
+
console.log();
|
|
58
|
+
logger.box({
|
|
59
|
+
App: app.name,
|
|
60
|
+
Status: statusIcon,
|
|
61
|
+
Framework: app.framework,
|
|
62
|
+
Domain: app.domain,
|
|
63
|
+
Git: app.git_url?.replace(/https?:\/\//, "") || "(none)",
|
|
64
|
+
Branch: app.git_branch,
|
|
65
|
+
});
|
|
66
|
+
console.log();
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
logger.error(`Failed: ${err.message}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const login_js_1 = require("./commands/login.js");
|
|
6
|
+
const deploy_js_1 = require("./commands/deploy.js");
|
|
7
|
+
const status_js_1 = require("./commands/status.js");
|
|
8
|
+
const logs_js_1 = require("./commands/logs.js");
|
|
9
|
+
const apps_js_1 = require("./commands/apps.js");
|
|
10
|
+
const server_js_1 = require("./mcp/server.js");
|
|
11
|
+
const program = new commander_1.Command();
|
|
12
|
+
program
|
|
13
|
+
.name("vc")
|
|
14
|
+
.description("VeryCloud CLI - Deploy apps with one command")
|
|
15
|
+
.version("0.1.0");
|
|
16
|
+
program
|
|
17
|
+
.command("login")
|
|
18
|
+
.description("Log in to VeryCloud via browser OAuth")
|
|
19
|
+
.option("-s, --server <url>", "Custom server URL (for development)")
|
|
20
|
+
.option("-g, --github", "Use GitHub instead of Google for login")
|
|
21
|
+
.action(login_js_1.loginCommand);
|
|
22
|
+
program
|
|
23
|
+
.command("deploy")
|
|
24
|
+
.description("Deploy current project to VeryCloud")
|
|
25
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
26
|
+
.option("-n, --name <name>", "App name (default: directory name)")
|
|
27
|
+
.action(deploy_js_1.deployCommand);
|
|
28
|
+
program
|
|
29
|
+
.command("status [app-name]")
|
|
30
|
+
.description("Show app status")
|
|
31
|
+
.action(status_js_1.statusCommand);
|
|
32
|
+
program
|
|
33
|
+
.command("logs [app-name]")
|
|
34
|
+
.description("Show deployment logs")
|
|
35
|
+
.action(logs_js_1.logsCommand);
|
|
36
|
+
program
|
|
37
|
+
.command("apps")
|
|
38
|
+
.description("List all apps")
|
|
39
|
+
.action(apps_js_1.appsCommand);
|
|
40
|
+
program
|
|
41
|
+
.command("mcp")
|
|
42
|
+
.description("Start MCP server (stdio) for AI tool integration")
|
|
43
|
+
.action(() => {
|
|
44
|
+
(0, server_js_1.startMCPServer)();
|
|
45
|
+
});
|
|
46
|
+
program.parse();
|
package/dist/lib/api.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
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.apiRequest = apiRequest;
|
|
37
|
+
const config_js_1 = require("./config.js");
|
|
38
|
+
const logger = __importStar(require("./logger.js"));
|
|
39
|
+
async function apiRequest(path, options = {}) {
|
|
40
|
+
const config = (0, config_js_1.loadConfig)();
|
|
41
|
+
if (!config && !options.token) {
|
|
42
|
+
logger.error("Not logged in. Run 'vc login' first.");
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const serverURL = config?.server_url || "";
|
|
46
|
+
const url = `${serverURL}${path}`;
|
|
47
|
+
const headers = {
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
...options.headers,
|
|
50
|
+
};
|
|
51
|
+
if (options.token) {
|
|
52
|
+
headers["Authorization"] = `Bearer ${options.token}`;
|
|
53
|
+
}
|
|
54
|
+
else if (config?.api_key) {
|
|
55
|
+
headers["X-API-Key"] = config.api_key;
|
|
56
|
+
}
|
|
57
|
+
const fetchOptions = {
|
|
58
|
+
method: options.method || "GET",
|
|
59
|
+
headers,
|
|
60
|
+
};
|
|
61
|
+
if (options.body) {
|
|
62
|
+
fetchOptions.body = JSON.stringify(options.body);
|
|
63
|
+
}
|
|
64
|
+
const resp = await fetch(url, fetchOptions);
|
|
65
|
+
if (resp.status === 204) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const json = (await resp.json());
|
|
69
|
+
if (!resp.ok || json.error) {
|
|
70
|
+
const msg = json.error?.message || `HTTP ${resp.status}`;
|
|
71
|
+
throw new Error(msg);
|
|
72
|
+
}
|
|
73
|
+
return json.data;
|
|
74
|
+
}
|