sunpeak 0.5.41 → 0.6.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 +1 -0
- package/bin/commands/build.mjs +4 -4
- package/bin/sunpeak.js +129 -6
- package/dist/chatgpt/conversation.d.ts +2 -1
- package/dist/chatgpt/globals.css +7 -0
- package/dist/index.cjs +99 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +99 -12
- package/dist/index.js.map +1 -1
- package/dist/mcp/entry.cjs +2 -2
- package/dist/mcp/entry.cjs.map +1 -1
- package/dist/mcp/entry.js +2 -2
- 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-DpriZ4jT.cjs → server-CQGbJWbk.cjs} +17 -8
- package/dist/{server-DpriZ4jT.cjs.map → server-CQGbJWbk.cjs.map} +1 -1
- package/dist/{server-SBlanUcf.js → server-DGCvp1RA.js} +17 -8
- package/dist/{server-SBlanUcf.js.map → server-DGCvp1RA.js.map} +1 -1
- package/dist/style.css +101 -11
- package/package.json +1 -1
- package/template/.sunpeak/dev.tsx +3 -3
- package/template/README.md +3 -3
- package/template/dist/chatgpt/albums.js +2 -2
- package/template/dist/chatgpt/carousel.js +1 -1
- package/template/dist/chatgpt/counter.js +1 -1
- package/template/node_modules/.vite/deps/_metadata.json +17 -17
- package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/template/src/components/album/album-carousel.test.tsx +84 -0
- package/template/src/components/album/album-carousel.tsx +168 -0
- package/template/src/components/album/albums.test.tsx +2 -2
- package/template/src/components/album/albums.tsx +3 -3
- package/template/src/components/album/index.ts +1 -0
- package/template/src/components/carousel/index.ts +1 -0
- package/template/src/components/index.ts +0 -2
- package/template/src/{components/resources → resources}/albums-resource.test.tsx +1 -1
- package/template/src/{components/resources → resources}/albums-resource.tsx +1 -1
- package/template/src/{components/resources → resources}/carousel-resource.test.tsx +1 -4
- package/template/src/{components/resources → resources}/carousel-resource.tsx +1 -2
- package/template/src/components/card/index.ts +0 -1
- /package/template/src/components/{card → carousel}/card.test.tsx +0 -0
- /package/template/src/components/{card → carousel}/card.tsx +0 -0
- /package/template/src/{components/resources → resources}/counter-resource.test.tsx +0 -0
- /package/template/src/{components/resources → resources}/counter-resource.tsx +0 -0
- /package/template/src/{components/resources → resources}/index.ts +0 -0
package/README.md
CHANGED
|
@@ -21,6 +21,7 @@ Quickstart, build, test, and ship your ChatGPT App locally!
|
|
|
21
21
|
|
|
22
22
|
[Demo (Hosted)](https://sunpeak.ai/#simulator) ~
|
|
23
23
|
[Demo (Video)](https://d10djik02wlf6x.cloudfront.net/sunpeak-demo-prod.mp4) ~
|
|
24
|
+
[Discord (NEW)](https://discord.gg/FB2QNXqRnw) ~
|
|
24
25
|
[Documentation](https://docs.sunpeak.ai/) ~
|
|
25
26
|
[GitHub](https://github.com/Sunpeak-AI/sunpeak)
|
|
26
27
|
|
package/bin/commands/build.mjs
CHANGED
|
@@ -26,12 +26,12 @@ export async function build(projectRoot = process.cwd()) {
|
|
|
26
26
|
const distDir = path.join(projectRoot, 'dist/chatgpt');
|
|
27
27
|
const buildDir = path.join(projectRoot, 'dist/build-output');
|
|
28
28
|
const tempDir = path.join(projectRoot, '.tmp');
|
|
29
|
-
const resourcesDir = path.join(projectRoot, 'src/
|
|
29
|
+
const resourcesDir = path.join(projectRoot, 'src/resources');
|
|
30
30
|
const templateFile = path.join(projectRoot, 'src/index-resource.tsx');
|
|
31
31
|
|
|
32
32
|
// Validate project structure
|
|
33
33
|
if (!existsSync(resourcesDir)) {
|
|
34
|
-
console.error('Error: src/
|
|
34
|
+
console.error('Error: src/resources directory not found');
|
|
35
35
|
console.error('Expected location: ' + resourcesDir);
|
|
36
36
|
console.error('\nThe build command expects the standard Sunpeak project structure.');
|
|
37
37
|
console.error('If you have customized your project structure, you may need to use');
|
|
@@ -106,7 +106,7 @@ export async function build(projectRoot = process.cwd()) {
|
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
if (resourceFiles.length === 0) {
|
|
109
|
-
console.error('Error: No resource files found in src/
|
|
109
|
+
console.error('Error: No resource files found in src/resources/');
|
|
110
110
|
console.error('Resource files should be named like: counter-resource.tsx');
|
|
111
111
|
process.exit(1);
|
|
112
112
|
}
|
|
@@ -144,7 +144,7 @@ export async function build(projectRoot = process.cwd()) {
|
|
|
144
144
|
|
|
145
145
|
// Create entry file from template in temp directory
|
|
146
146
|
const entryContent = template
|
|
147
|
-
.replace('// RESOURCE_IMPORT', `import { ${componentName} } from '../src/
|
|
147
|
+
.replace('// RESOURCE_IMPORT', `import { ${componentName} } from '../src/resources/${componentFile}';`)
|
|
148
148
|
.replace('// RESOURCE_MOUNT', `createRoot(root).render(<${componentName} />);`);
|
|
149
149
|
|
|
150
150
|
const entryPath = path.join(projectRoot, entry);
|
package/bin/sunpeak.js
CHANGED
|
@@ -27,7 +27,81 @@ function checkPackageJson() {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
function parseResourcesInput(input) {
|
|
31
|
+
const VALID_RESOURCES = ['albums', 'carousel', 'counter'];
|
|
32
|
+
|
|
33
|
+
// If no input, return all resources
|
|
34
|
+
if (!input || input.trim() === '') {
|
|
35
|
+
return VALID_RESOURCES;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Split by comma or space and trim
|
|
39
|
+
const tokens = input
|
|
40
|
+
.toLowerCase()
|
|
41
|
+
.split(/[,\s]+/)
|
|
42
|
+
.map((s) => s.trim())
|
|
43
|
+
.filter((s) => s.length > 0);
|
|
44
|
+
|
|
45
|
+
// Validate tokens
|
|
46
|
+
const invalid = tokens.filter((t) => !VALID_RESOURCES.includes(t));
|
|
47
|
+
if (invalid.length > 0) {
|
|
48
|
+
console.error(`Error: Invalid resource(s): ${invalid.join(', ')}`);
|
|
49
|
+
console.error(`Valid resources are: ${VALID_RESOURCES.join(', ')}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Remove duplicates
|
|
54
|
+
return [...new Set(tokens)];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function updateIndexFiles(targetDir, selectedResources) {
|
|
58
|
+
// Map resource names to their component/export names
|
|
59
|
+
const resourceMap = {
|
|
60
|
+
albums: { component: 'album', resourceClass: 'AlbumsResource', simulation: 'albums' },
|
|
61
|
+
carousel: { component: 'carousel', resourceClass: 'CarouselResource', simulation: 'carousel' },
|
|
62
|
+
counter: { component: null, resourceClass: 'CounterResource', simulation: 'counter' },
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Update components/index.ts
|
|
66
|
+
const componentsIndexPath = join(targetDir, 'src', 'components', 'index.ts');
|
|
67
|
+
const componentExports = selectedResources
|
|
68
|
+
.map((r) => resourceMap[r].component)
|
|
69
|
+
.filter((comp) => comp !== null) // Filter out null components
|
|
70
|
+
.filter((v, i, a) => a.indexOf(v) === i) // Remove duplicates
|
|
71
|
+
.map((comp) => `export * from './${comp}';`)
|
|
72
|
+
.join('\n');
|
|
73
|
+
writeFileSync(componentsIndexPath, componentExports + '\n');
|
|
74
|
+
|
|
75
|
+
// Update resources/index.ts
|
|
76
|
+
const resourcesIndexPath = join(targetDir, 'src', 'resources', 'index.ts');
|
|
77
|
+
const resourceExports = selectedResources
|
|
78
|
+
.map((r) => `export { ${resourceMap[r].resourceClass} } from './${r}-resource';`)
|
|
79
|
+
.join('\n');
|
|
80
|
+
writeFileSync(resourcesIndexPath, resourceExports + '\n');
|
|
81
|
+
|
|
82
|
+
// Update simulations/index.ts
|
|
83
|
+
const simulationsIndexPath = join(targetDir, 'src', 'simulations', 'index.ts');
|
|
84
|
+
const simulationImports = selectedResources
|
|
85
|
+
.map((r) => `import { ${r}Simulation } from './${r}-simulation.js';`)
|
|
86
|
+
.join('\n');
|
|
87
|
+
const simulationExports = selectedResources.map((r) => ` ${r}: ${r}Simulation,`).join('\n');
|
|
88
|
+
const simulationsContent = `/**
|
|
89
|
+
* Server-safe simulation configurations
|
|
90
|
+
*
|
|
91
|
+
* This file contains only metadata and can be safely imported in Node.js contexts
|
|
92
|
+
* (like MCP servers) without causing issues with CSS imports or React components.
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
${simulationImports}
|
|
96
|
+
|
|
97
|
+
export const SIMULATIONS = {
|
|
98
|
+
${simulationExports}
|
|
99
|
+
} as const;
|
|
100
|
+
`;
|
|
101
|
+
writeFileSync(simulationsIndexPath, simulationsContent);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function init(projectName, resourcesArg) {
|
|
31
105
|
if (!projectName) {
|
|
32
106
|
projectName = await prompt('☀️ 🏔️ Project name [my-app]: ');
|
|
33
107
|
if (!projectName) {
|
|
@@ -40,6 +114,16 @@ async function init(projectName) {
|
|
|
40
114
|
process.exit(1);
|
|
41
115
|
}
|
|
42
116
|
|
|
117
|
+
// Use resources from args or ask for them
|
|
118
|
+
let resourcesInput;
|
|
119
|
+
if (resourcesArg) {
|
|
120
|
+
resourcesInput = resourcesArg;
|
|
121
|
+
console.log(`☀️ 🏔️ Resources: ${resourcesArg}`);
|
|
122
|
+
} else {
|
|
123
|
+
resourcesInput = await prompt('☀️ 🏔️ Resources (UIs) to include [albums, carousel, counter]: ');
|
|
124
|
+
}
|
|
125
|
+
const selectedResources = parseResourcesInput(resourcesInput);
|
|
126
|
+
|
|
43
127
|
const targetDir = join(process.cwd(), projectName);
|
|
44
128
|
|
|
45
129
|
if (existsSync(targetDir)) {
|
|
@@ -53,11 +137,44 @@ async function init(projectName) {
|
|
|
53
137
|
|
|
54
138
|
mkdirSync(targetDir, { recursive: true });
|
|
55
139
|
|
|
140
|
+
// Map resource names to their component directory names
|
|
141
|
+
const resourceComponentMap = {
|
|
142
|
+
albums: 'album',
|
|
143
|
+
carousel: 'carousel',
|
|
144
|
+
counter: null, // Counter doesn't have a component directory
|
|
145
|
+
};
|
|
146
|
+
|
|
56
147
|
cpSync(templateDir, targetDir, {
|
|
57
148
|
recursive: true,
|
|
58
149
|
filter: (src) => {
|
|
59
150
|
const name = basename(src);
|
|
60
|
-
|
|
151
|
+
|
|
152
|
+
// Skip node_modules and lock file
|
|
153
|
+
if (name === 'node_modules' || name === 'pnpm-lock.yaml') {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Filter resource files based on selection
|
|
158
|
+
const VALID_RESOURCES = ['albums', 'carousel', 'counter'];
|
|
159
|
+
const excludedResources = VALID_RESOURCES.filter((r) => !selectedResources.includes(r));
|
|
160
|
+
|
|
161
|
+
for (const resource of excludedResources) {
|
|
162
|
+
// Skip resource files
|
|
163
|
+
if (name === `${resource}-resource.tsx` || name === `${resource}-resource.test.tsx`) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
// Skip simulation files
|
|
167
|
+
if (name === `${resource}-simulation.ts`) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
// Skip component directories (map resource name to component dir name)
|
|
171
|
+
const componentDirName = resourceComponentMap[resource];
|
|
172
|
+
if (componentDirName && src.includes('/components/') && name === componentDirName) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return true;
|
|
61
178
|
},
|
|
62
179
|
});
|
|
63
180
|
|
|
@@ -88,6 +205,9 @@ async function init(projectName) {
|
|
|
88
205
|
|
|
89
206
|
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
90
207
|
|
|
208
|
+
// Update index.ts files based on selected resources
|
|
209
|
+
updateIndexFiles(targetDir, selectedResources);
|
|
210
|
+
|
|
91
211
|
console.log(`
|
|
92
212
|
Done! To get started:
|
|
93
213
|
|
|
@@ -119,7 +239,7 @@ const [, , command, ...args] = process.argv;
|
|
|
119
239
|
|
|
120
240
|
switch (command) {
|
|
121
241
|
case 'new':
|
|
122
|
-
await init(args[0]);
|
|
242
|
+
await init(args[0], args[1]);
|
|
123
243
|
break;
|
|
124
244
|
|
|
125
245
|
case 'dev':
|
|
@@ -149,8 +269,11 @@ const [, , command, ...args] = process.argv;
|
|
|
149
269
|
☀️ 🏔️ sunpeak - The MCP App framework
|
|
150
270
|
|
|
151
271
|
Usage:
|
|
152
|
-
npx sunpeak new [name] Create a new project (no install needed)
|
|
153
|
-
pnpm dlx sunpeak new
|
|
272
|
+
npx sunpeak new [name] [resources] Create a new project (no install needed)
|
|
273
|
+
pnpm dlx sunpeak new Alternative with pnpm
|
|
274
|
+
|
|
275
|
+
Resources: albums, carousel, counter (comma/space separated, or "all")
|
|
276
|
+
Example: npx sunpeak new my-app "albums,carousel"
|
|
154
277
|
|
|
155
278
|
Inside your project, use npm scripts:
|
|
156
279
|
pnpm dev Start development server
|
|
@@ -159,7 +282,7 @@ Inside your project, use npm scripts:
|
|
|
159
282
|
pnpm test Run tests
|
|
160
283
|
|
|
161
284
|
Direct CLI commands (when sunpeak is installed):
|
|
162
|
-
sunpeak new [name]
|
|
285
|
+
sunpeak new [name] [resources] Create a new project
|
|
163
286
|
sunpeak dev Start dev server
|
|
164
287
|
sunpeak build Build resources
|
|
165
288
|
sunpeak mcp Start MCP server
|
|
@@ -6,6 +6,7 @@ interface ConversationProps {
|
|
|
6
6
|
appName?: string;
|
|
7
7
|
appIcon?: string;
|
|
8
8
|
userMessage?: string;
|
|
9
|
+
resourceMeta?: Record<string, unknown>;
|
|
9
10
|
}
|
|
10
|
-
export declare function Conversation({ children, screenWidth, appName, appIcon, userMessage, }: ConversationProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare function Conversation({ children, screenWidth, appName, appIcon, userMessage, resourceMeta, }: ConversationProps): import("react/jsx-runtime").JSX.Element;
|
|
11
12
|
export {};
|
package/dist/chatgpt/globals.css
CHANGED
|
@@ -30,3 +30,10 @@
|
|
|
30
30
|
@utility bg-sidebar {
|
|
31
31
|
background-color: var(--color-surface-secondary);
|
|
32
32
|
}
|
|
33
|
+
|
|
34
|
+
/* Ensure Select dropdowns appear above mobile drawer overlay when simulator is present */
|
|
35
|
+
@layer components {
|
|
36
|
+
:has(.sunpeak-simulator-root) :where([role="listbox"], [data-radix-select-content], [data-radix-popper-content-wrapper]) {
|
|
37
|
+
z-index: 100 !important;
|
|
38
|
+
}
|
|
39
|
+
}
|
package/dist/index.cjs
CHANGED
|
@@ -5706,6 +5706,7 @@ const preventDefaultHandler = (evt) => {
|
|
|
5706
5706
|
};
|
|
5707
5707
|
const Check = (props) => jsxRuntime.jsx("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", fill: "currentColor", ...props, children: jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M18.063 5.674a1 1 0 0 1 .263 1.39l-7.5 11a1 1 0 0 1-1.533.143l-4.5-4.5a1 1 0 1 1 1.414-1.414l3.647 3.647 6.82-10.003a1 1 0 0 1 1.39-.263Z", clipRule: "evenodd" }) });
|
|
5708
5708
|
const ChevronDownVector = (props) => jsxRuntime.jsx("svg", { width: "1em", height: "1em", viewBox: "0 0 16 9", fill: "currentColor", ...props, children: jsxRuntime.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M0.292893 0.292893C0.683418 -0.0976311 1.31658 -0.0976311 1.70711 0.292893L8 6.58579L14.2929 0.292894C14.6834 -0.0976305 15.3166 -0.0976304 15.7071 0.292894C16.0976 0.683418 16.0976 1.31658 15.7071 1.70711L8.70711 8.70711C8.31658 9.09763 7.68342 9.09763 7.29289 8.70711L0.292893 1.70711C-0.0976311 1.31658 -0.0976311 0.683417 0.292893 0.292893Z" }) });
|
|
5709
|
+
const ChevronRight = (props) => jsxRuntime.jsx("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", fill: "currentColor", ...props, children: jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M8.293 4.293a1 1 0 0 1 1.414 0l7 7a1 1 0 0 1 0 1.414l-7 7a1 1 0 0 1-1.414-1.414L14.586 12 8.293 5.707a1 1 0 0 1 0-1.414Z", clipRule: "evenodd" }) });
|
|
5709
5710
|
const CloseBold = (props) => jsxRuntime.jsx("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", fill: "currentColor", ...props, children: jsxRuntime.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M5.83071 5.83077C6.33839 5.32309 7.16151 5.32309 7.66919 5.83077L12 10.1615L16.3307 5.83077C16.8384 5.32309 17.6615 5.32309 18.1692 5.83077C18.6769 6.33845 18.6769 7.16157 18.1692 7.66925L13.8384 12L18.1692 16.3308C18.6769 16.8385 18.6769 17.6616 18.1692 18.1693C17.6615 18.6769 16.8384 18.6769 16.3307 18.1693L12 13.8385L7.66919 18.1693C7.16151 18.6769 6.33839 18.6769 5.83071 18.1693C5.32303 17.6616 5.32303 16.8385 5.83071 16.3308L10.1615 12L5.83071 7.66925C5.32303 7.16157 5.32303 6.33845 5.83071 5.83077Z", fill: "currentColor" }) });
|
|
5710
5711
|
const DropdownVector = (props) => jsxRuntime.jsx("svg", { width: "1em", height: "1em", viewBox: "0 0 10 16", fill: "currentColor", ...props, children: jsxRuntime.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.34151 0.747423C4.71854 0.417526 5.28149 0.417526 5.65852 0.747423L9.65852 4.24742C10.0742 4.61111 10.1163 5.24287 9.75259 5.6585C9.38891 6.07414 8.75715 6.11626 8.34151 5.75258L5.00001 2.82877L1.65852 5.75258C1.24288 6.11626 0.61112 6.07414 0.247438 5.6585C-0.116244 5.24287 -0.0741267 4.61111 0.34151 4.24742L4.34151 0.747423ZM0.246065 10.3578C0.608879 9.94139 1.24055 9.89795 1.65695 10.2608L5.00001 13.1737L8.34308 10.2608C8.75948 9.89795 9.39115 9.94139 9.75396 10.3578C10.1168 10.7742 10.0733 11.4058 9.65695 11.7687L5.65695 15.2539C5.28043 15.582 4.7196 15.582 4.34308 15.2539L0.343082 11.7687C-0.0733128 11.4058 -0.116749 10.7742 0.246065 10.3578Z" }) });
|
|
5711
5712
|
const Info = (props) => jsxRuntime.jsxs("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", fill: "currentColor", ...props, children: [jsxRuntime.jsx("path", { d: "M13 12a1 1 0 1 0-2 0v4a1 1 0 1 0 2 0v-4Zm-1-2.5A1.25 1.25 0 1 0 12 7a1.25 1.25 0 0 0 0 2.5Z" }), jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z", clipRule: "evenodd" })] });
|
|
@@ -7378,12 +7379,78 @@ const Segment = ({ children, ...restProps }) => {
|
|
|
7378
7379
|
};
|
|
7379
7380
|
SegmentedControl.Option = Segment;
|
|
7380
7381
|
function SimpleSidebar({ children, controls }) {
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7382
|
+
const [isDrawerOpen, setIsDrawerOpen] = React__namespace.useState(false);
|
|
7383
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sunpeak-simulator-root flex h-screen w-full overflow-hidden relative", children: [
|
|
7384
|
+
isDrawerOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7385
|
+
"div",
|
|
7386
|
+
{
|
|
7387
|
+
className: "md:hidden fixed inset-0 bg-black/50 z-40 pointer-events-auto",
|
|
7388
|
+
onClick: (e) => {
|
|
7389
|
+
if (e.target === e.currentTarget) {
|
|
7390
|
+
setIsDrawerOpen(false);
|
|
7391
|
+
}
|
|
7392
|
+
}
|
|
7393
|
+
}
|
|
7394
|
+
),
|
|
7395
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7396
|
+
"aside",
|
|
7397
|
+
{
|
|
7398
|
+
className: `
|
|
7399
|
+
w-56 flex flex-col border-r border-subtle bg-sidebar
|
|
7400
|
+
md:relative md:z-auto
|
|
7401
|
+
max-md:fixed max-md:inset-y-0 max-md:left-0 max-md:z-[100]
|
|
7402
|
+
max-md:transition-transform max-md:duration-300
|
|
7403
|
+
${isDrawerOpen ? "max-md:translate-x-0" : "max-md:-translate-x-full"}
|
|
7404
|
+
`,
|
|
7405
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto min-h-0 px-3 pb-3 pt-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
7406
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between sticky top-0 bg-sidebar z-10 py-2", children: [
|
|
7407
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xs font-semibold", children: "Controls" }),
|
|
7408
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7409
|
+
"button",
|
|
7410
|
+
{
|
|
7411
|
+
onClick: () => setIsDrawerOpen(false),
|
|
7412
|
+
className: "md:hidden text-secondary hover:text-primary transition-colors p-1",
|
|
7413
|
+
type: "button",
|
|
7414
|
+
"aria-label": "Close sidebar",
|
|
7415
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7416
|
+
"svg",
|
|
7417
|
+
{
|
|
7418
|
+
width: "16",
|
|
7419
|
+
height: "16",
|
|
7420
|
+
viewBox: "0 0 16 16",
|
|
7421
|
+
fill: "none",
|
|
7422
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
7423
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7424
|
+
"path",
|
|
7425
|
+
{
|
|
7426
|
+
d: "M12 4L4 12M4 4L12 12",
|
|
7427
|
+
stroke: "currentColor",
|
|
7428
|
+
strokeWidth: "2",
|
|
7429
|
+
strokeLinecap: "round"
|
|
7430
|
+
}
|
|
7431
|
+
)
|
|
7432
|
+
}
|
|
7433
|
+
)
|
|
7434
|
+
}
|
|
7435
|
+
)
|
|
7436
|
+
] }),
|
|
7437
|
+
controls
|
|
7438
|
+
] }) }) })
|
|
7439
|
+
}
|
|
7440
|
+
),
|
|
7441
|
+
/* @__PURE__ */ jsxRuntime.jsxs("main", { className: "flex-1 overflow-auto relative", children: [
|
|
7442
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7443
|
+
"button",
|
|
7444
|
+
{
|
|
7445
|
+
onClick: () => setIsDrawerOpen(true),
|
|
7446
|
+
className: "md:hidden fixed top-18 left-0 z-30 bg-sidebar border-r border-t border-b border-subtle rounded-r-md p-2 shadow-lg hover:bg-primary/10 transition-colors",
|
|
7447
|
+
type: "button",
|
|
7448
|
+
"aria-label": "Open sidebar",
|
|
7449
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, {})
|
|
7450
|
+
}
|
|
7451
|
+
),
|
|
7452
|
+
children
|
|
7453
|
+
] })
|
|
7387
7454
|
] });
|
|
7388
7455
|
}
|
|
7389
7456
|
function SidebarControl({ label, children }) {
|
|
@@ -7505,9 +7572,10 @@ const SCREEN_WIDTHS = {
|
|
|
7505
7572
|
function Conversation({
|
|
7506
7573
|
children,
|
|
7507
7574
|
screenWidth,
|
|
7508
|
-
appName = "Sunpeak
|
|
7575
|
+
appName = "Sunpeak",
|
|
7509
7576
|
appIcon,
|
|
7510
|
-
userMessage = "What have you got for me today?"
|
|
7577
|
+
userMessage = "What have you got for me today?",
|
|
7578
|
+
resourceMeta
|
|
7511
7579
|
}) {
|
|
7512
7580
|
const displayMode = useDisplayMode() ?? "inline";
|
|
7513
7581
|
const api = useWidgetAPI();
|
|
@@ -7541,7 +7609,25 @@ function Conversation({
|
|
|
7541
7609
|
}
|
|
7542
7610
|
) }),
|
|
7543
7611
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-primary flex items-center justify-center text-base", children: appName }),
|
|
7544
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end"
|
|
7612
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7613
|
+
Button,
|
|
7614
|
+
{
|
|
7615
|
+
variant: "outline",
|
|
7616
|
+
color: "primary",
|
|
7617
|
+
className: "bg-token-bg-primary",
|
|
7618
|
+
onClick: () => {
|
|
7619
|
+
const widgetDomain = resourceMeta == null ? void 0 : resourceMeta["openai/widgetDomain"];
|
|
7620
|
+
if ((api == null ? void 0 : api.openExternal) && widgetDomain) {
|
|
7621
|
+
api.openExternal({ href: widgetDomain });
|
|
7622
|
+
}
|
|
7623
|
+
},
|
|
7624
|
+
children: [
|
|
7625
|
+
appIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "me-2 h-4 w-4 flex items-center justify-center", children: appIcon }),
|
|
7626
|
+
"Open in ",
|
|
7627
|
+
appName
|
|
7628
|
+
]
|
|
7629
|
+
}
|
|
7630
|
+
) })
|
|
7545
7631
|
] }),
|
|
7546
7632
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full max-w-full overflow-auto", children }) }),
|
|
7547
7633
|
/* @__PURE__ */ jsxRuntime.jsx("footer", { className: "bg-surface", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[48rem] mx-auto px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7616,7 +7702,7 @@ function Conversation({
|
|
|
7616
7702
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-col gap-1 empty:hidden", children: displayMode === "pip" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7617
7703
|
"div",
|
|
7618
7704
|
{
|
|
7619
|
-
className: "no-scrollbar @w-xl/main:top-4 fixed start-4 end-4 top-
|
|
7705
|
+
className: "no-scrollbar @w-xl/main:top-4 fixed start-4 end-4 top-12 z-50 mx-auto max-w-[40rem] lg:max-w-[48rem] sm:start-0 sm:end-0 sm:top-[3.25rem] sm:w-full overflow-visible",
|
|
7620
7706
|
style: { maxHeight: "480px" },
|
|
7621
7707
|
children: [
|
|
7622
7708
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7633,7 +7719,7 @@ function Conversation({
|
|
|
7633
7719
|
children: /* @__PURE__ */ jsxRuntime.jsx(CloseBold, { className: "h-4 w-4" })
|
|
7634
7720
|
}
|
|
7635
7721
|
),
|
|
7636
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden h-full rounded-2xl sm:rounded-3xl shadow-[0px_0px_0px_1px_#fff3,0px_6px_20px_rgba(0,0,0,0.1)] md:-mx-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full max-w-full overflow-auto bg-[#212121]", children }) })
|
|
7722
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden h-full rounded-2xl sm:rounded-3xl shadow-[0px_0px_0px_1px_#fff3,0px_6px_20px_rgba(0,0,0,0.1)] md:-mx-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full max-w-full overflow-auto bg-white dark:bg-[#212121]", children }) })
|
|
7637
7723
|
]
|
|
7638
7724
|
}
|
|
7639
7725
|
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "no-scrollbar relative mb-2 @w-sm/main:w-full mx-0 max-sm:-mx-[1rem] max-sm:w-[100cqw] max-sm:overflow-hidden overflow-visible", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden h-full", children }) }) })
|
|
@@ -7850,7 +7936,7 @@ const DEFAULT_DISPLAY_MODE = "inline";
|
|
|
7850
7936
|
function ChatGPTSimulator({
|
|
7851
7937
|
children,
|
|
7852
7938
|
simulations = [],
|
|
7853
|
-
appName = "Sunpeak
|
|
7939
|
+
appName = "Sunpeak",
|
|
7854
7940
|
appIcon
|
|
7855
7941
|
}) {
|
|
7856
7942
|
const [screenWidth, setScreenWidth] = React__namespace.useState("full");
|
|
@@ -8344,6 +8430,7 @@ function ChatGPTSimulator({
|
|
|
8344
8430
|
appName,
|
|
8345
8431
|
appIcon,
|
|
8346
8432
|
userMessage,
|
|
8433
|
+
resourceMeta: selectedSim == null ? void 0 : selectedSim.resource._meta,
|
|
8347
8434
|
children: content
|
|
8348
8435
|
},
|
|
8349
8436
|
selectedKey
|