@4pm/cli 1.12.1 → 1.14.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 (2) hide show
  1. package/dist/index.js +44 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -32526,8 +32526,15 @@ function compareSemver(a, b2) {
32526
32526
  }
32527
32527
  return 0;
32528
32528
  }
32529
+ function canonVersion(v2) {
32530
+ const s3 = v2.trim().replace(/^v/i, "").toLowerCase();
32531
+ const m2 = /^(\d+\.\d+\.\d+)(.*)$/.exec(s3);
32532
+ if (!m2) return s3;
32533
+ const suffix = m2[2].replace(/^[-+]/, "");
32534
+ return suffix ? `${m2[1]}-${suffix}` : m2[1];
32535
+ }
32529
32536
  function shouldUpdateTo(current2, latest) {
32530
- return current2 !== latest && compareSemver(current2, latest) <= 0;
32537
+ return canonVersion(current2) !== canonVersion(latest) && compareSemver(current2, latest) <= 0;
32531
32538
  }
32532
32539
  function runningInstallRoot() {
32533
32540
  return dirname2(dirname2(fileURLToPath2(import.meta.url)));
@@ -32543,16 +32550,48 @@ function readInstalledVersion() {
32543
32550
  return "0.0.0";
32544
32551
  }
32545
32552
  }
32553
+ var NPM_INSTALL_TIMEOUT_MS = 18e4;
32554
+ var DOWNLOAD_TIMEOUT_MS = 6e4;
32555
+ function tailReason(raw) {
32556
+ const s3 = raw.trim();
32557
+ return s3.length > 800 ? `\u2026${s3.slice(-800)}` : s3;
32558
+ }
32546
32559
  function updateViaNpm(version) {
32547
32560
  if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(version)) {
32548
32561
  throw new Error(`Refusing to update: invalid version string "${version}".`);
32549
32562
  }
32550
- execSync2(`npm i -g @4pm/cli@${version}`, { stdio: "inherit" });
32563
+ try {
32564
+ execSync2(`npm i -g @4pm/cli@${version}`, {
32565
+ stdio: ["ignore", "pipe", "pipe"],
32566
+ encoding: "utf8",
32567
+ timeout: NPM_INSTALL_TIMEOUT_MS
32568
+ });
32569
+ } catch (err) {
32570
+ const e = err;
32571
+ if (e.killed) {
32572
+ throw new Error(`npm install timed out after ${NPM_INSTALL_TIMEOUT_MS / 1e3}s (\`npm i -g @4pm/cli@${version}\`).`);
32573
+ }
32574
+ const out = `${e.stderr?.toString() ?? ""}
32575
+ ${e.stdout?.toString() ?? ""}`;
32576
+ const reason = tailReason(out) || e.message || "npm install failed";
32577
+ throw new Error(`npm install failed: ${reason}`);
32578
+ }
32551
32579
  }
32552
32580
  async function updateViaDownload(tarballUrl, checksum, signature) {
32553
- const res = await fetch(tarballUrl);
32554
- if (!res.ok) throw new Error(`Failed to download tarball: HTTP ${res.status}`);
32555
- const buf = Buffer.from(await res.arrayBuffer());
32581
+ const controller = new AbortController();
32582
+ const timer = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
32583
+ let buf;
32584
+ try {
32585
+ const res = await fetch(tarballUrl, { signal: controller.signal });
32586
+ if (!res.ok) throw new Error(`Failed to download tarball: HTTP ${res.status}`);
32587
+ buf = Buffer.from(await res.arrayBuffer());
32588
+ } catch (err) {
32589
+ throw new Error(
32590
+ controller.signal.aborted ? `Downloading the update tarball timed out after ${DOWNLOAD_TIMEOUT_MS / 1e3}s.` : `Failed to download tarball: ${String(err)}`
32591
+ );
32592
+ } finally {
32593
+ clearTimeout(timer);
32594
+ }
32556
32595
  const actual = createHash2("sha256").update(buf).digest("hex");
32557
32596
  if (actual !== checksum) {
32558
32597
  throw new Error("Tarball checksum mismatch \u2014 aborting update (ADR-0015).");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4pm/cli",
3
- "version": "1.12.1",
3
+ "version": "1.14.0",
4
4
  "private": false,
5
5
  "description": "4PM CLI — drives Claude/Codex CLIs on AI worker machines (Node + TypeScript)",
6
6
  "license": "LicenseRef-4PM-Source-Available",