import { asConversationId } from './protocol/index.js'; import { type WidgetConfig } from './renderer.js'; import { type WidgetI18nOverrides } from './i18n.js'; export interface UserInfo { /** Display name shown in the conversation (e.g. "Sarah Chen"). */ name?: string; /** Email address — passed as conversation metadata for agent context. */ email?: string; /** Avatar URL — shown as the guest's avatar in both widget and dashboard. */ avatar?: string; /** Any custom key/value metadata to attach to the conversation * (e.g. plan tier, account ID, page URL). Shown to agents in the sidebar. */ meta?: Record; } export interface MountOptions { el: HTMLElement; /** Relay URL. Any scheme works — `https://api.example.com` is fine; the widget * derives the WebSocket URL (`wss://…/ws`) and REST base from it. */ url: string; /** HTTP(S) base for REST calls — only needed when the REST API is on a * DIFFERENT origin than the socket. Normally leave unset. */ apiUrl?: string; profileId: string; subjectId?: string; /** Open a user↔user direct conversation with `peerId` instead of a support * thread. Requires signed identity on the chatroom (both `kind: 'direct'` * and `peerId` together; `subjectId` is ignored — the server derives the * symmetric DM key so both sides land in the SAME conversation). */ kind?: 'direct'; peerId?: string; /** IDENTITY (tiered — the host owns identity, the widget never has to persist it): * 1. `token` — a signed identity token. Either a capability token, or (recommended * for embedders) an ES256 JWT `{sub,iat,exp}` signed by your backend with the * private key whose public half is set as the chatroom's `guestPublicKey`. * The server cryptographically verifies it. Works in ANY language/environment, * no cookies or storage required. This is the production path. * 2. `userId` — a stable id you already have for the visitor (e.g. your logged-in * user id). Unauthenticated ("you vouch for it") but works everywhere. Used * only when `token` is absent. * 3. Neither — the widget falls back to best-effort local identity on the host * origin (first-party cookie + localStorage). A returning visitor on the same * browser keeps their history; if storage is blocked they get a fresh chat. */ token?: string; /** Called when a signed token is rejected (expired): return a fresh token * from your backend to renew the session without a reload. */ refreshToken?: () => Promise; userId?: string; subject?: WidgetConfig['subject']; quickReplies?: string[]; accent?: string; /** Secondary accent (guest bubble + send button). Defaults to the design * blue; omit and it follows `accent` for a cohesive single-token retheme. */ accent2?: string; /** Colour scheme. Default 'light'. 'auto' follows the OS; 'dark'/'light' force it. */ theme?: 'auto' | 'light' | 'dark'; /** Load Baloo 2 + Nunito webfonts (default true). false = system fonts only. */ webfont?: boolean; /** Stack navigation: when set, the chatroom header shows a back chevron that * calls this. Used by `` so tapping a conversation opens the room and * the back arrow returns to the list — native-app style. */ onBack?: () => void; /** Turn this into a self-contained inbox: the back chevron opens the user's * full thread list IN PLACE (no navigation), and picking a row opens that * thread with a back chevron returning to the list. */ inbox?: boolean; /** Inbox scope: 'tenant' (default) lists the user's threads across ALL your * chatrooms; 'profile' limits to this chatroom. */ inboxScope?: 'tenant' | 'profile'; /** Target language for the 🌐 translate button shown under every incoming * message (via the server's /translate endpoint). Defaults to the guest's * own language (from `locale`/navigator.language) — translation is ON by * default. Set a specific ISO code to force it, or '' to disable. */ translateLang?: string; /** If true, mount as a floating launcher button that opens/closes the chat */ launcher?: boolean; /** Position of the launcher button: default 'bottom-right' */ position?: 'bottom-right' | 'bottom-left'; /** Launcher teaser — the "optional message" card shown ABOVE the closed * launcher button to invite a chat (like Channel.io's greeting). Pass a * string for just a title, or `{ title, subtitle }`. If omitted, the * widget uses `defaults.launcherMessage` from the chatroom manifest when * present. Dismissible by the visitor (remembered for the browser session); * auto-hides once the chat is opened. Only applies in `launcher` mode. */ launcherMessage?: string | { title: string; subtitle?: string; }; /** Optional user info for identified users. When provided, the name/email/ * avatar are shown to agents in the dashboard instead of the anonymous ID. * The token still controls identity — this is display metadata only. * Anonymous users (no token, no user) remain fully anonymous. */ user?: UserInfo; /** Optional per-tenant feature switches. All default to ON (omit for current * behavior). Set a flag to `false` to disable the feature — the widget then * does no work for it (no reaction picker built per message, no CSAT panel, * no KB-deflection lookups). Gating is by not wiring the handler, so the * renderer skips the feature entirely. */ features?: { reactions?: boolean; csat?: boolean; deflection?: boolean; }; /** UI language for built-in strings. A BCP-47 tag ('ko', 'ko-KR'), bare code, * or name. Omit to auto-detect from the visitor's browser (navigator.language). * Currently Korean ⇄ English; anything non-Korean resolves to English. */ locale?: string; /** i18n: override UI strings. All keys are optional — omitted keys use the * built-in dictionary for the resolved `locale` (English by default). */ i18n?: WidgetI18nOverrides; } export interface WidgetHandle { close(): void; } /** Unmount any widget currently mounted on `el`. No-op if nothing is mounted. */ export declare function unmount(el: Element): void; export declare function mount(opts: MountOptions): WidgetHandle; export { ChatStore } from './store.js'; export { ConnectionManager } from './connection.js'; export { Renderer } from './renderer.js'; export { asConversationId }; export { E2ESession, extractX3DHInit, type X3DHBundle } from './e2e.js'; export { PersistentOutbox, type OutboxItem } from './outbox.js'; export { restoreHistory, httpBaseFromWsUrl, resolveRelayUrls } from './history.js';