WordPress / WordPress/performance
Register Abilities for Performance Lab plugins
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 461
- Forks
- 165
- Avg merge
- 11h 12m
- Merged PRs (30d)
- 28
Description
With increasing the minimum supported version of WordPress to 6.9 (#2354), we can start to make more use of the Abilities API. This will allow for AI agents to more easily configure the plugins, while also making it easier for developers to interface with them via the REST API (/wp-abilities/v1) and via WP-CLI (wp ability), through which Abilities can be automatically exposed.
I asked Claude Code (Opus 4.6) to look at the plugins to propose a list of Abilities. In implementing any of these, ensure that a PR is only targeting one plugin at a time to make it easier to review and to allow multiple contributors to work in parallel.
Claude Analysis
Below is a proposed set of abilities, grouped by plugin. IDs use the convention {plugin-slug}/{verb-noun}. Each category would be registered once via wp_register_ability_category() (e.g. performance-lab), and each plugin's abilities would meta.show_in_rest = true unless noted.
I've biased toward abilities that an AI agent or remote client could plausibly want — read settings, fetch computed data, trigger regeneration, run diagnostics — and skipped pure CRUD that the existing REST API already covers.
optimization-detective (foundational — most ability-rich)
This is the framework everything else depends on, so it deserves the broadest surface.
| ID | Purpose | Input | Output | Permission |
|---|---|---|---|---|
optimization-detective/get-url-metrics |
Fetch stored URL Metrics for a URL across all viewport groups | url |
URL Metric groups (mobile/tablet/desktop), counts, freshness | edit_posts |
optimization-detective/get-lcp-element |
Get the detected LCP element (XPath, tag, attributes) per viewport group for a URL | url |
{ mobile: {...}, tablet: {...}, desktop: {...} } |
edit_posts |
optimization-detective/get-url-metrics-freshness |
Report whether stored metrics are complete/fresh, sample counts, last collected timestamp | url |
freshness summary | edit_posts |
optimization-detective/clear-url-metrics |
Delete URL Metrics for a single URL (force re-collection) | url |
success | manage_options |
optimization-detective/run-garbage-collection |
Manually run the stale URL Metrics GC | – | count deleted | manage_options |
optimization-detective/get-current-etag |
Return the current detection-script ETag (for cache-busting diagnostics) | – | etag | edit_posts |
optimization-detective/get-template-context |
Inspect the template/route context that would be assigned to a given URL | url |
context slug, query vars | edit_posts |
Read-only (meta.readonly: true): get-url-metrics, get-lcp-element, get-url-metrics-freshness, get-current-etag, get-template-context.
image-prioritizer
Builds on URL Metrics; abilities should expose its derived recommendations.
| ID | Purpose |
|---|---|
image-prioritizer/get-lcp-image |
Return the LCP image (URL, srcset, dimensions, fetchpriority decision) per viewport for a given page URL |
image-prioritizer/get-preload-links |
Return the <link rel=preload> items that would be injected for a URL |
image-prioritizer/get-lazy-load-decisions |
Per-image lazy/eager classification for a URL (img + background-image + video poster) |
image-prioritizer/get-video-poster-recommendations |
Recommended poster sizes per breakpoint for <video> elements on a URL |
All read-only.
embed-optimizer
| ID | Purpose |
|---|---|
embed-optimizer/get-embed-optimizations |
Return per-embed optimization data for a URL: in-viewport status, reserved min-height, DNS-prefetch hosts |
embed-optimizer/get-supported-providers |
List embed providers the visitor handles (Twitter/X, WordPress, YouTube, etc.) |
Read-only.
auto-sizes
Auto-sizes is largely automatic and has no settings, so abilities are diagnostic.
| ID | Purpose |
|---|---|
auto-sizes/compute-sizes-attribute |
Given an image's block context (alignment, width, ancestor columns), compute the sizes value the plugin would emit |
auto-sizes/get-version-status |
Report whether the polyfill is active or whether core ≥ 6.7 is handling sizes=auto |
Both read-only. The first is genuinely useful as a debugging/agent tool: "why did this image get this sizes value?"
dominant-color-images
| ID | Purpose | Permission |
|---|---|---|
dominant-color-images/get-attachment-color |
Return dominant_color and has_transparency for an attachment ID |
read |
dominant-color-images/compute-attachment-color |
Compute (without storing) the dominant color for an attachment — useful for previews | edit_posts |
dominant-color-images/regenerate-attachment-color |
Recompute and persist dominant color for an attachment (e.g. after the original is replaced) | edit_post (per-attachment) |
webp-uploads
This plugin already has REST shape via rest_prepare_attachment; abilities should expose targeted operations.
| ID | Purpose | Permission |
|---|---|---|
webp-uploads/get-attachment-sources |
Return the per-size sources map (mime → URL/path/filesize) for an attachment |
read |
webp-uploads/regenerate-attachment-sources |
Regenerate WebP/AVIF derivatives for one attachment | edit_post |
webp-uploads/get-format-settings |
Read perflab_modern_image_format, perflab_generate_webp_and_jpeg, perflab_generate_all_fallback_sizes, picture-element preference |
manage_options |
webp-uploads/update-format-settings |
Update any of the above | manage_options |
webp-uploads/get-server-format-support |
Report whether the active image editor supports WebP and AVIF output | manage_options |
webp-uploads/get-picture-element-markup |
Return the <picture> markup the plugin would emit for an attachment + size |
read |
speculation-rules
| ID | Purpose | Permission |
|---|---|---|
speculation-rules/get-settings |
Return mode, eagerness, authentication from plsr_speculation_rules |
manage_options |
speculation-rules/update-settings |
Update any of those three fields (validated against the same enums the settings UI uses) | manage_options |
speculation-rules/get-rules-for-url |
Return the speculation-rules JSON the plugin would emit for a given page URL | edit_posts |
speculation-rules/get-excluded-paths |
Return the URL patterns currently excluded (after plsr_speculation_rules_href_exclude_paths filter) |
edit_posts |
view-transitions
| ID | Purpose | Permission |
|---|---|---|
view-transitions/get-settings |
Read all plvt_view_transitions fields (animation, duration, selectors, admin toggle, override flag) |
manage_options |
view-transitions/update-settings |
Update any of those fields with validation | manage_options |
view-transitions/list-available-animations |
Enumerate built-in animation slugs (fade, slide-*, swipe-*, wipe-*) with human labels |
read |
view-transitions/get-theme-support-status |
Report whether the active theme declares native view-transition support (so the plugin would defer) | manage_options |
web-worker-offloading
This plugin is on a sunset track, so I'd keep the surface small.
| ID | Purpose | Permission |
|---|---|---|
web-worker-offloading/list-offloaded-scripts |
List script handles currently flagged with worker => true |
manage_options |
web-worker-offloading/get-partytown-config |
Return the resolved Partytown configuration after the plwwo_configuration filter |
manage_options |
Read-only.
performance-lab (umbrella plugin)
These are arguably the most agent-useful, since they let a client orchestrate the whole suite.
| ID | Purpose | Permission |
|---|---|---|
performance-lab/list-features |
List all known feature plugins with {slug, name, description, active, installed, version} |
activate_plugins |
performance-lab/get-feature |
Detail for one feature slug | activate_plugins |
performance-lab/activate-feature |
Install (if needed) and activate a feature plugin — wraps the existing features/{slug}:activate REST route |
install_plugins |
performance-lab/deactivate-feature |
Deactivate a feature plugin | activate_plugins |
performance-lab/get-server-timing-metrics |
Return the Server-Timing metrics that would be emitted for a given URL request | manage_options |
performance-lab/run-site-health-checks |
Run only the performance-related Site Health audits and return their results in a normalized shape | view_site_health_checks |
performance-lab/get-object-cache-dropin-status |
Report whether the object-cache drop-in is installed/managed by Performance Lab | manage_options |
Recommended ability categories
Register these once (in performance.php) so each plugin can attach to a shared taxonomy:
performance-lab— umbrella/feature managementperformance-lab/measurement— URL Metrics, Server-Timing, Site Health (optimization-detective, performance-lab)performance-lab/images— auto-sizes, dominant-color-images, image-prioritizer, webp-uploadsperformance-lab/navigation— speculation-rules, view-transitionsperformance-lab/scripts— web-worker-offloading, embed-optimizer
Cross-cutting design notes
- URL-shaped inputs. Many of these accept a
urlargument. The execute callback should normalize viahome_url()resolution and reject off-site URLs — otherwise an agent can poke arbitrary hosts through your endpoints. - Read-only flag matters. Anything labeled "get-" above should set
meta.readonly: trueso clients (and the WP AI client) can call them without confirmation prompts. - Permission callbacks should mirror existing UI gates — the same caps that protect Settings → Reading should protect
speculation-rules/update-settings, etc. Don't loosen them just because abilities feel "lighter" than REST. - Schema discipline. Every ability needs a JSON schema for both
input_schemaandoutput_schema— this is what makes them callable by AI clients vs. just being yet-another REST endpoint. - Where to register. Put each plugin's abilities in its existing
hooks.php(or a newabilities.phpincluded fromload.php) hooked onwp_abilities_api_init. Categories go onwp_abilities_api_categories_init.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Choose one plugin from the proposed list and start by reading its existing hooks.php or the load.php entry point. Check how wp_abilities_api_init and wp_abilities_api_categories_init are used, then define the requested ability schemas, permissions, and read-only metadata for that plugin. Done means one plugin has its abilities registered and the relevant REST or WP-CLI exposure works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100