@4pm/cli 1.10.2 → 1.11.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.js +42 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28541,8 +28541,14 @@ function selfUnlink(serverUrl, hashcode3) {
|
|
|
28541
28541
|
return post(serverUrl, "/machine-links/self-unlink", { hashcode3 });
|
|
28542
28542
|
}
|
|
28543
28543
|
async function fetchCliVersion(serverUrl) {
|
|
28544
|
-
const
|
|
28545
|
-
|
|
28544
|
+
const ctrl = new AbortController();
|
|
28545
|
+
const timer = setTimeout(() => ctrl.abort(), 2e4);
|
|
28546
|
+
try {
|
|
28547
|
+
const res = await fetch(`${serverUrl}/meta/cli-version`, { signal: ctrl.signal });
|
|
28548
|
+
return unwrap(res);
|
|
28549
|
+
} finally {
|
|
28550
|
+
clearTimeout(timer);
|
|
28551
|
+
}
|
|
28546
28552
|
}
|
|
28547
28553
|
|
|
28548
28554
|
// vendor/@4pm/constants/preferences.ts
|
|
@@ -32520,6 +32526,9 @@ function compareSemver(a, b2) {
|
|
|
32520
32526
|
}
|
|
32521
32527
|
return 0;
|
|
32522
32528
|
}
|
|
32529
|
+
function shouldUpdateTo(current2, latest) {
|
|
32530
|
+
return current2 !== latest && compareSemver(current2, latest) <= 0;
|
|
32531
|
+
}
|
|
32523
32532
|
function runningInstallRoot() {
|
|
32524
32533
|
return dirname2(dirname2(fileURLToPath2(import.meta.url)));
|
|
32525
32534
|
}
|
|
@@ -32572,10 +32581,10 @@ async function updateViaDownload(tarballUrl, checksum, signature) {
|
|
|
32572
32581
|
throw new Error(`Failed to extract the update tarball into ${installRoot}: ${String(err)}`);
|
|
32573
32582
|
}
|
|
32574
32583
|
}
|
|
32575
|
-
async function updateToLatest(serverUrl) {
|
|
32584
|
+
async function updateToLatest(serverUrl, force = false) {
|
|
32576
32585
|
if (CLI_VERSION.startsWith("0.0.0")) return { action: "dev-build", version: CLI_VERSION };
|
|
32577
32586
|
const meta = await fetchCliVersion(serverUrl);
|
|
32578
|
-
if (
|
|
32587
|
+
if (!force && !shouldUpdateTo(CLI_VERSION, meta.latest)) {
|
|
32579
32588
|
return { action: "already-latest", version: CLI_VERSION };
|
|
32580
32589
|
}
|
|
32581
32590
|
console.log(t("update.updating", { from: CLI_VERSION, to: meta.latest }));
|
|
@@ -32593,7 +32602,7 @@ async function updateToLatest(serverUrl) {
|
|
|
32593
32602
|
return { action: "failed", error: String(err), toVersion: meta.latest };
|
|
32594
32603
|
}
|
|
32595
32604
|
const installed = readInstalledVersion();
|
|
32596
|
-
if (
|
|
32605
|
+
if (shouldUpdateTo(installed, meta.latest)) {
|
|
32597
32606
|
return {
|
|
32598
32607
|
action: "failed",
|
|
32599
32608
|
error: `update ran but the installed version is still ${installed} (expected ${meta.latest}) \u2014 it did not apply to the running install at ${runningInstallRoot()}.`,
|
|
@@ -32612,7 +32621,7 @@ async function checkAndUpdate(serverUrl, autoUpdate) {
|
|
|
32612
32621
|
return { action: "none" };
|
|
32613
32622
|
}
|
|
32614
32623
|
const mandatory = compareSemver(CLI_VERSION, meta.minSupported) < 0;
|
|
32615
|
-
const outdated =
|
|
32624
|
+
const outdated = shouldUpdateTo(CLI_VERSION, meta.latest);
|
|
32616
32625
|
if (!outdated) return { action: "none" };
|
|
32617
32626
|
if (!mandatory && !autoUpdate) {
|
|
32618
32627
|
console.warn(t("update.newVersionAutoUpdateOff", { latest: meta.latest, current: CLI_VERSION }));
|
|
@@ -32644,7 +32653,7 @@ async function checkAndUpdate(serverUrl, autoUpdate) {
|
|
|
32644
32653
|
return { action: "none" };
|
|
32645
32654
|
}
|
|
32646
32655
|
const installed = readInstalledVersion();
|
|
32647
|
-
if (
|
|
32656
|
+
if (shouldUpdateTo(installed, meta.latest)) {
|
|
32648
32657
|
const msg = t("update.notApplied", { installed, expected: meta.latest });
|
|
32649
32658
|
if (mandatory) {
|
|
32650
32659
|
console.error(msg);
|
|
@@ -37003,6 +37012,10 @@ var workerToolCopySchema = external_exports.object({
|
|
|
37003
37012
|
/** Target machine-link ids to queue the manifest for (pushed on their next connect). */
|
|
37004
37013
|
targetLinkIds: external_exports.array(external_exports.string().uuid()).min(1).max(200)
|
|
37005
37014
|
});
|
|
37015
|
+
var adminPoolToolsCopySchema = external_exports.object({
|
|
37016
|
+
sourceUserId: external_exports.string().uuid(),
|
|
37017
|
+
targetUserIds: external_exports.array(external_exports.string().uuid()).min(1).max(200)
|
|
37018
|
+
});
|
|
37006
37019
|
var workerToolInstallSchema = external_exports.object({
|
|
37007
37020
|
/** Catalog id or npm package name (validated npm-name shape on the cli). */
|
|
37008
37021
|
name: external_exports.string().trim().min(1).max(214),
|
|
@@ -38282,6 +38295,12 @@ function sleep(ms2) {
|
|
|
38282
38295
|
t2.unref?.();
|
|
38283
38296
|
});
|
|
38284
38297
|
}
|
|
38298
|
+
function extractToolError(out) {
|
|
38299
|
+
const lines = out.split(/\r?\n/).map((l) => l.trim()).filter((l) => l && !/^npm warn\b/i.test(l));
|
|
38300
|
+
const errLines = lines.filter((l) => /npm error|npm err!|ERR_|ELIFECYCLE|unsupported engine|e404|etarget/i.test(l));
|
|
38301
|
+
const msg = (errLines.length ? errLines : lines).slice(-3).join(" \xB7 ");
|
|
38302
|
+
return msg.length > 500 ? `${msg.slice(0, 500)}\u2026` : msg;
|
|
38303
|
+
}
|
|
38285
38304
|
function classifyToolFailure(code, out) {
|
|
38286
38305
|
if (code === 124) return { reason: "timeout", retryable: true };
|
|
38287
38306
|
const t2 = out.toLowerCase();
|
|
@@ -38421,8 +38440,10 @@ async function runWorkerToolOp(op, name, manager, onLine, timeoutMs = TOOL_INSTA
|
|
|
38421
38440
|
return { ok: false, exitCode: 1, error: resolved.error ?? "Invalid package." };
|
|
38422
38441
|
}
|
|
38423
38442
|
onLine(`$ ${manager} ${opArgs(op, manager, resolved.pkg).join(" ")}`);
|
|
38424
|
-
const { code } = await run3(manager, opArgs(op, manager, resolved.pkg), onLine, timeoutMs);
|
|
38425
|
-
|
|
38443
|
+
const { code, out } = await run3(manager, opArgs(op, manager, resolved.pkg), onLine, timeoutMs);
|
|
38444
|
+
if (code === 0) return { ok: true, exitCode: code };
|
|
38445
|
+
const detail = extractToolError(out);
|
|
38446
|
+
return { ok: false, exitCode: code, error: detail ? `${manager} exited ${code}: ${detail}` : `${manager} exited ${code}` };
|
|
38426
38447
|
}
|
|
38427
38448
|
function setToolAutoUpdate(profileDir2, name, enabled) {
|
|
38428
38449
|
const resolved = resolvePackage(name, "update");
|
|
@@ -38456,7 +38477,8 @@ async function installPinned(name, version, manager, onLine, timeoutMs = TOOL_IN
|
|
|
38456
38477
|
if (code === 0) return { ok: true };
|
|
38457
38478
|
const { reason, retryable } = classifyToolFailure(code, out);
|
|
38458
38479
|
if (!retryable || attempt === TOOL_INSTALL_MAX_ATTEMPTS) {
|
|
38459
|
-
|
|
38480
|
+
const detail = extractToolError(out);
|
|
38481
|
+
return { ok: false, error: detail ? `${manager} exited ${code}: ${detail}` : `${manager} exited ${code}`, reason, retryable };
|
|
38460
38482
|
}
|
|
38461
38483
|
const base = TOOL_RETRY_BASE_MS * 3 ** (attempt - 1);
|
|
38462
38484
|
const wait = Math.round(base * (0.8 + Math.random() * 0.4));
|
|
@@ -38592,7 +38614,7 @@ var UpdateScheduler = class {
|
|
|
38592
38614
|
if (this.forcedPending) {
|
|
38593
38615
|
if (this.bus.busy !== null) return;
|
|
38594
38616
|
this.forcedPending = false;
|
|
38595
|
-
await this.runUpdate();
|
|
38617
|
+
await this.runUpdate(true);
|
|
38596
38618
|
return;
|
|
38597
38619
|
}
|
|
38598
38620
|
const p2 = this.policy;
|
|
@@ -38608,15 +38630,16 @@ var UpdateScheduler = class {
|
|
|
38608
38630
|
if (this.bus.busy !== null) return;
|
|
38609
38631
|
this.lastDoneDateKey = clock.dateKey;
|
|
38610
38632
|
this.pendingDateKey = null;
|
|
38611
|
-
await this.runUpdate();
|
|
38633
|
+
await this.runUpdate(false);
|
|
38612
38634
|
}
|
|
38613
|
-
/** Check + update, then re-exec the new binary on success (keeps `.cre`/profile).
|
|
38614
|
-
|
|
38635
|
+
/** Check + update, then re-exec the new binary on success (keeps `.cre`/profile). `force` installs the
|
|
38636
|
+
* server's latest unconditionally (an operator push) vs. the conditional daily-scheduled update. */
|
|
38637
|
+
async runUpdate(force) {
|
|
38615
38638
|
this.updating = true;
|
|
38616
38639
|
try {
|
|
38617
38640
|
await this.updateFlaggedTools();
|
|
38618
38641
|
this.bus.log(t("update.scheduledChecking"));
|
|
38619
|
-
const result = await updateToLatest(this.serverUrl);
|
|
38642
|
+
const result = await updateToLatest(this.serverUrl, force);
|
|
38620
38643
|
if (result.action === "already-latest") {
|
|
38621
38644
|
logger.info("update.scheduled.latest", { version: result.version });
|
|
38622
38645
|
return;
|
|
@@ -42201,7 +42224,10 @@ function handleToolsChannels(ctx, message, payload) {
|
|
|
42201
42224
|
ctx.send(WsChannels.TOOLS_DONE, {
|
|
42202
42225
|
opId,
|
|
42203
42226
|
ok: restoreFailed.length === 0,
|
|
42204
|
-
exitCode: restoreFailed.length === 0 ? 0 : 1
|
|
42227
|
+
exitCode: restoreFailed.length === 0 ? 0 : 1,
|
|
42228
|
+
// Name the tools that failed + their classified reason so the web card shows more than a
|
|
42229
|
+
// bare "failed" (the real per-tool npm/pnpm error already streamed in the log above).
|
|
42230
|
+
error: restoreFailed.length === 0 ? void 0 : restoreFailed.map((f2) => `${f2.name} (${f2.reason})`).join(", ")
|
|
42205
42231
|
});
|
|
42206
42232
|
await ctx.reportWorkerTools(restoreTrigger, restoreFailed);
|
|
42207
42233
|
}).catch(
|