sunpeak 0.7.10 → 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 (114) hide show
  1. package/README.md +9 -11
  2. package/bin/commands/deploy.mjs +18 -9
  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 +15 -12
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.js +15 -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-B9YgCQdS.cjs +5067 -0
  21. package/dist/server-B9YgCQdS.cjs.map +1 -0
  22. package/dist/server-DVmTC-SF.js +5068 -0
  23. package/dist/server-DVmTC-SF.js.map +1 -0
  24. package/dist/style.css +1 -1
  25. package/dist/types/simulation.d.ts +1 -1
  26. package/package.json +17 -17
  27. package/template/.sunpeak/dev.tsx +78 -15
  28. package/template/.sunpeak/vite-env.d.ts +1 -0
  29. package/template/README.md +6 -6
  30. package/template/dist/albums.js +4 -4
  31. package/template/dist/albums.json +1 -1
  32. package/template/dist/carousel.js +8 -8
  33. package/template/dist/carousel.json +1 -1
  34. package/template/dist/counter.js +4 -4
  35. package/template/dist/counter.json +1 -1
  36. package/template/dist/map.js +4 -4
  37. package/template/dist/map.json +1 -1
  38. package/template/node_modules/.bin/tsx +2 -2
  39. package/template/node_modules/.bin/vite +2 -2
  40. package/template/node_modules/.bin/vitest +2 -2
  41. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Avatar.js +7 -7
  42. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Avatar.js.map +1 -1
  43. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +6 -6
  44. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Checkbox.js +6 -6
  45. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Checkbox.js.map +1 -1
  46. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Icon.js +3 -3
  47. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Input.js +3 -3
  48. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +9 -9
  49. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js.map +1 -1
  50. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +33 -33
  51. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js.map +1 -1
  52. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js +7 -7
  53. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js.map +1 -1
  54. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_theme.js +2 -2
  55. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_theme.js.map +1 -1
  56. package/template/node_modules/.vite/deps/_metadata.json +60 -60
  57. package/template/node_modules/.vite/deps/{chunk-CQ3GYAYB.js → chunk-2DZGWGIP.js} +5 -5
  58. package/template/node_modules/.vite/deps/{chunk-CQ3GYAYB.js.map → chunk-2DZGWGIP.js.map} +1 -1
  59. package/template/node_modules/.vite/deps/{chunk-4TLBUCVB.js → chunk-BUOVMFCD.js} +6 -6
  60. package/template/node_modules/.vite/deps/{chunk-4TLBUCVB.js.map → chunk-BUOVMFCD.js.map} +2 -2
  61. package/template/node_modules/.vite/deps/{chunk-BAG6OO6S.js → chunk-DYQDWJMS.js} +5 -5
  62. package/template/node_modules/.vite/deps/{chunk-BAG6OO6S.js.map → chunk-DYQDWJMS.js.map} +1 -1
  63. package/template/node_modules/.vite/deps/{chunk-YOJ6QPGS.js → chunk-JAGHY6H6.js} +3 -3
  64. package/template/node_modules/.vite/deps/{chunk-YOJ6QPGS.js.map → chunk-JAGHY6H6.js.map} +1 -1
  65. package/template/node_modules/.vite/deps/{chunk-PTVT3RFX.js → chunk-JGVISENQ.js} +6 -6
  66. package/template/node_modules/.vite/deps/{chunk-PTVT3RFX.js.map → chunk-JGVISENQ.js.map} +1 -1
  67. package/template/node_modules/.vite/deps/{chunk-LR7NKCX5.js → chunk-SPYXUHEY.js} +44 -44
  68. package/template/node_modules/.vite/deps/{chunk-LR7NKCX5.js.map → chunk-SPYXUHEY.js.map} +1 -1
  69. package/template/node_modules/.vite/deps/{chunk-SGWD4VEU.js → chunk-TSEQUROC.js} +113 -107
  70. package/template/node_modules/.vite/deps/chunk-TSEQUROC.js.map +7 -0
  71. package/template/node_modules/.vite/deps/{chunk-XB525PXG.js → chunk-UM3ZGDFR.js} +747 -747
  72. package/template/node_modules/.vite/deps/{chunk-XB525PXG.js.map → chunk-UM3ZGDFR.js.map} +1 -1
  73. package/template/node_modules/.vite/deps/{chunk-KFGKZMLK.js → chunk-XZTIOEPG.js} +7 -7
  74. package/template/node_modules/.vite/deps/{chunk-KFGKZMLK.js.map → chunk-XZTIOEPG.js.map} +2 -2
  75. package/template/node_modules/.vite/deps/embla-carousel-react.js +3 -3
  76. package/template/node_modules/.vite/deps/embla-carousel-react.js.map +1 -1
  77. package/template/node_modules/.vite/deps/react-dom.js +2 -2
  78. package/template/node_modules/.vite/deps/react-dom_client.js +11 -11
  79. package/template/node_modules/.vite/deps/react-dom_client.js.map +2 -2
  80. package/template/node_modules/.vite/deps/react.js +1 -1
  81. package/template/node_modules/.vite/deps/react_jsx-dev-runtime.js +5 -5
  82. package/template/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +1 -1
  83. package/template/node_modules/.vite/deps/react_jsx-runtime.js +2 -2
  84. package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  85. package/template/package.json +11 -11
  86. package/template/src/components/map/map-view.test.tsx +1 -1
  87. package/template/src/components/map/map-view.tsx +1 -1
  88. package/template/src/components/map/map.tsx +1 -1
  89. package/template/src/components/map/place-card.test.tsx +1 -1
  90. package/template/src/components/map/place-card.tsx +1 -1
  91. package/template/src/components/map/place-carousel.test.tsx +1 -1
  92. package/template/src/components/map/place-carousel.tsx +1 -1
  93. package/template/src/components/map/place-inspector.test.tsx +1 -1
  94. package/template/src/components/map/place-inspector.tsx +1 -1
  95. package/template/src/components/map/place-list.test.tsx +1 -1
  96. package/template/src/components/map/place-list.tsx +1 -1
  97. package/template/src/components/map/types.ts +18 -0
  98. package/template/src/resources/index.ts +39 -4
  99. package/template/src/simulations/albums-show-simulation.json +131 -0
  100. package/template/src/simulations/carousel-show-simulation.json +68 -0
  101. package/template/src/simulations/counter-show-simulation.json +20 -0
  102. package/template/src/simulations/index.ts +17 -12
  103. package/template/src/simulations/map-show-simulation.json +123 -0
  104. package/template/src/vite-env.d.ts +1 -0
  105. package/template/tsconfig.json +1 -1
  106. package/dist/server-BOYwNazb.cjs +0 -930
  107. package/dist/server-BOYwNazb.cjs.map +0 -1
  108. package/dist/server-C6vMGV6H.js +0 -931
  109. package/dist/server-C6vMGV6H.js.map +0 -1
  110. package/template/node_modules/.vite/deps/chunk-SGWD4VEU.js.map +0 -7
  111. package/template/src/simulations/albums-simulation.ts +0 -147
  112. package/template/src/simulations/carousel-simulation.ts +0 -84
  113. package/template/src/simulations/counter-simulation.ts +0 -34
  114. package/template/src/simulations/map-simulation.ts +0 -154
@@ -1,20 +1,52 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- const server = require("../server-BOYwNazb.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-C6vMGV6H.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-BOYwNazb.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-C6vMGV6H.js";
1
+ import { r } from "../server-DVmTC-SF.js";
2
2
  export {
3
3
  r as runMCPServer
4
4
  };