Files
gh-emdashcodes-wp-ability-t…/skills/wordpress-ability-api/SKILL.md
2025-11-29 18:25:36 +08:00

486 lines
17 KiB
Markdown

---
name: wordpress-ability-api
description: This skill should be used when helping users create, edit, or register WordPress Abilities (both server-side PHP and client-side JavaScript), register ability categories, or set up the WordPress Abilities API as a dependency. Use when users say things like "create an ability", "help me build an ability", "set up the Ability API", or "register a category".
---
# WordPress Ability API
## Overview
This skill helps users work with the WordPress Abilities API - a standardized system for registering and discovering distinct units of functionality within WordPress. Use this skill to help users create server-side PHP abilities, client-side JavaScript abilities, register categories, and set up the API as a dependency.
The Abilities API makes WordPress functionality discoverable by AI agents and automation tools through machine-readable schemas, permissions, and validation.
## When to Use This Skill
Activate this skill when the user requests:
- **Creating abilities**: "Help me create an ability to...", "I want to make an ability that...", "Build me an ability for..."
- **Editing abilities**: "Update my ability", "Fix this ability code", "Modify the ability to..."
- **Setting up the API**: "Set up the Ability API", "Add the Ability API as a dependency", "Install the Abilities API"
- **Registering categories**: "Create a category for my abilities", "Register an ability category"
## Workflow Decision Tree
When this skill activates, determine what the user needs:
1. **Are they creating/editing an ability?**
→ Follow the "Creating Abilities" workflow below
2. **Do they need to set up the API first?**
→ Follow the "Setting Up the API" workflow below
3. **Are they just learning about the API?**
→ Reference the documentation in `references/` and explain concepts
## Using the Scaffold Script
The skill includes a `scripts/scaffold-ability.php` script designed for programmatic ability generation. Use this when creating abilities to quickly generate validated boilerplate code.
### Script Usage
```bash
php scripts/scaffold-ability.php \
--name="plugin/ability-name" \
--type="server" \
--category="data-retrieval" \
--label="Optional Label" \
--description="Optional description"
```
**Required Arguments:**
- `--name` - Ability name in format "namespace/ability-name"
- `--type` - Either "server" (PHP) or "client" (JavaScript)
- `--category` - Category slug (e.g., "data-retrieval", "data-modification")
**Optional Arguments:**
- `--label` - Human-readable label (auto-generated from name if omitted)
- `--description` - Detailed description (placeholder if omitted)
- `--readonly` - "true" or "false" (default: false)
- `--destructive` - "true" or "false" (default: true)
- `--idempotent` - "true" or "false" (default: false)
**Output:** Complete ability code printed to stdout, ready to be written to plugin files.
### When to Use the Scaffold Script
Use the scaffold script after gathering requirements from the user (Steps 1-3 of the workflow below). The script generates clean, validated boilerplate that follows best practices.
**Important:** Always gather required information from the user BEFORE calling the script, or generate sensible defaults based on context.
## Creating Abilities
When helping users create or edit abilities, follow this conversational workflow:
### Step 1: Understand the Functionality
Ask clarifying questions to understand what the ability should do:
- **What should this ability do?** (e.g., "Get site analytics", "Send notifications", "Update settings")
- **Is this a server-side or client-side ability?**
- **Server-side (PHP)**: Runs on the WordPress backend, accesses database, uses WordPress functions
- **Client-side (JavaScript)**: Runs in the browser, manipulates DOM, handles UI interactions
- **What input parameters does it need?** (e.g., user ID, date range, options)
- **What should it return?** (e.g., array of data, success boolean, error messages)
- **Who should be able to use it?** (permissions: any user, logged-in users, administrators, custom capability)
### Step 2: Determine Plugin Location
Ask where the ability code should live:
- **"Which plugin should this ability be registered in?"**
- If they have an existing plugin, use that
- If they need a new plugin, offer to create one using the `wordpress-plugin-scaffold` skill
### Step 3: Check for Category
Abilities must belong to a category. Ask:
- **"Which category should this ability belong to?"**
- Example categories: `data-retrieval`, `data-modification`, `communication`, `ecommerce`, `user-management`
- If they need a custom category, use `scripts/scaffold-category.php` to generate it:
```bash
php scripts/scaffold-category.php \
--name="custom-category" \
--label="Custom Category" \
--description="Description of what abilities belong here" \
--type="server|client"
```
- Alternatively, manually customize `assets/category-template.php`
- See `references/7.registering-categories.md` for detailed category registration information
### Step 4: Generate the Ability Code
Use the scaffold script to generate complete, validated code:
```bash
php scripts/scaffold-ability.php \
--name="namespace/ability-name" \
--type="server|client" \
--category="category-slug" \
--label="Human Label" \
--description="Detailed description" \
--readonly="true|false" \
--destructive="true|false" \
--idempotent="true|false"
```
**For server-side (PHP):** Outputs complete PHP code with callback and registration functions
**For client-side (JavaScript):** Outputs complete JavaScript code with async callback
Alternatively, manually copy and customize templates from `assets/` directory:
- `server-ability-template.php` - PHP abilities
- `client-ability-template.js` - JavaScript abilities
Replace all `{{PLACEHOLDERS}}` with actual values. See templates for full list of placeholders.
### Step 5: Validate the Code
Before adding the code to plugin files, validate it using the appropriate validation script:
#### Validate Abilities
**For PHP abilities:**
```bash
php scripts/validate-ability.php path/to/ability-file.php
```
**For JavaScript abilities:**
```bash
node scripts/validate-ability.js path/to/ability-file.js
```
#### Validate Categories
**For PHP categories:**
```bash
php scripts/validate-category.php path/to/category-file.php
```
**For JavaScript categories:**
```bash
node scripts/validate-category.js path/to/category-file.js
```
All validators check:
- **Structure**: Required fields (name, label, description, schemas/callbacks) are present
- **JSON Schema validity**: Schemas follow JSON Schema specification (abilities only)
- **Best practices**: Proper naming (kebab-case), annotations, permission callbacks
- **Common mistakes**: TODO placeholders, empty descriptions, security concerns
**Exit codes:**
- `0` - Validation passed
- `1` - Validation failed (errors found)
- `2` - File not found or invalid usage
Fix any errors reported by the validator before proceeding.
### Step 6: Add to Plugin Files
Write the validated code to the appropriate plugin files:
- **PHP abilities**: Add to plugin's main PHP file or create a dedicated `includes/abilities.php` file and hook into `abilities_api_init`
- **JavaScript abilities**: Add to enqueued JavaScript file with `@wordpress/abilities` dependency
- **Categories**: Register on `abilities_api_categories_init` hook before abilities
Use the Write tool to add the code to the correct location in the plugin.
### Step 7: Test the Ability
After code is added to plugin files, suggest testing approaches:
**Server-side (PHP):**
- Use `wp_get_ability('namespace/name')` to verify registration
- Test execution via REST API: `POST /wp-json/abilities/v1/abilities/{namespace}/{ability-name}/execute`
- Or test directly: `$ability->execute( $input_data )`
- Verify permissions work as expected
- Check input validation catches invalid data
**Client-side (JavaScript):**
- Open browser DevTools console
- Check registration: `wp.data.select('core/abilities').getAbility('namespace/ability-name')`
- Execute ability: `wp.data.dispatch('core/abilities').executeAbility('namespace/ability-name', inputData)`
- Check available abilities: `wp.data.select('core/abilities').getAbilities()`
- Verify permissions and error handling work correctly
## Setting Up the API
The WordPress Abilities API must be available before abilities can be registered. Help users set up the API based on their WordPress version:
### Check WordPress Version
**WordPress 6.9+**: The Abilities API is included in core - no setup needed!
**WordPress < 6.9**: The API must be installed as a plugin or dependency.
### Installation Options
Reference `references/2.getting-started.md` for detailed setup instructions. Guide users through the most appropriate method:
#### Option 1: As a Plugin (Easiest for Testing)
If they're using **wp-env** (check for `.wp-env.json`), help them add it via the `wp-env` skill:
```json
{
"plugins": ["WordPress/abilities-api"]
}
```
If they're using **WP-CLI**:
```bash
wp plugin install https://github.com/WordPress/abilities-api/releases/latest/download/abilities-api.zip
wp plugin activate abilities-api
```
#### Option 2: As a Plugin Dependency (Recommended for Plugins)
Help them add to their plugin header:
```php
/**
* Plugin Name: My Plugin
* Requires Plugins: abilities-api
*/
```
Then add availability check:
```php
if ( ! class_exists( 'WP_Ability' ) ) {
add_action( 'admin_notices', function() {
wp_admin_notice(
__( 'This plugin requires the Abilities API. Please install and activate it.', 'my-plugin' ),
'error'
);
} );
return;
}
```
#### Option 3: As a Composer Dependency
```bash
composer require wordpress/abilities-api
```
### Verify Installation
Help users verify the API is loaded:
```php
if ( class_exists( 'WP_Ability' ) ) {
// API is available
echo 'Abilities API version: ' . WP_ABILITIES_API_VERSION;
}
```
## Integration with Other Skills
This skill works well with:
- **wordpress-plugin-scaffold**: Use when users need a new plugin to register abilities in
- **wp-env**: Use for local development environment setup when installing the Abilities API
## Reference Documentation
The `references/` directory contains complete API documentation:
- **1.intro.md**: Core concepts, goals, and benefits of the Abilities API
- **2.getting-started.md**: Installation methods and basic usage examples
- **3.registering-abilities.md**: Comprehensive guide to `wp_register_ability()` with all parameters and examples
- **4.using-abilities.md**: How to retrieve and execute abilities in PHP
- **5.rest-api.md**: REST API endpoints for abilities
- **6.hooks.md**: Available WordPress hooks in the Abilities API
- **7.javascript-client.md**: Complete client-side JavaScript API reference
- **7.registering-categories.md**: How to register ability categories
**When to read references:**
- For specific parameter details → `3.registering-abilities.md`
- For setup instructions → `2.getting-started.md`
- For client-side abilities → `7.javascript-client.md`
- For category registration → `7.registering-categories.md`
- For conceptual understanding → `1.intro.md`
## Scripts and Templates
### Scripts (`scripts/`)
The skill includes automation scripts for generating and validating both abilities and categories:
#### Ability Scripts
- **scaffold-ability.php**: Programmatically generate ability code from CLI arguments
- Accepts: name, type, category, label, description, and annotation flags
- Outputs: Complete, validated ability code to stdout
- Usage: `php scripts/scaffold-ability.php --name="plugin/ability" --type="server" --category="data-retrieval"`
- Use when: Creating new abilities after gathering requirements
- **validate-ability.php**: Validate PHP ability code independently of WordPress
- Checks: Required fields, JSON Schema validity, best practices
- Outputs: Detailed validation results with errors and warnings
- Usage: `php scripts/validate-ability.php path/to/ability-file.php`
- Use when: Validating server-side PHP ability code before registration
- **validate-ability.js**: Validate JavaScript ability registration code
- Requirements: Node.js and acorn parser (`npm install acorn`)
- Parser: Uses acorn AST parser for accurate JavaScript parsing
- Checks: Required fields (name, category, callback), name format, schemas, permissions, annotations
- Outputs: Detailed validation results with errors and warnings
- Usage: `node scripts/validate-ability.js path/to/ability-file.js`
- Use when: Validating client-side JavaScript ability code before registration
#### Category Scripts
- **scaffold-category.php**: Programmatically generate category registration code
- Accepts: name, label, description, type (server/client)
- Outputs: Complete category registration code to stdout
- Usage: `php scripts/scaffold-category.php --name="category-slug" --label="Label" --description="Description" --type="server"`
- Use when: Creating custom categories for abilities
- Includes helpful comments about registration hooks and timing
- **validate-category.php**: Validate PHP category registration code
- Parser: Uses PHP's `token_get_all()` for accurate parsing
- Checks: Name format (kebab-case), required fields, description quality
- Outputs: Detailed validation results with errors and warnings
- Usage: `php scripts/validate-category.php path/to/category-file.php`
- Use when: Validating server-side PHP category code
- **validate-category.js**: Validate JavaScript category registration code
- Requirements: Node.js and acorn parser (`npm install acorn`)
- Parser: Uses acorn AST parser for accurate JavaScript parsing
- Checks: Same validations as PHP validator
- Outputs: Detailed validation results with errors and warnings
- Usage: `node scripts/validate-category.js path/to/category-file.js`
- Use when: Validating client-side JavaScript category code
### Template Assets (`assets/`)
The skill also includes manual starter templates:
- **server-ability-template.php**: Complete boilerplate for server-side PHP abilities
- **client-ability-template.js**: Complete boilerplate for client-side JavaScript abilities
- **category-template.php**: Template for server-side PHP category registration
- **client-category-template.js**: Template for client-side JavaScript category registration
**Note:** Templates use `{{PLACEHOLDER}}` syntax and are read by scaffold scripts. You can also manually copy and replace placeholders for custom needs. Scaffold scripts generate code by loading these templates and replacing placeholders with actual values.
## Best Practices
When helping users create abilities:
1. **Use descriptive names**: `my-plugin/get-user-analytics` not `my-plugin/analytics`
2. **Write detailed descriptions**: Help AI agents understand WHEN and HOW to use the ability
3. **Define complete schemas**: Use JSON Schema to validate inputs and document outputs
4. **Implement proper permissions**: Never use `__return_true` for sensitive operations
5. **Use appropriate annotations**:
- `readonly: true` for data retrieval abilities
- `destructive: false` for abilities that only add/update (never delete)
- `idempotent: true` for abilities that can be called repeatedly safely
6. **Handle errors gracefully**: Return `WP_Error` objects with clear error messages
7. **Test thoroughly**: Verify schema validation, permissions, and error cases
## Common Patterns
### Read-Only Data Retrieval
```php
'meta' => array(
'annotations' => array(
'readonly' => true,
'destructive' => false,
'idempotent' => true,
),
)
```
### Data Modification (Non-Destructive)
```php
'meta' => array(
'annotations' => array(
'readonly' => false,
'destructive' => false,
'idempotent' => false,
),
)
```
### Potentially Destructive Operations
```php
'meta' => array(
'annotations' => array(
'readonly' => false,
'destructive' => true,
'idempotent' => false,
),
),
'permission_callback' => function() {
return current_user_can( 'manage_options' );
}
```
## Advanced Features
### Client-Side Category Registration
When registering client-side abilities with custom categories, use `registerAbilityCategory()` before registering the ability:
```javascript
import { registerAbilityCategory, registerAbility } from '@wordpress/abilities';
// Register the category first
await registerAbilityCategory('my-custom-category', {
label: 'My Custom Category',
description: 'Description of what abilities belong in this category',
meta: {
icon: 'dashicons-admin-customizer',
priority: 10,
},
});
// Then register abilities using that category
await registerAbility({
name: 'my-plugin/my-ability',
category: 'my-custom-category', // Uses the client-registered category
// ... other properties
});
```
### Custom Ability Classes (Advanced)
For advanced use cases requiring custom behavior, specify a custom class that extends `WP_Ability` using the `ability_class` parameter:
```php
class Custom_Ability extends WP_Ability {
// Override methods for custom behavior
public function execute( $input = array() ) {
// Custom execution logic
return parent::execute( $input );
}
}
wp_register_ability( 'my-plugin/custom-ability', array(
// ... standard parameters
'ability_class' => Custom_Ability::class, // Use custom class instead of WP_Ability
) );
```
**Note:** This is an advanced feature. Most abilities should use the default `WP_Ability` class.