Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/diasmazhenov/wp-ai-executor/archive/refs/heads/main.zipSecure REST endpoint that lets any AI agent (Claude, Codex, Gemini, GPT, etc.) execute PHP code in the WordPress context.
Installation
- Copy the
wp-ai-executorfolder towp-content/plugins/ - Activate the plugin in Plugins → Installed Plugins
- The secret key is auto-generated on first activation and stored in
wp_options
Optionally, hard-code the key in wp-config.php:
define( 'WP_AI_EXECUTOR_KEY', 'your-64-char-hex-key' );
Endpoints
GET /wp-json/ai-executor/v1/health
Authenticated, read-only WordPress health diagnostics. Send X-AI-Key and use:
?mode=quickfor database latency, WordPress bootstrap time, PHP memory, WP-Cron backlog, disk space, autoload options, debug configuration, and cached update state, plus recent AI Executor REST latency;?mode=deep&refresh=1to additionally test WordPress loopback and REST API availability with five-second timeouts.
The response includes overall, summary, machine-readable checks, concrete
recommendations, and a bounded health history. Results are briefly cached and
stored in wp_options; no server files are created. The endpoint never restarts
services, clears caches, deletes logs, or changes WordPress settings. A fully
blocked PHP-FPM pool still requires nginx/PHP-FPM/MySQL hosting logs because no
WordPress plugin can answer while every PHP worker is unavailable. A short lock
prevents parallel deep checks from adding extra PHP-FPM pressure.
POST /wp-json/ai-executor/v1/run
Execute PHP code in the WordPress environment.
Headers:
X-AI-Key: <your-secret-key>
X-WPAE-Guide-Token: <token from /guide/ack>
X-WPAE-Guide-Hash: <hash from /guide/ack>
Content-Type: application/json
Body:
{ "code": "return get_bloginfo('name');" }
Response:
{
"return_value": "My WordPress Site",
"output": ""
}
GET /wp-json/ai-executor/v1/guide
Returns authenticated guidance for AI agents before they automate WordPress or Elementor. This is not a Codex-specific skill runtime. It is a portable prompt and implementation contract that any HTTP-capable agent can fetch and follow.
It includes:
- frontend design planning principles
- WordPress/Elementor automation workflow
- distilled
frontend-designandwordpress-elementor-devknowledge packs - native Elementor-first rules
- HTML widget enhancement policy
- Elementor
_elementor_datashape - required page meta keys
- verification checklist
- security rules
- a minimal PHP snippet for creating an Elementor page
The guide intentionally does not embed Codex skills as a runtime dependency. Instead, it ships portable distilled rules that Claude, Codex, GPT, Gemini, Qwen, scripts, or any HTTP-capable agent can fetch and apply.
KEY="your-secret-key"
SITE="https://yoursite.com"
curl -s "$SITE/wp-json/ai-executor/v1/guide" \
-H "X-AI-Key: $KEY"
POST /wp-json/ai-executor/v1/self-update
Safely updates only the plugin's own wp-ai-executor.php file from the
an immutable Git commit URL. This is the only supported filesystem write path.
General filesystem writes through /run remain blocked.
The downloaded file must pass required plugin marker validation before writing.
curl -s -X POST "$SITE/wp-json/ai-executor/v1/self-update" \
-H "X-AI-Key: $KEY" \
-H "X-WPAE-Guide-Token: $GUIDE_TOKEN" \
-H "X-WPAE-Guide-Hash: $GUIDE_HASH" \
-H "Content-Type: application/json" \
-d '{"source_url":"https://raw.githubusercontent.com/DiasMazhenov/wp-ai-executor/<40-char-commit-sha>/wp-ai-executor.php","dry_run":true}'
Accepted source URLs must match:
https://raw.githubusercontent.com/DiasMazhenov/wp-ai-executor/<40-char-commit-sha>/wp-ai-executor.php
GET /wp-json/ai-executor/v1/capabilities
Returns the executor's current safety and write capabilities. This reflects the site owner's settings from Settings → AI Executor.
Important fields include:
{
"can_execute_php": false,
"can_write_elementor": true,
"can_write_files_via_run": false,
"can_self_update_plugin": true,
"can_upload_media": true,
"can_create_exports": true,
"can_manage_skills": true,
"can_rollback": true,
"can_view_operation_logs": true,
"can_score_agent_conformance": true,
"elementor": {
"can_normalize": true,
"can_use_recipes": true,
"can_compose_sections": true
}
}
If a capability is disabled, the matching write endpoint returns 403 even
with a valid key and guide token.
LLM-агент и чат Elementor
Во вкладке Settings -> AI Executor -> LLM-агенты можно подключить один
активный OpenAI-compatible provider: OpenAI, DeepSeek, OpenRouter (по умолчанию
openrouter/free) или другой HTTPS-шлюз через custom base URL. API-ключ
шифруется и остается на сервере.
POST /wp-json/ai-executor/v1/llm/chat — безопасный proxy для текстового чата.
Он принимает message, необязательные последние history и ограниченный
context редактора. Обычные вопросы остаются консультационными, а явные
команды вроде «создай hero» могут вставить только новые элементы при включенных
llm_chat и elementor_writes; данные проходят существующий update, preflight,
protected-zone, visual-regression и rollback pipeline. Удаление и полная замена
страницы не поддерживаются. Непригодный action JSON проходит ограниченный repair;
резервный шаблон допускается только после ошибки генерации и проверки содержания. В редакторе Elementor при включенном разрешении появляется
плавающий чат с текущим статусом операции.
Он подключается на экране Elementor вида /wp-admin/post.php?post=ID&action=elementor.
Генератор сохраняет принятую композицию модели: native Flexbox, крупную типографику, заданные тексты, ссылки и палитру. Библиотечный шаблон больше не заменяет корректный ответ. Недостающие mobile/tablet-настройки дополняются, а явно заданные значения сохраняются. Пустые деревья и композиции больше 80 элементов отправляются на repair. Цвета проекта служат исходной палитрой; пользовательские цвета в native controls допустимы.
Все обращения к провайдеру в одной генерации делят бюджет 120 секунд. При истечении времени браузера результат записи считается неизвестным: повторная генерация автоматически не запускается. Отмена проверяет, что после операции страницу не изменили, и обновляет весь редактор.
Проверки разработчика: node --test tests/*.test.js (нужны Node.js и PHP 8+).
PHP-сценарии используют реальные генератор, нормализатор, design contract,
transport и undo с подменой WordPress/HTTP. Они не заменяют проверку
отрисованного блока в Elementor на компьютере и телефоне.
Deterministic design pipeline
Для генерации hero, process и pricing доступен отдельный флаг
design_pipeline_mode в Settings -> AI Executor -> LLM-агенты:
off(значение по умолчанию) оставляет прежний provider/legacy path;shadowстроит BriefIR, DesignPlan, LayoutReport и ElementorIR в памяти, сравнивает их с legacy-результатом и не передает новый tree в запись;activeприменяет локальный native compiler после структурной проверки.
Границы нового пути находятся в includes/llm/brief-ir.php,
includes/llm/design-plan.php, includes/elementor/elementor-ir.php и
includes/elementor/native-compiler.php. WidgetCapabilityRegistry,
ReferenceSet, semantic token resolver, LayoutReport и durable operation
ledger используются до существующего Elementor transaction/readback слоя.
Provider-generated JSON остается legacy adapter-ом и не становится внутренним
стандартом нового compiler-а. Для локальной проверки запустите
php tests/design-pipeline-contract.php.
Agent conformance scoring
Mutating and verification endpoints return an agent_conformance object. It is
a runtime score for whether the agent followed the guide and site policy.
The score is advisory, not a hard block: agents must treat weak or blocked
as unfinished work and correct the operation before claiming success.
Scored criteria include:
- guide token flow
- forbidden filesystem activity
- native Elementor validation
- Flexbox Containers only
- camelCase
widgetType - native visual settings for critical backgrounds/styles
- native heading hierarchy
- consistent native container padding/gaps
- visible native button CTA
- responsive Elementor settings
- deliberate palette variety
- populated native heading/text content
- explicit verification signal or
/audit
Example:
{
"agent_conformance": {
"score": 92,
"level": "strong",
"blocking_errors": [],
"criteria": {
"guide_token_flow": { "status": "pass", "points": 15, "max": 15 },
"file_policy": { "status": "pass", "points": 15, "max": 15 }
}
}
}
Operation logs also include the redacted agent_conformance_score and
agent_conformance_level summary fields.
Elementor Design Review Gate
POST /wp-json/ai-executor/v1/elementor/design-review combines the existing
visual, design-system, mobile, content, and editability checks into one
deterministic verdict: review, revise, or approved. Pass
transaction_design_review=true to a structured write to require approval and
auto-rollback when the review gate does not approve the saved data.
Repeated external-agent error audit
/audit and /elementor/visual-audit also return
repeated_agent_error_audit. It turns common third-party agent mistakes into
explicit checks with safe next fixes:
- legacy
section/column - snake-case
widget_type - HTML widget used as layout/content
- JavaScript-injected CSS for native Elementor properties
!importantheading typography overrides- excessive local typography overrides
- design-system marker drift
- fixed px layout risks
Agents must fix every fail check before claiming success. warn checks must
be fixed or explicitly explained.
POST /wp-json/ai-executor/v1/elementor/validate
Validates Elementor JSON without writing anything. Requires X-AI-Key.
{ "elementor_data": [] }
POST /wp-json/ai-executor/v1/elementor/normalize
Normalizes common Elementor JSON mistakes without writing anything. Requires
X-AI-Key. Use this before /elementor/page or /elementor/update when an
agent produced legacy sections/columns, widget_type, missing widgetType,
missing settings, missing elements, or incomplete container defaults.
It returns normalized_elementor_data, change_counts, a capped changes
list, before_errors, after_errors, and audit stats.
{
"elementor_data": [
{
"elType": "section",
"elements": [
{
"elType": "widget",
"widget_type": "heading",
"settings": { "title": "Hello" }
}
]
}
]
}
GET /wp-json/ai-executor/v1/elementor/recipes
Returns reusable native Elementor composition patterns. Recipes are not rigid templates; they are safe primitives and section patterns with variants and slots. Agents should use them for complex sections instead of inventing raw Elementor structure from scratch.
Available section recipes include:
hero.editorialfeature.gridprocess.stepspricing.comparisonfaq.accordioncta.bandproof.timelinecontact.block
curl -s "$SITE/wp-json/ai-executor/v1/elementor/recipes" \
-H "X-AI-Key: $KEY"
POST /wp-json/ai-executor/v1/elementor/blueprint
Returns a read-only page plan before any Elementor JSON is generated. Agents should call it first for new page work, then compose recipes or native container/widget primitives against the returned contract.
{
"subject": "website service landing page",
"audience": "business owners who need a clear offer page",
"goal": "get a consultation request",
"offer": "Landing page built in editable Elementor",
"language": "ru",
"style": "editorial premium service page",
"proof_points": ["7-14 day launch", "native Elementor", "no external files"],
"primary_cta": "Discuss the page"
}
The response includes design tokens, section plan, recipe IDs/variants, slot suggestions, native widget requirements, HTML enhancement zones, and design quality gates.
Project design tokens
The dashboard stores project design tokens in wp_options. They are returned
from /guide, /capabilities, and /elementor/blueprint, so agents can follow
the site's visual system before writing Elementor data.
POST /elementor/design-system also returns a backward-compatible Design
System Package v2 with a machine-readable manifest, generated DESIGN.md
content and semantic tokens. Pass post_id to inspect the active system for a
page. Use POST /elementor/design-system/update with dry_run=true before a
real update; successful writes return a rollback snapshot ID.
Stored token groups:
- palette
- typography roles
- spacing scale
- radii
- button style
- tone of voice
- design prohibitions
GET /wp-json/ai-executor/v1/elementor/recipes/{id}
Returns one recipe with its variants, slots, and native Elementor JSON pattern.
curl -s "$SITE/wp-json/ai-executor/v1/elementor/recipes/hero.editorial" \
-H "X-AI-Key: $KEY"
POST /wp-json/ai-executor/v1/elementor/compose
Composes a recipe variant with project-specific slot values and returns ready
Elementor JSON without writing anything. The returned elementor_data should
still be passed through /elementor/normalize, /elementor/validate, and then
saved with /elementor/page or /elementor/update.
{
"recipe_id": "hero.editorial",
"variant": "split-proof",
"slots": {
"headline": "A service page that makes the offer clear",
"subheadline": "Native Elementor structure with proof, process, and action.",
"cta_primary": "Discuss the page"
}
}
POST /wp-json/ai-executor/v1/elementor/page
Creates or updates a WordPress page and saves validated Elementor metadata.
Requires X-AI-Key, X-WPAE-Guide-Token, X-WPAE-Guide-Hash, and the
elementor_writes capability.
{
"title": "Landing Page",
"slug": "landing-page",
"status": "publish",
"template": "elementor_canvas",
"dry_run": true,
"elementor_data": []
}
Set dry_run=true to validate without writing. Real writes return
rollback_snapshot_id and rollback_expires_at; pass the snapshot ID to
/rollback if the page must be reverted.
POST /wp-json/ai-executor/v1/elementor/update
Updates Elementor metadata for an existing page after validation.
{
"post_id": 123,
"template": "elementor_canvas",
"dry_run": true,
"elementor_data": []
}
POST /wp-json/ai-executor/v1/rollback
Restores a short-lived rollback snapshot stored in wp_options.
Requires X-AI-Key, X-WPAE-Guide-Token, and X-WPAE-Guide-Hash.
{ "snapshot_id": "abc123" }
For arbitrary /run PHP, dry_run is intentionally unsupported. If a /run
mutation is risky, pass known targets before execution:
{
"code": "return update_option('example_option', 'new-value');",
"rollback_targets": {
"post_ids": [123],
"option_names": ["example_option"]
}
}
POST /wp-json/ai-executor/v1/audit
Audits a page after writing. Requires X-AI-Key; does not write anything.
Returns machine-readable findings for Elementor meta, JSON validity, Flexbox
Containers, widgetType, HTML widget layout risk, and basic native style checks.
{ "post_id": 123 }
POST /wp-json/ai-executor/v1/guide/session
Starts a short-lived guide session and returns guide_session_id,
guide_hash, expiration, and the required acknowledgement schema.
POST /wp-json/ai-executor/v1/guide/ack
Acknowledges that the agent read /guide, custom_skills, and
/capabilities. Returns:
X-WPAE-Guide-Token: <token>
X-WPAE-Guide-Hash: <hash>
All write endpoints require these headers.
Elementor block library
The plugin can copy and permanently store arbitrary Elementor containers, widgets, and template content, including blocks imported from other sites. This is separate from the built-in recipe library and from short-lived exports.
Supported input formats:
- a raw native Elementor element object;
- an array of native Elementor elements;
- an Elementor export envelope with
type: "elementor"and anelementsarray; - an Elementor template object with a
contentarray; - a
wpae-elementor-block-v1wrapper.
Editor users get Copy as JSON and Save to WP AI Executor library actions
in the Elementor container/widget context menu. The editor uses the logged-in
WordPress REST nonce; it never exposes X-AI-Key in browser code.
Agent endpoints:
GET /wp-json/ai-executor/v1/elementor/blocks
POST /wp-json/ai-executor/v1/elementor/blocks
GET /wp-json/ai-executor/v1/elementor/blocks/{id}
DELETE /wp-json/ai-executor/v1/elementor/blocks/{id}
POST /wp-json/ai-executor/v1/elementor/blocks/{id}
POST /wp-json/ai-executor/v1/elementor/blocks/{id}/duplicate
POST /wp-json/ai-executor/v1/elementor/blocks/{id}/publish
GET /wp-json/ai-executor/v1/elementor/blocks/{id}/instantiate?mode=preserve
New records carry a versioned `wpae-elementor-block-manifest-v1` sidecar with
workflow status, source skill, design-system reference, provenance/license,
parent revision, quality score and media dependencies. Existing records are
read as `published` for backward compatibility; draft blocks cannot be
instantiated. Approval runs the deterministic Design Review Gate, and
`published` is only reachable from `approved`.
preserve only creates new Elementor IDs and keeps the original design.
compatibility normalizes the block for the current Flexbox/write contract.
adapt additionally applies current design-system markers and deterministic
semantic color, typography, spacing, and radius tokens through native Elementor
settings. Its token_map report exposes mapped values, unmatched settings,
collisions, evidence, native paths, and protected enhancement skips. Foreign
blocks may be stored with design_system_id: null; the
compatibility report lists missing widgets, media references, legacy elements,
normalization requirements, and protected enhancement zones. The wrapper keeps
both the extracted elementor_data used for insertion and the exact
native_payload, so foreign template-level fields such as page_settings are
not discarded.
Imports may also include source: "copyelement", source_url and a
preview_url. The preview is stored as sanitized source metadata next to the
JSON; the remote image is not bundled into the plugin. The accepted payload
size for the private library is 4 MB. The package also contains the recovered
CopyElement Image Box c2644 JSON under
includes/elementor/copyelement/; the first library read imports it
idempotently as a private wpae_block record with its preview URL. This is the
plugin's private library, not Elementor's elementor_library.
The bundled set also includes the user-supplied CopyElement Testimonials c1198 and About c70 exports. They are imported into the same private
wpae_block library as draft records and must pass the Design Review Gate
before retrieval can use them. Their source exports did not include preview
assets, so the package keeps their preview metadata empty.
The bundled set also includes the user-supplied CopyElement Team c1429
export. It follows the same private-library import and Design Review Gate
workflow; its preview metadata remains empty when no preview asset is supplied.
New action requests in the editor chat retrieve only approved or published
private blocks, rank them by archetype, tags, title, description, and prompt
terms, then adapt a compatible repeated-card composition to the user's content.
The adapted result must pass the native shape and content-fidelity checks before
it replaces the provider composition; targeted edits and Vision repair passes
keep their bounded scope. The chat response exposes a library_retrieval step
with candidate and selection metadata without returning the stored block JSON.
Native Elementor Templates
Native saved templates from Elementor's elementor_library post type are
available to an agent through the canonical X-AI-Key header:
GET /wp-json/ai-executor/v1/elementor/templates?q=hero&type=section&limit=20
GET /wp-json/ai-executor/v1/elementor/templates/{id}
The list is a lightweight summary. The detail response is read-only and
contains the original elementor_data, normalized_elementor_data,
page_settings, and a compatibility report. Validate the normalized data
before using the existing structured Elementor write endpoints. The key is
never sent to browser JavaScript; the Elementor editor continues to use its
logged-in WordPress REST nonce for its own UI requests.
GET|POST /wp-json/ai-executor/v1/skills
Stores custom agent skills in the WordPress database. Skills are returned inside
/guide as custom_skills; no skill files are created on disk.
The same storage can be managed from Settings → AI Executor → Custom skills
by pasting SKILL.md content into the dashboard.
Body:
{
"id": "frontend-design",
"name": "frontend-design",
"description": "Project visual and UX rules",
"content": "Skill instructions as Markdown or plain text",
"enforce": [
{ "type": "forbid_elementor_eltype", "value": "section" },
{ "type": "require_widget_key", "value": "widgetType" },
{ "type": "allow_widget_type", "value": "heading" },
{ "type": "require_container_setting", "value": "background_color" },
{ "type": "forbid_html_pattern", "value": "<section" }
],
"manifest": {
"format": "wpae-skill-manifest-v1",
"version": "1.0.0",
"capabilities": ["elementor_read", "visual_audit"],
"inputs": ["subject", "audience"],
"pipeline": [
{"method": "POST", "endpoint": "/elementor/blueprint"},
{"method": "POST", "endpoint": "/elementor/visual-audit"}
],
"license": "MIT",
"compatibility": {"requires_flexbox": true}
},
"enabled": true,
"priority": 10
}
manifest is optional; legacy skills remain valid. The plugin validates its
capabilities and workflow against a closed WPAE endpoint allowlist. A manifest
cannot authorize /run, self-update, shell, MCP, WP-CLI, browser-admin writes,
or server files, and its content is never executed as code.
Use POST /wp-json/ai-executor/v1/skills/validate to normalize or reject a
manifest without writing it. This read-only endpoint works even when the site
owner has disabled manage_skills; all skill mutations remain blocked.
Supported enforce rule types:
forbid_elementor_eltyperequire_widget_keyforbid_widget_keyallow_widget_typeforbid_widget_typerequire_widget_settingwith optionaltargetrequire_container_settingforbid_html_pattern
GET /wp-json/ai-executor/v1/skills/export
Returns a database-only JSON skill bundle. No files are created.
{
"schema": "wp-ai-executor.skill-bundle",
"schema_version": 1,
"skills": []
}
POST /wp-json/ai-executor/v1/skills/import
Imports a JSON skill bundle into wp_options. Requires the manage_skills
capability and guide-token headers. Use mode=merge to add/update, or
mode=replace to replace all current skills.
{
"mode": "merge",
"skills": [
{
"id": "project-rules",
"name": "Project rules",
"content": "# Instructions"
}
]
}
DELETE /wp-json/ai-executor/v1/skills/{id}
Deletes a custom skill from the database.
POST /wp-json/ai-executor/v1/media/upload
Uploads validated media through the WordPress uploads API. Allowed MIME types:
JPEG, PNG, WebP, GIF, PDF. Max size: 8 MB. The binary signature must match
the requested mime_type.
POST /wp-json/ai-executor/v1/exports/create
Creates a short-lived JSON export in wp_options, not in public uploads.
Max size: 1 MB. The response includes an authenticated /exports/{id}
endpoint and no public URL.
GET /wp-json/ai-executor/v1/exports
Returns export metadata only: active count, expired count, storage limits, total active bytes, and authenticated export endpoints. It does not return raw export JSON.
POST /wp-json/ai-executor/v1/exports/prune
Deletes expired export records from wp_options. Requires the exports
capability and a fresh guide token. The dashboard exposes the same cleanup as
a button under Короткоживущие exports.
GET /wp-json/ai-executor/v1/exports/{id}
Returns a non-public export by ID with X-AI-Key. Expired exports return 404.
GET /wp-json/ai-executor/v1/logs
Returns recent authenticated operation metadata from wp_options.
Logs are capped and do not include API keys, guide tokens, raw request bodies,
raw page payloads, raw response payloads, or secrets.
AI Vision safety
/vision/analyze accepts at most 12 provider calls per site-wide 10-minute
window. A report for a different post_id cannot review or gate another page.
transaction_vision_review=true accepts only a same-post report created by
/vision/analyze; externally submitted /vision/report data stays advisory.
{
"logs": [
{
"time": "2026-07-05T20:00:00+00:00",
"method": "POST",
"endpoint": "/elementor/page",
"status": 200,
"duration_ms": 428,
"target_ids": { "post_id": 123 },
"rollback_snapshot_id": "abc123"
}
]
}
Usage Examples
Bash / curl (production, no browser needed)
KEY="your-secret-key"
SITE="https://yoursite.com"
curl -s -X POST "$SITE/wp-json/ai-executor/v1/run" \
-H "Content-Type: application/json" \
-H "X-AI-Key: $KEY" \
-d '{"code": "return get_option(\"blogname\");"}'
JavaScript / Browser (local dev)
const KEY = 'your-secret-key';
window.aiPHP = async (code) => {
const res = await fetch('/wp-json/ai-executor/v1/run', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-AI-Key': KEY },
body: JSON.stringify({ code })
});
const d = await res.json();
return d.return_value ?? d.error;
};
// Usage:
await aiPHP(`return get_bloginfo('name') . ' | PHP ' . PHP_VERSION;`);
Agent bootstrap
Ask any agent to fetch /guide first:
Before making WordPress changes, call:
GET /wp-json/ai-executor/v1/guide with X-AI-Key.
Then call /guide/session, read /guide and /capabilities, call /guide/ack,
and pass X-WPAE-Guide-Token plus X-WPAE-Guide-Hash to every write endpoint.
Follow the returned agent_prompt, embedded_skill_packs, frontend_design rules,
custom_skills, wordpress_elementor workflow, page_meta contract,
html_enhancement_policy, and verification_checklist. Then use /run for execution
and verify the published URL plus Elementor metadata.
Use /elementor/normalize before saving any Elementor JSON that contains legacy
sections/columns, snake-case widget_type, missing widgetType, missing settings,
missing elements arrays, or incomplete container defaults.
For complex or non-standard sections, call /elementor/recipes, inspect the
recipe slots/variants, call /elementor/compose, then normalize and validate the
returned elementor_data before saving.
Important: build Elementor page structure and content with native editable
Elementor elements. Use containers and widget settings such as `heading`,
`text-editor`, `button`, `icon-list`, `image`, `divider`, and `spacer`.
Use only Elementor Flexbox Containers for layout. In `_elementor_data`, layout
nodes must be `elType: "container"` only. Legacy `elType: "section"` and
`elType: "column"` are forbidden and must be converted to nested containers
before saving.
Every widget must use Elementor's exact camelCase `widgetType` key. Never use
`widget_type`; Elementor will treat that as missing widget identity and can
render empty widgets.
The executor validates changed `_elementor_data` after each `/run` call and
blocks legacy `section`/`column`, snake-case `widget_type`, and widgets missing
`widgetType`, rolling changed Elementor data back when possible.
Critical visual state must also be set natively: backgrounds, text colors,
borders, border radius, spacing, dimensions, and alignment. Scoped CSS may use
`!important` as a fallback when Elementor/theme CSS wins specificity, but CSS
must not be the only source for essential contrast or layout.
The Elementor `html` widget is allowed only for small JavaScript snippets or
complex CSS enhancements when native settings are not enough. Do not use it as
the main page markup/content/layout container, and do not use shortcode widgets
to fake editable page sections. After writing `_elementor_data`, recursively
inspect any `html` widgets and confirm they are enhancement-only.
Never create external files through this plugin. Do not create temporary
loaders, mu-plugins, helper PHP files, CSS/JS/JSON/base64 payload files, scratch
files, or files in `/tmp`. Use WordPress APIs and Elementor metadata instead.
By default `/run` rejects common filesystem write/delete operations and
shell/process execution.
Use only dedicated endpoints for allowed writes: `/self-update`,
`/elementor/page`, `/elementor/update`, `/media/upload`, `/exports/create`,
and `/skills`. Use `/audit` after page writes. Read `agent_conformance` in
write and audit responses; `weak` or `blocked` means the task is not complete.
Agent quality gates
Before writing a landing page, the agent should produce or internally resolve:
- subject, audience, and the page's single job
- 4-6 color tokens
- display, body, and utility typography roles
- section map / wireframe
- one distinctive signature element
- native Elementor element plan
- CSS/JS enhancement plan, if needed
After writing, the agent should verify:
- permalink returns HTTP 200
- post status and Elementor meta are correct
_elementor_datadecodes as a recursive array_elementor_datacontains zero legacysectionorcolumnelements- every
elType: "widget"element has non-emptywidgetTypeand nowidget_type - main copy lives in native widget settings
- any
htmlwidget is CSS/JS enhancement-only - critical backgrounds, borders, spacing, and contrast exist in native Elementor settings
- no external files, temporary loaders, mu-plugins, or scratch files are created
- no obvious desktop/mobile overlap or horizontal overflow
agent_conformance.levelisstrongor at leastacceptable
Security
- All requests require the
X-AI-Keyheader - Key is a 64-char cryptographically random hex string
- Key comparison uses
hash_equals()to prevent timing attacks - Secret keys are shown only to WordPress administrators in Settings → AI Executor; the REST API never returns them
- The
/guideendpoint is authenticated because it describes privileged automation workflows - Site-owner capability toggles in Settings → AI Executor can enable
/run, self-update, Elementor writes, media upload, exports, skills management, and filesystem writes /runis disabled by default and blocks common filesystem write/delete functions and shell/process execution when explicitly enabled/runvalidates changed Elementor data and blocks legacy sections/columns or missingwidgetType/elementor/validate,/elementor/page, and/elementor/updateprovide structured Elementor JSON validation and saving/auditreturns machine-readable page verification findings- write endpoints require a fresh guide token from
/guide/session+/guide/ack /self-updateis the only allowed plugin file write path and only writes the current plugin file from an immutable Git commit URL using an atomic replacement/skillsstores custom skills in the database, not as files- skills can include limited
enforcerules that runtime validators apply /media/uploadis the only non-plugin file write endpoint;/exports/createstores short-lived JSON inwp_options- For extra security on production, hard-code the key in
wp-config.phpand delete it fromwp_options
Compatibility
- WordPress 5.9+
- PHP 8.0+
- Works with any AI agent that can make HTTP requests
License
MIT