/**
 * UI Bridge Native Server Types
 *
 * Types for the embedded HTTP server.
 */
import type { NativeUIBridgeConfig, NativeActionResponse, NativeFindResponse, NativeBridgeSnapshot } from '../core/types';
import type { ComponentActionResponse, PageNavigationResponse } from '../control/types';
import type { ElementDesignData, StateStyles, ResponsiveSnapshot } from '../design/design-types';
/**
 * Navigation provider for React Native apps.
 *
 * Apps supply this to enable programmatic navigation via the UI Bridge
 * (e.g., `control/page/navigate` and `control/page/back`).
 * For Expo Router: pass `router.push` and `router.back`.
 */
export interface NavigationProvider {
    navigate: (url: string) => void;
    back?: () => void;
    /** Replace current route (no back-stack entry). For Expo Router: router.replace */
    replace?: (url: string) => void;
    /** Refresh the current route. For Expo Router: router.replace(currentPath) */
    refresh?: () => void;
}
/**
 * Screenshot provider for React Native apps.
 *
 * Apps supply this to enable screen capture via the UI Bridge
 * (`control/screenshot`). For react-native-view-shot: pass a function
 * that calls `captureRef` on the root view and returns base64 PNG data.
 */
export interface ScreenshotProvider {
    /** Capture the current screen and return base64-encoded PNG data (no data: prefix). */
    capture: () => Promise<{
        base64: string;
        width: number;
        height: number;
    }>;
}
/** Device keep-awake capability, injected by the host app (expo-keep-awake is mobile-only). */
export interface KeepAwakeProvider {
    request(source: string, durationMs?: number): void;
    release(source: string): void;
}
/**
 * Route provider for React Native apps.
 *
 * Apps supply this to expose the current navigation route in UI Bridge snapshots.
 * For Expo Router: render a RouteTracker component inside the router context that
 * calls `usePathname()` / `useSegments()` and writes the result to a module-level ref.
 */
export interface RouteProvider {
    /** Return the current route path (e.g. "/(tabs)/runs"), or null if unknown. */
    getCurrentRoute: () => string | null;
    /** Return the current route segments (e.g. ["(tabs)", "runs"]), if available. */
    getSegments?: () => string[];
    /**
     * Subscribe to route changes. Required so the UI Bridge can clear stale
     * layouts on route changes with zero lag.
     *
     * Implementers must invoke `listener` synchronously whenever the route
     * changes, passing the new route (or null if unknown). The returned function
     * must unsubscribe the listener.
     *
     * For Expo Router: wrap your RouteTracker component in a module-level
     * listener set and call each listener from within the tracker's effect.
     */
    subscribe: (listener: (route: string | null) => void) => () => void;
}
/**
 * Server configuration
 */
export interface NativeServerConfig extends NativeUIBridgeConfig {
    /** Enable CORS */
    cors?: boolean;
    /** Allowed origins for CORS */
    allowedOrigins?: string[];
    /**
     * Enable test-only HTTP endpoints (currently `control/modal/push` and
     * `control/modal/dismiss/:id`) so external runners can drive registry
     * state. Default `false`; the React provider mirrors
     * `features.testHooks` into this slot.
     */
    testHooks?: boolean;
    /**
     * Enable the read-only observability capture (console.error/warn +
     * fetch/XHR ring buffers backing `GET /control/console-errors` and
     * `GET /sdk/network-requests`). When omitted, falls back to the
     * `testHooks` value so existing consumers are unchanged; set explicitly
     * to decouple release-build capture from the testHooks-gated control
     * surface. The React provider mirrors `features.observability` into
     * this slot.
     */
    observability?: boolean;
    /**
     * Viewport getter for `POST /control/page-health`.
     *
     * Injected by `UIBridgeNativeProvider` from `Dimensions.get('window')`.
     * Lives at config-injection level because importing react-native from
     * `handlers.ts` (or even `require('react-native')` with try/catch) crashed
     * the host RN app in 0.6.3/0.6.4: Metro/Hermes raised
     * `unknownModuleError` past every local try/catch and tore down the JS
     * thread (blank screen, React tree destroyed). The provider already has
     * a live import of `react-native`, so it's the safe injection point.
     *
     * When absent: `page-health` falls back to `body.viewport`, then `{0,0}`
     * (degenerate coverage report — no crash).
     */
    viewportProvider?: () => {
        width: number;
        height: number;
    };
}
/**
 * Route definition
 */
export interface RouteDefinition {
    method: 'GET' | 'POST' | 'PUT' | 'DELETE';
    path: string;
    description: string;
}
/**
 * All UI Bridge Native routes
 */
export declare const UI_BRIDGE_NATIVE_ROUTES: Record<string, RouteDefinition>;
/**
 * Request body for `POST /ai/fill-form`.
 *
 * The mobile native bridge has no `setValue` action — text inputs are driven
 * via the `type` action (which calls `onChangeText`). The fillForm handler
 * dispatches each field as `executor.executeAction(elementId, { action: 'type',
 * params: { text: value, clear: true } })` so existing values are atomically
 * replaced (matching the web bridge's "setValue" semantics).
 *
 * Shape mirrors the runner's `POST /ui-bridge/ai/fill-form` documented in
 * docs-site/api/runner-features.md (array-of-pairs form), so callers can use
 * the same JSON across mobile and web/runner without special-casing.
 */
export interface FillFormFieldInput {
    /** Target element id (registered id, testID, accessibilityLabel, etc.) */
    elementId: string;
    /** Text value to write into the input. */
    value: string;
}
export interface FillFormRequest {
    fields: FillFormFieldInput[];
}
/**
 * Per-field outcome returned by `POST /ai/fill-form`.
 */
export interface FillFormFieldResult {
    /** Element id from the request, echoed back. */
    elementId: string;
    /** Whether `executor.executeAction` reported success for this field. */
    success: boolean;
    /** Error message when `success === false`. Omitted on success. */
    error?: string;
}
/**
 * Response payload returned in `APIResponse.data` for `POST /ai/fill-form`.
 */
export interface FillFormResponse {
    results: FillFormFieldResult[];
    succeededCount: number;
    failedCount: number;
}
/**
 * Request body for `POST /control/tap` — synthesize a press at given screen
 * coordinates by searching registered elements whose layout rect contains the
 * point.
 *
 * The handler picks the topmost (smallest-area) match — usually the innermost
 * child — then dispatches the requested action via the standard executor.
 * `action` defaults to `'press'`.
 */
export interface TapAtRequest {
    x: number;
    y: number;
    action?: 'press' | 'longPress' | 'doubleTap';
}
/**
 * Response payload returned in `APIResponse.data` for `POST /control/tap`.
 */
export interface TapAtResponse {
    /** Element id whose rect contained the tap coords. */
    elementId: string;
    /** Action that was dispatched. */
    action: 'press' | 'longPress' | 'doubleTap';
    /** The element's layout rect at dispatch time (best-effort). */
    layout: {
        x: number;
        y: number;
        width: number;
        height: number;
        pageX?: number;
        pageY?: number;
    } | null;
}
/**
 * Single console error/warn entry captured by the observability ring buffer.
 * Returned by `GET /control/console-errors`.
 */
export interface ConsoleErrorEntry {
    /** ms since epoch when the entry was captured. */
    timestamp: number;
    /** `'error'` or `'warn'`. */
    level: 'error' | 'warn';
    /** Joined message string (matches what console would have printed). */
    message: string;
    /** Captured stack trace if any of the args was an Error. */
    stack?: string;
}
/**
 * Response payload for `GET /control/console-errors`.
 */
export interface ConsoleErrorsResponse {
    entries: ConsoleErrorEntry[];
    /** Number of entries returned (post `since`/`limit` filtering). */
    count: number;
    /** Total entries currently held in the ring buffer (pre-filter). */
    bufferSize: number;
    /**
     * Whether the console capture patch is actively installed. `false` means
     * the endpoint is mounted and schema-valid but not observing — typically
     * because `features.testHooks` is off (production builds don't patch
     * `console.error`/`console.warn`). When `false`, `entries` is always empty.
     */
    installed: boolean;
}
/**
 * Single network request entry captured by the observability ring buffer.
 * Returned by `GET /sdk/network-requests`.
 */
export interface NetworkRequestEntry {
    /** ms since epoch at request start. */
    timestamp: number;
    /** HTTP method (uppercased). */
    method: string;
    /** Resolved request URL. */
    url: string;
    /** HTTP status code, or 0 if the request errored before a response. */
    status: number;
    /** Wall-clock duration in ms from start to settlement. */
    durationMs: number;
    /** Whether the request settled with a 2xx response. */
    ok: boolean;
    /** Error message when the request rejected before a response. */
    error?: string;
}
/**
 * Response payload for `GET /sdk/network-requests`.
 */
export interface NetworkRequestsResponse {
    entries: NetworkRequestEntry[];
    count: number;
    bufferSize: number;
    /**
     * Whether the network capture patch is actively installed. `false` means
     * the endpoint is mounted and schema-valid but not observing — typically
     * because `features.testHooks` is off (production builds don't patch
     * `fetch`/`XMLHttpRequest`). When `false`, `entries` is always empty.
     */
    installed: boolean;
}
/**
 * Request body for `POST /control/modal/push`.
 *
 * Mirrors `ModalDetector.pushModal`'s `ModalPushInput` shape; `metadata` is
 * a free-form object the test runner can stash for later assertions but is
 * not currently surfaced in the snapshot.
 */
export interface PushModalRequest {
    id: string;
    title?: string;
    type?: string;
    blocking?: boolean;
    dismissible?: boolean;
    metadata?: Record<string, unknown>;
}
/**
 * Response payload for `POST /control/modal/push`.
 */
export interface PushModalResponse {
    pushed: boolean;
    id: string;
    title?: string;
    type?: string;
    blocking?: boolean;
    dismissible?: boolean;
    pushedAt: number;
}
/**
 * Response payload for `POST /control/modal/dismiss/:id`.
 */
export interface DismissModalResponse {
    dismissed: string;
}
/**
 * API response wrapper
 */
export interface APIResponse<T = unknown> {
    success: boolean;
    data?: T;
    error?: string;
    code?: string;
    timestamp: number;
}
/**
 * Handler context
 */
export interface HandlerContext {
    params: Record<string, string>;
    query: Record<string, string>;
    body: unknown;
}
/**
 * Handler function type
 */
export type HandlerFunction<T = unknown> = (context: HandlerContext) => Promise<APIResponse<T>>;
/**
 * Server handlers interface
 */
export interface NativeServerHandlers {
    getElements: HandlerFunction<{
        elements: unknown[];
    }>;
    getElement: HandlerFunction<{
        element: unknown;
    }>;
    getElementState: HandlerFunction<{
        state: unknown;
    }>;
    executeAction: HandlerFunction<NativeActionResponse>;
    getComponents: HandlerFunction<{
        components: unknown[];
    }>;
    getComponent: HandlerFunction<{
        component: unknown;
    }>;
    executeComponentAction: HandlerFunction<ComponentActionResponse>;
    find: HandlerFunction<NativeFindResponse>;
    getSnapshot: HandlerFunction<NativeBridgeSnapshot>;
    getPageHealth: HandlerFunction<unknown>;
    getWorkflows: HandlerFunction<{
        workflows: unknown[];
    }>;
    runWorkflow: HandlerFunction<{
        runId: string;
        status: string;
        steps: Array<{
            stepId: string;
            type: string;
            status: string;
            result?: unknown;
            error?: string;
            durationMs: number;
        }>;
        totalSteps: number;
        completedSteps: number;
        failedSteps: number;
        skippedSteps: number;
        durationMs: number;
    }>;
    pageRefresh: HandlerFunction<PageNavigationResponse>;
    pageNavigate: HandlerFunction<PageNavigationResponse>;
    pageReplace: HandlerFunction<PageNavigationResponse>;
    pageGoBack: HandlerFunction<PageNavigationResponse>;
    pageGoForward: HandlerFunction<PageNavigationResponse>;
    getScreenshot: HandlerFunction<{
        screenshot: string;
        width: number;
        height: number;
    }>;
    getElementStyles: HandlerFunction<ElementDesignData>;
    getElementStateStyles: HandlerFunction<{
        elementId: string;
        stateStyles: StateStyles[];
    }>;
    getDesignSnapshot: HandlerFunction<{
        elements: ElementDesignData[];
        timestamp: number;
    }>;
    getResponsiveSnapshots: HandlerFunction<ResponsiveSnapshot[]>;
    runDesignAudit: HandlerFunction<unknown>;
    loadStyleGuide: HandlerFunction<{
        loaded: boolean;
    }>;
    getStyleGuide: HandlerFunction<unknown>;
    clearStyleGuide: HandlerFunction<{
        cleared: boolean;
    }>;
    evaluateQuality: HandlerFunction<unknown>;
    getQualityContexts: HandlerFunction<Array<{
        name: string;
        description: string;
    }>>;
    saveBaseline: HandlerFunction<{
        saved: boolean;
        elementCount: number;
    }>;
    diffBaseline: HandlerFunction<unknown>;
    getMethods: HandlerFunction<{
        methods: Array<{
            method: string;
            httpMethods?: string[];
            description?: string;
        }>;
    }>;
    fillForm: HandlerFunction<FillFormResponse>;
    clickByText: HandlerFunction<{
        clicked: boolean;
        element?: unknown;
    }>;
    clickBySelector: HandlerFunction<never>;
    typeInto: HandlerFunction<{
        typed: boolean;
        element?: unknown;
    }>;
    readValue: HandlerFunction<never>;
    findByText: HandlerFunction<Array<{
        index: number;
        id: string;
        type: string;
        label?: string;
    }>>;
    aiForms: HandlerFunction<never>;
    aiIdleStatus: HandlerFunction<never>;
    aiChangeBufferEnable: HandlerFunction<never>;
    aiWaitForElement: HandlerFunction<never>;
    tapAt: HandlerFunction<TapAtResponse>;
    getConsoleErrors: HandlerFunction<ConsoleErrorsResponse>;
    getNetworkRequests: HandlerFunction<NetworkRequestsResponse>;
    pushModal: HandlerFunction<PushModalResponse>;
    dismissModal: HandlerFunction<DismissModalResponse>;
    keepAwake: HandlerFunction<{
        enabled: boolean;
        durationMs: number | null;
    }>;
    health: HandlerFunction<Record<string, unknown>>;
}
//# sourceMappingURL=types.d.ts.map