> */ private static array $caps = array(); /** * Hook registration. Capabilities carry translated descriptions, and * WordPress 6.7+ warns when translations load before `init`, so they are * registered there (REST routes are built later, on rest_api_init). */ public static function init(): void { add_action( 'init', array( __CLASS__, 'register_all' ), 5 ); } /** * Register free-core capabilities, then let premium modules add theirs. */ public static function register_all(): void { AgentAdapt_Catalog::register(); AgentAdapt_Policies::register(); AgentAdapt_Cart::register(); AgentAdapt_Handoff::register(); AgentAdapt_Orders::register(); /** * Register further capabilities with AgentAdapt_Capabilities::register(). */ do_action( 'agentadapt_register_capabilities' ); } /** * Declare a capability. * * @param string $id Dotted id, e.g. catalog.search. * @param array $def { * @type string $summary One line for the OpenAPI summary. * @type string $description What it does, for an agent choosing a tool. * @type string $method GET|POST|PATCH|DELETE. * @type string $path Route under /agent-adapt/v1, {param} placeholders. * @type string[] $scopes Account scopes required; empty = guest. * @type array $params name → JSON Schema (+ 'required' => bool, 'in' => path|query|body). * @type array $response JSON Schema of the success body. * @type array $errors Optional: refusals particular to it, HTTP status => description (OpenAPI). * @type callable $handler fn( AgentAdapt_Context, array $params ): array|WP_Error. * } */ public static function register( string $id, array $def ): void { $def['id'] = $id; $def['method'] = strtoupper( (string) ( $def['method'] ?? 'GET' ) ); $def['scopes'] = array_values( (array) ( $def['scopes'] ?? array() ) ); $def['params'] = (array) ( $def['params'] ?? array() ); if ( ! is_callable( $def['handler'] ?? null ) || empty( $def['path'] ) ) { _doing_it_wrong( __METHOD__, esc_html( "capability $id needs a path and a callable handler" ), '0.1.0' ); return; } self::$caps[ $id ] = $def; } /** * Withdraw a capability (merchant policy). Every channel is generated * from the registry, so a withdrawn capability has no route and no * OpenAPI entry, and the gate refuses it as unknown. * * @param string $id Capability id. */ public static function remove( string $id ): void { unset( self::$caps[ $id ] ); } /** * One definition, or null. * * @param string $id Capability id. * @return array|null */ public static function get( string $id ): ?array { return self::$caps[ $id ] ?? null; } /** * All definitions. * * @return array> */ public static function all(): array { return self::$caps; } }