@mks2508/coolify-mks-cli-mcp 0.6.3 → 0.9.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.
- package/dist/cli/coolify-state.d.ts +101 -5
- package/dist/cli/coolify-state.d.ts.map +1 -1
- package/dist/cli/index.js +23165 -11543
- package/dist/cli/ui/highlighter.d.ts +28 -0
- package/dist/cli/ui/highlighter.d.ts.map +1 -0
- package/dist/cli/ui/index.d.ts +9 -0
- package/dist/cli/ui/index.d.ts.map +1 -0
- package/dist/cli/ui/spinners.d.ts +100 -0
- package/dist/cli/ui/spinners.d.ts.map +1 -0
- package/dist/cli/ui/tables.d.ts +103 -0
- package/dist/cli/ui/tables.d.ts.map +1 -0
- package/dist/coolify/config.d.ts +25 -0
- package/dist/coolify/config.d.ts.map +1 -1
- package/dist/coolify/index.d.ts +139 -12
- package/dist/coolify/index.d.ts.map +1 -1
- package/dist/coolify/types.d.ts +160 -2
- package/dist/coolify/types.d.ts.map +1 -1
- package/dist/examples/demo-ui.d.ts +8 -0
- package/dist/examples/demo-ui.d.ts.map +1 -0
- package/dist/index.cjs +2580 -230
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2598 -226
- package/dist/index.js.map +1 -1
- package/dist/sdk.d.ts +96 -7
- package/dist/sdk.d.ts.map +1 -1
- package/dist/server/stdio.js +475 -73
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/utils/env-parser.d.ts +24 -0
- package/dist/utils/env-parser.d.ts.map +1 -0
- package/dist/utils/format.d.ts +32 -0
- package/dist/utils/format.d.ts.map +1 -1
- package/package.json +17 -4
- package/src/cli/actions.ts +9 -2
- package/src/cli/commands/create.ts +332 -24
- package/src/cli/commands/db.ts +37 -0
- package/src/cli/commands/delete.ts +6 -2
- package/src/cli/commands/deploy.ts +347 -49
- package/src/cli/commands/deployments.ts +6 -2
- package/src/cli/commands/diagnose.ts +3 -3
- package/src/cli/commands/env.ts +424 -31
- package/src/cli/commands/exec.ts +6 -2
- package/src/cli/commands/init.ts +991 -0
- package/src/cli/commands/logs.ts +224 -24
- package/src/cli/commands/main-menu.ts +21 -0
- package/src/cli/commands/projects.ts +312 -29
- package/src/cli/commands/restart.ts +6 -2
- package/src/cli/commands/service-logs.ts +14 -0
- package/src/cli/commands/show.ts +45 -12
- package/src/cli/commands/start.ts +6 -2
- package/src/cli/commands/status.ts +554 -0
- package/src/cli/commands/stop.ts +6 -2
- package/src/cli/commands/svc.ts +7 -1
- package/src/cli/commands/update.ts +79 -2
- package/src/cli/commands/volumes.ts +293 -0
- package/src/cli/coolify-state.ts +203 -12
- package/src/cli/index.ts +138 -11
- package/src/cli/name-resolver.ts +228 -0
- package/src/cli/ui/banner.ts +276 -0
- package/src/cli/ui/highlighter.ts +176 -0
- package/src/cli/ui/index.ts +9 -0
- package/src/cli/ui/prompts.ts +155 -0
- package/src/cli/ui/screen.ts +630 -0
- package/src/cli/ui/select.ts +280 -0
- package/src/cli/ui/spinners.ts +256 -0
- package/src/cli/ui/tables.ts +407 -0
- package/src/coolify/config.ts +75 -0
- package/src/coolify/index.ts +565 -101
- package/src/coolify/types.ts +165 -2
- package/src/examples/demo-ui.ts +78 -0
- package/src/sdk.ts +211 -1
- package/src/tools/definitions.ts +22 -0
- package/src/tools/handlers.ts +19 -0
- package/src/utils/env-parser.ts +45 -0
- package/src/utils/format.ts +178 -0
package/src/cli/index.ts
CHANGED
|
@@ -9,12 +9,17 @@
|
|
|
9
9
|
|
|
10
10
|
import { Command } from "commander";
|
|
11
11
|
import chalk from "chalk";
|
|
12
|
+
import { setVerbosity } from "@mks2508/better-logger";
|
|
13
|
+
|
|
14
|
+
// Silence SDK logger in CLI mode — all progress goes through spinners/prompts
|
|
15
|
+
setVerbosity("silent");
|
|
12
16
|
import { createCommand } from "./commands/create.js";
|
|
13
17
|
import { deployCommand } from "./commands/deploy.js";
|
|
14
18
|
import { listCommand } from "./commands/list.js";
|
|
15
19
|
import { logsCommand } from "./commands/logs.js";
|
|
16
20
|
import { serversCommand } from "./commands/servers.js";
|
|
17
21
|
import { projectsCommand } from "./commands/projects.js";
|
|
22
|
+
import { statusCommand } from "./commands/status.js";
|
|
18
23
|
import { environmentsCommand } from "./commands/environments.js";
|
|
19
24
|
import { configCommand } from "./commands/config.js";
|
|
20
25
|
import { envCommand } from "./commands/env.js";
|
|
@@ -28,6 +33,7 @@ import { stopCommand } from "./commands/stop.js";
|
|
|
28
33
|
import { restartCommand } from "./commands/restart.js";
|
|
29
34
|
import { buildLogsCommand } from "./commands/build-logs.js";
|
|
30
35
|
import { serviceLogsCommand } from "./commands/service-logs.js";
|
|
36
|
+
import { initCommand } from "./commands/init.js";
|
|
31
37
|
import { versionCommand } from "./commands/version.js";
|
|
32
38
|
import { databasesCommand } from "./commands/databases.js";
|
|
33
39
|
import { servicesCommand as servicesListCommand } from "./commands/services.js";
|
|
@@ -37,6 +43,7 @@ import {
|
|
|
37
43
|
dbListCommand,
|
|
38
44
|
dbGetCommand,
|
|
39
45
|
dbCreateCommand,
|
|
46
|
+
dbUpdateCommand,
|
|
40
47
|
dbStartCommand,
|
|
41
48
|
dbStopCommand,
|
|
42
49
|
dbRestartCommand,
|
|
@@ -75,13 +82,30 @@ import {
|
|
|
75
82
|
networkInspectCommand,
|
|
76
83
|
analyzeDeployCommand,
|
|
77
84
|
} from "./commands/network.js";
|
|
85
|
+
import {
|
|
86
|
+
volumesListCommand,
|
|
87
|
+
volumesAddCommand,
|
|
88
|
+
volumesRemoveCommand,
|
|
89
|
+
} from "./commands/volumes.js";
|
|
78
90
|
|
|
79
91
|
const program = new Command();
|
|
80
92
|
|
|
93
|
+
// Detect binary name to show correct help
|
|
94
|
+
const binaryName = process.argv[1]?.includes("coolify-cli") ? "coolify-cli" : "coolify-mcp";
|
|
95
|
+
|
|
81
96
|
program
|
|
82
|
-
.name(
|
|
83
|
-
.description(
|
|
84
|
-
|
|
97
|
+
.name(binaryName)
|
|
98
|
+
.description(
|
|
99
|
+
`${chalk.bold.hex("#8c52ff")("Coolify CLI")} — Manage deployments, env vars, and resources\n` +
|
|
100
|
+
` Global: ${chalk.gray("bun install -g @mks2508/coolify-mks-cli-mcp")}`,
|
|
101
|
+
)
|
|
102
|
+
.version("0.9.0")
|
|
103
|
+
.addHelpText("beforeAll", () => {
|
|
104
|
+
// Show banner before help output
|
|
105
|
+
const { showAutoBanner } = require("./ui/banner.js");
|
|
106
|
+
showAutoBanner("0.9.0");
|
|
107
|
+
return "";
|
|
108
|
+
});
|
|
85
109
|
|
|
86
110
|
// Create application
|
|
87
111
|
program
|
|
@@ -126,6 +150,18 @@ program
|
|
|
126
150
|
'Base directory for build context (default: "/")',
|
|
127
151
|
"/",
|
|
128
152
|
)
|
|
153
|
+
.option(
|
|
154
|
+
"--github-app-uuid <uuid>",
|
|
155
|
+
"GitHub App UUID (auto-detected if not provided)",
|
|
156
|
+
)
|
|
157
|
+
.option(
|
|
158
|
+
"--private-key-uuid <uuid>",
|
|
159
|
+
"Private key UUID (required for private-deploy-key type)",
|
|
160
|
+
)
|
|
161
|
+
.option(
|
|
162
|
+
"--domain <domain>",
|
|
163
|
+
"Domain to set after creation (e.g., app.example.com or https://app.example.com)",
|
|
164
|
+
)
|
|
129
165
|
.action(createCommand);
|
|
130
166
|
|
|
131
167
|
// Config command
|
|
@@ -137,6 +173,16 @@ program
|
|
|
137
173
|
.option("--value <value>", 'Configuration value (for "set" action)')
|
|
138
174
|
.action(configCommand);
|
|
139
175
|
|
|
176
|
+
// Init application (link existing or create new)
|
|
177
|
+
program
|
|
178
|
+
.command("init")
|
|
179
|
+
.description("Initialize Coolify deployment (link existing or create new)")
|
|
180
|
+
.option("--yes", "Auto-mode with defaults")
|
|
181
|
+
.option("--force", "Ignore existing .coolify.json")
|
|
182
|
+
.option("--name <name>", "App name")
|
|
183
|
+
.option("--link", "Link-only mode (don't create new apps)")
|
|
184
|
+
.action(initCommand);
|
|
185
|
+
|
|
140
186
|
// List applications
|
|
141
187
|
program
|
|
142
188
|
.command("list")
|
|
@@ -152,6 +198,8 @@ program
|
|
|
152
198
|
.description("Deploy an application (reads .coolify.json if no UUID)")
|
|
153
199
|
.option("-f, --force", "Force rebuild without cache")
|
|
154
200
|
.option("-t, --tag <tag>", "Deploy specific tag/version")
|
|
201
|
+
.option("--all", "Deploy all apps from .coolify.json in parallel")
|
|
202
|
+
.option("--service <name>", "Deploy specific service from .coolify.json")
|
|
155
203
|
.action(deployCommand);
|
|
156
204
|
|
|
157
205
|
// Logs command
|
|
@@ -159,10 +207,17 @@ program
|
|
|
159
207
|
.command("logs [uuid]")
|
|
160
208
|
.description("Get application logs (reads .coolify.json if no UUID)")
|
|
161
209
|
.option("-n, --lines <number>", "Number of lines to retrieve", "50")
|
|
162
|
-
.option("-f, --follow", "Follow logs in real-time")
|
|
210
|
+
.option("-f, --follow", "Follow logs in real-time (polls every 2s)")
|
|
211
|
+
.option("--errors", "Show errors only")
|
|
212
|
+
.option("--since <duration>", "Show logs since duration (e.g. 1h, 30m, 2d)")
|
|
163
213
|
.action((uuid, options) => {
|
|
164
214
|
const lines = parseInt(options.lines, 10);
|
|
165
|
-
logsCommand(uuid, {
|
|
215
|
+
logsCommand(uuid, {
|
|
216
|
+
lines,
|
|
217
|
+
follow: options.follow,
|
|
218
|
+
errors: options.errors,
|
|
219
|
+
since: options.since,
|
|
220
|
+
});
|
|
166
221
|
});
|
|
167
222
|
|
|
168
223
|
// Servers command
|
|
@@ -172,6 +227,13 @@ program
|
|
|
172
227
|
|
|
173
228
|
.action((options) => serversCommand(options));
|
|
174
229
|
|
|
230
|
+
// Status dashboard
|
|
231
|
+
program
|
|
232
|
+
.command("status")
|
|
233
|
+
.description("Show status dashboard")
|
|
234
|
+
.option("-w, --watch", "Auto-refresh every 5s")
|
|
235
|
+
.action((options) => statusCommand(options));
|
|
236
|
+
|
|
175
237
|
// Projects command
|
|
176
238
|
program
|
|
177
239
|
.command("projects")
|
|
@@ -179,6 +241,8 @@ program
|
|
|
179
241
|
|
|
180
242
|
.option("--create <name>", "Create a new project with this name")
|
|
181
243
|
.option("--description <desc>", "Project description (use with --create)")
|
|
244
|
+
.option("--show <uuid>", "Show project details with environments, apps, and databases")
|
|
245
|
+
.option("--apps <uuid>", "Show all applications in a project")
|
|
182
246
|
.action((options) => projectsCommand(options));
|
|
183
247
|
|
|
184
248
|
// Environments command
|
|
@@ -192,9 +256,21 @@ program
|
|
|
192
256
|
program
|
|
193
257
|
.command("env [uuid]")
|
|
194
258
|
.description("Manage env vars (reads .coolify.json if no UUID)")
|
|
195
|
-
.option(
|
|
259
|
+
.option(
|
|
260
|
+
"--set <KEY=VALUE>",
|
|
261
|
+
"Set an environment variable (can be repeated: --set A=1 --set B=2)",
|
|
262
|
+
(value: string, prev: string[] | undefined) => (prev ?? []).concat(value),
|
|
263
|
+
[] as string[],
|
|
264
|
+
)
|
|
196
265
|
.option("--delete <KEY>", "Delete an environment variable")
|
|
266
|
+
.option("--get <KEY>", "Get a single environment variable value (prints value, no colors)")
|
|
197
267
|
.option("--buildtime", "Mark variable as build-time only (use with --set)")
|
|
268
|
+
.option("--runtime-only", "Mark variable as runtime only, not build-time (use with --set)")
|
|
269
|
+
.option("--sync [file]", "Sync env vars from .env file (default: .env, or stdin with -)")
|
|
270
|
+
.option("--dry-run", "Preview changes without applying (use with --sync)")
|
|
271
|
+
.option("--prune", "Delete vars not in file (use with --sync)")
|
|
272
|
+
.option("--table", "Show env vars in table format")
|
|
273
|
+
.option("--json", "Output machine-parseable JSON (ICoolifyEnvVar[])")
|
|
198
274
|
.action((uuid, options) => envCommand(uuid, options));
|
|
199
275
|
|
|
200
276
|
// Update application
|
|
@@ -223,7 +299,20 @@ program
|
|
|
223
299
|
)
|
|
224
300
|
.option("--auto-deploy", "Enable auto-deploy on git push")
|
|
225
301
|
.option("--no-auto-deploy", "Disable auto-deploy on git push")
|
|
302
|
+
.option(
|
|
303
|
+
"--watch-paths <paths>",
|
|
304
|
+
'Watch paths for selective auto-deploy (newline-separated globs, e.g. "src/**\\npackages/**")',
|
|
305
|
+
)
|
|
306
|
+
.option("--clear-watch-paths", "Clear watch paths (deploy on all changes)")
|
|
226
307
|
.option("--force-https", "Enable forced HTTPS redirect")
|
|
308
|
+
.option("--health-check-enabled", "Enable health check")
|
|
309
|
+
.option("--no-health-check-enabled", "Disable health check")
|
|
310
|
+
.option("--health-check-path <path>", "Health check path (e.g., /health)")
|
|
311
|
+
.option("--health-check-port <port>", "Health check port")
|
|
312
|
+
.option("--health-check-interval <seconds>", "Health check interval in seconds")
|
|
313
|
+
.option("--health-check-timeout <seconds>", "Health check timeout in seconds")
|
|
314
|
+
.option("--health-check-retries <n>", "Health check retries")
|
|
315
|
+
.option("--health-check-start-period <seconds>", "Health check start period in seconds")
|
|
227
316
|
.action((uuid, options) => updateCommand({ uuid, ...options }));
|
|
228
317
|
|
|
229
318
|
// Delete application
|
|
@@ -335,6 +424,12 @@ db.command("list").description("List all databases").action(dbListCommand);
|
|
|
335
424
|
db.command("get <uuid>")
|
|
336
425
|
.description("Get database details")
|
|
337
426
|
.action(dbGetCommand);
|
|
427
|
+
db.command("update <uuid>")
|
|
428
|
+
.description("Update database configuration")
|
|
429
|
+
.option("--public-port <port>", "Publish port (e.g., 127.0.0.1:5432 or 5432)")
|
|
430
|
+
.option("--is-public", "Make database publicly accessible")
|
|
431
|
+
.option("--no-is-public", "Make database private")
|
|
432
|
+
.action((uuid, options) => dbUpdateCommand(uuid, options));
|
|
338
433
|
db.command("create <type>")
|
|
339
434
|
.description(
|
|
340
435
|
"Create database (postgresql, mysql, mariadb, mongodb, redis, keydb, clickhouse, dragonfly)",
|
|
@@ -479,11 +574,43 @@ program
|
|
|
479
574
|
.description("Analyze a failed deployment (extract errors, suggest fixes)")
|
|
480
575
|
.action(analyzeDeployCommand);
|
|
481
576
|
|
|
482
|
-
//
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
577
|
+
// ─── Volumes subcommands ──────────────────────────────────────────────────────
|
|
578
|
+
|
|
579
|
+
const volumes = program.command("volumes").description("Manage volumes for docker-compose apps");
|
|
580
|
+
volumes
|
|
581
|
+
.command("list <uuid>")
|
|
582
|
+
.description("List volumes for an application")
|
|
583
|
+
.option("--service <name>", "Service name (for multi-service compose)")
|
|
584
|
+
.action((uuid, options) => volumesListCommand(uuid, options));
|
|
585
|
+
volumes
|
|
586
|
+
.command("add <uuid>")
|
|
587
|
+
.description("Add a bind mount volume")
|
|
588
|
+
.requiredOption("--source <path>", "Source path on host")
|
|
589
|
+
.requiredOption("--target <path>", "Target path in container")
|
|
590
|
+
.option("--service <name>", "Service name (required for multi-service compose)")
|
|
591
|
+
.option("--no-restart", "Skip automatic redeploy after adding volume")
|
|
592
|
+
.action((uuid, options) => volumesAddCommand(uuid, options));
|
|
593
|
+
volumes
|
|
594
|
+
.command("remove <uuid>")
|
|
595
|
+
.description("Remove a volume by target path")
|
|
596
|
+
.requiredOption("--target <path>", "Target path in container to remove")
|
|
597
|
+
.option("--service <name>", "Service name (required for multi-service compose)")
|
|
598
|
+
.option("--no-restart", "Skip automatic redeploy after removing volume")
|
|
599
|
+
.action((uuid, options) => volumesRemoveCommand(uuid, options));
|
|
600
|
+
volumes.action(() => volumes.help());
|
|
601
|
+
|
|
602
|
+
// Show help by default (or interactive menu if no args)
|
|
603
|
+
program.action(async () => {
|
|
604
|
+
// If called without arguments, show interactive menu
|
|
605
|
+
if (process.argv.length <= 2) {
|
|
606
|
+
const { mainMenu } = await import("./commands/main-menu.js");
|
|
607
|
+
await mainMenu();
|
|
608
|
+
} else {
|
|
609
|
+
// Show help if called with unknown command
|
|
610
|
+
console.log(chalk.cyan("Coolify MCP CLI v0.8.0"));
|
|
611
|
+
console.log(chalk.gray("Manage Coolify deployments from the command line\n"));
|
|
612
|
+
program.help();
|
|
613
|
+
}
|
|
487
614
|
});
|
|
488
615
|
|
|
489
616
|
program.parse();
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Name-to-UUID resolver for CLI.
|
|
3
|
+
*
|
|
4
|
+
* Allows users to reference Coolify resources by friendly name instead
|
|
5
|
+
* of UUID. Caches API responses in-memory during the CLI session.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { isOk } from "@mks2508/no-throw";
|
|
11
|
+
import { getCoolifyService } from "../coolify/index.js";
|
|
12
|
+
import type { ICoolifyApplication } from "../coolify/types.js";
|
|
13
|
+
import type { ICoolifyDatabase } from "../coolify/types.js";
|
|
14
|
+
import type { ICoolifyProject } from "../coolify/types.js";
|
|
15
|
+
import type { ICoolifyService as ICoolifyServiceType } from "../coolify/types.js";
|
|
16
|
+
|
|
17
|
+
/** In-memory cache for API responses during a single CLI session. */
|
|
18
|
+
const cache = {
|
|
19
|
+
apps: null as ICoolifyApplication[] | null,
|
|
20
|
+
databases: null as ICoolifyDatabase[] | null,
|
|
21
|
+
services: null as ICoolifyServiceType[] | null,
|
|
22
|
+
projects: null as ICoolifyProject[] | null,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Checks if a string looks like a Coolify UUID.
|
|
27
|
+
*
|
|
28
|
+
* Coolify UUIDs are lowercase alphanumeric strings, typically 20-30 chars.
|
|
29
|
+
*
|
|
30
|
+
* @param value - The string to check
|
|
31
|
+
* @returns True if the string looks like a UUID
|
|
32
|
+
*/
|
|
33
|
+
function looksLikeUuid(value: string): boolean {
|
|
34
|
+
return /^[a-z0-9]{16,40}$/.test(value);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Fetches and caches the list of applications from Coolify API.
|
|
39
|
+
*
|
|
40
|
+
* @returns Array of applications, or empty array on error
|
|
41
|
+
*/
|
|
42
|
+
async function getApps(): Promise<ICoolifyApplication[]> {
|
|
43
|
+
if (cache.apps) return cache.apps;
|
|
44
|
+
|
|
45
|
+
const coolify = getCoolifyService();
|
|
46
|
+
const initResult = await coolify.init();
|
|
47
|
+
if (isOk(initResult)) {
|
|
48
|
+
const result = await coolify.listApplications();
|
|
49
|
+
if (isOk(result)) {
|
|
50
|
+
cache.apps = result.value;
|
|
51
|
+
return cache.apps;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Fetches and caches the list of databases from Coolify API.
|
|
59
|
+
*
|
|
60
|
+
* @returns Array of databases, or empty array on error
|
|
61
|
+
*/
|
|
62
|
+
async function getDatabases(): Promise<ICoolifyDatabase[]> {
|
|
63
|
+
if (cache.databases) return cache.databases;
|
|
64
|
+
|
|
65
|
+
const coolify = getCoolifyService();
|
|
66
|
+
const initResult = await coolify.init();
|
|
67
|
+
if (isOk(initResult)) {
|
|
68
|
+
const result = await coolify.listDatabases();
|
|
69
|
+
if (isOk(result)) {
|
|
70
|
+
cache.databases = result.value;
|
|
71
|
+
return cache.databases;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Fetches and caches the list of services from Coolify API.
|
|
79
|
+
*
|
|
80
|
+
* @returns Array of services, or empty array on error
|
|
81
|
+
*/
|
|
82
|
+
async function getServices(): Promise<ICoolifyServiceType[]> {
|
|
83
|
+
if (cache.services) return cache.services;
|
|
84
|
+
|
|
85
|
+
const coolify = getCoolifyService();
|
|
86
|
+
const initResult = await coolify.init();
|
|
87
|
+
if (isOk(initResult)) {
|
|
88
|
+
const result = await coolify.listServices();
|
|
89
|
+
if (isOk(result)) {
|
|
90
|
+
cache.services = result.value;
|
|
91
|
+
return cache.services;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Resolves a name or UUID to a UUID.
|
|
99
|
+
*
|
|
100
|
+
* Accepts: UUID directly, app name, database name, or service name.
|
|
101
|
+
* Searches applications first, then databases, then services.
|
|
102
|
+
* Results are cached in-memory for the duration of the CLI session.
|
|
103
|
+
*
|
|
104
|
+
* @param nameOrUuid - A friendly name or UUID string
|
|
105
|
+
* @returns The resolved UUID, or null if not found
|
|
106
|
+
*/
|
|
107
|
+
export async function resolveNameOrUuid(
|
|
108
|
+
nameOrUuid: string,
|
|
109
|
+
): Promise<string | null> {
|
|
110
|
+
if (looksLikeUuid(nameOrUuid)) return nameOrUuid;
|
|
111
|
+
|
|
112
|
+
const query = nameOrUuid.toLowerCase();
|
|
113
|
+
|
|
114
|
+
// Search applications
|
|
115
|
+
const apps = await getApps();
|
|
116
|
+
const app = apps.find((a) => a.name?.toLowerCase() === query);
|
|
117
|
+
if (app) return app.uuid;
|
|
118
|
+
|
|
119
|
+
// Search databases
|
|
120
|
+
const databases = await getDatabases();
|
|
121
|
+
const db = databases.find((d) => d.name?.toLowerCase() === query);
|
|
122
|
+
if (db) return db.uuid;
|
|
123
|
+
|
|
124
|
+
// Search services
|
|
125
|
+
const services = await getServices();
|
|
126
|
+
const svc = services.find((s) => s.name?.toLowerCase() === query);
|
|
127
|
+
if (svc) return svc.uuid;
|
|
128
|
+
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Resolves a name or UUID specifically for applications.
|
|
134
|
+
*
|
|
135
|
+
* @param nameOrUuid - A friendly name or UUID string
|
|
136
|
+
* @returns The resolved application UUID, or null if not found
|
|
137
|
+
*/
|
|
138
|
+
export async function resolveAppNameOrUuid(
|
|
139
|
+
nameOrUuid: string,
|
|
140
|
+
): Promise<string | null> {
|
|
141
|
+
if (looksLikeUuid(nameOrUuid)) return nameOrUuid;
|
|
142
|
+
|
|
143
|
+
const query = nameOrUuid.toLowerCase();
|
|
144
|
+
const apps = await getApps();
|
|
145
|
+
const app = apps.find((a) => a.name?.toLowerCase() === query);
|
|
146
|
+
return app?.uuid ?? null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Resolves a name or UUID specifically for databases.
|
|
151
|
+
*
|
|
152
|
+
* @param nameOrUuid - A friendly name or UUID string
|
|
153
|
+
* @returns The resolved database UUID, or null if not found
|
|
154
|
+
*/
|
|
155
|
+
export async function resolveDbNameOrUuid(
|
|
156
|
+
nameOrUuid: string,
|
|
157
|
+
): Promise<string | null> {
|
|
158
|
+
if (looksLikeUuid(nameOrUuid)) return nameOrUuid;
|
|
159
|
+
|
|
160
|
+
const query = nameOrUuid.toLowerCase();
|
|
161
|
+
const databases = await getDatabases();
|
|
162
|
+
const db = databases.find((d) => d.name?.toLowerCase() === query);
|
|
163
|
+
return db?.uuid ?? null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Fetches and caches the list of projects from Coolify API.
|
|
168
|
+
*
|
|
169
|
+
* @returns Array of projects, or empty array on error
|
|
170
|
+
*/
|
|
171
|
+
async function getProjects(): Promise<ICoolifyProject[]> {
|
|
172
|
+
if (cache.projects) return cache.projects;
|
|
173
|
+
|
|
174
|
+
const coolify = getCoolifyService();
|
|
175
|
+
const initResult = await coolify.init();
|
|
176
|
+
if (isOk(initResult)) {
|
|
177
|
+
const result = await coolify.listProjects();
|
|
178
|
+
if (isOk(result)) {
|
|
179
|
+
cache.projects = result.value;
|
|
180
|
+
return cache.projects;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Resolves a name or UUID specifically for projects.
|
|
188
|
+
*
|
|
189
|
+
* @param nameOrUuid - A friendly name or UUID string
|
|
190
|
+
* @returns The resolved project UUID, or null if not found
|
|
191
|
+
*/
|
|
192
|
+
export async function resolveProjectNameOrUuid(
|
|
193
|
+
nameOrUuid: string,
|
|
194
|
+
): Promise<string | null> {
|
|
195
|
+
if (looksLikeUuid(nameOrUuid)) return nameOrUuid;
|
|
196
|
+
|
|
197
|
+
const query = nameOrUuid.toLowerCase();
|
|
198
|
+
const projects = await getProjects();
|
|
199
|
+
const project = projects.find((p) => p.name?.toLowerCase() === query);
|
|
200
|
+
return project?.uuid ?? null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Resolves a name or UUID specifically for services.
|
|
205
|
+
*
|
|
206
|
+
* @param nameOrUuid - A friendly name or UUID string
|
|
207
|
+
* @returns The resolved service UUID, or null if not found
|
|
208
|
+
*/
|
|
209
|
+
export async function resolveSvcNameOrUuid(
|
|
210
|
+
nameOrUuid: string,
|
|
211
|
+
): Promise<string | null> {
|
|
212
|
+
if (looksLikeUuid(nameOrUuid)) return nameOrUuid;
|
|
213
|
+
|
|
214
|
+
const query = nameOrUuid.toLowerCase();
|
|
215
|
+
const services = await getServices();
|
|
216
|
+
const svc = services.find((s) => s.name?.toLowerCase() === query);
|
|
217
|
+
return svc?.uuid ?? null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Clears the in-memory cache. Useful for testing or long-running sessions.
|
|
222
|
+
*/
|
|
223
|
+
export function clearResolverCache(): void {
|
|
224
|
+
cache.apps = null;
|
|
225
|
+
cache.databases = null;
|
|
226
|
+
cache.services = null;
|
|
227
|
+
cache.projects = null;
|
|
228
|
+
}
|