@thorprovider/storefront 0.4.0-mvp.0 → 0.4.0-mvp.2
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.
- package/README.md +173 -153
- package/VENDOR.md +69 -0
- package/assets/openspec/config.yaml +38 -0
- package/assets/templates/AGENTS.md +76 -0
- package/assets/templates/app/app/[[...slug]]/page.tsx +42 -1
- package/assets/templates/app/app/[[...slug]]/renderer.tsx +13 -2
- package/assets/templates/app/app/globals.css +5 -8
- package/assets/templates/app/app/layout.tsx +1 -5
- package/assets/templates/app/app/robots.ts +9 -3
- package/assets/templates/app/app/sitemap.ts +64 -5
- package/assets/templates/app/lib/__STOREFRONT__/actions.ts +70 -0
- package/assets/templates/app/lib/__STOREFRONT__/catalog.ts +15 -5
- package/assets/templates/app/lib/__STOREFRONT__/commerce.ts +71 -0
- package/assets/templates/app/lib/__STOREFRONT__/composition.ts +26 -0
- package/assets/templates/app/lib/__STOREFRONT__/handlers.core.ts +36 -4
- package/assets/templates/app/lib/__STOREFRONT__/registry.tsx +82 -50
- package/assets/templates/app/lib/__STOREFRONT__/runtime.ts +3 -0
- package/assets/templates/app/lib/__STOREFRONT__/schema.ts +29 -14
- package/assets/templates/app/lib/__STOREFRONT__/section-observation.ts +182 -0
- package/assets/templates/app/lib/__STOREFRONT__/section-sources.ts +130 -0
- package/assets/templates/app/lib/__STOREFRONT__/shell/content.ts +31 -7
- package/assets/templates/app/lib/__STOREFRONT__/shell/props.ts +4 -0
- package/assets/templates/app/lib/__STOREFRONT__/spec/index.ts +56 -26
- package/assets/templates/app/lib/__STOREFRONT__/spec/seo.ts +165 -0
- package/assets/templates/app/lib/__STOREFRONT__/store-context.ts +26 -7
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/index.ts +2 -1
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/products.client.tsx +100 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/products.tsx +19 -0
- package/assets/templates/app/lib/__STOREFRONT__/views/sections/schema.products.ts +39 -0
- package/assets/templates/features/checkout/handlers.ts +6 -0
- package/assets/templates/features/customer-auth/state.ts +10 -1
- package/assets/templates/views/account/index.tsx +1 -1
- package/assets/templates/views/account/registry.tsx +80 -19
- package/assets/templates/views/account/schema.ts +1 -0
- package/assets/templates/views/cart/content.ts +11 -0
- package/assets/templates/views/cart/data.ts +23 -0
- package/assets/templates/views/cart/index.tsx +53 -0
- package/assets/templates/views/cart/props.ts +12 -0
- package/assets/templates/views/cart/registry.tsx +81 -0
- package/assets/templates/views/cart/schema.ts +52 -0
- package/assets/templates/views/category/assembly/assembly.json +1 -0
- package/assets/templates/views/category/assembly/index.skeleton.tsx +64 -6
- package/assets/templates/views/category/assembly/registry.skeleton.tsx +2 -1
- package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/binding.json +5 -0
- package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/catalog.part +4 -0
- package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/element.part +7 -0
- package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/registry.part +18 -0
- package/assets/templates/views/category/index.tsx +76 -7
- package/assets/templates/views/category/props.ts +7 -0
- package/assets/templates/views/category/registry.tsx +19 -0
- package/assets/templates/views/category/schema.ts +13 -0
- package/assets/templates/views/home/assembly/assembly.json +9 -0
- package/assets/templates/views/home/assembly/index.skeleton.tsx +22 -4
- package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/element.part +1 -1
- package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/registry.part +2 -2
- package/assets/templates/views/home/data.ts +9 -0
- package/assets/templates/views/home/index.tsx +23 -5
- package/assets/templates/views/home/registry.tsx +2 -2
- package/assets/templates/views/product/data.ts +4 -2
- package/assets/templates/views/product/index.tsx +49 -5
- package/assets/templates/views/product/props.ts +7 -0
- package/assets/templates/views/product/registry.tsx +25 -0
- package/assets/templates/views/product/schema.ts +13 -0
- package/assets/templates/views/static/content.ts +4 -4
- package/assets/templates/views/static/index.tsx +1 -1
- package/bin/storefront.js +1231 -154
- package/examples/merchandising/category-led.json +37 -0
- package/examples/merchandising/collection-led.json +37 -0
- package/package.json +11 -7
- package/recipes/archetypes.json +9 -22
- package/recipes/catalog.json +40 -1
- package/recipes/features.json +25 -2
- package/recipes/recipe.schema.json +1 -1
- package/recipes/recipes.json +32 -30
- package/recipes/sections.json +10 -0
- package/recipes/validate.mjs +54 -0
- package/scripts/candidate.mjs +4 -4
- package/scripts/composers.mjs +25 -5
- package/scripts/env-file.mjs +86 -0
- package/scripts/file-classes.mjs +5 -0
- package/scripts/migrate-english-routes.mjs +276 -0
- package/scripts/pinning.mjs +74 -5
- package/scripts/plan-apply.mjs +149 -5
- package/scripts/reconcile.mjs +49 -11
- package/scripts/render-templates.mjs +97 -44
- package/scripts/section-config.mjs +253 -0
- package/scripts/starter.mjs +17 -0
- package/scripts/theme/color.mjs +185 -0
- package/scripts/theme/css-theme.mjs +233 -0
- package/scripts/theme/fonts.mjs +123 -0
- package/scripts/theme/import-export.mjs +125 -0
- package/scripts/theme/preset.mjs +93 -0
- package/scripts/theme/theme-plan.mjs +292 -0
- package/scripts/theme/tokens.mjs +137 -0
- package/scripts/view-assembly.mjs +47 -1
- package/skills/sf-feature/SKILL.md +32 -19
- package/skills/sf-setup/SKILL.md +79 -0
- package/skills/sf-theme-gen/SKILL.md +99 -36
- package/skills/sf-theme-gen/references/shadcn-theming.md +87 -0
- package/skills/{shadcn-theming/references/templates → sf-theme-gen/references}/theme-setup.md +15 -19
- package/skills/{shadcn-theming → sf-theme-gen}/references/theming-guide.md +6 -11
- package/skills/sf-view-gen/SKILL.md +63 -40
- package/skills/sf-view-gen/assets/recipes/archetypes.json +9 -22
- package/skills/sf-view-gen/assets/recipes/catalog.json +40 -1
- package/skills/sf-view-gen/assets/recipes/features.json +25 -2
- package/skills/sf-view-gen/assets/recipes/recipes.json +32 -30
- package/skills/sf-view-gen/assets/recipes/sections.json +10 -0
- package/skills/sf-view-gen/assets/templates/views/sections/products.client.tsx +100 -0
- package/skills/sf-view-gen/assets/templates/views/sections/products.tsx +19 -0
- package/skills/sf-view-gen/assets/templates/views/sections/schema.products.ts +39 -0
- package/skills/{json-render-core/SKILL.md → sf-view-gen/references/json-render-core.md} +4 -27
- package/skills/{json-render-next/SKILL.md → sf-view-gen/references/json-render-next.md} +5 -8
- package/skills/{json-render-react/SKILL.md → sf-view-gen/references/json-render-react.md} +3 -5
- package/skills/{json-render-shadcn/SKILL.md → sf-view-gen/references/json-render-shadcn.md} +3 -5
- package/skills/sf-view-gen/references/views.md +28 -37
- package/skills/sf-view-gen/scripts/validate.mjs +54 -0
- package/skills/storefront-workflow/SKILL.md +94 -31
- package/skills/{storefront-best-practices/reference/design.md → storefront-workflow/references/design-consistency.md} +13 -29
- package/CHANGELOG.md +0 -84
- package/assets/templates/views/user-panel/index.tsx +0 -106
- package/assets/templates/views/user-panel/registry.tsx +0 -54
- package/assets/templates/views/user-panel/schema.ts +0 -79
- package/commands/sf-add-view.md +0 -57
- package/commands/sf-feature.md +0 -28
- package/commands/sf-theme.md +0 -26
- package/commands/sf-view.md +0 -67
- package/skills/building-storefronts/SKILL.md +0 -178
- package/skills/building-storefronts/references/frontend-integration.md +0 -229
- package/skills/json-render-remotion/SKILL.md +0 -111
- package/skills/json-render-solid/SKILL.md +0 -204
- package/skills/nextjs-shadcn/SKILL.md +0 -367
- package/skills/nextjs-shadcn/references/architecture.md +0 -499
- package/skills/nextjs-shadcn/references/project-setup.md +0 -162
- package/skills/nextjs-shadcn/references/shadcn-platform.md +0 -261
- package/skills/nextjs-shadcn/references/sidebar.md +0 -274
- package/skills/nextjs-shadcn/references/styling.md +0 -555
- package/skills/shadcn-component-discovery/SKILL.md +0 -273
- package/skills/shadcn-component-discovery/references/registries.md +0 -226
- package/skills/shadcn-theming/SKILL.md +0 -104
- package/skills/storefront-best-practices/SKILL.md +0 -421
- package/skills/storefront-best-practices/reference/components/breadcrumbs.md +0 -123
- package/skills/storefront-best-practices/reference/components/cart-popup.md +0 -189
- package/skills/storefront-best-practices/reference/components/country-selector.md +0 -298
- package/skills/storefront-best-practices/reference/components/footer.md +0 -112
- package/skills/storefront-best-practices/reference/components/hero.md +0 -241
- package/skills/storefront-best-practices/reference/components/megamenu.md +0 -239
- package/skills/storefront-best-practices/reference/components/navbar.md +0 -397
- package/skills/storefront-best-practices/reference/components/popups.md +0 -221
- package/skills/storefront-best-practices/reference/components/product-card.md +0 -125
- package/skills/storefront-best-practices/reference/components/product-reviews.md +0 -217
- package/skills/storefront-best-practices/reference/components/product-slider.md +0 -174
- package/skills/storefront-best-practices/reference/components/search.md +0 -101
- package/skills/storefront-best-practices/reference/connecting-to-backend.md +0 -391
- package/skills/storefront-best-practices/reference/features/promotions.md +0 -307
- package/skills/storefront-best-practices/reference/features/wishlist.md +0 -230
- package/skills/storefront-best-practices/reference/layouts/account.md +0 -380
- package/skills/storefront-best-practices/reference/layouts/cart.md +0 -316
- package/skills/storefront-best-practices/reference/layouts/checkout.md +0 -486
- package/skills/storefront-best-practices/reference/layouts/home-page.md +0 -264
- package/skills/storefront-best-practices/reference/layouts/order-confirmation.md +0 -231
- package/skills/storefront-best-practices/reference/layouts/product-details.md +0 -527
- package/skills/storefront-best-practices/reference/layouts/product-listing.md +0 -520
- package/skills/storefront-best-practices/reference/layouts/static-pages.md +0 -356
- package/skills/storefront-best-practices/reference/medusa.md +0 -307
- /package/skills/{storefront-best-practices/reference → storefront-workflow/references}/mobile-responsiveness.md +0 -0
- /package/skills/{storefront-best-practices/reference → storefront-workflow/references}/seo.md +0 -0
package/README.md
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "@thorprovider/storefront"
|
|
3
|
-
purpose: "Deterministic storefront scaffolder and installable
|
|
4
|
-
lastReviewed: "2026-10-
|
|
3
|
+
purpose: "Deterministic storefront scaffolder and installable skill suite for Thor Commerce"
|
|
4
|
+
lastReviewed: "2026-10-14"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# @thorprovider/storefront
|
|
8
8
|
|
|
9
|
-
Deterministic storefront scaffolder and installable
|
|
9
|
+
Deterministic storefront scaffolder and installable skill suite for Thor Commerce.
|
|
10
10
|
|
|
11
|
-
`npx @thorprovider/storefront create <dir>` scaffolds a complete, buildable storefront
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
`npx @thorprovider/storefront create <dir>` scaffolds a complete, buildable storefront,
|
|
12
|
+
installs its OpenCode skill suite into `<dir>/.opencode/skills/`, and writes a managed
|
|
13
|
+
root `AGENTS.md` — all from static templates, a recipe registry, and vendored skills,
|
|
14
|
+
with nothing else from the monorepo needed at generation time.
|
|
15
|
+
|
|
16
|
+
A generated storefront ships **no `/sf-*` commands**. Guidance lives in the root
|
|
17
|
+
`AGENTS.md`, which states the authority rules and routes an intent (add a view, change
|
|
18
|
+
the theme, add a feature, connect a backend) to the skill that owns the procedure: open
|
|
19
|
+
the project in OpenCode and ask in natural language. The `storefront` CLI stays the
|
|
20
|
+
structural authority.
|
|
16
21
|
|
|
17
22
|
This README is organised in two parts:
|
|
18
23
|
|
|
@@ -50,37 +55,36 @@ cache (`~/.yarn/berry/cache`); repeat scaffolds then download no packages, and
|
|
|
50
55
|
|
|
51
56
|
### Install
|
|
52
57
|
|
|
53
|
-
Run the scaffolder directly from npm — no global install required
|
|
54
|
-
`yarn dlx
|
|
58
|
+
Run the scaffolder directly from npm — no global install required; the equivalent is
|
|
59
|
+
`yarn dlx @thorprovider/storefront`:
|
|
55
60
|
|
|
56
61
|
```bash
|
|
57
62
|
npx @thorprovider/storefront create my-shop \
|
|
58
63
|
--site-name "My Shop" \
|
|
59
|
-
--backend-url http://localhost:9000 \
|
|
60
64
|
--preset maia
|
|
61
65
|
```
|
|
62
66
|
|
|
63
|
-
```bash
|
|
64
|
-
yarn dlx @thorprovider/storefront create my-shop --preset maia
|
|
65
|
-
```
|
|
66
|
-
|
|
67
67
|
The first positional argument is the target directory: it is created if missing, and
|
|
68
68
|
it is where `.opencode/`, the Next.js app, and `lib/<name>/` live. Run the command
|
|
69
69
|
from the parent directory you want the project created in.
|
|
70
70
|
|
|
71
71
|
In a terminal, `create` runs an interactive wizard for any input you omit (name,
|
|
72
|
-
site name,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
site name, preset — Maia is preselected); an empty prompt accepts the suggested
|
|
73
|
+
default (name from the target basename, site name from its Title Case). Without a
|
|
74
|
+
terminal every required input must be a flag — the command fails fast and writes
|
|
75
|
+
nothing. Brand color is never prompted: pass `--brand`, or change it later in natural
|
|
76
|
+
language (the theme skill runs `storefront theme`).
|
|
77
|
+
|
|
78
|
+
`create` is structural and offline: it scaffolds a storefront that runs in **mock
|
|
79
|
+
mode** with no backend. Connecting a real backend is a separate, re-runnable step —
|
|
80
|
+
run `storefront setup` from inside the project (see [Backend
|
|
81
|
+
configuration](#backend-configuration)).
|
|
79
82
|
|
|
80
83
|
Once the package is installed as a dependency, the shorter binary form is available:
|
|
81
84
|
|
|
82
85
|
```bash
|
|
83
|
-
storefront create my-shop --preset maia # scaffold + install the suite
|
|
86
|
+
storefront create my-shop --preset maia # scaffold + install the suite (mock mode)
|
|
87
|
+
storefront setup --publishable-key <key> --region-id <id> # connect a real backend
|
|
84
88
|
storefront update # refresh an existing install
|
|
85
89
|
storefront doctor # report the recorded version and status
|
|
86
90
|
```
|
|
@@ -95,7 +99,6 @@ project root that will hold `.opencode/`:
|
|
|
95
99
|
storefront create my-shop \
|
|
96
100
|
--name my-shop \
|
|
97
101
|
--site-name "My Shop" \
|
|
98
|
-
--backend-url http://localhost:9000 \
|
|
99
102
|
--preset maia \
|
|
100
103
|
[--brand orange]
|
|
101
104
|
```
|
|
@@ -105,25 +108,23 @@ storefront create my-shop \
|
|
|
105
108
|
| `<dir>` (positional) | target project directory (created if missing) | required |
|
|
106
109
|
| `--name <name>` | kebab-case storefront name = `lib/<name>/` = `__STOREFRONT__` | prompted in the wizard |
|
|
107
110
|
| `--site-name <name>` | human site name (`__SITE_NAME__`) | Title Case of `<name>` (`my-shop` → `My Shop`) |
|
|
108
|
-
| `--backend-url <url>` | Medusa backend URL | `http://localhost:9000` |
|
|
109
111
|
| `--preset <preset>` | visual preset: `maia`, `nova`, `vega`, `luma`, `lyra`, `mira` | prompted in the wizard (Maia preselected) |
|
|
110
|
-
| `--
|
|
112
|
+
| `--starter` | seed the full curated composition — every curated view and feature — instead of the minimal `home`+`cart` baseline | off |
|
|
113
|
+
| `--brand <color>` | named brand color (`orange`, `blue`, …) applied as a chromatic primary family (primary/foreground/ring/nav) over the preset tokens (never prompted) | none |
|
|
111
114
|
| `--force`, `-f` | overwrite files that already exist | off |
|
|
112
115
|
|
|
113
|
-
The pipeline runs: preconditions → Next.js base (files only
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
placeholder substitution → default-page removal → `.env.local` + theme → suite
|
|
117
|
-
install into `.opencode/`.
|
|
116
|
+
The pipeline runs: preconditions → Next.js base (files only) → `.yarnrc.yml`
|
|
117
|
+
(`nodeLinker: node-modules`) → shadcn base with the preset → dependency install →
|
|
118
|
+
template copy + placeholder substitution → mock `.env.local` + theme → suite install.
|
|
118
119
|
|
|
119
|
-
Same inputs produce a byte-identical tree (verified by recursive `diff -r`).
|
|
120
|
-
`create` twice with different inputs is the only reason the output differs.
|
|
120
|
+
Same inputs produce a byte-identical tree (verified by recursive `diff -r`).
|
|
121
121
|
|
|
122
|
-
The suite install copies
|
|
123
|
-
skills
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
The suite install copies the shipped skills (own and vendored, flat) into
|
|
123
|
+
`<dir>/.opencode/skills/`, verifying generated copies against their source first. It
|
|
124
|
+
records the installed version in `.opencode/storefront.json` and is idempotent
|
|
125
|
+
(`--force` overwrites). `create` also writes the managed root `AGENTS.md` from the
|
|
126
|
+
derived template path, so `storefront sync` refreshes it and `storefront doctor`
|
|
127
|
+
reports drift.
|
|
127
128
|
|
|
128
129
|
### Run the storefront
|
|
129
130
|
|
|
@@ -134,69 +135,70 @@ cd my-shop
|
|
|
134
135
|
yarn dev
|
|
135
136
|
```
|
|
136
137
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
A fresh `create` seeds `home` + `cart` (home hero/benefits/category sections, a
|
|
139
|
+
navbar-owned cart sheet, a standalone `/cart` review route). Pass `--starter` to
|
|
140
|
+
seed the full curated composition instead — every curated view and feature, read
|
|
141
|
+
from the registry, held units excluded. Everything renders with only
|
|
142
|
+
`@thorprovider/blocks` (UI) and `@thorprovider/adapters` (data). Then grow it by asking
|
|
143
|
+
in natural language — the `AGENTS.md` router maps each intent to a skill that delegates
|
|
144
|
+
the structural write to the CLI:
|
|
140
145
|
|
|
141
146
|
```
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
147
|
+
add a product view # the view skill runs `storefront view add product`
|
|
148
|
+
add a testimonials section to home # the view skill composes the section, then syncs
|
|
149
|
+
change the theme to dark with a teal brand # the theme skill runs `storefront theme`
|
|
150
|
+
connect the backend to my Medusa store # the setup skill runs `storefront setup`
|
|
145
151
|
```
|
|
146
152
|
|
|
147
153
|
### Backend configuration
|
|
148
154
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
blank placeholders for the store identity, plus a committed `.env.example` that
|
|
153
|
-
documents every variable (never a real secret):
|
|
155
|
+
`create` writes a git-ignored `.env.local` that starts the store in **mock mode** —
|
|
156
|
+
no backend, a generated cookie secret, the store identity — plus a committed
|
|
157
|
+
`.env.example` documenting every variable:
|
|
154
158
|
|
|
155
159
|
```bash
|
|
156
|
-
# .env.local (git-ignored)
|
|
157
|
-
THOR_DATA_SOURCE=
|
|
158
|
-
MEDUSA_BASE_URL=http://localhost:9000
|
|
159
|
-
MEDUSA_PUBLISHABLE_KEY=
|
|
160
|
-
MEDUSA_REGION_ID=
|
|
161
|
-
MEDUSA_SALES_CHANNEL_ID=
|
|
160
|
+
# .env.local (git-ignored) — written by create
|
|
161
|
+
THOR_DATA_SOURCE=mock
|
|
162
162
|
THOR_STORE_ID=my-shop
|
|
163
|
-
THOR_CURRENCY_CODE=
|
|
164
163
|
THOR_SESSION_SECRET=<generated per install>
|
|
165
164
|
```
|
|
166
165
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
166
|
+
Mock mode is complete: views and the cart render from labelled demo data with no
|
|
167
|
+
configuration. To connect a real backend, run `storefront setup` from inside the project:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
storefront setup --publishable-key <key> --sales-channel-id <id> --region-id <region-id> [--backend-url <url>]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
In a terminal, `setup` prompts for the backend URL, publishable key, sales channel id,
|
|
174
|
+
and region. It takes the sales channel id as an explicit input (Medusa admin → Settings
|
|
175
|
+
→ Sales Channels), derives the region's currency (`GET /store/regions`), then **upserts**
|
|
176
|
+
only the keys it manages — `THOR_STORE_ID`, `THOR_SESSION_SECRET`, and user additions are
|
|
177
|
+
untouched. It is re-runnable (rotate the key, change the channel or region, re-point the
|
|
178
|
+
backend). Without a publishable key it stays in mock mode; without a channel id it reports the missing input and stays in mock mode.
|
|
179
|
+
|
|
180
|
+
The store context is **explicit and validated** in real mode: `MEDUSA_SALES_CHANNEL_ID`
|
|
181
|
+
scopes the store, `MEDUSA_REGION_ID` supplies currency, countries, and shipping, and
|
|
182
|
+
`MEDUSA_CURRENCY_CODE` (ISO 4217) comes from the environment and is **never hardcoded**.
|
|
183
|
+
`THOR_SESSION_SECRET` is the host-only cookie signing secret (≥16 chars, 32 recommended).
|
|
184
|
+
|
|
185
|
+
> **Renamed:** the currency variable was `THOR_CURRENCY_CODE` and is now
|
|
186
|
+
> `MEDUSA_CURRENCY_CODE`. An existing store renames it in `.env.local`, or re-runs
|
|
187
|
+
> `storefront setup`, which writes it.
|
|
188
|
+
|
|
189
|
+
`THOR_DATA_SOURCE` selects the mode **explicitly** and is never inferred from a failure.
|
|
190
|
+
`mock` renders labelled demo data and resolves a fixture store context in code (channel
|
|
191
|
+
`mock-sales-channel`, region `mock-region-us`, currency `USD`), so no context variables
|
|
192
|
+
are required. `medusa` uses the real backend: a missing provider or invalid config is a
|
|
193
|
+
**visible error** — never a silent fallback to demo data. Run `storefront setup`, then
|
|
194
|
+
restart `yarn dev`.
|
|
195
|
+
|
|
196
|
+
The guest flow is backend-authoritative end to end: the signed host cookie binds a
|
|
197
|
+
persistent backend cart; the PDP adds the explicitly selected variant; the cart and
|
|
198
|
+
checkout render the backend's totals; checkout applies the one approved manual TEST
|
|
199
|
+
provider and completes the cart with its native discriminator. An ambiguous completion
|
|
200
|
+
is never retried — the shopper reconciles the committed cart, and the active cart is
|
|
201
|
+
cleared only after a confirmed order. No card data is collected at launch.
|
|
200
202
|
|
|
201
203
|
### Troubleshooting / Known Issues
|
|
202
204
|
|
|
@@ -205,14 +207,14 @@ Each entry below follows the same shape: **cause** → **symptom** → **remedy*
|
|
|
205
207
|
#### Ancestor `.opencode/`
|
|
206
208
|
|
|
207
209
|
- **Cause**: an ancestor directory already contains a `.opencode/`.
|
|
208
|
-
- **Symptom**: OpenCode resolves the wrong
|
|
210
|
+
- **Symptom**: OpenCode resolves the wrong skill set or an ancestor's `AGENTS.md`, so you see stale or unrelated behaviour.
|
|
209
211
|
- **Remedy**: scaffold in a clean root with no ancestor `.opencode/`, or remove/relocate the ancestor `.opencode/` before opening the project.
|
|
210
212
|
|
|
211
213
|
#### Non-empty target directory
|
|
212
214
|
|
|
213
215
|
- **Cause**: `lib/<name>/` already exists, or the root is already a Next.js project.
|
|
214
216
|
- **Symptom**: the run stops at the preconditions stage with `lib/<name>/ already exists — refusing to overwrite`.
|
|
215
|
-
- **Remedy**: choose a different `--name`, or remove the existing `lib/<name>/`. To extend an existing storefront,
|
|
217
|
+
- **Remedy**: choose a different `--name`, or remove the existing `lib/<name>/`. To extend an existing storefront, run the `storefront` CLI from inside it (or ask in natural language — see `AGENTS.md`); run `create` in an empty directory.
|
|
216
218
|
|
|
217
219
|
#### Missing or invalid `--preset`
|
|
218
220
|
|
|
@@ -233,81 +235,92 @@ Each entry below follows the same shape: **cause** → **symptom** → **remedy*
|
|
|
233
235
|
|
|
234
236
|
#### Backend not configured
|
|
235
237
|
|
|
236
|
-
- **Cause**: `THOR_DATA_SOURCE=medusa` but `MEDUSA_BASE_URL`/`MEDUSA_PUBLISHABLE_KEY` are missing, empty, or unreachable.
|
|
238
|
+
- **Cause**: `THOR_DATA_SOURCE=medusa` but `MEDUSA_BASE_URL`/`MEDUSA_PUBLISHABLE_KEY` are missing, empty, or unreachable (for example, a store still in mock mode).
|
|
237
239
|
- **Symptom**: the storefront renders a visible error notice (`role="alert"`) instead of backend data; real-mode failures never degrade to a fake catalog.
|
|
238
|
-
- **Remedy**:
|
|
240
|
+
- **Remedy**: run `storefront setup` from inside the project to write the real-mode variables (see [Backend configuration](#backend-configuration)), then restart `yarn dev`. To stay offline, leave `THOR_DATA_SOURCE=mock`.
|
|
239
241
|
|
|
240
242
|
---
|
|
241
243
|
|
|
242
244
|
## What gets installed
|
|
243
245
|
|
|
244
246
|
```
|
|
245
|
-
<project
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
storefront-workflow/ # the four phases + CLI/manifest authority
|
|
256
|
-
sf-view-gen/ # assets/recipes/, scripts/validate.mjs
|
|
257
|
-
sf-feature/
|
|
258
|
-
sf-theme-gen/ # assets/
|
|
259
|
-
nextjs-shadcn/
|
|
260
|
-
shadcn-theming/
|
|
261
|
-
shadcn-component-discovery/
|
|
262
|
-
storefront-best-practices/
|
|
263
|
-
building-storefronts/
|
|
247
|
+
<project>/
|
|
248
|
+
AGENTS.md # managed (derived): RULE 0 rules + intent router
|
|
249
|
+
.opencode/
|
|
250
|
+
storefront.json # install record: version, pinning, owned asset BOM
|
|
251
|
+
skills/
|
|
252
|
+
storefront-workflow/ # four phases, CLI/manifest authority; references/ = design/mobile/SEO
|
|
253
|
+
sf-view-gen/ # view generation; references/ = json-render + views.md
|
|
254
|
+
sf-feature/ # feature bundles (feature-owned views + mounts)
|
|
255
|
+
sf-theme-gen/ # theme; references/ = theming guidance
|
|
256
|
+
sf-setup/ # connect/re-point a Medusa backend via `storefront setup`
|
|
264
257
|
```
|
|
265
258
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
[`commands/sf-feature.md`](./commands/sf-feature.md) and the workflow model is
|
|
259
|
+
The suite ships exactly these five operative skills plus their scoped references;
|
|
260
|
+
the retained generic knowledge is loaded explicitly by the owning skill and is not
|
|
261
|
+
separately installable. The workflow model is
|
|
270
262
|
[`skills/storefront-workflow/SKILL.md`](./skills/storefront-workflow/SKILL.md).
|
|
263
|
+
`create`/`update` also provision the pinned `@fission-ai/openspec` suite as a co-tenant (`openspec init --tools opencode` writes `openspec/`, the `openspec-*` skills, and the `opsx-*` commands, then the CLI seeds a storefront-aware `openspec/config.yaml`); the suite never installs over or removes those co-tenanted files. A non-trivial customization runs through the spec-driven loop surfaced as explore → plan → build → verify → inform, while a deterministic CLI change recorded in `storefront.config.json` needs no change and completion waits on `storefront sync` + `storefront doctor`.
|
|
271
264
|
|
|
272
265
|
## Workflow: bootstrap → compose → customize → verify
|
|
273
266
|
|
|
274
267
|
The project manifest (`storefront.config.json`) is the structural source of truth;
|
|
275
268
|
the `storefront` CLI is the only writer of derived files; the developer/agent edits
|
|
276
|
-
only user-owned files
|
|
277
|
-
model. Every command runs from inside the
|
|
269
|
+
only user-owned files and the bounded external surface. Read the installed
|
|
270
|
+
`storefront-workflow` skill for the full model. Every command runs from inside the
|
|
271
|
+
project (no directory argument).
|
|
278
272
|
|
|
279
273
|
| Phase | Authority | Command |
|
|
280
274
|
| --- | --- | --- |
|
|
281
275
|
| **Bootstrap** | CLI only | `npx @thorprovider/storefront create <dir> --name <name> --preset <preset>` |
|
|
282
|
-
| **Compose** | CLI only (agents choose, CLI writes) | `view add\|remove`, `feature add\|remove`, `
|
|
276
|
+
| **Compose** | CLI only (agents choose, CLI writes) | `view add\|remove`, `feature add\|remove`, `section add\|remove\|move`, `theme` |
|
|
283
277
|
| **Customize** | developer/agent | edit user-owned `content.ts`/`props.ts`/`data.ts`/`schema.ts`/`mappers.ts` |
|
|
284
278
|
| **Verify** | CLI + build | `npx @thorprovider/storefront sync`, `doctor`, `yarn build` |
|
|
285
279
|
|
|
286
280
|
**Ownership classes.** *Derived* files (`views/index.ts`, `views/registry.ts`,
|
|
287
281
|
`index.tsx`, `registry.tsx`, `catalog.ts`, `runtime.ts`, `spec/index.ts`,
|
|
288
|
-
`state.ts`, `handlers.ts`, `features/*/adapter.ts`) are regenerated
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
282
|
+
`state.ts`, `handlers.ts`, `features/*/adapter.ts`) are CLI-regenerated and never
|
|
283
|
+
hand-edited. *User-owned* files (content, props, data, local schema, mappers)
|
|
284
|
+
survive `sync`. *External* files (`app/layout.tsx`, `app/globals.css`) expose a
|
|
285
|
+
**bounded** surface — theme tokens/foreground pairs, fonts, global identity — that
|
|
286
|
+
must preserve the CLI-managed wiring (stylesheet import, provider/mode markers,
|
|
287
|
+
block token contract); the CLI appends it idempotently.
|
|
288
|
+
|
|
289
|
+
**Curated composition.** The CLI registry (`storefront views --json`,
|
|
290
|
+
`features --json`, `recipes --json`) is the authority for what is installable.
|
|
291
|
+
Curated MVP views: `home`, `product`, `cart`, `category`, `checkout`, `account`,
|
|
292
|
+
`static`. Curated MVP features: `checkout` (owns the `checkout` view —
|
|
293
|
+
`view add checkout` is rejected, use `feature add checkout`), `customer-auth`
|
|
294
|
+
(owns `account`), `static-pages` (owns `static`), and the mount-only `benefits`,
|
|
295
|
+
`catalog-search`, `category-filters`, and `navigability`. `recommendations` is
|
|
296
|
+
held post-MVP and rejected before any write. `create` seeds `home` and `cart`;
|
|
297
|
+
`--starter` seeds every curated view and feature. Home editorial (`faq`, `cta`) and
|
|
298
|
+
data-bound `products` sections: see [Product sections](docs/product-sections.md).
|
|
299
|
+
|
|
300
|
+
**Cart lifecycle and checkout independence.** The cart review is a normal view,
|
|
301
|
+
not a shell element: `view add cart` installs it, `view remove cart` drops it
|
|
302
|
+
(which also hides the lateral's "View cart" action and leaves `/cart` unrouted;
|
|
303
|
+
the navbar icon still opens the compact lateral). `sync` never silently adds it
|
|
304
|
+
to an existing store — upgrading is an explicit `view add cart`. Cart and
|
|
305
|
+
checkout are independent: review works without checkout (its action is hidden),
|
|
306
|
+
and adding `checkout` never adds the cart view. The CLI derives
|
|
307
|
+
`cartViewAvailable`/`checkoutAvailable` from the installed views/features into
|
|
308
|
+
`composition.ts`, which the generated wiring reads.
|
|
301
309
|
|
|
302
310
|
**Prerequisites and pinning.** Node `>=20.9.0`, `node-modules` linker, and the
|
|
303
311
|
canonical Yarn pinned in the generated `package.json` as
|
|
304
312
|
`"packageManager": "yarn@4.5.1"` (Corepack resolves it; the scaffold runs every
|
|
305
313
|
install under that version). The generated project pins an exact compatible
|
|
306
|
-
candidate toolset and installs the
|
|
307
|
-
|
|
308
|
-
|
|
314
|
+
candidate toolset and installs the `@thorprovider/*` packages from the npm
|
|
315
|
+
registry by default. `--packs <dir>` is an optional path for local candidates
|
|
316
|
+
(published or unpublished): it maps each dependency to a packed tarball via Yarn `resolutions`
|
|
317
|
+
(no workspace import), and the CLI verifies every tarball before writing
|
|
318
|
+
anything — the manifest `name`/`version` must match the expected toolset, and the
|
|
319
|
+
packed `@thorprovider/runtime` must export every value the generated host
|
|
320
|
+
`commerce.ts` imports; a stale or mismatched pack is refused with a named code
|
|
321
|
+
before any file is written. No package-manager safety policy is suppressed: the generated
|
|
309
322
|
`.yarnrc.yml` sets no `npmPreapprovedPackages`, and the pinned versions are
|
|
310
|
-
published past Yarn's age gate. `doctor` reports the observed linker/Node/Yarn
|
|
323
|
+
intended to be published past Yarn's age gate. `doctor` reports the observed linker/Node/Yarn
|
|
311
324
|
against the declared ranges and exits non-zero on a mismatch instead of a false
|
|
312
325
|
clean stamp.
|
|
313
326
|
|
|
@@ -341,7 +354,8 @@ storefront apply --plan plan.json [--json]
|
|
|
341
354
|
The operations envelope is `{ "formatVersion": 1, "operations": [ ... ] }` (missing or
|
|
342
355
|
different `formatVersion` → `E_INVALID_ENVELOPE`). Operation names are
|
|
343
356
|
`view.add|remove|configure` and `feature.add|remove|configure`; `view add|remove` and
|
|
344
|
-
`feature add|remove` remain thin aliases over the same engine
|
|
357
|
+
`feature add|remove` remain thin aliases over the same engine, and so do
|
|
358
|
+
`section add|remove|move`/`sections [<view>]` over `section.add|remove|reorder` (see [Product sections](docs/product-sections.md)).
|
|
345
359
|
|
|
346
360
|
**What E1 proves.** The only executable non-default swap is `home.benefits`
|
|
347
361
|
`Feature1 → Feature2` (identical `BenefitsItem[]` data shape, no bridge); every bridged
|
|
@@ -354,28 +368,33 @@ options are rejected (`E_UNPROVEN_CHECKOUT_OPTION`). The category filter's actio
|
|
|
354
368
|
no-op; catalog search/filters (E2) and composable sections (E3) are **not** implemented
|
|
355
369
|
here.
|
|
356
370
|
|
|
357
|
-
##
|
|
371
|
+
## Agent guidance and skills
|
|
358
372
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
|
373
|
+
A generated storefront ships a managed root `AGENTS.md` and no `/sf-*` commands.
|
|
374
|
+
`AGENTS.md` states the non-negotiable authority rules (RULE 0) and routes each intent
|
|
375
|
+
to the skill that owns the procedure; the skill then delegates the structural write to
|
|
376
|
+
the `storefront` CLI.
|
|
377
|
+
|
|
378
|
+
| Intent | Skill | CLI it drives |
|
|
379
|
+
| --- | --- | --- |
|
|
380
|
+
| Add or remove a view; compose a view's sections; edit user-owned content/props/data | `sf-view-gen` | `storefront view add\|remove`, `section …`, `views --json` |
|
|
381
|
+
| Change colors, theme mode, typography, radius, presets, or identity/SEO metadata | `sf-theme-gen` | `storefront theme` (`--brand`, `--primary`, `--accent`, `--radius`, `--font-sans`, `--set`, `--preset`, `--import`, `--export`, `--mode`) |
|
|
382
|
+
| Add or remove a feature bundle (e.g. `checkout`) | `sf-feature` | `storefront feature add\|remove` |
|
|
383
|
+
| Connect or re-point a Medusa backend | `sf-setup` | `storefront setup` |
|
|
384
|
+
| Edit a view's content/props/data, map props or data, reshape composition, or any change whose acceptance is not a CLI assertion (non-trivial) | `storefront-workflow` | the spec-driven loop, surfaced as **explore → plan → build → verify → inform** |
|
|
365
385
|
|
|
366
|
-
Scaffolding
|
|
367
|
-
|
|
368
|
-
mode is likewise a CLI capability: `npx @thorprovider/storefront theme --mode light|dark|system`.
|
|
386
|
+
Scaffolding is `npx @thorprovider/storefront create <dir>`; connecting a real backend is
|
|
387
|
+
`storefront setup` from inside the project (see [Backend configuration](#backend-configuration)).
|
|
369
388
|
|
|
370
389
|
## Philosophy: determinism first; the LLM only where there is judgment
|
|
371
390
|
|
|
372
391
|
A storefront task is one of three kinds, and the tool follows the kind:
|
|
373
392
|
|
|
374
393
|
- **Deterministic** (output is a pure function of input) → a CLI subcommand with flags
|
|
375
|
-
(e.g. `storefront theme --
|
|
394
|
+
(e.g. `storefront theme --brand orange --radius 0.75rem`). Repeatable, reviewable, no model in the loop.
|
|
376
395
|
- **Mixed** → split it: the script applies the deterministic part, the LLM decides the
|
|
377
|
-
judgment part (
|
|
378
|
-
- **Pure judgment** → an `sf-*` skill (e.g.
|
|
396
|
+
judgment part (the `sf-theme-gen` skill chooses the brand color; `storefront theme --brand` applies it).
|
|
397
|
+
- **Pure judgment** → an `sf-*` skill (e.g. `sf-view-gen`): variant selection, copy, and
|
|
379
398
|
layout choices live here.
|
|
380
399
|
|
|
381
400
|
**Test criterion**: if you can assert the result without a model ("after this, the file
|
|
@@ -410,7 +429,7 @@ lib/<name>/
|
|
|
410
429
|
catalog.ts, registry.tsx, runtime.ts, handlers.ts, state.ts # derived shell; compose the barrel
|
|
411
430
|
mappers.ts * # user-owned: CardProduct -> block props
|
|
412
431
|
shell/
|
|
413
|
-
content.ts * # user-owned: wordmark accents + footer newsletter
|
|
432
|
+
content.ts * # user-owned: wordmark accents + navbar note + footer newsletter
|
|
414
433
|
props.ts * # user-owned: shell element props
|
|
415
434
|
spec/index.ts, spec/page-root.ts, spec/types.ts # derived routes built from the barrel
|
|
416
435
|
views/
|
|
@@ -432,9 +451,10 @@ The shell's derived `spec/index.ts` imports the user-owned `shell/props.ts`
|
|
|
432
451
|
surface and footer copy are configured without touching derived files. Configure
|
|
433
452
|
`shell/content.ts` (`logoAccent`/`brandAccent`, `navbarClassName`/`footerClassName`,
|
|
434
453
|
`brandDescription`, `linkColumns`); defaults are neutral and link only to served routes
|
|
435
|
-
(`/`, `/
|
|
454
|
+
(`/`, `/categories`, `/checkout`), never dead `#` links. `newsletter` defaults to `false`
|
|
436
455
|
and the scaffold ships no submit callback, so a content-only newsletter renders no form
|
|
437
|
-
— never a fake form.
|
|
456
|
+
— never a fake form. `shippingNote` defaults to `''`: while it is empty (and there are
|
|
457
|
+
no utility links) the navbar renders no utility strip, so no placeholder note is shown.
|
|
438
458
|
|
|
439
459
|
A view's derived `index.tsx` imports the user-owned `content.ts`/`props.ts`/
|
|
440
460
|
`data.ts`, so a customization changes real spec/loader output and survives `sync`.
|
package/VENDOR.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Vendored material and provenance
|
|
2
|
+
|
|
3
|
+
`@thorprovider/storefront` ships exactly five **operative skills** — first-party,
|
|
4
|
+
authored in this package: `storefront-workflow`, `sf-view-gen`, `sf-feature`,
|
|
5
|
+
`sf-setup`, and `sf-theme-gen`. Everything else the suite needs is either retained
|
|
6
|
+
generic knowledge, shipped as a **scoped reference** an operative skill loads by
|
|
7
|
+
relative path, or retired and no longer shipped. This file records the origin and
|
|
8
|
+
the adaptation of that retained material. The generator never reads
|
|
9
|
+
machine-global skills at runtime; the copies below are the authority the suite
|
|
10
|
+
resolves.
|
|
11
|
+
|
|
12
|
+
## First-party operative skills (not vendored)
|
|
13
|
+
|
|
14
|
+
| Skill | Path | Purpose |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| storefront-workflow | `skills/storefront-workflow/` | The four-phase model (bootstrap → compose → customize → verify) and the CLI/manifest authority |
|
|
17
|
+
| sf-view-gen | `skills/sf-view-gen/` | Add/modify a view via the CLI; owns the retained json-render references |
|
|
18
|
+
| sf-feature | `skills/sf-feature/` | Add/remove a feature bundle via the CLI |
|
|
19
|
+
| sf-setup | `skills/sf-setup/` | Connect or re-point the Medusa backend via `storefront setup` |
|
|
20
|
+
| sf-theme-gen | `skills/sf-theme-gen/` | Theme tokens, typography, identity; owns the retained theming references |
|
|
21
|
+
|
|
22
|
+
## Retained references
|
|
23
|
+
|
|
24
|
+
Useful generic knowledge is retained **only** as references inside the operative
|
|
25
|
+
skill that owns the procedure. A reference is not an independently selectable
|
|
26
|
+
skill (it is not a `SKILL.md`).
|
|
27
|
+
|
|
28
|
+
| Retained reference | Owning skill | Upstream source | Refresh date | Adapted |
|
|
29
|
+
|---|---|---|---|---|
|
|
30
|
+
| `references/design-consistency.md` | `skills/storefront-workflow/` | `~/.config/opencode/skills/storefront-best-practices` | 2026-10-14 | Kept as a reference; UX/design-consistency guidance retained, raw Medusa SDK / React Query / direct-`/store` fetching removed |
|
|
31
|
+
| `references/mobile-responsiveness.md` | `skills/storefront-workflow/` | `~/.config/opencode/skills/storefront-best-practices` | 2026-10-14 | Kept as a reference; responsive/mobile guidance retained, raw SDK fetching removed |
|
|
32
|
+
| `references/seo.md` | `skills/storefront-workflow/` | `~/.config/opencode/skills/storefront-best-practices` | 2026-10-14 | Kept as a reference; SEO/accessibility guidance retained, entity-metadata policy preserved |
|
|
33
|
+
| `references/shadcn-theming.md` | `skills/sf-theme-gen/` | `~/.config/opencode/skills/shadcn-theming` | 2026-10-14 | Unavailable tooling (`TeamCreate`, `fuse-ai-pilot`) and raw `shadcn init`/`shadcn add` scaffolding-and-discovery steps removed; OKLCH token/foreground-pair rules and the lightness rule kept |
|
|
34
|
+
| `references/theme-setup.md` | `skills/sf-theme-gen/` | `~/.config/opencode/skills/shadcn-theming/references/templates` | 2026-10-14 | Kept as a reference; adapted to the generated storefront's external-file bounds |
|
|
35
|
+
| `references/theming-guide.md` | `skills/sf-theme-gen/` | `~/.config/opencode/skills/shadcn-theming/references` | 2026-10-14 | Kept as a reference; adapted to the generated storefront's external-file bounds |
|
|
36
|
+
| `references/json-render-core.md` | `skills/sf-view-gen/` | `~/.config/opencode/skills/json-render/core` | 2026-10-14 | Flattened from the standalone `json-render-core` skill to a reference; reachable only by relative path from `sf-view-gen` |
|
|
37
|
+
| `references/json-render-react.md` | `skills/sf-view-gen/` | `~/.config/opencode/skills/json-render/react` | 2026-10-14 | Flattened from the standalone `json-render-react` skill to a reference; reachable only by relative path from `sf-view-gen` |
|
|
38
|
+
| `references/json-render-next.md` | `skills/sf-view-gen/` | `~/.config/opencode/skills/json-render/next` | 2026-10-14 | Flattened from the standalone `json-render-next` skill to a reference; reachable only by relative path from `sf-view-gen` |
|
|
39
|
+
| `references/json-render-shadcn.md` | `skills/sf-view-gen/` | `~/.config/opencode/skills/json-render/shadcn` | 2026-10-14 | Flattened from the standalone `json-render-shadcn` skill to a reference; reachable only by relative path from `sf-view-gen` |
|
|
40
|
+
| `references/views.md` | `skills/sf-view-gen/` | Authored in this package | 2026-10-14 | First-party; documents the curated view set read from `storefront views --json` |
|
|
41
|
+
|
|
42
|
+
## Retired
|
|
43
|
+
|
|
44
|
+
These were previously bundled flat under `skills/` as standalone installable
|
|
45
|
+
skills. They are no longer shipped as active skills or as retained reference
|
|
46
|
+
material, and `storefront update` retires an installed copy that is verifiably
|
|
47
|
+
unmodified.
|
|
48
|
+
|
|
49
|
+
| Retired item | Upstream source | Last bundled | Why retired |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| `nextjs-shadcn` | `~/.config/opencode/skills/nextjs-shadcn` | 2026-09-28 | Broadly-triggering generic skill; `shadcn init`/`shadcn add` scaffolding contradicts the CLI-only generation rule |
|
|
52
|
+
| `shadcn-component-discovery` | `~/.config/opencode/skills/shadcn-component-discovery` | 2026-09-28 | Broadly-triggering generic skill; UI is limited to `@thorprovider/blocks` |
|
|
53
|
+
| `building-storefronts` | `~/.config/opencode/skills/building-storefronts` | 2026-09-28 | Broadly-triggering generic skill; pushes raw SDK / React Query fetching the storefront cannot use |
|
|
54
|
+
| `json-render-solid` | `~/.config/opencode/skills/json-render/solid` | 2026-09-28 | Irrelevant renderer; the generated storefront renders React/Next only |
|
|
55
|
+
| `json-render-remotion` | `~/.config/opencode/skills/json-render/remotion` | 2026-09-28 | Irrelevant renderer; video timelines are out of scope for a spec-based storefront |
|
|
56
|
+
|
|
57
|
+
## Excluded
|
|
58
|
+
|
|
59
|
+
Never bundled: the `json-render` `codegen`, `devtools`, `directives`, `image`, and
|
|
60
|
+
`mcp` material. They are irrelevant to a generated storefront and are not shipped
|
|
61
|
+
in any form.
|
|
62
|
+
|
|
63
|
+
## Maintenance
|
|
64
|
+
|
|
65
|
+
To refresh a retained reference: re-copy the upstream material to a reference
|
|
66
|
+
file under the owning skill's `references/`, update the `Refresh date` above, and
|
|
67
|
+
bump the package version. If a reference is retired, move it to the **Retired**
|
|
68
|
+
table with its reason; `storefront update` retires a verifiably unmodified
|
|
69
|
+
installed copy of it. See the package README maintenance note.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Storefront OpenSpec configuration — seeded by @thorprovider/storefront.
|
|
2
|
+
#
|
|
3
|
+
# This file is storefront-owned: `storefront update` re-applies it after
|
|
4
|
+
# re-running `openspec init`. Put customization in the storefront's own files,
|
|
5
|
+
# not here.
|
|
6
|
+
schema: spec-driven
|
|
7
|
+
|
|
8
|
+
context: |
|
|
9
|
+
This project is a generated Thor Commerce storefront. A storefront is defined by
|
|
10
|
+
its manifest (storefront.config.json) and produced by the `storefront` CLI. The
|
|
11
|
+
CLI is the authority for every structural change — views, features, sections,
|
|
12
|
+
theme, and setup — and it is the only writer of derived files. Manual edits are
|
|
13
|
+
limited to user-owned files (view content/props/data/schema, mappers, icon-map,
|
|
14
|
+
shell) plus the bounded external surface of app/globals.css and app/layout.tsx,
|
|
15
|
+
and must preserve the CLI-managed imports and markers.
|
|
16
|
+
Determinism first: a change the CLI performs deterministically stays with the CLI.
|
|
17
|
+
A deterministic change the CLI records in storefront.config.json is trivial and
|
|
18
|
+
does not require an OpenSpec change; the manifest is its record. A change that
|
|
19
|
+
requires judgment — content authoring, prop/data mapping, composition reshaping,
|
|
20
|
+
or a cross-file redesign whose acceptance is not a CLI assertion — is non-trivial
|
|
21
|
+
and is driven through the spec-driven loop, surfaced to the user as the five
|
|
22
|
+
stages explore → plan → build → verify → inform, orchestrated by the agent
|
|
23
|
+
without asking the user to confirm each artifact. Keep any OpenSpec change
|
|
24
|
+
consistent with the storefront authorities: structural edits still go through
|
|
25
|
+
the CLI.
|
|
26
|
+
|
|
27
|
+
rules:
|
|
28
|
+
proposal:
|
|
29
|
+
- "State the why, the observable storefront change, and the affected view(s) or feature(s); keep deferred scope explicit."
|
|
30
|
+
- "Do not restate this context or these rules in the artifact body."
|
|
31
|
+
specs:
|
|
32
|
+
- "New capabilities start with ## Purpose and ## ADDED Requirements; scenarios use exactly four hashtags (#### Scenario:) and every requirement has at least one."
|
|
33
|
+
- "Describe observable behavior, not implementation details."
|
|
34
|
+
design:
|
|
35
|
+
- "Record each decision with its why and the alternative considered; state how the change respects the CLI-as-authority and the user-owned surface."
|
|
36
|
+
tasks:
|
|
37
|
+
- "Group tasks by dependency; each task is a checkbox and states its own verification."
|
|
38
|
+
- "Never report the change complete until `storefront sync` and `storefront doctor` pass and the change's acceptance is met."
|