sunpeak 0.16.10 → 0.16.12

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.
package/README.md CHANGED
@@ -22,7 +22,7 @@ Quickstart, build, test, and ship your Claude or ChatGPT App!
22
22
 
23
23
  [Demo (Hosted)](https://sunpeak.ai/simulator) ~
24
24
  [Demo (Video)](https://cdn.sunpeak.ai/sunpeak-demo-prod.mp4) ~
25
- [Discord (NEW)](https://discord.gg/FB2QNXqRnw) ~
25
+ [Discord](https://discord.gg/FB2QNXqRnw) ~
26
26
  [Documentation](https://sunpeak.ai/docs) ~
27
27
  [GitHub](https://github.com/Sunpeak-AI/sunpeak)
28
28
 
@@ -45,7 +45,7 @@ sunpeak new
45
45
 
46
46
  ## Overview
47
47
 
48
- `sunpeak` is an npm package that helps you build MCP Apps (interactive UI resources) while keeping your MCP server client-agnostic. Built on the [MCP Apps SDK](https://github.com/modelcontextprotocol/ext-apps) (`@modelcontextprotocol/ext-apps`). `sunpeak` consists of:
48
+ `sunpeak` is an npm package that helps you build MCP Apps (interactive UI [resources](https://sunpeak.ai/docs/mcp-apps/mcp/resources)) while keeping your [MCP server](https://sunpeak.ai/docs/mcp-apps/mcp/overview) client-agnostic. Built on the [MCP Apps SDK](https://github.com/modelcontextprotocol/ext-apps) (`@modelcontextprotocol/ext-apps`). `sunpeak` consists of:
49
49
 
50
50
  ### The `sunpeak` library
51
51
 
@@ -55,21 +55,21 @@ sunpeak new
55
55
 
56
56
  ### The `sunpeak` framework
57
57
 
58
- Next.js for MCP Apps. Using an example App `my-app` with a `Review` UI (MCP resource), `sunpeak` projects look like:
58
+ Next.js for MCP Apps. Using an example App `my-app` with a `Review` UI ([MCP resource](https://sunpeak.ai/docs/mcp-apps/mcp/resources)), `sunpeak` projects look like:
59
59
 
60
60
  ```bash
61
61
  my-app/
62
62
  ├── src/
63
63
  │ ├── resources/
64
64
  │ │ └── review/
65
- │ │ └── review.tsx # Review UI component + resource metadata.
65
+ │ │ └── review.tsx # Review UI component + resource metadata.
66
66
  │ ├── tools/
67
- │ │ ├── review-diff.ts # Tool with handler, schema, and resource reference.
68
- │ │ └── review-post.ts # Multiple tools can share one resource.
69
- │ └── server.ts # Optional: auth, server config.
67
+ │ │ ├── review-diff.ts # Tool with handler, schema, and resource reference.
68
+ │ │ └── review-post.ts # Multiple tools can share one resource.
69
+ │ └── server.ts # Optional: auth, server config.
70
70
  ├── tests/simulations/
71
- │ ├── review-diff.json # Mock state for testing.
72
- │ └── review-post.json # Mock state for testing.
71
+ │ ├── review-diff.json # Mock state for testing.
72
+ │ └── review-post.json # Mock state for testing.
73
73
  └── package.json
74
74
  ```
75
75
 
@@ -92,11 +92,11 @@ Commands for managing MCP Apps:
92
92
 
93
93
  ## Example App
94
94
 
95
- Example `Resource`, `Simulation`, and testing file (using the `Simulator`) for an MCP resource called "Review".
95
+ Example `Resource`, `Simulation`, and testing file (using the `Simulator`) for an [MCP resource](https://sunpeak.ai/docs/mcp-apps/mcp/resources) called "Review".
96
96
 
97
97
  ### `Resource` Component
98
98
 
99
- Each resource `.tsx` file exports both the React component and the MCP resource metadata:
99
+ Each resource `.tsx` file exports both the React component and the [MCP resource](https://sunpeak.ai/docs/mcp-apps/mcp/resources) metadata:
100
100
 
101
101
  ```tsx
102
102
  // src/resources/review/review.tsx
@@ -222,5 +222,6 @@ npx skills add Sunpeak-AI/sunpeak@create-sunpeak-app
222
222
  ## Resources
223
223
 
224
224
  - [MCP Apps Documentation](https://sunpeak.ai/docs/mcp-apps/introduction)
225
+ - [MCP Overview](https://sunpeak.ai/docs/mcp-apps/mcp/overview) · [Tools](https://sunpeak.ai/docs/mcp-apps/mcp/tools) · [Resources](https://sunpeak.ai/docs/mcp-apps/mcp/resources)
225
226
  - [MCP Apps SDK](https://github.com/modelcontextprotocol/ext-apps)
226
227
  - [ChatGPT Apps SDK Design Guidelines](https://developers.openai.com/apps-sdk/concepts/design-guidelines)
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const simulator = require("../simulator-yk9BZ7Vl.cjs");
4
- const chatgpt_index = require("../index-4ydX_boR.cjs");
3
+ const simulator = require("../simulator-tkLFRzjr.cjs");
4
+ const chatgpt_index = require("../index-BsWYp00t.cjs");
5
5
  const simulatorUrl = require("../simulator-url-rgg_KYOg.cjs");
6
6
  const discovery = require("../discovery-DmB8_4QL.cjs");
7
7
  exports.IframeResource = simulator.IframeResource;
@@ -1,5 +1,5 @@
1
- import { I, M, a, S, T, j, m } from "../simulator-CZewOh4c.js";
2
- import { C } from "../index-DrzvUEVi.js";
1
+ import { I, M, a, S, T, j, m } from "../simulator-BUF-_85b.js";
2
+ import { C } from "../index-Dyoz9lnx.js";
3
3
  import { c } from "../simulator-url-CuLqtnSS.js";
4
4
  import { b, a as a2, c as c2, d, e, f, g, h, i, t } from "../discovery-CH80W5l9.js";
5
5
  export {
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const simulator = require("../simulator-yk9BZ7Vl.cjs");
3
+ const simulator = require("../simulator-tkLFRzjr.cjs");
4
4
  exports.ClaudeSimulator = simulator.Simulator;
5
5
  //# sourceMappingURL=index.cjs.map
@@ -1,4 +1,4 @@
1
- import { S } from "../simulator-CZewOh4c.js";
1
+ import { S } from "../simulator-BUF-_85b.js";
2
2
  export {
3
3
  S as ClaudeSimulator
4
4
  };
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const simulator = require("./simulator-yk9BZ7Vl.cjs");
2
+ const simulator = require("./simulator-tkLFRzjr.cjs");
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
5
  const simulatorUrl = require("./simulator-url-rgg_KYOg.cjs");
@@ -204,9 +204,10 @@ function ChatGPTSimulator({
204
204
  const csp = selectedSim ? simulator.extractResourceCSP(selectedSim.resource) : void 0;
205
205
  const hasIframeContent = !!(resourceUrl || resourceScript);
206
206
  const isTransitioning = hasIframeContent && displayMode !== readyDisplayMode;
207
+ const iframeBg = "var(--sim-bg-conversation, var(--color-background-primary, transparent))";
207
208
  let content;
208
209
  if (resourceUrl) {
209
- content = /* @__PURE__ */ jsxRuntime.jsx(
210
+ content = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full", style: { background: iframeBg }, children: /* @__PURE__ */ jsxRuntime.jsx(
210
211
  simulator.IframeResource,
211
212
  {
212
213
  src: resourceUrl,
@@ -220,10 +221,11 @@ function ChatGPTSimulator({
220
221
  onDisplayModeReady: handleDisplayModeReady,
221
222
  debugInjectState: modelContext,
222
223
  className: "h-full w-full"
223
- }
224
- );
224
+ },
225
+ selectedSimulationName
226
+ ) });
225
227
  } else if (resourceScript) {
226
- content = /* @__PURE__ */ jsxRuntime.jsx(
228
+ content = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full", style: { background: iframeBg }, children: /* @__PURE__ */ jsxRuntime.jsx(
227
229
  simulator.IframeResource,
228
230
  {
229
231
  scriptSrc: resourceScript,
@@ -238,8 +240,9 @@ function ChatGPTSimulator({
238
240
  onDisplayModeReady: handleDisplayModeReady,
239
241
  debugInjectState: modelContext,
240
242
  className: "h-full w-full"
241
- }
242
- );
243
+ },
244
+ selectedSimulationName
245
+ ) });
243
246
  } else {
244
247
  content = children;
245
248
  }
@@ -491,8 +494,7 @@ function ChatGPTSimulator({
491
494
  userMessage: selectedSim?.userMessage,
492
495
  isTransitioning,
493
496
  children: content
494
- },
495
- selectedSimulationName
497
+ }
496
498
  )
497
499
  }
498
500
  ) });
@@ -521,4 +523,4 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
521
523
  }, Symbol.toStringTag, { value: "Module" }));
522
524
  exports.ChatGPTSimulator = ChatGPTSimulator;
523
525
  exports.index = index;
524
- //# sourceMappingURL=index-4ydX_boR.cjs.map
526
+ //# sourceMappingURL=index-BsWYp00t.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BsWYp00t.cjs","sources":["../src/chatgpt/chatgpt-simulator.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n SimpleSidebar,\n SidebarControl,\n SidebarCollapsibleControl,\n SidebarSelect,\n SidebarInput,\n SidebarCheckbox,\n SidebarTextarea,\n SidebarToggle,\n} from '../simulator/simple-sidebar';\nimport { Conversation } from './chatgpt-conversation';\nimport { IframeResource, extractResourceCSP } from '../simulator/iframe-resource';\nimport { ThemeProvider } from '../simulator/theme-provider';\nimport type {\n McpUiHostContext,\n McpUiDisplayMode,\n McpUiTheme,\n} from '@modelcontextprotocol/ext-apps';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { ScreenWidth } from '../simulator/simulator-types';\nimport type { Simulation } from '../types/simulation';\n\ntype Platform = NonNullable<McpUiHostContext['platform']>;\n\nconst DEFAULT_THEME: McpUiTheme = 'dark';\nconst DEFAULT_DISPLAY_MODE: McpUiDisplayMode = 'inline';\nconst DEFAULT_PLATFORM: Platform = 'desktop';\n\ninterface ChatGPTSimulatorProps {\n children?: React.ReactNode;\n simulations?: Record<string, Simulation>;\n appName?: string;\n appIcon?: string;\n}\n\n/**\n * Parse URL params for initial simulator values.\n * Supported params:\n * - simulation: simulation name (e.g., 'show-albums')\n * - theme: 'light' | 'dark'\n * - displayMode: 'inline' | 'pip' | 'fullscreen'\n * - locale: e.g., 'en-US'\n * - maxHeight: number (for pip mode)\n * - deviceType: 'mobile' | 'tablet' | 'desktop' → maps to platform\n * - hover: 'true' | 'false'\n * - touch: 'true' | 'false'\n * - safeAreaTop, safeAreaBottom, safeAreaLeft, safeAreaRight: number\n * - host: 'chatgpt' | 'claude'\n */\nfunction parseUrlParams(): {\n simulation?: string;\n theme?: McpUiTheme;\n displayMode?: McpUiDisplayMode;\n locale?: string;\n containerMaxHeight?: number;\n platform?: Platform;\n deviceCapabilities?: { hover?: boolean; touch?: boolean };\n safeAreaInsets?: { top: number; bottom: number; left: number; right: number };\n} {\n if (typeof window === 'undefined') return {};\n\n const params = new URLSearchParams(window.location.search);\n\n const simulation = params.get('simulation') ?? undefined;\n const theme = params.get('theme') as McpUiTheme | null;\n const displayMode = params.get('displayMode') as McpUiDisplayMode | null;\n const locale = params.get('locale');\n const maxHeightParam = params.get('maxHeight');\n const containerMaxHeight = maxHeightParam ? Number(maxHeightParam) : undefined;\n\n // Map deviceType param to MCP Apps platform\n const deviceType = params.get('deviceType');\n let platform: Platform | undefined;\n if (deviceType === 'mobile' || deviceType === 'tablet') {\n platform = 'mobile';\n } else if (deviceType === 'desktop') {\n platform = 'desktop';\n }\n\n // Device capabilities\n const hoverParam = params.get('hover');\n const touchParam = params.get('touch');\n const hasCapParams = hoverParam || touchParam;\n const deviceCapabilities = hasCapParams\n ? {\n hover: hoverParam === 'false' ? false : true,\n touch: touchParam === 'true' ? true : false,\n }\n : undefined;\n\n // Safe area insets\n const safeAreaTop = params.get('safeAreaTop');\n const safeAreaBottom = params.get('safeAreaBottom');\n const safeAreaLeft = params.get('safeAreaLeft');\n const safeAreaRight = params.get('safeAreaRight');\n const hasSafeAreaParams = safeAreaTop || safeAreaBottom || safeAreaLeft || safeAreaRight;\n const safeAreaInsets = hasSafeAreaParams\n ? {\n top: safeAreaTop ? Number(safeAreaTop) : 0,\n bottom: safeAreaBottom ? Number(safeAreaBottom) : 0,\n left: safeAreaLeft ? Number(safeAreaLeft) : 0,\n right: safeAreaRight ? Number(safeAreaRight) : 0,\n }\n : undefined;\n\n return {\n simulation,\n theme: theme ?? undefined,\n displayMode: displayMode ?? undefined,\n locale: locale ?? undefined,\n containerMaxHeight,\n platform,\n deviceCapabilities,\n safeAreaInsets,\n };\n}\n\nexport function ChatGPTSimulator({\n children,\n simulations = {},\n appName = 'Sunpeak',\n appIcon,\n}: ChatGPTSimulatorProps) {\n const simulationNames = Object.keys(simulations);\n const urlParams = useMemo(() => parseUrlParams(), []);\n const [screenWidth, setScreenWidth] = React.useState<ScreenWidth>('full');\n\n const isMobileWidth = (width: ScreenWidth) => width === 'mobile-s' || width === 'mobile-l';\n\n // Find initial simulation from URL params\n const initialSimulationName = useMemo(() => {\n const defaultName = simulationNames[0] ?? '';\n if (!urlParams.simulation) return defaultName;\n return urlParams.simulation in simulations ? urlParams.simulation : defaultName;\n }, [urlParams.simulation, simulations, simulationNames]);\n\n const [selectedSimulationName, setSelectedSimulationName] =\n React.useState<string>(initialSimulationName);\n\n const selectedSim = simulations[selectedSimulationName];\n\n // ── Host context state ──────────────────────────────────────────\n\n const [theme, setTheme] = useState<McpUiTheme>(urlParams.theme ?? DEFAULT_THEME);\n const [displayMode, _setDisplayMode] = useState<McpUiDisplayMode>(\n urlParams.displayMode ?? DEFAULT_DISPLAY_MODE\n );\n const [locale, setLocale] = useState(urlParams.locale ?? 'en-US');\n const [containerMaxHeight, setContainerMaxHeight] = useState(urlParams.containerMaxHeight ?? 480);\n const [platform, setPlatform] = useState<Platform>(urlParams.platform ?? DEFAULT_PLATFORM);\n const [hover, setHover] = useState(urlParams.deviceCapabilities?.hover ?? true);\n const [touch, setTouch] = useState(urlParams.deviceCapabilities?.touch ?? false);\n const [safeAreaInsets, setSafeAreaInsets] = useState(\n urlParams.safeAreaInsets ?? { top: 0, bottom: 0, left: 0, right: 0 }\n );\n\n // Display mode setter that respects mobile width constraints\n const setDisplayMode = (mode: McpUiDisplayMode) => {\n if (isMobileWidth(screenWidth) && mode === 'pip') {\n _setDisplayMode('fullscreen');\n } else {\n _setDisplayMode(mode);\n }\n };\n\n // Track which display mode the iframe has confirmed rendering.\n // Content is hidden when displayMode !== readyDisplayMode (transition in progress).\n // Initialized to displayMode so there's no transition on first render.\n const [readyDisplayMode, setReadyDisplayMode] = useState<McpUiDisplayMode>(\n urlParams.displayMode ?? DEFAULT_DISPLAY_MODE\n );\n\n const handleDisplayModeReady = useCallback((mode: string) => {\n setReadyDisplayMode(mode as McpUiDisplayMode);\n }, []);\n\n // Build host context from state\n const hostContext = useMemo<McpUiHostContext>(\n () => ({\n theme,\n displayMode,\n locale,\n platform,\n deviceCapabilities: { hover, touch },\n safeAreaInsets,\n ...(displayMode === 'pip' ? { containerDimensions: { maxHeight: containerMaxHeight } } : {}),\n }),\n [theme, displayMode, locale, platform, hover, touch, safeAreaInsets, containerMaxHeight]\n );\n\n // ── Tool data state ─────────────────────────────────────────────\n\n // Parsed tool data (sent to host/iframe)\n const [toolInput, setToolInput] = useState<Record<string, unknown>>(\n () => selectedSim?.toolInput ?? {}\n );\n const [toolResult, setToolResult] = useState<CallToolResult | undefined>(\n () => selectedSim?.toolResult as CallToolResult | undefined\n );\n\n // Editable JSON strings for sidebar\n const [toolInputJson, setToolInputJson] = useState(() => JSON.stringify(toolInput, null, 2));\n const [toolResultJson, setToolResultJson] = useState(() =>\n JSON.stringify(toolResult ?? null, null, 2)\n );\n\n // Model context - bidirectional: shows what app sends, editable to inject state back\n // When edited, gets merged into toolResult.structuredContent to send to app\n const [modelContextJson, setModelContextJson] = useState<string>('null');\n const [modelContext, setModelContext] = useState<Record<string, unknown> | null>(null);\n\n // Track which field is being edited to prevent reset loops\n const [editingField, setEditingField] = useState<string | null>(null);\n\n // JSON validation errors\n const [toolInputError, setToolInputError] = useState('');\n const [toolResultError, setToolResultError] = useState('');\n const [modelContextError, setModelContextError] = useState('');\n\n // Reset tool data when simulation changes\n // Note: editingField is intentionally NOT in deps - we check it inside to guard\n // against overwriting user edits, but we don't want changes to editingField\n // to trigger a re-run (which would reset values when editing ends)\n useEffect(() => {\n const newInput = selectedSim?.toolInput ?? {};\n const newResult = (selectedSim?.toolResult as CallToolResult | undefined) ?? undefined;\n setToolInput(newInput);\n setToolResult(newResult);\n if (editingField !== 'toolInput') {\n setToolInputJson(JSON.stringify(newInput, null, 2));\n setToolInputError('');\n }\n if (editingField !== 'toolResult') {\n setToolResultJson(JSON.stringify(newResult ?? null, null, 2));\n setToolResultError('');\n }\n if (editingField !== 'modelContext') {\n setModelContextJson('null');\n setModelContext(null);\n setModelContextError('');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedSimulationName, selectedSim]);\n\n // Disallow PiP on mobile widths\n useEffect(() => {\n if (isMobileWidth(screenWidth) && displayMode === 'pip') {\n _setDisplayMode('fullscreen');\n }\n }, [screenWidth, displayMode]);\n\n // ── Host callbacks ──────────────────────────────────────────────\n\n const handleDisplayModeChange = (mode: McpUiDisplayMode) => {\n setDisplayMode(mode);\n };\n\n const handleUpdateModelContext = (content: unknown[], structuredContent?: unknown) => {\n setModelContextJson(JSON.stringify(structuredContent ?? content, null, 2));\n };\n\n // ── JSON helpers ────────────────────────────────────────────────\n\n const validateJSON = (\n json: string,\n setJson: (value: string) => void,\n setError: (error: string) => void\n ) => {\n setJson(json);\n try {\n if (json.trim() !== '') JSON.parse(json);\n setError('');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Invalid JSON');\n }\n };\n\n const commitJSON = (\n json: string,\n setError: (error: string) => void,\n updateFn: (value: Record<string, unknown> | null) => void\n ) => {\n try {\n const parsed = json.trim() === '' ? null : JSON.parse(json);\n setError('');\n updateFn(parsed);\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Invalid JSON');\n } finally {\n setEditingField(null);\n }\n };\n\n // ── Content rendering ───────────────────────────────────────────\n\n // Merge modelContext into toolResult.structuredContent when sending to app\n // This simulates a host that round-trips app state (like ChatGPT's widgetState)\n const effectiveToolResult = useMemo((): CallToolResult | undefined => {\n if (!toolResult && !modelContext) return undefined;\n if (!modelContext) return toolResult;\n\n // Merge modelContext into structuredContent\n const baseResult = toolResult ?? { content: [] };\n const baseStructured = (baseResult.structuredContent as Record<string, unknown>) ?? {};\n return {\n ...baseResult,\n structuredContent: { ...baseStructured, ...modelContext },\n };\n }, [toolResult, modelContext]);\n\n // Get resource URL (dev mode) or script URL (production)\n const resourceUrl = selectedSim?.resourceUrl;\n const resourceScript = selectedSim?.resourceScript;\n\n const csp = selectedSim ? extractResourceCSP(selectedSim.resource) : undefined;\n\n // Build content based on rendering mode.\n // All rendering goes through IframeResource for consistent behavior with ChatGPT.\n const hasIframeContent = !!(resourceUrl || resourceScript);\n\n // Content is transitioning when the display mode has changed but the iframe\n // hasn't yet confirmed it has rendered with the new mode.\n // For non-iframe content (children), there's no async rendering so no transition.\n const isTransitioning = hasIframeContent && displayMode !== readyDisplayMode;\n\n // The wrapper div stays mounted across key changes, providing a themed\n // background while the iframe (opacity: 0) loads new content.\n const iframeBg = 'var(--sim-bg-conversation, var(--color-background-primary, transparent))';\n let content: React.ReactNode;\n if (resourceUrl) {\n // Dev mode: load HTML page directly (supports Vite HMR)\n content = (\n <div className=\"h-full w-full\" style={{ background: iframeBg }}>\n <IframeResource\n key={selectedSimulationName}\n src={resourceUrl}\n hostContext={hostContext}\n toolInput={toolInput}\n toolResult={effectiveToolResult}\n hostOptions={{\n onDisplayModeChange: handleDisplayModeChange,\n onUpdateModelContext: handleUpdateModelContext,\n }}\n onDisplayModeReady={handleDisplayModeReady}\n debugInjectState={modelContext}\n className=\"h-full w-full\"\n />\n </div>\n );\n } else if (resourceScript) {\n // Production mode: generate HTML wrapper for script\n content = (\n <div className=\"h-full w-full\" style={{ background: iframeBg }}>\n <IframeResource\n key={selectedSimulationName}\n scriptSrc={resourceScript}\n hostContext={hostContext}\n toolInput={toolInput}\n toolResult={effectiveToolResult}\n csp={csp}\n hostOptions={{\n onDisplayModeChange: handleDisplayModeChange,\n onUpdateModelContext: handleUpdateModelContext,\n }}\n onDisplayModeReady={handleDisplayModeReady}\n debugInjectState={modelContext}\n className=\"h-full w-full\"\n />\n </div>\n );\n } else {\n content = children;\n }\n\n return (\n <ThemeProvider theme={theme}>\n <SimpleSidebar\n controls={\n <div className=\"space-y-2\">\n {simulationNames.length > 1 && (\n <SidebarControl label=\"Simulation\">\n <SidebarSelect\n value={selectedSimulationName}\n onChange={(value) => setSelectedSimulationName(value)}\n options={simulationNames.map((name) => {\n const sim = simulations[name];\n const resourceTitle =\n (sim.resource.title as string | undefined) || sim.resource.name;\n const toolTitle = (sim.tool.title as string | undefined) || sim.tool.name;\n return {\n value: name,\n label: `${resourceTitle}: ${toolTitle}`,\n };\n })}\n />\n </SidebarControl>\n )}\n\n <SidebarControl label=\"Simulation Width\">\n <SidebarSelect\n value={screenWidth}\n onChange={(value) => setScreenWidth(value as ScreenWidth)}\n options={[\n { value: 'mobile-s', label: 'Mobile S (375px)' },\n { value: 'mobile-l', label: 'Mobile L (425px)' },\n { value: 'tablet', label: 'Tablet (768px)' },\n { value: 'full', label: '100% (Full)' },\n ]}\n />\n </SidebarControl>\n\n <SidebarCollapsibleControl label=\"Host Context\" defaultCollapsed={false}>\n <div className=\"space-y-2\">\n <SidebarControl label=\"Theme\">\n <SidebarToggle\n value={theme}\n onChange={(value) => setTheme(value as McpUiTheme)}\n options={[\n { value: 'light', label: 'Light' },\n { value: 'dark', label: 'Dark' },\n ]}\n />\n </SidebarControl>\n\n <SidebarControl label=\"Display Mode\">\n <SidebarToggle\n value={displayMode}\n onChange={(value) => setDisplayMode(value as McpUiDisplayMode)}\n options={[\n { value: 'inline', label: 'Inline' },\n { value: 'pip', label: 'PiP' },\n { value: 'fullscreen', label: 'Full' },\n ]}\n />\n </SidebarControl>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <SidebarControl label=\"Locale\">\n <SidebarInput\n value={locale}\n onChange={(value) => setLocale(value)}\n placeholder=\"e.g. en-US\"\n />\n </SidebarControl>\n\n <SidebarControl label=\"Max Height (PiP)\">\n <SidebarInput\n type=\"number\"\n value={\n displayMode === 'pip' && containerMaxHeight !== undefined\n ? String(containerMaxHeight)\n : ''\n }\n onChange={(value) => {\n if (displayMode === 'pip') {\n setContainerMaxHeight(value ? Number(value) : 480);\n }\n }}\n placeholder={displayMode === 'pip' ? '480' : '-'}\n disabled={displayMode !== 'pip'}\n />\n </SidebarControl>\n </div>\n\n <SidebarControl label=\"Platform\">\n <SidebarSelect\n value={platform}\n onChange={(value) => {\n const p = value as Platform;\n setPlatform(p);\n // Set appropriate default capabilities based on platform\n if (p === 'mobile') {\n setHover(false);\n setTouch(true);\n } else if (p === 'desktop') {\n setHover(true);\n setTouch(false);\n } else {\n setHover(true);\n setTouch(false);\n }\n }}\n options={[\n { value: 'mobile', label: 'Mobile' },\n { value: 'desktop', label: 'Desktop' },\n { value: 'web', label: 'Web' },\n ]}\n />\n </SidebarControl>\n\n <div className=\"pl-4\">\n <SidebarControl label=\"Device Capabilities\">\n <div className=\"flex gap-2\">\n <SidebarCheckbox checked={hover} onChange={setHover} label=\"Hover\" />\n <SidebarCheckbox checked={touch} onChange={setTouch} label=\"Touch\" />\n </div>\n </SidebarControl>\n </div>\n\n <SidebarControl label=\"Safe Area Insets\">\n <div className=\"grid grid-cols-4 gap-1\">\n <div className=\"flex items-center gap-0.5\">\n <span\n className=\"text-[10px]\"\n style={{ color: 'var(--color-text-secondary)' }}\n >\n &uarr;\n </span>\n <SidebarInput\n type=\"number\"\n value={String(safeAreaInsets.top)}\n onChange={(value) =>\n setSafeAreaInsets((prev) => ({ ...prev, top: Number(value) }))\n }\n />\n </div>\n <div className=\"flex items-center gap-0.5\">\n <span\n className=\"text-[10px]\"\n style={{ color: 'var(--color-text-secondary)' }}\n >\n &darr;\n </span>\n <SidebarInput\n type=\"number\"\n value={String(safeAreaInsets.bottom)}\n onChange={(value) =>\n setSafeAreaInsets((prev) => ({ ...prev, bottom: Number(value) }))\n }\n />\n </div>\n <div className=\"flex items-center gap-0.5\">\n <span\n className=\"text-[10px]\"\n style={{ color: 'var(--color-text-secondary)' }}\n >\n &larr;\n </span>\n <SidebarInput\n type=\"number\"\n value={String(safeAreaInsets.left)}\n onChange={(value) =>\n setSafeAreaInsets((prev) => ({ ...prev, left: Number(value) }))\n }\n />\n </div>\n <div className=\"flex items-center gap-0.5\">\n <span\n className=\"text-[10px]\"\n style={{ color: 'var(--color-text-secondary)' }}\n >\n &rarr;\n </span>\n <SidebarInput\n type=\"number\"\n value={String(safeAreaInsets.right)}\n onChange={(value) =>\n setSafeAreaInsets((prev) => ({ ...prev, right: Number(value) }))\n }\n />\n </div>\n </div>\n </SidebarControl>\n </div>\n </SidebarCollapsibleControl>\n\n <SidebarCollapsibleControl label=\"App Context\" defaultCollapsed>\n <SidebarTextarea\n value={modelContextJson}\n onChange={(json) => validateJSON(json, setModelContextJson, setModelContextError)}\n onFocus={() => setEditingField('modelContext')}\n onBlur={() =>\n commitJSON(modelContextJson, setModelContextError, (parsed) => {\n setModelContext(parsed as Record<string, unknown> | null);\n })\n }\n error={modelContextError}\n maxRows={8}\n />\n </SidebarCollapsibleControl>\n\n <SidebarCollapsibleControl label=\"Tool Input (JSON)\">\n <SidebarTextarea\n value={toolInputJson}\n onChange={(json) => validateJSON(json, setToolInputJson, setToolInputError)}\n onFocus={() => setEditingField('toolInput')}\n onBlur={() =>\n commitJSON(toolInputJson, setToolInputError, (parsed) =>\n setToolInput((parsed as Record<string, unknown>) ?? {})\n )\n }\n error={toolInputError}\n maxRows={8}\n />\n </SidebarCollapsibleControl>\n\n <SidebarCollapsibleControl label=\"Tool Result (JSON)\">\n <SidebarTextarea\n value={toolResultJson}\n onChange={(json) => validateJSON(json, setToolResultJson, setToolResultError)}\n onFocus={() => setEditingField('toolResult')}\n onBlur={() =>\n commitJSON(toolResultJson, setToolResultError, (parsed) => {\n if (parsed === null) {\n setToolResult(undefined);\n } else {\n // Wrap raw object as structuredContent in a CallToolResult\n const result = parsed as Record<string, unknown>;\n if ('content' in result || 'structuredContent' in result) {\n setToolResult(result as CallToolResult);\n } else {\n setToolResult({ content: [], structuredContent: result });\n }\n }\n })\n }\n error={toolResultError}\n maxRows={8}\n />\n </SidebarCollapsibleControl>\n </div>\n }\n >\n <Conversation\n screenWidth={screenWidth}\n displayMode={displayMode}\n platform={platform}\n onRequestDisplayMode={handleDisplayModeChange}\n appName={appName}\n appIcon={appIcon}\n userMessage={selectedSim?.userMessage}\n isTransitioning={isTransitioning}\n >\n {content}\n </Conversation>\n </SimpleSidebar>\n </ThemeProvider>\n );\n}\n"],"names":["useMemo","React","useState","useCallback","useEffect","content","extractResourceCSP","jsx","IframeResource","ThemeProvider","SimpleSidebar","jsxs","SidebarControl","SidebarSelect","SidebarCollapsibleControl","SidebarToggle","SidebarInput","SidebarCheckbox","SidebarTextarea","Conversation"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { I as IframeResource, M as McpAppHost, a as SCREEN_WIDTHS, b as SidebarCheckbox, c as SidebarCollapsibleControl, d as SidebarControl, e as SidebarInput, f as SidebarSelect, g as SidebarTextarea, h as SidebarToggle, i as SimpleSidebar, S as Simulator, T as ThemeProvider, j as extractResourceCSP, k as getHostShell, l as getRegisteredHosts, r as registerHostShell, u as useSimulatorState, m as useThemeContext } from "./simulator-CZewOh4c.js";
1
+ import { I as IframeResource, M as McpAppHost, a as SCREEN_WIDTHS, b as SidebarCheckbox, c as SidebarCollapsibleControl, d as SidebarControl, e as SidebarInput, f as SidebarSelect, g as SidebarTextarea, h as SidebarToggle, i as SimpleSidebar, S as Simulator, T as ThemeProvider, j as extractResourceCSP, k as getHostShell, l as getRegisteredHosts, r as registerHostShell, u as useSimulatorState, m as useThemeContext } from "./simulator-BUF-_85b.js";
2
2
  import { c as createSimulatorUrl } from "./simulator-url-CuLqtnSS.js";
3
3
  import { b as buildDevSimulations, a as buildResourceMap, c as buildSimulations, d as createResourceExports, e as extractResourceKey, f as extractSimulationKey, g as findResourceDirs, h as findResourceKey, i as getComponentName, t as toPascalCase } from "./discovery-CH80W5l9.js";
4
4
  const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -37,4 +37,4 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
37
37
  export {
38
38
  index as i
39
39
  };
40
- //# sourceMappingURL=index-CuZnuVOT.js.map
40
+ //# sourceMappingURL=index-DJt59490.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DJt59490.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { j as extractResourceCSP, T as ThemeProvider, i as SimpleSidebar, C as Conversation, d as SidebarControl, f as SidebarSelect, c as SidebarCollapsibleControl, h as SidebarToggle, e as SidebarInput, b as SidebarCheckbox, g as SidebarTextarea, I as IframeResource, M as McpAppHost, a as SCREEN_WIDTHS, S as Simulator, m as useThemeContext } from "./simulator-CZewOh4c.js";
1
+ import { j as extractResourceCSP, T as ThemeProvider, i as SimpleSidebar, C as Conversation, d as SidebarControl, f as SidebarSelect, c as SidebarCollapsibleControl, h as SidebarToggle, e as SidebarInput, b as SidebarCheckbox, g as SidebarTextarea, I as IframeResource, M as McpAppHost, a as SCREEN_WIDTHS, S as Simulator, m as useThemeContext } from "./simulator-BUF-_85b.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { useMemo, useState, useCallback, useEffect } from "react";
@@ -187,9 +187,10 @@ function ChatGPTSimulator({
187
187
  const csp = selectedSim ? extractResourceCSP(selectedSim.resource) : void 0;
188
188
  const hasIframeContent = !!(resourceUrl || resourceScript);
189
189
  const isTransitioning = hasIframeContent && displayMode !== readyDisplayMode;
190
+ const iframeBg = "var(--sim-bg-conversation, var(--color-background-primary, transparent))";
190
191
  let content;
191
192
  if (resourceUrl) {
192
- content = /* @__PURE__ */ jsx(
193
+ content = /* @__PURE__ */ jsx("div", { className: "h-full w-full", style: { background: iframeBg }, children: /* @__PURE__ */ jsx(
193
194
  IframeResource,
194
195
  {
195
196
  src: resourceUrl,
@@ -203,10 +204,11 @@ function ChatGPTSimulator({
203
204
  onDisplayModeReady: handleDisplayModeReady,
204
205
  debugInjectState: modelContext,
205
206
  className: "h-full w-full"
206
- }
207
- );
207
+ },
208
+ selectedSimulationName
209
+ ) });
208
210
  } else if (resourceScript) {
209
- content = /* @__PURE__ */ jsx(
211
+ content = /* @__PURE__ */ jsx("div", { className: "h-full w-full", style: { background: iframeBg }, children: /* @__PURE__ */ jsx(
210
212
  IframeResource,
211
213
  {
212
214
  scriptSrc: resourceScript,
@@ -221,8 +223,9 @@ function ChatGPTSimulator({
221
223
  onDisplayModeReady: handleDisplayModeReady,
222
224
  debugInjectState: modelContext,
223
225
  className: "h-full w-full"
224
- }
225
- );
226
+ },
227
+ selectedSimulationName
228
+ ) });
226
229
  } else {
227
230
  content = children;
228
231
  }
@@ -474,8 +477,7 @@ function ChatGPTSimulator({
474
477
  userMessage: selectedSim?.userMessage,
475
478
  isTransitioning,
476
479
  children: content
477
- },
478
- selectedSimulationName
480
+ }
479
481
  )
480
482
  }
481
483
  ) });
@@ -506,4 +508,4 @@ export {
506
508
  ChatGPTSimulator as C,
507
509
  index as i
508
510
  };
509
- //# sourceMappingURL=index-DrzvUEVi.js.map
511
+ //# sourceMappingURL=index-Dyoz9lnx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Dyoz9lnx.js","sources":["../src/chatgpt/chatgpt-simulator.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n SimpleSidebar,\n SidebarControl,\n SidebarCollapsibleControl,\n SidebarSelect,\n SidebarInput,\n SidebarCheckbox,\n SidebarTextarea,\n SidebarToggle,\n} from '../simulator/simple-sidebar';\nimport { Conversation } from './chatgpt-conversation';\nimport { IframeResource, extractResourceCSP } from '../simulator/iframe-resource';\nimport { ThemeProvider } from '../simulator/theme-provider';\nimport type {\n McpUiHostContext,\n McpUiDisplayMode,\n McpUiTheme,\n} from '@modelcontextprotocol/ext-apps';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { ScreenWidth } from '../simulator/simulator-types';\nimport type { Simulation } from '../types/simulation';\n\ntype Platform = NonNullable<McpUiHostContext['platform']>;\n\nconst DEFAULT_THEME: McpUiTheme = 'dark';\nconst DEFAULT_DISPLAY_MODE: McpUiDisplayMode = 'inline';\nconst DEFAULT_PLATFORM: Platform = 'desktop';\n\ninterface ChatGPTSimulatorProps {\n children?: React.ReactNode;\n simulations?: Record<string, Simulation>;\n appName?: string;\n appIcon?: string;\n}\n\n/**\n * Parse URL params for initial simulator values.\n * Supported params:\n * - simulation: simulation name (e.g., 'show-albums')\n * - theme: 'light' | 'dark'\n * - displayMode: 'inline' | 'pip' | 'fullscreen'\n * - locale: e.g., 'en-US'\n * - maxHeight: number (for pip mode)\n * - deviceType: 'mobile' | 'tablet' | 'desktop' → maps to platform\n * - hover: 'true' | 'false'\n * - touch: 'true' | 'false'\n * - safeAreaTop, safeAreaBottom, safeAreaLeft, safeAreaRight: number\n * - host: 'chatgpt' | 'claude'\n */\nfunction parseUrlParams(): {\n simulation?: string;\n theme?: McpUiTheme;\n displayMode?: McpUiDisplayMode;\n locale?: string;\n containerMaxHeight?: number;\n platform?: Platform;\n deviceCapabilities?: { hover?: boolean; touch?: boolean };\n safeAreaInsets?: { top: number; bottom: number; left: number; right: number };\n} {\n if (typeof window === 'undefined') return {};\n\n const params = new URLSearchParams(window.location.search);\n\n const simulation = params.get('simulation') ?? undefined;\n const theme = params.get('theme') as McpUiTheme | null;\n const displayMode = params.get('displayMode') as McpUiDisplayMode | null;\n const locale = params.get('locale');\n const maxHeightParam = params.get('maxHeight');\n const containerMaxHeight = maxHeightParam ? Number(maxHeightParam) : undefined;\n\n // Map deviceType param to MCP Apps platform\n const deviceType = params.get('deviceType');\n let platform: Platform | undefined;\n if (deviceType === 'mobile' || deviceType === 'tablet') {\n platform = 'mobile';\n } else if (deviceType === 'desktop') {\n platform = 'desktop';\n }\n\n // Device capabilities\n const hoverParam = params.get('hover');\n const touchParam = params.get('touch');\n const hasCapParams = hoverParam || touchParam;\n const deviceCapabilities = hasCapParams\n ? {\n hover: hoverParam === 'false' ? false : true,\n touch: touchParam === 'true' ? true : false,\n }\n : undefined;\n\n // Safe area insets\n const safeAreaTop = params.get('safeAreaTop');\n const safeAreaBottom = params.get('safeAreaBottom');\n const safeAreaLeft = params.get('safeAreaLeft');\n const safeAreaRight = params.get('safeAreaRight');\n const hasSafeAreaParams = safeAreaTop || safeAreaBottom || safeAreaLeft || safeAreaRight;\n const safeAreaInsets = hasSafeAreaParams\n ? {\n top: safeAreaTop ? Number(safeAreaTop) : 0,\n bottom: safeAreaBottom ? Number(safeAreaBottom) : 0,\n left: safeAreaLeft ? Number(safeAreaLeft) : 0,\n right: safeAreaRight ? Number(safeAreaRight) : 0,\n }\n : undefined;\n\n return {\n simulation,\n theme: theme ?? undefined,\n displayMode: displayMode ?? undefined,\n locale: locale ?? undefined,\n containerMaxHeight,\n platform,\n deviceCapabilities,\n safeAreaInsets,\n };\n}\n\nexport function ChatGPTSimulator({\n children,\n simulations = {},\n appName = 'Sunpeak',\n appIcon,\n}: ChatGPTSimulatorProps) {\n const simulationNames = Object.keys(simulations);\n const urlParams = useMemo(() => parseUrlParams(), []);\n const [screenWidth, setScreenWidth] = React.useState<ScreenWidth>('full');\n\n const isMobileWidth = (width: ScreenWidth) => width === 'mobile-s' || width === 'mobile-l';\n\n // Find initial simulation from URL params\n const initialSimulationName = useMemo(() => {\n const defaultName = simulationNames[0] ?? '';\n if (!urlParams.simulation) return defaultName;\n return urlParams.simulation in simulations ? urlParams.simulation : defaultName;\n }, [urlParams.simulation, simulations, simulationNames]);\n\n const [selectedSimulationName, setSelectedSimulationName] =\n React.useState<string>(initialSimulationName);\n\n const selectedSim = simulations[selectedSimulationName];\n\n // ── Host context state ──────────────────────────────────────────\n\n const [theme, setTheme] = useState<McpUiTheme>(urlParams.theme ?? DEFAULT_THEME);\n const [displayMode, _setDisplayMode] = useState<McpUiDisplayMode>(\n urlParams.displayMode ?? DEFAULT_DISPLAY_MODE\n );\n const [locale, setLocale] = useState(urlParams.locale ?? 'en-US');\n const [containerMaxHeight, setContainerMaxHeight] = useState(urlParams.containerMaxHeight ?? 480);\n const [platform, setPlatform] = useState<Platform>(urlParams.platform ?? DEFAULT_PLATFORM);\n const [hover, setHover] = useState(urlParams.deviceCapabilities?.hover ?? true);\n const [touch, setTouch] = useState(urlParams.deviceCapabilities?.touch ?? false);\n const [safeAreaInsets, setSafeAreaInsets] = useState(\n urlParams.safeAreaInsets ?? { top: 0, bottom: 0, left: 0, right: 0 }\n );\n\n // Display mode setter that respects mobile width constraints\n const setDisplayMode = (mode: McpUiDisplayMode) => {\n if (isMobileWidth(screenWidth) && mode === 'pip') {\n _setDisplayMode('fullscreen');\n } else {\n _setDisplayMode(mode);\n }\n };\n\n // Track which display mode the iframe has confirmed rendering.\n // Content is hidden when displayMode !== readyDisplayMode (transition in progress).\n // Initialized to displayMode so there's no transition on first render.\n const [readyDisplayMode, setReadyDisplayMode] = useState<McpUiDisplayMode>(\n urlParams.displayMode ?? DEFAULT_DISPLAY_MODE\n );\n\n const handleDisplayModeReady = useCallback((mode: string) => {\n setReadyDisplayMode(mode as McpUiDisplayMode);\n }, []);\n\n // Build host context from state\n const hostContext = useMemo<McpUiHostContext>(\n () => ({\n theme,\n displayMode,\n locale,\n platform,\n deviceCapabilities: { hover, touch },\n safeAreaInsets,\n ...(displayMode === 'pip' ? { containerDimensions: { maxHeight: containerMaxHeight } } : {}),\n }),\n [theme, displayMode, locale, platform, hover, touch, safeAreaInsets, containerMaxHeight]\n );\n\n // ── Tool data state ─────────────────────────────────────────────\n\n // Parsed tool data (sent to host/iframe)\n const [toolInput, setToolInput] = useState<Record<string, unknown>>(\n () => selectedSim?.toolInput ?? {}\n );\n const [toolResult, setToolResult] = useState<CallToolResult | undefined>(\n () => selectedSim?.toolResult as CallToolResult | undefined\n );\n\n // Editable JSON strings for sidebar\n const [toolInputJson, setToolInputJson] = useState(() => JSON.stringify(toolInput, null, 2));\n const [toolResultJson, setToolResultJson] = useState(() =>\n JSON.stringify(toolResult ?? null, null, 2)\n );\n\n // Model context - bidirectional: shows what app sends, editable to inject state back\n // When edited, gets merged into toolResult.structuredContent to send to app\n const [modelContextJson, setModelContextJson] = useState<string>('null');\n const [modelContext, setModelContext] = useState<Record<string, unknown> | null>(null);\n\n // Track which field is being edited to prevent reset loops\n const [editingField, setEditingField] = useState<string | null>(null);\n\n // JSON validation errors\n const [toolInputError, setToolInputError] = useState('');\n const [toolResultError, setToolResultError] = useState('');\n const [modelContextError, setModelContextError] = useState('');\n\n // Reset tool data when simulation changes\n // Note: editingField is intentionally NOT in deps - we check it inside to guard\n // against overwriting user edits, but we don't want changes to editingField\n // to trigger a re-run (which would reset values when editing ends)\n useEffect(() => {\n const newInput = selectedSim?.toolInput ?? {};\n const newResult = (selectedSim?.toolResult as CallToolResult | undefined) ?? undefined;\n setToolInput(newInput);\n setToolResult(newResult);\n if (editingField !== 'toolInput') {\n setToolInputJson(JSON.stringify(newInput, null, 2));\n setToolInputError('');\n }\n if (editingField !== 'toolResult') {\n setToolResultJson(JSON.stringify(newResult ?? null, null, 2));\n setToolResultError('');\n }\n if (editingField !== 'modelContext') {\n setModelContextJson('null');\n setModelContext(null);\n setModelContextError('');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedSimulationName, selectedSim]);\n\n // Disallow PiP on mobile widths\n useEffect(() => {\n if (isMobileWidth(screenWidth) && displayMode === 'pip') {\n _setDisplayMode('fullscreen');\n }\n }, [screenWidth, displayMode]);\n\n // ── Host callbacks ──────────────────────────────────────────────\n\n const handleDisplayModeChange = (mode: McpUiDisplayMode) => {\n setDisplayMode(mode);\n };\n\n const handleUpdateModelContext = (content: unknown[], structuredContent?: unknown) => {\n setModelContextJson(JSON.stringify(structuredContent ?? content, null, 2));\n };\n\n // ── JSON helpers ────────────────────────────────────────────────\n\n const validateJSON = (\n json: string,\n setJson: (value: string) => void,\n setError: (error: string) => void\n ) => {\n setJson(json);\n try {\n if (json.trim() !== '') JSON.parse(json);\n setError('');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Invalid JSON');\n }\n };\n\n const commitJSON = (\n json: string,\n setError: (error: string) => void,\n updateFn: (value: Record<string, unknown> | null) => void\n ) => {\n try {\n const parsed = json.trim() === '' ? null : JSON.parse(json);\n setError('');\n updateFn(parsed);\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Invalid JSON');\n } finally {\n setEditingField(null);\n }\n };\n\n // ── Content rendering ───────────────────────────────────────────\n\n // Merge modelContext into toolResult.structuredContent when sending to app\n // This simulates a host that round-trips app state (like ChatGPT's widgetState)\n const effectiveToolResult = useMemo((): CallToolResult | undefined => {\n if (!toolResult && !modelContext) return undefined;\n if (!modelContext) return toolResult;\n\n // Merge modelContext into structuredContent\n const baseResult = toolResult ?? { content: [] };\n const baseStructured = (baseResult.structuredContent as Record<string, unknown>) ?? {};\n return {\n ...baseResult,\n structuredContent: { ...baseStructured, ...modelContext },\n };\n }, [toolResult, modelContext]);\n\n // Get resource URL (dev mode) or script URL (production)\n const resourceUrl = selectedSim?.resourceUrl;\n const resourceScript = selectedSim?.resourceScript;\n\n const csp = selectedSim ? extractResourceCSP(selectedSim.resource) : undefined;\n\n // Build content based on rendering mode.\n // All rendering goes through IframeResource for consistent behavior with ChatGPT.\n const hasIframeContent = !!(resourceUrl || resourceScript);\n\n // Content is transitioning when the display mode has changed but the iframe\n // hasn't yet confirmed it has rendered with the new mode.\n // For non-iframe content (children), there's no async rendering so no transition.\n const isTransitioning = hasIframeContent && displayMode !== readyDisplayMode;\n\n // The wrapper div stays mounted across key changes, providing a themed\n // background while the iframe (opacity: 0) loads new content.\n const iframeBg = 'var(--sim-bg-conversation, var(--color-background-primary, transparent))';\n let content: React.ReactNode;\n if (resourceUrl) {\n // Dev mode: load HTML page directly (supports Vite HMR)\n content = (\n <div className=\"h-full w-full\" style={{ background: iframeBg }}>\n <IframeResource\n key={selectedSimulationName}\n src={resourceUrl}\n hostContext={hostContext}\n toolInput={toolInput}\n toolResult={effectiveToolResult}\n hostOptions={{\n onDisplayModeChange: handleDisplayModeChange,\n onUpdateModelContext: handleUpdateModelContext,\n }}\n onDisplayModeReady={handleDisplayModeReady}\n debugInjectState={modelContext}\n className=\"h-full w-full\"\n />\n </div>\n );\n } else if (resourceScript) {\n // Production mode: generate HTML wrapper for script\n content = (\n <div className=\"h-full w-full\" style={{ background: iframeBg }}>\n <IframeResource\n key={selectedSimulationName}\n scriptSrc={resourceScript}\n hostContext={hostContext}\n toolInput={toolInput}\n toolResult={effectiveToolResult}\n csp={csp}\n hostOptions={{\n onDisplayModeChange: handleDisplayModeChange,\n onUpdateModelContext: handleUpdateModelContext,\n }}\n onDisplayModeReady={handleDisplayModeReady}\n debugInjectState={modelContext}\n className=\"h-full w-full\"\n />\n </div>\n );\n } else {\n content = children;\n }\n\n return (\n <ThemeProvider theme={theme}>\n <SimpleSidebar\n controls={\n <div className=\"space-y-2\">\n {simulationNames.length > 1 && (\n <SidebarControl label=\"Simulation\">\n <SidebarSelect\n value={selectedSimulationName}\n onChange={(value) => setSelectedSimulationName(value)}\n options={simulationNames.map((name) => {\n const sim = simulations[name];\n const resourceTitle =\n (sim.resource.title as string | undefined) || sim.resource.name;\n const toolTitle = (sim.tool.title as string | undefined) || sim.tool.name;\n return {\n value: name,\n label: `${resourceTitle}: ${toolTitle}`,\n };\n })}\n />\n </SidebarControl>\n )}\n\n <SidebarControl label=\"Simulation Width\">\n <SidebarSelect\n value={screenWidth}\n onChange={(value) => setScreenWidth(value as ScreenWidth)}\n options={[\n { value: 'mobile-s', label: 'Mobile S (375px)' },\n { value: 'mobile-l', label: 'Mobile L (425px)' },\n { value: 'tablet', label: 'Tablet (768px)' },\n { value: 'full', label: '100% (Full)' },\n ]}\n />\n </SidebarControl>\n\n <SidebarCollapsibleControl label=\"Host Context\" defaultCollapsed={false}>\n <div className=\"space-y-2\">\n <SidebarControl label=\"Theme\">\n <SidebarToggle\n value={theme}\n onChange={(value) => setTheme(value as McpUiTheme)}\n options={[\n { value: 'light', label: 'Light' },\n { value: 'dark', label: 'Dark' },\n ]}\n />\n </SidebarControl>\n\n <SidebarControl label=\"Display Mode\">\n <SidebarToggle\n value={displayMode}\n onChange={(value) => setDisplayMode(value as McpUiDisplayMode)}\n options={[\n { value: 'inline', label: 'Inline' },\n { value: 'pip', label: 'PiP' },\n { value: 'fullscreen', label: 'Full' },\n ]}\n />\n </SidebarControl>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <SidebarControl label=\"Locale\">\n <SidebarInput\n value={locale}\n onChange={(value) => setLocale(value)}\n placeholder=\"e.g. en-US\"\n />\n </SidebarControl>\n\n <SidebarControl label=\"Max Height (PiP)\">\n <SidebarInput\n type=\"number\"\n value={\n displayMode === 'pip' && containerMaxHeight !== undefined\n ? String(containerMaxHeight)\n : ''\n }\n onChange={(value) => {\n if (displayMode === 'pip') {\n setContainerMaxHeight(value ? Number(value) : 480);\n }\n }}\n placeholder={displayMode === 'pip' ? '480' : '-'}\n disabled={displayMode !== 'pip'}\n />\n </SidebarControl>\n </div>\n\n <SidebarControl label=\"Platform\">\n <SidebarSelect\n value={platform}\n onChange={(value) => {\n const p = value as Platform;\n setPlatform(p);\n // Set appropriate default capabilities based on platform\n if (p === 'mobile') {\n setHover(false);\n setTouch(true);\n } else if (p === 'desktop') {\n setHover(true);\n setTouch(false);\n } else {\n setHover(true);\n setTouch(false);\n }\n }}\n options={[\n { value: 'mobile', label: 'Mobile' },\n { value: 'desktop', label: 'Desktop' },\n { value: 'web', label: 'Web' },\n ]}\n />\n </SidebarControl>\n\n <div className=\"pl-4\">\n <SidebarControl label=\"Device Capabilities\">\n <div className=\"flex gap-2\">\n <SidebarCheckbox checked={hover} onChange={setHover} label=\"Hover\" />\n <SidebarCheckbox checked={touch} onChange={setTouch} label=\"Touch\" />\n </div>\n </SidebarControl>\n </div>\n\n <SidebarControl label=\"Safe Area Insets\">\n <div className=\"grid grid-cols-4 gap-1\">\n <div className=\"flex items-center gap-0.5\">\n <span\n className=\"text-[10px]\"\n style={{ color: 'var(--color-text-secondary)' }}\n >\n &uarr;\n </span>\n <SidebarInput\n type=\"number\"\n value={String(safeAreaInsets.top)}\n onChange={(value) =>\n setSafeAreaInsets((prev) => ({ ...prev, top: Number(value) }))\n }\n />\n </div>\n <div className=\"flex items-center gap-0.5\">\n <span\n className=\"text-[10px]\"\n style={{ color: 'var(--color-text-secondary)' }}\n >\n &darr;\n </span>\n <SidebarInput\n type=\"number\"\n value={String(safeAreaInsets.bottom)}\n onChange={(value) =>\n setSafeAreaInsets((prev) => ({ ...prev, bottom: Number(value) }))\n }\n />\n </div>\n <div className=\"flex items-center gap-0.5\">\n <span\n className=\"text-[10px]\"\n style={{ color: 'var(--color-text-secondary)' }}\n >\n &larr;\n </span>\n <SidebarInput\n type=\"number\"\n value={String(safeAreaInsets.left)}\n onChange={(value) =>\n setSafeAreaInsets((prev) => ({ ...prev, left: Number(value) }))\n }\n />\n </div>\n <div className=\"flex items-center gap-0.5\">\n <span\n className=\"text-[10px]\"\n style={{ color: 'var(--color-text-secondary)' }}\n >\n &rarr;\n </span>\n <SidebarInput\n type=\"number\"\n value={String(safeAreaInsets.right)}\n onChange={(value) =>\n setSafeAreaInsets((prev) => ({ ...prev, right: Number(value) }))\n }\n />\n </div>\n </div>\n </SidebarControl>\n </div>\n </SidebarCollapsibleControl>\n\n <SidebarCollapsibleControl label=\"App Context\" defaultCollapsed>\n <SidebarTextarea\n value={modelContextJson}\n onChange={(json) => validateJSON(json, setModelContextJson, setModelContextError)}\n onFocus={() => setEditingField('modelContext')}\n onBlur={() =>\n commitJSON(modelContextJson, setModelContextError, (parsed) => {\n setModelContext(parsed as Record<string, unknown> | null);\n })\n }\n error={modelContextError}\n maxRows={8}\n />\n </SidebarCollapsibleControl>\n\n <SidebarCollapsibleControl label=\"Tool Input (JSON)\">\n <SidebarTextarea\n value={toolInputJson}\n onChange={(json) => validateJSON(json, setToolInputJson, setToolInputError)}\n onFocus={() => setEditingField('toolInput')}\n onBlur={() =>\n commitJSON(toolInputJson, setToolInputError, (parsed) =>\n setToolInput((parsed as Record<string, unknown>) ?? {})\n )\n }\n error={toolInputError}\n maxRows={8}\n />\n </SidebarCollapsibleControl>\n\n <SidebarCollapsibleControl label=\"Tool Result (JSON)\">\n <SidebarTextarea\n value={toolResultJson}\n onChange={(json) => validateJSON(json, setToolResultJson, setToolResultError)}\n onFocus={() => setEditingField('toolResult')}\n onBlur={() =>\n commitJSON(toolResultJson, setToolResultError, (parsed) => {\n if (parsed === null) {\n setToolResult(undefined);\n } else {\n // Wrap raw object as structuredContent in a CallToolResult\n const result = parsed as Record<string, unknown>;\n if ('content' in result || 'structuredContent' in result) {\n setToolResult(result as CallToolResult);\n } else {\n setToolResult({ content: [], structuredContent: result });\n }\n }\n })\n }\n error={toolResultError}\n maxRows={8}\n />\n </SidebarCollapsibleControl>\n </div>\n }\n >\n <Conversation\n screenWidth={screenWidth}\n displayMode={displayMode}\n platform={platform}\n onRequestDisplayMode={handleDisplayModeChange}\n appName={appName}\n appIcon={appIcon}\n userMessage={selectedSim?.userMessage}\n isTransitioning={isTransitioning}\n >\n {content}\n </Conversation>\n </SimpleSidebar>\n </ThemeProvider>\n );\n}\n"],"names":["content"],"mappings":";;;;;;AA0BA,MAAM,gBAA4B;AAClC,MAAM,uBAAyC;AAC/C,MAAM,mBAA6B;AAuBnC,SAAS,iBASP;AACA,MAAI,OAAO,WAAW,YAAa,QAAO,CAAA;AAE1C,QAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAEzD,QAAM,aAAa,OAAO,IAAI,YAAY,KAAK;AAC/C,QAAM,QAAQ,OAAO,IAAI,OAAO;AAChC,QAAM,cAAc,OAAO,IAAI,aAAa;AAC5C,QAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,QAAM,iBAAiB,OAAO,IAAI,WAAW;AAC7C,QAAM,qBAAqB,iBAAiB,OAAO,cAAc,IAAI;AAGrE,QAAM,aAAa,OAAO,IAAI,YAAY;AAC1C,MAAI;AACJ,MAAI,eAAe,YAAY,eAAe,UAAU;AACtD,eAAW;AAAA,EACb,WAAW,eAAe,WAAW;AACnC,eAAW;AAAA,EACb;AAGA,QAAM,aAAa,OAAO,IAAI,OAAO;AACrC,QAAM,aAAa,OAAO,IAAI,OAAO;AACrC,QAAM,eAAe,cAAc;AACnC,QAAM,qBAAqB,eACvB;AAAA,IACE,OAAO,eAAe,UAAU,QAAQ;AAAA,IACxC,OAAO,eAAe,SAAS,OAAO;AAAA,EAAA,IAExC;AAGJ,QAAM,cAAc,OAAO,IAAI,aAAa;AAC5C,QAAM,iBAAiB,OAAO,IAAI,gBAAgB;AAClD,QAAM,eAAe,OAAO,IAAI,cAAc;AAC9C,QAAM,gBAAgB,OAAO,IAAI,eAAe;AAChD,QAAM,oBAAoB,eAAe,kBAAkB,gBAAgB;AAC3E,QAAM,iBAAiB,oBACnB;AAAA,IACE,KAAK,cAAc,OAAO,WAAW,IAAI;AAAA,IACzC,QAAQ,iBAAiB,OAAO,cAAc,IAAI;AAAA,IAClD,MAAM,eAAe,OAAO,YAAY,IAAI;AAAA,IAC5C,OAAO,gBAAgB,OAAO,aAAa,IAAI;AAAA,EAAA,IAEjD;AAEJ,SAAO;AAAA,IACL;AAAA,IACA,OAAO,SAAS;AAAA,IAChB,aAAa,eAAe;AAAA,IAC5B,QAAQ,UAAU;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,cAAc,CAAA;AAAA,EACd,UAAU;AAAA,EACV;AACF,GAA0B;AACxB,QAAM,kBAAkB,OAAO,KAAK,WAAW;AAC/C,QAAM,YAAY,QAAQ,MAAM,eAAA,GAAkB,CAAA,CAAE;AACpD,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAsB,MAAM;AAExE,QAAM,gBAAgB,CAAC,UAAuB,UAAU,cAAc,UAAU;AAGhF,QAAM,wBAAwB,QAAQ,MAAM;AAC1C,UAAM,cAAc,gBAAgB,CAAC,KAAK;AAC1C,QAAI,CAAC,UAAU,WAAY,QAAO;AAClC,WAAO,UAAU,cAAc,cAAc,UAAU,aAAa;AAAA,EACtE,GAAG,CAAC,UAAU,YAAY,aAAa,eAAe,CAAC;AAEvD,QAAM,CAAC,wBAAwB,yBAAyB,IACtD,MAAM,SAAiB,qBAAqB;AAE9C,QAAM,cAAc,YAAY,sBAAsB;AAItD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAqB,UAAU,SAAS,aAAa;AAC/E,QAAM,CAAC,aAAa,eAAe,IAAI;AAAA,IACrC,UAAU,eAAe;AAAA,EAAA;AAE3B,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,UAAU,UAAU,OAAO;AAChE,QAAM,CAAC,oBAAoB,qBAAqB,IAAI,SAAS,UAAU,sBAAsB,GAAG;AAChG,QAAM,CAAC,UAAU,WAAW,IAAI,SAAmB,UAAU,YAAY,gBAAgB;AACzF,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,UAAU,oBAAoB,SAAS,IAAI;AAC9E,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,UAAU,oBAAoB,SAAS,KAAK;AAC/E,QAAM,CAAC,gBAAgB,iBAAiB,IAAI;AAAA,IAC1C,UAAU,kBAAkB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,EAAA;AAAA,EAAE;AAIrE,QAAM,iBAAiB,CAAC,SAA2B;AACjD,QAAI,cAAc,WAAW,KAAK,SAAS,OAAO;AAChD,sBAAgB,YAAY;AAAA,IAC9B,OAAO;AACL,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF;AAKA,QAAM,CAAC,kBAAkB,mBAAmB,IAAI;AAAA,IAC9C,UAAU,eAAe;AAAA,EAAA;AAG3B,QAAM,yBAAyB,YAAY,CAAC,SAAiB;AAC3D,wBAAoB,IAAwB;AAAA,EAC9C,GAAG,CAAA,CAAE;AAGL,QAAM,cAAc;AAAA,IAClB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB,EAAE,OAAO,MAAA;AAAA,MAC7B;AAAA,MACA,GAAI,gBAAgB,QAAQ,EAAE,qBAAqB,EAAE,WAAW,mBAAA,MAAyB,CAAA;AAAA,IAAC;AAAA,IAE5F,CAAC,OAAO,aAAa,QAAQ,UAAU,OAAO,OAAO,gBAAgB,kBAAkB;AAAA,EAAA;AAMzF,QAAM,CAAC,WAAW,YAAY,IAAI;AAAA,IAChC,MAAM,aAAa,aAAa,CAAA;AAAA,EAAC;AAEnC,QAAM,CAAC,YAAY,aAAa,IAAI;AAAA,IAClC,MAAM,aAAa;AAAA,EAAA;AAIrB,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,MAAM,KAAK,UAAU,WAAW,MAAM,CAAC,CAAC;AAC3F,QAAM,CAAC,gBAAgB,iBAAiB,IAAI;AAAA,IAAS,MACnD,KAAK,UAAU,cAAc,MAAM,MAAM,CAAC;AAAA,EAAA;AAK5C,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAiB,MAAM;AACvE,QAAM,CAAC,cAAc,eAAe,IAAI,SAAyC,IAAI;AAGrF,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,IAAI;AAGpE,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,EAAE;AACvD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,EAAE;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAS,EAAE;AAM7D,YAAU,MAAM;AACd,UAAM,WAAW,aAAa,aAAa,CAAA;AAC3C,UAAM,YAAa,aAAa,cAA6C;AAC7E,iBAAa,QAAQ;AACrB,kBAAc,SAAS;AACvB,QAAI,iBAAiB,aAAa;AAChC,uBAAiB,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAClD,wBAAkB,EAAE;AAAA,IACtB;AACA,QAAI,iBAAiB,cAAc;AACjC,wBAAkB,KAAK,UAAU,aAAa,MAAM,MAAM,CAAC,CAAC;AAC5D,yBAAmB,EAAE;AAAA,IACvB;AACA,QAAI,iBAAiB,gBAAgB;AACnC,0BAAoB,MAAM;AAC1B,sBAAgB,IAAI;AACpB,2BAAqB,EAAE;AAAA,IACzB;AAAA,EAEF,GAAG,CAAC,wBAAwB,WAAW,CAAC;AAGxC,YAAU,MAAM;AACd,QAAI,cAAc,WAAW,KAAK,gBAAgB,OAAO;AACvD,sBAAgB,YAAY;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,aAAa,WAAW,CAAC;AAI7B,QAAM,0BAA0B,CAAC,SAA2B;AAC1D,mBAAe,IAAI;AAAA,EACrB;AAEA,QAAM,2BAA2B,CAACA,UAAoB,sBAAgC;AACpF,wBAAoB,KAAK,UAAU,qBAAqBA,UAAS,MAAM,CAAC,CAAC;AAAA,EAC3E;AAIA,QAAM,eAAe,CACnB,MACA,SACA,aACG;AACH,YAAQ,IAAI;AACZ,QAAI;AACF,UAAI,KAAK,KAAA,MAAW,GAAI,MAAK,MAAM,IAAI;AACvC,eAAS,EAAE;AAAA,IACb,SAAS,GAAG;AACV,eAAS,aAAa,QAAQ,EAAE,UAAU,cAAc;AAAA,IAC1D;AAAA,EACF;AAEA,QAAM,aAAa,CACjB,MACA,UACA,aACG;AACH,QAAI;AACF,YAAM,SAAS,KAAK,KAAA,MAAW,KAAK,OAAO,KAAK,MAAM,IAAI;AAC1D,eAAS,EAAE;AACX,eAAS,MAAM;AAAA,IACjB,SAAS,GAAG;AACV,eAAS,aAAa,QAAQ,EAAE,UAAU,cAAc;AAAA,IAC1D,UAAA;AACE,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF;AAMA,QAAM,sBAAsB,QAAQ,MAAkC;AACpE,QAAI,CAAC,cAAc,CAAC,aAAc,QAAO;AACzC,QAAI,CAAC,aAAc,QAAO;AAG1B,UAAM,aAAa,cAAc,EAAE,SAAS,CAAA,EAAC;AAC7C,UAAM,iBAAkB,WAAW,qBAAiD,CAAA;AACpF,WAAO;AAAA,MACL,GAAG;AAAA,MACH,mBAAmB,EAAE,GAAG,gBAAgB,GAAG,aAAA;AAAA,IAAa;AAAA,EAE5D,GAAG,CAAC,YAAY,YAAY,CAAC;AAG7B,QAAM,cAAc,aAAa;AACjC,QAAM,iBAAiB,aAAa;AAEpC,QAAM,MAAM,cAAc,mBAAmB,YAAY,QAAQ,IAAI;AAIrE,QAAM,mBAAmB,CAAC,EAAE,eAAe;AAK3C,QAAM,kBAAkB,oBAAoB,gBAAgB;AAI5D,QAAM,WAAW;AACjB,MAAI;AACJ,MAAI,aAAa;AAEf,cACE,oBAAC,SAAI,WAAU,iBAAgB,OAAO,EAAE,YAAY,YAClD,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ,aAAa;AAAA,UACX,qBAAqB;AAAA,UACrB,sBAAsB;AAAA,QAAA;AAAA,QAExB,oBAAoB;AAAA,QACpB,kBAAkB;AAAA,QAClB,WAAU;AAAA,MAAA;AAAA,MAXL;AAAA,IAAA,GAaT;AAAA,EAEJ,WAAW,gBAAgB;AAEzB,cACE,oBAAC,SAAI,WAAU,iBAAgB,OAAO,EAAE,YAAY,YAClD,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,QACA,aAAa;AAAA,UACX,qBAAqB;AAAA,UACrB,sBAAsB;AAAA,QAAA;AAAA,QAExB,oBAAoB;AAAA,QACpB,kBAAkB;AAAA,QAClB,WAAU;AAAA,MAAA;AAAA,MAZL;AAAA,IAAA,GAcT;AAAA,EAEJ,OAAO;AACL,cAAU;AAAA,EACZ;AAEA,SACE,oBAAC,iBAAc,OACb,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,UACE,qBAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,QAAA,gBAAgB,SAAS,KACxB,oBAAC,gBAAA,EAAe,OAAM,cACpB,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,0BAA0B,KAAK;AAAA,YACpD,SAAS,gBAAgB,IAAI,CAAC,SAAS;AACrC,oBAAM,MAAM,YAAY,IAAI;AAC5B,oBAAM,gBACH,IAAI,SAAS,SAAgC,IAAI,SAAS;AAC7D,oBAAM,YAAa,IAAI,KAAK,SAAgC,IAAI,KAAK;AACrE,qBAAO;AAAA,gBACL,OAAO;AAAA,gBACP,OAAO,GAAG,aAAa,KAAK,SAAS;AAAA,cAAA;AAAA,YAEzC,CAAC;AAAA,UAAA;AAAA,QAAA,GAEL;AAAA,QAGF,oBAAC,gBAAA,EAAe,OAAM,oBACpB,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,eAAe,KAAoB;AAAA,YACxD,SAAS;AAAA,cACP,EAAE,OAAO,YAAY,OAAO,mBAAA;AAAA,cAC5B,EAAE,OAAO,YAAY,OAAO,mBAAA;AAAA,cAC5B,EAAE,OAAO,UAAU,OAAO,iBAAA;AAAA,cAC1B,EAAE,OAAO,QAAQ,OAAO,cAAA;AAAA,YAAc;AAAA,UACxC;AAAA,QAAA,GAEJ;AAAA,QAEA,oBAAC,6BAA0B,OAAM,gBAAe,kBAAkB,OAChE,UAAA,qBAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,UAAA,oBAAC,gBAAA,EAAe,OAAM,SACpB,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,UAAU,SAAS,KAAmB;AAAA,cACjD,SAAS;AAAA,gBACP,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,gBACzB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,cAAO;AAAA,YACjC;AAAA,UAAA,GAEJ;AAAA,UAEA,oBAAC,gBAAA,EAAe,OAAM,gBACpB,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,UAAU,eAAe,KAAyB;AAAA,cAC7D,SAAS;AAAA,gBACP,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,gBAC1B,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,gBACvB,EAAE,OAAO,cAAc,OAAO,OAAA;AAAA,cAAO;AAAA,YACvC;AAAA,UAAA,GAEJ;AAAA,UAEA,qBAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,YAAA,oBAAC,gBAAA,EAAe,OAAM,UACpB,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU,CAAC,UAAU,UAAU,KAAK;AAAA,gBACpC,aAAY;AAAA,cAAA;AAAA,YAAA,GAEhB;AAAA,YAEA,oBAAC,gBAAA,EAAe,OAAM,oBACpB,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OACE,gBAAgB,SAAS,uBAAuB,SAC5C,OAAO,kBAAkB,IACzB;AAAA,gBAEN,UAAU,CAAC,UAAU;AACnB,sBAAI,gBAAgB,OAAO;AACzB,0CAAsB,QAAQ,OAAO,KAAK,IAAI,GAAG;AAAA,kBACnD;AAAA,gBACF;AAAA,gBACA,aAAa,gBAAgB,QAAQ,QAAQ;AAAA,gBAC7C,UAAU,gBAAgB;AAAA,cAAA;AAAA,YAAA,EAC5B,CACF;AAAA,UAAA,GACF;AAAA,UAEA,oBAAC,gBAAA,EAAe,OAAM,YACpB,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,UAAU;AACnB,sBAAM,IAAI;AACV,4BAAY,CAAC;AAEb,oBAAI,MAAM,UAAU;AAClB,2BAAS,KAAK;AACd,2BAAS,IAAI;AAAA,gBACf,WAAW,MAAM,WAAW;AAC1B,2BAAS,IAAI;AACb,2BAAS,KAAK;AAAA,gBAChB,OAAO;AACL,2BAAS,IAAI;AACb,2BAAS,KAAK;AAAA,gBAChB;AAAA,cACF;AAAA,cACA,SAAS;AAAA,gBACP,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,gBAC1B,EAAE,OAAO,WAAW,OAAO,UAAA;AAAA,gBAC3B,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,cAAM;AAAA,YAC/B;AAAA,UAAA,GAEJ;AAAA,UAEA,oBAAC,OAAA,EAAI,WAAU,QACb,UAAA,oBAAC,gBAAA,EAAe,OAAM,uBACpB,UAAA,qBAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,YAAA,oBAAC,mBAAgB,SAAS,OAAO,UAAU,UAAU,OAAM,SAAQ;AAAA,gCAClE,iBAAA,EAAgB,SAAS,OAAO,UAAU,UAAU,OAAM,QAAA,CAAQ;AAAA,UAAA,EAAA,CACrE,GACF,GACF;AAAA,8BAEC,gBAAA,EAAe,OAAM,oBACpB,UAAA,qBAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,YAAA,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,cAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO,EAAE,OAAO,8BAAA;AAAA,kBACjB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAO,OAAO,eAAe,GAAG;AAAA,kBAChC,UAAU,CAAC,UACT,kBAAkB,CAAC,UAAU,EAAE,GAAG,MAAM,KAAK,OAAO,KAAK,IAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YAEjE,GACF;AAAA,YACA,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,cAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO,EAAE,OAAO,8BAAA;AAAA,kBACjB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAO,OAAO,eAAe,MAAM;AAAA,kBACnC,UAAU,CAAC,UACT,kBAAkB,CAAC,UAAU,EAAE,GAAG,MAAM,QAAQ,OAAO,KAAK,IAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YAEpE,GACF;AAAA,YACA,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,cAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO,EAAE,OAAO,8BAAA;AAAA,kBACjB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAO,OAAO,eAAe,IAAI;AAAA,kBACjC,UAAU,CAAC,UACT,kBAAkB,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YAElE,GACF;AAAA,YACA,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,cAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO,EAAE,OAAO,8BAAA;AAAA,kBACjB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAO,OAAO,eAAe,KAAK;AAAA,kBAClC,UAAU,CAAC,UACT,kBAAkB,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,OAAO,KAAK,IAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YAEnE,EAAA,CACF;AAAA,UAAA,EAAA,CACF,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAEA,oBAAC,2BAAA,EAA0B,OAAM,eAAc,kBAAgB,MAC7D,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,SAAS,aAAa,MAAM,qBAAqB,oBAAoB;AAAA,YAChF,SAAS,MAAM,gBAAgB,cAAc;AAAA,YAC7C,QAAQ,MACN,WAAW,kBAAkB,sBAAsB,CAAC,WAAW;AAC7D,8BAAgB,MAAwC;AAAA,YAC1D,CAAC;AAAA,YAEH,OAAO;AAAA,YACP,SAAS;AAAA,UAAA;AAAA,QAAA,GAEb;AAAA,QAEA,oBAAC,2BAAA,EAA0B,OAAM,qBAC/B,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,SAAS,aAAa,MAAM,kBAAkB,iBAAiB;AAAA,YAC1E,SAAS,MAAM,gBAAgB,WAAW;AAAA,YAC1C,QAAQ,MACN;AAAA,cAAW;AAAA,cAAe;AAAA,cAAmB,CAAC,WAC5C,aAAc,UAAsC,CAAA,CAAE;AAAA,YAAA;AAAA,YAG1D,OAAO;AAAA,YACP,SAAS;AAAA,UAAA;AAAA,QAAA,GAEb;AAAA,QAEA,oBAAC,2BAAA,EAA0B,OAAM,sBAC/B,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,SAAS,aAAa,MAAM,mBAAmB,kBAAkB;AAAA,YAC5E,SAAS,MAAM,gBAAgB,YAAY;AAAA,YAC3C,QAAQ,MACN,WAAW,gBAAgB,oBAAoB,CAAC,WAAW;AACzD,kBAAI,WAAW,MAAM;AACnB,8BAAc,MAAS;AAAA,cACzB,OAAO;AAEL,sBAAM,SAAS;AACf,oBAAI,aAAa,UAAU,uBAAuB,QAAQ;AACxD,gCAAc,MAAwB;AAAA,gBACxC,OAAO;AACL,gCAAc,EAAE,SAAS,CAAA,GAAI,mBAAmB,QAAQ;AAAA,gBAC1D;AAAA,cACF;AAAA,YACF,CAAC;AAAA,YAEH,OAAO;AAAA,YACP,SAAS;AAAA,UAAA;AAAA,QAAA,EACX,CACF;AAAA,MAAA,GACF;AAAA,MAGF,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA,sBAAsB;AAAA,UACtB;AAAA,UACA;AAAA,UACA,aAAa,aAAa;AAAA,UAC1B;AAAA,UAEC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACH;AAAA,EAAA,GAEJ;AAEJ;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const simulator = require("./simulator-yk9BZ7Vl.cjs");
2
+ const simulator = require("./simulator-tkLFRzjr.cjs");
3
3
  const simulatorUrl = require("./simulator-url-rgg_KYOg.cjs");
4
4
  const discovery = require("./discovery-DmB8_4QL.cjs");
5
5
  const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -36,4 +36,4 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
36
36
  useThemeContext: simulator.useThemeContext
37
37
  }, Symbol.toStringTag, { value: "Module" }));
38
38
  exports.index = index;
39
- //# sourceMappingURL=index-BB4bUvhY.cjs.map
39
+ //# sourceMappingURL=index-POfU7IR6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-POfU7IR6.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.cjs CHANGED
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const useApp = require("./use-app-BpAJqzdE.cjs");
4
4
  const platform_index = require("./platform/index.cjs");
5
- const simulator_index = require("./index-BB4bUvhY.cjs");
6
- const chatgpt_index = require("./index-4ydX_boR.cjs");
5
+ const simulator_index = require("./index-POfU7IR6.cjs");
6
+ const chatgpt_index = require("./index-BsWYp00t.cjs");
7
7
  const React = require("react");
8
8
  const protocol = require("./protocol-BOjXuK6l.cjs");
9
- const simulator = require("./simulator-yk9BZ7Vl.cjs");
9
+ const simulator = require("./simulator-tkLFRzjr.cjs");
10
10
  const jsxRuntime = require("react/jsx-runtime");
11
11
  const discovery = require("./discovery-DmB8_4QL.cjs");
12
12
  function _interopNamespaceDefault(e2) {
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { u as useApp, s as s6$1, n as nb, r as rb } from "./use-app-WOUdh1PR.js";
2
2
  import { g, $, x, C, d, w, Q, G, e, E, z, S, J, L, h, P, i, q, _, m, o, t, N, I, T, K, v, A, l, X, j, D, U, k, V, O, W, y, a, Y, f, B, Z, F, b, R, c, H, M, p } from "./use-app-WOUdh1PR.js";
3
3
  import { detectPlatform, isChatGPT, isClaude } from "./platform/index.js";
4
- import { i as i2 } from "./index-CuZnuVOT.js";
5
- import { i as i3 } from "./index-DrzvUEVi.js";
4
+ import { i as i2 } from "./index-DJt59490.js";
5
+ import { i as i3 } from "./index-Dyoz9lnx.js";
6
6
  import * as React from "react";
7
7
  import { useEffect, useState, useRef, useCallback, useSyncExternalStore, useMemo, forwardRef } from "react";
8
8
  import { C as ContentBlockSchema, a as CallToolResultSchema, T as ToolSchema, R as RequestIdSchema, I as ImplementationSchema } from "./protocol-BD5jDQEx.js";
9
- import { D as DEFAULT_STYLE_VARIABLES } from "./simulator-CZewOh4c.js";
9
+ import { D as DEFAULT_STYLE_VARIABLES } from "./simulator-BUF-_85b.js";
10
10
  import { jsx } from "react/jsx-runtime";
11
11
  import { a as a2, d as d2 } from "./discovery-CH80W5l9.js";
12
12
  var Me = Object.defineProperty;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const simulator = require("../simulator-yk9BZ7Vl.cjs");
3
+ const simulator = require("../simulator-tkLFRzjr.cjs");
4
4
  const simulatorUrl = require("../simulator-url-rgg_KYOg.cjs");
5
5
  const discovery = require("../discovery-DmB8_4QL.cjs");
6
6
  exports.IframeResource = simulator.IframeResource;
@@ -1,4 +1,4 @@
1
- import { I, M, a, b, c, d, e, f, g, h, i, S, T, j, k, l, r, u, m } from "../simulator-CZewOh4c.js";
1
+ import { I, M, a, b, c, d, e, f, g, h, i, S, T, j, k, l, r, u, m } from "../simulator-BUF-_85b.js";
2
2
  import { c as c2 } from "../simulator-url-CuLqtnSS.js";
3
3
  import { b as b2, a as a2, c as c3, d as d2, e as e2, f as f2, g as g2, h as h2, i as i2, t } from "../discovery-CH80W5l9.js";
4
4
  export {