/** Shared types — one file, pi style. */ import type { TSchema, Static } from "typebox"; /** The fixed tool surface. Same three names on every platform and strategy. */ export declare const TOOL_NAMES: readonly ["gui_targets", "gui_observe", "gui_act"]; export interface ToolResult { content: Array<{ type: "text"; text: string; } | { type: "image"; data: string; mimeType: string; }>; details: Record; } /** One tool. `promptSnippet`/`promptGuidelines` feed the pi system prompt in extension * mode; hosts like Claude Code only see `description`. */ export interface GuiToolSpec { name: string; label: string; description: string; promptSnippet: string; promptGuidelines?: string[]; parameters: T; execute(params: Static): Promise; } /** Erase the schema generic so specs can live in one array. */ export declare function spec(s: GuiToolSpec): GuiToolSpec; /** * The surface the agent was driving is GONE and must not be recreated — the user closed the * browser window, or the device went away. Distinct from an ordinary failure: there is * nothing to retry and nothing to re-observe, so the tool answers with a stop instruction * instead of a reason to try again. Replacing the surface behind the user's back would fight * them and hide the fact from the model, which is how a closed window turned into a new one. */ export declare class SurfaceGoneError extends Error { readonly surfaceGone = true; } export declare function text(t: string, details?: Record): ToolResult; /** How observations ground actions: text element refs, screenshot coordinates, or both. */ export type Strategy = "tree" | "pixels" | "hybrid"; /** An operable surface: tab, window, app (device later). Ids are stable for the * session — unlike element refs, which are re-minted on every observation. */ export interface TargetInfo { id: string; kind: "tab" | "window" | "app" | "device"; title: string; active: boolean; } /** An extra verb a driver adds to gui_act (e.g. open_url, swipe, ax_action). * The schema is one full branch of the action union, including a literal `kind`. */ export interface VerbSpec { kind: string; schema: TSchema; } export interface Element { ref: string; role: string; name: string; state: string; rect: { x: number; y: number; w: number; h: number; }; } export interface Snapshot { url: string; title: string; elements: Element[]; text: string; meta: { scrollY: number; viewportH: number; docH: number; }; } /** One atomic platform observation. Drivers whose platform returns structure and * pixels from the same capture provide both here, so a hybrid observation never * invalidates its own element refs by taking a second screenshot. */ export interface SnapshotCapture { snapshot: Snapshot; image?: { bytes: Buffer; mimeType: string; }; } /** Result of comparing two consecutive observations — the effect-evidence ring. */ export type Verdict = "changed" | "frozen" | "unknown"; export interface ActResult { /** Whether the action was dispatched. Not a claim about its effect — that is the observation's job. */ ok: boolean; note?: string; } /** How the context engine prunes gui tool results for a given strategy. */ export interface ContextPolicy { /** Keep this many recent gui tool results verbatim; older ones are reduced to stubs. */ keepRecentObservations: number; /** Keep at most this many recent images; older ones become text placeholders. */ keepImages: number; }