@bettercms-ai/mcp 0.59.2 → 0.61.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.
package/dist/index.js CHANGED
@@ -2268,15 +2268,19 @@ var uiObject = z.object({
2268
2268
  collapsed: z.boolean().optional().describe("start this panel collapsed. Use it for long optional sections."),
2269
2269
  preview: z.object({
2270
2270
  title: z.string().min(1).optional().describe("CHILD KEY whose value titles a collapsed row"),
2271
+ subtitle: z.string().min(1).optional().describe("CHILD KEY whose value is the row's second line (e.g. 'level' \u2192 'Heading \xB7 h2')"),
2271
2272
  media: z.string().min(1).optional().describe("CHILD KEY whose value is the row's thumbnail (image/file/url all work)")
2272
2273
  }).optional().describe(
2273
- "how ONE ITEM summarises itself when collapsed. Both slots name a CHILD KEY of THIS field/prop \u2014 not a value, not a dotted path. Without it a repeater of testimonials reads 'Item 1, Item 2, Item 3'; with {title:'author', media:'avatar'} it reads the names with their faces."
2274
+ "how ONE ITEM summarises itself when collapsed. Every slot names a CHILD KEY of THIS field/prop \u2014 not a value, not a dotted path. Without it a repeater of testimonials reads 'Item 1, Item 2, Item 3'; with {title:'author', media:'avatar'} it reads the names with their faces."
2274
2275
  ),
2275
2276
  layout: z.enum(["list", "grid"]).optional().describe(
2276
2277
  "how the ITEMS are arranged. Omit (\u2261 'list') for rows of text; 'grid' for items whose thumbnail is the thing you scan \u2014 a gallery, a logo wall, a team. Same placement rule as `preview`."
2277
2278
  ),
2278
2279
  reorderable: z.boolean().optional().describe(
2279
2280
  "omit (\u2261 true) unless the order is PART OF THE MEANING. `false` LOCKS the list \u2014 a 'three steps' band that must stay three steps in that order, a nav whose order is semantic, a timeline. Valid only where there is a list to lock."
2281
+ ),
2282
+ control: z.enum(["segmented", "slider"]).optional().describe(
2283
+ "editor control for a LEAF. Omit for the default. 'segmented' on a select with a few short options (alignment, theme, size); 'slider' on a number that has config.min < config.max (opacity, columns). Anything else is refused with the rule named."
2280
2284
  )
2281
2285
  });
2282
2286
  var fieldShape = {
@@ -2976,6 +2980,7 @@ function buildToolDefs(deps) {
2976
2980
  category: componentCategory.optional().describe("defaults to 'custom'"),
2977
2981
  group: z.string().min(1).max(100).optional().describe("the folder editors see in the dashboard's Components tab, addressed by NAME (e.g. 'Sections', 'Navigation', 'Forms'). Resolved against this project's Groups and CREATED when missing, so a whole-site run can file everything without looking any id up first. Separate from `category`, which is the picker tab."),
2978
2982
  sectionType: sectionType.optional(),
2983
+ variantOf: z.string().min(1).max(255).optional().describe("id/slug of the component this is a VARIANT of: joins or starts its family (422 if its shared inputs are missing)"),
2979
2984
  projectId: z.string().nullable().optional().describe("owning project id; null creates a workspace-wide global component"),
2980
2985
  allowedOn: allowedOn.optional(),
2981
2986
  description: z.string().optional(),
@@ -2992,6 +2997,7 @@ function buildToolDefs(deps) {
2992
2997
  sectionType: sectionType.nullable().optional().describe(
2993
2998
  "null demotes it to an ordinary component \u2014 it disappears from the 'Add a section' picker, and instances already placed keep rendering but lose their section chrome and variant switcher"
2994
2999
  ),
3000
+ variantOf: z.string().min(1).max(255).optional().describe("see create_component"),
2995
3001
  allowedOn: allowedOn.optional().describe("REPLACES the placement allowlist"),
2996
3002
  description: z.string().optional(),
2997
3003
  blockJson: z.array(blockObject).optional().describe("REPLACES the block tree"),
@@ -4718,7 +4724,7 @@ ${notes.join("\n")}` : summary, created);
4718
4724
  name: "create_component",
4719
4725
  config: {
4720
4726
  title: "Create a reusable component",
4721
- description: "Create a reusable component from a blockJson tree. THIS IS ALSO HOW A PAGE GETS ITS SECTIONS: set `sectionType` (e.g. 'Hero') and the component becomes a placeable section, selectable in the editor's 'Add a section' picker. Components sharing a `sectionType` are its layout VARIANTS \u2014 one Hero with a 'Centered' and a 'Two-column' variant, same prop keys, so a swap keeps the content. CONFIRM the structure with the user first. blockJson is an array of blocks \u2014 the same set create_page accepts (heading, text/richtext, image, button, spacer, video, columns, section, slider, tabs, navbar, footer, form, component, collection), NOT a narrower one; `section` nests child blocks in props.children and `columns` in props.columns. `props` declares overridable fields. Returns the new id \u2014 render with `<BcmsBlocks>`. Always lands as a DRAFT \u2014 call publish_component to put it on the live site; until then it renders as NOTHING there, with no error. " + SECTION_DOCTRINE,
4727
+ description: "Create a reusable component from a blockJson tree. THIS IS ALSO HOW A PAGE GETS ITS SECTIONS: set `sectionType` (e.g. 'Hero') and the component becomes a placeable section, selectable in the editor's 'Add a section' picker. Components sharing a `sectionType` are its layout VARIANTS \u2014 one Hero with a 'Centered' and a 'Two-column' variant, same prop keys, so a swap keeps the content. CONFIRM the structure with the user first. blockJson is an array of blocks \u2014 the same set create_page accepts (heading, text/richtext, image, button, spacer, video, columns, section, slider, tabs, navbar, footer, form, component, collection), NOT a narrower one; `section` nests child blocks in props.children and `columns` in props.columns. `props` declares overridable fields. Returns the new id \u2014 render with `<BcmsBlocks>`. Always lands as a DRAFT \u2014 call publish_component to put it on the live site; until then it renders as NOTHING there, with no error. Buttons auto-join the project's Button family; section buttons link to its looks." + SECTION_DOCTRINE,
4722
4728
  inputSchema: createComponentInput.shape
4723
4729
  },
4724
4730
  handler: guard(
@@ -5033,7 +5039,7 @@ ${lines.join("\n")}`, found);
5033
5039
  name: "duplicate_component",
5034
5040
  config: {
5035
5041
  title: "Add a look to a component family",
5036
- description: "Add a new LOOK to a component's variant family (\"+ New variant\"), e.g. a Ghost button the site does not have: copy the component into the same family and folder under `name`, with a new unique slug. `preset` restyles its button block: primary / secondary fill it with the brand kit's primary / accent colour; ghost drops the fill and border, keeps the padding and colours the text with the old fill; link is a ghost with no padding. Omit `preset` for a plain copy. outline drops the fill, keeps the padding and draws a border all round in the old fill's colour, which becomes the text colour. A look the style vocabulary cannot express is refused with 422 and the reason \u2014 relay it, never approximate it with update_component. 409 means that name is already a look in the family. When the family's contract is published and this connection may publish, the new look is published at once and is choosable in every section's style select; otherwise it is a draft: call publish_component.",
5042
+ description: "Add a new LOOK to a component's variant family (\"+ New variant\"), e.g. a Ghost button the site does not have: copy the component into the same family and folder under `name`, with a new unique slug. `preset` restyles its button block: primary / secondary fill it with the brand kit's primary / accent colour; ghost drops the fill and border, keeps the padding and colours the text with the old fill; link is a ghost with no padding. Omit `preset` for a plain copy. Starts a family if none. outline drops the fill, keeps the padding and draws a border all round in the old fill's colour, which becomes the text colour. A look the style vocabulary cannot express is refused with 422 and the reason \u2014 relay it, never approximate it with update_component. 409 means that name is already a look in the family. When the family's contract is published and this connection may publish, the new look is published at once and is choosable in every section's style select; otherwise it is a draft: call publish_component.",
5037
5043
  inputSchema: duplicateComponentInput.shape
5038
5044
  },
5039
5045
  handler: guard(
@@ -5896,8 +5902,8 @@ delivered value \u2014 they change editor chrome only.
5896
5902
  BARE KEY, and the key namespace is FLAT across the model (\xA7 the duplicate-key rule), so the
5897
5903
  key you reference must exist.
5898
5904
  - **\`ui.collapsed\`** \u2014 start a nesting field's panel closed. For long optional sections.
5899
- - **\`ui.preview\`** \u2014 how ONE ITEM of a nesting field summarises itself when collapsed. Both
5900
- slots name a **CHILD FIELD KEY of that field** \u2014 not a value, not a dotted path.
5905
+ - **\`ui.preview\`** \u2014 how ONE ITEM of a nesting field summarises itself when collapsed. Each
5906
+ slot (\`title\`, \`subtitle\`, \`media\`) names a **CHILD FIELD KEY of that field** \u2014 not a value, not a dotted path.
5901
5907
  Without it a repeater of ten testimonials reads "Item 1 \u2026 Item 10" and the author has to open
5902
5908
  each one to find the one they meant. \`media\` may point at an \`image\`, \`file\` or url-ish
5903
5909
  \`text\` child; the type is not constrained.
@@ -5909,19 +5915,25 @@ delivered value \u2014 they change editor chrome only.
5909
5915
  in that order, a nav whose order is semantic, a timeline. Locking a list nobody should reorder
5910
5916
  is the declaration there was previously no way to make; locking one out of tidiness takes a
5911
5917
  capability away from the author, so do not set it "just in case".
5918
+ - **\`ui.control\`** \u2014 which control a LEAF edits with; omit it for the default. \`'segmented'\` on a
5919
+ \`select\` with a few short options (alignment, theme, size: one click instead of a dropdown);
5920
+ \`'slider'\` on a \`number\` with \`config.min\` < \`config.max\` (opacity, columns). Anywhere else it
5921
+ is refused with the rule named.
5912
5922
 
5913
- **Five refusals, all deliberate, all 400 with the fix in the message.**
5923
+ **Six refusals, all deliberate, all 400 with the fix in the message.**
5914
5924
  1. An unknown key inside \`ui\` is REJECTED, not stripped. \`ui\` is a strict object precisely so
5915
5925
  that a typo is a refusal you can read instead of a 200 with your declaration gone.
5916
5926
  2. \`ui.preview\` on a LEAF field is refused \u2014 it summarises an item, and a leaf has no items.
5917
5927
  Valid on \`group\`, \`repeater\`, an \`array\` with \`config.zones\`, or \`modular\`.
5918
- 3. \`preview.title\` / \`preview.media\` naming a key that is not a child of that field is refused,
5928
+ 3. \`preview.title\` / \`preview.subtitle\` / \`preview.media\` naming a key that is not a child of that field is refused,
5919
5929
  and the error lists the valid child keys.
5920
5930
  4. \`ui.layout\` follows the same rule as \`preview\`: nesting fields only. A leaf has no items
5921
5931
  to arrange.
5922
5932
  5. \`ui.reorderable\` is STRICTER \u2014 it needs a LIST, not merely children. Valid on \`repeater\`,
5923
5933
  an \`array\` with \`config.zones.repeatable\`, or \`modular\`. A \`group\` (and a non-repeatable
5924
5934
  zone) holds exactly ONE item, so there is nothing there to drag and the write is refused.
5935
+ 6. \`ui.control\` outside its fit is refused: \`segmented\` needs a \`select\`, \`slider\` a \`number\`
5936
+ whose \`config.min\` and \`config.max\` are both set with min < max.
5925
5937
 
5926
5938
  **The same \`ui\` rides on COMPONENT PROPS.** \`create_component\` / \`update_component\` take it on
5927
5939
  each entry of \`props\`, with the placement rules the prop vocabulary implies: \`preview\` and
@@ -6583,9 +6595,10 @@ Read bettercms://playbook/schema section 14 first \u2014 it has the exact prop s
6583
6595
  **What you are setting** (all of these ride on any field, on create_content_model / create_page /
6584
6596
  add_field / add_page_field; none of them affect delivery):
6585
6597
  ui.collapsed start a nesting field's panel closed
6586
- ui.preview {title,media} which CHILD FIELD KEY titles a collapsed row, and which is its thumb
6598
+ ui.preview {title,subtitle,media} which CHILD FIELD KEY titles a collapsed row, its second line, its thumb
6587
6599
  ui.layout 'list'|'grid'|'table' how its items are arranged; table is for repeatable row schemas; omit for list
6588
6600
  ui.reorderable omit (= true) unless the ORDER IS THE MEANING; false LOCKS the list
6601
+ ui.control 'segmented'|'slider' a LEAF's control: segmented on a select, slider on a number with config.min < max
6589
6602
  helpText one line under the field: what to WRITE here
6590
6603
  showIf hide a field until another field has a value
6591
6604