AcrossAI Abilities Manager

Descrición

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

Features:

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

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

Security:

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

Third-party integrations (optional):

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

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

External Services

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

1. Calendly external link (calendly.com)

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

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

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

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

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

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

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

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

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

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

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

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

Privacy Policy

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

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

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

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

Capturas

Instalación

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

Add-ons:

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

Preguntas frecuentes

Does this plugin support Multisite?

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

Does this plugin modify the WordPress ability registry?

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

What happens when I reset an override?

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

What is the Ability Library?

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

What is the MCP Adapter integration?

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

Does this plugin make external HTTP requests?

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

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

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

Comentarios

Non hai recensións para este plugin.

Colaboradores e desenvolvedores

“AcrossAI Abilities Manager” é un software de código aberto. As seguintes persoas colaboraron con este plugin.

Colaboradores

Traduce “AcrossAI Abilities Manager” ao teu idioma.

Interesado no desenvolvemento?

Revisa o código, bota unha ollada aorepositorio SVN, ou subscríbete ao log de desenvolvemento por RSS.

Rexistro de cambios

0.0.20

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

0.0.19

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

0.0.18

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

    • 0.0.26 — the Consultations submenu (introduced in 0.0.24) previously embedded the Calendly widget via assets.calendly.com/assets/external/widget.js and an iframe pointed at calendly.com/acrossai/using-ai-in-wordpress. It now renders a self-contained call-to-action page that opens calendly.com in a new browser tab only when the admin clicks the button — no Calendly script, iframe, or asset is loaded inside wp-admin. Fixes the “using iframes for admin pages” prohibition.
    • 0.0.27 — the Add-ons page’s install action is now WordPress.org-only. Cards whose source is wordpress.org continue to render an in-page Install / Activate / Deactivate button (routed through WordPress core’s plugins_api() + Plugin_Upgrader). Cards with any other source (e.g. github, freemius, or any consumer-defined value) render an external “Get add-on ” link that opens the vendor’s site in a new browser tab — users install those add-ons via WP admin’s standard Plugins Add New Upload Plugin flow, or via the vendor’s own installer. Fixes the “installing plugins/themes/add-ons from non-WordPress.org servers” prohibition. Same design pattern used by WooCommerce and GiveWP for their extension marketplaces. Also adds a new public helper AddonsInstaller::is_installable_source( array $addon ): bool and defense-in-depth rejection in the AJAX install handler.

    Purely additive on the AcrossAI parent-menu surface — no changes to any of our own submenus (Ability Library at priority 2, Settings at priority 20). SettingsPage‘s public constructor signature is unchanged. Consumers that only ship wp.org-sourced add-ons see no visible change; consumers pushing GitHub/Freemius entries via the acrossai_addons filter will see those cards flip from Install button to “Get add-on ” link — no code change required on their side.

  • 20 new PHPUnit tests + 12 new Jest tests cover the base-class contract, the extension pattern end-to-end, resilience under target-plugin deactivation, the default-OFF safety property, and the sparse-storage bugfix regression. Full suite: 191 tests passing.
  • 6 new durable memory entries in docs/memory/ (DECISIONS.md, ARCHITECTURE.md, BUGS.md, INDEX.md) capture the reusable patterns: DEC-ABILITY-DEFINITION-CTOR-HOOKS, PATTERN-LIBRARY-INTEGRATION-BASE, PATTERN-LIBRARY-INTEGRATION-TAB-EXTENSION, PATTERN-FILTERABLE-CAPABILITY-RAISE-ONLY, BUG-WP-CORE-ABILITY-CATEGORY-PRE-REGISTRATION, BUG-SPARSE-STORAGE-UNIFORM-DEFAULT-ASSUMPTION. Documented so the next contributor doesn’t rediscover the same traps (specifically: WP core silently rejects abilities whose category isn’t pre-registered via wp_register_ability_category, and asymmetric-default keys break naive sparse-storage optimisations).
  • 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.17.

0.0.17

  • New — 7 Recovery Mode abilities under a new Recovery category. Adds acrossai/get-recovery-mode-status, acrossai/list-paused-plugins, acrossai/list-paused-themes, acrossai/get-recovery-exit-url, acrossai/unpause-plugin, acrossai/unpause-theme, and acrossai/list-recent-fatal-errors. Together they let an AI agent driving the site over REST/MCP detect if WordPress has entered Recovery Mode after a fatal error, enumerate paused (fatally-erroring) plugins and themes with their captured error details, clear a paused entry so WP retries loading the extension on the next request, retrieve the admin-clickable exit URL, and pull grouped fatal-error signatures from debug.log. Every write action gates on manage_options + File_Mods_Guard::blocked_response(); fuzzy plugin/theme identifiers flow through the existing Plugin_Helpers::resolve_plugin() / Theme_Helpers::resolve_theme() resolvers.
  • Intentional non-goals: no programmatic recovery-mode trigger, no programmatic exit. WP core has no public API to enter recovery mode from a REST call (the handler only fires on a real fatal at a protected endpoint), and exit is guarded by both a session cookie and a nonce that a normal admin REST session can’t satisfy. The get-recovery-exit-url ability returns the URL for an admin (or a browser-driving agent) to follow instead.
  • Docs — recovery-mode compatibility noted on 3 existing abilities. activate-plugin, deactivate-plugin, and activate-theme now mention in their description that they work in recovery mode (they only update the active_plugins / active-theme option and don’t load the extension file).
  • Ships without JS, DB, or REST-controller changes. Purely new PHP source under includes/Abilities/Recovery/ plus 7-line bootstrap wiring. 21 new PHPUnit tests under the new feature-059-unit testsuite.

0.0.16

  • New — acrossai/reinstall-wp-core ability under the Core category. Reinstalls the currently-installed WordPress version by handing a synthetic offer with response = 'reinstall' to WP core’s Core_Upgrader::upgrade() — same code path the WordPress dashboard’s “Reinstall now” button uses. Uses allow_relaxed_file_ownership=false so ownership mismatches surface as errors instead of silent partial-upgrades. Requires BOTH manage_options AND update_core; honours DISALLOW_FILE_MODS via File_Mods_Guard; multisite-guarded; refuses when core is being actively updated to a different version (use acrossai/update-wp-core for that). Complements the existing acrossai/update-wp-core, acrossai/rollback-wp-core, and acrossai/check-wp-core-update abilities.
  • BREAKING — every ability slug has been renamed. Two changes at once: (a) namespace shortens from acrossai-abilities-manager/ (27 chars) to acrossai/ (9 chars), and (b) suffixes flip to verb-first form. Every ability is now acrossai/<verb>-<subject> — e.g. acrossai/get-site-title, acrossai/activate-theme, acrossai/list-plugins — instead of the pre-0.0.16 acrossai-abilities-manager/<subject>-<verb> form. 163 suffixes changed; 56 already-verb-first suffixes only had their namespace shortened. Every ability’s label was already verb-first (“Get Site Title”, “Activate Theme”), so the slug now reads the same word order as the label. Motivation: alignment with the WordPress core MCP adapter convention (mcp-adapter/discover-abilities, mcp-adapter/execute-ability) and with the broader function-calling / MCP naming used by every major LLM tool-use spec.
  • Class files and PHP class names flipped to verb-first too. 162 files renamed to match their slugs — Site_Title_Get.php Get_Site_Title.php, Theme_Activate.php Activate_Theme.php, etc. Internal-only change; no external API surface. PSR-4 autoload picks up the new file/class names automatically.
  • No automatic data migration. The plugin is still small enough that no auto-migration ships with this release. If you had a pre-0.0.16 install with saved overrides or ACL rules keyed on the old acrossai-abilities-manager/<subject>-<verb> slugs, wipe those rows manually (Custom Abilities admin page clear overrides; Access Control admin page clear rules) and re-create them under the new acrossai/<verb>-<subject> names. External callers (custom code, saved MCP client configs, scripts calling /wp-json/wp-abilities/v1/abilities/acrossai-abilities-manager/<old-slug>/run) must update their slug strings to /wp-json/wp-abilities/v1/abilities/acrossai/<new-slug>/run. No backwards-compatibility aliases are shipped.

0.0.15

  • Bulk Actions overhaul on the Custom Abilities admin page — Site Access / MCP Exposure / User Access / Overrides. Replaces the misleading Publish / Unpublish / Delete dropdown (WP-CPT vocabulary that never mapped to how ability overrides behave) with four ability-native optgroups that mirror the per-row edit drawer: Site Access tri-state (Force Allow / Inherit / Force Block writing site_allowed), MCP Exposure tri-state (Enable / Default / Disable writing show_in_mcp), User Access (opens a modal that mounts the composer’s <AccessControl> picker and applies one rule across every selected slug, plus a “Reset to Default — allow everyone” quick action), and Overrides Force Reset (clears every override column per slug via the existing DELETE /abilities/{slug}/override endpoint). Destructive transitions (Force Block, MCP Disable, User Access Reset, Force Reset) prompt for confirmation before dispatch.
  • Row-level checkbox and Edit action now work on every ability regardless of Source. The pre-0.0.15 checkbox gate limited selection to Custom (db) rows only — a hangover from the deleted Publish/Unpublish/Delete flow. Bulk tri-state operations apply to any Source, so every visible row now shows a checkbox and can be included in a bulk selection. The Edit action was already unconditional across sources; verified with the same release.
  • Full-screen busy overlay with WP-native spinner + body scroll-lock during every bulk apply. Uses <span class="spinner is-active"> (the same spinner WP admin shows next to Save Draft) over a backdrop-blurred wash; the underlying page is un-clickable and the body cannot scroll until the bulk request set resolves. Escape-to-dismiss on the User Access modal is suppressed while its apply is in flight to prevent half-applied state on the underlying multi-slug write.
  • Client-side only release. No PHP changes, no new REST endpoints, no new database tables, no new composer or npm packages. All storage, sanitisation, capability enforcement, and REST controllers are unchanged. The feature loops the pre-existing per-slug endpoints under Promise.all inside three new Redux thunks (bulkUpdateTristate, bulkClearOverrides, bulkSetUserAccessRule); the composer package’s provider enumeration and rule storage are reused verbatim.
  • 25 new Jest tests across three suites cover payload discipline (raw JSON true / false / null on tri-state writes), partial-failure re-throw discipline (operator sees an error and keeps the selection for retry instead of a silent success), composer null-response guard, and a slug-encoding regression guard (see below). Also adds two new architecture patterns and one new bug pattern to docs/memory/.
  • Fixed: composer User Access rule keys were storing the ability slug with the / character stripped when applied via the bulk path. Root cause: client-side encodeURIComponent(slug) on the composer PUT URL was collapsed to nothing by the composer’s key sanitizer (%2F was stripped rather than decoded back to /), producing orphan rows like acrossai-abilities-managerblock-pattern-delete. Fixed by matching the per-row edit drawer’s pattern — passing the slug raw into the URL. Server-side sanitize_ability_slug() still validates independently, so no security regression. Guarded by a Jest regression test.

0.0.14

  • wp.org banner artwork refreshed + filenames renamed to the WP.org canonical convention. banner1544x500.png banner-1544x500.png and banner772x250.png banner-772x250.png. WordPress.org’s plugin directory only auto-detects banners at the dashed paths (.wordpress-org/banner-{width}x{height}.png) — the un-dashed variants shipped in 0.0.13 were not being surfaced on the plugin listing page. Both banners also carry updated artwork in this release. wp.org-assets-only change; no plugin code touched.

0.0.13

  • Docs — ability gap audit landed under specs/054-ability-gap-audit/. Tracks 31 abilities across 10 domains that external AI-tool inventories expect but the plugin does not yet expose (Site editor / structure, Admin menu, Navigation, Users, Content index / search / linking, Content advanced, Taxonomy, Media, Site lifecycle, Comments). Current registered inventory: 187 abilities under acrossai/*, verified via grep against wp_register_ability and confirmed wired 1:1 into AcrossAI_Core_Abilities_Bootstrap.php. For every missing ability, the audit names the closest existing ability in the plugin (or explicitly declares the domain as absent) so future implementation waves do not accidentally duplicate work. Each missing ability becomes its own follow-up spec later. No runtime code changes; audit-only release.
  • wp.org assets — banner (1544×500 and 772×250) and a sixth screenshot added. The plugin directory listing now shows a proper header banner (previously falling back to the WordPress.org default header since 0.0.4) and a sixth screenshot covering the Settings page (Display + Upload Media Abilities sections). Metadata-only change to .wordpress-org/ — no plugin code touched.
  • 31 new abilities across 10 domains — 187 218. Ships the entire backlog surfaced by the external AI-tool inventory audit. Two new categories are added: acrossai-abilities-manager-admin-menu (5 abilities) and acrossai-abilities-manager-content-search (11 abilities). Single-item additions land in existing categories: users-current-access (Users), taxonomy-set-term-image (Taxonomies), comments-bulk-update (Comments), media-rename-file (Media), navigation-get-context + navigation-list-locations (Menus), content-update-block + content-autosaves-inspect (Content), site-editor-get-context + site-editor-refresh-context + site-structure-list-reusable-blocks + site-structure-list-block-areas (Block), site-maintenance-report (SiteHealth), plugin-lifecycle-get-plugin (Plugins), theme-lifecycle-get-theme (Themes).
  • New option-backed lifecycle event log. plugin-lifecycle-get-plugin and theme-lifecycle-get-theme return last_activated_at / last_deactivated_at / last_updated_at timestamps from a rolling event log (acrossai_abilities_manager_lifecycle_log option, capped at 50 events per plugin/theme). Events are recorded from 0.0.13 forward — pre-0.0.13 lifecycle history is not backfilled and those timestamps read 0 until the next event fires.
  • New option-backed internal-link suggestion store. The 5 content-internal-link-* abilities (create, list, review, apply, policy) plus content-audit-internal-links persist to acrossai_abilities_manager_link_suggestions (option-backed, capped at 500 total suggestions). Zero external HTTP; zero new database tables.
  • No breaking changes. No existing ability slug / input schema / output schema / permission callback is altered. Every previously-registered ability still resolves to the same class.
  • Safety notes. media-rename-file refuses filenames with a directory separator, null byte, or leading dot; enforces realpath containment inside the attachment’s original upload sub-directory; refuses to clobber an existing target. comments-bulk-update requires moderate_comments and caps at 100 comment ids per call. content-internal-link-suggestion-apply requires edit_others_posts, re-validates the target as same-site, and only mutates on first-occurrence substring match.

0.0.12

  • New — WordPress core rollback ability under the Core category. acrossai/rollback-wp-core rolls back WordPress core to an earlier offered version via WP core’s Core_Upgrader::upgrade() — the same class the WordPress dashboard uses for forward updates. Fetches the offer list from the WP.org Core API 1.7 endpoint (https://api.wordpress.org/core/version-check/1.7/) via wp_remote_get(), picks the requested version, and hands the offer directly to the upgrader. Uses only WordPress functions; no bundled updater code. Requires BOTH manage_options AND update_core; honours DISALLOW_FILE_MODS via File_Mods_Guard; multisite-guarded; refuses when the target version is equal to or newer than the currently-installed version (steers callers to wp-core-update). The per-locale offer list is cached in a site transient with a day-long TTL. Annotated destructive=true — rolling WordPress back is a real production operation and clients should surface it accordingly. Inspired by Andy Fragen’s core-rollback plugin (MIT-licensed). See PR #77.
  • First outbound HTTP request from the plugin. Historically the plugin has made zero outbound HTTP requests on its own (the Add-ons page delegates to the WordPress plugin installer’s own contact with WordPress.org; other abilities operate on the local site). wp-core-rollback introduces the plugin’s first direct outbound request — to api.wordpress.org/core/version-check/1.7/. The URL is a hardcoded class constant (no SSRF surface), the request has a 15-second timeout, and only the sanitized locale is derived from user input. The per-locale offer list is cached in a site transient with a day-long TTL, so the request rate is bounded to at most one call per day per locale per site.

0.0.11

  • New — WordPress core update abilities under a new “Core” category. Two new abilities: acrossai/check-wp-core-update reports whether a WordPress core update is available (returns current_version, new_version, download URL, PHP / MySQL requirements — flattens WP’s core update offer into a JSON-friendly shape); acrossai/update-wp-core applies the update via WP core’s Core_Upgrader::upgrade(). When called with no arguments it upgrades to the first response=upgrade offer from get_core_updates(); pass version (+ optional locale) to pin to a specific offer. Requires BOTH manage_options AND update_core (matches WP core’s own admin gate). Honours DISALLOW_FILE_MODS via File_Mods_Guard. Multisite guard bails cleanly if the current user lacks network-level update_core. Idempotent — re-running when no update is available returns a clean success envelope with updated=false. Uses WP core functions exclusively; no bundled updater, no custom HTTP, no custom integrity checks. See PR #75.
  • New Core category folder. includes/Abilities/Core/ joins the existing 17 Category folders (Plugins, Themes, FileManager, Cache, Database, Users, Block, Settings, Fonts, Content, Taxonomies, Media, Comments, Menus, Options, Cron, SiteHealth). Displayed as a new “Core” tab on the Ability Library page. Not a new module — Constitution §I locks the module count at five; Category folders are sub-partitions of the existing Custom Ability Registration module.
  • Backup filenames — human-readable and time-sortable. Filenames produced by zip-create (and finalized zips from zip-upload) change from backup-{type}-{slug}-{random-12-chars}.zip to {slug}-{unix-timestamp}-{ms}.zip (e.g. hello-dolly-1721260800-517.zip). Lexicographic sort now equals chronological sort; the target is readable at a glance. The 3-digit millisecond suffix from microtime(true) prevents same-second collisions when two back-to-back calls target the same slug. Trade-off: dropping the 12-char random suffix removes the enumeration-by-guessing defense the old scheme provided. Mitigations still in force: the .htaccess in wp-content/uploads/acrossai-backups/ still disables directory listing (Options -Indexes) and still blocks execution of PHP-family extensions, and zip-list / zip-download still require manage_options. Backups created on 0.0.9 / 0.0.10 with the old scheme continue to work — the filename change only affects new backups.
  • Spec-Kit backfill for Feature 041. specs/041-backup-restore-abilities-and-updates/ now exists with the full artifact set (spec, plan, tasks, checklists, security-constraints, memory-synthesis, architecture-review) documenting the 8 abilities that shipped in 0.0.9 and the 0.0.10 include_hidden fix. Same seven-file layout used by Feature 053’s backfill.

0.0.10

  • Fix (Create_Zip_Backup) — include_hidden=false now applies recursively. The 0.0.9 implementation used RecursiveIteratorIterator::SELF_FIRST with a per-entry basename check that only skipped the top-level hidden directory itself; the iterator kept descending into it, so files INSIDE a hidden directory (e.g. .git/objects/xxx) were still added because their basenames don’t start with .. Fixed to check EVERY segment of the entry’s relative path — same approach the reference download-plugin uses in its app/Plugins/Base.php. Applied to both the archive assembly (append_dir_to_zip) and the pre-write size guard (estimate_tree_size). If you called zip-create with include_hidden=false against a dev checkout in 0.0.9, the archive contained the full contents of every hidden directory beneath the source — regenerate any such archives on 0.0.10. See PR #73.

0.0.9

  • New — six Zip abilities under FileManager for backup / restore workflows. acrossai/create-zip-backup archives a plugin, theme, uploads folder, mu-plugins folder, or any ABSPATH-relative path into wp-content/uploads/acrossai-backups/<random>.zip and returns the download URL + SHA-256. zip-upload accepts a zip via base64, chunked (up to 8 MB per chunk / 64 MB per session, filterable), or a remote URL and finalizes it into the same directory after validating the PK\x03\x04 magic bytes. zip-extract extracts a zip already on disk or fetched from a URL into a resolved target directory (plugin / theme / uploads / mu-plugins / path); every archive entry is audited for zip-slip (.. segments, absolute paths, backslashes, null bytes) before extraction. zip-download returns a fresh URL + metadata for any managed zip. zip-list paginates the managed directories, newest first. zip-delete removes a zip from the managed directories idempotently. The backups directory is hardened on first use with an .htaccess that blocks PHP execution while keeping .zip downloads reachable, plus an empty index.php for enumeration defense. All abilities enforce manage_options; every mutating ability honours DISALLOW_FILE_MODS via the shared File_Mods_Guard. See PR #TBD.
  • New — acrossai/update-plugin and acrossai/update-theme abilities. The Plugins and Themes categories previously shipped an update-check reporter but no way to apply updates through the abilities API. The new abilities wrap WP core Plugin_Upgrader::bulk_upgrade() / Theme_Upgrader::bulk_upgrade() (same pattern as the existing plugin-install / theme-install), accept an array of plugin files / slugs or theme stylesheets, and return per-slug results with from_version, to_version, updated, and message. Update_Plugin additionally requires update_plugins; Update_Theme additionally requires update_themes. Idempotent: re-running when no update is available reports updated_count: 0 with a clean success envelope.
  • Shared utilities: Backups_Storage and Zip_Target_Resolver. New helpers under includes/Abilities/Utilities/. Backups_Storage manages the acrossai-backups/ and acrossai-staging/ directories under wp-content/uploads/, generates enumeration-resistant random filenames, resolves managed paths with realpath() boundary checks, and computes SHA-256 for the listing / download responses. Zip_Target_Resolver maps (target_type, target) to an absolute filesystem path — plugin slugs resolve via Plugin_Helpers (existing fuzzy resolver), theme stylesheets via Theme_Helpers, uploads via wp_get_upload_dir(), mu-plugins via WPMU_PLUGIN_DIR, and path values via a strict inside-ABSPATH realpath check.
  • Upload_Zip_Backup chunk sweeper cron. A new daily cron (acrossai_abilities_manager_zip_upload_sweep_chunks) sweeps abandoned chunk sessions from wp-content/uploads/acrossai-staging/ after the configurable TTL (default: 1 day, filterable via acrossai_abilities_manager_zip_upload_session_ttl). Mirrors the existing Upload_Media sweeper.
  • New configurable limits. acrossai_abilities_manager_zip_max_bytes (default 512 MB) caps the decompressed size of any zip written or extracted. acrossai_abilities_manager_zip_upload_chunk_max_bytes (default 8 MB base64) and acrossai_abilities_manager_zip_upload_session_max_bytes (default 64 MB base64) cap the chunked upload flow.

0.0.8

  • Freemius integration removed entirely. The freemius/wordpress-sdk composer dependency is dropped (upstream acrossai-co/main-menu 0.0.21+ no longer requires it). The plugin no longer sends any data to Freemius, no longer shows a Connect / Login / Buy affordance on the Add-ons page, and the entire Freemius vendored SDK tree (~2,000 files) is removed from the installable ZIP. If you previously connected a Freemius account tied to this plugin, that connection is now inert; any fs_* or freemius_* rows in wp_options are no longer read by anything and can be safely deleted (e.g. wp option list --search='fs_*' then wp option delete <name> for each). This supersedes the 0.0.6 changelog entry about Freemius credentials — those credentials are no longer used. See PR #69.
  • Add-ons page — free-only, and this plugin excluded from its own listing. The Add-ons page (?page=acrossai-addons) now lists only free companion plugins hosted on WordPress.org (Install / Activate / Deactivate via the standard WP plugin installer). This plugin no longer appears in its own Add-ons page — a small self-filter on the acrossai_addons hook removes it, since it’s obviously already active when the page renders. Other AcrossAI companion plugins (MCP Manager, Model Manager, Turn Off AI Features) still list normally.
  • Library page — title and Enable All / Disable All buttons on a single horizontal row. The “Ability Library” page heading and the bulk-action buttons introduced in 0.0.7 (Feature 052) now share one line at the top of the page (title anchored left, buttons anchored right). Saves vertical space; matches administrator expectations for admin page layouts.
  • Dependencies: acrossai-co/main-menu bumped from 0.0.14 to 0.0.23. Three-hop bump (0.0.21 0.0.22 0.0.23) accumulated during the release cycle. Consumer API surface (SettingsPage, MenuRegistrar, AddonsPageRenderer) preserved across each hop; no code changes required beyond removing the old \AcrossAI_Addon\AddonsPage instantiation (class deleted upstream in 0.0.21 — its responsibilities moved into \AcrossAI_Main_Menu\MenuRegistrar which is registered automatically when the shared SettingsPage bootstrap runs).

0.0.7

  • Library page — bulk Enable All / Disable All action buttons. A new right-aligned header row above the tab strip on ?page=acrossai-abilities-library renders two side-by-side buttons that toggle every ability category currently in view with a single click. Actions are scoped to the active tab: on the All tab they touch every registered category; on a specific tab (Core, Blocks, Themes, Users, Cache, File Manager, Cron, Database, Plugins) they only touch categories whose ability metadata declares that tab_group. Categories in other tabs pass through byte-for-byte unchanged. Each category’s mode (All / Specific) and per-slug selections are preserved on both actions — a Disable All Enable All cycle is a lossless round-trip. Persisted via the existing POST /acrossai-abilities-library/v1/abilities/config REST route (manage_options + nonce, unchanged). See PR #68.
  • URL-synced tabs on the Library page. The active tab is now reflected in the browser URL as ?tab=<slug>. Deep-linkable, bookmarkable, and browser back / forward navigation re-syncs the visible tab. Direct-navigation to ?page=acrossai-abilities-library&tab=themes opens the Themes tab on first paint. Invalid tab values silently fall back to the default All view — no error, no console warning. The default All view keeps the canonical URL clean by removing the …