Stand up the monorepo skeleton and land the first Phase 0 artifacts: pairing threat model, plugin catalog, builder detect, 20-prompt golden harness, and synthetic 2GB mirror timing.
1.9 KiB
1.9 KiB
Spike: builder detect (R6 / R13)
Status: done
Question
How do we know what actually renders a page?
Done when
- A site-info payload reports
builder: elementor | beaver | divi | gutenberg | classic - Detection uses plugin slugs + post meta
- Documented in the plugin API sketch below
Result
detectBuilder() in e2e/golden/src/builder-detect.ts.
Order (first match wins):
- Active
elementorand_elementor_edit_modeor_elementor_data→elementor - Active
beaver-builder-lite-versionorbb-pluginand_fl_builder_dataor_fl_builder_enabled→beaver - Theme
Divior activedivi-builderand_et_pb_use_builder === on→divi - Any post content contains
<!-- wp:→gutenberg - Else
classic
Plugin slug alone is not enough (inactive junk). Gutenberg markup loses to Elementor when both exist — Elementor is what renders.
Proved on the two golden fixtures and six unit tests.
Plugin API sketch
GET /wp-json/wursor/v1/site-info (read token + HMAC)
{
"theme": "hello-elementor",
"plugins": [{ "slug": "elementor", "active": true }],
"wordpress_version": "6.5.5",
"php_version": "8.1.30",
"builder": "elementor",
"capabilities": { "content": true, "design": true, "install": true },
"preflight": { "https": true, "rest": true, "disallow_file_mods": false }
}
builder is computed on the plugin with the same rules as detectBuilder. Content and design playbooks must use this field. Editing post_content on an Elementor site is a failed test.
Decision
- Context: Elementor stores the page in post meta. Gutenberg stores it in
post_content. - Chosen: slugs + the meta keys those builders actually write. Priority: paid builders, then block markup, then classic.
- Rejected: “if elementor is installed, always Elementor” (inactive plugin). Theme-name-only detection.
- Reverted later?