/** * Transport-neutral interaction model for addressable form controls. * * The registry deliberately knows nothing about chat, agents, WebMCP, or the * DOM. Controls register serializable metadata plus small imperative handles; * adapters translate voice/chat/tutorial requests into commands. */ export type ControlKind = 'text' | 'email' | 'password' | 'number' | 'date' | 'time' | 'datetime' | 'textarea' | 'select' | 'listbox' | 'combobox' | 'multi-select' | 'tags-input' | 'checkbox' | 'radio-group' | 'switch' | 'toggle-button' | 'slider' | 'range-slider' | 'segmented-control' | 'file' | 'custom'; export type ControlSensitivity = 'public' | 'personal' | 'sensitive' | 'secret'; export type ControlCapability = 'read' | 'focus' | 'reveal' | 'highlight' | 'explain' | 'validate' | 'stage' | 'apply' | 'clear' | 'undo'; export interface ControlSubject { type: string; id: string; label?: string; } /** Stable address for a control, following AdminShell's Tool Identity pattern. */ export interface ControlIdentity { formId: string; controlId: string; subject?: ControlSubject; } export interface ControlOption { value: string | number; label: string; disabled?: boolean; } export interface ControlConstraints { required?: boolean; min?: number | string; max?: number | string; step?: number | string; minLength?: number; maxLength?: number; pattern?: string; } /** Optional declarative metadata shared by every control primitive. */ export interface ControlInteractionOptions { /** Stable id inside the enclosing form. Defaults to name, then DOM id. */ id?: string; description?: string; sensitivity?: ControlSensitivity; readable?: boolean; writable?: boolean; subject?: ControlSubject; } export interface ControlMetadata { kind: ControlKind; label?: string; description?: string; sensitivity?: ControlSensitivity; readable?: boolean; writable?: boolean; constraints?: ControlConstraints; options?: ControlOption[]; unit?: string; capabilities?: ControlCapability[]; } export interface ControlRuntimeState { disabled?: boolean; readonly?: boolean; valid?: boolean; validationMessage?: string; } export interface ControlSnapshot { identity: ControlIdentity; metadata: ControlMetadata; state: ControlRuntimeState & { value?: unknown; valueRedacted: boolean; stagedValue?: unknown; stagedValueRedacted?: boolean; }; } export interface ControlRegistration { identity: ControlIdentity; metadata: ControlMetadata; getValue?: () => unknown; setValue?: (value: unknown) => void | Promise; clear?: () => void | Promise; focus?: () => void | Promise; reveal?: () => void | Promise; highlight?: (durationMs?: number) => void | Promise; validate?: () => boolean | Promise; getState?: () => ControlRuntimeState; } export type ControlCommandAction = 'focus' | 'reveal' | 'highlight' | 'explain' | 'validate' | 'stage' | 'apply' | 'clear' | 'undo'; export type ControlCommand = { action: 'focus' | 'reveal' | 'explain' | 'validate' | 'undo'; identity: ControlIdentity; } | { action: 'highlight'; identity: ControlIdentity; durationMs?: number; } | { action: 'stage'; identity: ControlIdentity; value: unknown; } | { action: 'apply'; identity: ControlIdentity; value?: unknown; } | { action: 'clear'; identity: ControlIdentity; }; export type ControlCommandSource = 'user' | 'voice' | 'agent' | 'tutorial' | 'test'; export interface ControlCommandContext { source: ControlCommandSource; /** Agent mutations require this explicit consent signal by default. */ confirmed?: boolean; actorId?: string; sessionId?: string; } export interface ControlPolicyDecision { allowed: boolean; reason?: string; } export type ControlInteractionPolicy = (command: ControlCommand, context: ControlCommandContext, snapshot: ControlSnapshot) => ControlPolicyDecision | Promise; export interface ControlCommandResult { ok: boolean; action: ControlCommandAction; identity: ControlIdentity; snapshot?: ControlSnapshot; reason?: string; } export interface ControlInteractionEvent { type: 'registered' | 'unregistered' | 'staged' | 'command'; identity: ControlIdentity; command?: ControlCommand; context?: ControlCommandContext; result?: ControlCommandResult; timestamp: number; } export interface ControlInteractionRegistry { register(registration: ControlRegistration): () => void; unregister(identity: ControlIdentity): void; list(formId?: string): ControlSnapshot[]; get(identity: ControlIdentity): ControlSnapshot | undefined; execute(command: ControlCommand, context?: ControlCommandContext): Promise; subscribe(listener: (event: ControlInteractionEvent) => void): () => void; } export interface CreateControlInteractionRegistryOptions { policy?: ControlInteractionPolicy; } /** Create an isolated registry; apps choose where and how it is exposed. */ export declare function createControlInteractionRegistry(options?: CreateControlInteractionRegistryOptions): ControlInteractionRegistry; //# sourceMappingURL=control-interaction.d.ts.map