Install
$ agentstack add skill-yahiasherif002-claude-skills-build-theme ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Building a NUMU V3 Theme
The four packages and their roles — never blur them:
| Package | Role | Reaches the theme how | |---|---|---| | @numueg/theme-cli (≥0.7.0) | scaffold, dev server, validate, publish | dev dependency, numu-theme bin | | @numueg/theme-plugin (≥0.6.0) | vite build → dist/theme.js + import-map.json + manifest | numuTheme({ federate: true }) in vite.config | | @numueg/theme-sdk (≥0.10.0) | React runtime: hooks, components, contexts | externalized — the host storefront serves it via import map; the bundle never inlines it | | @numueg/theme-kit (≥0.1.0) | React-free helpers: settings guards, i18n pick, money, image | inlined into the bundle at build; pure functions, no runtime coupling |
1. Scaffold
npx @numueg/theme-cli init # or: numu-theme init
The scaffold already includes: all required templates, the standard 5-color + 2-font settings_schema.json block (wired to --theme-* CSS vars), Header/Footer + ~15 sections, vite.config with numuTheme({ federate: true }), bilingual patterns.
Non-negotiable rule: component filename = schema section type. A section whose schema type is featured_collection lives in src/sections/featured_collection.tsx. The registry is built by filename convention; a mismatch = section silently never renders.
2. Dependencies
// package.json — the split matters
"dependencies": { "@numueg/theme-kit": "^0.1.0" }, // inlined
"devDependencies": { "@numueg/theme-sdk": "^0.10.0", // externalized at build
"@numueg/theme-plugin": "^0.6.0",
"@numueg/theme-cli": "^0.7.0" }
3. Settings access — theme-kit, never hand-rolled guards
Merchant settings arrive as untyped JSON. Do NOT write local asString/localized helpers (that was the pre-kit copy-paste era). Import from the kit:
import {
localized, // localized(locale, en, ar) — ar-aware picker
asString, asNumber, asBool, asArray, asRecord, // type guards w/ fallbacks
asImageUrl, asImageAlt, // image-setting readers
readBlocks, pickItems, // block-container readers
formatMoney, centsToMajor, // money formatting
asImageTransform, applyImageTransform, // focal-point/crop transforms
} from "@numueg/theme-kit";
const title = asString(s.title) || localized(locale, "New arrivals", "وصل حديثاً");
If a helper is missing from the kit, add it TO the kit (PR + release), don't fork it locally.
4. SDK usage — what each new feature gives you for free
- Navigation: always `` from the SDK. Since 0.10 it
soft-navigates (client-side transition, no reload/remount) when the host supports it and falls back to a full nav otherwise. Programmatic: requestNavigate(href). Never use next/link, window.location, or raw `` for internal paths.
- Money: `
or kitformatMoney`.
NEVER hand-divide /100 or hardcode "EGP"/"ج.م" — multi-currency is live. ⚠ Pitfall: variant.price.amount is cents; product.price is major units.
- Global sections:
useSectionGroup("header")/"footer"returns the ordered
instances from themeSettings.section_groups; render them through your own registry. Themes that do this render their chrome on EVERY route consistently.
- Template overrides:
usePage().templatecarriesproduct.etc. The host
resolves template_suffix (Shopify OS 2.0-style variants) — render whatever template key you're handed; never hardcode "the product template".
- Data:
useCachedResource(key, fetcher)for theme-custom data (SWR-style dedup +
cross-instance sync). Catalog basics come from useShop/useProduct/useCollection/ useProducts/useCart/useCustomer/useNavigation/useSearch.
- Variants:
useVariantSelection(product)— it publishes the live picker axes to the
selection registry so addItem labels cart lines ("Black, L") even for legacy products. Custom add-to-cart buttons: publishVariantSelection/readVariantSelection.
- Checkout/account:
useCheckout,useShippingRates,useOrders,useCustomerAddresses,
useReorder, useGiftCardBalance — themes own these UIs.
- Rich text from merchants: SDK `
only (sanitizes). NeverdangerouslySetInnerHTML`. - Entry:
defineThemeEntry(ThemeRoot)— givesmount(client) +createApp(SSR
string render). Both must work: SSR parity is validated.
5. i18n / RTL — bilingual is mandatory
Every user-facing string ships en + ar. Fixed chrome strings: const t = useT()-style via SDK useLocale, or kit localized(locale, en, ar). Merchant content: bilingual settings (heading_en/heading_ar or i18n maps) read with localized. Layout must survive dir="rtl" — use logical CSS properties (margin-inline-start, not margin-left).
6. Validate + dev loop
numu-theme dev # local dev server against a store
numu-theme check # schema/manifest validation (single-source: SDK /validation)
numu-theme lint # section conventions
npm run build # vite + plugin → dist/theme.js, import-map.json, manifest
Build output must show federate: true and the current sdk_compat_minor in dist/import-map.json, with react/@numueg/theme-sdk externalized (grep dist/theme.js for from"react" — it must be an import, not inlined source).
- The host gates on
sdk_compat_minor: a bundle built against a NEWER SDK minor than
the host runtime serves is refused with a clear error. Build against the published SDK version the storefront runtime serves.
- If the theme renders its own header/footer chrome via section groups, the manifest
flag renders_global_sections (plugin ≥0.6.0 emits it) tells the host not to double-render fallback chrome.
7. Ship
- Bump
theme.jsonversion — the marketplace seed is idempotent by slug+version;
an unbumped version silently overwrites in place and merchants never see an update.
- Commit to
V3-themeson a feature branch → PR → merge tomain(triggers the R2
deploy + registry seed for test + prod).
- Stores are never auto-switched — merchants adopt the new version from the hub.
Pitfalls checklist (each one has bitten us)
- [ ] filename = schema type for every section
- [ ] no local guard helpers — kit imports only
- [ ] no
/100, no hardcoded currency strings; `` everywhere - [ ]
variant.price.amount= cents,product.price= major - [ ] SDK `
for ALL internal nav (soft nav is free; raw` forfeits it) - [ ] header/footer read from
useSectionGroup, not hardcoded - [ ] render
page.templateas handed (template overrides) - [ ] bilingual en/ar + RTL-safe CSS on every section
- [ ] `` for merchant HTML
- [ ] SSR parity:
createApprenders without window/document access at module top level - [ ]
theme.jsonversion bumped before merge - [ ] built against the SDK minor the host runtime currently serves
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Yahiasherif002
- Source: Yahiasherif002/claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.