Skip to content

Add wp connectors list and wp connectors get commands#9

Merged
swissspidy merged 15 commits intomainfrom
copilot/add-connectors-command
Mar 11, 2026
Merged

Add wp connectors list and wp connectors get commands#9
swissspidy merged 15 commits intomainfrom
copilot/add-connectors-command

Conversation

Copy link
Contributor

Copilot AI commented Mar 5, 2026

Exposes the WP 7.0 connector registry (_wp_connectors_get_connector_settings()) via two new WP-CLI commands, giving operators visibility into available AI providers and their configuration state.

New commands

  • wp connectors list — tabular view of all registered connectors. Default columns: name, description, status. Additional fields (type, auth_method, plugin_slug, credentials_url) are available via --fields. Supports --status filtering and --format (table/csv/json/yaml).
  • wp connectors get <connector> — detail view for a single connector rendered as a Field/Value pivot table (like wp post get). Default fields: name, description, status, credentials_url, api_key (masked, via WP core's option_* filter). Additional fields (type, auth_method, plugin_slug) available via --fields.

The status column reflects the connector's current state:

  • connected — an API key is configured
  • active — the provider plugin is active (or the provider is registered directly without a plugin slug)
  • installed — the plugin is installed but not activated
  • not installed — the plugin is not present

Plugin install/active status is resolved by matching the connector's plugin.slug against get_plugins() output.

$ wp connectors list
+-----------+-----------------------------------------------+---------------+
| name      | description                                   | status        |
+-----------+-----------------------------------------------+---------------+
| Anthropic | Text generation with Claude.                  | not installed |
| Google    | Text and image generation with Gemini...      | not installed |
| OpenAI    | Text and image generation with GPT and Dall-E | connected     |
+-----------+-----------------------------------------------+---------------+

$ wp connectors list --status=connected
+-----------+-----------------------------------------------+-----------+
| name      | description                                   | status    |
+-----------+-----------------------------------------------+-----------+
| OpenAI    | Text and image generation with GPT and Dall-E | connected |
+-----------+-----------------------------------------------+-----------+

$ wp connectors get openai
+-----------------+-----------------------------------------------+
| Field           | Value                                         |
+-----------------+-----------------------------------------------+
| name            | OpenAI                                        |
| description     | Text and image generation with GPT and Dall-E |
| status          | connected                                     |
| credentials_url | https://platform.openai.com/api-keys          |
| api_key         | ••••••••••••6789                              |
+-----------------+-----------------------------------------------+

Removed

The wp ai credentials family of commands (list, get, set, delete) has been removed. API keys can be managed directly via wp option update <setting_name> <value>.

Tests

Behat scenarios cover: built-in provider listing with name, description, and status fields; not installed / active / connected status transitions; --status filter; get pivot layout with masked API key; --fields filtering including hidden fields; error on unknown connector ID; installing the OpenAI provider plugin to flip status; filtering by active status; and a community plugin (ai-provider-for-azure-openai) appearing in the list with status: active.

Original prompt

This section details on the original issue you should resolve

<issue_title>Add connectors command</issue_title>
<issue_description>This is a follow up to #6 and #7.

We should add wp connectors list and wp connectors get commands that uses _wp_connectors_get_connector_settings to display information about the available connectors (name, description, status, api key, auth method, etc).

The plugin slug is available there so we can show whether the connector is installed or not.

See https://github.com/WordPress/wordpress-develop/blob/5f0ac6faf6a1ddd567009fe3a33fb029b6dbcc4a/src/wp-includes/connectors.php#L118 for that code.

We could add tests that install the plugins for the default providers (openai, anthropic, google) and even install a community plugin such as https://github.com/zaherg/ai-provider-for-openrouter and verify that it shows up in the connectors list.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@github-actions github-actions bot added command:ai-credentials-get Related to 'ai credentials get' command command:ai-credentials-list Related to 'ai credentials list' command enhancement New feature or request scope:distribution Related to distribution scope:testing Related to testing labels Mar 5, 2026
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Copilot AI changed the title [WIP] Add connectors command to manage plugins Add wp connectors list and wp connectors get commands Mar 5, 2026
@swissspidy

This comment was marked as resolved.

…gin_slug/type/auth_method by default

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

…ove credentials commands

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@codecov
Copy link

codecov bot commented Mar 11, 2026

Codecov Report

❌ Patch coverage is 0% with 90 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Connectors_Command.php 0.00% 90 Missing ⚠️

📢 Thoughts on this report? Let us know!

@swissspidy swissspidy marked this pull request as ready for review March 11, 2026 15:24
Copilot AI review requested due to automatic review settings March 11, 2026 15:24
@swissspidy swissspidy merged commit 4f91b63 into main Mar 11, 2026
54 of 55 checks passed
@swissspidy swissspidy deleted the copilot/add-connectors-command branch March 11, 2026 15:24
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds new WP-CLI surface area for inspecting WordPress 7.0’s connector registry, replacing the removed wp ai credentials command family with read-only visibility into connector availability and configuration.

Changes:

  • Introduces wp connectors list and wp connectors get commands backed by _wp_connectors_get_connector_settings().
  • Removes wp ai credentials commands and their Behat coverage; updates command registration/docs accordingly.
  • Adds Behat coverage for connector listing, filtering, status detection, and per-connector detail output.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/Credentials_Command.php Removes the legacy credentials management command implementation.
src/Connectors_Command.php Adds the new connectors command with list and get subcommands and status resolution logic.
src/AI_Command.php Docblock formatting fix for --stdout option.
features/credentials.feature Removes Behat scenarios for deleted credentials commands.
features/connectors.feature Adds Behat scenarios covering the new connectors commands and status behaviors.
composer.json Updates declared commands and adds dev dependencies needed by tests (option/plugin commands).
ai-command.php Registers the new connectors command and removes the old credentials command registration.
README.md Regenerates/updates docs to reflect command changes and minimum WP-CLI version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +294 to +305
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}

$active_plugins = (array) get_option( 'active_plugins', array() );
foreach ( $active_plugins as $plugin_file ) {
if ( ! is_string( $plugin_file ) ) {
continue;
}
if ( strpos( $plugin_file, $slug . '/' ) === 0 || $plugin_file === $slug . '.php' ) {
return true;
}
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

is_plugin_active() currently checks only the active_plugins option, which will misreport status on multisite where plugins can be network-activated via active_sitewide_plugins. Consider resolving the actual plugin file via get_plugins() and then using WordPress core’s is_plugin_active()/is_plugin_active_for_network() APIs (or checking both active plugin sources) so status is accurate in all setups.

Suggested change
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$active_plugins = (array) get_option( 'active_plugins', array() );
foreach ( $active_plugins as $plugin_file ) {
if ( ! is_string( $plugin_file ) ) {
continue;
}
if ( strpos( $plugin_file, $slug . '/' ) === 0 || $plugin_file === $slug . '.php' ) {
return true;
}
if ( ! function_exists( 'is_plugin_active' ) || ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$plugins = get_plugins();
foreach ( $plugins as $plugin_file => $plugin_data ) {
if ( ! is_string( $plugin_file ) ) {
continue;
}
if ( strpos( $plugin_file, $slug . '/' ) !== 0 && $plugin_file !== $slug . '.php' ) {
continue;
}
if ( is_plugin_active( $plugin_file ) ) {
return true;
}
if ( function_exists( 'is_multisite' ) && is_multisite() && function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( $plugin_file ) ) {
return true;
}

Copilot uses AI. Check for mistakes.
Comment on lines +273 to +283
private function is_plugin_installed( string $slug ): bool {
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}

foreach ( array_keys( get_plugins() ) as $plugin_file ) {
if ( strpos( $plugin_file, $slug . '/' ) === 0 || $plugin_file === $slug . '.php' ) {
return true;
}
}

Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

is_plugin_installed() calls get_plugins() and scans the full plugin list. Because get_connector_status() can invoke this per connector, listing many connectors can repeatedly perform expensive filesystem scans. Consider caching the results of get_plugins() (and the active plugin list) once per command invocation and reusing them for all connectors.

Copilot uses AI. Check for mistakes.
Comment on lines +25 to +29
protected $default_fields = [
'name',
'description',
'status',
];
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

This file introduces short array syntax ([...]) for $default_fields, but the rest of the codebase appears to consistently use long array syntax (array(...)) (e.g., src/AI_Command.php). For consistency with existing style (and to avoid PHPCS/WPCS mismatches), consider switching this to array(...).

Suggested change
protected $default_fields = [
'name',
'description',
'status',
];
protected $default_fields = array(
'name',
'description',
'status',
);

Copilot uses AI. Check for mistakes.

```bash
wp package install wp-cli/ai-command:dev-main
wp package install wp-cli/ai-command:dev-master
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

The install snippet uses wp package install wp-cli/ai-command:dev-master. If the repository’s development branch is main (as is common now), this reference will fail for users. Consider updating the command to the correct dev branch name (e.g., dev-main) and aligning composer.json branch-alias accordingly.

Suggested change
wp package install wp-cli/ai-command:dev-master
wp package install wp-cli/ai-command:dev-main

Copilot uses AI. Check for mistakes.
Comment on lines +197 to +199
Scenario: Community plugin shows up in connectors list
When I run `wp plugin install https://github.com/aslamdoctor/ai-provider-for-grok/archive/refs/heads/master.zip --activate`
And I run `wp connectors list --format=json`
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

This scenario installs a community plugin from a GitHub master.zip URL (ai-provider-for-grok), but the PR description states the community-plugin coverage is for a different plugin. Please align the scenario with the PR description (or update the description). Also consider pinning to a tagged release/commit archive (or a WordPress.org slug) to avoid CI breakage if the upstream branch changes.

Copilot uses AI. Check for mistakes.
$item = $this->build_connector_item( $connector_id, $connector );

// Retrieve and append the (possibly masked) API key.
$auth = is_array( $connector['authentication'] ) ? $connector['authentication'] : array();
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

$connector['authentication'] is accessed directly and passed to is_array(). If the key is missing, PHP will raise an "Undefined index" notice. Use a null-coalescing/isset() guard before reading the key so connectors without an authentication block don’t generate warnings.

Suggested change
$auth = is_array( $connector['authentication'] ) ? $connector['authentication'] : array();
$auth = ( isset( $connector['authentication'] ) && is_array( $connector['authentication'] ) ) ? $connector['authentication'] : array();

Copilot uses AI. Check for mistakes.
Comment on lines +202 to +205
private function build_connector_item( string $connector_id, array $connector ): array {
$auth = is_array( $connector['authentication'] ) ? $connector['authentication'] : array();
$plugin = isset( $connector['plugin'] ) && is_array( $connector['plugin'] ) ? $connector['plugin'] : array();
$plugin_slug = isset( $plugin['slug'] ) && is_string( $plugin['slug'] ) ? $plugin['slug'] : '';
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

$connector['authentication'] is read without an isset()/null-coalescing guard (same pattern as in get()), which can emit an "Undefined index" notice if a connector doesn’t define authentication. Consider normalizing $auth via $connector['authentication'] ?? [] and validating it’s an array before use.

Copilot uses AI. Check for mistakes.
# Plugin requires PHP 7.4.
@require-wp-7.0 @require-php-7.4
Scenario: Community plugin shows up in connectors list
When I run `wp plugin install https://github.com/aslamdoctor/ai-provider-for-grok/archive/refs/heads/master.zip --activate`
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

This Behat scenario installs and activates a third-party WordPress plugin directly from a mutable GitHub branch URL (master) on every test run, without pinning to an immutable commit or verifying integrity. If that external repository is ever compromised or the maintainer pushes malicious code, running the test suite (e.g., in CI) will execute attacker-controlled PHP with access to the test environment and potentially build artifacts or secrets. To mitigate this supply chain risk, pin the download to a specific release or commit (or host a vetted mirror under your control) and, where possible, verify the download via checksum or signature before installation.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

command:ai-credentials-get Related to 'ai credentials get' command command:ai-credentials-list Related to 'ai credentials list' command enhancement New feature or request scope:distribution Related to distribution scope:testing Related to testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add connectors command

3 participants