From 274d05dfe79bb5d1804167bcf4cf6dd54e94ed66 Mon Sep 17 00:00:00 2001 From: Galin Iliev Date: Mon, 27 Apr 2026 23:41:56 -0700 Subject: [PATCH] fix(wizard): use setup token for onboarding health check Fixes #72203 Co-authored-by: OpenClaw Bot --- src/wizard/setup.finalize.test.ts | 56 ++++++++++++++++++++++++++++++- src/wizard/setup.finalize.ts | 16 ++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/wizard/setup.finalize.test.ts b/src/wizard/setup.finalize.test.ts index 1cf41285b1b..0cf75eba601 100644 --- a/src/wizard/setup.finalize.test.ts +++ b/src/wizard/setup.finalize.test.ts @@ -13,6 +13,7 @@ const waitForGatewayReachable = vi.hoisted(() => vi.fn<() => Promise<{ ok: boolean; detail?: string }>>(async () => ({ ok: true })), ); const setupWizardShellCompletion = vi.hoisted(() => vi.fn(async () => {})); +const healthCommand = vi.hoisted(() => vi.fn(async () => {})); const buildGatewayInstallPlan = vi.hoisted(() => vi.fn(async () => ({ programArguments: [], @@ -86,7 +87,7 @@ vi.mock("../commands/health-format.js", () => ({ })); vi.mock("../commands/health.js", () => ({ - healthCommand: vi.fn(async () => {}), + healthCommand, })); vi.mock("../commands/onboard-search.js", () => ({ @@ -243,6 +244,8 @@ describe("finalizeSetupWizard", () => { waitForGatewayReachable.mockReset(); waitForGatewayReachable.mockResolvedValue({ ok: true }); setupWizardShellCompletion.mockClear(); + healthCommand.mockReset(); + healthCommand.mockResolvedValue(undefined); buildGatewayInstallPlan.mockClear(); gatewayServiceInstall.mockClear(); gatewayServiceIsLoaded.mockReset(); @@ -558,6 +561,57 @@ describe("finalizeSetupWizard", () => { ); }); + it("uses the setup token for health checks to avoid local env token drift", async () => { + const prompter = createLaterPrompter(); + + await finalizeSetupWizard({ + flow: "quickstart", + opts: { + acceptRisk: true, + authChoice: "skip", + installDaemon: false, + skipHealth: false, + skipUi: true, + }, + baseConfig: {}, + nextConfig: { + gateway: { + auth: { + mode: "token", + token: "config-token", + }, + }, + }, + workspaceDir: "/tmp", + settings: { + port: 18789, + bind: "loopback", + authMode: "token", + gatewayToken: "session-token", + tailscaleMode: "off", + tailscaleResetOnExit: false, + }, + prompter, + runtime: createRuntime(), + }); + + expect(healthCommand).toHaveBeenCalledWith( + expect.objectContaining({ + json: false, + timeoutMs: 10_000, + config: expect.objectContaining({ + gateway: expect.objectContaining({ + auth: expect.objectContaining({ + mode: "token", + token: "session-token", + }), + }), + }), + }), + expect.any(Object), + ); + }); + it("shows actionable gateway guidance instead of a hard error in no-daemon onboarding", async () => { waitForGatewayReachable.mockResolvedValue({ ok: false, diff --git a/src/wizard/setup.finalize.ts b/src/wizard/setup.finalize.ts index bf0a87ad329..f2588f8f917 100644 --- a/src/wizard/setup.finalize.ts +++ b/src/wizard/setup.finalize.ts @@ -252,7 +252,21 @@ export async function finalizeSetupWizard( }); if (gatewayProbe.ok) { try { - await healthCommand({ json: false, timeoutMs: 10_000 }, runtime); + const healthConfig: OpenClawConfig = + settings.authMode === "token" && settings.gatewayToken + ? { + ...nextConfig, + gateway: { + ...nextConfig.gateway, + auth: { + ...nextConfig.gateway?.auth, + mode: "token", + token: settings.gatewayToken, + }, + }, + } + : nextConfig; + await healthCommand({ json: false, timeoutMs: 10_000, config: healthConfig }, runtime); } catch (err) { runtime.error(formatHealthCheckFailure(err)); await prompter.note(