sunpeak 0.1.19 โ†’ 0.1.25

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sunpeak AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,11 @@
1
+ <div align="center">
2
+ <a href="https://sunpeak.ai">
3
+ <picture>
4
+ <img alt="Sunpeak logo" src="https://sunpeak.ai/images/sunpeak_github.svg">
5
+ </picture>
6
+ </a>
7
+ </div>
8
+
1
9
  # sunpeak
2
10
 
3
11
  [![npm version](https://img.shields.io/npm/v/sunpeak.svg?style=flat-square)](https://www.npmjs.com/package/sunpeak)
@@ -7,24 +15,26 @@
7
15
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.6-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
8
16
  [![React](https://img.shields.io/badge/React-18%20%7C%2019-blue?style=flat-square&logo=react)](https://reactjs.org/)
9
17
 
10
- React library for cross-platform genAI App UIs. Supports **OpenAI ChatGPT Apps**, with pluggable architecture for **Gemini**, **Claude**, and other platforms.
18
+ React library for ChatGPT Apps. Build and test ChatGPT Apps locally with approved components.
11
19
 
12
- ![ChatGPT Simulator](./assets/chatgpt-simulator.png)
20
+ ![ChatGPT Simulator](https://sunpeak.ai/images/chatgpt-simulator.png)
13
21
 
14
22
  **Key Features:**
15
23
  - ๐Ÿ“บ ChatGPT simulator for rapid UI component development.
16
24
  - ๐Ÿ“ฑ Interface for cross-platform custom components.
17
- - ๐Ÿค [MUI](https://mui.com/material-ui/)-based components compliant with the OpenAI design system.
25
+ - ๐Ÿค [Material UI](https://mui.com/material-ui/)-based components compliant with the OpenAI design system.
18
26
  - ๐Ÿ“š Library of approved Apps.
19
27
  - ๐Ÿงช Testing framework that replicates advanced platform behavior locally.
20
28
 
21
- ## Development Quickstart
29
+ ## Quickstart
30
+
31
+ Requirements: Node (20+), pnpm (10+)
22
32
 
23
- Requirements: Node 20+, pnpm 10+
33
+ Use our `create-sunpeak` utility to scaffold your own sunpeak app:
24
34
 
25
35
  ```bash
26
- git clone https://github.com/Sunpeak-AI/sunpeak.git
27
- pnpm dev
36
+ pnpm dlx create-sunpeak my-app
37
+ cd my-app && pnpm dev
28
38
  ```
29
39
 
30
40
  ## Building Apps
@@ -77,10 +87,6 @@ export const MyApp = GenAI(({ maxHeight, colorScheme }) => (
77
87
  - ๐Ÿ”„ **Anthropic Claude** - Design system available (SDK support coming soon)
78
88
  - ๐Ÿ”ง **Custom platforms** - Implement your own platform adapter
79
89
 
80
- ### Platform Auto-Detection
81
-
82
- Sunpeak automatically detects the active platform. No configuration needed for basic usage!
83
-
84
90
  ## What's Included
85
91
 
86
92
  ### Components
@@ -89,7 +95,7 @@ Sunpeak automatically detects the active platform. No configuration needed for b
89
95
  - Platform constraints (maxHeight)
90
96
  - **Card** - Responsive card component
91
97
  - **Carousel** - Horizontal scrolling carousel
92
- - **ChatGPTSimulator** - Local development environment
98
+ - **ChatGPTSimulator** - Local development & testing environment
93
99
 
94
100
  ### Hooks
95
101
  - **usePlatformGlobal** - Platform-agnostic global state access
@@ -102,20 +108,15 @@ Sunpeak automatically detects the active platform. No configuration needed for b
102
108
 
103
109
  ### Design Systems
104
110
  - **ChatGPT** - MUI theme following OpenAI Apps SDK guidelines
105
- - **Custom** - Build your own MUI theme (see [THEMING.md](./THEMING.md))
111
+ - **Custom** - Build your own MUI theme
106
112
 
107
- **See [THEMING.md](./THEMING.md)** for creating custom design systems and complete theming documentation.
113
+ ## Contributing
108
114
 
109
- ## Deployment
115
+ We welcome your contributions!
110
116
 
111
- On pushes to `main`, Github Actions CI/CD automatically increments the version number, creates the git tag & release, and deploys to npm.
117
+ For development quickstart on this package, see [DEVELOPMENT.md](./DEVELOPMENT.md).
112
118
 
113
119
  ## Resources
114
120
 
115
121
  - [OpenAI ChatGPT Apps SDK Design Guidelines](https://developers.openai.com/apps-sdk/concepts/design-guidelines)
116
122
  - [OpenAI ChatGPT Apps SDK Examples](https://github.com/openai/openai-apps-sdk-examples)
117
- - [Theming Guide](./THEMING.md)
118
-
119
- ## License
120
-
121
- MIT
package/dist/index.cjs CHANGED
@@ -404,6 +404,7 @@ var Carousel = ({
404
404
  maxWidth = 800,
405
405
  showArrows = true,
406
406
  showEdgeGradients = true,
407
+ cardWidth: cardWidthProp,
407
408
  className,
408
409
  ...props
409
410
  }) => {
@@ -417,7 +418,16 @@ var Carousel = ({
417
418
  const displayMode = useDisplayMode();
418
419
  const theme = material.useTheme();
419
420
  const isFullscreen = displayMode === "fullscreen";
420
- const cardWidth = isFullscreen ? 340 : void 0;
421
+ const getCardWidth = () => {
422
+ if (typeof cardWidthProp === "number") {
423
+ return cardWidthProp;
424
+ }
425
+ if (typeof cardWidthProp === "object") {
426
+ return isFullscreen ? cardWidthProp.fullscreen ?? 340 : cardWidthProp.inline ?? 220;
427
+ }
428
+ return isFullscreen ? 340 : 220;
429
+ };
430
+ const cardWidth = getCardWidth();
421
431
  const checkScroll = () => {
422
432
  const el = scrollRef.current;
423
433
  if (!el) return;
@@ -501,7 +511,7 @@ var Carousel = ({
501
511
  display: "none"
502
512
  }
503
513
  },
504
- children: isFullscreen ? react.Children.map(children, (child) => /* @__PURE__ */ jsxRuntime.jsx(
514
+ children: react.Children.map(children, (child) => /* @__PURE__ */ jsxRuntime.jsx(
505
515
  material.Box,
506
516
  {
507
517
  sx: {
@@ -514,7 +524,7 @@ var Carousel = ({
514
524
  },
515
525
  children: child
516
526
  }
517
- )) : children
527
+ ))
518
528
  }
519
529
  ) }),
520
530
  showEdgeGradients && canScrollLeft && /* @__PURE__ */ jsxRuntime.jsx(
@@ -1083,10 +1093,15 @@ function ChatGPTSimulator({
1083
1093
  {
1084
1094
  sx: {
1085
1095
  minHeight: "100vh",
1096
+ width: "100vw",
1086
1097
  display: "flex",
1087
1098
  fontFamily: theme.typography.fontFamily,
1088
1099
  backgroundColor: theme.palette.background.default,
1089
- color: theme.palette.text.primary
1100
+ color: theme.palette.text.primary,
1101
+ boxSizing: "border-box",
1102
+ "@media (max-width: 768px)": {
1103
+ flexDirection: "column"
1104
+ }
1090
1105
  },
1091
1106
  children: [
1092
1107
  showControls && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1094,7 +1109,7 @@ function ChatGPTSimulator({
1094
1109
  {
1095
1110
  sx: {
1096
1111
  width: "250px",
1097
- minWidth: "250px",
1112
+ flexShrink: 0,
1098
1113
  padding: theme.spacing(5),
1099
1114
  display: "flex",
1100
1115
  flexDirection: "column",
@@ -1102,9 +1117,9 @@ function ChatGPTSimulator({
1102
1117
  overflowY: "auto",
1103
1118
  backgroundColor: theme.palette.mode === "light" ? theme.palette.background.paper : theme.palette.background.default,
1104
1119
  borderRight: `1px solid ${theme.palette.divider}`,
1120
+ boxSizing: "border-box",
1105
1121
  "@media (max-width: 768px)": {
1106
1122
  width: "100%",
1107
- minWidth: "unset",
1108
1123
  borderRight: "none",
1109
1124
  borderBottom: `1px solid ${theme.palette.divider}`,
1110
1125
  padding: theme.spacing(4)
@@ -1183,15 +1198,14 @@ function ChatGPTSimulator({
1183
1198
  {
1184
1199
  sx: {
1185
1200
  flex: 1,
1201
+ minWidth: 0,
1186
1202
  display: "flex",
1187
1203
  flexDirection: "column",
1188
- margin: "0 auto",
1189
1204
  overflowY: "auto",
1190
1205
  padding: isFullscreen ? 0 : `${theme.spacing(4)} 0 ${theme.spacing(4)} ${theme.spacing(6)}`,
1191
1206
  position: "relative",
1192
- width: bodyWidth,
1193
- maxWidth: bodyWidth,
1194
- height: isFullscreen ? "100vh" : "auto"
1207
+ height: isFullscreen ? "100vh" : "auto",
1208
+ boxSizing: "border-box"
1195
1209
  },
1196
1210
  children: [
1197
1211
  isFullscreen && /* @__PURE__ */ jsxRuntime.jsx(
@@ -1219,17 +1233,18 @@ function ChatGPTSimulator({
1219
1233
  material.Box,
1220
1234
  {
1221
1235
  sx: {
1222
- maxWidth: "48rem",
1236
+ maxWidth: bodyWidth === "100%" ? "48rem" : bodyWidth,
1223
1237
  mx: "auto",
1224
1238
  flex: 1,
1225
1239
  position: "relative",
1226
1240
  display: "flex",
1227
1241
  width: "100%",
1228
1242
  minWidth: 0,
1229
- flexDirection: "column"
1243
+ flexDirection: "column",
1244
+ boxSizing: "border-box"
1230
1245
  },
1231
1246
  children: [
1232
- /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", maxWidth: "100%", flexDirection: "column", flexGrow: 1 }, children: [
1247
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", maxWidth: "100%", flexDirection: "column", flexGrow: 1, minWidth: 0, boxSizing: "border-box" }, children: [
1233
1248
  !isFullscreen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1234
1249
  /* @__PURE__ */ jsxRuntime.jsx(
1235
1250
  material.Box,
@@ -1254,10 +1269,12 @@ function ChatGPTSimulator({
1254
1269
  borderRadius: theme.spacing(3),
1255
1270
  lineHeight: 1.5,
1256
1271
  fontSize: theme.typography.body1.fontSize,
1257
- overflow: "hidden",
1258
- minWidth: "100px",
1259
- backgroundColor: theme.palette.mode === "light" ? theme.palette.grey[100] : theme.palette.grey[800],
1260
- color: theme.palette.text.primary
1272
+ overflowWrap: "break-word",
1273
+ wordBreak: "break-word",
1274
+ minWidth: 0,
1275
+ backgroundColor: theme.palette.grey[100],
1276
+ color: theme.palette.text.primary,
1277
+ boxSizing: "border-box"
1261
1278
  },
1262
1279
  children: userMessage
1263
1280
  }
@@ -1272,12 +1289,14 @@ function ChatGPTSimulator({
1272
1289
  position: "relative",
1273
1290
  display: "flex",
1274
1291
  width: "100%",
1292
+ minWidth: 0,
1275
1293
  flexDirection: "column",
1276
1294
  alignItems: "flex-end",
1277
1295
  gap: theme.spacing(2),
1278
1296
  textAlign: "start",
1279
1297
  wordBreak: "break-word",
1280
- whiteSpace: "normal"
1298
+ whiteSpace: "normal",
1299
+ boxSizing: "border-box"
1281
1300
  },
1282
1301
  children: /* @__PURE__ */ jsxRuntime.jsx(
1283
1302
  material.Box,
@@ -1285,12 +1304,14 @@ function ChatGPTSimulator({
1285
1304
  sx: {
1286
1305
  display: "flex",
1287
1306
  width: "100%",
1307
+ minWidth: 0,
1288
1308
  flexDirection: "column",
1289
1309
  gap: theme.spacing(1),
1290
1310
  "&:empty": { display: "none" },
1291
- "&:first-of-type": { pt: "1px" }
1311
+ "&:first-of-type": { pt: "1px" },
1312
+ boxSizing: "border-box"
1292
1313
  },
1293
- children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { width: "100%", wordBreak: "break-word" }, children: [
1314
+ children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { width: "100%", minWidth: 0, wordBreak: "break-word", boxSizing: "border-box" }, children: [
1294
1315
  /* @__PURE__ */ jsxRuntime.jsxs(
1295
1316
  material.Box,
1296
1317
  {
@@ -1315,11 +1336,9 @@ function ChatGPTSimulator({
1315
1336
  {
1316
1337
  sx: {
1317
1338
  overflow: "hidden",
1318
- minWidth: "300px",
1319
- maxWidth: "100%",
1320
- "@media (max-width: 768px)": {
1321
- minWidth: "200px"
1322
- }
1339
+ width: "100%",
1340
+ minWidth: 0,
1341
+ boxSizing: "border-box"
1323
1342
  },
1324
1343
  children: renderChildren()
1325
1344
  }
@@ -1338,9 +1357,11 @@ function ChatGPTSimulator({
1338
1357
  display: "flex",
1339
1358
  flexDirection: "column",
1340
1359
  width: "100%",
1360
+ minWidth: 0,
1341
1361
  height: "100%",
1342
1362
  overflowY: "auto",
1343
- paddingBottom: "80px"
1363
+ paddingBottom: "80px",
1364
+ boxSizing: "border-box"
1344
1365
  },
1345
1366
  children: renderChildren()
1346
1367
  }
@@ -1355,9 +1376,11 @@ function ChatGPTSimulator({
1355
1376
  left: 0,
1356
1377
  right: 0,
1357
1378
  margin: `${theme.spacing(4)} 0`,
1379
+ padding: `0 ${theme.spacing(10)} 0 ${theme.spacing(4)}`,
1358
1380
  display: "flex",
1359
1381
  justifyContent: "center",
1360
- pointerEvents: "none"
1382
+ pointerEvents: "none",
1383
+ boxSizing: "border-box"
1361
1384
  },
1362
1385
  children: /* @__PURE__ */ jsxRuntime.jsx(
1363
1386
  material.TextField,
@@ -1368,9 +1391,10 @@ function ChatGPTSimulator({
1368
1391
  pointerEvents: "auto",
1369
1392
  width: "100%",
1370
1393
  maxWidth: "800px",
1394
+ boxSizing: "border-box",
1371
1395
  "& .MuiOutlinedInput-root": {
1372
1396
  borderRadius: theme.spacing(8),
1373
- backgroundColor: theme.palette.mode === "light" ? theme.palette.grey[100] : theme.palette.grey[800],
1397
+ backgroundColor: theme.palette.grey[100],
1374
1398
  "& fieldset": {
1375
1399
  borderColor: theme.palette.mode === "light" ? theme.palette.grey[300] : theme.palette.grey[700]
1376
1400
  },