Making WordPress.org

Changeset 14709


Ignore:
Timestamp:
03/13/2026 01:41:57 PM (6 weeks ago)
Author:
obenland
Message:

WordPress.org Abilities: Add validate-readme tool and refactor base class.

Add the validate-readme MCP tool for AI agents to validate plugin readme
files using the plugin directory's existing Validator class. Results are
returned as structured JSON with HTML messages converted to markdown.

Rename Resource_Base to Ability_Base since it now serves as the shared
base for tools, resources, and prompts. Move the plugin-directory
autoloader bootstrap and HTML-to-markdown conversion into it, removing
duplication from Reserved_Slugs. Remove redundant auth guidance from the
server description since the MCP adapter enforces authentication at the
session level.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities
Files:
2 added
8 edited
1 moved

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/class-mcp-server.php

    r14703 r14709  
    5555                    'WordPress.org MCP Server — provides tools, resources, and prompts for interacting with WordPress.org services.',
    5656                    'Use prompts/list to discover available workflows for specific tasks. Browse wporg://* resources for reference documentation.',
    57                     'All write operations require authentication via application password. To set up authentication, visit: https://login.wordpress.org/?action=authorize_application&app_id=c4c73a54-96d7-47b9-9bdc-1a66b9b04505',
    5857                )
    5958            ),
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/class-registrar.php

    r14703 r14709  
    5454        Plugin_Directory\Resources\Plugin_FAQ::register();
    5555
     56        // Tools.
     57        Plugin_Directory\Tools\Validate_Readme::register();
     58
    5659        // Prompts.
    5760        Plugin_Directory\Prompts\Prepare_Plugin::register();
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/plugins/plugin-directory/class-ability-base.php

    r14708 r14709  
    11<?php
    22/**
    3  * Base class for plugin directory resource abilities.
     3 * Base class for plugin directory abilities.
    44 *
    5  * Provides shared helpers for resources that pull content from
    6  * developer.wordpress.org (blog ID 33).
     5 * Provides shared utilities for abilities that interact with the
     6 * plugin-directory plugin or developer.wordpress.org content.
    77 *
    88 * @package WordPressdotorg\Abilities\Plugins\Plugin_Directory
     
    1616
    1717/**
    18  * Resource_Base class.
     18 * Ability_Base class.
    1919 */
    20 class Resource_Base {
     20class Ability_Base {
    2121
    2222    /**
     
    2626     */
    2727    const DEVELOPER_BLOG_ID = 33;
     28
     29    /**
     30     * Register the plugin-directory autoloader if it hasn't been loaded yet.
     31     *
     32     * This is needed when abilities reference classes from the plugin-directory
     33     * plugin (e.g. Readme\Validator, Trademarks) that may not be autoloaded yet.
     34     */
     35    protected static function maybe_load_plugin_directory(): void {
     36        static $loaded = false;
     37
     38        if ( $loaded ) {
     39            return;
     40        }
     41
     42        $autoloader = WP_PLUGIN_DIR . '/plugin-directory/class-autoloader.php';
     43
     44        if ( ! file_exists( $autoloader ) ) {
     45            return;
     46        }
     47
     48        require_once $autoloader;
     49        \WordPressdotorg\Plugin_Directory\Autoloader\register_class_path(
     50            'WordPressdotorg\\Plugin_Directory',
     51            WP_PLUGIN_DIR . '/plugin-directory'
     52        );
     53
     54        $loaded = true;
     55    }
     56
     57    /**
     58     * Convert HTML to markdown when available, falling back to plain text.
     59     *
     60     * Uses the wp_html_to_markdown() function from the html-to-md mu-plugin
     61     * when available. Falls back to stripping tags if the converter is not loaded.
     62     *
     63     * @param string $html The HTML string to convert.
     64     * @return string The converted text.
     65     */
     66    protected static function html_to_text( string $html ): string {
     67        if ( function_exists( 'wp_html_to_markdown' ) ) {
     68            return wp_html_to_markdown( $html );
     69        }
     70
     71        return wp_strip_all_tags( $html );
     72    }
    2873
    2974    /**
     
    63108        }
    64109
    65         $mime_type = 'text/html';
    66 
    67         if ( function_exists( 'wp_html_to_markdown' ) ) {
    68             $text      = wp_html_to_markdown( $text );
    69             $mime_type = 'text/markdown';
    70         }
     110        $text      = self::html_to_text( $text );
     111        $mime_type = function_exists( 'wp_html_to_markdown' ) ? 'text/markdown' : 'text/plain';
    71112
    72113        return array(
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/plugins/plugin-directory/prompts/class-prepare-plugin.php

    r14703 r14709  
    8787## Step 3: Validate readme.txt
    8888
    89 Use the `wporg/validate-readme` tool with the contents of `{$plugin_path}/readme.txt`.
     89Use the `wporg/plugins/plugin-directory/validate-readme` tool with the contents of `{$plugin_path}/readme.txt`.
    9090
    9191If no readme.txt exists, create one following the `wporg://plugins/plugin-directory/readme-standard` resource.
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/plugins/plugin-directory/resources/class-plugin-faq.php

    r14703 r14709  
    1010namespace WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resources;
    1111
    12 use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resource_Base;
     12use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Ability_Base;
    1313
    1414defined( 'ABSPATH' ) || exit;
     
    1717 * Plugin_FAQ class.
    1818 */
    19 class Plugin_FAQ extends Resource_Base {
     19class Plugin_FAQ extends Ability_Base {
    2020
    2121    /**
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/plugins/plugin-directory/resources/class-plugin-guidelines.php

    r14703 r14709  
    1010namespace WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resources;
    1111
    12 use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resource_Base;
     12use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Ability_Base;
    1313
    1414defined( 'ABSPATH' ) || exit;
     
    1717 * Plugin_Guidelines class.
    1818 */
    19 class Plugin_Guidelines extends Resource_Base {
     19class Plugin_Guidelines extends Ability_Base {
    2020
    2121    /**
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/plugins/plugin-directory/resources/class-plugin-headers.php

    r14703 r14709  
    1010namespace WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resources;
    1111
    12 use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resource_Base;
     12use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Ability_Base;
    1313
    1414defined( 'ABSPATH' ) || exit;
     
    1717 * Plugin_Headers class.
    1818 */
    19 class Plugin_Headers extends Resource_Base {
     19class Plugin_Headers extends Ability_Base {
    2020
    2121    /**
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/plugins/plugin-directory/resources/class-readme-standard.php

    r14703 r14709  
    1010namespace WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resources;
    1111
    12 use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resource_Base;
     12use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Ability_Base;
    1313
    1414defined( 'ABSPATH' ) || exit;
     
    1717 * Readme_Standard class.
    1818 */
    19 class Readme_Standard extends Resource_Base {
     19class Readme_Standard extends Ability_Base {
    2020
    2121    /**
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-abilities/plugins/plugin-directory/resources/class-reserved-slugs.php

    r14703 r14709  
    1010namespace WordPressdotorg\Abilities\Plugins\Plugin_Directory\Resources;
    1111
     12use WordPressdotorg\Abilities\Plugins\Plugin_Directory\Ability_Base;
    1213use WordPressdotorg\Plugin_Directory\Admin\Metabox\Review_Tools;
    1314use WordPressdotorg\Plugin_Directory\Trademarks;
     
    1819 * Reserved_Slugs class.
    1920 */
    20 class Reserved_Slugs {
     21class Reserved_Slugs extends Ability_Base {
    2122
    2223    /**
     
    4647     */
    4748    public static function execute(): array {
    48         self::maybe_load_plugin_directory_autoloader();
     49        self::maybe_load_plugin_directory();
    4950
    5051        if ( class_exists( Trademarks::class ) && class_exists( Review_Tools::class ) ) {
     
    6061                'mimeType' => 'text/markdown',
    6162            ),
    62         );
    63     }
    64 
    65     /**
    66      * Register the plugin-directory autoloader if it hasn't been loaded yet.
    67      */
    68     private static function maybe_load_plugin_directory_autoloader(): void {
    69         if ( class_exists( Trademarks::class, false ) ) {
    70             return;
    71         }
    72 
    73         $autoloader = WP_PLUGIN_DIR . '/plugin-directory/class-autoloader.php';
    74 
    75         if ( ! file_exists( $autoloader ) ) {
    76             return;
    77         }
    78 
    79         require_once $autoloader;
    80         \WordPressdotorg\Plugin_Directory\Autoloader\register_class_path(
    81             'WordPressdotorg\\Plugin_Directory',
    82             WP_PLUGIN_DIR . '/plugin-directory'
    8363        );
    8464    }
Note: See TracChangeset for help on using the changeset viewer.