$npx -y skills add 40RTY-ai/shopify-admin-skills --skill shopify-admin-agentic-product-jsonld-backfillBackfill the structured product/variant fields that power Product JSON-LD — barcode (GTIN), SKU, vendor, product type, weight — so AI agents can quote exact, in-stock items instead of guessing.
| 1 | ## Purpose |
| 2 | AI shopping agents read a product's structured data (the fields Shopify themes emit as `schema.org/Product` JSON-LD) to confirm price, availability, and identity. Missing barcodes (GTIN), SKUs, vendor, or product type leave the listing ambiguous — so the agent skips it or recommends a competitor whose data is complete. This skill finds products/variants with those gaps and backfills them: vendor and product type at the product level, barcode/SKU at the variant level. Fixes the agentiq.report findings `product-schema-jsonld`, `gtin-sku-pdp`, and `variant-metadata`. |
| 3 | |
| 4 | ## Prerequisites |
| 5 | - Authenticated Shopify CLI session (`shopify auth login --store <domain>`) |
| 6 | - Required API scopes: `read_products`, `write_products` |
| 7 | |
| 8 | ## Parameters |
| 9 | All skills accept these universal parameters: |
| 10 | |
| 11 | | Parameter | Type | Required | Default | Description | |
| 12 | |-----------|--------|----------|---------|-------------| |
| 13 | | store | string | yes | — | Store domain (e.g., mystore.myshopify.com) | |
| 14 | | format | string | no | human | Output format: `human` (default) or `json` | |
| 15 | | dry_run | bool | no | false | Preview mutations without executing | |
| 16 | |
| 17 | Skill-specific parameters: |
| 18 | |
| 19 | | Parameter | Type | Required | Default | Description | |
| 20 | |-----------|------|----------|---------|-------------| |
| 21 | | collection_id | string | no | — | Limit to a collection GID (else whole catalog) | |
| 22 | | tag | string | no | — | Limit to a product tag | |
| 23 | | set_vendor | string | no | — | Vendor to apply where missing (else only reports) | |
| 24 | | set_product_type | string | no | — | Product type to apply where missing | |
| 25 | | barcodes_csv | string | no | — | Path to a CSV of `sku,barcode` to map GTINs onto matching variants | |
| 26 | | fields | string | no | all | Comma list of fields to backfill: `vendor,product_type,barcode,sku` | |
| 27 | |
| 28 | ## Safety |
| 29 | |
| 30 | > ⚠️ Step 3 (`productUpdate`) and Step 4 (`productVariantsBulkUpdate`) write live product/variant data. Barcodes and SKUs are matched from your `barcodes_csv`; a wrong mapping mislabels a product's identity to every agent. Always run `dry_run: true` first and verify the change set CSV. This skill never overwrites a field that already has a value — it only fills blanks. |
| 31 | |
| 32 | ## Workflow Steps |
| 33 | |
| 34 | 1. **OPERATION:** `products` — query |
| 35 | **Inputs:** `first: 250`, optional `query: "tag:'<tag>'"` or collection filter; fields `vendor`, `productType`, `variants{ id sku barcode }`; paginate until `hasNextPage: false`. |
| 36 | **Expected output:** Products/variants with missing target fields. |
| 37 | |
| 38 | 2. **COMPUTE (no API):** build the change set — only blank fields, joined to `barcodes_csv` by SKU for barcodes. Emit the preview CSV. |
| 39 | |
| 40 | 3. **OPERATION:** `productUpdate` — mutation |
| 41 | **Inputs:** per product `{ id, vendor?, productType? }` (only where blank and a value is supplied). |
| 42 | **Expected output:** Updated product; collect `userErrors`. |
| 43 | |
| 44 | 4. **OPERATION:** `productVariantsBulkUpdate` — mutation |
| 45 | **Inputs:** per product `productId` + `variants: [{ id, barcode?, inventoryItem: { sku? } }]` for blank variant fields. |
| 46 | **Expected output:** Updated variants; collect `userErrors` across batches. |
| 47 | |
| 48 | ## GraphQL Operations |
| 49 | |
| 50 | ```graphql |
| 51 | # products:query — validated against api_version 2025-01 |
| 52 | query BackfillProducts($first: Int!, $after: String, $query: String) { |
| 53 | products(first: $first, after: $after, query: $query) { |
| 54 | edges { |
| 55 | node { |
| 56 | id |
| 57 | title |
| 58 | vendor |
| 59 | productType |
| 60 | variants(first: 100) { |
| 61 | edges { node { id sku barcode } } |
| 62 | } |
| 63 | } |
| 64 | } |
| 65 | pageInfo { hasNextPage endCursor } |
| 66 | } |
| 67 | } |
| 68 | ``` |
| 69 | |
| 70 | ```graphql |
| 71 | # productUpdate:mutation — validated against api_version 2025-01 |
| 72 | mutation BackfillProductFields($input: ProductInput!) { |
| 73 | productUpdate(input: $input) { |
| 74 | product { id vendor productType } |
| 75 | userErrors { field message } |
| 76 | } |
| 77 | } |
| 78 | ``` |
| 79 | |
| 80 | ```graphql |
| 81 | # productVariantsBulkUpdate:mutation — validated against api_version 2025-01 |
| 82 | mutation BackfillVariantFields($productId: ID!, $variants: [ProductVariantsBulkInput!]!) { |
| 83 | productVariantsBulkUpdate(productId: $productId, variants: $variants) { |
| 84 | productVariants { id sku barcode } |
| 85 | userErrors { field message } |
| 86 | } |
| 87 | } |
| 88 | ``` |
| 89 | |
| 90 | ## Session Tracking |
| 91 | |
| 92 | **Claude MUST emit the following output at each stage. This is mandatory.** |
| 93 | |
| 94 | **On start**, emit: |
| 95 | ``` |
| 96 | ╔══════════════════════════════════════════════╗ |
| 97 | ║ SKILL: <skill name> ║ |
| 98 | ║ Store: <store d |