agentflow-core 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -62,7 +62,8 @@ function loadGraph(input) {
62
62
  events: raw.events ?? [],
63
63
  traceId: raw.traceId,
64
64
  spanId: raw.spanId,
65
- parentSpanId: raw.parentSpanId
65
+ parentSpanId: raw.parentSpanId,
66
+ metadata: raw.metadata ?? {}
66
67
  };
67
68
  }
68
69
  function graphToJson(graph) {
@@ -93,7 +94,7 @@ var init_loader = __esm({
93
94
  });
94
95
 
95
96
  // src/cli.ts
96
- var import_path3 = require("path");
97
+ var import_node_path7 = require("path");
97
98
 
98
99
  // src/live.ts
99
100
  var import_node_fs2 = require("fs");
@@ -191,7 +192,7 @@ function groupByTraceId(graphs) {
191
192
  }
192
193
  function stitchTrace(graphs) {
193
194
  if (graphs.length === 0) throw new Error("No graphs to stitch");
194
- const traceId = graphs[0].traceId ?? "";
195
+ const traceId = graphs[0]?.traceId ?? "";
195
196
  const graphsBySpan = /* @__PURE__ */ new Map();
196
197
  const childMap = /* @__PURE__ */ new Map();
197
198
  let rootGraph = null;
@@ -268,7 +269,7 @@ function pidMatchesName(pid, name) {
268
269
  function readPidFile(path) {
269
270
  try {
270
271
  const pid = parseInt((0, import_node_fs.readFileSync)(path, "utf8").trim(), 10);
271
- return isNaN(pid) ? null : pid;
272
+ return Number.isNaN(pid) ? null : pid;
272
273
  } catch {
273
274
  return null;
274
275
  }
@@ -303,8 +304,15 @@ function auditSystemd(config) {
303
304
  if (config.systemdUnit === null || config.systemdUnit === void 0) return null;
304
305
  const unit = config.systemdUnit;
305
306
  try {
306
- const raw = (0, import_node_child_process.execSync)(
307
- `systemctl --user show ${unit} --property=ActiveState,SubState,MainPID,NRestarts,Result --no-pager 2>/dev/null`,
307
+ const raw = (0, import_node_child_process.execFileSync)(
308
+ "systemctl",
309
+ [
310
+ "--user",
311
+ "show",
312
+ unit,
313
+ "--property=ActiveState,SubState,MainPID,NRestarts,Result",
314
+ "--no-pager"
315
+ ],
308
316
  { encoding: "utf8", timeout: 5e3 }
309
317
  );
310
318
  const props = {};
@@ -312,11 +320,11 @@ function auditSystemd(config) {
312
320
  const [k, ...v] = line.split("=");
313
321
  if (k) props[k.trim()] = v.join("=").trim();
314
322
  }
315
- const activeState = props["ActiveState"] ?? "unknown";
316
- const subState = props["SubState"] ?? "unknown";
317
- const mainPid = parseInt(props["MainPID"] ?? "0", 10);
318
- const restarts = parseInt(props["NRestarts"] ?? "0", 10);
319
- const result = props["Result"] ?? "unknown";
323
+ const activeState = props.ActiveState ?? "unknown";
324
+ const subState = props.SubState ?? "unknown";
325
+ const mainPid = parseInt(props.MainPID ?? "0", 10);
326
+ const restarts = parseInt(props.NRestarts ?? "0", 10);
327
+ const result = props.Result ?? "unknown";
320
328
  return {
321
329
  unit,
322
330
  activeState,
@@ -369,10 +377,10 @@ function readCmdline(pid) {
369
377
  }
370
378
  function getOsProcesses(processName) {
371
379
  try {
372
- const raw = (0, import_node_child_process.execSync)(
373
- `ps -eo pid,pcpu,pmem,etime,lstart,args --no-headers`,
374
- { encoding: "utf8", timeout: 5e3 }
375
- );
380
+ const raw = (0, import_node_child_process.execSync)(`ps -eo pid,pcpu,pmem,etime,lstart,args --no-headers`, {
381
+ encoding: "utf8",
382
+ timeout: 5e3
383
+ });
376
384
  const results = [];
377
385
  for (const line of raw.split("\n")) {
378
386
  if (!line.includes(processName)) continue;
@@ -380,7 +388,7 @@ function getOsProcesses(processName) {
380
388
  const trimmed = line.trim();
381
389
  const parts = trimmed.split(/\s+/);
382
390
  const pid = parseInt(parts[0] ?? "0", 10);
383
- if (isNaN(pid) || pid <= 0) continue;
391
+ if (Number.isNaN(pid) || pid <= 0) continue;
384
392
  const cpu = parts[1] ?? "0";
385
393
  const mem = parts[2] ?? "0";
386
394
  const elapsed = parts[3] ?? "";
@@ -395,9 +403,11 @@ function getOsProcesses(processName) {
395
403
  }
396
404
  }
397
405
  function discoverProcessConfig(dirs) {
398
- let pidFile;
399
- let workersFile;
400
- let processName = "";
406
+ const configs = discoverAllProcessConfigs(dirs);
407
+ return configs.length > 0 ? configs[0] ?? null : null;
408
+ }
409
+ function discoverAllProcessConfigs(dirs) {
410
+ const configs = /* @__PURE__ */ new Map();
401
411
  for (const dir of dirs) {
402
412
  if (!(0, import_node_fs.existsSync)(dir)) continue;
403
413
  let entries;
@@ -413,35 +423,63 @@ function discoverProcessConfig(dirs) {
413
423
  } catch {
414
424
  continue;
415
425
  }
416
- if (f.endsWith(".pid") && !pidFile) {
417
- pidFile = fp;
418
- if (!processName) {
419
- processName = (0, import_node_path.basename)(f, ".pid");
426
+ if (f.endsWith(".pid")) {
427
+ const name = (0, import_node_path.basename)(f, ".pid");
428
+ if (!configs.has(name)) {
429
+ configs.set(name, { processName: name });
420
430
  }
431
+ const cfg = configs.get(name) ?? { processName: name };
432
+ if (!cfg.pidFile) cfg.pidFile = fp;
421
433
  }
422
- if ((f === "workers.json" || f.endsWith("-workers.json")) && !workersFile) {
423
- workersFile = fp;
424
- if (!processName && f !== "workers.json") {
425
- processName = (0, import_node_path.basename)(f, "-workers.json");
434
+ if (f === "workers.json" || f.endsWith("-workers.json")) {
435
+ const name = f === "workers.json" ? "" : (0, import_node_path.basename)(f, "-workers.json");
436
+ if (name && !configs.has(name)) {
437
+ configs.set(name, { processName: name });
438
+ }
439
+ if (name) {
440
+ const cfg = configs.get(name) ?? { processName: name };
441
+ if (!cfg.workersFile) cfg.workersFile = fp;
426
442
  }
427
443
  }
428
444
  }
429
445
  }
430
- if (!processName && !pidFile && !workersFile) return null;
431
- if (!processName) processName = "agent";
432
- let systemdUnit;
433
446
  try {
434
- const unitName = `${processName}.service`;
435
- const result = (0, import_node_child_process.execSync)(
436
- `systemctl --user show ${unitName} --property=LoadState --no-pager 2>/dev/null`,
437
- { encoding: "utf8", timeout: 3e3 }
447
+ const raw = (0, import_node_child_process.execSync)(
448
+ "systemctl --user list-units --type=service --all --no-legend --no-pager 2>/dev/null",
449
+ { encoding: "utf8", timeout: 5e3 }
438
450
  );
439
- if (result.includes("LoadState=loaded")) {
440
- systemdUnit = unitName;
451
+ for (const line of raw.trim().split("\n")) {
452
+ if (!line.trim()) continue;
453
+ const parts = line.trim().split(/\s+/);
454
+ const unitName = parts[0] ?? "";
455
+ const loadState = parts[1] ?? "";
456
+ if (!unitName.endsWith(".service") || loadState !== "loaded") continue;
457
+ const name = unitName.replace(".service", "");
458
+ if (/^(dbus|gpg-agent|dirmngr|keyboxd|snapd\.|pk-|launchpadlib-)/.test(name)) continue;
459
+ if (!configs.has(name)) {
460
+ configs.set(name, { processName: name });
461
+ }
462
+ const cfg = configs.get(name) ?? { processName: name };
463
+ cfg.systemdUnit = unitName;
441
464
  }
442
465
  } catch {
443
466
  }
444
- return { processName, pidFile, workersFile, systemdUnit };
467
+ for (const cfg of configs.values()) {
468
+ if (cfg.systemdUnit !== void 0) continue;
469
+ try {
470
+ const unitName = `${cfg.processName}.service`;
471
+ const result = (0, import_node_child_process.execFileSync)(
472
+ "systemctl",
473
+ ["--user", "show", unitName, "--property=LoadState", "--no-pager"],
474
+ { encoding: "utf8", timeout: 3e3 }
475
+ );
476
+ if (result.includes("LoadState=loaded")) {
477
+ cfg.systemdUnit = unitName;
478
+ }
479
+ } catch {
480
+ }
481
+ }
482
+ return [...configs.values()];
445
483
  }
446
484
  function auditProcesses(config) {
447
485
  const pidFile = auditPidFile(config);
@@ -457,16 +495,45 @@ function auditProcesses(config) {
457
495
  }
458
496
  }
459
497
  if (systemd?.mainPid) knownPids.add(systemd.mainPid);
498
+ const childPids = /* @__PURE__ */ new Set();
499
+ for (const knownPid of knownPids) {
500
+ try {
501
+ const childrenRaw = (0, import_node_fs.readFileSync)(
502
+ `/proc/${knownPid}/task/${knownPid}/children`,
503
+ "utf8"
504
+ ).trim();
505
+ if (childrenRaw) {
506
+ for (const c of childrenRaw.split(/\s+/)) {
507
+ const cp = parseInt(c, 10);
508
+ if (!Number.isNaN(cp)) childPids.add(cp);
509
+ }
510
+ }
511
+ } catch {
512
+ }
513
+ }
514
+ for (const p of osProcesses) {
515
+ if (knownPids.has(p.pid)) continue;
516
+ try {
517
+ const statusContent = (0, import_node_fs.readFileSync)(`/proc/${p.pid}/status`, "utf8");
518
+ const ppidMatch = statusContent.match(/^PPid:\s+(\d+)/m);
519
+ if (ppidMatch) {
520
+ const ppid = parseInt(ppidMatch[1] ?? "0", 10);
521
+ if (knownPids.has(ppid)) childPids.add(p.pid);
522
+ }
523
+ } catch {
524
+ }
525
+ }
460
526
  const selfPid = process.pid;
461
527
  const selfPpid = process.ppid;
462
528
  const orphans = osProcesses.filter(
463
- (p) => !knownPids.has(p.pid) && p.pid !== selfPid && p.pid !== selfPpid
529
+ (p) => !knownPids.has(p.pid) && !childPids.has(p.pid) && p.pid !== selfPid && p.pid !== selfPpid
464
530
  );
465
531
  const problems = [];
466
532
  if (pidFile?.stale) problems.push(`Stale PID file: ${pidFile.reason}`);
467
533
  if (systemd?.crashLooping) problems.push("Systemd unit is crash-looping (auto-restart)");
468
534
  if (systemd?.failed) problems.push("Systemd unit has failed");
469
- if (systemd && systemd.restarts > 10) problems.push(`High systemd restart count: ${systemd.restarts}`);
535
+ if (systemd && systemd.restarts > 10)
536
+ problems.push(`High systemd restart count: ${systemd.restarts}`);
470
537
  if (pidFile?.pid && systemd?.mainPid && pidFile.pid !== systemd.mainPid) {
471
538
  problems.push(`PID mismatch: file says ${pidFile.pid}, systemd says ${systemd.mainPid}`);
472
539
  }
@@ -475,15 +542,24 @@ function auditProcesses(config) {
475
542
  if (w.stale) problems.push(`Worker "${w.name}" (pid ${w.pid}) declares running but is dead`);
476
543
  }
477
544
  }
478
- if (orphans.length > 0) problems.push(`${orphans.length} orphan process(es) not tracked by PID file or workers registry`);
545
+ if (orphans.length > 0)
546
+ problems.push(
547
+ `${orphans.length} orphan process(es) not tracked by PID file or workers registry`
548
+ );
479
549
  return { pidFile, systemd, workers, osProcesses, orphans, problems };
480
550
  }
481
551
  function formatAuditReport(result) {
482
552
  const lines = [];
483
553
  lines.push("");
484
- lines.push("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
485
- lines.push("\u2551 \u{1F50D} P R O C E S S A U D I T \u2551");
486
- lines.push("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
554
+ lines.push(
555
+ "\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"
556
+ );
557
+ lines.push(
558
+ "\u2551 \u{1F50D} P R O C E S S A U D I T \u2551"
559
+ );
560
+ lines.push(
561
+ "\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
562
+ );
487
563
  if (result.pidFile) {
488
564
  const pf = result.pidFile;
489
565
  const icon = pf.pid && pf.alive && pf.matchesProcess ? "\u2705" : pf.stale ? "\u26A0\uFE0F " : "\u2139\uFE0F ";
@@ -501,25 +577,33 @@ function formatAuditReport(result) {
501
577
  }
502
578
  if (result.workers) {
503
579
  const w = result.workers;
504
- lines.push(`
505
- Workers (orchestrator pid ${w.orchestratorPid ?? "unknown"} ${w.orchestratorAlive ? "\u2705" : "\u274C"})`);
580
+ lines.push(
581
+ `
582
+ Workers (orchestrator pid ${w.orchestratorPid ?? "unknown"} ${w.orchestratorAlive ? "\u2705" : "\u274C"})`
583
+ );
506
584
  for (const worker of w.workers) {
507
585
  const icon = worker.declaredStatus === "running" && worker.alive ? "\u{1F7E2}" : worker.stale ? "\u{1F534} STALE" : "\u26AA";
508
- lines.push(` ${icon} ${worker.name.padEnd(14)} pid=${String(worker.pid ?? "-").padEnd(8)} status=${worker.declaredStatus}`);
586
+ lines.push(
587
+ ` ${icon} ${worker.name.padEnd(14)} pid=${String(worker.pid ?? "-").padEnd(8)} status=${worker.declaredStatus}`
588
+ );
509
589
  }
510
590
  }
511
591
  if (result.osProcesses.length > 0) {
512
592
  lines.push(`
513
593
  OS Processes (${result.osProcesses.length} total)`);
514
594
  for (const p of result.osProcesses) {
515
- lines.push(` PID ${String(p.pid).padEnd(8)} CPU=${p.cpu.padEnd(6)} MEM=${p.mem.padEnd(6)} Up=${p.elapsed.padEnd(10)} ${p.command.substring(0, 50)}`);
595
+ lines.push(
596
+ ` PID ${String(p.pid).padEnd(8)} CPU=${p.cpu.padEnd(6)} MEM=${p.mem.padEnd(6)} Up=${p.elapsed.padEnd(10)} ${p.command.substring(0, 50)}`
597
+ );
516
598
  }
517
599
  }
518
600
  if (result.orphans.length > 0) {
519
601
  lines.push(`
520
602
  \u26A0\uFE0F ${result.orphans.length} ORPHAN PROCESS(ES):`);
521
603
  for (const p of result.orphans) {
522
- lines.push(` PID ${String(p.pid).padEnd(8)} CPU=${p.cpu.padEnd(6)} MEM=${p.mem.padEnd(6)} Up=${p.elapsed}`);
604
+ lines.push(
605
+ ` PID ${String(p.pid).padEnd(8)} CPU=${p.cpu.padEnd(6)} MEM=${p.mem.padEnd(6)} Up=${p.elapsed}`
606
+ );
523
607
  lines.push(` Started: ${p.started}`);
524
608
  lines.push(` Command: ${p.cmdline || p.command}`);
525
609
  }
@@ -557,14 +641,14 @@ function parseArgs(argv) {
557
641
  if (args[0] === "live") args.shift();
558
642
  let i = 0;
559
643
  while (i < args.length) {
560
- const arg = args[i];
644
+ const arg = args[i] ?? "";
561
645
  if (arg === "--help" || arg === "-h") {
562
646
  printUsage();
563
647
  process.exit(0);
564
648
  } else if (arg === "--refresh" || arg === "-r") {
565
649
  i++;
566
650
  const v = parseInt(args[i] ?? "", 10);
567
- if (!isNaN(v) && v > 0) config.refreshMs = v * 1e3;
651
+ if (!Number.isNaN(v) && v > 0) config.refreshMs = v * 1e3;
568
652
  i++;
569
653
  } else if (arg === "--recursive" || arg === "-R") {
570
654
  config.recursive = true;
@@ -645,12 +729,22 @@ function scanFiles(dirs, recursive) {
645
729
  if (!stat.isFile()) continue;
646
730
  if (f.endsWith(".json")) {
647
731
  seen.add(fp);
648
- const entry = { filename: f, path: fp, mtime: stat.mtime.getTime(), ext: ".json" };
732
+ const entry = {
733
+ filename: f,
734
+ path: fp,
735
+ mtime: stat.mtime.getTime(),
736
+ ext: ".json"
737
+ };
649
738
  results.push(entry);
650
739
  dirResults.push(entry);
651
740
  } else if (f.endsWith(".jsonl")) {
652
741
  seen.add(fp);
653
- const entry = { filename: f, path: fp, mtime: stat.mtime.getTime(), ext: ".jsonl" };
742
+ const entry = {
743
+ filename: f,
744
+ path: fp,
745
+ mtime: stat.mtime.getTime(),
746
+ ext: ".jsonl"
747
+ };
654
748
  results.push(entry);
655
749
  dirResults.push(entry);
656
750
  }
@@ -712,7 +806,7 @@ function findTimestamp(obj) {
712
806
  if (typeof val === "number") return val > 1e12 ? val : val * 1e3;
713
807
  if (typeof val === "string") {
714
808
  const d = Date.parse(val);
715
- if (!isNaN(d)) return d;
809
+ if (!Number.isNaN(d)) return d;
716
810
  }
717
811
  }
718
812
  return 0;
@@ -744,7 +838,7 @@ function extractDetail(obj) {
744
838
  }
745
839
  return parts.join(" | ") || "";
746
840
  }
747
- function tryLoadTrace(fp, raw) {
841
+ function tryLoadTrace(_fp, raw) {
748
842
  if (typeof raw !== "object" || raw === null) return null;
749
843
  const obj = raw;
750
844
  if (!("nodes" in obj)) return null;
@@ -854,7 +948,7 @@ function processJsonlFile(file) {
854
948
  if (!content) return [];
855
949
  const lines = content.split("\n");
856
950
  const lineCount = lines.length;
857
- const lastObj = JSON.parse(lines[lines.length - 1]);
951
+ const lastObj = JSON.parse(lines[lines.length - 1] ?? "{}");
858
952
  const name = lastObj.jobId ?? lastObj.agentId ?? lastObj.name ?? lastObj.id ?? nameFromFile(file.filename);
859
953
  if (lastObj.action !== void 0 || lastObj.jobId !== void 0) {
860
954
  const status2 = findStatus(lastObj);
@@ -950,7 +1044,7 @@ function processJsonlFile(file) {
950
1044
  }
951
1045
  const parts = [];
952
1046
  if (model) {
953
- const shortModel = model.includes("/") ? model.split("/").pop() : model;
1047
+ const shortModel = model.includes("/") ? model.split("/").pop() ?? model : model;
954
1048
  parts.push(shortModel.slice(0, 20));
955
1049
  }
956
1050
  if (toolCalls.length > 0) {
@@ -995,7 +1089,8 @@ function writeLine(lines, text) {
995
1089
  }
996
1090
  function flushLines(lines) {
997
1091
  process.stdout.write("\x1B[H");
998
- process.stdout.write(lines.join("\n") + "\n");
1092
+ process.stdout.write(`${lines.join("\n")}
1093
+ `);
999
1094
  process.stdout.write("\x1B[J");
1000
1095
  }
1001
1096
  var prevFileCount = 0;
@@ -1089,7 +1184,7 @@ function render(config) {
1089
1184
  const status = fail > 0 ? "error" : running > 0 ? "running" : ok > 0 ? "ok" : "unknown";
1090
1185
  groups.push({
1091
1186
  name: groupName,
1092
- source: records[0].source,
1187
+ source: records[0]?.source ?? "trace",
1093
1188
  status,
1094
1189
  lastTs,
1095
1190
  detail: `${records.length} agents`,
@@ -1114,15 +1209,15 @@ function render(config) {
1114
1209
  if (age > 36e5 || age < 0) continue;
1115
1210
  const idx = 11 - Math.floor(age / 3e5);
1116
1211
  if (idx >= 0 && idx < 12) {
1117
- buckets[idx]++;
1118
- if (r.status === "error") failBuckets[idx]++;
1212
+ buckets[idx] = (buckets[idx] ?? 0) + 1;
1213
+ if (r.status === "error") failBuckets[idx] = (failBuckets[idx] ?? 0) + 1;
1119
1214
  }
1120
1215
  }
1121
1216
  const maxBucket = Math.max(...buckets, 1);
1122
1217
  const sparkChars = " \u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";
1123
1218
  const spark = buckets.map((v, i) => {
1124
1219
  const level = Math.round(v / maxBucket * 8);
1125
- return (failBuckets[i] > 0 ? C.red : C.green) + sparkChars[level] + C.reset;
1220
+ return ((failBuckets[i] ?? 0) > 0 ? C.red : C.green) + sparkChars[level] + C.reset;
1126
1221
  }).join("");
1127
1222
  let auditResult = null;
1128
1223
  if (now - lastAuditTime > 1e4) {
@@ -1135,8 +1230,10 @@ function render(config) {
1135
1230
  cachedAuditResult = auditResult;
1136
1231
  lastAuditTime = now;
1137
1232
  } catch (err) {
1138
- process.stderr.write(`[agentflow] process audit error: ${err instanceof Error ? err.message : err}
1139
- `);
1233
+ process.stderr.write(
1234
+ `[agentflow] process audit error: ${err instanceof Error ? err.message : err}
1235
+ `
1236
+ );
1140
1237
  }
1141
1238
  }
1142
1239
  } else {
@@ -1193,7 +1290,7 @@ function render(config) {
1193
1290
  return new Date(ts).toLocaleTimeString();
1194
1291
  }
1195
1292
  function truncate(s, max) {
1196
- return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
1293
+ return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
1197
1294
  }
1198
1295
  const termWidth = process.stdout.columns || 120;
1199
1296
  const detailWidth = Math.max(20, termWidth - 60);
@@ -1234,7 +1331,8 @@ function render(config) {
1234
1331
  if (ar.systemd) {
1235
1332
  const si = ar.systemd.activeState === "active" ? `${C.green}\u25CF${C.reset}` : ar.systemd.crashLooping ? `${C.yellow}\u25CF${C.reset}` : ar.systemd.failed ? `${C.red}\u25CF${C.reset}` : `${C.dim}\u25CB${C.reset}`;
1236
1333
  sysdLabel = ` ${C.bold}Systemd${C.reset} ${si} ${ar.systemd.activeState}`;
1237
- if (ar.systemd.restarts > 0) sysdLabel += ` ${C.dim}(${ar.systemd.restarts} restarts)${C.reset}`;
1334
+ if (ar.systemd.restarts > 0)
1335
+ sysdLabel += ` ${C.dim}(${ar.systemd.restarts} restarts)${C.reset}`;
1238
1336
  }
1239
1337
  let pidLabel = "";
1240
1338
  if (ar.pidFile?.pid) {
@@ -1243,7 +1341,10 @@ function render(config) {
1243
1341
  }
1244
1342
  writeLine(L, "");
1245
1343
  writeLine(L, ` ${C.bold}${C.under}Process Health${C.reset}`);
1246
- writeLine(L, ` ${healthIcon} ${healthLabel}${pidLabel}${sysdLabel} ${C.bold}Procs${C.reset} ${C.dim}${ar.osProcesses.length}${C.reset} ${ar.orphans.length > 0 ? `${C.red}Orphans ${ar.orphans.length}${C.reset}` : `${C.dim}Orphans 0${C.reset}`}`);
1344
+ writeLine(
1345
+ L,
1346
+ ` ${healthIcon} ${healthLabel}${pidLabel}${sysdLabel} ${C.bold}Procs${C.reset} ${C.dim}${ar.osProcesses.length}${C.reset} ${ar.orphans.length > 0 ? `${C.red}Orphans ${ar.orphans.length}${C.reset}` : `${C.dim}Orphans 0${C.reset}`}`
1347
+ );
1247
1348
  if (workerParts.length > 0) {
1248
1349
  writeLine(L, ` ${C.dim}Workers${C.reset} ${workerParts.join(" ")}`);
1249
1350
  }
@@ -1255,7 +1356,10 @@ function render(config) {
1255
1356
  if (ar.orphans.length > 0) {
1256
1357
  for (const o of ar.orphans.slice(0, 5)) {
1257
1358
  const cmd = (o.cmdline || o.command).substring(0, detailWidth);
1258
- writeLine(L, ` ${C.red}?${C.reset} ${C.dim}pid=${o.pid} cpu=${o.cpu} mem=${o.mem} up=${o.elapsed}${C.reset} ${C.dim}${cmd}${C.reset}`);
1359
+ writeLine(
1360
+ L,
1361
+ ` ${C.red}?${C.reset} ${C.dim}pid=${o.pid} cpu=${o.cpu} mem=${o.mem} up=${o.elapsed}${C.reset} ${C.dim}${cmd}${C.reset}`
1362
+ );
1259
1363
  }
1260
1364
  if (ar.orphans.length > 5) {
1261
1365
  writeLine(L, ` ${C.dim}... +${ar.orphans.length - 5} more orphans${C.reset}`);
@@ -1329,7 +1433,7 @@ function render(config) {
1329
1433
  for (let i = 0; i < Math.min(tree.length, 6); i++) {
1330
1434
  const tg = tree[i];
1331
1435
  const depth = getDistDepth(dt, tg.spanId);
1332
- const indent = " " + "\u2502 ".repeat(Math.max(0, depth - 1));
1436
+ const indent = ` ${"\u2502 ".repeat(Math.max(0, depth - 1))}`;
1333
1437
  const isLast = i === tree.length - 1 || getDistDepth(dt, tree[i + 1]?.spanId) <= depth;
1334
1438
  const conn = depth === 0 ? " " : isLast ? "\u2514\u2500 " : "\u251C\u2500 ";
1335
1439
  const gs = tg.status === "completed" ? `${C.green}\u2713${C.reset}` : tg.status === "failed" ? `${C.red}\u2717${C.reset}` : `${C.yellow}\u23F3${C.reset}`;
@@ -1350,7 +1454,7 @@ function render(config) {
1350
1454
  const t = new Date(r.lastActive).toLocaleTimeString();
1351
1455
  const agent = truncate(r.id, 26).padEnd(26);
1352
1456
  const age = Math.floor((Date.now() - r.lastActive) / 1e3);
1353
- const ageStr = age < 60 ? age + "s ago" : age < 3600 ? Math.floor(age / 60) + "m ago" : Math.floor(age / 3600) + "h ago";
1457
+ const ageStr = age < 60 ? `${age}s ago` : age < 3600 ? `${Math.floor(age / 60)}m ago` : `${Math.floor(age / 3600)}h ago`;
1354
1458
  const det = truncate(r.detail, detailWidth);
1355
1459
  writeLine(
1356
1460
  L,
@@ -1364,7 +1468,7 @@ function render(config) {
1364
1468
  for (const d of config.dirs) writeLine(L, ` ${C.dim} ${d}${C.reset}`);
1365
1469
  }
1366
1470
  writeLine(L, "");
1367
- const dirLabel = config.dirs.length === 1 ? config.dirs[0] : `${config.dirs.length} directories`;
1471
+ const dirLabel = config.dirs.length === 1 ? config.dirs[0] ?? "" : `${config.dirs.length} directories`;
1368
1472
  writeLine(L, ` ${C.dim}Watching: ${dirLabel}${C.reset}`);
1369
1473
  writeLine(L, ` ${C.dim}Press Ctrl+C to exit${C.reset}`);
1370
1474
  flushLines(L);
@@ -1415,7 +1519,7 @@ function startLive(argv) {
1415
1519
  };
1416
1520
  process.on("SIGINT", () => {
1417
1521
  cleanup();
1418
- console.log(C.dim + "Monitor stopped." + C.reset);
1522
+ console.log(`${C.dim}Monitor stopped.${C.reset}`);
1419
1523
  process.exit(0);
1420
1524
  });
1421
1525
  process.on("SIGTERM", () => {
@@ -1430,7 +1534,7 @@ var import_node_fs3 = require("fs");
1430
1534
  var import_node_path3 = require("path");
1431
1535
 
1432
1536
  // src/graph-builder.ts
1433
- var import_crypto = require("crypto");
1537
+ var import_node_crypto = require("crypto");
1434
1538
  function deepFreeze(obj) {
1435
1539
  if (obj === null || typeof obj !== "object") return obj;
1436
1540
  if (obj instanceof Map) {
@@ -1461,8 +1565,8 @@ function createGraphBuilder(config) {
1461
1565
  const generateId = config?.idGenerator ?? createCounterIdGenerator();
1462
1566
  const agentId = config?.agentId ?? "unknown";
1463
1567
  const trigger = config?.trigger ?? "manual";
1464
- const spanId = (0, import_crypto.randomUUID)();
1465
- const traceId = config?.traceId ?? (typeof process !== "undefined" ? process.env?.AGENTFLOW_TRACE_ID : void 0) ?? (0, import_crypto.randomUUID)();
1568
+ const spanId = (0, import_node_crypto.randomUUID)();
1569
+ const traceId = config?.traceId ?? (typeof process !== "undefined" ? process.env?.AGENTFLOW_TRACE_ID : void 0) ?? (0, import_node_crypto.randomUUID)();
1466
1570
  const parentSpanId = config?.parentSpanId ?? (typeof process !== "undefined" ? process.env?.AGENTFLOW_PARENT_SPAN_ID : void 0) ?? null;
1467
1571
  const graphId = generateId();
1468
1572
  const startTime = Date.now();
@@ -1682,7 +1786,7 @@ function agentIdFromFilename(filePath) {
1682
1786
  const cleaned = base.replace(/-state$/, "");
1683
1787
  return `alfred-${cleaned}`;
1684
1788
  }
1685
- function deriveAgentId(command) {
1789
+ function deriveAgentId(_command) {
1686
1790
  return "orchestrator";
1687
1791
  }
1688
1792
  function fileTimestamp() {
@@ -1792,14 +1896,18 @@ async function runTraced(config) {
1792
1896
  const filename = `${graph.agentId}-${ts}.json`;
1793
1897
  const outPath = (0, import_node_path3.join)(resolvedTracesDir, filename);
1794
1898
  const resolvedOut = (0, import_node_path3.resolve)(outPath);
1795
- if (!resolvedOut.startsWith(resolvedTracesDir + "/") && resolvedOut !== resolvedTracesDir) {
1796
- throw new Error(`Path traversal detected: agentId "${graph.agentId}" escapes traces directory`);
1899
+ if (!resolvedOut.startsWith(`${resolvedTracesDir}/`) && resolvedOut !== resolvedTracesDir) {
1900
+ throw new Error(
1901
+ `Path traversal detected: agentId "${graph.agentId}" escapes traces directory`
1902
+ );
1797
1903
  }
1798
1904
  (0, import_node_fs3.writeFileSync)(outPath, JSON.stringify(graphToJson(graph), null, 2), "utf-8");
1799
1905
  tracePaths.push(outPath);
1800
1906
  }
1801
1907
  if (tracePaths.length > 0) {
1802
- console.log(`\u{1F50D} Run "agentflow trace show ${orchestratorGraph.id} --traces-dir ${resolvedTracesDir}" to inspect`);
1908
+ console.log(
1909
+ `\u{1F50D} Run "agentflow trace show ${orchestratorGraph.id} --traces-dir ${resolvedTracesDir}" to inspect`
1910
+ );
1803
1911
  }
1804
1912
  return {
1805
1913
  exitCode,
@@ -1812,11 +1920,11 @@ async function runTraced(config) {
1812
1920
  }
1813
1921
 
1814
1922
  // src/trace-cli.ts
1815
- var import_path2 = require("path");
1923
+ var import_node_path5 = require("path");
1816
1924
 
1817
1925
  // src/trace-store.ts
1818
1926
  var import_promises = require("fs/promises");
1819
- var import_path = require("path");
1927
+ var import_node_path4 = require("path");
1820
1928
  init_loader();
1821
1929
  function createTraceStore(dir) {
1822
1930
  async function ensureDir() {
@@ -1834,7 +1942,7 @@ function createTraceStore(dir) {
1834
1942
  for (const file of files) {
1835
1943
  if (!file.endsWith(".json")) continue;
1836
1944
  try {
1837
- const content = await (0, import_promises.readFile)((0, import_path.join)(dir, file), "utf-8");
1945
+ const content = await (0, import_promises.readFile)((0, import_node_path4.join)(dir, file), "utf-8");
1838
1946
  const graph = loadGraph(content);
1839
1947
  graphs.push(graph);
1840
1948
  } catch {
@@ -1846,10 +1954,10 @@ function createTraceStore(dir) {
1846
1954
  async save(graph) {
1847
1955
  await ensureDir();
1848
1956
  const json = graphToJson(graph);
1849
- const filePath = (0, import_path.join)(dir, `${graph.id}.json`);
1850
- const resolvedBase = (0, import_path.resolve)(dir);
1851
- const resolvedPath = (0, import_path.resolve)(filePath);
1852
- if (!resolvedPath.startsWith(resolvedBase + "/") && resolvedPath !== resolvedBase) {
1957
+ const filePath = (0, import_node_path4.join)(dir, `${graph.id}.json`);
1958
+ const resolvedBase = (0, import_node_path4.resolve)(dir);
1959
+ const resolvedPath = (0, import_node_path4.resolve)(filePath);
1960
+ if (!resolvedPath.startsWith(`${resolvedBase}/`) && resolvedPath !== resolvedBase) {
1853
1961
  throw new Error(`Path traversal detected: "${graph.id}" escapes base directory`);
1854
1962
  }
1855
1963
  await (0, import_promises.writeFile)(filePath, JSON.stringify(json, null, 2), "utf-8");
@@ -1857,7 +1965,7 @@ function createTraceStore(dir) {
1857
1965
  },
1858
1966
  async get(graphId) {
1859
1967
  await ensureDir();
1860
- const filePath = (0, import_path.join)(dir, `${graphId}.json`);
1968
+ const filePath = (0, import_node_path4.join)(dir, `${graphId}.json`);
1861
1969
  try {
1862
1970
  const content = await (0, import_promises.readFile)(filePath, "utf-8");
1863
1971
  return loadGraph(content);
@@ -1979,7 +2087,8 @@ function toAsciiTree(graph) {
1979
2087
  const children = getChildren(graph, nodeId);
1980
2088
  const childPrefix = isRoot ? "" : prefix + (isLast ? " " : "\u2502 ");
1981
2089
  for (let i = 0; i < children.length; i++) {
1982
- renderNode(children[i].id, childPrefix, i === children.length - 1, false);
2090
+ const childId = children[i]?.id;
2091
+ if (childId) renderNode(childId, childPrefix, i === children.length - 1, false);
1983
2092
  }
1984
2093
  }
1985
2094
  renderNode(graph.rootNodeId, "", true, true);
@@ -2053,9 +2162,9 @@ function toTimeline(graph) {
2053
2162
  function getTracesDir(argv) {
2054
2163
  const idx = argv.indexOf("--traces-dir");
2055
2164
  if (idx !== -1 && argv[idx + 1]) {
2056
- return (0, import_path2.resolve)(argv[idx + 1]);
2165
+ return (0, import_node_path5.resolve)(argv[idx + 1]);
2057
2166
  }
2058
- return (0, import_path2.resolve)("./traces");
2167
+ return (0, import_node_path5.resolve)("./traces");
2059
2168
  }
2060
2169
  function getFlag(argv, name) {
2061
2170
  const idx = argv.indexOf(name);
@@ -2241,7 +2350,7 @@ async function handleTrace(argv) {
2241
2350
  // src/watch.ts
2242
2351
  var import_node_fs5 = require("fs");
2243
2352
  var import_node_os = require("os");
2244
- var import_node_path4 = require("path");
2353
+ var import_node_path6 = require("path");
2245
2354
 
2246
2355
  // src/watch-alerts.ts
2247
2356
  var import_node_child_process3 = require("child_process");
@@ -2367,10 +2476,10 @@ function parseDuration(input) {
2367
2476
  const match = input.match(/^(\d+(?:\.\d+)?)\s*(s|m|h|d)$/i);
2368
2477
  if (!match) {
2369
2478
  const n = parseInt(input, 10);
2370
- return isNaN(n) ? 0 : n * 1e3;
2479
+ return Number.isNaN(n) ? 0 : n * 1e3;
2371
2480
  }
2372
- const value = parseFloat(match[1]);
2373
- switch (match[2].toLowerCase()) {
2481
+ const value = parseFloat(match[1] ?? "0");
2482
+ switch (match[2]?.toLowerCase()) {
2374
2483
  case "s":
2375
2484
  return value * 1e3;
2376
2485
  case "m":
@@ -2397,7 +2506,7 @@ function loadWatchState(filePath) {
2397
2506
  }
2398
2507
  }
2399
2508
  function saveWatchState(filePath, state) {
2400
- const tmp = filePath + ".tmp";
2509
+ const tmp = `${filePath}.tmp`;
2401
2510
  try {
2402
2511
  (0, import_node_fs4.writeFileSync)(tmp, JSON.stringify(state, null, 2), "utf8");
2403
2512
  (0, import_node_fs4.renameSync)(tmp, filePath);
@@ -2413,12 +2522,12 @@ function estimateInterval(history) {
2413
2522
  const sorted = [...history].sort((a, b) => a - b);
2414
2523
  const deltas = [];
2415
2524
  for (let i = 1; i < sorted.length; i++) {
2416
- const d = sorted[i] - sorted[i - 1];
2525
+ const d = (sorted[i] ?? 0) - (sorted[i - 1] ?? 0);
2417
2526
  if (d > 0) deltas.push(d);
2418
2527
  }
2419
2528
  if (deltas.length === 0) return 0;
2420
2529
  deltas.sort((a, b) => a - b);
2421
- return deltas[Math.floor(deltas.length / 2)];
2530
+ return deltas[Math.floor(deltas.length / 2)] ?? 0;
2422
2531
  }
2423
2532
  function detectTransitions(previous, currentRecords, config, now) {
2424
2533
  const alerts = [];
@@ -2575,7 +2684,7 @@ function parseWatchArgs(argv) {
2575
2684
  if (args[0] === "watch") args.shift();
2576
2685
  let i = 0;
2577
2686
  while (i < args.length) {
2578
- const arg = args[i];
2687
+ const arg = args[i] ?? "";
2579
2688
  if (arg === "--help" || arg === "-h") {
2580
2689
  printWatchUsage();
2581
2690
  process.exit(0);
@@ -2598,8 +2707,8 @@ function parseWatchArgs(argv) {
2598
2707
  i++;
2599
2708
  const val = args[i] ?? "";
2600
2709
  if (val === "telegram") {
2601
- const botToken = process.env["AGENTFLOW_TELEGRAM_BOT_TOKEN"] ?? "";
2602
- const chatId = process.env["AGENTFLOW_TELEGRAM_CHAT_ID"] ?? "";
2710
+ const botToken = process.env.AGENTFLOW_TELEGRAM_BOT_TOKEN ?? "";
2711
+ const chatId = process.env.AGENTFLOW_TELEGRAM_CHAT_ID ?? "";
2603
2712
  if (botToken && chatId) {
2604
2713
  notifyChannels.push({ type: "telegram", botToken, chatId });
2605
2714
  } else {
@@ -2616,7 +2725,7 @@ function parseWatchArgs(argv) {
2616
2725
  } else if (arg === "--poll") {
2617
2726
  i++;
2618
2727
  const v = parseInt(args[i] ?? "", 10);
2619
- if (!isNaN(v) && v > 0) pollIntervalMs = v * 1e3;
2728
+ if (!Number.isNaN(v) && v > 0) pollIntervalMs = v * 1e3;
2620
2729
  i++;
2621
2730
  } else if (arg === "--cooldown") {
2622
2731
  i++;
@@ -2631,20 +2740,20 @@ function parseWatchArgs(argv) {
2631
2740
  recursive = true;
2632
2741
  i++;
2633
2742
  } else if (!arg.startsWith("-")) {
2634
- dirs.push((0, import_node_path4.resolve)(arg));
2743
+ dirs.push((0, import_node_path6.resolve)(arg));
2635
2744
  i++;
2636
2745
  } else {
2637
2746
  i++;
2638
2747
  }
2639
2748
  }
2640
- if (dirs.length === 0) dirs.push((0, import_node_path4.resolve)("."));
2749
+ if (dirs.length === 0) dirs.push((0, import_node_path6.resolve)("."));
2641
2750
  if (alertConditions.length === 0) {
2642
2751
  alertConditions.push({ type: "error" });
2643
2752
  alertConditions.push({ type: "recovery" });
2644
2753
  }
2645
2754
  notifyChannels.unshift({ type: "stdout" });
2646
2755
  if (!stateFilePath) {
2647
- stateFilePath = (0, import_node_path4.join)(dirs[0], ".agentflow-watch-state.json");
2756
+ stateFilePath = (0, import_node_path6.join)(dirs[0] ?? ".", ".agentflow-watch-state.json");
2648
2757
  }
2649
2758
  return {
2650
2759
  dirs,
@@ -2652,7 +2761,7 @@ function parseWatchArgs(argv) {
2652
2761
  pollIntervalMs,
2653
2762
  alertConditions,
2654
2763
  notifyChannels,
2655
- stateFilePath: (0, import_node_path4.resolve)(stateFilePath),
2764
+ stateFilePath: (0, import_node_path6.resolve)(stateFilePath),
2656
2765
  cooldownMs
2657
2766
  };
2658
2767
  }
@@ -2732,7 +2841,7 @@ agentflow watch started`);
2732
2841
  console.log(` Poll: ${config.pollIntervalMs / 1e3}s`);
2733
2842
  console.log(` Alert on: ${condLabels.join(", ")}`);
2734
2843
  console.log(
2735
- ` Notify: stdout${channelLabels.length > 0 ? ", " + channelLabels.join(", ") : ""}`
2844
+ ` Notify: stdout${channelLabels.length > 0 ? `, ${channelLabels.join(", ")}` : ""}`
2736
2845
  );
2737
2846
  console.log(` Cooldown: ${Math.floor(config.cooldownMs / 6e4)}m`);
2738
2847
  console.log(` State: ${config.stateFilePath}`);
@@ -2936,11 +3045,11 @@ async function runCommand(argv) {
2936
3045
  if (result.tracePaths.length > 0) {
2937
3046
  console.log("\u{1F4DD} Traces saved:");
2938
3047
  const orchPath = result.tracePaths[0];
2939
- const orchName = (0, import_path3.basename)(orchPath, ".json").split("-")[0] ?? "orchestrator";
3048
+ const orchName = (0, import_node_path7.basename)(orchPath, ".json").split("-")[0] ?? "orchestrator";
2940
3049
  console.log(` ${orchName.padEnd(14)} \u2192 ${orchPath}`);
2941
3050
  for (let i = 1; i < result.tracePaths.length; i++) {
2942
3051
  const tPath = result.tracePaths[i];
2943
- const name = (0, import_path3.basename)(tPath, ".json").replace(/-\d{4}-.*$/, "");
3052
+ const name = (0, import_node_path7.basename)(tPath, ".json").replace(/-\d{4}-.*$/, "");
2944
3053
  const isLast = i === result.tracePaths.length - 1;
2945
3054
  const prefix = isLast ? "\u2514\u2500" : "\u251C\u2500";
2946
3055
  console.log(` ${prefix} ${name.padEnd(12)} \u2192 ${tPath} (state changed)`);
@@ -2965,7 +3074,7 @@ function parseAuditArgs(argv) {
2965
3074
  if (args[0] === "audit") args.shift();
2966
3075
  let i = 0;
2967
3076
  while (i < args.length) {
2968
- const arg = args[i];
3077
+ const arg = args[i] ?? "";
2969
3078
  if (arg === "--help" || arg === "-h") {
2970
3079
  printAuditUsage();
2971
3080
  process.exit(0);
@@ -2989,7 +3098,7 @@ function parseAuditArgs(argv) {
2989
3098
  systemdUnit = null;
2990
3099
  i++;
2991
3100
  } else if (!arg.startsWith("-")) {
2992
- discoverDirs.push((0, import_path3.resolve)(arg));
3101
+ discoverDirs.push((0, import_node_path7.resolve)(arg));
2993
3102
  i++;
2994
3103
  } else {
2995
3104
  i++;
@@ -2998,12 +3107,16 @@ function parseAuditArgs(argv) {
2998
3107
  if (!processName && !pidFile && !workersFile && discoverDirs.length > 0) {
2999
3108
  const discovered = discoverProcessConfig(discoverDirs);
3000
3109
  if (discovered) {
3001
- console.log(`Auto-discovered: process="${discovered.processName}"${discovered.pidFile ? ` pid-file=${discovered.pidFile}` : ""}${discovered.workersFile ? ` workers=${discovered.workersFile}` : ""}`);
3110
+ console.log(
3111
+ `Auto-discovered: process="${discovered.processName}"${discovered.pidFile ? ` pid-file=${discovered.pidFile}` : ""}${discovered.workersFile ? ` workers=${discovered.workersFile}` : ""}`
3112
+ );
3002
3113
  return { ...discovered, systemdUnit };
3003
3114
  }
3004
3115
  }
3005
3116
  if (!processName) {
3006
- console.error("Error: --process <name> is required, or provide directories for auto-discovery.");
3117
+ console.error(
3118
+ "Error: --process <name> is required, or provide directories for auto-discovery."
3119
+ );
3007
3120
  console.error("Examples:");
3008
3121
  console.error(" agentflow audit --process alfred --pid-file ./data/alfred.pid");
3009
3122
  console.error(" agentflow audit ./data # auto-discovers *.pid and workers.json");
@@ -3051,7 +3164,7 @@ function runAudit(argv) {
3051
3164
  async function main() {
3052
3165
  const argv = process.argv.slice(2);
3053
3166
  const knownCommands = ["run", "live", "watch", "trace", "audit"];
3054
- if (argv.length === 0 || !knownCommands.includes(argv[0]) && (argv.includes("--help") || argv.includes("-h"))) {
3167
+ if (argv.length === 0 || !knownCommands.includes(argv[0] ?? "") && (argv.includes("--help") || argv.includes("-h"))) {
3055
3168
  printHelp();
3056
3169
  process.exit(0);
3057
3170
  }