import "./tool-display-B7qTeoCS.js";
import "./paths-D4_LjrY7.js";
import { b as resolveUserPath, g as pathExists } from "./utils-BnlaT0eO.js";
import "./theme-CG-K7m8u.js";
import "./thinking-CKGMvVgd.js";
import "./reply-DbpXq1MH.js";
import "./subsystem-ocBR131w.js";
import { r as restoreTerminalState } from "./runtime-CRvfzclG.js";
import "./exec-CZr_EJHt.js";
import { y as DEFAULT_BOOTSTRAP_FILENAME } from "./agent-scope-CVnlY0oG.js";
import "./model-selection-p6J3l4qF.js";
import "./github-copilot-token-CjSKohyA.js";
import { r as resolveCliName, t as formatCliCommand } from "./command-format-Dh6J8CvS.js";
import "./emitter-oHo8y9ow.js";
import "./sqlite-wYNyDR1B.js";
import "./reliability-Dl7hbRzF.js";
import "./boolean-DGGu1sGA.js";
import "./env-CvUd308i.js";
import "./validation-p1IK70TM.js";
import "./config-DJ3A5x_1.js";
import "./manifest-registry-U2EDFVP4.js";
import "./runner-BZrNCxMY.js";
import "./image-tool.helpers-tqRivaKA.js";
import "./models-config-DLUtus3b.js";
import "./pi-model-discovery-4-XyjjxG.js";
import "./pi-embedded-utils-BraP32ED.js";
import "./redact-DcYCKU6u.js";
import "./pi-embedded-helpers-CLkeTWAT.js";
import "./sandbox-C5rKvtrA.js";
import "./chrome-BQkAVfz8.js";
import "./tailscale-CcUMoDkd.js";
import "./auth-BxKMeEw-.js";
import "./server-context-s_zNpSdX.js";
import "./frontmatter-VFr0KMAQ.js";
import "./skills-CHYyY1lO.js";
import "./routes-CT0DmotX.js";
import "./errors-DbYSuCgv.js";
import "./paths-Ct4sqLyX.js";
import "./ssrf-tneKFjA6.js";
import "./image-ops-C0D77XHD.js";
import "./store-Cdm3Z5cQ.js";
import "./ports-DvLDsgl0.js";
import "./trash-BRBQoy9m.js";
import "./sessions-Ct2d_bGl.js";
import "./message-channel-DSU96OKy.js";
import "./dock-DY0TWaYa.js";
import "./normalize-DgwtBdm-.js";
import "./accounts-BZv5WxME.js";
import "./accounts-DFaskvEN.js";
import "./accounts-T7o73ZSN.js";
import "./bindings-BbaWTQJM.js";
import "./logging-wfRfbMvt.js";
import "./client-36a9DTBg.js";
import "./plugins-DYgcd4QJ.js";
import "./targets-qjNLO5UC.js";
import "./paths-DRyRQF9o.js";
import "./tool-images-CRPqucMe.js";
import "./image-Dx_UDO2W.js";
import "./fetch-guard-C12KgXTM.js";
import "./api-key-rotation-Bl9Larnz.js";
import "./fetch-Dy3Y7lWo.js";
import "./session-files-DroWN-X3.js";
import "./model-catalog-DyP7lvDH.js";
import "./tokens-DuLZdp8u.js";
import "./heartbeat-BJ0mtjXV.js";
import "./helpers-DAXsRcXO.js";
import "./targets-D3Hd_LiZ.js";
import "./with-timeout-BeRjsuGt.js";
import "./diagnostic-Ct9JySKv.js";
import "./diagnostic-session-state-CjvcsE8F.js";
import "./lanes-s-MZ35vD.js";
import "./reply-payloads-Idpqh_HL.js";
import "./route-reply-C3GnJgPP.js";
import "./tts-pLGM3rbp.js";
import "./audio-Cf4_M2_g.js";
import "./model-p-v6-khS.js";
import "./chat-trace-DE0u11RV.js";
import "./response-prefix-template-ZNVQwQzJ.js";
import "./tool-tracking-BeyzFfAx.js";
import "./memory-cli-D_iCajsu.js";
import "./manager-Be4wtySp.js";
import "./retry-BR_e19Qc.js";
import "./hybrid-oFciuzzr.js";
import "./common-oaZdjdal.js";
import "./send-BFMLircB.js";
import "./chunk-CF0Wb8FK.js";
import "./markdown-tables-BkkSACKz.js";
import "./media-Ce9mjBUa.js";
import "./ir-DDJn3mJR.js";
import "./render-Cz3PVxTW.js";
import "./commands-registry-CvAV0O7w.js";
import "./client-DNPnFy4E.js";
import "./call-C206Z-zx.js";
import "./sessions-helpers-DYJnJN3U.js";
import "./external-content-CNcZgk3W.js";
import "./send-BQth8hb0.js";
import "./channel-activity-C8K3u-iy.js";
import "./fetch-CdBeMr8t.js";
import "./tables-GfMspQYU.js";
import "./server-startup-users-Bb0MWaNU.js";
import "./resolve-route-D-YVS8mL.js";
import "./pairing-store-Z_SXyT9W.js";
import "./replies-AgkcH9tU.js";
import "./reply-prefix-DB7HiPpn.js";
import "./workspace-dirs-C1v5ssUA.js";
import "./skill-commands-vM7RDRiG.js";
import "./pi-tools.policy-C7_kjOAN.js";
import "./send-BKH82oGz.js";
import { d as openUrl, h as resolveControlUiLinks, i as detectBrowserOpenSupport, o as formatControlUiSshHint, p as probeGatewayReachable, y as waitForGatewayReachable } from "./onboard-helpers-B0CkVZ2U.js";
import "./prompt-style-D4OL61iD.js";
import "./onboard-helpers-BvqKOAqv.js";
import "./outbound-attachment-DzzKBoks.js";
import "./targets-B17-mYQK.js";
import "./pairing-labels-BoIZlK5l.js";
import "./send-C5tjqyuP.js";
import "./session-cost-usage-UDBgjJvw.js";
import "./send-XU_khFvN.js";
import "./proxy-CjhP7CG1.js";
import "./links-G4gKCCcI.js";
import "./cli-utils-Cps3tWFt.js";
import "./help-format-DukcHIxz.js";
import "./progress-WmzCxxhb.js";
import "./active-listener-CEwpUvTV.js";
import "./exec-approvals-C7AUcy3J.js";
import "./gateway-DKSm1BrZ.js";
import "./nodes-utils-yMGpHJYN.js";
import "./model-fallback-BPqOLk8z.js";
import "./typed-schema-4lv655ii.js";
import "./knowledge-graph-D4-b38d_.js";
import "./runtime-guard-ChZ6T0fk.js";
import "./program-context-DgkRwT3k.js";
import "./deliver-DhB9l23e.js";
import "./delivery-queue-CKcfhYo3.js";
import "./note-U4_LTORH.js";
import { t as ensureControlUiAssetsBuilt } from "./control-ui-assets-D8Bf0fDO.js";
import { r as isSystemdUserServiceAvailable } from "./systemd-CdTDtFWy.js";
import { t as resolveGatewayService } from "./service-tzRBQba1.js";
import { a as gatewayInstallErrorHint, i as buildGatewayInstallPlan, n as GATEWAY_DAEMON_RUNTIME_OPTIONS, t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-CamLzRLO.js";
import "./daemon-install-helpers-OEyMcFNy.js";
import { t as formatHealthCheckFailure } from "./health-format-KPl365j1.js";
import { r as healthCommand } from "./health-u_Dm-5Ek.js";
import { r as installCompletion } from "./completion-cli-D0nbU7J_.js";
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-A37alwFV.js";
import { t as runTui } from "./tui-BpehHyx_.js";
import "./doctor-completion-BZ8v-7aT.js";
import os from "node:os";
import path from "node:path";
import fs from "node:fs/promises";

//#region src/wizard/onboarding.completion.ts
async function resolveProfileHint(shell) {
	const home = process.env.HOME || os.homedir();
	if (shell === "zsh") return "~/.zshrc";
	if (shell === "bash") return await pathExists(path.join(home, ".bashrc")) ? "~/.bashrc" : "~/.bash_profile";
	if (shell === "fish") return "~/.config/fish/config.fish";
	return "$PROFILE";
}
function formatReloadHint(shell, profileHint) {
	if (shell === "powershell") return "Restart your shell (or reload your PowerShell profile).";
	return `Restart your shell or run: source ${profileHint}`;
}
async function setupOnboardingShellCompletion(params) {
	const deps = {
		resolveCliName,
		checkShellCompletionStatus,
		ensureCompletionCacheExists,
		installCompletion,
		...params.deps
	};
	const cliName = deps.resolveCliName();
	const completionStatus = await deps.checkShellCompletionStatus(cliName);
	if (completionStatus.usesSlowPattern) {
		if (await deps.ensureCompletionCacheExists(cliName)) await deps.installCompletion(completionStatus.shell, true, cliName);
		return;
	}
	if (completionStatus.profileInstalled && !completionStatus.cacheExists) {
		await deps.ensureCompletionCacheExists(cliName);
		return;
	}
	if (!completionStatus.profileInstalled) {
		if (!(params.flow === "quickstart" ? true : await params.prompter.confirm({
			message: `Enable ${completionStatus.shell} shell completion for ${cliName}?`,
			initialValue: true
		}))) return;
		if (!await deps.ensureCompletionCacheExists(cliName)) {
			await params.prompter.note(`Failed to generate completion cache. Run \`${cliName} completion --install\` later.`, "Shell completion");
			return;
		}
		await deps.installCompletion(completionStatus.shell, true, cliName);
		const profileHint = await resolveProfileHint(completionStatus.shell);
		await params.prompter.note(`Shell completion installed. ${formatReloadHint(completionStatus.shell, profileHint)}`, "Shell completion");
	}
}

//#endregion
//#region src/wizard/onboarding.finalize.ts
async function finalizeOnboardingWizard(options) {
	const { flow, opts, baseConfig, nextConfig, settings, prompter, runtime } = options;
	const withWizardProgress = async (label, options, work) => {
		const progress = prompter.progress(label);
		try {
			return await work(progress);
		} finally {
			progress.stop(options.doneMessage);
		}
	};
	const systemdAvailable = process.platform === "linux" ? await isSystemdUserServiceAvailable() : true;
	if (process.platform === "linux" && !systemdAvailable) await prompter.note("Systemd user services are unavailable. Skipping lingering checks and service install.", "Systemd");
	if (process.platform === "linux" && systemdAvailable) {
		const { ensureSystemdUserLingerInteractive } = await import("./systemd-linger-D4DzdniD.js").then((n) => n.r);
		await ensureSystemdUserLingerInteractive({
			runtime,
			prompter: {
				confirm: prompter.confirm,
				note: prompter.note
			},
			reason: "Linux installs use a systemd user service by default. Without lingering, systemd stops the user session on logout/idle and kills the Gateway.",
			requireConfirm: false
		});
	}
	const explicitInstallDaemon = typeof opts.installDaemon === "boolean" ? opts.installDaemon : void 0;
	let installDaemon;
	if (explicitInstallDaemon !== void 0) installDaemon = explicitInstallDaemon;
	else if (process.platform === "linux" && !systemdAvailable) installDaemon = false;
	else if (flow === "quickstart") installDaemon = true;
	else installDaemon = await prompter.confirm({
		message: "Install Gateway service (recommended)",
		initialValue: true
	});
	if (process.platform === "linux" && !systemdAvailable && installDaemon) {
		await prompter.note("Systemd user services are unavailable; skipping service install. Use your container supervisor or `docker compose up -d`.", "Gateway service");
		installDaemon = false;
	}
	if (installDaemon) {
		const daemonRuntime = flow === "quickstart" ? DEFAULT_GATEWAY_DAEMON_RUNTIME : await prompter.select({
			message: "Gateway service runtime",
			options: GATEWAY_DAEMON_RUNTIME_OPTIONS,
			initialValue: opts.daemonRuntime ?? DEFAULT_GATEWAY_DAEMON_RUNTIME
		});
		if (flow === "quickstart") await prompter.note("QuickStart uses Node for the Gateway service (stable + supported).", "Gateway service runtime");
		const service = resolveGatewayService();
		const loaded = await service.isLoaded({ env: process.env });
		if (loaded) {
			const action = await prompter.select({
				message: "Gateway service already installed",
				options: [
					{
						value: "restart",
						label: "Restart"
					},
					{
						value: "reinstall",
						label: "Reinstall"
					},
					{
						value: "skip",
						label: "Skip"
					}
				]
			});
			if (action === "restart") await withWizardProgress("Gateway service", { doneMessage: "Gateway service restarted." }, async (progress) => {
				progress.update("Restarting Gateway service…");
				await service.restart({
					env: process.env,
					stdout: process.stdout
				});
			});
			else if (action === "reinstall") await withWizardProgress("Gateway service", { doneMessage: "Gateway service uninstalled." }, async (progress) => {
				progress.update("Uninstalling Gateway service…");
				await service.uninstall({
					env: process.env,
					stdout: process.stdout
				});
			});
		}
		if (!loaded || loaded && !await service.isLoaded({ env: process.env })) {
			const progress = prompter.progress("Gateway service");
			let installError = null;
			try {
				progress.update("Preparing Gateway service…");
				const { programArguments, workingDirectory, environment } = await buildGatewayInstallPlan({
					env: process.env,
					port: settings.port,
					token: settings.gatewayToken,
					runtime: daemonRuntime,
					warn: (message, title) => prompter.note(message, title),
					config: nextConfig
				});
				progress.update("Installing Gateway service…");
				await service.install({
					env: process.env,
					stdout: process.stdout,
					programArguments,
					workingDirectory,
					environment
				});
			} catch (err) {
				installError = err instanceof Error ? err.message : String(err);
			} finally {
				progress.stop(installError ? "Gateway service install failed." : "Gateway service installed.");
			}
			if (installError) {
				await prompter.note(`Gateway service install failed: ${installError}`, "Gateway");
				await prompter.note(gatewayInstallErrorHint(), "Gateway");
			}
		}
	}
	if (!opts.skipHealth) {
		await waitForGatewayReachable({
			url: resolveControlUiLinks({
				bind: nextConfig.gateway?.bind ?? "loopback",
				port: settings.port,
				customBindHost: nextConfig.gateway?.customBindHost,
				basePath: void 0
			}).wsUrl,
			token: settings.gatewayToken,
			deadlineMs: 15e3
		});
		try {
			await healthCommand({
				json: false,
				timeoutMs: 1e4
			}, runtime);
		} catch (err) {
			runtime.error(formatHealthCheckFailure(err));
			await prompter.note([
				"Docs:",
				"https://docs.openclaw.ai/gateway/health",
				"https://docs.openclaw.ai/gateway/troubleshooting"
			].join("\n"), "Health check help");
		}
	}
	const controlUiEnabled = nextConfig.gateway?.controlUi?.enabled ?? baseConfig.gateway?.controlUi?.enabled ?? true;
	if (!opts.skipUi && controlUiEnabled) {
		const controlUiAssets = await ensureControlUiAssetsBuilt(runtime);
		if (!controlUiAssets.ok && controlUiAssets.message) runtime.error(controlUiAssets.message);
	}
	await prompter.note([
		"Add nodes for extra features:",
		"- macOS app (system + notifications)",
		"- iOS app (camera/canvas)",
		"- Android app (camera/canvas)"
	].join("\n"), "Optional apps");
	const controlUiBasePath = nextConfig.gateway?.controlUi?.basePath ?? baseConfig.gateway?.controlUi?.basePath;
	const links = resolveControlUiLinks({
		bind: settings.bind,
		port: settings.port,
		customBindHost: settings.customBindHost,
		basePath: controlUiBasePath
	});
	const authedUrl = settings.authMode === "token" && settings.gatewayToken ? `${links.httpUrl}#token=${encodeURIComponent(settings.gatewayToken)}` : links.httpUrl;
	const gatewayProbe = await probeGatewayReachable({
		url: links.wsUrl,
		token: settings.authMode === "token" ? settings.gatewayToken : void 0,
		password: settings.authMode === "password" ? nextConfig.gateway?.auth?.password : ""
	});
	const gatewayStatusLine = gatewayProbe.ok ? "Gateway: reachable" : `Gateway: not detected${gatewayProbe.detail ? ` (${gatewayProbe.detail})` : ""}`;
	const bootstrapPath = path.join(resolveUserPath(options.workspaceDir), DEFAULT_BOOTSTRAP_FILENAME);
	const hasBootstrap = await fs.access(bootstrapPath).then(() => true).catch(() => false);
	await prompter.note([
		`Web UI: ${links.httpUrl}`,
		settings.authMode === "token" && settings.gatewayToken ? `Web UI (with token): ${authedUrl}` : void 0,
		`Gateway WS: ${links.wsUrl}`,
		gatewayStatusLine,
		"Docs: https://docs.openclaw.ai/web/control-ui"
	].filter(Boolean).join("\n"), "Control UI");
	let controlUiOpened = false;
	let controlUiOpenHint;
	let hatchChoice = null;
	let launchedTui = false;
	if (!opts.skipUi && gatewayProbe.ok) {
		if (hasBootstrap) await prompter.note([
			"This is the defining action that makes your agent you.",
			"Please take your time.",
			"The more you tell it, the better the experience will be.",
			"We will send: \"Wake up, my friend!\""
		].join("\n"), "Start TUI (best option!)");
		await prompter.note([
			"Gateway token: shared auth for the Gateway + Control UI.",
			"Stored in: ~/.openclaw/openclaw.json (gateway.auth.token) or OPENCLAW_GATEWAY_TOKEN.",
			`View token: ${formatCliCommand("openclaw config get gateway.auth.token")}`,
			`Generate token: ${formatCliCommand("openclaw doctor --generate-gateway-token")}`,
			"Web UI stores a copy in this browser's localStorage (openclaw.control.settings.v1).",
			`Open the dashboard anytime: ${formatCliCommand("openclaw dashboard --no-open")}`,
			"If prompted: paste the token into Control UI settings (or use the tokenized dashboard URL)."
		].join("\n"), "Token");
		hatchChoice = await prompter.select({
			message: "How do you want to hatch your bot?",
			options: [
				{
					value: "tui",
					label: "Hatch in TUI (recommended)"
				},
				{
					value: "web",
					label: "Open the Web UI"
				},
				{
					value: "later",
					label: "Do this later"
				}
			],
			initialValue: "tui"
		});
		if (hatchChoice === "tui") {
			restoreTerminalState("pre-onboarding tui", { resumeStdinIfPaused: true });
			await runTui({
				url: links.wsUrl,
				token: settings.authMode === "token" ? settings.gatewayToken : void 0,
				password: settings.authMode === "password" ? nextConfig.gateway?.auth?.password : "",
				deliver: false,
				message: hasBootstrap ? "Wake up, my friend!" : void 0
			});
			launchedTui = true;
		} else if (hatchChoice === "web") {
			if ((await detectBrowserOpenSupport()).ok) {
				controlUiOpened = await openUrl(authedUrl);
				if (!controlUiOpened) controlUiOpenHint = formatControlUiSshHint({
					port: settings.port,
					basePath: controlUiBasePath,
					token: settings.authMode === "token" ? settings.gatewayToken : void 0
				});
			} else controlUiOpenHint = formatControlUiSshHint({
				port: settings.port,
				basePath: controlUiBasePath,
				token: settings.authMode === "token" ? settings.gatewayToken : void 0
			});
			await prompter.note([
				`Dashboard link (with token): ${authedUrl}`,
				controlUiOpened ? "Opened in your browser. Keep that tab to control OpenClaw." : "Copy/paste this URL in a browser on this machine to control OpenClaw.",
				controlUiOpenHint
			].filter(Boolean).join("\n"), "Dashboard ready");
		} else await prompter.note(`When you're ready: ${formatCliCommand("openclaw dashboard --no-open")}`, "Later");
	} else if (opts.skipUi) await prompter.note("Skipping Control UI/TUI prompts.", "Control UI");
	await prompter.note(["Back up your agent workspace.", "Docs: https://docs.openclaw.ai/concepts/agent-workspace"].join("\n"), "Workspace backup");
	await prompter.note("Running agents on your computer is risky — harden your setup: https://docs.openclaw.ai/security", "Security");
	await setupOnboardingShellCompletion({
		flow,
		prompter
	});
	if (!opts.skipUi && settings.authMode === "token" && Boolean(settings.gatewayToken) && hatchChoice === null) {
		if ((await detectBrowserOpenSupport()).ok) {
			controlUiOpened = await openUrl(authedUrl);
			if (!controlUiOpened) controlUiOpenHint = formatControlUiSshHint({
				port: settings.port,
				basePath: controlUiBasePath,
				token: settings.gatewayToken
			});
		} else controlUiOpenHint = formatControlUiSshHint({
			port: settings.port,
			basePath: controlUiBasePath,
			token: settings.gatewayToken
		});
		await prompter.note([
			`Dashboard link (with token): ${authedUrl}`,
			controlUiOpened ? "Opened in your browser. Keep that tab to control OpenClaw." : "Copy/paste this URL in a browser on this machine to control OpenClaw.",
			controlUiOpenHint
		].filter(Boolean).join("\n"), "Dashboard ready");
	}
	const webSearchKey = (nextConfig.tools?.web?.search?.apiKey ?? "").trim();
	const webSearchEnv = (process.env.BRAVE_API_KEY ?? "").trim();
	const hasWebSearchKey = Boolean(webSearchKey || webSearchEnv);
	await prompter.note(hasWebSearchKey ? [
		"Web search is enabled, so your agent can look things up online when needed.",
		"",
		webSearchKey ? "API key: stored in config (tools.web.search.apiKey)." : "API key: provided via BRAVE_API_KEY env var (Gateway environment).",
		"Docs: https://docs.openclaw.ai/tools/web"
	].join("\n") : [
		"If you want your agent to be able to search the web, you’ll need an API key.",
		"",
		"OpenClaw uses Brave Search for the `web_search` tool. Without a Brave Search API key, web search won’t work.",
		"",
		"Set it up interactively:",
		`- Run: ${formatCliCommand("openclaw configure --section web")}`,
		"- Enable web_search and paste your Brave Search API key",
		"",
		"Alternative: set BRAVE_API_KEY in the Gateway environment (no config changes).",
		"Docs: https://docs.openclaw.ai/tools/web"
	].join("\n"), "Web search (optional)");
	await prompter.note("What now: https://openclaw.ai/showcase (\"What People Are Building\").", "What now");
	await prompter.outro(controlUiOpened ? "Onboarding complete. Dashboard opened; keep that tab to control OpenClaw." : "Onboarding complete. Use the dashboard link above to control OpenClaw.");
	return { launchedTui };
}

//#endregion
export { finalizeOnboardingWizard };