sunpeak 0.14.3 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -28
- package/bin/commands/build.mjs +2 -1
- package/bin/commands/dev.mjs +72 -2
- package/dist/chatgpt/{conversation.d.ts → chatgpt-conversation.d.ts} +1 -1
- package/dist/chatgpt/chatgpt-host.d.ts +1 -0
- package/dist/chatgpt/globals.css +618 -6156
- package/dist/chatgpt/index.cjs +11 -8
- package/dist/chatgpt/index.cjs.map +1 -1
- package/dist/chatgpt/index.d.ts +10 -32
- package/dist/chatgpt/index.js +15 -12
- package/dist/chatgpt/index.js.map +1 -1
- package/dist/claude/claude-conversation.d.ts +23 -0
- package/dist/claude/claude-host.d.ts +1 -0
- package/dist/claude/index.cjs +6 -0
- package/dist/claude/index.cjs.map +1 -0
- package/dist/claude/index.d.ts +1 -0
- package/dist/claude/index.js +6 -0
- package/dist/claude/index.js.map +1 -0
- package/dist/claude-host-C7KPfOM8.cjs +284 -0
- package/dist/claude-host-C7KPfOM8.cjs.map +1 -0
- package/dist/claude-host-CaD7ptbt.js +283 -0
- package/dist/claude-host-CaD7ptbt.js.map +1 -0
- package/dist/{discovery-COZUnY6a.js → discovery-DzV3HLXs.js} +5 -5
- package/dist/{discovery-COZUnY6a.js.map → discovery-DzV3HLXs.js.map} +1 -1
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/use-app-tools.d.ts +44 -0
- package/dist/hooks/use-update-model-context.d.ts +29 -0
- package/dist/index-BKrboRah.js +44 -0
- package/dist/index-BKrboRah.js.map +1 -0
- package/dist/index-BSKuY-oH.cjs +527 -0
- package/dist/index-BSKuY-oH.cjs.map +1 -0
- package/dist/index-CiqvXo8n.js +512 -0
- package/dist/index-CiqvXo8n.js.map +1 -0
- package/dist/index-Dr-L0Nb3.cjs +43 -0
- package/dist/index-Dr-L0Nb3.cjs.map +1 -0
- package/dist/index.cjs +1705 -1647
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2732 -2675
- package/dist/index.js.map +1 -1
- package/dist/lib/default-style-variables.d.ts +2 -0
- package/dist/lib/discovery-cli.js +1 -1
- package/dist/mcp/index.cjs +86 -27
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.d.ts +3 -1
- package/dist/mcp/index.js +85 -26
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server.d.ts +4 -3
- package/dist/mcp/types.d.ts +11 -0
- package/dist/platform/chatgpt/index.cjs +1 -1
- package/dist/platform/chatgpt/index.js +1 -1
- package/dist/platform/index.cjs +3 -0
- package/dist/platform/index.cjs.map +1 -1
- package/dist/platform/index.d.ts +3 -1
- package/dist/platform/index.js +3 -0
- package/dist/platform/index.js.map +1 -1
- package/dist/{protocol-BQCnIrc9.js → protocol-DFbsCx7E.js} +29 -29
- package/dist/{protocol-BQCnIrc9.js.map → protocol-DFbsCx7E.js.map} +1 -1
- package/dist/simulator/host-styles.d.ts +5 -0
- package/dist/simulator/hosts.d.ts +73 -0
- package/dist/{chatgpt → simulator}/iframe-resource.d.ts +27 -3
- package/dist/simulator/index.cjs +40 -0
- package/dist/simulator/index.cjs.map +1 -0
- package/dist/simulator/index.d.ts +18 -0
- package/dist/simulator/index.js +40 -0
- package/dist/simulator/index.js.map +1 -0
- package/dist/{chatgpt → simulator}/mcp-app-host.d.ts +8 -1
- package/dist/simulator/mock-openai-runtime.d.ts +20 -0
- package/dist/{chatgpt → simulator}/simulator-url.d.ts +8 -1
- package/dist/simulator/simulator.d.ts +12 -0
- package/dist/{chatgpt → simulator}/theme-provider.d.ts +3 -1
- package/dist/simulator/use-simulator-state.d.ts +91 -0
- package/dist/simulator-BqZmzFVR.cjs +8214 -0
- package/dist/simulator-BqZmzFVR.cjs.map +1 -0
- package/dist/simulator-CMgCGNuD.js +8199 -0
- package/dist/simulator-CMgCGNuD.js.map +1 -0
- package/dist/simulator-url-BQ-7SMht.js +335 -0
- package/dist/simulator-url-BQ-7SMht.js.map +1 -0
- package/dist/simulator-url-uNqOCaPJ.cjs +334 -0
- package/dist/simulator-url-uNqOCaPJ.cjs.map +1 -0
- package/dist/style.css +558 -6143
- package/dist/types/runtime.d.ts +1 -1
- package/dist/{use-app-D7kRAPSG.cjs → use-app-BnoSPiUT.cjs} +2 -1
- package/dist/{use-app-D7kRAPSG.cjs.map → use-app-BnoSPiUT.cjs.map} +1 -1
- package/dist/{use-app-Dvr4LKs2.js → use-app-D_TeaMFG.js} +4 -3
- package/dist/{use-app-Dvr4LKs2.js.map → use-app-D_TeaMFG.js.map} +1 -1
- package/package.json +18 -3
- package/template/.sunpeak/dev.tsx +4 -4
- package/template/.sunpeak/resource-loader.html +1 -1
- package/template/node_modules/.bin/nodemon +2 -2
- package/template/node_modules/.bin/playwright +2 -2
- package/template/node_modules/.bin/sunpeak +2 -2
- package/template/node_modules/.bin/tsc +2 -2
- package/template/node_modules/.bin/tsserver +2 -2
- package/template/node_modules/.bin/tsx +2 -2
- package/template/node_modules/.bin/vite +2 -2
- package/template/src/components/avatar.tsx +4 -1
- package/template/src/components/button.tsx +17 -20
- package/template/src/resources/albums/albums-resource.tsx +2 -3
- package/template/src/resources/albums/components/album-card.tsx +4 -2
- package/template/src/resources/albums/components/film-strip.test.tsx +2 -2
- package/template/src/resources/albums/components/film-strip.tsx +2 -2
- package/template/src/resources/albums/components/fullscreen-viewer.tsx +7 -5
- package/template/src/resources/carousel/carousel-resource.tsx +2 -3
- package/template/src/resources/carousel/components/card.test.tsx +3 -2
- package/template/src/resources/carousel/components/card.tsx +8 -4
- package/template/src/resources/map/components/map-view.tsx +1 -1
- package/template/src/resources/map/components/map.tsx +1 -1
- package/template/src/resources/map/components/place-card.tsx +8 -4
- package/template/src/resources/map/components/place-carousel.tsx +1 -1
- package/template/src/resources/map/components/place-inspector.tsx +15 -7
- package/template/src/resources/map/components/place-list.tsx +7 -4
- package/template/src/resources/map/map-resource.tsx +0 -2
- package/template/src/resources/review/review-resource.tsx +61 -27
- package/template/tests/e2e/albums.spec.ts +118 -102
- package/template/tests/e2e/carousel.spec.ts +103 -100
- package/template/tests/e2e/map.spec.ts +220 -181
- package/template/tests/e2e/review.spec.ts +224 -198
- package/dist/_commonjsHelpers-Bc2YnDe1.cjs +0 -8
- package/dist/_commonjsHelpers-Bc2YnDe1.cjs.map +0 -1
- package/dist/_commonjsHelpers-DWwsNxpa.js +0 -9
- package/dist/_commonjsHelpers-DWwsNxpa.js.map +0 -1
- package/dist/index-CJ3jfcjj.js +0 -15131
- package/dist/index-CJ3jfcjj.js.map +0 -1
- package/dist/index-Cdeg96So.cjs +0 -15147
- package/dist/index-Cdeg96So.cjs.map +0 -1
- /package/dist/{chatgpt → simulator}/simple-sidebar.d.ts +0 -0
- /package/dist/{chatgpt/chatgpt-simulator-types.d.ts → simulator/simulator-types.d.ts} +0 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
import { C as Conversation, c as createSimulatorUrl } from "./simulator-url-BQ-7SMht.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { useMemo, useState, useCallback, useEffect } from "react";
|
|
5
|
+
import { j as extractResourceCSP, T as ThemeProvider, i as SimpleSidebar, 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-CMgCGNuD.js";
|
|
6
|
+
import { b as buildDevSimulations, a as buildResourceMap, c as buildSimulations, d as createResourceExports, e as extractResourceKey, f as extractSimulationKey, g as extractSimulationName, h as findResourceDirs, i as findResourceKey, j as findSimulationFiles, k as getComponentName, l as isSimulationFile, t as toPascalCase } from "./discovery-DzV3HLXs.js";
|
|
7
|
+
const DEFAULT_THEME = "dark";
|
|
8
|
+
const DEFAULT_DISPLAY_MODE = "inline";
|
|
9
|
+
const DEFAULT_PLATFORM = "desktop";
|
|
10
|
+
function parseUrlParams() {
|
|
11
|
+
if (typeof window === "undefined") return {};
|
|
12
|
+
const params = new URLSearchParams(window.location.search);
|
|
13
|
+
const simulation = params.get("simulation") ?? void 0;
|
|
14
|
+
const theme = params.get("theme");
|
|
15
|
+
const displayMode = params.get("displayMode");
|
|
16
|
+
const locale = params.get("locale");
|
|
17
|
+
const maxHeightParam = params.get("maxHeight");
|
|
18
|
+
const containerMaxHeight = maxHeightParam ? Number(maxHeightParam) : void 0;
|
|
19
|
+
const deviceType = params.get("deviceType");
|
|
20
|
+
let platform;
|
|
21
|
+
if (deviceType === "mobile" || deviceType === "tablet") {
|
|
22
|
+
platform = "mobile";
|
|
23
|
+
} else if (deviceType === "desktop") {
|
|
24
|
+
platform = "desktop";
|
|
25
|
+
}
|
|
26
|
+
const hoverParam = params.get("hover");
|
|
27
|
+
const touchParam = params.get("touch");
|
|
28
|
+
const hasCapParams = hoverParam || touchParam;
|
|
29
|
+
const deviceCapabilities = hasCapParams ? {
|
|
30
|
+
hover: hoverParam === "false" ? false : true,
|
|
31
|
+
touch: touchParam === "true" ? true : false
|
|
32
|
+
} : void 0;
|
|
33
|
+
const safeAreaTop = params.get("safeAreaTop");
|
|
34
|
+
const safeAreaBottom = params.get("safeAreaBottom");
|
|
35
|
+
const safeAreaLeft = params.get("safeAreaLeft");
|
|
36
|
+
const safeAreaRight = params.get("safeAreaRight");
|
|
37
|
+
const hasSafeAreaParams = safeAreaTop || safeAreaBottom || safeAreaLeft || safeAreaRight;
|
|
38
|
+
const safeAreaInsets = hasSafeAreaParams ? {
|
|
39
|
+
top: safeAreaTop ? Number(safeAreaTop) : 0,
|
|
40
|
+
bottom: safeAreaBottom ? Number(safeAreaBottom) : 0,
|
|
41
|
+
left: safeAreaLeft ? Number(safeAreaLeft) : 0,
|
|
42
|
+
right: safeAreaRight ? Number(safeAreaRight) : 0
|
|
43
|
+
} : void 0;
|
|
44
|
+
return {
|
|
45
|
+
simulation,
|
|
46
|
+
theme: theme ?? void 0,
|
|
47
|
+
displayMode: displayMode ?? void 0,
|
|
48
|
+
locale: locale ?? void 0,
|
|
49
|
+
containerMaxHeight,
|
|
50
|
+
platform,
|
|
51
|
+
deviceCapabilities,
|
|
52
|
+
safeAreaInsets
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function ChatGPTSimulator({
|
|
56
|
+
children,
|
|
57
|
+
simulations = {},
|
|
58
|
+
appName = "Sunpeak",
|
|
59
|
+
appIcon
|
|
60
|
+
}) {
|
|
61
|
+
const simulationNames = Object.keys(simulations);
|
|
62
|
+
const urlParams = useMemo(() => parseUrlParams(), []);
|
|
63
|
+
const [screenWidth, setScreenWidth] = React.useState("full");
|
|
64
|
+
const isMobileWidth = (width) => width === "mobile-s" || width === "mobile-l";
|
|
65
|
+
const initialSimulationName = useMemo(() => {
|
|
66
|
+
const defaultName = simulationNames[0] ?? "";
|
|
67
|
+
if (!urlParams.simulation) return defaultName;
|
|
68
|
+
return urlParams.simulation in simulations ? urlParams.simulation : defaultName;
|
|
69
|
+
}, [urlParams.simulation, simulations, simulationNames]);
|
|
70
|
+
const [selectedSimulationName, setSelectedSimulationName] = React.useState(initialSimulationName);
|
|
71
|
+
const selectedSim = simulations[selectedSimulationName];
|
|
72
|
+
const [theme, setTheme] = useState(urlParams.theme ?? DEFAULT_THEME);
|
|
73
|
+
const [displayMode, _setDisplayMode] = useState(
|
|
74
|
+
urlParams.displayMode ?? DEFAULT_DISPLAY_MODE
|
|
75
|
+
);
|
|
76
|
+
const [locale, setLocale] = useState(urlParams.locale ?? "en-US");
|
|
77
|
+
const [containerMaxHeight, setContainerMaxHeight] = useState(urlParams.containerMaxHeight ?? 480);
|
|
78
|
+
const [platform, setPlatform] = useState(urlParams.platform ?? DEFAULT_PLATFORM);
|
|
79
|
+
const [hover, setHover] = useState(urlParams.deviceCapabilities?.hover ?? true);
|
|
80
|
+
const [touch, setTouch] = useState(urlParams.deviceCapabilities?.touch ?? false);
|
|
81
|
+
const [safeAreaInsets, setSafeAreaInsets] = useState(
|
|
82
|
+
urlParams.safeAreaInsets ?? { top: 0, bottom: 0, left: 0, right: 0 }
|
|
83
|
+
);
|
|
84
|
+
const setDisplayMode = (mode) => {
|
|
85
|
+
if (isMobileWidth(screenWidth) && mode === "pip") {
|
|
86
|
+
_setDisplayMode("fullscreen");
|
|
87
|
+
} else {
|
|
88
|
+
_setDisplayMode(mode);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const [readyDisplayMode, setReadyDisplayMode] = useState(
|
|
92
|
+
urlParams.displayMode ?? DEFAULT_DISPLAY_MODE
|
|
93
|
+
);
|
|
94
|
+
const handleDisplayModeReady = useCallback((mode) => {
|
|
95
|
+
setReadyDisplayMode(mode);
|
|
96
|
+
}, []);
|
|
97
|
+
const hostContext = useMemo(
|
|
98
|
+
() => ({
|
|
99
|
+
theme,
|
|
100
|
+
displayMode,
|
|
101
|
+
locale,
|
|
102
|
+
platform,
|
|
103
|
+
deviceCapabilities: { hover, touch },
|
|
104
|
+
safeAreaInsets,
|
|
105
|
+
...displayMode === "pip" ? { containerDimensions: { maxHeight: containerMaxHeight } } : {}
|
|
106
|
+
}),
|
|
107
|
+
[theme, displayMode, locale, platform, hover, touch, safeAreaInsets, containerMaxHeight]
|
|
108
|
+
);
|
|
109
|
+
const [toolInput, setToolInput] = useState(
|
|
110
|
+
() => selectedSim?.toolInput ?? {}
|
|
111
|
+
);
|
|
112
|
+
const [toolResult, setToolResult] = useState(
|
|
113
|
+
() => selectedSim?.toolResult
|
|
114
|
+
);
|
|
115
|
+
const [toolInputJson, setToolInputJson] = useState(() => JSON.stringify(toolInput, null, 2));
|
|
116
|
+
const [toolResultJson, setToolResultJson] = useState(
|
|
117
|
+
() => JSON.stringify(toolResult ?? null, null, 2)
|
|
118
|
+
);
|
|
119
|
+
const [modelContextJson, setModelContextJson] = useState("null");
|
|
120
|
+
const [modelContext, setModelContext] = useState(null);
|
|
121
|
+
const [editingField, setEditingField] = useState(null);
|
|
122
|
+
const [toolInputError, setToolInputError] = useState("");
|
|
123
|
+
const [toolResultError, setToolResultError] = useState("");
|
|
124
|
+
const [modelContextError, setModelContextError] = useState("");
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
const newInput = selectedSim?.toolInput ?? {};
|
|
127
|
+
const newResult = selectedSim?.toolResult ?? void 0;
|
|
128
|
+
setToolInput(newInput);
|
|
129
|
+
setToolResult(newResult);
|
|
130
|
+
if (editingField !== "toolInput") {
|
|
131
|
+
setToolInputJson(JSON.stringify(newInput, null, 2));
|
|
132
|
+
setToolInputError("");
|
|
133
|
+
}
|
|
134
|
+
if (editingField !== "toolResult") {
|
|
135
|
+
setToolResultJson(JSON.stringify(newResult ?? null, null, 2));
|
|
136
|
+
setToolResultError("");
|
|
137
|
+
}
|
|
138
|
+
if (editingField !== "modelContext") {
|
|
139
|
+
setModelContextJson("null");
|
|
140
|
+
setModelContext(null);
|
|
141
|
+
setModelContextError("");
|
|
142
|
+
}
|
|
143
|
+
}, [selectedSimulationName, selectedSim]);
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
if (isMobileWidth(screenWidth) && displayMode === "pip") {
|
|
146
|
+
_setDisplayMode("fullscreen");
|
|
147
|
+
}
|
|
148
|
+
}, [screenWidth, displayMode]);
|
|
149
|
+
const handleDisplayModeChange = (mode) => {
|
|
150
|
+
setDisplayMode(mode);
|
|
151
|
+
};
|
|
152
|
+
const handleUpdateModelContext = (content2, structuredContent) => {
|
|
153
|
+
setModelContextJson(JSON.stringify(structuredContent ?? content2, null, 2));
|
|
154
|
+
};
|
|
155
|
+
const validateJSON = (json, setJson, setError) => {
|
|
156
|
+
setJson(json);
|
|
157
|
+
try {
|
|
158
|
+
if (json.trim() !== "") JSON.parse(json);
|
|
159
|
+
setError("");
|
|
160
|
+
} catch (e) {
|
|
161
|
+
setError(e instanceof Error ? e.message : "Invalid JSON");
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const commitJSON = (json, setError, updateFn) => {
|
|
165
|
+
try {
|
|
166
|
+
const parsed = json.trim() === "" ? null : JSON.parse(json);
|
|
167
|
+
setError("");
|
|
168
|
+
updateFn(parsed);
|
|
169
|
+
} catch (e) {
|
|
170
|
+
setError(e instanceof Error ? e.message : "Invalid JSON");
|
|
171
|
+
} finally {
|
|
172
|
+
setEditingField(null);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const effectiveToolResult = useMemo(() => {
|
|
176
|
+
if (!toolResult && !modelContext) return void 0;
|
|
177
|
+
if (!modelContext) return toolResult;
|
|
178
|
+
const baseResult = toolResult ?? { content: [] };
|
|
179
|
+
const baseStructured = baseResult.structuredContent ?? {};
|
|
180
|
+
return {
|
|
181
|
+
...baseResult,
|
|
182
|
+
structuredContent: { ...baseStructured, ...modelContext }
|
|
183
|
+
};
|
|
184
|
+
}, [toolResult, modelContext]);
|
|
185
|
+
const resourceUrl = selectedSim?.resourceUrl;
|
|
186
|
+
const resourceScript = selectedSim?.resourceScript;
|
|
187
|
+
const csp = selectedSim ? extractResourceCSP(selectedSim.resource) : void 0;
|
|
188
|
+
const hasIframeContent = !!(resourceUrl || resourceScript);
|
|
189
|
+
const isTransitioning = hasIframeContent && displayMode !== readyDisplayMode;
|
|
190
|
+
let content;
|
|
191
|
+
if (resourceUrl) {
|
|
192
|
+
content = /* @__PURE__ */ jsx(
|
|
193
|
+
IframeResource,
|
|
194
|
+
{
|
|
195
|
+
src: resourceUrl,
|
|
196
|
+
hostContext,
|
|
197
|
+
toolInput,
|
|
198
|
+
toolResult: effectiveToolResult,
|
|
199
|
+
hostOptions: {
|
|
200
|
+
onDisplayModeChange: handleDisplayModeChange,
|
|
201
|
+
onUpdateModelContext: handleUpdateModelContext
|
|
202
|
+
},
|
|
203
|
+
onDisplayModeReady: handleDisplayModeReady,
|
|
204
|
+
debugInjectState: modelContext,
|
|
205
|
+
className: "h-full w-full"
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
} else if (resourceScript) {
|
|
209
|
+
content = /* @__PURE__ */ jsx(
|
|
210
|
+
IframeResource,
|
|
211
|
+
{
|
|
212
|
+
scriptSrc: resourceScript,
|
|
213
|
+
hostContext,
|
|
214
|
+
toolInput,
|
|
215
|
+
toolResult: effectiveToolResult,
|
|
216
|
+
csp,
|
|
217
|
+
hostOptions: {
|
|
218
|
+
onDisplayModeChange: handleDisplayModeChange,
|
|
219
|
+
onUpdateModelContext: handleUpdateModelContext
|
|
220
|
+
},
|
|
221
|
+
onDisplayModeReady: handleDisplayModeReady,
|
|
222
|
+
debugInjectState: modelContext,
|
|
223
|
+
className: "h-full w-full"
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
} else {
|
|
227
|
+
content = children;
|
|
228
|
+
}
|
|
229
|
+
return /* @__PURE__ */ jsx(ThemeProvider, { theme, children: /* @__PURE__ */ jsx(
|
|
230
|
+
SimpleSidebar,
|
|
231
|
+
{
|
|
232
|
+
controls: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
233
|
+
simulationNames.length > 1 && /* @__PURE__ */ jsx(SidebarControl, { label: "Simulation", children: /* @__PURE__ */ jsx(
|
|
234
|
+
SidebarSelect,
|
|
235
|
+
{
|
|
236
|
+
value: selectedSimulationName,
|
|
237
|
+
onChange: (value) => setSelectedSimulationName(value),
|
|
238
|
+
options: simulationNames.map((name) => {
|
|
239
|
+
const sim = simulations[name];
|
|
240
|
+
const resourceTitle = sim.resource.title || sim.resource.name;
|
|
241
|
+
const toolTitle = sim.tool.title || sim.tool.name;
|
|
242
|
+
return {
|
|
243
|
+
value: name,
|
|
244
|
+
label: `${resourceTitle}: ${toolTitle}`
|
|
245
|
+
};
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
) }),
|
|
249
|
+
/* @__PURE__ */ jsx(SidebarControl, { label: "Simulation Width", children: /* @__PURE__ */ jsx(
|
|
250
|
+
SidebarSelect,
|
|
251
|
+
{
|
|
252
|
+
value: screenWidth,
|
|
253
|
+
onChange: (value) => setScreenWidth(value),
|
|
254
|
+
options: [
|
|
255
|
+
{ value: "mobile-s", label: "Mobile S (375px)" },
|
|
256
|
+
{ value: "mobile-l", label: "Mobile L (425px)" },
|
|
257
|
+
{ value: "tablet", label: "Tablet (768px)" },
|
|
258
|
+
{ value: "full", label: "100% (Full)" }
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
) }),
|
|
262
|
+
/* @__PURE__ */ jsx(SidebarCollapsibleControl, { label: "Host Context", defaultCollapsed: false, children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
263
|
+
/* @__PURE__ */ jsx(SidebarControl, { label: "Theme", children: /* @__PURE__ */ jsx(
|
|
264
|
+
SidebarToggle,
|
|
265
|
+
{
|
|
266
|
+
value: theme,
|
|
267
|
+
onChange: (value) => setTheme(value),
|
|
268
|
+
options: [
|
|
269
|
+
{ value: "light", label: "Light" },
|
|
270
|
+
{ value: "dark", label: "Dark" }
|
|
271
|
+
]
|
|
272
|
+
}
|
|
273
|
+
) }),
|
|
274
|
+
/* @__PURE__ */ jsx(SidebarControl, { label: "Display Mode", children: /* @__PURE__ */ jsx(
|
|
275
|
+
SidebarToggle,
|
|
276
|
+
{
|
|
277
|
+
value: displayMode,
|
|
278
|
+
onChange: (value) => setDisplayMode(value),
|
|
279
|
+
options: [
|
|
280
|
+
{ value: "inline", label: "Inline" },
|
|
281
|
+
{ value: "pip", label: "PiP" },
|
|
282
|
+
{ value: "fullscreen", label: "Full" }
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
) }),
|
|
286
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
287
|
+
/* @__PURE__ */ jsx(SidebarControl, { label: "Locale", children: /* @__PURE__ */ jsx(
|
|
288
|
+
SidebarInput,
|
|
289
|
+
{
|
|
290
|
+
value: locale,
|
|
291
|
+
onChange: (value) => setLocale(value),
|
|
292
|
+
placeholder: "e.g. en-US"
|
|
293
|
+
}
|
|
294
|
+
) }),
|
|
295
|
+
/* @__PURE__ */ jsx(SidebarControl, { label: "Max Height (PiP)", children: /* @__PURE__ */ jsx(
|
|
296
|
+
SidebarInput,
|
|
297
|
+
{
|
|
298
|
+
type: "number",
|
|
299
|
+
value: displayMode === "pip" && containerMaxHeight !== void 0 ? String(containerMaxHeight) : "",
|
|
300
|
+
onChange: (value) => {
|
|
301
|
+
if (displayMode === "pip") {
|
|
302
|
+
setContainerMaxHeight(value ? Number(value) : 480);
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
placeholder: displayMode === "pip" ? "480" : "-",
|
|
306
|
+
disabled: displayMode !== "pip"
|
|
307
|
+
}
|
|
308
|
+
) })
|
|
309
|
+
] }),
|
|
310
|
+
/* @__PURE__ */ jsx(SidebarControl, { label: "Platform", children: /* @__PURE__ */ jsx(
|
|
311
|
+
SidebarSelect,
|
|
312
|
+
{
|
|
313
|
+
value: platform,
|
|
314
|
+
onChange: (value) => {
|
|
315
|
+
const p = value;
|
|
316
|
+
setPlatform(p);
|
|
317
|
+
if (p === "mobile") {
|
|
318
|
+
setHover(false);
|
|
319
|
+
setTouch(true);
|
|
320
|
+
} else if (p === "desktop") {
|
|
321
|
+
setHover(true);
|
|
322
|
+
setTouch(false);
|
|
323
|
+
} else {
|
|
324
|
+
setHover(true);
|
|
325
|
+
setTouch(false);
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
options: [
|
|
329
|
+
{ value: "mobile", label: "Mobile" },
|
|
330
|
+
{ value: "desktop", label: "Desktop" },
|
|
331
|
+
{ value: "web", label: "Web" }
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
) }),
|
|
335
|
+
/* @__PURE__ */ jsx("div", { className: "pl-4", children: /* @__PURE__ */ jsx(SidebarControl, { label: "Device Capabilities", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
336
|
+
/* @__PURE__ */ jsx(SidebarCheckbox, { checked: hover, onChange: setHover, label: "Hover" }),
|
|
337
|
+
/* @__PURE__ */ jsx(SidebarCheckbox, { checked: touch, onChange: setTouch, label: "Touch" })
|
|
338
|
+
] }) }) }),
|
|
339
|
+
/* @__PURE__ */ jsx(SidebarControl, { label: "Safe Area Insets", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-4 gap-1", children: [
|
|
340
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
341
|
+
/* @__PURE__ */ jsx(
|
|
342
|
+
"span",
|
|
343
|
+
{
|
|
344
|
+
className: "text-[10px]",
|
|
345
|
+
style: { color: "var(--color-text-secondary)" },
|
|
346
|
+
children: "↑"
|
|
347
|
+
}
|
|
348
|
+
),
|
|
349
|
+
/* @__PURE__ */ jsx(
|
|
350
|
+
SidebarInput,
|
|
351
|
+
{
|
|
352
|
+
type: "number",
|
|
353
|
+
value: String(safeAreaInsets.top),
|
|
354
|
+
onChange: (value) => setSafeAreaInsets((prev) => ({ ...prev, top: Number(value) }))
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
] }),
|
|
358
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
359
|
+
/* @__PURE__ */ jsx(
|
|
360
|
+
"span",
|
|
361
|
+
{
|
|
362
|
+
className: "text-[10px]",
|
|
363
|
+
style: { color: "var(--color-text-secondary)" },
|
|
364
|
+
children: "↓"
|
|
365
|
+
}
|
|
366
|
+
),
|
|
367
|
+
/* @__PURE__ */ jsx(
|
|
368
|
+
SidebarInput,
|
|
369
|
+
{
|
|
370
|
+
type: "number",
|
|
371
|
+
value: String(safeAreaInsets.bottom),
|
|
372
|
+
onChange: (value) => setSafeAreaInsets((prev) => ({ ...prev, bottom: Number(value) }))
|
|
373
|
+
}
|
|
374
|
+
)
|
|
375
|
+
] }),
|
|
376
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
377
|
+
/* @__PURE__ */ jsx(
|
|
378
|
+
"span",
|
|
379
|
+
{
|
|
380
|
+
className: "text-[10px]",
|
|
381
|
+
style: { color: "var(--color-text-secondary)" },
|
|
382
|
+
children: "←"
|
|
383
|
+
}
|
|
384
|
+
),
|
|
385
|
+
/* @__PURE__ */ jsx(
|
|
386
|
+
SidebarInput,
|
|
387
|
+
{
|
|
388
|
+
type: "number",
|
|
389
|
+
value: String(safeAreaInsets.left),
|
|
390
|
+
onChange: (value) => setSafeAreaInsets((prev) => ({ ...prev, left: Number(value) }))
|
|
391
|
+
}
|
|
392
|
+
)
|
|
393
|
+
] }),
|
|
394
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
395
|
+
/* @__PURE__ */ jsx(
|
|
396
|
+
"span",
|
|
397
|
+
{
|
|
398
|
+
className: "text-[10px]",
|
|
399
|
+
style: { color: "var(--color-text-secondary)" },
|
|
400
|
+
children: "→"
|
|
401
|
+
}
|
|
402
|
+
),
|
|
403
|
+
/* @__PURE__ */ jsx(
|
|
404
|
+
SidebarInput,
|
|
405
|
+
{
|
|
406
|
+
type: "number",
|
|
407
|
+
value: String(safeAreaInsets.right),
|
|
408
|
+
onChange: (value) => setSafeAreaInsets((prev) => ({ ...prev, right: Number(value) }))
|
|
409
|
+
}
|
|
410
|
+
)
|
|
411
|
+
] })
|
|
412
|
+
] }) })
|
|
413
|
+
] }) }),
|
|
414
|
+
/* @__PURE__ */ jsx(SidebarCollapsibleControl, { label: "App Context", defaultCollapsed: true, children: /* @__PURE__ */ jsx(
|
|
415
|
+
SidebarTextarea,
|
|
416
|
+
{
|
|
417
|
+
value: modelContextJson,
|
|
418
|
+
onChange: (json) => validateJSON(json, setModelContextJson, setModelContextError),
|
|
419
|
+
onFocus: () => setEditingField("modelContext"),
|
|
420
|
+
onBlur: () => commitJSON(modelContextJson, setModelContextError, (parsed) => {
|
|
421
|
+
setModelContext(parsed);
|
|
422
|
+
}),
|
|
423
|
+
error: modelContextError,
|
|
424
|
+
maxRows: 8
|
|
425
|
+
}
|
|
426
|
+
) }),
|
|
427
|
+
/* @__PURE__ */ jsx(SidebarCollapsibleControl, { label: "Tool Input (JSON)", children: /* @__PURE__ */ jsx(
|
|
428
|
+
SidebarTextarea,
|
|
429
|
+
{
|
|
430
|
+
value: toolInputJson,
|
|
431
|
+
onChange: (json) => validateJSON(json, setToolInputJson, setToolInputError),
|
|
432
|
+
onFocus: () => setEditingField("toolInput"),
|
|
433
|
+
onBlur: () => commitJSON(
|
|
434
|
+
toolInputJson,
|
|
435
|
+
setToolInputError,
|
|
436
|
+
(parsed) => setToolInput(parsed ?? {})
|
|
437
|
+
),
|
|
438
|
+
error: toolInputError,
|
|
439
|
+
maxRows: 8
|
|
440
|
+
}
|
|
441
|
+
) }),
|
|
442
|
+
/* @__PURE__ */ jsx(SidebarCollapsibleControl, { label: "Tool Result (JSON)", children: /* @__PURE__ */ jsx(
|
|
443
|
+
SidebarTextarea,
|
|
444
|
+
{
|
|
445
|
+
value: toolResultJson,
|
|
446
|
+
onChange: (json) => validateJSON(json, setToolResultJson, setToolResultError),
|
|
447
|
+
onFocus: () => setEditingField("toolResult"),
|
|
448
|
+
onBlur: () => commitJSON(toolResultJson, setToolResultError, (parsed) => {
|
|
449
|
+
if (parsed === null) {
|
|
450
|
+
setToolResult(void 0);
|
|
451
|
+
} else {
|
|
452
|
+
const result = parsed;
|
|
453
|
+
if ("content" in result || "structuredContent" in result) {
|
|
454
|
+
setToolResult(result);
|
|
455
|
+
} else {
|
|
456
|
+
setToolResult({ content: [], structuredContent: result });
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}),
|
|
460
|
+
error: toolResultError,
|
|
461
|
+
maxRows: 8
|
|
462
|
+
}
|
|
463
|
+
) })
|
|
464
|
+
] }),
|
|
465
|
+
children: /* @__PURE__ */ jsx(
|
|
466
|
+
Conversation,
|
|
467
|
+
{
|
|
468
|
+
screenWidth,
|
|
469
|
+
displayMode,
|
|
470
|
+
platform,
|
|
471
|
+
onRequestDisplayMode: handleDisplayModeChange,
|
|
472
|
+
appName,
|
|
473
|
+
appIcon,
|
|
474
|
+
userMessage: selectedSim?.userMessage,
|
|
475
|
+
isTransitioning,
|
|
476
|
+
children: content
|
|
477
|
+
},
|
|
478
|
+
selectedSimulationName
|
|
479
|
+
)
|
|
480
|
+
}
|
|
481
|
+
) });
|
|
482
|
+
}
|
|
483
|
+
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
484
|
+
__proto__: null,
|
|
485
|
+
ChatGPTSimulator,
|
|
486
|
+
IframeResource,
|
|
487
|
+
McpAppHost,
|
|
488
|
+
SCREEN_WIDTHS,
|
|
489
|
+
Simulator,
|
|
490
|
+
ThemeProvider,
|
|
491
|
+
buildDevSimulations,
|
|
492
|
+
buildResourceMap,
|
|
493
|
+
buildSimulations,
|
|
494
|
+
createResourceExports,
|
|
495
|
+
createSimulatorUrl,
|
|
496
|
+
extractResourceCSP,
|
|
497
|
+
extractResourceKey,
|
|
498
|
+
extractSimulationKey,
|
|
499
|
+
extractSimulationName,
|
|
500
|
+
findResourceDirs,
|
|
501
|
+
findResourceKey,
|
|
502
|
+
findSimulationFiles,
|
|
503
|
+
getComponentName,
|
|
504
|
+
isSimulationFile,
|
|
505
|
+
toPascalCase,
|
|
506
|
+
useThemeContext
|
|
507
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
508
|
+
export {
|
|
509
|
+
ChatGPTSimulator as C,
|
|
510
|
+
index as i
|
|
511
|
+
};
|
|
512
|
+
//# sourceMappingURL=index-CiqvXo8n.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-CiqvXo8n.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., 'albums-show')\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 let content: React.ReactNode;\n if (resourceUrl) {\n // Dev mode: load HTML page directly (supports Vite HMR)\n content = (\n <IframeResource\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 );\n } else if (resourceScript) {\n // Production mode: generate HTML wrapper for script\n content = (\n <IframeResource\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 );\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 ↑\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 ↓\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 ←\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 →\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 key={selectedSimulationName}\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;AAE5D,MAAI;AACJ,MAAI,aAAa;AAEf,cACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,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,IAAA;AAAA,EAGhB,WAAW,gBAAgB;AAEzB,cACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,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,IAAA;AAAA,EAGhB,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,UAGC,UAAA;AAAA,QAAA;AAAA,QAFI;AAAA,MAAA;AAAA,IAGP;AAAA,EAAA,GAEJ;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const simulatorUrl = require("./simulator-url-uNqOCaPJ.cjs");
|
|
3
|
+
require("./claude-host-C7KPfOM8.cjs");
|
|
4
|
+
const simulator = require("./simulator-BqZmzFVR.cjs");
|
|
5
|
+
const discovery = require("./discovery-CRR3SlyI.cjs");
|
|
6
|
+
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
7
|
+
__proto__: null,
|
|
8
|
+
IframeResource: simulator.IframeResource,
|
|
9
|
+
McpAppHost: simulator.McpAppHost,
|
|
10
|
+
SCREEN_WIDTHS: simulator.SCREEN_WIDTHS,
|
|
11
|
+
SidebarCheckbox: simulator.SidebarCheckbox,
|
|
12
|
+
SidebarCollapsibleControl: simulator.SidebarCollapsibleControl,
|
|
13
|
+
SidebarControl: simulator.SidebarControl,
|
|
14
|
+
SidebarInput: simulator.SidebarInput,
|
|
15
|
+
SidebarSelect: simulator.SidebarSelect,
|
|
16
|
+
SidebarTextarea: simulator.SidebarTextarea,
|
|
17
|
+
SidebarToggle: simulator.SidebarToggle,
|
|
18
|
+
SimpleSidebar: simulator.SimpleSidebar,
|
|
19
|
+
Simulator: simulator.Simulator,
|
|
20
|
+
ThemeProvider: simulator.ThemeProvider,
|
|
21
|
+
buildDevSimulations: discovery.buildDevSimulations,
|
|
22
|
+
buildResourceMap: discovery.buildResourceMap,
|
|
23
|
+
buildSimulations: discovery.buildSimulations,
|
|
24
|
+
createResourceExports: discovery.createResourceExports,
|
|
25
|
+
createSimulatorUrl: simulatorUrl.createSimulatorUrl,
|
|
26
|
+
extractResourceCSP: simulator.extractResourceCSP,
|
|
27
|
+
extractResourceKey: discovery.extractResourceKey,
|
|
28
|
+
extractSimulationKey: discovery.extractSimulationKey,
|
|
29
|
+
extractSimulationName: discovery.extractSimulationName,
|
|
30
|
+
findResourceDirs: discovery.findResourceDirs,
|
|
31
|
+
findResourceKey: discovery.findResourceKey,
|
|
32
|
+
findSimulationFiles: discovery.findSimulationFiles,
|
|
33
|
+
getComponentName: discovery.getComponentName,
|
|
34
|
+
getHostShell: simulator.getHostShell,
|
|
35
|
+
getRegisteredHosts: simulator.getRegisteredHosts,
|
|
36
|
+
isSimulationFile: discovery.isSimulationFile,
|
|
37
|
+
registerHostShell: simulator.registerHostShell,
|
|
38
|
+
toPascalCase: discovery.toPascalCase,
|
|
39
|
+
useSimulatorState: simulator.useSimulatorState,
|
|
40
|
+
useThemeContext: simulator.useThemeContext
|
|
41
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
42
|
+
exports.index = index;
|
|
43
|
+
//# sourceMappingURL=index-Dr-L0Nb3.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-Dr-L0Nb3.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|