@bettercms-ai/mcp 0.65.1 → 0.66.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -81,6 +81,10 @@ These hold on every task. The reference in brackets has the detail and the codes
81
81
  CMS on a bound leaf and an edit shows in preview and after publish.
82
82
  12. **Bulk work runs as code, not as a chain of tool calls.** Propose the mapping and dry-run it
83
83
  before a high-volume write; use the MCP for state, targeted fixes and reports.
84
+ 13. **A build makes a site live, not editable.** It brings in SEO and meta, media, the brand and
85
+ the models `bcms-content.json` declares. Pages, collections, forms, bindings and components
86
+ are `editor_setup`'s: run it after an import or a rebuild (`get_deploy_status` `editorSetup`
87
+ `never` or `stale`). [getting-started.md]
84
88
 
85
89
  ## What you do, and what only the owner does
86
90
 
@@ -30,7 +30,7 @@ Inside a section, pick the smallest shape that holds the children:
30
30
 
31
31
  Never let a component contain itself, directly or through a child.
32
32
 
33
- ## 2. The componentize lane (a site whose pages were derived at import)
33
+ ## 2. The componentize lane (a site whose pages `editor_setup` derived)
34
34
 
35
35
  1. `get_componentize_plan { summary: true }` first (no values; the full plan is hundreds of KB,
36
36
  and `paged: true` reads it 10 pages at a time). It creates nothing and is computed live from
@@ -60,8 +60,10 @@ Never let a component contain itself, directly or through a child.
60
60
  `ALREADY_COMPONENTIZED`.
61
61
  5. `publish_component` for each, then publish the pages. An unpublished component renders
62
62
  nothing on the live site.
63
- 6. In the repo, run the codemod with `--componentize` and a `--receipt` file, commit and push the
64
- files it wrote, and hand that receipt verbatim to `submit_componentize_receipt`. It records
63
+ 6. The repository half. With no checkout, `componentize_sections { digest, codemod: true }` runs
64
+ the section-order codemod on the repo's own Actions (`skipped` means there is no repo it may
65
+ commit to). In a checkout, run the codemod with `--componentize` and a `--receipt` file, commit
66
+ and push the files it wrote, and hand that receipt verbatim to `submit_componentize_receipt`. It records
65
67
  each extracted section as the source of the component with the same slug, so no
66
68
  `set_component_source` per component is needed. Deploy.
67
69
  7. Output validation, from step 3 of §6.
@@ -149,8 +149,15 @@ A code-built site ships only what its templates draw, whatever the page's `block
149
149
  editor reaches the live site only when the template loops over the page's blocks in order and
150
150
  each section root carries its block id as `data-bcms-block`. The codemod's `--componentize` pass
151
151
  generates `src/lib/bcms-sections.ts` for the loop and adds those attributes. Until it ships, the
152
- editor locks Add section and reordering on that route, and `submit_conversion_receipt` keeps
152
+ editor still adds, moves, swaps and removes sections (saved, and drawn on the canvas at once),
153
+ tells the author that publishing leaves the live order to the site's code, and its "Let BetterCMS
154
+ control section order" button commits that same codemod to the connected repository. `submit_conversion_receipt` keeps
153
155
  `complete: false` with one `SECTIONS_UNSTAMPED` row per route.
156
+ - **The order is measured, not assumed.** A release reads the stamped section roots in document order:
157
+ a build that draws them in the CMS order (`ordered: true` on the binding report's structure row)
158
+ owns nothing, whatever sections it has no code for; one that draws them in its own order
159
+ (`ordered: false`) — a template that hardcodes its bands and stamps each with a snapshot id — is
160
+ code-ordered as soon as the CMS order moves. Stamp ids only from the loop, never as literals.
154
161
  - **No chrome placements on a page.** A nav, footer or modal placement the site's layout draws
155
162
  renders nowhere, and the editor locks its outline row and skips it when it moves the sections
156
163
  around it. Remove it.
@@ -232,7 +239,7 @@ Components are organised into `component_groups` (the folders of the Components
232
239
  `Sections/<Page title>` (`Sections/<Page title>/<pattern>` for a template), and a dashboard or
233
240
  studio run leaves it unfiled. The receipt's `components.groups` lists the Groups it filed into.
234
241
  A reused component keeps its Group.
235
- - Sections a release imports are filed the same way, after the release.
242
+ - Sections `editor_setup` componentizes are filed the same way.
236
243
  - `componentize_sections` reuses a component by identity and slug, never by family, so a
237
244
  hand-built `Hero / Split` is not picked for a derived hero band. Run `dryRun: true` and read
238
245
  `components.wouldDuplicate`: each id is an existing same-family component the run would sit a
@@ -29,7 +29,9 @@ A page is `singleton` (one page and its own content: home, about, a legal page)
29
29
  Choose by repetition: a shape that repeats per item is a collection; a one-off is a singleton,
30
30
  even when it lists items, because the list page reads the collection. A dynamic page is its
31
31
  collection: the model and its entries both point at the page (`content_models.page_id`,
32
- `content_entries.page_id`), so never create a separate page per entry.
32
+ `content_entries.page_id`), so never create a separate page per entry. A dynamic page made with
33
+ `create_page` takes its route pattern and its collection through `update_page { dynamic:
34
+ { previewPath, modelId } }`: `/blog/{slug}`, and an existing collection with no page yet.
33
35
 
34
36
  | Source pattern | BetterCMS destination |
35
37
  |---|---|
@@ -69,6 +69,7 @@ and add the new result. Update the file as each row moves, so a reset loses at m
69
69
 
70
70
  | # | Step | Reference |
71
71
  |---|---|---|
72
+ | 0 | Editor setup: `editor_setup { check: true }` reads `ready` for the live build (run `editor_setup` when it does not) | [getting-started.md](getting-started.md) |
72
73
  | 1 | Routing and data shape: page / collection / entry classification and folders; keep public URLs | [content-modeling.md](content-modeling.md) |
73
74
  | 2 | Sections and reuse: every band a section; dedupe compatible patterns into variants and overrides; nav and footer as globals (`get_componentize_plan`, `componentize_sections` on a components project) | [components.md](components.md), [componentize.md](componentize.md) |
74
75
  | 3 | Editor contract: field types, labels, validation, Portable Text accept lists, nested groups | [portable-text.md](portable-text.md) |
@@ -166,6 +166,7 @@ Rules:
166
166
  | List, read, create, update, delete forms | MCP: `list_forms`, `get_form`, `create_form`, `update_form`, `delete_form` |
167
167
  | Read and delete submissions | MCP: `list_form_submissions`, `delete_form_submission` |
168
168
  | Publish | MCP: `publish_form`. Unpublish: dashboard Forms tab |
169
+ | Mark a derived form as not a form (a search box, a widget), or restore it | MCP: `update_form { ignored: true }` / `{ ignored: false }` |
169
170
  | Integrations (Google Sheets, Slack, webhook, email, HubSpot, Salesforce) | Dashboard |
170
171
  | Turnstile on/off, honeypot field name, notification emails | MCP: `create_form` / `update_form` (`turnstileEnabled`, `honeypotField`, `notifyEmails`). The Turnstile secret key: dashboard only; sending `turnstileSecretKey` through the API is refused with 403 `FORM_SECRET_DASHBOARD_ONLY` |
171
172
 
@@ -62,9 +62,13 @@ Everything else has a default. Do not ask about it; decide, then report what you
62
62
 
63
63
  ### Phase 3 — Convert and componentize
64
64
 
65
- Check: `submit_conversion_receipt` returned complete and `get_componentize_plan` proposes
66
- nothing more.
65
+ Check: `editor_setup { check: true }` reads `ready`, `submit_conversion_receipt` returned complete
66
+ and `get_componentize_plan` proposes nothing more.
67
67
 
68
+ 0. A build brings in only SEO and meta, media, the brand and the models `bcms-content.json`
69
+ declares. Pages, collections, forms, bindings and components come from `editor_setup`: run it
70
+ and poll `editor_setup { check: true }` until `ready` before anything below. Run it again
71
+ whenever `get_deploy_status` reports `editorSetup` `stale`.
68
72
  1. Explore the repo (the "Read when" column of SKILL.md's reference table names the signals) and
69
73
  read `get_site_composition`.
70
74
  2. If `list_env_vars` reports `missing` variables, run `npx @bettercms-ai/cli@latest env push`
@@ -75,8 +79,8 @@ nothing more.
75
79
  3. Run the `convert_site` prompt end to end. Its finish line is the only one; repeat until the
76
80
  receipt is complete, never stop at a partial one.
77
81
  4. When the answer was components: `get_componentize_plan`, confirm it with the user, apply it
78
- with `componentize_sections`, then the repository half and `submit_componentize_receipt`
79
- ([componentize.md](componentize.md)).
82
+ with `componentize_sections`, then the repository half (`componentize_sections { codemod: true }`
83
+ when there is no checkout) and `submit_componentize_receipt` ([componentize.md](componentize.md)).
80
84
  5. Work the rest through [finish-site.md](finish-site.md) (gap ledger, repair order, proof loop).
81
85
 
82
86
  ### Phase 4 — Publish and verify
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bettercms-ai/mcp",
3
- "version": "0.65.1",
3
+ "version": "0.66.0",
4
4
  "type": "module",
5
5
  "description": "BetterCMS MCP server — schema, content, forms + components authoring tools over the Management API, authed via OAuth device-code.",
6
6
  "bin": {