@nmakarov/cli-toolkit 0.50.0 → 0.53.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
@@ -1147,6 +1147,7 @@ __export(src_exports, {
1147
1147
  ensureTasksRuntime: () => ensureTasksRuntime,
1148
1148
  flushTaskIpcLogs: () => flushTaskIpcLogs,
1149
1149
  getArgsInstance: () => getArgsInstance,
1150
+ getPm2Process: () => getPm2Process,
1150
1151
  h: () => import_react5.createElement,
1151
1152
  initServiceStructure: () => initServiceStructure,
1152
1153
  installDeps: () => installDeps,
@@ -1193,6 +1194,7 @@ __export(src_exports, {
1193
1194
  resolveSteps: () => resolveSteps,
1194
1195
  rollbackService: () => rollbackService,
1195
1196
  run: () => run,
1197
+ runCapture: () => runCapture,
1196
1198
  runNodeTaskScript: () => runNodeTaskScript,
1197
1199
  runReleaseTests: () => runReleaseTests,
1198
1200
  runRemoteCli: () => runRemoteCli,
@@ -1210,6 +1212,8 @@ __export(src_exports, {
1210
1212
  showScreen: () => showScreen,
1211
1213
  showWordGridScreen: () => showWordGridScreen,
1212
1214
  sshRun: () => sshRun,
1215
+ startPm2: () => startPm2,
1216
+ stopPm2: () => stopPm2,
1213
1217
  syncEnv: () => syncEnv,
1214
1218
  taskHistoryInsertFromQueueRow: () => taskHistoryInsertFromQueueRow,
1215
1219
  timeMatcher: () => timeMatcher,
@@ -1227,6 +1231,7 @@ __export(src_exports, {
1227
1231
  useRef: () => import_react5.useRef,
1228
1232
  useState: () => import_react5.useState,
1229
1233
  waitForTaskResult: () => waitForTaskResult,
1234
+ waitPm2: () => waitPm2,
1230
1235
  writeReleaseBuildInfo: () => writeReleaseBuildInfo
1231
1236
  });
1232
1237
  module.exports = __toCommonJS(src_exports);
@@ -5383,8 +5388,13 @@ function defineService(service) {
5383
5388
  const pm2 = {
5384
5389
  appName: service.name,
5385
5390
  args: "",
5391
+ stopAllowance: 60,
5386
5392
  ...service.pm2
5387
5393
  };
5394
+ if (pm2.killTimeout == null) {
5395
+ const stopSec = Number(pm2.stopAllowance);
5396
+ pm2.killTimeout = Number.isFinite(stopSec) && stopSec > 0 ? Math.floor(stopSec * 1e3) + 5e3 : 65e3;
5397
+ }
5388
5398
  const nginx = service.nginx ? { siteName: service.name, ...service.nginx } : null;
5389
5399
  return {
5390
5400
  repoDirName: deriveRepoDirName(service.repoUrl),
@@ -5465,6 +5475,30 @@ function run(cmd, args, options = {}) {
5465
5475
  function runShell(command, options = {}) {
5466
5476
  return run("bash", ["-lc", command], options);
5467
5477
  }
5478
+ function runCapture(cmd, args, options = {}) {
5479
+ const { cwd, env, logger, allowFail = false } = options;
5480
+ return new Promise((resolve3, reject) => {
5481
+ logger?.info?.(`$ ${cmd} ${args.join(" ")}${cwd ? ` (cwd=${cwd})` : ""}`);
5482
+ const child = (0, import_node_child_process.spawn)(cmd, args, {
5483
+ cwd,
5484
+ env: env ?? process.env,
5485
+ stdio: ["ignore", "pipe", "pipe"]
5486
+ });
5487
+ let stdout = "";
5488
+ let stderr = "";
5489
+ child.stdout?.on("data", (chunk) => {
5490
+ stdout += chunk.toString();
5491
+ });
5492
+ child.stderr?.on("data", (chunk) => {
5493
+ stderr += chunk.toString();
5494
+ });
5495
+ child.on("error", reject);
5496
+ child.on("close", (code) => {
5497
+ if (code === 0 || allowFail) resolve3({ stdout, stderr, code });
5498
+ else reject(new Error(`${cmd} exited with code ${code}${stderr ? `: ${stderr.trim()}` : ""}`));
5499
+ });
5500
+ });
5501
+ }
5468
5502
 
5469
5503
  // src/deploy/log.js
5470
5504
  var import_promises = require("fs/promises");
@@ -5682,7 +5716,7 @@ async function runReleaseTests(service, releasePath, paths, options = {}) {
5682
5716
  // src/deploy/prune.js
5683
5717
  var import_promises7 = require("fs/promises");
5684
5718
  async function pruneReleases(service, paths, options = {}) {
5685
- const { dryRun = false, logger = console } = options;
5719
+ const { dryRun = false, logger = console, protect = [] } = options;
5686
5720
  const keep = service.keepReleases ?? 3;
5687
5721
  const releases = await listReleases(paths);
5688
5722
  let activeName = null;
@@ -5696,6 +5730,9 @@ async function pruneReleases(service, paths, options = {}) {
5696
5730
  if (keepSet.size < keep) keepSet.add(rel.name);
5697
5731
  }
5698
5732
  if (activeName) keepSet.add(activeName);
5733
+ for (const name of protect) {
5734
+ if (name) keepSet.add(name);
5735
+ }
5699
5736
  const toRemove = releases.filter((rel) => !keepSet.has(rel.name));
5700
5737
  for (const rel of toRemove) {
5701
5738
  if (dryRun) {
@@ -5709,14 +5746,101 @@ async function pruneReleases(service, paths, options = {}) {
5709
5746
  }
5710
5747
 
5711
5748
  // src/deploy/pm2.js
5749
+ function sleep(ms) {
5750
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
5751
+ }
5752
+ async function getPm2Process(appName, options = {}) {
5753
+ const { logger } = options;
5754
+ const { stdout } = await runCapture("bash", ["-lc", "pm2 jlist"], { logger });
5755
+ let list;
5756
+ try {
5757
+ list = JSON.parse(stdout || "[]");
5758
+ } catch (err) {
5759
+ throw new Error(`pm2 jlist: invalid JSON (${err?.message ?? err})`);
5760
+ }
5761
+ if (!Array.isArray(list)) return null;
5762
+ return list.find((p) => p?.name === appName) ?? null;
5763
+ }
5764
+ async function waitPm2(appName, predicate, options = {}) {
5765
+ const {
5766
+ timeoutMs = 65e3,
5767
+ pollMs = 500,
5768
+ dryRun = false,
5769
+ logger = console,
5770
+ label = "condition"
5771
+ } = options;
5772
+ if (dryRun) {
5773
+ logger.info?.(`[dryRun] would wait pm2 ${appName} for ${label}`);
5774
+ return null;
5775
+ }
5776
+ const deadline = Date.now() + timeoutMs;
5777
+ let lastStatus = "(unknown)";
5778
+ while (Date.now() < deadline) {
5779
+ const proc = await getPm2Process(appName, { logger });
5780
+ lastStatus = proc?.pm2_env?.status ?? "(missing)";
5781
+ if (predicate(proc)) return proc;
5782
+ await sleep(pollMs);
5783
+ }
5784
+ throw new Error(
5785
+ `pm2 wait timed out after ${timeoutMs}ms for ${appName} (${label}); last status=${lastStatus}`
5786
+ );
5787
+ }
5712
5788
  async function reloadPm2(paths, options = {}) {
5713
- const { dryRun = false, logger = console } = options;
5789
+ const { dryRun = false, logger = console, appName = null, waitTimeoutMs = 65e3 } = options;
5714
5790
  if (dryRun) {
5715
5791
  logger.info(`[dryRun] would pm2 startOrReload ${paths.ecosystem} --update-env`);
5716
5792
  return;
5717
5793
  }
5718
5794
  await runShell(`pm2 startOrReload "${paths.ecosystem}" --update-env`, { logger });
5719
5795
  logger.info("pm2 reloaded");
5796
+ if (appName) {
5797
+ await waitPm2(
5798
+ appName,
5799
+ (proc) => proc?.pm2_env?.status === "online",
5800
+ { timeoutMs: waitTimeoutMs, logger, label: "online after reload" }
5801
+ );
5802
+ logger.info(`pm2 ${appName} online`);
5803
+ }
5804
+ }
5805
+ async function stopPm2(appName, options = {}) {
5806
+ const { dryRun = false, logger = console, waitTimeoutMs = 65e3 } = options;
5807
+ if (dryRun) {
5808
+ logger.info(`[dryRun] would pm2 stop ${appName}`);
5809
+ return;
5810
+ }
5811
+ const before = await getPm2Process(appName, { logger });
5812
+ if (!before) {
5813
+ logger.info(`pm2 ${appName}: not present (already stopped)`);
5814
+ return;
5815
+ }
5816
+ if (before.pm2_env?.status === "stopped") {
5817
+ logger.info(`pm2 ${appName}: already stopped`);
5818
+ return;
5819
+ }
5820
+ await runShell(`pm2 stop "${appName}"`, { logger });
5821
+ await waitPm2(
5822
+ appName,
5823
+ (proc) => !proc || proc.pm2_env?.status === "stopped",
5824
+ { timeoutMs: waitTimeoutMs, logger, label: "stopped" }
5825
+ );
5826
+ logger.info(`pm2 ${appName} stopped`);
5827
+ }
5828
+ async function startPm2(paths, options = {}) {
5829
+ const { dryRun = false, logger = console, appName = null, waitTimeoutMs = 65e3 } = options;
5830
+ if (dryRun) {
5831
+ logger.info(`[dryRun] would pm2 start ${paths.ecosystem} --update-env`);
5832
+ return;
5833
+ }
5834
+ await runShell(`pm2 start "${paths.ecosystem}" --update-env`, { logger });
5835
+ logger.info("pm2 started");
5836
+ if (appName) {
5837
+ await waitPm2(
5838
+ appName,
5839
+ (proc) => proc?.pm2_env?.status === "online",
5840
+ { timeoutMs: waitTimeoutMs, logger, label: "online after start" }
5841
+ );
5842
+ logger.info(`pm2 ${appName} online`);
5843
+ }
5720
5844
  }
5721
5845
 
5722
5846
  // src/deploy/nginx.js
@@ -5945,10 +6069,26 @@ async function requireDeployRoot(parentDir, serviceRoot) {
5945
6069
  This is meant to run on the target host (where ${parentDir} exists). For a local dry run use --appsRoot=/tmp/<service>.`
5946
6070
  );
5947
6071
  }
6072
+ function resolveKillTimeoutMs(pm2) {
6073
+ const explicit = Number(pm2?.killTimeout);
6074
+ if (Number.isFinite(explicit) && explicit > 0) return Math.floor(explicit);
6075
+ const stopSec = Number(pm2?.stopAllowance);
6076
+ if (Number.isFinite(stopSec) && stopSec > 0) return Math.floor(stopSec * 1e3) + 5e3;
6077
+ return 65e3;
6078
+ }
6079
+ function resolvePm2Args(pm2) {
6080
+ const base = String(pm2?.args ?? "").trim();
6081
+ const stopSec = Number(pm2?.stopAllowance);
6082
+ if (!Number.isFinite(stopSec) || stopSec <= 0) return base;
6083
+ if (/(?:^|\s)--stopAllowance=/.test(base)) return base;
6084
+ return `${base}${base ? " " : ""}--stopAllowance=${Math.floor(stopSec)}`.trim();
6085
+ }
5948
6086
  function buildEcosystemConfig(service, paths) {
5949
6087
  const { pm2 } = service;
5950
6088
  const outLog = (0, import_node_path8.join)(paths.logs, `${pm2.appName}.out.log`);
5951
6089
  const errLog = (0, import_node_path8.join)(paths.logs, `${pm2.appName}.err.log`);
6090
+ const killTimeoutMs = resolveKillTimeoutMs(pm2);
6091
+ const args = resolvePm2Args(pm2);
5952
6092
  return `/**
5953
6093
  * pm2 ecosystem for ${service.name} \u2014 written by cli-toolkit deploy from the
5954
6094
  * service manifest (init/deploy). Do not hand-edit; change pm2.* in the
@@ -5960,7 +6100,7 @@ module.exports = {
5960
6100
  name: "${pm2.appName}",
5961
6101
  script: "${pm2.script}",
5962
6102
  cwd: "${paths.current}",
5963
- args: "${pm2.args ?? ""}",
6103
+ args: ${JSON.stringify(args)},
5964
6104
  instances: 1,
5965
6105
  exec_mode: "fork",
5966
6106
  autorestart: true,
@@ -5968,6 +6108,8 @@ module.exports = {
5968
6108
  max_restarts: 10,
5969
6109
  restart_delay: 2000,
5970
6110
  max_memory_restart: "1500M",
6111
+ // Grace window after SIGINT/SIGTERM before SIGKILL (ms). Align with --stopAllowance.
6112
+ kill_timeout: ${killTimeoutMs},
5971
6113
  out_file: "${outLog}",
5972
6114
  error_file: "${errLog}",
5973
6115
  merge_logs: true,
@@ -6168,15 +6310,27 @@ async function bootstrapHost(service, options = {}) {
6168
6310
  }
6169
6311
 
6170
6312
  // src/deploy/deploy-service.js
6313
+ var import_promises13 = require("fs/promises");
6314
+ function resolveKillTimeoutMs2(service) {
6315
+ const explicit = Number(service.pm2?.killTimeout);
6316
+ if (Number.isFinite(explicit) && explicit > 0) return Math.floor(explicit);
6317
+ const stopSec = Number(service.pm2?.stopAllowance);
6318
+ if (Number.isFinite(stopSec) && stopSec > 0) return Math.floor(stopSec * 1e3) + 5e3;
6319
+ return 65e3;
6320
+ }
6171
6321
  async function deployService(service, options = {}) {
6172
6322
  const {
6173
6323
  dryRun = false,
6174
6324
  skipPull = false,
6175
6325
  skipTests = false,
6176
6326
  skipNginx = false,
6327
+ stopFirst = false,
6177
6328
  logger = console
6178
6329
  } = options;
6179
6330
  const paths = servicePaths(service);
6331
+ const appName = service.pm2.appName;
6332
+ const killTimeoutMs = resolveKillTimeoutMs2(service);
6333
+ const waitTimeoutMs = killTimeoutMs + 1e4;
6180
6334
  await initServiceStructure(service, { dryRun, logger });
6181
6335
  if (!skipPull) await pullRepo(service, { dryRun, logger });
6182
6336
  await syncEnv(service, { dryRun, logger });
@@ -6184,21 +6338,38 @@ async function deployService(service, options = {}) {
6184
6338
  await writeReleaseBuildInfo(service, releasePath, { stamp, dryRun, logger });
6185
6339
  await installDeps(service, releasePath, paths, { dryRun, logger });
6186
6340
  if (!skipTests) await runReleaseTests(service, releasePath, paths, { dryRun, logger });
6187
- await activateRelease(releasePath, paths, { dryRun, logger });
6188
- await pruneReleases(service, paths, { dryRun, logger });
6189
- await reloadPm2(paths, { dryRun, logger });
6341
+ let previousReleaseName = null;
6342
+ try {
6343
+ const prev = await (0, import_promises13.readlink)(paths.current);
6344
+ previousReleaseName = prev.split("/").pop() || null;
6345
+ } catch {
6346
+ }
6347
+ if (stopFirst) {
6348
+ logger.info(`deploy mode=stopFirst app=${appName} killTimeoutMs=${killTimeoutMs}`);
6349
+ await stopPm2(appName, { dryRun, logger, waitTimeoutMs });
6350
+ await activateRelease(releasePath, paths, { dryRun, logger });
6351
+ await pruneReleases(service, paths, { dryRun, logger });
6352
+ await startPm2(paths, { dryRun, logger, appName, waitTimeoutMs });
6353
+ } else {
6354
+ logger.info(
6355
+ `deploy mode=rolling app=${appName} killTimeoutMs=${killTimeoutMs}` + (previousReleaseName ? ` previous=${previousReleaseName}` : "")
6356
+ );
6357
+ await activateRelease(releasePath, paths, { dryRun, logger });
6358
+ await reloadPm2(paths, { dryRun, logger, appName, waitTimeoutMs });
6359
+ await pruneReleases(service, paths, { dryRun, logger });
6360
+ }
6190
6361
  if (!skipNginx) await enableNginxUpstream(service, { dryRun, logger });
6191
- const summary = `deploy complete stamp=${stamp} dryRun=${dryRun}`;
6362
+ const summary = `deploy complete stamp=${stamp} mode=${stopFirst ? "stopFirst" : "rolling"} dryRun=${dryRun}`;
6192
6363
  logger.info(summary);
6193
6364
  if (!dryRun) await appendDeployLog(paths.deployLog, summary);
6194
- return { stamp, releasePath };
6365
+ return { stamp, releasePath, mode: stopFirst ? "stopFirst" : "rolling" };
6195
6366
  }
6196
6367
 
6197
6368
  // src/deploy/provision-service.js
6198
- var import_promises13 = require("fs/promises");
6369
+ var import_promises14 = require("fs/promises");
6199
6370
  async function pathExists6(path5) {
6200
6371
  try {
6201
- await (0, import_promises13.access)(path5);
6372
+ await (0, import_promises14.access)(path5);
6202
6373
  return true;
6203
6374
  } catch {
6204
6375
  return false;
@@ -6232,7 +6403,7 @@ async function provisionService(service, options = {}) {
6232
6403
  }
6233
6404
 
6234
6405
  // src/deploy/rollback-service.js
6235
- var import_promises14 = require("fs/promises");
6406
+ var import_promises15 = require("fs/promises");
6236
6407
  async function rollbackService(service, options = {}) {
6237
6408
  const { release: targetName, dryRun = false, logger = console } = options;
6238
6409
  const paths = servicePaths(service);
@@ -6240,7 +6411,7 @@ async function rollbackService(service, options = {}) {
6240
6411
  if (releases.length === 0) throw new Error("No releases to roll back to");
6241
6412
  let activeName = null;
6242
6413
  try {
6243
- const target = await (0, import_promises14.readlink)(paths.current);
6414
+ const target = await (0, import_promises15.readlink)(paths.current);
6244
6415
  activeName = target.split("/").pop();
6245
6416
  } catch {
6246
6417
  throw new Error("No active release (current symlink missing)");
@@ -6267,14 +6438,14 @@ async function rollbackService(service, options = {}) {
6267
6438
  }
6268
6439
 
6269
6440
  // src/deploy/ssh-remote.js
6270
- var import_promises15 = require("fs/promises");
6441
+ var import_promises16 = require("fs/promises");
6271
6442
  var import_node_os3 = require("os");
6272
6443
  var import_node_path10 = require("path");
6273
6444
  var import_node_child_process4 = require("child_process");
6274
6445
  var REMOTE_CLI_REL = "node_modules/@nmakarov/cli-toolkit/scripts/deploy/cli.js";
6275
6446
  async function pathExists7(path5) {
6276
6447
  try {
6277
- await (0, import_promises15.access)(path5);
6448
+ await (0, import_promises16.access)(path5);
6278
6449
  return true;
6279
6450
  } catch {
6280
6451
  return false;
@@ -6366,9 +6537,9 @@ async function ensureEnvOnRemote(host, service, options = {}) {
6366
6537
  if (!await pathExists7(localPath)) return false;
6367
6538
  logger.info(`copying .env ${localPath} \u2192 ${host}:${paths.repoEnv}`);
6368
6539
  await sshRun(host, `mkdir -p ${shellQuote((0, import_node_path10.dirname)(paths.repoEnv))}`, { logger });
6369
- const scrubbed = scrubEnvContent(await (0, import_promises15.readFile)(localPath, "utf8"), service.envScrubPatterns ?? []);
6540
+ const scrubbed = scrubEnvContent(await (0, import_promises16.readFile)(localPath, "utf8"), service.envScrubPatterns ?? []);
6370
6541
  const tmp = (0, import_node_path10.join)((0, import_node_os3.tmpdir)(), `deploy-env-${Date.now()}`);
6371
- await (0, import_promises15.writeFile)(tmp, scrubbed, { mode: 384 });
6542
+ await (0, import_promises16.writeFile)(tmp, scrubbed, { mode: 384 });
6372
6543
  await scp(tmp, `${host}:${paths.repoEnv}`, { logger });
6373
6544
  await sshRun(host, `chmod 600 ${shellQuote(paths.repoEnv)}`, { logger });
6374
6545
  return true;
@@ -7702,7 +7873,7 @@ var TaskShellCommand = class extends AbstractTask {
7702
7873
 
7703
7874
  // src/tasks/coreTasks/TaskSystemInfo.js
7704
7875
  var import_node_os5 = __toESM(require("os"), 1);
7705
- var import_promises16 = __toESM(require("fs/promises"), 1);
7876
+ var import_promises17 = __toESM(require("fs/promises"), 1);
7706
7877
  function toGb(valueBytes) {
7707
7878
  return `${(valueBytes / 1024 ** 3).toFixed(2)} GB`;
7708
7879
  }
@@ -7710,7 +7881,7 @@ function toMb(valueBytes) {
7710
7881
  return `${(valueBytes / 1024 ** 2).toFixed(2)} MB`;
7711
7882
  }
7712
7883
  async function getDiskStats() {
7713
- const stats = await import_promises16.default.statfs("/");
7884
+ const stats = await import_promises17.default.statfs("/");
7714
7885
  const total = Number(stats.bsize) * Number(stats.blocks);
7715
7886
  const free = Number(stats.bsize) * Number(stats.bavail);
7716
7887
  const used = total - free;
@@ -7863,7 +8034,7 @@ var TaskStopRunner = class extends AbstractTask {
7863
8034
  */
7864
8035
  static async resolveCustomParams(context, overrides = {}) {
7865
8036
  const merged = AbstractTask._mergeTypedParams(context, "task-stop", {
7866
- allowanceMs: "number default 5000"
8037
+ allowanceMs: "number default 60000"
7867
8038
  }, overrides);
7868
8039
  const allowanceMs = Number(merged.allowanceMs);
7869
8040
  if (!Number.isFinite(allowanceMs) || allowanceMs < 0) {
@@ -7877,7 +8048,7 @@ var TaskStopRunner = class extends AbstractTask {
7877
8048
  * @returns {Promise<{ success: true, results: { stopRunner: true, allowanceMs: number, message: string } }>}
7878
8049
  */
7879
8050
  async run() {
7880
- const allowanceMs = Number(this.task?.params?.allowanceMs ?? 5e3);
8051
+ const allowanceMs = Number(this.task?.params?.allowanceMs ?? 6e4);
7881
8052
  this.context.logger.warn?.(`[TaskStopRunner] stop requested (allowanceMs=${allowanceMs})`);
7882
8053
  return {
7883
8054
  success: true,
@@ -8562,7 +8733,7 @@ function normalizeRegistry(registry) {
8562
8733
  if (registry instanceof TasksRegistry) return registry;
8563
8734
  return new TasksRegistry().addMany(registry);
8564
8735
  }
8565
- async function enqueueStopTask(context, serviceGroup, queueName = "tasks", allowanceMs = 5e3) {
8736
+ async function enqueueStopTask(context, serviceGroup, queueName = "tasks", allowanceMs = 6e4) {
8566
8737
  return enqueueTask(context, {
8567
8738
  queueName,
8568
8739
  name: "stopRunner",
@@ -8701,7 +8872,7 @@ async function executeClaimedTask(context, tasksTable, historyTable, row, regist
8701
8872
  await db(tasksTable).where({ id: row.id }).delete();
8702
8873
  }
8703
8874
  const stopRunnerRequested = !!(results && typeof results === "object" && results.stopRunner === true);
8704
- const stopAllowanceMs = stopRunnerRequested ? Number(results.allowanceMs ?? 5e3) : 0;
8875
+ const stopAllowanceMs = stopRunnerRequested ? Number(results.allowanceMs ?? 6e4) : 0;
8705
8876
  return { stopRunnerRequested, stopAllowanceMs };
8706
8877
  }
8707
8878
  function shuffleTaskRowsInPlace(rows) {
@@ -8791,7 +8962,7 @@ async function runTasksLoop(context, options) {
8791
8962
  const runningTaskInstances = /* @__PURE__ */ new Map();
8792
8963
  let runningControlPromise = null;
8793
8964
  let stopRequested = false;
8794
- let stopAllowanceMs = 5e3;
8965
+ let stopAllowanceMs = Number(context.stopAllowanceMs) > 0 ? Number(context.stopAllowanceMs) : 6e4;
8795
8966
  context.tasksRunnerStop = false;
8796
8967
  let registryReg = null;
8797
8968
  let registryInterval = null;
@@ -8858,7 +9029,7 @@ async function runTasksLoop(context, options) {
8858
9029
  ).then(async (outcome) => {
8859
9030
  if (outcome.stopRunnerRequested && !stopRequested) {
8860
9031
  stopRequested = true;
8861
- stopAllowanceMs = outcome.stopAllowanceMs || 5e3;
9032
+ stopAllowanceMs = outcome.stopAllowanceMs || stopAllowanceMs;
8862
9033
  context.tasksRunnerStop = true;
8863
9034
  await signalRunningTasksStop(context, runningTaskInstances, stopAllowanceMs);
8864
9035
  }
@@ -8884,7 +9055,7 @@ async function runTasksLoop(context, options) {
8884
9055
  const p = executeClaimedTask(context, tasksTable, historyTable, claimed, registry, runningTaskInstances).then(async (outcome) => {
8885
9056
  if (outcome.stopRunnerRequested && !stopRequested) {
8886
9057
  stopRequested = true;
8887
- stopAllowanceMs = outcome.stopAllowanceMs || 5e3;
9058
+ stopAllowanceMs = outcome.stopAllowanceMs || stopAllowanceMs;
8888
9059
  context.tasksRunnerStop = true;
8889
9060
  await signalRunningTasksStop(context, runningTaskInstances, stopAllowanceMs);
8890
9061
  }
@@ -8905,7 +9076,9 @@ async function runTasksLoop(context, options) {
8905
9076
  }
8906
9077
  }
8907
9078
  if (context.isStop() && !stopRequested) {
8908
- await signalRunningTasksStop(context, runningTaskInstances, 5e3);
9079
+ stopRequested = true;
9080
+ stopAllowanceMs = Number(context.stopAllowanceMs) > 0 ? Number(context.stopAllowanceMs) : stopAllowanceMs;
9081
+ await signalRunningTasksStop(context, runningTaskInstances, stopAllowanceMs);
8909
9082
  }
8910
9083
  if (runningPromises.size > 0) {
8911
9084
  if (stopRequested) {
@@ -9190,6 +9363,7 @@ var TasksManager = class _TasksManager {
9190
9363
  ensureTasksRuntime,
9191
9364
  flushTaskIpcLogs,
9192
9365
  getArgsInstance,
9366
+ getPm2Process,
9193
9367
  h,
9194
9368
  initServiceStructure,
9195
9369
  installDeps,
@@ -9236,6 +9410,7 @@ var TasksManager = class _TasksManager {
9236
9410
  resolveSteps,
9237
9411
  rollbackService,
9238
9412
  run,
9413
+ runCapture,
9239
9414
  runNodeTaskScript,
9240
9415
  runReleaseTests,
9241
9416
  runRemoteCli,
@@ -9253,6 +9428,8 @@ var TasksManager = class _TasksManager {
9253
9428
  showScreen,
9254
9429
  showWordGridScreen,
9255
9430
  sshRun,
9431
+ startPm2,
9432
+ stopPm2,
9256
9433
  syncEnv,
9257
9434
  taskHistoryInsertFromQueueRow,
9258
9435
  timeMatcher,
@@ -9270,6 +9447,7 @@ var TasksManager = class _TasksManager {
9270
9447
  useRef,
9271
9448
  useState,
9272
9449
  waitForTaskResult,
9450
+ waitPm2,
9273
9451
  writeReleaseBuildInfo
9274
9452
  });
9275
9453
  //# sourceMappingURL=index.cjs.map