@mks2508/coolify-mks-cli-mcp 0.4.3 → 0.6.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.
Files changed (88) hide show
  1. package/dist/cli/coolify-state.d.ts +51 -0
  2. package/dist/cli/coolify-state.d.ts.map +1 -0
  3. package/dist/cli/index.js +2862 -631
  4. package/dist/coolify/config.d.ts +1 -1
  5. package/dist/coolify/config.d.ts.map +1 -1
  6. package/dist/coolify/index.d.ts +626 -12
  7. package/dist/coolify/index.d.ts.map +1 -1
  8. package/dist/coolify/types.d.ts +87 -3
  9. package/dist/coolify/types.d.ts.map +1 -1
  10. package/dist/dist-C4hIkHif.js +66 -0
  11. package/dist/dist-C4hIkHif.js.map +1 -0
  12. package/dist/dist-DEPvJhbP.js +3 -0
  13. package/dist/index.cjs +8511 -28542
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts +32 -8
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +8470 -28506
  18. package/dist/index.js.map +1 -1
  19. package/dist/network.d.ts +75 -0
  20. package/dist/network.d.ts.map +1 -0
  21. package/dist/sdk.d.ts +356 -0
  22. package/dist/sdk.d.ts.map +1 -0
  23. package/dist/server/index.d.ts +9 -0
  24. package/dist/server/index.d.ts.map +1 -0
  25. package/dist/server/sse.js +3 -1
  26. package/dist/server/stdio.d.ts +0 -2
  27. package/dist/server/stdio.d.ts.map +1 -1
  28. package/dist/server/stdio.js +3307 -1618
  29. package/dist/tools/definitions.d.ts +1 -1
  30. package/dist/tools/definitions.d.ts.map +1 -1
  31. package/dist/tools/handlers.d.ts +6 -7
  32. package/dist/tools/handlers.d.ts.map +1 -1
  33. package/dist/tools/index.d.ts +8 -0
  34. package/dist/tools/index.d.ts.map +1 -0
  35. package/dist/trace.d.ts +71 -0
  36. package/dist/trace.d.ts.map +1 -0
  37. package/dist/utils/format.d.ts +1 -1
  38. package/dist/utils/format.d.ts.map +1 -1
  39. package/package.json +13 -7
  40. package/src/cli/actions.ts +162 -0
  41. package/src/cli/commands/active-deployments.ts +24 -0
  42. package/src/cli/commands/build-logs.ts +58 -0
  43. package/src/cli/commands/cancel-deploy.ts +35 -0
  44. package/src/cli/commands/config.ts +53 -47
  45. package/src/cli/commands/create.ts +74 -53
  46. package/src/cli/commands/databases.ts +63 -0
  47. package/src/cli/commands/db.ts +68 -0
  48. package/src/cli/commands/delete.ts +41 -29
  49. package/src/cli/commands/deploy.ts +42 -21
  50. package/src/cli/commands/deployments.ts +41 -31
  51. package/src/cli/commands/destinations.ts +19 -27
  52. package/src/cli/commands/diagnose.ts +139 -0
  53. package/src/cli/commands/env.ts +66 -41
  54. package/src/cli/commands/environments.ts +36 -32
  55. package/src/cli/commands/exec.ts +39 -0
  56. package/src/cli/commands/keys.ts +46 -0
  57. package/src/cli/commands/list.ts +29 -27
  58. package/src/cli/commands/logs.ts +33 -18
  59. package/src/cli/commands/network.ts +145 -0
  60. package/src/cli/commands/projects.ts +51 -39
  61. package/src/cli/commands/restart.ts +60 -0
  62. package/src/cli/commands/server-resources.ts +71 -0
  63. package/src/cli/commands/servers.ts +23 -23
  64. package/src/cli/commands/service-logs.ts +59 -0
  65. package/src/cli/commands/services.ts +63 -0
  66. package/src/cli/commands/show.ts +72 -41
  67. package/src/cli/commands/start.ts +60 -0
  68. package/src/cli/commands/stop.ts +60 -0
  69. package/src/cli/commands/svc.ts +68 -0
  70. package/src/cli/commands/teams.ts +60 -0
  71. package/src/cli/commands/update.ts +73 -49
  72. package/src/cli/commands/version.ts +37 -0
  73. package/src/cli/coolify-state.ts +88 -0
  74. package/src/cli/index.ts +400 -125
  75. package/src/coolify/config.ts +29 -27
  76. package/src/coolify/index.ts +2221 -371
  77. package/src/coolify/types.ts +218 -123
  78. package/src/index.ts +82 -868
  79. package/src/network.ts +298 -0
  80. package/src/sdk.ts +597 -0
  81. package/src/server/index.ts +13 -0
  82. package/src/server/sse.ts +33 -25
  83. package/src/server/stdio.ts +24 -27
  84. package/src/tools/definitions.ts +893 -264
  85. package/src/tools/handlers.ts +556 -748
  86. package/src/tools/index.ts +8 -0
  87. package/src/trace.ts +116 -0
  88. package/src/utils/format.ts +36 -33
package/dist/cli/index.js CHANGED
@@ -17,6 +17,16 @@ var __toESM = (mod, isNodeMode, target) => {
17
17
  return to;
18
18
  };
19
19
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
29
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
20
30
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
21
31
 
22
32
  // ../../../node_modules/.bun/commander@12.1.0/node_modules/commander/lib/error.js
@@ -1858,6 +1868,27 @@ var require_commander = __commonJS((exports) => {
1858
1868
  exports.InvalidOptionArgumentError = InvalidArgumentError;
1859
1869
  });
1860
1870
 
1871
+ // ../../../node_modules/.bun/@mks2508+no-throw@0.1.0/node_modules/@mks2508/no-throw/dist/index.mjs
1872
+ function ok(value) {
1873
+ return {
1874
+ ok: true,
1875
+ value
1876
+ };
1877
+ }
1878
+ function err(error) {
1879
+ return {
1880
+ ok: false,
1881
+ error
1882
+ };
1883
+ }
1884
+ function isOk(result) {
1885
+ return result.ok;
1886
+ }
1887
+ function isErr(result) {
1888
+ return !result.ok;
1889
+ }
1890
+ var init_dist = () => {};
1891
+
1861
1892
  // ../../../node_modules/.bun/cli-spinners@2.9.2/node_modules/cli-spinners/spinners.json
1862
1893
  var require_spinners = __commonJS((exports, module) => {
1863
1894
  module.exports = {
@@ -5188,6 +5219,206 @@ var require_table = __commonJS((exports, module) => {
5188
5219
  module.exports = Table;
5189
5220
  });
5190
5221
 
5222
+ // src/trace.ts
5223
+ class OperationTracer {
5224
+ operation;
5225
+ steps = [];
5226
+ startTime;
5227
+ stepStart;
5228
+ onStep;
5229
+ constructor(operation, onStep) {
5230
+ this.operation = operation;
5231
+ this.startTime = Date.now();
5232
+ this.stepStart = this.startTime;
5233
+ this.onStep = onStep;
5234
+ }
5235
+ step(step, detail) {
5236
+ const now = Date.now();
5237
+ const traceStep = {
5238
+ ts: new Date(now).toISOString(),
5239
+ step,
5240
+ durationMs: now - this.stepStart,
5241
+ detail
5242
+ };
5243
+ this.steps.push(traceStep);
5244
+ this.stepStart = now;
5245
+ this.onStep?.(step, detail);
5246
+ if (process.stderr.isTTY) {
5247
+ const prefix = `\x1B[90m[${this.operation}]\x1B[0m`;
5248
+ const elapsed = `\x1B[33m${traceStep.durationMs}ms\x1B[0m`;
5249
+ const detailStr = detail ? ` \x1B[90m(${detail})\x1B[0m` : "";
5250
+ process.stderr.write(`${prefix} ${step} ${elapsed}${detailStr}
5251
+ `);
5252
+ }
5253
+ }
5254
+ finish(success, error) {
5255
+ return {
5256
+ operation: this.operation,
5257
+ steps: this.steps,
5258
+ totalMs: Date.now() - this.startTime,
5259
+ success,
5260
+ error
5261
+ };
5262
+ }
5263
+ }
5264
+
5265
+ // src/network.ts
5266
+ var exports_network = {};
5267
+ __export(exports_network, {
5268
+ inspectNetwork: () => inspectNetwork,
5269
+ analyzeDeployFailure: () => analyzeDeployFailure
5270
+ });
5271
+ async function safeExec(svc, uuid, command) {
5272
+ const result = await svc.executeCommand(uuid, command);
5273
+ if (isErr(result))
5274
+ return "";
5275
+ return result.value.response || result.value.message || "";
5276
+ }
5277
+ async function inspectNetwork(svc, appUuid, servicesToTest = []) {
5278
+ const tracer = new OperationTracer("network:inspect");
5279
+ try {
5280
+ tracer.step("Fetching /etc/hosts");
5281
+ const hostsRaw = await safeExec(svc, appUuid, "cat /etc/hosts 2>/dev/null");
5282
+ const hosts = hostsRaw.split(`
5283
+ `).filter((l) => l.trim() && !l.startsWith("#"));
5284
+ tracer.step("Checking network interfaces");
5285
+ const ifRaw = await safeExec(svc, appUuid, "ip addr 2>/dev/null || ifconfig 2>/dev/null || cat /proc/net/if_inet6 2>/dev/null || echo 'no network tools'");
5286
+ const interfaces = ifRaw.split(`
5287
+ `).filter((l) => l.includes("inet") || l.includes("scope"));
5288
+ tracer.step("Extracting network env vars");
5289
+ const envRaw = await safeExec(svc, appUuid, "env 2>/dev/null | grep -iE '(HOST|PORT|URL|DATABASE|REDIS|MONGO|POSTGRES|MYSQL|DB_|COOLIFY)' | sort");
5290
+ const networkEnv = {};
5291
+ for (const line of envRaw.split(`
5292
+ `).filter(Boolean)) {
5293
+ const [key, ...rest] = line.split("=");
5294
+ if (key)
5295
+ networkEnv[key] = rest.join("=");
5296
+ }
5297
+ tracer.step("Testing DNS resolution");
5298
+ const dnsTargets = [
5299
+ ...servicesToTest,
5300
+ ...Object.values(networkEnv).filter((v) => !v.includes("/") && !v.includes(":")).filter((v) => /^[a-z][a-z0-9-]*$/i.test(v))
5301
+ ];
5302
+ const uniqueTargets = [...new Set(dnsTargets)].slice(0, 10);
5303
+ const dns = [];
5304
+ for (const hostname of uniqueTargets) {
5305
+ const nslookup = await safeExec(svc, appUuid, `getent hosts ${hostname} 2>/dev/null || nslookup ${hostname} 2>/dev/null || echo 'FAIL'`);
5306
+ const resolved = !nslookup.includes("FAIL") && nslookup.trim().length > 0;
5307
+ const ip = resolved ? nslookup.split(/\s+/)[0] : undefined;
5308
+ dns.push({ hostname, resolved, ip });
5309
+ }
5310
+ tracer.step("Testing service connectivity", `${uniqueTargets.length} targets`);
5311
+ const connectivity = [];
5312
+ for (const target of servicesToTest) {
5313
+ const start = Date.now();
5314
+ const curlResult = await safeExec(svc, appUuid, `timeout 3 sh -c "echo > /dev/tcp/${target}/80 2>/dev/null && echo OK || curl -sf --max-time 2 http://${target}/ >/dev/null 2>&1 && echo OK || echo FAIL"`);
5315
+ connectivity.push({
5316
+ target,
5317
+ reachable: curlResult.includes("OK"),
5318
+ responseTime: Date.now() - start
5319
+ });
5320
+ }
5321
+ const trace = tracer.finish(true);
5322
+ return ok({ hosts, dns, networkEnv, connectivity, interfaces, trace });
5323
+ } catch (error) {
5324
+ const trace = tracer.finish(false, error instanceof Error ? error.message : String(error));
5325
+ return err(new Error(`Network inspection failed: ${trace.error}`));
5326
+ }
5327
+ }
5328
+ async function analyzeDeployFailure(svc, deploymentUuid) {
5329
+ const tracer = new OperationTracer("deploy:analyze");
5330
+ try {
5331
+ tracer.step("Fetching deployment details");
5332
+ const deployResult = await svc.getDeploymentLogs(deploymentUuid);
5333
+ if (isErr(deployResult)) {
5334
+ return err(deployResult.error);
5335
+ }
5336
+ const { status, logs: rawLogs } = deployResult.value;
5337
+ tracer.step("Extracting error lines", `${rawLogs.length} chars`);
5338
+ const lines = rawLogs.split(`
5339
+ `);
5340
+ const errors = lines.filter((l) => /error|ERR!|failed|FAIL|fatal|panic|exception/i.test(l) && !/no error|success/i.test(l));
5341
+ tracer.step("Categorizing error");
5342
+ let matchedPattern = ERROR_PATTERNS.find((p) => p.pattern.test(rawLogs));
5343
+ if (!matchedPattern) {
5344
+ matchedPattern = {
5345
+ pattern: /./,
5346
+ category: "unknown",
5347
+ summary: "Unknown build failure",
5348
+ suggestion: "Check the full build logs with `build-logs <deployment-uuid>` for details."
5349
+ };
5350
+ }
5351
+ const trace = tracer.finish(true);
5352
+ return ok({
5353
+ deploymentUuid,
5354
+ status,
5355
+ rawLogs,
5356
+ errors: errors.slice(0, 20),
5357
+ category: matchedPattern.category,
5358
+ summary: matchedPattern.summary,
5359
+ suggestion: matchedPattern.suggestion,
5360
+ trace
5361
+ });
5362
+ } catch (error) {
5363
+ const trace = tracer.finish(false, error instanceof Error ? error.message : String(error));
5364
+ return err(new Error(`Deploy analysis failed: ${trace.error}`));
5365
+ }
5366
+ }
5367
+ var ERROR_PATTERNS;
5368
+ var init_network = __esm(() => {
5369
+ init_dist();
5370
+ ERROR_PATTERNS = [
5371
+ {
5372
+ pattern: /npm ERR!|yarn error|pnpm ERR/i,
5373
+ category: "install_error",
5374
+ summary: "Package installation failed",
5375
+ suggestion: "Check package.json for invalid dependencies. Try deleting lock file and rebuilding."
5376
+ },
5377
+ {
5378
+ pattern: /COPY failed|COPY --from.*not found|no such file/i,
5379
+ category: "docker_error",
5380
+ summary: "Dockerfile COPY failed — file not found",
5381
+ suggestion: "Check Dockerfile paths and base_directory. Ensure source files exist in build context."
5382
+ },
5383
+ {
5384
+ pattern: /error TS\d+|TypeError|SyntaxError|ReferenceError/i,
5385
+ category: "build_error",
5386
+ summary: "TypeScript/JavaScript compilation error",
5387
+ suggestion: "Fix the type errors locally before deploying. Run `bun run typecheck`."
5388
+ },
5389
+ {
5390
+ pattern: /ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|getaddrinfo/i,
5391
+ category: "network_error",
5392
+ summary: "Network connectivity issue during build",
5393
+ suggestion: "Server may have DNS issues or firewall blocking outbound connections. Check server network."
5394
+ },
5395
+ {
5396
+ pattern: /OOMKilled|out of memory|Cannot allocate memory/i,
5397
+ category: "build_error",
5398
+ summary: "Out of memory during build",
5399
+ suggestion: "Server ran out of RAM. Use a build server or increase server memory."
5400
+ },
5401
+ {
5402
+ pattern: /context deadline exceeded|timed out/i,
5403
+ category: "timeout",
5404
+ summary: "Operation timed out",
5405
+ suggestion: "Build took too long. Check if server is overloaded or network is slow."
5406
+ },
5407
+ {
5408
+ pattern: /permission denied|EACCES/i,
5409
+ category: "docker_error",
5410
+ summary: "Permission denied",
5411
+ suggestion: "Check file permissions in Dockerfile. Ensure non-root user has access to needed paths."
5412
+ },
5413
+ {
5414
+ pattern: /exec.*not found|command not found/i,
5415
+ category: "build_error",
5416
+ summary: "Command not found during build",
5417
+ suggestion: "A required binary is missing in the Docker image. Add it to the Dockerfile or use a different base image."
5418
+ }
5419
+ ];
5420
+ });
5421
+
5191
5422
  // ../../../node_modules/.bun/commander@12.1.0/node_modules/commander/esm.mjs
5192
5423
  var import__ = __toESM(require_commander(), 1);
5193
5424
  var {
@@ -5693,25 +5924,8 @@ var chalk = createChalk();
5693
5924
  var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
5694
5925
  var source_default = chalk;
5695
5926
 
5696
- // ../../../node_modules/.bun/@mks2508+no-throw@0.1.0/node_modules/@mks2508/no-throw/dist/index.mjs
5697
- function ok(value) {
5698
- return {
5699
- ok: true,
5700
- value
5701
- };
5702
- }
5703
- function err(error) {
5704
- return {
5705
- ok: false,
5706
- error
5707
- };
5708
- }
5709
- function isOk(result) {
5710
- return result.ok;
5711
- }
5712
- function isErr(result) {
5713
- return !result.ok;
5714
- }
5927
+ // src/cli/commands/create.ts
5928
+ init_dist();
5715
5929
 
5716
5930
  // ../../../node_modules/.bun/ora@8.2.0/node_modules/ora/index.js
5717
5931
  import process9 from "node:process";
@@ -6523,6 +6737,9 @@ function ora(options) {
6523
6737
  return new Ora(options);
6524
6738
  }
6525
6739
 
6740
+ // src/coolify/index.ts
6741
+ init_dist();
6742
+
6526
6743
  // ../../../node_modules/.bun/@mks2508+better-logger@4.0.0/node_modules/@mks2508/better-logger/dist/chunks/environment-COWvu6Wz.js
6527
6744
  function isMinifiedFile(filename) {
6528
6745
  const minifiedPatterns = [
@@ -11131,6 +11348,7 @@ var stylePresets = {
11131
11348
  };
11132
11349
 
11133
11350
  // src/coolify/config.ts
11351
+ init_dist();
11134
11352
  import { readFile, writeFile, mkdir } from "node:fs/promises";
11135
11353
  import { existsSync } from "node:fs";
11136
11354
  import { homedir } from "node:os";
@@ -11201,7 +11419,11 @@ class CoolifyService {
11201
11419
  async request(endpoint, options = {}) {
11202
11420
  const startTime = Date.now();
11203
11421
  if (!this.baseUrl || !this.token) {
11204
- return { error: "Coolify not configured", status: 0, durationMs: Date.now() - startTime };
11422
+ return {
11423
+ error: "Coolify not configured",
11424
+ status: 0,
11425
+ durationMs: Date.now() - startTime
11426
+ };
11205
11427
  }
11206
11428
  try {
11207
11429
  const baseUrl = this.baseUrl.replace(/\/+$/, "");
@@ -11222,7 +11444,11 @@ class CoolifyService {
11222
11444
  data = text ? JSON.parse(text) : undefined;
11223
11445
  } catch {
11224
11446
  if (!response.ok) {
11225
- return { error: text || `HTTP ${response.status}`, status: response.status, durationMs };
11447
+ return {
11448
+ error: text || `HTTP ${response.status}`,
11449
+ status: response.status,
11450
+ durationMs
11451
+ };
11226
11452
  }
11227
11453
  }
11228
11454
  if (!response.ok) {
@@ -11258,7 +11484,7 @@ class CoolifyService {
11258
11484
  params.set("force", "true");
11259
11485
  const endpoint = `/deploy${params.toString() ? `?${params.toString()}` : ""}`;
11260
11486
  const result = await this.request(endpoint, {
11261
- method: "POST"
11487
+ method: "GET"
11262
11488
  });
11263
11489
  if (result.error) {
11264
11490
  log.error(`Deployment failed: ${result.error}`);
@@ -11291,7 +11517,9 @@ class CoolifyService {
11291
11517
  "private-deploy-key": "/applications/private-deploy-key",
11292
11518
  dockerfile: "/applications/dockerfile",
11293
11519
  "docker-image": "/applications/docker-image",
11294
- "docker-compose": "/applications/docker-compose"
11520
+ "docker-compose": "/applications/docker-compose",
11521
+ dockerimage: "/applications/dockerimage",
11522
+ dockercompose: "/applications/dockercompose"
11295
11523
  };
11296
11524
  const endpoint = endpointMap[appType] || "/applications/public";
11297
11525
  const body = {
@@ -11355,7 +11583,9 @@ class CoolifyService {
11355
11583
  const listResult = await this.request(`/applications/${appUuid}/envs`);
11356
11584
  const existing = listResult.data?.find((v) => v.key === key);
11357
11585
  if (existing) {
11358
- await this.request(`/applications/${appUuid}/envs/${existing.uuid}`, { method: "DELETE" });
11586
+ await this.request(`/applications/${appUuid}/envs/${existing.uuid}`, {
11587
+ method: "DELETE"
11588
+ });
11359
11589
  const repost = await this.request(`/applications/${appUuid}/envs`, {
11360
11590
  method: "POST",
11361
11591
  body: JSON.stringify({ key, value, is_preview: false })
@@ -11387,7 +11617,7 @@ class CoolifyService {
11387
11617
  log.success(`Environment variables retrieved for ${appUuid}`);
11388
11618
  return ok(result.data || []);
11389
11619
  }
11390
- async setEnvironmentVariable(appUuid, key, value, isBuildTime = false) {
11620
+ async setEnvironmentVariable(appUuid, key, value, _isBuildTime = false) {
11391
11621
  log.info(`Setting environment variable ${key} for ${appUuid}`);
11392
11622
  const existingVars = await this.getEnvironmentVariables(appUuid);
11393
11623
  if (isErr(existingVars)) {
@@ -11446,8 +11676,17 @@ class CoolifyService {
11446
11676
  }
11447
11677
  return ok(result.data?.status || "unknown");
11448
11678
  }
11449
- async listServers() {
11450
- const result = await this.request("/servers");
11679
+ async listServers(page, perPage) {
11680
+ let endpoint = "/servers";
11681
+ const params = new URLSearchParams;
11682
+ if (page)
11683
+ params.set("page", page.toString());
11684
+ if (perPage)
11685
+ params.set("per_page", perPage.toString());
11686
+ if (params.toString()) {
11687
+ endpoint += `?${params.toString()}`;
11688
+ }
11689
+ const result = await this.request(endpoint);
11451
11690
  if (result.error) {
11452
11691
  return err(new Error(result.error));
11453
11692
  }
@@ -11463,14 +11702,32 @@ class CoolifyService {
11463
11702
  log.success(`Server details retrieved: ${serverUuid}`);
11464
11703
  return ok(result.data);
11465
11704
  }
11466
- async listGithubApps() {
11467
- const result = await this.request("/github-apps");
11705
+ async listGithubApps(page, perPage) {
11706
+ let endpoint = "/github-apps";
11707
+ const params = new URLSearchParams;
11708
+ if (page)
11709
+ params.set("page", page.toString());
11710
+ if (perPage)
11711
+ params.set("per_page", perPage.toString());
11712
+ if (params.toString()) {
11713
+ endpoint += `?${params.toString()}`;
11714
+ }
11715
+ const result = await this.request(endpoint);
11468
11716
  if (result.error)
11469
11717
  return err(new Error(result.error));
11470
11718
  return ok(result.data || []);
11471
11719
  }
11472
- async listProjects() {
11473
- const result = await this.request("/projects");
11720
+ async listProjects(page, perPage) {
11721
+ let endpoint = "/projects";
11722
+ const params = new URLSearchParams;
11723
+ if (page)
11724
+ params.set("page", page.toString());
11725
+ if (perPage)
11726
+ params.set("per_page", perPage.toString());
11727
+ if (params.toString()) {
11728
+ endpoint += `?${params.toString()}`;
11729
+ }
11730
+ const result = await this.request(endpoint);
11474
11731
  if (result.error) {
11475
11732
  return err(new Error(result.error));
11476
11733
  }
@@ -11499,8 +11756,17 @@ class CoolifyService {
11499
11756
  log.success(`Environments retrieved for project ${projectUuid}`);
11500
11757
  return ok(result.data?.environments || []);
11501
11758
  }
11502
- async listTeams() {
11503
- const result = await this.request("/teams");
11759
+ async listTeams(page, perPage) {
11760
+ let endpoint = "/teams";
11761
+ const params = new URLSearchParams;
11762
+ if (page)
11763
+ params.set("page", page.toString());
11764
+ if (perPage)
11765
+ params.set("per_page", perPage.toString());
11766
+ if (params.toString()) {
11767
+ endpoint += `?${params.toString()}`;
11768
+ }
11769
+ const result = await this.request(endpoint);
11504
11770
  if (result.error) {
11505
11771
  return err(new Error(result.error));
11506
11772
  }
@@ -11513,7 +11779,7 @@ class CoolifyService {
11513
11779
  }
11514
11780
  return ok(result.data?.destinations || []);
11515
11781
  }
11516
- async listApplications(teamId, projectId) {
11782
+ async listApplications(teamId, projectId, page, perPage) {
11517
11783
  log.info("Listing applications");
11518
11784
  let endpoint = "/applications";
11519
11785
  const params = new URLSearchParams;
@@ -11521,6 +11787,10 @@ class CoolifyService {
11521
11787
  params.set("team_id", teamId);
11522
11788
  if (projectId)
11523
11789
  params.set("project_id", projectId);
11790
+ if (page)
11791
+ params.set("page", page.toString());
11792
+ if (perPage)
11793
+ params.set("per_page", perPage.toString());
11524
11794
  if (params.toString()) {
11525
11795
  endpoint += `?${params.toString()}`;
11526
11796
  }
@@ -11532,9 +11802,20 @@ class CoolifyService {
11532
11802
  log.success(`Listed ${result.data?.length || 0} applications`);
11533
11803
  return ok(result.data || []);
11534
11804
  }
11535
- async deleteApplication(appUuid) {
11805
+ async deleteApplication(appUuid, options) {
11536
11806
  log.info(`Deleting application ${appUuid}`);
11537
- const result = await this.request(`/applications/${appUuid}`, {
11807
+ const params = new URLSearchParams;
11808
+ if (options?.deleteConfigurations)
11809
+ params.set("delete_configurations", "true");
11810
+ if (options?.deleteVolumes)
11811
+ params.set("delete_volumes", "true");
11812
+ if (options?.dockerCleanup)
11813
+ params.set("docker_cleanup", "true");
11814
+ if (options?.deleteConnectedNetworks)
11815
+ params.set("delete_connected_networks", "true");
11816
+ const queryString = params.toString();
11817
+ const endpoint = `/applications/${appUuid}${queryString ? `?${queryString}` : ""}`;
11818
+ const result = await this.request(endpoint, {
11538
11819
  method: "DELETE"
11539
11820
  });
11540
11821
  if (result.error) {
@@ -11592,7 +11873,9 @@ class CoolifyService {
11592
11873
  if (options.follow)
11593
11874
  params.set("follow", "true");
11594
11875
  if (options.tail)
11595
- params.set("tail", options.tail.toString());
11876
+ params.set("lines", options.tail.toString());
11877
+ if (options.serviceName)
11878
+ params.set("service_name", options.serviceName);
11596
11879
  const endpoint = `/applications/${appUuid}/logs${params.toString() ? `?${params.toString()}` : ""}`;
11597
11880
  const result = await this.request(endpoint);
11598
11881
  if (result.error) {
@@ -11608,9 +11891,35 @@ class CoolifyService {
11608
11891
  timestamp: new Date().toISOString()
11609
11892
  });
11610
11893
  }
11894
+ async executeCommand(appUuid, command) {
11895
+ log.info(`Executing command on application ${appUuid}`);
11896
+ const result = await this.request(`/applications/${appUuid}/execute-command`, {
11897
+ method: "POST",
11898
+ body: JSON.stringify({ command })
11899
+ });
11900
+ if (result.error) {
11901
+ log.error(`Failed to execute command: ${result.error}`);
11902
+ return err(new Error(result.error));
11903
+ }
11904
+ log.success(`Command executed on ${appUuid}`);
11905
+ return ok(result.data || { message: "Command executed" });
11906
+ }
11907
+ async bulkUpdateEnvironmentVariables(appUuid, envVars) {
11908
+ log.info(`Bulk updating ${envVars.length} env vars for ${appUuid}`);
11909
+ const result = await this.request(`/applications/${appUuid}/envs/bulk`, {
11910
+ method: "PATCH",
11911
+ body: JSON.stringify(envVars)
11912
+ });
11913
+ if (result.error) {
11914
+ log.error(`Failed to bulk update env vars: ${result.error}`);
11915
+ return err(new Error(result.error));
11916
+ }
11917
+ log.success(`Bulk updated ${envVars.length} env vars for ${appUuid}`);
11918
+ return ok(result.data || { message: "Environment variables updated" });
11919
+ }
11611
11920
  async getApplicationDeploymentHistory(appUuid) {
11612
11921
  log.info(`Getting deployment history for ${appUuid}`);
11613
- const result = await this.request(`/applications/${appUuid}/deployments`);
11922
+ const result = await this.request(`/deployments/applications/${appUuid}`);
11614
11923
  if (result.error) {
11615
11924
  log.error(`Failed to get deployment history: ${result.error}`);
11616
11925
  return err(new Error(result.error));
@@ -11618,10 +11927,17 @@ class CoolifyService {
11618
11927
  log.success(`Deployment history retrieved for ${appUuid}`);
11619
11928
  return ok(result.data?.deployments || []);
11620
11929
  }
11621
- async startApplication(appUuid) {
11930
+ async startApplication(appUuid, options) {
11622
11931
  log.info(`Starting application ${appUuid}`);
11623
- const result = await this.request(`/applications/${appUuid}/start`, {
11624
- method: "POST"
11932
+ const params = new URLSearchParams;
11933
+ if (options?.force)
11934
+ params.set("force", "true");
11935
+ if (options?.instantDeploy)
11936
+ params.set("instant_deploy", "true");
11937
+ const queryString = params.toString();
11938
+ const endpoint = `/applications/${appUuid}/start${queryString ? `?${queryString}` : ""}`;
11939
+ const result = await this.request(endpoint, {
11940
+ method: "GET"
11625
11941
  });
11626
11942
  if (result.error) {
11627
11943
  log.error(`Failed to start application: ${result.error}`);
@@ -11632,9 +11948,7 @@ class CoolifyService {
11632
11948
  }
11633
11949
  async stopApplication(appUuid) {
11634
11950
  log.info(`Stopping application ${appUuid}`);
11635
- const result = await this.request(`/applications/${appUuid}/stop`, {
11636
- method: "POST"
11637
- });
11951
+ const result = await this.request(`/applications/${appUuid}/stop`, { method: "GET" });
11638
11952
  if (result.error) {
11639
11953
  log.error(`Failed to stop application: ${result.error}`);
11640
11954
  return err(new Error(result.error));
@@ -11644,9 +11958,7 @@ class CoolifyService {
11644
11958
  }
11645
11959
  async restartApplication(appUuid) {
11646
11960
  log.info(`Restarting application ${appUuid}`);
11647
- const result = await this.request(`/applications/${appUuid}/restart`, {
11648
- method: "POST"
11649
- });
11961
+ const result = await this.request(`/applications/${appUuid}/restart`, { method: "GET" });
11650
11962
  if (result.error) {
11651
11963
  log.error(`Failed to restart application: ${result.error}`);
11652
11964
  return err(new Error(result.error));
@@ -11654,281 +11966,1529 @@ class CoolifyService {
11654
11966
  log.success(`Application restarted: ${appUuid}`);
11655
11967
  return ok(result.data);
11656
11968
  }
11657
- async listDeployments() {
11658
- log.info("Listing active deployments");
11659
- const result = await this.request("/deployments");
11660
- if (result.error) {
11661
- log.error(`Failed to list deployments: ${result.error}`);
11662
- return err(new Error(result.error));
11969
+ async getVersion() {
11970
+ log.info("Getting Coolify version");
11971
+ if (!this.baseUrl || !this.token) {
11972
+ return err(new Error("Coolify not configured"));
11663
11973
  }
11664
- log.success(`Listed ${result.data?.length || 0} active deployments`);
11665
- return ok(result.data || []);
11666
- }
11667
- async getDeployment(deploymentUuid) {
11668
- log.info(`Getting deployment details for ${deploymentUuid}`);
11669
- const result = await this.request(`/deployments/${deploymentUuid}`);
11670
- if (result.error) {
11671
- log.error(`Failed to get deployment: ${result.error}`);
11672
- return err(new Error(result.error));
11974
+ try {
11975
+ const baseUrl = this.baseUrl.replace(/\/+$/, "");
11976
+ const url = `${baseUrl}/api/v1/version`;
11977
+ const response = await fetch(url, {
11978
+ headers: {
11979
+ Authorization: `Bearer ${this.token}`
11980
+ }
11981
+ });
11982
+ if (!response.ok) {
11983
+ return err(new Error(`HTTP ${response.status}: ${response.statusText}`));
11984
+ }
11985
+ const version = (await response.text()).trim();
11986
+ log.success(`Coolify version: ${version}`);
11987
+ return ok({ version });
11988
+ } catch (error) {
11989
+ const message = error instanceof Error ? error.message : "Unknown error";
11990
+ return err(new Error(message));
11673
11991
  }
11674
- log.success(`Deployment details retrieved: ${deploymentUuid}`);
11675
- return ok(result.data);
11676
11992
  }
11677
- async getApplicationDeployments(appUuid, skip = 0, take = 10) {
11678
- log.info(`Getting deployments for application ${appUuid}`);
11993
+ async listDatabases(page, perPage) {
11994
+ log.info("Listing databases");
11995
+ let endpoint = "/databases";
11679
11996
  const params = new URLSearchParams;
11680
- if (skip > 0)
11681
- params.set("skip", skip.toString());
11682
- if (take !== 10)
11683
- params.set("take", take.toString());
11684
- const endpoint = `/applications/${appUuid}/deployments${params.toString() ? `?${params.toString()}` : ""}`;
11997
+ if (page)
11998
+ params.set("page", page.toString());
11999
+ if (perPage)
12000
+ params.set("per_page", perPage.toString());
12001
+ if (params.toString())
12002
+ endpoint += `?${params.toString()}`;
11685
12003
  const result = await this.request(endpoint);
11686
- if (result.error) {
11687
- log.error(`Failed to get application deployments: ${result.error}`);
12004
+ if (result.error)
11688
12005
  return err(new Error(result.error));
11689
- }
11690
- const deployments = result.data?.deployments || [];
11691
- log.success(`Retrieved ${deployments.length} deployments for ${appUuid}`);
11692
- return ok(deployments);
12006
+ log.success(`Listed ${result.data?.length || 0} databases`);
12007
+ return ok(result.data || []);
11693
12008
  }
11694
- }
11695
- var instance = null;
11696
- function getCoolifyService() {
11697
- if (!instance) {
11698
- instance = new CoolifyService;
12009
+ async getDatabase(uuid) {
12010
+ log.info(`Getting database ${uuid}`);
12011
+ const result = await this.request(`/databases/${uuid}`);
12012
+ if (result.error)
12013
+ return err(new Error(result.error));
12014
+ return ok(result.data);
11699
12015
  }
11700
- return instance;
11701
- }
11702
-
11703
- // src/cli/commands/create.ts
11704
- async function createCommand2(options) {
11705
- const spinner = ora("Initializing Coolify connection...").start();
11706
- try {
11707
- const coolify = getCoolifyService();
11708
- const initResult = await coolify.init();
11709
- if (isErr(initResult)) {
11710
- spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
11711
- return;
11712
- }
11713
- let environmentUuid = options.environment;
11714
- if (!environmentUuid) {
11715
- spinner.text = "Fetching project environments...";
11716
- const envResult = await coolify.getProjectEnvironments(options.project);
11717
- if (isOk(envResult) && envResult.value.length > 0) {
11718
- environmentUuid = envResult.value[0].uuid;
11719
- const envName = envResult.value[0].name;
11720
- spinner.info(source_default.cyan(`Using environment: ${envName} (${environmentUuid.slice(0, 8)}...)`));
11721
- } else {
11722
- spinner.fail(source_default.red("No environments found for project. Please specify --environment <uuid>"));
11723
- return;
11724
- }
11725
- }
11726
- if (!environmentUuid) {
11727
- spinner.fail(source_default.red("Environment UUID is required"));
11728
- return;
11729
- }
11730
- spinner.text = "Creating application...";
11731
- const result = await coolify.createApplication({
11732
- name: options.name,
11733
- description: options.description,
11734
- projectUuid: options.project,
11735
- environmentUuid,
11736
- serverUuid: options.server,
11737
- type: options.type || "public",
11738
- githubRepoUrl: options.repo,
11739
- branch: options.branch || "main",
11740
- buildPack: options.buildPack || "dockerfile",
11741
- portsExposes: options.ports || "3000",
11742
- dockerImage: options.dockerImage,
11743
- dockerCompose: options.dockerCompose,
11744
- dockerComposeLocation: options.dockerComposeLocation,
11745
- dockerfileLocation: options.dockerfileLocation,
11746
- baseDirectory: options.baseDirectory
11747
- }, (percent, message) => {
11748
- spinner.text = `${source_default.bold(`[${percent}%]`)} ${message}`;
12016
+ async createDatabase(dbType, data) {
12017
+ log.info(`Creating ${dbType} database`);
12018
+ const result = await this.request(`/databases/${dbType}`, {
12019
+ method: "POST",
12020
+ body: JSON.stringify(data)
11749
12021
  });
11750
- if (isOk(result)) {
11751
- spinner.succeed(source_default.green(`Application created! UUID: ${source_default.cyan(result.value.uuid?.slice(0, 8))}`));
11752
- console.log(` Full UUID: ${source_default.cyan(result.value.uuid)}`);
11753
- console.log(` Name: ${source_default.cyan(options.name)}`);
11754
- console.log(` Type: ${source_default.cyan(options.type || "public")}`);
11755
- console.log(` Next steps:`);
11756
- console.log(` 1. Set environment variables: ${source_default.yellow("coolify-mcp env " + result.value.uuid?.slice(0, 8))}`);
11757
- console.log(` 2. Deploy application: ${source_default.yellow("coolify-mcp deploy " + result.value.uuid?.slice(0, 8))}`);
11758
- } else {
11759
- spinner.fail(source_default.red(`Creation failed: ${result.error.message}`));
11760
- }
11761
- } catch (error) {
11762
- spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12022
+ if (result.error)
12023
+ return err(new Error(result.error));
12024
+ log.success(`Database created: ${result.data?.uuid}`);
12025
+ return ok(result.data);
11763
12026
  }
11764
- }
11765
-
11766
- // src/cli/commands/deploy.ts
11767
- async function deployCommand(uuid, options) {
11768
- const spinner = ora("Initializing Coolify connection...").start();
11769
- try {
11770
- const coolify = getCoolifyService();
11771
- const initResult = await coolify.init();
11772
- if (isErr(initResult)) {
11773
- spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
11774
- return;
11775
- }
11776
- spinner.text = "Triggering deployment...";
11777
- const result = await coolify.deploy({
11778
- uuid,
11779
- force: options.force,
11780
- tag: options.tag
11781
- }, (percent, message) => {
11782
- spinner.text = `${source_default.bold(`[${percent}%]`)} ${message}`;
12027
+ async updateDatabase(uuid, data) {
12028
+ log.info(`Updating database ${uuid}`);
12029
+ const result = await this.request(`/databases/${uuid}`, {
12030
+ method: "PATCH",
12031
+ body: JSON.stringify(data)
11783
12032
  });
11784
- if (isOk(result)) {
11785
- spinner.succeed(source_default.green(`Deployment triggered! UUID: ${source_default.cyan(result.value.deploymentUuid?.slice(0, 8))}`));
11786
- console.log(` Resource UUID: ${source_default.cyan(result.value.resourceUuid?.slice(0, 8))}`);
11787
- } else {
11788
- spinner.fail(source_default.red(`Deployment failed: ${result.error.message}`));
11789
- }
11790
- } catch (error) {
11791
- spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
11792
- }
12033
+ if (result.error)
12034
+ return err(new Error(result.error));
12035
+ log.success(`Database updated: ${uuid}`);
12036
+ return ok(result.data);
12037
+ }
12038
+ async deleteDatabase(uuid, options) {
12039
+ log.info(`Deleting database ${uuid}`);
12040
+ const params = new URLSearchParams;
12041
+ if (options?.deleteConfigurations)
12042
+ params.set("delete_configurations", "true");
12043
+ if (options?.deleteVolumes)
12044
+ params.set("delete_volumes", "true");
12045
+ if (options?.dockerCleanup)
12046
+ params.set("docker_cleanup", "true");
12047
+ if (options?.deleteConnectedNetworks)
12048
+ params.set("delete_connected_networks", "true");
12049
+ const queryString = params.toString();
12050
+ const endpoint = `/databases/${uuid}${queryString ? `?${queryString}` : ""}`;
12051
+ const result = await this.request(endpoint, {
12052
+ method: "DELETE"
12053
+ });
12054
+ if (result.error)
12055
+ return err(new Error(result.error));
12056
+ log.success(`Database deleted: ${uuid}`);
12057
+ return ok({ success: true, message: "Database deleted" });
12058
+ }
12059
+ async startDatabase(uuid) {
12060
+ log.info(`Starting database ${uuid}`);
12061
+ const result = await this.request(`/databases/${uuid}/start`, { method: "GET" });
12062
+ if (result.error)
12063
+ return err(new Error(result.error));
12064
+ log.success(`Database started: ${uuid}`);
12065
+ return ok(result.data || { message: "Database started" });
12066
+ }
12067
+ async stopDatabase(uuid) {
12068
+ log.info(`Stopping database ${uuid}`);
12069
+ const result = await this.request(`/databases/${uuid}/stop`, { method: "GET" });
12070
+ if (result.error)
12071
+ return err(new Error(result.error));
12072
+ log.success(`Database stopped: ${uuid}`);
12073
+ return ok(result.data || { message: "Database stopped" });
12074
+ }
12075
+ async restartDatabase(uuid) {
12076
+ log.info(`Restarting database ${uuid}`);
12077
+ const result = await this.request(`/databases/${uuid}/restart`, { method: "GET" });
12078
+ if (result.error)
12079
+ return err(new Error(result.error));
12080
+ log.success(`Database restarted: ${uuid}`);
12081
+ return ok(result.data || { message: "Database restarted" });
12082
+ }
12083
+ async listDatabaseBackups(databaseUuid) {
12084
+ log.info(`Listing backups for database ${databaseUuid}`);
12085
+ const result = await this.request(`/databases/${databaseUuid}/backups`);
12086
+ if (result.error)
12087
+ return err(new Error(result.error));
12088
+ return ok(result.data || []);
12089
+ }
12090
+ async getDatabaseBackup(databaseUuid, backupUuid) {
12091
+ const result = await this.request(`/databases/${databaseUuid}/backups/${backupUuid}`);
12092
+ if (result.error)
12093
+ return err(new Error(result.error));
12094
+ return ok(result.data);
12095
+ }
12096
+ async createDatabaseBackup(databaseUuid, data) {
12097
+ log.info(`Creating backup for database ${databaseUuid}`);
12098
+ const result = await this.request(`/databases/${databaseUuid}/backups`, { method: "POST", body: JSON.stringify(data) });
12099
+ if (result.error)
12100
+ return err(new Error(result.error));
12101
+ log.success("Database backup created");
12102
+ return ok(result.data);
12103
+ }
12104
+ async updateDatabaseBackup(databaseUuid, backupUuid, data) {
12105
+ const result = await this.request(`/databases/${databaseUuid}/backups/${backupUuid}`, { method: "PATCH", body: JSON.stringify(data) });
12106
+ if (result.error)
12107
+ return err(new Error(result.error));
12108
+ return ok(result.data || { message: "Backup updated" });
12109
+ }
12110
+ async deleteDatabaseBackup(databaseUuid, backupUuid) {
12111
+ const result = await this.request(`/databases/${databaseUuid}/backups/${backupUuid}`, { method: "DELETE" });
12112
+ if (result.error)
12113
+ return err(new Error(result.error));
12114
+ return ok(result.data || { message: "Backup deleted" });
12115
+ }
12116
+ async listServices(page, perPage) {
12117
+ log.info("Listing services");
12118
+ let endpoint = "/services";
12119
+ const params = new URLSearchParams;
12120
+ if (page)
12121
+ params.set("page", page.toString());
12122
+ if (perPage)
12123
+ params.set("per_page", perPage.toString());
12124
+ if (params.toString())
12125
+ endpoint += `?${params.toString()}`;
12126
+ const result = await this.request(endpoint);
12127
+ if (result.error)
12128
+ return err(new Error(result.error));
12129
+ log.success(`Listed ${result.data?.length || 0} services`);
12130
+ return ok(result.data || []);
12131
+ }
12132
+ async getService(uuid) {
12133
+ log.info(`Getting service ${uuid}`);
12134
+ const result = await this.request(`/services/${uuid}`);
12135
+ if (result.error)
12136
+ return err(new Error(result.error));
12137
+ return ok(result.data);
12138
+ }
12139
+ async createService(data) {
12140
+ log.info("Creating service");
12141
+ const result = await this.request("/services", {
12142
+ method: "POST",
12143
+ body: JSON.stringify(data)
12144
+ });
12145
+ if (result.error)
12146
+ return err(new Error(result.error));
12147
+ log.success(`Service created: ${result.data?.uuid}`);
12148
+ return ok(result.data);
12149
+ }
12150
+ async updateService(uuid, data) {
12151
+ log.info(`Updating service ${uuid}`);
12152
+ const result = await this.request(`/services/${uuid}`, {
12153
+ method: "PATCH",
12154
+ body: JSON.stringify(data)
12155
+ });
12156
+ if (result.error)
12157
+ return err(new Error(result.error));
12158
+ log.success(`Service updated: ${uuid}`);
12159
+ return ok(result.data);
12160
+ }
12161
+ async deleteService(uuid, options) {
12162
+ log.info(`Deleting service ${uuid}`);
12163
+ const params = new URLSearchParams;
12164
+ if (options?.deleteConfigurations)
12165
+ params.set("delete_configurations", "true");
12166
+ if (options?.deleteVolumes)
12167
+ params.set("delete_volumes", "true");
12168
+ if (options?.dockerCleanup)
12169
+ params.set("docker_cleanup", "true");
12170
+ if (options?.deleteConnectedNetworks)
12171
+ params.set("delete_connected_networks", "true");
12172
+ const queryString = params.toString();
12173
+ const endpoint = `/services/${uuid}${queryString ? `?${queryString}` : ""}`;
12174
+ const result = await this.request(endpoint, {
12175
+ method: "DELETE"
12176
+ });
12177
+ if (result.error)
12178
+ return err(new Error(result.error));
12179
+ log.success(`Service deleted: ${uuid}`);
12180
+ return ok({ success: true, message: "Service deleted" });
12181
+ }
12182
+ async startService(uuid) {
12183
+ log.info(`Starting service ${uuid}`);
12184
+ const result = await this.request(`/services/${uuid}/start`, { method: "GET" });
12185
+ if (result.error)
12186
+ return err(new Error(result.error));
12187
+ log.success(`Service started: ${uuid}`);
12188
+ return ok(result.data || { message: "Service started" });
12189
+ }
12190
+ async stopService(uuid) {
12191
+ log.info(`Stopping service ${uuid}`);
12192
+ const result = await this.request(`/services/${uuid}/stop`, { method: "GET" });
12193
+ if (result.error)
12194
+ return err(new Error(result.error));
12195
+ log.success(`Service stopped: ${uuid}`);
12196
+ return ok(result.data || { message: "Service stopped" });
12197
+ }
12198
+ async restartService(uuid) {
12199
+ log.info(`Restarting service ${uuid}`);
12200
+ const result = await this.request(`/services/${uuid}/restart`, { method: "GET" });
12201
+ if (result.error)
12202
+ return err(new Error(result.error));
12203
+ log.success(`Service restarted: ${uuid}`);
12204
+ return ok(result.data || { message: "Service restarted" });
12205
+ }
12206
+ async listServiceEnvVars(uuid) {
12207
+ const result = await this.request(`/services/${uuid}/envs`);
12208
+ if (result.error)
12209
+ return err(new Error(result.error));
12210
+ return ok(result.data || []);
12211
+ }
12212
+ async createServiceEnvVar(uuid, data) {
12213
+ const result = await this.request(`/services/${uuid}/envs`, { method: "POST", body: JSON.stringify(data) });
12214
+ if (result.error)
12215
+ return err(new Error(result.error));
12216
+ return ok(result.data);
12217
+ }
12218
+ async getServerResources(serverUuid) {
12219
+ log.info(`Getting resources for server ${serverUuid}`);
12220
+ const result = await this.request(`/servers/${serverUuid}/resources`);
12221
+ if (result.error)
12222
+ return err(new Error(result.error));
12223
+ return ok(result.data || []);
12224
+ }
12225
+ async getServerDomains(serverUuid) {
12226
+ log.info(`Getting domains for server ${serverUuid}`);
12227
+ const result = await this.request(`/servers/${serverUuid}/domains`);
12228
+ if (result.error)
12229
+ return err(new Error(result.error));
12230
+ return ok(result.data || []);
12231
+ }
12232
+ async validateServer(serverUuid) {
12233
+ log.info(`Validating server ${serverUuid}`);
12234
+ const result = await this.request(`/servers/${serverUuid}/validate`);
12235
+ if (result.error)
12236
+ return err(new Error(result.error));
12237
+ return ok(result.data || { message: "Server validated" });
12238
+ }
12239
+ async createServer(data) {
12240
+ log.info("Creating server");
12241
+ const result = await this.request("/servers", {
12242
+ method: "POST",
12243
+ body: JSON.stringify(data)
12244
+ });
12245
+ if (result.error)
12246
+ return err(new Error(result.error));
12247
+ log.success(`Server created: ${result.data?.uuid}`);
12248
+ return ok(result.data);
12249
+ }
12250
+ async deleteServer(serverUuid) {
12251
+ log.info(`Deleting server ${serverUuid}`);
12252
+ const result = await this.request(`/servers/${serverUuid}`, { method: "DELETE" });
12253
+ if (result.error)
12254
+ return err(new Error(result.error));
12255
+ log.success(`Server deleted: ${serverUuid}`);
12256
+ return ok(result.data || { message: "Server deleted" });
12257
+ }
12258
+ async updateProject(uuid, data) {
12259
+ log.info(`Updating project ${uuid}`);
12260
+ const result = await this.request(`/projects/${uuid}`, {
12261
+ method: "PATCH",
12262
+ body: JSON.stringify(data)
12263
+ });
12264
+ if (result.error)
12265
+ return err(new Error(result.error));
12266
+ log.success(`Project updated: ${uuid}`);
12267
+ return ok(result.data);
12268
+ }
12269
+ async deleteProject(uuid) {
12270
+ log.info(`Deleting project ${uuid}`);
12271
+ const result = await this.request(`/projects/${uuid}`, { method: "DELETE" });
12272
+ if (result.error)
12273
+ return err(new Error(result.error));
12274
+ log.success(`Project deleted: ${uuid}`);
12275
+ return ok(result.data || { message: "Project deleted" });
12276
+ }
12277
+ async createProjectEnvironment(projectUuid, data) {
12278
+ log.info(`Creating environment in project ${projectUuid}`);
12279
+ const result = await this.request(`/projects/${projectUuid}/environments`, { method: "POST", body: JSON.stringify(data) });
12280
+ if (result.error)
12281
+ return err(new Error(result.error));
12282
+ log.success("Environment created");
12283
+ return ok(result.data);
12284
+ }
12285
+ async getCurrentTeam() {
12286
+ log.info("Getting current team");
12287
+ const result = await this.request("/teams/current");
12288
+ if (result.error)
12289
+ return err(new Error(result.error));
12290
+ return ok(result.data);
12291
+ }
12292
+ async getTeam(id) {
12293
+ log.info(`Getting team ${id}`);
12294
+ const result = await this.request(`/teams/${id}`);
12295
+ if (result.error)
12296
+ return err(new Error(result.error));
12297
+ return ok(result.data);
12298
+ }
12299
+ async getTeamMembers(id) {
12300
+ log.info(`Getting members for team ${id}`);
12301
+ const result = await this.request(`/teams/${id}/members`);
12302
+ if (result.error)
12303
+ return err(new Error(result.error));
12304
+ return ok(result.data || []);
12305
+ }
12306
+ async cancelDeployment(deploymentUuid) {
12307
+ log.info(`Cancelling deployment ${deploymentUuid}`);
12308
+ const result = await this.request(`/deployments/${deploymentUuid}/cancel`, { method: "POST" });
12309
+ if (result.error)
12310
+ return err(new Error(result.error));
12311
+ log.success(`Deployment cancelled: ${deploymentUuid}`);
12312
+ return ok(result.data || { message: "Deployment cancelled" });
12313
+ }
12314
+ async listPrivateKeys() {
12315
+ log.info("Listing private keys");
12316
+ const result = await this.request("/security/keys");
12317
+ if (result.error)
12318
+ return err(new Error(result.error));
12319
+ return ok(result.data || []);
12320
+ }
12321
+ async getPrivateKey(uuid) {
12322
+ const result = await this.request(`/security/keys/${uuid}`);
12323
+ if (result.error)
12324
+ return err(new Error(result.error));
12325
+ return ok(result.data);
12326
+ }
12327
+ async createPrivateKey(data) {
12328
+ log.info("Creating private key");
12329
+ const result = await this.request("/security/keys", {
12330
+ method: "POST",
12331
+ body: JSON.stringify(data)
12332
+ });
12333
+ if (result.error)
12334
+ return err(new Error(result.error));
12335
+ log.success(`Private key created: ${result.data?.uuid}`);
12336
+ return ok(result.data);
12337
+ }
12338
+ async updatePrivateKey(uuid, data) {
12339
+ const result = await this.request(`/security/keys/${uuid}`, { method: "PATCH", body: JSON.stringify(data) });
12340
+ if (result.error)
12341
+ return err(new Error(result.error));
12342
+ return ok(result.data);
12343
+ }
12344
+ async deletePrivateKey(uuid) {
12345
+ log.info(`Deleting private key ${uuid}`);
12346
+ const result = await this.request(`/security/keys/${uuid}`, { method: "DELETE" });
12347
+ if (result.error)
12348
+ return err(new Error(result.error));
12349
+ log.success(`Private key deleted: ${uuid}`);
12350
+ return ok(result.data || { message: "Private key deleted" });
12351
+ }
12352
+ async createGitHubApp(data) {
12353
+ log.info("Creating GitHub App");
12354
+ const result = await this.request("/github-apps", { method: "POST", body: JSON.stringify(data) });
12355
+ if (result.error)
12356
+ return err(new Error(result.error));
12357
+ return ok(result.data);
12358
+ }
12359
+ async updateGitHubApp(id, data) {
12360
+ const result = await this.request(`/github-apps/${id}`, { method: "PATCH", body: JSON.stringify(data) });
12361
+ if (result.error)
12362
+ return err(new Error(result.error));
12363
+ return ok(result.data || { message: "GitHub App updated" });
12364
+ }
12365
+ async deleteGitHubApp(id) {
12366
+ log.info(`Deleting GitHub App ${id}`);
12367
+ const result = await this.request(`/github-apps/${id}`, { method: "DELETE" });
12368
+ if (result.error)
12369
+ return err(new Error(result.error));
12370
+ return ok(result.data || { message: "GitHub App deleted" });
12371
+ }
12372
+ async listDeployments(page, perPage) {
12373
+ log.info("Listing active deployments");
12374
+ let endpoint = "/deployments";
12375
+ const params = new URLSearchParams;
12376
+ if (page)
12377
+ params.set("page", page.toString());
12378
+ if (perPage)
12379
+ params.set("per_page", perPage.toString());
12380
+ if (params.toString()) {
12381
+ endpoint += `?${params.toString()}`;
12382
+ }
12383
+ const result = await this.request(endpoint);
12384
+ if (result.error) {
12385
+ log.error(`Failed to list deployments: ${result.error}`);
12386
+ return err(new Error(result.error));
12387
+ }
12388
+ log.success(`Listed ${result.data?.length || 0} active deployments`);
12389
+ return ok(result.data || []);
12390
+ }
12391
+ async getDeployment(deploymentUuid) {
12392
+ log.info(`Getting deployment details for ${deploymentUuid}`);
12393
+ const result = await this.request(`/deployments/${deploymentUuid}`);
12394
+ if (result.error) {
12395
+ log.error(`Failed to get deployment: ${result.error}`);
12396
+ return err(new Error(result.error));
12397
+ }
12398
+ log.success(`Deployment details retrieved: ${deploymentUuid}`);
12399
+ return ok(result.data);
12400
+ }
12401
+ async getDeploymentLogs(deploymentUuid) {
12402
+ log.info(`Getting deployment logs for ${deploymentUuid}`);
12403
+ const result = await this.request(`/deployments/${deploymentUuid}`);
12404
+ if (result.error) {
12405
+ log.error(`Failed to get deployment logs: ${result.error}`);
12406
+ return err(new Error(result.error));
12407
+ }
12408
+ log.success(`Deployment logs retrieved: ${deploymentUuid}`);
12409
+ return ok({
12410
+ status: result.data?.status || "unknown",
12411
+ logs: result.data?.logs || "",
12412
+ deployment_uuid: result.data?.deployment_uuid || deploymentUuid
12413
+ });
12414
+ }
12415
+ async getApplicationDeployments(appUuid, skip = 0, take = 10) {
12416
+ log.info(`Getting deployments for application ${appUuid}`);
12417
+ const params = new URLSearchParams;
12418
+ if (skip > 0)
12419
+ params.set("skip", skip.toString());
12420
+ if (take !== 10)
12421
+ params.set("take", take.toString());
12422
+ const endpoint = `/applications/${appUuid}/deployments${params.toString() ? `?${params.toString()}` : ""}`;
12423
+ const result = await this.request(endpoint);
12424
+ if (result.error) {
12425
+ log.error(`Failed to get application deployments: ${result.error}`);
12426
+ return err(new Error(result.error));
12427
+ }
12428
+ const deployments = result.data?.deployments || [];
12429
+ log.success(`Retrieved ${deployments.length} deployments for ${appUuid}`);
12430
+ return ok(deployments);
12431
+ }
12432
+ async listApplicationDeployments(appUuid) {
12433
+ log.info(`Listing deployments for application ${appUuid}`);
12434
+ const result = await this.request(`/deployments/applications/${appUuid}`);
12435
+ if (result.error) {
12436
+ log.error(`Failed to list application deployments: ${result.error}`);
12437
+ return err(new Error(result.error));
12438
+ }
12439
+ const deployments = result.data?.deployments || [];
12440
+ log.success(`Listed ${deployments.length} deployments for ${appUuid}`);
12441
+ return ok(deployments);
12442
+ }
12443
+ async resolveApplication(query) {
12444
+ log.info(`Resolving application: ${query}`);
12445
+ if (this.isLikelyUuid(query)) {
12446
+ const apps2 = await this.listApplications();
12447
+ if (isErr(apps2))
12448
+ return err(apps2.error);
12449
+ const match = apps2.value.find((a) => a.uuid === query);
12450
+ if (match)
12451
+ return ok(match);
12452
+ }
12453
+ const apps = await this.listApplications();
12454
+ if (isErr(apps))
12455
+ return err(apps.error);
12456
+ const lowerQuery = query.toLowerCase();
12457
+ const matches = apps.value.filter((a) => a.name?.toLowerCase() === lowerQuery || a.fqdn?.toLowerCase().includes(lowerQuery) || a.uuid.startsWith(query));
12458
+ if (matches.length === 1)
12459
+ return ok(matches[0]);
12460
+ if (matches.length === 0) {
12461
+ return err(new Error(`No application found matching "${query}". Use 'list' to see available applications.`));
12462
+ }
12463
+ const names = matches.map((a) => ` - ${a.name} (${a.uuid})`).join(`
12464
+ `);
12465
+ return err(new Error(`Multiple applications match "${query}":
12466
+ ${names}
12467
+ Please use the full UUID.`));
12468
+ }
12469
+ async resolveServer(query) {
12470
+ log.info(`Resolving server: ${query}`);
12471
+ const servers = await this.listServers();
12472
+ if (isErr(servers))
12473
+ return err(servers.error);
12474
+ const lowerQuery = query.toLowerCase();
12475
+ const match = servers.value.find((s) => s.uuid === query || s.name?.toLowerCase() === lowerQuery || s.ip === query || s.uuid.startsWith(query));
12476
+ if (match)
12477
+ return ok(match);
12478
+ return err(new Error(`No server found matching "${query}". Use 'servers' to see available servers.`));
12479
+ }
12480
+ isLikelyUuid(query) {
12481
+ if (/^[a-z0-9]{20,}$/i.test(query))
12482
+ return true;
12483
+ if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(query))
12484
+ return true;
12485
+ return false;
12486
+ }
12487
+ async diagnoseApplication(query) {
12488
+ log.info(`Diagnosing application: ${query}`);
12489
+ const appResult = await this.resolveApplication(query);
12490
+ if (isErr(appResult))
12491
+ return err(appResult.error);
12492
+ const app = appResult.value;
12493
+ const issues = [];
12494
+ const [deploymentsResult, envResult, logsResult] = await Promise.all([
12495
+ this.getApplicationDeploymentHistory(app.uuid),
12496
+ this.getEnvironmentVariables(app.uuid),
12497
+ this.getApplicationLogs(app.uuid, { tail: 20 })
12498
+ ]);
12499
+ const deployments = isErr(deploymentsResult) ? [] : deploymentsResult.value;
12500
+ const envVarCount = isErr(envResult) ? 0 : envResult.value.length;
12501
+ const recentLogs = isErr(logsResult) ? [] : logsResult.value.logs;
12502
+ if (app.status?.includes("stopped")) {
12503
+ issues.push("Application is stopped");
12504
+ }
12505
+ if (!app.fqdn) {
12506
+ issues.push("No domain configured");
12507
+ }
12508
+ if (envVarCount === 0) {
12509
+ issues.push("No environment variables set");
12510
+ }
12511
+ const recentDeploys = deployments.slice(-5);
12512
+ const failedDeploys = recentDeploys.filter((d) => d.status?.includes("failed"));
12513
+ if (failedDeploys.length > 0) {
12514
+ issues.push(`${failedDeploys.length} of last ${recentDeploys.length} deployments failed`);
12515
+ }
12516
+ log.success(`Diagnosis complete for ${app.name}`);
12517
+ return ok({
12518
+ application: app,
12519
+ recentDeployments: recentDeploys,
12520
+ envVarCount,
12521
+ recentLogs,
12522
+ issues
12523
+ });
12524
+ }
12525
+ async diagnoseServer(query) {
12526
+ log.info(`Diagnosing server: ${query}`);
12527
+ const serverResult = await this.resolveServer(query);
12528
+ if (isErr(serverResult))
12529
+ return err(serverResult.error);
12530
+ const server = serverResult.value;
12531
+ const issues = [];
12532
+ const [resourcesResult, domainsResult] = await Promise.all([
12533
+ this.getServerResources(server.uuid),
12534
+ this.getServerDomains(server.uuid)
12535
+ ]);
12536
+ const resources = isErr(resourcesResult) ? [] : resourcesResult.value;
12537
+ const domains = isErr(domainsResult) ? [] : domainsResult.value;
12538
+ if (!server.is_reachable) {
12539
+ issues.push("Server is not reachable");
12540
+ }
12541
+ if (!server.is_usable) {
12542
+ issues.push("Server is not usable");
12543
+ }
12544
+ if (resources.length === 0) {
12545
+ issues.push("No resources deployed on this server");
12546
+ }
12547
+ log.success(`Server diagnosis complete for ${server.name}`);
12548
+ return ok({ server, resources, domains, issues });
12549
+ }
12550
+ async findInfrastructureIssues() {
12551
+ log.info("Scanning infrastructure for issues");
12552
+ const [serversR, appsR, dbsR, svcsR] = await Promise.all([
12553
+ this.listServers(),
12554
+ this.listApplications(),
12555
+ this.listDatabases(),
12556
+ this.listServices()
12557
+ ]);
12558
+ const servers = isErr(serversR) ? [] : serversR.value;
12559
+ const apps = isErr(appsR) ? [] : appsR.value;
12560
+ const dbs = isErr(dbsR) ? [] : dbsR.value;
12561
+ const svcs = isErr(svcsR) ? [] : svcsR.value;
12562
+ const issues = [];
12563
+ for (const server of servers) {
12564
+ if (!server.is_reachable) {
12565
+ issues.push({
12566
+ type: "server",
12567
+ resource: server.name,
12568
+ uuid: server.uuid,
12569
+ message: "Server unreachable"
12570
+ });
12571
+ }
12572
+ }
12573
+ for (const app of apps) {
12574
+ if (app.status?.includes("stopped")) {
12575
+ issues.push({
12576
+ type: "application",
12577
+ resource: app.name,
12578
+ uuid: app.uuid,
12579
+ message: "Application stopped"
12580
+ });
12581
+ }
12582
+ if (app.status?.includes("failed") || app.status?.includes("error")) {
12583
+ issues.push({
12584
+ type: "application",
12585
+ resource: app.name,
12586
+ uuid: app.uuid,
12587
+ message: `Status: ${app.status}`
12588
+ });
12589
+ }
12590
+ }
12591
+ for (const db of dbs) {
12592
+ if (db.status?.includes("stopped") || db.status?.includes("exited")) {
12593
+ issues.push({
12594
+ type: "database",
12595
+ resource: db.name,
12596
+ uuid: db.uuid,
12597
+ message: `Database stopped: ${db.status}`
12598
+ });
12599
+ }
12600
+ }
12601
+ for (const svc of svcs) {
12602
+ if (svc.status?.includes("stopped") || svc.status?.includes("exited")) {
12603
+ issues.push({
12604
+ type: "service",
12605
+ resource: svc.name,
12606
+ uuid: svc.uuid,
12607
+ message: `Service stopped: ${svc.status}`
12608
+ });
12609
+ }
12610
+ }
12611
+ log.success(`Infrastructure scan complete: ${issues.length} issue(s) found`);
12612
+ return ok({
12613
+ totalServers: servers.length,
12614
+ totalApps: apps.length,
12615
+ totalDatabases: dbs.length,
12616
+ totalServices: svcs.length,
12617
+ issues
12618
+ });
12619
+ }
12620
+ async restartProjectApps(projectUuid) {
12621
+ log.info(`Restarting all apps in project ${projectUuid}`);
12622
+ const appsResult = await this.listApplications(undefined, projectUuid);
12623
+ if (isErr(appsResult))
12624
+ return err(appsResult.error);
12625
+ const apps = appsResult.value;
12626
+ const failed = [];
12627
+ let succeeded = 0;
12628
+ for (const app of apps) {
12629
+ const result = await this.restartApplication(app.uuid);
12630
+ if (isErr(result)) {
12631
+ failed.push(`${app.name} (${app.uuid}): ${result.error.message}`);
12632
+ } else {
12633
+ succeeded++;
12634
+ }
12635
+ }
12636
+ log.success(`Restarted ${succeeded}/${apps.length} apps in project`);
12637
+ return ok({ total: apps.length, succeeded, failed });
12638
+ }
12639
+ async redeployProjectApps(projectUuid, force = false) {
12640
+ log.info(`Redeploying all apps in project ${projectUuid}`);
12641
+ const appsResult = await this.listApplications(undefined, projectUuid);
12642
+ if (isErr(appsResult))
12643
+ return err(appsResult.error);
12644
+ const apps = appsResult.value;
12645
+ const failed = [];
12646
+ let succeeded = 0;
12647
+ for (const app of apps) {
12648
+ const result = await this.deploy({ uuid: app.uuid, force });
12649
+ if (isErr(result)) {
12650
+ failed.push(`${app.name} (${app.uuid}): ${result.error.message}`);
12651
+ } else {
12652
+ succeeded++;
12653
+ }
12654
+ }
12655
+ log.success(`Redeployed ${succeeded}/${apps.length} apps in project`);
12656
+ return ok({ total: apps.length, succeeded, failed });
12657
+ }
12658
+ async stopAllApps() {
12659
+ log.info("Stopping all applications");
12660
+ const appsResult = await this.listApplications();
12661
+ if (isErr(appsResult))
12662
+ return err(appsResult.error);
12663
+ const running = appsResult.value.filter((a) => !a.status?.includes("stopped"));
12664
+ const failed = [];
12665
+ let succeeded = 0;
12666
+ for (const app of running) {
12667
+ const result = await this.stopApplication(app.uuid);
12668
+ if (isErr(result)) {
12669
+ failed.push(`${app.name} (${app.uuid}): ${result.error.message}`);
12670
+ } else {
12671
+ succeeded++;
12672
+ }
12673
+ }
12674
+ log.success(`Stopped ${succeeded}/${running.length} apps`);
12675
+ return ok({ total: running.length, succeeded, failed });
12676
+ }
12677
+ async listApplicationSummaries() {
12678
+ const result = await this.listApplications();
12679
+ if (isErr(result))
12680
+ return err(result.error);
12681
+ return ok(result.value.map((a) => ({
12682
+ uuid: a.uuid,
12683
+ name: a.name,
12684
+ status: a.status,
12685
+ fqdn: a.fqdn || null
12686
+ })));
12687
+ }
12688
+ async listServerSummaries() {
12689
+ const result = await this.listServers();
12690
+ if (isErr(result))
12691
+ return err(result.error);
12692
+ return ok(result.value.map((s) => ({
12693
+ uuid: s.uuid,
12694
+ name: s.name,
12695
+ ip: s.ip || "",
12696
+ is_reachable: s.is_reachable || false
12697
+ })));
12698
+ }
12699
+ async listDatabaseSummaries() {
12700
+ const result = await this.listDatabases();
12701
+ if (isErr(result))
12702
+ return err(result.error);
12703
+ return ok(result.value.map((d) => ({
12704
+ uuid: d.uuid,
12705
+ name: d.name,
12706
+ type: d.type,
12707
+ status: d.status
12708
+ })));
12709
+ }
12710
+ async listServiceSummaries() {
12711
+ const result = await this.listServices();
12712
+ if (isErr(result))
12713
+ return err(result.error);
12714
+ return ok(result.value.map((s) => ({
12715
+ uuid: s.uuid,
12716
+ name: s.name,
12717
+ type: s.type,
12718
+ status: s.status
12719
+ })));
12720
+ }
12721
+ }
12722
+ var instance = null;
12723
+ function getCoolifyService() {
12724
+ if (!instance) {
12725
+ instance = new CoolifyService;
12726
+ }
12727
+ return instance;
12728
+ }
12729
+
12730
+ // src/cli/commands/create.ts
12731
+ async function createCommand2(options) {
12732
+ const spinner = ora("Initializing Coolify connection...").start();
12733
+ try {
12734
+ const coolify = getCoolifyService();
12735
+ const initResult = await coolify.init();
12736
+ if (isErr(initResult)) {
12737
+ spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
12738
+ return;
12739
+ }
12740
+ let environmentUuid = options.environment;
12741
+ if (!environmentUuid) {
12742
+ spinner.text = "Fetching project environments...";
12743
+ const envResult = await coolify.getProjectEnvironments(options.project);
12744
+ if (isOk(envResult) && envResult.value.length > 0) {
12745
+ environmentUuid = envResult.value[0].uuid;
12746
+ const envName = envResult.value[0].name;
12747
+ spinner.info(source_default.cyan(`Using environment: ${envName} (${environmentUuid})`));
12748
+ } else {
12749
+ spinner.fail(source_default.red("No environments found for project. Please specify --environment <uuid>"));
12750
+ return;
12751
+ }
12752
+ }
12753
+ if (!environmentUuid) {
12754
+ spinner.fail(source_default.red("Environment UUID is required"));
12755
+ return;
12756
+ }
12757
+ spinner.text = "Creating application...";
12758
+ const result = await coolify.createApplication({
12759
+ name: options.name,
12760
+ description: options.description,
12761
+ projectUuid: options.project,
12762
+ environmentUuid,
12763
+ serverUuid: options.server,
12764
+ type: options.type || "public",
12765
+ githubRepoUrl: options.repo,
12766
+ branch: options.branch || "main",
12767
+ buildPack: options.buildPack || "dockerfile",
12768
+ portsExposes: options.ports || "3000",
12769
+ dockerImage: options.dockerImage,
12770
+ dockerCompose: options.dockerCompose,
12771
+ dockerComposeLocation: options.dockerComposeLocation,
12772
+ dockerfileLocation: options.dockerfileLocation,
12773
+ baseDirectory: options.baseDirectory
12774
+ }, (percent, message) => {
12775
+ spinner.text = `${source_default.bold(`[${percent}%]`)} ${message}`;
12776
+ });
12777
+ if (isOk(result)) {
12778
+ spinner.succeed(source_default.green(`Application created! UUID: ${source_default.cyan(result.value.uuid)}`));
12779
+ console.log(` Name: ${source_default.cyan(options.name)}`);
12780
+ console.log(` Type: ${source_default.cyan(options.type || "public")}`);
12781
+ console.log(` Next steps:`);
12782
+ console.log(` 1. Set environment variables: ${source_default.yellow("coolify-mcp env " + result.value.uuid)}`);
12783
+ console.log(` 2. Deploy application: ${source_default.yellow("coolify-mcp deploy " + result.value.uuid)}`);
12784
+ } else {
12785
+ spinner.fail(source_default.red(`Creation failed: ${result.error.message}`));
12786
+ }
12787
+ } catch (error) {
12788
+ spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12789
+ }
12790
+ }
12791
+
12792
+ // src/cli/commands/deploy.ts
12793
+ init_dist();
12794
+
12795
+ // src/cli/coolify-state.ts
12796
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
12797
+ import { join as join2 } from "node:path";
12798
+ var STATE_FILE = ".coolify.json";
12799
+ function loadCoolifyState() {
12800
+ const statePath = join2(process.cwd(), STATE_FILE);
12801
+ if (!existsSync2(statePath)) {
12802
+ return null;
12803
+ }
12804
+ try {
12805
+ const content = readFileSync(statePath, "utf-8");
12806
+ const state = JSON.parse(content);
12807
+ if (!state.appUuid) {
12808
+ return null;
12809
+ }
12810
+ return state;
12811
+ } catch {
12812
+ return null;
12813
+ }
12814
+ }
12815
+ function resolveUuid(uuid, field = "appUuid") {
12816
+ if (uuid)
12817
+ return uuid;
12818
+ const state = loadCoolifyState();
12819
+ if (!state)
12820
+ return null;
12821
+ const value = state[field];
12822
+ return typeof value === "string" ? value : null;
12823
+ }
12824
+
12825
+ // src/cli/commands/deploy.ts
12826
+ async function deployCommand(uuid, options) {
12827
+ const resolvedUuid = resolveUuid(uuid);
12828
+ if (!resolvedUuid) {
12829
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found in current directory"));
12830
+ return;
12831
+ }
12832
+ uuid = resolvedUuid;
12833
+ const spinner = ora("Initializing Coolify connection...").start();
12834
+ try {
12835
+ const coolify = getCoolifyService();
12836
+ const initResult = await coolify.init();
12837
+ if (isErr(initResult)) {
12838
+ spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
12839
+ return;
12840
+ }
12841
+ spinner.text = "Triggering deployment...";
12842
+ const result = await coolify.deploy({
12843
+ uuid,
12844
+ force: options.force,
12845
+ tag: options.tag
12846
+ }, (percent, message) => {
12847
+ spinner.text = `${source_default.bold(`[${percent}%]`)} ${message}`;
12848
+ });
12849
+ if (isOk(result)) {
12850
+ spinner.succeed(source_default.green(`Deployment triggered! UUID: ${source_default.cyan(result.value.deploymentUuid)}`));
12851
+ console.log(` Resource UUID: ${source_default.cyan(result.value.resourceUuid)}`);
12852
+ } else {
12853
+ spinner.fail(source_default.red(`Deployment failed: ${result.error.message}`));
12854
+ }
12855
+ } catch (error) {
12856
+ spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12857
+ }
12858
+ }
12859
+
12860
+ // src/cli/commands/list.ts
12861
+ init_dist();
12862
+ var import_cli_table32 = __toESM(require_table(), 1);
12863
+
12864
+ // src/utils/format.ts
12865
+ var import_cli_table3 = __toESM(require_table(), 1);
12866
+ function getTerminalWidth2() {
12867
+ return process.stdout.columns || 80;
12868
+ }
12869
+ function createTable(headers, colWidths) {
12870
+ const columns = getTerminalWidth2();
12871
+ return new import_cli_table3.default({
12872
+ head: headers.map((h) => source_default.cyan(h)),
12873
+ colWidths: colWidths || calculateColumnWidths(columns, headers.length)
12874
+ });
12875
+ }
12876
+ function calculateColumnWidths(totalWidth, numColumns) {
12877
+ const padding = 4;
12878
+ const availableWidth = totalWidth - padding * numColumns;
12879
+ const colWidth = Math.floor(availableWidth / numColumns);
12880
+ return Array(numColumns).fill(colWidth);
12881
+ }
12882
+ function formatStatus(status) {
12883
+ const statusMap = {
12884
+ running: source_default.green("● Running"),
12885
+ "running:unknown": source_default.green("● Running"),
12886
+ stopped: source_default.red("○ Stopped"),
12887
+ restarting: source_default.yellow("◐ Restarting"),
12888
+ error: source_default.red("✗ Error"),
12889
+ deploying: source_default.yellow("◐ Deploying")
12890
+ };
12891
+ return statusMap[status] || status;
12892
+ }
12893
+
12894
+ // src/cli/commands/list.ts
12895
+ async function listCommand(options) {
12896
+ const coolify = getCoolifyService();
12897
+ const initResult = await coolify.init();
12898
+ if (isErr(initResult)) {
12899
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
12900
+ return;
12901
+ }
12902
+ const result = await coolify.listApplications(options.team, options.project);
12903
+ if (isErr(result)) {
12904
+ console.error(source_default.red(`Error: ${result.error.message}`));
12905
+ return;
12906
+ }
12907
+ const apps = result.value;
12908
+ if (apps.length === 0) {
12909
+ console.log(source_default.yellow("No applications found"));
12910
+ return;
12911
+ }
12912
+ const table = new import_cli_table32.default({
12913
+ head: [
12914
+ source_default.cyan("UUID"),
12915
+ source_default.cyan("Name"),
12916
+ source_default.cyan("Status"),
12917
+ source_default.cyan("Server")
12918
+ ]
12919
+ });
12920
+ for (const app of apps) {
12921
+ table.push([
12922
+ app.uuid,
12923
+ app.name,
12924
+ formatStatus(app.status),
12925
+ app.destination?.server?.name || "N/A"
12926
+ ]);
12927
+ }
12928
+ console.log(table.toString());
12929
+ console.log(source_default.gray(`Total: ${apps.length} application(s)`));
12930
+ }
12931
+
12932
+ // src/cli/commands/logs.ts
12933
+ init_dist();
12934
+ async function logsCommand(uuid, options) {
12935
+ const resolvedUuid = resolveUuid(uuid);
12936
+ if (!resolvedUuid) {
12937
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
12938
+ return;
12939
+ }
12940
+ uuid = resolvedUuid;
12941
+ const coolify = getCoolifyService();
12942
+ const initResult = await coolify.init();
12943
+ if (isErr(initResult)) {
12944
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
12945
+ return;
12946
+ }
12947
+ const result = await coolify.getApplicationLogs(uuid, {
12948
+ tail: options.lines || 50
12949
+ });
12950
+ if (isErr(result)) {
12951
+ console.error(source_default.red(`Error: ${result.error.message}`));
12952
+ return;
12953
+ }
12954
+ const logs = result.value;
12955
+ if (logs.logs.length === 0) {
12956
+ console.log(source_default.yellow("No logs available"));
12957
+ return;
12958
+ }
12959
+ console.log(source_default.gray(`Application logs (${logs.logs.length} lines):
12960
+ `));
12961
+ for (const line of logs.logs) {
12962
+ console.log(line);
12963
+ }
12964
+ if (options.follow) {
12965
+ console.log(source_default.yellow(`
12966
+ Follow mode not yet implemented`));
12967
+ }
12968
+ }
12969
+
12970
+ // src/cli/commands/servers.ts
12971
+ init_dist();
12972
+ async function serversCommand(_options = {}) {
12973
+ const coolify = getCoolifyService();
12974
+ const initResult = await coolify.init();
12975
+ if (isErr(initResult)) {
12976
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
12977
+ return;
12978
+ }
12979
+ const result = await coolify.listServers();
12980
+ if (isErr(result)) {
12981
+ console.error(source_default.red(`Error: ${result.error.message}`));
12982
+ return;
12983
+ }
12984
+ const servers = result.value;
12985
+ if (servers.length === 0) {
12986
+ console.log(source_default.yellow("No servers found"));
12987
+ return;
12988
+ }
12989
+ const table = createTable(["UUID", "Name", "IP", "Status"], [28, 25, 20, 15]);
12990
+ for (const server of servers) {
12991
+ const statusColor = server.is_usable ? source_default.green : source_default.red;
12992
+ table.push([
12993
+ server.uuid,
12994
+ server.name,
12995
+ server.ip || "N/A",
12996
+ statusColor(server.is_usable ? "● Usable" : "○ Unusable")
12997
+ ]);
12998
+ }
12999
+ console.log(table.toString());
13000
+ console.log(source_default.gray(`Total: ${servers.length} server(s)`));
13001
+ }
13002
+
13003
+ // src/cli/commands/projects.ts
13004
+ init_dist();
13005
+ var import_cli_table33 = __toESM(require_table(), 1);
13006
+ async function projectsCommand(options = {}) {
13007
+ const spinner = ora("Connecting to Coolify...").start();
13008
+ try {
13009
+ const coolify = getCoolifyService();
13010
+ const initResult = await coolify.init();
13011
+ if (isErr(initResult)) {
13012
+ spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
13013
+ return;
13014
+ }
13015
+ if (options.create) {
13016
+ spinner.text = `Creating project "${options.create}"...`;
13017
+ const createResult = await coolify.createProject(options.create, options.description);
13018
+ if (isOk(createResult)) {
13019
+ spinner.succeed(source_default.green(`Project created: ${source_default.cyan(createResult.value.uuid)}`));
13020
+ console.log(` Name: ${source_default.cyan(options.create)}`);
13021
+ console.log(` UUID: ${source_default.cyan(createResult.value.uuid)}`);
13022
+ } else {
13023
+ spinner.fail(source_default.red(`Failed to create project: ${createResult.error.message}`));
13024
+ }
13025
+ return;
13026
+ }
13027
+ spinner.text = "Fetching projects...";
13028
+ const result = await coolify.listProjects();
13029
+ if (isOk(result)) {
13030
+ spinner.succeed(source_default.green("Projects retrieved"));
13031
+ const projects = result.value;
13032
+ if (projects.length === 0) {
13033
+ console.log(source_default.yellow("No projects found"));
13034
+ return;
13035
+ }
13036
+ const table = new import_cli_table33.default({
13037
+ head: [
13038
+ source_default.cyan("UUID"),
13039
+ source_default.cyan("Name"),
13040
+ source_default.cyan("Description")
13041
+ ]
13042
+ });
13043
+ for (const project of projects) {
13044
+ table.push([project.uuid, project.name, project.description || "-"]);
13045
+ }
13046
+ console.log(table.toString());
13047
+ console.log(source_default.gray(`Total: ${projects.length} project(s)`));
13048
+ } else {
13049
+ spinner.fail(source_default.red(`Failed to fetch projects: ${result.error.message}`));
13050
+ }
13051
+ } catch (error) {
13052
+ spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
13053
+ }
13054
+ }
13055
+
13056
+ // src/cli/commands/environments.ts
13057
+ init_dist();
13058
+ var import_cli_table34 = __toESM(require_table(), 1);
13059
+ async function environmentsCommand(projectUuid, _options = {}) {
13060
+ const spinner = ora("Connecting to Coolify...").start();
13061
+ try {
13062
+ const coolify = getCoolifyService();
13063
+ const initResult = await coolify.init();
13064
+ if (isErr(initResult)) {
13065
+ spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
13066
+ return;
13067
+ }
13068
+ spinner.text = `Fetching environments for project ${projectUuid}...`;
13069
+ const result = await coolify.getProjectEnvironments(projectUuid);
13070
+ if (isOk(result)) {
13071
+ spinner.succeed(source_default.green("Environments retrieved"));
13072
+ const environments = result.value;
13073
+ if (environments.length === 0) {
13074
+ console.log(source_default.yellow("No environments found for this project"));
13075
+ return;
13076
+ }
13077
+ const table = new import_cli_table34.default({
13078
+ head: [
13079
+ source_default.cyan("UUID"),
13080
+ source_default.cyan("Name"),
13081
+ source_default.cyan("Description")
13082
+ ]
13083
+ });
13084
+ for (const env2 of environments) {
13085
+ table.push([env2.uuid, env2.name, env2.description || "-"]);
13086
+ }
13087
+ console.log(table.toString());
13088
+ console.log(source_default.gray(`Total: ${environments.length} environment(s)`));
13089
+ } else {
13090
+ spinner.fail(source_default.red(`Failed to fetch environments: ${result.error.message}`));
13091
+ }
13092
+ } catch (error) {
13093
+ spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
13094
+ }
13095
+ }
13096
+
13097
+ // src/cli/commands/config.ts
13098
+ init_dist();
13099
+ import { existsSync as existsSync3 } from "node:fs";
13100
+ async function configCommand(action, args) {
13101
+ if (action === "set") {
13102
+ if (!args.key || !args.value) {
13103
+ console.error(source_default.red('Error: key and value are required for "set" command'));
13104
+ console.log(source_default.gray("Usage: coolify-mcp config set <key> <value>"));
13105
+ console.log(source_default.gray("Keys: url, token"));
13106
+ return;
13107
+ }
13108
+ const result = await loadConfig();
13109
+ if (isOk(result)) {
13110
+ const config = result.value;
13111
+ if (args.key === "url") {
13112
+ config.url = args.value;
13113
+ } else if (args.key === "token") {
13114
+ config.token = args.value;
13115
+ } else {
13116
+ console.error(source_default.red(`Error: Unknown key "${args.key}"`));
13117
+ return;
13118
+ }
13119
+ const saveResult = await saveConfig(config);
13120
+ if (isOk(saveResult)) {
13121
+ console.log(source_default.green(`Config updated: ${args.key} = ${args.value}`));
13122
+ } else {
13123
+ console.error(source_default.red(`Error: ${saveResult.error.message}`));
13124
+ }
13125
+ }
13126
+ } else if (action === "get") {
13127
+ const result = await loadConfig();
13128
+ if (isOk(result)) {
13129
+ const config = result.value;
13130
+ console.log(source_default.cyan("Current configuration:"));
13131
+ console.log(` URL: ${source_default.gray(config.url || "(not set)")}`);
13132
+ console.log(` Token: ${source_default.gray(config.token ? "(set)" : "(not set)")}`);
13133
+ } else {
13134
+ console.error(source_default.red(`Error: ${result.error.message}`));
13135
+ }
13136
+ } else if (action === "path") {
13137
+ console.log(source_default.cyan("Config file:"));
13138
+ console.log(` ${CONFIG_FILE}`);
13139
+ if (existsSync3(CONFIG_FILE)) {
13140
+ console.log(source_default.gray(" Status: File exists"));
13141
+ } else {
13142
+ console.log(source_default.yellow(" Status: File does not exist"));
13143
+ }
13144
+ } else {
13145
+ console.log(source_default.cyan("Coolify MCP Configuration"));
13146
+ console.log();
13147
+ console.log(source_default.gray("Commands:"));
13148
+ console.log(" coolify-mcp config set <key> <value> Set a config value");
13149
+ console.log(" coolify-mcp config get Show current config");
13150
+ console.log(" coolify-mcp config path Show config file path");
13151
+ console.log();
13152
+ console.log(source_default.gray("Keys:"));
13153
+ console.log(" url - Coolify instance URL");
13154
+ console.log(" token - Coolify API token");
13155
+ console.log();
13156
+ console.log(source_default.gray("Environment variables:"));
13157
+ console.log(" COOLIFY_URL - Coolify instance URL");
13158
+ console.log(" COOLIFY_TOKEN - Coolify API token");
13159
+ }
11793
13160
  }
11794
13161
 
11795
- // src/cli/commands/list.ts
11796
- var import_cli_table32 = __toESM(require_table(), 1);
11797
-
11798
- // src/utils/format.ts
11799
- var import_cli_table3 = __toESM(require_table(), 1);
11800
- function getTerminalWidth2() {
11801
- return process.stdout.columns || 80;
11802
- }
11803
- function createTable(headers, colWidths) {
11804
- const columns = getTerminalWidth2();
11805
- return new import_cli_table3.default({
11806
- head: headers.map((h) => source_default.cyan(h)),
11807
- colWidths: colWidths || calculateColumnWidths(columns, headers.length)
11808
- });
13162
+ // src/cli/commands/env.ts
13163
+ init_dist();
13164
+ async function envCommand(uuid, options = {}) {
13165
+ const resolvedUuid = resolveUuid(uuid);
13166
+ if (!resolvedUuid) {
13167
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
13168
+ return;
13169
+ }
13170
+ uuid = resolvedUuid;
13171
+ const coolify = getCoolifyService();
13172
+ const initResult = await coolify.init();
13173
+ if (isErr(initResult)) {
13174
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
13175
+ return;
13176
+ }
13177
+ if (options.set) {
13178
+ const [key, ...valueParts] = options.set.split("=");
13179
+ const value = valueParts.join("=");
13180
+ if (!key || value === undefined) {
13181
+ console.error(source_default.red("Error: Invalid format. Use --set KEY=VALUE"));
13182
+ return;
13183
+ }
13184
+ const result2 = await coolify.setEnvironmentVariable(uuid, key, value, options.buildtime ?? false);
13185
+ if (isErr(result2)) {
13186
+ console.error(source_default.red(`Error: ${result2.error.message}`));
13187
+ return;
13188
+ }
13189
+ console.log(source_default.green(`✓ Set ${source_default.bold(key)} for ${uuid}`));
13190
+ return;
13191
+ }
13192
+ if (options.delete) {
13193
+ const result2 = await coolify.deleteEnvironmentVariable(uuid, options.delete);
13194
+ if (isErr(result2)) {
13195
+ console.error(source_default.red(`Error: ${result2.error.message}`));
13196
+ return;
13197
+ }
13198
+ console.log(source_default.green(`✓ Deleted ${source_default.bold(options.delete)} from ${uuid}`));
13199
+ return;
13200
+ }
13201
+ const result = await coolify.getEnvironmentVariables(uuid);
13202
+ if (isErr(result)) {
13203
+ console.error(source_default.red(`Error: ${result.error.message}`));
13204
+ return;
13205
+ }
13206
+ const envVars = result.value;
13207
+ if (envVars.length === 0) {
13208
+ console.log(source_default.yellow("No environment variables found"));
13209
+ return;
13210
+ }
13211
+ console.log(source_default.cyan(`Environment variables (${envVars.length}):
13212
+ `));
13213
+ const runtimeVars = envVars.filter((ev) => ev.is_runtime);
13214
+ const buildtimeVars = envVars.filter((ev) => ev.is_buildtime);
13215
+ if (runtimeVars.length > 0) {
13216
+ console.log(source_default.yellow.bold("Runtime:"));
13217
+ for (const ev of runtimeVars) {
13218
+ const required = ev.is_required ? source_default.red(" *") : "";
13219
+ console.log(` ${source_default.green(ev.key)}${required} = ${source_default.gray(ev.value)}`);
13220
+ }
13221
+ console.log();
13222
+ }
13223
+ if (buildtimeVars.length > 0) {
13224
+ console.log(source_default.blue.bold("Buildtime:"));
13225
+ for (const ev of buildtimeVars) {
13226
+ console.log(` ${source_default.green(ev.key)} = ${source_default.gray(ev.value)}`);
13227
+ }
13228
+ }
11809
13229
  }
11810
- function calculateColumnWidths(totalWidth, numColumns) {
11811
- const padding = 4;
11812
- const availableWidth = totalWidth - padding * numColumns;
11813
- const colWidth = Math.floor(availableWidth / numColumns);
11814
- return Array(numColumns).fill(colWidth);
13230
+
13231
+ // src/cli/commands/update.ts
13232
+ init_dist();
13233
+ async function updateCommand(options) {
13234
+ const uuid = resolveUuid(options.uuid);
13235
+ if (!uuid) {
13236
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
13237
+ return;
13238
+ }
13239
+ options.uuid = uuid;
13240
+ console.log(source_default.cyan(`Updating application ${source_default.bold(uuid)}...`));
13241
+ const service = getCoolifyService();
13242
+ const initResult = await service.init();
13243
+ if (isErr(initResult)) {
13244
+ console.error(source_default.red("Failed to initialize Coolify service"));
13245
+ console.error(source_default.gray(initResult.error.message));
13246
+ process.exit(1);
13247
+ }
13248
+ const updateOptions = {};
13249
+ if (options.name)
13250
+ updateOptions.name = options.name;
13251
+ if (options.description)
13252
+ updateOptions.description = options.description;
13253
+ if (options.buildPack)
13254
+ updateOptions.buildPack = options.buildPack;
13255
+ if (options.gitBranch)
13256
+ updateOptions.gitBranch = options.gitBranch;
13257
+ if (options.ports)
13258
+ updateOptions.portsExposes = options.ports;
13259
+ if (options.installCommand)
13260
+ updateOptions.installCommand = options.installCommand;
13261
+ if (options.buildCommand)
13262
+ updateOptions.buildCommand = options.buildCommand;
13263
+ if (options.startCommand)
13264
+ updateOptions.startCommand = options.startCommand;
13265
+ if (options.dockerfileLocation)
13266
+ updateOptions.dockerfileLocation = options.dockerfileLocation;
13267
+ if (options.baseDirectory)
13268
+ updateOptions.baseDirectory = options.baseDirectory;
13269
+ if (options.domains)
13270
+ updateOptions.domains = options.domains;
13271
+ if (options.autoDeploy !== undefined)
13272
+ updateOptions.isAutoDeployEnabled = options.autoDeploy;
13273
+ if (options.forceHttps)
13274
+ updateOptions.isForceHttpsEnabled = true;
13275
+ if (Object.keys(updateOptions).length === 0) {
13276
+ console.warn(source_default.yellow("No update options provided. Use --help to see available options."));
13277
+ process.exit(0);
13278
+ }
13279
+ const result = await service.updateApplication(options.uuid, updateOptions);
13280
+ if (isErr(result)) {
13281
+ console.error(source_default.red("Failed to update application"));
13282
+ console.error(source_default.gray(result.error.message));
13283
+ process.exit(1);
13284
+ }
13285
+ console.log(source_default.green("Application updated successfully"));
13286
+ console.log(source_default.gray(`UUID: ${result.value.uuid}`));
13287
+ console.log(source_default.gray(`Name: ${result.value.name}`));
13288
+ if (result.value.description) {
13289
+ console.log(source_default.gray(`Description: ${result.value.description}`));
13290
+ }
11815
13291
  }
11816
- function formatStatus(status) {
11817
- const statusMap = {
11818
- running: source_default.green("● Running"),
11819
- "running:unknown": source_default.green("● Running"),
11820
- stopped: source_default.red("○ Stopped"),
11821
- restarting: source_default.yellow("◐ Restarting"),
11822
- error: source_default.red(" Error"),
11823
- deploying: source_default.yellow("◐ Deploying")
11824
- };
11825
- return statusMap[status] || status;
13292
+
13293
+ // src/cli/commands/delete.ts
13294
+ init_dist();
13295
+ async function deleteCommand(uuid, options = {}) {
13296
+ const resolvedUuid = resolveUuid(uuid);
13297
+ if (!resolvedUuid) {
13298
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
13299
+ return;
13300
+ }
13301
+ uuid = resolvedUuid;
13302
+ const service = getCoolifyService();
13303
+ const initResult = await service.init();
13304
+ if (isErr(initResult)) {
13305
+ console.error(source_default.red("Failed to initialize Coolify service"));
13306
+ console.error(source_default.gray(initResult.error.message));
13307
+ process.exit(1);
13308
+ }
13309
+ if (!options.force && !options.yes) {
13310
+ const readline = await import("readline");
13311
+ const rl = readline.createInterface({
13312
+ input: process.stdin,
13313
+ output: process.stdout
13314
+ });
13315
+ const answer = await new Promise((resolve) => {
13316
+ rl.question(source_default.yellow(`Are you sure you want to delete application ${source_default.bold(uuid)}? (yes/no): `), (ans) => {
13317
+ rl.close();
13318
+ resolve(ans.toLowerCase());
13319
+ });
13320
+ });
13321
+ if (answer !== "yes" && answer !== "y") {
13322
+ console.log(source_default.gray("Operation cancelled"));
13323
+ process.exit(0);
13324
+ }
13325
+ }
13326
+ console.log(source_default.cyan(`Deleting application ${source_default.bold(uuid)}...`));
13327
+ const result = await service.deleteApplication(uuid);
13328
+ if (isErr(result)) {
13329
+ console.error(source_default.red("Failed to delete application"));
13330
+ console.error(source_default.gray(result.error.message));
13331
+ process.exit(1);
13332
+ }
13333
+ console.log(source_default.green("Application deleted successfully"));
13334
+ if (result.value.message) {
13335
+ console.log(source_default.gray(result.value.message));
13336
+ }
11826
13337
  }
11827
13338
 
11828
- // src/cli/commands/list.ts
11829
- async function listCommand(options) {
13339
+ // src/cli/commands/destinations.ts
13340
+ init_dist();
13341
+ var import_cli_table35 = __toESM(require_table(), 1);
13342
+ async function destinationsCommand(serverUuid) {
11830
13343
  const coolify = getCoolifyService();
11831
13344
  const initResult = await coolify.init();
11832
13345
  if (isErr(initResult)) {
11833
13346
  console.error(source_default.red(`Error: ${initResult.error.message}`));
11834
13347
  return;
11835
13348
  }
11836
- const result = await coolify.listApplications(options.team, options.project);
13349
+ const result = await coolify.getServerDestinations(serverUuid);
11837
13350
  if (isErr(result)) {
11838
13351
  console.error(source_default.red(`Error: ${result.error.message}`));
11839
13352
  return;
11840
13353
  }
11841
- const apps = result.value;
11842
- if (apps.length === 0) {
11843
- console.log(source_default.yellow("No applications found"));
11844
- return;
11845
- }
11846
- const table = new import_cli_table32.default({
11847
- head: [
11848
- source_default.cyan("UUID"),
11849
- source_default.cyan("Name"),
11850
- source_default.cyan("Status"),
11851
- source_default.cyan("Server")
11852
- ],
11853
- ...options.full ? { colWidths: [36, 30, 20, 10] } : {}
11854
- });
11855
- for (const app of apps) {
11856
- table.push([
11857
- options.full ? app.uuid : app.uuid.slice(0, 8),
11858
- app.name,
11859
- formatStatus(app.status),
11860
- app.destination?.server?.name || "N/A"
11861
- ]);
13354
+ const destinations = result.value;
13355
+ if (destinations.length === 0) {
13356
+ console.log(source_default.yellow("No destinations found"));
13357
+ return;
13358
+ }
13359
+ const table = new import_cli_table35.default({
13360
+ head: [source_default.cyan("UUID"), source_default.cyan("Name"), source_default.cyan("Network")]
13361
+ });
13362
+ for (const dest of destinations) {
13363
+ table.push([dest.uuid, dest.name, dest.network || "N/A"]);
11862
13364
  }
11863
13365
  console.log(table.toString());
11864
- console.log(source_default.gray(`Total: ${apps.length} application(s)`));
13366
+ console.log(source_default.gray(`Total: ${destinations.length} destination(s)`));
11865
13367
  }
11866
13368
 
11867
- // src/cli/commands/logs.ts
11868
- async function logsCommand(uuid, options) {
13369
+ // src/cli/commands/show.ts
13370
+ init_dist();
13371
+ async function showCommand(uuid) {
13372
+ const resolvedUuid = resolveUuid(uuid);
13373
+ if (!resolvedUuid) {
13374
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
13375
+ return;
13376
+ }
13377
+ uuid = resolvedUuid;
11869
13378
  const coolify = getCoolifyService();
11870
13379
  const initResult = await coolify.init();
11871
13380
  if (isErr(initResult)) {
11872
13381
  console.error(source_default.red(`Error: ${initResult.error.message}`));
11873
13382
  return;
11874
13383
  }
11875
- const result = await coolify.getApplicationLogs(uuid, { tail: options.lines || 50 });
13384
+ const result = await coolify.listApplications();
11876
13385
  if (isErr(result)) {
11877
13386
  console.error(source_default.red(`Error: ${result.error.message}`));
11878
13387
  return;
11879
13388
  }
11880
- const logs = result.value;
11881
- if (logs.logs.length === 0) {
11882
- console.log(source_default.yellow("No logs available"));
13389
+ const apps = result.value;
13390
+ const app = apps.find((a) => a.uuid === uuid || a.uuid.startsWith(uuid));
13391
+ if (!app) {
13392
+ console.error(source_default.red(`Application not found: ${uuid}`));
11883
13393
  return;
11884
13394
  }
11885
- console.log(source_default.gray(`Application logs (${logs.logs.length} lines):
11886
- `));
11887
- for (const line of logs.logs) {
11888
- console.log(line);
11889
- }
11890
- if (options.follow) {
11891
- console.log(source_default.yellow(`
11892
- Follow mode not yet implemented`));
13395
+ console.log(source_default.cyan("Application Details:"));
13396
+ console.log("");
13397
+ console.log(source_default.gray("UUID: ") + source_default.white(app.uuid));
13398
+ console.log(source_default.gray("Name: ") + source_default.white(app.name));
13399
+ console.log(source_default.gray("Status: ") + source_default.white(app.status));
13400
+ console.log(source_default.gray("Description:") + source_default.white(app.description || "N/A"));
13401
+ console.log(source_default.gray("Repository: ") + source_default.white(app.git_repository || "N/A"));
13402
+ console.log(source_default.gray("Branch: ") + source_default.white(app.git_branch || "N/A"));
13403
+ console.log(source_default.gray("Build Pack: ") + source_default.white(app.build_pack || "N/A"));
13404
+ console.log(source_default.gray("Ports: ") + source_default.white(app.ports_exposes || "N/A"));
13405
+ console.log(source_default.gray("FQDN: ") + source_default.white(app.fqdn || "N/A"));
13406
+ console.log(source_default.gray("Dockerfile: ") + source_default.white(app.dockerfile_location || "N/A"));
13407
+ console.log(source_default.gray("Base Dir: ") + source_default.white(app.base_directory || "N/A"));
13408
+ console.log("");
13409
+ console.log(source_default.cyan("Destination:"));
13410
+ if (app.destination) {
13411
+ console.log(source_default.gray(" UUID: ") + source_default.white(app.destination.uuid));
13412
+ console.log(source_default.gray(" Name: ") + source_default.white(app.destination.name));
13413
+ if (app.destination.server) {
13414
+ console.log(source_default.gray(" Server:") + source_default.white(` ${app.destination.server.name} (${app.destination.server.ip})`));
13415
+ }
13416
+ } else {
13417
+ console.log(source_default.yellow(" No destination configured"));
11893
13418
  }
13419
+ console.log("");
13420
+ console.log(source_default.cyan("Commands:"));
13421
+ if (app.install_command)
13422
+ console.log(source_default.gray(" Install: ") + source_default.white(app.install_command));
13423
+ if (app.build_command)
13424
+ console.log(source_default.gray(" Build: ") + source_default.white(app.build_command));
13425
+ if (app.start_command)
13426
+ console.log(source_default.gray(" Start: ") + source_default.white(app.start_command));
11894
13427
  }
11895
13428
 
11896
- // src/cli/commands/servers.ts
11897
- async function serversCommand(options = {}) {
13429
+ // src/cli/commands/deployments.ts
13430
+ init_dist();
13431
+ var import_cli_table36 = __toESM(require_table(), 1);
13432
+ async function deploymentsCommand(uuid, options = {}) {
13433
+ const resolvedUuid = resolveUuid(uuid);
13434
+ if (!resolvedUuid) {
13435
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
13436
+ return;
13437
+ }
13438
+ uuid = resolvedUuid;
11898
13439
  const coolify = getCoolifyService();
11899
13440
  const initResult = await coolify.init();
11900
13441
  if (isErr(initResult)) {
11901
13442
  console.error(source_default.red(`Error: ${initResult.error.message}`));
11902
13443
  return;
11903
13444
  }
11904
- const result = await coolify.listServers();
13445
+ const result = await coolify.getApplicationDeploymentHistory(uuid);
11905
13446
  if (isErr(result)) {
11906
13447
  console.error(source_default.red(`Error: ${result.error.message}`));
11907
13448
  return;
11908
13449
  }
11909
- const servers = result.value;
11910
- if (servers.length === 0) {
11911
- console.log(source_default.yellow("No servers found"));
13450
+ let deployments = result.value;
13451
+ deployments = deployments.reverse();
13452
+ if (options.limit) {
13453
+ deployments = deployments.slice(0, options.limit);
13454
+ }
13455
+ if (deployments.length === 0) {
13456
+ console.log(source_default.yellow("No deployments found"));
11912
13457
  return;
11913
13458
  }
11914
- const table = createTable(["UUID", "Name", "IP", "Status"], [options.full ? 36 : 8, 25, 20, 15]);
11915
- for (const server of servers) {
11916
- const statusColor = server.is_usable ? source_default.green : source_default.red;
13459
+ const table = new import_cli_table36.default({
13460
+ head: [
13461
+ source_default.cyan("ID"),
13462
+ source_default.cyan("UUID"),
13463
+ source_default.cyan("Status"),
13464
+ source_default.cyan("Commit"),
13465
+ source_default.cyan("Created")
13466
+ ],
13467
+ ...options.full ? { colWidths: [8, 36, 20, 10, 20] } : {}
13468
+ });
13469
+ for (const dep of deployments) {
11917
13470
  table.push([
11918
- options.full ? server.uuid : server.uuid.slice(0, 8),
11919
- server.name,
11920
- server.ip || "N/A",
11921
- statusColor(server.is_usable ? "● Usable" : "○ Unusable")
13471
+ String(dep.id),
13472
+ dep.uuid || "-",
13473
+ formatStatus(dep.status),
13474
+ dep.commit?.slice(0, 7) || "-",
13475
+ new Date(dep.created_at).toLocaleString()
11922
13476
  ]);
11923
13477
  }
11924
13478
  console.log(table.toString());
11925
- console.log(source_default.gray(`Total: ${servers.length} server(s)`));
13479
+ console.log(source_default.gray(`Total: ${deployments.length} deployment(s)`));
11926
13480
  }
11927
13481
 
11928
- // src/cli/commands/projects.ts
11929
- var import_cli_table33 = __toESM(require_table(), 1);
11930
- async function projectsCommand(options = {}) {
11931
- const spinner = ora("Connecting to Coolify...").start();
13482
+ // src/cli/commands/start.ts
13483
+ init_dist();
13484
+ async function startCommand(uuid) {
13485
+ const resolvedUuid = resolveUuid(uuid);
13486
+ if (!resolvedUuid) {
13487
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
13488
+ return;
13489
+ }
13490
+ uuid = resolvedUuid;
13491
+ const spinner = ora("Initializing Coolify connection...").start();
11932
13492
  try {
11933
13493
  const coolify = getCoolifyService();
11934
13494
  const initResult = await coolify.init();
@@ -11936,56 +13496,28 @@ async function projectsCommand(options = {}) {
11936
13496
  spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
11937
13497
  return;
11938
13498
  }
11939
- if (options.create) {
11940
- spinner.text = `Creating project "${options.create}"...`;
11941
- const createResult = await coolify.createProject(options.create, options.description);
11942
- if (isOk(createResult)) {
11943
- spinner.succeed(source_default.green(`Project created: ${source_default.cyan(createResult.value.uuid)}`));
11944
- console.log(` Name: ${source_default.cyan(options.create)}`);
11945
- console.log(` UUID: ${source_default.cyan(createResult.value.uuid)}`);
11946
- } else {
11947
- spinner.fail(source_default.red(`Failed to create project: ${createResult.error.message}`));
11948
- }
13499
+ spinner.text = "Starting application...";
13500
+ const result = await coolify.startApplication(uuid);
13501
+ if (isErr(result)) {
13502
+ spinner.fail(source_default.red(`Failed to start application: ${result.error.message}`));
11949
13503
  return;
11950
13504
  }
11951
- spinner.text = "Fetching projects...";
11952
- const result = await coolify.listProjects();
11953
- if (isOk(result)) {
11954
- spinner.succeed(source_default.green("Projects retrieved"));
11955
- const projects = result.value;
11956
- if (projects.length === 0) {
11957
- console.log(source_default.yellow("No projects found"));
11958
- return;
11959
- }
11960
- const table = new import_cli_table33.default({
11961
- head: [
11962
- source_default.cyan("UUID"),
11963
- source_default.cyan("Name"),
11964
- source_default.cyan("Description")
11965
- ],
11966
- ...options.full ? { colWidths: [36, 30, 40] } : {}
11967
- });
11968
- for (const project of projects) {
11969
- table.push([
11970
- options.full ? project.uuid : project.uuid.slice(0, 8),
11971
- project.name,
11972
- project.description || "-"
11973
- ]);
11974
- }
11975
- console.log(table.toString());
11976
- console.log(source_default.gray(`Total: ${projects.length} project(s)`));
11977
- } else {
11978
- spinner.fail(source_default.red(`Failed to fetch projects: ${result.error.message}`));
11979
- }
13505
+ spinner.succeed(source_default.green(`Application started: ${source_default.cyan(uuid)}`));
11980
13506
  } catch (error) {
11981
13507
  spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
11982
13508
  }
11983
13509
  }
11984
13510
 
11985
- // src/cli/commands/environments.ts
11986
- var import_cli_table34 = __toESM(require_table(), 1);
11987
- async function environmentsCommand(projectUuid, options = {}) {
11988
- const spinner = ora("Connecting to Coolify...").start();
13511
+ // src/cli/commands/stop.ts
13512
+ init_dist();
13513
+ async function stopCommand(uuid) {
13514
+ const resolvedUuid = resolveUuid(uuid);
13515
+ if (!resolvedUuid) {
13516
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
13517
+ return;
13518
+ }
13519
+ uuid = resolvedUuid;
13520
+ const spinner = ora("Initializing Coolify connection...").start();
11989
13521
  try {
11990
13522
  const coolify = getCoolifyService();
11991
13523
  const initResult = await coolify.init();
@@ -11993,394 +13525,1042 @@ async function environmentsCommand(projectUuid, options = {}) {
11993
13525
  spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
11994
13526
  return;
11995
13527
  }
11996
- spinner.text = `Fetching environments for project ${projectUuid.slice(0, 8)}...`;
11997
- const result = await coolify.getProjectEnvironments(projectUuid);
11998
- if (isOk(result)) {
11999
- spinner.succeed(source_default.green("Environments retrieved"));
12000
- const environments = result.value;
12001
- if (environments.length === 0) {
12002
- console.log(source_default.yellow("No environments found for this project"));
12003
- return;
12004
- }
12005
- const table = new import_cli_table34.default({
12006
- head: [
12007
- source_default.cyan("UUID"),
12008
- source_default.cyan("Name"),
12009
- source_default.cyan("Description")
12010
- ],
12011
- ...options.full ? { colWidths: [36, 25, 40] } : {}
12012
- });
12013
- for (const env2 of environments) {
12014
- table.push([
12015
- options.full ? env2.uuid : env2.uuid.slice(0, 8),
12016
- env2.name,
12017
- env2.description || "-"
12018
- ]);
12019
- }
12020
- console.log(table.toString());
12021
- console.log(source_default.gray(`Total: ${environments.length} environment(s)`));
12022
- } else {
12023
- spinner.fail(source_default.red(`Failed to fetch environments: ${result.error.message}`));
13528
+ spinner.text = "Stopping application...";
13529
+ const result = await coolify.stopApplication(uuid);
13530
+ if (isErr(result)) {
13531
+ spinner.fail(source_default.red(`Failed to stop application: ${result.error.message}`));
13532
+ return;
12024
13533
  }
13534
+ spinner.succeed(source_default.green(`Application stopped: ${source_default.cyan(uuid)}`));
12025
13535
  } catch (error) {
12026
13536
  spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12027
13537
  }
12028
13538
  }
12029
13539
 
12030
- // src/cli/commands/config.ts
12031
- import { existsSync as existsSync2 } from "node:fs";
12032
- async function configCommand(action, args) {
12033
- if (action === "set") {
12034
- if (!args.key || !args.value) {
12035
- console.error(source_default.red('Error: key and value are required for "set" command'));
12036
- console.log(source_default.gray("Usage: coolify-mcp config set <key> <value>"));
12037
- console.log(source_default.gray("Keys: url, token"));
13540
+ // src/cli/commands/restart.ts
13541
+ init_dist();
13542
+ async function restartCommand(uuid) {
13543
+ const resolvedUuid = resolveUuid(uuid);
13544
+ if (!resolvedUuid) {
13545
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
13546
+ return;
13547
+ }
13548
+ uuid = resolvedUuid;
13549
+ const spinner = ora("Initializing Coolify connection...").start();
13550
+ try {
13551
+ const coolify = getCoolifyService();
13552
+ const initResult = await coolify.init();
13553
+ if (isErr(initResult)) {
13554
+ spinner.fail(source_default.red(`Failed to initialize: ${initResult.error.message}`));
12038
13555
  return;
12039
13556
  }
12040
- const result = await loadConfig();
12041
- if (isOk(result)) {
12042
- const config = result.value;
12043
- if (args.key === "url") {
12044
- config.url = args.value;
12045
- } else if (args.key === "token") {
12046
- config.token = args.value;
12047
- } else {
12048
- console.error(source_default.red(`Error: Unknown key "${args.key}"`));
12049
- return;
12050
- }
12051
- const saveResult = await saveConfig(config);
12052
- if (isOk(saveResult)) {
12053
- console.log(source_default.green(`Config updated: ${args.key} = ${args.value}`));
12054
- } else {
12055
- console.error(source_default.red(`Error: ${saveResult.error.message}`));
12056
- }
12057
- }
12058
- } else if (action === "get") {
12059
- const result = await loadConfig();
12060
- if (isOk(result)) {
12061
- const config = result.value;
12062
- console.log(source_default.cyan("Current configuration:"));
12063
- console.log(` URL: ${source_default.gray(config.url || "(not set)")}`);
12064
- console.log(` Token: ${source_default.gray(config.token ? "(set)" : "(not set)")}`);
12065
- } else {
12066
- console.error(source_default.red(`Error: ${result.error.message}`));
12067
- }
12068
- } else if (action === "path") {
12069
- console.log(source_default.cyan("Config file:"));
12070
- console.log(` ${CONFIG_FILE}`);
12071
- if (existsSync2(CONFIG_FILE)) {
12072
- console.log(source_default.gray(" Status: File exists"));
12073
- } else {
12074
- console.log(source_default.yellow(" Status: File does not exist"));
13557
+ spinner.text = "Restarting application...";
13558
+ const result = await coolify.restartApplication(uuid);
13559
+ if (isErr(result)) {
13560
+ spinner.fail(source_default.red(`Failed to restart application: ${result.error.message}`));
13561
+ return;
12075
13562
  }
12076
- } else {
12077
- console.log(source_default.cyan("Coolify MCP Configuration"));
12078
- console.log();
12079
- console.log(source_default.gray("Commands:"));
12080
- console.log(" coolify-mcp config set <key> <value> Set a config value");
12081
- console.log(" coolify-mcp config get Show current config");
12082
- console.log(" coolify-mcp config path Show config file path");
12083
- console.log();
12084
- console.log(source_default.gray("Keys:"));
12085
- console.log(" url - Coolify instance URL");
12086
- console.log(" token - Coolify API token");
12087
- console.log();
12088
- console.log(source_default.gray("Environment variables:"));
12089
- console.log(" COOLIFY_URL - Coolify instance URL");
12090
- console.log(" COOLIFY_TOKEN - Coolify API token");
13563
+ spinner.succeed(source_default.green(`Application restarted: ${source_default.cyan(uuid)}`));
13564
+ } catch (error) {
13565
+ spinner.fail(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
13566
+ }
13567
+ }
13568
+
13569
+ // src/cli/commands/build-logs.ts
13570
+ init_dist();
13571
+ async function buildLogsCommand(deploymentUuid, options) {
13572
+ const coolify = getCoolifyService();
13573
+ const initResult = await coolify.init();
13574
+ if (isErr(initResult)) {
13575
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
13576
+ return;
13577
+ }
13578
+ const result = await coolify.getDeploymentLogs(deploymentUuid);
13579
+ if (isErr(result)) {
13580
+ console.error(source_default.red(`Error: ${result.error.message}`));
13581
+ return;
13582
+ }
13583
+ const { status, logs } = result.value;
13584
+ console.log(source_default.cyan("Deployment:") + " " + source_default.white(deploymentUuid));
13585
+ console.log(source_default.cyan("Status: ") + " " + source_default.white(status));
13586
+ console.log("");
13587
+ if (!logs || logs.length === 0) {
13588
+ console.log(source_default.yellow("No build logs available"));
13589
+ return;
13590
+ }
13591
+ const lines = logs.split(`
13592
+ `);
13593
+ const tail = options.lines || lines.length;
13594
+ const output = lines.slice(-tail);
13595
+ console.log(source_default.gray(`Build logs (${output.length} lines):
13596
+ `));
13597
+ for (const line of output) {
13598
+ console.log(line);
13599
+ }
13600
+ }
13601
+
13602
+ // src/cli/commands/service-logs.ts
13603
+ init_dist();
13604
+ async function serviceLogsCommand(uuid, serviceName, options) {
13605
+ const coolify = getCoolifyService();
13606
+ const initResult = await coolify.init();
13607
+ if (isErr(initResult)) {
13608
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
13609
+ return;
13610
+ }
13611
+ const result = await coolify.getApplicationLogs(uuid, {
13612
+ tail: options.lines || 50,
13613
+ serviceName
13614
+ });
13615
+ if (isErr(result)) {
13616
+ console.error(source_default.red(`Error: ${result.error.message}`));
13617
+ return;
13618
+ }
13619
+ const logs = result.value;
13620
+ if (logs.logs.length === 0) {
13621
+ console.log(source_default.yellow(`No logs available for service "${serviceName}"`));
13622
+ return;
13623
+ }
13624
+ console.log(source_default.gray(`Service "${source_default.white(serviceName)}" logs (${logs.logs.length} lines):
13625
+ `));
13626
+ for (const line of logs.logs) {
13627
+ console.log(line);
12091
13628
  }
12092
13629
  }
12093
13630
 
12094
- // src/cli/commands/env.ts
12095
- async function envCommand(uuid, options = {}) {
13631
+ // src/cli/commands/version.ts
13632
+ init_dist();
13633
+ async function versionCommand() {
12096
13634
  const coolify = getCoolifyService();
12097
13635
  const initResult = await coolify.init();
12098
13636
  if (isErr(initResult)) {
12099
13637
  console.error(source_default.red(`Error: ${initResult.error.message}`));
12100
13638
  return;
12101
13639
  }
12102
- if (options.set) {
12103
- const [key, ...valueParts] = options.set.split("=");
12104
- const value = valueParts.join("=");
12105
- if (!key || value === undefined) {
12106
- console.error(source_default.red("Error: Invalid format. Use --set KEY=VALUE"));
12107
- return;
12108
- }
12109
- const result2 = await coolify.setEnvironmentVariable(uuid, key, value, options.buildtime ?? false);
12110
- if (isErr(result2)) {
12111
- console.error(source_default.red(`Error: ${result2.error.message}`));
12112
- return;
12113
- }
12114
- console.log(source_default.green(`✓ Set ${source_default.bold(key)} for ${uuid.slice(0, 8)}`));
13640
+ const result = await coolify.getVersion();
13641
+ if (isErr(result)) {
13642
+ console.error(source_default.red(`Error: ${result.error.message}`));
12115
13643
  return;
12116
13644
  }
12117
- if (options.delete) {
12118
- const result2 = await coolify.deleteEnvironmentVariable(uuid, options.delete);
12119
- if (isErr(result2)) {
12120
- console.error(source_default.red(`Error: ${result2.error.message}`));
12121
- return;
12122
- }
12123
- console.log(source_default.green(`✓ Deleted ${source_default.bold(options.delete)} from ${uuid.slice(0, 8)}`));
13645
+ console.log(source_default.cyan("Coolify Server Version:"), source_default.bold(result.value.version));
13646
+ }
13647
+
13648
+ // src/cli/commands/databases.ts
13649
+ init_dist();
13650
+ var import_cli_table37 = __toESM(require_table(), 1);
13651
+ async function databasesCommand(_options = {}) {
13652
+ const coolify = getCoolifyService();
13653
+ const initResult = await coolify.init();
13654
+ if (isErr(initResult)) {
13655
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
12124
13656
  return;
12125
13657
  }
12126
- const result = await coolify.getEnvironmentVariables(uuid);
13658
+ const result = await coolify.listDatabases();
12127
13659
  if (isErr(result)) {
12128
13660
  console.error(source_default.red(`Error: ${result.error.message}`));
12129
13661
  return;
12130
13662
  }
12131
- const envVars = result.value;
12132
- if (envVars.length === 0) {
12133
- console.log(source_default.yellow("No environment variables found"));
13663
+ const databases = result.value;
13664
+ if (databases.length === 0) {
13665
+ console.log(source_default.yellow("No databases found"));
12134
13666
  return;
12135
13667
  }
12136
- console.log(source_default.cyan(`Environment variables (${envVars.length}):
12137
- `));
12138
- const runtimeVars = envVars.filter((ev) => ev.is_runtime);
12139
- const buildtimeVars = envVars.filter((ev) => ev.is_buildtime);
12140
- if (runtimeVars.length > 0) {
12141
- console.log(source_default.yellow.bold("Runtime:"));
12142
- for (const ev of runtimeVars) {
12143
- const required = ev.is_required ? source_default.red(" *") : "";
12144
- console.log(` ${source_default.green(ev.key)}${required} = ${source_default.gray(ev.value)}`);
12145
- }
12146
- console.log();
13668
+ const table = new import_cli_table37.default({
13669
+ head: [
13670
+ source_default.cyan("UUID"),
13671
+ source_default.cyan("Name"),
13672
+ source_default.cyan("Type"),
13673
+ source_default.cyan("Status")
13674
+ ]
13675
+ });
13676
+ for (const db of databases) {
13677
+ table.push([
13678
+ db.uuid,
13679
+ db.name || "-",
13680
+ db.type || "-",
13681
+ formatStatus(db.status)
13682
+ ]);
12147
13683
  }
12148
- if (buildtimeVars.length > 0) {
12149
- console.log(source_default.blue.bold("Buildtime:"));
12150
- for (const ev of buildtimeVars) {
12151
- console.log(` ${source_default.green(ev.key)} = ${source_default.gray(ev.value)}`);
12152
- }
13684
+ console.log(table.toString());
13685
+ console.log(source_default.gray(`Total: ${databases.length} database(s)`));
13686
+ }
13687
+
13688
+ // src/cli/commands/services.ts
13689
+ init_dist();
13690
+ var import_cli_table38 = __toESM(require_table(), 1);
13691
+ async function servicesCommand(_options = {}) {
13692
+ const coolify = getCoolifyService();
13693
+ const initResult = await coolify.init();
13694
+ if (isErr(initResult)) {
13695
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
13696
+ return;
13697
+ }
13698
+ const result = await coolify.listServices();
13699
+ if (isErr(result)) {
13700
+ console.error(source_default.red(`Error: ${result.error.message}`));
13701
+ return;
13702
+ }
13703
+ const services = result.value;
13704
+ if (services.length === 0) {
13705
+ console.log(source_default.yellow("No services found"));
13706
+ return;
13707
+ }
13708
+ const table = new import_cli_table38.default({
13709
+ head: [
13710
+ source_default.cyan("UUID"),
13711
+ source_default.cyan("Name"),
13712
+ source_default.cyan("Type"),
13713
+ source_default.cyan("Status")
13714
+ ]
13715
+ });
13716
+ for (const svc of services) {
13717
+ table.push([
13718
+ svc.uuid,
13719
+ svc.name || "-",
13720
+ svc.type || "-",
13721
+ formatStatus(svc.status)
13722
+ ]);
12153
13723
  }
13724
+ console.log(table.toString());
13725
+ console.log(source_default.gray(`Total: ${services.length} service(s)`));
12154
13726
  }
12155
13727
 
12156
- // src/cli/commands/update.ts
12157
- async function updateCommand(options) {
12158
- console.log(source_default.cyan(`Updating application ${source_default.bold(options.uuid)}...`));
12159
- const service = getCoolifyService();
12160
- const initResult = await service.init();
13728
+ // src/cli/commands/cancel-deploy.ts
13729
+ init_dist();
13730
+ async function cancelDeployCommand(deploymentUuid) {
13731
+ const coolify = getCoolifyService();
13732
+ const initResult = await coolify.init();
12161
13733
  if (isErr(initResult)) {
12162
- console.error(source_default.red("Failed to initialize Coolify service"));
12163
- console.error(source_default.gray(initResult.error.message));
12164
- process.exit(1);
13734
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
13735
+ return;
12165
13736
  }
12166
- const updateOptions = {};
12167
- if (options.name)
12168
- updateOptions.name = options.name;
12169
- if (options.description)
12170
- updateOptions.description = options.description;
12171
- if (options.buildPack)
12172
- updateOptions.buildPack = options.buildPack;
12173
- if (options.gitBranch)
12174
- updateOptions.gitBranch = options.gitBranch;
12175
- if (options.ports)
12176
- updateOptions.portsExposes = options.ports;
12177
- if (options.installCommand)
12178
- updateOptions.installCommand = options.installCommand;
12179
- if (options.buildCommand)
12180
- updateOptions.buildCommand = options.buildCommand;
12181
- if (options.startCommand)
12182
- updateOptions.startCommand = options.startCommand;
12183
- if (options.dockerfileLocation)
12184
- updateOptions.dockerfileLocation = options.dockerfileLocation;
12185
- if (options.baseDirectory)
12186
- updateOptions.baseDirectory = options.baseDirectory;
12187
- if (options.domains)
12188
- updateOptions.domains = options.domains;
12189
- if (options.autoDeploy !== undefined)
12190
- updateOptions.isAutoDeployEnabled = options.autoDeploy;
12191
- if (options.forceHttps)
12192
- updateOptions.isForceHttpsEnabled = true;
12193
- if (Object.keys(updateOptions).length === 0) {
12194
- console.warn(source_default.yellow("No update options provided. Use --help to see available options."));
12195
- process.exit(0);
13737
+ const result = await coolify.cancelDeployment(deploymentUuid);
13738
+ if (isErr(result)) {
13739
+ console.error(source_default.red(`Error: ${result.error.message}`));
13740
+ return;
13741
+ }
13742
+ console.log(source_default.green(`Deployment ${deploymentUuid} cancelled`));
13743
+ }
13744
+
13745
+ // src/cli/commands/server-resources.ts
13746
+ init_dist();
13747
+ var import_cli_table39 = __toESM(require_table(), 1);
13748
+ async function serverResourcesCommand(serverUuid, _options = {}) {
13749
+ const coolify = getCoolifyService();
13750
+ const initResult = await coolify.init();
13751
+ if (isErr(initResult)) {
13752
+ console.error(source_default.red(`Error: ${initResult.error.message}`));
13753
+ return;
13754
+ }
13755
+ const result = await coolify.getServerResources(serverUuid);
13756
+ if (isErr(result)) {
13757
+ console.error(source_default.red(`Error: ${result.error.message}`));
13758
+ return;
13759
+ }
13760
+ const resources = result.value;
13761
+ if (resources.length === 0) {
13762
+ console.log(source_default.yellow("No resources found on this server"));
13763
+ return;
13764
+ }
13765
+ const table = new import_cli_table39.default({
13766
+ head: [
13767
+ source_default.cyan("UUID"),
13768
+ source_default.cyan("Name"),
13769
+ source_default.cyan("Type"),
13770
+ source_default.cyan("Status")
13771
+ ]
13772
+ });
13773
+ for (const res of resources) {
13774
+ table.push([
13775
+ res.uuid,
13776
+ res.name || "-",
13777
+ res.type || "-",
13778
+ formatStatus(res.status)
13779
+ ]);
13780
+ }
13781
+ console.log(table.toString());
13782
+ console.log(source_default.gray(`Total: ${resources.length} resource(s) on server ${serverUuid}`));
13783
+ }
13784
+
13785
+ // src/cli/actions.ts
13786
+ var import_cli_table310 = __toESM(require_table(), 1);
13787
+
13788
+ // src/sdk.ts
13789
+ init_dist();
13790
+ function unwrap(result) {
13791
+ if (isErr(result))
13792
+ throw result.error;
13793
+ return result.value;
13794
+ }
13795
+
13796
+ class ApplicationsResource {
13797
+ svc;
13798
+ constructor(svc) {
13799
+ this.svc = svc;
13800
+ }
13801
+ async list(options) {
13802
+ return unwrap(await this.svc.listApplications(options?.teamId, options?.projectId, options?.page, options?.perPage));
13803
+ }
13804
+ async listSummaries() {
13805
+ return unwrap(await this.svc.listApplicationSummaries());
13806
+ }
13807
+ async resolve(query) {
13808
+ return unwrap(await this.svc.resolveApplication(query));
13809
+ }
13810
+ async create(options, onProgress) {
13811
+ return unwrap(await this.svc.createApplication(options, onProgress));
13812
+ }
13813
+ async deploy(uuid, options, onProgress) {
13814
+ return unwrap(await this.svc.deploy({ uuid, ...options }, onProgress));
13815
+ }
13816
+ async start(uuid, options) {
13817
+ return unwrap(await this.svc.startApplication(uuid, options));
13818
+ }
13819
+ async stop(uuid) {
13820
+ return unwrap(await this.svc.stopApplication(uuid));
13821
+ }
13822
+ async restart(uuid) {
13823
+ return unwrap(await this.svc.restartApplication(uuid));
13824
+ }
13825
+ async delete(uuid, options) {
13826
+ return unwrap(await this.svc.deleteApplication(uuid, options));
13827
+ }
13828
+ async update(uuid, options) {
13829
+ return unwrap(await this.svc.updateApplication(uuid, options));
13830
+ }
13831
+ async logs(uuid, options) {
13832
+ return unwrap(await this.svc.getApplicationLogs(uuid, options));
13833
+ }
13834
+ async deployments(uuid, skip, take) {
13835
+ return unwrap(await this.svc.getApplicationDeployments(uuid, skip, take));
13836
+ }
13837
+ async exec(uuid, command) {
13838
+ return unwrap(await this.svc.executeCommand(uuid, command));
13839
+ }
13840
+ async envVars(uuid) {
13841
+ return unwrap(await this.svc.getEnvironmentVariables(uuid));
13842
+ }
13843
+ async setEnv(uuid, key, value, isBuildTime) {
13844
+ return unwrap(await this.svc.setEnvironmentVariable(uuid, key, value, isBuildTime));
13845
+ }
13846
+ async bulkSetEnv(uuid, vars) {
13847
+ return unwrap(await this.svc.bulkUpdateEnvironmentVariables(uuid, vars));
13848
+ }
13849
+ async deleteEnv(uuid, key) {
13850
+ return unwrap(await this.svc.deleteEnvironmentVariable(uuid, key));
13851
+ }
13852
+ }
13853
+
13854
+ class DatabasesResource {
13855
+ svc;
13856
+ constructor(svc) {
13857
+ this.svc = svc;
13858
+ }
13859
+ async list(options) {
13860
+ return unwrap(await this.svc.listDatabases(options?.page, options?.perPage));
13861
+ }
13862
+ async listSummaries() {
13863
+ return unwrap(await this.svc.listDatabaseSummaries());
13864
+ }
13865
+ async get(uuid) {
13866
+ return unwrap(await this.svc.getDatabase(uuid));
13867
+ }
13868
+ async create(type, data) {
13869
+ return unwrap(await this.svc.createDatabase(type, data));
13870
+ }
13871
+ async update(uuid, data) {
13872
+ return unwrap(await this.svc.updateDatabase(uuid, data));
13873
+ }
13874
+ async start(uuid) {
13875
+ return unwrap(await this.svc.startDatabase(uuid));
13876
+ }
13877
+ async stop(uuid) {
13878
+ return unwrap(await this.svc.stopDatabase(uuid));
13879
+ }
13880
+ async restart(uuid) {
13881
+ return unwrap(await this.svc.restartDatabase(uuid));
13882
+ }
13883
+ async delete(uuid, options) {
13884
+ return unwrap(await this.svc.deleteDatabase(uuid, options));
13885
+ }
13886
+ async backups(uuid) {
13887
+ return unwrap(await this.svc.listDatabaseBackups(uuid));
13888
+ }
13889
+ async getBackup(dbUuid, backupUuid) {
13890
+ return unwrap(await this.svc.getDatabaseBackup(dbUuid, backupUuid));
13891
+ }
13892
+ async createBackup(dbUuid, data) {
13893
+ return unwrap(await this.svc.createDatabaseBackup(dbUuid, data));
13894
+ }
13895
+ async deleteBackup(dbUuid, backupUuid) {
13896
+ return unwrap(await this.svc.deleteDatabaseBackup(dbUuid, backupUuid));
13897
+ }
13898
+ }
13899
+
13900
+ class ServicesResource {
13901
+ svc;
13902
+ constructor(svc) {
13903
+ this.svc = svc;
13904
+ }
13905
+ async list(options) {
13906
+ return unwrap(await this.svc.listServices(options?.page, options?.perPage));
13907
+ }
13908
+ async listSummaries() {
13909
+ return unwrap(await this.svc.listServiceSummaries());
13910
+ }
13911
+ async get(uuid) {
13912
+ return unwrap(await this.svc.getService(uuid));
13913
+ }
13914
+ async create(data) {
13915
+ return unwrap(await this.svc.createService(data));
13916
+ }
13917
+ async update(uuid, data) {
13918
+ return unwrap(await this.svc.updateService(uuid, data));
13919
+ }
13920
+ async start(uuid) {
13921
+ return unwrap(await this.svc.startService(uuid));
13922
+ }
13923
+ async stop(uuid) {
13924
+ return unwrap(await this.svc.stopService(uuid));
13925
+ }
13926
+ async restart(uuid) {
13927
+ return unwrap(await this.svc.restartService(uuid));
13928
+ }
13929
+ async delete(uuid, options) {
13930
+ return unwrap(await this.svc.deleteService(uuid, options));
13931
+ }
13932
+ async envVars(uuid) {
13933
+ return unwrap(await this.svc.listServiceEnvVars(uuid));
13934
+ }
13935
+ async setEnv(uuid, data) {
13936
+ return unwrap(await this.svc.createServiceEnvVar(uuid, data));
13937
+ }
13938
+ }
13939
+
13940
+ class ServersResource {
13941
+ svc;
13942
+ constructor(svc) {
13943
+ this.svc = svc;
13944
+ }
13945
+ async list(options) {
13946
+ return unwrap(await this.svc.listServers(options?.page, options?.perPage));
13947
+ }
13948
+ async listSummaries() {
13949
+ return unwrap(await this.svc.listServerSummaries());
13950
+ }
13951
+ async resolve(query) {
13952
+ return unwrap(await this.svc.resolveServer(query));
13953
+ }
13954
+ async get(uuid) {
13955
+ return unwrap(await this.svc.getServer(uuid));
13956
+ }
13957
+ async create(data) {
13958
+ return unwrap(await this.svc.createServer(data));
13959
+ }
13960
+ async delete(uuid) {
13961
+ return unwrap(await this.svc.deleteServer(uuid));
13962
+ }
13963
+ async resources(uuid) {
13964
+ return unwrap(await this.svc.getServerResources(uuid));
13965
+ }
13966
+ async domains(uuid) {
13967
+ return unwrap(await this.svc.getServerDomains(uuid));
13968
+ }
13969
+ async destinations(uuid) {
13970
+ return unwrap(await this.svc.getServerDestinations(uuid));
13971
+ }
13972
+ async validate(uuid) {
13973
+ return unwrap(await this.svc.validateServer(uuid));
13974
+ }
13975
+ }
13976
+
13977
+ class ProjectsResource {
13978
+ svc;
13979
+ constructor(svc) {
13980
+ this.svc = svc;
13981
+ }
13982
+ async list(options) {
13983
+ return unwrap(await this.svc.listProjects(options?.page, options?.perPage));
13984
+ }
13985
+ async create(name, description) {
13986
+ return unwrap(await this.svc.createProject(name, description));
13987
+ }
13988
+ async update(uuid, data) {
13989
+ return unwrap(await this.svc.updateProject(uuid, data));
13990
+ }
13991
+ async delete(uuid) {
13992
+ return unwrap(await this.svc.deleteProject(uuid));
13993
+ }
13994
+ async environments(projectUuid) {
13995
+ return unwrap(await this.svc.getProjectEnvironments(projectUuid));
13996
+ }
13997
+ async createEnvironment(projectUuid, data) {
13998
+ return unwrap(await this.svc.createProjectEnvironment(projectUuid, data));
13999
+ }
14000
+ }
14001
+
14002
+ class TeamsResource {
14003
+ svc;
14004
+ constructor(svc) {
14005
+ this.svc = svc;
14006
+ }
14007
+ async list(options) {
14008
+ return unwrap(await this.svc.listTeams(options?.page, options?.perPage));
14009
+ }
14010
+ async current() {
14011
+ return unwrap(await this.svc.getCurrentTeam());
14012
+ }
14013
+ async get(id) {
14014
+ return unwrap(await this.svc.getTeam(id));
14015
+ }
14016
+ async members(teamId) {
14017
+ return unwrap(await this.svc.getTeamMembers(teamId));
14018
+ }
14019
+ }
14020
+
14021
+ class KeysResource {
14022
+ svc;
14023
+ constructor(svc) {
14024
+ this.svc = svc;
14025
+ }
14026
+ async list() {
14027
+ return unwrap(await this.svc.listPrivateKeys());
14028
+ }
14029
+ async get(uuid) {
14030
+ return unwrap(await this.svc.getPrivateKey(uuid));
14031
+ }
14032
+ async create(data) {
14033
+ return unwrap(await this.svc.createPrivateKey(data));
14034
+ }
14035
+ async update(uuid, data) {
14036
+ return unwrap(await this.svc.updatePrivateKey(uuid, data));
14037
+ }
14038
+ async delete(uuid) {
14039
+ return unwrap(await this.svc.deletePrivateKey(uuid));
14040
+ }
14041
+ }
14042
+
14043
+ class DeploymentsResource {
14044
+ svc;
14045
+ constructor(svc) {
14046
+ this.svc = svc;
12196
14047
  }
12197
- const result = await service.updateApplication(options.uuid, updateOptions);
12198
- if (isErr(result)) {
12199
- console.error(source_default.red("Failed to update application"));
12200
- console.error(source_default.gray(result.error.message));
12201
- process.exit(1);
14048
+ async active(options) {
14049
+ return unwrap(await this.svc.listDeployments(options?.page, options?.perPage));
12202
14050
  }
12203
- console.log(source_default.green("Application updated successfully"));
12204
- console.log(source_default.gray(`UUID: ${result.value.uuid}`));
12205
- console.log(source_default.gray(`Name: ${result.value.name}`));
12206
- if (result.value.description) {
12207
- console.log(source_default.gray(`Description: ${result.value.description}`));
14051
+ async get(uuid) {
14052
+ return unwrap(await this.svc.getDeployment(uuid));
14053
+ }
14054
+ async logs(uuid) {
14055
+ return unwrap(await this.svc.getDeploymentLogs(uuid));
14056
+ }
14057
+ async cancel(uuid) {
14058
+ return unwrap(await this.svc.cancelDeployment(uuid));
12208
14059
  }
12209
14060
  }
12210
14061
 
12211
- // src/cli/commands/delete.ts
12212
- async function deleteCommand(uuid, options = {}) {
12213
- const service = getCoolifyService();
12214
- const initResult = await service.init();
12215
- if (isErr(initResult)) {
12216
- console.error(source_default.red("Failed to initialize Coolify service"));
12217
- console.error(source_default.gray(initResult.error.message));
12218
- process.exit(1);
14062
+ class DiagnoseResource {
14063
+ svc;
14064
+ constructor(svc) {
14065
+ this.svc = svc;
12219
14066
  }
12220
- if (!options.force && !options.yes) {
12221
- const readline = await import("readline");
12222
- const rl = readline.createInterface({
12223
- input: process.stdin,
12224
- output: process.stdout
12225
- });
12226
- const answer = await new Promise((resolve) => {
12227
- rl.question(source_default.yellow(`Are you sure you want to delete application ${source_default.bold(uuid)}? (yes/no): `), (ans) => {
12228
- rl.close();
12229
- resolve(ans.toLowerCase());
14067
+ async app(query) {
14068
+ return unwrap(await this.svc.diagnoseApplication(query));
14069
+ }
14070
+ async server(query) {
14071
+ return unwrap(await this.svc.diagnoseServer(query));
14072
+ }
14073
+ async infrastructure() {
14074
+ return unwrap(await this.svc.findInfrastructureIssues());
14075
+ }
14076
+ async deployFailure(deploymentUuid) {
14077
+ const { analyzeDeployFailure: analyzeDeployFailure2 } = await Promise.resolve().then(() => (init_network(), exports_network));
14078
+ return unwrap(await analyzeDeployFailure2(this.svc, deploymentUuid));
14079
+ }
14080
+ }
14081
+
14082
+ class NetworkResource {
14083
+ svc;
14084
+ constructor(svc) {
14085
+ this.svc = svc;
14086
+ }
14087
+ async inspect(appUuid, servicesToTest) {
14088
+ const { inspectNetwork: inspectNetwork2 } = await Promise.resolve().then(() => (init_network(), exports_network));
14089
+ return unwrap(await inspectNetwork2(this.svc, appUuid, servicesToTest));
14090
+ }
14091
+ }
14092
+
14093
+ class BatchResource {
14094
+ svc;
14095
+ constructor(svc) {
14096
+ this.svc = svc;
14097
+ }
14098
+ async restartProject(projectUuid) {
14099
+ return unwrap(await this.svc.restartProjectApps(projectUuid));
14100
+ }
14101
+ async redeployProject(projectUuid, force) {
14102
+ return unwrap(await this.svc.redeployProjectApps(projectUuid, force));
14103
+ }
14104
+ async stopAll() {
14105
+ return unwrap(await this.svc.stopAllApps());
14106
+ }
14107
+ }
14108
+
14109
+ class GitHubAppsResource {
14110
+ svc;
14111
+ constructor(svc) {
14112
+ this.svc = svc;
14113
+ }
14114
+ async list(options) {
14115
+ return unwrap(await this.svc.listGithubApps(options?.page, options?.perPage));
14116
+ }
14117
+ async create(data) {
14118
+ return unwrap(await this.svc.createGitHubApp(data));
14119
+ }
14120
+ async update(id, data) {
14121
+ return unwrap(await this.svc.updateGitHubApp(id, data));
14122
+ }
14123
+ async delete(id) {
14124
+ return unwrap(await this.svc.deleteGitHubApp(id));
14125
+ }
14126
+ }
14127
+
14128
+ class Coolify {
14129
+ svc;
14130
+ initialized = false;
14131
+ applications;
14132
+ databases;
14133
+ services;
14134
+ servers;
14135
+ projects;
14136
+ teams;
14137
+ keys;
14138
+ deployments;
14139
+ diagnose;
14140
+ network;
14141
+ batch;
14142
+ githubApps;
14143
+ constructor(options) {
14144
+ this.svc = new CoolifyService;
14145
+ if (options) {
14146
+ process.env.COOLIFY_URL = options.url;
14147
+ process.env.COOLIFY_TOKEN = options.token;
14148
+ }
14149
+ const autoInit = (resource) => {
14150
+ return new Proxy(resource, {
14151
+ get: (target, prop, receiver) => {
14152
+ const value = Reflect.get(target, prop, receiver);
14153
+ if (typeof value !== "function")
14154
+ return value;
14155
+ return async (...args) => {
14156
+ await this.ensureInit();
14157
+ return value.apply(target, args);
14158
+ };
14159
+ }
12230
14160
  });
12231
- });
12232
- if (answer !== "yes" && answer !== "y") {
12233
- console.log(source_default.gray("Operation cancelled"));
12234
- process.exit(0);
14161
+ };
14162
+ this.applications = autoInit(new ApplicationsResource(this.svc));
14163
+ this.databases = autoInit(new DatabasesResource(this.svc));
14164
+ this.services = autoInit(new ServicesResource(this.svc));
14165
+ this.servers = autoInit(new ServersResource(this.svc));
14166
+ this.projects = autoInit(new ProjectsResource(this.svc));
14167
+ this.teams = autoInit(new TeamsResource(this.svc));
14168
+ this.keys = autoInit(new KeysResource(this.svc));
14169
+ this.deployments = autoInit(new DeploymentsResource(this.svc));
14170
+ this.diagnose = autoInit(new DiagnoseResource(this.svc));
14171
+ this.network = autoInit(new NetworkResource(this.svc));
14172
+ this.batch = autoInit(new BatchResource(this.svc));
14173
+ this.githubApps = autoInit(new GitHubAppsResource(this.svc));
14174
+ }
14175
+ static fromEnv() {
14176
+ return new Coolify;
14177
+ }
14178
+ async ensureInit() {
14179
+ if (this.initialized)
14180
+ return;
14181
+ const initResult = await this.svc.init();
14182
+ if (isErr(initResult)) {
14183
+ throw new Error(`Coolify connection failed: ${initResult.error.message}`);
12235
14184
  }
14185
+ this.initialized = true;
12236
14186
  }
12237
- console.log(source_default.cyan(`Deleting application ${source_default.bold(uuid)}...`));
12238
- const result = await service.deleteApplication(uuid);
12239
- if (isErr(result)) {
12240
- console.error(source_default.red("Failed to delete application"));
12241
- console.error(source_default.gray(result.error.message));
12242
- process.exit(1);
12243
- }
12244
- console.log(source_default.green("Application deleted successfully"));
12245
- if (result.value.message) {
12246
- console.log(source_default.gray(result.value.message));
14187
+ async version() {
14188
+ await this.ensureInit();
14189
+ return unwrap(await this.svc.getVersion());
12247
14190
  }
12248
14191
  }
12249
14192
 
12250
- // src/cli/commands/destinations.ts
12251
- var import_cli_table35 = __toESM(require_table(), 1);
12252
- async function destinationsCommand(serverUuid) {
12253
- const coolify = getCoolifyService();
12254
- const initResult = await coolify.init();
12255
- if (isErr(initResult)) {
12256
- console.error(source_default.red(`Error: ${initResult.error.message}`));
14193
+ // src/cli/actions.ts
14194
+ var _sdk = null;
14195
+ function getSdk() {
14196
+ if (!_sdk)
14197
+ _sdk = Coolify.fromEnv();
14198
+ return _sdk;
14199
+ }
14200
+ async function runAction(uuid, actionLabel, callFn, successMsg) {
14201
+ const resolved = resolveUuid(uuid);
14202
+ if (!resolved) {
14203
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
12257
14204
  return;
12258
14205
  }
12259
- const result = await coolify.getServerDestinations(serverUuid);
12260
- if (isErr(result)) {
12261
- console.error(source_default.red(`Error: ${result.error.message}`));
14206
+ const spinner = ora("Connecting to Coolify...").start();
14207
+ try {
14208
+ spinner.text = `${actionLabel}...`;
14209
+ await callFn(getSdk(), resolved);
14210
+ spinner.succeed(source_default.green(successMsg(resolved)));
14211
+ } catch (error) {
14212
+ spinner.fail(source_default.red(`Failed: ${error instanceof Error ? error.message : String(error)}`));
14213
+ }
14214
+ }
14215
+ async function runList(resourceLabel, callFn, columns) {
14216
+ try {
14217
+ const items = await callFn(getSdk());
14218
+ if (items.length === 0) {
14219
+ console.log(source_default.yellow(`No ${resourceLabel} found`));
14220
+ return;
14221
+ }
14222
+ const table = new import_cli_table310.default({
14223
+ head: columns.map((c) => source_default.cyan(c.header))
14224
+ });
14225
+ for (const item of items) {
14226
+ table.push(columns.map((c) => c.value(item)));
14227
+ }
14228
+ console.log(table.toString());
14229
+ console.log(source_default.gray(`Total: ${items.length} ${resourceLabel}`));
14230
+ } catch (error) {
14231
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
14232
+ }
14233
+ }
14234
+ async function runGet(uuid, _resourceLabel, callFn, formatFn) {
14235
+ const resolved = resolveUuid(uuid);
14236
+ if (!resolved) {
14237
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
12262
14238
  return;
12263
14239
  }
12264
- const destinations = result.value;
12265
- if (destinations.length === 0) {
12266
- console.log(source_default.yellow("No destinations found"));
14240
+ try {
14241
+ const item = await callFn(getSdk(), resolved);
14242
+ formatFn(item);
14243
+ } catch (error) {
14244
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
14245
+ }
14246
+ }
14247
+ function getCliSdk() {
14248
+ return getSdk();
14249
+ }
14250
+
14251
+ // src/cli/commands/db.ts
14252
+ var dbListCommand = () => runList("database(s)", (s) => s.databases.list(), [
14253
+ { header: "UUID", value: (d) => d.uuid },
14254
+ { header: "Name", value: (d) => d.name || "-" },
14255
+ { header: "Type", value: (d) => d.type || "-" },
14256
+ { header: "Status", value: (d) => formatStatus(d.status) }
14257
+ ]);
14258
+ var dbGetCommand = (uuid) => runGet(uuid, "database", (s, u) => s.databases.get(u), (db) => {
14259
+ console.log(source_default.cyan("Database Details:"));
14260
+ console.log(source_default.gray("UUID: ") + db.uuid);
14261
+ console.log(source_default.gray("Name: ") + db.name);
14262
+ console.log(source_default.gray("Type: ") + (db.type || "-"));
14263
+ console.log(source_default.gray("Status: ") + formatStatus(db.status));
14264
+ });
14265
+ var dbStartCommand = (uuid) => runAction(uuid, "Starting database", (s, u) => s.databases.start(u), (u) => `Database started: ${u}`);
14266
+ var dbStopCommand = (uuid) => runAction(uuid, "Stopping database", (s, u) => s.databases.stop(u), (u) => `Database stopped: ${u}`);
14267
+ var dbRestartCommand = (uuid) => runAction(uuid, "Restarting database", (s, u) => s.databases.restart(u), (u) => `Database restarted: ${u}`);
14268
+ var dbDeleteCommand = (uuid) => runAction(uuid, "Deleting database", (s, u) => s.databases.delete(u), (u) => `Database deleted: ${u}`);
14269
+
14270
+ // src/cli/commands/svc.ts
14271
+ var svcListCommand = () => runList("service(s)", (s) => s.services.list(), [
14272
+ { header: "UUID", value: (s) => s.uuid },
14273
+ { header: "Name", value: (s) => s.name || "-" },
14274
+ { header: "Type", value: (s) => s.type || "-" },
14275
+ { header: "Status", value: (s) => formatStatus(s.status) }
14276
+ ]);
14277
+ var svcGetCommand = (uuid) => runGet(uuid, "service", (s, u) => s.services.get(u), (svc) => {
14278
+ console.log(source_default.cyan("Service Details:"));
14279
+ console.log(source_default.gray("UUID: ") + svc.uuid);
14280
+ console.log(source_default.gray("Name: ") + svc.name);
14281
+ console.log(source_default.gray("Type: ") + (svc.type || "-"));
14282
+ console.log(source_default.gray("Status: ") + formatStatus(svc.status));
14283
+ });
14284
+ var svcStartCommand = (uuid) => runAction(uuid, "Starting service", (s, u) => s.services.start(u), (u) => `Service started: ${u}`);
14285
+ var svcStopCommand = (uuid) => runAction(uuid, "Stopping service", (s, u) => s.services.stop(u), (u) => `Service stopped: ${u}`);
14286
+ var svcRestartCommand = (uuid) => runAction(uuid, "Restarting service", (s, u) => s.services.restart(u), (u) => `Service restarted: ${u}`);
14287
+ var svcDeleteCommand = (uuid) => runAction(uuid, "Deleting service", (s, u) => s.services.delete(u), (u) => `Service deleted: ${u}`);
14288
+
14289
+ // src/cli/commands/keys.ts
14290
+ var keysListCommand = () => runList("key(s)", (s) => s.keys.list(), [
14291
+ { header: "UUID", value: (k) => k.uuid },
14292
+ { header: "Name", value: (k) => k.name || "-" },
14293
+ { header: "Git?", value: (k) => k.is_git_related ? "Yes" : "No" },
14294
+ {
14295
+ header: "Created",
14296
+ value: (k) => k.created_at ? new Date(k.created_at).toLocaleDateString() : "-"
14297
+ }
14298
+ ]);
14299
+ var keysGetCommand = (uuid) => runGet(uuid, "private key", (s, u) => s.keys.get(u), (key) => {
14300
+ console.log(source_default.cyan("Private Key Details:"));
14301
+ console.log(source_default.gray("UUID: ") + key.uuid);
14302
+ console.log(source_default.gray("Name: ") + key.name);
14303
+ console.log(source_default.gray("Git-related:") + (key.is_git_related ? " Yes" : " No"));
14304
+ });
14305
+ var keysDeleteCommand = (uuid) => runAction(uuid, "Deleting private key", (s, u) => s.keys.delete(u), (u) => `Private key deleted: ${u}`);
14306
+
14307
+ // src/cli/commands/teams.ts
14308
+ var teamsListCommand = () => runList("team(s)", (s) => s.teams.list(), [
14309
+ { header: "ID", value: (t) => String(t.id) },
14310
+ { header: "Name", value: (t) => t.name },
14311
+ { header: "Personal", value: (t) => t.personal_team ? "Yes" : "No" }
14312
+ ]);
14313
+ async function teamsCurrentCommand() {
14314
+ try {
14315
+ const team = await getCliSdk().teams.current();
14316
+ console.log(source_default.cyan("Current Team:"));
14317
+ console.log(source_default.gray("ID: ") + team.id);
14318
+ console.log(source_default.gray("Name: ") + team.name);
14319
+ console.log(source_default.gray("Personal: ") + (team.personal_team ? "Yes" : "No"));
14320
+ } catch (error) {
14321
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
14322
+ }
14323
+ }
14324
+ async function teamsMembersCommand(teamId) {
14325
+ const id = parseInt(teamId, 10);
14326
+ if (isNaN(id)) {
14327
+ console.error(source_default.red("Error: Team ID must be a number"));
12267
14328
  return;
12268
14329
  }
12269
- const table = new import_cli_table35.default({
12270
- head: [
12271
- source_default.cyan("UUID"),
12272
- source_default.cyan("Name"),
12273
- source_default.cyan("Network")
12274
- ]
12275
- });
12276
- for (const dest of destinations) {
12277
- table.push([
12278
- dest.uuid,
12279
- dest.name,
12280
- dest.network || "N/A"
12281
- ]);
14330
+ try {
14331
+ const members = await getCliSdk().teams.members(id);
14332
+ if (members.length === 0) {
14333
+ console.log(source_default.yellow("No members found"));
14334
+ return;
14335
+ }
14336
+ console.log(source_default.cyan(`Team ${teamId} Members:`));
14337
+ for (const m of members) {
14338
+ console.log(` ${source_default.bold(m.name)} (${source_default.gray(m.email)})`);
14339
+ }
14340
+ } catch (error) {
14341
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12282
14342
  }
12283
- console.log(table.toString());
12284
- console.log(source_default.gray(`Total: ${destinations.length} destination(s)`));
12285
14343
  }
12286
14344
 
12287
- // src/cli/commands/show.ts
12288
- async function showCommand(uuid) {
12289
- const coolify = getCoolifyService();
12290
- const initResult = await coolify.init();
12291
- if (isErr(initResult)) {
12292
- console.error(source_default.red(`Error: ${initResult.error.message}`));
14345
+ // src/cli/commands/diagnose.ts
14346
+ async function diagnoseAppCommand(query) {
14347
+ const resolved = query || resolveUuid(undefined);
14348
+ if (!resolved) {
14349
+ console.error(source_default.red("Error: No app name/UUID provided and no .coolify.json found"));
12293
14350
  return;
12294
14351
  }
12295
- const result = await coolify.listApplications();
12296
- if (isErr(result)) {
12297
- console.error(source_default.red(`Error: ${result.error.message}`));
12298
- return;
14352
+ console.log(source_default.cyan(`Diagnosing application: ${resolved}...
14353
+ `));
14354
+ try {
14355
+ const { application, recentDeployments, envVarCount, recentLogs, issues } = await getCliSdk().diagnose.app(resolved);
14356
+ console.log(source_default.bold("Application:"));
14357
+ console.log(` ${source_default.gray("Name:")} ${application.name}`);
14358
+ console.log(` ${source_default.gray("UUID:")} ${application.uuid}`);
14359
+ console.log(` ${source_default.gray("Status:")} ${formatStatus(application.status)}`);
14360
+ console.log(` ${source_default.gray("FQDN:")} ${application.fqdn || "none"}`);
14361
+ console.log(` ${source_default.gray("Env vars:")} ${envVarCount}`);
14362
+ if (recentDeployments.length > 0) {
14363
+ console.log(source_default.bold(`
14364
+ Recent Deployments:`));
14365
+ for (const d of recentDeployments) {
14366
+ const status = d.status?.includes("failed") ? source_default.red(d.status) : source_default.green(d.status);
14367
+ console.log(` ${source_default.gray(d.uuid.slice(0, 12))} ${status} ${source_default.gray(new Date(d.created_at).toLocaleString())}`);
14368
+ }
14369
+ }
14370
+ if (recentLogs.length > 0) {
14371
+ console.log(source_default.bold(`
14372
+ Recent Logs (last 5):`));
14373
+ for (const line of recentLogs.slice(-5)) {
14374
+ console.log(` ${source_default.gray(line)}`);
14375
+ }
14376
+ }
14377
+ if (issues.length > 0) {
14378
+ console.log(source_default.bold.red(`
14379
+ Issues (${issues.length}):`));
14380
+ for (const issue of issues) {
14381
+ console.log(` ${source_default.red("!")} ${issue}`);
14382
+ }
14383
+ } else {
14384
+ console.log(source_default.bold.green(`
14385
+ No issues detected`));
14386
+ }
14387
+ } catch (error) {
14388
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12299
14389
  }
12300
- const apps = result.value;
12301
- const app = apps.find((a) => a.uuid === uuid || a.uuid.startsWith(uuid));
12302
- if (!app) {
12303
- console.error(source_default.red(`Application not found: ${uuid}`));
12304
- return;
14390
+ }
14391
+ async function diagnoseServerCommand(query) {
14392
+ console.log(source_default.cyan(`Diagnosing server: ${query}...
14393
+ `));
14394
+ try {
14395
+ const { server, resources, domains, issues } = await getCliSdk().diagnose.server(query);
14396
+ console.log(source_default.bold("Server:"));
14397
+ console.log(` ${source_default.gray("Name:")} ${server.name}`);
14398
+ console.log(` ${source_default.gray("UUID:")} ${server.uuid}`);
14399
+ console.log(` ${source_default.gray("IP:")} ${server.ip || "-"}`);
14400
+ console.log(` ${source_default.gray("Reachable:")} ${server.is_reachable ? source_default.green("Yes") : source_default.red("No")}`);
14401
+ console.log(` ${source_default.gray("Resources:")} ${resources.length}`);
14402
+ console.log(` ${source_default.gray("Domains:")} ${domains.length}`);
14403
+ if (issues.length > 0) {
14404
+ console.log(source_default.bold.red(`
14405
+ Issues (${issues.length}):`));
14406
+ for (const issue of issues) {
14407
+ console.log(` ${source_default.red("!")} ${issue}`);
14408
+ }
14409
+ } else {
14410
+ console.log(source_default.bold.green(`
14411
+ No issues detected`));
14412
+ }
14413
+ } catch (error) {
14414
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12305
14415
  }
12306
- console.log(source_default.cyan("Application Details:"));
12307
- console.log("");
12308
- console.log(source_default.gray("UUID: ") + source_default.white(app.uuid));
12309
- console.log(source_default.gray("Name: ") + source_default.white(app.name));
12310
- console.log(source_default.gray("Status: ") + source_default.white(app.status));
12311
- console.log(source_default.gray("Description:") + source_default.white(app.description || "N/A"));
12312
- console.log(source_default.gray("Repository: ") + source_default.white(app.git_repository || "N/A"));
12313
- console.log(source_default.gray("Branch: ") + source_default.white(app.git_branch || "N/A"));
12314
- console.log(source_default.gray("Build Pack: ") + source_default.white(app.build_pack || "N/A"));
12315
- console.log(source_default.gray("Ports: ") + source_default.white(app.ports_exposes || "N/A"));
12316
- console.log(source_default.gray("FQDN: ") + source_default.white(app.fqdn || "N/A"));
12317
- console.log(source_default.gray("Dockerfile: ") + source_default.white(app.dockerfile_location || "N/A"));
12318
- console.log(source_default.gray("Base Dir: ") + source_default.white(app.base_directory || "N/A"));
12319
- console.log("");
12320
- console.log(source_default.cyan("Destination:"));
12321
- if (app.destination) {
12322
- console.log(source_default.gray(" UUID: ") + source_default.white(app.destination.uuid));
12323
- console.log(source_default.gray(" Name: ") + source_default.white(app.destination.name));
12324
- if (app.destination.server) {
12325
- console.log(source_default.gray(" Server:") + source_default.white(` ${app.destination.server.name} (${app.destination.server.ip})`));
14416
+ }
14417
+ async function scanIssuesCommand() {
14418
+ console.log(source_default.cyan(`Scanning infrastructure...
14419
+ `));
14420
+ try {
14421
+ const { totalServers, totalApps, totalDatabases, totalServices, issues } = await getCliSdk().diagnose.infrastructure();
14422
+ console.log(source_default.bold("Infrastructure Summary:"));
14423
+ console.log(` ${source_default.gray("Servers:")} ${totalServers}`);
14424
+ console.log(` ${source_default.gray("Apps:")} ${totalApps}`);
14425
+ console.log(` ${source_default.gray("Databases:")} ${totalDatabases}`);
14426
+ console.log(` ${source_default.gray("Services:")} ${totalServices}`);
14427
+ if (issues.length > 0) {
14428
+ console.log(source_default.bold.red(`
14429
+ Issues (${issues.length}):`));
14430
+ for (const issue of issues) {
14431
+ console.log(` ${source_default.red("!")} [${issue.type}] ${issue.resource} (${issue.uuid}): ${issue.message}`);
14432
+ }
14433
+ } else {
14434
+ console.log(source_default.bold.green(`
14435
+ No issues detected across all infrastructure`));
12326
14436
  }
12327
- } else {
12328
- console.log(source_default.yellow(" No destination configured"));
14437
+ } catch (error) {
14438
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12329
14439
  }
12330
- console.log("");
12331
- console.log(source_default.cyan("Commands:"));
12332
- if (app.install_command)
12333
- console.log(source_default.gray(" Install: ") + source_default.white(app.install_command));
12334
- if (app.build_command)
12335
- console.log(source_default.gray(" Build: ") + source_default.white(app.build_command));
12336
- if (app.start_command)
12337
- console.log(source_default.gray(" Start: ") + source_default.white(app.start_command));
12338
14440
  }
12339
14441
 
12340
- // src/cli/commands/deployments.ts
12341
- var import_cli_table36 = __toESM(require_table(), 1);
12342
- async function deploymentsCommand(uuid, options = {}) {
12343
- const coolify = getCoolifyService();
12344
- const initResult = await coolify.init();
12345
- if (isErr(initResult)) {
12346
- console.error(source_default.red(`Error: ${initResult.error.message}`));
14442
+ // src/cli/commands/exec.ts
14443
+ async function execCommand(uuid, command) {
14444
+ const resolved = resolveUuid(uuid);
14445
+ if (!resolved) {
14446
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
12347
14447
  return;
12348
14448
  }
12349
- const result = await coolify.getApplicationDeploymentHistory(uuid);
12350
- if (isErr(result)) {
12351
- console.error(source_default.red(`Error: ${result.error.message}`));
12352
- return;
14449
+ console.log(source_default.gray(`Executing on ${resolved}: ${command}`));
14450
+ try {
14451
+ const result = await getCliSdk().applications.exec(resolved, command);
14452
+ if (result.response) {
14453
+ console.log(result.response);
14454
+ } else if (result.message) {
14455
+ console.log(source_default.green(result.message));
14456
+ }
14457
+ } catch (error) {
14458
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12353
14459
  }
12354
- let deployments = result.value;
12355
- deployments = deployments.reverse();
12356
- if (options.limit) {
12357
- deployments = deployments.slice(0, options.limit);
14460
+ }
14461
+
14462
+ // src/cli/commands/active-deployments.ts
14463
+ var activeDeploymentsCommand = () => runList("active deployment(s)", (s) => s.deployments.active(), [
14464
+ { header: "UUID", value: (d) => d.uuid },
14465
+ { header: "Status", value: (d) => formatStatus(d.status) },
14466
+ { header: "Commit", value: (d) => d.commit?.slice(0, 7) || "-" },
14467
+ {
14468
+ header: "Created",
14469
+ value: (d) => new Date(d.created_at).toLocaleString()
12358
14470
  }
12359
- if (deployments.length === 0) {
12360
- console.log(source_default.yellow("No deployments found"));
14471
+ ]);
14472
+
14473
+ // src/cli/commands/network.ts
14474
+ async function networkInspectCommand(uuid, options = {}) {
14475
+ const resolved = resolveUuid(uuid);
14476
+ if (!resolved) {
14477
+ console.error(source_default.red("Error: No UUID provided and no .coolify.json found"));
12361
14478
  return;
12362
14479
  }
12363
- const table = new import_cli_table36.default({
12364
- head: [
12365
- source_default.cyan("ID"),
12366
- source_default.cyan("UUID"),
12367
- source_default.cyan("Status"),
12368
- source_default.cyan("Commit"),
12369
- source_default.cyan("Created")
12370
- ],
12371
- ...options.full ? { colWidths: [8, 36, 20, 10, 20] } : {}
12372
- });
12373
- for (const dep of deployments) {
12374
- table.push([
12375
- String(dep.id),
12376
- options.full ? dep.uuid : dep.uuid.slice(0, 8),
12377
- formatStatus(dep.status),
12378
- dep.commit?.slice(0, 7) || "-",
12379
- new Date(dep.created_at).toLocaleString()
12380
- ]);
14480
+ const servicesToTest = options.services ? options.services.split(",").map((s) => s.trim()) : [];
14481
+ console.log(source_default.cyan(`Inspecting network for ${resolved}...
14482
+ `));
14483
+ try {
14484
+ const info = await getCliSdk().network.inspect(resolved, servicesToTest);
14485
+ console.log(source_default.bold("Container Hosts (/etc/hosts):"));
14486
+ if (info.hosts.length > 0) {
14487
+ for (const h of info.hosts) {
14488
+ console.log(` ${source_default.gray(h)}`);
14489
+ }
14490
+ } else {
14491
+ console.log(source_default.yellow(" No entries"));
14492
+ }
14493
+ if (info.interfaces.length > 0) {
14494
+ console.log(source_default.bold(`
14495
+ Network Interfaces:`));
14496
+ for (const iface of info.interfaces) {
14497
+ console.log(` ${source_default.gray(iface.trim())}`);
14498
+ }
14499
+ }
14500
+ const envEntries = Object.entries(info.networkEnv);
14501
+ if (envEntries.length > 0) {
14502
+ console.log(source_default.bold(`
14503
+ Network Environment Variables:`));
14504
+ for (const [key, val] of envEntries) {
14505
+ console.log(` ${source_default.green(key)} = ${source_default.gray(val)}`);
14506
+ }
14507
+ }
14508
+ if (info.dns.length > 0) {
14509
+ console.log(source_default.bold(`
14510
+ DNS Resolution:`));
14511
+ for (const d of info.dns) {
14512
+ const status = d.resolved ? source_default.green(`✓ ${d.ip}`) : source_default.red("✗ FAILED");
14513
+ console.log(` ${source_default.white(d.hostname)} → ${status}`);
14514
+ }
14515
+ }
14516
+ if (info.connectivity.length > 0) {
14517
+ console.log(source_default.bold(`
14518
+ Service Connectivity:`));
14519
+ for (const c of info.connectivity) {
14520
+ const status = c.reachable ? source_default.green(`✓ reachable (${c.responseTime}ms)`) : source_default.red("✗ unreachable");
14521
+ console.log(` ${source_default.white(c.target)} → ${status}`);
14522
+ }
14523
+ }
14524
+ console.log(source_default.bold(`
14525
+ Trace:`));
14526
+ for (const step of info.trace.steps) {
14527
+ console.log(` ${source_default.gray(step.step)} ${source_default.yellow(step.durationMs + "ms")}${step.detail ? source_default.gray(` (${step.detail})`) : ""}`);
14528
+ }
14529
+ console.log(source_default.gray(` Total: ${info.trace.totalMs}ms`));
14530
+ } catch (error) {
14531
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
14532
+ }
14533
+ }
14534
+ async function analyzeDeployCommand(deploymentUuid) {
14535
+ console.log(source_default.cyan(`Analyzing deployment ${deploymentUuid}...
14536
+ `));
14537
+ try {
14538
+ const analysis = await getCliSdk().diagnose.deployFailure(deploymentUuid);
14539
+ console.log(source_default.bold("Deployment:"));
14540
+ console.log(` ${source_default.gray("UUID:")} ${analysis.deploymentUuid}`);
14541
+ console.log(` ${source_default.gray("Status:")} ${analysis.status}`);
14542
+ console.log(` ${source_default.gray("Category:")} ${source_default.yellow(analysis.category)}`);
14543
+ console.log(source_default.bold.red(`
14544
+ Diagnosis: ${analysis.summary}`));
14545
+ console.log(source_default.cyan(`Suggestion: ${analysis.suggestion}`));
14546
+ if (analysis.errors.length > 0) {
14547
+ console.log(source_default.bold(`
14548
+ Error Lines (${analysis.errors.length}):`));
14549
+ for (const line of analysis.errors.slice(0, 10)) {
14550
+ console.log(` ${source_default.red(line.trim())}`);
14551
+ }
14552
+ if (analysis.errors.length > 10) {
14553
+ console.log(source_default.gray(` ... and ${analysis.errors.length - 10} more`));
14554
+ }
14555
+ }
14556
+ console.log(source_default.bold(`
14557
+ Trace:`));
14558
+ for (const step of analysis.trace.steps) {
14559
+ console.log(` ${source_default.gray(step.step)} ${source_default.yellow(step.durationMs + "ms")}${step.detail ? source_default.gray(` (${step.detail})`) : ""}`);
14560
+ }
14561
+ } catch (error) {
14562
+ console.error(source_default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
12381
14563
  }
12382
- console.log(table.toString());
12383
- console.log(source_default.gray(`Total: ${deployments.length} deployment(s)`));
12384
14564
  }
12385
14565
 
12386
14566
  // src/cli/index.ts
@@ -12388,26 +14568,77 @@ var program2 = new Command;
12388
14568
  program2.name("coolify-mcp").description("CLI for Coolify deployment management").version("0.1.0");
12389
14569
  program2.command("create").description("Create a new application").option("--name <name>", "Application name").option("--description <desc>", "Application description").option("--server <uuid>", "Server UUID").option("--project <uuid>", "Project UUID").option("--environment <uuid>", "Environment UUID (auto-fetched if not provided)").option("--repo <url>", "Git repository URL").option("--branch <branch>", "Git branch", "main").option("--type <type>", "Application type (public, private-github-app, private-deploy-key, dockerfile, docker-image, docker-compose)", "public").option("--build-pack <pack>", "Build pack (dockerfile, nixpacks, static, dockercompose)", "dockerfile").option("--ports <ports>", "Ports to expose (default: 3000)", "3000").option("--docker-image <image>", "Docker image (for docker-image type)").option("--docker-compose <content>", "Docker Compose content (for docker-compose type)").option("--docker-compose-location <path>", 'Docker Compose file path (for dockercompose buildPack, e.g., "docker-compose.yml")').option("--dockerfile-location <path>", 'Dockerfile location (e.g., "apps/haidodocs/Dockerfile")').option("--base-directory <dir>", 'Base directory for build context (default: "/")', "/").action(createCommand2);
12390
14570
  program2.command("config").description("Manage configuration").argument("[action]", "Action to perform (set, get, path)").option("--key <key>", 'Configuration key (for "set" action)').option("--value <value>", 'Configuration value (for "set" action)').action(configCommand);
12391
- program2.command("list").description("List all applications").option("-t, --team <id>", "Filter by team ID").option("-p, --project <id>", "Filter by project ID").option("--full", "Show full UUIDs instead of truncated").action(listCommand);
12392
- program2.command("deploy <uuid>").description("Deploy an application").option("-f, --force", "Force rebuild without cache").option("-t, --tag <tag>", "Deploy specific tag/version").action(deployCommand);
12393
- program2.command("logs <uuid>").description("Get application logs").option("-n, --lines <number>", "Number of lines to retrieve", "50").option("-f, --follow", "Follow logs in real-time").action((uuid, options) => {
14571
+ program2.command("list").description("List all applications").option("-t, --team <id>", "Filter by team ID").option("-p, --project <id>", "Filter by project ID").action(listCommand);
14572
+ program2.command("deploy [uuid]").description("Deploy an application (reads .coolify.json if no UUID)").option("-f, --force", "Force rebuild without cache").option("-t, --tag <tag>", "Deploy specific tag/version").action(deployCommand);
14573
+ program2.command("logs [uuid]").description("Get application logs (reads .coolify.json if no UUID)").option("-n, --lines <number>", "Number of lines to retrieve", "50").option("-f, --follow", "Follow logs in real-time").action((uuid, options) => {
12394
14574
  const lines = parseInt(options.lines, 10);
12395
14575
  logsCommand(uuid, { lines, follow: options.follow });
12396
14576
  });
12397
- program2.command("servers").description("List available servers").option("--full", "Show full UUIDs instead of truncated").action((options) => serversCommand(options));
12398
- program2.command("projects").description("List or create projects").option("--full", "Show full UUIDs instead of truncated").option("--create <name>", "Create a new project with this name").option("--description <desc>", "Project description (use with --create)").action((options) => projectsCommand(options));
12399
- program2.command("environments <projectUuid>").description("List environments for a project").option("--full", "Show full UUIDs instead of truncated").action((projectUuid, options) => environmentsCommand(projectUuid, options));
12400
- program2.command("env <uuid>").description("Manage environment variables for an application").option("--set <KEY=VALUE>", "Set an environment variable").option("--delete <KEY>", "Delete an environment variable").option("--buildtime", "Mark variable as build-time only (use with --set)").action((uuid, options) => envCommand(uuid, options));
12401
- program2.command("update <uuid>").description("Update an application configuration").option("--name <name>", "Application name").option("--description <desc>", "Application description").option("--build-pack <pack>", "Build pack (dockerfile, nixpacks, static)").option("--git-branch <branch>", "Git branch").option("--ports <ports>", "Ports to expose (e.g., 3000)").option("--install-command <cmd>", "Install command (nixpacks)").option("--build-command <cmd>", "Build command").option("--start-command <cmd>", "Start command").option("--dockerfile-location <path>", 'Dockerfile location (e.g., "apps/haidodocs/Dockerfile")').option("--base-directory <dir>", 'Base directory for build context (e.g., "/")').option("--domains <domains>", 'Domains (comma-separated with protocol, e.g., "https://app.example.com")').option("--auto-deploy", "Enable auto-deploy on git push").option("--no-auto-deploy", "Disable auto-deploy on git push").option("--force-https", "Enable forced HTTPS redirect").action((uuid, options) => updateCommand({ uuid, ...options }));
12402
- program2.command("delete <uuid>").description("Delete an application").option("-f, --force", "Skip confirmation prompt").option("-y, --yes", "Skip confirmation prompt (alias for --force)").action((uuid, options) => deleteCommand(uuid, options));
14577
+ program2.command("servers").description("List available servers").action((options) => serversCommand(options));
14578
+ program2.command("projects").description("List or create projects").option("--create <name>", "Create a new project with this name").option("--description <desc>", "Project description (use with --create)").action((options) => projectsCommand(options));
14579
+ program2.command("environments <projectUuid>").description("List environments for a project").action((projectUuid, options) => environmentsCommand(projectUuid, options));
14580
+ program2.command("env [uuid]").description("Manage env vars (reads .coolify.json if no UUID)").option("--set <KEY=VALUE>", "Set an environment variable").option("--delete <KEY>", "Delete an environment variable").option("--buildtime", "Mark variable as build-time only (use with --set)").action((uuid, options) => envCommand(uuid, options));
14581
+ program2.command("update [uuid]").description("Update app config (reads .coolify.json if no UUID)").option("--name <name>", "Application name").option("--description <desc>", "Application description").option("--build-pack <pack>", "Build pack (dockerfile, nixpacks, static)").option("--git-branch <branch>", "Git branch").option("--ports <ports>", "Ports to expose (e.g., 3000)").option("--install-command <cmd>", "Install command (nixpacks)").option("--build-command <cmd>", "Build command").option("--start-command <cmd>", "Start command").option("--dockerfile-location <path>", 'Dockerfile location (e.g., "apps/haidodocs/Dockerfile")').option("--base-directory <dir>", 'Base directory for build context (e.g., "/")').option("--domains <domains>", 'Domains (comma-separated with protocol, e.g., "https://app.example.com")').option("--auto-deploy", "Enable auto-deploy on git push").option("--no-auto-deploy", "Disable auto-deploy on git push").option("--force-https", "Enable forced HTTPS redirect").action((uuid, options) => updateCommand({ uuid, ...options }));
14582
+ program2.command("delete [uuid]").description("Delete application (reads .coolify.json if no UUID)").option("-f, --force", "Skip confirmation prompt").option("-y, --yes", "Skip confirmation prompt (alias for --force)").action((uuid, options) => deleteCommand(uuid, options));
12403
14583
  program2.command("destinations <serverUuid>").description("List available destinations for a server").action(destinationsCommand);
12404
- program2.command("show <uuid>").description("Show detailed information about an application").action(showCommand);
12405
- program2.command("deployments <uuid>").description("Show deployment history for an application").option("--full", "Show full UUIDs").option("-n, --limit <number>", "Limit number of deployments shown", "10").action((uuid, options) => {
14584
+ program2.command("show [uuid]").description("Show app details (reads .coolify.json if no UUID)").action(showCommand);
14585
+ program2.command("deployments [uuid]").description("Show deployment history (reads .coolify.json if no UUID)").option("-n, --limit <number>", "Limit number of deployments shown", "10").action((uuid, options) => {
12406
14586
  const limit = parseInt(options.limit, 10);
12407
14587
  deploymentsCommand(uuid, { full: options.full, limit });
12408
14588
  });
14589
+ program2.command("start [uuid]").description("Start application (reads .coolify.json if no UUID)").action(startCommand);
14590
+ program2.command("stop [uuid]").description("Stop application (reads .coolify.json if no UUID)").action(stopCommand);
14591
+ program2.command("restart [uuid]").description("Restart application (reads .coolify.json if no UUID)").action(restartCommand);
14592
+ program2.command("build-logs <deployment-uuid>").description("View build/deployment logs for a specific deployment").option("-n, --lines <number>", "Number of lines to show (tail)").action((deploymentUuid, options) => {
14593
+ const lines = options.lines ? parseInt(options.lines, 10) : undefined;
14594
+ buildLogsCommand(deploymentUuid, { lines });
14595
+ });
14596
+ program2.command("service-logs <uuid> <service-name>").description("View logs for a specific docker-compose service").option("-n, --lines <number>", "Number of lines to retrieve", "50").action((uuid, serviceName, options) => {
14597
+ const lines = parseInt(options.lines, 10);
14598
+ serviceLogsCommand(uuid, serviceName, { lines });
14599
+ });
14600
+ program2.command("version").description("Show Coolify server version").action(versionCommand);
14601
+ program2.command("databases").description("List all databases").action((options) => databasesCommand(options));
14602
+ program2.command("services").description("List all services").action((options) => servicesCommand(options));
14603
+ program2.command("cancel-deploy <deployment-uuid>").description("Cancel an in-progress deployment").action(cancelDeployCommand);
14604
+ program2.command("server-resources <server-uuid>").description("List resources deployed on a server").action((serverUuid, options) => serverResourcesCommand(serverUuid, options));
14605
+ var db = program2.command("db").description("Manage databases");
14606
+ db.command("list").description("List all databases").action(dbListCommand);
14607
+ db.command("get <uuid>").description("Get database details").action(dbGetCommand);
14608
+ db.command("start <uuid>").description("Start a database").action(dbStartCommand);
14609
+ db.command("stop <uuid>").description("Stop a database").action(dbStopCommand);
14610
+ db.command("restart <uuid>").description("Restart a database").action(dbRestartCommand);
14611
+ db.command("delete <uuid>").description("Delete a database").action(dbDeleteCommand);
14612
+ db.action(() => db.help());
14613
+ var svc = program2.command("svc").description("Manage services");
14614
+ svc.command("list").description("List all services").action(svcListCommand);
14615
+ svc.command("get <uuid>").description("Get service details").action(svcGetCommand);
14616
+ svc.command("start <uuid>").description("Start a service").action(svcStartCommand);
14617
+ svc.command("stop <uuid>").description("Stop a service").action(svcStopCommand);
14618
+ svc.command("restart <uuid>").description("Restart a service").action(svcRestartCommand);
14619
+ svc.command("delete <uuid>").description("Delete a service").action(svcDeleteCommand);
14620
+ svc.action(() => svc.help());
14621
+ var keys = program2.command("keys").description("Manage SSH private keys");
14622
+ keys.command("list").description("List all private keys").action(keysListCommand);
14623
+ keys.command("get <uuid>").description("Get private key details").action(keysGetCommand);
14624
+ keys.command("delete <uuid>").description("Delete a private key").action(keysDeleteCommand);
14625
+ keys.action(() => keys.help());
14626
+ var team = program2.command("team").description("Manage teams");
14627
+ team.command("list").description("List all teams").action(teamsListCommand);
14628
+ team.command("current").description("Show current team").action(teamsCurrentCommand);
14629
+ team.command("members <team-id>").description("Show team members").action(teamsMembersCommand);
14630
+ team.action(() => team.help());
14631
+ program2.command("diagnose [query]").description("Diagnose application (reads .coolify.json if no query)").action(diagnoseAppCommand);
14632
+ program2.command("diagnose-server <query>").description("Diagnose a server (name, IP, or UUID)").action(diagnoseServerCommand);
14633
+ program2.command("scan").description("Scan all infrastructure for issues").action(scanIssuesCommand);
14634
+ program2.command("exec [uuid] <command>").description("Execute command on app container (reads .coolify.json)").action(execCommand);
14635
+ program2.command("active-deployments").description("List all active/queued deployments").action(activeDeploymentsCommand);
14636
+ var net = program2.command("network").description("Network diagnostics");
14637
+ net.command("inspect [uuid]").description("Inspect container network (DNS, hosts, connectivity)").option("--services <names>", "Comma-separated service names to test (e.g., db,redis)").action((uuid, options) => networkInspectCommand(uuid, options));
14638
+ net.action(() => net.help());
14639
+ program2.command("analyze-deploy <deployment-uuid>").description("Analyze a failed deployment (extract errors, suggest fixes)").action(analyzeDeployCommand);
12409
14640
  program2.action(() => {
12410
- console.log(source_default.cyan("Coolify MCP CLI"));
14641
+ console.log(source_default.cyan("Coolify MCP CLI v0.6.0"));
12411
14642
  console.log(source_default.gray(`Manage Coolify deployments from the command line
12412
14643
  `));
12413
14644
  program2.help();