@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.
- package/dist/index.cjs +178 -57
- 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/.
|
|
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 =
|
|
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/.
|
|
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))
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1219
|
-
|
|
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
|
-
|
|
1236
|
-
if (backup.
|
|
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
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
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))
|
|
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
|
-
|
|
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)
|
|
1289
|
-
|
|
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))
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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