import "./pi-embedded-utils-Dx4_ysu7.js";
import { G as truncateUtf16Safe } from "./subsystem-B57zAnh3.js";
import "./paths-aMBPuCJR.js";
import "./auth-profiles-vy16iW9a.js";
import "./env-DFfOiqpV.js";
import "./exec-rVpUMUjU.js";
import "./agent-scope-C3vq_G9s.js";
import "./github-copilot-token-5G6j3BB0.js";
import "./reliability-CU83NHOD.js";
import "./sqlite-CbyDDiup.js";
import "./accounts-Diz2TIQa.js";
import "./dock-YZOG_yQS.js";
import "./normalize-C804TuMz.js";
import "./bindings-DLG2Bod-.js";
import "./plugins-DqFdJSNb.js";
import "./message-channel-Cw5DRkgR.js";
import "./image-ops-D6in9bm7.js";
import "./pi-embedded-helpers-14yhAK8Z.js";
import { n as loadConfig } from "./config-BWfcFg-o.js";
import "./manifest-registry-DOrMVNcS.js";
import { _ as withCdpSocket, d as normalizeCdpWsUrl, g as getHeadersWithAuth, m as fetchJson, p as appendCdpPath, t as getChromeWebSocketUrl } from "./chrome-CdUTjfym.js";
import "./server-context-CCjHJE9j.js";
import "./skills-WWjjkPNZ.js";
import "./redact-BXcZFg1V.js";
import { n as formatErrorMessage } from "./errors-CGLTQpIl.js";
import "./ssrf-Clw7QAxV.js";
import { v as capArrayByJsonBytes } from "./sessions-Bge3YYgW.js";
import "./paths-a4Li8t1f.js";
import "./tool-images-DTeIBF5l.js";
import "./thinking-B4KYQMkY.js";
import { a as jsonResult, u as readStringParam } from "./common-CBZ0Olph.js";
import { n as callGateway } from "./call-qL_BTieR.js";
import { a as stripToolMessages, c as resolveEffectiveSessionToolsVisibility, l as resolveSandboxedSessionToolContext, m as resolveSessionReference, o as createAgentToAgentPolicy, s as createSessionVisibilityGuard, u as isRequesterSpawnedSessionVisible } from "./sessions-helpers-CApxk4ya.js";
import { Type } from "@sinclair/typebox";
import { chromium } from "playwright-core";

//#region src/agents/tools/sessions/sessions-history-tool.ts
const SessionsHistoryToolSchema = Type.Object({
	sessionKey: Type.String(),
	limit: Type.Optional(Type.Number({ minimum: 1 })),
	includeTools: Type.Optional(Type.Boolean())
});
const SESSIONS_HISTORY_MAX_BYTES = 80 * 1024;
const SESSIONS_HISTORY_TEXT_MAX_CHARS = 4e3;
function truncateHistoryText(text) {
	if (text.length <= SESSIONS_HISTORY_TEXT_MAX_CHARS) return {
		text,
		truncated: false
	};
	return {
		text: `${truncateUtf16Safe(text, SESSIONS_HISTORY_TEXT_MAX_CHARS)}\n…(truncated)…`,
		truncated: true
	};
}
function sanitizeHistoryContentBlock(block) {
	if (!block || typeof block !== "object") return {
		block,
		truncated: false
	};
	const entry = { ...block };
	let truncated = false;
	const type = typeof entry.type === "string" ? entry.type : "";
	if (typeof entry.text === "string") {
		const res = truncateHistoryText(entry.text);
		entry.text = res.text;
		truncated ||= res.truncated;
	}
	if (type === "thinking") {
		if (typeof entry.thinking === "string") {
			const res = truncateHistoryText(entry.thinking);
			entry.thinking = res.text;
			truncated ||= res.truncated;
		}
		if ("thinkingSignature" in entry) {
			delete entry.thinkingSignature;
			truncated = true;
		}
	}
	if (typeof entry.partialJson === "string") {
		const res = truncateHistoryText(entry.partialJson);
		entry.partialJson = res.text;
		truncated ||= res.truncated;
	}
	if (type === "image") {
		const data = typeof entry.data === "string" ? entry.data : void 0;
		const bytes = data ? data.length : void 0;
		if ("data" in entry) {
			delete entry.data;
			truncated = true;
		}
		entry.omitted = true;
		if (bytes !== void 0) entry.bytes = bytes;
	}
	return {
		block: entry,
		truncated
	};
}
function sanitizeHistoryMessage(message) {
	if (!message || typeof message !== "object") return {
		message,
		truncated: false
	};
	const entry = { ...message };
	let truncated = false;
	if ("details" in entry) {
		delete entry.details;
		truncated = true;
	}
	if ("usage" in entry) {
		delete entry.usage;
		truncated = true;
	}
	if ("cost" in entry) {
		delete entry.cost;
		truncated = true;
	}
	if (typeof entry.content === "string") {
		const res = truncateHistoryText(entry.content);
		entry.content = res.text;
		truncated ||= res.truncated;
	} else if (Array.isArray(entry.content)) {
		const updated = entry.content.map((block) => sanitizeHistoryContentBlock(block));
		entry.content = updated.map((item) => item.block);
		truncated ||= updated.some((item) => item.truncated);
	}
	if (typeof entry.text === "string") {
		const res = truncateHistoryText(entry.text);
		entry.text = res.text;
		truncated ||= res.truncated;
	}
	return {
		message: entry,
		truncated
	};
}
function jsonUtf8Bytes(value) {
	try {
		return Buffer.byteLength(JSON.stringify(value), "utf8");
	} catch {
		return Buffer.byteLength(String(value), "utf8");
	}
}
function enforceSessionsHistoryHardCap(params) {
	if (params.bytes <= params.maxBytes) return {
		items: params.items,
		bytes: params.bytes,
		hardCapped: false
	};
	const last = params.items.at(-1);
	const lastOnly = last ? [last] : [];
	const lastBytes = jsonUtf8Bytes(lastOnly);
	if (lastBytes <= params.maxBytes) return {
		items: lastOnly,
		bytes: lastBytes,
		hardCapped: true
	};
	const placeholder = [{
		role: "assistant",
		content: "[sessions_history omitted: message too large]"
	}];
	return {
		items: placeholder,
		bytes: jsonUtf8Bytes(placeholder),
		hardCapped: true
	};
}
function createSessionsHistoryTool(opts) {
	return {
		label: "Session History",
		name: "sessions_history",
		description: "Fetch message history for a session.",
		parameters: SessionsHistoryToolSchema,
		execute: async (_toolCallId, args) => {
			const params = args;
			const sessionKeyParam = readStringParam(params, "sessionKey", { required: true });
			const cfg = loadConfig();
			const { mainKey, alias, effectiveRequesterKey, restrictToSpawned } = resolveSandboxedSessionToolContext({
				cfg,
				agentSessionKey: opts?.agentSessionKey,
				sandboxed: opts?.sandboxed
			});
			const resolvedSession = await resolveSessionReference({
				sessionKey: sessionKeyParam,
				alias,
				mainKey,
				requesterInternalKey: effectiveRequesterKey,
				restrictToSpawned
			});
			if (!resolvedSession.ok) return jsonResult({
				status: resolvedSession.status,
				error: resolvedSession.error
			});
			const resolvedKey = resolvedSession.key;
			const displayKey = resolvedSession.displayKey;
			const resolvedViaSessionId = resolvedSession.resolvedViaSessionId;
			if (restrictToSpawned && !resolvedViaSessionId && resolvedKey !== effectiveRequesterKey) {
				if (!await isRequesterSpawnedSessionVisible({
					requesterSessionKey: effectiveRequesterKey,
					targetSessionKey: resolvedKey
				})) return jsonResult({
					status: "forbidden",
					error: `Session not visible from this sandboxed agent session: ${sessionKeyParam}`
				});
			}
			const a2aPolicy = createAgentToAgentPolicy(cfg);
			const access = (await createSessionVisibilityGuard({
				action: "history",
				requesterSessionKey: effectiveRequesterKey,
				visibility: resolveEffectiveSessionToolsVisibility({
					cfg,
					sandboxed: opts?.sandboxed === true
				}),
				a2aPolicy
			})).check(resolvedKey);
			if (!access.allowed) return jsonResult({
				status: access.status,
				error: access.error
			});
			const limit = typeof params.limit === "number" && Number.isFinite(params.limit) ? Math.max(1, Math.floor(params.limit)) : void 0;
			const includeTools = Boolean(params.includeTools);
			const result = await callGateway({
				method: "chat.history",
				params: {
					sessionKey: resolvedKey,
					limit
				}
			});
			const rawMessages = Array.isArray(result?.messages) ? result.messages : [];
			const selectedMessages = includeTools ? rawMessages : stripToolMessages(rawMessages);
			const sanitizedMessages = selectedMessages.map((message) => sanitizeHistoryMessage(message));
			const contentTruncated = sanitizedMessages.some((entry) => entry.truncated);
			const cappedMessages = capArrayByJsonBytes(sanitizedMessages.map((entry) => entry.message), SESSIONS_HISTORY_MAX_BYTES);
			const droppedMessages = cappedMessages.items.length < selectedMessages.length;
			const hardened = enforceSessionsHistoryHardCap({
				items: cappedMessages.items,
				bytes: cappedMessages.bytes,
				maxBytes: SESSIONS_HISTORY_MAX_BYTES
			});
			return jsonResult({
				sessionKey: displayKey,
				messages: hardened.items,
				truncated: droppedMessages || contentTruncated || hardened.hardCapped,
				droppedMessages: droppedMessages || hardened.hardCapped,
				contentTruncated,
				bytes: hardened.bytes
			});
		}
	};
}

//#endregion
//#region src/browser/pw-session.ts
const pageStates = /* @__PURE__ */ new WeakMap();
const contextStates = /* @__PURE__ */ new WeakMap();
const observedContexts = /* @__PURE__ */ new WeakSet();
const observedPages = /* @__PURE__ */ new WeakSet();
const roleRefsByTarget = /* @__PURE__ */ new Map();
const MAX_ROLE_REFS_CACHE = 50;
const MAX_CONSOLE_MESSAGES = 500;
const MAX_PAGE_ERRORS = 200;
const MAX_NETWORK_REQUESTS = 500;
let cached = null;
let connecting = null;
function normalizeCdpUrl(raw) {
	return raw.replace(/\/$/, "");
}
function findNetworkRequestById(state, id) {
	for (let i = state.requests.length - 1; i >= 0; i -= 1) {
		const candidate = state.requests[i];
		if (candidate && candidate.id === id) return candidate;
	}
}
function roleRefsKey(cdpUrl, targetId) {
	return `${normalizeCdpUrl(cdpUrl)}::${targetId}`;
}
function rememberRoleRefsForTarget(opts) {
	const targetId = opts.targetId.trim();
	if (!targetId) return;
	roleRefsByTarget.set(roleRefsKey(opts.cdpUrl, targetId), {
		refs: opts.refs,
		...opts.frameSelector ? { frameSelector: opts.frameSelector } : {},
		...opts.mode ? { mode: opts.mode } : {}
	});
	while (roleRefsByTarget.size > MAX_ROLE_REFS_CACHE) {
		const first = roleRefsByTarget.keys().next();
		if (first.done) break;
		roleRefsByTarget.delete(first.value);
	}
}
function storeRoleRefsForTarget(opts) {
	const state = ensurePageState(opts.page);
	state.roleRefs = opts.refs;
	state.roleRefsFrameSelector = opts.frameSelector;
	state.roleRefsMode = opts.mode;
	if (!opts.targetId?.trim()) return;
	rememberRoleRefsForTarget({
		cdpUrl: opts.cdpUrl,
		targetId: opts.targetId,
		refs: opts.refs,
		frameSelector: opts.frameSelector,
		mode: opts.mode
	});
}
function restoreRoleRefsForTarget(opts) {
	const targetId = opts.targetId?.trim() || "";
	if (!targetId) return;
	const cached = roleRefsByTarget.get(roleRefsKey(opts.cdpUrl, targetId));
	if (!cached) return;
	const state = ensurePageState(opts.page);
	if (state.roleRefs) return;
	state.roleRefs = cached.refs;
	state.roleRefsFrameSelector = cached.frameSelector;
	state.roleRefsMode = cached.mode;
}
function ensurePageState(page) {
	const existing = pageStates.get(page);
	if (existing) return existing;
	const state = {
		console: [],
		errors: [],
		requests: [],
		requestIds: /* @__PURE__ */ new WeakMap(),
		nextRequestId: 0,
		armIdUpload: 0,
		armIdDialog: 0,
		armIdDownload: 0
	};
	pageStates.set(page, state);
	if (!observedPages.has(page)) {
		observedPages.add(page);
		page.on("console", (msg) => {
			const entry = {
				type: msg.type(),
				text: msg.text(),
				timestamp: (/* @__PURE__ */ new Date()).toISOString(),
				location: msg.location()
			};
			state.console.push(entry);
			if (state.console.length > MAX_CONSOLE_MESSAGES) state.console.shift();
		});
		page.on("pageerror", (err) => {
			state.errors.push({
				message: err?.message ? String(err.message) : String(err),
				name: err?.name ? String(err.name) : void 0,
				stack: err?.stack ? String(err.stack) : void 0,
				timestamp: (/* @__PURE__ */ new Date()).toISOString()
			});
			if (state.errors.length > MAX_PAGE_ERRORS) state.errors.shift();
		});
		page.on("request", (req) => {
			state.nextRequestId += 1;
			const id = `r${state.nextRequestId}`;
			state.requestIds.set(req, id);
			state.requests.push({
				id,
				timestamp: (/* @__PURE__ */ new Date()).toISOString(),
				method: req.method(),
				url: req.url(),
				resourceType: req.resourceType()
			});
			if (state.requests.length > MAX_NETWORK_REQUESTS) state.requests.shift();
		});
		page.on("response", (resp) => {
			const req = resp.request();
			const id = state.requestIds.get(req);
			if (!id) return;
			const rec = findNetworkRequestById(state, id);
			if (!rec) return;
			rec.status = resp.status();
			rec.ok = resp.ok();
		});
		page.on("requestfailed", (req) => {
			const id = state.requestIds.get(req);
			if (!id) return;
			const rec = findNetworkRequestById(state, id);
			if (!rec) return;
			rec.failureText = req.failure()?.errorText;
			rec.ok = false;
		});
		page.on("close", () => {
			pageStates.delete(page);
			observedPages.delete(page);
		});
	}
	return state;
}
function observeContext(context) {
	if (observedContexts.has(context)) return;
	observedContexts.add(context);
	ensureContextState(context);
	for (const page of context.pages()) ensurePageState(page);
	context.on("page", (page) => ensurePageState(page));
}
function ensureContextState(context) {
	const existing = contextStates.get(context);
	if (existing) return existing;
	const state = { traceActive: false };
	contextStates.set(context, state);
	return state;
}
function observeBrowser(browser) {
	for (const context of browser.contexts()) observeContext(context);
}
async function connectBrowser(cdpUrl) {
	const normalized = normalizeCdpUrl(cdpUrl);
	if (cached?.cdpUrl === normalized) return cached;
	if (connecting) return await connecting;
	const connectWithRetry = async () => {
		let lastErr;
		for (let attempt = 0; attempt < 2; attempt += 1) try {
			const timeout = 3e3 + attempt * 2e3;
			const endpoint = await getChromeWebSocketUrl(normalized, timeout).catch(() => null) ?? normalized;
			const headers = getHeadersWithAuth(endpoint);
			const browser = await chromium.connectOverCDP(endpoint, {
				timeout,
				headers
			});
			const onDisconnected = () => {
				if (cached?.browser === browser) cached = null;
			};
			const connected = {
				browser,
				cdpUrl: normalized,
				onDisconnected
			};
			cached = connected;
			browser.on("disconnected", onDisconnected);
			observeBrowser(browser);
			return connected;
		} catch (err) {
			lastErr = err;
			const delay = 200 + attempt * 200;
			await new Promise((r) => setTimeout(r, delay));
		}
		if (lastErr instanceof Error) throw lastErr;
		const message = lastErr ? formatErrorMessage(lastErr) : "CDP connect failed";
		throw new Error(message);
	};
	connecting = connectWithRetry().finally(() => {
		connecting = null;
	});
	return await connecting;
}
async function getAllPages(browser) {
	return browser.contexts().flatMap((c) => c.pages());
}
async function pageTargetId(page) {
	const session = await page.context().newCDPSession(page);
	try {
		const info = await session.send("Target.getTargetInfo");
		return String(info?.targetInfo?.targetId ?? "").trim() || null;
	} finally {
		await session.detach().catch(() => {});
	}
}
async function findPageByTargetId(browser, targetId, cdpUrl) {
	const pages = await getAllPages(browser);
	let resolvedViaCdp = false;
	for (const page of pages) {
		let tid = null;
		try {
			tid = await pageTargetId(page);
			resolvedViaCdp = true;
		} catch {
			tid = null;
		}
		if (tid && tid === targetId) return page;
	}
	if (!resolvedViaCdp && pages.length === 1) return pages[0];
	if (cdpUrl) try {
		const listUrl = `${cdpUrl.replace(/\/+$/, "").replace(/^ws:/, "http:").replace(/\/cdp$/, "")}/json/list`;
		const response = await fetch(listUrl, { headers: getHeadersWithAuth(listUrl) });
		if (response.ok) {
			const targets = await response.json();
			const target = targets.find((t) => t.id === targetId);
			if (target) {
				const urlMatch = pages.filter((p) => p.url() === target.url);
				if (urlMatch.length === 1) return urlMatch[0];
				if (urlMatch.length > 1) {
					const sameUrlTargets = targets.filter((t) => t.url === target.url);
					if (sameUrlTargets.length === urlMatch.length) {
						const idx = sameUrlTargets.findIndex((t) => t.id === targetId);
						if (idx >= 0 && idx < urlMatch.length) return urlMatch[idx];
					}
				}
			}
		}
	} catch {}
	return null;
}
async function getPageForTargetId(opts) {
	const { browser } = await connectBrowser(opts.cdpUrl);
	const pages = await getAllPages(browser);
	if (!pages.length) throw new Error("No pages available in the connected browser.");
	const first = pages[0];
	if (!opts.targetId) return first;
	const found = await findPageByTargetId(browser, opts.targetId, opts.cdpUrl);
	if (!found) {
		if (pages.length === 1) return first;
		throw new Error("tab not found");
	}
	return found;
}
function refLocator(page, ref) {
	const normalized = ref.startsWith("@") ? ref.slice(1) : ref.startsWith("ref=") ? ref.slice(4) : ref;
	if (/^e\d+$/.test(normalized)) {
		const state = pageStates.get(page);
		if (state?.roleRefsMode === "aria") return (state.roleRefsFrameSelector ? page.frameLocator(state.roleRefsFrameSelector) : page).locator(`aria-ref=${normalized}`);
		const info = state?.roleRefs?.[normalized];
		if (!info) throw new Error(`Unknown ref "${normalized}". Run a new snapshot and use a ref from that snapshot.`);
		const locAny = state?.roleRefsFrameSelector ? page.frameLocator(state.roleRefsFrameSelector) : page;
		const locator = info.name ? locAny.getByRole(info.role, {
			name: info.name,
			exact: true
		}) : locAny.getByRole(info.role);
		return info.nth !== void 0 ? locator.nth(info.nth) : locator;
	}
	return page.locator(`aria-ref=${normalized}`);
}
async function closePlaywrightBrowserConnection() {
	const cur = cached;
	cached = null;
	connecting = null;
	if (!cur) return;
	if (cur.onDisconnected && typeof cur.browser.off === "function") cur.browser.off("disconnected", cur.onDisconnected);
	await cur.browser.close().catch(() => {});
}
function normalizeCdpHttpBaseForJsonEndpoints(cdpUrl) {
	try {
		const url = new URL(cdpUrl);
		if (url.protocol === "ws:") url.protocol = "http:";
		else if (url.protocol === "wss:") url.protocol = "https:";
		url.pathname = url.pathname.replace(/\/devtools\/browser\/.*$/, "");
		url.pathname = url.pathname.replace(/\/cdp$/, "");
		return url.toString().replace(/\/$/, "");
	} catch {
		return cdpUrl.replace(/^ws:/, "http:").replace(/^wss:/, "https:").replace(/\/devtools\/browser\/.*$/, "").replace(/\/cdp$/, "").replace(/\/$/, "");
	}
}
function cdpSocketNeedsAttach(wsUrl) {
	try {
		const pathname = new URL(wsUrl).pathname;
		return pathname === "/cdp" || pathname.endsWith("/cdp") || pathname.includes("/devtools/browser/");
	} catch {
		return false;
	}
}
async function tryTerminateExecutionViaCdp(opts) {
	const cdpHttpBase = normalizeCdpHttpBaseForJsonEndpoints(opts.cdpUrl);
	const pages = await fetchJson(appendCdpPath(cdpHttpBase, "/json/list"), 2e3).catch(() => null);
	if (!pages || pages.length === 0) return;
	const target = pages.find((p) => String(p.id ?? "").trim() === opts.targetId);
	const wsUrlRaw = String(target?.webSocketDebuggerUrl ?? "").trim();
	if (!wsUrlRaw) return;
	const wsUrl = normalizeCdpWsUrl(wsUrlRaw, cdpHttpBase);
	const needsAttach = cdpSocketNeedsAttach(wsUrl);
	const runWithTimeout = async (work, ms) => {
		let timer;
		const timeoutPromise = new Promise((_, reject) => {
			timer = setTimeout(() => reject(/* @__PURE__ */ new Error("CDP command timed out")), ms);
		});
		try {
			return await Promise.race([work, timeoutPromise]);
		} finally {
			if (timer) clearTimeout(timer);
		}
	};
	await withCdpSocket(wsUrl, async (send) => {
		let sessionId;
		try {
			if (needsAttach) {
				const attached = await runWithTimeout(send("Target.attachToTarget", {
					targetId: opts.targetId,
					flatten: true
				}), 1500);
				if (typeof attached?.sessionId === "string" && attached.sessionId.trim()) sessionId = attached.sessionId;
			}
			await runWithTimeout(send("Runtime.terminateExecution", void 0, sessionId), 1500);
			if (sessionId) send("Target.detachFromTarget", { sessionId }).catch(() => {});
		} catch {}
	}, { handshakeTimeoutMs: 2e3 }).catch(() => {});
}
/**
* Best-effort cancellation for stuck page operations.
*
* Playwright serializes CDP commands per page; a long-running or stuck operation (notably evaluate)
* can block all subsequent commands. We cannot safely "cancel" an individual command, and we do
* not want to close the actual Chromium tab. Instead, we disconnect Playwright's CDP connection
* so in-flight commands fail fast and the next request reconnects transparently.
*
* IMPORTANT: We CANNOT call Connection.close() because Playwright shares a single Connection
* across all objects (BrowserType, Browser, etc.). Closing it corrupts the entire Playwright
* instance, preventing reconnection.
*
* Instead we:
* 1. Null out `cached` so the next call triggers a fresh connectOverCDP
* 2. Fire-and-forget browser.close() — it may hang but won't block us
* 3. The next connectBrowser() creates a completely new CDP WebSocket connection
*
* The old browser.close() eventually resolves when the in-browser evaluate timeout fires,
* or the old connection gets GC'd. Either way, it doesn't affect the fresh connection.
*/
async function forceDisconnectPlaywrightForTarget(opts) {
	const normalized = normalizeCdpUrl(opts.cdpUrl);
	if (cached?.cdpUrl !== normalized) return;
	const cur = cached;
	cached = null;
	connecting = null;
	if (cur) {
		if (cur.onDisconnected && typeof cur.browser.off === "function") cur.browser.off("disconnected", cur.onDisconnected);
		const targetId = opts.targetId?.trim() || "";
		if (targetId) await tryTerminateExecutionViaCdp({
			cdpUrl: normalized,
			targetId
		}).catch(() => {});
		cur.browser.close().catch(() => {});
	}
}
/**
* List all pages/tabs from the persistent Playwright connection.
* Used for remote profiles where HTTP-based /json/list is ephemeral.
*/
async function listPagesViaPlaywright(opts) {
	const { browser } = await connectBrowser(opts.cdpUrl);
	const pages = await getAllPages(browser);
	const results = [];
	for (const page of pages) {
		const tid = await pageTargetId(page).catch(() => null);
		if (tid) results.push({
			targetId: tid,
			title: await page.title().catch(() => ""),
			url: page.url(),
			type: "page"
		});
	}
	return results;
}
/**
* Create a new page/tab using the persistent Playwright connection.
* Used for remote profiles where HTTP-based /json/new is ephemeral.
* Returns the new page's targetId and metadata.
*/
async function createPageViaPlaywright(opts) {
	const { browser } = await connectBrowser(opts.cdpUrl);
	const context = browser.contexts()[0] ?? await browser.newContext();
	ensureContextState(context);
	const page = await context.newPage();
	ensurePageState(page);
	const targetUrl = opts.url.trim() || "about:blank";
	if (targetUrl !== "about:blank") await page.goto(targetUrl, { timeout: 3e4 }).catch(() => {});
	const tid = await pageTargetId(page).catch(() => null);
	if (!tid) throw new Error("Failed to get targetId for new page");
	return {
		targetId: tid,
		title: await page.title().catch(() => ""),
		url: page.url(),
		type: "page"
	};
}
/**
* Close a page/tab by targetId using the persistent Playwright connection.
* Used for remote profiles where HTTP-based /json/close is ephemeral.
*/
async function closePageByTargetIdViaPlaywright(opts) {
	const { browser } = await connectBrowser(opts.cdpUrl);
	const page = await findPageByTargetId(browser, opts.targetId, opts.cdpUrl);
	if (!page) throw new Error("tab not found");
	await page.close();
}
/**
* Focus a page/tab by targetId using the persistent Playwright connection.
* Used for remote profiles where HTTP-based /json/activate can be ephemeral.
*/
async function focusPageByTargetIdViaPlaywright(opts) {
	const { browser } = await connectBrowser(opts.cdpUrl);
	const page = await findPageByTargetId(browser, opts.targetId, opts.cdpUrl);
	if (!page) throw new Error("tab not found");
	try {
		await page.bringToFront();
	} catch (err) {
		const session = await page.context().newCDPSession(page);
		try {
			await session.send("Page.bringToFront");
			return;
		} catch {
			throw err;
		} finally {
			await session.detach().catch(() => {});
		}
	}
}

//#endregion
export { ensurePageState as a, getPageForTargetId as c, createSessionsHistoryTool, rememberRoleRefsForTarget as d, restoreRoleRefsForTarget as f, ensureContextState as i, listPagesViaPlaywright as l, closePlaywrightBrowserConnection as n, focusPageByTargetIdViaPlaywright as o, storeRoleRefsForTarget as p, createPageViaPlaywright as r, forceDisconnectPlaywrightForTarget as s, closePageByTargetIdViaPlaywright as t, refLocator as u };