Skip to content

Conversation

spenserhale
Copy link

To use Composer for installing into the plugins folder, the type should be 'wordpress-plugin'.
To use Composer as commonly set up for WordPress, and in the mcp-adapter README, the type should be updated.

Docs:

With Composer

Until the plugin is available on Packagist, you will need to add the repository to your composer.json file.

{
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/WordPress/abilities-api.git"
    },
    // ... other repositories.
  ],
  "extra": {
    "installer-paths": {
      // This should match your WordPress+Composer setup.
      "wp-content/plugins/{$name}/": [
          "type:wordpress-plugin"
      ]
      // .. other paths.
    }
  }
  // ... rest of your composer.json.
}

Then, require the package in your project:

composer require wordpress/abilities-api

To use Composer for installing into the plugins folder, the type should be 'wordpress-plugin'.
Copy link

github-actions bot commented Sep 11, 2025

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: spenserhale <[email protected]>
Co-authored-by: justlevine <[email protected]>
Co-authored-by: felixarntz <[email protected]>
Co-authored-by: jonathanbossenger <[email protected]>
Co-authored-by: gziolo <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link

codecov bot commented Sep 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.22%. Comparing base (118c476) to head (2b9cf64).

Additional details and impacted files
@@            Coverage Diff            @@
##              trunk      #66   +/-   ##
=========================================
  Coverage     84.22%   84.22%           
  Complexity       96       96           
=========================================
  Files             8        8           
  Lines           507      507           
=========================================
  Hits            427      427           
  Misses           80       80           
Flag Coverage Δ
unit 84.22% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gziolo gziolo added the [Tool] Issues related to development tooling, such as linting, testing, or CI label Sep 11, 2025
Copy link
Contributor

@justlevine justlevine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR @spenserhale🙇

I've shared my thoughts a few times:
AFAIK this change only benefits us and has ZERO downsides.

(Imo it should be part of #51 and added to the PR description for props-bot)

@Jameswlepage / @jeffpaul / @felixarntz - It would be really helpful to know why y'all vetoed this previously so we can either have a transparent conversation about it, or minimally document the decision and its rationale so we have something to point to when this gets brought up by others in the future.

Copy link
Member

@felixarntz felixarntz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spenserhale Thank you for the PR!

I'm marking this as requesting changes purely to clarify that it shouldn't be merged until a decision is made whether we want to do this - as we previously consciously decided against it.

@felixarntz
Copy link
Member

@justlevine Sharing some of my thoughts:

  • We have this on Packagist for the use-case where people want to consume this as a package/library, e.g. bundling in a WordPress plugin.
  • As far as I'm aware, it was planned to also release this as a plugin on WordPress.org. That would automatically create a WordPress plugin on WPackagist.

This is why I believe we should maintain the library type on Packagist - it's meant to be used as a library. If you want to install this as a plugin and still use Composer, the recommended approach would be the WPackagist route.

@justlevine
Copy link
Contributor

justlevine commented Sep 15, 2025

Thanks very much for sharing @felixarntz 🙇

  • I would like to point out that the "bundling" use case is (afaik) a short term solution until the Abilities API is shipped into WordPress core in 2.5 months, so it's hard to say that it's "recommended" to use this via Packagist or a future theoretical WPackagist.
  • Also reminder, you can use wpackagist-plugin/* as a pure Composer library (see how we use Plugin Check), so it hard to accept a philosophical argument like " it's meant to be used as a library" when "type:wordpress-plugin" is completely identical to a "type:library" unless a user explicitly opts-in by updating their composer.json to map that type to a specific location. It's a 100% additive change.

It's even harder to accept this when currently, this repo is not on w.org so this isn't just arbitrarily forcing people to install via a different source, it prevents anyone from using Abilities API as a Composer-managed plugin at all.

Doubly when the request is now coming from a person who isnt on the core AI team. This is no longer theoretical, it's actual friction preventing experimentation with the Abilities API.

@jonathanbossenger
Copy link
Contributor

Referring to the original post announcing the Abilities API: https://make.wordpress.org/ai/2025/07/17/abilities-api/

AFAIK, it was never the plan to make the Abilities API available as a plugin on WordPress.org, this is what the AI Experiements plugin was supposed to be.

So my question here is, at what point was it decided to turn this into an installable plugin? What's the specific use case that we decided it needed to work as a plugin and not be used as a library via Composer?

@gziolo
Copy link
Member

gziolo commented Sep 16, 2025

So my question here is, at what point was it decided to turn this into an installable plugin? What's the specific use case that we decided it needed to work as a plugin and not be used as a library via Composer?

There were several discussions related to that, the idea is to have a featured plugin that helps to explore more ideas before they land in WordPress core after 6.9. One example that comes to my mind:

@justlevine
Copy link
Contributor

justlevine commented Sep 16, 2025

So my question here is, at what point was it decided to turn this into an installable plugin? What's the specific use case that we decided it needed to work as a plugin and not be used as a library via Composer?

There were several discussions related to that, the idea is to have a featured plugin that helps to explore more ideas before they land in WordPress core after 6.9.

There were also a handful of discussions as why for pre-6.9 it makes sense to also make this installable as a plugin (though not necessarily submitted to w.org due to the short timeline) . I'm AFK so I cant rly link dive right now, but iirc it boiled down to the following:

  1. Easier migration path to WP6.9 for early adopters
  2. Better conflict resolution between multiple projects/versions/ (e.g. MCP Adapter + Experiments on the same site, let alone anything 3rd-party)
  3. Most importantly it's no-cost additive that makes it easier for people to quickly test and give feedback on the Abilities API. This has been the Core AI team's driving factor for most architecture decisions across the different repos: merging quickly to prioritize real-world feedback instead of the usual WordPress contribution flows/rubberducking/etc.

@jonathanbossenger
Copy link
Contributor

@gziolo @justlevine thanks for the context.

Follow-up question.

I only use Composer to manage dependencies for plugins, not install plugins for Composer-managed WordPress site builds.

My understanding was that the recommended way to install plugins in a Composer-managed site build requires the use of https://wpackagist.org/, which requires the plugin to be available on WordPress.org.

To the best of my knowledge, the only other way to install plugins on composer-managed WordPress sites is to manually configure and install them from the GitHub repository, as described in the original issue description. There's no way to composer require wordpress/abilities-api and it installs it from packagist.org?

Happy to be corrected here if I am wrong.

@justlevine
Copy link
Contributor

justlevine commented Sep 16, 2025

My understanding was that the recommended way to install plugins in a Composer-managed site build requires the use of https://wpackagist.org/, which requires the plugin to be available on WordPress.org.

There's a bit more nuance to this. WPackagist mirrors W.org, automatically creating a composer-installable facade so those plugins can

  • a) get notified of version updates
  • b) be mappable to wp-content/plugins. (It uses wpackagist-plugin as the library subtype for mapping instead of wordpress-plugin)

It's recommended inasmuch as W.org is recommended (vs a GitHub tagged release asset) and because it doesn't require the developer to explicitly make their plugin/theme Composer-installable.

(It also includes the Installer Paths library

To the best of my knowledge, the only other way to install plugins on composer-managed WordPress sites is to manually configure and install them from the GitHub repository, as described in the original issue description. There's no way to composer require wordpress/abilities-api and it installs it from packagist.org?

Mostly true. In order for Composer to autoinstall packages into a folder other than vendor

  1. A targetable library sub"type" in the package's composer.json
  2. An extra.installer-paths in the consumer's composer.json that maps the type to the location (ie what's in the issue description).

That said, the consumer can still manually require composer/installers and then map using just the package name e.g.

...
  "installer-paths": {
      ... The existing library type mapping
      "path/to/wp-content/plugins/{$name}/": [ "wordpress/abilities-api" ]
        }

But the user would need to be aware that their existing type-based mappings aren't working for abilities-api, that it's not some composer/plugin bug but how our composer.json is configured, and that there's an API to let them manually map per-package.

So worst case docs (and now this PR discussion) provides a troubleshooting path forward if we keep using "type:library",

(but since docs don't fix bad DX we'd ideally have a practical justification for the unnecessary friction)

@jonathanbossenger
Copy link
Contributor

Got it, thanks @justlevine

Based on that, would it correct to say that it's posssible to require abilities-api as a dependancy in a custom plugin which can be created as type:wordpress-plugin, and then that plugin is installed in the correct way to a composer managed WordPress site?

I understand your POV about DX and making it easier for folks to install and test this out, but I also see the POV that this code is just a library, not what one would consider a fully fledged plugin. It contains no specific functionality other than the underlying API, so I can see how the core AI team reps would want to keep it "tagged" as a library.

If we adapt our installation steps to indicate this fact, and include the instructions to correctly installing and using this library as a dependancy of a custom plugin, we acheive both goals.

@justlevine
Copy link
Contributor

justlevine commented Sep 17, 2025

@jonathanbossenger not sure I understood, so please correct/redirect me:

but I also see the POV that this code is just a library, not what one would consider a fully fledged plugin.

I think this is the root of the discrepancy so starting here and going backwards.

If I understood this correctly, you're using "library" and "plugin" colloquially (from a user pov), while I (and Composer) are using the technical definition:

  • A Composer library is a collection of PHP classes/methods/etc that can be consumed by other projects.
  • A WordPress plugin integrates with WordPress to provide functionality (including implementing/accessing stuff from that library library ).

Good illustration of the practical difference in definitions, is how php-ai-client (a library) is made available to WordPress by wp-ai-client (a plugin), which is also currently a Composer "type":"library" and will follow the keep/change decision we make here.

Another example of Core prior art is the REST API. Colloquially it's identical to the Abilities API in that it wasn't a "fully fledged plugin" from a user POV, but a wordpress-plugin from Composer's POV. (PS: that part of what shaped Plugin Dependencies, making plugin as a (colloquial) library a natively recommend alternative to Composer and "pure" libraries. )

So with that in mind:

would it correct to say that it's posssible to require abilities-api as a dependancy in a custom plugin which can be created as type:wordpress-plugin, and then that plugin is installed in the correct way to a composer managed WordPress site?

Abilities API is already a plugin and already used as a plugin. Even the internal Composer setup behaves "as a plugin" (autoinitializing the endpoint and not like a "pure library". #55 is just one of several examples where the decision explicitly and intentionally conflicted with the stated reasons for "type:library", but unlike this PR created actual problems for using Abilities API as a pure Composer library).

I'm not sure if the suggestion is that:

  • we remove all that so this repo can only be consumed by installing via composer (like php-ai-client),or
  • create and maintaining an additional repo just so we can add an additional composer.json (like wpackagist but with all the contributor overhead)
  • (maybe something else)?

IMO either would be worse than the existing status quo, where the friction is only limited to Composer-based WP installations and can be troubleshooted/worked around via docs (and from a "meta" ensuring that we're proceeding consistently when there are practical tradeoffs, which is the real import to finally having this conversation and why I won't shut up abt it 😅)

@justlevine
Copy link
Contributor

(and from a "meta" ensuring that we're proceeding consistently when there are practical tradeoffs, which is the real import to finally having this conversation and why I won't shut up abt it 😅)

Case in point:

We need to decide how to handle the built client assets. A "real" library wouldn't be enqueuing assets into WordPress, but since other decisions have already turned this repo into a "library-in-name-only" we need an approach on how to build and bundle these assets if a user wants to composer require this as a Composer library or a plugin.

The weight of the downsides is exacerbated by our inconsistency which makes it hard to recommend the optimal solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Tool] Issues related to development tooling, such as linting, testing, or CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants