/**
 * Sandboxed generated UI: a catalog component whose props are HTML, CSS and JavaScript the model
 * writes for a one-off interactive answer (a calculator, a small simulation, a bespoke chart) when
 * no catalog component fits. Opt-in — add {@link Sandbox} (or {@link defineSandbox}`({ … })`) to a
 * catalog, or pass `sandbox: true` to `genui({ … })`.
 *
 * Everything here is framework-free and isomorphic: the server uses the definition (description,
 * schema, text fallback, streaming trim), the browser renderer uses the same policy to build the
 * iframe document and to check what the frame sends back.
 */
import { type ComponentDefinition } from './catalog.js';
import { type SandboxKitDocs } from './sandbox-kit.js';
/** The component name the builtin {@link Sandbox} registers under. */
export declare const SANDBOX_COMPONENT = "Sandbox";
/** The props a model writes, in the order it writes them (see {@link SANDBOX_FIELD_ORDER}). */
export interface SandboxProps {
    /** Height in CSS pixels to reserve while the code streams. The frame then sizes to its content. */
    initialHeight?: number;
    /** Short lines shown in the placeholder while the code streams ("Setting up the calculator…"). */
    placeholderMessages?: string[];
    /** A short title, for the frame's accessible name and for text-only clients. */
    title?: string;
    /** One or two sentences on what the view shows — what a client that cannot run it prints. */
    summary?: string;
    /** Styles, injected in a `<style>` before the HTML. */
    css?: string;
    /** The body markup. No `<script src>` (no network); inline `<script>` runs once the view is live. */
    html?: string;
    /** Function declarations, run once as one classic script after the HTML. */
    jsFunctions?: string;
    /** Statements run in order after `jsFunctions`, each as its own classic script (no top-level await). */
    jsExpressions?: string[];
    /**
     * The view as JSX using the app's kit (`sandbox({ kit })`): plain JavaScript + JSX defining
     * `function App()`, compiled and rendered in the frame. Drawn as it streams, once it parses.
     */
    jsx?: string;
}
/**
 * The order the fields stream in, and the order the renderer uses them: a placeholder of the right
 * height first, then the styles (so the markup never draws unstyled), the markup, and the behavior
 * last — the same sequence as CopilotKit's Open Generative UI.
 */
export declare const SANDBOX_FIELD_ORDER: readonly ['initialHeight', 'placeholderMessages', 'title', 'summary', 'css', 'html', 'jsFunctions', 'jsExpressions', 'jsx'];
/**
 * Who the sandbox may reach and how much it may send back. The DEFAULT IS NO NETWORK AT ALL: no
 * fetch, no external script, style, font, image or media — only inline code and `data:`/`blob:`
 * URLs. List origins (`https://tile.openstreetmap.org`, or `https://*.tile.openstreetmap.org`) per
 * kind to open exactly those.
 */
export interface SandboxPolicy {
    allow?: {
        /** `img-src` (map tiles, photos). */
        images?: readonly string[];
        /** `connect-src` (`fetch`, `XMLHttpRequest`, `WebSocket`). */
        connect?: readonly string[];
        /** `script-src` (a charting library from a CDN). */
        scripts?: readonly string[];
        /** `style-src`. */
        styles?: readonly string[];
        /** `font-src`. */
        fonts?: readonly string[];
        /** `media-src`. */
        media?: readonly string[];
    };
    /** Largest `agent.send(…)` payload accepted, as JSON, in bytes. Default 8192. */
    maxPayloadBytes?: number;
    /** Least time between two accepted sends from one view, in ms. Default 1000. */
    minSendIntervalMs?: number;
    /** Most sends one view may make. Default 20. */
    maxSends?: number;
    /** Tallest the frame may grow, in CSS pixels. Default 1600. */
    maxHeight?: number;
}
export declare const SANDBOX_DEFAULTS: {
    readonly initialHeight: 240;
    readonly maxPayloadBytes: 8192;
    readonly minSendIntervalMs: 1000;
    readonly maxSends: 20;
    readonly maxHeight: 1600;
};
/** Throws unless every listed origin is a bare `https://host[:port]` (or `https://*.host`). */
export declare function assertSandboxPolicy(policy: SandboxPolicy): void;
/**
 * The Content-Security-Policy every sandbox document carries (as a `<meta>`, first thing in its
 * head). Inline scripts and styles run — they ARE the generated UI — but nothing else loads, no
 * form posts and no navigation of the frame's base, unless the policy lists an origin.
 */
export declare function sandboxCsp(policy?: SandboxPolicy): string;
/** The `sandbox` attribute of the frame: scripts, and nothing else — above all no `allow-same-origin`. */
export declare const SANDBOX_IFRAME_FLAGS = "allow-scripts";
/** The type tags of the messages a sandbox frame and its host exchange. */
export declare const SANDBOX_MESSAGE: {
    /** frame → host: the bridge is up. */
    readonly ready: 'agora:sandbox:ready';
    /** frame → host: `{ height }` — the content's height. */
    readonly resize: 'agora:sandbox:resize';
    /** frame → host: `{ payload }` — `agent.send(payload)`. */
    readonly send: 'agora:sandbox:send';
    /** frame → host: `{ message }` — an uncaught error in the generated code. */
    readonly error: 'agora:sandbox:error';
    /** host → frame: `{ css, html }` — redraw the preview (no scripts run). */
    readonly render: 'agora:sandbox:render';
    /** host → frame: `{ code }` — run one more classic script. */
    readonly run: 'agora:sandbox:run';
    /** host → frame: `{ css, dark }` — the host's theme changed (light/dark, a new stylesheet). */
    readonly theme: 'agora:sandbox:theme';
    /** host → frame: `{ code, final }` — the JSX so far (`final` once the model is done). */
    readonly jsx: 'agora:sandbox:jsx';
    /**
     * frame → host: the frame is up and waits for its shared assets (a document built with
     * `sharedAssets`); it says `ready` once they are in.
     */
    readonly load: 'agora:sandbox:load';
    /** host → frame: `{ styles?, tailwind?, kit? }` — the shared assets' text. */
    readonly assets: 'agora:sandbox:assets';
};
/**
 * The assets a host hands a frame built with `sharedAssets` (the answer to its `load`): the text of
 * each, fetched once by the page. The frame puts each in an inline `<style>` / `<script>` — what the
 * CSP already allows — so the policy is the same as for an inlined document.
 */
export interface SandboxSharedAssets {
    /** The app's compiled styles. */
    styles?: string;
    /** The Tailwind browser runtime. */
    tailwind?: string;
    /** The kit bundle (React, ReactDOM, the components, the wrapper). */
    kit?: string;
}
export interface SandboxDocumentOptions {
    /** A per-frame value every bridge message carries, so the host can tell this frame's messages apart. */
    token: string;
    /**
     * Where the bridge posts its messages (the host page's origin). The frame's own origin is opaque
     * (`null`): it can address its parent, never be addressed by name.
     */
    hostOrigin: string;
    policy?: SandboxPolicy;
    /**
     * `'preview'`: CSS + markup only, scripts stripped; the host redraws it with `render` messages
     * while the model writes. `'live'`: the whole view, its inline scripts and `jsFunctions` /
     * `jsExpressions` included.
     */
    mode: 'preview' | 'live';
    /** Run the JavaScript fields inline (`live` only). Default true; false when the host streams them in with `run`. */
    inlineJs?: boolean;
    /**
     * The host's theme (`hostThemeCss(collectHostThemeVars(document), dark)`): put on the frame's
     * `:root`, and kept current with `theme` messages. `dark` mirrors the host's `dark` class;
     * `attributes`, its light/dark attributes (`data-theme`, `data-bs-theme`…).
     */
    theme?: {
        css: string;
        dark: boolean;
        attributes?: Record<string, string>;
    };
    /** The app's compiled styles (`genuiSandboxKit({ styles })`), before the theme and the model's CSS. */
    styles?: string;
    /** Tailwind: the `@tailwindcss/browser` runtime source, and the `@theme` mapping the host's variables. */
    tailwind?: {
        runtime: string;
        theme?: string;
    };
    /**
     * The kit bundle's source (an IIFE setting `window.Kit`, `React`, `ReactDOM`): inlined, and the JSX
     * runtime with it — the frame then draws `jsx` (posted with `jsx` messages, or `initialJsx`).
     */
    kit?: string;
    /** JSX to draw as soon as the document loads (a whole view: `final: true`). */
    initialJsx?: {
        code: string;
        final: boolean;
    };
    /**
     * The heavy assets come from the host instead of the `srcdoc`: the document carries none of
     * `styles`, the Tailwind runtime or `kit` — only which of them it needs — and asks its host for them
     * (`load`); the host answers with `assets` ({@link SandboxSharedAssets}), the text it fetched once
     * for the whole page. The frame puts them in inline `<style>`/`<script>` elements — the same CSP as
     * an inlined document, nothing more allowed — and says `ready` once they are in. The body stays
     * hidden until then, so nothing draws unstyled. Ignored for `react-native` (inlined there).
     */
    sharedAssets?: {
        styles?: boolean;
        tailwind?: boolean;
        kit?: boolean;
    };
    /**
     * How the bridge reaches its host. `'parent'` (default): `parent.postMessage` to `hostOrigin`, an
     * iframe in a page. `'react-native'`: `window.ReactNativeWebView.postMessage(JSON)`, the document
     * as a `react-native-webview` source (`hostOrigin` unused), with a device-width viewport. The host
     * talks back the same way either way — `message` events whose `source` is the frame's parent.
     */
    transport?: 'parent' | 'react-native';
}
/**
 * The `srcdoc` of a sandbox frame. The CSP `<meta>` comes first, then the bridge, the base styles and
 * the model's CSS, then its markup — and, live, its `jsFunctions` and each `jsExpressions` entry as
 * classic scripts, in that order.
 */
export declare function buildSandboxDocument(props: SandboxProps, options: SandboxDocumentOptions): string;
/** Which shared assets a document built with {@link SandboxDocumentOptions.sharedAssets} asks for. */
export declare function sandboxSharedAssetsWanted(options: Pick<SandboxDocumentOptions, 'sharedAssets' | 'transport'>): {
    styles: boolean;
    tailwind: boolean;
    kit: boolean;
};
/**
 * Markup the model is still writing, made safe to draw as a preview: the half-written tag at the end
 * dropped, `<script>`/`<style>`/`<head>` blocks (whole or cut off) removed, a cut-off entity dropped,
 * and only what is inside `<body>` kept.
 */
export declare function previewHtml(html: string): string;
/**
 * Sandbox props as they are while the model writes them: only what may be shown or run. CSS and
 * `jsFunctions` are held until their string closes, a `jsExpressions` entry until it closes (code is
 * never run half written), a half-written placeholder line is dropped; the markup streams as it is.
 */
export declare function sandboxPartialProps(props: Record<string, unknown>, input: {
    isOpen(container: object): boolean;
    pendingMember(container: object): unknown;
}): Record<string, unknown>;
/**
 * Where the kit's docs come from: the docs themselves, or a function read each time the model is
 * told about the sandbox (dev: the Vite plugin rewrites them as the components change).
 */
export type SandboxKitSource = SandboxKitDocs | (() => SandboxKitDocs | undefined);
/** Where the theme's variable names (for the prompt) come from — the same shapes as the kit. */
export type SandboxThemeSource = Record<string, string> | readonly string[] | (() => Record<string, string> | readonly string[] | undefined);
export interface DefineSandboxOptions {
    /** Component name. Default `Sandbox`. */
    name?: string;
    /** Replaces the model-facing description (keep the "last resort" rule in it). */
    description?: string;
    /** Extra rules appended to the description (house style, what the app wants from it). */
    instructions?: string;
    /** Network allowances and send limits; also what the renderer enforces by default. */
    policy?: SandboxPolicy;
    version?: number;
    /**
     * The app's theme in the frame: the renderer reads the host page's CSS custom properties from
     * `:root` and puts them on the frame's (and follows light/dark changes). Default `'inherit'` (on);
     * `false` turns it off. `vars` names them for the model (the Vite plugin finds them on its own).
     */
    theme?: boolean | 'inherit' | {
        vars?: SandboxThemeSource;
    };
    /**
     * The app's design system in the frame — whatever `genuiSandboxKit()` built: its compiled styles
     * (fonts and images inlined), the Tailwind runtime with the app's theme when the styles use
     * Tailwind, its components and wrapper (the model then writes `jsx`). What the model is told is
     * read from the docs: components and props, Tailwind tokens or the CSS class vocabulary, the
     * theme's variables, `stylesDocs`. `true`: the server's `sandbox({ kit: true })` finds them
     * through Vite; or pass the docs (or a function returning them) yourself.
     */
    kit?: boolean | SandboxKitSource;
    /**
     * Which kit `kit: true` finds, when the app builds several (`genuiSandboxKit({ name })`): its name.
     * Default: the unnamed one.
     */
    kitName?: string;
}
/** How a sandbox draws: theme and kit on or off. */
export interface SandboxView {
    theme: boolean;
    kit: boolean;
}
/** A sandbox definition: a {@link ComponentDefinition} that carries its {@link SandboxPolicy}. */
export type SandboxDefinition = ComponentDefinition<SandboxProps> & {
    readonly sandbox: SandboxPolicy;
    /** Theme and kit, as the definition was given them. */
    readonly sandboxView?: SandboxView;
    /** The options it was defined with — what a server resolves the kit for. */
    readonly sandboxOptions?: Readonly<DefineSandboxOptions>;
};
/**
 * A sandbox component. `streaming: 'partial'`, so in tree mode it draws while the model writes it:
 * a placeholder of `initialHeight`, then the styled markup, then — once the code has closed — the
 * live view. With a kit, JSX draws as it streams, each time what has arrived parses.
 *
 * ```ts
 * const catalog = defineCatalog([...myComponents, defineSandbox({ policy: { allow: { images: ['https://tile.openstreetmap.org'] } } })])
 * ```
 */
export declare function defineSandbox(options?: DefineSandboxOptions): SandboxDefinition;
/**
 * A minimal, valid call of a sandbox's own tool (`ui__sandbox`), as the model should write it: JSX
 * when the kit draws JSX (a kit `Button` when there is one), HTML otherwise. The JSX is a JSON
 * STRING — quoted, newlines escaped — which is what a model writing code (OpenCode) gets wrong.
 */
export declare function sandboxCallExample(definition: unknown): string | undefined;
/**
 * Whether a sandbox's props draw as JSX (the kit) or as HTML. A model under strict tool calling
 * (OpenAI's) fills every property, so it may write a whole view in one field and a stub in the
 * other (`function App() { return null }` next to the real `html`): the field that holds the view —
 * the longer one — wins. JSX only when it has something in it.
 */
export declare function sandboxDrawsJsx(props: Pick<SandboxProps, 'jsx' | 'html'>): boolean;
/** The builtin sandbox: no network, default limits. */
export declare const Sandbox: SandboxDefinition;
/** The sandbox policy a definition carries (`{}` for a component that is not a sandbox). */
export declare function sandboxPolicyOf(definition: unknown): SandboxPolicy | undefined;
//# sourceMappingURL=sandbox.d.ts.map