sunpeak 0.18.9 → 0.18.13

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 (68) hide show
  1. package/README.md +12 -0
  2. package/bin/commands/inspect.mjs +4 -1
  3. package/bin/commands/start.mjs +2 -1
  4. package/bin/lib/sandbox-server.mjs +12 -1
  5. package/dist/chatgpt/index.cjs +1 -1
  6. package/dist/chatgpt/index.js +1 -1
  7. package/dist/claude/index.cjs +1 -1
  8. package/dist/claude/index.js +1 -1
  9. package/dist/host/chatgpt/index.cjs +1 -1
  10. package/dist/host/chatgpt/index.js +1 -1
  11. package/dist/index.cjs +93 -93
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.js +54 -54
  14. package/dist/index.js.map +1 -1
  15. package/dist/inspector/hosts.d.ts +12 -0
  16. package/dist/inspector/index.cjs +1 -1
  17. package/dist/inspector/index.js +1 -1
  18. package/dist/{inspector-CTMccsz9.cjs → inspector-8nPV2A-z.cjs} +93 -51
  19. package/dist/inspector-8nPV2A-z.cjs.map +1 -0
  20. package/dist/{inspector-DkS75JCk.js → inspector-Cdo5BK2D.js} +92 -50
  21. package/dist/inspector-Cdo5BK2D.js.map +1 -0
  22. package/dist/mcp/index.cjs +69 -62
  23. package/dist/mcp/index.cjs.map +1 -1
  24. package/dist/mcp/index.js +63 -56
  25. package/dist/mcp/index.js.map +1 -1
  26. package/dist/mcp/production-server.d.ts +12 -0
  27. package/dist/{protocol-DJmRaBzO.js → protocol-BfAACnv0.js} +14 -9
  28. package/dist/{protocol-DJmRaBzO.js.map → protocol-BfAACnv0.js.map} +1 -1
  29. package/dist/{protocol-jbxhzcnS.cjs → protocol-C7kTcBr_.cjs} +14 -9
  30. package/dist/{protocol-jbxhzcnS.cjs.map → protocol-C7kTcBr_.cjs.map} +1 -1
  31. package/dist/style.css +36 -1
  32. package/dist/{use-app-BNbz1uzj.js → use-app-CfP9VypY.js} +107 -56
  33. package/dist/use-app-CfP9VypY.js.map +1 -0
  34. package/dist/{use-app-Dqh20JPP.cjs → use-app-CzcYw1Kz.cjs} +165 -114
  35. package/dist/use-app-CzcYw1Kz.cjs.map +1 -0
  36. package/package.json +3 -3
  37. package/template/README.md +12 -0
  38. package/template/dist/albums/albums.html +16 -15
  39. package/template/dist/albums/albums.json +1 -1
  40. package/template/dist/carousel/carousel.html +20 -19
  41. package/template/dist/carousel/carousel.json +1 -1
  42. package/template/dist/map/map.html +7 -6
  43. package/template/dist/map/map.json +1 -1
  44. package/template/dist/review/review.html +6 -5
  45. package/template/dist/review/review.json +1 -1
  46. package/template/node_modules/.vite/deps/_metadata.json +3 -3
  47. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js +49 -49
  48. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js.map +1 -1
  49. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js +49 -49
  50. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js.map +1 -1
  51. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js +89 -89
  52. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js.map +1 -1
  53. package/template/node_modules/.vite-mcp/deps/_metadata.json +24 -24
  54. package/template/node_modules/.vite-mcp/deps/{protocol-CTflwIfG.js → protocol-B_qKkui_.js} +14 -9
  55. package/template/node_modules/.vite-mcp/deps/protocol-B_qKkui_.js.map +1 -0
  56. package/template/src/resources/carousel/carousel.test.tsx +16 -2
  57. package/template/src/resources/carousel/carousel.tsx +42 -14
  58. package/template/src/resources/carousel/components/carousel.tsx +20 -0
  59. package/template/src/resources/carousel/components/index.ts +1 -0
  60. package/template/src/resources/carousel/components/place-detail.tsx +153 -0
  61. package/template/tests/e2e/carousel.spec.ts +125 -0
  62. package/template/tests/live/carousel.spec.ts +2 -2
  63. package/template/tests/simulations/show-carousel.json +54 -5
  64. package/dist/inspector-CTMccsz9.cjs.map +0 -1
  65. package/dist/inspector-DkS75JCk.js.map +0 -1
  66. package/dist/use-app-BNbz1uzj.js.map +0 -1
  67. package/dist/use-app-Dqh20JPP.cjs.map +0 -1
  68. package/template/node_modules/.vite-mcp/deps/protocol-CTflwIfG.js.map +0 -1
@@ -80,6 +80,18 @@ export interface HostShell {
80
80
  * Defaults to ['inline', 'pip', 'fullscreen'] if not specified.
81
81
  */
82
82
  availableDisplayModes?: McpUiDisplayMode[];
83
+ /**
84
+ * Safe area insets per display mode.
85
+ * When the user switches display modes in the inspector, the safe area
86
+ * is automatically updated to match (unless the user has manually overridden it).
87
+ * Extracted from real hosts via the host-sync tool.
88
+ */
89
+ safeAreaByDisplayMode?: Partial<Record<McpUiDisplayMode, {
90
+ top?: number;
91
+ bottom?: number;
92
+ left?: number;
93
+ right?: number;
94
+ }>>;
83
95
  /**
84
96
  * CSS containing @font-face rules for the host's custom fonts.
85
97
  * Injected into the inspector page when this host is active so the
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../chunk-9hOWP6kD.cjs");
3
- const require_inspector = require("../inspector-CTMccsz9.cjs");
3
+ const require_inspector = require("../inspector-8nPV2A-z.cjs");
4
4
  const require_inspector_url = require("../inspector-url-C3LTKgXt.cjs");
5
5
  const require_discovery = require("../discovery-Clu4uHp1.cjs");
6
6
  //#region src/inspector/index.ts
@@ -1,5 +1,5 @@
1
1
  import { r as __exportAll } from "../chunk-D6g4UhsZ.js";
2
- import { _ as McpAppHost, a as SidebarControl, b as getRegisteredHosts, c as SidebarTextarea, d as ThemeProvider, f as useThemeContext, g as extractResourceCSP, h as IframeResource, i as SidebarCollapsibleControl, l as SidebarToggle, m as useInspectorState, n as resolveServerToolResult, o as SidebarInput, p as useMcpConnection, r as SidebarCheckbox, s as SidebarSelect, t as Inspector, u as SimpleSidebar, v as SCREEN_WIDTHS, x as registerHostShell, y as getHostShell } from "../inspector-DkS75JCk.js";
2
+ import { _ as McpAppHost, a as SidebarControl, b as getRegisteredHosts, c as SidebarTextarea, d as ThemeProvider, f as useThemeContext, g as extractResourceCSP, h as IframeResource, i as SidebarCollapsibleControl, l as SidebarToggle, m as useInspectorState, n as resolveServerToolResult, o as SidebarInput, p as useMcpConnection, r as SidebarCheckbox, s as SidebarSelect, t as Inspector, u as SimpleSidebar, v as SCREEN_WIDTHS, x as registerHostShell, y as getHostShell } from "../inspector-Cdo5BK2D.js";
3
3
  import { t as createInspectorUrl } from "../inspector-url-CyQcuBI9.js";
4
4
  import { c as toPascalCase, i as findResourceKey, n as extractSimulationKey, r as findResourceDirs, s as getComponentName, t as extractResourceKey } from "../discovery-Cgoegt62.js";
5
5
  //#region src/inspector/index.ts
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-9hOWP6kD.cjs");
2
- const require_protocol = require("./protocol-jbxhzcnS.cjs");
2
+ const require_protocol = require("./protocol-C7kTcBr_.cjs");
3
3
  let react = require("react");
4
4
  react = require_chunk.__toESM(react);
5
5
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -378,7 +378,7 @@ function Conversation({ children, screenWidth, displayMode, platform, onRequestD
378
378
  //#region src/chatgpt/chatgpt-host.ts
379
379
  /**
380
380
  * ChatGPT host version info — matches what ChatGPT reports via the MCP protocol.
381
- * Verified against production ChatGPT on 2026-03-19.
381
+ * Verified against production ChatGPT on 2026-03-30.
382
382
  */
383
383
  var CHATGPT_HOST_INFO = {
384
384
  name: "chatgpt",
@@ -410,6 +410,11 @@ registerHostShell({
410
410
  hostCapabilities: CHATGPT_HOST_CAPABILITIES,
411
411
  userAgent: "chatgpt",
412
412
  styleVariables: { ...DEFAULT_STYLE_VARIABLES },
413
+ safeAreaByDisplayMode: {
414
+ inline: {},
415
+ fullscreen: { bottom: 150 },
416
+ pip: {}
417
+ },
413
418
  pageStyles: {
414
419
  "--sim-bg-sidebar": "light-dark(#ffffff, #212121)",
415
420
  "--sim-bg-conversation": "light-dark(#ffffff, #212121)",
@@ -665,7 +670,7 @@ function ClaudeConversation({ children, screenWidth, displayMode, platform, onRe
665
670
  //#region src/claude/claude-host.ts
666
671
  /**
667
672
  * Claude host version info — matches what Claude reports via the MCP protocol.
668
- * Verified against production Claude on 2026-03-25.
673
+ * Verified against production Claude on 2026-03-30.
669
674
  */
670
675
  var CLAUDE_HOST_INFO = {
671
676
  name: "Claude",
@@ -673,7 +678,7 @@ var CLAUDE_HOST_INFO = {
673
678
  };
674
679
  /**
675
680
  * Claude host capabilities — matches what Claude reports via the MCP protocol.
676
- * Verified against production Claude on 2026-03-25.
681
+ * Verified against production Claude on 2026-03-30.
677
682
  *
678
683
  * Notable: Claude supports downloadFile, updateModelContext.image, and
679
684
  * message.text. serverTools and serverResources both report listChanged.
@@ -776,6 +781,15 @@ registerHostShell({
776
781
  "--sim-bg-user-bubble": "light-dark(rgb(240, 238, 230), rgb(20, 20, 19))",
777
782
  "--sim-bg-reply-input": "light-dark(rgb(255, 255, 255), rgb(48, 48, 46))"
778
783
  },
784
+ safeAreaByDisplayMode: {
785
+ inline: {},
786
+ fullscreen: {
787
+ top: 16,
788
+ right: 16,
789
+ bottom: 138,
790
+ left: 16
791
+ }
792
+ },
779
793
  availableDisplayModes: ["inline", "fullscreen"],
780
794
  fontCss: `@font-face {
781
795
  font-family: "Anthropic Sans";
@@ -795,12 +809,12 @@ registerHostShell({
795
809
  }`
796
810
  });
797
811
  //#endregion
798
- //#region ../../node_modules/.pnpm/@modelcontextprotocol+ext-apps@1.3.1_@modelcontextprotocol+sdk@1.27.1_zod@4.3.6__react-_cd1fb28fd87e0bddd0a29eba0721855d/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js
799
- var G = "2026-01-26", p = require_protocol.union([require_protocol.literal("light"), require_protocol.literal("dark")]).describe("Color theme preference for the host environment."), D = require_protocol.union([
812
+ //#region ../../node_modules/.pnpm/@modelcontextprotocol+ext-apps@1.3.2_@modelcontextprotocol+sdk@1.29.0_zod@4.3.6__react-_38e5f6c50a4ca9cf3f1dffc73a60c951/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js
813
+ var G = "2026-01-26", m = require_protocol.union([require_protocol.literal("light"), require_protocol.literal("dark")]).describe("Color theme preference for the host environment."), W = require_protocol.union([
800
814
  require_protocol.literal("inline"),
801
815
  require_protocol.literal("fullscreen"),
802
816
  require_protocol.literal("pip")
803
- ]).describe("Display mode for UI presentation."), IQ = require_protocol.union([
817
+ ]).describe("Display mode for UI presentation."), _Q = require_protocol.union([
804
818
  require_protocol.literal("--color-background-primary"),
805
819
  require_protocol.literal("--color-background-secondary"),
806
820
  require_protocol.literal("--color-background-tertiary"),
@@ -877,7 +891,7 @@ var G = "2026-01-26", p = require_protocol.union([require_protocol.literal("ligh
877
891
  require_protocol.literal("--shadow-sm"),
878
892
  require_protocol.literal("--shadow-md"),
879
893
  require_protocol.literal("--shadow-lg")
880
- ]).describe("CSS variable keys available to MCP apps for theming."), AQ = require_protocol.record(IQ.describe(`Style variables for theming MCP apps.
894
+ ]).describe("CSS variable keys available to MCP apps for theming."), OQ = require_protocol.record(_Q.describe(`Style variables for theming MCP apps.
881
895
 
882
896
  Individual style keys are optional - hosts may provide any subset of these values.
883
897
  Values are strings containing CSS values (colors, sizes, font stacks, etc.).
@@ -905,7 +919,7 @@ require_protocol.object({ isError: require_protocol.boolean().optional().describ
905
919
  var L = require_protocol.object({
906
920
  method: require_protocol.literal("ui/notifications/sandbox-proxy-ready"),
907
921
  params: require_protocol.object({})
908
- }), j = require_protocol.object({
922
+ }), N = require_protocol.object({
909
923
  connectDomains: require_protocol.array(require_protocol.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
910
924
 
911
925
  - Maps to CSP \`connect-src\` directive
@@ -913,7 +927,7 @@ var L = require_protocol.object({
913
927
  resourceDomains: require_protocol.array(require_protocol.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),
914
928
  frameDomains: require_protocol.array(require_protocol.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),
915
929
  baseUriDomains: require_protocol.array(require_protocol.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")
916
- }), E = require_protocol.object({
930
+ }), j = require_protocol.object({
917
931
  camera: require_protocol.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),
918
932
  microphone: require_protocol.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),
919
933
  geolocation: require_protocol.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),
@@ -937,9 +951,9 @@ require_protocol.object({
937
951
  method: require_protocol.literal("ui/notifications/tool-cancelled"),
938
952
  params: require_protocol.object({ reason: require_protocol.string().optional().describe("Optional reason for the cancellation (e.g., \"user action\", \"timeout\").") })
939
953
  });
940
- var c = require_protocol.object({ fonts: require_protocol.string().optional() }), n = require_protocol.object({
941
- variables: AQ.optional().describe("CSS variables for theming the app."),
942
- css: c.optional().describe("CSS blocks that apps can inject.")
954
+ var p = require_protocol.object({ fonts: require_protocol.string().optional() }), c = require_protocol.object({
955
+ variables: OQ.optional().describe("CSS variables for theming the app."),
956
+ css: p.optional().describe("CSS blocks that apps can inject.")
943
957
  });
944
958
  require_protocol.object({
945
959
  method: require_protocol.literal("ui/resource-teardown"),
@@ -955,7 +969,7 @@ var H = require_protocol.record(require_protocol.string(), require_protocol.unkn
955
969
  }), M = require_protocol.object({
956
970
  method: require_protocol.literal("ui/notifications/request-teardown"),
957
971
  params: require_protocol.object({}).optional()
958
- }), i = require_protocol.object({
972
+ }), n = require_protocol.object({
959
973
  experimental: require_protocol.object({}).optional().describe("Experimental features (structure TBD)."),
960
974
  openLinks: require_protocol.object({}).optional().describe("Host supports opening external URLs."),
961
975
  downloadFile: require_protocol.object({}).optional().describe("Host supports file downloads via ui/download-file."),
@@ -963,22 +977,22 @@ var H = require_protocol.record(require_protocol.string(), require_protocol.unkn
963
977
  serverResources: require_protocol.object({ listChanged: require_protocol.boolean().optional().describe("Host supports resources/list_changed notifications.") }).optional().describe("Host can proxy resource reads to the MCP server."),
964
978
  logging: require_protocol.object({}).optional().describe("Host accepts log messages."),
965
979
  sandbox: require_protocol.object({
966
- permissions: E.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),
967
- csp: j.optional().describe("CSP domains approved by the host.")
980
+ permissions: j.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),
981
+ csp: N.optional().describe("CSP domains approved by the host.")
968
982
  }).optional().describe("Sandbox configuration applied by the host."),
969
983
  updateModelContext: O.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),
970
984
  message: O.optional().describe("Host supports receiving content messages (ui/message) from the view.")
971
- }), l = require_protocol.object({
985
+ }), i = require_protocol.object({
972
986
  experimental: require_protocol.object({}).optional().describe("Experimental features (structure TBD)."),
973
987
  tools: require_protocol.object({ listChanged: require_protocol.boolean().optional().describe("App supports tools/list_changed notifications.") }).optional().describe("App exposes MCP-style tools that the host can call."),
974
- availableDisplayModes: require_protocol.array(D).optional().describe("Display modes the app supports.")
988
+ availableDisplayModes: require_protocol.array(W).optional().describe("Display modes the app supports.")
975
989
  }), v = require_protocol.object({
976
990
  method: require_protocol.literal("ui/notifications/initialized"),
977
991
  params: require_protocol.object({}).optional()
978
992
  });
979
993
  require_protocol.object({
980
- csp: j.optional().describe("Content Security Policy configuration for UI resources."),
981
- permissions: E.optional().describe("Sandbox permissions requested by the UI resource."),
994
+ csp: N.optional().describe("Content Security Policy configuration for UI resources."),
995
+ permissions: j.optional().describe("Sandbox permissions requested by the UI resource."),
982
996
  domain: require_protocol.string().optional().describe(`Dedicated origin for view sandbox.
983
997
 
984
998
  Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.
@@ -996,15 +1010,15 @@ Boolean requesting whether a visible border and background is provided by the ho
996
1010
  - \`false\`: request no visible border + background
997
1011
  - omitted: host decides border`)
998
1012
  });
999
- var W = require_protocol.object({
1013
+ var E = require_protocol.object({
1000
1014
  method: require_protocol.literal("ui/request-display-mode"),
1001
- params: require_protocol.object({ mode: D.describe("The display mode being requested.") })
1015
+ params: require_protocol.object({ mode: W.describe("The display mode being requested.") })
1002
1016
  });
1003
- require_protocol.object({ mode: D.describe("The display mode that was actually set. May differ from requested if not supported.") }).passthrough();
1004
- var r = require_protocol.union([require_protocol.literal("model"), require_protocol.literal("app")]).describe("Tool visibility scope - who can access the tool.");
1017
+ require_protocol.object({ mode: W.describe("The display mode that was actually set. May differ from requested if not supported.") }).passthrough();
1018
+ var l = require_protocol.union([require_protocol.literal("model"), require_protocol.literal("app")]).describe("Tool visibility scope - who can access the tool.");
1005
1019
  require_protocol.object({
1006
1020
  resourceUri: require_protocol.string().optional(),
1007
- visibility: require_protocol.array(r).optional().describe(`Who can access this tool. Default: ["model", "app"]
1021
+ visibility: require_protocol.array(l).optional().describe(`Who can access this tool. Default: ["model", "app"]
1008
1022
  - "model": Tool visible to and callable by the agent
1009
1023
  - "app": Tool callable by the app from this server only`)
1010
1024
  });
@@ -1024,8 +1038,8 @@ require_protocol.object({
1024
1038
  params: require_protocol.object({
1025
1039
  html: require_protocol.string().describe("HTML content to load into the inner iframe."),
1026
1040
  sandbox: require_protocol.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),
1027
- csp: j.optional().describe("CSP configuration from resource metadata."),
1028
- permissions: E.optional().describe("Sandbox permissions from resource metadata.")
1041
+ csp: N.optional().describe("CSP configuration from resource metadata."),
1042
+ permissions: j.optional().describe("Sandbox permissions from resource metadata.")
1029
1043
  })
1030
1044
  });
1031
1045
  require_protocol.object({
@@ -1037,10 +1051,10 @@ var y = require_protocol.object({
1037
1051
  id: require_protocol.RequestIdSchema.optional().describe("JSON-RPC id of the tools/call request."),
1038
1052
  tool: require_protocol.ToolSchema.describe("Tool definition including name, inputSchema, etc.")
1039
1053
  }).optional().describe("Metadata of the tool call that instantiated this App."),
1040
- theme: p.optional().describe("Current color theme preference."),
1041
- styles: n.optional().describe("Style configuration for theming the app."),
1042
- displayMode: D.optional().describe("How the UI is currently displayed."),
1043
- availableDisplayModes: require_protocol.array(D).optional().describe("Display modes the host supports."),
1054
+ theme: m.optional().describe("Current color theme preference."),
1055
+ styles: c.optional().describe("Style configuration for theming the app."),
1056
+ displayMode: W.optional().describe("How the UI is currently displayed."),
1057
+ availableDisplayModes: require_protocol.array(W).optional().describe("Display modes the host supports."),
1044
1058
  containerDimensions: require_protocol.union([require_protocol.object({ height: require_protocol.number().describe("Fixed container height in pixels.") }), require_protocol.object({ maxHeight: require_protocol.union([require_protocol.number(), require_protocol._undefined()]).optional().describe("Maximum container height in pixels.") })]).and(require_protocol.union([require_protocol.object({ width: require_protocol.number().describe("Fixed container width in pixels.") }), require_protocol.object({ maxWidth: require_protocol.union([require_protocol.number(), require_protocol._undefined()]).optional().describe("Maximum container width in pixels.") })])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
1045
1059
  container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),
1046
1060
  locale: require_protocol.string().optional().describe("User's language and region preference in BCP 47 format."),
@@ -1076,17 +1090,17 @@ var f = require_protocol.object({
1076
1090
  method: require_protocol.literal("ui/initialize"),
1077
1091
  params: require_protocol.object({
1078
1092
  appInfo: require_protocol.ImplementationSchema.describe("App identification (name and version)."),
1079
- appCapabilities: l.describe("Features and capabilities this app provides."),
1093
+ appCapabilities: i.describe("Features and capabilities this app provides."),
1080
1094
  protocolVersion: require_protocol.string().describe("Protocol version this app supports.")
1081
1095
  })
1082
1096
  });
1083
1097
  require_protocol.object({
1084
1098
  protocolVersion: require_protocol.string().describe("Negotiated protocol version string (e.g., \"2025-11-21\")."),
1085
1099
  hostInfo: require_protocol.ImplementationSchema.describe("Host application identification and version."),
1086
- hostCapabilities: i.describe("Features and capabilities provided by the host."),
1100
+ hostCapabilities: n.describe("Features and capabilities provided by the host."),
1087
1101
  hostContext: y.describe("Rich context about the host environment.")
1088
1102
  }).passthrough();
1089
- var N = class {
1103
+ var D = class {
1090
1104
  eventTarget;
1091
1105
  eventSource;
1092
1106
  messageListener;
@@ -1120,8 +1134,8 @@ var N = class {
1120
1134
  sessionId;
1121
1135
  setProtocolVersion;
1122
1136
  };
1123
- var aQ = [G];
1124
- var tQ = class extends require_protocol.Protocol {
1137
+ var lQ = [G];
1138
+ var rQ = class extends require_protocol.Protocol {
1125
1139
  _client;
1126
1140
  _hostInfo;
1127
1141
  _capabilities;
@@ -1133,9 +1147,9 @@ var tQ = class extends require_protocol.Protocol {
1133
1147
  this._client = X;
1134
1148
  this._hostInfo = Y;
1135
1149
  this._capabilities = Z;
1136
- this._hostContext = $?.hostContext || {}, this.setRequestHandler(d, (K) => this._oninitialize(K)), this.setRequestHandler(require_protocol.PingRequestSchema, (K, J) => {
1137
- return this.onping?.(K.params, J), {};
1138
- }), this.setRequestHandler(W, (K) => {
1150
+ this._hostContext = $?.hostContext || {}, this.setRequestHandler(d, (J) => this._oninitialize(J)), this.setRequestHandler(require_protocol.PingRequestSchema, (J, K) => {
1151
+ return this.onping?.(J.params, K), {};
1152
+ }), this.setRequestHandler(E, (J) => {
1139
1153
  return { mode: this._hostContext.displayMode ?? "inline" };
1140
1154
  });
1141
1155
  }
@@ -1174,7 +1188,7 @@ var tQ = class extends require_protocol.Protocol {
1174
1188
  this.setNotificationHandler(M, (Y) => X(Y.params));
1175
1189
  }
1176
1190
  set onrequestdisplaymode(X) {
1177
- this.setRequestHandler(W, async (Y, Z) => {
1191
+ this.setRequestHandler(E, async (Y, Z) => {
1178
1192
  return X(Y.params, Z);
1179
1193
  });
1180
1194
  }
@@ -1246,7 +1260,7 @@ var tQ = class extends require_protocol.Protocol {
1246
1260
  async _oninitialize(X) {
1247
1261
  let Y = X.params.protocolVersion;
1248
1262
  return this._appCapabilities = X.params.appCapabilities, this._appInfo = X.params.appInfo, {
1249
- protocolVersion: aQ.includes(Y) ? Y : G,
1263
+ protocolVersion: lQ.includes(Y) ? Y : G,
1250
1264
  hostCapabilities: this.getCapabilities(),
1251
1265
  hostInfo: this._hostInfo,
1252
1266
  hostContext: this._hostContext
@@ -1255,9 +1269,9 @@ var tQ = class extends require_protocol.Protocol {
1255
1269
  setHostContext(X) {
1256
1270
  let Y = {}, Z = !1;
1257
1271
  for (let $ of Object.keys(X)) {
1258
- let K = this._hostContext[$], J = X[$];
1259
- if (sQ(K, J)) continue;
1260
- Y[$] = J, Z = !0;
1272
+ let J = this._hostContext[$], K = X[$];
1273
+ if (oQ(J, K)) continue;
1274
+ Y[$] = K, Z = !0;
1261
1275
  }
1262
1276
  if (Z) this._hostContext = X, this.sendHostContextChange(Y);
1263
1277
  }
@@ -1347,7 +1361,7 @@ var tQ = class extends require_protocol.Protocol {
1347
1361
  return super.connect(X);
1348
1362
  }
1349
1363
  };
1350
- function sQ(X, Y) {
1364
+ function oQ(X, Y) {
1351
1365
  return JSON.stringify(X) === JSON.stringify(Y);
1352
1366
  }
1353
1367
  //#endregion
@@ -1385,7 +1399,7 @@ var McpAppHost = class {
1385
1399
  constructor(options = {}) {
1386
1400
  this.options = options;
1387
1401
  this._prevDisplayMode = options.hostContext?.displayMode;
1388
- this.bridge = new tQ(null, options.hostInfo ?? DEFAULT_HOST_INFO, options.hostCapabilities ?? DEFAULT_HOST_CAPABILITIES, { hostContext: options.hostContext });
1402
+ this.bridge = new rQ(null, options.hostInfo ?? DEFAULT_HOST_INFO, options.hostCapabilities ?? DEFAULT_HOST_CAPABILITIES, { hostContext: options.hostContext });
1389
1403
  this.bridge.oninitialized = () => {
1390
1404
  this._initialized = true;
1391
1405
  if (this._pendingToolInput) {
@@ -1462,7 +1476,10 @@ var McpAppHost = class {
1462
1476
  if (this.options.onRequestTeardown) this.options.onRequestTeardown();
1463
1477
  else console.log("[MCP App] requestTeardown (app requested close)");
1464
1478
  };
1479
+ let sandboxReadyFired = false;
1465
1480
  this.bridge.onsandboxready = () => {
1481
+ if (sandboxReadyFired) return;
1482
+ sandboxReadyFired = true;
1466
1483
  this.options.onSandboxReady?.();
1467
1484
  };
1468
1485
  }
@@ -1482,7 +1499,7 @@ var McpAppHost = class {
1482
1499
  console.log(`%c[MCP ↑]%c app → host: %c${label}`, "color:#6ee7b7", "color:inherit", "color:#93c5fd", data);
1483
1500
  };
1484
1501
  window.addEventListener("message", this._messageListener);
1485
- const transport = new N(contentWindow, contentWindow);
1502
+ const transport = new D(contentWindow, contentWindow);
1486
1503
  await this.bridge.connect(transport);
1487
1504
  }
1488
1505
  /**
@@ -1801,6 +1818,7 @@ iframe { border: none; width: 100%; height: 100%; display: block; }
1801
1818
  });
1802
1819
 
1803
1820
  function createInnerFrame(params) {
1821
+ clearInterval(readyInterval);
1804
1822
  if (innerFrame) innerFrame.remove();
1805
1823
 
1806
1824
  innerFrame = document.createElement('iframe');
@@ -1820,6 +1838,7 @@ iframe { border: none; width: 100%; height: 100%; display: block; }
1820
1838
  }
1821
1839
 
1822
1840
  function createInnerFrameWithSrc(params) {
1841
+ clearInterval(readyInterval);
1823
1842
  if (innerFrame) innerFrame.remove();
1824
1843
 
1825
1844
  innerFrame = document.createElement('iframe');
@@ -1897,9 +1916,20 @@ iframe { border: none; width: 100%; height: 100%; display: block; }
1897
1916
  '});}});';
1898
1917
 
1899
1918
  // Signal to the host that the proxy is ready.
1900
- // Use setTimeout to ensure the host's PostMessageTransport listener
1901
- // is set up before we send the ready notification. The srcdoc is parsed
1902
- // synchronously by the browser, which can race with React's ref callback.
1919
+ // The srcdoc is parsed synchronously by the browser, which can race with
1920
+ // React's ref callback that sets up the PostMessage listener. To handle
1921
+ // this, we send the ready notification repeatedly until the host
1922
+ // acknowledges it (by sending content to load). The interval is cleared
1923
+ // as soon as we receive any message from the host (createInnerFrame or
1924
+ // createInnerFrameWithSrc), or after 10 seconds as a safety limit.
1925
+ var readyInterval = setInterval(function() {
1926
+ window.parent.postMessage({
1927
+ jsonrpc: '2.0',
1928
+ method: 'ui/notifications/sandbox-proxy-ready',
1929
+ params: {}
1930
+ }, '*');
1931
+ }, 200);
1932
+ // Send the first one immediately (next tick)
1903
1933
  setTimeout(function() {
1904
1934
  window.parent.postMessage({
1905
1935
  jsonrpc: '2.0',
@@ -1907,6 +1937,9 @@ iframe { border: none; width: 100%; height: 100%; display: block; }
1907
1937
  params: {}
1908
1938
  }, '*');
1909
1939
  }, 0);
1940
+ // Stop retrying after 10 seconds — if the host hasn't responded by then,
1941
+ // something else is wrong.
1942
+ setTimeout(function() { clearInterval(readyInterval); }, 10000);
1910
1943
  })();
1911
1944
  <\/script>
1912
1945
  </body>
@@ -2516,6 +2549,15 @@ function useInspectorState({ simulations, defaultHost = "chatgpt" }) {
2516
2549
  (0, react.useEffect)(() => {
2517
2550
  if (isMobileWidth(screenWidth) && displayMode === "pip") _setDisplayMode("fullscreen");
2518
2551
  }, [screenWidth, displayMode]);
2552
+ (0, react.useEffect)(() => {
2553
+ const modeInsets = getHostShell(activeHost)?.safeAreaByDisplayMode?.[displayMode];
2554
+ if (modeInsets) setSafeAreaInsets({
2555
+ top: modeInsets.top ?? 0,
2556
+ bottom: modeInsets.bottom ?? 0,
2557
+ left: modeInsets.left ?? 0,
2558
+ right: modeInsets.right ?? 0
2559
+ });
2560
+ }, [displayMode, activeHost]);
2519
2561
  const handleDisplayModeChange = (mode) => {
2520
2562
  setDisplayMode(mode);
2521
2563
  };
@@ -4368,4 +4410,4 @@ Object.defineProperty(exports, "useThemeContext", {
4368
4410
  }
4369
4411
  });
4370
4412
 
4371
- //# sourceMappingURL=inspector-CTMccsz9.cjs.map
4413
+ //# sourceMappingURL=inspector-8nPV2A-z.cjs.map