AcrossAI Abilities Manager

Description

AcrossAI Abilities Manager gives site administrators full visibility and control over every ability registered via the WordPress Abilities API (wp_get_ability()).

Features:

  • Browse all abilities — a searchable, sortable, paginated table listing every registered ability with slug, provider, source, and current status.
  • Toggle allow/disallow — enable or disable any ability site-wide with a single click. Changes are saved instantly without a page reload.
  • Edit ability metadata — override readonly, destructive, idempotent, show_in_rest, show_in_mcp, mcp_type, and mcp_servers fields per ability using a tri-state system (Yes / No / Inherit from registry).
  • Reset overrides — restore any ability back to its registry defaults with one click.
  • Bulk actions — allow, disallow, or reset up to 50 abilities at once.
  • Ability Library — enable or disable add-on ability groups from a dedicated Library page, with All/Specific mode controls per group.
  • Add-ons page — browse companion plugins from the WordPress admin. WordPress.org-hosted add-ons install / activate / deactivate in place; add-ons distributed elsewhere link out to the vendor’s site so you can install them via Plugins Add New Upload Plugin.
  • MCP server list — view all registered MCP servers when the MCP Adapter plugin is active.

All overrides are stored in a dedicated database table. The WordPress ability registry is never modified — only the fields that differ from registry defaults are persisted.

Security:

  • All endpoints require manage_options capability.
  • All state-changing requests are protected by WordPress nonce verification.
  • All input is sanitized; all output is escaped.

Third-party integrations (optional):

  • MCP Adapter plugin — if active, the plugin displays a list of registered MCP servers inside the ability edit panel. No data is sent to any external service. The MCP Adapter plugin communicates only with your own WordPress installation.

This plugin’s own code makes no external HTTP requests. One admin-only surface can contact an external service on your behalf: the AcrossAI Add-ons page installs WordPress.org-hosted companion plugins directly through WordPress core’s own plugin installer (api.wordpress.org + downloads.wordpress.org). Add-ons registered with any other source (e.g. GitHub, Freemius) are shown as external “Get add-on ” links that open the vendor’s site in a new browser tab — the plugin does not download or install them itself. The AcrossAI Consultations submenu renders a static call-to-action button that opens calendly.com in a new browser tab only after the administrator clicks it — no third-party asset is loaded inside wp-admin. Full disclosure — including what data is transmitted to each service and links to their terms + privacy policies — is in the External Services section below.

External Services

This plugin connects to the following external services on your behalf. Each connection is triggered by a specific admin-only action and is disclosed here per the WordPress.org plugin directory guidelines.

1. Calendly external link (calendly.com)

What it is: Calendly is a third-party scheduling service. The AcrossAI Consultations submenu displays a static call-to-action button that links out to a Calendly booking page for AcrossAI consultations (“Using AI in WordPress”).

When it is contacted: Never on page render. The Consultations submenu at /wp-admin/admin.php?page=acrossai-consultations is a self-contained wp-admin page — it does not load any Calendly script, iframe, cookie, or asset. Calendly is only contacted if the administrator explicitly clicks the “Book a Consultation” button, at which point their browser navigates directly to https://calendly.com/acrossai/using-ai-in-wordpress in a new tab (target="_blank" rel="noopener noreferrer"). This is identical to clicking any external hyperlink from an admin page.

What is loaded on the Consultations page: Nothing from Calendly. The page renders self-contained HTML + CSS. The only external asset referenced by the page is Google Fonts (Space Grotesk + IBM Plex Sans via fonts.googleapis.com) — permitted under the “third-party CDNs beyond fonts” carve-out in the WordPress plugin guidelines.

What data is transmitted to Calendly: Nothing by this plugin. If the administrator clicks the CTA button, their browser navigates directly to Calendly and sends standard browser metadata (IP address, User-Agent, referrer) to Calendly as with any external link. If the administrator then chooses to book a consultation on Calendly’s own site, any information they enter into Calendly’s booking form (name, email address, meeting preferences, etc.) is transmitted to and processed by Calendly. This plugin does not intercept, store, or forward that data.

Terms of service: https://calendly.com/pages/terms
Privacy policy: https://calendly.com/pages/privacy

2. WordPress.org plugin directory (api.wordpress.org and downloads.wordpress.org)

What it is: The Add-ons page (/wp-admin/admin.php?page=acrossai-addons) uses the WordPress.org plugin directory to install free companion plugins directly from wp-admin.

When it is contacted: Only when an authenticated administrator (install_plugins capability) clicks the “Install” button on a card whose source is wordpress.org. Contact happens through WordPress core’s own plugins_api() and Plugin_Upgrader — this plugin does not issue direct HTTP requests. Add-ons registered with any other source (e.g. github, freemius) are rendered as external “Get add-on ” links that open the vendor’s site in a new browser tab; the plugin does NOT download or install those add-ons itself, so no request is made to the vendor’s servers from wp-admin.

What data is transmitted: The WordPress core plugin API request payload (site URL, WP version, PHP version, locale) as per WordPress core’s standard update check protocol.

Terms of service: https://wordpress.org/about/terms/
Privacy policy: https://wordpress.org/about/privacy/

3. WordPress.org core version-check API (api.wordpress.org/core/version-check/1.7/)

Called only when an administrator invokes the acrossai/rollback-wp-core ability (registered under the Core category) and the local core-version cache has expired. Rate-bounded to at most one request per day per locale per site via a site-transient cache. This is a WordPress-core-hosted API — no data beyond the standard WordPress core version-check request payload is transmitted. Same wp.org terms + privacy policy as service #2 above.

Privacy Policy

This plugin does not itself collect, store, or transmit any user data to any third party.

Several admin-only actions can cause external services to receive data — all are described in the External Services section above and are triggered only by an authenticated administrator:

  • The AcrossAI Consultations admin page displays a static call-to-action button. Merely loading the Consultations page sends no data to Calendly — no Calendly script, iframe, or asset is loaded inside wp-admin. If the administrator clicks the CTA button, their browser opens calendly.com/acrossai/using-ai-in-wordpress in a new tab, at which point standard browser metadata (IP, User-Agent, referrer) is sent to Calendly and Calendly’s own privacy policy applies. If they then book a consultation on Calendly’s site, information they enter into Calendly’s form (name, email, meeting details) is transmitted to Calendly.
  • Installing a WordPress.org-hosted add-on from the AcrossAI Add-ons page contacts the WordPress.org plugin directory via WordPress core’s own plugins_api() and Plugin_Upgrader (api.wordpress.org + downloads.wordpress.org). Add-ons distributed elsewhere (e.g. GitHub, Freemius) are rendered as external “Get add-on ” links that open the vendor’s site in a new browser tab — the plugin itself does not download or install those add-ons, so no request is sent to the vendor’s servers from wp-admin. If the administrator clicks the external link, their browser navigates directly to the vendor and standard browser metadata (IP, User-Agent, referrer) is sent to the vendor as with any external hyperlink.
  • Invoking the acrossai/rollback-wp-core ability contacts the WordPress.org core version-check API (a WordPress-core-hosted service) via the standard WordPress update API.

No data is sent to any external server without an explicit administrator action.

Screenshots

Installation

  1. Upload the acrossai-abilities-manager folder to /wp-content/plugins/.
  2. Activate the plugin through the Plugins menu in WordPress.
  3. Navigate to AcrossAI Abilities Manager in the WordPress admin menu.

Add-ons:

  1. Go to AcrossAI Add-ons to browse available companion plugins.
  2. All add-ons are free and hosted on WordPress.org; each card offers a one-click Install / Activate / Deactivate action via the standard WordPress plugin installer.

FAQ

Does this plugin support Multisite?

No. This plugin has not been tested on WordPress Multisite installations.

Does this plugin modify the WordPress ability registry?

No. The plugin stores only overrides — fields that differ from the registry defaults. The ability registry itself (wp_get_ability()) is never modified.

What happens when I reset an override?

The override row is deleted from the database. The ability will inherit its values from the registry again.

What is the Ability Library?

The Library page lets you enable or disable ability groups registered by add-on plugins. Each group shows an ON/OFF master toggle and an All/Specific mode selector. In Specific mode, individual ability slots can be toggled independently.

What is the MCP Adapter integration?

If the MCP Adapter plugin is active on your site, AcrossAI Abilities Manager will display the list of registered MCP servers in the ability edit panel. This is entirely optional — the plugin works without the MCP Adapter.

Does this plugin make external HTTP requests?

The plugin’s own code makes no external HTTP requests. Two admin-only surfaces trigger external connections on behalf of an authenticated administrator:

  • AcrossAI Consultations submenu — renders a static call-to-action button that links to https://calendly.com/acrossai/using-ai-in-wordpress and opens in a new browser tab. The plugin does not load any Calendly script, iframe, or asset inside wp-admin. Calendly is only contacted if the administrator explicitly clicks the button — at which point their browser navigates directly to calendly.com, exactly as with any external hyperlink.
  • AcrossAI Add-ons submenu — installs WordPress.org-hosted companion plugins in place through WordPress core’s plugins_api() + Plugin_Upgrader (contacts api.wordpress.org + downloads.wordpress.org). Add-ons registered with any other source (e.g. GitHub, Freemius) render as external “Get add-on ” links that open the vendor’s site in a new browser tab — the plugin does not download or install those add-ons itself. Users install off-directory add-ons via WP admin’s standard Plugins Add New Upload Plugin flow (or via the vendor’s own installer once the paid plugin is activated).

Full disclosure — including what data is transmitted, and links to each service’s terms + privacy policy — is in the External Services section of this readme.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“AcrossAI Abilities Manager” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

0.0.27 – 2026-08-14

Patch release — UI polish + admin-surface rename following the 0.0.26 Feature 067 rollup. No new abilities; both entries below are UX-affecting changes to the admin surface. Plugin version bumped 0.0.26 0.0.27.

  • Rename — “Ability Library” admin page is now “Ability Integrations”. The submenu label (“Library” “Integrations”), page title (“Ability Library” “Ability Integrations”), main heading, and URL slug (page=acrossai-abilities-library page=acrossai-abilities-integrations) all updated. Bookmarks / external links to the old slug will 404 in wp-admin — update saved links to the new URL. Internal class names, hook names, REST endpoint namespace (/wp-json/acrossai-abilities-library/v1/), and the DOM mount id are unchanged (deliberately scoped rename — extending to the REST namespace would break external MCP callers).
  • UI fix — Elementor abilities now render under their own “Elementor” tab in the Ability Integrations screen, not “Core”. Every Elementor ability (all 88 under acrossai/elementor-*) had its meta tab_group set to 'core', causing the group to appear in the Core tab with only a sub-heading identifying it as Elementor. Flipped every declaration to tab_group => 'elementor' (63 files including Base_Audit_Ability, which drives the 25 audit subclasses via inheritance). The Ability Integrations UI auto-derives tab names from distinct tab_group values, so a new “Elementor” tab appears without any frontend/asset rebuild.

0.0.26 – 2026-08-14

Release rollup — 89 abilities total: 87 unreleased Elementor abilities (Feature 067 completion) + 2 native site maintenance-mode abilities. Plugin version bumped 0.0.25 0.0.26. Elementor abilities gate on class_exists('\Elementor\Plugin') (with 8 additionally gated on Elementor Pro); site maintenance-mode toggle has no plugin dependency.

  • Native site maintenance-mode toggle (2 abilities):

    • acrossai/set-site-maintenance-mode — activate WordPress core maintenance mode by writing the ABSPATH/.maintenance marker file (the same file WP core writes during plugin/theme/core updates). A wp-cron event refreshes the marker every 5 minutes so the site stays down for the requested duration_minutes (default 60, hard-cap 1440). Requires confirm=true — blocks wp-admin as well as the frontend.
    • acrossai/unset-site-maintenance-mode — deactivate: delete the marker, clear the refresh cron, drop the expiry option. Idempotent — safe to call when maintenance mode is already inactive. Reports was_active in the response.
    • Both live under the existing acrossai-abilities-manager-site-health category alongside acrossai/get-maintenance-mode-status (Feature 063 read). No Elementor / plugin dependency — works on every WP install.
  • Feature 067 COMPLETE — 87 additional Elementor abilities ship in this release. Combined with the 2 foundation abilities from 0.0.25, the full 88 planned abilities are now available under the acrossai/elementor-* namespace. Design-audit ability logic is skeletal (Base_Audit_Ability skeleton returning empty findings) — real audit heuristics to be filled in follow-up work.

Batch 10 — full-document replacement (closes the parity gap):
* acrossai/elementor-update-data — overwrite the entire _elementor_data tree for a post with a caller-supplied element array; optional page_settings merge; force_replace=true required when the new payload is materially smaller than the existing document. Returns element_count + cache scope report.

Batch 9 — 29 design-audit abilities (this commit):

Aggregators + scorers (4):
* acrossai/elementor-evaluate-design — aggregate report from every registered design audit (score + findings + recommendations).
* acrossai/elementor-suggest-design-fixes — turn aggregated findings into concrete fix recommendations.
* acrossai/elementor-score-distinctiveness — neutral distinctiveness score for structural repetition.
* acrossai/elementor-extract-design-tokens — extract recurring colors / typography / spacing / dimensional tokens.

Individual audits (14):
* Column: audit-column-alignment-rhythm, audit-column-balance, audit-column-dominance, audit-column-necessity, audit-column-patterns
* Composition & emphasis: audit-composition-rhythm, audit-emphasis-drift, audit-section-rivalry, audit-separator-discipline, audit-surface-overuse
* Layout & repetition: audit-generic-component-repetition, audit-generic-layout-patterns, audit-layout-mechanism-fit, audit-native-widget-opportunities

Subtree operations — destructive (7):
* apply-text-hierarchy, enforce-boundary-coherence, fix-visible-gap-rhythm, normalize-responsive-values, normalize-section-spacing-rhythm, reset-negative-margins-subtree, zero-container-padding-subtree

Copy / sync / convert helpers — destructive (4):
* copy-lane-settings, copy-row-balance, image-widget-to-background-container, sync-component-variant

New utility class includes/Abilities/Elementor/Base_Audit_Ability.php provides the shared skeleton for 27 of the 29 audit abilities — subclasses supply audit_slug, audit_label, audit_description, and analyze(). Evaluate_Design and Suggest_Design_Fixes are self-contained aggregators.

Batch 8 — 8 Elementor Pro-gated abilities:
* acrossai/elementor-list-custom-code — list Custom Code snippets from elementor_snippet CPT; optional location filter.
* acrossai/elementor-get-custom-code — read one snippet including its code body.
* acrossai/elementor-create-custom-code — create snippet with title, code, location (head / body_start / body_end / footer), priority, status.
* acrossai/elementor-update-custom-code — update snippet fields.
* acrossai/elementor-delete-custom-code — trash (default) or permanently delete with force=true.
* acrossai/elementor-list-form-submissions — list Form widget submissions from the e_submissions table; optional form_id filter + include_values flag. Graceful degradation when the Pro submissions table is missing.
* acrossai/elementor-get-form-submission — read one submission by ID; optional field values.
* acrossai/elementor-delete-form-submission — permanently delete submission + its e_submissions_values rows; requires confirm=true.

All 8 Pro abilities gated on both class_exists( '\Elementor\Plugin' ) and class_exists( '\ElementorPro\Plugin' ) || defined( 'ELEMENTOR_PRO_VERSION' ) — silently absent on sites without Elementor Pro. Runtime deactivation returns error_code: elementor_pro_missing.

Batch 7 — 7 kits & site-settings abilities:
* acrossai/elementor-list-kits — list all Elementor kits; marks active kit.
* acrossai/elementor-get-kit-settings — read kit settings (defaults to active kit).
* acrossai/elementor-update-kit-settings — merge new settings; force_replace for full overwrite; site-wide cache invalidation.
* acrossai/elementor-set-active-kit — switch site-wide active kit; invalidates cache.
* acrossai/elementor-list-global-widgets — list global (reusable) widgets from elementor_library CPT.
* acrossai/elementor-list-experiments — list feature flags with current + default state.
* acrossai/elementor-update-experiment — toggle experiment state (active | inactive | default).

Batch 6 — 11 template abilities:
* acrossai/elementor-list-templates — list saved templates with filters on template_type + status + pagination.
* acrossai/elementor-get-template — return one template’s metadata + conditions + optional _elementor_data.
* acrossai/elementor-create-template — create a new template of type page / section / popup / header / footer / single / archive; sets taxonomy term + Elementor meta.
* acrossai/elementor-update-template — update title / page_settings / full data with force_replace guard.
* acrossai/elementor-delete-template — trash (default) or permanently delete with force=true.
* acrossai/elementor-restore-template — restore a trashed template.
* acrossai/elementor-duplicate-template — clone template preserving type + conditions + sub_type; regenerates element IDs.
* acrossai/elementor-empty-trash — permanently delete every trashed template; requires confirm=true.
* acrossai/elementor-export-template — export template as JSON-encodable object (title, template_type, sub_type, page_settings, content, conditions).
* acrossai/elementor-import-template — import from JSON export; regenerates element IDs; optional overwrite_id to replace an existing template.
* acrossai/elementor-find-template-for-pattern — rank saved templates by keyword match (title + tax term + widget-types in content); returns top N with scores.

Batch 5 — 11 site-management abilities:
* acrossai/elementor-clear-cache — clear Elementor cache at post / site / all scope; optional regenerate_css=true for a specific post.
* acrossai/elementor-replace-urls — bulk find/replace URLs across every Elementor document on the site with dry_run=true default preview.
* acrossai/elementor-get-maintenance-mode — read current maintenance mode settings (mode, template, exclude rules).
* acrossai/elementor-update-maintenance-mode — enable/disable maintenance mode with mode selection (maintenance | coming_soon).
* acrossai/elementor-get-theme-builder-conditions — read display conditions attached to an Elementor template.
* acrossai/elementor-update-theme-builder-conditions — replace display conditions; pass empty array to clear. Invalidates Elementor’s condition cache.
* acrossai/elementor-get-official-widget-catalog — canonical widget catalog (Basic / Pro / Theme / WooCommerce) with 12-hour transient.
* acrossai/elementor-get-official-pattern-guidance — pattern & layout guidance (widgets / patterns / layouts topics) grounded in Elementor documentation.
* acrossai/elementor-get-theme-context — active theme + Elementor version + active kit + viewport settings snapshot.
* acrossai/elementor-get-style-guide — style-guide summary from active kit (colors, typography, buttons, forms, layout, custom CSS).
* acrossai/elementor-evaluate-render-context — inspect frontend template + canvas type + edit-mode flag for a post.

Batch 4 — 9 page-composition abilities:
* acrossai/elementor-create-page — insert a new post/page pre-configured for Elementor (sets _elementor_edit_mode, _elementor_template_type, _elementor_version; seeds empty _elementor_data). Returns edit URL.
* acrossai/elementor-update-page-settings — merge new page-level settings into _elementor_page_settings. force_replace guard on materially-smaller payloads.
* acrossai/elementor-patch-data — find/replace text within the raw Elementor JSON string; updates every widget containing the match in one pass.
* acrossai/elementor-clone-data — copy the full Elementor tree from one post to another with fresh element IDs throughout. Optionally include page settings. force_replace guard on populated targets.
* acrossai/elementor-add-heading — widget shortcut (title, header_size h1-h6, align, title_color).
* acrossai/elementor-add-text-editor — widget shortcut (editor HTML, align).
* acrossai/elementor-add-image — widget shortcut (image ID or URL, size, align, caption, link).
* acrossai/elementor-add-button — widget shortcut (text, link, size xs-xl, align).
* acrossai/elementor-add-post-tabs — higher-order shortcut: Nested Tabs widget where each tab contains a native Posts widget (optionally filtered by taxonomy term or query args).

Batch 3 — 6 element-lifecycle abilities (previously in this section):
* acrossai/elementor-merge-element-settings — deep-merge new settings into an element by ID. Additive (no force_replace guard needed); reports changed_keys in the response.
* acrossai/elementor-delete-element — remove an element by ID. Guarded by force_delete=true for top-level or populated (with-children) elements.
* acrossai/elementor-remove-element — safer alias for delete-element with identical semantics.
* acrossai/elementor-move-element — atomic move to a new parent/position with descendant-guard preventing cycle-creating moves into own subtree.
* acrossai/elementor-duplicate-element — deep-clone an element (all nested children included) with fresh IDs generated throughout the cloned subtree; inserted as the next sibling.
* acrossai/elementor-reorder-elements — reorder direct children of a parent (or root); children omitted from ordered_element_ids retain their prior relative order and are appended after.

Batch 2 — 5 abilities merged earlier:
* acrossai/elementor-get-element — read a single element by 7-char hex ID.
* acrossai/elementor-find-elements — search by element_type / widget_type / contains-text.
* acrossai/elementor-update-element — replace by ID with force_replace guard.
* acrossai/elementor-add-container — insert Elementor v3+ container.
* acrossai/elementor-add-widget — insert any registered widget (validated via Widget_Controls).

Test coverage: 43 (b2) + 40 (b3) + 53 (b4) + 64 (b5) + 53 (b6) + 33 (b7) + 45 (b8) + 8 (b9 manifest) = 339 new source-inspection tests across 58 test files. Full suite: 975 tests, 1991 assertions, 0 failures. phpcs (WPCS strict) and phpstan (level 8) both clean.

Feature 067 ability surface complete: 88 of 88 abilities. Foundation + 2 shipped in 0.0.25 + 86 in this release. Every planned ability shipped. Design-audit analysis logic is skeletal (returns empty findings + recommendations); the audit surface is registered and composable via Design_Audit_Runner, real heuristics to be filled in follow-up work.

0.0.25

  • New — Feature 067 Elementor Ability Suite (interim ship: foundation + 2 abilities). First release of the planned 88-ability Elementor integration. This interim release delivers the full foundational infrastructure plus two highest-value abilities. Follow-up features (068+) will incrementally add the remaining 86 abilities.

Foundation — 6 utility classes + category registrar under includes/Abilities/Utilities/Elementor/ and includes/Abilities/Elementor/:
* Category_Registrar — registers the new acrossai-abilities-manager-elementor ability category. Self-guards on class_exists( '\Elementor\Plugin' ) so the category is silently absent on non-Elementor sites.
* Document_Repository — Elementor document I/O with mandatory wp_slash() policy on _elementor_data writes, cache invalidation (Elementor files manager + WP post cache + _elementor_css meta delete), and full tree helpers (find/insert/remove/reorder/replace by element ID, deep-clone with fresh IDs, descendant-guard).
* Widget_Controls — schema-safe summariser over Elementor’s WidgetsManager::get_widget_types() with case-insensitive control-name filtering.
* Template_QueryWP_Query wrappers for the elementor_library CPT with tax filters + keyword-scoring for pattern-search abilities.
* Guidance_Catalog — canonical Elementor.com widget catalog (60+ Basic/Pro/Theme/WooCommerce widgets seeded, 12-hour transient) + pattern & layout guidance data (nav-menu vs mega-menu, container vs section, Grid vs Flexbox for symmetric columns, etc.).
* Design_Audit_Runner — orchestrator for the 28 design-audit abilities landing in follow-up features (register + run individual + run-all with aggregate score + findings + recommendations).

Bootstrap gating in includes/Abilities/AcrossAI_Core_Abilities_Bootstrap.php:
* Two-layer gate: outer class_exists( '\Elementor\Plugin' ) at plugins_loaded P20 (registration-time) plus per-ability defense-in-depth check at execution time (runtime deactivation returns clean error_code: elementor_missing envelope, no fatals).
* Inner Pro gate: class_exists( '\ElementorPro\Plugin' ) || defined( 'ELEMENTOR_PRO_VERSION' ) for the future Custom Code + Form Submissions abilities.
* Split into two private methods register_elementor_free_abilities() + register_elementor_pro_abilities() — new new Elementor\<Class>() lines added as each ability class lands.

Two shipped abilities under acrossai/elementor-* namespace:
* acrossai/elementor-get-widget-controls — schema-lookup primitive. Returns the schema-safe control summary for any registered Elementor widget on the current site (free + Pro + third-party). Enables clients to author valid add-widget / update-element payloads without hard-coded per-widget wrappers. Optional case-insensitive search filter.
* acrossai/elementor-get-data — the read primitive. Returns the parsed Elementor document tree + page settings for a post, plus recursive element count.

Test coverage: 44 new utility tests + 15 new ability tests = 59 additional PHPUnit assertions. Full suite: 636 tests, 1530 assertions, 0 failures. phpcs (WPCS strict) and phpstan (level 8) both clean.

Test-bootstrap additions: stubs for wp_rand, get_transient, set_transient, delete_transient, and HOUR_IN_SECONDS constant to support the new utilities under the unit-only bootstrap.

Spec artifacts at specs/067-elementor-abilities/: complete design for all 88 abilities documented in spec.md / plan.md / research.md / data-model.md / contracts/abilities.md / quickstart.md / tasks.md — follow-up features will implement Phases 3-13 tasks against these contracts.

0.0.24

  • New — 6 abilities and 1 enhancement for full Gutenberg block-tree control (feature 066). Closes the gap between the plugin’s existing block-registry surface and per-post block-tree manipulation. All abilities live under the existing acrossai-abilities-manager-content category.

Feature 066 — Block tree mutation & nested editing (6 new abilities + 1 modified).
* acrossai/get-post-blocks — return a post’s parsed Gutenberg block tree with each block annotated with its canonical integer-array path (e.g. [0, 2, 1] = 2nd grandchild of the 3rd child of the 1st top-level block). Read-only, idempotent.
* acrossai/add-block — insert a new block into a post at parent_path + index. Appends when the requested index exceeds the current sibling count.
* acrossai/remove-block — remove the block at a canonical path; returns the removed payload so callers can undo/log.
* acrossai/duplicate-block — deep-clone the block at a path (including all inner blocks) and insert the clone as the next sibling.
* acrossai/move-block — atomically move a block from from_path to to_parent_path + to_index. Refuses moves into the source’s own subtree (would create a cycle).
* acrossai/insert-pattern — resolve a saved block pattern by slug across database / active theme / installed plugins, then insert its constituent blocks at parent_path + index. Ambiguous slugs return multiple_locations so callers can disambiguate via source / theme_type / plugin_slug.
* acrossai/update-post-block (modified) — now accepts an optional path input for nested editing at any depth. Existing consumers using block_index or block_name + occurrence see zero behaviour change — the path branch is a strict addition.
* All write abilities share the same guards as the existing update-post-block: manage_options + edit_posts globally, edit_post per-post, post-type whitelist against internal CPTs (revision / nav_menu_item / custom_css / customize_changeset / oembed_cache / user_request), block-name regex validation, and soft-fail attribute-schema validation against the registered block type.
* Shared Block_Tree utility (includes/Abilities/Utilities/Block_Tree.php) centralises tree-path primitives — walk, get-at-path, insert / remove / replace / move, block-name and attribute-schema validation. Extracts what was previously private inline logic in Update_Post_Block::execute.
* Test coverage: 82 new PHPUnit assertions across 8 test files.

0.0.23

  • New — 30 abilities across three feature spec drops (062, 063, 064). Bulk expansion of the plugin’s ability surface. No breaking changes.

Feature 062 — Role & capability CRUD + site-wide DB search-replace (8 abilities).
* acrossai/add-role-capability, acrossai/remove-role-capability, acrossai/create-role, acrossai/delete-role, acrossai/reset-role, acrossai/add-user-capability, acrossai/remove-user-capability — writers for the role/cap surface WordPress core REST does not expose. Every write is destructive: true.
* acrossai/search-replace — site-wide serialized-data-safe string replacement across every WordPress-managed table. dry_run: true by default — the ability returns a per-table / per-column match tally without mutating any row, and mutating writes only happen when the caller explicitly passes dry_run: false. Table allowlist mirrors Update_Db_Rows.php (validates every input table against SHOW TABLES before scanning). Skips wp_posts.guid unless the caller explicitly opts in via include_guids: true (safer default than WP-CLI). Recursive maybe_unserialize / maybe_serialize walk keeps serialized meta / options structurally valid.
* Guardrails: remove-role-capability refuses to strip a WP-core administrator baseline capability from the administrator role; delete-role refuses on any of the 5 built-in roles AND when the role is still held by any user; reset-role accepts only the 5 built-in role slugs; remove-user-capability refuses to strip a WP-core admin cap from the last remaining administrator.

Feature 063 — Site introspection reads + new Widgets category (11 abilities).
* acrossai/get-wp-version, acrossai/get-db-prefix, acrossai/get-wp-config-constant, acrossai/list-theme-mods, acrossai/list-rewrite-rules, acrossai/list-image-sizes, acrossai/get-comment-count, acrossai/get-maintenance-mode-status, acrossai/test-wp-cron — small single-purpose reads that WordPress does not expose through a public REST endpoint. Every ability is readonly: true, idempotent: true, destructive: false.
* acrossai/list-widgets, acrossai/list-sidebars — legacy widget-system introspection under a new Widgets category (slug acrossai-abilities-manager-widgets).
* Guardrails: get-wp-config-constant hard-blocks disclosure of AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT, and DB_PASSWORD regardless of the manage_options gate; get-maintenance-mode-status uses WordPress core’s own 10-minute staleness threshold; test-wp-cron fires a single non-blocking wp_remote_get() with a 0.01s timeout so it never hangs a REST response.

Feature 064 — Transient CRUD, nested option access, plugin lifecycle & checksum integrity (11 abilities).
* Transient CRUD (Cache category): acrossai/get-transient, acrossai/list-transients (paginated, search-filterable, expiry-aware), acrossai/delete-transient, acrossai/delete-expired-transients — closes the previous read-nothing / bulk-only-delete gap.
* Nested option access (Options category): acrossai/get-nested-option-value and acrossai/patch-option-value — read or mutate one nested key inside a serialized option without round-tripping the whole blob. Guarded by Update_Option::BLOCKED_OPTIONS (extracted as a public const on Update_Option in this release so both classes share one authoritative block-list of 21 protected core options).
* Post-meta append (Content category): acrossai/add-post-meta — WordPress core add_post_meta() semantics with the WP-core unique flag. Complements the existing update / delete post-meta writers.
* Plugin lifecycle (Plugins category): acrossai/search-wp-plugin-directory (searches the WordPress.org plugin directory via plugins_api(); short description sanitised via wp_kses_post()), acrossai/uninstall-plugin (fires the plugin’s registered uninstall hook + deletes files via WP core uninstall_plugin(); refuses on active plugins and on sites with DISALLOW_FILE_MODS), acrossai/verify-plugin-checksums.
* Core integrity (Core category): acrossai/verify-core-checksums — fetches the official api.wordpress.org checksums manifest via wp_remote_get() and compares md5_file() hashes; per-file status: 'ok'|'modified'|'missing'|'added' and a summary counter.

  • Every one of the 30 new abilities gates on current_user_can( 'manage_options' ) using the identical permission-callback pattern already used by all 219 existing abilities: static function (): bool { return current_user_can( 'manage_options' ); }. No cap escalation via filter.
  • One new ability category — Widgets (acrossai-abilities-manager-widgets), registered via includes/Abilities/Widgets/Category_Registrar.php mirroring the shape of includes/Abilities/Menus/.
  • 204 new PHPUnit test methods on top of the previous 191 (final suite: ~395 methods across the 8.1 8.5 PHP CI matrix). Every new class file passes PHPStan level 8 and the plugin’s PHPCS WPCS strict profile.
  • No breaking changes. No ability slug rename. No REST endpoint change. No option-shape change. No new required capability. Existing 218 abilities behave identically. The Update_Option::BLOCKED_OPTIONS extraction in Feature 064 is a pure move of an inline literal into a public const; behaviour is unchanged. Safe upgrade from 0.0.22.

0.0.22

  • New — acrossai/delete-post-meta ability under the Content category. Deletes a single post meta row via WordPress core delete_post_meta(). Accepts post_id + key (with the WP-core-native meta_key alias) and an optional value (with meta_value alias). When a value is supplied, only rows matching that value are removed; otherwise every row for the given key is removed. Gated by manage_options; annotated destructive: true, idempotent: true. Mirrors the shape of acrossai/update-post-meta for consistent client ergonomics.
  • Fixed — acrossai/update-post-meta no longer rejects protected meta keys (#99). The pre-0.0.22 execute() short-circuited with success: false whenever is_protected_meta( $key, 'post' ) returned true, contradicting the class docblock (“Works for ANY meta key”). Now the ability writes any key the manage_options gate allows through — the capability check remains the sole access boundary. The registered description was also updated to match the new behaviour (“Works for any meta key, including protected keys.”).
  • Composer dependency bump — acrossai-co/main-menu 0.0.30 0.0.33. Rolls three shared-menu library releases into one hop; composer.lock regenerated to reference e17e1e8.
  • No breaking changes. No ability slug rename. No REST endpoint change. No option-shape change. No new required capability. Existing 218 abilities behave identically. Safe upgrade from 0.0.21.

0.0.21

  • Composer dependency bump — wpboilerplate/wpb-access-control ^2.0.0 ^3.1.0. Adopts two major releases of the shared access-control library in one hop:
    • v3.0.0 (breaking, but not for this plugin). The two plugin-dependent providers shipped in the library’s v1.4.0 / v1.5.0 — BuddyBossProfileTypeProvider (bb_profile_type) and MemberPressMembershipProvider (mepr_membership) — were extracted into a separate WordPress add-on called AcrossAI User Access Pro (acrossai/user-access-pro), along with eight new integrations (LearnDash Group, LifterLMS Membership, Paid Memberships Pro, Restrict Content Pro, WooCommerce Memberships, s2Member Level, Wishlist Member Level, Memberium Membership). The library now ships only the three WordPress-native providers (wp_role, wp_user, wp_capability) plus a new wpb_access_control_register_providers global filter for add-on registration. This plugin uses only AccessControlManager + RuleTable — neither of the removed provider classes. No consumer-side code change is required; every existing Access Control rule shape is preserved and the per-consumer AccessControlManager( $providers_filter, $table_slug ) constructor signature is unchanged.
    • v3.1.0. Adds a new AccessControlManager::TYPE_AUTHENTICATED ('authenticated') sentinel rule type — grants access to any logged-in user without requiring a specific role or capability match. Rendered in the Access Control dropdown as “Any logged-in user”, stored as a single sentinel row like everyone. Also renames the public option label from “Everyone (no restriction)” to “Public (no login required)” for clarity. Existing rules are untouched; the everyone key behaves identically.
  • New Access Control rule affordance on every ability. Site administrators can now pick “Any logged-in user” from the Access Control dropdown on the ability edit panel — useful for abilities that should be reachable by every authenticated user (including subscribers) without curating a specific role list. Rules using the previous “Everyone” wording continue to work unchanged; the dropdown label just clarifies that everyone means “no login required.”
  • Migration required only for sites vendoring the built assets. Consumer plugins that pin vendor/wpboilerplate/wpb-access-control/assets/build/ in their release bundle should composer update and rebuild to pick up the new dropdown option. This plugin re-vendors the library’s compiled CSS via admin/Main.php::enqueue_styles() and the composer update this changelog entry documents already regenerates that asset path.
  • No breaking changes. No ability slug rename. No REST endpoint change. No option-shape change. No new required capability. Every existing 218 abilities behave identically. Existing Access Control rules keep working — the removed BuddyBoss / MemberPress providers were never registered from this plugin (they defaulted to is_available() === false in the library’s v1.6.0 – v2.0.x range on sites that had not explicitly opted in). Safe upgrade from 0.0.20.

0.0.20

  • Changed — access-control library-missing notice now routes through the shared AcrossAI notice hub. The pre-0.0.20 AcrossAI_Abilities_Access_Control::maybe_show_library_notice() method was hooked on WordPress core admin_notices and printed a raw .notice.notice-warning banner on every admin screen when the wpb-access-control library wasn’t loaded. It is renamed to register_library_notice( array $notices ): array and now registers into the new acrossai_notices filter shipped by acrossai-co/main-menu 0.0.30. The notice appears in two places instead: (1) as a card on the new AcrossAI Notices submenu (only registered when at least one notice is present, with a WP-style count bubble on the menu label), and (2) as a single top-of-page WordPress-native .notice.notice-warning.is-dismissible summary banner (“AcrossAI has N notifications for your attention — View notices ”) printed on every other admin page. Dismissal is fingerprint-persisted per user until the notice set changes. Notice record shape: id=wpb_access_control_missing, type=warning, source=AcrossAI Abilities Manager. Semantics are unchanged — the fail-open behaviour, the manage_options gate (enforced by the menu itself and the summary emitter), and the message copy are all preserved.
  • Composer dependency bump — acrossai-co/main-menu 0.0.29 0.0.30. Ships the cross-plugin notice system this release routes through:
    • New acrossai_notices filter — any AcrossAI consumer plugin can push admin-notice records into a shared collection using a single documented record shape (id, title, message, type, optional source, optional action { label, url }). Later registrations of the same id are ignored (first-wins). Missing id or both title and message empty the entry is dropped.
    • New AcrossAI Notices submenu (slug acrossai-notices, class NoticesPageRenderer) — only registered when at least one notice exists. Menu label carries a WP-style count bubble (.awaiting-mod).
    • New top-of-page summary notice emitter (SummaryNoticeEmitter) — prints one WordPress-native dismissible banner on every other admin page linking to the Notices submenu. Dismissal is fingerprint-based (SHA-1 of sorted notice IDs stored in per-user meta _acrossai_notices_summary_fp) so the summary re-appears whenever the notice set changes.
    • New AJAX endpoint wp_ajax_acrossai_notices_dismiss_summary — nonce + manage_options guarded; server re-validates the client-supplied fingerprint against the current notice set as defense-in-depth against poisoning the user meta with an unrelated hash.
    • New public classes under AcrossAI_Main_Menu\: Notices, NoticesPageRenderer, NoticesAjaxHandlers, SummaryNoticeEmitter. New page-slug constant SettingsPage::NOTICES_SLUG and static accessor SettingsPage::get_notices(): ?Notices for consumers that want to inspect the current notice list programmatically.
  • Note — the vendor-missing boot-resilience notice in Includes\Main::__construct() remains on core admin_notices. That code path fires precisely when the composer autoloader is absent — the moment when the shared main-menu package isn’t loadable either — so the acrossai_notices filter cannot be reached from it. This is intentional and matches Constitution §V Integration Resilience.
  • No breaking changes. No ability slug rename. No REST endpoint change. No option-shape change. No new required capability. Existing 218 abilities behave identically. Safe upgrade from 0.0.19.

0.0.19

  • New — MCP Manager promo callout on the ability edit form. The MCP Exposure section (Section 3) of the Custom Abilities edit page now surfaces a blue-tinted informational callout advertising the sibling acrossai-mcp-manager plugin when it is not installed / active on the current site. The callout renders directly below the existing “Heads up” warning and offers two actions: an “Install from Add-ons” button that deep-links to the AcrossAI Add-ons page (admin.php?page=acrossai-addons), and a “Learn more” external link to https://acrossai.co/mcp-manager/. When the AcrossAI MCP Manager plugin IS active on the site, the callout is fully suppressed — zero UI on the edit form. Detection uses WordPress core is_plugin_active( 'acrossai-mcp-manager/acrossai-mcp-manager.php' ) inside the admin script enqueue path; the resolved boolean plus the two URLs are injected into the existing window.acrossaiAbilitiesManager localize payload as mcp_manager_active, mcp_manager_addons_url, and mcp_manager_info_url. The callout also degrades gracefully on older bundles or a customised localize payload — the two action buttons render only when their corresponding URL keys are non-empty.
  • Composer dependency bump — acrossai-co/main-menu 0.0.27 0.0.29. Two-hop bump rolled into one release:
    • 0.0.28 — refreshed the Add-ons page baseline catalogue. The hard-coded add-on list now surfaces three entries: AcrossAI Abilities Manager (wp.org), AcrossAI MCP Manager (wp.org), and AI Connectors (external “Get add-on ” link to acrossai.co/ai-connectors/#pricing). AcrossAI Model Manager and Turn Off AI Features are dropped from the hard-coded baseline — sites that still want them can register them via the acrossai_addons filter unchanged. All three baseline cards render the shared AcrossAI SVG logo from acrossai.co instead of per-plugin ps.w.org PNG icons, so the Add-ons page reads as one product surface. Icon fit switched from cover to contain (with 6px padding) so wide/horizontal SVG logos render fully instead of being cropped inside the 56×56 icon box. Grid pinned to a fixed 3-column layout (repeat(3, minmax(0, 1fr))) with responsive fallbacks (2 cols under 1100px, 1 col under 720px). New optional learn_more_url add-on field renders as a “Learn more” text link inside the card action row for every add-on regardless of source.
    • 0.0.29 — reworked the Add-ons card action states so the page reads as a discovery surface, not a plugin manager. Active add-ons now render a non-clickable green “● Running” pill instead of a “Deactivate” button; deactivation stays in Plugins Installed Plugins where WP admins expect it (new CSS classes .acrossai-addons__status / .acrossai-addons__status--active / .acrossai-addons__status-dot). Installed non-wordpress.org add-ons now show an in-page Activate button instead of always rendering the external “Get add-on ” link — detection is source-agnostic and driven by AddonsInstaller::find_plugin_file(), so a paid/off-directory add-on that the admin uploaded via Plugins Add New Upload Plugin can be activated straight from the AcrossAI Add-ons page. The Install code path remains restricted to wordpress.org sources (WP.org guideline #8 — no change). The AI Connectors baseline entry declares install_folder => 'acrossai-ai-connectors' so install detection matches the actual plugin folder even though the registry slug (ai-connectors) differs — canonical example for consumers whose extracted folder ≠ slug.
  • No breaking changes. No ability slug rename. No REST endpoint change. No option-shape change. No new required capability. Existing 218 abilities behave identically. Safe upgrade from 0.0.18.

0.0.18

  • New — Third-party integration framework (Feature 060) with Advanced Custom Fields as the first concrete integration. Adds a new “Acf” tab to the Ability Library page (/wp-admin/admin.php?page=acrossai-abilities-library&tab=acf) with a single toggle labelled “Advanced Custom Fields (AI)”. Flipping the toggle ON attaches add_filter( 'acf/settings/enable_acf_ai', '__return_true' ) early enough in plugins_loaded (priority 20) that ACF picks it up on the same request and registers its FieldGroup / PostType / Taxonomy AI abilities. Flipping OFF leaves ACF’s default (writes disabled) in place. Default is OFF for every integration — enabling AI-driven schema manipulation on a production site is always an explicit admin decision. The tab and card only appear when the target plugin (ACF) is installed AND active on the current site; deactivating ACF while the toggle is on preserves the saved state without leaking any error notice or fatal.
  • New — extensibility surface for third-party AcrossAI plugins. Any WordPress plugin can now register its own regular ability cards on an integration’s tab (alongside the integration’s own toggle card) using a documented 3-step contract: (1) register the ability category on wp_abilities_api_categories_init via wp_register_ability_category(), (2) extend \AcrossAI_Abilities_Manager\Includes\Modules\Library\Ability_Definition, and (3) set meta.acrossai.tab_group on the ability’s args to the integration’s published TAB_GROUP constant (e.g. \AcrossAI_Abilities_Manager\Includes\Abilities\Integrations\ACF::TAB_GROUP). Reads from the new AcrossAI_Integration_Ability_Base docblock + the quickstart worked example under specs/060-library-third-party-integration-toggles/quickstart.md. This is the mechanism that lets the sibling acrossai-acf-abilities plugin surface its own cards on the same “Acf” tab.
  • New REST filter — acrossai_integration_toggle_capability. Lets sites raise (never lower) the WordPress capability required to flip an integration toggle. Default is manage_options (matches the rest of the Ability Library page); a site can attach a filter returning e.g. manage_network_options and a manage_options-only user will then receive HTTP 403 on the REST write. Enforced server-side on the same write path that persists the toggle — cannot be bypassed by a crafted REST request even if the JS UI presented the toggle as interactive. Companion action acrossai_integration_toggle_denied fires immediately before the 403 so sites can wire audit logging without amending core code.
  • Bugfix — sparse-storage in acrossai_library_config was silently stripping integration ON entries. The pre-Feature-060 sparse-storage rule in AcrossAI_Ability_Library_Config::save_config() assumed every category defaults to enabled=true, so a { enabled: true, mode: 'all', sub_keys: {} } payload was stripped as “default state”. Feature 060 integration categories invert that default (missing = OFF …