@mks2508/coolify-mks-cli-mcp 0.5.0 → 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 +25 -22
  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 +34 -18
  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 +24 -16
  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 +34 -18
  68. package/src/cli/commands/stop.ts +34 -18
  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 +383 -151
  75. package/src/coolify/config.ts +29 -27
  76. package/src/coolify/index.ts +1829 -123
  77. package/src/coolify/types.ts +217 -124
  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
@@ -4,30 +4,36 @@
4
4
  * @module
5
5
  */
6
6
 
7
- import { isOk, isErr } from '@mks2508/no-throw'
8
- import ora from 'ora'
9
- import chalk from 'chalk'
10
- import { getCoolifyService } from '../../coolify/index.js'
7
+ import { isOk, isErr } from "@mks2508/no-throw";
8
+ import ora from "ora";
9
+ import chalk from "chalk";
10
+ import { getCoolifyService } from "../../coolify/index.js";
11
11
 
12
12
  /**
13
13
  * Create command options.
14
14
  */
15
15
  interface ICreateOptions {
16
- name: string
17
- description?: string
18
- server: string
19
- project: string
20
- environment?: string
21
- repo?: string
22
- branch?: string
23
- type?: 'public' | 'private-github-app' | 'private-deploy-key' | 'dockerfile' | 'docker-image' | 'docker-compose'
24
- buildPack?: 'dockerfile' | 'nixpacks' | 'static' | 'dockercompose'
25
- ports?: string
26
- dockerImage?: string
27
- dockerCompose?: string
28
- dockerComposeLocation?: string
29
- dockerfileLocation?: string
30
- baseDirectory?: string
16
+ name: string;
17
+ description?: string;
18
+ server: string;
19
+ project: string;
20
+ environment?: string;
21
+ repo?: string;
22
+ branch?: string;
23
+ type?:
24
+ | "public"
25
+ | "private-github-app"
26
+ | "private-deploy-key"
27
+ | "dockerfile"
28
+ | "docker-image"
29
+ | "docker-compose";
30
+ buildPack?: "dockerfile" | "nixpacks" | "static" | "dockercompose";
31
+ ports?: string;
32
+ dockerImage?: string;
33
+ dockerCompose?: string;
34
+ dockerComposeLocation?: string;
35
+ dockerfileLocation?: string;
36
+ baseDirectory?: string;
31
37
  }
32
38
 
33
39
  /**
@@ -36,43 +42,51 @@ interface ICreateOptions {
36
42
  * @param options - Create options
37
43
  */
38
44
  export async function createCommand(options: ICreateOptions) {
39
- const spinner = ora('Initializing Coolify connection...').start()
45
+ const spinner = ora("Initializing Coolify connection...").start();
40
46
 
41
47
  try {
42
- const coolify = getCoolifyService()
43
- const initResult = await coolify.init()
48
+ const coolify = getCoolifyService();
49
+ const initResult = await coolify.init();
44
50
 
45
51
  if (isErr(initResult)) {
46
- spinner.fail(chalk.red(`Failed to initialize: ${initResult.error.message}`))
47
- return
52
+ spinner.fail(
53
+ chalk.red(`Failed to initialize: ${initResult.error.message}`),
54
+ );
55
+ return;
48
56
  }
49
57
 
50
58
  // Auto-fetch environment UUID if not provided
51
- let environmentUuid: string | undefined = options.environment
59
+ let environmentUuid: string | undefined = options.environment;
52
60
 
53
61
  if (!environmentUuid) {
54
- spinner.text = 'Fetching project environments...'
62
+ spinner.text = "Fetching project environments...";
55
63
 
56
- const envResult = await coolify.getProjectEnvironments(options.project)
64
+ const envResult = await coolify.getProjectEnvironments(options.project);
57
65
 
58
66
  if (isOk(envResult) && envResult.value.length > 0) {
59
67
  // Use the first environment (usually "production")
60
- environmentUuid = envResult.value[0].uuid
61
- const envName = envResult.value[0].name
62
- spinner.info(chalk.cyan(`Using environment: ${envName} (${environmentUuid.slice(0, 8)}...)`))
68
+ environmentUuid = envResult.value[0].uuid;
69
+ const envName = envResult.value[0].name;
70
+ spinner.info(
71
+ chalk.cyan(`Using environment: ${envName} (${environmentUuid})`),
72
+ );
63
73
  } else {
64
- spinner.fail(chalk.red('No environments found for project. Please specify --environment <uuid>'))
65
- return
74
+ spinner.fail(
75
+ chalk.red(
76
+ "No environments found for project. Please specify --environment <uuid>",
77
+ ),
78
+ );
79
+ return;
66
80
  }
67
81
  }
68
82
 
69
83
  // Ensure environmentUuid is defined before creating application
70
84
  if (!environmentUuid) {
71
- spinner.fail(chalk.red('Environment UUID is required'))
72
- return
85
+ spinner.fail(chalk.red("Environment UUID is required"));
86
+ return;
73
87
  }
74
88
 
75
- spinner.text = 'Creating application...'
89
+ spinner.text = "Creating application...";
76
90
 
77
91
  const result = await coolify.createApplication(
78
92
  {
@@ -81,11 +95,11 @@ export async function createCommand(options: ICreateOptions) {
81
95
  projectUuid: options.project,
82
96
  environmentUuid,
83
97
  serverUuid: options.server,
84
- type: options.type || 'public',
98
+ type: options.type || "public",
85
99
  githubRepoUrl: options.repo,
86
- branch: options.branch || 'main',
87
- buildPack: options.buildPack || 'dockerfile',
88
- portsExposes: options.ports || '3000',
100
+ branch: options.branch || "main",
101
+ buildPack: options.buildPack || "dockerfile",
102
+ portsExposes: options.ports || "3000",
89
103
  dockerImage: options.dockerImage,
90
104
  dockerCompose: options.dockerCompose,
91
105
  dockerComposeLocation: options.dockerComposeLocation,
@@ -93,26 +107,33 @@ export async function createCommand(options: ICreateOptions) {
93
107
  baseDirectory: options.baseDirectory,
94
108
  },
95
109
  (percent, message) => {
96
- spinner.text = `${chalk.bold(`[${percent}%]`)} ${message}`
97
- }
98
- )
110
+ spinner.text = `${chalk.bold(`[${percent}%]`)} ${message}`;
111
+ },
112
+ );
99
113
 
100
114
  if (isOk(result)) {
101
115
  spinner.succeed(
102
- chalk.green(`Application created! UUID: ${chalk.cyan(result.value.uuid?.slice(0, 8))}`)
103
- )
104
- console.log(` Full UUID: ${chalk.cyan(result.value.uuid)}`)
105
- console.log(` Name: ${chalk.cyan(options.name)}`)
106
- console.log(` Type: ${chalk.cyan(options.type || 'public')}`)
107
- console.log(` Next steps:`)
108
- console.log(` 1. Set environment variables: ${chalk.yellow('coolify-mcp env ' + result.value.uuid?.slice(0, 8))}`)
109
- console.log(` 2. Deploy application: ${chalk.yellow('coolify-mcp deploy ' + result.value.uuid?.slice(0, 8))}`)
116
+ chalk.green(
117
+ `Application created! UUID: ${chalk.cyan(result.value.uuid)}`,
118
+ ),
119
+ );
120
+ console.log(` Name: ${chalk.cyan(options.name)}`);
121
+ console.log(` Type: ${chalk.cyan(options.type || "public")}`);
122
+ console.log(` Next steps:`);
123
+ console.log(
124
+ ` 1. Set environment variables: ${chalk.yellow("coolify-mcp env " + result.value.uuid)}`,
125
+ );
126
+ console.log(
127
+ ` 2. Deploy application: ${chalk.yellow("coolify-mcp deploy " + result.value.uuid)}`,
128
+ );
110
129
  } else {
111
- spinner.fail(chalk.red(`Creation failed: ${result.error.message}`))
130
+ spinner.fail(chalk.red(`Creation failed: ${result.error.message}`));
112
131
  }
113
132
  } catch (error) {
114
133
  spinner.fail(
115
- chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`)
116
- )
134
+ chalk.red(
135
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
136
+ ),
137
+ );
117
138
  }
118
139
  }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Databases command for CLI.
3
+ *
4
+ * Lists all databases in Coolify.
5
+ *
6
+ * @module
7
+ */
8
+
9
+ import { isErr } from "@mks2508/no-throw";
10
+ import chalk from "chalk";
11
+ import Table from "cli-table3";
12
+ import { getCoolifyService } from "../../coolify/index.js";
13
+ import { formatStatus } from "../../utils/format.js";
14
+
15
+ /**
16
+ * Databases command handler.
17
+ *
18
+ * @param options - Command options
19
+ */
20
+ export async function databasesCommand(_options: { full?: boolean } = {}) {
21
+ const coolify = getCoolifyService();
22
+ const initResult = await coolify.init();
23
+
24
+ if (isErr(initResult)) {
25
+ console.error(chalk.red(`Error: ${initResult.error.message}`));
26
+ return;
27
+ }
28
+
29
+ const result = await coolify.listDatabases();
30
+
31
+ if (isErr(result)) {
32
+ console.error(chalk.red(`Error: ${result.error.message}`));
33
+ return;
34
+ }
35
+
36
+ const databases = result.value;
37
+
38
+ if (databases.length === 0) {
39
+ console.log(chalk.yellow("No databases found"));
40
+ return;
41
+ }
42
+
43
+ const table = new Table({
44
+ head: [
45
+ chalk.cyan("UUID"),
46
+ chalk.cyan("Name"),
47
+ chalk.cyan("Type"),
48
+ chalk.cyan("Status"),
49
+ ],
50
+ });
51
+
52
+ for (const db of databases) {
53
+ table.push([
54
+ db.uuid,
55
+ db.name || "-",
56
+ db.type || "-",
57
+ formatStatus(db.status),
58
+ ]);
59
+ }
60
+
61
+ console.log(table.toString());
62
+ console.log(chalk.gray(`Total: ${databases.length} database(s)`));
63
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Database 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 { ICoolifyDatabase } from "../../coolify/types.js";
9
+
10
+ /** List all databases. */
11
+ export const dbListCommand = () =>
12
+ runList<ICoolifyDatabase>("database(s)", (s) => s.databases.list(), [
13
+ { header: "UUID", value: (d) => d.uuid },
14
+ { header: "Name", value: (d) => d.name || "-" },
15
+ { header: "Type", value: (d) => d.type || "-" },
16
+ { header: "Status", value: (d) => formatStatus(d.status) },
17
+ ]);
18
+
19
+ /** Get database details. */
20
+ export const dbGetCommand = (uuid: string) =>
21
+ runGet<ICoolifyDatabase>(
22
+ uuid,
23
+ "database",
24
+ (s, u) => s.databases.get(u),
25
+ (db) => {
26
+ console.log(chalk.cyan("Database Details:"));
27
+ console.log(chalk.gray("UUID: ") + db.uuid);
28
+ console.log(chalk.gray("Name: ") + db.name);
29
+ console.log(chalk.gray("Type: ") + (db.type || "-"));
30
+ console.log(chalk.gray("Status: ") + formatStatus(db.status));
31
+ },
32
+ );
33
+
34
+ /** Start a database. */
35
+ export const dbStartCommand = (uuid: string) =>
36
+ runAction(
37
+ uuid,
38
+ "Starting database",
39
+ (s, u) => s.databases.start(u),
40
+ (u) => `Database started: ${u}`,
41
+ );
42
+
43
+ /** Stop a database. */
44
+ export const dbStopCommand = (uuid: string) =>
45
+ runAction(
46
+ uuid,
47
+ "Stopping database",
48
+ (s, u) => s.databases.stop(u),
49
+ (u) => `Database stopped: ${u}`,
50
+ );
51
+
52
+ /** Restart a database. */
53
+ export const dbRestartCommand = (uuid: string) =>
54
+ runAction(
55
+ uuid,
56
+ "Restarting database",
57
+ (s, u) => s.databases.restart(u),
58
+ (u) => `Database restarted: ${u}`,
59
+ );
60
+
61
+ /** Delete a database. */
62
+ export const dbDeleteCommand = (uuid: string) =>
63
+ runAction(
64
+ uuid,
65
+ "Deleting database",
66
+ (s, u) => s.databases.delete(u),
67
+ (u) => `Database deleted: ${u}`,
68
+ );
@@ -6,64 +6,76 @@
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'
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";
12
13
 
13
14
  /**
14
15
  * Executes the delete command.
16
+ * If no UUID is provided, reads from .coolify.json in the current directory.
15
17
  *
16
- * @param uuid - Application UUID
18
+ * @param uuid - Application UUID (optional if .coolify.json exists)
17
19
  * @param options - Command options
18
20
  */
19
21
  export async function deleteCommand(
20
- uuid: string,
21
- options: { force?: boolean; yes?: boolean } = {}
22
+ uuid: string | undefined,
23
+ options: { force?: boolean; yes?: boolean } = {},
22
24
  ): Promise<void> {
23
- const service = getCoolifyService()
24
- const initResult = await service.init()
25
+ const resolvedUuid = resolveUuid(uuid);
26
+ if (!resolvedUuid) {
27
+ console.error(
28
+ chalk.red("Error: No UUID provided and no .coolify.json found"),
29
+ );
30
+ return;
31
+ }
32
+ uuid = resolvedUuid;
33
+ const service = getCoolifyService();
34
+ const initResult = await service.init();
25
35
 
26
36
  if (isErr(initResult)) {
27
- console.error(chalk.red('Failed to initialize Coolify service'))
28
- console.error(chalk.gray(initResult.error.message))
29
- process.exit(1)
37
+ console.error(chalk.red("Failed to initialize Coolify service"));
38
+ console.error(chalk.gray(initResult.error.message));
39
+ process.exit(1);
30
40
  }
31
41
 
32
42
  if (!options.force && !options.yes) {
33
- const readline = await import('readline')
43
+ const readline = await import("readline");
34
44
  const rl = readline.createInterface({
35
45
  input: process.stdin,
36
46
  output: process.stdout,
37
- })
47
+ });
38
48
 
39
49
  const answer = await new Promise<string>((resolve) => {
40
50
  rl.question(
41
- chalk.yellow(`Are you sure you want to delete application ${chalk.bold(uuid)}? (yes/no): `),
51
+ chalk.yellow(
52
+ `Are you sure you want to delete application ${chalk.bold(uuid)}? (yes/no): `,
53
+ ),
42
54
  (ans) => {
43
- rl.close()
44
- resolve(ans.toLowerCase())
45
- }
46
- )
47
- })
55
+ rl.close();
56
+ resolve(ans.toLowerCase());
57
+ },
58
+ );
59
+ });
48
60
 
49
- if (answer !== 'yes' && answer !== 'y') {
50
- console.log(chalk.gray('Operation cancelled'))
51
- process.exit(0)
61
+ if (answer !== "yes" && answer !== "y") {
62
+ console.log(chalk.gray("Operation cancelled"));
63
+ process.exit(0);
52
64
  }
53
65
  }
54
66
 
55
- console.log(chalk.cyan(`Deleting application ${chalk.bold(uuid)}...`))
67
+ console.log(chalk.cyan(`Deleting application ${chalk.bold(uuid)}...`));
56
68
 
57
- const result = await service.deleteApplication(uuid)
69
+ const result = await service.deleteApplication(uuid);
58
70
 
59
71
  if (isErr(result)) {
60
- console.error(chalk.red('Failed to delete application'))
61
- console.error(chalk.gray(result.error.message))
62
- process.exit(1)
72
+ console.error(chalk.red("Failed to delete application"));
73
+ console.error(chalk.gray(result.error.message));
74
+ process.exit(1);
63
75
  }
64
76
 
65
- console.log(chalk.green('Application deleted successfully'))
77
+ console.log(chalk.green("Application deleted successfully"));
66
78
  if (result.value.message) {
67
- console.log(chalk.gray(result.value.message))
79
+ console.log(chalk.gray(result.value.message));
68
80
  }
69
81
  }
@@ -4,30 +4,47 @@
4
4
  * @module
5
5
  */
6
6
 
7
- import { isOk, isErr } from '@mks2508/no-throw'
8
- import ora from 'ora'
9
- import chalk from 'chalk'
10
- import { getCoolifyService } from '../../coolify/index.js'
7
+ import { isOk, 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";
11
12
 
12
13
  /**
13
14
  * Deploy command handler.
15
+ * If no UUID is provided, reads from .coolify.json in the current directory.
14
16
  *
15
- * @param uuid - Application UUID
17
+ * @param uuid - Application UUID (optional if .coolify.json exists)
16
18
  * @param options - Deploy options
17
19
  */
18
- export async function deployCommand(uuid: string, options: { force?: boolean; tag?: string }) {
19
- const spinner = ora('Initializing Coolify connection...').start()
20
+ export async function deployCommand(
21
+ uuid: string | undefined,
22
+ options: { force?: boolean; tag?: string },
23
+ ) {
24
+ const resolvedUuid = resolveUuid(uuid);
25
+ if (!resolvedUuid) {
26
+ console.error(
27
+ chalk.red(
28
+ "Error: No UUID provided and no .coolify.json found in current directory",
29
+ ),
30
+ );
31
+ return;
32
+ }
33
+ uuid = resolvedUuid;
34
+ const spinner = ora("Initializing Coolify connection...").start();
20
35
 
21
36
  try {
22
- const coolify = getCoolifyService()
23
- const initResult = await coolify.init()
37
+ const coolify = getCoolifyService();
38
+ const initResult = await coolify.init();
24
39
 
25
40
  if (isErr(initResult)) {
26
- spinner.fail(chalk.red(`Failed to initialize: ${initResult.error.message}`))
27
- return
41
+ spinner.fail(
42
+ chalk.red(`Failed to initialize: ${initResult.error.message}`),
43
+ );
44
+ return;
28
45
  }
29
46
 
30
- spinner.text = 'Triggering deployment...'
47
+ spinner.text = "Triggering deployment...";
31
48
 
32
49
  const result = await coolify.deploy(
33
50
  {
@@ -36,21 +53,25 @@ export async function deployCommand(uuid: string, options: { force?: boolean; ta
36
53
  tag: options.tag,
37
54
  },
38
55
  (percent, message) => {
39
- spinner.text = `${chalk.bold(`[${percent}%]`)} ${message}`
40
- }
41
- )
56
+ spinner.text = `${chalk.bold(`[${percent}%]`)} ${message}`;
57
+ },
58
+ );
42
59
 
43
60
  if (isOk(result)) {
44
61
  spinner.succeed(
45
- chalk.green(`Deployment triggered! UUID: ${chalk.cyan(result.value.deploymentUuid?.slice(0, 8))}`)
46
- )
47
- console.log(` Resource UUID: ${chalk.cyan(result.value.resourceUuid?.slice(0, 8))}`)
62
+ chalk.green(
63
+ `Deployment triggered! UUID: ${chalk.cyan(result.value.deploymentUuid)}`,
64
+ ),
65
+ );
66
+ console.log(` Resource UUID: ${chalk.cyan(result.value.resourceUuid)}`);
48
67
  } else {
49
- spinner.fail(chalk.red(`Deployment failed: ${result.error.message}`))
68
+ spinner.fail(chalk.red(`Deployment failed: ${result.error.message}`));
50
69
  }
51
70
  } catch (error) {
52
71
  spinner.fail(
53
- chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`)
54
- )
72
+ chalk.red(
73
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
74
+ ),
75
+ );
55
76
  }
56
77
  }
@@ -6,72 +6,82 @@
6
6
  * @module
7
7
  */
8
8
 
9
- import { isErr } from '@mks2508/no-throw'
10
- import chalk from 'chalk'
11
- import Table from 'cli-table3'
12
- import { getCoolifyService } from '../../coolify/index.js'
13
- import { formatStatus } from '../../utils/format.js'
9
+ import { isErr } from "@mks2508/no-throw";
10
+ import chalk from "chalk";
11
+ import Table from "cli-table3";
12
+ import { getCoolifyService } from "../../coolify/index.js";
13
+ import { formatStatus } from "../../utils/format.js";
14
+ import { resolveUuid } from "../coolify-state.js";
14
15
 
15
16
  /**
16
17
  * Deployments command handler.
18
+ * If no UUID is provided, reads from .coolify.json in the current directory.
17
19
  *
18
- * @param uuid - Application UUID
20
+ * @param uuid - Application UUID (optional if .coolify.json exists)
19
21
  * @param options - Command options
20
22
  */
21
23
  export async function deploymentsCommand(
22
- uuid: string,
23
- options: { full?: boolean; limit?: number } = {}
24
+ uuid: string | undefined,
25
+ options: { full?: boolean; limit?: number } = {},
24
26
  ) {
25
- const coolify = getCoolifyService()
26
- const initResult = await coolify.init()
27
+ const resolvedUuid = resolveUuid(uuid);
28
+ if (!resolvedUuid) {
29
+ console.error(
30
+ chalk.red("Error: No UUID provided and no .coolify.json found"),
31
+ );
32
+ return;
33
+ }
34
+ uuid = resolvedUuid;
35
+ const coolify = getCoolifyService();
36
+ const initResult = await coolify.init();
27
37
 
28
38
  if (isErr(initResult)) {
29
- console.error(chalk.red(`Error: ${initResult.error.message}`))
30
- return
39
+ console.error(chalk.red(`Error: ${initResult.error.message}`));
40
+ return;
31
41
  }
32
42
 
33
- const result = await coolify.getApplicationDeploymentHistory(uuid)
43
+ const result = await coolify.getApplicationDeploymentHistory(uuid);
34
44
 
35
45
  if (isErr(result)) {
36
- console.error(chalk.red(`Error: ${result.error.message}`))
37
- return
46
+ console.error(chalk.red(`Error: ${result.error.message}`));
47
+ return;
38
48
  }
39
49
 
40
- let deployments = result.value
50
+ let deployments = result.value;
41
51
 
42
52
  // Show most recent first
43
- deployments = deployments.reverse()
53
+ deployments = deployments.reverse();
44
54
 
45
55
  if (options.limit) {
46
- deployments = deployments.slice(0, options.limit)
56
+ deployments = deployments.slice(0, options.limit);
47
57
  }
48
58
 
49
59
  if (deployments.length === 0) {
50
- console.log(chalk.yellow('No deployments found'))
51
- return
60
+ console.log(chalk.yellow("No deployments found"));
61
+ return;
52
62
  }
53
63
 
54
64
  const table = new Table({
55
65
  head: [
56
- chalk.cyan('ID'),
57
- chalk.cyan('UUID'),
58
- chalk.cyan('Status'),
59
- chalk.cyan('Commit'),
60
- chalk.cyan('Created'),
66
+ chalk.cyan("ID"),
67
+ chalk.cyan("UUID"),
68
+ chalk.cyan("Status"),
69
+ chalk.cyan("Commit"),
70
+ chalk.cyan("Created"),
61
71
  ],
62
72
  ...(options.full ? { colWidths: [8, 36, 20, 10, 20] } : {}),
63
- })
73
+ });
64
74
 
65
75
  for (const dep of deployments) {
66
76
  table.push([
67
77
  String(dep.id),
68
- options.full ? dep.uuid : dep.uuid.slice(0, 8),
78
+ dep.uuid || "-",
69
79
  formatStatus(dep.status),
70
- dep.commit?.slice(0, 7) || '-',
80
+ dep.commit?.slice(0, 7) || "-",
71
81
  new Date(dep.created_at).toLocaleString(),
72
- ])
82
+ ]);
73
83
  }
74
84
 
75
- console.log(table.toString())
76
- console.log(chalk.gray(`Total: ${deployments.length} deployment(s)`))
85
+ console.log(table.toString());
86
+ console.log(chalk.gray(`Total: ${deployments.length} deployment(s)`));
77
87
  }