fix(configure): bound gateway hint probes

This commit is contained in:
Ayaan Zaidi
2026-04-22 10:17:02 +05:30
parent c1b21a2a3a
commit f4966351a1
2 changed files with 69 additions and 26 deletions

View File

@@ -242,6 +242,38 @@ describe("runConfigureWizard", () => {
);
});
it("keeps startup gateway hint probes bounded", async () => {
setupBaseWizardState({
gateway: {
mode: "local",
remote: {
url: "wss://gateway.example.test",
token: "token",
},
},
});
queueWizardPrompts({
select: ["local", "__continue"],
confirm: [],
});
await runConfigureWizard({ command: "configure" }, createRuntime());
expect(mocks.probeGatewayReachable).toHaveBeenCalledWith(
expect.objectContaining({
url: "ws://127.0.0.1:18789",
timeoutMs: 300,
}),
);
expect(mocks.probeGatewayReachable).toHaveBeenCalledWith(
expect.objectContaining({
url: "wss://gateway.example.test",
token: "token",
timeoutMs: 300,
}),
);
});
it("exits with code 1 when configure wizard is cancelled", async () => {
const runtime = createRuntime();
setupBaseWizardState();

View File

@@ -52,6 +52,8 @@ import { setupSkills } from "./onboard-skills.js";
type ConfigureSectionChoice = WizardSection | "__continue";
type SetupPluginConfigModule = typeof import("../wizard/setup.plugin-config.js");
const GATEWAY_HINT_PROBE_TIMEOUT_MS = 300;
let setupPluginConfigModulePromise: Promise<SetupPluginConfigModule> | undefined;
function loadSetupPluginConfigModule(): Promise<SetupPluginConfigModule> {
@@ -386,33 +388,42 @@ export async function runConfigureWizard(
}
const localUrl = "ws://127.0.0.1:18789";
const baseLocalProbeToken = await resolveGatewaySecretInputForWizard({
cfg: baseConfig,
value: baseConfig.gateway?.auth?.token,
path: "gateway.auth.token",
});
const baseLocalProbePassword = await resolveGatewaySecretInputForWizard({
cfg: baseConfig,
value: baseConfig.gateway?.auth?.password,
path: "gateway.auth.password",
});
const localProbe = await probeGatewayReachable({
url: localUrl,
token: process.env.OPENCLAW_GATEWAY_TOKEN ?? baseLocalProbeToken,
password: process.env.OPENCLAW_GATEWAY_PASSWORD ?? baseLocalProbePassword,
});
const remoteUrl = normalizeOptionalString(baseConfig.gateway?.remote?.url) ?? "";
const baseRemoteProbeToken = await resolveGatewaySecretInputForWizard({
cfg: baseConfig,
value: baseConfig.gateway?.remote?.token,
path: "gateway.remote.token",
});
const remoteProbe = remoteUrl
? await probeGatewayReachable({
url: remoteUrl,
token: baseRemoteProbeToken,
})
: null;
const localProbePromise = (async () => {
const [baseLocalProbeToken, baseLocalProbePassword] = await Promise.all([
resolveGatewaySecretInputForWizard({
cfg: baseConfig,
value: baseConfig.gateway?.auth?.token,
path: "gateway.auth.token",
}),
resolveGatewaySecretInputForWizard({
cfg: baseConfig,
value: baseConfig.gateway?.auth?.password,
path: "gateway.auth.password",
}),
]);
return probeGatewayReachable({
url: localUrl,
token: process.env.OPENCLAW_GATEWAY_TOKEN ?? baseLocalProbeToken,
password: process.env.OPENCLAW_GATEWAY_PASSWORD ?? baseLocalProbePassword,
timeoutMs: GATEWAY_HINT_PROBE_TIMEOUT_MS,
});
})();
const remoteProbePromise = remoteUrl
? (async () => {
const baseRemoteProbeToken = await resolveGatewaySecretInputForWizard({
cfg: baseConfig,
value: baseConfig.gateway?.remote?.token,
path: "gateway.remote.token",
});
return probeGatewayReachable({
url: remoteUrl,
token: baseRemoteProbeToken,
timeoutMs: GATEWAY_HINT_PROBE_TIMEOUT_MS,
});
})()
: Promise.resolve(null);
const [localProbe, remoteProbe] = await Promise.all([localProbePromise, remoteProbePromise]);
const mode = guardCancel(
await select({