/**
 * Trust boundary for catalog data leaving the MCP server.
 *
 * Everything this server returns about an extension was written by somebody
 * else: the store listing and manifest by the extension's author, the review
 * text by arbitrary store users, and finding titles by our own scanners and by
 * an LLM that read the extension's code in order to describe it. All of it
 * lands directly in an AI client's context window, next to that client's tools.
 *
 * That is the second-order half of the injection problem. The scanning pipeline
 * defends its own LLM call (`llm_analysis_adapter._render_prompt`), but the
 * finding it produces is then read back out by a different agent — one that,
 * unlike the scanner, usually has a shell. A sentence planted in an extension
 * description that survives all the way into `get_reviews` output is the only
 * path in this system that runs from "text in a stranger's package" to "command
 * on a developer's machine".
 *
 * Two things travel with every catalog payload:
 *
 *   1. `_notice` — states, in the payload itself, that these strings are data.
 *      An instruction is the only thing that defends against readable text
 *      asking the reader to act on it, and it has to arrive WITH the data
 *      rather than in documentation the agent never reads.
 *   2. `defangDeep` — removes what JSON encoding does not. `JSON.stringify`
 *      escapes quotes, backslashes and control characters, so nothing here can
 *      break out of the string it sits in; it does NOT touch zero-width or
 *      bidi codepoints (invisible to whoever reads the transcript afterwards,
 *      ordinary text to a tokenizer) or backtick runs (which close the markdown
 *      fence a client renders the result in).
 *
 * Content is preserved, never deleted. An extension whose description tries to
 * steer an automated reader is worth seeing and reporting; a filter that
 * silently removed the attempt would hide exactly the thing worth knowing.
 *
 * Mirrors `_defang_untrusted_text` / `_defang_envelope` in
 * `dags/src/dags/scanners/llm_analysis_adapter.py`. Nothing can import across
 * that boundary — one side is Python in the pipeline, the other TypeScript in a
 * published npm package — so the two are kept in step by
 * `untrusted.test.ts::parity` rather than by a shared module.
 */
/**
 * C0/C1 control characters are deliberately NOT stripped here, and this differs
 * on purpose from `sanitizeThirdPartyLabel` in @extenshi/cli, which does strip
 * them (`CONTROL_RE`).
 *
 * The two paths have different sinks. Everything here is serialised by
 * `JSON.stringify`, which encodes control characters as escape sequences, so
 * they arrive as visible text rather than as terminal commands — and these
 * payloads are prose a reader has to read, so flattening them would cost
 * evidence for no gain. The CLI prints names straight to a terminal through
 * chalk with no encoding in between, where an ESC sequence is executed.
 *
 * So: do not "fix" the omission here, and do not copy this approach into the
 * CLI. The first would make descriptions unreadable; the second would reopen a
 * terminal-injection gap.
 */
export declare const UNTRUSTED_NOTICE: string;
/** Neutralise what JSON encoding misses, without removing content. */
export declare function defangUntrusted(text: string, maxLength?: number): string;
/** Apply `defangUntrusted` to every string in a payload. Keys are ours. */
export declare function defangDeep<T>(value: T): T;
/**
 * Serialise a catalog payload for an MCP tool result.
 *
 * `_notice` is added as a field rather than as a prefix line so the result stays
 * a single parseable JSON object — `@extenshi/mcp` is published, and a consumer
 * doing `JSON.parse` on the tool result must keep working. The addition is
 * additive for anyone reading named fields.
 */
export declare function renderCatalogPayload(payload: unknown): string;
//# sourceMappingURL=untrusted.d.ts.map