sunpeak 0.10.6 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +44 -19
  2. package/bin/commands/dev.mjs +173 -12
  3. package/bin/sunpeak.js +3 -11
  4. package/dist/chatgpt/index.cjs +1 -1
  5. package/dist/chatgpt/index.js +1 -1
  6. package/dist/index.cjs +1 -1
  7. package/dist/index.js +2 -2
  8. package/dist/mcp/entry.cjs +2 -1
  9. package/dist/mcp/entry.cjs.map +1 -1
  10. package/dist/mcp/entry.js +2 -1
  11. package/dist/mcp/entry.js.map +1 -1
  12. package/dist/mcp/favicon.d.ts +2 -0
  13. package/dist/mcp/index.cjs +3 -1
  14. package/dist/mcp/index.cjs.map +1 -1
  15. package/dist/mcp/index.d.ts +1 -0
  16. package/dist/mcp/index.js +3 -1
  17. package/dist/mcp/types.d.ts +7 -0
  18. package/dist/{server-CnRhUNGQ.js → server-BI9Y531R.js} +153 -29
  19. package/dist/{server-CnRhUNGQ.js.map → server-BI9Y531R.js.map} +1 -1
  20. package/dist/{server-B-T6Y3-J.cjs → server-CcLDAGBE.cjs} +153 -29
  21. package/dist/{server-B-T6Y3-J.cjs.map → server-CcLDAGBE.cjs.map} +1 -1
  22. package/dist/{simulator-url-pSDp_VWO.cjs → simulator-url-CYMOGoB1.cjs} +28 -17
  23. package/dist/simulator-url-CYMOGoB1.cjs.map +1 -0
  24. package/dist/{simulator-url-BUKX-wRa.js → simulator-url-DG79-dU3.js} +27 -16
  25. package/dist/simulator-url-DG79-dU3.js.map +1 -0
  26. package/package.json +1 -1
  27. package/template/README.md +6 -7
  28. package/template/_gitignore +4 -0
  29. package/template/dist/albums/albums.js +4 -4
  30. package/template/dist/albums/albums.json +1 -1
  31. package/template/dist/carousel/carousel.js +3 -3
  32. package/template/dist/carousel/carousel.json +1 -1
  33. package/template/dist/map/map.js +8 -8
  34. package/template/dist/map/map.json +1 -1
  35. package/template/dist/review/review.js +3 -3
  36. package/template/dist/review/review.json +1 -1
  37. package/template/index.html +0 -1
  38. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +7 -7
  39. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +1 -1
  40. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +7 -7
  41. package/template/node_modules/.vite/deps/_metadata.json +34 -34
  42. package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  43. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Avatar.js +96 -0
  44. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Avatar.js.map +7 -0
  45. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Button.js +625 -0
  46. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Button.js.map +7 -0
  47. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Checkbox.js +33 -0
  48. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Checkbox.js.map +7 -0
  49. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Icon.js +1498 -0
  50. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Icon.js.map +7 -0
  51. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Input.js +13 -0
  52. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Input.js.map +7 -0
  53. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_SegmentedControl.js +103 -0
  54. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_SegmentedControl.js.map +7 -0
  55. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Select.js +3680 -0
  56. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Select.js.map +7 -0
  57. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Textarea.js +95 -0
  58. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_components_Textarea.js.map +7 -0
  59. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_theme.js +45 -0
  60. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/@openai_apps-sdk-ui_theme.js.map +7 -0
  61. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-2UDYPUBJ.js +15201 -0
  62. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-2UDYPUBJ.js.map +7 -0
  63. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-6QVG4F2X.js +93 -0
  64. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-6QVG4F2X.js.map +7 -0
  65. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-BUOVMFCD.js +1004 -0
  66. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-BUOVMFCD.js.map +7 -0
  67. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-CNYJBM5F.js +21 -0
  68. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-CNYJBM5F.js.map +7 -0
  69. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-EGRHWZRV.js +1 -0
  70. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-EGRHWZRV.js.map +7 -0
  71. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-ILHRZGIS.js +46 -0
  72. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-ILHRZGIS.js.map +7 -0
  73. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-JAGHY6H6.js +231 -0
  74. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-JAGHY6H6.js.map +7 -0
  75. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-JGVISENQ.js +292 -0
  76. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-JGVISENQ.js.map +7 -0
  77. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-P5LK4A7U.js +112 -0
  78. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-P5LK4A7U.js.map +7 -0
  79. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-QPJAV452.js +13 -0
  80. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-QPJAV452.js.map +7 -0
  81. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-RYYR2YMB.js +111 -0
  82. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-RYYR2YMB.js.map +7 -0
  83. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-UM3ZGDFR.js +4480 -0
  84. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-UM3ZGDFR.js.map +7 -0
  85. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-XZTIOEPG.js +280 -0
  86. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/chunk-XZTIOEPG.js.map +7 -0
  87. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/clsx.js +10 -0
  88. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/clsx.js.map +7 -0
  89. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/embla-carousel-react.js +1712 -0
  90. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/embla-carousel-react.js.map +7 -0
  91. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/embla-carousel-wheel-gestures.js +589 -0
  92. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/embla-carousel-wheel-gestures.js.map +7 -0
  93. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/mapbox-gl.js +32835 -0
  94. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/mapbox-gl.js.map +7 -0
  95. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/package.json +3 -0
  96. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react-dom.js +7 -0
  97. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react-dom.js.map +7 -0
  98. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react-dom_client.js +20217 -0
  99. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react-dom_client.js.map +7 -0
  100. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react.js +6 -0
  101. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react.js.map +7 -0
  102. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react_jsx-dev-runtime.js +278 -0
  103. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react_jsx-dev-runtime.js.map +7 -0
  104. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react_jsx-runtime.js +7 -0
  105. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/react_jsx-runtime.js.map +7 -0
  106. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/tailwind-merge.js +3095 -0
  107. package/template/node_modules/.vite-mcp/deps_temp_c8c8077a/tailwind-merge.js.map +7 -0
  108. package/template/package.json +0 -1
  109. package/bin/commands/mcp.mjs +0 -77
  110. package/dist/simulator-url-BUKX-wRa.js.map +0 -1
  111. package/dist/simulator-url-pSDp_VWO.cjs.map +0 -1
  112. package/template/public/favicon.ico +0 -0
@@ -6,6 +6,8 @@ const path = require("node:path");
6
6
  const index_js = require("@modelcontextprotocol/sdk/server/index.js");
7
7
  const sse_js = require("@modelcontextprotocol/sdk/server/sse.js");
8
8
  const zod = require("zod");
9
+ const FAVICON_BASE64 = "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";
10
+ const FAVICON_BUFFER = Buffer.from(FAVICON_BASE64, "base64");
9
11
  function $constructor(name, initializer2, params) {
10
12
  function init(inst, def) {
11
13
  var _a;
@@ -4821,7 +4823,7 @@ union([
4821
4823
  ListTasksResultSchema,
4822
4824
  CreateTaskResultSchema
4823
4825
  ]);
4824
- function readResourceHtml(distPath) {
4826
+ function readResourceHtmlProd(distPath) {
4825
4827
  const htmlPath = path.resolve(distPath);
4826
4828
  if (!fs.existsSync(htmlPath)) {
4827
4829
  throw new Error(
@@ -4843,12 +4845,75 @@ ${jsContents}
4843
4845
  </body>
4844
4846
  </html>`;
4845
4847
  }
4846
- function createAppServer(config2) {
4847
- const { name = "sunpeak-app", version: version2 = "0.1.0", simulations } = config2;
4848
+ function getViteResourceHtml(srcPath) {
4849
+ const fileName = srcPath.split("/").pop()?.replace(/-resource\.tsx$/, "") ?? "";
4850
+ const componentName = fileName.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("") + "Resource";
4851
+ const devServerUrl = "http://localhost:6766";
4852
+ const entryParams = new URLSearchParams({ src: srcPath, component: componentName });
4853
+ const virtualModuleUrl = `${devServerUrl}/@id/virtual:sunpeak-entry?${entryParams.toString()}`;
4854
+ return `<!DOCTYPE html>
4855
+ <html>
4856
+ <head>
4857
+ <meta charset="UTF-8">
4858
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4859
+ </head>
4860
+ <body>
4861
+ <script type="module">
4862
+ import { injectIntoGlobalHook } from "${devServerUrl}/@react-refresh";
4863
+ injectIntoGlobalHook(window);
4864
+ window.$RefreshReg$ = () => {};
4865
+ window.$RefreshSig$ = () => (type) => type;
4866
+ window.__vite_plugin_react_preamble_installed__ = true;
4867
+ <\/script>
4868
+ <script type="module" src="${devServerUrl}/@vite/client"><\/script>
4869
+ <script type="module">
4870
+ (async () => {
4871
+ if (!navigator.permissions?.query) return;
4872
+ const protocol = window.location.protocol;
4873
+ if (protocol !== 'http:' && protocol !== 'https:') return;
4874
+ const host = window.location.hostname;
4875
+ const isLoopback = host === 'localhost' || /^127\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.test(host) || host === '::1';
4876
+ if (isLoopback) return;
4877
+ try {
4878
+ const status = await navigator.permissions.query({ name: "local-network-access" });
4879
+ if (status.state === "denied") {
4880
+ document.getElementById('root').innerHTML = '<div style="background:#fef2f2;border:2px solid #ef4444;border-radius:8px;padding:16px;text-align:center;font-family:system-ui,sans-serif;"><div style="color:#ef4444;font-size:18px;font-weight:600;margin-bottom:8px;">Local network access permission is denied</div><div style="color:#ef4444;font-size:14px;">Please enable it in your browser settings. <a href="https://developer.chrome.com/blog/local-network-access" target="_blank" style="color:#ef4444;text-decoration:underline;">Learn more</a></div></div>';
4881
+ }
4882
+ } catch (e) {}
4883
+ })();
4884
+ <\/script>
4885
+ <div id="root"></div>
4886
+ <script type="module" src="${virtualModuleUrl}"><\/script>
4887
+ </body>
4888
+ </html>`;
4889
+ }
4890
+ function getResourceHtml(simulation, viteMode) {
4891
+ if (viteMode && simulation.srcPath) {
4892
+ return getViteResourceHtml(simulation.srcPath);
4893
+ }
4894
+ return readResourceHtmlProd(simulation.distPath);
4895
+ }
4896
+ const DEV_SERVER_URL = "http://localhost:6766";
4897
+ const HMR_WS_URL = "ws://localhost:24678";
4898
+ function injectViteCSP(existingMeta) {
4899
+ const meta = existingMeta ?? {};
4900
+ const widgetCSP = meta["openai/widgetCSP"] ?? {};
4901
+ const existingResourceDomains = widgetCSP["resource_domains"] ?? [];
4902
+ const resourceDomains = existingResourceDomains.includes(DEV_SERVER_URL) ? existingResourceDomains : [...existingResourceDomains, DEV_SERVER_URL];
4903
+ const existingConnectDomains = widgetCSP["connect_domains"] ?? [];
4904
+ const connectDomains = existingConnectDomains.includes(HMR_WS_URL) ? existingConnectDomains : [...existingConnectDomains, HMR_WS_URL];
4905
+ return {
4906
+ ...meta,
4907
+ "openai/widgetCSP": {
4908
+ ...widgetCSP,
4909
+ resource_domains: resourceDomains,
4910
+ connect_domains: connectDomains
4911
+ }
4912
+ };
4913
+ }
4914
+ function createAppServer(config2, simulations, viteMode) {
4915
+ const { name = "sunpeak-app", version: version2 = "0.1.0" } = config2;
4848
4916
  const toolInputParser = zod.z.object({});
4849
- const resourceContentMap = new Map(
4850
- simulations.map((simulation) => [simulation.tool.name, readResourceHtml(simulation.distPath)])
4851
- );
4852
4917
  const devTimestamp = Date.now().toString(36);
4853
4918
  const resources = simulations.map((simulation) => {
4854
4919
  const resource = simulation.resource;
@@ -4872,11 +4937,13 @@ function createAppServer(config2) {
4872
4937
  simulation.callToolResult ?? { structuredContent: null, _meta: {} }
4873
4938
  ])
4874
4939
  );
4875
- const resourceMap = new Map(
4940
+ const uriToSimulation = new Map(
4941
+ resources.map((resource, index) => [resource.uri, simulations[index]])
4942
+ );
4943
+ const resourceMetaMap = new Map(
4876
4944
  resources.map((resource, index) => [
4877
4945
  resource.uri,
4878
4946
  {
4879
- content: resourceContentMap.get(simulations[index].tool.name),
4880
4947
  resource,
4881
4948
  _meta: simulations[index].resource._meta
4882
4949
  }
@@ -4895,24 +4962,35 @@ function createAppServer(config2) {
4895
4962
  }
4896
4963
  );
4897
4964
  server.setRequestHandler(ListResourcesRequestSchema, async (_request) => {
4898
- console.log(`[MCP] ListResources → ${resources.length} resource(s)`);
4965
+ console.log(
4966
+ `[MCP] ListResources → ${resources.length} resource(s)${viteMode ? " (vite mode)" : ""}`
4967
+ );
4968
+ if (viteMode) {
4969
+ const resourcesWithCsp = resources.map((resource) => ({
4970
+ ...resource,
4971
+ _meta: injectViteCSP(resource._meta)
4972
+ }));
4973
+ return { resources: resourcesWithCsp };
4974
+ }
4899
4975
  return { resources };
4900
4976
  });
4901
4977
  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
4902
4978
  const requestedUri = request.params.uri;
4903
- const resourceData = resourceMap.get(requestedUri);
4904
- if (!resourceData) {
4979
+ const simulation = uriToSimulation.get(requestedUri);
4980
+ const meta = resourceMetaMap.get(requestedUri);
4981
+ if (!simulation || !meta) {
4905
4982
  throw new Error(`Unknown resource: ${requestedUri}`);
4906
4983
  }
4907
- const sizeKB = (resourceData.content.length / 1024).toFixed(1);
4908
- console.log(`[MCP] ReadResource: ${requestedUri} ${sizeKB}KB`);
4984
+ const content = getResourceHtml(simulation, viteMode);
4985
+ const sizeKB = (content.length / 1024).toFixed(1);
4986
+ console.log(`[MCP] ReadResource: ${requestedUri} → ${sizeKB}KB${viteMode ? " (vite)" : ""}`);
4909
4987
  return {
4910
4988
  contents: [
4911
4989
  {
4912
- uri: resourceData.resource.uri,
4913
- mimeType: resourceData.resource.mimeType,
4914
- text: resourceData.content,
4915
- _meta: resourceData._meta
4990
+ uri: meta.resource.uri,
4991
+ mimeType: meta.resource.mimeType,
4992
+ text: content,
4993
+ _meta: viteMode ? injectViteCSP(meta._meta) : meta._meta
4916
4994
  }
4917
4995
  ]
4918
4996
  };
@@ -4951,9 +5029,9 @@ function createAppServer(config2) {
4951
5029
  const sessions = /* @__PURE__ */ new Map();
4952
5030
  const ssePath = "/mcp";
4953
5031
  const postPath = "/mcp/messages";
4954
- async function handleSseRequest(res, config2) {
5032
+ async function handleSseRequest(res, config2, simulations, viteMode) {
4955
5033
  res.setHeader("Access-Control-Allow-Origin", "*");
4956
- const server = createAppServer(config2);
5034
+ const server = createAppServer(config2, simulations, viteMode);
4957
5035
  const transport = new sse_js.SSEServerTransport(postPath, res);
4958
5036
  const sessionId = transport.sessionId;
4959
5037
  sessions.set(sessionId, { server, transport });
@@ -4979,7 +5057,7 @@ async function handleSseRequest(res, config2) {
4979
5057
  }
4980
5058
  async function handlePostMessage(req, res, url) {
4981
5059
  res.setHeader("Access-Control-Allow-Origin", "*");
4982
- res.setHeader("Access-Control-Allow-Headers", "content-type");
5060
+ res.setHeader("Access-Control-Allow-Headers", "content-type, ngrok-skip-browser-warning");
4983
5061
  const sessionId = url.searchParams.get("sessionId");
4984
5062
  if (!sessionId) {
4985
5063
  res.writeHead(400).end("Missing sessionId query parameter");
@@ -5002,32 +5080,74 @@ async function handlePostMessage(req, res, url) {
5002
5080
  function runMCPServer(config2) {
5003
5081
  const portEnv = Number(process.env.PORT ?? 6766);
5004
5082
  const port = config2.port ?? (Number.isFinite(portEnv) ? portEnv : 6766);
5083
+ const { simulations } = config2;
5084
+ const viteServer = config2.viteServer;
5085
+ const viteMode = !!viteServer;
5005
5086
  const httpServer = node_http.createServer(async (req, res) => {
5006
5087
  if (!req.url) {
5007
5088
  res.writeHead(400).end("Missing URL");
5008
5089
  return;
5009
5090
  }
5010
5091
  const url = new node_url.URL(req.url, `http://${req.headers.host ?? "localhost"}`);
5011
- console.log(`[HTTP] ${req.method} ${url.pathname}`);
5012
- if (req.method === "OPTIONS" && (url.pathname === ssePath || url.pathname === postPath)) {
5092
+ if (req.method === "OPTIONS") {
5013
5093
  res.writeHead(204, {
5014
5094
  "Access-Control-Allow-Origin": "*",
5015
5095
  "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
5016
- "Access-Control-Allow-Headers": "content-type"
5096
+ "Access-Control-Allow-Headers": "content-type, ngrok-skip-browser-warning"
5017
5097
  });
5018
5098
  res.end();
5019
5099
  return;
5020
5100
  }
5101
+ if (req.method === "GET" && url.pathname === "/") {
5102
+ res.writeHead(200, {
5103
+ "Content-Type": "text/html",
5104
+ "Access-Control-Allow-Origin": "*"
5105
+ });
5106
+ res.end(`<!DOCTYPE html>
5107
+ <html>
5108
+ <head>
5109
+ <meta charset="UTF-8" />
5110
+ <link rel="icon" type="image/png" href="/favicon.ico" />
5111
+ <title>Sunpeak MCP Server</title>
5112
+ </head>
5113
+ <body><h1>Sunpeak MCP Server</h1><p>Connect via <a href="/mcp">/mcp</a></p></body>
5114
+ </html>`);
5115
+ return;
5116
+ }
5117
+ if (req.method === "GET" && url.pathname === "/favicon.ico") {
5118
+ res.writeHead(200, {
5119
+ "Content-Type": "image/png",
5120
+ "Content-Length": FAVICON_BUFFER.length,
5121
+ "Cache-Control": "public, max-age=86400",
5122
+ "Access-Control-Allow-Origin": "*"
5123
+ });
5124
+ res.end(FAVICON_BUFFER);
5125
+ return;
5126
+ }
5021
5127
  if (req.method === "GET" && url.pathname === ssePath) {
5022
- await handleSseRequest(res, config2);
5128
+ console.log(`[HTTP] ${req.method} ${url.pathname}`);
5129
+ await handleSseRequest(res, config2, simulations, viteMode);
5023
5130
  return;
5024
5131
  }
5025
5132
  if (req.method === "POST" && url.pathname === postPath) {
5133
+ console.log(`[HTTP] ${req.method} ${url.pathname}`);
5026
5134
  await handlePostMessage(req, res, url);
5027
5135
  return;
5028
5136
  }
5137
+ if (viteServer) {
5138
+ res.setHeader("Access-Control-Allow-Origin", "*");
5139
+ res.setHeader("Access-Control-Allow-Headers", "content-type, ngrok-skip-browser-warning");
5140
+ viteServer.middlewares(req, res);
5141
+ return;
5142
+ }
5143
+ console.log(`[HTTP] ${req.method} ${url.pathname} → 404`);
5029
5144
  res.writeHead(404).end("Not Found");
5030
5145
  });
5146
+ if (viteServer) {
5147
+ httpServer.on("upgrade", (request, socket, head) => {
5148
+ viteServer.ws.handleUpgrade(request, socket, head);
5149
+ });
5150
+ }
5031
5151
  httpServer.on("clientError", (err, socket) => {
5032
5152
  console.error("HTTP client error", err);
5033
5153
  socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
@@ -5035,9 +5155,11 @@ function runMCPServer(config2) {
5035
5155
  httpServer.listen(port, () => {
5036
5156
  console.log(`Sunpeak MCP server listening on http://localhost:${port}`);
5037
5157
  console.log(` SSE stream: GET http://localhost:${port}${ssePath}`);
5038
- console.log(` Message post endpoint: POST http://localhost:${port}${postPath}?sessionId=...`);
5158
+ if (viteMode) {
5159
+ console.log(` Vite HMR: enabled (source files served with hot reload)`);
5160
+ }
5039
5161
  });
5040
- const shutdown = () => {
5162
+ const shutdown = async () => {
5041
5163
  console.log("\nShutting down MCP server...");
5042
5164
  httpServer.close(() => {
5043
5165
  console.log("MCP server closed");
@@ -5048,8 +5170,10 @@ function runMCPServer(config2) {
5048
5170
  process.exit(1);
5049
5171
  }, 5e3);
5050
5172
  };
5051
- process.on("SIGTERM", shutdown);
5052
- process.on("SIGINT", shutdown);
5173
+ process.on("SIGTERM", () => void shutdown());
5174
+ process.on("SIGINT", () => void shutdown());
5053
5175
  }
5176
+ exports.FAVICON_BASE64 = FAVICON_BASE64;
5177
+ exports.FAVICON_BUFFER = FAVICON_BUFFER;
5054
5178
  exports.runMCPServer = runMCPServer;
5055
- //# sourceMappingURL=server-B-T6Y3-J.cjs.map
5179
+ //# sourceMappingURL=server-CcLDAGBE.cjs.map