sunpeak 0.8.6 → 0.9.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 (77) hide show
  1. package/bin/commands/build.mjs +3 -3
  2. package/bin/commands/pull.mjs +2 -2
  3. package/bin/sunpeak.js +8 -6
  4. package/dist/chatgpt/chatgpt-simulator.d.ts +1 -2
  5. package/dist/chatgpt/index.cjs +9 -0
  6. package/dist/chatgpt/index.cjs.map +1 -0
  7. package/dist/chatgpt/index.d.ts +3 -1
  8. package/dist/chatgpt/index.js +9 -0
  9. package/dist/chatgpt/index.js.map +1 -0
  10. package/dist/chatgpt/simulator-url.d.ts +127 -0
  11. package/dist/index.cjs +39 -8448
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.js +58 -8466
  14. package/dist/index.js.map +1 -1
  15. package/dist/mcp/entry.cjs +2 -1
  16. package/dist/mcp/entry.cjs.map +1 -1
  17. package/dist/mcp/entry.js +2 -1
  18. package/dist/mcp/entry.js.map +1 -1
  19. package/dist/mcp/index.cjs +1 -1
  20. package/dist/mcp/index.d.ts +1 -1
  21. package/dist/mcp/index.js +1 -1
  22. package/dist/mcp/server.d.ts +1 -1
  23. package/dist/mcp/types.d.ts +3 -9
  24. package/dist/{server-DVmTC-SF.js → server-310A1k9o.js} +2 -2
  25. package/dist/{server-DVmTC-SF.js.map → server-310A1k9o.js.map} +1 -1
  26. package/dist/{server-B9YgCQdS.cjs → server-CSybLAYo.cjs} +2 -2
  27. package/dist/{server-B9YgCQdS.cjs.map → server-CSybLAYo.cjs.map} +1 -1
  28. package/dist/simulator-url-CG8lAAC3.cjs +8545 -0
  29. package/dist/simulator-url-CG8lAAC3.cjs.map +1 -0
  30. package/dist/simulator-url-CexnaL-e.js +8529 -0
  31. package/dist/simulator-url-CexnaL-e.js.map +1 -0
  32. package/dist/style.css +5872 -5894
  33. package/dist/types/simulation.d.ts +6 -32
  34. package/package.json +7 -3
  35. package/template/.sunpeak/dev.tsx +8 -7
  36. package/template/README.md +5 -5
  37. package/template/dist/albums.js +1 -1
  38. package/template/dist/albums.json +1 -1
  39. package/template/dist/carousel.js +1 -1
  40. package/template/dist/carousel.json +1 -1
  41. package/template/dist/map.js +1 -1
  42. package/template/dist/map.json +1 -1
  43. package/template/dist/review.js +2 -2
  44. package/template/dist/review.json +1 -1
  45. package/template/node_modules/.bin/playwright +21 -0
  46. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +3 -3
  47. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +4 -4
  48. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +20 -20
  49. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js +3 -3
  50. package/template/node_modules/.vite/deps/_metadata.json +38 -38
  51. package/template/node_modules/.vite/deps/{chunk-SPYXUHEY.js → chunk-N6DVYEXK.js} +8 -8
  52. package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  53. package/template/package.json +3 -1
  54. package/template/playwright.config.ts +26 -0
  55. package/template/src/resources/index.ts +4 -4
  56. package/template/src/resources/map-resource.test.tsx +95 -0
  57. package/template/src/resources/review-resource.test.tsx +538 -0
  58. package/template/src/resources/review-resource.tsx +6 -1
  59. package/template/src/simulations/albums-show-simulation.json +1 -1
  60. package/template/src/simulations/carousel-show-simulation.json +1 -1
  61. package/template/src/simulations/map-show-simulation.json +1 -1
  62. package/template/src/simulations/review-diff-simulation.json +1 -1
  63. package/template/src/simulations/review-post-simulation.json +1 -1
  64. package/template/src/simulations/review-purchase-simulation.json +1 -1
  65. package/template/test-results/.last-run.json +4 -0
  66. package/template/tests/e2e/albums.spec.ts +120 -0
  67. package/template/tests/e2e/carousel.spec.ts +127 -0
  68. package/template/tests/e2e/map.spec.ts +188 -0
  69. package/template/tests/e2e/review.spec.ts +245 -0
  70. package/template/vitest.config.ts +1 -0
  71. package/template/dist/counter.js +0 -49
  72. package/template/dist/counter.json +0 -15
  73. package/template/src/resources/counter-resource.json +0 -12
  74. package/template/src/resources/counter-resource.test.tsx +0 -116
  75. package/template/src/resources/counter-resource.tsx +0 -101
  76. package/template/src/simulations/counter-show-simulation.json +0 -20
  77. /package/template/node_modules/.vite/deps/{chunk-SPYXUHEY.js.map → chunk-N6DVYEXK.js.map} +0 -0
@@ -87,10 +87,10 @@ export async function build(projectRoot = process.cwd()) {
87
87
  const resourceFiles = readdirSync(resourcesDir)
88
88
  .filter(file => file.endsWith('-resource.tsx'))
89
89
  .map(file => {
90
- // Extract kebab-case name: 'counter-resource.tsx' -> 'counter'
90
+ // Extract kebab-case name: 'review-resource.tsx' -> 'review'
91
91
  const kebabName = file.replace('-resource.tsx', '');
92
92
 
93
- // Convert kebab-case to PascalCase: 'counter' -> 'Counter', 'my-widget' -> 'MyWidget'
93
+ // Convert kebab-case to PascalCase: 'review' -> 'Review', 'my-widget' -> 'MyWidget'
94
94
  const pascalName = kebabName
95
95
  .split('-')
96
96
  .map(word => word.charAt(0).toUpperCase() + word.slice(1))
@@ -107,7 +107,7 @@ export async function build(projectRoot = process.cwd()) {
107
107
 
108
108
  if (resourceFiles.length === 0) {
109
109
  console.error('Error: No resource files found in src/resources/');
110
- console.error('Resource files should be named like: counter-resource.tsx');
110
+ console.error('Resource files should be named like: review-resource.tsx');
111
111
  process.exit(1);
112
112
  }
113
113
 
@@ -111,7 +111,7 @@ Options:
111
111
 
112
112
  Examples:
113
113
  sunpeak pull -r myorg/my-app -t prod Pull all resources tagged "prod"
114
- sunpeak pull -r myorg/my-app -t prod -n counter Pull only the "counter" resource
114
+ sunpeak pull -r myorg/my-app -t prod -n review Pull only the "review" resource
115
115
  sunpeak pull -r myorg/my-app -t v1.0.0 Pull a specific version
116
116
  `);
117
117
  return;
@@ -247,7 +247,7 @@ Options:
247
247
 
248
248
  Examples:
249
249
  sunpeak pull -r myorg/my-app -t prod Pull all resources tagged "prod"
250
- sunpeak pull -r myorg/my-app -t prod -n counter Pull only the "counter" resource
250
+ sunpeak pull -r myorg/my-app -t prod -n review Pull only the "review" resource
251
251
  sunpeak pull -r myorg/my-app -t v1.0.0 Pull a specific version
252
252
  `);
253
253
  process.exit(0);
package/bin/sunpeak.js CHANGED
@@ -28,7 +28,7 @@ function checkPackageJson() {
28
28
  }
29
29
 
30
30
  function parseResourcesInput(input) {
31
- const VALID_RESOURCES = ['albums', 'carousel', 'counter', 'map', 'review'];
31
+ const VALID_RESOURCES = ['albums', 'carousel', 'map', 'review'];
32
32
 
33
33
  // If no input, return all resources
34
34
  if (!input || input.trim() === '') {
@@ -59,7 +59,6 @@ function updateIndexFiles(targetDir, selectedResources) {
59
59
  const resourceMap = {
60
60
  albums: { component: 'album', resourceClass: 'AlbumsResource' },
61
61
  carousel: { component: 'carousel', resourceClass: 'CarouselResource' },
62
- counter: { component: null, resourceClass: 'CounterResource' },
63
62
  map: { component: 'map', resourceClass: 'MapResource' },
64
63
  review: { component: null, resourceClass: 'ReviewResource' },
65
64
  };
@@ -139,7 +138,7 @@ async function init(projectName, resourcesArg) {
139
138
  console.log(`☀️ 🏔️ Resources: ${resourcesArg}`);
140
139
  } else {
141
140
  resourcesInput = await prompt(
142
- '☀️ 🏔️ Resources (UIs) to include [albums, carousel, counter, map, review]: '
141
+ '☀️ 🏔️ Resources (UIs) to include [albums, carousel, map, review]: '
143
142
  );
144
143
  }
145
144
  const selectedResources = parseResourcesInput(resourcesInput);
@@ -161,7 +160,6 @@ async function init(projectName, resourcesArg) {
161
160
  const resourceComponentMap = {
162
161
  albums: 'album',
163
162
  carousel: 'carousel',
164
- counter: null, // Counter doesn't have a component directory
165
163
  map: 'map',
166
164
  review: null, // Review doesn't have a component directory
167
165
  };
@@ -177,7 +175,7 @@ async function init(projectName, resourcesArg) {
177
175
  }
178
176
 
179
177
  // Filter resource files based on selection
180
- const VALID_RESOURCES = ['albums', 'carousel', 'counter', 'map', 'review'];
178
+ const VALID_RESOURCES = ['albums', 'carousel', 'map', 'review'];
181
179
  const excludedResources = VALID_RESOURCES.filter((r) => !selectedResources.includes(r));
182
180
 
183
181
  for (const resource of excludedResources) {
@@ -194,6 +192,10 @@ async function init(projectName, resourcesArg) {
194
192
  if (name.startsWith(`${resource}-`) && name.endsWith('-simulation.json')) {
195
193
  return false;
196
194
  }
195
+ // Skip e2e test files for excluded resources
196
+ if (src.includes('/tests/e2e/') && name === `${resource}.spec.ts`) {
197
+ return false;
198
+ }
197
199
  // Skip component directories (map resource name to component dir name)
198
200
  const componentDirName = resourceComponentMap[resource];
199
201
  if (componentDirName && src.includes('/components/') && name === componentDirName) {
@@ -416,7 +418,7 @@ Usage:
416
418
  sunpeak upgrade Upgrade sunpeak to latest version
417
419
  sunpeak --version Show version number
418
420
 
419
- Resources: albums, carousel, counter, map, review (comma/space separated)
421
+ Resources: albums, carousel, map, review (comma/space separated)
420
422
  Example: sunpeak new my-app "albums,carousel"
421
423
 
422
424
  For more information, visit: https://sunpeak.ai/
@@ -1,9 +1,8 @@
1
1
  import { Simulation } from '../types/simulation';
2
2
  import * as React from 'react';
3
- type SimulationWithResource = Simulation & Required<Pick<Simulation, 'resource'>>;
4
3
  interface ChatGPTSimulatorProps {
5
4
  children?: React.ReactNode;
6
- simulations?: SimulationWithResource[];
5
+ simulations?: Record<string, Simulation>;
7
6
  appName?: string;
8
7
  appIcon?: string;
9
8
  }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const simulatorUrl = require("../simulator-url-CG8lAAC3.cjs");
4
+ exports.ChatGPTSimulator = simulatorUrl.ChatGPTSimulator;
5
+ exports.ThemeProvider = simulatorUrl.ThemeProvider;
6
+ exports.createSimulatorUrl = simulatorUrl.createSimulatorUrl;
7
+ exports.initMockOpenAI = simulatorUrl.initMockOpenAI;
8
+ exports.useThemeContext = simulatorUrl.useThemeContext;
9
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -1,4 +1,6 @@
1
1
  export { ChatGPTSimulator } from './chatgpt-simulator';
2
- export type { Simulation, SimulationCallToolResult, SimulationGlobals } from '../types/simulation';
2
+ export type { Simulation } from '../types/simulation';
3
3
  export { initMockOpenAI } from './mock-openai';
4
4
  export * from './theme-provider';
5
+ export { createSimulatorUrl } from './simulator-url';
6
+ export type { SimulatorUrlParams } from './simulator-url';
@@ -0,0 +1,9 @@
1
+ import { C, T, c, i, u } from "../simulator-url-CexnaL-e.js";
2
+ export {
3
+ C as ChatGPTSimulator,
4
+ T as ThemeProvider,
5
+ c as createSimulatorUrl,
6
+ i as initMockOpenAI,
7
+ u as useThemeContext
8
+ };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,127 @@
1
+ import { Theme, DisplayMode, DeviceType, ViewMode } from '../types/runtime';
2
+ /**
3
+ * Strongly-typed URL parameters for the ChatGPT Simulator.
4
+ *
5
+ * Use with `createSimulatorUrl()` to generate type-safe URL paths for e2e tests.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { createSimulatorUrl } from 'sunpeak/chatgpt';
10
+ *
11
+ * // In e2e tests:
12
+ * await page.goto(createSimulatorUrl({
13
+ * simulation: 'albums-show',
14
+ * theme: 'dark',
15
+ * displayMode: 'fullscreen',
16
+ * }));
17
+ * ```
18
+ */
19
+ export interface SimulatorUrlParams {
20
+ /**
21
+ * The simulation name to load (e.g., 'albums-show', 'review-diff').
22
+ * Corresponds to the simulation JSON filename without the '-simulation.json' suffix.
23
+ */
24
+ simulation?: string;
25
+ /**
26
+ * The color theme for the simulator.
27
+ * @default 'dark'
28
+ */
29
+ theme?: Theme;
30
+ /**
31
+ * The display mode for the widget.
32
+ * - 'inline': Embedded in the conversation
33
+ * - 'pip': Picture-in-picture mode with max height
34
+ * - 'fullscreen': Full screen overlay
35
+ * @default 'inline'
36
+ */
37
+ displayMode?: DisplayMode;
38
+ /**
39
+ * The locale for the simulator (e.g., 'en-US', 'ja-JP').
40
+ * @default 'en-US'
41
+ */
42
+ locale?: string;
43
+ /**
44
+ * Maximum height in pixels for PiP mode.
45
+ * Only applicable when displayMode is 'pip'.
46
+ */
47
+ maxHeight?: number;
48
+ /**
49
+ * The device type to simulate.
50
+ * Affects default hover/touch capabilities.
51
+ */
52
+ deviceType?: DeviceType;
53
+ /**
54
+ * Whether the device supports hover interactions.
55
+ * @default true for desktop, false for mobile/tablet
56
+ */
57
+ hover?: boolean;
58
+ /**
59
+ * Whether the device supports touch interactions.
60
+ * @default false for desktop, true for mobile/tablet
61
+ */
62
+ touch?: boolean;
63
+ /**
64
+ * Safe area inset from the top of the screen (in pixels).
65
+ * Used for devices with notches or status bars.
66
+ */
67
+ safeAreaTop?: number;
68
+ /**
69
+ * Safe area inset from the bottom of the screen (in pixels).
70
+ * Used for devices with home indicators.
71
+ */
72
+ safeAreaBottom?: number;
73
+ /**
74
+ * Safe area inset from the left of the screen (in pixels).
75
+ */
76
+ safeAreaLeft?: number;
77
+ /**
78
+ * Safe area inset from the right of the screen (in pixels).
79
+ */
80
+ safeAreaRight?: number;
81
+ /**
82
+ * The view mode for the widget.
83
+ * - 'modal': Display as a modal dialog
84
+ * - 'default': Normal display
85
+ */
86
+ viewMode?: ViewMode;
87
+ }
88
+ /**
89
+ * Creates a URL path with query parameters for the ChatGPT Simulator.
90
+ *
91
+ * @param params - The simulator parameters to encode
92
+ * @param basePath - The base path for the URL (default: '/')
93
+ * @returns A URL path string with encoded query parameters
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * // Basic usage
98
+ * createSimulatorUrl({ simulation: 'albums-show', theme: 'light' })
99
+ * // Returns: '/?simulation=albums-show&theme=light'
100
+ *
101
+ * // With display mode
102
+ * createSimulatorUrl({
103
+ * simulation: 'review-diff',
104
+ * theme: 'dark',
105
+ * displayMode: 'fullscreen',
106
+ * })
107
+ * // Returns: '/?simulation=review-diff&theme=dark&displayMode=fullscreen'
108
+ *
109
+ * // With device simulation
110
+ * createSimulatorUrl({
111
+ * simulation: 'map-show',
112
+ * deviceType: 'mobile',
113
+ * touch: true,
114
+ * hover: false,
115
+ * })
116
+ * // Returns: '/?simulation=map-show&deviceType=mobile&touch=true&hover=false'
117
+ *
118
+ * // With safe area insets (for notch simulation)
119
+ * createSimulatorUrl({
120
+ * simulation: 'carousel-show',
121
+ * safeAreaTop: 44,
122
+ * safeAreaBottom: 34,
123
+ * })
124
+ * // Returns: '/?simulation=carousel-show&safeAreaTop=44&safeAreaBottom=34'
125
+ * ```
126
+ */
127
+ export declare function createSimulatorUrl(params: SimulatorUrlParams, basePath?: string): string;