import type { ComponentChannels } from './channels.js';
import { type GenuiValidation, type JsonSchema, type JsonSchemaValidator, type PropsSchema } from './schema.js';
/**
 * One component a server may push into a conversation. Data only — how it LOOKS is each app's own
 * renderer, looked up by {@link name}. The same definition serves the model (description + props
 * schema), the server (validation), text-only channels ({@link fallbackText}) and the client
 * (validation before rendering).
 */
export interface ComponentDefinition<P = Record<string, unknown>> {
    /** Registry key, e.g. `DataTable`. What a `ui` frame's `component` names. */
    name: string;
    /** Human label: "Data table". */
    title: string;
    /** Shown to the model: what the component is for and when to use it. */
    description: string;
    /** The props schema: a Standard Schema (Zod, Valibot, ArkType) or a JSON Schema object. */
    props: PropsSchema;
    /** Portable normalized props schema. Required when input transformations are not idempotent. */
    outputProps?: PropsSchema;
    /**
     * The component takes nested elements (a layout: `Stack`, `Card`). Only meaningful in tree mode,
     * where a node's `children` are validated against the catalog too. Outside tree mode such a
     * component has nothing to hold, so it gets no `ui__show_*` tool and the generic show tool does
     * not offer it.
     */
    children?: boolean;
    /**
     * Plain text / Slack mrkdwn rendering of these props, for a channel that cannot draw the
     * component. Absent → {@link componentToText} prints the props as JSON. An empty string renders
     * nothing (a layout with nothing of its own to say); in a tree its children still render.
     */
    fallbackText?(props: P): string;
    /**
     * Pushed by the server (e.g. an approval card), never offered to the model. Excluded from
     * {@link catalogToModelText} and from the tool factories.
     */
    internal?: boolean;
    /**
     * Schema version of {@link props}. Stamped on every `ui` frame the component is pushed with, so a
     * client can keep rendering messages persisted under an older shape.
     */
    version?: number;
    /**
     * How this component appears in a tree the model is still writing (tree mode with streaming
     * previews — see `GenuiToolsOptions.streaming`). Absent → the tree's default.
     *
     * - `'partial'`: drawn as soon as its type is known, its props filling in as they arrive (the
     *   node is flagged `incomplete` until its object closes).
     * - `'complete'`: held back until its whole subtree has arrived — the node is sent as a
     *   placeholder (`held`, no props, no children) and drawn once it closes. For a component that
     *   cannot draw half its data: a chart, a map.
     */
    streaming?: GenuiStreaming;
    /**
     * What a preview may show of props the model is still writing (a `streaming: 'partial'` node, or
     * a per-component call being previewed): drop what must not be drawn or run half written. Called
     * with the raw partial props and the parser's view of them. Absent → the props as they are.
     */
    partialProps?(props: Record<string, unknown>, input: {
        isOpen(container: object): boolean;
        pendingMember(container: object): unknown;
    }): Record<string, unknown>;
    /**
     * What the component is on a channel the server draws for, by channel name: `whatsapp: (props) =>
     * ({ text, buttons })`, `telegram: …`, `email: (props) => ({ html })` (see `ChannelNativeMessage`).
     * Without one the channel sends {@link fallbackText}. `false` → never offered on that channel.
     */
    channels?: ComponentChannels<P>;
    /**
     * Checks beyond the props schema, run on the server once the props are valid — the sandbox parses
     * its code here. An `error` refuses the call (the model gets its message and retries); a
     * `warning` lets it through and is handed back with the result.
     */
    check?(props: P): GenuiCheck[] | Promise<GenuiCheck[]>;
}
/** One finding of a {@link ComponentDefinition.check}. */
export interface GenuiCheck {
    severity: 'error' | 'warning';
    /** What kind of mistake it is (what telemetry counts): `syntax`, `bridge`, `unknown-component`, … */
    category: string;
    /** Short, with where and the fix: "jsx line 12:5: `flippy.send` — the bridge is `agent.send(payload)`". */
    message: string;
}
/** The second argument of {@link defineComponent}: what a component is on each channel. */
export interface DefineComponentExtras<P> {
    channels?: ComponentChannels<P>;
}
/** How a tree node appears while the model writes it ({@link ComponentDefinition.streaming}). */
export type GenuiStreaming = 'partial' | 'complete';
/** Component names: an identifier a registry key, a tool name and a snake_case slug can all be derived from. */
export declare const COMPONENT_NAME: RegExp;
/** Declare a component. Validates the name and returns the definition unchanged (typed). */
export declare function defineComponent<P = Record<string, unknown>>(definition: ComponentDefinition<P>, extras?: DefineComponentExtras<P>): ComponentDefinition<P>;
export interface CatalogOptions {
    /** How JSON Schema props are checked. Default: {@link builtinJsonSchemaValidator}; pass `ajvValidator(new Ajv())` for full JSON Schema. */
    jsonSchemaValidator?: JsonSchemaValidator;
}
/** An immutable set of component definitions, looked up by name. */
export interface Catalog {
    readonly components: readonly ComponentDefinition<unknown>[];
    readonly validator: JsonSchemaValidator;
    get(name: string): ComponentDefinition<unknown> | undefined;
    has(name: string): boolean;
    /** The components a model may be offered (every non-`internal` one). */
    modelComponents(): ComponentDefinition<unknown>[];
    /** Validate `props` for `component`. An unknown component is a validation failure, not a throw. */
    validate(component: string, props: unknown): Promise<GenuiValidation<Record<string, unknown>>>;
    /**
     * {@link validate} without waiting — `undefined` only when the component's Standard Schema
     * validates asynchronously. An unknown component is a failure, as in `validate`.
     */
    validateSync(component: string, props: unknown): GenuiValidation<Record<string, unknown>> | undefined;
    /** The component's props as JSON Schema, when it can be derived (see {@link toJsonSchema}). */
    jsonSchemaFor(component: string): JsonSchema | undefined;
    /** A new catalog with these components added (a later definition replaces an earlier one of the same name). */
    extend(components: readonly ComponentDefinition<unknown>[]): Catalog;
}
/**
 * Collect component definitions into a {@link Catalog}. Names must be unique; to override a
 * definition (e.g. a builtin), use {@link Catalog.extend}.
 */
export declare function defineCatalog(components: readonly ComponentDefinition<unknown>[], options?: CatalogOptions): Catalog;
/**
 * The model components that stand on their own: every one but a layout (`children: true`). Outside
 * tree mode nothing can be nested, so a layout could only be pushed empty — it gets no
 * `ui__show_*` tool and is not offered by the generic show tool.
 */
export declare function standaloneComponents(catalog: Catalog): ComponentDefinition<unknown>[];
/** `DataTable` → `data_table`, `KPICards` → `kpi_cards`. */
export declare function toSnakeCase(name: string): string;
/** The per-component tool name: `ui__show_data_table` with the default prefix. */
export declare function toolNameFor(component: string, prefix?: string): string;
//# sourceMappingURL=catalog.d.ts.map