sunpeak 0.7.11 → 0.8.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 (64) hide show
  1. package/README.md +2 -1
  2. package/bin/commands/deploy.mjs +18 -8
  3. package/bin/commands/login.mjs +73 -55
  4. package/bin/commands/logout.mjs +26 -12
  5. package/bin/commands/pull.mjs +60 -39
  6. package/bin/commands/push.mjs +73 -49
  7. package/bin/commands/upgrade.mjs +203 -0
  8. package/bin/sunpeak.js +62 -31
  9. package/dist/chatgpt/chatgpt-simulator.d.ts +2 -1
  10. package/dist/index.cjs +9 -12
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.js +9 -12
  13. package/dist/index.js.map +1 -1
  14. package/dist/mcp/entry.cjs +41 -9
  15. package/dist/mcp/entry.cjs.map +1 -1
  16. package/dist/mcp/entry.js +42 -10
  17. package/dist/mcp/entry.js.map +1 -1
  18. package/dist/mcp/index.cjs +1 -1
  19. package/dist/mcp/index.js +1 -1
  20. package/dist/{server-CziiHU7V.cjs → server-B9YgCQdS.cjs} +3 -2
  21. package/dist/{server-CziiHU7V.cjs.map → server-B9YgCQdS.cjs.map} +1 -1
  22. package/dist/{server-D8kyzuiq.js → server-DVmTC-SF.js} +3 -2
  23. package/dist/{server-D8kyzuiq.js.map → server-DVmTC-SF.js.map} +1 -1
  24. package/dist/types/simulation.d.ts +1 -1
  25. package/package.json +1 -1
  26. package/template/.sunpeak/dev.tsx +78 -15
  27. package/template/.sunpeak/vite-env.d.ts +1 -0
  28. package/template/README.md +6 -6
  29. package/template/dist/albums.json +1 -1
  30. package/template/dist/carousel.json +1 -1
  31. package/template/dist/counter.json +1 -1
  32. package/template/dist/map.json +1 -1
  33. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +3 -3
  34. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +1 -1
  35. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +16 -16
  36. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js +3 -3
  37. package/template/node_modules/.vite/deps/_metadata.json +32 -32
  38. package/template/node_modules/.vite/deps/{chunk-N6DVYEXK.js → chunk-SPYXUHEY.js} +8 -8
  39. package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  40. package/template/src/components/map/map-view.test.tsx +1 -1
  41. package/template/src/components/map/map-view.tsx +1 -1
  42. package/template/src/components/map/map.tsx +1 -1
  43. package/template/src/components/map/place-card.test.tsx +1 -1
  44. package/template/src/components/map/place-card.tsx +1 -1
  45. package/template/src/components/map/place-carousel.test.tsx +1 -1
  46. package/template/src/components/map/place-carousel.tsx +1 -1
  47. package/template/src/components/map/place-inspector.test.tsx +1 -1
  48. package/template/src/components/map/place-inspector.tsx +1 -1
  49. package/template/src/components/map/place-list.test.tsx +1 -1
  50. package/template/src/components/map/place-list.tsx +1 -1
  51. package/template/src/components/map/types.ts +18 -0
  52. package/template/src/resources/index.ts +39 -4
  53. package/template/src/simulations/albums-show-simulation.json +131 -0
  54. package/template/src/simulations/carousel-show-simulation.json +68 -0
  55. package/template/src/simulations/counter-show-simulation.json +20 -0
  56. package/template/src/simulations/index.ts +17 -12
  57. package/template/src/simulations/map-show-simulation.json +123 -0
  58. package/template/src/vite-env.d.ts +1 -0
  59. package/template/tsconfig.json +1 -1
  60. package/template/src/simulations/albums-simulation.ts +0 -147
  61. package/template/src/simulations/carousel-simulation.ts +0 -84
  62. package/template/src/simulations/counter-simulation.ts +0 -34
  63. package/template/src/simulations/map-simulation.ts +0 -154
  64. /package/template/node_modules/.vite/deps/{chunk-N6DVYEXK.js.map → chunk-SPYXUHEY.js.map} +0 -0
@@ -1,20 +1,52 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- const server = require("../server-CziiHU7V.cjs");
3
+ const server = require("../server-B9YgCQdS.cjs");
4
4
  const path = require("path");
5
5
  const fs = require("fs");
6
6
  const projectRoot = process.cwd();
7
+ function findResourceKey(simulationKey, resourceKeys) {
8
+ const sorted = [...resourceKeys].sort((a, b) => b.length - a.length);
9
+ for (const resourceKey of sorted) {
10
+ if (simulationKey === resourceKey || simulationKey.startsWith(resourceKey + "-")) {
11
+ return resourceKey;
12
+ }
13
+ }
14
+ return void 0;
15
+ }
7
16
  async function startServer() {
8
17
  const pkgPath = path.join(projectRoot, "package.json");
9
18
  const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
10
- const simulationsPath = path.join(projectRoot, "src/simulations/index.ts");
11
- const { SIMULATIONS } = await import(simulationsPath);
12
- const simulations = Object.entries(
13
- SIMULATIONS
14
- ).map(([simulationKey, simulation]) => ({
15
- ...simulation,
16
- distPath: path.join(projectRoot, `dist/${simulationKey}.js`)
17
- }));
19
+ const resourcesDir = path.join(projectRoot, "src/resources");
20
+ const resourceFiles = fs.readdirSync(resourcesDir).filter((f) => f.endsWith("-resource.json"));
21
+ const resourcesMap = /* @__PURE__ */ new Map();
22
+ for (const filename of resourceFiles) {
23
+ const key = filename.replace(/-resource\.json$/, "");
24
+ const resourcePath = path.join(resourcesDir, filename);
25
+ const resource = JSON.parse(fs.readFileSync(resourcePath, "utf-8"));
26
+ resourcesMap.set(key, resource);
27
+ }
28
+ const resourceKeys = Array.from(resourcesMap.keys());
29
+ const simulationsDir = path.join(projectRoot, "src/simulations");
30
+ const simulationFiles = fs.readdirSync(simulationsDir).filter((f) => f.endsWith("-simulation.json"));
31
+ const simulations = [];
32
+ for (const filename of simulationFiles) {
33
+ const simulationKey = filename.replace(/-simulation\.json$/, "");
34
+ const simulationPath = path.join(simulationsDir, filename);
35
+ const simulation = JSON.parse(fs.readFileSync(simulationPath, "utf-8"));
36
+ const resourceKey = findResourceKey(simulationKey, resourceKeys);
37
+ if (!resourceKey) {
38
+ console.warn(
39
+ `No matching resource found for simulation "${simulationKey}". Expected a resource file like src/resources/${simulationKey.split("-")[0]}-resource.json`
40
+ );
41
+ continue;
42
+ }
43
+ const resource = resourcesMap.get(resourceKey);
44
+ simulations.push({
45
+ ...simulation,
46
+ distPath: path.join(projectRoot, `dist/${resourceKey}.js`),
47
+ resource
48
+ });
49
+ }
18
50
  server.runMCPServer({
19
51
  name: pkg.name || "Sunpeak",
20
52
  version: pkg.version || "0.1.0",
@@ -1 +1 @@
1
- {"version":3,"file":"entry.cjs","sources":["../../src/mcp/entry.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Internal MCP server entry point\n * This is run by nodemon or directly to start the MCP server\n * It automatically discovers the user's project and simulations\n */\nimport { runMCPServer, type SimulationWithDist } from './index.js';\nimport path from 'path';\nimport { readFileSync } from 'fs';\n\n// Determine project root (where this is being run from)\nconst projectRoot = process.cwd();\n\nasync function startServer() {\n // Read package.json for app metadata\n const pkgPath = path.join(projectRoot, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n\n // Dynamically import user's simulations\n const simulationsPath = path.join(projectRoot, 'src/simulations/index.ts');\n const { SIMULATIONS } = await import(simulationsPath);\n\n // Add distPath to each simulation for the MCP server\n const simulations = Object.entries(\n SIMULATIONS as Record<string, Omit<SimulationWithDist, 'distPath'>>\n ).map(([simulationKey, simulation]) => ({\n ...simulation,\n distPath: path.join(projectRoot, `dist/${simulationKey}.js`),\n }));\n\n runMCPServer({\n name: pkg.name || 'Sunpeak',\n version: pkg.version || '0.1.0',\n simulations,\n port: 6766,\n });\n}\n\nstartServer().catch((error) => {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n});\n"],"names":["readFileSync","runMCPServer"],"mappings":";;;;;AAWA,MAAM,cAAc,QAAQ,IAAA;AAE5B,eAAe,cAAc;AAE3B,QAAM,UAAU,KAAK,KAAK,aAAa,cAAc;AACrD,QAAM,MAAM,KAAK,MAAMA,GAAAA,aAAa,SAAS,OAAO,CAAC;AAGrD,QAAM,kBAAkB,KAAK,KAAK,aAAa,0BAA0B;AACzE,QAAM,EAAE,YAAA,IAAgB,MAAM,OAAO;AAGrC,QAAM,cAAc,OAAO;AAAA,IACzB;AAAA,EAAA,EACA,IAAI,CAAC,CAAC,eAAe,UAAU,OAAO;AAAA,IACtC,GAAG;AAAA,IACH,UAAU,KAAK,KAAK,aAAa,QAAQ,aAAa,KAAK;AAAA,EAAA,EAC3D;AAEFC,sBAAa;AAAA,IACX,MAAM,IAAI,QAAQ;AAAA,IAClB,SAAS,IAAI,WAAW;AAAA,IACxB;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AACH;AAEA,cAAc,MAAM,CAAC,UAAU;AAC7B,UAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAQ,KAAK,CAAC;AAChB,CAAC;"}
1
+ {"version":3,"file":"entry.cjs","sources":["../../src/mcp/entry.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Internal MCP server entry point\n * This is run by nodemon or directly to start the MCP server\n *\n * Auto-discovers simulations and resources by file naming convention:\n * - simulations/{resource}-{tool}-simulation.json (e.g., albums-show-simulation.json)\n * - resources/{resource}-resource.json\n */\nimport { runMCPServer, type SimulationWithDist } from './index.js';\nimport path from 'path';\nimport { readFileSync, readdirSync } from 'fs';\nimport type { Resource } from '@modelcontextprotocol/sdk/types.js';\n\n// Determine project root (where this is being run from)\nconst projectRoot = process.cwd();\n\n/**\n * Find the best matching resource key for a simulation key.\n * Matches the longest resource name that is a prefix of the simulation key.\n * e.g., 'albums-show' matches 'albums' (not 'album' if both exist)\n */\nfunction findResourceKey(simulationKey: string, resourceKeys: string[]): string | undefined {\n // Sort by length descending to find longest match first\n const sorted = [...resourceKeys].sort((a, b) => b.length - a.length);\n for (const resourceKey of sorted) {\n if (simulationKey === resourceKey || simulationKey.startsWith(resourceKey + '-')) {\n return resourceKey;\n }\n }\n return undefined;\n}\n\nasync function startServer() {\n // Read package.json for app metadata\n const pkgPath = path.join(projectRoot, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n\n // Auto-discover resource files first (to build lookup map)\n const resourcesDir = path.join(projectRoot, 'src/resources');\n const resourceFiles = readdirSync(resourcesDir).filter((f) => f.endsWith('-resource.json'));\n\n const resourcesMap = new Map<string, Resource>();\n for (const filename of resourceFiles) {\n // Extract key from filename: 'counter-resource.json' -> 'counter'\n const key = filename.replace(/-resource\\.json$/, '');\n const resourcePath = path.join(resourcesDir, filename);\n const resource = JSON.parse(readFileSync(resourcePath, 'utf-8')) as Resource;\n resourcesMap.set(key, resource);\n }\n\n const resourceKeys = Array.from(resourcesMap.keys());\n\n // Auto-discover simulation files\n const simulationsDir = path.join(projectRoot, 'src/simulations');\n const simulationFiles = readdirSync(simulationsDir).filter((f) => f.endsWith('-simulation.json'));\n\n // Build simulations array from discovered files\n const simulations: SimulationWithDist[] = [];\n\n for (const filename of simulationFiles) {\n // Extract simulation key from filename: 'albums-show-simulation.json' -> 'albums-show'\n const simulationKey = filename.replace(/-simulation\\.json$/, '');\n\n // Load simulation data\n const simulationPath = path.join(simulationsDir, filename);\n const simulation = JSON.parse(readFileSync(simulationPath, 'utf-8'));\n\n // Find matching resource by best prefix match\n const resourceKey = findResourceKey(simulationKey, resourceKeys);\n if (!resourceKey) {\n console.warn(\n `No matching resource found for simulation \"${simulationKey}\". ` +\n `Expected a resource file like src/resources/${simulationKey.split('-')[0]}-resource.json`\n );\n continue;\n }\n\n const resource = resourcesMap.get(resourceKey)!;\n\n simulations.push({\n ...simulation,\n distPath: path.join(projectRoot, `dist/${resourceKey}.js`),\n resource,\n });\n }\n\n runMCPServer({\n name: pkg.name || 'Sunpeak',\n version: pkg.version || '0.1.0',\n simulations,\n port: 6766,\n });\n}\n\nstartServer().catch((error) => {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n});\n"],"names":["readFileSync","readdirSync","runMCPServer"],"mappings":";;;;;AAeA,MAAM,cAAc,QAAQ,IAAA;AAO5B,SAAS,gBAAgB,eAAuB,cAA4C;AAE1F,QAAM,SAAS,CAAC,GAAG,YAAY,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACnE,aAAW,eAAe,QAAQ;AAChC,QAAI,kBAAkB,eAAe,cAAc,WAAW,cAAc,GAAG,GAAG;AAChF,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,cAAc;AAE3B,QAAM,UAAU,KAAK,KAAK,aAAa,cAAc;AACrD,QAAM,MAAM,KAAK,MAAMA,GAAAA,aAAa,SAAS,OAAO,CAAC;AAGrD,QAAM,eAAe,KAAK,KAAK,aAAa,eAAe;AAC3D,QAAM,gBAAgBC,eAAY,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,gBAAgB,CAAC;AAE1F,QAAM,mCAAmB,IAAA;AACzB,aAAW,YAAY,eAAe;AAEpC,UAAM,MAAM,SAAS,QAAQ,oBAAoB,EAAE;AACnD,UAAM,eAAe,KAAK,KAAK,cAAc,QAAQ;AACrD,UAAM,WAAW,KAAK,MAAMD,GAAAA,aAAa,cAAc,OAAO,CAAC;AAC/D,iBAAa,IAAI,KAAK,QAAQ;AAAA,EAChC;AAEA,QAAM,eAAe,MAAM,KAAK,aAAa,MAAM;AAGnD,QAAM,iBAAiB,KAAK,KAAK,aAAa,iBAAiB;AAC/D,QAAM,kBAAkBC,eAAY,cAAc,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,kBAAkB,CAAC;AAGhG,QAAM,cAAoC,CAAA;AAE1C,aAAW,YAAY,iBAAiB;AAEtC,UAAM,gBAAgB,SAAS,QAAQ,sBAAsB,EAAE;AAG/D,UAAM,iBAAiB,KAAK,KAAK,gBAAgB,QAAQ;AACzD,UAAM,aAAa,KAAK,MAAMD,GAAAA,aAAa,gBAAgB,OAAO,CAAC;AAGnE,UAAM,cAAc,gBAAgB,eAAe,YAAY;AAC/D,QAAI,CAAC,aAAa;AAChB,cAAQ;AAAA,QACN,8CAA8C,aAAa,kDACV,cAAc,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,MAAA;AAE9E;AAAA,IACF;AAEA,UAAM,WAAW,aAAa,IAAI,WAAW;AAE7C,gBAAY,KAAK;AAAA,MACf,GAAG;AAAA,MACH,UAAU,KAAK,KAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MACzD;AAAA,IAAA,CACD;AAAA,EACH;AAEAE,sBAAa;AAAA,IACX,MAAM,IAAI,QAAQ;AAAA,IAClB,SAAS,IAAI,WAAW;AAAA,IACxB;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AACH;AAEA,cAAc,MAAM,CAAC,UAAU;AAC7B,UAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAQ,KAAK,CAAC;AAChB,CAAC;"}
package/dist/mcp/entry.js CHANGED
@@ -1,19 +1,51 @@
1
1
  #!/usr/bin/env node
2
- import { r as runMCPServer } from "../server-D8kyzuiq.js";
2
+ import { r as runMCPServer } from "../server-DVmTC-SF.js";
3
3
  import path from "path";
4
- import { readFileSync } from "fs";
4
+ import { readFileSync, readdirSync } from "fs";
5
5
  const projectRoot = process.cwd();
6
+ function findResourceKey(simulationKey, resourceKeys) {
7
+ const sorted = [...resourceKeys].sort((a, b) => b.length - a.length);
8
+ for (const resourceKey of sorted) {
9
+ if (simulationKey === resourceKey || simulationKey.startsWith(resourceKey + "-")) {
10
+ return resourceKey;
11
+ }
12
+ }
13
+ return void 0;
14
+ }
6
15
  async function startServer() {
7
16
  const pkgPath = path.join(projectRoot, "package.json");
8
17
  const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
9
- const simulationsPath = path.join(projectRoot, "src/simulations/index.ts");
10
- const { SIMULATIONS } = await import(simulationsPath);
11
- const simulations = Object.entries(
12
- SIMULATIONS
13
- ).map(([simulationKey, simulation]) => ({
14
- ...simulation,
15
- distPath: path.join(projectRoot, `dist/${simulationKey}.js`)
16
- }));
18
+ const resourcesDir = path.join(projectRoot, "src/resources");
19
+ const resourceFiles = readdirSync(resourcesDir).filter((f) => f.endsWith("-resource.json"));
20
+ const resourcesMap = /* @__PURE__ */ new Map();
21
+ for (const filename of resourceFiles) {
22
+ const key = filename.replace(/-resource\.json$/, "");
23
+ const resourcePath = path.join(resourcesDir, filename);
24
+ const resource = JSON.parse(readFileSync(resourcePath, "utf-8"));
25
+ resourcesMap.set(key, resource);
26
+ }
27
+ const resourceKeys = Array.from(resourcesMap.keys());
28
+ const simulationsDir = path.join(projectRoot, "src/simulations");
29
+ const simulationFiles = readdirSync(simulationsDir).filter((f) => f.endsWith("-simulation.json"));
30
+ const simulations = [];
31
+ for (const filename of simulationFiles) {
32
+ const simulationKey = filename.replace(/-simulation\.json$/, "");
33
+ const simulationPath = path.join(simulationsDir, filename);
34
+ const simulation = JSON.parse(readFileSync(simulationPath, "utf-8"));
35
+ const resourceKey = findResourceKey(simulationKey, resourceKeys);
36
+ if (!resourceKey) {
37
+ console.warn(
38
+ `No matching resource found for simulation "${simulationKey}". Expected a resource file like src/resources/${simulationKey.split("-")[0]}-resource.json`
39
+ );
40
+ continue;
41
+ }
42
+ const resource = resourcesMap.get(resourceKey);
43
+ simulations.push({
44
+ ...simulation,
45
+ distPath: path.join(projectRoot, `dist/${resourceKey}.js`),
46
+ resource
47
+ });
48
+ }
17
49
  runMCPServer({
18
50
  name: pkg.name || "Sunpeak",
19
51
  version: pkg.version || "0.1.0",
@@ -1 +1 @@
1
- {"version":3,"file":"entry.js","sources":["../../src/mcp/entry.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Internal MCP server entry point\n * This is run by nodemon or directly to start the MCP server\n * It automatically discovers the user's project and simulations\n */\nimport { runMCPServer, type SimulationWithDist } from './index.js';\nimport path from 'path';\nimport { readFileSync } from 'fs';\n\n// Determine project root (where this is being run from)\nconst projectRoot = process.cwd();\n\nasync function startServer() {\n // Read package.json for app metadata\n const pkgPath = path.join(projectRoot, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n\n // Dynamically import user's simulations\n const simulationsPath = path.join(projectRoot, 'src/simulations/index.ts');\n const { SIMULATIONS } = await import(simulationsPath);\n\n // Add distPath to each simulation for the MCP server\n const simulations = Object.entries(\n SIMULATIONS as Record<string, Omit<SimulationWithDist, 'distPath'>>\n ).map(([simulationKey, simulation]) => ({\n ...simulation,\n distPath: path.join(projectRoot, `dist/${simulationKey}.js`),\n }));\n\n runMCPServer({\n name: pkg.name || 'Sunpeak',\n version: pkg.version || '0.1.0',\n simulations,\n port: 6766,\n });\n}\n\nstartServer().catch((error) => {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n});\n"],"names":[],"mappings":";;;;AAWA,MAAM,cAAc,QAAQ,IAAA;AAE5B,eAAe,cAAc;AAE3B,QAAM,UAAU,KAAK,KAAK,aAAa,cAAc;AACrD,QAAM,MAAM,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC;AAGrD,QAAM,kBAAkB,KAAK,KAAK,aAAa,0BAA0B;AACzE,QAAM,EAAE,YAAA,IAAgB,MAAM,OAAO;AAGrC,QAAM,cAAc,OAAO;AAAA,IACzB;AAAA,EAAA,EACA,IAAI,CAAC,CAAC,eAAe,UAAU,OAAO;AAAA,IACtC,GAAG;AAAA,IACH,UAAU,KAAK,KAAK,aAAa,QAAQ,aAAa,KAAK;AAAA,EAAA,EAC3D;AAEF,eAAa;AAAA,IACX,MAAM,IAAI,QAAQ;AAAA,IAClB,SAAS,IAAI,WAAW;AAAA,IACxB;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AACH;AAEA,cAAc,MAAM,CAAC,UAAU;AAC7B,UAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAQ,KAAK,CAAC;AAChB,CAAC;"}
1
+ {"version":3,"file":"entry.js","sources":["../../src/mcp/entry.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Internal MCP server entry point\n * This is run by nodemon or directly to start the MCP server\n *\n * Auto-discovers simulations and resources by file naming convention:\n * - simulations/{resource}-{tool}-simulation.json (e.g., albums-show-simulation.json)\n * - resources/{resource}-resource.json\n */\nimport { runMCPServer, type SimulationWithDist } from './index.js';\nimport path from 'path';\nimport { readFileSync, readdirSync } from 'fs';\nimport type { Resource } from '@modelcontextprotocol/sdk/types.js';\n\n// Determine project root (where this is being run from)\nconst projectRoot = process.cwd();\n\n/**\n * Find the best matching resource key for a simulation key.\n * Matches the longest resource name that is a prefix of the simulation key.\n * e.g., 'albums-show' matches 'albums' (not 'album' if both exist)\n */\nfunction findResourceKey(simulationKey: string, resourceKeys: string[]): string | undefined {\n // Sort by length descending to find longest match first\n const sorted = [...resourceKeys].sort((a, b) => b.length - a.length);\n for (const resourceKey of sorted) {\n if (simulationKey === resourceKey || simulationKey.startsWith(resourceKey + '-')) {\n return resourceKey;\n }\n }\n return undefined;\n}\n\nasync function startServer() {\n // Read package.json for app metadata\n const pkgPath = path.join(projectRoot, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n\n // Auto-discover resource files first (to build lookup map)\n const resourcesDir = path.join(projectRoot, 'src/resources');\n const resourceFiles = readdirSync(resourcesDir).filter((f) => f.endsWith('-resource.json'));\n\n const resourcesMap = new Map<string, Resource>();\n for (const filename of resourceFiles) {\n // Extract key from filename: 'counter-resource.json' -> 'counter'\n const key = filename.replace(/-resource\\.json$/, '');\n const resourcePath = path.join(resourcesDir, filename);\n const resource = JSON.parse(readFileSync(resourcePath, 'utf-8')) as Resource;\n resourcesMap.set(key, resource);\n }\n\n const resourceKeys = Array.from(resourcesMap.keys());\n\n // Auto-discover simulation files\n const simulationsDir = path.join(projectRoot, 'src/simulations');\n const simulationFiles = readdirSync(simulationsDir).filter((f) => f.endsWith('-simulation.json'));\n\n // Build simulations array from discovered files\n const simulations: SimulationWithDist[] = [];\n\n for (const filename of simulationFiles) {\n // Extract simulation key from filename: 'albums-show-simulation.json' -> 'albums-show'\n const simulationKey = filename.replace(/-simulation\\.json$/, '');\n\n // Load simulation data\n const simulationPath = path.join(simulationsDir, filename);\n const simulation = JSON.parse(readFileSync(simulationPath, 'utf-8'));\n\n // Find matching resource by best prefix match\n const resourceKey = findResourceKey(simulationKey, resourceKeys);\n if (!resourceKey) {\n console.warn(\n `No matching resource found for simulation \"${simulationKey}\". ` +\n `Expected a resource file like src/resources/${simulationKey.split('-')[0]}-resource.json`\n );\n continue;\n }\n\n const resource = resourcesMap.get(resourceKey)!;\n\n simulations.push({\n ...simulation,\n distPath: path.join(projectRoot, `dist/${resourceKey}.js`),\n resource,\n });\n }\n\n runMCPServer({\n name: pkg.name || 'Sunpeak',\n version: pkg.version || '0.1.0',\n simulations,\n port: 6766,\n });\n}\n\nstartServer().catch((error) => {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n});\n"],"names":[],"mappings":";;;;AAeA,MAAM,cAAc,QAAQ,IAAA;AAO5B,SAAS,gBAAgB,eAAuB,cAA4C;AAE1F,QAAM,SAAS,CAAC,GAAG,YAAY,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACnE,aAAW,eAAe,QAAQ;AAChC,QAAI,kBAAkB,eAAe,cAAc,WAAW,cAAc,GAAG,GAAG;AAChF,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,cAAc;AAE3B,QAAM,UAAU,KAAK,KAAK,aAAa,cAAc;AACrD,QAAM,MAAM,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC;AAGrD,QAAM,eAAe,KAAK,KAAK,aAAa,eAAe;AAC3D,QAAM,gBAAgB,YAAY,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,gBAAgB,CAAC;AAE1F,QAAM,mCAAmB,IAAA;AACzB,aAAW,YAAY,eAAe;AAEpC,UAAM,MAAM,SAAS,QAAQ,oBAAoB,EAAE;AACnD,UAAM,eAAe,KAAK,KAAK,cAAc,QAAQ;AACrD,UAAM,WAAW,KAAK,MAAM,aAAa,cAAc,OAAO,CAAC;AAC/D,iBAAa,IAAI,KAAK,QAAQ;AAAA,EAChC;AAEA,QAAM,eAAe,MAAM,KAAK,aAAa,MAAM;AAGnD,QAAM,iBAAiB,KAAK,KAAK,aAAa,iBAAiB;AAC/D,QAAM,kBAAkB,YAAY,cAAc,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,kBAAkB,CAAC;AAGhG,QAAM,cAAoC,CAAA;AAE1C,aAAW,YAAY,iBAAiB;AAEtC,UAAM,gBAAgB,SAAS,QAAQ,sBAAsB,EAAE;AAG/D,UAAM,iBAAiB,KAAK,KAAK,gBAAgB,QAAQ;AACzD,UAAM,aAAa,KAAK,MAAM,aAAa,gBAAgB,OAAO,CAAC;AAGnE,UAAM,cAAc,gBAAgB,eAAe,YAAY;AAC/D,QAAI,CAAC,aAAa;AAChB,cAAQ;AAAA,QACN,8CAA8C,aAAa,kDACV,cAAc,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,MAAA;AAE9E;AAAA,IACF;AAEA,UAAM,WAAW,aAAa,IAAI,WAAW;AAE7C,gBAAY,KAAK;AAAA,MACf,GAAG;AAAA,MACH,UAAU,KAAK,KAAK,aAAa,QAAQ,WAAW,KAAK;AAAA,MACzD;AAAA,IAAA,CACD;AAAA,EACH;AAEA,eAAa;AAAA,IACX,MAAM,IAAI,QAAQ;AAAA,IAClB,SAAS,IAAI,WAAW;AAAA,IACxB;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AACH;AAEA,cAAc,MAAM,CAAC,UAAU;AAC7B,UAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAQ,KAAK,CAAC;AAChB,CAAC;"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const server = require("../server-CziiHU7V.cjs");
3
+ const server = require("../server-B9YgCQdS.cjs");
4
4
  exports.runMCPServer = server.runMCPServer;
5
5
  //# sourceMappingURL=index.cjs.map
package/dist/mcp/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { r } from "../server-D8kyzuiq.js";
1
+ import { r } from "../server-DVmTC-SF.js";
2
2
  export {
3
3
  r as runMCPServer
4
4
  };
@@ -4837,7 +4837,7 @@ function readResourceHtml(distPath) {
4837
4837
  const htmlPath = path.resolve(distPath);
4838
4838
  if (!fs.existsSync(htmlPath)) {
4839
4839
  throw new Error(
4840
- `Widget file not found at ${htmlPath}. Run "pnpm build" to generate the built app.`
4840
+ `Widget file not found at ${htmlPath}. Run "sunpeak build" to generate the built app.`
4841
4841
  );
4842
4842
  }
4843
4843
  const jsContents = fs.readFileSync(htmlPath, "utf8");
@@ -4971,6 +4971,7 @@ async function handleSseRequest(res, config2) {
4971
4971
  sessions.set(sessionId, { server, transport });
4972
4972
  console.log(`[MCP] Session started: ${sessionId.substring(0, 8)}... (${sessions.size} active)`);
4973
4973
  transport.onclose = async () => {
4974
+ if (!sessions.has(sessionId)) return;
4974
4975
  sessions.delete(sessionId);
4975
4976
  console.log(`[MCP] Session closed: ${sessionId.substring(0, 8)}... (${sessions.size} active)`);
4976
4977
  await server.close();
@@ -5063,4 +5064,4 @@ function runMCPServer(config2) {
5063
5064
  process.on("SIGINT", shutdown);
5064
5065
  }
5065
5066
  exports.runMCPServer = runMCPServer;
5066
- //# sourceMappingURL=server-CziiHU7V.cjs.map
5067
+ //# sourceMappingURL=server-B9YgCQdS.cjs.map