@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.
Files changed (166) hide show
  1. package/README.md +173 -153
  2. package/VENDOR.md +69 -0
  3. package/assets/openspec/config.yaml +38 -0
  4. package/assets/templates/AGENTS.md +76 -0
  5. package/assets/templates/app/app/[[...slug]]/page.tsx +42 -1
  6. package/assets/templates/app/app/[[...slug]]/renderer.tsx +13 -2
  7. package/assets/templates/app/app/globals.css +5 -8
  8. package/assets/templates/app/app/layout.tsx +1 -5
  9. package/assets/templates/app/app/robots.ts +9 -3
  10. package/assets/templates/app/app/sitemap.ts +64 -5
  11. package/assets/templates/app/lib/__STOREFRONT__/actions.ts +70 -0
  12. package/assets/templates/app/lib/__STOREFRONT__/catalog.ts +15 -5
  13. package/assets/templates/app/lib/__STOREFRONT__/commerce.ts +71 -0
  14. package/assets/templates/app/lib/__STOREFRONT__/composition.ts +26 -0
  15. package/assets/templates/app/lib/__STOREFRONT__/handlers.core.ts +36 -4
  16. package/assets/templates/app/lib/__STOREFRONT__/registry.tsx +82 -50
  17. package/assets/templates/app/lib/__STOREFRONT__/runtime.ts +3 -0
  18. package/assets/templates/app/lib/__STOREFRONT__/schema.ts +29 -14
  19. package/assets/templates/app/lib/__STOREFRONT__/section-observation.ts +182 -0
  20. package/assets/templates/app/lib/__STOREFRONT__/section-sources.ts +130 -0
  21. package/assets/templates/app/lib/__STOREFRONT__/shell/content.ts +31 -7
  22. package/assets/templates/app/lib/__STOREFRONT__/shell/props.ts +4 -0
  23. package/assets/templates/app/lib/__STOREFRONT__/spec/index.ts +56 -26
  24. package/assets/templates/app/lib/__STOREFRONT__/spec/seo.ts +165 -0
  25. package/assets/templates/app/lib/__STOREFRONT__/store-context.ts +26 -7
  26. package/assets/templates/app/lib/__STOREFRONT__/views/sections/index.ts +2 -1
  27. package/assets/templates/app/lib/__STOREFRONT__/views/sections/products.client.tsx +100 -0
  28. package/assets/templates/app/lib/__STOREFRONT__/views/sections/products.tsx +19 -0
  29. package/assets/templates/app/lib/__STOREFRONT__/views/sections/schema.products.ts +39 -0
  30. package/assets/templates/features/checkout/handlers.ts +6 -0
  31. package/assets/templates/features/customer-auth/state.ts +10 -1
  32. package/assets/templates/views/account/index.tsx +1 -1
  33. package/assets/templates/views/account/registry.tsx +80 -19
  34. package/assets/templates/views/account/schema.ts +1 -0
  35. package/assets/templates/views/cart/content.ts +11 -0
  36. package/assets/templates/views/cart/data.ts +23 -0
  37. package/assets/templates/views/cart/index.tsx +53 -0
  38. package/assets/templates/views/cart/props.ts +12 -0
  39. package/assets/templates/views/cart/registry.tsx +81 -0
  40. package/assets/templates/views/cart/schema.ts +52 -0
  41. package/assets/templates/views/category/assembly/assembly.json +1 -0
  42. package/assets/templates/views/category/assembly/index.skeleton.tsx +64 -6
  43. package/assets/templates/views/category/assembly/registry.skeleton.tsx +2 -1
  44. package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/binding.json +5 -0
  45. package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/catalog.part +4 -0
  46. package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/element.part +7 -0
  47. package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/registry.part +18 -0
  48. package/assets/templates/views/category/index.tsx +76 -7
  49. package/assets/templates/views/category/props.ts +7 -0
  50. package/assets/templates/views/category/registry.tsx +19 -0
  51. package/assets/templates/views/category/schema.ts +13 -0
  52. package/assets/templates/views/home/assembly/assembly.json +9 -0
  53. package/assets/templates/views/home/assembly/index.skeleton.tsx +22 -4
  54. package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/element.part +1 -1
  55. package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/registry.part +2 -2
  56. package/assets/templates/views/home/data.ts +9 -0
  57. package/assets/templates/views/home/index.tsx +23 -5
  58. package/assets/templates/views/home/registry.tsx +2 -2
  59. package/assets/templates/views/product/data.ts +4 -2
  60. package/assets/templates/views/product/index.tsx +49 -5
  61. package/assets/templates/views/product/props.ts +7 -0
  62. package/assets/templates/views/product/registry.tsx +25 -0
  63. package/assets/templates/views/product/schema.ts +13 -0
  64. package/assets/templates/views/static/content.ts +4 -4
  65. package/assets/templates/views/static/index.tsx +1 -1
  66. package/bin/storefront.js +1231 -154
  67. package/examples/merchandising/category-led.json +37 -0
  68. package/examples/merchandising/collection-led.json +37 -0
  69. package/package.json +11 -7
  70. package/recipes/archetypes.json +9 -22
  71. package/recipes/catalog.json +40 -1
  72. package/recipes/features.json +25 -2
  73. package/recipes/recipe.schema.json +1 -1
  74. package/recipes/recipes.json +32 -30
  75. package/recipes/sections.json +10 -0
  76. package/recipes/validate.mjs +54 -0
  77. package/scripts/candidate.mjs +4 -4
  78. package/scripts/composers.mjs +25 -5
  79. package/scripts/env-file.mjs +86 -0
  80. package/scripts/file-classes.mjs +5 -0
  81. package/scripts/migrate-english-routes.mjs +276 -0
  82. package/scripts/pinning.mjs +74 -5
  83. package/scripts/plan-apply.mjs +149 -5
  84. package/scripts/reconcile.mjs +49 -11
  85. package/scripts/render-templates.mjs +97 -44
  86. package/scripts/section-config.mjs +253 -0
  87. package/scripts/starter.mjs +17 -0
  88. package/scripts/theme/color.mjs +185 -0
  89. package/scripts/theme/css-theme.mjs +233 -0
  90. package/scripts/theme/fonts.mjs +123 -0
  91. package/scripts/theme/import-export.mjs +125 -0
  92. package/scripts/theme/preset.mjs +93 -0
  93. package/scripts/theme/theme-plan.mjs +292 -0
  94. package/scripts/theme/tokens.mjs +137 -0
  95. package/scripts/view-assembly.mjs +47 -1
  96. package/skills/sf-feature/SKILL.md +32 -19
  97. package/skills/sf-setup/SKILL.md +79 -0
  98. package/skills/sf-theme-gen/SKILL.md +99 -36
  99. package/skills/sf-theme-gen/references/shadcn-theming.md +87 -0
  100. package/skills/{shadcn-theming/references/templates → sf-theme-gen/references}/theme-setup.md +15 -19
  101. package/skills/{shadcn-theming → sf-theme-gen}/references/theming-guide.md +6 -11
  102. package/skills/sf-view-gen/SKILL.md +63 -40
  103. package/skills/sf-view-gen/assets/recipes/archetypes.json +9 -22
  104. package/skills/sf-view-gen/assets/recipes/catalog.json +40 -1
  105. package/skills/sf-view-gen/assets/recipes/features.json +25 -2
  106. package/skills/sf-view-gen/assets/recipes/recipes.json +32 -30
  107. package/skills/sf-view-gen/assets/recipes/sections.json +10 -0
  108. package/skills/sf-view-gen/assets/templates/views/sections/products.client.tsx +100 -0
  109. package/skills/sf-view-gen/assets/templates/views/sections/products.tsx +19 -0
  110. package/skills/sf-view-gen/assets/templates/views/sections/schema.products.ts +39 -0
  111. package/skills/{json-render-core/SKILL.md → sf-view-gen/references/json-render-core.md} +4 -27
  112. package/skills/{json-render-next/SKILL.md → sf-view-gen/references/json-render-next.md} +5 -8
  113. package/skills/{json-render-react/SKILL.md → sf-view-gen/references/json-render-react.md} +3 -5
  114. package/skills/{json-render-shadcn/SKILL.md → sf-view-gen/references/json-render-shadcn.md} +3 -5
  115. package/skills/sf-view-gen/references/views.md +28 -37
  116. package/skills/sf-view-gen/scripts/validate.mjs +54 -0
  117. package/skills/storefront-workflow/SKILL.md +94 -31
  118. package/skills/{storefront-best-practices/reference/design.md → storefront-workflow/references/design-consistency.md} +13 -29
  119. package/CHANGELOG.md +0 -84
  120. package/assets/templates/views/user-panel/index.tsx +0 -106
  121. package/assets/templates/views/user-panel/registry.tsx +0 -54
  122. package/assets/templates/views/user-panel/schema.ts +0 -79
  123. package/commands/sf-add-view.md +0 -57
  124. package/commands/sf-feature.md +0 -28
  125. package/commands/sf-theme.md +0 -26
  126. package/commands/sf-view.md +0 -67
  127. package/skills/building-storefronts/SKILL.md +0 -178
  128. package/skills/building-storefronts/references/frontend-integration.md +0 -229
  129. package/skills/json-render-remotion/SKILL.md +0 -111
  130. package/skills/json-render-solid/SKILL.md +0 -204
  131. package/skills/nextjs-shadcn/SKILL.md +0 -367
  132. package/skills/nextjs-shadcn/references/architecture.md +0 -499
  133. package/skills/nextjs-shadcn/references/project-setup.md +0 -162
  134. package/skills/nextjs-shadcn/references/shadcn-platform.md +0 -261
  135. package/skills/nextjs-shadcn/references/sidebar.md +0 -274
  136. package/skills/nextjs-shadcn/references/styling.md +0 -555
  137. package/skills/shadcn-component-discovery/SKILL.md +0 -273
  138. package/skills/shadcn-component-discovery/references/registries.md +0 -226
  139. package/skills/shadcn-theming/SKILL.md +0 -104
  140. package/skills/storefront-best-practices/SKILL.md +0 -421
  141. package/skills/storefront-best-practices/reference/components/breadcrumbs.md +0 -123
  142. package/skills/storefront-best-practices/reference/components/cart-popup.md +0 -189
  143. package/skills/storefront-best-practices/reference/components/country-selector.md +0 -298
  144. package/skills/storefront-best-practices/reference/components/footer.md +0 -112
  145. package/skills/storefront-best-practices/reference/components/hero.md +0 -241
  146. package/skills/storefront-best-practices/reference/components/megamenu.md +0 -239
  147. package/skills/storefront-best-practices/reference/components/navbar.md +0 -397
  148. package/skills/storefront-best-practices/reference/components/popups.md +0 -221
  149. package/skills/storefront-best-practices/reference/components/product-card.md +0 -125
  150. package/skills/storefront-best-practices/reference/components/product-reviews.md +0 -217
  151. package/skills/storefront-best-practices/reference/components/product-slider.md +0 -174
  152. package/skills/storefront-best-practices/reference/components/search.md +0 -101
  153. package/skills/storefront-best-practices/reference/connecting-to-backend.md +0 -391
  154. package/skills/storefront-best-practices/reference/features/promotions.md +0 -307
  155. package/skills/storefront-best-practices/reference/features/wishlist.md +0 -230
  156. package/skills/storefront-best-practices/reference/layouts/account.md +0 -380
  157. package/skills/storefront-best-practices/reference/layouts/cart.md +0 -316
  158. package/skills/storefront-best-practices/reference/layouts/checkout.md +0 -486
  159. package/skills/storefront-best-practices/reference/layouts/home-page.md +0 -264
  160. package/skills/storefront-best-practices/reference/layouts/order-confirmation.md +0 -231
  161. package/skills/storefront-best-practices/reference/layouts/product-details.md +0 -527
  162. package/skills/storefront-best-practices/reference/layouts/product-listing.md +0 -520
  163. package/skills/storefront-best-practices/reference/layouts/static-pages.md +0 -356
  164. package/skills/storefront-best-practices/reference/medusa.md +0 -307
  165. /package/skills/{storefront-best-practices/reference → storefront-workflow/references}/mobile-responsiveness.md +0 -0
  166. /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 command suite for Thor Commerce"
4
- lastReviewed: "2026-10-08"
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 command suite for Thor Commerce.
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
- and installs the `/sf-*` OpenCode command suite into `<dir>/.opencode/` in the same
13
- run. It ships static project templates, a recipe registry, and vendored skills, and
14
- installs them into any project's `.opencode/` directory. Nothing else from the Thor
15
- Commerce monorepo is required at generation time.
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. `npx` and
54
- `yarn dlx` are equivalent:
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, backend URL, preset — Maia is preselected). Pressing Enter on an empty
73
- prompt accepts the suggested default: the storefront name is suggested from the
74
- target directory basename, and the site name from the Title Case of that name
75
- (`my-shop` → `My Shop`). Without a terminal, every required input must be passed
76
- as a flag; the command fails fast and writes nothing rather than guessing. Brand
77
- color is never asked by the wizard — apply it later with `/sf-theme`, or pass
78
- `--brand` on the command line.
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
- | `--brand <color>` | named brand color overriding preset primary/nav/ring tokens (never prompted) | none |
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, `--skip-install`) →
114
- `.yarnrc.yml` (`nodeLinker: node-modules`, retry and concurrency hardening) →
115
- shadcn base with the preset → dependency install → template copy +
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`). Running
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 `commands/` and the shipped skills under `skills/` (own
123
- skills and vendored skills, flat) into `<dir>/.opencode/`. It verifies its own
124
- generated copies against their source before copying, records the installed version
125
- in `.opencode/storefront.json`, and is idempotent: use `--force` to overwrite files
126
- that already exist.
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
- The storefront renders its home view — hero, benefits, and category sections — using
138
- only `@thorprovider/blocks` for UI and `@thorprovider/adapters` for data. Then grow
139
- it incrementally from OpenCode:
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
- /sf-add-view product # add a view from its recipe
143
- /sf-view home add a testimonials section # modify an existing view
144
- /sf-theme # colors, typography, identity
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
- Generated projects resolve an explicit single-store context from the host
150
- environment before any commerce call. `create` writes a git-ignored `.env.local`
151
- with the data source and backend URL you passed, a generated cookie secret, and
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=medusa
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
- The store context is **explicit and validated**:
168
-
169
- - `THOR_STORE_ID` — stable store identity (seeded from the manifest name).
170
- - `MEDUSA_SALES_CHANNEL_ID` — the sales channel the store is scoped to.
171
- - `MEDUSA_REGION_ID` — the backend region that supplies currency, countries, and
172
- shipping.
173
- - `THOR_CURRENCY_CODE` — ISO 4217 currency, taken from the environment; it is
174
- **never hardcoded** in the app.
175
- - `THOR_SESSION_SECRET` — host-only cookie signing secret (≥16 chars, 32
176
- recommended). Generate your own; never commit or log it.
177
-
178
- `THOR_DATA_SOURCE` selects the mode **explicitly** and is never inferred from a
179
- failure:
180
-
181
- - `THOR_DATA_SOURCE=mock` renders labelled demo data (`Datos de demostración`).
182
- The store context must match the mock fixture: channel
183
- `mock-sales-channel`, region `mock-region-us` (currency `USD`) or
184
- `mock-region-eu` (currency `EUR`). The committed `.env.example` ships these.
185
- - `THOR_DATA_SOURCE=medusa` uses the real backend. A missing provider, invalid
186
- configuration, or a provider failure is surfaced as a **visible error** — the
187
- store never silently degrades to demo data. Until `MEDUSA_PUBLISHABLE_KEY` is
188
- set, the home view shows the error notice instead of a fake catalog. Fill in
189
- the variables, then restart `yarn dev` to serve real catalog data.
190
-
191
- The guest flow is backend-authoritative end to end: the signed host cookie
192
- issues a shopper identity and binds a persistent backend cart; the PDP adds the
193
- explicitly selected variant; the cart and checkout render the backend's totals;
194
- checkout applies the one approved manual TEST provider after shipping and
195
- completes the cart with its native discriminator. An ambiguous completion is
196
- never retried — the shopper reconciles the committed cart, and the active cart
197
- is cleared only after a confirmed order. No card data is collected at launch.
198
-
199
- For offline-only work set `THOR_DATA_SOURCE=mock` on purpose.
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 command set (`/sf-add-view`, `/sf-view`, `/sf-theme`), so you see stale or unrelated behaviour.
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, use `/sf-add-view`; run `create` in an empty directory.
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**: fill in the variables in [Backend configuration](#backend-configuration) and restart `yarn dev`. For offline work set `THOR_DATA_SOURCE=mock` on purpose.
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>/.opencode/
246
- storefront.json # install record: { version, installedAt, pinning }
247
- # pinning separates declared ranges from the resolved
248
- # versions, yarn.lock hash, and owned asset BOM
249
- commands/
250
- sf-add-view.md
251
- sf-view.md
252
- sf-feature.md
253
- sf-theme.md
254
- skills/
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
- Each skill carries the templates, recipes, and scripts it uses inside its own
267
- directory. Skills address them by relative path, so nothing needs the package to be
268
- located on disk at generation time. The feature command is
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. Read the installed `storefront-workflow` skill for the full
277
- model. Every command runs from inside the project (no directory argument).
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`, `theme --mode` |
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 by the CLI and
289
- never hand-edited. *User-owned* files (content, props, data, local schema, mapper
290
- bodies) are consumed through thin derived wrappers and survive `sync` and removal.
291
- *External* files (`app/layout.tsx`, `app/globals.css`) belong to create-next-app +
292
- shadcn; the CLI only appends idempotent markers.
293
-
294
- **Curated MVP defaults.** Standalone views `home`, `category`, `product`; the
295
- `checkout` feature (which owns the `checkout` view — a direct `view add checkout`
296
- is rejected, use `feature add checkout`). Held post-MVP and rejected before any
297
- write: `user-panel`, recommendations, and sections. A generated storefront is not a
298
- complete commerce implementation: the `checkout` feature ships structural wiring
299
- only, and the purchase flow is owned by the separate `single-tenant-commerce-mvp`
300
- change.
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 local `@thorprovider/*` packages from packed
307
- tarballs via Yarn `resolutions` (`--packs <dir>`), with no publish and no
308
- workspace import. No package-manager safety policy is suppressed: the generated
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
- ## Commands
371
+ ## Agent guidance and skills
358
372
 
359
- | Command | Purpose |
360
- | --- | --- |
361
- | `/sf-add-view <view>` | Add a curated view via the CLI (`product`, `category`; `checkout` via `/sf-feature`) |
362
- | `/sf-view <view> <change>` | Customize a view's user-owned content/props/data, then `sync` |
363
- | `/sf-feature add\|remove <name>` | Add/remove a feature bundle (e.g. `checkout`) via the CLI |
364
- | `/sf-theme` | Customize OKLCH color tokens (light/dark), typography, and identity metadata |
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 itself is `npx @thorprovider/storefront create <dir>` — there is no
367
- `/sf-init` command; the wizard lives in the CLI and is deterministic. The color
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 --mode`). Repeatable, reviewable, no model in the loop.
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 (`/sf-theme` decides the mode; `storefront theme --mode` applies it).
378
- - **Pure judgment** → an `sf-*` skill (e.g. `/sf-view`): variant selection, copy, and
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
- (`/`, `/categorias`, `/checkout`), never dead `#` links. `newsletter` defaults to `false`
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."