import type { SnapshotStore } from "@oh-my-pi/hashline";
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
import { type Component, Container, type NativeScrollbackLiveRegion, type TUI } from "@oh-my-pi/pi-tui";
/**
 * Transcript-side probe telling a block whether it is still inside the live
 * (repaintable) region. Implemented by `TranscriptContainer`; injected rather
 * than imported so the component stays decoupled from the transcript.
 */
export interface TranscriptLiveRegionProbe {
    isBlockInLiveRegion(component: Component): boolean;
}
export interface ToolExecutionOptions {
    snapshots?: SnapshotStore;
    showImages?: boolean;
    editFuzzyThreshold?: number;
    editAllowFuzzy?: boolean;
    /** Live-region probe used to settle detached task progress once the block
     * leaves the repaintable transcript region. */
    liveRegion?: TranscriptLiveRegionProbe;
}
export interface ToolExecutionHandle extends Component {
    updateArgs(args: any, toolCallId?: string): void;
    updateResult(result: {
        content: Array<{
            type: string;
            text?: string;
            data?: string;
            mimeType?: string;
        }>;
        details?: any;
        isError?: boolean;
    }, isPartial?: boolean, toolCallId?: string): void;
    setArgsComplete(toolCallId?: string): void;
    setExpanded(expanded: boolean): void;
}
/** Redraw live tool blocks at the spinner's glyph-advance rate. Rendering more
 * often produced identical frames — the previous 30fps cadence emitted ~2.4
 * paints per glyph step, and although the terminal I/O layer dedupes those, the
 * compose pipeline still ran end-to-end per frame (issue #4353). Matching the
 * render tick to the glyph tick halves the paints during tool execution with no
 * visible change. */
export declare const SPINNER_RENDER_INTERVAL_MS = 80;
/** Advance the spinner glyph at its classic ~12.5fps step (mirrors `Loader`). */
export declare const SPINNER_GLYPH_ADVANCE_MS = 80;
/** Phase-locked spinner glyph index shared by every live tool block so parallel
 * spinners advance in lockstep instead of each tracking its own start time. */
export declare function sharedSpinnerFrame(frameCount: number, now?: number): number;
/**
 * Component that renders a tool call with its result (updateable)
 */
export declare class ToolExecutionComponent extends Container implements NativeScrollbackLiveRegion {
    #private;
    constructor(toolName: string, args: any, options: ToolExecutionOptions | undefined, tool: AgentTool | undefined, ui: TUI, cwd?: string, _toolCallId?: string);
    updateArgs(args: any, _toolCallId?: string): void;
    /**
     * Signal that args are complete (tool is about to execute).
     * This triggers an immediate final diff computation for edit-like tools.
     */
    setArgsComplete(_toolCallId?: string): void;
    /**
     * Await the streaming diff recompute kicked off by the most recent
     * `updateArgs`/`setArgsComplete`. The recompute reads the file and re-runs the
     * whole-file Myers diff off the render path, signalling completion only via a
     * throttled `requestRender`. Tests await this to sample a *settled* preview
     * deterministically instead of racing the spinner's render ticks.
     */
    whenPreviewSettled(): Promise<void>;
    updateResult(result: {
        content: Array<{
            type: string;
            text?: string;
            data?: string;
            mimeType?: string;
        }>;
        details?: any;
        isError?: boolean;
    }, isPartial?: boolean, _toolCallId?: string): void;
    /**
     * Standalone harnesses may mount a tool component directly under `TUI`
     * instead of inside `TranscriptContainer`. In that shape the component must
     * report its own live-region seam while unfinalized, or the core renderer
     * treats it like shell output and commits still-mutating preview rows to
     * immutable native scrollback before the result replaces them.
     */
    getNativeScrollbackLiveRegionStart(): number | undefined;
    /**
     * Whether this block has reached a terminal state for transcript freezing.
     * Reports `false` while it can still visually change so the
     * {@link TranscriptContainer} keeps it inside the repaintable live region:
     * a foreground tool awaiting its result, or one streaming partial output.
     * A final (non-partial) result, a background-async tool the agent has moved
     * past, or an explicit {@link seal} flips it to `true`.
     */
    isTranscriptBlockFinalized(): boolean;
    /**
     * Mark the tool terminal even though no result arrived (the turn aborted or
     * abandoned it) and stop animating, so it can freeze and stops pinning the
     * transcript live region.
     */
    seal(): void;
    /**
     * Whether this block is a supersedable result snapshot that has not been
     * sealed. Such a block never finalized, so none of its rows entered native
     * scrollback and the whole block can be removed when a follow-up matching
     * tool call supersedes it.
     */
    isDisplaceableBlock(): boolean;
    canBeDisplacedBy(nextToolName: string | undefined): boolean;
    /**
     * Stop spinner animation and cleanup resources.
     */
    stopAnimation(): void;
    setExpanded(expanded: boolean): void;
    setShowImages(show: boolean): void;
    invalidate(): void;
    render(width: number): readonly string[];
}
