import { Tn as resolveModelProfile } from "./unified-runner-4O0ifBsI.js";
import "./registry-Sbac4a4z.js";
import "./paths-By0XjHBk.js";
import "./utils-CTPsqyE_.js";
import "./subsystem-CHbO_DkH.js";
import "./auth-profiles-Ce7R_25e.js";
import "./exec-DuYbft0z.js";
import "./agent-scope-DOrZjOnW.js";
import "./model-selection-7wdmO-Iw.js";
import "./file-lock-BVUYnlQv.js";
import "./agent-paths-BbZSGrUA.js";
import "./pi-embedded-helpers-D-OFjhdI.js";
import { i as loadConfig } from "./config-B4jkreCN.js";
import "./boolean-CbZoNRMn.js";
import "./env-BRnPI9sO.js";
import "./shell-env-Dc3iU7HK.js";
import "./manifest-registry-D1MLZEjS.js";
import "./sandbox-BkznAPKO.js";
import "./chrome-DJChpTwP.js";
import "./tailscale-DpKBMIvx.js";
import "./auth-Bkx-QuRN.js";
import "./server-context-ChcbJgNo.js";
import "./frontmatter-B_jqcova.js";
import "./skills-BwDmcZdt.js";
import "./routes-ivqbutvM.js";
import "./redact-B3O-RBO1.js";
import "./errors-bI7Tdx75.js";
import "./fs-safe-BdejYjW8.js";
import "./paths-DObzwe08.js";
import "./ssrf-DOZRI5XH.js";
import "./image-ops-L70xVnpG.js";
import "./ports-gxLM5ahL.js";
import "./trash-_YhavPQI.js";
import "./sessions-Dxf5Kjig.js";
import "./dock-hF45sewN.js";
import "./message-channel-DgjXWzf-.js";
import "./plugins-CF5skkHh.js";
import "./send-B0jHSNMF.js";
import "./paths-BtvQ7JvU.js";
import "./thinking-COroyVA5.js";
import "./tokens-0yh2UnJq.js";
import "./deliver-lTZLIQqf.js";
import "./diagnostic-DbT9t0Sh.js";
import "./diagnostic-session-state-DnkpMfCl.js";
import "./model-auth-1EAQvYRv.js";
import "./github-copilot-token-D-FdDfee.js";
import "./models-config-B5Xxy-c-.js";
import "./pi-auth-json-Db8XJVGL.js";
import "./session-cost-usage-D3mgssM_.js";
import "./session-utils-Cs1jlD-q.js";
import "./with-timeout-DPR4A2dx.js";
import "./reply-prefix-BFNeXT65.js";
import "./memory-BZ24UkLW.js";
import "./manager-Cw7IJGbB.js";
import "./sqlite-Cod7C5ba.js";
import "./chunk-BxfKjCUx.js";
import "./markdown-tables-CS1Tvb3z.js";
import "./fetch-guard-JHxT9355.js";
import "./local-roots-CgDCgCuM.js";
import "./commands-DUzLGgEZ.js";
import "./commands-registry-Ca5hh7nh.js";
import "./client-DH75FlQF.js";
import "./call-AZ9vNhST.js";
import "./pairing-token-Dcy37-4s.js";
import "./tool-display-DFOL6UQ9.js";
import "./skills-remote-bz71Bstn.js";
import "./workspace-dirs-jKFQf7of.js";
import "./pi-model-discovery-ClQLvlCW.js";
import "./model-catalog-IWi6-nY9.js";
import "./skill-commands-DDGGlq68.js";
import "./pairing-store-BNhJOnWn.js";
import "./exec-approvals-DioSaIeH.js";
import "./nodes-screen-De9ma6e1.js";
import "./breakdown-B_Dhhm3K.js";
import "./control-service-D8kKOts5.js";
import "./stagger-DQs772BN.js";
import "./channel-selection-H1qOf0q-.js";
import "./delivery-queue-OAc7hsIs.js";
import "./bindings-DIhsYGa_.js";
import "./resolve-route-C1IIA6kH.js";
import "./links-Bqr0FxXx.js";
import "./cli-utils-CuyGL3rq.js";
import "./help-format-7hFcsqss.js";
import "./progress-swt2y17x.js";
import "./memory-cli-0HHYm-B8.js";
import "./logging-BWknayJl.js";
import "./replies-CbXXjn9X.js";
import "./pi-tools.policy-H2t-Xkfc.js";
import "./model-MUMSB_7d.js";
import "./deps-Bf9dt2UO.js";
import "./runtime-guard-CWA00ZXa.js";
import "./catalog-BptA-dUv.js";
import "./skills-status-BKX1PjCc.js";
import "./prompt-style-olk5zI5k.js";
import "./install-safe-path-B2JrFspY.js";
import "./skill-scanner-BCgVcIwi.js";
import "./channels-status-issues-DLIzUsjR.js";
import "./onboard-helpers-7IGQ8nAM.js";
import "./systemd-CUIM0n5P.js";
import "./service-e6MzlLCd.js";
import "./diagnostics-DlZODdRf.js";
import "./table-0A3xKJVC.js";
import "./audit-C_3fAFeS.js";
import "./status-D7QX7VDk.js";
import "./health-7UqIGG8U.js";
import "./control-ui-assets-CJQ97d4u.js";
import "./update-check-BCL_K7kx.js";
import { n as handleGatewayRequest } from "./server-methods-Bl41VzMu.js";
import "./push-apns-CyAPMMJC.js";
import "./agent-DxRVDqSg.js";
import "./agents.config-B7sNDvhz.js";
import "./dm-policy-shared-CeFt0nch.js";
import "./node-service-BH08wY5j.js";
import "./status.update-DGJi0OLl.js";
import "./skills-install-Dwzsjoc8.js";
import "./update-runner-BLV8SI96.js";

//#region src/gateway/glass-ui-ws.ts
const SESSION_KEY = "agent:main:main";
/** Synthetic client used for all glass-ui bridge requests. */
const GLASS_UI_CLIENT = { connect: {
	minProtocol: 3,
	maxProtocol: 3,
	client: {
		id: "webchat",
		version: "1.0.0",
		platform: "server",
		mode: "webchat"
	},
	role: "operator",
	scopes: ["operator.admin"],
	caps: [],
	auth: {},
	userAgent: "symi-glass-ui-bridge/1.0.0",
	locale: "en-US"
} };
function isWebchatConnect() {
	return true;
}
function safeSend(ws, data) {
	try {
		if (ws.readyState === ws.OPEN) ws.send(JSON.stringify(data));
	} catch {}
}
function createGlassUiBridge(opts) {
	const { wss, context, extraHandlers, onBroadcast } = opts;
	const browserClients = /* @__PURE__ */ new Map();
	let broadcastSeq = 0;
	function broadcastToBrowsers(msg, seq) {
		for (const [, state] of browserClients) {
			if (seq <= state.lastBroadcastSeq) continue;
			state.lastBroadcastSeq = seq;
			safeSend(state.ws, msg);
		}
	}
	const broadcastUnsub = onBroadcast((event, payload) => {
		broadcastSeq++;
		const seq = broadcastSeq;
		if (event === "chat") broadcastToBrowsers({
			type: "chat",
			payload,
			_seq: seq
		}, seq);
		else if (event === "agent") broadcastToBrowsers({
			type: "agent",
			payload,
			_seq: seq
		}, seq);
		else if (event === "subagent") broadcastToBrowsers({
			type: "subagent",
			payload,
			_seq: seq
		}, seq);
		else if (event === "profile") broadcastToBrowsers({
			type: "profile",
			payload,
			_seq: seq
		}, seq);
	});
	/** Dispatch an RPC method through the gateway's internal handler. */
	async function dispatchRpc(method, params) {
		return new Promise((resolve) => {
			const req = {
				type: "req",
				id: "glass-bridge",
				method,
				params
			};
			const respond = (ok, payload, error) => {
				resolve({
					ok,
					payload,
					error
				});
			};
			handleGatewayRequest({
				req,
				client: GLASS_UI_CLIENT,
				isWebchatConnect,
				respond,
				context,
				extraHandlers
			});
		});
	}
	async function loadAndSendHistory(ws, attempt = 1) {
		const maxAttempts = 3;
		try {
			const result = await dispatchRpc("chat.history", { sessionKey: SESSION_KEY });
			if (result.ok) {
				const payload = result.payload;
				safeSend(ws, {
					type: "history",
					messages: payload.messages ?? [],
					total: payload.total ?? 0,
					hasMore: payload.hasMore ?? false,
					startIndex: payload.startIndex ?? 0
				});
			} else if (attempt < maxAttempts) setTimeout(() => void loadAndSendHistory(ws, attempt + 1), 1500 * attempt);
			else safeSend(ws, {
				type: "history",
				messages: [],
				total: 0,
				hasMore: false,
				startIndex: 0,
				error: "history.unavailable",
				recoverable: true
			});
		} catch {
			if (attempt < maxAttempts) setTimeout(() => void loadAndSendHistory(ws, attempt + 1), 1500 * attempt);
			else safeSend(ws, {
				type: "history",
				messages: [],
				total: 0,
				hasMore: false,
				startIndex: 0,
				error: "history.unavailable",
				recoverable: true
			});
		}
	}
	function sendInitialProfile(ws) {
		try {
			const cfg = loadConfig();
			const modelId = cfg.agents?.defaults?.model?.primary;
			if (!modelId) return;
			safeSend(ws, {
				type: "profile",
				payload: {
					event: "profile",
					profile: resolveModelProfile(modelId, cfg.models?.profiles),
					modelId
				}
			});
		} catch {}
	}
	wss.on("connection", (ws) => {
		browserClients.set(ws, {
			ws,
			lastBroadcastSeq: broadcastSeq
		});
		safeSend(ws, {
			type: "status",
			connected: true
		});
		sendInitialProfile(ws);
		loadAndSendHistory(ws);
		ws.on("message", (data) => {
			let msg;
			try {
				const text = Buffer.isBuffer(data) ? data.toString("utf8") : data instanceof ArrayBuffer ? Buffer.from(data).toString("utf8") : Array.isArray(data) ? Buffer.concat(data).toString("utf8") : "";
				msg = JSON.parse(text);
			} catch {
				return;
			}
			const type = msg.type;
			if (type === "chat.send") {
				(async () => {
					try {
						await dispatchRpc("chat.send", {
							sessionKey: SESSION_KEY,
							message: msg.message,
							idempotencyKey: crypto.randomUUID()
						});
					} catch (err) {
						safeSend(ws, {
							type: "error",
							message: String(err)
						});
					}
				})();
				return;
			}
			if (type === "chat.abort") {
				(async () => {
					try {
						const params = { sessionKey: SESSION_KEY };
						if (msg.runId) params.runId = msg.runId;
						await dispatchRpc("chat.abort", params);
					} catch (err) {
						safeSend(ws, {
							type: "error",
							message: String(err)
						});
					}
				})();
				return;
			}
			if (type === "rpc") {
				const rpcId = msg.id;
				const method = msg.method;
				const params = msg.params ?? {};
				(async () => {
					try {
						const result = await dispatchRpc(method, params);
						safeSend(ws, {
							type: "rpc.response",
							id: rpcId,
							ok: result.ok,
							payload: result.payload,
							error: result.error
						});
					} catch (err) {
						safeSend(ws, {
							type: "rpc.response",
							id: rpcId,
							ok: false,
							error: { message: String(err) }
						});
					}
				})();
				return;
			}
		});
		ws.on("close", () => {
			browserClients.delete(ws);
		});
		ws.on("error", () => {
			browserClients.delete(ws);
		});
	});
	return () => {
		broadcastUnsub();
		for (const [, state] of browserClients) try {
			state.ws.close();
		} catch {}
		browserClients.clear();
	};
}

//#endregion
export { createGlassUiBridge };