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.
- package/README.md +9 -11
- package/bin/commands/deploy.mjs +18 -9
- package/bin/commands/login.mjs +73 -55
- package/bin/commands/logout.mjs +26 -12
- package/bin/commands/pull.mjs +60 -39
- package/bin/commands/push.mjs +73 -49
- package/bin/commands/upgrade.mjs +203 -0
- package/bin/sunpeak.js +62 -31
- package/dist/chatgpt/chatgpt-simulator.d.ts +2 -1
- package/dist/index.cjs +15 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +15 -12
- package/dist/index.js.map +1 -1
- package/dist/mcp/entry.cjs +41 -9
- package/dist/mcp/entry.cjs.map +1 -1
- package/dist/mcp/entry.js +42 -10
- package/dist/mcp/entry.js.map +1 -1
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/server-B9YgCQdS.cjs +5067 -0
- package/dist/server-B9YgCQdS.cjs.map +1 -0
- package/dist/server-DVmTC-SF.js +5068 -0
- package/dist/server-DVmTC-SF.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/types/simulation.d.ts +1 -1
- package/package.json +17 -17
- package/template/.sunpeak/dev.tsx +78 -15
- package/template/.sunpeak/vite-env.d.ts +1 -0
- package/template/README.md +6 -6
- package/template/dist/albums.js +4 -4
- package/template/dist/albums.json +1 -1
- package/template/dist/carousel.js +8 -8
- package/template/dist/carousel.json +1 -1
- package/template/dist/counter.js +4 -4
- package/template/dist/counter.json +1 -1
- package/template/dist/map.js +4 -4
- package/template/dist/map.json +1 -1
- package/template/node_modules/.bin/tsx +2 -2
- package/template/node_modules/.bin/vite +2 -2
- package/template/node_modules/.bin/vitest +2 -2
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Avatar.js +7 -7
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Avatar.js.map +1 -1
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +6 -6
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Checkbox.js +6 -6
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Checkbox.js.map +1 -1
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Icon.js +3 -3
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Input.js +3 -3
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +9 -9
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js.map +1 -1
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +33 -33
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js.map +1 -1
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js +7 -7
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js.map +1 -1
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_theme.js +2 -2
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_theme.js.map +1 -1
- package/template/node_modules/.vite/deps/_metadata.json +60 -60
- package/template/node_modules/.vite/deps/{chunk-CQ3GYAYB.js → chunk-2DZGWGIP.js} +5 -5
- package/template/node_modules/.vite/deps/{chunk-CQ3GYAYB.js.map → chunk-2DZGWGIP.js.map} +1 -1
- package/template/node_modules/.vite/deps/{chunk-4TLBUCVB.js → chunk-BUOVMFCD.js} +6 -6
- package/template/node_modules/.vite/deps/{chunk-4TLBUCVB.js.map → chunk-BUOVMFCD.js.map} +2 -2
- package/template/node_modules/.vite/deps/{chunk-BAG6OO6S.js → chunk-DYQDWJMS.js} +5 -5
- package/template/node_modules/.vite/deps/{chunk-BAG6OO6S.js.map → chunk-DYQDWJMS.js.map} +1 -1
- package/template/node_modules/.vite/deps/{chunk-YOJ6QPGS.js → chunk-JAGHY6H6.js} +3 -3
- package/template/node_modules/.vite/deps/{chunk-YOJ6QPGS.js.map → chunk-JAGHY6H6.js.map} +1 -1
- package/template/node_modules/.vite/deps/{chunk-PTVT3RFX.js → chunk-JGVISENQ.js} +6 -6
- package/template/node_modules/.vite/deps/{chunk-PTVT3RFX.js.map → chunk-JGVISENQ.js.map} +1 -1
- package/template/node_modules/.vite/deps/{chunk-LR7NKCX5.js → chunk-SPYXUHEY.js} +44 -44
- package/template/node_modules/.vite/deps/{chunk-LR7NKCX5.js.map → chunk-SPYXUHEY.js.map} +1 -1
- package/template/node_modules/.vite/deps/{chunk-SGWD4VEU.js → chunk-TSEQUROC.js} +113 -107
- package/template/node_modules/.vite/deps/chunk-TSEQUROC.js.map +7 -0
- package/template/node_modules/.vite/deps/{chunk-XB525PXG.js → chunk-UM3ZGDFR.js} +747 -747
- package/template/node_modules/.vite/deps/{chunk-XB525PXG.js.map → chunk-UM3ZGDFR.js.map} +1 -1
- package/template/node_modules/.vite/deps/{chunk-KFGKZMLK.js → chunk-XZTIOEPG.js} +7 -7
- package/template/node_modules/.vite/deps/{chunk-KFGKZMLK.js.map → chunk-XZTIOEPG.js.map} +2 -2
- package/template/node_modules/.vite/deps/embla-carousel-react.js +3 -3
- package/template/node_modules/.vite/deps/embla-carousel-react.js.map +1 -1
- package/template/node_modules/.vite/deps/react-dom.js +2 -2
- package/template/node_modules/.vite/deps/react-dom_client.js +11 -11
- package/template/node_modules/.vite/deps/react-dom_client.js.map +2 -2
- package/template/node_modules/.vite/deps/react.js +1 -1
- package/template/node_modules/.vite/deps/react_jsx-dev-runtime.js +5 -5
- package/template/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +1 -1
- package/template/node_modules/.vite/deps/react_jsx-runtime.js +2 -2
- package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/template/package.json +11 -11
- package/template/src/components/map/map-view.test.tsx +1 -1
- package/template/src/components/map/map-view.tsx +1 -1
- package/template/src/components/map/map.tsx +1 -1
- package/template/src/components/map/place-card.test.tsx +1 -1
- package/template/src/components/map/place-card.tsx +1 -1
- package/template/src/components/map/place-carousel.test.tsx +1 -1
- package/template/src/components/map/place-carousel.tsx +1 -1
- package/template/src/components/map/place-inspector.test.tsx +1 -1
- package/template/src/components/map/place-inspector.tsx +1 -1
- package/template/src/components/map/place-list.test.tsx +1 -1
- package/template/src/components/map/place-list.tsx +1 -1
- package/template/src/components/map/types.ts +18 -0
- package/template/src/resources/index.ts +39 -4
- package/template/src/simulations/albums-show-simulation.json +131 -0
- package/template/src/simulations/carousel-show-simulation.json +68 -0
- package/template/src/simulations/counter-show-simulation.json +20 -0
- package/template/src/simulations/index.ts +17 -12
- package/template/src/simulations/map-show-simulation.json +123 -0
- package/template/src/vite-env.d.ts +1 -0
- package/template/tsconfig.json +1 -1
- package/dist/server-BOYwNazb.cjs +0 -930
- package/dist/server-BOYwNazb.cjs.map +0 -1
- package/dist/server-C6vMGV6H.js +0 -931
- package/dist/server-C6vMGV6H.js.map +0 -1
- package/template/node_modules/.vite/deps/chunk-SGWD4VEU.js.map +0 -7
- package/template/src/simulations/albums-simulation.ts +0 -147
- package/template/src/simulations/carousel-simulation.ts +0 -84
- package/template/src/simulations/counter-simulation.ts +0 -34
- package/template/src/simulations/map-simulation.ts +0 -154
package/dist/style.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! tailwindcss v4.1.
|
|
1
|
+
/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
|
|
2
2
|
@layer properties {
|
|
3
3
|
@supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {
|
|
4
4
|
*, :before, :after, ::backdrop {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sunpeak",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "The ChatGPT App framework. Quickstart, build, & test your ChatGPT App locally!",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -57,40 +57,40 @@
|
|
|
57
57
|
"author": "Sunpeak AI",
|
|
58
58
|
"license": "MIT",
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@openai/apps-sdk-ui": "^0.2.
|
|
60
|
+
"@openai/apps-sdk-ui": "^0.2.1",
|
|
61
61
|
"react": "^18.0.0 || ^19.0.0",
|
|
62
62
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@modelcontextprotocol/sdk": "^
|
|
65
|
+
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
66
66
|
"clsx": "^2.1.1",
|
|
67
67
|
"tailwind-merge": "^3.4.0",
|
|
68
|
-
"zod": "^3.
|
|
68
|
+
"zod": "^3.25.76"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@playwright/test": "^1.
|
|
72
|
-
"@tailwindcss/vite": "^4.1.
|
|
71
|
+
"@playwright/test": "^1.57.0",
|
|
72
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
73
73
|
"@testing-library/jest-dom": "^6.9.1",
|
|
74
|
-
"@testing-library/react": "^16.3.
|
|
74
|
+
"@testing-library/react": "^16.3.1",
|
|
75
75
|
"@testing-library/user-event": "^14.6.1",
|
|
76
|
-
"@types/node": "^
|
|
76
|
+
"@types/node": "^22.15.3",
|
|
77
77
|
"@types/react": "^19.2.7",
|
|
78
78
|
"@types/react-dom": "^19.2.3",
|
|
79
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
80
|
-
"@typescript-eslint/parser": "^8.
|
|
81
|
-
"@vitejs/plugin-react": "^4.
|
|
82
|
-
"eslint": "^9.39.
|
|
79
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
80
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
81
|
+
"@vitejs/plugin-react": "^4.5.2",
|
|
82
|
+
"eslint": "^9.39.2",
|
|
83
83
|
"eslint-config-prettier": "^10.1.8",
|
|
84
84
|
"eslint-plugin-react": "^7.37.5",
|
|
85
85
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
86
|
-
"jsdom": "^27.
|
|
87
|
-
"prettier": "^3.
|
|
86
|
+
"jsdom": "^27.3.0",
|
|
87
|
+
"prettier": "^3.7.4",
|
|
88
88
|
"react": "^19.2.0",
|
|
89
89
|
"react-dom": "^19.2.0",
|
|
90
|
-
"tailwindcss": "^4.1.
|
|
90
|
+
"tailwindcss": "^4.1.18",
|
|
91
91
|
"ts-node": "^10.9.2",
|
|
92
|
-
"tsx": "^4.
|
|
93
|
-
"typescript": "^5.
|
|
92
|
+
"tsx": "^4.21.0",
|
|
93
|
+
"typescript": "^5.9.3",
|
|
94
94
|
"vite": "^5.4.21",
|
|
95
95
|
"vite-plugin-dts": "^4.5.4",
|
|
96
96
|
"vitest": "^4.0.12"
|
|
@@ -1,44 +1,107 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bootstrap file for Sunpeak dev server
|
|
3
3
|
* This file bootstraps the ChatGPT simulator for development
|
|
4
|
+
*
|
|
5
|
+
* Auto-discovers simulations and resources by file naming convention:
|
|
6
|
+
* - simulations/{resource}-{tool}-simulation.json (e.g., albums-show-simulation.json)
|
|
7
|
+
* - resources/{resource}-resource.json
|
|
8
|
+
* - resources/{Resource}Resource component (PascalCase)
|
|
4
9
|
*/
|
|
5
10
|
import { StrictMode } from 'react';
|
|
6
11
|
import { createRoot } from 'react-dom/client';
|
|
7
12
|
import { ChatGPTSimulator, type Simulation } from 'sunpeak';
|
|
8
|
-
import
|
|
9
|
-
import * as Resources from '../src/resources';
|
|
13
|
+
import resourceComponents from '../src/resources';
|
|
10
14
|
import '../src/styles/globals.css';
|
|
11
15
|
|
|
16
|
+
// Auto-discover all simulation and resource JSON files
|
|
17
|
+
const simulationModules = import.meta.glob('../src/simulations/*-simulation.json', {
|
|
18
|
+
eager: true,
|
|
19
|
+
});
|
|
20
|
+
const resourceModules = import.meta.glob('../src/resources/*-resource.json', { eager: true });
|
|
21
|
+
|
|
22
|
+
// Build resource map from discovered files
|
|
23
|
+
type ResourceData = { name: string; [key: string]: unknown };
|
|
24
|
+
const resourcesMap = new Map<string, ResourceData>();
|
|
25
|
+
for (const [path, module] of Object.entries(resourceModules)) {
|
|
26
|
+
// Extract key from path: '../src/resources/counter-resource.json' -> 'counter'
|
|
27
|
+
const match = path.match(/\/([^/]+)-resource\.json$/);
|
|
28
|
+
const key = match?.[1];
|
|
29
|
+
if (key) {
|
|
30
|
+
resourcesMap.set(key, (module as { default: ResourceData }).default);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Get sorted resource keys for best-match lookup (longest first)
|
|
35
|
+
const resourceKeys = Array.from(resourcesMap.keys()).sort((a, b) => b.length - a.length);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Find the best matching resource for a simulation key.
|
|
39
|
+
* Matches the longest resource name that is a prefix of the simulation key.
|
|
40
|
+
* e.g., 'albums-show' matches 'albums' (not 'album' if both exist)
|
|
41
|
+
*/
|
|
42
|
+
function findResourceKey(simulationKey: string): string | undefined {
|
|
43
|
+
// Simulation key format: {resource}-{tool} (e.g., 'albums-show')
|
|
44
|
+
// Find the longest resource name that matches as a prefix followed by '-'
|
|
45
|
+
for (const resourceKey of resourceKeys) {
|
|
46
|
+
if (simulationKey === resourceKey || simulationKey.startsWith(resourceKey + '-')) {
|
|
47
|
+
return resourceKey;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
12
53
|
/**
|
|
13
54
|
* Convert resource name to component name
|
|
14
55
|
* Example: 'carousel' -> 'CarouselResource', 'counter' -> 'CounterResource'
|
|
15
56
|
*/
|
|
16
|
-
function
|
|
17
|
-
// Convert name to PascalCase and append 'Resource'
|
|
57
|
+
function getResourceComponent(name: string): React.ComponentType {
|
|
18
58
|
const pascalName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
19
59
|
const componentName = `${pascalName}Resource`;
|
|
20
60
|
|
|
21
|
-
const component =
|
|
61
|
+
const component = resourceComponents[componentName];
|
|
22
62
|
|
|
23
63
|
if (!component) {
|
|
24
64
|
throw new Error(
|
|
25
65
|
`Resource component "${componentName}" not found for resource "${name}". ` +
|
|
26
|
-
`Make sure
|
|
66
|
+
`Make sure src/resources/${name}-resource.tsx exists with a default export.`
|
|
27
67
|
);
|
|
28
68
|
}
|
|
29
69
|
|
|
30
|
-
return component
|
|
70
|
+
return component;
|
|
31
71
|
}
|
|
32
72
|
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
73
|
+
// Build simulations array from discovered files
|
|
74
|
+
type SimulationData = Omit<Simulation, 'resourceComponent' | 'resource'>;
|
|
75
|
+
const simulations: Simulation[] = [];
|
|
76
|
+
|
|
77
|
+
for (const [path, module] of Object.entries(simulationModules)) {
|
|
78
|
+
// Extract simulation key from path: '../src/simulations/albums-show-simulation.json' -> 'albums-show'
|
|
79
|
+
const match = path.match(/\/([^/]+)-simulation\.json$/);
|
|
80
|
+
const simulationKey = match?.[1];
|
|
81
|
+
if (!simulationKey) continue;
|
|
82
|
+
|
|
83
|
+
const simulation = (module as { default: SimulationData }).default;
|
|
84
|
+
|
|
85
|
+
// Find matching resource by best prefix match
|
|
86
|
+
const resourceKey = findResourceKey(simulationKey);
|
|
87
|
+
if (!resourceKey) {
|
|
88
|
+
console.warn(
|
|
89
|
+
`No matching resource found for simulation "${simulationKey}". ` +
|
|
90
|
+
`Expected a resource file like src/resources/${simulationKey.split('-')[0]}-resource.json`
|
|
91
|
+
);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const resource = resourcesMap.get(resourceKey)!;
|
|
96
|
+
|
|
97
|
+
simulations.push({
|
|
98
|
+
...simulation,
|
|
99
|
+
resource,
|
|
100
|
+
resourceComponent: getResourceComponent(resource.name),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
40
103
|
|
|
41
|
-
// Read app config from
|
|
104
|
+
// Read app config from environment or use defaults
|
|
42
105
|
const appName = import.meta.env?.VITE_APP_NAME || 'Sunpeak';
|
|
43
106
|
const appIcon = import.meta.env?.VITE_APP_ICON || '🌄';
|
|
44
107
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
package/template/README.md
CHANGED
|
@@ -8,7 +8,7 @@ For an initial overview of your new app and the sunpeak API, refer to the [docum
|
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
pnpm install
|
|
11
|
-
|
|
11
|
+
sunpeak dev
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
That's it! Edit the resource files in [./src/resources/](./src/resources/) to build your resource UI.
|
|
@@ -16,9 +16,9 @@ That's it! Edit the resource files in [./src/resources/](./src/resources/) to bu
|
|
|
16
16
|
## Commands
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
sunpeak dev # Start development server
|
|
20
|
+
sunpeak build # Build all resources for production
|
|
21
|
+
sunpeak mcp # Start MCP server with auto-reload
|
|
22
22
|
pnpm test # Run tests with Vitest
|
|
23
23
|
```
|
|
24
24
|
|
|
@@ -62,7 +62,7 @@ Test your app directly in ChatGPT using the built-in MCP server:
|
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
64
|
# Start the MCP server (rebuilds and restarts on file changes).
|
|
65
|
-
|
|
65
|
+
sunpeak mcp
|
|
66
66
|
|
|
67
67
|
# In another terminal, run a tunnel. For example:
|
|
68
68
|
ngrok http 6766
|
|
@@ -79,7 +79,7 @@ When you make changes to the UI, refresh your app in ChatGPT after the MCP serve
|
|
|
79
79
|
Build your app for production:
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
|
-
|
|
82
|
+
sunpeak build
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
This creates optimized builds in `dist/`:
|