@elementor/editor-canvas 4.3.0-993 → 4.3.0-995

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.mjs CHANGED
@@ -1806,46 +1806,6 @@ function clipboardRootsAreAtomicForms(elements) {
1806
1806
  }
1807
1807
  return elements.every((el) => getClipboardElementType(el) === FORM_ELEMENT_TYPE);
1808
1808
  }
1809
- function hasFormAncestor(node) {
1810
- return node.closest(FORM_ELEMENT_TYPE) !== null;
1811
- }
1812
- function collectFormAncestorErrors(xml) {
1813
- const errors = [];
1814
- for (const node of xml.querySelectorAll("*")) {
1815
- if (!FORM_FIELD_ELEMENT_TYPES.has(node.tagName.toLowerCase())) {
1816
- continue;
1817
- }
1818
- if (hasFormAncestor(node)) {
1819
- continue;
1820
- }
1821
- const id = node.getAttribute("configuration-id");
1822
- errors.push(
1823
- `<${node.tagName}${id ? ` configuration-id="${id}"` : ""}> must be nested inside <e-form> (any ancestor depth is allowed).`
1824
- );
1825
- }
1826
- return errors;
1827
- }
1828
- function collectSubmitButtonErrors(xml) {
1829
- const errors = [];
1830
- for (const form of xml.querySelectorAll("e-form")) {
1831
- const submitButtons = form.querySelectorAll("e-form-submit-button");
1832
- if (submitButtons.length === 0) {
1833
- errors.push(`<e-form> has no <e-form-submit-button>.`);
1834
- } else if (submitButtons.length > 1) {
1835
- errors.push(`<e-form> has ${submitButtons.length} submit buttons \u2014 only 1 is allowed.`);
1836
- }
1837
- }
1838
- return errors;
1839
- }
1840
- function collectEmptyMessageErrors(xml) {
1841
- const errors = [];
1842
- for (const node of xml.querySelectorAll("e-form-success-message, e-form-error-message")) {
1843
- if (node.children.length === 0) {
1844
- errors.push(`<${node.tagName}> must have at least one child element (e.g. <e-atomic-paragraph>).`);
1845
- }
1846
- }
1847
- return errors;
1848
- }
1849
1809
 
1850
1810
  // src/form-structure/enforce-form-ancestor-commands.ts
1851
1811
  var FORM_FIELDS_OUTSIDE_ALERT = {
@@ -4486,23 +4446,100 @@ function getElementDisplayName(container) {
4486
4446
  }
4487
4447
 
4488
4448
  // src/mcp/tools/build-composition/tool.ts
4489
- import { getCurrentDocument } from "@elementor/editor-documents";
4490
- import {
4491
- createElement as createElement13,
4492
- deleteElement as deleteElement2,
4493
- getContainer as getContainer5,
4494
- getWidgetsCache as getWidgetsCache8
4495
- } from "@elementor/editor-elements";
4496
- import { dispatchMcpStylesAppliedEvent } from "@elementor/editor-mcp";
4449
+ import { getCurrentDocument, reloadCurrentDocument } from "@elementor/editor-documents";
4450
+ import { getContainer as getContainer4, selectElement } from "@elementor/editor-elements";
4451
+ import { AxiosError, httpService as httpService6 } from "@elementor/http-client";
4452
+ import { z } from "@elementor/schema";
4453
+ var MCP_PROXY_URL5 = "elementor/v1/mcp-proxy";
4454
+ var initBuildCompositionTool = (reg) => {
4455
+ const { addTool } = reg;
4456
+ addTool({
4457
+ name: "build-composition",
4458
+ description: "Build a V4 element composition on the Elementor canvas via the server-side MCP ability. Pass the raw XML tags directly as xmlStructure \u2014 do NOT wrap the value in <![CDATA[ ... ]]>, code fences, or quotes. The document is saved as a draft. Reload the editor after calling this tool to see the result.",
4459
+ schema: {
4460
+ xmlStructure: z.string().describe(
4461
+ 'Valid XML structure with custom Elementor widget tags. Every element MUST have a unique configuration-id attribute (e.g. <e-heading configuration-id="hero-title"></e-heading>). No attributes, classes, IDs, or text nodes in XML. Pass raw XML \u2014 do not wrap in CDATA.'
4462
+ ),
4463
+ elementConfig: z.record(
4464
+ z.string().describe("configuration-id"),
4465
+ z.record(z.string().describe("property name"), z.any().describe("PropValue"))
4466
+ ).optional().describe("Map configuration-id \u2192 widget PropValues ($$type + value)."),
4467
+ style: z.record(
4468
+ z.string().describe("configuration-id"),
4469
+ z.record(z.string().describe("CSS property name"), z.string().describe("CSS value"))
4470
+ ).optional().describe(
4471
+ "Map configuration-id \u2192 raw CSS declarations (property \u2192 value strings; no selectors). Server converts to native styles; unconvertible declarations become the element custom CSS."
4472
+ ),
4473
+ parentId: z.string().optional().describe("ID of the parent container. Omit or pass 'document' to insert at document root."),
4474
+ dryRun: z.boolean().optional().describe("If true, validate and return the resolved tree without persisting.")
4475
+ },
4476
+ outputSchema: {
4477
+ rootElementIds: z.array(z.string()),
4478
+ previewUrl: z.string(),
4479
+ version: z.string(),
4480
+ resolvedXml: z.string(),
4481
+ llmInstructions: z.string(),
4482
+ warnings: z.array(z.string()).optional()
4483
+ },
4484
+ handler: async ({ xmlStructure, elementConfig, style, parentId, dryRun }) => {
4485
+ const document2 = getCurrentDocument();
4486
+ if (!document2?.id) {
4487
+ throw new Error("No active document found.");
4488
+ }
4489
+ try {
4490
+ const { data } = await httpService6().post(MCP_PROXY_URL5, {
4491
+ tool: "build-composition",
4492
+ input: {
4493
+ post_id: document2.id,
4494
+ xml_structure: xmlStructure,
4495
+ element_config: elementConfig ?? {},
4496
+ style: style ?? {},
4497
+ parent_id: parentId ?? "document",
4498
+ dry_run: dryRun ?? false
4499
+ }
4500
+ });
4501
+ if (!dryRun) {
4502
+ await reloadCurrentDocument();
4503
+ const [firstRootId] = data.data.root_element_ids;
4504
+ if (firstRootId) {
4505
+ selectElement(firstRootId);
4506
+ getContainer4(firstRootId)?.view?.el?.scrollIntoView({
4507
+ behavior: "smooth",
4508
+ block: "center"
4509
+ });
4510
+ }
4511
+ }
4512
+ return {
4513
+ rootElementIds: data.data.root_element_ids,
4514
+ previewUrl: data.data.preview_url,
4515
+ version: data.data.version,
4516
+ resolvedXml: data.data.resolved_xml,
4517
+ llmInstructions: data.data.llm_instructions,
4518
+ warnings: data.data.warnings
4519
+ };
4520
+ } catch (error) {
4521
+ throw new Error(getErrorMessage(error));
4522
+ }
4523
+ }
4524
+ });
4525
+ };
4526
+ function getErrorMessage(error) {
4527
+ if (error instanceof AxiosError) {
4528
+ const data = error.response?.data;
4529
+ if (data?.message) {
4530
+ return data.code ? `${data.code}: ${data.message}` : data.message;
4531
+ }
4532
+ }
4533
+ if (error instanceof Error) {
4534
+ return error.message;
4535
+ }
4536
+ return "build-composition failed with an unknown error.";
4537
+ }
4497
4538
 
4498
- // src/composition-builder/composition-builder.ts
4499
- import {
4500
- createElement as createElement12,
4501
- deleteElement,
4502
- generateElementId as generateElementId2,
4503
- getContainer as getContainer4,
4504
- getWidgetsCache as getWidgetsCache6
4505
- } from "@elementor/editor-elements";
4539
+ // src/mcp/tools/configure-element/tool.ts
4540
+ import { getContainer as getContainer5, getWidgetsCache as getWidgetsCache6 } from "@elementor/editor-elements";
4541
+ import { dispatchMcpStylesAppliedEvent } from "@elementor/editor-mcp";
4542
+ import { Schema as Schema2 } from "@elementor/editor-props";
4506
4543
 
4507
4544
  // src/mcp/utils/do-update-element-property.ts
4508
4545
  import {
@@ -4782,782 +4819,11 @@ Expected Schema: ${jsonSchema}`
4782
4819
  runCommandSync2("document/save/set-is-modified", { status: true }, { internal: true });
4783
4820
  };
4784
4821
 
4785
- // src/composition-builder/utils/required-default-child-tags.ts
4786
- function getRequiredDefaultChildTemplates(elementConfig) {
4787
- const defaultChildren = elementConfig?.default_children;
4788
- if (!Array.isArray(defaultChildren)) {
4789
- return [];
4790
- }
4791
- return defaultChildren.filter((child) => child?.meta?.required ?? false);
4792
- }
4793
-
4794
- // src/composition-builder/utils/required-children-enforcer.ts
4795
- var REQUIRED_CHILD_SCHEMA_HINT = "Use the widget schema resource; under llm_guidance.required_direct_children for V4 widgets.";
4796
- var RequiredChildrenEnforcer = class {
4797
- elementType;
4798
- requiredTemplates;
4799
- constructor(elementType, widgetsCache) {
4800
- this.elementType = elementType;
4801
- this.requiredTemplates = getRequiredDefaultChildTemplates(widgetsCache[elementType]);
4802
- }
4803
- enforce(xml) {
4804
- if (this.requiredTemplates.length === 0) {
4805
- return;
4806
- }
4807
- const errors = [];
4808
- for (const rootNode of Array.from(xml.children)) {
4809
- this.collectMissingRequiredErrors(rootNode, errors);
4810
- }
4811
- if (errors.length) {
4812
- throw new Error(`${errors.join("\n")}
4813
- ${REQUIRED_CHILD_SCHEMA_HINT}`);
4814
- }
4815
- }
4816
- collectMissingRequiredErrors(node, errors) {
4817
- if (node.tagName === this.elementType) {
4818
- const existingChildTags = new Set(Array.from(node.children).map((child) => child.tagName));
4819
- const missingTags = this.requiredTemplates.map((child) => child.widgetType ?? child.elType ?? "").filter((type) => type && !existingChildTags.has(type));
4820
- if (missingTags.length) {
4821
- const configurationId = node.getAttribute("configuration-id");
4822
- const location2 = configurationId ? `<${node.tagName} configuration-id="${configurationId}">` : `<${node.tagName}>`;
4823
- errors.push(
4824
- `${location2} Missing required direct child element tag(s): ${missingTags.join(", ")}.`
4825
- );
4826
- }
4827
- }
4828
- for (const childNode of Array.from(node.children)) {
4829
- this.collectMissingRequiredErrors(childNode, errors);
4830
- }
4831
- }
4832
- };
4833
-
4834
- // src/composition-builder/composition-builder.ts
4835
- var CREATE_ELEMENT_INVALID_CONTAINER_MESSAGE = "createElement did not return an element container with a model.";
4836
- var CompositionBuilder = class _CompositionBuilder {
4837
- elementConfig = {};
4838
- elementStylesConfig = {};
4839
- elementCustomCSS = {};
4840
- rootContainers = [];
4841
- api = {
4842
- createElement: createElement12,
4843
- deleteElement,
4844
- getWidgetsCache: getWidgetsCache6,
4845
- generateElementId: generateElementId2,
4846
- getContainer: getContainer4,
4847
- doUpdateElementProperty
4848
- };
4849
- xml;
4850
- static fromXMLString(xmlString, api = {}) {
4851
- const parser = new DOMParser();
4852
- const xmlDoc = parser.parseFromString(xmlString, "application/xml");
4853
- const errorNode = xmlDoc.querySelector("parsererror");
4854
- if (errorNode) {
4855
- throw new Error("Failed to parse XML string: " + errorNode.textContent);
4856
- }
4857
- return new _CompositionBuilder({
4858
- xml: xmlDoc,
4859
- api
4860
- });
4861
- }
4862
- constructor(opts) {
4863
- const { api = {}, elementConfig = {}, stylesConfig = {}, customCSS = {}, xml } = opts;
4864
- this.xml = xml;
4865
- Object.assign(this.api, api);
4866
- this.setElementConfig(elementConfig);
4867
- this.setStylesConfig(stylesConfig);
4868
- this.setCustomCSS(customCSS);
4869
- }
4870
- setElementConfig(config) {
4871
- this.elementConfig = config;
4872
- }
4873
- setStylesConfig(config) {
4874
- this.elementStylesConfig = config;
4875
- }
4876
- setCustomCSS(config) {
4877
- this.elementCustomCSS = config;
4878
- }
4879
- getXML() {
4880
- return this.xml;
4881
- }
4882
- buildModelTree(node, widgetsCache) {
4883
- const elementTag = node.tagName;
4884
- const isWidget = widgetsCache[elementTag]?.elType === "widget";
4885
- const id = this.api.generateElementId();
4886
- const children = Array.from(node.children).map((child) => this.buildModelTree(child, widgetsCache));
4887
- node.setAttribute("id", id);
4888
- const base = {
4889
- id,
4890
- skipDefaultChildren: true,
4891
- elements: children,
4892
- editor_settings: {
4893
- title: node.getAttribute("configuration-id") ?? void 0
4894
- },
4895
- elType: "widget"
4896
- };
4897
- if (isWidget) {
4898
- return { ...base, elType: "widget", widgetType: elementTag };
4899
- }
4900
- return { ...base, elType: elementTag };
4901
- }
4902
- async awaitViewRender(element) {
4903
- const view = element.view;
4904
- if (view?._currentRenderPromise instanceof Promise) {
4905
- await view._currentRenderPromise;
4906
- } else {
4907
- await Promise.resolve();
4908
- }
4909
- }
4910
- validateChildTypes(node, widgetsCache) {
4911
- const errors = [];
4912
- const allowedChildTypes = widgetsCache[node.tagName]?.allowed_child_types;
4913
- if (allowedChildTypes?.length) {
4914
- for (const child of Array.from(node.children)) {
4915
- if (!allowedChildTypes.includes(child.tagName)) {
4916
- errors.push(
4917
- `"${child.tagName}" is not allowed as a child of "${node.tagName}". Allowed: ${allowedChildTypes.join(", ")}`
4918
- );
4919
- }
4920
- }
4921
- }
4922
- for (const child of Array.from(node.children)) {
4923
- errors.push(...this.validateChildTypes(child, widgetsCache));
4924
- }
4925
- return errors;
4926
- }
4927
- matchNodeByConfigId(configId) {
4928
- const node = this.xml.querySelector(`[configuration-id="${configId}"]`);
4929
- if (!node) {
4930
- throw new Error(`Configuration id "${configId}" does not have target node.`);
4931
- }
4932
- const id = node.getAttribute("id");
4933
- if (!id) {
4934
- throw new Error(`Node with configuration id "${configId}" does not have element id.`);
4935
- }
4936
- const element = this.api.getContainer(id);
4937
- if (!element) {
4938
- throw new Error(`Element with id "${id}" not found but should exist.`);
4939
- }
4940
- return {
4941
- element,
4942
- node
4943
- };
4944
- }
4945
- async applyProperties() {
4946
- const configErrors = [];
4947
- const styleErrors = [];
4948
- const allConfigIds = /* @__PURE__ */ new Set([
4949
- ...Object.keys(this.elementConfig),
4950
- ...Object.keys(this.elementStylesConfig),
4951
- ...Object.keys(this.elementCustomCSS)
4952
- ]);
4953
- for (const configId of allConfigIds) {
4954
- let element, node;
4955
- try {
4956
- ({ element, node } = this.matchNodeByConfigId(configId));
4957
- } catch (matchErr) {
4958
- const msg = matchErr.message;
4959
- if (this.elementConfig[configId]) {
4960
- configErrors.push(msg);
4961
- }
4962
- if (this.elementStylesConfig[configId] || this.elementCustomCSS[configId]) {
4963
- styleErrors.push(msg);
4964
- }
4965
- continue;
4966
- }
4967
- const config = this.elementConfig[configId];
4968
- if (config) {
4969
- for (const [propertyName, propertyValue] of Object.entries(config)) {
4970
- try {
4971
- this.api.doUpdateElementProperty({
4972
- elementId: element.id,
4973
- propertyName,
4974
- propertyValue,
4975
- elementType: node.tagName
4976
- });
4977
- } catch (error) {
4978
- configErrors.push(error.message);
4979
- }
4980
- }
4981
- }
4982
- const styleConfig = this.elementStylesConfig[configId];
4983
- const hasInvalidStyles = false;
4984
- if (styleConfig) {
4985
- const validStylesPropValues = {};
4986
- for (const [styleName, stylePropValue] of Object.entries(styleConfig)) {
4987
- if (styleName === "$intention") {
4988
- continue;
4989
- } else {
4990
- validStylesPropValues[styleName] = stylePropValue;
4991
- }
4992
- }
4993
- if (Object.keys(validStylesPropValues).length > 0) {
4994
- try {
4995
- this.api.doUpdateElementProperty({
4996
- elementId: element.id,
4997
- propertyName: "_styles",
4998
- propertyValue: validStylesPropValues,
4999
- elementType: node.tagName
5000
- });
5001
- } catch (error) {
5002
- styleErrors.push(String(error));
5003
- }
5004
- }
5005
- }
5006
- const intentionCss = typeof styleConfig?.$intention === "string" ? styleConfig.$intention.trim() : "";
5007
- const fallbackCss = hasInvalidStyles && intentionCss ? intentionCss : "";
5008
- const mergedCustomCss = mergeCustomCssText(this.elementCustomCSS[configId], fallbackCss);
5009
- if (mergedCustomCss) {
5010
- try {
5011
- this.api.doUpdateElementProperty({
5012
- elementId: element.id,
5013
- propertyName: "_styles",
5014
- propertyValue: { custom_css: mergedCustomCss },
5015
- elementType: node.tagName
5016
- });
5017
- } catch (cssErr) {
5018
- styleErrors.push(String(cssErr));
5019
- }
5020
- }
5021
- await this.awaitViewRender(element);
5022
- }
5023
- return { configErrors, styleErrors };
5024
- }
5025
- async build(rootContainer) {
5026
- const widgetsCache = this.api.getWidgetsCache() || {};
5027
- new Set(this.xml.querySelectorAll("*")).forEach((node) => {
5028
- if (!widgetsCache[node.tagName]) {
5029
- throw new Error(`Unknown widget type: ${node.tagName}`);
5030
- }
5031
- });
5032
- const typesWithRequiredChildren = Object.keys(widgetsCache).filter(
5033
- (elementType) => getRequiredDefaultChildTemplates(widgetsCache[elementType]).length > 0
5034
- );
5035
- typesWithRequiredChildren.forEach((elementType) => {
5036
- new RequiredChildrenEnforcer(elementType, widgetsCache).enforce(this.xml);
5037
- });
5038
- const childTypeErrors = [];
5039
- for (const rootChild of Array.from(this.xml.children)) {
5040
- childTypeErrors.push(...this.validateChildTypes(rootChild, widgetsCache));
5041
- }
5042
- if (childTypeErrors.length) {
5043
- throw new Error(`Invalid element structure:
5044
- ${childTypeErrors.join("\n")}`);
5045
- }
5046
- const formErrors = [
5047
- ...collectFormAncestorErrors(this.xml),
5048
- ...collectSubmitButtonErrors(this.xml),
5049
- ...collectEmptyMessageErrors(this.xml)
5050
- ];
5051
- const children = Array.from(this.xml.children);
5052
- for (const childNode of children) {
5053
- const modelTree = this.buildModelTree(childNode, widgetsCache);
5054
- try {
5055
- const newElement = this.api.createElement({
5056
- container: rootContainer,
5057
- model: modelTree,
5058
- options: { useHistory: false }
5059
- });
5060
- if (!newElement?.model) {
5061
- throw new Error(CREATE_ELEMENT_INVALID_CONTAINER_MESSAGE);
5062
- }
5063
- this.rootContainers.push(newElement);
5064
- await this.awaitViewRender(newElement);
5065
- } catch (e) {
5066
- const attempToRestoreInvalidContainer = this.api.getContainer(modelTree.id);
5067
- if (attempToRestoreInvalidContainer) {
5068
- this.api.deleteElement({ container: attempToRestoreInvalidContainer });
5069
- }
5070
- throw e;
5071
- }
5072
- }
5073
- const { configErrors, styleErrors } = await this.applyProperties();
5074
- if (typeof window !== "undefined") {
5075
- const targetWindow = window.top || window;
5076
- targetWindow.dispatchEvent(
5077
- new CustomEvent("elementor/composition/built", {
5078
- detail: { rootContainers: this.rootContainers.map((c) => c.id) }
5079
- })
5080
- );
5081
- }
5082
- return {
5083
- configErrors,
5084
- styleErrors,
5085
- formErrors,
5086
- rootContainers: [...this.rootContainers]
5087
- };
5088
- }
5089
- };
5090
-
5091
- // src/utils/tracking.ts
5092
- import { trackEvent } from "@elementor/events";
5093
- var trackCanvasEvent = (data) => {
5094
- trackEvent(data);
5095
- };
5096
-
5097
- // src/mcp/utils/element-data-util.ts
5098
- import { getWidgetsCache as getWidgetsCache7 } from "@elementor/editor-elements";
5099
- function hasV3Controls(controls) {
5100
- return typeof controls === "object" && controls !== null && Object.keys(controls).length > 0;
5101
- }
5102
- function isWidgetAvailableForLLM(config) {
5103
- if (!config) {
5104
- return false;
5105
- }
5106
- if (config.meta?.llm_support === false) {
5107
- return false;
5108
- }
5109
- if (config.title === "Component") {
5110
- return false;
5111
- }
5112
- if (config.atomic_props_schema) {
5113
- return true;
5114
- }
5115
- return hasV3Controls(config.controls);
5116
- }
5117
-
5118
- // src/mcp/utils/get-composition-target-container.ts
5119
- import { COMPONENT_DOCUMENT_TYPE } from "@elementor/editor-documents";
5120
- function getCompositionTargetContainer(documentContainer, documentType) {
5121
- const firstChild = documentContainer.children?.[0];
5122
- if (documentType === COMPONENT_DOCUMENT_TYPE && firstChild) {
5123
- return firstChild;
5124
- }
5125
- return documentContainer;
5126
- }
5127
-
5128
- // src/mcp/tools/build-composition/prompt.ts
5129
- import { toolPrompts } from "@elementor/editor-mcp";
5130
- var BUILD_COMPOSITIONS_GUIDE_URI = "elementor://canvas/tools/build-compositions-guide";
5131
- var generatePrompt = () => {
5132
- const buildCompositionsToolPrompt = toolPrompts("build-compositions");
5133
- buildCompositionsToolPrompt.description(`
5134
- # RESOURCES (Read before use)
5135
- - [elementor://global-classes] - Check FIRST for reusable classes
5136
- - [elementor://global-variables] - ONLY use variables defined here
5137
- - [${AVAILABLE_WIDGETS_URI}/v4]
5138
-
5139
- # TOOL SUPPORT
5140
- This tool support v4 elements only
5141
-
5142
- # WORKFLOW
5143
- 1. Check/create global classes via "manage-global-classes" tool
5144
- 2. Build composition (THIS TOOL) - minimal inline styles
5145
- 3. Apply classes via "apply-global-class" tool
5146
-
5147
- # XML STRUCTURE
5148
- - Use widget tags: \`<e-button configuration-id="btn1"></e-button>\`
5149
- - Containers: "e-flexbox", "e-div-block", "e-tabs"
5150
- - Every element needs unique "configuration-id"
5151
- - No attributes, classes, IDs, or text nodes in XML
5152
-
5153
- ## NESTED ELEMENTS
5154
- Some elements have internal tree structures (nesting). When using these elements, you MUST build the FULL tree in XML.
5155
- - Check \`llm_guidance.nesting\` in widget schemas for structure requirements
5156
- - \`llm_guidance.required_direct_children\` lists element types that must appear as direct child tags in XML (from widget defaults)
5157
- - \`allowed_child_types\` lists which element types can be nested inside
5158
- - \`allowed_parents\` lists which element types this element can be placed inside
5159
-
5160
- # CONFIGURATION
5161
- - Map configuration-id \u2192 elementConfig (props) + style (raw CSS declarations)
5162
- - elementConfig PropValues require \`$$type\` matching schema
5163
- - style is raw CSS (property \u2192 value strings); the server converts it to native styles and stores any unconvertible declarations as the element custom CSS
5164
- - NO LINKS in configuration
5165
- - Retry on errors up to 10x
5166
- - Check \`llm_guidance.default_settings\` in widget schemas \u2014 omit only keys listed there from elementConfig unless the user explicitly asks to change them
5167
-
5168
- # DYNAMIC TAGS
5169
- - A value can be made dynamic wherever its schema exposes a \`"$$type": "dynamic"\` variant. This may be the property root OR a NESTED field (e.g. an image's \`src\`, not the whole \`image\`).
5170
- - Put the dynamic object EXACTLY at that node, in place of the static variant. The variant's \`name\` lists the allowed tags; read [${DYNAMIC_TAGS_URI}] for each tag's settings schema.
5171
- - Provide at that node: \`{ "$$type": "dynamic", "value": { "name": "<allowed tag>", "settings": { ... } } }\`
5172
- - Example (image): \`{ "$$type": "image", "value": { "src": { "$$type": "dynamic", "value": { "name": "<image tag>", "settings": { ... } } } } }\`
5173
- - Do NOT send \`group\` (it is resolved automatically). Populate \`settings\` strictly per the tag's schema; use \`{}\` only when it has none.
5174
-
5175
- Note about configuration ids: These names are visible to the end-user, make sure they make sense, related and relevant.
5176
-
5177
- # DESIGN PHILOSOPHY: CONTEXT-DRIVEN CREATIVITY
5178
-
5179
- **Use the user's context aggressively.** Business type, brand personality, target audience, and purpose should drive every design decision. A law firm needs gravitas; a children's app needs playfulness. Don't default to generic.
5180
-
5181
- ## SIZING: DEFAULT IS NO SIZE (CRITICAL)
5182
-
5183
- **DO NOT specify height or width unless you have a specific visual reason.**
5184
-
5185
- Flexbox and CSS already handle sizing automatically:
5186
- - Containers grow to fit their content
5187
- - Flex children distribute space via flex properties, not width/height
5188
- - Text elements size to their content
5189
-
5190
- WHEN TO SPECIFY SIZE:
5191
- - min-height on ROOT section for viewport-spanning hero (use min-height, NOT height)
5192
- - max-width for contained content areas (e.g., max-width: 60rem)
5193
- - Explicit aspect ratios for media containers
5194
-
5195
- NEVER SPECIFY:
5196
- - height on nested containers (causes overflow)
5197
- - width on flex children (use flex-basis or gap instead)
5198
- - 100vh on anything except root-level sections
5199
- - Any size "just to be safe" - if unsure, OMIT IT
5200
-
5201
- vh units are VIEWPORT-relative. Nested 100vh inside 100vh = 200vh overflow.
5202
-
5203
- GOOD: \`<e-flexbox>content naturally sizes</e-flexbox>\`
5204
- BAD: \`<e-flexbox style="height:100vh"><e-div-block style="height:100vh">overflow</e-div-block></e-flexbox>\`
5205
-
5206
- ## Layout Variety (Break the Template)
5207
- - AVOID: Full-width 100vh hero \u2192 three columns \u2192 testimonials \u2192 CTA (every AI does this)
5208
- - VARY heights: Use auto-height sections with generous padding (6rem+). Let content breathe
5209
- - VARY widths: Not everything spans full width. Use contained sections (max-width: 960px) mixed with edge-to-edge
5210
- - ASYMMETRIC grids: 2:1, 1:3, offset layouts. Avoid equal column widths
5211
- - Negative space as design element: Large margins create focus and sophistication
5212
- - Break alignment intentionally: Offset headings, overlapping elements, broken grids
5213
-
5214
- ## Visual Depth & Effects
5215
- - Layer elements: Overlapping cards, text over images, floating elements
5216
- - Subtle shadows with color tint (not pure black): \`box-shadow: 0 20px 60px rgba(<brand-color-here>, 0.15)\`
5217
- - Gradient overlays on images for text readability
5218
- - Border radius variation: Mix sharp (0) and soft (1rem+) corners purposefully
5219
- - Backdrop blur for glassmorphism where appropriate
5220
- - Micro-interactions via CSS: hover transforms, transitions (0.3s ease)
5221
-
5222
- ## Typography with Character
5223
- - Display fonts for headlines (from user's brand or contextually appropriate)
5224
- - Size contrast: 4rem+ headlines vs 1rem body. Make hierarchy unmistakable
5225
- - Letter-spacing: Tight for large headlines (-0.02em), loose for small caps (0.1em)
5226
- - Line-height: Tight for headlines (1.1), generous for body (1.6-1.8)
5227
- - Text decoration: Underlines, highlights, gradient text for emphasis
5228
-
5229
- ## Color with Purpose
5230
- - Extract palette from user context (brand colors, industry norms, mood)
5231
- - 60-30-10 rule: dominant, secondary, accent
5232
- - Tinted neutrals over pure grays: warm (#faf8f5, #2d2a26) or cool (#f5f7fa, #1e2430)
5233
- - Color blocking: Large colored sections create visual rhythm
5234
- - Gradient directions: Diagonal (135deg, 225deg) feel more dynamic than vertical
5235
-
5236
- ## Spacing Strategy
5237
- - Section padding: 6rem-10rem vertical, creating breathing room
5238
- - Rhythm variation: Tight groups (2rem) with generous gaps between (6rem)
5239
- - Use rem/em exclusively for responsive scaling
5240
- - Generous padding on CTAs: min 1rem 2.5rem
5241
-
5242
- # HARD CONSTRAINTS
5243
- - Variables ONLY from [elementor://global-variables] (others throw errors)
5244
- - Avoid SVG widgets unless assets are pre-uploaded
5245
- - Check \`llm_guidance\` in widget schemas (\`default_styles\`, nesting, required children)
5246
-
5247
- # PARAMETERS
5248
- - **xmlStructure**: Valid XML with configuration-id attributes
5249
- - **elementConfig**: configuration-id \u2192 widget PropValues
5250
- - **style**: configuration-id \u2192 raw CSS declarations (property \u2192 value strings; no selectors)
5251
- `);
5252
- buildCompositionsToolPrompt.example(`
5253
- Section with heading + button (NO explicit heights - content sizes naturally):
5254
- {
5255
- xmlStructure: "<e-flexbox configuration-id="Main Section"><e-heading configuration-id="Section Title"></e-heading><e-button configuration-id="Call to Action"></e-button></e-flexbox>",
5256
- elementConfig: {
5257
- "section1": { "tag": { "$$type": "string", "value": "section" } }
5258
- },
5259
- style: {
5260
- "Section Title": {
5261
- "padding": "6rem 4rem",
5262
- "background": "linear-gradient(135deg, #faf8f5 0%, #f0ebe4 100%)",
5263
- "font-size": "3.5rem",
5264
- "color": "#2d2a26"
5265
- }
5266
- }
5267
- }
5268
- Note: No height/width specified on any element - flexbox handles layout automatically.
5269
- `);
5270
- buildCompositionsToolPrompt.parameter(
5271
- "xmlStructure",
5272
- `Valid XML structure with custom elementor tags and configuration-id attributes.`
5273
- );
5274
- buildCompositionsToolPrompt.parameter("elementConfig", `Record mapping configuration IDs to widget PropValues.`);
5275
- buildCompositionsToolPrompt.parameter(
5276
- "style",
5277
- `Record mapping configuration IDs to raw CSS declarations (property \u2192 value strings).`
5278
- );
5279
- buildCompositionsToolPrompt.instruction(
5280
- `Element IDs in the returned XML represent actual widgets. Use these IDs for subsequent styling or configuration changes.`
5281
- );
5282
- return buildCompositionsToolPrompt.prompt();
5283
- };
5284
-
5285
- // src/mcp/tools/build-composition/schema.ts
5286
- import { z } from "@elementor/schema";
5287
- var inputSchema = {
5288
- xmlStructure: z.string().describe("The XML structure representing the composition to be built"),
5289
- elementConfig: z.record(
5290
- z.string().describe("The configuration id"),
5291
- z.record(
5292
- z.string().describe("property name"),
5293
- z.any().describe(`The PropValue for the property, refer to ${WIDGET_SCHEMA_URI}`)
5294
- )
5295
- ).describe("A record mapping element IDs to their configuration objects. REQUIRED"),
5296
- style: z.record(
5297
- z.string().describe("The configuration id"),
5298
- z.record(
5299
- z.string().describe('A CSS property name, e.g. "color", "padding".'),
5300
- z.string().describe('A CSS value, e.g. "6rem 4rem", "#2d2a26".')
5301
- )
5302
- ).describe(
5303
- "A record mapping element configuration IDs to their raw CSS declarations (property\u2192value). Converted to native styles server-side; any declaration that cannot be converted is stored as the element custom CSS."
5304
- ).default({})
5305
- };
5306
- var outputSchema = {
5307
- errors: z.string().describe("Error message if the composition building failed").optional(),
5308
- xmlStructure: z.string().describe(
5309
- "The built XML structure as a string. Must use this XML after completion of building the composition, it contains real IDs."
5310
- ).optional(),
5311
- llm_instructions: z.string().describe("Instructions what to do next, Important to follow these instructions!").optional()
5312
- };
5313
-
5314
- // src/mcp/tools/build-composition/xml-leaf-wrapper.ts
5315
- var DIV_BLOCK_TAG = "e-div-block";
5316
- var ZERO_SPACING = {
5317
- $$type: "size",
5318
- value: {
5319
- size: {
5320
- $$type: "number",
5321
- value: 0
5322
- },
5323
- unit: {
5324
- $$type: "string",
5325
- value: "px"
5326
- }
5327
- }
5328
- };
5329
- function adaptLeafRootParams(params) {
5330
- const doc = new DOMParser().parseFromString(params.xmlStructure, "application/xml");
5331
- const rootElement = doc.documentElement;
5332
- if (!isLeafWidget(rootElement.tagName, params.widgetsCache)) {
5333
- return params;
5334
- }
5335
- const wrapperConfigId = getDivBlockWrapperConfigId(params.widgetsCache);
5336
- return {
5337
- ...params,
5338
- xmlStructure: serializeWrapped(doc, rootElement, wrapperConfigId),
5339
- stylesConfig: {
5340
- ...params.stylesConfig,
5341
- [wrapperConfigId]: {
5342
- margin: ZERO_SPACING,
5343
- padding: ZERO_SPACING,
5344
- ...params.stylesConfig[wrapperConfigId]
5345
- }
5346
- }
5347
- };
5348
- }
5349
- function getDivBlockWrapperConfigId(widgetsCache) {
5350
- return widgetsCache[DIV_BLOCK_TAG]?.title ?? DIV_BLOCK_TAG;
5351
- }
5352
- function isLeafWidget(tagName, widgetsCache) {
5353
- return widgetsCache[tagName]?.elType === "widget";
5354
- }
5355
- function serializeWrapped(doc, rootElement, wrapperConfigId) {
5356
- const wrapper = doc.createElement(DIV_BLOCK_TAG);
5357
- wrapper.setAttribute("configuration-id", wrapperConfigId);
5358
- wrapper.appendChild(rootElement.cloneNode(true));
5359
- const wrappedDoc = new DOMParser().parseFromString(`<${DIV_BLOCK_TAG} />`, "application/xml");
5360
- wrappedDoc.replaceChild(wrapper, wrappedDoc.documentElement);
5361
- return new XMLSerializer().serializeToString(wrappedDoc);
5362
- }
5363
-
5364
- // src/mcp/tools/build-composition/tool.ts
5365
- var ELEMENT_ADDED_EVENT = "elementor/canvas/element-added";
5366
- var initBuildCompositionsTool = (reg) => {
5367
- const { addTool, resource } = reg;
5368
- resource(
5369
- "build-compositions-guide",
5370
- BUILD_COMPOSITIONS_GUIDE_URI,
5371
- {
5372
- title: "Build Compositions Guide",
5373
- description: "Detailed guide for using the build-compositions tool",
5374
- mimeType: "text/plain"
5375
- },
5376
- async (uri) => ({
5377
- contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
5378
- })
5379
- );
5380
- addTool({
5381
- name: "build-compositions",
5382
- description: "Build V4 element compositions on the Elementor canvas. Read the guide resource before use.",
5383
- schema: inputSchema,
5384
- requiredResources: [
5385
- { description: "Build compositions guide", uri: BUILD_COMPOSITIONS_GUIDE_URI },
5386
- { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
5387
- { description: "Global Classes", uri: "elementor://global-classes" },
5388
- { description: "Global Variables", uri: "elementor://global-variables" },
5389
- { description: "Styles best practices", uri: BEST_PRACTICES_URI },
5390
- { description: "Available widgets for this tool", uri: AVAILABLE_WIDGETS_URI_V4 },
5391
- { description: "Dynamic tags catalog", uri: DYNAMIC_TAGS_URI }
5392
- ],
5393
- outputSchema,
5394
- handler: async (rawParams) => {
5395
- assertCompositionXmlUsesV4WidgetsOnly(rawParams.xmlStructure);
5396
- const { stylesConfig: convertedStyles, customCSS } = await convertCompositionStyles(rawParams.style);
5397
- const { xmlStructure, elementConfig, stylesConfig } = adaptLeafRootParams({
5398
- ...rawParams,
5399
- stylesConfig: convertedStyles,
5400
- widgetsCache: getWidgetsCache8() ?? {}
5401
- });
5402
- let generatedXML = "";
5403
- const errors = [];
5404
- const rootContainers = [];
5405
- const documentContainer = getContainer5("document");
5406
- const currentDocument = getCurrentDocument();
5407
- const targetContainer = getCompositionTargetContainer(documentContainer, currentDocument?.type.value);
5408
- try {
5409
- const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
5410
- createElement: createElement13,
5411
- deleteElement: deleteElement2,
5412
- getWidgetsCache: getWidgetsCache8
5413
- });
5414
- compositionBuilder.setElementConfig(elementConfig);
5415
- compositionBuilder.setStylesConfig(stylesConfig);
5416
- compositionBuilder.setCustomCSS(customCSS);
5417
- const {
5418
- configErrors,
5419
- formErrors,
5420
- rootContainers: generatedRootContainers
5421
- } = await compositionBuilder.build(targetContainer);
5422
- rootContainers.push(...generatedRootContainers);
5423
- generatedXML = new XMLSerializer().serializeToString(compositionBuilder.getXML());
5424
- rootContainers.forEach((container) => {
5425
- const elementData = container.model?.toJSON();
5426
- if (elementData) {
5427
- onElementAdded(elementData);
5428
- }
5429
- });
5430
- Object.values(stylesConfig).forEach((styleValue) => {
5431
- dispatchMcpStylesAppliedEvent({ styleValue });
5432
- });
5433
- if (configErrors.length) {
5434
- errors.push(...configErrors.map((msg) => new Error(msg)));
5435
- }
5436
- if (formErrors.length) {
5437
- errors.push(...formErrors.map((msg) => new Error(msg)));
5438
- }
5439
- } catch (error) {
5440
- errors.push(error);
5441
- }
5442
- if (errors.length) {
5443
- rootContainers.forEach((rootContainer) => {
5444
- deleteElement2({
5445
- container: rootContainer,
5446
- options: { useHistory: false }
5447
- });
5448
- });
5449
- const errorMessages = errors.map((e) => {
5450
- if (typeof e === "string") {
5451
- return e;
5452
- }
5453
- if (e instanceof Error) {
5454
- return e.message || String(e);
5455
- }
5456
- if (typeof e === "object" && e !== null) {
5457
- return JSON.stringify(e);
5458
- }
5459
- return String(e);
5460
- }).filter(
5461
- (msg) => msg && msg.trim() !== "" && msg !== "{}" && msg !== "null" && msg !== "undefined"
5462
- );
5463
- if (errorMessages.length === 0) {
5464
- throw new Error(
5465
- "Failed to build composition: Unknown error occurred. No error details available."
5466
- );
5467
- }
5468
- const errorText = `Failed to build composition with the following errors:
5469
-
5470
- ${errorMessages.join(
5471
- "\n\n"
5472
- )}`;
5473
- throw new Error(errorText);
5474
- }
5475
- return {
5476
- xmlStructure: generatedXML,
5477
- errors: errors?.length ? errors.map((e) => typeof e === "string" ? e : e.message).join("\n\n") : void 0,
5478
- llm_instructions: `The composition was built successfully with element IDs embedded in the XML.
5479
-
5480
- **CRITICAL NEXT STEPS** (Follow in order):
5481
- 1. **Apply Global Classes**: Use "apply-global-class" tool to apply the global classes you created BEFORE building this composition
5482
- - Check the created element IDs in the returned XML
5483
- - Apply semantic classes (heading-primary, button-cta, etc.) to appropriate elements
5484
-
5485
- 2. **Fine-tune if needed**: Use "configure-element" tool only for element-specific adjustments that don't warrant global classes
5486
-
5487
- Remember: Global classes ensure design consistency and reusability. Don't skip applying them!
5488
- `
5489
- };
5490
- }
5491
- });
5492
- };
5493
- async function convertCompositionStyles(style) {
5494
- const stylesConfig = {};
5495
- const customCSS = {};
5496
- if (!style || Object.keys(style).length === 0) {
5497
- return { stylesConfig, customCSS };
5498
- }
5499
- const results = await convertStyleBlocksToAtomic(style);
5500
- for (const [configId, { props, customCss }] of Object.entries(results)) {
5501
- stylesConfig[configId] = props;
5502
- if (customCss) {
5503
- customCSS[configId] = customCss;
5504
- }
5505
- }
5506
- return { stylesConfig, customCSS };
5507
- }
5508
- function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
5509
- const doc = new DOMParser().parseFromString(xmlStructure, "application/xml");
5510
- if (doc.querySelector("parsererror")) {
5511
- throw new Error("Failed to parse XML string: " + doc);
5512
- }
5513
- const widgetsCache = getWidgetsCache8() ?? {};
5514
- for (const node of doc.querySelectorAll("*")) {
5515
- const type = node.tagName;
5516
- const widgetData = widgetsCache[type];
5517
- if (!widgetData) {
5518
- continue;
5519
- }
5520
- if (widgetData.elType !== "widget") {
5521
- continue;
5522
- }
5523
- if (!isWidgetAvailableForLLM(widgetData) || !widgetData.atomic_props_schema) {
5524
- throw new Error(`This tool does not support element type: ${type}`);
5525
- }
5526
- }
5527
- }
5528
- function onElementAdded(element) {
5529
- const elType = element.elType ?? "";
5530
- const widgetType = element.widgetType ?? "";
5531
- const elementName = elType === "widget" ? widgetType : elType;
5532
- trackCanvasEvent({
5533
- eventName: "add_element",
5534
- executed_by: "mcp_tool",
5535
- element_name: elementName,
5536
- element_type: elType,
5537
- widget_type: widgetType
5538
- });
5539
- const event = {
5540
- element,
5541
- executedBy: "mcp_tool"
5542
- };
5543
- window.dispatchEvent(new CustomEvent(ELEMENT_ADDED_EVENT, { detail: event }));
5544
- if (element.elements?.length) {
5545
- element.elements?.forEach((childElement) => {
5546
- onElementAdded(childElement);
5547
- });
5548
- }
5549
- }
5550
-
5551
- // src/mcp/tools/configure-element/tool.ts
5552
- import { getContainer as getContainer6, getWidgetsCache as getWidgetsCache9 } from "@elementor/editor-elements";
5553
- import { dispatchMcpStylesAppliedEvent as dispatchMcpStylesAppliedEvent2 } from "@elementor/editor-mcp";
5554
- import { Schema as Schema2 } from "@elementor/editor-props";
5555
-
5556
4822
  // src/mcp/tools/configure-element/prompt.ts
5557
- import { toolPrompts as toolPrompts2 } from "@elementor/editor-mcp";
4823
+ import { toolPrompts } from "@elementor/editor-mcp";
5558
4824
  var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
5559
- var generatePrompt2 = () => {
5560
- const configureElementToolPrompt = toolPrompts2("configure-element");
4825
+ var generatePrompt = () => {
4826
+ const configureElementToolPrompt = toolPrompts("configure-element");
5561
4827
  configureElementToolPrompt.description(`
5562
4828
  Configure an existing element on the page.
5563
4829
 
@@ -5665,11 +4931,11 @@ NO Advanced tab. Never mention Advanced tab.
5665
4931
  `);
5666
4932
  return configureElementToolPrompt.prompt();
5667
4933
  };
5668
- var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt2();
4934
+ var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt();
5669
4935
 
5670
4936
  // src/mcp/tools/configure-element/schema.ts
5671
4937
  import { z as z2 } from "@elementor/schema";
5672
- var inputSchema2 = {
4938
+ var inputSchema = {
5673
4939
  propertiesToChange: z2.record(
5674
4940
  z2.string().describe("The property name."),
5675
4941
  z2.any().describe(`PropValue, refer to [${WIDGET_SCHEMA_URI}] by correct type, as appears in elementType`),
@@ -5686,7 +4952,7 @@ var inputSchema2 = {
5686
4952
  elementType: z2.string().describe("The type of the element to retrieve the schema"),
5687
4953
  elementId: z2.string().describe("The unique id of the element to configure")
5688
4954
  };
5689
- var outputSchema2 = {
4955
+ var outputSchema = {
5690
4956
  success: z2.boolean().describe(
5691
4957
  "Whether the configuration change was successful, only if propertyName and propertyValue are provided"
5692
4958
  )
@@ -5704,27 +4970,27 @@ var initConfigureElementTool = (reg) => {
5704
4970
  mimeType: "text/plain"
5705
4971
  },
5706
4972
  async (uri) => ({
5707
- contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt2() }]
4973
+ contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
5708
4974
  })
5709
4975
  );
5710
4976
  addTool({
5711
4977
  name: "configure-element",
5712
4978
  description: "Configure an existing V4 element's properties and styles. Read the guide resource before use.",
5713
- schema: inputSchema2,
5714
- outputSchema: outputSchema2,
4979
+ schema: inputSchema,
4980
+ outputSchema,
5715
4981
  requiredResources: [
5716
4982
  { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
5717
4983
  { description: "Configure element guide", uri: CONFIGURE_ELEMENT_GUIDE_URI },
5718
4984
  { description: "Dynamic tags catalog", uri: DYNAMIC_TAGS_URI }
5719
4985
  ],
5720
4986
  handler: async ({ elementId, propertiesToChange, elementType, style }) => {
5721
- const widgetData = getWidgetsCache9()?.[elementType];
4987
+ const widgetData = getWidgetsCache6()?.[elementType];
5722
4988
  if (!widgetData) {
5723
4989
  throw new Error(
5724
4990
  `Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
5725
4991
  );
5726
4992
  }
5727
- const container = getContainer6(elementId);
4993
+ const container = getContainer5(elementId);
5728
4994
  if (!container) {
5729
4995
  throw new Error(`Element with id ${elementId} not found`);
5730
4996
  }
@@ -5789,7 +5055,7 @@ async function applyStyleFromCss(opts) {
5789
5055
  propertyValue: styleValue,
5790
5056
  customCssWriteMode: "merge-with-stored"
5791
5057
  });
5792
- dispatchMcpStylesAppliedEvent2({ styleValue });
5058
+ dispatchMcpStylesAppliedEvent({ styleValue });
5793
5059
  } catch (error) {
5794
5060
  throw new Error(
5795
5061
  createUpdateErrorMessage({
@@ -5817,9 +5083,9 @@ Provide styling as raw CSS via the "style" parameter (a flat map of CSS property
5817
5083
 
5818
5084
  // src/mcp/tools/create-element/tool.ts
5819
5085
  import { getCurrentDocument as getCurrentDocument2 } from "@elementor/editor-documents";
5820
- import { httpService as httpService6 } from "@elementor/http-client";
5086
+ import { httpService as httpService7 } from "@elementor/http-client";
5821
5087
  import { z as z3 } from "@elementor/schema";
5822
- var MCP_PROXY_URL5 = "elementor/v1/mcp-proxy";
5088
+ var MCP_PROXY_URL6 = "elementor/v1/mcp-proxy";
5823
5089
  var initCreateElementTool = (reg) => {
5824
5090
  const { addTool } = reg;
5825
5091
  addTool({
@@ -5839,7 +5105,7 @@ var initCreateElementTool = (reg) => {
5839
5105
  if (!document2?.id) {
5840
5106
  throw new Error("No active document found.");
5841
5107
  }
5842
- const { data } = await httpService6().post(MCP_PROXY_URL5, {
5108
+ const { data } = await httpService7().post(MCP_PROXY_URL6, {
5843
5109
  tool: "create-element",
5844
5110
  input: {
5845
5111
  parent_id: parentId ?? "document",
@@ -5857,13 +5123,13 @@ var initCreateElementTool = (reg) => {
5857
5123
  };
5858
5124
 
5859
5125
  // src/mcp/tools/get-element-config/tool.ts
5860
- import { getContainer as getContainer7, getElementStyles as getElementStyles2, getWidgetsCache as getWidgetsCache10 } from "@elementor/editor-elements";
5126
+ import { getContainer as getContainer6, getElementStyles as getElementStyles2, getWidgetsCache as getWidgetsCache7 } from "@elementor/editor-elements";
5861
5127
  import { Schema as Schema3 } from "@elementor/editor-props";
5862
5128
  import { z as z4 } from "@elementor/schema";
5863
5129
  var schema = {
5864
5130
  elementId: z4.string()
5865
5131
  };
5866
- var outputSchema3 = {
5132
+ var outputSchema2 = {
5867
5133
  properties: z4.record(z4.string(), z4.any()).describe("A record mapping PropTypes to their corresponding PropValues"),
5868
5134
  style: z4.record(z4.string(), z4.any()).describe("A record mapping StyleSchema properties to their corresponding PropValues"),
5869
5135
  childElements: z4.array(
@@ -5890,14 +5156,14 @@ var initGetElementConfigTool = (reg) => {
5890
5156
  name: "get-element-configuration-values",
5891
5157
  description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
5892
5158
  schema,
5893
- outputSchema: outputSchema3,
5159
+ outputSchema: outputSchema2,
5894
5160
  handler: async ({ elementId }) => {
5895
- const element = getContainer7(elementId);
5161
+ const element = getContainer6(elementId);
5896
5162
  if (!element) {
5897
5163
  throw new Error(`Element with ID ${elementId} not found.`);
5898
5164
  }
5899
5165
  const elementType = element.model.get("widgetType") || element.model.get("elType") || "";
5900
- const widgetData = getWidgetsCache10()?.[elementType];
5166
+ const widgetData = getWidgetsCache7()?.[elementType];
5901
5167
  if (!widgetData) {
5902
5168
  throw new Error(
5903
5169
  `Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
@@ -5909,7 +5175,7 @@ var initGetElementConfigTool = (reg) => {
5909
5175
  );
5910
5176
  }
5911
5177
  const elementRawSettings = element.settings;
5912
- const propSchema = getWidgetsCache10()?.[elementType]?.atomic_props_schema;
5178
+ const propSchema = getWidgetsCache7()?.[elementType]?.atomic_props_schema;
5913
5179
  if (!elementRawSettings || !propSchema) {
5914
5180
  throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
5915
5181
  }
@@ -5960,10 +5226,10 @@ var initCanvasMcp = (reg) => {
5960
5226
  initEditorStateResource(reg);
5961
5227
  initGeneralContextResource(reg);
5962
5228
  initBestPracticesResource(reg);
5963
- initBuildCompositionsTool(reg);
5964
5229
  initGetElementConfigTool(reg);
5965
5230
  initConfigureElementTool(reg);
5966
5231
  initCreateElementTool(reg);
5232
+ initBuildCompositionTool(reg);
5967
5233
  initBreakpointsResource(reg);
5968
5234
  };
5969
5235
 
@@ -6163,7 +5429,7 @@ function shouldBlock(sourceElements, targetElements) {
6163
5429
  }
6164
5430
 
6165
5431
  // src/style-commands/paste-style.ts
6166
- import { getContainer as getContainer8, getElementSetting, updateElementSettings as updateElementSettings2 } from "@elementor/editor-elements";
5432
+ import { getContainer as getContainer7, getElementSetting, updateElementSettings as updateElementSettings2 } from "@elementor/editor-elements";
6167
5433
  import { classesPropTypeUtil } from "@elementor/editor-props";
6168
5434
  import {
6169
5435
  __privateListenTo as listenTo5,
@@ -6172,7 +5438,7 @@ import {
6172
5438
  } from "@elementor/editor-v1-adapters";
6173
5439
 
6174
5440
  // src/utils/command-utils.ts
6175
- import { getElementLabel as getElementLabel2, getWidgetsCache as getWidgetsCache11 } from "@elementor/editor-elements";
5441
+ import { getElementLabel as getElementLabel2, getWidgetsCache as getWidgetsCache8 } from "@elementor/editor-elements";
6176
5442
  import { CLASSES_PROP_KEY } from "@elementor/editor-props";
6177
5443
  import { __ as __5 } from "@wordpress/i18n";
6178
5444
  function hasAtomicWidgets(args) {
@@ -6197,7 +5463,7 @@ function getClassesProp(container) {
6197
5463
  }
6198
5464
  function getContainerSchema(container) {
6199
5465
  const type = container?.model.get("widgetType") || container?.model.get("elType");
6200
- const widgetsCache = getWidgetsCache11();
5466
+ const widgetsCache = getWidgetsCache8();
6201
5467
  const elementType = widgetsCache?.[type];
6202
5468
  return elementType?.atomic_props_schema ?? null;
6203
5469
  }
@@ -6316,7 +5582,7 @@ function pasteStyles(args, pasteLocalStyle) {
6316
5582
  }
6317
5583
  const clipboardElements = getClipboardElements(storageKey);
6318
5584
  const [clipboardElement] = clipboardElements ?? [];
6319
- const clipboardContainer = getContainer8(clipboardElement.id);
5585
+ const clipboardContainer = getContainer7(clipboardElement.id);
6320
5586
  if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
6321
5587
  return;
6322
5588
  }
@@ -6593,10 +5859,10 @@ function useEscapeOnCanvas(canvasDocument, onEscape) {
6593
5859
  }
6594
5860
 
6595
5861
  // src/utils/after-render.ts
6596
- import { getContainer as getContainer9 } from "@elementor/editor-elements";
5862
+ import { getContainer as getContainer8 } from "@elementor/editor-elements";
6597
5863
  function doAfterRender(elementIds, callback) {
6598
5864
  const pending = elementIds.map((elementId) => {
6599
- const view = getContainer9(elementId)?.view;
5865
+ const view = getContainer8(elementId)?.view;
6600
5866
  if (!view || !hasDoAfterRender(view)) {
6601
5867
  return void 0;
6602
5868
  }
@@ -6611,6 +5877,9 @@ function doAfterRender(elementIds, callback) {
6611
5877
  function hasDoAfterRender(view) {
6612
5878
  return typeof view?._doAfterRender === "function";
6613
5879
  }
5880
+
5881
+ // src/sync/element-added-event.ts
5882
+ var ELEMENT_ADDED_EVENT = "elementor/canvas/element-added";
6614
5883
  export {
6615
5884
  BREAKPOINTS_SCHEMA_FULL_URI,
6616
5885
  BREAKPOINTS_SCHEMA_URI,