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.
Files changed (128) hide show
  1. package/README.md +32 -28
  2. package/bin/commands/build.mjs +2 -1
  3. package/bin/commands/dev.mjs +72 -2
  4. package/dist/chatgpt/{conversation.d.ts → chatgpt-conversation.d.ts} +1 -1
  5. package/dist/chatgpt/chatgpt-host.d.ts +1 -0
  6. package/dist/chatgpt/globals.css +618 -6156
  7. package/dist/chatgpt/index.cjs +11 -8
  8. package/dist/chatgpt/index.cjs.map +1 -1
  9. package/dist/chatgpt/index.d.ts +10 -32
  10. package/dist/chatgpt/index.js +15 -12
  11. package/dist/chatgpt/index.js.map +1 -1
  12. package/dist/claude/claude-conversation.d.ts +23 -0
  13. package/dist/claude/claude-host.d.ts +1 -0
  14. package/dist/claude/index.cjs +6 -0
  15. package/dist/claude/index.cjs.map +1 -0
  16. package/dist/claude/index.d.ts +1 -0
  17. package/dist/claude/index.js +6 -0
  18. package/dist/claude/index.js.map +1 -0
  19. package/dist/claude-host-C7KPfOM8.cjs +284 -0
  20. package/dist/claude-host-C7KPfOM8.cjs.map +1 -0
  21. package/dist/claude-host-CaD7ptbt.js +283 -0
  22. package/dist/claude-host-CaD7ptbt.js.map +1 -0
  23. package/dist/{discovery-COZUnY6a.js → discovery-DzV3HLXs.js} +5 -5
  24. package/dist/{discovery-COZUnY6a.js.map → discovery-DzV3HLXs.js.map} +1 -1
  25. package/dist/hooks/index.d.ts +4 -0
  26. package/dist/hooks/use-app-tools.d.ts +44 -0
  27. package/dist/hooks/use-update-model-context.d.ts +29 -0
  28. package/dist/index-BKrboRah.js +44 -0
  29. package/dist/index-BKrboRah.js.map +1 -0
  30. package/dist/index-BSKuY-oH.cjs +527 -0
  31. package/dist/index-BSKuY-oH.cjs.map +1 -0
  32. package/dist/index-CiqvXo8n.js +512 -0
  33. package/dist/index-CiqvXo8n.js.map +1 -0
  34. package/dist/index-Dr-L0Nb3.cjs +43 -0
  35. package/dist/index-Dr-L0Nb3.cjs.map +1 -0
  36. package/dist/index.cjs +1705 -1647
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.js +2732 -2675
  40. package/dist/index.js.map +1 -1
  41. package/dist/lib/default-style-variables.d.ts +2 -0
  42. package/dist/lib/discovery-cli.js +1 -1
  43. package/dist/mcp/index.cjs +86 -27
  44. package/dist/mcp/index.cjs.map +1 -1
  45. package/dist/mcp/index.d.ts +3 -1
  46. package/dist/mcp/index.js +85 -26
  47. package/dist/mcp/index.js.map +1 -1
  48. package/dist/mcp/server.d.ts +4 -3
  49. package/dist/mcp/types.d.ts +11 -0
  50. package/dist/platform/chatgpt/index.cjs +1 -1
  51. package/dist/platform/chatgpt/index.js +1 -1
  52. package/dist/platform/index.cjs +3 -0
  53. package/dist/platform/index.cjs.map +1 -1
  54. package/dist/platform/index.d.ts +3 -1
  55. package/dist/platform/index.js +3 -0
  56. package/dist/platform/index.js.map +1 -1
  57. package/dist/{protocol-BQCnIrc9.js → protocol-DFbsCx7E.js} +29 -29
  58. package/dist/{protocol-BQCnIrc9.js.map → protocol-DFbsCx7E.js.map} +1 -1
  59. package/dist/simulator/host-styles.d.ts +5 -0
  60. package/dist/simulator/hosts.d.ts +73 -0
  61. package/dist/{chatgpt → simulator}/iframe-resource.d.ts +27 -3
  62. package/dist/simulator/index.cjs +40 -0
  63. package/dist/simulator/index.cjs.map +1 -0
  64. package/dist/simulator/index.d.ts +18 -0
  65. package/dist/simulator/index.js +40 -0
  66. package/dist/simulator/index.js.map +1 -0
  67. package/dist/{chatgpt → simulator}/mcp-app-host.d.ts +8 -1
  68. package/dist/simulator/mock-openai-runtime.d.ts +20 -0
  69. package/dist/{chatgpt → simulator}/simulator-url.d.ts +8 -1
  70. package/dist/simulator/simulator.d.ts +12 -0
  71. package/dist/{chatgpt → simulator}/theme-provider.d.ts +3 -1
  72. package/dist/simulator/use-simulator-state.d.ts +91 -0
  73. package/dist/simulator-BqZmzFVR.cjs +8214 -0
  74. package/dist/simulator-BqZmzFVR.cjs.map +1 -0
  75. package/dist/simulator-CMgCGNuD.js +8199 -0
  76. package/dist/simulator-CMgCGNuD.js.map +1 -0
  77. package/dist/simulator-url-BQ-7SMht.js +335 -0
  78. package/dist/simulator-url-BQ-7SMht.js.map +1 -0
  79. package/dist/simulator-url-uNqOCaPJ.cjs +334 -0
  80. package/dist/simulator-url-uNqOCaPJ.cjs.map +1 -0
  81. package/dist/style.css +558 -6143
  82. package/dist/types/runtime.d.ts +1 -1
  83. package/dist/{use-app-D7kRAPSG.cjs → use-app-BnoSPiUT.cjs} +2 -1
  84. package/dist/{use-app-D7kRAPSG.cjs.map → use-app-BnoSPiUT.cjs.map} +1 -1
  85. package/dist/{use-app-Dvr4LKs2.js → use-app-D_TeaMFG.js} +4 -3
  86. package/dist/{use-app-Dvr4LKs2.js.map → use-app-D_TeaMFG.js.map} +1 -1
  87. package/package.json +18 -3
  88. package/template/.sunpeak/dev.tsx +4 -4
  89. package/template/.sunpeak/resource-loader.html +1 -1
  90. package/template/node_modules/.bin/nodemon +2 -2
  91. package/template/node_modules/.bin/playwright +2 -2
  92. package/template/node_modules/.bin/sunpeak +2 -2
  93. package/template/node_modules/.bin/tsc +2 -2
  94. package/template/node_modules/.bin/tsserver +2 -2
  95. package/template/node_modules/.bin/tsx +2 -2
  96. package/template/node_modules/.bin/vite +2 -2
  97. package/template/src/components/avatar.tsx +4 -1
  98. package/template/src/components/button.tsx +17 -20
  99. package/template/src/resources/albums/albums-resource.tsx +2 -3
  100. package/template/src/resources/albums/components/album-card.tsx +4 -2
  101. package/template/src/resources/albums/components/film-strip.test.tsx +2 -2
  102. package/template/src/resources/albums/components/film-strip.tsx +2 -2
  103. package/template/src/resources/albums/components/fullscreen-viewer.tsx +7 -5
  104. package/template/src/resources/carousel/carousel-resource.tsx +2 -3
  105. package/template/src/resources/carousel/components/card.test.tsx +3 -2
  106. package/template/src/resources/carousel/components/card.tsx +8 -4
  107. package/template/src/resources/map/components/map-view.tsx +1 -1
  108. package/template/src/resources/map/components/map.tsx +1 -1
  109. package/template/src/resources/map/components/place-card.tsx +8 -4
  110. package/template/src/resources/map/components/place-carousel.tsx +1 -1
  111. package/template/src/resources/map/components/place-inspector.tsx +15 -7
  112. package/template/src/resources/map/components/place-list.tsx +7 -4
  113. package/template/src/resources/map/map-resource.tsx +0 -2
  114. package/template/src/resources/review/review-resource.tsx +61 -27
  115. package/template/tests/e2e/albums.spec.ts +118 -102
  116. package/template/tests/e2e/carousel.spec.ts +103 -100
  117. package/template/tests/e2e/map.spec.ts +220 -181
  118. package/template/tests/e2e/review.spec.ts +224 -198
  119. package/dist/_commonjsHelpers-Bc2YnDe1.cjs +0 -8
  120. package/dist/_commonjsHelpers-Bc2YnDe1.cjs.map +0 -1
  121. package/dist/_commonjsHelpers-DWwsNxpa.js +0 -9
  122. package/dist/_commonjsHelpers-DWwsNxpa.js.map +0 -1
  123. package/dist/index-CJ3jfcjj.js +0 -15131
  124. package/dist/index-CJ3jfcjj.js.map +0 -1
  125. package/dist/index-Cdeg96So.cjs +0 -15147
  126. package/dist/index-Cdeg96So.cjs.map +0 -1
  127. /package/dist/{chatgpt → simulator}/simple-sidebar.d.ts +0 -0
  128. /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 &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 key={selectedSimulationName}\n >\n {content}\n </Conversation>\n </SimpleSidebar>\n </ThemeProvider>\n );\n}\n"],"names":["content"],"mappings":"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"}
@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}