import { r as formatErrorMessage } from "./errors-CGMew-1w.js";
import { n as defaultRuntime } from "./runtime-CgZZEqw7.js";
import { m as resolveUserPath } from "./utils-CE5zxr9Z.js";
import { r as theme } from "./theme-AvNURkOg.js";
import { u as resolveGatewayPort } from "./paths-CAiS8AEq.js";
import { h as writeConfigFile, l as readConfigFileSnapshot } from "./io-B_JNqEVl.js";
import { l as normalizeSecretInputString } from "./types.secrets-CjPCMEo4.js";
import "./config-BR67jvKt.js";
import { t as formatCliCommand } from "./command-format-BeJUeZeT.js";
import { t as WizardCancelledError } from "./prompts-BfdBLC3y.js";
import { t as resolveSetupSecretInputString } from "./setup.secret-input-BR7Y2Hg1.js";
import path from "node:path";
import os from "node:os";
//#region src/wizard/setup.ts
async function resolveAuthChoiceModelSelectionPolicy(params) {
	const preferredProvider = await params.resolvePreferredProviderForAuthChoice({
		choice: params.authChoice,
		config: params.config,
		workspaceDir: params.workspaceDir,
		env: params.env
	});
	const { resolvePluginProviders, resolveProviderPluginChoice } = await import("./provider-auth-choice.runtime-vMTeMwtE.js");
	const providers = resolvePluginProviders({
		config: params.config,
		workspaceDir: params.workspaceDir,
		env: params.env,
		mode: "setup"
	});
	const resolvedChoice = resolveProviderPluginChoice({
		providers,
		choice: params.authChoice
	});
	const matchedProvider = resolvedChoice?.provider ?? (preferredProvider ? providers.find((provider) => provider.id.trim() === preferredProvider.trim()) : void 0);
	const setupPolicy = resolvedChoice?.wizard?.modelSelection ?? matchedProvider?.wizard?.setup?.modelSelection;
	return {
		preferredProvider,
		promptWhenAuthChoiceProvided: setupPolicy?.promptWhenAuthChoiceProvided === true,
		allowKeepCurrent: setupPolicy?.allowKeepCurrent ?? true
	};
}
async function requireRiskAcknowledgement(params) {
	if (params.opts.acceptRisk === true) return;
	await params.prompter.note([
		"欢迎使用 KaijiBot 👾",
		"",
		"KaijiBot 是一个具备系统访问能力的 AI 助手：",
		"- 可以读写文件、执行命令、搜索网络",
		"- 会随对话逐渐学习你的偏好和兴趣（认知系统）",
		"- 可能会主动联系你分享有价值的洞察",
		"",
		"安全提示：",
		"- 请勿在不可信的网络环境中暴露 Gateway",
		"- 不要把 API Key 或敏感信息放在 agent 可访问的路径下"
	].join("\n"), "安全须知");
	if (!await params.prompter.confirm({
		message: "我已了解以上内容，继续配置？",
		initialValue: true
	})) throw new WizardCancelledError("risk not accepted");
}
async function runSetupWizard(opts, runtime = defaultRuntime, prompter) {
	const onboardHelpers = await import("./onboard-helpers-BWtEuQlN.js");
	onboardHelpers.printWizardHeader(runtime);
	await prompter.intro("KaijiBot 配置向导");
	await requireRiskAcknowledgement({
		opts,
		prompter
	});
	const snapshot = await readConfigFileSnapshot();
	let baseConfig = snapshot.valid ? snapshot.exists ? snapshot.sourceConfig ?? snapshot.config : {} : {};
	if (snapshot.exists && !snapshot.valid) {
		await prompter.note(onboardHelpers.summarizeExistingConfig(baseConfig), "Invalid config");
		if (snapshot.issues.length > 0) await prompter.note([
			...snapshot.issues.map((iss) => `- ${iss.path}: ${iss.message}`),
			"",
			"Docs: https://github.com/Kaiji-Z/kaijibot"
		].join("\n"), "Config issues");
		await prompter.outro(`配置无效。运行 \`${formatCliCommand("kaijibot doctor")}\` 修复后重新执行配置。`);
		runtime.exit(1);
		return;
	}
	const compatibilityNotices = snapshot.valid ? (await import("./status-uZ_er_Qd.js")).buildPluginCompatibilityNotices({ config: baseConfig }) : [];
	if (compatibilityNotices.length > 0) {
		const { formatPluginCompatibilityNotice: fmtNotice } = await import("./status-uZ_er_Qd.js");
		await prompter.note([
			`Detected ${compatibilityNotices.length} plugin compatibility notice${compatibilityNotices.length === 1 ? "" : "s"} in the current config.`,
			...compatibilityNotices.slice(0, 4).map((notice) => `- ${fmtNotice(notice)}`),
			...compatibilityNotices.length > 4 ? [`- ... +${compatibilityNotices.length - 4} more`] : [],
			"",
			`Review: ${formatCliCommand("kaijibot doctor")}`,
			`Inspect: ${formatCliCommand("kaijibot plugins inspect --all")}`
		].join("\n"), "Plugin compatibility");
	}
	if (!snapshot.exists) {
		const { detectMigrationSource, enumerateSourceAgents, enumerateSourceSkills, runFreshMigration } = await import("./openclaw-migrator-ulNNIw-g.js");
		const migrationSource = detectMigrationSource();
		if (migrationSource) {
			const agentList = await enumerateSourceAgents(migrationSource);
			const skillsList = await enumerateSourceSkills(migrationSource);
			runtime.log(`  ${theme.info("→")} Found ${migrationSource.brand} installation at: ${migrationSource.dir}`);
			runtime.log(`    Agents: ${agentList.length > 0 ? agentList.map((a) => a.id).join(", ") : "main"}`);
			runtime.log(`    Skills: ${skillsList.length}`);
			runtime.log("");
			if (await prompter.confirm({
				message: `Import data from ${migrationSource.brand}?`,
				initialValue: true
			})) {
				runtime.log("Running migration...");
				const migrationLog = (msg) => runtime.log(`  ${theme.muted(msg)}`);
				const report = await runFreshMigration(migrationSource, path.resolve(os.homedir(), ".kaijibot"), {
					dryRun: false,
					overwrite: false,
					migrateSecrets: false,
					log: migrationLog
				});
				runtime.log("");
				runtime.log(theme.success(`Migration complete: ${report.totalChanges} change(s), ${report.totalSkipped} skipped.`));
				if (report.totalWarnings > 0) runtime.log(theme.warn(`  ${report.totalWarnings} warning(s).`));
				runtime.log("");
			}
		}
	}
	const quickstartHint = `Configure details later via ${formatCliCommand("kaijibot configure")}.`;
	const manualHint = "Configure port, network, Tailscale, and auth options.";
	const explicitFlowRaw = opts.flow?.trim();
	const normalizedExplicitFlow = explicitFlowRaw === "manual" ? "advanced" : explicitFlowRaw;
	if (normalizedExplicitFlow && normalizedExplicitFlow !== "quickstart" && normalizedExplicitFlow !== "advanced") {
		runtime.error("无效的 --flow 参数（请使用 quickstart、manual 或 advanced）。");
		runtime.exit(1);
		return;
	}
	let flow = (normalizedExplicitFlow === "quickstart" || normalizedExplicitFlow === "advanced" ? normalizedExplicitFlow : void 0) ?? await prompter.select({
		message: "配置模式",
		options: [{
			value: "quickstart",
			label: "快速配置",
			hint: quickstartHint
		}, {
			value: "advanced",
			label: "手动配置",
			hint: manualHint
		}],
		initialValue: "quickstart"
	});
	if (opts.mode === "remote" && flow === "quickstart") {
		await prompter.note("QuickStart only supports local gateways. Switching to Manual mode.", "QuickStart");
		flow = "advanced";
	}
	if (snapshot.exists) {
		await prompter.note(onboardHelpers.summarizeExistingConfig(baseConfig), "Existing config detected");
		if (await prompter.select({
			message: "配置处理方式",
			options: [
				{
					value: "keep",
					label: "使用现有配置"
				},
				{
					value: "modify",
					label: "更新配置"
				},
				{
					value: "reset",
					label: "重置"
				}
			]
		}) === "reset") {
			const workspaceDefault = baseConfig.agents?.defaults?.workspace ?? onboardHelpers.DEFAULT_WORKSPACE;
			const resetScope = await prompter.select({
				message: "重置范围",
				options: [
					{
						value: "config",
						label: "仅配置"
					},
					{
						value: "config+creds+sessions",
						label: "配置 + 凭证 + 会话"
					},
					{
						value: "full",
						label: "完全重置（配置 + 凭证 + 会话 + 工作空间）"
					}
				]
			});
			await onboardHelpers.handleReset(resetScope, resolveUserPath(workspaceDefault), runtime);
			baseConfig = {};
		}
	}
	const quickstartGateway = (() => {
		const hasExisting = typeof baseConfig.gateway?.port === "number" || baseConfig.gateway?.bind !== void 0 || baseConfig.gateway?.auth?.mode !== void 0 || baseConfig.gateway?.auth?.token !== void 0 || baseConfig.gateway?.auth?.password !== void 0 || baseConfig.gateway?.customBindHost !== void 0 || baseConfig.gateway?.tailscale?.mode !== void 0;
		const bindRaw = baseConfig.gateway?.bind;
		const bind = bindRaw === "loopback" || bindRaw === "lan" || bindRaw === "auto" || bindRaw === "custom" || bindRaw === "tailnet" ? bindRaw : "loopback";
		let authMode = "token";
		if (baseConfig.gateway?.auth?.mode === "token" || baseConfig.gateway?.auth?.mode === "password") authMode = baseConfig.gateway.auth.mode;
		else if (baseConfig.gateway?.auth?.token) authMode = "token";
		else if (baseConfig.gateway?.auth?.password) authMode = "password";
		const tailscaleRaw = baseConfig.gateway?.tailscale?.mode;
		const tailscaleMode = tailscaleRaw === "off" || tailscaleRaw === "serve" || tailscaleRaw === "funnel" ? tailscaleRaw : "off";
		return {
			hasExisting,
			port: resolveGatewayPort(baseConfig),
			bind,
			authMode,
			tailscaleMode,
			token: baseConfig.gateway?.auth?.token,
			password: baseConfig.gateway?.auth?.password,
			customBindHost: baseConfig.gateway?.customBindHost,
			tailscaleResetOnExit: baseConfig.gateway?.tailscale?.resetOnExit ?? false
		};
	})();
	if (flow === "quickstart") {
		const formatBind = (value) => {
			if (value === "loopback") return "Loopback (127.0.0.1)";
			if (value === "lan") return "LAN";
			if (value === "custom") return "Custom IP";
			if (value === "tailnet") return "Tailnet (Tailscale IP)";
			return "Auto";
		};
		const formatAuth = (value) => {
			if (value === "token") return "Token (default)";
			return "Password";
		};
		const formatTailscale = (value) => {
			if (value === "off") return "Off";
			if (value === "serve") return "Serve";
			return "Funnel";
		};
		const quickstartLines = quickstartGateway.hasExisting ? [
			"Keeping your current gateway settings:",
			`Gateway port: ${quickstartGateway.port}`,
			`Gateway bind: ${formatBind(quickstartGateway.bind)}`,
			...quickstartGateway.bind === "custom" && quickstartGateway.customBindHost ? [`Gateway custom IP: ${quickstartGateway.customBindHost}`] : [],
			`Gateway auth: ${formatAuth(quickstartGateway.authMode)}`,
			`Tailscale exposure: ${formatTailscale(quickstartGateway.tailscaleMode)}`,
			"Direct to chat channels."
		] : [
			`Gateway port: ${quickstartGateway.port}`,
			"Gateway bind: Loopback (127.0.0.1)",
			"Gateway auth: Token (default)",
			"Tailscale exposure: Off",
			"Direct to chat channels."
		];
		await prompter.note(quickstartLines.join("\n"), "QuickStart");
	}
	const localPort = resolveGatewayPort(baseConfig);
	const localUrl = `ws://127.0.0.1:${localPort}`;
	let localGatewayToken = process.env.KAIJIBOT_GATEWAY_TOKEN;
	try {
		const resolvedGatewayToken = await resolveSetupSecretInputString({
			config: baseConfig,
			value: baseConfig.gateway?.auth?.token,
			path: "gateway.auth.token",
			env: process.env
		});
		if (resolvedGatewayToken) localGatewayToken = resolvedGatewayToken;
	} catch (error) {
		await prompter.note(["Could not resolve gateway.auth.token SecretRef for setup probe.", formatErrorMessage(error)].join("\n"), "Gateway auth");
	}
	let localGatewayPassword = process.env.KAIJIBOT_GATEWAY_PASSWORD;
	try {
		const resolvedGatewayPassword = await resolveSetupSecretInputString({
			config: baseConfig,
			value: baseConfig.gateway?.auth?.password,
			path: "gateway.auth.password",
			env: process.env
		});
		if (resolvedGatewayPassword) localGatewayPassword = resolvedGatewayPassword;
	} catch (error) {
		await prompter.note(["Could not resolve gateway.auth.password SecretRef for setup probe.", formatErrorMessage(error)].join("\n"), "Gateway auth");
	}
	const localProbe = await onboardHelpers.probeGatewayReachable({
		url: localUrl,
		token: localGatewayToken,
		password: localGatewayPassword
	});
	const remoteUrl = baseConfig.gateway?.remote?.url?.trim() ?? "";
	let remoteGatewayToken = normalizeSecretInputString(baseConfig.gateway?.remote?.token);
	try {
		const resolvedRemoteGatewayToken = await resolveSetupSecretInputString({
			config: baseConfig,
			value: baseConfig.gateway?.remote?.token,
			path: "gateway.remote.token",
			env: process.env
		});
		if (resolvedRemoteGatewayToken) remoteGatewayToken = resolvedRemoteGatewayToken;
	} catch (error) {
		await prompter.note(["Could not resolve gateway.remote.token SecretRef for setup probe.", formatErrorMessage(error)].join("\n"), "Gateway auth");
	}
	const remoteProbe = remoteUrl ? await onboardHelpers.probeGatewayReachable({
		url: remoteUrl,
		token: remoteGatewayToken
	}) : null;
	const mode = opts.mode ?? (flow === "quickstart" ? "local" : await prompter.select({
		message: "你想配置什么？",
		options: [{
			value: "local",
			label: "本地网关（本机）",
			hint: localProbe.ok ? `Gateway reachable (${localUrl})` : `No gateway detected (${localUrl})`
		}, {
			value: "remote",
			label: "远程网关（仅信息）",
			hint: !remoteUrl ? "No remote URL configured yet" : remoteProbe?.ok ? `Gateway reachable (${remoteUrl})` : `Configured but unreachable (${remoteUrl})`
		}]
	}));
	if (mode === "remote") {
		const { promptRemoteGatewayConfig } = await import("./onboard-remote-6g472Azq.js");
		const { logConfigUpdated } = await import("./logging-BYyiSagC.js");
		let nextConfig = await promptRemoteGatewayConfig(baseConfig, prompter, { secretInputMode: opts.secretInputMode });
		nextConfig = onboardHelpers.applyWizardMetadata(nextConfig, {
			command: "onboard",
			mode
		});
		await writeConfigFile(nextConfig);
		logConfigUpdated(runtime);
		await prompter.outro("远程网关已配置。");
		return;
	}
	const workspaceDir = resolveUserPath((opts.workspace ?? (flow === "quickstart" ? baseConfig.agents?.defaults?.workspace ?? onboardHelpers.DEFAULT_WORKSPACE : await prompter.text({
		message: "工作空间目录",
		initialValue: baseConfig.agents?.defaults?.workspace ?? onboardHelpers.DEFAULT_WORKSPACE
	}))).trim() || onboardHelpers.DEFAULT_WORKSPACE);
	const { applyLocalSetupWorkspaceConfig } = await import("./onboard-config-BPXiaYYN.js");
	let nextConfig = applyLocalSetupWorkspaceConfig(baseConfig, workspaceDir);
	const { ensureAuthProfileStore } = await import("./agents/auth-profiles.runtime.js");
	const { promptAuthChoiceGrouped } = await import("./auth-choice-prompt-Cgu2LpI9.js");
	const { promptCustomApiConfig } = await import("./onboard-custom-zLhOZMC9.js");
	const { applyAuthChoice, resolvePreferredProviderForAuthChoice, warnIfModelConfigLooksOff } = await import("./auth-choice-LJE59H0c.js");
	const { applyPrimaryModel, promptDefaultModel } = await import("./model-picker-F6jOGTva.js");
	const authStore = ensureAuthProfileStore(void 0, { allowKeychainPrompt: false });
	const authChoiceFromPrompt = opts.authChoice === void 0;
	const authChoice = opts.authChoice ?? await promptAuthChoiceGrouped({
		prompter,
		store: authStore,
		includeSkip: true,
		config: nextConfig,
		workspaceDir
	});
	if (authChoice === "custom-api-key") nextConfig = (await promptCustomApiConfig({
		prompter,
		runtime,
		config: nextConfig,
		secretInputMode: opts.secretInputMode
	})).config;
	else {
		const authResult = await applyAuthChoice({
			authChoice,
			config: nextConfig,
			prompter,
			runtime,
			setDefaultModel: true,
			opts: {
				tokenProvider: opts.tokenProvider,
				token: opts.authChoice === "apiKey" && opts.token ? opts.token : void 0
			}
		});
		nextConfig = authResult.config;
		if (authResult.agentModelOverride) nextConfig = applyPrimaryModel(nextConfig, authResult.agentModelOverride);
	}
	const authChoiceModelSelectionPolicy = authChoice === "custom-api-key" ? void 0 : await resolveAuthChoiceModelSelectionPolicy({
		authChoice,
		config: nextConfig,
		workspaceDir,
		resolvePreferredProviderForAuthChoice
	});
	if (authChoice !== "custom-api-key" && (authChoiceFromPrompt || authChoiceModelSelectionPolicy?.promptWhenAuthChoiceProvided === true)) {
		const modelSelection = await promptDefaultModel({
			config: nextConfig,
			prompter,
			allowKeep: authChoiceModelSelectionPolicy?.allowKeepCurrent ?? true,
			ignoreAllowlist: true,
			includeProviderPluginSetups: true,
			preferredProvider: authChoiceModelSelectionPolicy?.preferredProvider,
			workspaceDir,
			runtime
		});
		if (modelSelection.config) nextConfig = modelSelection.config;
		if (modelSelection.model) nextConfig = applyPrimaryModel(nextConfig, modelSelection.model);
	}
	await warnIfModelConfigLooksOff(nextConfig, prompter);
	const { configureGatewayForSetup } = await import("./setup.gateway-config-Cn1Mk0a_.js");
	const gateway = await configureGatewayForSetup({
		flow,
		baseConfig,
		nextConfig,
		localPort,
		quickstartGateway,
		secretInputMode: opts.secretInputMode,
		prompter,
		runtime
	});
	nextConfig = gateway.nextConfig;
	const settings = gateway.settings;
	if (opts.skipChannels ?? opts.skipProviders) await prompter.note("Skipping channel setup.", "Channels");
	else {
		const { listChannelPlugins } = await import("./plugins-DupmVEkS.js");
		const { setupChannels } = await import("./onboard-channels-Dzt2gyVJ.js");
		const quickstartAllowFromChannels = flow === "quickstart" ? listChannelPlugins().filter((plugin) => plugin.meta.quickstartAllowFrom).map((plugin) => plugin.id) : [];
		nextConfig = await setupChannels(nextConfig, runtime, prompter, {
			allowSignalInstall: true,
			forceAllowFromChannels: quickstartAllowFromChannels,
			skipDmPolicyPrompt: flow === "quickstart",
			skipConfirm: flow === "quickstart",
			quickstartDefaults: flow === "quickstart",
			secretInputMode: opts.secretInputMode
		});
	}
	await writeConfigFile(nextConfig);
	const { logConfigUpdated } = await import("./logging-BYyiSagC.js");
	logConfigUpdated(runtime);
	await onboardHelpers.ensureWorkspaceAndSessions(workspaceDir, runtime, { skipBootstrap: Boolean(nextConfig.agents?.defaults?.skipBootstrap) });
	if (opts.skipSearch) await prompter.note("Skipping search setup.", "Search");
	else {
		const { setupSearch } = await import("./onboard-search-xk260uQq.js");
		nextConfig = await setupSearch(nextConfig, runtime, prompter, {
			quickstartDefaults: flow === "quickstart",
			secretInputMode: opts.secretInputMode
		});
	}
	if (opts.skipSkills) await prompter.note("Skipping skills setup.", "Skills");
	else {
		const { setupSkills } = await import("./onboard-skills-DgZDTNyw.js");
		nextConfig = await setupSkills(nextConfig, workspaceDir, runtime, prompter);
	}
	{
		const { isChannelConfigured } = await import("./channel-configured-Vna1zJRf.js");
		if (isChannelConfigured(nextConfig, "feishu")) {
			const { areLarkSkillsInstalled } = await import("./auto-disable-CmJfHDbk.js");
			if (areLarkSkillsInstalled()) await prompter.note("lark-cli skills already installed.", "Lark CLI Skills");
			else {
				const { installLarkCliSkills } = await import("./install-skills-CQnadGky.js");
				try {
					const result = await installLarkCliSkills();
					if (result.ok) {
						const count = result.installed ?? "";
						await prompter.note(`Installed ${count} lark-cli skills to ~/.agents/skills/`, "Lark CLI Skills");
					} else if (result.error === "lark-cli not available") await prompter.note([
						"lark-cli is not installed — Feishu skills (lark-*) were not set up.",
						"",
						"To install later:",
						"  npm install -g @larksuite/cli",
						"  npx skills add larksuite/cli -g --all",
						"",
						"Then restart the gateway."
					].join("\n"), "Lark CLI Skills");
					else runtime.log(`  ⚠ lark-cli skills install failed: ${result.error}`);
				} catch (err) {
					const message = err instanceof Error ? err.message : String(err);
					runtime.log(`  ⚠ lark-cli skills install failed: ${message}`);
				}
			}
		}
	}
	if (flow !== "quickstart") {
		const { setupPluginConfig } = await import("./setup.plugin-config-DQuICERk.js");
		nextConfig = await setupPluginConfig({
			config: nextConfig,
			prompter,
			workspaceDir
		});
	}
	const { setupInternalHooks } = await import("./onboard-hooks-Di6ObuXM.js");
	nextConfig = await setupInternalHooks(nextConfig, runtime, prompter);
	nextConfig = onboardHelpers.applyWizardMetadata(nextConfig, {
		command: "onboard",
		mode
	});
	await writeConfigFile(nextConfig);
	const { finalizeSetupWizard } = await import("./setup.finalize-LzTrYU85.js");
	const { launchedTui } = await finalizeSetupWizard({
		flow,
		opts,
		baseConfig,
		nextConfig,
		workspaceDir,
		settings,
		prompter,
		runtime
	});
	if (launchedTui) return;
}
//#endregion
export { runSetupWizard as t };
