sunpeak 0.19.12 → 0.20.2

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 (85) hide show
  1. package/README.md +2 -2
  2. package/bin/commands/inspect.mjs +361 -12
  3. package/bin/commands/test-init.mjs +190 -118
  4. package/bin/commands/test.mjs +12 -1
  5. package/bin/lib/eval/eval-runner.mjs +7 -1
  6. package/bin/lib/inspect/inspect-config.mjs +17 -2
  7. package/bin/lib/inspect/inspect-server.d.mts +32 -0
  8. package/bin/lib/inspect/inspect-server.mjs +11 -0
  9. package/bin/lib/live/live-config.d.mts +10 -0
  10. package/bin/lib/live/live-config.mjs +34 -2
  11. package/bin/lib/resolve-bin.mjs +39 -0
  12. package/bin/lib/test/base-config.mjs +6 -3
  13. package/bin/lib/test/matchers.mjs +2 -2
  14. package/bin/lib/test/test-config.mjs +19 -8
  15. package/bin/lib/test/test-fixtures.d.mts +52 -92
  16. package/bin/lib/test/test-fixtures.mjs +174 -147
  17. package/dist/chatgpt/index.cjs +1 -1
  18. package/dist/chatgpt/index.js +1 -1
  19. package/dist/claude/index.cjs +1 -1
  20. package/dist/claude/index.js +1 -1
  21. package/dist/host/chatgpt/index.cjs +1 -1
  22. package/dist/host/chatgpt/index.js +1 -1
  23. package/dist/index.cjs +4 -4
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.js +3 -3
  26. package/dist/index.js.map +1 -1
  27. package/dist/inspector/index.cjs +1 -1
  28. package/dist/inspector/index.js +1 -1
  29. package/dist/{inspector-D5DckQuU.js → inspector-BBDa5yCm.js} +57 -23
  30. package/dist/inspector-BBDa5yCm.js.map +1 -0
  31. package/dist/{inspector-jY9O18z9.cjs → inspector-DAA1Wiyh.cjs} +58 -24
  32. package/dist/inspector-DAA1Wiyh.cjs.map +1 -0
  33. package/dist/lib/discovery-cli.cjs +1 -1
  34. package/dist/mcp/index.cjs +22 -25
  35. package/dist/mcp/index.cjs.map +1 -1
  36. package/dist/mcp/index.js +19 -22
  37. package/dist/mcp/index.js.map +1 -1
  38. package/dist/{use-app-Bfargfa3.js → use-app-Cr0auUa1.js} +2 -2
  39. package/dist/{use-app-Bfargfa3.js.map → use-app-Cr0auUa1.js.map} +1 -1
  40. package/dist/{use-app-CbsBEmwv.cjs → use-app-DPkj5Jp_.cjs} +2 -2
  41. package/dist/{use-app-CbsBEmwv.cjs.map → use-app-DPkj5Jp_.cjs.map} +1 -1
  42. package/package.json +17 -11
  43. package/template/dist/albums/albums.html +4 -4
  44. package/template/dist/albums/albums.json +1 -1
  45. package/template/dist/carousel/carousel.html +4 -4
  46. package/template/dist/carousel/carousel.json +1 -1
  47. package/template/dist/map/map.html +6 -6
  48. package/template/dist/map/map.json +1 -1
  49. package/template/dist/review/review.html +4 -4
  50. package/template/dist/review/review.json +1 -1
  51. package/template/node_modules/.bin/vite +2 -2
  52. package/template/node_modules/.bin/vitest +2 -2
  53. package/template/node_modules/.vite/deps/_metadata.json +4 -4
  54. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js +1 -1
  55. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps.js.map +1 -1
  56. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js +1 -1
  57. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_app-bridge.js.map +1 -1
  58. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js +1 -1
  59. package/template/node_modules/.vite-mcp/deps/@modelcontextprotocol_ext-apps_react.js.map +1 -1
  60. package/template/node_modules/.vite-mcp/deps/@testing-library_react.js +4 -4
  61. package/template/node_modules/.vite-mcp/deps/@testing-library_react.js.map +1 -1
  62. package/template/node_modules/.vite-mcp/deps/_metadata.json +33 -33
  63. package/template/node_modules/.vite-mcp/deps/{client-CU1wWud4.js → client-B_5CX--u.js} +7 -7
  64. package/template/node_modules/.vite-mcp/deps/{client-CU1wWud4.js.map → client-B_5CX--u.js.map} +1 -1
  65. package/template/node_modules/.vite-mcp/deps/embla-carousel-react.js +1 -1
  66. package/template/node_modules/.vite-mcp/deps/embla-carousel-react.js.map +1 -1
  67. package/template/node_modules/.vite-mcp/deps/react-dom.js +3 -3
  68. package/template/node_modules/.vite-mcp/deps/react-dom.js.map +1 -1
  69. package/template/node_modules/.vite-mcp/deps/react-dom_client.js +1 -1
  70. package/template/node_modules/.vite-mcp/deps/react.js +3 -3
  71. package/template/node_modules/.vite-mcp/deps/react.js.map +1 -1
  72. package/template/node_modules/.vite-mcp/deps/react_jsx-dev-runtime.js +2 -2
  73. package/template/node_modules/.vite-mcp/deps/react_jsx-dev-runtime.js.map +1 -1
  74. package/template/node_modules/.vite-mcp/deps/react_jsx-runtime.js +2 -2
  75. package/template/node_modules/.vite-mcp/deps/react_jsx-runtime.js.map +1 -1
  76. package/template/node_modules/.vite-mcp/deps/vitest.js +1024 -622
  77. package/template/node_modules/.vite-mcp/deps/vitest.js.map +1 -1
  78. package/template/package.json +6 -6
  79. package/template/tests/e2e/albums.spec.ts +24 -52
  80. package/template/tests/e2e/carousel.spec.ts +36 -58
  81. package/template/tests/e2e/map.spec.ts +35 -56
  82. package/template/tests/e2e/review.spec.ts +56 -85
  83. package/template/tests/e2e/visual.spec.ts +14 -12
  84. package/dist/inspector-D5DckQuU.js.map +0 -1
  85. package/dist/inspector-jY9O18z9.cjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  const require_chunk = require("./chunk-9hOWP6kD.cjs");
2
2
  const require_protocol = require("./protocol-C8pFDmcy.cjs");
3
3
  let react = require("react");
4
- react = require_chunk.__toESM(react);
4
+ react = require_chunk.__toESM(react, 1);
5
5
  let react_jsx_runtime = require("react/jsx-runtime");
6
6
  //#region src/lib/default-style-variables.ts
7
7
  var DEFAULT_STYLE_VARIABLES = {
@@ -809,7 +809,7 @@ registerHostShell({
809
809
  }`
810
810
  });
811
811
  //#endregion
812
- //#region ../../node_modules/.pnpm/@modelcontextprotocol+ext-apps@1.5.0_@modelcontextprotocol+sdk@1.29.0_zod@4.3.6__react-_f4871531d9cf52c692eb6edc1ee416ef/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js
812
+ //#region ../../node_modules/.pnpm/@modelcontextprotocol+ext-apps@1.5.0_@modelcontextprotocol+sdk@1.29.0_zod@4.3.6__react-_a8a8e071c354e7dd6f62871eadf46f99/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js
813
813
  var j = class extends require_protocol.Protocol {
814
814
  _registeredMethods = /* @__PURE__ */ new Set();
815
815
  _eventSlots = /* @__PURE__ */ new Map();
@@ -1508,6 +1508,11 @@ var DEFAULT_HOST_INFO = {
1508
1508
  name: "SunpeakInspector",
1509
1509
  version: "1.0.0"
1510
1510
  };
1511
+ /**
1512
+ * Debug logger for MCP bridge messages. Uses CSS-formatted console.log in browsers,
1513
+ * no-ops during unit tests (Vitest) where the output is just noise.
1514
+ */
1515
+ var debugLog = typeof process !== "undefined" && process.env?.VITEST ? () => {} : console.log;
1511
1516
  var DEFAULT_HOST_CAPABILITIES = {
1512
1517
  openLinks: {},
1513
1518
  serverTools: {},
@@ -1559,25 +1564,25 @@ var McpAppHost = class {
1559
1564
  console.warn("[MCP App] openLink blocked invalid URL:", url);
1560
1565
  }
1561
1566
  const ack = {};
1562
- console.log(`%c[MCP ↓]%c host → app: %copenLink ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1567
+ debugLog(`%c[MCP ↓]%c host → app: %copenLink ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1563
1568
  return ack;
1564
1569
  };
1565
1570
  this.bridge.onmessage = async ({ role, content }) => {
1566
1571
  if (this.options.onMessage) this.options.onMessage(role, content);
1567
1572
  const ack = {};
1568
- console.log(`%c[MCP ↓]%c host → app: %csendMessage ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1573
+ debugLog(`%c[MCP ↓]%c host → app: %csendMessage ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1569
1574
  return ack;
1570
1575
  };
1571
1576
  this.bridge.onrequestdisplaymode = async ({ mode }) => {
1572
1577
  this.options.onDisplayModeChange?.(mode);
1573
1578
  const result = { mode };
1574
- console.log(`%c[MCP ↓]%c host → app: %crequestDisplayMode result`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1579
+ debugLog(`%c[MCP ↓]%c host → app: %crequestDisplayMode result`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1575
1580
  return result;
1576
1581
  };
1577
1582
  this.bridge.onupdatemodelcontext = async ({ content, structuredContent }) => {
1578
1583
  this.options.onUpdateModelContext?.(content ?? [], structuredContent);
1579
1584
  const ack = {};
1580
- console.log(`%c[MCP ↓]%c host → app: %cupdateModelContext ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1585
+ debugLog(`%c[MCP ↓]%c host → app: %cupdateModelContext ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1581
1586
  return ack;
1582
1587
  };
1583
1588
  this.bridge.onsizechange = (params) => {
@@ -1601,18 +1606,18 @@ var McpAppHost = class {
1601
1606
  type: "text",
1602
1607
  text: `[Inspector] Tool "${params.name}" called (no handler configured)`
1603
1608
  }] };
1604
- console.log(`%c[MCP ↓]%c host → app: %ccallServerTool result(${params.name})`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1609
+ debugLog(`%c[MCP ↓]%c host → app: %ccallServerTool result(${params.name})`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1605
1610
  return result;
1606
1611
  };
1607
1612
  this.bridge.ondownloadfile = async ({ contents }) => {
1608
1613
  if (this.options.onDownloadFile) this.options.onDownloadFile(contents);
1609
1614
  const ack = {};
1610
- console.log(`%c[MCP ↓]%c host → app: %cdownloadFile ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1615
+ debugLog(`%c[MCP ↓]%c host → app: %cdownloadFile ack`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", ack);
1611
1616
  return ack;
1612
1617
  };
1613
1618
  this.bridge.onrequestteardown = () => {
1614
1619
  if (this.options.onRequestTeardown) this.options.onRequestTeardown();
1615
- else console.log("[MCP App] requestTeardown (app requested close)");
1620
+ else debugLog("[MCP App] requestTeardown (app requested close)");
1616
1621
  };
1617
1622
  let sandboxReadyFired = false;
1618
1623
  this.bridge.onsandboxready = () => {
@@ -1633,8 +1638,7 @@ var McpAppHost = class {
1633
1638
  if (!data || typeof data !== "object") return;
1634
1639
  const method = data.method;
1635
1640
  if (method?.startsWith("sunpeak/") || method === "ui/notifications/sandbox-proxy-ready") return;
1636
- const label = method ?? (data.id != null ? `response #${data.id}` : "unknown");
1637
- console.log(`%c[MCP ↑]%c app → host: %c${label}`, "color:#6ee7b7", "color:inherit", "color:#93c5fd", data);
1641
+ debugLog(`%c[MCP ↑]%c app → host: %c${method ?? (data.id != null ? `response #${data.id}` : "unknown")}`, "color:#6ee7b7", "color:inherit", "color:#93c5fd", data);
1638
1642
  };
1639
1643
  window.addEventListener("message", this._messageListener);
1640
1644
  const transport = new z(contentWindow, contentWindow);
@@ -1689,7 +1693,7 @@ var McpAppHost = class {
1689
1693
  * to commit its DOM before firing onDisplayModeReady.
1690
1694
  */
1691
1695
  setHostContext(context) {
1692
- console.log(`%c[MCP ↓]%c host → app: %csetHostContext`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", context);
1696
+ debugLog(`%c[MCP ↓]%c host → app: %csetHostContext`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", context);
1693
1697
  this.bridge.setHostContext(context);
1694
1698
  const currentMode = context.displayMode;
1695
1699
  if (currentMode && currentMode !== this._prevDisplayMode) {
@@ -1706,7 +1710,7 @@ var McpAppHost = class {
1706
1710
  */
1707
1711
  sendToolInput(args) {
1708
1712
  const params = { arguments: args };
1709
- console.log(`%c[MCP ↓]%c host → app: %csendToolInput`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1713
+ debugLog(`%c[MCP ↓]%c host → app: %csendToolInput`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1710
1714
  if (this._initialized) this.bridge.sendToolInput(params);
1711
1715
  else this._pendingToolInput = params;
1712
1716
  }
@@ -1715,7 +1719,7 @@ var McpAppHost = class {
1715
1719
  * If the app hasn't initialized yet, the result is queued.
1716
1720
  */
1717
1721
  sendToolResult(result) {
1718
- console.log(`%c[MCP ↓]%c host → app: %csendToolResult`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1722
+ debugLog(`%c[MCP ↓]%c host → app: %csendToolResult`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", result);
1719
1723
  if (this._initialized) this.bridge.sendToolResult(result);
1720
1724
  else this._pendingToolResult = result;
1721
1725
  }
@@ -1725,7 +1729,7 @@ var McpAppHost = class {
1725
1729
  */
1726
1730
  sendToolInputPartial(args) {
1727
1731
  const params = { arguments: args };
1728
- console.log(`%c[MCP ↓]%c host → app: %csendToolInputPartial`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1732
+ debugLog(`%c[MCP ↓]%c host → app: %csendToolInputPartial`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1729
1733
  if (this._initialized) this.bridge.sendToolInputPartial(params);
1730
1734
  }
1731
1735
  /**
@@ -1734,7 +1738,7 @@ var McpAppHost = class {
1734
1738
  */
1735
1739
  sendToolCancelled(reason) {
1736
1740
  const params = reason ? { reason } : {};
1737
- console.log(`%c[MCP ↓]%c host → app: %csendToolCancelled`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1741
+ debugLog(`%c[MCP ↓]%c host → app: %csendToolCancelled`, "color:#f9a8d4", "color:inherit", "color:#93c5fd", params);
1738
1742
  if (this._initialized) this.bridge.sendToolCancelled(params);
1739
1743
  }
1740
1744
  /**
@@ -2492,6 +2496,8 @@ var DEFAULT_PLATFORM = "desktop";
2492
2496
  * - safeAreaTop, safeAreaBottom, safeAreaLeft, safeAreaRight: number
2493
2497
  * - host: 'chatgpt' | 'claude'
2494
2498
  * - tool: tool name (e.g., 'show-albums') — selects tool without mock data
2499
+ * - toolInput: JSON-encoded tool arguments (overrides simulation fixture data)
2500
+ * - autoRun: 'true' — call the tool on load when no fixture data exists (set by test fixtures)
2495
2501
  * - prodResources: 'true' | 'false'
2496
2502
  */
2497
2503
  function parseUrlParams() {
@@ -2499,6 +2505,11 @@ function parseUrlParams() {
2499
2505
  const params = new URLSearchParams(window.location.search);
2500
2506
  const simulation = params.get("simulation") ?? void 0;
2501
2507
  const tool = params.get("tool") ?? void 0;
2508
+ const toolInputParam = params.get("toolInput");
2509
+ let toolInput;
2510
+ if (toolInputParam) try {
2511
+ toolInput = JSON.parse(toolInputParam);
2512
+ } catch {}
2502
2513
  const theme = params.get("theme");
2503
2514
  const displayMode = params.get("displayMode");
2504
2515
  const locale = params.get("locale");
@@ -2536,6 +2547,7 @@ function parseUrlParams() {
2536
2547
  return {
2537
2548
  simulation,
2538
2549
  tool,
2550
+ toolInput,
2539
2551
  theme: theme ?? void 0,
2540
2552
  displayMode: displayMode ?? void 0,
2541
2553
  locale: locale ?? void 0,
@@ -2655,7 +2667,7 @@ function useInspectorState({ simulations, defaultHost = "chatgpt" }) {
2655
2667
  safeAreaInsets,
2656
2668
  containerDimensions
2657
2669
  ]);
2658
- const [toolInput, setToolInput] = (0, react.useState)(() => selectedSim?.toolInput ?? {});
2670
+ const [toolInput, setToolInput] = (0, react.useState)(() => urlParams.toolInput ?? selectedSim?.toolInput ?? {});
2659
2671
  const [toolResult, setToolResult] = (0, react.useState)(() => selectedSim?.toolResult);
2660
2672
  const [toolInputJson, setToolInputJson] = (0, react.useState)(() => JSON.stringify(toolInput, null, 2));
2661
2673
  const [toolResultJson, setToolResultJson] = (0, react.useState)(() => JSON.stringify(toolResult ?? null, null, 2));
@@ -2666,7 +2678,7 @@ function useInspectorState({ simulations, defaultHost = "chatgpt" }) {
2666
2678
  const [toolResultError, setToolResultError] = (0, react.useState)("");
2667
2679
  const [modelContextError, setModelContextError] = (0, react.useState)("");
2668
2680
  (0, react.useEffect)(() => {
2669
- const newInput = selectedSim?.toolInput ?? {};
2681
+ const newInput = urlParams.toolInput ?? selectedSim?.toolInput ?? {};
2670
2682
  const newResult = selectedSim?.toolResult ?? void 0;
2671
2683
  setToolInput(newInput);
2672
2684
  setToolResult(newResult);
@@ -3342,13 +3354,15 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3342
3354
  if (typeof window === "undefined") return {
3343
3355
  tool: null,
3344
3356
  simulation: null,
3345
- noMockData: false
3357
+ noMockData: false,
3358
+ autoRun: false
3346
3359
  };
3347
3360
  const params = new URLSearchParams(window.location.search);
3348
3361
  return {
3349
3362
  tool: params.get("tool"),
3350
3363
  simulation: params.get("simulation"),
3351
- noMockData: false
3364
+ noMockData: false,
3365
+ autoRun: params.get("autoRun") === "true"
3352
3366
  };
3353
3367
  }, []);
3354
3368
  const [selectedToolName, setSelectedToolName] = react.useState(() => {
@@ -3624,6 +3638,19 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3624
3638
  effectiveSimulationName,
3625
3639
  state
3626
3640
  ]);
3641
+ const autoRunFired = react.useRef(false);
3642
+ react.useEffect(() => {
3643
+ if (initUrlParams.autoRun && !autoRunFired.current && activeSimulationName === null && (onCallTool || onCallToolDirect)) {
3644
+ autoRunFired.current = true;
3645
+ handleRun();
3646
+ }
3647
+ }, [
3648
+ initUrlParams.autoRun,
3649
+ activeSimulationName,
3650
+ onCallTool,
3651
+ onCallToolDirect,
3652
+ handleRun
3653
+ ]);
3627
3654
  const activeShell = getHostShell(state.activeHost);
3628
3655
  const registeredHosts = getRegisteredHosts();
3629
3656
  const ShellConversation = activeShell?.Conversation;
@@ -3878,10 +3905,10 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
3878
3905
  children: conversationContent
3879
3906
  })
3880
3907
  });
3881
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeProvider, {
3908
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ThemeProvider, {
3882
3909
  theme: state.theme,
3883
3910
  applyTheme,
3884
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SimpleSidebar, {
3911
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SimpleSidebar, {
3885
3912
  controls: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3886
3913
  className: "space-y-1",
3887
3914
  children: [
@@ -4411,7 +4438,14 @@ function Inspector({ children, simulations: initialSimulations = {}, appName = "
4411
4438
  ]
4412
4439
  }),
4413
4440
  children: conversationContent
4414
- })
4441
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("script", {
4442
+ type: "application/json",
4443
+ id: "__tool-result",
4444
+ dangerouslySetInnerHTML: { __html: JSON.stringify(state.toolResult ? {
4445
+ ...state.toolResult,
4446
+ source: activeSimulationName ? "fixture" : "server"
4447
+ } : null).replace(/</g, "\\u003c") }
4448
+ })]
4415
4449
  });
4416
4450
  }
4417
4451
  //#endregion
@@ -4548,4 +4582,4 @@ Object.defineProperty(exports, "useThemeContext", {
4548
4582
  }
4549
4583
  });
4550
4584
 
4551
- //# sourceMappingURL=inspector-jY9O18z9.cjs.map
4585
+ //# sourceMappingURL=inspector-DAA1Wiyh.cjs.map