fix(update): tailor gateway recovery hints by platform (#83191)

Summary:
- The PR updates the CLI post-update gateway recovery formatter and tests to show Linux, macOS, Windows, or generic service-manager guidance, plus a changelog entry.
- Reproducibility: yes. Source inspection gives a high-confidence reproduction path: current main reaches a fo ... hAgent recovery text, while the platform contract says Linux uses systemd and Windows uses Scheduled Tasks.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(update): tailor gateway recovery hints by platform

Validation:
- ClawSweeper review passed for head 0cf2a0c5a7.
- Required merge gates passed before the squash merge.

Prepared head SHA: 0cf2a0c5a7
Review: https://github.com/openclaw/openclaw/pull/83191#issuecomment-4471471293

Co-authored-by: Rubén Cuevas <hi@rubencu.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
This commit is contained in:
clawsweeper[bot]
2026-05-17 16:48:08 +00:00
committed by GitHub
parent af62fd45cd
commit 893f580072
3 changed files with 76 additions and 4 deletions

View File

@@ -6,9 +6,11 @@ import {
buildGatewayInstallEntrypointCandidates as resolveGatewayInstallEntrypointCandidates,
resolveGatewayInstallEntrypoint,
} from "../../daemon/gateway-entrypoint.js";
import type { UpdateRunResult } from "../../infra/update-runner.js";
import {
buildInvalidConfigPostCoreUpdateResult,
collectMissingPluginInstallPayloads,
formatPostUpdateGatewayRecoveryInstructions,
recoverInstalledLaunchAgentAfterUpdate,
recoverLaunchAgentAndRecheckGatewayHealth,
resolvePostCoreUpdateChildStdio,
@@ -348,6 +350,52 @@ describe("shouldUseLegacyProcessRestartAfterUpdate", () => {
expect(shouldUseLegacyProcessRestartAfterUpdate({ updateMode: "unknown" })).toBe(true);
});
});
describe("formatPostUpdateGatewayRecoveryInstructions", () => {
const result: UpdateRunResult = {
status: "error",
mode: "git",
steps: [],
durationMs: 0,
};
it("uses systemd wording on Linux instead of macOS LaunchAgent instructions", () => {
const [line] = formatPostUpdateGatewayRecoveryInstructions(result, "linux");
expect(line).toContain("the systemd user service");
expect(line).toContain("openclaw gateway restart");
expect(line).toContain("openclaw gateway install --force");
expect(line).toContain("openclaw gateway status --deep");
expect(line).not.toContain("Linux reports");
expect(line).not.toContain("macOS");
expect(line).not.toContain("LaunchAgent");
});
it("keeps LaunchAgent recovery wording on macOS", () => {
const [line] = formatPostUpdateGatewayRecoveryInstructions(result, "darwin");
expect(line).toContain("the LaunchAgent is installed but not loaded");
expect(line).toContain("logged-in macOS user session");
});
it("uses Windows service-manager wording on Windows", () => {
const [line] = formatPostUpdateGatewayRecoveryInstructions(result, "win32");
expect(line).toContain("the gateway Scheduled Task or Windows login item");
expect(line).not.toContain("LaunchAgent");
expect(line).not.toContain("Startup-folder");
});
it("uses generic service-manager wording for unsupported Node platforms", () => {
const [line] = formatPostUpdateGatewayRecoveryInstructions(result, "freebsd");
expect(line).toContain("local service manager");
expect(line).not.toContain("systemd");
expect(line).not.toContain("LaunchAgent");
expect(line).not.toContain("Scheduled Task");
});
});
describe("recoverInstalledLaunchAgentAfterUpdate", () => {
it("re-bootstraps an installed-but-not-loaded macOS LaunchAgent after update", async () => {
const service = {} as never;