import { Tn as resolveModelProfile } from "./unified-runner-DXjH-prv.js";
import "./registry-Sbac4a4z.js";
import "./paths-By0XjHBk.js";
import "./utils-CTPsqyE_.js";
import "./subsystem-CHbO_DkH.js";
import "./auth-profiles-D5nYBj_Z.js";
import "./exec-DuYbft0z.js";
import "./agent-scope-Bnsyyeci.js";
import "./model-selection-CCTzD29o.js";
import "./file-lock-2AecMjCa.js";
import "./agent-paths-BbZSGrUA.js";
import "./pi-embedded-helpers-j1JrlsI0.js";
import { i as loadConfig } from "./config-BngIfn5l.js";
import "./boolean-CbZoNRMn.js";
import "./env-BRnPI9sO.js";
import "./shell-env-Dc3iU7HK.js";
import "./manifest-registry-D1MLZEjS.js";
import "./sandbox-CZGTCone.js";
import "./chrome-38OnGyuN.js";
import "./tailscale-DpKBMIvx.js";
import "./auth-Bkx-QuRN.js";
import "./server-context-DXdk410X.js";
import "./frontmatter-B_jqcova.js";
import "./skills-CYcBtLGH.js";
import "./routes-BwTUoI5h.js";
import "./redact-B3O-RBO1.js";
import "./errors-bI7Tdx75.js";
import "./fs-safe-B0Is-oLk.js";
import "./paths-BWqg8NZT.js";
import "./ssrf-DOZRI5XH.js";
import "./image-ops-BzCBIakN.js";
import "./ports-CB_Iu83U.js";
import "./trash-_YhavPQI.js";
import "./sessions-BCc3THTm.js";
import "./dock-hF45sewN.js";
import "./message-channel-DgjXWzf-.js";
import "./plugins-CF5skkHh.js";
import "./send-CxjvucMO.js";
import "./paths-BtvQ7JvU.js";
import "./thinking-COroyVA5.js";
import "./tokens-0yh2UnJq.js";
import "./deliver-CWMFmMCv.js";
import "./diagnostic-DbT9t0Sh.js";
import "./diagnostic-session-state-DnkpMfCl.js";
import "./model-auth-_C07_3Yr.js";
import "./github-copilot-token-D-FdDfee.js";
import "./models-config-DlXge3Sd.js";
import "./pi-auth-json-D-vdh-nY.js";
import "./session-cost-usage-D3mgssM_.js";
import "./session-utils-CJhcRx3E.js";
import "./with-timeout-CLrF-Yr_.js";
import "./reply-prefix-CtZtkTJK.js";
import "./memory-BFnx3v3_.js";
import "./manager-DG6PODgu.js";
import "./sqlite-BpogPlQW.js";
import "./chunk-BxfKjCUx.js";
import "./markdown-tables-CS1Tvb3z.js";
import "./fetch-guard-JHxT9355.js";
import "./local-roots-2Jb79HZ8.js";
import "./commands-DUzLGgEZ.js";
import "./commands-registry-CwXsDVuO.js";
import "./client-CTrfpKT3.js";
import "./call-Bpjj5p7I.js";
import "./pairing-token-B703A1U3.js";
import "./tool-display-DFOL6UQ9.js";
import "./skills-remote-BcRQTDsZ.js";
import "./workspace-dirs-DCICLTHx.js";
import "./pi-model-discovery-ClQLvlCW.js";
import "./model-catalog-BWurV7gl.js";
import "./skill-commands-DWvXs3lz.js";
import "./pairing-store-Be-ZQK87.js";
import "./exec-approvals-DioSaIeH.js";
import "./nodes-screen-Cp5QP3ET.js";
import "./breakdown-B_Dhhm3K.js";
import "./control-service-CUreKVeY.js";
import "./stagger-DQs772BN.js";
import "./channel-selection-H1qOf0q-.js";
import "./delivery-queue-OAc7hsIs.js";
import "./bindings-DIhsYGa_.js";
import "./resolve-route-Du0VftVs.js";
import "./links-Bqr0FxXx.js";
import "./cli-utils-CuyGL3rq.js";
import "./help-format-7hFcsqss.js";
import "./progress-swt2y17x.js";
import "./memory-cli-CHNghdrm.js";
import "./logging-BWknayJl.js";
import "./replies-B_3j7R_Q.js";
import "./pi-tools.policy-CvAqjEH9.js";
import "./model-Cwbcw-km.js";
import "./deps-CdibsPMx.js";
import "./runtime-guard-CWA00ZXa.js";
import "./catalog-BptA-dUv.js";
import "./skills-status-DLnCHUZ2.js";
import "./prompt-style-olk5zI5k.js";
import "./install-safe-path-BrpA09f2.js";
import "./skill-scanner-CIlHPszT.js";
import "./channels-status-issues-DLIzUsjR.js";
import "./onboard-helpers-BKejzolA.js";
import "./systemd-CsoVnIbM.js";
import "./service-CRZoXO_n.js";
import "./diagnostics-CYkqD5lP.js";
import "./table-0A3xKJVC.js";
import "./audit-CXIXYDRx.js";
import "./status-BWxLtb3D.js";
import "./health-CMbUI4aN.js";
import "./control-ui-assets-B8B9z_Ll.js";
import "./update-check-u6Jgr1cz.js";
import { n as handleGatewayRequest } from "./server-methods-DfVfzYqq.js";
import "./push-apns-CBGvXev_.js";
import "./agent-NT0EKnK_.js";
import "./agents.config-DA0ISLi7.js";
import "./dm-policy-shared-B61_yf6G.js";
import "./node-service-Cc18m-uk.js";
import "./status.update-CKfyV6zw.js";
import "./skills-install-BTa9IuQ6.js";
import "./update-runner-G2YgEATs.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 };