@nmakarov/cli-toolkit 0.75.0 → 0.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1433,6 +1433,7 @@ __export(src_exports, {
1433
1433
  npmInstallEnv: () => npmInstallEnv,
1434
1434
  organizeFooterMessages: () => organizeFooterMessages,
1435
1435
  parseGitHost: () => parseGitHost,
1436
+ parsePm2Jlist: () => parsePm2Jlist,
1436
1437
  prepareGitHost: () => prepareGitHost,
1437
1438
  provisionService: () => provisionService,
1438
1439
  pruneReleases: () => pruneReleases,
@@ -5356,7 +5357,8 @@ var LEVEL_COLORS = {
5356
5357
  silly: import_chalk.default.gray,
5357
5358
  request: import_chalk.default.green,
5358
5359
  response: import_chalk.default.yellow,
5359
- progress: import_chalk.default.green,
5360
+ // Magenta stands out from white info / green request lines.
5361
+ progress: import_chalk.default.magentaBright,
5360
5362
  results: import_chalk.default.magenta
5361
5363
  };
5362
5364
  var Logger = class _Logger {
@@ -5375,7 +5377,8 @@ var Logger = class _Logger {
5375
5377
  this.updateTransport();
5376
5378
  }
5377
5379
  /**
5378
- * Configure logger options. Accepts both LoggerOptions shape and flat param names (levels string, progressWithTimes, progressThrottleMs).
5380
+ * Configure logger options. Accepts both LoggerOptions shape and flat param names
5381
+ * (levels string, progressWithTimes, progressWithRate, progressThrottleMs).
5379
5382
  */
5380
5383
  configure(options) {
5381
5384
  if (options.mode !== void 0) {
@@ -5395,10 +5398,12 @@ var Logger = class _Logger {
5395
5398
  }
5396
5399
  if (options.progress !== void 0) {
5397
5400
  if (options.progress.withTimes !== void 0) this.options.progressTimes = options.progress.withTimes;
5401
+ if (options.progress.withRate !== void 0) this.options.progressRate = options.progress.withRate;
5398
5402
  if (options.progress.throttleMs !== void 0) this.options.progressThrottle = options.progress.throttleMs;
5399
5403
  }
5400
5404
  const flat = options;
5401
5405
  if (flat.progressWithTimes !== void 0) this.options.progressTimes = flat.progressWithTimes;
5406
+ if (flat.progressWithRate !== void 0) this.options.progressRate = flat.progressWithRate;
5402
5407
  if (flat.progressThrottleMs !== void 0) this.options.progressThrottle = flat.progressThrottleMs;
5403
5408
  }
5404
5409
  /**
@@ -5415,6 +5420,7 @@ var Logger = class _Logger {
5415
5420
  timestamp: "boolean default false",
5416
5421
  levels: "string",
5417
5422
  progressWithTimes: "boolean default false",
5423
+ progressWithRate: "boolean default false",
5418
5424
  progressThrottleMs: "number"
5419
5425
  };
5420
5426
  const discovered = context.params.getAllForModule("logger", paramDefs);
@@ -5433,6 +5439,7 @@ var Logger = class _Logger {
5433
5439
  timestamp: false,
5434
5440
  levels: DEFAULT_LEVELS,
5435
5441
  progressTimes: false,
5442
+ progressRate: false,
5436
5443
  progressThrottle: void 0
5437
5444
  };
5438
5445
  }
@@ -5498,15 +5505,23 @@ var Logger = class _Logger {
5498
5505
  if (!this.startTimes[prefix ?? ""]) {
5499
5506
  this.startTimes[prefix ?? ""] = Date.now();
5500
5507
  }
5501
- if (this.options.progressTimes) {
5508
+ const wantTimes = this.options.progressTimes;
5509
+ const wantRate = this.options.progressRate;
5510
+ if (wantTimes || wantRate) {
5502
5511
  const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? ""]) / 1e3;
5503
- let remaining = -1;
5504
- if (count > 1) {
5505
- const rate = elapsedSeconds / (count - 1);
5506
- remaining = (total - count) * rate;
5512
+ const intervals = count > 1 ? count - 1 : 0;
5513
+ const itemsPerSec = intervals > 0 && elapsedSeconds > 0 ? intervals / elapsedSeconds : -1;
5514
+ if (wantTimes) {
5515
+ let remaining = -1;
5516
+ if (itemsPerSec > 0) {
5517
+ remaining = (total - count) / itemsPerSec;
5518
+ }
5519
+ payload.elapsed = this.round(elapsedSeconds, 2);
5520
+ payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;
5521
+ }
5522
+ if (wantRate) {
5523
+ payload.rate = itemsPerSec >= 0 ? this.round(itemsPerSec, 2) : itemsPerSec;
5507
5524
  }
5508
- payload.elapsed = this.round(elapsedSeconds, 2);
5509
- payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;
5510
5525
  }
5511
5526
  if (count >= total) {
5512
5527
  delete this.startTimes[prefix ?? ""];
@@ -5571,10 +5586,13 @@ var Logger = class _Logger {
5571
5586
  parts.push(formatter.bold(struct.message));
5572
5587
  }
5573
5588
  if (struct.level === "progress") {
5589
+ const formatter = LEVEL_COLORS[struct.level];
5574
5590
  if (struct.elapsed !== void 0 && struct.remaining !== void 0) {
5575
- const formatter = LEVEL_COLORS[struct.level];
5576
5591
  parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));
5577
5592
  }
5593
+ if (struct.rate !== void 0) {
5594
+ parts.push(formatter(struct.rate >= 0 ? `${struct.rate}/s` : "-/s"));
5595
+ }
5578
5596
  }
5579
5597
  if (struct.chunks && struct.chunks.length) {
5580
5598
  parts.push(this.inspectChunks(struct.chunks));
@@ -6071,16 +6089,28 @@ function isPidAlive(pid) {
6071
6089
  return false;
6072
6090
  }
6073
6091
  }
6092
+ function parsePm2Jlist(stdout) {
6093
+ const raw = String(stdout ?? "");
6094
+ const text = raw.split("\n").filter((line) => !line.startsWith("[PM2]")).join("\n").trim();
6095
+ if (!text) return [];
6096
+ try {
6097
+ const parsed = JSON.parse(text);
6098
+ return Array.isArray(parsed) ? parsed : [];
6099
+ } catch (err) {
6100
+ throw new Error(`pm2 jlist: invalid JSON (${err?.message ?? err})`);
6101
+ }
6102
+ }
6074
6103
  async function getPm2Process(appName, options = {}) {
6075
6104
  const { logger } = options;
6105
+ await runCapture("bash", ["-lc", "pm2 ping >/dev/null 2>&1 || true"], { logger }).catch(() => {
6106
+ });
6076
6107
  const { stdout } = await runCapture("bash", ["-lc", "pm2 jlist"], { logger });
6077
6108
  let list;
6078
6109
  try {
6079
- list = JSON.parse(stdout || "[]");
6110
+ list = parsePm2Jlist(stdout);
6080
6111
  } catch (err) {
6081
6112
  throw new Error(`pm2 jlist: invalid JSON (${err?.message ?? err})`);
6082
6113
  }
6083
- if (!Array.isArray(list)) return null;
6084
6114
  return list.find((p) => p?.name === appName) ?? null;
6085
6115
  }
6086
6116
  async function waitPm2(appName, predicate, options = {}) {
@@ -8545,6 +8575,7 @@ var LOGGER_RUNTIME_KEYS = [
8545
8575
  "route",
8546
8576
  "prefix",
8547
8577
  "progressWithTimes",
8578
+ "progressWithRate",
8548
8579
  "progressThrottleMs"
8549
8580
  ];
8550
8581
  var DEFAULT_RUNTIME_PARAM_SPECS = [
@@ -8656,6 +8687,7 @@ function coerceRuntimeValue(key, value) {
8656
8687
  case "showLevel":
8657
8688
  case "timestamp":
8658
8689
  case "progressWithTimes":
8690
+ case "progressWithRate":
8659
8691
  if (typeof value === "boolean") return value;
8660
8692
  if (value === "true" || value === "1") return true;
8661
8693
  if (value === "false" || value === "0") return false;
@@ -10274,6 +10306,7 @@ var TasksManager = class _TasksManager {
10274
10306
  npmInstallEnv,
10275
10307
  organizeFooterMessages,
10276
10308
  parseGitHost,
10309
+ parsePm2Jlist,
10277
10310
  prepareGitHost,
10278
10311
  provisionService,
10279
10312
  pruneReleases,