---
title: 'Agent editability'
description: 'Make the shop''s structure editable by AI agents and machine config — homepage section layout, theme tokens, and the catalog — via MCP tools and JSON files.'
canonical: 'https://cartwright.app/docs/features/agent-editability'
---

# Agent editability (/docs/features/agent-editability)



Agent editability is about letting an **AI agent or a machine-written config file** change the
*structure* of the shop: the homepage section order, the theme tokens, and the catalog itself.

> **Not the same as [in-place editing](/docs/features/in-place-editing).** In-place editing
> (engine v0.14.0) is a human admin who **clicks a copy element** on the live storefront and lets an
> AI rewrite the **text**. Agent editability (engine v0.16.0) is **agents and JSON** editing the
> shop's **layout, theme, and catalog** — different layer, complementary feature.

## Section layout (`sectionLayout` / `layoutJson`) [#section-layout-sectionlayout--layoutjson]

Turn on the `sectionLayout` flag (default-off) and an AI agent can reorder or hide the studio
homepage sections via the `design.set_layout` MCP tool — without editing `homepage.tsx`.

* The override is stored as `BrandingSettings.layoutJson` (runtime-mutable; works on a read-only
  serverless filesystem). Null → the design pack's default order (zero regression).
* **Required sections (hero, CTA footer) cannot be hidden.** Unknown keys are ignored.
* `design.set_layout` is **revertible** via the audit log; `design.get_layout` reads the current
  override. Both use the `settings:*` scope.
* Flag off → the hardcoded section order renders byte-identical.

```jsonc
// design.set_layout input — reorder + hide one section
{
  "confirm": true,
  "layout": {
    "sections": [
      { "key": "hero", "enabled": true },
      { "key": "featureGrid", "enabled": true },
      { "key": "valueProps", "enabled": false },
      { "key": "ctaFooter", "enabled": true }
    ]
  }
}
```

## Extended `themeJson` (fonts + radius) [#extended-themejson-fonts--radius]

The same `themeJson` override that holds the 6-colour palette now accepts optional `fonts` and
`radius` as a **strict superset** — a current palette parses and renders identically.

```jsonc
{
  "accent": "#d97757", "accentDeep": "#b25b3f", "cream": "#faf6f0",
  "sand": "#efe7da", "ink": "#1f1b16", "muted": "#7c7268",
  "fonts": { "sans": "Inter, sans-serif", "mono": "JetBrains Mono, monospace" },
  "radius": { "md": "12px", "lg": "20px", "xl": "28px" }
}
```

Values are **injection-guarded** before they reach the inline `<style>` (radius must match
`^\d+(\.\d+)?(px|rem|em|%)$`, fonts may not contain `{ } ; <`), and a bad sub-value is dropped
without rejecting the palette. (`fonts.sans` re-points the family name; loading a new webfont is
separate.)

## `products.json` machine-seed [#productsjson-machine-seed]

Seed an entire catalog from a validated JSON file instead of editing TypeScript:

```bash
pnpm seed
```

* If `prisma/products.json` exists it overlays the template's products (categories/pages stay in the
  template, since products reference `categorySlug`).
* **Prices are in øre** (machine-precise — e.g. `89900` = 899,00 kr), validated against a zod schema
  with **per-row errors** that fail fast. No file → the TypeScript template is used.

## Setup safety [#setup-safety]

A fail-fast env preflight surfaces a missing `AUTH_SECRET` or database URL **on boot** with a
one-line fix, instead of a confusing downstream error.
