/**
 * buildParseSessionFromTui — synthesize a parseSession function from the
 * manifest tui block alone.
 *
 * Composition:
 *   1. detectStatus from tui.spinner/modal/settledPrompt/dispatchOrder
 *      (delegated to buildDetectStatusFromTui)
 *   2. parseApproval from tui.modal (delegated to buildParseApprovalFromTui)
 *   3. message extraction from tui.transcriptPty (this file)
 *
 * The result has the same shape as the legacy parse_output:
 *   { status, messages, activeModal, transcriptAuthority?, coverage?, providerSessionId? }
 *
 * Identity stamping (providerUnitKey, bubbleId, sequence, bubbleState) is
 * applied by the caller, mirroring _shared/parse_session.js. We export the
 * stamper as `normalizeMessageIdentity` for reuse.
 */
import { type ModalTuiSpec } from './parse-approval.js';
export interface PrefixSpec {
    regex: string;
    flags?: string;
}
export interface ToolPrefixSpec extends PrefixSpec {
    skip?: boolean;
}
export interface ChromePatternSpec {
    regex: string;
    flags?: string;
    label?: string;
}
export interface TranscriptPtySpec {
    $schema?: 'adhdev:tui/transcript-pty@1';
    assistantPrefix: PrefixSpec;
    userPrefix?: PrefixSpec;
    toolPrefix?: ToolPrefixSpec;
    continuationLine?: {
        indented?: boolean;
    };
    chromePatterns?: ChromePatternSpec[];
    stripLeadingChrome?: boolean;
    scope?: 'screen' | 'buffer' | 'tail';
    /**
     * Optional SGR background-color codes that mark a USER turn. Some TUIs
     * (cursor-agent) render the user's submitted message and the composer echo
     * inside a colored box but render the assistant answer as a plain line with
     * no background. After ANSI stripping both look like bare 2-space lines, so
     * a bg-less assistant answer and a boxed user echo are indistinguishable by
     * text prefix alone — the user echo then leaks into an assistant bubble.
     * When set, a raw line whose ANSI carries any of these background SGRs (e.g.
     * "48;5;233") is classified as a user turn regardless of its stripped text,
     * so the plain assistant answer is the only assistant bubble left. Matched
     * against the raw pre-strip line; the visible text is still ANSI-stripped
     * for the bubble content.
     *
     * Value-agnostic mode: the sentinel "*" (or "48;*" / "bg") matches ANY
     * background-color SGR — 256-color `48;5;<n>` OR truecolor `48;2;<r>;<g>;<b>`
     * — instead of an allowlist of exact color numbers. This is the robust form:
     * the earlier allowlist bug recurred every time a TUI changed its exact box
     * color (cursor `48;5;233` guess, opencode rc.531), because a hard-coded
     * color that no longer matched let the boxed user echo fall through to the
     * permissive assistantPrefix. The sentinel keys off the *presence* of a
     * background-color param group — the structural signal of a boxed turn —
     * so a genuine assistant line (no background SGR) is still classified
     * assistant. Chrome patterns are filtered BEFORE this check, so bg-colored
     * chrome (e.g. the "→ Add a follow-up" composer footer) is already excluded
     * and does not become a spurious user bubble.
     */
    userBackgroundSgr?: string[];
}
export interface SessionIdExtractionSpec {
    $schema?: 'adhdev:tui/session-id-extraction@1';
    regex: string;
    flags?: string;
    scope?: 'screen' | 'tail' | 'buffer';
    label?: string;
}
export interface ParseSessionTuiSpec {
    spinner?: any;
    settledPrompt?: any;
    modal?: ModalTuiSpec;
    dispatchOrder?: any;
    transcriptPty: TranscriptPtySpec;
    sessionIdExtraction?: SessionIdExtractionSpec;
}
export interface SynthesizedMessage {
    role: 'user' | 'assistant';
    kind?: 'standard' | 'tool';
    content: string;
    receivedAt?: number;
}
export interface SynthesizedSession {
    status: string | null;
    messages: SynthesizedMessage[];
    activeModal: {
        message: string;
        buttons: string[];
    } | null;
    modal: {
        message: string;
        buttons: string[];
    } | null;
    parsedStatus: string | null;
    transcriptAuthority?: 'provider' | 'daemon';
    coverage?: 'full' | 'tail' | 'current-turn';
    providerSessionId?: string;
}
export declare function normalizeMessageIdentity<T extends {
    role?: string;
    kind?: string;
    content?: string;
}>(messages: T[], status: string): Array<T & {
    providerUnitKey: string;
    bubbleId: string;
    sequence: number;
    _turnKey: string;
    bubbleState: 'streaming' | 'final';
}>;
export declare function buildParseSessionFromTui(spec: ParseSessionTuiSpec): (input: any) => SynthesizedSession;
