@bettercms-ai/mcp 0.73.0 → 0.73.1
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
|
@@ -2989,6 +2989,7 @@ var PARAM_TEXT = {
|
|
|
2989
2989
|
recommendedMax: "a SOFT limit (characters, items or value): the editor warns past it, never refuses",
|
|
2990
2990
|
openMode: "object/array/group/repeater: how the value (or each row) opens: 'inline', 'drill', 'popover' or 'dialog'",
|
|
2991
2991
|
fromBuiltin: "a builtin:* id from list_components: copies it into the project; fields you send win",
|
|
2992
|
+
componentPreview: "how ONE instance reads as a ROW in a parent's slot list (a /kit schema's document-level `preview`): {title?, subtitle?, media?} each a TOP-LEVEL prop key (422 preview_key_unknown otherwise), fallback? a literal row label (\u2264120), icon? a dock icon name. null clears it",
|
|
2992
2993
|
describes: "for editors: what it is and holds; omitted: written for you",
|
|
2993
2994
|
runtimeBundle: "instead of pageId: the server-app bundle cleanup",
|
|
2994
2995
|
pageRef: "page id or path ('/de/about'); a bare slug only when one page has it",
|
|
@@ -3034,7 +3035,7 @@ var DETACHED_COPY_NOTE = "{overrides?}: a rich-text embed's separate-copy `field
|
|
|
3034
3035
|
var UNPROPPED_COPY_NOTE = "A `warnings` entry UNPROPPED_COPY names copy no prop targets, which nobody can edit: add a prop with a `target` for each leaf it lists.";
|
|
3035
3036
|
var UPDATE_PAGE_IF_MATCH_NOTE = "get_page's `optimisticVersion`: the write applies only at that version, and a 409 means the page changed since, so read it again. Send it whenever you pass blockJson, which REPLACES the whole composition.";
|
|
3036
3037
|
var SLOT_MULTIPLE_NOTE = "'slot' with config.multiple holds a list [{componentId, overrides?}] (config.maxItems, default 12, at most 50): target.path 'props.children' on a section. V2 slots, 'table' mode 'types': playbook \xA75.";
|
|
3037
|
-
var PROP_V2_NOTE = "Props take the fields' V2 keys (\xA714): 'object' = ONE {child: value} from config.fields, \u226410 levels (field_depth_exceeded); datetime|slug|email|phone|json|location|tags|rating|code|reference|multi-reference as that field (a reference names contentModelId, or polymorphic + allowedModelSlugs; page reads hydrate its entries); helpMore, advanced, recommendedMax, openMode, config.scale, ui.layout rows|chips|gallery, ui.preview.fallback, showIf notEmpty|empty.";
|
|
3038
|
+
var PROP_V2_NOTE = "Props take the fields' V2 keys (\xA714): 'object' = ONE {child: value} from config.fields, \u226410 levels (field_depth_exceeded); datetime|slug|email|phone|json|location|tags|rating|code|reference|multi-reference as that field (a reference names contentModelId, or polymorphic + allowedModelSlugs; page reads hydrate its entries); helpMore, advanced, recommendedMax, openMode, config.scale, ui.layout rows|chips|gallery, ui.preview.fallback, showIf notEmpty|empty. Send helpText: null for a prop whose /kit schema has no description (omitted, the platform writes one).";
|
|
3038
3039
|
var LAYOUT_LOCK_NOTE = "A Global field with `overridable:false` + `lockReason` (add-field `field`, update-field `patch`) refuses page overrides (LAYOUT_FIELD_NOT_OVERRIDABLE); get_layout scope page lists stored ones as `shadowed`.";
|
|
3039
3040
|
|
|
3040
3041
|
// src/entry-query.ts
|
|
@@ -3268,10 +3269,10 @@ var propUiObject = uiObject.extend({
|
|
|
3268
3269
|
}).optional().describe("the group this prop (or sub-field) sits in. The FIRST member defines {id, label, kind?, icon?, collapsed?, description?, columns?, collapsible?, layout?, order?}; later ones send only {id}."),
|
|
3269
3270
|
tab: z.strictObject({
|
|
3270
3271
|
id: z.string().min(1).max(40),
|
|
3271
|
-
label: z.string().min(1).max(
|
|
3272
|
+
label: z.string().min(1).max(40).optional(),
|
|
3272
3273
|
icon: uiObject.shape.icon,
|
|
3273
3274
|
order: z.number().int().min(0).max(99).optional()
|
|
3274
|
-
}).optional().describe("TOP-LEVEL props only: the dock tab this prop sits in (a V2 kit schema `groups` entry: Content, Design, \u2026). The FIRST prop in a tab defines {id, label, icon?, order?}; later ones send only {id}. \u22648 tabs, labels unique; a group's members share one tab.")
|
|
3275
|
+
}).optional().describe("TOP-LEVEL props only: the dock tab this prop sits in (a V2 kit schema `groups` entry: Content, Design, \u2026). The FIRST prop in a tab defines {id, label, icon?, order?}; later ones send only {id}. \u22648 tabs, labels \u226440 chars and unique; a group's members share one tab.")
|
|
3275
3276
|
});
|
|
3276
3277
|
var choiceOption = z.union([z.string(), z.object({ label: z.string(), value: z.string(), icon: z.string().optional(), description: z.string().optional() })]);
|
|
3277
3278
|
var fieldShape = {
|
|
@@ -3664,7 +3665,7 @@ var withProjectId = (def) => ({
|
|
|
3664
3665
|
return currentProject.run(arg("projectId"), () => currentBranch.run(arg("branchId"), () => def.handler(args)));
|
|
3665
3666
|
}
|
|
3666
3667
|
});
|
|
3667
|
-
var autoHelpNote = (args) => typeof args.helpText === "string" && args.helpText.trim() ? "" : " No helpText was sent, so the platform wrote it (helpSource: auto); send helpText with update_field to write your own.";
|
|
3668
|
+
var autoHelpNote = (args) => args.helpText === null || typeof args.helpText === "string" && args.helpText.trim() ? "" : " No helpText was sent, so the platform wrote it (helpSource: auto); send helpText with update_field to write your own.";
|
|
3668
3669
|
function buildToolDefs(deps) {
|
|
3669
3670
|
async function withClient(fn) {
|
|
3670
3671
|
const token = await deps.auth.getAccessToken();
|
|
@@ -3971,6 +3972,7 @@ function buildToolDefs(deps) {
|
|
|
3971
3972
|
// 'select' — required, choices
|
|
3972
3973
|
// 'group'/'table'/'object' sub-shape. Typed loosely here (the server validates the full
|
|
3973
3974
|
// recursive shape, 10 levels at most) so a deep tree needs no Zod mirror in the client.
|
|
3975
|
+
// A sub-field may be a 'slot' (its value at its key in the object or row), with the slot keys above.
|
|
3974
3976
|
fields: z.array(z.record(z.string(), z.unknown())).optional(),
|
|
3975
3977
|
min: z.number().optional(),
|
|
3976
3978
|
// 'number'
|
|
@@ -3982,7 +3984,7 @@ function buildToolDefs(deps) {
|
|
|
3982
3984
|
// override that omits it still saves — so it is a marker the dashboard renders and
|
|
3983
3985
|
// get_site_composition counts, never a refusal. Parity: componentPropDefSchema on the server.
|
|
3984
3986
|
required: z.boolean().optional().describe("mark the field required in the editor. An editor HINT: the API still accepts a placement that leaves it empty, and get_site_composition is what reports one."),
|
|
3985
|
-
helpText: z.string().max(200).optional().describe("hint shown under the control, muted (\u2264 200 chars)"),
|
|
3987
|
+
helpText: z.string().max(200).nullable().optional().describe("hint shown under the control, muted (\u2264 200 chars). null = no help on purpose (a /kit schema with no description); omitted = the platform writes it"),
|
|
3986
3988
|
placeholder: z.string().max(120).optional().describe("ghost text inside a text-ish control (\u2264 120 chars)"),
|
|
3987
3989
|
// Stored markers on a prop: nothing refuses a prop value for them. Declared so an echo keeps them.
|
|
3988
3990
|
readOnly: z.union([z.literal(true), z.literal("developer")]).optional(),
|
|
@@ -4071,6 +4073,13 @@ function buildToolDefs(deps) {
|
|
|
4071
4073
|
"section family, e.g. 'Hero' \u2014 set this with a library category to make the component selectable in the page editor's 'Add a section' picker. Components sharing one are layout variants of one section."
|
|
4072
4074
|
);
|
|
4073
4075
|
const allowedOn = z.array(z.string().regex(/^(\*|slug:[a-z0-9-]+|type:(singleton|dynamic|template))$/)).max(100).describe("placement allowlist: *, slug:<page-slug>, and/or type:singleton|dynamic|template");
|
|
4076
|
+
const componentPreviewArg = z.strictObject({
|
|
4077
|
+
title: z.string().min(1).max(64).optional(),
|
|
4078
|
+
subtitle: z.string().min(1).max(64).optional(),
|
|
4079
|
+
media: z.string().min(1).max(64).optional(),
|
|
4080
|
+
fallback: z.string().min(1).max(120).optional(),
|
|
4081
|
+
icon: dockIconArg.optional()
|
|
4082
|
+
}).nullable().describe(PARAM_TEXT.componentPreview);
|
|
4074
4083
|
const createComponentInput = z.object({
|
|
4075
4084
|
name: z.string().min(1),
|
|
4076
4085
|
slug: slug.describe("url-safe unique slug (lowercase letters/numbers/hyphens)"),
|
|
@@ -4082,6 +4091,7 @@ function buildToolDefs(deps) {
|
|
|
4082
4091
|
projectId: z.string().nullable().optional().describe("owning project id; null creates a workspace-wide global component"),
|
|
4083
4092
|
allowedOn: allowedOn.optional(),
|
|
4084
4093
|
description: z.string().optional().describe(PARAM_TEXT.describes),
|
|
4094
|
+
preview: componentPreviewArg.optional(),
|
|
4085
4095
|
blockJson: z.array(blockObject).default([]).describe("the component's block tree"),
|
|
4086
4096
|
props: z.array(componentPropObject).default([]).describe(
|
|
4087
4097
|
"overridable fields. DECLARE A PROP \u2014 WITH A `target` \u2014 for every string, link and image a marketer will ever touch: only the leaves a prop targets are click-to-edit. Each one may carry `ui` to say how its control presents in the inspector \u2014 a collapsed group, what titles and thumbnails a table's rows, whether that table's rows can be dragged at all. 'button' is ONE unit {label, href, variant?, size?, arrow?, icon?, newTab?} on a button block's 'props', never a text prop plus a url prop. 'link' an href, 'date' YYYY-MM-DD, 'color' a hex, 'file' {url, name?}, 'icon' an icon name or an image, 'multiselect' a string[] from config.options (required). " + SLOT_MULTIPLE_NOTE + " " + PROP_V2_NOTE
|
|
@@ -4098,6 +4108,7 @@ function buildToolDefs(deps) {
|
|
|
4098
4108
|
variantOf: z.string().min(1).max(255).optional().describe("see create_component"),
|
|
4099
4109
|
allowedOn: allowedOn.optional().describe("REPLACES the placement allowlist"),
|
|
4100
4110
|
description: z.string().optional(),
|
|
4111
|
+
preview: componentPreviewArg.optional(),
|
|
4101
4112
|
blockJson: z.array(blockObject).optional().describe("REPLACES the block tree"),
|
|
4102
4113
|
props: z.array(componentPropObject).optional().describe(
|
|
4103
4114
|
"REPLACES the prop array \u2014 include every prop you want to keep, WITH its stored `ui`, or that prop's authoring chrome is dropped along with the prop. Read get_component first."
|
|
@@ -4106,7 +4117,7 @@ function buildToolDefs(deps) {
|
|
|
4106
4117
|
propGroup: z.record(z.string(), z.record(z.string(), z.unknown()).nullable()).optional().describe("prop key \u2192 its ui.group ({id, label?, kind?, icon?, collapsed?}), null takes it out"),
|
|
4107
4118
|
propTab: z.record(z.string(), z.record(z.string(), z.unknown()).nullable()).optional().describe("prop key \u2192 its ui.tab ({id, label?, icon?, order?}), the V2 schema group it sits in. The FIRST top-level prop in a tab defines {id, label, icon?, order?}, later ones send {id}; \u22648 tabs; one group's members share one tab. null takes it out"),
|
|
4108
4119
|
propLabel: z.record(z.string(), z.string().min(1).max(255)).optional().describe("prop key \u2192 label"),
|
|
4109
|
-
propHelpText: z.record(z.string(), z.string().max(200).nullable()).optional().describe("prop key \u2192 help text
|
|
4120
|
+
propHelpText: z.record(z.string(), z.string().max(200).nullable()).optional().describe("prop key \u2192 help text; null = no help on purpose (stays empty, never refilled)"),
|
|
4110
4121
|
override: z.boolean().optional().describe(OVERRIDE_NOTE),
|
|
4111
4122
|
ifMatch: z.number().int().min(0).optional().describe(COMPONENT_IF_MATCH_NOTE),
|
|
4112
4123
|
confirmed: z.boolean().optional().describe(PARAM_TEXT.confirmedInput)
|
|
@@ -6529,8 +6540,11 @@ Then declare what an editor may change, via \`props\`:
|
|
|
6529
6540
|
]
|
|
6530
6541
|
|
|
6531
6542
|
Each prop also takes \`required\`, \`helpText\` (\u2264 200 chars) and \`placeholder\` (\u2264 120), which the
|
|
6532
|
-
dashboard's prop editor renders.
|
|
6543
|
+
dashboard's prop editor renders. \`helpText\` is three-state: a string is yours, \`null\` is no help on
|
|
6544
|
+
purpose (send it for a prop whose /kit schema has no description; nothing refills it), and omitted
|
|
6545
|
+
lets the platform write one. They are HINTS: nothing on the write path refuses a placement
|
|
6533
6546
|
that leaves a required prop empty, so \`get_site_composition\` is what reports one.
|
|
6547
|
+
A /kit schema's document-level \`preview\` \u2192 the component's \`preview\` ({title?, subtitle?, media?} are top-level prop keys, plus \`fallback?\`, \`icon?\`); slot rows read it.
|
|
6534
6548
|
|
|
6535
6549
|
\u{1F534} **On a components-first page, \`props\` is the ONLY editing surface.** Click-to-edit binds
|
|
6536
6550
|
\`heading\`/\`text\`/\`button\`/\`image\` blocks; it does **not** bind a \`component\` block, because
|
|
@@ -6582,7 +6596,12 @@ A \`slot\` field (V2 blocks inside a block) takes the same \`config.blockSlugs\`
|
|
|
6582
6596
|
but stores each child INLINE: \`[{ _key, _type: '<block slug>', _variant?, _settings?, ...values }]\`,
|
|
6583
6597
|
its values judged by its block's fields. A component's \`slot\` prop with \`config.multiple\`
|
|
6584
6598
|
takes the same child shape with \`_type\` the COMPONENT id (no \`_variant\`: a variant is its own
|
|
6585
|
-
component). A
|
|
6599
|
+
component). A \`slot\` may also be a SUB-FIELD: inside a \`group\` / \`object\` prop's
|
|
6600
|
+
\`config.fields\` or a \`table\` row (an item type's \`fields\` too), with the slot prop's
|
|
6601
|
+
config keys (\`componentIds\`, \`multiple\`, \`minItems\`/\`maxItems\`, \`slotSettings\`). Its value
|
|
6602
|
+
sits at its key in the object or row, \`{ componentId, overrides? }\` or a list with
|
|
6603
|
+
\`config.multiple\`, judged like a slot prop's: the same allowlist, depth cap and cycle refusal.
|
|
6604
|
+
A list of several item shapes on a component is a \`table\` prop with
|
|
6586
6605
|
\`config.mode: 'types'\` and \`config.itemTypes: [{ name, label?, fields }]\`, rows
|
|
6587
6606
|
\`[{ _key?, _type: '<name>', ...values }]\`.
|
|
6588
6607
|
|
|
@@ -7038,8 +7057,10 @@ hints the dashboard renders \u2014 they are NOT enforced at write time, so an ov
|
|
|
7038
7057
|
required prop still saves; \`get_site_composition\` is what reports those. Use \`select\` with
|
|
7039
7058
|
\`config.options\` for layout / theme / alignment / spacing variants that change only styling,
|
|
7040
7059
|
and a SEPARATE variant component when the markup differs. Repeatable list \u2192 \`table\`; fixed
|
|
7041
|
-
cluster \u2192 \`group\`. Nesting
|
|
7042
|
-
\`table
|
|
7060
|
+
cluster \u2192 \`group\`. Nesting goes up to 10 levels counting the prop itself. A \`table\` row may hold a
|
|
7061
|
+
\`table\` (rows), a data table (\`config.mode: "data"\`) or a polymorphic list
|
|
7062
|
+
(\`config.mode: "types"\`), so a size guide's rows can each carry a chart and a multi-step
|
|
7063
|
+
form's steps can each carry their fields. Deeper is refused (\`field_depth_exceeded\`).
|
|
7043
7064
|
|
|
7044
7065
|
**5. Design, responsiveness and accessibility.** \`componentize_sections\` and \`npx
|
|
7045
7066
|
@bettercms-ai/convert --componentize\` move the section's markup VERBATIM \u2014 classes, responsive
|
|
@@ -7406,7 +7427,7 @@ back each prop's stored \`ui\` or you delete it along with the prop. Props have
|
|
|
7406
7427
|
prop joins a group with \`ui.group\`: the FIRST prop of a group defines \`{ id, label, kind?, icon?,
|
|
7407
7428
|
collapsed? }\` (kind \`group\` or \`row\`; a tab is \`ui.tab\`, never a group kind), and every later prop
|
|
7408
7429
|
sends \`{ id }\` only. A prop joins a TAB with \`ui.tab\` the same way: the FIRST top-level prop in a tab
|
|
7409
|
-
defines \`{ id, label, icon?, order? }\`, later props send \`{ id }\`; at most 8 tabs, labels \
|
|
7430
|
+
defines \`{ id, label, icon?, order? }\`, later props send \`{ id }\`; at most 8 tabs, labels \u226440 characters
|
|
7410
7431
|
and unique; top-level props only (never a sub-field); all members of one \`ui.group\` share one tab. A V2
|
|
7411
7432
|
kit entry's schema \`groups\` and each field's \`group\` map 1:1 to \`ui.tab\`, so its \`design\` group is a
|
|
7412
7433
|
tab named Design holding the theme, sticky and similar props. A FIELD never takes \`ui.group\` or
|
|
@@ -7484,7 +7505,7 @@ Importance orders a screen: required fields first, then array order.
|
|
|
7484
7505
|
An unknown \`openMode\` is refused with \`openMode_invalid\`, one on a leaf \`openMode_leaf\`; a bad \`config.scale\` with \`scale_invalid\`; more than 10 nested field levels with \`field_depth_exceeded\`. update_field sets and clears (null) helpMore, advanced, recommendedMax and openMode on an existing field.
|
|
7485
7506
|
|
|
7486
7507
|
**Tabs.** A \`kind: 'tab'\` fieldset is a tab:
|
|
7487
|
-
- at most **3** tabs, names at most
|
|
7508
|
+
- at most **3** tabs, names at most 40 characters and unique;
|
|
7488
7509
|
- top-level fields only: tabs never nest (a component's props take tabs through \`ui.tab\`, its own rules);
|
|
7489
7510
|
- untabbed fields stay PINNED above the strip;
|
|
7490
7511
|
- a group or row fieldset joins a tab with \`tab: '<tab id>'\`; groups in a non-first tab default open;
|
|
@@ -7766,7 +7787,7 @@ Read \`bettercms://playbook/schema\` \xA712 first \u2014 this is the short form
|
|
|
7766
7787
|
4. **Fields** = \`props\`: text, richtext, image, url, boolean, number, select, group, table, slot.
|
|
7767
7788
|
Always a \`defaultValue\`; \`required\` / \`helpText\` / \`placeholder\` are editor hints, not write
|
|
7768
7789
|
-time enforcement. \`select\` for styling-only variants, a separate component when the markup
|
|
7769
|
-
differs. Nesting
|
|
7790
|
+
differs. Nesting goes up to 10 levels; a \`table\` row may hold a data table or a polymorphic list.
|
|
7770
7791
|
5. **Quality.** The componentize lane and \`npx @bettercms-ai/convert --componentize\` move markup
|
|
7771
7792
|
VERBATIM \u2014 classes, responsive utilities, aria attributes, alt text all survive. Never
|
|
7772
7793
|
restyle. Dry-run first.
|