sunpeak 0.8.1 → 0.8.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.
Files changed (37) hide show
  1. package/bin/commands/dev.mjs +60 -4
  2. package/bin/commands/mcp.mjs +1 -1
  3. package/bin/sunpeak.js +6 -4
  4. package/dist/index.cjs +4 -2
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.js +4 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/style.css +62 -0
  9. package/package.json +1 -1
  10. package/template/README.md +29 -14
  11. package/template/dist/albums.js +1 -1
  12. package/template/dist/albums.json +3 -2
  13. package/template/dist/carousel.js +1 -1
  14. package/template/dist/carousel.json +3 -2
  15. package/template/dist/confirmation.js +49 -0
  16. package/template/dist/confirmation.json +16 -0
  17. package/template/dist/counter.js +1 -1
  18. package/template/dist/counter.json +7 -2
  19. package/template/dist/map.js +1 -1
  20. package/template/dist/map.json +6 -3
  21. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +3 -3
  22. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +1 -1
  23. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +16 -16
  24. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js +3 -3
  25. package/template/node_modules/.vite/deps/_metadata.json +32 -32
  26. package/template/node_modules/.vite/deps/{chunk-SPYXUHEY.js → chunk-N6DVYEXK.js} +8 -8
  27. package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  28. package/template/src/resources/albums-resource.json +1 -1
  29. package/template/src/resources/carousel-resource.json +1 -1
  30. package/template/src/resources/confirmation-resource.json +12 -0
  31. package/template/src/resources/confirmation-resource.tsx +479 -0
  32. package/template/src/resources/counter-resource.json +4 -1
  33. package/template/src/resources/map-resource.json +7 -2
  34. package/template/src/simulations/confirmation-diff-simulation.json +80 -0
  35. package/template/src/simulations/confirmation-post-simulation.json +56 -0
  36. package/template/src/simulations/confirmation-purchase-simulation.json +88 -0
  37. /package/template/node_modules/.vite/deps/{chunk-SPYXUHEY.js.map → chunk-N6DVYEXK.js.map} +0 -0
@@ -1,9 +1,56 @@
1
1
  #!/usr/bin/env node
2
- import { createServer } from 'vite';
3
- import react from '@vitejs/plugin-react';
4
- import tailwindcss from '@tailwindcss/vite';
5
2
  import { existsSync } from 'fs';
6
- import { join, resolve, basename } from 'path';
3
+ import { join, resolve, basename, dirname } from 'path';
4
+ import { createRequire } from 'module';
5
+ import { pathToFileURL } from 'url';
6
+
7
+ /**
8
+ * Import a module from the project's node_modules using ESM resolution
9
+ */
10
+ async function importFromProject(require, moduleName) {
11
+ // Resolve the module's main entry to find its location
12
+ const resolvedPath = require.resolve(moduleName);
13
+
14
+ // Walk up to find package.json
15
+ const { readFileSync } = await import('fs');
16
+ let pkgDir = dirname(resolvedPath);
17
+ let pkg;
18
+ while (pkgDir !== dirname(pkgDir)) {
19
+ try {
20
+ const pkgJsonPath = join(pkgDir, 'package.json');
21
+ pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
22
+ if (pkg.name === moduleName || moduleName.startsWith(pkg.name + '/')) {
23
+ break;
24
+ }
25
+ } catch {
26
+ // No package.json at this level, keep looking
27
+ }
28
+ pkgDir = dirname(pkgDir);
29
+ }
30
+
31
+ if (!pkg) {
32
+ // Fallback to CJS resolution if we can't find package.json
33
+ return import(resolvedPath);
34
+ }
35
+
36
+ // Determine ESM entry: exports.import > exports.default > module > main
37
+ let entry = pkg.main || 'index.js';
38
+ if (pkg.exports) {
39
+ const exp = pkg.exports['.'] || pkg.exports;
40
+ if (typeof exp === 'string') {
41
+ entry = exp;
42
+ } else if (exp.import) {
43
+ entry = typeof exp.import === 'string' ? exp.import : exp.import.default;
44
+ } else if (exp.default) {
45
+ entry = exp.default;
46
+ }
47
+ } else if (pkg.module) {
48
+ entry = pkg.module;
49
+ }
50
+
51
+ const entryPath = join(pkgDir, entry);
52
+ return import(pathToFileURL(entryPath).href);
53
+ }
7
54
 
8
55
  /**
9
56
  * Start the Vite development server
@@ -18,6 +65,15 @@ export async function dev(projectRoot = process.cwd(), args = []) {
18
65
  process.exit(1);
19
66
  }
20
67
 
68
+ // Import vite and plugins from the project's node_modules (ESM)
69
+ const require = createRequire(join(projectRoot, 'package.json'));
70
+ const vite = await importFromProject(require, 'vite');
71
+ const createServer = vite.createServer;
72
+ const reactPlugin = await importFromProject(require, '@vitejs/plugin-react');
73
+ const react = reactPlugin.default;
74
+ const tailwindPlugin = await importFromProject(require, '@tailwindcss/vite');
75
+ const tailwindcss = tailwindPlugin.default;
76
+
21
77
  // Parse port from args or use default
22
78
  let port = parseInt(process.env.PORT || '6767');
23
79
  const portArgIndex = args.findIndex(arg => arg === '--port' || arg === '-p');
@@ -29,7 +29,7 @@ export async function mcp(projectRoot = process.cwd(), args = []) {
29
29
  // Add inline nodemon configuration
30
30
  nodemonArgs.push(
31
31
  '--watch', 'src',
32
- '--ext', 'ts,tsx,js,jsx,css',
32
+ '--ext', 'ts,tsx,js,jsx,css,json',
33
33
  '--ignore', 'dist',
34
34
  '--ignore', 'node_modules',
35
35
  '--ignore', '.tmp',
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'];
31
+ const VALID_RESOURCES = ['albums', 'carousel', 'confirmation', 'counter', 'map'];
32
32
 
33
33
  // If no input, return all resources
34
34
  if (!input || input.trim() === '') {
@@ -59,6 +59,7 @@ function updateIndexFiles(targetDir, selectedResources) {
59
59
  const resourceMap = {
60
60
  albums: { component: 'album', resourceClass: 'AlbumsResource' },
61
61
  carousel: { component: 'carousel', resourceClass: 'CarouselResource' },
62
+ confirmation: { component: null, resourceClass: 'ConfirmationResource' },
62
63
  counter: { component: null, resourceClass: 'CounterResource' },
63
64
  map: { component: 'map', resourceClass: 'MapResource' },
64
65
  };
@@ -138,7 +139,7 @@ async function init(projectName, resourcesArg) {
138
139
  console.log(`☀️ 🏔️ Resources: ${resourcesArg}`);
139
140
  } else {
140
141
  resourcesInput = await prompt(
141
- '☀️ 🏔️ Resources (UIs) to include [albums, carousel, counter, map]: '
142
+ '☀️ 🏔️ Resources (UIs) to include [albums, carousel, confirmation, counter, map]: '
142
143
  );
143
144
  }
144
145
  const selectedResources = parseResourcesInput(resourcesInput);
@@ -160,6 +161,7 @@ async function init(projectName, resourcesArg) {
160
161
  const resourceComponentMap = {
161
162
  albums: 'album',
162
163
  carousel: 'carousel',
164
+ confirmation: null, // Confirmation doesn't have a component directory
163
165
  counter: null, // Counter doesn't have a component directory
164
166
  map: 'map',
165
167
  };
@@ -175,7 +177,7 @@ async function init(projectName, resourcesArg) {
175
177
  }
176
178
 
177
179
  // Filter resource files based on selection
178
- const VALID_RESOURCES = ['albums', 'carousel', 'counter', 'map'];
180
+ const VALID_RESOURCES = ['albums', 'carousel', 'confirmation', 'counter', 'map'];
179
181
  const excludedResources = VALID_RESOURCES.filter((r) => !selectedResources.includes(r));
180
182
 
181
183
  for (const resource of excludedResources) {
@@ -402,7 +404,7 @@ Usage:
402
404
  npx sunpeak new [name] [resources] Create a new project (no install needed)
403
405
  pnpm dlx sunpeak new Alternative with pnpm
404
406
 
405
- Resources: albums, carousel, counter, map (comma/space separated)
407
+ Resources: albums, carousel, confirmation, counter, map (comma/space separated)
406
408
  Example: npx sunpeak new my-app "albums,carousel"
407
409
 
408
410
  Inside your project, use npm scripts:
package/dist/index.cjs CHANGED
@@ -7585,6 +7585,8 @@ function Conversation({
7585
7585
  }) {
7586
7586
  const displayMode = useDisplayMode() ?? "inline";
7587
7587
  const api = useWidgetAPI();
7588
+ const userAgent = useUserAgent();
7589
+ const isDesktop = (userAgent == null ? void 0 : userAgent.device.type) === "desktop";
7588
7590
  const containerWidth = screenWidth === "full" ? "100%" : `${SCREEN_WIDTHS[screenWidth]}px`;
7589
7591
  if (displayMode === "fullscreen") {
7590
7592
  const handleClose = () => {
@@ -7614,8 +7616,8 @@ function Conversation({
7614
7616
  children: /* @__PURE__ */ jsxRuntime.jsx(CloseBold, {})
7615
7617
  }
7616
7618
  ) }),
7617
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-primary flex items-center justify-center text-base", children: appName }),
7618
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(
7619
+ isDesktop && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-primary flex items-center justify-center text-base", children: appName }),
7620
+ isDesktop && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(
7619
7621
  Button,
7620
7622
  {
7621
7623
  variant: "outline",