@mcp-use/inspector 7.0.0-canary.21 → 7.0.0-canary.22

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.
@@ -2097,11 +2097,11 @@ import {
2097
2097
  Zap
2098
2098
  } from "lucide-react";
2099
2099
  import React7, {
2100
- useCallback as useCallback11,
2101
- useEffect as useEffect10,
2100
+ useCallback as useCallback13,
2101
+ useEffect as useEffect11,
2102
2102
  useMemo as useMemo10,
2103
- useRef as useRef7,
2104
- useState as useState12
2103
+ useRef as useRef8,
2104
+ useState as useState14
2105
2105
  } from "react";
2106
2106
  import { toast as toast4 } from "sonner";
2107
2107
 
@@ -6811,12 +6811,13 @@ import { X as X3 } from "lucide-react";
6811
6811
  import { useMcpClient } from "mcp-use/react";
6812
6812
  import {
6813
6813
  memo,
6814
- useCallback as useCallback9,
6815
- useEffect as useEffect8,
6814
+ useCallback as useCallback11,
6815
+ useEffect as useEffect9,
6816
6816
  useMemo as useMemo8,
6817
- useRef as useRef5,
6818
- useState as useState10
6817
+ useRef as useRef6,
6818
+ useState as useState12
6819
6819
  } from "react";
6820
+ import { createPortal } from "react-dom";
6820
6821
 
6821
6822
  // src/server/rpc-log-bus.ts
6822
6823
  var SimpleEventEmitter = class {
@@ -7000,6 +7001,121 @@ function useMcpAppsHostContext({
7000
7001
  );
7001
7002
  }
7002
7003
 
7004
+ // src/client/lib/use-sandbox-remount-generation.ts
7005
+ import { useCallback as useCallback8, useRef as useRef4, useState as useState9 } from "react";
7006
+ function useSandboxRemountGeneration() {
7007
+ const [generation, setGeneration] = useState9(0);
7008
+ const hasMountedOnceRef = useRef4(false);
7009
+ const onSandboxMount = useCallback8(() => {
7010
+ if (!hasMountedOnceRef.current) {
7011
+ hasMountedOnceRef.current = true;
7012
+ return false;
7013
+ }
7014
+ setGeneration((g) => g + 1);
7015
+ return true;
7016
+ }, []);
7017
+ return { sandboxGeneration: generation, onSandboxMount };
7018
+ }
7019
+
7020
+ // src/client/lib/widget-fullscreen.ts
7021
+ import { useCallback as useCallback9, useEffect as useEffect7, useState as useState10 } from "react";
7022
+ var SHELL_BASE = "w-full h-full min-h-0 bg-background flex flex-col [&:fullscreen]:h-full [&:fullscreen]:w-full [&:fullscreen]:bg-background";
7023
+ var WIDGET_FULLSCREEN_NATIVE_CLASSES = SHELL_BASE;
7024
+ var WIDGET_FULLSCREEN_OVERLAY_CLASSES = `fixed inset-0 z-[100] ${SHELL_BASE}`;
7025
+ var WIDGET_PIP_SHELL_CLASSES = [
7026
+ "fixed top-4 left-1/2 -translate-x-1/2 z-[100]",
7027
+ "rounded-3xl w-full min-w-[300px] h-[400px]",
7028
+ "shadow-2xl border overflow-hidden",
7029
+ "bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80",
7030
+ "flex flex-col"
7031
+ ].join(" ");
7032
+ var WIDGET_FULLSCREEN_DOCUMENT_ATTR = "data-mcp-widget-fullscreen";
7033
+ var WIDGET_DISPLAY_MODE_ATTR = "data-mcp-widget-display-mode";
7034
+ function fullscreenShellClass(cssFallback) {
7035
+ return cssFallback ? WIDGET_FULLSCREEN_OVERLAY_CLASSES : WIDGET_FULLSCREEN_NATIVE_CLASSES;
7036
+ }
7037
+ function useWidgetDisplayModeDocumentChrome(displayMode) {
7038
+ useEffect7(() => {
7039
+ if (typeof document === "undefined") return;
7040
+ if (displayMode === "pip" || displayMode === "fullscreen") {
7041
+ document.documentElement.setAttribute(
7042
+ WIDGET_DISPLAY_MODE_ATTR,
7043
+ displayMode
7044
+ );
7045
+ if (displayMode === "fullscreen") {
7046
+ document.documentElement.setAttribute(
7047
+ WIDGET_FULLSCREEN_DOCUMENT_ATTR,
7048
+ ""
7049
+ );
7050
+ } else {
7051
+ document.documentElement.removeAttribute(
7052
+ WIDGET_FULLSCREEN_DOCUMENT_ATTR
7053
+ );
7054
+ }
7055
+ return () => {
7056
+ document.documentElement.removeAttribute(WIDGET_DISPLAY_MODE_ATTR);
7057
+ document.documentElement.removeAttribute(
7058
+ WIDGET_FULLSCREEN_DOCUMENT_ATTR
7059
+ );
7060
+ };
7061
+ }
7062
+ document.documentElement.removeAttribute(WIDGET_DISPLAY_MODE_ATTR);
7063
+ document.documentElement.removeAttribute(WIDGET_FULLSCREEN_DOCUMENT_ATTR);
7064
+ }, [displayMode]);
7065
+ }
7066
+ function useWidgetDisplayModeControls({
7067
+ containerRef,
7068
+ displayMode,
7069
+ setDisplayMode
7070
+ }) {
7071
+ const [cssFallback, setCssFallback] = useState10(false);
7072
+ const isFullscreen = displayMode === "fullscreen";
7073
+ const isPip = displayMode === "pip";
7074
+ useWidgetDisplayModeDocumentChrome(displayMode);
7075
+ useEffect7(() => {
7076
+ const onFullscreenChange = () => {
7077
+ if (!document.fullscreenElement && displayMode === "fullscreen") {
7078
+ setCssFallback(false);
7079
+ setDisplayMode("inline");
7080
+ }
7081
+ };
7082
+ document.addEventListener("fullscreenchange", onFullscreenChange);
7083
+ return () => document.removeEventListener("fullscreenchange", onFullscreenChange);
7084
+ }, [displayMode, setDisplayMode]);
7085
+ const handleDisplayModeChange = useCallback9(
7086
+ async (mode) => {
7087
+ if (mode === "fullscreen") {
7088
+ try {
7089
+ await containerRef.current?.requestFullscreen();
7090
+ setCssFallback(false);
7091
+ } catch {
7092
+ setCssFallback(true);
7093
+ }
7094
+ setDisplayMode("fullscreen");
7095
+ return;
7096
+ }
7097
+ try {
7098
+ if (document.fullscreenElement) {
7099
+ await document.exitFullscreen();
7100
+ }
7101
+ } catch {
7102
+ }
7103
+ setCssFallback(false);
7104
+ setDisplayMode(mode);
7105
+ },
7106
+ [containerRef, setDisplayMode]
7107
+ );
7108
+ const fullscreenShellClassName = isFullscreen ? fullscreenShellClass(cssFallback) : void 0;
7109
+ const pipShellClassName = isPip ? WIDGET_PIP_SHELL_CLASSES : void 0;
7110
+ return {
7111
+ handleDisplayModeChange,
7112
+ fullscreenShellClassName,
7113
+ pipShellClassName,
7114
+ isFullscreen,
7115
+ isPip
7116
+ };
7117
+ }
7118
+
7003
7119
  // src/client/components/FullscreenNavbar.tsx
7004
7120
  import { X as X2 } from "lucide-react";
7005
7121
  import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
@@ -7013,7 +7129,7 @@ function FullscreenNavbar({
7013
7129
  "div",
7014
7130
  {
7015
7131
  className: cn(
7016
- "fixed top-0 left-0 right-0 z-50 flex items-center justify-between px-4 py-3",
7132
+ "shrink-0 z-50 flex w-full items-center justify-between px-4 py-3",
7017
7133
  "bg-background/80 backdrop-blur-md border-b border-border",
7018
7134
  "supports-[backdrop-filter]:bg-background/60",
7019
7135
  className
@@ -7049,12 +7165,12 @@ function FullscreenNavbar({
7049
7165
  // src/client/components/ui/SandboxedIframe.tsx
7050
7166
  import {
7051
7167
  forwardRef as forwardRef5,
7052
- useCallback as useCallback8,
7053
- useEffect as useEffect7,
7168
+ useCallback as useCallback10,
7169
+ useEffect as useEffect8,
7054
7170
  useImperativeHandle,
7055
7171
  useMemo as useMemo6,
7056
- useRef as useRef4,
7057
- useState as useState9
7172
+ useRef as useRef5,
7173
+ useState as useState11
7058
7174
  } from "react";
7059
7175
  import { jsx as jsx26 } from "react/jsx-runtime";
7060
7176
  var SandboxedIframe = forwardRef5(function SandboxedIframe2({
@@ -7065,14 +7181,18 @@ var SandboxedIframe = forwardRef5(function SandboxedIframe2({
7065
7181
  permissive,
7066
7182
  onProxyReady,
7067
7183
  onLoad,
7184
+ onSandboxMount,
7068
7185
  onMessage,
7069
7186
  className,
7070
7187
  style,
7071
7188
  title = "Sandboxed Content"
7072
7189
  }, ref) {
7073
- const outerRef = useRef4(null);
7074
- const [proxyReady, setProxyReady] = useState9(false);
7075
- const [sandboxProxyUrl] = useState9(() => {
7190
+ const outerRef = useRef5(null);
7191
+ const [proxyReady, setProxyReady] = useState11(false);
7192
+ useEffect8(() => {
7193
+ onSandboxMount?.();
7194
+ }, [onSandboxMount]);
7195
+ const [sandboxProxyUrl] = useState11(() => {
7076
7196
  const currentHost = window.location.hostname;
7077
7197
  const currentPort = window.location.port;
7078
7198
  const protocol = window.location.protocol;
@@ -7114,7 +7234,7 @@ var SandboxedIframe = forwardRef5(function SandboxedIframe2({
7114
7234
  }),
7115
7235
  [sandboxProxyOrigin]
7116
7236
  );
7117
- const handleMessage = useCallback8(
7237
+ const handleMessage = useCallback10(
7118
7238
  (event) => {
7119
7239
  if (event.origin !== sandboxProxyOrigin && sandboxProxyOrigin !== "*") {
7120
7240
  return;
@@ -7130,11 +7250,11 @@ var SandboxedIframe = forwardRef5(function SandboxedIframe2({
7130
7250
  },
7131
7251
  [sandboxProxyOrigin, onProxyReady, onMessage]
7132
7252
  );
7133
- useEffect7(() => {
7253
+ useEffect8(() => {
7134
7254
  window.addEventListener("message", handleMessage);
7135
7255
  return () => window.removeEventListener("message", handleMessage);
7136
7256
  }, [handleMessage]);
7137
- useEffect7(() => {
7257
+ useEffect8(() => {
7138
7258
  if (!proxyReady || !html || !outerRef.current?.contentWindow) return;
7139
7259
  outerRef.current.contentWindow.postMessage(
7140
7260
  {
@@ -7303,8 +7423,8 @@ function MCPAppsRendererBase({
7303
7423
  chromeless,
7304
7424
  inlineWidthOverride
7305
7425
  }) {
7306
- const sandboxRef = useRef5(null);
7307
- const bridgeRef = useRef5(null);
7426
+ const sandboxRef = useRef6(null);
7427
+ const bridgeRef = useRef6(null);
7308
7428
  const { resolvedTheme } = useTheme();
7309
7429
  const { servers } = useMcpClient();
7310
7430
  const serverFromContext = servers.find((s) => s.id === serverId);
@@ -7317,41 +7437,80 @@ function MCPAppsRendererBase({
7317
7437
  setWidgetModelContext,
7318
7438
  setWidgetDeclaredCsp
7319
7439
  } = useWidgetDebug();
7320
- const [initCount, setInitCount] = useState10(0);
7321
- const [loadError, setLoadError] = useState10(null);
7322
- const [widgetHtml, setWidgetHtml] = useState10(null);
7323
- const [isReady, setIsReady] = useState10(false);
7324
- const [showSpinner, setShowSpinner] = useState10(true);
7325
- const hasLoadedOnceRef = useRef5(false);
7326
- const toolInputSentRef = useRef5(null);
7327
- const lastSentPropsRef = useRef5(null);
7328
- const lastSentToolOutputKeyRef = useRef5(null);
7329
- const lastInitTimeRef = useRef5(0);
7330
- const resendTimerRef = useRef5(
7440
+ const [initCount, setInitCount] = useState12(0);
7441
+ const [loadError, setLoadError] = useState12(null);
7442
+ const [widgetHtml, setWidgetHtml] = useState12(null);
7443
+ const [isReady, setIsReady] = useState12(false);
7444
+ const [showSpinner, setShowSpinner] = useState12(true);
7445
+ const hasLoadedOnceRef = useRef6(false);
7446
+ const toolInputSentRef = useRef6(null);
7447
+ const lastSentPropsRef = useRef6(null);
7448
+ const lastSentToolOutputKeyRef = useRef6(null);
7449
+ const lastInitTimeRef = useRef6(0);
7450
+ const resendTimerRef = useRef6(
7331
7451
  void 0
7332
7452
  );
7333
- const toolInputRef = useRef5(toolInput);
7334
- const toolOutputRef = useRef5(toolOutput);
7335
- const customPropsRef = useRef5(customProps);
7336
- const readResourceRef = useRef5(readResource);
7337
- const serverRef = useRef5(server);
7338
- const lastHostContextRef = useRef5(null);
7453
+ const toolInputRef = useRef6(toolInput);
7454
+ const toolOutputRef = useRef6(toolOutput);
7455
+ const customPropsRef = useRef6(customProps);
7456
+ const readResourceRef = useRef6(readResource);
7457
+ const serverRef = useRef6(server);
7458
+ const lastHostContextRef = useRef6(null);
7339
7459
  toolInputRef.current = toolInput;
7340
7460
  toolOutputRef.current = toolOutput;
7341
7461
  customPropsRef.current = customProps;
7342
7462
  readResourceRef.current = readResource;
7343
7463
  serverRef.current = server;
7344
- const [widgetCsp, setWidgetCsp] = useState10(void 0);
7345
- const [widgetPermissions, setWidgetPermissions] = useState10(void 0);
7346
- const [prefersBorder, setPrefersBorder] = useState10(false);
7347
- const [internalDisplayMode, setInternalDisplayMode] = useState10("inline");
7464
+ const [widgetCsp, setWidgetCsp] = useState12(void 0);
7465
+ const [widgetPermissions, setWidgetPermissions] = useState12(void 0);
7466
+ const [prefersBorder, setPrefersBorder] = useState12(false);
7467
+ const [internalDisplayMode, setInternalDisplayMode] = useState12("inline");
7348
7468
  const displayMode = displayModeProp ?? internalDisplayMode;
7349
- const displayModeRef = useRef5(displayMode);
7469
+ const containerRef = useRef6(null);
7470
+ const prevControlledDisplayModeRef = useRef6(displayModeProp);
7471
+ const setDisplayMode = useCallback11(
7472
+ (mode) => {
7473
+ if (displayModeProp !== void 0) {
7474
+ prevControlledDisplayModeRef.current = mode;
7475
+ }
7476
+ if (onDisplayModeChange) onDisplayModeChange(mode);
7477
+ else setInternalDisplayMode(mode);
7478
+ },
7479
+ [onDisplayModeChange, displayModeProp]
7480
+ );
7481
+ const { sandboxGeneration, onSandboxMount } = useSandboxRemountGeneration();
7482
+ const handleSandboxMount = useCallback11(() => {
7483
+ if (onSandboxMount()) {
7484
+ if (hasLoadedOnceRef.current) {
7485
+ setShowSpinner(true);
7486
+ setIsReady(false);
7487
+ }
7488
+ }
7489
+ }, [onSandboxMount]);
7490
+ const {
7491
+ handleDisplayModeChange,
7492
+ fullscreenShellClassName,
7493
+ pipShellClassName,
7494
+ isFullscreen,
7495
+ isPip
7496
+ } = useWidgetDisplayModeControls({
7497
+ containerRef,
7498
+ displayMode,
7499
+ setDisplayMode
7500
+ });
7501
+ const handleDisplayModeChangeRef = useRef6(handleDisplayModeChange);
7502
+ handleDisplayModeChangeRef.current = handleDisplayModeChange;
7503
+ const displayModeRef = useRef6(displayMode);
7350
7504
  displayModeRef.current = displayMode;
7351
- const [inlineHeight, setInlineHeight] = useState10(
7505
+ useEffect9(() => {
7506
+ if (displayModeProp === void 0) return;
7507
+ if (prevControlledDisplayModeRef.current === displayModeProp) return;
7508
+ prevControlledDisplayModeRef.current = displayModeProp;
7509
+ void handleDisplayModeChangeRef.current(displayModeProp);
7510
+ }, [displayModeProp]);
7511
+ const [inlineHeight, setInlineHeight] = useState12(
7352
7512
  MCP_APPS_CONFIG.DIMENSIONS.DEFAULT_HEIGHT
7353
7513
  );
7354
- const containerRef = useRef5(null);
7355
7514
  const cspMode = playground.cspMode;
7356
7515
  const deviceType = playground.deviceType;
7357
7516
  const customViewport = playground.customViewport;
@@ -7375,7 +7534,11 @@ function MCPAppsRendererBase({
7375
7534
  toolMetadata,
7376
7535
  tool
7377
7536
  });
7378
- useEffect8(() => {
7537
+ useEffect9(() => {
7538
+ hasLoadedOnceRef.current = false;
7539
+ readyFiredRef.current = false;
7540
+ }, [toolCallId, resourceUri]);
7541
+ useEffect9(() => {
7379
7542
  const fetchWidgetHtml = async () => {
7380
7543
  try {
7381
7544
  const resourceResult = await readResource(resourceUri);
@@ -7498,15 +7661,15 @@ function MCPAppsRendererBase({
7498
7661
  };
7499
7662
  fetchWidgetHtml();
7500
7663
  }, [serverId, resourceUri, toolCallId, toolName]);
7501
- const prevCspModeRef = useRef5(cspMode);
7502
- useEffect8(() => {
7664
+ const prevCspModeRef = useRef6(cspMode);
7665
+ useEffect9(() => {
7503
7666
  if (prevCspModeRef.current === cspMode) return;
7504
7667
  prevCspModeRef.current = cspMode;
7505
7668
  if (hasLoadedOnceRef.current && onRerun) {
7506
7669
  onRerun();
7507
7670
  }
7508
7671
  }, [cspMode, onRerun]);
7509
- useEffect8(() => {
7672
+ useEffect9(() => {
7510
7673
  if (initCount <= 1) return;
7511
7674
  let cancelled2 = false;
7512
7675
  (async () => {
@@ -7524,10 +7687,14 @@ function MCPAppsRendererBase({
7524
7687
  cancelled2 = true;
7525
7688
  };
7526
7689
  }, [initCount, resourceUri, readResource]);
7527
- useEffect8(() => {
7690
+ useEffect9(() => {
7528
7691
  if (!widgetHtml || !sandboxRef.current) return;
7529
7692
  const iframe = sandboxRef.current.getIframeElement();
7530
7693
  if (!iframe?.contentWindow) return;
7694
+ lastInitTimeRef.current = 0;
7695
+ toolInputSentRef.current = null;
7696
+ lastSentPropsRef.current = null;
7697
+ lastSentToolOutputKeyRef.current = null;
7531
7698
  setInitCount(0);
7532
7699
  const customTransport = {
7533
7700
  sessionId: void 0,
@@ -7641,11 +7808,7 @@ function MCPAppsRendererBase({
7641
7808
  };
7642
7809
  bridge.onrequestdisplaymode = async ({ mode }) => {
7643
7810
  const requestedMode = mode ?? "inline";
7644
- if (onDisplayModeChange) {
7645
- onDisplayModeChange(requestedMode);
7646
- } else {
7647
- setInternalDisplayMode(requestedMode);
7648
- }
7811
+ await handleDisplayModeChangeRef.current(requestedMode);
7649
7812
  return { mode: requestedMode };
7650
7813
  };
7651
7814
  bridge.onupdatemodelcontext = async ({ content, structuredContent }) => {
@@ -7710,9 +7873,11 @@ function MCPAppsRendererBase({
7710
7873
  );
7711
7874
  });
7712
7875
  const handleMessage = (event) => {
7713
- const proxyOrigin = new URL(iframe.src).origin;
7876
+ const activeIframe = sandboxRef.current?.getIframeElement();
7877
+ if (!activeIframe?.contentWindow) return;
7878
+ const proxyOrigin = new URL(activeIframe.src).origin;
7714
7879
  if (event.origin !== proxyOrigin) return;
7715
- if (event.source !== iframe.contentWindow) return;
7880
+ if (event.source !== activeIframe.contentWindow) return;
7716
7881
  if (event.data?.type === "iframe-console-log") {
7717
7882
  if (event.data.level === "error" && typeof window !== "undefined" && window.parent !== window) {
7718
7883
  const args = Array.isArray(event.data.args) ? event.data.args : [];
@@ -7777,11 +7942,12 @@ function MCPAppsRendererBase({
7777
7942
  }, [
7778
7943
  widgetHtml,
7779
7944
  sandboxRef,
7780
- toolCallId
7945
+ toolCallId,
7946
+ sandboxGeneration
7781
7947
  // readResource, server: use refs to avoid bridge tear-down/recreate on parent re-renders
7782
7948
  // (which would reset initCount and cause iframe/widget to re-init, appearing as "re-render")
7783
7949
  ]);
7784
- useEffect8(() => {
7950
+ useEffect9(() => {
7785
7951
  const bridge = bridgeRef.current;
7786
7952
  if (!bridge || initCount === 0) return;
7787
7953
  const contextKey = JSON.stringify(hostContext);
@@ -7789,12 +7955,12 @@ function MCPAppsRendererBase({
7789
7955
  lastHostContextRef.current = contextKey;
7790
7956
  bridge.setHostContext(hostContext);
7791
7957
  }, [hostContext, initCount]);
7792
- useEffect8(() => {
7958
+ useEffect9(() => {
7793
7959
  const bridge = bridgeRef.current;
7794
7960
  if (!bridge || initCount === 0 || !partialToolInput) return;
7795
7961
  bridge.sendToolInputPartial({ arguments: partialToolInput });
7796
7962
  }, [initCount, partialToolInput]);
7797
- useEffect8(() => {
7963
+ useEffect9(() => {
7798
7964
  const bridge = bridgeRef.current;
7799
7965
  if (!bridge || initCount === 0) return;
7800
7966
  const parsedCustomProps = {};
@@ -7833,7 +7999,7 @@ function MCPAppsRendererBase({
7833
7999
  lastSentPropsRef.current = propsKey;
7834
8000
  }
7835
8001
  }, [initCount, toolInput, customProps, toolCallId, partialToolInput]);
7836
- useEffect8(() => {
8002
+ useEffect9(() => {
7837
8003
  const bridge = bridgeRef.current;
7838
8004
  if (!bridge || initCount === 0) return;
7839
8005
  if (toolOutput) {
@@ -7866,12 +8032,12 @@ function MCPAppsRendererBase({
7866
8032
  }
7867
8033
  }
7868
8034
  }, [initCount, toolOutput, toolCallId, customProps]);
7869
- useEffect8(() => {
8035
+ useEffect9(() => {
7870
8036
  const bridge = bridgeRef.current;
7871
8037
  if (!bridge || initCount === 0 || !cancelled) return;
7872
8038
  bridge.sendToolCancelled({ reason: "Cancelled by user" });
7873
8039
  }, [cancelled, initCount]);
7874
- const handleSandboxMessage = useCallback9(
8040
+ const handleSandboxMessage = useCallback11(
7875
8041
  (event) => {
7876
8042
  if (event.data?.type !== "mcp-apps:csp-violation") return;
7877
8043
  const {
@@ -7901,59 +8067,16 @@ function MCPAppsRendererBase({
7901
8067
  },
7902
8068
  [toolCallId, addCspViolation]
7903
8069
  );
7904
- useEffect8(() => {
7905
- const handleFullscreenChange = () => {
7906
- if (!document.fullscreenElement && displayMode === "fullscreen") {
7907
- if (onDisplayModeChange) {
7908
- onDisplayModeChange("inline");
7909
- } else {
7910
- setInternalDisplayMode("inline");
7911
- }
7912
- }
7913
- };
7914
- document.addEventListener("fullscreenchange", handleFullscreenChange);
7915
- return () => {
7916
- document.removeEventListener("fullscreenchange", handleFullscreenChange);
7917
- };
7918
- }, [displayMode, onDisplayModeChange]);
7919
- const handleDisplayModeChange = useCallback9(
7920
- async (mode) => {
7921
- try {
7922
- if (mode === "fullscreen") {
7923
- if (containerRef.current) {
7924
- await containerRef.current.requestFullscreen();
7925
- }
7926
- } else {
7927
- if (document.fullscreenElement) {
7928
- await document.exitFullscreen();
7929
- }
7930
- }
7931
- if (onDisplayModeChange) {
7932
- onDisplayModeChange(mode);
7933
- } else {
7934
- setInternalDisplayMode(mode);
7935
- }
7936
- } catch (err) {
7937
- console.error("[MCPAppsRenderer] Display mode error:", err);
7938
- if (onDisplayModeChange) {
7939
- onDisplayModeChange(mode);
7940
- } else {
7941
- setInternalDisplayMode(mode);
7942
- }
7943
- }
7944
- },
7945
- [onDisplayModeChange]
7946
- );
7947
- const iframeEffectivelyReady = isReady || initCount > 0;
7948
- const readyFiredRef = useRef5(false);
7949
- useEffect8(() => {
8070
+ const iframeEffectivelyReady = initCount > 0 || isReady && !hasLoadedOnceRef.current;
8071
+ const readyFiredRef = useRef6(false);
8072
+ useEffect9(() => {
7950
8073
  if (readyFiredRef.current) return;
7951
8074
  if (initCount > 0) {
7952
8075
  readyFiredRef.current = true;
7953
8076
  onReady?.();
7954
8077
  }
7955
8078
  }, [initCount, onReady]);
7956
- useEffect8(() => {
8079
+ useEffect9(() => {
7957
8080
  if (!iframeEffectivelyReady || !showSpinner) return;
7958
8081
  const timer = setTimeout(() => {
7959
8082
  setShowSpinner(false);
@@ -7970,18 +8093,12 @@ function MCPAppsRendererBase({
7970
8093
  if (!widgetHtml) {
7971
8094
  return /* @__PURE__ */ jsx30(WidgetWrapper, { className, noWrapper, children: /* @__PURE__ */ jsx30("div", { className: "flex absolute left-0 top-0 items-center justify-center w-full h-full", children: /* @__PURE__ */ jsx30(Spinner, { className: "size-5" }) }) });
7972
8095
  }
7973
- const isPip = displayMode === "pip";
7974
- const isFullscreen = displayMode === "fullscreen";
7975
8096
  const containerClassName = (() => {
7976
- if (isFullscreen) {
7977
- return "fixed inset-0 z-40 w-full h-full bg-background flex flex-col";
8097
+ if (fullscreenShellClassName) {
8098
+ return fullscreenShellClassName;
7978
8099
  }
7979
- if (isPip) {
7980
- return [
7981
- `fixed top-4 left-1/2 -translate-x-1/2 z-50 rounded-3xl w-full min-w-[300px] h-[400px]`,
7982
- "shadow-2xl border overflow-hidden",
7983
- "bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80"
7984
- ].join(" ");
8100
+ if (pipShellClassName) {
8101
+ return pipShellClassName;
7985
8102
  }
7986
8103
  return "flex group flex-1 items-center justify-center";
7987
8104
  })();
@@ -7991,7 +8108,7 @@ function MCPAppsRendererBase({
7991
8108
  maxWidth: displayMode === "inline" ? `${inlineMaxWidth}px` : "100%",
7992
8109
  transition: isFullscreen || isPip ? void 0 : "height 300ms ease-out"
7993
8110
  };
7994
- return /* @__PURE__ */ jsx30(WidgetWrapper, { className, noWrapper, children: /* @__PURE__ */ jsxs15(
8111
+ const widgetShell = /* @__PURE__ */ jsxs15(
7995
8112
  "div",
7996
8113
  {
7997
8114
  ref: containerRef,
@@ -8021,8 +8138,8 @@ function MCPAppsRendererBase({
8021
8138
  "div",
8022
8139
  {
8023
8140
  className: cn(
8024
- "flex-1 w-full h-full flex justify-center items-center relative",
8025
- isFullscreen && !chromeless && "pt-14",
8141
+ "relative w-full min-h-0",
8142
+ isFullscreen || isPip ? "flex flex-1 flex-col" : "flex flex-1 justify-center items-center",
8026
8143
  !isPip && !isFullscreen && (invoking || invoked) && "pt-8"
8027
8144
  ),
8028
8145
  children: [
@@ -8030,8 +8147,11 @@ function MCPAppsRendererBase({
8030
8147
  /* @__PURE__ */ jsxs15(
8031
8148
  "div",
8032
8149
  {
8033
- className: "relative w-full h-full",
8034
- style: { maxWidth: iframeStyle.maxWidth },
8150
+ className: cn(
8151
+ "relative w-full",
8152
+ isFullscreen || isPip ? "h-full min-h-0 flex-1" : "h-full"
8153
+ ),
8154
+ style: isFullscreen || isPip ? void 0 : { maxWidth: iframeStyle.maxWidth },
8035
8155
  children: [
8036
8156
  /* @__PURE__ */ jsx30("div", { className: "absolute -top-8 left-2 z-10 h-full", children: !isPip && !isFullscreen && (invoking || invoked) && /* @__PURE__ */ jsxs15("div", { className: "whitespace-nowrap", children: [
8037
8157
  invoking && !toolOutput && /* @__PURE__ */ jsx30(TextShimmer, { className: "text-xs ", children: invoking }),
@@ -8046,6 +8166,7 @@ function MCPAppsRendererBase({
8046
8166
  csp: widgetCsp,
8047
8167
  permissions: widgetPermissions,
8048
8168
  permissive: cspMode === "permissive",
8169
+ onSandboxMount: handleSandboxMount,
8049
8170
  onLoad: () => setIsReady(true),
8050
8171
  onMessage: handleSandboxMessage,
8051
8172
  title: `MCP App: ${toolName}`,
@@ -8069,7 +8190,8 @@ function MCPAppsRendererBase({
8069
8190
  )
8070
8191
  ]
8071
8192
  }
8072
- ) });
8193
+ );
8194
+ return /* @__PURE__ */ jsx30(WidgetWrapper, { className, noWrapper, children: isPip && typeof document !== "undefined" ? createPortal(widgetShell, document.body) : widgetShell });
8073
8195
  }
8074
8196
  function mcpAppsRendererAreEqual(prev, next) {
8075
8197
  const keys = [
@@ -8147,7 +8269,8 @@ function McpUIRenderer({ resource, className }) {
8147
8269
  // src/client/components/OpenAIComponentRenderer.tsx
8148
8270
  import { X as X4 } from "lucide-react";
8149
8271
  import { useMcpClient as useMcpClient2 } from "mcp-use/react";
8150
- import { memo as memo2, useCallback as useCallback10, useEffect as useEffect9, useRef as useRef6, useState as useState11 } from "react";
8272
+ import { memo as memo2, useCallback as useCallback12, useEffect as useEffect10, useRef as useRef7, useState as useState13 } from "react";
8273
+ import { createPortal as createPortal2 } from "react-dom";
8151
8274
 
8152
8275
  // src/client/utils/iframeConsoleInterceptor.ts
8153
8276
  var IFRAME_CONSOLE_INTERCEPTOR_SCRIPT = `
@@ -8325,7 +8448,7 @@ function injectConsoleInterceptor(iframe) {
8325
8448
  }
8326
8449
 
8327
8450
  // src/client/components/OpenAIComponentRenderer.tsx
8328
- import { jsx as jsx32, jsxs as jsxs16 } from "react/jsx-runtime";
8451
+ import { Fragment as Fragment7, jsx as jsx32, jsxs as jsxs16 } from "react/jsx-runtime";
8329
8452
  function Wrapper({
8330
8453
  children,
8331
8454
  className,
@@ -8361,46 +8484,48 @@ function OpenAIComponentRendererBase({
8361
8484
  invoked,
8362
8485
  onUpdateGlobals
8363
8486
  }) {
8364
- const iframeRef = useRef6(null);
8365
- const containerRef = useRef6(null);
8366
- const [isReady, setIsReady] = useState11(false);
8367
- const [showSkeleton, setShowSkeleton] = useState11(true);
8368
- const hasLoadedOnceRef = useRef6(false);
8369
- const [error, setError] = useState11(null);
8370
- const [widgetUrl, setWidgetUrl] = useState11(null);
8371
- const [iframeHeight, setIframeHeight] = useState11(400);
8372
- const lastMeasuredHeightRef = useRef6(0);
8373
- const lastNotifiedHeightRef = useRef6(0);
8374
- const useNotifiedHeightRef = useRef6(false);
8375
- const [centerVertically, setCenterVertically] = useState11(false);
8376
- const [displayMode, setDisplayMode] = useState11("inline");
8377
- const [isSameOrigin, setIsSameOrigin] = useState11(false);
8378
- const [isPipHovered, setIsPipHovered] = useState11(false);
8379
- const [useDevMode, setUseDevMode] = useState11(false);
8380
- const [widgetToolInput, setWidgetToolInput] = useState11(null);
8381
- const [_widgetToolOutput, setWidgetToolOutput] = useState11(null);
8382
- const pendingGlobalUpdatesRef = useRef6(null);
8383
- const flushGlobalsRafRef = useRef6(null);
8384
- const batchedGlobalsRef = useRef6(null);
8385
- const batchScheduledRef = useRef6(false);
8386
- const lastSentToolOutputKeyRef = useRef6(null);
8387
- const toolIdRef = useRef6(
8487
+ const iframeRef = useRef7(null);
8488
+ const containerRef = useRef7(null);
8489
+ const [isReady, setIsReady] = useState13(false);
8490
+ const [showSkeleton, setShowSkeleton] = useState13(true);
8491
+ const hasLoadedOnceRef = useRef7(false);
8492
+ const [error, setError] = useState13(null);
8493
+ const [widgetUrl, setWidgetUrl] = useState13(null);
8494
+ const [iframeHeight, setIframeHeight] = useState13(400);
8495
+ const lastMeasuredHeightRef = useRef7(0);
8496
+ const lastNotifiedHeightRef = useRef7(0);
8497
+ const useNotifiedHeightRef = useRef7(false);
8498
+ const [centerVertically, setCenterVertically] = useState13(false);
8499
+ const [displayMode, setDisplayMode] = useState13("inline");
8500
+ const [isSameOrigin, setIsSameOrigin] = useState13(false);
8501
+ const [isPipHovered, setIsPipHovered] = useState13(false);
8502
+ const [useDevMode, setUseDevMode] = useState13(false);
8503
+ const [widgetToolInput, setWidgetToolInput] = useState13(null);
8504
+ const [_widgetToolOutput, setWidgetToolOutput] = useState13(null);
8505
+ const pendingGlobalUpdatesRef = useRef7(null);
8506
+ const flushGlobalsRafRef = useRef7(null);
8507
+ const batchedGlobalsRef = useRef7(null);
8508
+ const batchScheduledRef = useRef7(false);
8509
+ const lastSentToolOutputKeyRef = useRef7(null);
8510
+ const toolIdRef = useRef7(
8388
8511
  `tool-${Date.now()}-${Math.random().toString(36).substring(7)}`
8389
8512
  );
8390
8513
  const toolId = toolIdRef.current;
8391
- const hasSetWidgetUrlRef = useRef6(false);
8514
+ const hasSetWidgetUrlRef = useRef7(false);
8392
8515
  const { servers } = useMcpClient2();
8393
8516
  const server = servers.find((connection) => connection.id === serverId);
8517
+ const serverRef = useRef7(server);
8518
+ serverRef.current = server;
8394
8519
  const serverBaseUrl = serverBaseUrlProp ?? server?.url;
8395
8520
  const { resolvedTheme } = useTheme();
8396
8521
  const { playground, addWidget, addCspViolation } = useWidgetDebug();
8397
- const toolArgsRef = useRef6(toolArgs);
8398
- const toolResultRef = useRef6(toolResult);
8399
- const readResourceRef = useRef6(readResource);
8400
- const serverBaseUrlRef = useRef6(serverBaseUrl);
8401
- const resolvedThemeRef = useRef6(resolvedTheme);
8402
- const customPropsRef = useRef6(customProps);
8403
- useEffect9(() => {
8522
+ const toolArgsRef = useRef7(toolArgs);
8523
+ const toolResultRef = useRef7(toolResult);
8524
+ const readResourceRef = useRef7(readResource);
8525
+ const serverBaseUrlRef = useRef7(serverBaseUrl);
8526
+ const resolvedThemeRef = useRef7(resolvedTheme);
8527
+ const customPropsRef = useRef7(customProps);
8528
+ useEffect10(() => {
8404
8529
  toolArgsRef.current = toolArgs;
8405
8530
  toolResultRef.current = toolResult;
8406
8531
  readResourceRef.current = readResource;
@@ -8408,7 +8533,7 @@ function OpenAIComponentRendererBase({
8408
8533
  resolvedThemeRef.current = resolvedTheme;
8409
8534
  customPropsRef.current = customProps;
8410
8535
  });
8411
- useEffect9(() => {
8536
+ useEffect10(() => {
8412
8537
  let cancelled = false;
8413
8538
  const storeAndSetUrl = async () => {
8414
8539
  const currentToolResult = toolResultRef.current;
@@ -8508,7 +8633,7 @@ function OpenAIComponentRendererBase({
8508
8633
  // toolResult._meta is updated via updateIframeGlobals() without re-storing.
8509
8634
  toolResult
8510
8635
  ]);
8511
- const updateIframeGlobals = useCallback10(
8636
+ const updateIframeGlobals = useCallback12(
8512
8637
  (updates) => {
8513
8638
  batchedGlobalsRef.current = {
8514
8639
  ...batchedGlobalsRef.current || {},
@@ -8618,7 +8743,7 @@ function OpenAIComponentRendererBase({
8618
8743
  },
8619
8744
  [onUpdateGlobals]
8620
8745
  );
8621
- useEffect9(() => {
8746
+ useEffect10(() => {
8622
8747
  return () => {
8623
8748
  if (flushGlobalsRafRef.current !== null) {
8624
8749
  window.cancelAnimationFrame(flushGlobalsRafRef.current);
@@ -8626,7 +8751,7 @@ function OpenAIComponentRendererBase({
8626
8751
  }
8627
8752
  };
8628
8753
  }, []);
8629
- useEffect9(() => {
8754
+ useEffect10(() => {
8630
8755
  if (!toolResult || !isReady || !iframeRef.current?.contentWindow) return;
8631
8756
  const structuredContent = toolResult?.structuredContent || toolResult;
8632
8757
  const metadata = toolResult?._meta || null;
@@ -8638,47 +8763,55 @@ function OpenAIComponentRendererBase({
8638
8763
  toolResponseMetadata: metadata
8639
8764
  });
8640
8765
  }, [toolResult, isReady, updateIframeGlobals]);
8641
- const handleDisplayModeChange = useCallback10(
8642
- async (mode) => {
8643
- try {
8644
- if (mode === "fullscreen") {
8645
- if (document.fullscreenElement) {
8646
- setDisplayMode(mode);
8647
- updateIframeGlobals({ displayMode: mode });
8648
- return;
8649
- }
8650
- if (containerRef.current) {
8651
- await containerRef.current.requestFullscreen();
8652
- setDisplayMode(mode);
8653
- updateIframeGlobals({ displayMode: mode });
8654
- console.log("[OpenAIComponentRenderer] Entered fullscreen");
8655
- }
8656
- } else {
8657
- if (document.fullscreenElement) {
8658
- await document.exitFullscreen();
8659
- }
8660
- setDisplayMode(mode);
8661
- updateIframeGlobals({ displayMode: mode });
8662
- console.log("[OpenAIComponentRenderer] Exited fullscreen");
8663
- }
8664
- } catch (err) {
8665
- console.error("[OpenAIComponentRenderer] Fullscreen error:", err);
8666
- setDisplayMode(mode);
8667
- updateIframeGlobals({ displayMode: mode });
8668
- }
8766
+ const setDisplayModeWithGlobals = useCallback12(
8767
+ (mode) => {
8768
+ setDisplayMode(mode);
8769
+ updateIframeGlobals({ displayMode: mode });
8669
8770
  },
8670
8771
  [updateIframeGlobals]
8671
8772
  );
8672
- useEffect9(() => {
8773
+ const {
8774
+ handleDisplayModeChange,
8775
+ fullscreenShellClassName,
8776
+ pipShellClassName,
8777
+ isPip
8778
+ } = useWidgetDisplayModeControls({
8779
+ containerRef,
8780
+ displayMode,
8781
+ setDisplayMode: setDisplayModeWithGlobals
8782
+ });
8783
+ const iframeMountCountRef = useRef7(0);
8784
+ const [iframeMountGeneration, setIframeMountGeneration] = useState13(0);
8785
+ const setIframeRef = useCallback12((node) => {
8786
+ iframeRef.current = node;
8787
+ if (!node) return;
8788
+ iframeMountCountRef.current += 1;
8789
+ if (iframeMountCountRef.current > 1) {
8790
+ setIframeMountGeneration((g) => g + 1);
8791
+ if (hasLoadedOnceRef.current) {
8792
+ setShowSkeleton(true);
8793
+ setIsReady(false);
8794
+ }
8795
+ }
8796
+ }, []);
8797
+ const handleDisplayModeChangeRef = useRef7(handleDisplayModeChange);
8798
+ handleDisplayModeChangeRef.current = handleDisplayModeChange;
8799
+ const widgetUrlRef = useRef7(null);
8800
+ useEffect10(() => {
8673
8801
  if (!widgetUrl) return;
8674
- setIsReady(false);
8675
- if (!hasLoadedOnceRef.current) {
8676
- setShowSkeleton(true);
8802
+ const widgetUrlChanged = widgetUrlRef.current !== widgetUrl;
8803
+ widgetUrlRef.current = widgetUrl;
8804
+ if (widgetUrlChanged) {
8805
+ setIsReady(false);
8806
+ if (!hasLoadedOnceRef.current) {
8807
+ setShowSkeleton(true);
8808
+ }
8677
8809
  }
8678
8810
  setError(null);
8679
8811
  let hasHandledLoad = false;
8680
8812
  const handleMessage = async (event) => {
8681
- if (!iframeRef.current || event.source !== iframeRef.current.contentWindow) {
8813
+ const activeIframe = iframeRef.current;
8814
+ if (!activeIframe || event.source !== activeIframe.contentWindow) {
8682
8815
  return;
8683
8816
  }
8684
8817
  if (event.data?.type === "iframe-console-log") {
@@ -8745,15 +8878,20 @@ function OpenAIComponentRendererBase({
8745
8878
  break;
8746
8879
  case "openai:callTool":
8747
8880
  try {
8748
- if (!server) {
8881
+ const currentServer = serverRef.current;
8882
+ if (!currentServer) {
8749
8883
  throw new Error("Server connection not available");
8750
8884
  }
8751
8885
  const { toolName: toolName2, params, requestId } = event.data;
8752
- const result = await server.callTool(toolName2, params || {}, {
8753
- timeout: 6e5,
8754
- // 10 minutes
8755
- resetTimeoutOnProgress: true
8756
- });
8886
+ const result = await currentServer.callTool(
8887
+ toolName2,
8888
+ params || {},
8889
+ {
8890
+ timeout: 6e5,
8891
+ // 10 minutes
8892
+ resetTimeoutOnProgress: true
8893
+ }
8894
+ );
8757
8895
  let formattedResult;
8758
8896
  if (result && typeof result === "object") {
8759
8897
  if (Array.isArray(result.contents)) {
@@ -8858,7 +8996,7 @@ function OpenAIComponentRendererBase({
8858
8996
  try {
8859
8997
  const { mode } = event.data;
8860
8998
  if (mode && ["inline", "pip", "fullscreen"].includes(mode)) {
8861
- await handleDisplayModeChange(mode);
8999
+ await handleDisplayModeChangeRef.current(mode);
8862
9000
  }
8863
9001
  } catch (err) {
8864
9002
  console.error(
@@ -8937,14 +9075,12 @@ function OpenAIComponentRendererBase({
8937
9075
  }, [
8938
9076
  widgetUrl,
8939
9077
  isSameOrigin,
8940
- handleDisplayModeChange,
8941
- server,
8942
9078
  serverId,
8943
- resolvedTheme,
8944
9079
  updateIframeGlobals,
8945
- useDevMode
9080
+ useDevMode,
9081
+ iframeMountGeneration
8946
9082
  ]);
8947
- useEffect9(() => {
9083
+ useEffect10(() => {
8948
9084
  if (!isReady) return;
8949
9085
  if (!isSameOrigin) {
8950
9086
  updateIframeGlobals({ theme: resolvedTheme });
@@ -8962,14 +9098,12 @@ function OpenAIComponentRendererBase({
8962
9098
  }
8963
9099
  updateIframeGlobals({ theme: resolvedTheme });
8964
9100
  }, [resolvedTheme, isReady, isSameOrigin, updateIframeGlobals]);
8965
- useEffect9(() => {
8966
- if (!isReady || !showSkeleton) {
8967
- return;
8968
- }
9101
+ useEffect10(() => {
9102
+ if (!isReady || !showSkeleton) return;
8969
9103
  setShowSkeleton(false);
8970
9104
  hasLoadedOnceRef.current = true;
8971
9105
  }, [isReady, showSkeleton]);
8972
- useEffect9(() => {
9106
+ useEffect10(() => {
8973
9107
  if (!widgetUrl || !isSameOrigin) return;
8974
9108
  const measure = () => {
8975
9109
  if (useNotifiedHeightRef.current) {
@@ -9002,7 +9136,7 @@ function OpenAIComponentRendererBase({
9002
9136
  window.removeEventListener("resize", measure);
9003
9137
  };
9004
9138
  }, [widgetUrl, isSameOrigin]);
9005
- useEffect9(() => {
9139
+ useEffect10(() => {
9006
9140
  const evaluateCentering = () => {
9007
9141
  const container = containerRef.current;
9008
9142
  if (!container) return;
@@ -9015,26 +9149,7 @@ function OpenAIComponentRendererBase({
9015
9149
  window.removeEventListener("resize", evaluateCentering);
9016
9150
  };
9017
9151
  }, [iframeHeight]);
9018
- useEffect9(() => {
9019
- const handleFullscreenChange = () => {
9020
- if (!document.fullscreenElement && displayMode === "fullscreen") {
9021
- setDisplayMode("inline");
9022
- updateIframeGlobals({ displayMode: "inline" });
9023
- console.log("[OpenAIComponentRenderer] Fullscreen exited by user");
9024
- } else if (document.fullscreenElement && displayMode !== "fullscreen") {
9025
- setDisplayMode("fullscreen");
9026
- updateIframeGlobals({ displayMode: "fullscreen" });
9027
- }
9028
- };
9029
- document.addEventListener("fullscreenchange", handleFullscreenChange);
9030
- document.addEventListener("fullscreenerror", (e) => {
9031
- console.error("[OpenAIComponentRenderer] Fullscreen error:", e);
9032
- });
9033
- return () => {
9034
- document.removeEventListener("fullscreenchange", handleFullscreenChange);
9035
- };
9036
- }, [displayMode, updateIframeGlobals]);
9037
- useEffect9(() => {
9152
+ useEffect10(() => {
9038
9153
  if (widgetUrl && resolvedTheme && isReady) {
9039
9154
  const timeoutId = setTimeout(() => {
9040
9155
  updateIframeGlobals({ theme: resolvedTheme });
@@ -9051,9 +9166,101 @@ function OpenAIComponentRendererBase({
9051
9166
  if (!widgetUrl) {
9052
9167
  return /* @__PURE__ */ jsx32(Wrapper, { className, noWrapper, children: /* @__PURE__ */ jsx32("div", { className: "flex absolute left-0 top-0 items-center justify-center w-full h-full", children: /* @__PURE__ */ jsx32(Spinner, { className: "size-5" }) }) });
9053
9168
  }
9169
+ const widgetShell = /* @__PURE__ */ jsxs16(
9170
+ "div",
9171
+ {
9172
+ ref: containerRef,
9173
+ className: cn(
9174
+ "w-full h-full flex flex-col min-h-0",
9175
+ displayMode === "fullscreen" ? "items-stretch justify-stretch" : cn(
9176
+ "justify-center items-center",
9177
+ centerVertically && "items-center"
9178
+ ),
9179
+ fullscreenShellClassName,
9180
+ pipShellClassName
9181
+ ),
9182
+ style: isPip ? { maxWidth: MCP_APPS_CONFIG.DIMENSIONS.PIP_MAX_WIDTH } : void 0,
9183
+ onMouseEnter: () => isPip && setIsPipHovered(true),
9184
+ onMouseLeave: () => isPip && setIsPipHovered(false),
9185
+ children: [
9186
+ displayMode === "fullscreen" && /* @__PURE__ */ jsx32(
9187
+ FullscreenNavbar,
9188
+ {
9189
+ title: toolName,
9190
+ onClose: () => handleDisplayModeChange("inline")
9191
+ }
9192
+ ),
9193
+ isPip && /* @__PURE__ */ jsx32(
9194
+ "button",
9195
+ {
9196
+ onClick: () => handleDisplayModeChange("inline"),
9197
+ className: cn(
9198
+ "absolute top-2 right-2 z-50",
9199
+ "flex items-center justify-center",
9200
+ "w-8 h-8 rounded-full",
9201
+ "bg-background/90 hover:bg-background",
9202
+ "border border-border",
9203
+ "shadow-lg",
9204
+ "transition-opacity duration-200",
9205
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
9206
+ isPipHovered ? "opacity-100" : "opacity-0"
9207
+ ),
9208
+ "aria-label": "Exit Picture in Picture",
9209
+ children: /* @__PURE__ */ jsx32(X4, { className: "w-4 h-4 text-foreground" })
9210
+ }
9211
+ ),
9212
+ /* @__PURE__ */ jsx32(
9213
+ "div",
9214
+ {
9215
+ className: cn(
9216
+ "relative w-full min-h-0",
9217
+ displayMode === "fullscreen" || displayMode === "pip" ? "flex flex-1 flex-col" : cn(
9218
+ "flex flex-1 justify-center items-center",
9219
+ centerVertically && "items-center"
9220
+ ),
9221
+ displayMode === "inline" && (invoking || invoked) && "pt-8"
9222
+ ),
9223
+ children: /* @__PURE__ */ jsxs16(
9224
+ "div",
9225
+ {
9226
+ className: cn(
9227
+ "relative w-full",
9228
+ displayMode === "fullscreen" || displayMode === "pip" ? "h-full min-h-0 flex-1" : "max-w-[768px]"
9229
+ ),
9230
+ children: [
9231
+ displayMode === "inline" && (invoking || invoked) && /* @__PURE__ */ jsxs16("div", { className: "absolute -top-8 left-2 z-10 whitespace-nowrap", children: [
9232
+ invoking && !toolResult && /* @__PURE__ */ jsx32(TextShimmer, { className: "text-xs", children: invoking }),
9233
+ invoked && toolResult && /* @__PURE__ */ jsx32("span", { className: "text-xs text-muted-foreground", children: invoked })
9234
+ ] }),
9235
+ /* @__PURE__ */ jsx32(
9236
+ "iframe",
9237
+ {
9238
+ ref: setIframeRef,
9239
+ src: widgetUrl,
9240
+ className: cn(
9241
+ displayMode === "inline" && "w-full",
9242
+ displayMode === "fullscreen" && "w-full h-full rounded-none",
9243
+ displayMode === "pip" && "w-full h-full rounded-lg"
9244
+ ),
9245
+ style: {
9246
+ height: displayMode === "fullscreen" || displayMode === "pip" ? "100%" : `${iframeHeight}px`
9247
+ },
9248
+ sandbox: IFRAME_SANDBOX_PERMISSIONS,
9249
+ title: `OpenAI Component: ${toolName}`,
9250
+ allow: "web-share"
9251
+ }
9252
+ )
9253
+ ]
9254
+ }
9255
+ )
9256
+ }
9257
+ )
9258
+ ]
9259
+ }
9260
+ );
9054
9261
  return /* @__PURE__ */ jsxs16(Wrapper, { className, noWrapper, children: [
9055
- showSkeleton && /* @__PURE__ */ jsx32("div", { className: "flex absolute left-0 top-0 items-center justify-center w-full h-full z-0", children: /* @__PURE__ */ jsx32(Spinner, { className: "size-5" }) }),
9056
- showConsole && isSameOrigin && displayMode !== "fullscreen" && displayMode !== "pip" && /* @__PURE__ */ jsx32("div", { className: "absolute top-2 right-2 z-30 flex items-center gap-2", children: /* @__PURE__ */ jsx32(
9262
+ !isPip && showSkeleton && /* @__PURE__ */ jsx32("div", { className: "flex absolute left-0 top-0 items-center justify-center w-full h-full z-0", children: /* @__PURE__ */ jsx32(Spinner, { className: "size-5" }) }),
9263
+ showConsole && isSameOrigin && !isPip && displayMode !== "fullscreen" && /* @__PURE__ */ jsx32("div", { className: "absolute top-2 right-2 z-30 flex items-center gap-2", children: /* @__PURE__ */ jsx32(
9057
9264
  MCPAppsDebugControls,
9058
9265
  {
9059
9266
  displayMode,
@@ -9070,84 +9277,10 @@ function OpenAIComponentRendererBase({
9070
9277
  onUpdateGlobals: updateIframeGlobals
9071
9278
  }
9072
9279
  ) }),
9073
- /* @__PURE__ */ jsxs16(
9074
- "div",
9075
- {
9076
- ref: containerRef,
9077
- className: cn(
9078
- "w-full h-full flex flex-col justify-center items-center",
9079
- centerVertically && "items-center",
9080
- displayMode === "fullscreen" && "bg-background",
9081
- displayMode === "pip" && `fixed top-4 left-1/2 -translate-x-1/2 z-50 rounded-3xl w-full min-w-[300px] h-[400px] shadow-2xl border overflow-hidden`
9082
- ),
9083
- style: displayMode === "pip" ? { maxWidth: MCP_APPS_CONFIG.DIMENSIONS.PIP_MAX_WIDTH } : void 0,
9084
- onMouseEnter: () => displayMode === "pip" && setIsPipHovered(true),
9085
- onMouseLeave: () => displayMode === "pip" && setIsPipHovered(false),
9086
- children: [
9087
- displayMode === "fullscreen" && document.fullscreenElement && /* @__PURE__ */ jsx32(
9088
- FullscreenNavbar,
9089
- {
9090
- title: toolName,
9091
- onClose: () => handleDisplayModeChange("inline")
9092
- }
9093
- ),
9094
- displayMode === "pip" && /* @__PURE__ */ jsx32(
9095
- "button",
9096
- {
9097
- onClick: () => handleDisplayModeChange("inline"),
9098
- className: cn(
9099
- "absolute top-2 right-2 z-50",
9100
- "flex items-center justify-center",
9101
- "w-8 h-8 rounded-full",
9102
- "bg-background/90 hover:bg-background",
9103
- "border border-border",
9104
- "shadow-lg",
9105
- "transition-opacity duration-200",
9106
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
9107
- isPipHovered ? "opacity-100" : "opacity-0"
9108
- ),
9109
- "aria-label": "Exit Picture in Picture",
9110
- children: /* @__PURE__ */ jsx32(X4, { className: "w-4 h-4 text-foreground" })
9111
- }
9112
- ),
9113
- /* @__PURE__ */ jsx32(
9114
- "div",
9115
- {
9116
- className: cn(
9117
- "flex-1 w-full flex justify-center items-center relative",
9118
- displayMode === "fullscreen" && "pt-14",
9119
- centerVertically && "items-center",
9120
- displayMode === "inline" && (invoking || invoked) && "pt-8"
9121
- ),
9122
- children: /* @__PURE__ */ jsxs16("div", { className: "relative w-full max-w-[768px]", children: [
9123
- displayMode === "inline" && (invoking || invoked) && /* @__PURE__ */ jsxs16("div", { className: "absolute -top-8 left-2 z-10 whitespace-nowrap", children: [
9124
- invoking && !toolResult && /* @__PURE__ */ jsx32(TextShimmer, { className: "text-xs", children: invoking }),
9125
- invoked && toolResult && /* @__PURE__ */ jsx32("span", { className: "text-xs text-muted-foreground", children: invoked })
9126
- ] }),
9127
- /* @__PURE__ */ jsx32(
9128
- "iframe",
9129
- {
9130
- ref: iframeRef,
9131
- src: widgetUrl,
9132
- className: cn(
9133
- displayMode === "inline" && "w-full",
9134
- displayMode === "fullscreen" && "w-full h-full rounded-none",
9135
- displayMode === "pip" && "w-full h-full rounded-lg"
9136
- ),
9137
- style: {
9138
- height: displayMode === "fullscreen" || displayMode === "pip" ? "100%" : `${iframeHeight}px`
9139
- },
9140
- sandbox: IFRAME_SANDBOX_PERMISSIONS,
9141
- title: `OpenAI Component: ${toolName}`,
9142
- allow: "web-share"
9143
- }
9144
- )
9145
- ] })
9146
- }
9147
- )
9148
- ]
9149
- }
9150
- )
9280
+ isPip && typeof document !== "undefined" ? /* @__PURE__ */ jsxs16(Fragment7, { children: [
9281
+ showSkeleton && /* @__PURE__ */ jsx32("div", { className: "fixed inset-0 z-[99] flex items-center justify-center bg-background/40", children: /* @__PURE__ */ jsx32(Spinner, { className: "size-5" }) }),
9282
+ createPortal2(widgetShell, document.body)
9283
+ ] }) : widgetShell
9151
9284
  ] });
9152
9285
  }
9153
9286
  function openAIComponentRendererAreEqual(prev, next) {
@@ -9232,8 +9365,8 @@ function NotFound({
9232
9365
  // src/client/components/tools/ToolResultDisplay.tsx
9233
9366
  import { jsx as jsx34, jsxs as jsxs18 } from "react/jsx-runtime";
9234
9367
  function RelativeTimeDisplay({ timestamp }) {
9235
- const [label, setLabel] = useState12(() => getRelativeTime(timestamp));
9236
- useEffect10(() => {
9368
+ const [label, setLabel] = useState14(() => getRelativeTime(timestamp));
9369
+ useEffect11(() => {
9237
9370
  const update = () => setLabel(getRelativeTime(timestamp));
9238
9371
  update();
9239
9372
  const id = setInterval(update, 1e3);
@@ -9276,10 +9409,10 @@ function isValidJSON(str) {
9276
9409
  }
9277
9410
  }
9278
9411
  function FormattedContentDisplay({ content }) {
9279
- const [formattedIndices, setFormattedIndices] = useState12(
9412
+ const [formattedIndices, setFormattedIndices] = useState14(
9280
9413
  /* @__PURE__ */ new Set()
9281
9414
  );
9282
- const toggleFormat = useCallback11((idx) => {
9415
+ const toggleFormat = useCallback13((idx) => {
9283
9416
  setFormattedIndices((prev) => {
9284
9417
  const next = new Set(prev);
9285
9418
  if (next.has(idx)) {
@@ -9496,26 +9629,26 @@ function ToolResultDisplay({
9496
9629
  isMaximized = false,
9497
9630
  onRerunTool
9498
9631
  }) {
9499
- const [selectedIndex, setSelectedIndex] = useState12(0);
9500
- const [formattedMode, setFormattedMode] = useState12(true);
9501
- const [viewMode, setViewMode] = useState12(null);
9502
- const [mcpAppsDisplayMode, setMcpAppsDisplayMode] = useState12("inline");
9503
- const [activeProps, setActiveProps] = useState12(
9632
+ const [selectedIndex, setSelectedIndex] = useState14(0);
9633
+ const [formattedMode, setFormattedMode] = useState14(true);
9634
+ const [viewMode, setViewMode] = useState14(null);
9635
+ const [mcpAppsDisplayMode, setMcpAppsDisplayMode] = useState14("inline");
9636
+ const [activeProps, setActiveProps] = useState14(
9504
9637
  null
9505
9638
  );
9506
- const hasSeenComponentViewRef = useRef7(false);
9639
+ const hasSeenComponentViewRef = useRef8(false);
9507
9640
  const currentResult = results[0];
9508
9641
  const toolResults = currentResult ? results.filter((r) => r.toolName === currentResult.toolName) : [];
9509
9642
  const result = toolResults[selectedIndex] || toolResults[0];
9510
9643
  const originalResultIndex = results.findIndex((r) => r === result);
9511
9644
  const errorMessageForCopy = result ? result.error || extractErrorMessage(result.result) : null;
9512
9645
  const copyableText = errorMessageForCopy != null ? errorMessageForCopy : result != null ? JSON.stringify(result.result, null, 2) : "";
9513
- useEffect10(() => {
9646
+ useEffect11(() => {
9514
9647
  if (toolResults.length > 0 && selectedIndex >= toolResults.length) {
9515
9648
  setSelectedIndex(0);
9516
9649
  }
9517
9650
  }, [toolResults.length, selectedIndex]);
9518
- useEffect10(() => {
9651
+ useEffect11(() => {
9519
9652
  hasSeenComponentViewRef.current = false;
9520
9653
  setViewMode(null);
9521
9654
  }, [currentResult?.toolName]);
@@ -9527,11 +9660,11 @@ function ToolResultDisplay({
9527
9660
  () => result?.result,
9528
9661
  [result?.timestamp, result?.duration, selectedIndex]
9529
9662
  );
9530
- const memoizedReadResource = useCallback11(
9663
+ const memoizedReadResource = useCallback13(
9531
9664
  (uri) => readResource(uri),
9532
9665
  [readResource]
9533
9666
  );
9534
- const memoizedOnSendFollowUp = useCallback11(
9667
+ const memoizedOnSendFollowUp = useCallback13(
9535
9668
  (content2) => {
9536
9669
  const text = content2.filter(
9537
9670
  (c) => c.type === "text" && "text" in c
@@ -9631,7 +9764,7 @@ function ToolResultDisplay({
9631
9764
  openaiOutputTemplate,
9632
9765
  mcpAppsResourceUri
9633
9766
  ]);
9634
- useEffect10(() => {
9767
+ useEffect11(() => {
9635
9768
  if (availableViews.length === 0) return;
9636
9769
  const isCurrentModeAvailable = viewMode && availableViews.some((v) => v.mode === viewMode);
9637
9770
  const firstComponentView = availableViews.find((v) => v.mode !== "json");
@@ -9932,7 +10065,7 @@ function ToolResultDisplay({
9932
10065
  }
9933
10066
 
9934
10067
  // src/client/components/chat/ToolResultRenderer.tsx
9935
- import { useEffect as useEffect11, useMemo as useMemo12, useRef as useRef8, useState as useState13 } from "react";
10068
+ import { useEffect as useEffect12, useMemo as useMemo12, useRef as useRef9, useState as useState15 } from "react";
9936
10069
 
9937
10070
  // src/client/components/chat/MCPUIResource.tsx
9938
10071
  import { memo as memo3, useMemo as useMemo11 } from "react";
@@ -9970,7 +10103,7 @@ var MCPUIResource = memo3(({ resource }) => {
9970
10103
  });
9971
10104
 
9972
10105
  // src/client/components/chat/ToolResultRenderer.tsx
9973
- import { Fragment as Fragment7, jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
10106
+ import { Fragment as Fragment8, jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
9974
10107
  function ModelContextBadge({ widgetId }) {
9975
10108
  const { getWidget } = useWidgetDebug();
9976
10109
  const widget = getWidget(widgetId);
@@ -9996,8 +10129,8 @@ function ToolResultRenderer({
9996
10129
  cancelled
9997
10130
  }) {
9998
10131
  const { playground } = useWidgetDebug();
9999
- const [resourceData, setResourceData] = useState13(null);
10000
- const fetchedUriRef = useRef8(null);
10132
+ const [resourceData, setResourceData] = useState15(null);
10133
+ const fetchedUriRef = useRef9(null);
10001
10134
  const toolCallId = useMemo12(
10002
10135
  () => `chat-tool-${toolName}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
10003
10136
  [toolName]
@@ -10076,7 +10209,7 @@ function ToolResultRenderer({
10076
10209
  isAppsSdkTool,
10077
10210
  toolMetaJson
10078
10211
  ]);
10079
- useEffect11(() => {
10212
+ useEffect12(() => {
10080
10213
  if (extractedResource) {
10081
10214
  setResourceData(extractedResource);
10082
10215
  fetchedUriRef.current = extractedResource.uri || null;
@@ -10146,7 +10279,7 @@ function ToolResultRenderer({
10146
10279
  ] });
10147
10280
  }
10148
10281
  if (isMcpAppsTool && resourceUri && serverId && readResource) {
10149
- return /* @__PURE__ */ jsxs19(Fragment7, { children: [
10282
+ return /* @__PURE__ */ jsxs19(Fragment8, { children: [
10150
10283
  /* @__PURE__ */ jsx36(
10151
10284
  MCPAppsRenderer,
10152
10285
  {
@@ -10212,7 +10345,7 @@ function ToolResultRenderer({
10212
10345
  }
10213
10346
  }
10214
10347
  if (mcpUIResources.length > 0) {
10215
- return /* @__PURE__ */ jsx36(Fragment7, { children: mcpUIResources.map((resource) => /* @__PURE__ */ jsx36(
10348
+ return /* @__PURE__ */ jsx36(Fragment8, { children: mcpUIResources.map((resource) => /* @__PURE__ */ jsx36(
10216
10349
  MCPUIResource,
10217
10350
  {
10218
10351
  resource
@@ -10231,14 +10364,14 @@ function ToolResultRenderer({
10231
10364
  }
10232
10365
 
10233
10366
  // src/client/context/InspectorContext.tsx
10234
- import { createContext as createContext3, use as use4, useCallback as useCallback12, useState as useState14 } from "react";
10367
+ import { createContext as createContext3, use as use4, useCallback as useCallback14, useState as useState16 } from "react";
10235
10368
  import { jsx as jsx37 } from "react/jsx-runtime";
10236
10369
  var InspectorContext = createContext3(
10237
10370
  void 0
10238
10371
  );
10239
10372
  function InspectorProvider({ children }) {
10240
10373
  const hostedChatUrl = (typeof window !== "undefined" ? window.__MANUFACT_CHAT_URL__ : void 0) ?? (typeof import.meta !== "undefined" ? import.meta.env?.VITE_MANUFACT_CHAT_URL : void 0);
10241
- const [state, setState] = useState14({
10374
+ const [state, setState] = useState16({
10242
10375
  selectedServerId: null,
10243
10376
  activeTab: "tools",
10244
10377
  selectedToolName: null,
@@ -10258,28 +10391,28 @@ function InspectorProvider({ children }) {
10258
10391
  chatEnableFreeTierUpgrade: true
10259
10392
  } : {}
10260
10393
  });
10261
- const setSelectedServerId = useCallback12((serverId) => {
10394
+ const setSelectedServerId = useCallback14((serverId) => {
10262
10395
  setState((prev) => ({ ...prev, selectedServerId: serverId }));
10263
10396
  }, []);
10264
- const setActiveTab = useCallback12((tab) => {
10397
+ const setActiveTab = useCallback14((tab) => {
10265
10398
  setState((prev) => ({ ...prev, activeTab: tab }));
10266
10399
  }, []);
10267
- const setSelectedToolName = useCallback12((toolName) => {
10400
+ const setSelectedToolName = useCallback14((toolName) => {
10268
10401
  setState((prev) => ({ ...prev, selectedToolName: toolName }));
10269
10402
  }, []);
10270
- const setSelectedPromptName = useCallback12((promptName) => {
10403
+ const setSelectedPromptName = useCallback14((promptName) => {
10271
10404
  setState((prev) => ({ ...prev, selectedPromptName: promptName }));
10272
10405
  }, []);
10273
- const setSelectedResourceUri = useCallback12((resourceUri) => {
10406
+ const setSelectedResourceUri = useCallback14((resourceUri) => {
10274
10407
  setState((prev) => ({ ...prev, selectedResourceUri: resourceUri }));
10275
10408
  }, []);
10276
- const setSelectedSamplingRequestId = useCallback12(
10409
+ const setSelectedSamplingRequestId = useCallback14(
10277
10410
  (requestId) => {
10278
10411
  setState((prev) => ({ ...prev, selectedSamplingRequestId: requestId }));
10279
10412
  },
10280
10413
  []
10281
10414
  );
10282
- const setSelectedElicitationRequestId = useCallback12(
10415
+ const setSelectedElicitationRequestId = useCallback14(
10283
10416
  (requestId) => {
10284
10417
  setState((prev) => ({
10285
10418
  ...prev,
@@ -10288,19 +10421,19 @@ function InspectorProvider({ children }) {
10288
10421
  },
10289
10422
  []
10290
10423
  );
10291
- const setTunnelUrl = useCallback12((tunnelUrl) => {
10424
+ const setTunnelUrl = useCallback14((tunnelUrl) => {
10292
10425
  setState((prev) => ({ ...prev, tunnelUrl }));
10293
10426
  }, []);
10294
- const setIsTunnelStarting = useCallback12((isTunnelStarting) => {
10427
+ const setIsTunnelStarting = useCallback14((isTunnelStarting) => {
10295
10428
  setState((prev) => ({ ...prev, isTunnelStarting }));
10296
10429
  }, []);
10297
- const setEmbeddedMode = useCallback12(
10430
+ const setEmbeddedMode = useCallback14(
10298
10431
  (isEmbedded, config = {}) => {
10299
10432
  setState((prev) => ({ ...prev, isEmbedded, embeddedConfig: config }));
10300
10433
  },
10301
10434
  []
10302
10435
  );
10303
- const navigateToItem = useCallback12(
10436
+ const navigateToItem = useCallback14(
10304
10437
  (serverId, tab, itemIdentifier) => {
10305
10438
  console.warn("[InspectorContext] navigateToItem called:", {
10306
10439
  serverId,
@@ -10320,7 +10453,7 @@ function InspectorProvider({ children }) {
10320
10453
  },
10321
10454
  []
10322
10455
  );
10323
- const clearSelection = useCallback12(() => {
10456
+ const clearSelection = useCallback14(() => {
10324
10457
  setState((prev) => ({
10325
10458
  ...prev,
10326
10459
  selectedToolName: null,
@@ -10415,12 +10548,12 @@ function ResizableHandle({
10415
10548
  import { AnimatePresence, motion as motion2 } from "motion/react";
10416
10549
  import { ChevronLeft } from "lucide-react";
10417
10550
  import {
10418
- useCallback as useCallback13,
10419
- useEffect as useEffect15,
10551
+ useCallback as useCallback15,
10552
+ useEffect as useEffect16,
10420
10553
  useImperativeHandle as useImperativeHandle2,
10421
10554
  useMemo as useMemo14,
10422
- useRef as useRef12,
10423
- useState as useState18
10555
+ useRef as useRef13,
10556
+ useState as useState20
10424
10557
  } from "react";
10425
10558
 
10426
10559
  // src/client/components/shared/ListItem.tsx
@@ -10527,7 +10660,7 @@ function Kbd({ className, ...props }) {
10527
10660
  }
10528
10661
 
10529
10662
  // src/client/components/shared/ListTabHeader.tsx
10530
- import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs21 } from "react/jsx-runtime";
10663
+ import { Fragment as Fragment9, jsx as jsx42, jsxs as jsxs21 } from "react/jsx-runtime";
10531
10664
  function ListTabHeader({
10532
10665
  activeTab,
10533
10666
  isSearchExpanded,
@@ -10550,9 +10683,9 @@ function ListTabHeader({
10550
10683
  }) {
10551
10684
  const isPrimaryTab = activeTab === primaryTabName;
10552
10685
  return /* @__PURE__ */ jsxs21("div", { className: "flex flex-row items-center justify-between p-4 sm:p-4 py-3 gap-2", children: [
10553
- /* @__PURE__ */ jsx42("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: !isSearchExpanded ? /* @__PURE__ */ jsxs21(Fragment8, { children: [
10686
+ /* @__PURE__ */ jsx42("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: !isSearchExpanded ? /* @__PURE__ */ jsxs21(Fragment9, { children: [
10554
10687
  /* @__PURE__ */ jsx42("h2", { className: "text-lg font-medium text-gray-900 dark:text-gray-100", children: isPrimaryTab ? primaryTabTitle : secondaryTabTitle }),
10555
- isPrimaryTab && /* @__PURE__ */ jsxs21(Fragment8, { children: [
10688
+ isPrimaryTab && /* @__PURE__ */ jsxs21(Fragment9, { children: [
10556
10689
  /* @__PURE__ */ jsx42(
10557
10690
  Badge,
10558
10691
  {
@@ -10637,7 +10770,7 @@ function ListTabHeader({
10637
10770
 
10638
10771
  // src/client/components/shared/RpcPanel.tsx
10639
10772
  import { ChevronDown as ChevronDown5, Copy as Copy6, Trash2 as Trash23 } from "lucide-react";
10640
- import { useEffect as useEffect13, useRef as useRef10, useState as useState16 } from "react";
10773
+ import { useEffect as useEffect14, useRef as useRef11, useState as useState18 } from "react";
10641
10774
 
10642
10775
  // src/client/components/logging/JsonRpcLoggerView.tsx
10643
10776
  import {
@@ -10652,7 +10785,7 @@ import {
10652
10785
  getAllRpcLogs,
10653
10786
  subscribeToRpcLogs
10654
10787
  } from "mcp-use/react";
10655
- import { useEffect as useEffect12, useMemo as useMemo13, useRef as useRef9, useState as useState15 } from "react";
10788
+ import { useEffect as useEffect13, useMemo as useMemo13, useRef as useRef10, useState as useState17 } from "react";
10656
10789
  import { toast as toast5 } from "sonner";
10657
10790
  import { jsx as jsx43, jsxs as jsxs22 } from "react/jsx-runtime";
10658
10791
  function JsonRpcLoggerView({
@@ -10661,10 +10794,10 @@ function JsonRpcLoggerView({
10661
10794
  onClearRef,
10662
10795
  onExportRef
10663
10796
  } = {}) {
10664
- const [items, setItems] = useState15([]);
10665
- const scrollRef = useRef9(null);
10666
- const [expanded, setExpanded] = useState15(/* @__PURE__ */ new Set());
10667
- const [searchQuery] = useState15("");
10797
+ const [items, setItems] = useState17([]);
10798
+ const scrollRef = useRef10(null);
10799
+ const [expanded, setExpanded] = useState17(/* @__PURE__ */ new Set());
10800
+ const [searchQuery] = useState17("");
10668
10801
  const toggleExpanded = (id) => {
10669
10802
  setExpanded((prev) => {
10670
10803
  const next = new Set(prev);
@@ -10709,7 +10842,7 @@ function JsonRpcLoggerView({
10709
10842
  if (!serverIds || serverIds.length === 0) return "";
10710
10843
  return [...serverIds].sort().join(",");
10711
10844
  }, [serverIds]);
10712
- useEffect12(() => {
10845
+ useEffect13(() => {
10713
10846
  if (onClearRef) {
10714
10847
  onClearRef.current = clearMessages;
10715
10848
  }
@@ -10719,7 +10852,7 @@ function JsonRpcLoggerView({
10719
10852
  }
10720
10853
  };
10721
10854
  }, [onClearRef, clearMessages]);
10722
- useEffect12(() => {
10855
+ useEffect13(() => {
10723
10856
  if (onExportRef) {
10724
10857
  onExportRef.current = exportAllMessages;
10725
10858
  }
@@ -10729,10 +10862,10 @@ function JsonRpcLoggerView({
10729
10862
  }
10730
10863
  };
10731
10864
  }, [onExportRef, exportAllMessages]);
10732
- useEffect12(() => {
10865
+ useEffect13(() => {
10733
10866
  onCountChange?.(items.length);
10734
10867
  }, [items.length, onCountChange]);
10735
- useEffect12(() => {
10868
+ useEffect13(() => {
10736
10869
  console.log("[RPC Logger] Subscribing to RPC logs for servers:", serverIds);
10737
10870
  const existingLogs = getAllRpcLogs();
10738
10871
  const filteredLogs = serverIds && serverIds.length > 0 ? existingLogs.filter((log) => serverIds.includes(log.serverId)) : existingLogs;
@@ -10863,12 +10996,12 @@ function JsonRpcLoggerView({
10863
10996
  // src/client/components/shared/RpcPanel.tsx
10864
10997
  import { jsx as jsx44, jsxs as jsxs23 } from "react/jsx-runtime";
10865
10998
  function RpcPanel({ serverId, className }) {
10866
- const [rpcMessageCount, setRpcMessageCount] = useState16(0);
10867
- const [rpcPanelCollapsed, setRpcPanelCollapsed] = useState16(true);
10999
+ const [rpcMessageCount, setRpcMessageCount] = useState18(0);
11000
+ const [rpcPanelCollapsed, setRpcPanelCollapsed] = useState18(true);
10868
11001
  const rpcPanelRef = usePanelRef();
10869
- const clearRpcMessagesRef = useRef10(null);
10870
- const exportRpcMessagesRef = useRef10(null);
10871
- useEffect13(() => {
11002
+ const clearRpcMessagesRef = useRef11(null);
11003
+ const exportRpcMessagesRef = useRef11(null);
11004
+ useEffect14(() => {
10872
11005
  rpcPanelRef.current?.collapse();
10873
11006
  }, []);
10874
11007
  const handleResize = (size) => {
@@ -11107,8 +11240,8 @@ import {
11107
11240
  Save as Save2,
11108
11241
  X as X5
11109
11242
  } from "lucide-react";
11110
- import { useEffect as useEffect14, useRef as useRef11, useState as useState17 } from "react";
11111
- import { Fragment as Fragment9, jsx as jsx47, jsxs as jsxs26 } from "react/jsx-runtime";
11243
+ import { useEffect as useEffect15, useRef as useRef12, useState as useState19 } from "react";
11244
+ import { Fragment as Fragment10, jsx as jsx47, jsxs as jsxs26 } from "react/jsx-runtime";
11112
11245
  function ToolExecutionPanel({
11113
11246
  selectedTool,
11114
11247
  toolArgs,
@@ -11125,14 +11258,14 @@ function ToolExecutionPanel({
11125
11258
  sendEmptyFields,
11126
11259
  onToggleEmpty
11127
11260
  }) {
11128
- const [showCancelButton, setShowCancelButton] = useState17(false);
11129
- const [showMetadata, setShowMetadata] = useState17(false);
11130
- const [copiedMetadata, setCopiedMetadata] = useState17(false);
11131
- const [copiedPayload, setCopiedPayload] = useState17(false);
11132
- const [isDescriptionExpanded, setIsDescriptionExpanded] = useState17(false);
11133
- const [isDescriptionTruncated, setIsDescriptionTruncated] = useState17(false);
11134
- const descriptionRef = useRef11(null);
11135
- useEffect14(() => {
11261
+ const [showCancelButton, setShowCancelButton] = useState19(false);
11262
+ const [showMetadata, setShowMetadata] = useState19(false);
11263
+ const [copiedMetadata, setCopiedMetadata] = useState19(false);
11264
+ const [copiedPayload, setCopiedPayload] = useState19(false);
11265
+ const [isDescriptionExpanded, setIsDescriptionExpanded] = useState19(false);
11266
+ const [isDescriptionTruncated, setIsDescriptionTruncated] = useState19(false);
11267
+ const descriptionRef = useRef12(null);
11268
+ useEffect15(() => {
11136
11269
  if (descriptionRef.current && selectedTool?.description) {
11137
11270
  const element = descriptionRef.current;
11138
11271
  const lineHeight = parseFloat(getComputedStyle(element).lineHeight);
@@ -11161,7 +11294,7 @@ function ToolExecutionPanel({
11161
11294
  } catch {
11162
11295
  }
11163
11296
  };
11164
- useEffect14(() => {
11297
+ useEffect15(() => {
11165
11298
  const handleKeyDown = (event) => {
11166
11299
  if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
11167
11300
  if (selectedTool && !isExecuting && isConnected) {
@@ -11262,11 +11395,11 @@ function ToolExecutionPanel({
11262
11395
  variant: showCancelButton ? "destructive" : "default",
11263
11396
  size: "sm",
11264
11397
  className: "lg:size-default gap-2 transition-all",
11265
- children: showCancelButton ? /* @__PURE__ */ jsxs26(Fragment9, { children: [
11398
+ children: showCancelButton ? /* @__PURE__ */ jsxs26(Fragment10, { children: [
11266
11399
  /* @__PURE__ */ jsx47(X5, { className: "h-4 w-4" }),
11267
11400
  /* @__PURE__ */ jsx47("span", { className: "hidden sm:inline", children: "Cancel" }),
11268
11401
  /* @__PURE__ */ jsx47("span", { className: "hidden sm:inline text-[12px] border border-current p-1 rounded-full ml-2", children: "Esc" })
11269
- ] }) : /* @__PURE__ */ jsxs26(Fragment9, { children: [
11402
+ ] }) : /* @__PURE__ */ jsxs26(Fragment10, { children: [
11270
11403
  /* @__PURE__ */ jsx47(Spinner, { className: "mr-2" }),
11271
11404
  /* @__PURE__ */ jsx47("span", { className: "hidden sm:inline", children: "Executing..." })
11272
11405
  ] })
@@ -11283,10 +11416,10 @@ function ToolExecutionPanel({
11283
11416
  disabled: isExecuting || !isConnected,
11284
11417
  size: "sm",
11285
11418
  className: "lg:size-default pr-1! gap-0",
11286
- children: isExecuting ? /* @__PURE__ */ jsxs26(Fragment9, { children: [
11419
+ children: isExecuting ? /* @__PURE__ */ jsxs26(Fragment10, { children: [
11287
11420
  /* @__PURE__ */ jsx47(Spinner, { className: "mr-2" }),
11288
11421
  /* @__PURE__ */ jsx47("span", { className: "hidden sm:inline", children: "Executing..." })
11289
- ] }) : /* @__PURE__ */ jsxs26(Fragment9, { children: [
11422
+ ] }) : /* @__PURE__ */ jsxs26(Fragment10, { children: [
11290
11423
  /* @__PURE__ */ jsx47(Play2, { className: "h-4 w-4 sm:mr-2" }),
11291
11424
  /* @__PURE__ */ jsx47("span", { className: "hidden sm:inline", children: "Execute" }),
11292
11425
  /* @__PURE__ */ jsx47("span", { className: "hidden sm:inline text-[12px] border text-zinc-300 p-1 rounded-full border-zinc-300 dark:text-zinc-600 dark:border-zinc-500 ml-2", children: "\u2318\u21B5" })
@@ -11314,10 +11447,10 @@ function ToolExecutionPanel({
11314
11447
  {
11315
11448
  onClick: () => setIsDescriptionExpanded(!isDescriptionExpanded),
11316
11449
  className: "relative z-10 inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 mt-1 transition-colors",
11317
- children: isDescriptionExpanded ? /* @__PURE__ */ jsxs26(Fragment9, { children: [
11450
+ children: isDescriptionExpanded ? /* @__PURE__ */ jsxs26(Fragment10, { children: [
11318
11451
  "Show less",
11319
11452
  /* @__PURE__ */ jsx47(ChevronUp, { className: "h-3 w-3" })
11320
- ] }) : /* @__PURE__ */ jsxs26(Fragment9, { children: [
11453
+ ] }) : /* @__PURE__ */ jsxs26(Fragment10, { children: [
11321
11454
  "Show more",
11322
11455
  /* @__PURE__ */ jsx47(ChevronDown6, { className: "h-3 w-3" })
11323
11456
  ] })
@@ -11603,7 +11736,7 @@ function AlertDialogCancel({
11603
11736
  }
11604
11737
 
11605
11738
  // src/client/components/ToolsTab.tsx
11606
- import { Fragment as Fragment10, jsx as jsx51, jsxs as jsxs29 } from "react/jsx-runtime";
11739
+ import { Fragment as Fragment11, jsx as jsx51, jsxs as jsxs29 } from "react/jsx-runtime";
11607
11740
  var SAVED_REQUESTS_KEY = "mcp-inspector-saved-requests";
11608
11741
  function ToolsTab({
11609
11742
  ref,
@@ -11614,45 +11747,45 @@ function ToolsTab({
11614
11747
  isConnected,
11615
11748
  refreshTools
11616
11749
  }) {
11617
- const [isRefreshing, setIsRefreshing] = useState18(false);
11618
- const [selectedTool, setSelectedTool] = useState18(null);
11619
- const [selectedSavedRequest, setSelectedSavedRequest] = useState18(null);
11750
+ const [isRefreshing, setIsRefreshing] = useState20(false);
11751
+ const [selectedTool, setSelectedTool] = useState20(null);
11752
+ const [selectedSavedRequest, setSelectedSavedRequest] = useState20(null);
11620
11753
  const { selectedToolName, setSelectedToolName } = useInspector();
11621
- const [toolArgs, setToolArgs] = useState18({});
11622
- const [setFields, setSetFields] = useState18(/* @__PURE__ */ new Set());
11623
- const [sendEmptyFields, setSendEmptyFields] = useState18(
11754
+ const [toolArgs, setToolArgs] = useState20({});
11755
+ const [setFields, setSetFields] = useState20(/* @__PURE__ */ new Set());
11756
+ const [sendEmptyFields, setSendEmptyFields] = useState20(
11624
11757
  /* @__PURE__ */ new Set()
11625
11758
  );
11626
- const [results, setResults] = useState18([]);
11627
- const [isExecuting, setIsExecuting] = useState18(false);
11628
- const [copiedResult, setCopiedResult] = useState18(null);
11629
- const [abortController, setAbortController] = useState18(null);
11630
- const [searchQuery, setSearchQuery] = useState18("");
11631
- const [activeTab, setActiveTab] = useState18("tools");
11632
- const [savedRequests, setSavedRequests] = useState18([]);
11633
- const [saveDialogOpen, setSaveDialogOpen] = useState18(false);
11634
- const [requestName, setRequestName] = useState18("");
11635
- const [isSearchExpanded, setIsSearchExpanded] = useState18(false);
11636
- const [focusedIndex, setFocusedIndex] = useState18(-1);
11637
- const searchInputRef = useRef12(null);
11638
- const [isMobile, setIsMobile] = useState18(false);
11639
- const [mobileView, setMobileView] = useState18(
11759
+ const [results, setResults] = useState20([]);
11760
+ const [isExecuting, setIsExecuting] = useState20(false);
11761
+ const [copiedResult, setCopiedResult] = useState20(null);
11762
+ const [abortController, setAbortController] = useState20(null);
11763
+ const [searchQuery, setSearchQuery] = useState20("");
11764
+ const [activeTab, setActiveTab] = useState20("tools");
11765
+ const [savedRequests, setSavedRequests] = useState20([]);
11766
+ const [saveDialogOpen, setSaveDialogOpen] = useState20(false);
11767
+ const [requestName, setRequestName] = useState20("");
11768
+ const [isSearchExpanded, setIsSearchExpanded] = useState20(false);
11769
+ const [focusedIndex, setFocusedIndex] = useState20(-1);
11770
+ const searchInputRef = useRef13(null);
11771
+ const [isMobile, setIsMobile] = useState20(false);
11772
+ const [mobileView, setMobileView] = useState20(
11640
11773
  "list"
11641
11774
  );
11642
- const [isMaximized, setIsMaximized] = useState18(false);
11643
- const [autoFillDialog, setAutoFillDialog] = useState18({
11775
+ const [isMaximized, setIsMaximized] = useState20(false);
11776
+ const [autoFillDialog, setAutoFillDialog] = useState20({
11644
11777
  open: false,
11645
11778
  parsedObject: {},
11646
11779
  fieldsToUpdate: [],
11647
11780
  newFields: [],
11648
11781
  resolve: null
11649
11782
  });
11650
- const [autoFilledFields, setAutoFilledFields] = useState18(
11783
+ const [autoFilledFields, setAutoFilledFields] = useState20(
11651
11784
  /* @__PURE__ */ new Set()
11652
11785
  );
11653
11786
  const leftPanelRef = usePanelRef();
11654
11787
  const toolParamsPanelRef = usePanelRef();
11655
- useEffect15(() => {
11788
+ useEffect16(() => {
11656
11789
  const checkMobile = () => {
11657
11790
  setIsMobile(window.innerWidth < 1024);
11658
11791
  };
@@ -11660,14 +11793,14 @@ function ToolsTab({
11660
11793
  window.addEventListener("resize", checkMobile);
11661
11794
  return () => window.removeEventListener("resize", checkMobile);
11662
11795
  }, []);
11663
- useEffect15(() => {
11796
+ useEffect16(() => {
11664
11797
  if (selectedTool) {
11665
11798
  setMobileView("detail");
11666
11799
  } else {
11667
11800
  setMobileView("list");
11668
11801
  }
11669
11802
  }, [selectedTool]);
11670
- useEffect15(() => {
11803
+ useEffect16(() => {
11671
11804
  if (isMobile && results.length > 0 && !isExecuting) {
11672
11805
  setMobileView("response");
11673
11806
  }
@@ -11689,7 +11822,7 @@ function ToolsTab({
11689
11822
  }
11690
11823
  }
11691
11824
  }));
11692
- useEffect15(() => {
11825
+ useEffect16(() => {
11693
11826
  try {
11694
11827
  const saved = localStorage.getItem(SAVED_REQUESTS_KEY);
11695
11828
  if (saved) {
@@ -11699,7 +11832,7 @@ function ToolsTab({
11699
11832
  console.error("[ToolsTab] Failed to load saved requests:", error);
11700
11833
  }
11701
11834
  }, []);
11702
- const handleMaximize = useCallback13(() => {
11835
+ const handleMaximize = useCallback15(() => {
11703
11836
  if (!isMaximized) {
11704
11837
  if (leftPanelRef.current) {
11705
11838
  leftPanelRef.current.collapse();
@@ -11718,7 +11851,7 @@ function ToolsTab({
11718
11851
  setIsMaximized(false);
11719
11852
  }
11720
11853
  }, [isMaximized, leftPanelRef, toolParamsPanelRef]);
11721
- const saveSavedRequests = useCallback13((requests) => {
11854
+ const saveSavedRequests = useCallback15((requests) => {
11722
11855
  try {
11723
11856
  localStorage.setItem(SAVED_REQUESTS_KEY, JSON.stringify(requests));
11724
11857
  setSavedRequests(requests);
@@ -11733,7 +11866,7 @@ function ToolsTab({
11733
11866
  (tool) => tool.name.toLowerCase().includes(query) || tool.description?.toLowerCase().includes(query)
11734
11867
  );
11735
11868
  }, [tools, searchQuery]);
11736
- const handleToolSelect = useCallback13((tool) => {
11869
+ const handleToolSelect = useCallback15((tool) => {
11737
11870
  setSelectedTool(tool);
11738
11871
  const initialArgs = {};
11739
11872
  const initialSetFields = /* @__PURE__ */ new Set();
@@ -11750,7 +11883,7 @@ function ToolsTab({
11750
11883
  setSetFields(initialSetFields);
11751
11884
  setSendEmptyFields(/* @__PURE__ */ new Set());
11752
11885
  }, []);
11753
- const loadSavedRequest = useCallback13(
11886
+ const loadSavedRequest = useCallback15(
11754
11887
  (request) => {
11755
11888
  const tool = tools.find((t) => t.name === request.toolName);
11756
11889
  if (tool) {
@@ -11763,17 +11896,17 @@ function ToolsTab({
11763
11896
  },
11764
11897
  [tools]
11765
11898
  );
11766
- useEffect15(() => {
11899
+ useEffect16(() => {
11767
11900
  if (isSearchExpanded && searchInputRef.current) {
11768
11901
  searchInputRef.current.focus();
11769
11902
  }
11770
11903
  }, [isSearchExpanded]);
11771
- const handleSearchBlur = useCallback13(() => {
11904
+ const handleSearchBlur = useCallback15(() => {
11772
11905
  if (!searchQuery.trim()) {
11773
11906
  setIsSearchExpanded(false);
11774
11907
  }
11775
11908
  }, [searchQuery]);
11776
- const handleRefresh = useCallback13(async () => {
11909
+ const handleRefresh = useCallback15(async () => {
11777
11910
  if (!refreshTools) return;
11778
11911
  setIsRefreshing(true);
11779
11912
  try {
@@ -11782,15 +11915,15 @@ function ToolsTab({
11782
11915
  setIsRefreshing(false);
11783
11916
  }
11784
11917
  }, [refreshTools]);
11785
- useEffect15(() => {
11918
+ useEffect16(() => {
11786
11919
  if (activeTab !== "tools") {
11787
11920
  setIsSearchExpanded(false);
11788
11921
  }
11789
11922
  }, [activeTab]);
11790
- useEffect15(() => {
11923
+ useEffect16(() => {
11791
11924
  setFocusedIndex(-1);
11792
11925
  }, [searchQuery, activeTab]);
11793
- useEffect15(() => {
11926
+ useEffect16(() => {
11794
11927
  const handleKeyDown = (e) => {
11795
11928
  const target = e.target;
11796
11929
  const isInputFocused = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.contentEditable === "true";
@@ -11835,7 +11968,7 @@ function ToolsTab({
11835
11968
  handleToolSelect,
11836
11969
  loadSavedRequest
11837
11970
  ]);
11838
- useEffect15(() => {
11971
+ useEffect16(() => {
11839
11972
  if (focusedIndex >= 0) {
11840
11973
  const itemId = activeTab === "tools" ? `tool-${filteredTools[focusedIndex]?.name}` : `saved-${savedRequests[focusedIndex]?.id}`;
11841
11974
  const element = document.getElementById(itemId);
@@ -11844,7 +11977,7 @@ function ToolsTab({
11844
11977
  }
11845
11978
  }
11846
11979
  }, [focusedIndex, filteredTools, savedRequests, activeTab]);
11847
- useEffect15(() => {
11980
+ useEffect16(() => {
11848
11981
  if (selectedToolName && tools.length > 0) {
11849
11982
  const tool = tools.find((t) => t.name === selectedToolName);
11850
11983
  if (tool && selectedTool?.name !== tool.name) {
@@ -11869,7 +12002,7 @@ function ToolsTab({
11869
12002
  handleToolSelect,
11870
12003
  setSelectedToolName
11871
12004
  ]);
11872
- useEffect15(() => {
12005
+ useEffect16(() => {
11873
12006
  if (selectedTool) {
11874
12007
  const updatedTool = tools.find((t) => t.name === selectedTool.name);
11875
12008
  if (!updatedTool) {
@@ -11883,7 +12016,7 @@ function ToolsTab({
11883
12016
  }
11884
12017
  }
11885
12018
  }, [tools, selectedTool, setSelectedToolName]);
11886
- const handleArgChange = useCallback13(
12019
+ const handleArgChange = useCallback15(
11887
12020
  (key, value) => {
11888
12021
  const rootSchema = selectedTool?.inputSchema || {};
11889
12022
  const prop = selectedTool?.inputSchema?.properties?.[key];
@@ -11916,7 +12049,7 @@ function ToolsTab({
11916
12049
  },
11917
12050
  [selectedTool]
11918
12051
  );
11919
- const handleToggleEmpty = useCallback13(
12052
+ const handleToggleEmpty = useCallback15(
11920
12053
  (key, expectedType, pressed) => {
11921
12054
  if (pressed) {
11922
12055
  const emptyValue = expectedType === "array" ? "[]" : expectedType === "object" ? "{}" : "";
@@ -11938,7 +12071,7 @@ function ToolsTab({
11938
12071
  },
11939
12072
  []
11940
12073
  );
11941
- const handleBulkPaste = useCallback13(
12074
+ const handleBulkPaste = useCallback15(
11942
12075
  async (pastedText, _fieldKey) => {
11943
12076
  if (!selectedTool) return false;
11944
12077
  const parsedObject = parseObjectFromPaste(pastedText);
@@ -12000,7 +12133,7 @@ function ToolsTab({
12000
12133
  },
12001
12134
  [selectedTool, toolArgs, handleArgChange]
12002
12135
  );
12003
- const handleAutoFillConfirm = useCallback13(() => {
12136
+ const handleAutoFillConfirm = useCallback15(() => {
12004
12137
  if (!autoFillDialog.resolve) return;
12005
12138
  autoFillDialog.fieldsToUpdate.forEach(({ key, newValue }) => {
12006
12139
  handleArgChange(key, String(newValue));
@@ -12020,7 +12153,7 @@ function ToolsTab({
12020
12153
  resolve: null
12021
12154
  });
12022
12155
  }, [autoFillDialog, handleArgChange]);
12023
- const handleAutoFillCancel = useCallback13(() => {
12156
+ const handleAutoFillCancel = useCallback15(() => {
12024
12157
  if (!autoFillDialog.resolve) return;
12025
12158
  autoFillDialog.resolve(false);
12026
12159
  setAutoFillDialog({
@@ -12044,7 +12177,7 @@ function ToolsTab({
12044
12177
  }
12045
12178
  return result;
12046
12179
  }, [selectedTool, toolArgs, setFields, sendEmptyFields]);
12047
- const executeTool = useCallback13(async () => {
12180
+ const executeTool = useCallback15(async () => {
12048
12181
  if (!selectedTool || isExecuting) return;
12049
12182
  const controller = new AbortController();
12050
12183
  setAbortController(controller);
@@ -12205,7 +12338,7 @@ function ToolsTab({
12205
12338
  readResource,
12206
12339
  serverId
12207
12340
  ]);
12208
- const handleCopyResult = useCallback13(async (index, text) => {
12341
+ const handleCopyResult = useCallback15(async (index, text) => {
12209
12342
  try {
12210
12343
  await copyToClipboard(text);
12211
12344
  setCopiedResult(index);
@@ -12214,14 +12347,14 @@ function ToolsTab({
12214
12347
  console.error("[ToolsTab] Failed to copy result:", error);
12215
12348
  }
12216
12349
  }, []);
12217
- const handleDeleteResult = useCallback13((index) => {
12350
+ const handleDeleteResult = useCallback15((index) => {
12218
12351
  setResults((prev) => prev.filter((_, i) => i !== index));
12219
12352
  }, []);
12220
12353
  const filteredResults = useMemo14(() => {
12221
12354
  if (!selectedTool) return [];
12222
12355
  return results.filter((r) => r.toolName === selectedTool.name);
12223
12356
  }, [results, selectedTool]);
12224
- const handleFullscreen = useCallback13(
12357
+ const handleFullscreen = useCallback15(
12225
12358
  (index) => {
12226
12359
  const result = filteredResults[index];
12227
12360
  if (result) {
@@ -12248,12 +12381,12 @@ function ToolsTab({
12248
12381
  },
12249
12382
  [results]
12250
12383
  );
12251
- const openSaveDialog = useCallback13(() => {
12384
+ const openSaveDialog = useCallback15(() => {
12252
12385
  if (!selectedTool) return;
12253
12386
  setRequestName("");
12254
12387
  setSaveDialogOpen(true);
12255
12388
  }, [selectedTool]);
12256
- const saveRequest = useCallback13(() => {
12389
+ const saveRequest = useCallback15(() => {
12257
12390
  if (!selectedTool) return;
12258
12391
  const newRequest = {
12259
12392
  id: `${Date.now()}-${Math.random()}`,
@@ -12283,7 +12416,7 @@ function ToolsTab({
12283
12416
  saveSavedRequests,
12284
12417
  serverId
12285
12418
  ]);
12286
- const deleteSavedRequest = useCallback13(
12419
+ const deleteSavedRequest = useCallback15(
12287
12420
  (id) => {
12288
12421
  saveSavedRequests(savedRequests.filter((r) => r.id !== id));
12289
12422
  if (selectedSavedRequest?.id === id) {
@@ -12324,7 +12457,7 @@ function ToolsTab({
12324
12457
  children: "Tools"
12325
12458
  }
12326
12459
  ),
12327
- mobileView === "detail" && /* @__PURE__ */ jsxs29(Fragment10, { children: [
12460
+ mobileView === "detail" && /* @__PURE__ */ jsxs29(Fragment11, { children: [
12328
12461
  /* @__PURE__ */ jsx51("span", { className: "mx-2 text-muted-foreground", children: "/" }),
12329
12462
  /* @__PURE__ */ jsx51(
12330
12463
  "button",
@@ -12337,7 +12470,7 @@ function ToolsTab({
12337
12470
  }
12338
12471
  )
12339
12472
  ] }),
12340
- mobileView === "response" && /* @__PURE__ */ jsxs29(Fragment10, { children: [
12473
+ mobileView === "response" && /* @__PURE__ */ jsxs29(Fragment11, { children: [
12341
12474
  /* @__PURE__ */ jsx51("span", { className: "mx-2 text-muted-foreground", children: "/" }),
12342
12475
  /* @__PURE__ */ jsx51("span", { className: "text-foreground", children: "Response" })
12343
12476
  ] })
@@ -12670,12 +12803,12 @@ ToolsTab.displayName = "ToolsTab";
12670
12803
  import { AnimatePresence as AnimatePresence2, motion as motion3 } from "motion/react";
12671
12804
  import { ChevronLeft as ChevronLeft2 } from "lucide-react";
12672
12805
  import {
12673
- useCallback as useCallback16,
12674
- useEffect as useEffect17,
12806
+ useCallback as useCallback18,
12807
+ useEffect as useEffect18,
12675
12808
  useImperativeHandle as useImperativeHandle3,
12676
12809
  useMemo as useMemo16,
12677
- useRef as useRef13,
12678
- useState as useState21
12810
+ useRef as useRef14,
12811
+ useState as useState23
12679
12812
  } from "react";
12680
12813
 
12681
12814
  // src/client/components/resources/ResourceResultDisplay.tsx
@@ -12689,7 +12822,7 @@ import {
12689
12822
  Maximize as Maximize3,
12690
12823
  Zap as Zap2
12691
12824
  } from "lucide-react";
12692
- import { useCallback as useCallback14, useMemo as useMemo15, useState as useState19 } from "react";
12825
+ import { useCallback as useCallback16, useMemo as useMemo15, useState as useState21 } from "react";
12693
12826
  import { jsx as jsx52, jsxs as jsxs30 } from "react/jsx-runtime";
12694
12827
  function extractErrorMessage2(result) {
12695
12828
  if ("error" in result && result.error && typeof result.error === "string") {
@@ -12723,13 +12856,13 @@ function ResourceResultDisplay({
12723
12856
  llmConfig
12724
12857
  }) {
12725
12858
  const emptyToolInput = useMemo15(() => ({}), []);
12726
- const [activeProps, setActiveProps] = useState19(
12859
+ const [activeProps, setActiveProps] = useState21(
12727
12860
  null
12728
12861
  );
12729
- const handlePropsChange = useCallback14((p) => {
12862
+ const handlePropsChange = useCallback16((p) => {
12730
12863
  setActiveProps(p);
12731
12864
  }, []);
12732
- const [mcpAppsDisplayMode, setMcpAppsDisplayMode] = useState19("inline");
12865
+ const [mcpAppsDisplayMode, setMcpAppsDisplayMode] = useState21("inline");
12733
12866
  let openaiAnnotations = [];
12734
12867
  let openaiOutputTemplate;
12735
12868
  if (result?.resourceAnnotations) {
@@ -13067,7 +13200,7 @@ function ResourcesList({
13067
13200
 
13068
13201
  // src/client/components/resources/ResourcesTabHeader.tsx
13069
13202
  import { RefreshCw as RefreshCw2, Search as Search3 } from "lucide-react";
13070
- import { Fragment as Fragment11, jsx as jsx54, jsxs as jsxs32 } from "react/jsx-runtime";
13203
+ import { Fragment as Fragment12, jsx as jsx54, jsxs as jsxs32 } from "react/jsx-runtime";
13071
13204
  function ResourcesTabHeader({
13072
13205
  isSearchExpanded,
13073
13206
  searchQuery,
@@ -13079,7 +13212,7 @@ function ResourcesTabHeader({
13079
13212
  onRefresh,
13080
13213
  isRefreshing = false
13081
13214
  }) {
13082
- return /* @__PURE__ */ jsx54("div", { className: "flex flex-row items-center justify-between p-4 sm:p-4 py-3 gap-2", children: /* @__PURE__ */ jsx54("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: !isSearchExpanded ? /* @__PURE__ */ jsxs32(Fragment11, { children: [
13215
+ return /* @__PURE__ */ jsx54("div", { className: "flex flex-row items-center justify-between p-4 sm:p-4 py-3 gap-2", children: /* @__PURE__ */ jsx54("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: !isSearchExpanded ? /* @__PURE__ */ jsxs32(Fragment12, { children: [
13083
13216
  /* @__PURE__ */ jsx54("h2", { className: "text-lg font-medium text-gray-900 dark:text-gray-100", children: "Resources" }),
13084
13217
  /* @__PURE__ */ jsx54(
13085
13218
  Badge,
@@ -13141,7 +13274,7 @@ function ResourcesTabHeader({
13141
13274
  }
13142
13275
 
13143
13276
  // src/client/components/chat/useConfig.ts
13144
- import { useCallback as useCallback15, useEffect as useEffect16, useState as useState20 } from "react";
13277
+ import { useCallback as useCallback17, useEffect as useEffect17, useState as useState22 } from "react";
13145
13278
 
13146
13279
  // src/client/components/chat/types.ts
13147
13280
  var DEFAULT_MODELS = {
@@ -13237,14 +13370,14 @@ function formatFileSize(bytes) {
13237
13370
 
13238
13371
  // src/client/components/chat/useConfig.ts
13239
13372
  function useConfig({ mcpServerUrl }) {
13240
- const [llmConfig, setLLMConfig] = useState20(null);
13241
- const [authConfig, setAuthConfig] = useState20(null);
13242
- const [configDialogOpen, setConfigDialogOpen] = useState20(false);
13243
- const [tempProvider, setTempProvider] = useState20("openai");
13244
- const [tempApiKey, setTempApiKey] = useState20("");
13245
- const [tempModel, setTempModel] = useState20(DEFAULT_MODELS.openai);
13246
- const [tempBaseUrl, setTempBaseUrl] = useState20(getDefaultBaseUrl("openai"));
13247
- const getApiKeys = useCallback15(() => {
13373
+ const [llmConfig, setLLMConfig] = useState22(null);
13374
+ const [authConfig, setAuthConfig] = useState22(null);
13375
+ const [configDialogOpen, setConfigDialogOpen] = useState22(false);
13376
+ const [tempProvider, setTempProvider] = useState22("openai");
13377
+ const [tempApiKey, setTempApiKey] = useState22("");
13378
+ const [tempModel, setTempModel] = useState22(DEFAULT_MODELS.openai);
13379
+ const [tempBaseUrl, setTempBaseUrl] = useState22(getDefaultBaseUrl("openai"));
13380
+ const getApiKeys = useCallback17(() => {
13248
13381
  const saved = localStorage.getItem("mcp-inspector-api-keys");
13249
13382
  if (saved) {
13250
13383
  try {
@@ -13256,10 +13389,10 @@ function useConfig({ mcpServerUrl }) {
13256
13389
  }
13257
13390
  return {};
13258
13391
  }, []);
13259
- const saveApiKeys = useCallback15((apiKeys) => {
13392
+ const saveApiKeys = useCallback17((apiKeys) => {
13260
13393
  localStorage.setItem("mcp-inspector-api-keys", JSON.stringify(apiKeys));
13261
13394
  }, []);
13262
- const getBaseUrls = useCallback15(() => {
13395
+ const getBaseUrls = useCallback17(() => {
13263
13396
  const saved = localStorage.getItem("mcp-inspector-base-urls");
13264
13397
  if (saved) {
13265
13398
  try {
@@ -13271,14 +13404,14 @@ function useConfig({ mcpServerUrl }) {
13271
13404
  }
13272
13405
  return {};
13273
13406
  }, []);
13274
- const saveBaseUrls = useCallback15((baseUrls) => {
13407
+ const saveBaseUrls = useCallback17((baseUrls) => {
13275
13408
  localStorage.setItem("mcp-inspector-base-urls", JSON.stringify(baseUrls));
13276
13409
  }, []);
13277
- const [tempAuthType, setTempAuthType] = useState20("none");
13278
- const [tempUsername, setTempUsername] = useState20("");
13279
- const [tempPassword, setTempPassword] = useState20("");
13280
- const [tempToken, setTempToken] = useState20("");
13281
- useEffect16(() => {
13410
+ const [tempAuthType, setTempAuthType] = useState22("none");
13411
+ const [tempUsername, setTempUsername] = useState22("");
13412
+ const [tempPassword, setTempPassword] = useState22("");
13413
+ const [tempToken, setTempToken] = useState22("");
13414
+ useEffect17(() => {
13282
13415
  const loadConfig = () => {
13283
13416
  const saved = localStorage.getItem("mcp-inspector-llm-config");
13284
13417
  const apiKeys = getApiKeys();
@@ -13314,7 +13447,7 @@ function useConfig({ mcpServerUrl }) {
13314
13447
  window.removeEventListener("storage", handleStorageChange);
13315
13448
  };
13316
13449
  }, [getApiKeys, getBaseUrls]);
13317
- useEffect16(() => {
13450
+ useEffect17(() => {
13318
13451
  const saved = localStorage.getItem("mcp-inspector-auth-config");
13319
13452
  if (saved) {
13320
13453
  try {
@@ -13343,7 +13476,7 @@ function useConfig({ mcpServerUrl }) {
13343
13476
  }
13344
13477
  }
13345
13478
  }, [mcpServerUrl]);
13346
- useEffect16(() => {
13479
+ useEffect17(() => {
13347
13480
  if (!providerSupportsBaseUrl(tempProvider)) {
13348
13481
  setTempModel(DEFAULT_MODELS[tempProvider]);
13349
13482
  }
@@ -13352,7 +13485,7 @@ function useConfig({ mcpServerUrl }) {
13352
13485
  setTempApiKey(apiKeys[tempProvider] || "");
13353
13486
  setTempBaseUrl(baseUrls[tempProvider] || getDefaultBaseUrl(tempProvider));
13354
13487
  }, [tempProvider, getApiKeys, getBaseUrls]);
13355
- const saveLLMConfig = useCallback15(() => {
13488
+ const saveLLMConfig = useCallback17(() => {
13356
13489
  if (providerRequiresApiKey(tempProvider) && !tempApiKey.trim()) {
13357
13490
  return;
13358
13491
  }
@@ -13419,7 +13552,7 @@ function useConfig({ mcpServerUrl }) {
13419
13552
  getBaseUrls,
13420
13553
  saveBaseUrls
13421
13554
  ]);
13422
- const clearConfig = useCallback15(() => {
13555
+ const clearConfig = useCallback17(() => {
13423
13556
  setLLMConfig(null);
13424
13557
  setAuthConfig(null);
13425
13558
  const apiKeys = getApiKeys();
@@ -13457,7 +13590,7 @@ function useConfig({ mcpServerUrl }) {
13457
13590
  }
13458
13591
 
13459
13592
  // src/client/components/ResourcesTab.tsx
13460
- import { Fragment as Fragment12, jsx as jsx55, jsxs as jsxs33 } from "react/jsx-runtime";
13593
+ import { Fragment as Fragment13, jsx as jsx55, jsxs as jsxs33 } from "react/jsx-runtime";
13461
13594
  function ResourcesTab({
13462
13595
  ref,
13463
13596
  resources,
@@ -13467,27 +13600,27 @@ function ResourcesTab({
13467
13600
  mcpServerUrl,
13468
13601
  refreshResources
13469
13602
  }) {
13470
- const [isRefreshing, setIsRefreshing] = useState21(false);
13471
- const [selectedResource, setSelectedResource] = useState21(
13603
+ const [isRefreshing, setIsRefreshing] = useState23(false);
13604
+ const [selectedResource, setSelectedResource] = useState23(
13472
13605
  null
13473
13606
  );
13474
13607
  const { selectedResourceUri, setSelectedResourceUri } = useInspector();
13475
13608
  const { llmConfig } = useConfig({ mcpServerUrl });
13476
- const [currentResult, setCurrentResult] = useState21(
13609
+ const [currentResult, setCurrentResult] = useState23(
13477
13610
  null
13478
13611
  );
13479
- const [isLoading, setIsLoading] = useState21(false);
13480
- const [searchQuery, setSearchQuery] = useState21("");
13481
- const [activeTab] = useState21("resources");
13482
- const [previewMode, setPreviewMode] = useState21(true);
13483
- const [isSearchExpanded, setIsSearchExpanded] = useState21(false);
13484
- const [focusedIndex, setFocusedIndex] = useState21(-1);
13485
- const [isCopied, setIsCopied] = useState21(false);
13486
- const searchInputRef = useRef13(null);
13487
- const resourceDisplayRef = useRef13(null);
13488
- const [isMobile, setIsMobile] = useState21(false);
13489
- const [mobileView, setMobileView] = useState21("list");
13490
- useEffect17(() => {
13612
+ const [isLoading, setIsLoading] = useState23(false);
13613
+ const [searchQuery, setSearchQuery] = useState23("");
13614
+ const [activeTab] = useState23("resources");
13615
+ const [previewMode, setPreviewMode] = useState23(true);
13616
+ const [isSearchExpanded, setIsSearchExpanded] = useState23(false);
13617
+ const [focusedIndex, setFocusedIndex] = useState23(-1);
13618
+ const [isCopied, setIsCopied] = useState23(false);
13619
+ const searchInputRef = useRef14(null);
13620
+ const resourceDisplayRef = useRef14(null);
13621
+ const [isMobile, setIsMobile] = useState23(false);
13622
+ const [mobileView, setMobileView] = useState23("list");
13623
+ useEffect18(() => {
13491
13624
  const checkMobile = () => {
13492
13625
  setIsMobile(window.innerWidth < 1024);
13493
13626
  };
@@ -13495,7 +13628,7 @@ function ResourcesTab({
13495
13628
  window.addEventListener("resize", checkMobile);
13496
13629
  return () => window.removeEventListener("resize", checkMobile);
13497
13630
  }, []);
13498
- useEffect17(() => {
13631
+ useEffect18(() => {
13499
13632
  if (selectedResource) {
13500
13633
  setMobileView("detail");
13501
13634
  } else {
@@ -13519,17 +13652,17 @@ function ResourcesTab({
13519
13652
  }
13520
13653
  }
13521
13654
  }));
13522
- useEffect17(() => {
13655
+ useEffect18(() => {
13523
13656
  if (isSearchExpanded && searchInputRef.current) {
13524
13657
  searchInputRef.current.focus();
13525
13658
  }
13526
13659
  }, [isSearchExpanded]);
13527
- const handleSearchBlur = useCallback16(() => {
13660
+ const handleSearchBlur = useCallback18(() => {
13528
13661
  if (!searchQuery.trim()) {
13529
13662
  setIsSearchExpanded(false);
13530
13663
  }
13531
13664
  }, [searchQuery]);
13532
- const handleRefresh = useCallback16(async () => {
13665
+ const handleRefresh = useCallback18(async () => {
13533
13666
  if (!refreshResources) return;
13534
13667
  setIsRefreshing(true);
13535
13668
  try {
@@ -13545,7 +13678,7 @@ function ResourcesTab({
13545
13678
  (resource) => resource.name.toLowerCase().includes(query) || resource.description?.toLowerCase().includes(query) || resource.uri.toLowerCase().includes(query)
13546
13679
  );
13547
13680
  }, [resources, searchQuery]);
13548
- const handleResourceSelect = useCallback16(
13681
+ const handleResourceSelect = useCallback18(
13549
13682
  async (resource) => {
13550
13683
  setSelectedResource(resource);
13551
13684
  if (isConnected) {
@@ -13602,10 +13735,10 @@ function ResourcesTab({
13602
13735
  },
13603
13736
  [readResource, serverId, isConnected]
13604
13737
  );
13605
- useEffect17(() => {
13738
+ useEffect18(() => {
13606
13739
  setFocusedIndex(-1);
13607
13740
  }, [searchQuery, activeTab]);
13608
- useEffect17(() => {
13741
+ useEffect18(() => {
13609
13742
  const handleKeyDown = (e) => {
13610
13743
  const target = e.target;
13611
13744
  const isInputFocused = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.contentEditable === "true";
@@ -13636,7 +13769,7 @@ function ResourcesTab({
13636
13769
  document.addEventListener("keydown", handleKeyDown);
13637
13770
  return () => document.removeEventListener("keydown", handleKeyDown);
13638
13771
  }, [focusedIndex, filteredResources, handleResourceSelect]);
13639
- useEffect17(() => {
13772
+ useEffect18(() => {
13640
13773
  if (focusedIndex >= 0) {
13641
13774
  const itemId = `resource-${filteredResources[focusedIndex]?.uri}`;
13642
13775
  const element = document.getElementById(itemId);
@@ -13645,7 +13778,7 @@ function ResourcesTab({
13645
13778
  }
13646
13779
  }
13647
13780
  }, [focusedIndex, filteredResources]);
13648
- useEffect17(() => {
13781
+ useEffect18(() => {
13649
13782
  if (selectedResourceUri && resources.length > 0) {
13650
13783
  const resource = resources.find((r) => r.uri === selectedResourceUri);
13651
13784
  if (resource && selectedResource?.uri !== resource.uri) {
@@ -13669,7 +13802,7 @@ function ResourcesTab({
13669
13802
  handleResourceSelect,
13670
13803
  setSelectedResourceUri
13671
13804
  ]);
13672
- useEffect17(() => {
13805
+ useEffect18(() => {
13673
13806
  if (selectedResource) {
13674
13807
  const updatedResource = resources.find(
13675
13808
  (r) => r.uri === selectedResource.uri
@@ -13682,7 +13815,7 @@ function ResourcesTab({
13682
13815
  }
13683
13816
  }
13684
13817
  }, [resources, selectedResource]);
13685
- const handleCopy = useCallback16(async () => {
13818
+ const handleCopy = useCallback18(async () => {
13686
13819
  if (!currentResult) return;
13687
13820
  try {
13688
13821
  await copyToClipboard(JSON.stringify(currentResult.result, null, 2));
@@ -13692,7 +13825,7 @@ function ResourcesTab({
13692
13825
  console.error("[ResourcesTab] Failed to copy result:", error);
13693
13826
  }
13694
13827
  }, [currentResult]);
13695
- const handleDownload = useCallback16(() => {
13828
+ const handleDownload = useCallback18(() => {
13696
13829
  if (!currentResult) return;
13697
13830
  try {
13698
13831
  const blob = new globalThis.Blob(
@@ -13713,7 +13846,7 @@ function ResourcesTab({
13713
13846
  console.error("[ResourcesTab] Failed to download result:", error);
13714
13847
  }
13715
13848
  }, [currentResult]);
13716
- const handleFullscreen = useCallback16(async () => {
13849
+ const handleFullscreen = useCallback18(async () => {
13717
13850
  if (!resourceDisplayRef.current) return;
13718
13851
  try {
13719
13852
  if (!document.fullscreenElement) {
@@ -13753,7 +13886,7 @@ function ResourcesTab({
13753
13886
  children: "Resources"
13754
13887
  }
13755
13888
  ),
13756
- mobileView === "detail" && /* @__PURE__ */ jsxs33(Fragment12, { children: [
13889
+ mobileView === "detail" && /* @__PURE__ */ jsxs33(Fragment13, { children: [
13757
13890
  /* @__PURE__ */ jsx55("span", { className: "mx-2 text-muted-foreground", children: "/" }),
13758
13891
  /* @__PURE__ */ jsx55("span", { className: "text-foreground", children: "Content" })
13759
13892
  ] })
@@ -13903,11 +14036,11 @@ ResourcesTab.displayName = "ResourcesTab";
13903
14036
  import { AnimatePresence as AnimatePresence3, motion as motion4 } from "motion/react";
13904
14037
  import { ChevronLeft as ChevronLeft3 } from "lucide-react";
13905
14038
  import {
13906
- useCallback as useCallback18,
13907
- useEffect as useEffect21,
14039
+ useCallback as useCallback20,
14040
+ useEffect as useEffect22,
13908
14041
  useImperativeHandle as useImperativeHandle4,
13909
- useRef as useRef14,
13910
- useState as useState26
14042
+ useRef as useRef15,
14043
+ useState as useState28
13911
14044
  } from "react";
13912
14045
 
13913
14046
  // src/client/components/prompts/PromptsList.tsx
@@ -14029,7 +14162,7 @@ function SavedPromptsList({
14029
14162
 
14030
14163
  // src/client/components/prompts/PromptExecutionPanel.tsx
14031
14164
  import { Play as Play3, Save as Save3 } from "lucide-react";
14032
- import { useEffect as useEffect18 } from "react";
14165
+ import { useEffect as useEffect19 } from "react";
14033
14166
 
14034
14167
  // src/client/components/prompts/PromptInputForm.tsx
14035
14168
  import { jsx as jsx59, jsxs as jsxs36 } from "react/jsx-runtime";
@@ -14136,7 +14269,7 @@ function PromptInputForm({
14136
14269
  }
14137
14270
 
14138
14271
  // src/client/components/prompts/PromptExecutionPanel.tsx
14139
- import { Fragment as Fragment13, jsx as jsx60, jsxs as jsxs37 } from "react/jsx-runtime";
14272
+ import { Fragment as Fragment14, jsx as jsx60, jsxs as jsxs37 } from "react/jsx-runtime";
14140
14273
  function PromptExecutionPanel({
14141
14274
  selectedPrompt,
14142
14275
  promptArgs,
@@ -14146,7 +14279,7 @@ function PromptExecutionPanel({
14146
14279
  onExecute,
14147
14280
  onSave
14148
14281
  }) {
14149
- useEffect18(() => {
14282
+ useEffect19(() => {
14150
14283
  const handleKeyDown = (event) => {
14151
14284
  if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
14152
14285
  if (selectedPrompt && !isExecuting && isConnected) {
@@ -14177,10 +14310,10 @@ function PromptExecutionPanel({
14177
14310
  size: "sm",
14178
14311
  className: "lg:size-default pr-1! gap-0",
14179
14312
  "data-testid": "prompt-execute-button",
14180
- children: isExecuting ? /* @__PURE__ */ jsxs37(Fragment13, { children: [
14313
+ children: isExecuting ? /* @__PURE__ */ jsxs37(Fragment14, { children: [
14181
14314
  /* @__PURE__ */ jsx60(Spinner, { className: "mr-2" }),
14182
14315
  /* @__PURE__ */ jsx60("span", { className: "hidden sm:inline", children: "Executing..." })
14183
- ] }) : /* @__PURE__ */ jsxs37(Fragment13, { children: [
14316
+ ] }) : /* @__PURE__ */ jsxs37(Fragment14, { children: [
14184
14317
  /* @__PURE__ */ jsx60(Play3, { className: "h-4 w-4 sm:mr-2" }),
14185
14318
  /* @__PURE__ */ jsx60("span", { className: "hidden sm:inline", children: "Execute" }),
14186
14319
  /* @__PURE__ */ jsx60("span", { className: "hidden sm:inline text-[12px] border text-zinc-300 p-1 rounded-full border-zinc-300 dark:text-zinc-600 dark:border-zinc-500 ml-2", children: "\u2318\u21B5" })
@@ -14226,16 +14359,16 @@ import {
14226
14359
  Trash2 as Trash25,
14227
14360
  Zap as Zap3
14228
14361
  } from "lucide-react";
14229
- import { useEffect as useEffect19, useState as useState24 } from "react";
14362
+ import { useEffect as useEffect20, useState as useState26 } from "react";
14230
14363
 
14231
14364
  // src/client/components/prompts/PromptMessageCard.tsx
14232
14365
  import { Check as Check7, Copy as Copy10 } from "lucide-react";
14233
- import { useState as useState23 } from "react";
14366
+ import { useState as useState25 } from "react";
14234
14367
 
14235
14368
  // src/client/components/shared/MarkdownRenderer.tsx
14236
14369
  import { Check as Check6, Copy as Copy9 } from "lucide-react";
14237
14370
  import Markdown from "markdown-to-jsx";
14238
- import { useState as useState22 } from "react";
14371
+ import { useState as useState24 } from "react";
14239
14372
  import { Prism as SyntaxHighlighter2 } from "react-syntax-highlighter";
14240
14373
 
14241
14374
  // src/client/components/ui/checkbox.tsx
@@ -14321,7 +14454,7 @@ var TableCell = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE_
14321
14454
  TableCell.displayName = "TableCell";
14322
14455
 
14323
14456
  // src/client/components/shared/MarkdownRenderer.tsx
14324
- import { Fragment as Fragment14, jsx as jsx63, jsxs as jsxs38 } from "react/jsx-runtime";
14457
+ import { Fragment as Fragment15, jsx as jsx63, jsxs as jsxs38 } from "react/jsx-runtime";
14325
14458
  function CodeBlock({
14326
14459
  children,
14327
14460
  className
@@ -14336,7 +14469,7 @@ function CodeBlock({
14336
14469
  language = className.replace(/^(lang-|language-)\s*/, "").trim();
14337
14470
  }
14338
14471
  }
14339
- const [isCopied, setIsCopied] = useState22(false);
14472
+ const [isCopied, setIsCopied] = useState24(false);
14340
14473
  const codeContent = String(children).trim();
14341
14474
  const handleCopy = async () => {
14342
14475
  await copyToClipboard(codeContent);
@@ -14425,7 +14558,7 @@ function MarkdownRenderer({ content }) {
14425
14558
  options: {
14426
14559
  overrides: {
14427
14560
  code: Code3,
14428
- pre: ({ children }) => /* @__PURE__ */ jsx63(Fragment14, { children }),
14561
+ pre: ({ children }) => /* @__PURE__ */ jsx63(Fragment15, { children }),
14429
14562
  h1: ({ children }) => /* @__PURE__ */ jsx63("h1", { className: "text-xl font-bold text-foreground mb-2 mt-4", children }),
14430
14563
  h2: ({ children }) => /* @__PURE__ */ jsx63("h2", { className: "text-lg font-bold text-foreground mb-2 mt-4", children }),
14431
14564
  h3: ({ children }) => /* @__PURE__ */ jsx63("h3", { className: "text-base font-bold text-foreground mb-2 mt-4", children }),
@@ -14511,7 +14644,7 @@ function extractTextFromContent(content) {
14511
14644
  return JSON.stringify(content, null, 2);
14512
14645
  }
14513
14646
  function PromptMessageCard({ message, index }) {
14514
- const [isCopied, setIsCopied] = useState23(false);
14647
+ const [isCopied, setIsCopied] = useState25(false);
14515
14648
  const handleCopy = async () => {
14516
14649
  const text = extractTextFromContent(message.content);
14517
14650
  await copyToClipboard(text);
@@ -14617,19 +14750,19 @@ function PromptResultDisplay({
14617
14750
  onMaximize,
14618
14751
  isMaximized = false
14619
14752
  }) {
14620
- const [selectedIndex, setSelectedIndex] = useState24(0);
14621
- const [relativeTime, setRelativeTime] = useState24("");
14622
- const [formattedMode, setFormattedMode] = useState24(true);
14753
+ const [selectedIndex, setSelectedIndex] = useState26(0);
14754
+ const [relativeTime, setRelativeTime] = useState26("");
14755
+ const [formattedMode, setFormattedMode] = useState26(true);
14623
14756
  const currentResult = results[0];
14624
14757
  const promptResults = currentResult ? results.filter((r) => r.promptName === currentResult.promptName) : [];
14625
14758
  const result = promptResults[selectedIndex] || promptResults[0];
14626
14759
  const originalResultIndex = results.findIndex((r) => r === result);
14627
- useEffect19(() => {
14760
+ useEffect20(() => {
14628
14761
  if (promptResults.length > 0 && selectedIndex >= promptResults.length) {
14629
14762
  setSelectedIndex(0);
14630
14763
  }
14631
14764
  }, [promptResults.length, selectedIndex]);
14632
- useEffect19(() => {
14765
+ useEffect20(() => {
14633
14766
  const updateTime = () => {
14634
14767
  if (result) {
14635
14768
  setRelativeTime(getRelativeTime2(result.timestamp));
@@ -14756,17 +14889,17 @@ function PromptResultDisplay({
14756
14889
  }
14757
14890
 
14758
14891
  // src/client/hooks/useMCPPrompts.ts
14759
- import { useState as useState25, useCallback as useCallback17, useEffect as useEffect20, useMemo as useMemo17 } from "react";
14892
+ import { useState as useState27, useCallback as useCallback19, useEffect as useEffect21, useMemo as useMemo17 } from "react";
14760
14893
  function useMCPPrompts({
14761
14894
  prompts,
14762
14895
  callPrompt,
14763
14896
  serverId
14764
14897
  }) {
14765
- const [selectedPrompt, setSelectedPrompt] = useState25(null);
14766
- const [promptArgs, setPromptArgs] = useState25({});
14767
- const [results, setResults] = useState25([]);
14768
- const [isExecuting, setIsExecuting] = useState25(false);
14769
- const [searchQuery, setSearchQuery] = useState25("");
14898
+ const [selectedPrompt, setSelectedPrompt] = useState27(null);
14899
+ const [promptArgs, setPromptArgs] = useState27({});
14900
+ const [results, setResults] = useState27([]);
14901
+ const [isExecuting, setIsExecuting] = useState27(false);
14902
+ const [searchQuery, setSearchQuery] = useState27("");
14770
14903
  const filteredPrompts = useMemo17(() => {
14771
14904
  if (!searchQuery.trim()) return prompts;
14772
14905
  const query = searchQuery.toLowerCase();
@@ -14774,7 +14907,7 @@ function useMCPPrompts({
14774
14907
  (prompt) => prompt.name.toLowerCase().includes(query) || prompt.description?.toLowerCase().includes(query)
14775
14908
  );
14776
14909
  }, [prompts, searchQuery]);
14777
- const handlePromptSelect = useCallback17((prompt) => {
14910
+ const handlePromptSelect = useCallback19((prompt) => {
14778
14911
  setSelectedPrompt(prompt);
14779
14912
  const initialArgs = {};
14780
14913
  if (prompt.arguments) {
@@ -14784,10 +14917,10 @@ function useMCPPrompts({
14784
14917
  }
14785
14918
  setPromptArgs(initialArgs);
14786
14919
  }, []);
14787
- const handleArgChange = useCallback17((key, value) => {
14920
+ const handleArgChange = useCallback19((key, value) => {
14788
14921
  setPromptArgs((prev) => ({ ...prev, [key]: value }));
14789
14922
  }, []);
14790
- const executePrompt = useCallback17(
14923
+ const executePrompt = useCallback19(
14791
14924
  async (prompt, args) => {
14792
14925
  if (isExecuting) return;
14793
14926
  setIsExecuting(true);
@@ -14841,13 +14974,13 @@ function useMCPPrompts({
14841
14974
  },
14842
14975
  [isExecuting, callPrompt, serverId]
14843
14976
  );
14844
- const handleDeleteResult = useCallback17((index) => {
14977
+ const handleDeleteResult = useCallback19((index) => {
14845
14978
  setResults((prev) => prev.filter((_, i) => i !== index));
14846
14979
  }, []);
14847
- const clearPromptResults = useCallback17(() => {
14980
+ const clearPromptResults = useCallback19(() => {
14848
14981
  setResults([]);
14849
14982
  }, []);
14850
- useEffect20(() => {
14983
+ useEffect21(() => {
14851
14984
  if (selectedPrompt) {
14852
14985
  const updatedPrompt = prompts.find((p) => p.name === selectedPrompt.name);
14853
14986
  if (!updatedPrompt) {
@@ -14862,7 +14995,7 @@ function useMCPPrompts({
14862
14995
  }
14863
14996
  }
14864
14997
  }, [prompts, selectedPrompt]);
14865
- const executeSelectedPrompt = useCallback17(async () => {
14998
+ const executeSelectedPrompt = useCallback19(async () => {
14866
14999
  if (!selectedPrompt || isExecuting) return;
14867
15000
  executePrompt(selectedPrompt, promptArgs);
14868
15001
  }, [selectedPrompt, promptArgs, isExecuting, executePrompt]);
@@ -14886,7 +15019,7 @@ function useMCPPrompts({
14886
15019
  }
14887
15020
 
14888
15021
  // src/client/components/PromptsTab.tsx
14889
- import { Fragment as Fragment15, jsx as jsx66, jsxs as jsxs41 } from "react/jsx-runtime";
15022
+ import { Fragment as Fragment16, jsx as jsx66, jsxs as jsxs41 } from "react/jsx-runtime";
14890
15023
  var SAVED_PROMPTS_KEY = "mcp-inspector-saved-prompts";
14891
15024
  function PromptsTab({
14892
15025
  ref,
@@ -14896,22 +15029,22 @@ function PromptsTab({
14896
15029
  isConnected,
14897
15030
  refreshPrompts
14898
15031
  }) {
14899
- const [isRefreshing, setIsRefreshing] = useState26(false);
14900
- const [selectedSavedPrompt, setSelectedSavedPrompt] = useState26(null);
15032
+ const [isRefreshing, setIsRefreshing] = useState28(false);
15033
+ const [selectedSavedPrompt, setSelectedSavedPrompt] = useState28(null);
14901
15034
  const { selectedPromptName, setSelectedPromptName } = useInspector();
14902
- const [copiedResult, setCopiedResult] = useState26(null);
14903
- const [activeTab, setActiveTab] = useState26("prompts");
14904
- const [savedPrompts, setSavedPrompts] = useState26([]);
14905
- const [_saveDialogOpen, setSaveDialogOpen] = useState26(false);
14906
- const [_promptName, setPromptName] = useState26("");
14907
- const [isSearchExpanded, setIsSearchExpanded] = useState26(false);
14908
- const [focusedIndex, setFocusedIndex] = useState26(-1);
14909
- const searchInputRef = useRef14(null);
14910
- const [isMobile, setIsMobile] = useState26(false);
14911
- const [mobileView, setMobileView] = useState26(
15035
+ const [copiedResult, setCopiedResult] = useState28(null);
15036
+ const [activeTab, setActiveTab] = useState28("prompts");
15037
+ const [savedPrompts, setSavedPrompts] = useState28([]);
15038
+ const [_saveDialogOpen, setSaveDialogOpen] = useState28(false);
15039
+ const [_promptName, setPromptName] = useState28("");
15040
+ const [isSearchExpanded, setIsSearchExpanded] = useState28(false);
15041
+ const [focusedIndex, setFocusedIndex] = useState28(-1);
15042
+ const searchInputRef = useRef15(null);
15043
+ const [isMobile, setIsMobile] = useState28(false);
15044
+ const [mobileView, setMobileView] = useState28(
14912
15045
  "list"
14913
15046
  );
14914
- const [isMaximized, setIsMaximized] = useState26(false);
15047
+ const [isMaximized, setIsMaximized] = useState28(false);
14915
15048
  const {
14916
15049
  filteredPrompts,
14917
15050
  selectedPrompt,
@@ -14929,7 +15062,7 @@ function PromptsTab({
14929
15062
  } = useMCPPrompts({ prompts, callPrompt, serverId });
14930
15063
  const leftPanelRef = usePanelRef();
14931
15064
  const toolParamsPanelRef = usePanelRef();
14932
- useEffect21(() => {
15065
+ useEffect22(() => {
14933
15066
  const checkMobile = () => {
14934
15067
  setIsMobile(window.innerWidth < 1024);
14935
15068
  };
@@ -14937,14 +15070,14 @@ function PromptsTab({
14937
15070
  window.addEventListener("resize", checkMobile);
14938
15071
  return () => window.removeEventListener("resize", checkMobile);
14939
15072
  }, []);
14940
- useEffect21(() => {
15073
+ useEffect22(() => {
14941
15074
  if (selectedPrompt) {
14942
15075
  setMobileView("detail");
14943
15076
  } else {
14944
15077
  setMobileView("list");
14945
15078
  }
14946
15079
  }, [selectedPrompt]);
14947
- useEffect21(() => {
15080
+ useEffect22(() => {
14948
15081
  if (isMobile && results.length > 0 && !isExecuting) {
14949
15082
  setMobileView("response");
14950
15083
  }
@@ -14966,7 +15099,7 @@ function PromptsTab({
14966
15099
  }
14967
15100
  }
14968
15101
  }));
14969
- useEffect21(() => {
15102
+ useEffect22(() => {
14970
15103
  try {
14971
15104
  const saved = localStorage.getItem(SAVED_PROMPTS_KEY);
14972
15105
  if (saved) {
@@ -14977,24 +15110,24 @@ function PromptsTab({
14977
15110
  console.error("[PromptsTab] Failed to load saved prompts:", error);
14978
15111
  }
14979
15112
  }, []);
14980
- const saveSavedPrompts = useCallback18((prompts2) => {
15113
+ const saveSavedPrompts = useCallback20((prompts2) => {
14981
15114
  try {
14982
15115
  localStorage.setItem(SAVED_PROMPTS_KEY, JSON.stringify(prompts2));
14983
15116
  } catch (error) {
14984
15117
  console.error("[PromptsTab] Failed to save prompts:", error);
14985
15118
  }
14986
15119
  }, []);
14987
- useEffect21(() => {
15120
+ useEffect22(() => {
14988
15121
  if (isSearchExpanded && searchInputRef.current) {
14989
15122
  searchInputRef.current.focus();
14990
15123
  }
14991
15124
  }, [isSearchExpanded]);
14992
- const handleSearchBlur = useCallback18(() => {
15125
+ const handleSearchBlur = useCallback20(() => {
14993
15126
  if (!searchQuery.trim()) {
14994
15127
  setIsSearchExpanded(false);
14995
15128
  }
14996
15129
  }, [searchQuery]);
14997
- const handleRefresh = useCallback18(async () => {
15130
+ const handleRefresh = useCallback20(async () => {
14998
15131
  if (!refreshPrompts) return;
14999
15132
  setIsRefreshing(true);
15000
15133
  try {
@@ -15003,7 +15136,7 @@ function PromptsTab({
15003
15136
  setIsRefreshing(false);
15004
15137
  }
15005
15138
  }, [refreshPrompts]);
15006
- const loadSavedPrompt = useCallback18(
15139
+ const loadSavedPrompt = useCallback20(
15007
15140
  (prompt) => {
15008
15141
  const promptObj = prompts.find((p) => p.name === prompt.promptName);
15009
15142
  if (promptObj) {
@@ -15014,10 +15147,10 @@ function PromptsTab({
15014
15147
  },
15015
15148
  [prompts, setSelectedPrompt, setPromptArgs]
15016
15149
  );
15017
- useEffect21(() => {
15150
+ useEffect22(() => {
15018
15151
  setFocusedIndex(-1);
15019
15152
  }, [searchQuery, activeTab]);
15020
- useEffect21(() => {
15153
+ useEffect22(() => {
15021
15154
  const handleKeyDown = (e) => {
15022
15155
  const target = e.target;
15023
15156
  const isInputFocused = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.contentEditable === "true";
@@ -15062,7 +15195,7 @@ function PromptsTab({
15062
15195
  handlePromptSelect,
15063
15196
  loadSavedPrompt
15064
15197
  ]);
15065
- useEffect21(() => {
15198
+ useEffect22(() => {
15066
15199
  if (focusedIndex >= 0) {
15067
15200
  const itemId = activeTab === "prompts" ? `prompt-${filteredPrompts[focusedIndex]?.name}` : `saved-prompt-${savedPrompts[focusedIndex]?.id}`;
15068
15201
  const element = document.getElementById(itemId);
@@ -15071,7 +15204,7 @@ function PromptsTab({
15071
15204
  }
15072
15205
  }
15073
15206
  }, [focusedIndex, filteredPrompts, savedPrompts, activeTab]);
15074
- useEffect21(() => {
15207
+ useEffect22(() => {
15075
15208
  console.warn("[PromptsTab] Auto-selection effect triggered:", {
15076
15209
  selectedPromptName,
15077
15210
  promptsCount: prompts.length,
@@ -15111,7 +15244,7 @@ function PromptsTab({
15111
15244
  handlePromptSelect,
15112
15245
  setSelectedPromptName
15113
15246
  ]);
15114
- const handleCopyResult = useCallback18(async (index, result) => {
15247
+ const handleCopyResult = useCallback20(async (index, result) => {
15115
15248
  try {
15116
15249
  await copyToClipboard(JSON.stringify(result, null, 2));
15117
15250
  setCopiedResult(index);
@@ -15120,7 +15253,7 @@ function PromptsTab({
15120
15253
  console.error("[PromptsTab] Failed to copy result:", error);
15121
15254
  }
15122
15255
  }, []);
15123
- const handleFullscreen = useCallback18(
15256
+ const handleFullscreen = useCallback20(
15124
15257
  (index) => {
15125
15258
  if (isMobile) {
15126
15259
  setMobileView("response");
@@ -15152,7 +15285,7 @@ function PromptsTab({
15152
15285
  },
15153
15286
  [isMobile, results]
15154
15287
  );
15155
- const handleMaximize = useCallback18(() => {
15288
+ const handleMaximize = useCallback20(() => {
15156
15289
  if (!isMaximized) {
15157
15290
  if (leftPanelRef.current) {
15158
15291
  leftPanelRef.current.collapse();
@@ -15171,12 +15304,12 @@ function PromptsTab({
15171
15304
  setIsMaximized(false);
15172
15305
  }
15173
15306
  }, [isMaximized, leftPanelRef, toolParamsPanelRef]);
15174
- const openSaveDialog = useCallback18(() => {
15307
+ const openSaveDialog = useCallback20(() => {
15175
15308
  if (!selectedPrompt) return;
15176
15309
  setPromptName("");
15177
15310
  setSaveDialogOpen(true);
15178
15311
  }, [selectedPrompt]);
15179
- const deleteSavedPrompt = useCallback18(
15312
+ const deleteSavedPrompt = useCallback20(
15180
15313
  (id) => {
15181
15314
  saveSavedPrompts(savedPrompts.filter((p) => p.id !== id));
15182
15315
  if (selectedSavedPrompt?.id === id) {
@@ -15217,7 +15350,7 @@ function PromptsTab({
15217
15350
  children: "Prompts"
15218
15351
  }
15219
15352
  ),
15220
- mobileView === "detail" && /* @__PURE__ */ jsxs41(Fragment15, { children: [
15353
+ mobileView === "detail" && /* @__PURE__ */ jsxs41(Fragment16, { children: [
15221
15354
  /* @__PURE__ */ jsx66("span", { className: "mx-2 text-muted-foreground", children: "/" }),
15222
15355
  /* @__PURE__ */ jsx66(
15223
15356
  "button",
@@ -15230,7 +15363,7 @@ function PromptsTab({
15230
15363
  }
15231
15364
  )
15232
15365
  ] }),
15233
- mobileView === "response" && /* @__PURE__ */ jsxs41(Fragment15, { children: [
15366
+ mobileView === "response" && /* @__PURE__ */ jsxs41(Fragment16, { children: [
15234
15367
  /* @__PURE__ */ jsx66("span", { className: "mx-2 text-muted-foreground", children: "/" }),
15235
15368
  /* @__PURE__ */ jsx66("span", { className: "text-foreground", children: "Response" })
15236
15369
  ] })
@@ -15433,18 +15566,18 @@ PromptsTab.displayName = "PromptsTab";
15433
15566
 
15434
15567
  // src/client/components/ChatTab.tsx
15435
15568
  import {
15436
- useCallback as useCallback26,
15437
- useEffect as useEffect27,
15569
+ useCallback as useCallback28,
15570
+ useEffect as useEffect28,
15438
15571
  useMemo as useMemo20,
15439
- useRef as useRef20,
15440
- useState as useState36
15572
+ useRef as useRef21,
15573
+ useState as useState38
15441
15574
  } from "react";
15442
15575
  import { toast as toast7 } from "sonner";
15443
15576
 
15444
15577
  // src/client/hooks/useKeyboardShortcuts.ts
15445
- import { useEffect as useEffect22 } from "react";
15578
+ import { useEffect as useEffect23 } from "react";
15446
15579
  function useKeyboardShortcuts(handlers) {
15447
- useEffect22(() => {
15580
+ useEffect23(() => {
15448
15581
  const handleKeyDown = (event) => {
15449
15582
  const target = event.target;
15450
15583
  const isInputFocused = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.contentEditable === "true";
@@ -15511,7 +15644,7 @@ import { Copy as Copy12, Download as Download3, SquarePen } from "lucide-react";
15511
15644
 
15512
15645
  // src/client/components/chat/ConfigurationDialog.tsx
15513
15646
  import { Check as Check9, ChevronsUpDown, Eye, EyeOff, Key, Loader2 as Loader22 } from "lucide-react";
15514
- import { useEffect as useEffect23, useState as useState27 } from "react";
15647
+ import { useEffect as useEffect24, useState as useState29 } from "react";
15515
15648
 
15516
15649
  // src/client/components/chat/providerMeta.tsx
15517
15650
  import { jsx as jsx67 } from "react/jsx-runtime";
@@ -15765,13 +15898,13 @@ function ConfigurationDialog({
15765
15898
  buttonLabel: _buttonLabel = "Configure API Key",
15766
15899
  freeTierInfo
15767
15900
  }) {
15768
- const [models, setModels] = useState27([]);
15769
- const [isLoadingModels, setIsLoadingModels] = useState27(false);
15770
- const [modelError, setModelError] = useState27(null);
15771
- const [comboboxOpen, setComboboxOpen] = useState27(false);
15772
- const [showPassword, setShowPassword] = useState27(false);
15901
+ const [models, setModels] = useState29([]);
15902
+ const [isLoadingModels, setIsLoadingModels] = useState29(false);
15903
+ const [modelError, setModelError] = useState29(null);
15904
+ const [comboboxOpen, setComboboxOpen] = useState29(false);
15905
+ const [showPassword, setShowPassword] = useState29(false);
15773
15906
  const modelsCacheKey = getModelsCacheKey(tempProvider, tempBaseUrl);
15774
- useEffect23(() => {
15907
+ useEffect24(() => {
15775
15908
  const needsApiKey = providerRequiresApiKey(tempProvider);
15776
15909
  const needsBaseUrl = providerSupportsBaseUrl(tempProvider);
15777
15910
  if (!open || !tempProvider || needsApiKey && !tempApiKey.trim() || needsBaseUrl && !tempBaseUrl.trim()) {
@@ -15820,7 +15953,7 @@ function ConfigurationDialog({
15820
15953
  const timeoutId = setTimeout(loadModels, 500);
15821
15954
  return () => clearTimeout(timeoutId);
15822
15955
  }, [tempApiKey, tempBaseUrl, tempProvider, open, modelsCacheKey]);
15823
- useEffect23(() => {
15956
+ useEffect24(() => {
15824
15957
  if (open) {
15825
15958
  onModelChange("");
15826
15959
  }
@@ -16183,11 +16316,11 @@ import { Send, Square } from "lucide-react";
16183
16316
 
16184
16317
  // src/client/components/chat/ChatInput.tsx
16185
16318
  import { Image as ImageIcon, Paperclip, X as X6 } from "lucide-react";
16186
- import { useRef as useRef15 } from "react";
16319
+ import { useRef as useRef16 } from "react";
16187
16320
 
16188
16321
  // src/client/components/chat/ToolSelector.tsx
16189
16322
  import { Wrench as Wrench3 } from "lucide-react";
16190
- import { useCallback as useCallback19, useMemo as useMemo18, useState as useState28 } from "react";
16323
+ import { useCallback as useCallback21, useMemo as useMemo18, useState as useState30 } from "react";
16191
16324
  import { jsx as jsx70, jsxs as jsxs44 } from "react/jsx-runtime";
16192
16325
  function ToolSelector({
16193
16326
  tools,
@@ -16195,11 +16328,11 @@ function ToolSelector({
16195
16328
  onDisabledToolsChange,
16196
16329
  disabled
16197
16330
  }) {
16198
- const [open, setOpen] = useState28(false);
16331
+ const [open, setOpen] = useState30(false);
16199
16332
  const enabledCount = tools.length - disabledTools.size;
16200
16333
  const allEnabled = disabledTools.size === 0;
16201
16334
  const someDisabled = disabledTools.size > 0 && disabledTools.size < tools.length;
16202
- const toggleTool = useCallback19(
16335
+ const toggleTool = useCallback21(
16203
16336
  (toolName) => {
16204
16337
  const next = new Set(disabledTools);
16205
16338
  if (next.has(toolName)) {
@@ -16211,7 +16344,7 @@ function ToolSelector({
16211
16344
  },
16212
16345
  [disabledTools, onDisabledToolsChange]
16213
16346
  );
16214
- const toggleAll = useCallback19(() => {
16347
+ const toggleAll = useCallback21(() => {
16215
16348
  if (allEnabled) {
16216
16349
  onDisabledToolsChange(new Set(tools.map((t) => t.name)));
16217
16350
  } else {
@@ -16332,7 +16465,7 @@ function ChatInput({
16332
16465
  onAttachmentAdd,
16333
16466
  onAttachmentRemove
16334
16467
  }) {
16335
- const fileInputRef = useRef15(null);
16468
+ const fileInputRef = useRef16(null);
16336
16469
  const handleFileSelect = (e) => {
16337
16470
  const files = e.target.files;
16338
16471
  if (files && files.length > 0) {
@@ -16478,7 +16611,7 @@ function PromptResultsList({
16478
16611
 
16479
16612
  // src/client/components/chat/PromptsDropdown.tsx
16480
16613
  import { MessageSquare as MessageSquare4 } from "lucide-react";
16481
- import { useEffect as useEffect24 } from "react";
16614
+ import { useEffect as useEffect25 } from "react";
16482
16615
  import { jsx as jsx73, jsxs as jsxs47 } from "react/jsx-runtime";
16483
16616
  function PromptsDropdown({
16484
16617
  isOpen,
@@ -16488,7 +16621,7 @@ function PromptsDropdown({
16488
16621
  onPromptSelect
16489
16622
  }) {
16490
16623
  if (!isOpen) return null;
16491
- useEffect24(() => {
16624
+ useEffect25(() => {
16492
16625
  if (focusedIndex >= 0) {
16493
16626
  const element = document.getElementById(`prompt-${focusedIndex}`);
16494
16627
  if (element) {
@@ -16694,7 +16827,7 @@ function AuroraBackground({
16694
16827
 
16695
16828
  // src/client/components/ui/blur-fade.tsx
16696
16829
  import { AnimatePresence as AnimatePresence4, motion as motion5, useInView } from "motion/react";
16697
- import { useRef as useRef16 } from "react";
16830
+ import { useRef as useRef17 } from "react";
16698
16831
  import { jsx as jsx76 } from "react/jsx-runtime";
16699
16832
  function BlurFade({
16700
16833
  children,
@@ -16709,7 +16842,7 @@ function BlurFade({
16709
16842
  blur = "6px",
16710
16843
  ...props
16711
16844
  }) {
16712
- const ref = useRef16(null);
16845
+ const ref = useRef17(null);
16713
16846
  const inViewResult = useInView(ref, { once: true, margin: inViewMargin });
16714
16847
  const isInView = !inView || inViewResult;
16715
16848
  const defaultVariants = {
@@ -16917,14 +17050,14 @@ function ConfigureEmptyState({
16917
17050
  }
16918
17051
 
16919
17052
  // src/client/components/chat/MessageList.tsx
16920
- import { memo as memo4, useCallback as useCallback21, useEffect as useEffect26, useRef as useRef17 } from "react";
17053
+ import { memo as memo4, useCallback as useCallback23, useEffect as useEffect27, useRef as useRef18 } from "react";
16921
17054
 
16922
17055
  // src/client/components/chat/CopyButton.tsx
16923
17056
  import { Check as Check10, Copy as Copy13 } from "lucide-react";
16924
- import { useState as useState29 } from "react";
17057
+ import { useState as useState31 } from "react";
16925
17058
  import { jsx as jsx79 } from "react/jsx-runtime";
16926
17059
  function CopyButton({ text }) {
16927
- const [isCopied, setIsCopied] = useState29(false);
17060
+ const [isCopied, setIsCopied] = useState31(false);
16928
17061
  const handleCopy = async () => {
16929
17062
  await copyToClipboard(text);
16930
17063
  setIsCopied(true);
@@ -17203,7 +17336,7 @@ function UserMessage({
17203
17336
  }
17204
17337
 
17205
17338
  // src/client/components/chat/InlineElicitationCard.tsx
17206
- import { useState as useState31 } from "react";
17339
+ import { useState as useState33 } from "react";
17207
17340
  import { ExternalLink } from "lucide-react";
17208
17341
  import { toast as toast6 } from "sonner";
17209
17342
 
@@ -17229,7 +17362,7 @@ function getMultiSelectChoices(field) {
17229
17362
  }
17230
17363
 
17231
17364
  // src/client/components/elicitation/shared/ElicitationFormFields.tsx
17232
- import { Fragment as Fragment16, jsx as jsx83, jsxs as jsxs55 } from "react/jsx-runtime";
17365
+ import { Fragment as Fragment17, jsx as jsx83, jsxs as jsxs55 } from "react/jsx-runtime";
17233
17366
  function ElicitationFormFields({
17234
17367
  request,
17235
17368
  formData,
@@ -17424,18 +17557,18 @@ function ElicitationFormFields({
17424
17557
  showOuterLabelForBoolean,
17425
17558
  emptyFallback
17426
17559
  ]);
17427
- return /* @__PURE__ */ jsx83(Fragment16, { children: rendered });
17560
+ return /* @__PURE__ */ jsx83(Fragment17, { children: rendered });
17428
17561
  }
17429
17562
 
17430
17563
  // src/client/components/elicitation/shared/useElicitationForm.ts
17431
- import { useCallback as useCallback20, useEffect as useEffect25, useState as useState30 } from "react";
17564
+ import { useCallback as useCallback22, useEffect as useEffect26, useState as useState32 } from "react";
17432
17565
  function useElicitationForm(request) {
17433
- const [formData, setFormData] = useState30({});
17434
- const [urlCompleted, setUrlCompleted] = useState30(false);
17566
+ const [formData, setFormData] = useState32({});
17567
+ const [urlCompleted, setUrlCompleted] = useState32(false);
17435
17568
  const mode = request?.request.mode || "form";
17436
17569
  const isFormMode = mode === "form";
17437
17570
  const isUrlMode = mode === "url";
17438
- useEffect25(() => {
17571
+ useEffect26(() => {
17439
17572
  if (request && isFormMode && "requestedSchema" in request.request) {
17440
17573
  const schema = request.request.requestedSchema;
17441
17574
  const initial = {};
@@ -17461,10 +17594,10 @@ function useElicitationForm(request) {
17461
17594
  }
17462
17595
  setUrlCompleted(false);
17463
17596
  }, [request?.id, isFormMode]);
17464
- const setFieldValue = useCallback20((fieldName, value) => {
17597
+ const setFieldValue = useCallback22((fieldName, value) => {
17465
17598
  setFormData((prev) => ({ ...prev, [fieldName]: value }));
17466
17599
  }, []);
17467
- const getMissingRequiredFields = useCallback20(() => {
17600
+ const getMissingRequiredFields = useCallback22(() => {
17468
17601
  if (!request || !isFormMode || !("requestedSchema" in request.request)) {
17469
17602
  return [];
17470
17603
  }
@@ -17503,8 +17636,8 @@ function InlineElicitationCard({
17503
17636
  isFormMode,
17504
17637
  isUrlMode
17505
17638
  } = useElicitationForm(request);
17506
- const [responded, setResponded] = useState31(false);
17507
- const [responseLabel, setResponseLabel] = useState31("");
17639
+ const [responded, setResponded] = useState33(false);
17640
+ const [responseLabel, setResponseLabel] = useState33("");
17508
17641
  const handleAccept = () => {
17509
17642
  if (responded) return;
17510
17643
  if (isFormMode) {
@@ -17646,7 +17779,7 @@ function InlineElicitationCard({
17646
17779
  }
17647
17780
 
17648
17781
  // src/client/components/chat/MessageList.tsx
17649
- import { Fragment as Fragment17, jsx as jsx85, jsxs as jsxs57 } from "react/jsx-runtime";
17782
+ import { Fragment as Fragment18, jsx as jsx85, jsxs as jsxs57 } from "react/jsx-runtime";
17650
17783
  var MessageList = memo4(
17651
17784
  ({
17652
17785
  messages,
@@ -17660,7 +17793,7 @@ var MessageList = memo4(
17660
17793
  onApproveElicitation,
17661
17794
  onRejectElicitation
17662
17795
  }) => {
17663
- const messagesEndRef = useRef17(null);
17796
+ const messagesEndRef = useRef18(null);
17664
17797
  const getToolMeta = (toolName) => {
17665
17798
  const normalize = (n) => n.replace(/-/g, "_");
17666
17799
  const key = normalize(toolName);
@@ -17672,7 +17805,7 @@ var MessageList = memo4(
17672
17805
  const protocol = detectWidgetProtocol(toolMeta, void 0);
17673
17806
  return protocol !== null && protocol !== "mcp-ui";
17674
17807
  };
17675
- const handleFollowUp = useCallback21(
17808
+ const handleFollowUp = useCallback23(
17676
17809
  (content) => {
17677
17810
  const text = content.filter(
17678
17811
  (c) => c.type === "text" && "text" in c
@@ -17688,7 +17821,7 @@ var MessageList = memo4(
17688
17821
  },
17689
17822
  [sendMessage]
17690
17823
  );
17691
- useEffect26(() => {
17824
+ useEffect27(() => {
17692
17825
  if (messages.length > 0 && messagesEndRef.current) {
17693
17826
  messagesEndRef.current.scrollIntoView({
17694
17827
  behavior: !isLoading ? "smooth" : "auto",
@@ -17784,7 +17917,7 @@ var MessageList = memo4(
17784
17917
  ] }, partKey);
17785
17918
  }
17786
17919
  return null;
17787
- }) : /* @__PURE__ */ jsxs57(Fragment17, { children: [
17920
+ }) : /* @__PURE__ */ jsxs57(Fragment18, { children: [
17788
17921
  /* @__PURE__ */ jsx85(
17789
17922
  AssistantMessage,
17790
17923
  {
@@ -17840,7 +17973,7 @@ var MessageList = memo4(
17840
17973
  );
17841
17974
 
17842
17975
  // src/client/components/chat/useChatMessages.ts
17843
- import { useCallback as useCallback22, useRef as useRef18, useState as useState32 } from "react";
17976
+ import { useCallback as useCallback24, useRef as useRef19, useState as useState34 } from "react";
17844
17977
 
17845
17978
  // src/client/components/chat/conversion.ts
17846
17979
  function convertMessagesToProvider2(messages) {
@@ -17928,13 +18061,13 @@ function useChatMessages({
17928
18061
  extraHeaders,
17929
18062
  body: bodyBuilder
17930
18063
  }) {
17931
- const [messages, setMessages] = useState32(initialMessages ?? []);
17932
- const [isLoading, setIsLoading] = useState32(false);
17933
- const [attachments, setAttachments] = useState32([]);
17934
- const [rateLimitInfo, setRateLimitInfo] = useState32(null);
17935
- const [mcpServerAuthRequired, setMcpServerAuthRequired] = useState32(null);
17936
- const abortControllerRef = useRef18(null);
17937
- const sendMessage = useCallback22(
18064
+ const [messages, setMessages] = useState34(initialMessages ?? []);
18065
+ const [isLoading, setIsLoading] = useState34(false);
18066
+ const [attachments, setAttachments] = useState34([]);
18067
+ const [rateLimitInfo, setRateLimitInfo] = useState34(null);
18068
+ const [mcpServerAuthRequired, setMcpServerAuthRequired] = useState34(null);
18069
+ const abortControllerRef = useRef19(null);
18070
+ const sendMessage = useCallback24(
17938
18071
  async (userInput, promptResults, extraAttachments) => {
17939
18072
  const allAttachments = [...attachments, ...extraAttachments ?? []];
17940
18073
  const hasContent = userInput.trim() || promptResults.length > 0 || allAttachments.length > 0;
@@ -18291,23 +18424,23 @@ ${parts2.join("\n")}`
18291
18424
  bodyBuilder
18292
18425
  ]
18293
18426
  );
18294
- const clearMessages = useCallback22(() => {
18427
+ const clearMessages = useCallback24(() => {
18295
18428
  setMessages([]);
18296
18429
  setRateLimitInfo(null);
18297
18430
  setMcpServerAuthRequired(null);
18298
18431
  }, []);
18299
- const clearRateLimitInfo = useCallback22(() => {
18432
+ const clearRateLimitInfo = useCallback24(() => {
18300
18433
  setRateLimitInfo(null);
18301
18434
  }, []);
18302
- const clearMcpServerAuthRequired = useCallback22(() => {
18435
+ const clearMcpServerAuthRequired = useCallback24(() => {
18303
18436
  setMcpServerAuthRequired(null);
18304
18437
  }, []);
18305
- const stop = useCallback22(() => {
18438
+ const stop = useCallback24(() => {
18306
18439
  if (abortControllerRef.current) {
18307
18440
  abortControllerRef.current.abort();
18308
18441
  }
18309
18442
  }, []);
18310
- const addAttachment = useCallback22(async (file) => {
18443
+ const addAttachment = useCallback24(async (file) => {
18311
18444
  try {
18312
18445
  const attachment = await fileToAttachment(file);
18313
18446
  setAttachments((prev) => {
@@ -18326,10 +18459,10 @@ ${parts2.join("\n")}`
18326
18459
  }
18327
18460
  }
18328
18461
  }, []);
18329
- const removeAttachment = useCallback22((index) => {
18462
+ const removeAttachment = useCallback24((index) => {
18330
18463
  setAttachments((prev) => prev.filter((_, i) => i !== index));
18331
18464
  }, []);
18332
- const clearAttachments = useCallback22(() => {
18465
+ const clearAttachments = useCallback24(() => {
18333
18466
  setAttachments([]);
18334
18467
  }, []);
18335
18468
  return {
@@ -18426,7 +18559,7 @@ async function* runToolLoop(params) {
18426
18559
  }
18427
18560
 
18428
18561
  // src/client/components/chat/useChatMessagesClientSide.ts
18429
- import { useCallback as useCallback23, useRef as useRef19, useState as useState33 } from "react";
18562
+ import { useCallback as useCallback25, useRef as useRef20, useState as useState35 } from "react";
18430
18563
  var SYSTEM_PROMPT = "You are a helpful assistant with access to MCP tools. Help users interact with the MCP server.";
18431
18564
  function useChatMessagesClientSide({
18432
18565
  connection,
@@ -18436,11 +18569,11 @@ function useChatMessagesClientSide({
18436
18569
  widgetModelContexts,
18437
18570
  disabledTools
18438
18571
  }) {
18439
- const [messages, setMessages] = useState33([]);
18440
- const [isLoading, setIsLoading] = useState33(false);
18441
- const [attachments, setAttachments] = useState33([]);
18442
- const abortControllerRef = useRef19(null);
18443
- const sendMessage = useCallback23(
18572
+ const [messages, setMessages] = useState35([]);
18573
+ const [isLoading, setIsLoading] = useState35(false);
18574
+ const [attachments, setAttachments] = useState35([]);
18575
+ const abortControllerRef = useRef20(null);
18576
+ const sendMessage = useCallback25(
18444
18577
  async (userInput, promptResults, extraAttachments) => {
18445
18578
  const allAttachments = [...attachments, ...extraAttachments ?? []];
18446
18579
  const hasContent = userInput.trim() || promptResults.length > 0 || allAttachments.length > 0;
@@ -18787,15 +18920,15 @@ ${widgetParts.join("\n")}`,
18787
18920
  widgetModelContexts
18788
18921
  ]
18789
18922
  );
18790
- const clearMessages = useCallback23(() => {
18923
+ const clearMessages = useCallback25(() => {
18791
18924
  setMessages([]);
18792
18925
  }, []);
18793
- const stop = useCallback23(() => {
18926
+ const stop = useCallback25(() => {
18794
18927
  if (abortControllerRef.current) {
18795
18928
  abortControllerRef.current.abort();
18796
18929
  }
18797
18930
  }, []);
18798
- const addAttachment = useCallback23(async (file) => {
18931
+ const addAttachment = useCallback25(async (file) => {
18799
18932
  try {
18800
18933
  const attachment = await fileToAttachment(file);
18801
18934
  setAttachments((prev) => {
@@ -18814,10 +18947,10 @@ ${widgetParts.join("\n")}`,
18814
18947
  }
18815
18948
  }
18816
18949
  }, []);
18817
- const removeAttachment = useCallback23((index) => {
18950
+ const removeAttachment = useCallback25((index) => {
18818
18951
  setAttachments((prev) => prev.filter((_, i) => i !== index));
18819
18952
  }, []);
18820
- const clearAttachments = useCallback23(() => {
18953
+ const clearAttachments = useCallback25(() => {
18821
18954
  setAttachments([]);
18822
18955
  }, []);
18823
18956
  return {
@@ -18836,7 +18969,7 @@ ${widgetParts.join("\n")}`,
18836
18969
 
18837
18970
  // src/client/components/chat/McpReconnectBanner.tsx
18838
18971
  import { AlertCircle, RefreshCw as RefreshCw3 } from "lucide-react";
18839
- import { useCallback as useCallback24, useState as useState34 } from "react";
18972
+ import { useCallback as useCallback26, useState as useState36 } from "react";
18840
18973
  import { jsx as jsx86, jsxs as jsxs58 } from "react/jsx-runtime";
18841
18974
  function McpReconnectBanner({
18842
18975
  serverName,
@@ -18845,8 +18978,8 @@ function McpReconnectBanner({
18845
18978
  onReconnect,
18846
18979
  onDismiss
18847
18980
  }) {
18848
- const [isReconnecting, setIsReconnecting] = useState34(false);
18849
- const handleClick = useCallback24(async () => {
18981
+ const [isReconnecting, setIsReconnecting] = useState36(false);
18982
+ const handleClick = useCallback26(async () => {
18850
18983
  setIsReconnecting(true);
18851
18984
  try {
18852
18985
  await onReconnect();
@@ -18913,9 +19046,9 @@ function McpReconnectBanner({
18913
19046
  }
18914
19047
 
18915
19048
  // src/client/components/LoginModal.tsx
18916
- import { useCallback as useCallback25, useState as useState35 } from "react";
19049
+ import { useCallback as useCallback27, useState as useState37 } from "react";
18917
19050
  import { AlertCircle as AlertCircle2, Eye as Eye2, EyeOff as EyeOff2 } from "lucide-react";
18918
- import { Fragment as Fragment18, jsx as jsx87, jsxs as jsxs59 } from "react/jsx-runtime";
19051
+ import { Fragment as Fragment19, jsx as jsx87, jsxs as jsxs59 } from "react/jsx-runtime";
18919
19052
  function GoogleIcon({ className }) {
18920
19053
  return /* @__PURE__ */ jsxs59(
18921
19054
  "svg",
@@ -18980,14 +19113,14 @@ function LoginModal({
18980
19113
  onDismiss,
18981
19114
  onUseApiKey
18982
19115
  }) {
18983
- const [email, setEmail] = useState35("");
18984
- const [password, setPassword] = useState35("");
18985
- const [showPassword, setShowPassword] = useState35(false);
18986
- const [error, setError] = useState35(null);
18987
- const [loading, setLoading] = useState35(
19116
+ const [email, setEmail] = useState37("");
19117
+ const [password, setPassword] = useState37("");
19118
+ const [showPassword, setShowPassword] = useState37(false);
19119
+ const [error, setError] = useState37(null);
19120
+ const [loading, setLoading] = useState37(
18988
19121
  null
18989
19122
  );
18990
- const handleSuccess = useCallback25(() => {
19123
+ const handleSuccess = useCallback27(() => {
18991
19124
  window.dispatchEvent(new CustomEvent("manufact:session-changed"));
18992
19125
  onDismiss();
18993
19126
  }, [onDismiss]);
@@ -19146,7 +19279,7 @@ function LoginModal({
19146
19279
  /* @__PURE__ */ jsx87(AlertCircle2, { className: "h-4 w-4 shrink-0" }),
19147
19280
  error
19148
19281
  ] }),
19149
- /* @__PURE__ */ jsx87(Button, { type: "submit", disabled: isLoading, className: "w-full", children: loading === "email" ? /* @__PURE__ */ jsxs59(Fragment18, { children: [
19282
+ /* @__PURE__ */ jsx87(Button, { type: "submit", disabled: isLoading, className: "w-full", children: loading === "email" ? /* @__PURE__ */ jsxs59(Fragment19, { children: [
19150
19283
  /* @__PURE__ */ jsx87(Spinner, { className: "mr-2" }),
19151
19284
  "Signing in\u2026"
19152
19285
  ] }) : "Sign in" })
@@ -19180,7 +19313,7 @@ function LoginModal({
19180
19313
  }
19181
19314
  )
19182
19315
  ] }),
19183
- onUseApiKey && /* @__PURE__ */ jsxs59(Fragment18, { children: [
19316
+ onUseApiKey && /* @__PURE__ */ jsxs59(Fragment19, { children: [
19184
19317
  /* @__PURE__ */ jsx87(Divider, { text: "or" }),
19185
19318
  /* @__PURE__ */ jsx87(
19186
19319
  "button",
@@ -19259,15 +19392,15 @@ function ChatTab({
19259
19392
  extraHeaders,
19260
19393
  body
19261
19394
  }) {
19262
- const [inputValue, setInputValue] = useState36("");
19263
- const [promptsDropdownOpen, setPromptsDropdownOpen] = useState36(false);
19264
- const [promptFocusedIndex, setPromptFocusedIndex] = useState36(-1);
19265
- const [quickQuestions, setQuickQuestions] = useState36(chatQuickQuestions);
19266
- const [followups, setFollowups] = useState36(chatFollowups);
19267
- const [disabledTools, setDisabledTools] = useState36(/* @__PURE__ */ new Set());
19268
- const textareaRef = useRef20(null);
19269
- const messagesAreaRef = useRef20(null);
19270
- const triggerSpanRef = useRef20(null);
19395
+ const [inputValue, setInputValue] = useState38("");
19396
+ const [promptsDropdownOpen, setPromptsDropdownOpen] = useState38(false);
19397
+ const [promptFocusedIndex, setPromptFocusedIndex] = useState38(-1);
19398
+ const [quickQuestions, setQuickQuestions] = useState38(chatQuickQuestions);
19399
+ const [followups, setFollowups] = useState38(chatFollowups);
19400
+ const [disabledTools, setDisabledTools] = useState38(/* @__PURE__ */ new Set());
19401
+ const textareaRef = useRef21(null);
19402
+ const messagesAreaRef = useRef21(null);
19403
+ const triggerSpanRef = useRef21(null);
19271
19404
  const toolInfos = useMemo20(
19272
19405
  () => (connection.tools ?? []).map((t) => ({
19273
19406
  name: t.name,
@@ -19292,7 +19425,7 @@ function ChatTab({
19292
19425
  clearConfig
19293
19426
  } = useConfig({ mcpServerUrl: connection.url });
19294
19427
  const hostUsesServerManagedStream = !useClientSide && managedLlmConfig != null;
19295
- const [forceClientSide, setForceClientSide] = useState36(
19428
+ const [forceClientSide, setForceClientSide] = useState38(
19296
19429
  () => hostUsesServerManagedStream ? false : !!localLlmConfig
19297
19430
  );
19298
19431
  const effectiveClientSide = hostUsesServerManagedStream ? forceClientSide : useClientSide || forceClientSide || !!localLlmConfig;
@@ -19339,7 +19472,7 @@ function ChatTab({
19339
19472
  const clearRateLimitInfo = effectiveClientSide ? void 0 : serverSideChat.clearRateLimitInfo;
19340
19473
  const mcpServerAuthRequired = effectiveClientSide ? null : serverSideChat.mcpServerAuthRequired ?? null;
19341
19474
  const clearMcpServerAuthRequired = effectiveClientSide ? void 0 : serverSideChat.clearMcpServerAuthRequired;
19342
- const handleMcpReconnect = useCallback26(async () => {
19475
+ const handleMcpReconnect = useCallback28(async () => {
19343
19476
  try {
19344
19477
  await connection.authenticate();
19345
19478
  } catch (err) {
@@ -19361,13 +19494,13 @@ function ChatTab({
19361
19494
  onDismiss: clearMcpServerAuthRequired
19362
19495
  }
19363
19496
  ) : null;
19364
- const handleUseApiKey = useCallback26(() => {
19497
+ const handleUseApiKey = useCallback28(() => {
19365
19498
  clearRateLimitInfo?.();
19366
19499
  setForceClientSide(true);
19367
19500
  setConfigDialogOpen(true);
19368
19501
  }, [clearRateLimitInfo, setConfigDialogOpen]);
19369
- const [showLoginModal, setShowLoginModal] = useState36(false);
19370
- const handleOpenLogin = useCallback26(() => {
19502
+ const [showLoginModal, setShowLoginModal] = useState38(false);
19503
+ const handleOpenLogin = useCallback28(() => {
19371
19504
  setConfigDialogOpen(false);
19372
19505
  setShowLoginModal(true);
19373
19506
  }, [setConfigDialogOpen]);
@@ -19388,11 +19521,11 @@ function ChatTab({
19388
19521
  callPrompt,
19389
19522
  serverId
19390
19523
  });
19391
- const sanitizeStringList = useCallback26((input) => {
19524
+ const sanitizeStringList = useCallback28((input) => {
19392
19525
  if (!Array.isArray(input)) return [];
19393
19526
  return input.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean).slice(0, 8);
19394
19527
  }, []);
19395
- const serializeMessageContent = useCallback26((message) => {
19528
+ const serializeMessageContent = useCallback28((message) => {
19396
19529
  if (typeof message.content === "string" && message.content.trim()) {
19397
19530
  return message.content;
19398
19531
  }
@@ -19407,7 +19540,7 @@ function ChatTab({
19407
19540
  }
19408
19541
  return "";
19409
19542
  }, []);
19410
- const serializeToolResult = useCallback26((result) => {
19543
+ const serializeToolResult = useCallback28((result) => {
19411
19544
  if (result === null || result === void 0) return "No result";
19412
19545
  if (typeof result === "string") {
19413
19546
  try {
@@ -19440,7 +19573,7 @@ function ChatTab({
19440
19573
  }
19441
19574
  return JSON.stringify(result, null, 2);
19442
19575
  }, []);
19443
- const getSerializedMessages = useCallback26(() => {
19576
+ const getSerializedMessages = useCallback28(() => {
19444
19577
  return messages.map((message) => {
19445
19578
  const textContent = serializeMessageContent(message);
19446
19579
  const toolInvocations = message.parts?.filter((p) => p.type === "tool-invocation" && p.toolInvocation).map((p) => ({
@@ -19459,7 +19592,7 @@ function ChatTab({
19459
19592
  };
19460
19593
  });
19461
19594
  }, [messages, serializeMessageContent]);
19462
- const postBridgeEvent = useCallback26(
19595
+ const postBridgeEvent = useCallback28(
19463
19596
  (type, payload = {}) => {
19464
19597
  if (typeof window === "undefined" || window.parent === window) return;
19465
19598
  window.parent.postMessage(
@@ -19473,7 +19606,7 @@ function ChatTab({
19473
19606
  },
19474
19607
  [serverId]
19475
19608
  );
19476
- useEffect27(() => {
19609
+ useEffect28(() => {
19477
19610
  postBridgeEvent("mcp-inspector:chat:ready", {
19478
19611
  capabilities: {
19479
19612
  send: true,
@@ -19485,7 +19618,7 @@ function ChatTab({
19485
19618
  }
19486
19619
  });
19487
19620
  }, [postBridgeEvent]);
19488
- useEffect27(() => {
19621
+ useEffect28(() => {
19489
19622
  postBridgeEvent("mcp-inspector:chat:state_changed", {
19490
19623
  isLoading,
19491
19624
  messageCount: messages.length,
@@ -19501,7 +19634,7 @@ function ChatTab({
19501
19634
  postBridgeEvent,
19502
19635
  quickQuestions
19503
19636
  ]);
19504
- useEffect27(() => {
19637
+ useEffect28(() => {
19505
19638
  const handleMessage = (event) => {
19506
19639
  if (!event.data || typeof event.data !== "object") return;
19507
19640
  const data = event.data;
@@ -19729,12 +19862,12 @@ function ChatTab({
19729
19862
  useKeyboardShortcuts(
19730
19863
  enableKeyboardShortcuts ? { onNewChat: clearMessages } : {}
19731
19864
  );
19732
- const clearPromptsUIState = useCallback26(() => {
19865
+ const clearPromptsUIState = useCallback28(() => {
19733
19866
  setPromptFocusedIndex(-1);
19734
19867
  setPromptsDropdownOpen(false);
19735
19868
  triggerSpanRef.current = null;
19736
19869
  }, []);
19737
- const updatePromptsDropdownState = useCallback26(() => {
19870
+ const updatePromptsDropdownState = useCallback28(() => {
19738
19871
  if (!textareaRef.current) {
19739
19872
  return;
19740
19873
  }
@@ -19749,28 +19882,28 @@ function ChatTab({
19749
19882
  clearPromptsUIState();
19750
19883
  }
19751
19884
  }, [inputValue, clearPromptsUIState]);
19752
- useEffect27(() => {
19885
+ useEffect28(() => {
19753
19886
  if (llmConfig && messages.length === 0 && textareaRef.current) {
19754
19887
  textareaRef.current.focus();
19755
19888
  }
19756
19889
  }, [llmConfig, messages.length]);
19757
- useEffect27(() => {
19890
+ useEffect28(() => {
19758
19891
  if (!isLoading && messages.length > 0 && textareaRef.current) {
19759
19892
  textareaRef.current.focus();
19760
19893
  }
19761
19894
  }, [isLoading, messages.length]);
19762
- useEffect27(() => {
19895
+ useEffect28(() => {
19763
19896
  if (!textareaRef.current) {
19764
19897
  return;
19765
19898
  }
19766
19899
  updatePromptsDropdownState();
19767
19900
  }, [inputValue, updatePromptsDropdownState]);
19768
- const clearPromptsState = useCallback26(() => {
19901
+ const clearPromptsState = useCallback28(() => {
19769
19902
  setSelectedPrompt(null);
19770
19903
  setPromptArgs({});
19771
19904
  clearPromptsUIState();
19772
19905
  }, [clearPromptsUIState]);
19773
- const handlePromptSelect = useCallback26(
19906
+ const handlePromptSelect = useCallback28(
19774
19907
  async (prompt) => {
19775
19908
  setSelectedPrompt(prompt);
19776
19909
  if (prompt.arguments && prompt.arguments.length > 0) {
@@ -19800,7 +19933,7 @@ function ChatTab({
19800
19933
  },
19801
19934
  [executePrompt, clearPromptsState, inputValue]
19802
19935
  );
19803
- const handleSendMessage = useCallback26(() => {
19936
+ const handleSendMessage = useCallback28(() => {
19804
19937
  const hasContent = inputValue.trim() || results.length > 0 || attachments.length > 0;
19805
19938
  if (!hasContent) {
19806
19939
  return;
@@ -19809,7 +19942,7 @@ function ChatTab({
19809
19942
  setInputValue("");
19810
19943
  clearPromptResults();
19811
19944
  }, [inputValue, results, sendMessage, clearPromptResults, attachments]);
19812
- const handlePromptKeyDown = useCallback26(
19945
+ const handlePromptKeyDown = useCallback28(
19813
19946
  (e) => {
19814
19947
  if (e.key === "ArrowDown") {
19815
19948
  setPromptFocusedIndex((prev) => {
@@ -19838,7 +19971,7 @@ function ChatTab({
19838
19971
  clearPromptsUIState
19839
19972
  ]
19840
19973
  );
19841
- const handleKeyDown = useCallback26(
19974
+ const handleKeyDown = useCallback28(
19842
19975
  (e) => {
19843
19976
  if (PROMPT_ARROW_KEYS.includes(e.key) && promptsDropdownOpen) {
19844
19977
  e.preventDefault();
@@ -19850,7 +19983,7 @@ function ChatTab({
19850
19983
  },
19851
19984
  [handleSendMessage, handlePromptKeyDown, promptsDropdownOpen]
19852
19985
  );
19853
- const handleKeyUp = useCallback26(
19986
+ const handleKeyUp = useCallback28(
19854
19987
  (e) => {
19855
19988
  if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
19856
19989
  updatePromptsDropdownState();
@@ -19858,7 +19991,7 @@ function ChatTab({
19858
19991
  },
19859
19992
  [updatePromptsDropdownState]
19860
19993
  );
19861
- const formatMessagesAsMarkdown = useCallback26(
19994
+ const formatMessagesAsMarkdown = useCallback28(
19862
19995
  (messages2) => {
19863
19996
  let content = `# Chat Export - ${(/* @__PURE__ */ new Date()).toLocaleString()}
19864
19997
 
@@ -19898,14 +20031,14 @@ ${sections.join("\n\n")}`;
19898
20031
  },
19899
20032
  [serializeMessageContent, serializeToolResult]
19900
20033
  );
19901
- const handleCopyChat = useCallback26(() => {
20034
+ const handleCopyChat = useCallback28(() => {
19902
20035
  const formattedMessages = formatMessagesAsMarkdown(messages);
19903
20036
  copyToClipboard(formattedMessages).then(
19904
20037
  () => toast7.success("Chat copied to clipboard"),
19905
20038
  () => toast7.error("Failed to copy chat")
19906
20039
  );
19907
20040
  }, [messages, formatMessagesAsMarkdown]);
19908
- const handleExportChat = useCallback26(
20041
+ const handleExportChat = useCallback28(
19909
20042
  (format) => {
19910
20043
  const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
19911
20044
  const filename = `chat-export-${dateStr}`;
@@ -19938,11 +20071,11 @@ ${sections.join("\n\n")}`;
19938
20071
  },
19939
20072
  [messages, formatMessagesAsMarkdown, serializeMessageContent]
19940
20073
  );
19941
- const handleClearConfig = useCallback26(() => {
20074
+ const handleClearConfig = useCallback28(() => {
19942
20075
  clearConfig();
19943
20076
  clearMessages();
19944
20077
  }, [clearConfig, clearMessages]);
19945
- const handleQuickQuestionSelect = useCallback26(
20078
+ const handleQuickQuestionSelect = useCallback28(
19946
20079
  (question) => {
19947
20080
  if (!question.trim()) return;
19948
20081
  if (!llmConfig || !isConnected) return;
@@ -19955,7 +20088,7 @@ ${sections.join("\n\n")}`;
19955
20088
  },
19956
20089
  [postBridgeEvent, sendMessage, llmConfig, isConnected]
19957
20090
  );
19958
- const handleFollowupSelect = useCallback26(
20091
+ const handleFollowupSelect = useCallback28(
19959
20092
  (followup) => {
19960
20093
  if (!followup.trim()) return;
19961
20094
  if (!llmConfig || !isConnected) return;