@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
@@ -6,69 +6,100 @@
6
6
  * @module
7
7
  */
8
8
 
9
- import { isErr } from '@mks2508/no-throw'
10
- import chalk from 'chalk'
11
- import { getCoolifyService } from '../../coolify/index.js'
12
- import type { ICoolifyApplication } from '../../coolify/types.js'
9
+ import { isErr } from "@mks2508/no-throw";
10
+ import chalk from "chalk";
11
+ import { getCoolifyService } from "../../coolify/index.js";
12
+ import { resolveUuid } from "../coolify-state.js";
13
13
 
14
14
  /**
15
15
  * Show command handler.
16
+ * If no UUID is provided, reads from .coolify.json in the current directory.
16
17
  *
17
- * @param uuid - Application UUID
18
+ * @param uuid - Application UUID (optional if .coolify.json exists)
18
19
  */
19
- export async function showCommand(uuid: string) {
20
- const coolify = getCoolifyService()
21
- const initResult = await coolify.init()
20
+ export async function showCommand(uuid?: string) {
21
+ const resolvedUuid = resolveUuid(uuid);
22
+ if (!resolvedUuid) {
23
+ console.error(
24
+ chalk.red("Error: No UUID provided and no .coolify.json found"),
25
+ );
26
+ return;
27
+ }
28
+ uuid = resolvedUuid;
29
+ const coolify = getCoolifyService();
30
+ const initResult = await coolify.init();
22
31
 
23
32
  if (isErr(initResult)) {
24
- console.error(chalk.red(`Error: ${initResult.error.message}`))
25
- return
33
+ console.error(chalk.red(`Error: ${initResult.error.message}`));
34
+ return;
26
35
  }
27
36
 
28
37
  // We need to add getApplication method to CoolifyService
29
38
  // For now, use listApplications and filter
30
- const result = await coolify.listApplications()
39
+ const result = await coolify.listApplications();
31
40
 
32
41
  if (isErr(result)) {
33
- console.error(chalk.red(`Error: ${result.error.message}`))
34
- return
42
+ console.error(chalk.red(`Error: ${result.error.message}`));
43
+ return;
35
44
  }
36
45
 
37
- const apps = result.value
38
- const app = apps.find(a => a.uuid === uuid || a.uuid.startsWith(uuid))
46
+ const apps = result.value;
47
+ const app = apps.find((a) => a.uuid === uuid || a.uuid.startsWith(uuid));
39
48
 
40
49
  if (!app) {
41
- console.error(chalk.red(`Application not found: ${uuid}`))
42
- return
50
+ console.error(chalk.red(`Application not found: ${uuid}`));
51
+ return;
43
52
  }
44
53
 
45
- console.log(chalk.cyan('Application Details:'))
46
- console.log('')
47
- console.log(chalk.gray('UUID: ') + chalk.white(app.uuid))
48
- console.log(chalk.gray('Name: ') + chalk.white(app.name))
49
- console.log(chalk.gray('Status: ') + chalk.white(app.status))
50
- console.log(chalk.gray('Description:') + chalk.white(app.description || 'N/A'))
51
- console.log(chalk.gray('Repository: ') + chalk.white(app.git_repository || 'N/A'))
52
- console.log(chalk.gray('Branch: ') + chalk.white(app.git_branch || 'N/A'))
53
- console.log(chalk.gray('Build Pack: ') + chalk.white(app.build_pack || 'N/A'))
54
- console.log(chalk.gray('Ports: ') + chalk.white(app.ports_exposes || 'N/A'))
55
- console.log(chalk.gray('FQDN: ') + chalk.white(app.fqdn || 'N/A'))
56
- console.log(chalk.gray('Dockerfile: ') + chalk.white(app.dockerfile_location || 'N/A'))
57
- console.log(chalk.gray('Base Dir: ') + chalk.white(app.base_directory || 'N/A'))
58
- console.log('')
59
- console.log(chalk.cyan('Destination:'))
54
+ console.log(chalk.cyan("Application Details:"));
55
+ console.log("");
56
+ console.log(chalk.gray("UUID: ") + chalk.white(app.uuid));
57
+ console.log(chalk.gray("Name: ") + chalk.white(app.name));
58
+ console.log(chalk.gray("Status: ") + chalk.white(app.status));
59
+ console.log(
60
+ chalk.gray("Description:") + chalk.white(app.description || "N/A"),
61
+ );
62
+ console.log(
63
+ chalk.gray("Repository: ") + chalk.white(app.git_repository || "N/A"),
64
+ );
65
+ console.log(
66
+ chalk.gray("Branch: ") + chalk.white(app.git_branch || "N/A"),
67
+ );
68
+ console.log(
69
+ chalk.gray("Build Pack: ") + chalk.white(app.build_pack || "N/A"),
70
+ );
71
+ console.log(
72
+ chalk.gray("Ports: ") + chalk.white(app.ports_exposes || "N/A"),
73
+ );
74
+ console.log(chalk.gray("FQDN: ") + chalk.white(app.fqdn || "N/A"));
75
+ console.log(
76
+ chalk.gray("Dockerfile: ") + chalk.white(app.dockerfile_location || "N/A"),
77
+ );
78
+ console.log(
79
+ chalk.gray("Base Dir: ") + chalk.white(app.base_directory || "N/A"),
80
+ );
81
+ console.log("");
82
+ console.log(chalk.cyan("Destination:"));
60
83
  if (app.destination) {
61
- console.log(chalk.gray(' UUID: ') + chalk.white(app.destination.uuid))
62
- console.log(chalk.gray(' Name: ') + chalk.white(app.destination.name))
84
+ console.log(chalk.gray(" UUID: ") + chalk.white(app.destination.uuid));
85
+ console.log(chalk.gray(" Name: ") + chalk.white(app.destination.name));
63
86
  if (app.destination.server) {
64
- console.log(chalk.gray(' Server:') + chalk.white(` ${app.destination.server.name} (${app.destination.server.ip})`))
87
+ console.log(
88
+ chalk.gray(" Server:") +
89
+ chalk.white(
90
+ ` ${app.destination.server.name} (${app.destination.server.ip})`,
91
+ ),
92
+ );
65
93
  }
66
94
  } else {
67
- console.log(chalk.yellow(' No destination configured'))
95
+ console.log(chalk.yellow(" No destination configured"));
68
96
  }
69
- console.log('')
70
- console.log(chalk.cyan('Commands:'))
71
- if (app.install_command) console.log(chalk.gray(' Install: ') + chalk.white(app.install_command))
72
- if (app.build_command) console.log(chalk.gray(' Build: ') + chalk.white(app.build_command))
73
- if (app.start_command) console.log(chalk.gray(' Start: ') + chalk.white(app.start_command))
97
+ console.log("");
98
+ console.log(chalk.cyan("Commands:"));
99
+ if (app.install_command)
100
+ console.log(chalk.gray(" Install: ") + chalk.white(app.install_command));
101
+ if (app.build_command)
102
+ console.log(chalk.gray(" Build: ") + chalk.white(app.build_command));
103
+ if (app.start_command)
104
+ console.log(chalk.gray(" Start: ") + chalk.white(app.start_command));
74
105
  }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Start command for CLI.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { isErr } from "@mks2508/no-throw";
8
+ import ora from "ora";
9
+ import chalk from "chalk";
10
+ import { getCoolifyService } from "../../coolify/index.js";
11
+ import { resolveUuid } from "../coolify-state.js";
12
+
13
+ /**
14
+ * Start command handler.
15
+ * If no UUID is provided, reads from .coolify.json in the current directory.
16
+ *
17
+ * @param uuid - Application UUID (optional if .coolify.json exists)
18
+ */
19
+ export async function startCommand(uuid?: string) {
20
+ const resolvedUuid = resolveUuid(uuid);
21
+ if (!resolvedUuid) {
22
+ console.error(
23
+ chalk.red("Error: No UUID provided and no .coolify.json found"),
24
+ );
25
+ return;
26
+ }
27
+ uuid = resolvedUuid;
28
+ const spinner = ora("Initializing Coolify connection...").start();
29
+
30
+ try {
31
+ const coolify = getCoolifyService();
32
+ const initResult = await coolify.init();
33
+
34
+ if (isErr(initResult)) {
35
+ spinner.fail(
36
+ chalk.red(`Failed to initialize: ${initResult.error.message}`),
37
+ );
38
+ return;
39
+ }
40
+
41
+ spinner.text = "Starting application...";
42
+
43
+ const result = await coolify.startApplication(uuid);
44
+
45
+ if (isErr(result)) {
46
+ spinner.fail(
47
+ chalk.red(`Failed to start application: ${result.error.message}`),
48
+ );
49
+ return;
50
+ }
51
+
52
+ spinner.succeed(chalk.green(`Application started: ${chalk.cyan(uuid)}`));
53
+ } catch (error) {
54
+ spinner.fail(
55
+ chalk.red(
56
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
57
+ ),
58
+ );
59
+ }
60
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Stop command for CLI.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { isErr } from "@mks2508/no-throw";
8
+ import ora from "ora";
9
+ import chalk from "chalk";
10
+ import { getCoolifyService } from "../../coolify/index.js";
11
+ import { resolveUuid } from "../coolify-state.js";
12
+
13
+ /**
14
+ * Stop command handler.
15
+ * If no UUID is provided, reads from .coolify.json in the current directory.
16
+ *
17
+ * @param uuid - Application UUID (optional if .coolify.json exists)
18
+ */
19
+ export async function stopCommand(uuid?: string) {
20
+ const resolvedUuid = resolveUuid(uuid);
21
+ if (!resolvedUuid) {
22
+ console.error(
23
+ chalk.red("Error: No UUID provided and no .coolify.json found"),
24
+ );
25
+ return;
26
+ }
27
+ uuid = resolvedUuid;
28
+ const spinner = ora("Initializing Coolify connection...").start();
29
+
30
+ try {
31
+ const coolify = getCoolifyService();
32
+ const initResult = await coolify.init();
33
+
34
+ if (isErr(initResult)) {
35
+ spinner.fail(
36
+ chalk.red(`Failed to initialize: ${initResult.error.message}`),
37
+ );
38
+ return;
39
+ }
40
+
41
+ spinner.text = "Stopping application...";
42
+
43
+ const result = await coolify.stopApplication(uuid);
44
+
45
+ if (isErr(result)) {
46
+ spinner.fail(
47
+ chalk.red(`Failed to stop application: ${result.error.message}`),
48
+ );
49
+ return;
50
+ }
51
+
52
+ spinner.succeed(chalk.green(`Application stopped: ${chalk.cyan(uuid)}`));
53
+ } catch (error) {
54
+ spinner.fail(
55
+ chalk.red(
56
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
57
+ ),
58
+ );
59
+ }
60
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Service subcommands for CLI — all go through SDK.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { runAction, runList, runGet, chalk, formatStatus } from "../actions.js";
8
+ import type { ICoolifyService } from "../../coolify/types.js";
9
+
10
+ /** List all services. */
11
+ export const svcListCommand = () =>
12
+ runList<ICoolifyService>("service(s)", (s) => s.services.list(), [
13
+ { header: "UUID", value: (s) => s.uuid },
14
+ { header: "Name", value: (s) => s.name || "-" },
15
+ { header: "Type", value: (s) => s.type || "-" },
16
+ { header: "Status", value: (s) => formatStatus(s.status) },
17
+ ]);
18
+
19
+ /** Get service details. */
20
+ export const svcGetCommand = (uuid: string) =>
21
+ runGet<ICoolifyService>(
22
+ uuid,
23
+ "service",
24
+ (s, u) => s.services.get(u),
25
+ (svc) => {
26
+ console.log(chalk.cyan("Service Details:"));
27
+ console.log(chalk.gray("UUID: ") + svc.uuid);
28
+ console.log(chalk.gray("Name: ") + svc.name);
29
+ console.log(chalk.gray("Type: ") + (svc.type || "-"));
30
+ console.log(chalk.gray("Status: ") + formatStatus(svc.status));
31
+ },
32
+ );
33
+
34
+ /** Start a service. */
35
+ export const svcStartCommand = (uuid: string) =>
36
+ runAction(
37
+ uuid,
38
+ "Starting service",
39
+ (s, u) => s.services.start(u),
40
+ (u) => `Service started: ${u}`,
41
+ );
42
+
43
+ /** Stop a service. */
44
+ export const svcStopCommand = (uuid: string) =>
45
+ runAction(
46
+ uuid,
47
+ "Stopping service",
48
+ (s, u) => s.services.stop(u),
49
+ (u) => `Service stopped: ${u}`,
50
+ );
51
+
52
+ /** Restart a service. */
53
+ export const svcRestartCommand = (uuid: string) =>
54
+ runAction(
55
+ uuid,
56
+ "Restarting service",
57
+ (s, u) => s.services.restart(u),
58
+ (u) => `Service restarted: ${u}`,
59
+ );
60
+
61
+ /** Delete a service. */
62
+ export const svcDeleteCommand = (uuid: string) =>
63
+ runAction(
64
+ uuid,
65
+ "Deleting service",
66
+ (s, u) => s.services.delete(u),
67
+ (u) => `Service deleted: ${u}`,
68
+ );
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Teams subcommands for CLI — all go through SDK.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { runList, chalk, getCliSdk } from "../actions.js";
8
+ import type { ICoolifyTeam } from "../../coolify/types.js";
9
+
10
+ /** List all teams. */
11
+ export const teamsListCommand = () =>
12
+ runList<ICoolifyTeam>("team(s)", (s) => s.teams.list(), [
13
+ { header: "ID", value: (t) => String(t.id) },
14
+ { header: "Name", value: (t) => t.name },
15
+ { header: "Personal", value: (t) => (t.personal_team ? "Yes" : "No") },
16
+ ]);
17
+
18
+ /** Get current team. */
19
+ export async function teamsCurrentCommand(): Promise<void> {
20
+ try {
21
+ const team = await getCliSdk().teams.current();
22
+ console.log(chalk.cyan("Current Team:"));
23
+ console.log(chalk.gray("ID: ") + team.id);
24
+ console.log(chalk.gray("Name: ") + team.name);
25
+ console.log(chalk.gray("Personal: ") + (team.personal_team ? "Yes" : "No"));
26
+ } catch (error) {
27
+ console.error(
28
+ chalk.red(
29
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
30
+ ),
31
+ );
32
+ }
33
+ }
34
+
35
+ /** Get team members. */
36
+ export async function teamsMembersCommand(teamId: string): Promise<void> {
37
+ const id = parseInt(teamId, 10);
38
+ if (isNaN(id)) {
39
+ console.error(chalk.red("Error: Team ID must be a number"));
40
+ return;
41
+ }
42
+
43
+ try {
44
+ const members = await getCliSdk().teams.members(id);
45
+ if (members.length === 0) {
46
+ console.log(chalk.yellow("No members found"));
47
+ return;
48
+ }
49
+ console.log(chalk.cyan(`Team ${teamId} Members:`));
50
+ for (const m of members) {
51
+ console.log(` ${chalk.bold(m.name)} (${chalk.gray(m.email)})`);
52
+ }
53
+ } catch (error) {
54
+ console.error(
55
+ chalk.red(
56
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
57
+ ),
58
+ );
59
+ }
60
+ }
@@ -6,29 +6,30 @@
6
6
  * @module
7
7
  */
8
8
 
9
- import { isErr } from '@mks2508/no-throw'
10
- import chalk from 'chalk'
11
- import { getCoolifyService } from '../../coolify/index.js'
12
- import type { ICoolifyUpdateOptions } from '../../coolify/types.js'
9
+ import { isErr } from "@mks2508/no-throw";
10
+ import chalk from "chalk";
11
+ import { getCoolifyService } from "../../coolify/index.js";
12
+ import type { ICoolifyUpdateOptions } from "../../coolify/types.js";
13
+ import { resolveUuid } from "../coolify-state.js";
13
14
 
14
15
  /**
15
16
  * Options for the update command.
16
17
  */
17
18
  interface IUpdateCommandOptions {
18
- uuid: string
19
- name?: string
20
- description?: string
21
- buildPack?: string
22
- gitBranch?: string
23
- ports?: string
24
- installCommand?: string
25
- buildCommand?: string
26
- startCommand?: string
27
- dockerfileLocation?: string
28
- baseDirectory?: string
29
- domains?: string
30
- autoDeploy?: boolean
31
- forceHttps?: boolean
19
+ uuid?: string;
20
+ name?: string;
21
+ description?: string;
22
+ buildPack?: string;
23
+ gitBranch?: string;
24
+ ports?: string;
25
+ installCommand?: string;
26
+ buildCommand?: string;
27
+ startCommand?: string;
28
+ dockerfileLocation?: string;
29
+ baseDirectory?: string;
30
+ domains?: string;
31
+ autoDeploy?: boolean;
32
+ forceHttps?: boolean;
32
33
  }
33
34
 
34
35
  /**
@@ -36,52 +37,75 @@ interface IUpdateCommandOptions {
36
37
  *
37
38
  * @param options - Command options
38
39
  */
39
- export async function updateCommand(options: IUpdateCommandOptions): Promise<void> {
40
- console.log(chalk.cyan(`Updating application ${chalk.bold(options.uuid)}...`))
40
+ export async function updateCommand(
41
+ options: IUpdateCommandOptions,
42
+ ): Promise<void> {
43
+ const uuid = resolveUuid(options.uuid);
44
+ if (!uuid) {
45
+ console.error(
46
+ chalk.red("Error: No UUID provided and no .coolify.json found"),
47
+ );
48
+ return;
49
+ }
50
+ options.uuid = uuid;
51
+ console.log(chalk.cyan(`Updating application ${chalk.bold(uuid)}...`));
41
52
 
42
- const service = getCoolifyService()
43
- const initResult = await service.init()
53
+ const service = getCoolifyService();
54
+ const initResult = await service.init();
44
55
 
45
56
  if (isErr(initResult)) {
46
- console.error(chalk.red('Failed to initialize Coolify service'))
47
- console.error(chalk.gray(initResult.error.message))
48
- process.exit(1)
57
+ console.error(chalk.red("Failed to initialize Coolify service"));
58
+ console.error(chalk.gray(initResult.error.message));
59
+ process.exit(1);
49
60
  }
50
61
 
51
- const updateOptions: ICoolifyUpdateOptions = {}
62
+ const updateOptions: ICoolifyUpdateOptions = {};
52
63
 
53
- if (options.name) updateOptions.name = options.name
54
- if (options.description) updateOptions.description = options.description
55
- if (options.buildPack) updateOptions.buildPack = options.buildPack as 'dockerfile' | 'nixpacks' | 'static' | 'dockercompose'
56
- if (options.gitBranch) updateOptions.gitBranch = options.gitBranch
57
- if (options.ports) updateOptions.portsExposes = options.ports
58
- if (options.installCommand) updateOptions.installCommand = options.installCommand
59
- if (options.buildCommand) updateOptions.buildCommand = options.buildCommand
60
- if (options.startCommand) updateOptions.startCommand = options.startCommand
61
- if (options.dockerfileLocation) updateOptions.dockerfileLocation = options.dockerfileLocation
62
- if (options.baseDirectory) updateOptions.baseDirectory = options.baseDirectory
63
- if (options.domains) updateOptions.domains = options.domains
64
- if (options.autoDeploy !== undefined) updateOptions.isAutoDeployEnabled = options.autoDeploy
65
- if (options.forceHttps) updateOptions.isForceHttpsEnabled = true
64
+ if (options.name) updateOptions.name = options.name;
65
+ if (options.description) updateOptions.description = options.description;
66
+ if (options.buildPack)
67
+ updateOptions.buildPack = options.buildPack as
68
+ | "dockerfile"
69
+ | "nixpacks"
70
+ | "static"
71
+ | "dockercompose";
72
+ if (options.gitBranch) updateOptions.gitBranch = options.gitBranch;
73
+ if (options.ports) updateOptions.portsExposes = options.ports;
74
+ if (options.installCommand)
75
+ updateOptions.installCommand = options.installCommand;
76
+ if (options.buildCommand) updateOptions.buildCommand = options.buildCommand;
77
+ if (options.startCommand) updateOptions.startCommand = options.startCommand;
78
+ if (options.dockerfileLocation)
79
+ updateOptions.dockerfileLocation = options.dockerfileLocation;
80
+ if (options.baseDirectory)
81
+ updateOptions.baseDirectory = options.baseDirectory;
82
+ if (options.domains) updateOptions.domains = options.domains;
83
+ if (options.autoDeploy !== undefined)
84
+ updateOptions.isAutoDeployEnabled = options.autoDeploy;
85
+ if (options.forceHttps) updateOptions.isForceHttpsEnabled = true;
66
86
 
67
87
  if (Object.keys(updateOptions).length === 0) {
68
- console.warn(chalk.yellow('No update options provided. Use --help to see available options.'))
69
- process.exit(0)
88
+ console.warn(
89
+ chalk.yellow(
90
+ "No update options provided. Use --help to see available options.",
91
+ ),
92
+ );
93
+ process.exit(0);
70
94
  }
71
95
 
72
- const result = await service.updateApplication(options.uuid, updateOptions)
96
+ const result = await service.updateApplication(options.uuid, updateOptions);
73
97
 
74
98
  if (isErr(result)) {
75
- console.error(chalk.red('Failed to update application'))
76
- console.error(chalk.gray(result.error.message))
77
- process.exit(1)
99
+ console.error(chalk.red("Failed to update application"));
100
+ console.error(chalk.gray(result.error.message));
101
+ process.exit(1);
78
102
  }
79
103
 
80
- console.log(chalk.green('Application updated successfully'))
81
- console.log(chalk.gray(`UUID: ${result.value.uuid}`))
82
- console.log(chalk.gray(`Name: ${result.value.name}`))
104
+ console.log(chalk.green("Application updated successfully"));
105
+ console.log(chalk.gray(`UUID: ${result.value.uuid}`));
106
+ console.log(chalk.gray(`Name: ${result.value.name}`));
83
107
 
84
108
  if (result.value.description) {
85
- console.log(chalk.gray(`Description: ${result.value.description}`))
109
+ console.log(chalk.gray(`Description: ${result.value.description}`));
86
110
  }
87
111
  }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Version command for CLI.
3
+ *
4
+ * Shows the Coolify server version.
5
+ *
6
+ * @module
7
+ */
8
+
9
+ import { isErr } from "@mks2508/no-throw";
10
+ import chalk from "chalk";
11
+ import { getCoolifyService } from "../../coolify/index.js";
12
+
13
+ /**
14
+ * Version command handler.
15
+ * Displays the Coolify server version.
16
+ */
17
+ export async function versionCommand() {
18
+ const coolify = getCoolifyService();
19
+ const initResult = await coolify.init();
20
+
21
+ if (isErr(initResult)) {
22
+ console.error(chalk.red(`Error: ${initResult.error.message}`));
23
+ return;
24
+ }
25
+
26
+ const result = await coolify.getVersion();
27
+
28
+ if (isErr(result)) {
29
+ console.error(chalk.red(`Error: ${result.error.message}`));
30
+ return;
31
+ }
32
+
33
+ console.log(
34
+ chalk.cyan("Coolify Server Version:"),
35
+ chalk.bold(result.value.version),
36
+ );
37
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * .coolify.json state loader for CLI.
3
+ *
4
+ * When running CLI commands from a project directory that has a .coolify.json
5
+ * (generated by create-bunspace or first deploy), reads the state to auto-fill
6
+ * UUIDs so users don't need to copy-paste them.
7
+ *
8
+ * @module
9
+ */
10
+
11
+ import { existsSync, readFileSync } from "node:fs";
12
+ import { join } from "node:path";
13
+
14
+ /**
15
+ * State stored in .coolify.json (generated by create-bunspace deployer).
16
+ */
17
+ export interface ICoolifyDeployState {
18
+ /** Application UUID in Coolify */
19
+ appUuid: string;
20
+ /** Server UUID */
21
+ serverUuid: string;
22
+ /** Project UUID */
23
+ projectUuid: string;
24
+ /** Environment UUID */
25
+ environmentUuid: string;
26
+ /** Domain if configured */
27
+ domain?: string;
28
+ /** Docker compose or Dockerfile path */
29
+ dockerComposePath?: string;
30
+ /** Base directory for build context */
31
+ baseDirectory?: string;
32
+ /** Git branch */
33
+ branch?: string;
34
+ /** Application type */
35
+ type?: string;
36
+ /** Build pack */
37
+ buildPack?: string;
38
+ /** Auto-deploy enabled */
39
+ autoDeployEnabled?: boolean;
40
+ }
41
+
42
+ const STATE_FILE = ".coolify.json";
43
+
44
+ /**
45
+ * Loads .coolify.json from the current working directory.
46
+ *
47
+ * @returns The deploy state if found, null otherwise
48
+ */
49
+ export function loadCoolifyState(): ICoolifyDeployState | null {
50
+ const statePath = join(process.cwd(), STATE_FILE);
51
+
52
+ if (!existsSync(statePath)) {
53
+ return null;
54
+ }
55
+
56
+ try {
57
+ const content = readFileSync(statePath, "utf-8");
58
+ const state = JSON.parse(content) as ICoolifyDeployState;
59
+
60
+ if (!state.appUuid) {
61
+ return null;
62
+ }
63
+
64
+ return state;
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Resolves a UUID argument — if not provided, tries to read from .coolify.json.
72
+ *
73
+ * @param uuid - UUID from CLI argument (may be undefined)
74
+ * @param field - Which field to read from .coolify.json (default: appUuid)
75
+ * @returns The resolved UUID or null if not found
76
+ */
77
+ export function resolveUuid(
78
+ uuid: string | undefined,
79
+ field: keyof ICoolifyDeployState = "appUuid",
80
+ ): string | null {
81
+ if (uuid) return uuid;
82
+
83
+ const state = loadCoolifyState();
84
+ if (!state) return null;
85
+
86
+ const value = state[field];
87
+ return typeof value === "string" ? value : null;
88
+ }