@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
@@ -6,10 +6,10 @@
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'
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
13
 
14
14
  /**
15
15
  * Destinations command handler.
@@ -17,44 +17,36 @@ import { getCoolifyService } from '../../coolify/index.js'
17
17
  * @param serverUuid - Server UUID
18
18
  */
19
19
  export async function destinationsCommand(serverUuid: string) {
20
- const coolify = getCoolifyService()
21
- const initResult = await coolify.init()
20
+ const coolify = getCoolifyService();
21
+ const initResult = await coolify.init();
22
22
 
23
23
  if (isErr(initResult)) {
24
- console.error(chalk.red(`Error: ${initResult.error.message}`))
25
- return
24
+ console.error(chalk.red(`Error: ${initResult.error.message}`));
25
+ return;
26
26
  }
27
27
 
28
- const result = await coolify.getServerDestinations(serverUuid)
28
+ const result = await coolify.getServerDestinations(serverUuid);
29
29
 
30
30
  if (isErr(result)) {
31
- console.error(chalk.red(`Error: ${result.error.message}`))
32
- return
31
+ console.error(chalk.red(`Error: ${result.error.message}`));
32
+ return;
33
33
  }
34
34
 
35
- const destinations = result.value
35
+ const destinations = result.value;
36
36
 
37
37
  if (destinations.length === 0) {
38
- console.log(chalk.yellow('No destinations found'))
39
- return
38
+ console.log(chalk.yellow("No destinations found"));
39
+ return;
40
40
  }
41
41
 
42
42
  const table = new Table({
43
- head: [
44
- chalk.cyan('UUID'),
45
- chalk.cyan('Name'),
46
- chalk.cyan('Network'),
47
- ],
48
- })
43
+ head: [chalk.cyan("UUID"), chalk.cyan("Name"), chalk.cyan("Network")],
44
+ });
49
45
 
50
46
  for (const dest of destinations) {
51
- table.push([
52
- dest.uuid,
53
- dest.name,
54
- dest.network || 'N/A',
55
- ])
47
+ table.push([dest.uuid, dest.name, dest.network || "N/A"]);
56
48
  }
57
49
 
58
- console.log(table.toString())
59
- console.log(chalk.gray(`Total: ${destinations.length} destination(s)`))
50
+ console.log(table.toString());
51
+ console.log(chalk.gray(`Total: ${destinations.length} destination(s)`));
60
52
  }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Diagnostic subcommands for CLI — all go through SDK.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { chalk, getCliSdk, formatStatus } from "../actions.js";
8
+ import { resolveUuid } from "../coolify-state.js";
9
+
10
+ /** Diagnose an application. */
11
+ export async function diagnoseAppCommand(query?: string): Promise<void> {
12
+ const resolved = query || resolveUuid(undefined);
13
+ if (!resolved) {
14
+ console.error(
15
+ chalk.red("Error: No app name/UUID provided and no .coolify.json found"),
16
+ );
17
+ return;
18
+ }
19
+
20
+ console.log(chalk.cyan(`Diagnosing application: ${resolved}...\n`));
21
+
22
+ try {
23
+ const { application, recentDeployments, envVarCount, recentLogs, issues } =
24
+ await getCliSdk().diagnose.app(resolved);
25
+
26
+ console.log(chalk.bold("Application:"));
27
+ console.log(` ${chalk.gray("Name:")} ${application.name}`);
28
+ console.log(` ${chalk.gray("UUID:")} ${application.uuid}`);
29
+ console.log(
30
+ ` ${chalk.gray("Status:")} ${formatStatus(application.status)}`,
31
+ );
32
+ console.log(` ${chalk.gray("FQDN:")} ${application.fqdn || "none"}`);
33
+ console.log(` ${chalk.gray("Env vars:")} ${envVarCount}`);
34
+
35
+ if (recentDeployments.length > 0) {
36
+ console.log(chalk.bold("\nRecent Deployments:"));
37
+ for (const d of recentDeployments) {
38
+ const status = d.status?.includes("failed")
39
+ ? chalk.red(d.status)
40
+ : chalk.green(d.status);
41
+ console.log(
42
+ ` ${chalk.gray(d.uuid.slice(0, 12))} ${status} ${chalk.gray(new Date(d.created_at).toLocaleString())}`,
43
+ );
44
+ }
45
+ }
46
+
47
+ if (recentLogs.length > 0) {
48
+ console.log(chalk.bold("\nRecent Logs (last 5):"));
49
+ for (const line of recentLogs.slice(-5)) {
50
+ console.log(` ${chalk.gray(line)}`);
51
+ }
52
+ }
53
+
54
+ if (issues.length > 0) {
55
+ console.log(chalk.bold.red(`\nIssues (${issues.length}):`));
56
+ for (const issue of issues) {
57
+ console.log(` ${chalk.red("!")} ${issue}`);
58
+ }
59
+ } else {
60
+ console.log(chalk.bold.green("\nNo issues detected"));
61
+ }
62
+ } catch (error) {
63
+ console.error(
64
+ chalk.red(
65
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
66
+ ),
67
+ );
68
+ }
69
+ }
70
+
71
+ /** Diagnose a server. */
72
+ export async function diagnoseServerCommand(query: string): Promise<void> {
73
+ console.log(chalk.cyan(`Diagnosing server: ${query}...\n`));
74
+
75
+ try {
76
+ const { server, resources, domains, issues } =
77
+ await getCliSdk().diagnose.server(query);
78
+
79
+ console.log(chalk.bold("Server:"));
80
+ console.log(` ${chalk.gray("Name:")} ${server.name}`);
81
+ console.log(` ${chalk.gray("UUID:")} ${server.uuid}`);
82
+ console.log(` ${chalk.gray("IP:")} ${server.ip || "-"}`);
83
+ console.log(
84
+ ` ${chalk.gray("Reachable:")} ${server.is_reachable ? chalk.green("Yes") : chalk.red("No")}`,
85
+ );
86
+ console.log(` ${chalk.gray("Resources:")} ${resources.length}`);
87
+ console.log(` ${chalk.gray("Domains:")} ${domains.length}`);
88
+
89
+ if (issues.length > 0) {
90
+ console.log(chalk.bold.red(`\nIssues (${issues.length}):`));
91
+ for (const issue of issues) {
92
+ console.log(` ${chalk.red("!")} ${issue}`);
93
+ }
94
+ } else {
95
+ console.log(chalk.bold.green("\nNo issues detected"));
96
+ }
97
+ } catch (error) {
98
+ console.error(
99
+ chalk.red(
100
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
101
+ ),
102
+ );
103
+ }
104
+ }
105
+
106
+ /** Scan all infrastructure for issues. */
107
+ export async function scanIssuesCommand(): Promise<void> {
108
+ console.log(chalk.cyan("Scanning infrastructure...\n"));
109
+
110
+ try {
111
+ const { totalServers, totalApps, totalDatabases, totalServices, issues } =
112
+ await getCliSdk().diagnose.infrastructure();
113
+
114
+ console.log(chalk.bold("Infrastructure Summary:"));
115
+ console.log(` ${chalk.gray("Servers:")} ${totalServers}`);
116
+ console.log(` ${chalk.gray("Apps:")} ${totalApps}`);
117
+ console.log(` ${chalk.gray("Databases:")} ${totalDatabases}`);
118
+ console.log(` ${chalk.gray("Services:")} ${totalServices}`);
119
+
120
+ if (issues.length > 0) {
121
+ console.log(chalk.bold.red(`\nIssues (${issues.length}):`));
122
+ for (const issue of issues) {
123
+ console.log(
124
+ ` ${chalk.red("!")} [${issue.type}] ${issue.resource} (${issue.uuid}): ${issue.message}`,
125
+ );
126
+ }
127
+ } else {
128
+ console.log(
129
+ chalk.bold.green("\nNo issues detected across all infrastructure"),
130
+ );
131
+ }
132
+ } catch (error) {
133
+ console.error(
134
+ chalk.red(
135
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
136
+ ),
137
+ );
138
+ }
139
+ }
@@ -4,99 +4,124 @@
4
4
  * @module
5
5
  */
6
6
 
7
- import { isErr } from '@mks2508/no-throw'
8
- import chalk from 'chalk'
9
- import { getCoolifyService } from '../../coolify/index.js'
7
+ import { isErr } from "@mks2508/no-throw";
8
+ import chalk from "chalk";
9
+ import { getCoolifyService } from "../../coolify/index.js";
10
+ import { resolveUuid } from "../coolify-state.js";
10
11
 
11
12
  interface IEnvCommandOptions {
12
- set?: string
13
- delete?: string
14
- buildtime?: boolean
13
+ set?: string;
14
+ delete?: string;
15
+ buildtime?: boolean;
15
16
  }
16
17
 
17
18
  /**
18
19
  * Env vars command handler.
20
+ * If no UUID is provided, reads from .coolify.json in the current directory.
19
21
  *
20
- * @param uuid - Application UUID
22
+ * @param uuid - Application UUID (optional if .coolify.json exists)
21
23
  * @param options - Command options
22
24
  */
23
- export async function envCommand(uuid: string, options: IEnvCommandOptions = {}) {
24
- const coolify = getCoolifyService()
25
- const initResult = await coolify.init()
25
+ export async function envCommand(
26
+ uuid: string | undefined,
27
+ options: IEnvCommandOptions = {},
28
+ ) {
29
+ const resolvedUuid = resolveUuid(uuid);
30
+ if (!resolvedUuid) {
31
+ console.error(
32
+ chalk.red("Error: No UUID provided and no .coolify.json found"),
33
+ );
34
+ return;
35
+ }
36
+ uuid = resolvedUuid;
37
+ const coolify = getCoolifyService();
38
+ const initResult = await coolify.init();
26
39
 
27
40
  if (isErr(initResult)) {
28
- console.error(chalk.red(`Error: ${initResult.error.message}`))
29
- return
41
+ console.error(chalk.red(`Error: ${initResult.error.message}`));
42
+ return;
30
43
  }
31
44
 
32
45
  // Handle --set KEY=VALUE
33
46
  if (options.set) {
34
- const [key, ...valueParts] = options.set.split('=')
35
- const value = valueParts.join('=') // Handle values with = in them
47
+ const [key, ...valueParts] = options.set.split("=");
48
+ const value = valueParts.join("="); // Handle values with = in them
36
49
 
37
50
  if (!key || value === undefined) {
38
- console.error(chalk.red('Error: Invalid format. Use --set KEY=VALUE'))
39
- return
51
+ console.error(chalk.red("Error: Invalid format. Use --set KEY=VALUE"));
52
+ return;
40
53
  }
41
54
 
42
- const result = await coolify.setEnvironmentVariable(uuid, key, value, options.buildtime ?? false)
55
+ const result = await coolify.setEnvironmentVariable(
56
+ uuid,
57
+ key,
58
+ value,
59
+ options.buildtime ?? false,
60
+ );
43
61
 
44
62
  if (isErr(result)) {
45
- console.error(chalk.red(`Error: ${result.error.message}`))
46
- return
63
+ console.error(chalk.red(`Error: ${result.error.message}`));
64
+ return;
47
65
  }
48
66
 
49
- console.log(chalk.green(`✓ Set ${chalk.bold(key)} for ${uuid.slice(0, 8)}`))
50
- return
67
+ console.log(chalk.green(`✓ Set ${chalk.bold(key)} for ${uuid}`));
68
+ return;
51
69
  }
52
70
 
53
71
  // Handle --delete KEY
54
72
  if (options.delete) {
55
- const result = await coolify.deleteEnvironmentVariable(uuid, options.delete)
73
+ const result = await coolify.deleteEnvironmentVariable(
74
+ uuid,
75
+ options.delete,
76
+ );
56
77
 
57
78
  if (isErr(result)) {
58
- console.error(chalk.red(`Error: ${result.error.message}`))
59
- return
79
+ console.error(chalk.red(`Error: ${result.error.message}`));
80
+ return;
60
81
  }
61
82
 
62
- console.log(chalk.green(`✓ Deleted ${chalk.bold(options.delete)} from ${uuid.slice(0, 8)}`))
63
- return
83
+ console.log(
84
+ chalk.green(`✓ Deleted ${chalk.bold(options.delete)} from ${uuid}`),
85
+ );
86
+ return;
64
87
  }
65
88
 
66
89
  // Default: list env vars
67
- const result = await coolify.getEnvironmentVariables(uuid)
90
+ const result = await coolify.getEnvironmentVariables(uuid);
68
91
 
69
92
  if (isErr(result)) {
70
- console.error(chalk.red(`Error: ${result.error.message}`))
71
- return
93
+ console.error(chalk.red(`Error: ${result.error.message}`));
94
+ return;
72
95
  }
73
96
 
74
- const envVars = result.value
97
+ const envVars = result.value;
75
98
 
76
99
  if (envVars.length === 0) {
77
- console.log(chalk.yellow('No environment variables found'))
78
- return
100
+ console.log(chalk.yellow("No environment variables found"));
101
+ return;
79
102
  }
80
103
 
81
- console.log(chalk.cyan(`Environment variables (${envVars.length}):\n`))
104
+ console.log(chalk.cyan(`Environment variables (${envVars.length}):\n`));
82
105
 
83
106
  // Separar runtime de buildtime
84
- const runtimeVars = envVars.filter(ev => ev.is_runtime)
85
- const buildtimeVars = envVars.filter(ev => ev.is_buildtime)
107
+ const runtimeVars = envVars.filter((ev) => ev.is_runtime);
108
+ const buildtimeVars = envVars.filter((ev) => ev.is_buildtime);
86
109
 
87
110
  if (runtimeVars.length > 0) {
88
- console.log(chalk.yellow.bold('Runtime:'))
111
+ console.log(chalk.yellow.bold("Runtime:"));
89
112
  for (const ev of runtimeVars) {
90
- const required = ev.is_required ? chalk.red(' *') : ''
91
- console.log(` ${chalk.green(ev.key)}${required} = ${chalk.gray(ev.value)}`)
113
+ const required = ev.is_required ? chalk.red(" *") : "";
114
+ console.log(
115
+ ` ${chalk.green(ev.key)}${required} = ${chalk.gray(ev.value)}`,
116
+ );
92
117
  }
93
- console.log()
118
+ console.log();
94
119
  }
95
120
 
96
121
  if (buildtimeVars.length > 0) {
97
- console.log(chalk.blue.bold('Buildtime:'))
122
+ console.log(chalk.blue.bold("Buildtime:"));
98
123
  for (const ev of buildtimeVars) {
99
- console.log(` ${chalk.green(ev.key)} = ${chalk.gray(ev.value)}`)
124
+ console.log(` ${chalk.green(ev.key)} = ${chalk.gray(ev.value)}`);
100
125
  }
101
126
  }
102
127
  }
@@ -4,11 +4,11 @@
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 Table from 'cli-table3'
11
- 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 Table from "cli-table3";
11
+ import { getCoolifyService } from "../../coolify/index.js";
12
12
 
13
13
  /**
14
14
  * Environments command handler.
@@ -16,57 +16,61 @@ import { getCoolifyService } from '../../coolify/index.js'
16
16
  * @param projectUuid - Project UUID to get environments for
17
17
  * @param options - Command options
18
18
  */
19
- export async function environmentsCommand(projectUuid: string, options: { full?: boolean } = {}) {
20
- const spinner = ora('Connecting to Coolify...').start()
19
+ export async function environmentsCommand(
20
+ projectUuid: string,
21
+ _options: { full?: boolean } = {},
22
+ ) {
23
+ const spinner = ora("Connecting to Coolify...").start();
21
24
 
22
25
  try {
23
- const coolify = getCoolifyService()
24
- const initResult = await coolify.init()
26
+ const coolify = getCoolifyService();
27
+ const initResult = await coolify.init();
25
28
 
26
29
  if (isErr(initResult)) {
27
- spinner.fail(chalk.red(`Failed to initialize: ${initResult.error.message}`))
28
- return
30
+ spinner.fail(
31
+ chalk.red(`Failed to initialize: ${initResult.error.message}`),
32
+ );
33
+ return;
29
34
  }
30
35
 
31
- spinner.text = `Fetching environments for project ${projectUuid.slice(0, 8)}...`
36
+ spinner.text = `Fetching environments for project ${projectUuid}...`;
32
37
 
33
- const result = await coolify.getProjectEnvironments(projectUuid)
38
+ const result = await coolify.getProjectEnvironments(projectUuid);
34
39
 
35
40
  if (isOk(result)) {
36
- spinner.succeed(chalk.green('Environments retrieved'))
41
+ spinner.succeed(chalk.green("Environments retrieved"));
37
42
 
38
- const environments = result.value
43
+ const environments = result.value;
39
44
 
40
45
  if (environments.length === 0) {
41
- console.log(chalk.yellow('No environments found for this project'))
42
- return
46
+ console.log(chalk.yellow("No environments found for this project"));
47
+ return;
43
48
  }
44
49
 
45
50
  const table = new Table({
46
51
  head: [
47
- chalk.cyan('UUID'),
48
- chalk.cyan('Name'),
49
- chalk.cyan('Description'),
52
+ chalk.cyan("UUID"),
53
+ chalk.cyan("Name"),
54
+ chalk.cyan("Description"),
50
55
  ],
51
- ...(options.full ? { colWidths: [36, 25, 40] } : {}),
52
- })
56
+ });
53
57
 
54
58
  for (const env of environments) {
55
- table.push([
56
- options.full ? env.uuid : env.uuid.slice(0, 8),
57
- env.name,
58
- env.description || '-',
59
- ])
59
+ table.push([env.uuid, env.name, env.description || "-"]);
60
60
  }
61
61
 
62
- console.log(table.toString())
63
- console.log(chalk.gray(`Total: ${environments.length} environment(s)`))
62
+ console.log(table.toString());
63
+ console.log(chalk.gray(`Total: ${environments.length} environment(s)`));
64
64
  } else {
65
- spinner.fail(chalk.red(`Failed to fetch environments: ${result.error.message}`))
65
+ spinner.fail(
66
+ chalk.red(`Failed to fetch environments: ${result.error.message}`),
67
+ );
66
68
  }
67
69
  } catch (error) {
68
70
  spinner.fail(
69
- chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`)
70
- )
71
+ chalk.red(
72
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
73
+ ),
74
+ );
71
75
  }
72
76
  }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Execute command on application container — goes through SDK.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { chalk, getCliSdk } from "../actions.js";
8
+ import { resolveUuid } from "../coolify-state.js";
9
+
10
+ /** Execute a command on an application's running container. */
11
+ export async function execCommand(
12
+ uuid: string | undefined,
13
+ command: string,
14
+ ): Promise<void> {
15
+ const resolved = resolveUuid(uuid);
16
+ if (!resolved) {
17
+ console.error(
18
+ chalk.red("Error: No UUID provided and no .coolify.json found"),
19
+ );
20
+ return;
21
+ }
22
+
23
+ console.log(chalk.gray(`Executing on ${resolved}: ${command}`));
24
+
25
+ try {
26
+ const result = await getCliSdk().applications.exec(resolved, command);
27
+ if (result.response) {
28
+ console.log(result.response);
29
+ } else if (result.message) {
30
+ console.log(chalk.green(result.message));
31
+ }
32
+ } catch (error) {
33
+ console.error(
34
+ chalk.red(
35
+ `Error: ${error instanceof Error ? error.message : String(error)}`,
36
+ ),
37
+ );
38
+ }
39
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * SSH Private key subcommands for CLI — all go through SDK.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { runAction, runList, runGet, chalk } from "../actions.js";
8
+ import type { ICoolifyPrivateKey } from "../../coolify/types.js";
9
+
10
+ /** List all private keys. */
11
+ export const keysListCommand = () =>
12
+ runList<ICoolifyPrivateKey>("key(s)", (s) => s.keys.list(), [
13
+ { header: "UUID", value: (k) => k.uuid },
14
+ { header: "Name", value: (k) => k.name || "-" },
15
+ { header: "Git?", value: (k) => (k.is_git_related ? "Yes" : "No") },
16
+ {
17
+ header: "Created",
18
+ value: (k) =>
19
+ k.created_at ? new Date(k.created_at).toLocaleDateString() : "-",
20
+ },
21
+ ]);
22
+
23
+ /** Get private key details. */
24
+ export const keysGetCommand = (uuid: string) =>
25
+ runGet<ICoolifyPrivateKey>(
26
+ uuid,
27
+ "private key",
28
+ (s, u) => s.keys.get(u),
29
+ (key) => {
30
+ console.log(chalk.cyan("Private Key Details:"));
31
+ console.log(chalk.gray("UUID: ") + key.uuid);
32
+ console.log(chalk.gray("Name: ") + key.name);
33
+ console.log(
34
+ chalk.gray("Git-related:") + (key.is_git_related ? " Yes" : " No"),
35
+ );
36
+ },
37
+ );
38
+
39
+ /** Delete a private key. */
40
+ export const keysDeleteCommand = (uuid: string) =>
41
+ runAction(
42
+ uuid,
43
+ "Deleting private key",
44
+ (s, u) => s.keys.delete(u),
45
+ (u) => `Private key deleted: ${u}`,
46
+ );
@@ -4,60 +4,62 @@
4
4
  * @module
5
5
  */
6
6
 
7
- import { isErr } from '@mks2508/no-throw'
8
- import chalk from 'chalk'
9
- import Table from 'cli-table3'
10
- import { getCoolifyService } from '../../coolify/index.js'
11
- import { formatStatus } from '../../utils/format.js'
7
+ import { isErr } from "@mks2508/no-throw";
8
+ import chalk from "chalk";
9
+ import Table from "cli-table3";
10
+ import { getCoolifyService } from "../../coolify/index.js";
11
+ import { formatStatus } from "../../utils/format.js";
12
12
 
13
13
  /**
14
14
  * List command handler.
15
15
  *
16
16
  * @param options - List options
17
17
  */
18
- export async function listCommand(options: { team?: string; project?: string; full?: boolean }) {
19
- const coolify = getCoolifyService()
20
- const initResult = await coolify.init()
18
+ export async function listCommand(options: {
19
+ team?: string;
20
+ project?: string;
21
+ }) {
22
+ const coolify = getCoolifyService();
23
+ const initResult = await coolify.init();
21
24
 
22
25
  if (isErr(initResult)) {
23
- console.error(chalk.red(`Error: ${initResult.error.message}`))
24
- return
26
+ console.error(chalk.red(`Error: ${initResult.error.message}`));
27
+ return;
25
28
  }
26
29
 
27
- const result = await coolify.listApplications(options.team, options.project)
30
+ const result = await coolify.listApplications(options.team, options.project);
28
31
 
29
32
  if (isErr(result)) {
30
- console.error(chalk.red(`Error: ${result.error.message}`))
31
- return
33
+ console.error(chalk.red(`Error: ${result.error.message}`));
34
+ return;
32
35
  }
33
36
 
34
- const apps = result.value
37
+ const apps = result.value;
35
38
 
36
39
  if (apps.length === 0) {
37
- console.log(chalk.yellow('No applications found'))
38
- return
40
+ console.log(chalk.yellow("No applications found"));
41
+ return;
39
42
  }
40
43
 
41
44
  // Usar ancho dinámico basado en el contenido
42
45
  const table = new Table({
43
46
  head: [
44
- chalk.cyan('UUID'),
45
- chalk.cyan('Name'),
46
- chalk.cyan('Status'),
47
- chalk.cyan('Server')
47
+ chalk.cyan("UUID"),
48
+ chalk.cyan("Name"),
49
+ chalk.cyan("Status"),
50
+ chalk.cyan("Server"),
48
51
  ],
49
- ...(options.full ? { colWidths: [36, 30, 20, 10] } : {}),
50
- })
52
+ });
51
53
 
52
54
  for (const app of apps) {
53
55
  table.push([
54
- options.full ? app.uuid : app.uuid.slice(0, 8),
56
+ app.uuid,
55
57
  app.name,
56
58
  formatStatus(app.status),
57
- app.destination?.server?.name || 'N/A',
58
- ])
59
+ app.destination?.server?.name || "N/A",
60
+ ]);
59
61
  }
60
62
 
61
- console.log(table.toString())
62
- console.log(chalk.gray(`Total: ${apps.length} application(s)`))
63
+ console.log(table.toString());
64
+ console.log(chalk.gray(`Total: ${apps.length} application(s)`));
63
65
  }