launch week Respira for WordPress is live on DevHunt until Monday. Live on DevHunt this week. See the launch

Plugin 6.11.1MCP Server 6.11.0 May 5, 2026 Bug-bash · Cumulative

Respira 6.11
Self-Heal

Every customer-reported bug, fixed.

The release i should have shipped weeks ago. Self-Heal closes the ledger of customer-reported bugs that accumulated through the v6.10.x family-bug arc, plus every open public github issue. The release name reflects the posture: every bug fixed here is one the platform should have caught itself, and v6.11 is where the platform starts catching them.

14 customer bugs fixed across 5 named trial threads
7 github issues closed #18 #19 #20 #21 #23 #24 #25
5 cross-cutting audits unicode, schemas, kses, anon-read, render trace
0 breaking changes cumulative roll-forward into v7.0
Respira 6.11.0 Self-Heal — bug-bash release

The story

Three arcs that shaped the release

Three independent customer trials surfaced bugs that turned out to share a shape. Fixing them as a class produced a healthier platform than patching them one at a time. Customer names withheld; technical details intact.

html-to-builder convert on Breakdance

A pro-services firm running an html-to-Breakdance convert pipeline against a 100KB+ source surfaced four classes of render-only issues that all passed the data-layer io-ts contract but failed the per-widget render gate. The data layer was already solid post-v6.10.3. The render gate was a separate, undocumented validator on the Breakdance frontend that the convert emitter wasn’t producing widgets for cleanly.

  • Per-widget render validator that runs after the io-ts envelope and enforces required keys per widget type. EssentialElements\Section needs a design key. EssentialElements\Button needs a valid URL. Hash anchors no longer satisfy the validator.
  • Sanitizer pass replaces <br> and <br/> with a single space before whitespace normalization runs. Six headings on the pilot site that were rendering as merged words now render with correct word boundaries.
  • Parent Text widget collapses to structural-only properties when its children are themselves Text widgets. Stat clusters where a <div class="num">3</div> containing <span>3</span> produced two stacked Text widgets at adjacent depths now collapse to a single Container with one Text leaf.
  • Inline-flow children preserve their CSS-display hint. <span class="num">100</span><span class="unit">%</span> patterns render as 100% on a single line again instead of stacked vertically.

silent blank-page renders on Oxygen Classic

A trial customer spent two weeks debugging why respira_build_page produced a postmeta blob that looked structurally correct on disk but rendered as a blank section between header and footer. The diagnosis traced cleanly: the writer was emitting string GUIDs for ct_id instead of numeric integers like native Oxygen pages use. Oxygen’s CSS regenerator and front-end render layer expect numeric ct_id, the lookup misses, render is suppressed, page renders blank.

  • Numeric ct_id allocation in the Oxygen inject_content() path. Queries existing _ct_builder_json for the max ct_id, allocates max(existing) + 1, integer-typed, no respira_ prefix. Native Oxygen pages on the same site stay valid.
  • respira_oxygen_renumber_page(post_id) migration tool for already-broken pages built on v6.x with string ct_ids. Snapshot-backed, non-destructive, rewrites string ct_ids to allocated integers in one pass.
  • respira_get_builder_info surfaces oxygen_string_ct_id_count so the agent can detect the regression on a page proactively, before the next write, and offer to renumber.

Divi 5 calibration loop

A recurring calibration loop on Divi 5 surfaced four bug-shape issues plus one schema-accessibility issue that share root causes with the larger schema-quality posture in the release. The lesson at every step: the LLM falls back to HTML it knows when the schema doesn’t show the convention. Closing the gap requires examples on the schema endpoint, not just types.

  • Counter 100%% doubling when percent_sign: on: schema endpoint advertises the constraint that number is the numeric portion only when the percent toggle is on, plus a complexify path that strips trailing % when the toggle is on.
  • Pricing-table <ul><li> injection where Divi handles bullets natively: schema endpoint ships a bullets-as-string examples array. The agent stops falling back to HTML it knows.
  • Contact-form submit-button bg routing missed because formButton.decoration.background.* is its own nested attr group not shared with divi/button: an audit pass across every Divi module with embedded sub-buttons treats it as a class instead of one-by-one.
  • Flex-column visual-builder vs. wireframe-view divergence: a normaliser at the simplifier layer emits flex weights at the row level, not column-sub-row, so visual-builder and wireframe-view render identically.
  • GET /respira/v1/divi/modules/divi/button/schema previously required auth: schemas are non-sensitive, the auth gate is removed everywhere across every adapter so agents can introspect what divi/button looks like before they write.

Audits

Cross-cutting fixes

Five issue-shapes each surfaced independently across multiple builders and got fixed as a class rather than per-adapter. The pattern lives here so future builders inherit the convention.

JSON post-meta unicode safety

Every adapter that writes builder data to postmeta (elementor, bricks, divi, breakdance, beaver) now uses wp_slash() before update_post_meta(), matching elementor’s own pattern, AND switches json_encode() to JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES so \uXXXX escapes never appear in the first place. Cyrillic, CJK, Arabic, Hebrew, and emoji content survives every update_module call now. Closes a longstanding silent-corruption regression.

MCP server tool-schema audit

Every tool’s parameter schema now consistently uses snake_case. An audit script in CI catches any future regression. respira_switch_site previously failed with "Site with ID undefined" on every multi-site call. respira_remove_element previously sent element_id to a REST endpoint expecting identifier_type + identifier_value. Both addressed.

Duplicator hardening

Every wp_insert_post-via-respira call site (page duplicator, post duplicator, snapshot-restore) now bypasses kses for the duration of the duplication via wp_set_current_user(admin) + kses_remove_filters() / kses_init_filters(). Eliminates silent stripping of <script> and <style> tags inside builder code modules. Senja widgets, custom CSS blocks, and analytics snippets inside et_pb_code and equivalent modules now duplicate byte-identical to the original.

Schema endpoints anon-readable

GET /respira/v1/{builder}/modules/{type}/schema is now anon-readable on every adapter (divi, bricks, breakdance, beaver, wpbakery, elementor, oxygen). Schemas are non-sensitive, and forcing auth was breaking cold-start agent flows where Claude introspects what an element looks like before writing.

Render-trace fields on every write

Every adapter’s write response now carries trace fields (route, target, path_resolved, validator_warnings, render_validator_pass) so support diagnostics no longer require live screen-shares. When a customer reports "edit didn’t land", the trace tells whether persistence succeeded, the renderer rejected the widget, or an upstream layer intercepted the request.

Per-builder + tool

Adapter-by-adapter breakdown

Every fix that landed in v6.11, scoped to the adapter or tool surface it lives in. Each one closes either a customer-reported issue or a public github issue.

Bricks paper cuts

3 inject foot-guns

Element-name validator with Levenshtein-ranked "did you mean" suggestions for unknown names instead of silent rendering of name: "div". Auto-wrap on array content input so callers don’t have to know the undocumented { elements: [...] } envelope. _cssGlobalClasses now documented as a first-class property on every element with a worked example in the tool description.

Bricks REST 500 on find_element

github #21 ntrance

A TypeError in Respira_Builder_Tree_Utility::find_recursive() returned 500 on every find_element call when the data structure had non-array elements at any tree level. One-line is_array() guard fixes it. Reported with the exact patch in the issue thread; applied verbatim.

Beaver foundation

3 persist-and-render bugs

Three bugs blocked the heading / text / button persist-and-render flow on Beaver Builder Pro. update_element no longer silently no-ops (read-modify-write canary asserts the new content is in _fl_builder_data before declaring success). Heading text now lands under settings.heading (Beaver’s fl-heading reads that, not settings.text). Button URLs survive complexify (link, link_target, link_nofollow all preserved).

Cross-builder text identifier alias

Beaver, Breakdance, WPBakery

find_element({identifier_type: "text", …}) now works on Beaver, Breakdance, and WPBakery as an alias of content. Three builders previously returned 404; one shared Respira_Builder_Identifier_Aliases helper covers every adapter going forward.

Divi 4 shortcode write support

github #24 pablolic

The "Legacy block at index 0 must remain opaque" guard from the v6.7.x Divi 5 ship was a placeholder that was never lifted. Divi 4 pages were effectively read-only for update_element. v6.11 ships actual Divi 4 shortcode write support via a per-attribute writer using the existing find_node() walker, plus respira_rewrite_legacy_shortcode(post_id, new_post_content) for atomic replacement when the per-attribute path doesn’t fit.

Divi button_url validator

github #25 pablolic

Relaxed to match esc_url_raw semantics. Accepted forms now: fragment-only (#), fragment id (#section-id), relative paths (/, ./, ../), mailto:, tel:, sms:, query-only (?query), plus all standard http(s). Pre-existing button_url="#" on sibling modules no longer blocks writes to unrelated modules; validation is scoped to the fields the caller is actually mutating. javascript: is rejected with a specific scheme rule.

wordpress_diagnose_connection

new MCP tool

Runs a full self-check battery and reports back structured findings when a customer site behaves oddly. Detects HTML-instead-of-JSON responses (extracts the page <title> from the body so you instantly know which layer is intercepting), edge-layer presence (Cloudflare cf-ray, Wordfence x-wordfence-*, Sucuri x-sucuri-*), schema-vs-rest drift, Authorization-header arrival, and Respira route registration. Pairs with a server-side /respira/v1/diagnostic/report plugin endpoint that surfaces what the MCP server can’t see from outside.

Plugin auto-connect on Overview tab

admin UX

v6.10.0 wired the auto-connect block into the License view, but customers landing on the Overview tab first saw the paste-only flow and could not find the auto-connect path at all. The connect block now appears on Overview (?page=respira-for-wordpress) too, mirrored into admin/views/dashboard.php. Same block, both tabs. New customers connect in one click instead of digging for the API key paste field.

Posture

What "Self-Heal" means going forward

Every bug fixed here is one the platform should have caught itself. v6.11 is where the platform starts catching them: read-modify-write canaries on every write, scoped validators that don’t reject pre-existing data the caller didn’t touch, audit scripts that prevent schema-vs-rest drift from regressing in CI, structural error returns instead of silent no-ops, anon-readable schema endpoints so agents can self-correct before they write.

Self-heal as a posture: respira recovers gracefully where it used to fail silently. Every adapter inherits the convention going forward.

Update to 6.11.0

If you’re on any v6.10.x release, this is a clean roll-forward with zero breaking changes.