register_tools(); } // ── Admin ────────────────────────────────────────────────────────────── if ( is_admin() ) { new AICOM_Admin(); } // ── Admin Bar (fires on both admin and frontend for logged-in admins) ── add_action( 'admin_bar_menu', [ 'AICOM_Admin', 'register_admin_bar' ], 100 ); add_action( 'wp_ajax_aicom_toolbar_toggle', [ 'AICOM_Admin', 'ajax_toolbar_toggle' ] ); add_action( 'wp_ajax_aicom_save_preset', [ 'AICOM_Admin', 'ajax_save_preset' ] ); add_action( 'wp_ajax_aicom_delete_preset', [ 'AICOM_Admin', 'ajax_delete_preset' ] ); // Enqueue toolbar JS/CSS on frontend too (admin_enqueue_scripts only fires in /wp-admin) add_action( 'wp_enqueue_scripts', function (): void { if ( ! is_admin_bar_showing() || ! current_user_can( 'manage_options' ) ) { return; } wp_enqueue_style( 'aicom-admin', AICOM_URL . 'assets/admin.css', [], AICOM_VERSION ); wp_enqueue_script( 'aicom-admin', AICOM_URL . 'assets/admin.js', [ 'jquery' ], AICOM_VERSION, true ); wp_localize_script( 'aicom-admin', 'AICOM_MCP', [ 'ajaxUrl' => admin_url( 'admin-ajax.php' ), ] ); } ); // ── REST Endpoint ────────────────────────────────────────────────────── add_action( 'rest_api_init', function (): void { register_rest_route( 'aicom/v1', '/mcp', [ 'methods' => [ 'POST', 'GET' ], 'callback' => 'aicom_rest_handler', // permission_callback is intentionally open — authentication and authorization // are fully handled inside AICOM_Tool_Router::dispatch() via API key validation, // scope checks, and lock-state enforcement before any operation is executed. 'permission_callback' => '__return_true', ] ); } ); // ── Fallback Endpoint (/index.php?aicom=1) ───────────────────────── add_action( 'init', function (): void { if ( ! empty( $_GET['aicom'] ) && ( $_GET['aicom'] === '1' ) ) { if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'GET' ) { // Health check wp_send_json( [ 'ok' => true, 'server' => 'AICOM - AI Commander', 'version' => AICOM_VERSION ] ); } $body = file_get_contents( 'php://input' ); $result = AICOM_Tool_Router::dispatch( $body ?: '{}' ); wp_send_json( $result ); } } ); } // ── REST Handler ─────────────────────────────────────────────────────────── function aicom_rest_handler( WP_REST_Request $request ): WP_REST_Response { // GET = health/status endpoint if ( $request->get_method() === 'GET' ) { return new WP_REST_Response( [ 'ok' => true, 'server' => 'AICOM - AI Commander', 'version' => AICOM_VERSION, 'lock' => AICOM_Lock_Manager::get_state(), ] ); } // POST = MCP dispatch $body = $request->get_body(); $result = AICOM_Tool_Router::dispatch( $body ?: '{}' ); $http_status = isset( $result['error'] ) ? ( $result['error']['http_status'] ?? 400 ) : 200; unset( $result['error']['http_status'] ); return new WP_REST_Response( $result, 200 ); // Always HTTP 200; errors encoded in body per MCP convention }