sunpeak 0.18.2 → 0.18.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.
Files changed (76) hide show
  1. package/bin/commands/dev.mjs +6 -2
  2. package/bin/commands/inspect.mjs +405 -5
  3. package/bin/commands/new.mjs +5 -0
  4. package/bin/lib/dev-overlay.mjs +50 -0
  5. package/bin/lib/live/live-config.d.mts +3 -0
  6. package/bin/lib/live/live-config.mjs +3 -1
  7. package/bin/lib/sandbox-server.mjs +11 -1
  8. package/dist/chatgpt/index.cjs +2 -2
  9. package/dist/chatgpt/index.js +2 -2
  10. package/dist/claude/index.cjs +1 -1
  11. package/dist/claude/index.js +1 -1
  12. package/dist/hooks/index.d.ts +1 -0
  13. package/dist/hooks/use-request-teardown.d.ts +21 -0
  14. package/dist/host/chatgpt/index.cjs +1 -1
  15. package/dist/host/chatgpt/index.js +1 -1
  16. package/dist/index.cjs +110 -70
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.ts +3 -3
  19. package/dist/index.js +68 -31
  20. package/dist/index.js.map +1 -1
  21. package/dist/inspector/hosts.d.ts +12 -0
  22. package/dist/inspector/index.cjs +2 -2
  23. package/dist/inspector/index.js +2 -2
  24. package/dist/inspector/inspector-url.d.ts +13 -0
  25. package/dist/inspector/mcp-app-host.d.ts +3 -0
  26. package/dist/inspector/simple-sidebar.d.ts +1 -1
  27. package/dist/inspector/use-inspector-state.d.ts +2 -0
  28. package/dist/inspector/use-mcp-connection.d.ts +9 -1
  29. package/dist/{inspector-CByJjmPD.cjs → inspector-CKc58UuI.cjs} +557 -136
  30. package/dist/inspector-CKc58UuI.cjs.map +1 -0
  31. package/dist/{inspector-ClhpqKLi.js → inspector-DZrN0kej.js} +556 -135
  32. package/dist/inspector-DZrN0kej.js.map +1 -0
  33. package/dist/{inspector-url-7qhtJwY6.cjs → inspector-url-C3LTKgXt.cjs} +3 -1
  34. package/dist/inspector-url-C3LTKgXt.cjs.map +1 -0
  35. package/dist/{inspector-url-DuEFmxLP.js → inspector-url-CyQcuBI9.js} +3 -1
  36. package/dist/inspector-url-CyQcuBI9.js.map +1 -0
  37. package/dist/mcp/index.cjs +119 -40
  38. package/dist/mcp/index.cjs.map +1 -1
  39. package/dist/mcp/index.js +116 -37
  40. package/dist/mcp/index.js.map +1 -1
  41. package/dist/style.css +12 -0
  42. package/dist/{use-app-X7JbGskk.js → use-app-BNbz1uzj.js} +51 -42
  43. package/dist/use-app-BNbz1uzj.js.map +1 -0
  44. package/dist/{use-app-D2h-aiyr.cjs → use-app-Dqh20JPP.cjs} +93 -72
  45. package/dist/use-app-Dqh20JPP.cjs.map +1 -0
  46. package/package.json +2 -2
  47. package/template/dist/albums/albums.html +3 -3
  48. package/template/dist/albums/albums.json +1 -1
  49. package/template/dist/carousel/carousel.html +3 -3
  50. package/template/dist/carousel/carousel.json +1 -1
  51. package/template/dist/map/map.html +3 -3
  52. package/template/dist/map/map.json +1 -1
  53. package/template/dist/review/review.html +3 -3
  54. package/template/dist/review/review.json +1 -1
  55. package/template/node_modules/.vite/deps/_metadata.json +3 -3
  56. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js +51 -42
  57. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js.map +1 -1
  58. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js +56 -50
  59. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js.map +1 -1
  60. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js +52 -43
  61. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js.map +1 -1
  62. package/template/node_modules/.vite-mcp/deps/_metadata.json +22 -22
  63. package/template/tests/e2e/albums.spec.ts +20 -16
  64. package/template/tests/e2e/carousel.spec.ts +1 -1
  65. package/template/tests/e2e/dev-overlay.spec.ts +118 -0
  66. package/template/tests/e2e/helpers.ts +13 -0
  67. package/template/tests/e2e/map.spec.ts +1 -1
  68. package/template/tests/e2e/review.spec.ts +1 -1
  69. package/template/tests/live/albums.spec.ts +10 -0
  70. package/template/tests/live/playwright.config.ts +1 -1
  71. package/dist/inspector-CByJjmPD.cjs.map +0 -1
  72. package/dist/inspector-ClhpqKLi.js.map +0 -1
  73. package/dist/inspector-url-7qhtJwY6.cjs.map +0 -1
  74. package/dist/inspector-url-DuEFmxLP.js.map +0 -1
  75. package/dist/use-app-D2h-aiyr.cjs.map +0 -1
  76. package/dist/use-app-X7JbGskk.js.map +0 -1
@@ -487,7 +487,9 @@ function ClaudeConversation({ children, screenWidth, displayMode, platform, onRe
487
487
  style: {
488
488
  transform: "translate(0)",
489
489
  backgroundColor: "var(--sim-bg-conversation, var(--color-background-primary))",
490
- color: "var(--color-text-primary)"
490
+ color: "var(--color-text-primary)",
491
+ fontFamily: "var(--font-sans)",
492
+ WebkitFontSmoothing: "antialiased"
491
493
  },
492
494
  children: [
493
495
  isFullscreen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -521,17 +523,20 @@ function ClaudeConversation({ children, screenWidth, displayMode, platform, onRe
521
523
  style: { backgroundColor: "var(--sim-bg-conversation, var(--color-background-primary))" },
522
524
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
523
525
  className: "max-w-[48rem] mx-auto",
524
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
525
- type: "text",
526
- name: "userInput",
527
- disabled: true,
528
- placeholder: "Reply to sunpeak...",
529
- className: "w-full rounded-xl px-4 py-2.5 text-sm",
526
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
527
+ className: "relative rounded-[20px] px-4 py-2.5",
530
528
  style: {
531
529
  backgroundColor: "var(--sim-bg-reply-input, var(--color-background-secondary))",
532
- border: "1px solid var(--color-border-primary)",
533
- color: "var(--color-text-primary)"
534
- }
530
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.035), 0 0 0 0.5px var(--color-border-tertiary)"
531
+ },
532
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
533
+ className: "w-full text-base outline-none opacity-50",
534
+ style: {
535
+ lineHeight: "1.4",
536
+ color: "var(--color-text-tertiary)"
537
+ },
538
+ children: "Reply to sunpeak..."
539
+ })
535
540
  })
536
541
  })
537
542
  })
@@ -559,8 +564,14 @@ function ClaudeConversation({ children, screenWidth, displayMode, platform, onRe
559
564
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
560
565
  className: "max-w-[48rem] mx-auto flex justify-end",
561
566
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
562
- className: "inline-block rounded-2xl px-4 py-2.5 text-sm max-w-[85%]",
563
- style: { backgroundColor: "var(--sim-bg-user-bubble, var(--color-background-tertiary))" },
567
+ className: "inline-flex rounded-xl max-w-[85%] break-words",
568
+ style: {
569
+ padding: "10px 16px",
570
+ lineHeight: "22.4px",
571
+ fontSize: "16px",
572
+ fontWeight: 430,
573
+ backgroundColor: "var(--sim-bg-user-bubble, var(--color-background-tertiary))"
574
+ },
564
575
  children: userMessage
565
576
  })
566
577
  })
@@ -630,17 +641,18 @@ function ClaudeConversation({ children, screenWidth, displayMode, platform, onRe
630
641
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
631
642
  className: "max-w-[48rem] mx-auto px-4 py-4",
632
643
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
633
- className: "relative",
634
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
635
- type: "text",
636
- name: "userInput",
637
- disabled: true,
638
- placeholder: "Reply to sunpeak...",
639
- className: "w-full rounded-xl px-4 py-2.5 text-sm",
644
+ className: "relative rounded-[20px] px-4 py-2.5",
645
+ style: {
646
+ backgroundColor: "var(--sim-bg-reply-input, var(--color-background-secondary))",
647
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.035), 0 0 0 0.5px var(--color-border-tertiary)"
648
+ },
649
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
650
+ className: "w-full text-base outline-none opacity-50",
640
651
  style: {
641
- backgroundColor: "var(--sim-bg-reply-input, var(--color-background-secondary))",
642
- border: "1px solid var(--color-border-primary)"
643
- }
652
+ lineHeight: "1.4",
653
+ color: "var(--color-text-tertiary)"
654
+ },
655
+ children: "Reply to sunpeak..."
644
656
  })
645
657
  })
646
658
  })
@@ -651,17 +663,32 @@ function ClaudeConversation({ children, screenWidth, displayMode, platform, onRe
651
663
  }
652
664
  //#endregion
653
665
  //#region src/claude/claude-host.ts
666
+ /**
667
+ * Claude host version info — matches what Claude reports via the MCP protocol.
668
+ * Verified against production Claude on 2026-03-25.
669
+ */
654
670
  var CLAUDE_HOST_INFO = {
655
671
  name: "Claude",
656
672
  version: "1.0.0"
657
673
  };
674
+ /**
675
+ * Claude host capabilities — matches what Claude reports via the MCP protocol.
676
+ * Verified against production Claude on 2026-03-25.
677
+ *
678
+ * Notable: Claude supports downloadFile, updateModelContext.image, and
679
+ * message.text. serverTools and serverResources both report listChanged.
680
+ * No sandbox.permissions (no microphone etc.). No PiP display mode.
681
+ */
658
682
  var CLAUDE_HOST_CAPABILITIES = {
659
683
  openLinks: {},
660
- serverTools: {},
661
- serverResources: {},
662
684
  downloadFile: {},
685
+ serverTools: { listChanged: true },
686
+ serverResources: { listChanged: true },
663
687
  logging: {},
664
- updateModelContext: { text: {} },
688
+ updateModelContext: {
689
+ text: {},
690
+ image: {}
691
+ },
665
692
  message: { text: {} },
666
693
  sandbox: {}
667
694
  };
@@ -680,35 +707,100 @@ registerHostShell({
680
707
  applyTheme: applyClaudeTheme,
681
708
  hostInfo: CLAUDE_HOST_INFO,
682
709
  hostCapabilities: CLAUDE_HOST_CAPABILITIES,
683
- userAgent: "claude",
684
710
  styleVariables: {
685
711
  ...DEFAULT_STYLE_VARIABLES,
686
- "--color-background-primary": "light-dark(#faf9f5, #262624)",
687
- "--color-background-secondary": "light-dark(#ffffff, #3a3935)",
688
- "--color-background-tertiary": "light-dark(#e8e4dc, #4a4843)",
689
- "--color-background-inverse": "light-dark(#2b2a27, #f3f0e8)",
690
- "--color-text-primary": "light-dark(#2d2b27, #e8e4dc)",
691
- "--color-text-secondary": "light-dark(#6b6560, #9b9690)",
692
- "--color-text-tertiary": "light-dark(#9b9690, #6b6560)",
693
- "--color-text-inverse": "light-dark(#e8e4dc, #2d2b27)",
694
- "--color-border-primary": "light-dark(#e0ddd5, #4a4843)",
695
- "--color-border-secondary": "light-dark(#d5d1c8, #5a5753)",
696
- "--color-border-tertiary": "light-dark(#f0ede5, #3a3935)"
712
+ "--color-background-primary": "light-dark(rgba(255, 255, 255, 1), rgba(48, 48, 46, 1))",
713
+ "--color-background-secondary": "light-dark(rgba(245, 244, 237, 1), rgba(38, 38, 36, 1))",
714
+ "--color-background-tertiary": "light-dark(rgba(250, 249, 245, 1), rgba(20, 20, 19, 1))",
715
+ "--color-background-inverse": "light-dark(rgba(20, 20, 19, 1), rgba(250, 249, 245, 1))",
716
+ "--color-background-ghost": "light-dark(rgba(255, 255, 255, 0), rgba(48, 48, 46, 0))",
717
+ "--color-background-info": "light-dark(rgba(214, 228, 246, 1), rgba(37, 62, 95, 1))",
718
+ "--color-background-danger": "light-dark(rgba(247, 236, 236, 1), rgba(96, 42, 40, 1))",
719
+ "--color-background-success": "light-dark(rgba(233, 241, 220, 1), rgba(27, 70, 20, 1))",
720
+ "--color-background-warning": "light-dark(rgba(246, 238, 223, 1), rgba(72, 58, 15, 1))",
721
+ "--color-background-disabled": "light-dark(rgba(255, 255, 255, 0.5), rgba(48, 48, 46, 0.5))",
722
+ "--color-text-primary": "light-dark(rgba(20, 20, 19, 1), rgba(250, 249, 245, 1))",
723
+ "--color-text-secondary": "light-dark(rgba(61, 61, 58, 1), rgba(194, 192, 182, 1))",
724
+ "--color-text-tertiary": "light-dark(rgba(115, 114, 108, 1), rgba(156, 154, 146, 1))",
725
+ "--color-text-inverse": "light-dark(rgba(255, 255, 255, 1), rgba(20, 20, 19, 1))",
726
+ "--color-text-ghost": "light-dark(rgba(115, 114, 108, 0.5), rgba(156, 154, 146, 0.5))",
727
+ "--color-text-info": "light-dark(rgba(50, 102, 173, 1), rgba(128, 170, 221, 1))",
728
+ "--color-text-danger": "light-dark(rgba(127, 44, 40, 1), rgba(238, 136, 132, 1))",
729
+ "--color-text-success": "light-dark(rgba(38, 91, 25, 1), rgba(122, 185, 72, 1))",
730
+ "--color-text-warning": "light-dark(rgba(90, 72, 21, 1), rgba(209, 160, 65, 1))",
731
+ "--color-text-disabled": "light-dark(rgba(20, 20, 19, 0.5), rgba(250, 249, 245, 0.5))",
732
+ "--color-border-primary": "light-dark(rgba(31, 30, 29, 0.4), rgba(222, 220, 209, 0.4))",
733
+ "--color-border-secondary": "light-dark(rgba(31, 30, 29, 0.3), rgba(222, 220, 209, 0.3))",
734
+ "--color-border-tertiary": "light-dark(rgba(31, 30, 29, 0.15), rgba(222, 220, 209, 0.15))",
735
+ "--color-border-inverse": "light-dark(rgba(255, 255, 255, 0.3), rgba(20, 20, 19, 0.15))",
736
+ "--color-border-ghost": "light-dark(rgba(31, 30, 29, 0), rgba(222, 220, 209, 0))",
737
+ "--color-border-info": "light-dark(rgba(70, 130, 213, 1), rgba(70, 130, 213, 1))",
738
+ "--color-border-danger": "light-dark(rgba(167, 61, 57, 1), rgba(205, 92, 88, 1))",
739
+ "--color-border-success": "light-dark(rgba(67, 116, 38, 1), rgba(89, 145, 48, 1))",
740
+ "--color-border-warning": "light-dark(rgba(128, 92, 31, 1), rgba(168, 120, 41, 1))",
741
+ "--color-border-disabled": "light-dark(rgba(31, 30, 29, 0.1), rgba(222, 220, 209, 0.1))",
742
+ "--color-ring-primary": "light-dark(rgba(20, 20, 19, 0.7), rgba(250, 249, 245, 0.7))",
743
+ "--color-ring-secondary": "light-dark(rgba(61, 61, 58, 0.7), rgba(194, 192, 182, 0.7))",
744
+ "--color-ring-inverse": "light-dark(rgba(255, 255, 255, 0.7), rgba(20, 20, 19, 0.7))",
745
+ "--color-ring-info": "light-dark(rgba(50, 102, 173, 0.5), rgba(128, 170, 221, 0.5))",
746
+ "--color-ring-danger": "light-dark(rgba(167, 61, 57, 0.5), rgba(205, 92, 88, 0.5))",
747
+ "--color-ring-success": "light-dark(rgba(67, 116, 38, 0.5), rgba(89, 145, 48, 0.5))",
748
+ "--color-ring-warning": "light-dark(rgba(128, 92, 31, 0.5), rgba(168, 120, 41, 0.5))",
749
+ "--font-sans": "\"Anthropic Sans\", system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif",
750
+ "--font-mono": "ui-monospace, monospace",
751
+ "--font-text-xs-size": "12px",
752
+ "--font-text-sm-size": "14px",
753
+ "--font-text-md-size": "16px",
754
+ "--font-text-lg-size": "20px",
755
+ "--font-heading-xs-size": "12px",
756
+ "--font-heading-sm-size": "14px",
757
+ "--font-heading-md-size": "16px",
758
+ "--font-heading-lg-size": "20px",
759
+ "--font-heading-xl-size": "24px",
760
+ "--font-heading-2xl-size": "28px",
761
+ "--font-heading-3xl-size": "36px",
762
+ "--font-text-md-line-height": "1.4",
763
+ "--font-text-lg-line-height": "1.25",
764
+ "--font-heading-lg-line-height": "1.25",
765
+ "--font-heading-2xl-line-height": "1.1",
766
+ "--font-heading-3xl-line-height": "1",
767
+ "--border-radius-xs": "4px",
768
+ "--border-radius-sm": "6px",
769
+ "--border-radius-md": "8px",
770
+ "--border-radius-lg": "10px",
771
+ "--border-width-regular": "0.5px"
697
772
  },
698
773
  pageStyles: {
699
- "--sim-bg-sidebar": "light-dark(#f9f8f3, #252523)",
700
- "--sim-bg-conversation": "light-dark(#faf9f5, #262624)",
701
- "--sim-bg-user-bubble": "light-dark(#f1eee6, #141413)",
702
- "--sim-bg-reply-input": "light-dark(#ffffff, #30302e)"
703
- }
774
+ "--sim-bg-sidebar": "light-dark(rgb(250, 249, 245), rgb(38, 38, 36))",
775
+ "--sim-bg-conversation": "light-dark(rgb(250, 249, 245), rgb(38, 38, 36))",
776
+ "--sim-bg-user-bubble": "light-dark(rgb(240, 238, 230), rgb(20, 20, 19))",
777
+ "--sim-bg-reply-input": "light-dark(rgb(255, 255, 255), rgb(48, 48, 46))"
778
+ },
779
+ availableDisplayModes: ["inline", "fullscreen"],
780
+ fontCss: `@font-face {
781
+ font-family: "Anthropic Sans";
782
+ src: url("https://assets-proxy.anthropic.com/claude-ai/v2/assets/v1/cc27851ad-CFxw3nG7.woff2") format("woff2");
783
+ font-weight: 300 800;
784
+ font-style: normal;
785
+ font-display: swap;
786
+ font-feature-settings: "dlig" 0;
787
+ }
788
+ @font-face {
789
+ font-family: "Anthropic Sans";
790
+ src: url("https://assets-proxy.anthropic.com/claude-ai/v2/assets/v1/c9d3a3a49-BI1hrwN4.woff2") format("woff2");
791
+ font-weight: 300 800;
792
+ font-style: italic;
793
+ font-display: swap;
794
+ font-feature-settings: "dlig" 0;
795
+ }`
704
796
  });
705
797
  //#endregion
706
- //#region ../../node_modules/.pnpm/@modelcontextprotocol+ext-apps@1.2.2_@modelcontextprotocol+sdk@1.27.1_zod@4.3.6__react-_e9bf7657371391a829fe8b4e289b253c/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js
707
- 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."), D = require_protocol.union([
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([
708
800
  require_protocol.literal("inline"),
709
801
  require_protocol.literal("fullscreen"),
710
802
  require_protocol.literal("pip")
711
- ]).describe("Display mode for UI presentation."), OQ = require_protocol.union([
803
+ ]).describe("Display mode for UI presentation."), IQ = require_protocol.union([
712
804
  require_protocol.literal("--color-background-primary"),
713
805
  require_protocol.literal("--color-background-secondary"),
714
806
  require_protocol.literal("--color-background-tertiary"),
@@ -785,7 +877,7 @@ var G = "2026-01-26", m = require_protocol.union([require_protocol.literal("ligh
785
877
  require_protocol.literal("--shadow-sm"),
786
878
  require_protocol.literal("--shadow-md"),
787
879
  require_protocol.literal("--shadow-lg")
788
- ]).describe("CSS variable keys available to MCP apps for theming."), VQ = require_protocol.record(OQ.describe(`Style variables for theming MCP apps.
880
+ ]).describe("CSS variable keys available to MCP apps for theming."), AQ = require_protocol.record(IQ.describe(`Style variables for theming MCP apps.
789
881
 
790
882
  Individual style keys are optional - hosts may provide any subset of these values.
791
883
  Values are strings containing CSS values (colors, sizes, font stacks, etc.).
@@ -810,7 +902,7 @@ for compatibility with Zod schema generation. Both are functionally equivalent f
810
902
  require_protocol.object({ isError: require_protocol.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).") }).passthrough();
811
903
  require_protocol.object({ isError: require_protocol.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).") }).passthrough();
812
904
  require_protocol.object({ isError: require_protocol.boolean().optional().describe("True if the host rejected or failed to deliver the message.") }).passthrough();
813
- var F = require_protocol.object({
905
+ var L = require_protocol.object({
814
906
  method: require_protocol.literal("ui/notifications/sandbox-proxy-ready"),
815
907
  params: require_protocol.object({})
816
908
  }), j = require_protocol.object({
@@ -845,22 +937,25 @@ require_protocol.object({
845
937
  method: require_protocol.literal("ui/notifications/tool-cancelled"),
846
938
  params: require_protocol.object({ reason: require_protocol.string().optional().describe("Optional reason for the cancellation (e.g., \"user action\", \"timeout\").") })
847
939
  });
848
- var p = require_protocol.object({ fonts: require_protocol.string().optional() }), c = require_protocol.object({
849
- variables: VQ.optional().describe("CSS variables for theming the app."),
850
- css: p.optional().describe("CSS blocks that apps can inject.")
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.")
851
943
  });
852
944
  require_protocol.object({
853
945
  method: require_protocol.literal("ui/resource-teardown"),
854
946
  params: require_protocol.object({})
855
947
  });
856
- var R = require_protocol.record(require_protocol.string(), require_protocol.unknown()), O = require_protocol.object({
948
+ var H = require_protocol.record(require_protocol.string(), require_protocol.unknown()), O = require_protocol.object({
857
949
  text: require_protocol.object({}).optional().describe("Host supports text content blocks."),
858
950
  image: require_protocol.object({}).optional().describe("Host supports image content blocks."),
859
951
  audio: require_protocol.object({}).optional().describe("Host supports audio content blocks."),
860
952
  resource: require_protocol.object({}).optional().describe("Host supports resource content blocks."),
861
953
  resourceLink: require_protocol.object({}).optional().describe("Host supports resource link content blocks."),
862
954
  structuredContent: require_protocol.object({}).optional().describe("Host supports structured content.")
863
- }), n = require_protocol.object({
955
+ }), M = require_protocol.object({
956
+ method: require_protocol.literal("ui/notifications/request-teardown"),
957
+ params: require_protocol.object({}).optional()
958
+ }), i = require_protocol.object({
864
959
  experimental: require_protocol.object({}).optional().describe("Experimental features (structure TBD)."),
865
960
  openLinks: require_protocol.object({}).optional().describe("Host supports opening external URLs."),
866
961
  downloadFile: require_protocol.object({}).optional().describe("Host supports file downloads via ui/download-file."),
@@ -873,11 +968,11 @@ var R = require_protocol.record(require_protocol.string(), require_protocol.unkn
873
968
  }).optional().describe("Sandbox configuration applied by the host."),
874
969
  updateModelContext: O.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),
875
970
  message: O.optional().describe("Host supports receiving content messages (ui/message) from the view.")
876
- }), i = require_protocol.object({
971
+ }), l = require_protocol.object({
877
972
  experimental: require_protocol.object({}).optional().describe("Experimental features (structure TBD)."),
878
973
  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."),
879
974
  availableDisplayModes: require_protocol.array(D).optional().describe("Display modes the app supports.")
880
- }), M = require_protocol.object({
975
+ }), v = require_protocol.object({
881
976
  method: require_protocol.literal("ui/notifications/initialized"),
882
977
  params: require_protocol.object({}).optional()
883
978
  });
@@ -906,18 +1001,18 @@ var W = require_protocol.object({
906
1001
  params: require_protocol.object({ mode: D.describe("The display mode being requested.") })
907
1002
  });
908
1003
  require_protocol.object({ mode: D.describe("The display mode that was actually set. May differ from requested if not supported.") }).passthrough();
909
- var l = require_protocol.union([require_protocol.literal("model"), require_protocol.literal("app")]).describe("Tool visibility scope - who can access the tool.");
1004
+ var r = require_protocol.union([require_protocol.literal("model"), require_protocol.literal("app")]).describe("Tool visibility scope - who can access the tool.");
910
1005
  require_protocol.object({
911
1006
  resourceUri: require_protocol.string().optional(),
912
- visibility: require_protocol.array(l).optional().describe(`Who can access this tool. Default: ["model", "app"]
1007
+ visibility: require_protocol.array(r).optional().describe(`Who can access this tool. Default: ["model", "app"]
913
1008
  - "model": Tool visible to and callable by the agent
914
1009
  - "app": Tool callable by the app from this server only`)
915
1010
  });
916
1011
  require_protocol.object({ mimeTypes: require_protocol.array(require_protocol.string()).optional().describe("Array of supported MIME types for UI resources.\nMust include `\"text/html;profile=mcp-app\"` for MCP Apps support.") });
917
- var S = require_protocol.object({
1012
+ var C = require_protocol.object({
918
1013
  method: require_protocol.literal("ui/download-file"),
919
1014
  params: require_protocol.object({ contents: require_protocol.array(require_protocol.union([require_protocol.EmbeddedResourceSchema, require_protocol.ResourceLinkSchema])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.") })
920
- }), C = require_protocol.object({
1015
+ }), S = require_protocol.object({
921
1016
  method: require_protocol.literal("ui/message"),
922
1017
  params: require_protocol.object({
923
1018
  role: require_protocol.literal("user").describe("Message role, currently only \"user\" is supported."),
@@ -937,13 +1032,13 @@ require_protocol.object({
937
1032
  method: require_protocol.literal("ui/notifications/tool-result"),
938
1033
  params: require_protocol.CallToolResultSchema.describe("Standard MCP tool execution result.")
939
1034
  });
940
- var q = require_protocol.object({
1035
+ var y = require_protocol.object({
941
1036
  toolInfo: require_protocol.object({
942
1037
  id: require_protocol.RequestIdSchema.optional().describe("JSON-RPC id of the tools/call request."),
943
1038
  tool: require_protocol.ToolSchema.describe("Tool definition including name, inputSchema, etc.")
944
1039
  }).optional().describe("Metadata of the tool call that instantiated this App."),
945
- theme: m.optional().describe("Current color theme preference."),
946
- styles: c.optional().describe("Style configuration for theming the app."),
1040
+ theme: p.optional().describe("Current color theme preference."),
1041
+ styles: n.optional().describe("Style configuration for theming the app."),
947
1042
  displayMode: D.optional().describe("How the UI is currently displayed."),
948
1043
  availableDisplayModes: require_protocol.array(D).optional().describe("Display modes the host supports."),
949
1044
  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
@@ -969,27 +1064,27 @@ container holding the app. Specify either width or maxWidth, and either height o
969
1064
  }).passthrough();
970
1065
  require_protocol.object({
971
1066
  method: require_protocol.literal("ui/notifications/host-context-changed"),
972
- params: q.describe("Partial context update containing only changed fields.")
1067
+ params: y.describe("Partial context update containing only changed fields.")
973
1068
  });
974
- var y = require_protocol.object({
1069
+ var f = require_protocol.object({
975
1070
  method: require_protocol.literal("ui/update-model-context"),
976
1071
  params: require_protocol.object({
977
1072
  content: require_protocol.array(require_protocol.ContentBlockSchema).optional().describe("Context content blocks (text, image, etc.)."),
978
1073
  structuredContent: require_protocol.record(require_protocol.string(), require_protocol.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")
979
1074
  })
980
- }), f = require_protocol.object({
1075
+ }), d = require_protocol.object({
981
1076
  method: require_protocol.literal("ui/initialize"),
982
1077
  params: require_protocol.object({
983
1078
  appInfo: require_protocol.ImplementationSchema.describe("App identification (name and version)."),
984
- appCapabilities: i.describe("Features and capabilities this app provides."),
1079
+ appCapabilities: l.describe("Features and capabilities this app provides."),
985
1080
  protocolVersion: require_protocol.string().describe("Protocol version this app supports.")
986
1081
  })
987
1082
  });
988
1083
  require_protocol.object({
989
1084
  protocolVersion: require_protocol.string().describe("Negotiated protocol version string (e.g., \"2025-11-21\")."),
990
1085
  hostInfo: require_protocol.ImplementationSchema.describe("Host application identification and version."),
991
- hostCapabilities: n.describe("Features and capabilities provided by the host."),
992
- hostContext: q.describe("Rich context about the host environment.")
1086
+ hostCapabilities: i.describe("Features and capabilities provided by the host."),
1087
+ hostContext: y.describe("Rich context about the host environment.")
993
1088
  }).passthrough();
994
1089
  var N = class {
995
1090
  eventTarget;
@@ -1025,8 +1120,8 @@ var N = class {
1025
1120
  sessionId;
1026
1121
  setProtocolVersion;
1027
1122
  };
1028
- var rQ = [G];
1029
- var oQ = class extends require_protocol.Protocol {
1123
+ var aQ = [G];
1124
+ var tQ = class extends require_protocol.Protocol {
1030
1125
  _client;
1031
1126
  _hostInfo;
1032
1127
  _capabilities;
@@ -1038,7 +1133,7 @@ var oQ = class extends require_protocol.Protocol {
1038
1133
  this._client = X;
1039
1134
  this._hostInfo = Y;
1040
1135
  this._capabilities = Z;
1041
- this._hostContext = $?.hostContext || {}, this.setRequestHandler(f, (K) => this._oninitialize(K)), this.setRequestHandler(require_protocol.PingRequestSchema, (K, J) => {
1136
+ this._hostContext = $?.hostContext || {}, this.setRequestHandler(d, (K) => this._oninitialize(K)), this.setRequestHandler(require_protocol.PingRequestSchema, (K, J) => {
1042
1137
  return this.onping?.(K.params, J), {};
1043
1138
  }), this.setRequestHandler(W, (K) => {
1044
1139
  return { mode: this._hostContext.displayMode ?? "inline" };
@@ -1055,13 +1150,13 @@ var oQ = class extends require_protocol.Protocol {
1055
1150
  this.setNotificationHandler(P, (Y) => X(Y.params));
1056
1151
  }
1057
1152
  set onsandboxready(X) {
1058
- this.setNotificationHandler(F, (Y) => X(Y.params));
1153
+ this.setNotificationHandler(L, (Y) => X(Y.params));
1059
1154
  }
1060
1155
  set oninitialized(X) {
1061
- this.setNotificationHandler(M, (Y) => X(Y.params));
1156
+ this.setNotificationHandler(v, (Y) => X(Y.params));
1062
1157
  }
1063
1158
  set onmessage(X) {
1064
- this.setRequestHandler(C, async (Y, Z) => {
1159
+ this.setRequestHandler(S, async (Y, Z) => {
1065
1160
  return X(Y.params, Z);
1066
1161
  });
1067
1162
  }
@@ -1071,10 +1166,13 @@ var oQ = class extends require_protocol.Protocol {
1071
1166
  });
1072
1167
  }
1073
1168
  set ondownloadfile(X) {
1074
- this.setRequestHandler(S, async (Y, Z) => {
1169
+ this.setRequestHandler(C, async (Y, Z) => {
1075
1170
  return X(Y.params, Z);
1076
1171
  });
1077
1172
  }
1173
+ set onrequestteardown(X) {
1174
+ this.setNotificationHandler(M, (Y) => X(Y.params));
1175
+ }
1078
1176
  set onrequestdisplaymode(X) {
1079
1177
  this.setRequestHandler(W, async (Y, Z) => {
1080
1178
  return X(Y.params, Z);
@@ -1086,7 +1184,7 @@ var oQ = class extends require_protocol.Protocol {
1086
1184
  });
1087
1185
  }
1088
1186
  set onupdatemodelcontext(X) {
1089
- this.setRequestHandler(y, async (Y, Z) => {
1187
+ this.setRequestHandler(f, async (Y, Z) => {
1090
1188
  return X(Y.params, Z);
1091
1189
  });
1092
1190
  }
@@ -1148,7 +1246,7 @@ var oQ = class extends require_protocol.Protocol {
1148
1246
  async _oninitialize(X) {
1149
1247
  let Y = X.params.protocolVersion;
1150
1248
  return this._appCapabilities = X.params.appCapabilities, this._appInfo = X.params.appInfo, {
1151
- protocolVersion: rQ.includes(Y) ? Y : G,
1249
+ protocolVersion: aQ.includes(Y) ? Y : G,
1152
1250
  hostCapabilities: this.getCapabilities(),
1153
1251
  hostInfo: this._hostInfo,
1154
1252
  hostContext: this._hostContext
@@ -1158,7 +1256,7 @@ var oQ = class extends require_protocol.Protocol {
1158
1256
  let Y = {}, Z = !1;
1159
1257
  for (let $ of Object.keys(X)) {
1160
1258
  let K = this._hostContext[$], J = X[$];
1161
- if (aQ(K, J)) continue;
1259
+ if (sQ(K, J)) continue;
1162
1260
  Y[$] = J, Z = !0;
1163
1261
  }
1164
1262
  if (Z) this._hostContext = X, this.sendHostContextChange(Y);
@@ -1203,7 +1301,7 @@ var oQ = class extends require_protocol.Protocol {
1203
1301
  return this.request({
1204
1302
  method: "ui/resource-teardown",
1205
1303
  params: X
1206
- }, R, Y);
1304
+ }, H, Y);
1207
1305
  }
1208
1306
  sendResourceTeardown = this.teardownResource;
1209
1307
  async connect(X) {
@@ -1249,7 +1347,7 @@ var oQ = class extends require_protocol.Protocol {
1249
1347
  return super.connect(X);
1250
1348
  }
1251
1349
  };
1252
- function aQ(X, Y) {
1350
+ function sQ(X, Y) {
1253
1351
  return JSON.stringify(X) === JSON.stringify(Y);
1254
1352
  }
1255
1353
  //#endregion
@@ -1283,10 +1381,11 @@ var McpAppHost = class {
1283
1381
  _prevDisplayMode;
1284
1382
  _pendingToolInput = null;
1285
1383
  _pendingToolResult = null;
1384
+ _messageListener = null;
1286
1385
  constructor(options = {}) {
1287
1386
  this.options = options;
1288
1387
  this._prevDisplayMode = options.hostContext?.displayMode;
1289
- this.bridge = new oQ(null, options.hostInfo ?? DEFAULT_HOST_INFO, options.hostCapabilities ?? DEFAULT_HOST_CAPABILITIES, { hostContext: options.hostContext });
1388
+ this.bridge = new tQ(null, options.hostInfo ?? DEFAULT_HOST_INFO, options.hostCapabilities ?? DEFAULT_HOST_CAPABILITIES, { hostContext: options.hostContext });
1290
1389
  this.bridge.oninitialized = () => {
1291
1390
  this._initialized = true;
1292
1391
  if (this._pendingToolInput) {
@@ -1299,38 +1398,35 @@ var McpAppHost = class {
1299
1398
  }
1300
1399
  };
1301
1400
  this.bridge.onopenlink = async ({ url }) => {
1302
- console.log("[MCP App] openLink:", url);
1303
1401
  if (this.options.onOpenLink) this.options.onOpenLink(url);
1304
- else {
1305
- try {
1306
- const parsed = new URL(url);
1307
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
1308
- console.warn("[MCP App] openLink blocked non-http(s) URL:", url);
1309
- return {};
1310
- }
1311
- } catch {
1312
- console.warn("[MCP App] openLink blocked invalid URL:", url);
1313
- return {};
1314
- }
1315
- window.open(url, "_blank");
1402
+ else try {
1403
+ const parsed = new URL(url);
1404
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") console.warn("[MCP App] openLink blocked non-http(s) URL:", url);
1405
+ else window.open(url, "_blank");
1406
+ } catch {
1407
+ console.warn("[MCP App] openLink blocked invalid URL:", url);
1316
1408
  }
1317
- return {};
1409
+ const ack = {};
1410
+ console.log(`%c[MCP ↓]%c host → app: %copenLink ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1411
+ return ack;
1318
1412
  };
1319
1413
  this.bridge.onmessage = async ({ role, content }) => {
1320
1414
  if (this.options.onMessage) this.options.onMessage(role, content);
1321
- else console.log("[MCP App] sendMessage:", {
1322
- role,
1323
- content
1324
- });
1325
- return {};
1415
+ const ack = {};
1416
+ console.log(`%c[MCP ↓]%c host → app: %csendMessage ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1417
+ return ack;
1326
1418
  };
1327
1419
  this.bridge.onrequestdisplaymode = async ({ mode }) => {
1328
1420
  this.options.onDisplayModeChange?.(mode);
1329
- return { mode };
1421
+ const result = { mode };
1422
+ console.log(`%c[MCP ↓]%c host → app: %crequestDisplayMode result`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1423
+ return result;
1330
1424
  };
1331
1425
  this.bridge.onupdatemodelcontext = async ({ content, structuredContent }) => {
1332
1426
  this.options.onUpdateModelContext?.(content ?? [], structuredContent);
1333
- return {};
1427
+ const ack = {};
1428
+ console.log(`%c[MCP ↓]%c host → app: %cupdateModelContext ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1429
+ return ack;
1334
1430
  };
1335
1431
  this.bridge.onsizechange = (params) => {
1336
1432
  this.options.onSizeChanged?.(params);
@@ -1347,17 +1443,24 @@ var McpAppHost = class {
1347
1443
  }
1348
1444
  };
1349
1445
  this.bridge.oncalltool = async (params) => {
1350
- if (this.options.onCallTool) return this.options.onCallTool(params);
1351
- console.log("[MCP App] callServerTool:", params.name, params.arguments);
1352
- return { content: [{
1446
+ let result;
1447
+ if (this.options.onCallTool) result = await this.options.onCallTool(params);
1448
+ else result = { content: [{
1353
1449
  type: "text",
1354
1450
  text: `[Inspector] Tool "${params.name}" called (no handler configured)`
1355
1451
  }] };
1452
+ console.log(`%c[MCP ↓]%c host → app: %ccallServerTool result(${params.name})`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1453
+ return result;
1356
1454
  };
1357
1455
  this.bridge.ondownloadfile = async ({ contents }) => {
1358
1456
  if (this.options.onDownloadFile) this.options.onDownloadFile(contents);
1359
- else console.log("[MCP App] downloadFile:", contents.length, "item(s)");
1360
- return {};
1457
+ const ack = {};
1458
+ console.log(`%c[MCP ↓]%c host → app: %cdownloadFile ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1459
+ return ack;
1460
+ };
1461
+ this.bridge.onrequestteardown = () => {
1462
+ if (this.options.onRequestTeardown) this.options.onRequestTeardown();
1463
+ else console.log("[MCP App] requestTeardown (app requested close)");
1361
1464
  };
1362
1465
  this.bridge.onsandboxready = () => {
1363
1466
  this.options.onSandboxReady?.();
@@ -1367,7 +1470,18 @@ var McpAppHost = class {
1367
1470
  * Connect to an iframe's contentWindow.
1368
1471
  */
1369
1472
  async connectToIframe(contentWindow) {
1473
+ if (this._messageListener) window.removeEventListener("message", this._messageListener);
1370
1474
  this._contentWindow = contentWindow;
1475
+ this._messageListener = (event) => {
1476
+ if (event.source !== contentWindow) return;
1477
+ const data = event.data;
1478
+ if (!data || typeof data !== "object") return;
1479
+ const method = data.method;
1480
+ if (method?.startsWith("sunpeak/") || method === "ui/notifications/sandbox-proxy-ready") return;
1481
+ const label = method ?? (data.id != null ? `response #${data.id}` : "unknown");
1482
+ console.log(`%c[MCP ↑]%c app → host: %c${label}`, "color:#6ee7b7", "color:inherit", "color:#93c5fd", data);
1483
+ };
1484
+ window.addEventListener("message", this._messageListener);
1371
1485
  const transport = new N(contentWindow, contentWindow);
1372
1486
  await this.bridge.connect(transport);
1373
1487
  }
@@ -1402,11 +1516,12 @@ var McpAppHost = class {
1402
1516
  this._fenceCleanup = cleanup;
1403
1517
  window.addEventListener("message", handler);
1404
1518
  try {
1405
- win.postMessage({
1519
+ const fenceMsg = {
1406
1520
  jsonrpc: "2.0",
1407
1521
  method: "sunpeak/fence",
1408
1522
  params: { fenceId: id }
1409
- }, "*");
1523
+ };
1524
+ win.postMessage(fenceMsg, "*");
1410
1525
  } catch {
1411
1526
  cleanup();
1412
1527
  resolve();
@@ -1419,6 +1534,7 @@ var McpAppHost = class {
1419
1534
  * to commit its DOM before firing onDisplayModeReady.
1420
1535
  */
1421
1536
  setHostContext(context) {
1537
+ console.log(`%c[MCP ↓]%c host → app: %csetHostContext`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", context);
1422
1538
  this.bridge.setHostContext(context);
1423
1539
  const currentMode = context.displayMode;
1424
1540
  if (currentMode && currentMode !== this._prevDisplayMode) {
@@ -1435,6 +1551,7 @@ var McpAppHost = class {
1435
1551
  */
1436
1552
  sendToolInput(args) {
1437
1553
  const params = { arguments: args };
1554
+ console.log(`%c[MCP ↓]%c host → app: %csendToolInput`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1438
1555
  if (this._initialized) this.bridge.sendToolInput(params);
1439
1556
  else this._pendingToolInput = params;
1440
1557
  }
@@ -1443,6 +1560,7 @@ var McpAppHost = class {
1443
1560
  * If the app hasn't initialized yet, the result is queued.
1444
1561
  */
1445
1562
  sendToolResult(result) {
1563
+ console.log(`%c[MCP ↓]%c host → app: %csendToolResult`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1446
1564
  if (this._initialized) this.bridge.sendToolResult(result);
1447
1565
  else this._pendingToolResult = result;
1448
1566
  }
@@ -1452,6 +1570,7 @@ var McpAppHost = class {
1452
1570
  */
1453
1571
  sendToolInputPartial(args) {
1454
1572
  const params = { arguments: args };
1573
+ console.log(`%c[MCP ↓]%c host → app: %csendToolInputPartial`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1455
1574
  if (this._initialized) this.bridge.sendToolInputPartial(params);
1456
1575
  }
1457
1576
  /**
@@ -1460,6 +1579,7 @@ var McpAppHost = class {
1460
1579
  */
1461
1580
  sendToolCancelled(reason) {
1462
1581
  const params = reason ? { reason } : {};
1582
+ console.log(`%c[MCP ↓]%c host → app: %csendToolCancelled`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1463
1583
  if (this._initialized) this.bridge.sendToolCancelled(params);
1464
1584
  }
1465
1585
  /**
@@ -1483,6 +1603,10 @@ var McpAppHost = class {
1483
1603
  * Close the connection.
1484
1604
  */
1485
1605
  async close() {
1606
+ if (this._messageListener) {
1607
+ window.removeEventListener("message", this._messageListener);
1608
+ this._messageListener = null;
1609
+ }
1486
1610
  this._fenceCleanup?.();
1487
1611
  this._fenceCleanup = null;
1488
1612
  try {
@@ -1593,7 +1717,7 @@ function generateSandboxProxyHtml(platformScript) {
1593
1717
  <head>
1594
1718
  <meta name="color-scheme" content="${colorScheme}" />
1595
1719
  <style>
1596
- html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; }
1720
+ html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: transparent; }
1597
1721
  iframe { border: none; width: 100%; height: 100%; display: block; }
1598
1722
  </style>
1599
1723
  </head>
@@ -1656,6 +1780,16 @@ iframe { border: none; width: 100%; height: 100%; display: block; }
1656
1780
  return;
1657
1781
  }
1658
1782
 
1783
+ // Sync color-scheme on the inner iframe element when theme changes.
1784
+ // This ensures prefers-color-scheme resolves correctly inside the app.
1785
+ // Important: do NOT set color-scheme on the proxy's own document —
1786
+ // changing it from the initial 'dark' causes Chrome to re-evaluate
1787
+ // the CSS Canvas as opaque white, blocking the host's conversation
1788
+ // background from showing through the transparent proxy.
1789
+ if (data.method === 'ui/notifications/host-context-changed' && data.params && data.params.theme) {
1790
+ if (innerFrame) innerFrame.style.colorScheme = data.params.theme;
1791
+ }
1792
+
1659
1793
  // Forward all other messages to the inner iframe
1660
1794
  if (innerWindow) {
1661
1795
  try { innerWindow.postMessage(data, '*'); } catch(e) { /* detached */ }
@@ -2204,6 +2338,10 @@ function parseUrlParams() {
2204
2338
  const host = params.get("host") ?? void 0;
2205
2339
  const prodResourcesParam = params.get("prodResources");
2206
2340
  const prodResources = prodResourcesParam === "true" ? true : prodResourcesParam === "false" ? false : void 0;
2341
+ const sidebarParam = params.get("sidebar");
2342
+ const sidebar = sidebarParam === "false" ? false : sidebarParam === "true" ? true : void 0;
2343
+ const devOverlayParam = params.get("devOverlay");
2344
+ const devOverlay = devOverlayParam === "false" ? false : devOverlayParam === "true" ? true : void 0;
2207
2345
  const deviceType = params.get("deviceType");
2208
2346
  let platform;
2209
2347
  if (deviceType === "mobile" || deviceType === "tablet") platform = "mobile";
@@ -2236,7 +2374,9 @@ function parseUrlParams() {
2236
2374
  deviceCapabilities,
2237
2375
  safeAreaInsets,
2238
2376
  host: host ?? void 0,
2239
- prodResources
2377
+ prodResources,
2378
+ sidebar,
2379
+ devOverlay
2240
2380
  };
2241
2381
  }
2242
2382
  function useInspectorState({ simulations, defaultHost = "chatgpt" }) {
@@ -2487,7 +2627,9 @@ function useInspectorState({ simulations, defaultHost = "chatgpt" }) {
2487
2627
  permissions: resourceMeta?.permissions,
2488
2628
  prefersBorder: resourceMeta?.prefersBorder ?? false,
2489
2629
  urlTool: urlParams.tool,
2490
- urlProdResources: urlParams.prodResources
2630
+ urlProdResources: urlParams.prodResources,
2631
+ urlSidebar: urlParams.sidebar,
2632
+ urlDevOverlay: urlParams.devOverlay
2491
2633
  };
2492
2634
  }
2493
2635
  //#endregion
@@ -2508,15 +2650,17 @@ function useMcpConnection(initialServerUrl) {
2508
2650
  const [error, setError] = (0, react.useState)();
2509
2651
  const [simulations, setSimulations] = (0, react.useState)();
2510
2652
  const [hasReconnected, setHasReconnected] = (0, react.useState)(false);
2511
- const reconnect = (0, react.useCallback)(async (url) => {
2653
+ const reconnect = (0, react.useCallback)(async (url, auth) => {
2512
2654
  setHasReconnected(true);
2513
2655
  setStatus("connecting");
2514
2656
  setError(void 0);
2515
2657
  try {
2658
+ const body = { url };
2659
+ if (auth && auth.type !== "none") body.auth = auth;
2516
2660
  const res = await fetch("/__sunpeak/connect", {
2517
2661
  method: "POST",
2518
2662
  headers: { "Content-Type": "application/json" },
2519
- body: JSON.stringify({ url })
2663
+ body: JSON.stringify(body)
2520
2664
  });
2521
2665
  if (!res.ok) {
2522
2666
  let message = `Connection failed (${res.status})`;
@@ -2535,6 +2679,12 @@ function useMcpConnection(initialServerUrl) {
2535
2679
  setSimulations(void 0);
2536
2680
  }
2537
2681
  }, []);
2682
+ const setConnected = (0, react.useCallback)((sims) => {
2683
+ setHasReconnected(true);
2684
+ setStatus("connected");
2685
+ setError(void 0);
2686
+ setSimulations(sims);
2687
+ }, []);
2538
2688
  (0, react.useEffect)(() => {
2539
2689
  if (!initialServerUrl) return;
2540
2690
  let cancelled = false;
@@ -2560,7 +2710,8 @@ function useMcpConnection(initialServerUrl) {
2560
2710
  error,
2561
2711
  simulations,
2562
2712
  hasReconnected,
2563
- reconnect
2713
+ reconnect,
2714
+ setConnected
2564
2715
  };
2565
2716
  }
2566
2717
  //#endregion
@@ -3044,22 +3195,146 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3044
3195
  defaultHost
3045
3196
  });
3046
3197
  const [serverUrl, setServerUrl] = react.useState(mcpServerUrl ?? "");
3198
+ const [authType, setAuthType] = react.useState("none");
3199
+ const [bearerToken, setBearerToken] = react.useState("");
3200
+ const [oauthScopes, setOauthScopes] = react.useState("");
3201
+ const [oauthClientId, setOauthClientId] = react.useState("");
3202
+ const [oauthClientSecret, setOauthClientSecret] = react.useState("");
3203
+ const [oauthStatus, setOauthStatus] = react.useState("none");
3204
+ const [oauthError, setOauthError] = react.useState();
3047
3205
  const connection = useMcpConnection(mcpServerUrl || void 0);
3048
3206
  const [prodResources, setProdResources] = react.useState(state.urlProdResources ?? defaultProdResources);
3207
+ const showSidebar = state.urlSidebar !== false;
3208
+ const showDevOverlay = state.urlDevOverlay !== false;
3049
3209
  const [isRunning, setIsRunning] = react.useState(false);
3050
3210
  const [hasRun, setHasRun] = react.useState(false);
3051
3211
  const [showCheck, setShowCheck] = react.useState(false);
3052
3212
  const checkTimerRef = react.useRef(void 0);
3213
+ const oauthCleanupRef = react.useRef(void 0);
3053
3214
  react.useEffect(() => {
3054
3215
  state.setSelectedSimulationName(effectiveSimulationName);
3055
3216
  }, [effectiveSimulationName]);
3217
+ const currentAuthConfig = react.useMemo(() => {
3218
+ if (authType === "bearer" && bearerToken) return {
3219
+ type: "bearer",
3220
+ bearerToken
3221
+ };
3222
+ if (authType === "oauth") return { type: "oauth" };
3223
+ }, [authType, bearerToken]);
3056
3224
  const prevServerUrlRef = react.useRef(serverUrl);
3057
3225
  react.useEffect(() => {
3058
3226
  const urlChanged = serverUrl !== prevServerUrlRef.current;
3059
3227
  prevServerUrlRef.current = serverUrl;
3060
3228
  if (!urlChanged) return;
3061
- if (serverUrl) connection.reconnect(serverUrl);
3062
- }, [serverUrl, connection.reconnect]);
3229
+ if (serverUrl) {
3230
+ setOauthStatus("none");
3231
+ setOauthError(void 0);
3232
+ if (authType === "oauth") return;
3233
+ connection.reconnect(serverUrl, currentAuthConfig);
3234
+ }
3235
+ }, [
3236
+ serverUrl,
3237
+ connection.reconnect,
3238
+ authType,
3239
+ currentAuthConfig
3240
+ ]);
3241
+ const handleStartOAuth = react.useCallback(async () => {
3242
+ if (!serverUrl || demoMode) return;
3243
+ setOauthStatus("authorizing");
3244
+ setOauthError(void 0);
3245
+ const popup = window.open("about:blank", `sunpeak-oauth-${Date.now()}`, "width=600,height=700,popup=yes");
3246
+ try {
3247
+ const res = await fetch("/__sunpeak/oauth/start", {
3248
+ method: "POST",
3249
+ headers: { "Content-Type": "application/json" },
3250
+ body: JSON.stringify({
3251
+ url: serverUrl,
3252
+ scope: oauthScopes || void 0,
3253
+ clientId: oauthClientId || void 0,
3254
+ clientSecret: oauthClientSecret || void 0
3255
+ })
3256
+ });
3257
+ if (!res.ok) {
3258
+ let message = `OAuth start failed (${res.status})`;
3259
+ try {
3260
+ const json = await res.json();
3261
+ if (json.error) message = json.error;
3262
+ } catch {}
3263
+ throw new Error(message);
3264
+ }
3265
+ const data = await res.json();
3266
+ if (data.error) {
3267
+ popup?.close();
3268
+ setOauthError(data.error);
3269
+ setOauthStatus("error");
3270
+ return;
3271
+ }
3272
+ if (data.status === "authorized") {
3273
+ popup?.close();
3274
+ setOauthStatus("authorized");
3275
+ connection.setConnected(data.simulations);
3276
+ return;
3277
+ }
3278
+ if (data.status === "redirect" && data.authUrl) {
3279
+ if (!popup || popup.closed) {
3280
+ setOauthError("Popup was blocked. Allow popups for this site and try again.");
3281
+ setOauthStatus("error");
3282
+ return;
3283
+ }
3284
+ popup.location.href = data.authUrl;
3285
+ let checkClosed;
3286
+ let bc;
3287
+ const cleanup = () => {
3288
+ clearInterval(checkClosed);
3289
+ window.removeEventListener("message", handleMessage);
3290
+ bc?.close();
3291
+ oauthCleanupRef.current = void 0;
3292
+ };
3293
+ oauthCleanupRef.current?.();
3294
+ oauthCleanupRef.current = cleanup;
3295
+ const handleOAuthResult = (result) => {
3296
+ cleanup();
3297
+ if (result.error) {
3298
+ setOauthError(result.errorDescription || result.error);
3299
+ setOauthStatus("error");
3300
+ } else if (result.success) {
3301
+ setOauthStatus("authorized");
3302
+ connection.setConnected(result.simulations);
3303
+ }
3304
+ };
3305
+ const handleMessage = (event) => {
3306
+ if (event.origin !== window.location.origin) return;
3307
+ if (event.data?.type !== "sunpeak-oauth-callback") return;
3308
+ handleOAuthResult(event.data);
3309
+ };
3310
+ window.addEventListener("message", handleMessage);
3311
+ if (typeof BroadcastChannel !== "undefined") {
3312
+ bc = new BroadcastChannel("sunpeak-oauth");
3313
+ bc.onmessage = (event) => {
3314
+ if (event.data?.type !== "sunpeak-oauth-callback") return;
3315
+ handleOAuthResult(event.data);
3316
+ };
3317
+ }
3318
+ checkClosed = setInterval(() => {
3319
+ if (popup?.closed) {
3320
+ cleanup();
3321
+ setOauthStatus((prev) => prev === "authorizing" ? "none" : prev);
3322
+ }
3323
+ }, 500);
3324
+ }
3325
+ } catch (err) {
3326
+ popup?.close();
3327
+ setOauthError(err instanceof Error ? err.message : String(err));
3328
+ setOauthStatus("error");
3329
+ }
3330
+ }, [
3331
+ serverUrl,
3332
+ oauthScopes,
3333
+ oauthClientId,
3334
+ oauthClientSecret,
3335
+ demoMode,
3336
+ connection
3337
+ ]);
3063
3338
  react.useEffect(() => {
3064
3339
  if (connection.simulations) setSimulations(connection.simulations);
3065
3340
  else if (connection.status === "error" && connection.hasReconnected) setSimulations({});
@@ -3091,33 +3366,57 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3091
3366
  react.useEffect(() => {
3092
3367
  setHasRun(false);
3093
3368
  }, [effectiveSimulationName]);
3094
- react.useEffect(() => () => clearTimeout(checkTimerRef.current), []);
3369
+ react.useEffect(() => () => {
3370
+ clearTimeout(checkTimerRef.current);
3371
+ oauthCleanupRef.current?.();
3372
+ }, []);
3095
3373
  const handleRun = react.useCallback(async () => {
3096
3374
  const caller = onCallToolDirect ?? onCallTool;
3097
3375
  const sim = simulations[effectiveSimulationName];
3098
3376
  if (!caller || !sim) return;
3099
3377
  const toolName = sim.tool.name;
3100
3378
  setIsRunning(true);
3379
+ const startTime = performance.now();
3101
3380
  try {
3102
3381
  const result = await caller({
3103
3382
  name: toolName,
3104
3383
  arguments: state.toolInput
3105
3384
  });
3106
- state.setToolResult(result);
3107
- state.setToolResultJson(JSON.stringify(result, null, 2));
3385
+ const clientMs = Math.round((performance.now() - startTime) * 10) / 10;
3386
+ const resultMeta = result?._meta;
3387
+ const serverMs = (resultMeta?._sunpeak)?.requestTimeMs;
3388
+ const durationMs = typeof serverMs === "number" ? serverMs : clientMs;
3389
+ const resultWithTiming = {
3390
+ ...result,
3391
+ _meta: {
3392
+ ...resultMeta,
3393
+ _sunpeak: { requestTimeMs: durationMs }
3394
+ }
3395
+ };
3396
+ state.setToolResult(resultWithTiming);
3397
+ const displayResult = resultMeta?._sunpeak ? (() => {
3398
+ const { _sunpeak: _, ...cleanMeta } = resultMeta;
3399
+ const clean = { ...result };
3400
+ clean._meta = Object.keys(cleanMeta).length > 0 ? cleanMeta : void 0;
3401
+ if (clean._meta === void 0) delete clean._meta;
3402
+ return clean;
3403
+ })() : result;
3404
+ state.setToolResultJson(JSON.stringify(displayResult, null, 2));
3108
3405
  state.setToolResultError("");
3109
3406
  setHasRun(true);
3110
3407
  setShowCheck(true);
3111
3408
  clearTimeout(checkTimerRef.current);
3112
3409
  checkTimerRef.current = setTimeout(() => setShowCheck(false), 2e3);
3113
3410
  } catch (err) {
3411
+ const durationMs = Math.round((performance.now() - startTime) * 10) / 10;
3114
3412
  const message = err instanceof Error ? err.message : String(err);
3115
3413
  state.setToolResult({
3116
3414
  content: [{
3117
3415
  type: "text",
3118
3416
  text: `Error: ${message}`
3119
3417
  }],
3120
- isError: true
3418
+ isError: true,
3419
+ _meta: { _sunpeak: { requestTimeMs: durationMs } }
3121
3420
  });
3122
3421
  state.setToolResultJson(JSON.stringify({
3123
3422
  content: [{
@@ -3146,16 +3445,26 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3146
3445
  const ctx = { ...state.hostContext };
3147
3446
  if (styleVars) ctx.styles = { variables: styleVars };
3148
3447
  if (userAgent) ctx.userAgent = userAgent;
3448
+ if (activeShell?.availableDisplayModes) ctx.availableDisplayModes = activeShell.availableDisplayModes;
3149
3449
  return ctx;
3150
3450
  }, [state.hostContext, activeShell]);
3451
+ const { displayMode, setDisplayMode } = state;
3151
3452
  react.useEffect(() => {
3453
+ const modes = activeShell?.availableDisplayModes;
3454
+ if (modes && !modes.includes(displayMode)) setDisplayMode("inline");
3455
+ }, [
3456
+ activeShell,
3457
+ displayMode,
3458
+ setDisplayMode
3459
+ ]);
3460
+ react.useLayoutEffect(() => {
3152
3461
  const vars = activeShell?.styleVariables;
3153
3462
  if (!vars) return;
3154
3463
  const root = document.documentElement;
3155
3464
  for (const [key, value] of Object.entries(vars)) if (value) root.style.setProperty(key, value);
3156
3465
  }, [activeShell]);
3157
3466
  const prevPageStyleKeysRef = react.useRef([]);
3158
- react.useEffect(() => {
3467
+ react.useLayoutEffect(() => {
3159
3468
  const root = document.documentElement;
3160
3469
  for (const key of prevPageStyleKeysRef.current) root.style.removeProperty(key);
3161
3470
  const pageStyles = activeShell?.pageStyles;
@@ -3168,6 +3477,22 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3168
3477
  prevPageStyleKeysRef.current = keys;
3169
3478
  } else prevPageStyleKeysRef.current = [];
3170
3479
  }, [activeShell]);
3480
+ react.useLayoutEffect(() => {
3481
+ const fontCss = activeShell?.fontCss;
3482
+ const id = "sunpeak-host-fonts";
3483
+ const existing = document.getElementById(id);
3484
+ if (!fontCss) {
3485
+ existing?.remove();
3486
+ return;
3487
+ }
3488
+ if (existing) existing.textContent = fontCss;
3489
+ else {
3490
+ const style = document.createElement("style");
3491
+ style.id = id;
3492
+ style.textContent = fontCss;
3493
+ document.head.appendChild(style);
3494
+ }
3495
+ }, [activeShell]);
3171
3496
  const handleCallTool = react.useCallback((params) => {
3172
3497
  if (activeSimulationName) {
3173
3498
  const mock = simulations[activeSimulationName]?.serverTools?.[params.name];
@@ -3226,7 +3551,8 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3226
3551
  clearTimeout(timer);
3227
3552
  };
3228
3553
  }, [prodResourcesPath]);
3229
- const effectiveResourceUrl = (prodResourcesPath && prodResourcesReady ? prodResourcesPath : void 0) ?? state.resourceUrl;
3554
+ const baseResourceUrl = (prodResourcesPath && prodResourcesReady ? prodResourcesPath : void 0) ?? state.resourceUrl;
3555
+ const effectiveResourceUrl = baseResourceUrl && !showDevOverlay ? `${baseResourceUrl}${baseResourceUrl.includes("?") ? "&" : "?"}devOverlay=false` : baseResourceUrl;
3230
3556
  const prodResourcesLoading = !!prodResourcesPath && !prodResourcesReady;
3231
3557
  const hasTools = toolNames.length > 0;
3232
3558
  const showEmptyState = !(activeSimulationName !== null && currentSim?.toolResult != null) && !hasRun;
@@ -3344,6 +3670,26 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3344
3670
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M0 0L10 6L0 12V0Z" })
3345
3671
  }), "Run"]
3346
3672
  }) : void 0;
3673
+ const conversationContent = ShellConversation ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShellConversation, {
3674
+ screenWidth: state.screenWidth,
3675
+ displayMode: state.displayMode,
3676
+ platform: state.platform,
3677
+ onRequestDisplayMode: state.handleDisplayModeChange,
3678
+ appName,
3679
+ appIcon,
3680
+ userMessage,
3681
+ onContentWidthChange: state.handleContentWidthChange,
3682
+ headerAction: runButton,
3683
+ children: content
3684
+ }) : content;
3685
+ if (!showSidebar) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeProvider, {
3686
+ theme: state.theme,
3687
+ applyTheme,
3688
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3689
+ className: "flex h-screen w-screen",
3690
+ children: conversationContent
3691
+ })
3692
+ });
3347
3693
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeProvider, {
3348
3694
  theme: state.theme,
3349
3695
  applyTheme,
@@ -3371,6 +3717,92 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3371
3717
  disabled: demoMode
3372
3718
  })
3373
3719
  }),
3720
+ !demoMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCollapsibleControl, {
3721
+ label: "Authentication",
3722
+ defaultCollapsed: authType === "none",
3723
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3724
+ className: "space-y-1",
3725
+ children: [
3726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarSelect, {
3727
+ value: authType,
3728
+ onChange: (value) => {
3729
+ const newType = value;
3730
+ setAuthType(newType);
3731
+ setOauthStatus("none");
3732
+ setOauthError(void 0);
3733
+ if (newType === "none" && serverUrl) connection.reconnect(serverUrl);
3734
+ },
3735
+ options: [
3736
+ {
3737
+ value: "none",
3738
+ label: "None"
3739
+ },
3740
+ {
3741
+ value: "bearer",
3742
+ label: "Bearer Token"
3743
+ },
3744
+ {
3745
+ value: "oauth",
3746
+ label: "OAuth"
3747
+ }
3748
+ ]
3749
+ }),
3750
+ authType === "bearer" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarInput, {
3751
+ type: "password",
3752
+ value: bearerToken,
3753
+ onChange: (value) => {
3754
+ setBearerToken(value);
3755
+ if (serverUrl && value) connection.reconnect(serverUrl, {
3756
+ type: "bearer",
3757
+ bearerToken: value
3758
+ });
3759
+ },
3760
+ applyOnBlur: true,
3761
+ placeholder: "Paste your token"
3762
+ }),
3763
+ authType === "oauth" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3764
+ className: "space-y-1",
3765
+ children: [
3766
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarInput, {
3767
+ value: oauthClientId,
3768
+ onChange: setOauthClientId,
3769
+ applyOnBlur: true,
3770
+ placeholder: "Client ID (optional)"
3771
+ }),
3772
+ oauthClientId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarInput, {
3773
+ type: "password",
3774
+ value: oauthClientSecret,
3775
+ onChange: setOauthClientSecret,
3776
+ applyOnBlur: true,
3777
+ placeholder: "Client Secret (optional)"
3778
+ }),
3779
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarInput, {
3780
+ value: oauthScopes,
3781
+ onChange: setOauthScopes,
3782
+ applyOnBlur: true,
3783
+ placeholder: "Scopes (optional)"
3784
+ }),
3785
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3786
+ type: "button",
3787
+ onClick: handleStartOAuth,
3788
+ disabled: !serverUrl || oauthStatus === "authorizing",
3789
+ className: "w-full h-7 text-xs rounded-md px-2 transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed",
3790
+ style: {
3791
+ backgroundColor: oauthStatus === "authorized" ? "#22c55e" : "var(--color-text-primary)",
3792
+ color: "var(--color-background-primary)"
3793
+ },
3794
+ children: oauthStatus === "authorizing" ? "Authorizing…" : oauthStatus === "authorized" ? "Authorized" : "Authorize"
3795
+ }),
3796
+ oauthError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3797
+ className: "text-[9px]",
3798
+ style: { color: "var(--color-text-danger, #dc2626)" },
3799
+ children: oauthError
3800
+ })
3801
+ ]
3802
+ })
3803
+ ]
3804
+ })
3805
+ }, `auth-${authType === "none" ? "none" : "active"}`),
3374
3806
  !hideInspectorModes && !demoMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarCheckbox, {
3375
3807
  checked: prodResources,
3376
3808
  onChange: setProdResources,
@@ -3526,7 +3958,7 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3526
3958
  value: "fullscreen",
3527
3959
  label: "Full"
3528
3960
  }
3529
- ]
3961
+ ].filter((opt) => !activeShell?.availableDisplayModes || activeShell.availableDisplayModes.includes(opt.value))
3530
3962
  })
3531
3963
  }),
3532
3964
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -3790,18 +4222,7 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3790
4222
  })
3791
4223
  ]
3792
4224
  }),
3793
- children: ShellConversation ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShellConversation, {
3794
- screenWidth: state.screenWidth,
3795
- displayMode: state.displayMode,
3796
- platform: state.platform,
3797
- onRequestDisplayMode: state.handleDisplayModeChange,
3798
- appName,
3799
- appIcon,
3800
- userMessage,
3801
- onContentWidthChange: state.handleContentWidthChange,
3802
- headerAction: runButton,
3803
- children: content
3804
- }) : content
4225
+ children: conversationContent
3805
4226
  })
3806
4227
  });
3807
4228
  }
@@ -3939,4 +4360,4 @@ Object.defineProperty(exports, "useThemeContext", {
3939
4360
  }
3940
4361
  });
3941
4362
 
3942
- //# sourceMappingURL=inspector-CByJjmPD.cjs.map
4363
+ //# sourceMappingURL=inspector-CKc58UuI.cjs.map