@qodalis/cli-server-jobs 2.2.0 → 2.4.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.
@@ -2247,28 +2247,30 @@ var jobs = (() => {
2247
2247
  brightCyan: "#a5f3fc",
2248
2248
  brightWhite: "#f1f5f9"
2249
2249
  },
2250
+ // Soft grey paper and slate text; every color reads at 4.5:1 or more on the background
2250
2251
  light: {
2251
- background: "#ffffff",
2252
- foreground: "#1f2937",
2252
+ background: "#f7f8fa",
2253
+ foreground: "#334155",
2253
2254
  cursor: "#4f46e5",
2254
- selectionBackground: "#c7d2fe",
2255
- selectionForeground: "#111827",
2256
- black: "#1f2937",
2257
- red: "#dc2626",
2258
- green: "#15803d",
2259
- yellow: "#a16207",
2260
- blue: "#4f46e5",
2261
- magenta: "#9333ea",
2262
- cyan: "#0e7490",
2263
- white: "#6b7280",
2264
- brightBlack: "#6b7280",
2265
- brightRed: "#b91c1c",
2266
- brightGreen: "#166534",
2267
- brightYellow: "#854d0e",
2268
- brightBlue: "#4338ca",
2269
- brightMagenta: "#7e22ce",
2270
- brightCyan: "#155e75",
2271
- brightWhite: "#374151"
2255
+ cursorAccent: "#f7f8fa",
2256
+ selectionBackground: "#d9def7",
2257
+ selectionForeground: "#1e293b",
2258
+ black: "#334155",
2259
+ red: "#c93c37",
2260
+ green: "#2c7a4b",
2261
+ yellow: "#946200",
2262
+ blue: "#3d5bd9",
2263
+ magenta: "#8b3fc7",
2264
+ cyan: "#0e7586",
2265
+ white: "#5b6577",
2266
+ brightBlack: "#667085",
2267
+ brightRed: "#b42a25",
2268
+ brightGreen: "#1f6a3d",
2269
+ brightYellow: "#7a5100",
2270
+ brightBlue: "#2f47bd",
2271
+ brightMagenta: "#7431ad",
2272
+ brightCyan: "#0a6170",
2273
+ brightWhite: "#1e293b"
2272
2274
  },
2273
2275
  classic: {
2274
2276
  background: "#0c0c0c",
@@ -2894,17 +2896,18 @@ var jobs = (() => {
2894
2896
  danger: "#f87171",
2895
2897
  shadow: "rgba(0, 0, 0, 0.45)"
2896
2898
  }),
2899
+ // Soft grey paper instead of pure white, slate text rather than black: easier on the eyes
2897
2900
  light: Object.freeze({
2898
- background: "#ffffff",
2899
- headerBackground: "#f8fafc",
2900
- border: "#e2e8f0",
2901
- text: "#0f172a",
2902
- textSecondary: "#64748b",
2901
+ background: "#f7f8fa",
2902
+ headerBackground: "#eceff3",
2903
+ border: "#d9dee6",
2904
+ text: "#1e293b",
2905
+ textSecondary: "#5b6577",
2903
2906
  accent: "#4f46e5",
2904
- hoverBackground: "rgba(79, 70, 229, 0.08)",
2905
- activeBackground: "rgba(79, 70, 229, 0.14)",
2906
- danger: "#dc2626",
2907
- shadow: "rgba(15, 23, 42, 0.14)"
2907
+ hoverBackground: "rgba(30, 41, 59, 0.06)",
2908
+ activeBackground: "rgba(79, 70, 229, 0.12)",
2909
+ danger: "#c93c37",
2910
+ shadow: "rgba(15, 23, 42, 0.12)"
2908
2911
  })
2909
2912
  });
2910
2913
  var PALETTE_TERMINALS = {
@@ -3317,6 +3320,24 @@ var jobs = (() => {
3317
3320
  if (diff < 864e5) return `${Math.round(diff / 36e5)}h ago`;
3318
3321
  return `${Math.round(diff / 864e5)}d ago`;
3319
3322
  }
3323
+ function formatSpan(value) {
3324
+ if (value === null || value === void 0 || value === "") return null;
3325
+ if (typeof value === "string") return value;
3326
+ if (!Number.isFinite(value) || value < 0) return null;
3327
+ const units = [[864e5, "d"], [36e5, "h"], [6e4, "m"], [1e3, "s"]];
3328
+ for (const [size, unit] of units) {
3329
+ if (value >= size && value % size === 0) return `${value / size}${unit}`;
3330
+ }
3331
+ return value >= 1e3 ? `${(value / 1e3).toFixed(1)}s` : `${value}ms`;
3332
+ }
3333
+ function formatRunning(job) {
3334
+ const running = job.runningExecutionIds?.length ?? (job.currentExecutionId ? 1 : 0);
3335
+ const max = job.maxConcurrentRuns ?? 1;
3336
+ if (running === 0 && !job.queued) return null;
3337
+ const parts = [max > 1 ? `${running}/${max} running` : `${running} running`];
3338
+ if (job.queued) parts.push("1 queued");
3339
+ return parts.join(", ");
3340
+ }
3320
3341
  function formatDuration(ms) {
3321
3342
  if (ms == null) return "-";
3322
3343
  if (ms < 1e3) return `${ms}ms`;
@@ -3682,6 +3703,11 @@ var jobs = (() => {
3682
3703
  t.t("cli.server.jobs.edit.help.change_job_step_step", "Change a job step by step: description, group, cron schedule or interval, max retries, timeout and overlap policy (skip, queue or cancel). Press Enter to keep a value and Ctrl+C or Escape to cancel; nothing changes until you confirm. A job on several servers needs --server.")
3683
3704
  );
3684
3705
  context.writer.writeln();
3706
+ writeWrapped(
3707
+ context,
3708
+ t.t("cli.server.jobs.edit.help.max_concurrent_runs", "Max concurrent runs: how many runs of the job may go at the same time (1 by default). When that many are running, the overlap policy decides what happens to the next one.")
3709
+ );
3710
+ context.writer.writeln();
3685
3711
  writeUsage(context, [
3686
3712
  ["server jobs edit <name|id>", ""]
3687
3713
  ]);
@@ -3773,7 +3799,7 @@ var jobs = (() => {
3773
3799
  j.name,
3774
3800
  j.group ?? "-",
3775
3801
  statusColor(j.status, context.writer),
3776
- j.schedule ?? (j.interval ? `every ${j.interval}ms` : "-"),
3802
+ j.schedule ?? (formatSpan(j.interval) ? `every ${formatSpan(j.interval)}` : "-"),
3777
3803
  formatRelativeTime(j.lastRunAt),
3778
3804
  formatRelativeTime(j.nextRunAt),
3779
3805
  formatDuration(j.lastRunDuration)
@@ -3811,12 +3837,16 @@ var jobs = (() => {
3811
3837
  ["Status", statusColor(job.status, context.writer)],
3812
3838
  [
3813
3839
  "Schedule",
3814
- job.schedule ?? (job.interval ? `every ${job.interval}ms` : "-")
3840
+ job.schedule ?? (formatSpan(job.interval) ? `every ${formatSpan(job.interval)}` : "-")
3815
3841
  ],
3816
3842
  ["Max Retries", String(job.maxRetries)],
3817
- ["Timeout", job.timeout ? `${job.timeout}ms` : "none"],
3843
+ ["Timeout", formatSpan(job.timeout) ?? "none"],
3818
3844
  ["Overlap Policy", job.overlapPolicy],
3819
- ["Current Execution", job.currentExecutionId ?? "none"],
3845
+ ["Max Concurrent Runs", String(job.maxConcurrentRuns ?? 1)],
3846
+ [
3847
+ "Running",
3848
+ job.runningExecutionIds && job.runningExecutionIds.length > 1 ? `${formatRunning(job)}: ${job.runningExecutionIds.join(", ")}` : formatRunning(job) && job.currentExecutionId ? `${formatRunning(job)} (${job.currentExecutionId})` : formatRunning(job) ?? "none"
3849
+ ],
3820
3850
  ["Next Run", formatRelativeTime(job.nextRunAt)],
3821
3851
  ["Last Run", formatRelativeTime(job.lastRunAt)],
3822
3852
  [
@@ -4060,7 +4090,7 @@ var jobs = (() => {
4060
4090
  const newGroup = await ask(`Group [${job.group ?? "none"}]: `);
4061
4091
  if (newGroup == null) return cancelled();
4062
4092
  if (newGroup) update.group = newGroup;
4063
- const currentSchedule = job.schedule ?? (job.interval ? `interval: ${job.interval}ms` : "none");
4093
+ const currentSchedule = job.schedule ?? (formatSpan(job.interval) ? `interval: ${formatSpan(job.interval)}` : "none");
4064
4094
  const newSchedule = await ask(
4065
4095
  `Cron schedule [${currentSchedule}]: `
4066
4096
  );
@@ -4068,7 +4098,7 @@ var jobs = (() => {
4068
4098
  if (newSchedule) update.schedule = newSchedule;
4069
4099
  if (!newSchedule) {
4070
4100
  const newInterval = await ask(
4071
- `Interval (e.g. 30s, 5m) [${job.interval ? `${job.interval}ms` : "none"}]: `
4101
+ `Interval (e.g. 30s, 5m) [${formatSpan(job.interval) ?? "none"}]: `
4072
4102
  );
4073
4103
  if (newInterval == null) return cancelled();
4074
4104
  if (newInterval) update.interval = newInterval;
@@ -4082,7 +4112,7 @@ var jobs = (() => {
4082
4112
  }
4083
4113
  }
4084
4114
  const newTimeout = await ask(
4085
- `Timeout (e.g. 5m, 1h) [${job.timeout ? `${job.timeout}ms` : "none"}]: `
4115
+ `Timeout (e.g. 5m, 1h) [${formatSpan(job.timeout) ?? "none"}]: `
4086
4116
  );
4087
4117
  if (newTimeout == null) return cancelled();
4088
4118
  if (newTimeout) update.timeout = newTimeout;
@@ -4093,6 +4123,20 @@ var jobs = (() => {
4093
4123
  if (newOverlap && ["skip", "queue", "cancel"].includes(newOverlap.toLowerCase())) {
4094
4124
  update.overlapPolicy = newOverlap.toLowerCase();
4095
4125
  }
4126
+ const newMax = await ask(
4127
+ `Max concurrent runs [${job.maxConcurrentRuns ?? 1}]: `
4128
+ );
4129
+ if (newMax == null) return cancelled();
4130
+ if (newMax) {
4131
+ const parsed = Number(newMax);
4132
+ if (Number.isInteger(parsed) && parsed >= 1) {
4133
+ update.maxConcurrentRuns = parsed;
4134
+ } else {
4135
+ context.writer.writeWarning(
4136
+ "Max concurrent runs must be a whole number of at least 1; kept as it was."
4137
+ );
4138
+ }
4139
+ }
4096
4140
  if (Object.keys(update).length === 0) {
4097
4141
  context.writer.writeInfo("No changes made.");
4098
4142
  return;