← BrightSiteCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to BrightSite
Snapshot Sep 30, 2026 · 22:57 UTC · version 1.1.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "staging-redesign",
"description": "Build a BrightSite redesign or large change safely on a staging site, preview it, then promote it live in one atomic flip — instead of editing the live site directly. Use when the user wants a \"staging site,\" \"redesign safely,\" \"build a new version without breaking the live site,\" \"preview before it goes live,\" \"rebuild the homepage,\" \"flip the whole site at once,\" \"a safe place to work,\" or is doing a full visual rebuild (new fonts/layout/multiple pages) they don't want visitors to see until it's ready. For per-entity staged edits on the live site (a single page's unpublished draft), the normal `*_staged` + `publish_page` flow is enough — use this skill only when you want a full isolated copy.",
"included_files": [],
"skill_md_contents": "---\nname: staging-redesign\ndescription: Build a BrightSite redesign or large change safely on a staging site, preview it, then promote it live in one atomic flip — instead of editing the live site directly. Use when the user wants a \"staging site,\" \"redesign safely,\" \"build a new version without breaking the live site,\" \"preview before it goes live,\" \"rebuild the homepage,\" \"flip the whole site at once,\" \"a safe place to work,\" or is doing a full visual rebuild (new fonts/layout/multiple pages) they don't want visitors to see until it's ready. For per-entity staged edits on the live site (a single page's unpublished draft), the normal `*_staged` + `publish_page` flow is enough — use this skill only when you want a full isolated copy.\n---\n\n# Build a Redesign on a Staging Site, Then Promote\n\nA **staging site** is a full, independent, editable copy of the live site's content\n(pages, layouts, components, forms, blog, media, global CSS/JS, Tailwind config, site\nidentity, redirects) that lives under the same account. You build the redesign on it\ninvisibly, preview it at a gated subdomain, then **promote** it — one atomic flip that\nmakes the staging content live and archives the old live site (restorable). Account-level\ndata (custom domain, analytics, form submissions, team, billing, tracking IDs) is shared\nand never touched by a promote.\n\nUse this instead of editing the live site directly whenever the change is big enough that\nyou don't want visitors seeing a half-finished state, or you need to flip several entities\n(global code + a layout swap + N pages) at the same moment.\n\n## When to use this vs. the normal staged-fields flow\n\n| Situation | Use |\n|---|---|\n| One page's copy tweak, a new draft page, a blog post | Normal flow: `update_page` writes `*_staged`, `publish_page` ships it. Live stays as-is until you publish. |\n| Full redesign, new global fonts/layout, multi-page rebuild, \"flip it all at once\", \"let me preview the whole thing first\" | **This skill** — a staging site. |\n\nThe staged-fields flow only stages *content* fields (`heex_staged`, `css_staged`, …).\nStructural fields — `layout_id`, `slug`, `status`, `is_home_page`, `meta_*`, and anything\n`update_site_identity` sets — take effect on the **live** site immediately, with no staged\nvariant. A staging site stages *everything*, which is why it's the right tool for a rebuild.\n\n## Key mechanic: the `site` param\n\nEvery content tool (`create_page`, `update_page`, `update_layout`, `update_global_code`,\n`create_component`, `request_upload`, `update_site_identity`, `list_pages`, `get_page`, …)\ntakes an optional **`site`** param:\n\n- **omitted** or `\"live\"` → the live site (default, backwards-compatible).\n- `\"staging\"` → the account's staging site.\n- an explicit **site ID** (from `list_staging_sites`) → that specific site, as long as it's\n **active** (`live` or `staging`). Archived sites (rollback snapshots) are rejected —\n they're immutable history; `restore_staging_site` first if you need to edit one.\n\nAuthorization is still by `account_id` — you must be a member of the org, and the target\nsite must belong to it. Passing a staging site ID as `account_id` does **not** work (it's a\nsite, not an account); always pass `account_id` = the org and select the site with `site`.\n\n## Workflow\n\n### 1. Create the staging site\n\n```\nmcp__brightsite__create_staging_site { account_id: \"<ORG_ID>\" }\n → { id, name, slug, type: \"staging\", preview_url, ... }\n```\n\nThis clones the live site synchronously (content + media). It is **plan-gated** — it fails\nwith a \"plan\" / \"limit\" message if staging isn't on the account's plan or a staging site\nalready exists. If one already exists, either reuse it or `discard_staging_site` first.\n\nKeep the returned `id` and `preview_url`. You can also fetch them any time with\n`mcp__brightsite__list_staging_sites` or `mcp__brightsite__get_staging_status`.\n\n### 2. Author into staging — pass `site: \"staging\"` on every write\n\nBuild the redesign exactly as you normally would, but add `site: \"staging\"` (or the site\nID) to each call. The live site is untouched.\n\n```\nmcp__brightsite__update_global_code { account_id, site: \"staging\", css_staged: \"...\", tailwind_config_staged: \"...\" }\nmcp__brightsite__update_layout { account_id, site: \"staging\", id: \"<layout_id>\", heex_staged: \"...\" }\nmcp__brightsite__create_page { account_id, site: \"staging\", title, slug, heex, params_schema, ... }\nmcp__brightsite__request_upload { account_id, site: \"staging\", file_name, content_type } # media lands on staging\n```\n\nIf you're building editable content, load the **visual-editor-authoring** skill and apply\nit — `site: \"staging\"` composes with everything there.\n\n> Reads honor `site` too. `list_pages`/`get_page` with `site: \"staging\"` show the staging\n> copy; without it, they show live. Use this to diff-by-eye or verify your writes landed.\n\n### 3. Preview before promoting\n\nThe staging site is served at its own gated subdomain — the `preview_url` returned by\n`create_staging_site` / `list_staging_sites`. Open it (or screenshot it) and confirm the\nredesign looks right. Tracking (GA/GTM/Pixel) is suppressed on staging previews, so you\nwon't pollute analytics.\n\n### 4. Review the diff\n\n```\nmcp__brightsite__staging_diff { account_id: \"<ORG_ID>\" }\n → { has_changes, totals: {added, modified, removed}, by_type, drift }\n```\n\n`drift` = live items that were edited *after* the staging copy was made — a promote would\noverwrite them with the staging version. If `drift` is non-empty and you didn't intend it,\nreconcile before promoting (re-apply that live edit on staging, or accept the overwrite).\n\n### 5. Promote (atomic flip)\n\n```\nmcp__brightsite__promote_staging { account_id: \"<ORG_ID>\" }\n```\n\nRuns in the **background**: it validates the staging content and takes a full backup of the\ncurrent live site first, then flips `live_site_id`. It returns immediately with\n`status: \"promoting\"`. **Poll `get_staging_status`** until the staging site is gone and the\nlive site is the former staging site.\n\nThe previously-live site is archived and restorable:\n\n```\nmcp__brightsite__restore_staging_site { account_id } # undo the last promotion\nmcp__brightsite__restore_staging_site { account_id, site_id: \"<archived_id>\" } # restore a specific archived site\n```\n\n### 6. (Optional) Discard instead of promoting\n\nIf the redesign is abandoned:\n\n```\nmcp__brightsite__discard_staging_site { account_id } # permanently deletes staging content + media, frees the slot\n```\n\n## Anti-patterns to avoid\n\n- **Passing the staging site ID as `account_id`.** It's a site, not an account —\n authorization is by org. Always pass `account_id` = the org and select the site with the\n `site` param. (`account_id: \"<staging_site_id>\"` returns \"Access denied\".)\n- **Forgetting `site: \"staging\"` on a write during a redesign.** The call silently targets\n the LIVE site (that's the default). If a change you meant for staging shows up in\n `staging_diff` as live `drift`, you wrote to the wrong site — reverse it and redo with\n `site: \"staging\"`.\n- **Using a staging site for a one-line copy fix.** Overkill. Use `update_page` +\n `publish_page` on the live site instead.\n- **Promoting without previewing.** Always open the `preview_url` (or screenshot it) and\n run `staging_diff` first — a promote flips the public site.\n- **Assuming promote is instant.** It's backgrounded (it backs up live first). Poll\n `get_staging_status` to confirm; don't report \"done\" off the immediate `\"promoting\"`.\n- **Expecting analytics/form submissions/tracking IDs to move.** They're account-level and\n shared — a promote never touches them. Only site content moves.\n\n## MCP tools used\n\n- `mcp__brightsite__create_staging_site` — clone live → new staging site (plan-gated, sync).\n- `mcp__brightsite__list_staging_sites` / `mcp__brightsite__get_staging_status` — find the\n staging site ID + `preview_url`; check whether one exists.\n- `mcp__brightsite__staging_diff` — added/modified/removed counts + `drift` vs. live.\n- `mcp__brightsite__promote_staging` — flip staging → live (background; poll to confirm).\n- `mcp__brightsite__restore_staging_site` — undo a promotion / restore an archived site.\n- `mcp__brightsite__discard_staging_site` — delete the staging site and its content.\n- Every content tool (`create_page`, `update_page`, `update_layout`, `update_global_code`,\n `create_component`, `update_component`, `request_upload`, `update_site_identity`, …) with\n the optional `site` param to target `\"staging\"` (or a site ID) instead of live.\n"
}SHA-256: 6f176ec5a4367bfbb5f5fd0a8845e278b2d59ad0e0e81b6b8875d4925e958199