@thorprovider/storefront 0.3.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 (109) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +333 -0
  3. package/assets/templates/app/app/[[...slug]]/page.tsx +17 -0
  4. package/assets/templates/app/app/[[...slug]]/renderer.tsx +10 -0
  5. package/assets/templates/app/app/globals.css +101 -0
  6. package/assets/templates/app/app/layout.tsx +35 -0
  7. package/assets/templates/app/lib/__STOREFRONT__/catalog.ts +88 -0
  8. package/assets/templates/app/lib/__STOREFRONT__/handlers.ts +42 -0
  9. package/assets/templates/app/lib/__STOREFRONT__/mappers.ts +47 -0
  10. package/assets/templates/app/lib/__STOREFRONT__/registry.tsx +98 -0
  11. package/assets/templates/app/lib/__STOREFRONT__/runtime.ts +17 -0
  12. package/assets/templates/app/lib/__STOREFRONT__/spec/index.ts +48 -0
  13. package/assets/templates/app/lib/__STOREFRONT__/spec/page-root.ts +26 -0
  14. package/assets/templates/app/lib/__STOREFRONT__/spec/types.ts +14 -0
  15. package/assets/templates/app/lib/__STOREFRONT__/state.ts +35 -0
  16. package/assets/templates/app/lib/__STOREFRONT__/views/index.ts +7 -0
  17. package/assets/templates/app/lib/__STOREFRONT__/views/sections/faq.tsx +29 -0
  18. package/assets/templates/app/lib/__STOREFRONT__/views/sections/logoCloud.tsx +29 -0
  19. package/assets/templates/app/lib/__STOREFRONT__/views/sections/pricing.tsx +33 -0
  20. package/assets/templates/app/lib/__STOREFRONT__/views/sections/statistics.tsx +29 -0
  21. package/assets/templates/app/lib/__STOREFRONT__/views/sections/testimonials.tsx +28 -0
  22. package/assets/templates/app/lib/__STOREFRONT__/views/types.ts +46 -0
  23. package/assets/templates/views/home/index.tsx +142 -0
  24. package/assets/templates/views/home/registry.tsx +65 -0
  25. package/bin/storefront.js +531 -0
  26. package/commands/sf-add-view.md +26 -0
  27. package/commands/sf-theme.md +20 -0
  28. package/commands/sf-view.md +25 -0
  29. package/package.json +48 -0
  30. package/recipes/archetype.schema.json +39 -0
  31. package/recipes/archetypes.json +148 -0
  32. package/recipes/recipe.schema.json +59 -0
  33. package/recipes/recipes.json +90 -0
  34. package/recipes/sections.json +46 -0
  35. package/recipes/validate.mjs +190 -0
  36. package/scripts/render-templates.mjs +255 -0
  37. package/scripts/sync-assets.mjs +87 -0
  38. package/skills/building-storefronts/SKILL.md +178 -0
  39. package/skills/building-storefronts/references/frontend-integration.md +229 -0
  40. package/skills/json-render-core/SKILL.md +291 -0
  41. package/skills/json-render-next/SKILL.md +194 -0
  42. package/skills/json-render-react/SKILL.md +298 -0
  43. package/skills/json-render-remotion/SKILL.md +111 -0
  44. package/skills/json-render-shadcn/SKILL.md +159 -0
  45. package/skills/json-render-solid/SKILL.md +204 -0
  46. package/skills/nextjs-shadcn/SKILL.md +367 -0
  47. package/skills/nextjs-shadcn/references/architecture.md +499 -0
  48. package/skills/nextjs-shadcn/references/project-setup.md +162 -0
  49. package/skills/nextjs-shadcn/references/shadcn-platform.md +261 -0
  50. package/skills/nextjs-shadcn/references/sidebar.md +274 -0
  51. package/skills/nextjs-shadcn/references/styling.md +555 -0
  52. package/skills/sf-theme-gen/SKILL.md +61 -0
  53. package/skills/sf-view-gen/SKILL.md +116 -0
  54. package/skills/sf-view-gen/assets/recipes/archetypes.json +148 -0
  55. package/skills/sf-view-gen/assets/recipes/recipes.json +90 -0
  56. package/skills/sf-view-gen/assets/recipes/sections.json +46 -0
  57. package/skills/sf-view-gen/assets/templates/views/category/index.tsx +86 -0
  58. package/skills/sf-view-gen/assets/templates/views/category/registry.tsx +48 -0
  59. package/skills/sf-view-gen/assets/templates/views/checkout/index.tsx +192 -0
  60. package/skills/sf-view-gen/assets/templates/views/checkout/registry.tsx +45 -0
  61. package/skills/sf-view-gen/assets/templates/views/product/index.tsx +122 -0
  62. package/skills/sf-view-gen/assets/templates/views/product/registry.tsx +49 -0
  63. package/skills/sf-view-gen/assets/templates/views/sections/faq.client.tsx +20 -0
  64. package/skills/sf-view-gen/assets/templates/views/sections/faq.tsx +21 -0
  65. package/skills/sf-view-gen/assets/templates/views/sections/logoCloud.client.tsx +18 -0
  66. package/skills/sf-view-gen/assets/templates/views/sections/logoCloud.tsx +21 -0
  67. package/skills/sf-view-gen/assets/templates/views/sections/pricing.client.tsx +20 -0
  68. package/skills/sf-view-gen/assets/templates/views/sections/pricing.tsx +23 -0
  69. package/skills/sf-view-gen/assets/templates/views/sections/statistics.client.tsx +18 -0
  70. package/skills/sf-view-gen/assets/templates/views/sections/statistics.tsx +21 -0
  71. package/skills/sf-view-gen/assets/templates/views/sections/testimonials.client.tsx +19 -0
  72. package/skills/sf-view-gen/assets/templates/views/sections/testimonials.tsx +19 -0
  73. package/skills/sf-view-gen/assets/templates/views/user-panel/index.tsx +168 -0
  74. package/skills/sf-view-gen/assets/templates/views/user-panel/registry.tsx +49 -0
  75. package/skills/sf-view-gen/references/views.md +69 -0
  76. package/skills/sf-view-gen/scripts/validate.mjs +190 -0
  77. package/skills/shadcn-component-discovery/SKILL.md +273 -0
  78. package/skills/shadcn-component-discovery/references/registries.md +226 -0
  79. package/skills/shadcn-theming/SKILL.md +104 -0
  80. package/skills/shadcn-theming/references/templates/theme-setup.md +109 -0
  81. package/skills/shadcn-theming/references/theming-guide.md +90 -0
  82. package/skills/storefront-best-practices/SKILL.md +421 -0
  83. package/skills/storefront-best-practices/reference/components/breadcrumbs.md +123 -0
  84. package/skills/storefront-best-practices/reference/components/cart-popup.md +189 -0
  85. package/skills/storefront-best-practices/reference/components/country-selector.md +298 -0
  86. package/skills/storefront-best-practices/reference/components/footer.md +112 -0
  87. package/skills/storefront-best-practices/reference/components/hero.md +241 -0
  88. package/skills/storefront-best-practices/reference/components/megamenu.md +239 -0
  89. package/skills/storefront-best-practices/reference/components/navbar.md +397 -0
  90. package/skills/storefront-best-practices/reference/components/popups.md +221 -0
  91. package/skills/storefront-best-practices/reference/components/product-card.md +125 -0
  92. package/skills/storefront-best-practices/reference/components/product-reviews.md +217 -0
  93. package/skills/storefront-best-practices/reference/components/product-slider.md +174 -0
  94. package/skills/storefront-best-practices/reference/components/search.md +101 -0
  95. package/skills/storefront-best-practices/reference/connecting-to-backend.md +391 -0
  96. package/skills/storefront-best-practices/reference/design.md +388 -0
  97. package/skills/storefront-best-practices/reference/features/promotions.md +307 -0
  98. package/skills/storefront-best-practices/reference/features/wishlist.md +230 -0
  99. package/skills/storefront-best-practices/reference/layouts/account.md +380 -0
  100. package/skills/storefront-best-practices/reference/layouts/cart.md +316 -0
  101. package/skills/storefront-best-practices/reference/layouts/checkout.md +486 -0
  102. package/skills/storefront-best-practices/reference/layouts/home-page.md +264 -0
  103. package/skills/storefront-best-practices/reference/layouts/order-confirmation.md +231 -0
  104. package/skills/storefront-best-practices/reference/layouts/product-details.md +527 -0
  105. package/skills/storefront-best-practices/reference/layouts/product-listing.md +520 -0
  106. package/skills/storefront-best-practices/reference/layouts/static-pages.md +356 -0
  107. package/skills/storefront-best-practices/reference/medusa.md +307 -0
  108. package/skills/storefront-best-practices/reference/mobile-responsiveness.md +183 -0
  109. package/skills/storefront-best-practices/reference/seo.md +195 -0
@@ -0,0 +1,367 @@
1
+ ---
2
+ name: nextjs-shadcn
3
+ argument-hint: "[component or page]"
4
+ description: Creates Next.js frontends with shadcn/ui. Use when building React UIs, components, pages, or applications with shadcn, Tailwind, or modern frontend patterns. Also use when the user asks to create a new Next.js project, add UI components, style pages, or build any web interface — even if they don't mention shadcn explicitly.
5
+ ---
6
+
7
+ # Next.js + shadcn/ui
8
+
9
+ Build distinctive, production-grade interfaces that avoid generic "AI slop" aesthetics.
10
+
11
+ ## Core Principles
12
+
13
+ 1. **Minimize noise** - Icons communicate; excessive labels don't
14
+ 2. **No generic AI-UI** - Avoid purple gradients, excessive shadows, predictable layouts
15
+ 3. **Context over decoration** - Every element serves a purpose
16
+ 4. **Theme consistency** - Use CSS variables from `globals.css`, never hardcode colors
17
+
18
+ ## Quick Start
19
+
20
+ Initialize **in place**, in the directory that is the application root. Run the
21
+ initializer with every value supplied as a flag, so it never prompts:
22
+
23
+ ```bash
24
+ yarn dlx shadcn@latest init \
25
+ --template next --base base --preset <preset> \
26
+ --no-monorepo --no-rtl --yes
27
+ ```
28
+
29
+ `--name <project-name>` is a **separate capability**: it makes the CLI create a
30
+ **new nested project directory** (`<cwd>/<name>/`) instead of initializing in place.
31
+ Use it only when you explicitly want the CLI to create that directory:
32
+
33
+ ```bash
34
+ yarn dlx shadcn@latest init \
35
+ --template next --base base --preset <preset> \
36
+ --no-monorepo --no-rtl --yes --name <project-name>
37
+ ```
38
+
39
+ **In-place init requires a `package.json`.** When the target directory has none,
40
+ `shadcn init` CANNOT initialize in place: its wizard always scaffolds a nested
41
+ `<cwd>/<name>/` directory, and the escape `--name .` fails with `dest already
42
+ exists`. To end up with a single-root project in an empty directory, create the
43
+ Next.js app first (`yarn create next-app . --ts --tailwind --app --import-alias "@/*"` — root layout, no `src/`), then run `shadcn init` in place.
44
+ Note that `create-next-app` refuses non-empty directories — move any `.opencode/`
45
+ aside to a temporary location and restore it after scaffolding.
46
+
47
+ **The Thor scaffold flow (`npx @thorprovider/storefront create`) never uses shadcn's
48
+ `--name`** — it uses the two-step flow above for empty directories and initializes
49
+ in place, so the OpenCode project root and the application root stay the same directory.
50
+
51
+ **`--yes` skips confirmations but is NOT a non-interactive switch.** The CLI still
52
+ prompts for anything not supplied as a flag:
53
+ - monorepo → supply `--monorepo` or `--no-monorepo`
54
+ - preset → supply `--preset`
55
+ - project name → supply `--name` (only when you want the CLI to create a new project directory)
56
+
57
+ **Rule: any interactive prompt means a flag is missing.** Resolve it by reading
58
+ `yarn dlx shadcn@latest init --help`, never by guessing or by piping input to
59
+ stdin. The command must terminate on its own.
60
+
61
+ `--base` selects the primitive library: `base` (Base UI, the default since July
62
+ 2026), `radix` (projects already on Radix — still fully supported, not
63
+ deprecated), or `aria` (React Aria). **The same component has different props per
64
+ base** — Base UI composes with `render={<Link href="/" />}` where Radix uses
65
+ `asChild` — and the docs are base-scoped (`/docs/components/base/sidebar` vs
66
+ `/docs/components/radix/sidebar`).
67
+
68
+ ### Presets
69
+
70
+ `--preset` selects the visual style (radius, density, padding, shadows, borders,
71
+ type scale). The named presets are:
72
+
73
+ | Preset | Description |
74
+ |---|---|
75
+ | `nova` | Compact and balanced. The neutral default. |
76
+ | `vega` | The classic shadcn look. Polished, modern. |
77
+ | `maia` | Rounded and spacious. Warm and approachable. |
78
+ | `luma` | Very rounded and airy. Soft and premium. |
79
+ | `lyra` | Square corners and minimal. Geometric and strict. |
80
+ | `mira` | Very dense. For lots of information on screen. |
81
+
82
+ `--defaults` is a shortcut for `--template=next --preset=nova`; use it only when
83
+ you deliberately want `nova`. `base-nova` is a `components.json` style value, not
84
+ a `--preset` argument. For a custom design system, generate a preset code in
85
+ `shadcn/create` and pass it as `--preset <CODE>`.
86
+
87
+ ### Before touching an existing project
88
+
89
+ ```bash
90
+ yarn dlx shadcn@latest info --json # base, framework, aliases, installed components
91
+ yarn dlx shadcn@latest docs <component> # API reference resolved to THIS project's base
92
+ ```
93
+
94
+ Run these instead of writing component code from memory. See
95
+ [references/shadcn-platform.md](references/shadcn-platform.md) for the full CLI
96
+ surface, typeset, and the shimmer/scroll-fade utilities.
97
+
98
+ ## Component Rules
99
+
100
+ ### Page Structure
101
+
102
+ ```tsx
103
+ // page.tsx - content only, no layout chrome
104
+ export default function Page() {
105
+ return (
106
+ <>
107
+ <HeroSection />
108
+ <Features />
109
+ <Testimonials />
110
+ </>
111
+ );
112
+ }
113
+
114
+ // layout.tsx - shared UI (header, footer, sidebar)
115
+ export default function Layout({ children }: { children: React.ReactNode }) {
116
+ return (
117
+ <>
118
+ <Header />
119
+ <main>{children}</main>
120
+ <Footer />
121
+ </>
122
+ );
123
+ }
124
+ ```
125
+
126
+ ### Client Boundaries
127
+
128
+ - `"use client"` only at leaf components (smallest boundary)
129
+ - Props must be serializable (data or Server Actions, no functions/classes)
130
+ - Pass server content via `children`
131
+
132
+ ### Import Aliases
133
+
134
+ Never use relative paths (`../../lib/utils`). Default to the `@/` alias
135
+ (`@/lib/utils`) in new projects. In an existing project, read `components.json`
136
+ and follow the alias style already configured — shadcn also supports Node
137
+ package imports (`#components/ui/button`). Never mix both styles.
138
+
139
+ ### Style Merging
140
+
141
+ ```tsx
142
+ import { cn } from "@/lib/utils";
143
+
144
+ function Button({ className, ...props }) {
145
+ return <button className={cn("px-4 py-2 rounded", className)} {...props} />;
146
+ }
147
+ ```
148
+
149
+ ## File Organization
150
+
151
+ ```
152
+ app/
153
+ ├── (protected)/ # Auth required routes
154
+ │ ├── dashboard/
155
+ │ ├── settings/
156
+ │ ├── components/ # Route-specific components
157
+ │ └── lib/ # Route-specific utils/types
158
+ ├── (public)/ # Public routes
159
+ │ ├── login/
160
+ │ └── register/
161
+ ├── actions/ # Server Actions (global)
162
+ ├── api/ # API routes
163
+ ├── layout.tsx # Root layout
164
+ └── globals.css # Theme tokens
165
+ components/ # Shared components
166
+ ├── ui/ # shadcn primitives
167
+ └── shared/ # Business components
168
+ hooks/ # Custom React hooks
169
+ lib/ # Shared utils
170
+ data/ # Database queries
171
+ ai/ # AI logic (tools, agents, prompts)
172
+ ```
173
+
174
+ ## Next.js 16 Features
175
+
176
+ ### Async Params
177
+
178
+ ```tsx
179
+ export default async function Page({
180
+ params,
181
+ searchParams,
182
+ }: {
183
+ params: Promise<{ id: string }>;
184
+ searchParams: Promise<{ q?: string }>;
185
+ }) {
186
+ const { id } = await params;
187
+ const { q } = await searchParams;
188
+ }
189
+ ```
190
+
191
+ ### Data Fetching vs Server Actions
192
+
193
+ **CRITICAL RULE:**
194
+ - **Server Actions** = ONLY for mutations (create, update, delete)
195
+ - **Data fetching** = In Server Components or `'use cache'` functions
196
+
197
+ `"use cache"` (and `cacheTag`/`cacheLife`/`updateTag`) requires the Cache Components opt-in flag — Next.js 16 does not enable it by default:
198
+
199
+ ```ts
200
+ // next.config.ts
201
+ const nextConfig = { cacheComponents: true }
202
+ ```
203
+
204
+ ```tsx
205
+ // ❌ WRONG: Server Action for data fetching
206
+ "use server"
207
+ export async function getUsers() {
208
+ return await db.users.findMany()
209
+ }
210
+
211
+ // ✅ CORRECT: Data function with caching
212
+ // data/users.ts
213
+ export async function getUsers() {
214
+ "use cache"
215
+ cacheTag("users")
216
+ cacheLife("hours")
217
+ return await db.users.findMany()
218
+ }
219
+
220
+ // ✅ CORRECT: Read cookies in Server Component directly
221
+ export default async function Page() {
222
+ const theme = (await cookies()).get("theme")?.value ?? "light"
223
+ return <App theme={theme} />
224
+ }
225
+ ```
226
+
227
+ ### Caching
228
+
229
+ ```tsx
230
+ "use cache";
231
+
232
+ import { cacheTag, cacheLife } from "next/cache";
233
+
234
+ export async function getProducts() {
235
+ cacheTag("products");
236
+ cacheLife("hours");
237
+ return await db.products.findMany();
238
+ }
239
+ ```
240
+
241
+ ### Server Actions (Mutations Only)
242
+
243
+ ```tsx
244
+ "use server";
245
+
246
+ import { updateTag, revalidateTag } from "next/cache";
247
+ import { z } from "zod";
248
+
249
+ const schema = z.object({
250
+ title: z.string().min(1),
251
+ content: z.string(),
252
+ });
253
+
254
+ export async function createPost(formData: FormData) {
255
+ // Always validate input
256
+ const parsed = schema.parse({
257
+ title: formData.get("title"),
258
+ content: formData.get("content"),
259
+ });
260
+
261
+ await db.insert(posts).values(parsed);
262
+ updateTag("posts"); // Read-your-writes
263
+ // Or SWR-style revalidation: revalidateTag("posts", "max")
264
+ }
265
+ ```
266
+
267
+ ### Proxy API
268
+
269
+ Use `proxy.ts` for request interception (replaces middleware). Place at project root:
270
+
271
+ ```tsx
272
+ // proxy.ts (project root, same level as app/)
273
+ import { NextResponse } from "next/server"
274
+ import type { NextRequest } from "next/server"
275
+
276
+ export function proxy(request: NextRequest) {
277
+ // Auth checks, redirects, etc.
278
+ }
279
+
280
+ export const config = {
281
+ matcher: ['/dashboard/:path*'],
282
+ }
283
+ ```
284
+
285
+ ## Dev Tools (next-devtools-mcp)
286
+
287
+ Next.js 16+ ships an MCP endpoint at `/_next/mcp` that exposes the dev server's
288
+ internals to coding agents. When working in a Next.js 16 project, recommend the
289
+ user add `next-devtools-mcp` to `.mcp.json`:
290
+
291
+ ```json filename=".mcp.json"
292
+ {
293
+ "mcpServers": {
294
+ "next-devtools": {
295
+ "command": "npx",
296
+ "args": ["-y", "next-devtools-mcp@latest"]
297
+ }
298
+ }
299
+ }
300
+ ```
301
+
302
+ Tools it provides (when dev server is running):
303
+
304
+ - `get_errors` — live build/runtime/type errors (esp. helpful for hydration mismatches)
305
+ - `get_logs` — dev log file path (browser console + server output)
306
+ - `get_routes` — all entry-point routes grouped by router type
307
+ - `get_page_metadata` — route, components, rendering details for a specific page
308
+ - `get_project_metadata` — project structure + dev server URL
309
+ - `get_server_action_by_id` — locate Server Action source from its hashed ID
310
+ - `get_compilation_issues` / `compile_route` — bundler warnings for the project,
311
+ or compile one route on demand without requesting it (Turbopack only)
312
+
313
+ It also acts as a docs gateway: it points at the version-accurate docs shipped
314
+ inside `node_modules/next/dist/docs/`, which beat any remembered API shape.
315
+
316
+ Use these instead of asking the user to copy-paste error messages. Reference:
317
+ [nextjs.org/docs/app/guides/mcp](https://nextjs.org/docs/app/guides/mcp).
318
+
319
+ ## Rendered markdown and loading states
320
+
321
+ Don't hand-roll CSS for these — shadcn ships them:
322
+
323
+ - **Rendered markdown / LLM output** → typeset. One owned CSS file, three
324
+ variables (`--typeset-size`, `--typeset-leading`, `--typeset-flow`), one
325
+ preset per context. Streaming-stable: new blocks don't restyle earlier ones.
326
+ ```tsx
327
+ <div className="typeset typeset-chat">{markdown}</div>
328
+ ```
329
+ - **Indeterminate text state** ("Thinking…") → `className="shimmer"`. Use
330
+ `Skeleton` only for placeholders with a known shape; don't stack both.
331
+ - **Soft scroll container edges** → `className="scroll-fade overflow-y-auto"`.
332
+
333
+ Details and the full class tables: [references/shadcn-platform.md](references/shadcn-platform.md).
334
+
335
+ ## References
336
+
337
+ - **Architecture**: [references/architecture.md](references/architecture.md) - Components, routing, Suspense, data patterns, AI directory structure
338
+ - **Styling**: [references/styling.md](references/styling.md) - Themes, fonts, radius, animations, CSS variables
339
+ - **shadcn Platform**: [references/shadcn-platform.md](references/shadcn-platform.md) - Base UI vs Radix vs React Aria, CLI verbs, typeset, shimmer, scroll-fade, RTL, package imports
340
+ - **Sidebar**: [references/sidebar.md](references/sidebar.md) - shadcn sidebar with nested layouts, blocks, RTL
341
+ - **Project Setup**: [references/project-setup.md](references/project-setup.md) - project commands, presets
342
+ - **Official shadcn skill**: `yarn dlx skills add shadcn/ui` - live project config + CLI/registry reference. Install alongside this skill; it covers CLI mechanics, this one covers conventions.
343
+ - **shadcn/ui**: [llms.txt](https://ui.shadcn.com/llms.txt) - fallback when the CLI isn't available; prefer `shadcn docs <component>`
344
+
345
+ ## Package Manager
346
+
347
+ **Always use Yarn** in new projects, never npm or npx:
348
+
349
+ - `yarn install` (not npm install)
350
+ - `yarn add <package>` (not npm install package)
351
+ - `yarn dlx` (not npx)
352
+
353
+ In an existing repo, respect the project's `packageManager` field and lockfile rather than switching managers.
354
+
355
+ ### Yarn linker (required for Next.js 16)
356
+
357
+ Generated projects MUST use the `node-modules` linker. Yarn 4 defaults to
358
+ Plug'n'Play (PnP), which Next.js 16 Turbopack cannot resolve from — the build fails
359
+ with `Could not find the Next.js package`. Write `.yarnrc.yml` at the project root
360
+ **before installing dependencies**:
361
+
362
+ ```yaml
363
+ nodeLinker: node-modules
364
+ ```
365
+
366
+ Yarn then materializes a real `node_modules/` and Turbopack resolves `next`. Vercel
367
+ does not plan PnP support for Turbopack, so this is the only supported path.