mcp-use 1.5.0-canary.0 → 1.5.0-canary.2

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 (40) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{chunk-RE7EYFDV.js → chunk-GPAOZN2F.js} +459 -967
  3. package/dist/{chunk-GRLCLVAK.js → chunk-UT7O4SIJ.js} +14 -4
  4. package/dist/index.cjs +500 -998
  5. package/dist/index.js +12 -6
  6. package/dist/src/browser.cjs +14 -4
  7. package/dist/src/browser.js +1 -1
  8. package/dist/src/client/browser.d.ts.map +1 -1
  9. package/dist/src/connectors/base.d.ts +5 -0
  10. package/dist/src/connectors/base.d.ts.map +1 -1
  11. package/dist/src/connectors/http.d.ts.map +1 -1
  12. package/dist/src/react/ErrorBoundary.d.ts +24 -0
  13. package/dist/src/react/ErrorBoundary.d.ts.map +1 -0
  14. package/dist/src/react/Image.d.ts +11 -0
  15. package/dist/src/react/Image.d.ts.map +1 -0
  16. package/dist/src/react/McpUseProvider.d.ts +46 -0
  17. package/dist/src/react/McpUseProvider.d.ts.map +1 -0
  18. package/dist/src/react/ThemeProvider.d.ts +14 -0
  19. package/dist/src/react/ThemeProvider.d.ts.map +1 -0
  20. package/dist/src/react/WidgetControls.d.ts +44 -0
  21. package/dist/src/react/WidgetControls.d.ts.map +1 -0
  22. package/dist/src/react/index.cjs +500 -998
  23. package/dist/src/react/index.d.ts +9 -6
  24. package/dist/src/react/index.d.ts.map +1 -1
  25. package/dist/src/react/index.js +12 -6
  26. package/dist/src/react/types.d.ts +2 -0
  27. package/dist/src/react/types.d.ts.map +1 -1
  28. package/dist/src/react/useMcp.d.ts.map +1 -1
  29. package/dist/src/react/useWidget.d.ts.map +1 -1
  30. package/dist/src/react/widget-types.d.ts +6 -0
  31. package/dist/src/react/widget-types.d.ts.map +1 -1
  32. package/dist/src/server/connect-adapter.d.ts.map +1 -1
  33. package/dist/src/server/index.cjs +232 -21
  34. package/dist/src/server/index.js +232 -21
  35. package/dist/src/server/mcp-server.d.ts.map +1 -1
  36. package/package.json +6 -4
  37. package/dist/src/react/WidgetDebugger.d.ts +0 -31
  38. package/dist/src/react/WidgetDebugger.d.ts.map +0 -1
  39. package/dist/src/react/WidgetFullscreenWrapper.d.ts +0 -32
  40. package/dist/src/react/WidgetFullscreenWrapper.d.ts.map +0 -1
@@ -31,8 +31,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/react/index.ts
32
32
  var react_exports = {};
33
33
  __export(react_exports, {
34
- WidgetDebugger: () => WidgetDebugger,
35
- WidgetFullscreenWrapper: () => WidgetFullscreenWrapper,
34
+ ErrorBoundary: () => ErrorBoundary,
35
+ Image: () => Image,
36
+ McpUseProvider: () => McpUseProvider,
37
+ ThemeProvider: () => ThemeProvider,
38
+ WidgetControls: () => WidgetControls,
36
39
  onMcpAuthorization: () => onMcpAuthorization,
37
40
  useMcp: () => useMcp,
38
41
  useWidget: () => useWidget,
@@ -905,7 +908,11 @@ var HttpConnector = class extends BaseConnector {
905
908
  maxRetries: 2
906
909
  }
907
910
  });
908
- const transport = await this.connectionManager.start();
911
+ let transport = await this.connectionManager.start();
912
+ if (this.opts.wrapTransport) {
913
+ const serverId = this.baseUrl;
914
+ transport = this.opts.wrapTransport(transport, serverId);
915
+ }
909
916
  this.client = new import_client.Client(this.clientInfo, this.opts.clientOptions);
910
917
  try {
911
918
  await this.client.connect(transport);
@@ -939,7 +946,11 @@ var HttpConnector = class extends BaseConnector {
939
946
  headers: this.headers
940
947
  }
941
948
  });
942
- const transport = await this.connectionManager.start();
949
+ let transport = await this.connectionManager.start();
950
+ if (this.opts.wrapTransport) {
951
+ const serverId = this.baseUrl;
952
+ transport = this.opts.wrapTransport(transport, serverId);
953
+ }
943
954
  this.client = new import_client.Client(this.clientInfo, this.opts.clientOptions);
944
955
  await this.client.connect(transport);
945
956
  this.connected = true;
@@ -1358,15 +1369,17 @@ var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
1358
1369
  * Supports HTTP and WebSocket connectors only
1359
1370
  */
1360
1371
  createConnectorFromConfig(serverConfig) {
1361
- const { url, transport, headers, authToken, authProvider } = serverConfig;
1372
+ const { url, transport, headers, authToken, authProvider, wrapTransport } = serverConfig;
1362
1373
  if (!url) {
1363
1374
  throw new Error("Server URL is required");
1364
1375
  }
1365
1376
  const connectorOptions = {
1366
1377
  headers,
1367
1378
  authToken,
1368
- authProvider
1379
+ authProvider,
1369
1380
  // ← Pass OAuth provider to connector
1381
+ wrapTransport
1382
+ // ← Pass transport wrapper if provided
1370
1383
  };
1371
1384
  if (transport === "websocket" || url.startsWith("ws://") || url.startsWith("wss://")) {
1372
1385
  return new WebSocketConnector(url, connectorOptions);
@@ -1625,8 +1638,9 @@ function useMcp(options) {
1625
1638
  onPopupWindow,
1626
1639
  timeout = 3e4,
1627
1640
  // 30 seconds default for connection timeout
1628
- sseReadTimeout = 3e5
1641
+ sseReadTimeout = 3e5,
1629
1642
  // 5 minutes default for SSE read timeout
1643
+ wrapTransport
1630
1644
  } = options;
1631
1645
  const [state, setState] = (0, import_react.useState)("discovering");
1632
1646
  const [tools, setTools] = (0, import_react.useState)([]);
@@ -1777,8 +1791,17 @@ function useMcp(options) {
1777
1791
  }
1778
1792
  clientRef.current.addServer(serverName, {
1779
1793
  ...serverConfig,
1780
- authProvider: authProviderRef.current
1794
+ authProvider: authProviderRef.current,
1781
1795
  // ← SDK handles OAuth automatically!
1796
+ wrapTransport: wrapTransport ? (transport) => {
1797
+ console.log(
1798
+ "[useMcp] Applying transport wrapper for server:",
1799
+ serverName,
1800
+ "url:",
1801
+ url
1802
+ );
1803
+ return wrapTransport(transport, url);
1804
+ } : void 0
1782
1805
  });
1783
1806
  const session = await clientRef.current.createSession(serverName);
1784
1807
  await session.initialize();
@@ -2321,15 +2344,61 @@ async function onMcpAuthorization() {
2321
2344
  }
2322
2345
  __name(onMcpAuthorization, "onMcpAuthorization");
2323
2346
 
2347
+ // src/react/ErrorBoundary.tsx
2348
+ var import_react2 = __toESM(require("react"), 1);
2349
+ var ErrorBoundary = class extends import_react2.default.Component {
2350
+ static {
2351
+ __name(this, "ErrorBoundary");
2352
+ }
2353
+ constructor(props) {
2354
+ super(props);
2355
+ this.state = { hasError: false, error: null };
2356
+ }
2357
+ static getDerivedStateFromError(error) {
2358
+ return { hasError: true, error };
2359
+ }
2360
+ componentDidCatch(error, errorInfo) {
2361
+ console.error("Widget Error:", error, errorInfo);
2362
+ }
2363
+ render() {
2364
+ if (this.state.hasError) {
2365
+ return /* @__PURE__ */ import_react2.default.createElement("div", { className: "p-4 border border-red-500 bg-red-50 text-red-900 rounded-md dark:bg-red-900/20 dark:text-red-100" }, /* @__PURE__ */ import_react2.default.createElement("h3", { className: "font-bold mb-2" }, "Widget Error"), /* @__PURE__ */ import_react2.default.createElement("pre", { className: "text-sm whitespace-pre-wrap" }, this.state.error?.message));
2366
+ }
2367
+ return this.props.children;
2368
+ }
2369
+ };
2370
+
2371
+ // src/react/Image.tsx
2372
+ var import_react3 = __toESM(require("react"), 1);
2373
+ var Image = /* @__PURE__ */ __name(({ src, ...props }) => {
2374
+ const publicUrl = typeof window !== "undefined" && window.__mcpPublicUrl ? window.__mcpPublicUrl : "";
2375
+ const getFinalSrc = /* @__PURE__ */ __name((source) => {
2376
+ if (!source) return source;
2377
+ if (source.startsWith("http://") || source.startsWith("https://") || source.startsWith("data:")) {
2378
+ return source;
2379
+ }
2380
+ if (!publicUrl) {
2381
+ return source;
2382
+ }
2383
+ const cleanSrc = source.startsWith("/") ? source.slice(1) : source;
2384
+ return `${publicUrl}/${cleanSrc}`;
2385
+ }, "getFinalSrc");
2386
+ const finalSrc = getFinalSrc(src);
2387
+ return /* @__PURE__ */ import_react3.default.createElement("img", { src: finalSrc, ...props });
2388
+ }, "Image");
2389
+
2390
+ // src/react/ThemeProvider.tsx
2391
+ var import_react5 = __toESM(require("react"), 1);
2392
+
2324
2393
  // src/react/useWidget.ts
2325
- var import_react2 = require("react");
2394
+ var import_react4 = require("react");
2326
2395
 
2327
2396
  // src/react/widget-types.ts
2328
2397
  var SET_GLOBALS_EVENT_TYPE = "openai:set_globals";
2329
2398
 
2330
2399
  // src/react/useWidget.ts
2331
2400
  function useOpenAiGlobal(key) {
2332
- return (0, import_react2.useSyncExternalStore)(
2401
+ return (0, import_react4.useSyncExternalStore)(
2333
2402
  (onChange) => {
2334
2403
  const handleSetGlobal = /* @__PURE__ */ __name((event) => {
2335
2404
  const customEvent = event;
@@ -2353,10 +2422,10 @@ function useOpenAiGlobal(key) {
2353
2422
  }
2354
2423
  __name(useOpenAiGlobal, "useOpenAiGlobal");
2355
2424
  function useWidget(defaultProps) {
2356
- const [isOpenAiAvailable, setIsOpenAiAvailable] = (0, import_react2.useState)(
2425
+ const [isOpenAiAvailable, setIsOpenAiAvailable] = (0, import_react4.useState)(
2357
2426
  () => typeof window !== "undefined" && !!window.openai
2358
2427
  );
2359
- (0, import_react2.useEffect)(() => {
2428
+ (0, import_react4.useEffect)(() => {
2360
2429
  if (typeof window !== "undefined" && window.openai) {
2361
2430
  setIsOpenAiAvailable(true);
2362
2431
  return;
@@ -2390,11 +2459,12 @@ function useWidget(defaultProps) {
2390
2459
  }
2391
2460
  };
2392
2461
  }, []);
2393
- const provider = (0, import_react2.useMemo)(() => {
2462
+ const provider = (0, import_react4.useMemo)(() => {
2394
2463
  return isOpenAiAvailable ? "openai" : "mcp-ui";
2395
2464
  }, [isOpenAiAvailable]);
2396
- const urlParams = (0, import_react2.useMemo)(() => {
2397
- const urlParams2 = new URLSearchParams(window?.location?.search);
2465
+ const searchString = typeof window !== "undefined" ? window.location.search : "";
2466
+ const urlParams = (0, import_react4.useMemo)(() => {
2467
+ const urlParams2 = new URLSearchParams(searchString);
2398
2468
  if (urlParams2.has("mcpUseParams")) {
2399
2469
  return JSON.parse(urlParams2.get("mcpUseParams"));
2400
2470
  }
@@ -2403,7 +2473,7 @@ function useWidget(defaultProps) {
2403
2473
  toolOutput: {},
2404
2474
  toolId: ""
2405
2475
  };
2406
- }, [window?.location?.search]);
2476
+ }, [searchString]);
2407
2477
  const toolInput = provider === "openai" ? useOpenAiGlobal("toolInput") : urlParams.toolInput;
2408
2478
  const toolOutput = provider === "openai" ? useOpenAiGlobal("toolOutput") : urlParams.toolOutput;
2409
2479
  const toolResponseMetadata = useOpenAiGlobal("toolResponseMetadata");
@@ -2414,13 +2484,19 @@ function useWidget(defaultProps) {
2414
2484
  const maxHeight = useOpenAiGlobal("maxHeight");
2415
2485
  const userAgent = useOpenAiGlobal("userAgent");
2416
2486
  const locale = useOpenAiGlobal("locale");
2417
- const [localWidgetState, setLocalWidgetState] = (0, import_react2.useState)(null);
2418
- (0, import_react2.useEffect)(() => {
2487
+ const mcp_url = (0, import_react4.useMemo)(() => {
2488
+ if (typeof window !== "undefined" && window.__mcpPublicUrl) {
2489
+ return window.__mcpPublicUrl.replace(/\/mcp-use\/public$/, "");
2490
+ }
2491
+ return "";
2492
+ }, []);
2493
+ const [localWidgetState, setLocalWidgetState] = (0, import_react4.useState)(null);
2494
+ (0, import_react4.useEffect)(() => {
2419
2495
  if (widgetState !== void 0) {
2420
2496
  setLocalWidgetState(widgetState);
2421
2497
  }
2422
2498
  }, [widgetState]);
2423
- const callTool = (0, import_react2.useCallback)(
2499
+ const callTool = (0, import_react4.useCallback)(
2424
2500
  async (name, args) => {
2425
2501
  if (!window.openai?.callTool) {
2426
2502
  throw new Error("window.openai.callTool is not available");
@@ -2429,7 +2505,7 @@ function useWidget(defaultProps) {
2429
2505
  },
2430
2506
  []
2431
2507
  );
2432
- const sendFollowUpMessage = (0, import_react2.useCallback)(
2508
+ const sendFollowUpMessage = (0, import_react4.useCallback)(
2433
2509
  async (prompt) => {
2434
2510
  if (!window.openai?.sendFollowUpMessage) {
2435
2511
  throw new Error("window.openai.sendFollowUpMessage is not available");
@@ -2438,13 +2514,13 @@ function useWidget(defaultProps) {
2438
2514
  },
2439
2515
  []
2440
2516
  );
2441
- const openExternal = (0, import_react2.useCallback)((href) => {
2517
+ const openExternal = (0, import_react4.useCallback)((href) => {
2442
2518
  if (!window.openai?.openExternal) {
2443
2519
  throw new Error("window.openai.openExternal is not available");
2444
2520
  }
2445
2521
  window.openai.openExternal({ href });
2446
2522
  }, []);
2447
- const requestDisplayMode = (0, import_react2.useCallback)(
2523
+ const requestDisplayMode = (0, import_react4.useCallback)(
2448
2524
  async (mode) => {
2449
2525
  if (!window.openai?.requestDisplayMode) {
2450
2526
  throw new Error("window.openai.requestDisplayMode is not available");
@@ -2453,16 +2529,17 @@ function useWidget(defaultProps) {
2453
2529
  },
2454
2530
  []
2455
2531
  );
2456
- const setState = (0, import_react2.useCallback)(
2532
+ const setState = (0, import_react4.useCallback)(
2457
2533
  async (state) => {
2458
- const newState = typeof state === "function" ? state(localWidgetState) : state;
2459
2534
  if (!window.openai?.setWidgetState) {
2460
2535
  throw new Error("window.openai.setWidgetState is not available");
2461
2536
  }
2537
+ const currentState = widgetState !== void 0 ? widgetState : localWidgetState;
2538
+ const newState = typeof state === "function" ? state(currentState) : state;
2462
2539
  setLocalWidgetState(newState);
2463
2540
  return window.openai.setWidgetState(newState);
2464
2541
  },
2465
- [localWidgetState]
2542
+ [widgetState, localWidgetState]
2466
2543
  );
2467
2544
  return {
2468
2545
  // Props and state (with defaults)
@@ -2481,6 +2558,7 @@ function useWidget(defaultProps) {
2481
2558
  capabilities: { hover: true, touch: false }
2482
2559
  },
2483
2560
  locale: locale || "en",
2561
+ mcp_url,
2484
2562
  // Actions
2485
2563
  callTool,
2486
2564
  sendFollowUpMessage,
@@ -2503,7 +2581,7 @@ function useWidgetTheme() {
2503
2581
  __name(useWidgetTheme, "useWidgetTheme");
2504
2582
  function useWidgetState(defaultState) {
2505
2583
  const { state, setState } = useWidget();
2506
- (0, import_react2.useEffect)(() => {
2584
+ (0, import_react4.useEffect)(() => {
2507
2585
  if (state === null && defaultState !== void 0 && window.openai?.setWidgetState) {
2508
2586
  setState(defaultState);
2509
2587
  }
@@ -2512,283 +2590,49 @@ function useWidgetState(defaultState) {
2512
2590
  }
2513
2591
  __name(useWidgetState, "useWidgetState");
2514
2592
 
2515
- // src/react/WidgetFullscreenWrapper.tsx
2516
- var import_react3 = __toESM(require("react"), 1);
2517
- function WidgetFullscreenWrapper({
2518
- children,
2519
- className = "",
2520
- position = "top-right",
2521
- attachTo,
2522
- showLabels = true
2523
- }) {
2524
- const { displayMode, requestDisplayMode, theme, safeArea, isAvailable } = useWidget();
2525
- const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
2526
- const containerRef = (0, import_react3.useRef)(null);
2527
- const isFullscreen = displayMode === "fullscreen" && isAvailable;
2528
- const isPip = displayMode === "pip" && isAvailable;
2529
- const isDark = theme === "dark";
2530
- const buttonBg = isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.7)";
2531
- const buttonBgHover = isDark ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.9)";
2532
- const buttonColor = "white";
2533
- const getPositionStyles = /* @__PURE__ */ __name(() => {
2534
- const baseOffset = 16;
2535
- const topOffset = safeArea?.insets?.top ? `${Math.max(baseOffset, safeArea.insets.top + 8)}px` : `${baseOffset}px`;
2536
- const rightOffset = safeArea?.insets?.right ? `${Math.max(baseOffset, safeArea.insets.right + 8)}px` : `${baseOffset}px`;
2537
- const bottomOffset = safeArea?.insets?.bottom ? `${Math.max(baseOffset, safeArea.insets.bottom + 8)}px` : `${baseOffset}px`;
2538
- const leftOffset = safeArea?.insets?.left ? `${Math.max(baseOffset, safeArea.insets.left + 8)}px` : `${baseOffset}px`;
2539
- const styles = {
2540
- position: "absolute",
2541
- zIndex: 1e3,
2542
- display: "flex",
2543
- gap: "8px",
2544
- opacity: isHovered ? 1 : 0,
2545
- transition: "opacity 0.2s ease-in-out",
2546
- pointerEvents: isHovered ? "auto" : "none"
2547
- };
2548
- switch (position) {
2549
- case "top-left":
2550
- styles.top = topOffset;
2551
- styles.left = leftOffset;
2552
- break;
2553
- case "top-center":
2554
- styles.top = topOffset;
2555
- styles.left = "50%";
2556
- styles.transform = "translateX(-50%)";
2557
- break;
2558
- case "top-right":
2559
- styles.top = topOffset;
2560
- styles.right = rightOffset;
2561
- break;
2562
- case "center-left":
2563
- styles.top = "50%";
2564
- styles.left = leftOffset;
2565
- styles.transform = "translateY(-50%)";
2566
- break;
2567
- case "center-right":
2568
- styles.top = "50%";
2569
- styles.right = rightOffset;
2570
- styles.transform = "translateY(-50%)";
2571
- break;
2572
- case "bottom-left":
2573
- styles.bottom = bottomOffset;
2574
- styles.left = leftOffset;
2575
- break;
2576
- case "bottom-center":
2577
- styles.bottom = bottomOffset;
2578
- styles.left = "50%";
2579
- styles.transform = "translateX(-50%)";
2580
- break;
2581
- case "bottom-right":
2582
- styles.bottom = bottomOffset;
2583
- styles.right = rightOffset;
2584
- break;
2585
- default:
2586
- styles.top = topOffset;
2587
- styles.right = rightOffset;
2588
- break;
2589
- }
2590
- return styles;
2591
- }, "getPositionStyles");
2592
- (0, import_react3.useEffect)(() => {
2593
- if (!attachTo) return;
2594
- const handleMouseEnter = /* @__PURE__ */ __name(() => setIsHovered(true), "handleMouseEnter");
2595
- const handleMouseLeave = /* @__PURE__ */ __name(() => setIsHovered(false), "handleMouseLeave");
2596
- attachTo.addEventListener("mouseenter", handleMouseEnter);
2597
- attachTo.addEventListener("mouseleave", handleMouseLeave);
2598
- return () => {
2599
- attachTo.removeEventListener("mouseenter", handleMouseEnter);
2600
- attachTo.removeEventListener("mouseleave", handleMouseLeave);
2601
- };
2602
- }, [attachTo]);
2603
- const handleFullscreen = /* @__PURE__ */ __name(async () => {
2604
- try {
2605
- await requestDisplayMode("fullscreen");
2606
- } catch (error) {
2607
- console.error("Failed to go fullscreen:", error);
2608
- }
2609
- }, "handleFullscreen");
2610
- const handlePip = /* @__PURE__ */ __name(async () => {
2611
- try {
2612
- await requestDisplayMode("pip");
2613
- } catch (error) {
2614
- console.error("Failed to go pip:", error);
2615
- }
2616
- }, "handlePip");
2617
- const getTooltipStyles = /* @__PURE__ */ __name(() => {
2618
- const baseStyles = {
2619
- position: "absolute",
2620
- padding: "4px 8px",
2621
- backgroundColor: isDark ? "rgba(0, 0, 0, 0.9)" : "rgba(0, 0, 0, 0.9)",
2622
- color: "white",
2623
- borderRadius: "4px",
2624
- fontSize: "12px",
2625
- whiteSpace: "nowrap",
2626
- pointerEvents: "none",
2627
- transition: "opacity 0.2s ease-in-out"
2628
- };
2629
- switch (position) {
2630
- case "top-right":
2631
- return {
2632
- ...baseStyles,
2633
- top: "100%",
2634
- right: "0",
2635
- marginTop: "8px"
2636
- };
2637
- case "top-left":
2638
- return {
2639
- ...baseStyles,
2640
- top: "100%",
2641
- left: "0",
2642
- marginTop: "8px"
2643
- };
2644
- case "top-center":
2645
- return {
2646
- ...baseStyles,
2647
- top: "100%",
2648
- left: "50%",
2649
- transform: "translateX(-50%)",
2650
- marginTop: "8px"
2651
- };
2652
- case "bottom-right":
2653
- return {
2654
- ...baseStyles,
2655
- bottom: "100%",
2656
- right: "0",
2657
- marginBottom: "8px"
2658
- };
2659
- case "bottom-left":
2660
- return {
2661
- ...baseStyles,
2662
- bottom: "100%",
2663
- left: "0",
2664
- marginBottom: "8px"
2665
- };
2666
- case "bottom-center":
2667
- return {
2668
- ...baseStyles,
2669
- bottom: "100%",
2670
- left: "50%",
2671
- transform: "translateX(-50%)",
2672
- marginBottom: "8px"
2673
- };
2674
- case "center-left":
2675
- return {
2676
- ...baseStyles,
2677
- left: "100%",
2678
- top: "50%",
2679
- transform: "translateY(-50%)",
2680
- marginLeft: "8px"
2681
- };
2682
- case "center-right":
2683
- return {
2684
- ...baseStyles,
2685
- right: "100%",
2686
- top: "50%",
2687
- transform: "translateY(-50%)",
2688
- marginRight: "8px"
2689
- };
2690
- default:
2691
- return {
2692
- ...baseStyles,
2693
- top: "100%",
2694
- right: "0",
2695
- marginTop: "8px"
2696
- };
2593
+ // src/react/ThemeProvider.tsx
2594
+ var ThemeProvider = /* @__PURE__ */ __name(({
2595
+ children
2596
+ }) => {
2597
+ const { theme, isAvailable } = useWidget();
2598
+ console.log("theme", theme);
2599
+ const [systemPreference, setSystemPreference] = (0, import_react5.useState)(
2600
+ () => {
2601
+ if (typeof window === "undefined") return "light";
2602
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
2697
2603
  }
2698
- }, "getTooltipStyles");
2699
- const IconButton = /* @__PURE__ */ __name(({
2700
- onClick,
2701
- label,
2702
- children: icon
2703
- }) => {
2704
- const [isButtonHovered, setIsButtonHovered] = (0, import_react3.useState)(false);
2705
- const tooltipStyles = getTooltipStyles();
2706
- return /* @__PURE__ */ import_react3.default.createElement(
2707
- "button",
2708
- {
2709
- style: {
2710
- padding: "8px",
2711
- backgroundColor: buttonBg,
2712
- color: buttonColor,
2713
- border: "none",
2714
- borderRadius: "8px",
2715
- cursor: "pointer",
2716
- display: "flex",
2717
- alignItems: "center",
2718
- justifyContent: "center",
2719
- width: "32px",
2720
- height: "32px",
2721
- transition: "background-color 0.2s",
2722
- backdropFilter: "blur(8px)",
2723
- WebkitBackdropFilter: "blur(8px)",
2724
- boxShadow: isDark ? "0 2px 8px rgba(0, 0, 0, 0.3)" : "0 2px 8px rgba(0, 0, 0, 0.2)",
2725
- position: "relative"
2726
- },
2727
- onMouseEnter: (e) => {
2728
- e.currentTarget.style.backgroundColor = buttonBgHover;
2729
- setIsButtonHovered(true);
2730
- },
2731
- onMouseLeave: (e) => {
2732
- e.currentTarget.style.backgroundColor = buttonBg;
2733
- setIsButtonHovered(false);
2734
- },
2735
- onClick,
2736
- "aria-label": label
2737
- },
2738
- /* @__PURE__ */ import_react3.default.createElement(
2739
- "svg",
2740
- {
2741
- xmlns: "http://www.w3.org/2000/svg",
2742
- width: "16",
2743
- height: "16",
2744
- viewBox: "0 0 24 24",
2745
- fill: "none",
2746
- stroke: "currentColor",
2747
- strokeWidth: "2",
2748
- strokeLinecap: "round",
2749
- strokeLinejoin: "round",
2750
- style: { display: "block" }
2751
- },
2752
- icon
2753
- ),
2754
- showLabels && /* @__PURE__ */ import_react3.default.createElement(
2755
- "span",
2756
- {
2757
- style: {
2758
- ...tooltipStyles,
2759
- opacity: isButtonHovered ? 1 : 0
2760
- }
2761
- },
2762
- label
2763
- )
2764
- );
2765
- }, "IconButton");
2766
- return /* @__PURE__ */ import_react3.default.createElement(
2767
- "div",
2768
- {
2769
- ref: containerRef,
2770
- className,
2771
- style: {
2772
- position: "relative",
2773
- height: "fit-content"
2774
- },
2775
- onMouseEnter: () => !attachTo && setIsHovered(true),
2776
- onMouseLeave: () => !attachTo && setIsHovered(false)
2777
- },
2778
- !isFullscreen && !isPip && /* @__PURE__ */ import_react3.default.createElement("div", { style: getPositionStyles() }, /* @__PURE__ */ import_react3.default.createElement(IconButton, { onClick: handleFullscreen, label: "Fullscreen" }, /* @__PURE__ */ import_react3.default.createElement("path", { d: "M15 3h6v6" }), /* @__PURE__ */ import_react3.default.createElement("path", { d: "m21 3-7 7" }), /* @__PURE__ */ import_react3.default.createElement("path", { d: "m3 21 7-7" }), /* @__PURE__ */ import_react3.default.createElement("path", { d: "M9 21H3v-6" })), /* @__PURE__ */ import_react3.default.createElement(IconButton, { onClick: handlePip, label: "Picture in Picture" }, /* @__PURE__ */ import_react3.default.createElement("path", { d: "M21 9V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10c0 1.1.9 2 2 2h4" }), /* @__PURE__ */ import_react3.default.createElement("rect", { width: "10", height: "7", x: "12", y: "13", rx: "2" }))),
2779
- children
2780
2604
  );
2781
- }
2782
- __name(WidgetFullscreenWrapper, "WidgetFullscreenWrapper");
2605
+ (0, import_react5.useEffect)(() => {
2606
+ if (typeof window === "undefined") return;
2607
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
2608
+ const handleChange = /* @__PURE__ */ __name((e) => {
2609
+ setSystemPreference(e.matches ? "dark" : "light");
2610
+ }, "handleChange");
2611
+ mediaQuery.addEventListener("change", handleChange);
2612
+ return () => mediaQuery.removeEventListener("change", handleChange);
2613
+ }, []);
2614
+ const effectiveTheme = isAvailable ? theme : systemPreference;
2615
+ (0, import_react5.useLayoutEffect)(() => {
2616
+ if (typeof document === "undefined") return;
2617
+ if (effectiveTheme === "dark") {
2618
+ document.documentElement.classList.add("dark");
2619
+ } else {
2620
+ document.documentElement.classList.remove("dark");
2621
+ }
2622
+ }, [effectiveTheme]);
2623
+ return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, children);
2624
+ }, "ThemeProvider");
2783
2625
 
2784
- // src/react/WidgetDebugger.tsx
2785
- var import_react4 = __toESM(require("react"), 1);
2786
- function WidgetDebugger({
2626
+ // src/react/WidgetControls.tsx
2627
+ var import_react6 = __toESM(require("react"), 1);
2628
+ function WidgetControls({
2787
2629
  children,
2788
2630
  className = "",
2789
2631
  position = "top-right",
2790
2632
  attachTo,
2791
- showLabels = true
2633
+ showLabels = true,
2634
+ debugger: enableDebugger = false,
2635
+ viewControls = false
2792
2636
  }) {
2793
2637
  const {
2794
2638
  props,
@@ -2808,23 +2652,24 @@ function WidgetDebugger({
2808
2652
  requestDisplayMode,
2809
2653
  setState
2810
2654
  } = useWidget();
2811
- const [isHovered, setIsHovered] = (0, import_react4.useState)(false);
2812
- const [isOverlayOpen, setIsOverlayOpen] = (0, import_react4.useState)(false);
2813
- const containerRef = (0, import_react4.useRef)(null);
2814
- const overlayRef = (0, import_react4.useRef)(null);
2815
- const [windowOpenAiKeys, setWindowOpenAiKeys] = (0, import_react4.useState)([]);
2816
- const [actionResult, setActionResult] = (0, import_react4.useState)("");
2817
- const [toolName, setToolName] = (0, import_react4.useState)("get-my-city");
2818
- const [toolArgs, setToolArgs] = (0, import_react4.useState)("{}");
2819
- const [followUpMessage, setFollowUpMessage] = (0, import_react4.useState)(
2655
+ const [isHovered, setIsHovered] = (0, import_react6.useState)(false);
2656
+ const [isOverlayOpen, setIsOverlayOpen] = (0, import_react6.useState)(false);
2657
+ const containerRef = (0, import_react6.useRef)(null);
2658
+ const overlayRef = (0, import_react6.useRef)(null);
2659
+ const [windowOpenAiKeys, setWindowOpenAiKeys] = (0, import_react6.useState)([]);
2660
+ const [actionResult, setActionResult] = (0, import_react6.useState)("");
2661
+ const [toolName, setToolName] = (0, import_react6.useState)("get-my-city");
2662
+ const [toolArgs, setToolArgs] = (0, import_react6.useState)("{}");
2663
+ const [followUpMessage, setFollowUpMessage] = (0, import_react6.useState)(
2820
2664
  "Test follow-up message"
2821
2665
  );
2822
- const [externalUrl, setExternalUrl] = (0, import_react4.useState)(
2666
+ const [externalUrl, setExternalUrl] = (0, import_react6.useState)(
2823
2667
  "https://docs.mcp-use.com"
2824
2668
  );
2825
2669
  const isFullscreen = displayMode === "fullscreen" && isAvailable;
2826
2670
  const isPip = displayMode === "pip" && isAvailable;
2827
- (0, import_react4.useEffect)(() => {
2671
+ const isDevMode = typeof window !== "undefined" && window.location.pathname.includes("/inspector/api/dev-widget/");
2672
+ (0, import_react6.useEffect)(() => {
2828
2673
  const timeoutId = setTimeout(() => {
2829
2674
  if (typeof window !== "undefined" && window.openai) {
2830
2675
  try {
@@ -2837,75 +2682,88 @@ function WidgetDebugger({
2837
2682
  setWindowOpenAiKeys([]);
2838
2683
  }
2839
2684
  }, 100);
2840
- return () => clearTimeout(timeoutId);
2685
+ return () => {
2686
+ clearTimeout(timeoutId);
2687
+ };
2841
2688
  }, []);
2842
2689
  const isDark = theme === "dark";
2843
- const buttonBg = isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.7)";
2844
- const buttonBgHover = isDark ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.9)";
2845
- const buttonColor = "white";
2846
- const getPositionStyles = /* @__PURE__ */ __name(() => {
2690
+ const getPositionClasses = /* @__PURE__ */ __name(() => {
2691
+ const baseClasses = [
2692
+ "absolute",
2693
+ "z-[1000]",
2694
+ "flex",
2695
+ "gap-2",
2696
+ "transition-opacity",
2697
+ "duration-200",
2698
+ "ease-in-out",
2699
+ isHovered ? "opacity-100" : "opacity-0",
2700
+ isHovered ? "pointer-events-auto" : "pointer-events-none"
2701
+ ];
2702
+ switch (position) {
2703
+ case "top-left":
2704
+ return [...baseClasses, "top-4", "left-4"];
2705
+ case "top-center":
2706
+ return [...baseClasses, "top-4", "left-1/2", "-translate-x-1/2"];
2707
+ case "top-right":
2708
+ return [...baseClasses, "top-4", "right-4"];
2709
+ case "center-left":
2710
+ return [...baseClasses, "top-1/2", "left-4", "-translate-y-1/2"];
2711
+ case "center-right":
2712
+ return [...baseClasses, "top-1/2", "right-4", "-translate-y-1/2"];
2713
+ case "bottom-left":
2714
+ return [...baseClasses, "bottom-4", "left-4"];
2715
+ case "bottom-center":
2716
+ return [...baseClasses, "bottom-4", "left-1/2", "-translate-x-1/2"];
2717
+ case "bottom-right":
2718
+ return [...baseClasses, "bottom-4", "right-4"];
2719
+ default:
2720
+ return [...baseClasses, "top-4", "right-4"];
2721
+ }
2722
+ }, "getPositionClasses");
2723
+ const getPositionOffsetStyles = /* @__PURE__ */ __name(() => {
2847
2724
  const baseOffset = 16;
2848
- const topOffset = safeArea?.insets?.top ? `${Math.max(baseOffset, safeArea.insets.top + 8)}px` : `${baseOffset}px`;
2849
- const rightOffset = safeArea?.insets?.right ? `${Math.max(baseOffset, safeArea.insets.right + 8)}px` : `${baseOffset}px`;
2850
- const bottomOffset = safeArea?.insets?.bottom ? `${Math.max(baseOffset, safeArea.insets.bottom + 8)}px` : `${baseOffset}px`;
2851
- const leftOffset = safeArea?.insets?.left ? `${Math.max(baseOffset, safeArea.insets.left + 8)}px` : `${baseOffset}px`;
2852
- const styles = {
2853
- position: "absolute",
2854
- zIndex: 1e3,
2855
- display: "flex",
2856
- gap: "8px",
2857
- opacity: isHovered ? 1 : 0,
2858
- transition: "opacity 0.2s ease-in-out",
2859
- pointerEvents: isHovered ? "auto" : "none"
2860
- };
2725
+ const topOffset = safeArea?.insets?.top ? Math.max(baseOffset, safeArea.insets.top + 8) : baseOffset;
2726
+ const rightOffset = safeArea?.insets?.right ? Math.max(baseOffset, safeArea.insets.right + 8) : baseOffset;
2727
+ const bottomOffset = safeArea?.insets?.bottom ? Math.max(baseOffset, safeArea.insets.bottom + 8) : baseOffset;
2728
+ const leftOffset = safeArea?.insets?.left ? Math.max(baseOffset, safeArea.insets.left + 8) : baseOffset;
2729
+ const styles = {};
2861
2730
  switch (position) {
2862
2731
  case "top-left":
2863
- styles.top = topOffset;
2864
- styles.left = leftOffset;
2732
+ styles.top = `${topOffset}px`;
2733
+ styles.left = `${leftOffset}px`;
2865
2734
  break;
2866
2735
  case "top-center":
2867
- styles.top = topOffset;
2868
- styles.left = "50%";
2869
- styles.transform = "translateX(-50%)";
2736
+ styles.top = `${topOffset}px`;
2870
2737
  break;
2871
2738
  case "top-right":
2872
- styles.top = topOffset;
2873
- styles.right = rightOffset;
2874
- if (!isFullscreen && !isPip) {
2875
- styles.right = `calc(${rightOffset} + 80px)`;
2876
- }
2739
+ styles.top = `${topOffset}px`;
2740
+ styles.right = `${rightOffset}px`;
2877
2741
  break;
2878
2742
  case "center-left":
2879
- styles.top = "50%";
2880
- styles.left = leftOffset;
2881
- styles.transform = "translateY(-50%)";
2743
+ styles.left = `${leftOffset}px`;
2882
2744
  break;
2883
2745
  case "center-right":
2884
- styles.top = "50%";
2885
- styles.right = rightOffset;
2886
- styles.transform = "translateY(-50%)";
2746
+ styles.right = `${rightOffset}px`;
2887
2747
  break;
2888
2748
  case "bottom-left":
2889
- styles.bottom = bottomOffset;
2890
- styles.left = leftOffset;
2749
+ styles.bottom = `${bottomOffset}px`;
2750
+ styles.left = `${leftOffset}px`;
2891
2751
  break;
2892
2752
  case "bottom-center":
2893
- styles.bottom = bottomOffset;
2894
- styles.left = "50%";
2895
- styles.transform = "translateX(-50%)";
2753
+ styles.bottom = `${bottomOffset}px`;
2896
2754
  break;
2897
2755
  case "bottom-right":
2898
- styles.bottom = bottomOffset;
2899
- styles.right = rightOffset;
2756
+ styles.bottom = `${bottomOffset}px`;
2757
+ styles.right = `${rightOffset}px`;
2900
2758
  break;
2901
2759
  default:
2902
- styles.top = topOffset;
2903
- styles.right = rightOffset;
2760
+ styles.top = `${topOffset}px`;
2761
+ styles.right = `${rightOffset}px`;
2904
2762
  break;
2905
2763
  }
2906
2764
  return styles;
2907
- }, "getPositionStyles");
2908
- (0, import_react4.useEffect)(() => {
2765
+ }, "getPositionOffsetStyles");
2766
+ (0, import_react6.useEffect)(() => {
2909
2767
  if (!attachTo) return;
2910
2768
  const handleMouseEnter = /* @__PURE__ */ __name(() => setIsHovered(true), "handleMouseEnter");
2911
2769
  const handleMouseLeave = /* @__PURE__ */ __name(() => setIsHovered(false), "handleMouseLeave");
@@ -2916,7 +2774,7 @@ function WidgetDebugger({
2916
2774
  attachTo.removeEventListener("mouseleave", handleMouseLeave);
2917
2775
  };
2918
2776
  }, [attachTo]);
2919
- (0, import_react4.useEffect)(() => {
2777
+ (0, import_react6.useEffect)(() => {
2920
2778
  if (!isOverlayOpen) return;
2921
2779
  const handleClickOutside = /* @__PURE__ */ __name((event) => {
2922
2780
  if (overlayRef.current && !overlayRef.current.contains(event.target)) {
@@ -2928,7 +2786,7 @@ function WidgetDebugger({
2928
2786
  document.removeEventListener("mousedown", handleClickOutside);
2929
2787
  };
2930
2788
  }, [isOverlayOpen]);
2931
- (0, import_react4.useEffect)(() => {
2789
+ (0, import_react6.useEffect)(() => {
2932
2790
  if (isOverlayOpen) {
2933
2791
  document.body.style.overflow = "hidden";
2934
2792
  } else {
@@ -2987,128 +2845,97 @@ function WidgetDebugger({
2987
2845
  setActionResult(`Error: ${error.message}`);
2988
2846
  }
2989
2847
  }, "handleSetState");
2990
- const getTooltipStyles = /* @__PURE__ */ __name(() => {
2991
- const baseStyles = {
2992
- position: "absolute",
2993
- padding: "4px 8px",
2994
- backgroundColor: "rgba(0, 0, 0, 0.9)",
2995
- color: "white",
2996
- borderRadius: "4px",
2997
- fontSize: "12px",
2998
- whiteSpace: "nowrap",
2999
- pointerEvents: "none",
3000
- transition: "opacity 0.2s ease-in-out"
3001
- };
2848
+ const handleFullscreen = /* @__PURE__ */ __name(async () => {
2849
+ try {
2850
+ await requestDisplayMode("fullscreen");
2851
+ } catch (error) {
2852
+ console.error("Failed to go fullscreen:", error);
2853
+ }
2854
+ }, "handleFullscreen");
2855
+ const handlePip = /* @__PURE__ */ __name(async () => {
2856
+ try {
2857
+ await requestDisplayMode("pip");
2858
+ } catch (error) {
2859
+ console.error("Failed to go pip:", error);
2860
+ }
2861
+ }, "handlePip");
2862
+ const getTooltipClasses = /* @__PURE__ */ __name(() => {
2863
+ const baseClasses = [
2864
+ "absolute",
2865
+ "px-2",
2866
+ "py-1",
2867
+ "bg-black/90",
2868
+ "text-white",
2869
+ "rounded",
2870
+ "text-xs",
2871
+ "whitespace-nowrap",
2872
+ "pointer-events-none",
2873
+ "transition-opacity",
2874
+ "duration-200",
2875
+ "ease-in-out"
2876
+ ];
3002
2877
  switch (position) {
3003
2878
  case "top-right":
3004
- return {
3005
- ...baseStyles,
3006
- top: "100%",
3007
- right: "0",
3008
- marginTop: "8px"
3009
- };
2879
+ return [...baseClasses, "top-full", "right-0", "mt-2"];
3010
2880
  case "top-left":
3011
- return {
3012
- ...baseStyles,
3013
- top: "100%",
3014
- left: "0",
3015
- marginTop: "8px"
3016
- };
2881
+ return [...baseClasses, "top-full", "left-0", "mt-2"];
3017
2882
  case "top-center":
3018
- return {
3019
- ...baseStyles,
3020
- top: "100%",
3021
- left: "50%",
3022
- transform: "translateX(-50%)",
3023
- marginTop: "8px"
3024
- };
2883
+ return [
2884
+ ...baseClasses,
2885
+ "top-full",
2886
+ "left-1/2",
2887
+ "-translate-x-1/2",
2888
+ "mt-2"
2889
+ ];
3025
2890
  case "bottom-right":
3026
- return {
3027
- ...baseStyles,
3028
- bottom: "100%",
3029
- right: "0",
3030
- marginBottom: "8px"
3031
- };
2891
+ return [...baseClasses, "bottom-full", "right-0", "mb-2"];
3032
2892
  case "bottom-left":
3033
- return {
3034
- ...baseStyles,
3035
- bottom: "100%",
3036
- left: "0",
3037
- marginBottom: "8px"
3038
- };
2893
+ return [...baseClasses, "bottom-full", "left-0", "mb-2"];
3039
2894
  case "bottom-center":
3040
- return {
3041
- ...baseStyles,
3042
- bottom: "100%",
3043
- left: "50%",
3044
- transform: "translateX(-50%)",
3045
- marginBottom: "8px"
3046
- };
2895
+ return [
2896
+ ...baseClasses,
2897
+ "bottom-full",
2898
+ "left-1/2",
2899
+ "-translate-x-1/2",
2900
+ "mb-2"
2901
+ ];
3047
2902
  case "center-left":
3048
- return {
3049
- ...baseStyles,
3050
- left: "100%",
3051
- top: "50%",
3052
- transform: "translateY(-50%)",
3053
- marginLeft: "8px"
3054
- };
2903
+ return [
2904
+ ...baseClasses,
2905
+ "left-full",
2906
+ "top-1/2",
2907
+ "-translate-y-1/2",
2908
+ "ml-2"
2909
+ ];
3055
2910
  case "center-right":
3056
- return {
3057
- ...baseStyles,
3058
- right: "100%",
3059
- top: "50%",
3060
- transform: "translateY(-50%)",
3061
- marginRight: "8px"
3062
- };
2911
+ return [
2912
+ ...baseClasses,
2913
+ "right-full",
2914
+ "top-1/2",
2915
+ "-translate-y-1/2",
2916
+ "mr-2"
2917
+ ];
3063
2918
  default:
3064
- return {
3065
- ...baseStyles,
3066
- top: "100%",
3067
- right: "0",
3068
- marginTop: "8px"
3069
- };
2919
+ return [...baseClasses, "top-full", "right-0", "mt-2"];
3070
2920
  }
3071
- }, "getTooltipStyles");
2921
+ }, "getTooltipClasses");
3072
2922
  const IconButton = /* @__PURE__ */ __name(({
3073
2923
  onClick,
3074
2924
  label,
3075
2925
  children: icon
3076
2926
  }) => {
3077
- const [isButtonHovered, setIsButtonHovered] = (0, import_react4.useState)(false);
3078
- const tooltipStyles = getTooltipStyles();
3079
- return /* @__PURE__ */ import_react4.default.createElement(
2927
+ const [isButtonHovered, setIsButtonHovered] = (0, import_react6.useState)(false);
2928
+ const tooltipClasses = getTooltipClasses();
2929
+ return /* @__PURE__ */ import_react6.default.createElement(
3080
2930
  "button",
3081
2931
  {
3082
- style: {
3083
- padding: "8px",
3084
- backgroundColor: buttonBg,
3085
- color: buttonColor,
3086
- border: "none",
3087
- borderRadius: "8px",
3088
- cursor: "pointer",
3089
- display: "flex",
3090
- alignItems: "center",
3091
- justifyContent: "center",
3092
- width: "32px",
3093
- height: "32px",
3094
- transition: "background-color 0.2s",
3095
- backdropFilter: "blur(8px)",
3096
- WebkitBackdropFilter: "blur(8px)",
3097
- boxShadow: isDark ? "0 2px 8px rgba(0, 0, 0, 0.3)" : "0 2px 8px rgba(0, 0, 0, 0.2)",
3098
- position: "relative"
3099
- },
3100
- onMouseEnter: (e) => {
3101
- e.currentTarget.style.backgroundColor = buttonBgHover;
3102
- setIsButtonHovered(true);
3103
- },
3104
- onMouseLeave: (e) => {
3105
- e.currentTarget.style.backgroundColor = buttonBg;
3106
- setIsButtonHovered(false);
3107
- },
2932
+ className: `p-2 ${isDark ? "bg-white/10 hover:bg-white/20" : "bg-black/70 hover:bg-black/90"} text-white border-none rounded-lg cursor-pointer flex items-center justify-center w-8 h-8 transition-colors duration-200 backdrop-blur-md ${isDark ? "shadow-[0_2px_8px_rgba(0,0,0,0.3)]" : "shadow-[0_2px_8px_rgba(0,0,0,0.2)]"} relative`,
2933
+ onMouseEnter: () => setIsButtonHovered(true),
2934
+ onMouseLeave: () => setIsButtonHovered(false),
3108
2935
  onClick,
3109
2936
  "aria-label": label
3110
2937
  },
3111
- /* @__PURE__ */ import_react4.default.createElement(
2938
+ /* @__PURE__ */ import_react6.default.createElement(
3112
2939
  "svg",
3113
2940
  {
3114
2941
  xmlns: "http://www.w3.org/2000/svg",
@@ -3120,17 +2947,14 @@ function WidgetDebugger({
3120
2947
  strokeWidth: "2",
3121
2948
  strokeLinecap: "round",
3122
2949
  strokeLinejoin: "round",
3123
- style: { display: "block" }
2950
+ className: "block"
3124
2951
  },
3125
2952
  icon
3126
2953
  ),
3127
- showLabels && /* @__PURE__ */ import_react4.default.createElement(
2954
+ showLabels && /* @__PURE__ */ import_react6.default.createElement(
3128
2955
  "span",
3129
2956
  {
3130
- style: {
3131
- ...tooltipStyles,
3132
- opacity: isButtonHovered ? 1 : 0
3133
- }
2957
+ className: `${tooltipClasses.join(" ")} ${isButtonHovered ? "opacity-100" : "opacity-0"}`
3134
2958
  },
3135
2959
  label
3136
2960
  )
@@ -3157,567 +2981,245 @@ function WidgetDebugger({
3157
2981
  const { top, bottom, left, right } = sa.insets;
3158
2982
  return `T:${top} B:${bottom} L:${left} R:${right}`;
3159
2983
  }, "formatSafeArea");
3160
- return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(
2984
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(
3161
2985
  "div",
3162
2986
  {
3163
2987
  ref: containerRef,
3164
- className,
3165
- style: {
3166
- position: "relative",
3167
- height: "fit-content"
3168
- },
2988
+ className: `${className} relative h-fit`,
3169
2989
  onMouseEnter: () => !attachTo && setIsHovered(true),
3170
2990
  onMouseLeave: () => !attachTo && setIsHovered(false)
3171
2991
  },
3172
- /* @__PURE__ */ import_react4.default.createElement("div", { style: getPositionStyles() }, /* @__PURE__ */ import_react4.default.createElement(IconButton, { onClick: handleToggleOverlay, label: "Debug Info" }, /* @__PURE__ */ import_react4.default.createElement("path", { d: "M12 20v-9" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M14.12 3.88 16 2" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M21 21a4 4 0 0 0-3.81-4" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M21 5a4 4 0 0 1-3.55 3.97" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M22 13h-4" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M3 21a4 4 0 0 1 3.81-4" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M3 5a4 4 0 0 0 3.55 3.97" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M6 13H2" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "m8 2 1.88 1.88" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M9 7.13V6a3 3 0 1 1 6 0v1.13" }))),
2992
+ /* @__PURE__ */ import_react6.default.createElement(
2993
+ "div",
2994
+ {
2995
+ className: getPositionClasses().join(" "),
2996
+ style: getPositionOffsetStyles()
2997
+ },
2998
+ !isDevMode && /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, !isFullscreen && !isPip && /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, (viewControls === true || viewControls === "fullscreen") && /* @__PURE__ */ import_react6.default.createElement(IconButton, { onClick: handleFullscreen, label: "Fullscreen" }, /* @__PURE__ */ import_react6.default.createElement("path", { d: "M15 3h6v6" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "m21 3-7 7" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "m3 21 7-7" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M9 21H3v-6" })), (viewControls === true || viewControls === "pip") && /* @__PURE__ */ import_react6.default.createElement(IconButton, { onClick: handlePip, label: "Picture in Picture" }, /* @__PURE__ */ import_react6.default.createElement("path", { d: "M21 9V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10c0 1.1.9 2 2 2h4" }), /* @__PURE__ */ import_react6.default.createElement("rect", { width: "10", height: "7", x: "12", y: "13", rx: "2" }))), enableDebugger && /* @__PURE__ */ import_react6.default.createElement(IconButton, { onClick: handleToggleOverlay, label: "Debug Info" }, /* @__PURE__ */ import_react6.default.createElement("path", { d: "M12 20v-9" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M14.12 3.88 16 2" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M21 21a4 4 0 0 0-3.81-4" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M21 5a4 4 0 0 1-3.55 3.97" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M22 13h-4" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M3 21a4 4 0 0 1 3.81-4" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M3 5a4 4 0 0 0 3.55 3.97" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M6 13H2" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "m8 2 1.88 1.88" }), /* @__PURE__ */ import_react6.default.createElement("path", { d: "M9 7.13V6a3 3 0 1 1 6 0v1.13" })))
2999
+ ),
3173
3000
  children
3174
- ), isOverlayOpen && /* @__PURE__ */ import_react4.default.createElement(
3001
+ ), isOverlayOpen && enableDebugger && /* @__PURE__ */ import_react6.default.createElement(
3175
3002
  "div",
3176
3003
  {
3177
3004
  ref: overlayRef,
3178
- style: {
3179
- position: "fixed",
3180
- top: 0,
3181
- left: 0,
3182
- right: 0,
3183
- bottom: 0,
3184
- backgroundColor: "#000000",
3185
- color: "#ffffff",
3186
- fontFamily: "monospace",
3187
- fontSize: "12px",
3188
- zIndex: 1e4,
3189
- overflow: "auto",
3190
- padding: "16px"
3191
- },
3005
+ className: "fixed inset-0 bg-black text-white font-mono text-xs z-[10000] overflow-auto p-4",
3192
3006
  onClick: (e) => {
3193
3007
  if (e.target === overlayRef.current) {
3194
3008
  setIsOverlayOpen(false);
3195
3009
  }
3196
3010
  }
3197
3011
  },
3198
- /* @__PURE__ */ import_react4.default.createElement(
3012
+ /* @__PURE__ */ import_react6.default.createElement(
3199
3013
  "button",
3200
3014
  {
3201
3015
  onClick: () => setIsOverlayOpen(false),
3202
- style: {
3203
- position: "absolute",
3204
- top: "16px",
3205
- right: "16px",
3206
- backgroundColor: "rgba(255, 255, 255, 0.1)",
3207
- color: "#ffffff",
3208
- border: "none",
3209
- borderRadius: "4px",
3210
- width: "32px",
3211
- height: "32px",
3212
- cursor: "pointer",
3213
- display: "flex",
3214
- alignItems: "center",
3215
- justifyContent: "center",
3216
- fontSize: "18px",
3217
- lineHeight: 1
3218
- },
3016
+ className: "absolute top-4 right-4 bg-white/10 text-white border-none rounded w-8 h-8 cursor-pointer flex items-center justify-center text-lg leading-none",
3219
3017
  "aria-label": "Close"
3220
3018
  },
3221
3019
  "\xD7"
3222
3020
  ),
3223
- /* @__PURE__ */ import_react4.default.createElement(
3224
- "div",
3021
+ /* @__PURE__ */ import_react6.default.createElement("div", { className: "max-w-[1200px] mx-auto pt-10" }, /* @__PURE__ */ import_react6.default.createElement("h1", { className: "text-lg font-bold mb-4 border-b border-gray-700 pb-2" }, "Debug Info"), /* @__PURE__ */ import_react6.default.createElement("table", { className: "w-full border-collapse border-spacing-0" }, /* @__PURE__ */ import_react6.default.createElement("tbody", null, /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Props"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 whitespace-pre-wrap break-all" }, formatValue(props))), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Output"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 whitespace-pre-wrap break-all" }, formatValue(output))), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Metadata"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 whitespace-pre-wrap break-all" }, formatValue(metadata))), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "State"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 whitespace-pre-wrap break-all" }, formatValue(state))), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Theme"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2" }, theme)), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Display Mode"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2" }, displayMode)), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Locale"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2" }, locale)), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Max Height"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2" }, maxHeight, "px")), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "User Agent"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2" }, formatUserAgent(userAgent))), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Safe Area"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2" }, formatSafeArea(safeArea))), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "API Available"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2" }, isAvailable ? "Yes" : "No")), /* @__PURE__ */ import_react6.default.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "window.openai Keys"), /* @__PURE__ */ import_react6.default.createElement("td", { className: "p-2" }, windowOpenAiKeys.length > 0 ? windowOpenAiKeys.join(", ") : "N/A")))), /* @__PURE__ */ import_react6.default.createElement("h2", { className: "text-base font-bold mt-8 mb-4 border-b border-gray-700 pb-2" }, "Actions"), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
3022
+ "input",
3225
3023
  {
3226
- style: { maxWidth: "1200px", margin: "0 auto", paddingTop: "40px" }
3024
+ type: "text",
3025
+ value: toolName,
3026
+ onChange: (e) => setToolName(e.target.value),
3027
+ placeholder: "Tool name",
3028
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs w-[150px]"
3029
+ }
3030
+ ), /* @__PURE__ */ import_react6.default.createElement(
3031
+ "input",
3032
+ {
3033
+ type: "text",
3034
+ value: toolArgs,
3035
+ onChange: (e) => setToolArgs(e.target.value),
3036
+ placeholder: '{"key": "value"}',
3037
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
3038
+ }
3039
+ ), /* @__PURE__ */ import_react6.default.createElement(
3040
+ "button",
3041
+ {
3042
+ onClick: handleCallTool,
3043
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
3227
3044
  },
3228
- /* @__PURE__ */ import_react4.default.createElement(
3229
- "h1",
3230
- {
3231
- style: {
3232
- fontSize: "18px",
3233
- fontWeight: "bold",
3234
- marginBottom: "16px",
3235
- borderBottom: "1px solid #333",
3236
- paddingBottom: "8px"
3237
- }
3238
- },
3239
- "Debug Info"
3240
- ),
3241
- /* @__PURE__ */ import_react4.default.createElement(
3242
- "table",
3243
- {
3244
- style: {
3245
- width: "100%",
3246
- borderCollapse: "collapse",
3247
- borderSpacing: 0
3248
- }
3249
- },
3250
- /* @__PURE__ */ import_react4.default.createElement("tbody", null, /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3251
- "td",
3252
- {
3253
- style: {
3254
- padding: "8px",
3255
- fontWeight: "bold",
3256
- width: "200px",
3257
- verticalAlign: "top"
3258
- }
3259
- },
3260
- "Props"
3261
- ), /* @__PURE__ */ import_react4.default.createElement(
3262
- "td",
3263
- {
3264
- style: {
3265
- padding: "8px",
3266
- whiteSpace: "pre-wrap",
3267
- wordBreak: "break-all"
3268
- }
3269
- },
3270
- formatValue(props)
3271
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3272
- "td",
3273
- {
3274
- style: {
3275
- padding: "8px",
3276
- fontWeight: "bold",
3277
- width: "200px",
3278
- verticalAlign: "top"
3279
- }
3280
- },
3281
- "Output"
3282
- ), /* @__PURE__ */ import_react4.default.createElement(
3283
- "td",
3284
- {
3285
- style: {
3286
- padding: "8px",
3287
- whiteSpace: "pre-wrap",
3288
- wordBreak: "break-all"
3289
- }
3290
- },
3291
- formatValue(output)
3292
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3293
- "td",
3294
- {
3295
- style: {
3296
- padding: "8px",
3297
- fontWeight: "bold",
3298
- width: "200px",
3299
- verticalAlign: "top"
3300
- }
3301
- },
3302
- "Metadata"
3303
- ), /* @__PURE__ */ import_react4.default.createElement(
3304
- "td",
3305
- {
3306
- style: {
3307
- padding: "8px",
3308
- whiteSpace: "pre-wrap",
3309
- wordBreak: "break-all"
3310
- }
3311
- },
3312
- formatValue(metadata)
3313
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3314
- "td",
3315
- {
3316
- style: {
3317
- padding: "8px",
3318
- fontWeight: "bold",
3319
- width: "200px",
3320
- verticalAlign: "top"
3321
- }
3322
- },
3323
- "State"
3324
- ), /* @__PURE__ */ import_react4.default.createElement(
3325
- "td",
3326
- {
3327
- style: {
3328
- padding: "8px",
3329
- whiteSpace: "pre-wrap",
3330
- wordBreak: "break-all"
3331
- }
3332
- },
3333
- formatValue(state)
3334
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3335
- "td",
3336
- {
3337
- style: {
3338
- padding: "8px",
3339
- fontWeight: "bold",
3340
- width: "200px",
3341
- verticalAlign: "top"
3342
- }
3343
- },
3344
- "Theme"
3345
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, theme)), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3346
- "td",
3347
- {
3348
- style: {
3349
- padding: "8px",
3350
- fontWeight: "bold",
3351
- width: "200px",
3352
- verticalAlign: "top"
3353
- }
3354
- },
3355
- "Display Mode"
3356
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, displayMode)), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3357
- "td",
3358
- {
3359
- style: {
3360
- padding: "8px",
3361
- fontWeight: "bold",
3362
- width: "200px",
3363
- verticalAlign: "top"
3364
- }
3365
- },
3366
- "Locale"
3367
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, locale)), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3368
- "td",
3369
- {
3370
- style: {
3371
- padding: "8px",
3372
- fontWeight: "bold",
3373
- width: "200px",
3374
- verticalAlign: "top"
3375
- }
3376
- },
3377
- "Max Height"
3378
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, maxHeight, "px")), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3379
- "td",
3380
- {
3381
- style: {
3382
- padding: "8px",
3383
- fontWeight: "bold",
3384
- width: "200px",
3385
- verticalAlign: "top"
3386
- }
3387
- },
3388
- "User Agent"
3389
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, formatUserAgent(userAgent))), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3390
- "td",
3391
- {
3392
- style: {
3393
- padding: "8px",
3394
- fontWeight: "bold",
3395
- width: "200px",
3396
- verticalAlign: "top"
3397
- }
3398
- },
3399
- "Safe Area"
3400
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, formatSafeArea(safeArea))), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3401
- "td",
3402
- {
3403
- style: {
3404
- padding: "8px",
3405
- fontWeight: "bold",
3406
- width: "200px",
3407
- verticalAlign: "top"
3408
- }
3409
- },
3410
- "API Available"
3411
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, isAvailable ? "Yes" : "No")), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
3412
- "td",
3413
- {
3414
- style: {
3415
- padding: "8px",
3416
- fontWeight: "bold",
3417
- width: "200px",
3418
- verticalAlign: "top"
3419
- }
3420
- },
3421
- "window.openai Keys"
3422
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, windowOpenAiKeys.length > 0 ? windowOpenAiKeys.join(", ") : "N/A")))
3423
- ),
3424
- /* @__PURE__ */ import_react4.default.createElement(
3425
- "h2",
3426
- {
3427
- style: {
3428
- fontSize: "16px",
3429
- fontWeight: "bold",
3430
- marginTop: "32px",
3431
- marginBottom: "16px",
3432
- borderBottom: "1px solid #333",
3433
- paddingBottom: "8px"
3434
- }
3435
- },
3436
- "Actions"
3437
- ),
3438
- /* @__PURE__ */ import_react4.default.createElement(
3439
- "div",
3440
- {
3441
- style: { display: "flex", flexDirection: "column", gap: "12px" }
3442
- },
3443
- /* @__PURE__ */ import_react4.default.createElement(
3444
- "div",
3445
- {
3446
- style: { display: "flex", gap: "8px", alignItems: "center" }
3447
- },
3448
- /* @__PURE__ */ import_react4.default.createElement(
3449
- "input",
3450
- {
3451
- type: "text",
3452
- value: toolName,
3453
- onChange: (e) => setToolName(e.target.value),
3454
- placeholder: "Tool name",
3455
- style: {
3456
- padding: "6px 8px",
3457
- backgroundColor: "#1a1a1a",
3458
- color: "#ffffff",
3459
- border: "1px solid #333",
3460
- borderRadius: "4px",
3461
- fontFamily: "monospace",
3462
- fontSize: "12px",
3463
- width: "150px"
3464
- }
3465
- }
3466
- ),
3467
- /* @__PURE__ */ import_react4.default.createElement(
3468
- "input",
3469
- {
3470
- type: "text",
3471
- value: toolArgs,
3472
- onChange: (e) => setToolArgs(e.target.value),
3473
- placeholder: '{"key": "value"}',
3474
- style: {
3475
- padding: "6px 8px",
3476
- backgroundColor: "#1a1a1a",
3477
- color: "#ffffff",
3478
- border: "1px solid #333",
3479
- borderRadius: "4px",
3480
- fontFamily: "monospace",
3481
- fontSize: "12px",
3482
- flex: 1
3483
- }
3484
- }
3485
- ),
3486
- /* @__PURE__ */ import_react4.default.createElement(
3487
- "button",
3488
- {
3489
- onClick: handleCallTool,
3490
- style: {
3491
- padding: "6px 12px",
3492
- backgroundColor: "#333",
3493
- color: "#ffffff",
3494
- border: "1px solid #555",
3495
- borderRadius: "4px",
3496
- cursor: "pointer",
3497
- fontFamily: "monospace",
3498
- fontSize: "12px"
3499
- }
3500
- },
3501
- "Call Tool"
3502
- )
3503
- ),
3504
- /* @__PURE__ */ import_react4.default.createElement(
3505
- "div",
3506
- {
3507
- style: { display: "flex", gap: "8px", alignItems: "center" }
3508
- },
3509
- /* @__PURE__ */ import_react4.default.createElement(
3510
- "input",
3511
- {
3512
- type: "text",
3513
- value: followUpMessage,
3514
- onChange: (e) => setFollowUpMessage(e.target.value),
3515
- placeholder: "Follow-up message",
3516
- style: {
3517
- padding: "6px 8px",
3518
- backgroundColor: "#1a1a1a",
3519
- color: "#ffffff",
3520
- border: "1px solid #333",
3521
- borderRadius: "4px",
3522
- fontFamily: "monospace",
3523
- fontSize: "12px",
3524
- flex: 1
3525
- }
3526
- }
3527
- ),
3528
- /* @__PURE__ */ import_react4.default.createElement(
3529
- "button",
3530
- {
3531
- onClick: handleSendFollowUpMessage,
3532
- style: {
3533
- padding: "6px 12px",
3534
- backgroundColor: "#333",
3535
- color: "#ffffff",
3536
- border: "1px solid #555",
3537
- borderRadius: "4px",
3538
- cursor: "pointer",
3539
- fontFamily: "monospace",
3540
- fontSize: "12px"
3541
- }
3542
- },
3543
- "Send Follow-Up"
3544
- )
3545
- ),
3546
- /* @__PURE__ */ import_react4.default.createElement(
3547
- "div",
3548
- {
3549
- style: { display: "flex", gap: "8px", alignItems: "center" }
3550
- },
3551
- /* @__PURE__ */ import_react4.default.createElement(
3552
- "input",
3553
- {
3554
- type: "text",
3555
- value: externalUrl,
3556
- onChange: (e) => setExternalUrl(e.target.value),
3557
- placeholder: "External URL",
3558
- style: {
3559
- padding: "6px 8px",
3560
- backgroundColor: "#1a1a1a",
3561
- color: "#ffffff",
3562
- border: "1px solid #333",
3563
- borderRadius: "4px",
3564
- fontFamily: "monospace",
3565
- fontSize: "12px",
3566
- flex: 1
3567
- }
3568
- }
3569
- ),
3570
- /* @__PURE__ */ import_react4.default.createElement(
3571
- "button",
3572
- {
3573
- onClick: handleOpenExternal,
3574
- style: {
3575
- padding: "6px 12px",
3576
- backgroundColor: "#333",
3577
- color: "#ffffff",
3578
- border: "1px solid #555",
3579
- borderRadius: "4px",
3580
- cursor: "pointer",
3581
- fontFamily: "monospace",
3582
- fontSize: "12px"
3583
- }
3584
- },
3585
- "Open Link"
3586
- )
3587
- ),
3588
- /* @__PURE__ */ import_react4.default.createElement(
3589
- "div",
3590
- {
3591
- style: { display: "flex", gap: "8px", alignItems: "center" }
3592
- },
3593
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "150px", fontSize: "12px" } }, "Display Mode:"),
3594
- /* @__PURE__ */ import_react4.default.createElement(
3595
- "button",
3596
- {
3597
- onClick: () => handleRequestDisplayMode("inline"),
3598
- style: {
3599
- padding: "6px 12px",
3600
- backgroundColor: "#333",
3601
- color: "#ffffff",
3602
- border: "1px solid #555",
3603
- borderRadius: "4px",
3604
- cursor: "pointer",
3605
- fontFamily: "monospace",
3606
- fontSize: "12px",
3607
- flex: 1
3608
- }
3609
- },
3610
- "Inline"
3611
- ),
3612
- /* @__PURE__ */ import_react4.default.createElement(
3613
- "button",
3614
- {
3615
- onClick: () => handleRequestDisplayMode("pip"),
3616
- style: {
3617
- padding: "6px 12px",
3618
- backgroundColor: "#333",
3619
- color: "#ffffff",
3620
- border: "1px solid #555",
3621
- borderRadius: "4px",
3622
- cursor: "pointer",
3623
- fontFamily: "monospace",
3624
- fontSize: "12px",
3625
- flex: 1
3626
- }
3627
- },
3628
- "PiP"
3629
- ),
3630
- /* @__PURE__ */ import_react4.default.createElement(
3631
- "button",
3632
- {
3633
- onClick: () => handleRequestDisplayMode("fullscreen"),
3634
- style: {
3635
- padding: "6px 12px",
3636
- backgroundColor: "#333",
3637
- color: "#ffffff",
3638
- border: "1px solid #555",
3639
- borderRadius: "4px",
3640
- cursor: "pointer",
3641
- fontFamily: "monospace",
3642
- fontSize: "12px",
3643
- flex: 1
3644
- }
3645
- },
3646
- "Fullscreen"
3647
- )
3648
- ),
3649
- /* @__PURE__ */ import_react4.default.createElement(
3650
- "div",
3651
- {
3652
- style: { display: "flex", gap: "8px", alignItems: "center" }
3653
- },
3654
- /* @__PURE__ */ import_react4.default.createElement(
3655
- "button",
3656
- {
3657
- onClick: handleSetState,
3658
- style: {
3659
- padding: "6px 12px",
3660
- backgroundColor: "#333",
3661
- color: "#ffffff",
3662
- border: "1px solid #555",
3663
- borderRadius: "4px",
3664
- cursor: "pointer",
3665
- fontFamily: "monospace",
3666
- fontSize: "12px"
3667
- }
3668
- },
3669
- "Set State (Add Timestamp)"
3670
- )
3671
- ),
3672
- actionResult && /* @__PURE__ */ import_react4.default.createElement(
3673
- "div",
3674
- {
3675
- style: {
3676
- marginTop: "8px",
3677
- padding: "8px",
3678
- backgroundColor: "#1a1a1a",
3679
- border: "1px solid #333",
3680
- borderRadius: "4px",
3681
- whiteSpace: "pre-wrap",
3682
- wordBreak: "break-all",
3683
- fontSize: "11px",
3684
- maxHeight: "200px",
3685
- overflow: "auto"
3686
- }
3687
- },
3688
- /* @__PURE__ */ import_react4.default.createElement(
3689
- "div",
3690
- {
3691
- style: {
3692
- fontWeight: "bold",
3693
- marginBottom: "4px",
3694
- color: "#aaa"
3695
- }
3696
- },
3697
- "Result:"
3698
- ),
3699
- actionResult,
3700
- /* @__PURE__ */ import_react4.default.createElement(
3701
- "button",
3702
- {
3703
- onClick: () => setActionResult(""),
3704
- style: {
3705
- marginTop: "8px",
3706
- padding: "4px 8px",
3707
- backgroundColor: "#333",
3708
- color: "#ffffff",
3709
- border: "1px solid #555",
3710
- borderRadius: "4px",
3711
- cursor: "pointer",
3712
- fontFamily: "monospace",
3713
- fontSize: "11px"
3714
- }
3715
- },
3716
- "Clear"
3717
- )
3718
- )
3719
- )
3720
- )
3045
+ "Call Tool"
3046
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
3047
+ "input",
3048
+ {
3049
+ type: "text",
3050
+ value: followUpMessage,
3051
+ onChange: (e) => setFollowUpMessage(e.target.value),
3052
+ placeholder: "Follow-up message",
3053
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
3054
+ }
3055
+ ), /* @__PURE__ */ import_react6.default.createElement(
3056
+ "button",
3057
+ {
3058
+ onClick: handleSendFollowUpMessage,
3059
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
3060
+ },
3061
+ "Send Follow-Up"
3062
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
3063
+ "input",
3064
+ {
3065
+ type: "text",
3066
+ value: externalUrl,
3067
+ onChange: (e) => setExternalUrl(e.target.value),
3068
+ placeholder: "External URL",
3069
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
3070
+ }
3071
+ ), /* @__PURE__ */ import_react6.default.createElement(
3072
+ "button",
3073
+ {
3074
+ onClick: handleOpenExternal,
3075
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
3076
+ },
3077
+ "Open Link"
3078
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "w-[150px] text-xs" }, "Display Mode:"), /* @__PURE__ */ import_react6.default.createElement(
3079
+ "button",
3080
+ {
3081
+ onClick: () => handleRequestDisplayMode("inline"),
3082
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
3083
+ },
3084
+ "Inline"
3085
+ ), /* @__PURE__ */ import_react6.default.createElement(
3086
+ "button",
3087
+ {
3088
+ onClick: () => handleRequestDisplayMode("pip"),
3089
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
3090
+ },
3091
+ "PiP"
3092
+ ), /* @__PURE__ */ import_react6.default.createElement(
3093
+ "button",
3094
+ {
3095
+ onClick: () => handleRequestDisplayMode("fullscreen"),
3096
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
3097
+ },
3098
+ "Fullscreen"
3099
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
3100
+ "button",
3101
+ {
3102
+ onClick: handleSetState,
3103
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
3104
+ },
3105
+ "Set State (Add Timestamp)"
3106
+ )), actionResult && /* @__PURE__ */ import_react6.default.createElement("div", { className: "mt-2 p-2 bg-[#1a1a1a] border border-gray-700 rounded whitespace-pre-wrap break-all text-[11px] max-h-[200px] overflow-auto" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "font-bold mb-1 text-gray-400" }, "Result:"), actionResult, /* @__PURE__ */ import_react6.default.createElement(
3107
+ "button",
3108
+ {
3109
+ onClick: () => setActionResult(""),
3110
+ className: "mt-2 py-1 px-2 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-[11px]"
3111
+ },
3112
+ "Clear"
3113
+ ))))
3721
3114
  ));
3722
3115
  }
3723
- __name(WidgetDebugger, "WidgetDebugger");
3116
+ __name(WidgetControls, "WidgetControls");
3117
+
3118
+ // src/react/McpUseProvider.tsx
3119
+ var import_react7 = __toESM(require("react"), 1);
3120
+ var import_react_router_dom = require("react-router-dom");
3121
+ function getBasename() {
3122
+ if (typeof window === "undefined") return "/";
3123
+ const path = window.location.pathname;
3124
+ const match = path.match(/^(\/inspector\/api\/dev-widget\/[^/]+)/);
3125
+ if (match) {
3126
+ return match[1];
3127
+ }
3128
+ return "/";
3129
+ }
3130
+ __name(getBasename, "getBasename");
3131
+ var HEIGHT_DEBOUNCE_MS = 150;
3132
+ var MIN_HEIGHT_CHANGE_PX = 5;
3133
+ function McpUseProvider({
3134
+ children,
3135
+ debugger: enableDebugger = false,
3136
+ viewControls = false,
3137
+ autoSize = false
3138
+ }) {
3139
+ const basename = getBasename();
3140
+ const containerRef = (0, import_react7.useRef)(null);
3141
+ const lastHeightRef = (0, import_react7.useRef)(0);
3142
+ const debounceTimeoutRef = (0, import_react7.useRef)(null);
3143
+ const notificationInProgressRef = (0, import_react7.useRef)(false);
3144
+ const notifyHeight = (0, import_react7.useCallback)((height) => {
3145
+ if (typeof window !== "undefined" && window.openai?.notifyIntrinsicHeight) {
3146
+ notificationInProgressRef.current = true;
3147
+ window.openai.notifyIntrinsicHeight(height).then(() => {
3148
+ notificationInProgressRef.current = false;
3149
+ }).catch((error) => {
3150
+ notificationInProgressRef.current = false;
3151
+ console.error(
3152
+ "[McpUseProvider] Failed to notify intrinsic height:",
3153
+ error
3154
+ );
3155
+ });
3156
+ }
3157
+ }, []);
3158
+ const debouncedNotifyHeight = (0, import_react7.useCallback)(
3159
+ (height) => {
3160
+ if (debounceTimeoutRef.current) {
3161
+ clearTimeout(debounceTimeoutRef.current);
3162
+ }
3163
+ debounceTimeoutRef.current = setTimeout(() => {
3164
+ const heightDiff = Math.abs(height - lastHeightRef.current);
3165
+ if (heightDiff >= MIN_HEIGHT_CHANGE_PX && height > 0) {
3166
+ lastHeightRef.current = height;
3167
+ notifyHeight(height);
3168
+ }
3169
+ }, HEIGHT_DEBOUNCE_MS);
3170
+ },
3171
+ [notifyHeight]
3172
+ );
3173
+ (0, import_react7.useEffect)(() => {
3174
+ if (!autoSize) {
3175
+ return;
3176
+ }
3177
+ const container = containerRef.current;
3178
+ if (!container || typeof ResizeObserver === "undefined") {
3179
+ return;
3180
+ }
3181
+ const observer = new ResizeObserver((entries) => {
3182
+ if (notificationInProgressRef.current) {
3183
+ return;
3184
+ }
3185
+ for (const entry of entries) {
3186
+ const height = entry.contentRect.height;
3187
+ const scrollHeight = entry.target.scrollHeight;
3188
+ const intrinsicHeight = Math.max(height, scrollHeight);
3189
+ debouncedNotifyHeight(intrinsicHeight);
3190
+ }
3191
+ });
3192
+ observer.observe(container);
3193
+ const initialHeight = Math.max(
3194
+ container.offsetHeight,
3195
+ container.scrollHeight
3196
+ );
3197
+ if (initialHeight > 0) {
3198
+ debouncedNotifyHeight(initialHeight);
3199
+ }
3200
+ return () => {
3201
+ observer.disconnect();
3202
+ if (debounceTimeoutRef.current) {
3203
+ clearTimeout(debounceTimeoutRef.current);
3204
+ debounceTimeoutRef.current = null;
3205
+ }
3206
+ notificationInProgressRef.current = false;
3207
+ };
3208
+ }, [autoSize, debouncedNotifyHeight]);
3209
+ let content = children;
3210
+ content = /* @__PURE__ */ import_react7.default.createElement(ErrorBoundary, null, content);
3211
+ if (enableDebugger || viewControls) {
3212
+ content = /* @__PURE__ */ import_react7.default.createElement(WidgetControls, { debugger: enableDebugger, viewControls }, content);
3213
+ }
3214
+ content = /* @__PURE__ */ import_react7.default.createElement(import_react_router_dom.BrowserRouter, { basename }, content);
3215
+ content = /* @__PURE__ */ import_react7.default.createElement(ThemeProvider, null, content);
3216
+ if (autoSize) {
3217
+ const containerStyle = {
3218
+ width: "100%",
3219
+ minHeight: 0
3220
+ };
3221
+ content = /* @__PURE__ */ import_react7.default.createElement("div", { ref: containerRef, style: containerStyle }, content);
3222
+ }
3223
+ return /* @__PURE__ */ import_react7.default.createElement(import_react7.StrictMode, null, content);
3224
+ }
3225
+ __name(McpUseProvider, "McpUseProvider");