export type Severity = 'bug' | 'idea' | 'ux' | 'a11y';
export type Position = 'bottom-right' | 'bottom-left' | 'hidden';
export type Theme = 'auto' | 'light' | 'dark';
export type HeadersConfig = Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
export type ContextConfig = () => Record<string, unknown>;
export interface PayloadMetadata {
    url: string;
    referrer?: string;
    userAgent: string;
    viewport: {
        w: number;
        h: number;
        dpr: number;
    };
    screen: {
        w: number;
        h: number;
    };
    timezone: string;
    locale: string;
    theme?: 'light' | 'dark';
    capturedAt: string;
}
export interface PluginSuccessEntry {
    v: number;
    [k: string]: unknown;
}
export interface PluginFailureEntry {
    error: string;
    stack?: string;
}
export type PluginEntry = PluginSuccessEntry | PluginFailureEntry;
export interface FeedbackPayload {
    description: string;
    severity: Severity;
    metadata: PayloadMetadata;
    context?: Record<string, unknown>;
    plugins: Record<string, PluginEntry>;
}
export declare function isPluginFailure(entry: PluginEntry | undefined): entry is PluginFailureEntry;
export interface LabelMap {
    triggerButton: string;
    drawerTitle: string;
    closeButton: string;
    send: string;
    sending: string;
    sentSuccess: string;
    descriptionLabel: string;
    descriptionPlaceholder: string;
    severityLabel: string;
    severityBug: string;
    severityIdea: string;
    severityUx: string;
    severityA11y: string;
}
export interface BaseField<K extends string> {
    type: K;
    /** Per-plugin key in ctx.formValues. */
    name: string;
    label?: string;
    description?: string;
}
export interface ToggleField extends BaseField<'toggle'> {
    defaultValue?: boolean;
}
export interface TextField extends BaseField<'text'> {
    defaultValue?: string;
    placeholder?: string;
}
export interface TextareaField extends BaseField<'textarea'> {
    defaultValue?: string;
    placeholder?: string;
    rows?: number;
}
export interface SelectField extends BaseField<'select'> {
    defaultValue?: string;
    options: Array<{
        value: string;
        label?: string;
    }>;
}
export interface RadioField extends BaseField<'radio'> {
    defaultValue?: string;
    options: Array<{
        value: string;
        label?: string;
    }>;
}
export interface NumberField extends BaseField<'number'> {
    defaultValue?: number;
    min?: number;
    max?: number;
    step?: number;
}
export type FormField = ToggleField | TextField | TextareaField | SelectField | RadioField | NumberField;
export type DeclarativeForm = {
    title?: string;
    fields: FormField[];
};
export type ImperativeForm = {
    title?: string;
    render: (slot: HTMLElement, ctx: BeaconCtx) => void | (() => void);
};
export type Mode = 'minimize' | 'hide' | 'pickElement';
export interface BeaconLifecycleEvent {
    payload?: FeedbackPayload;
    response?: TransportResponse;
    cancel?: (reason: string) => void;
}
export interface BeaconCtx {
    readonly pluginName: string;
    captured(name: string): PluginEntry | undefined;
    readonly formValues: Record<string, unknown>;
    requestMode(mode: Mode): Promise<() => void>;
    overlay(opts: {
        render: (slot: HTMLElement) => void | (() => void);
    }): () => void;
    on(ev: 'open' | 'close' | 'beforeSubmit' | 'afterSubmit', handler: (e: BeaconLifecycleEvent) => void): () => void;
    readonly signal: AbortSignal;
    captureSignal(): AbortSignal | undefined;
}
export interface BeaconPlugin {
    name: string;
    version?: number;
    setupOnce?(ctx: BeaconCtx): void | (() => void);
    form?(ctx: BeaconCtx): DeclarativeForm | ImperativeForm;
    capture?(ctx: BeaconCtx): unknown | Promise<unknown>;
}
export interface InitOptions {
    endpoint: string;
    headers?: HeadersConfig;
    context?: ContextConfig;
    /** fetch credentials mode. Default 'omit' per §9 (safe for cross-origin
     *  consumers); same-origin apps that gate the endpoint behind cookie auth
     *  should pass 'same-origin'. */
    credentials?: RequestCredentials;
    plugins?: BeaconPlugin[];
    defaultPlugins?: boolean;
    position?: Position;
    theme?: Theme;
    labels?: Partial<LabelMap>;
    debug?: boolean;
    healthIndicator?: 'never' | 'dev' | 'always';
}
export interface PluginStatus {
    state: 'active' | 'failed';
    failures: number;
    error?: {
        message: string;
        stack?: string;
        at: 'setupOnce' | 'capture' | 'form';
    };
}
export interface BeaconStatus {
    ready: boolean;
    transport: 'ok' | 'error' | 'idle';
    plugins: Record<string, PluginStatus>;
}
export type SystemEvent = 'plugin:error' | 'submit:success' | 'submit:error' | 'ready';
export interface PluginErrorEvent {
    plugin: string;
    error: Error;
    at: 'setupOnce' | 'capture' | 'form';
}
export interface SubmitSuccessEvent {
    payload: FeedbackPayload;
    response: TransportResponse;
}
export interface SubmitErrorEvent {
    payload: FeedbackPayload;
    error: Error;
}
export interface ReadyEvent {
    ready: true;
}
export type SystemEventPayload<E extends SystemEvent> = E extends 'plugin:error' ? PluginErrorEvent : E extends 'submit:success' ? SubmitSuccessEvent : E extends 'submit:error' ? SubmitErrorEvent : E extends 'ready' ? ReadyEvent : never;
export interface TransportResponse {
    ok: boolean;
    status: number;
    body: unknown;
}
//# sourceMappingURL=types.d.ts.map