Fix: Prism reverse-proxy no longer intercepts requests from logged-in users. Prism serves content from a separate backend host that has no knowledge of the WordPress session, so proxying an authenticated member returned the backend’s logged-out view (or a redirect to login/dashboard) and broke member-only pages (e.g. archive/library links bouncing to the dashboard). prism_handle_request now returns early for any logged-in request, so member and admin traffic is always rendered by WordPress itself. Also hardened route matching to skip malformed and empty// path prefixes, which would otherwise match every request on the site.
2.1.0
Feature: explicit per-page scope for Class A intents. Every static-output intent (e.g. custom_json_ld, head_meta_tag) now carries an explicit scope — either site-wide or a list of target page URLs — so schema/meta meant for one page no longer renders on every page. There is no implicit site-wide: megaseo-web requires the caller to declare scope. Scope is stored inside the existing intent params (no DB schema change), and the runtime matches the current request (by resolved post id, front page, or normalized path) before echoing. Intents published before this release have no stored scope and continue to render site-wide (backward compatible).
Feature: head_meta_tag deduplication. When a known SEO plugin (Yoast, Rank Math) is active, a description intent now overrides that plugin’s meta description via its filter instead of emitting a duplicate <meta name=”description”> tag. MEGA also dedups its own head metas so the same name is emitted at most once per request.
Feature: GET /mega/v1/intents/{id} returns the full intent row (including stored params with scope and the pre-rendered rendered_html) for operational inspection. The list endpoint still omits those heavy fields.
2.0.1
Hotfix: self-heal the wp_mega_intents table on plugin upgrade. v2.0.0 created the table only inside an activation hook and lazy REST write paths, so sites that auto-updated from v1.x to v2.0.0 without ever writing an intent ran the intent runtime against a missing table on every request, and wpdb echoed a public DB error before the doctype on home pages and inside REST/JSON responses. v2.0.1 adds (a) a plugins_loaded priority-5 MegaIntentRunner::maybe_upgrade() that runs dbDelta on a schema-version option mismatch, and (b) a suppress_errors guard around the runtime’s intent-load SELECT so a missing table can never leak wpdb::print_error() output into the response. Pure hotfix — no API changes.
2.0.0
Feature: intent runtime (safe-WP-code pipeline). New POST/GET/DELETE /mega/v1/intents and POST /mega/v1/intents/kill-all endpoints let the MEGA SEO platform push validated, hard-coded site behaviors into customer sites without executing any bot-supplied code. The bot picks an intent_type from a closed registry (e.g. tracking_pixel, verification_meta, consent_script, heatmap_pixel, custom_json_ld, head_meta_tag, noindex_pages, outbound_link_attrs, disable_emojis, image_loading_attr) and supplies structured params; megaseo-web validates the params and, for static-output intents, pre-renders the HTML payload server-side. The plugin echoes that pre-rendered HTML verbatim from a hooked closure or runs a hard-coded named handler for behavior intents. No eval(), assert(string), or other dynamic-code primitive is ever applied to intent data. Intents live in a new wp_mega_intents table; the dispatcher in runtime/intent-runner.php wraps every handler callback in try/catch(Throwable) plus a register_shutdown_function so a runtime fatal auto-deactivates the offending intent instead of bricking the site. A ?mega-safe-mode=1 query parameter (requires manage_options) is the customer’s emergency disable hatch. The megaseo-web side (per-intent Zod validation, per-customer feature flag gating Class B intents, post-publish regression probe, Atlas task block reasons) is described in the platform’s safe-WP-code plan doc.
1.7.0
Feature: builder-aware widget edit surface. New GET /mega/v1/editor/widgets/<id>, PATCH /mega/v1/editor/widgets/<id>/<widget_id>, and POST /mega/v1/editor/revisions/<id>/restore endpoints expose a unified scalar-edit API across Elementor, Gutenberg, and Classic WP. The plugin auto-detects which page builder owns each post and dispatches to the matching MegaEditorAdapter. Every PATCH snapshots a WP revision first so the MEGA bot CLI can issue a single-call undo after a bad edit. Elementor support is pinned to major version <= 3 as a safety guard. Returns 404 with code: editor_builder_unsupported when an unknown builder is detected so callers can fall back gracefully.
1.6.2
Feature: ?diagnostic=1 query param on POST /mega/v1/pages/<id>. When set, skips the mega_managed=1 postmeta write so the MEGA SEO platform’s CMS diagnostic worker can run a non-destructive page text-revert probe on a customer’s most-recent published page without permanently tagging it as MEGA-owned. No effect on production write paths (which call without the flag); the platform’s diagnostic Inngest worker passes diagnostic=1 and the bot’s normal publishing code does not.
1.6.1
Removed self-update mechanism to comply with WordPress.org Plugin Directory guideline #8 (no loading executable code from external sources). Updates now flow exclusively through the WordPress.org plugin directory. No functional changes to /pages, /cache/flush, or any other endpoint shipped in 1.6.0.
1.6.0
Feature: dedicated /mega/v1/pages REST surface — GET|POST /mega/v1/pages (list/create) and GET|PUT|DELETE /mega/v1/pages/<id> (read/update/delete) pinned to post_type=page. Mirrors the existing /posts handler shape (same response keys, same meta / schema_jsonld / seo_title / meta_description write semantics) so platform clients can use one parser for both. Returns 404 if the requested ID is not a page so callers can’t accidentally mutate a post via the pages route. Unblocks the CMS diagnostic worker’s page-revert probe and the page on-page-SEO bot path, both of which previously had to fall back to direct WP REST + Basic Auth.
Feature: POST /mega/v1/cache/flush — purges Yoast indexables, Rank Math sitemap, WP Rocket, W3 Total Cache, LiteSpeed Cache, WP Super Cache, and WP core object cache. Each backend is detected at runtime and wrapped in try/catch so a mis-behaving cache plugin can’t cascade-fail the whole flush. Optional post_id param scopes WP-core post-cache invalidation to a single post. Returns a {cleared: {…}} summary so callers can log which backends fired. Lets writer pipelines force-revalidate freshly-written content/meta without waiting on each cache backend’s natural TTL.
1.5.2
Maintenance release: republish of 1.5.1 to refresh the WordPress.org plugin directory metadata. No code change vs 1.5.1 — the schema-adapter fix below is the substantive change customers should care about. (1.5.1 was committed to SVN but the WordPress.org directory’s metadata-refresh pipeline did not pick it up; 10up’s deploy action refuses to re-push an already-tagged version, so a new tag is required to nudge the directory.)
1.5.1
Fix: per-page JSON-LD schema for body-bearing @type values now persists with its full body on Yoast and AIOSEO sites.
Yoast: FAQPage and QAPage are no longer promoted to _yoast_wpseo_schema_page_type (the bare-@type slot). They fall through to the existing extras path (_mega_yoast_schema_extra) so mainEntity (questions/answers) is preserved.
AIOSEO: FAQPage, Recipe, Product, ProductReview, Course, Dataset, Movie, Service, Car, SoftwareApplication, HowTo, and Person are no longer promoted to wp_aioseo_posts.schema.default.graphName. They fall through to extras (_mega_aioseo_schema_extra) so mainEntity / recipeIngredient / offers / jobTitle / worksFor / etc. are preserved.
Both extras paths render verbatim via the existing wpseo_schema_graph / aioseo_schema_output filters — the same path Organization and BreadcrumbList have used since 1.3.0.
Previously these types were reduced to a bare {“@type”:”…”} on storage and the host SEO plugin rendered an empty stub node.
No-op for Rank Math sites (its adapter already wrote full bodies per @type).
No-op for Article / WebPage / BlogPosting / NewsArticle on either adapter — those keep using native promotion because the host plugin reconstructs their body from the WP post record.
1.4.0
Feature: AIOSEO (All in One SEO) schema adapter — GET|PUT|DELETE /mega/v1/posts/<id>/schema now works on sites running AIOSEO Lite or Pro, in addition to Rank Math and Yoast.
The first JSON-LD node whose @type matches an AIOSEO-known graph (Article, BlogPosting, NewsArticle, WebPage, FAQPage, Product, Recipe, Service, Person, Course, Dataset, Movie, ProductReview, Car, SoftwareApplication) is promoted to wp_aioseo_posts.schema.default.graphName and shows up in AIOSEO’s post-editor schema metabox.
Remaining nodes are stashed in _mega_aioseo_schema_extra and merged into AIOSEO’s rendered @graph at request time via the official aioseo_schema_output filter — same extension pattern Yoast uses.
A sentinel postmeta key (_mega_aioseo_default_owner) tracks which default.graphName slot we own so we never overwrite a manual selection a customer made in the AIOSEO metabox.
AIOSEO’s user-authored graphs[] and customGraphs[] arrays are read but never written by this plugin — they remain entirely under customer control.
Feature: AIOSEO SEO title and meta description support — seo_title and meta_description on GET|POST|PUT /mega/v1/posts[/<id>] now read from and write to the wp_aioseo_posts.title / wp_aioseo_posts.description columns when AIOSEO is the active SEO plugin.
Updated: mega_schema_no_seo_plugin error message now mentions AIOSEO alongside Rank Math and Yoast.
1.3.0
Feature: per-post JSON-LD schema via host SEO plugin (Rank Math / Yoast).
New endpoints GET|PUT|DELETE /mega/v1/posts/<id>/schema and inline schema_jsonld field on POST|PUT /mega/v1/posts[/<id>]. REPLACE-ALL semantics — read before writing to preserve.
Rank Math adapter writes one rank_math_schema_<Type> post meta row per JSON-LD node; Rank Math renders them as part of its native schema graph and they appear in the Rank Math editor UI.
Yoast adapter maps page-type / article-type nodes to _yoast_wpseo_schema_page_type / _yoast_wpseo_schema_article_type (visible in the Yoast UI). Nodes that don’t fit those selectors are stashed in _mega_yoast_schema_extra and rendered into Yoast’s runtime graph via the wpseo_schema_graph filter.
GET /mega/v1/posts accepts a new post_type query parameter (single, comma-separated list, or any) and a free-text search parameter so the platform can enumerate pages and custom post types, not just blog posts.
Removed: the _mega_jsonld_schema self-rendered wp_head injection shipped in 1.2.2. Replaced by the adapter above so the host SEO plugin owns rendering — avoids duplicate <script type=”application/ld+json”> tags and makes schema visible in Yoast / Rank Math UIs. The _mega_jsonld_schema post_meta key is no longer read; legacy values can be removed with DELETE /mega/v1/posts/<id>/schema after migrating to the new path.
1.2.2
Feature: render bot-managed JSON-LD schema in <head> on singular views. Reads the _mega_jsonld_schema post_meta key (written through the existing meta:{} field on POST /mega/v1/posts/<id>) and emits it as <script type=”application/ld+json” data-mega-managed=”1″> at wp_head priority 99. Lets the MEGA platform deploy LocalBusiness / RealEstateAgent / FAQ / Service schema on sites that don’t have Yoast or Rank Math controlling the relevant schema type. A site-wide schema slot is planned for a follow-up release.
1.2.1
Compatibility: defer Prism’s template_redirect hook to priority 20 so plugins like WP Fusion (default priority 10) can run their auth and membership gates first. Prevents authenticated users from being redirected away from archive pages on sites that gate content via template_redirect.
1.1.1
Maintenance release
1.1.0
New Feature: Prism – Reverse proxy functionality
Serve external content through your WordPress site with configurable routes