# Page Management

> Compile, create, inspect, and safely edit storefront pages with the MCP v3 action routers

Canonical URL: https://fa7e86e3d553:3005/tools/page-management

Storefront pages are authored as source-format HTML and managed through four
MCP v3 tools:

| Tool | Responsibility |
|---|---|
| `lexsis_pages` | Read pages, inspect source, compile, diff, and run integrity checks |
| `lexsis_drafts` | Apply reversible source, section, island, head, and version changes |
| `lexsis_page_create` | Create a new draft page and return its preview |
| `lexsis_live_ops` | Publish, unpublish, delete, or roll back after explicit approval |

Call `lexsis_discover` when an action or its current arguments are unfamiliar.
Former operation names such as `compile_page_source` remain searchable through
`lexsis_discover`, but they are not top-level tools on the consolidated
endpoint.

## Standard call shape

```json
{
  "name": "lexsis_pages",
  "arguments": {
    "action": "get",
    "args": {
      "page_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    }
  }
}
```

Successful calls expose the selected router and action:

```typescript
{
  ok: true;
  tool: string;
  action: string;
  data: unknown;
  meta: {
    operation: string;
    surface_version: "3.0";
  };
}
```

Router-level validation and dispatch failures use:

```typescript
{
  ok: false;
  tool: string;
  action: string;
  error: {
    code: string;
    message: string;
    details?: unknown;
  };
}
```

Some underlying operation handlers can still return a domain error object
inside `data`. Treat either `ok:false` or `data.error` as failure.

## Create a page

### 1. Resolve the store and theme

Use `lexsis_workspace` action `stores`, then `lexsis_brand` actions
`list_themes` and `get_theme`. Do not create a branded page if the selected
workspace has no valid theme.

### 2. Compile without saving

```json
{
  "name": "lexsis_pages",
  "arguments": {
    "action": "compile",
    "args": {
      "source": "<!-- section: hero --><section class=\"grid grid-cols-1 gap-8 lg:grid-cols-2\"><h1>Summer Collection</h1></section>",
      "head": { "title": "Summer Collection" },
      "theme_css": ":root { --lx-accent-color: #4b2e24; }"
    }
  }
}
```

Compilation returns structural validation plus the generated page styles:

```typescript
{
  ok: boolean;
  compile_issues: Array<{
    severity: "error" | "warning";
    check: string;
    section_id?: string;
    message: string;
  }>;
  validation_errors: string[];
  validation_warnings: string[];
  compile_id: string;
  bundle_hash: string;
  expires_at: string;
  local_preview_url: null;
  bundle_path: null;
  preview_status: {
    available: false;
    code: "DRAFT_REQUIRED";
    message: string;
  };
  section_count: number;
  styles: {
    compiled_page_css: string;
    style_manifest: {
      engine: "tailwindcss";
      compiler_version: string;
      input_version: number;
      input_sha256: string;
      candidate_count: number;
      css_bytes: number;
    };
    missing_candidates: string[];
  };
  page: object;
}
```

Fix every error and every missing Tailwind candidate before continuing.
Compilation is validation only: it does not save a page, upload a bundle, or
create a hosted preview. The short-lived compile artifact remains available for
30 minutes and can be passed directly to draft creation.

### 3. Create the draft

```json
{
  "name": "lexsis_page_create",
  "arguments": {
    "action": "create",
    "args": {
      "slug": "summer-collection",
      "source": "<!-- section: hero --><section class=\"grid grid-cols-1 gap-8 lg:grid-cols-2\"><h1>Summer Collection</h1></section>",
      "head": { "title": "Summer Collection" },
      "theme_css": ":root { --lx-accent-color: #4b2e24; }",
      "archetype": "landing",
      "theme_id": "theme-uuid",
      "inherit_header": true,
      "inherit_footer": true,
      "workspace_id": "workspace-uuid",
      "store_id": "store-uuid",
      "publish": false
    }
  }
}
```

The consolidated create action is draft-only. It rejects `publish:true`.
Draft creation stores the exact validated bundle in shared object storage.
Verify the returned `/v/{slug}?preview=1` `preview_url`, then publish through
`lexsis_live_ops`. Production responses never use `/bundle/{hash}`; that route
is reserved for explicit local development and renderer parity tests.

## Edit an existing page

### 1. Resolve authoritative edit context

Always begin with `lexsis_pages` action `edit_context`:

```json
{
  "name": "lexsis_pages",
  "arguments": {
    "action": "edit_context",
    "args": {
      "page_id": "page-uuid"
    }
  }
}
```

The response identifies:

```typescript
{
  page_id: string;
  workspace_id: string;
  page_workspace_id: string;
  store_id: string;
  store_workspace_id: string;
  selected_workspace_id: string | null;
  workspace_consistent: boolean;
  shop_domain: string;
  theme_id: string | null;
  current_version: number;
  published_version_id: string | null;
  published_version: number | null;
  has_unpublished_changes: boolean;
  status: "draft" | "published" | "archived";
  source_available: boolean;
  product_binding: Record<string, unknown> | null;
  preview_url: string | null;
  corrective_action: string | null;
}
```

`page_id` is authoritative for existing-page edits. Normally omit `store_id`;
when supplied, it is an assertion that must match the page's resolved store.
Stop if `workspace_consistent` is false or `corrective_action` is non-null.

### 2. Read the smallest useful source

- `lexsis_pages` action `section_source` — preferred for one-section changes.
- `lexsis_pages` action `source` — use for multi-section or page-wide changes.
- `lexsis_pages` action `content` — inspect the compiled representation.
- `lexsis_pages` action `inspect` — inspect section ordering and island usage.

### 3. Apply one atomic version

Use `lexsis_drafts` action `page_patch` for localized changes:

```json
{
  "name": "lexsis_drafts",
  "arguments": {
    "action": "page_patch",
    "args": {
      "page_id": "page-uuid",
      "expected_version": 6,
      "change_note": "Add trust icons after BuyBox",
      "changes": [
        {
          "operation": "insert_after_island",
          "section_id": "product-hero",
          "island_name": "BuyBox",
          "content": "<div class=\"grid grid-cols-4 gap-4\">...</div>"
        }
      ]
    }
  }
}
```

Supported patch operations:

| Operation | Required fields |
|---|---|
| `upsert_section` | `source`; optional `section_id` and `position` |
| `remove_section` | `section_id` |
| `move_section` | `section_id`, `position` |
| `update_island_props` | `section_id`, `island_name`, `props_patch`; optional `occurrence` |
| `insert_after_island` | `section_id`, `island_name`, `content`; optional `occurrence` |

Positions accept a zero-based index, `"first"`, `"last"`,
`{"before":"section-id"}`, or `{"after":"section-id"}`.

Other edit actions:

| `lexsis_drafts` action | Use it for |
|---|---|
| `page_replace` | Replace the complete source while preserving head, theme, and scripts |
| `page_update_section` | Compile and upsert exactly one source-format section |
| `page_remove_section` | Remove one section |
| `page_move_section` | Reorder one section |
| `page_update_head` | Update head, SEO, fonts, cart mode, or complete `theme_css`; source-backed theme changes recompile and atomically replace the page |
| `page_duplicate` | Create an independent draft copy |
| `page_variation` | Create an experiment-oriented page variation |

For source-backed pages, `page_update_head` detects `theme_css`, recompiles the
complete stored source, and writes through the atomic source-replacement path.
Direct backend head-only theme patching is not sufficient because it would
leave `compiled_page_css` stale.

### 4. Handle version conflicts

Pass the `current_version` returned by `edit_context` as `expected_version`.
If another edit wins first, the server returns a conflict with the new current
version. Re-read the source, reapply the intended change, and submit a new
patch. Never retry a stale patch blindly.

> **Current limitation:** `page_patch` does not yet expose an idempotency key.
> Use `expected_version` to prevent duplicate stale writes and inspect the
> current diff before retrying after a timeout. Use idempotency only on actions
> whose schema returned by `lexsis_discover` includes it.

### 5. Verify the result

Run:

1. `lexsis_pages` action `diff`
2. `lexsis_pages` action `integrity`
3. Browser QA with the calling agent at 390px, 768px, and 1280px

The MCP returns a preview URL but does not run a shared browser session.
The host agent is responsible for screenshots, computed-style inspection,
hover testing, console errors, and responsive verification.

## Published-page edits

Editing a published page creates a new non-live current version. Public
rendering continues to use `published_version_id` until a later successful
`lexsis_live_ops` action `publish` promotes the reviewed version.

Use `has_unpublished_changes` to detect when the current draft differs from the
live version. A failed republish preserves the previously published version.

## Publishing and deployment boundaries

`lexsis_live_ops` action `publish` marks the Lexsis page as published after
validation. It does not itself create or update a Shopify page.

The following are separate lifecycle concepts:

- **Draft preview** — renderer URL for an unpublished version.
- **Lexsis publish** — changes the Lexsis page status.
- **Standalone deployment** — publishes to Lexsis-hosted storefront delivery.
- **Shopify push** — creates or updates the merchant-facing Shopify page or
  redirect through a separate deployment operation.

The publish response can contain `url:null` when no public deployment URL has
been created. Continue using `preview_url` for QA in that case.

## Destructive operations

`lexsis_live_ops` requires explicit approval:

| Action | Effect |
|---|---|
| `publish` | Promote the reviewed page/version to published state |
| `unpublish` | Begin asynchronous removal from live delivery |
| `delete` | Permanently delete one or more unpublished pages |
| `rollback` | Move the page back to a selected previous version |
| `scale_winner` | Promote an experiment winner |

Unpublish a page and wait for completion before deleting it.

## Best practices

1. Resolve `edit_context` before every editing session.
2. Read and patch the smallest possible source unit.
3. Use one `page_patch` call for related changes so they produce one version.
4. Pass `expected_version`; add an idempotency key only when the selected
   action schema supports it.
5. Compile before creating and run integrity checks after editing.
6. Use Tailwind for structural and responsive styling.
7. Perform browser QA before every live operation.
8. Distinguish Lexsis publishing from Shopify deployment.

## Related

- [Page Source Contract](/pages/schema)
- [Publishing](/pages/publishing)
- [Theming](/pages/theming)
- [Styling Issues](/troubleshooting/styling-issues)
