@elementor/editor-canvas 4.1.0-837 → 4.1.0-beta1

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
@@ -121,6 +121,9 @@ function isWidgetAvailableForLLM(config) {
121
121
  if (config.meta?.llm_support === false) {
122
122
  return false;
123
123
  }
124
+ if (config.title === "Component") {
125
+ return false;
126
+ }
124
127
  if (config.atomic_props_schema) {
125
128
  return true;
126
129
  }
@@ -342,7 +345,7 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
342
345
 
343
346
  // src/init.tsx
344
347
  var import_editor = require("@elementor/editor");
345
- var import_editor_mcp3 = require("@elementor/editor-mcp");
348
+ var import_editor_mcp4 = require("@elementor/editor-mcp");
346
349
 
347
350
  // src/components/classes-rename.tsx
348
351
  var import_react = require("react");
@@ -3882,6 +3885,7 @@ var import_editor_elements13 = require("@elementor/editor-elements");
3882
3885
  var import_editor_elements11 = require("@elementor/editor-elements");
3883
3886
  var import_editor_props6 = require("@elementor/editor-props");
3884
3887
  var import_editor_styles5 = require("@elementor/editor-styles");
3888
+ var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
3885
3889
  function resolvePropValue(value, forceKey) {
3886
3890
  const Utils = window.elementorV2.editorVariables.Utils;
3887
3891
  return import_editor_props6.Schema.adjustLlmPropValueSchema(value, {
@@ -3990,6 +3994,7 @@ var doUpdateElementProperty = (params) => {
3990
3994
  },
3991
3995
  withHistory: false
3992
3996
  });
3997
+ (0, import_editor_v1_adapters19.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
3993
3998
  };
3994
3999
 
3995
4000
  // src/mcp/utils/validate-input.ts
@@ -4085,6 +4090,7 @@ var CompositionBuilder = class _CompositionBuilder {
4085
4090
  rootContainers = [];
4086
4091
  api = {
4087
4092
  createElement: import_editor_elements13.createElement,
4093
+ deleteElement: import_editor_elements13.deleteElement,
4088
4094
  getWidgetsCache: import_editor_elements13.getWidgetsCache,
4089
4095
  generateElementId: import_editor_elements13.generateElementId,
4090
4096
  getContainer: import_editor_elements13.getContainer,
@@ -4135,7 +4141,8 @@ var CompositionBuilder = class _CompositionBuilder {
4135
4141
  elements: children,
4136
4142
  editor_settings: {
4137
4143
  title: node.getAttribute("configuration-id") ?? void 0
4138
- }
4144
+ },
4145
+ elType: "widget"
4139
4146
  };
4140
4147
  if (isWidget) {
4141
4148
  return { ...base, elType: "widget", widgetType: elementTag };
@@ -4167,12 +4174,6 @@ var CompositionBuilder = class _CompositionBuilder {
4167
4174
  }
4168
4175
  return errors;
4169
4176
  }
4170
- findSchemaForNode(node) {
4171
- const widgetsCache = this.api.getWidgetsCache() || {};
4172
- const widgetType = node.tagName;
4173
- const widgetData = widgetsCache[widgetType]?.atomic_props_schema;
4174
- return widgetData || null;
4175
- }
4176
4177
  matchNodeByConfigId(configId) {
4177
4178
  const node = this.xml.querySelector(`[configuration-id="${configId}"]`);
4178
4179
  if (!node) {
@@ -4294,13 +4295,24 @@ ${childTypeErrors.join("\n")}`);
4294
4295
  const children = Array.from(this.xml.children);
4295
4296
  for (const childNode of children) {
4296
4297
  const modelTree = this.buildModelTree(childNode, widgetsCache);
4297
- const newElement = this.api.createElement({
4298
- container: rootContainer,
4299
- model: modelTree,
4300
- options: { useHistory: false }
4301
- });
4302
- this.rootContainers.push(newElement);
4303
- await this.awaitViewRender(newElement);
4298
+ try {
4299
+ const newElement = this.api.createElement({
4300
+ container: rootContainer,
4301
+ model: modelTree,
4302
+ options: { useHistory: false }
4303
+ });
4304
+ this.rootContainers.push(newElement);
4305
+ await this.awaitViewRender(newElement);
4306
+ } catch (e) {
4307
+ const attemptToRestoreInvalidContainer = this.api.getContainer(modelTree.id);
4308
+ if (attemptToRestoreInvalidContainer) {
4309
+ this.api.deleteElement({
4310
+ container: attemptToRestoreInvalidContainer,
4311
+ options: { useHistory: false }
4312
+ });
4313
+ }
4314
+ throw e;
4315
+ }
4304
4316
  }
4305
4317
  const { configErrors, styleErrors, invalidStyles } = await this.applyProperties();
4306
4318
  return {
@@ -4324,6 +4336,7 @@ function getCompositionTargetContainer(documentContainer, documentType) {
4324
4336
 
4325
4337
  // src/mcp/tools/build-composition/prompt.ts
4326
4338
  var import_editor_mcp2 = require("@elementor/editor-mcp");
4339
+ var BUILD_COMPOSITIONS_GUIDE_URI = "elementor://canvas/tools/build-compositions-guide";
4327
4340
  var generatePrompt = () => {
4328
4341
  const buildCompositionsToolPrompt = (0, import_editor_mcp2.toolPrompts)("build-compositions");
4329
4342
  buildCompositionsToolPrompt.description(`
@@ -4505,12 +4518,25 @@ var outputSchema = {
4505
4518
 
4506
4519
  // src/mcp/tools/build-composition/tool.ts
4507
4520
  var initBuildCompositionsTool = (reg) => {
4508
- const { addTool } = reg;
4521
+ const { addTool, resource } = reg;
4522
+ resource(
4523
+ "build-compositions-guide",
4524
+ BUILD_COMPOSITIONS_GUIDE_URI,
4525
+ {
4526
+ title: "Build Compositions Guide",
4527
+ description: "Detailed guide for using the build-compositions tool",
4528
+ mimeType: "text/plain"
4529
+ },
4530
+ async (uri) => ({
4531
+ contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
4532
+ })
4533
+ );
4509
4534
  addTool({
4510
4535
  name: "build-compositions",
4511
- description: generatePrompt(),
4536
+ description: "Build V4 element compositions on the Elementor canvas. Read the guide resource before use.",
4512
4537
  schema: inputSchema,
4513
4538
  requiredResources: [
4539
+ { description: "Build compositions guide", uri: BUILD_COMPOSITIONS_GUIDE_URI },
4514
4540
  { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
4515
4541
  { description: "Styles schema", uri: STYLE_SCHEMA_URI },
4516
4542
  { description: "Global Classes", uri: "elementor://global-classes" },
@@ -4534,6 +4560,7 @@ var initBuildCompositionsTool = (reg) => {
4534
4560
  try {
4535
4561
  const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
4536
4562
  createElement: import_editor_elements14.createElement,
4563
+ deleteElement: import_editor_elements14.deleteElement,
4537
4564
  getWidgetsCache: import_editor_elements14.getWidgetsCache
4538
4565
  });
4539
4566
  compositionBuilder.setElementConfig(elementConfig);
@@ -4638,7 +4665,12 @@ function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
4638
4665
  var import_editor_elements15 = require("@elementor/editor-elements");
4639
4666
 
4640
4667
  // src/mcp/tools/configure-element/prompt.ts
4641
- var configureElementToolPrompt = `Configure an existing element on the page.
4668
+ var import_editor_mcp3 = require("@elementor/editor-mcp");
4669
+ var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
4670
+ var generatePrompt2 = () => {
4671
+ const configureElementToolPrompt = (0, import_editor_mcp3.toolPrompts)("configure-element");
4672
+ configureElementToolPrompt.description(`
4673
+ Configure an existing element on the page.
4642
4674
 
4643
4675
  # **CRITICAL - REQUIRED INFORMATION (Must read before using this tool)**
4644
4676
  1. [${WIDGET_SCHEMA_URI}]
@@ -4653,12 +4685,6 @@ Before using this tool, check the definitions of the elements PropTypes at the r
4653
4685
  All widgets share a common _style property for styling, which uses the common styles schema.
4654
4686
  Retrieve and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
4655
4687
 
4656
- # Parameters
4657
- - propertiesToChange: An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object.
4658
- - stylePropertiesToChange: An object containing the style properties to change, with their new values. OPTIONAL
4659
- - elementId: The ID of the element to configure. MANDATORY
4660
- - elementType: The type of the element to configure (i.e. e-heading, e-button). MANDATORY
4661
-
4662
4688
  # When to use this tool
4663
4689
  When a user requires to change anything in an element, such as updating text, colors, sizes, or other configurable properties.
4664
4690
  This tool handles elements of type "widget".
@@ -4687,7 +4713,7 @@ You can use multiple property changes at once by providing multiple entries in t
4687
4713
  Some properties are nested, use the root property name, then objects with nested values inside, as the complete schema suggests.
4688
4714
 
4689
4715
  Make sure you have the "widget-schema-by-type" resource available to retrieve the PropType schema for the element type you are configuring.
4690
- Make sure you have to "styles-schema" resources available to retrieve the common styles schema.
4716
+ Make sure you have the "styles-schema" resources available to retrieve the common styles schema.
4691
4717
 
4692
4718
  # How to configure elements
4693
4719
  We use a dedicated PropType Schema for configuring elements, including styles. When you configure an element, you must use the EXACT PropType Value as defined in the schema.
@@ -4695,8 +4721,21 @@ For styleProperties, use the style schema provided, as it also uses the PropType
4695
4721
  For all non-primitive types, provide the key property as defined in the schema as $$type in the generated object, as it is MANDATORY for parsing.
4696
4722
 
4697
4723
  Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property from the original configuration for every property you are changing.
4698
-
4699
- # Example
4724
+ `);
4725
+ configureElementToolPrompt.parameter("elementId", "The ID of the element to configure. MANDATORY.");
4726
+ configureElementToolPrompt.parameter(
4727
+ "elementType",
4728
+ "The type of the element to configure (i.e. e-heading, e-button). MANDATORY."
4729
+ );
4730
+ configureElementToolPrompt.parameter(
4731
+ "propertiesToChange",
4732
+ "An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object."
4733
+ );
4734
+ configureElementToolPrompt.parameter(
4735
+ "stylePropertiesToChange",
4736
+ "An object containing the style properties to change, with their new values. OPTIONAL."
4737
+ );
4738
+ configureElementToolPrompt.example(`
4700
4739
  \`\`\`json
4701
4740
  {
4702
4741
  propertiesToChange: {
@@ -4712,7 +4751,7 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
4712
4751
  },
4713
4752
  stylePropertiesToChange: {
4714
4753
  'line-height': {
4715
- $$type: 'size', // MANDATORY do not forget to include the correct $$type for every property
4754
+ $$type: 'size',
4716
4755
  value: {
4717
4756
  size: {
4718
4757
  $$type: 'number',
@@ -4729,11 +4768,13 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
4729
4768
  elementType: 'element-type'
4730
4769
  };
4731
4770
  \`\`\`
4732
-
4733
- <IMPORTANT>
4734
- The $$type property is MANDATORY for every value, it is required to parse the value and apply application-level effects.
4735
- </IMPORTANT>
4736
- `;
4771
+ `);
4772
+ configureElementToolPrompt.instruction(
4773
+ "The $$type property is MANDATORY for every value; it is required to parse the value and apply application-level effects."
4774
+ );
4775
+ return configureElementToolPrompt.prompt();
4776
+ };
4777
+ var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt2();
4737
4778
 
4738
4779
  // src/mcp/tools/configure-element/schema.ts
4739
4780
  var import_schema3 = require("@elementor/schema");
@@ -4759,15 +4800,28 @@ var outputSchema2 = {
4759
4800
 
4760
4801
  // src/mcp/tools/configure-element/tool.ts
4761
4802
  var initConfigureElementTool = (reg) => {
4762
- const { addTool } = reg;
4803
+ const { addTool, resource } = reg;
4804
+ resource(
4805
+ "configure-element-guide",
4806
+ CONFIGURE_ELEMENT_GUIDE_URI,
4807
+ {
4808
+ title: "Configure Element Guide",
4809
+ description: "Detailed guide for using the configure-element tool",
4810
+ mimeType: "text/plain"
4811
+ },
4812
+ async (uri) => ({
4813
+ contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt2() }]
4814
+ })
4815
+ );
4763
4816
  addTool({
4764
4817
  name: "configure-element",
4765
- description: configureElementToolPrompt,
4818
+ description: "Configure an existing V4 element's properties and styles. Read the guide resource before use.",
4766
4819
  schema: inputSchema2,
4767
4820
  outputSchema: outputSchema2,
4768
4821
  requiredResources: [
4769
4822
  { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
4770
- { description: "Styles schema", uri: STYLE_SCHEMA_URI }
4823
+ { description: "Styles schema", uri: STYLE_SCHEMA_URI },
4824
+ { description: "Configure element guide", uri: CONFIGURE_ELEMENT_GUIDE_URI }
4771
4825
  ],
4772
4826
  modelPreferences: {
4773
4827
  hints: [{ name: "claude-sonnet-4-5" }],
@@ -4965,15 +5019,6 @@ var initGetElementConfigTool = (reg) => {
4965
5019
 
4966
5020
  // src/mcp/canvas-mcp.ts
4967
5021
  var initCanvasMcp = (reg) => {
4968
- const { setMCPDescription } = reg;
4969
- setMCPDescription(
4970
- `Everything related to V4 ( Atomic ) canvas.
4971
- # Canvas workflow for new compositions
4972
- - Configure elements settings and styles
4973
- - Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
4974
- - Get and retrieve element configuration values
4975
- `
4976
- );
4977
5022
  initWidgetsSchemaResource(reg);
4978
5023
  initAvailableWidgetsResource(reg);
4979
5024
  initDocumentStructureResource(reg);
@@ -5101,14 +5146,14 @@ Note: The "size" property controls image resolution/loading, not visual size. Se
5101
5146
  // src/prevent-link-in-link-commands.ts
5102
5147
  var import_editor_elements17 = require("@elementor/editor-elements");
5103
5148
  var import_editor_notifications3 = require("@elementor/editor-notifications");
5104
- var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
5149
+ var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
5105
5150
  var import_i18n4 = require("@wordpress/i18n");
5106
5151
  function initLinkInLinkPrevention() {
5107
- (0, import_editor_v1_adapters19.blockCommand)({
5152
+ (0, import_editor_v1_adapters20.blockCommand)({
5108
5153
  command: "document/elements/paste",
5109
5154
  condition: blockLinkInLinkPaste
5110
5155
  });
5111
- (0, import_editor_v1_adapters19.blockCommand)({
5156
+ (0, import_editor_v1_adapters20.blockCommand)({
5112
5157
  command: "document/elements/move",
5113
5158
  condition: blockLinkInLinkMove
5114
5159
  });
@@ -5184,7 +5229,7 @@ function shouldBlock(sourceElements, targetElements) {
5184
5229
  // src/style-commands/paste-style.ts
5185
5230
  var import_editor_elements20 = require("@elementor/editor-elements");
5186
5231
  var import_editor_props10 = require("@elementor/editor-props");
5187
- var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
5232
+ var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
5188
5233
 
5189
5234
  // src/utils/command-utils.ts
5190
5235
  var import_editor_elements18 = require("@elementor/editor-elements");
@@ -5231,9 +5276,9 @@ function getTitleForContainers(containers) {
5231
5276
  // src/style-commands/undoable-actions/paste-element-style.ts
5232
5277
  var import_editor_elements19 = require("@elementor/editor-elements");
5233
5278
  var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
5234
- var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
5279
+ var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
5235
5280
  var import_i18n6 = require("@wordpress/i18n");
5236
- var undoablePasteElementStyle = () => (0, import_editor_v1_adapters20.undoable)(
5281
+ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters21.undoable)(
5237
5282
  {
5238
5283
  do: ({ containers, newStyle }) => {
5239
5284
  return containers.map((container) => {
@@ -5309,12 +5354,12 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters20.undoable)(
5309
5354
  // src/style-commands/paste-style.ts
5310
5355
  function initPasteStyleCommand() {
5311
5356
  const pasteElementStyleCommand = undoablePasteElementStyle();
5312
- (0, import_editor_v1_adapters21.blockCommand)({
5357
+ (0, import_editor_v1_adapters22.blockCommand)({
5313
5358
  command: "document/elements/paste-style",
5314
5359
  condition: hasAtomicWidgets
5315
5360
  });
5316
- (0, import_editor_v1_adapters21.__privateListenTo)(
5317
- (0, import_editor_v1_adapters21.commandStartEvent)("document/elements/paste-style"),
5361
+ (0, import_editor_v1_adapters22.__privateListenTo)(
5362
+ (0, import_editor_v1_adapters22.commandStartEvent)("document/elements/paste-style"),
5318
5363
  (e) => pasteStyles(e.args, pasteElementStyleCommand)
5319
5364
  );
5320
5365
  }
@@ -5365,14 +5410,14 @@ function pasteClasses(containers, classes) {
5365
5410
  }
5366
5411
 
5367
5412
  // src/style-commands/reset-style.ts
5368
- var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
5413
+ var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
5369
5414
 
5370
5415
  // src/style-commands/undoable-actions/reset-element-style.ts
5371
5416
  var import_editor_elements21 = require("@elementor/editor-elements");
5372
5417
  var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
5373
- var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
5418
+ var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
5374
5419
  var import_i18n7 = require("@wordpress/i18n");
5375
- var undoableResetElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
5420
+ var undoableResetElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
5376
5421
  {
5377
5422
  do: ({ containers }) => {
5378
5423
  return containers.map((container) => {
@@ -5416,12 +5461,12 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
5416
5461
  // src/style-commands/reset-style.ts
5417
5462
  function initResetStyleCommand() {
5418
5463
  const resetElementStyles = undoableResetElementStyle();
5419
- (0, import_editor_v1_adapters23.blockCommand)({
5464
+ (0, import_editor_v1_adapters24.blockCommand)({
5420
5465
  command: "document/elements/reset-style",
5421
5466
  condition: hasAtomicWidgets
5422
5467
  });
5423
- (0, import_editor_v1_adapters23.__privateListenTo)(
5424
- (0, import_editor_v1_adapters23.commandStartEvent)("document/elements/reset-style"),
5468
+ (0, import_editor_v1_adapters24.__privateListenTo)(
5469
+ (0, import_editor_v1_adapters24.commandStartEvent)("document/elements/reset-style"),
5425
5470
  (e) => resetStyles(e.args, resetElementStyles)
5426
5471
  );
5427
5472
  }
@@ -5467,8 +5512,14 @@ function init() {
5467
5512
  component: ClassesRename
5468
5513
  });
5469
5514
  initCanvasMcp(
5470
- (0, import_editor_mcp3.getMCPByDomain)("canvas", {
5471
- instructions: mcpDescription
5515
+ (0, import_editor_mcp4.getMCPByDomain)("canvas", {
5516
+ instructions: `Everything related to V4 ( Atomic ) canvas.
5517
+ # Canvas workflow for new compositions
5518
+ - Configure elements settings and styles
5519
+ - Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
5520
+ - Get and retrieve element configuration values
5521
+ `,
5522
+ docs: mcpDescription
5472
5523
  })
5473
5524
  );
5474
5525
  initTabsModelExtensions();
package/dist/index.mjs CHANGED
@@ -64,6 +64,9 @@ function isWidgetAvailableForLLM(config) {
64
64
  if (config.meta?.llm_support === false) {
65
65
  return false;
66
66
  }
67
+ if (config.title === "Component") {
68
+ return false;
69
+ }
67
70
  if (config.atomic_props_schema) {
68
71
  return true;
69
72
  }
@@ -3853,7 +3856,7 @@ function getElementDisplayName(container) {
3853
3856
  import { getCurrentDocument } from "@elementor/editor-documents";
3854
3857
  import {
3855
3858
  createElement as createElement8,
3856
- deleteElement,
3859
+ deleteElement as deleteElement2,
3857
3860
  getContainer as getContainer5,
3858
3861
  getWidgetsCache as getWidgetsCache9
3859
3862
  } from "@elementor/editor-elements";
@@ -3861,6 +3864,7 @@ import {
3861
3864
  // src/composition-builder/composition-builder.ts
3862
3865
  import {
3863
3866
  createElement as createElement7,
3867
+ deleteElement,
3864
3868
  generateElementId as generateElementId2,
3865
3869
  getContainer as getContainer4,
3866
3870
  getWidgetsCache as getWidgetsCache8
@@ -3876,6 +3880,7 @@ import {
3876
3880
  } from "@elementor/editor-elements";
3877
3881
  import { getPropSchemaFromCache, Schema as Schema2 } from "@elementor/editor-props";
3878
3882
  import { getStylesSchema as getStylesSchema3 } from "@elementor/editor-styles";
3883
+ import { __privateRunCommandSync as runCommandSync2 } from "@elementor/editor-v1-adapters";
3879
3884
  function resolvePropValue(value, forceKey) {
3880
3885
  const Utils = window.elementorV2.editorVariables.Utils;
3881
3886
  return Schema2.adjustLlmPropValueSchema(value, {
@@ -3984,6 +3989,7 @@ var doUpdateElementProperty = (params) => {
3984
3989
  },
3985
3990
  withHistory: false
3986
3991
  });
3992
+ runCommandSync2("document/save/set-is-modified", { status: true }, { internal: true });
3987
3993
  };
3988
3994
 
3989
3995
  // src/mcp/utils/validate-input.ts
@@ -4079,6 +4085,7 @@ var CompositionBuilder = class _CompositionBuilder {
4079
4085
  rootContainers = [];
4080
4086
  api = {
4081
4087
  createElement: createElement7,
4088
+ deleteElement,
4082
4089
  getWidgetsCache: getWidgetsCache8,
4083
4090
  generateElementId: generateElementId2,
4084
4091
  getContainer: getContainer4,
@@ -4129,7 +4136,8 @@ var CompositionBuilder = class _CompositionBuilder {
4129
4136
  elements: children,
4130
4137
  editor_settings: {
4131
4138
  title: node.getAttribute("configuration-id") ?? void 0
4132
- }
4139
+ },
4140
+ elType: "widget"
4133
4141
  };
4134
4142
  if (isWidget) {
4135
4143
  return { ...base, elType: "widget", widgetType: elementTag };
@@ -4161,12 +4169,6 @@ var CompositionBuilder = class _CompositionBuilder {
4161
4169
  }
4162
4170
  return errors;
4163
4171
  }
4164
- findSchemaForNode(node) {
4165
- const widgetsCache = this.api.getWidgetsCache() || {};
4166
- const widgetType = node.tagName;
4167
- const widgetData = widgetsCache[widgetType]?.atomic_props_schema;
4168
- return widgetData || null;
4169
- }
4170
4172
  matchNodeByConfigId(configId) {
4171
4173
  const node = this.xml.querySelector(`[configuration-id="${configId}"]`);
4172
4174
  if (!node) {
@@ -4288,13 +4290,24 @@ ${childTypeErrors.join("\n")}`);
4288
4290
  const children = Array.from(this.xml.children);
4289
4291
  for (const childNode of children) {
4290
4292
  const modelTree = this.buildModelTree(childNode, widgetsCache);
4291
- const newElement = this.api.createElement({
4292
- container: rootContainer,
4293
- model: modelTree,
4294
- options: { useHistory: false }
4295
- });
4296
- this.rootContainers.push(newElement);
4297
- await this.awaitViewRender(newElement);
4293
+ try {
4294
+ const newElement = this.api.createElement({
4295
+ container: rootContainer,
4296
+ model: modelTree,
4297
+ options: { useHistory: false }
4298
+ });
4299
+ this.rootContainers.push(newElement);
4300
+ await this.awaitViewRender(newElement);
4301
+ } catch (e) {
4302
+ const attemptToRestoreInvalidContainer = this.api.getContainer(modelTree.id);
4303
+ if (attemptToRestoreInvalidContainer) {
4304
+ this.api.deleteElement({
4305
+ container: attemptToRestoreInvalidContainer,
4306
+ options: { useHistory: false }
4307
+ });
4308
+ }
4309
+ throw e;
4310
+ }
4298
4311
  }
4299
4312
  const { configErrors, styleErrors, invalidStyles } = await this.applyProperties();
4300
4313
  return {
@@ -4318,6 +4331,7 @@ function getCompositionTargetContainer(documentContainer, documentType) {
4318
4331
 
4319
4332
  // src/mcp/tools/build-composition/prompt.ts
4320
4333
  import { toolPrompts } from "@elementor/editor-mcp";
4334
+ var BUILD_COMPOSITIONS_GUIDE_URI = "elementor://canvas/tools/build-compositions-guide";
4321
4335
  var generatePrompt = () => {
4322
4336
  const buildCompositionsToolPrompt = toolPrompts("build-compositions");
4323
4337
  buildCompositionsToolPrompt.description(`
@@ -4499,12 +4513,25 @@ var outputSchema = {
4499
4513
 
4500
4514
  // src/mcp/tools/build-composition/tool.ts
4501
4515
  var initBuildCompositionsTool = (reg) => {
4502
- const { addTool } = reg;
4516
+ const { addTool, resource } = reg;
4517
+ resource(
4518
+ "build-compositions-guide",
4519
+ BUILD_COMPOSITIONS_GUIDE_URI,
4520
+ {
4521
+ title: "Build Compositions Guide",
4522
+ description: "Detailed guide for using the build-compositions tool",
4523
+ mimeType: "text/plain"
4524
+ },
4525
+ async (uri) => ({
4526
+ contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
4527
+ })
4528
+ );
4503
4529
  addTool({
4504
4530
  name: "build-compositions",
4505
- description: generatePrompt(),
4531
+ description: "Build V4 element compositions on the Elementor canvas. Read the guide resource before use.",
4506
4532
  schema: inputSchema,
4507
4533
  requiredResources: [
4534
+ { description: "Build compositions guide", uri: BUILD_COMPOSITIONS_GUIDE_URI },
4508
4535
  { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
4509
4536
  { description: "Styles schema", uri: STYLE_SCHEMA_URI },
4510
4537
  { description: "Global Classes", uri: "elementor://global-classes" },
@@ -4528,6 +4555,7 @@ var initBuildCompositionsTool = (reg) => {
4528
4555
  try {
4529
4556
  const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
4530
4557
  createElement: createElement8,
4558
+ deleteElement: deleteElement2,
4531
4559
  getWidgetsCache: getWidgetsCache9
4532
4560
  });
4533
4561
  compositionBuilder.setElementConfig(elementConfig);
@@ -4556,7 +4584,7 @@ var initBuildCompositionsTool = (reg) => {
4556
4584
  }
4557
4585
  if (errors.length) {
4558
4586
  rootContainers.forEach((rootContainer) => {
4559
- deleteElement({
4587
+ deleteElement2({
4560
4588
  container: rootContainer,
4561
4589
  options: { useHistory: false }
4562
4590
  });
@@ -4632,7 +4660,12 @@ function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
4632
4660
  import { getWidgetsCache as getWidgetsCache10 } from "@elementor/editor-elements";
4633
4661
 
4634
4662
  // src/mcp/tools/configure-element/prompt.ts
4635
- var configureElementToolPrompt = `Configure an existing element on the page.
4663
+ import { toolPrompts as toolPrompts2 } from "@elementor/editor-mcp";
4664
+ var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
4665
+ var generatePrompt2 = () => {
4666
+ const configureElementToolPrompt = toolPrompts2("configure-element");
4667
+ configureElementToolPrompt.description(`
4668
+ Configure an existing element on the page.
4636
4669
 
4637
4670
  # **CRITICAL - REQUIRED INFORMATION (Must read before using this tool)**
4638
4671
  1. [${WIDGET_SCHEMA_URI}]
@@ -4647,12 +4680,6 @@ Before using this tool, check the definitions of the elements PropTypes at the r
4647
4680
  All widgets share a common _style property for styling, which uses the common styles schema.
4648
4681
  Retrieve and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
4649
4682
 
4650
- # Parameters
4651
- - propertiesToChange: An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object.
4652
- - stylePropertiesToChange: An object containing the style properties to change, with their new values. OPTIONAL
4653
- - elementId: The ID of the element to configure. MANDATORY
4654
- - elementType: The type of the element to configure (i.e. e-heading, e-button). MANDATORY
4655
-
4656
4683
  # When to use this tool
4657
4684
  When a user requires to change anything in an element, such as updating text, colors, sizes, or other configurable properties.
4658
4685
  This tool handles elements of type "widget".
@@ -4681,7 +4708,7 @@ You can use multiple property changes at once by providing multiple entries in t
4681
4708
  Some properties are nested, use the root property name, then objects with nested values inside, as the complete schema suggests.
4682
4709
 
4683
4710
  Make sure you have the "widget-schema-by-type" resource available to retrieve the PropType schema for the element type you are configuring.
4684
- Make sure you have to "styles-schema" resources available to retrieve the common styles schema.
4711
+ Make sure you have the "styles-schema" resources available to retrieve the common styles schema.
4685
4712
 
4686
4713
  # How to configure elements
4687
4714
  We use a dedicated PropType Schema for configuring elements, including styles. When you configure an element, you must use the EXACT PropType Value as defined in the schema.
@@ -4689,8 +4716,21 @@ For styleProperties, use the style schema provided, as it also uses the PropType
4689
4716
  For all non-primitive types, provide the key property as defined in the schema as $$type in the generated object, as it is MANDATORY for parsing.
4690
4717
 
4691
4718
  Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property from the original configuration for every property you are changing.
4692
-
4693
- # Example
4719
+ `);
4720
+ configureElementToolPrompt.parameter("elementId", "The ID of the element to configure. MANDATORY.");
4721
+ configureElementToolPrompt.parameter(
4722
+ "elementType",
4723
+ "The type of the element to configure (i.e. e-heading, e-button). MANDATORY."
4724
+ );
4725
+ configureElementToolPrompt.parameter(
4726
+ "propertiesToChange",
4727
+ "An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object."
4728
+ );
4729
+ configureElementToolPrompt.parameter(
4730
+ "stylePropertiesToChange",
4731
+ "An object containing the style properties to change, with their new values. OPTIONAL."
4732
+ );
4733
+ configureElementToolPrompt.example(`
4694
4734
  \`\`\`json
4695
4735
  {
4696
4736
  propertiesToChange: {
@@ -4706,7 +4746,7 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
4706
4746
  },
4707
4747
  stylePropertiesToChange: {
4708
4748
  'line-height': {
4709
- $$type: 'size', // MANDATORY do not forget to include the correct $$type for every property
4749
+ $$type: 'size',
4710
4750
  value: {
4711
4751
  size: {
4712
4752
  $$type: 'number',
@@ -4723,11 +4763,13 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
4723
4763
  elementType: 'element-type'
4724
4764
  };
4725
4765
  \`\`\`
4726
-
4727
- <IMPORTANT>
4728
- The $$type property is MANDATORY for every value, it is required to parse the value and apply application-level effects.
4729
- </IMPORTANT>
4730
- `;
4766
+ `);
4767
+ configureElementToolPrompt.instruction(
4768
+ "The $$type property is MANDATORY for every value; it is required to parse the value and apply application-level effects."
4769
+ );
4770
+ return configureElementToolPrompt.prompt();
4771
+ };
4772
+ var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt2();
4731
4773
 
4732
4774
  // src/mcp/tools/configure-element/schema.ts
4733
4775
  import { z as z2 } from "@elementor/schema";
@@ -4753,15 +4795,28 @@ var outputSchema2 = {
4753
4795
 
4754
4796
  // src/mcp/tools/configure-element/tool.ts
4755
4797
  var initConfigureElementTool = (reg) => {
4756
- const { addTool } = reg;
4798
+ const { addTool, resource } = reg;
4799
+ resource(
4800
+ "configure-element-guide",
4801
+ CONFIGURE_ELEMENT_GUIDE_URI,
4802
+ {
4803
+ title: "Configure Element Guide",
4804
+ description: "Detailed guide for using the configure-element tool",
4805
+ mimeType: "text/plain"
4806
+ },
4807
+ async (uri) => ({
4808
+ contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt2() }]
4809
+ })
4810
+ );
4757
4811
  addTool({
4758
4812
  name: "configure-element",
4759
- description: configureElementToolPrompt,
4813
+ description: "Configure an existing V4 element's properties and styles. Read the guide resource before use.",
4760
4814
  schema: inputSchema2,
4761
4815
  outputSchema: outputSchema2,
4762
4816
  requiredResources: [
4763
4817
  { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
4764
- { description: "Styles schema", uri: STYLE_SCHEMA_URI }
4818
+ { description: "Styles schema", uri: STYLE_SCHEMA_URI },
4819
+ { description: "Configure element guide", uri: CONFIGURE_ELEMENT_GUIDE_URI }
4765
4820
  ],
4766
4821
  modelPreferences: {
4767
4822
  hints: [{ name: "claude-sonnet-4-5" }],
@@ -4959,15 +5014,6 @@ var initGetElementConfigTool = (reg) => {
4959
5014
 
4960
5015
  // src/mcp/canvas-mcp.ts
4961
5016
  var initCanvasMcp = (reg) => {
4962
- const { setMCPDescription } = reg;
4963
- setMCPDescription(
4964
- `Everything related to V4 ( Atomic ) canvas.
4965
- # Canvas workflow for new compositions
4966
- - Configure elements settings and styles
4967
- - Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
4968
- - Get and retrieve element configuration values
4969
- `
4970
- );
4971
5017
  initWidgetsSchemaResource(reg);
4972
5018
  initAvailableWidgetsResource(reg);
4973
5019
  initDocumentStructureResource(reg);
@@ -5479,7 +5525,13 @@ function init() {
5479
5525
  });
5480
5526
  initCanvasMcp(
5481
5527
  getMCPByDomain("canvas", {
5482
- instructions: mcpDescription
5528
+ instructions: `Everything related to V4 ( Atomic ) canvas.
5529
+ # Canvas workflow for new compositions
5530
+ - Configure elements settings and styles
5531
+ - Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
5532
+ - Get and retrieve element configuration values
5533
+ `,
5534
+ docs: mcpDescription
5483
5535
  })
5484
5536
  );
5485
5537
  initTabsModelExtensions();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-canvas",
3
3
  "description": "Elementor Editor Canvas",
4
- "version": "4.1.0-837",
4
+ "version": "4.1.0-beta1",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -37,25 +37,25 @@
37
37
  "react-dom": "^18.3.1"
38
38
  },
39
39
  "dependencies": {
40
- "@elementor/editor": "4.1.0-837",
40
+ "@elementor/editor": "4.1.0-beta1",
41
41
  "dompurify": "^3.2.6",
42
- "@elementor/editor-controls": "4.1.0-837",
43
- "@elementor/editor-documents": "4.1.0-837",
44
- "@elementor/editor-elements": "4.1.0-837",
45
- "@elementor/editor-interactions": "4.1.0-837",
46
- "@elementor/editor-mcp": "4.1.0-837",
47
- "@elementor/editor-notifications": "4.1.0-837",
48
- "@elementor/editor-props": "4.1.0-837",
49
- "@elementor/editor-responsive": "4.1.0-837",
50
- "@elementor/editor-styles": "4.1.0-837",
51
- "@elementor/editor-styles-repository": "4.1.0-837",
52
- "@elementor/editor-ui": "4.1.0-837",
53
- "@elementor/editor-v1-adapters": "4.1.0-837",
54
- "@elementor/schema": "4.1.0-837",
55
- "@elementor/twing": "4.1.0-837",
42
+ "@elementor/editor-controls": "4.1.0-beta1",
43
+ "@elementor/editor-documents": "4.1.0-beta1",
44
+ "@elementor/editor-elements": "4.1.0-beta1",
45
+ "@elementor/editor-interactions": "4.1.0-beta1",
46
+ "@elementor/editor-mcp": "4.1.0-beta1",
47
+ "@elementor/editor-notifications": "4.1.0-beta1",
48
+ "@elementor/editor-props": "4.1.0-beta1",
49
+ "@elementor/editor-responsive": "4.1.0-beta1",
50
+ "@elementor/editor-styles": "4.1.0-beta1",
51
+ "@elementor/editor-styles-repository": "4.1.0-beta1",
52
+ "@elementor/editor-ui": "4.1.0-beta1",
53
+ "@elementor/editor-v1-adapters": "4.1.0-beta1",
54
+ "@elementor/schema": "4.1.0-beta1",
55
+ "@elementor/twing": "4.1.0-beta1",
56
56
  "@elementor/ui": "1.37.5",
57
- "@elementor/utils": "4.1.0-837",
58
- "@elementor/wp-media": "4.1.0-837",
57
+ "@elementor/utils": "4.1.0-beta1",
58
+ "@elementor/wp-media": "4.1.0-beta1",
59
59
  "@floating-ui/react": "^0.27.5",
60
60
  "@wordpress/i18n": "^5.13.0"
61
61
  },
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  createElement,
3
3
  type CreateElementParams,
4
+ deleteElement,
4
5
  generateElementId,
5
6
  getContainer,
6
7
  getWidgetsCache,
7
8
  type V1Element,
8
9
  type V1ElementConfig,
10
+ type V1ElementModelProps,
9
11
  } from '@elementor/editor-elements';
10
12
  import { type z } from '@elementor/schema';
11
13
 
@@ -17,6 +19,7 @@ type AnyConfig = Record< string, Record< string, AnyValue > >;
17
19
 
18
20
  type API = {
19
21
  createElement: typeof createElement;
22
+ deleteElement: typeof deleteElement;
20
23
  getWidgetsCache: typeof getWidgetsCache;
21
24
  generateElementId: typeof generateElementId;
22
25
  getContainer: typeof getContainer;
@@ -38,6 +41,7 @@ export class CompositionBuilder {
38
41
  private rootContainers: V1Element[] = [];
39
42
  private api: API = {
40
43
  createElement,
44
+ deleteElement,
41
45
  getWidgetsCache,
42
46
  generateElementId,
43
47
  getContainer,
@@ -94,15 +98,26 @@ export class CompositionBuilder {
94
98
 
95
99
  node.setAttribute( 'id', id );
96
100
 
97
- const base = {
101
+ const base: V1ElementModelProps = {
98
102
  id,
99
103
  skipDefaultChildren: true,
100
- elements: children,
104
+ elements: children as V1ElementModelProps[ 'elements' ],
101
105
  editor_settings: {
102
106
  title: node.getAttribute( 'configuration-id' ) ?? undefined,
103
107
  },
108
+ elType: 'widget',
104
109
  };
105
110
 
111
+ // TODO: Restore this code once components are working in compositions
112
+ // if ( elementTag === 'e-component' ) {
113
+ // // apply component id before applying values
114
+ // const elementConfig = this.elementConfig[ String( node.getAttribute( 'configuration-id' ) ) ];
115
+ // if ( elementConfig ) {
116
+ // base.settings = base.settings || {};
117
+ // base.settings.component_instance = elementConfig.component_instance;
118
+ // }
119
+ // }
120
+
106
121
  if ( isWidget ) {
107
122
  return { ...base, elType: 'widget' as const, widgetType: elementTag };
108
123
  }
@@ -142,13 +157,6 @@ export class CompositionBuilder {
142
157
  return errors;
143
158
  }
144
159
 
145
- private findSchemaForNode( node: Element ) {
146
- const widgetsCache = this.api.getWidgetsCache() || {};
147
- const widgetType = node.tagName;
148
- const widgetData = widgetsCache[ widgetType ]?.atomic_props_schema;
149
- return widgetData || null;
150
- }
151
-
152
160
  private matchNodeByConfigId( configId: string ) {
153
161
  const node = this.xml.querySelector( `[configuration-id="${ configId }"]` );
154
162
  if ( ! node ) {
@@ -282,15 +290,24 @@ export class CompositionBuilder {
282
290
  for ( const childNode of children ) {
283
291
  const modelTree = this.buildModelTree( childNode, widgetsCache );
284
292
 
285
- const newElement = this.api.createElement( {
286
- container: rootContainer,
287
- model: modelTree as CreateElementParams[ 'model' ],
288
- options: { useHistory: false },
289
- } );
290
-
291
- this.rootContainers.push( newElement );
292
-
293
- await this.awaitViewRender( newElement );
293
+ try {
294
+ const newElement = this.api.createElement( {
295
+ container: rootContainer,
296
+ model: modelTree as CreateElementParams[ 'model' ],
297
+ options: { useHistory: false },
298
+ } );
299
+ this.rootContainers.push( newElement );
300
+ await this.awaitViewRender( newElement );
301
+ } catch ( e: unknown ) {
302
+ const attemptToRestoreInvalidContainer = this.api.getContainer( modelTree.id as string );
303
+ if ( attemptToRestoreInvalidContainer ) {
304
+ this.api.deleteElement( {
305
+ container: attemptToRestoreInvalidContainer,
306
+ options: { useHistory: false },
307
+ } );
308
+ }
309
+ throw e;
310
+ }
294
311
  }
295
312
 
296
313
  const { configErrors, styleErrors, invalidStyles } = await this.applyProperties();
package/src/init.tsx CHANGED
@@ -53,7 +53,13 @@ export function init() {
53
53
 
54
54
  initCanvasMcp(
55
55
  getMCPByDomain( 'canvas', {
56
- instructions: mcpDescription,
56
+ instructions: `Everything related to V4 ( Atomic ) canvas.
57
+ # Canvas workflow for new compositions
58
+ - Configure elements settings and styles
59
+ - Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
60
+ - Get and retrieve element configuration values
61
+ `,
62
+ docs: mcpDescription,
57
63
  } )
58
64
  );
59
65
 
@@ -12,15 +12,6 @@ import { initConfigureElementTool } from './tools/configure-element/tool';
12
12
  import { initGetElementConfigTool } from './tools/get-element-config/tool';
13
13
 
14
14
  export const initCanvasMcp = ( reg: MCPRegistryEntry ) => {
15
- const { setMCPDescription } = reg;
16
- setMCPDescription(
17
- `Everything related to V4 ( Atomic ) canvas.
18
- # Canvas workflow for new compositions
19
- - Configure elements settings and styles
20
- - Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
21
- - Get and retrieve element configuration values
22
- `
23
- );
24
15
  initWidgetsSchemaResource( reg );
25
16
  initAvailableWidgetsResource( reg );
26
17
  initDocumentStructureResource( reg );
@@ -2,6 +2,8 @@ import { toolPrompts } from '@elementor/editor-mcp';
2
2
 
3
3
  import { AVAILABLE_WIDGETS_URI } from '../../resources/available-widgets-resource';
4
4
 
5
+ export const BUILD_COMPOSITIONS_GUIDE_URI = 'elementor://canvas/tools/build-compositions-guide';
6
+
5
7
  export const generatePrompt = () => {
6
8
  const buildCompositionsToolPrompt = toolPrompts( 'build-compositions' );
7
9
 
@@ -13,17 +13,31 @@ import { AVAILABLE_WIDGETS_URI_V4 } from '../../resources/available-widgets-reso
13
13
  import { BEST_PRACTICES_URI, STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
14
14
  import { doUpdateElementProperty } from '../../utils/do-update-element-property';
15
15
  import { getCompositionTargetContainer } from '../../utils/get-composition-target-container';
16
- import { generatePrompt } from './prompt';
16
+ import { BUILD_COMPOSITIONS_GUIDE_URI, generatePrompt } from './prompt';
17
17
  import { inputSchema as schema, outputSchema } from './schema';
18
18
 
19
19
  export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
20
- const { addTool } = reg;
20
+ const { addTool, resource } = reg;
21
+
22
+ resource(
23
+ 'build-compositions-guide',
24
+ BUILD_COMPOSITIONS_GUIDE_URI,
25
+ {
26
+ title: 'Build Compositions Guide',
27
+ description: 'Detailed guide for using the build-compositions tool',
28
+ mimeType: 'text/plain',
29
+ },
30
+ async ( uri: URL ) => ( {
31
+ contents: [ { uri: uri.href, mimeType: 'text/plain', text: generatePrompt() } ],
32
+ } )
33
+ );
21
34
 
22
35
  addTool( {
23
36
  name: 'build-compositions',
24
- description: generatePrompt(),
37
+ description: 'Build V4 element compositions on the Elementor canvas. Read the guide resource before use.',
25
38
  schema,
26
39
  requiredResources: [
40
+ { description: 'Build compositions guide', uri: BUILD_COMPOSITIONS_GUIDE_URI },
27
41
  { description: 'Widgets schema', uri: WIDGET_SCHEMA_URI },
28
42
  { description: 'Styles schema', uri: STYLE_SCHEMA_URI },
29
43
  { description: 'Global Classes', uri: 'elementor://global-classes' },
@@ -47,6 +61,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
47
61
  try {
48
62
  const compositionBuilder = CompositionBuilder.fromXMLString( xmlStructure, {
49
63
  createElement,
64
+ deleteElement,
50
65
  getWidgetsCache,
51
66
  } );
52
67
  compositionBuilder.setElementConfig( elementConfig );
@@ -1,6 +1,14 @@
1
+ import { toolPrompts } from '@elementor/editor-mcp';
2
+
1
3
  import { STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
2
4
 
3
- export const configureElementToolPrompt = `Configure an existing element on the page.
5
+ export const CONFIGURE_ELEMENT_GUIDE_URI = 'elementor://canvas/tools/configure-element-guide';
6
+
7
+ export const generatePrompt = () => {
8
+ const configureElementToolPrompt = toolPrompts( 'configure-element' );
9
+
10
+ configureElementToolPrompt.description( `
11
+ Configure an existing element on the page.
4
12
 
5
13
  # **CRITICAL - REQUIRED INFORMATION (Must read before using this tool)**
6
14
  1. [${ WIDGET_SCHEMA_URI }]
@@ -15,12 +23,6 @@ Before using this tool, check the definitions of the elements PropTypes at the r
15
23
  All widgets share a common _style property for styling, which uses the common styles schema.
16
24
  Retrieve and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
17
25
 
18
- # Parameters
19
- - propertiesToChange: An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object.
20
- - stylePropertiesToChange: An object containing the style properties to change, with their new values. OPTIONAL
21
- - elementId: The ID of the element to configure. MANDATORY
22
- - elementType: The type of the element to configure (i.e. e-heading, e-button). MANDATORY
23
-
24
26
  # When to use this tool
25
27
  When a user requires to change anything in an element, such as updating text, colors, sizes, or other configurable properties.
26
28
  This tool handles elements of type "widget".
@@ -49,7 +51,7 @@ You can use multiple property changes at once by providing multiple entries in t
49
51
  Some properties are nested, use the root property name, then objects with nested values inside, as the complete schema suggests.
50
52
 
51
53
  Make sure you have the "widget-schema-by-type" resource available to retrieve the PropType schema for the element type you are configuring.
52
- Make sure you have to "styles-schema" resources available to retrieve the common styles schema.
54
+ Make sure you have the "styles-schema" resources available to retrieve the common styles schema.
53
55
 
54
56
  # How to configure elements
55
57
  We use a dedicated PropType Schema for configuring elements, including styles. When you configure an element, you must use the EXACT PropType Value as defined in the schema.
@@ -57,8 +59,26 @@ For styleProperties, use the style schema provided, as it also uses the PropType
57
59
  For all non-primitive types, provide the key property as defined in the schema as $$type in the generated object, as it is MANDATORY for parsing.
58
60
 
59
61
  Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property from the original configuration for every property you are changing.
62
+ ` );
63
+
64
+ configureElementToolPrompt.parameter( 'elementId', 'The ID of the element to configure. MANDATORY.' );
65
+
66
+ configureElementToolPrompt.parameter(
67
+ 'elementType',
68
+ 'The type of the element to configure (i.e. e-heading, e-button). MANDATORY.'
69
+ );
70
+
71
+ configureElementToolPrompt.parameter(
72
+ 'propertiesToChange',
73
+ 'An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object.'
74
+ );
60
75
 
61
- # Example
76
+ configureElementToolPrompt.parameter(
77
+ 'stylePropertiesToChange',
78
+ 'An object containing the style properties to change, with their new values. OPTIONAL.'
79
+ );
80
+
81
+ configureElementToolPrompt.example( `
62
82
  \`\`\`json
63
83
  {
64
84
  propertiesToChange: {
@@ -74,7 +94,7 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
74
94
  },
75
95
  stylePropertiesToChange: {
76
96
  'line-height': {
77
- $$type: 'size', // MANDATORY do not forget to include the correct $$type for every property
97
+ $$type: 'size',
78
98
  value: {
79
99
  size: {
80
100
  $$type: 'number',
@@ -91,8 +111,13 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
91
111
  elementType: 'element-type'
92
112
  };
93
113
  \`\`\`
114
+ ` );
94
115
 
95
- <IMPORTANT>
96
- The $$type property is MANDATORY for every value, it is required to parse the value and apply application-level effects.
97
- </IMPORTANT>
98
- `;
116
+ configureElementToolPrompt.instruction(
117
+ 'The $$type property is MANDATORY for every value; it is required to parse the value and apply application-level effects.'
118
+ );
119
+
120
+ return configureElementToolPrompt.prompt();
121
+ };
122
+
123
+ export const CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt();
@@ -4,20 +4,34 @@ import { type MCPRegistryEntry } from '@elementor/editor-mcp';
4
4
  import { STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
5
5
  import { doUpdateElementProperty } from '../../utils/do-update-element-property';
6
6
  import { validateInput } from '../../utils/validate-input';
7
- import { configureElementToolPrompt } from './prompt';
7
+ import { CONFIGURE_ELEMENT_GUIDE_URI, generatePrompt } from './prompt';
8
8
  import { inputSchema as schema, outputSchema } from './schema';
9
9
 
10
10
  export const initConfigureElementTool = ( reg: MCPRegistryEntry ) => {
11
- const { addTool } = reg;
11
+ const { addTool, resource } = reg;
12
+
13
+ resource(
14
+ 'configure-element-guide',
15
+ CONFIGURE_ELEMENT_GUIDE_URI,
16
+ {
17
+ title: 'Configure Element Guide',
18
+ description: 'Detailed guide for using the configure-element tool',
19
+ mimeType: 'text/plain',
20
+ },
21
+ async ( uri: URL ) => ( {
22
+ contents: [ { uri: uri.href, mimeType: 'text/plain', text: generatePrompt() } ],
23
+ } )
24
+ );
12
25
 
13
26
  addTool( {
14
27
  name: 'configure-element',
15
- description: configureElementToolPrompt,
28
+ description: "Configure an existing V4 element's properties and styles. Read the guide resource before use.",
16
29
  schema,
17
30
  outputSchema,
18
31
  requiredResources: [
19
32
  { description: 'Widgets schema', uri: WIDGET_SCHEMA_URI },
20
33
  { description: 'Styles schema', uri: STYLE_SCHEMA_URI },
34
+ { description: 'Configure element guide', uri: CONFIGURE_ELEMENT_GUIDE_URI },
21
35
  ],
22
36
  modelPreferences: {
23
37
  hints: [ { name: 'claude-sonnet-4-5' } ],
@@ -7,6 +7,7 @@ import {
7
7
  } from '@elementor/editor-elements';
8
8
  import { getPropSchemaFromCache, type PropValue, Schema, type TransformablePropValue } from '@elementor/editor-props';
9
9
  import { type CustomCss, getStylesSchema } from '@elementor/editor-styles';
10
+ import { __privateRunCommandSync as runCommandSync } from '@elementor/editor-v1-adapters';
10
11
  import { type Utils as IUtils } from '@elementor/editor-variables';
11
12
  import { type z } from '@elementor/schema';
12
13
 
@@ -135,4 +136,5 @@ export const doUpdateElementProperty = ( params: OwnParams ) => {
135
136
  },
136
137
  withHistory: false,
137
138
  } );
139
+ runCommandSync( 'document/save/set-is-modified', { status: true }, { internal: true } );
138
140
  };
@@ -17,6 +17,10 @@ export function isWidgetAvailableForLLM( config: V1ElementConfig | undefined ):
17
17
  if ( config.meta?.llm_support === false ) {
18
18
  return false;
19
19
  }
20
+ // TODO: Restore component once working in compositions
21
+ if ( config.title === 'Component' ) {
22
+ return false;
23
+ }
20
24
  if ( config.atomic_props_schema ) {
21
25
  return true;
22
26
  }