

























@@ -1,4 +1,5 @@
11import { spawn, type ChildProcess } from "node:child_process";
2+import { existsSync } from "node:fs";
23import fs from "node:fs/promises";
34import os from "node:os";
45import path from "node:path";
@@ -8,6 +9,7 @@ import {
89ensureCompletionCacheExists,
910} from "../../commands/doctor-completion.js";
1011import { doctorCommand } from "../../commands/doctor.js";
12+import { createPreUpdateConfigSnapshot } from "../../config/backup-rotation.js";
1113import {
1214ConfigMutationConflictError,
1315assertConfigWriteAllowedInCurrentMode,
@@ -17,6 +19,7 @@ import {
1719} from "../../config/config.js";
1820import { formatConfigIssueLines } from "../../config/issue-format.js";
1921import { asResolvedSourceConfig, asRuntimeConfig } from "../../config/materialize.js";
22+import { CONFIG_PATH } from "../../config/paths.js";
2023import type { OpenClawConfig } from "../../config/types.openclaw.js";
2124import type { PluginInstallRecord } from "../../config/types.plugins.js";
2225import { GATEWAY_SERVICE_KIND, GATEWAY_SERVICE_MARKER } from "../../daemon/constants.js";
@@ -138,6 +141,13 @@ const POST_INSTALL_DOCTOR_SERVICE_ENV_KEYS = [
138141] as const;
139142const POST_UPDATE_PLUGIN_REPAIR_GUIDANCE = "Run openclaw doctor --fix to attempt automatic repair.";
140143144+async function createUpdateConfigSnapshot(): Promise<void> {
145+await createPreUpdateConfigSnapshot({
146+configPath: CONFIG_PATH,
147+fs: { writeFile: fs.writeFile, readFile: fs.readFile, existsSync },
148+});
149+}
150+141151const UPDATE_QUIPS = [
142152"Leveled up! New skills unlocked. You're welcome.",
143153"Fresh code, same lobster. Miss me?",
@@ -1025,6 +1035,7 @@ async function runPackageInstallUpdate(params: {
10251035postVerifyStep: async (verifiedPackageRoot) => {
10261036const entryPath = await resolveGatewayInstallEntrypoint(verifiedPackageRoot);
10271037if (entryPath) {
1038+await createUpdateConfigSnapshot();
10281039return await runUpdateStep({
10291040name: `${CLI_NAME} doctor`,
10301041argv: [resolveNodeRunner(), entryPath, "doctor", "--non-interactive", "--fix"],
@@ -1645,9 +1656,11 @@ async function maybeRestartService(params: {
16451656// that already produced the expected gateway version, a second kickstart
16461657// would only race the healthy supervisor-owned process.
16471658if (!refreshedGatewayAlreadyHealthy && params.restartScriptPath) {
1659+await createUpdateConfigSnapshot();
16481660await runRestartScript(params.restartScriptPath);
16491661restartInitiated = true;
16501662} else if (!refreshedGatewayAlreadyHealthy && params.refreshServiceEnv && isPackageUpdate) {
1663+await createUpdateConfigSnapshot();
16511664restarted = await runUpdatedInstallGatewayRestart({
16521665result: params.result,
16531666jsonMode: Boolean(params.opts.json),
@@ -1658,6 +1671,7 @@ async function maybeRestartService(params: {
16581671!refreshedGatewayAlreadyHealthy &&
16591672shouldUseLegacyProcessRestartAfterUpdate({ updateMode: params.result.mode })
16601673) {
1674+await createUpdateConfigSnapshot();
16611675restarted = await runDaemonRestart();
16621676} else if (!refreshedGatewayAlreadyHealthy && !params.opts.json) {
16631677defaultRuntime.log(theme.muted("No installed gateway service found; skipped restart."));
@@ -1684,6 +1698,7 @@ async function maybeRestartService(params: {
16841698if (!params.opts.json && restarted) {
16851699defaultRuntime.log(theme.success("Daemon restarted successfully."));
16861700defaultRuntime.log("");
1701+await createUpdateConfigSnapshot();
16871702process.env.OPENCLAW_UPDATE_IN_PROGRESS = "1";
16881703process.env[UPDATE_PARENT_SUPPORTS_DOCTOR_CONFIG_WRITE_ENV] = "1";
16891704try {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。