import { t as findCodeRegions } from "./code-regions-BSt0fAqe.js";
import { n as flattenMarkdownDetails, t as stripInternalRuntimeScaffolding } from "./protocol-scaffolding-DzzlrFF6.js";
//#region src/infra/outbound/sanitize-text.ts
const HTML_TAG_RE = /<\/?[a-z][a-z0-9_.:-]*(?=[\s/>])[^>]*>/gi;
const MAY_CONTAIN_MARKDOWN_CODE_RE = /[`~]|\t| {4}/;
const CODE_ESCAPE = "\0e";
const CODE_PLACEHOLDER = "\0p";
const CONVERTIBLE_HTML_OPEN_TAG_RE = /<(b|strong|i|em|s|strike|del|code|h[1-6]|li)(?=\s|>)(?:[^"'<>]|"[^"]*"|'[^']*')*>/gi;
const EMPTY_HTML_ELEMENT_RE = /<((?!(?:br|p|div)(?=[\s>]))[a-z][a-z0-9_.:-]*)(?=[\s>])(?:[^"'<>]|"[^"]*"|'[^']*')*>(?:[^\S\r\n\u2028\u2029]|<(?!\/?(?:br|p|div)(?=[\s/>]))\/?[a-z][a-z0-9_.:-]*(?=[\s/>])(?:[^"'<>]|"[^"]*"|'[^']*')*>)*<\/\1\s*>/gi;
function removeMatchesUntilStable(text, pattern) {
	let previous;
	let current = text;
	do {
		previous = current;
		current = current.replace(pattern, "");
	} while (current !== previous);
	return current;
}
function convertHtmlOutsideCode(text, options) {
	const boldMarker = options.style === "markdown" ? "**" : "*";
	const strikeMarker = options.style === "markdown" ? "~~" : "~";
	return removeMatchesUntilStable(removeMatchesUntilStable(text.replace(/<((?:https?:\/\/|mailto:)[^<>\s]+)>/gi, "$1").replace(CONVERTIBLE_HTML_OPEN_TAG_RE, "<$1>"), EMPTY_HTML_ELEMENT_RE).replace(/<br\s*\/?>/gi, "\n").replace(/<\/?(p|div)>/gi, "\n").replace(/<(b|strong)>(.*?)<\/\1>/gi, `${boldMarker}$2${boldMarker}`).replace(/<(i|em)>(.*?)<\/\1>/gi, "_$2_").replace(/<(s|strike|del)>(.*?)<\/\1>/gi, `${strikeMarker}$2${strikeMarker}`).replace(/<code>(.*?)<\/code>/gi, "`$1`").replace(/<h[1-6]>(.*?)<\/h[1-6]>/gi, `\n${boldMarker}$1${boldMarker}\n`).replace(/<li>(.*?)<\/li>/gi, "• $1\n"), HTML_TAG_RE).replace(/\n{3,}/g, "\n\n");
}
/**
* Convert common HTML tags to their plain-text/lightweight-markup equivalents
* and strip anything that remains.
*
* The function is intentionally conservative — it only targets tags that models
* are known to produce and avoids false positives on angle brackets in normal
* prose (e.g. `a < b`), in fenced blocks, and in inline code spans.
*/
function sanitizeForPlainText(text, options = {}) {
	const prepared = flattenMarkdownDetails(stripInternalRuntimeScaffolding(text));
	const codeRegions = (prepared.includes("<") || prepared.includes("\n\n\n")) && MAY_CONTAIN_MARKDOWN_CODE_RE.test(prepared) ? findCodeRegions(prepared) : [];
	if (codeRegions.length === 0) return convertHtmlOutsideCode(prepared, options);
	const preservedCode = [];
	let masked = "";
	let cursor = 0;
	for (const region of codeRegions) {
		masked += prepared.slice(cursor, region.start).replaceAll("\0", CODE_ESCAPE);
		masked += CODE_PLACEHOLDER;
		preservedCode.push(prepared.slice(region.start, region.end));
		cursor = region.end;
	}
	masked += prepared.slice(cursor).replaceAll("\0", CODE_ESCAPE);
	const converted = convertHtmlOutsideCode(masked, options);
	let restored = "";
	cursor = 0;
	for (const code of preservedCode) {
		const placeholder = converted.indexOf(CODE_PLACEHOLDER, cursor);
		restored += converted.slice(cursor, placeholder).replaceAll(CODE_ESCAPE, "\0");
		restored += code;
		cursor = placeholder + 2;
	}
	return restored + converted.slice(cursor).replaceAll(CODE_ESCAPE, "\0");
}
//#endregion
export { sanitizeForPlainText as t };
