import type { OpenClawConfig } from "../../config/config.js"; import { detectBinary as defaultDetectBinary } from "../../plugins/setup-binary.js"; import type { ChannelSetupWizard, ChannelSetupWizardStatus, ChannelSetupWizardTextInput, } from "./setup-wizard.js"; type SetupTextInputParams = Parameters>[0]; type SetupStatusParams = Parameters>[0]; export function createDetectedBinaryStatus(params: { channelLabel: string; binaryLabel: string; configuredLabel: string; unconfiguredLabel: string; configuredHint: string; unconfiguredHint: string; configuredScore: number; unconfiguredScore: number; resolveConfigured: (params: { cfg: OpenClawConfig }) => boolean | Promise; resolveBinaryPath: (params: { cfg: OpenClawConfig }) => string; detectBinary?: (path: string) => Promise; }): ChannelSetupWizardStatus { const detectBinary = params.detectBinary ?? defaultDetectBinary; return { configuredLabel: params.configuredLabel, unconfiguredLabel: params.unconfiguredLabel, configuredHint: params.configuredHint, unconfiguredHint: params.unconfiguredHint, configuredScore: params.configuredScore, unconfiguredScore: params.unconfiguredScore, resolveConfigured: params.resolveConfigured, resolveStatusLines: async ({ cfg, configured }: SetupStatusParams) => { const binaryPath = params.resolveBinaryPath({ cfg }); const detected = await detectBinary(binaryPath); return [ `${params.channelLabel}: ${configured ? params.configuredLabel : params.unconfiguredLabel}`, `${params.binaryLabel}: ${detected ? "found" : "missing"} (${binaryPath})`, ]; }, resolveSelectionHint: async ({ cfg }) => (await detectBinary(params.resolveBinaryPath({ cfg }))) ? params.configuredHint : params.unconfiguredHint, resolveQuickstartScore: async ({ cfg }) => (await detectBinary(params.resolveBinaryPath({ cfg }))) ? params.configuredScore : params.unconfiguredScore, }; } export function createCliPathTextInput(params: { inputKey: ChannelSetupWizardTextInput["inputKey"]; message: string; resolvePath: (params: SetupTextInputParams) => string | undefined; shouldPrompt: NonNullable; helpTitle?: string; helpLines?: string[]; }): ChannelSetupWizardTextInput { return { inputKey: params.inputKey, message: params.message, currentValue: params.resolvePath, initialValue: params.resolvePath, shouldPrompt: params.shouldPrompt, confirmCurrentValue: false, applyCurrentValue: true, ...(params.helpTitle ? { helpTitle: params.helpTitle } : {}), ...(params.helpLines ? { helpLines: params.helpLines } : {}), }; } export function createDelegatedSetupWizardStatusResolvers( loadWizard: () => Promise, ): Pick< ChannelSetupWizardStatus, "resolveStatusLines" | "resolveSelectionHint" | "resolveQuickstartScore" > { return { resolveStatusLines: async (params) => (await loadWizard()).status.resolveStatusLines?.(params) ?? [], resolveSelectionHint: async (params) => await (await loadWizard()).status.resolveSelectionHint?.(params), resolveQuickstartScore: async (params) => await (await loadWizard()).status.resolveQuickstartScore?.(params), }; } export function createDelegatedTextInputShouldPrompt(params: { loadWizard: () => Promise; inputKey: ChannelSetupWizardTextInput["inputKey"]; }): NonNullable { return async (inputParams) => { const input = (await params.loadWizard()).textInputs?.find( (entry) => entry.inputKey === params.inputKey, ); return (await input?.shouldPrompt?.(inputParams)) ?? false; }; }