@bettercms-ai/mcp 0.30.0 → 0.31.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 +47 -14
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2485,6 +2485,10 @@ function buildToolDefs(deps) {
|
|
|
2485
2485
|
command: layoutCommand.describe("one canonical discriminated Layout command; authority is derived from type"),
|
|
2486
2486
|
ifMatch: z.number().int().nonnegative().describe("revision returned by get_layout")
|
|
2487
2487
|
});
|
|
2488
|
+
const publishLayoutInput = z.object({
|
|
2489
|
+
projectId: z.string().min(1).optional().describe("required only for a workspace-scoped grant"),
|
|
2490
|
+
ifMatch: z.number().int().nonnegative().describe("revision returned by get_layout (scope global)")
|
|
2491
|
+
});
|
|
2488
2492
|
const componentCategory = z.enum([
|
|
2489
2493
|
"navbar",
|
|
2490
2494
|
"footer",
|
|
@@ -2833,8 +2837,8 @@ function buildToolDefs(deps) {
|
|
|
2833
2837
|
def(
|
|
2834
2838
|
"update_project",
|
|
2835
2839
|
"Update the connected project",
|
|
2836
|
-
"Update the connected project's settings \u2014 rename it, change its slug/description, SEO defaults, or
|
|
2837
|
-
z.object({ name: z.string().optional(), slug: z.string().optional(), description: z.string().optional(), visibility: z.string().optional(), seoDefaults: z.record(z.string(), z.unknown()).optional() }).shape,
|
|
2840
|
+
"Update the connected project's settings \u2014 rename it, change its slug/description, SEO defaults, visibility, or `presentation`. Only the provided fields change. `presentation` themes the platform's OWN renderer (the one serving a site built in the CMS with no deployed build, and previewing structural drafts everywhere) with the same closed knobs as bcms-presentation.json \u2014 DTCG { $type, $value } tokens keyed like 'page.maxWidth', 'nav.background'. Without it that renderer is a generic 768px document theme. An invalid manifest is 422 PRESENTATION_INVALID.",
|
|
2841
|
+
z.object({ name: z.string().optional(), slug: z.string().optional(), description: z.string().optional(), visibility: z.string().optional(), seoDefaults: z.record(z.string(), z.unknown()).optional(), presentation: z.record(z.string(), z.unknown()).optional().describe("theme knobs for the platform renderer, keyed like bcms-presentation.json") }).shape,
|
|
2838
2842
|
async (c, a) => ok("Updated project.", await data(c, "PATCH", `/management/projects/current`, a))
|
|
2839
2843
|
),
|
|
2840
2844
|
def(
|
|
@@ -3565,7 +3569,7 @@ function buildToolDefs(deps) {
|
|
|
3565
3569
|
})
|
|
3566
3570
|
)
|
|
3567
3571
|
},
|
|
3568
|
-
// ── Project/page Layout (draft
|
|
3572
|
+
// ── Project/page Layout (draft commands + Global Layout publish; page overrides publish with the page) ──
|
|
3569
3573
|
{
|
|
3570
3574
|
name: "get_layout",
|
|
3571
3575
|
config: {
|
|
@@ -3590,6 +3594,18 @@ function buildToolDefs(deps) {
|
|
|
3590
3594
|
return ok(`Updated ${layout.scope === "global" ? "Global" : `Page ${layout.pageSlug}`} Layout draft to revision ${layout.revision}.`, layout);
|
|
3591
3595
|
}))
|
|
3592
3596
|
},
|
|
3597
|
+
{
|
|
3598
|
+
name: "publish_layout",
|
|
3599
|
+
config: {
|
|
3600
|
+
title: "Publish the Global Layout draft",
|
|
3601
|
+
description: "Publish the connected project's GLOBAL Layout draft (navigation, footer, every reserved section) so the live site builds from it. Until this is called the layout stays draft and get_layout copy:'published' answers PUBLISHED_LAYOUT_UNAVAILABLE \u2014 site chrome authored with update_layout is NOT live. Read get_layout first and pass its revision as ifMatch; a stale revision returns 409 \u2014 re-read, never retry blindly. A 422 lists validation issues to fix with update_layout first. Verify with get_layout copy:'published' and check the copy echo \u2014 this tool's own response is the write's echo, not a receipt. Page overrides go live with the page (update_page status:'published'). A 403 PUBLISH_NOT_GRANTED means this connection can author drafts but cannot publish \u2014 say so and let the user allow publishing or publish from the dashboard.",
|
|
3602
|
+
inputSchema: publishLayoutInput.shape
|
|
3603
|
+
},
|
|
3604
|
+
handler: guard(async (args) => withClient(async (client) => {
|
|
3605
|
+
const layout = await client.publishManagedLayout(args);
|
|
3606
|
+
return ok(`Published the Global Layout at revision ${layout.revision} (copy: published). Verify with get_layout copy:'published'.`, layout);
|
|
3607
|
+
}))
|
|
3608
|
+
},
|
|
3593
3609
|
// ── Components (discover + author reusable symbols) ──
|
|
3594
3610
|
{
|
|
3595
3611
|
name: "list_components",
|
|
@@ -3788,9 +3804,11 @@ Decide before your first call; converting later means rewriting content.
|
|
|
3788
3804
|
|
|
3789
3805
|
## 3. Anatomy of a real section component
|
|
3790
3806
|
|
|
3791
|
-
A component that is only headings and text renders as an unstyled stack
|
|
3792
|
-
|
|
3793
|
-
\`
|
|
3807
|
+
A component that is only headings and text renders as an unstyled stack \u2014 plain text on white
|
|
3808
|
+
in a 768px column, on the live site AND in the visual editor. Every section the product ships
|
|
3809
|
+
looks like this \u2014 a \`section\` block carrying \`style\`, with content nested in
|
|
3810
|
+
\`props.children\`. \`create_component\` and \`update_component\` return a \`warnings\` entry when a
|
|
3811
|
+
Section's root section has no \`style\`; treat it as a defect, not a note:
|
|
3794
3812
|
|
|
3795
3813
|
{
|
|
3796
3814
|
type: "section", id: "root",
|
|
@@ -3845,8 +3863,8 @@ words (the page-builder model): each placement takes that group's current values
|
|
|
3845
3863
|
kept and marked \`origin: "componentized"\` so the editor stops offering a second place to type
|
|
3846
3864
|
them. Either way, running it again converts nothing and duplicates nothing. Then run \`npx @bettercms-ai/convert --componentize\` in the repo
|
|
3847
3865
|
so its templates render those sections from \`pages[].blocks\`, and finish with the publishes:
|
|
3848
|
-
\`publish_component\` every new component
|
|
3849
|
-
sections as empty strings.
|
|
3866
|
+
\`publish_component\` every new component, \`publish_layout\` if you touched site chrome (nav,
|
|
3867
|
+
footer), and publish the pages, or the site renders the sections as empty strings.
|
|
3850
3868
|
|
|
3851
3869
|
## 5. Blocks and modular fields
|
|
3852
3870
|
|
|
@@ -3911,6 +3929,7 @@ is interpolated per entry with \`{{fieldKey}}\` placeholders \u2014 \`{{title}}\
|
|
|
3911
3929
|
5. pages create_page with blockJson placing those components
|
|
3912
3930
|
6. content create_content_entry / set_page_content
|
|
3913
3931
|
7. publish update_page status:'published'
|
|
3932
|
+
7b. layout publish_layout <- if you authored the Global Layout (nav/footer); page overrides publish with the page
|
|
3914
3933
|
8. check get_next_steps, and fix what it lists
|
|
3915
3934
|
|
|
3916
3935
|
## 8. Two ways to ship a blank site
|
|
@@ -3930,8 +3949,11 @@ in preview and is blank in production. Always pass the project's id.
|
|
|
3930
3949
|
accepts it and ignores it**, silently. No error, no warning, wrong project.
|
|
3931
3950
|
|
|
3932
3951
|
So call \`get_project\` (no arguments) first \u2014 it reports the project you are actually
|
|
3933
|
-
writing to. If that is not where the work belongs
|
|
3934
|
-
|
|
3952
|
+
writing to. If that is not where the work belongs \u2014 or it answers that the grant covers the
|
|
3953
|
+
whole workspace \u2014 stop and tell the user the one-step fix: in the BetterCMS dashboard open
|
|
3954
|
+
**Settings \u2192 Connected AI clients** and use **Scope to project** on this connection. No tool
|
|
3955
|
+
can switch it, but the user does NOT need to re-authorize or re-add the server: the next call
|
|
3956
|
+
after that runs with the new scope. Then retry.
|
|
3935
3957
|
|
|
3936
3958
|
If you must probe, probe with a \`create_content_model\` \u2014 models are deletable
|
|
3937
3959
|
(\`delete_content_model\`, soft-delete) and **there is no \`delete_component\`**. A component
|
|
@@ -3957,6 +3979,7 @@ in this order:
|
|
|
3957
3979
|
|
|
3958
3980
|
1. create_component per section (they land as DRAFTS)
|
|
3959
3981
|
2. publish_component each one \u2014 unpublished renders as NOTHING, on a page that 200s
|
|
3982
|
+
2b. publish_layout if you authored site chrome \u2014 the layout is a separate publish
|
|
3960
3983
|
3. set_page_content place them as \`component\` blocks on the page
|
|
3961
3984
|
4. list_extraction_candidates / extract_component
|
|
3962
3985
|
now that blocks exist, fold any section repeated 3+ times
|
|
@@ -3983,6 +4006,13 @@ type scale, nav position and background, footer surface \u2014 as DTCG \`{"$type
|
|
|
3983
4006
|
entries. Redeclare it on every deploy; absent means "declared nothing" and previews fall back
|
|
3984
4007
|
to platform defaults that will not look like this site.
|
|
3985
4008
|
|
|
4009
|
+
**A site built in the CMS with NO deployed build has only that renderer** \u2014 live and in the
|
|
4010
|
+
editor \u2014 so the generic theme IS the site until you theme it. Theme it without a deploy:
|
|
4011
|
+
\`update_project { presentation: { "page.maxWidth": { "$type": "dimension", "$value": 1200 },
|
|
4012
|
+
"nav.background": { "$type": "color", "$value": "#0b0b0b" }, ... } }\` takes the same knobs as
|
|
4013
|
+
bcms-presentation.json, and set \`style\` on every Section's root (\xA73). A later deploy that
|
|
4014
|
+
ships bcms-presentation.json replaces it wholesale.
|
|
4015
|
+
|
|
3986
4016
|
**Editing binds by VALUE.** The editor matches CMS field values against the text the site
|
|
3987
4017
|
renders. Three consequences, each load-bearing:
|
|
3988
4018
|
|
|
@@ -3995,6 +4025,7 @@ renders. Three consequences, each load-bearing:
|
|
|
3995
4025
|
c. set_page_content values EXACTLY equal to the text the site renders \u2014
|
|
3996
4026
|
binding matches by value, so a paraphrase binds nothing
|
|
3997
4027
|
d. update_page status 'published' \u2014 the canvas binds the PUBLISHED copy
|
|
4028
|
+
e. publish_layout if site chrome was authored \u2014 the canvas binds the PUBLISHED layout too
|
|
3998
4029
|
2. A value that renders in more than one place is still ONE field: bind every element that
|
|
3999
4030
|
renders it, and the editor keeps them in sync \u2014 an edit patches every copy at once.
|
|
4000
4031
|
Binding only one copy leaves the others showing the old text until the next rebuild.
|
|
@@ -4050,7 +4081,8 @@ green on the wrong document. Three rules, none optional:
|
|
|
4050
4081
|
the draft; a PUBLISH claim verifies ONLY via \`get_layout copy:'published'\` (or the
|
|
4051
4082
|
entry/page's published copy) \u2014 and check the response's \`copy\` echo says
|
|
4052
4083
|
'published'. A reader that ignores your copy selector hands you the draft and a
|
|
4053
|
-
false green; the echo is how you catch it.
|
|
4084
|
+
false green; the echo is how you catch it. \`publish_layout\`'s own response echoes
|
|
4085
|
+
copy:'published' too \u2014 that is the WRITE's echo, not a receipt; still re-read.
|
|
4054
4086
|
2. Publish and deploy are SEPARATE claims. "Published" means the published copy changed;
|
|
4055
4087
|
the LIVE SITE changes only after its next deploy/rebuild. Never report "it's live"
|
|
4056
4088
|
from a publish receipt \u2014 fetch the live URL (cache-busted) for that claim.
|
|
@@ -4287,9 +4319,10 @@ error-prone, so go slow and confirm. Never guess the layout.
|
|
|
4287
4319
|
6. **\`publish_component\`.** It lands as a DRAFT, and a draft component renders as NOTHING on
|
|
4288
4320
|
the live site \u2014 no error, no placeholder. This step is not optional.
|
|
4289
4321
|
`;
|
|
4290
|
-
var LAYOUT_FLOW = `### Project/page Layout authoring \u2192 \`get_layout\` / \`update_layout\`
|
|
4291
|
-
Edit the project's draft Global Layout or one page's draft override.
|
|
4292
|
-
|
|
4322
|
+
var LAYOUT_FLOW = `### Project/page Layout authoring \u2192 \`get_layout\` / \`update_layout\` / \`publish_layout\`
|
|
4323
|
+
Edit the project's draft Global Layout or one page's draft override. \`update_layout\` never
|
|
4324
|
+
changes the live site; \`publish_layout\` takes the Global Layout draft live (page overrides go
|
|
4325
|
+
live with their page). Until it is called, site chrome you authored is NOT on the live site.
|
|
4293
4326
|
1. **Read first** \u2014 call \`get_layout\` with scope \`global\`, or scope \`page\` + pageId.
|
|
4294
4327
|
Keep the returned \`revision\`; every write must pass it as \`ifMatch\`.
|
|
4295
4328
|
2. **Choose one discriminated command type** \u2014 the server derives its authority family;
|