create-skybridge 0.0.0-dev.e9f6a8d → 0.0.0-dev.ea09368

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 (66) hide show
  1. package/dist/index.js +46 -24
  2. package/package.json +4 -4
  3. package/templates/blank/Dockerfile +2 -2
  4. package/templates/blank/node_modules/.bin/alpic +2 -2
  5. package/templates/blank/node_modules/.bin/tsc +2 -2
  6. package/templates/blank/node_modules/.bin/tsserver +2 -2
  7. package/templates/blank/node_modules/.bin/tsx +2 -2
  8. package/templates/blank/node_modules/.bin/vite +2 -2
  9. package/templates/blank/package.json +8 -8
  10. package/templates/demo/Dockerfile +2 -2
  11. package/templates/demo/node_modules/.bin/alpic +2 -2
  12. package/templates/demo/node_modules/.bin/tsc +2 -2
  13. package/templates/demo/node_modules/.bin/tsserver +2 -2
  14. package/templates/demo/node_modules/.bin/tsx +2 -2
  15. package/templates/demo/node_modules/.bin/vite +2 -2
  16. package/templates/demo/package.json +17 -17
  17. package/templates/ecom/.dockerignore +4 -0
  18. package/templates/ecom/.env.template +2 -0
  19. package/templates/ecom/.ladle/components.tsx +26 -0
  20. package/templates/ecom/.ladle/config.mjs +11 -0
  21. package/templates/ecom/.ladle/vite.config.ts +11 -0
  22. package/templates/ecom/AGENTS.md +2 -0
  23. package/templates/ecom/Dockerfile +53 -0
  24. package/templates/ecom/README.md +92 -0
  25. package/templates/ecom/_gitignore +9 -0
  26. package/templates/ecom/alpic.json +3 -0
  27. package/templates/ecom/node_modules/.bin/alpic +21 -0
  28. package/templates/ecom/node_modules/.bin/ladle +21 -0
  29. package/templates/ecom/node_modules/.bin/sb +21 -0
  30. package/templates/ecom/node_modules/.bin/skybridge +21 -0
  31. package/templates/ecom/node_modules/.bin/tsc +21 -0
  32. package/templates/ecom/node_modules/.bin/tsserver +21 -0
  33. package/templates/ecom/node_modules/.bin/tsx +21 -0
  34. package/templates/ecom/node_modules/.bin/vite +21 -0
  35. package/templates/ecom/package.json +41 -0
  36. package/templates/ecom/src/components/empty-state.stories.tsx +3 -0
  37. package/templates/ecom/src/components/empty-state.tsx +12 -0
  38. package/templates/ecom/src/components/product-card.css.ts +136 -0
  39. package/templates/ecom/src/components/product-card.stories.tsx +58 -0
  40. package/templates/ecom/src/components/product-card.tsx +101 -0
  41. package/templates/ecom/src/components/product-carousel.css.ts +134 -0
  42. package/templates/ecom/src/components/product-carousel.stories.tsx +64 -0
  43. package/templates/ecom/src/components/product-carousel.tsx +195 -0
  44. package/templates/ecom/src/components/view-frame.css.ts +22 -0
  45. package/templates/ecom/src/components/view-frame.tsx +27 -0
  46. package/templates/ecom/src/config.ts +12 -0
  47. package/templates/ecom/src/design/contract.css.ts +39 -0
  48. package/templates/ecom/src/design/fonts.css +15 -0
  49. package/templates/ecom/src/design/primitives.css.ts +101 -0
  50. package/templates/ecom/src/design/recipes/typography.css.ts +75 -0
  51. package/templates/ecom/src/design/sprinkles.css.ts +128 -0
  52. package/templates/ecom/src/design/themes/dark.css.ts +36 -0
  53. package/templates/ecom/src/design/themes/light.css.ts +36 -0
  54. package/templates/ecom/src/design/tokens.ts +8 -0
  55. package/templates/ecom/src/helpers.ts +4 -0
  56. package/templates/ecom/src/i18n.ts +27 -0
  57. package/templates/ecom/src/index.css +9 -0
  58. package/templates/ecom/src/lib/cx.ts +9 -0
  59. package/templates/ecom/src/lib/format.ts +9 -0
  60. package/templates/ecom/src/server.ts +43 -0
  61. package/templates/ecom/src/tools/render-carousel.ts +234 -0
  62. package/templates/ecom/src/tools/search-products.ts +182 -0
  63. package/templates/ecom/src/types.ts +13 -0
  64. package/templates/ecom/src/views/carousel/index.tsx +94 -0
  65. package/templates/ecom/tsconfig.json +11 -0
  66. package/templates/ecom/vite.config.ts +8 -0
@@ -0,0 +1,94 @@
1
+ import "../../index.css";
2
+
3
+ import { type ReactNode, useState } from "react";
4
+ import { EmptyState } from "../../components/empty-state";
5
+ import {
6
+ ProductCard,
7
+ ProductCardSkeleton,
8
+ } from "../../components/product-card";
9
+ import { ProductCarousel } from "../../components/product-carousel";
10
+ import { ViewFrame } from "../../components/view-frame";
11
+ import { sprinkles } from "../../design/tokens";
12
+ import { useToolInfo } from "../../helpers.js";
13
+ import { useLabels } from "../../i18n";
14
+ import { formatPrice } from "../../lib/format";
15
+ import type { Product } from "../../tools/render-carousel.js";
16
+
17
+ const SKELETON_COUNT = 4;
18
+
19
+ // One narration line per on-screen product. `id` ties the card back to its full
20
+ // record in structuredContent.
21
+ function narrate(product: Product, index: number): string {
22
+ const { card } = product;
23
+ const price = card.price ? ` - ${formatPrice(card.price)}` : "";
24
+ const oos = card.outOfStock ? " [out of stock]" : "";
25
+ return `${index + 1}. ${card.title} (id: ${product.id})${price}${oos}`;
26
+ }
27
+
28
+ /**
29
+ * Carousel view for the `render-carousel` tool. Reads the full products from
30
+ * `_meta` (via useToolInfo().responseMetadata) and renders one card each.
31
+ * `structuredContent` is the model's grounding and is not used to render.
32
+ */
33
+ function Carousel() {
34
+ const { responseMetadata } = useToolInfo<"render-carousel">();
35
+ const [visibleIndices, setVisibleIndices] = useState<number[]>([]);
36
+ const labels = useLabels();
37
+
38
+ // Tool still resolving: reserve the layout with skeleton cards.
39
+ if (responseMetadata == null) {
40
+ const skeletons: ReactNode[] = [];
41
+ for (let i = 0; i < SKELETON_COUNT; i++) {
42
+ skeletons.push(<ProductCardSkeleton key={i} />);
43
+ }
44
+ return (
45
+ <ViewFrame>
46
+ <div className={sprinkles({ p: "3xs" })}>
47
+ <ProductCarousel loading>{skeletons}</ProductCarousel>
48
+ </div>
49
+ </ViewFrame>
50
+ );
51
+ }
52
+
53
+ const products = responseMetadata?.products ?? [];
54
+
55
+ if (products.length === 0) {
56
+ return (
57
+ <ViewFrame>
58
+ <EmptyState message={labels.noProducts} />
59
+ </ViewFrame>
60
+ );
61
+ }
62
+
63
+ const cards: ReactNode[] = [];
64
+ for (const [index, product] of products.entries()) {
65
+ const { card } = product;
66
+ cards.push(
67
+ <ProductCard
68
+ key={product.id}
69
+ data-llm={visibleIndices.includes(index) ? narrate(product, index) : ""}
70
+ title={card.title}
71
+ price={card.price}
72
+ media={card.media}
73
+ outOfStock={card.outOfStock}
74
+ />,
75
+ );
76
+ }
77
+
78
+ const narration = `Carousel of ${products.length} product(s); the user scrolls horizontally. On screen now:`;
79
+
80
+ return (
81
+ <ViewFrame>
82
+ <div className={sprinkles({ p: "3xs" })}>
83
+ <ProductCarousel
84
+ onVisibleChange={setVisibleIndices}
85
+ data-llm={narration}
86
+ >
87
+ {cards}
88
+ </ProductCarousel>
89
+ </div>
90
+ </ViewFrame>
91
+ );
92
+ }
93
+
94
+ export default Carousel;
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "skybridge/tsconfig",
3
+
4
+ "compilerOptions": {
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "types": ["node", "vite/client"]
8
+ },
9
+
10
+ "include": ["src", ".skybridge/**/*.d.ts"]
11
+ }
@@ -0,0 +1,8 @@
1
+ import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
2
+ import react from "@vitejs/plugin-react";
3
+ import { skybridge } from "skybridge/vite";
4
+ import { defineConfig, type PluginOption } from "vite";
5
+
6
+ export default defineConfig({
7
+ plugins: [skybridge() as PluginOption, react(), vanillaExtractPlugin()],
8
+ });