squad-openclaw 2026.2.2201 → 2026.2.2203
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 +114 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2183,7 +2183,7 @@ function registerSqlTools(api) {
|
|
|
2183
2183
|
}
|
|
2184
2184
|
|
|
2185
2185
|
// src/version.ts
|
|
2186
|
-
import {
|
|
2186
|
+
import { spawn } from "child_process";
|
|
2187
2187
|
import fs9 from "fs";
|
|
2188
2188
|
import path10 from "path";
|
|
2189
2189
|
import { fileURLToPath } from "url";
|
|
@@ -2193,6 +2193,9 @@ var updateInProgress = false;
|
|
|
2193
2193
|
var VERIFY_TIMEOUT_MS = 2e4;
|
|
2194
2194
|
var VERIFY_INTERVAL_MS = 500;
|
|
2195
2195
|
var RESTART_BUFFER_MS = 5e3;
|
|
2196
|
+
var REGISTRY_TIMEOUT_MS = 2500;
|
|
2197
|
+
var COMMAND_OUTPUT_LIMIT = 8e3;
|
|
2198
|
+
var COMMAND_KILL_GRACE_MS = 2e3;
|
|
2196
2199
|
function readInstalledVersionFromConfig() {
|
|
2197
2200
|
try {
|
|
2198
2201
|
const raw = fs9.readFileSync(CONFIG_PATH, "utf-8");
|
|
@@ -2243,9 +2246,9 @@ function getCurrentVersion() {
|
|
|
2243
2246
|
return "0.0.0";
|
|
2244
2247
|
}
|
|
2245
2248
|
}
|
|
2246
|
-
async function fetchLatestVersion() {
|
|
2249
|
+
async function fetchLatestVersion(timeoutMs = REGISTRY_TIMEOUT_MS) {
|
|
2247
2250
|
const controller = new AbortController();
|
|
2248
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
2251
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
2249
2252
|
try {
|
|
2250
2253
|
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`, {
|
|
2251
2254
|
signal: controller.signal
|
|
@@ -2257,14 +2260,64 @@ async function fetchLatestVersion() {
|
|
|
2257
2260
|
clearTimeout(timeout);
|
|
2258
2261
|
}
|
|
2259
2262
|
}
|
|
2260
|
-
function
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2263
|
+
async function runCommand(args, timeoutMs) {
|
|
2264
|
+
return new Promise((resolve) => {
|
|
2265
|
+
const child = spawn("openclaw", args, {
|
|
2266
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
2267
|
+
detached: true
|
|
2265
2268
|
});
|
|
2266
|
-
|
|
2267
|
-
|
|
2269
|
+
let output = "";
|
|
2270
|
+
let timedOut = false;
|
|
2271
|
+
let resolved = false;
|
|
2272
|
+
let killGraceTimer = null;
|
|
2273
|
+
const append = (chunk) => {
|
|
2274
|
+
output += chunk.toString();
|
|
2275
|
+
if (output.length > COMMAND_OUTPUT_LIMIT) {
|
|
2276
|
+
output = output.slice(output.length - COMMAND_OUTPUT_LIMIT);
|
|
2277
|
+
}
|
|
2278
|
+
};
|
|
2279
|
+
const finalize = (result) => {
|
|
2280
|
+
if (resolved) return;
|
|
2281
|
+
resolved = true;
|
|
2282
|
+
if (killGraceTimer) clearTimeout(killGraceTimer);
|
|
2283
|
+
clearTimeout(timeout);
|
|
2284
|
+
resolve(result);
|
|
2285
|
+
};
|
|
2286
|
+
child.stdout?.on("data", append);
|
|
2287
|
+
child.stderr?.on("data", append);
|
|
2288
|
+
child.on("error", (err2) => {
|
|
2289
|
+
append(String(err2));
|
|
2290
|
+
finalize({
|
|
2291
|
+
ok: false,
|
|
2292
|
+
timedOut,
|
|
2293
|
+
exitCode: null,
|
|
2294
|
+
signal: null,
|
|
2295
|
+
output
|
|
2296
|
+
});
|
|
2297
|
+
});
|
|
2298
|
+
child.on("close", (code, signal) => {
|
|
2299
|
+
finalize({
|
|
2300
|
+
ok: !timedOut && code === 0,
|
|
2301
|
+
timedOut,
|
|
2302
|
+
exitCode: code,
|
|
2303
|
+
signal,
|
|
2304
|
+
output
|
|
2305
|
+
});
|
|
2306
|
+
});
|
|
2307
|
+
const timeout = setTimeout(() => {
|
|
2308
|
+
timedOut = true;
|
|
2309
|
+
try {
|
|
2310
|
+
process.kill(-child.pid, "SIGTERM");
|
|
2311
|
+
} catch {
|
|
2312
|
+
}
|
|
2313
|
+
killGraceTimer = setTimeout(() => {
|
|
2314
|
+
try {
|
|
2315
|
+
process.kill(-child.pid, "SIGKILL");
|
|
2316
|
+
} catch {
|
|
2317
|
+
}
|
|
2318
|
+
}, COMMAND_KILL_GRACE_MS);
|
|
2319
|
+
}, timeoutMs);
|
|
2320
|
+
});
|
|
2268
2321
|
}
|
|
2269
2322
|
function sleep(ms) {
|
|
2270
2323
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -2399,13 +2452,25 @@ async function waitForVerifiedInstall() {
|
|
|
2399
2452
|
function registerVersionMethods(api) {
|
|
2400
2453
|
api.registerGatewayMethod(
|
|
2401
2454
|
"squad.version.check",
|
|
2402
|
-
async ({ respond }) => {
|
|
2455
|
+
async ({ respond, params }) => {
|
|
2403
2456
|
try {
|
|
2457
|
+
const checkParams = params ?? {};
|
|
2404
2458
|
const current = getCurrentVersion();
|
|
2459
|
+
if (checkParams.skipRegistry) {
|
|
2460
|
+
console.log("[version_check_local] returning local version only");
|
|
2461
|
+
respond(true, {
|
|
2462
|
+
current,
|
|
2463
|
+
latest: null,
|
|
2464
|
+
updateAvailable: false,
|
|
2465
|
+
registrySkipped: true
|
|
2466
|
+
});
|
|
2467
|
+
return;
|
|
2468
|
+
}
|
|
2405
2469
|
let latest;
|
|
2406
2470
|
try {
|
|
2407
2471
|
latest = await fetchLatestVersion();
|
|
2408
2472
|
} catch {
|
|
2473
|
+
console.log("[version_check_registry_timeout] npm registry unavailable");
|
|
2409
2474
|
respond(true, {
|
|
2410
2475
|
current,
|
|
2411
2476
|
latest: null,
|
|
@@ -2433,6 +2498,7 @@ function registerVersionMethods(api) {
|
|
|
2433
2498
|
return;
|
|
2434
2499
|
}
|
|
2435
2500
|
updateInProgress = true;
|
|
2501
|
+
const updateAttemptId = `${Date.now()}-${Math.random().toString(16).slice(2, 8)}`;
|
|
2436
2502
|
try {
|
|
2437
2503
|
const before = getCurrentVersion();
|
|
2438
2504
|
const beforeInstalledVersion = readInstalledVersionFromConfig();
|
|
@@ -2448,19 +2514,25 @@ function registerVersionMethods(api) {
|
|
|
2448
2514
|
configBackup = fs9.readFileSync(CONFIG_PATH, "utf-8");
|
|
2449
2515
|
} catch {
|
|
2450
2516
|
}
|
|
2451
|
-
|
|
2517
|
+
await runCommand(["doctor", "--fix"], 3e4);
|
|
2452
2518
|
try {
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2519
|
+
const first = await runCommand(["plugins", "update", PACKAGE_NAME], 12e4);
|
|
2520
|
+
updateOutput = first.output;
|
|
2521
|
+
if (!first.ok) {
|
|
2522
|
+
throw new Error(
|
|
2523
|
+
first.timedOut ? "UPDATE_TIMEOUT: plugins update timed out" : `UPDATE_FAILED: plugins update exited with code ${String(first.exitCode)}`
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2457
2526
|
} catch (firstErr) {
|
|
2458
|
-
|
|
2527
|
+
await runCommand(["doctor", "--fix"], 3e4);
|
|
2459
2528
|
try {
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2529
|
+
const retry = await runCommand(["plugins", "update", PACKAGE_NAME], 12e4);
|
|
2530
|
+
updateOutput = retry.output;
|
|
2531
|
+
if (!retry.ok) {
|
|
2532
|
+
throw new Error(
|
|
2533
|
+
retry.timedOut ? "UPDATE_TIMEOUT: plugins update timed out after retry" : `UPDATE_FAILED: plugins update retry exited with code ${String(retry.exitCode)}`
|
|
2534
|
+
);
|
|
2535
|
+
}
|
|
2464
2536
|
} catch (installErr) {
|
|
2465
2537
|
if (configBackup) {
|
|
2466
2538
|
try {
|
|
@@ -2471,9 +2543,11 @@ function registerVersionMethods(api) {
|
|
|
2471
2543
|
const firstMsg = firstErr instanceof Error ? firstErr.message : String(firstErr);
|
|
2472
2544
|
const retryMsg = installErr instanceof Error ? installErr.message : String(installErr);
|
|
2473
2545
|
respond(false, {
|
|
2546
|
+
code: /UPDATE_TIMEOUT/.test(retryMsg) ? "UPDATE_TIMEOUT" : "UPDATE_FAILED",
|
|
2474
2547
|
error: `Update failed after doctor fix retry: ${retryMsg}`,
|
|
2475
2548
|
output: updateOutput,
|
|
2476
|
-
firstError: firstMsg
|
|
2549
|
+
firstError: firstMsg,
|
|
2550
|
+
updateAttemptId
|
|
2477
2551
|
});
|
|
2478
2552
|
return;
|
|
2479
2553
|
}
|
|
@@ -2487,9 +2561,11 @@ function registerVersionMethods(api) {
|
|
|
2487
2561
|
}
|
|
2488
2562
|
}
|
|
2489
2563
|
respond(false, {
|
|
2564
|
+
code: "VERIFY_FAILED",
|
|
2490
2565
|
error: `Update verification failed: ${verification.reason ?? "unknown error"}`,
|
|
2491
2566
|
output: updateOutput.slice(0, 500),
|
|
2492
|
-
verification
|
|
2567
|
+
verification,
|
|
2568
|
+
updateAttemptId
|
|
2493
2569
|
});
|
|
2494
2570
|
return;
|
|
2495
2571
|
}
|
|
@@ -2498,10 +2574,12 @@ function registerVersionMethods(api) {
|
|
|
2498
2574
|
if (beforeInstalledVersion && verificationAfterReconcile.packageVersion && beforeInstalledVersion === verificationAfterReconcile.packageVersion) {
|
|
2499
2575
|
const alreadyLatest = !!latestVersion && compareVersions(verificationAfterReconcile.packageVersion, latestVersion) >= 0;
|
|
2500
2576
|
respond(false, {
|
|
2577
|
+
code: "UPDATE_FAILED",
|
|
2501
2578
|
error: alreadyLatest ? `Already at latest version (${verificationAfterReconcile.packageVersion}).` : `Update command completed but installed version did not change (${verificationAfterReconcile.packageVersion}).`,
|
|
2502
2579
|
output: updateOutput.slice(0, 500),
|
|
2503
2580
|
verification: verificationAfterReconcile,
|
|
2504
|
-
latestVersion
|
|
2581
|
+
latestVersion,
|
|
2582
|
+
updateAttemptId
|
|
2505
2583
|
});
|
|
2506
2584
|
return;
|
|
2507
2585
|
}
|
|
@@ -2514,22 +2592,27 @@ function registerVersionMethods(api) {
|
|
|
2514
2592
|
restartInMs: RESTART_BUFFER_MS,
|
|
2515
2593
|
verification: verificationAfterReconcile,
|
|
2516
2594
|
latestVersion,
|
|
2517
|
-
output: updateOutput.slice(0, 500)
|
|
2595
|
+
output: updateOutput.slice(0, 500),
|
|
2596
|
+
updateAttemptId
|
|
2518
2597
|
});
|
|
2519
2598
|
await sleep(RESTART_BUFFER_MS);
|
|
2520
2599
|
console.log(
|
|
2521
2600
|
`[version] Plugin update verified (was ${before}), restarting gateway...`
|
|
2522
2601
|
);
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2602
|
+
const restartResult = await runCommand(["gateway", "restart"], 3e4);
|
|
2603
|
+
if (!restartResult.ok && !restartResult.timedOut) {
|
|
2604
|
+
console.log("[update_cmd_timeout] restart command failed unexpectedly", {
|
|
2605
|
+
updateAttemptId,
|
|
2606
|
+
exitCode: restartResult.exitCode,
|
|
2607
|
+
signal: restartResult.signal
|
|
2527
2608
|
});
|
|
2528
|
-
} catch {
|
|
2529
2609
|
}
|
|
2530
2610
|
} catch (e) {
|
|
2531
2611
|
const msg = e instanceof Error ? e.message : String(e);
|
|
2532
|
-
respond(false, {
|
|
2612
|
+
respond(false, {
|
|
2613
|
+
code: /VERIFY_FAILED/.test(msg) ? "VERIFY_FAILED" : /UPDATE_TIMEOUT/.test(msg) ? "UPDATE_TIMEOUT" : "UPDATE_FAILED",
|
|
2614
|
+
error: msg
|
|
2615
|
+
});
|
|
2533
2616
|
} finally {
|
|
2534
2617
|
updateInProgress = false;
|
|
2535
2618
|
}
|
package/package.json
CHANGED