Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions data-machine.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ function () {
// Agent auth callback handler (receives tokens from external DM instances).
new \DataMachine\Core\Auth\AgentAuthCallback();

// Register ability categories first — must happen before any ability registration.
require_once __DIR__ . '/inc/Abilities/AbilityCategories.php';
\DataMachine\Abilities\AbilityCategories::ensure_registered();

// Load abilities
require_once __DIR__ . '/inc/Abilities/AuthAbilities.php';
require_once __DIR__ . '/inc/Abilities/File/FileConstants.php';
Expand Down
159 changes: 159 additions & 0 deletions inc/Abilities/AbilityCategories.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?php
/**
* Ability Categories
*
* Centralized registration of all Data Machine ability categories.
* Each category groups related abilities for discoverability, tool
* scoping (pipeline tool filtering), permission boundaries, and
* MCP/REST API organization.
*
* @package DataMachine\Abilities
* @since 0.55.0
*/

namespace DataMachine\Abilities;

defined( 'ABSPATH' ) || exit;

class AbilityCategories {

/**
* Category slug constants for use in ability registrations.
*
* Extension plugins should define their own constants or use string
* literals following the same naming convention.
*/
public const CONTENT = 'datamachine/content';
public const MEDIA = 'datamachine/media';
public const ANALYTICS = 'datamachine/analytics';
public const SEO = 'datamachine/seo';
public const MEMORY = 'datamachine/memory';
public const TAXONOMY = 'datamachine/taxonomy';
public const PUBLISHING = 'datamachine/publishing';
public const FETCH = 'datamachine/fetch';
public const EMAIL = 'datamachine/email';
public const PIPELINE = 'datamachine/pipeline';
public const FLOW = 'datamachine/flow';
public const JOBS = 'datamachine/jobs';
public const AGENT = 'datamachine/agent';
public const SETTINGS = 'datamachine/settings';
public const AUTH = 'datamachine/auth';
public const LOGGING = 'datamachine/logging';
public const SYSTEM = 'datamachine/system';
public const CHAT = 'datamachine/chat';

private static bool $registered = false;

/**
* Register all Data Machine ability categories.
*
* Safe to call multiple times — uses a static guard.
* Should be called on `wp_abilities_api_categories_init` or
* via did_action() check.
*/
public static function register(): void {
if ( self::$registered ) {
return;
}

$categories = array(
self::CONTENT => array(
'label' => __( 'Content', 'data-machine' ),
'description' => __( 'Content querying, editing, searching, and block operations.', 'data-machine' ),
),
self::MEDIA => array(
'label' => __( 'Media', 'data-machine' ),
'description' => __( 'Image generation, alt text, media upload, validation, and optimization.', 'data-machine' ),
),
self::ANALYTICS => array(
'label' => __( 'Analytics', 'data-machine' ),
'description' => __( 'Google Analytics, Search Console, Bing Webmaster, and PageSpeed.', 'data-machine' ),
),
self::SEO => array(
'label' => __( 'SEO', 'data-machine' ),
'description' => __( 'Internal linking, meta descriptions, and IndexNow.', 'data-machine' ),
),
self::MEMORY => array(
'label' => __( 'Memory', 'data-machine' ),
'description' => __( 'Agent memory, daily journals, and agent file management.', 'data-machine' ),
),
self::TAXONOMY => array(
'label' => __( 'Taxonomy', 'data-machine' ),
'description' => __( 'Taxonomy term CRUD and resolution.', 'data-machine' ),
),
self::PUBLISHING => array(
'label' => __( 'Publishing', 'data-machine' ),
'description' => __( 'WordPress publishing, email sending, and post updates.', 'data-machine' ),
),
self::FETCH => array(
'label' => __( 'Fetch', 'data-machine' ),
'description' => __( 'RSS, WordPress API, media, files, and email fetching.', 'data-machine' ),
),
self::EMAIL => array(
'label' => __( 'Email', 'data-machine' ),
'description' => __( 'Email management — reply, delete, move, flag, unsubscribe.', 'data-machine' ),
),
self::PIPELINE => array(
'label' => __( 'Pipeline', 'data-machine' ),
'description' => __( 'Pipeline CRUD, step management, handler and step-type discovery.', 'data-machine' ),
),
self::FLOW => array(
'label' => __( 'Flow', 'data-machine' ),
'description' => __( 'Flow CRUD, scheduling, queue management, and webhook triggers.', 'data-machine' ),
),
self::JOBS => array(
'label' => __( 'Jobs', 'data-machine' ),
'description' => __( 'Job management, health monitoring, recovery, and workflow execution.', 'data-machine' ),
),
self::AGENT => array(
'label' => __( 'Agent', 'data-machine' ),
'description' => __( 'Agent CRUD, tokens, pings, duplicate checking, and processed items.', 'data-machine' ),
),
self::SETTINGS => array(
'label' => __( 'Settings', 'data-machine' ),
'description' => __( 'Plugin settings, tool configuration, and handler defaults.', 'data-machine' ),
),
self::AUTH => array(
'label' => __( 'Auth', 'data-machine' ),
'description' => __( 'OAuth provider management and authentication.', 'data-machine' ),
),
self::LOGGING => array(
'label' => __( 'Logging', 'data-machine' ),
'description' => __( 'Log reading, writing, clearing, and metadata.', 'data-machine' ),
),
self::SYSTEM => array(
'label' => __( 'System', 'data-machine' ),
'description' => __( 'System health, session titles, and background task execution.', 'data-machine' ),
),
self::CHAT => array(
'label' => __( 'Chat', 'data-machine' ),
'description' => __( 'Chat session management and messaging.', 'data-machine' ),
),
);

foreach ( $categories as $slug => $args ) {
wp_register_ability_category( $slug, $args );
}

self::$registered = true;
}

/**
* Ensure categories are registered.
*
* Handles timing: if the categories_init hook already fired, registers
* immediately. Otherwise hooks into it. This mirrors the pattern used
* by individual ability classes.
*/
public static function ensure_registered(): void {
if ( self::$registered ) {
return;
}

if ( did_action( 'wp_abilities_api_categories_init' ) ) {
self::register();
} else {
add_action( 'wp_abilities_api_categories_init', array( self::class, 'register' ) );
}
}
}
12 changes: 6 additions & 6 deletions inc/Abilities/AgentAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private function registerAbilities(): void {
array(
'label' => 'Rename Agent',
'description' => 'Rename an agent slug — updates database and moves filesystem directory',
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'required' => array( 'old_slug', 'new_slug' ),
Expand Down Expand Up @@ -78,7 +78,7 @@ private function registerAbilities(): void {
array(
'label' => 'List Agents',
'description' => 'List all registered agent identities',
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'properties' => new \stdClass(),
Expand Down Expand Up @@ -113,7 +113,7 @@ private function registerAbilities(): void {
array(
'label' => 'Create Agent',
'description' => 'Create a new agent identity with filesystem directory and owner access. Admins can create agents for any user. Non-admins with create_own_agent can create one agent for themselves.',
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'required' => array( 'agent_slug' ),
Expand Down Expand Up @@ -160,7 +160,7 @@ private function registerAbilities(): void {
array(
'label' => 'Get Agent',
'description' => 'Retrieve a single agent by slug or ID with access grants and directory info',
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'properties' => array(
Expand Down Expand Up @@ -199,7 +199,7 @@ private function registerAbilities(): void {
array(
'label' => 'Update Agent',
'description' => 'Update an agent\'s mutable fields (name, config, status)',
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'required' => array( 'agent_id' ),
Expand Down Expand Up @@ -241,7 +241,7 @@ private function registerAbilities(): void {
array(
'label' => 'Delete Agent',
'description' => 'Delete an agent record and access grants, optionally removing filesystem directory',
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'properties' => array(
Expand Down
8 changes: 4 additions & 4 deletions inc/Abilities/AgentMemoryAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private function registerAbilities(): void {
array(
'label' => 'Get Agent Memory',
'description' => 'Read agent file content — full file or a specific section. Supports any agent file (MEMORY.md, SOUL.md, USER.md, etc.).',
'category' => 'datamachine',
'category' => 'datamachine/memory',
'input_schema' => array(
'type' => 'object',
'properties' => array(
Expand Down Expand Up @@ -89,7 +89,7 @@ private function registerAbilities(): void {
array(
'label' => 'Update Agent Memory',
'description' => 'Write to a specific section of an agent file — set (replace) or append. Supports any agent file.',
'category' => 'datamachine',
'category' => 'datamachine/memory',
'input_schema' => array(
'type' => 'object',
'properties' => array(
Expand Down Expand Up @@ -141,7 +141,7 @@ private function registerAbilities(): void {
array(
'label' => 'Search Agent Memory',
'description' => 'Search across agent file content. Returns matching lines with context, grouped by section. Supports any agent file.',
'category' => 'datamachine',
'category' => 'datamachine/memory',
'input_schema' => array(
'type' => 'object',
'required' => array( 'query' ),
Expand Down Expand Up @@ -201,7 +201,7 @@ private function registerAbilities(): void {
array(
'label' => 'List Agent Memory Sections',
'description' => 'List all section headers in an agent file. Supports any agent file.',
'category' => 'datamachine',
'category' => 'datamachine/memory',
'input_schema' => array(
'type' => 'object',
'properties' => array(
Expand Down
2 changes: 1 addition & 1 deletion inc/Abilities/AgentPing/SendPingAbility.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ private function registerAbility(): void {
array(
'label' => __( 'Send Ping', 'data-machine' ),
'description' => __( 'Send pipeline context to webhook endpoints. Supports multiple URLs (one per line).', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'required' => array( 'webhook_url' ),
Expand Down
6 changes: 3 additions & 3 deletions inc/Abilities/AgentTokenAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private function registerCreateToken(): void {
array(
'label' => __( 'Create Agent Token', 'data-machine' ),
'description' => __( 'Create a bearer token for agent runtime authentication. The raw token is only returned once.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'required' => array( 'agent_id' ),
Expand Down Expand Up @@ -96,7 +96,7 @@ private function registerRevokeToken(): void {
array(
'label' => __( 'Revoke Agent Token', 'data-machine' ),
'description' => __( 'Revoke (delete) an agent bearer token. The token will immediately stop working.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'required' => array( 'agent_id', 'token_id' ),
Expand Down Expand Up @@ -132,7 +132,7 @@ private function registerListTokens(): void {
array(
'label' => __( 'List Agent Tokens', 'data-machine' ),
'description' => __( 'List all tokens for an agent. Returns metadata only (never the token value).', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/agent',
'input_schema' => array(
'type' => 'object',
'required' => array( 'agent_id' ),
Expand Down
2 changes: 1 addition & 1 deletion inc/Abilities/Analytics/BingWebmasterAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private function registerAbilities(): void {
array(
'label' => 'Bing Webmaster Tools',
'description' => 'Fetch search analytics data from Bing Webmaster Tools API',
'category' => 'datamachine',
'category' => 'datamachine/analytics',
'input_schema' => array(
'type' => 'object',
'required' => array( 'action' ),
Expand Down
2 changes: 1 addition & 1 deletion inc/Abilities/Analytics/GoogleAnalyticsAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ private function registerAbilities(): void {
array(
'label' => 'Google Analytics',
'description' => 'Fetch visitor analytics data from Google Analytics (GA4) Data API',
'category' => 'datamachine',
'category' => 'datamachine/analytics',
'input_schema' => array(
'type' => 'object',
'required' => array( 'action' ),
Expand Down
2 changes: 1 addition & 1 deletion inc/Abilities/Analytics/GoogleSearchConsoleAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private function registerAbilities(): void {
array(
'label' => 'Google Search Console',
'description' => 'Fetch search analytics data from Google Search Console API',
'category' => 'datamachine',
'category' => 'datamachine/analytics',
'input_schema' => array(
'type' => 'object',
'required' => array( 'action' ),
Expand Down
2 changes: 1 addition & 1 deletion inc/Abilities/Analytics/PageSpeedAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private function registerAbilities(): void {
array(
'label' => 'PageSpeed Insights',
'description' => 'Run Lighthouse audits via PageSpeed Insights API for performance, accessibility, SEO, and best practices scores',
'category' => 'datamachine',
'category' => 'datamachine/analytics',
'input_schema' => array(
'type' => 'object',
'required' => array( 'action' ),
Expand Down
12 changes: 6 additions & 6 deletions inc/Abilities/AuthAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ private function registerGetAuthStatus(): void {
array(
'label' => __( 'Get Auth Status', 'data-machine' ),
'description' => __( 'Get OAuth/authentication status for a handler including authorization URL if applicable.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/auth',
'input_schema' => array(
'type' => 'object',
'required' => array( 'handler_slug' ),
Expand Down Expand Up @@ -234,7 +234,7 @@ private function registerDisconnectAuth(): void {
array(
'label' => __( 'Disconnect Auth', 'data-machine' ),
'description' => __( 'Disconnect/revoke authentication for a handler.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/auth',
'input_schema' => array(
'type' => 'object',
'required' => array( 'handler_slug' ),
Expand Down Expand Up @@ -266,7 +266,7 @@ private function registerSaveAuthConfig(): void {
array(
'label' => __( 'Save Auth Config', 'data-machine' ),
'description' => __( 'Save authentication configuration for a handler.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/auth',
'input_schema' => array(
'type' => 'object',
'required' => array( 'handler_slug' ),
Expand Down Expand Up @@ -302,7 +302,7 @@ private function registerSetAuthToken(): void {
array(
'label' => __( 'Set Auth Token', 'data-machine' ),
'description' => __( 'Manually set authentication token and account data for a handler. Used for migration, CI, and headless auth setup.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/auth',
'input_schema' => array(
'type' => 'object',
'required' => array( 'handler_slug', 'account_data' ),
Expand Down Expand Up @@ -338,7 +338,7 @@ private function registerRefreshAuth(): void {
array(
'label' => __( 'Refresh Auth Token', 'data-machine' ),
'description' => __( 'Force a token refresh for an OAuth2 handler. Only works for providers that support token refresh.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/auth',
'input_schema' => array(
'type' => 'object',
'required' => array( 'handler_slug' ),
Expand Down Expand Up @@ -371,7 +371,7 @@ private function registerListProviders(): void {
array(
'label' => __( 'List Auth Providers', 'data-machine' ),
'description' => __( 'List all registered authentication providers with status, config fields, and account details.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/auth',
'input_schema' => array(
'type' => 'object',
'properties' => array(),
Expand Down
2 changes: 1 addition & 1 deletion inc/Abilities/Chat/CreateChatSessionAbility.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private function registerAbility(): void {
array(
'label' => __( 'Create Chat Session', 'data-machine' ),
'description' => __( 'Create a new chat session for a user.', 'data-machine' ),
'category' => 'datamachine',
'category' => 'datamachine/chat',
'input_schema' => array(
'type' => 'object',
'properties' => array(
Expand Down
Loading
Loading