@mcp-b/char 0.0.6 → 0.1.1

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 +2374 -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 +2508 -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 +1259 -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 +1142 -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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mcp-b/char",
3
- "version": "0.0.6",
4
- "description": "Char - AI chat agent for React and web components. Drop-in widget with MCP tool support.",
3
+ "version": "0.1.1",
4
+ "description": "Char host shell. Framework-agnostic custom element that bridges to the iframe embed runtime.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
7
7
  "homepage": "https://github.com/WebMCP-org/char#readme",
@@ -13,151 +13,59 @@
13
13
  "url": "git+https://github.com/WebMCP-org/char.git"
14
14
  },
15
15
  "files": [
16
- "dist",
17
- "THIRD_PARTY_NOTICES.md"
16
+ "dist"
18
17
  ],
19
18
  "main": "./dist/index.js",
20
19
  "module": "./dist/index.js",
21
20
  "types": "./dist/index.d.ts",
21
+ "customElements": "./dist/custom-elements.json",
22
22
  "exports": {
23
23
  ".": {
24
24
  "types": "./dist/index.d.ts",
25
25
  "import": "./dist/index.js",
26
26
  "default": "./dist/index.js"
27
27
  },
28
- "./react": {
29
- "types": "./dist/index.d.ts",
30
- "import": "./dist/index.js",
31
- "default": "./dist/index.js"
28
+ "./display-mode-policy": {
29
+ "types": "./dist/display-mode-policy.d.ts",
30
+ "import": "./dist/display-mode-policy.js",
31
+ "default": "./dist/display-mode-policy.js"
32
32
  },
33
33
  "./web-component": {
34
34
  "types": "./dist/web-component.d.ts",
35
35
  "import": "./dist/web-component.js",
36
36
  "default": "./dist/web-component.js"
37
37
  },
38
- "./standalone": {
39
- "types": "./dist/web-component.d.ts",
40
- "import": "./dist/web-component-standalone.iife.js",
41
- "default": "./dist/web-component-standalone.iife.js"
38
+ "./shell-component": {
39
+ "types": "./dist/shell-component.d.ts",
40
+ "import": "./dist/shell-component.js",
41
+ "default": "./dist/shell-component.js"
42
42
  },
43
- "./realtimekit": {
44
- "types": "./dist/realtimekit.d.ts",
45
- "import": "./dist/realtimekit.js",
46
- "default": "./dist/realtimekit.js"
43
+ "./utils": {
44
+ "types": "./dist/utils.d.ts",
45
+ "import": "./dist/utils.js",
46
+ "default": "./dist/utils.js"
47
47
  },
48
48
  "./package.json": "./package.json"
49
49
  },
50
50
  "publishConfig": {
51
51
  "access": "public"
52
52
  },
53
- "dependencies": {
54
- "@ai-sdk/react": "^3.0.59",
55
- "@assistant-ui/react": "^0.12.5",
56
- "@assistant-ui/react-markdown": "^0.12.2",
57
- "@cloudflare/ai-chat": "^0.0.5",
58
- "@cloudflare/realtimekit-react": "^1.2.4",
59
- "@cloudflare/realtimekit-react-ui": "^1.1.0",
60
- "@mcp-b/react-webmcp": "1.1.1",
61
- "@mcp-b/transports": "1.3.0",
62
- "@modelcontextprotocol/sdk": "1.25.3",
63
- "@openai/agents-realtime": "^0.3.8",
64
- "@r2wc/react-to-web-component": "^2.1.0",
65
- "@radix-ui/react-avatar": "^1.1.11",
66
- "@radix-ui/react-checkbox": "^1.3.3",
67
- "@radix-ui/react-collapsible": "^1.1.12",
68
- "@radix-ui/react-dialog": "^1.1.15",
69
- "@radix-ui/react-label": "^2.1.8",
70
- "@radix-ui/react-popover": "^1.1.15",
71
- "@radix-ui/react-radio-group": "^1.3.8",
72
- "@radix-ui/react-scroll-area": "^1.2.10",
73
- "@radix-ui/react-select": "^2.2.5",
74
- "@radix-ui/react-separator": "^1.1.8",
75
- "@radix-ui/react-slot": "^1.2.4",
76
- "@radix-ui/react-tooltip": "^1.2.8",
77
- "@rjsf/core": "^6.2.5",
78
- "@rjsf/shadcn": "^6.2.5",
79
- "@rjsf/utils": "^6.2.5",
80
- "@rjsf/validator-ajv8": "^6.2.5",
81
- "agents": "^0.3.9",
82
- "ai": "^6.0.69",
83
- "ajv": "^8.17.1",
84
- "assistant-stream": "^0.3.1",
85
- "class-variance-authority": "^0.7.1",
86
- "clsx": "^2.1.1",
87
- "date-fns": "^4.1.0",
88
- "fast-json-stable-stringify": "^2.1.0",
89
- "jsonrepair": "^3.13.2",
90
- "lucide-react": "^0.563.0",
91
- "motion": "^12.29.2",
92
- "react-compiler-runtime": "^1.0.0",
93
- "react-day-picker": "^9.13.0",
94
- "react-error-boundary": "^6.1.0",
95
- "react-markdown": "^10.1.0",
96
- "remark-gfm": "^4.0.1",
97
- "sonner": "^2.0.7",
98
- "tailwind-merge": "^3.4.0",
99
- "tw-animate-css": "^1.4.0",
100
- "zod": "^3.25.76",
101
- "zustand": "^5.0.10"
102
- },
103
- "peerDependencies": {
104
- "react": "^18.0.0 || ^19.0.0",
105
- "react-dom": "^18.0.0 || ^19.0.0",
106
- "tailwindcss": ">=3.0.0"
107
- },
108
- "peerDependenciesMeta": {
109
- "tailwindcss": {
110
- "optional": true
111
- }
112
- },
53
+ "dependencies": {},
113
54
  "devDependencies": {
114
- "@arethetypeswrong/core": "^0.18.2",
115
- "@rollup/plugin-babel": "^6.1.0",
116
- "@storybook/addon-themes": "^10.2.7",
117
- "@storybook/react": "^10.2.7",
118
- "@storybook/react-vite": "^10.2.7",
119
- "@tailwindcss/cli": "^4.1.18",
120
- "@tailwindcss/vite": "^4.1.18",
121
- "@testing-library/jest-dom": "^6.9.1",
122
- "@testing-library/react": "^16.3.0",
123
- "@tsconfig/strictest": "^2.0.8",
124
- "@types/json-schema": "^7.0.15",
125
55
  "@types/node": "^25.2.1",
126
56
  "@types/react": "^19.2.10",
127
- "@types/react-dom": "^19.2.3",
128
- "@vitejs/plugin-react": "^5.1.3",
129
- "babel-plugin-react-compiler": "^1.0.0",
130
- "bumpp": "^10.4.1",
131
57
  "happy-dom": "^20.5.0",
132
- "publint": "^0.3.17",
133
- "react": "^19.2.4",
134
- "react-dom": "^19.2.4",
135
- "storybook": "^10.2.7",
136
- "tailwindcss": "^4.1.18",
137
58
  "tsdown": "^0.20.3",
138
59
  "typescript": "^5.9.3",
139
- "vite": "^7.3.1",
140
60
  "vitest": "^4.0.18",
141
- "@mcp-b/shared-types": "0.0.0",
142
- "@char-ai/auth": "0.1.0"
61
+ "@mcp-b/shared-types": "0.0.1"
143
62
  },
144
63
  "scripts": {
145
- "build": "pnpm run build:css && pnpm run build:inline-styles && pnpm run build:clean-js && pnpm run build:copy-types && pnpm run build:styles-types && pnpm run build:js",
146
- "build:css": "mkdir -p dist/styles && tailwindcss -i src/styles/globals.css -o dist/styles/globals.css --minify",
147
- "build:inline-styles": "node scripts/generate-inline-styles.js",
148
- "build:clean-js": "rm -f dist/*.js dist/*.d.ts dist/*.map",
149
- "build:js": "NODE_ENV=production tsdown",
150
- "build:styles-types": "echo '// Type declarations for CSS module import\nexport {};' > dist/styles.d.ts",
151
- "build:copy-types": "echo 'No manual type files to copy'",
64
+ "build": "rm -f dist/*.js dist/*.d.ts dist/*.map && NODE_ENV=production tsdown && pnpm docs:cem",
152
65
  "dev": "tsdown --watch",
153
- "dev:css": "tailwindcss -i src/styles/globals.css -o dist/styles/globals.css --watch",
154
- "play": "vite --config playground/vite.config.ts",
155
- "storybook": "storybook dev -p 6006 --ci",
156
- "build:storybook": "storybook build",
157
- "test": "vitest",
158
- "check:types": "pnpm run build:css && pnpm run build:inline-styles && tsc --noEmit",
159
- "check:lint": "node ./scripts/check-lint.mjs",
160
- "check:lint:all": "biome lint src tests",
161
- "release": "bumpp && pnpm publish"
66
+ "docs:cem": "pnpm -w exec cem analyze --config packages/char/custom-elements-manifest.config.mjs",
67
+ "test": "vitest run",
68
+ "check:types": "tsc --noEmit",
69
+ "check:lint": "biome lint src"
162
70
  }
163
71
  }
@@ -1,52 +0,0 @@
1
- # Third-Party Notices
2
-
3
- This package (@mcp-b/char) bundles the following third-party software.
4
- Each is listed with its license type. Full license texts are available
5
- in the respective packages' source repositories.
6
-
7
- ## MIT License
8
-
9
- - **@assistant-ui/react** - Chat UI primitives
10
- - **@assistant-ui/react-markdown** - Markdown rendering for assistant-ui
11
- - **@cloudflare/ai-chat** - Cloudflare AI chat client
12
- - **@modelcontextprotocol/sdk** - Model Context Protocol SDK
13
- - **@r2wc/react-to-web-component** - React to Web Component bridge
14
- - **@rjsf/shadcn** - JSON Schema Form shadcn theme
15
- - **agents** - Cloudflare Agents SDK
16
- - **assistant-stream** - Streaming utilities for assistant-ui
17
- - **clsx** - Utility for constructing className strings
18
- - **date-fns** - Date utility library
19
- - **fast-json-stable-stringify** - Deterministic JSON.stringify
20
- - **motion** - Animation library (Framer Motion)
21
- - **react-day-picker** - Date picker component
22
- - **react-error-boundary** - React error boundary component
23
- - **react-markdown** - Markdown renderer for React
24
- - **remark-gfm** - GitHub Flavored Markdown support
25
- - **sonner** - Toast notification library
26
- - **tailwind-merge** - Tailwind CSS class merging
27
- - **tw-animate-css** - Tailwind CSS animations
28
- - **zod** - TypeScript-first schema validation
29
- - **zustand** - State management
30
-
31
- ## Apache-2.0 License
32
-
33
- - **@ai-sdk/react** - Vercel AI SDK React bindings
34
- - **ai** - Vercel AI SDK
35
- - **@cloudflare/realtimekit-react** - Cloudflare RealtimeKit React bindings
36
- - **@cloudflare/realtimekit-react-ui** - Cloudflare RealtimeKit UI components
37
- - **@rjsf/core** - React JSON Schema Form core
38
- - **@rjsf/utils** - React JSON Schema Form utilities
39
- - **@rjsf/validator-ajv8** - JSON Schema Form AJV8 validator
40
- - **class-variance-authority** - CSS variant utility
41
-
42
- ## ISC License
43
-
44
- - **jsonrepair** - JSON repair utility
45
- - **lucide-react** - Icon library
46
-
47
- ## Peer Dependencies (not bundled in ESM build)
48
-
49
- - **react** - MIT License - Copyright (c) Meta Platforms, Inc. and affiliates
50
- - **react-dom** - MIT License - Copyright (c) Meta Platforms, Inc. and affiliates
51
-
52
- Note: The standalone IIFE build bundles React and ReactDOM.
@@ -1,244 +0,0 @@
1
- /*! @mcp-b/char | Copyright (c) 2025 Kukumis Inc. All rights reserved. | UNLICENSED */
2
- import { r as cn, t as Button } from "./button-BLnLZvxR.js";
3
- import { c } from "react-compiler-runtime";
4
- import { useCallback, useEffect, useMemo, useRef } from "react";
5
- import { jsx, jsxs } from "react/jsx-runtime";
6
- import { RealtimeKitProvider, useRealtimeKitClient } from "@cloudflare/realtimekit-react";
7
- import { RtkMeeting } from "@cloudflare/realtimekit-react-ui";
8
-
9
- //#region src/components/voice/RealtimeKitCallPanel.tsx
10
- const RealtimeKitCallPanel = ({ authToken, meetingId, onEnded, showSetupScreen = true, debugLabel = "rtk:customer" }) => {
11
- const [meeting, initMeeting] = useRealtimeKitClient();
12
- const onEndedRef = useRef(onEnded);
13
- const lastMeetingStateRef = useRef(null);
14
- const debugEnabled = useMemo(() => {
15
- if (typeof window === "undefined") return false;
16
- try {
17
- return window.__CHAR_RTK_DEBUG__ === true || window.localStorage.getItem("char:rtk-debug") === "true";
18
- } catch {
19
- return false;
20
- }
21
- }, []);
22
- const logDebug = useCallback((message, payload) => {
23
- if (!debugEnabled) return;
24
- if (payload) console.debug(`[${debugLabel}] ${message}`, payload);
25
- else console.debug(`[${debugLabel}] ${message}`);
26
- }, [debugEnabled, debugLabel]);
27
- useEffect(() => {
28
- onEndedRef.current = onEnded;
29
- }, [onEnded]);
30
- useEffect(() => {
31
- if (!authToken) return;
32
- let cancelled = false;
33
- logDebug("initMeeting:start", {
34
- meetingId,
35
- hasToken: Boolean(authToken),
36
- tokenLength: authToken.length
37
- });
38
- initMeeting({
39
- authToken,
40
- defaults: {
41
- audio: true,
42
- video: false
43
- }
44
- }).then((client) => {
45
- if (cancelled) return;
46
- if (client) logDebug("initMeeting:success", { meetingId });
47
- else logDebug("initMeeting:undefined", { meetingId });
48
- }).catch((error) => {
49
- if (cancelled) return;
50
- logDebug("initMeeting:error", {
51
- meetingId,
52
- error: error instanceof Error ? error.message : String(error)
53
- });
54
- });
55
- return () => {
56
- cancelled = true;
57
- };
58
- }, [
59
- authToken,
60
- initMeeting,
61
- logDebug,
62
- meetingId
63
- ]);
64
- const handleStatesUpdate = useCallback((event) => {
65
- const nextState = event.detail?.meeting ?? null;
66
- const prevState = lastMeetingStateRef.current;
67
- lastMeetingStateRef.current = nextState;
68
- logDebug("meeting:state", {
69
- meetingId,
70
- state: nextState
71
- });
72
- if (prevState && nextState === "ended" && prevState !== "ended") onEndedRef.current?.();
73
- }, [logDebug, meetingId]);
74
- if (!meeting) return /* @__PURE__ */ jsx("div", {
75
- className: "flex h-full items-center justify-center text-sm text-muted-foreground",
76
- children: "Connecting to the call..."
77
- });
78
- return /* @__PURE__ */ jsx(RealtimeKitProvider, {
79
- value: meeting,
80
- children: /* @__PURE__ */ jsx(RtkMeeting, {
81
- mode: "fill",
82
- meeting,
83
- showSetupScreen,
84
- onRtkStatesUpdate: handleStatesUpdate
85
- })
86
- });
87
- };
88
-
89
- //#endregion
90
- //#region src/components/voice/VoiceHandoffPanel.tsx
91
- const AI_ONLY_HANDOFF_STATUS = "ai_only";
92
- const HANDOFF_PENDING_STATUS = "handoff_pending";
93
- const HUMAN_ACTIVE_STATUS = "human_active";
94
- const VoiceHandoffPanel = (t0) => {
95
- const $ = c(34);
96
- const { handoffStatus, joinResult, isRequesting, error, onRequestToken, onEnd } = t0;
97
- let t1;
98
- if ($[0] !== onRequestToken) {
99
- t1 = () => {
100
- onRequestToken().catch(_temp);
101
- };
102
- $[0] = onRequestToken;
103
- $[1] = t1;
104
- } else t1 = $[1];
105
- const requestToken = t1;
106
- let t2;
107
- if ($[2] !== onEnd) {
108
- t2 = () => {
109
- onEnd().catch(_temp2);
110
- };
111
- $[2] = onEnd;
112
- $[3] = t2;
113
- } else t2 = $[3];
114
- const endCall = t2;
115
- let t3;
116
- let t4;
117
- if ($[4] !== error || $[5] !== handoffStatus || $[6] !== isRequesting || $[7] !== joinResult || $[8] !== requestToken) {
118
- t3 = () => {
119
- if (handoffStatus === AI_ONLY_HANDOFF_STATUS) return;
120
- if (joinResult || isRequesting || error) return;
121
- requestToken();
122
- };
123
- t4 = [
124
- handoffStatus,
125
- joinResult,
126
- isRequesting,
127
- error,
128
- requestToken
129
- ];
130
- $[4] = error;
131
- $[5] = handoffStatus;
132
- $[6] = isRequesting;
133
- $[7] = joinResult;
134
- $[8] = requestToken;
135
- $[9] = t3;
136
- $[10] = t4;
137
- } else {
138
- t3 = $[9];
139
- t4 = $[10];
140
- }
141
- useEffect(t3, t4);
142
- if (handoffStatus === AI_ONLY_HANDOFF_STATUS) return null;
143
- const isLive = handoffStatus === HUMAN_ACTIVE_STATUS;
144
- const t5 = isLive ? "bg-emerald-500" : "bg-amber-500 animate-pulse";
145
- let t6;
146
- if ($[11] !== t5) {
147
- t6 = cn("h-2 w-2 rounded-full", t5);
148
- $[11] = t5;
149
- $[12] = t6;
150
- } else t6 = $[12];
151
- let t7;
152
- if ($[13] !== t6) {
153
- t7 = /* @__PURE__ */ jsx("span", { className: t6 });
154
- $[13] = t6;
155
- $[14] = t7;
156
- } else t7 = $[14];
157
- const t8 = isLive ? "Live support" : "Connecting support";
158
- let t9;
159
- if ($[15] !== t7 || $[16] !== t8) {
160
- t9 = /* @__PURE__ */ jsxs("div", {
161
- className: "flex items-center gap-2 text-xs font-medium uppercase tracking-wide text-muted-foreground",
162
- children: [t7, t8]
163
- });
164
- $[15] = t7;
165
- $[16] = t8;
166
- $[17] = t9;
167
- } else t9 = $[17];
168
- let t10;
169
- if ($[18] !== endCall || $[19] !== isRequesting) {
170
- t10 = /* @__PURE__ */ jsx(Button, {
171
- type: "button",
172
- variant: "outline",
173
- size: "sm",
174
- onClick: endCall,
175
- disabled: isRequesting,
176
- children: "End call"
177
- });
178
- $[18] = endCall;
179
- $[19] = isRequesting;
180
- $[20] = t10;
181
- } else t10 = $[20];
182
- let t11;
183
- if ($[21] !== t10 || $[22] !== t9) {
184
- t11 = /* @__PURE__ */ jsxs("div", {
185
- className: "flex items-center justify-between gap-3 border-b border-border/60 px-4 py-3",
186
- children: [t9, t10]
187
- });
188
- $[21] = t10;
189
- $[22] = t9;
190
- $[23] = t11;
191
- } else t11 = $[23];
192
- let t12;
193
- if ($[24] !== error) {
194
- t12 = error ? /* @__PURE__ */ jsx("div", {
195
- className: "px-4 pt-3 text-xs text-destructive",
196
- children: error
197
- }) : null;
198
- $[24] = error;
199
- $[25] = t12;
200
- } else t12 = $[25];
201
- let t13;
202
- if ($[26] !== endCall || $[27] !== handoffStatus || $[28] !== joinResult) {
203
- t13 = /* @__PURE__ */ jsx("div", {
204
- className: "flex min-h-0 flex-1",
205
- children: joinResult ? /* @__PURE__ */ jsx(RealtimeKitCallPanel, {
206
- authToken: joinResult.authToken,
207
- meetingId: joinResult.meetingId,
208
- onEnded: endCall
209
- }) : /* @__PURE__ */ jsx("div", {
210
- className: "flex h-full w-full flex-col items-center justify-center gap-2 px-6 text-center text-sm text-muted-foreground",
211
- children: handoffStatus === HANDOFF_PENDING_STATUS ? /* @__PURE__ */ jsx("p", {
212
- className: "text-xs text-muted-foreground",
213
- children: "Waiting for a support agent to join…"
214
- }) : /* @__PURE__ */ jsx("p", { children: "Preparing the call..." })
215
- })
216
- });
217
- $[26] = endCall;
218
- $[27] = handoffStatus;
219
- $[28] = joinResult;
220
- $[29] = t13;
221
- } else t13 = $[29];
222
- let t14;
223
- if ($[30] !== t11 || $[31] !== t12 || $[32] !== t13) {
224
- t14 = /* @__PURE__ */ jsxs("div", {
225
- className: "flex min-h-0 flex-1 flex-col overflow-hidden",
226
- children: [
227
- t11,
228
- t12,
229
- t13
230
- ]
231
- });
232
- $[30] = t11;
233
- $[31] = t12;
234
- $[32] = t13;
235
- $[33] = t14;
236
- } else t14 = $[33];
237
- return t14;
238
- };
239
- function _temp() {}
240
- function _temp2() {}
241
-
242
- //#endregion
243
- export { VoiceHandoffPanel as default };
244
- //# sourceMappingURL=VoiceHandoffPanel-CIFIJSDs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VoiceHandoffPanel-CIFIJSDs.js","names":["RealtimeKitProvider","useRealtimeKitClient","RtkMeeting","useCallback","useEffect","useMemo","useRef","FC","RtkMeetingState","meeting","RealtimeKitCallPanelProps","authToken","meetingId","onEnded","showSetupScreen","debugLabel","RealtimeKitCallPanel","initMeeting","onEndedRef","lastMeetingStateRef","debugEnabled","window","globalWindow","Window","__CHAR_RTK_DEBUG__","localStorage","getItem","logDebug","message","payload","Record","console","debug","current","cancelled","hasToken","Boolean","tokenLength","length","defaults","audio","video","then","client","catch","error","Error","String","handleStatesUpdate","event","CustomEvent","nextState","detail","prevState","state","Button","cn","useCallback","useEffect","FC","RealtimeKitCallPanel","RealtimeKitJoinResult","VoiceSessionState","HandoffStatus","AI_ONLY_HANDOFF_STATUS","HANDOFF_PENDING_STATUS","HUMAN_ACTIVE_STATUS","VoiceHandoffPanelProps","handoffStatus","joinResult","isRequesting","error","onRequestToken","Promise","onEnd","VoiceHandoffPanel","t0","$","_c","t1","catch","_temp","requestToken","t2","_temp2","endCall","t3","t4","isLive","t5","t6","t7","t8","t9","t10","t11","t12","t13","authToken","meetingId","t14"],"sources":["../src/components/voice/RealtimeKitCallPanel.tsx","../src/components/voice/VoiceHandoffPanel.tsx"],"sourcesContent":["import { RealtimeKitProvider, useRealtimeKitClient } from '@cloudflare/realtimekit-react'\nimport { RtkMeeting } from '@cloudflare/realtimekit-react-ui'\nimport { useCallback, useEffect, useMemo, useRef, type FC } from 'react'\n\ntype RtkMeetingState = {\n\tmeeting?: 'idle' | 'setup' | 'joined' | 'ended' | 'waiting'\n}\n\ninterface RealtimeKitCallPanelProps {\n\tauthToken: string\n\tmeetingId?: string\n\tonEnded?: () => void\n\tshowSetupScreen?: boolean\n\tdebugLabel?: string\n}\n\nconst RealtimeKitCallPanel: FC<RealtimeKitCallPanelProps> = ({\n\tauthToken,\n\tmeetingId,\n\tonEnded,\n\tshowSetupScreen = true,\n\tdebugLabel = 'rtk:customer',\n}) => {\n\tconst [meeting, initMeeting] = useRealtimeKitClient()\n\tconst onEndedRef = useRef(onEnded)\n\tconst lastMeetingStateRef = useRef<RtkMeetingState['meeting'] | null>(null)\n\tconst debugEnabled = useMemo(() => {\n\t\tif (typeof window === 'undefined') return false\n\t\ttry {\n\t\t\tconst globalWindow = window as Window & { __CHAR_RTK_DEBUG__?: boolean }\n\t\t\treturn (\n\t\t\t\tglobalWindow.__CHAR_RTK_DEBUG__ === true ||\n\t\t\t\twindow.localStorage.getItem('char:rtk-debug') === 'true'\n\t\t\t)\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}, [])\n\n\tconst logDebug = useCallback(\n\t\t(message: string, payload?: Record<string, unknown>) => {\n\t\t\tif (!debugEnabled) return\n\t\t\tif (payload) {\n\t\t\t\tconsole.debug(`[${debugLabel}] ${message}`, payload)\n\t\t\t} else {\n\t\t\t\tconsole.debug(`[${debugLabel}] ${message}`)\n\t\t\t}\n\t\t},\n\t\t[debugEnabled, debugLabel],\n\t)\n\n\tuseEffect(() => {\n\t\tonEndedRef.current = onEnded\n\t}, [onEnded])\n\n\tuseEffect(() => {\n\t\tif (!authToken) return\n\t\tlet cancelled = false\n\t\tlogDebug('initMeeting:start', {\n\t\t\tmeetingId,\n\t\t\thasToken: Boolean(authToken),\n\t\t\ttokenLength: authToken.length,\n\t\t})\n\t\tvoid initMeeting({\n\t\t\tauthToken,\n\t\t\tdefaults: {\n\t\t\t\taudio: true,\n\t\t\t\tvideo: false,\n\t\t\t},\n\t\t})\n\t\t\t.then((client) => {\n\t\t\t\tif (cancelled) return\n\t\t\t\tif (client) {\n\t\t\t\t\tlogDebug('initMeeting:success', { meetingId })\n\t\t\t\t} else {\n\t\t\t\t\tlogDebug('initMeeting:undefined', { meetingId })\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tif (cancelled) return\n\t\t\t\tlogDebug('initMeeting:error', {\n\t\t\t\t\tmeetingId,\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t})\n\t\t\t})\n\n\t\treturn () => {\n\t\t\tcancelled = true\n\t\t}\n\t}, [authToken, initMeeting, logDebug, meetingId])\n\n\tconst handleStatesUpdate = useCallback((event: CustomEvent<RtkMeetingState>) => {\n\t\tconst nextState = event.detail?.meeting ?? null\n\t\tconst prevState = lastMeetingStateRef.current\n\t\tlastMeetingStateRef.current = nextState\n\t\tlogDebug('meeting:state', { meetingId, state: nextState })\n\n\t\tif (prevState && nextState === 'ended' && prevState !== 'ended') {\n\t\t\tonEndedRef.current?.()\n\t\t}\n\t}, [logDebug, meetingId])\n\n\tif (!meeting) {\n\t\treturn (\n\t\t\t<div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n\t\t\t\tConnecting to the call...\n\t\t\t</div>\n\t\t)\n\t}\n\n\treturn (\n\t\t<RealtimeKitProvider value={meeting}>\n\t\t\t<RtkMeeting\n\t\t\t\tmode=\"fill\"\n\t\t\t\tmeeting={meeting}\n\t\t\t\tshowSetupScreen={showSetupScreen}\n\t\t\t\tonRtkStatesUpdate={handleStatesUpdate}\n\t\t\t/>\n\t\t</RealtimeKitProvider>\n\t)\n}\n\nexport default RealtimeKitCallPanel\n","import { Button } from '@/components/ui/button'\nimport { cn } from '@/utils/cn'\nimport { useCallback, useEffect, type FC } from 'react'\n\nimport RealtimeKitCallPanel from './RealtimeKitCallPanel'\n\nimport type { RealtimeKitJoinResult, VoiceSessionState } from '@mcp-b/shared-types'\n\ntype HandoffStatus = VoiceSessionState['handoffStatus']\nconst AI_ONLY_HANDOFF_STATUS: HandoffStatus = 'ai_only'\nconst HANDOFF_PENDING_STATUS: HandoffStatus = 'handoff_pending'\nconst HUMAN_ACTIVE_STATUS: HandoffStatus = 'human_active'\n\ninterface VoiceHandoffPanelProps {\n\thandoffStatus: HandoffStatus\n\tjoinResult: RealtimeKitJoinResult | null\n\tisRequesting: boolean\n\terror: string | null\n\tonRequestToken: () => Promise<void>\n\tonEnd: () => Promise<void>\n}\n\nconst VoiceHandoffPanel: FC<VoiceHandoffPanelProps> = ({\n\thandoffStatus,\n\tjoinResult,\n\tisRequesting,\n\terror,\n\tonRequestToken,\n\tonEnd,\n}) => {\n\tconst requestToken = useCallback(() => {\n\t\tonRequestToken().catch(() => undefined)\n\t}, [onRequestToken])\n\n\tconst endCall = useCallback(() => {\n\t\tonEnd().catch(() => undefined)\n\t}, [onEnd])\n\n\tuseEffect(() => {\n\t\tif (handoffStatus === AI_ONLY_HANDOFF_STATUS) return\n\t\tif (joinResult || isRequesting || error) return\n\t\trequestToken()\n\t}, [handoffStatus, joinResult, isRequesting, error, requestToken])\n\n\tif (handoffStatus === AI_ONLY_HANDOFF_STATUS) {\n\t\treturn null\n\t}\n\n\tconst isLive = handoffStatus === HUMAN_ACTIVE_STATUS\n\n\treturn (\n\t\t<div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n\t\t\t<div className=\"flex items-center justify-between gap-3 border-b border-border/60 px-4 py-3\">\n\t\t\t\t<div className=\"flex items-center gap-2 text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'h-2 w-2 rounded-full',\n\t\t\t\t\t\t\tisLive ? 'bg-emerald-500' : 'bg-amber-500 animate-pulse',\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t{isLive ? 'Live support' : 'Connecting support'}\n\t\t\t\t</div>\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tonClick={endCall}\n\t\t\t\t\tdisabled={isRequesting}\n\t\t\t\t>\n\t\t\t\t\tEnd call\n\t\t\t\t</Button>\n\t\t\t</div>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"px-4 pt-3 text-xs text-destructive\">{error}</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"flex min-h-0 flex-1\">\n\t\t\t\t{joinResult ? (\n\t\t\t\t\t<RealtimeKitCallPanel\n\t\t\t\t\t\tauthToken={joinResult.authToken}\n\t\t\t\t\t\tmeetingId={joinResult.meetingId}\n\t\t\t\t\t\tonEnded={endCall}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<div className=\"flex h-full w-full flex-col items-center justify-center gap-2 px-6 text-center text-sm text-muted-foreground\">\n\t\t\t\t\t\t{handoffStatus === HANDOFF_PENDING_STATUS ? (\n\t\t\t\t\t\t\t<p className=\"text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\tWaiting for a support agent to join…\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<p>Preparing the call...</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport default VoiceHandoffPanel\n"],"mappings":"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"}
@@ -1,105 +0,0 @@
1
- /*! @mcp-b/char | Copyright (c) 2025 Kukumis Inc. All rights reserved. | UNLICENSED */
2
- import { c } from "react-compiler-runtime";
3
- import "react";
4
- import { clsx } from "clsx";
5
- import { twMerge } from "tailwind-merge";
6
- import { jsx } from "react/jsx-runtime";
7
- import { Slot } from "@radix-ui/react-slot";
8
- import { cva } from "class-variance-authority";
9
-
10
- //#region src/utils/cn.ts
11
- /**
12
- * Merges Tailwind CSS classes with proper precedence handling.
13
- * Combines clsx for conditional classes and tailwind-merge for deduplication.
14
- */
15
- function cn(...inputs) {
16
- return twMerge(clsx(inputs));
17
- }
18
-
19
- //#endregion
20
- //#region src/components/ui/button.tsx
21
- const buttonVariants = cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", {
22
- variants: {
23
- variant: {
24
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
25
- destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
26
- outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
27
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
28
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
29
- link: "text-primary underline-offset-4 hover:underline"
30
- },
31
- size: {
32
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
33
- xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
34
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
35
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
36
- icon: "size-9",
37
- "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
38
- "icon-sm": "size-8",
39
- "icon-lg": "size-10"
40
- }
41
- },
42
- defaultVariants: {
43
- variant: "default",
44
- size: "default"
45
- }
46
- });
47
- function Button(t0) {
48
- const $ = c(16);
49
- let className;
50
- let props;
51
- let t1;
52
- let t2;
53
- let t3;
54
- if ($[0] !== t0) {
55
- ({className, variant: t1, size: t2, asChild: t3, ...props} = t0);
56
- $[0] = t0;
57
- $[1] = className;
58
- $[2] = props;
59
- $[3] = t1;
60
- $[4] = t2;
61
- $[5] = t3;
62
- } else {
63
- className = $[1];
64
- props = $[2];
65
- t1 = $[3];
66
- t2 = $[4];
67
- t3 = $[5];
68
- }
69
- const variant = t1 === void 0 ? "default" : t1;
70
- const size = t2 === void 0 ? "default" : t2;
71
- const Comp = (t3 === void 0 ? false : t3) ? Slot : "button";
72
- let t4;
73
- if ($[6] !== className || $[7] !== size || $[8] !== variant) {
74
- t4 = cn(buttonVariants({
75
- variant,
76
- size,
77
- className
78
- }));
79
- $[6] = className;
80
- $[7] = size;
81
- $[8] = variant;
82
- $[9] = t4;
83
- } else t4 = $[9];
84
- let t5;
85
- if ($[10] !== Comp || $[11] !== props || $[12] !== size || $[13] !== t4 || $[14] !== variant) {
86
- t5 = /* @__PURE__ */ jsx(Comp, {
87
- "data-slot": "button",
88
- "data-variant": variant,
89
- "data-size": size,
90
- className: t4,
91
- ...props
92
- });
93
- $[10] = Comp;
94
- $[11] = props;
95
- $[12] = size;
96
- $[13] = t4;
97
- $[14] = variant;
98
- $[15] = t5;
99
- } else t5 = $[15];
100
- return t5;
101
- }
102
-
103
- //#endregion
104
- export { buttonVariants as n, cn as r, Button as t };
105
- //# sourceMappingURL=button-BLnLZvxR.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"button-BLnLZvxR.js","names":["clsx","twMerge","ClassValue","cn","inputs","React","Slot","cva","VariantProps","cn","buttonVariants","variants","variant","default","destructive","outline","secondary","ghost","link","size","xs","sm","lg","icon","defaultVariants","Button","t0","$","_c","className","props","t1","t2","t3","asChild","undefined","Comp","t4","t5"],"sources":["../src/utils/cn.ts","../src/components/ui/button.tsx"],"sourcesContent":["import { clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nimport type { ClassValue } from 'clsx'\n\n/**\n * Merges Tailwind CSS classes with proper precedence handling.\n * Combines clsx for conditional classes and tailwind-merge for deduplication.\n */\nexport function cn(...inputs: ClassValue[]): string {\n\treturn twMerge(clsx(inputs))\n}\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/utils/cn\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n"],"mappings":";;;;;;;;;;;;;;AASA,SAAgBG,GAAG,GAAGC,QAA8B;AACnD,QAAOH,QAAQD,KAAKI,OAAO,CAAC;;;;;ACJ7B,MAAMM,iBAAiBH,IACrB,+bACA;CACEI,UAAU;EACRC,SAAS;GACPC,SAAS;GACTC,aACE;GACFC,SACE;GACFC,WACE;GACFC,OACE;GACFC,MAAM;GACP;EACDC,MAAM;GACJN,SAAS;GACTO,IAAI;GACJC,IAAI;GACJC,IAAI;GACJC,MAAM;GACN,WAAW;GACX,WAAW;GACX,WAAW;GACb;EACD;CACDC,iBAAiB;EACfZ,SAAS;EACTO,MAAM;EACR;CAEJ,CAAC;AAED,SAAAM,OAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;AAAA,KAAAN,EAAA,OAAAD,IAAA;AAAgB,GAAA,CAAAG,WAAAjB,SAAAmB,IAAAZ,MAAAa,IAAAE,SAAAD,OAAAH,SAAAJ;AASbC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;AAAAF,IAAA,KAAAG;AAAAH,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;AAAAL,IAAA,KAAAM;QAAA;AAAAJ,cAAAF,EAAA;AAAAG,UAAAH,EAAA;AAAAI,OAAAJ,EAAA;AAAAK,OAAAL,EAAA;AAAAM,OAAAN,EAAA;;CAPD,MAAAf,UAAAmB,OAAAI,SAAA,YAAAJ;CACA,MAAAZ,OAAAa,OAAAG,SAAA,YAAAH;CAOA,MAAAI,QANAH,OAAAE,SAAA,QAAAF,MAMa3B,OAAA;CAAyB,IAAA+B;AAAA,KAAAV,EAAA,OAAAE,aAAAF,EAAA,OAAAR,QAAAQ,EAAA,OAAAf,SAAA;AAOvByB,OAAA5B,GAAGC,eAAe;GAAAE;GAAAO;GAAAU;GAA4B,CAAC,CAAC;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAR;AAAAQ,IAAA,KAAAf;AAAAe,IAAA,KAAAU;OAAAA,MAAAV,EAAA;CAAA,IAAAW;AAAA,KAAAX,EAAA,QAAAS,QAAAT,EAAA,QAAAG,SAAAH,EAAA,QAAAR,QAAAQ,EAAA,QAAAU,MAAAV,EAAA,QAAAf,SAAA;AAJ7D0B,OAAA,oBAAC;GACW,aAAA;GACI1B,gBAAAA;GACHO,aAAAA;GACA,WAAAkB;GAAgD,GACvDP;IACJ;AAAAH,IAAA,MAAAS;AAAAT,IAAA,MAAAG;AAAAH,IAAA,MAAAR;AAAAQ,IAAA,MAAAU;AAAAV,IAAA,MAAAf;AAAAe,IAAA,MAAAW;OAAAA,MAAAX,EAAA;AAAA,QANFW"}
@@ -1,15 +0,0 @@
1
-
2
- import { FC } from "react";
3
-
4
- //#region src/components/voice/RealtimeKitCallPanel.d.ts
5
- interface RealtimeKitCallPanelProps {
6
- authToken: string;
7
- meetingId?: string;
8
- onEnded?: () => void;
9
- showSetupScreen?: boolean;
10
- debugLabel?: string;
11
- }
12
- declare const RealtimeKitCallPanel: FC<RealtimeKitCallPanelProps>;
13
- //#endregion
14
- export { RealtimeKitCallPanel as default };
15
- //# sourceMappingURL=realtimekit.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtimekit.d.ts","names":[],"sources":["../src/components/voice/RealtimeKitCallPanel.tsx"],"mappings":";;;;UAQU,yBAAA;EACT,SAAA;EACA,SAAA;EACA,OAAA;EACA,eAAA;EACA,UAAA;AAAA;AAAA,cAGK,oBAAA,EAAsB,EAAA,CAAG,yBAAA"}