/**
 * findings/answerText — the ONE reader of the reserved key in an answer's
 * TEXT (9.114.2).
 *
 * Pattern: an incremental scanner — a character state machine with no scope
 *          and no I/O, fed chunk by chunk (`reservedMemberFilter`) or whole
 *          (`withoutReservedMembers`), with the same bytes out either way.
 * Role:    core/ layer leaf. `stages/callLLM.ts` feeds it the provider's
 *          stream under the arm, so `agentfootprint.stream.token` never
 *          carries the model's notes; `peel.ts · peelAnswerFindings` feeds
 *          it the whole answer, so the answer the run returns is exactly the
 *          text the stream showed.
 *
 * THE RULE
 *   Every JSON object written in the text — the whole answer, one in a code
 *   block, one in the prose, one in a list — loses its own `_findings` member:
 *   the key, the value and the separator that joined it to its neighbours,
 *   and nothing else. A `_findings` inside another object's VALUE is data and
 *   stays. Each removed value is handed back (`removed`), as written, for the
 *   peel to read as the answer's declaration.
 *
 *   - An object left with nothing in it goes whole — its line too — when it
 *     stood on a line of its own outside any list: the whole answer, a
 *     paragraph of its own, a code block of its own. A code block left empty
 *     goes with its fences. The removed line's indentation and the whole
 *     blank lines after it go; the next line keeps its own indentation. No
 *     blank lines are left at either end of the text. The whole answer, left with nothing, is `{}` (a JSON answer stays
 *     JSON). Anywhere else an emptied object stays as `{}`, so the JSON or
 *     code around it keeps its shape. A string inside a list is read as a
 *     string, so a `]` or `{` in it neither ends the list nor opens an object.
 *   - An answer that held nothing but notes — a code block of them, or
 *     several objects of them — is left empty; only an answer that was one
 *     bare JSON object becomes `{}`.
 *   - Text that stops being JSON part way (`{see below}`, a stray quote or a
 *     raw line break inside a `_findings` value) is given back exactly as it
 *     was written; nothing is removed from it except a `_findings` member
 *     that was already complete. An object that held nothing but such
 *     complete notes when the text stopped being JSON (a model one closing
 *     brace short) ends there, and goes as an emptied object does. Keys and
 *     values are read by JSON's own grammar (`JsonValue`), so the first
 *     character JSON cannot take decides it — not a count of brackets, which
 *     prose may never balance.
 *   - Text that ends inside a `_findings` value that is JSON so far (a
 *     cut-off stream) keeps it hidden and reports it `complete: false`.
 *   - Nothing removed ⇒ the text comes back byte for byte, whatever the
 *     chunking. What is held back while undecided is bounded by a line:
 *     whitespace, a key (a raw line break ends one — JSON allows none), `{`
 *     until its first key is read, a separator, a code fence line, the rest
 *     of an emptied object's line. The one exception is a `_findings` value:
 *     it is never shown while it is JSON so far, and one that stops being
 *     JSON is held until the character that breaks it and then given back as
 *     written — so that hold can span as many lines as the notes do.
 */
/** One `_findings` member the scanner took out of the text. */
export interface RemovedMember {
    /** Which object in the text held it, counted from 0 in text order. */
    readonly object: number;
    /** The member's value exactly as written — cut short when the text ended inside it. */
    readonly valueText: string;
    /** False when the text ended before the value did. */
    readonly complete: boolean;
}
/** The scanner, fed piece by piece. */
export interface ReservedMemberFilter {
    /** Feed the next piece of text; returns what can be shown now. */
    push(chunk: string): string;
    /** No more text: returns what was held back. After it, every call returns `''`. */
    end(): string;
    /** Every member removed so far, in text order. */
    readonly removed: readonly RemovedMember[];
}
/** A fresh scanner for one text (one provider call's content). */
export declare function reservedMemberFilter(key?: string): ReservedMemberFilter;
/** The whole-text form: the text without its reserved members, and what was removed. */
export declare function withoutReservedMembers(text: string, key?: string): {
    readonly text: string;
    readonly removed: readonly RemovedMember[];
};
