← 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.
  • heroPrompt string optional The seller's own prompt for the hero image. Drawn from verbatim when the home page has a hero slot to fill; absent = a lifestyle shot of what the shop sells. A hero image already in facts.identity.heroImage wins over both.
  • 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.
  • publish boolean optional FALSE = build everything and open nothing: the storefront stays off and the twelve pages stay drafts, for a person to review first (the store-builder workflow opens and publishes after its approval). Absent = go live in test mode, as before.
  • acceptPartial boolean optional TRUE = `ok` means the store is READY (six-plus products and twelve published pages with no bracket), not that every step verified — a missing product photo or a live card key is still named in `steps` and `complete` stays false. For a build a person reviews next (the store-builder workflow), where one failed image must not fail the whole run. Absent = the strict verdict.

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. With `acceptPartial`, TRUE when the store is ready (catalogue + verify) — see `complete`.
  • complete boolean Every step verified — the strict verdict, whatever `acceptPartial` said.
  • 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 · chat · verify — each ok or failed with a reason. Nothing is skipped silently. `chat` writes the shop assistant (the page chat pack) onto every role page that has none.
  • 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 9
  • one.ie/web/src/lib/puck/packs/shop/about.ts:110
  • one.ie/web/src/lib/puck/packs/shop/contact.ts:87
  • one.ie/web/src/lib/puck/packs/shop/faq.ts:45
  • one.ie/web/src/lib/puck/packs/shop/home.ts:66
  • one.ie/web/src/lib/puck/packs/shop/index.ts:27
  • one.ie/web/src/lib/puck/packs/shop/shipping-returns.ts:45
  • one.ie/web/src/lib/puck/strip-placeholders.ts:6
  • one.ie/web/src/lib/receiver-index.generated.ts:314
  • one.ie/web/src/lib/resolvers/storefront/shop-build.ts:238
Agent runtime 1
  • channels/src/tools/commerce.ts:104
Workflow 1
  • one.ie/web/src/lib/workflow-templates.ts:222
→

Answered by

shop:build one.ie/web/src/lib/resolvers/commerce.ts:903 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"
        ]
      }
    },
    "heroPrompt": {
      "description": "The seller's own prompt for the hero image. Drawn from verbatim when the home page has a hero slot to fill; absent = a lifestyle shot of what the shop sells. A hero image already in facts.identity.heroImage wins over both.",
      "type": "string"
    },
    "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": {}
    },
    "publish": {
      "description": "FALSE = build everything and open nothing: the storefront stays off and the twelve pages stay drafts, for a person to review first (the store-builder workflow opens and publishes after its approval). Absent = go live in test mode, as before.",
      "type": "boolean"
    },
    "acceptPartial": {
      "description": "TRUE = `ok` means the store is READY (six-plus products and twelve published pages with no bracket), not that every step verified — a missing product photo or a live card key is still named in `steps` and `complete` stays false. For a build a person reviews next (the store-builder workflow), where one failed image must not fail the whole run. Absent = the strict verdict.",
      "type": "boolean"
    }
  },
  "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. With `acceptPartial`, TRUE when the store is ready (catalogue + verify) — see `complete`."
    },
    "complete": {
      "description": "Every step verified — the strict verdict, whatever `acceptPartial` said.",
      "type": "boolean"
    },
    "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 · chat · verify — each ok or failed with a reason. Nothing is skipped silently. `chat` writes the shop assistant (the page chat pack) onto every role page that has none.",
      "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"
  ]
}