mcp-use 1.5.0-canary.0 → 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.
@@ -609,6 +609,52 @@ function useMcp(options) {
609
609
  }
610
610
  __name(useMcp, "useMcp");
611
611
 
612
+ // src/react/ErrorBoundary.tsx
613
+ import React from "react";
614
+ var ErrorBoundary = class extends React.Component {
615
+ static {
616
+ __name(this, "ErrorBoundary");
617
+ }
618
+ constructor(props) {
619
+ super(props);
620
+ this.state = { hasError: false, error: null };
621
+ }
622
+ static getDerivedStateFromError(error) {
623
+ return { hasError: true, error };
624
+ }
625
+ componentDidCatch(error, errorInfo) {
626
+ console.error("Widget Error:", error, errorInfo);
627
+ }
628
+ render() {
629
+ if (this.state.hasError) {
630
+ return /* @__PURE__ */ React.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__ */ React.createElement("h3", { className: "font-bold mb-2" }, "Widget Error"), /* @__PURE__ */ React.createElement("pre", { className: "text-sm whitespace-pre-wrap" }, this.state.error?.message));
631
+ }
632
+ return this.props.children;
633
+ }
634
+ };
635
+
636
+ // src/react/Image.tsx
637
+ import React2 from "react";
638
+ var Image = /* @__PURE__ */ __name(({ src, ...props }) => {
639
+ const publicUrl = typeof window !== "undefined" && window.__mcpPublicUrl ? window.__mcpPublicUrl : "";
640
+ const getFinalSrc = /* @__PURE__ */ __name((source) => {
641
+ if (!source) return source;
642
+ if (source.startsWith("http://") || source.startsWith("https://") || source.startsWith("data:")) {
643
+ return source;
644
+ }
645
+ if (!publicUrl) {
646
+ return source;
647
+ }
648
+ const cleanSrc = source.startsWith("/") ? source.slice(1) : source;
649
+ return `${publicUrl}/${cleanSrc}`;
650
+ }, "getFinalSrc");
651
+ const finalSrc = getFinalSrc(src);
652
+ return /* @__PURE__ */ React2.createElement("img", { src: finalSrc, ...props });
653
+ }, "Image");
654
+
655
+ // src/react/ThemeProvider.tsx
656
+ import React3, { useEffect as useEffect3, useLayoutEffect, useState as useState3 } from "react";
657
+
612
658
  // src/react/useWidget.ts
613
659
  import {
614
660
  useCallback as useCallback2,
@@ -687,8 +733,9 @@ function useWidget(defaultProps) {
687
733
  const provider = useMemo(() => {
688
734
  return isOpenAiAvailable ? "openai" : "mcp-ui";
689
735
  }, [isOpenAiAvailable]);
736
+ const searchString = typeof window !== "undefined" ? window.location.search : "";
690
737
  const urlParams = useMemo(() => {
691
- const urlParams2 = new URLSearchParams(window?.location?.search);
738
+ const urlParams2 = new URLSearchParams(searchString);
692
739
  if (urlParams2.has("mcpUseParams")) {
693
740
  return JSON.parse(urlParams2.get("mcpUseParams"));
694
741
  }
@@ -697,7 +744,7 @@ function useWidget(defaultProps) {
697
744
  toolOutput: {},
698
745
  toolId: ""
699
746
  };
700
- }, [window?.location?.search]);
747
+ }, [searchString]);
701
748
  const toolInput = provider === "openai" ? useOpenAiGlobal("toolInput") : urlParams.toolInput;
702
749
  const toolOutput = provider === "openai" ? useOpenAiGlobal("toolOutput") : urlParams.toolOutput;
703
750
  const toolResponseMetadata = useOpenAiGlobal("toolResponseMetadata");
@@ -708,6 +755,12 @@ function useWidget(defaultProps) {
708
755
  const maxHeight = useOpenAiGlobal("maxHeight");
709
756
  const userAgent = useOpenAiGlobal("userAgent");
710
757
  const locale = useOpenAiGlobal("locale");
758
+ const mcp_url = useMemo(() => {
759
+ if (typeof window !== "undefined" && window.__mcpPublicUrl) {
760
+ return window.__mcpPublicUrl.replace(/\/mcp-use\/public$/, "");
761
+ }
762
+ return "";
763
+ }, []);
711
764
  const [localWidgetState, setLocalWidgetState] = useState2(null);
712
765
  useEffect2(() => {
713
766
  if (widgetState !== void 0) {
@@ -749,14 +802,15 @@ function useWidget(defaultProps) {
749
802
  );
750
803
  const setState = useCallback2(
751
804
  async (state) => {
752
- const newState = typeof state === "function" ? state(localWidgetState) : state;
753
805
  if (!window.openai?.setWidgetState) {
754
806
  throw new Error("window.openai.setWidgetState is not available");
755
807
  }
808
+ const currentState = widgetState !== void 0 ? widgetState : localWidgetState;
809
+ const newState = typeof state === "function" ? state(currentState) : state;
756
810
  setLocalWidgetState(newState);
757
811
  return window.openai.setWidgetState(newState);
758
812
  },
759
- [localWidgetState]
813
+ [widgetState, localWidgetState]
760
814
  );
761
815
  return {
762
816
  // Props and state (with defaults)
@@ -775,6 +829,7 @@ function useWidget(defaultProps) {
775
829
  capabilities: { hover: true, touch: false }
776
830
  },
777
831
  locale: locale || "en",
832
+ mcp_url,
778
833
  // Actions
779
834
  callTool,
780
835
  sendFollowUpMessage,
@@ -806,283 +861,49 @@ function useWidgetState(defaultState) {
806
861
  }
807
862
  __name(useWidgetState, "useWidgetState");
808
863
 
809
- // src/react/WidgetFullscreenWrapper.tsx
810
- import React, { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
811
- function WidgetFullscreenWrapper({
812
- children,
813
- className = "",
814
- position = "top-right",
815
- attachTo,
816
- showLabels = true
817
- }) {
818
- const { displayMode, requestDisplayMode, theme, safeArea, isAvailable } = useWidget();
819
- const [isHovered, setIsHovered] = useState3(false);
820
- const containerRef = useRef2(null);
821
- const isFullscreen = displayMode === "fullscreen" && isAvailable;
822
- const isPip = displayMode === "pip" && isAvailable;
823
- const isDark = theme === "dark";
824
- const buttonBg = isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.7)";
825
- const buttonBgHover = isDark ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.9)";
826
- const buttonColor = "white";
827
- const getPositionStyles = /* @__PURE__ */ __name(() => {
828
- const baseOffset = 16;
829
- const topOffset = safeArea?.insets?.top ? `${Math.max(baseOffset, safeArea.insets.top + 8)}px` : `${baseOffset}px`;
830
- const rightOffset = safeArea?.insets?.right ? `${Math.max(baseOffset, safeArea.insets.right + 8)}px` : `${baseOffset}px`;
831
- const bottomOffset = safeArea?.insets?.bottom ? `${Math.max(baseOffset, safeArea.insets.bottom + 8)}px` : `${baseOffset}px`;
832
- const leftOffset = safeArea?.insets?.left ? `${Math.max(baseOffset, safeArea.insets.left + 8)}px` : `${baseOffset}px`;
833
- const styles = {
834
- position: "absolute",
835
- zIndex: 1e3,
836
- display: "flex",
837
- gap: "8px",
838
- opacity: isHovered ? 1 : 0,
839
- transition: "opacity 0.2s ease-in-out",
840
- pointerEvents: isHovered ? "auto" : "none"
841
- };
842
- switch (position) {
843
- case "top-left":
844
- styles.top = topOffset;
845
- styles.left = leftOffset;
846
- break;
847
- case "top-center":
848
- styles.top = topOffset;
849
- styles.left = "50%";
850
- styles.transform = "translateX(-50%)";
851
- break;
852
- case "top-right":
853
- styles.top = topOffset;
854
- styles.right = rightOffset;
855
- break;
856
- case "center-left":
857
- styles.top = "50%";
858
- styles.left = leftOffset;
859
- styles.transform = "translateY(-50%)";
860
- break;
861
- case "center-right":
862
- styles.top = "50%";
863
- styles.right = rightOffset;
864
- styles.transform = "translateY(-50%)";
865
- break;
866
- case "bottom-left":
867
- styles.bottom = bottomOffset;
868
- styles.left = leftOffset;
869
- break;
870
- case "bottom-center":
871
- styles.bottom = bottomOffset;
872
- styles.left = "50%";
873
- styles.transform = "translateX(-50%)";
874
- break;
875
- case "bottom-right":
876
- styles.bottom = bottomOffset;
877
- styles.right = rightOffset;
878
- break;
879
- default:
880
- styles.top = topOffset;
881
- styles.right = rightOffset;
882
- break;
864
+ // src/react/ThemeProvider.tsx
865
+ var ThemeProvider = /* @__PURE__ */ __name(({
866
+ children
867
+ }) => {
868
+ const { theme, isAvailable } = useWidget();
869
+ console.log("theme", theme);
870
+ const [systemPreference, setSystemPreference] = useState3(
871
+ () => {
872
+ if (typeof window === "undefined") return "light";
873
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
883
874
  }
884
- return styles;
885
- }, "getPositionStyles");
875
+ );
886
876
  useEffect3(() => {
887
- if (!attachTo) return;
888
- const handleMouseEnter = /* @__PURE__ */ __name(() => setIsHovered(true), "handleMouseEnter");
889
- const handleMouseLeave = /* @__PURE__ */ __name(() => setIsHovered(false), "handleMouseLeave");
890
- attachTo.addEventListener("mouseenter", handleMouseEnter);
891
- attachTo.addEventListener("mouseleave", handleMouseLeave);
892
- return () => {
893
- attachTo.removeEventListener("mouseenter", handleMouseEnter);
894
- attachTo.removeEventListener("mouseleave", handleMouseLeave);
895
- };
896
- }, [attachTo]);
897
- const handleFullscreen = /* @__PURE__ */ __name(async () => {
898
- try {
899
- await requestDisplayMode("fullscreen");
900
- } catch (error) {
901
- console.error("Failed to go fullscreen:", error);
902
- }
903
- }, "handleFullscreen");
904
- const handlePip = /* @__PURE__ */ __name(async () => {
905
- try {
906
- await requestDisplayMode("pip");
907
- } catch (error) {
908
- console.error("Failed to go pip:", error);
909
- }
910
- }, "handlePip");
911
- const getTooltipStyles = /* @__PURE__ */ __name(() => {
912
- const baseStyles = {
913
- position: "absolute",
914
- padding: "4px 8px",
915
- backgroundColor: isDark ? "rgba(0, 0, 0, 0.9)" : "rgba(0, 0, 0, 0.9)",
916
- color: "white",
917
- borderRadius: "4px",
918
- fontSize: "12px",
919
- whiteSpace: "nowrap",
920
- pointerEvents: "none",
921
- transition: "opacity 0.2s ease-in-out"
922
- };
923
- switch (position) {
924
- case "top-right":
925
- return {
926
- ...baseStyles,
927
- top: "100%",
928
- right: "0",
929
- marginTop: "8px"
930
- };
931
- case "top-left":
932
- return {
933
- ...baseStyles,
934
- top: "100%",
935
- left: "0",
936
- marginTop: "8px"
937
- };
938
- case "top-center":
939
- return {
940
- ...baseStyles,
941
- top: "100%",
942
- left: "50%",
943
- transform: "translateX(-50%)",
944
- marginTop: "8px"
945
- };
946
- case "bottom-right":
947
- return {
948
- ...baseStyles,
949
- bottom: "100%",
950
- right: "0",
951
- marginBottom: "8px"
952
- };
953
- case "bottom-left":
954
- return {
955
- ...baseStyles,
956
- bottom: "100%",
957
- left: "0",
958
- marginBottom: "8px"
959
- };
960
- case "bottom-center":
961
- return {
962
- ...baseStyles,
963
- bottom: "100%",
964
- left: "50%",
965
- transform: "translateX(-50%)",
966
- marginBottom: "8px"
967
- };
968
- case "center-left":
969
- return {
970
- ...baseStyles,
971
- left: "100%",
972
- top: "50%",
973
- transform: "translateY(-50%)",
974
- marginLeft: "8px"
975
- };
976
- case "center-right":
977
- return {
978
- ...baseStyles,
979
- right: "100%",
980
- top: "50%",
981
- transform: "translateY(-50%)",
982
- marginRight: "8px"
983
- };
984
- default:
985
- return {
986
- ...baseStyles,
987
- top: "100%",
988
- right: "0",
989
- marginTop: "8px"
990
- };
877
+ if (typeof window === "undefined") return;
878
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
879
+ const handleChange = /* @__PURE__ */ __name((e) => {
880
+ setSystemPreference(e.matches ? "dark" : "light");
881
+ }, "handleChange");
882
+ mediaQuery.addEventListener("change", handleChange);
883
+ return () => mediaQuery.removeEventListener("change", handleChange);
884
+ }, []);
885
+ const effectiveTheme = isAvailable ? theme : systemPreference;
886
+ useLayoutEffect(() => {
887
+ if (typeof document === "undefined") return;
888
+ if (effectiveTheme === "dark") {
889
+ document.documentElement.classList.add("dark");
890
+ } else {
891
+ document.documentElement.classList.remove("dark");
991
892
  }
992
- }, "getTooltipStyles");
993
- const IconButton = /* @__PURE__ */ __name(({
994
- onClick,
995
- label,
996
- children: icon
997
- }) => {
998
- const [isButtonHovered, setIsButtonHovered] = useState3(false);
999
- const tooltipStyles = getTooltipStyles();
1000
- return /* @__PURE__ */ React.createElement(
1001
- "button",
1002
- {
1003
- style: {
1004
- padding: "8px",
1005
- backgroundColor: buttonBg,
1006
- color: buttonColor,
1007
- border: "none",
1008
- borderRadius: "8px",
1009
- cursor: "pointer",
1010
- display: "flex",
1011
- alignItems: "center",
1012
- justifyContent: "center",
1013
- width: "32px",
1014
- height: "32px",
1015
- transition: "background-color 0.2s",
1016
- backdropFilter: "blur(8px)",
1017
- WebkitBackdropFilter: "blur(8px)",
1018
- boxShadow: isDark ? "0 2px 8px rgba(0, 0, 0, 0.3)" : "0 2px 8px rgba(0, 0, 0, 0.2)",
1019
- position: "relative"
1020
- },
1021
- onMouseEnter: (e) => {
1022
- e.currentTarget.style.backgroundColor = buttonBgHover;
1023
- setIsButtonHovered(true);
1024
- },
1025
- onMouseLeave: (e) => {
1026
- e.currentTarget.style.backgroundColor = buttonBg;
1027
- setIsButtonHovered(false);
1028
- },
1029
- onClick,
1030
- "aria-label": label
1031
- },
1032
- /* @__PURE__ */ React.createElement(
1033
- "svg",
1034
- {
1035
- xmlns: "http://www.w3.org/2000/svg",
1036
- width: "16",
1037
- height: "16",
1038
- viewBox: "0 0 24 24",
1039
- fill: "none",
1040
- stroke: "currentColor",
1041
- strokeWidth: "2",
1042
- strokeLinecap: "round",
1043
- strokeLinejoin: "round",
1044
- style: { display: "block" }
1045
- },
1046
- icon
1047
- ),
1048
- showLabels && /* @__PURE__ */ React.createElement(
1049
- "span",
1050
- {
1051
- style: {
1052
- ...tooltipStyles,
1053
- opacity: isButtonHovered ? 1 : 0
1054
- }
1055
- },
1056
- label
1057
- )
1058
- );
1059
- }, "IconButton");
1060
- return /* @__PURE__ */ React.createElement(
1061
- "div",
1062
- {
1063
- ref: containerRef,
1064
- className,
1065
- style: {
1066
- position: "relative",
1067
- height: "fit-content"
1068
- },
1069
- onMouseEnter: () => !attachTo && setIsHovered(true),
1070
- onMouseLeave: () => !attachTo && setIsHovered(false)
1071
- },
1072
- !isFullscreen && !isPip && /* @__PURE__ */ React.createElement("div", { style: getPositionStyles() }, /* @__PURE__ */ React.createElement(IconButton, { onClick: handleFullscreen, label: "Fullscreen" }, /* @__PURE__ */ React.createElement("path", { d: "M15 3h6v6" }), /* @__PURE__ */ React.createElement("path", { d: "m21 3-7 7" }), /* @__PURE__ */ React.createElement("path", { d: "m3 21 7-7" }), /* @__PURE__ */ React.createElement("path", { d: "M9 21H3v-6" })), /* @__PURE__ */ React.createElement(IconButton, { onClick: handlePip, label: "Picture in Picture" }, /* @__PURE__ */ React.createElement("path", { d: "M21 9V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10c0 1.1.9 2 2 2h4" }), /* @__PURE__ */ React.createElement("rect", { width: "10", height: "7", x: "12", y: "13", rx: "2" }))),
1073
- children
1074
- );
1075
- }
1076
- __name(WidgetFullscreenWrapper, "WidgetFullscreenWrapper");
893
+ }, [effectiveTheme]);
894
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, children);
895
+ }, "ThemeProvider");
1077
896
 
1078
- // src/react/WidgetDebugger.tsx
1079
- import React2, { useEffect as useEffect4, useRef as useRef3, useState as useState4 } from "react";
1080
- function WidgetDebugger({
897
+ // src/react/WidgetControls.tsx
898
+ import React4, { useEffect as useEffect4, useRef as useRef2, useState as useState4 } from "react";
899
+ function WidgetControls({
1081
900
  children,
1082
901
  className = "",
1083
902
  position = "top-right",
1084
903
  attachTo,
1085
- showLabels = true
904
+ showLabels = true,
905
+ debugger: enableDebugger = false,
906
+ viewControls = false
1086
907
  }) {
1087
908
  const {
1088
909
  props,
@@ -1104,8 +925,8 @@ function WidgetDebugger({
1104
925
  } = useWidget();
1105
926
  const [isHovered, setIsHovered] = useState4(false);
1106
927
  const [isOverlayOpen, setIsOverlayOpen] = useState4(false);
1107
- const containerRef = useRef3(null);
1108
- const overlayRef = useRef3(null);
928
+ const containerRef = useRef2(null);
929
+ const overlayRef = useRef2(null);
1109
930
  const [windowOpenAiKeys, setWindowOpenAiKeys] = useState4([]);
1110
931
  const [actionResult, setActionResult] = useState4("");
1111
932
  const [toolName, setToolName] = useState4("get-my-city");
@@ -1118,6 +939,7 @@ function WidgetDebugger({
1118
939
  );
1119
940
  const isFullscreen = displayMode === "fullscreen" && isAvailable;
1120
941
  const isPip = displayMode === "pip" && isAvailable;
942
+ const isDevMode = typeof window !== "undefined" && window.location.pathname.includes("/inspector/api/dev-widget/");
1121
943
  useEffect4(() => {
1122
944
  const timeoutId = setTimeout(() => {
1123
945
  if (typeof window !== "undefined" && window.openai) {
@@ -1131,74 +953,87 @@ function WidgetDebugger({
1131
953
  setWindowOpenAiKeys([]);
1132
954
  }
1133
955
  }, 100);
1134
- return () => clearTimeout(timeoutId);
956
+ return () => {
957
+ clearTimeout(timeoutId);
958
+ };
1135
959
  }, []);
1136
960
  const isDark = theme === "dark";
1137
- const buttonBg = isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.7)";
1138
- const buttonBgHover = isDark ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.9)";
1139
- const buttonColor = "white";
1140
- const getPositionStyles = /* @__PURE__ */ __name(() => {
961
+ const getPositionClasses = /* @__PURE__ */ __name(() => {
962
+ const baseClasses = [
963
+ "absolute",
964
+ "z-[1000]",
965
+ "flex",
966
+ "gap-2",
967
+ "transition-opacity",
968
+ "duration-200",
969
+ "ease-in-out",
970
+ isHovered ? "opacity-100" : "opacity-0",
971
+ isHovered ? "pointer-events-auto" : "pointer-events-none"
972
+ ];
973
+ switch (position) {
974
+ case "top-left":
975
+ return [...baseClasses, "top-4", "left-4"];
976
+ case "top-center":
977
+ return [...baseClasses, "top-4", "left-1/2", "-translate-x-1/2"];
978
+ case "top-right":
979
+ return [...baseClasses, "top-4", "right-4"];
980
+ case "center-left":
981
+ return [...baseClasses, "top-1/2", "left-4", "-translate-y-1/2"];
982
+ case "center-right":
983
+ return [...baseClasses, "top-1/2", "right-4", "-translate-y-1/2"];
984
+ case "bottom-left":
985
+ return [...baseClasses, "bottom-4", "left-4"];
986
+ case "bottom-center":
987
+ return [...baseClasses, "bottom-4", "left-1/2", "-translate-x-1/2"];
988
+ case "bottom-right":
989
+ return [...baseClasses, "bottom-4", "right-4"];
990
+ default:
991
+ return [...baseClasses, "top-4", "right-4"];
992
+ }
993
+ }, "getPositionClasses");
994
+ const getPositionOffsetStyles = /* @__PURE__ */ __name(() => {
1141
995
  const baseOffset = 16;
1142
- const topOffset = safeArea?.insets?.top ? `${Math.max(baseOffset, safeArea.insets.top + 8)}px` : `${baseOffset}px`;
1143
- const rightOffset = safeArea?.insets?.right ? `${Math.max(baseOffset, safeArea.insets.right + 8)}px` : `${baseOffset}px`;
1144
- const bottomOffset = safeArea?.insets?.bottom ? `${Math.max(baseOffset, safeArea.insets.bottom + 8)}px` : `${baseOffset}px`;
1145
- const leftOffset = safeArea?.insets?.left ? `${Math.max(baseOffset, safeArea.insets.left + 8)}px` : `${baseOffset}px`;
1146
- const styles = {
1147
- position: "absolute",
1148
- zIndex: 1e3,
1149
- display: "flex",
1150
- gap: "8px",
1151
- opacity: isHovered ? 1 : 0,
1152
- transition: "opacity 0.2s ease-in-out",
1153
- pointerEvents: isHovered ? "auto" : "none"
1154
- };
996
+ const topOffset = safeArea?.insets?.top ? Math.max(baseOffset, safeArea.insets.top + 8) : baseOffset;
997
+ const rightOffset = safeArea?.insets?.right ? Math.max(baseOffset, safeArea.insets.right + 8) : baseOffset;
998
+ const bottomOffset = safeArea?.insets?.bottom ? Math.max(baseOffset, safeArea.insets.bottom + 8) : baseOffset;
999
+ const leftOffset = safeArea?.insets?.left ? Math.max(baseOffset, safeArea.insets.left + 8) : baseOffset;
1000
+ const styles = {};
1155
1001
  switch (position) {
1156
1002
  case "top-left":
1157
- styles.top = topOffset;
1158
- styles.left = leftOffset;
1003
+ styles.top = `${topOffset}px`;
1004
+ styles.left = `${leftOffset}px`;
1159
1005
  break;
1160
1006
  case "top-center":
1161
- styles.top = topOffset;
1162
- styles.left = "50%";
1163
- styles.transform = "translateX(-50%)";
1007
+ styles.top = `${topOffset}px`;
1164
1008
  break;
1165
1009
  case "top-right":
1166
- styles.top = topOffset;
1167
- styles.right = rightOffset;
1168
- if (!isFullscreen && !isPip) {
1169
- styles.right = `calc(${rightOffset} + 80px)`;
1170
- }
1010
+ styles.top = `${topOffset}px`;
1011
+ styles.right = `${rightOffset}px`;
1171
1012
  break;
1172
1013
  case "center-left":
1173
- styles.top = "50%";
1174
- styles.left = leftOffset;
1175
- styles.transform = "translateY(-50%)";
1014
+ styles.left = `${leftOffset}px`;
1176
1015
  break;
1177
1016
  case "center-right":
1178
- styles.top = "50%";
1179
- styles.right = rightOffset;
1180
- styles.transform = "translateY(-50%)";
1017
+ styles.right = `${rightOffset}px`;
1181
1018
  break;
1182
1019
  case "bottom-left":
1183
- styles.bottom = bottomOffset;
1184
- styles.left = leftOffset;
1020
+ styles.bottom = `${bottomOffset}px`;
1021
+ styles.left = `${leftOffset}px`;
1185
1022
  break;
1186
1023
  case "bottom-center":
1187
- styles.bottom = bottomOffset;
1188
- styles.left = "50%";
1189
- styles.transform = "translateX(-50%)";
1024
+ styles.bottom = `${bottomOffset}px`;
1190
1025
  break;
1191
1026
  case "bottom-right":
1192
- styles.bottom = bottomOffset;
1193
- styles.right = rightOffset;
1027
+ styles.bottom = `${bottomOffset}px`;
1028
+ styles.right = `${rightOffset}px`;
1194
1029
  break;
1195
1030
  default:
1196
- styles.top = topOffset;
1197
- styles.right = rightOffset;
1031
+ styles.top = `${topOffset}px`;
1032
+ styles.right = `${rightOffset}px`;
1198
1033
  break;
1199
1034
  }
1200
1035
  return styles;
1201
- }, "getPositionStyles");
1036
+ }, "getPositionOffsetStyles");
1202
1037
  useEffect4(() => {
1203
1038
  if (!attachTo) return;
1204
1039
  const handleMouseEnter = /* @__PURE__ */ __name(() => setIsHovered(true), "handleMouseEnter");
@@ -1281,128 +1116,97 @@ function WidgetDebugger({
1281
1116
  setActionResult(`Error: ${error.message}`);
1282
1117
  }
1283
1118
  }, "handleSetState");
1284
- const getTooltipStyles = /* @__PURE__ */ __name(() => {
1285
- const baseStyles = {
1286
- position: "absolute",
1287
- padding: "4px 8px",
1288
- backgroundColor: "rgba(0, 0, 0, 0.9)",
1289
- color: "white",
1290
- borderRadius: "4px",
1291
- fontSize: "12px",
1292
- whiteSpace: "nowrap",
1293
- pointerEvents: "none",
1294
- transition: "opacity 0.2s ease-in-out"
1295
- };
1119
+ const handleFullscreen = /* @__PURE__ */ __name(async () => {
1120
+ try {
1121
+ await requestDisplayMode("fullscreen");
1122
+ } catch (error) {
1123
+ console.error("Failed to go fullscreen:", error);
1124
+ }
1125
+ }, "handleFullscreen");
1126
+ const handlePip = /* @__PURE__ */ __name(async () => {
1127
+ try {
1128
+ await requestDisplayMode("pip");
1129
+ } catch (error) {
1130
+ console.error("Failed to go pip:", error);
1131
+ }
1132
+ }, "handlePip");
1133
+ const getTooltipClasses = /* @__PURE__ */ __name(() => {
1134
+ const baseClasses = [
1135
+ "absolute",
1136
+ "px-2",
1137
+ "py-1",
1138
+ "bg-black/90",
1139
+ "text-white",
1140
+ "rounded",
1141
+ "text-xs",
1142
+ "whitespace-nowrap",
1143
+ "pointer-events-none",
1144
+ "transition-opacity",
1145
+ "duration-200",
1146
+ "ease-in-out"
1147
+ ];
1296
1148
  switch (position) {
1297
1149
  case "top-right":
1298
- return {
1299
- ...baseStyles,
1300
- top: "100%",
1301
- right: "0",
1302
- marginTop: "8px"
1303
- };
1150
+ return [...baseClasses, "top-full", "right-0", "mt-2"];
1304
1151
  case "top-left":
1305
- return {
1306
- ...baseStyles,
1307
- top: "100%",
1308
- left: "0",
1309
- marginTop: "8px"
1310
- };
1152
+ return [...baseClasses, "top-full", "left-0", "mt-2"];
1311
1153
  case "top-center":
1312
- return {
1313
- ...baseStyles,
1314
- top: "100%",
1315
- left: "50%",
1316
- transform: "translateX(-50%)",
1317
- marginTop: "8px"
1318
- };
1154
+ return [
1155
+ ...baseClasses,
1156
+ "top-full",
1157
+ "left-1/2",
1158
+ "-translate-x-1/2",
1159
+ "mt-2"
1160
+ ];
1319
1161
  case "bottom-right":
1320
- return {
1321
- ...baseStyles,
1322
- bottom: "100%",
1323
- right: "0",
1324
- marginBottom: "8px"
1325
- };
1162
+ return [...baseClasses, "bottom-full", "right-0", "mb-2"];
1326
1163
  case "bottom-left":
1327
- return {
1328
- ...baseStyles,
1329
- bottom: "100%",
1330
- left: "0",
1331
- marginBottom: "8px"
1332
- };
1164
+ return [...baseClasses, "bottom-full", "left-0", "mb-2"];
1333
1165
  case "bottom-center":
1334
- return {
1335
- ...baseStyles,
1336
- bottom: "100%",
1337
- left: "50%",
1338
- transform: "translateX(-50%)",
1339
- marginBottom: "8px"
1340
- };
1166
+ return [
1167
+ ...baseClasses,
1168
+ "bottom-full",
1169
+ "left-1/2",
1170
+ "-translate-x-1/2",
1171
+ "mb-2"
1172
+ ];
1341
1173
  case "center-left":
1342
- return {
1343
- ...baseStyles,
1344
- left: "100%",
1345
- top: "50%",
1346
- transform: "translateY(-50%)",
1347
- marginLeft: "8px"
1348
- };
1174
+ return [
1175
+ ...baseClasses,
1176
+ "left-full",
1177
+ "top-1/2",
1178
+ "-translate-y-1/2",
1179
+ "ml-2"
1180
+ ];
1349
1181
  case "center-right":
1350
- return {
1351
- ...baseStyles,
1352
- right: "100%",
1353
- top: "50%",
1354
- transform: "translateY(-50%)",
1355
- marginRight: "8px"
1356
- };
1182
+ return [
1183
+ ...baseClasses,
1184
+ "right-full",
1185
+ "top-1/2",
1186
+ "-translate-y-1/2",
1187
+ "mr-2"
1188
+ ];
1357
1189
  default:
1358
- return {
1359
- ...baseStyles,
1360
- top: "100%",
1361
- right: "0",
1362
- marginTop: "8px"
1363
- };
1190
+ return [...baseClasses, "top-full", "right-0", "mt-2"];
1364
1191
  }
1365
- }, "getTooltipStyles");
1192
+ }, "getTooltipClasses");
1366
1193
  const IconButton = /* @__PURE__ */ __name(({
1367
1194
  onClick,
1368
1195
  label,
1369
1196
  children: icon
1370
1197
  }) => {
1371
1198
  const [isButtonHovered, setIsButtonHovered] = useState4(false);
1372
- const tooltipStyles = getTooltipStyles();
1373
- return /* @__PURE__ */ React2.createElement(
1199
+ const tooltipClasses = getTooltipClasses();
1200
+ return /* @__PURE__ */ React4.createElement(
1374
1201
  "button",
1375
1202
  {
1376
- style: {
1377
- padding: "8px",
1378
- backgroundColor: buttonBg,
1379
- color: buttonColor,
1380
- border: "none",
1381
- borderRadius: "8px",
1382
- cursor: "pointer",
1383
- display: "flex",
1384
- alignItems: "center",
1385
- justifyContent: "center",
1386
- width: "32px",
1387
- height: "32px",
1388
- transition: "background-color 0.2s",
1389
- backdropFilter: "blur(8px)",
1390
- WebkitBackdropFilter: "blur(8px)",
1391
- boxShadow: isDark ? "0 2px 8px rgba(0, 0, 0, 0.3)" : "0 2px 8px rgba(0, 0, 0, 0.2)",
1392
- position: "relative"
1393
- },
1394
- onMouseEnter: (e) => {
1395
- e.currentTarget.style.backgroundColor = buttonBgHover;
1396
- setIsButtonHovered(true);
1397
- },
1398
- onMouseLeave: (e) => {
1399
- e.currentTarget.style.backgroundColor = buttonBg;
1400
- setIsButtonHovered(false);
1401
- },
1203
+ 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`,
1204
+ onMouseEnter: () => setIsButtonHovered(true),
1205
+ onMouseLeave: () => setIsButtonHovered(false),
1402
1206
  onClick,
1403
1207
  "aria-label": label
1404
1208
  },
1405
- /* @__PURE__ */ React2.createElement(
1209
+ /* @__PURE__ */ React4.createElement(
1406
1210
  "svg",
1407
1211
  {
1408
1212
  xmlns: "http://www.w3.org/2000/svg",
@@ -1414,17 +1218,14 @@ function WidgetDebugger({
1414
1218
  strokeWidth: "2",
1415
1219
  strokeLinecap: "round",
1416
1220
  strokeLinejoin: "round",
1417
- style: { display: "block" }
1221
+ className: "block"
1418
1222
  },
1419
1223
  icon
1420
1224
  ),
1421
- showLabels && /* @__PURE__ */ React2.createElement(
1225
+ showLabels && /* @__PURE__ */ React4.createElement(
1422
1226
  "span",
1423
1227
  {
1424
- style: {
1425
- ...tooltipStyles,
1426
- opacity: isButtonHovered ? 1 : 0
1427
- }
1228
+ className: `${tooltipClasses.join(" ")} ${isButtonHovered ? "opacity-100" : "opacity-0"}`
1428
1229
  },
1429
1230
  label
1430
1231
  )
@@ -1451,577 +1252,258 @@ function WidgetDebugger({
1451
1252
  const { top, bottom, left, right } = sa.insets;
1452
1253
  return `T:${top} B:${bottom} L:${left} R:${right}`;
1453
1254
  }, "formatSafeArea");
1454
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
1255
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(
1455
1256
  "div",
1456
1257
  {
1457
1258
  ref: containerRef,
1458
- className,
1459
- style: {
1460
- position: "relative",
1461
- height: "fit-content"
1462
- },
1259
+ className: `${className} relative h-fit`,
1463
1260
  onMouseEnter: () => !attachTo && setIsHovered(true),
1464
1261
  onMouseLeave: () => !attachTo && setIsHovered(false)
1465
1262
  },
1466
- /* @__PURE__ */ React2.createElement("div", { style: getPositionStyles() }, /* @__PURE__ */ React2.createElement(IconButton, { onClick: handleToggleOverlay, label: "Debug Info" }, /* @__PURE__ */ React2.createElement("path", { d: "M12 20v-9" }), /* @__PURE__ */ React2.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__ */ React2.createElement("path", { d: "M14.12 3.88 16 2" }), /* @__PURE__ */ React2.createElement("path", { d: "M21 21a4 4 0 0 0-3.81-4" }), /* @__PURE__ */ React2.createElement("path", { d: "M21 5a4 4 0 0 1-3.55 3.97" }), /* @__PURE__ */ React2.createElement("path", { d: "M22 13h-4" }), /* @__PURE__ */ React2.createElement("path", { d: "M3 21a4 4 0 0 1 3.81-4" }), /* @__PURE__ */ React2.createElement("path", { d: "M3 5a4 4 0 0 0 3.55 3.97" }), /* @__PURE__ */ React2.createElement("path", { d: "M6 13H2" }), /* @__PURE__ */ React2.createElement("path", { d: "m8 2 1.88 1.88" }), /* @__PURE__ */ React2.createElement("path", { d: "M9 7.13V6a3 3 0 1 1 6 0v1.13" }))),
1263
+ /* @__PURE__ */ React4.createElement(
1264
+ "div",
1265
+ {
1266
+ className: getPositionClasses().join(" "),
1267
+ style: getPositionOffsetStyles()
1268
+ },
1269
+ !isDevMode && /* @__PURE__ */ React4.createElement(React4.Fragment, null, !isFullscreen && !isPip && /* @__PURE__ */ React4.createElement(React4.Fragment, null, (viewControls === true || viewControls === "fullscreen") && /* @__PURE__ */ React4.createElement(IconButton, { onClick: handleFullscreen, label: "Fullscreen" }, /* @__PURE__ */ React4.createElement("path", { d: "M15 3h6v6" }), /* @__PURE__ */ React4.createElement("path", { d: "m21 3-7 7" }), /* @__PURE__ */ React4.createElement("path", { d: "m3 21 7-7" }), /* @__PURE__ */ React4.createElement("path", { d: "M9 21H3v-6" })), (viewControls === true || viewControls === "pip") && /* @__PURE__ */ React4.createElement(IconButton, { onClick: handlePip, label: "Picture in Picture" }, /* @__PURE__ */ React4.createElement("path", { d: "M21 9V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10c0 1.1.9 2 2 2h4" }), /* @__PURE__ */ React4.createElement("rect", { width: "10", height: "7", x: "12", y: "13", rx: "2" }))), enableDebugger && /* @__PURE__ */ React4.createElement(IconButton, { onClick: handleToggleOverlay, label: "Debug Info" }, /* @__PURE__ */ React4.createElement("path", { d: "M12 20v-9" }), /* @__PURE__ */ React4.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__ */ React4.createElement("path", { d: "M14.12 3.88 16 2" }), /* @__PURE__ */ React4.createElement("path", { d: "M21 21a4 4 0 0 0-3.81-4" }), /* @__PURE__ */ React4.createElement("path", { d: "M21 5a4 4 0 0 1-3.55 3.97" }), /* @__PURE__ */ React4.createElement("path", { d: "M22 13h-4" }), /* @__PURE__ */ React4.createElement("path", { d: "M3 21a4 4 0 0 1 3.81-4" }), /* @__PURE__ */ React4.createElement("path", { d: "M3 5a4 4 0 0 0 3.55 3.97" }), /* @__PURE__ */ React4.createElement("path", { d: "M6 13H2" }), /* @__PURE__ */ React4.createElement("path", { d: "m8 2 1.88 1.88" }), /* @__PURE__ */ React4.createElement("path", { d: "M9 7.13V6a3 3 0 1 1 6 0v1.13" })))
1270
+ ),
1467
1271
  children
1468
- ), isOverlayOpen && /* @__PURE__ */ React2.createElement(
1272
+ ), isOverlayOpen && enableDebugger && /* @__PURE__ */ React4.createElement(
1469
1273
  "div",
1470
1274
  {
1471
1275
  ref: overlayRef,
1472
- style: {
1473
- position: "fixed",
1474
- top: 0,
1475
- left: 0,
1476
- right: 0,
1477
- bottom: 0,
1478
- backgroundColor: "#000000",
1479
- color: "#ffffff",
1480
- fontFamily: "monospace",
1481
- fontSize: "12px",
1482
- zIndex: 1e4,
1483
- overflow: "auto",
1484
- padding: "16px"
1485
- },
1276
+ className: "fixed inset-0 bg-black text-white font-mono text-xs z-[10000] overflow-auto p-4",
1486
1277
  onClick: (e) => {
1487
1278
  if (e.target === overlayRef.current) {
1488
1279
  setIsOverlayOpen(false);
1489
1280
  }
1490
1281
  }
1491
1282
  },
1492
- /* @__PURE__ */ React2.createElement(
1283
+ /* @__PURE__ */ React4.createElement(
1493
1284
  "button",
1494
1285
  {
1495
1286
  onClick: () => setIsOverlayOpen(false),
1496
- style: {
1497
- position: "absolute",
1498
- top: "16px",
1499
- right: "16px",
1500
- backgroundColor: "rgba(255, 255, 255, 0.1)",
1501
- color: "#ffffff",
1502
- border: "none",
1503
- borderRadius: "4px",
1504
- width: "32px",
1505
- height: "32px",
1506
- cursor: "pointer",
1507
- display: "flex",
1508
- alignItems: "center",
1509
- justifyContent: "center",
1510
- fontSize: "18px",
1511
- lineHeight: 1
1512
- },
1287
+ 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",
1513
1288
  "aria-label": "Close"
1514
1289
  },
1515
1290
  "\xD7"
1516
1291
  ),
1517
- /* @__PURE__ */ React2.createElement(
1518
- "div",
1292
+ /* @__PURE__ */ React4.createElement("div", { className: "max-w-[1200px] mx-auto pt-10" }, /* @__PURE__ */ React4.createElement("h1", { className: "text-lg font-bold mb-4 border-b border-gray-700 pb-2" }, "Debug Info"), /* @__PURE__ */ React4.createElement("table", { className: "w-full border-collapse border-spacing-0" }, /* @__PURE__ */ React4.createElement("tbody", null, /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Props"), /* @__PURE__ */ React4.createElement("td", { className: "p-2 whitespace-pre-wrap break-all" }, formatValue(props))), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Output"), /* @__PURE__ */ React4.createElement("td", { className: "p-2 whitespace-pre-wrap break-all" }, formatValue(output))), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Metadata"), /* @__PURE__ */ React4.createElement("td", { className: "p-2 whitespace-pre-wrap break-all" }, formatValue(metadata))), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "State"), /* @__PURE__ */ React4.createElement("td", { className: "p-2 whitespace-pre-wrap break-all" }, formatValue(state))), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Theme"), /* @__PURE__ */ React4.createElement("td", { className: "p-2" }, theme)), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Display Mode"), /* @__PURE__ */ React4.createElement("td", { className: "p-2" }, displayMode)), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Locale"), /* @__PURE__ */ React4.createElement("td", { className: "p-2" }, locale)), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Max Height"), /* @__PURE__ */ React4.createElement("td", { className: "p-2" }, maxHeight, "px")), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "User Agent"), /* @__PURE__ */ React4.createElement("td", { className: "p-2" }, formatUserAgent(userAgent))), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "Safe Area"), /* @__PURE__ */ React4.createElement("td", { className: "p-2" }, formatSafeArea(safeArea))), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "API Available"), /* @__PURE__ */ React4.createElement("td", { className: "p-2" }, isAvailable ? "Yes" : "No")), /* @__PURE__ */ React4.createElement("tr", { className: "border-b border-gray-700" }, /* @__PURE__ */ React4.createElement("td", { className: "p-2 font-bold w-[200px] align-top" }, "window.openai Keys"), /* @__PURE__ */ React4.createElement("td", { className: "p-2" }, windowOpenAiKeys.length > 0 ? windowOpenAiKeys.join(", ") : "N/A")))), /* @__PURE__ */ React4.createElement("h2", { className: "text-base font-bold mt-8 mb-4 border-b border-gray-700 pb-2" }, "Actions"), /* @__PURE__ */ React4.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React4.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ React4.createElement(
1293
+ "input",
1519
1294
  {
1520
- style: { maxWidth: "1200px", margin: "0 auto", paddingTop: "40px" }
1295
+ type: "text",
1296
+ value: toolName,
1297
+ onChange: (e) => setToolName(e.target.value),
1298
+ placeholder: "Tool name",
1299
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs w-[150px]"
1300
+ }
1301
+ ), /* @__PURE__ */ React4.createElement(
1302
+ "input",
1303
+ {
1304
+ type: "text",
1305
+ value: toolArgs,
1306
+ onChange: (e) => setToolArgs(e.target.value),
1307
+ placeholder: '{"key": "value"}',
1308
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
1309
+ }
1310
+ ), /* @__PURE__ */ React4.createElement(
1311
+ "button",
1312
+ {
1313
+ onClick: handleCallTool,
1314
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
1521
1315
  },
1522
- /* @__PURE__ */ React2.createElement(
1523
- "h1",
1524
- {
1525
- style: {
1526
- fontSize: "18px",
1527
- fontWeight: "bold",
1528
- marginBottom: "16px",
1529
- borderBottom: "1px solid #333",
1530
- paddingBottom: "8px"
1531
- }
1532
- },
1533
- "Debug Info"
1534
- ),
1535
- /* @__PURE__ */ React2.createElement(
1536
- "table",
1537
- {
1538
- style: {
1539
- width: "100%",
1540
- borderCollapse: "collapse",
1541
- borderSpacing: 0
1542
- }
1543
- },
1544
- /* @__PURE__ */ React2.createElement("tbody", null, /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1545
- "td",
1546
- {
1547
- style: {
1548
- padding: "8px",
1549
- fontWeight: "bold",
1550
- width: "200px",
1551
- verticalAlign: "top"
1552
- }
1553
- },
1554
- "Props"
1555
- ), /* @__PURE__ */ React2.createElement(
1556
- "td",
1557
- {
1558
- style: {
1559
- padding: "8px",
1560
- whiteSpace: "pre-wrap",
1561
- wordBreak: "break-all"
1562
- }
1563
- },
1564
- formatValue(props)
1565
- )), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1566
- "td",
1567
- {
1568
- style: {
1569
- padding: "8px",
1570
- fontWeight: "bold",
1571
- width: "200px",
1572
- verticalAlign: "top"
1573
- }
1574
- },
1575
- "Output"
1576
- ), /* @__PURE__ */ React2.createElement(
1577
- "td",
1578
- {
1579
- style: {
1580
- padding: "8px",
1581
- whiteSpace: "pre-wrap",
1582
- wordBreak: "break-all"
1583
- }
1584
- },
1585
- formatValue(output)
1586
- )), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1587
- "td",
1588
- {
1589
- style: {
1590
- padding: "8px",
1591
- fontWeight: "bold",
1592
- width: "200px",
1593
- verticalAlign: "top"
1594
- }
1595
- },
1596
- "Metadata"
1597
- ), /* @__PURE__ */ React2.createElement(
1598
- "td",
1599
- {
1600
- style: {
1601
- padding: "8px",
1602
- whiteSpace: "pre-wrap",
1603
- wordBreak: "break-all"
1604
- }
1605
- },
1606
- formatValue(metadata)
1607
- )), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1608
- "td",
1609
- {
1610
- style: {
1611
- padding: "8px",
1612
- fontWeight: "bold",
1613
- width: "200px",
1614
- verticalAlign: "top"
1615
- }
1616
- },
1617
- "State"
1618
- ), /* @__PURE__ */ React2.createElement(
1619
- "td",
1620
- {
1621
- style: {
1622
- padding: "8px",
1623
- whiteSpace: "pre-wrap",
1624
- wordBreak: "break-all"
1625
- }
1626
- },
1627
- formatValue(state)
1628
- )), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1629
- "td",
1630
- {
1631
- style: {
1632
- padding: "8px",
1633
- fontWeight: "bold",
1634
- width: "200px",
1635
- verticalAlign: "top"
1636
- }
1637
- },
1638
- "Theme"
1639
- ), /* @__PURE__ */ React2.createElement("td", { style: { padding: "8px" } }, theme)), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1640
- "td",
1641
- {
1642
- style: {
1643
- padding: "8px",
1644
- fontWeight: "bold",
1645
- width: "200px",
1646
- verticalAlign: "top"
1647
- }
1648
- },
1649
- "Display Mode"
1650
- ), /* @__PURE__ */ React2.createElement("td", { style: { padding: "8px" } }, displayMode)), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1651
- "td",
1652
- {
1653
- style: {
1654
- padding: "8px",
1655
- fontWeight: "bold",
1656
- width: "200px",
1657
- verticalAlign: "top"
1658
- }
1659
- },
1660
- "Locale"
1661
- ), /* @__PURE__ */ React2.createElement("td", { style: { padding: "8px" } }, locale)), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1662
- "td",
1663
- {
1664
- style: {
1665
- padding: "8px",
1666
- fontWeight: "bold",
1667
- width: "200px",
1668
- verticalAlign: "top"
1669
- }
1670
- },
1671
- "Max Height"
1672
- ), /* @__PURE__ */ React2.createElement("td", { style: { padding: "8px" } }, maxHeight, "px")), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1673
- "td",
1674
- {
1675
- style: {
1676
- padding: "8px",
1677
- fontWeight: "bold",
1678
- width: "200px",
1679
- verticalAlign: "top"
1680
- }
1681
- },
1682
- "User Agent"
1683
- ), /* @__PURE__ */ React2.createElement("td", { style: { padding: "8px" } }, formatUserAgent(userAgent))), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1684
- "td",
1685
- {
1686
- style: {
1687
- padding: "8px",
1688
- fontWeight: "bold",
1689
- width: "200px",
1690
- verticalAlign: "top"
1691
- }
1692
- },
1693
- "Safe Area"
1694
- ), /* @__PURE__ */ React2.createElement("td", { style: { padding: "8px" } }, formatSafeArea(safeArea))), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1695
- "td",
1696
- {
1697
- style: {
1698
- padding: "8px",
1699
- fontWeight: "bold",
1700
- width: "200px",
1701
- verticalAlign: "top"
1702
- }
1703
- },
1704
- "API Available"
1705
- ), /* @__PURE__ */ React2.createElement("td", { style: { padding: "8px" } }, isAvailable ? "Yes" : "No")), /* @__PURE__ */ React2.createElement("tr", { style: { borderBottom: "1px solid #333" } }, /* @__PURE__ */ React2.createElement(
1706
- "td",
1707
- {
1708
- style: {
1709
- padding: "8px",
1710
- fontWeight: "bold",
1711
- width: "200px",
1712
- verticalAlign: "top"
1713
- }
1714
- },
1715
- "window.openai Keys"
1716
- ), /* @__PURE__ */ React2.createElement("td", { style: { padding: "8px" } }, windowOpenAiKeys.length > 0 ? windowOpenAiKeys.join(", ") : "N/A")))
1717
- ),
1718
- /* @__PURE__ */ React2.createElement(
1719
- "h2",
1720
- {
1721
- style: {
1722
- fontSize: "16px",
1723
- fontWeight: "bold",
1724
- marginTop: "32px",
1725
- marginBottom: "16px",
1726
- borderBottom: "1px solid #333",
1727
- paddingBottom: "8px"
1728
- }
1729
- },
1730
- "Actions"
1731
- ),
1732
- /* @__PURE__ */ React2.createElement(
1733
- "div",
1734
- {
1735
- style: { display: "flex", flexDirection: "column", gap: "12px" }
1736
- },
1737
- /* @__PURE__ */ React2.createElement(
1738
- "div",
1739
- {
1740
- style: { display: "flex", gap: "8px", alignItems: "center" }
1741
- },
1742
- /* @__PURE__ */ React2.createElement(
1743
- "input",
1744
- {
1745
- type: "text",
1746
- value: toolName,
1747
- onChange: (e) => setToolName(e.target.value),
1748
- placeholder: "Tool name",
1749
- style: {
1750
- padding: "6px 8px",
1751
- backgroundColor: "#1a1a1a",
1752
- color: "#ffffff",
1753
- border: "1px solid #333",
1754
- borderRadius: "4px",
1755
- fontFamily: "monospace",
1756
- fontSize: "12px",
1757
- width: "150px"
1758
- }
1759
- }
1760
- ),
1761
- /* @__PURE__ */ React2.createElement(
1762
- "input",
1763
- {
1764
- type: "text",
1765
- value: toolArgs,
1766
- onChange: (e) => setToolArgs(e.target.value),
1767
- placeholder: '{"key": "value"}',
1768
- style: {
1769
- padding: "6px 8px",
1770
- backgroundColor: "#1a1a1a",
1771
- color: "#ffffff",
1772
- border: "1px solid #333",
1773
- borderRadius: "4px",
1774
- fontFamily: "monospace",
1775
- fontSize: "12px",
1776
- flex: 1
1777
- }
1778
- }
1779
- ),
1780
- /* @__PURE__ */ React2.createElement(
1781
- "button",
1782
- {
1783
- onClick: handleCallTool,
1784
- style: {
1785
- padding: "6px 12px",
1786
- backgroundColor: "#333",
1787
- color: "#ffffff",
1788
- border: "1px solid #555",
1789
- borderRadius: "4px",
1790
- cursor: "pointer",
1791
- fontFamily: "monospace",
1792
- fontSize: "12px"
1793
- }
1794
- },
1795
- "Call Tool"
1796
- )
1797
- ),
1798
- /* @__PURE__ */ React2.createElement(
1799
- "div",
1800
- {
1801
- style: { display: "flex", gap: "8px", alignItems: "center" }
1802
- },
1803
- /* @__PURE__ */ React2.createElement(
1804
- "input",
1805
- {
1806
- type: "text",
1807
- value: followUpMessage,
1808
- onChange: (e) => setFollowUpMessage(e.target.value),
1809
- placeholder: "Follow-up message",
1810
- style: {
1811
- padding: "6px 8px",
1812
- backgroundColor: "#1a1a1a",
1813
- color: "#ffffff",
1814
- border: "1px solid #333",
1815
- borderRadius: "4px",
1816
- fontFamily: "monospace",
1817
- fontSize: "12px",
1818
- flex: 1
1819
- }
1820
- }
1821
- ),
1822
- /* @__PURE__ */ React2.createElement(
1823
- "button",
1824
- {
1825
- onClick: handleSendFollowUpMessage,
1826
- style: {
1827
- padding: "6px 12px",
1828
- backgroundColor: "#333",
1829
- color: "#ffffff",
1830
- border: "1px solid #555",
1831
- borderRadius: "4px",
1832
- cursor: "pointer",
1833
- fontFamily: "monospace",
1834
- fontSize: "12px"
1835
- }
1836
- },
1837
- "Send Follow-Up"
1838
- )
1839
- ),
1840
- /* @__PURE__ */ React2.createElement(
1841
- "div",
1842
- {
1843
- style: { display: "flex", gap: "8px", alignItems: "center" }
1844
- },
1845
- /* @__PURE__ */ React2.createElement(
1846
- "input",
1847
- {
1848
- type: "text",
1849
- value: externalUrl,
1850
- onChange: (e) => setExternalUrl(e.target.value),
1851
- placeholder: "External URL",
1852
- style: {
1853
- padding: "6px 8px",
1854
- backgroundColor: "#1a1a1a",
1855
- color: "#ffffff",
1856
- border: "1px solid #333",
1857
- borderRadius: "4px",
1858
- fontFamily: "monospace",
1859
- fontSize: "12px",
1860
- flex: 1
1861
- }
1862
- }
1863
- ),
1864
- /* @__PURE__ */ React2.createElement(
1865
- "button",
1866
- {
1867
- onClick: handleOpenExternal,
1868
- style: {
1869
- padding: "6px 12px",
1870
- backgroundColor: "#333",
1871
- color: "#ffffff",
1872
- border: "1px solid #555",
1873
- borderRadius: "4px",
1874
- cursor: "pointer",
1875
- fontFamily: "monospace",
1876
- fontSize: "12px"
1877
- }
1878
- },
1879
- "Open Link"
1880
- )
1881
- ),
1882
- /* @__PURE__ */ React2.createElement(
1883
- "div",
1884
- {
1885
- style: { display: "flex", gap: "8px", alignItems: "center" }
1886
- },
1887
- /* @__PURE__ */ React2.createElement("span", { style: { width: "150px", fontSize: "12px" } }, "Display Mode:"),
1888
- /* @__PURE__ */ React2.createElement(
1889
- "button",
1890
- {
1891
- onClick: () => handleRequestDisplayMode("inline"),
1892
- style: {
1893
- padding: "6px 12px",
1894
- backgroundColor: "#333",
1895
- color: "#ffffff",
1896
- border: "1px solid #555",
1897
- borderRadius: "4px",
1898
- cursor: "pointer",
1899
- fontFamily: "monospace",
1900
- fontSize: "12px",
1901
- flex: 1
1902
- }
1903
- },
1904
- "Inline"
1905
- ),
1906
- /* @__PURE__ */ React2.createElement(
1907
- "button",
1908
- {
1909
- onClick: () => handleRequestDisplayMode("pip"),
1910
- style: {
1911
- padding: "6px 12px",
1912
- backgroundColor: "#333",
1913
- color: "#ffffff",
1914
- border: "1px solid #555",
1915
- borderRadius: "4px",
1916
- cursor: "pointer",
1917
- fontFamily: "monospace",
1918
- fontSize: "12px",
1919
- flex: 1
1920
- }
1921
- },
1922
- "PiP"
1923
- ),
1924
- /* @__PURE__ */ React2.createElement(
1925
- "button",
1926
- {
1927
- onClick: () => handleRequestDisplayMode("fullscreen"),
1928
- style: {
1929
- padding: "6px 12px",
1930
- backgroundColor: "#333",
1931
- color: "#ffffff",
1932
- border: "1px solid #555",
1933
- borderRadius: "4px",
1934
- cursor: "pointer",
1935
- fontFamily: "monospace",
1936
- fontSize: "12px",
1937
- flex: 1
1938
- }
1939
- },
1940
- "Fullscreen"
1941
- )
1942
- ),
1943
- /* @__PURE__ */ React2.createElement(
1944
- "div",
1945
- {
1946
- style: { display: "flex", gap: "8px", alignItems: "center" }
1947
- },
1948
- /* @__PURE__ */ React2.createElement(
1949
- "button",
1950
- {
1951
- onClick: handleSetState,
1952
- style: {
1953
- padding: "6px 12px",
1954
- backgroundColor: "#333",
1955
- color: "#ffffff",
1956
- border: "1px solid #555",
1957
- borderRadius: "4px",
1958
- cursor: "pointer",
1959
- fontFamily: "monospace",
1960
- fontSize: "12px"
1961
- }
1962
- },
1963
- "Set State (Add Timestamp)"
1964
- )
1965
- ),
1966
- actionResult && /* @__PURE__ */ React2.createElement(
1967
- "div",
1968
- {
1969
- style: {
1970
- marginTop: "8px",
1971
- padding: "8px",
1972
- backgroundColor: "#1a1a1a",
1973
- border: "1px solid #333",
1974
- borderRadius: "4px",
1975
- whiteSpace: "pre-wrap",
1976
- wordBreak: "break-all",
1977
- fontSize: "11px",
1978
- maxHeight: "200px",
1979
- overflow: "auto"
1980
- }
1981
- },
1982
- /* @__PURE__ */ React2.createElement(
1983
- "div",
1984
- {
1985
- style: {
1986
- fontWeight: "bold",
1987
- marginBottom: "4px",
1988
- color: "#aaa"
1989
- }
1990
- },
1991
- "Result:"
1992
- ),
1993
- actionResult,
1994
- /* @__PURE__ */ React2.createElement(
1995
- "button",
1996
- {
1997
- onClick: () => setActionResult(""),
1998
- style: {
1999
- marginTop: "8px",
2000
- padding: "4px 8px",
2001
- backgroundColor: "#333",
2002
- color: "#ffffff",
2003
- border: "1px solid #555",
2004
- borderRadius: "4px",
2005
- cursor: "pointer",
2006
- fontFamily: "monospace",
2007
- fontSize: "11px"
2008
- }
2009
- },
2010
- "Clear"
2011
- )
2012
- )
2013
- )
2014
- )
1316
+ "Call Tool"
1317
+ )), /* @__PURE__ */ React4.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ React4.createElement(
1318
+ "input",
1319
+ {
1320
+ type: "text",
1321
+ value: followUpMessage,
1322
+ onChange: (e) => setFollowUpMessage(e.target.value),
1323
+ placeholder: "Follow-up message",
1324
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
1325
+ }
1326
+ ), /* @__PURE__ */ React4.createElement(
1327
+ "button",
1328
+ {
1329
+ onClick: handleSendFollowUpMessage,
1330
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
1331
+ },
1332
+ "Send Follow-Up"
1333
+ )), /* @__PURE__ */ React4.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ React4.createElement(
1334
+ "input",
1335
+ {
1336
+ type: "text",
1337
+ value: externalUrl,
1338
+ onChange: (e) => setExternalUrl(e.target.value),
1339
+ placeholder: "External URL",
1340
+ className: "py-1.5 px-2 bg-[#1a1a1a] text-white border border-gray-700 rounded font-mono text-xs flex-1"
1341
+ }
1342
+ ), /* @__PURE__ */ React4.createElement(
1343
+ "button",
1344
+ {
1345
+ onClick: handleOpenExternal,
1346
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
1347
+ },
1348
+ "Open Link"
1349
+ )), /* @__PURE__ */ React4.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ React4.createElement("span", { className: "w-[150px] text-xs" }, "Display Mode:"), /* @__PURE__ */ React4.createElement(
1350
+ "button",
1351
+ {
1352
+ onClick: () => handleRequestDisplayMode("inline"),
1353
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
1354
+ },
1355
+ "Inline"
1356
+ ), /* @__PURE__ */ React4.createElement(
1357
+ "button",
1358
+ {
1359
+ onClick: () => handleRequestDisplayMode("pip"),
1360
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
1361
+ },
1362
+ "PiP"
1363
+ ), /* @__PURE__ */ React4.createElement(
1364
+ "button",
1365
+ {
1366
+ onClick: () => handleRequestDisplayMode("fullscreen"),
1367
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs flex-1"
1368
+ },
1369
+ "Fullscreen"
1370
+ )), /* @__PURE__ */ React4.createElement("div", { className: "flex gap-2 items-center" }, /* @__PURE__ */ React4.createElement(
1371
+ "button",
1372
+ {
1373
+ onClick: handleSetState,
1374
+ className: "py-1.5 px-3 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-xs"
1375
+ },
1376
+ "Set State (Add Timestamp)"
1377
+ )), actionResult && /* @__PURE__ */ React4.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__ */ React4.createElement("div", { className: "font-bold mb-1 text-gray-400" }, "Result:"), actionResult, /* @__PURE__ */ React4.createElement(
1378
+ "button",
1379
+ {
1380
+ onClick: () => setActionResult(""),
1381
+ className: "mt-2 py-1 px-2 bg-gray-800 text-white border border-gray-600 rounded cursor-pointer font-mono text-[11px]"
1382
+ },
1383
+ "Clear"
1384
+ ))))
2015
1385
  ));
2016
1386
  }
2017
- __name(WidgetDebugger, "WidgetDebugger");
1387
+ __name(WidgetControls, "WidgetControls");
1388
+
1389
+ // src/react/McpUseProvider.tsx
1390
+ import React5, { StrictMode, useCallback as useCallback3, useEffect as useEffect5, useRef as useRef3 } from "react";
1391
+ import { BrowserRouter } from "react-router-dom";
1392
+ function getBasename() {
1393
+ if (typeof window === "undefined") return "/";
1394
+ const path = window.location.pathname;
1395
+ const match = path.match(/^(\/inspector\/api\/dev-widget\/[^/]+)/);
1396
+ if (match) {
1397
+ return match[1];
1398
+ }
1399
+ return "/";
1400
+ }
1401
+ __name(getBasename, "getBasename");
1402
+ var HEIGHT_DEBOUNCE_MS = 150;
1403
+ var MIN_HEIGHT_CHANGE_PX = 5;
1404
+ function McpUseProvider({
1405
+ children,
1406
+ debugger: enableDebugger = false,
1407
+ viewControls = false,
1408
+ autoSize = false
1409
+ }) {
1410
+ const basename = getBasename();
1411
+ const containerRef = useRef3(null);
1412
+ const lastHeightRef = useRef3(0);
1413
+ const debounceTimeoutRef = useRef3(null);
1414
+ const notificationInProgressRef = useRef3(false);
1415
+ const notifyHeight = useCallback3((height) => {
1416
+ if (typeof window !== "undefined" && window.openai?.notifyIntrinsicHeight) {
1417
+ notificationInProgressRef.current = true;
1418
+ window.openai.notifyIntrinsicHeight(height).then(() => {
1419
+ notificationInProgressRef.current = false;
1420
+ }).catch((error) => {
1421
+ notificationInProgressRef.current = false;
1422
+ console.error(
1423
+ "[McpUseProvider] Failed to notify intrinsic height:",
1424
+ error
1425
+ );
1426
+ });
1427
+ }
1428
+ }, []);
1429
+ const debouncedNotifyHeight = useCallback3(
1430
+ (height) => {
1431
+ if (debounceTimeoutRef.current) {
1432
+ clearTimeout(debounceTimeoutRef.current);
1433
+ }
1434
+ debounceTimeoutRef.current = setTimeout(() => {
1435
+ const heightDiff = Math.abs(height - lastHeightRef.current);
1436
+ if (heightDiff >= MIN_HEIGHT_CHANGE_PX && height > 0) {
1437
+ lastHeightRef.current = height;
1438
+ notifyHeight(height);
1439
+ }
1440
+ }, HEIGHT_DEBOUNCE_MS);
1441
+ },
1442
+ [notifyHeight]
1443
+ );
1444
+ useEffect5(() => {
1445
+ if (!autoSize) {
1446
+ return;
1447
+ }
1448
+ const container = containerRef.current;
1449
+ if (!container || typeof ResizeObserver === "undefined") {
1450
+ return;
1451
+ }
1452
+ const observer = new ResizeObserver((entries) => {
1453
+ if (notificationInProgressRef.current) {
1454
+ return;
1455
+ }
1456
+ for (const entry of entries) {
1457
+ const height = entry.contentRect.height;
1458
+ const scrollHeight = entry.target.scrollHeight;
1459
+ const intrinsicHeight = Math.max(height, scrollHeight);
1460
+ debouncedNotifyHeight(intrinsicHeight);
1461
+ }
1462
+ });
1463
+ observer.observe(container);
1464
+ const initialHeight = Math.max(
1465
+ container.offsetHeight,
1466
+ container.scrollHeight
1467
+ );
1468
+ if (initialHeight > 0) {
1469
+ debouncedNotifyHeight(initialHeight);
1470
+ }
1471
+ return () => {
1472
+ observer.disconnect();
1473
+ if (debounceTimeoutRef.current) {
1474
+ clearTimeout(debounceTimeoutRef.current);
1475
+ debounceTimeoutRef.current = null;
1476
+ }
1477
+ notificationInProgressRef.current = false;
1478
+ };
1479
+ }, [autoSize, debouncedNotifyHeight]);
1480
+ let content = children;
1481
+ content = /* @__PURE__ */ React5.createElement(ErrorBoundary, null, content);
1482
+ if (enableDebugger || viewControls) {
1483
+ content = /* @__PURE__ */ React5.createElement(WidgetControls, { debugger: enableDebugger, viewControls }, content);
1484
+ }
1485
+ content = /* @__PURE__ */ React5.createElement(BrowserRouter, { basename }, content);
1486
+ content = /* @__PURE__ */ React5.createElement(ThemeProvider, null, content);
1487
+ if (autoSize) {
1488
+ const containerStyle = {
1489
+ width: "100%",
1490
+ minHeight: 0
1491
+ };
1492
+ content = /* @__PURE__ */ React5.createElement("div", { ref: containerRef, style: containerStyle }, content);
1493
+ }
1494
+ return /* @__PURE__ */ React5.createElement(StrictMode, null, content);
1495
+ }
1496
+ __name(McpUseProvider, "McpUseProvider");
2018
1497
 
2019
1498
  export {
2020
1499
  useMcp,
1500
+ ErrorBoundary,
1501
+ Image,
2021
1502
  useWidget,
2022
1503
  useWidgetProps,
2023
1504
  useWidgetTheme,
2024
1505
  useWidgetState,
2025
- WidgetFullscreenWrapper,
2026
- WidgetDebugger
1506
+ ThemeProvider,
1507
+ WidgetControls,
1508
+ McpUseProvider
2027
1509
  };