{"id":311005,"date":"2026-06-26T06:49:51","date_gmt":"2026-06-26T06:49:51","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/acrossai-abilities-manager\/"},"modified":"2026-08-13T20:23:39","modified_gmt":"2026-08-13T20:23:39","slug":"acrossai-abilities-manager","status":"publish","type":"plugin","link":"https:\/\/lin.wordpress.org\/plugins\/acrossai-abilities-manager\/","author":15295430,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.0.27","stable_tag":"0.0.27","tested":"7.0.4","requires":"6.9","requires_php":"8.1","requires_plugins":null,"header_name":"AcrossAI Abilities Manager","header_author":"raftaar1191","header_description":"Manage and customize the abilities of AcrossAI on your WordPress site. Tailor the AI's capabilities to suit your needs, enhancing user experience and engagement.","assets_banners_color":"fdfdfe","last_updated":"2026-08-13 20:23:39","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/github.com\/acrosswp\/acrossai-abilities-manager","header_plugin_uri":"https:\/\/acrossai.co\/","header_author_uri":"https:\/\/profiles.wordpress.org\/raftaar1191\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":910,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.0.1":{"tag":"0.0.1","author":"raftaar1191","date":"2026-06-26 06:49:29"},"0.0.10":{"tag":"0.0.10","author":"raftaar1191","date":"2026-07-18 00:50:18"},"0.0.11":{"tag":"0.0.11","author":"raftaar1191","date":"2026-07-18 15:51:33"},"0.0.12":{"tag":"0.0.12","author":"raftaar1191","date":"2026-07-18 16:15:59"},"0.0.13":{"tag":"0.0.13","author":"raftaar1191","date":"2026-07-20 03:01:52"},"0.0.14":{"tag":"0.0.14","author":"raftaar1191","date":"2026-07-20 03:08:58"},"0.0.15":{"tag":"0.0.15","author":"raftaar1191","date":"2026-07-20 19:33:50"},"0.0.17":{"tag":"0.0.17","author":"raftaar1191","date":"2026-07-25 15:38:31"},"0.0.18":{"tag":"0.0.18","author":"raftaar1191","date":"2026-07-27 09:05:53"},"0.0.19":{"tag":"0.0.19","author":"raftaar1191","date":"2026-07-31 07:41:16"},"0.0.2":{"tag":"0.0.2","author":"raftaar1191","date":"2026-07-02 12:04:52"},"0.0.20":{"tag":"0.0.20","author":"raftaar1191","date":"2026-08-02 14:45:00"},"0.0.21":{"tag":"0.0.21","author":"raftaar1191","date":"2026-08-08 09:21:59"},"0.0.22":{"tag":"0.0.22","author":"raftaar1191","date":"2026-08-10 18:14:44"},"0.0.23":{"tag":"0.0.23","author":"raftaar1191","date":"2026-08-11 09:38:46"},"0.0.24":{"tag":"0.0.24","author":"raftaar1191","date":"2026-08-12 17:51:24"},"0.0.25":{"tag":"0.0.25","author":"raftaar1191","date":"2026-08-13 13:28:41"},"0.0.26":{"tag":"0.0.26","author":"raftaar1191","date":"2026-08-13 19:38:26"},"0.0.27":{"tag":"0.0.27","author":"raftaar1191","date":"2026-08-13 20:23:39"},"0.0.3":{"tag":"0.0.3","author":"raftaar1191","date":"2026-07-02 12:30:19"},"0.0.4":{"tag":"0.0.4","author":"raftaar1191","date":"2026-07-03 22:38:31"},"0.0.5":{"tag":"0.0.5","author":"raftaar1191","date":"2026-07-04 01:29:09"},"0.0.6":{"tag":"0.0.6","author":"raftaar1191","date":"2026-07-13 14:09:04"},"0.0.7":{"tag":"0.0.7","author":"raftaar1191","date":"2026-07-13 18:14:55"},"0.0.8":{"tag":"0.0.8","author":"raftaar1191","date":"2026-07-17 00:32:32"},"0.0.9":{"tag":"0.0.9","author":"raftaar1191","date":"2026-07-17 16:29:43"}},"upgrade_notice":{"0.0.21":"<p>Bumps the <code>wpboilerplate\/wpb-access-control<\/code> composer dependency from <code>^2.0.0<\/code> to <code>^3.1.0<\/code> \u2014 two library releases in one hop. v3.0.0 removed two plugin-dependent providers (<code>BuddyBossProfileTypeProvider<\/code>, <code>MemberPressMembershipProvider<\/code>) that were extracted into a separate add-on (<code>acrossai\/user-access-pro<\/code>); this plugin uses only the core <code>AccessControlManager<\/code> + <code>RuleTable<\/code> classes, so no consumer code change is required. v3.1.0 adds a new &quot;Any logged-in user&quot; option to the Access Control dropdown (backed by a new <code>authenticated<\/code> sentinel rule type), and renames &quot;Everyone (no restriction)&quot; \u2192 &quot;Public (no login required)&quot; for clarity. Existing rules unaffected. Safe upgrade from 0.0.20.<\/p>","0.0.20":"<p>Routes the access-control library-missing warning through the new shared AcrossAI notice hub (<code>acrossai_notices<\/code> filter shipped by <code>acrossai-co\/main-menu<\/code> 0.0.30). Instead of a raw wp-admin banner on every screen, the notice now appears on the new AcrossAI \u2192 Notices submenu (with a count bubble on the menu label) and as a single top-of-page summary banner (&quot;AcrossAI has N notifications for your attention \u2014 View notices \u2192&quot;) whose dismissal persists per user until the notice set changes. The fail-open semantics and message copy are unchanged. No breaking changes; existing abilities unaffected. Safe upgrade from 0.0.19.<\/p>","0.0.19":"<p>Adds a blue promotional callout on the ability edit form (MCP Exposure section) that advertises the sibling AcrossAI MCP Manager plugin when it is not installed \/ active. The callout links to the AcrossAI Add-ons page for install and to acrossai.co\/mcp-manager\/ for more info. Fully suppressed when the AcrossAI MCP Manager plugin is active. Also bumps the <code>acrossai-co\/main-menu<\/code> composer dependency from 0.0.27 to 0.0.29 \u2014 0.0.28 refreshes the Add-ons page baseline catalogue (AcrossAI Abilities Manager + AcrossAI MCP Manager + AI Connectors) with shared brand icon, <code>contain<\/code>-fitted icon boxes, fixed 3-column grid layout, and a new optional <code>learn_more_url<\/code> field; 0.0.29 reworks the card action states so active add-ons render a non-clickable &quot;\u25cf Running&quot; pill (deactivation stays in Plugins \u2192 Installed Plugins) and installed non-wp.org add-ons now show an in-page Activate button instead of always linking out. No breaking changes; existing abilities unaffected. Safe upgrade from 0.0.18.<\/p>","0.0.18":"<p>New third-party integration framework (Feature 060) with Advanced Custom Fields as the first concrete integration \u2014 flip one toggle on the new &quot;Acf&quot; tab of the Ability Library page to enable ACF&#039;s AI abilities without editing code. Also new: extensibility surface so other AcrossAI plugins can add their own cards to an integration&#039;s tab, filterable capability check for the toggle (via <code>acrossai_integration_toggle_capability<\/code>), and audit action (<code>acrossai_integration_toggle_denied<\/code>). Fixes a sparse-storage bug that could silently strip the integration ON state. Bumps the <code>acrossai-co\/main-menu<\/code> composer dependency from 0.0.23 to 0.0.27 to land two WordPress.org plugin directory guideline #8 fixes: the Consultations submenu now uses an external-link CTA instead of an embedded Calendly iframe, and the Add-ons page install action is now WordPress.org-only (non-wp.org cards render as external &quot;Get add-on \u2197&quot; links opening the vendor&#039;s site in a new tab). No breaking changes; existing abilities unaffected. Safe upgrade from 0.0.17.<\/p>","0.0.17":"<p>BREAKING \u2014 every ability slug has been renamed. Namespace shortens from <code>acrossai-abilities-manager\/<\/code> to <code>acrossai\/<\/code>; suffixes flip to verb-first form (e.g. <code>site-title-get<\/code> \u2192 <code>get-site-title<\/code>, <code>theme-activate<\/code> \u2192 <code>activate-theme<\/code>). External callers (custom code, saved MCP client configs, ACL entries created outside the plugin&#039;s UI, scripts calling <code>\/wp-json\/wp-abilities\/v1\/abilities\/acrossai-abilities-manager\/\/run<\/code>) must update their slug references to <code>\/wp-json\/wp-abilities\/v1\/abilities\/acrossai\/\/run<\/code>. No backwards-compatibility aliases; no automatic data migration \u2014 clear pre-existing overrides + ACL rules keyed on old slugs from the admin UI and re-add them under the new names. Also new: 7 Recovery Mode abilities (detect recovery, list paused plugins\/themes, unpause, exit URL, fatal-error log filter) and <code>acrossai\/reinstall-wp-core<\/code>. 162 PHP class files renamed to match slugs (internal-only; PSR-4 autoload picks up automatically). PHP 8.1+ \/ WP 6.9+ floor unchanged.<\/p>","0.0.15":"<p>UI-only release. Replaces the Custom Abilities Bulk Actions dropdown (Publish \/ Unpublish \/ Delete) with Site Access, MCP Exposure, User Access, and Overrides operations that match the per-row edit drawer. Row-level checkbox now works on every ability regardless of Source. Reuses existing REST endpoints; no new database tables, no new endpoints, no PHP changes, no dependency changes, no permission changes. Also fixes a bug that stored composer User Access rule keys with the ability slug&#039;s <code>\/<\/code> character stripped when applied via the (new) bulk path. Safe upgrade.<\/p>","0.0.14":"<p>wp.org assets only. Refreshes the banner artwork and renames both banner files from <code>banner{width}x{height}.png<\/code> to the WP.org-canonical <code>banner-{width}x{height}.png<\/code> (the 0.0.13 filenames were not being auto-detected by the plugin directory). No plugin code touched; no REST, DB, or capability changes. Safe upgrade.<\/p>","0.0.13":"<p>Docs + wp.org assets only. Adds <code>specs\/054-ability-gap-audit\/<\/code> (a reference audit of abilities that external AI-tool inventories expect but the plugin does not yet expose) and commits the previously-untracked <code>.wordpress-org<\/code> banner (1544\u00d7500 + 772\u00d7250) and a sixth screenshot covering the Settings page. No functional changes; no REST, DB, or capability changes; no code touched under <code>includes\/<\/code> or <code>src\/<\/code>. Safe upgrade.\nAdds 31 new abilities across 10 domains (187 \u2192 218). Two new categories join the Ability Library: Admin Menu (5 abilities) and Content Search (11 abilities). Introduces two option-backed data stores: a lifecycle event log for plugin\/theme activate\/deactivate\/update timestamps, and an internal-link suggestion queue capped at 500 entries. Zero new REST endpoints, zero new capability requirements beyond the operation-specific caps already enforced by WP core (moderate_comments, upload_files, edit_others_posts). Zero external HTTP; zero new database tables. No breaking changes to existing abilities. Safe upgrade.<\/p>","0.0.12":"<p>Adds a third ability to the Core tab \u2014 <code>wp-core-rollback<\/code> \u2014 that rolls back WordPress core to an earlier version via WP core&#039;s <code>Core_Upgrader::upgrade()<\/code>, the same class the dashboard uses for forward updates. Requires both <code>manage_options<\/code> and <code>update_core<\/code>; honours <code>DISALLOW_FILE_MODS<\/code>; refuses when the target version isn&#039;t strictly older than the currently-installed version. Introduces the plugin&#039;s first outbound HTTP request (to <code>api.wordpress.org\/core\/version-check\/1.7\/<\/code>), rate-bounded to at most one request per day per locale per site via a site-transient cache. No breaking changes; no database, REST, or capability changes to existing abilities. Safe upgrade.<\/p>","0.0.11":"<p>Adds two WordPress-core-scoped abilities under a new &quot;Core&quot; tab in the Ability Library \u2014 <code>wp-core-update-check<\/code> (report availability) and <code>wp-core-update<\/code> (apply via <code>Core_Upgrader<\/code>). The update ability requires both <code>manage_options<\/code> and <code>update_core<\/code>; honours <code>DISALLOW_FILE_MODS<\/code>; multisite-guarded. Also changes backup filenames from <code>backup-{type}-{slug}-{random}.zip<\/code> to <code>{slug}-{unix-timestamp}-{ms}.zip<\/code> \u2014 human-readable and time-sortable, but predictable (directory listing remains disabled on the backups dir). Existing backups continue to work; the filename change only affects new backups. No breaking changes; no database, REST, or capability changes to existing abilities. Safe upgrade.<\/p>","0.0.10":"<p>Bugfix release. <code>Create_Zip_Backup<\/code> with <code>include_hidden=false<\/code> was silently descending into hidden directories and archiving their contents in 0.0.9 (only the top-level <code>.git\/<\/code> etc. entry was skipped, not the files beneath it). Fixed to check every segment of each entry&#039;s relative path. Regenerate any <code>include_hidden=false<\/code> archives created on 0.0.9 if their source tree contained hidden directories. No breaking changes; no database, REST, or capability changes. Safe upgrade.<\/p>","0.0.9":"<p>Adds eight new abilities: six under FileManager for zip-based backup \/ restore workflows (<code>zip-create<\/code>, <code>zip-upload<\/code>, <code>zip-extract<\/code>, <code>zip-download<\/code>, <code>zip-list<\/code>, <code>zip-delete<\/code>) plus <code>plugin-update<\/code> and <code>theme-update<\/code> that finally let AI clients apply pending WordPress core updates through the Abilities API. All new abilities enforce <code>manage_options<\/code>; mutating abilities additionally honour <code>DISALLOW_FILE_MODS<\/code>. Zip extraction rejects zip-slip archives (any entry containing <code>..<\/code>, an absolute path, a backslash, or a null byte). Zip uploads are validated for the <code>PK<\/code> magic signature before finalization. A new <code>wp-content\/uploads\/acrossai-backups\/<\/code> directory is created on first use, hardened with an <code>.htaccess<\/code> that blocks PHP execution but permits <code>.zip<\/code> downloads (required so the URLs returned by <code>zip-create<\/code> remain reachable). No breaking changes to existing abilities, REST endpoints, capability requirements, or database schema. Safe upgrade.<\/p>","0.0.8":"<p>IMPORTANT: this release <strong>removes the Freemius integration entirely<\/strong> \u2014 the plugin no longer sends any data to Freemius and no longer offers a Connect \/ Login \/ Buy affordance on the Add-ons page. If you previously connected a Freemius account tied to this plugin, that connection is now inert; stale <code>fs_*<\/code> or <code>freemius_*<\/code> rows in <code>wp_options<\/code> are safe to delete manually. Also: the Add-ons page now shows only free WordPress.org companion plugins (and no longer lists this plugin itself); the Library page compacts its title + bulk-action buttons onto one horizontal row; and <code>acrossai-co\/main-menu<\/code> bumps <code>0.0.14 \u2192 0.0.23<\/code>. No breaking changes to REST endpoints, capability requirements, or database schema. Safe upgrade.<\/p>","0.0.7":"<p>Adds Library page bulk Enable All \/ Disable All buttons scoped to the active tab, URL-synced tabs (<code>?tab=<\/code>) for deep-linkable views, and a readonly ability preview on disabled cards. No breaking changes; no database schema changes; no new REST endpoints; no new capability requirements. <code>mode<\/code> and per-slug selections are preserved through disable \/ enable cycles. Safe upgrade.<\/p>","0.0.6":"<p>IMPORTANT: this release absorbs the companion <code>acrossai-core-abilities<\/code> plugin \u2014 deactivate and uninstall that plugin after upgrading to avoid duplicate ability registrations. BREAKING for downstream integrators: 17 category slugs rebranded <code>acrossai-core-abilities-<\/code> \u2192 <code>acrossai-abilities-manager-<\/code> and 176 ability slugs <code>acrossai-core-abilities\/<\/code> \u2192 <code>acrossai\/<\/code>; update any MCP\/REST\/WP-CLI callers that referenced the legacy slugs. Ability payload shapes and permission callbacks unchanged. Also promotes Themes \/ Blocks \/ Plugins \/ Users \/ Database \/ Cron \/ Cache \/ File Manager to their own Library page tabs, bumps <code>acrossai-co\/main-menu<\/code> to <code>0.0.14<\/code>, and rotates Freemius credentials.<\/p>","0.0.5":"<p>Dependency-only release: refreshes the bundled <code>acrossai-co\/main-menu<\/code> package to <code>0.0.11<\/code>. No functional changes to this plugin. Safe upgrade.<\/p>","0.0.4":"<p>IMPORTANT for add-on developers: Library display fields <code>sub_group<\/code>, <code>sub_group_label<\/code>, and <code>tab_group<\/code> must now be nested under <code>$args[&amp;#039;meta&amp;#039;][&amp;#039;acrossai&amp;#039;]<\/code> when calling <code>wp_register_ability()<\/code>. The old top-level shape is silently dropped \u2014 cards will render without their sub-group heading or custom tab placement until you migrate. End users and site administrators are not affected; no data migration, no DB or REST changes. Also swaps the WordPress.org plugin icon to an SVG and drops the directory banners.<\/p>","0.0.3":"<p>Fixes the 0.0.2 activation error on WordPress.org installs \u2014 the release ZIP now includes the Composer autoloader. No functional or user-facing changes vs 0.0.2. If you hit the &quot;Composer autoloader is missing&quot; error on 0.0.2, delete the plugin folder and reinstall 0.0.3.<\/p>","0.0.2":"<p>IMPORTANT: (1) This release does NOT migrate Access Control rules from previous versions. If you had configured any Access Control rules on abilities, audit and reconfigure them after upgrading. Pre-existing rules remain in the database (in the orphaned <code>{prefix}wpb_access_control<\/code> table) but are no longer applied. (2) Ability execution logging has been removed \u2014 the Logs admin page is gone; ability-execution denials are no longer recorded by this plugin. Install a compatible logging plugin if you need this signal.<\/p>","0.0.1":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon.svg":{"filename":"icon.svg","revision":3595583,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3614045,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3614045,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.0.1","0.0.10","0.0.11","0.0.12","0.0.13","0.0.14","0.0.15","0.0.17","0.0.18","0.0.19","0.0.2","0.0.20","0.0.21","0.0.22","0.0.23","0.0.24","0.0.25","0.0.26","0.0.27","0.0.3","0.0.4","0.0.5","0.0.6","0.0.7","0.0.8","0.0.9"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3614043,"resolution":"1","location":"assets","locale":"","width":3268,"height":1874},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3614043,"resolution":"2","location":"assets","locale":"","width":3268,"height":1874},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3614043,"resolution":"3","location":"assets","locale":"","width":3268,"height":1874},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3614043,"resolution":"4","location":"assets","locale":"","width":3268,"height":1874},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3614043,"resolution":"5","location":"assets","locale":"","width":3268,"height":1874},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3614043,"resolution":"6","location":"assets","locale":"","width":3268,"height":1874}},"screenshots":{"1":"The Abilities Manager admin page \u2014 searchable, sortable ability table.","2":"The edit drawer \u2014 tri-state override controls for each ability field.","3":"Bulk actions toolbar for allow\/disallow\/reset across multiple abilities.","4":"The Ability Library page \u2014 enable\/disable add-on ability groups.","5":"The Add-ons page \u2014 browse free companion plugins.","6":"Settings \u2014 Display (abilities-per-page) and Upload Media Abilities (allowed-MIME list + Add file types)."}},"plugin_section":[],"plugin_tags":[251511,268952,1912,2353,174442],"plugin_category":[],"plugin_contributors":[140910],"plugin_business_model":[],"class_list":["post-311005","plugin","type-plugin","status-publish","hentry","plugin_tags-abilities","plugin_tags-ability-management","plugin_tags-access-control","plugin_tags-ai","plugin_tags-site-management","plugin_contributors-raftaar1191","plugin_committers-raftaar1191"],"banners":{"banner":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/banner-772x250.png?rev=3614045","banner_2x":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/banner-1544x500.png?rev=3614045","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/icon.svg?rev=3595583","icon":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/icon.svg?rev=3595583","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/screenshot-1.png?rev=3614043","caption":"The Abilities Manager admin page \u2014 searchable, sortable ability table."},{"src":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/screenshot-2.png?rev=3614043","caption":"The edit drawer \u2014 tri-state override controls for each ability field."},{"src":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/screenshot-3.png?rev=3614043","caption":"Bulk actions toolbar for allow\/disallow\/reset across multiple abilities."},{"src":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/screenshot-4.png?rev=3614043","caption":"The Ability Library page \u2014 enable\/disable add-on ability groups."},{"src":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/screenshot-5.png?rev=3614043","caption":"The Add-ons page \u2014 browse free companion plugins."},{"src":"https:\/\/ps.w.org\/acrossai-abilities-manager\/assets\/screenshot-6.png?rev=3614043","caption":"Settings \u2014 Display (abilities-per-page) and Upload Media Abilities (allowed-MIME list + Add file types)."}],"raw_content":"<!--section=description-->\n<p>AcrossAI Abilities Manager gives site administrators full visibility and control over every ability registered via the WordPress Abilities API (<code>wp_get_ability()<\/code>).<\/p>\n\n<p><strong>Features:<\/strong><\/p>\n\n<ul>\n<li><strong>Browse all abilities<\/strong> \u2014 a searchable, sortable, paginated table listing every registered ability with slug, provider, source, and current status.<\/li>\n<li><strong>Toggle allow\/disallow<\/strong> \u2014 enable or disable any ability site-wide with a single click. Changes are saved instantly without a page reload.<\/li>\n<li><strong>Edit ability metadata<\/strong> \u2014 override <code>readonly<\/code>, <code>destructive<\/code>, <code>idempotent<\/code>, <code>show_in_rest<\/code>, <code>show_in_mcp<\/code>, <code>mcp_type<\/code>, and <code>mcp_servers<\/code> fields per ability using a tri-state system (Yes \/ No \/ Inherit from registry).<\/li>\n<li><strong>Reset overrides<\/strong> \u2014 restore any ability back to its registry defaults with one click.<\/li>\n<li><strong>Bulk actions<\/strong> \u2014 allow, disallow, or reset up to 50 abilities at once.<\/li>\n<li><strong>Ability Library<\/strong> \u2014 enable or disable add-on ability groups from a dedicated Library page, with All\/Specific mode controls per group.<\/li>\n<li><strong>Add-ons page<\/strong> \u2014 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 \u2192 Add New \u2192 Upload Plugin.<\/li>\n<li><strong>MCP server list<\/strong> \u2014 view all registered MCP servers when the MCP Adapter plugin is active.<\/li>\n<\/ul>\n\n<p>All overrides are stored in a dedicated database table. The WordPress ability registry is never modified \u2014 only the fields that differ from registry defaults are persisted.<\/p>\n\n<p><strong>Security:<\/strong><\/p>\n\n<ul>\n<li>All endpoints require <code>manage_options<\/code> capability.<\/li>\n<li>All state-changing requests are protected by WordPress nonce verification.<\/li>\n<li>All input is sanitized; all output is escaped.<\/li>\n<\/ul>\n\n<p><strong>Third-party integrations (optional):<\/strong><\/p>\n\n<ul>\n<li><strong>MCP Adapter plugin<\/strong> \u2014 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.<\/li>\n<\/ul>\n\n<p>This plugin's own code makes no external HTTP requests. One admin-only surface can contact an external service on your behalf: the AcrossAI \u2192 Add-ons page installs WordPress.org-hosted companion plugins directly through WordPress core's own plugin installer (<code>api.wordpress.org<\/code> + <code>downloads.wordpress.org<\/code>). Add-ons registered with any other source (e.g. GitHub, Freemius) are shown as external \"Get add-on \u2197\" links that open the vendor's site in a new browser tab \u2014 the plugin does not download or install them itself. The AcrossAI \u2192 Consultations submenu renders a static call-to-action button that opens <code>calendly.com<\/code> in a new browser tab only after the administrator clicks it \u2014 no third-party asset is loaded inside wp-admin. Full disclosure \u2014 including what data is transmitted to each service and links to their terms + privacy policies \u2014 is in the <strong>External Services<\/strong> section below.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>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.<\/p>\n\n<p><strong>1. Calendly external link (<code>calendly.com<\/code>)<\/strong><\/p>\n\n<p><em>What it is:<\/em> Calendly is a third-party scheduling service. The AcrossAI \u2192 Consultations submenu displays a static call-to-action button that links out to a Calendly booking page for AcrossAI consultations (\"Using AI in WordPress\").<\/p>\n\n<p><em>When it is contacted:<\/em> Never on page render. The Consultations submenu at <code>\/wp-admin\/admin.php?page=acrossai-consultations<\/code> is a self-contained wp-admin page \u2014 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 <code>https:\/\/calendly.com\/acrossai\/using-ai-in-wordpress<\/code> in a new tab (<code>target=\"_blank\" rel=\"noopener noreferrer\"<\/code>). This is identical to clicking any external hyperlink from an admin page.<\/p>\n\n<p><em>What is loaded on the Consultations page:<\/em> 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 <code>fonts.googleapis.com<\/code>) \u2014 permitted under the \"third-party CDNs beyond fonts\" carve-out in the WordPress plugin guidelines.<\/p>\n\n<p><em>What data is transmitted to Calendly:<\/em> 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.<\/p>\n\n<p><em>Terms of service:<\/em> https:\/\/calendly.com\/pages\/terms\n<em>Privacy policy:<\/em> https:\/\/calendly.com\/pages\/privacy<\/p>\n\n<p><strong>2. WordPress.org plugin directory (<code>api.wordpress.org<\/code> and <code>downloads.wordpress.org<\/code>)<\/strong><\/p>\n\n<p><em>What it is:<\/em> The Add-ons page (<code>\/wp-admin\/admin.php?page=acrossai-addons<\/code>) uses the WordPress.org plugin directory to install free companion plugins directly from wp-admin.<\/p>\n\n<p><em>When it is contacted:<\/em> Only when an authenticated administrator (<code>install_plugins<\/code> capability) clicks the \"Install\" button on a card whose <code>source<\/code> is <code>wordpress.org<\/code>. Contact happens through WordPress core's own <code>plugins_api()<\/code> and <code>Plugin_Upgrader<\/code> \u2014 this plugin does not issue direct HTTP requests. Add-ons registered with any other source (e.g. <code>github<\/code>, <code>freemius<\/code>) are rendered as external \"Get add-on \u2197\" 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.<\/p>\n\n<p><em>What data is transmitted:<\/em> The WordPress core plugin API request payload (site URL, WP version, PHP version, locale) as per WordPress core's standard update check protocol.<\/p>\n\n<p><em>Terms of service:<\/em> https:\/\/wordpress.org\/about\/terms\/\n<em>Privacy policy:<\/em> https:\/\/wordpress.org\/about\/privacy\/<\/p>\n\n<p><strong>3. WordPress.org core version-check API (<code>api.wordpress.org\/core\/version-check\/1.7\/<\/code>)<\/strong><\/p>\n\n<p>Called only when an administrator invokes the <code>acrossai\/rollback-wp-core<\/code> 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 \u2014 no data beyond the standard WordPress core version-check request payload is transmitted. Same wp.org terms + privacy policy as service #2 above.<\/p>\n\n<h3>Privacy Policy<\/h3>\n\n<p>This plugin does not itself collect, store, or transmit any user data to any third party.<\/p>\n\n<p>Several admin-only actions can cause external services to receive data \u2014 all are described in the External Services section above and are triggered only by an authenticated administrator:<\/p>\n\n<ul>\n<li>The AcrossAI \u2192 Consultations admin page displays a static call-to-action button. Merely loading the Consultations page sends no data to Calendly \u2014 no Calendly script, iframe, or asset is loaded inside wp-admin. If the administrator clicks the CTA button, their browser opens <code>calendly.com\/acrossai\/using-ai-in-wordpress<\/code> 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.<\/li>\n<li>Installing a WordPress.org-hosted add-on from the AcrossAI \u2192 Add-ons page contacts the WordPress.org plugin directory via WordPress core's own <code>plugins_api()<\/code> and <code>Plugin_Upgrader<\/code> (<code>api.wordpress.org<\/code> + <code>downloads.wordpress.org<\/code>). Add-ons distributed elsewhere (e.g. GitHub, Freemius) are rendered as external \"Get add-on \u2197\" links that open the vendor's site in a new browser tab \u2014 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.<\/li>\n<li>Invoking the <code>acrossai\/rollback-wp-core<\/code> ability contacts the WordPress.org core version-check API (a WordPress-core-hosted service) via the standard WordPress update API.<\/li>\n<\/ul>\n\n<p>No data is sent to any external server without an explicit administrator action.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>acrossai-abilities-manager<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> menu in WordPress.<\/li>\n<li>Navigate to <strong>AcrossAI Abilities Manager<\/strong> in the WordPress admin menu.<\/li>\n<\/ol>\n\n<p><strong>Add-ons:<\/strong><\/p>\n\n<ol>\n<li>Go to <strong>AcrossAI \u2192 Add-ons<\/strong> to browse available companion plugins.<\/li>\n<li>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.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20support%20multisite%3F\"><h3>Does this plugin support Multisite?<\/h3><\/dt>\n<dd><p>No. This plugin has not been tested on WordPress Multisite installations.<\/p><\/dd>\n<dt id=\"does%20this%20plugin%20modify%20the%20wordpress%20ability%20registry%3F\"><h3>Does this plugin modify the WordPress ability registry?<\/h3><\/dt>\n<dd><p>No. The plugin stores only overrides \u2014 fields that differ from the registry defaults. The ability registry itself (<code>wp_get_ability()<\/code>) is never modified.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20i%20reset%20an%20override%3F\"><h3>What happens when I reset an override?<\/h3><\/dt>\n<dd><p>The override row is deleted from the database. The ability will inherit its values from the registry again.<\/p><\/dd>\n<dt id=\"what%20is%20the%20ability%20library%3F\"><h3>What is the Ability Library?<\/h3><\/dt>\n<dd><p>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.<\/p><\/dd>\n<dt id=\"what%20is%20the%20mcp%20adapter%20integration%3F\"><h3>What is the MCP Adapter integration?<\/h3><\/dt>\n<dd><p>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 \u2014 the plugin works without the MCP Adapter.<\/p><\/dd>\n<dt id=\"does%20this%20plugin%20make%20external%20http%20requests%3F\"><h3>Does this plugin make external HTTP requests?<\/h3><\/dt>\n<dd><p>The plugin's own code makes no external HTTP requests. Two admin-only surfaces trigger external connections on behalf of an authenticated administrator:<\/p>\n\n<ul>\n<li><strong>AcrossAI \u2192 Consultations<\/strong> submenu \u2014 renders a static call-to-action button that links to <code>https:\/\/calendly.com\/acrossai\/using-ai-in-wordpress<\/code> 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 \u2014 at which point their browser navigates directly to <code>calendly.com<\/code>, exactly as with any external hyperlink.<\/li>\n<li><strong>AcrossAI \u2192 Add-ons<\/strong> submenu \u2014 installs WordPress.org-hosted companion plugins in place through WordPress core's <code>plugins_api()<\/code> + <code>Plugin_Upgrader<\/code> (contacts <code>api.wordpress.org<\/code> + <code>downloads.wordpress.org<\/code>). Add-ons registered with any other source (e.g. GitHub, Freemius) render as external \"Get add-on \u2197\" links that open the vendor's site in a new browser tab \u2014 the plugin does not download or install those add-ons itself. Users install off-directory add-ons via WP admin's standard <strong>Plugins \u2192 Add New \u2192 Upload Plugin<\/strong> flow (or via the vendor's own installer once the paid plugin is activated).<\/li>\n<\/ul>\n\n<p>Full disclosure \u2014 including what data is transmitted, and links to each service's terms + privacy policy \u2014 is in the <strong>External Services<\/strong> section of this readme.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.0.27 - 2026-08-14<\/h4>\n\n<p><strong>Patch release \u2014 UI polish + admin-surface rename following the 0.0.26 Feature 067 rollup.<\/strong> No new abilities; both entries below are UX-affecting changes to the admin surface. Plugin version bumped 0.0.26 \u2192 0.0.27.<\/p>\n\n<ul>\n<li><strong>Rename \u2014 \"Ability Library\" admin page is now \"Ability Integrations\".<\/strong> The submenu label (\"Library\" \u2192 \"Integrations\"), page title (\"Ability Library\" \u2192 \"Ability Integrations\"), main heading, and URL slug (<code>page=acrossai-abilities-library<\/code> \u2192 <code>page=acrossai-abilities-integrations<\/code>) all updated. Bookmarks \/ external links to the old slug will 404 in wp-admin \u2014 update saved links to the new URL. Internal class names, hook names, REST endpoint namespace (<code>\/wp-json\/acrossai-abilities-library\/v1\/<\/code>), and the DOM mount id are unchanged (deliberately scoped rename \u2014 extending to the REST namespace would break external MCP callers).<\/li>\n<li><strong>UI fix \u2014 Elementor abilities now render under their own \"Elementor\" tab in the Ability Integrations screen, not \"Core\".<\/strong> Every Elementor ability (all 88 under <code>acrossai\/elementor-*<\/code>) had its meta <code>tab_group<\/code> set to <code>'core'<\/code>, causing the group to appear in the Core tab with only a sub-heading identifying it as Elementor. Flipped every declaration to <code>tab_group =&gt; 'elementor'<\/code> (63 files including <code>Base_Audit_Ability<\/code>, which drives the 25 audit subclasses via inheritance). The Ability Integrations UI auto-derives tab names from distinct <code>tab_group<\/code> values, so a new \"Elementor\" tab appears without any frontend\/asset rebuild.<\/li>\n<\/ul>\n\n<h4>0.0.26 - 2026-08-14<\/h4>\n\n<p><strong>Release rollup \u2014 89 abilities total: 87 unreleased Elementor abilities (Feature 067 completion) + 2 native site maintenance-mode abilities.<\/strong> Plugin version bumped 0.0.25 \u2192 0.0.26. Elementor abilities gate on <code>class_exists('\\Elementor\\Plugin')<\/code> (with 8 additionally gated on Elementor Pro); site maintenance-mode toggle has no plugin dependency.<\/p>\n\n<ul>\n<li><p><strong>Native site maintenance-mode toggle (2 abilities):<\/strong><\/p>\n\n<ul>\n<li><code>acrossai\/set-site-maintenance-mode<\/code> \u2014 activate WordPress core maintenance mode by writing the <code>ABSPATH\/.maintenance<\/code> 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 <code>duration_minutes<\/code> (default 60, hard-cap 1440). Requires <code>confirm=true<\/code> \u2014 blocks wp-admin as well as the frontend.<\/li>\n<li><code>acrossai\/unset-site-maintenance-mode<\/code> \u2014 deactivate: delete the marker, clear the refresh cron, drop the expiry option. Idempotent \u2014 safe to call when maintenance mode is already inactive. Reports <code>was_active<\/code> in the response.<\/li>\n<li>Both live under the existing <code>acrossai-abilities-manager-site-health<\/code> category alongside <code>acrossai\/get-maintenance-mode-status<\/code> (Feature 063 read). No Elementor \/ plugin dependency \u2014 works on every WP install.<\/li>\n<\/ul><\/li>\n<li><p><strong>Feature 067 COMPLETE \u2014 87 additional Elementor abilities ship in this release.<\/strong> Combined with the 2 foundation abilities from 0.0.25, the full 88 planned abilities are now available under the <code>acrossai\/elementor-*<\/code> namespace. Design-audit ability logic is skeletal (<code>Base_Audit_Ability<\/code> skeleton returning empty findings) \u2014 real audit heuristics to be filled in follow-up work.<\/p><\/li>\n<\/ul>\n\n<p><strong>Batch 10 \u2014 full-document replacement (closes the parity gap):<\/strong>\n  * <code>acrossai\/elementor-update-data<\/code> \u2014 overwrite the entire <code>_elementor_data<\/code> tree for a post with a caller-supplied element array; optional <code>page_settings<\/code> merge; <code>force_replace=true<\/code> required when the new payload is materially smaller than the existing document. Returns <code>element_count<\/code> + cache scope report.<\/p>\n\n<p><strong>Batch 9 \u2014 29 design-audit abilities (this commit):<\/strong><\/p>\n\n<p>Aggregators + scorers (4):\n  * <code>acrossai\/elementor-evaluate-design<\/code> \u2014 aggregate report from every registered design audit (score + findings + recommendations).\n  * <code>acrossai\/elementor-suggest-design-fixes<\/code> \u2014 turn aggregated findings into concrete fix recommendations.\n  * <code>acrossai\/elementor-score-distinctiveness<\/code> \u2014 neutral distinctiveness score for structural repetition.\n  * <code>acrossai\/elementor-extract-design-tokens<\/code> \u2014 extract recurring colors \/ typography \/ spacing \/ dimensional tokens.<\/p>\n\n<p>Individual audits (14):\n  * Column: <code>audit-column-alignment-rhythm<\/code>, <code>audit-column-balance<\/code>, <code>audit-column-dominance<\/code>, <code>audit-column-necessity<\/code>, <code>audit-column-patterns<\/code>\n  * Composition &amp; emphasis: <code>audit-composition-rhythm<\/code>, <code>audit-emphasis-drift<\/code>, <code>audit-section-rivalry<\/code>, <code>audit-separator-discipline<\/code>, <code>audit-surface-overuse<\/code>\n  * Layout &amp; repetition: <code>audit-generic-component-repetition<\/code>, <code>audit-generic-layout-patterns<\/code>, <code>audit-layout-mechanism-fit<\/code>, <code>audit-native-widget-opportunities<\/code><\/p>\n\n<p>Subtree operations \u2014 destructive (7):\n  * <code>apply-text-hierarchy<\/code>, <code>enforce-boundary-coherence<\/code>, <code>fix-visible-gap-rhythm<\/code>, <code>normalize-responsive-values<\/code>, <code>normalize-section-spacing-rhythm<\/code>, <code>reset-negative-margins-subtree<\/code>, <code>zero-container-padding-subtree<\/code><\/p>\n\n<p>Copy \/ sync \/ convert helpers \u2014 destructive (4):\n  * <code>copy-lane-settings<\/code>, <code>copy-row-balance<\/code>, <code>image-widget-to-background-container<\/code>, <code>sync-component-variant<\/code><\/p>\n\n<p>New utility class <code>includes\/Abilities\/Elementor\/Base_Audit_Ability.php<\/code> provides the shared skeleton for 27 of the 29 audit abilities \u2014 subclasses supply <code>audit_slug<\/code>, <code>audit_label<\/code>, <code>audit_description<\/code>, and <code>analyze()<\/code>. <code>Evaluate_Design<\/code> and <code>Suggest_Design_Fixes<\/code> are self-contained aggregators.<\/p>\n\n<p><strong>Batch 8 \u2014 8 Elementor Pro-gated abilities:<\/strong>\n  * <code>acrossai\/elementor-list-custom-code<\/code> \u2014 list Custom Code snippets from <code>elementor_snippet<\/code> CPT; optional location filter.\n  * <code>acrossai\/elementor-get-custom-code<\/code> \u2014 read one snippet including its code body.\n  * <code>acrossai\/elementor-create-custom-code<\/code> \u2014 create snippet with title, code, location (head \/ body_start \/ body_end \/ footer), priority, status.\n  * <code>acrossai\/elementor-update-custom-code<\/code> \u2014 update snippet fields.\n  * <code>acrossai\/elementor-delete-custom-code<\/code> \u2014 trash (default) or permanently delete with <code>force=true<\/code>.\n  * <code>acrossai\/elementor-list-form-submissions<\/code> \u2014 list Form widget submissions from the <code>e_submissions<\/code> table; optional <code>form_id<\/code> filter + <code>include_values<\/code> flag. Graceful degradation when the Pro submissions table is missing.\n  * <code>acrossai\/elementor-get-form-submission<\/code> \u2014 read one submission by ID; optional field values.\n  * <code>acrossai\/elementor-delete-form-submission<\/code> \u2014 permanently delete submission + its <code>e_submissions_values<\/code> rows; requires <code>confirm=true<\/code>.<\/p>\n\n<p>All 8 Pro abilities gated on <strong>both<\/strong> <code>class_exists( '\\Elementor\\Plugin' )<\/code> <strong>and<\/strong> <code>class_exists( '\\ElementorPro\\Plugin' ) || defined( 'ELEMENTOR_PRO_VERSION' )<\/code> \u2014 silently absent on sites without Elementor Pro. Runtime deactivation returns <code>error_code: elementor_pro_missing<\/code>.<\/p>\n\n<p><strong>Batch 7 \u2014 7 kits &amp; site-settings abilities:<\/strong>\n  * <code>acrossai\/elementor-list-kits<\/code> \u2014 list all Elementor kits; marks active kit.\n  * <code>acrossai\/elementor-get-kit-settings<\/code> \u2014 read kit settings (defaults to active kit).\n  * <code>acrossai\/elementor-update-kit-settings<\/code> \u2014 merge new settings; <code>force_replace<\/code> for full overwrite; site-wide cache invalidation.\n  * <code>acrossai\/elementor-set-active-kit<\/code> \u2014 switch site-wide active kit; invalidates cache.\n  * <code>acrossai\/elementor-list-global-widgets<\/code> \u2014 list global (reusable) widgets from elementor_library CPT.\n  * <code>acrossai\/elementor-list-experiments<\/code> \u2014 list feature flags with current + default state.\n  * <code>acrossai\/elementor-update-experiment<\/code> \u2014 toggle experiment state (active | inactive | default).<\/p>\n\n<p><strong>Batch 6 \u2014 11 template abilities:<\/strong>\n  * <code>acrossai\/elementor-list-templates<\/code> \u2014 list saved templates with filters on <code>template_type<\/code> + <code>status<\/code> + pagination.\n  * <code>acrossai\/elementor-get-template<\/code> \u2014 return one template's metadata + conditions + optional <code>_elementor_data<\/code>.\n  * <code>acrossai\/elementor-create-template<\/code> \u2014 create a new template of type page \/ section \/ popup \/ header \/ footer \/ single \/ archive; sets taxonomy term + Elementor meta.\n  * <code>acrossai\/elementor-update-template<\/code> \u2014 update title \/ page_settings \/ full data with <code>force_replace<\/code> guard.\n  * <code>acrossai\/elementor-delete-template<\/code> \u2014 trash (default) or permanently delete with <code>force=true<\/code>.\n  * <code>acrossai\/elementor-restore-template<\/code> \u2014 restore a trashed template.\n  * <code>acrossai\/elementor-duplicate-template<\/code> \u2014 clone template preserving type + conditions + sub_type; regenerates element IDs.\n  * <code>acrossai\/elementor-empty-trash<\/code> \u2014 permanently delete every trashed template; requires <code>confirm=true<\/code>.\n  * <code>acrossai\/elementor-export-template<\/code> \u2014 export template as JSON-encodable object (title, template_type, sub_type, page_settings, content, conditions).\n  * <code>acrossai\/elementor-import-template<\/code> \u2014 import from JSON export; regenerates element IDs; optional <code>overwrite_id<\/code> to replace an existing template.\n  * <code>acrossai\/elementor-find-template-for-pattern<\/code> \u2014 rank saved templates by keyword match (title + tax term + widget-types in content); returns top N with scores.<\/p>\n\n<p><strong>Batch 5 \u2014 11 site-management abilities:<\/strong>\n  * <code>acrossai\/elementor-clear-cache<\/code> \u2014 clear Elementor cache at post \/ site \/ all scope; optional <code>regenerate_css=true<\/code> for a specific post.\n  * <code>acrossai\/elementor-replace-urls<\/code> \u2014 bulk find\/replace URLs across every Elementor document on the site with <code>dry_run=true<\/code> default preview.\n  * <code>acrossai\/elementor-get-maintenance-mode<\/code> \u2014 read current maintenance mode settings (mode, template, exclude rules).\n  * <code>acrossai\/elementor-update-maintenance-mode<\/code> \u2014 enable\/disable maintenance mode with mode selection (maintenance | coming_soon).\n  * <code>acrossai\/elementor-get-theme-builder-conditions<\/code> \u2014 read display conditions attached to an Elementor template.\n  * <code>acrossai\/elementor-update-theme-builder-conditions<\/code> \u2014 replace display conditions; pass empty array to clear. Invalidates Elementor's condition cache.\n  * <code>acrossai\/elementor-get-official-widget-catalog<\/code> \u2014 canonical widget catalog (Basic \/ Pro \/ Theme \/ WooCommerce) with 12-hour transient.\n  * <code>acrossai\/elementor-get-official-pattern-guidance<\/code> \u2014 pattern &amp; layout guidance (widgets \/ patterns \/ layouts topics) grounded in Elementor documentation.\n  * <code>acrossai\/elementor-get-theme-context<\/code> \u2014 active theme + Elementor version + active kit + viewport settings snapshot.\n  * <code>acrossai\/elementor-get-style-guide<\/code> \u2014 style-guide summary from active kit (colors, typography, buttons, forms, layout, custom CSS).\n  * <code>acrossai\/elementor-evaluate-render-context<\/code> \u2014 inspect frontend template + canvas type + edit-mode flag for a post.<\/p>\n\n<p><strong>Batch 4 \u2014 9 page-composition abilities:<\/strong>\n  * <code>acrossai\/elementor-create-page<\/code> \u2014 insert a new post\/page pre-configured for Elementor (sets <code>_elementor_edit_mode<\/code>, <code>_elementor_template_type<\/code>, <code>_elementor_version<\/code>; seeds empty <code>_elementor_data<\/code>). Returns edit URL.\n  * <code>acrossai\/elementor-update-page-settings<\/code> \u2014 merge new page-level settings into <code>_elementor_page_settings<\/code>. <code>force_replace<\/code> guard on materially-smaller payloads.\n  * <code>acrossai\/elementor-patch-data<\/code> \u2014 find\/replace text within the raw Elementor JSON string; updates every widget containing the match in one pass.\n  * <code>acrossai\/elementor-clone-data<\/code> \u2014 copy the full Elementor tree from one post to another with fresh element IDs throughout. Optionally include page settings. <code>force_replace<\/code> guard on populated targets.\n  * <code>acrossai\/elementor-add-heading<\/code> \u2014 widget shortcut (title, header_size h1-h6, align, title_color).\n  * <code>acrossai\/elementor-add-text-editor<\/code> \u2014 widget shortcut (editor HTML, align).\n  * <code>acrossai\/elementor-add-image<\/code> \u2014 widget shortcut (image ID or URL, size, align, caption, link).\n  * <code>acrossai\/elementor-add-button<\/code> \u2014 widget shortcut (text, link, size xs-xl, align).\n  * <code>acrossai\/elementor-add-post-tabs<\/code> \u2014 higher-order shortcut: Nested Tabs widget where each tab contains a native Posts widget (optionally filtered by taxonomy term or query args).<\/p>\n\n<p><strong>Batch 3 \u2014 6 element-lifecycle abilities (previously in this section):<\/strong>\n  * <code>acrossai\/elementor-merge-element-settings<\/code> \u2014 deep-merge new settings into an element by ID. Additive (no force_replace guard needed); reports <code>changed_keys<\/code> in the response.\n  * <code>acrossai\/elementor-delete-element<\/code> \u2014 remove an element by ID. Guarded by <code>force_delete=true<\/code> for top-level or populated (with-children) elements.\n  * <code>acrossai\/elementor-remove-element<\/code> \u2014 safer alias for <code>delete-element<\/code> with identical semantics.\n  * <code>acrossai\/elementor-move-element<\/code> \u2014 atomic move to a new parent\/position with descendant-guard preventing cycle-creating moves into own subtree.\n  * <code>acrossai\/elementor-duplicate-element<\/code> \u2014 deep-clone an element (all nested children included) with fresh IDs generated throughout the cloned subtree; inserted as the next sibling.\n  * <code>acrossai\/elementor-reorder-elements<\/code> \u2014 reorder direct children of a parent (or root); children omitted from <code>ordered_element_ids<\/code> retain their prior relative order and are appended after.<\/p>\n\n<p><strong>Batch 2 \u2014 5 abilities merged earlier:<\/strong>\n  * <code>acrossai\/elementor-get-element<\/code> \u2014 read a single element by 7-char hex ID.\n  * <code>acrossai\/elementor-find-elements<\/code> \u2014 search by <code>element_type<\/code> \/ <code>widget_type<\/code> \/ contains-text.\n  * <code>acrossai\/elementor-update-element<\/code> \u2014 replace by ID with <code>force_replace<\/code> guard.\n  * <code>acrossai\/elementor-add-container<\/code> \u2014 insert Elementor v3+ container.\n  * <code>acrossai\/elementor-add-widget<\/code> \u2014 insert any registered widget (validated via <code>Widget_Controls<\/code>).<\/p>\n\n<p><strong>Test coverage:<\/strong> 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.<\/p>\n\n<p><strong>Feature 067 ability surface complete: 88 of 88 abilities.<\/strong> 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 <code>Design_Audit_Runner<\/code>, real heuristics to be filled in follow-up work.<\/p>\n\n<h4>0.0.25<\/h4>\n\n<ul>\n<li><strong>New \u2014 Feature 067 Elementor Ability Suite (interim ship: foundation + 2 abilities).<\/strong> 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.<\/li>\n<\/ul>\n\n<p><strong>Foundation \u2014 6 utility classes + category registrar under <code>includes\/Abilities\/Utilities\/Elementor\/<\/code> and <code>includes\/Abilities\/Elementor\/<\/code>:<\/strong>\n  * <code>Category_Registrar<\/code> \u2014 registers the new <code>acrossai-abilities-manager-elementor<\/code> ability category. Self-guards on <code>class_exists( '\\Elementor\\Plugin' )<\/code> so the category is silently absent on non-Elementor sites.\n  * <code>Document_Repository<\/code> \u2014 Elementor document I\/O with mandatory <code>wp_slash()<\/code> policy on <code>_elementor_data<\/code> writes, cache invalidation (Elementor files manager + WP post cache + <code>_elementor_css<\/code> meta delete), and full tree helpers (find\/insert\/remove\/reorder\/replace by element ID, deep-clone with fresh IDs, descendant-guard).\n  * <code>Widget_Controls<\/code> \u2014 schema-safe summariser over Elementor's <code>WidgetsManager::get_widget_types()<\/code> with case-insensitive control-name filtering.\n  * <code>Template_Query<\/code> \u2014 <code>WP_Query<\/code> wrappers for the <code>elementor_library<\/code> CPT with tax filters + keyword-scoring for pattern-search abilities.\n  * <code>Guidance_Catalog<\/code> \u2014 canonical Elementor.com widget catalog (60+ Basic\/Pro\/Theme\/WooCommerce widgets seeded, 12-hour transient) + pattern &amp; layout guidance data (nav-menu vs mega-menu, container vs section, Grid vs Flexbox for symmetric columns, etc.).\n  * <code>Design_Audit_Runner<\/code> \u2014 orchestrator for the 28 design-audit abilities landing in follow-up features (register + run individual + run-all with aggregate score + findings + recommendations).<\/p>\n\n<p><strong>Bootstrap gating<\/strong> in <code>includes\/Abilities\/AcrossAI_Core_Abilities_Bootstrap.php<\/code>:\n  * Two-layer gate: outer <code>class_exists( '\\Elementor\\Plugin' )<\/code> at <code>plugins_loaded<\/code> P20 (registration-time) plus per-ability defense-in-depth check at execution time (runtime deactivation returns clean <code>error_code: elementor_missing<\/code> envelope, no fatals).\n  * Inner Pro gate: <code>class_exists( '\\ElementorPro\\Plugin' ) || defined( 'ELEMENTOR_PRO_VERSION' )<\/code> for the future Custom Code + Form Submissions abilities.\n  * Split into two private methods <code>register_elementor_free_abilities()<\/code> + <code>register_elementor_pro_abilities()<\/code> \u2014 new <code>new Elementor\\&lt;Class&gt;()<\/code> lines added as each ability class lands.<\/p>\n\n<p><strong>Two shipped abilities under <code>acrossai\/elementor-*<\/code> namespace:<\/strong>\n  * <code>acrossai\/elementor-get-widget-controls<\/code> \u2014 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.\n  * <code>acrossai\/elementor-get-data<\/code> \u2014 the read primitive. Returns the parsed Elementor document tree + page settings for a post, plus recursive element count.<\/p>\n\n<p><strong>Test coverage:<\/strong> 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.<\/p>\n\n<p><strong>Test-bootstrap additions:<\/strong> stubs for <code>wp_rand<\/code>, <code>get_transient<\/code>, <code>set_transient<\/code>, <code>delete_transient<\/code>, and <code>HOUR_IN_SECONDS<\/code> constant to support the new utilities under the unit-only bootstrap.<\/p>\n\n<p><strong>Spec artifacts<\/strong> at <code>specs\/067-elementor-abilities\/<\/code>: complete design for all 88 abilities documented in <code>spec.md<\/code> \/ <code>plan.md<\/code> \/ <code>research.md<\/code> \/ <code>data-model.md<\/code> \/ <code>contracts\/abilities.md<\/code> \/ <code>quickstart.md<\/code> \/ <code>tasks.md<\/code> \u2014 follow-up features will implement Phases 3-13 tasks against these contracts.<\/p>\n\n<h4>0.0.24<\/h4>\n\n<ul>\n<li><strong>New \u2014 6 abilities and 1 enhancement for full Gutenberg block-tree control (feature 066).<\/strong> Closes the gap between the plugin's existing block-registry surface and per-post block-tree manipulation. All abilities live under the existing <code>acrossai-abilities-manager-content<\/code> category.<\/li>\n<\/ul>\n\n<p><strong>Feature 066 \u2014 Block tree mutation &amp; nested editing (6 new abilities + 1 modified).<\/strong>\n  * <code>acrossai\/get-post-blocks<\/code> \u2014 return a post's parsed Gutenberg block tree with each block annotated with its canonical integer-array path (e.g. <code>[0, 2, 1]<\/code> = 2nd grandchild of the 3rd child of the 1st top-level block). Read-only, idempotent.\n  * <code>acrossai\/add-block<\/code> \u2014 insert a new block into a post at <code>parent_path<\/code> + <code>index<\/code>. Appends when the requested index exceeds the current sibling count.\n  * <code>acrossai\/remove-block<\/code> \u2014 remove the block at a canonical path; returns the removed payload so callers can undo\/log.\n  * <code>acrossai\/duplicate-block<\/code> \u2014 deep-clone the block at a path (including all inner blocks) and insert the clone as the next sibling.\n  * <code>acrossai\/move-block<\/code> \u2014 atomically move a block from <code>from_path<\/code> to <code>to_parent_path<\/code> + <code>to_index<\/code>. Refuses moves into the source's own subtree (would create a cycle).\n  * <code>acrossai\/insert-pattern<\/code> \u2014 resolve a saved block pattern by slug across database \/ active theme \/ installed plugins, then insert its constituent blocks at <code>parent_path<\/code> + <code>index<\/code>. Ambiguous slugs return <code>multiple_locations<\/code> so callers can disambiguate via <code>source<\/code> \/ <code>theme_type<\/code> \/ <code>plugin_slug<\/code>.\n  * <code>acrossai\/update-post-block<\/code> (modified) \u2014 now accepts an optional <code>path<\/code> input for nested editing at any depth. Existing consumers using <code>block_index<\/code> or <code>block_name<\/code> + <code>occurrence<\/code> see <strong>zero behaviour change<\/strong> \u2014 the path branch is a strict addition.\n  * All write abilities share the same guards as the existing <code>update-post-block<\/code>: <code>manage_options<\/code> + <code>edit_posts<\/code> globally, <code>edit_post<\/code> 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.\n  * Shared <code>Block_Tree<\/code> utility (<code>includes\/Abilities\/Utilities\/Block_Tree.php<\/code>) centralises tree-path primitives \u2014 walk, get-at-path, insert \/ remove \/ replace \/ move, block-name and attribute-schema validation. Extracts what was previously private inline logic in <code>Update_Post_Block::execute<\/code>.\n  * Test coverage: 82 new PHPUnit assertions across 8 test files.<\/p>\n\n<h4>0.0.23<\/h4>\n\n<ul>\n<li><strong>New \u2014 30 abilities across three feature spec drops (062, 063, 064).<\/strong> Bulk expansion of the plugin's ability surface. No breaking changes.<\/li>\n<\/ul>\n\n<p><strong>Feature 062 \u2014 Role &amp; capability CRUD + site-wide DB search-replace (8 abilities).<\/strong>\n  * <code>acrossai\/add-role-capability<\/code>, <code>acrossai\/remove-role-capability<\/code>, <code>acrossai\/create-role<\/code>, <code>acrossai\/delete-role<\/code>, <code>acrossai\/reset-role<\/code>, <code>acrossai\/add-user-capability<\/code>, <code>acrossai\/remove-user-capability<\/code> \u2014 writers for the role\/cap surface WordPress core REST does not expose. Every write is <code>destructive: true<\/code>.\n  * <code>acrossai\/search-replace<\/code> \u2014 site-wide serialized-data-safe string replacement across every WordPress-managed table. <strong><code>dry_run: true<\/code> by default<\/strong> \u2014 the ability returns a per-table \/ per-column match tally without mutating any row, and mutating writes only happen when the caller explicitly passes <code>dry_run: false<\/code>. Table allowlist mirrors <code>Update_Db_Rows.php<\/code> (validates every input table against <code>SHOW TABLES<\/code> before scanning). Skips <code>wp_posts.guid<\/code> unless the caller explicitly opts in via <code>include_guids: true<\/code> (safer default than WP-CLI). Recursive <code>maybe_unserialize<\/code> \/ <code>maybe_serialize<\/code> walk keeps serialized meta \/ options structurally valid.\n  * Guardrails: <code>remove-role-capability<\/code> refuses to strip a WP-core administrator baseline capability from the <code>administrator<\/code> role; <code>delete-role<\/code> refuses on any of the 5 built-in roles AND when the role is still held by any user; <code>reset-role<\/code> accepts only the 5 built-in role slugs; <code>remove-user-capability<\/code> refuses to strip a WP-core admin cap from the last remaining administrator.<\/p>\n\n<p><strong>Feature 063 \u2014 Site introspection reads + new Widgets category (11 abilities).<\/strong>\n  * <code>acrossai\/get-wp-version<\/code>, <code>acrossai\/get-db-prefix<\/code>, <code>acrossai\/get-wp-config-constant<\/code>, <code>acrossai\/list-theme-mods<\/code>, <code>acrossai\/list-rewrite-rules<\/code>, <code>acrossai\/list-image-sizes<\/code>, <code>acrossai\/get-comment-count<\/code>, <code>acrossai\/get-maintenance-mode-status<\/code>, <code>acrossai\/test-wp-cron<\/code> \u2014 small single-purpose reads that WordPress does not expose through a public REST endpoint. Every ability is <code>readonly: true, idempotent: true, destructive: false<\/code>.\n  * <code>acrossai\/list-widgets<\/code>, <code>acrossai\/list-sidebars<\/code> \u2014 legacy widget-system introspection under a new <strong>Widgets<\/strong> category (slug <code>acrossai-abilities-manager-widgets<\/code>).\n  * Guardrails: <code>get-wp-config-constant<\/code> hard-blocks disclosure of <code>AUTH_KEY<\/code>, <code>SECURE_AUTH_KEY<\/code>, <code>LOGGED_IN_KEY<\/code>, <code>NONCE_KEY<\/code>, <code>AUTH_SALT<\/code>, <code>SECURE_AUTH_SALT<\/code>, <code>LOGGED_IN_SALT<\/code>, <code>NONCE_SALT<\/code>, and <code>DB_PASSWORD<\/code> regardless of the <code>manage_options<\/code> gate; <code>get-maintenance-mode-status<\/code> uses WordPress core's own 10-minute staleness threshold; <code>test-wp-cron<\/code> fires a single non-blocking <code>wp_remote_get()<\/code> with a 0.01s timeout so it never hangs a REST response.<\/p>\n\n<p><strong>Feature 064 \u2014 Transient CRUD, nested option access, plugin lifecycle &amp; checksum integrity (11 abilities).<\/strong>\n  * Transient CRUD (Cache category): <code>acrossai\/get-transient<\/code>, <code>acrossai\/list-transients<\/code> (paginated, search-filterable, expiry-aware), <code>acrossai\/delete-transient<\/code>, <code>acrossai\/delete-expired-transients<\/code> \u2014 closes the previous read-nothing \/ bulk-only-delete gap.\n  * Nested option access (Options category): <code>acrossai\/get-nested-option-value<\/code> and <code>acrossai\/patch-option-value<\/code> \u2014 read or mutate one nested key inside a serialized option without round-tripping the whole blob. Guarded by <code>Update_Option::BLOCKED_OPTIONS<\/code> (extracted as a <code>public const<\/code> on <code>Update_Option<\/code> in this release so both classes share one authoritative block-list of 21 protected core options).\n  * Post-meta append (Content category): <code>acrossai\/add-post-meta<\/code> \u2014 WordPress core <code>add_post_meta()<\/code> semantics with the WP-core <code>unique<\/code> flag. Complements the existing update \/ delete post-meta writers.\n  * Plugin lifecycle (Plugins category): <code>acrossai\/search-wp-plugin-directory<\/code> (searches the WordPress.org plugin directory via <code>plugins_api()<\/code>; short description sanitised via <code>wp_kses_post()<\/code>), <code>acrossai\/uninstall-plugin<\/code> (fires the plugin's registered uninstall hook + deletes files via WP core <code>uninstall_plugin()<\/code>; refuses on active plugins and on sites with <code>DISALLOW_FILE_MODS<\/code>), <code>acrossai\/verify-plugin-checksums<\/code>.\n  * Core integrity (Core category): <code>acrossai\/verify-core-checksums<\/code> \u2014 fetches the official <code>api.wordpress.org<\/code> checksums manifest via <code>wp_remote_get()<\/code> and compares <code>md5_file()<\/code> hashes; per-file <code>status: 'ok'|'modified'|'missing'|'added'<\/code> and a summary counter.<\/p>\n\n<ul>\n<li><strong>Every one of the 30 new abilities gates on <code>current_user_can( 'manage_options' )<\/code><\/strong> using the identical permission-callback pattern already used by all 219 existing abilities: <code>static function (): bool { return current_user_can( 'manage_options' ); }<\/code>. No cap escalation via filter.<\/li>\n<li><strong>One new ability category \u2014 Widgets<\/strong> (<code>acrossai-abilities-manager-widgets<\/code>), registered via <code>includes\/Abilities\/Widgets\/Category_Registrar.php<\/code> mirroring the shape of <code>includes\/Abilities\/Menus\/<\/code>.<\/li>\n<li><strong>204 new PHPUnit test methods<\/strong> on top of the previous 191 (final suite: ~395 methods across the 8.1 \u2192 8.5 PHP CI matrix). Every new class file passes PHPStan level 8 and the plugin's PHPCS WPCS strict profile.<\/li>\n<li><strong>No breaking changes.<\/strong> No ability slug rename. No REST endpoint change. No option-shape change. No new required capability. Existing 218 abilities behave identically. The <code>Update_Option::BLOCKED_OPTIONS<\/code> extraction in Feature 064 is a pure move of an inline literal into a <code>public const<\/code>; behaviour is unchanged. Safe upgrade from 0.0.22.<\/li>\n<\/ul>\n\n<h4>0.0.22<\/h4>\n\n<ul>\n<li><strong>New \u2014 <code>acrossai\/delete-post-meta<\/code> ability under the Content category.<\/strong> Deletes a single post meta row via WordPress core <code>delete_post_meta()<\/code>. Accepts <code>post_id<\/code> + <code>key<\/code> (with the WP-core-native <code>meta_key<\/code> alias) and an optional <code>value<\/code> (with <code>meta_value<\/code> alias). When a value is supplied, only rows matching that value are removed; otherwise every row for the given key is removed. Gated by <code>manage_options<\/code>; annotated <code>destructive: true<\/code>, <code>idempotent: true<\/code>. Mirrors the shape of <code>acrossai\/update-post-meta<\/code> for consistent client ergonomics.<\/li>\n<li><strong>Fixed \u2014 <code>acrossai\/update-post-meta<\/code> no longer rejects protected meta keys (#99).<\/strong> The pre-0.0.22 <code>execute()<\/code> short-circuited with <code>success: false<\/code> whenever <code>is_protected_meta( $key, 'post' )<\/code> returned true, contradicting the class docblock (\"Works for ANY meta key\"). Now the ability writes any key the <code>manage_options<\/code> gate allows through \u2014 the capability check remains the sole access boundary. The registered <code>description<\/code> was also updated to match the new behaviour (\"Works for any meta key, including protected keys.\").<\/li>\n<li><strong>Composer dependency bump \u2014 <code>acrossai-co\/main-menu<\/code> 0.0.30 \u2192 0.0.33.<\/strong> Rolls three shared-menu library releases into one hop; <code>composer.lock<\/code> regenerated to reference <code>e17e1e8<\/code>.<\/li>\n<li><strong>No breaking changes.<\/strong> 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.<\/li>\n<\/ul>\n\n<h4>0.0.21<\/h4>\n\n<ul>\n<li><strong>Composer dependency bump \u2014 <code>wpboilerplate\/wpb-access-control<\/code> <code>^2.0.0<\/code> \u2192 <code>^3.1.0<\/code>.<\/strong> Adopts two major releases of the shared access-control library in one hop:\n\n<ul>\n<li><strong>v3.0.0 (breaking, but not for this plugin).<\/strong> The two plugin-dependent providers shipped in the library's v1.4.0 \/ v1.5.0 \u2014 <code>BuddyBossProfileTypeProvider<\/code> (<code>bb_profile_type<\/code>) and <code>MemberPressMembershipProvider<\/code> (<code>mepr_membership<\/code>) \u2014 were extracted into a separate WordPress add-on called <strong>AcrossAI User Access Pro<\/strong> (<code>acrossai\/user-access-pro<\/code>), 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 (<code>wp_role<\/code>, <code>wp_user<\/code>, <code>wp_capability<\/code>) plus a new <code>wpb_access_control_register_providers<\/code> global filter for add-on registration. <strong>This plugin uses only <code>AccessControlManager<\/code> + <code>RuleTable<\/code> \u2014 neither of the removed provider classes.<\/strong> No consumer-side code change is required; every existing Access Control rule shape is preserved and the per-consumer <code>AccessControlManager( $providers_filter, $table_slug )<\/code> constructor signature is unchanged.<\/li>\n<li><strong>v3.1.0.<\/strong> Adds a new <code>AccessControlManager::TYPE_AUTHENTICATED<\/code> (<code>'authenticated'<\/code>) sentinel rule type \u2014 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 <code>everyone<\/code>. Also renames the public option label from \"Everyone (no restriction)\" to \"Public (no login required)\" for clarity. Existing rules are untouched; the <code>everyone<\/code> key behaves identically.<\/li>\n<\/ul><\/li>\n<li><strong>New Access Control rule affordance on every ability.<\/strong> Site administrators can now pick \"Any logged-in user\" from the Access Control dropdown on the ability edit panel \u2014 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 <code>everyone<\/code> means \"no login required.\"<\/li>\n<li><strong>Migration required only for sites vendoring the built assets.<\/strong> Consumer plugins that pin <code>vendor\/wpboilerplate\/wpb-access-control\/assets\/build\/<\/code> in their release bundle should <code>composer update<\/code> and rebuild to pick up the new dropdown option. This plugin re-vendors the library's compiled CSS via <code>admin\/Main.php::enqueue_styles()<\/code> and the <code>composer update<\/code> this changelog entry documents already regenerates that asset path.<\/li>\n<li><strong>No breaking changes.<\/strong> 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 \u2014 the removed BuddyBoss \/ MemberPress providers were never registered from this plugin (they defaulted to <code>is_available() === false<\/code> in the library's v1.6.0 \u2013 v2.0.x range on sites that had not explicitly opted in). Safe upgrade from 0.0.20.<\/li>\n<\/ul>\n\n<h4>0.0.20<\/h4>\n\n<ul>\n<li><strong>Changed \u2014 access-control library-missing notice now routes through the shared AcrossAI notice hub.<\/strong> The pre-0.0.20 <code>AcrossAI_Abilities_Access_Control::maybe_show_library_notice()<\/code> method was hooked on WordPress core <code>admin_notices<\/code> and printed a raw <code>.notice.notice-warning<\/code> banner on every admin screen when the <code>wpb-access-control<\/code> library wasn't loaded. It is renamed to <code>register_library_notice( array $notices ): array<\/code> and now registers into the new <code>acrossai_notices<\/code> filter shipped by <code>acrossai-co\/main-menu<\/code> 0.0.30. The notice appears in two places instead: (1) as a card on the new <strong>AcrossAI \u2192 Notices<\/strong> 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 <code>.notice.notice-warning.is-dismissible<\/code> summary banner (\"AcrossAI has N notifications for your attention \u2014 View notices \u2192\") printed on every other admin page. Dismissal is fingerprint-persisted per user until the notice set changes. Notice record shape: <code>id=wpb_access_control_missing<\/code>, <code>type=warning<\/code>, <code>source=AcrossAI Abilities Manager<\/code>. Semantics are unchanged \u2014 the fail-open behaviour, the <code>manage_options<\/code> gate (enforced by the menu itself and the summary emitter), and the message copy are all preserved.<\/li>\n<li><strong>Composer dependency bump \u2014 <code>acrossai-co\/main-menu<\/code> 0.0.29 \u2192 0.0.30.<\/strong> Ships the cross-plugin notice system this release routes through:\n\n<ul>\n<li>New <code>acrossai_notices<\/code> filter \u2014 any AcrossAI consumer plugin can push admin-notice records into a shared collection using a single documented record shape (<code>id<\/code>, <code>title<\/code>, <code>message<\/code>, <code>type<\/code>, optional <code>source<\/code>, optional <code>action { label, url }<\/code>). Later registrations of the same <code>id<\/code> are ignored (first-wins). Missing <code>id<\/code> or both <code>title<\/code> and <code>message<\/code> empty \u2192 the entry is dropped.<\/li>\n<li>New <strong>AcrossAI \u2192 Notices<\/strong> submenu (slug <code>acrossai-notices<\/code>, class <code>NoticesPageRenderer<\/code>) \u2014 only registered when at least one notice exists. Menu label carries a WP-style count bubble (<code>.awaiting-mod<\/code>).<\/li>\n<li>New top-of-page summary notice emitter (<code>SummaryNoticeEmitter<\/code>) \u2014 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 <code>_acrossai_notices_summary_fp<\/code>) so the summary re-appears whenever the notice set changes.<\/li>\n<li>New AJAX endpoint <code>wp_ajax_acrossai_notices_dismiss_summary<\/code> \u2014 nonce + <code>manage_options<\/code> 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.<\/li>\n<li>New public classes under <code>AcrossAI_Main_Menu\\<\/code>: <code>Notices<\/code>, <code>NoticesPageRenderer<\/code>, <code>NoticesAjaxHandlers<\/code>, <code>SummaryNoticeEmitter<\/code>. New page-slug constant <code>SettingsPage::NOTICES_SLUG<\/code> and static accessor <code>SettingsPage::get_notices(): ?Notices<\/code> for consumers that want to inspect the current notice list programmatically.<\/li>\n<\/ul><\/li>\n<li><strong>Note \u2014 the vendor-missing boot-resilience notice in <code>Includes\\Main::__construct()<\/code> remains on core <code>admin_notices<\/code>.<\/strong> That code path fires precisely when the composer autoloader is absent \u2014 the moment when the shared main-menu package isn't loadable either \u2014 so the <code>acrossai_notices<\/code> filter cannot be reached from it. This is intentional and matches Constitution \u00a7V Integration Resilience.<\/li>\n<li><strong>No breaking changes.<\/strong> 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.<\/li>\n<\/ul>\n\n<h4>0.0.19<\/h4>\n\n<ul>\n<li><strong>New \u2014 MCP Manager promo callout on the ability edit form.<\/strong> The MCP Exposure section (Section 3) of the Custom Abilities edit page now surfaces a blue-tinted informational callout advertising the sibling <code>acrossai-mcp-manager<\/code> 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 (<code>admin.php?page=acrossai-addons<\/code>), and a \"Learn more\" external link to <code>https:\/\/acrossai.co\/mcp-manager\/<\/code>. When the AcrossAI MCP Manager plugin IS active on the site, the callout is fully suppressed \u2014 zero UI on the edit form. Detection uses WordPress core <code>is_plugin_active( 'acrossai-mcp-manager\/acrossai-mcp-manager.php' )<\/code> inside the admin script enqueue path; the resolved boolean plus the two URLs are injected into the existing <code>window.acrossaiAbilitiesManager<\/code> localize payload as <code>mcp_manager_active<\/code>, <code>mcp_manager_addons_url<\/code>, and <code>mcp_manager_info_url<\/code>. The callout also degrades gracefully on older bundles or a customised localize payload \u2014 the two action buttons render only when their corresponding URL keys are non-empty.<\/li>\n<li><strong>Composer dependency bump \u2014 <code>acrossai-co\/main-menu<\/code> 0.0.27 \u2192 0.0.29.<\/strong> Two-hop bump rolled into one release:\n\n<ul>\n<li><em>0.0.28<\/em> \u2014 refreshed the Add-ons page baseline catalogue. The hard-coded add-on list now surfaces three entries: <strong>AcrossAI Abilities Manager<\/strong> (wp.org), <strong>AcrossAI MCP Manager<\/strong> (wp.org), and <strong>AI Connectors<\/strong> (external \"Get add-on \u2197\" link to <code>acrossai.co\/ai-connectors\/#pricing<\/code>). AcrossAI Model Manager and Turn Off AI Features are dropped from the hard-coded baseline \u2014 sites that still want them can register them via the <code>acrossai_addons<\/code> filter unchanged. All three baseline cards render the shared AcrossAI SVG logo from <code>acrossai.co<\/code> instead of per-plugin <code>ps.w.org<\/code> PNG icons, so the Add-ons page reads as one product surface. Icon fit switched from <code>cover<\/code> to <code>contain<\/code> (with 6px padding) so wide\/horizontal SVG logos render fully instead of being cropped inside the 56\u00d756 icon box. Grid pinned to a fixed 3-column layout (<code>repeat(3, minmax(0, 1fr))<\/code>) with responsive fallbacks (2 cols under 1100px, 1 col under 720px). New optional <code>learn_more_url<\/code> add-on field renders as a \"Learn more\" text link inside the card action row for every add-on regardless of <code>source<\/code>.<\/li>\n<li><em>0.0.29<\/em> \u2014 reworked the Add-ons card action states so the page reads as a <strong>discovery surface, not a plugin manager<\/strong>. Active add-ons now render a non-clickable green <strong>\"\u25cf Running\"<\/strong> pill instead of a \"Deactivate\" button; deactivation stays in Plugins \u2192 Installed Plugins where WP admins expect it (new CSS classes <code>.acrossai-addons__status<\/code> \/ <code>.acrossai-addons__status--active<\/code> \/ <code>.acrossai-addons__status-dot<\/code>). Installed non-<code>wordpress.org<\/code> add-ons now show an in-page <strong>Activate<\/strong> button instead of always rendering the external \"Get add-on \u2197\" link \u2014 detection is source-agnostic and driven by <code>AddonsInstaller::find_plugin_file()<\/code>, so a paid\/off-directory add-on that the admin uploaded via Plugins \u2192 Add New \u2192 Upload Plugin can be activated straight from the AcrossAI Add-ons page. The Install code path remains restricted to <code>wordpress.org<\/code> sources (WP.org guideline #8 \u2014 no change). The <code>AI Connectors<\/code> baseline entry declares <code>install_folder =&gt; 'acrossai-ai-connectors'<\/code> so install detection matches the actual plugin folder even though the registry slug (<code>ai-connectors<\/code>) differs \u2014 canonical example for consumers whose extracted folder \u2260 slug.<\/li>\n<\/ul><\/li>\n<li><strong>No breaking changes.<\/strong> 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.<\/li>\n<\/ul>\n\n<h4>0.0.18<\/h4>\n\n<ul>\n<li><strong>New \u2014 Third-party integration framework (Feature 060) with Advanced Custom Fields as the first concrete integration.<\/strong> Adds a new \"Acf\" tab to the Ability Library page (<code>\/wp-admin\/admin.php?page=acrossai-abilities-library&amp;tab=acf<\/code>) with a single toggle labelled \"Advanced Custom Fields (AI)\". Flipping the toggle ON attaches <code>add_filter( 'acf\/settings\/enable_acf_ai', '__return_true' )<\/code> early enough in <code>plugins_loaded<\/code> (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 <strong>OFF<\/strong> for every integration \u2014 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.<\/li>\n<li><strong>New \u2014 extensibility surface for third-party AcrossAI plugins.<\/strong> 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 <code>wp_abilities_api_categories_init<\/code> via <code>wp_register_ability_category()<\/code>, (2) extend <code>\\AcrossAI_Abilities_Manager\\Includes\\Modules\\Library\\Ability_Definition<\/code>, and (3) set <code>meta.acrossai.tab_group<\/code> on the ability's args to the integration's published <code>TAB_GROUP<\/code> constant (e.g. <code>\\AcrossAI_Abilities_Manager\\Includes\\Abilities\\Integrations\\ACF::TAB_GROUP<\/code>). Reads from the new <code>AcrossAI_Integration_Ability_Base<\/code> docblock + the quickstart worked example under <code>specs\/060-library-third-party-integration-toggles\/quickstart.md<\/code>. This is the mechanism that lets the sibling <code>acrossai-acf-abilities<\/code> plugin surface its own cards on the same \"Acf\" tab.<\/li>\n<li><strong>New REST filter \u2014 <code>acrossai_integration_toggle_capability<\/code>.<\/strong> Lets sites raise (never lower) the WordPress capability required to flip an integration toggle. Default is <code>manage_options<\/code> (matches the rest of the Ability Library page); a site can attach a filter returning e.g. <code>manage_network_options<\/code> and a <code>manage_options<\/code>-only user will then receive HTTP 403 on the REST write. Enforced server-side on the same write path that persists the toggle \u2014 cannot be bypassed by a crafted REST request even if the JS UI presented the toggle as interactive. Companion action <code>acrossai_integration_toggle_denied<\/code> fires immediately before the 403 so sites can wire audit logging without amending core code.<\/li>\n<li><strong>Bugfix \u2014 sparse-storage in <code>acrossai_library_config<\/code> was silently stripping integration ON entries.<\/strong> The pre-Feature-060 sparse-storage rule in <code>AcrossAI_Ability_Library_Config::save_config()<\/code> assumed every category defaults to <code>enabled=true<\/code>, so a <code>{ enabled: true, mode: 'all', sub_keys: {} }<\/code> payload was stripped as \"default state\". Feature 060 integration categories invert that default (missing = OFF  &hellip;<\/li>\n<\/ul>","raw_excerpt":"Manage every WordPress ability registered on your site \u2014 view, search, override, and bulk-control ability metadata from a single admin page.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/311005","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=311005"}],"author":[{"embeddable":true,"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/raftaar1191"}],"wp:attachment":[{"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=311005"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=311005"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=311005"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=311005"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=311005"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/lin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=311005"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}