export type PauseRec = Record; export interface PauseRect { x: number; y: number; width: number; height: number; } /** Where a run stopped / continues: batch step, then stroke / point / frac inside a path (contract ComputerResumePoint). */ export interface PausePosition { step?: number; stroke?: number; point?: number; frac?: number; } /** How far a cancelled path / drag got, as the helper reports it (contract ComputerPathProgress). */ export interface PauseProgress { stroke?: number; point?: number; frac?: number; pressed?: boolean; } /** What the pauses of one command did (contract ComputerPauseReport). */ export interface PauseReport { count: number; pausedMs: number; refocused?: number; moved?: boolean; resumedStrokes?: number; } /** The part of a ComputerResult the engine reads. */ export interface PauseResult { ok: boolean; kind?: string; text?: string; error?: { code?: string; message?: string; }; [k: string]: unknown; } export interface PauseWindow { windowId: string; appId?: string; title?: string; bounds: PauseRect; focused?: boolean; minimized?: boolean; } export declare const PAUSE_DEFAULTS: { /** The user must be idle this long before the run goes on. */ readonly quietMs: 1500; /** One pause lasts at most this long; then the run stops with user_interrupted and a resume point. */ readonly maxPauseMs: 60000; /** Pause time the server grants per command on top of its deadline. */ readonly budgetMs: 180000; /** A step interrupted more often than this stops (the user keeps taking over). */ readonly maxResumesPerStep: 20; /** Time kept back before the deadline: a pause ends in time to report where it stopped. */ readonly reserveMs: 1500; }; /** Reads that send no input: they run while the user is busy. Everything else waits until the user is idle. */ export declare const PAUSE_PASSIVE_KINDS: ReadonlySet; /** Pointer streams cancelled the moment the user takes over (never fight for the cursor); short atomic writes finish. */ export declare const PAUSE_CANCEL_KINDS: ReadonlySet; export declare function pauseNeedsIdle(kind: string): boolean; export declare function pauseRectMoved(a: PauseRect, b: PauseRect, tol?: number): boolean; export declare function pauseRectResized(a: PauseRect, b: PauseRect, tol?: number): boolean; type PausePt = number[]; /** * The rest of one stroke from (point, frac): it starts on the last sample the pointer reached (pressed again there, * one sample of overlap, no gap, nothing drawn twice beyond it), then every later point; times are shifted to start at * 0. null when nothing is left (the stroke had reached its last point). */ export declare function pauseTrimStroke(stroke: PausePt[], point: number, frac: number): PausePt[] | null; /** A path from a position (strokes before `stroke` are done, that stroke goes on from point / frac); null when nothing is left. */ export declare function pauseTrimPath(action: PauseRec, pos: PausePosition): PauseRec | null; /** * The helper's progress on a path that was itself cut at `base`, as a position in the ORIGINAL path. The cut path's * point 0 is the re-pressed sample on base segment (point -> point + 1); its point k >= 1 is base point + k. */ export declare function pauseAbsolute(base: PausePosition, rel: PauseProgress): PausePosition; /** A resumeFrom as a position (step, stroke, point: whole numbers >= 0; frac in 0..1); null when absent. */ export declare function pausePositionOf(v: unknown): PausePosition | null; /** * A window / region path moved with its window (same size only: a canvas does not scale with its window, so a resized * window stops the run). null when it cannot follow (screen pixels, or resized). */ export declare function pauseShiftPath(action: PauseRec, from: PauseRect, to: PauseRect): PauseRec | null; /** * One step after its window moved from `from` to `to`: window / region paths move with it; points in screen pixels * and refs bound to a screen taken before the move cannot follow (null: stop there); a label is found again (its * snapshot binding is dropped). Steps on other windows, or without coordinates, are unchanged. */ export declare function pauseShiftStep(step: PauseRec, from: PauseRect, to: PauseRect): PauseRec | null; export type PauseStopReason = "stopped" | "max_pause" | "deadline" | "window_closed" | "dialog" | "moved" | "refocus" | "repress" | "dropped" | "unknown_progress" | "stale" | "too_many"; export interface PauseStop { reason: PauseStopReason; message: string; /** Inside a path: where it stopped (stroke / point / frac in the step's original strokes). */ at?: PausePosition; } /** What the executor needs from its host. Every command goes through `exec` (the host's own checks apply). */ export interface PauseHost { now(): number; sleep(ms: number): Promise; /** Runs one helper command (never batch / handoff / keep_awake) and resolves with its result, cancelled or not. */ exec(action: PauseRec, id: string): Promise; /** Cancels one running command for a pause; its (stopped) result, with `progress`, still resolves `exec`. */ cancel(id: string): void; /** Releases every key and mouse button the helper holds. */ release(): void; /** The command was answered elsewhere (Stop, the deadline, the app closing): stop waiting, act on nothing. */ ended(): boolean; /** Time left before the command's deadline (ms). */ timeLeft(): number; /** Pushes the deadline back by up to `ms` from the pause budget (negative: gives time back); returns what moved. */ extend(ms: number): number; /** Time of the last real user input the host saw (0: none). */ lastInputAt(): number; /** The helper refused because someone is using the computer: start a new quiet period from now. */ markInput(): void; /** Shows / hides "Paused while you use the computer". */ overlay(paused: boolean): void; quietMs: number; maxPauseMs: number; } /** State of one command that may pause (a single action, or every step of a batch). */ export declare class PauseRun { count: number; pausedMs: number; refocused: number; moved: boolean; resumedStrokes: number; /** Keys (hold_key) and buttons (mouse down) the run holds; released at a pause, pressed again before going on. */ readonly keys: Map; readonly buttons: Set; pointer: { x: number; y: number; } | null; /** The run's window (the last result's `current`). */ windowId: string | null; /** Windows that moved during a pause: where they were first, where they are now. */ readonly shifts: Map; current: { id: string; kind: string; } | null; readonly cancelled: Set; /** The user took over since the last pause: the next step that sends input pauses first. */ interrupted: boolean; holds(): boolean; /** Real user input: cancel a pointer stream now, let go of what the run holds; the next step pauses. */ onUserInput(host: Pick): void; /** What a finished step left held, where the pointer is, which window the run is in. */ track(action: PauseRec, r: PauseResult): void; report(): PauseReport | undefined; /** A step as it must run now: moved with its window if that window moved during an earlier pause (null: it cannot). */ adapt(step: PauseRec): PauseRec | null; } /** One line for a result that paused: how often, how long, what was done to go on. */ export declare function pauseReportText(r: PauseReport | undefined): string; /** The message of a run that stopped: why, where, and how to continue (resume_from). */ export declare function pauseStopText(stop: PauseStop, where: string, resume: PausePosition): string; /** * One step that pauses for the user instead of failing. Before a step that sends input, it waits while the user is * busy; a pointer stream the user interrupted goes on from where it was (a path from its last sample, a drag from * its start if nothing was picked up, a move / hover / mouse step again). `start`: a path's resume position. * Returns the step's result, or `stop` when the run cannot go on safely (the caller answers user_interrupted). */ export declare function pauseRunStep(host: PauseHost, run: PauseRun, step: PauseRec, id: string, start?: PausePosition | null): Promise<{ result: PauseResult; } | { stop: PauseStop; }>; export {};