@bettercms-ai/mcp 0.70.0 → 0.71.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.
@@ -79,6 +79,19 @@ Builds run `build:bcms` instead of `build` when `package.json` declares it. Keep
79
79
  of it and every step the build needs in: `"build": "astro check && astro build"` beside
80
80
  `"build:bcms": "astro build"`. The convert codemod adds one to a repo whose build chains a check.
81
81
 
82
+ ### A section change that is held at the write
83
+
84
+ `update_page` and `compose_pages` save the draft and answer with `holds` when a `blockJson` adds,
85
+ moves or removes a section the live page cannot show yet. Each hold has a `reason`, a `message`,
86
+ the `sections` it is about and the one `action`. Never report such a write as done:
87
+
88
+ - `CODE_FIXED_SECTIONS`: the site's code fixes this page's sections, so no publish ships the
89
+ change. The action is `componentize_sections` with `codemod: true`; after its build, publish.
90
+ - `SECTION_NEEDS_BUILD`: the build draws the page's sections from BetterCMS. Publish: the build
91
+ starts by itself, and a move or a removal needs none.
92
+ - `STRUCTURE_UNMEASURED`: nothing has measured the page. Publish, then read the publish's outcome
93
+ in `get_deploy_status`.
94
+
82
95
  ### Reading `get_deploy_status`
83
96
 
84
97
  - `release` is the newest release: `id`, `sha`, `status`, `phaseMarks`, `error`, `createdAt`.
@@ -92,6 +105,24 @@ of it and every step the build needs in: `"build": "astro check && astro build"`
92
105
  and ready on staging while production keeps the older sha, until `promote_project` runs.
93
106
  - The poll is finished only when `slot` is `current`, or when `awaitingPromote` is false and
94
107
  `productionSha` equals the sha you deployed.
108
+ - `publishes` is the newest publishes, value by value. `status` `live` means every published value
109
+ was found in the file the site serves that page from. `partial` means some were not: `summary`
110
+ counts them ("3 of 4 live · 1 held") and `notLive` lists each with its `route`, `address`,
111
+ `state`, `reason` and the one `action` that fixes it. Never tell the user a publish is live
112
+ while it reads `partial`: relay the reason and do the action, then poll again.
113
+
114
+ | `reason` | `state` | The one action |
115
+ |---|---|---|
116
+ | `NOT_STAMPED` | held | Rebuild: the built page has no element for the field and does not show it |
117
+ | `VALUE_REFUSED` | held | Bind the field to an element that can hold its value |
118
+ | `APP_DOES_NOT_READ` | held | Convert in code: make the page's code read the published field |
119
+ | `ROWS_NEED_BUILD`, `SECTION_NEEDS_BUILD`, `NEEDS_BUILD` | held | Wait for the build the publish started |
120
+ | `STRUCTURE_UNBOUND` | refused | Let BetterCMS control section order (componentize with the codemod) |
121
+ | `SECTION_MISSING` | held | The same: the served page does not render the section |
122
+ | `STYLE_NOT_PAINTABLE` | held | Run editor setup so section roots carry `sectionRootAttrs` |
123
+ | `WINDOW_NOT_OPEN` | held | Nothing: it goes live when its window opens |
124
+ | `ROUTE_NOT_OWNED` | held | Change one of the two page paths that share the URL |
125
+ | `APP_UNREACHABLE`, `NOT_CHECKED`, `EDGE_PENDING`, `IMAGE_UNAVAILABLE`, `STRUCTURE_UNMEASURED` | unverified | Poll again; publish again if it stays |
95
126
 
96
127
  ### Deploy to Vercel or Netlify
97
128
 
@@ -109,8 +109,8 @@ Value (`set_page_content`):
109
109
  "hero_eyebrow": "Freight visibility for mid-size shippers",
110
110
  "hero_title": "Know where every container is before your customer asks.",
111
111
  "hero_lede": "Live ETAs from 140 carriers, delays flagged before they cost you, and one shared view for ops and sales.",
112
- "hero_primary": { "label": "Book a demo", "href": "/demo", "variant": "primary", "arrow": true },
113
- "hero_secondary": { "label": "Start free trial", "href": "https://app.kestrelfreight.com/signup", "variant": "secondary" },
112
+ "hero_primary": { "label": "Book a demo", "href": "/demo", "arrow": true },
113
+ "hero_secondary": { "label": "Start free trial", "href": "https://app.kestrelfreight.com/signup" },
114
114
  "hero_image": {
115
115
  "url": "/img/hero-harbor-2560.jpg",
116
116
  "altText": "Container cranes over a quiet harbor at dusk",
@@ -149,6 +149,8 @@ Bound template (classes unchanged, shortened here):
149
149
  - The image binding sits on the `<img>`, not the `<picture>`. The alt text travels in the image
150
150
  value (`altText`): a publish writes it to the bound element's `alt`. When `get_conversion_brief`
151
151
  lists a separate alt path, declare that path in `data-bcms-props` with kind `text`.
152
+ - Neither button value names a `variant`: the anchors keep the site's own `btn-primary` and
153
+ `btn-ghost`, and the release reads those two looks into the project's Button family.
152
154
  - An `href` is kind `url`, never `text`. The label gets its own `<span>` so a save does not erase
153
155
  the arrow; the arrow is drawn by `BcmsButton` ([components.md](components.md)), so remove the
154
156
  hand-written `<svg>` once the button renders through it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bettercms-ai/mcp",
3
- "version": "0.70.0",
3
+ "version": "0.71.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": {
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@bettercms-ai/device-auth": "^0.2.0",
35
- "@bettercms-ai/sdk": "^1.28.0",
35
+ "@bettercms-ai/sdk": "^1.29.0",
36
36
  "@modelcontextprotocol/sdk": "^1.30.0",
37
37
  "zod": "^4.3.6"
38
38
  },