@mks2508/coolify-mks-cli-mcp 0.8.0 → 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.
Files changed (45) hide show
  1. package/dist/cli/coolify-state.d.ts +12 -4
  2. package/dist/cli/coolify-state.d.ts.map +1 -1
  3. package/dist/cli/index.js +8886 -7957
  4. package/dist/coolify/config.d.ts +25 -0
  5. package/dist/coolify/config.d.ts.map +1 -1
  6. package/dist/coolify/index.d.ts +118 -10
  7. package/dist/coolify/index.d.ts.map +1 -1
  8. package/dist/coolify/types.d.ts +61 -1
  9. package/dist/coolify/types.d.ts.map +1 -1
  10. package/dist/index.cjs +2267 -227
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.js +2289 -227
  13. package/dist/index.js.map +1 -1
  14. package/dist/sdk.d.ts +56 -8
  15. package/dist/sdk.d.ts.map +1 -1
  16. package/dist/server/stdio.js +253 -100
  17. package/dist/tools/definitions.d.ts.map +1 -1
  18. package/dist/tools/handlers.d.ts.map +1 -1
  19. package/dist/utils/env-parser.d.ts +24 -0
  20. package/dist/utils/env-parser.d.ts.map +1 -0
  21. package/dist/utils/format.d.ts +32 -0
  22. package/dist/utils/format.d.ts.map +1 -1
  23. package/package.json +2 -1
  24. package/src/cli/commands/create.ts +279 -37
  25. package/src/cli/commands/env.ts +348 -54
  26. package/src/cli/commands/init.ts +69 -15
  27. package/src/cli/commands/main-menu.ts +1 -1
  28. package/src/cli/commands/projects.ts +3 -3
  29. package/src/cli/commands/show.ts +39 -10
  30. package/src/cli/commands/status.ts +23 -7
  31. package/src/cli/commands/svc.ts +7 -1
  32. package/src/cli/commands/update.ts +52 -0
  33. package/src/cli/commands/volumes.ts +293 -0
  34. package/src/cli/coolify-state.ts +42 -4
  35. package/src/cli/index.ts +50 -4
  36. package/src/cli/ui/banner.ts +3 -3
  37. package/src/cli/ui/screen.ts +26 -2
  38. package/src/coolify/config.ts +75 -0
  39. package/src/coolify/index.ts +325 -106
  40. package/src/coolify/types.ts +62 -1
  41. package/src/sdk.ts +87 -39
  42. package/src/tools/definitions.ts +22 -0
  43. package/src/tools/handlers.ts +19 -0
  44. package/src/utils/env-parser.ts +45 -0
  45. package/src/utils/format.ts +178 -0
package/dist/index.js CHANGED
@@ -4,17 +4,42 @@ import { homedir } from "node:os";
4
4
  import { join } from "node:path";
5
5
 
6
6
  //#region rolldown:runtime
7
+ var __create = Object.create;
7
8
  var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
10
  var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __getProtoOf = Object.getPrototypeOf;
12
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
13
  var __esm = (fn, res) => function() {
10
14
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
15
  };
16
+ var __commonJS = (cb, mod) => function() {
17
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18
+ };
12
19
  var __export = (target, all) => {
13
20
  for (var name in all) __defProp(target, name, {
14
21
  get: all[name],
15
22
  enumerable: true
16
23
  });
17
24
  };
25
+ var __copyProps = (to, from, except, desc) => {
26
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
27
+ key = keys[i];
28
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
29
+ get: ((k) => from[k]).bind(null, key),
30
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
31
+ });
32
+ }
33
+ return to;
34
+ };
35
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
36
+ value: mod,
37
+ enumerable: true
38
+ }) : target, mod));
39
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
40
+ if (typeof require !== "undefined") return require.apply(this, arguments);
41
+ throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function.");
42
+ });
18
43
 
19
44
  //#endregion
20
45
  //#region ../../../node_modules/.bun/@mks2508+no-throw@0.1.0/node_modules/@mks2508/no-throw/dist/index.mjs
@@ -515,10 +540,10 @@ function isRunningInTerminal() {
515
540
  return Boolean(isTTY || hasTerminalEnv || isTerminalProgram);
516
541
  }
517
542
  function supportsANSI() {
518
- const env = getEnvironment();
519
- if (env === "browser") return false;
520
- if (env === "terminal") return true;
521
- if (env === "server") return checkServerANSISupport();
543
+ const env$1 = getEnvironment();
544
+ if (env$1 === "browser") return false;
545
+ if (env$1 === "terminal") return true;
546
+ if (env$1 === "server") return checkServerANSISupport();
522
547
  return false;
523
548
  }
524
549
  function checkServerANSISupport() {
@@ -527,8 +552,8 @@ function checkServerANSISupport() {
527
552
  return Boolean(supportsANSI2);
528
553
  }
529
554
  function getColorCapability() {
530
- const env = getEnvironment();
531
- if (env === "browser") return "full";
555
+ const env$1 = getEnvironment();
556
+ if (env$1 === "browser") return "full";
532
557
  if (!supportsANSI()) return "none";
533
558
  if (typeof process !== "undefined" && process.env) {
534
559
  const hasTrueColor = process.env.COLORTERM === "truecolor" || process.env.COLORTERM === "24bit";
@@ -938,7 +963,7 @@ var TerminalRenderer = class {
938
963
  /**
939
964
  * Get ANSI style codes
940
965
  */
941
- getStyleCode(styles) {
966
+ getStyleCode(styles$2) {
942
967
  const styleCodes = {
943
968
  "bold": "1",
944
969
  "dim": "2",
@@ -946,27 +971,27 @@ var TerminalRenderer = class {
946
971
  "underline": "4",
947
972
  "reset": "0"
948
973
  };
949
- const codes = styles.map((style) => styleCodes[style] || "0").join(";");
950
- return codes ? `\x1B[${codes}m` : "";
974
+ const codes$1 = styles$2.map((style) => styleCodes[style] || "0").join(";");
975
+ return codes$1 ? `\x1B[${codes$1}m` : "";
951
976
  }
952
977
  /**
953
978
  * Convert log styles to ANSI formatting
954
979
  */
955
- renderTerminal(level, message, timestamp, prefix, location, styles) {
980
+ renderTerminal(level$1, message, timestamp, prefix, location, styles$2) {
956
981
  const reset = "\x1B[0m";
957
982
  const result = {
958
983
  text: "",
959
984
  reset
960
985
  };
961
- if (styles) {
962
- result.timestamp = this.styleTimestamp(timestamp, styles.timestamp);
963
- result.level = this.styleLevel(level, styles.level);
964
- result.prefix = this.stylePrefix(prefix, styles.prefix);
965
- result.message = this.styleMessage(message, styles.message);
966
- result.location = this.styleLocation(location, styles.location);
986
+ if (styles$2) {
987
+ result.timestamp = this.styleTimestamp(timestamp, styles$2.timestamp);
988
+ result.level = this.styleLevel(level$1, styles$2.level);
989
+ result.prefix = this.stylePrefix(prefix, styles$2.prefix);
990
+ result.message = this.styleMessage(message, styles$2.message);
991
+ result.location = this.styleLocation(location, styles$2.location);
967
992
  } else {
968
993
  result.timestamp = this.styleTimestamp(timestamp);
969
- result.level = this.styleLevel(level);
994
+ result.level = this.styleLevel(level$1);
970
995
  result.prefix = this.stylePrefix(prefix);
971
996
  result.message = this.styleMessage(message);
972
997
  result.location = this.styleLocation(location);
@@ -992,9 +1017,9 @@ var TerminalRenderer = class {
992
1017
  /**
993
1018
  * Style level with appropriate colors and formatting
994
1019
  */
995
- styleLevel(level, style) {
1020
+ styleLevel(level$1, style) {
996
1021
  if (!style?.show) return "";
997
- const levelText = this.getLevelText(level);
1022
+ const levelText = this.getLevelText(level$1);
998
1023
  const levelColors = {
999
1024
  "debug": "magenta",
1000
1025
  "info": "blue",
@@ -1003,7 +1028,7 @@ var TerminalRenderer = class {
1003
1028
  "critical": "red"
1004
1029
  };
1005
1030
  if (this.colorCapability === "none") return `[${levelText}]`;
1006
- const color = levelColors[level] || "white";
1031
+ const color = levelColors[level$1] || "white";
1007
1032
  const colorCode = this.getColorCode(color);
1008
1033
  const boldStyle = this.getStyleCode(["bold"]);
1009
1034
  if (style?.style === "compact") return `${colorCode}[${levelText}]`;
@@ -1042,7 +1067,7 @@ var TerminalRenderer = class {
1042
1067
  /**
1043
1068
  * Get text representation of log level
1044
1069
  */
1045
- getLevelText(level) {
1070
+ getLevelText(level$1) {
1046
1071
  const levelMap = {
1047
1072
  "debug": "DEBUG",
1048
1073
  "info": "INFO",
@@ -1050,12 +1075,12 @@ var TerminalRenderer = class {
1050
1075
  "error": "ERROR",
1051
1076
  "critical": "CRITICAL"
1052
1077
  };
1053
- return levelMap[level] || String(level).toUpperCase();
1078
+ return levelMap[level$1] || String(level$1).toUpperCase();
1054
1079
  }
1055
1080
  /**
1056
1081
  * Create cyberpunk-style ANSI rendering with truecolor support
1057
1082
  */
1058
- renderCyberpunk(level, message, timestamp, prefix, location) {
1083
+ renderCyberpunk(level$1, message, timestamp, prefix, location) {
1059
1084
  const reset = ANSI.reset;
1060
1085
  const cyberpunkColors = {
1061
1086
  "debug": "#ff00ff",
@@ -1066,10 +1091,10 @@ var TerminalRenderer = class {
1066
1091
  };
1067
1092
  const parts = [];
1068
1093
  if (timestamp) parts.push(`${ANSI.dim}${timestamp}${reset}`);
1069
- const levelColor = this.getColorCode(cyberpunkColors[level] || "#ffffff");
1094
+ const levelColor = this.getColorCode(cyberpunkColors[level$1] || "#ffffff");
1070
1095
  const bgBlack = ANSI.bg.black;
1071
- const bold = level === "critical" ? ANSI.bold : "";
1072
- parts.push(`${bgBlack}${levelColor}${bold} ${this.getLevelText(level)} ${reset}`);
1096
+ const bold = level$1 === "critical" ? ANSI.bold : "";
1097
+ parts.push(`${bgBlack}${levelColor}${bold} ${this.getLevelText(level$1)} ${reset}`);
1073
1098
  if (prefix) {
1074
1099
  const cyanColor = this.getColorCode("#00ffff");
1075
1100
  parts.push(`${bgBlack}${cyanColor}[${prefix.toUpperCase()}]${reset}`);
@@ -1084,7 +1109,7 @@ var TerminalRenderer = class {
1084
1109
  /**
1085
1110
  * Create minimal ANSI rendering with truecolor support
1086
1111
  */
1087
- renderMinimal(level, message, timestamp, prefix) {
1112
+ renderMinimal(level$1, message, timestamp, prefix) {
1088
1113
  const reset = ANSI.reset;
1089
1114
  const minimalColors = {
1090
1115
  "debug": "#c678dd",
@@ -1095,9 +1120,9 @@ var TerminalRenderer = class {
1095
1120
  };
1096
1121
  const parts = [];
1097
1122
  if (timestamp) parts.push(`${ANSI.dim}${timestamp}${reset}`);
1098
- const levelColor = this.getColorCode(minimalColors[level] || "#abb2bf");
1099
- const bold = level === "critical" ? ANSI.bold : "";
1100
- parts.push(`${levelColor}${bold}${this.getLevelText(level)}:${reset}`);
1123
+ const levelColor = this.getColorCode(minimalColors[level$1] || "#abb2bf");
1124
+ const bold = level$1 === "critical" ? ANSI.bold : "";
1125
+ parts.push(`${levelColor}${bold}${this.getLevelText(level$1)}:${reset}`);
1101
1126
  if (prefix) {
1102
1127
  const cyanColor = this.getColorCode("#56b6c2");
1103
1128
  parts.push(`${cyanColor}[${prefix.toUpperCase()}]${reset}`);
@@ -1111,7 +1136,7 @@ var TerminalRenderer = class {
1111
1136
  /**
1112
1137
  * Get chalk-like interface for log level with truecolor support
1113
1138
  */
1114
- getChalkForLevel(level) {
1139
+ getChalkForLevel(level$1) {
1115
1140
  const levelColors = {
1116
1141
  "debug": "#c678dd",
1117
1142
  "info": "#61afef",
@@ -1122,7 +1147,7 @@ var TerminalRenderer = class {
1122
1147
  const reset = ANSI.reset;
1123
1148
  return {
1124
1149
  color: (text) => {
1125
- const color = levelColors[level] || "#abb2bf";
1150
+ const color = levelColors[level$1] || "#abb2bf";
1126
1151
  const colorCode = this.getColorCode(color);
1127
1152
  return `${colorCode}${text}${reset}`;
1128
1153
  },
@@ -1157,28 +1182,28 @@ var CSS2ANSIAdapter = class {
1157
1182
  /**
1158
1183
  * Convert LogStyles to ANSIStyle for terminal rendering
1159
1184
  */
1160
- adaptStyles(level, message, timestamp, prefix, location, styles, presetName) {
1185
+ adaptStyles(level$1, message, timestamp, prefix, location, styles$2, presetName) {
1161
1186
  if (presetName) switch (presetName) {
1162
- case "cyberpunk": return this.renderer.renderCyberpunk(level, message, timestamp, prefix, location);
1163
- case "minimal": return this.renderer.renderMinimal(level, message, timestamp, prefix);
1164
- case "production": return this.adaptProductionStyles(level, message, timestamp, prefix, location, styles);
1165
- case "debug": return this.adaptDebugStyles(level, message, timestamp, prefix, location, styles);
1166
- case "glassmorphism": return this.adaptGlassmorphismStyles(level, message, timestamp, prefix, location, styles);
1187
+ case "cyberpunk": return this.renderer.renderCyberpunk(level$1, message, timestamp, prefix, location);
1188
+ case "minimal": return this.renderer.renderMinimal(level$1, message, timestamp, prefix);
1189
+ case "production": return this.adaptProductionStyles(level$1, message, timestamp, prefix, location, styles$2);
1190
+ case "debug": return this.adaptDebugStyles(level$1, message, timestamp, prefix, location, styles$2);
1191
+ case "glassmorphism": return this.adaptGlassmorphismStyles(level$1, message, timestamp, prefix, location, styles$2);
1167
1192
  }
1168
- return this.renderer.renderTerminal(level, message, timestamp, prefix, location, styles);
1193
+ return this.renderer.renderTerminal(level$1, message, timestamp, prefix, location, styles$2);
1169
1194
  }
1170
1195
  /**
1171
1196
  * Adapt production preset for terminal
1172
1197
  */
1173
- adaptProductionStyles(level, message, timestamp, prefix, location, styles) {
1198
+ adaptProductionStyles(level$1, message, timestamp, prefix, location, styles$2) {
1174
1199
  const reset = "\x1B[0m";
1175
- const levelChalk = this.renderer.getChalkForLevel(level);
1200
+ const levelChalk = this.renderer.getChalkForLevel(level$1);
1176
1201
  const parts = [];
1177
- if (timestamp && styles?.timestamp?.show) parts.push(levelChalk.dim(timestamp));
1178
- if (styles?.level?.show) parts.push(levelChalk.color(`[${this.renderer["getLevelText"](level)}]`));
1179
- if (prefix && styles?.prefix?.show) parts.push(levelChalk.dim(`[${prefix}]`));
1180
- if (message && styles?.message?.show) parts.push(levelChalk.reset(message));
1181
- if (location && styles?.location?.show) parts.push(levelChalk.dim(`(${location})`));
1202
+ if (timestamp && styles$2?.timestamp?.show) parts.push(levelChalk.dim(timestamp));
1203
+ if (styles$2?.level?.show) parts.push(levelChalk.color(`[${this.renderer["getLevelText"](level$1)}]`));
1204
+ if (prefix && styles$2?.prefix?.show) parts.push(levelChalk.dim(`[${prefix}]`));
1205
+ if (message && styles$2?.message?.show) parts.push(levelChalk.reset(message));
1206
+ if (location && styles$2?.location?.show) parts.push(levelChalk.dim(`(${location})`));
1182
1207
  return {
1183
1208
  text: parts.join(" ") + reset,
1184
1209
  reset
@@ -1187,17 +1212,17 @@ var CSS2ANSIAdapter = class {
1187
1212
  /**
1188
1213
  * Adapt debug preset for terminal
1189
1214
  */
1190
- adaptDebugStyles(level, message, timestamp, prefix, location, styles) {
1215
+ adaptDebugStyles(level$1, message, timestamp, prefix, location, styles$2) {
1191
1216
  const reset = "\x1B[0m";
1192
- const levelChalk = this.renderer.getChalkForLevel(level);
1217
+ const levelChalk = this.renderer.getChalkForLevel(level$1);
1193
1218
  const parts = [];
1194
- if (timestamp && styles?.timestamp?.show) parts.push(levelChalk.dim(timestamp));
1195
- if (styles?.level?.show) if (styles?.level?.style === "compact") parts.push(levelChalk.color(`[${this.renderer["getLevelText"](level)}]`));
1196
- else parts.push(levelChalk.bold(`[${this.renderer["getLevelText"](level)}]`));
1197
- if (prefix && styles?.prefix?.show) if (styles?.prefix?.style === "compact") parts.push(levelChalk.cyan.dim(`[${prefix}]`));
1219
+ if (timestamp && styles$2?.timestamp?.show) parts.push(levelChalk.dim(timestamp));
1220
+ if (styles$2?.level?.show) if (styles$2?.level?.style === "compact") parts.push(levelChalk.color(`[${this.renderer["getLevelText"](level$1)}]`));
1221
+ else parts.push(levelChalk.bold(`[${this.renderer["getLevelText"](level$1)}]`));
1222
+ if (prefix && styles$2?.prefix?.show) if (styles$2?.prefix?.style === "compact") parts.push(levelChalk.cyan.dim(`[${prefix}]`));
1198
1223
  else parts.push(levelChalk.cyan.bold(`[${prefix}]`));
1199
- if (message && styles?.message?.show) parts.push(levelChalk.reset(message));
1200
- if (location && styles?.location?.show) if (styles?.location?.style === "clickable") parts.push(levelChalk.dim(`${location} (clickable)`));
1224
+ if (message && styles$2?.message?.show) parts.push(levelChalk.reset(message));
1225
+ if (location && styles$2?.location?.show) if (styles$2?.location?.style === "clickable") parts.push(levelChalk.dim(`${location} (clickable)`));
1201
1226
  else parts.push(levelChalk.dim(`(${location})`));
1202
1227
  return {
1203
1228
  text: parts.join(" ") + reset,
@@ -1207,15 +1232,15 @@ var CSS2ANSIAdapter = class {
1207
1232
  /**
1208
1233
  * Adapt glassmorphism preset for terminal
1209
1234
  */
1210
- adaptGlassmorphismStyles(level, message, timestamp, prefix, location, styles) {
1235
+ adaptGlassmorphismStyles(level$1, message, timestamp, prefix, location, styles$2) {
1211
1236
  const reset = "\x1B[0m";
1212
- const levelChalk = this.renderer.getChalkForLevel(level);
1237
+ const levelChalk = this.renderer.getChalkForLevel(level$1);
1213
1238
  const parts = [];
1214
- if (timestamp && styles?.timestamp?.show) parts.push(levelChalk.dim(timestamp));
1215
- if (styles?.level?.show) parts.push(levelChalk.bgGray(` ${this.renderer["getLevelText"](level)} `));
1216
- if (prefix && styles?.prefix?.show) parts.push(levelChalk.bgBlue(`[${prefix}]`));
1217
- if (message && styles?.message?.show) parts.push(levelChalk.reset(message));
1218
- if (location && styles?.location?.show) parts.push(levelChalk.dim(`(${location})`));
1239
+ if (timestamp && styles$2?.timestamp?.show) parts.push(levelChalk.dim(timestamp));
1240
+ if (styles$2?.level?.show) parts.push(levelChalk.bgGray(` ${this.renderer["getLevelText"](level$1)} `));
1241
+ if (prefix && styles$2?.prefix?.show) parts.push(levelChalk.bgBlue(`[${prefix}]`));
1242
+ if (message && styles$2?.message?.show) parts.push(levelChalk.reset(message));
1243
+ if (location && styles$2?.location?.show) parts.push(levelChalk.dim(`(${location})`));
1219
1244
  return {
1220
1245
  text: parts.join(" ") + reset,
1221
1246
  reset
@@ -1266,9 +1291,9 @@ var CSS2ANSIAdapter = class {
1266
1291
  /**
1267
1292
  * Check if a style should be rendered in terminal
1268
1293
  */
1269
- shouldRenderStyle(styleType, styles) {
1270
- if (!styles) return true;
1271
- const styleConfig = styles[styleType];
1294
+ shouldRenderStyle(styleType, styles$2) {
1295
+ if (!styles$2) return true;
1296
+ const styleConfig = styles$2[styleType];
1272
1297
  return styleConfig?.show !== false;
1273
1298
  }
1274
1299
  /**
@@ -1279,8 +1304,8 @@ var CSS2ANSIAdapter = class {
1279
1304
  }
1280
1305
  };
1281
1306
  const css2ansiAdapter = new CSS2ANSIAdapter();
1282
- function adaptToTerminal(level, message, timestamp, prefix, location, styles, presetName) {
1283
- return css2ansiAdapter.adaptStyles(level, message, timestamp, prefix, location, styles, presetName);
1307
+ function adaptToTerminal(level$1, message, timestamp, prefix, location, styles$2, presetName) {
1308
+ return css2ansiAdapter.adaptStyles(level$1, message, timestamp, prefix, location, styles$2, presetName);
1284
1309
  }
1285
1310
  function detectDevToolsTheme() {
1286
1311
  try {
@@ -1292,9 +1317,9 @@ function detectDevToolsTheme() {
1292
1317
  return "light";
1293
1318
  }
1294
1319
  }
1295
- function getAdaptiveColor(colors, theme) {
1320
+ function getAdaptiveColor(colors$2, theme) {
1296
1321
  const currentTheme = theme ?? detectDevToolsTheme();
1297
- return colors[currentTheme];
1322
+ return colors$2[currentTheme];
1298
1323
  }
1299
1324
  function setupThemeChangeListener(callback) {
1300
1325
  try {
@@ -1316,11 +1341,11 @@ function setupThemeChangeListener(callback) {
1316
1341
  return null;
1317
1342
  }
1318
1343
  }
1319
- function createStyledOutput(level, levelStyles, prefix, message, stackInfo, autoDetectTheme = true, presetStyles, presetName) {
1320
- const levelConfig = levelStyles[level];
1344
+ function createStyledOutput(level$1, levelStyles, prefix, message, stackInfo, autoDetectTheme = true, presetStyles, presetName) {
1345
+ const levelConfig = levelStyles[level$1];
1321
1346
  const timestamp = formatTimestamp();
1322
1347
  const environment = getEnvironment();
1323
- if (environment !== "browser" && supportsANSI()) return createTerminalOutput(level, message, timestamp, prefix, stackInfo, presetStyles, presetName);
1348
+ if (environment !== "browser" && supportsANSI()) return createTerminalOutput(level$1, message, timestamp, prefix, stackInfo, presetStyles, presetName);
1324
1349
  const currentTheme = autoDetectTheme ? detectDevToolsTheme() : "light";
1325
1350
  const timestampStyle = new StyleBuilder().color(getAdaptiveColor(ADAPTIVE_COLORS.timestamp, currentTheme)).size("11px").font("Monaco, Consolas, monospace").build();
1326
1351
  const levelStyle = new StyleBuilder().bg(levelConfig.background).color(levelConfig.color).border(levelConfig.border).shadow(levelConfig.shadow).padding("2px 8px").rounded("4px").bold().font("Monaco, Consolas, monospace").size("12px").build();
@@ -1328,18 +1353,18 @@ function createStyledOutput(level, levelStyles, prefix, message, stackInfo, auto
1328
1353
  const messageStyle = new StyleBuilder().color(getAdaptiveColor(ADAPTIVE_COLORS.messageText, currentTheme)).font("system-ui, -apple-system, sans-serif").size("14px").build();
1329
1354
  const locationStyle = new StyleBuilder().color(getAdaptiveColor(ADAPTIVE_COLORS.location, currentTheme)).size("11px").font("Monaco, Consolas, monospace").build();
1330
1355
  let format = `%c${timestamp.slice(11, 23)} %c${levelConfig.emoji} ${levelConfig.label}`;
1331
- const styles = [timestampStyle, levelStyle];
1356
+ const styles$2 = [timestampStyle, levelStyle];
1332
1357
  if (prefix) {
1333
1358
  format += ` %c${prefix}`;
1334
- styles.push(prefixStyle);
1359
+ styles$2.push(prefixStyle);
1335
1360
  }
1336
1361
  format += ` %c${message}`;
1337
- styles.push(messageStyle);
1362
+ styles$2.push(messageStyle);
1338
1363
  if (stackInfo) {
1339
1364
  format += ` %c(${stackInfo.file}:${stackInfo.line}:${stackInfo.column})`;
1340
- styles.push(locationStyle);
1365
+ styles$2.push(locationStyle);
1341
1366
  }
1342
- return [format, ...styles];
1367
+ return [format, ...styles$2];
1343
1368
  }
1344
1369
  function generateLogId() {
1345
1370
  return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
@@ -1362,9 +1387,9 @@ function safeStringify(obj, _maxDepth = 3) {
1362
1387
  return String(obj);
1363
1388
  }
1364
1389
  }
1365
- function createTerminalOutput(level, message, timestamp, prefix, stackInfo, presetStyles, presetName) {
1390
+ function createTerminalOutput(level$1, message, timestamp, prefix, stackInfo, presetStyles, presetName) {
1366
1391
  const location = stackInfo ? `${stackInfo.file}:${stackInfo.line}:${stackInfo.column}` : void 0;
1367
- const ansiStyle = adaptToTerminal(level, message, timestamp, prefix, location, presetStyles, presetName);
1392
+ const ansiStyle = adaptToTerminal(level$1, message, timestamp, prefix, location, presetStyles, presetName);
1368
1393
  return [ansiStyle.text];
1369
1394
  }
1370
1395
  const isNode = typeof process !== "undefined" && process.versions && process.versions.node;
@@ -1401,9 +1426,9 @@ var SerializerRegistry = class {
1401
1426
  pattern: regex.source,
1402
1427
  flags: regex.flags
1403
1428
  }), 90);
1404
- this.add(Map, (map, ctx) => {
1429
+ this.add(Map, (map$1, ctx) => {
1405
1430
  const obj = {};
1406
- map.forEach((value, key) => {
1431
+ map$1.forEach((value, key) => {
1407
1432
  const keyStr = typeof key === "object" ? JSON.stringify(key) : String(key);
1408
1433
  obj[keyStr] = this.serializeInternal(value, {
1409
1434
  ...ctx,
@@ -1631,7 +1656,7 @@ var TransportManager = class {
1631
1656
  }
1632
1657
  add(target) {
1633
1658
  const id = generateTransportId();
1634
- const level = target.level || this.defaultLevel;
1659
+ const level$1 = target.level || this.defaultLevel;
1635
1660
  let transport;
1636
1661
  if (typeof target.target === "string") throw new Error(`String transport targets not supported. Use inline transport object.`);
1637
1662
  else transport = target.target;
@@ -1639,8 +1664,8 @@ var TransportManager = class {
1639
1664
  id,
1640
1665
  transport,
1641
1666
  options: target.options || {},
1642
- level,
1643
- levelValue: LOG_LEVELS[level]
1667
+ level: level$1,
1668
+ levelValue: LOG_LEVELS[level$1]
1644
1669
  };
1645
1670
  this.transports.set(id, entry);
1646
1671
  return id;
@@ -2498,10 +2523,10 @@ var LogStyleBuilder = class {
2498
2523
  /**
2499
2524
  * Internal method to update part configuration
2500
2525
  */
2501
- _updatePartConfig(part, styles) {
2526
+ _updatePartConfig(part, styles$2) {
2502
2527
  if (part === "layout" || part === "backdrop" || part === "transparency") return;
2503
2528
  if (!this.logStyles[part]) this.logStyles[part] = {};
2504
- this.logStyles[part].style = styles;
2529
+ this.logStyles[part].style = styles$2;
2505
2530
  }
2506
2531
  };
2507
2532
  var PartStyleBuilderProxy = class {
@@ -2527,8 +2552,8 @@ var PartStyleBuilderProxy = class {
2527
2552
  * Helper to apply styles to the parent builder
2528
2553
  */
2529
2554
  applyStyles(styler) {
2530
- const styles = styler.build();
2531
- this.parentBuilder._updatePartConfig(this.partName, styles);
2555
+ const styles$2 = styler.build();
2556
+ this.parentBuilder._updatePartConfig(this.partName, styles$2);
2532
2557
  return this;
2533
2558
  }
2534
2559
  };
@@ -3072,11 +3097,11 @@ var ExportLogHandler = class {
3072
3097
  /**
3073
3098
  * Handle incoming log and store in buffer
3074
3099
  */
3075
- handle(level, message, args, metadata) {
3100
+ handle(level$1, message, args, metadata) {
3076
3101
  const entry = {
3077
3102
  id: generateLogId(),
3078
3103
  timestamp: metadata.timestamp,
3079
- level,
3104
+ level: level$1,
3080
3105
  prefix: metadata.prefix,
3081
3106
  message,
3082
3107
  args,
@@ -3236,15 +3261,15 @@ var ExportLogHandler = class {
3236
3261
  }
3237
3262
  if (options.groupBy === "level") {
3238
3263
  const grouped = logs.reduce((acc, entry) => {
3239
- const level = entry.level;
3240
- if (!acc[level]) acc[level] = [];
3241
- const levelArray = acc[level];
3264
+ const level$1 = entry.level;
3265
+ if (!acc[level$1]) acc[level$1] = [];
3266
+ const levelArray = acc[level$1];
3242
3267
  if (levelArray) levelArray.push(entry);
3243
3268
  return acc;
3244
3269
  }, {});
3245
- Object.entries(grouped).forEach(([level, entries]) => {
3246
- const emoji = this.getLevelEmoji(level);
3247
- content += `## ${emoji} ${level.toUpperCase()} (${entries.length})
3270
+ Object.entries(grouped).forEach(([level$1, entries]) => {
3271
+ const emoji = this.getLevelEmoji(level$1);
3272
+ content += `## ${emoji} ${level$1.toUpperCase()} (${entries.length})
3248
3273
 
3249
3274
  `;
3250
3275
  entries.forEach((entry) => {
@@ -3275,10 +3300,10 @@ var ExportLogHandler = class {
3275
3300
  exportPlain(logs, options) {
3276
3301
  return logs.map((entry) => {
3277
3302
  const time = formatDisplayTime(new Date(entry.timestamp), options.minimal ? "time-only" : "short");
3278
- const level = entry.level.toUpperCase().padEnd(8);
3303
+ const level$1 = entry.level.toUpperCase().padEnd(8);
3279
3304
  const prefix = entry.prefix ? `[${entry.prefix}] ` : "";
3280
3305
  const location = !options.minimal && entry.location ? ` (${entry.location.file}:${entry.location.line})` : "";
3281
- return `${time} ${level} ${prefix}${entry.message}${location}`;
3306
+ return `${time} ${level$1} ${prefix}${entry.message}${location}`;
3282
3307
  }).join("\n");
3283
3308
  }
3284
3309
  /**
@@ -3340,7 +3365,7 @@ var ExportLogHandler = class {
3340
3365
  /**
3341
3366
  * Get emoji for log level
3342
3367
  */
3343
- getLevelEmoji(level) {
3368
+ getLevelEmoji(level$1) {
3344
3369
  const emojis = {
3345
3370
  debug: "🐞",
3346
3371
  info: "ℹ️",
@@ -3348,7 +3373,7 @@ var ExportLogHandler = class {
3348
3373
  error: "❌",
3349
3374
  critical: "🔥"
3350
3375
  };
3351
- return emojis[level] || "";
3376
+ return emojis[level$1] || "";
3352
3377
  }
3353
3378
  /**
3354
3379
  * Main export function
@@ -4413,8 +4438,8 @@ var Logger = class {
4413
4438
  *
4414
4439
  * @since 0.3.0
4415
4440
  */
4416
- setVerbosity(level) {
4417
- this.config.verbosity = level;
4441
+ setVerbosity(level$1) {
4442
+ this.config.verbosity = level$1;
4418
4443
  }
4419
4444
  /**
4420
4445
  * Establece el tema del logger
@@ -4930,7 +4955,7 @@ var Logger = class {
4930
4955
  * @param {LogLevel} level - Nivel de log a verificar
4931
4956
  * @returns {boolean} True si debe mostrarse, false si no
4932
4957
  */
4933
- shouldLog(level) {
4958
+ shouldLog(level$1) {
4934
4959
  if (this.config.verbosity === "silent") return false;
4935
4960
  const levels = {
4936
4961
  debug: 0,
@@ -4939,7 +4964,7 @@ var Logger = class {
4939
4964
  error: 3,
4940
4965
  critical: 4
4941
4966
  };
4942
- return levels[level] >= levels[this.config.verbosity];
4967
+ return levels[level$1] >= levels[this.config.verbosity];
4943
4968
  }
4944
4969
  /**
4945
4970
  * Obtiene el prefijo efectivo (global + scope)
@@ -4956,8 +4981,8 @@ var Logger = class {
4956
4981
  * @param {LogLevel} level - Nivel del log
4957
4982
  * @param {...any} args - Argumentos a loggear
4958
4983
  */
4959
- log(level, ...args) {
4960
- if (!this.shouldLog(level)) return;
4984
+ log(level$1, ...args) {
4985
+ if (!this.shouldLog(level$1)) return;
4961
4986
  const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
4962
4987
  const prefix = this.getEffectivePrefix();
4963
4988
  const timestamp = formatTimestamp();
@@ -4969,7 +4994,7 @@ var Logger = class {
4969
4994
  }
4970
4995
  const additionalArgs = serializedArgs.slice(1);
4971
4996
  let hookEntry = {
4972
- level,
4997
+ level: level$1,
4973
4998
  message,
4974
4999
  args: serializedArgs,
4975
5000
  timestamp,
@@ -4979,20 +5004,20 @@ var Logger = class {
4979
5004
  this.hookManager.emit("beforeLog", hookEntry).then((processed) => {
4980
5005
  message = processed.message;
4981
5006
  }).catch(() => {});
4982
- const [format, ...styles2] = createStyledOutput(level, LEVEL_STYLES, prefix, message, this.displaySettings.showLocation ? stackInfo : null, this.config.autoDetectTheme, this._activePreset, this._activePresetName);
5007
+ const [format, ...styles2] = createStyledOutput(level$1, LEVEL_STYLES, prefix, message, this.displaySettings.showLocation ? stackInfo : null, this.config.autoDetectTheme, this._activePreset, this._activePresetName);
4983
5008
  const groupIndent = " ".repeat(this.groupDepth);
4984
5009
  const finalFormat = groupIndent + format;
4985
- this.writeOutput(finalFormat, level, styles2, additionalArgs);
5010
+ this.writeOutput(finalFormat, level$1, styles2, additionalArgs);
4986
5011
  if (this.exportHandler) this.exportHandler.setGroupInfo(this.groupDepth);
4987
5012
  const metadata = {
4988
5013
  timestamp,
4989
- level,
5014
+ level: level$1,
4990
5015
  prefix,
4991
5016
  stackInfo: stackInfo ? stackInfo : void 0
4992
5017
  };
4993
5018
  this.handlers.forEach((handler) => {
4994
5019
  try {
4995
- handler.handle(level, message, serializedArgs, metadata);
5020
+ handler.handle(level$1, message, serializedArgs, metadata);
4996
5021
  } catch (error2) {
4997
5022
  console.error("Log handler failed:", error2);
4998
5023
  }
@@ -5006,8 +5031,8 @@ var Logger = class {
5006
5031
  critical: 4
5007
5032
  };
5008
5033
  const record = {
5009
- level,
5010
- levelValue: levelValues[level],
5034
+ level: level$1,
5035
+ levelValue: levelValues[level$1],
5011
5036
  time: Date.now(),
5012
5037
  msg: message,
5013
5038
  prefix,
@@ -5022,14 +5047,14 @@ var Logger = class {
5022
5047
  }
5023
5048
  this.hookManager.emit("afterLog", hookEntry).catch(() => {});
5024
5049
  }
5025
- logWithBindings(bindings, level, ...args) {
5026
- if (!this.shouldLog(level)) return;
5050
+ logWithBindings(bindings, level$1, ...args) {
5051
+ if (!this.shouldLog(level$1)) return;
5027
5052
  let prefix = "";
5028
5053
  const colorCapability = getColorCapability();
5029
5054
  if (bindings.badges?.length) prefix += bindings.badges.map((b) => formatBadge(b, "pill", colorCapability, "#00ff88")).join(" ") + " ";
5030
5055
  if (bindings.scope) prefix += formatBadge(bindings.scope, "pill", colorCapability, "#00ffff") + " ";
5031
5056
  if (prefix && args.length > 0) args[0] = prefix + String(args[0]);
5032
- this.log(level, ...args);
5057
+ this.log(level$1, ...args);
5033
5058
  }
5034
5059
  debug(...args) {
5035
5060
  this.log("debug", ...args);
@@ -5389,12 +5414,12 @@ var Logger = class {
5389
5414
  * @param {any[]} additionalArgs - Additional arguments to log
5390
5415
  * @since 4.0.0
5391
5416
  */
5392
- writeOutput(message, level, styles2, additionalArgs) {
5417
+ writeOutput(message, level$1, styles2, additionalArgs) {
5393
5418
  const mode = this.config.outputMode ?? "console";
5394
5419
  if (mode === "silent") return;
5395
5420
  if (mode === "custom" && this.config.outputWriter) {
5396
5421
  const fullMessage = additionalArgs.length > 0 ? `${message} ${additionalArgs.map((a) => String(a)).join(" ")}` : message;
5397
- this.config.outputWriter.write(fullMessage, level, styles2);
5422
+ this.config.outputWriter.write(fullMessage, level$1, styles2);
5398
5423
  return;
5399
5424
  }
5400
5425
  if (additionalArgs.length > 0) console.log(message, ...styles2, ...additionalArgs);
@@ -5559,6 +5584,7 @@ async function loadConfig() {
5559
5584
  return err(error instanceof Error ? error : new Error(String(error)));
5560
5585
  }
5561
5586
  }
5587
+ const SETTINGS_CACHE_FILE = join(CONFIG_DIR, "app-settings-cache.json");
5562
5588
 
5563
5589
  //#endregion
5564
5590
  //#region src/coolify/index.ts
@@ -5654,12 +5680,20 @@ var CoolifyService = class {
5654
5680
  let data;
5655
5681
  try {
5656
5682
  data = text ? JSON.parse(text) : void 0;
5657
- } catch {
5683
+ } catch (parseErr) {
5684
+ const preview = text ? text.slice(0, 200) : "(empty body)";
5685
+ const method = options.method ?? "GET";
5686
+ log.warn(`Failed to parse JSON response from ${method} ${endpoint} (status ${response.status}): ${parseErr instanceof Error ? parseErr.message : String(parseErr)}. Body preview: ${preview}`);
5658
5687
  if (!response.ok) return {
5659
5688
  error: text || `HTTP ${response.status}`,
5660
5689
  status: response.status,
5661
5690
  durationMs
5662
5691
  };
5692
+ return {
5693
+ error: `Response was not valid JSON (status ${response.status}): ${preview}`,
5694
+ status: response.status,
5695
+ durationMs
5696
+ };
5663
5697
  }
5664
5698
  if (!response.ok) {
5665
5699
  const parsed = data;
@@ -5753,8 +5787,8 @@ var CoolifyService = class {
5753
5787
  "private-github-app": "/applications/private-github-app",
5754
5788
  "private-deploy-key": "/applications/private-deploy-key",
5755
5789
  dockerfile: "/applications/dockerfile",
5756
- "docker-image": "/applications/docker-image",
5757
- "docker-compose": "/applications/docker-compose",
5790
+ "docker-image": "/applications/dockerimage",
5791
+ "docker-compose": "/applications/dockercompose",
5758
5792
  dockerimage: "/applications/dockerimage",
5759
5793
  dockercompose: "/applications/dockercompose"
5760
5794
  };
@@ -5764,19 +5798,30 @@ var CoolifyService = class {
5764
5798
  description: options.description,
5765
5799
  project_uuid: options.projectUuid,
5766
5800
  environment_uuid: options.environmentUuid,
5801
+ environment_name: options.environmentName,
5767
5802
  server_uuid: options.serverUuid
5768
5803
  };
5769
- if (options.githubRepoUrl) body.git_repository = options.githubRepoUrl.replace(/^https?:\/\/github\.com\//, "").replace(/\.git$/, "");
5804
+ if (options.githubRepoUrl) body.git_repository = options.githubRepoUrl;
5770
5805
  if (appType === "public" || appType === "private-github-app" || appType === "private-deploy-key") {
5771
5806
  if (options.githubAppUuid) body.github_app_uuid = options.githubAppUuid;
5807
+ if (appType === "private-deploy-key" && options.privateKeyUuid) body.private_key_uuid = options.privateKeyUuid;
5772
5808
  body.git_branch = options.branch || "main";
5773
5809
  body.build_pack = options.buildPack || "dockerfile";
5774
5810
  if (options.portsExposes) body.ports_exposes = options.portsExposes;
5775
- if (options.dockerfileLocation) body.dockerfile_location = options.dockerfileLocation;
5776
- if (options.dockerComposeLocation) body.docker_compose_location = options.dockerComposeLocation;
5777
- if (options.baseDirectory) body.base_directory = options.baseDirectory;
5778
- } else if (appType === "docker-image" && options.dockerImage) body.docker_image = options.dockerImage;
5779
- else if (appType === "docker-compose" && options.dockerCompose) body.docker_compose = options.dockerCompose;
5811
+ if (options.dockerfileLocation) {
5812
+ const p = options.dockerfileLocation;
5813
+ body.dockerfile_location = p.startsWith("/") ? p : `/${p}`;
5814
+ }
5815
+ if (options.dockerComposeLocation) {
5816
+ const p = options.dockerComposeLocation;
5817
+ body.docker_compose_location = p.startsWith("/") ? p : `/${p}`;
5818
+ }
5819
+ if (options.baseDirectory) {
5820
+ const p = options.baseDirectory;
5821
+ body.base_directory = p.startsWith("/") ? p : `/${p}`;
5822
+ }
5823
+ } else if (appType === "docker-image" && options.dockerImage) body.docker_registry_image_name = options.dockerImage;
5824
+ else if (appType === "docker-compose" && options.dockerCompose) body.docker_compose_raw = options.dockerCompose;
5780
5825
  log.debug(`Create application body: ${JSON.stringify(body, null, 2)}`);
5781
5826
  log.debug(`Endpoint: POST ${endpoint}`);
5782
5827
  const result = await this.request(endpoint, {
@@ -5797,51 +5842,30 @@ var CoolifyService = class {
5797
5842
  /**
5798
5843
  * Sets environment variables for an application.
5799
5844
  *
5845
+ * Delegates to {@link bulkUpdateEnvironmentVariables} so the same
5846
+ * create-or-update logic applies. This fixes the post-delete scenario
5847
+ * (where the variable was deleted via the API and only its base value
5848
+ * from docker-compose/git remains visible) and prevents duplicates
5849
+ * that the singular POST endpoint would create when called for a key
5850
+ * that already exists. Also eliminates the N+1 API calls and the
5851
+ * TOCTOU race between the DELETE and the re-POST that the previous
5852
+ * per-key POST -> DELETE -> re-POST dance had.
5853
+ *
5800
5854
  * @param appUuid - Application UUID
5801
5855
  * @param envVars - Environment variables to set
5802
5856
  * @returns Result indicating success or error
5803
5857
  */
5804
5858
  async setEnvironmentVariables(appUuid, envVars) {
5805
5859
  log.info(`Setting ${Object.keys(envVars).length} environment variables for ${appUuid}`);
5806
- for (const [key, value] of Object.entries(envVars)) {
5807
- const result = await this.request(`/applications/${appUuid}/envs`, {
5808
- method: "POST",
5809
- body: JSON.stringify({
5810
- key,
5811
- value,
5812
- is_preview: false,
5813
- is_buildtime: false
5814
- })
5815
- });
5816
- if (result.error && result.error.includes("already exists")) {
5817
- const listResult = await this.request(`/applications/${appUuid}/envs`);
5818
- const existing = listResult.data?.find((v) => v.key === key);
5819
- if (existing) {
5820
- await this.request(`/applications/${appUuid}/envs/${existing.uuid}`, { method: "DELETE" });
5821
- const repost = await this.request(`/applications/${appUuid}/envs`, {
5822
- method: "POST",
5823
- body: JSON.stringify({
5824
- key,
5825
- value,
5826
- is_preview: false,
5827
- is_buildtime: false
5828
- })
5829
- });
5830
- if (repost.error) {
5831
- log.error(`Failed to update env var ${key}: ${repost.error}`);
5832
- return err(new Error(`Failed to update ${key}: ${repost.error}`));
5833
- }
5834
- log.debug(`Updated existing env var: ${key}`);
5835
- } else {
5836
- log.error(`Failed to set env var ${key}: ${result.error}`);
5837
- return err(new Error(`Failed to set ${key}: ${result.error}`));
5838
- }
5839
- } else if (result.error) {
5840
- log.error(`Failed to set env var ${key}: ${result.error}`);
5841
- return err(new Error(`Failed to set ${key}: ${result.error}`));
5842
- }
5843
- }
5844
- log.success(`${Object.keys(envVars).length} environment variables set`);
5860
+ const vars = Object.entries(envVars).map(([key, value]) => ({
5861
+ key,
5862
+ value,
5863
+ is_buildtime: false,
5864
+ is_runtime: true
5865
+ }));
5866
+ const result = await this.bulkUpdateEnvironmentVariables(appUuid, vars);
5867
+ if (isErr(result)) return err(result.error);
5868
+ log.success(`${vars.length} environment variables set`);
5845
5869
  return ok(void 0);
5846
5870
  }
5847
5871
  /**
@@ -5862,48 +5886,31 @@ var CoolifyService = class {
5862
5886
  }
5863
5887
  /**
5864
5888
  * Sets a single environment variable for an application.
5865
- * Uses PATCH if variable exists, POST if it doesn't.
5889
+ *
5890
+ * Delegates to {@link bulkUpdateEnvironmentVariables} so the same
5891
+ * create-or-update logic applies. This fixes the post-delete scenario
5892
+ * (where the variable was deleted via the API and only its base value
5893
+ * from docker-compose/git remains visible) and prevents duplicates
5894
+ * that the singular PATCH endpoint would create when called without
5895
+ * the variable's UUID.
5866
5896
  *
5867
5897
  * @param appUuid - Application UUID
5868
5898
  * @param key - Variable name
5869
5899
  * @param value - Variable value
5870
- * @param isBuildTime - Whether the variable is available at build time (only for new vars)
5900
+ * @param isBuildTime - Whether the variable is available at build time
5901
+ * (only for new vars; existing runtime-only vars will be flipped to
5902
+ * build-time and vice versa).
5871
5903
  * @returns Result indicating success or error
5872
5904
  */
5873
5905
  async setEnvironmentVariable(appUuid, key, value, isBuildTime = false) {
5874
5906
  log.info(`Setting environment variable ${key} for ${appUuid} (buildtime: ${isBuildTime})`);
5875
- const existingVars = await this.getEnvironmentVariables(appUuid);
5876
- if (isErr(existingVars)) return err(existingVars.error);
5877
- const exists = existingVars.value.some((ev) => ev.key === key);
5878
- if (exists) {
5879
- log.debug(`Variable ${key} exists, using PATCH to update`);
5880
- const result = await this.request(`/applications/${appUuid}/envs`, {
5881
- method: "PATCH",
5882
- body: JSON.stringify({
5883
- key,
5884
- value,
5885
- is_buildtime: isBuildTime
5886
- })
5887
- });
5888
- if (result.error) {
5889
- log.error(`Failed to update env var: ${result.error}`);
5890
- return err(new Error(result.error));
5891
- }
5892
- } else {
5893
- log.debug(`Variable ${key} does not exist, using POST to create`);
5894
- const result = await this.request(`/applications/${appUuid}/envs`, {
5895
- method: "POST",
5896
- body: JSON.stringify({
5897
- key,
5898
- value,
5899
- is_buildtime: isBuildTime
5900
- })
5901
- });
5902
- if (result.error) {
5903
- log.error(`Failed to create env var: ${result.error}`);
5904
- return err(new Error(result.error));
5905
- }
5906
- }
5907
+ const result = await this.bulkUpdateEnvironmentVariables(appUuid, [{
5908
+ key,
5909
+ value,
5910
+ is_buildtime: isBuildTime,
5911
+ is_runtime: !isBuildTime
5912
+ }]);
5913
+ if (isErr(result)) return err(result.error);
5907
5914
  log.success(`Environment variable ${key} set for ${appUuid}`);
5908
5915
  return ok(void 0);
5909
5916
  }
@@ -5993,6 +6000,27 @@ var CoolifyService = class {
5993
6000
  return ok(result.data || []);
5994
6001
  }
5995
6002
  /**
6003
+ * Lists all GitHub Apps configured in Coolify.
6004
+ * Fetches all pages internally and returns a flat list.
6005
+ *
6006
+ * @param perPage - Items per page for each request (default: 50)
6007
+ * @returns Result with all GitHub Apps or error
6008
+ */
6009
+ async listGithubAppsAll(perPage = 50) {
6010
+ const allApps = [];
6011
+ let page = 1;
6012
+ while (true) {
6013
+ const result = await this.listGithubApps(page, perPage);
6014
+ if (isErr(result)) return err(result.error);
6015
+ const apps = result.value;
6016
+ if (apps.length === 0) break;
6017
+ allApps.push(...apps);
6018
+ if (apps.length < perPage) break;
6019
+ page++;
6020
+ }
6021
+ return ok(allApps);
6022
+ }
6023
+ /**
5996
6024
  * Lists all projects.
5997
6025
  *
5998
6026
  * @param page - Optional page number for pagination
@@ -6151,8 +6179,10 @@ var CoolifyService = class {
6151
6179
  if (options.baseDirectory) body.base_directory = options.baseDirectory;
6152
6180
  if (options.domains) body.domains = options.domains;
6153
6181
  if (options.dockerComposeDomains) body.docker_compose_domains = options.dockerComposeDomains;
6182
+ if (options.dockerComposeRaw !== void 0) body.docker_compose_raw = options.dockerComposeRaw;
6154
6183
  if (options.isForceHttpsEnabled !== void 0) body.is_force_https_enabled = options.isForceHttpsEnabled;
6155
6184
  if (options.isAutoDeployEnabled !== void 0) body.is_auto_deploy_enabled = options.isAutoDeployEnabled;
6185
+ if (options.watchPaths !== void 0) body.watch_paths = options.watchPaths;
6156
6186
  if (options.healthCheckEnabled !== void 0) body.health_check_enabled = options.healthCheckEnabled;
6157
6187
  if (options.healthCheckPath) body.health_check_path = options.healthCheckPath;
6158
6188
  if (options.healthCheckPort) body.health_check_port = String(options.healthCheckPort);
@@ -6223,15 +6253,22 @@ var CoolifyService = class {
6223
6253
  /**
6224
6254
  * Bulk updates environment variables for an application.
6225
6255
  *
6256
+ * Uses the bulk endpoint `PATCH /applications/{appUuid}/envs/bulk` which
6257
+ * has create-or-update semantics: if the variable exists in the override
6258
+ * table, its value is updated; otherwise a new override is created. This
6259
+ * is the only reliable way to update a variable that has been deleted
6260
+ * (i.e. its base value from docker-compose/git is still visible in
6261
+ * `getEnvironmentVariables` but no override row exists).
6262
+ *
6226
6263
  * @param appUuid - Application UUID
6227
- * @param envVars - Array of { key, value, is_preview? } objects
6264
+ * @param envVars - Array of variable definitions to upsert
6228
6265
  * @returns Result indicating success or error
6229
6266
  */
6230
6267
  async bulkUpdateEnvironmentVariables(appUuid, envVars) {
6231
6268
  log.info(`Bulk updating ${envVars.length} env vars for ${appUuid}`);
6232
6269
  const result = await this.request(`/applications/${appUuid}/envs/bulk`, {
6233
6270
  method: "PATCH",
6234
- body: JSON.stringify(envVars)
6271
+ body: JSON.stringify({ data: envVars })
6235
6272
  });
6236
6273
  if (result.error) {
6237
6274
  log.error(`Failed to bulk update env vars: ${result.error}`);
@@ -6241,6 +6278,32 @@ var CoolifyService = class {
6241
6278
  return ok(result.data || { message: "Environment variables updated" });
6242
6279
  }
6243
6280
  /**
6281
+ * Bulk updates environment variables for a database.
6282
+ *
6283
+ * Uses the bulk endpoint `PATCH /databases/{databaseUuid}/envs/bulk` which
6284
+ * has create-or-update semantics. Note: the database schema is narrower
6285
+ * than applications — it accepts `key`, `value`, `is_literal`,
6286
+ * `is_multiline`, `is_shown_once` but does NOT accept `is_preview`,
6287
+ * `is_buildtime` or `is_runtime` (those flags are application-only).
6288
+ *
6289
+ * @param databaseUuid - Database UUID
6290
+ * @param envVars - Array of variable definitions to upsert
6291
+ * @returns Result indicating success or error
6292
+ */
6293
+ async bulkUpdateDatabaseEnvVars(databaseUuid, envVars) {
6294
+ log.info(`Bulk updating ${envVars.length} env vars for database ${databaseUuid}`);
6295
+ const result = await this.request(`/databases/${databaseUuid}/envs/bulk`, {
6296
+ method: "PATCH",
6297
+ body: JSON.stringify({ data: envVars })
6298
+ });
6299
+ if (result.error) {
6300
+ log.error(`Failed to bulk update database env vars: ${result.error}`);
6301
+ return err(new Error(result.error));
6302
+ }
6303
+ log.success(`Bulk updated ${envVars.length} env vars for database ${databaseUuid}`);
6304
+ return ok(result.data || { message: "Environment variables updated" });
6305
+ }
6306
+ /**
6244
6307
  * Gets deployment history for an application.
6245
6308
  *
6246
6309
  * @param appUuid - Application UUID
@@ -6648,10 +6711,10 @@ var CoolifyService = class {
6648
6711
  const envIdMap = new Map();
6649
6712
  for (let i = 0; i < projects.length; i++) {
6650
6713
  const envResult = envResults[i];
6651
- if (envResult.status === "fulfilled" && !isErr(envResult.value)) for (const env of envResult.value.value) envIdMap.set(env.id, {
6714
+ if (envResult.status === "fulfilled" && !isErr(envResult.value)) for (const env$1 of envResult.value.value) envIdMap.set(env$1.id, {
6652
6715
  projectUuid: projects[i].uuid,
6653
- envName: env.name,
6654
- envUuid: env.uuid
6716
+ envName: env$1.name,
6717
+ envUuid: env$1.uuid
6655
6718
  });
6656
6719
  }
6657
6720
  const projectNodes = projects.map((p) => ({
@@ -6663,15 +6726,15 @@ var CoolifyService = class {
6663
6726
  const projectMap = new Map();
6664
6727
  for (const node of projectNodes) projectMap.set(node.uuid, node);
6665
6728
  const envNodeMap = new Map();
6666
- for (const [envId, info] of envIdMap) {
6667
- const project = projectMap.get(info.projectUuid);
6729
+ for (const [envId, info$1] of envIdMap) {
6730
+ const project = projectMap.get(info$1.projectUuid);
6668
6731
  if (!project) continue;
6669
6732
  let envNode = project.environments.find((e) => e.id === envId);
6670
6733
  if (!envNode) {
6671
6734
  envNode = {
6672
6735
  id: envId,
6673
- uuid: info.envUuid,
6674
- name: info.envName,
6736
+ uuid: info$1.envUuid,
6737
+ name: info$1.envName,
6675
6738
  resources: []
6676
6739
  };
6677
6740
  project.environments.push(envNode);
@@ -6792,8 +6855,46 @@ var CoolifyService = class {
6792
6855
  return ok(result.data || []);
6793
6856
  }
6794
6857
  /**
6858
+ * Bulk updates environment variables for a service.
6859
+ *
6860
+ * Uses the bulk endpoint `PATCH /services/{uuid}/envs/bulk` which has
6861
+ * create-or-update semantics: if the variable exists in the override
6862
+ * table, its value is updated; otherwise a new override is created.
6863
+ *
6864
+ * This is the only reliable way to update a variable that has been
6865
+ * deleted (i.e. its base value from docker-compose/git is still visible
6866
+ * in `listServiceEnvVars` but no override row exists), and the only way
6867
+ * to set the same key twice without the `POST /services/{uuid}/envs`
6868
+ * returning 409 "already exists".
6869
+ *
6870
+ * @param serviceUuid - Service UUID
6871
+ * @param envVars - Array of variable definitions to upsert
6872
+ * @returns Result indicating success or error
6873
+ */
6874
+ async bulkUpdateServiceEnvVars(serviceUuid, envVars) {
6875
+ log.info(`Bulk updating ${envVars.length} env vars for service ${serviceUuid}`);
6876
+ const result = await this.request(`/services/${serviceUuid}/envs/bulk`, {
6877
+ method: "PATCH",
6878
+ body: JSON.stringify({ data: envVars })
6879
+ });
6880
+ if (result.error) {
6881
+ log.error(`Failed to bulk update service env vars: ${result.error}`);
6882
+ return err(new Error(result.error));
6883
+ }
6884
+ log.success(`Bulk updated ${envVars.length} env vars for service ${serviceUuid}`);
6885
+ return ok(result.data || { message: "Environment variables updated" });
6886
+ }
6887
+ /**
6795
6888
  * Creates an environment variable for a service.
6796
6889
  *
6890
+ * NOTE: Prefer `bulkUpdateServiceEnvVars` for any non-trivial use case.
6891
+ * This endpoint uses `POST /services/{uuid}/envs` and returns 409
6892
+ * "already exists" when the key is already present as an override,
6893
+ * with no recovery path on the server side. Bulk has create-or-update
6894
+ * semantics and handles both new and existing keys reliably.
6895
+ *
6896
+ * Kept for callers that explicitly want a strict create-only operation.
6897
+ *
6797
6898
  * @param uuid - Service UUID
6798
6899
  * @param data - Env var data (key, value, is_preview)
6799
6900
  * @returns Result with created env var UUID or error
@@ -6807,6 +6908,69 @@ var CoolifyService = class {
6807
6908
  return ok(result.data);
6808
6909
  }
6809
6910
  /**
6911
+ * Deletes an environment variable from a service.
6912
+ *
6913
+ * @param serviceUuid - Service UUID
6914
+ * @param key - Variable name to delete
6915
+ * @returns Result indicating success or error
6916
+ */
6917
+ async deleteServiceEnvVar(serviceUuid, key) {
6918
+ log.info(`Deleting environment variable ${key} from service ${serviceUuid}`);
6919
+ const envVarsResult = await this.listServiceEnvVars(serviceUuid);
6920
+ if (isErr(envVarsResult)) return err(envVarsResult.error);
6921
+ const envVar = envVarsResult.value.find((ev) => ev.key === key);
6922
+ if (!envVar) {
6923
+ log.error(`Environment variable ${key} not found on service ${serviceUuid}`);
6924
+ return err(new Error(`Environment variable ${key} not found`));
6925
+ }
6926
+ const result = await this.request(`/services/${serviceUuid}/envs/${envVar.uuid}`, { method: "DELETE" });
6927
+ if (result.error) {
6928
+ log.error(`Failed to delete service env var: ${result.error}`);
6929
+ return err(new Error(result.error));
6930
+ }
6931
+ log.success(`Environment variable ${key} deleted from service ${serviceUuid}`);
6932
+ return ok(void 0);
6933
+ }
6934
+ /**
6935
+ * Lists environment variables for a database.
6936
+ *
6937
+ * @param databaseUuid - Database UUID
6938
+ * @returns Result with env vars list or error
6939
+ */
6940
+ async listDatabaseEnvVars(databaseUuid) {
6941
+ log.info(`Listing env vars for database ${databaseUuid}`);
6942
+ const result = await this.request(`/databases/${databaseUuid}/envs`);
6943
+ if (result.error) {
6944
+ log.error(`Failed to list database env vars: ${result.error}`);
6945
+ return err(new Error(result.error));
6946
+ }
6947
+ return ok(result.data || []);
6948
+ }
6949
+ /**
6950
+ * Deletes an environment variable from a database.
6951
+ *
6952
+ * @param databaseUuid - Database UUID
6953
+ * @param key - Variable name to delete
6954
+ * @returns Result indicating success or error
6955
+ */
6956
+ async deleteDatabaseEnvVar(databaseUuid, key) {
6957
+ log.info(`Deleting environment variable ${key} from database ${databaseUuid}`);
6958
+ const envVarsResult = await this.listDatabaseEnvVars(databaseUuid);
6959
+ if (isErr(envVarsResult)) return err(envVarsResult.error);
6960
+ const envVar = envVarsResult.value.find((ev) => ev.key === key);
6961
+ if (!envVar) {
6962
+ log.error(`Environment variable ${key} not found on database ${databaseUuid}`);
6963
+ return err(new Error(`Environment variable ${key} not found`));
6964
+ }
6965
+ const result = await this.request(`/databases/${databaseUuid}/envs/${envVar.uuid}`, { method: "DELETE" });
6966
+ if (result.error) {
6967
+ log.error(`Failed to delete database env var: ${result.error}`);
6968
+ return err(new Error(result.error));
6969
+ }
6970
+ log.success(`Environment variable ${key} deleted from database ${databaseUuid}`);
6971
+ return ok(void 0);
6972
+ }
6973
+ /**
6810
6974
  * Gets resources deployed on a server.
6811
6975
  *
6812
6976
  * @param serverUuid - Server UUID
@@ -7511,6 +7675,45 @@ function getCoolifyService() {
7511
7675
  return instance;
7512
7676
  }
7513
7677
 
7678
+ //#endregion
7679
+ //#region src/utils/env-parser.ts
7680
+ /**
7681
+ * .env file parser shared between the SDK (syncEnv) and the CLI (--sync stdin).
7682
+ *
7683
+ * Kept as a standalone exported function (not a class method) so both the
7684
+ * SDK's ApplicationsResource and the CLI's stdin sync handler can use the
7685
+ * same implementation without coupling to either.
7686
+ *
7687
+ * @module
7688
+ */
7689
+ /**
7690
+ * Parses .env-style content into a Map.
7691
+ *
7692
+ * Handles:
7693
+ * - Comments (lines starting with `#`)
7694
+ * - Empty lines (skipped)
7695
+ * - Quoted values (`"value"` or `'value'`)
7696
+ * - Values containing `=` (only the first `=` is the separator)
7697
+ * - Lines without `=` (skipped — invalid)
7698
+ *
7699
+ * @param content - File contents in KEY=VALUE format
7700
+ * @returns Map of key → value (empty string for `KEY=` with no value)
7701
+ */
7702
+ function parseEnvContent(content) {
7703
+ const envVars = new Map();
7704
+ for (const line of content.split("\n")) {
7705
+ const trimmed = line.trim();
7706
+ if (!trimmed || trimmed.startsWith("#")) continue;
7707
+ const eq = trimmed.indexOf("=");
7708
+ if (eq === -1) continue;
7709
+ const key = trimmed.slice(0, eq).trim();
7710
+ let value = trimmed.slice(eq + 1).trim();
7711
+ if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
7712
+ if (key) envVars.set(key, value);
7713
+ }
7714
+ return envVars;
7715
+ }
7716
+
7514
7717
  //#endregion
7515
7718
  //#region src/sdk.ts
7516
7719
  init_dist();
@@ -7529,6 +7732,10 @@ var ApplicationsResource = class {
7529
7732
  async listSummaries() {
7530
7733
  return unwrap(await this.svc.listApplicationSummaries());
7531
7734
  }
7735
+ /** Get a single application by UUID with full details (including settings and watch_paths). */
7736
+ async get(uuid) {
7737
+ return unwrap(await this.svc.getApplication(uuid));
7738
+ }
7532
7739
  /** Resolve application by name, domain, or UUID. */
7533
7740
  async resolve(query) {
7534
7741
  return unwrap(await this.svc.resolveApplication(query));
@@ -7595,10 +7802,15 @@ var ApplicationsResource = class {
7595
7802
  async syncEnv(uuid, options = {}) {
7596
7803
  const { filePath, dryRun = false, prune = false, onProgress } = options;
7597
7804
  let envContent;
7805
+ const { readFileSync: readFileSync$1 } = await import("node:fs");
7806
+ const { resolve, isAbsolute } = await import("node:path");
7807
+ const target = filePath || ".env";
7808
+ const absoluteTarget = isAbsolute(target) ? target : resolve(process.cwd(), target);
7598
7809
  try {
7599
- envContent = await Bun.file(filePath || ".env").text();
7600
- } catch {
7601
- throw new Error(filePath ? `Cannot read file: ${filePath}` : "No .env file found in current directory");
7810
+ envContent = readFileSync$1(absoluteTarget, "utf-8");
7811
+ } catch (err$1) {
7812
+ const msg = err$1 instanceof Error ? err$1.message : String(err$1);
7813
+ throw new Error(`Cannot read env file at ${absoluteTarget} (resolved from ${target}): ${msg}`);
7602
7814
  }
7603
7815
  const localVars = this.parseEnvContent(envContent);
7604
7816
  if (localVars.size === 0) return {
@@ -7676,25 +7888,14 @@ var ApplicationsResource = class {
7676
7888
  }
7677
7889
  /**
7678
7890
  * Parse .env file content into a Map.
7679
- * Handles comments, empty lines, and quoted values.
7891
+ * Delegates to the shared utility in `./utils/env-parser.js` so the SDK
7892
+ * and CLI use a single implementation.
7680
7893
  *
7681
7894
  * @param content - The .env file content
7682
7895
  * @returns Map of environment variables
7683
7896
  */
7684
7897
  parseEnvContent(content) {
7685
- const envVars = new Map();
7686
- const lines = content.split("\n");
7687
- for (const line of lines) {
7688
- const trimmedLine = line.trim();
7689
- if (!trimmedLine || trimmedLine.startsWith("#")) continue;
7690
- const eqIndex = trimmedLine.indexOf("=");
7691
- if (eqIndex === -1) continue;
7692
- const key = trimmedLine.slice(0, eqIndex).trim();
7693
- let value = trimmedLine.slice(eqIndex + 1).trim();
7694
- if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
7695
- envVars.set(key, value);
7696
- }
7697
- return envVars;
7898
+ return parseEnvContent(content);
7698
7899
  }
7699
7900
  };
7700
7901
  var DatabasesResource = class {
@@ -7741,6 +7942,24 @@ var DatabasesResource = class {
7741
7942
  async deleteBackup(dbUuid, backupUuid) {
7742
7943
  return unwrap(await this.svc.deleteDatabaseBackup(dbUuid, backupUuid));
7743
7944
  }
7945
+ /** List env vars for a database. */
7946
+ async envVars(uuid) {
7947
+ return unwrap(await this.svc.listDatabaseEnvVars(uuid));
7948
+ }
7949
+ /**
7950
+ * Bulk set (create-or-update) env vars for a database.
7951
+ *
7952
+ * Note: the database schema is narrower than applications — only
7953
+ * `is_literal`, `is_multiline`, `is_shown_once` are accepted. No
7954
+ * `is_preview` / `is_buildtime` / `is_runtime`.
7955
+ */
7956
+ async bulkSetEnv(uuid, vars) {
7957
+ return unwrap(await this.svc.bulkUpdateDatabaseEnvVars(uuid, vars));
7958
+ }
7959
+ /** Delete a database env var by key. Resolves key → UUID, then DELETE. */
7960
+ async deleteEnv(uuid, key) {
7961
+ return unwrap(await this.svc.deleteDatabaseEnvVar(uuid, key));
7962
+ }
7744
7963
  };
7745
7964
  var ServicesResource = class {
7746
7965
  constructor(svc) {
@@ -7777,8 +7996,34 @@ var ServicesResource = class {
7777
7996
  async envVars(uuid) {
7778
7997
  return unwrap(await this.svc.listServiceEnvVars(uuid));
7779
7998
  }
7999
+ /**
8000
+ * Sets (creates or updates) a single env var for a service.
8001
+ *
8002
+ * Delegates to the bulk endpoint `PATCH /services/{uuid}/envs/bulk`,
8003
+ * which has create-or-update semantics — calling this for the same key
8004
+ * a second time updates the override value rather than failing with
8005
+ * 409 "already exists" (which is what the raw `POST /services/{uuid}/envs`
8006
+ * endpoint does). Mirrors `ApplicationsResource.setEnv`.
8007
+ *
8008
+ * @param uuid - Service UUID
8009
+ * @param data - Env var data (key, value, is_preview)
8010
+ */
7780
8011
  async setEnv(uuid, data) {
7781
- return unwrap(await this.svc.createServiceEnvVar(uuid, data));
8012
+ return unwrap(await this.svc.bulkUpdateServiceEnvVars(uuid, [data]));
8013
+ }
8014
+ /**
8015
+ * Bulk set (create-or-update) env vars for a service.
8016
+ * Mirrors `ApplicationsResource.bulkSetEnv`.
8017
+ *
8018
+ * @param uuid - Service UUID
8019
+ * @param vars - Array of env var definitions to upsert
8020
+ */
8021
+ async bulkSetEnv(uuid, vars) {
8022
+ return unwrap(await this.svc.bulkUpdateServiceEnvVars(uuid, vars));
8023
+ }
8024
+ /** Delete a service env var by key. Resolves key → UUID, then DELETE. */
8025
+ async deleteEnv(uuid, key) {
8026
+ return unwrap(await this.svc.deleteServiceEnvVar(uuid, key));
7782
8027
  }
7783
8028
  };
7784
8029
  var ServersResource = class {
@@ -8323,6 +8568,11 @@ Redeploy after updating to apply changes.`,
8323
8568
  type: "string",
8324
8569
  description: "Base directory for build context (default: \"/\")"
8325
8570
  },
8571
+ watchPaths: {
8572
+ type: "string",
8573
+ description: "Watch paths for selective auto-deploy. Newline-separated globs (e.g. \"src/**\\npackages/**\"). Set to empty string or null to clear.",
8574
+ nullable: true
8575
+ },
8326
8576
  dockerComposeDomains: {
8327
8577
  type: "string",
8328
8578
  description: "Docker Compose domains JSON: { \"service-name\": { \"domain\": \"https://...\" } }"
@@ -8331,6 +8581,20 @@ Redeploy after updating to apply changes.`,
8331
8581
  required: ["uuid"]
8332
8582
  }
8333
8583
  },
8584
+ {
8585
+ name: "get_application",
8586
+ description: `Get detailed information about a Coolify application including settings (auto-deploy, force HTTPS) and watch paths.
8587
+
8588
+ Returns full application details that list_applications doesn't include.`,
8589
+ inputSchema: {
8590
+ type: "object",
8591
+ properties: { uuid: {
8592
+ type: "string",
8593
+ description: "Application UUID"
8594
+ } },
8595
+ required: ["uuid"]
8596
+ }
8597
+ },
8334
8598
  {
8335
8599
  name: "set_domains",
8336
8600
  description: `Set domains/FQDN for a Coolify application.
@@ -9199,11 +9463,25 @@ async function handleToolCall(name, args) {
9199
9463
  startCommand: a.startCommand,
9200
9464
  domains: a.domains,
9201
9465
  isForceHttpsEnabled: a.isForceHttpsEnabled,
9202
- isAutoDeployEnabled: a.isAutoDeployEnabled
9466
+ isAutoDeployEnabled: a.isAutoDeployEnabled,
9467
+ watchPaths: a.watchPaths
9203
9468
  }).then((app) => ({
9204
9469
  message: `Application ${a.uuid} updated`,
9205
9470
  application: app
9206
9471
  })), "Failed to update application");
9472
+ case "get_application": return mcpCall((s) => s.applications.get(a.uuid).then((app) => ({
9473
+ uuid: app.uuid,
9474
+ name: app.name,
9475
+ status: app.status,
9476
+ fqdn: app.fqdn,
9477
+ git_repository: app.git_repository,
9478
+ git_branch: app.git_branch,
9479
+ build_pack: app.build_pack,
9480
+ dockerfile_location: app.dockerfile_location,
9481
+ base_directory: app.base_directory,
9482
+ watch_paths: app.watch_paths,
9483
+ settings: app.settings
9484
+ })), "Failed to get application");
9207
9485
  case "get_application_logs": return mcpCall((s) => s.applications.logs(a.uuid, {
9208
9486
  tail: a.tail,
9209
9487
  serviceName: a.serviceName
@@ -9563,6 +9841,1787 @@ var init_network = __esm({ "src/network.ts"() {
9563
9841
  ];
9564
9842
  } });
9565
9843
 
9844
+ //#endregion
9845
+ //#region ../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/debug.js
9846
+ var require_debug = __commonJS({ "../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/debug.js"(exports, module) {
9847
+ let messages = [];
9848
+ let level = 0;
9849
+ const debug$3 = (msg, min) => {
9850
+ if (level >= min) messages.push(msg);
9851
+ };
9852
+ debug$3.WARN = 1;
9853
+ debug$3.INFO = 2;
9854
+ debug$3.DEBUG = 3;
9855
+ debug$3.reset = () => {
9856
+ messages = [];
9857
+ };
9858
+ debug$3.setDebugLevel = (v) => {
9859
+ level = v;
9860
+ };
9861
+ debug$3.warn = (msg) => debug$3(msg, debug$3.WARN);
9862
+ debug$3.info = (msg) => debug$3(msg, debug$3.INFO);
9863
+ debug$3.debug = (msg) => debug$3(msg, debug$3.DEBUG);
9864
+ debug$3.debugMessages = () => messages;
9865
+ module.exports = debug$3;
9866
+ } });
9867
+
9868
+ //#endregion
9869
+ //#region ../../../node_modules/.bun/ansi-regex@5.0.1/node_modules/ansi-regex/index.js
9870
+ var require_ansi_regex = __commonJS({ "../../../node_modules/.bun/ansi-regex@5.0.1/node_modules/ansi-regex/index.js"(exports, module) {
9871
+ module.exports = ({ onlyFirst = false } = {}) => {
9872
+ const pattern = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");
9873
+ return new RegExp(pattern, onlyFirst ? void 0 : "g");
9874
+ };
9875
+ } });
9876
+
9877
+ //#endregion
9878
+ //#region ../../../node_modules/.bun/strip-ansi@6.0.1/node_modules/strip-ansi/index.js
9879
+ var require_strip_ansi = __commonJS({ "../../../node_modules/.bun/strip-ansi@6.0.1/node_modules/strip-ansi/index.js"(exports, module) {
9880
+ const ansiRegex = require_ansi_regex();
9881
+ module.exports = (string) => typeof string === "string" ? string.replace(ansiRegex(), "") : string;
9882
+ } });
9883
+
9884
+ //#endregion
9885
+ //#region ../../../node_modules/.bun/is-fullwidth-code-point@3.0.0/node_modules/is-fullwidth-code-point/index.js
9886
+ var require_is_fullwidth_code_point = __commonJS({ "../../../node_modules/.bun/is-fullwidth-code-point@3.0.0/node_modules/is-fullwidth-code-point/index.js"(exports, module) {
9887
+ const isFullwidthCodePoint$1 = (codePoint) => {
9888
+ if (Number.isNaN(codePoint)) return false;
9889
+ if (codePoint >= 4352 && (codePoint <= 4447 || codePoint === 9001 || codePoint === 9002 || 11904 <= codePoint && codePoint <= 12871 && codePoint !== 12351 || 12880 <= codePoint && codePoint <= 19903 || 19968 <= codePoint && codePoint <= 42182 || 43360 <= codePoint && codePoint <= 43388 || 44032 <= codePoint && codePoint <= 55203 || 63744 <= codePoint && codePoint <= 64255 || 65040 <= codePoint && codePoint <= 65049 || 65072 <= codePoint && codePoint <= 65131 || 65281 <= codePoint && codePoint <= 65376 || 65504 <= codePoint && codePoint <= 65510 || 110592 <= codePoint && codePoint <= 110593 || 127488 <= codePoint && codePoint <= 127569 || 131072 <= codePoint && codePoint <= 262141)) return true;
9890
+ return false;
9891
+ };
9892
+ module.exports = isFullwidthCodePoint$1;
9893
+ module.exports.default = isFullwidthCodePoint$1;
9894
+ } });
9895
+
9896
+ //#endregion
9897
+ //#region ../../../node_modules/.bun/emoji-regex@8.0.0/node_modules/emoji-regex/index.js
9898
+ var require_emoji_regex = __commonJS({ "../../../node_modules/.bun/emoji-regex@8.0.0/node_modules/emoji-regex/index.js"(exports, module) {
9899
+ module.exports = function() {
9900
+ return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
9901
+ };
9902
+ } });
9903
+
9904
+ //#endregion
9905
+ //#region ../../../node_modules/.bun/string-width@4.2.3/node_modules/string-width/index.js
9906
+ var require_string_width = __commonJS({ "../../../node_modules/.bun/string-width@4.2.3/node_modules/string-width/index.js"(exports, module) {
9907
+ const stripAnsi = require_strip_ansi();
9908
+ const isFullwidthCodePoint = require_is_fullwidth_code_point();
9909
+ const emojiRegex = require_emoji_regex();
9910
+ const stringWidth$1 = (string) => {
9911
+ if (typeof string !== "string" || string.length === 0) return 0;
9912
+ string = stripAnsi(string);
9913
+ if (string.length === 0) return 0;
9914
+ string = string.replace(emojiRegex(), " ");
9915
+ let width = 0;
9916
+ for (let i = 0; i < string.length; i++) {
9917
+ const code = string.codePointAt(i);
9918
+ if (code <= 31 || code >= 127 && code <= 159) continue;
9919
+ if (code >= 768 && code <= 879) continue;
9920
+ if (code > 65535) i++;
9921
+ width += isFullwidthCodePoint(code) ? 2 : 1;
9922
+ }
9923
+ return width;
9924
+ };
9925
+ module.exports = stringWidth$1;
9926
+ module.exports.default = stringWidth$1;
9927
+ } });
9928
+
9929
+ //#endregion
9930
+ //#region ../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/utils.js
9931
+ var require_utils = __commonJS({ "../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/utils.js"(exports, module) {
9932
+ const stringWidth = require_string_width();
9933
+ function codeRegex(capture) {
9934
+ return capture ? /\u001b\[((?:\d*;){0,5}\d*)m/g : /\u001b\[(?:\d*;){0,5}\d*m/g;
9935
+ }
9936
+ function strlen(str) {
9937
+ let code = codeRegex();
9938
+ let stripped = ("" + str).replace(code, "");
9939
+ let split = stripped.split("\n");
9940
+ return split.reduce(function(memo, s) {
9941
+ return stringWidth(s) > memo ? stringWidth(s) : memo;
9942
+ }, 0);
9943
+ }
9944
+ function repeat(str, times) {
9945
+ return Array(times + 1).join(str);
9946
+ }
9947
+ function pad(str, len, pad$1, dir) {
9948
+ let length = strlen(str);
9949
+ if (len + 1 >= length) {
9950
+ let padlen = len - length;
9951
+ switch (dir) {
9952
+ case "right": {
9953
+ str = repeat(pad$1, padlen) + str;
9954
+ break;
9955
+ }
9956
+ case "center": {
9957
+ let right = Math.ceil(padlen / 2);
9958
+ let left = padlen - right;
9959
+ str = repeat(pad$1, left) + str + repeat(pad$1, right);
9960
+ break;
9961
+ }
9962
+ default: {
9963
+ str = str + repeat(pad$1, padlen);
9964
+ break;
9965
+ }
9966
+ }
9967
+ }
9968
+ return str;
9969
+ }
9970
+ let codeCache = {};
9971
+ function addToCodeCache(name, on, off) {
9972
+ on = "\x1B[" + on + "m";
9973
+ off = "\x1B[" + off + "m";
9974
+ codeCache[on] = {
9975
+ set: name,
9976
+ to: true
9977
+ };
9978
+ codeCache[off] = {
9979
+ set: name,
9980
+ to: false
9981
+ };
9982
+ codeCache[name] = {
9983
+ on,
9984
+ off
9985
+ };
9986
+ }
9987
+ addToCodeCache("bold", 1, 22);
9988
+ addToCodeCache("italics", 3, 23);
9989
+ addToCodeCache("underline", 4, 24);
9990
+ addToCodeCache("inverse", 7, 27);
9991
+ addToCodeCache("strikethrough", 9, 29);
9992
+ function updateState(state, controlChars) {
9993
+ let controlCode = controlChars[1] ? parseInt(controlChars[1].split(";")[0]) : 0;
9994
+ if (controlCode >= 30 && controlCode <= 39 || controlCode >= 90 && controlCode <= 97) {
9995
+ state.lastForegroundAdded = controlChars[0];
9996
+ return;
9997
+ }
9998
+ if (controlCode >= 40 && controlCode <= 49 || controlCode >= 100 && controlCode <= 107) {
9999
+ state.lastBackgroundAdded = controlChars[0];
10000
+ return;
10001
+ }
10002
+ if (controlCode === 0) {
10003
+ for (let i in state)
10004
+ /* istanbul ignore else */
10005
+ if (Object.prototype.hasOwnProperty.call(state, i)) delete state[i];
10006
+ return;
10007
+ }
10008
+ let info$1 = codeCache[controlChars[0]];
10009
+ if (info$1) state[info$1.set] = info$1.to;
10010
+ }
10011
+ function readState(line) {
10012
+ let code = codeRegex(true);
10013
+ let controlChars = code.exec(line);
10014
+ let state = {};
10015
+ while (controlChars !== null) {
10016
+ updateState(state, controlChars);
10017
+ controlChars = code.exec(line);
10018
+ }
10019
+ return state;
10020
+ }
10021
+ function unwindState(state, ret) {
10022
+ let lastBackgroundAdded = state.lastBackgroundAdded;
10023
+ let lastForegroundAdded = state.lastForegroundAdded;
10024
+ delete state.lastBackgroundAdded;
10025
+ delete state.lastForegroundAdded;
10026
+ Object.keys(state).forEach(function(key) {
10027
+ if (state[key]) ret += codeCache[key].off;
10028
+ });
10029
+ if (lastBackgroundAdded && lastBackgroundAdded != "\x1B[49m") ret += "\x1B[49m";
10030
+ if (lastForegroundAdded && lastForegroundAdded != "\x1B[39m") ret += "\x1B[39m";
10031
+ return ret;
10032
+ }
10033
+ function rewindState(state, ret) {
10034
+ let lastBackgroundAdded = state.lastBackgroundAdded;
10035
+ let lastForegroundAdded = state.lastForegroundAdded;
10036
+ delete state.lastBackgroundAdded;
10037
+ delete state.lastForegroundAdded;
10038
+ Object.keys(state).forEach(function(key) {
10039
+ if (state[key]) ret = codeCache[key].on + ret;
10040
+ });
10041
+ if (lastBackgroundAdded && lastBackgroundAdded != "\x1B[49m") ret = lastBackgroundAdded + ret;
10042
+ if (lastForegroundAdded && lastForegroundAdded != "\x1B[39m") ret = lastForegroundAdded + ret;
10043
+ return ret;
10044
+ }
10045
+ function truncateWidth(str, desiredLength) {
10046
+ if (str.length === strlen(str)) return str.substr(0, desiredLength);
10047
+ while (strlen(str) > desiredLength) str = str.slice(0, -1);
10048
+ return str;
10049
+ }
10050
+ function truncateWidthWithAnsi(str, desiredLength) {
10051
+ let code = codeRegex(true);
10052
+ let split = str.split(codeRegex());
10053
+ let splitIndex = 0;
10054
+ let retLen = 0;
10055
+ let ret = "";
10056
+ let myArray;
10057
+ let state = {};
10058
+ while (retLen < desiredLength) {
10059
+ myArray = code.exec(str);
10060
+ let toAdd = split[splitIndex];
10061
+ splitIndex++;
10062
+ if (retLen + strlen(toAdd) > desiredLength) toAdd = truncateWidth(toAdd, desiredLength - retLen);
10063
+ ret += toAdd;
10064
+ retLen += strlen(toAdd);
10065
+ if (retLen < desiredLength) {
10066
+ if (!myArray) break;
10067
+ ret += myArray[0];
10068
+ updateState(state, myArray);
10069
+ }
10070
+ }
10071
+ return unwindState(state, ret);
10072
+ }
10073
+ function truncate(str, desiredLength, truncateChar) {
10074
+ truncateChar = truncateChar || "…";
10075
+ let lengthOfStr = strlen(str);
10076
+ if (lengthOfStr <= desiredLength) return str;
10077
+ desiredLength -= strlen(truncateChar);
10078
+ let ret = truncateWidthWithAnsi(str, desiredLength);
10079
+ ret += truncateChar;
10080
+ const hrefTag = "\x1B]8;;\x07";
10081
+ if (str.includes(hrefTag) && !ret.includes(hrefTag)) ret += hrefTag;
10082
+ return ret;
10083
+ }
10084
+ function defaultOptions() {
10085
+ return {
10086
+ chars: {
10087
+ top: "─",
10088
+ "top-mid": "┬",
10089
+ "top-left": "┌",
10090
+ "top-right": "┐",
10091
+ bottom: "─",
10092
+ "bottom-mid": "┴",
10093
+ "bottom-left": "└",
10094
+ "bottom-right": "┘",
10095
+ left: "│",
10096
+ "left-mid": "├",
10097
+ mid: "─",
10098
+ "mid-mid": "┼",
10099
+ right: "│",
10100
+ "right-mid": "┤",
10101
+ middle: "│"
10102
+ },
10103
+ truncate: "…",
10104
+ colWidths: [],
10105
+ rowHeights: [],
10106
+ colAligns: [],
10107
+ rowAligns: [],
10108
+ style: {
10109
+ "padding-left": 1,
10110
+ "padding-right": 1,
10111
+ head: ["red"],
10112
+ border: ["grey"],
10113
+ compact: false
10114
+ },
10115
+ head: []
10116
+ };
10117
+ }
10118
+ function mergeOptions(options, defaults) {
10119
+ options = options || {};
10120
+ defaults = defaults || defaultOptions();
10121
+ let ret = Object.assign({}, defaults, options);
10122
+ ret.chars = Object.assign({}, defaults.chars, options.chars);
10123
+ ret.style = Object.assign({}, defaults.style, options.style);
10124
+ return ret;
10125
+ }
10126
+ function wordWrap(maxLength, input) {
10127
+ let lines = [];
10128
+ let split = input.split(/(\s+)/g);
10129
+ let line = [];
10130
+ let lineLength = 0;
10131
+ let whitespace;
10132
+ for (let i = 0; i < split.length; i += 2) {
10133
+ let word = split[i];
10134
+ let newLength = lineLength + strlen(word);
10135
+ if (lineLength > 0 && whitespace) newLength += whitespace.length;
10136
+ if (newLength > maxLength) {
10137
+ if (lineLength !== 0) lines.push(line.join(""));
10138
+ line = [word];
10139
+ lineLength = strlen(word);
10140
+ } else {
10141
+ line.push(whitespace || "", word);
10142
+ lineLength = newLength;
10143
+ }
10144
+ whitespace = split[i + 1];
10145
+ }
10146
+ if (lineLength) lines.push(line.join(""));
10147
+ return lines;
10148
+ }
10149
+ function textWrap(maxLength, input) {
10150
+ let lines = [];
10151
+ let line = "";
10152
+ function pushLine(str, ws) {
10153
+ if (line.length && ws) line += ws;
10154
+ line += str;
10155
+ while (line.length > maxLength) {
10156
+ lines.push(line.slice(0, maxLength));
10157
+ line = line.slice(maxLength);
10158
+ }
10159
+ }
10160
+ let split = input.split(/(\s+)/g);
10161
+ for (let i = 0; i < split.length; i += 2) pushLine(split[i], i && split[i - 1]);
10162
+ if (line.length) lines.push(line);
10163
+ return lines;
10164
+ }
10165
+ function multiLineWordWrap(maxLength, input, wrapOnWordBoundary = true) {
10166
+ let output = [];
10167
+ input = input.split("\n");
10168
+ const handler = wrapOnWordBoundary ? wordWrap : textWrap;
10169
+ for (let i = 0; i < input.length; i++) output.push.apply(output, handler(maxLength, input[i]));
10170
+ return output;
10171
+ }
10172
+ function colorizeLines(input) {
10173
+ let state = {};
10174
+ let output = [];
10175
+ for (let i = 0; i < input.length; i++) {
10176
+ let line = rewindState(state, input[i]);
10177
+ state = readState(line);
10178
+ let temp = Object.assign({}, state);
10179
+ output.push(unwindState(temp, line));
10180
+ }
10181
+ return output;
10182
+ }
10183
+ /**
10184
+ * Credit: Matheus Sampaio https://github.com/matheussampaio
10185
+ */
10186
+ function hyperlink(url, text) {
10187
+ const OSC = "\x1B]";
10188
+ const BEL = "\x07";
10189
+ const SEP = ";";
10190
+ return [
10191
+ OSC,
10192
+ "8",
10193
+ SEP,
10194
+ SEP,
10195
+ url || text,
10196
+ BEL,
10197
+ text,
10198
+ OSC,
10199
+ "8",
10200
+ SEP,
10201
+ SEP,
10202
+ BEL
10203
+ ].join("");
10204
+ }
10205
+ module.exports = {
10206
+ strlen,
10207
+ repeat,
10208
+ pad,
10209
+ truncate,
10210
+ mergeOptions,
10211
+ wordWrap: multiLineWordWrap,
10212
+ colorizeLines,
10213
+ hyperlink
10214
+ };
10215
+ } });
10216
+
10217
+ //#endregion
10218
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/styles.js
10219
+ var require_styles = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/styles.js"(exports, module) {
10220
+ var styles$1 = {};
10221
+ module["exports"] = styles$1;
10222
+ var codes = {
10223
+ reset: [0, 0],
10224
+ bold: [1, 22],
10225
+ dim: [2, 22],
10226
+ italic: [3, 23],
10227
+ underline: [4, 24],
10228
+ inverse: [7, 27],
10229
+ hidden: [8, 28],
10230
+ strikethrough: [9, 29],
10231
+ black: [30, 39],
10232
+ red: [31, 39],
10233
+ green: [32, 39],
10234
+ yellow: [33, 39],
10235
+ blue: [34, 39],
10236
+ magenta: [35, 39],
10237
+ cyan: [36, 39],
10238
+ white: [37, 39],
10239
+ gray: [90, 39],
10240
+ grey: [90, 39],
10241
+ brightRed: [91, 39],
10242
+ brightGreen: [92, 39],
10243
+ brightYellow: [93, 39],
10244
+ brightBlue: [94, 39],
10245
+ brightMagenta: [95, 39],
10246
+ brightCyan: [96, 39],
10247
+ brightWhite: [97, 39],
10248
+ bgBlack: [40, 49],
10249
+ bgRed: [41, 49],
10250
+ bgGreen: [42, 49],
10251
+ bgYellow: [43, 49],
10252
+ bgBlue: [44, 49],
10253
+ bgMagenta: [45, 49],
10254
+ bgCyan: [46, 49],
10255
+ bgWhite: [47, 49],
10256
+ bgGray: [100, 49],
10257
+ bgGrey: [100, 49],
10258
+ bgBrightRed: [101, 49],
10259
+ bgBrightGreen: [102, 49],
10260
+ bgBrightYellow: [103, 49],
10261
+ bgBrightBlue: [104, 49],
10262
+ bgBrightMagenta: [105, 49],
10263
+ bgBrightCyan: [106, 49],
10264
+ bgBrightWhite: [107, 49],
10265
+ blackBG: [40, 49],
10266
+ redBG: [41, 49],
10267
+ greenBG: [42, 49],
10268
+ yellowBG: [43, 49],
10269
+ blueBG: [44, 49],
10270
+ magentaBG: [45, 49],
10271
+ cyanBG: [46, 49],
10272
+ whiteBG: [47, 49]
10273
+ };
10274
+ Object.keys(codes).forEach(function(key) {
10275
+ var val = codes[key];
10276
+ var style = styles$1[key] = [];
10277
+ style.open = "\x1B[" + val[0] + "m";
10278
+ style.close = "\x1B[" + val[1] + "m";
10279
+ });
10280
+ } });
10281
+
10282
+ //#endregion
10283
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/system/has-flag.js
10284
+ var require_has_flag = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/system/has-flag.js"(exports, module) {
10285
+ module.exports = function(flag, argv) {
10286
+ argv = argv || process.argv;
10287
+ var terminatorPos = argv.indexOf("--");
10288
+ var prefix = /^-{1,2}/.test(flag) ? "" : "--";
10289
+ var pos = argv.indexOf(prefix + flag);
10290
+ return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
10291
+ };
10292
+ } });
10293
+
10294
+ //#endregion
10295
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/system/supports-colors.js
10296
+ var require_supports_colors = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/system/supports-colors.js"(exports, module) {
10297
+ var os = __require("os");
10298
+ var hasFlag = require_has_flag();
10299
+ var env = process.env;
10300
+ var forceColor = void 0;
10301
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false")) forceColor = false;
10302
+ else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) forceColor = true;
10303
+ if ("FORCE_COLOR" in env) forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
10304
+ function translateLevel(level$1) {
10305
+ if (level$1 === 0) return false;
10306
+ return {
10307
+ level: level$1,
10308
+ hasBasic: true,
10309
+ has256: level$1 >= 2,
10310
+ has16m: level$1 >= 3
10311
+ };
10312
+ }
10313
+ function supportsColor(stream) {
10314
+ if (forceColor === false) return 0;
10315
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) return 3;
10316
+ if (hasFlag("color=256")) return 2;
10317
+ if (stream && !stream.isTTY && forceColor !== true) return 0;
10318
+ var min = forceColor ? 1 : 0;
10319
+ if (process.platform === "win32") {
10320
+ var osRelease = os.release().split(".");
10321
+ if (Number(process.versions.node.split(".")[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
10322
+ return 1;
10323
+ }
10324
+ if ("CI" in env) {
10325
+ if ([
10326
+ "TRAVIS",
10327
+ "CIRCLECI",
10328
+ "APPVEYOR",
10329
+ "GITLAB_CI"
10330
+ ].some(function(sign) {
10331
+ return sign in env;
10332
+ }) || env.CI_NAME === "codeship") return 1;
10333
+ return min;
10334
+ }
10335
+ if ("TEAMCITY_VERSION" in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
10336
+ if ("TERM_PROGRAM" in env) {
10337
+ var version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
10338
+ switch (env.TERM_PROGRAM) {
10339
+ case "iTerm.app": return version >= 3 ? 3 : 2;
10340
+ case "Hyper": return 3;
10341
+ case "Apple_Terminal": return 2;
10342
+ }
10343
+ }
10344
+ if (/-256(color)?$/i.test(env.TERM)) return 2;
10345
+ if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) return 1;
10346
+ if ("COLORTERM" in env) return 1;
10347
+ if (env.TERM === "dumb") return min;
10348
+ return min;
10349
+ }
10350
+ function getSupportLevel(stream) {
10351
+ var level$1 = supportsColor(stream);
10352
+ return translateLevel(level$1);
10353
+ }
10354
+ module.exports = {
10355
+ supportsColor: getSupportLevel,
10356
+ stdout: getSupportLevel(process.stdout),
10357
+ stderr: getSupportLevel(process.stderr)
10358
+ };
10359
+ } });
10360
+
10361
+ //#endregion
10362
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/custom/trap.js
10363
+ var require_trap = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/custom/trap.js"(exports, module) {
10364
+ module["exports"] = function runTheTrap(text, options) {
10365
+ var result = "";
10366
+ text = text || "Run the trap, drop the bass";
10367
+ text = text.split("");
10368
+ var trap = {
10369
+ a: [
10370
+ "@",
10371
+ "Ą",
10372
+ "Ⱥ",
10373
+ "Ʌ",
10374
+ "Δ",
10375
+ "Λ",
10376
+ "Д"
10377
+ ],
10378
+ b: [
10379
+ "ß",
10380
+ "Ɓ",
10381
+ "Ƀ",
10382
+ "ɮ",
10383
+ "β",
10384
+ "฿"
10385
+ ],
10386
+ c: [
10387
+ "©",
10388
+ "Ȼ",
10389
+ "Ͼ"
10390
+ ],
10391
+ d: [
10392
+ "Ð",
10393
+ "Ɗ",
10394
+ "Ԁ",
10395
+ "ԁ",
10396
+ "Ԃ",
10397
+ "ԃ"
10398
+ ],
10399
+ e: [
10400
+ "Ë",
10401
+ "ĕ",
10402
+ "Ǝ",
10403
+ "ɘ",
10404
+ "Σ",
10405
+ "ξ",
10406
+ "Ҽ",
10407
+ "੬"
10408
+ ],
10409
+ f: ["Ӻ"],
10410
+ g: ["ɢ"],
10411
+ h: [
10412
+ "Ħ",
10413
+ "ƕ",
10414
+ "Ң",
10415
+ "Һ",
10416
+ "Ӈ",
10417
+ "Ԋ"
10418
+ ],
10419
+ i: ["༏"],
10420
+ j: ["Ĵ"],
10421
+ k: [
10422
+ "ĸ",
10423
+ "Ҡ",
10424
+ "Ӄ",
10425
+ "Ԟ"
10426
+ ],
10427
+ l: ["Ĺ"],
10428
+ m: [
10429
+ "ʍ",
10430
+ "Ӎ",
10431
+ "ӎ",
10432
+ "Ԡ",
10433
+ "ԡ",
10434
+ "൩"
10435
+ ],
10436
+ n: [
10437
+ "Ñ",
10438
+ "ŋ",
10439
+ "Ɲ",
10440
+ "Ͷ",
10441
+ "Π",
10442
+ "Ҋ"
10443
+ ],
10444
+ o: [
10445
+ "Ø",
10446
+ "õ",
10447
+ "ø",
10448
+ "Ǿ",
10449
+ "ʘ",
10450
+ "Ѻ",
10451
+ "ם",
10452
+ "۝",
10453
+ "๏"
10454
+ ],
10455
+ p: ["Ƿ", "Ҏ"],
10456
+ q: ["্"],
10457
+ r: [
10458
+ "®",
10459
+ "Ʀ",
10460
+ "Ȑ",
10461
+ "Ɍ",
10462
+ "ʀ",
10463
+ "Я"
10464
+ ],
10465
+ s: [
10466
+ "§",
10467
+ "Ϟ",
10468
+ "ϟ",
10469
+ "Ϩ"
10470
+ ],
10471
+ t: [
10472
+ "Ł",
10473
+ "Ŧ",
10474
+ "ͳ"
10475
+ ],
10476
+ u: ["Ʊ", "Ս"],
10477
+ v: ["ט"],
10478
+ w: [
10479
+ "Ш",
10480
+ "Ѡ",
10481
+ "Ѽ",
10482
+ "൰"
10483
+ ],
10484
+ x: [
10485
+ "Ҳ",
10486
+ "Ӿ",
10487
+ "Ӽ",
10488
+ "ӽ"
10489
+ ],
10490
+ y: [
10491
+ "¥",
10492
+ "Ұ",
10493
+ "Ӌ"
10494
+ ],
10495
+ z: ["Ƶ", "ɀ"]
10496
+ };
10497
+ text.forEach(function(c) {
10498
+ c = c.toLowerCase();
10499
+ var chars = trap[c] || [" "];
10500
+ var rand = Math.floor(Math.random() * chars.length);
10501
+ if (typeof trap[c] !== "undefined") result += trap[c][rand];
10502
+ else result += c;
10503
+ });
10504
+ return result;
10505
+ };
10506
+ } });
10507
+
10508
+ //#endregion
10509
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/custom/zalgo.js
10510
+ var require_zalgo = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/custom/zalgo.js"(exports, module) {
10511
+ module["exports"] = function zalgo(text, options) {
10512
+ text = text || " he is here ";
10513
+ var soul = {
10514
+ "up": [
10515
+ "̍",
10516
+ "̎",
10517
+ "̄",
10518
+ "̅",
10519
+ "̿",
10520
+ "̑",
10521
+ "̆",
10522
+ "̐",
10523
+ "͒",
10524
+ "͗",
10525
+ "͑",
10526
+ "̇",
10527
+ "̈",
10528
+ "̊",
10529
+ "͂",
10530
+ "̓",
10531
+ "̈",
10532
+ "͊",
10533
+ "͋",
10534
+ "͌",
10535
+ "̃",
10536
+ "̂",
10537
+ "̌",
10538
+ "͐",
10539
+ "̀",
10540
+ "́",
10541
+ "̋",
10542
+ "̏",
10543
+ "̒",
10544
+ "̓",
10545
+ "̔",
10546
+ "̽",
10547
+ "̉",
10548
+ "ͣ",
10549
+ "ͤ",
10550
+ "ͥ",
10551
+ "ͦ",
10552
+ "ͧ",
10553
+ "ͨ",
10554
+ "ͩ",
10555
+ "ͪ",
10556
+ "ͫ",
10557
+ "ͬ",
10558
+ "ͭ",
10559
+ "ͮ",
10560
+ "ͯ",
10561
+ "̾",
10562
+ "͛",
10563
+ "͆",
10564
+ "̚"
10565
+ ],
10566
+ "down": [
10567
+ "̖",
10568
+ "̗",
10569
+ "̘",
10570
+ "̙",
10571
+ "̜",
10572
+ "̝",
10573
+ "̞",
10574
+ "̟",
10575
+ "̠",
10576
+ "̤",
10577
+ "̥",
10578
+ "̦",
10579
+ "̩",
10580
+ "̪",
10581
+ "̫",
10582
+ "̬",
10583
+ "̭",
10584
+ "̮",
10585
+ "̯",
10586
+ "̰",
10587
+ "̱",
10588
+ "̲",
10589
+ "̳",
10590
+ "̹",
10591
+ "̺",
10592
+ "̻",
10593
+ "̼",
10594
+ "ͅ",
10595
+ "͇",
10596
+ "͈",
10597
+ "͉",
10598
+ "͍",
10599
+ "͎",
10600
+ "͓",
10601
+ "͔",
10602
+ "͕",
10603
+ "͖",
10604
+ "͙",
10605
+ "͚",
10606
+ "̣"
10607
+ ],
10608
+ "mid": [
10609
+ "̕",
10610
+ "̛",
10611
+ "̀",
10612
+ "́",
10613
+ "͘",
10614
+ "̡",
10615
+ "̢",
10616
+ "̧",
10617
+ "̨",
10618
+ "̴",
10619
+ "̵",
10620
+ "̶",
10621
+ "͜",
10622
+ "͝",
10623
+ "͞",
10624
+ "͟",
10625
+ "͠",
10626
+ "͢",
10627
+ "̸",
10628
+ "̷",
10629
+ "͡",
10630
+ " ҉"
10631
+ ]
10632
+ };
10633
+ var all = [].concat(soul.up, soul.down, soul.mid);
10634
+ function randomNumber(range) {
10635
+ var r = Math.floor(Math.random() * range);
10636
+ return r;
10637
+ }
10638
+ function isChar(character) {
10639
+ var bool = false;
10640
+ all.filter(function(i) {
10641
+ bool = i === character;
10642
+ });
10643
+ return bool;
10644
+ }
10645
+ function heComes(text$1, options$1) {
10646
+ var result = "";
10647
+ var counts;
10648
+ var l;
10649
+ options$1 = options$1 || {};
10650
+ options$1["up"] = typeof options$1["up"] !== "undefined" ? options$1["up"] : true;
10651
+ options$1["mid"] = typeof options$1["mid"] !== "undefined" ? options$1["mid"] : true;
10652
+ options$1["down"] = typeof options$1["down"] !== "undefined" ? options$1["down"] : true;
10653
+ options$1["size"] = typeof options$1["size"] !== "undefined" ? options$1["size"] : "maxi";
10654
+ text$1 = text$1.split("");
10655
+ for (l in text$1) {
10656
+ if (isChar(l)) continue;
10657
+ result = result + text$1[l];
10658
+ counts = {
10659
+ "up": 0,
10660
+ "down": 0,
10661
+ "mid": 0
10662
+ };
10663
+ switch (options$1.size) {
10664
+ case "mini":
10665
+ counts.up = randomNumber(8);
10666
+ counts.mid = randomNumber(2);
10667
+ counts.down = randomNumber(8);
10668
+ break;
10669
+ case "maxi":
10670
+ counts.up = randomNumber(16) + 3;
10671
+ counts.mid = randomNumber(4) + 1;
10672
+ counts.down = randomNumber(64) + 3;
10673
+ break;
10674
+ default:
10675
+ counts.up = randomNumber(8) + 1;
10676
+ counts.mid = randomNumber(6) / 2;
10677
+ counts.down = randomNumber(8) + 1;
10678
+ break;
10679
+ }
10680
+ var arr = [
10681
+ "up",
10682
+ "mid",
10683
+ "down"
10684
+ ];
10685
+ for (var d in arr) {
10686
+ var index$1 = arr[d];
10687
+ for (var i = 0; i <= counts[index$1]; i++) if (options$1[index$1]) result = result + soul[index$1][randomNumber(soul[index$1].length)];
10688
+ }
10689
+ }
10690
+ return result;
10691
+ }
10692
+ return heComes(text, options);
10693
+ };
10694
+ } });
10695
+
10696
+ //#endregion
10697
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/maps/america.js
10698
+ var require_america = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/maps/america.js"(exports, module) {
10699
+ module["exports"] = function(colors$2) {
10700
+ return function(letter, i, exploded) {
10701
+ if (letter === " ") return letter;
10702
+ switch (i % 3) {
10703
+ case 0: return colors$2.red(letter);
10704
+ case 1: return colors$2.white(letter);
10705
+ case 2: return colors$2.blue(letter);
10706
+ }
10707
+ };
10708
+ };
10709
+ } });
10710
+
10711
+ //#endregion
10712
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/maps/zebra.js
10713
+ var require_zebra = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/maps/zebra.js"(exports, module) {
10714
+ module["exports"] = function(colors$2) {
10715
+ return function(letter, i, exploded) {
10716
+ return i % 2 === 0 ? letter : colors$2.inverse(letter);
10717
+ };
10718
+ };
10719
+ } });
10720
+
10721
+ //#endregion
10722
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/maps/rainbow.js
10723
+ var require_rainbow = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/maps/rainbow.js"(exports, module) {
10724
+ module["exports"] = function(colors$2) {
10725
+ var rainbowColors = [
10726
+ "red",
10727
+ "yellow",
10728
+ "green",
10729
+ "blue",
10730
+ "magenta"
10731
+ ];
10732
+ return function(letter, i, exploded) {
10733
+ if (letter === " ") return letter;
10734
+ else return colors$2[rainbowColors[i++ % rainbowColors.length]](letter);
10735
+ };
10736
+ };
10737
+ } });
10738
+
10739
+ //#endregion
10740
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/maps/random.js
10741
+ var require_random = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/maps/random.js"(exports, module) {
10742
+ module["exports"] = function(colors$2) {
10743
+ var available = [
10744
+ "underline",
10745
+ "inverse",
10746
+ "grey",
10747
+ "yellow",
10748
+ "red",
10749
+ "green",
10750
+ "blue",
10751
+ "white",
10752
+ "cyan",
10753
+ "magenta",
10754
+ "brightYellow",
10755
+ "brightRed",
10756
+ "brightGreen",
10757
+ "brightBlue",
10758
+ "brightWhite",
10759
+ "brightCyan",
10760
+ "brightMagenta"
10761
+ ];
10762
+ return function(letter, i, exploded) {
10763
+ return letter === " " ? letter : colors$2[available[Math.round(Math.random() * (available.length - 2))]](letter);
10764
+ };
10765
+ };
10766
+ } });
10767
+
10768
+ //#endregion
10769
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/colors.js
10770
+ var require_colors = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/lib/colors.js"(exports, module) {
10771
+ var colors$1 = {};
10772
+ module["exports"] = colors$1;
10773
+ colors$1.themes = {};
10774
+ var util = __require("util");
10775
+ var ansiStyles = colors$1.styles = require_styles();
10776
+ var defineProps = Object.defineProperties;
10777
+ var newLineRegex = new RegExp(/[\r\n]+/g);
10778
+ colors$1.supportsColor = require_supports_colors().supportsColor;
10779
+ if (typeof colors$1.enabled === "undefined") colors$1.enabled = colors$1.supportsColor() !== false;
10780
+ colors$1.enable = function() {
10781
+ colors$1.enabled = true;
10782
+ };
10783
+ colors$1.disable = function() {
10784
+ colors$1.enabled = false;
10785
+ };
10786
+ colors$1.stripColors = colors$1.strip = function(str) {
10787
+ return ("" + str).replace(/\x1B\[\d+m/g, "");
10788
+ };
10789
+ var stylize = colors$1.stylize = function stylize$1(str, style) {
10790
+ if (!colors$1.enabled) return str + "";
10791
+ var styleMap = ansiStyles[style];
10792
+ if (!styleMap && style in colors$1) return colors$1[style](str);
10793
+ return styleMap.open + str + styleMap.close;
10794
+ };
10795
+ var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
10796
+ var escapeStringRegexp = function(str) {
10797
+ if (typeof str !== "string") throw new TypeError("Expected a string");
10798
+ return str.replace(matchOperatorsRe, "\\$&");
10799
+ };
10800
+ function build(_styles) {
10801
+ var builder = function builder$1() {
10802
+ return applyStyle.apply(builder$1, arguments);
10803
+ };
10804
+ builder._styles = _styles;
10805
+ builder.__proto__ = proto;
10806
+ return builder;
10807
+ }
10808
+ var styles = function() {
10809
+ var ret = {};
10810
+ ansiStyles.grey = ansiStyles.gray;
10811
+ Object.keys(ansiStyles).forEach(function(key) {
10812
+ ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), "g");
10813
+ ret[key] = { get: function() {
10814
+ return build(this._styles.concat(key));
10815
+ } };
10816
+ });
10817
+ return ret;
10818
+ }();
10819
+ var proto = defineProps(function colors$2() {}, styles);
10820
+ function applyStyle() {
10821
+ var args = Array.prototype.slice.call(arguments);
10822
+ var str = args.map(function(arg) {
10823
+ if (arg != null && arg.constructor === String) return arg;
10824
+ else return util.inspect(arg);
10825
+ }).join(" ");
10826
+ if (!colors$1.enabled || !str) return str;
10827
+ var newLinesPresent = str.indexOf("\n") != -1;
10828
+ var nestedStyles = this._styles;
10829
+ var i = nestedStyles.length;
10830
+ while (i--) {
10831
+ var code = ansiStyles[nestedStyles[i]];
10832
+ str = code.open + str.replace(code.closeRe, code.open) + code.close;
10833
+ if (newLinesPresent) str = str.replace(newLineRegex, function(match) {
10834
+ return code.close + match + code.open;
10835
+ });
10836
+ }
10837
+ return str;
10838
+ }
10839
+ colors$1.setTheme = function(theme) {
10840
+ if (typeof theme === "string") {
10841
+ console.log("colors.setTheme now only accepts an object, not a string. If you are trying to set a theme from a file, it is now your (the caller's) responsibility to require the file. The old syntax looked like colors.setTheme(__dirname + '/../themes/generic-logging.js'); The new syntax looks like colors.setTheme(require(__dirname + '/../themes/generic-logging.js'));");
10842
+ return;
10843
+ }
10844
+ for (var style in theme) (function(style$1) {
10845
+ colors$1[style$1] = function(str) {
10846
+ if (typeof theme[style$1] === "object") {
10847
+ var out = str;
10848
+ for (var i in theme[style$1]) out = colors$1[theme[style$1][i]](out);
10849
+ return out;
10850
+ }
10851
+ return colors$1[theme[style$1]](str);
10852
+ };
10853
+ })(style);
10854
+ };
10855
+ function init() {
10856
+ var ret = {};
10857
+ Object.keys(styles).forEach(function(name) {
10858
+ ret[name] = { get: function() {
10859
+ return build([name]);
10860
+ } };
10861
+ });
10862
+ return ret;
10863
+ }
10864
+ var sequencer = function sequencer$1(map$1, str) {
10865
+ var exploded = str.split("");
10866
+ exploded = exploded.map(map$1);
10867
+ return exploded.join("");
10868
+ };
10869
+ colors$1.trap = require_trap();
10870
+ colors$1.zalgo = require_zalgo();
10871
+ colors$1.maps = {};
10872
+ colors$1.maps.america = require_america()(colors$1);
10873
+ colors$1.maps.zebra = require_zebra()(colors$1);
10874
+ colors$1.maps.rainbow = require_rainbow()(colors$1);
10875
+ colors$1.maps.random = require_random()(colors$1);
10876
+ for (var map in colors$1.maps) (function(map$1) {
10877
+ colors$1[map$1] = function(str) {
10878
+ return sequencer(colors$1.maps[map$1], str);
10879
+ };
10880
+ })(map);
10881
+ defineProps(colors$1, init());
10882
+ } });
10883
+
10884
+ //#endregion
10885
+ //#region ../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/safe.js
10886
+ var require_safe = __commonJS({ "../../../node_modules/.bun/@colors+colors@1.5.0/node_modules/@colors/colors/safe.js"(exports, module) {
10887
+ var colors = require_colors();
10888
+ module["exports"] = colors;
10889
+ } });
10890
+
10891
+ //#endregion
10892
+ //#region ../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/cell.js
10893
+ var require_cell = __commonJS({ "../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/cell.js"(exports, module) {
10894
+ const { info, debug: debug$2 } = require_debug();
10895
+ const utils$1 = require_utils();
10896
+ var Cell$1 = class Cell$1 {
10897
+ /**
10898
+ * A representation of a cell within the table.
10899
+ * Implementations must have `init` and `draw` methods,
10900
+ * as well as `colSpan`, `rowSpan`, `desiredHeight` and `desiredWidth` properties.
10901
+ * @param options
10902
+ * @constructor
10903
+ */
10904
+ constructor(options) {
10905
+ this.setOptions(options);
10906
+ /**
10907
+ * Each cell will have it's `x` and `y` values set by the `layout-manager` prior to
10908
+ * `init` being called;
10909
+ * @type {Number}
10910
+ */
10911
+ this.x = null;
10912
+ this.y = null;
10913
+ }
10914
+ setOptions(options) {
10915
+ if ([
10916
+ "boolean",
10917
+ "number",
10918
+ "bigint",
10919
+ "string"
10920
+ ].indexOf(typeof options) !== -1) options = { content: "" + options };
10921
+ options = options || {};
10922
+ this.options = options;
10923
+ let content = options.content;
10924
+ if ([
10925
+ "boolean",
10926
+ "number",
10927
+ "bigint",
10928
+ "string"
10929
+ ].indexOf(typeof content) !== -1) this.content = String(content);
10930
+ else if (!content) this.content = this.options.href || "";
10931
+ else throw new Error("Content needs to be a primitive, got: " + typeof content);
10932
+ this.colSpan = options.colSpan || 1;
10933
+ this.rowSpan = options.rowSpan || 1;
10934
+ if (this.options.href) Object.defineProperty(this, "href", { get() {
10935
+ return this.options.href;
10936
+ } });
10937
+ }
10938
+ mergeTableOptions(tableOptions, cells) {
10939
+ this.cells = cells;
10940
+ let optionsChars = this.options.chars || {};
10941
+ let tableChars = tableOptions.chars;
10942
+ let chars = this.chars = {};
10943
+ CHAR_NAMES.forEach(function(name) {
10944
+ setOption(optionsChars, tableChars, name, chars);
10945
+ });
10946
+ this.truncate = this.options.truncate || tableOptions.truncate;
10947
+ let style = this.options.style = this.options.style || {};
10948
+ let tableStyle = tableOptions.style;
10949
+ setOption(style, tableStyle, "padding-left", this);
10950
+ setOption(style, tableStyle, "padding-right", this);
10951
+ this.head = style.head || tableStyle.head;
10952
+ this.border = style.border || tableStyle.border;
10953
+ this.fixedWidth = tableOptions.colWidths[this.x];
10954
+ this.lines = this.computeLines(tableOptions);
10955
+ this.desiredWidth = utils$1.strlen(this.content) + this.paddingLeft + this.paddingRight;
10956
+ this.desiredHeight = this.lines.length;
10957
+ }
10958
+ computeLines(tableOptions) {
10959
+ const tableWordWrap = tableOptions.wordWrap || tableOptions.textWrap;
10960
+ const { wordWrap: wordWrap$1 = tableWordWrap } = this.options;
10961
+ if (this.fixedWidth && wordWrap$1) {
10962
+ this.fixedWidth -= this.paddingLeft + this.paddingRight;
10963
+ if (this.colSpan) {
10964
+ let i = 1;
10965
+ while (i < this.colSpan) {
10966
+ this.fixedWidth += tableOptions.colWidths[this.x + i];
10967
+ i++;
10968
+ }
10969
+ }
10970
+ const { wrapOnWordBoundary: tableWrapOnWordBoundary = true } = tableOptions;
10971
+ const { wrapOnWordBoundary = tableWrapOnWordBoundary } = this.options;
10972
+ return this.wrapLines(utils$1.wordWrap(this.fixedWidth, this.content, wrapOnWordBoundary));
10973
+ }
10974
+ return this.wrapLines(this.content.split("\n"));
10975
+ }
10976
+ wrapLines(computedLines) {
10977
+ const lines = utils$1.colorizeLines(computedLines);
10978
+ if (this.href) return lines.map((line) => utils$1.hyperlink(this.href, line));
10979
+ return lines;
10980
+ }
10981
+ /**
10982
+ * Initializes the Cells data structure.
10983
+ *
10984
+ * @param tableOptions - A fully populated set of tableOptions.
10985
+ * In addition to the standard default values, tableOptions must have fully populated the
10986
+ * `colWidths` and `rowWidths` arrays. Those arrays must have lengths equal to the number
10987
+ * of columns or rows (respectively) in this table, and each array item must be a Number.
10988
+ *
10989
+ */
10990
+ init(tableOptions) {
10991
+ let x = this.x;
10992
+ let y = this.y;
10993
+ this.widths = tableOptions.colWidths.slice(x, x + this.colSpan);
10994
+ this.heights = tableOptions.rowHeights.slice(y, y + this.rowSpan);
10995
+ this.width = this.widths.reduce(sumPlusOne, -1);
10996
+ this.height = this.heights.reduce(sumPlusOne, -1);
10997
+ this.hAlign = this.options.hAlign || tableOptions.colAligns[x];
10998
+ this.vAlign = this.options.vAlign || tableOptions.rowAligns[y];
10999
+ this.drawRight = x + this.colSpan == tableOptions.colWidths.length;
11000
+ }
11001
+ /**
11002
+ * Draws the given line of the cell.
11003
+ * This default implementation defers to methods `drawTop`, `drawBottom`, `drawLine` and `drawEmpty`.
11004
+ * @param lineNum - can be `top`, `bottom` or a numerical line number.
11005
+ * @param spanningCell - will be a number if being called from a RowSpanCell, and will represent how
11006
+ * many rows below it's being called from. Otherwise it's undefined.
11007
+ * @returns {String} The representation of this line.
11008
+ */
11009
+ draw(lineNum, spanningCell) {
11010
+ if (lineNum == "top") return this.drawTop(this.drawRight);
11011
+ if (lineNum == "bottom") return this.drawBottom(this.drawRight);
11012
+ let content = utils$1.truncate(this.content, 10, this.truncate);
11013
+ if (!lineNum) info(`${this.y}-${this.x}: ${this.rowSpan - lineNum}x${this.colSpan} Cell ${content}`);
11014
+ let padLen = Math.max(this.height - this.lines.length, 0);
11015
+ let padTop;
11016
+ switch (this.vAlign) {
11017
+ case "center":
11018
+ padTop = Math.ceil(padLen / 2);
11019
+ break;
11020
+ case "bottom":
11021
+ padTop = padLen;
11022
+ break;
11023
+ default: padTop = 0;
11024
+ }
11025
+ if (lineNum < padTop || lineNum >= padTop + this.lines.length) return this.drawEmpty(this.drawRight, spanningCell);
11026
+ let forceTruncation = this.lines.length > this.height && lineNum + 1 >= this.height;
11027
+ return this.drawLine(lineNum - padTop, this.drawRight, forceTruncation, spanningCell);
11028
+ }
11029
+ /**
11030
+ * Renders the top line of the cell.
11031
+ * @param drawRight - true if this method should render the right edge of the cell.
11032
+ * @returns {String}
11033
+ */
11034
+ drawTop(drawRight) {
11035
+ let content = [];
11036
+ if (this.cells) this.widths.forEach(function(width, index$1) {
11037
+ content.push(this._topLeftChar(index$1));
11038
+ content.push(utils$1.repeat(this.chars[this.y == 0 ? "top" : "mid"], width));
11039
+ }, this);
11040
+ else {
11041
+ content.push(this._topLeftChar(0));
11042
+ content.push(utils$1.repeat(this.chars[this.y == 0 ? "top" : "mid"], this.width));
11043
+ }
11044
+ if (drawRight) content.push(this.chars[this.y == 0 ? "topRight" : "rightMid"]);
11045
+ return this.wrapWithStyleColors("border", content.join(""));
11046
+ }
11047
+ _topLeftChar(offset) {
11048
+ let x = this.x + offset;
11049
+ let leftChar;
11050
+ if (this.y == 0) leftChar = x == 0 ? "topLeft" : offset == 0 ? "topMid" : "top";
11051
+ else if (x == 0) leftChar = "leftMid";
11052
+ else {
11053
+ leftChar = offset == 0 ? "midMid" : "bottomMid";
11054
+ if (this.cells) {
11055
+ let spanAbove = this.cells[this.y - 1][x] instanceof Cell$1.ColSpanCell;
11056
+ if (spanAbove) leftChar = offset == 0 ? "topMid" : "mid";
11057
+ if (offset == 0) {
11058
+ let i = 1;
11059
+ while (this.cells[this.y][x - i] instanceof Cell$1.ColSpanCell) i++;
11060
+ if (this.cells[this.y][x - i] instanceof Cell$1.RowSpanCell) leftChar = "leftMid";
11061
+ }
11062
+ }
11063
+ }
11064
+ return this.chars[leftChar];
11065
+ }
11066
+ wrapWithStyleColors(styleProperty, content) {
11067
+ if (this[styleProperty] && this[styleProperty].length) try {
11068
+ let colors$2 = require_safe();
11069
+ for (let i = this[styleProperty].length - 1; i >= 0; i--) colors$2 = colors$2[this[styleProperty][i]];
11070
+ return colors$2(content);
11071
+ } catch (e) {
11072
+ return content;
11073
+ }
11074
+ else return content;
11075
+ }
11076
+ /**
11077
+ * Renders a line of text.
11078
+ * @param lineNum - Which line of text to render. This is not necessarily the line within the cell.
11079
+ * There may be top-padding above the first line of text.
11080
+ * @param drawRight - true if this method should render the right edge of the cell.
11081
+ * @param forceTruncationSymbol - `true` if the rendered text should end with the truncation symbol even
11082
+ * if the text fits. This is used when the cell is vertically truncated. If `false` the text should
11083
+ * only include the truncation symbol if the text will not fit horizontally within the cell width.
11084
+ * @param spanningCell - a number of if being called from a RowSpanCell. (how many rows below). otherwise undefined.
11085
+ * @returns {String}
11086
+ */
11087
+ drawLine(lineNum, drawRight, forceTruncationSymbol, spanningCell) {
11088
+ let left = this.chars[this.x == 0 ? "left" : "middle"];
11089
+ if (this.x && spanningCell && this.cells) {
11090
+ let cellLeft = this.cells[this.y + spanningCell][this.x - 1];
11091
+ while (cellLeft instanceof ColSpanCell$1) cellLeft = this.cells[cellLeft.y][cellLeft.x - 1];
11092
+ if (!(cellLeft instanceof RowSpanCell$1)) left = this.chars["rightMid"];
11093
+ }
11094
+ let leftPadding = utils$1.repeat(" ", this.paddingLeft);
11095
+ let right = drawRight ? this.chars["right"] : "";
11096
+ let rightPadding = utils$1.repeat(" ", this.paddingRight);
11097
+ let line = this.lines[lineNum];
11098
+ let len = this.width - (this.paddingLeft + this.paddingRight);
11099
+ if (forceTruncationSymbol) line += this.truncate || "…";
11100
+ let content = utils$1.truncate(line, len, this.truncate);
11101
+ content = utils$1.pad(content, len, " ", this.hAlign);
11102
+ content = leftPadding + content + rightPadding;
11103
+ return this.stylizeLine(left, content, right);
11104
+ }
11105
+ stylizeLine(left, content, right) {
11106
+ left = this.wrapWithStyleColors("border", left);
11107
+ right = this.wrapWithStyleColors("border", right);
11108
+ if (this.y === 0) content = this.wrapWithStyleColors("head", content);
11109
+ return left + content + right;
11110
+ }
11111
+ /**
11112
+ * Renders the bottom line of the cell.
11113
+ * @param drawRight - true if this method should render the right edge of the cell.
11114
+ * @returns {String}
11115
+ */
11116
+ drawBottom(drawRight) {
11117
+ let left = this.chars[this.x == 0 ? "bottomLeft" : "bottomMid"];
11118
+ let content = utils$1.repeat(this.chars.bottom, this.width);
11119
+ let right = drawRight ? this.chars["bottomRight"] : "";
11120
+ return this.wrapWithStyleColors("border", left + content + right);
11121
+ }
11122
+ /**
11123
+ * Renders a blank line of text within the cell. Used for top and/or bottom padding.
11124
+ * @param drawRight - true if this method should render the right edge of the cell.
11125
+ * @param spanningCell - a number of if being called from a RowSpanCell. (how many rows below). otherwise undefined.
11126
+ * @returns {String}
11127
+ */
11128
+ drawEmpty(drawRight, spanningCell) {
11129
+ let left = this.chars[this.x == 0 ? "left" : "middle"];
11130
+ if (this.x && spanningCell && this.cells) {
11131
+ let cellLeft = this.cells[this.y + spanningCell][this.x - 1];
11132
+ while (cellLeft instanceof ColSpanCell$1) cellLeft = this.cells[cellLeft.y][cellLeft.x - 1];
11133
+ if (!(cellLeft instanceof RowSpanCell$1)) left = this.chars["rightMid"];
11134
+ }
11135
+ let right = drawRight ? this.chars["right"] : "";
11136
+ let content = utils$1.repeat(" ", this.width);
11137
+ return this.stylizeLine(left, content, right);
11138
+ }
11139
+ };
11140
+ var ColSpanCell$1 = class {
11141
+ /**
11142
+ * A Cell that doesn't do anything. It just draws empty lines.
11143
+ * Used as a placeholder in column spanning.
11144
+ * @constructor
11145
+ */
11146
+ constructor() {}
11147
+ draw(lineNum) {
11148
+ if (typeof lineNum === "number") debug$2(`${this.y}-${this.x}: 1x1 ColSpanCell`);
11149
+ return "";
11150
+ }
11151
+ init() {}
11152
+ mergeTableOptions() {}
11153
+ };
11154
+ var RowSpanCell$1 = class {
11155
+ /**
11156
+ * A placeholder Cell for a Cell that spans multiple rows.
11157
+ * It delegates rendering to the original cell, but adds the appropriate offset.
11158
+ * @param originalCell
11159
+ * @constructor
11160
+ */
11161
+ constructor(originalCell) {
11162
+ this.originalCell = originalCell;
11163
+ }
11164
+ init(tableOptions) {
11165
+ let y = this.y;
11166
+ let originalY = this.originalCell.y;
11167
+ this.cellOffset = y - originalY;
11168
+ this.offset = findDimension(tableOptions.rowHeights, originalY, this.cellOffset);
11169
+ }
11170
+ draw(lineNum) {
11171
+ if (lineNum == "top") return this.originalCell.draw(this.offset, this.cellOffset);
11172
+ if (lineNum == "bottom") return this.originalCell.draw("bottom");
11173
+ debug$2(`${this.y}-${this.x}: 1x${this.colSpan} RowSpanCell for ${this.originalCell.content}`);
11174
+ return this.originalCell.draw(this.offset + 1 + lineNum);
11175
+ }
11176
+ mergeTableOptions() {}
11177
+ };
11178
+ function firstDefined(...args) {
11179
+ return args.filter((v) => v !== void 0 && v !== null).shift();
11180
+ }
11181
+ function setOption(objA, objB, nameB, targetObj) {
11182
+ let nameA = nameB.split("-");
11183
+ if (nameA.length > 1) {
11184
+ nameA[1] = nameA[1].charAt(0).toUpperCase() + nameA[1].substr(1);
11185
+ nameA = nameA.join("");
11186
+ targetObj[nameA] = firstDefined(objA[nameA], objA[nameB], objB[nameA], objB[nameB]);
11187
+ } else targetObj[nameB] = firstDefined(objA[nameB], objB[nameB]);
11188
+ }
11189
+ function findDimension(dimensionTable, startingIndex, span) {
11190
+ let ret = dimensionTable[startingIndex];
11191
+ for (let i = 1; i < span; i++) ret += 1 + dimensionTable[startingIndex + i];
11192
+ return ret;
11193
+ }
11194
+ function sumPlusOne(a, b) {
11195
+ return a + b + 1;
11196
+ }
11197
+ let CHAR_NAMES = [
11198
+ "top",
11199
+ "top-mid",
11200
+ "top-left",
11201
+ "top-right",
11202
+ "bottom",
11203
+ "bottom-mid",
11204
+ "bottom-left",
11205
+ "bottom-right",
11206
+ "left",
11207
+ "left-mid",
11208
+ "mid",
11209
+ "mid-mid",
11210
+ "right",
11211
+ "right-mid",
11212
+ "middle"
11213
+ ];
11214
+ module.exports = Cell$1;
11215
+ module.exports.ColSpanCell = ColSpanCell$1;
11216
+ module.exports.RowSpanCell = RowSpanCell$1;
11217
+ } });
11218
+
11219
+ //#endregion
11220
+ //#region ../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/layout-manager.js
11221
+ var require_layout_manager = __commonJS({ "../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/layout-manager.js"(exports, module) {
11222
+ const { warn, debug: debug$1 } = require_debug();
11223
+ const Cell = require_cell();
11224
+ const { ColSpanCell, RowSpanCell } = Cell;
11225
+ (function() {
11226
+ function next(alloc, col) {
11227
+ if (alloc[col] > 0) return next(alloc, col + 1);
11228
+ return col;
11229
+ }
11230
+ function layoutTable(table) {
11231
+ let alloc = {};
11232
+ table.forEach(function(row, rowIndex) {
11233
+ let col = 0;
11234
+ row.forEach(function(cell) {
11235
+ cell.y = rowIndex;
11236
+ cell.x = rowIndex ? next(alloc, col) : col;
11237
+ const rowSpan = cell.rowSpan || 1;
11238
+ const colSpan = cell.colSpan || 1;
11239
+ if (rowSpan > 1) for (let cs = 0; cs < colSpan; cs++) alloc[cell.x + cs] = rowSpan;
11240
+ col = cell.x + colSpan;
11241
+ });
11242
+ Object.keys(alloc).forEach((idx) => {
11243
+ alloc[idx]--;
11244
+ if (alloc[idx] < 1) delete alloc[idx];
11245
+ });
11246
+ });
11247
+ }
11248
+ function maxWidth(table) {
11249
+ let mw = 0;
11250
+ table.forEach(function(row) {
11251
+ row.forEach(function(cell) {
11252
+ mw = Math.max(mw, cell.x + (cell.colSpan || 1));
11253
+ });
11254
+ });
11255
+ return mw;
11256
+ }
11257
+ function maxHeight(table) {
11258
+ return table.length;
11259
+ }
11260
+ function cellsConflict(cell1, cell2) {
11261
+ let yMin1 = cell1.y;
11262
+ let yMax1 = cell1.y - 1 + (cell1.rowSpan || 1);
11263
+ let yMin2 = cell2.y;
11264
+ let yMax2 = cell2.y - 1 + (cell2.rowSpan || 1);
11265
+ let yConflict = !(yMin1 > yMax2 || yMin2 > yMax1);
11266
+ let xMin1 = cell1.x;
11267
+ let xMax1 = cell1.x - 1 + (cell1.colSpan || 1);
11268
+ let xMin2 = cell2.x;
11269
+ let xMax2 = cell2.x - 1 + (cell2.colSpan || 1);
11270
+ let xConflict = !(xMin1 > xMax2 || xMin2 > xMax1);
11271
+ return yConflict && xConflict;
11272
+ }
11273
+ function conflictExists(rows, x, y) {
11274
+ let i_max = Math.min(rows.length - 1, y);
11275
+ let cell = {
11276
+ x,
11277
+ y
11278
+ };
11279
+ for (let i = 0; i <= i_max; i++) {
11280
+ let row = rows[i];
11281
+ for (let j = 0; j < row.length; j++) if (cellsConflict(cell, row[j])) return true;
11282
+ }
11283
+ return false;
11284
+ }
11285
+ function allBlank(rows, y, xMin, xMax) {
11286
+ for (let x = xMin; x < xMax; x++) if (conflictExists(rows, x, y)) return false;
11287
+ return true;
11288
+ }
11289
+ function addRowSpanCells(table) {
11290
+ table.forEach(function(row, rowIndex) {
11291
+ row.forEach(function(cell) {
11292
+ for (let i = 1; i < cell.rowSpan; i++) {
11293
+ let rowSpanCell = new RowSpanCell(cell);
11294
+ rowSpanCell.x = cell.x;
11295
+ rowSpanCell.y = cell.y + i;
11296
+ rowSpanCell.colSpan = cell.colSpan;
11297
+ insertCell(rowSpanCell, table[rowIndex + i]);
11298
+ }
11299
+ });
11300
+ });
11301
+ }
11302
+ function addColSpanCells(cellRows) {
11303
+ for (let rowIndex = cellRows.length - 1; rowIndex >= 0; rowIndex--) {
11304
+ let cellColumns = cellRows[rowIndex];
11305
+ for (let columnIndex = 0; columnIndex < cellColumns.length; columnIndex++) {
11306
+ let cell = cellColumns[columnIndex];
11307
+ for (let k = 1; k < cell.colSpan; k++) {
11308
+ let colSpanCell = new ColSpanCell();
11309
+ colSpanCell.x = cell.x + k;
11310
+ colSpanCell.y = cell.y;
11311
+ cellColumns.splice(columnIndex + 1, 0, colSpanCell);
11312
+ }
11313
+ }
11314
+ }
11315
+ }
11316
+ function insertCell(cell, row) {
11317
+ let x = 0;
11318
+ while (x < row.length && row[x].x < cell.x) x++;
11319
+ row.splice(x, 0, cell);
11320
+ }
11321
+ function fillInTable(table) {
11322
+ let h_max = maxHeight(table);
11323
+ let w_max = maxWidth(table);
11324
+ debug$1(`Max rows: ${h_max}; Max cols: ${w_max}`);
11325
+ for (let y = 0; y < h_max; y++) for (let x = 0; x < w_max; x++) if (!conflictExists(table, x, y)) {
11326
+ let opts = {
11327
+ x,
11328
+ y,
11329
+ colSpan: 1,
11330
+ rowSpan: 1
11331
+ };
11332
+ x++;
11333
+ while (x < w_max && !conflictExists(table, x, y)) {
11334
+ opts.colSpan++;
11335
+ x++;
11336
+ }
11337
+ let y2 = y + 1;
11338
+ while (y2 < h_max && allBlank(table, y2, opts.x, opts.x + opts.colSpan)) {
11339
+ opts.rowSpan++;
11340
+ y2++;
11341
+ }
11342
+ let cell = new Cell(opts);
11343
+ cell.x = opts.x;
11344
+ cell.y = opts.y;
11345
+ warn(`Missing cell at ${cell.y}-${cell.x}.`);
11346
+ insertCell(cell, table[y]);
11347
+ }
11348
+ }
11349
+ function generateCells(rows) {
11350
+ return rows.map(function(row) {
11351
+ if (!Array.isArray(row)) {
11352
+ let key = Object.keys(row)[0];
11353
+ row = row[key];
11354
+ if (Array.isArray(row)) {
11355
+ row = row.slice();
11356
+ row.unshift(key);
11357
+ } else row = [key, row];
11358
+ }
11359
+ return row.map(function(cell) {
11360
+ return new Cell(cell);
11361
+ });
11362
+ });
11363
+ }
11364
+ function makeTableLayout(rows) {
11365
+ let cellRows = generateCells(rows);
11366
+ layoutTable(cellRows);
11367
+ fillInTable(cellRows);
11368
+ addRowSpanCells(cellRows);
11369
+ addColSpanCells(cellRows);
11370
+ return cellRows;
11371
+ }
11372
+ module.exports = {
11373
+ makeTableLayout,
11374
+ layoutTable,
11375
+ addRowSpanCells,
11376
+ maxWidth,
11377
+ fillInTable,
11378
+ computeWidths: makeComputeWidths("colSpan", "desiredWidth", "x", 1),
11379
+ computeHeights: makeComputeWidths("rowSpan", "desiredHeight", "y", 1)
11380
+ };
11381
+ })();
11382
+ function makeComputeWidths(colSpan, desiredWidth, x, forcedMin) {
11383
+ return function(vals, table) {
11384
+ let result = [];
11385
+ let spanners = [];
11386
+ let auto = {};
11387
+ table.forEach(function(row) {
11388
+ row.forEach(function(cell) {
11389
+ if ((cell[colSpan] || 1) > 1) spanners.push(cell);
11390
+ else result[cell[x]] = Math.max(result[cell[x]] || 0, cell[desiredWidth] || 0, forcedMin);
11391
+ });
11392
+ });
11393
+ vals.forEach(function(val, index$1) {
11394
+ if (typeof val === "number") result[index$1] = val;
11395
+ });
11396
+ for (let k = spanners.length - 1; k >= 0; k--) {
11397
+ let cell = spanners[k];
11398
+ let span = cell[colSpan];
11399
+ let col = cell[x];
11400
+ let existingWidth = result[col];
11401
+ let editableCols = typeof vals[col] === "number" ? 0 : 1;
11402
+ if (typeof existingWidth === "number") for (let i = 1; i < span; i++) {
11403
+ existingWidth += 1 + result[col + i];
11404
+ if (typeof vals[col + i] !== "number") editableCols++;
11405
+ }
11406
+ else {
11407
+ existingWidth = desiredWidth === "desiredWidth" ? cell.desiredWidth - 1 : 1;
11408
+ if (!auto[col] || auto[col] < existingWidth) auto[col] = existingWidth;
11409
+ }
11410
+ if (cell[desiredWidth] > existingWidth) {
11411
+ let i = 0;
11412
+ while (editableCols > 0 && cell[desiredWidth] > existingWidth) {
11413
+ if (typeof vals[col + i] !== "number") {
11414
+ let dif = Math.round((cell[desiredWidth] - existingWidth) / editableCols);
11415
+ existingWidth += dif;
11416
+ result[col + i] += dif;
11417
+ editableCols--;
11418
+ }
11419
+ i++;
11420
+ }
11421
+ }
11422
+ }
11423
+ Object.assign(vals, result, auto);
11424
+ for (let j = 0; j < vals.length; j++) vals[j] = Math.max(forcedMin, vals[j] || 0);
11425
+ };
11426
+ }
11427
+ } });
11428
+
11429
+ //#endregion
11430
+ //#region ../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/table.js
11431
+ var require_table = __commonJS({ "../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/table.js"(exports, module) {
11432
+ const debug = require_debug();
11433
+ const utils = require_utils();
11434
+ const tableLayout = require_layout_manager();
11435
+ var Table$1 = class extends Array {
11436
+ constructor(opts) {
11437
+ super();
11438
+ const options = utils.mergeOptions(opts);
11439
+ Object.defineProperty(this, "options", {
11440
+ value: options,
11441
+ enumerable: options.debug
11442
+ });
11443
+ if (options.debug) {
11444
+ switch (typeof options.debug) {
11445
+ case "boolean":
11446
+ debug.setDebugLevel(debug.WARN);
11447
+ break;
11448
+ case "number":
11449
+ debug.setDebugLevel(options.debug);
11450
+ break;
11451
+ case "string":
11452
+ debug.setDebugLevel(parseInt(options.debug, 10));
11453
+ break;
11454
+ default:
11455
+ debug.setDebugLevel(debug.WARN);
11456
+ debug.warn(`Debug option is expected to be boolean, number, or string. Received a ${typeof options.debug}`);
11457
+ }
11458
+ Object.defineProperty(this, "messages", { get() {
11459
+ return debug.debugMessages();
11460
+ } });
11461
+ }
11462
+ }
11463
+ toString() {
11464
+ let array = this;
11465
+ let headersPresent = this.options.head && this.options.head.length;
11466
+ if (headersPresent) {
11467
+ array = [this.options.head];
11468
+ if (this.length) array.push.apply(array, this);
11469
+ } else this.options.style.head = [];
11470
+ let cells = tableLayout.makeTableLayout(array);
11471
+ cells.forEach(function(row) {
11472
+ row.forEach(function(cell) {
11473
+ cell.mergeTableOptions(this.options, cells);
11474
+ }, this);
11475
+ }, this);
11476
+ tableLayout.computeWidths(this.options.colWidths, cells);
11477
+ tableLayout.computeHeights(this.options.rowHeights, cells);
11478
+ cells.forEach(function(row) {
11479
+ row.forEach(function(cell) {
11480
+ cell.init(this.options);
11481
+ }, this);
11482
+ }, this);
11483
+ let result = [];
11484
+ for (let rowIndex = 0; rowIndex < cells.length; rowIndex++) {
11485
+ let row = cells[rowIndex];
11486
+ let heightOfRow = this.options.rowHeights[rowIndex];
11487
+ if (rowIndex === 0 || !this.options.style.compact || rowIndex == 1 && headersPresent) doDraw(row, "top", result);
11488
+ for (let lineNum = 0; lineNum < heightOfRow; lineNum++) doDraw(row, lineNum, result);
11489
+ if (rowIndex + 1 == cells.length) doDraw(row, "bottom", result);
11490
+ }
11491
+ return result.join("\n");
11492
+ }
11493
+ get width() {
11494
+ let str = this.toString().split("\n");
11495
+ return str[0].length;
11496
+ }
11497
+ };
11498
+ Table$1.reset = () => debug.reset();
11499
+ function doDraw(row, lineNum, result) {
11500
+ let line = [];
11501
+ row.forEach(function(cell) {
11502
+ line.push(cell.draw(lineNum));
11503
+ });
11504
+ let str = line.join("");
11505
+ if (str.length) result.push(str);
11506
+ }
11507
+ module.exports = Table$1;
11508
+ } });
11509
+
11510
+ //#endregion
11511
+ //#region ../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/index.js
11512
+ var require_cli_table3 = __commonJS({ "../../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/index.js"(exports, module) {
11513
+ module.exports = require_table();
11514
+ } });
11515
+
11516
+ //#endregion
11517
+ //#region src/utils/format.ts
11518
+ var import_cli_table3 = __toESM(require_cli_table3(), 1);
11519
+ /**
11520
+ * Validates a port number string (single or comma-separated).
11521
+ * Valid: "3000", "3000,3001", "80,443,8080"
11522
+ * Invalid: "abc", "99999", "0", "-1", "3000,", ",3000"
11523
+ *
11524
+ * @param ports - Port string to validate
11525
+ * @returns Object with valid flag, parsed ports, and error message
11526
+ */
11527
+ function validatePorts(ports) {
11528
+ if (!ports || !ports.trim()) return {
11529
+ valid: false,
11530
+ ports: [],
11531
+ error: "Port string is empty"
11532
+ };
11533
+ const parts = ports.split(",").map((p) => p.trim());
11534
+ const parsed = [];
11535
+ for (const part of parts) {
11536
+ if (!/^\d+$/.test(part)) return {
11537
+ valid: false,
11538
+ ports: [],
11539
+ error: `Invalid port "${part}" — must be a number`
11540
+ };
11541
+ const num = parseInt(part, 10);
11542
+ if (num < 1 || num > 65535) return {
11543
+ valid: false,
11544
+ ports: [],
11545
+ error: `Port ${num} out of range (1-65535)`
11546
+ };
11547
+ parsed.push(num);
11548
+ }
11549
+ const dupes = parsed.filter((p, i) => parsed.indexOf(p) !== i);
11550
+ if (dupes.length > 0) return {
11551
+ valid: false,
11552
+ ports: parsed,
11553
+ error: `Duplicate port: ${dupes[0]}`
11554
+ };
11555
+ return {
11556
+ valid: true,
11557
+ ports: parsed
11558
+ };
11559
+ }
11560
+ /**
11561
+ * Validates a .coolify.json state object (single-app format).
11562
+ * Checks required fields, types, and port validity.
11563
+ *
11564
+ * @param state - The parsed JSON object
11565
+ * @returns Object with valid flag, warnings, and errors
11566
+ */
11567
+ function validateCoolifyState(state) {
11568
+ const errors = [];
11569
+ const warnings = [];
11570
+ const isMultiApp = Array.isArray(state.apps);
11571
+ const isSingleApp = typeof state.appUuid === "string";
11572
+ if (!isMultiApp && !isSingleApp) {
11573
+ errors.push("Invalid format: must have \"appUuid\" (single-app) or \"apps\" array (multi-app)");
11574
+ return {
11575
+ valid: false,
11576
+ errors,
11577
+ warnings
11578
+ };
11579
+ }
11580
+ const commonRequired = [
11581
+ "serverUuid",
11582
+ "projectUuid",
11583
+ "environmentUuid"
11584
+ ];
11585
+ for (const field of commonRequired) if (!state[field] || typeof state[field] !== "string") errors.push(`Missing or invalid required field: ${field}`);
11586
+ if (isSingleApp) {
11587
+ if (state.portsExposes && typeof state.portsExposes === "string") {
11588
+ const portResult = validatePorts(state.portsExposes);
11589
+ if (!portResult.valid) warnings.push(`portsExposes: ${portResult.error}`);
11590
+ }
11591
+ if (state.buildPack && typeof state.buildPack === "string") {
11592
+ const validBuildPacks = [
11593
+ "dockerfile",
11594
+ "nixpacks",
11595
+ "static",
11596
+ "dockercompose"
11597
+ ];
11598
+ if (!validBuildPacks.includes(state.buildPack)) warnings.push(`Unknown buildPack "${state.buildPack}" — expected: ${validBuildPacks.join(", ")}`);
11599
+ }
11600
+ }
11601
+ if (isMultiApp) {
11602
+ const apps = state.apps;
11603
+ if (apps.length === 0) errors.push("Multi-app format requires at least one app");
11604
+ for (let i = 0; i < apps.length; i++) {
11605
+ const app = apps[i];
11606
+ if (!app.uuid || typeof app.uuid !== "string") errors.push(`apps[${i}]: missing or invalid "uuid"`);
11607
+ if (!app.name || typeof app.name !== "string") errors.push(`apps[${i}]: missing or invalid "name"`);
11608
+ if (!app.service || typeof app.service !== "string") errors.push(`apps[${i}]: missing or invalid "service"`);
11609
+ if (app.port !== void 0) {
11610
+ const port = app.port;
11611
+ if (typeof port !== "number" || port < 1 || port > 65535) warnings.push(`apps[${i}] (${app.name}): invalid port ${port}`);
11612
+ }
11613
+ }
11614
+ const uuids = apps.map((a) => a.uuid).filter(Boolean);
11615
+ const dupeUuids = uuids.filter((u, i) => uuids.indexOf(u) !== i);
11616
+ if (dupeUuids.length > 0) errors.push(`Duplicate app UUIDs: ${dupeUuids.join(", ")}`);
11617
+ }
11618
+ return {
11619
+ valid: errors.length === 0,
11620
+ errors,
11621
+ warnings
11622
+ };
11623
+ }
11624
+
9566
11625
  //#endregion
9567
11626
  //#region src/cli/coolify-state.ts
9568
11627
  const STATE_FILE = ".coolify.json";
@@ -9602,6 +11661,9 @@ function loadCoolifyState() {
9602
11661
  return null;
9603
11662
  }
9604
11663
  if (!state.appUuid) return null;
11664
+ const validation = validateCoolifyState(state);
11665
+ if (!validation.valid) console.error(`Warning: .coolify.json has errors: ${validation.errors.join("; ")}`);
11666
+ if (validation.warnings.length > 0) for (const w of validation.warnings) console.error(`Warning: .coolify.json — ${w}`);
9605
11667
  return state;
9606
11668
  } catch {
9607
11669
  return null;