← Receivers

shop:build

shop family

Build a complete store in one call: storefront on in test mode with the basket, 6–12 products with copy, prices, an image and a stocked variant each, grouped into 3–4 collections, and the twelve shop pages filled and published with no bracket left. Never invents a founder, year, address or policy — those come back in factsToAdd. A second call creates nothing and answers the same receipt.

Effect
ask
Awaits an outcome — the call returns the response below.
Caller
member
The class of authority the caller must already hold, decided from the attested context with no round trip.
Cost
variable
What one call costs, so you can budget before acting.
Reversible
no
This cannot be undone. Dry-run it first where the contract allows.
Idempotent
yes
Safe to retry as-is.

Send it with your agent

One click hands your coding agent a prompt that registers the substrate, reads this contract, and makes the call. Launch opens the app; the others copy the prompt.

Claude Code
Codex
Cursor
Gemini CLI
Claude Desktop
ChatGPT
curl -X POST https://one.ie/api/ask/shop:build \
  -H "Authorization: Bearer $ONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"data": { "workspace": "tea-test", "description": "A small loose-leaf tea shop in Galway selling single-origin teas, blends and teaware." }}'

The key is never in a link. npx -y @oneie/cli login writes it to ~/.config/oneie/key on your machine.

Request

Validated before dispatch — an invalid payload is refused with the fix, never half-applied.

  • workspace string optional Which workspace to build. NOT an authority claim — the attested caller must control it (callerControlsWorkspace). Absent = the caller's own.
  • slug string optional Alias of `workspace`, for callers that speak the storefront receivers' field name.
  • description string required Plain English: what the business is and what it sells. The model writes the catalogue from this and nothing else.
  • products object[] optional Products the owner already knows. Used first; the model only fills the gap to six-plus. A product without a price is reported, never priced by guess.
  • currency string optional ISO 4217, default USD.
  • brand object optional The shop's name (else the workspace's display name) and an optional tagline.
  • facts object optional Optional ShopBusinessFacts (lib/puck/fill-shop-pack.ts) the owner typed — contact, policies, founder. Passed through to pages:fill-shop-pack and validated there.

Response

What comes back from the call.

  • ok boolean TRUE only when every step verified from the rows: twelve pages published with no bracket, six-plus products each with a price, an image and a stocked variant, the storefront and basket on, card rail in test mode.
  • error string A refusal before any step ran: `forbidden` · `no_db` · `missing description`.
  • workspace string
  • storeUrl string
  • mode test | live The card rail as MEASURED for the store's page (resolveStripeForPage), not as intended.
  • cryptoNetwork string The crypto rail as measured (resolveOneNetwork): mainnet | testnet.
  • businessName string
  • heroImage string | null
  • productIds string[]
  • products object[]
  • collections string[]
  • pages object[]
  • factsToAdd object[] Facts only the owner can give. Each one's sentence was left off the published pages rather than invented.
  • steps object[] storefront · catalogue · images · variants · pages · hero · fill · publish · verify — each ok or failed with a reason. Nothing is skipped silently.
  • created object What THIS call wrote. All zero on a repeat call.

Traffic

Every call to shop:build, counted where it is dispatched — over HTTP or in-process alike. Aggregate only — no actor, no payload, no workspace.

Counting…

Wiring

Every place in the open source that names shop:build, and the file that answers it. Read from the tree at build time — a receiver is reached by NAME through one door, so there is no import edge to follow and a grep is the honest shape of the question. Structure, not volume — the count is in Traffic above.

Called from

UI 1
  • one.ie/web/src/components/studio/ShopBuilder.tsx:1
API route 4
  • one.ie/web/src/lib/puck/packs/shop/home.ts:66
  • one.ie/web/src/lib/puck/strip-placeholders.ts:6
  • one.ie/web/src/lib/receiver-index.generated.ts:310
  • one.ie/web/src/lib/resolvers/storefront/shop-build.ts:238
Agent runtime 1
  • channels/src/tools/commerce.ts:104
→

Answered by

shop:build one.ie/web/src/lib/resolvers/commerce.ts:874 Dispatched through POST /api/ask/shop:build, after the envelope validates the payload.
JSON Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "workspace": {
      "description": "Which workspace to build. NOT an authority claim — the attested caller must control it (callerControlsWorkspace). Absent = the caller's own.",
      "type": "string"
    },
    "slug": {
      "description": "Alias of `workspace`, for callers that speak the storefront receivers' field name.",
      "type": "string"
    },
    "description": {
      "type": "string",
      "minLength": 1,
      "description": "Plain English: what the business is and what it sells. The model writes the catalogue from this and nothing else."
    },
    "products": {
      "description": "Products the owner already knows. Used first; the model only fills the gap to six-plus. A product without a price is reported, never priced by guess.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "price": {
            "description": "MINOR units of `currency` (2400 = 24.00) — the same unit as products:create's unit_amount.",
            "type": "number"
          },
          "description": {
            "description": "Kept verbatim; the model writes one only when this is absent.",
            "type": "string"
          }
        },
        "required": [
          "name"
        ]
      }
    },
    "currency": {
      "description": "ISO 4217, default USD.",
      "type": "string"
    },
    "brand": {
      "description": "The shop's name (else the workspace's display name) and an optional tagline.",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "tagline": {
          "type": "string"
        }
      }
    },
    "facts": {
      "description": "Optional ShopBusinessFacts (lib/puck/fill-shop-pack.ts) the owner typed — contact, policies, founder. Passed through to pages:fill-shop-pack and validated there.",
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    }
  },
  "required": [
    "description"
  ]
}
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean",
      "description": "TRUE only when every step verified from the rows: twelve pages published with no bracket, six-plus products each with a price, an image and a stocked variant, the storefront and basket on, card rail in test mode."
    },
    "error": {
      "description": "A refusal before any step ran: `forbidden` · `no_db` · `missing description`.",
      "type": "string"
    },
    "workspace": {
      "type": "string"
    },
    "storeUrl": {
      "type": "string"
    },
    "mode": {
      "description": "The card rail as MEASURED for the store's page (resolveStripeForPage), not as intended.",
      "type": "string",
      "enum": [
        "test",
        "live"
      ]
    },
    "cryptoNetwork": {
      "description": "The crypto rail as measured (resolveOneNetwork): mainnet | testnet.",
      "type": "string"
    },
    "businessName": {
      "type": "string"
    },
    "heroImage": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "productIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "products": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      }
    },
    "collections": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "pages": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "role": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "role",
          "slug",
          "title",
          "status",
          "url"
        ]
      }
    },
    "factsToAdd": {
      "description": "Facts only the owner can give. Each one's sentence was left off the published pages rather than invented.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "fact": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "token": {
            "type": "string"
          }
        },
        "required": [
          "fact",
          "token"
        ]
      }
    },
    "steps": {
      "description": "storefront · catalogue · images · variants · pages · hero · fill · publish · verify — each ok or failed with a reason. Nothing is skipped silently.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "step": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          },
          "detail": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          }
        },
        "required": [
          "step",
          "ok"
        ]
      }
    },
    "created": {
      "description": "What THIS call wrote. All zero on a repeat call.",
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "number"
      }
    }
  },
  "required": [
    "ok"
  ]
}