import * as react_jsx_runtime from 'react/jsx-runtime'; import React, { ReactNode, ComponentType } from 'react'; import { StateStore, StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, UIElement, SchemaDefinition, Spec, FlatElement } from '@json-render/core'; export { Spec, StateModel, StateStore, createStateStore } from '@json-render/core'; export { InkSchema, InkSpec, schema } from './schema.js'; import { Components, Actions, SetState } from './server.js'; export { ActionFn, ComponentContext, ComponentFn } from './server.js'; export { ActionDefinition, ComponentDefinition, standardActionDefinitions, standardComponentDefinitions } from './catalog.js'; import 'zod'; /** * State context value */ interface StateContextValue { /** The current state model */ state: StateModel; /** Get a value by path */ get: (path: string) => unknown; /** Set a value by path */ set: (path: string, value: unknown) => void; /** Update multiple values at once */ update: (updates: Record) => void; /** Return the live state snapshot from the underlying store (not the React render snapshot). */ getSnapshot: () => StateModel; } /** * Props for StateProvider */ interface StateProviderProps { /** * External store that owns the state. When provided, the provider operates * in **controlled mode** — `initialState` and `onStateChange` are ignored * and the store is the single source of truth. */ store?: StateStore; /** Initial state model (used only in uncontrolled mode) */ initialState?: StateModel; /** * Callback when state changes (used only in uncontrolled mode). * Called once per `set` or `update` with all changed entries. */ onStateChange?: (changes: Array<{ path: string; value: unknown; }>) => void; children: ReactNode; } /** * Provider for state model context. * * Supports two modes: * - **Controlled**: pass a `store` prop (e.g. backed by Redux / Zustand). * - **Uncontrolled** (default): omit `store` and optionally pass * `initialState` / `onStateChange`. */ declare function StateProvider({ store: externalStore, initialState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element; /** * Hook to access the state context */ declare function useStateStore(): StateContextValue; /** * Hook to get a value from the state model */ declare function useStateValue(path: string): T | undefined; /** * Hook to get and set a value from the state model (like useState). * * @deprecated Use {@link useBoundProp} with `$bindState` expressions instead. * `useStateBinding` takes a raw state path string, while `useBoundProp` works * with the renderer's `bindings` map and supports both `$bindState` and * `$bindItem` expressions. */ declare function useStateBinding(path: string): [T | undefined, (value: T) => void]; /** * Visibility context value */ interface VisibilityContextValue { /** Evaluate a visibility condition */ isVisible: (condition: VisibilityCondition | undefined) => boolean; /** The underlying visibility context */ ctx: VisibilityContext; } /** * Props for VisibilityProvider */ interface VisibilityProviderProps { children: ReactNode; } /** * Provider for visibility evaluation */ declare function VisibilityProvider({ children }: VisibilityProviderProps): react_jsx_runtime.JSX.Element; /** * Hook to access visibility evaluation */ declare function useVisibility(): VisibilityContextValue; /** * Hook to check if a condition is visible */ declare function useIsVisible(condition: VisibilityCondition | undefined): boolean; /** * Pending confirmation state */ interface PendingConfirmation { /** The resolved action */ action: ResolvedAction; /** The action handler */ handler: ActionHandler; /** Resolve callback */ resolve: () => void; /** Reject callback */ reject: () => void; } /** * Action context value */ interface ActionContextValue { /** Registered action handlers */ handlers: Record; /** Actions currently executing (count of in-flight executions per action name) */ loadingActions: Map; /** Pending confirmation dialog */ pendingConfirmation: PendingConfirmation | null; /** Execute an action binding */ execute: (binding: ActionBinding) => Promise; /** Confirm the pending action */ confirm: () => void; /** Cancel the pending action */ cancel: () => void; } /** * Props for ActionProvider */ interface ActionProviderProps { /** Action handlers (custom handlers override built-in actions) */ handlers?: Record; /** Navigation function */ navigate?: (path: string) => void; children: ReactNode; } /** * Provider for action execution */ declare function ActionProvider({ handlers: initialHandlers, navigate, children, }: ActionProviderProps): react_jsx_runtime.JSX.Element; /** * Hook to access action context */ declare function useActions(): ActionContextValue; /** * Hook for a single action binding — returns execute and loading state. */ declare function useAction(binding: ActionBinding): { execute: () => Promise; isLoading: boolean; }; /** * Props for ConfirmDialog component */ interface ConfirmDialogProps { /** The confirmation config */ confirm: ActionConfirm; /** Called when confirmed */ onConfirm: () => void; /** Called when cancelled */ onCancel: () => void; } /** * Terminal confirmation dialog using Ink's Box/Text and useInput. * Press Y to confirm, N or Escape to cancel. */ declare function ConfirmDialog({ confirm, onConfirm, onCancel, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element; /** * Field validation state */ interface FieldValidationState { /** Whether the field has been touched */ touched: boolean; /** Whether the field has been validated */ validated: boolean; /** Validation result */ result: ValidationResult | null; } /** * Validation context value */ interface ValidationContextValue { /** Custom validation functions from catalog */ customFunctions: Record; /** Validation state by field path */ fieldStates: Record; /** Validate a field */ validate: (path: string, config: ValidationConfig) => ValidationResult; /** Mark field as touched */ touch: (path: string) => void; /** Clear validation for a field */ clear: (path: string) => void; /** Validate all fields */ validateAll: () => boolean; /** Register field config */ registerField: (path: string, config: ValidationConfig) => void; /** Unregister field (removes from validateAll and clears state) */ unregisterField: (path: string) => void; } /** * Props for ValidationProvider */ interface ValidationProviderProps { /** Custom validation functions from catalog */ customFunctions?: Record; children: ReactNode; } /** * Provider for validation */ declare function ValidationProvider({ customFunctions, children, }: ValidationProviderProps): react_jsx_runtime.JSX.Element; /** * Hook to access validation context */ declare function useValidation(): ValidationContextValue; /** * Hook to optionally access validation context (returns null if outside provider). */ declare function useOptionalValidation(): ValidationContextValue | null; /** * Hook to get validation state for a field */ declare function useFieldValidation(path: string, config?: ValidationConfig): { state: FieldValidationState; validate: () => ValidationResult; touch: () => void; clear: () => void; errors: string[]; isValid: boolean; }; /** * Repeat scope value provided to child elements inside a repeated element. */ interface RepeatScopeValue { /** The current array item object */ item: unknown; /** Index of the current item in the array */ index: number; /** Absolute state path to the current array item (e.g. "/todos/0") — used for statePath two-way binding */ basePath: string; } /** * Provides repeat scope to child elements so $item and $index expressions resolve correctly. */ declare function RepeatScopeProvider({ item, index, basePath, children, }: RepeatScopeValue & { children: ReactNode; }): react_jsx_runtime.JSX.Element; /** * Read the current repeat scope (or null if not inside a repeated element). */ declare function useRepeatScope(): RepeatScopeValue | null; declare function FocusProvider({ children }: { children: React.ReactNode; }): react_jsx_runtime.JSX.Element; /** * Hook for interactive components. Registers on mount via useEffect, * unregisters on unmount. Returns `isActive` boolean for gating `useInput`. * * Uses React.useId() for stable, instance-scoped IDs (no module-level counters). */ declare function useFocus(): { isActive: boolean; id: string; }; /** * Hook to suppress/restore Tab cycling. * Used by modal dialogs (e.g. ConfirmDialog) to prevent background focus changes. * * Tracks the disabled value at effect time via a ref to avoid double-decrement * when the `disabled` prop toggles from true to false. */ declare function useFocusDisable(disabled: boolean): void; /** * Props passed to component renderers */ interface ComponentRenderProps

> { /** The element being rendered */ element: UIElement; /** Rendered children */ children?: ReactNode; /** Emit a named event. The renderer resolves the event to action binding(s) from the element's `on` field. */ emit: (event: string) => void; /** * Two-way binding paths resolved from `$bindState` / `$bindItem` expressions. * Maps prop name → absolute state path for write-back. */ bindings?: Record; /** Whether the parent is loading */ loading?: boolean; } /** * Component renderer type */ type ComponentRenderer

> = ComponentType>; /** * Registry of component renderers */ type ComponentRegistry = Record>; /** * Props for the Renderer component */ interface RendererProps { /** The UI spec to render */ spec: Spec | null; /** * Component registry. If omitted, only standard components are used. * When provided, custom components are merged with (and override) standard components. */ registry?: ComponentRegistry; /** Whether to include standard components (default: true) */ includeStandard?: boolean; /** Whether the spec is currently loading/streaming */ loading?: boolean; /** Fallback component for unknown types */ fallback?: ComponentRenderer; } /** * Main renderer component. * * By default, standard Ink components are included. * Custom components in `registry` override standard ones with the same name. */ declare function Renderer({ spec, registry: customRegistry, includeStandard, loading, fallback, }: RendererProps): react_jsx_runtime.JSX.Element | null; /** * Props for JSONUIProvider */ interface JSONUIProviderProps { /** * External store (controlled mode). When provided, `initialState` and * `onStateChange` are ignored. */ store?: StateStore; /** Initial state model (uncontrolled mode) */ initialState?: Record; /** Action handlers */ handlers?: Record) => Promise | unknown>; /** Navigation function */ navigate?: (path: string) => void; /** Custom validation functions */ validationFunctions?: Record) => boolean>; /** Callback when state changes (uncontrolled mode) */ onStateChange?: (changes: Array<{ path: string; value: unknown; }>) => void; children: ReactNode; } /** * Combined provider for all JSONUI contexts */ declare function JSONUIProvider({ store, initialState, handlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element; /** * Result returned by defineRegistry */ interface DefineRegistryResult { /** Component registry for `` */ registry: ComponentRegistry; /** * Create ActionProvider-compatible handlers. */ handlers: (getSetState: () => SetState | undefined, getState: () => StateModel) => Record) => Promise>; /** * Execute an action by name imperatively */ executeAction: (actionName: string, params: Record | undefined, setState: SetState, state?: StateModel) => Promise; } /** * Create a registry from a catalog with components and/or actions. */ declare function defineRegistry(_catalog: C, options: { components?: Components; actions?: Actions; }): DefineRegistryResult; /** * Props for renderers created with createRenderer */ interface CreateRendererProps { /** The spec to render (AI-generated JSON) */ spec: Spec | null; /** * External store (controlled mode). */ store?: StateStore; /** State context for dynamic values (uncontrolled mode) */ state?: Record; /** Action handler */ onAction?: (actionName: string, params?: Record) => void; /** Callback when state changes (uncontrolled mode) */ onStateChange?: (changes: Array<{ path: string; value: unknown; }>) => void; /** Whether the spec is currently loading/streaming */ loading?: boolean; /** Fallback component for unknown types */ fallback?: ComponentRenderer; } /** * Component map type */ type ComponentMap> = { [K in keyof TComponents]: ComponentType>>; }; /** * Create a renderer from a catalog */ declare function createRenderer; }>(_catalog: Catalog, components: ComponentMap): ComponentType; declare const standardComponents: ComponentRegistry; /** * Hook for two-way bound props. Returns `[value, setValue]` where: * * - `value` is the already-resolved prop value (passed through from render props) * - `setValue` writes back to the bound state path (no-op if not bound) * * @example * ```tsx * const [value, setValue] = useBoundProp(element.props.value, bindings?.value); * ``` */ declare function useBoundProp(propValue: T | undefined, bindingPath: string | undefined): [T | undefined, (value: T) => void]; /** * Options for useUIStream */ interface UseUIStreamOptions { /** API endpoint */ api: string; /** Callback when complete */ onComplete?: (spec: Spec) => void; /** Callback on error */ onError?: (error: Error) => void; /** * Custom fetch implementation with ReadableStream support. * * Falls back to the global `fetch` if not provided. */ fetch?: (url: string, init?: RequestInit) => Promise; /** * Enable validation and auto-repair. * * When true: * - **Mid-stream**: Each JSONL line is validated as it arrives. If a line * is malformed JSON (and recovery fails), the stream is aborted * immediately and a repair prompt is sent to continue generation. * - **Post-stream**: After the stream completes, structural validation * runs (missing children, visible-in-props, etc.). Issues that can be * auto-fixed are fixed locally; remaining errors trigger a repair prompt. * * Defaults to false. */ validate?: boolean; /** * Maximum number of automatic repair retries (covers both mid-stream * and post-stream retries combined). Defaults to 5. */ maxRetries?: number; } /** * Return type for useUIStream */ interface UseUIStreamReturn { /** Current UI spec */ spec: Spec | null; /** Whether currently streaming */ isStreaming: boolean; /** Error if any */ error: Error | null; /** Send a prompt to generate UI */ send: (prompt: string, context?: Record) => Promise; /** Stop the current generation */ stop: () => void; /** Clear the current spec */ clear: () => void; } /** * Hook for streaming UI generation via JSONL patches. * * @example * ```tsx * const { spec, isStreaming, send } = useUIStream({ * api: "/api/generate-ui", * onComplete: (spec) => console.log("Done!", spec), * }); * * // Trigger generation * await send("Create a dashboard with stats"); * * // Render the spec * * ``` */ declare function useUIStream({ api, onComplete, onError, fetch: fetchFn, validate: enableValidation, maxRetries, }: UseUIStreamOptions): UseUIStreamReturn; /** * Convert a flat element list to a Spec. * Input elements use key/parentKey to establish identity and relationships. * Output spec uses the map-based format where key is the map entry key * and parent-child relationships are expressed through children arrays. */ declare function flatToTree(elements: FlatElement[]): Spec; export { type ActionContextValue, ActionProvider, type ActionProviderProps, Actions, type ComponentMap, type ComponentRegistry, type ComponentRenderProps, type ComponentRenderer, Components, ConfirmDialog, type ConfirmDialogProps, type CreateRendererProps, type DefineRegistryResult, type FieldValidationState, FocusProvider, JSONUIProvider, type JSONUIProviderProps, type PendingConfirmation, Renderer, type RendererProps, RepeatScopeProvider, type RepeatScopeValue, SetState, type StateContextValue, StateProvider, type StateProviderProps, type UseUIStreamOptions, type UseUIStreamReturn, type ValidationContextValue, ValidationProvider, type ValidationProviderProps, type VisibilityContextValue, VisibilityProvider, type VisibilityProviderProps, createRenderer, defineRegistry, flatToTree, standardComponents, useAction, useActions, useBoundProp, useFieldValidation, useFocus, useFocusDisable, useIsVisible, useOptionalValidation, useRepeatScope, useStateBinding, useStateStore, useStateValue, useUIStream, useValidation, useVisibility };