@vibedhost/cli 1.0.4 → 1.0.6

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.
Files changed (3) hide show
  1. package/dist/index.js +244 -0
  2. package/package.json +1 -1
  3. package/src/index.ts +267 -0
package/dist/index.js CHANGED
@@ -20,6 +20,12 @@ async function main() {
20
20
  case "whoami":
21
21
  await handleWhoami();
22
22
  break;
23
+ case "token":
24
+ await handleToken();
25
+ break;
26
+ case "app":
27
+ await handleApp();
28
+ break;
23
29
  case "deploy":
24
30
  await handleDeploy();
25
31
  break;
@@ -69,6 +75,8 @@ Commands:
69
75
  login Authenticate this terminal with your VibedHost account
70
76
  logout Disconnect active account credentials from this machine
71
77
  whoami Display authenticated account and workspace inventory
78
+ token Display authenticated MCP API token and client configuration
79
+ app <create|list|status> Launch and inspect 1-Click catalog applications (WordPress, n8n, Ghost, etc.)
72
80
  deploy [dir] Package and deploy local project to dedicated workspace
73
81
  status [app] Check real-time application deployment and routing status
74
82
  logs [app] Stream live application logs or container build output
@@ -978,6 +986,242 @@ async function handleDb() {
978
986
  }
979
987
  console.log("Usage: vibed db [create|list|link|unlink] (or npx @vibedhost/cli db [create|list|link|unlink])");
980
988
  }
989
+ async function handleToken() {
990
+ const config = (0, utils_1.readGlobalConfig)();
991
+ if (!config?.token) {
992
+ console.log("Not authenticated. Run 'vibed login' (or 'npx @vibedhost/cli login') to connect your account.");
993
+ return;
994
+ }
995
+ console.log("\nVibedHost Personal Access Token & MCP Configuration");
996
+ console.log("------------------------------------------------------------");
997
+ console.log(`Account: ${config.email || "Authenticated User"}`);
998
+ console.log(`Token: ${config.token}`);
999
+ console.log("\nAdd to Claude Code, Cursor, or ChatGPT MCP Settings (JSON):");
1000
+ console.log(JSON.stringify({
1001
+ mcpServers: {
1002
+ vibedhost: {
1003
+ url: `${utils_1.API_BASE_URL}/api/mcp`,
1004
+ headers: {
1005
+ Authorization: `Bearer ${config.token}`
1006
+ }
1007
+ }
1008
+ }
1009
+ }, null, 2));
1010
+ console.log("------------------------------------------------------------\n");
1011
+ }
1012
+ async function handleApp() {
1013
+ const config = (0, utils_1.readGlobalConfig)();
1014
+ if (!config?.token) {
1015
+ console.error("Not authenticated. Please run 'vibed login' (or 'npx @vibedhost/cli login') first.");
1016
+ process.exit(1);
1017
+ }
1018
+ const subCommand = args[1] || "list";
1019
+ const projectConfig = (0, utils_1.readProjectConfig)();
1020
+ // 0. APP STATUS
1021
+ if (subCommand === "status") {
1022
+ if (args[2]) {
1023
+ args[1] = args[2];
1024
+ }
1025
+ await handleStatus();
1026
+ return;
1027
+ }
1028
+ // 1. APP LIST
1029
+ if (subCommand === "list") {
1030
+ try {
1031
+ const res = await fetch(`${utils_1.API_BASE_URL}/api/cli/workspaces`, {
1032
+ headers: { Authorization: `Bearer ${config.token}` }
1033
+ });
1034
+ const data = (await res.json());
1035
+ if (!res.ok) {
1036
+ console.error(`Error: ${data.error || "Failed to fetch applications."}`);
1037
+ process.exit(1);
1038
+ }
1039
+ console.log("\nActive Web Applications & Services:");
1040
+ console.log("------------------------------------------------------------");
1041
+ let totalAppCount = 0;
1042
+ (data.workspaces || []).forEach((ws) => {
1043
+ const webApps = (ws.apps || []).filter((a) => a.type !== "DATABASE");
1044
+ if (webApps.length > 0) {
1045
+ console.log(`Workspace: ${ws.name} (${ws.planName})`);
1046
+ webApps.forEach((a, idx) => {
1047
+ totalAppCount++;
1048
+ const urlStr = a.domain ? `https://${a.domain}` : "Initializing";
1049
+ console.log(` [${idx + 1}] ${a.name} (${a.type}) • Status: ${a.status}`);
1050
+ console.log(` URL: ${urlStr}`);
1051
+ });
1052
+ console.log("");
1053
+ }
1054
+ });
1055
+ if (totalAppCount === 0) {
1056
+ console.log("No web applications deployed yet.");
1057
+ console.log("Run 'vibed deploy' inside a project folder or 'vibed app create <name>' to launch a 1-Click app.\n");
1058
+ }
1059
+ else {
1060
+ console.log("------------------------------------------------------------\n");
1061
+ }
1062
+ }
1063
+ catch (err) {
1064
+ console.error(`Connection error: ${err.message}`);
1065
+ }
1066
+ return;
1067
+ }
1068
+ // 2. APP CREATE (1-Click Catalog Launcher)
1069
+ if (subCommand === "create") {
1070
+ let appName = args[2] && !args[2].startsWith("--") ? args[2] : "";
1071
+ const catalogIndex = args.indexOf("--catalog");
1072
+ const appFlagIndex = args.indexOf("--app");
1073
+ let explicitCatalog = catalogIndex !== -1 ? args[catalogIndex + 1] : appFlagIndex !== -1 ? args[appFlagIndex + 1] : "";
1074
+ if (!appName && process.stdin.isTTY) {
1075
+ appName = await (0, utils_1.askQuestion)("Application Service Name", "my-wordpress");
1076
+ }
1077
+ else if (!appName) {
1078
+ appName = "my-wordpress";
1079
+ }
1080
+ if (!explicitCatalog && process.stdin.isTTY) {
1081
+ console.log("\nSelect 1-Click Application to Launch:");
1082
+ console.log(" [1] WordPress (CMS + Dedicated MySQL 8.0)");
1083
+ console.log(" [2] n8n.io (Workflow Automation + Postgres)");
1084
+ console.log(" [3] PocketBase (Lean Backend + SQLite)");
1085
+ console.log(" [4] Ghost (Publishing + MySQL 8.0)");
1086
+ console.log(" [5] Directus (BaaS + Postgres)");
1087
+ console.log(" [6] MinIO (S3-Compatible Object Storage)");
1088
+ console.log(" [7] Uptime Kuma (Uptime Monitoring & Status Pages)");
1089
+ console.log(" [8] Umami (Privacy Analytics + Postgres)");
1090
+ console.log(" [9] MeiliSearch (High-Speed Full-Text Search)");
1091
+ console.log(" [10] Qdrant (Vector AI Database)");
1092
+ const chosen = await (0, utils_1.askQuestion)("Enter number", "1");
1093
+ const map = {
1094
+ "1": "wordpress",
1095
+ "2": "n8n",
1096
+ "3": "pocketbase",
1097
+ "4": "ghost",
1098
+ "5": "directus",
1099
+ "6": "minio",
1100
+ "7": "uptime-kuma",
1101
+ "8": "umami",
1102
+ "9": "meilisearch",
1103
+ "10": "qdrant"
1104
+ };
1105
+ explicitCatalog = map[chosen] || "wordpress";
1106
+ }
1107
+ const cleanCatalogKey = (explicitCatalog || "wordpress").toLowerCase().trim();
1108
+ console.log(`\nLaunching 1-Click '${cleanCatalogKey}' as '${appName}' on dedicated workspace...`);
1109
+ try {
1110
+ const res = await fetch(`${utils_1.API_BASE_URL}/api/cli/app`, {
1111
+ method: "POST",
1112
+ headers: {
1113
+ Authorization: `Bearer ${config.token}`,
1114
+ "Content-Type": "application/json"
1115
+ },
1116
+ body: JSON.stringify({
1117
+ action: "CREATE_APP",
1118
+ workspaceId: projectConfig?.workspaceId,
1119
+ name: appName,
1120
+ catalogKey: cleanCatalogKey
1121
+ })
1122
+ });
1123
+ const rawText = await res.text();
1124
+ let data = {};
1125
+ try {
1126
+ data = JSON.parse(rawText);
1127
+ }
1128
+ catch {
1129
+ throw new Error(`Gateway returned unexpected response (${res.status}): ${rawText.slice(0, 150)}`);
1130
+ }
1131
+ if (!res.ok || !data.success) {
1132
+ console.error(`Launch error: ${data.error || "Failed to launch catalog application."}`);
1133
+ process.exit(1);
1134
+ }
1135
+ console.log("Building application container in background...");
1136
+ // Progressive status polling loop (up to 90 seconds)
1137
+ const startTime = Date.now();
1138
+ let isLive = false;
1139
+ let isFailed = false;
1140
+ const finalAppName = data.name || appName;
1141
+ while (!isLive && !isFailed && Date.now() - startTime < 90000) {
1142
+ await new Promise((r) => setTimeout(r, 2500));
1143
+ const elapsedSec = Math.round((Date.now() - startTime) / 1000);
1144
+ try {
1145
+ const checkRes = await fetch(`${utils_1.API_BASE_URL}/api/cli/logs?appName=${encodeURIComponent(finalAppName)}`, { headers: { Authorization: `Bearer ${config.token}` } });
1146
+ const checkData = (await checkRes.json());
1147
+ if (checkData.status === "active") {
1148
+ isLive = true;
1149
+ break;
1150
+ }
1151
+ else if (checkData.status === "failed") {
1152
+ isFailed = true;
1153
+ break;
1154
+ }
1155
+ else {
1156
+ process.stdout.write(`\rBuilding application container in background... (${elapsedSec}s)`);
1157
+ }
1158
+ }
1159
+ catch { }
1160
+ }
1161
+ process.stdout.write("\r" + " ".repeat(65) + "\r");
1162
+ if (isLive) {
1163
+ console.log(`
1164
+ Application Ready & Online!
1165
+ ------------------------------------------------------------
1166
+ Service Name: ${data.name}
1167
+ Catalog Type: ${data.catalogKey}
1168
+ Workspace: ${data.workspaceName}
1169
+ Status: Active
1170
+
1171
+ Live URL: https://${data.domain}`);
1172
+ if (data.adminPath) {
1173
+ console.log(`Admin URL: https://${data.domain}${data.adminPath}`);
1174
+ }
1175
+ if (data.defaultUser) {
1176
+ console.log(`Admin User: ${data.defaultUser}`);
1177
+ }
1178
+ if (data.defaultPassword) {
1179
+ console.log(`Admin Pass: ${data.defaultPassword}`);
1180
+ }
1181
+ console.log(`------------------------------------------------------------\n`);
1182
+ }
1183
+ else if (isFailed) {
1184
+ console.error(`
1185
+ Application Launch Unsuccessful
1186
+ ------------------------------------------------------------
1187
+ Service: ${finalAppName}
1188
+ Workspace: ${data.workspaceName}
1189
+ Status: Failed
1190
+
1191
+ Launch unsuccessful.
1192
+ Run 'vibed logs ${finalAppName}' to view container error logs.
1193
+ ------------------------------------------------------------
1194
+ `);
1195
+ process.exit(1);
1196
+ }
1197
+ else {
1198
+ console.log(`
1199
+ Application Launch in Progress
1200
+ ------------------------------------------------------------
1201
+ Service Name: ${data.name}
1202
+ Catalog Type: ${data.catalogKey}
1203
+ Workspace: ${data.workspaceName}
1204
+ Status: Building
1205
+
1206
+ Your application is continuing to initialize in the background.
1207
+ Run 'vibed status ${finalAppName}' to check real-time status.
1208
+ Run 'vibed logs ${finalAppName}' to view live startup logs.`);
1209
+ if (data.defaultUser) {
1210
+ console.log(`Admin User: ${data.defaultUser}`);
1211
+ }
1212
+ if (data.defaultPassword) {
1213
+ console.log(`Admin Pass: ${data.defaultPassword}`);
1214
+ }
1215
+ console.log(`------------------------------------------------------------\n`);
1216
+ }
1217
+ }
1218
+ catch (err) {
1219
+ console.error(`\nConnection error: ${err.message}`);
1220
+ }
1221
+ return;
1222
+ }
1223
+ console.log("Usage: vibed app [create|list|status] (or npx @vibedhost/cli app [create|list|status])");
1224
+ }
981
1225
  main().catch((err) => {
982
1226
  console.error(`Execution error: ${err.message}`);
983
1227
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibedhost/cli",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "VibedHost Cloud Engine CLI: Deploy applications to dedicated cloud workspaces directly from your terminal.",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {
package/src/index.ts CHANGED
@@ -32,6 +32,12 @@ async function main() {
32
32
  case "whoami":
33
33
  await handleWhoami();
34
34
  break;
35
+ case "token":
36
+ await handleToken();
37
+ break;
38
+ case "app":
39
+ await handleApp();
40
+ break;
35
41
  case "deploy":
36
42
  await handleDeploy();
37
43
  break;
@@ -82,6 +88,8 @@ Commands:
82
88
  login Authenticate this terminal with your VibedHost account
83
89
  logout Disconnect active account credentials from this machine
84
90
  whoami Display authenticated account and workspace inventory
91
+ token Display authenticated MCP API token and client configuration
92
+ app <create|list|status> Launch and inspect 1-Click catalog applications (WordPress, n8n, Ghost, etc.)
85
93
  deploy [dir] Package and deploy local project to dedicated workspace
86
94
  status [app] Check real-time application deployment and routing status
87
95
  logs [app] Stream live application logs or container build output
@@ -1094,6 +1102,265 @@ async function handleDb() {
1094
1102
  console.log("Usage: vibed db [create|list|link|unlink] (or npx @vibedhost/cli db [create|list|link|unlink])");
1095
1103
  }
1096
1104
 
1105
+ async function handleToken() {
1106
+ const config = readGlobalConfig();
1107
+ if (!config?.token) {
1108
+ console.log("Not authenticated. Run 'vibed login' (or 'npx @vibedhost/cli login') to connect your account.");
1109
+ return;
1110
+ }
1111
+
1112
+ console.log("\nVibedHost Personal Access Token & MCP Configuration");
1113
+ console.log("------------------------------------------------------------");
1114
+ console.log(`Account: ${config.email || "Authenticated User"}`);
1115
+ console.log(`Token: ${config.token}`);
1116
+ console.log("\nAdd to Claude Code, Cursor, or ChatGPT MCP Settings (JSON):");
1117
+ console.log(
1118
+ JSON.stringify(
1119
+ {
1120
+ mcpServers: {
1121
+ vibedhost: {
1122
+ url: `${API_BASE_URL}/api/mcp`,
1123
+ headers: {
1124
+ Authorization: `Bearer ${config.token}`
1125
+ }
1126
+ }
1127
+ }
1128
+ },
1129
+ null,
1130
+ 2
1131
+ )
1132
+ );
1133
+ console.log("------------------------------------------------------------\n");
1134
+ }
1135
+
1136
+ async function handleApp() {
1137
+ const config = readGlobalConfig();
1138
+ if (!config?.token) {
1139
+ console.error("Not authenticated. Please run 'vibed login' (or 'npx @vibedhost/cli login') first.");
1140
+ process.exit(1);
1141
+ }
1142
+
1143
+ const subCommand = args[1] || "list";
1144
+ const projectConfig = readProjectConfig();
1145
+
1146
+ // 0. APP STATUS
1147
+ if (subCommand === "status") {
1148
+ if (args[2]) {
1149
+ args[1] = args[2];
1150
+ }
1151
+ await handleStatus();
1152
+ return;
1153
+ }
1154
+
1155
+ // 1. APP LIST
1156
+ if (subCommand === "list") {
1157
+ try {
1158
+ const res = await fetch(`${API_BASE_URL}/api/cli/workspaces`, {
1159
+ headers: { Authorization: `Bearer ${config.token}` }
1160
+ });
1161
+ const data = (await res.json()) as any;
1162
+
1163
+ if (!res.ok) {
1164
+ console.error(`Error: ${data.error || "Failed to fetch applications."}`);
1165
+ process.exit(1);
1166
+ }
1167
+
1168
+ console.log("\nActive Web Applications & Services:");
1169
+ console.log("------------------------------------------------------------");
1170
+
1171
+ let totalAppCount = 0;
1172
+ (data.workspaces || []).forEach((ws: any) => {
1173
+ const webApps = (ws.apps || []).filter((a: any) => a.type !== "DATABASE");
1174
+ if (webApps.length > 0) {
1175
+ console.log(`Workspace: ${ws.name} (${ws.planName})`);
1176
+ webApps.forEach((a: any, idx: number) => {
1177
+ totalAppCount++;
1178
+ const urlStr = a.domain ? `https://${a.domain}` : "Initializing";
1179
+ console.log(` [${idx + 1}] ${a.name} (${a.type}) • Status: ${a.status}`);
1180
+ console.log(` URL: ${urlStr}`);
1181
+ });
1182
+ console.log("");
1183
+ }
1184
+ });
1185
+
1186
+ if (totalAppCount === 0) {
1187
+ console.log("No web applications deployed yet.");
1188
+ console.log("Run 'vibed deploy' inside a project folder or 'vibed app create <name>' to launch a 1-Click app.\n");
1189
+ } else {
1190
+ console.log("------------------------------------------------------------\n");
1191
+ }
1192
+ } catch (err: any) {
1193
+ console.error(`Connection error: ${err.message}`);
1194
+ }
1195
+ return;
1196
+ }
1197
+
1198
+ // 2. APP CREATE (1-Click Catalog Launcher)
1199
+ if (subCommand === "create") {
1200
+ let appName = args[2] && !args[2].startsWith("--") ? args[2] : "";
1201
+ const catalogIndex = args.indexOf("--catalog");
1202
+ const appFlagIndex = args.indexOf("--app");
1203
+ let explicitCatalog = catalogIndex !== -1 ? args[catalogIndex + 1] : appFlagIndex !== -1 ? args[appFlagIndex + 1] : "";
1204
+
1205
+ if (!appName && process.stdin.isTTY) {
1206
+ appName = await askQuestion("Application Service Name", "my-wordpress");
1207
+ } else if (!appName) {
1208
+ appName = "my-wordpress";
1209
+ }
1210
+
1211
+ if (!explicitCatalog && process.stdin.isTTY) {
1212
+ console.log("\nSelect 1-Click Application to Launch:");
1213
+ console.log(" [1] WordPress (CMS + Dedicated MySQL 8.0)");
1214
+ console.log(" [2] n8n.io (Workflow Automation + Postgres)");
1215
+ console.log(" [3] PocketBase (Lean Backend + SQLite)");
1216
+ console.log(" [4] Ghost (Publishing + MySQL 8.0)");
1217
+ console.log(" [5] Directus (BaaS + Postgres)");
1218
+ console.log(" [6] MinIO (S3-Compatible Object Storage)");
1219
+ console.log(" [7] Uptime Kuma (Uptime Monitoring & Status Pages)");
1220
+ console.log(" [8] Umami (Privacy Analytics + Postgres)");
1221
+ console.log(" [9] MeiliSearch (High-Speed Full-Text Search)");
1222
+ console.log(" [10] Qdrant (Vector AI Database)");
1223
+ const chosen = await askQuestion("Enter number", "1");
1224
+ const map: Record<string, string> = {
1225
+ "1": "wordpress",
1226
+ "2": "n8n",
1227
+ "3": "pocketbase",
1228
+ "4": "ghost",
1229
+ "5": "directus",
1230
+ "6": "minio",
1231
+ "7": "uptime-kuma",
1232
+ "8": "umami",
1233
+ "9": "meilisearch",
1234
+ "10": "qdrant"
1235
+ };
1236
+ explicitCatalog = map[chosen] || "wordpress";
1237
+ }
1238
+
1239
+ const cleanCatalogKey = (explicitCatalog || "wordpress").toLowerCase().trim();
1240
+ console.log(`\nLaunching 1-Click '${cleanCatalogKey}' as '${appName}' on dedicated workspace...`);
1241
+
1242
+ try {
1243
+ const res = await fetch(`${API_BASE_URL}/api/cli/app`, {
1244
+ method: "POST",
1245
+ headers: {
1246
+ Authorization: `Bearer ${config.token}`,
1247
+ "Content-Type": "application/json"
1248
+ },
1249
+ body: JSON.stringify({
1250
+ action: "CREATE_APP",
1251
+ workspaceId: projectConfig?.workspaceId,
1252
+ name: appName,
1253
+ catalogKey: cleanCatalogKey
1254
+ })
1255
+ });
1256
+
1257
+ const rawText = await res.text();
1258
+ let data: any = {};
1259
+ try {
1260
+ data = JSON.parse(rawText);
1261
+ } catch {
1262
+ throw new Error(`Gateway returned unexpected response (${res.status}): ${rawText.slice(0, 150)}`);
1263
+ }
1264
+
1265
+ if (!res.ok || !data.success) {
1266
+ console.error(`Launch error: ${data.error || "Failed to launch catalog application."}`);
1267
+ process.exit(1);
1268
+ }
1269
+
1270
+ console.log("Building application container in background...");
1271
+
1272
+ // Progressive status polling loop (up to 90 seconds)
1273
+ const startTime = Date.now();
1274
+ let isLive = false;
1275
+ let isFailed = false;
1276
+ const finalAppName = data.name || appName;
1277
+
1278
+ while (!isLive && !isFailed && Date.now() - startTime < 90000) {
1279
+ await new Promise((r) => setTimeout(r, 2500));
1280
+ const elapsedSec = Math.round((Date.now() - startTime) / 1000);
1281
+ try {
1282
+ const checkRes = await fetch(
1283
+ `${API_BASE_URL}/api/cli/logs?appName=${encodeURIComponent(finalAppName)}`,
1284
+ { headers: { Authorization: `Bearer ${config.token}` } }
1285
+ );
1286
+ const checkData = (await checkRes.json()) as any;
1287
+
1288
+ if (checkData.status === "active") {
1289
+ isLive = true;
1290
+ break;
1291
+ } else if (checkData.status === "failed") {
1292
+ isFailed = true;
1293
+ break;
1294
+ } else {
1295
+ process.stdout.write(`\rBuilding application container in background... (${elapsedSec}s)`);
1296
+ }
1297
+ } catch {}
1298
+ }
1299
+
1300
+ process.stdout.write("\r" + " ".repeat(65) + "\r");
1301
+
1302
+ if (isLive) {
1303
+ console.log(`
1304
+ Application Ready & Online!
1305
+ ------------------------------------------------------------
1306
+ Service Name: ${data.name}
1307
+ Catalog Type: ${data.catalogKey}
1308
+ Workspace: ${data.workspaceName}
1309
+ Status: Active
1310
+
1311
+ Live URL: https://${data.domain}`);
1312
+ if (data.adminPath) {
1313
+ console.log(`Admin URL: https://${data.domain}${data.adminPath}`);
1314
+ }
1315
+ if (data.defaultUser) {
1316
+ console.log(`Admin User: ${data.defaultUser}`);
1317
+ }
1318
+ if (data.defaultPassword) {
1319
+ console.log(`Admin Pass: ${data.defaultPassword}`);
1320
+ }
1321
+ console.log(`------------------------------------------------------------\n`);
1322
+ } else if (isFailed) {
1323
+ console.error(`
1324
+ Application Launch Unsuccessful
1325
+ ------------------------------------------------------------
1326
+ Service: ${finalAppName}
1327
+ Workspace: ${data.workspaceName}
1328
+ Status: Failed
1329
+
1330
+ Launch unsuccessful.
1331
+ Run 'vibed logs ${finalAppName}' to view container error logs.
1332
+ ------------------------------------------------------------
1333
+ `);
1334
+ process.exit(1);
1335
+ } else {
1336
+ console.log(`
1337
+ Application Launch in Progress
1338
+ ------------------------------------------------------------
1339
+ Service Name: ${data.name}
1340
+ Catalog Type: ${data.catalogKey}
1341
+ Workspace: ${data.workspaceName}
1342
+ Status: Building
1343
+
1344
+ Your application is continuing to initialize in the background.
1345
+ Run 'vibed status ${finalAppName}' to check real-time status.
1346
+ Run 'vibed logs ${finalAppName}' to view live startup logs.`);
1347
+ if (data.defaultUser) {
1348
+ console.log(`Admin User: ${data.defaultUser}`);
1349
+ }
1350
+ if (data.defaultPassword) {
1351
+ console.log(`Admin Pass: ${data.defaultPassword}`);
1352
+ }
1353
+ console.log(`------------------------------------------------------------\n`);
1354
+ }
1355
+ } catch (err: any) {
1356
+ console.error(`\nConnection error: ${err.message}`);
1357
+ }
1358
+ return;
1359
+ }
1360
+
1361
+ console.log("Usage: vibed app [create|list|status] (or npx @vibedhost/cli app [create|list|status])");
1362
+ }
1363
+
1097
1364
  main().catch((err) => {
1098
1365
  console.error(`Execution error: ${err.message}`);
1099
1366
  process.exit(1);