Skip to content

v3.4.0 — Themes, WP-CLI, SVG Uploads

Choose a tag to compare

@wpacademy wpacademy released this 14 Jul 21:23

A new Themes domain: give an AI agent full context on the active theme, manage its settings, and create a child theme so it can safely edit theme files.

Added

  • WP-CLI tools (4 tools, free, disabled-by-default). Let a connected AI run wp commands: run-wp-cli (synchronous — returns stdout/stderr/exit code), plus dispatch-wp-cli / get-wp-cli-job / list-wp-cli-jobs for background jobs (long migrations / bulk tasks run as a detached process you poll for status + output). Two execution modes: in-process via WP_CLI::runcommand() when connected over the WP-CLI stdio transport (no shell), or a proc_open shell path (argv array — no shell interpolation) when an admin configures a wp base command (Connection tab, or the EMCP_TOOLS_WPCLI_COMMAND constant) for HTTP/proxy connections. Guarded by a command blocklist (refuses eval, eval-file, shell, server, raw db query/cli/import, config set, package install, and injection/retarget flags --exec/--require/--path/--ssh) with a quote-aware, Windows-path-safe tokenizer; all four require manage_options, ship disabled-by-default (command-execution surface), and runs are recorded to the change ledger. New classes EMCP_Tools_WPCLI_Validator / _Runner / _Jobs (includes/wpcli/) + EMCP_Tools_WPCLI_Abilities; a new WP-CLI category on the Tools tab.
  • Themes tab: theme integrations (two dispatcher tools each). A new Themes sub-tab on the Tools screen, following the ACF two-dispatcher pattern (one Read tool, one Write tool, each bundling internal operations). Two layers on a shared base so new frameworks are cheap to add:
    • Active Theme (theme-read / theme-write, works for any active theme). theme-read: get-theme-context (active/parent, detected framework, is_block_theme, template dir, theme supports, registered menu locations, whether a child theme exists) and get-mods (theme_mod values). theme-write: set-mods (write theme_mod values, structural keys like menu locations refused) and create-child-theme (scaffold style.css + functions.php and activate a child of the active parent, so the agent can then edit theme files via the Filesystem tools; requires confirm:true, idempotent, refuses grandchildren).
    • Astra (astra-read / astra-write, registers only when Astra is the active theme). Generic get-settings ({ group? colors/typography/layout/header-footer, keys? }) and update-settings ({ values }) over a curated astra-settings allowlist, mirroring the WordPress Settings domain (typed metadata, non-allowlisted keys reported in skipped[]).
    • Spectra Blocks (spectra-read / spectra-write, registers only when the Spectra plugin (Ultimate Addons for Gutenberg) is active). The blocks/builder counterpart to the Astra theme pack, a Spectra-aware discover -> inspect -> act layer that mirrors the Elementor widget catalog. spectra-read: list-blocks (compact catalog of the site's Spectra blocks, with category/search filters, sourced live from Spectra's registry so nothing is guessed) and get-block-schema (a block's key attributes: real attribute names + defaults read from Spectra's own attributes.php, a highlighted subset by default or the first N capped, full:true for the whole set, plus a ready-to-use example and a doc link). spectra-write: add-block (insert a Spectra block into a post at a position, with a generated block_id; Spectra applies its own defaults, and container blocks like buttons get their required inner-block template). Building pages then reuses the existing Gutenberg block tools against the returned post.
    • Astra and Spectra are grouped as one "Astra + Spectra" section on the Themes tab, since they are a theme + blocks combo. Each tool's toggle is enabled only when its component is installed and active (Astra tools require the Astra theme; Spectra tools require the Spectra plugin) and is greyed out + disabled otherwise, the same way Elementor tools are gated when Elementor is inactive, with a per-card hint on how to enable it.
      Reads are enabled by default; the write dispatchers (theme-write / astra-write / spectra-write) ship disabled-by-default (opt in on the Tools tab). Building pages with a theme's blocks/patterns reuses the existing Gutenberg tools; this domain supplies the context. More framework packs (Kadence, GeneratePress) build on the same base.
  • SVG Uploads module (free, opt-in). A self-contained, safe way to allow SVG uploads to the Media Library without a third-party plugin — aimed at sites without Elementor (Elementor already permits SVG for authorized users). When enabled on the Modules tab it (1) registers the svg mime for users who can upload_files (or admins-only, a per-module toggle), (2) fixes wp_check_filetype_and_ext() so the real-content MIME check doesn't reject SVGs on the REST/sideload path (the piece most SVG plugins miss — so sideload-image and the MCP media tools can import SVGs), and (3) sanitizes every uploaded SVG with the bundled enshrined/svg-sanitize library (scripts, event handlers, javascript: URIs and external references stripped) — fail-closed: an SVG that can't be cleaned is rejected. Off by default given the security surface. New classes EMCP_Tools_SVG_Support_Module + EMCP_Tools_SVG_Sanitizer (includes/modules/svg-support/); enshrined/svg-sanitize is bundled in vendor/.
  • get-block-schema now surfaces Spectra's shared-helper attributes. A block's attributes.php (what get-block-schema reads) omits attributes registered via a shared helper — the container background image/video, border radius, and box shadow. The container schema now includes a shared_attributes map (with the real attribute names, e.g. backgroundType:'image' + backgroundImage:{id,url} + overlay, overlayType:'gradient' + gradientValue, containerBorder*Radius, boxShadow*) plus a schema_note steering agents to these native attributes instead of a core/html workaround.

Changed

  • search-images and sideload-image are now core WordPress tools — they register on any site regardless of Elementor (they only need a stock-provider API key + the Media Library), matching the plugin's beyond-Elementor philosophy. Previously both were gated behind Elementor being active. add-stock-image (which adds an image widget to the page) remains Elementor-gated.