A single timeline. Every version Respira has shipped, with the stories behind the ones that mattered. Click into any release tagged story for the full write-up.
Runtime Abilities API collision guard, in the plugin's own source
fixRuntime Abilities API collision guard, in the plugin's own source. 7.4.6's per-class guard is injected into the bundled wordpress/abilities-api by a Composer post-install script, which a from-source composer install --no
fixOxygen Classic page JSON now matches an editor-saved page exactly. build_page wrote the canonical _ct_builder_json tree with a bare id root and no per-node depth / ct_depth; a natively saved Oxygen 4.9.x page uses ct_id
June 15, 2026
No more Cannot declare class WP_Ability_Category site-down on Bedrock/Kinsta (WP 6.9+/7.0)
fixNo more Cannot declare class WP_Ability_Category site-down on Bedrock/Kinsta (WP 6.9+/7.0). On Bedrock layouts ABSPATH has no trailing slash, so the 7.4.2 collision guard's ABSPATH . WPINC join produced a malformed path,
fixOne-click "Connect to respira.press" no longer dead-ends on "you are not allowed to access this page." The OAuth round-trip returned the browser to a hidden admin alias that WordPress de-registers, so the final redirect
fixIn-place Divi 5 edits no longer collapse settings-shaped multi-element content. validate_render_critical_attrs is now settings-aware, so the validated inject path (used when an agent rebuilds an existing page) accepts th
June 14, 2026
Patch. Divi 5 page generation now produces native, editable, rendering modules from the looser content shapes agents actually send. Before, a homepage request often came back as
fixFIX: Divi 5 builds collapsed to plain text / a raw code block instead of native editable sections and modules. A new normalization pass lifts loose content synonyms (heading text, button text + url, paragraph content, ne
fixFIX: native Divi 5 modules could render as empty containers. The normalized content is now written to the settings bucket (which the complexifier expands into the title.innerContent.desktop.value / content.innerContent.d
fixFIX: a build whose attributes.content was a scalar string (e.g. divi/text) could fatal in the Divi 5 attribute-group deep-merge. The merge now runs only when the existing group is itself an array.
June 14, 2026
Patch. Oxygen 6 native page building. The agent now writes real, editable Oxygen 6 elements (sections, headings, text, buttons, images) instead of falling back to a single HTML
fixFIX: Oxygen 6 page generation collapsed to a single HTML code block instead of native, editable sections and modules. Respira's build path emitted Breakdance EssentialElements\* element classes, which a pure Oxygen 6 sit
fixFIX: update_element and extract/inject round-trips on Oxygen 6 could report success while persisting nothing — the edit landed in an attribute bucket the rebuild ignored. The Oxygen 6 build path now reads content from th
June 13, 2026
SmartCrawl Pro (WPMU DEV) SEO support
addSmartCrawl Pro (WPMU DEV) SEO support. Respira now detects SmartCrawl and writes and reads its native _wds_* post and term meta — title, meta description, focus keyword, canonical, and the split index/follow robots flags
fixElementor v4 atomic styles applied through an explicit styles:{} block were generated but never worn by the element. The flat-CSS write path already linked the minted style id into the element's class list; the styles-bl
fixElementor global colours: the kit's system colours (primary, secondary, text, accent) could not be changed. update_elementor_global_colors only ever wrote custom_colors, so passing a system _id appended a duplicate custo
fixDivi 5: a blurb's image was written to a group the renderer ignores, so it never appeared. Divi 5 reads the blurb image from imageIcon.innerContent.desktop.value.src and shows it only when useIcon is off; Respira wrote s
fixDivi 5: the bar counter targeted a module slug Divi 5 does not register. The number/percent → barProgress routing was keyed on divi/bar-counter / divi/bar-counters-item, which do not exist, so a counter rendered at 0%. I
fixDivi 5: an image's click-through link did not apply. image_url on divi/image wrote to …value.url, but Divi 5 reads the link from …value.linkUrl. It now writes linkUrl
June 13, 2026
Site-down fatal on WordPress 6.9+ ("Cannot declare class WP_Ability_Category")
fixSite-down fatal on WordPress 6.9+ ("Cannot declare class WP_Ability_Category"). The bundled wordpress/abilities-api polyfill loaded through Composer's files-autoload the moment the plugin required vendor/autoload.php, wh
June 12, 2026
Security validator false positive
fixSecurity validator false positive. The inline-event-handler pattern (/on\w+\s*=/i) matched onXXX= anywhere in content — including inside shortcode attribute values like button_text="Start minikursus for 222 kr.". The pat
fixPlaybooks not appearing in the ChatGPT tool list. get_ability_ids_for_adapter() called Respira_Playbooks::get_registered_ability_ids(), which reads from a static array populated during wp_abilities_api_init. That action
fixDivi 5.7 Visual Builder opens blank after Respira writes. Divi 5.7 changed its VB initialisation to read content from the WordPress autosave revision ({post_id}-autosave-v1) rather than the _et_pb_page_content meta. Page
fixDuplicated Divi 5.7 page appears empty in Visual Builder. Same root cause: newly duplicated pages have no autosave revision. Respira now seeds the revision at duplication time so the VB opens with the correct content
fixDivi code module becomes inaccessible after a CSS or HTML update. The same autosave-revision gap applied to targeted element updates: updating a code module's content wrote the new post_content but left the autosave revi
fixDivi 5 column widths collapse to 0px on a 3-column row. When an asymmetric flex column structure (e.g. 60/20/20) was distributed across 3 or more columns, the fractional percentages were computed correctly but the third
What the agent writes is what actually lands on the page
A deep pass through every supported builder, closing the gaps where a write reported success but the page stayed stale or blank. Styling now lands on Oxygen, Beaver Builder, Elementor v4 Atomic, Bricks, Divi 4 and Divi 5. Brizy and Visual Composer move from read to write, with their caveats stated. Recovery gets deeper: custom CSS and page settings are captured, and globals are versioned, so deleting a Bricks global class, a Divi preset, or an Elementor kit color leaves a recovery point. And when something cannot be persisted in a way the builder reads, Respira says exactly what did not land instead of reporting success. Every fix verified on a real site by loading the actual rendered page.
addBrizy moved from read to write. Respira can now write Brizy pages that Brizy's own editor opens and the front end renders. Writes are labeled with their caveats in the docs (front-end compile depends on Brizy's compiler
addVisual Composer moved from read to write. Respira now writes in VC's canonical storage format, so the editor loads the page and the front end renders. Labeled with its caveats (VC recompiles on the next editor save)
addGlobals are now versioned. Deleting a Bricks global class, a Divi preset, or an Elementor kit color now leaves a recovery point. "The agent deleted my global class" used to be unrecoverable; now you can roll it back. Res
addYour own custom CSS and page settings are now captured in snapshots, so the edits Respira makes to things like custom CSS are recoverable, not just the main content
addLoud-drop behaviour across builders. When a value cannot be persisted in a way the builder reads, Respira names exactly what did not land and tells the agent not to retry blindly. This is the systemic version of the per-
addAn internal check now runs across the test fleet to confirm that every builder function Respira calls actually exists in that builder. It would have caught several of the silent failures below the day they were written,
fixOxygen: generated CSS was being written without the selectors it needed, so styles never reached the page. Element styling now renders, and dynamic content resolves correctly. Code blocks that contained quotes could corr
June 12, 2026
respira_redeem_token returned an empty response in non-Cowork agents
fixrespira_redeem_token returned an empty response in non-Cowork agents (e.g. Antigravity). The redeem path bypasses the normal tool-call wrapper and returned a plain object; non-Claude clients that expect the standard {con
fixCowork token redemption now surfaces a RESPIRA_CONFIG_B64 update hint. When the MCP server is configured via the RESPIRA_CONFIG_B64 environment variable (common in managed hosting setups), redeeming a new Cowork token wr
addpost_parent schema exposed on update_page, create_post, update_post, and build_page tools. The plugin has always forwarded post_parent to WordPress, but the MCP schema didn't declare the parameter, so agents couldn't set
June 10, 2026
Divi 5 builds with rich native modules by default
addDivi 5 builds with rich native modules by default. The agent now advertises divi/heading, divi/text, divi/image, divi/button, and divi/blurb alongside the structural blocks. Before this, the only content block offered by
addDropped Divi 5 styling now fails loudly. When a style attribute is not supported on a Divi 5 module, the write still saves the content but now returns a clear dropped_settings summary naming exactly which styles did not
changeConnecting an AI assistant moved to the respira.press dashboard. The plugin's connect screen is now a status band plus one button that opens the dashboard MCP page with this site preselected (you land signed in). Pick yo
June 10, 2026
inject_builder_content now accepts target_path to add modules to an existing column
addinject_builder_content now accepts target_path to add modules to an existing column. Pass the path of the target container (e.g. target_path: "sections[0].rows[0].columns[0]") along with content containing the new module
fixPlaybooks now appear in the streamable MCP tools/list. get_ability_ids_for_adapter() never read from the WP Abilities registry, so respira-playbooks/* IDs (registered dynamically at boot) were invisible to ChatGPT and Cl
fixinject_builder_content now accepts target_path to add modules to an existing column. Pass the path of the target container (e.g. target_path: "sections[0].rows[0].columns[0]") along with content containing the new module
fixDivi 5 column nodes now appear as columns[n] in path strings instead of modules[n]. build_path_string() previously used modules[n] for every node at depth 2 or deeper, making columns and leaf modules indistinguishable. A
fixWebMCP input size limit raised from 100 KB to 10 MB. The wmcp_max_input_size default was set in 2023 before Divi 5 adoption. Pages with > ~50 KB of builder content failed silently with Tool execution failed. Raised to 10
fixElementor Pro Global Widgets no longer cause a PHP 500 after any page edit. simplify_structure() only preserved id/elType/settings/elements/widgetType/isInner, so the top-level templateID property on Global Widget elemen
June 10, 2026
Divi 5 build guidance points the agent at the rich native modules
changeDivi 5 build guidance points the agent at the rich native modules. The server's Divi 5 blurb now says heading, text, image, button, and blurb are advertised by default and safe to build with, and to prefer them over divi
changeNo more per-inject Divi 4 vs Divi 5 round-trip. The editing contract now tells the agent to auto-detect the version from the page (respira_get_builder_info / respira_read_page, with the plugin already flipping into Divi
addDropped-styling warnings are hoisted to the top of build results. When a Divi 5 (or any builder) write drops style settings the builder does not recognise, wordpress_inject_builder_content, wordpress_build_page, and word
June 9, 2026
The plugin details screen no longer reports "Compatible up to: 6.7"
fixThe plugin details screen no longer reports "Compatible up to: 6.7". The update checker hardcoded a stale tested-up-to value, so WordPress 7.0 sites saw a "This plugin has not been tested with your current version of Wor
improvedPrint / Save PDF on the activity report prints the report, not the admin screen. The button called window.print() on the live wp-admin page, so the PDF captured the whole admin chrome (the dark sidebar) and had no report
June 8, 2026
OAuth discovery now rides the REST API instead of /.well-known/
fixOAuth discovery now rides the REST API instead of /.well-known/. Connecting Claude Desktop by URL runs an OAuth handshake that starts by fetching a small discovery document. That document was only served at /.well-known/
June 8, 2026
Playbook runs are bracketed in one snapshot session
addPlaybook runs are bracketed in one snapshot session. Every write a playbook step makes already captured a before + after snapshot; those snapshots now all join one session for the run, and the playbook result returns rec
June 8, 2026
Playbook steps accept the hyphenated tool names MCP clients emit
fixPlaybook steps accept the hyphenated tool names MCP clients emit. A step naming a tool in the client form (e.g. respira_wordpress-create-page-duplicate, as ChatGPT exposes it) was rejected as "not in the playbook executi
fixElement-level tools reach their v2 routes from a playbook. The executor dispatched every step to the v1 REST namespace, but find_element, update_element, and the snapshot tools register only on v2, so those steps failed
fixupdate_element routes to the element-update endpoint, not update_module. The allowlist mapped respira_update_element to the update_module path (a whole-tree round trip that is lossy on Divi 4) and required a spurious bui
June 8, 2026
Element and widget tools no longer reject a valid post_id on the native MCP / WebMCP path
fixElement and widget tools no longer reject a valid post_id on the native MCP / WebMCP path. The WebMCP argument normalizer treated a self-referential argument map (post_id -> post_id) as a rename and deleted post_id befor
June 7, 2026
Cascade rollback (session-level recovery)
addCascade rollback (session-level recovery). Destructive structure operations that previously captured nothing — deleting an ACF field group, a custom post type, a taxonomy, or changing/deleting an option — now capture a r
addEditable ACF field groups from the no-code path. Field groups the agent creates now persist as real, wp-admin-editable acf-field-group posts instead of read-only PHP-registered groups, so a no-coder can adjust what the a
addACF field-quality guidance. The create-field-group path now steers the agent to the right field type (taxonomy / relationship / post_object / url / image) instead of defaulting everything to text, to set return_format on
changeMedia sideload by default for add_image. A remote image URL is now downloaded into the Media Library and the widget points at the local copy instead of hotlinking a third-party URL that can rot or hotlink-block. Re-addin
changeReversibility wording matched to behavior. In-product and agent-facing copy now states that snapshot + rollback covers every page/post edit and every destructive structure change, with whole-session cascade rollback, rat
June 7, 2026
Plugin version telemetry on activate and license check
addPlugin version telemetry on activate and license check. The plugin now includes its version in the activation payload and the periodic license validation request. Both are guarded, so an older build that does not define
June 7, 2026
report_issue over the site-URL MCP endpoint
addreport_issue over the site-URL MCP endpoint. OAuth and dashboard-token clients (ChatGPT, Claude Desktop, claude.ai) can now file a structured bug report from inside the chat. It validates title/brief/steps, attaches the
addlist_playbooks and create_playbook over the site-URL MCP endpoint. The playbook management verbs were registered only as REST routes, never as MCP abilities, so the native endpoint never surfaced them (the npm server cal
fixA full-page Divi write could fail security_validation_failed on its own legitimate markup. The trusted-builder-shortcode check stripped opening tags and leaf modules but left orphan closing tags ([/et_pb_column] ...) on
fixThe documented id module identifier silently returned module_not_found on Divi. update_module accepts module_identifier.id (the Divi module_id, e.g. "ole") and the API mapped it, but the Divi resolver had no case for it,
fixDivi section paths accept a bare or slash-prefixed index. path: "6" and path: "/6" now target the seventh top-level section (equivalent to sections[6]), alongside the existing sections[6] and dotted-index forms
June 7, 2026
update_module on Elementor returned a bare "module not found" (HTTP 500) for a widget id that find_element had just resolved
fixupdate_module on Elementor returned a bare "module not found" (HTTP 500) for a widget id that find_element had just resolved. On template-heavy sites the hero/H1 is often rendered into the page from a global widget or a
June 7, 2026
v2 tools over the native MCP endpoint returned "Missing required v2 scope: read_basic"
fixv2 tools over the native MCP endpoint returned "Missing required v2 scope: read_basic". Tools that dispatch through the WebMCP route-callback bridge (every *-v2 read/write tool: read-page-v2, read-post-v2, etc.) ran the
June 7, 2026
Cascade rollback tools
addCascade rollback tools. wordpress_restore_session undoes a whole session of changes in one call, restoring every distinct object a destructive multi-step task touched (pages, ACF field groups, post types, taxonomies, opt
changeACF field-group tool guidance. wordpress_create_acf_field_group now steers the agent to pick the right field type (taxonomy / relationship / post_object / url / image) rather than defaulting to text, to set return_format
changeReversibility wording matched to behavior in the server instructions and snapshot tool descriptions: rollback covers every page/post edit and every destructive structure change, with whole-session cascade rollback
June 6, 2026
update_module reported success but wrote nothing when an Elementor widget edit was sent under the builder-native settings bucket
fixupdate_module reported success but wrote nothing when an Elementor widget edit was sent under the builder-native settings bucket. Elementor stores widget attributes under settings (what get_attributes_key() returns and w
June 6, 2026
Playbook steps referencing a tool by its wordpress_* alias were still rejected as unknown
fixPlaybook steps referencing a tool by its wordpress_* alias were still rejected as unknown. 7.2.1 added six element/builder tools to the playbook executor allowlist, but the allowlist is keyed only by the respira_* canoni
June 6, 2026
Elementor v4 atomic widget writes (e.g. e-heading) could false-fail with respira_elementor_meta_write_unverified even though the write succe
fixElementor v4 atomic widget writes (e.g. e-heading) could false-fail with respira_elementor_meta_write_unverified even though the write succeeded. After writing _elementor_data, verify_elementor_meta_write() re-reads the
June 6, 2026
New Gutenberg blocks injected with mode:append could be invisible in the block editor even though they were saved
fixNew Gutenberg blocks injected with mode:append could be invisible in the block editor even though they were saved. complexify_blocks() used an agent-supplied simplified content field verbatim as a block's innerHTML, so a
June 6, 2026
get_site_context failed strict output validation over the native /mcp (OAuth) connector on any site with a page builder
fixget_site_context failed strict output validation over the native /mcp (OAuth) connector on any site with a page builder. The ability's declared output_schema said page_builder was a plain string, but the handler returns
fixupdate_plugin could leave a private plugin deactivated. Core's Plugin_Upgrader::upgrade() deactivates a plugin during the file swap and only reactivates it on success, so an update that fails or no-ops (e.g. a private pl
June 6, 2026
Divi 4 modules with a bracketed attribute value could be truncated on edit
fixDivi 4 modules with a bracketed attribute value could be truncated on edit. When a module carried an attribute whose value contains a ] inside quotes (the common case is a global color, which Divi serializes as global_co
fixbatch_update on Elementor wrote to the wrong attribute bucket. batch_update hardcoded 'attrs' as the key it patched, but Elementor stores element attributes under 'settings'. Batched edits on Elementor therefore wrote in
fixSix element and builder primitives were unreachable from playbooks. respira_create_page_duplicate, respira_create_post_duplicate, respira_extract_builder_content, respira_get_page_outline, respira_get_builder_inline_sche
fixClaude Desktop / claude.ai rejected the whole tool list when an inhaled ability had a union-typed input schema. The native /mcp endpoint passed each ability's inputSchema through unchanged. Some inhaled third-party abili
June 6, 2026
Connect by browser sign-in (OAuth 2.0)
addConnect by browser sign-in (OAuth 2.0). Claude Desktop, claude.ai, Claude Code, ChatGPT (Developer Mode), Cursor, and Codex can now add your site as a custom connector by URL. The app discovers respira.press as the autho
addThe native /mcp endpoint now advertises OAuth discovery per the MCP 2025-06-18 authorization spec: it serves /.well-known/oauth-protected-resource (RFC 9728) and its 401 carries a WWW-Authenticate: Bearer resource_metada
addNew "Connect by browser sign-in" panel on the Setup screen, showing your site's MCP URL and step-by-step instructions, with a copy-paste starter prompt. A new **Connected apps** page in the respira.press dashboard lists
secOAuth access tokens are bound to a single site (RFC 8707) and validated by introspection at respira.press: a token issued for one site is rejected on every other site. Tokens are short-lived, refresh on rotation with reu
June 6, 2026
Cowork token redemption could hang instead of failing with a clear error
fixCowork token redemption could hang instead of failing with a clear error. The respira_redeem_token fetch to respira.press was the only network call in the package without a timeout. On a slow network, a corporate proxy,
June 6, 2026
--doctor no longer hangs
fix--doctor no longer hangs. The health-check command is implemented, shown in --help, and recommended in error messages, but it was missing from the CLI dispatch in index.ts — so running npx @respira/wordpress-mcp-server -
June 6, 2026
Tool calls no longer get stuck on https://example.com
fixTool calls no longer get stuck on https://example.com. If the connector was ever started without a configuration, it wrote a placeholder file to ~/.respira/config.json pointing at example.com, and that placeholder then w
fixThe connector now accepts the credential names people actually reach for. Alongside WORDPRESS_URL / WORDPRESS_API_KEY, it now also reads RESPIRA_URL / RESPIRA_API_KEY and the --wordpress-url / --api-key command-line flag
June 5, 2026
Claude Desktop connector no longer crashes on connect
fixClaude Desktop connector no longer crashes on connect. The 7.1.0 bundle added a TLS bootstrap that relaunched the connector in a second Node process (to pass --use-system-ca). That re-exec works in a plain shell but brea
June 5, 2026
The connector now fails loud instead of stalling silently on startup
fixThe connector now fails loud instead of stalling silently on startup. An older installed build handed a newer dashboard setup code used to start, accept the connect handshake, then hang until Claude Desktop killed it abo
June 4, 2026
Nested Gutenberg blocks were dropped when updating or appending
fixNested Gutenberg blocks were dropped when updating or appending. A group, columns/column, or any container block round-tripped through the block simplifier came back as an empty wrapper, silently discarding every nested
fixdelete_plugin (and activate/deactivate/update) failed on plugin slugs containing dots. A mispackaged inactive plugin with a directory like three-dh-shopkit-0.5.58 returned rest_no_route because the plugin REST routes onl
June 3, 2026
path identifier returned "element not found" on every builder
fixpath identifier returned "element not found" on every builder. find_builder_targets emits a positional path like /0/0/0, but the shared tree resolver returned false for path matches and never walked to the node, so batch
fixArray-wrapped SEO meta corrupted the Rank Math / Yoast editor. When an agent sent a scalar SEO field (e.g. rank_math_title) wrapped as an array, it was stored as an array, which crashed the SEO editor in wp-admin (Rank M
June 3, 2026
Approval token rejected when retrying a slow destructive tool
fixApproval token rejected when retrying a slow destructive tool. The one-time approval token issued for tools like update_plugin was consumed on first validation. When the underlying operation ran long (a plugin download +
June 3, 2026
Screen Options pushed the admin layout
fixScreen Options pushed the admin layout. WordPress's Screen Options tab forced the v7.1 React admin header down and crowded the sidebar rail, which hid the light/dark theme toggle. The tab is now hidden on Respira admin s
fixMCP setup connection failed on 7.x. MCP clients up to v6.19.11 (the latest published) verify the connection against GET /wp-json/respira/v2/health. That probe had moved to /v2/status and /v2/health was no longer register
Redesigned admin, public add-on SDK, generate_activity_report
A React-first plugin admin built around live telemetry: a bridge view of agent ↔ Respira ↔ site, real cards driven by eleven new REST endpoints, and a personalised greeting. A public add-on SDK ships so third-party plugin authors can register their own MCP abilities. And a new MCP tool, generate_activity_report, turns this site's audit log into a structured report your own agent shapes into prose — six framings cover the use cases customers actually have, time-saved math is calibrated to conservative per-tool baselines, and Respira never writes a single line of prose itself.
addCode signatures (Respira_Bricks_Signatures). Bricks refuses to render code / svg / queryEditor elements on the frontend unless they carry a signature minted by Bricks with the site secret. Elements pushed through the RES
addStructural autofix (Respira_Bricks_Autofix). Pre-validation repair pass on the build / inject path: strips bare px (skipping raw-CSS / text / url keys), renames div → block, regenerates invalid or duplicate IDs and rewri
addQuirks coercion + warnings (Respira_Bricks_Quirks). Centralises Bricks settings footguns with a clear split: silently coerce the safe ones (link.postId / _link.postId int → string so the href actually emits; harvest imag
addResponsive inference — builder-agnostic. Explicit, idempotent, non-destructive action that generates tablet + mobile breakpoint overrides for a desktop-only page. The scaling tables + fluid clamp() math live in a builder
addDesign-token import (Respira_Design_Token_Import). Bring a Tailwind theme object, a Figma Tokens Studio export, or a Style Dictionary / DTCG file into Bricks. Colours land as palette swatches plus --color-* CSS variables
addSection presets (Respira_Bricks_Section_Presets). A curated library of production-ready Bricks sections (hero, features, CTA, testimonials, pricing, stats, FAQ) an agent drops onto a page. Each flattens to Bricks' native
June 1, 2026
Claude Desktop connector now trusts your system certificate store
fixClaude Desktop connector now trusts your system certificate store. The .mcpb wrapper relaunches with Node's --use-system-ca flag when the bundled Node supports it, and the MCP server also merges OS roots into its per-sit
fixTLS trust loading is additive only. Respira keeps Node's built-in roots, adds OS roots, then adds a bundled Mozilla fallback CA file when no custom CA is configured. Certificate verification remains on. Working setups sh
fixBetter certificate failure guidance. If certificate verification still fails, the error now explains that the connector already trusts the system store and points to the explicit per-site "insecureTLS": true override in
add.mcpb TLS settings. Claude Desktop extension settings now expose Skip TLS verification as a last-resort opt-out and Custom CA bundle path for private CA or corporate proxy roots
May 31, 2026
A customer on a LiteSpeed/cPanel site with a perfectly valid certificate (SSL Labs A, full chain) kept getting an SSL/TLS error and spent days checking a cert that was never the
fixThe UNABLE_TO_VERIFY_LEAF_SIGNATURE / SELF_SIGNED_CERT_IN_CHAIN connection hint now says the certificate could not be verified on this machine (and the site cert is probably fine), and points at local antivirus HTTPS sca
addA real TLS escape hatch that takes effect: per-site insecureTLS: true in ~/.respira/config.json, or RESPIRA_TLS_INSECURE=1 per process. Sets rejectUnauthorized: false on the client's own HTTPS agent (so it works even whe
May 30, 2026
Setup wizard points to the one-command AI-tool
changeprintNextSteps now leads with npx add-mcp "npx -y @respira/wordpress-mcp-server", which auto-detects the AI tool (Cursor, Claude Code, Windsurf, Codex, and more) and writes its config while preserving other MCP servers.
May 30, 2026
Clearer first-run setup
change--setup prerequisites now lead with "a free respira.press account" and explain the plugin download and license key both live in the dashboard.
changeThe "not ready" exit message and the in-prompt API-key hint point to signing in at respira.press and downloading from the dashboard, instead of /releases.
change--help Links: plugin location updated to the dashboard download.
May 29, 2026
routing_notice on write responses (default on)
addrouting_notice on write responses (default on). When a write tool runs against the default site because the caller omitted site_id AND more than one site is connected, the response envelope now carries a one-line routing
addRESPIRA_REQUIRE_SITE_ID strict-scoping flag (opt-in, default off). When set (1/true/yes/on) on a multi-site configuration, a write tool called without an explicit site_id is refused with respira_site_id_required instead
noteThis is NOT a fix for a broken site_id wiring. Per-call site_id has been honoured by every write tool (including inject_builder_content) since v6.12.0 — they all resolve through the same resolveClient(args) path, and an
May 28, 2026
Skills library Download action now points at the right GitHub org
fixSkills library Download action now points at the right GitHub org. Companion fix to v7.0.57: the catalog URL was corrected when the agent-skills-wordpress repo transferred webmyc → respira-press, but the per-skill Respir
noteBundled with companion mcp-server v6.19.7 which fixes the respira_duplicate_element schema. Pre-fix, the MCP tool exposed a single element_id arg, but the plugin route /builder/elements/duplicate/{id} has always required
May 28, 2026
write_was_noop detector is now builder-aware
fixwrite_was_noop detector is now builder-aware. Pre-fix the v7.0.61 byte-conservation check snapshotted post_content before and after the write. Four of the seven adapters (Elementor, Bricks, Beaver, Oxygen, Breakdance, Br
fixElementor update_element repeater controls can now shrink. Pre-fix, update_element merged the wrap-target attrs via array_replace_recursive. For repeater controls (icon_list, gallery, tabs, social_icons) that's index-bas
fixElementor _elementor_data decode survives stray invalid UTF-8 bytes. Pre-fix, payloads containing a single bad byte (lone surrogate, mid-codepoint splice from copy-paste) tripped json_decode → JSON_ERROR_UTF8 and fell ba
fixbuild_page on Elementor preserves declared children + canonicalises widget shorthand. Pre-fix, complexify_structure only walked $item['elements'] for children — payloads using the cross-builder children key (the document
fixread_theme_file extension parse is now locale-independent. Pre-fix, pathinfo($relative, PATHINFO_EXTENSION) returned ?y? for vds/css/custom.css and empty-string for vds/style.css on at least one VMG-Agency host with an e
fixMCP per-page builder auto-detect now reads active_builder.name. Pre-fix, the fallback resolver in extractBuilderContent / getPageOutline / getBuilderInlineSchemas read info?.name from /context/builder-info. The endpoint
May 28, 2026
Preserve the structured WP_Error envelope across the wire
fixPreserve the structured WP_Error envelope across the wire. wordpress-client.ts constructed an Error(API error (status): message) and mapped data.code to error.name, but every other field from the plugin's WP_Error data b
May 28, 2026
delete_media schema exposes approval_token + force
adddelete_media schema exposes approval_token + force. The destructive gate landed on the WP side in v7.1.0-beta.1 but the MCP schema didn't expose the params, so agents couldn't complete the two-step approval round-trip. N
fixB3 / N20: inject_builder_content Divi detector misclassified wrapped extracts. detectDiviContentFormat now unwraps the {content: [...]} round-trip shape via the shared helper before walking. Pre-fix, wrapped extracts ret
May 28, 2026
respira_duplicate_element schema now matches the plugin route contract
fixrespira_duplicate_element schema now matches the plugin route contract. Pre-fix, the tool exposed a single element_id arg, but the plugin route /builder/elements/duplicate/{id} has always required identifier_type + ident
May 28, 2026
Per-page builder auto-detect now reads active_builder.name
fixPer-page builder auto-detect now reads active_builder.name. The fallback resolver in extractBuilderContent, getPageOutline, and getBuilderInlineSchemas read info?.name when builder was omitted, but /context/builder-info
noteThe companion plugin v7.0.64 bundles five plugin-side fixes; the most important is making write_was_noop builder-aware so Elementor / Oxygen / Bricks / Beaver writes stop tripping the noop signal on every successful call
May 27, 2026
beforeSend filter requires at least one Respira stack frame
fixbeforeSend filter requires at least one Respira stack frame. The existing filter only matched third-party errors with at least one stack frame under /wp-content/plugins/. Errors from /wp-content/mu-plugins/ (GoDaddy gd-s
fixBulk-resolved the 17 pre-existing noise issues in Sentry so the dashboard reflects only actionable errors going forward. Confirmed pattern across all 17: WordPress core wp.media, mediaelement, jQuery UI accordion, GoDadd
noteGoing forward, the actionable Sentry queue should stay near zero except when a real Respira-side error fires. If the new filter is too strict and drops a real Respira bug, the symptom will be "user reports issue but Sent
noteThis is plugin-side (admin JS); server-side PHP exception capture via \Sentry\init() upstream is unchanged.
May 27, 2026
Tree_Utility::reorder() accepts new_order as element IDs, not just integer positions
fixTree_Utility::reorder() accepts new_order as element IDs, not just integer positions. Pre-fix the method expected [2, 0, 1] integer positions in the container's current children array. Every MCP caller naturally passes e
noteThis is the third v7.0.59 aftermath ship (move_element 400 in 7.0.60, reorder_elements TypeError in 7.0.60, reorder_elements wrong-shape in 7.0.62). Same reporter found all three. The v7.0.59 11-bug bundle release exerci
noteVerified the new path against synthetic shapes covering: integer-position legacy callers, MCP id-shape callers, mixed-case where one id is unknown (must reject the whole reorder, not partial), and root-level container re
May 27, 2026
update_element response now carries write_diag + write_was_noop warning
improveddelete_page / delete_post respira_not_duplicate error message now names the existing duplicate id and tells the agent which call to make next. Pre-fix: "Only Respira duplicates can be deleted." Post-fix: "Cannot delete t
improvedget_option respira_option_not_found now returns fuzzy-name suggestions. Up to 5 closest matches from the site's actual options table, ranked by Levenshtein distance against the requested name. Tool at 64% success on 193
noteVerified all three changes lint clean and preserve back-compat. write_was_noop is purely additive (response shape gains two new top-level keys plus a conditional warning + warning_hint pair). Existing clients ignore unkn
noteThe update_element noop guard works across every builder adapter because it operates on post_content bytes after the adapter has run, not on the adapter's internal tree shape. Catches the bug class even when a specific a
noteNext in this MCP-quality batch (queued for v7.0.62): read_post suggest-next-tool on respira_post_not_found, apply_builder_patch concrete-example error envelope, update_module p95 latency profiling (currently 21.4s p95 on
fixmove_element HTTP 400 "Missing parameter(s): element_id_type, element_id_value" (bug 7f34f776). The MCP 6.19.3 align-to-identifier_type/identifier_value shift landed cleanly on the MCP side AND on the move_element HANDLE
fixreorder_elements HTTP 500 TypeError: explode(): Argument #2 ($string) must be of type string, array given (bug 30c083e3). Double-parse of container_path between layers. The REST handler at Respira_Element_Ops::reorder_el
noteBoth fixes are narrow (1 route registration entry + 1 typecheck block). No data migration, no breaking change for any existing caller shape.
noteSame reporter noted the documented respira_report_issue 401 from MCP — the bearer-on-license_key fix shipped yesterday in d89601b6 and is already live on respira.press. Their next bug should flow through the tool.
May 27, 2026
Divi 4 extract+inject round trip preserves per-column children order
fixDivi 4 extract+inject round trip preserves per-column children order. parse_divi_shortcodes flattened columns via array_merge and lost per-column boundaries; build_divi_shortcodes then round-robin'd children back across
fixElementor v3 Nested Element widgets — page-level saves no longer strip widget-level elements[]. complexify_structure only re-emitted $element['elements'] when the elType was a known container (v3 section/container/column
fixGutenberg update_element with {content: "..."} now persists to post_content. The universal interface wrapped any flat patch missing a "structural" key into the adapter's attrs bucket. For Gutenberg that meant {content: "
fixDivi 5 layout validator no longer over-rejects on append writes. B.W. reported every add_section / add_html / append-mode inject_builder_content failing with 16 verbatim "row should be inside section or column" errors —
fixDivi 5 approve/merge no longer corrupts < and > to literal "u003c". approve_duplicate_by_merging_into_original passed the duplicate's unslashed post_content straight to wp_update_post, which wp_unslash()s internally befo
fixmove_element no longer silently deletes; reorder_elements no longer 500s. The MCP schemas shipped param names the plugin handlers never read. move_element sent element_id + target_container_id while the plugin expected i
May 27, 2026
wordpress_create_playbook
addwordpress_create_playbook. Authors a JSON workflow composition that registers itself as a WordPress Ability and shows up as a callable tool on the next MCP handshake. The agent describes the workflow once, Respira stores
addwordpress_list_playbooks. Read-only enumeration of every Playbook on the site, with id / ability_id / label / step count / invocation_count / last_invoked_at. Use for "what playbooks are available" discovery before autho
addwordpress_get_playbook. Read one Playbook's full definition (input_schema, steps, returns template, audit metadata)
addwordpress_update_playbook. Modify an existing Playbook in place. Id is immutable. The destructive-tool check runs again on every update
addwordpress_delete_playbook. Drops a Playbook + its registered Ability. The Ability disappears from the MCP catalog on next handshake. Existing posts / data created by past invocations are not touched
internalAll five route through the generic callRestV1 wrapper added in v6.20.0 — no new client wrappers needed.
addwordpress_create_post_type / update / delete / list_custom_post_types. Agent provisions a new CPT in one call. Slug allowlist enforced server-side (lowercase, letters/digits/underscore, 1-20 chars, no reserved slugs like
addwordpress_create_taxonomy / update / delete / list_custom_taxonomies. Same shape as the CPT surface. Attaches to one or more post types via the post_types array. Hierarchical (category-like) or flat (tag-like) via the hi
addwordpress_create_acf_field_group / update / delete / list_acf_field_groups. ACF (free or Pro) must be active — all four refuse with respira_acf_not_active otherwise. Fields and location rules pass through ACF's canonical
internalNew callRestV1 helper on wordpress-client.ts. Mirror of the existing callRestV2 for endpoints under /wp-json/respira/v1/. The 12 new tools route through this so no per-tool wrapper method was needed
noteAll twelve write tools are manage_options-gated on the WP side. Lite version stays read-only — Pro-only for the v7.1 ship.
noteStructure definitions are stored in wp_options (respira_custom_post_types, respira_custom_taxonomies, respira_custom_acf_field_groups). Site export/import via wp-cli covers them automatically; no migration script require
May 27, 2026
respira_update_element exposes edit_target + confirm_live_edit at the top level
addrespira_update_element exposes edit_target + confirm_live_edit at the top level. [#3](https://github.com/respira-press/respira-wordpress-mcp/issues/3) (madeat3am, 2026-05-21). On a Bricks site with respira_allow_direct_e
note[#1](https://github.com/respira-press/respira-wordpress-mcp/issues/1) (remove_element parameter shape) was already resolved. Filed 2026-04-07 against MCP v5.5.0 and plugin v5.5.5. The MCP schema sent element_id while the
note[#2](https://github.com/respira-press/respira-wordpress-mcp/issues/2) (move_element parameter shape) was already resolved. Filed 2026-04-07 against the same setup. End-to-end fix landed in plugin v7.0.60 (which accepts b
May 27, 2026
wordpress_update_element surfaces the plugin's new write_was_noop warning at the tool-result level
addwordpress_update_element surfaces the plugin's new write_was_noop warning at the tool-result level. Plugin v7.0.61 adds write_diag + warning: "write_was_noop" to the update_element response when post_content did not chan
addwordpress_upload_media pre-flight size check. Dashboard showed 50.7% success / p95 = 120 SECONDS / 34.8% timeout >60s. Almost the entire long tail is the agent passing a base64 payload of a large image — the per-call wat
changeNode floor raised from 18 → 20. Node 18 went end-of-life 2025-04-30, npm 11 requires Node 20.17+, and @supabase/supabase-js already prints a deprecation warning on Node 18. Telemetry shows the median customer Node versio
May 27, 2026
Per-client HTTP agents + destroy-on-watchdog-trip
fixPer-client HTTP agents + destroy-on-watchdog-trip. Pre-v6.19.3 the WordPressClient axios instances used Node's shared http.globalAgent / https.globalAgent. When a write tool hung past RESPIRA_MAX_TOOL_TIMEOUT_MS the watc
fixrestore_snapshot polls for completion when the request times out. Heavy Divi / Oxygen pages can take 1-3 min to restore; pre-v6.19.3 the synchronous POST exceeded axios's 30s timeout even though the server-side restore c
rmwordpress_search_abilities MCP tool. Hit /wp-json/respira/v1/abilities/search, a route the plugin never registered. Every call 404'd. wordpress_get_builder_info + wordpress_search_docs cover the discoverable surface; wor
schemawordpress_move_element + wordpress_reorder_elements aligned with the plugin contract. The MCP schemas shipped param names the plugin handlers never read; the plugin handlers had to be patched in 7.0.59 to accept the lega
May 27, 2026
Released 2026-05-27.
changeReleased 2026-05-27.
addProduct brand support (product_brand taxonomy). The update-product and create-product abilities now accept brand_ids so an AI can assign or clear brands on a product the same way it already assigns categories and tags. Full CRUD endpoints l
addFeatured-image removal. The update-product ability now accepts image_id. Pass an attachment ID to set; pass 0 or null to remove the featured image. Previously the only image-related field on the response was a read-only URL; agents had no w
schemaProduct response shape gains brand_ids, brands, and image_id. image is unchanged.
May 25, 2026
"Approve all visible" button on the Changes / Approvals page
add"Approve all visible" button on the Changes / Approvals page. Renders only when respira_enable_bulk_approvals is on AND there are pending duplicates. The button shows the live pending count next to its label (Approve all
addrespira_list_pending_duplicate_ids AJAX endpoint. Returns the array of every post ID where _respira_duplicate=1 AND post_status IN ('draft','pending'), ordered by post_modified DESC. Same nonce + manage_options gate as t
addbulk_approvals_enabled + pending_duplicate_count flags in the localized respira_admin JS object. Lets the new button gate itself client-side without an extra round trip — hidden when the setting is off or the queue is em
noteNo new permission surface. The same manage_options capability + respira_enable_bulk_approvals toggle that gated the backend handler since 4.0.11 still gate the UI. The default for the toggle stays OFF for safety; admins
noteThe bulk handler is conservative — it never force-approves (every per-item call passes force: false). If a duplicate's original has changed since the duplicate was created, that one item shows in the per-item failure lis
May 24, 2026
Skills catalog URL points at the right GitHub org
fixSkills catalog URL points at the right GitHub org. The Respira_Admin::fetch_skills_catalog() helper still pulled from https://raw.githubusercontent.com/webmyc/agent-skills-wordpress/main/skills.json, but the repo was tra
noteBecause the pre-fix code path returned the error without setting the transient cache, no client-side cache needs busting. The fix takes effect on the first page load after upgrade.
noteOne-line URL change in admin/class-respira-admin.php plus a comment block that records why raw.githubusercontent.com is fragile to repo transfers, so the next maintainer doesn't reintroduce the same bug.
May 24, 2026
rest_no_route errors now carry the attempted path
fixrest_no_route errors now carry the attempted path. Previously, when WordPress returned rest_no_route (54 hits across two sites the week of 2026-05-24), the MCP recorded the generic WP string "No route was found matching
changeinject_builder_content description now lists Divi render-critical attrs. When any of the 10 Divi module types in the validator is missing its required attr (e.g. divi/heading without title, divi/button without button_tex
changeread_theme_file description hardened against non-stylesheet attempts. The schema already enforced .css / .scss / .less / .json, but agents kept trying .php / .html (5 hits the week of 2026-05-24, returning respira_theme_
May 24, 2026
Generic Error bucket in tool telemetry
fixGeneric Error bucket in tool telemetry. The dispatch wrapper at server.ts recorded error_code from Error.name, but ~6 tool wrappers (find_element, inject_builder_content, upload_media, batch_update, update_custom_post, a
addrespira_run_pagespeed_audit + respira_analyze_pagespeed (Phase E Tier 2). Real PageSpeed Insights v5 audit replaces the heuristic CWV path. respira_run_pagespeed_audit returns Lighthouse lab data (scores for performance/
addget_accessibility_scan schema accepts UUID strings. N15 — pre-fix the input schema declared scan_id: number but list_accessibility_scans returns UUID strings, so the two tools couldn't be paired
addlist_accessibility_scans pagination + summary mode. N16 — added limit, offset, summary_only (default true) params. Summary mode strips violations[].nodes and per-violation AI fix prompts; full payload remains via get_acc
addget_snapshot include opt-in. N26 — defaults to metadata-only (~5KB); pass include=content for the full builder payload (~78KB)
fixN6: site_id envelope leak. Every tool response carried site: <default site> even when a per-call site_id override resolved correctly. The MCP correctly serviced the call against the override but reported the default in t
fixN9: schema gaps on 5 destructive tools. create_user, update_user, delete_user, delete_custom_post, delete_menu all enforce server-side approval/force gates but the MCP schemas didn't expose the params. Added approval_tok
May 23, 2026
Divi is_builder_used() vetoes itself when _et_pb_use_builder='off'
fixDivi is_builder_used() vetoes itself when _et_pb_use_builder='off'. The explicit 'off' value is the user's signal that Divi is NOT active on this post (even though stale _et_pb_page_* meta from a previous Divi-active per
addupdate_element response now carries builder.name and builder.version. Surfaces the picked adapter directly in the response envelope so silent-write reports can name the adapter that claimed the post without a separate re
noteThe Lite plugin's is_divi_page() already vetoed on 'off' === $et_pb_use (only returns true on 'on'), so Lite was never affected and no sync port is needed.
noteOnce the customer confirms v7.0.56 lands the write correctly, the broader detect_builder() audit (theme-tiebreaker rule should also respect explicit per-post disables across all builders, not just Divi) is queued separat
May 23, 2026
expected_type opt-in pre-write validation on update_module for Divi 4
addexpected_type opt-in pre-write validation on update_module for Divi 4. Callers (MCP clients, apply_builder_patch, batch_update) can pass expected_type: 'et_pb_text' in the updates payload. If the resolver lands on a modu
addexpected_type and _skip_truncation_check are now also stripped from the attribute patch automatically so they cannot accidentally land in module attributes if a caller forgets to extract them.
noteThe root-cause fix (rewriting the path resolver to follow the nested children[] tree rather than the flat row-column merge) is queued for v7.0.56. Until then, agent clients calling Divi 4 update_module on multi-column ro
noteThe MCP server's update_module tool description will get a matching update in the next mcp-server release to advertise expected_type and recommend its use on Divi 4. Plugin-side ship goes out first so the surface is ther
May 23, 2026
Gutenberg is_builder_used() disqualifier checks values, not just key presence
fixGutenberg is_builder_used() disqualifier checks values, not just key presence. Each "other-builder" meta key now carries a predicate matching the source builder's own activity convention:
noteVerified the failure mode against M.P.'s exact scenario: a post duplicated from an original that has _et_pb_use_builder=off will, pre-v7.0.54, fall through Gutenberg's claim check despite Gutenberg being the only sensibl
noteThe pre-v7.0.54 disqualifier list pattern (presence-only) is a common code-smell across builder adapters. Future cleanup is queued to audit the cross-builder claim logic for the same stale-key class of bug, but for v7.0.
fixBricks option-group write endpoints recursively strip _respira_* keys from request bodies. handle_create_item was already stripping _respira_key_data at the top level only; expanded to recursive scrub_respira_internals()
fixupdate_element / element-ops envelope is_duplicate now matches the actually-resolved write target. Pre-v7.0.53, Respira_Element_Ops::target_metadata() read is_duplicate from resolve_mutation_target()'s output, which eval
fixGutenberg inject_content now guards the write against third-party save_post reverts AND verifies persistence. The customer report: 9 successive duplicates (340148, 340151, 340153, 340155, 340157, 340159, 340161, 340163,
noteThe Gutenberg silent-revert family also lives in the Divi adapter's update path for posts (Divi was enabled-then-disabled mid-session on the customer site, so duplicate detection may still route through Divi while Gutenb
noteThe Bricks scrub does not delete leaked data from already-corrupted rows — it strips at READ + WRITE. A separate one-shot migration to scrub stored values is queued but not blocking: the READ scrub keeps the leak out of
fixB-7: inject_builder_content rejects simplified types. Pre-fix the detector returned unknown for payloads using simplified types (section, row, column, heading, etc. without divi/ or et_pb_ prefix) and hard-failed with "D
fix{content: [...]} wrapper unwrap. Round-tripped extracts come back as {content: [...]}. The new unwrapBuilderContent helper normalises before forwarding so every downstream caller sees the same shape
fixCamrin@cspmarketingsolutions friendly→canonical param translation. Three structural tools (move_element, duplicate_element, reorder_elements) advertised friendly param names but the REST endpoints required typed pairs. D
May 22, 2026
Truncation guard in Respira_API::update_element only fires on REAL truncation now
fixTruncation guard in Respira_API::update_element only fires on REAL truncation now. Pre-v7.0.52 the guard at class-respira-api.php line 6159 compared the byte length of $updates['content'] (input) to the byte length of th
fixcontent + text identifier_types skip the verify step entirely. For those identifier shapes the post-write find_module is unreliable BY DESIGN (the identifier string was the thing we just changed). No verify, no false pos
fixNew updates._skip_truncation_check: true opt-out for callers that know the verify-find would land on the wrong node. Safety hatch — the guard stays opt-in-default for paths where it does catch real truncation
noteBug #1 from Morgan's report (update_element with match_content targets the FIRST match instead of the DEEPEST match) is actually addressed correctly by the v6.11.1+ find_divi4_shortcode deepest-match logic at class-build
noteBug #3 (4-minute timeout on update_page / inject_builder_content for ~113KB Divi shortcode pages) is the same large-page complexify-tree-walk overhead that bit M.P. on Fischers Fritze. Belongs to v7.1.
noteThe customer-facing impact of the false positive was severe: Morgan saw "tool failed" on a write that had actually persisted his changes correctly, retried via a workaround that bypassed type validation, and corrupted hi
May 21, 2026
Respira_Builder_Tree_Utility::matches() content identifier_type now deep-searches options / attrs / settings
fixRespira_Builder_Tree_Utility::matches() content identifier_type now deep-searches options / attrs / settings. Pre-7.0.51 the content matcher only checked $element['content'] (Elementor / Divi 4 top-level string) and $ele
fixupdate_element adds a normalize_element_updates($existing_element, $updates, $wrap_target) hook on Respira_Builder_Interface; Oxygen overrides it to route ct_image / ct_image_overlay flat patches into options.original. P
noteVerified end-to-end on Studio :8882 with Oxygen Classic 4.9.7. Test fixture: synthetic page with a ct_text_block whose options.ct_content is "Hello world<br>this is a paragraph ending in br" plus a ct_image with options.
noteThe normalize_element_updates hook lands on the interface as an optional method — adapters that don't override it pay no cost. Future adapter-specific patch normalisations (Beaver's nested font field family, Breakdance's
noteWider M.P. Härtetest findings: items #1, #2, #3, #5 are addressed by v7.0.47 → v7.0.50 (already shipped); the 4-minute timeout he flagged separately should also clear once v7.0.49's auto-heal removes the upstream 500 tri
May 21, 2026
divi_render_critical_attrs() no longer flags divi/column nodes missing attrs.type
fixdivi_render_critical_attrs() no longer flags divi/column nodes missing attrs.type. The render-critical-attrs map was introduced in v7.0.0 Bloom Phase B to catch LLM hand-writes that would render empty (heading without ti
noteVerified on Studio :8882 with synthetic 5-section Divi 5 tree containing 9 divi/column nodes with attrs => [] (the round-trip shape): validator returns 0 entries. Counter-test with deliberately bad leaf modules (heading
noteThis release narrows the validator surface but does NOT fix the broader inconsistency between build_page (skip validator) and inject_builder_content (apply validator). That's a deliberate scope decision: the column rule
noteThe Nettl reporter posted a very precise repro (5 sections, 4 rows, exact node counts) plus a working hypothesis pointing at content.innerContent. The actual root was different but the report's structured shape made the
May 21, 2026
update_page auto-heals a poisoned _wp_page_template before wp_update_post fires
fixupdate_page auto-heals a poisoned _wp_page_template before wp_update_post fires. Reads the existing value, validates against wp_get_theme()->get_page_templates($post, $post_type) (same method WP core's REST controller us
noteVerified on Studio :8882 with uncode theme active (registers 0 page templates). Test fixture: page poisoned with _wp_page_template=ct_template, then wp_update_post fired. Pre-v7.0.49: WP_Error invalid_page_template. Post
noteResolves the persisted-bad-state half of the M.P. bug. The 4-minute read timeout signal he separately flagged is almost certainly a follow-on of the 500 — a save_post hook chain (Cloudflare cache purge / Wordfence rescan
noteThe v7.0.48 guard stays in place. Defence-in-depth: v7.0.48 prevents new poisoned writes; v7.0.49 cleans up existing poisoned values; v7.0.47's shutdown handler still localises any remaining throws. M.P. should see clean
noteThe auto-heal only fires when needed (existing value present + not registered + not baseline). Pages with a registered template are unchanged. Pages with no template are unchanged. Zero behavioural impact on the 99% of i
May 21, 2026
Respira_API::update_post_meta_fields() validates _wp_page_template against the active theme's registered templates
fixRespira_API::update_post_meta_fields() validates _wp_page_template against the active theme's registered templates. Uses wp_get_theme()->get_page_templates($post, $post_type) (the same method WP core's REST controller us
fixRespira_Builder_Oxygen::inject_content() validates ct_template before the auto-set. Pre-7.0.48 the Oxygen adapter wrote _wp_page_template=ct_template whenever the existing value was empty or 'default', no matter whether
noteVerified end-to-end on Studio :8882 with Uncode theme active and Oxygen Classic 4.9.7 active. get_page_templates() returns an empty array on that stack. Test fixture: API call with _wp_page_template=ct_template correctly
noteThe v7.0.39 diagnostic envelope + v7.0.47 shutdown handler stay in place. Together with the v7.0.48 source-side guard the layered defence is: (a) bad value never reaches WP_REST_Posts_Controller (this release), (b) if so
noteThe Oxygen adapter still logs the skip explicitly because losing the page-template auto-set CAN matter on themes that override the page render. The customer-facing impact in that case is "page renders via theme template
May 21, 2026
New Respira_Analyzable_Content::html_for($post_id) shared content extractor; SEO / readability / Rank Math / performance / image / AEO analy
fixNew Respira_Analyzable_Content::html_for($post_id) shared content extractor; SEO / readability / Rank Math / performance / image / AEO analyzers all route through it. Detects the active builder via Respira_Builder_Interf
fixupdate_element REST handler now wraps register_shutdown_function around the request lifecycle. v7.0.39 added try/catch \Throwable on every userland exit site, but PHP-level fatals (memory exhaustion mid-request, max_exec
noteThe new extractor file (includes/analyzers/class-respira-analyzable-content.php) is included once per analyzer class file via if ( ! class_exists ) require_once. The five existing analyzer classes (class-respira-seo-anal
noteWPBakery / Bricks / Breakdance extractors are queued for the next ship. Today the dispatcher returns $post->post_content for those builders, which is at worst the same false negative the audit reported before this fix —
noteStudio test pattern for the next builders to come online: build a fresh page with empty post_content + populate the builder's native postmeta key with a minimal synthetic tree, then call each analyzer's analyze_* method
noteThe shutdown-handler change is additive over v7.0.39's userland try/catch — both run, and the userland catch still wins on every non-fatal throw. The shutdown hook only fires when PHP-level shutdown carries a fatal error
May 21, 2026
Tree_Utility::matches() type+match_content branch deep-searches attributes / attrs / settings for the needle
fixTree_Utility::matches() type+match_content branch deep-searches attributes / attrs / settings for the needle. Pre-7.0.46 the branch only ran stripos($element['content'], $match_content). Self-closing Divi 4 modules (et_p
noteCloses the github #32 follow-up surface P.L. raised — third increment on this issue but the underlying bug was always one piece deeper than the previous fix suggested. v7.0.29 added attribute-text matching for update_mod
noteVerified by inspection: the new match path uses text_contains for the content body (HTML-tolerant via the existing v6.5.1 sanitiser) and any_string_contains for the attribute buckets (recursive deep-search). Both helpers
May 21, 2026
batch_update per-operation resolver now forwards match_content to Tree_Utility::find()
fixbatch_update per-operation resolver now forwards match_content to Tree_Utility::find(). Pre-7.0.45 the call site only passed 4 args (the optional 5th match_content was dropped), so any batch operation targeting a specifi
fixbatch_update remove action gets the same fix. Both actions in the same method use the same shared $op_match_content variable
noteOperator-trapping severity: pre-fix the API returned success: true with the write landing on the wrong element. Mid-batch silent data loss with a green-status response.
noteCloses github #32. The Divi 4 customer surface arc (P.L. / Catholic Mass Times) over the v7.0.29 -> v7.0.45 chain: kses corruption (closed v7.0.29), column corruption (closed v7.0.29), silent no-op (closed v7.0.29), per-
May 19, 2026
wp.org review fixes
changeDisplay name updated to "Inhale: MCP Abilities by Respira" so the author attribution is visible in wp-admin plugin lists. Slug inhale-mcp-abilities is unchanged.
changeContributors field in readme.txt now lists urbankidro (the wp.org username that owns the plugin) instead of the brand string. The Author header still reads "Respira" so the visible attribution on the directory page is un
changeuninstall.php updated to remove the new primary key, the v0.4.0 migration flag, the canonical compat key, and every legacy key from v0.1.x and v0.2.x. Single-site and multisite sweep.
May 18, 2026
WordPress.org Plugin Directory submission
changeCanonical option key. v0.2.0+ stores the opted-in list under mcp_adapter_public_abilities — the same key proposed first-party in [WordPress/mcp-adapter#184](https://github.com/WordPress/mcp-adapter/pull/184). A one-shot
changeBrand-aligned chrome. Header with "by respira.press" Baskervville italic subtitle and a tiny version pill in the right-side toolbar. Light and dark themes both render with AA contrast
changeiOS-style toggle in the Status column for fast per-row inhale / exhale, on top of the standard wp-admin bulk-actions pattern
changeForeign admin notices suppressed on the Inhale settings page only, so the screen stays focused on the one decision it exists to support
changeHardened uninstall. Removes every option the plugin has ever written, single-site and multisite
changePlugin Directory readiness pass. ABSPATH guards on every shipped PHP file. Every output escaped. Every state-changing request nonce-verified and capability-gated. No remote calls, no tracking, no obfuscation, no bundled
May 17, 2026
hardening pass
changewp_die response code 403 + back link on the settings page permission denial path. Access logs and automated clients now see an authorization failure instead of a generic error
changeRow class escaping normalised: the abilities table's <tr class="…"> attribute is always rendered through esc_attr() instead of conditionally injecting the attribute fragment. No behavioral change, but conforms more stric
May 17, 2026
first public release
changeDiscovers every ability registered via the WordPress Abilities API and lists them in a wp-admin native list table.
changeStandard wp-admin selection + bulk-action UX: row checkboxes are selection; Bulk Actions dropdown plus Apply commits Inhale or Exhale immediately. No save-changes step.
changeRow-hover quick actions for single-ability inhale or exhale.
changeAnnotation badges on each ability (read-only, destructive, idempotent) sourced from the ability's declared meta; falls back to heuristic inference from the ability name when the registering plugin didn't tag it.
changeFilter views (All, Inhaled, Read-only, Destructive, Unannotated), a search box that matches across name / source / description, sortable columns, multi-select source filter, client-side pagination (20/50/100/All).
changeSources summary card above the table listing every plugin or theme that registers abilities, with the count per source and deep-links to each source's wp-admin home.
May 10, 2026
Zero-touch Cowork onboarding (Open in Cowork)
change.mcp.json sets RESPIRA_BOOTSTRAP_OK=1 so the npx server boots even without a config file present.
changeExisting RESPIRA_CONFIG_FILE, RESPIRA_AGENT_CLIENT, RESPIRA_AGENT_TRANSPORT env vars unchanged.
changeVersion label bumped in plugin.json and README.md.
changeThe skill-documented config shape ({url, apiKey}) crashed the MCP server silently on startup because the server required four fields (id, name, url, apiKey). User saw "MCP server still connecting…" forever.
changeThe Cowork form echoed pasted API keys into the chat transcript, contradicting the skill's own privacy promise.
change.mcp.json points RESPIRA_CONFIG_FILE at ~/.respira/config.json.
changenpm dependency pinned to @respira/wordpress-mcp-server@latest so the server schema fix lands immediately.
change/respira:connect-site skill rewritten: check for ~/.respira/config.json, point user at the dashboard to download it if missing, restart Cowork, test. Includes a "if startup fails" branch that reads ~/.respira/last-startu
changeREADME.md and INSTALL.md updated to describe the unified flow.
May 9, 2026
audience-first README rewrite
changeEdit a page without opening WP admin ("Update the headline on my client's homepage to say 'spring collection arriving'", about thirty seconds end to end)
changeMigrate a client site between page builders (sixteen supported paths, week of work into an afternoon)
changeAudit a site before a client meeting (SEO, AI search visibility, accessibility, mobile, technical debt, WooCommerce, with one-click fixes)
changeClean up a media library in one pass (alt text, compression, dimensions)
changeManage ten client sites from one conversation (multi-site context follows the conversation naturally)
changeNo code changes.
May 9, 2026
README accuracy pass: 30 skills
change8 slash commands for the most common workflows
change30 auto activating skills, broken down as:
change1 visual reviewer sub agent that shows what changed after every edit
changeFull access to all 180+ Respira MCP tools through the bundled @respira/wordpress-mcp-server
Every page-builder adapter promoted to deeper-intelligence parity
The biggest release since v5. Every builder adapter promoted in lockstep. Five cross-cutting Phase A invariants every adapter now inherits — render-validation gate, universal write-trace, Variables CRUD shape, source-driven catalog auto-scan, per-property typed validators — plus Phase B slices per builder that close the family-bug arcs surfaced across v6.10.x. 1076 standalone test assertions across 27 alpha cycles, zero failures.
phaseA.1 Render-validation gate. Post-write check: HEAD-fetch the preview URL plus parser-walk the persisted blob using the parser the adapter declares. 9 parser slugs ship. Either failing surfaces partial_write: true with st
Closes 14 customer bugs across 5 named trials and 7 GitHub issues
The release I should have shipped weeks ago. Closes 14 customer-reported bugs across 5 named trial threads and all 7 open public GitHub issues, plus 5 cross-cutting audits — JSON post-meta unicode safety across every adapter, MCP server tool-schema audit, duplicator kses bypass, schema endpoints anon-readable, render-trace fields on every write. New respira_diagnose_connection tool surfaces edge-layer interception so REST returning homepage HTML instead of JSON stops being opaque.
Self-updater fatal on every WP cron tick. class-updater.php:104 called \Respira_License::get_license_key() which has never existed on the core License class — every site that activated the add-on threw Uncaught Error: Call to undefined meth
fixSelf-updater fatal on every WP cron tick. class-updater.php:104 called \Respira_License::get_license_key() which has never existed on the core License class — every site that activated the add-on threw Uncaught Error: Call to undefined meth
April 20, 2026
drop keytar, fix whoami after login, unstick terminal, warm welcome
54 ACF tools covering field reads and writes, field-group management, ACF Pro repeaters, flexible content, galleries, options pages, relationships, and bulk updates. Every write snapshot-backed and dry-run previewable. Works on approximately 2 million WordPress sites that use ACF today.
add54 Advanced Custom Fields tools under respira_acf_*. ACF powers flexible content models on approximately 2 million WordPress sites. Before v6.6.0, Respira could only read ACF values through generic post-meta calls, which
addEvery write tool creates before_edit and after_edit snapshots via Respira_Snapshots::capture_snapshot(), audit-logs through Respira_Auth::log_action(), and supports dry_run=true to preview the change without executing. E
addLicense tier gating follows the existing scope model. Reads (get_*, list_*, search_*) require any valid API key and are available on Lite. Writes (update_*, delete_*, create_*) require the write scope and are available o
addACF presence detection in site context. Respira_Context::get_addons_context() now exposes addons.acf.{installed, pro, version, licensed}. MCP server uses this to register ACF tools only on sites where ACF is active and t
tested17/17 direct-handler assertions via mu-plugin probe.
tested54/54 HTTP assertions against the full endpoint surface using a real encrypted API key (wp-now + ACF 6.8.0): 28 free ACF tools return 200 with the expected payload shape, 26 Pro-gated tools correctly return 412 respira_a
changeSix-phase execution cycle: LoadContext -> PreHooks -> Resolve -> Execute -> PostHooks -> Return. Deterministic. Traceable. Every command runs through every phase
changeFive framework hook contracts, frozen for v0.1: before_resolve, filter_plan, before_execute, filter_result, after_execute. In v0.1 no callbacks register. v0.2 populates them. NullHookRegistry swaps for ManifestBackedHook
changeTyped ToolChainFunction<T> abstraction for all 34 commands. Each function declares capability (read | write | destructive), domain tags, and prerequisites
changeFile-organization convention: one BaseCommand subclass per file, one ToolChainFunction per file, always co-located. Named export <camelCasePath>Function
changeStructured JSON tracing via --verbose, written to ~/.respira/traces/{invocationId}.json. Hard cap 10,000 entries per invocation
addOxygen Deep Intelligence: Full intelligence package for Oxygen Builder — 49 components cataloged with properties, types, defaults, and nesting rules. Component registry with dynamic detection and 24-hour caching. JSON Sc
addOxygen Settings Validator: Validates component properties and data types before injection — colors, URLs, emails, numeric values, booleans, and arrays all checked with detailed error messages
Flatsome UX Builder joins as builder #12. 15 new WooCommerce Commerce tools with storefront design intelligence. Context-aware MCP tool filtering reduces tools in context by ~40. Three coordinated releases.
addFlatsome UX Builder as Builder #12: Full support for the most popular WooCommerce theme on ThemeForest (200K+ sales). Extract, inject, element ops, build_page, and snapshots all work. Detection by active theme. Shortcode
addShortcodeParser utility: Shared shortcode parsing and reconstruction for Divi 4 and Flatsome. Parameterized by tag prefix, column format, and detection patterns. Strict tag allowlists prevent cross-builder content confus
addBundled WooCommerce entitlement: Studio and Founder plans now include the WooCommerce add-on at no extra cost. Maker and Builder customers continue to purchase it separately
addContext-aware tool filtering (MCP server v6.0.0): The MCP server now filters the tool list based on detected builder and active plugins. Bricks tools hidden when Bricks is not active, WooCommerce tools hidden when WooCom
addWooCommerce snapshot safety: All existing WooCommerce write tools (create_product, update_product, update_stock) now create before/after snapshots and log to the audit trail. Previously these operations were invisible an
addFlatsome Intelligence package: 55 element definitions with attributes, types, defaults, nesting rules, and responsive patterns. 6 pre-built page patterns for AI agents
7 new Bricks-dedicated tools. Cross-site element search, page health diagnostics, Automatic.css integration, query loop discovery, style profiling, and design system export.
addCross-site element search (respira_search_bricks_elements): Search across ALL pages and templates for Bricks elements by type, global class name, or setting value. Find every instance of a specific element, audit class u
addPage health check (respira_bricks_health_check): Standalone diagnostic tool that detects orphaned elements, duplicate IDs, broken parent/child references, invalid global class references, empty containers, and heading hi
addACSS integration (respira_bricks_detect_acss, respira_bricks_import_acss): Auto-detect Automatic.css (ACSS) installation, read its color/spacing/typography variables, and import utility classes into the Bricks global cla
addQuery loop discovery (respira_bricks_query_loops): Find all Bricks elements that use query loops across the site. Filter by object type (post, term, user) or queried post type (product, page, etc.). Essential for auditin
addStyle profile learning (respira_bricks_style_profile): Analyze a page and extract its design patterns — colors used (with frequency), spacing values, typography (fonts, sizes, weights), and global class usage. Use to lea
addDesign system export (respira_bricks_design_system): Single-call export of the complete Bricks design system — global classes, color palette, theme styles, typography/variables, components, element types, and Bricks vers
65 new tools. Element-level editing across every supported builder, build_page declarative page creation, HTML-to-builder conversion, stock-image search, tool governance, and dynamic schemas for 12 builders.
addElement-level operations: find_element, update_element, move_element, duplicate_element, remove_element, batch_update (atomic), reorder_elements — works across all 11 builders via tree utility or native overrides
addbuild_page: Create complete pages from a declarative structure in a single API call. Returns preview URL
addStock images via Openverse: search_stock_images and sideload_image with CC attribution, domain allowlist, SSRF protection, and deduplication
addTool governance: Per-tool enable/disable with fail-open safety. Single chokepoint for REST + Abilities API. Audit logging
addElementor dynamic schemas: Reads control registry at runtime, maps to JSON Schema types. Settings validator with "did you mean?" suggestions
Every AI edit now has an undo button. New Changes page in wp-admin, storage management, merge-mode default for approvals, and WebMCP write-tool protection. Three months of "can you revert that?" tickets, gone.
Compact MCP responses, working-copy reuse, simpler multi-site setup, and a broad reliability pass driven by a single support ticket from a customer who asked for their money back. They stayed.
addAdded explicit live-edit preflight responses for original pages, posts, custom posts, builder module updates, and builder patch flows when direct editing is enabled. Clients must now choose editTarget: "live" or editTarg
addAdded rollback guidance for live edits, including the WordPress edit-screen URL for revisions and Respira pre-edit snapshot messaging.
addAdded support for dashboard-issued site tokens (respira_site_...) so hosted agency MCP exports can authenticate without per-site plugin-local keys.
addAdded a hosted-dashboard handoff card in wp-admin so agencies can open the dedicated account-wide MCP Setup page for all-sites exports, install commands, and AI setup prompts.
changeMulti-step write flows now reuse the current working duplicate when available and no longer create a duplicate during the confirmation-only preflight response.
changeGET /respira/v2/status now exposes whether direct editing of originals is enabled, so MCP clients can decide when to present live-edit confirmation.
Thrive Architect product pages — description edits didn't appear on the frontend — bulk_update_products with description / short_description wrote to post_content via WooCommerce setters, but Thrive Architect renders from its own wp_postmet
fixThrive Architect product pages — description edits didn't appear on the frontend — bulk_update_products with description / short_description wrote to post_content via WooCommerce setters, but Thrive Architect renders from its own wp_postmet
Product category CRUD endpoints and MCP tools (list/get/create/update/delete).
addProduct category CRUD endpoints and MCP tools (list/get/create/update/delete).
addProduct tag CRUD endpoints and MCP tools (list/get/create/update/delete).
changeProduct create/update now supports category and tag assignment payloads for safer taxonomy-aware catalog workflows.
cookies. the legal kind. one click and i'll get out of your way.
what you'd actually be saying yes to
tune your cookie preferences
essentials stay on regardless. the rest is opt-in. nothing fires until you tap save.
essentials
the cookies that make logging in work and remember which partner sent you. switching these off would just break the site, so the law does not let me make you opt out.
first-touch source on a /respira_acq cookie, plus a flag if an ai chatbot referred you. helps me figure out what is working without turning you into a tracking pixel statue.
messaging
customer.io for in-app notes, chatwoot when you click the support bubble. off by default. on means i can actually answer you in the app.