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, andmcp_serversfields 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_optionscapability. - 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-wordpressin 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()andPlugin_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-coreability 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
- Upload the
acrossai-abilities-managerfolder to/wp-content/plugins/. - Activate the plugin through the Plugins menu in WordPress.
- Navigate to AcrossAI Abilities Manager in the WordPress admin menu.
Add-ons:
- Go to AcrossAI Add-ons to browse available companion plugins.
- 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-wordpressand 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 tocalendly.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(contactsapi.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.
- AcrossAI Consultations submenu — renders a static call-to-action button that links to
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.
ContributorsTranslate “AcrossAI Abilities Manager” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
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-librarypage=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 metatab_groupset to'core', causing the group to appear in the Core tab with only a sub-heading identifying it as Elementor. Flipped every declaration totab_group => 'elementor'(63 files includingBase_Audit_Ability, which drives the 25 audit subclasses via inheritance). The Ability Integrations UI auto-derives tab names from distincttab_groupvalues, 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 theABSPATH/.maintenancemarker 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 requestedduration_minutes(default 60, hard-cap 1440). Requiresconfirm=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. Reportswas_activein the response.- Both live under the existing
acrossai-abilities-manager-site-healthcategory alongsideacrossai/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_Abilityskeleton 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_Query — WP_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-contentcategory.
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 viaincludes/Abilities/Widgets/Category_Registrar.phpmirroring the shape ofincludes/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_OPTIONSextraction in Feature 064 is a pure move of an inline literal into apublic const; behaviour is unchanged. Safe upgrade from 0.0.22.
0.0.22
- New —
acrossai/delete-post-metaability under the Content category. Deletes a single post meta row via WordPress coredelete_post_meta(). Acceptspost_id+key(with the WP-core-nativemeta_keyalias) and an optionalvalue(withmeta_valuealias). When a value is supplied, only rows matching that value are removed; otherwise every row for the given key is removed. Gated bymanage_options; annotateddestructive: true,idempotent: true. Mirrors the shape ofacrossai/update-post-metafor consistent client ergonomics. - Fixed —
acrossai/update-post-metano longer rejects protected meta keys (#99). The pre-0.0.22execute()short-circuited withsuccess: falsewheneveris_protected_meta( $key, 'post' )returned true, contradicting the class docblock (“Works for ANY meta key”). Now the ability writes any key themanage_optionsgate allows through — the capability check remains the sole access boundary. The registereddescriptionwas also updated to match the new behaviour (“Works for any meta key, including protected keys.”). - Composer dependency bump —
acrossai-co/main-menu0.0.30 0.0.33. Rolls three shared-menu library releases into one hop;composer.lockregenerated to referencee17e1e8. - 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) andMemberPressMembershipProvider(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 newwpb_access_control_register_providersglobal filter for add-on registration. This plugin uses onlyAccessControlManager+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-consumerAccessControlManager( $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 likeeveryone. Also renames the public option label from “Everyone (no restriction)” to “Public (no login required)” for clarity. Existing rules are untouched; theeveryonekey behaves identically.
- 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 —
- 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
everyonemeans “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 shouldcomposer updateand rebuild to pick up the new dropdown option. This plugin re-vendors the library’s compiled CSS viaadmin/Main.php::enqueue_styles()and thecomposer updatethis 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() === falsein 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 coreadmin_noticesand printed a raw.notice.notice-warningbanner on every admin screen when thewpb-access-controllibrary wasn’t loaded. It is renamed toregister_library_notice( array $notices ): arrayand now registers into the newacrossai_noticesfilter shipped byacrossai-co/main-menu0.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-dismissiblesummary 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, themanage_optionsgate (enforced by the menu itself and the summary emitter), and the message copy are all preserved. - Composer dependency bump —
acrossai-co/main-menu0.0.29 0.0.30. Ships the cross-plugin notice system this release routes through:- New
acrossai_noticesfilter — any AcrossAI consumer plugin can push admin-notice records into a shared collection using a single documented record shape (id,title,message,type, optionalsource, optionalaction { label, url }). Later registrations of the sameidare ignored (first-wins). Missingidor bothtitleandmessageempty the entry is dropped. - New AcrossAI Notices submenu (slug
acrossai-notices, classNoticesPageRenderer) — 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_optionsguarded; 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 constantSettingsPage::NOTICES_SLUGand static accessorSettingsPage::get_notices(): ?Noticesfor consumers that want to inspect the current notice list programmatically.
- New
- Note — the vendor-missing boot-resilience notice in
Includes\Main::__construct()remains on coreadmin_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 theacrossai_noticesfilter 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-managerplugin 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 tohttps://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 coreis_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 existingwindow.acrossaiAbilitiesManagerlocalize payload asmcp_manager_active,mcp_manager_addons_url, andmcp_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-menu0.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 theacrossai_addonsfilter unchanged. All three baseline cards render the shared AcrossAI SVG logo fromacrossai.coinstead of per-pluginps.w.orgPNG icons, so the Add-ons page reads as one product surface. Icon fit switched fromcovertocontain(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 optionallearn_more_urladd-on field renders as a “Learn more” text link inside the card action row for every add-on regardless ofsource. - 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.orgadd-ons now show an in-page Activate button instead of always rendering the external “Get add-on ” link — detection is source-agnostic and driven byAddonsInstaller::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 towordpress.orgsources (WP.org guideline #8 — no change). TheAI Connectorsbaseline entry declaresinstall_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.
- 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
- 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 attachesadd_filter( 'acf/settings/enable_acf_ai', '__return_true' )early enough inplugins_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_initviawp_register_ability_category(), (2) extend\AcrossAI_Abilities_Manager\Includes\Modules\Library\Ability_Definition, and (3) setmeta.acrossai.tab_groupon the ability’s args to the integration’s publishedTAB_GROUPconstant (e.g.\AcrossAI_Abilities_Manager\Includes\Abilities\Integrations\ACF::TAB_GROUP). Reads from the newAcrossAI_Integration_Ability_Basedocblock + the quickstart worked example underspecs/060-library-third-party-integration-toggles/quickstart.md. This is the mechanism that lets the siblingacrossai-acf-abilitiesplugin 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 ismanage_options(matches the rest of the Ability Library page); a site can attach a filter returning e.g.manage_network_optionsand amanage_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 actionacrossai_integration_toggle_deniedfires immediately before the 403 so sites can wire audit logging without amending core code. - Bugfix — sparse-storage in
acrossai_library_configwas silently stripping integration ON entries. The pre-Feature-060 sparse-storage rule inAcrossAI_Ability_Library_Config::save_config()assumed every category defaults toenabled=true, so a{ enabled: true, mode: 'all', sub_keys: {} }payload was stripped as “default state”. Feature 060 integration categories invert that default (missing = OFF …
