sunpeak 0.7.11 → 0.8.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 (64) hide show
  1. package/README.md +2 -1
  2. package/bin/commands/deploy.mjs +18 -8
  3. package/bin/commands/login.mjs +73 -55
  4. package/bin/commands/logout.mjs +26 -12
  5. package/bin/commands/pull.mjs +60 -39
  6. package/bin/commands/push.mjs +73 -49
  7. package/bin/commands/upgrade.mjs +203 -0
  8. package/bin/sunpeak.js +62 -31
  9. package/dist/chatgpt/chatgpt-simulator.d.ts +2 -1
  10. package/dist/index.cjs +9 -12
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.js +9 -12
  13. package/dist/index.js.map +1 -1
  14. package/dist/mcp/entry.cjs +41 -9
  15. package/dist/mcp/entry.cjs.map +1 -1
  16. package/dist/mcp/entry.js +42 -10
  17. package/dist/mcp/entry.js.map +1 -1
  18. package/dist/mcp/index.cjs +1 -1
  19. package/dist/mcp/index.js +1 -1
  20. package/dist/{server-CziiHU7V.cjs → server-B9YgCQdS.cjs} +3 -2
  21. package/dist/{server-CziiHU7V.cjs.map → server-B9YgCQdS.cjs.map} +1 -1
  22. package/dist/{server-D8kyzuiq.js → server-DVmTC-SF.js} +3 -2
  23. package/dist/{server-D8kyzuiq.js.map → server-DVmTC-SF.js.map} +1 -1
  24. package/dist/types/simulation.d.ts +1 -1
  25. package/package.json +1 -1
  26. package/template/.sunpeak/dev.tsx +78 -15
  27. package/template/.sunpeak/vite-env.d.ts +1 -0
  28. package/template/README.md +6 -6
  29. package/template/dist/albums.json +1 -1
  30. package/template/dist/carousel.json +1 -1
  31. package/template/dist/counter.json +1 -1
  32. package/template/dist/map.json +1 -1
  33. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +3 -3
  34. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +1 -1
  35. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +16 -16
  36. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js +3 -3
  37. package/template/node_modules/.vite/deps/_metadata.json +32 -32
  38. package/template/node_modules/.vite/deps/{chunk-N6DVYEXK.js → chunk-SPYXUHEY.js} +8 -8
  39. package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  40. package/template/src/components/map/map-view.test.tsx +1 -1
  41. package/template/src/components/map/map-view.tsx +1 -1
  42. package/template/src/components/map/map.tsx +1 -1
  43. package/template/src/components/map/place-card.test.tsx +1 -1
  44. package/template/src/components/map/place-card.tsx +1 -1
  45. package/template/src/components/map/place-carousel.test.tsx +1 -1
  46. package/template/src/components/map/place-carousel.tsx +1 -1
  47. package/template/src/components/map/place-inspector.test.tsx +1 -1
  48. package/template/src/components/map/place-inspector.tsx +1 -1
  49. package/template/src/components/map/place-list.test.tsx +1 -1
  50. package/template/src/components/map/place-list.tsx +1 -1
  51. package/template/src/components/map/types.ts +18 -0
  52. package/template/src/resources/index.ts +39 -4
  53. package/template/src/simulations/albums-show-simulation.json +131 -0
  54. package/template/src/simulations/carousel-show-simulation.json +68 -0
  55. package/template/src/simulations/counter-show-simulation.json +20 -0
  56. package/template/src/simulations/index.ts +17 -12
  57. package/template/src/simulations/map-show-simulation.json +123 -0
  58. package/template/src/vite-env.d.ts +1 -0
  59. package/template/tsconfig.json +1 -1
  60. package/template/src/simulations/albums-simulation.ts +0 -147
  61. package/template/src/simulations/carousel-simulation.ts +0 -84
  62. package/template/src/simulations/counter-simulation.ts +0 -34
  63. package/template/src/simulations/map-simulation.ts +0 -154
  64. /package/template/node_modules/.vite/deps/{chunk-N6DVYEXK.js.map → chunk-SPYXUHEY.js.map} +0 -0
@@ -42,6 +42,6 @@ export interface Simulation {
42
42
  userMessage?: string;
43
43
  simulationGlobals?: SimulationGlobals;
44
44
  tool: Tool;
45
- resource: Resource;
45
+ resource?: Resource;
46
46
  toolCall?: SimulationCallToolResult;
47
47
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sunpeak",
3
- "version": "0.7.11",
3
+ "version": "0.8.1",
4
4
  "description": "The ChatGPT App framework. Quickstart, build, & test your ChatGPT App locally!",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1,44 +1,107 @@
1
1
  /**
2
2
  * Bootstrap file for Sunpeak dev server
3
3
  * This file bootstraps the ChatGPT simulator for development
4
+ *
5
+ * Auto-discovers simulations and resources by file naming convention:
6
+ * - simulations/{resource}-{tool}-simulation.json (e.g., albums-show-simulation.json)
7
+ * - resources/{resource}-resource.json
8
+ * - resources/{Resource}Resource component (PascalCase)
4
9
  */
5
10
  import { StrictMode } from 'react';
6
11
  import { createRoot } from 'react-dom/client';
7
12
  import { ChatGPTSimulator, type Simulation } from 'sunpeak';
8
- import { SIMULATIONS } from '../src/simulations';
9
- import * as Resources from '../src/resources';
13
+ import resourceComponents from '../src/resources';
10
14
  import '../src/styles/globals.css';
11
15
 
16
+ // Auto-discover all simulation and resource JSON files
17
+ const simulationModules = import.meta.glob('../src/simulations/*-simulation.json', {
18
+ eager: true,
19
+ });
20
+ const resourceModules = import.meta.glob('../src/resources/*-resource.json', { eager: true });
21
+
22
+ // Build resource map from discovered files
23
+ type ResourceData = { name: string; [key: string]: unknown };
24
+ const resourcesMap = new Map<string, ResourceData>();
25
+ for (const [path, module] of Object.entries(resourceModules)) {
26
+ // Extract key from path: '../src/resources/counter-resource.json' -> 'counter'
27
+ const match = path.match(/\/([^/]+)-resource\.json$/);
28
+ const key = match?.[1];
29
+ if (key) {
30
+ resourcesMap.set(key, (module as { default: ResourceData }).default);
31
+ }
32
+ }
33
+
34
+ // Get sorted resource keys for best-match lookup (longest first)
35
+ const resourceKeys = Array.from(resourcesMap.keys()).sort((a, b) => b.length - a.length);
36
+
37
+ /**
38
+ * Find the best matching resource for a simulation key.
39
+ * Matches the longest resource name that is a prefix of the simulation key.
40
+ * e.g., 'albums-show' matches 'albums' (not 'album' if both exist)
41
+ */
42
+ function findResourceKey(simulationKey: string): string | undefined {
43
+ // Simulation key format: {resource}-{tool} (e.g., 'albums-show')
44
+ // Find the longest resource name that matches as a prefix followed by '-'
45
+ for (const resourceKey of resourceKeys) {
46
+ if (simulationKey === resourceKey || simulationKey.startsWith(resourceKey + '-')) {
47
+ return resourceKey;
48
+ }
49
+ }
50
+ return undefined;
51
+ }
52
+
12
53
  /**
13
54
  * Convert resource name to component name
14
55
  * Example: 'carousel' -> 'CarouselResource', 'counter' -> 'CounterResource'
15
56
  */
16
- function getResourceComponentFromName(name: string): React.ComponentType {
17
- // Convert name to PascalCase and append 'Resource'
57
+ function getResourceComponent(name: string): React.ComponentType {
18
58
  const pascalName = name.charAt(0).toUpperCase() + name.slice(1);
19
59
  const componentName = `${pascalName}Resource`;
20
60
 
21
- const component = Resources[componentName as keyof typeof Resources];
61
+ const component = resourceComponents[componentName];
22
62
 
23
63
  if (!component) {
24
64
  throw new Error(
25
65
  `Resource component "${componentName}" not found for resource "${name}". ` +
26
- `Make sure it's exported from src/resources/index.ts`
66
+ `Make sure src/resources/${name}-resource.tsx exists with a default export.`
27
67
  );
28
68
  }
29
69
 
30
- return component as React.ComponentType;
70
+ return component;
31
71
  }
32
72
 
33
- // Package the resource component with the simulation
34
- const simulations: Simulation[] = Object.values(
35
- SIMULATIONS as Record<string, Omit<Simulation, 'resourceComponent'>>
36
- ).map((simulation) => ({
37
- ...simulation,
38
- resourceComponent: getResourceComponentFromName(simulation.resource.name),
39
- }));
73
+ // Build simulations array from discovered files
74
+ type SimulationData = Omit<Simulation, 'resourceComponent' | 'resource'>;
75
+ const simulations: Simulation[] = [];
76
+
77
+ for (const [path, module] of Object.entries(simulationModules)) {
78
+ // Extract simulation key from path: '../src/simulations/albums-show-simulation.json' -> 'albums-show'
79
+ const match = path.match(/\/([^/]+)-simulation\.json$/);
80
+ const simulationKey = match?.[1];
81
+ if (!simulationKey) continue;
82
+
83
+ const simulation = (module as { default: SimulationData }).default;
84
+
85
+ // Find matching resource by best prefix match
86
+ const resourceKey = findResourceKey(simulationKey);
87
+ if (!resourceKey) {
88
+ console.warn(
89
+ `No matching resource found for simulation "${simulationKey}". ` +
90
+ `Expected a resource file like src/resources/${simulationKey.split('-')[0]}-resource.json`
91
+ );
92
+ continue;
93
+ }
94
+
95
+ const resource = resourcesMap.get(resourceKey)!;
96
+
97
+ simulations.push({
98
+ ...simulation,
99
+ resource,
100
+ resourceComponent: getResourceComponent(resource.name),
101
+ });
102
+ }
40
103
 
41
- // Read app config from package.json or use defaults
104
+ // Read app config from environment or use defaults
42
105
  const appName = import.meta.env?.VITE_APP_NAME || 'Sunpeak';
43
106
  const appIcon = import.meta.env?.VITE_APP_ICON || '🌄';
44
107
 
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -8,7 +8,7 @@ For an initial overview of your new app and the sunpeak API, refer to the [docum
8
8
 
9
9
  ```bash
10
10
  pnpm install
11
- pnpm dev
11
+ sunpeak dev
12
12
  ```
13
13
 
14
14
  That's it! Edit the resource files in [./src/resources/](./src/resources/) to build your resource UI.
@@ -16,9 +16,9 @@ That's it! Edit the resource files in [./src/resources/](./src/resources/) to bu
16
16
  ## Commands
17
17
 
18
18
  ```bash
19
- pnpm dev # Start development server
20
- pnpm build # Build all resources for production
21
- pnpm mcp # Start MCP server with auto-reload
19
+ sunpeak dev # Start development server
20
+ sunpeak build # Build all resources for production
21
+ sunpeak mcp # Start MCP server with auto-reload
22
22
  pnpm test # Run tests with Vitest
23
23
  ```
24
24
 
@@ -62,7 +62,7 @@ Test your app directly in ChatGPT using the built-in MCP server:
62
62
 
63
63
  ```bash
64
64
  # Start the MCP server (rebuilds and restarts on file changes).
65
- pnpm mcp
65
+ sunpeak mcp
66
66
 
67
67
  # In another terminal, run a tunnel. For example:
68
68
  ngrok http 6766
@@ -79,7 +79,7 @@ When you make changes to the UI, refresh your app in ChatGPT after the MCP serve
79
79
  Build your app for production:
80
80
 
81
81
  ```bash
82
- pnpm build
82
+ sunpeak build
83
83
  ```
84
84
 
85
85
  This creates optimized builds in `dist/`:
@@ -11,5 +11,5 @@
11
11
  ]
12
12
  }
13
13
  },
14
- "uri": "ui://albums-mjkeffk1"
14
+ "uri": "ui://albums-mjogxfpn"
15
15
  }
@@ -11,5 +11,5 @@
11
11
  ]
12
12
  }
13
13
  },
14
- "uri": "ui://carousel-mjkeffk1"
14
+ "uri": "ui://carousel-mjogxfpn"
15
15
  }
@@ -6,5 +6,5 @@
6
6
  "_meta": {
7
7
  "openai/widgetDomain": "https://sunpeak.ai"
8
8
  },
9
- "uri": "ui://counter-mjkeffk1"
9
+ "uri": "ui://counter-mjogxfpn"
10
10
  }
@@ -15,5 +15,5 @@
15
15
  ]
16
16
  }
17
17
  },
18
- "uri": "ui://map-mjkeffk1"
18
+ "uri": "ui://map-mjogxfpn"
19
19
  }
@@ -2,13 +2,13 @@ import {
2
2
  Button,
3
3
  ButtonLink,
4
4
  CopyButton
5
- } from "./chunk-N6DVYEXK.js";
5
+ } from "./chunk-SPYXUHEY.js";
6
+ import "./chunk-UM3ZGDFR.js";
6
7
  import "./chunk-JAGHY6H6.js";
7
- import "./chunk-QPJAV452.js";
8
8
  import "./chunk-DYQDWJMS.js";
9
+ import "./chunk-QPJAV452.js";
9
10
  import "./chunk-EGRHWZRV.js";
10
11
  import "./chunk-CNYJBM5F.js";
11
- import "./chunk-UM3ZGDFR.js";
12
12
  import "./chunk-JGVISENQ.js";
13
13
  import "./chunk-BUOVMFCD.js";
14
14
  import "./chunk-ILHRZGIS.js";
@@ -5,11 +5,11 @@ import {
5
5
  handlePressableMouseEnter,
6
6
  waitForAnimationFrame
7
7
  } from "./chunk-DYQDWJMS.js";
8
- import "./chunk-EGRHWZRV.js";
9
8
  import {
10
9
  dist_exports4 as dist_exports
11
10
  } from "./chunk-TSEQUROC.js";
12
11
  import "./chunk-XZTIOEPG.js";
12
+ import "./chunk-EGRHWZRV.js";
13
13
  import {
14
14
  clsx_default
15
15
  } from "./chunk-CNYJBM5F.js";
@@ -1,41 +1,41 @@
1
- import {
2
- Input
3
- } from "./chunk-2DZGWGIP.js";
4
1
  import {
5
2
  Button,
6
3
  LoadingIndicator,
7
4
  TransitionGroup
8
- } from "./chunk-N6DVYEXK.js";
5
+ } from "./chunk-SPYXUHEY.js";
6
+ import {
7
+ Check_default,
8
+ ChevronDownVector_default,
9
+ DropdownVector_default,
10
+ Info_default,
11
+ Search_default,
12
+ X_default
13
+ } from "./chunk-UM3ZGDFR.js";
9
14
  import {
10
15
  useTimeout
11
16
  } from "./chunk-JAGHY6H6.js";
12
- import {
13
- o
14
- } from "./chunk-QPJAV452.js";
15
17
  import {
16
18
  handlePressableMouseEnter,
17
19
  preventDefaultHandler,
18
20
  toCssVariables,
19
21
  waitForAnimationFrame
20
22
  } from "./chunk-DYQDWJMS.js";
21
- import "./chunk-EGRHWZRV.js";
22
23
  import {
23
24
  dist_exports,
24
25
  dist_exports3 as dist_exports2,
25
26
  dist_exports5 as dist_exports3
26
27
  } from "./chunk-TSEQUROC.js";
27
28
  import "./chunk-XZTIOEPG.js";
29
+ import {
30
+ Input
31
+ } from "./chunk-2DZGWGIP.js";
32
+ import {
33
+ o
34
+ } from "./chunk-QPJAV452.js";
35
+ import "./chunk-EGRHWZRV.js";
28
36
  import {
29
37
  clsx_default
30
38
  } from "./chunk-CNYJBM5F.js";
31
- import {
32
- Check_default,
33
- ChevronDownVector_default,
34
- DropdownVector_default,
35
- Info_default,
36
- Search_default,
37
- X_default
38
- } from "./chunk-UM3ZGDFR.js";
39
39
  import {
40
40
  require_jsx_runtime
41
41
  } from "./chunk-JGVISENQ.js";
@@ -1,9 +1,9 @@
1
- import {
2
- o
3
- } from "./chunk-QPJAV452.js";
4
1
  import {
5
2
  toCssVariables
6
3
  } from "./chunk-DYQDWJMS.js";
4
+ import {
5
+ o
6
+ } from "./chunk-QPJAV452.js";
7
7
  import "./chunk-EGRHWZRV.js";
8
8
  import {
9
9
  clsx_default
@@ -7,149 +7,149 @@
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": "8c524d9b",
10
+ "fileHash": "0e91efcd",
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": "8eeb19ea",
16
+ "fileHash": "a494a1bb",
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": "dda2010f",
22
+ "fileHash": "f8af2137",
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": "f7248748",
28
+ "fileHash": "ec4ed62f",
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": "f388143b",
34
+ "fileHash": "68e14c6b",
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": "0ea38e70",
40
+ "fileHash": "59569407",
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": "e240ec98",
46
+ "fileHash": "ebce4fc9",
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": "d32785b8",
52
+ "fileHash": "b7892cca",
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": "347dbcfc",
58
+ "fileHash": "bc414673",
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": "b4e29624",
64
+ "fileHash": "a5b83268",
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": "54b9002d",
70
+ "fileHash": "37b51fd8",
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": "c2845cba",
76
+ "fileHash": "1bd0d6c0",
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": "be140575",
82
+ "fileHash": "e9ee44f1",
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": "6a6afb72",
88
+ "fileHash": "42430903",
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": "74aac8d0",
94
+ "fileHash": "3da968c3",
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": "b9d0faec",
100
+ "fileHash": "3e16ffd7",
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": "36999890",
106
+ "fileHash": "7f23ced6",
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": "652a2f21",
112
+ "fileHash": "f79547d3",
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": "723987a7",
118
+ "fileHash": "f13263e2",
119
119
  "needsInterop": false
120
120
  }
121
121
  },
122
122
  "chunks": {
123
- "chunk-2DZGWGIP": {
124
- "file": "chunk-2DZGWGIP.js"
123
+ "chunk-SPYXUHEY": {
124
+ "file": "chunk-SPYXUHEY.js"
125
125
  },
126
- "chunk-N6DVYEXK": {
127
- "file": "chunk-N6DVYEXK.js"
126
+ "chunk-UM3ZGDFR": {
127
+ "file": "chunk-UM3ZGDFR.js"
128
128
  },
129
129
  "chunk-JAGHY6H6": {
130
130
  "file": "chunk-JAGHY6H6.js"
131
131
  },
132
- "chunk-QPJAV452": {
133
- "file": "chunk-QPJAV452.js"
134
- },
135
132
  "chunk-DYQDWJMS": {
136
133
  "file": "chunk-DYQDWJMS.js"
137
134
  },
138
- "chunk-EGRHWZRV": {
139
- "file": "chunk-EGRHWZRV.js"
140
- },
141
135
  "chunk-TSEQUROC": {
142
136
  "file": "chunk-TSEQUROC.js"
143
137
  },
144
138
  "chunk-XZTIOEPG": {
145
139
  "file": "chunk-XZTIOEPG.js"
146
140
  },
141
+ "chunk-2DZGWGIP": {
142
+ "file": "chunk-2DZGWGIP.js"
143
+ },
144
+ "chunk-QPJAV452": {
145
+ "file": "chunk-QPJAV452.js"
146
+ },
147
+ "chunk-EGRHWZRV": {
148
+ "file": "chunk-EGRHWZRV.js"
149
+ },
147
150
  "chunk-CNYJBM5F": {
148
151
  "file": "chunk-CNYJBM5F.js"
149
152
  },
150
- "chunk-UM3ZGDFR": {
151
- "file": "chunk-UM3ZGDFR.js"
152
- },
153
153
  "chunk-JGVISENQ": {
154
154
  "file": "chunk-JGVISENQ.js"
155
155
  },
@@ -1,9 +1,10 @@
1
+ import {
2
+ Check_default,
3
+ Copy_default
4
+ } from "./chunk-UM3ZGDFR.js";
1
5
  import {
2
6
  useTimeout
3
7
  } from "./chunk-JAGHY6H6.js";
4
- import {
5
- o
6
- } from "./chunk-QPJAV452.js";
7
8
  import {
8
9
  handlePressableMouseEnter,
9
10
  isDev,
@@ -15,13 +16,12 @@ import {
15
16
  toTransformProperty,
16
17
  waitForAnimationFrame
17
18
  } from "./chunk-DYQDWJMS.js";
19
+ import {
20
+ o
21
+ } from "./chunk-QPJAV452.js";
18
22
  import {
19
23
  clsx_default
20
24
  } from "./chunk-CNYJBM5F.js";
21
- import {
22
- Check_default,
23
- Copy_default
24
- } from "./chunk-UM3ZGDFR.js";
25
25
  import {
26
26
  require_jsx_runtime
27
27
  } from "./chunk-JGVISENQ.js";
@@ -625,4 +625,4 @@ export {
625
625
  ButtonLink,
626
626
  CopyButton
627
627
  };
628
- //# sourceMappingURL=chunk-N6DVYEXK.js.map
628
+ //# sourceMappingURL=chunk-SPYXUHEY.js.map
@@ -1 +1 @@
1
- {"version":"4.0.16","results":[[":src/components/map/map-view.test.tsx",{"duration":79.46838099999991,"failed":false}],[":src/resources/carousel-resource.test.tsx",{"duration":240.08223399999997,"failed":false}],[":src/components/album/albums.test.tsx",{"duration":351.6345040000001,"failed":false}],[":src/resources/counter-resource.test.tsx",{"duration":258.20634500000006,"failed":false}],[":src/components/map/place-inspector.test.tsx",{"duration":455.4559690000001,"failed":false}],[":src/components/album/fullscreen-viewer.test.tsx",{"duration":285.58507099999997,"failed":false}],[":src/components/map/place-list.test.tsx",{"duration":139.77515300000005,"failed":false}],[":src/components/map/place-card.test.tsx",{"duration":345.87943299999984,"failed":false}],[":src/components/map/place-carousel.test.tsx",{"duration":488.85430199999996,"failed":false}],[":src/components/album/album-carousel.test.tsx",{"duration":74.7320749999999,"failed":false}],[":src/components/carousel/carousel.test.tsx",{"duration":66.59458199999995,"failed":false}],[":src/resources/albums-resource.test.tsx",{"duration":251.85133800000017,"failed":false}],[":src/components/album/film-strip.test.tsx",{"duration":481.2766650000001,"failed":false}],[":src/components/album/album-card.test.tsx",{"duration":336.58156400000007,"failed":false}],[":src/components/carousel/card.test.tsx",{"duration":89.424129,"failed":false}]]}
1
+ {"version":"4.0.16","results":[[":src/components/album/albums.test.tsx",{"duration":369.608344,"failed":false}],[":src/resources/counter-resource.test.tsx",{"duration":298.88052300000027,"failed":false}],[":src/resources/carousel-resource.test.tsx",{"duration":229.87382100000013,"failed":false}],[":src/components/map/map-view.test.tsx",{"duration":74.3784169999999,"failed":false}],[":src/components/map/place-inspector.test.tsx",{"duration":396.6914099999999,"failed":false}],[":src/components/album/fullscreen-viewer.test.tsx",{"duration":235.851359,"failed":false}],[":src/components/map/place-list.test.tsx",{"duration":129.307685,"failed":false}],[":src/components/map/place-card.test.tsx",{"duration":346.68555300000025,"failed":false}],[":src/components/map/place-carousel.test.tsx",{"duration":392.8754509999999,"failed":false}],[":src/components/album/album-carousel.test.tsx",{"duration":79.79719499999987,"failed":false}],[":src/components/carousel/carousel.test.tsx",{"duration":75.20614599999999,"failed":false}],[":src/resources/albums-resource.test.tsx",{"duration":235.289847,"failed":false}],[":src/components/album/film-strip.test.tsx",{"duration":426.67748099999994,"failed":false}],[":src/components/album/album-card.test.tsx",{"duration":337.8234279999999,"failed":false}],[":src/components/carousel/card.test.tsx",{"duration":65.62471800000003,"failed":false}]]}
@@ -1,7 +1,7 @@
1
1
  import { render } from '@testing-library/react';
2
2
  import { describe, it, expect, vi, beforeEach } from 'vitest';
3
3
  import { MapView } from './map-view';
4
- import type { Place } from '../../simulations/map-simulation';
4
+ import type { Place } from './types';
5
5
 
6
6
  // Mock mapbox-gl
7
7
  vi.mock('mapbox-gl', () => ({
@@ -3,7 +3,7 @@ import mapboxgl from 'mapbox-gl';
3
3
  import 'mapbox-gl/dist/mapbox-gl.css';
4
4
  import { useMaxHeight } from 'sunpeak';
5
5
  import { cn } from '../../lib/index';
6
- import type { Place } from '../../simulations/map-simulation';
6
+ import type { Place } from './types';
7
7
 
8
8
  // Public Mapbox token for demo purposes
9
9
  mapboxgl.accessToken =
@@ -13,7 +13,7 @@ import { PlaceList } from './place-list';
13
13
  import { PlaceCarousel } from './place-carousel';
14
14
  import { PlaceInspector } from './place-inspector';
15
15
  import { MapView } from './map-view';
16
- import type { Place, MapData } from '../../simulations/map-simulation';
16
+ import type { Place, MapData } from './types';
17
17
 
18
18
  export interface MapState extends Record<string, unknown> {
19
19
  selectedPlaceId?: string | null;
@@ -1,7 +1,7 @@
1
1
  import { render, screen, fireEvent } from '@testing-library/react';
2
2
  import { describe, it, expect, vi } from 'vitest';
3
3
  import { PlaceCard } from './place-card';
4
- import type { Place } from '../../simulations/map-simulation';
4
+ import type { Place } from './types';
5
5
 
6
6
  describe('PlaceCard', () => {
7
7
  const mockPlace: Place = {
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Star } from '@openai/apps-sdk-ui/components/Icon';
3
3
  import { cn } from '../../lib/index';
4
- import type { Place } from '../../simulations/map-simulation';
4
+ import type { Place } from './types';
5
5
 
6
6
  export type PlaceCardProps = {
7
7
  place: Place;
@@ -1,7 +1,7 @@
1
1
  import { render, screen, fireEvent } from '@testing-library/react';
2
2
  import { describe, it, expect, vi } from 'vitest';
3
3
  import { PlaceCarousel } from './place-carousel';
4
- import type { Place } from '../../simulations/map-simulation';
4
+ import type { Place } from './types';
5
5
 
6
6
  describe('PlaceCarousel', () => {
7
7
  const mockPlaces: Place[] = [
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import useEmblaCarousel from 'embla-carousel-react';
3
3
  import { cn } from '../../lib/index';
4
4
  import { PlaceCard } from './place-card';
5
- import type { Place } from '../../simulations/map-simulation';
5
+ import type { Place } from './types';
6
6
 
7
7
  export type PlaceCarouselProps = {
8
8
  places: Place[];
@@ -1,7 +1,7 @@
1
1
  import { render, screen, fireEvent } from '@testing-library/react';
2
2
  import { describe, it, expect, vi } from 'vitest';
3
3
  import { PlaceInspector } from './place-inspector';
4
- import type { Place } from '../../simulations/map-simulation';
4
+ import type { Place } from './types';
5
5
 
6
6
  describe('PlaceInspector', () => {
7
7
  const mockPlace: Place = {
@@ -3,7 +3,7 @@ import { Button } from '@openai/apps-sdk-ui/components/Button';
3
3
  import { Avatar } from '@openai/apps-sdk-ui/components/Avatar';
4
4
  import { X, Star } from '@openai/apps-sdk-ui/components/Icon';
5
5
  import { cn } from '../../lib/index';
6
- import type { Place } from '../../simulations/map-simulation';
6
+ import type { Place } from './types';
7
7
 
8
8
  export type PlaceInspectorProps = {
9
9
  place: Place;