sunpeak 0.13.5 → 0.13.7
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/dist/chatgpt/conversation.d.ts +1 -7
- package/dist/chatgpt/iframe-resource.d.ts +13 -8
- package/dist/chatgpt/index.cjs +2 -1
- package/dist/chatgpt/index.cjs.map +1 -1
- package/dist/chatgpt/index.d.ts +1 -1
- package/dist/chatgpt/index.js +4 -3
- package/dist/chatgpt/mcp-app-host.d.ts +5 -0
- package/dist/{index-FiqdlIXV.cjs → index-B9MMk69u.cjs} +93 -59
- package/dist/index-B9MMk69u.cjs.map +1 -0
- package/dist/{index-BMqwRYBo.js → index-DqOCq5r8.js} +92 -58
- package/dist/index-DqOCq5r8.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/template/dist/albums/albums.json +1 -1
- package/template/dist/carousel/carousel.json +1 -1
- package/template/dist/map/map.json +1 -1
- package/template/dist/review/review.json +1 -1
- package/template/node_modules/.vite/deps/_metadata.json +25 -25
- package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/dist/index-BMqwRYBo.js.map +0 -1
- package/dist/index-FiqdlIXV.cjs.map +0 -1
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@modelcontextprotocol_ext-apps.js +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@modelcontextprotocol_ext-apps.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@modelcontextprotocol_ext-apps_app-bridge.js +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@modelcontextprotocol_ext-apps_app-bridge.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@modelcontextprotocol_ext-apps_react.js +3 -3
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@modelcontextprotocol_ext-apps_react.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Avatar.js +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Avatar.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Button.js +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Button.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Checkbox.js +1 -1
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Checkbox.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Icon.js +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Icon.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Input.js +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Input.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_SegmentedControl.js +4 -4
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_SegmentedControl.js.map +0 -0
- package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Select.js +7 -7
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Select.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Textarea.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_components_Textarea.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_theme.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/@openai_apps-sdk-ui_theme.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-3FUH6LFP.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-3FUH6LFP.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-4EQ7FTMQ.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-4EQ7FTMQ.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-4WVD247F.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-4WVD247F.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-ABGJ7IDC.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-ABGJ7IDC.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-DP4XHQAG.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-DP4XHQAG.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-EGRHWZRV.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-EGRHWZRV.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-EHI2XMPP.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-EHI2XMPP.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-JWMBYPFX.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-JWMBYPFX.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-PZDCUP6P.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-PZDCUP6P.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-Q2RBUOJ3.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-Q2RBUOJ3.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-SPDZ46BB.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-SPDZ46BB.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-WEIC4XKX.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-WEIC4XKX.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-WSHFT23M.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-WSHFT23M.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-XQARMNNG.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/chunk-XQARMNNG.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/clsx.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/clsx.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/embla-carousel-react.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/embla-carousel-react.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/embla-carousel-wheel-gestures.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/embla-carousel-wheel-gestures.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/mapbox-gl.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/mapbox-gl.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/package.json +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react-dom.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react-dom.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react-dom_client.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react-dom_client.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react_jsx-dev-runtime.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react_jsx-dev-runtime.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react_jsx-runtime.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/react_jsx-runtime.js.map +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/tailwind-merge.js +0 -0
- /package/template/node_modules/.vite-mcp/{deps_temp_f77cfa16 → deps_temp_78ab0da5}/tailwind-merge.js.map +0 -0
|
@@ -11,12 +11,6 @@ interface ConversationProps {
|
|
|
11
11
|
appName?: string;
|
|
12
12
|
appIcon?: string;
|
|
13
13
|
userMessage?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Whether the content is transitioning between display modes.
|
|
16
|
-
* When true, the content area is hidden (opacity 0) to prevent flashing
|
|
17
|
-
* stale content in the new layout.
|
|
18
|
-
*/
|
|
19
|
-
isTransitioning?: boolean;
|
|
20
14
|
}
|
|
21
15
|
/**
|
|
22
16
|
* Conversation layout that renders children (iframe) at a stable tree position.
|
|
@@ -31,5 +25,5 @@ interface ConversationProps {
|
|
|
31
25
|
* - **fullscreen**: content wrapper becomes `position: fixed` covering the viewport;
|
|
32
26
|
* fullscreen chrome (header/footer) rendered as a separate fixed overlay
|
|
33
27
|
*/
|
|
34
|
-
export declare function Conversation({ children, screenWidth, displayMode, platform, onRequestDisplayMode, appName, appIcon, userMessage,
|
|
28
|
+
export declare function Conversation({ children, screenWidth, displayMode, platform, onRequestDisplayMode, appName, appIcon, userMessage, }: ConversationProps): import("react/jsx-runtime").JSX.Element;
|
|
35
29
|
export {};
|
|
@@ -20,6 +20,17 @@ export interface ResourceCSP {
|
|
|
20
20
|
/** Domains allowed for scripts, images, styles, fonts */
|
|
21
21
|
resourceDomains?: string[];
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Extract CSP configuration from a resource's _meta.ui.csp field.
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractResourceCSP(resource: {
|
|
27
|
+
_meta?: unknown;
|
|
28
|
+
}): ResourceCSP | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Validates a CSP source entry is a safe origin URL (scheme + host + optional port).
|
|
31
|
+
* Rejects wildcards, CSP keywords, and whitespace that could inject extra directives.
|
|
32
|
+
*/
|
|
33
|
+
declare function isValidCspSource(source: string): boolean;
|
|
23
34
|
/**
|
|
24
35
|
* Generates a Content Security Policy string.
|
|
25
36
|
*/
|
|
@@ -56,13 +67,6 @@ interface IframeResourceProps {
|
|
|
56
67
|
className?: string;
|
|
57
68
|
/** Optional style for the iframe */
|
|
58
69
|
style?: React.CSSProperties;
|
|
59
|
-
/**
|
|
60
|
-
* Called after the iframe has rendered following a display mode change.
|
|
61
|
-
* The callback receives the display mode that was confirmed.
|
|
62
|
-
* Used by the simulator to hide content during transitions and only
|
|
63
|
-
* reveal it once the app has committed its DOM for the new mode.
|
|
64
|
-
*/
|
|
65
|
-
onDisplayModeReady?: (mode: string) => void;
|
|
66
70
|
/**
|
|
67
71
|
* Debug: State to inject directly into the app's useAppState hook.
|
|
68
72
|
* This bypasses the normal MCP Apps protocol and is for simulator testing.
|
|
@@ -81,10 +85,11 @@ interface IframeResourceProps {
|
|
|
81
85
|
* connects via PostMessageTransport to window.parent. The parent side uses
|
|
82
86
|
* McpAppHost (wrapping AppBridge) to communicate.
|
|
83
87
|
*/
|
|
84
|
-
export declare function IframeResource({ src, scriptSrc, hostContext, toolInput, toolResult, hostOptions, csp, className, style,
|
|
88
|
+
export declare function IframeResource({ src, scriptSrc, hostContext, toolInput, toolResult, hostOptions, csp, className, style, debugInjectState, }: IframeResourceProps): import("react/jsx-runtime").JSX.Element;
|
|
85
89
|
export declare const _testExports: {
|
|
86
90
|
escapeHtml: typeof escapeHtml;
|
|
87
91
|
isAllowedUrl: typeof isAllowedUrl;
|
|
92
|
+
isValidCspSource: typeof isValidCspSource;
|
|
88
93
|
generateCSP: typeof generateCSP;
|
|
89
94
|
generateScriptHtml: typeof generateScriptHtml;
|
|
90
95
|
ALLOWED_SCRIPT_ORIGINS: string[];
|
package/dist/chatgpt/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const chatgpt_index = require("../index-
|
|
3
|
+
const chatgpt_index = require("../index-B9MMk69u.cjs");
|
|
4
4
|
const discovery = require("../discovery-CRR3SlyI.cjs");
|
|
5
5
|
exports.ChatGPTSimulator = chatgpt_index.ChatGPTSimulator;
|
|
6
6
|
exports.IframeResource = chatgpt_index.IframeResource;
|
|
@@ -8,6 +8,7 @@ exports.McpAppHost = chatgpt_index.McpAppHost;
|
|
|
8
8
|
exports.SCREEN_WIDTHS = chatgpt_index.SCREEN_WIDTHS;
|
|
9
9
|
exports.ThemeProvider = chatgpt_index.ThemeProvider;
|
|
10
10
|
exports.createSimulatorUrl = chatgpt_index.createSimulatorUrl;
|
|
11
|
+
exports.extractResourceCSP = chatgpt_index.extractResourceCSP;
|
|
11
12
|
exports.useThemeContext = chatgpt_index.useThemeContext;
|
|
12
13
|
exports.buildDevSimulations = discovery.buildDevSimulations;
|
|
13
14
|
exports.buildResourceMap = discovery.buildResourceMap;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/chatgpt/index.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export type { ScreenWidth, SimulatorConfig } from './chatgpt-simulator-types';
|
|
|
27
27
|
export { SCREEN_WIDTHS } from './chatgpt-simulator-types';
|
|
28
28
|
export { McpAppHost } from './mcp-app-host';
|
|
29
29
|
export type { McpAppHostOptions } from './mcp-app-host';
|
|
30
|
-
export { IframeResource } from './iframe-resource';
|
|
30
|
+
export { IframeResource, extractResourceCSP } from './iframe-resource';
|
|
31
31
|
export type { ResourceCSP } from './iframe-resource';
|
|
32
32
|
export * from './theme-provider';
|
|
33
33
|
export { createSimulatorUrl } from './simulator-url';
|
package/dist/chatgpt/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C, I, M, S, T, a, u } from "../index-
|
|
2
|
-
import { a as a2, b, d, c, e, f, g, h, i, j, k, l, t } from "../discovery-COZUnY6a.js";
|
|
1
|
+
import { C, I, M, S, T, a, e, u } from "../index-DqOCq5r8.js";
|
|
2
|
+
import { a as a2, b, d, c, e as e2, f, g, h, i, j, k, l, t } from "../discovery-COZUnY6a.js";
|
|
3
3
|
export {
|
|
4
4
|
C as ChatGPTSimulator,
|
|
5
5
|
I as IframeResource,
|
|
@@ -11,7 +11,8 @@ export {
|
|
|
11
11
|
d as buildSimulations,
|
|
12
12
|
c as createResourceExports,
|
|
13
13
|
a as createSimulatorUrl,
|
|
14
|
-
e as
|
|
14
|
+
e as extractResourceCSP,
|
|
15
|
+
e2 as extractResourceKey,
|
|
15
16
|
f as extractSimulationKey,
|
|
16
17
|
g as extractSimulationName,
|
|
17
18
|
h as findResourceDirs,
|
|
@@ -12,6 +12,8 @@ export interface McpAppHostOptions {
|
|
|
12
12
|
}) => void;
|
|
13
13
|
onLog?: (params: LoggingMessageNotification['params']) => void;
|
|
14
14
|
onCallTool?: (params: CallToolRequest['params']) => CallToolResult | Promise<CallToolResult>;
|
|
15
|
+
/** Called after the iframe confirms rendering in a new display mode (paint fence resolved). */
|
|
16
|
+
onDisplayModeReady?: (mode: string) => void;
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* MCP Apps host for the Sunpeak simulator.
|
|
@@ -25,6 +27,7 @@ export declare class McpAppHost {
|
|
|
25
27
|
private _contentWindow;
|
|
26
28
|
private _fenceId;
|
|
27
29
|
private _fenceCleanup;
|
|
30
|
+
private _prevDisplayMode;
|
|
28
31
|
private _pendingToolInput;
|
|
29
32
|
private _pendingToolResult;
|
|
30
33
|
constructor(options?: McpAppHostOptions);
|
|
@@ -46,6 +49,8 @@ export declare class McpAppHost {
|
|
|
46
49
|
waitForPaint(): Promise<void>;
|
|
47
50
|
/**
|
|
48
51
|
* Update the host context and notify the connected app.
|
|
52
|
+
* Automatically detects display mode changes and waits for the iframe
|
|
53
|
+
* to commit its DOM before firing onDisplayModeReady.
|
|
49
54
|
*/
|
|
50
55
|
setHostContext(context: McpUiHostContext): void;
|
|
51
56
|
/**
|
|
@@ -5442,7 +5442,7 @@ const useEscCloseStack = (listening, cb) => {
|
|
|
5442
5442
|
}, [id, listening, latestCallback]);
|
|
5443
5443
|
};
|
|
5444
5444
|
const __vite_import_meta_env__ = { "DEV": false, "MODE": "production" };
|
|
5445
|
-
const META_ENV = typeof { url: typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-
|
|
5445
|
+
const META_ENV = typeof { url: typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index-B9MMk69u.cjs", document.baseURI).href } !== "undefined" ? __vite_import_meta_env__ : void 0;
|
|
5446
5446
|
const NODE_ENV = typeof process !== "undefined" && process.env?.NODE_ENV ? process.env?.NODE_ENV : "production";
|
|
5447
5447
|
const isDev = NODE_ENV === "development" || !!META_ENV?.DEV;
|
|
5448
5448
|
const isJSDomLike = typeof navigator !== "undefined" && /(jsdom|happy-dom)/i.test(navigator.userAgent) || typeof globalThis.happyDOM === "object";
|
|
@@ -7545,8 +7545,7 @@ function Conversation({
|
|
|
7545
7545
|
onRequestDisplayMode,
|
|
7546
7546
|
appName = "Sunpeak",
|
|
7547
7547
|
appIcon,
|
|
7548
|
-
userMessage = "What have you got for me today?"
|
|
7549
|
-
isTransitioning = false
|
|
7548
|
+
userMessage = "What have you got for me today?"
|
|
7550
7549
|
}) {
|
|
7551
7550
|
const isDesktop = platform2 === "desktop";
|
|
7552
7551
|
const containerWidth = screenWidth === "full" ? "100%" : `${SCREEN_WIDTHS[screenWidth]}px`;
|
|
@@ -7668,12 +7667,6 @@ function Conversation({
|
|
|
7668
7667
|
"div",
|
|
7669
7668
|
{
|
|
7670
7669
|
className: isPip ? "h-full w-full max-w-full overflow-auto bg-white dark:bg-[#212121]" : isFullscreen ? "h-full w-full max-w-full overflow-auto bg-surface" : "h-full w-full max-w-full bg-transparent",
|
|
7671
|
-
style: {
|
|
7672
|
-
opacity: isTransitioning ? 0 : 1,
|
|
7673
|
-
// Only animate the reveal — the hide must be instant
|
|
7674
|
-
// to prevent old content from being visible in the new layout.
|
|
7675
|
-
transition: isTransitioning ? "none" : "opacity 100ms"
|
|
7676
|
-
},
|
|
7677
7670
|
children
|
|
7678
7671
|
}
|
|
7679
7672
|
)
|
|
@@ -14071,10 +14064,12 @@ class McpAppHost {
|
|
|
14071
14064
|
_contentWindow = null;
|
|
14072
14065
|
_fenceId = 0;
|
|
14073
14066
|
_fenceCleanup = null;
|
|
14067
|
+
_prevDisplayMode;
|
|
14074
14068
|
_pendingToolInput = null;
|
|
14075
14069
|
_pendingToolResult = null;
|
|
14076
14070
|
constructor(options = {}) {
|
|
14077
14071
|
this.options = options;
|
|
14072
|
+
this._prevDisplayMode = options.hostContext?.displayMode;
|
|
14078
14073
|
this.bridge = new j_(null, HOST_INFO, HOST_CAPABILITIES, {
|
|
14079
14074
|
hostContext: options.hostContext
|
|
14080
14075
|
});
|
|
@@ -14094,6 +14089,16 @@ class McpAppHost {
|
|
|
14094
14089
|
if (this.options.onOpenLink) {
|
|
14095
14090
|
this.options.onOpenLink(url);
|
|
14096
14091
|
} else {
|
|
14092
|
+
try {
|
|
14093
|
+
const parsed = new URL(url);
|
|
14094
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
14095
|
+
console.warn("[MCP App] openLink blocked non-http(s) URL:", url);
|
|
14096
|
+
return {};
|
|
14097
|
+
}
|
|
14098
|
+
} catch {
|
|
14099
|
+
console.warn("[MCP App] openLink blocked invalid URL:", url);
|
|
14100
|
+
return {};
|
|
14101
|
+
}
|
|
14097
14102
|
window.open(url, "_blank");
|
|
14098
14103
|
}
|
|
14099
14104
|
return {};
|
|
@@ -14175,6 +14180,7 @@ class McpAppHost {
|
|
|
14175
14180
|
const id = ++this._fenceId;
|
|
14176
14181
|
return new Promise((resolve) => {
|
|
14177
14182
|
const handler = (event) => {
|
|
14183
|
+
if (event.source !== win) return;
|
|
14178
14184
|
if (event.data?.method === "sunpeak/fence-ack" && event.data.params?.fenceId === id) {
|
|
14179
14185
|
cleanup();
|
|
14180
14186
|
resolve();
|
|
@@ -14198,9 +14204,19 @@ class McpAppHost {
|
|
|
14198
14204
|
}
|
|
14199
14205
|
/**
|
|
14200
14206
|
* Update the host context and notify the connected app.
|
|
14207
|
+
* Automatically detects display mode changes and waits for the iframe
|
|
14208
|
+
* to commit its DOM before firing onDisplayModeReady.
|
|
14201
14209
|
*/
|
|
14202
14210
|
setHostContext(context) {
|
|
14203
14211
|
this.bridge.setHostContext(context);
|
|
14212
|
+
const currentMode = context.displayMode;
|
|
14213
|
+
if (currentMode && currentMode !== this._prevDisplayMode) {
|
|
14214
|
+
this._prevDisplayMode = currentMode;
|
|
14215
|
+
const mode = currentMode;
|
|
14216
|
+
this.waitForPaint().then(() => {
|
|
14217
|
+
this.options.onDisplayModeReady?.(mode);
|
|
14218
|
+
});
|
|
14219
|
+
}
|
|
14204
14220
|
}
|
|
14205
14221
|
/**
|
|
14206
14222
|
* Send tool input to the app.
|
|
@@ -14259,7 +14275,6 @@ class McpAppHost {
|
|
|
14259
14275
|
}
|
|
14260
14276
|
await this.bridge.close();
|
|
14261
14277
|
this._initialized = false;
|
|
14262
|
-
this._contentWindow = null;
|
|
14263
14278
|
}
|
|
14264
14279
|
/**
|
|
14265
14280
|
* Debug: Inject state directly into the app's useAppState hook.
|
|
@@ -14316,7 +14331,21 @@ function isAllowedUrl(src) {
|
|
|
14316
14331
|
return false;
|
|
14317
14332
|
}
|
|
14318
14333
|
}
|
|
14334
|
+
function extractResourceCSP(resource) {
|
|
14335
|
+
const meta = resource._meta;
|
|
14336
|
+
const ui2 = meta?.ui;
|
|
14337
|
+
return ui2?.csp;
|
|
14338
|
+
}
|
|
14319
14339
|
const SDK_RESOURCE_DOMAINS = ["https://cdn.openai.com"];
|
|
14340
|
+
function isValidCspSource(source) {
|
|
14341
|
+
if (!source || /[\s;,']/.test(source) || source === "*") return false;
|
|
14342
|
+
try {
|
|
14343
|
+
const url = new URL(source);
|
|
14344
|
+
return url.protocol === "http:" || url.protocol === "https:" || url.protocol === "ws:" || url.protocol === "wss:";
|
|
14345
|
+
} catch {
|
|
14346
|
+
return false;
|
|
14347
|
+
}
|
|
14348
|
+
}
|
|
14320
14349
|
function generateCSP(csp, scriptSrc) {
|
|
14321
14350
|
let scriptOrigin = "";
|
|
14322
14351
|
try {
|
|
@@ -14334,14 +14363,26 @@ function generateCSP(csp, scriptSrc) {
|
|
|
14334
14363
|
const connectSources = /* @__PURE__ */ new Set(["'self'"]);
|
|
14335
14364
|
if (scriptOrigin) connectSources.add(scriptOrigin);
|
|
14336
14365
|
if (csp?.connectDomains) {
|
|
14337
|
-
for (const domain of csp.connectDomains)
|
|
14366
|
+
for (const domain of csp.connectDomains) {
|
|
14367
|
+
if (isValidCspSource(domain)) {
|
|
14368
|
+
connectSources.add(domain);
|
|
14369
|
+
} else {
|
|
14370
|
+
console.warn("[IframeResource] Ignoring invalid CSP connect domain:", domain);
|
|
14371
|
+
}
|
|
14372
|
+
}
|
|
14338
14373
|
}
|
|
14339
14374
|
directives.push(`connect-src ${Array.from(connectSources).join(" ")}`);
|
|
14340
14375
|
const resourceSources = /* @__PURE__ */ new Set(["'self'", "data:", "blob:"]);
|
|
14341
14376
|
if (scriptOrigin) resourceSources.add(scriptOrigin);
|
|
14342
14377
|
for (const domain of SDK_RESOURCE_DOMAINS) resourceSources.add(domain);
|
|
14343
14378
|
if (csp?.resourceDomains) {
|
|
14344
|
-
for (const domain of csp.resourceDomains)
|
|
14379
|
+
for (const domain of csp.resourceDomains) {
|
|
14380
|
+
if (isValidCspSource(domain)) {
|
|
14381
|
+
resourceSources.add(domain);
|
|
14382
|
+
} else {
|
|
14383
|
+
console.warn("[IframeResource] Ignoring invalid CSP resource domain:", domain);
|
|
14384
|
+
}
|
|
14385
|
+
}
|
|
14345
14386
|
}
|
|
14346
14387
|
const resourceList = Array.from(resourceSources).join(" ");
|
|
14347
14388
|
directives.push(`img-src ${resourceList}`);
|
|
@@ -14349,11 +14390,29 @@ function generateCSP(csp, scriptSrc) {
|
|
|
14349
14390
|
directives.push(`media-src ${resourceList}`);
|
|
14350
14391
|
return directives.join("; ");
|
|
14351
14392
|
}
|
|
14393
|
+
const PAINT_FENCE_SCRIPT = `window.addEventListener("message",function(e){
|
|
14394
|
+
if(e.data&&e.data.method==="sunpeak/fence"){
|
|
14395
|
+
var fid=e.data.params&&e.data.params.fenceId;
|
|
14396
|
+
requestAnimationFrame(function(){
|
|
14397
|
+
e.source.postMessage({jsonrpc:"2.0",method:"sunpeak/fence-ack",params:{fenceId:fid}},"*");
|
|
14398
|
+
});}});`;
|
|
14399
|
+
function injectPaintFence(iframe) {
|
|
14400
|
+
try {
|
|
14401
|
+
const doc = iframe.contentDocument;
|
|
14402
|
+
if (!doc || doc.querySelector("script[data-sunpeak-fence]")) return;
|
|
14403
|
+
const script = doc.createElement("script");
|
|
14404
|
+
script.setAttribute("data-sunpeak-fence", "");
|
|
14405
|
+
script.textContent = PAINT_FENCE_SCRIPT;
|
|
14406
|
+
doc.head.appendChild(script);
|
|
14407
|
+
} catch {
|
|
14408
|
+
}
|
|
14409
|
+
}
|
|
14352
14410
|
function generateScriptHtml(scriptSrc, theme, cspPolicy) {
|
|
14353
14411
|
const safeScriptSrc = escapeHtml(scriptSrc);
|
|
14354
14412
|
const safeCsp = escapeHtml(cspPolicy);
|
|
14413
|
+
const safeTheme = escapeHtml(theme);
|
|
14355
14414
|
return `<!DOCTYPE html>
|
|
14356
|
-
<html lang="en" data-theme="${
|
|
14415
|
+
<html lang="en" data-theme="${safeTheme}">
|
|
14357
14416
|
<head>
|
|
14358
14417
|
<meta charset="UTF-8" />
|
|
14359
14418
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
@@ -14372,19 +14431,7 @@ function generateScriptHtml(scriptSrc, theme, cspPolicy) {
|
|
|
14372
14431
|
color-scheme: dark light;
|
|
14373
14432
|
}
|
|
14374
14433
|
</style>
|
|
14375
|
-
<script>
|
|
14376
|
-
// Paint fence responder — allows the host to wait for this iframe to
|
|
14377
|
-
// process pending messages and commit DOM updates before revealing content.
|
|
14378
|
-
// Formatted as JSON-RPC 2.0 notifications to avoid PostMessageTransport parse errors.
|
|
14379
|
-
window.addEventListener("message",function(e){
|
|
14380
|
-
if(e.data&&e.data.method==="sunpeak/fence"){
|
|
14381
|
-
var fid=e.data.params&&e.data.params.fenceId;
|
|
14382
|
-
requestAnimationFrame(function(){
|
|
14383
|
-
e.source.postMessage({jsonrpc:"2.0",method:"sunpeak/fence-ack",params:{fenceId:fid}},"*");
|
|
14384
|
-
});
|
|
14385
|
-
}
|
|
14386
|
-
});
|
|
14387
|
-
<\/script>
|
|
14434
|
+
<script>${PAINT_FENCE_SCRIPT}<\/script>
|
|
14388
14435
|
</head>
|
|
14389
14436
|
<body>
|
|
14390
14437
|
<div id="root"></div>
|
|
@@ -14402,14 +14449,13 @@ function IframeResource({
|
|
|
14402
14449
|
csp,
|
|
14403
14450
|
className,
|
|
14404
14451
|
style,
|
|
14405
|
-
onDisplayModeReady,
|
|
14406
14452
|
debugInjectState
|
|
14407
14453
|
}) {
|
|
14408
14454
|
const iframeRef = React.useRef(null);
|
|
14409
14455
|
const hostRef = React.useRef(null);
|
|
14410
|
-
const
|
|
14411
|
-
|
|
14412
|
-
|
|
14456
|
+
const [readyDisplayMode, setReadyDisplayMode] = React.useState(
|
|
14457
|
+
hostContext?.displayMode
|
|
14458
|
+
);
|
|
14413
14459
|
const resourceUrl = src ?? scriptSrc;
|
|
14414
14460
|
const hasReceivedSizeRef = React.useRef(false);
|
|
14415
14461
|
const host = React.useMemo(
|
|
@@ -14422,7 +14468,8 @@ function IframeResource({
|
|
|
14422
14468
|
hasReceivedSizeRef.current = true;
|
|
14423
14469
|
iframeRef.current.style.height = `${params.height}px`;
|
|
14424
14470
|
}
|
|
14425
|
-
}
|
|
14471
|
+
},
|
|
14472
|
+
onDisplayModeReady: (mode) => setReadyDisplayMode(mode)
|
|
14426
14473
|
}),
|
|
14427
14474
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
14428
14475
|
[]
|
|
@@ -14439,22 +14486,13 @@ function IframeResource({
|
|
|
14439
14486
|
[host]
|
|
14440
14487
|
);
|
|
14441
14488
|
const handleLoad = React.useCallback(() => {
|
|
14442
|
-
if (
|
|
14443
|
-
|
|
14444
|
-
|
|
14489
|
+
if (src && iframeRef.current) {
|
|
14490
|
+
injectPaintFence(iframeRef.current);
|
|
14491
|
+
}
|
|
14492
|
+
}, [src]);
|
|
14445
14493
|
React.useEffect(() => {
|
|
14446
14494
|
if (hostContext) {
|
|
14447
14495
|
host.setHostContext(hostContext);
|
|
14448
|
-
const currentMode = hostContext.displayMode;
|
|
14449
|
-
if (currentMode !== prevDisplayModeRef.current) {
|
|
14450
|
-
prevDisplayModeRef.current = currentMode;
|
|
14451
|
-
if (currentMode) {
|
|
14452
|
-
const mode = currentMode;
|
|
14453
|
-
host.waitForPaint().then(() => {
|
|
14454
|
-
onDisplayModeReadyRef.current?.(mode);
|
|
14455
|
-
});
|
|
14456
|
-
}
|
|
14457
|
-
}
|
|
14458
14496
|
}
|
|
14459
14497
|
}, [host, hostContext]);
|
|
14460
14498
|
React.useEffect(() => {
|
|
@@ -14490,6 +14528,7 @@ function IframeResource({
|
|
|
14490
14528
|
const theme = hostContext?.theme ?? "dark";
|
|
14491
14529
|
return generateScriptHtml(absoluteScriptSrc, theme, cspPolicy);
|
|
14492
14530
|
}, [scriptSrc, isValidUrl, csp, hostContext?.theme]);
|
|
14531
|
+
const isTransitioning = hostContext?.displayMode !== readyDisplayMode;
|
|
14493
14532
|
if (src) {
|
|
14494
14533
|
if (!isValidUrl) {
|
|
14495
14534
|
console.error("[IframeResource] URL not allowed:", src);
|
|
@@ -14513,6 +14552,10 @@ function IframeResource({
|
|
|
14513
14552
|
// Start with minHeight to prevent collapse, but allow auto-resize to set actual height.
|
|
14514
14553
|
// Don't use height: 100% as it requires explicit height in parent chain.
|
|
14515
14554
|
minHeight: "200px",
|
|
14555
|
+
// Hide during display mode transitions; reveal with a short fade once
|
|
14556
|
+
// the iframe has committed its DOM for the new mode.
|
|
14557
|
+
opacity: isTransitioning ? 0 : 1,
|
|
14558
|
+
transition: isTransitioning ? "none" : "opacity 100ms",
|
|
14516
14559
|
...style
|
|
14517
14560
|
},
|
|
14518
14561
|
title: "Resource Preview",
|
|
@@ -14536,6 +14579,8 @@ function IframeResource({
|
|
|
14536
14579
|
// Start with minHeight to prevent collapse, but allow auto-resize to set actual height.
|
|
14537
14580
|
// Don't use height: 100% as it requires explicit height in parent chain.
|
|
14538
14581
|
minHeight: "200px",
|
|
14582
|
+
opacity: isTransitioning ? 0 : 1,
|
|
14583
|
+
transition: isTransitioning ? "none" : "opacity 100ms",
|
|
14539
14584
|
...style
|
|
14540
14585
|
},
|
|
14541
14586
|
title: "Resource Preview",
|
|
@@ -14661,12 +14706,6 @@ function ChatGPTSimulator({
|
|
|
14661
14706
|
_setDisplayMode(mode);
|
|
14662
14707
|
}
|
|
14663
14708
|
};
|
|
14664
|
-
const [readyDisplayMode, setReadyDisplayMode] = React.useState(
|
|
14665
|
-
urlParams.displayMode ?? DEFAULT_DISPLAY_MODE
|
|
14666
|
-
);
|
|
14667
|
-
const handleDisplayModeReady = React.useCallback((mode) => {
|
|
14668
|
-
setReadyDisplayMode(mode);
|
|
14669
|
-
}, []);
|
|
14670
14709
|
const hostContext = React.useMemo(
|
|
14671
14710
|
() => ({
|
|
14672
14711
|
theme,
|
|
@@ -14757,11 +14796,7 @@ function ChatGPTSimulator({
|
|
|
14757
14796
|
}, [toolResult, modelContext]);
|
|
14758
14797
|
const resourceUrl = selectedSim?.resourceUrl;
|
|
14759
14798
|
const resourceScript = selectedSim?.resourceScript;
|
|
14760
|
-
const
|
|
14761
|
-
const resourceUi = resourceMeta?.ui;
|
|
14762
|
-
const csp = resourceUi?.csp;
|
|
14763
|
-
const hasIframeContent = !!(resourceUrl || resourceScript);
|
|
14764
|
-
const isTransitioning = hasIframeContent && displayMode !== readyDisplayMode;
|
|
14799
|
+
const csp = selectedSim ? extractResourceCSP(selectedSim.resource) : void 0;
|
|
14765
14800
|
let content;
|
|
14766
14801
|
if (resourceUrl) {
|
|
14767
14802
|
content = /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -14775,7 +14810,6 @@ function ChatGPTSimulator({
|
|
|
14775
14810
|
onDisplayModeChange: handleDisplayModeChange,
|
|
14776
14811
|
onUpdateModelContext: handleUpdateModelContext
|
|
14777
14812
|
},
|
|
14778
|
-
onDisplayModeReady: handleDisplayModeReady,
|
|
14779
14813
|
debugInjectState: modelContext,
|
|
14780
14814
|
className: "h-full w-full"
|
|
14781
14815
|
}
|
|
@@ -14793,7 +14827,6 @@ function ChatGPTSimulator({
|
|
|
14793
14827
|
onDisplayModeChange: handleDisplayModeChange,
|
|
14794
14828
|
onUpdateModelContext: handleUpdateModelContext
|
|
14795
14829
|
},
|
|
14796
|
-
onDisplayModeReady: handleDisplayModeReady,
|
|
14797
14830
|
debugInjectState: modelContext,
|
|
14798
14831
|
className: "h-full w-full"
|
|
14799
14832
|
}
|
|
@@ -15019,7 +15052,6 @@ function ChatGPTSimulator({
|
|
|
15019
15052
|
appName,
|
|
15020
15053
|
appIcon,
|
|
15021
15054
|
userMessage: selectedSim?.userMessage,
|
|
15022
|
-
isTransitioning,
|
|
15023
15055
|
children: content
|
|
15024
15056
|
},
|
|
15025
15057
|
selectedSimulationName
|
|
@@ -15080,6 +15112,7 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
15080
15112
|
buildSimulations: discovery.buildSimulations,
|
|
15081
15113
|
createResourceExports: discovery.createResourceExports,
|
|
15082
15114
|
createSimulatorUrl,
|
|
15115
|
+
extractResourceCSP,
|
|
15083
15116
|
extractResourceKey: discovery.extractResourceKey,
|
|
15084
15117
|
extractSimulationKey: discovery.extractSimulationKey,
|
|
15085
15118
|
extractSimulationName: discovery.extractSimulationName,
|
|
@@ -15098,6 +15131,7 @@ exports.SCREEN_WIDTHS = SCREEN_WIDTHS;
|
|
|
15098
15131
|
exports.ThemeProvider = ThemeProvider;
|
|
15099
15132
|
exports.clsx = clsx;
|
|
15100
15133
|
exports.createSimulatorUrl = createSimulatorUrl;
|
|
15134
|
+
exports.extractResourceCSP = extractResourceCSP;
|
|
15101
15135
|
exports.index = index;
|
|
15102
15136
|
exports.useThemeContext = useThemeContext;
|
|
15103
|
-
//# sourceMappingURL=index-
|
|
15137
|
+
//# sourceMappingURL=index-B9MMk69u.cjs.map
|