@mcp-b/char 0.0.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +76 -362
  2. package/dist/custom-elements.json +2180 -0
  3. package/dist/display-mode-policy.d.ts +82 -0
  4. package/dist/display-mode-policy.d.ts.map +1 -0
  5. package/dist/display-mode-policy.js +87 -0
  6. package/dist/display-mode-policy.js.map +1 -0
  7. package/dist/index.d.ts +707 -326
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2370 -15521
  10. package/dist/index.js.map +1 -1
  11. package/dist/shell-component.d.ts +379 -0
  12. package/dist/shell-component.d.ts.map +1 -0
  13. package/dist/shell-component.js +2504 -0
  14. package/dist/shell-component.js.map +1 -0
  15. package/dist/tsdoc-metadata.json +11 -0
  16. package/dist/utils.d.ts +161 -0
  17. package/dist/utils.d.ts.map +1 -0
  18. package/dist/utils.js +393 -0
  19. package/dist/utils.js.map +1 -0
  20. package/dist/web-component-standalone.iife.js +1255 -2358
  21. package/dist/web-component-standalone.iife.js.map +1 -1
  22. package/dist/web-component.d.ts +381 -180
  23. package/dist/web-component.d.ts.map +1 -1
  24. package/dist/web-component.js +1138 -15740
  25. package/dist/web-component.js.map +1 -1
  26. package/package.json +23 -115
  27. package/THIRD_PARTY_NOTICES.md +0 -52
  28. package/dist/VoiceHandoffPanel-CIFIJSDs.js +0 -244
  29. package/dist/VoiceHandoffPanel-CIFIJSDs.js.map +0 -1
  30. package/dist/button-BLnLZvxR.js +0 -105
  31. package/dist/button-BLnLZvxR.js.map +0 -1
  32. package/dist/realtimekit.d.ts +0 -15
  33. package/dist/realtimekit.d.ts.map +0 -1
  34. package/dist/realtimekit.js +0 -89
  35. package/dist/realtimekit.js.map +0 -1
  36. package/dist/styles/globals.css +0 -2
  37. package/dist/styles.d.ts +0 -2
  38. package/dist/web-component-standalone.css +0 -37
  39. package/dist/web-component-standalone.css.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,379 +1,760 @@
1
1
 
2
- import { FC, ReactNode } from "react";
3
- import * as react_jsx_runtime0 from "react/jsx-runtime";
4
- import { CallToolResult, GetPromptResult, Prompt } from "@modelcontextprotocol/sdk/types.js";
5
- import { z } from "zod";
6
-
7
- //#region src/utils/dev-mode.d.ts
2
+ //#region src/types.d.ts
3
+ /**
4
+ * Server-issued ticket auth payload.
5
+ * Used for SSR-friendly authentication flows.
6
+ *
7
+ * @public
8
+ */
9
+ interface TicketAuth {
10
+ /** Short-lived server-issued ticket used to start an authenticated session. */
11
+ ticket: string;
12
+ /** End-user identifier associated with the issued ticket. */
13
+ userId: string;
14
+ /** Organization identifier used to scope the authenticated session. */
15
+ orgId: string;
16
+ }
17
+ /**
18
+ * Development-only embed controls used by local host integrations.
19
+ *
20
+ * @public
21
+ */
8
22
  interface DevModeConfig {
9
- /**
10
- * Your Anthropic API key for chat.
11
- * Required for anonymous mode (no authToken).
12
- */
13
23
  anthropicApiKey?: string;
14
- /** Your OpenAI API key for voice mode (optional) */
15
24
  openaiApiKey?: string;
16
- /** Use window.location.origin instead of production API (for internal development) */
17
25
  useLocalApi?: boolean;
18
26
  }
19
- //#endregion
20
- //#region ../auth/dist/security/ticket.d.ts
21
27
  /**
22
- * Client-side ticket auth data.
23
- * This is what the embedded widget uses for WebSocket authentication.
28
+ * Connection options for the imperative connect() method.
29
+ *
30
+ * Supports two mutually exclusive authentication strategies:
31
+ * - `idToken` + `clientId`: Direct IDP token authentication (SPA-friendly)
32
+ * - `ticketAuth`: Pre-fetched ticket authentication (SSR-friendly)
33
+ *
34
+ * Exactly one strategy must be provided. The discriminated union prevents
35
+ * combining `idToken` and `ticketAuth` at the type level.
36
+ *
37
+ * @public
24
38
  */
25
- interface TicketAuth {
26
- /** The opaque ticket string */
27
- ticket: string;
28
- /** User ID (from token's sub claim) - needed for DO routing */
29
- userId: string;
30
- /** Organization ID - needed for DO routing */
31
- orgId: string;
39
+ type ConnectOptions = {
40
+ /** IDP token (ID token) for authentication. */idToken: string; /** OIDC client ID for audience validation. Required with `idToken`. */
41
+ clientId?: string; /** Optional organization context for multi-tenant same-origin dashboards. */
42
+ organizationId?: string; /** Must not be provided when using `idToken` authentication. */
43
+ ticketAuth?: never;
44
+ } | {
45
+ /** Pre-fetched ticket for SSR-friendly authentication. */ticketAuth: TicketAuth; /** Must not be provided when using `ticketAuth` authentication. */
46
+ idToken?: never; /** Must not be provided when using `ticketAuth` authentication. */
47
+ clientId?: never; /** Must not be provided when using `ticketAuth` authentication. */
48
+ organizationId?: never;
49
+ };
50
+ /**
51
+ * Host visual theme hint.
52
+ *
53
+ * @public
54
+ */
55
+ type CharTheme = 'light' | 'dark';
56
+ /**
57
+ * Allowed display modes for the host shell and embedded runtime.
58
+ *
59
+ * @public
60
+ */
61
+ type CharDisplayMode = 'inline' | 'fullscreen' | 'pip';
62
+ /**
63
+ * Host platform hint for embedded UI adaptations.
64
+ *
65
+ * @public
66
+ */
67
+ type CharPlatform = 'web' | 'desktop' | 'mobile';
68
+ /**
69
+ * Host-provided style payload applied inside the iframe.
70
+ *
71
+ * @public
72
+ */
73
+ interface CharHostStyles {
74
+ variables?: Record<string, string>;
75
+ fonts?: string;
76
+ }
77
+ /**
78
+ * Host container size constraints.
79
+ *
80
+ * @public
81
+ */
82
+ interface CharContainerDimensions {
83
+ width?: number;
84
+ height?: number;
85
+ maxWidth?: number;
86
+ maxHeight?: number;
32
87
  }
33
- //#endregion
34
- //#region ../shared-types/dist/schemas/mcp-client.d.ts
35
88
  /**
36
- * Unified configuration for MCP sources
89
+ * Lightweight device capability hints from the host environment.
90
+ *
91
+ * @public
37
92
  */
38
- declare const MCPSourceConfigSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
39
- type: z.ZodLiteral<"tab">; /** Target origin for postMessage security (default: window.location.origin for same-tab) */
40
- targetOrigin: z.ZodOptional<z.ZodString>; /** Channel ID for the TabClientTransport (default: 'mcp-default') */
41
- channelId: z.ZodOptional<z.ZodString>;
42
- }, "strip", z.ZodTypeAny, {
43
- type: "tab";
44
- targetOrigin?: string | undefined;
45
- channelId?: string | undefined;
46
- }, {
47
- type: "tab";
48
- targetOrigin?: string | undefined;
49
- channelId?: string | undefined;
50
- }>, z.ZodObject<{
51
- type: z.ZodLiteral<"http">; /** Server URL */
52
- url: z.ZodString; /** Optional authentication token (Bearer) */
53
- authToken: z.ZodOptional<z.ZodString>; /** Connection timeout in milliseconds (default: 30000) */
54
- timeout: z.ZodOptional<z.ZodNumber>; /** Auto-reconnect on disconnect (default: true) */
55
- autoReconnect: z.ZodOptional<z.ZodBoolean>;
56
- /**
57
- * Transport type preference:
58
- * - 'auto': Try HTTP first, fallback to SSE (default)
59
- * - 'http': HTTP Streamable transport only
60
- * - 'sse': Server-Sent Events transport only
61
- */
62
- transportType: z.ZodOptional<z.ZodEnum<["auto", "http", "sse"]>>; /** Custom headers to include in requests */
63
- customHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
64
- }, "strip", z.ZodTypeAny, {
65
- type: "http";
66
- url: string;
67
- authToken?: string | undefined;
68
- timeout?: number | undefined;
69
- autoReconnect?: boolean | undefined;
70
- transportType?: "auto" | "http" | "sse" | undefined;
71
- customHeaders?: Record<string, string> | undefined;
72
- }, {
73
- type: "http";
74
- url: string;
75
- authToken?: string | undefined;
76
- timeout?: number | undefined;
77
- autoReconnect?: boolean | undefined;
78
- transportType?: "auto" | "http" | "sse" | undefined;
79
- customHeaders?: Record<string, string> | undefined;
80
- }>]>;
81
- type MCPSourceConfig = z.infer<typeof MCPSourceConfigSchema>;
93
+ interface CharDeviceCapabilities {
94
+ touch?: boolean;
95
+ hover?: boolean;
96
+ pointerFine?: boolean;
97
+ }
82
98
  /**
83
- * Tool with source tracking for multi-source tool management.
84
- * The _sourceId identifies which client to route tool calls to.
99
+ * Safe-area inset values detected on the host.
85
100
  *
86
- * This extends the MCP SDK Tool interface shape.
101
+ * @public
87
102
  */
88
- declare const ToolWithSourceSchema: z.ZodObject<{
89
- name: z.ZodString;
90
- description: z.ZodOptional<z.ZodString>;
91
- inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
92
- annotations: z.ZodOptional<z.ZodObject<{
93
- title: z.ZodOptional<z.ZodString>;
94
- readOnlyHint: z.ZodOptional<z.ZodBoolean>;
95
- destructiveHint: z.ZodOptional<z.ZodBoolean>;
96
- idempotentHint: z.ZodOptional<z.ZodBoolean>;
97
- openWorldHint: z.ZodOptional<z.ZodBoolean>;
98
- }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
99
- title: z.ZodOptional<z.ZodString>;
100
- readOnlyHint: z.ZodOptional<z.ZodBoolean>;
101
- destructiveHint: z.ZodOptional<z.ZodBoolean>;
102
- idempotentHint: z.ZodOptional<z.ZodBoolean>;
103
- openWorldHint: z.ZodOptional<z.ZodBoolean>;
104
- }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
105
- title: z.ZodOptional<z.ZodString>;
106
- readOnlyHint: z.ZodOptional<z.ZodBoolean>;
107
- destructiveHint: z.ZodOptional<z.ZodBoolean>;
108
- idempotentHint: z.ZodOptional<z.ZodBoolean>;
109
- openWorldHint: z.ZodOptional<z.ZodBoolean>;
110
- }, z.ZodTypeAny, "passthrough">>>; /** Source identifier - 'local' for useWebMCP, 'remote' for remote MCP, or iframe/tab ID */
111
- _sourceId: z.ZodString;
112
- }, "strip", z.ZodTypeAny, {
113
- name: string;
114
- _sourceId: string;
115
- description?: string | undefined;
116
- inputSchema?: Record<string, unknown> | undefined;
117
- annotations?: z.objectOutputType<{
118
- title: z.ZodOptional<z.ZodString>;
119
- readOnlyHint: z.ZodOptional<z.ZodBoolean>;
120
- destructiveHint: z.ZodOptional<z.ZodBoolean>;
121
- idempotentHint: z.ZodOptional<z.ZodBoolean>;
122
- openWorldHint: z.ZodOptional<z.ZodBoolean>;
123
- }, z.ZodTypeAny, "passthrough"> | undefined;
124
- }, {
125
- name: string;
126
- _sourceId: string;
127
- description?: string | undefined;
128
- inputSchema?: Record<string, unknown> | undefined;
129
- annotations?: z.objectInputType<{
130
- title: z.ZodOptional<z.ZodString>;
131
- readOnlyHint: z.ZodOptional<z.ZodBoolean>;
132
- destructiveHint: z.ZodOptional<z.ZodBoolean>;
133
- idempotentHint: z.ZodOptional<z.ZodBoolean>;
134
- openWorldHint: z.ZodOptional<z.ZodBoolean>;
135
- }, z.ZodTypeAny, "passthrough"> | undefined;
136
- }>;
137
- type ToolWithSource = z.infer<typeof ToolWithSourceSchema>;
103
+ interface CharSafeAreaInsets {
104
+ top?: number;
105
+ right?: number;
106
+ bottom?: number;
107
+ left?: number;
108
+ }
138
109
  /**
139
- * State of an MCP source connection.
110
+ * Host shell capability flags advertised to the iframe runtime.
140
111
  *
141
- * Note: This schema uses z.unknown() for arrays of SDK types (Tool, Resource, etc.)
142
- * because we don't want to re-define those schemas here. Runtime validation
143
- * of these arrays should be done at the boundary where SDK types are received.
112
+ * @public
144
113
  */
145
- declare const MCPSourceSchema: z.ZodObject<{
146
- /** Unique identifier for this source */id: z.ZodString; /** Configuration used to create this source */
147
- config: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
148
- type: z.ZodLiteral<"tab">; /** Target origin for postMessage security (default: window.location.origin for same-tab) */
149
- targetOrigin: z.ZodOptional<z.ZodString>; /** Channel ID for the TabClientTransport (default: 'mcp-default') */
150
- channelId: z.ZodOptional<z.ZodString>;
151
- }, "strip", z.ZodTypeAny, {
152
- type: "tab";
153
- targetOrigin?: string | undefined;
154
- channelId?: string | undefined;
155
- }, {
156
- type: "tab";
157
- targetOrigin?: string | undefined;
158
- channelId?: string | undefined;
159
- }>, z.ZodObject<{
160
- type: z.ZodLiteral<"http">; /** Server URL */
161
- url: z.ZodString; /** Optional authentication token (Bearer) */
162
- authToken: z.ZodOptional<z.ZodString>; /** Connection timeout in milliseconds (default: 30000) */
163
- timeout: z.ZodOptional<z.ZodNumber>; /** Auto-reconnect on disconnect (default: true) */
164
- autoReconnect: z.ZodOptional<z.ZodBoolean>;
165
- /**
166
- * Transport type preference:
167
- * - 'auto': Try HTTP first, fallback to SSE (default)
168
- * - 'http': HTTP Streamable transport only
169
- * - 'sse': Server-Sent Events transport only
170
- */
171
- transportType: z.ZodOptional<z.ZodEnum<["auto", "http", "sse"]>>; /** Custom headers to include in requests */
172
- customHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
173
- }, "strip", z.ZodTypeAny, {
174
- type: "http";
175
- url: string;
176
- authToken?: string | undefined;
177
- timeout?: number | undefined;
178
- autoReconnect?: boolean | undefined;
179
- transportType?: "auto" | "http" | "sse" | undefined;
180
- customHeaders?: Record<string, string> | undefined;
181
- }, {
182
- type: "http";
183
- url: string;
184
- authToken?: string | undefined;
185
- timeout?: number | undefined;
186
- autoReconnect?: boolean | undefined;
187
- transportType?: "auto" | "http" | "sse" | undefined;
188
- customHeaders?: Record<string, string> | undefined;
189
- }>]>; /** Connection state */
190
- state: z.ZodEnum<["idle", "connecting", "connected", "error"]>; /** Connection error message (if any) */
191
- error: z.ZodNullable<z.ZodString>; /** Tools available from this source */
192
- tools: z.ZodArray<z.ZodUnknown, "many">; /** Resources available from this source */
193
- resources: z.ZodArray<z.ZodUnknown, "many">; /** Resource templates available from this source */
194
- resourceTemplates: z.ZodArray<z.ZodUnknown, "many">; /** Prompts available from this source */
195
- prompts: z.ZodArray<z.ZodUnknown, "many">;
196
- }, "strip", z.ZodTypeAny, {
197
- id: string;
198
- error: string | null;
199
- config: {
200
- type: "tab";
201
- targetOrigin?: string | undefined;
202
- channelId?: string | undefined;
203
- } | {
204
- type: "http";
205
- url: string;
206
- authToken?: string | undefined;
207
- timeout?: number | undefined;
208
- autoReconnect?: boolean | undefined;
209
- transportType?: "auto" | "http" | "sse" | undefined;
210
- customHeaders?: Record<string, string> | undefined;
211
- };
212
- state: "idle" | "connecting" | "connected" | "error";
213
- tools: unknown[];
214
- resources: unknown[];
215
- resourceTemplates: unknown[];
216
- prompts: unknown[];
217
- }, {
218
- id: string;
219
- error: string | null;
220
- config: {
221
- type: "tab";
222
- targetOrigin?: string | undefined;
223
- channelId?: string | undefined;
224
- } | {
225
- type: "http";
226
- url: string;
227
- authToken?: string | undefined;
228
- timeout?: number | undefined;
229
- autoReconnect?: boolean | undefined;
230
- transportType?: "auto" | "http" | "sse" | undefined;
231
- customHeaders?: Record<string, string> | undefined;
232
- };
233
- state: "idle" | "connecting" | "connected" | "error";
234
- tools: unknown[];
235
- resources: unknown[];
236
- resourceTemplates: unknown[];
237
- prompts: unknown[];
238
- }>;
239
- type MCPSource = z.infer<typeof MCPSourceSchema>;
240
- //#endregion
241
- //#region src/providers/MCPToolsProvider.d.ts
114
+ interface CharHostCapabilities {
115
+ supportedDisplayModes?: CharDisplayMode[];
116
+ supportsOpenLink?: boolean;
117
+ supportsTeardown?: boolean;
118
+ maxContainerWidth?: number;
119
+ }
120
+ /**
121
+ * Host context payload sent from the embedding page to the iframe runtime.
122
+ *
123
+ * @public
124
+ */
125
+ interface CharHostContext {
126
+ theme?: CharTheme;
127
+ styles?: CharHostStyles;
128
+ displayMode?: CharDisplayMode;
129
+ availableDisplayModes?: CharDisplayMode[];
130
+ containerDimensions?: CharContainerDimensions;
131
+ locale?: string;
132
+ timeZone?: string;
133
+ platform?: CharPlatform;
134
+ deviceCapabilities?: CharDeviceCapabilities;
135
+ safeAreaInsets?: CharSafeAreaInsets;
136
+ userAgent?: string;
137
+ hostCapabilities?: CharHostCapabilities;
138
+ }
139
+ /**
140
+ * Payload for the `char-size-changed` event.
141
+ *
142
+ * @public
143
+ */
144
+ interface CharSizeChangedDetail {
145
+ width?: number;
146
+ height?: number;
147
+ displayMode?: CharDisplayMode;
148
+ }
242
149
  /**
243
- * MCP Tools Context Value
150
+ * Payload for the `char-request-display-mode` event.
151
+ *
152
+ * @public
244
153
  */
245
- interface MCPToolsContextValue {
246
- /** All tools from all sources, tagged with _sourceId */
247
- tools: ToolWithSource[];
248
- /** All prompts from all sources */
249
- prompts: Prompt[];
250
- /** All sources and their states */
251
- sources: Map<string, MCPSource>;
252
- /** Add a new source */
253
- addSource: (id: string, config: MCPSourceConfig) => Promise<void>;
254
- /** Remove a source */
255
- removeSource: (id: string) => Promise<void>;
256
- /** Get a specific source */
257
- getSource: (id: string) => MCPSource | undefined;
258
- /** Check if a source is connected */
259
- isConnected: (id: string) => boolean;
260
- /** Call a tool (auto-routes based on tool name lookup) */
261
- callTool: (name: string, args: Record<string, unknown>) => Promise<CallToolResult>;
262
- /** Call a tool on a specific source */
263
- callToolOnSource: (sourceId: string, name: string, args: Record<string, unknown>) => Promise<CallToolResult>;
264
- /** Get a prompt's expanded content (auto-routes based on prompt name lookup) */
265
- getPrompt: (name: string, args?: Record<string, string>) => Promise<GetPromptResult>;
266
- /**
267
- * Refresh tools from all connected sources.
268
- * Call this after dynamically registering tools via useWebMCP inside the provider tree.
269
- */
270
- refreshTools: () => Promise<void>;
154
+ interface CharRequestDisplayModeDetail {
155
+ mode?: CharDisplayMode;
271
156
  }
272
- interface MCPToolsProviderProps {
273
- children: ReactNode;
274
- /** Auto-connect to same-tab source on mount (default: true) */
275
- autoConnectLocal?: boolean;
276
- /** Callback when tools change */
277
- onToolsChange?: (tools: ToolWithSource[]) => void;
278
- /** Callback when prompts change */
279
- onPromptsChange?: (prompts: Prompt[]) => void;
157
+ /**
158
+ * Payload for the `char-error` event.
159
+ *
160
+ * @public
161
+ */
162
+ interface CharErrorDetail {
163
+ code: string;
164
+ message?: string;
280
165
  }
281
- declare function MCPToolsProvider({
282
- children,
283
- autoConnectLocal,
284
- onToolsChange,
285
- onPromptsChange
286
- }: MCPToolsProviderProps): react_jsx_runtime0.JSX.Element;
287
166
  /**
288
- * Hook to access MCP Tools context
167
+ * Payload for the `char-open-link` event.
168
+ *
169
+ * @public
289
170
  */
290
- declare function useMCPTools(): MCPToolsContextValue;
171
+ interface CharOpenLinkDetail {
172
+ requestId: string;
173
+ url: string;
174
+ ok: boolean;
175
+ }
291
176
  //#endregion
292
- //#region src/index.d.ts
177
+ //#region src/web-component.d.ts
293
178
  /**
294
- * Props for the Char component
179
+ * `<char-agent>` custom element.
180
+ *
181
+ * Creates an iframe pointing to the SaaS app's /embed/ entrypoint and relays
182
+ * auth, styles, dark mode, display mode, and MCP messages via postMessage.
183
+ *
184
+ * Uses a unified `char-context` message with diffing (only changed fields
185
+ * are sent) instead of separate messages per concern.
186
+ *
187
+ * @public
295
188
  */
296
- interface CharProps {
189
+ declare class CharAgentElement extends HTMLElement {
190
+ static observedAttributes: string[];
191
+ /**
192
+ * React 19-friendly property form of `dev-mode`.
193
+ * Read once during `connectedCallback`.
194
+ */
195
+ devMode?: DevModeConfig;
196
+ /**
197
+ * React 19-friendly property form of `api-base`.
198
+ * Read once during `connectedCallback`.
199
+ */
200
+ apiBase?: string;
201
+ /** Active iframe element owned by this custom element instance. */
202
+ private _iframe;
203
+ /** MCP relay between host window and embed iframe. */
204
+ private _proxy;
205
+ /** Indicates whether the iframe has emitted `char-ready`. */
206
+ private _iframeReady;
207
+ /** Bound window message handler for iframe-originated events. */
208
+ private _messageListener;
209
+ /** Observer that tracks host theme mutations. */
210
+ private _darkModeObserver;
211
+ /** Media query object for `prefers-color-scheme`. */
212
+ private _darkModeMediaQuery;
213
+ /** Registered media query callback. */
214
+ private _darkModeMediaHandler;
215
+ /** Observer that tracks host style/class mutations. */
216
+ private _styleObserver;
217
+ /** Observer that tracks container size changes. */
218
+ private _containerResizeObserver;
219
+ /** In-flight teardown request waiting for iframe acknowledgement. */
220
+ private _teardownPending;
221
+ /** Monotonic sequence used to construct teardown request IDs. */
222
+ private _teardownSequence;
223
+ /** Re-entrancy guard used during disconnect lifecycle. */
224
+ private _isDisconnecting;
225
+ /** Last host context snapshot used for delta emission. */
226
+ private _hostContext;
227
+ /** Pending credentials that are flushed when the iframe is ready. */
228
+ private _pendingAuth;
229
+ /**
230
+ * Mount lifecycle: builds iframe runtime, starts proxying, and starts host observers.
231
+ * The existing runtime is reused when reconnecting during fast detach/reattach cycles.
232
+ */
233
+ connectedCallback(): void;
234
+ /**
235
+ * Determines whether this instance already has an initialized runtime.
236
+ */
237
+ private _hasActiveRuntime;
238
+ /**
239
+ * Parses and validates the iframe origin from the configured API base URL.
240
+ *
241
+ * @throws Error When `apiBase` is not a valid URL.
242
+ */
243
+ private _resolveIframeOrigin;
244
+ /**
245
+ * Creates a fully configured iframe element for the embed runtime.
246
+ */
247
+ private _createIframe;
248
+ /**
249
+ * Creates the message listener that filters by source/origin and dispatches typed events.
250
+ */
251
+ private _createMessageListener;
252
+ /**
253
+ * Routes validated iframe messages to local handlers and host DOM events.
254
+ */
255
+ private _handleIframeMessage;
256
+ /**
257
+ * Emits a host-facing custom event without detail payload.
258
+ */
259
+ private _emitCharEvent;
260
+ /**
261
+ * Emits a host-facing custom event with detail payload.
262
+ */
263
+ private _emitCharEventWithDetail;
264
+ /**
265
+ * Emits a standardized `char-error` event.
266
+ */
267
+ private _emitCharError;
268
+ /**
269
+ * Unmount lifecycle: requests iframe teardown and releases all host resources.
270
+ */
271
+ disconnectedCallback(): void;
272
+ /**
273
+ * Releases iframe, observers, listeners, and pending teardown state.
274
+ */
275
+ private _finalizeDisconnect;
276
+ /**
277
+ * Reacts to observed attribute updates after iframe readiness.
278
+ * Attributes that affect iframe boot configuration are intentionally ignored
279
+ * after mount (`dev-mode`, `enable-debug-tools`, `api-base`).
280
+ */
281
+ attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
282
+ /**
283
+ * Connect to the Char agent with authentication.
284
+ *
285
+ * The token is stored as a JavaScript property (not as a DOM attribute),
286
+ * preventing exposure to DOM inspection and session replay tools.
287
+ *
288
+ * @param options - Authentication payload for either ID token or ticket auth.
289
+ * @returns `true` when the payload is accepted; `false` when validation fails.
290
+ */
291
+ connect(options: ConnectOptions): boolean;
292
+ /**
293
+ * Convenience method for declarative wrappers.
294
+ * Applies auth when provided, otherwise clears auth.
295
+ *
296
+ * @param options - Auth payload to connect, or `null` to disconnect.
297
+ * @returns Result from `connect()` or `disconnect()`.
298
+ */
299
+ setAuth(options: ConnectOptions | null): boolean;
300
+ /**
301
+ * Disconnect from the Char agent.
302
+ * Clears the authentication token.
303
+ *
304
+ * @returns `true` when the disconnect message was sent; `false` when the iframe was not ready.
305
+ */
306
+ disconnect(): boolean;
307
+ /**
308
+ * Resolves the current iframe origin when mounted.
309
+ */
310
+ private _getIframeOrigin;
311
+ /**
312
+ * Update the host context sent to the iframe.
313
+ * Only changed fields are transmitted (diffing pattern).
314
+ *
315
+ * @param hostContext - Partial host context patch to merge and emit.
316
+ */
317
+ setHostContext(hostContext: CharHostContext): void;
318
+ /**
319
+ * Build and send the full initial context after iframe signals char-ready.
320
+ *
321
+ * @param iframeOrigin - Trusted origin used for postMessage target filtering.
322
+ */
323
+ private _sendInitialContext;
297
324
  /**
298
- * IDP token for SSO-first authentication.
325
+ * Send a context delta to the iframe.
299
326
  *
300
- * Pass your existing IDP token (from Okta, Azure AD, Auth0, Google, etc.)
301
- * and the backend will validate it against your organization's configured IDP.
327
+ * @param changes - Minimal context patch derived from diffing.
328
+ */
329
+ private _sendContextDelta;
330
+ /**
331
+ * Post authentication credentials to the iframe.
302
332
  *
303
- * When provided:
304
- * - Messages persist across refreshes (Cloudflare Durable Objects)
305
- * - User ID extracted from token's sub claim
306
- * - Tools shared across all your organization's apps
333
+ * @param iframeOrigin - Trusted origin used for postMessage target filtering.
334
+ */
335
+ private _postAuth;
336
+ /**
337
+ * Requests graceful iframe teardown and resolves once acknowledged or timed out.
307
338
  *
308
- * When NOT provided:
309
- * - Anonymous mode with Durable Objects
310
- * - Requires anthropicApiKey for AI calls
311
- * - Localhost-only for security
339
+ * @param iframeOrigin - Trusted origin used for postMessage target filtering.
340
+ * @param reason - Lifecycle reason for teardown.
341
+ * @returns Promise resolved when teardown flow completes.
312
342
  */
313
- authToken?: string;
343
+ private _requestTeardown;
314
344
  /**
315
- * OIDC client ID for audience validation.
316
- * Required when using `authToken` authentication.
345
+ * Completes an in-flight teardown promise when the iframe acknowledges it.
317
346
  *
318
- * This must match the token's `aud` claim and be in the organization's
319
- * `allowed_audiences` list (configured in the Char dashboard).
347
+ * @param requestId - Optional request identifier to match against pending teardown.
320
348
  */
321
- clientId?: string;
349
+ private _resolvePendingTeardown;
322
350
  /**
323
- * Pre-fetched ticket for SSR-friendly authentication.
351
+ * Handles open-link requests from the iframe with protocol allowlisting.
352
+ * This allowlist intentionally mirrors the iframe-side pre-filter.
324
353
  *
325
- * Benefits:
326
- * - IDP token never exposed to browser (in SSR mode)
327
- * - No JWKS fetch on every connection (validation done once)
328
- * - Ticket is short-lived (60s default) and single-use
354
+ * @param requestId - Link request identifier supplied by the iframe.
355
+ * @param url - Requested URL string.
356
+ * @param iframeOrigin - Trusted origin used for postMessage target filtering.
357
+ */
358
+ private _handleOpenLinkRequest;
359
+ /**
360
+ * Observe dark mode changes and forward to iframe via unified context.
329
361
  */
330
- ticketAuth?: TicketAuth;
362
+ private _observeDarkMode;
331
363
  /**
332
- * Controlled open state.
333
- * When provided, the host controls whether the agent UI is open or collapsed.
364
+ * Observe style attribute changes on <char-agent> to detect CSS variable updates.
365
+ * Re-extracts variables and sends delta via unified context.
334
366
  */
335
- open?: boolean;
367
+ private _observeStyleChanges;
336
368
  /**
337
- * Additional CSS class name for the container.
338
- * Useful for applying custom container styles.
369
+ * Observe host element dimensions to provide containerDimensions context.
339
370
  */
340
- className?: string;
371
+ private _observeContainerDimensions;
341
372
  /**
342
- * Callback when the close button is clicked.
343
- * Use this to control visibility from the host app.
373
+ * Resolve devMode from property (React 19) or attribute.
374
+ *
375
+ * @returns Parsed dev-mode configuration when valid.
344
376
  */
345
- onClose?: () => void;
377
+ private _resolveDevMode;
346
378
  /**
347
- * Development mode - use your own API keys for testing.
348
- * In production, leave this undefined to use your WebMCP plan.
379
+ * Resolve apiBase override from property (React 19) or attribute.
380
+ *
381
+ * @returns Sanitized API base URL without trailing slash.
349
382
  */
383
+ private _resolveApiBaseOverride;
384
+ }
385
+ /**
386
+ * Type declaration for the Char custom element.
387
+ * Useful for TypeScript consumers using refs.
388
+ *
389
+ * @public
390
+ */
391
+ /**
392
+ * Legacy alias for `CharAgentElement`.
393
+ *
394
+ * @public
395
+ */
396
+ type CharElement = CharAgentElement;
397
+ /**
398
+ * Backward-compatible alias for `CharAgentElement`.
399
+ *
400
+ * @public
401
+ */
402
+ type WebMCPAgentElement = CharAgentElement;
403
+ /**
404
+ * Register the <char-agent> custom element.
405
+ * Called automatically when importing this module.
406
+ *
407
+ * @param tagName - Optional custom tag name override.
408
+ *
409
+ * @public
410
+ */
411
+ declare function registerChar(tagName?: string): void;
412
+ declare global {
413
+ interface HTMLElementTagNameMap {
414
+ 'char-agent': CharAgentElement;
415
+ }
416
+ namespace JSX {
417
+ interface IntrinsicElements {
418
+ 'char-agent': {
419
+ /** Development mode configuration (JSON string for HTML attributes). */'dev-mode'?: string; /** Property form of dev mode config. */
420
+ devMode?: DevModeConfig; /** Explicit API base override, e.g. `https://staging-app.usechar.ai`. */
421
+ 'api-base'?: string; /** Property form of API base override. */
422
+ apiBase?: string; /** Enable debug tools for inspecting embedded agent internal state. */
423
+ 'enable-debug-tools'?: boolean; /** Display mode for host orchestration: `pip` is collapsed launcher mode. */
424
+ 'display-mode'?: CharDisplayMode; /** Callback when the close button inside the agent panel is clicked. */
425
+ onClose?: () => void; /** Imperative ref to the custom element instance. */
426
+ ref?: unknown;
427
+ [key: string]: unknown;
428
+ };
429
+ }
430
+ }
431
+ }
432
+ declare module 'react/jsx-runtime' {
433
+ namespace JSX {
434
+ interface IntrinsicElements {
435
+ 'char-agent': {
436
+ 'dev-mode'?: string;
437
+ devMode?: DevModeConfig;
438
+ 'api-base'?: string;
439
+ apiBase?: string;
440
+ 'enable-debug-tools'?: boolean;
441
+ 'display-mode'?: CharDisplayMode;
442
+ onClose?: () => void;
443
+ ref?: unknown;
444
+ [key: string]: unknown;
445
+ };
446
+ }
447
+ }
448
+ } //# sourceMappingURL=web-component.d.ts.map
449
+ //#endregion
450
+ //#region src/shell-component.d.ts
451
+ /**
452
+ * Allowed positions for the collapsed PIP composer surface.
453
+ *
454
+ * @public
455
+ */
456
+ type CharPipPosition = 'bottom-center' | 'bottom-right' | 'bottom-left';
457
+ /**
458
+ * Payload for `char-shell-open-change`.
459
+ *
460
+ * @public
461
+ */
462
+ interface CharShellOpenChangeDetail {
463
+ open: boolean;
464
+ }
465
+ /**
466
+ * `<char-agent-shell>` custom element.
467
+ *
468
+ * Opinionated host shell that composes a persistent inner `<char-agent>` and
469
+ * owns responsive mode policy plus host layout orchestration.
470
+ * This shell does not render chat controls, prompts, or composer UI.
471
+ * Visible assistant UI is always iframe-owned.
472
+ *
473
+ * Policy:
474
+ * - closed to `pip`
475
+ * - open desktop to `inline`
476
+ * - open narrow viewport to `fullscreen`
477
+ *
478
+ * @public
479
+ */
480
+ declare class CharAgentShellElement extends HTMLElement {
481
+ static observedAttributes: string[];
350
482
  devMode?: DevModeConfig;
483
+ apiBase?: string;
484
+ private _agent;
485
+ private _open;
486
+ private _fullscreenBreakpoint;
487
+ private _panelWidth;
488
+ private _pipWidth;
489
+ private _pipHeight;
490
+ private _pipPosition;
491
+ private _isNarrowViewport;
492
+ private _mediaQuery;
493
+ private _mediaQueryHandler;
494
+ private _pendingConnectOptions;
495
+ private _pendingHostContext;
496
+ private _isApplyingOpenAttribute;
497
+ private _forwardedListenersAttached;
498
+ private _healthState;
499
+ private _healthTimeoutId;
500
+ private _pipMeasuredHeight;
501
+ private _revealFrameId;
502
+ private _pipExpanded;
503
+ private _pipPillElement;
504
+ private _pipCollapseTimerId;
505
+ private _hoverMediaQuery;
506
+ private _pipListenersAttached;
507
+ private _pipAnimating;
508
+ private _pipAnimationTimeoutId;
509
+ private _pendingPipMeasuredHeight;
510
+ private _tapOutsideListener;
511
+ private _pipHiddenByScroll;
512
+ private _scrollListener;
513
+ private _scrollRafId;
514
+ private _lastScrollEl;
515
+ private _lastScrollTop;
516
+ private _scrollDelta;
517
+ private _swipeTouchStartY;
518
+ private _swipeStartAtTop;
519
+ private _swipeStartAtBottom;
520
+ private _swipeTouchStartListener;
521
+ private _swipeTouchEndListener;
522
+ private _wheelListener;
523
+ private _wheelDelta;
524
+ get open(): boolean;
525
+ set open(value: boolean);
526
+ get fullscreenBreakpoint(): number;
527
+ set fullscreenBreakpoint(value: number);
528
+ get panelWidth(): number;
529
+ set panelWidth(value: number);
530
+ get pipWidth(): number;
531
+ set pipWidth(value: number);
532
+ get pipHeight(): number;
533
+ set pipHeight(value: number);
534
+ get pipPosition(): CharPipPosition;
535
+ set pipPosition(value: CharPipPosition);
536
+ connectedCallback(): void;
537
+ disconnectedCallback(): void;
538
+ attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
539
+ /**
540
+ * Connects shell authentication and starts availability health checks.
541
+ *
542
+ * @param options - Authentication payload for either ID token or ticket auth.
543
+ * @returns `true` when connect is accepted by the inner element.
544
+ */
545
+ connect(options: ConnectOptions): boolean;
546
+ /**
547
+ * Clears authentication and disconnects the inner `<char-agent>`.
548
+ *
549
+ * @returns `true` when disconnect dispatch succeeds.
550
+ */
551
+ disconnect(): boolean;
552
+ /**
553
+ * Convenience method for declarative wrappers.
554
+ * Applies auth when provided, otherwise clears auth.
555
+ *
556
+ * @param options - Auth payload to connect, or `null` to disconnect.
557
+ * @returns Result from `connect()` or `disconnect()`.
558
+ */
559
+ setAuth(options: ConnectOptions | null): boolean;
560
+ /**
561
+ * Merges and forwards host context to the inner `<char-agent>`.
562
+ * Shell-owned fields (`displayMode`, `availableDisplayModes`) are ignored.
563
+ *
564
+ * @param hostContext - Partial host context patch to forward.
565
+ */
566
+ setHostContext(hostContext: CharHostContext): void;
567
+ /**
568
+ * Sets shell open state.
569
+ *
570
+ * @param open - Next desired open state.
571
+ */
572
+ setOpen(open: boolean): void;
351
573
  /**
352
- * Enable debug tools for inspecting embedded agent internal state.
353
- * @default false
574
+ * Toggles shell open state.
354
575
  */
355
- enableDebugTools?: boolean;
576
+ toggleOpen(): void;
577
+ private _upgradeProperty;
578
+ private _ensureAgent;
579
+ private _primeAgentBootConfig;
580
+ private _attachForwardedListeners;
581
+ private _detachForwardedListeners;
582
+ private _readConfigFromAttributes;
583
+ private _syncForwardedAttributes;
584
+ private _setupViewportObserver;
585
+ private _teardownViewportObserver;
586
+ private _applyDisplayModeAndLayout;
587
+ private _applyHostLayout;
588
+ private _composePipTransform;
589
+ private _applyAgentLayout;
590
+ private _ensurePipPill;
591
+ private _updatePipPillPosition;
592
+ private _applyPipVisualState;
593
+ private _setPipExpanded;
594
+ private _flushPendingPipMeasuredHeight;
595
+ private _isHoverDevice;
596
+ private _attachPipInteractionListeners;
597
+ private _detachPipInteractionListeners;
598
+ private _schedulePipCollapse;
599
+ private _clearPipCollapseTimer;
600
+ private _attachTapOutsideListener;
601
+ private _detachTapOutsideListener;
602
+ private _handlePipPointerEnter;
603
+ private _handlePipPointerLeave;
604
+ private _attachScrollHideListener;
605
+ private _evaluateScrollPosition;
606
+ private _detachScrollHideListener;
607
+ private _attachSwipeGestureListeners;
608
+ private _detachSwipeGestureListeners;
609
+ private _attachWheelFallbackListener;
610
+ private _detachWheelFallbackListener;
611
+ private _handlePillClick;
612
+ private _handlePillKeydown;
613
+ private _hidePipPill;
614
+ private _resetHostLayoutStyles;
615
+ private _resetAgentLayoutStyles;
616
+ private _applyUnavailableLayout;
617
+ private _applyPreReadyLayout;
618
+ private _startHealthWait;
619
+ private _stopHealthWait;
620
+ private _markHealthy;
621
+ private _cancelRevealFade;
622
+ private _startRevealFade;
623
+ private _setUnavailable;
624
+ private _recoverFromUnavailable;
625
+ private _setOpenInternal;
626
+ private _reflectOpenAttribute;
627
+ private _flushPendingConnectAndContext;
628
+ private _handleRequestDisplayMode;
629
+ private _handleClose;
630
+ private _handleInitialized;
631
+ private _handleInnerError;
632
+ private _handleInnerSizeChanged;
633
+ }
634
+ /**
635
+ * Registers the `<char-agent-shell>` custom element.
636
+ *
637
+ * @param tagName - Optional custom tag name override.
638
+ *
639
+ * @public
640
+ */
641
+ declare function registerCharShell(tagName?: string): void;
642
+ declare global {
643
+ interface HTMLElementTagNameMap {
644
+ 'char-agent-shell': CharAgentShellElement;
645
+ }
646
+ namespace JSX {
647
+ interface IntrinsicElements {
648
+ 'char-agent-shell': {
649
+ open?: boolean;
650
+ 'fullscreen-breakpoint'?: number;
651
+ 'panel-width'?: number;
652
+ 'pip-position'?: CharPipPosition;
653
+ 'pip-width'?: number;
654
+ 'pip-height'?: number;
655
+ 'dev-mode'?: string;
656
+ devMode?: DevModeConfig;
657
+ 'api-base'?: string;
658
+ apiBase?: string;
659
+ 'enable-debug-tools'?: boolean;
660
+ ref?: unknown;
661
+ [key: string]: unknown;
662
+ };
663
+ }
664
+ }
356
665
  }
666
+ declare module 'react/jsx-runtime' {
667
+ namespace JSX {
668
+ interface IntrinsicElements {
669
+ 'char-agent-shell': {
670
+ open?: boolean;
671
+ 'fullscreen-breakpoint'?: number;
672
+ 'panel-width'?: number;
673
+ 'pip-position'?: CharPipPosition;
674
+ 'pip-width'?: number;
675
+ 'pip-height'?: number;
676
+ 'dev-mode'?: string;
677
+ devMode?: DevModeConfig;
678
+ 'api-base'?: string;
679
+ apiBase?: string;
680
+ 'enable-debug-tools'?: boolean;
681
+ ref?: unknown;
682
+ [key: string]: unknown;
683
+ };
684
+ }
685
+ }
686
+ } //# sourceMappingURL=shell-component.d.ts.map
687
+ //#endregion
688
+ //#region src/display-mode-policy.d.ts
689
+ /**
690
+ * Default display modes advertised by Char hosts.
691
+ *
692
+ * Order matters for fallback behavior. When a preferred mode is unavailable,
693
+ * the first available mode is selected.
694
+ *
695
+ * @public
696
+ */
697
+ declare const DEFAULT_AVAILABLE_DISPLAY_MODES: readonly ["inline", "fullscreen", "pip"];
698
+ /**
699
+ * Runtime guard for Char display mode values.
700
+ *
701
+ * @param value - Raw value from host attributes, events, or external input.
702
+ * @returns `true` when the value is one of `inline`, `fullscreen`, or `pip`.
703
+ *
704
+ * @public
705
+ */
706
+ declare function isDisplayMode(value: string | null | undefined): value is CharDisplayMode;
707
+ /**
708
+ * Checks whether a display mode represents an expanded agent surface.
709
+ *
710
+ * Expanded modes are:
711
+ * - `inline` (panel-style)
712
+ * - `fullscreen` (viewport-filling)
713
+ *
714
+ * Collapsed mode is:
715
+ * - `pip` (launcher-only)
716
+ *
717
+ * @param mode - Current display mode from host context.
718
+ * @returns `true` for expanded modes and `false` for collapsed/undefined modes.
719
+ *
720
+ * @public
721
+ */
722
+ declare function isExpandedDisplayMode(mode: CharDisplayMode | undefined): boolean;
723
+ /**
724
+ * Resolves a preferred display mode against host-supported modes.
725
+ *
726
+ * An empty `availableModes` array means "no constraint" — the preferred mode
727
+ * is returned unconditionally. This is intentional: it allows callers to opt
728
+ * out of mode filtering without a separate code path.
729
+ *
730
+ * @param preferred - Preferred mode requested by host policy.
731
+ * @param availableModes - Supported modes advertised by the host.
732
+ * @returns Preferred mode when supported, otherwise the first available mode.
733
+ *
734
+ * @public
735
+ */
736
+ declare function resolveSupportedDisplayMode(preferred: CharDisplayMode, availableModes?: readonly CharDisplayMode[]): CharDisplayMode;
357
737
  /**
358
- * Char - Drop-in AI chat widget for React
359
- *
360
- * A fully self-contained chat widget with:
361
- * - SSO-first authentication (use your existing IDP token)
362
- * - MCP tool support (connect to any MCP server)
363
- * - Voice mode (talk to your AI assistant)
364
- * - Action-first UI (shows what the AI is doing, not just typing)
365
- * - Shadow DOM isolation (styles don't leak in or out)
366
- *
367
- * @example
368
- * ```tsx
369
- * <Char
370
- * ticketAuth={{ ticket, userId, orgId }}
371
- * open={isOpen}
372
- * onClose={() => setIsOpen(false)}
373
- * />
374
- * ```
738
+ * Resolves Char's standard host display-mode policy.
739
+ *
740
+ * Policy:
741
+ * - Closed state to `pip`
742
+ * - Open on desktop to `inline`
743
+ * - Open on narrow viewport to `fullscreen`
744
+ *
745
+ * The resolved mode is then constrained to `availableModes`.
746
+ *
747
+ * @param options - Host orchestration inputs: `open`, `isNarrowViewport`,
748
+ * and optional `availableModes`.
749
+ * @returns Final mode that satisfies policy and availability constraints.
750
+ *
751
+ * @public
375
752
  */
376
- declare const Char: FC<CharProps>;
753
+ declare function resolvePolicyDisplayMode(options: {
754
+ open: boolean;
755
+ isNarrowViewport: boolean;
756
+ availableModes?: readonly CharDisplayMode[];
757
+ }): CharDisplayMode;
377
758
  //#endregion
378
- export { Char, Char as default, CharProps, type DevModeConfig, type MCPToolsContextValue, MCPToolsProvider, type MCPToolsProviderProps, type TicketAuth, useMCPTools };
759
+ export { type CharAgentElement, type CharAgentShellElement, type CharContainerDimensions, type CharDeviceCapabilities, type CharDisplayMode, type CharElement, type CharErrorDetail, type CharHostCapabilities, type CharHostContext, type CharHostStyles, type CharOpenLinkDetail, type CharPipPosition, type CharPlatform, type CharRequestDisplayModeDetail, type CharSafeAreaInsets, type CharShellOpenChangeDetail, type CharSizeChangedDetail, type CharTheme, type ConnectOptions, DEFAULT_AVAILABLE_DISPLAY_MODES, type DevModeConfig, type TicketAuth, type WebMCPAgentElement, isDisplayMode, isExpandedDisplayMode, registerChar, registerCharShell, resolvePolicyDisplayMode, resolveSupportedDisplayMode };
379
760
  //# sourceMappingURL=index.d.ts.map