import type { ShadowContainer } from '../widget/shadow.js'; import type { I18nMessages } from '../i18n/index.js'; import type { ClarifyStreamResult } from '../api/client.js'; import type { SubmissionSessionResponse, TargetRect } from '../types.js'; interface ChatPopupOptions { targetName: string; x: number; y: number; targetRect?: TargetRect; messages: I18nMessages; position?: 'left' | 'right'; screenshotEnabled?: boolean; onScreenshotToggle?: (enabled: boolean) => void; onSubmit: (description: string) => Promise; onClarify: (sessionId: string, token: string, onDelta: (text: string) => void, signal?: AbortSignal) => Promise; onAnswer: (sessionId: string, token: string, message: string) => Promise; onFinalize: () => Promise | void; onCancel: () => void; /** A question is on screen: the card now holds an uploaded submission. */ onConversationOpen?: () => void; onActivity?: () => void; recordingSeconds?: number; resolveBoardLink?: () => (() => void) | undefined; resolveEmailCapture?: () => { onSubmit: (email: string) => Promise; } | undefined; } export declare class ChatPopup { private el; private sheet; private focusTrap; private messagesEl; private composerEl; private actionsEl; private inputEl; private sendBtn; private quickRepliesEl; private state; private i18n; private opts; private autoCloseTimer; private session; private clarifyAbort; private destroyed; constructor(shadow: ShadowContainer, opts: ChatPopupOptions); private handleEscape; private buildHTML; private bindEvents; private sendMessage; private handleAnswer; /** * The receipt goes up the moment the reporter is done rather than waiting on * the finalize round trip; the hand-off it returns is patched into the card * when it lands. A failed finalize replaces this receipt with an in-card * retry state so the reporter stays in the conversation they used. */ private showDone; /** * The success view takes over everything under the header — the transcript, * the quick replies and the composer are all gone, so the card reads as a * receipt rather than a conversation the reporter could keep typing into. */ private renderSuccess; /** Keep a failed background finalize in the conversation the reporter used. */ showFinalizeFailure(onRetry?: () => void): void; /** Restore the receipt after a retry reaches the final endpoint. */ showFinalizeSuccess(): void; /** * The board link and the email form are both built from the hand-off that * finalize returns, but the receipt renders the moment the reporter is done * rather than waiting on that round trip — so this runs twice: once against * whatever is already known, and again when finalize lands. */ private attachHandoff; private finalized; private finalizeInBackground; private buildEmailCard; private appendUserBubble; private streamingBubbleEl; private startStreamingBubble; private appendStreamDelta; private endStreamingBubble; private appendAiBubble; private renderSuggestions; private clearSuggestions; private showThinking; private removeThinking; private showRetryableError; private clearError; private showSkip; private skipAndSend; private hideSkip; private hideCapture; private setComposerDisabled; private positionCard; submit(text: string): void; /** Which submission this card holds — null while the reporter is still typing. */ sessionId(): string | null; destroy(): void; private armAutoCloseTimer; private clearAutoCloseTimer; } export {}; //# sourceMappingURL=chat-popup.d.ts.map