cimplify
CLI

Inspect

Read-only snapshot of a storefront's catalogue, brand, and merchandising state, for humans at the terminal and agents over `--json`.

cimplify inspect reads the same data the storefront sees, using the same NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY the running site uses. It hits the SDK's typed clients (no new server endpoints), so what inspect reports is exactly what a customer would render, with no privileged-vs-public divergence.

It's the companion to introspect (local repo state): introspect shows your auth/link/brand.ts/env/git, inspect shows the business state: products, collections, gaps.

Quick start

cimplify inspect                  # catalogue (default subcommand)
cimplify inspect catalogue
cimplify inspect catalogue --json # agent-friendly envelope
cimplify inspect catalogue --all  # walk the full catalogue for exact gap counts

inspect reads NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY from .env (or --public-key <key>). A cpk_live_… / cpk_test_… key targets hosted Cimplify; anything else (mock-dev, empty) targets the local mock on :8787.

Subcommands

CommandWhat it shows
inspectDefault: inspect catalogue.
inspect catalogueProducts, collections, categories, tags + gaps and shape hints.

brand, content, locale, and all are reserved for upcoming versions.

Flags

FlagMeaning
--public-key <key>Override the key from .env.
--limit <n>Sample size for the product page (default 20).
--allPaginate the entire catalogue. Exact gap counts; pays for the walk.
--cursor <token>Resume a previous walk from next_cursor.
--jsonEmit the locked JSON envelope (see below); suppress all human chatter.

What the human view looks like

$ cimplify inspect catalogue

  Bakery & Co.  ·  @bakeryco  ·  2 locations  ·  USD, GHS

  Products      142   ⚠ 11 no image · 7 no description · 23 not in any collection
  Collections     8   ⚠ 1 empty (seasonal)
  Categories     12   ⚠ 1 empty (specials)
  Tags           24   ⚠ 56 products untagged

  Top tags     vegan (18) · bestseller (12) · gluten-free (9) · new (5)

  Collections
    ▸ Featured       12 items   Croissant, Baguette, Pain au chocolat …
    ▸ New arrivals    8 items
    ▸ Seasonal        0 items   ⚠ empty


  Sample products  (first 20 of 142)
    abc1  Croissant            $3.50   img ✓   bestseller · vegan
    abc2  Baguette             $4.00   img ✓   bestseller
    abc3  Pain au chocolat     $4.50   img ✗   —                   ⚠ image, tags

  Gaps computed from first 20 products. Add --all for exact counts.

The JSON envelope (locked contract, schema_version: "1")

{
  "ok": true,
  "schema_version": "1",
  "data": {
    "business": {
      "handle": "bakeryco",
      "name": "Bakery & Co.",
      "currencies": ["USD", "GHS"],
      "locations": 2
    },
    "totals": {
      "products": 142,
      "collections": 8,
      "categories": 12,
      "distinct_tags": 24
    },
    "gaps": {
      "no_image": 11,
      "no_description": 7,
      "no_price": 0,
      "no_collection": 23,
      "no_tags": 56,
      "empty_collections": [{ "id": "col_seasonal", "name": "Seasonal" }],
      "empty_categories":  [{ "id": "cat_specials", "name": "Specials" }]
    },
    "products": {
      "sample": [
        {
          "id": "prod_abc1",
          "name": "Croissant",
          "slug": "croissant",
          "price": { "amount": "3.50", "currency": "USD" },
          "has_image": true,
          "has_description": true,
          "tags": ["vegan", "bestseller"],
          "collection_ids": ["col_featured"],
          "category_ids": ["cat_breakfast"],
          "variant_count": 3
        }
      ],
      "next_cursor": "eyJpZCI6IjE5In0",
      "returned": 20
    },
    "collections": [
      {
        "id": "col_featured",
        "name": "Featured",
        "slug": "featured",
        "product_count": 12,
        "sample_product_ids": ["prod_abc1", "prod_abc2", "prod_abc3"]
      }
    ],
    "categories": {
      "tree": [
        { "id": "cat_breakfast", "name": "Breakfast", "slug": "breakfast", "product_count": 24, "children": [] }
      ]
    },
    "tags": {
      "top": [{ "tag": "vegan", "count": 18 }, { "tag": "bestseller", "count": 12 }]
    }
  },
  "meta": {
    "fetched_at": "2026-05-23T10:15:32Z",
    "source": "hosted",
    "sampled": true,
    "sample_size": 20,
    "gaps_method": "sample",
    "shape_hints": ["medium_catalogue", "uses_collections", "has_empty_collection", "untagged_majority", "has_image_gaps"],
    "suggestions": [
      { "kind": "fix_no_image", "count": 11 },
      { "kind": "fix_no_collection", "count": 23 },
      { "kind": "merchandise_empty_collection", "collection_id": "col_seasonal", "name": "Seasonal" }
    ],
    "suggested_commands": ["cimplify inspect catalogue --all"]
  }
}

Error envelope

{
  "ok": false,
  "schema_version": "1",
  "error": {
    "code": "NO_PUBLIC_KEY",
    "message": "Set NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY in .env or pass --public-key.",
    "remediation": "Get one at desk.cimplify.io/settings/api."
  }
}

Field rules

  • ok is always present.
  • schema_version is a contract over the whole document; bump on removal, rename, or type change of any field, shape_hints token, or suggestions[].kind. Adding is non-breaking.
  • data.gaps.empty_collections / empty_categories are always arrays (return [], never omit).
  • data.products.sample is always page-ordered (never randomized).
  • next_cursor is null when the walk is exhausted.
  • meta.source is "hosted" or "mock". Locked.
  • meta.gaps_method is "sample" or "exact". Locked.
  • meta.shape_hints is sorted alphabetically (deterministic, diffable).
  • meta.suggestions is ordered by impact (most actionable first).
  • meta.fetched_at is the only timestamp; nothing in data carries time.

shape_hints vocabulary

Flat string tokens for agents to branch on. Adding tokens is non-breaking; removing/renaming bumps schema_version.

Catalogue size

TokenMeaning
empty_catalogue0 products. Whole storefront needs an empty-state.
tiny_catalogue1–9 products. Skip search, deep filters.
small_catalogue10–99 products. Default UX.
medium_catalogue100–999 products. Search nice-to-have.
large_catalogue1000+ products. Search + facets required.

Feature presence

TokenMeaning
has_variantsAt least one product has variants → variant picker UI.
has_addonsAt least one product has add-on options → modifier UI.
has_subscriptionsBilling plans exist → recurring pricing toggle.
has_compositesBundle / composite products exist.
has_recipesProducts linked to ProductComponent (restaurant / manufacturing).
has_time_profilesProducts have time-of-day windows → hours-aware UI.
has_input_fieldsBuyer-supplied inputs (engraving, message).
has_custom_attributesCustom attribute schemas defined.
per_location_pricingPrices vary by location.
multi_currency>1 currency configured.
multi_location>1 location configured.

Merchandising state

TokenMeaning
uses_collections≥1 non-empty collection exists.
uses_categories≥1 non-empty category.
has_empty_collection≥1 collection has 0 products.
has_empty_category≥1 category has 0 products.
untagged_majority>50% of products are untagged.
unmerchandised_majority>50% of products aren't in any collection.

Data quality

TokenMeaning
has_image_gaps≥1 product missing image.
has_description_gaps≥1 product missing description.
has_price_gaps≥1 product missing price.

Environment

TokenMeaning
mock_dataReading from cimplify-mock (key isn't cpk_live_* / cpk_test_*).

suggestions[].kind vocabulary

Each entry is a stable kind + typed payload. Copy lives here (and in cimplify explain inspect-suggestions) so agents don't invent phrasing.

KindPayloadImplied prompt
add_first_product{}Catalogue is empty; seed or add a product.
add_first_collection{}Products exist but no collections; group some.
fix_no_image{ count }N products without images; add placeholders.
fix_no_description{ count }N products lack descriptions; generate copy.
fix_no_price{ count }N products have no price; open the editor.
fix_no_collection{ count }N products not in any collection; suggest "Featured".
fix_no_tags{ count }N untagged products; suggest tags from name/category.
merchandise_empty_collection{ collection_id, name }Collection "X" is empty; pick products to feature.
merchandise_empty_category{ category_id, name }Category "X" has no products; fill or remove.
tag_uncategorized_products{ count }Majority untagged; bulk-tag from category.
enable_search_ui{ product_count }Large catalogue; add search + filters.

Exit codes

CodeMeaning
0OK.
1Generic failure.
10NETWORK_ERROR.
30INVALID_INPUT (e.g., bad --public-key).
40NO_PUBLIC_KEY: neither .env nor --public-key provided.

Versioning policy

schema_version is bumped only on removal, rename, or type change of any field, any shape_hints token, or any suggestions[].kind. Adding fields, tokens, or kinds is non-breaking. Agents should pin schema_version === "1" and treat unknown fields as ignorable.

On this page