Changelog
All notable changes to propeller-v2-accelerator are documented here.
The format is based on Keep a Changelog.
[Unreleased]
[0.5.6] - 2026-06-25
Added
- Contentful as a selectable CMS provider. The Next boilerplate now ships a
Contentful provider in
lib/cms/providers/contentful.ts, so the scaffolder offers it alongside Strapi and Prepr:--cms=contentful(and the interactive prompt). Contentful is hosted — no adapter package to install; selecting it setsCMS_PROVIDER=contentfuland uncomments theCONTENTFUL_SPACE_ID/CONTENTFUL_ENVIRONMENT/CONTENTFUL_CDA_TOKENcredential lines in the shop's.env.local.example. The generatedcms/README.mdgains a Contentful setup section (Space ID + Delivery API token, optional preview token).
Documentation
- Rewrite
docs/cms.mdxto the env-activation model. The page still described the obsolete adapter-package flow (npm installacms-adapter-*package and wire aCmsAdapterProvider), which no scaffolded shop uses. Replaced it with the real model — providers ship in the boilerplate and are selected at runtime byCMS_PROVIDER— plus a built-in-providers table (including Contentful) and a credentials-per-provider table. - List Contentful in the accelerator README and the CLI package README.
[0.5.5] - 2026-06-24
Documentation
- Fix the Propeller Commerce link in the package README — pointed at
propellercommerce.com(no hyphen); corrected tohttps://propeller-commerce.com/.
[0.5.4] - 2026-06-24
Documentation
- CLI package README now documents the CMS flow. The npm package page
(
packages/cli/README.md) had no CMS section — added one covering--cms=<provider>, that CMS is Next-only, env-based activation viaCMS_PROVIDER(no package to install), and the--cms=noneflat layout. Also flagged that a no-CMS shop is flat at the root (cd my-shop, notmy-shop/frontend). Docs-only; a version bump is required for npm to re-render the package README.
[0.5.3] - 2026-06-24
Fixed
--cms=<provider>now actually activates the CMS. The Next boilerplate ships every CMS provider inlib/cmsand selects one at runtime from theCMS_PROVIDERenv var, but the scaffolder never set it — so a--cms=preprshop silently behaved as no-CMS. Scaffolding with a CMS now writesCMS_PROVIDER=<provider>(+ its public mirror) into the shop's.env.local.exampleand uncomments that provider's credential lines, so the built-in provider is wired and the user sees exactly what to fill in. No package to install.- Generated CMS README /
propeller doctorno longer point at a non-existent npm package. Both referencedpropeller-v2-cms-adapter-*packages that are not published. The README now explains env-based activation (the provider already ships inlib/cms), anddoctorverifiesCMS_PROVIDERmatchespropeller.json→cms.adapter(and thatlib/cmsexists) instead of looking for the phantom package.
Changed
- CMS is a Next-only choice. Only the Next boilerplate has a CMS engine;
Vue and Nuxt have none. The CMS prompt is now shown only for the Next stack,
and
--cms=<x>on a Vue/Nuxt scaffold prints a notice and proceeds with no CMS instead of scaffolding a shop whose CMS selection does nothing.
[0.5.2] - 2026-06-24
Added
--cms=nonescaffold option for all three stacks. A shop with no CMS is now laid out flat at the shop root (nofrontend/split, no siblingcms/folder) with the entire CMS surface stripped. Next replaces the few CMS-referencing core files with CMS-free variants; Vue ships a no-CMS router variant (its routes are an array, not files); Nuxt deletes the file-based CMS pages and patches the dead/blognav links. The homepage falls back to the built-in static page.- Prepr as a first-class CMS choice (
--cms=prepr), backed by a newcms-adapter-preprpackage that implements the richCmsProvidercontract with runtime schema introspection. .textpatch.jsonoverlay primitive (packages/cli): an ordered list of exact find/replace ops applied to a cloned boilerplate file, for surgically editing files that merely reference an excised feature (e.g. one nav-link entry in a 400-line header) without overlaying them wholesale. Sibling of the existing.patch.jsonJSON-merge overlay; includes stale-snippet detection and CRLF-agnostic matching.
Changed
- CMS adapters adopt the richer
CmsProvidercontract frompropeller-v2-core-ui(typed blocks,getGlobal, category banners) — the boilerplate and accelerator now share one source of truth. Adopted additively, so existing adapters keep working. cms-adapter-*consume@propeller-commerce/propeller-v2-core-uifrom npm (scoped^0.3.0) instead of the github pin.
[0.5.1] - 2026-06-11
Added
- CLI package README (
packages/cli/README.md) so the npm package page is no longer blank. Documents the scoped install command, stacks, and modes.
Fixed
- Docs: install command now uses the scoped package name. The package
publishes as
@propeller-commerce/create-propeller-shop, so the unscopednpx create-propeller-shopdoes not resolve from npm. The root and CLI READMEs now shownpx @propeller-commerce/create-propeller-shop. (The installed executable remainscreate-propeller-shop.)
[0.5.0] - 2026-06-09
Changed (BREAKING — internal scaffold model)
-
Scaffold flow:
git clone --depth 1of the boilerplate at scaffold time, not a stale hand-copied subset of it. The previous model kept ~190–234 boilerplate files duplicated undertemplates/shop-<stack>/shared/. Boilerplate fixes had to be manually re-copied or shops silently shipped stale code — exactly the drift that produced the missingproxy.tsin shop-next, the divergentdata/config.ts(133 lines vs the boilerplate's 175), and the broken accelerator-vs-boilerplate parity the user finally called out. New flow:git clone --depth 1 --branch master --single-branch <boilerplate-repo>into a tempdir.- Copy the boilerplate's
frontend/(or repo root for next + nuxt) into the scaffold destination, EXCLUDINGnode_modules,.git,.next,.nuxt,.output,dist,.vite,.turbo,playwright-report,test-results,coverage,.claude,memory, and ANY.env*file (real secrets, not template defaults). - Apply
templates/shop-<stack>/overlay/on top — currentlypackage.patch.json(deep-merged onto the boilerplate's package.json) andREADME.template.md. - If
mode === 'b2c', delete paths listed intemplates/shop-<stack>/b2c-trim.json(quotes, quote-requests, authorization-*). - Write
propeller.jsonas before.
-
JSON patch overlay model. Overlay files ending in
.patch.jsonare DEEP-MERGED onto the boilerplate's existing JSON, instead of replacing it wholesale. The previouspackage.template.jsonhad to carry the ENTIRE package.json including every dependency version — which froze deps at whatever was committed to the accelerator and silently downgraded the boilerplate's current versions. With.patch.jsonthe boilerplate's version always wins for any key the patch doesn't explicitly override. To DELETE a key (e.g. drop a script the boilerplate ships), set it tonullin the patch. -
Local-boilerplate override for development. Set
PROPELLER_NEXT_BOILERPLATE_LOCAL,PROPELLER_VUE_BOILERPLATE_LOCAL, orPROPELLER_NUXT_BOILERPLATE_LOCALto a directory path and the CLI copies from it instead of cloning. Lets you test in-flight boilerplate changes without pushing first. Skipped files still apply. -
templates/shop-<stack>/b2c-trim.json— replaces the oldtemplates/shop-<stack>/b2b-routes/model. The boilerplate ships every route (b2b/hybrid is the default); the trim manifest deletes b2b-only routes whenmode === 'b2c'. Symmetric inversion of the old approach but compatible with "boilerplate is the source of truth".
Removed
templates/shop-<stack>/shared/— ~190–234 files per stack of stale boilerplate-copied code, deleted entirely.templates/shop-<stack>/b2b-routes/— replaced by the b2c-trim manifest model described above.packages/cli/src/template/copy.ts— superseded bypackages/cli/src/template/clone.ts.- The templated
.template.ts/tsx/vueoverlay variants oflayout.tsx,next.config.ts,proxy.ts,data/config.ts,nuxt.config.ts,src/router/index.tsare gone. The boilerplate's real versions are authoritative; anything truly shop-specific lives in.env.localorpropeller.jsonand is read at runtime, not baked at scaffold time.
Added
templates/shop-next/shared/proxy.template.ts— adds the language-prefix URL rewrite that the propeller-next boilerplate ships but that the accelerator template was missing. Without it, a hard reload of/en/category/X/Y(or any other localised dynamic route) falls into the(cms)/[...slug]catch-all, callsgetPage('en/category/X/Y'), returns null, and 404s. The proxy now strips the language prefix internally so the matchingcategory/[id]/[slug]page renders, and sets thepreferred_languagecookie so the client-side LanguageContext picks the same locale up on first load. Closes the "Next test shop throws 404 constantly when switching language" report.nonDefaultLocalesJsonArraysubstitution token —localesminusdefaultLocale, JSON-array-stringified. Used by the newproxy.template.tsto populateLOCALE_PREFIXES. Drives URL-prefix rewrite tables (and any future template that needs the same "everything except the default" projection of the locale list).
Fixed
-
propeller-v2-vue-uiSSR crash on catalog pages. The package shipped via the#masterGitHub pin had three unsafeprops.configuration.urls.getX()dereferences (ProductCard.vue:913,ClusterCard.vue:700,Breadcrumbs.vue:199). SearchView/CategoryView don't pass:configurationto<ProductGrid>, so SSR rendering of the first product card threwCannot read properties of undefined (reading 'urls')and returned 500. Fixed upstream at vue-ui master (5c9c06e, version 0.3.7) with?.urls?.guards plus'#'fallback. Newshop-vue/shop-nuxttest shops scaffolded frommasterwill pick this up automatically (both templates pin#master). -
i18n locales registry + AccessErrorView across all three templates — ports the propeller-vue 70aa338 / propeller-next a04c333 / propeller-nuxt d970fc7 i18n work, plus the fa7a4a3 / 795c896 / 7596f25 friendly 403/404 error views.
- shop-next
shared/lib/i18n/{index,client,server}.ts+providers/file.ts,shared/locales/{en,nl}/*.json(56 namespaces),shared/scripts/build-locales-registry.mjs,shared/components/access/AccessErrorView.tsx,shared/lib/errors.ts.layout.template.tsxwraps<TranslationsProvider>.package.template.jsongainslocales:build+predev+prebuildscripts. All ~20 touched pages + 3 islands + Header.tsx + 2 cms block components synced from propeller-next master tip.app/csr/*shadows added (weren't in the original 0.2.0 template). - shop-vue
shared/src/lib/i18n/{index,composable,providers/file}.ts,shared/src/locales/{en,nl}/*.json(55 namespaces),shared/scripts/build-locales-registry.mjs,shared/src/components/access/AccessErrorView.vue,shared/src/lib/errors.ts.package.template.jsongainslocales:build+predev+prebuildscripts. ~25 touched views + AppHeader.vue + AccountLayout.vue synced from propeller-vue master tip.src/views/csr/*shadows added. - shop-nuxt
shared/app/lib/i18n/{index,providers/file}.ts,shared/app/locales/{en,nl}/*.json(55 namespaces),shared/scripts/build-locales-registry.mjs,shared/app/components/access/AccessErrorView.vue,shared/app/lib/errors.ts.useTranslations.tscomposable swapped from stub to file-provider delegate.package.template.jsongainslocales:build+predev+prebuildscripts. 4 detail pages (order/quote/quote-request/thank-you) wired to AccessErrorView.
Smoke-tested by scaffolding all three stacks via
PROPELLER_TEMPLATES_DIR=… create-propeller-shop … --stack={next|vue|nuxt} --mode=hybrid --skip-install --yesinto D:/tmp/propeller-test/{next,vue,nuxt}-i18n. Verified each shop landed with the right locales count, AccessErrorView, lib/i18n tree, and locales:build script. - shop-next
-
templates/shop-nuxt/— Nuxt 3 SSR shop template extracted frompropeller-nuxt.create-propeller-shop --stack=nuxtnow produces a runnable Nuxt shop with the same mode-specific surface as the Next and Vue templates. Closes the consumer-matrix gap: same backend, same routes, same cache contract — now with a Vue SSR runtime.shared/— Nuxt 4-styleapp/directory (pages, layouts, components, plugins, middleware, stores, composables, utils), Nitroserver/(api endpoints + utils),i18n/locales/,nuxt.config.template.ts,package.template.json,tailwind.config.ts,tsconfig.json,.env.example,.gitignore. Catalog pages (category/[id]/[slug],cluster/[clusterId]/[slug],product/[productId]/[slug],search) ship as server-rendered shells with the interactive grid/filters/toolbar mounted inside<ClientOnly>. Anonymous catalog fetches go throughserver/utils/cache.ts:cachedSdkFetchbacked by NitrouseStorage('cache')with per-entity tags fromserver/utils/tags.ts.b2b-routes/— 8 B2B-only pages mounted only whenmode !== 'b2c':app/pages/account/quotes/,app/pages/account/quote-requests/,app/pages/account/authorization-requests.vue,app/pages/account/authorization-settings.vue,app/pages/account/price-requests.vue, andapp/pages/authorization-request-sent/[cartId].vue.Stackenum extended to'next' | 'vue' | 'nuxt'. CLI--stack=nuxt, prompt menu adds the option,propeller doctorlearns the Nuxt-shape b2b-routes probe and theapp/utils/config.tsportalMode lookup.nuxt.config.template.ts— first templated.tsfile in any template. The Vite alias for#app-manifestand thetailwindcss:sources:extendhook are resolved off__dirnameinstead of hard-coded absolute paths (the propeller-nuxt source used a Windows-only literal that wouldn't survive scaffold).
[0.4.0] - 2026-06-02
Aligns both shop templates (shop-next, shop-vue) with the
prop-cascade cleanup completed in the upstream package + reference
boilerplates.
Why this matters
A shop scaffolded before 0.4.0 started life with the verbose
infra-prop-cascading pattern: every view explicitly passed
graphqlClient, user, companyId, language, includeTax,
currency, configuration, and portalMode to every package
component, even though <PropellerProvider> was wrapping the routed
tree and could resolve them. After this release a fresh scaffold starts
clean — components resolve from the provider, views only pass domain
props.
What changed under the hood
This release sits on top of:
propeller-v2-react-ui@0.4.0— retrofitted 6 client components to consumeuseInfraProps; added provider-aware client wrappers for the 6@rsc-safecomponents (the pure versions stay on/purefor RSC use).propeller-v2-vue-ui@0.3.1— fixes the criticalinject()-inside-computedbug introduced in 0.3.0 that broke anonymous AddToCart on every retrofitted page. Required: 0.3.0 scaffolds are silently broken; 0.4.0 scaffolds are correct.
Both templates already pin the package via github:...#master, so a
fresh npx create-propeller-shop picks up the post-fix builds
automatically. No template-side dependency bump needed.
Template changes (mechanical prune)
shop-next (10 files, mirrors propeller-next's 0f65f50 +
ae9117c + 16c9350):
app/account/layout.tsx,app/account/page.tsxapp/category/[id]/[slug]/CategoryIsland.tsx+page.tsxapp/checkout/page.tsxapp/cluster/[clusterId]/[slug]/ClusterDetailIsland.tsxapp/product/[productId]/[slug]/ProductDetailIsland.tsx+page.tsxapp/search/[[...term]]/SearchIsland.tsx+page.tsx
shop-vue (23 files, mirrors propeller-vue's 94f74d3 + b6f604c
d30040c):
- 21
src/views/**files: catalog (Category, Cluster, Product, Search), Cart, Checkout, Home, Login, Register, ForgotPassword, Account views (Account, Addresses, FavoriteDetail, Favorites, OrderDetail, Orders), B2B account views (AuthorizationRequests, AuthorizationSettings, QuoteDetail, QuoteRequests, Quotes). - 2
src/components/layout/**:AppHeader.vue(the largest single cleanup — CompanySwitcher, SearchBar ×2, AccountIconAndMenu, CartIconAndSidebar, PropellerMenu ×2),AccountLayout.vue.
What stays
A small set of explicit infra props remains intentional:
graphqlClient={orderEditorGraphqlClient}on<PurchaseAuthorizationConfigurator>inb2b-routes/.../authorization-settings/page.tsx— only place using a non-default GraphQL client.<ProductPrice>/<ProductBulkPrices>frompropeller-v2-react-ui/purekeep explicitincludeTax/user/portalMode/currency— they're rendered from Server Components (ProductPriceIslandshape) and the provider isn't reachable in RSC.<CompanySwitcher>userprop — component not yet retrofitted in either UI package.<PriceToggle>includeTax/languageprops (Vue) — not yet retrofitted in vue-ui.
Migration
None. Existing scaffolded shops keep working unchanged (the templates
have no effect on already-generated shop directories). A fresh
create-propeller-shop run gets the clean version.
[0.3.3] - 2026-06-02
Added
- Docusaurus documentation site under
docs/, deployed to https://propeller-commerce.github.io/propeller-v2-accelerator/ via a new.github/workflows/docs.ymlGitHub Action (build + GitHub Pages deploy). The biggest of the new docs sites — covers getting-started, thecreate-propeller-shopCLI reference,propeller doctor, the three shop modes (b2b / b2c / hybrid) with the portal-mode interaction, the per-template surface (shop-next + shop-vue), CMS adapter wiring, the flat scaffolded<shop>/{frontend,cms}/layout, thepropeller.jsonschema (including every substitution variable), and the Phase B/C roadmap. release_to_githubstage in.gitlab-ci.yml— automatic GitHub Release on everyRelease X.Y.Zpush, mirroring the SDK pattern.
Notes
No CLI / scaffolding behaviour changes — this is a tooling release that backfills documentation + release automation. Existing scaffolded shops are unaffected.
[0.3.2] - 2026-06-02
Changed
- Dropped the
public_html/segment from scaffold output. Shops now land as<name>/frontend/and<name>/cms/instead of<name>/public_html/frontend/and<name>/public_html/cms/. Thepublic_html/indirection was a holdover from cPanel-style hosting that doesn't apply to the modern deployment targets we ship to — it just added a directory hop with no upside. propeller doctornow resolvespropeller.jsonfrom./or./frontend/(was./public_html/frontend/).scaffold.tswrites the frontend and CMS trees directly under the shop root; the next-steps banner now printscd <name>/frontendinstead of the longer path.- Doc updates in
README.md, bothREADME.template.mdfiles, thepropeller.jsonschema docstring, and thecmsReadme.tsheader comment to match.
Migration
Existing scaffolded shops are unaffected — the change only touches new
scaffolds. If you want to flatten an existing tree manually, move
public_html/frontend/ and public_html/cms/ up one level and delete
the empty public_html/.
[0.3.1] - 2026-06-01
End-to-end validation fixes — turning the smoke-test into a green doctor
run on real scaffolded shops.
Fixed
- Scaffolded shops no longer ship
.gitkeepplaceholders. The copy walker now skips.gitkeep(and the internaltemplate.jsonmanifest) by name. Also removed the leftover.gitkeepfiles from the template trees themselves so the skip is belt-and-braces. propeller doctor's B2B route check was looking forapp/account/contacts(Next) andContactsView.vue(Vue), neither of which exists in the boilerplate. Swapped the third probe toprice-requests/PriceRequestsView.vueso the check matches what the templates actually emit.propeller doctor's CMS adapter check was emittingfailfor a declared adapter that wasn't installed. Demoted towarnbecause the adapter packages are not yet published to npm and not pinned inpackage.jsonat scaffold time — the user installs them manually. The doctor still surfaces the gap so the omission isn't silent.
Validated
create-propeller-shop e2e-hybrid --stack=next --mode=hybrid --cms=strapi --yes
followed by propeller doctor in the scaffolded shop now returns
All checks passed. with three green checks and two yellow warnings (the
not-yet-installed packages).
[0.3.0] - 2026-06-01
Vue 3 + Vite SSR shop template extracted from propeller-vue/frontend.
create-propeller-shop --stack=vue now produces a runnable Vue shop with
the same mode-specific surface as the Next template (0.2.0).
Added
templates/shop-vue/shared/— root config (index.html,server.js,vite.config.ts, three tsconfigs,.env.example,.gitignore) plus the entiresrc/tree (App.vue, entry points,assets/,components/,composables/,lib/,stores/,views/minus B2B views andviews/csr/+views/blog/). Thesrc/views/account/retains only universal views: Account, Addresses, Favorites, FavoriteDetail, Invoices, Orders, OrderDetail.templates/shop-vue/b2b-routes/— 6 B2B views moved out of shared: QuotesView, QuoteDetailView, QuoteRequestsView, AuthorizationRequestsView, AuthorizationSettingsView, PriceRequestsView. Copied into the samesrc/views/account/path whenmode !== 'b2c'.src/router/index.template.ts— replaces the staticrouter/index.ts. Two Handlebars-driven behaviours:SHOP_MODEconstant is baked in ('b2b'/'b2c'/'hybrid') and drives the runtime userMode guard.{{#unless isB2C}}…{{/unless}}block around the B2B route entries — they're not registered at all in a pure b2c shop, so the router has nothing to match (no need to rely on the runtime guard for b2c).registerGuardsgains a new userMode check after the auth gate: routes listed inrouteUserModesreturn{ name: 'not-found' }when the resolved userMode doesn't match. Anonymous users pass through (the auth guard handles them).
package.template.jsonandREADME.template.mdmirroring the Next versions but for the Vue dependency set.template.jsonfor Vue bumped to0.3.0so the manifest version matches the CLI/template version.
Smoke-tested
create-propeller-shop test-vue-b2c --stack=vue --mode=b2c --cms=none --yes
and the hybrid+strapi / b2b+cms variants all produce the expected per-mode
view sets and per-mode router registrations.
[0.2.0] - 2026-06-01
Next.js shop template extracted from propeller-next and wired through the
scaffolder. create-propeller-shop --stack=next now produces a runnable
shop tree (115 files, 1.3 MB) in <name>/frontend/ with the
correct mode-specific surface.
Added
templates/shop-next/shared/— 107 files covering everything every Next shop needs regardless of mode:app/routes (login, register, cart, checkout, product, cluster, category, search, CMS catch-all, blog, the universalaccount/{orders,addresses,favorites,invoices}subtree, all api routes includingauth/,graphql/,revalidate/),components/,context/(Auth, Cart, Company, Global, Language, Price),data/(config, countries, defaults, companyViewerAttributes),hooks/,lib/(api, cms, server, seo, services, listingParams, userHint, utils),utils/, and the entirepublic/static asset folder.templates/shop-next/b2b-routes/— 8 files mounted only whenmode !== 'b2c':app/account/{quotes,quote-requests,authorization-requests,authorization-settings,price-requests}/, each gated at the page root withRequireUserMode allow={['b2b']}.lib/routeGuards.ts(NEW shared file) — declarative map of route → allowed userModes. Pages callRequireUserModein the JSX tree; a hybrid Customer hitting/account/quotesgetsnotFound()(the middleware-level guard was dropped — the JWT cookie carries no user type, so a per-page client guard is the simpler path).components/auth/RequireUserMode.tsx(NEW shared file) — client component that readsuseUserMode()from the React UI package and triggersnotFound()when the resolved mode isn't allowed.- Six
.template.*parameterised files, rendered through Handlebars at scaffold time and emitted with the.templatesuffix stripped:data/config.template.ts,app/layout.template.tsx,next.config.template.ts,package.template.json,README.template.md,.env.example. - Substitution context extended with
isB2B/isB2C/isHybridmode flags,cmsAdapterTsValue/cmsAdapterJsonValue/cmsAdapterPackage/cmsAdapterDisplayCMS variants,portalModeConstant(uppercase enum form),defaultLocaleLower,siteHostname/apiHostnamederived fromsiteUrl, andfeatureQuotes/featureAuthorization/featureContactsmode-derived defaults.
Changed
collectShopConfignow respectsdefaults.yes— missing values short- circuit to built-in defaults (stack=next, mode=hybrid, cms=none, locales=['en'], currency=EUR, portalMode=defaultPortalForMode(mode), siteUrl=https://<name>.example.com) instead of opening a prompt the caller can't answer in non-TTY runs.data/config.template.tsexposes a newshopModeliteral and defaultsincludeVAT: true(gross), tracking the runtime decision baked into Phase 0.- B2B page roots refactored from
export default function Page() { … }toexport default function Page() { return <RequireUserMode>…</RequireUserMode>; } function PageInner() { … }so the client-side userMode gate runs before the body executes.
Known limitations
- CMS adapter packages (
propeller-v2-cms-adapter-strapi,-cms) live inside this monorepo'spackages/; they are not yet published to npm or split into standalone repos, so the scaffoldedpackage.jsondoes not pin them. The scaffolded README instructs the user to install them manually via--install-links file:../../...ornpm installonce they are published. Thepropeller.json -> cms.adapterfield still records the choice sopropeller doctorcan verify installation later. next.config.template.tsships a minimalremotePatternslist derived from thesiteUrl. Shops with non-conventional API hostnames must edit it after scaffolding.
[0.1.0] - 2026-06-01
Initial scaffold. Monorepo skeleton + CLI shell + the two CMS adapter
packages. Templates ship empty (just .gitkeep + template.json); the
Next and Vue templates will be extracted from propeller-next and
propeller-vue in 0.2.0.
Added
packages/cli/—create-propeller-shopandpropellerbinaries built with tsup. Three commands:create-propeller-shop <name> [flags]— interactive scaffold flow. Accepts--stack,--mode,--cms,--locales,--default-locale,--currency-code,--portal-mode,--site-url,--skip-install,--yes. Any missing flag is asked via@inquirer/prompts.propeller doctor— validatespropeller.jsonagainst the Zod schema, verifies pinned packages are installed, checks portalMode matchesdata/config.ts, confirms B2B route presence matches mode, and verifies the declared CMS adapter is installed.propeller upgradeandpropeller eject— reserved for Phase B.
packages/cms-adapter-strapi/— Strapi v5 RESTCmsAdapterimplementation. Three methods (getPage,getMenu,getGlobals), optional API token, customisablefetchimpl for tests.packages/cms-adapter-cms/— Stub for the generic Propeller CMS backend. ReturnsnullfromgetPage/getMenu,{}fromgetGlobals. Exists so the adapter pattern is exercised end-to-end without blocking on backend availability.templates/shop-next/+templates/shop-vue/— Empty directories withtemplate.jsonmanifests declaring stack, version, andpropellerCompatranges. The actual route + component extraction lands in 0.2.0.propeller.jsonschema — Full Zod definition withShopMode,PortalMode,CmsAdapter,Stack, and abuildPropellerJsonhelper that translates prompt answers into a valid manifest.
Scope
v0.1 ships scaffolding infrastructure — CLI, schema, prompts, copy
walker, doctor. v0.2 ships the actual templates extracted from
propeller-next + propeller-vue. The schema and ejected list are wired
in from day one so Phase B (upgrade, eject) is non-breaking.