@mks2508/coolify-mks-cli-mcp 0.1.0 → 0.2.1
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.
- package/dist/cli/index.js +471 -34
- package/dist/coolify/index.d.ts +17 -2
- package/dist/coolify/index.d.ts.map +1 -1
- package/dist/coolify/types.d.ts +34 -4
- package/dist/coolify/types.d.ts.map +1 -1
- package/dist/index.cjs +79 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +79 -31
- package/dist/index.js.map +1 -1
- package/dist/server/stdio.js +79 -28
- package/package.json +1 -1
- package/src/cli/commands/create.ts +116 -0
- package/src/cli/commands/delete.ts +69 -0
- package/src/cli/commands/deployments.ts +77 -0
- package/src/cli/commands/destinations.ts +60 -0
- package/src/cli/commands/environments.ts +72 -0
- package/src/cli/commands/list.ts +3 -3
- package/src/cli/commands/projects.ts +69 -0
- package/src/cli/commands/servers.ts +3 -3
- package/src/cli/commands/show.ts +74 -0
- package/src/cli/commands/update.ts +81 -0
- package/src/cli/index.ts +92 -1
- package/src/coolify/index.ts +121 -30
- package/src/coolify/types.ts +41 -4
- package/src/index.ts +6 -3
- package/src/tools/handlers.ts +5 -2
package/dist/server/stdio.js
CHANGED
|
@@ -17148,7 +17148,8 @@ class CoolifyService {
|
|
|
17148
17148
|
return { error: "Coolify not configured", status: 0, durationMs: Date.now() - startTime };
|
|
17149
17149
|
}
|
|
17150
17150
|
try {
|
|
17151
|
-
const
|
|
17151
|
+
const baseUrl = this.baseUrl.replace(/\/+$/, "");
|
|
17152
|
+
const url = `${baseUrl}/api/v1${endpoint}`;
|
|
17152
17153
|
const response = await fetch(url, {
|
|
17153
17154
|
...options,
|
|
17154
17155
|
headers: {
|
|
@@ -17187,47 +17188,81 @@ class CoolifyService {
|
|
|
17187
17188
|
log.info(`Deploying application ${options.uuid || options.tag}`);
|
|
17188
17189
|
onProgress?.(25, "Validating deployment configuration");
|
|
17189
17190
|
onProgress?.(50, "Triggering build pipeline...");
|
|
17190
|
-
const
|
|
17191
|
-
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
|
|
17195
|
-
|
|
17196
|
-
|
|
17191
|
+
const params = new URLSearchParams;
|
|
17192
|
+
if (options.uuid)
|
|
17193
|
+
params.set("uuid", options.uuid);
|
|
17194
|
+
if (options.tag)
|
|
17195
|
+
params.set("tag", options.tag);
|
|
17196
|
+
if (options.force)
|
|
17197
|
+
params.set("force", "true");
|
|
17198
|
+
const endpoint = `/deploy${params.toString() ? `?${params.toString()}` : ""}`;
|
|
17199
|
+
const result = await this.request(endpoint, {
|
|
17200
|
+
method: "POST"
|
|
17197
17201
|
});
|
|
17198
17202
|
if (result.error) {
|
|
17199
17203
|
log.error(`Deployment failed: ${result.error}`);
|
|
17200
17204
|
return err(new Error(result.error));
|
|
17201
17205
|
}
|
|
17206
|
+
const deployments = result.data?.deployments || [];
|
|
17207
|
+
if (deployments.length === 0) {
|
|
17208
|
+
log.error("No deployments started");
|
|
17209
|
+
return err(new Error("No deployments started - check application configuration"));
|
|
17210
|
+
}
|
|
17211
|
+
const deployment = deployments[0];
|
|
17202
17212
|
onProgress?.(90, "Build started on Coolify server");
|
|
17203
17213
|
onProgress?.(100, "Deployment triggered");
|
|
17204
|
-
log.success(`Deployment started: ${
|
|
17214
|
+
log.success(`Deployment started: ${deployment.deployment_uuid}`);
|
|
17205
17215
|
return ok({
|
|
17206
17216
|
success: true,
|
|
17207
|
-
deploymentUuid:
|
|
17208
|
-
resourceUuid:
|
|
17217
|
+
deploymentUuid: deployment.deployment_uuid,
|
|
17218
|
+
resourceUuid: deployment.resource_uuid
|
|
17209
17219
|
});
|
|
17210
17220
|
}
|
|
17211
17221
|
async createApplication(options, onProgress) {
|
|
17212
17222
|
onProgress?.(5, `Preparing app "${options.name}"`);
|
|
17213
|
-
|
|
17223
|
+
const appType = options.type || "public";
|
|
17224
|
+
log.info(`Creating application ${options.name} (type: ${appType})`);
|
|
17214
17225
|
onProgress?.(25, `Validating server ${options.serverUuid.slice(0, 8)}...`);
|
|
17215
17226
|
onProgress?.(50, "Sending creation request to Coolify API...");
|
|
17216
|
-
const
|
|
17227
|
+
const endpointMap = {
|
|
17228
|
+
public: "/applications/public",
|
|
17229
|
+
"private-github-app": "/applications/private-github-app",
|
|
17230
|
+
"private-deploy-key": "/applications/private-deploy-key",
|
|
17231
|
+
dockerfile: "/applications/dockerfile",
|
|
17232
|
+
"docker-image": "/applications/docker-image",
|
|
17233
|
+
"docker-compose": "/applications/docker-compose"
|
|
17234
|
+
};
|
|
17235
|
+
const endpoint = endpointMap[appType] || "/applications/public";
|
|
17236
|
+
const body = {
|
|
17237
|
+
name: options.name,
|
|
17238
|
+
description: options.description,
|
|
17239
|
+
project_uuid: options.projectUuid,
|
|
17240
|
+
environment_uuid: options.environmentUuid,
|
|
17241
|
+
server_uuid: options.serverUuid
|
|
17242
|
+
};
|
|
17243
|
+
if (appType === "public" || appType === "private-github-app" || appType === "private-deploy-key") {
|
|
17244
|
+
if (options.githubRepoUrl) {
|
|
17245
|
+
body.git_repository = options.githubRepoUrl;
|
|
17246
|
+
}
|
|
17247
|
+
body.git_branch = options.branch || "main";
|
|
17248
|
+
body.build_pack = options.buildPack || "dockerfile";
|
|
17249
|
+
if (options.portsExposes) {
|
|
17250
|
+
body.ports_exposes = options.portsExposes;
|
|
17251
|
+
}
|
|
17252
|
+
if (options.dockerfileLocation) {
|
|
17253
|
+
body.dockerfile_location = options.dockerfileLocation;
|
|
17254
|
+
}
|
|
17255
|
+
if (options.baseDirectory) {
|
|
17256
|
+
body.base_directory = options.baseDirectory;
|
|
17257
|
+
}
|
|
17258
|
+
} else if (appType === "docker-image" && options.dockerImage) {
|
|
17259
|
+
body.docker_image = options.dockerImage;
|
|
17260
|
+
} else if (appType === "docker-compose" && options.dockerCompose) {
|
|
17261
|
+
body.docker_compose = options.dockerCompose;
|
|
17262
|
+
}
|
|
17263
|
+
const result = await this.request(endpoint, {
|
|
17217
17264
|
method: "POST",
|
|
17218
|
-
body: JSON.stringify(
|
|
17219
|
-
name: options.name,
|
|
17220
|
-
description: options.description,
|
|
17221
|
-
server_uuid: options.serverUuid,
|
|
17222
|
-
destination_uuid: options.destinationUuid,
|
|
17223
|
-
project_uuid: options.serverUuid,
|
|
17224
|
-
environment_name: "production",
|
|
17225
|
-
git_repository: options.githubRepoUrl,
|
|
17226
|
-
git_branch: options.branch || "main",
|
|
17227
|
-
build_pack: options.buildPack || "nixpacks",
|
|
17228
|
-
ports_exposes: "3000",
|
|
17229
|
-
instant_deploy: false
|
|
17230
|
-
})
|
|
17265
|
+
body: JSON.stringify(body)
|
|
17231
17266
|
});
|
|
17232
17267
|
if (result.error) {
|
|
17233
17268
|
log.error(`Failed to create application: ${result.error}`);
|
|
@@ -17299,6 +17334,16 @@ class CoolifyService {
|
|
|
17299
17334
|
}
|
|
17300
17335
|
return ok(result.data || []);
|
|
17301
17336
|
}
|
|
17337
|
+
async getProjectEnvironments(projectUuid) {
|
|
17338
|
+
log.info(`Getting environments for project ${projectUuid}`);
|
|
17339
|
+
const result = await this.request(`/projects/${projectUuid}`);
|
|
17340
|
+
if (result.error) {
|
|
17341
|
+
log.error(`Failed to get environments: ${result.error}`);
|
|
17342
|
+
return err(new Error(result.error));
|
|
17343
|
+
}
|
|
17344
|
+
log.success(`Environments retrieved for project ${projectUuid}`);
|
|
17345
|
+
return ok(result.data?.environments || []);
|
|
17346
|
+
}
|
|
17302
17347
|
async listTeams() {
|
|
17303
17348
|
const result = await this.request("/teams");
|
|
17304
17349
|
if (result.error) {
|
|
@@ -17363,6 +17408,10 @@ class CoolifyService {
|
|
|
17363
17408
|
body.build_command = options.buildCommand;
|
|
17364
17409
|
if (options.startCommand)
|
|
17365
17410
|
body.start_command = options.startCommand;
|
|
17411
|
+
if (options.dockerfileLocation)
|
|
17412
|
+
body.dockerfile_location = options.dockerfileLocation;
|
|
17413
|
+
if (options.baseDirectory)
|
|
17414
|
+
body.base_directory = options.baseDirectory;
|
|
17366
17415
|
const result = await this.request(`/applications/${appUuid}`, {
|
|
17367
17416
|
method: "PATCH",
|
|
17368
17417
|
body: JSON.stringify(body)
|
|
@@ -17401,7 +17450,7 @@ class CoolifyService {
|
|
|
17401
17450
|
return err(new Error(result.error));
|
|
17402
17451
|
}
|
|
17403
17452
|
log.success(`Deployment history retrieved for ${appUuid}`);
|
|
17404
|
-
return ok(result.data || []);
|
|
17453
|
+
return ok(result.data?.deployments || []);
|
|
17405
17454
|
}
|
|
17406
17455
|
async startApplication(appUuid) {
|
|
17407
17456
|
log.info(`Starting application ${appUuid}`);
|
|
@@ -18225,8 +18274,10 @@ async function handleCreateApplication(coolify, args) {
|
|
|
18225
18274
|
const result = await coolify.createApplication({
|
|
18226
18275
|
name: args.name,
|
|
18227
18276
|
description: args.description,
|
|
18277
|
+
projectUuid: args.projectUuid,
|
|
18278
|
+
environmentUuid: args.environmentUuid,
|
|
18228
18279
|
serverUuid: args.serverUuid,
|
|
18229
|
-
|
|
18280
|
+
type: "public",
|
|
18230
18281
|
githubRepoUrl: args.githubRepoUrl,
|
|
18231
18282
|
branch: args.branch,
|
|
18232
18283
|
buildPack: args.buildPack
|
package/package.json
CHANGED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create command for CLI.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
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'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create command options.
|
|
14
|
+
*/
|
|
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'
|
|
25
|
+
ports?: string
|
|
26
|
+
dockerImage?: string
|
|
27
|
+
dockerCompose?: string
|
|
28
|
+
dockerfileLocation?: string
|
|
29
|
+
baseDirectory?: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Create command handler.
|
|
34
|
+
*
|
|
35
|
+
* @param options - Create options
|
|
36
|
+
*/
|
|
37
|
+
export async function createCommand(options: ICreateOptions) {
|
|
38
|
+
const spinner = ora('Initializing Coolify connection...').start()
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const coolify = getCoolifyService()
|
|
42
|
+
const initResult = await coolify.init()
|
|
43
|
+
|
|
44
|
+
if (isErr(initResult)) {
|
|
45
|
+
spinner.fail(chalk.red(`Failed to initialize: ${initResult.error.message}`))
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Auto-fetch environment UUID if not provided
|
|
50
|
+
let environmentUuid: string | undefined = options.environment
|
|
51
|
+
|
|
52
|
+
if (!environmentUuid) {
|
|
53
|
+
spinner.text = 'Fetching project environments...'
|
|
54
|
+
|
|
55
|
+
const envResult = await coolify.getProjectEnvironments(options.project)
|
|
56
|
+
|
|
57
|
+
if (isOk(envResult) && envResult.value.length > 0) {
|
|
58
|
+
// Use the first environment (usually "production")
|
|
59
|
+
environmentUuid = envResult.value[0].uuid
|
|
60
|
+
const envName = envResult.value[0].name
|
|
61
|
+
spinner.info(chalk.cyan(`Using environment: ${envName} (${environmentUuid.slice(0, 8)}...)`))
|
|
62
|
+
} else {
|
|
63
|
+
spinner.fail(chalk.red('No environments found for project. Please specify --environment <uuid>'))
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Ensure environmentUuid is defined before creating application
|
|
69
|
+
if (!environmentUuid) {
|
|
70
|
+
spinner.fail(chalk.red('Environment UUID is required'))
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
spinner.text = 'Creating application...'
|
|
75
|
+
|
|
76
|
+
const result = await coolify.createApplication(
|
|
77
|
+
{
|
|
78
|
+
name: options.name,
|
|
79
|
+
description: options.description,
|
|
80
|
+
projectUuid: options.project,
|
|
81
|
+
environmentUuid,
|
|
82
|
+
serverUuid: options.server,
|
|
83
|
+
type: options.type || 'public',
|
|
84
|
+
githubRepoUrl: options.repo,
|
|
85
|
+
branch: options.branch || 'main',
|
|
86
|
+
buildPack: options.buildPack || 'dockerfile',
|
|
87
|
+
portsExposes: options.ports || '3000',
|
|
88
|
+
dockerImage: options.dockerImage,
|
|
89
|
+
dockerCompose: options.dockerCompose,
|
|
90
|
+
dockerfileLocation: options.dockerfileLocation,
|
|
91
|
+
baseDirectory: options.baseDirectory,
|
|
92
|
+
},
|
|
93
|
+
(percent, message) => {
|
|
94
|
+
spinner.text = `${chalk.bold(`[${percent}%]`)} ${message}`
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
if (isOk(result)) {
|
|
99
|
+
spinner.succeed(
|
|
100
|
+
chalk.green(`Application created! UUID: ${chalk.cyan(result.value.uuid?.slice(0, 8))}`)
|
|
101
|
+
)
|
|
102
|
+
console.log(` Full UUID: ${chalk.cyan(result.value.uuid)}`)
|
|
103
|
+
console.log(` Name: ${chalk.cyan(options.name)}`)
|
|
104
|
+
console.log(` Type: ${chalk.cyan(options.type || 'public')}`)
|
|
105
|
+
console.log(` Next steps:`)
|
|
106
|
+
console.log(` 1. Set environment variables: ${chalk.yellow('coolify-mcp env ' + result.value.uuid?.slice(0, 8))}`)
|
|
107
|
+
console.log(` 2. Deploy application: ${chalk.yellow('coolify-mcp deploy ' + result.value.uuid?.slice(0, 8))}`)
|
|
108
|
+
} else {
|
|
109
|
+
spinner.fail(chalk.red(`Creation failed: ${result.error.message}`))
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
spinner.fail(
|
|
113
|
+
chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`)
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delete application command.
|
|
3
|
+
*
|
|
4
|
+
* Deletes an existing Coolify application.
|
|
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
|
+
* Executes the delete command.
|
|
15
|
+
*
|
|
16
|
+
* @param uuid - Application UUID
|
|
17
|
+
* @param options - Command options
|
|
18
|
+
*/
|
|
19
|
+
export async function deleteCommand(
|
|
20
|
+
uuid: string,
|
|
21
|
+
options: { force?: boolean; yes?: boolean } = {}
|
|
22
|
+
): Promise<void> {
|
|
23
|
+
const service = getCoolifyService()
|
|
24
|
+
const initResult = await service.init()
|
|
25
|
+
|
|
26
|
+
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)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!options.force && !options.yes) {
|
|
33
|
+
const readline = await import('readline')
|
|
34
|
+
const rl = readline.createInterface({
|
|
35
|
+
input: process.stdin,
|
|
36
|
+
output: process.stdout,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const answer = await new Promise<string>((resolve) => {
|
|
40
|
+
rl.question(
|
|
41
|
+
chalk.yellow(`Are you sure you want to delete application ${chalk.bold(uuid)}? (yes/no): `),
|
|
42
|
+
(ans) => {
|
|
43
|
+
rl.close()
|
|
44
|
+
resolve(ans.toLowerCase())
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
if (answer !== 'yes' && answer !== 'y') {
|
|
50
|
+
console.log(chalk.gray('Operation cancelled'))
|
|
51
|
+
process.exit(0)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log(chalk.cyan(`Deleting application ${chalk.bold(uuid)}...`))
|
|
56
|
+
|
|
57
|
+
const result = await service.deleteApplication(uuid)
|
|
58
|
+
|
|
59
|
+
if (isErr(result)) {
|
|
60
|
+
console.error(chalk.red('Failed to delete application'))
|
|
61
|
+
console.error(chalk.gray(result.error.message))
|
|
62
|
+
process.exit(1)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log(chalk.green('Application deleted successfully'))
|
|
66
|
+
if (result.value.message) {
|
|
67
|
+
console.log(chalk.gray(result.value.message))
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployments command for CLI.
|
|
3
|
+
*
|
|
4
|
+
* Shows deployment history for an application.
|
|
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
|
+
* Deployments command handler.
|
|
17
|
+
*
|
|
18
|
+
* @param uuid - Application UUID
|
|
19
|
+
* @param options - Command options
|
|
20
|
+
*/
|
|
21
|
+
export async function deploymentsCommand(
|
|
22
|
+
uuid: string,
|
|
23
|
+
options: { full?: boolean; limit?: number } = {}
|
|
24
|
+
) {
|
|
25
|
+
const coolify = getCoolifyService()
|
|
26
|
+
const initResult = await coolify.init()
|
|
27
|
+
|
|
28
|
+
if (isErr(initResult)) {
|
|
29
|
+
console.error(chalk.red(`Error: ${initResult.error.message}`))
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = await coolify.getApplicationDeploymentHistory(uuid)
|
|
34
|
+
|
|
35
|
+
if (isErr(result)) {
|
|
36
|
+
console.error(chalk.red(`Error: ${result.error.message}`))
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let deployments = result.value
|
|
41
|
+
|
|
42
|
+
// Show most recent first
|
|
43
|
+
deployments = deployments.reverse()
|
|
44
|
+
|
|
45
|
+
if (options.limit) {
|
|
46
|
+
deployments = deployments.slice(0, options.limit)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (deployments.length === 0) {
|
|
50
|
+
console.log(chalk.yellow('No deployments found'))
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const table = new Table({
|
|
55
|
+
head: [
|
|
56
|
+
chalk.cyan('ID'),
|
|
57
|
+
chalk.cyan('UUID'),
|
|
58
|
+
chalk.cyan('Status'),
|
|
59
|
+
chalk.cyan('Commit'),
|
|
60
|
+
chalk.cyan('Created'),
|
|
61
|
+
],
|
|
62
|
+
...(options.full ? { colWidths: [8, 36, 20, 10, 20] } : {}),
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
for (const dep of deployments) {
|
|
66
|
+
table.push([
|
|
67
|
+
String(dep.id),
|
|
68
|
+
options.full ? dep.uuid : dep.uuid.slice(0, 8),
|
|
69
|
+
formatStatus(dep.status),
|
|
70
|
+
dep.commit?.slice(0, 7) || '-',
|
|
71
|
+
new Date(dep.created_at).toLocaleString(),
|
|
72
|
+
])
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log(table.toString())
|
|
76
|
+
console.log(chalk.gray(`Total: ${deployments.length} deployment(s)`))
|
|
77
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destinations command for CLI.
|
|
3
|
+
*
|
|
4
|
+
* Lists available destinations for a server.
|
|
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
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Destinations command handler.
|
|
16
|
+
*
|
|
17
|
+
* @param serverUuid - Server UUID
|
|
18
|
+
*/
|
|
19
|
+
export async function destinationsCommand(serverUuid: string) {
|
|
20
|
+
const coolify = getCoolifyService()
|
|
21
|
+
const initResult = await coolify.init()
|
|
22
|
+
|
|
23
|
+
if (isErr(initResult)) {
|
|
24
|
+
console.error(chalk.red(`Error: ${initResult.error.message}`))
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const result = await coolify.getServerDestinations(serverUuid)
|
|
29
|
+
|
|
30
|
+
if (isErr(result)) {
|
|
31
|
+
console.error(chalk.red(`Error: ${result.error.message}`))
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const destinations = result.value
|
|
36
|
+
|
|
37
|
+
if (destinations.length === 0) {
|
|
38
|
+
console.log(chalk.yellow('No destinations found'))
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const table = new Table({
|
|
43
|
+
head: [
|
|
44
|
+
chalk.cyan('UUID'),
|
|
45
|
+
chalk.cyan('Name'),
|
|
46
|
+
chalk.cyan('Network'),
|
|
47
|
+
],
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
for (const dest of destinations) {
|
|
51
|
+
table.push([
|
|
52
|
+
dest.uuid,
|
|
53
|
+
dest.name,
|
|
54
|
+
dest.network || 'N/A',
|
|
55
|
+
])
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log(table.toString())
|
|
59
|
+
console.log(chalk.gray(`Total: ${destinations.length} destination(s)`))
|
|
60
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environments command for CLI.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
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'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Environments command handler.
|
|
15
|
+
*
|
|
16
|
+
* @param projectUuid - Project UUID to get environments for
|
|
17
|
+
* @param options - Command options
|
|
18
|
+
*/
|
|
19
|
+
export async function environmentsCommand(projectUuid: string, options: { full?: boolean } = {}) {
|
|
20
|
+
const spinner = ora('Connecting to Coolify...').start()
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const coolify = getCoolifyService()
|
|
24
|
+
const initResult = await coolify.init()
|
|
25
|
+
|
|
26
|
+
if (isErr(initResult)) {
|
|
27
|
+
spinner.fail(chalk.red(`Failed to initialize: ${initResult.error.message}`))
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
spinner.text = `Fetching environments for project ${projectUuid.slice(0, 8)}...`
|
|
32
|
+
|
|
33
|
+
const result = await coolify.getProjectEnvironments(projectUuid)
|
|
34
|
+
|
|
35
|
+
if (isOk(result)) {
|
|
36
|
+
spinner.succeed(chalk.green('Environments retrieved'))
|
|
37
|
+
|
|
38
|
+
const environments = result.value
|
|
39
|
+
|
|
40
|
+
if (environments.length === 0) {
|
|
41
|
+
console.log(chalk.yellow('No environments found for this project'))
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const table = new Table({
|
|
46
|
+
head: [
|
|
47
|
+
chalk.cyan('UUID'),
|
|
48
|
+
chalk.cyan('Name'),
|
|
49
|
+
chalk.cyan('Description'),
|
|
50
|
+
],
|
|
51
|
+
...(options.full ? { colWidths: [36, 25, 40] } : {}),
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
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
|
+
])
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log(table.toString())
|
|
63
|
+
console.log(chalk.gray(`Total: ${environments.length} environment(s)`))
|
|
64
|
+
} else {
|
|
65
|
+
spinner.fail(chalk.red(`Failed to fetch environments: ${result.error.message}`))
|
|
66
|
+
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
spinner.fail(
|
|
69
|
+
chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`)
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
}
|
package/src/cli/commands/list.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { formatStatus } from '../../utils/format.js'
|
|
|
15
15
|
*
|
|
16
16
|
* @param options - List options
|
|
17
17
|
*/
|
|
18
|
-
export async function listCommand(options: { team?: string; project?: string }) {
|
|
18
|
+
export async function listCommand(options: { team?: string; project?: string; full?: boolean }) {
|
|
19
19
|
const coolify = getCoolifyService()
|
|
20
20
|
const initResult = await coolify.init()
|
|
21
21
|
|
|
@@ -46,12 +46,12 @@ export async function listCommand(options: { team?: string; project?: string })
|
|
|
46
46
|
chalk.cyan('Status'),
|
|
47
47
|
chalk.cyan('Server')
|
|
48
48
|
],
|
|
49
|
-
|
|
49
|
+
...(options.full ? { colWidths: [36, 30, 20, 10] } : {}),
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
for (const app of apps) {
|
|
53
53
|
table.push([
|
|
54
|
-
app.uuid,
|
|
54
|
+
options.full ? app.uuid : app.uuid.slice(0, 8),
|
|
55
55
|
app.name,
|
|
56
56
|
formatStatus(app.status),
|
|
57
57
|
app.destination?.server?.name || 'N/A',
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects command for CLI.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
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'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Projects command handler.
|
|
15
|
+
*/
|
|
16
|
+
export async function projectsCommand(options: { full?: boolean } = {}) {
|
|
17
|
+
const spinner = ora('Connecting to Coolify...').start()
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const coolify = getCoolifyService()
|
|
21
|
+
const initResult = await coolify.init()
|
|
22
|
+
|
|
23
|
+
if (isErr(initResult)) {
|
|
24
|
+
spinner.fail(chalk.red(`Failed to initialize: ${initResult.error.message}`))
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
spinner.text = 'Fetching projects...'
|
|
29
|
+
|
|
30
|
+
const result = await coolify.listProjects()
|
|
31
|
+
|
|
32
|
+
if (isOk(result)) {
|
|
33
|
+
spinner.succeed(chalk.green('Projects retrieved'))
|
|
34
|
+
|
|
35
|
+
const projects = result.value
|
|
36
|
+
|
|
37
|
+
if (projects.length === 0) {
|
|
38
|
+
console.log(chalk.yellow('No projects found'))
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const table = new Table({
|
|
43
|
+
head: [
|
|
44
|
+
chalk.cyan('UUID'),
|
|
45
|
+
chalk.cyan('Name'),
|
|
46
|
+
chalk.cyan('Description'),
|
|
47
|
+
],
|
|
48
|
+
...(options.full ? { colWidths: [36, 30, 40] } : {}),
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
for (const project of projects) {
|
|
52
|
+
table.push([
|
|
53
|
+
options.full ? project.uuid : project.uuid.slice(0, 8),
|
|
54
|
+
project.name,
|
|
55
|
+
project.description || '-',
|
|
56
|
+
])
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log(table.toString())
|
|
60
|
+
console.log(chalk.gray(`Total: ${projects.length} project(s)`))
|
|
61
|
+
} else {
|
|
62
|
+
spinner.fail(chalk.red(`Failed to fetch projects: ${result.error.message}`))
|
|
63
|
+
}
|
|
64
|
+
} catch (error) {
|
|
65
|
+
spinner.fail(
|
|
66
|
+
chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`)
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -12,7 +12,7 @@ import { createTable } from '../../utils/format.js'
|
|
|
12
12
|
/**
|
|
13
13
|
* Servers command handler.
|
|
14
14
|
*/
|
|
15
|
-
export async function serversCommand() {
|
|
15
|
+
export async function serversCommand(options: { full?: boolean } = {}) {
|
|
16
16
|
const coolify = getCoolifyService()
|
|
17
17
|
const initResult = await coolify.init()
|
|
18
18
|
|
|
@@ -35,12 +35,12 @@ export async function serversCommand() {
|
|
|
35
35
|
return
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const table = createTable(['UUID', 'Name', 'IP', 'Status'], [36, 25, 20, 15])
|
|
38
|
+
const table = createTable(['UUID', 'Name', 'IP', 'Status'], [options.full ? 36 : 8, 25, 20, 15])
|
|
39
39
|
|
|
40
40
|
for (const server of servers) {
|
|
41
41
|
const statusColor = server.is_usable ? chalk.green : chalk.red
|
|
42
42
|
table.push([
|
|
43
|
-
server.uuid.slice(0, 8),
|
|
43
|
+
options.full ? server.uuid : server.uuid.slice(0, 8),
|
|
44
44
|
server.name,
|
|
45
45
|
server.ip || 'N/A',
|
|
46
46
|
statusColor(server.is_usable ? '● Usable' : '○ Unusable'),
|