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
package/dist/index.cjs CHANGED
@@ -995,7 +995,9 @@ __export(index_exports, {
995
995
  BrowserOAuthClientProvider: () => BrowserOAuthClientProvider,
996
996
  ConnectMCPServerTool: () => ConnectMCPServerTool,
997
997
  E2BCodeExecutor: () => E2BCodeExecutor,
998
+ ErrorBoundary: () => ErrorBoundary,
998
999
  HttpConnector: () => HttpConnector,
1000
+ Image: () => Image,
999
1001
  LINEAR_OAUTH_CONFIG: () => LINEAR_OAUTH_CONFIG,
1000
1002
  LangChainAdapter: () => LangChainAdapter,
1001
1003
  ListMCPServersTool: () => ListMCPServersTool,
@@ -1003,6 +1005,7 @@ __export(index_exports, {
1003
1005
  MCPAgent: () => MCPAgent,
1004
1006
  MCPClient: () => MCPClient,
1005
1007
  MCPSession: () => MCPSession,
1008
+ McpUseProvider: () => McpUseProvider,
1006
1009
  OAuthHelper: () => OAuthHelper,
1007
1010
  ObservabilityManager: () => ObservabilityManager,
1008
1011
  PROMPTS: () => PROMPTS,
@@ -1011,10 +1014,10 @@ __export(index_exports, {
1011
1014
  ServerManager: () => ServerManager,
1012
1015
  StdioConnector: () => StdioConnector,
1013
1016
  Telemetry: () => Telemetry,
1017
+ ThemeProvider: () => ThemeProvider,
1014
1018
  VMCodeExecutor: () => VMCodeExecutor,
1015
1019
  WebSocketConnector: () => WebSocketConnector,
1016
- WidgetDebugger: () => WidgetDebugger,
1017
- WidgetFullscreenWrapper: () => WidgetFullscreenWrapper,
1020
+ WidgetControls: () => WidgetControls,
1018
1021
  createOAuthMCPConfig: () => createOAuthMCPConfig,
1019
1022
  createReadableStreamFromGenerator: () => createReadableStreamFromGenerator,
1020
1023
  isVMAvailable: () => isVMAvailable,
@@ -5440,7 +5443,11 @@ var HttpConnector = class extends BaseConnector {
5440
5443
  maxRetries: 2
5441
5444
  }
5442
5445
  });
5443
- const transport = await this.connectionManager.start();
5446
+ let transport = await this.connectionManager.start();
5447
+ if (this.opts.wrapTransport) {
5448
+ const serverId = this.baseUrl;
5449
+ transport = this.opts.wrapTransport(transport, serverId);
5450
+ }
5444
5451
  this.client = new import_client.Client(this.clientInfo, this.opts.clientOptions);
5445
5452
  try {
5446
5453
  await this.client.connect(transport);
@@ -5474,7 +5481,11 @@ var HttpConnector = class extends BaseConnector {
5474
5481
  headers: this.headers
5475
5482
  }
5476
5483
  });
5477
- const transport = await this.connectionManager.start();
5484
+ let transport = await this.connectionManager.start();
5485
+ if (this.opts.wrapTransport) {
5486
+ const serverId = this.baseUrl;
5487
+ transport = this.opts.wrapTransport(transport, serverId);
5488
+ }
5478
5489
  this.client = new import_client.Client(this.clientInfo, this.opts.clientOptions);
5479
5490
  await this.client.connect(transport);
5480
5491
  this.connected = true;
@@ -6897,15 +6908,17 @@ var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
6897
6908
  * Supports HTTP and WebSocket connectors only
6898
6909
  */
6899
6910
  createConnectorFromConfig(serverConfig) {
6900
- const { url, transport, headers, authToken, authProvider } = serverConfig;
6911
+ const { url, transport, headers, authToken, authProvider, wrapTransport } = serverConfig;
6901
6912
  if (!url) {
6902
6913
  throw new Error("Server URL is required");
6903
6914
  }
6904
6915
  const connectorOptions = {
6905
6916
  headers,
6906
6917
  authToken,
6907
- authProvider
6918
+ authProvider,
6908
6919
  // ← Pass OAuth provider to connector
6920
+ wrapTransport
6921
+ // ← Pass transport wrapper if provided
6909
6922
  };
6910
6923
  if (transport === "websocket" || url.startsWith("ws://") || url.startsWith("wss://")) {
6911
6924
  return new WebSocketConnector(url, connectorOptions);
@@ -6949,8 +6962,9 @@ function useMcp(options) {
6949
6962
  onPopupWindow,
6950
6963
  timeout = 3e4,
6951
6964
  // 30 seconds default for connection timeout
6952
- sseReadTimeout = 3e5
6965
+ sseReadTimeout = 3e5,
6953
6966
  // 5 minutes default for SSE read timeout
6967
+ wrapTransport
6954
6968
  } = options;
6955
6969
  const [state, setState] = (0, import_react.useState)("discovering");
6956
6970
  const [tools, setTools] = (0, import_react.useState)([]);
@@ -7101,8 +7115,17 @@ function useMcp(options) {
7101
7115
  }
7102
7116
  clientRef.current.addServer(serverName, {
7103
7117
  ...serverConfig,
7104
- authProvider: authProviderRef.current
7118
+ authProvider: authProviderRef.current,
7105
7119
  // ← SDK handles OAuth automatically!
7120
+ wrapTransport: wrapTransport ? (transport) => {
7121
+ console.log(
7122
+ "[useMcp] Applying transport wrapper for server:",
7123
+ serverName,
7124
+ "url:",
7125
+ url
7126
+ );
7127
+ return wrapTransport(transport, url);
7128
+ } : void 0
7106
7129
  });
7107
7130
  const session = await clientRef.current.createSession(serverName);
7108
7131
  await session.initialize();
@@ -7516,15 +7539,61 @@ function useMcp(options) {
7516
7539
  }
7517
7540
  __name(useMcp, "useMcp");
7518
7541
 
7542
+ // src/react/ErrorBoundary.tsx
7543
+ var import_react2 = __toESM(require("react"), 1);
7544
+ var ErrorBoundary = class extends import_react2.default.Component {
7545
+ static {
7546
+ __name(this, "ErrorBoundary");
7547
+ }
7548
+ constructor(props) {
7549
+ super(props);
7550
+ this.state = { hasError: false, error: null };
7551
+ }
7552
+ static getDerivedStateFromError(error) {
7553
+ return { hasError: true, error };
7554
+ }
7555
+ componentDidCatch(error, errorInfo) {
7556
+ console.error("Widget Error:", error, errorInfo);
7557
+ }
7558
+ render() {
7559
+ if (this.state.hasError) {
7560
+ 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));
7561
+ }
7562
+ return this.props.children;
7563
+ }
7564
+ };
7565
+
7566
+ // src/react/Image.tsx
7567
+ var import_react3 = __toESM(require("react"), 1);
7568
+ var Image = /* @__PURE__ */ __name(({ src, ...props }) => {
7569
+ const publicUrl = typeof window !== "undefined" && window.__mcpPublicUrl ? window.__mcpPublicUrl : "";
7570
+ const getFinalSrc = /* @__PURE__ */ __name((source) => {
7571
+ if (!source) return source;
7572
+ if (source.startsWith("http://") || source.startsWith("https://") || source.startsWith("data:")) {
7573
+ return source;
7574
+ }
7575
+ if (!publicUrl) {
7576
+ return source;
7577
+ }
7578
+ const cleanSrc = source.startsWith("/") ? source.slice(1) : source;
7579
+ return `${publicUrl}/${cleanSrc}`;
7580
+ }, "getFinalSrc");
7581
+ const finalSrc = getFinalSrc(src);
7582
+ return /* @__PURE__ */ import_react3.default.createElement("img", { src: finalSrc, ...props });
7583
+ }, "Image");
7584
+
7585
+ // src/react/ThemeProvider.tsx
7586
+ var import_react5 = __toESM(require("react"), 1);
7587
+
7519
7588
  // src/react/useWidget.ts
7520
- var import_react2 = require("react");
7589
+ var import_react4 = require("react");
7521
7590
 
7522
7591
  // src/react/widget-types.ts
7523
7592
  var SET_GLOBALS_EVENT_TYPE = "openai:set_globals";
7524
7593
 
7525
7594
  // src/react/useWidget.ts
7526
7595
  function useOpenAiGlobal(key) {
7527
- return (0, import_react2.useSyncExternalStore)(
7596
+ return (0, import_react4.useSyncExternalStore)(
7528
7597
  (onChange) => {
7529
7598
  const handleSetGlobal = /* @__PURE__ */ __name((event) => {
7530
7599
  const customEvent = event;
@@ -7548,10 +7617,10 @@ function useOpenAiGlobal(key) {
7548
7617
  }
7549
7618
  __name(useOpenAiGlobal, "useOpenAiGlobal");
7550
7619
  function useWidget(defaultProps) {
7551
- const [isOpenAiAvailable, setIsOpenAiAvailable] = (0, import_react2.useState)(
7620
+ const [isOpenAiAvailable, setIsOpenAiAvailable] = (0, import_react4.useState)(
7552
7621
  () => typeof window !== "undefined" && !!window.openai
7553
7622
  );
7554
- (0, import_react2.useEffect)(() => {
7623
+ (0, import_react4.useEffect)(() => {
7555
7624
  if (typeof window !== "undefined" && window.openai) {
7556
7625
  setIsOpenAiAvailable(true);
7557
7626
  return;
@@ -7585,11 +7654,12 @@ function useWidget(defaultProps) {
7585
7654
  }
7586
7655
  };
7587
7656
  }, []);
7588
- const provider = (0, import_react2.useMemo)(() => {
7657
+ const provider = (0, import_react4.useMemo)(() => {
7589
7658
  return isOpenAiAvailable ? "openai" : "mcp-ui";
7590
7659
  }, [isOpenAiAvailable]);
7591
- const urlParams = (0, import_react2.useMemo)(() => {
7592
- const urlParams2 = new URLSearchParams(window?.location?.search);
7660
+ const searchString = typeof window !== "undefined" ? window.location.search : "";
7661
+ const urlParams = (0, import_react4.useMemo)(() => {
7662
+ const urlParams2 = new URLSearchParams(searchString);
7593
7663
  if (urlParams2.has("mcpUseParams")) {
7594
7664
  return JSON.parse(urlParams2.get("mcpUseParams"));
7595
7665
  }
@@ -7598,7 +7668,7 @@ function useWidget(defaultProps) {
7598
7668
  toolOutput: {},
7599
7669
  toolId: ""
7600
7670
  };
7601
- }, [window?.location?.search]);
7671
+ }, [searchString]);
7602
7672
  const toolInput = provider === "openai" ? useOpenAiGlobal("toolInput") : urlParams.toolInput;
7603
7673
  const toolOutput = provider === "openai" ? useOpenAiGlobal("toolOutput") : urlParams.toolOutput;
7604
7674
  const toolResponseMetadata = useOpenAiGlobal("toolResponseMetadata");
@@ -7609,13 +7679,19 @@ function useWidget(defaultProps) {
7609
7679
  const maxHeight = useOpenAiGlobal("maxHeight");
7610
7680
  const userAgent = useOpenAiGlobal("userAgent");
7611
7681
  const locale = useOpenAiGlobal("locale");
7612
- const [localWidgetState, setLocalWidgetState] = (0, import_react2.useState)(null);
7613
- (0, import_react2.useEffect)(() => {
7682
+ const mcp_url = (0, import_react4.useMemo)(() => {
7683
+ if (typeof window !== "undefined" && window.__mcpPublicUrl) {
7684
+ return window.__mcpPublicUrl.replace(/\/mcp-use\/public$/, "");
7685
+ }
7686
+ return "";
7687
+ }, []);
7688
+ const [localWidgetState, setLocalWidgetState] = (0, import_react4.useState)(null);
7689
+ (0, import_react4.useEffect)(() => {
7614
7690
  if (widgetState !== void 0) {
7615
7691
  setLocalWidgetState(widgetState);
7616
7692
  }
7617
7693
  }, [widgetState]);
7618
- const callTool = (0, import_react2.useCallback)(
7694
+ const callTool = (0, import_react4.useCallback)(
7619
7695
  async (name, args) => {
7620
7696
  if (!window.openai?.callTool) {
7621
7697
  throw new Error("window.openai.callTool is not available");
@@ -7624,7 +7700,7 @@ function useWidget(defaultProps) {
7624
7700
  },
7625
7701
  []
7626
7702
  );
7627
- const sendFollowUpMessage = (0, import_react2.useCallback)(
7703
+ const sendFollowUpMessage = (0, import_react4.useCallback)(
7628
7704
  async (prompt) => {
7629
7705
  if (!window.openai?.sendFollowUpMessage) {
7630
7706
  throw new Error("window.openai.sendFollowUpMessage is not available");
@@ -7633,13 +7709,13 @@ function useWidget(defaultProps) {
7633
7709
  },
7634
7710
  []
7635
7711
  );
7636
- const openExternal = (0, import_react2.useCallback)((href) => {
7712
+ const openExternal = (0, import_react4.useCallback)((href) => {
7637
7713
  if (!window.openai?.openExternal) {
7638
7714
  throw new Error("window.openai.openExternal is not available");
7639
7715
  }
7640
7716
  window.openai.openExternal({ href });
7641
7717
  }, []);
7642
- const requestDisplayMode = (0, import_react2.useCallback)(
7718
+ const requestDisplayMode = (0, import_react4.useCallback)(
7643
7719
  async (mode) => {
7644
7720
  if (!window.openai?.requestDisplayMode) {
7645
7721
  throw new Error("window.openai.requestDisplayMode is not available");
@@ -7648,16 +7724,17 @@ function useWidget(defaultProps) {
7648
7724
  },
7649
7725
  []
7650
7726
  );
7651
- const setState = (0, import_react2.useCallback)(
7727
+ const setState = (0, import_react4.useCallback)(
7652
7728
  async (state) => {
7653
- const newState = typeof state === "function" ? state(localWidgetState) : state;
7654
7729
  if (!window.openai?.setWidgetState) {
7655
7730
  throw new Error("window.openai.setWidgetState is not available");
7656
7731
  }
7732
+ const currentState = widgetState !== void 0 ? widgetState : localWidgetState;
7733
+ const newState = typeof state === "function" ? state(currentState) : state;
7657
7734
  setLocalWidgetState(newState);
7658
7735
  return window.openai.setWidgetState(newState);
7659
7736
  },
7660
- [localWidgetState]
7737
+ [widgetState, localWidgetState]
7661
7738
  );
7662
7739
  return {
7663
7740
  // Props and state (with defaults)
@@ -7676,6 +7753,7 @@ function useWidget(defaultProps) {
7676
7753
  capabilities: { hover: true, touch: false }
7677
7754
  },
7678
7755
  locale: locale || "en",
7756
+ mcp_url,
7679
7757
  // Actions
7680
7758
  callTool,
7681
7759
  sendFollowUpMessage,
@@ -7698,7 +7776,7 @@ function useWidgetTheme() {
7698
7776
  __name(useWidgetTheme, "useWidgetTheme");
7699
7777
  function useWidgetState(defaultState) {
7700
7778
  const { state, setState } = useWidget();
7701
- (0, import_react2.useEffect)(() => {
7779
+ (0, import_react4.useEffect)(() => {
7702
7780
  if (state === null && defaultState !== void 0 && window.openai?.setWidgetState) {
7703
7781
  setState(defaultState);
7704
7782
  }
@@ -7707,283 +7785,49 @@ function useWidgetState(defaultState) {
7707
7785
  }
7708
7786
  __name(useWidgetState, "useWidgetState");
7709
7787
 
7710
- // src/react/WidgetFullscreenWrapper.tsx
7711
- var import_react3 = __toESM(require("react"), 1);
7712
- function WidgetFullscreenWrapper({
7713
- children,
7714
- className = "",
7715
- position = "top-right",
7716
- attachTo,
7717
- showLabels = true
7718
- }) {
7719
- const { displayMode, requestDisplayMode, theme, safeArea, isAvailable } = useWidget();
7720
- const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
7721
- const containerRef = (0, import_react3.useRef)(null);
7722
- const isFullscreen = displayMode === "fullscreen" && isAvailable;
7723
- const isPip = displayMode === "pip" && isAvailable;
7724
- const isDark = theme === "dark";
7725
- const buttonBg = isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.7)";
7726
- const buttonBgHover = isDark ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.9)";
7727
- const buttonColor = "white";
7728
- const getPositionStyles = /* @__PURE__ */ __name(() => {
7729
- const baseOffset = 16;
7730
- const topOffset = safeArea?.insets?.top ? `${Math.max(baseOffset, safeArea.insets.top + 8)}px` : `${baseOffset}px`;
7731
- const rightOffset = safeArea?.insets?.right ? `${Math.max(baseOffset, safeArea.insets.right + 8)}px` : `${baseOffset}px`;
7732
- const bottomOffset = safeArea?.insets?.bottom ? `${Math.max(baseOffset, safeArea.insets.bottom + 8)}px` : `${baseOffset}px`;
7733
- const leftOffset = safeArea?.insets?.left ? `${Math.max(baseOffset, safeArea.insets.left + 8)}px` : `${baseOffset}px`;
7734
- const styles = {
7735
- position: "absolute",
7736
- zIndex: 1e3,
7737
- display: "flex",
7738
- gap: "8px",
7739
- opacity: isHovered ? 1 : 0,
7740
- transition: "opacity 0.2s ease-in-out",
7741
- pointerEvents: isHovered ? "auto" : "none"
7742
- };
7743
- switch (position) {
7744
- case "top-left":
7745
- styles.top = topOffset;
7746
- styles.left = leftOffset;
7747
- break;
7748
- case "top-center":
7749
- styles.top = topOffset;
7750
- styles.left = "50%";
7751
- styles.transform = "translateX(-50%)";
7752
- break;
7753
- case "top-right":
7754
- styles.top = topOffset;
7755
- styles.right = rightOffset;
7756
- break;
7757
- case "center-left":
7758
- styles.top = "50%";
7759
- styles.left = leftOffset;
7760
- styles.transform = "translateY(-50%)";
7761
- break;
7762
- case "center-right":
7763
- styles.top = "50%";
7764
- styles.right = rightOffset;
7765
- styles.transform = "translateY(-50%)";
7766
- break;
7767
- case "bottom-left":
7768
- styles.bottom = bottomOffset;
7769
- styles.left = leftOffset;
7770
- break;
7771
- case "bottom-center":
7772
- styles.bottom = bottomOffset;
7773
- styles.left = "50%";
7774
- styles.transform = "translateX(-50%)";
7775
- break;
7776
- case "bottom-right":
7777
- styles.bottom = bottomOffset;
7778
- styles.right = rightOffset;
7779
- break;
7780
- default:
7781
- styles.top = topOffset;
7782
- styles.right = rightOffset;
7783
- break;
7784
- }
7785
- return styles;
7786
- }, "getPositionStyles");
7787
- (0, import_react3.useEffect)(() => {
7788
- if (!attachTo) return;
7789
- const handleMouseEnter = /* @__PURE__ */ __name(() => setIsHovered(true), "handleMouseEnter");
7790
- const handleMouseLeave = /* @__PURE__ */ __name(() => setIsHovered(false), "handleMouseLeave");
7791
- attachTo.addEventListener("mouseenter", handleMouseEnter);
7792
- attachTo.addEventListener("mouseleave", handleMouseLeave);
7793
- return () => {
7794
- attachTo.removeEventListener("mouseenter", handleMouseEnter);
7795
- attachTo.removeEventListener("mouseleave", handleMouseLeave);
7796
- };
7797
- }, [attachTo]);
7798
- const handleFullscreen = /* @__PURE__ */ __name(async () => {
7799
- try {
7800
- await requestDisplayMode("fullscreen");
7801
- } catch (error) {
7802
- console.error("Failed to go fullscreen:", error);
7803
- }
7804
- }, "handleFullscreen");
7805
- const handlePip = /* @__PURE__ */ __name(async () => {
7806
- try {
7807
- await requestDisplayMode("pip");
7808
- } catch (error) {
7809
- console.error("Failed to go pip:", error);
7810
- }
7811
- }, "handlePip");
7812
- const getTooltipStyles = /* @__PURE__ */ __name(() => {
7813
- const baseStyles = {
7814
- position: "absolute",
7815
- padding: "4px 8px",
7816
- backgroundColor: isDark ? "rgba(0, 0, 0, 0.9)" : "rgba(0, 0, 0, 0.9)",
7817
- color: "white",
7818
- borderRadius: "4px",
7819
- fontSize: "12px",
7820
- whiteSpace: "nowrap",
7821
- pointerEvents: "none",
7822
- transition: "opacity 0.2s ease-in-out"
7823
- };
7824
- switch (position) {
7825
- case "top-right":
7826
- return {
7827
- ...baseStyles,
7828
- top: "100%",
7829
- right: "0",
7830
- marginTop: "8px"
7831
- };
7832
- case "top-left":
7833
- return {
7834
- ...baseStyles,
7835
- top: "100%",
7836
- left: "0",
7837
- marginTop: "8px"
7838
- };
7839
- case "top-center":
7840
- return {
7841
- ...baseStyles,
7842
- top: "100%",
7843
- left: "50%",
7844
- transform: "translateX(-50%)",
7845
- marginTop: "8px"
7846
- };
7847
- case "bottom-right":
7848
- return {
7849
- ...baseStyles,
7850
- bottom: "100%",
7851
- right: "0",
7852
- marginBottom: "8px"
7853
- };
7854
- case "bottom-left":
7855
- return {
7856
- ...baseStyles,
7857
- bottom: "100%",
7858
- left: "0",
7859
- marginBottom: "8px"
7860
- };
7861
- case "bottom-center":
7862
- return {
7863
- ...baseStyles,
7864
- bottom: "100%",
7865
- left: "50%",
7866
- transform: "translateX(-50%)",
7867
- marginBottom: "8px"
7868
- };
7869
- case "center-left":
7870
- return {
7871
- ...baseStyles,
7872
- left: "100%",
7873
- top: "50%",
7874
- transform: "translateY(-50%)",
7875
- marginLeft: "8px"
7876
- };
7877
- case "center-right":
7878
- return {
7879
- ...baseStyles,
7880
- right: "100%",
7881
- top: "50%",
7882
- transform: "translateY(-50%)",
7883
- marginRight: "8px"
7884
- };
7885
- default:
7886
- return {
7887
- ...baseStyles,
7888
- top: "100%",
7889
- right: "0",
7890
- marginTop: "8px"
7891
- };
7788
+ // src/react/ThemeProvider.tsx
7789
+ var ThemeProvider = /* @__PURE__ */ __name(({
7790
+ children
7791
+ }) => {
7792
+ const { theme, isAvailable } = useWidget();
7793
+ console.log("theme", theme);
7794
+ const [systemPreference, setSystemPreference] = (0, import_react5.useState)(
7795
+ () => {
7796
+ if (typeof window === "undefined") return "light";
7797
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
7892
7798
  }
7893
- }, "getTooltipStyles");
7894
- const IconButton = /* @__PURE__ */ __name(({
7895
- onClick,
7896
- label,
7897
- children: icon
7898
- }) => {
7899
- const [isButtonHovered, setIsButtonHovered] = (0, import_react3.useState)(false);
7900
- const tooltipStyles = getTooltipStyles();
7901
- return /* @__PURE__ */ import_react3.default.createElement(
7902
- "button",
7903
- {
7904
- style: {
7905
- padding: "8px",
7906
- backgroundColor: buttonBg,
7907
- color: buttonColor,
7908
- border: "none",
7909
- borderRadius: "8px",
7910
- cursor: "pointer",
7911
- display: "flex",
7912
- alignItems: "center",
7913
- justifyContent: "center",
7914
- width: "32px",
7915
- height: "32px",
7916
- transition: "background-color 0.2s",
7917
- backdropFilter: "blur(8px)",
7918
- WebkitBackdropFilter: "blur(8px)",
7919
- boxShadow: isDark ? "0 2px 8px rgba(0, 0, 0, 0.3)" : "0 2px 8px rgba(0, 0, 0, 0.2)",
7920
- position: "relative"
7921
- },
7922
- onMouseEnter: (e) => {
7923
- e.currentTarget.style.backgroundColor = buttonBgHover;
7924
- setIsButtonHovered(true);
7925
- },
7926
- onMouseLeave: (e) => {
7927
- e.currentTarget.style.backgroundColor = buttonBg;
7928
- setIsButtonHovered(false);
7929
- },
7930
- onClick,
7931
- "aria-label": label
7932
- },
7933
- /* @__PURE__ */ import_react3.default.createElement(
7934
- "svg",
7935
- {
7936
- xmlns: "http://www.w3.org/2000/svg",
7937
- width: "16",
7938
- height: "16",
7939
- viewBox: "0 0 24 24",
7940
- fill: "none",
7941
- stroke: "currentColor",
7942
- strokeWidth: "2",
7943
- strokeLinecap: "round",
7944
- strokeLinejoin: "round",
7945
- style: { display: "block" }
7946
- },
7947
- icon
7948
- ),
7949
- showLabels && /* @__PURE__ */ import_react3.default.createElement(
7950
- "span",
7951
- {
7952
- style: {
7953
- ...tooltipStyles,
7954
- opacity: isButtonHovered ? 1 : 0
7955
- }
7956
- },
7957
- label
7958
- )
7959
- );
7960
- }, "IconButton");
7961
- return /* @__PURE__ */ import_react3.default.createElement(
7962
- "div",
7963
- {
7964
- ref: containerRef,
7965
- className,
7966
- style: {
7967
- position: "relative",
7968
- height: "fit-content"
7969
- },
7970
- onMouseEnter: () => !attachTo && setIsHovered(true),
7971
- onMouseLeave: () => !attachTo && setIsHovered(false)
7972
- },
7973
- !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" }))),
7974
- children
7975
7799
  );
7976
- }
7977
- __name(WidgetFullscreenWrapper, "WidgetFullscreenWrapper");
7800
+ (0, import_react5.useEffect)(() => {
7801
+ if (typeof window === "undefined") return;
7802
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
7803
+ const handleChange = /* @__PURE__ */ __name((e) => {
7804
+ setSystemPreference(e.matches ? "dark" : "light");
7805
+ }, "handleChange");
7806
+ mediaQuery.addEventListener("change", handleChange);
7807
+ return () => mediaQuery.removeEventListener("change", handleChange);
7808
+ }, []);
7809
+ const effectiveTheme = isAvailable ? theme : systemPreference;
7810
+ (0, import_react5.useLayoutEffect)(() => {
7811
+ if (typeof document === "undefined") return;
7812
+ if (effectiveTheme === "dark") {
7813
+ document.documentElement.classList.add("dark");
7814
+ } else {
7815
+ document.documentElement.classList.remove("dark");
7816
+ }
7817
+ }, [effectiveTheme]);
7818
+ return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, children);
7819
+ }, "ThemeProvider");
7978
7820
 
7979
- // src/react/WidgetDebugger.tsx
7980
- var import_react4 = __toESM(require("react"), 1);
7981
- function WidgetDebugger({
7821
+ // src/react/WidgetControls.tsx
7822
+ var import_react6 = __toESM(require("react"), 1);
7823
+ function WidgetControls({
7982
7824
  children,
7983
7825
  className = "",
7984
7826
  position = "top-right",
7985
7827
  attachTo,
7986
- showLabels = true
7828
+ showLabels = true,
7829
+ debugger: enableDebugger = false,
7830
+ viewControls = false
7987
7831
  }) {
7988
7832
  const {
7989
7833
  props,
@@ -8003,23 +7847,24 @@ function WidgetDebugger({
8003
7847
  requestDisplayMode,
8004
7848
  setState
8005
7849
  } = useWidget();
8006
- const [isHovered, setIsHovered] = (0, import_react4.useState)(false);
8007
- const [isOverlayOpen, setIsOverlayOpen] = (0, import_react4.useState)(false);
8008
- const containerRef = (0, import_react4.useRef)(null);
8009
- const overlayRef = (0, import_react4.useRef)(null);
8010
- const [windowOpenAiKeys, setWindowOpenAiKeys] = (0, import_react4.useState)([]);
8011
- const [actionResult, setActionResult] = (0, import_react4.useState)("");
8012
- const [toolName, setToolName] = (0, import_react4.useState)("get-my-city");
8013
- const [toolArgs, setToolArgs] = (0, import_react4.useState)("{}");
8014
- const [followUpMessage, setFollowUpMessage] = (0, import_react4.useState)(
7850
+ const [isHovered, setIsHovered] = (0, import_react6.useState)(false);
7851
+ const [isOverlayOpen, setIsOverlayOpen] = (0, import_react6.useState)(false);
7852
+ const containerRef = (0, import_react6.useRef)(null);
7853
+ const overlayRef = (0, import_react6.useRef)(null);
7854
+ const [windowOpenAiKeys, setWindowOpenAiKeys] = (0, import_react6.useState)([]);
7855
+ const [actionResult, setActionResult] = (0, import_react6.useState)("");
7856
+ const [toolName, setToolName] = (0, import_react6.useState)("get-my-city");
7857
+ const [toolArgs, setToolArgs] = (0, import_react6.useState)("{}");
7858
+ const [followUpMessage, setFollowUpMessage] = (0, import_react6.useState)(
8015
7859
  "Test follow-up message"
8016
7860
  );
8017
- const [externalUrl, setExternalUrl] = (0, import_react4.useState)(
7861
+ const [externalUrl, setExternalUrl] = (0, import_react6.useState)(
8018
7862
  "https://docs.mcp-use.com"
8019
7863
  );
8020
7864
  const isFullscreen = displayMode === "fullscreen" && isAvailable;
8021
7865
  const isPip = displayMode === "pip" && isAvailable;
8022
- (0, import_react4.useEffect)(() => {
7866
+ const isDevMode = typeof window !== "undefined" && window.location.pathname.includes("/inspector/api/dev-widget/");
7867
+ (0, import_react6.useEffect)(() => {
8023
7868
  const timeoutId = setTimeout(() => {
8024
7869
  if (typeof window !== "undefined" && window.openai) {
8025
7870
  try {
@@ -8032,75 +7877,88 @@ function WidgetDebugger({
8032
7877
  setWindowOpenAiKeys([]);
8033
7878
  }
8034
7879
  }, 100);
8035
- return () => clearTimeout(timeoutId);
7880
+ return () => {
7881
+ clearTimeout(timeoutId);
7882
+ };
8036
7883
  }, []);
8037
7884
  const isDark = theme === "dark";
8038
- const buttonBg = isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.7)";
8039
- const buttonBgHover = isDark ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.9)";
8040
- const buttonColor = "white";
8041
- const getPositionStyles = /* @__PURE__ */ __name(() => {
7885
+ const getPositionClasses = /* @__PURE__ */ __name(() => {
7886
+ const baseClasses = [
7887
+ "absolute",
7888
+ "z-[1000]",
7889
+ "flex",
7890
+ "gap-2",
7891
+ "transition-opacity",
7892
+ "duration-200",
7893
+ "ease-in-out",
7894
+ isHovered ? "opacity-100" : "opacity-0",
7895
+ isHovered ? "pointer-events-auto" : "pointer-events-none"
7896
+ ];
7897
+ switch (position) {
7898
+ case "top-left":
7899
+ return [...baseClasses, "top-4", "left-4"];
7900
+ case "top-center":
7901
+ return [...baseClasses, "top-4", "left-1/2", "-translate-x-1/2"];
7902
+ case "top-right":
7903
+ return [...baseClasses, "top-4", "right-4"];
7904
+ case "center-left":
7905
+ return [...baseClasses, "top-1/2", "left-4", "-translate-y-1/2"];
7906
+ case "center-right":
7907
+ return [...baseClasses, "top-1/2", "right-4", "-translate-y-1/2"];
7908
+ case "bottom-left":
7909
+ return [...baseClasses, "bottom-4", "left-4"];
7910
+ case "bottom-center":
7911
+ return [...baseClasses, "bottom-4", "left-1/2", "-translate-x-1/2"];
7912
+ case "bottom-right":
7913
+ return [...baseClasses, "bottom-4", "right-4"];
7914
+ default:
7915
+ return [...baseClasses, "top-4", "right-4"];
7916
+ }
7917
+ }, "getPositionClasses");
7918
+ const getPositionOffsetStyles = /* @__PURE__ */ __name(() => {
8042
7919
  const baseOffset = 16;
8043
- const topOffset = safeArea?.insets?.top ? `${Math.max(baseOffset, safeArea.insets.top + 8)}px` : `${baseOffset}px`;
8044
- const rightOffset = safeArea?.insets?.right ? `${Math.max(baseOffset, safeArea.insets.right + 8)}px` : `${baseOffset}px`;
8045
- const bottomOffset = safeArea?.insets?.bottom ? `${Math.max(baseOffset, safeArea.insets.bottom + 8)}px` : `${baseOffset}px`;
8046
- const leftOffset = safeArea?.insets?.left ? `${Math.max(baseOffset, safeArea.insets.left + 8)}px` : `${baseOffset}px`;
8047
- const styles = {
8048
- position: "absolute",
8049
- zIndex: 1e3,
8050
- display: "flex",
8051
- gap: "8px",
8052
- opacity: isHovered ? 1 : 0,
8053
- transition: "opacity 0.2s ease-in-out",
8054
- pointerEvents: isHovered ? "auto" : "none"
8055
- };
7920
+ const topOffset = safeArea?.insets?.top ? Math.max(baseOffset, safeArea.insets.top + 8) : baseOffset;
7921
+ const rightOffset = safeArea?.insets?.right ? Math.max(baseOffset, safeArea.insets.right + 8) : baseOffset;
7922
+ const bottomOffset = safeArea?.insets?.bottom ? Math.max(baseOffset, safeArea.insets.bottom + 8) : baseOffset;
7923
+ const leftOffset = safeArea?.insets?.left ? Math.max(baseOffset, safeArea.insets.left + 8) : baseOffset;
7924
+ const styles = {};
8056
7925
  switch (position) {
8057
7926
  case "top-left":
8058
- styles.top = topOffset;
8059
- styles.left = leftOffset;
7927
+ styles.top = `${topOffset}px`;
7928
+ styles.left = `${leftOffset}px`;
8060
7929
  break;
8061
7930
  case "top-center":
8062
- styles.top = topOffset;
8063
- styles.left = "50%";
8064
- styles.transform = "translateX(-50%)";
7931
+ styles.top = `${topOffset}px`;
8065
7932
  break;
8066
7933
  case "top-right":
8067
- styles.top = topOffset;
8068
- styles.right = rightOffset;
8069
- if (!isFullscreen && !isPip) {
8070
- styles.right = `calc(${rightOffset} + 80px)`;
8071
- }
7934
+ styles.top = `${topOffset}px`;
7935
+ styles.right = `${rightOffset}px`;
8072
7936
  break;
8073
7937
  case "center-left":
8074
- styles.top = "50%";
8075
- styles.left = leftOffset;
8076
- styles.transform = "translateY(-50%)";
7938
+ styles.left = `${leftOffset}px`;
8077
7939
  break;
8078
7940
  case "center-right":
8079
- styles.top = "50%";
8080
- styles.right = rightOffset;
8081
- styles.transform = "translateY(-50%)";
7941
+ styles.right = `${rightOffset}px`;
8082
7942
  break;
8083
7943
  case "bottom-left":
8084
- styles.bottom = bottomOffset;
8085
- styles.left = leftOffset;
7944
+ styles.bottom = `${bottomOffset}px`;
7945
+ styles.left = `${leftOffset}px`;
8086
7946
  break;
8087
7947
  case "bottom-center":
8088
- styles.bottom = bottomOffset;
8089
- styles.left = "50%";
8090
- styles.transform = "translateX(-50%)";
7948
+ styles.bottom = `${bottomOffset}px`;
8091
7949
  break;
8092
7950
  case "bottom-right":
8093
- styles.bottom = bottomOffset;
8094
- styles.right = rightOffset;
7951
+ styles.bottom = `${bottomOffset}px`;
7952
+ styles.right = `${rightOffset}px`;
8095
7953
  break;
8096
7954
  default:
8097
- styles.top = topOffset;
8098
- styles.right = rightOffset;
7955
+ styles.top = `${topOffset}px`;
7956
+ styles.right = `${rightOffset}px`;
8099
7957
  break;
8100
7958
  }
8101
7959
  return styles;
8102
- }, "getPositionStyles");
8103
- (0, import_react4.useEffect)(() => {
7960
+ }, "getPositionOffsetStyles");
7961
+ (0, import_react6.useEffect)(() => {
8104
7962
  if (!attachTo) return;
8105
7963
  const handleMouseEnter = /* @__PURE__ */ __name(() => setIsHovered(true), "handleMouseEnter");
8106
7964
  const handleMouseLeave = /* @__PURE__ */ __name(() => setIsHovered(false), "handleMouseLeave");
@@ -8111,7 +7969,7 @@ function WidgetDebugger({
8111
7969
  attachTo.removeEventListener("mouseleave", handleMouseLeave);
8112
7970
  };
8113
7971
  }, [attachTo]);
8114
- (0, import_react4.useEffect)(() => {
7972
+ (0, import_react6.useEffect)(() => {
8115
7973
  if (!isOverlayOpen) return;
8116
7974
  const handleClickOutside = /* @__PURE__ */ __name((event) => {
8117
7975
  if (overlayRef.current && !overlayRef.current.contains(event.target)) {
@@ -8123,7 +7981,7 @@ function WidgetDebugger({
8123
7981
  document.removeEventListener("mousedown", handleClickOutside);
8124
7982
  };
8125
7983
  }, [isOverlayOpen]);
8126
- (0, import_react4.useEffect)(() => {
7984
+ (0, import_react6.useEffect)(() => {
8127
7985
  if (isOverlayOpen) {
8128
7986
  document.body.style.overflow = "hidden";
8129
7987
  } else {
@@ -8182,128 +8040,97 @@ function WidgetDebugger({
8182
8040
  setActionResult(`Error: ${error.message}`);
8183
8041
  }
8184
8042
  }, "handleSetState");
8185
- const getTooltipStyles = /* @__PURE__ */ __name(() => {
8186
- const baseStyles = {
8187
- position: "absolute",
8188
- padding: "4px 8px",
8189
- backgroundColor: "rgba(0, 0, 0, 0.9)",
8190
- color: "white",
8191
- borderRadius: "4px",
8192
- fontSize: "12px",
8193
- whiteSpace: "nowrap",
8194
- pointerEvents: "none",
8195
- transition: "opacity 0.2s ease-in-out"
8196
- };
8043
+ const handleFullscreen = /* @__PURE__ */ __name(async () => {
8044
+ try {
8045
+ await requestDisplayMode("fullscreen");
8046
+ } catch (error) {
8047
+ console.error("Failed to go fullscreen:", error);
8048
+ }
8049
+ }, "handleFullscreen");
8050
+ const handlePip = /* @__PURE__ */ __name(async () => {
8051
+ try {
8052
+ await requestDisplayMode("pip");
8053
+ } catch (error) {
8054
+ console.error("Failed to go pip:", error);
8055
+ }
8056
+ }, "handlePip");
8057
+ const getTooltipClasses = /* @__PURE__ */ __name(() => {
8058
+ const baseClasses = [
8059
+ "absolute",
8060
+ "px-2",
8061
+ "py-1",
8062
+ "bg-black/90",
8063
+ "text-white",
8064
+ "rounded",
8065
+ "text-xs",
8066
+ "whitespace-nowrap",
8067
+ "pointer-events-none",
8068
+ "transition-opacity",
8069
+ "duration-200",
8070
+ "ease-in-out"
8071
+ ];
8197
8072
  switch (position) {
8198
8073
  case "top-right":
8199
- return {
8200
- ...baseStyles,
8201
- top: "100%",
8202
- right: "0",
8203
- marginTop: "8px"
8204
- };
8074
+ return [...baseClasses, "top-full", "right-0", "mt-2"];
8205
8075
  case "top-left":
8206
- return {
8207
- ...baseStyles,
8208
- top: "100%",
8209
- left: "0",
8210
- marginTop: "8px"
8211
- };
8076
+ return [...baseClasses, "top-full", "left-0", "mt-2"];
8212
8077
  case "top-center":
8213
- return {
8214
- ...baseStyles,
8215
- top: "100%",
8216
- left: "50%",
8217
- transform: "translateX(-50%)",
8218
- marginTop: "8px"
8219
- };
8078
+ return [
8079
+ ...baseClasses,
8080
+ "top-full",
8081
+ "left-1/2",
8082
+ "-translate-x-1/2",
8083
+ "mt-2"
8084
+ ];
8220
8085
  case "bottom-right":
8221
- return {
8222
- ...baseStyles,
8223
- bottom: "100%",
8224
- right: "0",
8225
- marginBottom: "8px"
8226
- };
8086
+ return [...baseClasses, "bottom-full", "right-0", "mb-2"];
8227
8087
  case "bottom-left":
8228
- return {
8229
- ...baseStyles,
8230
- bottom: "100%",
8231
- left: "0",
8232
- marginBottom: "8px"
8233
- };
8088
+ return [...baseClasses, "bottom-full", "left-0", "mb-2"];
8234
8089
  case "bottom-center":
8235
- return {
8236
- ...baseStyles,
8237
- bottom: "100%",
8238
- left: "50%",
8239
- transform: "translateX(-50%)",
8240
- marginBottom: "8px"
8241
- };
8090
+ return [
8091
+ ...baseClasses,
8092
+ "bottom-full",
8093
+ "left-1/2",
8094
+ "-translate-x-1/2",
8095
+ "mb-2"
8096
+ ];
8242
8097
  case "center-left":
8243
- return {
8244
- ...baseStyles,
8245
- left: "100%",
8246
- top: "50%",
8247
- transform: "translateY(-50%)",
8248
- marginLeft: "8px"
8249
- };
8098
+ return [
8099
+ ...baseClasses,
8100
+ "left-full",
8101
+ "top-1/2",
8102
+ "-translate-y-1/2",
8103
+ "ml-2"
8104
+ ];
8250
8105
  case "center-right":
8251
- return {
8252
- ...baseStyles,
8253
- right: "100%",
8254
- top: "50%",
8255
- transform: "translateY(-50%)",
8256
- marginRight: "8px"
8257
- };
8106
+ return [
8107
+ ...baseClasses,
8108
+ "right-full",
8109
+ "top-1/2",
8110
+ "-translate-y-1/2",
8111
+ "mr-2"
8112
+ ];
8258
8113
  default:
8259
- return {
8260
- ...baseStyles,
8261
- top: "100%",
8262
- right: "0",
8263
- marginTop: "8px"
8264
- };
8114
+ return [...baseClasses, "top-full", "right-0", "mt-2"];
8265
8115
  }
8266
- }, "getTooltipStyles");
8116
+ }, "getTooltipClasses");
8267
8117
  const IconButton = /* @__PURE__ */ __name(({
8268
8118
  onClick,
8269
8119
  label,
8270
8120
  children: icon
8271
8121
  }) => {
8272
- const [isButtonHovered, setIsButtonHovered] = (0, import_react4.useState)(false);
8273
- const tooltipStyles = getTooltipStyles();
8274
- return /* @__PURE__ */ import_react4.default.createElement(
8122
+ const [isButtonHovered, setIsButtonHovered] = (0, import_react6.useState)(false);
8123
+ const tooltipClasses = getTooltipClasses();
8124
+ return /* @__PURE__ */ import_react6.default.createElement(
8275
8125
  "button",
8276
8126
  {
8277
- style: {
8278
- padding: "8px",
8279
- backgroundColor: buttonBg,
8280
- color: buttonColor,
8281
- border: "none",
8282
- borderRadius: "8px",
8283
- cursor: "pointer",
8284
- display: "flex",
8285
- alignItems: "center",
8286
- justifyContent: "center",
8287
- width: "32px",
8288
- height: "32px",
8289
- transition: "background-color 0.2s",
8290
- backdropFilter: "blur(8px)",
8291
- WebkitBackdropFilter: "blur(8px)",
8292
- boxShadow: isDark ? "0 2px 8px rgba(0, 0, 0, 0.3)" : "0 2px 8px rgba(0, 0, 0, 0.2)",
8293
- position: "relative"
8294
- },
8295
- onMouseEnter: (e) => {
8296
- e.currentTarget.style.backgroundColor = buttonBgHover;
8297
- setIsButtonHovered(true);
8298
- },
8299
- onMouseLeave: (e) => {
8300
- e.currentTarget.style.backgroundColor = buttonBg;
8301
- setIsButtonHovered(false);
8302
- },
8127
+ 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`,
8128
+ onMouseEnter: () => setIsButtonHovered(true),
8129
+ onMouseLeave: () => setIsButtonHovered(false),
8303
8130
  onClick,
8304
8131
  "aria-label": label
8305
8132
  },
8306
- /* @__PURE__ */ import_react4.default.createElement(
8133
+ /* @__PURE__ */ import_react6.default.createElement(
8307
8134
  "svg",
8308
8135
  {
8309
8136
  xmlns: "http://www.w3.org/2000/svg",
@@ -8315,17 +8142,14 @@ function WidgetDebugger({
8315
8142
  strokeWidth: "2",
8316
8143
  strokeLinecap: "round",
8317
8144
  strokeLinejoin: "round",
8318
- style: { display: "block" }
8145
+ className: "block"
8319
8146
  },
8320
8147
  icon
8321
8148
  ),
8322
- showLabels && /* @__PURE__ */ import_react4.default.createElement(
8149
+ showLabels && /* @__PURE__ */ import_react6.default.createElement(
8323
8150
  "span",
8324
8151
  {
8325
- style: {
8326
- ...tooltipStyles,
8327
- opacity: isButtonHovered ? 1 : 0
8328
- }
8152
+ className: `${tooltipClasses.join(" ")} ${isButtonHovered ? "opacity-100" : "opacity-0"}`
8329
8153
  },
8330
8154
  label
8331
8155
  )
@@ -8352,570 +8176,248 @@ function WidgetDebugger({
8352
8176
  const { top, bottom, left, right } = sa.insets;
8353
8177
  return `T:${top} B:${bottom} L:${left} R:${right}`;
8354
8178
  }, "formatSafeArea");
8355
- return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(
8179
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(
8356
8180
  "div",
8357
8181
  {
8358
8182
  ref: containerRef,
8359
- className,
8360
- style: {
8361
- position: "relative",
8362
- height: "fit-content"
8363
- },
8183
+ className: `${className} relative h-fit`,
8364
8184
  onMouseEnter: () => !attachTo && setIsHovered(true),
8365
8185
  onMouseLeave: () => !attachTo && setIsHovered(false)
8366
8186
  },
8367
- /* @__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" }))),
8187
+ /* @__PURE__ */ import_react6.default.createElement(
8188
+ "div",
8189
+ {
8190
+ className: getPositionClasses().join(" "),
8191
+ style: getPositionOffsetStyles()
8192
+ },
8193
+ !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" })))
8194
+ ),
8368
8195
  children
8369
- ), isOverlayOpen && /* @__PURE__ */ import_react4.default.createElement(
8196
+ ), isOverlayOpen && enableDebugger && /* @__PURE__ */ import_react6.default.createElement(
8370
8197
  "div",
8371
8198
  {
8372
8199
  ref: overlayRef,
8373
- style: {
8374
- position: "fixed",
8375
- top: 0,
8376
- left: 0,
8377
- right: 0,
8378
- bottom: 0,
8379
- backgroundColor: "#000000",
8380
- color: "#ffffff",
8381
- fontFamily: "monospace",
8382
- fontSize: "12px",
8383
- zIndex: 1e4,
8384
- overflow: "auto",
8385
- padding: "16px"
8386
- },
8200
+ className: "fixed inset-0 bg-black text-white font-mono text-xs z-[10000] overflow-auto p-4",
8387
8201
  onClick: (e) => {
8388
8202
  if (e.target === overlayRef.current) {
8389
8203
  setIsOverlayOpen(false);
8390
8204
  }
8391
8205
  }
8392
8206
  },
8393
- /* @__PURE__ */ import_react4.default.createElement(
8207
+ /* @__PURE__ */ import_react6.default.createElement(
8394
8208
  "button",
8395
8209
  {
8396
8210
  onClick: () => setIsOverlayOpen(false),
8397
- style: {
8398
- position: "absolute",
8399
- top: "16px",
8400
- right: "16px",
8401
- backgroundColor: "rgba(255, 255, 255, 0.1)",
8402
- color: "#ffffff",
8403
- border: "none",
8404
- borderRadius: "4px",
8405
- width: "32px",
8406
- height: "32px",
8407
- cursor: "pointer",
8408
- display: "flex",
8409
- alignItems: "center",
8410
- justifyContent: "center",
8411
- fontSize: "18px",
8412
- lineHeight: 1
8413
- },
8211
+ 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",
8414
8212
  "aria-label": "Close"
8415
8213
  },
8416
8214
  "\xD7"
8417
8215
  ),
8418
- /* @__PURE__ */ import_react4.default.createElement(
8419
- "div",
8216
+ /* @__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(
8217
+ "input",
8420
8218
  {
8421
- style: { maxWidth: "1200px", margin: "0 auto", paddingTop: "40px" }
8219
+ type: "text",
8220
+ value: toolName,
8221
+ onChange: (e) => setToolName(e.target.value),
8222
+ placeholder: "Tool name",
8223
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs w-[150px]"
8224
+ }
8225
+ ), /* @__PURE__ */ import_react6.default.createElement(
8226
+ "input",
8227
+ {
8228
+ type: "text",
8229
+ value: toolArgs,
8230
+ onChange: (e) => setToolArgs(e.target.value),
8231
+ placeholder: '{"key": "value"}',
8232
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
8233
+ }
8234
+ ), /* @__PURE__ */ import_react6.default.createElement(
8235
+ "button",
8236
+ {
8237
+ onClick: handleCallTool,
8238
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
8422
8239
  },
8423
- /* @__PURE__ */ import_react4.default.createElement(
8424
- "h1",
8425
- {
8426
- style: {
8427
- fontSize: "18px",
8428
- fontWeight: "bold",
8429
- marginBottom: "16px",
8430
- borderBottom: "1px solid #333",
8431
- paddingBottom: "8px"
8432
- }
8433
- },
8434
- "Debug Info"
8435
- ),
8436
- /* @__PURE__ */ import_react4.default.createElement(
8437
- "table",
8438
- {
8439
- style: {
8440
- width: "100%",
8441
- borderCollapse: "collapse",
8442
- borderSpacing: 0
8443
- }
8444
- },
8445
- /* @__PURE__ */ import_react4.default.createElement("tbody", null, /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8446
- "td",
8447
- {
8448
- style: {
8449
- padding: "8px",
8450
- fontWeight: "bold",
8451
- width: "200px",
8452
- verticalAlign: "top"
8453
- }
8454
- },
8455
- "Props"
8456
- ), /* @__PURE__ */ import_react4.default.createElement(
8457
- "td",
8458
- {
8459
- style: {
8460
- padding: "8px",
8461
- whiteSpace: "pre-wrap",
8462
- wordBreak: "break-all"
8463
- }
8464
- },
8465
- formatValue(props)
8466
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8467
- "td",
8468
- {
8469
- style: {
8470
- padding: "8px",
8471
- fontWeight: "bold",
8472
- width: "200px",
8473
- verticalAlign: "top"
8474
- }
8475
- },
8476
- "Output"
8477
- ), /* @__PURE__ */ import_react4.default.createElement(
8478
- "td",
8479
- {
8480
- style: {
8481
- padding: "8px",
8482
- whiteSpace: "pre-wrap",
8483
- wordBreak: "break-all"
8484
- }
8485
- },
8486
- formatValue(output)
8487
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8488
- "td",
8489
- {
8490
- style: {
8491
- padding: "8px",
8492
- fontWeight: "bold",
8493
- width: "200px",
8494
- verticalAlign: "top"
8495
- }
8496
- },
8497
- "Metadata"
8498
- ), /* @__PURE__ */ import_react4.default.createElement(
8499
- "td",
8500
- {
8501
- style: {
8502
- padding: "8px",
8503
- whiteSpace: "pre-wrap",
8504
- wordBreak: "break-all"
8505
- }
8506
- },
8507
- formatValue(metadata)
8508
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8509
- "td",
8510
- {
8511
- style: {
8512
- padding: "8px",
8513
- fontWeight: "bold",
8514
- width: "200px",
8515
- verticalAlign: "top"
8516
- }
8517
- },
8518
- "State"
8519
- ), /* @__PURE__ */ import_react4.default.createElement(
8520
- "td",
8521
- {
8522
- style: {
8523
- padding: "8px",
8524
- whiteSpace: "pre-wrap",
8525
- wordBreak: "break-all"
8526
- }
8527
- },
8528
- formatValue(state)
8529
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8530
- "td",
8531
- {
8532
- style: {
8533
- padding: "8px",
8534
- fontWeight: "bold",
8535
- width: "200px",
8536
- verticalAlign: "top"
8537
- }
8538
- },
8539
- "Theme"
8540
- ), /* @__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(
8541
- "td",
8542
- {
8543
- style: {
8544
- padding: "8px",
8545
- fontWeight: "bold",
8546
- width: "200px",
8547
- verticalAlign: "top"
8548
- }
8549
- },
8550
- "Display Mode"
8551
- ), /* @__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(
8552
- "td",
8553
- {
8554
- style: {
8555
- padding: "8px",
8556
- fontWeight: "bold",
8557
- width: "200px",
8558
- verticalAlign: "top"
8559
- }
8560
- },
8561
- "Locale"
8562
- ), /* @__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(
8563
- "td",
8564
- {
8565
- style: {
8566
- padding: "8px",
8567
- fontWeight: "bold",
8568
- width: "200px",
8569
- verticalAlign: "top"
8570
- }
8571
- },
8572
- "Max Height"
8573
- ), /* @__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(
8574
- "td",
8575
- {
8576
- style: {
8577
- padding: "8px",
8578
- fontWeight: "bold",
8579
- width: "200px",
8580
- verticalAlign: "top"
8581
- }
8582
- },
8583
- "User Agent"
8584
- ), /* @__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(
8585
- "td",
8586
- {
8587
- style: {
8588
- padding: "8px",
8589
- fontWeight: "bold",
8590
- width: "200px",
8591
- verticalAlign: "top"
8592
- }
8593
- },
8594
- "Safe Area"
8595
- ), /* @__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(
8596
- "td",
8597
- {
8598
- style: {
8599
- padding: "8px",
8600
- fontWeight: "bold",
8601
- width: "200px",
8602
- verticalAlign: "top"
8603
- }
8604
- },
8605
- "API Available"
8606
- ), /* @__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(
8607
- "td",
8608
- {
8609
- style: {
8610
- padding: "8px",
8611
- fontWeight: "bold",
8612
- width: "200px",
8613
- verticalAlign: "top"
8614
- }
8615
- },
8616
- "window.openai Keys"
8617
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, windowOpenAiKeys.length > 0 ? windowOpenAiKeys.join(", ") : "N/A")))
8618
- ),
8619
- /* @__PURE__ */ import_react4.default.createElement(
8620
- "h2",
8621
- {
8622
- style: {
8623
- fontSize: "16px",
8624
- fontWeight: "bold",
8625
- marginTop: "32px",
8626
- marginBottom: "16px",
8627
- borderBottom: "1px solid #333",
8628
- paddingBottom: "8px"
8629
- }
8630
- },
8631
- "Actions"
8632
- ),
8633
- /* @__PURE__ */ import_react4.default.createElement(
8634
- "div",
8635
- {
8636
- style: { display: "flex", flexDirection: "column", gap: "12px" }
8637
- },
8638
- /* @__PURE__ */ import_react4.default.createElement(
8639
- "div",
8640
- {
8641
- style: { display: "flex", gap: "8px", alignItems: "center" }
8642
- },
8643
- /* @__PURE__ */ import_react4.default.createElement(
8644
- "input",
8645
- {
8646
- type: "text",
8647
- value: toolName,
8648
- onChange: (e) => setToolName(e.target.value),
8649
- placeholder: "Tool name",
8650
- style: {
8651
- padding: "6px 8px",
8652
- backgroundColor: "#1a1a1a",
8653
- color: "#ffffff",
8654
- border: "1px solid #333",
8655
- borderRadius: "4px",
8656
- fontFamily: "monospace",
8657
- fontSize: "12px",
8658
- width: "150px"
8659
- }
8660
- }
8661
- ),
8662
- /* @__PURE__ */ import_react4.default.createElement(
8663
- "input",
8664
- {
8665
- type: "text",
8666
- value: toolArgs,
8667
- onChange: (e) => setToolArgs(e.target.value),
8668
- placeholder: '{"key": "value"}',
8669
- style: {
8670
- padding: "6px 8px",
8671
- backgroundColor: "#1a1a1a",
8672
- color: "#ffffff",
8673
- border: "1px solid #333",
8674
- borderRadius: "4px",
8675
- fontFamily: "monospace",
8676
- fontSize: "12px",
8677
- flex: 1
8678
- }
8679
- }
8680
- ),
8681
- /* @__PURE__ */ import_react4.default.createElement(
8682
- "button",
8683
- {
8684
- onClick: handleCallTool,
8685
- style: {
8686
- padding: "6px 12px",
8687
- backgroundColor: "#333",
8688
- color: "#ffffff",
8689
- border: "1px solid #555",
8690
- borderRadius: "4px",
8691
- cursor: "pointer",
8692
- fontFamily: "monospace",
8693
- fontSize: "12px"
8694
- }
8695
- },
8696
- "Call Tool"
8697
- )
8698
- ),
8699
- /* @__PURE__ */ import_react4.default.createElement(
8700
- "div",
8701
- {
8702
- style: { display: "flex", gap: "8px", alignItems: "center" }
8703
- },
8704
- /* @__PURE__ */ import_react4.default.createElement(
8705
- "input",
8706
- {
8707
- type: "text",
8708
- value: followUpMessage,
8709
- onChange: (e) => setFollowUpMessage(e.target.value),
8710
- placeholder: "Follow-up message",
8711
- style: {
8712
- padding: "6px 8px",
8713
- backgroundColor: "#1a1a1a",
8714
- color: "#ffffff",
8715
- border: "1px solid #333",
8716
- borderRadius: "4px",
8717
- fontFamily: "monospace",
8718
- fontSize: "12px",
8719
- flex: 1
8720
- }
8721
- }
8722
- ),
8723
- /* @__PURE__ */ import_react4.default.createElement(
8724
- "button",
8725
- {
8726
- onClick: handleSendFollowUpMessage,
8727
- style: {
8728
- padding: "6px 12px",
8729
- backgroundColor: "#333",
8730
- color: "#ffffff",
8731
- border: "1px solid #555",
8732
- borderRadius: "4px",
8733
- cursor: "pointer",
8734
- fontFamily: "monospace",
8735
- fontSize: "12px"
8736
- }
8737
- },
8738
- "Send Follow-Up"
8739
- )
8740
- ),
8741
- /* @__PURE__ */ import_react4.default.createElement(
8742
- "div",
8743
- {
8744
- style: { display: "flex", gap: "8px", alignItems: "center" }
8745
- },
8746
- /* @__PURE__ */ import_react4.default.createElement(
8747
- "input",
8748
- {
8749
- type: "text",
8750
- value: externalUrl,
8751
- onChange: (e) => setExternalUrl(e.target.value),
8752
- placeholder: "External URL",
8753
- style: {
8754
- padding: "6px 8px",
8755
- backgroundColor: "#1a1a1a",
8756
- color: "#ffffff",
8757
- border: "1px solid #333",
8758
- borderRadius: "4px",
8759
- fontFamily: "monospace",
8760
- fontSize: "12px",
8761
- flex: 1
8762
- }
8763
- }
8764
- ),
8765
- /* @__PURE__ */ import_react4.default.createElement(
8766
- "button",
8767
- {
8768
- onClick: handleOpenExternal,
8769
- style: {
8770
- padding: "6px 12px",
8771
- backgroundColor: "#333",
8772
- color: "#ffffff",
8773
- border: "1px solid #555",
8774
- borderRadius: "4px",
8775
- cursor: "pointer",
8776
- fontFamily: "monospace",
8777
- fontSize: "12px"
8778
- }
8779
- },
8780
- "Open Link"
8781
- )
8782
- ),
8783
- /* @__PURE__ */ import_react4.default.createElement(
8784
- "div",
8785
- {
8786
- style: { display: "flex", gap: "8px", alignItems: "center" }
8787
- },
8788
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "150px", fontSize: "12px" } }, "Display Mode:"),
8789
- /* @__PURE__ */ import_react4.default.createElement(
8790
- "button",
8791
- {
8792
- onClick: () => handleRequestDisplayMode("inline"),
8793
- style: {
8794
- padding: "6px 12px",
8795
- backgroundColor: "#333",
8796
- color: "#ffffff",
8797
- border: "1px solid #555",
8798
- borderRadius: "4px",
8799
- cursor: "pointer",
8800
- fontFamily: "monospace",
8801
- fontSize: "12px",
8802
- flex: 1
8803
- }
8804
- },
8805
- "Inline"
8806
- ),
8807
- /* @__PURE__ */ import_react4.default.createElement(
8808
- "button",
8809
- {
8810
- onClick: () => handleRequestDisplayMode("pip"),
8811
- style: {
8812
- padding: "6px 12px",
8813
- backgroundColor: "#333",
8814
- color: "#ffffff",
8815
- border: "1px solid #555",
8816
- borderRadius: "4px",
8817
- cursor: "pointer",
8818
- fontFamily: "monospace",
8819
- fontSize: "12px",
8820
- flex: 1
8821
- }
8822
- },
8823
- "PiP"
8824
- ),
8825
- /* @__PURE__ */ import_react4.default.createElement(
8826
- "button",
8827
- {
8828
- onClick: () => handleRequestDisplayMode("fullscreen"),
8829
- style: {
8830
- padding: "6px 12px",
8831
- backgroundColor: "#333",
8832
- color: "#ffffff",
8833
- border: "1px solid #555",
8834
- borderRadius: "4px",
8835
- cursor: "pointer",
8836
- fontFamily: "monospace",
8837
- fontSize: "12px",
8838
- flex: 1
8839
- }
8840
- },
8841
- "Fullscreen"
8842
- )
8843
- ),
8844
- /* @__PURE__ */ import_react4.default.createElement(
8845
- "div",
8846
- {
8847
- style: { display: "flex", gap: "8px", alignItems: "center" }
8848
- },
8849
- /* @__PURE__ */ import_react4.default.createElement(
8850
- "button",
8851
- {
8852
- onClick: handleSetState,
8853
- style: {
8854
- padding: "6px 12px",
8855
- backgroundColor: "#333",
8856
- color: "#ffffff",
8857
- border: "1px solid #555",
8858
- borderRadius: "4px",
8859
- cursor: "pointer",
8860
- fontFamily: "monospace",
8861
- fontSize: "12px"
8862
- }
8863
- },
8864
- "Set State (Add Timestamp)"
8865
- )
8866
- ),
8867
- actionResult && /* @__PURE__ */ import_react4.default.createElement(
8868
- "div",
8869
- {
8870
- style: {
8871
- marginTop: "8px",
8872
- padding: "8px",
8873
- backgroundColor: "#1a1a1a",
8874
- border: "1px solid #333",
8875
- borderRadius: "4px",
8876
- whiteSpace: "pre-wrap",
8877
- wordBreak: "break-all",
8878
- fontSize: "11px",
8879
- maxHeight: "200px",
8880
- overflow: "auto"
8881
- }
8882
- },
8883
- /* @__PURE__ */ import_react4.default.createElement(
8884
- "div",
8885
- {
8886
- style: {
8887
- fontWeight: "bold",
8888
- marginBottom: "4px",
8889
- color: "#aaa"
8890
- }
8891
- },
8892
- "Result:"
8893
- ),
8894
- actionResult,
8895
- /* @__PURE__ */ import_react4.default.createElement(
8896
- "button",
8897
- {
8898
- onClick: () => setActionResult(""),
8899
- style: {
8900
- marginTop: "8px",
8901
- padding: "4px 8px",
8902
- backgroundColor: "#333",
8903
- color: "#ffffff",
8904
- border: "1px solid #555",
8905
- borderRadius: "4px",
8906
- cursor: "pointer",
8907
- fontFamily: "monospace",
8908
- fontSize: "11px"
8909
- }
8910
- },
8911
- "Clear"
8912
- )
8913
- )
8914
- )
8915
- )
8240
+ "Call Tool"
8241
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
8242
+ "input",
8243
+ {
8244
+ type: "text",
8245
+ value: followUpMessage,
8246
+ onChange: (e) => setFollowUpMessage(e.target.value),
8247
+ placeholder: "Follow-up message",
8248
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
8249
+ }
8250
+ ), /* @__PURE__ */ import_react6.default.createElement(
8251
+ "button",
8252
+ {
8253
+ onClick: handleSendFollowUpMessage,
8254
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
8255
+ },
8256
+ "Send Follow-Up"
8257
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
8258
+ "input",
8259
+ {
8260
+ type: "text",
8261
+ value: externalUrl,
8262
+ onChange: (e) => setExternalUrl(e.target.value),
8263
+ placeholder: "External URL",
8264
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
8265
+ }
8266
+ ), /* @__PURE__ */ import_react6.default.createElement(
8267
+ "button",
8268
+ {
8269
+ onClick: handleOpenExternal,
8270
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
8271
+ },
8272
+ "Open Link"
8273
+ )), /* @__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(
8274
+ "button",
8275
+ {
8276
+ onClick: () => handleRequestDisplayMode("inline"),
8277
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
8278
+ },
8279
+ "Inline"
8280
+ ), /* @__PURE__ */ import_react6.default.createElement(
8281
+ "button",
8282
+ {
8283
+ onClick: () => handleRequestDisplayMode("pip"),
8284
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
8285
+ },
8286
+ "PiP"
8287
+ ), /* @__PURE__ */ import_react6.default.createElement(
8288
+ "button",
8289
+ {
8290
+ onClick: () => handleRequestDisplayMode("fullscreen"),
8291
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
8292
+ },
8293
+ "Fullscreen"
8294
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
8295
+ "button",
8296
+ {
8297
+ onClick: handleSetState,
8298
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
8299
+ },
8300
+ "Set State (Add Timestamp)"
8301
+ )), 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(
8302
+ "button",
8303
+ {
8304
+ onClick: () => setActionResult(""),
8305
+ className: "mt-2 py-1 px-2 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-[11px]"
8306
+ },
8307
+ "Clear"
8308
+ ))))
8916
8309
  ));
8917
8310
  }
8918
- __name(WidgetDebugger, "WidgetDebugger");
8311
+ __name(WidgetControls, "WidgetControls");
8312
+
8313
+ // src/react/McpUseProvider.tsx
8314
+ var import_react7 = __toESM(require("react"), 1);
8315
+ var import_react_router_dom = require("react-router-dom");
8316
+ function getBasename() {
8317
+ if (typeof window === "undefined") return "/";
8318
+ const path4 = window.location.pathname;
8319
+ const match = path4.match(/^(\/inspector\/api\/dev-widget\/[^/]+)/);
8320
+ if (match) {
8321
+ return match[1];
8322
+ }
8323
+ return "/";
8324
+ }
8325
+ __name(getBasename, "getBasename");
8326
+ var HEIGHT_DEBOUNCE_MS = 150;
8327
+ var MIN_HEIGHT_CHANGE_PX = 5;
8328
+ function McpUseProvider({
8329
+ children,
8330
+ debugger: enableDebugger = false,
8331
+ viewControls = false,
8332
+ autoSize = false
8333
+ }) {
8334
+ const basename = getBasename();
8335
+ const containerRef = (0, import_react7.useRef)(null);
8336
+ const lastHeightRef = (0, import_react7.useRef)(0);
8337
+ const debounceTimeoutRef = (0, import_react7.useRef)(null);
8338
+ const notificationInProgressRef = (0, import_react7.useRef)(false);
8339
+ const notifyHeight = (0, import_react7.useCallback)((height) => {
8340
+ if (typeof window !== "undefined" && window.openai?.notifyIntrinsicHeight) {
8341
+ notificationInProgressRef.current = true;
8342
+ window.openai.notifyIntrinsicHeight(height).then(() => {
8343
+ notificationInProgressRef.current = false;
8344
+ }).catch((error) => {
8345
+ notificationInProgressRef.current = false;
8346
+ console.error(
8347
+ "[McpUseProvider] Failed to notify intrinsic height:",
8348
+ error
8349
+ );
8350
+ });
8351
+ }
8352
+ }, []);
8353
+ const debouncedNotifyHeight = (0, import_react7.useCallback)(
8354
+ (height) => {
8355
+ if (debounceTimeoutRef.current) {
8356
+ clearTimeout(debounceTimeoutRef.current);
8357
+ }
8358
+ debounceTimeoutRef.current = setTimeout(() => {
8359
+ const heightDiff = Math.abs(height - lastHeightRef.current);
8360
+ if (heightDiff >= MIN_HEIGHT_CHANGE_PX && height > 0) {
8361
+ lastHeightRef.current = height;
8362
+ notifyHeight(height);
8363
+ }
8364
+ }, HEIGHT_DEBOUNCE_MS);
8365
+ },
8366
+ [notifyHeight]
8367
+ );
8368
+ (0, import_react7.useEffect)(() => {
8369
+ if (!autoSize) {
8370
+ return;
8371
+ }
8372
+ const container = containerRef.current;
8373
+ if (!container || typeof ResizeObserver === "undefined") {
8374
+ return;
8375
+ }
8376
+ const observer = new ResizeObserver((entries) => {
8377
+ if (notificationInProgressRef.current) {
8378
+ return;
8379
+ }
8380
+ for (const entry of entries) {
8381
+ const height = entry.contentRect.height;
8382
+ const scrollHeight = entry.target.scrollHeight;
8383
+ const intrinsicHeight = Math.max(height, scrollHeight);
8384
+ debouncedNotifyHeight(intrinsicHeight);
8385
+ }
8386
+ });
8387
+ observer.observe(container);
8388
+ const initialHeight = Math.max(
8389
+ container.offsetHeight,
8390
+ container.scrollHeight
8391
+ );
8392
+ if (initialHeight > 0) {
8393
+ debouncedNotifyHeight(initialHeight);
8394
+ }
8395
+ return () => {
8396
+ observer.disconnect();
8397
+ if (debounceTimeoutRef.current) {
8398
+ clearTimeout(debounceTimeoutRef.current);
8399
+ debounceTimeoutRef.current = null;
8400
+ }
8401
+ notificationInProgressRef.current = false;
8402
+ };
8403
+ }, [autoSize, debouncedNotifyHeight]);
8404
+ let content = children;
8405
+ content = /* @__PURE__ */ import_react7.default.createElement(ErrorBoundary, null, content);
8406
+ if (enableDebugger || viewControls) {
8407
+ content = /* @__PURE__ */ import_react7.default.createElement(WidgetControls, { debugger: enableDebugger, viewControls }, content);
8408
+ }
8409
+ content = /* @__PURE__ */ import_react7.default.createElement(import_react_router_dom.BrowserRouter, { basename }, content);
8410
+ content = /* @__PURE__ */ import_react7.default.createElement(ThemeProvider, null, content);
8411
+ if (autoSize) {
8412
+ const containerStyle = {
8413
+ width: "100%",
8414
+ minHeight: 0
8415
+ };
8416
+ content = /* @__PURE__ */ import_react7.default.createElement("div", { ref: containerRef, style: containerStyle }, content);
8417
+ }
8418
+ return /* @__PURE__ */ import_react7.default.createElement(import_react7.StrictMode, null, content);
8419
+ }
8420
+ __name(McpUseProvider, "McpUseProvider");
8919
8421
 
8920
8422
  // src/client/prompts.ts
8921
8423
  var PROMPTS = {