sunpeak 0.4.2 → 0.4.4
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 +2 -2
- package/bin/sunpeak.js +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/template/README.md +1 -1
- package/template/dev/main.tsx +1 -1
- package/template/mcp/server.ts +5 -9
- package/template/src/components/album/albums.tsx +7 -7
- package/template/src/components/apps/AlbumsApp.tsx +13 -0
- package/template/src/{App.tsx → components/apps/App.tsx} +2 -2
- package/template/src/components/{simulations/carousel-simulation.tsx → apps/PlacesApp.tsx} +11 -17
- package/template/src/components/apps/active-app.ts +11 -0
- package/template/src/components/apps/index.ts +3 -0
- package/template/src/components/card/card.tsx +4 -0
- package/template/src/components/index.ts +1 -1
- package/template/src/index.chatgpt.tsx +4 -3
- package/template/src/index.ts +0 -1
- package/template/src/simulations/albums-simulation.ts +129 -0
- package/template/src/simulations/app-configs.ts +30 -0
- package/template/src/simulations/app-simulation.ts +15 -0
- package/template/src/simulations/carousel-simulation.ts +66 -0
- package/template/src/simulations/index.ts +16 -0
- package/template/src/simulations/simulations.ts +74 -0
- package/template/data/albums.json +0 -112
- package/template/data/places.json +0 -49
- package/template/src/components/simulations/albums-simulation.tsx +0 -20
- package/template/src/components/simulations/app-simulation.tsx +0 -13
- package/template/src/components/simulations/index.tsx +0 -14
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sunpeak",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "The
|
|
3
|
+
"version": "0.4.4",
|
|
4
|
+
"description": "The MCP App SDK. Quickstart, build, & test your ChatGPT App locally!",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.js",
|
package/template/README.md
CHANGED
|
@@ -10,7 +10,7 @@ For an initial overview of your new app and the sunpeak API, refer to the [docum
|
|
|
10
10
|
pnpm dev
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Edit [src/App.tsx](./src/App.tsx) to build your app UI.
|
|
13
|
+
Edit [./src/components/apps/App.tsx](./src/components/apps/App.tsx) to build your app UI.
|
|
14
14
|
|
|
15
15
|
## Development
|
|
16
16
|
|
package/template/dev/main.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import '../src/styles/globals.css';
|
|
|
3
3
|
import { StrictMode } from 'react';
|
|
4
4
|
import { createRoot } from 'react-dom/client';
|
|
5
5
|
import { ChatGPTSimulator } from 'sunpeak';
|
|
6
|
-
import { simulations } from '../src/
|
|
6
|
+
import { simulations } from '../src/simulations';
|
|
7
7
|
|
|
8
8
|
createRoot(document.getElementById('root')!).render(
|
|
9
9
|
<StrictMode>
|
package/template/mcp/server.ts
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
import { runMCPServer } from 'sunpeak/mcp';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
-
import {
|
|
4
|
+
import { activeConfig } from '../src/simulations/app-configs.js';
|
|
5
5
|
|
|
6
6
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
7
|
|
|
8
|
-
// Load places data from JSON file
|
|
9
|
-
const placesDataPath = path.resolve(__dirname, '../data/places.json');
|
|
10
|
-
const toolOutput = JSON.parse(readFileSync(placesDataPath, 'utf-8'));
|
|
11
|
-
|
|
12
8
|
runMCPServer({
|
|
13
|
-
name:
|
|
9
|
+
name: activeConfig.appName,
|
|
14
10
|
version: '0.1.0',
|
|
15
11
|
distPath: path.resolve(__dirname, '../dist/chatgpt/index.js'),
|
|
16
|
-
toolName:
|
|
17
|
-
toolDescription:
|
|
18
|
-
dummyData: toolOutput,
|
|
12
|
+
toolName: activeConfig.toolName,
|
|
13
|
+
toolDescription: activeConfig.toolDescription,
|
|
14
|
+
dummyData: activeConfig.toolOutput ?? {},
|
|
19
15
|
port: 6766,
|
|
20
16
|
});
|
|
@@ -15,22 +15,22 @@ export interface Album {
|
|
|
15
15
|
}>
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export interface
|
|
18
|
+
export interface AlbumsData extends Record<string, unknown> {
|
|
19
19
|
albums: Album[]
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export interface
|
|
22
|
+
export interface AlbumsState extends Record<string, unknown> {
|
|
23
23
|
selectedAlbumId?: string | null
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export type
|
|
26
|
+
export type AlbumsProps = {
|
|
27
27
|
className?: string
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export const
|
|
30
|
+
export const Albums = React.forwardRef<HTMLDivElement, AlbumsProps>(
|
|
31
31
|
({ className }, ref) => {
|
|
32
|
-
const data = useWidgetProps<
|
|
33
|
-
const [widgetState, setWidgetState] = useWidgetState<
|
|
32
|
+
const data = useWidgetProps<AlbumsData>(() => ({ albums: [] }))
|
|
33
|
+
const [widgetState, setWidgetState] = useWidgetState<AlbumsState>(() => ({
|
|
34
34
|
selectedAlbumId: null,
|
|
35
35
|
}))
|
|
36
36
|
const displayMode = useDisplayMode()
|
|
@@ -74,4 +74,4 @@ export const OpenAIAlbums = React.forwardRef<HTMLDivElement, OpenAIAlbumsProps>(
|
|
|
74
74
|
)
|
|
75
75
|
}
|
|
76
76
|
)
|
|
77
|
-
|
|
77
|
+
Albums.displayName = "Albums"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Albums } from "../album"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Production-ready Albums App
|
|
6
|
+
*
|
|
7
|
+
* This app displays photo albums in a carousel layout with fullscreen viewing capability.
|
|
8
|
+
* Can be dropped into any production environment without changes.
|
|
9
|
+
*/
|
|
10
|
+
export const AlbumsApp = React.forwardRef<HTMLDivElement>((_props, ref) => {
|
|
11
|
+
return <Albums ref={ref} />
|
|
12
|
+
})
|
|
13
|
+
AlbumsApp.displayName = "AlbumsApp"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import '
|
|
1
|
+
import '../../styles/globals.css';
|
|
2
2
|
|
|
3
3
|
import { useWidgetState } from 'sunpeak';
|
|
4
4
|
import { Button } from '@openai/apps-sdk-ui/components/Button';
|
|
@@ -18,7 +18,7 @@ interface CounterState extends Record<string, unknown> {
|
|
|
18
18
|
* - Check out the components folder for reusable components
|
|
19
19
|
* - Use sunpeak hooks for state management and display modes
|
|
20
20
|
* - Edit this file and see your changes live
|
|
21
|
-
* - Edit
|
|
21
|
+
* - Edit ../../simulations/app-simulation.tsx to customize your simulation
|
|
22
22
|
*/
|
|
23
23
|
export function App() {
|
|
24
24
|
const [widgetState, setWidgetState] = useWidgetState<CounterState>(() => ({
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
|
-
import type { Simulation } from "sunpeak"
|
|
3
2
|
import { useWidgetProps } from "sunpeak"
|
|
4
3
|
import { Carousel, Card } from ".."
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Production-ready Places App
|
|
7
|
+
*
|
|
8
|
+
* This app displays places in a carousel layout with cards.
|
|
9
|
+
* Can be dropped into any production environment without changes.
|
|
10
|
+
*/
|
|
6
11
|
|
|
7
12
|
export interface Place {
|
|
8
13
|
id: string
|
|
@@ -14,12 +19,12 @@ export interface Place {
|
|
|
14
19
|
description: string
|
|
15
20
|
}
|
|
16
21
|
|
|
17
|
-
export interface
|
|
22
|
+
export interface PlacesData extends Record<string, unknown> {
|
|
18
23
|
places: Place[]
|
|
19
24
|
}
|
|
20
25
|
|
|
21
|
-
const
|
|
22
|
-
const data = useWidgetProps<
|
|
26
|
+
export const PlacesApp = React.forwardRef<HTMLDivElement>((_props, ref) => {
|
|
27
|
+
const data = useWidgetProps<PlacesData>(() => ({ places: [] }))
|
|
23
28
|
|
|
24
29
|
return (
|
|
25
30
|
<div ref={ref}>
|
|
@@ -49,15 +54,4 @@ const CarouselComponent = React.forwardRef<HTMLDivElement>((_props, ref) => {
|
|
|
49
54
|
</div>
|
|
50
55
|
)
|
|
51
56
|
})
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
export const carouselSimulation: Simulation = {
|
|
55
|
-
value: 'carousel',
|
|
56
|
-
label: 'Carousel',
|
|
57
|
-
component: CarouselComponent,
|
|
58
|
-
appName: 'Splorin',
|
|
59
|
-
appIcon: '✈️',
|
|
60
|
-
userMessage: 'Show me popular places to visit in Austin Texas',
|
|
61
|
-
toolOutput: placesData,
|
|
62
|
-
widgetState: null,
|
|
63
|
-
}
|
|
57
|
+
PlacesApp.displayName = "PlacesApp"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Active app selection - SINGLE SOURCE OF TRUTH
|
|
3
|
+
*
|
|
4
|
+
* 👇 CHANGE THIS LINE to switch which app is active for the:
|
|
5
|
+
* - ChatGPT build (index.chatgpt.tsx)
|
|
6
|
+
* - MCP server (server.ts)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export type AppName = 'app' | 'albums' | 'carousel';
|
|
10
|
+
|
|
11
|
+
export const ACTIVE_APP: AppName = 'app';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createRoot } from 'react-dom/client';
|
|
2
|
-
import {
|
|
2
|
+
import { ActiveComponent as ActiveApp } from './simulations/simulations';
|
|
3
3
|
|
|
4
|
-
// Mount the
|
|
4
|
+
// Mount the active app
|
|
5
|
+
// To switch apps, edit ACTIVE_APP in components/apps/active-app.ts
|
|
5
6
|
const root = document.getElementById('root');
|
|
6
7
|
if (root) {
|
|
7
|
-
createRoot(root).render(<
|
|
8
|
+
createRoot(root).render(<ActiveApp />);
|
|
8
9
|
}
|
package/template/src/index.ts
CHANGED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-safe configuration for the albums simulation.
|
|
3
|
+
* This file contains only metadata and doesn't import React components or CSS.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const albumsData = {
|
|
7
|
+
albums: [
|
|
8
|
+
{
|
|
9
|
+
id: "summer-escape",
|
|
10
|
+
title: "Summer Slice",
|
|
11
|
+
cover: "https://persistent.oaistatic.com/pizzaz/pizzaz-1.png",
|
|
12
|
+
photos: [
|
|
13
|
+
{
|
|
14
|
+
id: "s1",
|
|
15
|
+
title: "Waves",
|
|
16
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-2.png"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: "s2",
|
|
20
|
+
title: "Palm trees",
|
|
21
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-3.png"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "s3",
|
|
25
|
+
title: "Sunset",
|
|
26
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-6.png"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "city-lights",
|
|
32
|
+
title: "Pepperoni Nights",
|
|
33
|
+
cover: "https://persistent.oaistatic.com/pizzaz/pizzaz-4.png",
|
|
34
|
+
photos: [
|
|
35
|
+
{
|
|
36
|
+
id: "c1",
|
|
37
|
+
title: "Downtown",
|
|
38
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-5.png"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "c2",
|
|
42
|
+
title: "Neon",
|
|
43
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-1.png"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "c3",
|
|
47
|
+
title: "Streets",
|
|
48
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-2.png"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "into-the-woods",
|
|
54
|
+
title: "Truffle Forest",
|
|
55
|
+
cover: "https://persistent.oaistatic.com/pizzaz/pizzaz-3.png",
|
|
56
|
+
photos: [
|
|
57
|
+
{
|
|
58
|
+
id: "n1",
|
|
59
|
+
title: "Forest path",
|
|
60
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-6.png"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: "n2",
|
|
64
|
+
title: "Misty",
|
|
65
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-4.png"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: "n3",
|
|
69
|
+
title: "Waterfall",
|
|
70
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-5.png"
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: "pizza-tour",
|
|
76
|
+
title: "Pizza tour",
|
|
77
|
+
cover: "https://persistent.oaistatic.com/pizzaz/pizzaz-1.png",
|
|
78
|
+
photos: [
|
|
79
|
+
{
|
|
80
|
+
id: "tonys-pizza-napoletana",
|
|
81
|
+
title: "Tony's Pizza Napoletana",
|
|
82
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-2.png"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "golden-boy-pizza",
|
|
86
|
+
title: "Golden Boy Pizza",
|
|
87
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-3.png"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: "pizzeria-delfina-mission",
|
|
91
|
+
title: "Pizzeria Delfina (Mission)",
|
|
92
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-6.png"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "ragazza",
|
|
96
|
+
title: "Ragazza",
|
|
97
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-4.png"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "del-popolo",
|
|
101
|
+
title: "Del Popolo",
|
|
102
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-5.png"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "square-pie-guys",
|
|
106
|
+
title: "Square Pie Guys",
|
|
107
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-1.png"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "zero-zero",
|
|
111
|
+
title: "Zero Zero",
|
|
112
|
+
url: "https://persistent.oaistatic.com/pizzaz/pizzaz-2.png"
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const albumsSimulationConfig = {
|
|
120
|
+
appName: 'Pizzaz',
|
|
121
|
+
value: 'albums',
|
|
122
|
+
label: 'Albums',
|
|
123
|
+
appIcon: '🍕',
|
|
124
|
+
userMessage: 'Pizza time',
|
|
125
|
+
toolOutput: albumsData,
|
|
126
|
+
widgetState: null,
|
|
127
|
+
toolName: 'show-app',
|
|
128
|
+
toolDescription: 'Show photo albums',
|
|
129
|
+
} as const;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-safe app configurations
|
|
3
|
+
*
|
|
4
|
+
* This file contains only metadata and can be safely imported in Node.js contexts
|
|
5
|
+
* (like MCP servers) without causing issues with CSS imports or React components.
|
|
6
|
+
*
|
|
7
|
+
* To switch apps, change ACTIVE_APP in components/apps/active-app.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { ACTIVE_APP } from '../components/apps/active-app';
|
|
11
|
+
import { appSimulationConfig } from './app-simulation';
|
|
12
|
+
import { albumsSimulationConfig } from './albums-simulation';
|
|
13
|
+
import { carouselSimulationConfig } from './carousel-simulation';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Server-safe config map - contains only metadata, no React components
|
|
17
|
+
*/
|
|
18
|
+
export const CONFIG_MAP = {
|
|
19
|
+
app: appSimulationConfig,
|
|
20
|
+
albums: albumsSimulationConfig,
|
|
21
|
+
carousel: carouselSimulationConfig,
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
export type AppName = keyof typeof CONFIG_MAP;
|
|
25
|
+
|
|
26
|
+
// Re-export for convenience
|
|
27
|
+
export { ACTIVE_APP };
|
|
28
|
+
|
|
29
|
+
// Active config for server use
|
|
30
|
+
export const activeConfig = CONFIG_MAP[ACTIVE_APP];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-safe configuration for the app simulation.
|
|
3
|
+
* This file contains only metadata and doesn't import React components or CSS.
|
|
4
|
+
*/
|
|
5
|
+
export const appSimulationConfig = {
|
|
6
|
+
appName: 'sunpeak',
|
|
7
|
+
value: 'app',
|
|
8
|
+
label: 'My App',
|
|
9
|
+
appIcon: '🏗️',
|
|
10
|
+
userMessage: 'What do you have for me today?',
|
|
11
|
+
toolOutput: null,
|
|
12
|
+
widgetState: null,
|
|
13
|
+
toolName: 'show-app',
|
|
14
|
+
toolDescription: 'Show the Sunpeak app',
|
|
15
|
+
} as const;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-safe configuration for the carousel simulation.
|
|
3
|
+
* This file contains only metadata and doesn't import React components or CSS.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const placesData = {
|
|
7
|
+
places: [
|
|
8
|
+
{
|
|
9
|
+
id: "1",
|
|
10
|
+
name: "Lady Bird Lake",
|
|
11
|
+
rating: 4.5,
|
|
12
|
+
category: "Waterfront",
|
|
13
|
+
location: "Austin",
|
|
14
|
+
image: "https://images.unsplash.com/photo-1520950237264-dfe336995c34?w=400&h=400&fit=crop",
|
|
15
|
+
description: "Scenic lake perfect for kayaking, paddleboarding, and trails."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "2",
|
|
19
|
+
name: "Texas State Capitol",
|
|
20
|
+
rating: 4.8,
|
|
21
|
+
category: "Historic Site",
|
|
22
|
+
location: "Austin",
|
|
23
|
+
image: "https://images.unsplash.com/photo-1664231978322-4d0b45c7027b?w=400&h=400&fit=crop",
|
|
24
|
+
description: "Stunning capitol building with free tours and beautiful grounds."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "3",
|
|
28
|
+
name: "The Paramount Theatre",
|
|
29
|
+
rating: 4.7,
|
|
30
|
+
category: "Architecture",
|
|
31
|
+
location: "Austin",
|
|
32
|
+
image: "https://images.unsplash.com/photo-1583097090970-4d3b940ea1a0?w=400&h=400&fit=crop",
|
|
33
|
+
description: "Century-old performance and movie theatre in the heart of downtown Austin."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "4",
|
|
37
|
+
name: "Zilker Park",
|
|
38
|
+
rating: 4.7,
|
|
39
|
+
category: "Park",
|
|
40
|
+
location: "Austin",
|
|
41
|
+
image: "https://images.unsplash.com/photo-1563828568124-f800803ba13c?w=400&h=400&fit=crop",
|
|
42
|
+
description: "Popular park with trails, sports fields, and Barton Springs Pool."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "5",
|
|
46
|
+
name: "South Congress Avenue",
|
|
47
|
+
rating: 4.6,
|
|
48
|
+
category: "Landmark",
|
|
49
|
+
location: "Austin",
|
|
50
|
+
image: "https://images.unsplash.com/photo-1588993608283-7f0eda4438be?w=400&h=400&fit=crop",
|
|
51
|
+
description: "Vibrant street with unique shops, restaurants, and live music."
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const carouselSimulationConfig = {
|
|
57
|
+
appName: 'Splorin',
|
|
58
|
+
value: 'carousel',
|
|
59
|
+
label: 'Carousel',
|
|
60
|
+
appIcon: '✈️',
|
|
61
|
+
userMessage: 'Show me popular places to visit in Austin Texas',
|
|
62
|
+
toolOutput: placesData,
|
|
63
|
+
widgetState: null,
|
|
64
|
+
toolName: 'show-app',
|
|
65
|
+
toolDescription: 'Show popular places to visit in Austin, Texas',
|
|
66
|
+
} as const;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simulation configurations
|
|
3
|
+
*
|
|
4
|
+
* These configs contain only metadata and can be safely imported in Node.js contexts
|
|
5
|
+
* (like MCP servers) without causing issues with CSS imports or React components.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { appSimulationConfig } from './app-simulation';
|
|
9
|
+
export { carouselSimulationConfig } from './carousel-simulation';
|
|
10
|
+
export { albumsSimulationConfig } from './albums-simulation';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Simulations - DO NOT import in Node.js/MCP server contexts!
|
|
14
|
+
* These include React components and CSS imports.
|
|
15
|
+
*/
|
|
16
|
+
export { appSimulation, albumsSimulation, carouselSimulation, simulations } from './simulations';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simulations - combines apps with their simulation configs
|
|
3
|
+
*
|
|
4
|
+
* This file creates simulations by pairing production-ready apps with their
|
|
5
|
+
* server-safe configs. Each simulation is used for development and testing.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: This file imports React components and CSS. Do not import this
|
|
8
|
+
* in Node.js/MCP server contexts. Use app-configs.ts instead.
|
|
9
|
+
*
|
|
10
|
+
* To switch apps, change ACTIVE_APP in components/apps/active-app.ts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { Simulation } from "sunpeak"
|
|
14
|
+
import type { ComponentType } from "react"
|
|
15
|
+
import { App } from "../components/apps/App"
|
|
16
|
+
import { AlbumsApp } from "../components/apps/AlbumsApp"
|
|
17
|
+
import { PlacesApp } from "../components/apps/PlacesApp"
|
|
18
|
+
import { CONFIG_MAP, ACTIVE_APP } from "./app-configs"
|
|
19
|
+
|
|
20
|
+
export const appSimulation: Simulation = {
|
|
21
|
+
...CONFIG_MAP.app,
|
|
22
|
+
component: App,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const albumsSimulation: Simulation = {
|
|
26
|
+
...CONFIG_MAP.albums,
|
|
27
|
+
component: AlbumsApp,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const carouselSimulation: Simulation = {
|
|
31
|
+
...CONFIG_MAP.carousel,
|
|
32
|
+
component: PlacesApp,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const simulations = [
|
|
36
|
+
appSimulation,
|
|
37
|
+
carouselSimulation,
|
|
38
|
+
albumsSimulation,
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Static map from simulation name to simulation config and component
|
|
43
|
+
*/
|
|
44
|
+
export const APP_MAP = {
|
|
45
|
+
app: {
|
|
46
|
+
config: CONFIG_MAP.app,
|
|
47
|
+
component: App,
|
|
48
|
+
simulation: appSimulation,
|
|
49
|
+
},
|
|
50
|
+
albums: {
|
|
51
|
+
config: CONFIG_MAP.albums,
|
|
52
|
+
component: AlbumsApp,
|
|
53
|
+
simulation: albumsSimulation,
|
|
54
|
+
},
|
|
55
|
+
carousel: {
|
|
56
|
+
config: CONFIG_MAP.carousel,
|
|
57
|
+
component: PlacesApp,
|
|
58
|
+
simulation: carouselSimulation,
|
|
59
|
+
},
|
|
60
|
+
} as const satisfies Record<string, {
|
|
61
|
+
config: typeof CONFIG_MAP[keyof typeof CONFIG_MAP];
|
|
62
|
+
component: ComponentType;
|
|
63
|
+
simulation: Simulation;
|
|
64
|
+
}>;
|
|
65
|
+
|
|
66
|
+
export type AppName = keyof typeof APP_MAP;
|
|
67
|
+
|
|
68
|
+
// Re-export for convenience
|
|
69
|
+
export { ACTIVE_APP, CONFIG_MAP };
|
|
70
|
+
|
|
71
|
+
// Derived exports for convenience
|
|
72
|
+
export const activeSimulation = APP_MAP[ACTIVE_APP].simulation;
|
|
73
|
+
export const activeConfig = APP_MAP[ACTIVE_APP].config;
|
|
74
|
+
export const ActiveComponent = APP_MAP[ACTIVE_APP].component;
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"albums": [
|
|
3
|
-
{
|
|
4
|
-
"id": "summer-escape",
|
|
5
|
-
"title": "Summer Slice",
|
|
6
|
-
"cover": "https://persistent.oaistatic.com/pizzaz/pizzaz-1.png",
|
|
7
|
-
"photos": [
|
|
8
|
-
{
|
|
9
|
-
"id": "s1",
|
|
10
|
-
"title": "Waves",
|
|
11
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-2.png"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"id": "s2",
|
|
15
|
-
"title": "Palm trees",
|
|
16
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-3.png"
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"id": "s3",
|
|
20
|
-
"title": "Sunset",
|
|
21
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-6.png"
|
|
22
|
-
}
|
|
23
|
-
]
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"id": "city-lights",
|
|
27
|
-
"title": "Pepperoni Nights",
|
|
28
|
-
"cover": "https://persistent.oaistatic.com/pizzaz/pizzaz-4.png",
|
|
29
|
-
"photos": [
|
|
30
|
-
{
|
|
31
|
-
"id": "c1",
|
|
32
|
-
"title": "Downtown",
|
|
33
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-5.png"
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"id": "c2",
|
|
37
|
-
"title": "Neon",
|
|
38
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-1.png"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"id": "c3",
|
|
42
|
-
"title": "Streets",
|
|
43
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-2.png"
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"id": "into-the-woods",
|
|
49
|
-
"title": "Truffle Forest",
|
|
50
|
-
"cover": "https://persistent.oaistatic.com/pizzaz/pizzaz-3.png",
|
|
51
|
-
"photos": [
|
|
52
|
-
{
|
|
53
|
-
"id": "n1",
|
|
54
|
-
"title": "Forest path",
|
|
55
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-6.png"
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"id": "n2",
|
|
59
|
-
"title": "Misty",
|
|
60
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-4.png"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"id": "n3",
|
|
64
|
-
"title": "Waterfall",
|
|
65
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-5.png"
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"id": "pizza-tour",
|
|
71
|
-
"title": "Pizza tour",
|
|
72
|
-
"cover": "https://persistent.oaistatic.com/pizzaz/pizzaz-1.png",
|
|
73
|
-
"photos": [
|
|
74
|
-
{
|
|
75
|
-
"id": "tonys-pizza-napoletana",
|
|
76
|
-
"title": "Tony's Pizza Napoletana",
|
|
77
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-2.png"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
"id": "golden-boy-pizza",
|
|
81
|
-
"title": "Golden Boy Pizza",
|
|
82
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-3.png"
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
"id": "pizzeria-delfina-mission",
|
|
86
|
-
"title": "Pizzeria Delfina (Mission)",
|
|
87
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-6.png"
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
"id": "ragazza",
|
|
91
|
-
"title": "Ragazza",
|
|
92
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-4.png"
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
"id": "del-popolo",
|
|
96
|
-
"title": "Del Popolo",
|
|
97
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-5.png"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
"id": "square-pie-guys",
|
|
101
|
-
"title": "Square Pie Guys",
|
|
102
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-1.png"
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
"id": "zero-zero",
|
|
106
|
-
"title": "Zero Zero",
|
|
107
|
-
"url": "https://persistent.oaistatic.com/pizzaz/pizzaz-2.png"
|
|
108
|
-
}
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
]
|
|
112
|
-
}
|