generating-weaverse-project-json — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited generating-weaverse-project-json (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Generate valid, import-ready Weaverse project export JSON files.
This skill produces JSON files that conform to the Weaverse import contract. It works independently — you can use it from a site migration, a design spec, a verbal description, or any other input that describes what pages and sections should exist.
The output is a single JSON file matching the schema in references/project-json-schema.md, with a real-world example in references/demo.json.
This skill accepts any of these as input:
cloning-websites-to-weaverse (website migration flow)figma-to-weaverse (Figma design flow)The only hard requirement: you need to know which section types to use. Read app/weaverse/components.ts to get the list of registered sections and blocks.
This skill produces an import JSON that establishes the project structure — pages, sections, and initial content. That JSON is imported once into the Weaverse Studio editor to create the project.
After the structure exists, ongoing content edits (copy, images, localization, bulk updates) should go through the `weaverse-content-api` skill, not by re-importing. The Content API can only update items that already exist, so the import-then-update split matters: use this skill to create structure, weaverse-content-api to maintain it. Keep the item ids stable between the two.
references/project-json-schema.md for the contract and references/demo.json for a complete real-world exampleapp/weaverse/components.ts to know which section and block types are availableapp/sections/ or app/components/ to learn valid schema fields, enum values, and defaultspython scripts/validate.py <output-file> to catch structural errors{
"version": "1.0.0",
"exportedAt": "<ISO timestamp>",
"project": { "name": "<name>", "config": {} },
"pages": [],
"pageAssignments": []
}Contains theme settings, locale, and colors. Accepted keys:
| Key | Type | Purpose |
|---|---|---|
previewHost | string | Dev server URL, usually http://localhost:3456 |
theme | object | Storefront-wide design tokens (colors, typography, layout) |
defaultLocale | object | { label, language, country, currency, pathPrefix } |
recentColors | string[] | Editor color picker recent colors |
For theme, refer to references/demo.json → project.config.theme for the full set of valid keys. Key categories:
colorPrimary, colorText, colorBackground, colorLine, colorTextSubtle, colorLineSubtle, colorTextInverse, colorForegroundbodyBaseSize, bodyBaseLineHeight, bodyBaseSpacing, h1BaseSize, headingBaseLineHeight, headingBaseSpacingpageWidth, footerWidth, headerWidth, navHeightDesktop, navHeightTablet, navHeightMobileheaderBgColor, headerText, footerBgColor, footerText, topbarBgColor, topbarTextColor, topbarHeightbuttonPrimaryBg, buttonPrimaryColor, buttonSecondaryBg, buttonSecondaryColor, btnCornerRadiuspcardAlignment, pcardImageRatio, pcardBorderRadius, pcardShowVendor, pcardShowReviews, pcardShowSalePrice, etc.newBadgeText, newBadgeColor, saleBadgeText, saleBadgeColor, soldOutBadgeText, soldOutBadgeColor, bestSellerBadgeText, bestSellerBadgeColorsocialFacebook, socialInstagram, socialLinkedIn, socialXnewsletterTitle, newsletterDescription, newsletterButtonText, newsletterPlaceholder, newsletterPopupEnabled, etc.Only include theme keys you understand and intend to set. Do not copy the entire demo theme blindly.
Each page has id, name, rootId, and a flat items array:
{
"id": "b98mnnqmv3tmce7wmw3l7vw4",
"name": "Homepage",
"rootId": "019b917a-f48f-72d4-aee7-3b1eae6b7dca",
"items": [
{ "id": "019b917a-f48f-72d4-aee7-3b1eae6b7dca", "type": "main", "data": {}, "children": [{ "id": "019b917a-f48f-72d4-aee7-3b1f5ca586c1" }] },
{ "id": "019b917a-f48f-72d4-aee7-3b1f5ca586c1", "type": "hero-image", "data": { "height": "small" }, "children": [{ "id": "019b917a-f48f-72d4-aee7-3b22cd55e21b" }] },
{ "id": "019b917a-f48f-72d4-aee7-3b22cd55e21b", "type": "heading", "data": { "content": "Welcome" }, "children": [] }
]
}Key rules:
items array, hierarchy is expressed through children id-referencesrootId[] for leaf items, [{ "id": "<item-id>" }] for parents{} when no non-default values are neededapp/weaverse/components.tsCRITICAL: The Weaverse importer expects both data and children to be present on EVERY item. Omitting them causes silent import failures (empty page renders). Always include "data": {} and "children": [] even when empty.
Maps pages to routes:
{ "pageId": "b98mnnqmv3tmce7wmw3l7vw4", "type": "INDEX", "handle": "", "locale": "en-us" }Common types: INDEX, PRODUCT, COLLECTION, ALL_PRODUCTS, COLLECTION_LIST, PAGE, BLOG, ARTICLE, CUSTOM.
For CUSTOM pages, set handle to the route slug (e.g., "reseller"). For standard template pages, handle is usually empty "".
Standard pages (product, collection, blog, article) that aren't being customized should be empty stubs:
{
"id": "qa8xa47ou35atbo1ik4w7v6y",
"name": "Default product",
"rootId": "019b917a-f490-794d-95d0-82a578d7cdfc",
"items": [{ "id": "019b917a-f490-794d-95d0-82a578d7cdfc", "type": "main", "data": {}, "children": [] }]
}Before writing any select, toggle-group, or position value, read the section source code. Common mistakes:
| Wrong | Correct | Field |
|---|---|---|
"custom" | "small", "medium", "large", "full" | height |
"stretch" | "full", "fixed" | width |
"right" / "left" | "start", "end" | desktopMediaPosition |
"white" / "black" | "light", "dark" | arrowsColor |
If a field matches the schema default, omit it. The Weaverse editor strips defaults on save. Including them creates noise.
Collections and products use object format, not bare strings:
// Collections
"collections": [{ "id": 456905851102, "handle": "covers" }]
// Products
"product": { "id": 123456789, "handle": "my-product" }If real Shopify IDs are unknown, omit the field or use []. Do not invent fake IDs.
External images use a bare URL string. Shopify-hosted images use the media object:
// External
"backgroundImage": "https://example.com/image.jpg"
// Shopify media
"backgroundImage": {
"id": "gid://shopify/MediaImage/12345",
"url": "https://cdn.shopify.com/...",
"width": 1920, "height": 1080, "altText": "Description"
}Page IDs and item IDs use different formats:
| Entity | Format | Example |
|---|---|---|
| Page `id` | CUID (25-char alphanumeric) | b98mnnqmv3tmce7wmw3l7vw4 |
Item `id` (and rootId) | UUID v7 (hyphenated) | 019b917a-f48f-72d4-aee7-3b1eae6b7dca |
Integrity rules:
id must be unique across the exportid must be unique across the exportrootId must match the root main item's id exactlyAfter generating the JSON, run the bundled validator:
python scripts/validate.py <path-to-output.json>The validator checks:
id, name, rootId, itemsrootId resolves to an item with type: "main"data and children fields (both required)pageAssignment.pageId values resolve to existing pagesFix any reported errors and re-run until clean. Do not deliver JSON that fails validation.
| Mistake | Fix |
|---|---|
Missing data or children on items | Both are REQUIRED on every item — use "data": {} and "children": [] even when empty |
Nesting full items inside children | Use { "id": "..." } references only |
rootId doesn't match any item | Ensure root main item's id equals rootId |
| Using unregistered section types | Read app/weaverse/components.ts first |
| Duplicate IDs | Page IDs = CUIDs, item IDs = UUIDs — every id must be unique |
Including default values in data | Omit fields that match schema defaults |
| Guessing enum values | Read the section source for valid options |
| Copying entire demo theme blindly | Only include keys you understand and intend |
Missing pageAssignments | Every page needs a route assignment |
| Fake Shopify IDs | Omit unknown IDs, let user select in editor |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.