@bettercms-ai/mcp 0.35.0 → 0.36.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/README.md CHANGED
File without changes
package/dist/index.js CHANGED
@@ -2024,29 +2024,30 @@ async function askFramework(deps) {
2024
2024
  }
2025
2025
  var AUTHORING_CHOICES = ["components", "fields"];
2026
2026
  var AUTHORING_LABELS = {
2027
- components: "Components \u2014 reusable section components placed as blocks; editors add, reorder and swap sections without touching a schema. Best for marketing and landing sites",
2028
- fields: "Fields \u2014 a typed field schema per page. Best for blogs, catalogues and directories, where many rows share one shape"
2027
+ components: "Components (recommended) \u2014 reusable section components placed as blocks; editors add, reorder and swap sections without touching a schema. Recommend it for every marketing, landing, agency or product site",
2028
+ fields: "Fields \u2014 a typed field schema per page. Only for a blog, catalogue or directory where many rows share one shape; editors can change a page's copy but cannot add, reorder or swap its sections"
2029
2029
  };
2030
2030
  var AUTHORING_PROMPT = [
2031
2031
  "Ask the user which authoring architecture this site should use, then call set_authoring_preference again with their answer as `preference`:",
2032
2032
  ...AUTHORING_CHOICES.map((c, i) => ` ${i + 1}. ${c} \u2014 ${AUTHORING_LABELS[c]}`),
2033
2033
  "",
2034
- "Answering 'components' does not convert anything \u2014 there is no field-to-block converter. It means you author the sections yourself: create_component, then publish_component (an unpublished component renders as NOTHING on the live site), then set_page_content placing `component` blocks. Once a page has blocks, list_extraction_candidates and extract_component fold the repeats.",
2034
+ "On a site whose pages were DERIVED at import, answering 'components' redoes nothing: after set_authoring_preference, get_componentize_plan proposes one component per section (it reads the PUBLISHED pages \u2014 no deploy needed to reach it), you confirm it with the user, then componentize_sections places them with `props.bind` (dry run first \u2014 they land as drafts and the page keeps its fields, values and bindings, so click-to-edit and the coverage meter are unchanged), then publish_component each one, publish the pages, run `npx @bettercms-ai/convert --componentize` in the repo, and deploy. For a section group the plan lists as NO_GROUP_ROOT or NOT_A_SECTION there is nothing to componentize, so author that section with create_component and set_page_content.",
2035
2035
  "",
2036
+ "Recommend components unless the user says the site is schema-first.",
2036
2037
  "Do not choose on their behalf. This is asked once per project."
2037
2038
  ].join("\n");
2038
2039
  async function askAuthoring(deps) {
2039
2040
  if (!deps.elicit) return { prompt: AUTHORING_PROMPT };
2040
2041
  try {
2041
2042
  const res = await deps.elicit({
2042
- message: "Which authoring architecture should this site use?",
2043
+ message: "Which authoring architecture should this site use? Components is recommended for a marketing site.",
2043
2044
  requestedSchema: {
2044
2045
  type: "object",
2045
2046
  properties: {
2046
2047
  preference: {
2047
2048
  type: "string",
2048
2049
  title: "Authoring architecture",
2049
- description: "How this site's pages are composed. Asked once per project.",
2050
+ description: "How this site's pages are composed. Components is recommended unless this is a schema-first site (a blog, catalogue or directory). Asked once per project.",
2050
2051
  enum: [...AUTHORING_CHOICES],
2051
2052
  enumNames: AUTHORING_CHOICES.map((c) => AUTHORING_LABELS[c])
2052
2053
  }
@@ -2877,7 +2878,7 @@ function buildToolDefs(deps) {
2877
2878
  def(
2878
2879
  "set_authoring_preference",
2879
2880
  "Set the site's authoring architecture",
2880
- "Record which authoring architecture this site uses \u2014 'components' (reusable section components placed as blocks; editors add, reorder and swap sections without touching a schema \u2014 best for marketing and landing sites) or 'fields' (a typed field schema per page \u2014 best for blogs, catalogues and directories). ASK THE USER; do not pick for them. Called without `preference`, this tool asks them directly (or hands you the question to ask). deploy_project, deploy_from_upload and promote_project all refuse with 409 AUTHORING_DECISION_REQUIRED until it is set, and that refusal carries this project's real page counts to show the user. Answering 'components' does NOT convert anything \u2014 there is no field-to-block converter; it means you author the sections yourself: create_component, then publish_component (an unpublished component renders as NOTHING on the live site), then set_page_content placing `component` blocks. Asked once per project; re-callable if the user changes their mind.",
2881
+ "Record which authoring architecture this site uses \u2014 'components' (RECOMMENDED: reusable section components placed as blocks; editors add, reorder and swap sections without touching a schema \u2014 recommend it for every marketing, landing, agency or product site) or 'fields' (a typed field schema per page \u2014 only for a blog, catalogue or directory where many rows share one shape). ASK THE USER; do not pick for them. Called without `preference`, this tool asks them directly (or hands you the question to ask). deploy_project, deploy_from_upload and promote_project all refuse with 409 AUTHORING_DECISION_REQUIRED until it is set, and that refusal carries this project's real page counts to show the user. On a site whose pages were DERIVED at import, answering 'components' redoes nothing: after set_authoring_preference, get_componentize_plan proposes one component per section (it reads the PUBLISHED pages \u2014 no deploy needed to reach it), you confirm it with the user, then componentize_sections places them with `props.bind` (dry run first \u2014 they land as drafts and the page keeps its fields, values and bindings, so click-to-edit and the coverage meter are unchanged), then publish_component each one, publish the pages, run `npx @bettercms-ai/convert --componentize` in the repo, and deploy. Recommend components unless the user says the site is schema-first. Asked once per project; re-callable if the user changes their mind.",
2881
2882
  // Optional in the schema for exactly the reason `framework` is above: a required arg is
2882
2883
  // rejected by the SDK before the handler runs, which would kill the elicitation below
2883
2884
  // and leave the model guessing. Optional here, answered by a human there. The backend
@@ -3804,7 +3805,8 @@ touching a schema. This is what \`create_component\` + \`create_page(blockJson)\
3804
3805
  A collection (\`create_content_model\`) plus entries.
3805
3806
 
3806
3807
  Most real sites are both: components for the marketing pages, a collection for the blog.
3807
- Decide before your first call; converting later means rewriting content.
3808
+ Decide before your first call; converting later means rewriting content \u2014 unless the site was
3809
+ DERIVED at import, where the componentize lane in \xA710 reuses every field.
3808
3810
 
3809
3811
  ## 2. The decision tree
3810
3812
 
@@ -3992,31 +3994,49 @@ out, let the user pick, call \`set_authoring_preference\`, then deploy again.
3992
3994
  It exists because an imported site arrives **field-driven whether anyone chose that or not**
3993
3995
  \u2014 a crawl-based import (Webflow, a starter, a template) emits pages with a typed field schema
3994
3996
  and an empty block tree, because that is all a crawl can infer. Nobody decided it. On a
3995
- marketing site it is the wrong answer, and \xA71 already says why converting later means
3996
- rewriting content. So the platform stops once, at the last moment it is still cheap.
3997
-
3998
- **Answering \`components\` does not convert anything.** There is no field-to-block converter,
3999
- and \`extract_component\` cannot stand in for one: it scans \`blockJson\`, which is empty on
4000
- exactly the pages that would need converting. What it means is that you author the sections,
4001
- in this order:
4002
-
4003
- 1. create_component per section (they land as DRAFTS)
4004
- 2. publish_component each one \u2014 unpublished renders as NOTHING, on a page that 200s
4005
- 2b. publish_layout if you authored site chrome \u2014 the layout is a separate publish
4006
- 3. set_page_content place them as \`component\` blocks on the page
4007
- 4. list_extraction_candidates / extract_component
4008
- now that blocks exist, fold any section repeated 3+ times
4009
-
4010
- Step 2 is not a formality: \`componentize_sections\` and \`create_component\` both land components
3997
+ marketing site it is the wrong answer. So the platform stops once, at the last moment it is
3998
+ still cheap \u2014 and on a derived site that moment costs nothing, because the componentize lane
3999
+ below reuses every field the import already derived.
4000
+
4001
+ **Recommend \`components\`.** On a site whose pages were DERIVED at import \u2014 the site \xA713
4002
+ describes \u2014 it redoes nothing: the componentize lane turns each top-level field GROUP into a
4003
+ component placement, and the page keeps its fields, its values and its bindings. In this order:
4004
+
4005
+ 1. set_authoring_preference { preference: "components" }
4006
+ 2. get_componentize_plan one component per section, computed live; creates nothing. It
4007
+ reads this project's PUBLISHED pages, so no deploy is needed
4008
+ to reach it \u2014 the deploy is the last step, not the first
4009
+ 3. show the user the plan and CONFIRM \u2014 it says how many components and which pages
4010
+ 4. componentize_sections \`dryRun: true\` first, then for real; components land as DRAFTS
4011
+ and each placement carries \`props.bind\` to the page's field
4012
+ group, so click-to-edit and the coverage meter do not change
4013
+ 5. publish_component each one \u2014 unpublished renders as NOTHING, on a page that 200s
4014
+ 5b. publish_layout if you authored site chrome \u2014 the layout is a separate publish
4015
+ 6. publish the pages
4016
+ 7. npx @bettercms-ai/convert --componentize in the repo, so its templates render these
4017
+ sections from \`pages[].blocks\`
4018
+ 8. deploy the ONLY deploy this sequence needs
4019
+
4020
+ Step 5 is not a formality: \`componentize_sections\` and \`create_component\` both land components
4011
4021
  as DRAFTS, so \`publish_component\` each one and publish the page \u2014 otherwise the canvas keeps
4012
4022
  painting the PUBLISHED copy and the editor reports N components unpublished.
4013
4023
 
4014
- **Answering \`fields\` is a real answer, not a deferral.** A blog, a catalogue or a directory
4015
- is schema-first by design (\xA71) and should stay that way. Say so and move on.
4016
-
4017
- Either way: ask, do not choose. The 409 carries this project's actual page counts \u2014 how many
4018
- are field-driven, block-driven, and how many place a reusable component \u2014 so quote those to
4019
- the user rather than describing the choice in the abstract.
4024
+ **A site with nothing to componentize you author by hand.** Where the plan offers nothing for
4025
+ a group (\`NO_GROUP_ROOT\` \u2014 the page's field keys are still the derive lane's own;
4026
+ \`NOT_A_SECTION\` \u2014 a lone scalar with no family), and on a site with no derived pages at all,
4027
+ the order is \`create_component\` per section \u2192 \`publish_component\` each \u2192 \`set_page_content\`
4028
+ placing \`component\` blocks \u2192 \`list_extraction_candidates\` / \`extract_component\` to fold any
4029
+ section repeated 3+ times. \`extract_component\` is not a converter and cannot stand in for the
4030
+ componentize lane: it scans \`blockJson\`, which is empty on exactly the pages that would need
4031
+ converting.
4032
+
4033
+ **Answering \`fields\` is a real answer, not a deferral** \u2014 for a SCHEMA-FIRST site. A blog, a
4034
+ catalogue or a directory is schema-first by design (\xA71) and should stay that way. On anything
4035
+ else it costs the editor the ability to add, reorder or swap sections. Say so and move on.
4036
+
4037
+ Either way: ask, do not choose \u2014 recommending is not answering. The 409 carries this project's
4038
+ actual page counts \u2014 how many are field-driven, block-driven, and how many place a reusable
4039
+ component \u2014 so quote those to the user rather than describing the choice in the abstract.
4020
4040
 
4021
4041
  ## 11. The canvas: what makes an imported site EDITABLE
4022
4042