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
@@ -5,6 +5,8 @@ import path from "node:path";
5
5
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
6
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
7
7
  import { z } from "zod";
8
+ const FAVICON_BASE64 = "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";
9
+ const FAVICON_BUFFER = Buffer.from(FAVICON_BASE64, "base64");
8
10
  function $constructor(name, initializer2, params) {
9
11
  function init(inst, def) {
10
12
  var _a;
@@ -4820,7 +4822,7 @@ union([
4820
4822
  ListTasksResultSchema,
4821
4823
  CreateTaskResultSchema
4822
4824
  ]);
4823
- function readResourceHtml(distPath) {
4825
+ function readResourceHtmlProd(distPath) {
4824
4826
  const htmlPath = path.resolve(distPath);
4825
4827
  if (!fs.existsSync(htmlPath)) {
4826
4828
  throw new Error(
@@ -4842,12 +4844,75 @@ ${jsContents}
4842
4844
  </body>
4843
4845
  </html>`;
4844
4846
  }
4845
- function createAppServer(config2) {
4846
- const { name = "sunpeak-app", version: version2 = "0.1.0", simulations } = config2;
4847
+ function getViteResourceHtml(srcPath) {
4848
+ const fileName = srcPath.split("/").pop()?.replace(/-resource\.tsx$/, "") ?? "";
4849
+ const componentName = fileName.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("") + "Resource";
4850
+ const devServerUrl = "http://localhost:6766";
4851
+ const entryParams = new URLSearchParams({ src: srcPath, component: componentName });
4852
+ const virtualModuleUrl = `${devServerUrl}/@id/virtual:sunpeak-entry?${entryParams.toString()}`;
4853
+ return `<!DOCTYPE html>
4854
+ <html>
4855
+ <head>
4856
+ <meta charset="UTF-8">
4857
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4858
+ </head>
4859
+ <body>
4860
+ <script type="module">
4861
+ import { injectIntoGlobalHook } from "${devServerUrl}/@react-refresh";
4862
+ injectIntoGlobalHook(window);
4863
+ window.$RefreshReg$ = () => {};
4864
+ window.$RefreshSig$ = () => (type) => type;
4865
+ window.__vite_plugin_react_preamble_installed__ = true;
4866
+ <\/script>
4867
+ <script type="module" src="${devServerUrl}/@vite/client"><\/script>
4868
+ <script type="module">
4869
+ (async () => {
4870
+ if (!navigator.permissions?.query) return;
4871
+ const protocol = window.location.protocol;
4872
+ if (protocol !== 'http:' && protocol !== 'https:') return;
4873
+ const host = window.location.hostname;
4874
+ const isLoopback = host === 'localhost' || /^127\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.test(host) || host === '::1';
4875
+ if (isLoopback) return;
4876
+ try {
4877
+ const status = await navigator.permissions.query({ name: "local-network-access" });
4878
+ if (status.state === "denied") {
4879
+ 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>';
4880
+ }
4881
+ } catch (e) {}
4882
+ })();
4883
+ <\/script>
4884
+ <div id="root"></div>
4885
+ <script type="module" src="${virtualModuleUrl}"><\/script>
4886
+ </body>
4887
+ </html>`;
4888
+ }
4889
+ function getResourceHtml(simulation, viteMode) {
4890
+ if (viteMode && simulation.srcPath) {
4891
+ return getViteResourceHtml(simulation.srcPath);
4892
+ }
4893
+ return readResourceHtmlProd(simulation.distPath);
4894
+ }
4895
+ const DEV_SERVER_URL = "http://localhost:6766";
4896
+ const HMR_WS_URL = "ws://localhost:24678";
4897
+ function injectViteCSP(existingMeta) {
4898
+ const meta = existingMeta ?? {};
4899
+ const widgetCSP = meta["openai/widgetCSP"] ?? {};
4900
+ const existingResourceDomains = widgetCSP["resource_domains"] ?? [];
4901
+ const resourceDomains = existingResourceDomains.includes(DEV_SERVER_URL) ? existingResourceDomains : [...existingResourceDomains, DEV_SERVER_URL];
4902
+ const existingConnectDomains = widgetCSP["connect_domains"] ?? [];
4903
+ const connectDomains = existingConnectDomains.includes(HMR_WS_URL) ? existingConnectDomains : [...existingConnectDomains, HMR_WS_URL];
4904
+ return {
4905
+ ...meta,
4906
+ "openai/widgetCSP": {
4907
+ ...widgetCSP,
4908
+ resource_domains: resourceDomains,
4909
+ connect_domains: connectDomains
4910
+ }
4911
+ };
4912
+ }
4913
+ function createAppServer(config2, simulations, viteMode) {
4914
+ const { name = "sunpeak-app", version: version2 = "0.1.0" } = config2;
4847
4915
  const toolInputParser = z.object({});
4848
- const resourceContentMap = new Map(
4849
- simulations.map((simulation) => [simulation.tool.name, readResourceHtml(simulation.distPath)])
4850
- );
4851
4916
  const devTimestamp = Date.now().toString(36);
4852
4917
  const resources = simulations.map((simulation) => {
4853
4918
  const resource = simulation.resource;
@@ -4871,11 +4936,13 @@ function createAppServer(config2) {
4871
4936
  simulation.callToolResult ?? { structuredContent: null, _meta: {} }
4872
4937
  ])
4873
4938
  );
4874
- const resourceMap = new Map(
4939
+ const uriToSimulation = new Map(
4940
+ resources.map((resource, index) => [resource.uri, simulations[index]])
4941
+ );
4942
+ const resourceMetaMap = new Map(
4875
4943
  resources.map((resource, index) => [
4876
4944
  resource.uri,
4877
4945
  {
4878
- content: resourceContentMap.get(simulations[index].tool.name),
4879
4946
  resource,
4880
4947
  _meta: simulations[index].resource._meta
4881
4948
  }
@@ -4894,24 +4961,35 @@ function createAppServer(config2) {
4894
4961
  }
4895
4962
  );
4896
4963
  server.setRequestHandler(ListResourcesRequestSchema, async (_request) => {
4897
- console.log(`[MCP] ListResources → ${resources.length} resource(s)`);
4964
+ console.log(
4965
+ `[MCP] ListResources → ${resources.length} resource(s)${viteMode ? " (vite mode)" : ""}`
4966
+ );
4967
+ if (viteMode) {
4968
+ const resourcesWithCsp = resources.map((resource) => ({
4969
+ ...resource,
4970
+ _meta: injectViteCSP(resource._meta)
4971
+ }));
4972
+ return { resources: resourcesWithCsp };
4973
+ }
4898
4974
  return { resources };
4899
4975
  });
4900
4976
  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
4901
4977
  const requestedUri = request.params.uri;
4902
- const resourceData = resourceMap.get(requestedUri);
4903
- if (!resourceData) {
4978
+ const simulation = uriToSimulation.get(requestedUri);
4979
+ const meta = resourceMetaMap.get(requestedUri);
4980
+ if (!simulation || !meta) {
4904
4981
  throw new Error(`Unknown resource: ${requestedUri}`);
4905
4982
  }
4906
- const sizeKB = (resourceData.content.length / 1024).toFixed(1);
4907
- console.log(`[MCP] ReadResource: ${requestedUri} ${sizeKB}KB`);
4983
+ const content = getResourceHtml(simulation, viteMode);
4984
+ const sizeKB = (content.length / 1024).toFixed(1);
4985
+ console.log(`[MCP] ReadResource: ${requestedUri} → ${sizeKB}KB${viteMode ? " (vite)" : ""}`);
4908
4986
  return {
4909
4987
  contents: [
4910
4988
  {
4911
- uri: resourceData.resource.uri,
4912
- mimeType: resourceData.resource.mimeType,
4913
- text: resourceData.content,
4914
- _meta: resourceData._meta
4989
+ uri: meta.resource.uri,
4990
+ mimeType: meta.resource.mimeType,
4991
+ text: content,
4992
+ _meta: viteMode ? injectViteCSP(meta._meta) : meta._meta
4915
4993
  }
4916
4994
  ]
4917
4995
  };
@@ -4950,9 +5028,9 @@ function createAppServer(config2) {
4950
5028
  const sessions = /* @__PURE__ */ new Map();
4951
5029
  const ssePath = "/mcp";
4952
5030
  const postPath = "/mcp/messages";
4953
- async function handleSseRequest(res, config2) {
5031
+ async function handleSseRequest(res, config2, simulations, viteMode) {
4954
5032
  res.setHeader("Access-Control-Allow-Origin", "*");
4955
- const server = createAppServer(config2);
5033
+ const server = createAppServer(config2, simulations, viteMode);
4956
5034
  const transport = new SSEServerTransport(postPath, res);
4957
5035
  const sessionId = transport.sessionId;
4958
5036
  sessions.set(sessionId, { server, transport });
@@ -4978,7 +5056,7 @@ async function handleSseRequest(res, config2) {
4978
5056
  }
4979
5057
  async function handlePostMessage(req, res, url) {
4980
5058
  res.setHeader("Access-Control-Allow-Origin", "*");
4981
- res.setHeader("Access-Control-Allow-Headers", "content-type");
5059
+ res.setHeader("Access-Control-Allow-Headers", "content-type, ngrok-skip-browser-warning");
4982
5060
  const sessionId = url.searchParams.get("sessionId");
4983
5061
  if (!sessionId) {
4984
5062
  res.writeHead(400).end("Missing sessionId query parameter");
@@ -5001,32 +5079,74 @@ async function handlePostMessage(req, res, url) {
5001
5079
  function runMCPServer(config2) {
5002
5080
  const portEnv = Number(process.env.PORT ?? 6766);
5003
5081
  const port = config2.port ?? (Number.isFinite(portEnv) ? portEnv : 6766);
5082
+ const { simulations } = config2;
5083
+ const viteServer = config2.viteServer;
5084
+ const viteMode = !!viteServer;
5004
5085
  const httpServer = createServer(async (req, res) => {
5005
5086
  if (!req.url) {
5006
5087
  res.writeHead(400).end("Missing URL");
5007
5088
  return;
5008
5089
  }
5009
5090
  const url = new URL$1(req.url, `http://${req.headers.host ?? "localhost"}`);
5010
- console.log(`[HTTP] ${req.method} ${url.pathname}`);
5011
- if (req.method === "OPTIONS" && (url.pathname === ssePath || url.pathname === postPath)) {
5091
+ if (req.method === "OPTIONS") {
5012
5092
  res.writeHead(204, {
5013
5093
  "Access-Control-Allow-Origin": "*",
5014
5094
  "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
5015
- "Access-Control-Allow-Headers": "content-type"
5095
+ "Access-Control-Allow-Headers": "content-type, ngrok-skip-browser-warning"
5016
5096
  });
5017
5097
  res.end();
5018
5098
  return;
5019
5099
  }
5100
+ if (req.method === "GET" && url.pathname === "/") {
5101
+ res.writeHead(200, {
5102
+ "Content-Type": "text/html",
5103
+ "Access-Control-Allow-Origin": "*"
5104
+ });
5105
+ res.end(`<!DOCTYPE html>
5106
+ <html>
5107
+ <head>
5108
+ <meta charset="UTF-8" />
5109
+ <link rel="icon" type="image/png" href="/favicon.ico" />
5110
+ <title>Sunpeak MCP Server</title>
5111
+ </head>
5112
+ <body><h1>Sunpeak MCP Server</h1><p>Connect via <a href="/mcp">/mcp</a></p></body>
5113
+ </html>`);
5114
+ return;
5115
+ }
5116
+ if (req.method === "GET" && url.pathname === "/favicon.ico") {
5117
+ res.writeHead(200, {
5118
+ "Content-Type": "image/png",
5119
+ "Content-Length": FAVICON_BUFFER.length,
5120
+ "Cache-Control": "public, max-age=86400",
5121
+ "Access-Control-Allow-Origin": "*"
5122
+ });
5123
+ res.end(FAVICON_BUFFER);
5124
+ return;
5125
+ }
5020
5126
  if (req.method === "GET" && url.pathname === ssePath) {
5021
- await handleSseRequest(res, config2);
5127
+ console.log(`[HTTP] ${req.method} ${url.pathname}`);
5128
+ await handleSseRequest(res, config2, simulations, viteMode);
5022
5129
  return;
5023
5130
  }
5024
5131
  if (req.method === "POST" && url.pathname === postPath) {
5132
+ console.log(`[HTTP] ${req.method} ${url.pathname}`);
5025
5133
  await handlePostMessage(req, res, url);
5026
5134
  return;
5027
5135
  }
5136
+ if (viteServer) {
5137
+ res.setHeader("Access-Control-Allow-Origin", "*");
5138
+ res.setHeader("Access-Control-Allow-Headers", "content-type, ngrok-skip-browser-warning");
5139
+ viteServer.middlewares(req, res);
5140
+ return;
5141
+ }
5142
+ console.log(`[HTTP] ${req.method} ${url.pathname} → 404`);
5028
5143
  res.writeHead(404).end("Not Found");
5029
5144
  });
5145
+ if (viteServer) {
5146
+ httpServer.on("upgrade", (request, socket, head) => {
5147
+ viteServer.ws.handleUpgrade(request, socket, head);
5148
+ });
5149
+ }
5030
5150
  httpServer.on("clientError", (err, socket) => {
5031
5151
  console.error("HTTP client error", err);
5032
5152
  socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
@@ -5034,9 +5154,11 @@ function runMCPServer(config2) {
5034
5154
  httpServer.listen(port, () => {
5035
5155
  console.log(`Sunpeak MCP server listening on http://localhost:${port}`);
5036
5156
  console.log(` SSE stream: GET http://localhost:${port}${ssePath}`);
5037
- console.log(` Message post endpoint: POST http://localhost:${port}${postPath}?sessionId=...`);
5157
+ if (viteMode) {
5158
+ console.log(` Vite HMR: enabled (source files served with hot reload)`);
5159
+ }
5038
5160
  });
5039
- const shutdown = () => {
5161
+ const shutdown = async () => {
5040
5162
  console.log("\nShutting down MCP server...");
5041
5163
  httpServer.close(() => {
5042
5164
  console.log("MCP server closed");
@@ -5047,10 +5169,12 @@ function runMCPServer(config2) {
5047
5169
  process.exit(1);
5048
5170
  }, 5e3);
5049
5171
  };
5050
- process.on("SIGTERM", shutdown);
5051
- process.on("SIGINT", shutdown);
5172
+ process.on("SIGTERM", () => void shutdown());
5173
+ process.on("SIGINT", () => void shutdown());
5052
5174
  }
5053
5175
  export {
5176
+ FAVICON_BASE64 as F,
5177
+ FAVICON_BUFFER as a,
5054
5178
  runMCPServer as r
5055
5179
  };
5056
- //# sourceMappingURL=server-CnRhUNGQ.js.map
5180
+ //# sourceMappingURL=server-BI9Y531R.js.map