@lark-apaas/openclaw-scripts-diagnose-cli 0.1.1-alpha.17 → 0.1.1-alpha.19

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.cjs +168 -217
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -996,20 +996,6 @@ function runRepair(input) {
996
996
  }
997
997
  }
998
998
  //#endregion
999
- //#region src/logger.ts
1000
- function makeLogger(logFile) {
1001
- try {
1002
- const dir = node_path.default.dirname(logFile);
1003
- if (!node_fs.default.existsSync(dir)) node_fs.default.mkdirSync(dir, { recursive: true });
1004
- } catch {}
1005
- return (msg) => {
1006
- const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}\n`;
1007
- try {
1008
- node_fs.default.appendFileSync(logFile, line);
1009
- } catch {}
1010
- };
1011
- }
1012
- //#endregion
1013
999
  //#region src/paths.ts
1014
1000
  /**
1015
1001
  * Central directory for all ephemeral diagnose/reset artifacts: task status
@@ -1017,10 +1003,6 @@ function makeLogger(logFile) {
1017
1003
  * (`reset-<taskId>.log`). Having everything under one dir makes debugging a
1018
1004
  * stuck reset much easier — `ls /tmp/openclaw-diagnose/` shows every recent
1019
1005
  * run, and each run's log is right next to its state.
1020
- *
1021
- * This dir is ephemeral (/tmp). Long-lived artifacts (e.g. core-backup.json
1022
- * used by reset to restore agents/bindings) live under the agent's .spark/
1023
- * directory instead, see CORE_BACKUP_PATH in reset.ts.
1024
1006
  */
1025
1007
  const DIAGNOSE_DIR = "/tmp/openclaw-diagnose";
1026
1008
  function resetResultFile(taskId) {
@@ -1029,131 +1011,19 @@ function resetResultFile(taskId) {
1029
1011
  function resetLogFile(taskId) {
1030
1012
  return `${DIAGNOSE_DIR}/reset-${taskId}.log`;
1031
1013
  }
1032
- function backupLogFile(taskId) {
1033
- return `${DIAGNOSE_DIR}/backup-${taskId}.log`;
1034
- }
1035
1014
  //#endregion
1036
- //#region src/backup.ts
1037
- const BACKUP_PATH = "/home/gem/workspace/agent/.spark/core-backup.json";
1038
- /**
1039
- * Async entry: spawn a detached worker that does the actual backup, return
1040
- * immediately with `{success: true}` (or `{success: false}` if spawn itself
1041
- * fails). The caller (Go side) treats backup as fire-and-forget, so it doesn't
1042
- * need to wait for completion. Each run gets a per-task log under
1043
- * /tmp/openclaw-diagnose/backup-<taskId>.log for postmortem debugging.
1044
- */
1045
- function startAsyncBackup(ctxBase64) {
1046
- const taskId = (0, node_crypto.randomUUID)();
1047
- const log = makeLogger(backupLogFile(taskId));
1048
- log(`=== startAsyncBackup spawning worker for taskId=${taskId} ===`);
1049
- try {
1050
- const child = (0, node_child_process.spawn)(process.execPath, [
1051
- process.argv[1],
1052
- "backup",
1053
- "--worker",
1054
- `--task-id=${taskId}`,
1055
- `--ctx=${ctxBase64}`
1056
- ], {
1057
- detached: true,
1058
- stdio: "ignore"
1059
- });
1060
- child.on("error", (err) => {
1061
- log(`FATAL worker failed to start: ${err.message}`);
1062
- });
1063
- child.unref();
1064
- log(`spawned worker pid=${child.pid}`);
1065
- return {
1066
- success: true,
1067
- taskId
1068
- };
1069
- } catch (e) {
1070
- log(`spawn threw: ${e.message}`);
1071
- return {
1072
- success: false,
1073
- error: "spawn backup worker failed: " + e.message,
1074
- taskId
1075
- };
1076
- }
1077
- }
1078
- /**
1079
- * Worker: actually do the backup. Each step is logged so a stuck or failing
1080
- * backup can be diagnosed by `cat /tmp/openclaw-diagnose/backup-<taskId>.log`.
1081
- *
1082
- * The real time sink here is `openclaw config validate --json` which can sit
1083
- * for tens of seconds when the sandbox is under load — that's why backup is
1084
- * async (Go callers don't have to block waiting on it).
1085
- */
1086
- function runBackup(input, taskId) {
1087
- const log = taskId ? makeLogger(backupLogFile(taskId)) : (() => {});
1088
- const startedAt = Date.now();
1089
- log(`=== runBackup started, configPath=${input.configPath}, pid=${process.pid} ===`);
1015
+ //#region src/logger.ts
1016
+ function makeLogger(logFile) {
1090
1017
  try {
1091
- const { configPath } = input;
1092
- log("step 1: openclaw config validate --json");
1093
- const t1 = Date.now();
1094
- let validation;
1018
+ const dir = node_path.default.dirname(logFile);
1019
+ if (!node_fs.default.existsSync(dir)) node_fs.default.mkdirSync(dir, { recursive: true });
1020
+ } catch {}
1021
+ return (msg) => {
1022
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}\n`;
1095
1023
  try {
1096
- const validateOutput = shell("openclaw config validate --json");
1097
- validation = JSON.parse(validateOutput);
1098
- } catch (e) {
1099
- const msg = "config validate command failed: " + e.message;
1100
- log(`step 1 FAIL after ${Date.now() - t1}ms: ${msg}`);
1101
- return {
1102
- success: false,
1103
- error: msg
1104
- };
1105
- }
1106
- log(`step 1 done in ${Date.now() - t1}ms, valid=${validation.valid}`);
1107
- if (!validation.valid) return {
1108
- success: false,
1109
- error: "config validation failed"
1110
- };
1111
- log("step 2: read + parse config");
1112
- if (!fileExists(configPath)) {
1113
- const msg = "config file not found: " + configPath;
1114
- log(`step 2 FAIL: ${msg}`);
1115
- return {
1116
- success: false,
1117
- error: msg
1118
- };
1119
- }
1120
- const config = loadJSON5().parse(readFile(configPath));
1121
- const backup = { _backup_meta: { created_at: (/* @__PURE__ */ new Date()).toISOString() } };
1122
- const kept = [];
1123
- if (config.agents) {
1124
- backup.agents = config.agents;
1125
- kept.push("agents");
1126
- }
1127
- if (config.bindings) {
1128
- backup.bindings = config.bindings;
1129
- kept.push("bindings");
1130
- }
1131
- if (config.tools) {
1132
- backup.tools = config.tools;
1133
- kept.push("tools");
1134
- }
1135
- const feishu = config.channels?.feishu;
1136
- if (feishu?.accounts) {
1137
- backup.channels = { feishu: { accounts: feishu.accounts } };
1138
- kept.push("channels.feishu.accounts");
1139
- }
1140
- log(`step 3: extracted [${kept.join(", ") || "nothing"}]`);
1141
- const backupDir = node_path.default.dirname(BACKUP_PATH);
1142
- if (!node_fs.default.existsSync(backupDir)) node_fs.default.mkdirSync(backupDir, { recursive: true });
1143
- const tmpPath = BACKUP_PATH + ".tmp";
1144
- node_fs.default.writeFileSync(tmpPath, JSON.stringify(backup, null, 2), "utf-8");
1145
- node_fs.default.renameSync(tmpPath, BACKUP_PATH);
1146
- log(`step 4: wrote ${BACKUP_PATH} (${JSON.stringify(backup).length} bytes)`);
1147
- log(`=== runBackup completed in ${Date.now() - startedAt}ms ===`);
1148
- return { success: true };
1149
- } catch (e) {
1150
- const msg = "backup failed: " + e.message;
1151
- log(`FATAL after ${Date.now() - startedAt}ms: ${msg}\n${e.stack ?? ""}`);
1152
- return {
1153
- success: false,
1154
- error: msg
1155
- };
1156
- }
1024
+ node_fs.default.appendFileSync(logFile, line);
1025
+ } catch {}
1026
+ };
1157
1027
  }
1158
1028
  //#endregion
1159
1029
  //#region src/reset-async.ts
@@ -1215,14 +1085,15 @@ const STEPS = [
1215
1085
  "生成默认配置",
1216
1086
  "杀掉 openclaw 进程",
1217
1087
  "等待沙箱初始化完成",
1218
- "重装 openclaw",
1088
+ "确认 openclaw 版本",
1219
1089
  "合并核心备份配置",
1220
1090
  "复制启动脚本",
1221
- "重装内置插件",
1091
+ "安装扩展",
1222
1092
  "启动并验证"
1223
1093
  ];
1224
1094
  const TOTAL_STEPS = STEPS.length;
1225
- const CORE_BACKUP_PATH = "/home/gem/workspace/agent/.spark/core-backup.json";
1095
+ /** Pre-packed extensions archive on OSS. Update this URL when releasing a new version. */
1096
+ const EXTENSIONS_OSS_URL = "https://miaoda-template-online.oss-cn-beijing.aliyuncs.com/builtin/tool/pkg/openclaw-extensions-2026.4.9.tar.gz";
1226
1097
  /**
1227
1098
  * Directory holding the bundled openclaw template (openclaw.json + scripts/).
1228
1099
  * Synced from git@code.byted.org:apaas/miaoda-openclaw-template.git via
@@ -1347,33 +1218,50 @@ function waitForInitNpm(maxWaitMs, log) {
1347
1218
  /**
1348
1219
  * Step 5: Ensure openclaw binary is at the template's recommended version.
1349
1220
  *
1350
- * Fast path (common): if `openclaw --version` already matches the version
1351
- * declared in the bundled template's openclaw.json, skip uninstall+install
1352
- * entirely and just run `openclaw doctor --fix` to realign config state.
1353
- *
1354
- * Slow path (rare only triggers if version mismatched or binary missing):
1355
- * uninstall + reinstall + doctor --fix. This is intentionally kept as a
1356
- * last resort because a transitive dep (matrix-sdk-crypto-nodejs) runs a
1357
- * postinstall hook that downloads a 22MB native binary from GitHub
1358
- * Releases, and the BOE sandbox's egress to objects.githubusercontent.com
1359
- * is throttled to ~10KB/s — a full reinstall can legitimately take 30+
1360
- * minutes. Hence we only pay that cost when version actually needs to change.
1221
+ * Only checks/installs the binary — does NOT run `doctor --fix` any more.
1222
+ * Extensions are installed separately via OSS tar.gz (Step 8), which means
1223
+ * the openclaw-lark extension schema is already in place when openclaw
1224
+ * starts, avoiding the schema-priority mismatch that caused doctor to
1225
+ * reject valid config fields like threadSession / footer.
1361
1226
  */
1362
- function reinstallOpenclaw(srcDir, log) {
1227
+ function ensureOpenclawBinary(srcDir, log) {
1363
1228
  const targetVersion = loadJSON5().parse(node_fs.default.readFileSync(node_path.default.join(srcDir, "openclaw.json"), "utf-8")).meta?.lastTouchedVersion;
1364
1229
  log(`target openclaw version: ${targetVersion ?? "<unset>"}`);
1365
1230
  if (targetVersion && isOpenclawAtVersion(targetVersion)) {
1366
- log("fast path: openclaw already at target version, skipping uninstall+install");
1367
- const t = Date.now();
1368
- shell("openclaw doctor --fix", 10 * 6e4);
1369
- log(`doctor --fix done in ${Date.now() - t}ms`);
1231
+ log("openclaw already at target version, nothing to do");
1370
1232
  return;
1371
1233
  }
1372
- log("version mismatched or binary missing, running full reinstall (may take 30+ min under slow network)");
1373
- try {
1234
+ if (isOpenclawInstalled()) {
1235
+ const updateCmd = `openclaw update${targetVersion ? " --tag v" + targetVersion : ""} --yes`;
1236
+ log(`openclaw installed but version mismatched, running: ${updateCmd}`);
1237
+ const timeout = 12 * 6e4;
1374
1238
  const t = Date.now();
1239
+ try {
1240
+ shell(updateCmd, timeout);
1241
+ log(`openclaw update done in ${Date.now() - t}ms`);
1242
+ } catch (e) {
1243
+ const elapsed = Date.now() - t;
1244
+ if (elapsed >= timeout - 1e3) log(`openclaw update timed out after ${elapsed}ms (non-fatal, continuing)`);
1245
+ else throw e;
1246
+ }
1247
+ } else {
1248
+ log("openclaw binary not found, running full reinstall");
1249
+ fullReinstall(targetVersion, log);
1250
+ }
1251
+ }
1252
+ /** Check if openclaw command exists (regardless of version). */
1253
+ function isOpenclawInstalled() {
1254
+ try {
1255
+ shell("which openclaw 2>/dev/null", 5e3);
1256
+ return true;
1257
+ } catch {
1258
+ return false;
1259
+ }
1260
+ }
1261
+ /** Full uninstall + reinstall from npm (slow path, triggers postinstall). */
1262
+ function fullReinstall(targetVersion, log) {
1263
+ try {
1375
1264
  shell("npm uninstall -g openclaw 2>/dev/null || true", 6e4);
1376
- log(`npm uninstall done in ${Date.now() - t}ms`);
1377
1265
  } catch {}
1378
1266
  try {
1379
1267
  shell("rm -rf /home/gem/.npm-global/lib/node_modules/openclaw /home/gem/.npm-global/bin/openclaw 2>/dev/null || true", 1e4);
@@ -1381,12 +1269,9 @@ function reinstallOpenclaw(srcDir, log) {
1381
1269
  } catch {}
1382
1270
  const installCmd = `npm i -g openclaw@${targetVersion || "latest"}`;
1383
1271
  log(`running: ${installCmd}`);
1384
- const installStart = Date.now();
1272
+ const t = Date.now();
1385
1273
  shell(installCmd, 30 * 6e4);
1386
- log(`npm install done in ${Date.now() - installStart}ms`);
1387
- const docStart = Date.now();
1388
- shell("openclaw doctor --fix", 10 * 6e4);
1389
- log(`doctor --fix done in ${Date.now() - docStart}ms`);
1274
+ log(`npm install done in ${Date.now() - t}ms`);
1390
1275
  }
1391
1276
  /** Return true if `openclaw --version` output contains `targetVersion`. */
1392
1277
  function isOpenclawAtVersion(targetVersion) {
@@ -1396,42 +1281,71 @@ function isOpenclawAtVersion(targetVersion) {
1396
1281
  return false;
1397
1282
  }
1398
1283
  }
1399
- /** Step 6: Merge core-backup.json into config + ensure allowedOrigins. */
1400
- function mergeCoreBackupAndOrigins(configPath, vars, log) {
1284
+ /** Step 6: Merge coreBackup from resetData + ensure allowedOrigins. */
1285
+ function mergeCoreBackupAndOrigins(configPath, vars, resetData, log) {
1401
1286
  const JSON5 = loadJSON5();
1402
- if (fileExists(CORE_BACKUP_PATH)) {
1403
- const backup = JSON.parse(node_fs.default.readFileSync(CORE_BACKUP_PATH, "utf-8"));
1287
+ const backup = resetData.coreBackup;
1288
+ if (backup) {
1404
1289
  const config = JSON5.parse(node_fs.default.readFileSync(configPath, "utf-8"));
1405
1290
  const merged = [];
1406
- if (backup.agents) {
1407
- config.agents = backup.agents;
1408
- merged.push("agents");
1291
+ if (backup.agents && backup.agents.length > 0) {
1292
+ if (!config.agents) config.agents = {};
1293
+ const agents = config.agents;
1294
+ if (!Array.isArray(agents.list)) agents.list = [];
1295
+ const configDir = node_path.default.dirname(configPath);
1296
+ for (const agent of backup.agents) {
1297
+ const enriched = {
1298
+ id: agent.id,
1299
+ name: agent.id,
1300
+ workspace: agent.workspace,
1301
+ agentDir: configDir + "/agents/" + agent.id + "/agent"
1302
+ };
1303
+ agents.list.push(enriched);
1304
+ }
1305
+ merged.push(`agents(+${backup.agents.length})`);
1306
+ const list = agents.list;
1307
+ let mainIdx = list.findIndex((a) => a.id === "main");
1308
+ if (mainIdx < 0) {
1309
+ list.unshift({ id: "main" });
1310
+ mainIdx = 0;
1311
+ }
1312
+ list[mainIdx].subagents = { allowAgents: ["*"] };
1313
+ list[mainIdx].default = true;
1314
+ merged.push("main-team-mode");
1315
+ const feishu = config.channels?.feishu;
1316
+ if (feishu) {
1317
+ if (!feishu.accounts) feishu.accounts = {};
1318
+ const accounts = feishu.accounts;
1319
+ const defaultAccount = {};
1320
+ for (const key of [
1321
+ "dmPolicy",
1322
+ "allowFrom",
1323
+ "groupPolicy",
1324
+ "groupAllowFrom"
1325
+ ]) if (feishu[key] !== void 0) defaultAccount[key] = feishu[key];
1326
+ if (Object.keys(defaultAccount).length > 0) {
1327
+ accounts.default = defaultAccount;
1328
+ merged.push("accounts.default");
1329
+ }
1330
+ }
1409
1331
  }
1410
- if (backup.bindings) {
1332
+ if (backup.bindings && backup.bindings.length > 0) {
1411
1333
  config.bindings = backup.bindings;
1412
1334
  merged.push("bindings");
1413
1335
  }
1414
- const backupAccounts = backup.channels?.feishu;
1415
- if (backupAccounts?.accounts) {
1336
+ const backupAccounts = backup.channels?.feishu?.accounts;
1337
+ if (backupAccounts && Object.keys(backupAccounts).length > 0) {
1416
1338
  if (!config.channels) config.channels = {};
1417
1339
  const ch = config.channels;
1418
1340
  if (!ch.feishu) ch.feishu = {};
1419
- ch.feishu.accounts = backupAccounts.accounts;
1341
+ const feishu = ch.feishu;
1342
+ if (!feishu.accounts) feishu.accounts = {};
1343
+ Object.assign(feishu.accounts, backupAccounts);
1420
1344
  merged.push("channels.feishu.accounts");
1421
1345
  }
1422
- const backupDeny = backup.tools?.deny;
1423
- if ((Array.isArray(backupDeny) ? backupDeny.filter((o) => typeof o === "string") : []).includes("agents_list")) {
1424
- if (!config.tools) config.tools = {};
1425
- const tools = config.tools;
1426
- const currentDeny = Array.isArray(tools.deny) ? tools.deny.filter((o) => typeof o === "string") : [];
1427
- if (!currentDeny.includes("agents_list")) {
1428
- tools.deny = [...currentDeny, "agents_list"];
1429
- merged.push("tools.deny+=agents_list");
1430
- }
1431
- }
1432
1346
  node_fs.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
1433
- log(`merged from ${CORE_BACKUP_PATH}: [${merged.join(", ") || "nothing"}]`);
1434
- } else log(`no backup at ${CORE_BACKUP_PATH}, skip merge`);
1347
+ log(`merged from coreBackup: [${merged.join(", ") || "nothing"}]`);
1348
+ } else log("no coreBackup in resetData, skip multi-agent merge");
1435
1349
  const expectedOrigins = Array.isArray(vars.expectedOrigins) ? vars.expectedOrigins : [];
1436
1350
  if (expectedOrigins.length === 0) {
1437
1351
  log("no expectedOrigins provided");
@@ -1472,20 +1386,69 @@ function copyStartupScripts(srcDir, configDir, log) {
1472
1386
  log(`copied scripts/* -> ${targetScriptsDir}`);
1473
1387
  }
1474
1388
  /**
1475
- * Step 8: Reinstall all plugins via openclaw CLI.
1389
+ * Step 8: Install extensions from OSS tar.gz or fall back to `openclaw plugins update`.
1390
+ *
1391
+ * 1. Derive the OSS URL from the openclaw version in the template config
1392
+ * 2. Download tar.gz → extract to a staging dir
1393
+ * 3. For each included extension, backup (mv) the user's existing copy
1394
+ * to a temp dir — extensions NOT in the archive are left untouched
1395
+ * 4. Move the fresh extensions from staging to the target dir
1476
1396
  *
1477
- * Simple execSync with a generous wall-clock timeout (15min). By now
1478
- * init_sandbox's npm should have finished (Step 4 waited for it), so we
1479
- * have exclusive npm access. Non-fatal a plugin update failure shouldn't
1480
- * stop the reset from restarting the gateway.
1397
+ * This bypasses npm entirely and avoids the schema-priority mismatch where
1398
+ * `openclaw doctor --fix` would validate config against the bundled feishu
1399
+ * plugin's strict schema before openclaw-lark is installed.
1400
+ *
1401
+ * Falls back to `openclaw plugins update --all` if the OSS download fails.
1481
1402
  */
1482
- function reinstallPlugins(log) {
1483
- const t = Date.now();
1403
+ function installExtensions(configDir, log) {
1404
+ const ossUrl = EXTENSIONS_OSS_URL;
1405
+ const targetExtDir = node_path.default.join(configDir, "extensions");
1406
+ const tmpBase = `/tmp/openclaw-ext-reset-${Date.now()}`;
1407
+ const stagingDir = node_path.default.join(tmpBase, "staging");
1408
+ const backupDir = node_path.default.join(tmpBase, "backup");
1409
+ const tarPath = node_path.default.join(tmpBase, "extensions.tar.gz");
1410
+ node_fs.default.mkdirSync(stagingDir, { recursive: true });
1411
+ node_fs.default.mkdirSync(backupDir, { recursive: true });
1484
1412
  try {
1485
- shell("openclaw plugins update --all", 15 * 6e4);
1486
- log(`plugins update --all done in ${Date.now() - t}ms`);
1487
- } catch (e) {
1488
- log(`plugins update failed after ${Date.now() - t}ms: ${e.message} (non-fatal, continuing)`);
1413
+ log(`downloading extensions from ${ossUrl}`);
1414
+ const dlStart = Date.now();
1415
+ shell(`curl -fsSL '${ossUrl}' -o '${tarPath}'`, 5 * 6e4);
1416
+ const size = node_fs.default.statSync(tarPath).size;
1417
+ log(`download done in ${Date.now() - dlStart}ms (${(size / 1024 / 1024).toFixed(1)}MB)`);
1418
+ shell(`tar -xzf '${tarPath}' -C '${stagingDir}'`, 6e4);
1419
+ const stagedExtDir = node_path.default.join(stagingDir, "extensions");
1420
+ if (!node_fs.default.existsSync(stagedExtDir)) throw new Error("tar.gz does not contain an extensions/ directory");
1421
+ const extNames = node_fs.default.readdirSync(stagedExtDir).filter((name) => node_fs.default.statSync(node_path.default.join(stagedExtDir, name)).isDirectory());
1422
+ log(`archive contains ${extNames.length} extension(s): ${extNames.join(", ")}`);
1423
+ if (!node_fs.default.existsSync(targetExtDir)) node_fs.default.mkdirSync(targetExtDir, { recursive: true });
1424
+ for (const name of extNames) {
1425
+ const target = node_path.default.join(targetExtDir, name);
1426
+ const staged = node_path.default.join(stagedExtDir, name);
1427
+ if (node_fs.default.existsSync(target)) {
1428
+ const backupDest = node_path.default.join(backupDir, name);
1429
+ node_fs.default.renameSync(target, backupDest);
1430
+ log(` ${name}: backed up existing to ${backupDest}`);
1431
+ }
1432
+ node_fs.default.renameSync(staged, target);
1433
+ log(` ${name}: installed`);
1434
+ }
1435
+ const packinfo = node_path.default.join(stagedExtDir, ".packinfo.json");
1436
+ if (node_fs.default.existsSync(packinfo)) {
1437
+ const info = node_fs.default.readFileSync(packinfo, "utf-8");
1438
+ node_fs.default.copyFileSync(packinfo, node_path.default.join(targetExtDir, ".packinfo.json"));
1439
+ log(`packinfo: ${info.trim()}`);
1440
+ }
1441
+ log("extensions installed from OSS successfully");
1442
+ } finally {
1443
+ try {
1444
+ node_fs.default.unlinkSync(tarPath);
1445
+ } catch {}
1446
+ try {
1447
+ node_fs.default.rmSync(stagingDir, {
1448
+ recursive: true,
1449
+ force: true
1450
+ });
1451
+ } catch {}
1489
1452
  }
1490
1453
  }
1491
1454
  /** Step 9: Write secrets/provider key files and restart openclaw. */
@@ -1559,13 +1522,13 @@ function runReset(input, taskId, resultFile) {
1559
1522
  step(4);
1560
1523
  waitForInitNpm(10 * 6e4, log);
1561
1524
  step(5);
1562
- reinstallOpenclaw(srcDir, log);
1525
+ ensureOpenclawBinary(srcDir, log);
1563
1526
  step(6);
1564
- mergeCoreBackupAndOrigins(configPath, vars, log);
1527
+ mergeCoreBackupAndOrigins(configPath, vars, resetData, log);
1565
1528
  step(7);
1566
1529
  copyStartupScripts(srcDir, configDir, log);
1567
1530
  step(8);
1568
- reinstallPlugins(log);
1531
+ installExtensions(configDir, log);
1569
1532
  step(9);
1570
1533
  writeSecretsAndRestart(vars, resetData, configDir, log);
1571
1534
  log(`step 9 "${STEPS[8]}" done in ${Date.now() - stepStartedAt}ms`);
@@ -1633,18 +1596,6 @@ switch (mode) {
1633
1596
  else console.log(JSON.stringify(runRepair(input)));
1634
1597
  break;
1635
1598
  }
1636
- case "backup": {
1637
- const ctx = args.find((a) => a.startsWith("--ctx="))?.slice(6);
1638
- if (!ctx) {
1639
- console.error("Error: --ctx=<base64> is required");
1640
- node_process.default.exit(1);
1641
- }
1642
- if (args.includes("--worker")) {
1643
- const taskId = args.find((a) => a.startsWith("--task-id="))?.slice(10);
1644
- runBackup(JSON.parse(Buffer.from(ctx, "base64").toString("utf-8")), taskId);
1645
- } else console.log(JSON.stringify(startAsyncBackup(ctx)));
1646
- break;
1647
- }
1648
1599
  case "reset":
1649
1600
  if (args.includes("--async")) {
1650
1601
  const ctx = args.find((a) => a.startsWith("--ctx="))?.slice(6);
@@ -1677,7 +1628,7 @@ switch (mode) {
1677
1628
  break;
1678
1629
  }
1679
1630
  default:
1680
- console.error("Usage: mclaw-diagnose <check|repair|backup|reset|get_reset_task> [options]");
1631
+ console.error("Usage: mclaw-diagnose <check|repair|reset|get_reset_task> [options]");
1681
1632
  node_process.default.exit(1);
1682
1633
  }
1683
1634
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/openclaw-scripts-diagnose-cli",
3
- "version": "0.1.1-alpha.17",
3
+ "version": "0.1.1-alpha.19",
4
4
  "description": "CLI for OpenClaw config diagnose and repair with JSON5 support",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {