create-skybridge 0.0.0-dev.a62841e → 0.0.0-dev.a63fad2

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 (65) 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 +99 -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 +190 -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/index.css +9 -0
  57. package/templates/ecom/src/lib/cx.ts +9 -0
  58. package/templates/ecom/src/lib/format.ts +9 -0
  59. package/templates/ecom/src/server.ts +43 -0
  60. package/templates/ecom/src/tools/render-carousel.ts +234 -0
  61. package/templates/ecom/src/tools/search-products.ts +182 -0
  62. package/templates/ecom/src/types.ts +13 -0
  63. package/templates/ecom/src/views/carousel/index.tsx +92 -0
  64. package/templates/ecom/tsconfig.json +11 -0
  65. package/templates/ecom/vite.config.ts +8 -0
@@ -0,0 +1,92 @@
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 { formatPrice } from "../../lib/format";
14
+ import type { Product } from "../../tools/render-carousel.js";
15
+
16
+ const SKELETON_COUNT = 4;
17
+
18
+ // One narration line per on-screen product. `id` ties the card back to its full
19
+ // record in structuredContent.
20
+ function narrate(product: Product, index: number): string {
21
+ const { card } = product;
22
+ const price = card.price ? ` - ${formatPrice(card.price)}` : "";
23
+ const oos = card.outOfStock ? " [out of stock]" : "";
24
+ return `${index + 1}. ${card.title} (id: ${product.id})${price}${oos}`;
25
+ }
26
+
27
+ /**
28
+ * Carousel view for the `render-carousel` tool. Reads the full products from
29
+ * `_meta` (via useToolInfo().responseMetadata) and renders one card each.
30
+ * `structuredContent` is the model's grounding and is not used to render.
31
+ */
32
+ function Carousel() {
33
+ const { responseMetadata } = useToolInfo<"render-carousel">();
34
+ const [visibleIndices, setVisibleIndices] = useState<number[]>([]);
35
+
36
+ // Tool still resolving: reserve the layout with skeleton cards.
37
+ if (responseMetadata == null) {
38
+ const skeletons: ReactNode[] = [];
39
+ for (let i = 0; i < SKELETON_COUNT; i++) {
40
+ skeletons.push(<ProductCardSkeleton key={i} />);
41
+ }
42
+ return (
43
+ <ViewFrame>
44
+ <div className={sprinkles({ p: "3xs" })}>
45
+ <ProductCarousel loading>{skeletons}</ProductCarousel>
46
+ </div>
47
+ </ViewFrame>
48
+ );
49
+ }
50
+
51
+ const products = responseMetadata?.products ?? [];
52
+
53
+ if (products.length === 0) {
54
+ return (
55
+ <ViewFrame>
56
+ <EmptyState message="No products to show." />
57
+ </ViewFrame>
58
+ );
59
+ }
60
+
61
+ const cards: ReactNode[] = [];
62
+ for (const [index, product] of products.entries()) {
63
+ const { card } = product;
64
+ cards.push(
65
+ <ProductCard
66
+ key={product.id}
67
+ data-llm={visibleIndices.includes(index) ? narrate(product, index) : ""}
68
+ title={card.title}
69
+ price={card.price}
70
+ media={card.media}
71
+ outOfStock={card.outOfStock}
72
+ />,
73
+ );
74
+ }
75
+
76
+ const narration = `Carousel of ${products.length} product(s); the user scrolls horizontally. On screen now:`;
77
+
78
+ return (
79
+ <ViewFrame>
80
+ <div className={sprinkles({ p: "3xs" })}>
81
+ <ProductCarousel
82
+ onVisibleChange={setVisibleIndices}
83
+ data-llm={narration}
84
+ >
85
+ {cards}
86
+ </ProductCarousel>
87
+ </div>
88
+ </ViewFrame>
89
+ );
90
+ }
91
+
92
+ 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
+ });