sunpeak 0.8.5 → 0.8.8

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 (34) hide show
  1. package/bin/commands/build.mjs +3 -3
  2. package/bin/commands/pull.mjs +2 -2
  3. package/bin/sunpeak.js +6 -8
  4. package/dist/mcp/entry.cjs.map +1 -1
  5. package/dist/mcp/entry.js.map +1 -1
  6. package/dist/style.css +0 -37
  7. package/package.json +1 -1
  8. package/template/.sunpeak/dev.tsx +2 -2
  9. package/template/README.md +5 -5
  10. package/template/dist/albums.js +1 -1
  11. package/template/dist/albums.json +1 -1
  12. package/template/dist/carousel.js +1 -1
  13. package/template/dist/carousel.json +1 -1
  14. package/template/dist/map.js +1 -1
  15. package/template/dist/map.json +1 -1
  16. package/template/dist/review.js +49 -0
  17. package/template/dist/{confirmation.json → review.json} +4 -4
  18. package/template/node_modules/.vite/deps/_metadata.json +19 -19
  19. package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  20. package/template/src/resources/index.ts +4 -4
  21. package/template/src/resources/map-resource.test.tsx +95 -0
  22. package/template/src/resources/{confirmation-resource.json → review-resource.json} +3 -3
  23. package/template/src/resources/review-resource.test.tsx +538 -0
  24. package/template/src/resources/{confirmation-resource.tsx → review-resource.tsx} +20 -20
  25. package/template/src/simulations/{confirmation-diff-simulation.json → review-diff-simulation.json} +4 -4
  26. package/template/src/simulations/{confirmation-post-simulation.json → review-post-simulation.json} +4 -4
  27. package/template/src/simulations/{confirmation-purchase-simulation.json → review-purchase-simulation.json} +4 -4
  28. package/template/dist/confirmation.js +0 -49
  29. package/template/dist/counter.js +0 -49
  30. package/template/dist/counter.json +0 -15
  31. package/template/src/resources/counter-resource.json +0 -12
  32. package/template/src/resources/counter-resource.test.tsx +0 -116
  33. package/template/src/resources/counter-resource.tsx +0 -101
  34. package/template/src/simulations/counter-show-simulation.json +0 -20
@@ -1,7 +1,7 @@
1
1
  {
2
- "name": "confirmation",
3
- "title": "Confirmation",
4
- "description": "Visualize and confirm a proposed set of changes or actions",
2
+ "name": "review",
3
+ "title": "Review",
4
+ "description": "Visualize and review a proposed set of changes or actions",
5
5
  "mimeType": "text/html+skybridge",
6
6
  "_meta": {
7
7
  "openai/widgetDomain": "https://sunpeak.ai",
@@ -12,5 +12,5 @@
12
12
  ]
13
13
  }
14
14
  },
15
- "uri": "ui://confirmation-mjt16aw5"
15
+ "uri": "ui://review-mjw4w0g9"
16
16
  }
@@ -7,115 +7,115 @@
7
7
  "react": {
8
8
  "src": "../../../../node_modules/.pnpm/react@19.2.3/node_modules/react/index.js",
9
9
  "file": "react.js",
10
- "fileHash": "0e51fec8",
10
+ "fileHash": "d6aa24ec",
11
11
  "needsInterop": true
12
12
  },
13
13
  "react-dom": {
14
14
  "src": "../../../../node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/index.js",
15
15
  "file": "react-dom.js",
16
- "fileHash": "4b45983a",
16
+ "fileHash": "a84166b8",
17
17
  "needsInterop": true
18
18
  },
19
19
  "react/jsx-dev-runtime": {
20
20
  "src": "../../../../node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-dev-runtime.js",
21
21
  "file": "react_jsx-dev-runtime.js",
22
- "fileHash": "8699c450",
22
+ "fileHash": "92c4ccf8",
23
23
  "needsInterop": true
24
24
  },
25
25
  "react/jsx-runtime": {
26
26
  "src": "../../../../node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime.js",
27
27
  "file": "react_jsx-runtime.js",
28
- "fileHash": "651d9e7f",
28
+ "fileHash": "fee8e947",
29
29
  "needsInterop": true
30
30
  },
31
31
  "@openai/apps-sdk-ui/components/Avatar": {
32
32
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Avatar/index.js",
33
33
  "file": "@openai_apps-sdk-ui_components_Avatar.js",
34
- "fileHash": "33128183",
34
+ "fileHash": "d1d0268f",
35
35
  "needsInterop": false
36
36
  },
37
37
  "@openai/apps-sdk-ui/components/Button": {
38
38
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Button/index.js",
39
39
  "file": "@openai_apps-sdk-ui_components_Button.js",
40
- "fileHash": "b929b5a5",
40
+ "fileHash": "0d815226",
41
41
  "needsInterop": false
42
42
  },
43
43
  "@openai/apps-sdk-ui/components/Checkbox": {
44
44
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Checkbox/index.js",
45
45
  "file": "@openai_apps-sdk-ui_components_Checkbox.js",
46
- "fileHash": "097d6898",
46
+ "fileHash": "e87c4e4e",
47
47
  "needsInterop": false
48
48
  },
49
49
  "@openai/apps-sdk-ui/components/Icon": {
50
50
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Icon/index.js",
51
51
  "file": "@openai_apps-sdk-ui_components_Icon.js",
52
- "fileHash": "d4c227fa",
52
+ "fileHash": "5c946825",
53
53
  "needsInterop": false
54
54
  },
55
55
  "@openai/apps-sdk-ui/components/Input": {
56
56
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Input/index.js",
57
57
  "file": "@openai_apps-sdk-ui_components_Input.js",
58
- "fileHash": "e4e68712",
58
+ "fileHash": "e5d8b16c",
59
59
  "needsInterop": false
60
60
  },
61
61
  "@openai/apps-sdk-ui/components/SegmentedControl": {
62
62
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/SegmentedControl/index.js",
63
63
  "file": "@openai_apps-sdk-ui_components_SegmentedControl.js",
64
- "fileHash": "b2d42700",
64
+ "fileHash": "4494f051",
65
65
  "needsInterop": false
66
66
  },
67
67
  "@openai/apps-sdk-ui/components/Select": {
68
68
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Select/index.js",
69
69
  "file": "@openai_apps-sdk-ui_components_Select.js",
70
- "fileHash": "2f773d0d",
70
+ "fileHash": "e67a1bb8",
71
71
  "needsInterop": false
72
72
  },
73
73
  "@openai/apps-sdk-ui/components/Textarea": {
74
74
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Textarea/index.js",
75
75
  "file": "@openai_apps-sdk-ui_components_Textarea.js",
76
- "fileHash": "c4149e45",
76
+ "fileHash": "c9eb4f91",
77
77
  "needsInterop": false
78
78
  },
79
79
  "@openai/apps-sdk-ui/theme": {
80
80
  "src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/lib/theme.js",
81
81
  "file": "@openai_apps-sdk-ui_theme.js",
82
- "fileHash": "e55a818f",
82
+ "fileHash": "8d57b3ed",
83
83
  "needsInterop": false
84
84
  },
85
85
  "clsx": {
86
86
  "src": "../../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs",
87
87
  "file": "clsx.js",
88
- "fileHash": "7928d437",
88
+ "fileHash": "e10bef76",
89
89
  "needsInterop": false
90
90
  },
91
91
  "embla-carousel-react": {
92
92
  "src": "../../../../node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.3/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js",
93
93
  "file": "embla-carousel-react.js",
94
- "fileHash": "1bb217b3",
94
+ "fileHash": "6d9c07d5",
95
95
  "needsInterop": false
96
96
  },
97
97
  "embla-carousel-wheel-gestures": {
98
98
  "src": "../../../../node_modules/.pnpm/embla-carousel-wheel-gestures@8.1.0_embla-carousel@8.6.0/node_modules/embla-carousel-wheel-gestures/dist/embla-carousel-wheel-gestures.esm.js",
99
99
  "file": "embla-carousel-wheel-gestures.js",
100
- "fileHash": "e5d1e192",
100
+ "fileHash": "3f6f688e",
101
101
  "needsInterop": false
102
102
  },
103
103
  "mapbox-gl": {
104
104
  "src": "../../../../node_modules/.pnpm/mapbox-gl@3.17.0/node_modules/mapbox-gl/dist/mapbox-gl.js",
105
105
  "file": "mapbox-gl.js",
106
- "fileHash": "0dca694e",
106
+ "fileHash": "7f66cd45",
107
107
  "needsInterop": true
108
108
  },
109
109
  "react-dom/client": {
110
110
  "src": "../../../../node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/client.js",
111
111
  "file": "react-dom_client.js",
112
- "fileHash": "36decb8e",
112
+ "fileHash": "c9a3870a",
113
113
  "needsInterop": true
114
114
  },
115
115
  "tailwind-merge": {
116
116
  "src": "../../../../node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.mjs",
117
117
  "file": "tailwind-merge.js",
118
- "fileHash": "0aa9c93c",
118
+ "fileHash": "9262acf9",
119
119
  "needsInterop": false
120
120
  }
121
121
  },
@@ -1 +1 @@
1
- {"version":"4.0.16","results":[[":src/components/album/albums.test.tsx",{"duration":326.520274,"failed":false}],[":src/resources/carousel-resource.test.tsx",{"duration":261.3222820000001,"failed":false}],[":src/resources/counter-resource.test.tsx",{"duration":342.0812799999994,"failed":false}],[":src/components/map/map-view.test.tsx",{"duration":73.70137100000011,"failed":false}],[":src/components/map/place-inspector.test.tsx",{"duration":432.93000200000006,"failed":false}],[":src/components/album/fullscreen-viewer.test.tsx",{"duration":253.5347079999999,"failed":false}],[":src/components/map/place-list.test.tsx",{"duration":161.95495300000016,"failed":false}],[":src/components/map/place-card.test.tsx",{"duration":370.12367099999983,"failed":false}],[":src/components/map/place-carousel.test.tsx",{"duration":403.4559099999999,"failed":false}],[":src/components/album/album-carousel.test.tsx",{"duration":85.3357390000001,"failed":false}],[":src/components/carousel/carousel.test.tsx",{"duration":95.43344399999978,"failed":false}],[":src/resources/albums-resource.test.tsx",{"duration":250.54613099999983,"failed":false}],[":src/components/album/film-strip.test.tsx",{"duration":484.06368499999985,"failed":false}],[":src/components/album/album-card.test.tsx",{"duration":324.16230099999984,"failed":false}],[":src/components/carousel/card.test.tsx",{"duration":84.68081699999993,"failed":false}]]}
1
+ {"version":"4.0.16","results":[[":src/components/album/albums.test.tsx",{"duration":334.697216,"failed":false}],[":src/resources/review-resource.test.tsx",{"duration":555.3965230000001,"failed":false}],[":src/resources/carousel-resource.test.tsx",{"duration":255.80494199999998,"failed":false}],[":src/components/map/map-view.test.tsx",{"duration":80.3751279999999,"failed":false}],[":src/components/map/place-inspector.test.tsx",{"duration":425.41421500000024,"failed":false}],[":src/components/album/fullscreen-viewer.test.tsx",{"duration":254.88947699999972,"failed":false}],[":src/components/map/place-list.test.tsx",{"duration":128.85422500000004,"failed":false}],[":src/components/map/place-card.test.tsx",{"duration":346.91089099999976,"failed":false}],[":src/components/map/place-carousel.test.tsx",{"duration":450.42473600000017,"failed":false}],[":src/components/album/album-carousel.test.tsx",{"duration":95.884546,"failed":false}],[":src/components/carousel/carousel.test.tsx",{"duration":82.93981499999995,"failed":false}],[":src/resources/map-resource.test.tsx",{"duration":289.9950490000001,"failed":false}],[":src/resources/albums-resource.test.tsx",{"duration":250.440699,"failed":false}],[":src/components/album/film-strip.test.tsx",{"duration":397.1800680000001,"failed":false}],[":src/components/carousel/card.test.tsx",{"duration":74.95684000000006,"failed":false}],[":src/components/album/album-card.test.tsx",{"duration":283.6294740000001,"failed":false}]]}
@@ -2,11 +2,11 @@
2
2
  * Auto-discovers and re-exports all resource components.
3
3
  *
4
4
  * Discovers all *-resource.tsx files and exports their component
5
- * with a PascalCase name (e.g., counter-resource.tsx -> CounterResource).
5
+ * with a PascalCase name (e.g., review-resource.tsx -> ReviewResource).
6
6
  *
7
7
  * Supports both export styles:
8
8
  * - Default export: export default MyComponent
9
- * - Named export: export const CounterResource = ...
9
+ * - Named export: export const ReviewResource = ...
10
10
  */
11
11
 
12
12
  // Auto-discover all resource component files
@@ -16,12 +16,12 @@ const resourceModules = import.meta.glob('./*-resource.tsx', { eager: true });
16
16
  const resources: Record<string, React.ComponentType> = {};
17
17
 
18
18
  for (const [path, module] of Object.entries(resourceModules)) {
19
- // Extract key from path: './counter-resource.tsx' -> 'counter'
19
+ // Extract key from path: './review-resource.tsx' -> 'review'
20
20
  const match = path.match(/\.\/(.+)-resource\.tsx$/);
21
21
  const key = match?.[1];
22
22
  if (!key) continue;
23
23
 
24
- // Convert to PascalCase and append 'Resource': 'counter' -> 'CounterResource'
24
+ // Convert to PascalCase and append 'Resource': 'review' -> 'ReviewResource'
25
25
  const pascalKey = key.charAt(0).toUpperCase() + key.slice(1);
26
26
  const exportName = `${pascalKey}Resource`;
27
27
 
@@ -0,0 +1,95 @@
1
+ import { render } from '@testing-library/react';
2
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
3
+ import { MapResource } from './map-resource';
4
+
5
+ // Mock sunpeak hooks
6
+ let mockSafeArea: { insets: { top: number; bottom: number; left: number; right: number } } | null =
7
+ {
8
+ insets: { top: 0, bottom: 0, left: 0, right: 0 },
9
+ };
10
+ let mockMaxHeight: number | null = 600;
11
+
12
+ vi.mock('sunpeak', () => ({
13
+ useSafeArea: () => mockSafeArea,
14
+ useMaxHeight: () => mockMaxHeight,
15
+ }));
16
+
17
+ // Mock the Map component
18
+ vi.mock('../components/map/map', () => ({
19
+ Map: () => <div data-testid="map">Map Component</div>,
20
+ }));
21
+
22
+ describe('MapResource', () => {
23
+ beforeEach(() => {
24
+ vi.clearAllMocks();
25
+ mockSafeArea = { insets: { top: 0, bottom: 0, left: 0, right: 0 } };
26
+ mockMaxHeight = 600;
27
+ });
28
+
29
+ it('renders the Map component', () => {
30
+ const { getByTestId } = render(<MapResource />);
31
+
32
+ expect(getByTestId('map')).toBeInTheDocument();
33
+ });
34
+
35
+ it('respects safe area insets', () => {
36
+ mockSafeArea = { insets: { top: 20, bottom: 30, left: 10, right: 15 } };
37
+
38
+ const { container } = render(<MapResource />);
39
+ const mainDiv = container.firstChild as HTMLElement;
40
+
41
+ expect(mainDiv).toHaveStyle({
42
+ paddingTop: '20px',
43
+ paddingBottom: '30px',
44
+ paddingLeft: '10px',
45
+ paddingRight: '15px',
46
+ });
47
+ });
48
+
49
+ it('respects maxHeight constraint', () => {
50
+ mockMaxHeight = 400;
51
+
52
+ const { container } = render(<MapResource />);
53
+ const mainDiv = container.firstChild as HTMLElement;
54
+
55
+ expect(mainDiv).toHaveStyle({
56
+ maxHeight: '400px',
57
+ });
58
+ });
59
+
60
+ it('handles null safe area', () => {
61
+ mockSafeArea = null;
62
+
63
+ const { container } = render(<MapResource />);
64
+ const mainDiv = container.firstChild as HTMLElement;
65
+
66
+ expect(mainDiv).toHaveStyle({
67
+ paddingTop: '0px',
68
+ paddingBottom: '0px',
69
+ paddingLeft: '0px',
70
+ paddingRight: '0px',
71
+ });
72
+ });
73
+
74
+ it('handles null maxHeight', () => {
75
+ mockMaxHeight = null;
76
+
77
+ const { container } = render(<MapResource />);
78
+ const mainDiv = container.firstChild as HTMLElement;
79
+
80
+ // maxHeight should not be set when null
81
+ expect(mainDiv.style.maxHeight).toBe('');
82
+ });
83
+
84
+ it('forwards ref to the container div', () => {
85
+ const ref = vi.fn();
86
+ render(<MapResource ref={ref} />);
87
+
88
+ expect(ref).toHaveBeenCalled();
89
+ expect(ref.mock.calls[0][0]).toBeInstanceOf(HTMLDivElement);
90
+ });
91
+
92
+ it('has the correct displayName', () => {
93
+ expect(MapResource.displayName).toBe('MapResource');
94
+ });
95
+ });
@@ -1,7 +1,7 @@
1
1
  {
2
- "name": "confirmation",
3
- "title": "Confirmation",
4
- "description": "Visualize and confirm a proposed set of changes or actions",
2
+ "name": "review",
3
+ "title": "Review",
4
+ "description": "Visualize and review a proposed set of changes or actions",
5
5
  "mimeType": "text/html+skybridge",
6
6
  "_meta": {
7
7
  "openai/widgetDomain": "https://sunpeak.ai",