@lark-apaas/openclaw-scripts-diagnose-cli 0.1.1-alpha.11 → 0.1.1-alpha.13

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 +178 -57
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -993,7 +993,7 @@ function runRepair(input) {
993
993
  }
994
994
  //#endregion
995
995
  //#region src/backup.ts
996
- const BACKUP_PATH = "/home/gem/workspace/.force/openclaw/core-backup.json";
996
+ const BACKUP_PATH = "/home/gem/workspace/agent/.spark/core-backup.json";
997
997
  function runBackup(input) {
998
998
  try {
999
999
  const { configPath } = input;
@@ -1033,6 +1033,40 @@ function runBackup(input) {
1033
1033
  }
1034
1034
  }
1035
1035
  //#endregion
1036
+ //#region src/paths.ts
1037
+ /**
1038
+ * Central directory for all ephemeral diagnose/reset artifacts: task status
1039
+ * files (`reset-<taskId>.json`) and human-readable step logs
1040
+ * (`reset-<taskId>.log`). Having everything under one dir makes debugging a
1041
+ * stuck reset much easier — `ls /tmp/openclaw-diagnose/` shows every recent
1042
+ * run, and each run's log is right next to its state.
1043
+ *
1044
+ * This dir is ephemeral (/tmp). Long-lived artifacts (e.g. core-backup.json
1045
+ * used by reset to restore agents/bindings) live under the agent's .spark/
1046
+ * directory instead, see CORE_BACKUP_PATH in reset.ts.
1047
+ */
1048
+ const DIAGNOSE_DIR = "/tmp/openclaw-diagnose";
1049
+ function resetResultFile(taskId) {
1050
+ return `${DIAGNOSE_DIR}/reset-${taskId}.json`;
1051
+ }
1052
+ function resetLogFile(taskId) {
1053
+ return `${DIAGNOSE_DIR}/reset-${taskId}.log`;
1054
+ }
1055
+ //#endregion
1056
+ //#region src/logger.ts
1057
+ function makeLogger(logFile) {
1058
+ try {
1059
+ const dir = node_path.default.dirname(logFile);
1060
+ if (!node_fs.default.existsSync(dir)) node_fs.default.mkdirSync(dir, { recursive: true });
1061
+ } catch {}
1062
+ return (msg) => {
1063
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}\n`;
1064
+ try {
1065
+ node_fs.default.appendFileSync(logFile, line);
1066
+ } catch {}
1067
+ };
1068
+ }
1069
+ //#endregion
1036
1070
  //#region src/reset-async.ts
1037
1071
  /**
1038
1072
  * Start an async reset task: spawn a detached child process and return the taskId.
@@ -1041,7 +1075,9 @@ function runBackup(input) {
1041
1075
  */
1042
1076
  function startAsyncReset(ctxBase64) {
1043
1077
  const taskId = (0, node_crypto.randomUUID)();
1044
- const resultFile = `/tmp/openclaw-reset-${taskId}.json`;
1078
+ const resultFile = resetResultFile(taskId);
1079
+ const log = makeLogger(resetLogFile(taskId));
1080
+ log(`=== startAsyncReset spawning worker for taskId=${taskId} ===`);
1045
1081
  const initial = {
1046
1082
  status: "running",
1047
1083
  step: 0,
@@ -1065,6 +1101,7 @@ function startAsyncReset(ctxBase64) {
1065
1101
  stdio: "ignore"
1066
1102
  });
1067
1103
  child.on("error", (err) => {
1104
+ log(`FATAL worker failed to start: ${err.message}`);
1068
1105
  const failResult = {
1069
1106
  status: "failed",
1070
1107
  step: 0,
@@ -1079,6 +1116,7 @@ function startAsyncReset(ctxBase64) {
1079
1116
  node_fs.default.renameSync(errTmpPath, resultFile);
1080
1117
  });
1081
1118
  child.unref();
1119
+ log(`spawned worker pid=${child.pid}`);
1082
1120
  return { taskId };
1083
1121
  }
1084
1122
  //#endregion
@@ -1095,7 +1133,7 @@ const STEPS = [
1095
1133
  "启动并验证"
1096
1134
  ];
1097
1135
  const TOTAL_STEPS = STEPS.length;
1098
- const CORE_BACKUP_PATH = "/home/gem/workspace/.force/openclaw/core-backup.json";
1136
+ const CORE_BACKUP_PATH = "/home/gem/workspace/agent/.spark/core-backup.json";
1099
1137
  /**
1100
1138
  * Directory holding the bundled openclaw template (openclaw.json + scripts/).
1101
1139
  * Synced from git@code.byted.org:apaas/miaoda-openclaw-template.git via
@@ -1142,8 +1180,11 @@ function markFailed(resultFile, step, error, startedAt) {
1142
1180
  });
1143
1181
  }
1144
1182
  /** Step 1: Backup current config as openclaw.json.bak.N */
1145
- function backupCurrentConfig(configPath) {
1146
- if (!fileExists(configPath)) return;
1183
+ function backupCurrentConfig(configPath, log) {
1184
+ if (!fileExists(configPath)) {
1185
+ log("no existing config, skip backup");
1186
+ return;
1187
+ }
1147
1188
  const dir = node_path.default.dirname(configPath);
1148
1189
  let maxN = 0;
1149
1190
  try {
@@ -1155,22 +1196,31 @@ function backupCurrentConfig(configPath) {
1155
1196
  }
1156
1197
  }
1157
1198
  } catch {}
1158
- node_fs.default.copyFileSync(configPath, configPath + ".bak." + (maxN + 1));
1199
+ const bakPath = configPath + ".bak." + (maxN + 1);
1200
+ node_fs.default.copyFileSync(configPath, bakPath);
1201
+ log(`backed up to ${bakPath}`);
1159
1202
  }
1160
1203
  /** Step 2: Replace $$__XXX__ placeholders and write default config. */
1161
- function generateDefaultConfig(srcDir, configPath, templateVars) {
1204
+ function generateDefaultConfig(srcDir, configPath, templateVars, log) {
1162
1205
  const srcConfigPath = node_path.default.join(srcDir, "openclaw.json");
1163
1206
  if (!fileExists(srcConfigPath)) throw new Error("template openclaw.json not found at " + srcConfigPath);
1164
1207
  let content = node_fs.default.readFileSync(srcConfigPath, "utf-8");
1165
- for (const [placeholder, value] of Object.entries(templateVars)) content = content.split(placeholder).join(value);
1208
+ let replaced = 0;
1209
+ for (const [placeholder, value] of Object.entries(templateVars)) {
1210
+ const parts = content.split(placeholder);
1211
+ if (parts.length > 1) replaced += parts.length - 1;
1212
+ content = parts.join(value);
1213
+ }
1166
1214
  node_fs.default.writeFileSync(configPath, content, "utf-8");
1215
+ log(`wrote ${configPath} (${replaced} placeholder(s) replaced, ${Object.keys(templateVars).length} provided)`);
1167
1216
  }
1168
1217
  /** Step 3: Kill all openclaw processes. */
1169
- function killOpenclawProcesses() {
1218
+ function killOpenclawProcesses(log) {
1170
1219
  try {
1171
1220
  shell("pkill -f openclaw-gateway || true", 5e3);
1172
1221
  } catch {}
1173
1222
  shell("sleep 2", 5e3);
1223
+ log("killed openclaw-gateway processes");
1174
1224
  }
1175
1225
  /**
1176
1226
  * Step 4: Wait for the sandbox's own init (init_sandbox.sh / concurrent npm
@@ -1180,22 +1230,30 @@ function killOpenclawProcesses() {
1180
1230
  * access. Polls every 10s up to `maxWaitMs`. If the deadline is hit we fall
1181
1231
  * through anyway — better to try than to fail the reset outright.
1182
1232
  */
1183
- function waitForInitNpm(maxWaitMs) {
1233
+ function waitForInitNpm(maxWaitMs, log) {
1184
1234
  const deadline = Date.now() + maxWaitMs;
1185
1235
  const ownPid = String(process.pid);
1236
+ let polls = 0;
1186
1237
  while (Date.now() < deadline) {
1238
+ polls++;
1187
1239
  let running = 0;
1188
1240
  try {
1189
1241
  const out = shell(`pgrep -af "init_sandbox.sh|npm install|npm i " | grep -v -- "${ownPid}" | wc -l`, 1e4);
1190
1242
  running = parseInt(out.trim(), 10) || 0;
1191
1243
  } catch {
1244
+ log(`poll ${polls}: no concurrent npm, proceeding`);
1245
+ return;
1246
+ }
1247
+ if (running === 0) {
1248
+ log(`poll ${polls}: no concurrent npm, proceeding`);
1192
1249
  return;
1193
1250
  }
1194
- if (running === 0) return;
1251
+ log(`poll ${polls}: ${running} concurrent npm/init process(es) still running, waiting 10s`);
1195
1252
  try {
1196
1253
  shell("sleep 10", 12e3);
1197
1254
  } catch {}
1198
1255
  }
1256
+ log(`deadline (${maxWaitMs}ms) hit after ${polls} poll(s), proceeding anyway`);
1199
1257
  }
1200
1258
  /**
1201
1259
  * Step 5: Reinstall openclaw to the version specified in template.
@@ -1206,17 +1264,30 @@ function waitForInitNpm(maxWaitMs) {
1206
1264
  * no idle-detection heuristics — waitForInitNpm above removes the main
1207
1265
  * source of contention so this step should run cleanly.
1208
1266
  */
1209
- function reinstallOpenclaw(srcDir) {
1267
+ function reinstallOpenclaw(srcDir, log) {
1210
1268
  const targetVersion = loadJSON5().parse(node_fs.default.readFileSync(node_path.default.join(srcDir, "openclaw.json"), "utf-8")).meta?.lastTouchedVersion;
1269
+ log(`target openclaw version: ${targetVersion ?? "<unset>"}`);
1211
1270
  if (targetVersion && isOpenclawAtVersion(targetVersion)) {
1212
- shell("openclaw doctor --fix", 12e4);
1271
+ log("fast path: already at target version, running doctor --fix only");
1272
+ const t = Date.now();
1273
+ shell("openclaw doctor --fix", 10 * 6e4);
1274
+ log(`doctor --fix done in ${Date.now() - t}ms`);
1213
1275
  return;
1214
1276
  }
1277
+ log("target version missing or mismatched, running full reinstall");
1215
1278
  try {
1279
+ const t = Date.now();
1216
1280
  shell("npm uninstall -g openclaw 2>/dev/null || true", 6e4);
1281
+ log(`npm uninstall done in ${Date.now() - t}ms`);
1217
1282
  } catch {}
1218
- shell(`npm i -g openclaw@${targetVersion || "latest"} --prefer-offline --fetch-timeout=60000 --fetch-retries=2`, 15 * 6e4);
1219
- shell("openclaw doctor --fix", 12e4);
1283
+ const installCmd = `npm i -g openclaw@${targetVersion || "latest"} --prefer-offline --fetch-timeout=60000 --fetch-retries=2`;
1284
+ log(`running: ${installCmd}`);
1285
+ const installStart = Date.now();
1286
+ shell(installCmd, 15 * 6e4);
1287
+ log(`npm install done in ${Date.now() - installStart}ms`);
1288
+ const docStart = Date.now();
1289
+ shell("openclaw doctor --fix", 10 * 6e4);
1290
+ log(`doctor --fix done in ${Date.now() - docStart}ms`);
1220
1291
  }
1221
1292
  /** Return true if `openclaw --version` output contains `targetVersion`. */
1222
1293
  function isOpenclawAtVersion(targetVersion) {
@@ -1227,48 +1298,69 @@ function isOpenclawAtVersion(targetVersion) {
1227
1298
  }
1228
1299
  }
1229
1300
  /** Step 6: Merge core-backup.json into config + ensure allowedOrigins. */
1230
- function mergeCoreBackupAndOrigins(configPath, vars) {
1301
+ function mergeCoreBackupAndOrigins(configPath, vars, log) {
1231
1302
  const JSON5 = loadJSON5();
1232
1303
  if (fileExists(CORE_BACKUP_PATH)) {
1233
1304
  const backup = JSON.parse(node_fs.default.readFileSync(CORE_BACKUP_PATH, "utf-8"));
1234
1305
  const config = JSON5.parse(node_fs.default.readFileSync(configPath, "utf-8"));
1235
- if (backup.agents) config.agents = backup.agents;
1236
- if (backup.bindings) config.bindings = backup.bindings;
1306
+ const merged = [];
1307
+ if (backup.agents) {
1308
+ config.agents = backup.agents;
1309
+ merged.push("agents");
1310
+ }
1311
+ if (backup.bindings) {
1312
+ config.bindings = backup.bindings;
1313
+ merged.push("bindings");
1314
+ }
1237
1315
  const backupAccounts = backup.channels?.feishu;
1238
1316
  if (backupAccounts?.accounts) {
1239
1317
  if (!config.channels) config.channels = {};
1240
1318
  const ch = config.channels;
1241
1319
  if (!ch.feishu) ch.feishu = {};
1242
1320
  ch.feishu.accounts = backupAccounts.accounts;
1321
+ merged.push("channels.feishu.accounts");
1243
1322
  }
1244
1323
  node_fs.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
1245
- }
1324
+ log(`merged from ${CORE_BACKUP_PATH}: [${merged.join(", ") || "nothing"}]`);
1325
+ } else log(`no backup at ${CORE_BACKUP_PATH}, skip merge`);
1246
1326
  const expectedOrigins = Array.isArray(vars.expectedOrigins) ? vars.expectedOrigins : [];
1247
- if (expectedOrigins.length > 0) {
1248
- const config = JSON5.parse(node_fs.default.readFileSync(configPath, "utf-8"));
1249
- if (!config.gateway) config.gateway = {};
1250
- const gw = config.gateway;
1251
- if (!gw.controlUi) gw.controlUi = {};
1252
- const cui = gw.controlUi;
1253
- const current = Array.isArray(cui.allowedOrigins) ? cui.allowedOrigins.filter((o) => typeof o === "string") : [];
1254
- if (current.includes("*")) return;
1255
- const seen = new Set(current);
1256
- const merged = [...current];
1257
- for (const o of expectedOrigins) if (!seen.has(o)) {
1258
- merged.push(o);
1259
- seen.add(o);
1260
- }
1261
- cui.allowedOrigins = merged;
1262
- node_fs.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
1327
+ if (expectedOrigins.length === 0) {
1328
+ log("no expectedOrigins provided");
1329
+ return;
1330
+ }
1331
+ const config = JSON5.parse(node_fs.default.readFileSync(configPath, "utf-8"));
1332
+ if (!config.gateway) config.gateway = {};
1333
+ const gw = config.gateway;
1334
+ if (!gw.controlUi) gw.controlUi = {};
1335
+ const cui = gw.controlUi;
1336
+ const current = Array.isArray(cui.allowedOrigins) ? cui.allowedOrigins.filter((o) => typeof o === "string") : [];
1337
+ if (current.includes("*")) {
1338
+ log("allowedOrigins already contains \"*\", skip origin merge");
1339
+ return;
1263
1340
  }
1341
+ const seen = new Set(current);
1342
+ const added = [];
1343
+ const mergedOrigins = [...current];
1344
+ for (const o of expectedOrigins) if (!seen.has(o)) {
1345
+ mergedOrigins.push(o);
1346
+ seen.add(o);
1347
+ added.push(o);
1348
+ }
1349
+ cui.allowedOrigins = mergedOrigins;
1350
+ node_fs.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
1351
+ log(`allowedOrigins: added ${added.length} (${JSON.stringify(added)}), total now ${mergedOrigins.length}`);
1264
1352
  }
1265
1353
  /** Step 7: Copy startup scripts from template to agent dir. */
1266
- function copyStartupScripts(srcDir, configDir) {
1354
+ function copyStartupScripts(srcDir, configDir, log) {
1267
1355
  const srcScriptsDir = node_path.default.join(srcDir, "scripts");
1268
1356
  const targetScriptsDir = node_path.default.join(configDir, "scripts");
1269
- if (!node_fs.default.existsSync(srcScriptsDir)) return;
1357
+ if (!node_fs.default.existsSync(srcScriptsDir)) {
1358
+ log(`no scripts/ in template, skip`);
1359
+ return;
1360
+ }
1270
1361
  if (!node_fs.default.existsSync(targetScriptsDir)) node_fs.default.mkdirSync(targetScriptsDir, { recursive: true });
1271
1362
  shell(`cp -r '${srcScriptsDir}'/* '${targetScriptsDir}/'`, 1e4);
1363
+ log(`copied scripts/* -> ${targetScriptsDir}`);
1272
1364
  }
1273
1365
  /**
1274
1366
  * Step 8: Reinstall all plugins via openclaw CLI.
@@ -1278,17 +1370,31 @@ function copyStartupScripts(srcDir, configDir) {
1278
1370
  * have exclusive npm access. Non-fatal — a plugin update failure shouldn't
1279
1371
  * stop the reset from restarting the gateway.
1280
1372
  */
1281
- function reinstallPlugins() {
1373
+ function reinstallPlugins(log) {
1374
+ const t = Date.now();
1282
1375
  try {
1283
1376
  shell("openclaw plugins update --all", 15 * 6e4);
1284
- } catch {}
1377
+ log(`plugins update --all done in ${Date.now() - t}ms`);
1378
+ } catch (e) {
1379
+ log(`plugins update failed after ${Date.now() - t}ms: ${e.message} (non-fatal, continuing)`);
1380
+ }
1285
1381
  }
1286
1382
  /** Step 9: Write secrets/provider key files and restart openclaw. */
1287
- function writeSecretsAndRestart(vars, resetData, configDir) {
1288
- if (resetData.secretsContent && vars.secretsFilePath) writeFile(vars.secretsFilePath, resetData.secretsContent);
1289
- if (resetData.providerKeyContent && vars.providerFilePath) writeFile(vars.providerFilePath, resetData.providerKeyContent);
1383
+ function writeSecretsAndRestart(vars, resetData, configDir, log) {
1384
+ if (resetData.secretsContent && vars.secretsFilePath) {
1385
+ writeFile(vars.secretsFilePath, resetData.secretsContent);
1386
+ log(`wrote secrets to ${vars.secretsFilePath}`);
1387
+ }
1388
+ if (resetData.providerKeyContent && vars.providerFilePath) {
1389
+ writeFile(vars.providerFilePath, resetData.providerKeyContent);
1390
+ log(`wrote provider key to ${vars.providerFilePath}`);
1391
+ }
1290
1392
  const restartScript = node_path.default.join(configDir, "scripts", "restart.sh");
1291
- if (fileExists(restartScript)) shell(`bash '${restartScript}'`, 3e4);
1393
+ if (fileExists(restartScript)) {
1394
+ const t = Date.now();
1395
+ shell(`bash '${restartScript}'`, 3e4);
1396
+ log(`restart.sh done in ${Date.now() - t}ms`);
1397
+ } else log(`no restart.sh at ${restartScript}, skip`);
1292
1398
  }
1293
1399
  /**
1294
1400
  * Run the 9-step reset process. Called from the worker entry point.
@@ -1306,45 +1412,60 @@ function runReset(input, taskId, resultFile) {
1306
1412
  const configDir = node_path.default.dirname(configPath);
1307
1413
  const srcDir = TEMPLATE_DIR;
1308
1414
  let currentStep = 0;
1415
+ let stepStartedAt = Date.now();
1416
+ const log = makeLogger(resetLogFile(taskId));
1417
+ log(`=== reset started, taskId=${taskId}, pid=${process.pid} ===`);
1418
+ log(`configPath=${configPath}, configDir=${configDir}, templateDir=${srcDir}`);
1309
1419
  if (!node_fs.default.existsSync(node_path.default.join(srcDir, "openclaw.json"))) {
1310
- markFailed(resultFile, 0, `bundled template not found at ${srcDir}`, startedAt);
1420
+ const err = `bundled template not found at ${srcDir}`;
1421
+ log(`ERROR: ${err}`);
1422
+ markFailed(resultFile, 0, err, startedAt);
1311
1423
  process.exit(1);
1312
1424
  }
1313
1425
  process.on("uncaughtException", (err) => {
1426
+ log(`FATAL uncaughtException: ${err.message}\n${err.stack ?? ""}`);
1314
1427
  markFailed(resultFile, currentStep, `uncaught exception: ${err.message}`, startedAt);
1315
1428
  process.exit(1);
1316
1429
  });
1317
1430
  process.on("unhandledRejection", (reason) => {
1431
+ log(`FATAL unhandledRejection: ${String(reason)}`);
1318
1432
  markFailed(resultFile, currentStep, `unhandled rejection: ${reason}`, startedAt);
1319
1433
  process.exit(1);
1320
1434
  });
1321
- /** Advance to the next step, updating the progress file. */
1435
+ /** Advance to the next step, updating the progress file and logging a boundary. */
1322
1436
  const step = (n) => {
1437
+ if (currentStep > 0) log(`step ${currentStep} "${STEPS[currentStep - 1]}" done in ${Date.now() - stepStartedAt}ms`);
1323
1438
  currentStep = n;
1439
+ stepStartedAt = Date.now();
1440
+ log(`--- step ${n}/${TOTAL_STEPS}: ${STEPS[n - 1]} ---`);
1324
1441
  updateProgress(resultFile, n, startedAt);
1325
1442
  };
1326
1443
  try {
1327
1444
  step(1);
1328
- backupCurrentConfig(configPath);
1445
+ backupCurrentConfig(configPath, log);
1329
1446
  step(2);
1330
- generateDefaultConfig(srcDir, configPath, resetData.templateVars);
1447
+ generateDefaultConfig(srcDir, configPath, resetData.templateVars, log);
1331
1448
  step(3);
1332
- killOpenclawProcesses();
1449
+ killOpenclawProcesses(log);
1333
1450
  step(4);
1334
- waitForInitNpm(10 * 6e4);
1451
+ waitForInitNpm(10 * 6e4, log);
1335
1452
  step(5);
1336
- reinstallOpenclaw(srcDir);
1453
+ reinstallOpenclaw(srcDir, log);
1337
1454
  step(6);
1338
- mergeCoreBackupAndOrigins(configPath, vars);
1455
+ mergeCoreBackupAndOrigins(configPath, vars, log);
1339
1456
  step(7);
1340
- copyStartupScripts(srcDir, configDir);
1457
+ copyStartupScripts(srcDir, configDir, log);
1341
1458
  step(8);
1342
- reinstallPlugins();
1459
+ reinstallPlugins(log);
1343
1460
  step(9);
1344
- writeSecretsAndRestart(vars, resetData, configDir);
1461
+ writeSecretsAndRestart(vars, resetData, configDir, log);
1462
+ log(`step 9 "${STEPS[8]}" done in ${Date.now() - stepStartedAt}ms`);
1463
+ log("=== reset completed successfully ===");
1345
1464
  markDone(resultFile, startedAt);
1346
1465
  } catch (e) {
1347
- markFailed(resultFile, currentStep, e.message, startedAt);
1466
+ const err = e.message;
1467
+ log(`ERROR in step ${currentStep} "${STEPS[currentStep - 1] ?? "init"}" after ${Date.now() - stepStartedAt}ms: ${err}\n${e.stack ?? ""}`);
1468
+ markFailed(resultFile, currentStep, err, startedAt);
1348
1469
  process.exit(1);
1349
1470
  }
1350
1471
  }
@@ -1356,7 +1477,7 @@ function runReset(input, taskId, resultFile) {
1356
1477
  * Returns immediately on terminal states (done/failed).
1357
1478
  */
1358
1479
  function getResetTask(taskId) {
1359
- const resultFile = `/tmp/openclaw-reset-${taskId}.json`;
1480
+ const resultFile = resetResultFile(taskId);
1360
1481
  const deadline = Date.now() + 3e4;
1361
1482
  while (Date.now() < deadline) {
1362
1483
  if (!node_fs.default.existsSync(resultFile)) {
@@ -1428,7 +1549,7 @@ switch (mode) {
1428
1549
  console.error("Error: --ctx=<base64> and --task-id=<id> are required for worker");
1429
1550
  node_process.default.exit(1);
1430
1551
  }
1431
- const resultFile = `/tmp/openclaw-reset-${taskId}.json`;
1552
+ const resultFile = resetResultFile(taskId);
1432
1553
  runReset(JSON.parse(Buffer.from(ctx, "base64").toString("utf-8")), taskId, resultFile);
1433
1554
  } else {
1434
1555
  console.error("Usage: reset --async --ctx=<base64> | reset --worker --task-id=<id> --ctx=<base64>");
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.11",
3
+ "version": "0.1.1-alpha.13",
4
4
  "description": "CLI for OpenClaw config diagnose and repair with JSON5 support",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {