mcp-use 1.4.1 → 1.5.0-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{chunk-RE7EYFDV.js → chunk-5XVM4A23.js} +446 -964
  3. package/dist/{chunk-35A6O3YH.js → chunk-MCF5P6GJ.js} +1 -1
  4. package/dist/{display-LIYVTGEU.js → display-YIYC6WJE.js} +77 -6
  5. package/dist/index.cjs +572 -1004
  6. package/dist/index.js +33 -12
  7. package/dist/src/agents/display.d.ts +5 -1
  8. package/dist/src/agents/display.d.ts.map +1 -1
  9. package/dist/src/agents/index.cjs +77 -6
  10. package/dist/src/agents/index.js +1 -1
  11. package/dist/src/browser.cjs +77 -6
  12. package/dist/src/browser.js +1 -1
  13. package/dist/src/client/codeExecutor.d.ts +1 -1
  14. package/dist/src/client/codeExecutor.d.ts.map +1 -1
  15. package/dist/src/client/executors/base.d.ts +10 -1
  16. package/dist/src/client/executors/base.d.ts.map +1 -1
  17. package/dist/src/client.d.ts +1 -1
  18. package/dist/src/client.d.ts.map +1 -1
  19. package/dist/src/react/ErrorBoundary.d.ts +24 -0
  20. package/dist/src/react/ErrorBoundary.d.ts.map +1 -0
  21. package/dist/src/react/Image.d.ts +11 -0
  22. package/dist/src/react/Image.d.ts.map +1 -0
  23. package/dist/src/react/McpUseProvider.d.ts +46 -0
  24. package/dist/src/react/McpUseProvider.d.ts.map +1 -0
  25. package/dist/src/react/ThemeProvider.d.ts +14 -0
  26. package/dist/src/react/ThemeProvider.d.ts.map +1 -0
  27. package/dist/src/react/WidgetControls.d.ts +44 -0
  28. package/dist/src/react/WidgetControls.d.ts.map +1 -0
  29. package/dist/src/react/index.cjs +474 -992
  30. package/dist/src/react/index.d.ts +9 -6
  31. package/dist/src/react/index.d.ts.map +1 -1
  32. package/dist/src/react/index.js +11 -5
  33. package/dist/src/react/useWidget.d.ts.map +1 -1
  34. package/dist/src/react/widget-types.d.ts +6 -0
  35. package/dist/src/react/widget-types.d.ts.map +1 -1
  36. package/dist/src/server/connect-adapter.d.ts.map +1 -1
  37. package/dist/src/server/index.cjs +232 -21
  38. package/dist/src/server/index.js +232 -21
  39. package/dist/src/server/mcp-server.d.ts.map +1 -1
  40. package/package.json +6 -4
  41. package/dist/src/react/WidgetDebugger.d.ts +0 -31
  42. package/dist/src/react/WidgetDebugger.d.ts.map +0 -1
  43. package/dist/src/react/WidgetFullscreenWrapper.d.ts +0 -32
  44. package/dist/src/react/WidgetFullscreenWrapper.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -722,9 +722,27 @@ function extractToolMessageContent(output) {
722
722
  }
723
723
  return null;
724
724
  }
725
- function formatSearchToolsAsTree(tools) {
725
+ function formatSearchToolsAsTree(tools, meta, query) {
726
+ const metaLines = [];
727
+ if (meta) {
728
+ if (meta.total_tools !== void 0) {
729
+ metaLines.push(`Total tools: ${meta.total_tools}`);
730
+ }
731
+ if (meta.namespaces && meta.namespaces.length > 0) {
732
+ metaLines.push(`Namespaces: ${meta.namespaces.join(", ")}`);
733
+ }
734
+ if (meta.result_count !== void 0) {
735
+ metaLines.push(`Results: ${meta.result_count}`);
736
+ }
737
+ }
726
738
  if (!Array.isArray(tools) || tools.length === 0) {
727
- return "(no tools found)";
739
+ const noResultsMsg = query ? `No tools found for query "${query}"` : "(no tools found)";
740
+ if (metaLines.length > 0) {
741
+ return `${metaLines.join("\n")}
742
+
743
+ ${noResultsMsg}`;
744
+ }
745
+ return noResultsMsg;
728
746
  }
729
747
  const toolsByServer = {};
730
748
  for (const tool of tools) {
@@ -735,6 +753,20 @@ function formatSearchToolsAsTree(tools) {
735
753
  toolsByServer[server].push(tool);
736
754
  }
737
755
  const lines = [];
756
+ if (meta) {
757
+ if (meta.total_tools !== void 0) {
758
+ lines.push(`Total tools: ${meta.total_tools}`);
759
+ }
760
+ if (meta.namespaces && meta.namespaces.length > 0) {
761
+ lines.push(`Namespaces: ${meta.namespaces.join(", ")}`);
762
+ }
763
+ if (meta.result_count !== void 0) {
764
+ lines.push(`Results: ${meta.result_count}`);
765
+ }
766
+ if (lines.length > 0) {
767
+ lines.push("");
768
+ }
769
+ }
738
770
  const servers = Object.keys(toolsByServer).sort();
739
771
  for (let i = 0; i < servers.length; i++) {
740
772
  const server = servers[i];
@@ -749,11 +781,34 @@ function formatSearchToolsAsTree(tools) {
749
781
  const isLastTool = j === serverTools.length - 1;
750
782
  const indent = isLastServer ? " " : "\u2502 ";
751
783
  const toolPrefix = isLastTool ? "\u2514\u2500" : "\u251C\u2500";
752
- let toolLine = `${indent}${toolPrefix} ${tool.name}`;
784
+ const toolLine = `${indent}${toolPrefix} ${tool.name}`;
785
+ lines.push(toolLine);
753
786
  if (tool.description) {
754
- toolLine += import_chalk.default.dim(` - ${tool.description}`);
787
+ const descAlign = isLastTool ? " " : "\u2502 ";
788
+ const descriptionIndent = `${indent}${descAlign}`;
789
+ const indentLength = stripAnsi(descriptionIndent).length;
790
+ const availableWidth = Math.max(40, TERMINAL_WIDTH - indentLength - 4);
791
+ const words = tool.description.split(/(\s+)/);
792
+ const wrappedLines = [];
793
+ let currentLine = "";
794
+ for (const word of words) {
795
+ const testLine = currentLine + word;
796
+ if (stripAnsi(testLine).length <= availableWidth) {
797
+ currentLine = testLine;
798
+ } else {
799
+ if (currentLine) {
800
+ wrappedLines.push(currentLine.trimEnd());
801
+ }
802
+ currentLine = word.trimStart();
803
+ }
804
+ }
805
+ if (currentLine) {
806
+ wrappedLines.push(currentLine.trimEnd());
807
+ }
808
+ for (const descLine of wrappedLines) {
809
+ lines.push(`${descriptionIndent}${import_chalk.default.dim(descLine)}`);
810
+ }
755
811
  }
756
- lines.push(toolLine);
757
812
  }
758
813
  }
759
814
  return lines.join("\n");
@@ -797,6 +852,8 @@ function handleToolEnd(event) {
797
852
  }
798
853
  }
799
854
  if (toolName === "search_tools") {
855
+ const toolInput = event.data?.input;
856
+ const query = toolInput?.query;
800
857
  let actualContent = content;
801
858
  if (typeof content === "object" && content !== null && !Array.isArray(content) && "content" in content) {
802
859
  const innerContent = content.content;
@@ -810,8 +867,22 @@ function handleToolEnd(event) {
810
867
  }
811
868
  }
812
869
  }
870
+ if (typeof actualContent === "object" && actualContent !== null && !Array.isArray(actualContent) && "results" in actualContent && Array.isArray(actualContent.results)) {
871
+ const results = actualContent.results;
872
+ const contentWithMeta = actualContent;
873
+ const meta = contentWithMeta.meta;
874
+ const treeStr = formatSearchToolsAsTree(results, meta, query);
875
+ const statusText = status === "success" ? import_chalk.default.green("Success") : import_chalk.default.red("Error");
876
+ const title2 = `${statusText}: ${toolName} - Result`;
877
+ printBox(treeStr, title2, void 0, false);
878
+ return;
879
+ }
813
880
  if (Array.isArray(actualContent)) {
814
- const treeStr = formatSearchToolsAsTree(actualContent);
881
+ const treeStr = formatSearchToolsAsTree(
882
+ actualContent,
883
+ void 0,
884
+ query
885
+ );
815
886
  const statusText = status === "success" ? import_chalk.default.green("Success") : import_chalk.default.red("Error");
816
887
  const title2 = `${statusText}: ${toolName} - Result`;
817
888
  printBox(treeStr, title2, void 0, false);
@@ -924,7 +995,9 @@ __export(index_exports, {
924
995
  BrowserOAuthClientProvider: () => BrowserOAuthClientProvider,
925
996
  ConnectMCPServerTool: () => ConnectMCPServerTool,
926
997
  E2BCodeExecutor: () => E2BCodeExecutor,
998
+ ErrorBoundary: () => ErrorBoundary,
927
999
  HttpConnector: () => HttpConnector,
1000
+ Image: () => Image,
928
1001
  LINEAR_OAUTH_CONFIG: () => LINEAR_OAUTH_CONFIG,
929
1002
  LangChainAdapter: () => LangChainAdapter,
930
1003
  ListMCPServersTool: () => ListMCPServersTool,
@@ -932,6 +1005,7 @@ __export(index_exports, {
932
1005
  MCPAgent: () => MCPAgent,
933
1006
  MCPClient: () => MCPClient,
934
1007
  MCPSession: () => MCPSession,
1008
+ McpUseProvider: () => McpUseProvider,
935
1009
  OAuthHelper: () => OAuthHelper,
936
1010
  ObservabilityManager: () => ObservabilityManager,
937
1011
  PROMPTS: () => PROMPTS,
@@ -940,10 +1014,10 @@ __export(index_exports, {
940
1014
  ServerManager: () => ServerManager,
941
1015
  StdioConnector: () => StdioConnector,
942
1016
  Telemetry: () => Telemetry,
1017
+ ThemeProvider: () => ThemeProvider,
943
1018
  VMCodeExecutor: () => VMCodeExecutor,
944
1019
  WebSocketConnector: () => WebSocketConnector,
945
- WidgetDebugger: () => WidgetDebugger,
946
- WidgetFullscreenWrapper: () => WidgetFullscreenWrapper,
1020
+ WidgetControls: () => WidgetControls,
947
1021
  createOAuthMCPConfig: () => createOAuthMCPConfig,
948
1022
  createReadableStreamFromGenerator: () => createReadableStreamFromGenerator,
949
1023
  isVMAvailable: () => isVMAvailable,
@@ -4016,18 +4090,17 @@ var BaseCodeExecutor = class {
4016
4090
  createSearchToolsFunction() {
4017
4091
  return async (query = "", detailLevel = "full") => {
4018
4092
  const allTools = [];
4093
+ const allNamespaces = /* @__PURE__ */ new Set();
4019
4094
  const queryLower = query.toLowerCase();
4020
4095
  const activeSessions = this.client.getAllActiveSessions();
4021
4096
  for (const [serverName, session] of Object.entries(activeSessions)) {
4022
4097
  if (serverName === "code_mode") continue;
4023
4098
  try {
4024
4099
  const tools = session.connector.tools;
4100
+ if (tools && tools.length > 0) {
4101
+ allNamespaces.add(serverName);
4102
+ }
4025
4103
  for (const tool of tools) {
4026
- if (query) {
4027
- const nameMatch = tool.name.toLowerCase().includes(queryLower);
4028
- const descMatch = tool.description?.toLowerCase().includes(queryLower);
4029
- if (!nameMatch && !descMatch) continue;
4030
- }
4031
4104
  if (detailLevel === "names") {
4032
4105
  allTools.push({ name: tool.name, server: serverName });
4033
4106
  } else if (detailLevel === "descriptions") {
@@ -4049,7 +4122,23 @@ var BaseCodeExecutor = class {
4049
4122
  logger.warn(`Failed to search tools in server ${serverName}: ${e}`);
4050
4123
  }
4051
4124
  }
4052
- return allTools;
4125
+ let filteredTools = allTools;
4126
+ if (query) {
4127
+ filteredTools = allTools.filter((tool) => {
4128
+ const nameMatch = tool.name.toLowerCase().includes(queryLower);
4129
+ const descMatch = tool.description?.toLowerCase().includes(queryLower);
4130
+ const serverMatch = tool.server.toLowerCase().includes(queryLower);
4131
+ return nameMatch || descMatch || serverMatch;
4132
+ });
4133
+ }
4134
+ return {
4135
+ meta: {
4136
+ total_tools: allTools.length,
4137
+ namespaces: Array.from(allNamespaces).sort(),
4138
+ result_count: filteredTools.length
4139
+ },
4140
+ results: filteredTools
4141
+ };
4053
4142
  };
4054
4143
  }
4055
4144
  };
@@ -7430,15 +7519,61 @@ function useMcp(options) {
7430
7519
  }
7431
7520
  __name(useMcp, "useMcp");
7432
7521
 
7522
+ // src/react/ErrorBoundary.tsx
7523
+ var import_react2 = __toESM(require("react"), 1);
7524
+ var ErrorBoundary = class extends import_react2.default.Component {
7525
+ static {
7526
+ __name(this, "ErrorBoundary");
7527
+ }
7528
+ constructor(props) {
7529
+ super(props);
7530
+ this.state = { hasError: false, error: null };
7531
+ }
7532
+ static getDerivedStateFromError(error) {
7533
+ return { hasError: true, error };
7534
+ }
7535
+ componentDidCatch(error, errorInfo) {
7536
+ console.error("Widget Error:", error, errorInfo);
7537
+ }
7538
+ render() {
7539
+ if (this.state.hasError) {
7540
+ 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));
7541
+ }
7542
+ return this.props.children;
7543
+ }
7544
+ };
7545
+
7546
+ // src/react/Image.tsx
7547
+ var import_react3 = __toESM(require("react"), 1);
7548
+ var Image = /* @__PURE__ */ __name(({ src, ...props }) => {
7549
+ const publicUrl = typeof window !== "undefined" && window.__mcpPublicUrl ? window.__mcpPublicUrl : "";
7550
+ const getFinalSrc = /* @__PURE__ */ __name((source) => {
7551
+ if (!source) return source;
7552
+ if (source.startsWith("http://") || source.startsWith("https://") || source.startsWith("data:")) {
7553
+ return source;
7554
+ }
7555
+ if (!publicUrl) {
7556
+ return source;
7557
+ }
7558
+ const cleanSrc = source.startsWith("/") ? source.slice(1) : source;
7559
+ return `${publicUrl}/${cleanSrc}`;
7560
+ }, "getFinalSrc");
7561
+ const finalSrc = getFinalSrc(src);
7562
+ return /* @__PURE__ */ import_react3.default.createElement("img", { src: finalSrc, ...props });
7563
+ }, "Image");
7564
+
7565
+ // src/react/ThemeProvider.tsx
7566
+ var import_react5 = __toESM(require("react"), 1);
7567
+
7433
7568
  // src/react/useWidget.ts
7434
- var import_react2 = require("react");
7569
+ var import_react4 = require("react");
7435
7570
 
7436
7571
  // src/react/widget-types.ts
7437
7572
  var SET_GLOBALS_EVENT_TYPE = "openai:set_globals";
7438
7573
 
7439
7574
  // src/react/useWidget.ts
7440
7575
  function useOpenAiGlobal(key) {
7441
- return (0, import_react2.useSyncExternalStore)(
7576
+ return (0, import_react4.useSyncExternalStore)(
7442
7577
  (onChange) => {
7443
7578
  const handleSetGlobal = /* @__PURE__ */ __name((event) => {
7444
7579
  const customEvent = event;
@@ -7462,10 +7597,10 @@ function useOpenAiGlobal(key) {
7462
7597
  }
7463
7598
  __name(useOpenAiGlobal, "useOpenAiGlobal");
7464
7599
  function useWidget(defaultProps) {
7465
- const [isOpenAiAvailable, setIsOpenAiAvailable] = (0, import_react2.useState)(
7600
+ const [isOpenAiAvailable, setIsOpenAiAvailable] = (0, import_react4.useState)(
7466
7601
  () => typeof window !== "undefined" && !!window.openai
7467
7602
  );
7468
- (0, import_react2.useEffect)(() => {
7603
+ (0, import_react4.useEffect)(() => {
7469
7604
  if (typeof window !== "undefined" && window.openai) {
7470
7605
  setIsOpenAiAvailable(true);
7471
7606
  return;
@@ -7499,11 +7634,12 @@ function useWidget(defaultProps) {
7499
7634
  }
7500
7635
  };
7501
7636
  }, []);
7502
- const provider = (0, import_react2.useMemo)(() => {
7637
+ const provider = (0, import_react4.useMemo)(() => {
7503
7638
  return isOpenAiAvailable ? "openai" : "mcp-ui";
7504
7639
  }, [isOpenAiAvailable]);
7505
- const urlParams = (0, import_react2.useMemo)(() => {
7506
- const urlParams2 = new URLSearchParams(window?.location?.search);
7640
+ const searchString = typeof window !== "undefined" ? window.location.search : "";
7641
+ const urlParams = (0, import_react4.useMemo)(() => {
7642
+ const urlParams2 = new URLSearchParams(searchString);
7507
7643
  if (urlParams2.has("mcpUseParams")) {
7508
7644
  return JSON.parse(urlParams2.get("mcpUseParams"));
7509
7645
  }
@@ -7512,7 +7648,7 @@ function useWidget(defaultProps) {
7512
7648
  toolOutput: {},
7513
7649
  toolId: ""
7514
7650
  };
7515
- }, [window?.location?.search]);
7651
+ }, [searchString]);
7516
7652
  const toolInput = provider === "openai" ? useOpenAiGlobal("toolInput") : urlParams.toolInput;
7517
7653
  const toolOutput = provider === "openai" ? useOpenAiGlobal("toolOutput") : urlParams.toolOutput;
7518
7654
  const toolResponseMetadata = useOpenAiGlobal("toolResponseMetadata");
@@ -7523,13 +7659,19 @@ function useWidget(defaultProps) {
7523
7659
  const maxHeight = useOpenAiGlobal("maxHeight");
7524
7660
  const userAgent = useOpenAiGlobal("userAgent");
7525
7661
  const locale = useOpenAiGlobal("locale");
7526
- const [localWidgetState, setLocalWidgetState] = (0, import_react2.useState)(null);
7527
- (0, import_react2.useEffect)(() => {
7662
+ const mcp_url = (0, import_react4.useMemo)(() => {
7663
+ if (typeof window !== "undefined" && window.__mcpPublicUrl) {
7664
+ return window.__mcpPublicUrl.replace(/\/mcp-use\/public$/, "");
7665
+ }
7666
+ return "";
7667
+ }, []);
7668
+ const [localWidgetState, setLocalWidgetState] = (0, import_react4.useState)(null);
7669
+ (0, import_react4.useEffect)(() => {
7528
7670
  if (widgetState !== void 0) {
7529
7671
  setLocalWidgetState(widgetState);
7530
7672
  }
7531
7673
  }, [widgetState]);
7532
- const callTool = (0, import_react2.useCallback)(
7674
+ const callTool = (0, import_react4.useCallback)(
7533
7675
  async (name, args) => {
7534
7676
  if (!window.openai?.callTool) {
7535
7677
  throw new Error("window.openai.callTool is not available");
@@ -7538,7 +7680,7 @@ function useWidget(defaultProps) {
7538
7680
  },
7539
7681
  []
7540
7682
  );
7541
- const sendFollowUpMessage = (0, import_react2.useCallback)(
7683
+ const sendFollowUpMessage = (0, import_react4.useCallback)(
7542
7684
  async (prompt) => {
7543
7685
  if (!window.openai?.sendFollowUpMessage) {
7544
7686
  throw new Error("window.openai.sendFollowUpMessage is not available");
@@ -7547,13 +7689,13 @@ function useWidget(defaultProps) {
7547
7689
  },
7548
7690
  []
7549
7691
  );
7550
- const openExternal = (0, import_react2.useCallback)((href) => {
7692
+ const openExternal = (0, import_react4.useCallback)((href) => {
7551
7693
  if (!window.openai?.openExternal) {
7552
7694
  throw new Error("window.openai.openExternal is not available");
7553
7695
  }
7554
7696
  window.openai.openExternal({ href });
7555
7697
  }, []);
7556
- const requestDisplayMode = (0, import_react2.useCallback)(
7698
+ const requestDisplayMode = (0, import_react4.useCallback)(
7557
7699
  async (mode) => {
7558
7700
  if (!window.openai?.requestDisplayMode) {
7559
7701
  throw new Error("window.openai.requestDisplayMode is not available");
@@ -7562,16 +7704,17 @@ function useWidget(defaultProps) {
7562
7704
  },
7563
7705
  []
7564
7706
  );
7565
- const setState = (0, import_react2.useCallback)(
7707
+ const setState = (0, import_react4.useCallback)(
7566
7708
  async (state) => {
7567
- const newState = typeof state === "function" ? state(localWidgetState) : state;
7568
7709
  if (!window.openai?.setWidgetState) {
7569
7710
  throw new Error("window.openai.setWidgetState is not available");
7570
7711
  }
7712
+ const currentState = widgetState !== void 0 ? widgetState : localWidgetState;
7713
+ const newState = typeof state === "function" ? state(currentState) : state;
7571
7714
  setLocalWidgetState(newState);
7572
7715
  return window.openai.setWidgetState(newState);
7573
7716
  },
7574
- [localWidgetState]
7717
+ [widgetState, localWidgetState]
7575
7718
  );
7576
7719
  return {
7577
7720
  // Props and state (with defaults)
@@ -7590,6 +7733,7 @@ function useWidget(defaultProps) {
7590
7733
  capabilities: { hover: true, touch: false }
7591
7734
  },
7592
7735
  locale: locale || "en",
7736
+ mcp_url,
7593
7737
  // Actions
7594
7738
  callTool,
7595
7739
  sendFollowUpMessage,
@@ -7612,7 +7756,7 @@ function useWidgetTheme() {
7612
7756
  __name(useWidgetTheme, "useWidgetTheme");
7613
7757
  function useWidgetState(defaultState) {
7614
7758
  const { state, setState } = useWidget();
7615
- (0, import_react2.useEffect)(() => {
7759
+ (0, import_react4.useEffect)(() => {
7616
7760
  if (state === null && defaultState !== void 0 && window.openai?.setWidgetState) {
7617
7761
  setState(defaultState);
7618
7762
  }
@@ -7621,283 +7765,49 @@ function useWidgetState(defaultState) {
7621
7765
  }
7622
7766
  __name(useWidgetState, "useWidgetState");
7623
7767
 
7624
- // src/react/WidgetFullscreenWrapper.tsx
7625
- var import_react3 = __toESM(require("react"), 1);
7626
- function WidgetFullscreenWrapper({
7627
- children,
7628
- className = "",
7629
- position = "top-right",
7630
- attachTo,
7631
- showLabels = true
7632
- }) {
7633
- const { displayMode, requestDisplayMode, theme, safeArea, isAvailable } = useWidget();
7634
- const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
7635
- const containerRef = (0, import_react3.useRef)(null);
7636
- const isFullscreen = displayMode === "fullscreen" && isAvailable;
7637
- const isPip = displayMode === "pip" && isAvailable;
7638
- const isDark = theme === "dark";
7639
- const buttonBg = isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.7)";
7640
- const buttonBgHover = isDark ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.9)";
7641
- const buttonColor = "white";
7642
- const getPositionStyles = /* @__PURE__ */ __name(() => {
7643
- const baseOffset = 16;
7644
- const topOffset = safeArea?.insets?.top ? `${Math.max(baseOffset, safeArea.insets.top + 8)}px` : `${baseOffset}px`;
7645
- const rightOffset = safeArea?.insets?.right ? `${Math.max(baseOffset, safeArea.insets.right + 8)}px` : `${baseOffset}px`;
7646
- const bottomOffset = safeArea?.insets?.bottom ? `${Math.max(baseOffset, safeArea.insets.bottom + 8)}px` : `${baseOffset}px`;
7647
- const leftOffset = safeArea?.insets?.left ? `${Math.max(baseOffset, safeArea.insets.left + 8)}px` : `${baseOffset}px`;
7648
- const styles = {
7649
- position: "absolute",
7650
- zIndex: 1e3,
7651
- display: "flex",
7652
- gap: "8px",
7653
- opacity: isHovered ? 1 : 0,
7654
- transition: "opacity 0.2s ease-in-out",
7655
- pointerEvents: isHovered ? "auto" : "none"
7656
- };
7657
- switch (position) {
7658
- case "top-left":
7659
- styles.top = topOffset;
7660
- styles.left = leftOffset;
7661
- break;
7662
- case "top-center":
7663
- styles.top = topOffset;
7664
- styles.left = "50%";
7665
- styles.transform = "translateX(-50%)";
7666
- break;
7667
- case "top-right":
7668
- styles.top = topOffset;
7669
- styles.right = rightOffset;
7670
- break;
7671
- case "center-left":
7672
- styles.top = "50%";
7673
- styles.left = leftOffset;
7674
- styles.transform = "translateY(-50%)";
7675
- break;
7676
- case "center-right":
7677
- styles.top = "50%";
7678
- styles.right = rightOffset;
7679
- styles.transform = "translateY(-50%)";
7680
- break;
7681
- case "bottom-left":
7682
- styles.bottom = bottomOffset;
7683
- styles.left = leftOffset;
7684
- break;
7685
- case "bottom-center":
7686
- styles.bottom = bottomOffset;
7687
- styles.left = "50%";
7688
- styles.transform = "translateX(-50%)";
7689
- break;
7690
- case "bottom-right":
7691
- styles.bottom = bottomOffset;
7692
- styles.right = rightOffset;
7693
- break;
7694
- default:
7695
- styles.top = topOffset;
7696
- styles.right = rightOffset;
7697
- break;
7698
- }
7699
- return styles;
7700
- }, "getPositionStyles");
7701
- (0, import_react3.useEffect)(() => {
7702
- if (!attachTo) return;
7703
- const handleMouseEnter = /* @__PURE__ */ __name(() => setIsHovered(true), "handleMouseEnter");
7704
- const handleMouseLeave = /* @__PURE__ */ __name(() => setIsHovered(false), "handleMouseLeave");
7705
- attachTo.addEventListener("mouseenter", handleMouseEnter);
7706
- attachTo.addEventListener("mouseleave", handleMouseLeave);
7707
- return () => {
7708
- attachTo.removeEventListener("mouseenter", handleMouseEnter);
7709
- attachTo.removeEventListener("mouseleave", handleMouseLeave);
7710
- };
7711
- }, [attachTo]);
7712
- const handleFullscreen = /* @__PURE__ */ __name(async () => {
7713
- try {
7714
- await requestDisplayMode("fullscreen");
7715
- } catch (error) {
7716
- console.error("Failed to go fullscreen:", error);
7717
- }
7718
- }, "handleFullscreen");
7719
- const handlePip = /* @__PURE__ */ __name(async () => {
7720
- try {
7721
- await requestDisplayMode("pip");
7722
- } catch (error) {
7723
- console.error("Failed to go pip:", error);
7724
- }
7725
- }, "handlePip");
7726
- const getTooltipStyles = /* @__PURE__ */ __name(() => {
7727
- const baseStyles = {
7728
- position: "absolute",
7729
- padding: "4px 8px",
7730
- backgroundColor: isDark ? "rgba(0, 0, 0, 0.9)" : "rgba(0, 0, 0, 0.9)",
7731
- color: "white",
7732
- borderRadius: "4px",
7733
- fontSize: "12px",
7734
- whiteSpace: "nowrap",
7735
- pointerEvents: "none",
7736
- transition: "opacity 0.2s ease-in-out"
7737
- };
7738
- switch (position) {
7739
- case "top-right":
7740
- return {
7741
- ...baseStyles,
7742
- top: "100%",
7743
- right: "0",
7744
- marginTop: "8px"
7745
- };
7746
- case "top-left":
7747
- return {
7748
- ...baseStyles,
7749
- top: "100%",
7750
- left: "0",
7751
- marginTop: "8px"
7752
- };
7753
- case "top-center":
7754
- return {
7755
- ...baseStyles,
7756
- top: "100%",
7757
- left: "50%",
7758
- transform: "translateX(-50%)",
7759
- marginTop: "8px"
7760
- };
7761
- case "bottom-right":
7762
- return {
7763
- ...baseStyles,
7764
- bottom: "100%",
7765
- right: "0",
7766
- marginBottom: "8px"
7767
- };
7768
- case "bottom-left":
7769
- return {
7770
- ...baseStyles,
7771
- bottom: "100%",
7772
- left: "0",
7773
- marginBottom: "8px"
7774
- };
7775
- case "bottom-center":
7776
- return {
7777
- ...baseStyles,
7778
- bottom: "100%",
7779
- left: "50%",
7780
- transform: "translateX(-50%)",
7781
- marginBottom: "8px"
7782
- };
7783
- case "center-left":
7784
- return {
7785
- ...baseStyles,
7786
- left: "100%",
7787
- top: "50%",
7788
- transform: "translateY(-50%)",
7789
- marginLeft: "8px"
7790
- };
7791
- case "center-right":
7792
- return {
7793
- ...baseStyles,
7794
- right: "100%",
7795
- top: "50%",
7796
- transform: "translateY(-50%)",
7797
- marginRight: "8px"
7798
- };
7799
- default:
7800
- return {
7801
- ...baseStyles,
7802
- top: "100%",
7803
- right: "0",
7804
- marginTop: "8px"
7805
- };
7768
+ // src/react/ThemeProvider.tsx
7769
+ var ThemeProvider = /* @__PURE__ */ __name(({
7770
+ children
7771
+ }) => {
7772
+ const { theme, isAvailable } = useWidget();
7773
+ console.log("theme", theme);
7774
+ const [systemPreference, setSystemPreference] = (0, import_react5.useState)(
7775
+ () => {
7776
+ if (typeof window === "undefined") return "light";
7777
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
7806
7778
  }
7807
- }, "getTooltipStyles");
7808
- const IconButton = /* @__PURE__ */ __name(({
7809
- onClick,
7810
- label,
7811
- children: icon
7812
- }) => {
7813
- const [isButtonHovered, setIsButtonHovered] = (0, import_react3.useState)(false);
7814
- const tooltipStyles = getTooltipStyles();
7815
- return /* @__PURE__ */ import_react3.default.createElement(
7816
- "button",
7817
- {
7818
- style: {
7819
- padding: "8px",
7820
- backgroundColor: buttonBg,
7821
- color: buttonColor,
7822
- border: "none",
7823
- borderRadius: "8px",
7824
- cursor: "pointer",
7825
- display: "flex",
7826
- alignItems: "center",
7827
- justifyContent: "center",
7828
- width: "32px",
7829
- height: "32px",
7830
- transition: "background-color 0.2s",
7831
- backdropFilter: "blur(8px)",
7832
- WebkitBackdropFilter: "blur(8px)",
7833
- boxShadow: isDark ? "0 2px 8px rgba(0, 0, 0, 0.3)" : "0 2px 8px rgba(0, 0, 0, 0.2)",
7834
- position: "relative"
7835
- },
7836
- onMouseEnter: (e) => {
7837
- e.currentTarget.style.backgroundColor = buttonBgHover;
7838
- setIsButtonHovered(true);
7839
- },
7840
- onMouseLeave: (e) => {
7841
- e.currentTarget.style.backgroundColor = buttonBg;
7842
- setIsButtonHovered(false);
7843
- },
7844
- onClick,
7845
- "aria-label": label
7846
- },
7847
- /* @__PURE__ */ import_react3.default.createElement(
7848
- "svg",
7849
- {
7850
- xmlns: "http://www.w3.org/2000/svg",
7851
- width: "16",
7852
- height: "16",
7853
- viewBox: "0 0 24 24",
7854
- fill: "none",
7855
- stroke: "currentColor",
7856
- strokeWidth: "2",
7857
- strokeLinecap: "round",
7858
- strokeLinejoin: "round",
7859
- style: { display: "block" }
7860
- },
7861
- icon
7862
- ),
7863
- showLabels && /* @__PURE__ */ import_react3.default.createElement(
7864
- "span",
7865
- {
7866
- style: {
7867
- ...tooltipStyles,
7868
- opacity: isButtonHovered ? 1 : 0
7869
- }
7870
- },
7871
- label
7872
- )
7873
- );
7874
- }, "IconButton");
7875
- return /* @__PURE__ */ import_react3.default.createElement(
7876
- "div",
7877
- {
7878
- ref: containerRef,
7879
- className,
7880
- style: {
7881
- position: "relative",
7882
- height: "fit-content"
7883
- },
7884
- onMouseEnter: () => !attachTo && setIsHovered(true),
7885
- onMouseLeave: () => !attachTo && setIsHovered(false)
7886
- },
7887
- !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" }))),
7888
- children
7889
7779
  );
7890
- }
7891
- __name(WidgetFullscreenWrapper, "WidgetFullscreenWrapper");
7780
+ (0, import_react5.useEffect)(() => {
7781
+ if (typeof window === "undefined") return;
7782
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
7783
+ const handleChange = /* @__PURE__ */ __name((e) => {
7784
+ setSystemPreference(e.matches ? "dark" : "light");
7785
+ }, "handleChange");
7786
+ mediaQuery.addEventListener("change", handleChange);
7787
+ return () => mediaQuery.removeEventListener("change", handleChange);
7788
+ }, []);
7789
+ const effectiveTheme = isAvailable ? theme : systemPreference;
7790
+ (0, import_react5.useLayoutEffect)(() => {
7791
+ if (typeof document === "undefined") return;
7792
+ if (effectiveTheme === "dark") {
7793
+ document.documentElement.classList.add("dark");
7794
+ } else {
7795
+ document.documentElement.classList.remove("dark");
7796
+ }
7797
+ }, [effectiveTheme]);
7798
+ return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, children);
7799
+ }, "ThemeProvider");
7892
7800
 
7893
- // src/react/WidgetDebugger.tsx
7894
- var import_react4 = __toESM(require("react"), 1);
7895
- function WidgetDebugger({
7801
+ // src/react/WidgetControls.tsx
7802
+ var import_react6 = __toESM(require("react"), 1);
7803
+ function WidgetControls({
7896
7804
  children,
7897
7805
  className = "",
7898
7806
  position = "top-right",
7899
7807
  attachTo,
7900
- showLabels = true
7808
+ showLabels = true,
7809
+ debugger: enableDebugger = false,
7810
+ viewControls = false
7901
7811
  }) {
7902
7812
  const {
7903
7813
  props,
@@ -7917,23 +7827,24 @@ function WidgetDebugger({
7917
7827
  requestDisplayMode,
7918
7828
  setState
7919
7829
  } = useWidget();
7920
- const [isHovered, setIsHovered] = (0, import_react4.useState)(false);
7921
- const [isOverlayOpen, setIsOverlayOpen] = (0, import_react4.useState)(false);
7922
- const containerRef = (0, import_react4.useRef)(null);
7923
- const overlayRef = (0, import_react4.useRef)(null);
7924
- const [windowOpenAiKeys, setWindowOpenAiKeys] = (0, import_react4.useState)([]);
7925
- const [actionResult, setActionResult] = (0, import_react4.useState)("");
7926
- const [toolName, setToolName] = (0, import_react4.useState)("get-my-city");
7927
- const [toolArgs, setToolArgs] = (0, import_react4.useState)("{}");
7928
- const [followUpMessage, setFollowUpMessage] = (0, import_react4.useState)(
7830
+ const [isHovered, setIsHovered] = (0, import_react6.useState)(false);
7831
+ const [isOverlayOpen, setIsOverlayOpen] = (0, import_react6.useState)(false);
7832
+ const containerRef = (0, import_react6.useRef)(null);
7833
+ const overlayRef = (0, import_react6.useRef)(null);
7834
+ const [windowOpenAiKeys, setWindowOpenAiKeys] = (0, import_react6.useState)([]);
7835
+ const [actionResult, setActionResult] = (0, import_react6.useState)("");
7836
+ const [toolName, setToolName] = (0, import_react6.useState)("get-my-city");
7837
+ const [toolArgs, setToolArgs] = (0, import_react6.useState)("{}");
7838
+ const [followUpMessage, setFollowUpMessage] = (0, import_react6.useState)(
7929
7839
  "Test follow-up message"
7930
7840
  );
7931
- const [externalUrl, setExternalUrl] = (0, import_react4.useState)(
7841
+ const [externalUrl, setExternalUrl] = (0, import_react6.useState)(
7932
7842
  "https://docs.mcp-use.com"
7933
7843
  );
7934
7844
  const isFullscreen = displayMode === "fullscreen" && isAvailable;
7935
7845
  const isPip = displayMode === "pip" && isAvailable;
7936
- (0, import_react4.useEffect)(() => {
7846
+ const isDevMode = typeof window !== "undefined" && window.location.pathname.includes("/inspector/api/dev-widget/");
7847
+ (0, import_react6.useEffect)(() => {
7937
7848
  const timeoutId = setTimeout(() => {
7938
7849
  if (typeof window !== "undefined" && window.openai) {
7939
7850
  try {
@@ -7946,75 +7857,88 @@ function WidgetDebugger({
7946
7857
  setWindowOpenAiKeys([]);
7947
7858
  }
7948
7859
  }, 100);
7949
- return () => clearTimeout(timeoutId);
7860
+ return () => {
7861
+ clearTimeout(timeoutId);
7862
+ };
7950
7863
  }, []);
7951
7864
  const isDark = theme === "dark";
7952
- const buttonBg = isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.7)";
7953
- const buttonBgHover = isDark ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.9)";
7954
- const buttonColor = "white";
7955
- const getPositionStyles = /* @__PURE__ */ __name(() => {
7865
+ const getPositionClasses = /* @__PURE__ */ __name(() => {
7866
+ const baseClasses = [
7867
+ "absolute",
7868
+ "z-[1000]",
7869
+ "flex",
7870
+ "gap-2",
7871
+ "transition-opacity",
7872
+ "duration-200",
7873
+ "ease-in-out",
7874
+ isHovered ? "opacity-100" : "opacity-0",
7875
+ isHovered ? "pointer-events-auto" : "pointer-events-none"
7876
+ ];
7877
+ switch (position) {
7878
+ case "top-left":
7879
+ return [...baseClasses, "top-4", "left-4"];
7880
+ case "top-center":
7881
+ return [...baseClasses, "top-4", "left-1/2", "-translate-x-1/2"];
7882
+ case "top-right":
7883
+ return [...baseClasses, "top-4", "right-4"];
7884
+ case "center-left":
7885
+ return [...baseClasses, "top-1/2", "left-4", "-translate-y-1/2"];
7886
+ case "center-right":
7887
+ return [...baseClasses, "top-1/2", "right-4", "-translate-y-1/2"];
7888
+ case "bottom-left":
7889
+ return [...baseClasses, "bottom-4", "left-4"];
7890
+ case "bottom-center":
7891
+ return [...baseClasses, "bottom-4", "left-1/2", "-translate-x-1/2"];
7892
+ case "bottom-right":
7893
+ return [...baseClasses, "bottom-4", "right-4"];
7894
+ default:
7895
+ return [...baseClasses, "top-4", "right-4"];
7896
+ }
7897
+ }, "getPositionClasses");
7898
+ const getPositionOffsetStyles = /* @__PURE__ */ __name(() => {
7956
7899
  const baseOffset = 16;
7957
- const topOffset = safeArea?.insets?.top ? `${Math.max(baseOffset, safeArea.insets.top + 8)}px` : `${baseOffset}px`;
7958
- const rightOffset = safeArea?.insets?.right ? `${Math.max(baseOffset, safeArea.insets.right + 8)}px` : `${baseOffset}px`;
7959
- const bottomOffset = safeArea?.insets?.bottom ? `${Math.max(baseOffset, safeArea.insets.bottom + 8)}px` : `${baseOffset}px`;
7960
- const leftOffset = safeArea?.insets?.left ? `${Math.max(baseOffset, safeArea.insets.left + 8)}px` : `${baseOffset}px`;
7961
- const styles = {
7962
- position: "absolute",
7963
- zIndex: 1e3,
7964
- display: "flex",
7965
- gap: "8px",
7966
- opacity: isHovered ? 1 : 0,
7967
- transition: "opacity 0.2s ease-in-out",
7968
- pointerEvents: isHovered ? "auto" : "none"
7969
- };
7900
+ const topOffset = safeArea?.insets?.top ? Math.max(baseOffset, safeArea.insets.top + 8) : baseOffset;
7901
+ const rightOffset = safeArea?.insets?.right ? Math.max(baseOffset, safeArea.insets.right + 8) : baseOffset;
7902
+ const bottomOffset = safeArea?.insets?.bottom ? Math.max(baseOffset, safeArea.insets.bottom + 8) : baseOffset;
7903
+ const leftOffset = safeArea?.insets?.left ? Math.max(baseOffset, safeArea.insets.left + 8) : baseOffset;
7904
+ const styles = {};
7970
7905
  switch (position) {
7971
7906
  case "top-left":
7972
- styles.top = topOffset;
7973
- styles.left = leftOffset;
7907
+ styles.top = `${topOffset}px`;
7908
+ styles.left = `${leftOffset}px`;
7974
7909
  break;
7975
7910
  case "top-center":
7976
- styles.top = topOffset;
7977
- styles.left = "50%";
7978
- styles.transform = "translateX(-50%)";
7911
+ styles.top = `${topOffset}px`;
7979
7912
  break;
7980
7913
  case "top-right":
7981
- styles.top = topOffset;
7982
- styles.right = rightOffset;
7983
- if (!isFullscreen && !isPip) {
7984
- styles.right = `calc(${rightOffset} + 80px)`;
7985
- }
7914
+ styles.top = `${topOffset}px`;
7915
+ styles.right = `${rightOffset}px`;
7986
7916
  break;
7987
7917
  case "center-left":
7988
- styles.top = "50%";
7989
- styles.left = leftOffset;
7990
- styles.transform = "translateY(-50%)";
7918
+ styles.left = `${leftOffset}px`;
7991
7919
  break;
7992
7920
  case "center-right":
7993
- styles.top = "50%";
7994
- styles.right = rightOffset;
7995
- styles.transform = "translateY(-50%)";
7921
+ styles.right = `${rightOffset}px`;
7996
7922
  break;
7997
7923
  case "bottom-left":
7998
- styles.bottom = bottomOffset;
7999
- styles.left = leftOffset;
7924
+ styles.bottom = `${bottomOffset}px`;
7925
+ styles.left = `${leftOffset}px`;
8000
7926
  break;
8001
7927
  case "bottom-center":
8002
- styles.bottom = bottomOffset;
8003
- styles.left = "50%";
8004
- styles.transform = "translateX(-50%)";
7928
+ styles.bottom = `${bottomOffset}px`;
8005
7929
  break;
8006
7930
  case "bottom-right":
8007
- styles.bottom = bottomOffset;
8008
- styles.right = rightOffset;
7931
+ styles.bottom = `${bottomOffset}px`;
7932
+ styles.right = `${rightOffset}px`;
8009
7933
  break;
8010
7934
  default:
8011
- styles.top = topOffset;
8012
- styles.right = rightOffset;
7935
+ styles.top = `${topOffset}px`;
7936
+ styles.right = `${rightOffset}px`;
8013
7937
  break;
8014
7938
  }
8015
7939
  return styles;
8016
- }, "getPositionStyles");
8017
- (0, import_react4.useEffect)(() => {
7940
+ }, "getPositionOffsetStyles");
7941
+ (0, import_react6.useEffect)(() => {
8018
7942
  if (!attachTo) return;
8019
7943
  const handleMouseEnter = /* @__PURE__ */ __name(() => setIsHovered(true), "handleMouseEnter");
8020
7944
  const handleMouseLeave = /* @__PURE__ */ __name(() => setIsHovered(false), "handleMouseLeave");
@@ -8025,7 +7949,7 @@ function WidgetDebugger({
8025
7949
  attachTo.removeEventListener("mouseleave", handleMouseLeave);
8026
7950
  };
8027
7951
  }, [attachTo]);
8028
- (0, import_react4.useEffect)(() => {
7952
+ (0, import_react6.useEffect)(() => {
8029
7953
  if (!isOverlayOpen) return;
8030
7954
  const handleClickOutside = /* @__PURE__ */ __name((event) => {
8031
7955
  if (overlayRef.current && !overlayRef.current.contains(event.target)) {
@@ -8037,7 +7961,7 @@ function WidgetDebugger({
8037
7961
  document.removeEventListener("mousedown", handleClickOutside);
8038
7962
  };
8039
7963
  }, [isOverlayOpen]);
8040
- (0, import_react4.useEffect)(() => {
7964
+ (0, import_react6.useEffect)(() => {
8041
7965
  if (isOverlayOpen) {
8042
7966
  document.body.style.overflow = "hidden";
8043
7967
  } else {
@@ -8096,128 +8020,97 @@ function WidgetDebugger({
8096
8020
  setActionResult(`Error: ${error.message}`);
8097
8021
  }
8098
8022
  }, "handleSetState");
8099
- const getTooltipStyles = /* @__PURE__ */ __name(() => {
8100
- const baseStyles = {
8101
- position: "absolute",
8102
- padding: "4px 8px",
8103
- backgroundColor: "rgba(0, 0, 0, 0.9)",
8104
- color: "white",
8105
- borderRadius: "4px",
8106
- fontSize: "12px",
8107
- whiteSpace: "nowrap",
8108
- pointerEvents: "none",
8109
- transition: "opacity 0.2s ease-in-out"
8110
- };
8023
+ const handleFullscreen = /* @__PURE__ */ __name(async () => {
8024
+ try {
8025
+ await requestDisplayMode("fullscreen");
8026
+ } catch (error) {
8027
+ console.error("Failed to go fullscreen:", error);
8028
+ }
8029
+ }, "handleFullscreen");
8030
+ const handlePip = /* @__PURE__ */ __name(async () => {
8031
+ try {
8032
+ await requestDisplayMode("pip");
8033
+ } catch (error) {
8034
+ console.error("Failed to go pip:", error);
8035
+ }
8036
+ }, "handlePip");
8037
+ const getTooltipClasses = /* @__PURE__ */ __name(() => {
8038
+ const baseClasses = [
8039
+ "absolute",
8040
+ "px-2",
8041
+ "py-1",
8042
+ "bg-black/90",
8043
+ "text-white",
8044
+ "rounded",
8045
+ "text-xs",
8046
+ "whitespace-nowrap",
8047
+ "pointer-events-none",
8048
+ "transition-opacity",
8049
+ "duration-200",
8050
+ "ease-in-out"
8051
+ ];
8111
8052
  switch (position) {
8112
8053
  case "top-right":
8113
- return {
8114
- ...baseStyles,
8115
- top: "100%",
8116
- right: "0",
8117
- marginTop: "8px"
8118
- };
8054
+ return [...baseClasses, "top-full", "right-0", "mt-2"];
8119
8055
  case "top-left":
8120
- return {
8121
- ...baseStyles,
8122
- top: "100%",
8123
- left: "0",
8124
- marginTop: "8px"
8125
- };
8056
+ return [...baseClasses, "top-full", "left-0", "mt-2"];
8126
8057
  case "top-center":
8127
- return {
8128
- ...baseStyles,
8129
- top: "100%",
8130
- left: "50%",
8131
- transform: "translateX(-50%)",
8132
- marginTop: "8px"
8133
- };
8058
+ return [
8059
+ ...baseClasses,
8060
+ "top-full",
8061
+ "left-1/2",
8062
+ "-translate-x-1/2",
8063
+ "mt-2"
8064
+ ];
8134
8065
  case "bottom-right":
8135
- return {
8136
- ...baseStyles,
8137
- bottom: "100%",
8138
- right: "0",
8139
- marginBottom: "8px"
8140
- };
8066
+ return [...baseClasses, "bottom-full", "right-0", "mb-2"];
8141
8067
  case "bottom-left":
8142
- return {
8143
- ...baseStyles,
8144
- bottom: "100%",
8145
- left: "0",
8146
- marginBottom: "8px"
8147
- };
8068
+ return [...baseClasses, "bottom-full", "left-0", "mb-2"];
8148
8069
  case "bottom-center":
8149
- return {
8150
- ...baseStyles,
8151
- bottom: "100%",
8152
- left: "50%",
8153
- transform: "translateX(-50%)",
8154
- marginBottom: "8px"
8155
- };
8070
+ return [
8071
+ ...baseClasses,
8072
+ "bottom-full",
8073
+ "left-1/2",
8074
+ "-translate-x-1/2",
8075
+ "mb-2"
8076
+ ];
8156
8077
  case "center-left":
8157
- return {
8158
- ...baseStyles,
8159
- left: "100%",
8160
- top: "50%",
8161
- transform: "translateY(-50%)",
8162
- marginLeft: "8px"
8163
- };
8078
+ return [
8079
+ ...baseClasses,
8080
+ "left-full",
8081
+ "top-1/2",
8082
+ "-translate-y-1/2",
8083
+ "ml-2"
8084
+ ];
8164
8085
  case "center-right":
8165
- return {
8166
- ...baseStyles,
8167
- right: "100%",
8168
- top: "50%",
8169
- transform: "translateY(-50%)",
8170
- marginRight: "8px"
8171
- };
8086
+ return [
8087
+ ...baseClasses,
8088
+ "right-full",
8089
+ "top-1/2",
8090
+ "-translate-y-1/2",
8091
+ "mr-2"
8092
+ ];
8172
8093
  default:
8173
- return {
8174
- ...baseStyles,
8175
- top: "100%",
8176
- right: "0",
8177
- marginTop: "8px"
8178
- };
8094
+ return [...baseClasses, "top-full", "right-0", "mt-2"];
8179
8095
  }
8180
- }, "getTooltipStyles");
8096
+ }, "getTooltipClasses");
8181
8097
  const IconButton = /* @__PURE__ */ __name(({
8182
8098
  onClick,
8183
8099
  label,
8184
8100
  children: icon
8185
8101
  }) => {
8186
- const [isButtonHovered, setIsButtonHovered] = (0, import_react4.useState)(false);
8187
- const tooltipStyles = getTooltipStyles();
8188
- return /* @__PURE__ */ import_react4.default.createElement(
8102
+ const [isButtonHovered, setIsButtonHovered] = (0, import_react6.useState)(false);
8103
+ const tooltipClasses = getTooltipClasses();
8104
+ return /* @__PURE__ */ import_react6.default.createElement(
8189
8105
  "button",
8190
8106
  {
8191
- style: {
8192
- padding: "8px",
8193
- backgroundColor: buttonBg,
8194
- color: buttonColor,
8195
- border: "none",
8196
- borderRadius: "8px",
8197
- cursor: "pointer",
8198
- display: "flex",
8199
- alignItems: "center",
8200
- justifyContent: "center",
8201
- width: "32px",
8202
- height: "32px",
8203
- transition: "background-color 0.2s",
8204
- backdropFilter: "blur(8px)",
8205
- WebkitBackdropFilter: "blur(8px)",
8206
- boxShadow: isDark ? "0 2px 8px rgba(0, 0, 0, 0.3)" : "0 2px 8px rgba(0, 0, 0, 0.2)",
8207
- position: "relative"
8208
- },
8209
- onMouseEnter: (e) => {
8210
- e.currentTarget.style.backgroundColor = buttonBgHover;
8211
- setIsButtonHovered(true);
8212
- },
8213
- onMouseLeave: (e) => {
8214
- e.currentTarget.style.backgroundColor = buttonBg;
8215
- setIsButtonHovered(false);
8216
- },
8107
+ 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`,
8108
+ onMouseEnter: () => setIsButtonHovered(true),
8109
+ onMouseLeave: () => setIsButtonHovered(false),
8217
8110
  onClick,
8218
8111
  "aria-label": label
8219
8112
  },
8220
- /* @__PURE__ */ import_react4.default.createElement(
8113
+ /* @__PURE__ */ import_react6.default.createElement(
8221
8114
  "svg",
8222
8115
  {
8223
8116
  xmlns: "http://www.w3.org/2000/svg",
@@ -8229,17 +8122,14 @@ function WidgetDebugger({
8229
8122
  strokeWidth: "2",
8230
8123
  strokeLinecap: "round",
8231
8124
  strokeLinejoin: "round",
8232
- style: { display: "block" }
8125
+ className: "block"
8233
8126
  },
8234
8127
  icon
8235
8128
  ),
8236
- showLabels && /* @__PURE__ */ import_react4.default.createElement(
8129
+ showLabels && /* @__PURE__ */ import_react6.default.createElement(
8237
8130
  "span",
8238
8131
  {
8239
- style: {
8240
- ...tooltipStyles,
8241
- opacity: isButtonHovered ? 1 : 0
8242
- }
8132
+ className: `${tooltipClasses.join(" ")} ${isButtonHovered ? "opacity-100" : "opacity-0"}`
8243
8133
  },
8244
8134
  label
8245
8135
  )
@@ -8266,570 +8156,248 @@ function WidgetDebugger({
8266
8156
  const { top, bottom, left, right } = sa.insets;
8267
8157
  return `T:${top} B:${bottom} L:${left} R:${right}`;
8268
8158
  }, "formatSafeArea");
8269
- return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(
8159
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(
8270
8160
  "div",
8271
8161
  {
8272
8162
  ref: containerRef,
8273
- className,
8274
- style: {
8275
- position: "relative",
8276
- height: "fit-content"
8277
- },
8163
+ className: `${className} relative h-fit`,
8278
8164
  onMouseEnter: () => !attachTo && setIsHovered(true),
8279
8165
  onMouseLeave: () => !attachTo && setIsHovered(false)
8280
8166
  },
8281
- /* @__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" }))),
8167
+ /* @__PURE__ */ import_react6.default.createElement(
8168
+ "div",
8169
+ {
8170
+ className: getPositionClasses().join(" "),
8171
+ style: getPositionOffsetStyles()
8172
+ },
8173
+ !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" })))
8174
+ ),
8282
8175
  children
8283
- ), isOverlayOpen && /* @__PURE__ */ import_react4.default.createElement(
8176
+ ), isOverlayOpen && enableDebugger && /* @__PURE__ */ import_react6.default.createElement(
8284
8177
  "div",
8285
8178
  {
8286
8179
  ref: overlayRef,
8287
- style: {
8288
- position: "fixed",
8289
- top: 0,
8290
- left: 0,
8291
- right: 0,
8292
- bottom: 0,
8293
- backgroundColor: "#000000",
8294
- color: "#ffffff",
8295
- fontFamily: "monospace",
8296
- fontSize: "12px",
8297
- zIndex: 1e4,
8298
- overflow: "auto",
8299
- padding: "16px"
8300
- },
8180
+ className: "fixed inset-0 bg-black text-white font-mono text-xs z-[10000] overflow-auto p-4",
8301
8181
  onClick: (e) => {
8302
8182
  if (e.target === overlayRef.current) {
8303
8183
  setIsOverlayOpen(false);
8304
8184
  }
8305
8185
  }
8306
8186
  },
8307
- /* @__PURE__ */ import_react4.default.createElement(
8187
+ /* @__PURE__ */ import_react6.default.createElement(
8308
8188
  "button",
8309
8189
  {
8310
8190
  onClick: () => setIsOverlayOpen(false),
8311
- style: {
8312
- position: "absolute",
8313
- top: "16px",
8314
- right: "16px",
8315
- backgroundColor: "rgba(255, 255, 255, 0.1)",
8316
- color: "#ffffff",
8317
- border: "none",
8318
- borderRadius: "4px",
8319
- width: "32px",
8320
- height: "32px",
8321
- cursor: "pointer",
8322
- display: "flex",
8323
- alignItems: "center",
8324
- justifyContent: "center",
8325
- fontSize: "18px",
8326
- lineHeight: 1
8327
- },
8191
+ 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",
8328
8192
  "aria-label": "Close"
8329
8193
  },
8330
8194
  "\xD7"
8331
8195
  ),
8332
- /* @__PURE__ */ import_react4.default.createElement(
8333
- "div",
8196
+ /* @__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(
8197
+ "input",
8198
+ {
8199
+ type: "text",
8200
+ value: toolName,
8201
+ onChange: (e) => setToolName(e.target.value),
8202
+ placeholder: "Tool name",
8203
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs w-[150px]"
8204
+ }
8205
+ ), /* @__PURE__ */ import_react6.default.createElement(
8206
+ "input",
8207
+ {
8208
+ type: "text",
8209
+ value: toolArgs,
8210
+ onChange: (e) => setToolArgs(e.target.value),
8211
+ placeholder: '{"key": "value"}',
8212
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
8213
+ }
8214
+ ), /* @__PURE__ */ import_react6.default.createElement(
8215
+ "button",
8334
8216
  {
8335
- style: { maxWidth: "1200px", margin: "0 auto", paddingTop: "40px" }
8217
+ onClick: handleCallTool,
8218
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
8336
8219
  },
8337
- /* @__PURE__ */ import_react4.default.createElement(
8338
- "h1",
8339
- {
8340
- style: {
8341
- fontSize: "18px",
8342
- fontWeight: "bold",
8343
- marginBottom: "16px",
8344
- borderBottom: "1px solid #333",
8345
- paddingBottom: "8px"
8346
- }
8347
- },
8348
- "Debug Info"
8349
- ),
8350
- /* @__PURE__ */ import_react4.default.createElement(
8351
- "table",
8352
- {
8353
- style: {
8354
- width: "100%",
8355
- borderCollapse: "collapse",
8356
- borderSpacing: 0
8357
- }
8358
- },
8359
- /* @__PURE__ */ import_react4.default.createElement("tbody", null, /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8360
- "td",
8361
- {
8362
- style: {
8363
- padding: "8px",
8364
- fontWeight: "bold",
8365
- width: "200px",
8366
- verticalAlign: "top"
8367
- }
8368
- },
8369
- "Props"
8370
- ), /* @__PURE__ */ import_react4.default.createElement(
8371
- "td",
8372
- {
8373
- style: {
8374
- padding: "8px",
8375
- whiteSpace: "pre-wrap",
8376
- wordBreak: "break-all"
8377
- }
8378
- },
8379
- formatValue(props)
8380
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8381
- "td",
8382
- {
8383
- style: {
8384
- padding: "8px",
8385
- fontWeight: "bold",
8386
- width: "200px",
8387
- verticalAlign: "top"
8388
- }
8389
- },
8390
- "Output"
8391
- ), /* @__PURE__ */ import_react4.default.createElement(
8392
- "td",
8393
- {
8394
- style: {
8395
- padding: "8px",
8396
- whiteSpace: "pre-wrap",
8397
- wordBreak: "break-all"
8398
- }
8399
- },
8400
- formatValue(output)
8401
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8402
- "td",
8403
- {
8404
- style: {
8405
- padding: "8px",
8406
- fontWeight: "bold",
8407
- width: "200px",
8408
- verticalAlign: "top"
8409
- }
8410
- },
8411
- "Metadata"
8412
- ), /* @__PURE__ */ import_react4.default.createElement(
8413
- "td",
8414
- {
8415
- style: {
8416
- padding: "8px",
8417
- whiteSpace: "pre-wrap",
8418
- wordBreak: "break-all"
8419
- }
8420
- },
8421
- formatValue(metadata)
8422
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8423
- "td",
8424
- {
8425
- style: {
8426
- padding: "8px",
8427
- fontWeight: "bold",
8428
- width: "200px",
8429
- verticalAlign: "top"
8430
- }
8431
- },
8432
- "State"
8433
- ), /* @__PURE__ */ import_react4.default.createElement(
8434
- "td",
8435
- {
8436
- style: {
8437
- padding: "8px",
8438
- whiteSpace: "pre-wrap",
8439
- wordBreak: "break-all"
8440
- }
8441
- },
8442
- formatValue(state)
8443
- )), /* @__PURE__ */ import_react4.default.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ import_react4.default.createElement(
8444
- "td",
8445
- {
8446
- style: {
8447
- padding: "8px",
8448
- fontWeight: "bold",
8449
- width: "200px",
8450
- verticalAlign: "top"
8451
- }
8452
- },
8453
- "Theme"
8454
- ), /* @__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(
8455
- "td",
8456
- {
8457
- style: {
8458
- padding: "8px",
8459
- fontWeight: "bold",
8460
- width: "200px",
8461
- verticalAlign: "top"
8462
- }
8463
- },
8464
- "Display Mode"
8465
- ), /* @__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(
8466
- "td",
8467
- {
8468
- style: {
8469
- padding: "8px",
8470
- fontWeight: "bold",
8471
- width: "200px",
8472
- verticalAlign: "top"
8473
- }
8474
- },
8475
- "Locale"
8476
- ), /* @__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(
8477
- "td",
8478
- {
8479
- style: {
8480
- padding: "8px",
8481
- fontWeight: "bold",
8482
- width: "200px",
8483
- verticalAlign: "top"
8484
- }
8485
- },
8486
- "Max Height"
8487
- ), /* @__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(
8488
- "td",
8489
- {
8490
- style: {
8491
- padding: "8px",
8492
- fontWeight: "bold",
8493
- width: "200px",
8494
- verticalAlign: "top"
8495
- }
8496
- },
8497
- "User Agent"
8498
- ), /* @__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(
8499
- "td",
8500
- {
8501
- style: {
8502
- padding: "8px",
8503
- fontWeight: "bold",
8504
- width: "200px",
8505
- verticalAlign: "top"
8506
- }
8507
- },
8508
- "Safe Area"
8509
- ), /* @__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(
8510
- "td",
8511
- {
8512
- style: {
8513
- padding: "8px",
8514
- fontWeight: "bold",
8515
- width: "200px",
8516
- verticalAlign: "top"
8517
- }
8518
- },
8519
- "API Available"
8520
- ), /* @__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(
8521
- "td",
8522
- {
8523
- style: {
8524
- padding: "8px",
8525
- fontWeight: "bold",
8526
- width: "200px",
8527
- verticalAlign: "top"
8528
- }
8529
- },
8530
- "window.openai Keys"
8531
- ), /* @__PURE__ */ import_react4.default.createElement("td", { style: { padding: "8px" } }, windowOpenAiKeys.length > 0 ? windowOpenAiKeys.join(", ") : "N/A")))
8532
- ),
8533
- /* @__PURE__ */ import_react4.default.createElement(
8534
- "h2",
8535
- {
8536
- style: {
8537
- fontSize: "16px",
8538
- fontWeight: "bold",
8539
- marginTop: "32px",
8540
- marginBottom: "16px",
8541
- borderBottom: "1px solid #333",
8542
- paddingBottom: "8px"
8543
- }
8544
- },
8545
- "Actions"
8546
- ),
8547
- /* @__PURE__ */ import_react4.default.createElement(
8548
- "div",
8549
- {
8550
- style: { display: "flex", flexDirection: "column", gap: "12px" }
8551
- },
8552
- /* @__PURE__ */ import_react4.default.createElement(
8553
- "div",
8554
- {
8555
- style: { display: "flex", gap: "8px", alignItems: "center" }
8556
- },
8557
- /* @__PURE__ */ import_react4.default.createElement(
8558
- "input",
8559
- {
8560
- type: "text",
8561
- value: toolName,
8562
- onChange: (e) => setToolName(e.target.value),
8563
- placeholder: "Tool name",
8564
- style: {
8565
- padding: "6px 8px",
8566
- backgroundColor: "#1a1a1a",
8567
- color: "#ffffff",
8568
- border: "1px solid #333",
8569
- borderRadius: "4px",
8570
- fontFamily: "monospace",
8571
- fontSize: "12px",
8572
- width: "150px"
8573
- }
8574
- }
8575
- ),
8576
- /* @__PURE__ */ import_react4.default.createElement(
8577
- "input",
8578
- {
8579
- type: "text",
8580
- value: toolArgs,
8581
- onChange: (e) => setToolArgs(e.target.value),
8582
- placeholder: '{"key": "value"}',
8583
- style: {
8584
- padding: "6px 8px",
8585
- backgroundColor: "#1a1a1a",
8586
- color: "#ffffff",
8587
- border: "1px solid #333",
8588
- borderRadius: "4px",
8589
- fontFamily: "monospace",
8590
- fontSize: "12px",
8591
- flex: 1
8592
- }
8593
- }
8594
- ),
8595
- /* @__PURE__ */ import_react4.default.createElement(
8596
- "button",
8597
- {
8598
- onClick: handleCallTool,
8599
- style: {
8600
- padding: "6px 12px",
8601
- backgroundColor: "#333",
8602
- color: "#ffffff",
8603
- border: "1px solid #555",
8604
- borderRadius: "4px",
8605
- cursor: "pointer",
8606
- fontFamily: "monospace",
8607
- fontSize: "12px"
8608
- }
8609
- },
8610
- "Call Tool"
8611
- )
8612
- ),
8613
- /* @__PURE__ */ import_react4.default.createElement(
8614
- "div",
8615
- {
8616
- style: { display: "flex", gap: "8px", alignItems: "center" }
8617
- },
8618
- /* @__PURE__ */ import_react4.default.createElement(
8619
- "input",
8620
- {
8621
- type: "text",
8622
- value: followUpMessage,
8623
- onChange: (e) => setFollowUpMessage(e.target.value),
8624
- placeholder: "Follow-up message",
8625
- style: {
8626
- padding: "6px 8px",
8627
- backgroundColor: "#1a1a1a",
8628
- color: "#ffffff",
8629
- border: "1px solid #333",
8630
- borderRadius: "4px",
8631
- fontFamily: "monospace",
8632
- fontSize: "12px",
8633
- flex: 1
8634
- }
8635
- }
8636
- ),
8637
- /* @__PURE__ */ import_react4.default.createElement(
8638
- "button",
8639
- {
8640
- onClick: handleSendFollowUpMessage,
8641
- style: {
8642
- padding: "6px 12px",
8643
- backgroundColor: "#333",
8644
- color: "#ffffff",
8645
- border: "1px solid #555",
8646
- borderRadius: "4px",
8647
- cursor: "pointer",
8648
- fontFamily: "monospace",
8649
- fontSize: "12px"
8650
- }
8651
- },
8652
- "Send Follow-Up"
8653
- )
8654
- ),
8655
- /* @__PURE__ */ import_react4.default.createElement(
8656
- "div",
8657
- {
8658
- style: { display: "flex", gap: "8px", alignItems: "center" }
8659
- },
8660
- /* @__PURE__ */ import_react4.default.createElement(
8661
- "input",
8662
- {
8663
- type: "text",
8664
- value: externalUrl,
8665
- onChange: (e) => setExternalUrl(e.target.value),
8666
- placeholder: "External URL",
8667
- style: {
8668
- padding: "6px 8px",
8669
- backgroundColor: "#1a1a1a",
8670
- color: "#ffffff",
8671
- border: "1px solid #333",
8672
- borderRadius: "4px",
8673
- fontFamily: "monospace",
8674
- fontSize: "12px",
8675
- flex: 1
8676
- }
8677
- }
8678
- ),
8679
- /* @__PURE__ */ import_react4.default.createElement(
8680
- "button",
8681
- {
8682
- onClick: handleOpenExternal,
8683
- style: {
8684
- padding: "6px 12px",
8685
- backgroundColor: "#333",
8686
- color: "#ffffff",
8687
- border: "1px solid #555",
8688
- borderRadius: "4px",
8689
- cursor: "pointer",
8690
- fontFamily: "monospace",
8691
- fontSize: "12px"
8692
- }
8693
- },
8694
- "Open Link"
8695
- )
8696
- ),
8697
- /* @__PURE__ */ import_react4.default.createElement(
8698
- "div",
8699
- {
8700
- style: { display: "flex", gap: "8px", alignItems: "center" }
8701
- },
8702
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "150px", fontSize: "12px" } }, "Display Mode:"),
8703
- /* @__PURE__ */ import_react4.default.createElement(
8704
- "button",
8705
- {
8706
- onClick: () => handleRequestDisplayMode("inline"),
8707
- style: {
8708
- padding: "6px 12px",
8709
- backgroundColor: "#333",
8710
- color: "#ffffff",
8711
- border: "1px solid #555",
8712
- borderRadius: "4px",
8713
- cursor: "pointer",
8714
- fontFamily: "monospace",
8715
- fontSize: "12px",
8716
- flex: 1
8717
- }
8718
- },
8719
- "Inline"
8720
- ),
8721
- /* @__PURE__ */ import_react4.default.createElement(
8722
- "button",
8723
- {
8724
- onClick: () => handleRequestDisplayMode("pip"),
8725
- style: {
8726
- padding: "6px 12px",
8727
- backgroundColor: "#333",
8728
- color: "#ffffff",
8729
- border: "1px solid #555",
8730
- borderRadius: "4px",
8731
- cursor: "pointer",
8732
- fontFamily: "monospace",
8733
- fontSize: "12px",
8734
- flex: 1
8735
- }
8736
- },
8737
- "PiP"
8738
- ),
8739
- /* @__PURE__ */ import_react4.default.createElement(
8740
- "button",
8741
- {
8742
- onClick: () => handleRequestDisplayMode("fullscreen"),
8743
- style: {
8744
- padding: "6px 12px",
8745
- backgroundColor: "#333",
8746
- color: "#ffffff",
8747
- border: "1px solid #555",
8748
- borderRadius: "4px",
8749
- cursor: "pointer",
8750
- fontFamily: "monospace",
8751
- fontSize: "12px",
8752
- flex: 1
8753
- }
8754
- },
8755
- "Fullscreen"
8756
- )
8757
- ),
8758
- /* @__PURE__ */ import_react4.default.createElement(
8759
- "div",
8760
- {
8761
- style: { display: "flex", gap: "8px", alignItems: "center" }
8762
- },
8763
- /* @__PURE__ */ import_react4.default.createElement(
8764
- "button",
8765
- {
8766
- onClick: handleSetState,
8767
- style: {
8768
- padding: "6px 12px",
8769
- backgroundColor: "#333",
8770
- color: "#ffffff",
8771
- border: "1px solid #555",
8772
- borderRadius: "4px",
8773
- cursor: "pointer",
8774
- fontFamily: "monospace",
8775
- fontSize: "12px"
8776
- }
8777
- },
8778
- "Set State (Add Timestamp)"
8779
- )
8780
- ),
8781
- actionResult && /* @__PURE__ */ import_react4.default.createElement(
8782
- "div",
8783
- {
8784
- style: {
8785
- marginTop: "8px",
8786
- padding: "8px",
8787
- backgroundColor: "#1a1a1a",
8788
- border: "1px solid #333",
8789
- borderRadius: "4px",
8790
- whiteSpace: "pre-wrap",
8791
- wordBreak: "break-all",
8792
- fontSize: "11px",
8793
- maxHeight: "200px",
8794
- overflow: "auto"
8795
- }
8796
- },
8797
- /* @__PURE__ */ import_react4.default.createElement(
8798
- "div",
8799
- {
8800
- style: {
8801
- fontWeight: "bold",
8802
- marginBottom: "4px",
8803
- color: "#aaa"
8804
- }
8805
- },
8806
- "Result:"
8807
- ),
8808
- actionResult,
8809
- /* @__PURE__ */ import_react4.default.createElement(
8810
- "button",
8811
- {
8812
- onClick: () => setActionResult(""),
8813
- style: {
8814
- marginTop: "8px",
8815
- padding: "4px 8px",
8816
- backgroundColor: "#333",
8817
- color: "#ffffff",
8818
- border: "1px solid #555",
8819
- borderRadius: "4px",
8820
- cursor: "pointer",
8821
- fontFamily: "monospace",
8822
- fontSize: "11px"
8823
- }
8824
- },
8825
- "Clear"
8826
- )
8827
- )
8828
- )
8829
- )
8220
+ "Call Tool"
8221
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
8222
+ "input",
8223
+ {
8224
+ type: "text",
8225
+ value: followUpMessage,
8226
+ onChange: (e) => setFollowUpMessage(e.target.value),
8227
+ placeholder: "Follow-up message",
8228
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
8229
+ }
8230
+ ), /* @__PURE__ */ import_react6.default.createElement(
8231
+ "button",
8232
+ {
8233
+ onClick: handleSendFollowUpMessage,
8234
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
8235
+ },
8236
+ "Send Follow-Up"
8237
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
8238
+ "input",
8239
+ {
8240
+ type: "text",
8241
+ value: externalUrl,
8242
+ onChange: (e) => setExternalUrl(e.target.value),
8243
+ placeholder: "External URL",
8244
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
8245
+ }
8246
+ ), /* @__PURE__ */ import_react6.default.createElement(
8247
+ "button",
8248
+ {
8249
+ onClick: handleOpenExternal,
8250
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
8251
+ },
8252
+ "Open Link"
8253
+ )), /* @__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(
8254
+ "button",
8255
+ {
8256
+ onClick: () => handleRequestDisplayMode("inline"),
8257
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
8258
+ },
8259
+ "Inline"
8260
+ ), /* @__PURE__ */ import_react6.default.createElement(
8261
+ "button",
8262
+ {
8263
+ onClick: () => handleRequestDisplayMode("pip"),
8264
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
8265
+ },
8266
+ "PiP"
8267
+ ), /* @__PURE__ */ import_react6.default.createElement(
8268
+ "button",
8269
+ {
8270
+ onClick: () => handleRequestDisplayMode("fullscreen"),
8271
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
8272
+ },
8273
+ "Fullscreen"
8274
+ )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ import_react6.default.createElement(
8275
+ "button",
8276
+ {
8277
+ onClick: handleSetState,
8278
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
8279
+ },
8280
+ "Set State (Add Timestamp)"
8281
+ )), 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(
8282
+ "button",
8283
+ {
8284
+ onClick: () => setActionResult(""),
8285
+ className: "mt-2 py-1 px-2 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-[11px]"
8286
+ },
8287
+ "Clear"
8288
+ ))))
8830
8289
  ));
8831
8290
  }
8832
- __name(WidgetDebugger, "WidgetDebugger");
8291
+ __name(WidgetControls, "WidgetControls");
8292
+
8293
+ // src/react/McpUseProvider.tsx
8294
+ var import_react7 = __toESM(require("react"), 1);
8295
+ var import_react_router_dom = require("react-router-dom");
8296
+ function getBasename() {
8297
+ if (typeof window === "undefined") return "/";
8298
+ const path4 = window.location.pathname;
8299
+ const match = path4.match(/^(\/inspector\/api\/dev-widget\/[^/]+)/);
8300
+ if (match) {
8301
+ return match[1];
8302
+ }
8303
+ return "/";
8304
+ }
8305
+ __name(getBasename, "getBasename");
8306
+ var HEIGHT_DEBOUNCE_MS = 150;
8307
+ var MIN_HEIGHT_CHANGE_PX = 5;
8308
+ function McpUseProvider({
8309
+ children,
8310
+ debugger: enableDebugger = false,
8311
+ viewControls = false,
8312
+ autoSize = false
8313
+ }) {
8314
+ const basename = getBasename();
8315
+ const containerRef = (0, import_react7.useRef)(null);
8316
+ const lastHeightRef = (0, import_react7.useRef)(0);
8317
+ const debounceTimeoutRef = (0, import_react7.useRef)(null);
8318
+ const notificationInProgressRef = (0, import_react7.useRef)(false);
8319
+ const notifyHeight = (0, import_react7.useCallback)((height) => {
8320
+ if (typeof window !== "undefined" && window.openai?.notifyIntrinsicHeight) {
8321
+ notificationInProgressRef.current = true;
8322
+ window.openai.notifyIntrinsicHeight(height).then(() => {
8323
+ notificationInProgressRef.current = false;
8324
+ }).catch((error) => {
8325
+ notificationInProgressRef.current = false;
8326
+ console.error(
8327
+ "[McpUseProvider] Failed to notify intrinsic height:",
8328
+ error
8329
+ );
8330
+ });
8331
+ }
8332
+ }, []);
8333
+ const debouncedNotifyHeight = (0, import_react7.useCallback)(
8334
+ (height) => {
8335
+ if (debounceTimeoutRef.current) {
8336
+ clearTimeout(debounceTimeoutRef.current);
8337
+ }
8338
+ debounceTimeoutRef.current = setTimeout(() => {
8339
+ const heightDiff = Math.abs(height - lastHeightRef.current);
8340
+ if (heightDiff >= MIN_HEIGHT_CHANGE_PX && height > 0) {
8341
+ lastHeightRef.current = height;
8342
+ notifyHeight(height);
8343
+ }
8344
+ }, HEIGHT_DEBOUNCE_MS);
8345
+ },
8346
+ [notifyHeight]
8347
+ );
8348
+ (0, import_react7.useEffect)(() => {
8349
+ if (!autoSize) {
8350
+ return;
8351
+ }
8352
+ const container = containerRef.current;
8353
+ if (!container || typeof ResizeObserver === "undefined") {
8354
+ return;
8355
+ }
8356
+ const observer = new ResizeObserver((entries) => {
8357
+ if (notificationInProgressRef.current) {
8358
+ return;
8359
+ }
8360
+ for (const entry of entries) {
8361
+ const height = entry.contentRect.height;
8362
+ const scrollHeight = entry.target.scrollHeight;
8363
+ const intrinsicHeight = Math.max(height, scrollHeight);
8364
+ debouncedNotifyHeight(intrinsicHeight);
8365
+ }
8366
+ });
8367
+ observer.observe(container);
8368
+ const initialHeight = Math.max(
8369
+ container.offsetHeight,
8370
+ container.scrollHeight
8371
+ );
8372
+ if (initialHeight > 0) {
8373
+ debouncedNotifyHeight(initialHeight);
8374
+ }
8375
+ return () => {
8376
+ observer.disconnect();
8377
+ if (debounceTimeoutRef.current) {
8378
+ clearTimeout(debounceTimeoutRef.current);
8379
+ debounceTimeoutRef.current = null;
8380
+ }
8381
+ notificationInProgressRef.current = false;
8382
+ };
8383
+ }, [autoSize, debouncedNotifyHeight]);
8384
+ let content = children;
8385
+ content = /* @__PURE__ */ import_react7.default.createElement(ErrorBoundary, null, content);
8386
+ if (enableDebugger || viewControls) {
8387
+ content = /* @__PURE__ */ import_react7.default.createElement(WidgetControls, { debugger: enableDebugger, viewControls }, content);
8388
+ }
8389
+ content = /* @__PURE__ */ import_react7.default.createElement(import_react_router_dom.BrowserRouter, { basename }, content);
8390
+ content = /* @__PURE__ */ import_react7.default.createElement(ThemeProvider, null, content);
8391
+ if (autoSize) {
8392
+ const containerStyle = {
8393
+ width: "100%",
8394
+ minHeight: 0
8395
+ };
8396
+ content = /* @__PURE__ */ import_react7.default.createElement("div", { ref: containerRef, style: containerStyle }, content);
8397
+ }
8398
+ return /* @__PURE__ */ import_react7.default.createElement(import_react7.StrictMode, null, content);
8399
+ }
8400
+ __name(McpUseProvider, "McpUseProvider");
8833
8401
 
8834
8402
  // src/client/prompts.ts
8835
8403
  var PROMPTS = {