propeller doctor
Sanity-check a scaffolded shop. Reads frontend/propeller.json (or the
file at the given path) and verifies the shop matches what the manifest
declares.
# inside a scaffolded shop (frontend/, or the root of a no-CMS shop)
npm run doctor
# anywhere else
npx -y -p @propeller-commerce/create-propeller-shop propeller doctor
What it checks
| # | Check | Level |
|---|---|---|
| 1 | propeller.json parses + validates against the Zod schema | red on failure |
| 2 | Every declared @propeller-commerce/* package resolves against node_modules/; none declared at all is also flagged | yellow on missing |
| 3 | The portal-mode var in the active env file (falling back to the example) matches shop.portalMode — NEXT_PUBLIC_PORTAL_MODE (Next), VITE_PORTAL_MODE (Vue), BOILERPLATE_PORTAL_MODE + NUXT_PUBLIC_PORTAL_MODE (Nuxt) | red on mismatch |
| 4 | B2B route shape matches mode (B2B routes present iff mode !== 'b2c') | red on mismatch |
| 5 | The CMS engine ships (lib/cms, Vue src/lib/cms) and CMS_PROVIDER selects the declared cms.adapter; the legacy cms value is flagged | yellow on mismatch |
Levels
- Green (✓) — passed.
- Yellow (!) — warning. Worth fixing but not a blocker.
- Red (✗) — failure. Exits with code 1.
Exit code
0— zero red checks. Any number of yellows is still a pass.1— at least one red check.
Use this in CI to gate merges:
- run: npm run doctor
Manifest resolution
doctor searches for propeller.json in this order:
./propeller.json./frontend/propeller.json
So you can run it from either the shop root or frontend/. If neither
exists, the run fails with a single red propeller.json not found …
finding.
Why declared-not-installed is yellow
A freshly scaffolded shop has not run npm install yet, so every package is
"declared but not installed" until it does. doctor surfaces the gap as a
warning so it isn't silent, without failing a shop that is simply not
installed yet.
Sample output
✓ propeller.json valid (v1, my-shop, hybrid).
✓ @propeller-commerce/propeller-v2-react-ui installed.
✓ @propeller-commerce/propeller-sdk-v2 installed.
! @propeller-commerce/propeller-v2-cms-react declared but not installed — run `npm install`.
✓ portalMode 'open' matches .env.local (NEXT_PUBLIC_PORTAL_MODE=open).
✓ B2B route presence matches mode=hybrid.
All checks passed.
Roadmap
propeller doctor --json— machine-readable findings for CI tooling.--strictflag to treat yellow as red.- Pin-drift check — flag installed package versions that don't match
the version stamped into
propeller.json -> dependencies.
Until those land, doctor is intentionally small and stable.