/** * Sanitize untrusted text before any LLM sees it. * * Always runs Layer 1 (invisible-char + ANSI stripping, lone-surrogate * normalization). When `html` is true, also lazy-loads the HTML layer to splice * out human-invisible HTML (comments, hidden elements — Layer 2) and detect * data-exfil-shaped URLs (Layer 3); the heavy remark/rehype dependency is only * imported on that path. The exfil scan runs on the pre-splice text so a beacon * URL hidden inside a `display:none` element is still reported, not buried by * its own removal. * * `found` names the categories neutralized; `warnings` carries the * operator-facing notices. `cleaned` is always a string, and a change only * ever carries a warning (no silent suppression). `options` is optional and * tolerates an explicit `null`/`undefined` (treated the same as omitted) — * only a genuinely malformed `text` (not a string) throws, deliberately: a * caller passing the wrong TYPE for `text` gets a clear, named error instead * of an internal TypeError leaking implementation details (or a silent, wrong * coercion of e.g. a number to a string). * @param {string} text * @param {{ html?: boolean } | null} [options] * @returns {Promise<{ cleaned: string, found: string[], warnings: string[] }>} */ export function sanitize(text: string, options?: { html?: boolean; } | null): Promise<{ cleaned: string; found: string[]; warnings: string[]; }>; export { applyLayer1, stripAnsiFully, LONE_SURROGATE_RE } from "./layer1.mjs"; export { stripInvisible, stripInvisibleWithReport, isSgrOnly, STRIP, SGR_RE, CHECKS, CATEGORY, CATEGORY_LABELS, LINGUISTIC_SCRIPTS, VS, BLANK_NON_CF, LONG_RUN_RE, LONG_RUN_THRESHOLD, SCATTERED_THRESHOLD } from "./invisible.mjs"; export { HTML_TAG_PRESENT, MD_LINK_HINT, SECRET_HINT, SECRET_HINT_EXT, matchesSecretHint } from "./gates.mjs";