Plugin Directory

Changeset 3766841


Ignore:
Timestamp:
10/26/2026 03:47:00 PM (2 weeks ago)
Author:
raftaar1191
Message:

Update to version 0.4.4 from GitHub

Location:
acrossai-mcp-manager
Files:
46 added
62 edited
1 copied

Legend:

Unmodified
Added
Removed
  • acrossai-mcp-manager/tags/0.4.4/acrossai-mcp-manager.php

    r3734601 r3766841  
    2424 * Plugin URI: https://acrossai.co/mcp-manager/
    2525 * Description: WordPress MCP server and admin for MCP Adapter: multiple servers, access control and one-click connectors for Claude, ChatGPT, Gemini, Grok and Cursor.
    26  * Version: 0.4.3
     26 * Version: 0.4.4
    2727 * Requires at least: 6.9
    2828 * Requires PHP: 8.1
  • acrossai-mcp-manager/tags/0.4.4/admin/Partials/MCPServerListTable.php

    r3720416 r3766841  
    404404                        '<a href="%s" class="acrossai-quicklink"><span class="dashicons dashicons-admin-tools" aria-hidden="true"></span><span class="acrossai-quicklink-label">%s</span></a>',
    405405                        esc_url( $quick_connect_url ),
    406                         esc_html__( 'Quick Connect via AcrossAI', 'acrossai-mcp-manager' )
     406                        esc_html__( 'Connect via AcrossAI', 'acrossai-mcp-manager' )
    407407                );
    408408
  • acrossai-mcp-manager/tags/0.4.4/admin/Partials/Menu.php

    r3702733 r3766841  
    9292                );
    9393
    94                 // 2) Quick Connect via AcrossAI — position 3, right after MCP (F072 FR-003).
     94                // 2) Connect via AcrossAI — position 3, right after MCP (F072 FR-003).
    9595                // URL-literal menu_slug + empty render callback = WP renders this
    9696                // submenu item as a direct link to the wizard URL; no dedicated
    … …  
    103103                        // tail is redundant. Every other surface (plugins.php action
    104104                        // link, servers-list button, per-row pill, Settings sub-nav,
    105                         // admin-bar chip) keeps the full "Quick Connect via AcrossAI"
     105                        // admin-bar chip) keeps the full "Connect via AcrossAI"
    106106                        // so the wizard is discoverable outside the sidebar too.
    107                         __( 'Quick Connect', 'acrossai-mcp-manager' ),
    108                         __( 'Quick Connect', 'acrossai-mcp-manager' ),
     107                        __( 'Connect', 'acrossai-mcp-manager' ),
     108                        __( 'Connect', 'acrossai-mcp-manager' ),
    109109                        'manage_options',
    110110                        'admin.php?page=' . AdminPageSlugs::PARENT . '&quick-connect=1&step=1',
    … …  
    146146                        '<a href="%s">%s</a>',
    147147                        $quick_connect_url,
    148                         esc_html__( 'Quick Connect via AcrossAI', 'acrossai-mcp-manager' )
     148                        esc_html__( 'Connect via AcrossAI', 'acrossai-mcp-manager' )
    149149                );
    150150
    151                 // Prepend Quick Connect via AcrossAI first, then Settings, so the final row order
    152                 // reads Settings | Quick Connect via AcrossAI | Deactivate | Download (F072 FR-002).
     151                // Prepend Connect via AcrossAI first, then Settings, so the final row order
     152                // reads Settings | Connect via AcrossAI | Deactivate | Download (F072 FR-002).
    153153                array_unshift( $links, $quick_connect_link );
    154154                array_unshift( $links, $settings_link );
  • acrossai-mcp-manager/tags/0.4.4/admin/Partials/Notices.php

    r3734601 r3766841  
    276276                                'id'      => 'acrossai_mcp_manager_firefox_tracking_protection',
    277277                                'title'   => __( 'Firefox tracking protection can block AI assistants from connecting', 'acrossai-mcp-manager' ),
    278                                 'message' => __( "You are viewing this page in Firefox. Its <strong>Enhanced Tracking Protection</strong> can stop an AI assistant part-way through connecting to this site — the connector is added, sign-in opens, and then nothing completes, usually with no error to explain it.<br><br>If a connection fails: click the <strong>shield icon</strong> to the left of the address bar, then switch <strong>Enhanced Tracking Protection</strong> off for this site and connect again. Firefox remembers the choice per site and it does not affect any other site you visit. You can switch it back on afterwards — the protection only interferes while the connection is being set up, not once it is working.", 'acrossai-mcp-manager' ),
     278                                'message' => __( 'You are viewing this page in Firefox. Its <strong>Enhanced Tracking Protection</strong> can stop an AI assistant part-way through connecting to this site — the connector is added, sign-in opens, and then nothing completes, usually with no error to explain it.<br><br>If a connection fails: click the <strong>shield icon</strong> to the left of the address bar, then switch <strong>Enhanced Tracking Protection</strong> off for this site and connect again. Firefox remembers the choice per site and it does not affect any other site you visit. You can switch it back on afterwards — the protection only interferes while the connection is being set up, not once it is working.', 'acrossai-mcp-manager' ),
    279279                                'type'    => 'info',
    280280                                'source'  => __( 'Connectors/Integrations', 'acrossai-mcp-manager' ),
  • acrossai-mcp-manager/tags/0.4.4/admin/Partials/QuickConnect/AdminBarEntry.php

    r3673028 r3766841  
    11<?php
    22/**
    3  * AdminBarEntry — persistent "Quick Connect via AcrossAI" chip in the admin bar.
     3 * AdminBarEntry — persistent "Connect via AcrossAI" chip in the admin bar.
    44 *
    55 * Feature 069 T044 (US2) — Provides a one-click entry point to the wizard
    … …  
    2222
    2323/**
    24  * Registers the "Quick Connect via AcrossAI" node on the wp-admin toolbar.
     24 * Registers the "Connect via AcrossAI" node on the wp-admin toolbar.
    2525 *
    2626 * @since 0.2.11
    … …  
    8282                                'id'    => self::NODE_ID,
    8383                                'title' => '<span class="ab-icon dashicons dashicons-admin-tools" style="top:3px;"></span>'
    84                                         . esc_html__( 'Quick Connect via AcrossAI', 'acrossai-mcp-manager' ),
     84                                        . esc_html__( 'Connect via AcrossAI', 'acrossai-mcp-manager' ),
    8585                                'href'  => esc_url( admin_url( 'admin.php?page=acrossai_mcp_manager&quick-connect=1&step=1' ) ),
    8686                                'meta'  => array(
  • acrossai-mcp-manager/tags/0.4.4/admin/Partials/QuickConnect/QuickConnectPage.php

    r3673028 r3766841  
    6969                echo '<noscript><p>';
    7070                echo esc_html__(
    71                         'The Quick Connect via AcrossAI wizard requires JavaScript. Enable JavaScript in your browser to use it.',
     71                        'The Connect via AcrossAI wizard requires JavaScript. Enable JavaScript in your browser to use it.',
    7272                        'acrossai-mcp-manager'
    7373                );
  • acrossai-mcp-manager/tags/0.4.4/admin/Partials/ServerTabs/McpTrackerTab.php

    r3634312 r3766841  
    1414namespace AcrossAI_MCP_Manager\Admin\Partials\ServerTabs;
    1515
     16use AcrossAI_MCP_Manager\Admin\Partials\ActivityLogPage;
     17
    1618// Exit if accessed directly.
    1719defined( 'ABSPATH' ) || exit;
    … …  
    2628final class McpTrackerTab extends AbstractServerTab {
    2729
    28         /**
    29          * WordPress.org plugin page URL for the "Get MCP Tracker" call to action.
    30          *
    31          * @since 0.0.6
    32          * @var string
    33          */
    34         private const WPORG_URL = 'https://wordpress.org/plugins/mcp-tracker/';
    3530
    3631        /**
    … …  
    7671         */
    7772        protected function render_body( array $server ): void {
     73                $server_id   = isset( $server['id'] ) ? (int) $server['id'] : 0;
    7874                $server_slug = ! empty( $server['server_slug'] )
    7975                        ? (string) $server['server_slug']
    8076                        : sanitize_title( (string) $server['server_name'] );
    8177
    82                 $tracker_active = defined( 'WPVMCPT_PLUGIN_VERSION' ) || class_exists( 'WPVMCPT\\Plugin' );
    83                 $tracker_url    = admin_url( 'admin.php?page=wpvmcpt-requests-list&server=' . rawurlencode( $server_slug ) );
     78                echo '<div class="mcp-tab-panel">';
     79                printf( '<h2>%s</h2>', esc_html__( 'Logs', 'acrossai-mcp-manager' ) );
     80                printf(
     81                        '<p class="description">%s</p>',
     82                        esc_html__( 'Requests this server answered, and what ran behind them.', 'acrossai-mcp-manager' )
     83                );
    8484
    85                 echo '<div class="mcp-tab-panel">';
    86                 printf( '<h2>%s</h2>', esc_html__( 'MCP Tracker', 'acrossai-mcp-manager' ) );
     85                // F096 — the same React app the global Activity page mounts, filtered to
     86                // this server with the Server column hidden. One component, two mount
     87                // points; the only difference is this bootstrap payload.
     88                ActivityLogPage::instance()->enqueue_bundle(
     89                        array(
     90                                'serverId'   => $server_id,
     91                                'showServer' => false,
     92                                'rootId'     => 'acrossai-mcp-activity-root',
     93                        )
     94                );
    8795
    88                 if ( $tracker_active ) {
    89                         $this->render_active( $server_slug, $tracker_url );
    90                 } else {
    91                         $this->render_inactive( $tracker_url );
     96                echo '<div id="acrossai-mcp-activity-root"></div>';
     97
     98                // The third-party plugin this tab used to advertise. Kept as a
     99                // secondary note rather than an install CTA: both logs can run at once
     100                // (different tables, no interference), and an operator who already has
     101                // it should be told why they are seeing two.
     102                if ( defined( 'WPVMCPT_PLUGIN_VERSION' ) || class_exists( 'WPVMCPT\\Plugin' ) ) {
     103                        $tracker_url = admin_url( 'admin.php?page=wpvmcpt-requests-list&server=' . rawurlencode( $server_slug ) );
     104
     105                        printf(
     106                                '<p class="description" style="margin-top:16px">%s <a href="%s">%s</a></p>',
     107                                esc_html__( 'MCP Tracker is also active on this site and logs the same traffic independently.', 'acrossai-mcp-manager' ),
     108                                esc_url( $tracker_url ),
     109                                esc_html__( 'Open MCP Tracker', 'acrossai-mcp-manager' )
     110                        );
    92111                }
    93112
    94113                echo '</div>';
    95114        }
    96 
    97         /**
    98          * Renders the "tracker active" branch — success notice + button + slug hint.
    99          *
    100          * @since 0.0.6
    101          * @param string $server_slug Server slug (already sanitized).
    102          * @param string $tracker_url Direct link to the request log filtered to this server.
    103          * @return void
    104          */
    105         private function render_active( string $server_slug, string $tracker_url ): void {
    106                 printf(
    107                         '<div class="notice notice-success inline"><p><strong>%1$s</strong> %2$s</p></div>',
    108                         esc_html__( 'MCP Tracker is active.', 'acrossai-mcp-manager' ),
    109                         esc_html__( 'View all logged requests for this server below.', 'acrossai-mcp-manager' )
    110                 );
    111 
    112                 printf(
    113                         '<p style="margin-top:16px;"><a href="%1$s" class="button button-primary">%2$s</a></p>',
    114                         esc_url( $tracker_url ),
    115                         esc_html__( 'View Request Log', 'acrossai-mcp-manager' )
    116                 );
    117 
    118                 echo '<p class="description" style="margin-top:12px;">';
    119                 /* translators: %s: server slug (wrapped in <code>) */
    120                 $slug_template = __( 'Direct link filtered to server: %s', 'acrossai-mcp-manager' );
    121                 printf(
    122                         wp_kses( $slug_template, array( 'code' => array() ) ),
    123                         '<code>' . esc_html( $server_slug ) . '</code>'
    124                 );
    125                 echo '<br />';
    126                 printf(
    127                         '<code style="user-select:all;">%s</code>',
    128                         esc_html( $tracker_url )
    129                 );
    130                 echo '</p>';
    131         }
    132 
    133         /**
    134          * Renders the "tracker not installed" branch — info notice + facts table + CTA.
    135          *
    136          * @since 0.0.6
    137          * @param string $tracker_url Direct link URL to display in the "Request log URL" row.
    138          * @return void
    139          */
    140         private function render_inactive( string $tracker_url ): void {
    141                 printf(
    142                         '<div class="notice notice-info inline"><p><strong>%1$s</strong> %2$s</p></div>',
    143                         esc_html__( 'MCP Tracker is not installed.', 'acrossai-mcp-manager' ),
    144                         esc_html__( 'Install the free MCP Tracker plugin to log and inspect every request made to this MCP server.', 'acrossai-mcp-manager' )
    145                 );
    146 
    147                 echo '<table class="form-table" style="margin-top:8px;">';
    148 
    149                 printf(
    150                         '<tr><th scope="row">%1$s</th><td><a href="%2$s" target="_blank" rel="noopener noreferrer">%3$s</a></td></tr>',
    151                         esc_html__( 'Plugin', 'acrossai-mcp-manager' ),
    152                         esc_url( self::WPORG_URL ),
    153                         esc_html__( 'MCP Tracker — WordPress.org', 'acrossai-mcp-manager' )
    154                 );
    155 
    156                 printf(
    157                         '<tr><th scope="row">%1$s</th><td>%2$s</td></tr>',
    158                         esc_html__( 'What it does', 'acrossai-mcp-manager' ),
    159                         esc_html__( 'Logs every incoming MCP request — tool calls, responses, errors, and timing — so you can audit activity, debug AI clients, and monitor server usage.', 'acrossai-mcp-manager' )
    160                 );
    161 
    162                 printf(
    163                         '<tr><th scope="row">%1$s</th><td><code style="user-select:all;">%2$s</code><p class="description">%3$s</p></td></tr>',
    164                         esc_html__( 'Request log URL', 'acrossai-mcp-manager' ),
    165                         esc_html( $tracker_url ),
    166                         esc_html__( 'Once installed and activated, this URL will open the request log filtered to this server.', 'acrossai-mcp-manager' )
    167                 );
    168 
    169                 echo '</table>';
    170 
    171                 printf(
    172                         '<p style="margin-top:16px;"><a href="%1$s" class="button" target="_blank" rel="noopener noreferrer">%2$s</a></p>',
    173                         esc_url( self::WPORG_URL ),
    174                         esc_html__( 'Get MCP Tracker', 'acrossai-mcp-manager' )
    175                 );
    176         }
    177115}
  • acrossai-mcp-manager/tags/0.4.4/admin/Partials/Settings.php

    r3704846 r3766841  
    806806                        esc_html__( 'Add New', 'acrossai-mcp-manager' ),
    807807                        esc_url( $quick_connect_url ),
    808                         esc_html__( 'Quick Connect via AcrossAI', 'acrossai-mcp-manager' )
     808                        esc_html__( 'Connect via AcrossAI', 'acrossai-mcp-manager' )
    809809                );
    810810
  • acrossai-mcp-manager/tags/0.4.4/admin/Partials/SettingsMenu.php

    r3702733 r3766841  
    2020namespace AcrossAI_MCP_Manager\Admin\Partials;
    2121
     22use AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants;
     23
    2224use AcrossAI_MCP_Manager\Includes\Abilities\Discover;
    2325
    … …  
    174176                                'default'           => 0,
    175177                        )
     178                );
     179
     180                // F096 — activity logging. TWO independent toggles: ability logging is
     181                // far noisier than request logging (one tools/call fans out into several
     182                // abilities, and non-MCP callers add rows with no MCP traffic at all),
     183                // so an operator must be able to run one without the other. Both off on
     184                // install — logging every request is a real cost and the WordPress AI
     185                // plugin's own equivalent sits behind an experiment gate for the same
     186                // reason. Laid out so Feature 097's change-recording toggle slots in as
     187                // a third row without restructuring.
     188                // The declared default MUST match the constant every reader passes to
     189                // get_option(). They are two different mechanisms and nothing makes
     190                // them agree, but unchecking the box depends on them agreeing:
     191                //
     192                // An unchecked checkbox posts no field, so `options.php` calls
     193                // update_option() with null, which sanitizes to false. update_option()
     194                // then compares that against `get_option( $option )` called WITHOUT an
     195                // explicit default — which resolves to whatever is declared HERE. If
     196                // this said false while readers defaulted to true, the comparison would
     197                // find false === false, write nothing, leave the option absent, and the
     198                // readers' true fallback would keep logging ON. The operator unticks
     199                // the box, the page reports success, and nothing changes.
     200                //
     201                // Verified directly: update_option( $option, false ) against an absent
     202                // option returns false and stores nothing.
     203                register_setting(
     204                        $option_group,
     205                        ActivityLogConstants::OPTION_REQUEST_LOGGING,
     206                        array(
     207                                'sanitize_callback' => 'rest_sanitize_boolean',
     208                                'default'           => ActivityLogConstants::DEFAULT_REQUEST_LOGGING,
     209                        )
     210                );
     211
     212                register_setting(
     213                        $option_group,
     214                        ActivityLogConstants::OPTION_ABILITY_LOGGING,
     215                        array(
     216                                'sanitize_callback' => 'rest_sanitize_boolean',
     217                                'default'           => ActivityLogConstants::DEFAULT_ABILITY_LOGGING,
     218                        )
     219                );
     220
     221                register_setting(
     222                        $option_group,
     223                        ActivityLogConstants::OPTION_RETENTION_REQUEST_DAYS,
     224                        array(
     225                                'sanitize_callback' => 'absint',
     226                                'default'           => ActivityLogConstants::DEFAULT_RETENTION_REQUEST_DAYS,
     227                        )
     228                );
     229
     230                register_setting(
     231                        $option_group,
     232                        ActivityLogConstants::OPTION_RETENTION_ABILITY_DAYS,
     233                        array(
     234                                'sanitize_callback' => 'absint',
     235                                'default'           => ActivityLogConstants::DEFAULT_RETENTION_ABILITY_DAYS,
     236                        )
     237                );
     238
     239                register_setting(
     240                        $option_group,
     241                        ActivityLogConstants::OPTION_MAX_EVENTS,
     242                        array(
     243                                'sanitize_callback' => 'absint',
     244                                'default'           => ActivityLogConstants::DEFAULT_MAX_EVENTS,
     245                        )
     246                );
     247
     248                add_settings_section(
     249                        'acrossai_mcp_activity_section',
     250                        __( 'MCP Activity Log', 'acrossai-mcp-manager' ),
     251                        array( $this, 'render_activity_section_description' ),
     252                        $page_slug
     253                );
     254
     255                add_settings_field(
     256                        ActivityLogConstants::OPTION_REQUEST_LOGGING,
     257                        __( 'Log MCP requests', 'acrossai-mcp-manager' ),
     258                        array( $this, 'render_activity_request_field' ),
     259                        $page_slug,
     260                        'acrossai_mcp_activity_section'
     261                );
     262
     263                add_settings_field(
     264                        ActivityLogConstants::OPTION_ABILITY_LOGGING,
     265                        __( 'Log ability runs', 'acrossai-mcp-manager' ),
     266                        array( $this, 'render_activity_ability_field' ),
     267                        $page_slug,
     268                        'acrossai_mcp_activity_section'
     269                );
     270
     271                add_settings_field(
     272                        'acrossai_mcp_activity_retention',
     273                        __( 'Keep events for', 'acrossai-mcp-manager' ),
     274                        array( $this, 'render_activity_retention_field' ),
     275                        $page_slug,
     276                        'acrossai_mcp_activity_section'
    176277                );
    177278
    … …  
    373474                );
    374475        }
     476
     477        /** Describe the activity-log section. */
     478        public function render_activity_section_description(): void {
     479                printf(
     480                        '<p>%s</p>',
     481                        esc_html__(
     482                                'Records what AI clients asked your MCP servers to do. On by default, and bounded by default: requests are kept for 30 days, ability runs for 7, and the log is capped at 50,000 events. A daily job applies all three. Switch either half off if you would rather it recorded nothing.',
     483                                'acrossai-mcp-manager'
     484                        )
     485                );
     486        }
     487
     488        /** Request-logging toggle. */
     489        public function render_activity_request_field(): void {
     490                $enabled = (bool) get_option( ActivityLogConstants::OPTION_REQUEST_LOGGING, ActivityLogConstants::DEFAULT_REQUEST_LOGGING );
     491
     492                printf(
     493                        '<label><input type="checkbox" name="%1$s" value="1" %2$s /> %3$s</label><p class="description">%4$s</p>',
     494                        esc_attr( ActivityLogConstants::OPTION_REQUEST_LOGGING ),
     495                        checked( $enabled, true, false ),
     496                        esc_html__( 'Record one row per MCP request', 'acrossai-mcp-manager' ),
     497                        esc_html__( 'What was asked, by which client, how it authenticated, whether it worked and how long it took.', 'acrossai-mcp-manager' )
     498                );
     499        }
     500
     501        /**
     502         * Ability-logging toggle.
     503         *
     504         * The description states that arguments are recorded. Redaction matches
     505         * sensitive KEY NAMES (token, secret, api_key and 21 more); it cannot cover
     506         * a secret pasted into a free-text value. An operator deserves to know that
     507         * before switching this on, rather than discovering it in a support thread.
     508         */
     509        public function render_activity_ability_field(): void {
     510                $enabled = (bool) get_option( ActivityLogConstants::OPTION_ABILITY_LOGGING, ActivityLogConstants::DEFAULT_ABILITY_LOGGING );
     511
     512                printf(
     513                        '<label><input type="checkbox" name="%1$s" value="1" %2$s /> %3$s</label><p class="description">%4$s</p>',
     514                        esc_attr( ActivityLogConstants::OPTION_ABILITY_LOGGING ),
     515                        checked( $enabled, true, false ),
     516                        esc_html__( 'Record one row per ability run', 'acrossai-mcp-manager' ),
     517                        esc_html__(
     518                                'Much noisier: one tool call can run several abilities, and REST, WP-CLI and admin callers are recorded too. Ability arguments are recorded — sensitive values are redacted by key name, so a secret inside a free-text field is stored as sent.',
     519                                'acrossai-mcp-manager'
     520                        )
     521                );
     522        }
     523
     524        /** Retention and the retained-event ceiling. */
     525        public function render_activity_retention_field(): void {
     526                printf(
     527                        '<p><label>%1$s <input type="number" min="0" name="%2$s" value="%3$d" class="small-text" /></label></p>'
     528                        . '<p><label>%4$s <input type="number" min="0" name="%5$s" value="%6$d" class="small-text" /></label></p>'
     529                        . '<p><label>%7$s <input type="number" min="0" name="%8$s" value="%9$d" class="small-text" /></label></p>'
     530                        . '<p class="description">%10$s</p>',
     531                        esc_html__( 'Requests, in days', 'acrossai-mcp-manager' ),
     532                        esc_attr( ActivityLogConstants::OPTION_RETENTION_REQUEST_DAYS ),
     533                        (int) get_option( ActivityLogConstants::OPTION_RETENTION_REQUEST_DAYS, ActivityLogConstants::DEFAULT_RETENTION_REQUEST_DAYS ),
     534                        esc_html__( 'Ability runs, in days', 'acrossai-mcp-manager' ),
     535                        esc_attr( ActivityLogConstants::OPTION_RETENTION_ABILITY_DAYS ),
     536                        (int) get_option( ActivityLogConstants::OPTION_RETENTION_ABILITY_DAYS, ActivityLogConstants::DEFAULT_RETENTION_ABILITY_DAYS ),
     537                        esc_html__( 'Maximum events kept, both halves together', 'acrossai-mcp-manager' ),
     538                        esc_attr( ActivityLogConstants::OPTION_MAX_EVENTS ),
     539                        (int) get_option( ActivityLogConstants::OPTION_MAX_EVENTS, ActivityLogConstants::DEFAULT_MAX_EVENTS ),
     540                        // The two retention fields are PER HALF and the ceiling is SHARED, so this
     541                        // paragraph has to switch scope mid-way. The previous wording said "the
     542                        // maximum is a hard ceiling" directly after a sentence about each half
     543                        // ageing out separately, which reads as a third per-half number — see the
     544                        // 2026-10-22 clarification. Say "shared", and say what it costs: heavy
     545                        // ability traffic shortening the request history is the surprising part.
     546                        esc_html__( 'The two day counts are separate, so noisy ability rows cannot force their cutoff onto the quieter request history. The maximum is different: it is one hard ceiling shared by both halves, and once the log passes it the oldest events are shed first whatever their kind — so heavy ability traffic can shorten your request history too. 0 means no limit.', 'acrossai-mcp-manager' )
     547                );
     548        }
    375549}
  • acrossai-mcp-manager/tags/0.4.4/build/js/quick-connect.asset.php

    r3733272 r3766841  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '1791032da0c2cc8273ba');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '895f81949c9b67aca0b3');
  • acrossai-mcp-manager/tags/0.4.4/build/js/quick-connect.js

    r3733272 r3766841  
    11(()=>{"use strict";var e={n:s=>{var a=s&&s.__esModule?()=>s.default:()=>s;return e.d(a,{a}),a},d:(s,a)=>{for(var r in a)e.o(a,r)&&!e.o(s,r)&&Object.defineProperty(s,r,{enumerable:!0,get:a[r]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.element,a=window.wp.apiFetch;var r=e.n(a);const t=window.wp.i18n,n=window.ReactJSXRuntime,i=["info","warning","success","error"],l=({status:e="info",children:s})=>{const a=i.includes(e)?e:"info";return(0,n.jsx)("div",{className:`qs-notice qs-notice--${a}`,role:"error"===a?"alert":"status",children:s})},c={1:"Choose a server",2:"Create a new server",3:"Choose access",4:"Enable Abilities Manager",5:"Enable abilities",6:"Enable server",7:"Pick a connection method",10:"One-click OAuth setup",11:"MCP Client setup",12:"npm setup",13:"WP-CLI setup",done:"You're all set!"},o=({step:e,displayIndex:a,totalSteps:r,isLoading:i,canAdvance:l,footerAction:o,hideContinue:d,belowFooter:p,onBack:m,onAdvance:u,onExit:g,children:_})=>{const h=window.acrossaiMcpQuickConnect||{},v=(0,s.useRef)(null),b=(0,s.useRef)(null);(0,s.useEffect)(()=>{if(!v.current)return;const e=v.current.querySelector('input, button, select, textarea, [tabindex]:not([tabindex="-1"]), [role="radio"]');e&&e.focus()},[e]),(0,s.useEffect)(()=>{if(!b.current)return;const s=c[e]||e,n="done"===e?s:/* translators: 1: current step number, 2: total steps, 3: step title */ /* translators: 1: current step number, 2: total steps, 3: step title */
    2 (0,t.__)("Step %1$d of %2$d, %3$s","acrossai-mcp-manager").replace("%1$d",String(a)).replace("%2$d",String(r)).replace("%3$s",s);b.current.textContent="";const i=setTimeout(()=>{b.current&&(b.current.textContent=n)},100);return()=>clearTimeout(i)},[e,a,r]);const x=Math.min(100,Math.max(0,Math.round(a/r*100))),y="1"===e||"done"===e,f="done"===e,w=["10","11","12","13"].includes(e)?(0,t.__)("Finish","acrossai-mcp-manager"):(0,t.__)("Continue","acrossai-mcp-manager"),j=o?[].concat(o).filter(Boolean):[],C=j.find(e=>e.isLoading),S=i||!!C;return(0,n.jsxs)(n.Fragment,{children:[S&&h.iconUrl&&(0,n.jsxs)("div",{className:"qs__initial-loading qs__initial-loading--overlay",role:"alert","aria-live":"assertive","aria-busy":"true",children:[(0,n.jsx)("img",{className:"qs__initial-loading-icon",src:h.iconUrl,alt:"","aria-hidden":"true"}),(0,n.jsx)("span",{className:"qs__sr-only",children:C?.label?C.label:(0,t.__)("Saving…","acrossai-mcp-manager")})]}),(0,n.jsx)("div",{className:"qs__progress",role:"progressbar","aria-valuenow":a,"aria-valuemin":1,"aria-valuemax":r,"aria-label":(0,t.__)("Wizard progress","acrossai-mcp-manager"),children:(0,n.jsx)("span",{className:"qs__progress-fill",style:{width:`${x}%`}})}),(0,n.jsxs)("header",{className:"qs__header",children:[h.logoUrl&&(0,n.jsx)("img",{className:"qs__header-logo",src:h.logoUrl,alt:"AcrossAI"}),(0,n.jsx)("span",{className:"qs__header-title",children:(0,t.__)("Quick Connect","acrossai-mcp-manager")}),(0,n.jsx)("a",{className:"qs__header-consult",href:"https://acrossai.co/consultations/",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("Free Consultations ↗","acrossai-mcp-manager")}),!f&&(0,n.jsx)("a",{className:"qs__header-exit",href:"#",onClick:e=>{e.preventDefault(),g?.()},children:(0,t.__)("Exit setup","acrossai-mcp-manager")})]}),(0,n.jsxs)("div",{className:"qs__content",ref:v,children:[_,!f&&(()=>{const e=y||S,s=!l||S||j.some(e=>e.disabled);return(0,n.jsxs)("footer",{className:"qs__footer",children:[(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--secondary",disabled:e,"aria-disabled":e,onClick:e?void 0:m,children:(0,t.__)("Back","acrossai-mcp-manager")}),!d&&(0,n.jsx)("button",{type:"button",className:j.length?"qs-btn qs-btn--secondary":"qs-btn","aria-disabled":s,onClick:s?void 0:u,children:w}),j.map(e=>{const s=!!(a=e).disabled||!!a.isLoading;var a;const r="secondary"===e.variant?"qs-btn qs-btn--secondary":"qs-btn";return e.href?(0,n.jsx)("a",{className:r,href:e.href,target:e.target||"_self",rel:"_blank"===e.target?"noopener noreferrer":void 0,"aria-disabled":s,onClick:e.onClick,children:e.label},e.label):(0,n.jsx)("button",{type:"button",className:r,"aria-disabled":s,onClick:s?void 0:e.onClick,children:e.label},e.label)})]})})(),!f&&p]}),(0,n.jsx)("div",{className:"qs__sr-only",ref:b,"aria-live":"polite","aria-atomic":"true"})]})},d=window.wp.url,p=["1","2","3","4","5","6","7","10","11","12","13","done"],m=(e,s)=>!!("2"===e&&s.skipCreate||"4"===e&&s.skipAbilitiesGate||"5"===e&&s.skipAbilities||"6"===e&&s.skipEnable||"10"===e&&s.skipConnectorsDetail||"11"===e&&s.skipClient||"12"===e&&s.skipNpm||"13"===e&&s.skipWpcli),u=()=>{const e=window.location.search||"",s=(0,d.getQueryArg)(e,"step"),a=(0,d.getQueryArg)(e,"method"),r=(0,d.getQueryArg)(e,"mode"),t=(0,d.getQueryArg)(e,"server"),n=t?parseInt(t,10):NaN;return{step:void 0===s||""===s?"1":String(s),method:void 0===a||""===a?null:String(a),mode:void 0===r||""===r?null:String(r),server:Number.isFinite(n)&&n>0?n:null}},g=(e,s,a,r)=>{let t=window.location.pathname+window.location.search;return t=(0,d.addQueryArgs)(t,{step:e}),t=s?(0,d.addQueryArgs)(t,{method:s}):(0,d.removeQueryArgs)(t,"method"),t=a?(0,d.addQueryArgs)(t,{mode:a}):(0,d.removeQueryArgs)(t,"mode"),t=r?(0,d.addQueryArgs)(t,{server:r}):(0,d.removeQueryArgs)(t,"server"),t},_="acrossai-mcp-qs-nav",h=()=>{"undefined"!=typeof window&&"function"==typeof CustomEvent&&window.dispatchEvent(new CustomEvent(_))},v=()=>{const[e,a]=(0,s.useState)(u);(0,s.useEffect)(()=>{const e=()=>a(u());return window.addEventListener("popstate",e),window.addEventListener(_,e),()=>{window.removeEventListener("popstate",e),window.removeEventListener(_,e)}},[]);const r=(0,s.useCallback)((e,s=null,r=null)=>{if(!p.includes(e))return;const t=u(),n=g(e,s,r,t.server);window.history.pushState({},"",n),a({step:e,method:s,mode:r,server:t.server}),h()},[]),t=(0,s.useCallback)(e=>{const s=u(),r={...s,mode:e||null},t=g(s.step,s.method,r.mode,s.server);window.history.pushState({},"",t),a(r),h()},[]),n=(0,s.useCallback)(e=>{const s=Number.isFinite(e)&&e>0?e:null,r=u();if(r.server===s)return;const t=g(r.step,r.method,r.mode,s);window.history.replaceState({},"",t),a({...r,server:s}),h()},[]),i=(0,s.useCallback)(({skips:s={}}={})=>{const a=p.indexOf(e.step);if(-1===a||a>=p.length-1)return;let t=a+1;for(;t<p.length-1&&m(p[t],s);)t+=1;r(p[t],null)},[e.step,r]),l=(0,s.useCallback)(({skips:s={}}={})=>{const a=p.indexOf(e.step);if(a<=0)return;let t=a-1;for(;t>0&&m(p[t],s);)t-=1;r(p[t],null)},[e.step,r]),c=(0,s.useCallback)(()=>{const e=(window.acrossaiMcpQuickConnect||{}).adminUrl||"/wp-admin/admin.php?page=acrossai_mcp_manager";window.location.href=e},[]);return(0,s.useMemo)(()=>({step:e.step,method:e.method,mode:e.mode,server:e.server,goTo:r,setMode:t,setServer:n,advance:i,back:l,exit:c}),[e.step,e.method,e.mode,e.server,r,t,n,i,l,c])},b={status:"idle",error:null,servers:[],abilities:{total:0,enabledForServer:null,hasManagerPlugin:!1},plugins:{abilitiesManager:"missing"},methods:{npm:[],clients:[],ai_connectors:[]},wizardState:{current_step:1,server_id:null,access_saved:!1,abilities_saved:!1,enabled:!1,method:null,created_at:null}},x="HYDRATE_START",y="HYDRATE_SUCCESS",f="HYDRATE_ERROR",w="SAVE_STEP_START",j="SAVE_STEP_SUCCESS",C="SAVE_STEP_ERROR",S="COMPLETE_START",k="COMPLETE_SUCCESS",N="CLEAR_ERROR",q=(e,s)=>{switch(s.type){case x:return{...e,status:"loading",error:null};case y:{const a=s.payload||{};return{...e,status:"ready",error:null,servers:Array.isArray(a.servers)?a.servers:[],abilities:a.abilities||e.abilities,plugins:a.plugins||e.plugins,methods:a.methods||e.methods,wizardState:{...e.wizardState,...a.wizardState||{}}}}case f:return{...e,status:"error",error:s.payload};case w:return{...e,status:"saving",error:null,wizardState:{...e.wizardState,...s.optimistic||{}}};case j:{const a=s.payload||{};return{...e,status:"ready",error:null,servers:Array.isArray(a.servers)?a.servers:e.servers,abilities:a.abilities||e.abilities,wizardState:{...e.wizardState,...a.wizardState||{}}}}case C:return{...e,status:"error",error:s.payload.error,wizardState:s.payload.rollbackState||e.wizardState};case S:return{...e,status:"saving",error:null};case k:case N:return{...e,status:"ready",error:null};default:return e}},A=e=>{if(e&&"object"==typeof e){const s=e.data?.status||e.status;if(403===s)return{code:"session_expired",message:(0,t.__)("Your session has expired. Please reload the page to continue.","acrossai-mcp-manager")};if(401===s)return{code:"not_authorized",message:(0,t.__)("You are no longer signed in. Please reload the page.","acrossai-mcp-manager")};if(e.message)return{code:e.code||"error",message:String(e.message)}}return{code:"network_error",message:(0,t.__)("Something went wrong. Please try again.","acrossai-mcp-manager")}},M=(0,s.createContext)(null),E=({children:e})=>{const[a,t]=(0,s.useReducer)(q,b),i=(0,s.useRef)("");if(!i.current){const e=window.acrossaiMcpQuickConnect||{};i.current=e.restUrl||"/wp-json/acrossai-mcp-manager/v1/quick-connect"}const l=(0,s.useCallback)(async()=>{t({type:x});try{const e=new URLSearchParams(window.location.search).get("server"),s=e?`${i.current}/state?server_id=${encodeURIComponent(e)}`:`${i.current}/state`,a=await r()({url:s,method:"GET"});return t({type:y,payload:a}),a}catch(e){return t({type:f,payload:A(e)}),null}},[]),c=(0,s.useCallback)(async(e,s={})=>{const n=a.wizardState,l={current_step:e,...s};t({type:w,optimistic:l});try{const a=await r()({url:`${i.current}/step`,method:"POST",data:{step:e,data:s}});return t({type:j,payload:a}),a}catch(e){return t({type:C,payload:{error:A(e),rollbackState:n}}),null}},[a.wizardState]),o=(0,s.useCallback)(async()=>{t({type:S});try{return await r()({url:`${i.current}/complete`,method:"POST"}),t({type:k}),!0}catch(e){return t({type:f,payload:A(e)}),!1}},[]),d=(0,s.useCallback)(()=>t({type:N}),[]);(0,s.useEffect)(()=>{const e=()=>{"ready"===a.status&&l()},s=()=>{"visible"===document.visibilityState&&e()};return window.addEventListener("focus",e),document.addEventListener("visibilitychange",s),window.addEventListener("popstate",e),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",s),window.removeEventListener("popstate",e)}},[l,a.status]);const p={state:a,isLoading:"loading"===a.status||"saving"===a.status,error:a.error,refetch:l,saveStep:c,complete:o,clearError:d};return(0,n.jsx)(M.Provider,{value:p,children:e})},z=()=>{const e=(0,s.useContext)(M);if(!e)throw new Error("useWizardState must be used within <WizardStateProvider>");return e},P=(0,s.createContext)({setCanAdvance:()=>{},setBeforeAdvance:()=>{},setFooterAction:()=>{},setHideContinue:()=>{},setBelowFooter:()=>{},advance:()=>{}}),T=e=>{const{setFooterAction:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(e||null),()=>a(null)),[e,a])},R=(e,a=null)=>{const{setCanAdvance:r,setBeforeAdvance:t}=(0,s.useContext)(P);(0,s.useEffect)(()=>(r(!!e),t(()=>a),()=>{r(!0),t(()=>null)}),[e,a,r,t])},$=({selected:e=!1,onSelect:s,title:a,subtitle:r,badge:t=null,children:i=null,name:l="qs-card",value:c=""})=>(0,n.jsxs)("label",{className:"qs-card"+(e?" qs-card--selected":""),role:"radio","aria-checked":e,tabIndex:0,onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),s?.())},children:[(0,n.jsx)("input",{type:"radio",name:l,value:c,checked:e,onChange:()=>s?.(),style:{position:"absolute",opacity:0,pointerEvents:"none"},tabIndex:-1}),(0,n.jsx)("span",{className:"qs-card__radio","aria-hidden":"true"}),(0,n.jsxs)("div",{className:"qs-card__body",children:[(0,n.jsxs)("div",{className:"qs-card__title",children:[a,t]}),r&&(0,n.jsx)("div",{className:"qs-card__subtitle",children:r}),i]})]}),I=["acrossai-mcp-server","mcp-adapter-default-server"],L=I[0],B=()=>{const{state:e,saveStep:a}=z(),r=e.wizardState.server_id,i=!!e.wizardState.create_intent;(0,s.useEffect)(()=>{"ready"!==e.status||0!==e.servers.length||i||a(1,{create_intent:!0})},[e.status,e.servers.length,i,a]),(0,s.useEffect)(()=>{if("ready"!==e.status||null!==r||i||0===e.servers.length)return;const s=I.reduce((s,a)=>s||e.servers.find(e=>e.slug===a),null)||e.servers[0];s&&a(1,{server_id:s.id})},[e.status,e.servers,r,i,a]),R(null!==r||i);const l=(0,s.useMemo)(()=>{const s=e.servers||[];return[...s.filter(e=>e.slug===L),...s.filter(e=>e.slug!==L)]},[e.servers]);return(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Which server should AI connect to?","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Pick an existing MCP server, or create a new one for this setup.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{role:"radiogroup","aria-label":(0,t.__)("MCP servers","acrossai-mcp-manager"),children:[l.map(e=>(0,n.jsx)($,{name:"qs-server-pick",value:String(e.id),selected:!i&&r===e.id,onSelect:()=>(async e=>{await a(1,{server_id:e})})(e.id),title:e.name,subtitle:(0,n.jsx)("code",{children:e.route_full}),badge:(0,n.jsxs)(n.Fragment,{children:[e.slug===L?(0,n.jsx)("span",{className:"qs-card__badge qs-card__badge--recommended",children:(0,t.__)("Recommended","acrossai-mcp-manager")}):null,e.enabled?null:(0,n.jsx)("span",{className:"qs-card__badge qs-card__badge--inactive",children:(0,t.__)("Inactive","acrossai-mcp-manager")})]})},e.id)),(0,n.jsx)($,{name:"qs-server-pick",value:"__create__",selected:i,onSelect:async()=>{await a(1,{create_intent:!0})},title:(0,t.__)("+ Create a new server","acrossai-mcp-manager"),subtitle:(0,t.__)("Set up a brand-new MCP server for this wizard.","acrossai-mcp-manager")})]})]})},U=e=>String(e).toLowerCase().replace(/[^a-z0-9\-_]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-"),W=()=>{const{saveStep:e}=z(),[a,r]=(0,s.useState)({server_name:"",server_slug:"",description:"",server_route_namespace:"mcp",server_route:"",server_version:"v1.0.0"}),[i,l]=(0,s.useState)(!1),[c,o]=(0,s.useState)(!1),[d,p]=(0,s.useState)(null),m=(0,s.useCallback)(async()=>{if(p(null),!a.server_name.trim())return p((0,t.__)("Server name is required.","acrossai-mcp-manager")),!1;const s=await e(2,{new_server:a});return!!(s&&s.wizardState&&s.wizardState.server_id)},[a,e]);return R(a.server_name.trim().length>0,m),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Create a new MCP server","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Fill in a name — the rest is auto-filled. Click Continue when you're done.","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Name","acrossai-mcp-manager")}),(0,n.jsx)("span",{style:{color:"#cc1818",marginLeft:4},children:"*"}),(0,n.jsx)("input",{type:"text",value:a.server_name,onChange:e=>{return s=e.target.value,void r(e=>({...e,server_name:s,server_slug:i?e.server_slug:U(s),server_route:c?e.server_route:U(s)}));var s},required:!0,style:{display:"block",width:"100%",padding:"8px",marginTop:4}})]})}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Slug","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_slug,onChange:e=>{return s=e.target.value,l(!0),void r(e=>({...e,server_slug:s,server_route:c?e.server_route:U(s)}));var s},style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]})}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Description","acrossai-mcp-manager")}),(0,n.jsx)("textarea",{value:a.description,onChange:e=>r(s=>({...s,description:e.target.value})),rows:3,style:{display:"block",width:"100%",padding:"8px",marginTop:4}})]})}),(0,n.jsxs)("div",{style:{display:"flex",gap:12,marginBottom:16},children:[(0,n.jsxs)("label",{style:{flex:1},children:[(0,n.jsx)("strong",{children:(0,t.__)("Route namespace","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_route_namespace,onChange:e=>r(s=>({...s,server_route_namespace:e.target.value})),style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]}),(0,n.jsxs)("label",{style:{flex:1},children:[(0,n.jsx)("strong",{children:(0,t.__)("Route","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_route,onChange:e=>{o(!0),r(s=>({...s,server_route:e.target.value}))},style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]}),(0,n.jsxs)("label",{style:{flex:"0 0 120px"},children:[(0,n.jsx)("strong",{children:(0,t.__)("Version","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_version,onChange:e=>r(s=>({...s,server_version:e.target.value})),style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]})]}),d&&(0,n.jsx)("div",{style:{color:"#cc1818",marginBottom:16},role:"alert",children:d})]})},O=[{value:"",label:"No user access added by admin"},{value:"everyone",label:"Public (no login required)"},{value:"authenticated",label:"Any logged-in user"}];function F({providers:e,value:s,onChange:a}){const r=e.filter(e=>!1!==e.available);return(0,n.jsxs)("select",{className:"wpb-ac__select",value:s,onChange:e=>a(e.target.value),children:[O.map(e=>(0,n.jsx)("option",{value:e.value,children:e.label},e.value)),r.map(e=>(0,n.jsx)("option",{value:e.id,children:e.label},e.id))]})}const Q={wp_role:"Select which WordPress Role values may access this resource. Leave all unchecked to deny everyone (except administrators).",wp_capability:"Select which WordPress capabilities grant access. Users holding any of the checked capabilities are allowed. Administrators always have access.",bb_profile_type:"Select which BuddyBoss profile types grant access. Users assigned to any of the checked profile types are allowed. Administrators always have access.",mepr_membership:"Select which MemberPress memberships grant access. Users with an active subscription to any of the checked memberships are allowed. Administrators always have access."};function D({providerId:e,options:s,selectedOptions:a,onToggle:r}){const t=Q[e]||null;return(0,n.jsxs)("div",{className:"wpb-ac__options-panel",children:[t&&(0,n.jsx)("p",{className:"wpb-ac__panel-description",children:t}),(0,n.jsx)("ul",{className:"wpb-ac__checkbox-list",children:s.map(e=>(0,n.jsx)("li",{className:"wpb-ac__checkbox-item",children:(0,n.jsxs)("label",{children:[(0,n.jsx)("input",{type:"checkbox",value:e.id,checked:a.includes(e.id),onChange:()=>r(e.id)}),e.label]})},e.id))})]})}function H({pluginSlug:e,restApiRoot:a,selectedUsers:t,onAdd:i,onRemove:l}){const[c,o]=(0,s.useState)(""),[d,p]=(0,s.useState)([]),[m,u]=(0,s.useState)(!1),g=(0,s.useRef)(null),_=(0,s.useRef)(null);(0,s.useEffect)(()=>{const e=e=>{_.current&&!_.current.contains(e.target)&&u(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);const h=(0,s.useCallback)(s=>{if(!s.trim())return p([]),void u(!1);r()({url:`${a}/wpb-ac/v1/${e}/users?search=${encodeURIComponent(s)}`}).then(e=>{p(e||[]),u(!0)}).catch(()=>p([]))},[e,a]),v=(0,s.useCallback)(e=>{const s=e.target.value;o(s),clearTimeout(g.current),g.current=setTimeout(()=>h(s),300)},[h]),b=(0,s.useCallback)(e=>{i({id:e.id,login:e.login,display_name:e.display_name}),o(""),p([]),u(!1)},[i]),x=d.filter(e=>!t.find(s=>s.id===e.id));return(0,n.jsxs)("div",{className:"wpb-ac__user-panel",ref:_,children:[(0,n.jsx)("p",{className:"wpb-ac__panel-description",children:"Search by username or email and select one or more users. Administrators always have access regardless of this list."}),(0,n.jsxs)("div",{className:"wpb-ac__search-wrapper",children:[(0,n.jsx)("input",{type:"text",className:"wpb-ac__search-input",placeholder:"Search by username or email...",value:c,onChange:v,onFocus:()=>x.length&&u(!0)}),m&&x.length>0&&(0,n.jsx)("ul",{className:"wpb-ac__search-dropdown",children:x.map(e=>(0,n.jsxs)("li",{className:"wpb-ac__search-option",onMouseDown:()=>b(e),children:[e.display_name," (",e.login,")"]},e.id))})]}),t.length>0&&(0,n.jsx)("div",{className:"wpb-ac__user-tags",children:t.map(e=>(0,n.jsxs)("span",{className:"wpb-ac__user-tag",children:[e.display_name," (",e.login,")",(0,n.jsx)("button",{type:"button",className:"wpb-ac__tag-remove",onClick:()=>l(e.id),"aria-label":`Remove ${e.display_name}`,children:"×"})]},e.id))})]})}function Y({pluginSlug:e,namespace:a,resourceKey:t,restApiRoot:i,nonce:l,title:c="Access Control",description:o="Control which users are allowed to connect to this MCP server. Administrators always have access regardless of this setting.",saveLabel:d="Save Access Control",onSave:p,hideSaveButton:m=!1,hideHeader:u=!1,onChange:g}){const[_,h]=(0,s.useState)(!0),[v,b]=(0,s.useState)(!1),[x,y]=(0,s.useState)(null),[f,w]=(0,s.useState)([]),[j,C]=(0,s.useState)(""),[S,k]=(0,s.useState)([]),[N,q]=(0,s.useState)([]),A=a.split("/").map(encodeURIComponent).join("%2F"),M=(0,s.useCallback)(e=>{const s=e.map(e=>`include[]=${e}`).join("&");r()({url:`${i}/wp/v2/users?${s}&per_page=100`}).then(e=>{q(e.map(e=>({id:String(e.id),login:e.slug,display_name:e.name})))}).catch(()=>{q(e.map(e=>({id:e,login:e,display_name:e})))})},[i]);(0,s.useEffect)(()=>{if(!t)return void h(!1);h(!0),y(null),w([]),C(""),k([]),q([]);let s=!1;return Promise.all([r()({url:`${i}/wpb-ac/v1/${e}/providers`}),r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`})]).then(([e,a])=>{if(s)return;w(e);const r=a.key||"",t=a.value||[];C(r),k(t),"wp_user"===r&&t.length>0&&M(t)}).catch(()=>{}).finally(()=>{s||h(!1)}),()=>{s=!0}},[e,i,A,t]);const E=(0,s.useCallback)(e=>{C(e),k([]),q([]),y(null)},[]),z=(0,s.useCallback)(e=>{k(s=>s.includes(e)?s.filter(s=>s!==e):[...s,e])},[]),P=(0,s.useCallback)(e=>{q(s=>s.find(s=>s.id===e.id)?s:[...s,e]),k(s=>s.includes(e.id)?s:[...s,e.id])},[]),T=(0,s.useCallback)(e=>{q(s=>s.filter(s=>s.id!==e)),k(s=>s.filter(s=>s!==e))},[]),R=(0,s.useCallback)(async()=>{b(!0),y(null);try{""===j?await r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`,method:"DELETE"}):await r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`,method:"PUT",data:{ac_key:j,ac_options:S}}),y({type:"success",message:"Access control saved."}),p?.(j,S)}catch(e){y({type:"error",message:e?.message||"Failed to save."})}finally{b(!1)}},[j,S,e,A,t,i,p]);(0,s.useEffect)(()=>{_||g?.(j,S)},[j,S,_]);const $=f.find(e=>e.id===j)||null,I=$&&"wp_user"!==$.id&&$.options?.length>0,L="wp_user"===j;return _?(0,n.jsx)("div",{className:"wpb-ac wpb-ac--loading",children:"Loading…"}):(0,n.jsxs)("div",{className:"wpb-ac",children:[!u&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("h2",{className:"wpb-ac__title",children:c}),(0,n.jsx)("p",{className:"wpb-ac__description",children:o})]}),(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:"Who can access"}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(F,{providers:f,value:j,onChange:E})})]}),I&&(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:$.label}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(D,{providerId:j,options:$.options,selectedOptions:S,onToggle:z})})]}),L&&(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:$?.label||"Users"}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(H,{pluginSlug:e,restApiRoot:i,selectedUsers:N,onAdd:P,onRemove:T})})]}),x&&(0,n.jsx)("p",{className:`wpb-ac__notice wpb-ac__notice--${x.type}`,children:x.message}),!m&&(0,n.jsx)("div",{className:"wpb-ac__footer",children:(0,n.jsx)("button",{type:"button",className:"wpb-ac__save-btn",onClick:R,disabled:v,children:v?"Saving…":d})})]})}const G=({pluginSlug:e,namespace:a="acrossai-mcp-manager",resourceKey:r,restApiRoot:t="/wp-json",nonce:n="",title:i,description:l,saveLabel:c,hideSaveButton:o=!1,onChange:d,onSave:p})=>e&&r?(0,s.createElement)(Y,{pluginSlug:e,namespace:a,resourceKey:r,restApiRoot:t,nonce:n,title:i||void 0,description:l||void 0,saveLabel:c||void 0,hideSaveButton:o,onChange:d,onSave:p}):null,V=()=>{const{state:e}=z(),a=(()=>{const{advance:e}=(0,s.useContext)(P);return e})(),i=window.acrossaiMcpQuickConnect||{},[c,o]=(0,s.useState)(null),[d,p]=(0,s.useState)(!1),m=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),u=(0,s.useRef)({key:null,options:[]}),g=(0,s.useCallback)((e,s)=>{u.current={key:e,options:Array.isArray(s)?s:[]}},[]),_=(0,s.useCallback)(async()=>{if(o(null),!m||null===u.current.key||""===u.current.key)return void a();const e=i.acPluginSlug||"mcp",s=i.acNamespace||"acrossai-mcp-manager",n=`${i.restApiRoot||"/wp-json"}/wpb-ac/v1/${e}/rules/${encodeURIComponent(s)}/${m.slug}`;p(!0);try{await r()({url:n,method:"PUT",data:{ac_key:u.current.key,ac_options:u.current.options}}),a()}catch(e){o(e&&e.message||(0,t.__)("Failed to save access control. Try again.","acrossai-mcp-manager"))}finally{p(!1)}},[m,i.acPluginSlug,i.acNamespace,i.restApiRoot,a]),h=(0,s.useMemo)(()=>m?{label:(0,t.__)("Save and Continue","acrossai-mcp-manager"),onClick:_,isLoading:d,disabled:d}:null,[m,_,d]);return T(h),m?(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Who can reach this server?","acrossai-mcp-manager")}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("Only administrators can reach this server until you add an access rule below.","acrossai-mcp-manager")}),c&&(0,n.jsx)(l,{status:"error",children:c}),(0,n.jsx)(G,{pluginSlug:i.acPluginSlug||"mcp",namespace:i.acNamespace||"acrossai-mcp-manager",resourceKey:m.slug,restApiRoot:i.restApiRoot||"/wp-json",nonce:i.restNonce||"",hideSaveButton:!0,onChange:g}),(0,n.jsx)("p",{className:"qs__step-subtitle",style:{marginTop:24},children:(0,t.__)("Continue skips saving (leaves current rule as-is). Save and Continue writes your changes and moves on. You can change this anytime under the server's Access Control tab.","acrossai-mcp-manager")})]}):(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Who can reach it?","acrossai-mcp-manager")}),(0,n.jsx)("p",{children:(0,t.__)("No server selected — go back to Step 1.","acrossai-mcp-manager")})]})},K=["Blocks","Cache","Comments","Content Search","Core","Cron","Database","File Manager","Media","Plugins","Rank Math","Settings","Site Health","Themes","Users","Widgets"],J=()=>{const{state:e,refetch:a}=z(),[i,c]=(0,s.useState)(!1),[o,d]=(0,s.useState)(null),p="missing"===e.plugins.abilitiesManager,m=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id)||null,[e.servers,e.wizardState.server_id]),u=null!==m&&!1===m.type_available;R(!u);const g=(0,s.useCallback)(async()=>{c(!0),d(null);try{const e=(window.acrossaiMcpQuickConnect||{}).restUrl||"/wp-json/acrossai-mcp-manager/v1/quick-connect";await r()({url:`${e}/install-plugin`,method:"POST",data:{slug:"acrossai-abilities-manager"}}),await a()}catch(e){d(e&&e.message||(0,t.__)("Something went wrong. Try again or install the plugin manually.","acrossai-mcp-manager"))}finally{c(!1)}},[a]),_=i?p?(0,t.__)("Installing…","acrossai-mcp-manager"):(0,t.__)("Activating…","acrossai-mcp-manager"):p?(0,t.__)("Install & Continue","acrossai-mcp-manager"):(0,t.__)("Activate & Continue","acrossai-mcp-manager"),h=(0,s.useMemo)(()=>({label:_,onClick:g,isLoading:i,disabled:i}),[_,g,i]);T(h);const v=(0,n.jsxs)("span",{className:"qs__brand-mark qs__brand-mark--inline",children:[(0,n.jsx)("span",{className:"qs__brand-mark__across",children:"Across"}),(0,n.jsx)("span",{className:"qs__brand-mark__ai",children:"AI"})]}),b=(0,s.createInterpolateElement)(p?(0,t.__)("Install <brand/> Abilities Manager","acrossai-mcp-manager"):(0,t.__)("Activate <brand/> Abilities Manager","acrossai-mcp-manager"),{brand:v});return(0,n.jsxs)("div",{children:[o&&(0,n.jsx)("div",{style:{marginBottom:20},children:(0,n.jsx)(l,{status:"error",children:o})}),u&&(0,n.jsx)("div",{style:{marginBottom:20},children:(0,n.jsx)(l,{status:"warning",children:(0,t.__)("This server's type requires the AcrossAI Abilities Manager, so it cannot be enabled later in this setup without it. Install it below, or go back and choose a different server type.","acrossai-mcp-manager")})}),(0,n.jsxs)("div",{className:"qs__gate-card",children:[(window.acrossaiMcpQuickConnect||{}).logoUrl&&(0,n.jsx)("img",{className:"qs__gate-card__logo",src:window.acrossaiMcpQuickConnect.logoUrl,alt:"","aria-hidden":"true"}),(0,n.jsx)("h2",{className:"qs__step-title",children:b}),(0,n.jsxs)("div",{className:"qs__gate-categories",children:[(0,n.jsx)("p",{className:"qs__gate-categories-label",children:(0,t.__)("Includes 350+ abilities for:","acrossai-mcp-manager")}),(0,n.jsx)("ul",{className:"qs__gate-bullets qs__gate-bullets--grid",children:K.map(e=>(0,n.jsx)("li",{children:e},e))})]}),(0,n.jsx)("div",{className:"qs__gate-actions",children:(0,n.jsx)("a",{className:"qs-btn qs-btn--secondary",href:"https://wordpress.org/plugins/acrossai-abilities-manager/",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("View on WordPress.org ↗","acrossai-mcp-manager")})})]}),(0,n.jsx)("div",{style:{marginTop:24},children:(0,n.jsx)(l,{status:"info",children:(0,t.__)("You can Continue without installing — the wizard will fall back to the 3 abilities WordPress ships with. Or install the plugin now to unlock the full 350+ set. You can broaden per-ability access in the next step.","acrossai-mcp-manager")})})]})},X=["core/get-environment-info","core/get-site-info","core/get-user-info"],Z=()=>{const{state:e,saveStep:a,isLoading:r}=z(),[i,c]=(0,s.useState)(!1),o=window.acrossaiMcpQuickConnect||{},d=e.plugins.abilitiesManager,p="active"===d,m="inactive"===d,u=e.plugins.abilitiesManagerActivateUrl||"",g=e.wizardState.server_id,_=e.abilities.total,h=e.abilities.enabledForServer,v=_>0&&null!==h&&h>=_,b=(0,s.useCallback)(async()=>{c(!0);try{await a(5,{enable_all_abilities:!0})}finally{c(!1)}},[a]),x=(0,s.useMemo)(()=>p&&!v?{label:(0,t.__)("Enable all and continue","acrossai-mcp-manager"),onClick:b,isLoading:i||r,disabled:i||r}:null,[p,v,b,i,r]);return T(x),p?(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("What should AI be able to do?","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-end",gap:16,justifyContent:"center",margin:"20px 0"},children:[(0,n.jsx)("span",{style:{fontSize:60,fontWeight:700,lineHeight:.9},children:null!==h?`${h} / ${_}`:_}),(0,n.jsxs)("div",{style:{paddingBottom:8},children:[(0,n.jsx)("div",{style:{fontSize:15,fontWeight:600},children:null!==h?(0,t.__)("enabled for this server","acrossai-mcp-manager"):(0,t.__)("abilities available","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{fontSize:13,color:"#757575"},children:(0,t.__)("From AcrossAI Abilities Manager.","acrossai-mcp-manager")})]})]}),v&&(0,n.jsx)(l,{status:"success",children:(0,t.__)("All abilities enabled for this server ✓","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{display:"flex",justifyContent:"center",marginBottom:20},children:(0,n.jsx)("a",{className:"qs-btn qs-btn--secondary",href:o.adminUrl&&g?`${o.adminUrl}&action=edit&server=${g}&tab=abilities`:"#",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("Configure abilities one-by-one ↗","acrossai-mcp-manager")})}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("By default, all abilities registered by Abilities Manager can be accessed by users with the manage_options capability (admins only). You can broaden this per-ability in the Access Control step.","acrossai-mcp-manager")})]}):(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("What should AI be able to do?","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-end",gap:16,justifyContent:"center",margin:"20px 0"},children:[(0,n.jsx)("span",{style:{fontSize:60,fontWeight:700,lineHeight:.9},children:null!==h?`${h} / ${_}`:_}),(0,n.jsxs)("div",{style:{paddingBottom:8},children:[(0,n.jsx)("div",{style:{fontSize:15,fontWeight:600},children:null!==h?(0,t.__)("enabled for this server","acrossai-mcp-manager"):(0,t.__)("abilities available","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{fontSize:13,color:"#757575"},children:(0,t.__)("WordPress ships with only 3 by default.","acrossai-mcp-manager")})]})]}),(0,n.jsx)("ul",{style:{listStyle:"none",padding:0,marginBottom:24,border:"1px solid #ddd",borderRadius:2},children:X.map(e=>(0,n.jsxs)("li",{style:{padding:"11px 14px",borderBottom:"1px solid #f0f0f0",fontFamily:"monospace",fontSize:12},children:["• ",e]},e))}),(0,n.jsxs)("div",{style:{border:"1px solid #c4b5fd",background:"#faf9ff",padding:20,borderRadius:2,marginBottom:20},children:[(0,n.jsx)("h3",{style:{margin:"0 0 12px",fontSize:15,fontWeight:600,color:"#312e81"},children:m?(0,t.__)("Activate AcrossAI Abilities Manager to unlock 350+ abilities","acrossai-mcp-manager"):(0,t.__)("Unlock 350+ abilities with AcrossAI Abilities Manager","acrossai-mcp-manager")}),(0,n.jsx)("p",{style:{fontSize:13,lineHeight:1.65,color:"#4c1d95",margin:"0 0 16px"},children:m?(0,t.__)("The plugin is already installed on this site. Activate it now to add 350+ new abilities your AI client can use.","acrossai-mcp-manager"):(0,t.__)("Create pages, update content, install plugins, update WordPress core, manage your entire site — all from your AI client.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",gap:14,alignItems:"center"},children:[m&&u?(0,n.jsx)("a",{className:"qs-btn",href:u,style:{background:"#4f46e5",borderColor:"#4f46e5"},children:(0,t.__)("Activate Abilities Manager","acrossai-mcp-manager")}):(0,n.jsx)("a",{className:"qs-btn",href:"https://wordpress.org/plugins/acrossai-abilities-manager/",target:"_blank",rel:"noopener noreferrer",style:{background:"#4f46e5",borderColor:"#4f46e5"},children:(0,t.__)("Install from WordPress.org","acrossai-mcp-manager")}),(0,n.jsx)("a",{href:"https://acrossai.co/use-cases/",target:"_blank",rel:"noopener noreferrer",style:{color:"#4f46e5",textDecoration:"none"},children:(0,t.__)("View case studies →","acrossai-mcp-manager")})]})]}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("By default, all abilities registered by Abilities Manager can be accessed by users with the manage_options capability (admins only). You can broaden this per-ability in the Access Control step.","acrossai-mcp-manager")})]})},ee=()=>{const{saveStep:e}=z(),[a,r]=(0,s.useState)(!1),i=(0,s.useCallback)(async()=>{r(!0);try{await e(6,{enabled:!0})}finally{r(!1)}},[e]),c=(0,s.useMemo)(()=>({label:(0,t.__)("Enable & Continue","acrossai-mcp-manager"),onClick:i,isLoading:a,disabled:a}),[i,a]);return T(c),((e=!0)=>{const{setHideContinue:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(!!e),()=>a(!1)),[e,a])})(!0),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Turn on your MCP endpoint","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("One more step. Your server needs to be enabled before it will accept any MCP requests.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{className:"qs__gate-card qs__gate-card--warning",children:[(0,n.jsxs)("div",{className:"qs__gate-stat",children:[(0,n.jsx)("span",{className:"qs__gate-stat-icon","aria-hidden":"true",children:"⏻"}),(0,n.jsx)("span",{className:"qs__gate-stat-label qs__gate-stat-label--warning",children:(0,t.__)("Server is currently disabled","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{className:"qs__gate-copy",children:(0,t.__)("While disabled, this server rejects every MCP request — even from administrators. Enable it to start accepting connections from your AI clients.","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__gate-copy qs__gate-copy--muted",children:(0,t.__)("You can disable this server at any time from the server list.","acrossai-mcp-manager")})]}),(0,n.jsx)("div",{style:{marginTop:24},children:(0,n.jsx)(l,{status:"info",children:(0,s.createInterpolateElement)((0,t.__)("AcrossAI MCP Manager runs on top of the <a>MCP Adapter</a> framework and adds an admin safety layer: every server starts disabled so a half-configured server can never accidentally accept requests. Enable this one once you've reviewed its access rules and abilities.","acrossai-mcp-manager"),{a:(0,n.jsx)("a",{href:"https://github.com/wordpress/mcp-adapter",target:"_blank",rel:"noopener noreferrer"})})})})]})},se=(e=20)=>({width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,focusable:!1}),ae=({size:e})=>(0,n.jsxs)("svg",{...se(e),children:[(0,n.jsx)("polyline",{points:"4 17 10 11 4 5"}),(0,n.jsx)("line",{x1:"12",y1:"19",x2:"20",y2:"19"})]}),re=({size:e})=>(0,n.jsx)("svg",{...se(e),children:(0,n.jsx)("polyline",{points:"20 6 9 17 4 12"})}),te=[{key:"connectors",title:(0,t.__)("One-click OAuth (Connectors)","acrossai-mcp-manager"),description:(0,t.__)("Paste one URL into Claude, ChatGPT, Grok, or Gemini and approve. No config files.","acrossai-mcp-manager"),icon:({size:e})=>(0,n.jsxs)("svg",{...se(e),children:[(0,n.jsx)("path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"}),(0,n.jsx)("path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"})]})},{key:"client",title:(0,t.__)("MCP Client","acrossai-mcp-manager"),description:(0,t.__)("Paste a JSON config into Claude Desktop, VS Code, Cursor, and more.","acrossai-mcp-manager"),icon:({size:e})=>(0,n.jsx)("svg",{...se(e),children:(0,n.jsx)("path",{d:"M19.439 7.85c-.049.322.059.648.289.878l1.568 1.568c.47.47.706 1.087.706 1.704s-.235 1.233-.706 1.704l-1.611 1.611a.98.98 0 0 1-.837.276c-.47-.07-.802-.48-.968-.925a2.501 2.501 0 1 0-3.214 3.214c.446.166.855.497.925.968a.979.979 0 0 1-.276.837l-1.61 1.61a2.404 2.404 0 0 1-1.705.707 2.402 2.402 0 0 1-1.704-.706l-1.568-1.568a1.026 1.026 0 0 0-.877-.29c-.493.074-.84.504-1.02.968a2.5 2.5 0 1 1-3.237-3.237c.464-.18.894-.527.967-1.02a1.026 1.026 0 0 0-.289-.877l-1.568-1.568A2.402 2.402 0 0 1 1.998 12c0-.617.236-1.234.706-1.704L4.23 8.77c.24-.24.581-.353.917-.303.515.077.877.528 1.073 1.01a2.5 2.5 0 1 0 3.259-3.259c-.482-.196-.933-.558-1.01-1.073-.05-.336.062-.676.303-.917l1.525-1.525A2.402 2.402 0 0 1 12 1.998c.617 0 1.234.236 1.704.706l1.568 1.568c.23.23.556.338.877.29.493-.074.84-.504 1.02-.968a2.5 2.5 0 1 1 3.237 3.237c-.464.18-.894.527-.967 1.02Z"})})},{key:"npm",title:(0,t.__)("npm (one-line install)","acrossai-mcp-manager"),description:(0,t.__)("Run a single npx command — no config files, no JSON.","acrossai-mcp-manager"),icon:ae},{key:"wpcli",title:(0,t.__)("WP-CLI (local subprocess)","acrossai-mcp-manager"),description:(0,t.__)("Best for CI or local dev. No network credentials transmitted.","acrossai-mcp-manager"),icon:ae}],ne=()=>{const{state:e,saveStep:a}=z(),r=e.wizardState.method,[i,l]=(0,s.useState)(null);R(null!==r);const c=(0,s.useCallback)(async e=>{l(e);try{await a(7,{method:e})}finally{l(null)}},[a]);return(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("How do you want to connect?","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Pick a connection method. You can add more later from the server's edit page.","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, minmax(0, 1fr))",gap:12},role:"radiogroup","aria-label":(0,t.__)("Connection methods","acrossai-mcp-manager"),children:te.map(e=>{const s=e.icon,a="connectors"===e.key,l=i===e.key;return(0,n.jsx)($,{name:"qs-method",value:e.key,selected:r===e.key,onSelect:l?void 0:()=>c(e.key),title:(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s,{size:18})," ",e.title,a&&(0,n.jsx)("span",{className:"qs-card__badge",children:(0,t.__)("RECOMMENDED","acrossai-mcp-manager")})]}),subtitle:e.description},e.key)})})]})},ie=window.wp.compose,le=({variant:e="inline",children:a,title:r})=>{const[i,l]=(0,s.useState)(!1);(0,s.useEffect)(()=>{if(!i)return;const e=setTimeout(()=>l(!1),2e3);return()=>clearTimeout(e)},[i]);const c=(0,ie.useCopyToClipboard)("string"==typeof a?a:"",()=>l(!0));return"pane"===e?(0,n.jsxs)("div",{className:"qs-code qs-code--pane",children:[(0,n.jsxs)("div",{className:"qs-code__title-bar",children:[(0,n.jsx)("span",{children:r||(0,t.__)("code","acrossai-mcp-manager")}),(0,n.jsx)("button",{ref:c,type:"button",className:"qs-code__copy-btn","aria-label":(0,t.__)("Copy code to clipboard","acrossai-mcp-manager"),children:i?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy config","acrossai-mcp-manager")})]}),(0,n.jsx)("pre",{children:a})]}):(0,n.jsxs)("div",{className:"qs-code qs-code--inline",children:[(0,n.jsx)("code",{children:a}),(0,n.jsx)("button",{ref:c,type:"button",className:"qs-code__copy-btn","aria-label":(0,t.__)("Copy command to clipboard","acrossai-mcp-manager"),children:i?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy","acrossai-mcp-manager")})]})},ce=()=>{const{state:e}=z(),s=e.setupRequired;return s&&s.message?(0,n.jsxs)(l,{status:"warning",children:[(0,n.jsx)("p",{children:(0,n.jsx)("strong",{children:(0,t.__)("Connection details are not ready yet.","acrossai-mcp-manager")})}),(0,n.jsx)("p",{children:s.message}),(0,n.jsx)("p",{children:(0,t.__)("Install and activate it, then return to this step — the server is already enabled, so nothing else needs changing.","acrossai-mcp-manager")})]}):null},oe=()=>{const{state:e}=z(),a=window.acrossaiMcpQuickConnect||{},r=e.methods.ai_connectors||[],[i,c]=(0,s.useState)(r[0]?r[0].slug:""),o=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),d=r.find(e=>e.slug===i),p=o?`${a.siteUrl||""}/wp-json/${o.route_full}`:"",m=e.methods.ai_connector_instructions||{},u=d&&m[d.slug]||"",g=u?u.replaceAll("__ACROSSAI_MCP_URL__",String(p).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")):"";return(e=>{const{setBelowFooter:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(e||null),()=>a(null)),[e,a])})((0,s.useMemo)(()=>o&&0!==r.length&&g?(0,n.jsx)("div",{className:"acrossai-mcp-connector-panel__setup-embed",dangerouslySetInnerHTML:{__html:g}}):null,[o,r.length,g])),o?0===r.length?(0,n.jsx)(l,{status:"info",children:(0,t.__)("No AI connectors are available on this site.","acrossai-mcp-manager")}):(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("div",{role:"tablist","aria-label":(0,t.__)("Connector providers","acrossai-mcp-manager"),style:{display:"flex",gap:8,marginBottom:16,flexWrap:"wrap"},children:r.map(e=>{const s=e.slug===i;return(0,n.jsx)("button",{type:"button",role:"tab","aria-selected":s,onClick:()=>c(e.slug),className:s?"qs-btn":"qs-btn qs-btn--secondary",children:e.name||e.slug},e.slug)})}),d&&(0,n.jsxs)("div",{children:[(0,n.jsx)("h3",{style:{margin:"0 0 12px",fontSize:16},children:d.name||d.slug}),(0,n.jsx)("p",{style:{fontSize:13,color:"#757575",marginBottom:8},children:(0,t.__)("MCP URL to paste into your AI client:","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:p}),!g&&(0,n.jsx)(l,{status:"info",children:(0,t.__)("This connector supports Dynamic Client Registration only — paste the MCP URL above into your AI client and it will register itself. No manual credentials to generate.","acrossai-mcp-manager")})]})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},de=()=>{const{state:e}=z(),a=e.methods.clients||[],[i,c]=(0,s.useState)(a[0]?a[0].slug:""),[o,d]=(0,s.useState)(!1),[p,m]=(0,s.useState)(""),[u,g]=(0,s.useState)(null),[_,h]=(0,s.useState)(!1);(0,s.useEffect)(()=>{m(""),g(null),h(!1)},[i]),(0,s.useEffect)(()=>{if(!_)return;const e=setTimeout(()=>h(!1),2e3);return()=>clearTimeout(e)},[_]);const v=(0,ie.useCopyToClipboard)(p,()=>h(!0)),b=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),x=(0,s.useMemo)(()=>a.find(e=>e.slug===i),[a,i]),y=(0,s.useCallback)(async()=>{if(b&&x){d(!0),g(null),m("");try{const e=await r()({path:"/acrossai-mcp-manager/v1/generate-app-password",method:"POST",data:{server_id:b.id,name:`Quick Edit - ${x.name||x.slug}`}});e&&e.password?m(String(e.password)):g((0,t.__)("Password generation succeeded but the response was malformed.","acrossai-mcp-manager"))}catch(e){g(e&&e.message||(0,t.__)("Could not generate the Application Password.","acrossai-mcp-manager"))}finally{d(!1)}}},[b,x]);if(!b)return(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")});if(0===a.length)return(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No MCP clients registered on this site.","acrossai-mcp-manager")});const f=(0,s.useMemo)(()=>{let e=x&&x.config?"string"==typeof x.config?x.config:JSON.stringify(x.config,null,2):JSON.stringify(x||{},null,2);return p&&(e=e.split("(paste generated password here)").join(p)),e},[x,p]),w=x?`json · ${x.name||x.slug}`:"json";return(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("div",{style:{marginBottom:12},children:(0,n.jsx)("span",{style:{fontSize:11,fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase",color:"#757575"},children:(0,t.__)("Choose your client","acrossai-mcp-manager")})}),(0,n.jsx)("div",{role:"tablist","aria-label":(0,t.__)("MCP clients","acrossai-mcp-manager"),style:{display:"flex",gap:7,flexWrap:"wrap",marginBottom:16},children:a.map(e=>{const s=e.slug===i;return(0,n.jsx)("button",{type:"button",role:"tab","aria-selected":s,onClick:()=>c(e.slug),className:s?"qs-btn":"qs-btn qs-btn--secondary",children:e.name||e.slug},e.slug)})}),(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 1","acrossai-mcp-manager")}),(0,t.__)("Generate the password","acrossai-mcp-manager")]}),(0,n.jsxs)("div",{className:"qs-step-body qs-generate-section",children:[(0,n.jsx)("button",{type:"button",className:"qs-btn qs-generate-section__btn",onClick:y,disabled:o,children:o?(0,t.__)("Generating…","acrossai-mcp-manager"):(0,t.__)("Generate New Application Password","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs-generate-section__desc",children:(0,t.__)("Creates a one-time password via WordPress Application Passwords. Shown only once — store it safely.","acrossai-mcp-manager")}),p&&(0,n.jsxs)("div",{className:"qs-generate-section__reveal",children:[(0,n.jsxs)("div",{className:"qs-generate-section__reveal-row",children:[(0,n.jsx)("input",{type:"text",readOnly:!0,value:p,className:"qs-generate-section__reveal-input","aria-label":(0,t.__)("Generated Application Password","acrossai-mcp-manager")}),(0,n.jsx)("button",{ref:v,type:"button",className:"qs-btn qs-btn--secondary",children:_?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{className:"qs-generate-section__reveal-warning",children:(0,t.__)("Shown once. The config below now includes this password — copy that to grab both at once.","acrossai-mcp-manager")})]}),u&&(0,n.jsx)("div",{style:{marginTop:12},children:(0,n.jsx)(l,{status:"error",children:u})})]})]}),x?.meta?.config_file&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 2","acrossai-mcp-manager")}),(0,t.__)("Open the config file","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("input",{type:"text",readOnly:!0,value:x.meta.config_file,className:"qs-meta-input qs-meta-input--full","aria-label":(0,t.__)("Config File path","acrossai-mcp-manager")})})]}),x?.meta?.top_level_key&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 3","acrossai-mcp-manager")}),(0,t.__)("Locate the top-level key","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("input",{type:"text",readOnly:!0,value:`"${x.meta.top_level_key}"`,className:"qs-meta-input qs-meta-input--full","aria-label":(0,t.__)("Top-Level Key","acrossai-mcp-manager")})})]}),(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 4","acrossai-mcp-manager")}),(0,t.__)("Copy this config and paste it under the top-level key","acrossai-mcp-manager")]}),(0,n.jsxs)("div",{className:"qs-step-body",children:[window.acrossaiMcpQuickConnect?.tlsBypass?.enabled&&(0,n.jsx)("div",{style:{marginBottom:12},children:(0,n.jsxs)(l,{status:"warning",children:[window.acrossaiMcpQuickConnect.tlsBypass.message," ",(0,n.jsx)("a",{href:window.acrossaiMcpQuickConnect.tlsBypass.docUrl,target:"_blank",rel:"noopener noreferrer",children:window.acrossaiMcpQuickConnect.tlsBypass.linkText})]})}),(0,n.jsx)(le,{variant:"pane",title:w,children:f})]})]}),x?.restartStep&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 5","acrossai-mcp-manager")}),(0,t.__)("Restart the MCP client","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("p",{style:{margin:0},children:x.restartStep})})]}),(0,n.jsx)("div",{style:{marginTop:20},children:(0,n.jsx)(l,{status:"info",children:(0,t.__)("The generated password belongs to your current WordPress user. Access Control still applies to every MCP request, so a user who is not allowed for this server will receive an access denied response even if they have a saved config.","acrossai-mcp-manager")})})]})},pe=()=>{const{state:e}=z(),a=window.acrossaiMcpQuickConnect||{},r=e.methods.npm||[],i=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]);return i?0===r.length?(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No npm methods registered.","acrossai-mcp-manager")}):(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("span",{style:{display:"block",fontSize:11,fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase",color:"#757575",marginBottom:8},children:(0,t.__)("Command","acrossai-mcp-manager")}),r.map((e,s)=>{const r=e.command||`npx -y @acrossai/mcp-manager --siteurl=${a.siteUrl} --server=${i.slug}`;return(0,n.jsx)(le,{variant:"inline",children:r},e.slug||s)}),(0,n.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:12,marginTop:20,marginBottom:20},children:[(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16},children:[(0,n.jsx)("strong",{style:{flex:"0 0 120px"},children:(0,t.__)("Site URL","acrossai-mcp-manager")}),(0,n.jsx)("code",{style:{background:"#f0f0f0",padding:"3px 8px",borderRadius:2,fontSize:12},children:a.siteUrl})]}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16},children:[(0,n.jsx)("strong",{style:{flex:"0 0 120px"},children:(0,t.__)("Server","acrossai-mcp-manager")}),(0,n.jsx)("code",{style:{background:"#f0f0f0",padding:"3px 8px",borderRadius:2,fontSize:12},children:i.slug})]})]}),(0,n.jsx)("p",{style:{fontSize:12,color:"#757575",lineHeight:1.5},children:(0,t.__)("The CLI prompts for an Application Password on first run and stores it in your OS keychain.","acrossai-mcp-manager")})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},me=()=>{const{state:e}=z(),a=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]);return a?(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("h3",{style:{margin:"0 0 6px",fontSize:16},children:(0,t.__)("STDIO Transport (Local / Subprocess Mode)","acrossai-mcp-manager")}),(0,n.jsx)("p",{style:{fontSize:13,color:"#757575",lineHeight:1.55,marginBottom:20},children:(0,t.__)("MCP clients can also connect by launching WP-CLI as a subprocess instead of calling the HTTP endpoint. Ideal for local WordPress installs — no credentials transmitted over the network.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{marginBottom:16},children:[(0,n.jsx)("strong",{children:(0,t.__)("List all registered MCP servers","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:"wp mcp-adapter list"})]}),(0,n.jsxs)("div",{style:{marginBottom:16},children:[(0,n.jsx)("strong",{children:(0,t.__)("Start the MCP server as a subprocess","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:`wp mcp-adapter serve --server=${a.slug} --user=admin`})]}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("Choose STDIO for local dev + CI. Choose HTTP (via the MCP Client or Connectors path) when the client is a hosted app that can't launch subprocesses on your machine.","acrossai-mcp-manager")})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},ue={connectors:"One-click OAuth (Connectors)",client:"MCP Client (npx bridge)",npm:"npm CLI",wpcli:"WP-CLI (STDIO)"},ge=()=>{const{state:e,complete:a,refetch:r}=z(),i=v(),l=window.acrossaiMcpQuickConnect||{};(0,s.useEffect)(()=>{a()},[]);const c=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),o=[{label:(0,t.__)("Server","acrossai-mcp-manager"),value:c?c.name:"—"},{label:(0,t.__)("Access","acrossai-mcp-manager"),value:e.wizardState.access_saved?(0,t.__)("Rule configured","acrossai-mcp-manager"):(0,t.__)("Administrators only (default)","acrossai-mcp-manager")},{label:(0,t.__)("Abilities","acrossai-mcp-manager"),value:null!==e.abilities.enabledForServer&&e.abilities.enabledForServer>0?/* translators: 1: enabled ability count, 2: total available */ /* translators: 1: enabled ability count, 2: total available */
     2(0,t.__)("Step %1$d of %2$d, %3$s","acrossai-mcp-manager").replace("%1$d",String(a)).replace("%2$d",String(r)).replace("%3$s",s);b.current.textContent="";const i=setTimeout(()=>{b.current&&(b.current.textContent=n)},100);return()=>clearTimeout(i)},[e,a,r]);const x=Math.min(100,Math.max(0,Math.round(a/r*100))),y="1"===e||"done"===e,f="done"===e,w=["10","11","12","13"].includes(e)?(0,t.__)("Finish","acrossai-mcp-manager"):(0,t.__)("Continue","acrossai-mcp-manager"),j=o?[].concat(o).filter(Boolean):[],C=j.find(e=>e.isLoading),S=i||!!C;return(0,n.jsxs)(n.Fragment,{children:[S&&h.iconUrl&&(0,n.jsxs)("div",{className:"qs__initial-loading qs__initial-loading--overlay",role:"alert","aria-live":"assertive","aria-busy":"true",children:[(0,n.jsx)("img",{className:"qs__initial-loading-icon",src:h.iconUrl,alt:"","aria-hidden":"true"}),(0,n.jsx)("span",{className:"qs__sr-only",children:C?.label?C.label:(0,t.__)("Saving…","acrossai-mcp-manager")})]}),(0,n.jsx)("div",{className:"qs__progress",role:"progressbar","aria-valuenow":a,"aria-valuemin":1,"aria-valuemax":r,"aria-label":(0,t.__)("Wizard progress","acrossai-mcp-manager"),children:(0,n.jsx)("span",{className:"qs__progress-fill",style:{width:`${x}%`}})}),(0,n.jsxs)("header",{className:"qs__header",children:[h.logoUrl&&(0,n.jsx)("img",{className:"qs__header-logo",src:h.logoUrl,alt:"AcrossAI"}),(0,n.jsx)("span",{className:"qs__header-title",children:(0,t.__)("Connect","acrossai-mcp-manager")}),(0,n.jsx)("a",{className:"qs__header-consult",href:"https://acrossai.co/consultations/",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("Free Consultations ↗","acrossai-mcp-manager")}),!f&&(0,n.jsx)("a",{className:"qs__header-exit",href:"#",onClick:e=>{e.preventDefault(),g?.()},children:(0,t.__)("Exit setup","acrossai-mcp-manager")})]}),(0,n.jsxs)("div",{className:"qs__content",ref:v,children:[_,!f&&(()=>{const e=y||S,s=!l||S||j.some(e=>e.disabled);return(0,n.jsxs)("footer",{className:"qs__footer",children:[(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--secondary",disabled:e,"aria-disabled":e,onClick:e?void 0:m,children:(0,t.__)("Back","acrossai-mcp-manager")}),!d&&(0,n.jsx)("button",{type:"button",className:j.length?"qs-btn qs-btn--secondary":"qs-btn","aria-disabled":s,onClick:s?void 0:u,children:w}),j.map(e=>{const s=!!(a=e).disabled||!!a.isLoading;var a;const r="secondary"===e.variant?"qs-btn qs-btn--secondary":"qs-btn";return e.href?(0,n.jsx)("a",{className:r,href:e.href,target:e.target||"_self",rel:"_blank"===e.target?"noopener noreferrer":void 0,"aria-disabled":s,onClick:e.onClick,children:e.label},e.label):(0,n.jsx)("button",{type:"button",className:r,"aria-disabled":s,onClick:s?void 0:e.onClick,children:e.label},e.label)})]})})(),!f&&p]}),(0,n.jsx)("div",{className:"qs__sr-only",ref:b,"aria-live":"polite","aria-atomic":"true"})]})},d=window.wp.url,p=["1","2","3","4","5","6","7","10","11","12","13","done"],m=(e,s)=>!!("2"===e&&s.skipCreate||"4"===e&&s.skipAbilitiesGate||"5"===e&&s.skipAbilities||"6"===e&&s.skipEnable||"10"===e&&s.skipConnectorsDetail||"11"===e&&s.skipClient||"12"===e&&s.skipNpm||"13"===e&&s.skipWpcli),u=()=>{const e=window.location.search||"",s=(0,d.getQueryArg)(e,"step"),a=(0,d.getQueryArg)(e,"method"),r=(0,d.getQueryArg)(e,"mode"),t=(0,d.getQueryArg)(e,"server"),n=t?parseInt(t,10):NaN;return{step:void 0===s||""===s?"1":String(s),method:void 0===a||""===a?null:String(a),mode:void 0===r||""===r?null:String(r),server:Number.isFinite(n)&&n>0?n:null}},g=(e,s,a,r)=>{let t=window.location.pathname+window.location.search;return t=(0,d.addQueryArgs)(t,{step:e}),t=s?(0,d.addQueryArgs)(t,{method:s}):(0,d.removeQueryArgs)(t,"method"),t=a?(0,d.addQueryArgs)(t,{mode:a}):(0,d.removeQueryArgs)(t,"mode"),t=r?(0,d.addQueryArgs)(t,{server:r}):(0,d.removeQueryArgs)(t,"server"),t},_="acrossai-mcp-qs-nav",h=()=>{"undefined"!=typeof window&&"function"==typeof CustomEvent&&window.dispatchEvent(new CustomEvent(_))},v=()=>{const[e,a]=(0,s.useState)(u);(0,s.useEffect)(()=>{const e=()=>a(u());return window.addEventListener("popstate",e),window.addEventListener(_,e),()=>{window.removeEventListener("popstate",e),window.removeEventListener(_,e)}},[]);const r=(0,s.useCallback)((e,s=null,r=null)=>{if(!p.includes(e))return;const t=u(),n=g(e,s,r,t.server);window.history.pushState({},"",n),a({step:e,method:s,mode:r,server:t.server}),h()},[]),t=(0,s.useCallback)(e=>{const s=u(),r={...s,mode:e||null},t=g(s.step,s.method,r.mode,s.server);window.history.pushState({},"",t),a(r),h()},[]),n=(0,s.useCallback)(e=>{const s=Number.isFinite(e)&&e>0?e:null,r=u();if(r.server===s)return;const t=g(r.step,r.method,r.mode,s);window.history.replaceState({},"",t),a({...r,server:s}),h()},[]),i=(0,s.useCallback)(({skips:s={}}={})=>{const a=p.indexOf(e.step);if(-1===a||a>=p.length-1)return;let t=a+1;for(;t<p.length-1&&m(p[t],s);)t+=1;r(p[t],null)},[e.step,r]),l=(0,s.useCallback)(({skips:s={}}={})=>{const a=p.indexOf(e.step);if(a<=0)return;let t=a-1;for(;t>0&&m(p[t],s);)t-=1;r(p[t],null)},[e.step,r]),c=(0,s.useCallback)(()=>{const e=(window.acrossaiMcpQuickConnect||{}).adminUrl||"/wp-admin/admin.php?page=acrossai_mcp_manager";window.location.href=e},[]);return(0,s.useMemo)(()=>({step:e.step,method:e.method,mode:e.mode,server:e.server,goTo:r,setMode:t,setServer:n,advance:i,back:l,exit:c}),[e.step,e.method,e.mode,e.server,r,t,n,i,l,c])},b={status:"idle",error:null,servers:[],abilities:{total:0,enabledForServer:null,hasManagerPlugin:!1},plugins:{abilitiesManager:"missing"},methods:{npm:[],clients:[],ai_connectors:[]},wizardState:{current_step:1,server_id:null,access_saved:!1,abilities_saved:!1,enabled:!1,method:null,created_at:null}},x="HYDRATE_START",y="HYDRATE_SUCCESS",f="HYDRATE_ERROR",w="SAVE_STEP_START",j="SAVE_STEP_SUCCESS",C="SAVE_STEP_ERROR",S="COMPLETE_START",k="COMPLETE_SUCCESS",N="CLEAR_ERROR",q=(e,s)=>{switch(s.type){case x:return{...e,status:"loading",error:null};case y:{const a=s.payload||{};return{...e,status:"ready",error:null,servers:Array.isArray(a.servers)?a.servers:[],abilities:a.abilities||e.abilities,plugins:a.plugins||e.plugins,methods:a.methods||e.methods,wizardState:{...e.wizardState,...a.wizardState||{}}}}case f:return{...e,status:"error",error:s.payload};case w:return{...e,status:"saving",error:null,wizardState:{...e.wizardState,...s.optimistic||{}}};case j:{const a=s.payload||{};return{...e,status:"ready",error:null,servers:Array.isArray(a.servers)?a.servers:e.servers,abilities:a.abilities||e.abilities,wizardState:{...e.wizardState,...a.wizardState||{}}}}case C:return{...e,status:"error",error:s.payload.error,wizardState:s.payload.rollbackState||e.wizardState};case S:return{...e,status:"saving",error:null};case k:case N:return{...e,status:"ready",error:null};default:return e}},A=e=>{if(e&&"object"==typeof e){const s=e.data?.status||e.status;if(403===s)return{code:"session_expired",message:(0,t.__)("Your session has expired. Please reload the page to continue.","acrossai-mcp-manager")};if(401===s)return{code:"not_authorized",message:(0,t.__)("You are no longer signed in. Please reload the page.","acrossai-mcp-manager")};if(e.message)return{code:e.code||"error",message:String(e.message)}}return{code:"network_error",message:(0,t.__)("Something went wrong. Please try again.","acrossai-mcp-manager")}},M=(0,s.createContext)(null),E=({children:e})=>{const[a,t]=(0,s.useReducer)(q,b),i=(0,s.useRef)("");if(!i.current){const e=window.acrossaiMcpQuickConnect||{};i.current=e.restUrl||"/wp-json/acrossai-mcp-manager/v1/quick-connect"}const l=(0,s.useCallback)(async()=>{t({type:x});try{const e=new URLSearchParams(window.location.search).get("server"),s=e?`${i.current}/state?server_id=${encodeURIComponent(e)}`:`${i.current}/state`,a=await r()({url:s,method:"GET"});return t({type:y,payload:a}),a}catch(e){return t({type:f,payload:A(e)}),null}},[]),c=(0,s.useCallback)(async(e,s={})=>{const n=a.wizardState,l={current_step:e,...s};t({type:w,optimistic:l});try{const a=await r()({url:`${i.current}/step`,method:"POST",data:{step:e,data:s}});return t({type:j,payload:a}),a}catch(e){return t({type:C,payload:{error:A(e),rollbackState:n}}),null}},[a.wizardState]),o=(0,s.useCallback)(async()=>{t({type:S});try{return await r()({url:`${i.current}/complete`,method:"POST"}),t({type:k}),!0}catch(e){return t({type:f,payload:A(e)}),!1}},[]),d=(0,s.useCallback)(()=>t({type:N}),[]);(0,s.useEffect)(()=>{const e=()=>{"ready"===a.status&&l()},s=()=>{"visible"===document.visibilityState&&e()};return window.addEventListener("focus",e),document.addEventListener("visibilitychange",s),window.addEventListener("popstate",e),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",s),window.removeEventListener("popstate",e)}},[l,a.status]);const p={state:a,isLoading:"loading"===a.status||"saving"===a.status,error:a.error,refetch:l,saveStep:c,complete:o,clearError:d};return(0,n.jsx)(M.Provider,{value:p,children:e})},z=()=>{const e=(0,s.useContext)(M);if(!e)throw new Error("useWizardState must be used within <WizardStateProvider>");return e},P=(0,s.createContext)({setCanAdvance:()=>{},setBeforeAdvance:()=>{},setFooterAction:()=>{},setHideContinue:()=>{},setBelowFooter:()=>{},advance:()=>{}}),T=e=>{const{setFooterAction:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(e||null),()=>a(null)),[e,a])},R=(e,a=null)=>{const{setCanAdvance:r,setBeforeAdvance:t}=(0,s.useContext)(P);(0,s.useEffect)(()=>(r(!!e),t(()=>a),()=>{r(!0),t(()=>null)}),[e,a,r,t])},$=({selected:e=!1,onSelect:s,title:a,subtitle:r,badge:t=null,children:i=null,name:l="qs-card",value:c=""})=>(0,n.jsxs)("label",{className:"qs-card"+(e?" qs-card--selected":""),role:"radio","aria-checked":e,tabIndex:0,onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),s?.())},children:[(0,n.jsx)("input",{type:"radio",name:l,value:c,checked:e,onChange:()=>s?.(),style:{position:"absolute",opacity:0,pointerEvents:"none"},tabIndex:-1}),(0,n.jsx)("span",{className:"qs-card__radio","aria-hidden":"true"}),(0,n.jsxs)("div",{className:"qs-card__body",children:[(0,n.jsxs)("div",{className:"qs-card__title",children:[a,t]}),r&&(0,n.jsx)("div",{className:"qs-card__subtitle",children:r}),i]})]}),I=["acrossai-mcp-server","mcp-adapter-default-server"],L=I[0],B=()=>{const{state:e,saveStep:a}=z(),r=e.wizardState.server_id,i=!!e.wizardState.create_intent;(0,s.useEffect)(()=>{"ready"!==e.status||0!==e.servers.length||i||a(1,{create_intent:!0})},[e.status,e.servers.length,i,a]),(0,s.useEffect)(()=>{if("ready"!==e.status||null!==r||i||0===e.servers.length)return;const s=I.reduce((s,a)=>s||e.servers.find(e=>e.slug===a),null)||e.servers[0];s&&a(1,{server_id:s.id})},[e.status,e.servers,r,i,a]),R(null!==r||i);const l=(0,s.useMemo)(()=>{const s=e.servers||[];return[...s.filter(e=>e.slug===L),...s.filter(e=>e.slug!==L)]},[e.servers]);return(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Which server should AI connect to?","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Pick an existing MCP server, or create a new one for this setup.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{role:"radiogroup","aria-label":(0,t.__)("MCP servers","acrossai-mcp-manager"),children:[l.map(e=>(0,n.jsx)($,{name:"qs-server-pick",value:String(e.id),selected:!i&&r===e.id,onSelect:()=>(async e=>{await a(1,{server_id:e})})(e.id),title:e.name,subtitle:(0,n.jsx)("code",{children:e.route_full}),badge:(0,n.jsxs)(n.Fragment,{children:[e.slug===L?(0,n.jsx)("span",{className:"qs-card__badge qs-card__badge--recommended",children:(0,t.__)("Recommended","acrossai-mcp-manager")}):null,e.enabled?null:(0,n.jsx)("span",{className:"qs-card__badge qs-card__badge--inactive",children:(0,t.__)("Inactive","acrossai-mcp-manager")})]})},e.id)),(0,n.jsx)($,{name:"qs-server-pick",value:"__create__",selected:i,onSelect:async()=>{await a(1,{create_intent:!0})},title:(0,t.__)("+ Create a new server","acrossai-mcp-manager"),subtitle:(0,t.__)("Set up a brand-new MCP server for this wizard.","acrossai-mcp-manager")})]})]})},U=e=>String(e).toLowerCase().replace(/[^a-z0-9\-_]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-"),W=()=>{const{saveStep:e}=z(),[a,r]=(0,s.useState)({server_name:"",server_slug:"",description:"",server_route_namespace:"mcp",server_route:"",server_version:"v1.0.0"}),[i,l]=(0,s.useState)(!1),[c,o]=(0,s.useState)(!1),[d,p]=(0,s.useState)(null),m=(0,s.useCallback)(async()=>{if(p(null),!a.server_name.trim())return p((0,t.__)("Server name is required.","acrossai-mcp-manager")),!1;const s=await e(2,{new_server:a});return!!(s&&s.wizardState&&s.wizardState.server_id)},[a,e]);return R(a.server_name.trim().length>0,m),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Create a new MCP server","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Fill in a name — the rest is auto-filled. Click Continue when you're done.","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Name","acrossai-mcp-manager")}),(0,n.jsx)("span",{style:{color:"#cc1818",marginLeft:4},children:"*"}),(0,n.jsx)("input",{type:"text",value:a.server_name,onChange:e=>{return s=e.target.value,void r(e=>({...e,server_name:s,server_slug:i?e.server_slug:U(s),server_route:c?e.server_route:U(s)}));var s},required:!0,style:{display:"block",width:"100%",padding:"8px",marginTop:4}})]})}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Slug","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_slug,onChange:e=>{return s=e.target.value,l(!0),void r(e=>({...e,server_slug:s,server_route:c?e.server_route:U(s)}));var s},style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]})}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Description","acrossai-mcp-manager")}),(0,n.jsx)("textarea",{value:a.description,onChange:e=>r(s=>({...s,description:e.target.value})),rows:3,style:{display:"block",width:"100%",padding:"8px",marginTop:4}})]})}),(0,n.jsxs)("div",{style:{display:"flex",gap:12,marginBottom:16},children:[(0,n.jsxs)("label",{style:{flex:1},children:[(0,n.jsx)("strong",{children:(0,t.__)("Route namespace","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_route_namespace,onChange:e=>r(s=>({...s,server_route_namespace:e.target.value})),style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]}),(0,n.jsxs)("label",{style:{flex:1},children:[(0,n.jsx)("strong",{children:(0,t.__)("Route","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_route,onChange:e=>{o(!0),r(s=>({...s,server_route:e.target.value}))},style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]}),(0,n.jsxs)("label",{style:{flex:"0 0 120px"},children:[(0,n.jsx)("strong",{children:(0,t.__)("Version","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_version,onChange:e=>r(s=>({...s,server_version:e.target.value})),style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]})]}),d&&(0,n.jsx)("div",{style:{color:"#cc1818",marginBottom:16},role:"alert",children:d})]})},O=[{value:"",label:"No user access added by admin"},{value:"everyone",label:"Public (no login required)"},{value:"authenticated",label:"Any logged-in user"}];function F({providers:e,value:s,onChange:a}){const r=e.filter(e=>!1!==e.available);return(0,n.jsxs)("select",{className:"wpb-ac__select",value:s,onChange:e=>a(e.target.value),children:[O.map(e=>(0,n.jsx)("option",{value:e.value,children:e.label},e.value)),r.map(e=>(0,n.jsx)("option",{value:e.id,children:e.label},e.id))]})}const Q={wp_role:"Select which WordPress Role values may access this resource. Leave all unchecked to deny everyone (except administrators).",wp_capability:"Select which WordPress capabilities grant access. Users holding any of the checked capabilities are allowed. Administrators always have access.",bb_profile_type:"Select which BuddyBoss profile types grant access. Users assigned to any of the checked profile types are allowed. Administrators always have access.",mepr_membership:"Select which MemberPress memberships grant access. Users with an active subscription to any of the checked memberships are allowed. Administrators always have access."};function D({providerId:e,options:s,selectedOptions:a,onToggle:r}){const t=Q[e]||null;return(0,n.jsxs)("div",{className:"wpb-ac__options-panel",children:[t&&(0,n.jsx)("p",{className:"wpb-ac__panel-description",children:t}),(0,n.jsx)("ul",{className:"wpb-ac__checkbox-list",children:s.map(e=>(0,n.jsx)("li",{className:"wpb-ac__checkbox-item",children:(0,n.jsxs)("label",{children:[(0,n.jsx)("input",{type:"checkbox",value:e.id,checked:a.includes(e.id),onChange:()=>r(e.id)}),e.label]})},e.id))})]})}function H({pluginSlug:e,restApiRoot:a,selectedUsers:t,onAdd:i,onRemove:l}){const[c,o]=(0,s.useState)(""),[d,p]=(0,s.useState)([]),[m,u]=(0,s.useState)(!1),g=(0,s.useRef)(null),_=(0,s.useRef)(null);(0,s.useEffect)(()=>{const e=e=>{_.current&&!_.current.contains(e.target)&&u(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);const h=(0,s.useCallback)(s=>{if(!s.trim())return p([]),void u(!1);r()({url:`${a}/wpb-ac/v1/${e}/users?search=${encodeURIComponent(s)}`}).then(e=>{p(e||[]),u(!0)}).catch(()=>p([]))},[e,a]),v=(0,s.useCallback)(e=>{const s=e.target.value;o(s),clearTimeout(g.current),g.current=setTimeout(()=>h(s),300)},[h]),b=(0,s.useCallback)(e=>{i({id:e.id,login:e.login,display_name:e.display_name}),o(""),p([]),u(!1)},[i]),x=d.filter(e=>!t.find(s=>s.id===e.id));return(0,n.jsxs)("div",{className:"wpb-ac__user-panel",ref:_,children:[(0,n.jsx)("p",{className:"wpb-ac__panel-description",children:"Search by username or email and select one or more users. Administrators always have access regardless of this list."}),(0,n.jsxs)("div",{className:"wpb-ac__search-wrapper",children:[(0,n.jsx)("input",{type:"text",className:"wpb-ac__search-input",placeholder:"Search by username or email...",value:c,onChange:v,onFocus:()=>x.length&&u(!0)}),m&&x.length>0&&(0,n.jsx)("ul",{className:"wpb-ac__search-dropdown",children:x.map(e=>(0,n.jsxs)("li",{className:"wpb-ac__search-option",onMouseDown:()=>b(e),children:[e.display_name," (",e.login,")"]},e.id))})]}),t.length>0&&(0,n.jsx)("div",{className:"wpb-ac__user-tags",children:t.map(e=>(0,n.jsxs)("span",{className:"wpb-ac__user-tag",children:[e.display_name," (",e.login,")",(0,n.jsx)("button",{type:"button",className:"wpb-ac__tag-remove",onClick:()=>l(e.id),"aria-label":`Remove ${e.display_name}`,children:"×"})]},e.id))})]})}function Y({pluginSlug:e,namespace:a,resourceKey:t,restApiRoot:i,nonce:l,title:c="Access Control",description:o="Control which users are allowed to connect to this MCP server. Administrators always have access regardless of this setting.",saveLabel:d="Save Access Control",onSave:p,hideSaveButton:m=!1,hideHeader:u=!1,onChange:g}){const[_,h]=(0,s.useState)(!0),[v,b]=(0,s.useState)(!1),[x,y]=(0,s.useState)(null),[f,w]=(0,s.useState)([]),[j,C]=(0,s.useState)(""),[S,k]=(0,s.useState)([]),[N,q]=(0,s.useState)([]),A=a.split("/").map(encodeURIComponent).join("%2F"),M=(0,s.useCallback)(e=>{const s=e.map(e=>`include[]=${e}`).join("&");r()({url:`${i}/wp/v2/users?${s}&per_page=100`}).then(e=>{q(e.map(e=>({id:String(e.id),login:e.slug,display_name:e.name})))}).catch(()=>{q(e.map(e=>({id:e,login:e,display_name:e})))})},[i]);(0,s.useEffect)(()=>{if(!t)return void h(!1);h(!0),y(null),w([]),C(""),k([]),q([]);let s=!1;return Promise.all([r()({url:`${i}/wpb-ac/v1/${e}/providers`}),r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`})]).then(([e,a])=>{if(s)return;w(e);const r=a.key||"",t=a.value||[];C(r),k(t),"wp_user"===r&&t.length>0&&M(t)}).catch(()=>{}).finally(()=>{s||h(!1)}),()=>{s=!0}},[e,i,A,t]);const E=(0,s.useCallback)(e=>{C(e),k([]),q([]),y(null)},[]),z=(0,s.useCallback)(e=>{k(s=>s.includes(e)?s.filter(s=>s!==e):[...s,e])},[]),P=(0,s.useCallback)(e=>{q(s=>s.find(s=>s.id===e.id)?s:[...s,e]),k(s=>s.includes(e.id)?s:[...s,e.id])},[]),T=(0,s.useCallback)(e=>{q(s=>s.filter(s=>s.id!==e)),k(s=>s.filter(s=>s!==e))},[]),R=(0,s.useCallback)(async()=>{b(!0),y(null);try{""===j?await r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`,method:"DELETE"}):await r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`,method:"PUT",data:{ac_key:j,ac_options:S}}),y({type:"success",message:"Access control saved."}),p?.(j,S)}catch(e){y({type:"error",message:e?.message||"Failed to save."})}finally{b(!1)}},[j,S,e,A,t,i,p]);(0,s.useEffect)(()=>{_||g?.(j,S)},[j,S,_]);const $=f.find(e=>e.id===j)||null,I=$&&"wp_user"!==$.id&&$.options?.length>0,L="wp_user"===j;return _?(0,n.jsx)("div",{className:"wpb-ac wpb-ac--loading",children:"Loading…"}):(0,n.jsxs)("div",{className:"wpb-ac",children:[!u&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("h2",{className:"wpb-ac__title",children:c}),(0,n.jsx)("p",{className:"wpb-ac__description",children:o})]}),(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:"Who can access"}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(F,{providers:f,value:j,onChange:E})})]}),I&&(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:$.label}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(D,{providerId:j,options:$.options,selectedOptions:S,onToggle:z})})]}),L&&(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:$?.label||"Users"}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(H,{pluginSlug:e,restApiRoot:i,selectedUsers:N,onAdd:P,onRemove:T})})]}),x&&(0,n.jsx)("p",{className:`wpb-ac__notice wpb-ac__notice--${x.type}`,children:x.message}),!m&&(0,n.jsx)("div",{className:"wpb-ac__footer",children:(0,n.jsx)("button",{type:"button",className:"wpb-ac__save-btn",onClick:R,disabled:v,children:v?"Saving…":d})})]})}const G=({pluginSlug:e,namespace:a="acrossai-mcp-manager",resourceKey:r,restApiRoot:t="/wp-json",nonce:n="",title:i,description:l,saveLabel:c,hideSaveButton:o=!1,onChange:d,onSave:p})=>e&&r?(0,s.createElement)(Y,{pluginSlug:e,namespace:a,resourceKey:r,restApiRoot:t,nonce:n,title:i||void 0,description:l||void 0,saveLabel:c||void 0,hideSaveButton:o,onChange:d,onSave:p}):null,V=()=>{const{state:e}=z(),a=(()=>{const{advance:e}=(0,s.useContext)(P);return e})(),i=window.acrossaiMcpQuickConnect||{},[c,o]=(0,s.useState)(null),[d,p]=(0,s.useState)(!1),m=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),u=(0,s.useRef)({key:null,options:[]}),g=(0,s.useCallback)((e,s)=>{u.current={key:e,options:Array.isArray(s)?s:[]}},[]),_=(0,s.useCallback)(async()=>{if(o(null),!m||null===u.current.key||""===u.current.key)return void a();const e=i.acPluginSlug||"mcp",s=i.acNamespace||"acrossai-mcp-manager",n=`${i.restApiRoot||"/wp-json"}/wpb-ac/v1/${e}/rules/${encodeURIComponent(s)}/${m.slug}`;p(!0);try{await r()({url:n,method:"PUT",data:{ac_key:u.current.key,ac_options:u.current.options}}),a()}catch(e){o(e&&e.message||(0,t.__)("Failed to save access control. Try again.","acrossai-mcp-manager"))}finally{p(!1)}},[m,i.acPluginSlug,i.acNamespace,i.restApiRoot,a]),h=(0,s.useMemo)(()=>m?{label:(0,t.__)("Save and Continue","acrossai-mcp-manager"),onClick:_,isLoading:d,disabled:d}:null,[m,_,d]);return T(h),m?(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Who can reach this server?","acrossai-mcp-manager")}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("Only administrators can reach this server until you add an access rule below.","acrossai-mcp-manager")}),c&&(0,n.jsx)(l,{status:"error",children:c}),(0,n.jsx)(G,{pluginSlug:i.acPluginSlug||"mcp",namespace:i.acNamespace||"acrossai-mcp-manager",resourceKey:m.slug,restApiRoot:i.restApiRoot||"/wp-json",nonce:i.restNonce||"",hideSaveButton:!0,onChange:g}),(0,n.jsx)("p",{className:"qs__step-subtitle",style:{marginTop:24},children:(0,t.__)("Continue skips saving (leaves current rule as-is). Save and Continue writes your changes and moves on. You can change this anytime under the server's Access Control tab.","acrossai-mcp-manager")})]}):(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Who can reach it?","acrossai-mcp-manager")}),(0,n.jsx)("p",{children:(0,t.__)("No server selected — go back to Step 1.","acrossai-mcp-manager")})]})},K=["Blocks","Cache","Comments","Content Search","Core","Cron","Database","File Manager","Media","Plugins","Rank Math","Settings","Site Health","Themes","Users","Widgets"],J=()=>{const{state:e,refetch:a}=z(),[i,c]=(0,s.useState)(!1),[o,d]=(0,s.useState)(null),p="missing"===e.plugins.abilitiesManager,m=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id)||null,[e.servers,e.wizardState.server_id]),u=null!==m&&!1===m.type_available;R(!u);const g=(0,s.useCallback)(async()=>{c(!0),d(null);try{const e=(window.acrossaiMcpQuickConnect||{}).restUrl||"/wp-json/acrossai-mcp-manager/v1/quick-connect";await r()({url:`${e}/install-plugin`,method:"POST",data:{slug:"acrossai-abilities-manager"}}),await a()}catch(e){d(e&&e.message||(0,t.__)("Something went wrong. Try again or install the plugin manually.","acrossai-mcp-manager"))}finally{c(!1)}},[a]),_=i?p?(0,t.__)("Installing…","acrossai-mcp-manager"):(0,t.__)("Activating…","acrossai-mcp-manager"):p?(0,t.__)("Install & Continue","acrossai-mcp-manager"):(0,t.__)("Activate & Continue","acrossai-mcp-manager"),h=(0,s.useMemo)(()=>({label:_,onClick:g,isLoading:i,disabled:i}),[_,g,i]);T(h);const v=(0,n.jsxs)("span",{className:"qs__brand-mark qs__brand-mark--inline",children:[(0,n.jsx)("span",{className:"qs__brand-mark__across",children:"Across"}),(0,n.jsx)("span",{className:"qs__brand-mark__ai",children:"AI"})]}),b=(0,s.createInterpolateElement)(p?(0,t.__)("Install <brand/> Abilities Manager","acrossai-mcp-manager"):(0,t.__)("Activate <brand/> Abilities Manager","acrossai-mcp-manager"),{brand:v});return(0,n.jsxs)("div",{children:[o&&(0,n.jsx)("div",{style:{marginBottom:20},children:(0,n.jsx)(l,{status:"error",children:o})}),u&&(0,n.jsx)("div",{style:{marginBottom:20},children:(0,n.jsx)(l,{status:"warning",children:(0,t.__)("This server's type requires the AcrossAI Abilities Manager, so it cannot be enabled later in this setup without it. Install it below, or go back and choose a different server type.","acrossai-mcp-manager")})}),(0,n.jsxs)("div",{className:"qs__gate-card",children:[(window.acrossaiMcpQuickConnect||{}).logoUrl&&(0,n.jsx)("img",{className:"qs__gate-card__logo",src:window.acrossaiMcpQuickConnect.logoUrl,alt:"","aria-hidden":"true"}),(0,n.jsx)("h2",{className:"qs__step-title",children:b}),(0,n.jsxs)("div",{className:"qs__gate-categories",children:[(0,n.jsx)("p",{className:"qs__gate-categories-label",children:(0,t.__)("Includes 350+ abilities for:","acrossai-mcp-manager")}),(0,n.jsx)("ul",{className:"qs__gate-bullets qs__gate-bullets--grid",children:K.map(e=>(0,n.jsx)("li",{children:e},e))})]}),(0,n.jsx)("div",{className:"qs__gate-actions",children:(0,n.jsx)("a",{className:"qs-btn qs-btn--secondary",href:"https://wordpress.org/plugins/acrossai-abilities-manager/",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("View on WordPress.org ↗","acrossai-mcp-manager")})})]}),(0,n.jsx)("div",{style:{marginTop:24},children:(0,n.jsx)(l,{status:"info",children:(0,t.__)("You can Continue without installing — the wizard will fall back to the 3 abilities WordPress ships with. Or install the plugin now to unlock the full 350+ set. You can broaden per-ability access in the next step.","acrossai-mcp-manager")})})]})},X=["core/get-environment-info","core/get-site-info","core/get-user-info"],Z=()=>{const{state:e,saveStep:a,isLoading:r}=z(),[i,c]=(0,s.useState)(!1),o=window.acrossaiMcpQuickConnect||{},d=e.plugins.abilitiesManager,p="active"===d,m="inactive"===d,u=e.plugins.abilitiesManagerActivateUrl||"",g=e.wizardState.server_id,_=e.abilities.total,h=e.abilities.enabledForServer,v=_>0&&null!==h&&h>=_,b=(0,s.useCallback)(async()=>{c(!0);try{await a(5,{enable_all_abilities:!0})}finally{c(!1)}},[a]),x=(0,s.useMemo)(()=>p&&!v?{label:(0,t.__)("Enable all and continue","acrossai-mcp-manager"),onClick:b,isLoading:i||r,disabled:i||r}:null,[p,v,b,i,r]);return T(x),p?(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("What should AI be able to do?","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-end",gap:16,justifyContent:"center",margin:"20px 0"},children:[(0,n.jsx)("span",{style:{fontSize:60,fontWeight:700,lineHeight:.9},children:null!==h?`${h} / ${_}`:_}),(0,n.jsxs)("div",{style:{paddingBottom:8},children:[(0,n.jsx)("div",{style:{fontSize:15,fontWeight:600},children:null!==h?(0,t.__)("enabled for this server","acrossai-mcp-manager"):(0,t.__)("abilities available","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{fontSize:13,color:"#757575"},children:(0,t.__)("From AcrossAI Abilities Manager.","acrossai-mcp-manager")})]})]}),v&&(0,n.jsx)(l,{status:"success",children:(0,t.__)("All abilities enabled for this server ✓","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{display:"flex",justifyContent:"center",marginBottom:20},children:(0,n.jsx)("a",{className:"qs-btn qs-btn--secondary",href:o.adminUrl&&g?`${o.adminUrl}&action=edit&server=${g}&tab=abilities`:"#",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("Configure abilities one-by-one ↗","acrossai-mcp-manager")})}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("By default, all abilities registered by Abilities Manager can be accessed by users with the manage_options capability (admins only). You can broaden this per-ability in the Access Control step.","acrossai-mcp-manager")})]}):(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("What should AI be able to do?","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-end",gap:16,justifyContent:"center",margin:"20px 0"},children:[(0,n.jsx)("span",{style:{fontSize:60,fontWeight:700,lineHeight:.9},children:null!==h?`${h} / ${_}`:_}),(0,n.jsxs)("div",{style:{paddingBottom:8},children:[(0,n.jsx)("div",{style:{fontSize:15,fontWeight:600},children:null!==h?(0,t.__)("enabled for this server","acrossai-mcp-manager"):(0,t.__)("abilities available","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{fontSize:13,color:"#757575"},children:(0,t.__)("WordPress ships with only 3 by default.","acrossai-mcp-manager")})]})]}),(0,n.jsx)("ul",{style:{listStyle:"none",padding:0,marginBottom:24,border:"1px solid #ddd",borderRadius:2},children:X.map(e=>(0,n.jsxs)("li",{style:{padding:"11px 14px",borderBottom:"1px solid #f0f0f0",fontFamily:"monospace",fontSize:12},children:["• ",e]},e))}),(0,n.jsxs)("div",{style:{border:"1px solid #c4b5fd",background:"#faf9ff",padding:20,borderRadius:2,marginBottom:20},children:[(0,n.jsx)("h3",{style:{margin:"0 0 12px",fontSize:15,fontWeight:600,color:"#312e81"},children:m?(0,t.__)("Activate AcrossAI Abilities Manager to unlock 350+ abilities","acrossai-mcp-manager"):(0,t.__)("Unlock 350+ abilities with AcrossAI Abilities Manager","acrossai-mcp-manager")}),(0,n.jsx)("p",{style:{fontSize:13,lineHeight:1.65,color:"#4c1d95",margin:"0 0 16px"},children:m?(0,t.__)("The plugin is already installed on this site. Activate it now to add 350+ new abilities your AI client can use.","acrossai-mcp-manager"):(0,t.__)("Create pages, update content, install plugins, update WordPress core, manage your entire site — all from your AI client.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",gap:14,alignItems:"center"},children:[m&&u?(0,n.jsx)("a",{className:"qs-btn",href:u,style:{background:"#4f46e5",borderColor:"#4f46e5"},children:(0,t.__)("Activate Abilities Manager","acrossai-mcp-manager")}):(0,n.jsx)("a",{className:"qs-btn",href:"https://wordpress.org/plugins/acrossai-abilities-manager/",target:"_blank",rel:"noopener noreferrer",style:{background:"#4f46e5",borderColor:"#4f46e5"},children:(0,t.__)("Install from WordPress.org","acrossai-mcp-manager")}),(0,n.jsx)("a",{href:"https://acrossai.co/use-cases/",target:"_blank",rel:"noopener noreferrer",style:{color:"#4f46e5",textDecoration:"none"},children:(0,t.__)("View case studies →","acrossai-mcp-manager")})]})]}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("By default, all abilities registered by Abilities Manager can be accessed by users with the manage_options capability (admins only). You can broaden this per-ability in the Access Control step.","acrossai-mcp-manager")})]})},ee=()=>{const{saveStep:e}=z(),[a,r]=(0,s.useState)(!1),i=(0,s.useCallback)(async()=>{r(!0);try{await e(6,{enabled:!0})}finally{r(!1)}},[e]),c=(0,s.useMemo)(()=>({label:(0,t.__)("Enable & Continue","acrossai-mcp-manager"),onClick:i,isLoading:a,disabled:a}),[i,a]);return T(c),((e=!0)=>{const{setHideContinue:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(!!e),()=>a(!1)),[e,a])})(!0),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Turn on your MCP endpoint","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("One more step. Your server needs to be enabled before it will accept any MCP requests.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{className:"qs__gate-card qs__gate-card--warning",children:[(0,n.jsxs)("div",{className:"qs__gate-stat",children:[(0,n.jsx)("span",{className:"qs__gate-stat-icon","aria-hidden":"true",children:"⏻"}),(0,n.jsx)("span",{className:"qs__gate-stat-label qs__gate-stat-label--warning",children:(0,t.__)("Server is currently disabled","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{className:"qs__gate-copy",children:(0,t.__)("While disabled, this server rejects every MCP request — even from administrators. Enable it to start accepting connections from your AI clients.","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__gate-copy qs__gate-copy--muted",children:(0,t.__)("You can disable this server at any time from the server list.","acrossai-mcp-manager")})]}),(0,n.jsx)("div",{style:{marginTop:24},children:(0,n.jsx)(l,{status:"info",children:(0,s.createInterpolateElement)((0,t.__)("AcrossAI MCP Manager runs on top of the <a>MCP Adapter</a> framework and adds an admin safety layer: every server starts disabled so a half-configured server can never accidentally accept requests. Enable this one once you've reviewed its access rules and abilities.","acrossai-mcp-manager"),{a:(0,n.jsx)("a",{href:"https://github.com/wordpress/mcp-adapter",target:"_blank",rel:"noopener noreferrer"})})})})]})},se=(e=20)=>({width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,focusable:!1}),ae=({size:e})=>(0,n.jsxs)("svg",{...se(e),children:[(0,n.jsx)("polyline",{points:"4 17 10 11 4 5"}),(0,n.jsx)("line",{x1:"12",y1:"19",x2:"20",y2:"19"})]}),re=({size:e})=>(0,n.jsx)("svg",{...se(e),children:(0,n.jsx)("polyline",{points:"20 6 9 17 4 12"})}),te=[{key:"connectors",title:(0,t.__)("One-click OAuth (Connectors)","acrossai-mcp-manager"),description:(0,t.__)("Paste one URL into Claude, ChatGPT, Grok, or Gemini and approve. No config files.","acrossai-mcp-manager"),icon:({size:e})=>(0,n.jsxs)("svg",{...se(e),children:[(0,n.jsx)("path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"}),(0,n.jsx)("path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"})]})},{key:"client",title:(0,t.__)("MCP Client","acrossai-mcp-manager"),description:(0,t.__)("Paste a JSON config into Claude Desktop, VS Code, Cursor, and more.","acrossai-mcp-manager"),icon:({size:e})=>(0,n.jsx)("svg",{...se(e),children:(0,n.jsx)("path",{d:"M19.439 7.85c-.049.322.059.648.289.878l1.568 1.568c.47.47.706 1.087.706 1.704s-.235 1.233-.706 1.704l-1.611 1.611a.98.98 0 0 1-.837.276c-.47-.07-.802-.48-.968-.925a2.501 2.501 0 1 0-3.214 3.214c.446.166.855.497.925.968a.979.979 0 0 1-.276.837l-1.61 1.61a2.404 2.404 0 0 1-1.705.707 2.402 2.402 0 0 1-1.704-.706l-1.568-1.568a1.026 1.026 0 0 0-.877-.29c-.493.074-.84.504-1.02.968a2.5 2.5 0 1 1-3.237-3.237c.464-.18.894-.527.967-1.02a1.026 1.026 0 0 0-.289-.877l-1.568-1.568A2.402 2.402 0 0 1 1.998 12c0-.617.236-1.234.706-1.704L4.23 8.77c.24-.24.581-.353.917-.303.515.077.877.528 1.073 1.01a2.5 2.5 0 1 0 3.259-3.259c-.482-.196-.933-.558-1.01-1.073-.05-.336.062-.676.303-.917l1.525-1.525A2.402 2.402 0 0 1 12 1.998c.617 0 1.234.236 1.704.706l1.568 1.568c.23.23.556.338.877.29.493-.074.84-.504 1.02-.968a2.5 2.5 0 1 1 3.237 3.237c-.464.18-.894.527-.967 1.02Z"})})},{key:"npm",title:(0,t.__)("npm (one-line install)","acrossai-mcp-manager"),description:(0,t.__)("Run a single npx command — no config files, no JSON.","acrossai-mcp-manager"),icon:ae},{key:"wpcli",title:(0,t.__)("WP-CLI (local subprocess)","acrossai-mcp-manager"),description:(0,t.__)("Best for CI or local dev. No network credentials transmitted.","acrossai-mcp-manager"),icon:ae}],ne=()=>{const{state:e,saveStep:a}=z(),r=e.wizardState.method,[i,l]=(0,s.useState)(null);R(null!==r);const c=(0,s.useCallback)(async e=>{l(e);try{await a(7,{method:e})}finally{l(null)}},[a]);return(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("How do you want to connect?","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Pick a connection method. You can add more later from the server's edit page.","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, minmax(0, 1fr))",gap:12},role:"radiogroup","aria-label":(0,t.__)("Connection methods","acrossai-mcp-manager"),children:te.map(e=>{const s=e.icon,a="connectors"===e.key,l=i===e.key;return(0,n.jsx)($,{name:"qs-method",value:e.key,selected:r===e.key,onSelect:l?void 0:()=>c(e.key),title:(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s,{size:18})," ",e.title,a&&(0,n.jsx)("span",{className:"qs-card__badge",children:(0,t.__)("RECOMMENDED","acrossai-mcp-manager")})]}),subtitle:e.description},e.key)})})]})},ie=window.wp.compose,le=({variant:e="inline",children:a,title:r})=>{const[i,l]=(0,s.useState)(!1);(0,s.useEffect)(()=>{if(!i)return;const e=setTimeout(()=>l(!1),2e3);return()=>clearTimeout(e)},[i]);const c=(0,ie.useCopyToClipboard)("string"==typeof a?a:"",()=>l(!0));return"pane"===e?(0,n.jsxs)("div",{className:"qs-code qs-code--pane",children:[(0,n.jsxs)("div",{className:"qs-code__title-bar",children:[(0,n.jsx)("span",{children:r||(0,t.__)("code","acrossai-mcp-manager")}),(0,n.jsx)("button",{ref:c,type:"button",className:"qs-code__copy-btn","aria-label":(0,t.__)("Copy code to clipboard","acrossai-mcp-manager"),children:i?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy config","acrossai-mcp-manager")})]}),(0,n.jsx)("pre",{children:a})]}):(0,n.jsxs)("div",{className:"qs-code qs-code--inline",children:[(0,n.jsx)("code",{children:a}),(0,n.jsx)("button",{ref:c,type:"button",className:"qs-code__copy-btn","aria-label":(0,t.__)("Copy command to clipboard","acrossai-mcp-manager"),children:i?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy","acrossai-mcp-manager")})]})},ce=()=>{const{state:e}=z(),s=e.setupRequired;return s&&s.message?(0,n.jsxs)(l,{status:"warning",children:[(0,n.jsx)("p",{children:(0,n.jsx)("strong",{children:(0,t.__)("Connection details are not ready yet.","acrossai-mcp-manager")})}),(0,n.jsx)("p",{children:s.message}),(0,n.jsx)("p",{children:(0,t.__)("Install and activate it, then return to this step — the server is already enabled, so nothing else needs changing.","acrossai-mcp-manager")})]}):null},oe=()=>{const{state:e}=z(),a=window.acrossaiMcpQuickConnect||{},r=e.methods.ai_connectors||[],[i,c]=(0,s.useState)(r[0]?r[0].slug:""),o=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),d=r.find(e=>e.slug===i),p=o?`${a.siteUrl||""}/wp-json/${o.route_full}`:"",m=e.methods.ai_connector_instructions||{},u=d&&m[d.slug]||"",g=u?u.replaceAll("__ACROSSAI_MCP_URL__",String(p).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")):"";return(e=>{const{setBelowFooter:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(e||null),()=>a(null)),[e,a])})((0,s.useMemo)(()=>o&&0!==r.length&&g?(0,n.jsx)("div",{className:"acrossai-mcp-connector-panel__setup-embed",dangerouslySetInnerHTML:{__html:g}}):null,[o,r.length,g])),o?0===r.length?(0,n.jsx)(l,{status:"info",children:(0,t.__)("No AI connectors are available on this site.","acrossai-mcp-manager")}):(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("div",{role:"tablist","aria-label":(0,t.__)("Connector providers","acrossai-mcp-manager"),style:{display:"flex",gap:8,marginBottom:16,flexWrap:"wrap"},children:r.map(e=>{const s=e.slug===i;return(0,n.jsx)("button",{type:"button",role:"tab","aria-selected":s,onClick:()=>c(e.slug),className:s?"qs-btn":"qs-btn qs-btn--secondary",children:e.name||e.slug},e.slug)})}),d&&(0,n.jsxs)("div",{children:[(0,n.jsx)("h3",{style:{margin:"0 0 12px",fontSize:16},children:d.name||d.slug}),(0,n.jsx)("p",{style:{fontSize:13,color:"#757575",marginBottom:8},children:(0,t.__)("MCP URL to paste into your AI client:","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:p}),!g&&(0,n.jsx)(l,{status:"info",children:(0,t.__)("This connector supports Dynamic Client Registration only — paste the MCP URL above into your AI client and it will register itself. No manual credentials to generate.","acrossai-mcp-manager")})]})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},de=()=>{const{state:e}=z(),a=e.methods.clients||[],[i,c]=(0,s.useState)(a[0]?a[0].slug:""),[o,d]=(0,s.useState)(!1),[p,m]=(0,s.useState)(""),[u,g]=(0,s.useState)(null),[_,h]=(0,s.useState)(!1);(0,s.useEffect)(()=>{m(""),g(null),h(!1)},[i]),(0,s.useEffect)(()=>{if(!_)return;const e=setTimeout(()=>h(!1),2e3);return()=>clearTimeout(e)},[_]);const v=(0,ie.useCopyToClipboard)(p,()=>h(!0)),b=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),x=(0,s.useMemo)(()=>a.find(e=>e.slug===i),[a,i]),y=(0,s.useCallback)(async()=>{if(b&&x){d(!0),g(null),m("");try{const e=await r()({path:"/acrossai-mcp-manager/v1/generate-app-password",method:"POST",data:{server_id:b.id,name:`Quick Edit - ${x.name||x.slug}`}});e&&e.password?m(String(e.password)):g((0,t.__)("Password generation succeeded but the response was malformed.","acrossai-mcp-manager"))}catch(e){g(e&&e.message||(0,t.__)("Could not generate the Application Password.","acrossai-mcp-manager"))}finally{d(!1)}}},[b,x]);if(!b)return(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")});if(0===a.length)return(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No MCP clients registered on this site.","acrossai-mcp-manager")});const f=(0,s.useMemo)(()=>{let e=x&&x.config?"string"==typeof x.config?x.config:JSON.stringify(x.config,null,2):JSON.stringify(x||{},null,2);return p&&(e=e.split("(paste generated password here)").join(p)),e},[x,p]),w=x?`json · ${x.name||x.slug}`:"json";return(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("div",{style:{marginBottom:12},children:(0,n.jsx)("span",{style:{fontSize:11,fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase",color:"#757575"},children:(0,t.__)("Choose your client","acrossai-mcp-manager")})}),(0,n.jsx)("div",{role:"tablist","aria-label":(0,t.__)("MCP clients","acrossai-mcp-manager"),style:{display:"flex",gap:7,flexWrap:"wrap",marginBottom:16},children:a.map(e=>{const s=e.slug===i;return(0,n.jsx)("button",{type:"button",role:"tab","aria-selected":s,onClick:()=>c(e.slug),className:s?"qs-btn":"qs-btn qs-btn--secondary",children:e.name||e.slug},e.slug)})}),(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 1","acrossai-mcp-manager")}),(0,t.__)("Generate the password","acrossai-mcp-manager")]}),(0,n.jsxs)("div",{className:"qs-step-body qs-generate-section",children:[(0,n.jsx)("button",{type:"button",className:"qs-btn qs-generate-section__btn",onClick:y,disabled:o,children:o?(0,t.__)("Generating…","acrossai-mcp-manager"):(0,t.__)("Generate New Application Password","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs-generate-section__desc",children:(0,t.__)("Creates a one-time password via WordPress Application Passwords. Shown only once — store it safely.","acrossai-mcp-manager")}),p&&(0,n.jsxs)("div",{className:"qs-generate-section__reveal",children:[(0,n.jsxs)("div",{className:"qs-generate-section__reveal-row",children:[(0,n.jsx)("input",{type:"text",readOnly:!0,value:p,className:"qs-generate-section__reveal-input","aria-label":(0,t.__)("Generated Application Password","acrossai-mcp-manager")}),(0,n.jsx)("button",{ref:v,type:"button",className:"qs-btn qs-btn--secondary",children:_?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{className:"qs-generate-section__reveal-warning",children:(0,t.__)("Shown once. The config below now includes this password — copy that to grab both at once.","acrossai-mcp-manager")})]}),u&&(0,n.jsx)("div",{style:{marginTop:12},children:(0,n.jsx)(l,{status:"error",children:u})})]})]}),x?.meta?.config_file&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 2","acrossai-mcp-manager")}),(0,t.__)("Open the config file","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("input",{type:"text",readOnly:!0,value:x.meta.config_file,className:"qs-meta-input qs-meta-input--full","aria-label":(0,t.__)("Config File path","acrossai-mcp-manager")})})]}),x?.meta?.top_level_key&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 3","acrossai-mcp-manager")}),(0,t.__)("Locate the top-level key","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("input",{type:"text",readOnly:!0,value:`"${x.meta.top_level_key}"`,className:"qs-meta-input qs-meta-input--full","aria-label":(0,t.__)("Top-Level Key","acrossai-mcp-manager")})})]}),(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 4","acrossai-mcp-manager")}),(0,t.__)("Copy this config and paste it under the top-level key","acrossai-mcp-manager")]}),(0,n.jsxs)("div",{className:"qs-step-body",children:[window.acrossaiMcpQuickConnect?.tlsBypass?.enabled&&(0,n.jsx)("div",{style:{marginBottom:12},children:(0,n.jsxs)(l,{status:"warning",children:[window.acrossaiMcpQuickConnect.tlsBypass.message," ",(0,n.jsx)("a",{href:window.acrossaiMcpQuickConnect.tlsBypass.docUrl,target:"_blank",rel:"noopener noreferrer",children:window.acrossaiMcpQuickConnect.tlsBypass.linkText})]})}),(0,n.jsx)(le,{variant:"pane",title:w,children:f})]})]}),x?.restartStep&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 5","acrossai-mcp-manager")}),(0,t.__)("Restart the MCP client","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("p",{style:{margin:0},children:x.restartStep})})]}),(0,n.jsx)("div",{style:{marginTop:20},children:(0,n.jsx)(l,{status:"info",children:(0,t.__)("The generated password belongs to your current WordPress user. Access Control still applies to every MCP request, so a user who is not allowed for this server will receive an access denied response even if they have a saved config.","acrossai-mcp-manager")})})]})},pe=()=>{const{state:e}=z(),a=window.acrossaiMcpQuickConnect||{},r=e.methods.npm||[],i=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]);return i?0===r.length?(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No npm methods registered.","acrossai-mcp-manager")}):(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("span",{style:{display:"block",fontSize:11,fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase",color:"#757575",marginBottom:8},children:(0,t.__)("Command","acrossai-mcp-manager")}),r.map((e,s)=>{const r=e.command||`npx -y @acrossai/mcp-manager --siteurl=${a.siteUrl} --server=${i.slug}`;return(0,n.jsx)(le,{variant:"inline",children:r},e.slug||s)}),(0,n.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:12,marginTop:20,marginBottom:20},children:[(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16},children:[(0,n.jsx)("strong",{style:{flex:"0 0 120px"},children:(0,t.__)("Site URL","acrossai-mcp-manager")}),(0,n.jsx)("code",{style:{background:"#f0f0f0",padding:"3px 8px",borderRadius:2,fontSize:12},children:a.siteUrl})]}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16},children:[(0,n.jsx)("strong",{style:{flex:"0 0 120px"},children:(0,t.__)("Server","acrossai-mcp-manager")}),(0,n.jsx)("code",{style:{background:"#f0f0f0",padding:"3px 8px",borderRadius:2,fontSize:12},children:i.slug})]})]}),(0,n.jsx)("p",{style:{fontSize:12,color:"#757575",lineHeight:1.5},children:(0,t.__)("The CLI prompts for an Application Password on first run and stores it in your OS keychain.","acrossai-mcp-manager")})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},me=()=>{const{state:e}=z(),a=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]);return a?(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("h3",{style:{margin:"0 0 6px",fontSize:16},children:(0,t.__)("STDIO Transport (Local / Subprocess Mode)","acrossai-mcp-manager")}),(0,n.jsx)("p",{style:{fontSize:13,color:"#757575",lineHeight:1.55,marginBottom:20},children:(0,t.__)("MCP clients can also connect by launching WP-CLI as a subprocess instead of calling the HTTP endpoint. Ideal for local WordPress installs — no credentials transmitted over the network.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{marginBottom:16},children:[(0,n.jsx)("strong",{children:(0,t.__)("List all registered MCP servers","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:"wp mcp-adapter list"})]}),(0,n.jsxs)("div",{style:{marginBottom:16},children:[(0,n.jsx)("strong",{children:(0,t.__)("Start the MCP server as a subprocess","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:`wp mcp-adapter serve --server=${a.slug} --user=admin`})]}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("Choose STDIO for local dev + CI. Choose HTTP (via the MCP Client or Connectors path) when the client is a hosted app that can't launch subprocesses on your machine.","acrossai-mcp-manager")})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},ue={connectors:"One-click OAuth (Connectors)",client:"MCP Client (npx bridge)",npm:"npm CLI",wpcli:"WP-CLI (STDIO)"},ge=()=>{const{state:e,complete:a,refetch:r}=z(),i=v(),l=window.acrossaiMcpQuickConnect||{};(0,s.useEffect)(()=>{a()},[]);const c=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),o=[{label:(0,t.__)("Server","acrossai-mcp-manager"),value:c?c.name:"—"},{label:(0,t.__)("Access","acrossai-mcp-manager"),value:e.wizardState.access_saved?(0,t.__)("Rule configured","acrossai-mcp-manager"):(0,t.__)("Administrators only (default)","acrossai-mcp-manager")},{label:(0,t.__)("Abilities","acrossai-mcp-manager"),value:null!==e.abilities.enabledForServer&&e.abilities.enabledForServer>0?/* translators: 1: enabled ability count, 2: total available */ /* translators: 1: enabled ability count, 2: total available */
    33(0,t.__)("%1$d of %2$d enabled","acrossai-mcp-manager").replace("%1$d",String(e.abilities.enabledForServer)).replace("%2$d",String(e.abilities.total)):(0,t.__)("None enabled","acrossai-mcp-manager")},{label:(0,t.__)("Connected via","acrossai-mcp-manager"),value:ue[e.wizardState.method]||"—"}];return(0,n.jsxs)("div",{style:{textAlign:"center",padding:"20px 0"},children:[(0,n.jsx)("div",{style:{width:60,height:60,borderRadius:"50%",background:"#edfaef",border:"2px solid #4ab866",display:"inline-flex",alignItems:"center",justifyContent:"center",marginBottom:20,color:"#4ab866"},"aria-hidden":"true",children:(0,n.jsx)(re,{size:32})}),(0,n.jsx)("h2",{className:"qs__step-title",style:{textAlign:"center"},children:(0,t.__)("You're all set!","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{border:"1px solid #ddd",borderRadius:2,margin:"24px auto",maxWidth:480,textAlign:"left"},children:o.map(e=>(0,n.jsxs)("div",{style:{display:"grid",gridTemplateColumns:"20px 140px 1fr",gap:12,alignItems:"center",padding:"12px 16px",borderBottom:"1px solid #f0f0f0"},children:[(0,n.jsx)("span",{style:{color:"#4ab866",fontSize:13,fontWeight:700},"aria-hidden":"true",children:"✓"}),(0,n.jsx)("span",{style:{fontSize:12.5,color:"#757575"},children:e.label}),(0,n.jsx)("span",{style:{fontSize:13,fontWeight:600},children:e.value})]},e.label))}),(0,n.jsxs)("div",{style:{display:"flex",justifyContent:"center",gap:12,flexWrap:"wrap"},children:[(0,n.jsx)("button",{type:"button",className:"qs-btn",onClick:()=>{l.adminUrl&&c&&(window.location.href=`${l.adminUrl}&action=edit&server=${c.id}`)},disabled:!c,children:(0,t.__)("Go to server dashboard","acrossai-mcp-manager")}),(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--secondary",onClick:async()=>{await r(),i.goTo("1")},children:(0,t.__)("Set up another server","acrossai-mcp-manager")}),(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--link",onClick:i.exit,children:(0,t.__)("Dismiss","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{style:{fontSize:12,color:"#757575",marginTop:24},children:(0,t.__)("You can re-run this wizard anytime from the top admin bar.","acrossai-mcp-manager")})]})},_e={1:()=>(0,n.jsx)(B,{}),2:()=>(0,n.jsx)(W,{}),3:()=>(0,n.jsx)(V,{}),4:()=>(0,n.jsx)(J,{}),5:()=>(0,n.jsx)(Z,{}),6:()=>(0,n.jsx)(ee,{}),7:()=>(0,n.jsx)(ne,{}),10:()=>(0,n.jsx)(oe,{}),11:()=>(0,n.jsx)(de,{}),12:()=>(0,n.jsx)(pe,{}),13:()=>(0,n.jsx)(me,{}),done:()=>(0,n.jsx)(ge,{})},he=()=>{const e=v(),{state:a,isLoading:r,error:i,refetch:c,clearError:d}=z(),[p,m]=(0,s.useState)(!0),[u,g]=(0,s.useState)(null),[_,h]=(0,s.useState)(null),[b,x]=(0,s.useState)(!1),[y,f]=(0,s.useState)(null);(0,s.useEffect)(()=>{"idle"===a.status&&c()},[]),(0,s.useEffect)(()=>{"ready"===a.status&&e.setServer(a.wizardState.server_id)},[a.status,a.wizardState.server_id,e]);const w=(0,s.useMemo)(()=>a.servers.find(e=>e.id===a.wizardState.server_id)||null,[a.servers,a.wizardState.server_id]),j=a.wizardState.method,C=(0,s.useMemo)(()=>({skipCreate:null!==a.wizardState.server_id&&!a.wizardState.create_intent,skipAbilitiesGate:"active"===a.plugins.abilitiesManager,skipAbilities:a.abilities.total>0&&null!==a.abilities.enabledForServer&&a.abilities.enabledForServer>=a.abilities.total,skipEnable:!(!w||!w.enabled),skipConnectorsDetail:"connectors"!==j,skipClient:"client"!==j,skipNpm:"npm"!==j,skipWpcli:"wpcli"!==j}),[a.wizardState.server_id,a.wizardState.create_intent,a.plugins.abilitiesManager,a.abilities.total,a.abilities.enabledForServer,w,j]);(0,s.useEffect)(()=>{"ready"===a.status&&("2"===e.step&&C.skipCreate||"4"===e.step&&C.skipAbilitiesGate||"5"===e.step&&C.skipAbilities||"6"===e.step&&C.skipEnable||"10"===e.step&&C.skipConnectorsDetail||"11"===e.step&&C.skipClient||"12"===e.step&&C.skipNpm||"13"===e.step&&C.skipWpcli)&&e.advance({skips:C})},[e.step,a.status,C,e]),(0,s.useEffect)(()=>{if("ready"!==a.status)return;if(!_e[e.step])return void e.goTo("1");if("1"===e.step||"done"===e.step)return;const s=(r=a.wizardState).server_id||r.create_intent?null:"1";var r;s&&s!==e.step&&e.goTo(s)},[e.step,a.status,a.wizardState,e]);const S=(0,s.useMemo)(()=>[{id:1,skip:!1},{id:2,skip:C.skipCreate},{id:3,skip:!1},{id:4,skip:C.skipAbilitiesGate},{id:5,skip:C.skipAbilities},{id:6,skip:C.skipEnable},{id:7,skip:!1},{id:10,skip:C.skipConnectorsDetail},{id:11,skip:C.skipClient},{id:12,skip:C.skipNpm},{id:13,skip:C.skipWpcli}],[C]),k=(0,s.useMemo)(()=>S.filter(e=>!e.skip).length,[S]),N=(0,s.useMemo)(()=>{if("done"===e.step)return k;const s=String(e.step);let a=0;for(const e of S)if(!e.skip&&(a+=1,String(e.id)===s))return a;return a},[e.step,k,S]),q=(0,s.useCallback)(()=>{e.advance({skips:C})},[e,C]),A=(0,s.useMemo)(()=>({setCanAdvance:m,setBeforeAdvance:g,setFooterAction:h,setHideContinue:x,setBelowFooter:f,advance:q}),[m,g,h,x,f,q]),M=["10","11","12","13"].includes(e.step),E=(0,s.useCallback)(async()=>{u&&!await u()||(M?e.goTo("done"):e.advance({skips:C}))},[e,C,u,M]),T=(0,s.useRef)(!1);if("ready"===a.status&&(T.current=!0),"idle"===a.status||"loading"===a.status&&!T.current){const e=window.acrossaiMcpQuickConnect||{};return(0,n.jsxs)("div",{className:"qs__initial-loading",children:[e.iconUrl?(0,n.jsx)("img",{className:"qs__initial-loading-icon",src:e.iconUrl,alt:"","aria-hidden":"true"}):null,(0,n.jsx)("span",{className:"qs__sr-only",children:(0,t.__)("Loading setup wizard…","acrossai-mcp-manager")})]})}return(0,n.jsx)(P.Provider,{value:A,children:(0,n.jsxs)(o,{step:e.step,displayIndex:N,totalSteps:k,isLoading:r,canAdvance:p,footerAction:_,hideContinue:b,belowFooter:y,onBack:()=>e.back({skips:C}),onAdvance:E,onExit:e.exit,children:[i&&(0,n.jsxs)(l,{status:"error",children:[i.message," ",(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--link",onClick:d,children:(0,t.__)("Dismiss","acrossai-mcp-manager")})]}),(_e[e.step]||_e[1])()]})})},ve=window.acrossaiMcpQuickConnect||{};ve.restNonce&&r().use(r().createNonceMiddleware(ve.restNonce));const be=()=>{const e=document.getElementById("acrossai-mcp-quick-connect-root");e&&(0,s.createRoot)(e).render((0,n.jsx)(E,{children:(0,n.jsx)(he,{})}))};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",be):be()})();
  • acrossai-mcp-manager/tags/0.4.4/changelog.txt

    r3734601 r3766841  
    88https://github.com/acrossaico/acrossai-mcp-manager/releases
    99
     10
     11= 0.4.4 =
     12* **New: a log of what AI assistants actually did on your site.** Every request an assistant makes, and every ability that ran to fulfil it, recorded together — one "create a page" from an assistant may run several abilities, and the log keeps them linked, so you open one entry and read what happened instead of inferring it from the result. It records which assistant, how it authenticated, whether it worked, how long it took, what was asked and roughly how much of your content was read back. Find it under **MCP → Activity Log**, or on an individual server's own tab.
     13* **The log is on from the moment you update, and bounded without being configured.** Requests are kept 30 days, ability runs 7 — they are much noisier — and the whole log is capped at 50,000 entries. A daily job applies all three. Every number is adjustable and either half can be switched off on the MCP settings tab. Recording is on by default because a log nobody enabled is a log nobody has when they need it; it is bounded by default because a plugin that records without being asked should also tidy up without being asked.
     14* **It tells you when it is failing.** An empty log and a broken log look identical, which is how a logging fault stays invisible. The screen and Site Health now both report when writes are failing, when the table cannot be reached, and when the daily cleanup has not run — the last one usually meaning WordPress scheduled tasks are not running at all on the site, which affects far more than this log.
     15* **Private by design.** Values that look like credentials are redacted by key name before anything is stored, response bodies are never kept, and WordPress's own personal-data export and erase both reach the log. Erasure clears the person from the record and keeps the event, so a subject request cannot be used to delete audit history.
     16* **Changed: the connection wizard is now called "Connect".** It was "Quick Connect via AcrossAI" in the admin bar, the menu, the server list and the wizard's own header. Nothing moved and nothing behaves differently — the label just says less.
     17* **Fixed: a PHP notice on every page load.** A database table was passing an index setting in a form newer PHP versions warn about. It had never had any effect — the table was not using it — so removing it changes nothing except that the notice stops. Only visible to sites with debug logging switched on.
    1018
    1119= 0.4.3 =
  • acrossai-mcp-manager/tags/0.4.4/includes/Abilities/AbilityHelpers.php

    r3685479 r3766841  
    8080                                $server_id,
    8181                                $ability->get_name(),
    82                                 is_array( $meta ) ? $meta : array()
     82                                // get_meta() declares `: array` in core — no guard needed.
     83                                $meta
    8384                        );
    8485                }
  • acrossai-mcp-manager/tags/0.4.4/includes/Abilities/Discover.php

    r3702733 r3766841  
    189189                $meta = $ability->get_meta();
    190190
    191                 if ( ! is_array( $meta ) || ! isset( $meta['acrossai']['tab_group'] ) ) {
     191                // No is_array() guard: WP_Ability::get_meta() declares `: array` in core,
     192                // so the check is dead code and PHPStan level 8 flags it.
     193                if ( ! isset( $meta['acrossai']['tab_group'] ) ) {
    192194                        return '';
    193195                }
  • acrossai-mcp-manager/tags/0.4.4/includes/Abilities/Execute.php

    r3702733 r3766841  
    1212namespace AcrossAI_MCP_Manager\Includes\Abilities;
    1313
     14use AcrossAI_MCP_Manager\Includes\Observability\CaptureContext;
    1415use WP\MCP\Domain\Utils\AbilityArgumentNormalizer;
    1516use WP_Error;
    … …  
    132133                $parameters = AbilityArgumentNormalizer::normalize( $ability, $parameters );
    133134
     135                $started = microtime( true );
     136
    134137                try {
    135                         $result = $ability->execute( $parameters );
     138                        // F096: same wrapper as Base_Toolset_Ability — one try/finally,
     139                        // owned by CaptureContext, so the two choke points cannot drift.
     140                        $result  = CaptureContext::instance()->around(
     141                                $ability_name,
     142                                static fn() => $ability->execute( $parameters )
     143                        );
     144                        $elapsed = ( microtime( true ) - $started ) * 1000;
     145
    136146                        if ( is_wp_error( $result ) ) {
     147                                AbilityActivityRecorder::instance()->record_bracketed(
     148                                        $ability_name,
     149                                        'error',
     150                                        array(
     151                                                'input'         => $parameters,
     152                                                'error_code'    => (string) $result->get_error_code(),
     153                                                'error_message' => $result->get_error_message(),
     154                                        ),
     155                                        $elapsed
     156                                );
     157
    137158                                return array(
    138159                                        'success' => false,
    … …  
    140161                                );
    141162                        }
     163
     164                        AbilityActivityRecorder::instance()->record_bracketed(
     165                                $ability_name,
     166                                'success',
     167                                array(
     168                                        'input'  => $parameters,
     169                                        'output' => $result,
     170                                ),
     171                                $elapsed
     172                        );
     173
    142174                        return array(
    143175                                'success' => true,
    … …  
    145177                        );
    146178                } catch ( \Throwable $e ) {
     179                        AbilityActivityRecorder::instance()->record_bracketed(
     180                                $ability_name,
     181                                'error',
     182                                array(
     183                                        'input'         => $parameters,
     184                                        'error_code'    => 'ability_threw',
     185                                        'error_message' => $e->getMessage(),
     186                                ),
     187                                ( microtime( true ) - $started ) * 1000
     188                        );
     189
    147190                        return array(
    148191                                'success' => false,
  • acrossai-mcp-manager/tags/0.4.4/includes/Abilities/Toolset/AbilityGroup.php

    r3704846 r3766841  
    107107                $meta = $ability->get_meta_item( 'acrossai' );
    108108
    109                 if ( ! is_array( $meta ) || ! isset( $meta['tab_group'] ) ) {
     109                // No is_array() guard: get_meta() declares `: array` in core.
     110                if ( ! isset( $meta['tab_group'] ) ) {
    110111                        return '';
    111112                }
  • acrossai-mcp-manager/tags/0.4.4/includes/Abilities/Toolset/Base_Toolset_Ability.php

    r3704846 r3766841  
    3030namespace AcrossAI_MCP_Manager\Includes\Abilities\Toolset;
    3131
     32use AcrossAI_MCP_Manager\Includes\Abilities\AbilityActivityRecorder;
     33use AcrossAI_MCP_Manager\Includes\Observability\CaptureContext;
    3234use AcrossAI_MCP_Manager\Includes\Abilities\Toolset\AbilityGroup;
    3335use AcrossAI_MCP_Manager\Includes\Abilities\Toolset\InputNormalizer;
    … …  
    10891091                );
    10901092
     1093                $started = microtime( true );
     1094
    10911095                try {
    1092                         $result = $target->execute( $parameters );
     1096                        // F096: capture is armed for the duration of this call, so an
     1097                        // ability event can be attributed to the MCP request that caused it
     1098                        // — and so Feature 097 can attribute its change rows to the same
     1099                        // call. `around()` owns the try/finally; a second hand-written
     1100                        // bracket here is how the two paths would drift apart.
     1101                        $result = CaptureContext::instance()->around(
     1102                                $name,
     1103                                static fn() => $target->execute( $parameters )
     1104                        );
    10931105                } catch ( \Throwable $e ) {
     1106                        AbilityActivityRecorder::instance()->record_bracketed(
     1107                                $name,
     1108                                'error',
     1109                                array(
     1110                                        'input'         => $parameters,
     1111                                        'error_code'    => 'ability_threw',
     1112                                        'error_message' => $e->getMessage(),
     1113                                ),
     1114                                ( microtime( true ) - $started ) * 1000
     1115                        );
     1116
    10941117                        /*
    10951118                         * An ability that throws would otherwise reach the transport as an
    … …  
    11001123                }
    11011124
     1125                $elapsed = ( microtime( true ) - $started ) * 1000;
     1126
    11021127                if ( is_wp_error( $result ) ) {
     1128                        // The only path that sees this on WordPress 6.9: core's
     1129                        // `wp_after_execute_ability` early-returns before firing on a
     1130                        // WP_Error, so a log built on the hook pair alone records
     1131                        // successes and is blind to every failure.
     1132                        AbilityActivityRecorder::instance()->record_bracketed(
     1133                                $name,
     1134                                'error',
     1135                                array(
     1136                                        'input'         => $parameters,
     1137                                        'error_code'    => (string) $result->get_error_code(),
     1138                                        'error_message' => $result->get_error_message(),
     1139                                ),
     1140                                $elapsed
     1141                        );
     1142
    11031143                        return array(
    11041144                                'action'        => 'execute',
    … …  
    11091149                        );
    11101150                }
     1151
     1152                AbilityActivityRecorder::instance()->record_bracketed(
     1153                        $name,
     1154                        'success',
     1155                        array(
     1156                                'input'  => $parameters,
     1157                                'output' => $result,
     1158                        ),
     1159                        $elapsed
     1160                );
    11111161
    11121162                return array(
  • acrossai-mcp-manager/tags/0.4.4/includes/Activator.php

    r3733272 r3766841  
    99use AcrossAI_MCP_Manager\Includes\Database\OAuthDataMigration;
    1010use AcrossAI_MCP_Manager\Includes\Database\CliAuthLog\Table as CliAuthLogTable;
     11use AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Table as ActivityLogTable;
     12use AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup as ActivityLogCleanup;
    1113use AcrossAI_MCP_Manager\Includes\Database\MCPServerAbility\Table as MCPServerAbilityTable;
    1214use AcrossAI_MCP_Manager\Includes\Database\MCPServerTool\Table as MCPServerToolTable;
    … …  
    7880                MCPServerToolTable::instance()->maybe_upgrade();
    7981                CliAuthLogTable::instance()->maybe_upgrade();
     82                // F096 — the activity log. Empty-table state is the correct initial
     83                // state: both enable toggles ship off, so nothing writes until an
     84                // operator opts in.
     85                ActivityLogTable::instance()->maybe_upgrade();
    8086                // Feature 017 — per-server ability exposure overrides. No seeder call —
    8187                // the empty-table state IS the correct backwards-compatible initial state.
    … …  
    113119                                MCPServerTable::instance(),
    114120                                CliAuthLogTable::instance(),
     121                                ActivityLogTable::instance(),
    115122                                MCPServerAbilityTable::instance(),
    116123                                MCPServerToolTable::instance(),
    … …  
    134141                        wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'acrossai_mcp_manager_oauth_cleanup' );
    135142                }
     143
     144                // F096 — daily retention + ceiling sweep for the activity log. Scheduled
     145                // only while a bound is configured; `sync_schedule()` also unschedules
     146                // when both retention periods and the ceiling are 0, so an operator who
     147                // turns everything off does not keep a daily event that deletes nothing.
     148                ActivityLogCleanup::sync_schedule();
    136149
    137150                // Feature 015 — Access Control v2 adoption. Create the
  • acrossai-mcp-manager/tags/0.4.4/includes/Database/MCPServerMeta/Schema.php

    r3628087 r3766841  
    5757         * `server_id_meta_key` (key, not unique) — mirrors wp_postmeta's
    5858         * `post_id` index shape; accelerates per-server key lookups.
    59          * meta_key partial-length (191) to fit within MySQL's index-key-length
    60          * limit under utf8mb4.
     59         *
     60         * NO index-level `length` key, deliberately. One used to sit on `meta_key`
     61         * (`'length' => array( 'meta_key' => 191 )`) intending a 191-character
     62         * prefix for the old 767-byte index limit. It never did anything:
     63         * BerlinDB's `Kern\Index` declares no `$length` property, so `set_vars()`
     64         * assigned it as a DYNAMIC property — deprecated from PHP 8.2 — and then
     65         * ignored it. Verified on the live table: `SUB_PART` is NULL, i.e. the
     66         * index covers the FULL column, which is what it has always done.
     67         *
     68         * It is also unnecessary. `varchar(255)` at utf8mb4 is 1020 bytes, well
     69         * inside InnoDB's 3072-byte limit under the DYNAMIC row format that MySQL
     70         * 5.7+ and 8.0 default to. The 191 figure belongs to the 767-byte era.
     71         *
     72         * Removing it is therefore zero functional change and silences a
     73         * deprecation notice that fired on EVERY request — `MCPServerMeta\Table`
     74         * is constructed in `Main::bootstrap_database_tables()`, which runs on
     75         * every page load, admin and front end alike. If a prefix is ever genuinely
     76         * needed, it has to be expressed somewhere BerlinDB reads; this key is not
     77         * that place.
    6178         *
    6279         * @var array
    … …  
    7794                        'type'    => 'key',
    7895                        'columns' => array( 'meta_key' ),
    79                         'length'  => array( 'meta_key' => 191 ),
    8096                ),
    8197        );
  • acrossai-mcp-manager/tags/0.4.4/includes/Deactivator.php

    r3610897 r3766841  
    4444                // beyond the require + delegation.
    4545                wp_clear_scheduled_hook( 'acrossai_mcp_manager_oauth_cleanup' );
     46
     47                // F096 — the activity log's retention sweep. Cleared by name, matching
     48                // the OAuth hook above: the constant lives on the Cleanup class but the
     49                // contract is the string, and deactivation must not depend on that class
     50                // being loadable.
     51                wp_clear_scheduled_hook( 'acrossai_mcp_manager_activity_cleanup' );
    4652        }
    4753}
  • acrossai-mcp-manager/tags/0.4.4/includes/Loader.php

    r3733272 r3766841  
    8686         *
    8787         * @since    0.0.1
    88          * @param    string $hook             The name of the WordPress action that is being registered.
    89          * @param    object $component        A reference to the instance of the object on which the action is defined.
    90          * @param    string $callback         The name of the function definition on the $component.
    91          * @param    int    $priority         Optional. The priority at which the function should be fired. Default is 10.
    92          * @param    int    $accepted_args    Optional. The number of arguments that should be passed to the $callback. Default is 1.
     88         * @param    string              $hook             The name of the WordPress action that is being registered.
     89         * @param    object|class-string $component A reference to the instance of the object on which the action is
     90         *                                            defined, or its class-string when the callback is static.
     91         * @param    string              $callback         The name of the function definition on the $component.
     92         * @param    int                 $priority         Optional. The priority at which the function should be fired. Default is 10.
     93         * @param    int                 $accepted_args    Optional. The number of arguments that should be passed to the $callback. Default is 1.
    9394         */
    9495        public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
    … …  
    100101         *
    101102         * @since    0.0.1
    102          * @param    string $hook             The name of the WordPress filter that is being registered.
    103          * @param    object $component        A reference to the instance of the object on which the filter is defined.
    104          * @param    string $callback         The name of the function definition on the $component.
    105          * @param    int    $priority         Optional. The priority at which the function should be fired. Default is 10.
    106          * @param    int    $accepted_args    Optional. The number of arguments that should be passed to the $callback. Default is 1.
     103         * @param    string              $hook             The name of the WordPress filter that is being registered.
     104         * @param    object|class-string $component A reference to the instance of the object on which the filter is
     105         *                                            defined, or its class-string when the callback is static.
     106         * @param    string              $callback         The name of the function definition on the $component.
     107         * @param    int                 $priority         Optional. The priority at which the function should be fired. Default is 10.
     108         * @param    int                 $accepted_args    Optional. The number of arguments that should be passed to the $callback. Default is 1.
    107109         */
    108110        public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
    … …  
    116118         * @since    0.0.1
    117119         * @access   private
    118          * @param    array  $hooks            The collection of hooks that is being registered (that is, actions or filters).
    119          * @param    string $hook             The name of the WordPress filter that is being registered.
    120          * @param    object $component        A reference to the instance of the object on which the filter is defined.
    121          * @param    string $callback         The name of the function definition on the $component.
    122          * @param    int    $priority         The priority at which the function should be fired.
    123          * @param    int    $accepted_args    The number of arguments that should be passed to the $callback.
     120         * @param    array               $hooks            The collection of hooks that is being registered (that is, actions or filters).
     121         * @param    string              $hook             The name of the WordPress filter that is being registered.
     122         * @param    object|class-string $component A reference to the instance of the object on which the filter is
     123         *                                            defined, or its class-string when the callback is static.
     124         * @param    string              $callback         The name of the function definition on the $component.
     125         * @param    int                 $priority         The priority at which the function should be fired.
     126         * @param    int                 $accepted_args    The number of arguments that should be passed to the $callback.
    124127         * @return   array                                  The collection of actions and filters registered with WordPress.
    125128         */
  • acrossai-mcp-manager/tags/0.4.4/includes/MCP/Controller.php

    r3733272 r3766841  
    232232                                array( HttpTransport::class ),
    233233                                ErrorLogMcpErrorHandler::class,
    234                                 NullMcpObservabilityHandler::class,
     234                                // F096: our handler ONLY when request logging is on. Reading the
     235                                // toggle here rather than inside the handler is what makes a disabled
     236                                // log cost nothing at runtime — the adapter keeps the Null handler and
     237                                // the recording path is never reached (FR-029).
     238                                \AcrossAI_MCP_Manager\Includes\Observability\HandlerResolver::class_string(),
    235239                                $tools,
    236240                                $resources,
  • acrossai-mcp-manager/tags/0.4.4/includes/Main.php

    r3734601 r3766841  
    116116                $this->load_dependencies();
    117117
     118                $this->register_activity_log_table();
     119
    118120                $this->set_locale();
    119121
    120122                $this->load_hooks();
     123        }
     124
     125        /**
     126         * Teach `$wpdb` the activity log's table name, on EVERY request.
     127         *
     128         * BerlinDB does not resolve a table name from the Query's `$table_name`
     129         * directly. `Query::get_table_name()` calls `get_table_prefix()`, which
     130         * reads `$wpdb->{$prefixed_name} ?? ''` — and that property is only ever
     131         * set by the Table object's own constructor. Construct no Table, and the
     132         * name resolves to the EMPTY STRING: the insert becomes
     133         * `SHOW FULL COLUMNS FROM ``` and fails, `add_item()` returns false, and
     134         * the Recorder's A15 try/catch swallows it. Nothing is written and nothing
     135         * is reported.
     136         *
     137         * Reconciliation runs on `admin_init` (see reconcile_database_schemas()),
     138         * which is enough to CREATE and migrate the table but not to make it
     139         * writable anywhere else — `admin_init` does not fire on a front-end REST
     140         * request or on WP-Cron. Both of those are load-bearing here: every MCP
     141         * call is a REST request, and the retention sweep is a cron event. The log
     142         * recorded nothing from real traffic, while every test passed, because the
     143         * test bootstrap constructs the Table itself.
     144         *
     145         * Safe to do unconditionally and this early. Table construction performs no
     146         * queries — `init()` sanitizes the name and calls `set_db_interface()`,
     147         * which only assigns `$wpdb` properties. The schema work lives in
     148         * `maybe_upgrade()`, which is NOT called here.
     149         *
     150         * Deliberately not gated on the logging toggles. The table must be
     151         * addressable for reads, retention and purge regardless of whether
     152         * recording is currently on, and an unresolvable name fails silently in
     153         * every one of those paths too.
     154         */
     155        private function register_activity_log_table(): void {
     156                \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Table::instance();
    121157        }
    122158
    … …  
    148184                $this->define( 'ACROSSAI_MCP_MANAGER_PLUGIN_NAME_SLUG', 'acrossai-mcp-manager' );
    149185                $this->define( 'ACROSSAI_MCP_MANAGER_PLUGIN_NAME', 'AcrossAI MCP Manager' );
    150                 $this->define( 'ACROSSAI_MCP_MANAGER_VERSION', '0.4.3' );
     186                $this->define( 'ACROSSAI_MCP_MANAGER_VERSION', '0.4.4' );
    151187        }
    152188
    … …  
    279315                        \AcrossAI_MCP_Manager\Includes\Database\OAuthClients\Table::instance(),
    280316                        \AcrossAI_MCP_Manager\Includes\Database\ConnectorApprovedUsers\Table::instance(),
    281                 );
     317                        // F096 — the activity log. Listed here as well as in Activator
     318                        // because WordPress skips activation hooks on a plugin UPDATE
     319                        // (B68): a site that already had this plugin active when 096
     320                        // shipped would otherwise have the toggles but no table, and every
     321                        // write would fail silently.
     322                        \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Table::instance(),
     323                );
     324
     325                $pending = 0;
    282326
    283327                foreach ( $tables as $table ) {
    284328                        $table->maybe_upgrade();
     329
     330                        if ( $table->needs_upgrade() ) {
     331                                ++$pending;
     332                        }
     333                }
     334
     335                // FR-013b. A failure recorded here is usually transient: the version is
     336                // left unstamped precisely so the migration retries on the next admin
     337                // load. Once nothing is pending, the recorded failures describe a state
     338                // that no longer exists and must stop being reported, or Site Health
     339                // shows a permanent red mark for a problem that fixed itself.
     340                //
     341                // Cleared wholesale rather than per table because BerlinDB's `Table`
     342                // exposes no public name accessor, so a stored failure cannot be matched
     343                // to a Table object from out here. "Nothing needs upgrading" covers it.
     344                if ( 0 === $pending ) {
     345                        \AcrossAI_MCP_Manager\Includes\Database\Support\SchemaFailureHealthCheck::instance()->clear_all();
    285346                }
    286347
    … …  
    863924                $this->loader->add_action( 'shutdown', $current_server_holder, 'clear', 999 );
    864925
     926                // ─────────────────────────────────────────────────────────────────
     927                // F096 — the activity log's OAuth attribution holder.
     928                //
     929                // Same A17 three-stage lifecycle as CurrentServerHolder above, for the
     930                // same reason: stage 3 (`shutdown`) is what stops a fatal leaving a
     931                // resolved OAuth identity in memory for the NEXT request to be
     932                // attributed to. A17 calls omitting it the number-one silent bug in
     933                // ad-hoc versions of this pattern, and in an activity log the symptom
     934                // would be one client's calls credited to another.
     935                //
     936                // `capture_oauth_context` listens for the scoped action TokenValidator
     937                // fires after a successful bearer validation — hooks here per A1,
     938                // never inside the validator (Principle V).
     939                // ─────────────────────────────────────────────────────────────────
     940                $auth_context_holder = \AcrossAI_MCP_Manager\Includes\Observability\AuthContextHolder::instance();
     941                $this->loader->add_action(
     942                        \AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants::ACTION_OAUTH_TOKEN_VALIDATED,
     943                        $auth_context_holder,
     944                        'capture_oauth_context',
     945                        10,
     946                        2
     947                );
     948                $this->loader->add_filter( 'rest_pre_dispatch', $auth_context_holder, 'reset_for_request', 5, 3 );
     949                $this->loader->add_filter( 'rest_post_dispatch', $auth_context_holder, 'clear', 999, 1 );
     950                $this->loader->add_action( 'shutdown', $auth_context_holder, 'clear', 999 );
     951
     952                // F096 — the activity log's REST surface and privacy callbacks.
     953                //
     954                // The exporter and eraser ship in THIS release rather than with the
     955                // governance story, because this release is what starts recording source
     956                // addresses. Clarification Q1 kept the full address on the condition
     957                // that the subject-data path accompanied it; deferring the callbacks
     958                // would keep the cost and drop the mitigation (SEC-T02).
     959                $this->loader->add_action(
     960                        'rest_api_init',
     961                        \AcrossAI_MCP_Manager\Includes\REST\ActivityLogController::instance(),
     962                        'register_routes'
     963                );
     964                $this->loader->add_filter(
     965                        'wp_privacy_personal_data_exporters',
     966                        \AcrossAI_MCP_Manager\Includes\Observability\PersonalData::class,
     967                        'register_exporter'
     968                );
     969                $this->loader->add_filter(
     970                        'wp_privacy_personal_data_erasers',
     971                        \AcrossAI_MCP_Manager\Includes\Observability\PersonalData::class,
     972                        'register_eraser'
     973                );
     974
     975                // The Activity screen: its own submenu under the shared AcrossAI parent,
     976                // not under tools.php. The asset enqueue is gated on the page hook, so
     977                // the 334 KB bundle never loads on an unrelated admin screen.
     978                $activity_page = \AcrossAI_MCP_Manager\Admin\Partials\ActivityLogPage::instance();
     979                $this->loader->add_action( 'admin_menu', $activity_page, 'register_menu', 20 );
     980                $this->loader->add_action( 'admin_enqueue_scripts', $activity_page, 'enqueue_assets' );
     981
     982                // F096 — ability capture.
     983                //
     984                // Core instruments WP_Ability::execute() for EVERY caller, so these
     985                // hooks cover MCP, the REST abilities route, WP-CLI and the admin UI
     986                // without any callback wrapping (which would duplicate core's own seam
     987                // and still miss non-MCP callers).
     988                //
     989                // The 7.1 quartet is feature-detected, NOT required: the plugin floor
     990                // is 6.9 and those hooks are @since 7.1.0. On 6.9 the guaranteed pair
     991                // records successes only — verified in core at class-wp-ability.php:634,
     992                // where a WP_Error early-returns before `wp_after_execute_ability`
     993                // fires, and at :615, where a permission denial returns before the
     994                // `before` hook fires at all. The always-on bracket in
     995                // Base_Toolset_Ability / Abilities\Execute is what covers failures and
     996                // denials for MCP-originated calls on every supported version.
     997                $ability_recorder = \AcrossAI_MCP_Manager\Includes\Abilities\AbilityActivityRecorder::instance();
     998                $this->loader->add_action( 'wp_before_execute_ability', $ability_recorder, 'on_before_execute', 10, 2 );
     999                $this->loader->add_action( 'wp_after_execute_ability', $ability_recorder, 'on_after_execute', 10, 3 );
     1000
     1001                if ( \AcrossAI_MCP_Manager\Includes\Abilities\AbilityActivityRecorder::has_rich_hooks() ) {
     1002                        $this->loader->add_filter( 'wp_ability_execute_result', $ability_recorder, 'on_execute_result', 10, 3 );
     1003                        $this->loader->add_filter( 'wp_ability_permission_result', $ability_recorder, 'on_permission_result', 10, 3 );
     1004                        $this->loader->add_filter( 'wp_ability_validate_input', $ability_recorder, 'on_validate_input', 10, 3 );
     1005                }
     1006
     1007                // The attribution context 097 attaches to. Same A17 three-stage
     1008                // lifecycle as the other two holders, for the same reason.
     1009                $capture_context = \AcrossAI_MCP_Manager\Includes\Observability\CaptureContext::instance();
     1010                $this->loader->add_filter( 'rest_pre_dispatch', $capture_context, 'reset_for_request', 5, 3 );
     1011                $this->loader->add_filter( 'rest_post_dispatch', $capture_context, 'clear', 999, 1 );
     1012                $this->loader->add_action( 'shutdown', $capture_context, 'clear', 999 );
     1013                $this->loader->add_filter( 'rest_post_dispatch', $ability_recorder, 'clear', 999, 1 );
     1014                $this->loader->add_action( 'shutdown', $ability_recorder, 'clear', 999 );
     1015
     1016                // F096 — response-size measurement (context cost).
     1017                //
     1018                // The observability seam passes tags and a duration and NEVER the result
     1019                // payload, so a response's SIZE is unreachable from the handler. These
     1020                // seven published vendor filters do see it, and are hooked purely to
     1021                // take a strlen() — no payload is retained, so there is nothing to
     1022                // redact and no truncation question.
     1023                //
     1024                // `mcp_adapter_tools_list` is the load-bearing one: tools/list has no
     1025                // ability children, so its size cannot be recovered by rolling up
     1026                // parent_id, and the tool catalogue injected at connect is usually the
     1027                // largest single context cost a server imposes.
     1028                //
     1029                // Every callback returns its input unchanged. Priority 10 with the exact
     1030                // arg counts the vendor passes.
     1031                $size_probe = \AcrossAI_MCP_Manager\Includes\Observability\ResponseSizeProbe::instance();
     1032                $this->loader->add_filter( 'mcp_adapter_tool_call_result', $size_probe, 'measure_tool_call', 10, 3 );
     1033                $this->loader->add_filter( 'mcp_adapter_tools_list', $size_probe, 'measure_tools_list', 10, 1 );
     1034                $this->loader->add_filter( 'mcp_adapter_initialize_response', $size_probe, 'measure_initialize', 10, 1 );
     1035                $this->loader->add_filter( 'mcp_adapter_prompt_get_result', $size_probe, 'measure_prompt_get', 10, 3 );
     1036                $this->loader->add_filter( 'mcp_adapter_prompts_list', $size_probe, 'measure_prompts_list', 10, 1 );
     1037                $this->loader->add_filter( 'mcp_adapter_resource_read_result', $size_probe, 'measure_resource_read', 10, 3 );
     1038                $this->loader->add_filter( 'mcp_adapter_resources_list', $size_probe, 'measure_resources_list', 10, 1 );
     1039
     1040                // F096 — the daily retention + ceiling sweep, and a re-sync whenever the
     1041                // bounds change so the schedule follows the settings rather than
     1042                // drifting from them until the next activation.
     1043                $activity_cleanup = \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::instance();
     1044                $this->loader->add_action(
     1045                        \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::CRON_HOOK,
     1046                        $activity_cleanup,
     1047                        'run'
     1048                );
     1049
     1050                // Reconcile the schedule on a normal boot, not only on activation and on
     1051                // a settings save. B68 again, and the default flip is what made it
     1052                // dangerous: WordPress skips activation hooks on a plugin UPDATE, and an
     1053                // operator who is happy with the shipped defaults never saves the
     1054                // settings form — so neither of the two paths that call
     1055                // `sync_schedule()` would ever run. While recording was OFF by default
     1056                // that was harmless: nothing was written, so a missing pruning job
     1057                // pruned nothing. Now that both halves record by default, the same gap
     1058                // means a site logs from its first request with NOTHING ever deleting a
     1059                // row. Priority 4, so the table reconciliation at 3 has already run.
     1060                $this->loader->add_action(
     1061                        'admin_init',
     1062                        \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::class,
     1063                        'sync_schedule',
     1064                        4
     1065                );
     1066
     1067                foreach (
     1068                        array(
     1069                                \AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants::OPTION_RETENTION_REQUEST_DAYS,
     1070                                \AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants::OPTION_RETENTION_ABILITY_DAYS,
     1071                                \AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants::OPTION_MAX_EVENTS,
     1072                        ) as $bound_option
     1073                ) {
     1074                        $this->loader->add_action(
     1075                                'update_option_' . $bound_option,
     1076                                \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::class,
     1077                                'sync_schedule'
     1078                        );
     1079                        $this->loader->add_action(
     1080                                'add_option_' . $bound_option,
     1081                                \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::class,
     1082                                'sync_schedule'
     1083                        );
     1084                }
     1085
    8651086                /**
    8661087                 * Feature 040 — the OAuth admin REST controllers (ClientRegistration + ConnectorAdmin)
    … …  
    9941215                $oauth_timezone_health = \AcrossAI_MCP_Manager\Includes\Database\Support\TimezoneHealthCheck::instance();
    9951216                $this->loader->add_filter( 'site_status_tests', $oauth_timezone_health, 'add_test' );
     1217
     1218                // F096 FR-013a. The Activity Log screen already says "recording is
     1219                // failing" when the counter is non-zero; this is the half that works
     1220                // without anyone opening that screen. Both are needed: the counter
     1221                // resets on the next successful write, so an intermittent fault can
     1222                // erase its own evidence before a human looks, and support cannot ask
     1223                // an operator for a screen they have to navigate to.
     1224                $recording_health = \AcrossAI_MCP_Manager\Includes\Observability\RecordingHealthCheck::instance();
     1225                $this->loader->add_filter( 'site_status_tests', $recording_health, 'add_test' );
     1226
     1227                // F096 FR-013b. `acrossai_mcp_schema_upgrade_failed` is fired by every
     1228                // Table subclass in this plugin and, until this listener, went nowhere.
     1229                // A signal with no listener is the same as no signal.
     1230                $schema_health = \AcrossAI_MCP_Manager\Includes\Database\Support\SchemaFailureHealthCheck::instance();
     1231                $this->loader->add_action( 'acrossai_mcp_schema_upgrade_failed', $schema_health, 'record_failure', 10, 3 );
     1232                $this->loader->add_filter( 'site_status_tests', $schema_health, 'add_test' );
    9961233
    9971234                // The five built-in connector profiles. `ConnectorProfileRegistry` builds
  • acrossai-mcp-manager/tags/0.4.4/includes/OAuth/TokenValidator.php

    r3733272 r3766841  
    1919use AcrossAI_MCP_Manager\Includes\OAuth\Repositories\ClientRepository;
    2020use AcrossAI_MCP_Manager\Includes\OAuth\Security\SecretsVault;
     21use AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants;
    2122
    2223defined( 'ABSPATH' ) || exit;
    … …  
    114115
    115116                        $resolved = (int) $row->user_id;
     117
     118                        /**
     119                         * Fires after a bearer token has been validated successfully.
     120                         *
     121                         * Fire-and-forget (D19): the return value is ignored and listeners
     122                         * must not throw — this method's own flow has to complete whatever
     123                         * happens downstream.
     124                         *
     125                         * Exists so the activity log can record HOW a client authenticated.
     126                         * This method resolves the client row and then discards it, so by
     127                         * the time the adapter's observability handler runs, nothing else
     128                         * can tell an AI connector from a bare DCR client. An action rather
     129                         * than a direct call into Observability keeps this module unaware
     130                         * of that one (Constitution Principle V); the listener is wired in
     131                         * Main.php per A1.
     132                         *
     133                         * @since 0.4.4
     134                         *
     135                         * @param string $connector_slug Connector slug, or '' for a bare client.
     136                         * @param string $client_name    Client display name, or ''.
     137                         */
     138                        do_action(
     139                                ActivityLogConstants::ACTION_OAUTH_TOKEN_VALIDATED,
     140                                isset( $row->connector_slug ) ? (string) $row->connector_slug : '',
     141                                isset( $row->client_name ) ? (string) $row->client_name : ''
     142                        );
     143
    116144                        return $resolved > 0 ? $resolved : $user_id;
    117145                } finally {
  • acrossai-mcp-manager/tags/0.4.4/phpstan-baseline.neon

    r3733272 r3766841  
    584584
    585585                -
    586                         message: '#^Call to function is_array\(\) with array\<string, mixed\> will always evaluate to true\.$#'
    587                         identifier: function.alreadyNarrowedType
    588                         count: 1
    589                         path: includes/Abilities/Discover.php
    590 
    591                 -
    592586                        message: '#^Call to function method_exists\(\) with WP_Ability and ''get_meta'' will always evaluate to true\.$#'
    593587                        identifier: function.alreadyNarrowedType
    … …  
    602596
    603597                -
    604                         message: '#^Call to function is_array\(\) with array\<string, mixed\> will always evaluate to true\.$#'
    605                         identifier: function.alreadyNarrowedType
    606                         count: 1
    607                         path: includes/Abilities/GetAbilityInfo.php
    608 
    609                 -
    610598                        message: '#^Access to an undefined property object\:\:\$override_abilities_permission\.$#'
    611599                        identifier: property.notFound
    … …  
    793781                        path: includes/Database/CliAuthLog/Row.php
    794782
     783                # F096 ActivityLog\Schema — the SAME four BerlinDB warts already recorded
     784                # below for CliAuthLog\Schema, and for the same reason: BerlinDB declares
     785                # $columns/$indexes as array<Kern\Column>/array<Kern\Index> while its own
     786                # boot() offers "legacy support for pre-set $columns array" and hydrates
     787                # plain arrays into objects. No covariant type exists that is also true of
     788                # what we assign, so there is no honest fix inside the file.
     789                #
     790                # FOLLOW-UP: the documented remedy is a stub file correcting
     791                # BerlinDB\Database\Kern\Schema's two @var tags. That would retire these
     792                # four AND the four CliAuthLog entries below in one change. Not done here
     793                # because a third-party stub changes analysis for every file that touches
     794                # BerlinDB, which is not a Phase 2 decision to make unilaterally.
     795                -
     796                        message: '#^PHPDoc type array of property AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema\:\:\$columns is not covariant with PHPDoc type array\<BerlinDB\\Database\\Kern\\Column\> of overridden property BerlinDB\\Database\\Kern\\Schema\:\:\$columns\.$#'
     797                        identifier: property.phpDocType
     798                        count: 1
     799                        path: includes/Database/ActivityLog/Schema.php
     800
     801                -
     802                        message: '#^PHPDoc type array of property AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema\:\:\$indexes is not covariant with PHPDoc type array\<BerlinDB\\Database\\Kern\\Index\> of overridden property BerlinDB\\Database\\Kern\\Schema\:\:\$indexes\.$#'
     803                        identifier: property.phpDocType
     804                        count: 1
     805                        path: includes/Database/ActivityLog/Schema.php
     806
     807                -
     808                        message: '#^Property AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema\:\:\$columns type has no value type specified in iterable type array\.$#'
     809                        identifier: missingType.iterableValue
     810                        count: 1
     811                        path: includes/Database/ActivityLog/Schema.php
     812
     813                -
     814                        message: '#^Property AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema\:\:\$indexes type has no value type specified in iterable type array\.$#'
     815                        identifier: missingType.iterableValue
     816                        count: 1
     817                        path: includes/Database/ActivityLog/Schema.php
     818
    795819                -
    796820                        message: '#^PHPDoc type array of property AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Schema\:\:\$columns is not covariant with PHPDoc type array\<BerlinDB\\Database\\Kern\\Column\> of overridden property BerlinDB\\Database\\Kern\\Schema\:\:\$columns\.$#'
    … …  
    15411565                        identifier: missingType.return
    15421566                        count: 1
    1543                         path: includes/Main.php
    1544 
    1545                 -
    1546                         message: '#^Parameter \#2 \$component of method AcrossAI_MCP_Manager\\Includes\\Loader\:\:add_action\(\) expects object, string given\.$#'
    1547                         identifier: argument.type
    1548                         count: 9
    1549                         path: includes/Main.php
    1550 
    1551                 -
    1552                         message: '#^Parameter \#2 \$component of method AcrossAI_MCP_Manager\\Includes\\Loader\:\:add_filter\(\) expects object, string given\.$#'
    1553                         identifier: argument.type
    1554                         count: 4
    15551567                        path: includes/Main.php
    15561568
  • acrossai-mcp-manager/tags/0.4.4/readme.txt

    r3734601 r3766841  
    55Requires PHP: 8.1
    66Tested up to: 7.1
    7 Stable tag: 0.4.3
     7Stable tag: 0.4.4
    88License: GPL-2.0-or-later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    3737* **Database**: schema and table sizes, index health, bloated autoloaded options, EXPLAIN on a slow query, serialisation-safe search-and-replace.
    3838* **Files**: browse, read, write and delete inside an administrator-defined allowlist; zip backups; wp-config constants; the debug log.
     39* **Activity log**: every MCP request and the abilities it ran, kept as a readable history with retention, a size cap and privacy controls.
    3940* **Cron, updates, diagnostics and cache**: overdue cron jobs, plugin and core updates with rollback and checksum checks, Site Health, recent fatal errors, transients and object cache.
    4041
    … …  
    7778* **File access is confined to an allowlist**, secrets are redacted from file and log reads, and database abilities never accept a raw table name.
    7879
     80= See What the AI Actually Did =
     81
     82Access control decides what an assistant **may** do. The activity log records what it **did**.
     83
     84* **Every request, and every ability behind it.** A single "create a page" from an assistant may run several abilities; the log keeps the request and its abilities together, so you can open one entry and read what actually happened rather than guessing from the result.
     85* **On from the moment you update, and bounded without being configured.** Requests are kept 30 days, ability runs 7, and the whole log is capped at 50,000 entries. A daily job applies all three. Both halves can be switched off.
     86* **Enough detail to answer the real questions**: which assistant, how it authenticated, whether it worked, how long it took, what it was asked and roughly how much of your content it read back.
     87* **It tells you when it is failing.** An empty log and a broken log look identical, so the screen and Site Health both say so when writes are failing, when the table cannot be reached, or when the daily cleanup has not run.
     88* **Private by design.** Sensitive values are redacted by key name before anything is stored, response bodies are never kept, and WordPress's own personal-data export and erase both reach it — erasing clears the person from the record while keeping the event, so the audit history stays intact.
     89
     90Find it under **MCP → Activity Log**, or on any individual server's own tab.
     91
    7992= Full Control Over Every Ability =
    8093
    … …  
    109122
    1101231. Go to **Plugins → Add New Plugin**, search for "AcrossAI MCP Manager", then click **Install Now** and **Activate**.
    111 2. The Quick Connect wizard opens automatically. Follow it, or close it and configure by hand.
     1242. The Connect wizard opens automatically. Follow it, or close it and configure by hand.
    1121253. For one-click setup, open **AcrossAI → MCP**, open a server, go to the **Connectors** tab and copy the URL into your AI client.
    1131264. For config-file clients, choose your client on the **Clients** tab, generate an Application Password, copy the JSON into your client and restart it.
    … …  
    131144= What is included? =
    132145
    133 AcrossAI is two free plugins on WordPress.org: MCP Manager (the server, connectors and access control) and Abilities Manager (the 357 abilities and their controls). Quick Connect sets up both in one click.
     146AcrossAI is two free plugins on WordPress.org: MCP Manager (the server, connectors and access control) and Abilities Manager (the 357 abilities and their controls). Connect sets up both in one click.
     147
     148= Can I see what the AI did to my site? =
     149
     150Yes. **MCP → Activity Log** records every request an assistant made and every ability that ran to fulfil it, with the two linked so you can open one entry and read the whole call. It records from the moment you update — requests kept 30 days, ability runs 7, capped at 50,000 entries, all adjustable, and either half can be switched off on the MCP settings tab.
     151
     152If recording ever fails, the screen and Site Health say so rather than showing an empty list, because a broken log and a quiet one otherwise look the same.
    134153
    135154= Is it free? =
    … …  
    241260The complete release history lives at [acrossai.co/changelog](https://acrossai.co/changelog/).
    242261
     262= 0.4.4 =
     263* **New: a log of what AI assistants actually did on your site.** Every request an assistant makes, and every ability that ran to fulfil it, recorded together — one "create a page" from an assistant may run several abilities, and the log keeps them linked, so you open one entry and read what happened instead of inferring it from the result. It records which assistant, how it authenticated, whether it worked, how long it took, what was asked and roughly how much of your content was read back. Find it under **MCP → Activity Log**, or on an individual server's own tab.
     264* **The log is on from the moment you update, and bounded without being configured.** Requests are kept 30 days, ability runs 7 — they are much noisier — and the whole log is capped at 50,000 entries. A daily job applies all three. Every number is adjustable and either half can be switched off on the MCP settings tab. Recording is on by default because a log nobody enabled is a log nobody has when they need it; it is bounded by default because a plugin that records without being asked should also tidy up without being asked.
     265* **It tells you when it is failing.** An empty log and a broken log look identical, which is how a logging fault stays invisible. The screen and Site Health now both report when writes are failing, when the table cannot be reached, and when the daily cleanup has not run — the last one usually meaning WordPress scheduled tasks are not running at all on the site, which affects far more than this log.
     266* **Private by design.** Values that look like credentials are redacted by key name before anything is stored, response bodies are never kept, and WordPress's own personal-data export and erase both reach the log. Erasure clears the person from the record and keeps the event, so a subject request cannot be used to delete audit history.
     267* **Changed: the connection wizard is now called "Connect".** It was "Quick Connect via AcrossAI" in the admin bar, the menu, the server list and the wizard's own header. Nothing moved and nothing behaves differently — the label just says less.
     268* **Fixed: a PHP notice on every page load.** A database table was passing an index setting in a form newer PHP versions warn about. It had never had any effect — the table was not using it — so removing it changes nothing except that the notice stops. Only visible to sites with debug logging switched on.
     269
    243270= 0.4.3 =
    244271* **New: a heads-up in Firefox, where tracking protection can block an assistant from connecting.** Firefox's Enhanced Tracking Protection can stop the connection part-way through — the connector is added, sign-in opens, and then nothing completes, with no error shown anywhere to explain it. Opening a connector screen in Firefox now shows a note explaining this and how to get past it: click the shield icon to the left of the address bar and switch Enhanced Tracking Protection off for this site, then connect again. The setting is remembered per site, affects nothing else you browse, and can be switched back on once the connection is working. The note appears only in Firefox and can be dismissed.
  • acrossai-mcp-manager/tags/0.4.4/uninstall.php

    r3734601 r3766841  
    8484        $wpdb->prefix . 'acrossai_mcp_server_tools',     // F020 per-server tool selection.
    8585        $wpdb->prefix . 'acrossai_mcp_servers_meta',     // F037 MCPServerMeta — per-server key/value settings (Embeds tab, etc).
     86        $wpdb->prefix . 'acrossai_mcp_activity_log',     // F096 activity log — MCP requests + ability runs.
    8687        // F095 — this plugin's own OAuth tables. See the DO NOT REMOVE note above.
    8788        $wpdb->prefix . 'acrossai_mcp_oauth_clients',
  • acrossai-mcp-manager/tags/0.4.4/vendor/composer/autoload_classmap.php

    r3733272 r3766841  
    88return array(
    99    'AcrossAI_MCP_Manager\\Admin\\Main' => $baseDir . '/admin/Main.php',
     10    'AcrossAI_MCP_Manager\\Admin\\Partials\\ActivityLogPage' => $baseDir . '/admin/Partials/ActivityLogPage.php',
    1011    'AcrossAI_MCP_Manager\\Admin\\Partials\\AddonsFilter' => $baseDir . '/admin/Partials/AddonsFilter.php',
    1112    'AcrossAI_MCP_Manager\\Admin\\Partials\\ApplicationPasswords' => $baseDir . '/admin/Partials/ApplicationPasswords.php',
    … …  
    4041    'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsMenu' => $baseDir . '/admin/Partials/SettingsMenu.php',
    4142    'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsRenderer' => $baseDir . '/admin/Partials/SettingsRenderer.php',
     43    'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityActivityRecorder' => $baseDir . '/includes/Abilities/AbilityActivityRecorder.php',
    4244    'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityHelpers' => $baseDir . '/includes/Abilities/AbilityHelpers.php',
    4345    'AcrossAI_MCP_Manager\\Includes\\Abilities\\CallbackReplacer' => $baseDir . '/includes/Abilities/CallbackReplacer.php',
    … …  
    8284    'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSettings' => $baseDir . '/includes/Connectors/ConnectorSettings.php',
    8385    'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSlugDisplay' => $baseDir . '/includes/Connectors/ConnectorSlugDisplay.php',
     86    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Cleanup' => $baseDir . '/includes/Database/ActivityLog/Cleanup.php',
     87    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Query' => $baseDir . '/includes/Database/ActivityLog/Query.php',
     88    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Recorder' => $baseDir . '/includes/Database/ActivityLog/Recorder.php',
     89    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Row' => $baseDir . '/includes/Database/ActivityLog/Row.php',
     90    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema' => $baseDir . '/includes/Database/ActivityLog/Schema.php',
     91    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Table' => $baseDir . '/includes/Database/ActivityLog/Table.php',
    8492    'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Query' => $baseDir . '/includes/Database/CliAuthLog/Query.php',
    8593    'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Recorder' => $baseDir . '/includes/Database/CliAuthLog/Recorder.php',
    … …  
    134142    'AcrossAI_MCP_Manager\\Includes\\Database\\SchemaReconciler' => $baseDir . '/includes/Database/SchemaReconciler.php',
    135143    'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\DatetimeColumn' => $baseDir . '/includes/Database/Support/DatetimeColumn.php',
     144    'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\SchemaFailureHealthCheck' => $baseDir . '/includes/Database/Support/SchemaFailureHealthCheck.php',
    136145    'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\TimezoneHealthCheck' => $baseDir . '/includes/Database/Support/TimezoneHealthCheck.php',
    137146    'AcrossAI_MCP_Manager\\Includes\\Deactivator' => $baseDir . '/includes/Deactivator.php',
    … …  
    187196    'AcrossAI_MCP_Manager\\Includes\\OAuth\\TokenValidator' => $baseDir . '/includes/OAuth/TokenValidator.php',
    188197    'AcrossAI_MCP_Manager\\Includes\\OAuth\\UserLifecycle' => $baseDir . '/includes/OAuth/UserLifecycle.php',
     198    'AcrossAI_MCP_Manager\\Includes\\Observability\\ActivityObservabilityHandler' => $baseDir . '/includes/Observability/ActivityObservabilityHandler.php',
     199    'AcrossAI_MCP_Manager\\Includes\\Observability\\AuthContextHolder' => $baseDir . '/includes/Observability/AuthContextHolder.php',
     200    'AcrossAI_MCP_Manager\\Includes\\Observability\\CaptureContext' => $baseDir . '/includes/Observability/CaptureContext.php',
     201    'AcrossAI_MCP_Manager\\Includes\\Observability\\ConnectionContext' => $baseDir . '/includes/Observability/ConnectionContext.php',
     202    'AcrossAI_MCP_Manager\\Includes\\Observability\\HandlerResolver' => $baseDir . '/includes/Observability/HandlerResolver.php',
     203    'AcrossAI_MCP_Manager\\Includes\\Observability\\PersonalData' => $baseDir . '/includes/Observability/PersonalData.php',
     204    'AcrossAI_MCP_Manager\\Includes\\Observability\\RecordingHealthCheck' => $baseDir . '/includes/Observability/RecordingHealthCheck.php',
     205    'AcrossAI_MCP_Manager\\Includes\\Observability\\ResponseSizeProbe' => $baseDir . '/includes/Observability/ResponseSizeProbe.php',
    189206    'AcrossAI_MCP_Manager\\Includes\\REST\\AbilitiesController' => $baseDir . '/includes/REST/AbilitiesController.php',
     207    'AcrossAI_MCP_Manager\\Includes\\REST\\ActivityLogController' => $baseDir . '/includes/REST/ActivityLogController.php',
    190208    'AcrossAI_MCP_Manager\\Includes\\REST\\CliController' => $baseDir . '/includes/REST/CliController.php',
    191209    'AcrossAI_MCP_Manager\\Includes\\REST\\ClientRendererController' => $baseDir . '/includes/REST/ClientRendererController.php',
    192210    'AcrossAI_MCP_Manager\\Includes\\REST\\QuickConnectController' => $baseDir . '/includes/REST/QuickConnectController.php',
    193211    'AcrossAI_MCP_Manager\\Includes\\REST\\ToolsController' => $baseDir . '/includes/REST/ToolsController.php',
     212    'AcrossAI_MCP_Manager\\Includes\\Utilities\\ActivityLogConstants' => $baseDir . '/includes/Utilities/ActivityLogConstants.php',
    194213    'AcrossAI_MCP_Manager\\Includes\\Utilities\\AdminPageSlugs' => $baseDir . '/includes/Utilities/AdminPageSlugs.php',
    195214    'AcrossAI_MCP_Manager\\Includes\\Utilities\\CacheHeaders' => $baseDir . '/includes/Utilities/CacheHeaders.php',
  • acrossai-mcp-manager/tags/0.4.4/vendor/composer/autoload_static.php

    r3733272 r3766841  
    7373    public static $classMap = array (
    7474        'AcrossAI_MCP_Manager\\Admin\\Main' => __DIR__ . '/../..' . '/admin/Main.php',
     75        'AcrossAI_MCP_Manager\\Admin\\Partials\\ActivityLogPage' => __DIR__ . '/../..' . '/admin/Partials/ActivityLogPage.php',
    7576        'AcrossAI_MCP_Manager\\Admin\\Partials\\AddonsFilter' => __DIR__ . '/../..' . '/admin/Partials/AddonsFilter.php',
    7677        'AcrossAI_MCP_Manager\\Admin\\Partials\\ApplicationPasswords' => __DIR__ . '/../..' . '/admin/Partials/ApplicationPasswords.php',
    … …  
    105106        'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsMenu' => __DIR__ . '/../..' . '/admin/Partials/SettingsMenu.php',
    106107        'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsRenderer' => __DIR__ . '/../..' . '/admin/Partials/SettingsRenderer.php',
     108        'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityActivityRecorder' => __DIR__ . '/../..' . '/includes/Abilities/AbilityActivityRecorder.php',
    107109        'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityHelpers' => __DIR__ . '/../..' . '/includes/Abilities/AbilityHelpers.php',
    108110        'AcrossAI_MCP_Manager\\Includes\\Abilities\\CallbackReplacer' => __DIR__ . '/../..' . '/includes/Abilities/CallbackReplacer.php',
    … …  
    147149        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSettings' => __DIR__ . '/../..' . '/includes/Connectors/ConnectorSettings.php',
    148150        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSlugDisplay' => __DIR__ . '/../..' . '/includes/Connectors/ConnectorSlugDisplay.php',
     151        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Cleanup' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Cleanup.php',
     152        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Query' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Query.php',
     153        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Recorder' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Recorder.php',
     154        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Row' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Row.php',
     155        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Schema.php',
     156        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Table' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Table.php',
    149157        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Query' => __DIR__ . '/../..' . '/includes/Database/CliAuthLog/Query.php',
    150158        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Recorder' => __DIR__ . '/../..' . '/includes/Database/CliAuthLog/Recorder.php',
    … …  
    199207        'AcrossAI_MCP_Manager\\Includes\\Database\\SchemaReconciler' => __DIR__ . '/../..' . '/includes/Database/SchemaReconciler.php',
    200208        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\DatetimeColumn' => __DIR__ . '/../..' . '/includes/Database/Support/DatetimeColumn.php',
     209        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\SchemaFailureHealthCheck' => __DIR__ . '/../..' . '/includes/Database/Support/SchemaFailureHealthCheck.php',
    201210        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\TimezoneHealthCheck' => __DIR__ . '/../..' . '/includes/Database/Support/TimezoneHealthCheck.php',
    202211        'AcrossAI_MCP_Manager\\Includes\\Deactivator' => __DIR__ . '/../..' . '/includes/Deactivator.php',
    … …  
    252261        'AcrossAI_MCP_Manager\\Includes\\OAuth\\TokenValidator' => __DIR__ . '/../..' . '/includes/OAuth/TokenValidator.php',
    253262        'AcrossAI_MCP_Manager\\Includes\\OAuth\\UserLifecycle' => __DIR__ . '/../..' . '/includes/OAuth/UserLifecycle.php',
     263        'AcrossAI_MCP_Manager\\Includes\\Observability\\ActivityObservabilityHandler' => __DIR__ . '/../..' . '/includes/Observability/ActivityObservabilityHandler.php',
     264        'AcrossAI_MCP_Manager\\Includes\\Observability\\AuthContextHolder' => __DIR__ . '/../..' . '/includes/Observability/AuthContextHolder.php',
     265        'AcrossAI_MCP_Manager\\Includes\\Observability\\CaptureContext' => __DIR__ . '/../..' . '/includes/Observability/CaptureContext.php',
     266        'AcrossAI_MCP_Manager\\Includes\\Observability\\ConnectionContext' => __DIR__ . '/../..' . '/includes/Observability/ConnectionContext.php',
     267        'AcrossAI_MCP_Manager\\Includes\\Observability\\HandlerResolver' => __DIR__ . '/../..' . '/includes/Observability/HandlerResolver.php',
     268        'AcrossAI_MCP_Manager\\Includes\\Observability\\PersonalData' => __DIR__ . '/../..' . '/includes/Observability/PersonalData.php',
     269        'AcrossAI_MCP_Manager\\Includes\\Observability\\RecordingHealthCheck' => __DIR__ . '/../..' . '/includes/Observability/RecordingHealthCheck.php',
     270        'AcrossAI_MCP_Manager\\Includes\\Observability\\ResponseSizeProbe' => __DIR__ . '/../..' . '/includes/Observability/ResponseSizeProbe.php',
    254271        'AcrossAI_MCP_Manager\\Includes\\REST\\AbilitiesController' => __DIR__ . '/../..' . '/includes/REST/AbilitiesController.php',
     272        'AcrossAI_MCP_Manager\\Includes\\REST\\ActivityLogController' => __DIR__ . '/../..' . '/includes/REST/ActivityLogController.php',
    255273        'AcrossAI_MCP_Manager\\Includes\\REST\\CliController' => __DIR__ . '/../..' . '/includes/REST/CliController.php',
    256274        'AcrossAI_MCP_Manager\\Includes\\REST\\ClientRendererController' => __DIR__ . '/../..' . '/includes/REST/ClientRendererController.php',
    257275        'AcrossAI_MCP_Manager\\Includes\\REST\\QuickConnectController' => __DIR__ . '/../..' . '/includes/REST/QuickConnectController.php',
    258276        'AcrossAI_MCP_Manager\\Includes\\REST\\ToolsController' => __DIR__ . '/../..' . '/includes/REST/ToolsController.php',
     277        'AcrossAI_MCP_Manager\\Includes\\Utilities\\ActivityLogConstants' => __DIR__ . '/../..' . '/includes/Utilities/ActivityLogConstants.php',
    259278        'AcrossAI_MCP_Manager\\Includes\\Utilities\\AdminPageSlugs' => __DIR__ . '/../..' . '/includes/Utilities/AdminPageSlugs.php',
    260279        'AcrossAI_MCP_Manager\\Includes\\Utilities\\CacheHeaders' => __DIR__ . '/../..' . '/includes/Utilities/CacheHeaders.php',
  • acrossai-mcp-manager/tags/0.4.4/vendor/composer/installed.php

    r3734601 r3766841  
    22    'root' => array(
    33        'name' => 'wpboilerplate/acrossai-mcp-manager',
    4         'pretty_version' => 'v0.4.3',
    5         'version' => '0.4.3.0',
    6         'reference' => '3fe89542507880384b80f8bd2315eb976044777f',
     4        'pretty_version' => 'v0.4.4',
     5        'version' => '0.4.4.0',
     6        'reference' => '0bda489a333ca8aad4dda333bfa25e25a0ff1628',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
    … …  
    5757        ),
    5858        'wpboilerplate/acrossai-mcp-manager' => array(
    59             'pretty_version' => 'v0.4.3',
    60             'version' => '0.4.3.0',
    61             'reference' => '3fe89542507880384b80f8bd2315eb976044777f',
     59            'pretty_version' => 'v0.4.4',
     60            'version' => '0.4.4.0',
     61            'reference' => '0bda489a333ca8aad4dda333bfa25e25a0ff1628',
    6262            'type' => 'wordpress-plugin',
    6363            'install_path' => __DIR__ . '/../../',
  • acrossai-mcp-manager/tags/0.4.4/vendor/composer/jetpack_autoload_classmap.php

    r3734601 r3766841  
    88return array(
    99        'AcrossAI_MCP_Manager\\Admin\\Main' => array(
    10                 'version' => '0.4.3.0',
     10                'version' => '0.4.4.0',
    1111                'path'    => $baseDir . '/admin/Main.php'
    1212        ),
     13        'AcrossAI_MCP_Manager\\Admin\\Partials\\ActivityLogPage' => array(
     14                'version' => '0.4.4.0',
     15                'path'    => $baseDir . '/admin/Partials/ActivityLogPage.php'
     16        ),
    1317        'AcrossAI_MCP_Manager\\Admin\\Partials\\AddonsFilter' => array(
    14                 'version' => '0.4.3.0',
     18                'version' => '0.4.4.0',
    1519                'path'    => $baseDir . '/admin/Partials/AddonsFilter.php'
    1620        ),
    1721        'AcrossAI_MCP_Manager\\Admin\\Partials\\ApplicationPasswords' => array(
    18                 'version' => '0.4.3.0',
     22                'version' => '0.4.4.0',
    1923                'path'    => $baseDir . '/admin/Partials/ApplicationPasswords.php'
    2024        ),
    2125        'AcrossAI_MCP_Manager\\Admin\\Partials\\CliAuthLogListTable' => array(
    22                 'version' => '0.4.3.0',
     26                'version' => '0.4.4.0',
    2327                'path'    => $baseDir . '/admin/Partials/CliAuthLogListTable.php'
    2428        ),
    2529        'AcrossAI_MCP_Manager\\Admin\\Partials\\MCPServerListTable' => array(
    26                 'version' => '0.4.3.0',
     30                'version' => '0.4.4.0',
    2731                'path'    => $baseDir . '/admin/Partials/MCPServerListTable.php'
    2832        ),
    2933        'AcrossAI_MCP_Manager\\Admin\\Partials\\Menu' => array(
    30                 'version' => '0.4.3.0',
     34                'version' => '0.4.4.0',
    3135                'path'    => $baseDir . '/admin/Partials/Menu.php'
    3236        ),
    3337        'AcrossAI_MCP_Manager\\Admin\\Partials\\Notices' => array(
    34                 'version' => '0.4.3.0',
     38                'version' => '0.4.4.0',
    3539                'path'    => $baseDir . '/admin/Partials/Notices.php'
    3640        ),
    3741        'AcrossAI_MCP_Manager\\Admin\\Partials\\QuickConnect\\ActivationRedirect' => array(
    38                 'version' => '0.4.3.0',
     42                'version' => '0.4.4.0',
    3943                'path'    => $baseDir . '/admin/Partials/QuickConnect/ActivationRedirect.php'
    4044        ),
    4145        'AcrossAI_MCP_Manager\\Admin\\Partials\\QuickConnect\\AdminBarEntry' => array(
    42                 'version' => '0.4.3.0',
     46                'version' => '0.4.4.0',
    4347                'path'    => $baseDir . '/admin/Partials/QuickConnect/AdminBarEntry.php'
    4448        ),
    4549        'AcrossAI_MCP_Manager\\Admin\\Partials\\QuickConnect\\QuickConnectPage' => array(
    46                 'version' => '0.4.3.0',
     50                'version' => '0.4.4.0',
    4751                'path'    => $baseDir . '/admin/Partials/QuickConnect/QuickConnectPage.php'
    4852        ),
    4953        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AIConnectorsTab' => array(
    50                 'version' => '0.4.3.0',
     54                'version' => '0.4.4.0',
    5155                'path'    => $baseDir . '/admin/Partials/ServerTabs/AIConnectorsTab.php'
    5256        ),
    5357        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AbilitiesTab' => array(
    54                 'version' => '0.4.3.0',
     58                'version' => '0.4.4.0',
    5559                'path'    => $baseDir . '/admin/Partials/ServerTabs/AbilitiesTab.php'
    5660        ),
    5761        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AbstractReactMountServerTab' => array(
    58                 'version' => '0.4.3.0',
     62                'version' => '0.4.4.0',
    5963                'path'    => $baseDir . '/admin/Partials/ServerTabs/AbstractReactMountServerTab.php'
    6064        ),
    6165        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AbstractServerTab' => array(
    62                 'version' => '0.4.3.0',
     66                'version' => '0.4.4.0',
    6367                'path'    => $baseDir . '/admin/Partials/ServerTabs/AbstractServerTab.php'
    6468        ),
    6569        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AccessControlTab' => array(
    66                 'version' => '0.4.3.0',
     70                'version' => '0.4.4.0',
    6771                'path'    => $baseDir . '/admin/Partials/ServerTabs/AccessControlTab.php'
    6872        ),
    6973        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\ClientsTab' => array(
    70                 'version' => '0.4.3.0',
     74                'version' => '0.4.4.0',
    7175                'path'    => $baseDir . '/admin/Partials/ServerTabs/ClientsTab.php'
    7276        ),
    7377        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\ConnectTab' => array(
    74                 'version' => '0.4.3.0',
     78                'version' => '0.4.4.0',
    7579                'path'    => $baseDir . '/admin/Partials/ServerTabs/ConnectTab.php'
    7680        ),
    7781        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\Connect\\MethodRegistry' => array(
    78                 'version' => '0.4.3.0',
     82                'version' => '0.4.4.0',
    7983                'path'    => $baseDir . '/admin/Partials/ServerTabs/Connect/MethodRegistry.php'
    8084        ),
    8185        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\DangerZoneTab' => array(
    82                 'version' => '0.4.3.0',
     86                'version' => '0.4.4.0',
    8387                'path'    => $baseDir . '/admin/Partials/ServerTabs/DangerZoneTab.php'
    8488        ),
    8589        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\EmbedsTab' => array(
    86                 'version' => '0.4.3.0',
     90                'version' => '0.4.4.0',
    8791                'path'    => $baseDir . '/admin/Partials/ServerTabs/EmbedsTab.php'
    8892        ),
    8993        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\FilteredServerTab' => array(
    90                 'version' => '0.4.3.0',
     94                'version' => '0.4.4.0',
    9195                'path'    => $baseDir . '/admin/Partials/ServerTabs/FilteredServerTab.php'
    9296        ),
    9397        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\McpTrackerTab' => array(
    94                 'version' => '0.4.3.0',
     98                'version' => '0.4.4.0',
    9599                'path'    => $baseDir . '/admin/Partials/ServerTabs/McpTrackerTab.php'
    96100        ),
    97101        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\NpmTab' => array(
    98                 'version' => '0.4.3.0',
     102                'version' => '0.4.4.0',
    99103                'path'    => $baseDir . '/admin/Partials/ServerTabs/NpmTab.php'
    100104        ),
    101105        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\OverviewTab' => array(
    102                 'version' => '0.4.3.0',
     106                'version' => '0.4.4.0',
    103107                'path'    => $baseDir . '/admin/Partials/ServerTabs/OverviewTab.php'
    104108        ),
    105109        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\Partials\\AbilitiesManagerPromoCard' => array(
    106                 'version' => '0.4.3.0',
     110                'version' => '0.4.4.0',
    107111                'path'    => $baseDir . '/admin/Partials/ServerTabs/Partials/AbilitiesManagerPromoCard.php'
    108112        ),
    109113        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\Partials\\TypeRequirementNotice' => array(
    110                 'version' => '0.4.3.0',
     114                'version' => '0.4.4.0',
    111115                'path'    => $baseDir . '/admin/Partials/ServerTabs/Partials/TypeRequirementNotice.php'
    112116        ),
    113117        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\Registry' => array(
    114                 'version' => '0.4.3.0',
     118                'version' => '0.4.4.0',
    115119                'path'    => $baseDir . '/admin/Partials/ServerTabs/Registry.php'
    116120        ),
    117121        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\ToolsTab' => array(
    118                 'version' => '0.4.3.0',
     122                'version' => '0.4.4.0',
    119123                'path'    => $baseDir . '/admin/Partials/ServerTabs/ToolsTab.php'
    120124        ),
    121125        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\UpdateServerTab' => array(
    122                 'version' => '0.4.3.0',
     126                'version' => '0.4.4.0',
    123127                'path'    => $baseDir . '/admin/Partials/ServerTabs/UpdateServerTab.php'
    124128        ),
    125129        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\WpCliTab' => array(
    126                 'version' => '0.4.3.0',
     130                'version' => '0.4.4.0',
    127131                'path'    => $baseDir . '/admin/Partials/ServerTabs/WpCliTab.php'
    128132        ),
    129133        'AcrossAI_MCP_Manager\\Admin\\Partials\\Settings' => array(
    130                 'version' => '0.4.3.0',
     134                'version' => '0.4.4.0',
    131135                'path'    => $baseDir . '/admin/Partials/Settings.php'
    132136        ),
    133137        'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsMenu' => array(
    134                 'version' => '0.4.3.0',
     138                'version' => '0.4.4.0',
    135139                'path'    => $baseDir . '/admin/Partials/SettingsMenu.php'
    136140        ),
    137141        'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsRenderer' => array(
    138                 'version' => '0.4.3.0',
     142                'version' => '0.4.4.0',
    139143                'path'    => $baseDir . '/admin/Partials/SettingsRenderer.php'
    140144        ),
     145        'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityActivityRecorder' => array(
     146                'version' => '0.4.4.0',
     147                'path'    => $baseDir . '/includes/Abilities/AbilityActivityRecorder.php'
     148        ),
    141149        'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityHelpers' => array(
    142                 'version' => '0.4.3.0',
     150                'version' => '0.4.4.0',
    143151                'path'    => $baseDir . '/includes/Abilities/AbilityHelpers.php'
    144152        ),
    145153        'AcrossAI_MCP_Manager\\Includes\\Abilities\\CallbackReplacer' => array(
    146                 'version' => '0.4.3.0',
     154                'version' => '0.4.4.0',
    147155                'path'    => $baseDir . '/includes/Abilities/CallbackReplacer.php'
    148156        ),
    149157        'AcrossAI_MCP_Manager\\Includes\\Abilities\\CurrentServerHolder' => array(
    150                 'version' => '0.4.3.0',
     158                'version' => '0.4.4.0',
    151159                'path'    => $baseDir . '/includes/Abilities/CurrentServerHolder.php'
    152160        ),
    153161        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Discover' => array(
    154                 'version' => '0.4.3.0',
     162                'version' => '0.4.4.0',
    155163                'path'    => $baseDir . '/includes/Abilities/Discover.php'
    156164        ),
    157165        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Execute' => array(
    158                 'version' => '0.4.3.0',
     166                'version' => '0.4.4.0',
    159167                'path'    => $baseDir . '/includes/Abilities/Execute.php'
    160168        ),
    161169        'AcrossAI_MCP_Manager\\Includes\\Abilities\\GetAbilityInfo' => array(
    162                 'version' => '0.4.3.0',
     170                'version' => '0.4.4.0',
    163171                'path'    => $baseDir . '/includes/Abilities/GetAbilityInfo.php'
    164172        ),
    165173        'AcrossAI_MCP_Manager\\Includes\\Abilities\\PermissionOverrideProcessor' => array(
    166                 'version' => '0.4.3.0',
     174                'version' => '0.4.4.0',
    167175                'path'    => $baseDir . '/includes/Abilities/PermissionOverrideProcessor.php'
    168176        ),
    169177        'AcrossAI_MCP_Manager\\Includes\\Abilities\\ServerGuide' => array(
    170                 'version' => '0.4.3.0',
     178                'version' => '0.4.4.0',
    171179                'path'    => $baseDir . '/includes/Abilities/ServerGuide.php'
    172180        ),
    173181        'AcrossAI_MCP_Manager\\Includes\\Abilities\\SetupRequired' => array(
    174                 'version' => '0.4.3.0',
     182                'version' => '0.4.4.0',
    175183                'path'    => $baseDir . '/includes/Abilities/SetupRequired.php'
    176184        ),
    177185        'AcrossAI_MCP_Manager\\Includes\\Abilities\\ToolAbilities' => array(
    178                 'version' => '0.4.3.0',
     186                'version' => '0.4.4.0',
    179187                'path'    => $baseDir . '/includes/Abilities/ToolAbilities.php'
    180188        ),
    181189        'AcrossAI_MCP_Manager\\Includes\\Abilities\\ToolsetExposureBridge' => array(
    182                 'version' => '0.4.3.0',
     190                'version' => '0.4.4.0',
    183191                'path'    => $baseDir . '/includes/Abilities/ToolsetExposureBridge.php'
    184192        ),
    185193        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\AbilityGroup' => array(
    186                 'version' => '0.4.3.0',
     194                'version' => '0.4.4.0',
    187195                'path'    => $baseDir . '/includes/Abilities/Toolset/AbilityGroup.php'
    188196        ),
    189197        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Appearance' => array(
    190                 'version' => '0.4.3.0',
     198                'version' => '0.4.4.0',
    191199                'path'    => $baseDir . '/includes/Abilities/Toolset/Appearance.php'
    192200        ),
    193201        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Base_Toolset_Ability' => array(
    194                 'version' => '0.4.3.0',
     202                'version' => '0.4.4.0',
    195203                'path'    => $baseDir . '/includes/Abilities/Toolset/Base_Toolset_Ability.php'
    196204        ),
    197205        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Blocks' => array(
    198                 'version' => '0.4.3.0',
     206                'version' => '0.4.4.0',
    199207                'path'    => $baseDir . '/includes/Abilities/Toolset/Blocks.php'
    200208        ),
    201209        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Cache' => array(
    202                 'version' => '0.4.3.0',
     210                'version' => '0.4.4.0',
    203211                'path'    => $baseDir . '/includes/Abilities/Toolset/Cache.php'
    204212        ),
    205213        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Category_Registrar' => array(
    206                 'version' => '0.4.3.0',
     214                'version' => '0.4.4.0',
    207215                'path'    => $baseDir . '/includes/Abilities/Toolset/Category_Registrar.php'
    208216        ),
    209217        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Configuration' => array(
    210                 'version' => '0.4.3.0',
     218                'version' => '0.4.4.0',
    211219                'path'    => $baseDir . '/includes/Abilities/Toolset/Configuration.php'
    212220        ),
    213221        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Content' => array(
    214                 'version' => '0.4.3.0',
     222                'version' => '0.4.4.0',
    215223                'path'    => $baseDir . '/includes/Abilities/Toolset/Content.php'
    216224        ),
    217225        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Cron' => array(
    218                 'version' => '0.4.3.0',
     226                'version' => '0.4.4.0',
    219227                'path'    => $baseDir . '/includes/Abilities/Toolset/Cron.php'
    220228        ),
    221229        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Database' => array(
    222                 'version' => '0.4.3.0',
     230                'version' => '0.4.4.0',
    223231                'path'    => $baseDir . '/includes/Abilities/Toolset/Database.php'
    224232        ),
    225233        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Diagnostics' => array(
    226                 'version' => '0.4.3.0',
     234                'version' => '0.4.4.0',
    227235                'path'    => $baseDir . '/includes/Abilities/Toolset/Diagnostics.php'
    228236        ),
    229237        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Files' => array(
    230                 'version' => '0.4.3.0',
     238                'version' => '0.4.4.0',
    231239                'path'    => $baseDir . '/includes/Abilities/Toolset/Files.php'
    232240        ),
    233241        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Guide' => array(
    234                 'version' => '0.4.3.0',
     242                'version' => '0.4.4.0',
    235243                'path'    => $baseDir . '/includes/Abilities/Toolset/Guide.php'
    236244        ),
    237245        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\InputNormalizer' => array(
    238                 'version' => '0.4.3.0',
     246                'version' => '0.4.4.0',
    239247                'path'    => $baseDir . '/includes/Abilities/Toolset/InputNormalizer.php'
    240248        ),
    241249        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Integrations' => array(
    242                 'version' => '0.4.3.0',
     250                'version' => '0.4.4.0',
    243251                'path'    => $baseDir . '/includes/Abilities/Toolset/Integrations.php'
    244252        ),
    245253        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Registrar' => array(
    246                 'version' => '0.4.3.0',
     254                'version' => '0.4.4.0',
    247255                'path'    => $baseDir . '/includes/Abilities/Toolset/Registrar.php'
    248256        ),
    249257        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Updates' => array(
    250                 'version' => '0.4.3.0',
     258                'version' => '0.4.4.0',
    251259                'path'    => $baseDir . '/includes/Abilities/Toolset/Updates.php'
    252260        ),
    253261        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Users' => array(
    254                 'version' => '0.4.3.0',
     262                'version' => '0.4.4.0',
    255263                'path'    => $baseDir . '/includes/Abilities/Toolset/Users.php'
    256264        ),
    257265        'AcrossAI_MCP_Manager\\Includes\\AccessControl\\AcrossAI_MCP_Access_Control' => array(
    258                 'version' => '0.4.3.0',
     266                'version' => '0.4.4.0',
    259267                'path'    => $baseDir . '/includes/AccessControl/AcrossAI_MCP_Access_Control.php'
    260268        ),
    261269        'AcrossAI_MCP_Manager\\Includes\\AccessControl\\TransportPermissionDefault' => array(
    262                 'version' => '0.4.3.0',
     270                'version' => '0.4.4.0',
    263271                'path'    => $baseDir . '/includes/AccessControl/TransportPermissionDefault.php'
    264272        ),
    265273        'AcrossAI_MCP_Manager\\Includes\\Activator' => array(
    266                 'version' => '0.4.3.0',
     274                'version' => '0.4.4.0',
    267275                'path'    => $baseDir . '/includes/Activator.php'
    268276        ),
    269277        'AcrossAI_MCP_Manager\\Includes\\Compat' => array(
    270                 'version' => '0.4.3.0',
     278                'version' => '0.4.4.0',
    271279                'path'    => $baseDir . '/includes/Compat.php'
    272280        ),
    273281        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\ChatGPTConnectorProfile' => array(
    274                 'version' => '0.4.3.0',
     282                'version' => '0.4.4.0',
    275283                'path'    => $baseDir . '/includes/ConnectorProfiles/ChatGPTConnectorProfile.php'
    276284        ),
    277285        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\ClaudeConnectorProfile' => array(
    278                 'version' => '0.4.3.0',
     286                'version' => '0.4.4.0',
    279287                'path'    => $baseDir . '/includes/ConnectorProfiles/ClaudeConnectorProfile.php'
    280288        ),
    281289        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\CursorConnectorProfile' => array(
    282                 'version' => '0.4.3.0',
     290                'version' => '0.4.4.0',
    283291                'path'    => $baseDir . '/includes/ConnectorProfiles/CursorConnectorProfile.php'
    284292        ),
    285293        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\GeminiConnectorProfile' => array(
    286                 'version' => '0.4.3.0',
     294                'version' => '0.4.4.0',
    287295                'path'    => $baseDir . '/includes/ConnectorProfiles/GeminiConnectorProfile.php'
    288296        ),
    289297        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\GrokConnectorProfile' => array(
    290                 'version' => '0.4.3.0',
     298                'version' => '0.4.4.0',
    291299                'path'    => $baseDir . '/includes/ConnectorProfiles/GrokConnectorProfile.php'
    292300        ),
    293301        'AcrossAI_MCP_Manager\\Includes\\Connectors\\AbstractConnectorProfile' => array(
    294                 'version' => '0.4.3.0',
     302                'version' => '0.4.4.0',
    295303                'path'    => $baseDir . '/includes/Connectors/AbstractConnectorProfile.php'
    296304        ),
    297305        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorProfileRegistry' => array(
    298                 'version' => '0.4.3.0',
     306                'version' => '0.4.4.0',
    299307                'path'    => $baseDir . '/includes/Connectors/ConnectorProfileRegistry.php'
    300308        ),
    301309        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSettings' => array(
    302                 'version' => '0.4.3.0',
     310                'version' => '0.4.4.0',
    303311                'path'    => $baseDir . '/includes/Connectors/ConnectorSettings.php'
    304312        ),
    305313        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSlugDisplay' => array(
    306                 'version' => '0.4.3.0',
     314                'version' => '0.4.4.0',
    307315                'path'    => $baseDir . '/includes/Connectors/ConnectorSlugDisplay.php'
    308316        ),
     317        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Cleanup' => array(
     318                'version' => '0.4.4.0',
     319                'path'    => $baseDir . '/includes/Database/ActivityLog/Cleanup.php'
     320        ),
     321        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Query' => array(
     322                'version' => '0.4.4.0',
     323                'path'    => $baseDir . '/includes/Database/ActivityLog/Query.php'
     324        ),
     325        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Recorder' => array(
     326                'version' => '0.4.4.0',
     327                'path'    => $baseDir . '/includes/Database/ActivityLog/Recorder.php'
     328        ),
     329        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Row' => array(
     330                'version' => '0.4.4.0',
     331                'path'    => $baseDir . '/includes/Database/ActivityLog/Row.php'
     332        ),
     333        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema' => array(
     334                'version' => '0.4.4.0',
     335                'path'    => $baseDir . '/includes/Database/ActivityLog/Schema.php'
     336        ),
     337        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Table' => array(
     338                'version' => '0.4.4.0',
     339                'path'    => $baseDir . '/includes/Database/ActivityLog/Table.php'
     340        ),
    309341        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Query' => array(
    310                 'version' => '0.4.3.0',
     342                'version' => '0.4.4.0',
    311343                'path'    => $baseDir . '/includes/Database/CliAuthLog/Query.php'
    312344        ),
    313345        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Recorder' => array(
    314                 'version' => '0.4.3.0',
     346                'version' => '0.4.4.0',
    315347                'path'    => $baseDir . '/includes/Database/CliAuthLog/Recorder.php'
    316348        ),
    317349        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Row' => array(
    318                 'version' => '0.4.3.0',
     350                'version' => '0.4.4.0',
    319351                'path'    => $baseDir . '/includes/Database/CliAuthLog/Row.php'
    320352        ),
    321353        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Schema' => array(
    322                 'version' => '0.4.3.0',
     354                'version' => '0.4.4.0',
    323355                'path'    => $baseDir . '/includes/Database/CliAuthLog/Schema.php'
    324356        ),
    325357        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Table' => array(
    326                 'version' => '0.4.3.0',
     358                'version' => '0.4.4.0',
    327359                'path'    => $baseDir . '/includes/Database/CliAuthLog/Table.php'
    328360        ),
    329361        'AcrossAI_MCP_Manager\\Includes\\Database\\ConnectorApprovedUsers\\Query' => array(
    330                 'version' => '0.4.3.0',
     362                'version' => '0.4.4.0',
    331363                'path'    => $baseDir . '/includes/Database/ConnectorApprovedUsers/Query.php'
    332364        ),
    333365        'AcrossAI_MCP_Manager\\Includes\\Database\\ConnectorApprovedUsers\\Row' => array(
    334                 'version' => '0.4.3.0',
     366                'version' => '0.4.4.0',
    335367                'path'    => $baseDir . '/includes/Database/ConnectorApprovedUsers/Row.php'
    336368        ),
    337369        'AcrossAI_MCP_Manager\\Includes\\Database\\ConnectorApprovedUsers\\Schema' => array(
    338                 'version' => '0.4.3.0',
     370                'version' => '0.4.4.0',
    339371                'path'    => $baseDir . '/includes/Database/ConnectorApprovedUsers/Schema.php'
    340372        ),
    341373        'AcrossAI_MCP_Manager\\Includes\\Database\\ConnectorApprovedUsers\\Table' => array(
    342                 'version' => '0.4.3.0',
     374                'version' => '0.4.4.0',
    343375                'path'    => $baseDir . '/includes/Database/ConnectorApprovedUsers/Table.php'
    344376        ),
    345377        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\ExposureResolver' => array(
    346                 'version' => '0.4.3.0',
     378                'version' => '0.4.4.0',
    347379                'path'    => $baseDir . '/includes/Database/MCPServerAbility/ExposureResolver.php'
    348380        ),
    349381        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\Query' => array(
    350                 'version' => '0.4.3.0',
     382                'version' => '0.4.4.0',
    351383                'path'    => $baseDir . '/includes/Database/MCPServerAbility/Query.php'
    352384        ),
    353385        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\Row' => array(
    354                 'version' => '0.4.3.0',
     386                'version' => '0.4.4.0',
    355387                'path'    => $baseDir . '/includes/Database/MCPServerAbility/Row.php'
    356388        ),
    357389        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\Schema' => array(
    358                 'version' => '0.4.3.0',
     390                'version' => '0.4.4.0',
    359391                'path'    => $baseDir . '/includes/Database/MCPServerAbility/Schema.php'
    360392        ),
    361393        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\Table' => array(
    362                 'version' => '0.4.3.0',
     394                'version' => '0.4.4.0',
    363395                'path'    => $baseDir . '/includes/Database/MCPServerAbility/Table.php'
    364396        ),
    365397        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerMeta\\Query' => array(
    366                 'version' => '0.4.3.0',
     398                'version' => '0.4.4.0',
    367399                'path'    => $baseDir . '/includes/Database/MCPServerMeta/Query.php'
    368400        ),
    369401        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerMeta\\Row' => array(
    370                 'version' => '0.4.3.0',
     402                'version' => '0.4.4.0',
    371403                'path'    => $baseDir . '/includes/Database/MCPServerMeta/Row.php'
    372404        ),
    373405        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerMeta\\Schema' => array(
    374                 'version' => '0.4.3.0',
     406                'version' => '0.4.4.0',
    375407                'path'    => $baseDir . '/includes/Database/MCPServerMeta/Schema.php'
    376408        ),
    377409        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerMeta\\Table' => array(
    378                 'version' => '0.4.3.0',
     410                'version' => '0.4.4.0',
    379411                'path'    => $baseDir . '/includes/Database/MCPServerMeta/Table.php'
    380412        ),
    381413        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerTool\\Query' => array(
    382                 'version' => '0.4.3.0',
     414                'version' => '0.4.4.0',
    383415                'path'    => $baseDir . '/includes/Database/MCPServerTool/Query.php'
    384416        ),
    385417        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerTool\\Row' => array(
    386                 'version' => '0.4.3.0',
     418                'version' => '0.4.4.0',
    387419                'path'    => $baseDir . '/includes/Database/MCPServerTool/Row.php'
    388420        ),
    389421        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerTool\\Schema' => array(
    390                 'version' => '0.4.3.0',
     422                'version' => '0.4.4.0',
    391423                'path'    => $baseDir . '/includes/Database/MCPServerTool/Schema.php'
    392424        ),
    393425        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerTool\\Table' => array(
    394                 'version' => '0.4.3.0',
     426                'version' => '0.4.4.0',
    395427                'path'    => $baseDir . '/includes/Database/MCPServerTool/Table.php'
    396428        ),
    397429        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\AbilityDiscovery' => array(
    398                 'version' => '0.4.3.0',
     430                'version' => '0.4.4.0',
    399431                'path'    => $baseDir . '/includes/Database/MCPServer/AbilityDiscovery.php'
    400432        ),
    401433        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\CreatedColumnBackfill' => array(
    402                 'version' => '0.4.3.0',
     434                'version' => '0.4.4.0',
    403435                'path'    => $baseDir . '/includes/Database/MCPServer/CreatedColumnBackfill.php'
    404436        ),
    405437        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\CuratedToolWriter' => array(
    406                 'version' => '0.4.3.0',
     438                'version' => '0.4.4.0',
    407439                'path'    => $baseDir . '/includes/Database/MCPServer/CuratedToolWriter.php'
    408440        ),
    409441        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\DefaultServerSeeder' => array(
    410                 'version' => '0.4.3.0',
     442                'version' => '0.4.4.0',
    411443                'path'    => $baseDir . '/includes/Database/MCPServer/DefaultServerSeeder.php'
    412444        ),
    413445        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\PolicyTransition' => array(
    414                 'version' => '0.4.3.0',
     446                'version' => '0.4.4.0',
    415447                'path'    => $baseDir . '/includes/Database/MCPServer/PolicyTransition.php'
    416448        ),
    417449        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ProtectedServers' => array(
    418                 'version' => '0.4.3.0',
     450                'version' => '0.4.4.0',
    419451                'path'    => $baseDir . '/includes/Database/MCPServer/ProtectedServers.php'
    420452        ),
    421453        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\Query' => array(
    422                 'version' => '0.4.3.0',
     454                'version' => '0.4.4.0',
    423455                'path'    => $baseDir . '/includes/Database/MCPServer/Query.php'
    424456        ),
    425457        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\Row' => array(
    426                 'version' => '0.4.3.0',
     458                'version' => '0.4.4.0',
    427459                'path'    => $baseDir . '/includes/Database/MCPServer/Row.php'
    428460        ),
    429461        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\Schema' => array(
    430                 'version' => '0.4.3.0',
     462                'version' => '0.4.4.0',
    431463                'path'    => $baseDir . '/includes/Database/MCPServer/Schema.php'
    432464        ),
    433465        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\SeededToolsBackfill' => array(
    434                 'version' => '0.4.3.0',
     466                'version' => '0.4.4.0',
    435467                'path'    => $baseDir . '/includes/Database/MCPServer/SeededToolsBackfill.php'
    436468        ),
    437469        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ServerEnablement' => array(
    438                 'version' => '0.4.3.0',
     470                'version' => '0.4.4.0',
    439471                'path'    => $baseDir . '/includes/Database/MCPServer/ServerEnablement.php'
    440472        ),
    441473        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ServerGuideBackfill' => array(
    442                 'version' => '0.4.3.0',
     474                'version' => '0.4.4.0',
    443475                'path'    => $baseDir . '/includes/Database/MCPServer/ServerGuideBackfill.php'
    444476        ),
    445477        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ServerTypes' => array(
    446                 'version' => '0.4.3.0',
     478                'version' => '0.4.4.0',
    447479                'path'    => $baseDir . '/includes/Database/MCPServer/ServerTypes.php'
    448480        ),
    449481        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\Table' => array(
    450                 'version' => '0.4.3.0',
     482                'version' => '0.4.4.0',
    451483                'path'    => $baseDir . '/includes/Database/MCPServer/Table.php'
    452484        ),
    453485        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ToolPolicy' => array(
    454                 'version' => '0.4.3.0',
     486                'version' => '0.4.4.0',
    455487                'path'    => $baseDir . '/includes/Database/MCPServer/ToolPolicy.php'
    456488        ),
    457489        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthAuthCodes\\Query' => array(
    458                 'version' => '0.4.3.0',
     490                'version' => '0.4.4.0',
    459491                'path'    => $baseDir . '/includes/Database/OAuthAuthCodes/Query.php'
    460492        ),
    461493        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthAuthCodes\\Row' => array(
    462                 'version' => '0.4.3.0',
     494                'version' => '0.4.4.0',
    463495                'path'    => $baseDir . '/includes/Database/OAuthAuthCodes/Row.php'
    464496        ),
    465497        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthAuthCodes\\Schema' => array(
    466                 'version' => '0.4.3.0',
     498                'version' => '0.4.4.0',
    467499                'path'    => $baseDir . '/includes/Database/OAuthAuthCodes/Schema.php'
    468500        ),
    469501        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthAuthCodes\\Table' => array(
    470                 'version' => '0.4.3.0',
     502                'version' => '0.4.4.0',
    471503                'path'    => $baseDir . '/includes/Database/OAuthAuthCodes/Table.php'
    472504        ),
    473505        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthClients\\Query' => array(
    474                 'version' => '0.4.3.0',
     506                'version' => '0.4.4.0',
    475507                'path'    => $baseDir . '/includes/Database/OAuthClients/Query.php'
    476508        ),
    477509        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthClients\\Row' => array(
    478                 'version' => '0.4.3.0',
     510                'version' => '0.4.4.0',
    479511                'path'    => $baseDir . '/includes/Database/OAuthClients/Row.php'
    480512        ),
    481513        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthClients\\Schema' => array(
    482                 'version' => '0.4.3.0',
     514                'version' => '0.4.4.0',
    483515                'path'    => $baseDir . '/includes/Database/OAuthClients/Schema.php'
    484516        ),
    485517        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthClients\\Table' => array(
    486                 'version' => '0.4.3.0',
     518                'version' => '0.4.4.0',
    487519                'path'    => $baseDir . '/includes/Database/OAuthClients/Table.php'
    488520        ),
    489521        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthDataMigration' => array(
    490                 'version' => '0.4.3.0',
     522                'version' => '0.4.4.0',
    491523                'path'    => $baseDir . '/includes/Database/OAuthDataMigration.php'
    492524        ),
    493525        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthTokens\\Query' => array(
    494                 'version' => '0.4.3.0',
     526                'version' => '0.4.4.0',
    495527                'path'    => $baseDir . '/includes/Database/OAuthTokens/Query.php'
    496528        ),
    497529        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthTokens\\Row' => array(
    498                 'version' => '0.4.3.0',
     530                'version' => '0.4.4.0',
    499531                'path'    => $baseDir . '/includes/Database/OAuthTokens/Row.php'
    500532        ),
    501533        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthTokens\\Schema' => array(
    502                 'version' => '0.4.3.0',
     534                'version' => '0.4.4.0',
    503535                'path'    => $baseDir . '/includes/Database/OAuthTokens/Schema.php'
    504536        ),
    505537        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthTokens\\Table' => array(
    506                 'version' => '0.4.3.0',
     538                'version' => '0.4.4.0',
    507539                'path'    => $baseDir . '/includes/Database/OAuthTokens/Table.php'
    508540        ),
    509541        'AcrossAI_MCP_Manager\\Includes\\Database\\SchemaReconciler' => array(
    510                 'version' => '0.4.3.0',
     542                'version' => '0.4.4.0',
    511543                'path'    => $baseDir . '/includes/Database/SchemaReconciler.php'
    512544        ),
    513545        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\DatetimeColumn' => array(
    514                 'version' => '0.4.3.0',
     546                'version' => '0.4.4.0',
    515547                'path'    => $baseDir . '/includes/Database/Support/DatetimeColumn.php'
    516548        ),
     549        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\SchemaFailureHealthCheck' => array(
     550                'version' => '0.4.4.0',
     551                'path'    => $baseDir . '/includes/Database/Support/SchemaFailureHealthCheck.php'
     552        ),
    517553        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\TimezoneHealthCheck' => array(
    518                 'version' => '0.4.3.0',
     554                'version' => '0.4.4.0',
    519555                'path'    => $baseDir . '/includes/Database/Support/TimezoneHealthCheck.php'
    520556        ),
    521557        'AcrossAI_MCP_Manager\\Includes\\Deactivator' => array(
    522                 'version' => '0.4.3.0',
     558                'version' => '0.4.4.0',
    523559                'path'    => $baseDir . '/includes/Deactivator.php'
    524560        ),
    525561        'AcrossAI_MCP_Manager\\Includes\\Discovery\\DiscoveryConnectorAdapter' => array(
    526                 'version' => '0.4.3.0',
     562                'version' => '0.4.4.0',
    527563                'path'    => $baseDir . '/includes/Discovery/DiscoveryConnectorAdapter.php'
    528564        ),
    529565        'AcrossAI_MCP_Manager\\Includes\\Embeds\\AbstractEmbedTransport' => array(
    530                 'version' => '0.4.3.0',
     566                'version' => '0.4.4.0',
    531567                'path'    => $baseDir . '/includes/Embeds/AbstractEmbedTransport.php'
    532568        ),
    533569        'AcrossAI_MCP_Manager\\Includes\\Embeds\\AiConnectorEmbedTransport' => array(
    534                 'version' => '0.4.3.0',
     570                'version' => '0.4.4.0',
    535571                'path'    => $baseDir . '/includes/Embeds/AiConnectorEmbedTransport.php'
    536572        ),
    537573        'AcrossAI_MCP_Manager\\Includes\\Embeds\\ClientEmbedTransport' => array(
    538                 'version' => '0.4.3.0',
     574                'version' => '0.4.4.0',
    539575                'path'    => $baseDir . '/includes/Embeds/ClientEmbedTransport.php'
    540576        ),
    541577        'AcrossAI_MCP_Manager\\Includes\\Embeds\\NpmEmbedTransport' => array(
    542                 'version' => '0.4.3.0',
     578                'version' => '0.4.4.0',
    543579                'path'    => $baseDir . '/includes/Embeds/NpmEmbedTransport.php'
    544580        ),
    545581        'AcrossAI_MCP_Manager\\Includes\\I18n' => array(
    546                 'version' => '0.4.3.0',
     582                'version' => '0.4.4.0',
    547583                'path'    => $baseDir . '/includes/I18n.php'
    548584        ),
    549585        'AcrossAI_MCP_Manager\\Includes\\Loader' => array(
    550                 'version' => '0.4.3.0',
     586                'version' => '0.4.4.0',
    551587                'path'    => $baseDir . '/includes/Loader.php'
    552588        ),
    553589        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\AbstractMCPClient' => array(
    554                 'version' => '0.4.3.0',
     590                'version' => '0.4.4.0',
    555591                'path'    => $baseDir . '/includes/MCPClients/AbstractMCPClient.php'
    556592        ),
    557593        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\AmazonQClient' => array(
    558                 'version' => '0.4.3.0',
     594                'version' => '0.4.4.0',
    559595                'path'    => $baseDir . '/includes/MCPClients/AmazonQClient.php'
    560596        ),
    561597        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\AntigravityClient' => array(
    562                 'version' => '0.4.3.0',
     598                'version' => '0.4.4.0',
    563599                'path'    => $baseDir . '/includes/MCPClients/AntigravityClient.php'
    564600        ),
    565601        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\ClaudeCodeClient' => array(
    566                 'version' => '0.4.3.0',
     602                'version' => '0.4.4.0',
    567603                'path'    => $baseDir . '/includes/MCPClients/ClaudeCodeClient.php'
    568604        ),
    569605        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\ClaudeDesktopClient' => array(
    570                 'version' => '0.4.3.0',
     606                'version' => '0.4.4.0',
    571607                'path'    => $baseDir . '/includes/MCPClients/ClaudeDesktopClient.php'
    572608        ),
    573609        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\ClineClient' => array(
    574                 'version' => '0.4.3.0',
     610                'version' => '0.4.4.0',
    575611                'path'    => $baseDir . '/includes/MCPClients/ClineClient.php'
    576612        ),
    577613        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\CodexClient' => array(
    578                 'version' => '0.4.3.0',
     614                'version' => '0.4.4.0',
    579615                'path'    => $baseDir . '/includes/MCPClients/CodexClient.php'
    580616        ),
    581617        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\CursorClient' => array(
    582                 'version' => '0.4.3.0',
     618                'version' => '0.4.4.0',
    583619                'path'    => $baseDir . '/includes/MCPClients/CursorClient.php'
    584620        ),
    585621        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\CustomClient' => array(
    586                 'version' => '0.4.3.0',
     622                'version' => '0.4.4.0',
    587623                'path'    => $baseDir . '/includes/MCPClients/CustomClient.php'
    588624        ),
    589625        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\GeminiClient' => array(
    590                 'version' => '0.4.3.0',
     626                'version' => '0.4.4.0',
    591627                'path'    => $baseDir . '/includes/MCPClients/GeminiClient.php'
    592628        ),
    593629        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\GitHubCopilotClient' => array(
    594                 'version' => '0.4.3.0',
     630                'version' => '0.4.4.0',
    595631                'path'    => $baseDir . '/includes/MCPClients/GitHubCopilotClient.php'
    596632        ),
    597633        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\KiloCodeClient' => array(
    598                 'version' => '0.4.3.0',
     634                'version' => '0.4.4.0',
    599635                'path'    => $baseDir . '/includes/MCPClients/KiloCodeClient.php'
    600636        ),
    601637        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\OpenCodeClient' => array(
    602                 'version' => '0.4.3.0',
     638                'version' => '0.4.4.0',
    603639                'path'    => $baseDir . '/includes/MCPClients/OpenCodeClient.php'
    604640        ),
    605641        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\RooCodeClient' => array(
    606                 'version' => '0.4.3.0',
     642                'version' => '0.4.4.0',
    607643                'path'    => $baseDir . '/includes/MCPClients/RooCodeClient.php'
    608644        ),
    609645        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\VSCodeClient' => array(
    610                 'version' => '0.4.3.0',
     646                'version' => '0.4.4.0',
    611647                'path'    => $baseDir . '/includes/MCPClients/VSCodeClient.php'
    612648        ),
    613649        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\WindsurfClient' => array(
    614                 'version' => '0.4.3.0',
     650                'version' => '0.4.4.0',
    615651                'path'    => $baseDir . '/includes/MCPClients/WindsurfClient.php'
    616652        ),
    617653        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\ZedClient' => array(
    618                 'version' => '0.4.3.0',
     654                'version' => '0.4.4.0',
    619655                'path'    => $baseDir . '/includes/MCPClients/ZedClient.php'
    620656        ),
    621657        'AcrossAI_MCP_Manager\\Includes\\MCP\\AbilityExposureGate' => array(
    622                 'version' => '0.4.3.0',
     658                'version' => '0.4.4.0',
    623659                'path'    => $baseDir . '/includes/MCP/AbilityExposureGate.php'
    624660        ),
    625661        'AcrossAI_MCP_Manager\\Includes\\MCP\\Controller' => array(
    626                 'version' => '0.4.3.0',
     662                'version' => '0.4.4.0',
    627663                'path'    => $baseDir . '/includes/MCP/Controller.php'
    628664        ),
    629665        'AcrossAI_MCP_Manager\\Includes\\MCP\\ToolExposureGate' => array(
    630                 'version' => '0.4.3.0',
     666                'version' => '0.4.4.0',
    631667                'path'    => $baseDir . '/includes/MCP/ToolExposureGate.php'
    632668        ),
    633669        'AcrossAI_MCP_Manager\\Includes\\Main' => array(
    634                 'version' => '0.4.3.0',
     670                'version' => '0.4.4.0',
    635671                'path'    => $baseDir . '/includes/Main.php'
    636672        ),
    637673        'AcrossAI_MCP_Manager\\Includes\\OAuth\\AuthorizationController' => array(
    638                 'version' => '0.4.3.0',
     674                'version' => '0.4.4.0',
    639675                'path'    => $baseDir . '/includes/OAuth/AuthorizationController.php'
    640676        ),
    641677        'AcrossAI_MCP_Manager\\Includes\\OAuth\\BearerChallengeHeader' => array(
    642                 'version' => '0.4.3.0',
     678                'version' => '0.4.4.0',
    643679                'path'    => $baseDir . '/includes/OAuth/BearerChallengeHeader.php'
    644680        ),
    645681        'AcrossAI_MCP_Manager\\Includes\\OAuth\\CimdRegistry' => array(
    646                 'version' => '0.4.3.0',
     682                'version' => '0.4.4.0',
    647683                'path'    => $baseDir . '/includes/OAuth/CimdRegistry.php'
    648684        ),
    649685        'AcrossAI_MCP_Manager\\Includes\\OAuth\\CimdResolver' => array(
    650                 'version' => '0.4.3.0',
     686                'version' => '0.4.4.0',
    651687                'path'    => $baseDir . '/includes/OAuth/CimdResolver.php'
    652688        ),
    653689        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Cleanup' => array(
    654                 'version' => '0.4.3.0',
     690                'version' => '0.4.4.0',
    655691                'path'    => $baseDir . '/includes/OAuth/Cleanup.php'
    656692        ),
    657693        'AcrossAI_MCP_Manager\\Includes\\OAuth\\ClientRegistrationController' => array(
    658                 'version' => '0.4.3.0',
     694                'version' => '0.4.4.0',
    659695                'path'    => $baseDir . '/includes/OAuth/ClientRegistrationController.php'
    660696        ),
    661697        'AcrossAI_MCP_Manager\\Includes\\OAuth\\ConnectorAdminController' => array(
    662                 'version' => '0.4.3.0',
     698                'version' => '0.4.4.0',
    663699                'path'    => $baseDir . '/includes/OAuth/ConnectorAdminController.php'
    664700        ),
    665701        'AcrossAI_MCP_Manager\\Includes\\OAuth\\DiscoveryConflictGuard' => array(
    666                 'version' => '0.4.3.0',
     702                'version' => '0.4.4.0',
    667703                'path'    => $baseDir . '/includes/OAuth/DiscoveryConflictGuard.php'
    668704        ),
    669705        'AcrossAI_MCP_Manager\\Includes\\OAuth\\DiscoveryController' => array(
    670                 'version' => '0.4.3.0',
     706                'version' => '0.4.4.0',
    671707                'path'    => $baseDir . '/includes/OAuth/DiscoveryController.php'
    672708        ),
    673709        'AcrossAI_MCP_Manager\\Includes\\OAuth\\DiscoveryHealthCheck' => array(
    674                 'version' => '0.4.3.0',
     710                'version' => '0.4.4.0',
    675711                'path'    => $baseDir . '/includes/OAuth/DiscoveryHealthCheck.php'
    676712        ),
    677713        'AcrossAI_MCP_Manager\\Includes\\OAuth\\MessagePage' => array(
    678                 'version' => '0.4.3.0',
     714                'version' => '0.4.4.0',
    679715                'path'    => $baseDir . '/includes/OAuth/MessagePage.php'
    680716        ),
    681717        'AcrossAI_MCP_Manager\\Includes\\OAuth\\OAuthRouter' => array(
    682                 'version' => '0.4.3.0',
     718                'version' => '0.4.4.0',
    683719                'path'    => $baseDir . '/includes/OAuth/OAuthRouter.php'
    684720        ),
    685721        'AcrossAI_MCP_Manager\\Includes\\OAuth\\PKCE' => array(
    686                 'version' => '0.4.3.0',
     722                'version' => '0.4.4.0',
    687723                'path'    => $baseDir . '/includes/OAuth/PKCE.php'
    688724        ),
    689725        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\AccessTokenRepository' => array(
    690                 'version' => '0.4.3.0',
     726                'version' => '0.4.4.0',
    691727                'path'    => $baseDir . '/includes/OAuth/Repositories/AccessTokenRepository.php'
    692728        ),
    693729        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\AuthCodeRepository' => array(
    694                 'version' => '0.4.3.0',
     730                'version' => '0.4.4.0',
    695731                'path'    => $baseDir . '/includes/OAuth/Repositories/AuthCodeRepository.php'
    696732        ),
    697733        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\ClientRepository' => array(
    698                 'version' => '0.4.3.0',
     734                'version' => '0.4.4.0',
    699735                'path'    => $baseDir . '/includes/OAuth/Repositories/ClientRepository.php'
    700736        ),
    701737        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\RefreshTokenRepository' => array(
    702                 'version' => '0.4.3.0',
     738                'version' => '0.4.4.0',
    703739                'path'    => $baseDir . '/includes/OAuth/Repositories/RefreshTokenRepository.php'
    704740        ),
    705741        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\ScopeRepository' => array(
    706                 'version' => '0.4.3.0',
     742                'version' => '0.4.4.0',
    707743                'path'    => $baseDir . '/includes/OAuth/Repositories/ScopeRepository.php'
    708744        ),
    709745        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Security\\RateLimiter' => array(
    710                 'version' => '0.4.3.0',
     746                'version' => '0.4.4.0',
    711747                'path'    => $baseDir . '/includes/OAuth/Security/RateLimiter.php'
    712748        ),
    713749        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Security\\SecretsVault' => array(
    714                 'version' => '0.4.3.0',
     750                'version' => '0.4.4.0',
    715751                'path'    => $baseDir . '/includes/OAuth/Security/SecretsVault.php'
    716752        ),
    717753        'AcrossAI_MCP_Manager\\Includes\\OAuth\\TokenController' => array(
    718                 'version' => '0.4.3.0',
     754                'version' => '0.4.4.0',
    719755                'path'    => $baseDir . '/includes/OAuth/TokenController.php'
    720756        ),
    721757        'AcrossAI_MCP_Manager\\Includes\\OAuth\\TokenValidator' => array(
    722                 'version' => '0.4.3.0',
     758                'version' => '0.4.4.0',
    723759                'path'    => $baseDir . '/includes/OAuth/TokenValidator.php'
    724760        ),
    725761        'AcrossAI_MCP_Manager\\Includes\\OAuth\\UserLifecycle' => array(
    726                 'version' => '0.4.3.0',
     762                'version' => '0.4.4.0',
    727763                'path'    => $baseDir . '/includes/OAuth/UserLifecycle.php'
    728764        ),
     765        'AcrossAI_MCP_Manager\\Includes\\Observability\\ActivityObservabilityHandler' => array(
     766                'version' => '0.4.4.0',
     767                'path'    => $baseDir . '/includes/Observability/ActivityObservabilityHandler.php'
     768        ),
     769        'AcrossAI_MCP_Manager\\Includes\\Observability\\AuthContextHolder' => array(
     770                'version' => '0.4.4.0',
     771                'path'    => $baseDir . '/includes/Observability/AuthContextHolder.php'
     772        ),
     773        'AcrossAI_MCP_Manager\\Includes\\Observability\\CaptureContext' => array(
     774                'version' => '0.4.4.0',
     775                'path'    => $baseDir . '/includes/Observability/CaptureContext.php'
     776        ),
     777        'AcrossAI_MCP_Manager\\Includes\\Observability\\ConnectionContext' => array(
     778                'version' => '0.4.4.0',
     779                'path'    => $baseDir . '/includes/Observability/ConnectionContext.php'
     780        ),
     781        'AcrossAI_MCP_Manager\\Includes\\Observability\\HandlerResolver' => array(
     782                'version' => '0.4.4.0',
     783                'path'    => $baseDir . '/includes/Observability/HandlerResolver.php'
     784        ),
     785        'AcrossAI_MCP_Manager\\Includes\\Observability\\PersonalData' => array(
     786                'version' => '0.4.4.0',
     787                'path'    => $baseDir . '/includes/Observability/PersonalData.php'
     788        ),
     789        'AcrossAI_MCP_Manager\\Includes\\Observability\\RecordingHealthCheck' => array(
     790                'version' => '0.4.4.0',
     791                'path'    => $baseDir . '/includes/Observability/RecordingHealthCheck.php'
     792        ),
     793        'AcrossAI_MCP_Manager\\Includes\\Observability\\ResponseSizeProbe' => array(
     794                'version' => '0.4.4.0',
     795                'path'    => $baseDir . '/includes/Observability/ResponseSizeProbe.php'
     796        ),
    729797        'AcrossAI_MCP_Manager\\Includes\\REST\\AbilitiesController' => array(
    730                 'version' => '0.4.3.0',
     798                'version' => '0.4.4.0',
    731799                'path'    => $baseDir . '/includes/REST/AbilitiesController.php'
    732800        ),
     801        'AcrossAI_MCP_Manager\\Includes\\REST\\ActivityLogController' => array(
     802                'version' => '0.4.4.0',
     803                'path'    => $baseDir . '/includes/REST/ActivityLogController.php'
     804        ),
    733805        'AcrossAI_MCP_Manager\\Includes\\REST\\CliController' => array(
    734                 'version' => '0.4.3.0',
     806                'version' => '0.4.4.0',
    735807                'path'    => $baseDir . '/includes/REST/CliController.php'
    736808        ),
    737809        'AcrossAI_MCP_Manager\\Includes\\REST\\ClientRendererController' => array(
    738                 'version' => '0.4.3.0',
     810                'version' => '0.4.4.0',
    739811                'path'    => $baseDir . '/includes/REST/ClientRendererController.php'
    740812        ),
    741813        'AcrossAI_MCP_Manager\\Includes\\REST\\QuickConnectController' => array(
    742                 'version' => '0.4.3.0',
     814                'version' => '0.4.4.0',
    743815                'path'    => $baseDir . '/includes/REST/QuickConnectController.php'
    744816        ),
    745817        'AcrossAI_MCP_Manager\\Includes\\REST\\ToolsController' => array(
    746                 'version' => '0.4.3.0',
     818                'version' => '0.4.4.0',
    747819                'path'    => $baseDir . '/includes/REST/ToolsController.php'
    748820        ),
     821        'AcrossAI_MCP_Manager\\Includes\\Utilities\\ActivityLogConstants' => array(
     822                'version' => '0.4.4.0',
     823                'path'    => $baseDir . '/includes/Utilities/ActivityLogConstants.php'
     824        ),
    749825        'AcrossAI_MCP_Manager\\Includes\\Utilities\\AdminPageSlugs' => array(
    750                 'version' => '0.4.3.0',
     826                'version' => '0.4.4.0',
    751827                'path'    => $baseDir . '/includes/Utilities/AdminPageSlugs.php'
    752828        ),
    753829        'AcrossAI_MCP_Manager\\Includes\\Utilities\\CacheHeaders' => array(
    754                 'version' => '0.4.3.0',
     830                'version' => '0.4.4.0',
    755831                'path'    => $baseDir . '/includes/Utilities/CacheHeaders.php'
    756832        ),
    757833        'AcrossAI_MCP_Manager\\Includes\\Utilities\\LocalEnvironment' => array(
    758                 'version' => '0.4.3.0',
     834                'version' => '0.4.4.0',
    759835                'path'    => $baseDir . '/includes/Utilities/LocalEnvironment.php'
    760836        ),
    761837        'AcrossAI_MCP_Manager\\Includes\\Utilities\\MCPServerFieldSanitizer' => array(
    762                 'version' => '0.4.3.0',
     838                'version' => '0.4.4.0',
    763839                'path'    => $baseDir . '/includes/Utilities/MCPServerFieldSanitizer.php'
    764840        ),
    765841        'AcrossAI_MCP_Manager\\Includes\\Utilities\\RegistryEntryNormalizer' => array(
    766                 'version' => '0.4.3.0',
     842                'version' => '0.4.4.0',
    767843                'path'    => $baseDir . '/includes/Utilities/RegistryEntryNormalizer.php'
    768844        ),
    769845        'AcrossAI_MCP_Manager\\Includes\\Utilities\\SiteSlug' => array(
    770                 'version' => '0.4.3.0',
     846                'version' => '0.4.4.0',
    771847                'path'    => $baseDir . '/includes/Utilities/SiteSlug.php'
    772848        ),
    773849        'AcrossAI_MCP_Manager\\Public\\Discovery\\ConnectionMethodRegistry' => array(
    774                 'version' => '0.4.3.0',
     850                'version' => '0.4.4.0',
    775851                'path'    => $baseDir . '/public/Discovery/ConnectionMethodRegistry.php'
    776852        ),
    777853        'AcrossAI_MCP_Manager\\Public\\Partials\\FrontendAuth' => array(
    778                 'version' => '0.4.3.0',
     854                'version' => '0.4.4.0',
    779855                'path'    => $baseDir . '/public/Partials/FrontendAuth.php'
    780856        ),
    781857        'AcrossAI_MCP_Manager\\Public\\Renderers\\AbstractClientRenderer' => array(
    782                 'version' => '0.4.3.0',
     858                'version' => '0.4.4.0',
    783859                'path'    => $baseDir . '/public/Renderers/AbstractClientRenderer.php'
    784860        ),
    785861        'AcrossAI_MCP_Manager\\Public\\Renderers\\AccessControlBlock' => array(
    786                 'version' => '0.4.3.0',
     862                'version' => '0.4.4.0',
    787863                'path'    => $baseDir . '/public/Renderers/AccessControlBlock.php'
    788864        ),
    789865        'AcrossAI_MCP_Manager\\Public\\Renderers\\EmbedBlock\\EmbedBlockRenderer' => array(
    790                 'version' => '0.4.3.0',
     866                'version' => '0.4.4.0',
    791867                'path'    => $baseDir . '/public/Renderers/EmbedBlock/EmbedBlockRenderer.php'
    792868        ),
    793869        'AcrossAI_MCP_Manager\\Public\\Renderers\\MCPClientsBlock' => array(
    794                 'version' => '0.4.3.0',
     870                'version' => '0.4.4.0',
    795871                'path'    => $baseDir . '/public/Renderers/MCPClientsBlock.php'
    796872        ),
    797873        'AcrossAI_MCP_Manager\\Public\\Renderers\\NpmClientBlock' => array(
    798                 'version' => '0.4.3.0',
     874                'version' => '0.4.4.0',
    799875                'path'    => $baseDir . '/public/Renderers/NpmClientBlock.php'
    800876        ),
    801877        'AcrossAI_MCP_Manager\\Public\\Renderers\\UserServers\\AbstractUserServersRenderer' => array(
    802                 'version' => '0.4.3.0',
     878                'version' => '0.4.4.0',
    803879                'path'    => $baseDir . '/public/Renderers/UserServers/AbstractUserServersRenderer.php'
    804880        ),
    805881        'AcrossAI_MCP_Manager\\Public\\Renderers\\UserServers\\UserServersBlock' => array(
    806                 'version' => '0.4.3.0',
     882                'version' => '0.4.4.0',
    807883                'path'    => $baseDir . '/public/Renderers/UserServers/UserServersBlock.php'
    808884        ),
  • acrossai-mcp-manager/trunk/acrossai-mcp-manager.php

    r3734601 r3766841  
    2424 * Plugin URI: https://acrossai.co/mcp-manager/
    2525 * Description: WordPress MCP server and admin for MCP Adapter: multiple servers, access control and one-click connectors for Claude, ChatGPT, Gemini, Grok and Cursor.
    26  * Version: 0.4.3
     26 * Version: 0.4.4
    2727 * Requires at least: 6.9
    2828 * Requires PHP: 8.1
  • acrossai-mcp-manager/trunk/admin/Partials/MCPServerListTable.php

    r3720416 r3766841  
    404404                        '<a href="%s" class="acrossai-quicklink"><span class="dashicons dashicons-admin-tools" aria-hidden="true"></span><span class="acrossai-quicklink-label">%s</span></a>',
    405405                        esc_url( $quick_connect_url ),
    406                         esc_html__( 'Quick Connect via AcrossAI', 'acrossai-mcp-manager' )
     406                        esc_html__( 'Connect via AcrossAI', 'acrossai-mcp-manager' )
    407407                );
    408408
  • acrossai-mcp-manager/trunk/admin/Partials/Menu.php

    r3702733 r3766841  
    9292                );
    9393
    94                 // 2) Quick Connect via AcrossAI — position 3, right after MCP (F072 FR-003).
     94                // 2) Connect via AcrossAI — position 3, right after MCP (F072 FR-003).
    9595                // URL-literal menu_slug + empty render callback = WP renders this
    9696                // submenu item as a direct link to the wizard URL; no dedicated
    … …  
    103103                        // tail is redundant. Every other surface (plugins.php action
    104104                        // link, servers-list button, per-row pill, Settings sub-nav,
    105                         // admin-bar chip) keeps the full "Quick Connect via AcrossAI"
     105                        // admin-bar chip) keeps the full "Connect via AcrossAI"
    106106                        // so the wizard is discoverable outside the sidebar too.
    107                         __( 'Quick Connect', 'acrossai-mcp-manager' ),
    108                         __( 'Quick Connect', 'acrossai-mcp-manager' ),
     107                        __( 'Connect', 'acrossai-mcp-manager' ),
     108                        __( 'Connect', 'acrossai-mcp-manager' ),
    109109                        'manage_options',
    110110                        'admin.php?page=' . AdminPageSlugs::PARENT . '&quick-connect=1&step=1',
    … …  
    146146                        '<a href="%s">%s</a>',
    147147                        $quick_connect_url,
    148                         esc_html__( 'Quick Connect via AcrossAI', 'acrossai-mcp-manager' )
     148                        esc_html__( 'Connect via AcrossAI', 'acrossai-mcp-manager' )
    149149                );
    150150
    151                 // Prepend Quick Connect via AcrossAI first, then Settings, so the final row order
    152                 // reads Settings | Quick Connect via AcrossAI | Deactivate | Download (F072 FR-002).
     151                // Prepend Connect via AcrossAI first, then Settings, so the final row order
     152                // reads Settings | Connect via AcrossAI | Deactivate | Download (F072 FR-002).
    153153                array_unshift( $links, $quick_connect_link );
    154154                array_unshift( $links, $settings_link );
  • acrossai-mcp-manager/trunk/admin/Partials/Notices.php

    r3734601 r3766841  
    276276                                'id'      => 'acrossai_mcp_manager_firefox_tracking_protection',
    277277                                'title'   => __( 'Firefox tracking protection can block AI assistants from connecting', 'acrossai-mcp-manager' ),
    278                                 'message' => __( "You are viewing this page in Firefox. Its <strong>Enhanced Tracking Protection</strong> can stop an AI assistant part-way through connecting to this site — the connector is added, sign-in opens, and then nothing completes, usually with no error to explain it.<br><br>If a connection fails: click the <strong>shield icon</strong> to the left of the address bar, then switch <strong>Enhanced Tracking Protection</strong> off for this site and connect again. Firefox remembers the choice per site and it does not affect any other site you visit. You can switch it back on afterwards — the protection only interferes while the connection is being set up, not once it is working.", 'acrossai-mcp-manager' ),
     278                                'message' => __( 'You are viewing this page in Firefox. Its <strong>Enhanced Tracking Protection</strong> can stop an AI assistant part-way through connecting to this site — the connector is added, sign-in opens, and then nothing completes, usually with no error to explain it.<br><br>If a connection fails: click the <strong>shield icon</strong> to the left of the address bar, then switch <strong>Enhanced Tracking Protection</strong> off for this site and connect again. Firefox remembers the choice per site and it does not affect any other site you visit. You can switch it back on afterwards — the protection only interferes while the connection is being set up, not once it is working.', 'acrossai-mcp-manager' ),
    279279                                'type'    => 'info',
    280280                                'source'  => __( 'Connectors/Integrations', 'acrossai-mcp-manager' ),
  • acrossai-mcp-manager/trunk/admin/Partials/QuickConnect/AdminBarEntry.php

    r3673028 r3766841  
    11<?php
    22/**
    3  * AdminBarEntry — persistent "Quick Connect via AcrossAI" chip in the admin bar.
     3 * AdminBarEntry — persistent "Connect via AcrossAI" chip in the admin bar.
    44 *
    55 * Feature 069 T044 (US2) — Provides a one-click entry point to the wizard
    … …  
    2222
    2323/**
    24  * Registers the "Quick Connect via AcrossAI" node on the wp-admin toolbar.
     24 * Registers the "Connect via AcrossAI" node on the wp-admin toolbar.
    2525 *
    2626 * @since 0.2.11
    … …  
    8282                                'id'    => self::NODE_ID,
    8383                                'title' => '<span class="ab-icon dashicons dashicons-admin-tools" style="top:3px;"></span>'
    84                                         . esc_html__( 'Quick Connect via AcrossAI', 'acrossai-mcp-manager' ),
     84                                        . esc_html__( 'Connect via AcrossAI', 'acrossai-mcp-manager' ),
    8585                                'href'  => esc_url( admin_url( 'admin.php?page=acrossai_mcp_manager&quick-connect=1&step=1' ) ),
    8686                                'meta'  => array(
  • acrossai-mcp-manager/trunk/admin/Partials/QuickConnect/QuickConnectPage.php

    r3673028 r3766841  
    6969                echo '<noscript><p>';
    7070                echo esc_html__(
    71                         'The Quick Connect via AcrossAI wizard requires JavaScript. Enable JavaScript in your browser to use it.',
     71                        'The Connect via AcrossAI wizard requires JavaScript. Enable JavaScript in your browser to use it.',
    7272                        'acrossai-mcp-manager'
    7373                );
  • acrossai-mcp-manager/trunk/admin/Partials/ServerTabs/McpTrackerTab.php

    r3634312 r3766841  
    1414namespace AcrossAI_MCP_Manager\Admin\Partials\ServerTabs;
    1515
     16use AcrossAI_MCP_Manager\Admin\Partials\ActivityLogPage;
     17
    1618// Exit if accessed directly.
    1719defined( 'ABSPATH' ) || exit;
    … …  
    2628final class McpTrackerTab extends AbstractServerTab {
    2729
    28         /**
    29          * WordPress.org plugin page URL for the "Get MCP Tracker" call to action.
    30          *
    31          * @since 0.0.6
    32          * @var string
    33          */
    34         private const WPORG_URL = 'https://wordpress.org/plugins/mcp-tracker/';
    3530
    3631        /**
    … …  
    7671         */
    7772        protected function render_body( array $server ): void {
     73                $server_id   = isset( $server['id'] ) ? (int) $server['id'] : 0;
    7874                $server_slug = ! empty( $server['server_slug'] )
    7975                        ? (string) $server['server_slug']
    8076                        : sanitize_title( (string) $server['server_name'] );
    8177
    82                 $tracker_active = defined( 'WPVMCPT_PLUGIN_VERSION' ) || class_exists( 'WPVMCPT\\Plugin' );
    83                 $tracker_url    = admin_url( 'admin.php?page=wpvmcpt-requests-list&server=' . rawurlencode( $server_slug ) );
     78                echo '<div class="mcp-tab-panel">';
     79                printf( '<h2>%s</h2>', esc_html__( 'Logs', 'acrossai-mcp-manager' ) );
     80                printf(
     81                        '<p class="description">%s</p>',
     82                        esc_html__( 'Requests this server answered, and what ran behind them.', 'acrossai-mcp-manager' )
     83                );
    8484
    85                 echo '<div class="mcp-tab-panel">';
    86                 printf( '<h2>%s</h2>', esc_html__( 'MCP Tracker', 'acrossai-mcp-manager' ) );
     85                // F096 — the same React app the global Activity page mounts, filtered to
     86                // this server with the Server column hidden. One component, two mount
     87                // points; the only difference is this bootstrap payload.
     88                ActivityLogPage::instance()->enqueue_bundle(
     89                        array(
     90                                'serverId'   => $server_id,
     91                                'showServer' => false,
     92                                'rootId'     => 'acrossai-mcp-activity-root',
     93                        )
     94                );
    8795
    88                 if ( $tracker_active ) {
    89                         $this->render_active( $server_slug, $tracker_url );
    90                 } else {
    91                         $this->render_inactive( $tracker_url );
     96                echo '<div id="acrossai-mcp-activity-root"></div>';
     97
     98                // The third-party plugin this tab used to advertise. Kept as a
     99                // secondary note rather than an install CTA: both logs can run at once
     100                // (different tables, no interference), and an operator who already has
     101                // it should be told why they are seeing two.
     102                if ( defined( 'WPVMCPT_PLUGIN_VERSION' ) || class_exists( 'WPVMCPT\\Plugin' ) ) {
     103                        $tracker_url = admin_url( 'admin.php?page=wpvmcpt-requests-list&server=' . rawurlencode( $server_slug ) );
     104
     105                        printf(
     106                                '<p class="description" style="margin-top:16px">%s <a href="%s">%s</a></p>',
     107                                esc_html__( 'MCP Tracker is also active on this site and logs the same traffic independently.', 'acrossai-mcp-manager' ),
     108                                esc_url( $tracker_url ),
     109                                esc_html__( 'Open MCP Tracker', 'acrossai-mcp-manager' )
     110                        );
    92111                }
    93112
    94113                echo '</div>';
    95114        }
    96 
    97         /**
    98          * Renders the "tracker active" branch — success notice + button + slug hint.
    99          *
    100          * @since 0.0.6
    101          * @param string $server_slug Server slug (already sanitized).
    102          * @param string $tracker_url Direct link to the request log filtered to this server.
    103          * @return void
    104          */
    105         private function render_active( string $server_slug, string $tracker_url ): void {
    106                 printf(
    107                         '<div class="notice notice-success inline"><p><strong>%1$s</strong> %2$s</p></div>',
    108                         esc_html__( 'MCP Tracker is active.', 'acrossai-mcp-manager' ),
    109                         esc_html__( 'View all logged requests for this server below.', 'acrossai-mcp-manager' )
    110                 );
    111 
    112                 printf(
    113                         '<p style="margin-top:16px;"><a href="%1$s" class="button button-primary">%2$s</a></p>',
    114                         esc_url( $tracker_url ),
    115                         esc_html__( 'View Request Log', 'acrossai-mcp-manager' )
    116                 );
    117 
    118                 echo '<p class="description" style="margin-top:12px;">';
    119                 /* translators: %s: server slug (wrapped in <code>) */
    120                 $slug_template = __( 'Direct link filtered to server: %s', 'acrossai-mcp-manager' );
    121                 printf(
    122                         wp_kses( $slug_template, array( 'code' => array() ) ),
    123                         '<code>' . esc_html( $server_slug ) . '</code>'
    124                 );
    125                 echo '<br />';
    126                 printf(
    127                         '<code style="user-select:all;">%s</code>',
    128                         esc_html( $tracker_url )
    129                 );
    130                 echo '</p>';
    131         }
    132 
    133         /**
    134          * Renders the "tracker not installed" branch — info notice + facts table + CTA.
    135          *
    136          * @since 0.0.6
    137          * @param string $tracker_url Direct link URL to display in the "Request log URL" row.
    138          * @return void
    139          */
    140         private function render_inactive( string $tracker_url ): void {
    141                 printf(
    142                         '<div class="notice notice-info inline"><p><strong>%1$s</strong> %2$s</p></div>',
    143                         esc_html__( 'MCP Tracker is not installed.', 'acrossai-mcp-manager' ),
    144                         esc_html__( 'Install the free MCP Tracker plugin to log and inspect every request made to this MCP server.', 'acrossai-mcp-manager' )
    145                 );
    146 
    147                 echo '<table class="form-table" style="margin-top:8px;">';
    148 
    149                 printf(
    150                         '<tr><th scope="row">%1$s</th><td><a href="%2$s" target="_blank" rel="noopener noreferrer">%3$s</a></td></tr>',
    151                         esc_html__( 'Plugin', 'acrossai-mcp-manager' ),
    152                         esc_url( self::WPORG_URL ),
    153                         esc_html__( 'MCP Tracker — WordPress.org', 'acrossai-mcp-manager' )
    154                 );
    155 
    156                 printf(
    157                         '<tr><th scope="row">%1$s</th><td>%2$s</td></tr>',
    158                         esc_html__( 'What it does', 'acrossai-mcp-manager' ),
    159                         esc_html__( 'Logs every incoming MCP request — tool calls, responses, errors, and timing — so you can audit activity, debug AI clients, and monitor server usage.', 'acrossai-mcp-manager' )
    160                 );
    161 
    162                 printf(
    163                         '<tr><th scope="row">%1$s</th><td><code style="user-select:all;">%2$s</code><p class="description">%3$s</p></td></tr>',
    164                         esc_html__( 'Request log URL', 'acrossai-mcp-manager' ),
    165                         esc_html( $tracker_url ),
    166                         esc_html__( 'Once installed and activated, this URL will open the request log filtered to this server.', 'acrossai-mcp-manager' )
    167                 );
    168 
    169                 echo '</table>';
    170 
    171                 printf(
    172                         '<p style="margin-top:16px;"><a href="%1$s" class="button" target="_blank" rel="noopener noreferrer">%2$s</a></p>',
    173                         esc_url( self::WPORG_URL ),
    174                         esc_html__( 'Get MCP Tracker', 'acrossai-mcp-manager' )
    175                 );
    176         }
    177115}
  • acrossai-mcp-manager/trunk/admin/Partials/Settings.php

    r3704846 r3766841  
    806806                        esc_html__( 'Add New', 'acrossai-mcp-manager' ),
    807807                        esc_url( $quick_connect_url ),
    808                         esc_html__( 'Quick Connect via AcrossAI', 'acrossai-mcp-manager' )
     808                        esc_html__( 'Connect via AcrossAI', 'acrossai-mcp-manager' )
    809809                );
    810810
  • acrossai-mcp-manager/trunk/admin/Partials/SettingsMenu.php

    r3702733 r3766841  
    2020namespace AcrossAI_MCP_Manager\Admin\Partials;
    2121
     22use AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants;
     23
    2224use AcrossAI_MCP_Manager\Includes\Abilities\Discover;
    2325
    … …  
    174176                                'default'           => 0,
    175177                        )
     178                );
     179
     180                // F096 — activity logging. TWO independent toggles: ability logging is
     181                // far noisier than request logging (one tools/call fans out into several
     182                // abilities, and non-MCP callers add rows with no MCP traffic at all),
     183                // so an operator must be able to run one without the other. Both off on
     184                // install — logging every request is a real cost and the WordPress AI
     185                // plugin's own equivalent sits behind an experiment gate for the same
     186                // reason. Laid out so Feature 097's change-recording toggle slots in as
     187                // a third row without restructuring.
     188                // The declared default MUST match the constant every reader passes to
     189                // get_option(). They are two different mechanisms and nothing makes
     190                // them agree, but unchecking the box depends on them agreeing:
     191                //
     192                // An unchecked checkbox posts no field, so `options.php` calls
     193                // update_option() with null, which sanitizes to false. update_option()
     194                // then compares that against `get_option( $option )` called WITHOUT an
     195                // explicit default — which resolves to whatever is declared HERE. If
     196                // this said false while readers defaulted to true, the comparison would
     197                // find false === false, write nothing, leave the option absent, and the
     198                // readers' true fallback would keep logging ON. The operator unticks
     199                // the box, the page reports success, and nothing changes.
     200                //
     201                // Verified directly: update_option( $option, false ) against an absent
     202                // option returns false and stores nothing.
     203                register_setting(
     204                        $option_group,
     205                        ActivityLogConstants::OPTION_REQUEST_LOGGING,
     206                        array(
     207                                'sanitize_callback' => 'rest_sanitize_boolean',
     208                                'default'           => ActivityLogConstants::DEFAULT_REQUEST_LOGGING,
     209                        )
     210                );
     211
     212                register_setting(
     213                        $option_group,
     214                        ActivityLogConstants::OPTION_ABILITY_LOGGING,
     215                        array(
     216                                'sanitize_callback' => 'rest_sanitize_boolean',
     217                                'default'           => ActivityLogConstants::DEFAULT_ABILITY_LOGGING,
     218                        )
     219                );
     220
     221                register_setting(
     222                        $option_group,
     223                        ActivityLogConstants::OPTION_RETENTION_REQUEST_DAYS,
     224                        array(
     225                                'sanitize_callback' => 'absint',
     226                                'default'           => ActivityLogConstants::DEFAULT_RETENTION_REQUEST_DAYS,
     227                        )
     228                );
     229
     230                register_setting(
     231                        $option_group,
     232                        ActivityLogConstants::OPTION_RETENTION_ABILITY_DAYS,
     233                        array(
     234                                'sanitize_callback' => 'absint',
     235                                'default'           => ActivityLogConstants::DEFAULT_RETENTION_ABILITY_DAYS,
     236                        )
     237                );
     238
     239                register_setting(
     240                        $option_group,
     241                        ActivityLogConstants::OPTION_MAX_EVENTS,
     242                        array(
     243                                'sanitize_callback' => 'absint',
     244                                'default'           => ActivityLogConstants::DEFAULT_MAX_EVENTS,
     245                        )
     246                );
     247
     248                add_settings_section(
     249                        'acrossai_mcp_activity_section',
     250                        __( 'MCP Activity Log', 'acrossai-mcp-manager' ),
     251                        array( $this, 'render_activity_section_description' ),
     252                        $page_slug
     253                );
     254
     255                add_settings_field(
     256                        ActivityLogConstants::OPTION_REQUEST_LOGGING,
     257                        __( 'Log MCP requests', 'acrossai-mcp-manager' ),
     258                        array( $this, 'render_activity_request_field' ),
     259                        $page_slug,
     260                        'acrossai_mcp_activity_section'
     261                );
     262
     263                add_settings_field(
     264                        ActivityLogConstants::OPTION_ABILITY_LOGGING,
     265                        __( 'Log ability runs', 'acrossai-mcp-manager' ),
     266                        array( $this, 'render_activity_ability_field' ),
     267                        $page_slug,
     268                        'acrossai_mcp_activity_section'
     269                );
     270
     271                add_settings_field(
     272                        'acrossai_mcp_activity_retention',
     273                        __( 'Keep events for', 'acrossai-mcp-manager' ),
     274                        array( $this, 'render_activity_retention_field' ),
     275                        $page_slug,
     276                        'acrossai_mcp_activity_section'
    176277                );
    177278
    … …  
    373474                );
    374475        }
     476
     477        /** Describe the activity-log section. */
     478        public function render_activity_section_description(): void {
     479                printf(
     480                        '<p>%s</p>',
     481                        esc_html__(
     482                                'Records what AI clients asked your MCP servers to do. On by default, and bounded by default: requests are kept for 30 days, ability runs for 7, and the log is capped at 50,000 events. A daily job applies all three. Switch either half off if you would rather it recorded nothing.',
     483                                'acrossai-mcp-manager'
     484                        )
     485                );
     486        }
     487
     488        /** Request-logging toggle. */
     489        public function render_activity_request_field(): void {
     490                $enabled = (bool) get_option( ActivityLogConstants::OPTION_REQUEST_LOGGING, ActivityLogConstants::DEFAULT_REQUEST_LOGGING );
     491
     492                printf(
     493                        '<label><input type="checkbox" name="%1$s" value="1" %2$s /> %3$s</label><p class="description">%4$s</p>',
     494                        esc_attr( ActivityLogConstants::OPTION_REQUEST_LOGGING ),
     495                        checked( $enabled, true, false ),
     496                        esc_html__( 'Record one row per MCP request', 'acrossai-mcp-manager' ),
     497                        esc_html__( 'What was asked, by which client, how it authenticated, whether it worked and how long it took.', 'acrossai-mcp-manager' )
     498                );
     499        }
     500
     501        /**
     502         * Ability-logging toggle.
     503         *
     504         * The description states that arguments are recorded. Redaction matches
     505         * sensitive KEY NAMES (token, secret, api_key and 21 more); it cannot cover
     506         * a secret pasted into a free-text value. An operator deserves to know that
     507         * before switching this on, rather than discovering it in a support thread.
     508         */
     509        public function render_activity_ability_field(): void {
     510                $enabled = (bool) get_option( ActivityLogConstants::OPTION_ABILITY_LOGGING, ActivityLogConstants::DEFAULT_ABILITY_LOGGING );
     511
     512                printf(
     513                        '<label><input type="checkbox" name="%1$s" value="1" %2$s /> %3$s</label><p class="description">%4$s</p>',
     514                        esc_attr( ActivityLogConstants::OPTION_ABILITY_LOGGING ),
     515                        checked( $enabled, true, false ),
     516                        esc_html__( 'Record one row per ability run', 'acrossai-mcp-manager' ),
     517                        esc_html__(
     518                                'Much noisier: one tool call can run several abilities, and REST, WP-CLI and admin callers are recorded too. Ability arguments are recorded — sensitive values are redacted by key name, so a secret inside a free-text field is stored as sent.',
     519                                'acrossai-mcp-manager'
     520                        )
     521                );
     522        }
     523
     524        /** Retention and the retained-event ceiling. */
     525        public function render_activity_retention_field(): void {
     526                printf(
     527                        '<p><label>%1$s <input type="number" min="0" name="%2$s" value="%3$d" class="small-text" /></label></p>'
     528                        . '<p><label>%4$s <input type="number" min="0" name="%5$s" value="%6$d" class="small-text" /></label></p>'
     529                        . '<p><label>%7$s <input type="number" min="0" name="%8$s" value="%9$d" class="small-text" /></label></p>'
     530                        . '<p class="description">%10$s</p>',
     531                        esc_html__( 'Requests, in days', 'acrossai-mcp-manager' ),
     532                        esc_attr( ActivityLogConstants::OPTION_RETENTION_REQUEST_DAYS ),
     533                        (int) get_option( ActivityLogConstants::OPTION_RETENTION_REQUEST_DAYS, ActivityLogConstants::DEFAULT_RETENTION_REQUEST_DAYS ),
     534                        esc_html__( 'Ability runs, in days', 'acrossai-mcp-manager' ),
     535                        esc_attr( ActivityLogConstants::OPTION_RETENTION_ABILITY_DAYS ),
     536                        (int) get_option( ActivityLogConstants::OPTION_RETENTION_ABILITY_DAYS, ActivityLogConstants::DEFAULT_RETENTION_ABILITY_DAYS ),
     537                        esc_html__( 'Maximum events kept, both halves together', 'acrossai-mcp-manager' ),
     538                        esc_attr( ActivityLogConstants::OPTION_MAX_EVENTS ),
     539                        (int) get_option( ActivityLogConstants::OPTION_MAX_EVENTS, ActivityLogConstants::DEFAULT_MAX_EVENTS ),
     540                        // The two retention fields are PER HALF and the ceiling is SHARED, so this
     541                        // paragraph has to switch scope mid-way. The previous wording said "the
     542                        // maximum is a hard ceiling" directly after a sentence about each half
     543                        // ageing out separately, which reads as a third per-half number — see the
     544                        // 2026-10-22 clarification. Say "shared", and say what it costs: heavy
     545                        // ability traffic shortening the request history is the surprising part.
     546                        esc_html__( 'The two day counts are separate, so noisy ability rows cannot force their cutoff onto the quieter request history. The maximum is different: it is one hard ceiling shared by both halves, and once the log passes it the oldest events are shed first whatever their kind — so heavy ability traffic can shorten your request history too. 0 means no limit.', 'acrossai-mcp-manager' )
     547                );
     548        }
    375549}
  • acrossai-mcp-manager/trunk/build/js/quick-connect.asset.php

    r3733272 r3766841  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '1791032da0c2cc8273ba');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '895f81949c9b67aca0b3');
  • acrossai-mcp-manager/trunk/build/js/quick-connect.js

    r3733272 r3766841  
    11(()=>{"use strict";var e={n:s=>{var a=s&&s.__esModule?()=>s.default:()=>s;return e.d(a,{a}),a},d:(s,a)=>{for(var r in a)e.o(a,r)&&!e.o(s,r)&&Object.defineProperty(s,r,{enumerable:!0,get:a[r]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.element,a=window.wp.apiFetch;var r=e.n(a);const t=window.wp.i18n,n=window.ReactJSXRuntime,i=["info","warning","success","error"],l=({status:e="info",children:s})=>{const a=i.includes(e)?e:"info";return(0,n.jsx)("div",{className:`qs-notice qs-notice--${a}`,role:"error"===a?"alert":"status",children:s})},c={1:"Choose a server",2:"Create a new server",3:"Choose access",4:"Enable Abilities Manager",5:"Enable abilities",6:"Enable server",7:"Pick a connection method",10:"One-click OAuth setup",11:"MCP Client setup",12:"npm setup",13:"WP-CLI setup",done:"You're all set!"},o=({step:e,displayIndex:a,totalSteps:r,isLoading:i,canAdvance:l,footerAction:o,hideContinue:d,belowFooter:p,onBack:m,onAdvance:u,onExit:g,children:_})=>{const h=window.acrossaiMcpQuickConnect||{},v=(0,s.useRef)(null),b=(0,s.useRef)(null);(0,s.useEffect)(()=>{if(!v.current)return;const e=v.current.querySelector('input, button, select, textarea, [tabindex]:not([tabindex="-1"]), [role="radio"]');e&&e.focus()},[e]),(0,s.useEffect)(()=>{if(!b.current)return;const s=c[e]||e,n="done"===e?s:/* translators: 1: current step number, 2: total steps, 3: step title */ /* translators: 1: current step number, 2: total steps, 3: step title */
    2 (0,t.__)("Step %1$d of %2$d, %3$s","acrossai-mcp-manager").replace("%1$d",String(a)).replace("%2$d",String(r)).replace("%3$s",s);b.current.textContent="";const i=setTimeout(()=>{b.current&&(b.current.textContent=n)},100);return()=>clearTimeout(i)},[e,a,r]);const x=Math.min(100,Math.max(0,Math.round(a/r*100))),y="1"===e||"done"===e,f="done"===e,w=["10","11","12","13"].includes(e)?(0,t.__)("Finish","acrossai-mcp-manager"):(0,t.__)("Continue","acrossai-mcp-manager"),j=o?[].concat(o).filter(Boolean):[],C=j.find(e=>e.isLoading),S=i||!!C;return(0,n.jsxs)(n.Fragment,{children:[S&&h.iconUrl&&(0,n.jsxs)("div",{className:"qs__initial-loading qs__initial-loading--overlay",role:"alert","aria-live":"assertive","aria-busy":"true",children:[(0,n.jsx)("img",{className:"qs__initial-loading-icon",src:h.iconUrl,alt:"","aria-hidden":"true"}),(0,n.jsx)("span",{className:"qs__sr-only",children:C?.label?C.label:(0,t.__)("Saving…","acrossai-mcp-manager")})]}),(0,n.jsx)("div",{className:"qs__progress",role:"progressbar","aria-valuenow":a,"aria-valuemin":1,"aria-valuemax":r,"aria-label":(0,t.__)("Wizard progress","acrossai-mcp-manager"),children:(0,n.jsx)("span",{className:"qs__progress-fill",style:{width:`${x}%`}})}),(0,n.jsxs)("header",{className:"qs__header",children:[h.logoUrl&&(0,n.jsx)("img",{className:"qs__header-logo",src:h.logoUrl,alt:"AcrossAI"}),(0,n.jsx)("span",{className:"qs__header-title",children:(0,t.__)("Quick Connect","acrossai-mcp-manager")}),(0,n.jsx)("a",{className:"qs__header-consult",href:"https://acrossai.co/consultations/",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("Free Consultations ↗","acrossai-mcp-manager")}),!f&&(0,n.jsx)("a",{className:"qs__header-exit",href:"#",onClick:e=>{e.preventDefault(),g?.()},children:(0,t.__)("Exit setup","acrossai-mcp-manager")})]}),(0,n.jsxs)("div",{className:"qs__content",ref:v,children:[_,!f&&(()=>{const e=y||S,s=!l||S||j.some(e=>e.disabled);return(0,n.jsxs)("footer",{className:"qs__footer",children:[(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--secondary",disabled:e,"aria-disabled":e,onClick:e?void 0:m,children:(0,t.__)("Back","acrossai-mcp-manager")}),!d&&(0,n.jsx)("button",{type:"button",className:j.length?"qs-btn qs-btn--secondary":"qs-btn","aria-disabled":s,onClick:s?void 0:u,children:w}),j.map(e=>{const s=!!(a=e).disabled||!!a.isLoading;var a;const r="secondary"===e.variant?"qs-btn qs-btn--secondary":"qs-btn";return e.href?(0,n.jsx)("a",{className:r,href:e.href,target:e.target||"_self",rel:"_blank"===e.target?"noopener noreferrer":void 0,"aria-disabled":s,onClick:e.onClick,children:e.label},e.label):(0,n.jsx)("button",{type:"button",className:r,"aria-disabled":s,onClick:s?void 0:e.onClick,children:e.label},e.label)})]})})(),!f&&p]}),(0,n.jsx)("div",{className:"qs__sr-only",ref:b,"aria-live":"polite","aria-atomic":"true"})]})},d=window.wp.url,p=["1","2","3","4","5","6","7","10","11","12","13","done"],m=(e,s)=>!!("2"===e&&s.skipCreate||"4"===e&&s.skipAbilitiesGate||"5"===e&&s.skipAbilities||"6"===e&&s.skipEnable||"10"===e&&s.skipConnectorsDetail||"11"===e&&s.skipClient||"12"===e&&s.skipNpm||"13"===e&&s.skipWpcli),u=()=>{const e=window.location.search||"",s=(0,d.getQueryArg)(e,"step"),a=(0,d.getQueryArg)(e,"method"),r=(0,d.getQueryArg)(e,"mode"),t=(0,d.getQueryArg)(e,"server"),n=t?parseInt(t,10):NaN;return{step:void 0===s||""===s?"1":String(s),method:void 0===a||""===a?null:String(a),mode:void 0===r||""===r?null:String(r),server:Number.isFinite(n)&&n>0?n:null}},g=(e,s,a,r)=>{let t=window.location.pathname+window.location.search;return t=(0,d.addQueryArgs)(t,{step:e}),t=s?(0,d.addQueryArgs)(t,{method:s}):(0,d.removeQueryArgs)(t,"method"),t=a?(0,d.addQueryArgs)(t,{mode:a}):(0,d.removeQueryArgs)(t,"mode"),t=r?(0,d.addQueryArgs)(t,{server:r}):(0,d.removeQueryArgs)(t,"server"),t},_="acrossai-mcp-qs-nav",h=()=>{"undefined"!=typeof window&&"function"==typeof CustomEvent&&window.dispatchEvent(new CustomEvent(_))},v=()=>{const[e,a]=(0,s.useState)(u);(0,s.useEffect)(()=>{const e=()=>a(u());return window.addEventListener("popstate",e),window.addEventListener(_,e),()=>{window.removeEventListener("popstate",e),window.removeEventListener(_,e)}},[]);const r=(0,s.useCallback)((e,s=null,r=null)=>{if(!p.includes(e))return;const t=u(),n=g(e,s,r,t.server);window.history.pushState({},"",n),a({step:e,method:s,mode:r,server:t.server}),h()},[]),t=(0,s.useCallback)(e=>{const s=u(),r={...s,mode:e||null},t=g(s.step,s.method,r.mode,s.server);window.history.pushState({},"",t),a(r),h()},[]),n=(0,s.useCallback)(e=>{const s=Number.isFinite(e)&&e>0?e:null,r=u();if(r.server===s)return;const t=g(r.step,r.method,r.mode,s);window.history.replaceState({},"",t),a({...r,server:s}),h()},[]),i=(0,s.useCallback)(({skips:s={}}={})=>{const a=p.indexOf(e.step);if(-1===a||a>=p.length-1)return;let t=a+1;for(;t<p.length-1&&m(p[t],s);)t+=1;r(p[t],null)},[e.step,r]),l=(0,s.useCallback)(({skips:s={}}={})=>{const a=p.indexOf(e.step);if(a<=0)return;let t=a-1;for(;t>0&&m(p[t],s);)t-=1;r(p[t],null)},[e.step,r]),c=(0,s.useCallback)(()=>{const e=(window.acrossaiMcpQuickConnect||{}).adminUrl||"/wp-admin/admin.php?page=acrossai_mcp_manager";window.location.href=e},[]);return(0,s.useMemo)(()=>({step:e.step,method:e.method,mode:e.mode,server:e.server,goTo:r,setMode:t,setServer:n,advance:i,back:l,exit:c}),[e.step,e.method,e.mode,e.server,r,t,n,i,l,c])},b={status:"idle",error:null,servers:[],abilities:{total:0,enabledForServer:null,hasManagerPlugin:!1},plugins:{abilitiesManager:"missing"},methods:{npm:[],clients:[],ai_connectors:[]},wizardState:{current_step:1,server_id:null,access_saved:!1,abilities_saved:!1,enabled:!1,method:null,created_at:null}},x="HYDRATE_START",y="HYDRATE_SUCCESS",f="HYDRATE_ERROR",w="SAVE_STEP_START",j="SAVE_STEP_SUCCESS",C="SAVE_STEP_ERROR",S="COMPLETE_START",k="COMPLETE_SUCCESS",N="CLEAR_ERROR",q=(e,s)=>{switch(s.type){case x:return{...e,status:"loading",error:null};case y:{const a=s.payload||{};return{...e,status:"ready",error:null,servers:Array.isArray(a.servers)?a.servers:[],abilities:a.abilities||e.abilities,plugins:a.plugins||e.plugins,methods:a.methods||e.methods,wizardState:{...e.wizardState,...a.wizardState||{}}}}case f:return{...e,status:"error",error:s.payload};case w:return{...e,status:"saving",error:null,wizardState:{...e.wizardState,...s.optimistic||{}}};case j:{const a=s.payload||{};return{...e,status:"ready",error:null,servers:Array.isArray(a.servers)?a.servers:e.servers,abilities:a.abilities||e.abilities,wizardState:{...e.wizardState,...a.wizardState||{}}}}case C:return{...e,status:"error",error:s.payload.error,wizardState:s.payload.rollbackState||e.wizardState};case S:return{...e,status:"saving",error:null};case k:case N:return{...e,status:"ready",error:null};default:return e}},A=e=>{if(e&&"object"==typeof e){const s=e.data?.status||e.status;if(403===s)return{code:"session_expired",message:(0,t.__)("Your session has expired. Please reload the page to continue.","acrossai-mcp-manager")};if(401===s)return{code:"not_authorized",message:(0,t.__)("You are no longer signed in. Please reload the page.","acrossai-mcp-manager")};if(e.message)return{code:e.code||"error",message:String(e.message)}}return{code:"network_error",message:(0,t.__)("Something went wrong. Please try again.","acrossai-mcp-manager")}},M=(0,s.createContext)(null),E=({children:e})=>{const[a,t]=(0,s.useReducer)(q,b),i=(0,s.useRef)("");if(!i.current){const e=window.acrossaiMcpQuickConnect||{};i.current=e.restUrl||"/wp-json/acrossai-mcp-manager/v1/quick-connect"}const l=(0,s.useCallback)(async()=>{t({type:x});try{const e=new URLSearchParams(window.location.search).get("server"),s=e?`${i.current}/state?server_id=${encodeURIComponent(e)}`:`${i.current}/state`,a=await r()({url:s,method:"GET"});return t({type:y,payload:a}),a}catch(e){return t({type:f,payload:A(e)}),null}},[]),c=(0,s.useCallback)(async(e,s={})=>{const n=a.wizardState,l={current_step:e,...s};t({type:w,optimistic:l});try{const a=await r()({url:`${i.current}/step`,method:"POST",data:{step:e,data:s}});return t({type:j,payload:a}),a}catch(e){return t({type:C,payload:{error:A(e),rollbackState:n}}),null}},[a.wizardState]),o=(0,s.useCallback)(async()=>{t({type:S});try{return await r()({url:`${i.current}/complete`,method:"POST"}),t({type:k}),!0}catch(e){return t({type:f,payload:A(e)}),!1}},[]),d=(0,s.useCallback)(()=>t({type:N}),[]);(0,s.useEffect)(()=>{const e=()=>{"ready"===a.status&&l()},s=()=>{"visible"===document.visibilityState&&e()};return window.addEventListener("focus",e),document.addEventListener("visibilitychange",s),window.addEventListener("popstate",e),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",s),window.removeEventListener("popstate",e)}},[l,a.status]);const p={state:a,isLoading:"loading"===a.status||"saving"===a.status,error:a.error,refetch:l,saveStep:c,complete:o,clearError:d};return(0,n.jsx)(M.Provider,{value:p,children:e})},z=()=>{const e=(0,s.useContext)(M);if(!e)throw new Error("useWizardState must be used within <WizardStateProvider>");return e},P=(0,s.createContext)({setCanAdvance:()=>{},setBeforeAdvance:()=>{},setFooterAction:()=>{},setHideContinue:()=>{},setBelowFooter:()=>{},advance:()=>{}}),T=e=>{const{setFooterAction:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(e||null),()=>a(null)),[e,a])},R=(e,a=null)=>{const{setCanAdvance:r,setBeforeAdvance:t}=(0,s.useContext)(P);(0,s.useEffect)(()=>(r(!!e),t(()=>a),()=>{r(!0),t(()=>null)}),[e,a,r,t])},$=({selected:e=!1,onSelect:s,title:a,subtitle:r,badge:t=null,children:i=null,name:l="qs-card",value:c=""})=>(0,n.jsxs)("label",{className:"qs-card"+(e?" qs-card--selected":""),role:"radio","aria-checked":e,tabIndex:0,onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),s?.())},children:[(0,n.jsx)("input",{type:"radio",name:l,value:c,checked:e,onChange:()=>s?.(),style:{position:"absolute",opacity:0,pointerEvents:"none"},tabIndex:-1}),(0,n.jsx)("span",{className:"qs-card__radio","aria-hidden":"true"}),(0,n.jsxs)("div",{className:"qs-card__body",children:[(0,n.jsxs)("div",{className:"qs-card__title",children:[a,t]}),r&&(0,n.jsx)("div",{className:"qs-card__subtitle",children:r}),i]})]}),I=["acrossai-mcp-server","mcp-adapter-default-server"],L=I[0],B=()=>{const{state:e,saveStep:a}=z(),r=e.wizardState.server_id,i=!!e.wizardState.create_intent;(0,s.useEffect)(()=>{"ready"!==e.status||0!==e.servers.length||i||a(1,{create_intent:!0})},[e.status,e.servers.length,i,a]),(0,s.useEffect)(()=>{if("ready"!==e.status||null!==r||i||0===e.servers.length)return;const s=I.reduce((s,a)=>s||e.servers.find(e=>e.slug===a),null)||e.servers[0];s&&a(1,{server_id:s.id})},[e.status,e.servers,r,i,a]),R(null!==r||i);const l=(0,s.useMemo)(()=>{const s=e.servers||[];return[...s.filter(e=>e.slug===L),...s.filter(e=>e.slug!==L)]},[e.servers]);return(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Which server should AI connect to?","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Pick an existing MCP server, or create a new one for this setup.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{role:"radiogroup","aria-label":(0,t.__)("MCP servers","acrossai-mcp-manager"),children:[l.map(e=>(0,n.jsx)($,{name:"qs-server-pick",value:String(e.id),selected:!i&&r===e.id,onSelect:()=>(async e=>{await a(1,{server_id:e})})(e.id),title:e.name,subtitle:(0,n.jsx)("code",{children:e.route_full}),badge:(0,n.jsxs)(n.Fragment,{children:[e.slug===L?(0,n.jsx)("span",{className:"qs-card__badge qs-card__badge--recommended",children:(0,t.__)("Recommended","acrossai-mcp-manager")}):null,e.enabled?null:(0,n.jsx)("span",{className:"qs-card__badge qs-card__badge--inactive",children:(0,t.__)("Inactive","acrossai-mcp-manager")})]})},e.id)),(0,n.jsx)($,{name:"qs-server-pick",value:"__create__",selected:i,onSelect:async()=>{await a(1,{create_intent:!0})},title:(0,t.__)("+ Create a new server","acrossai-mcp-manager"),subtitle:(0,t.__)("Set up a brand-new MCP server for this wizard.","acrossai-mcp-manager")})]})]})},U=e=>String(e).toLowerCase().replace(/[^a-z0-9\-_]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-"),W=()=>{const{saveStep:e}=z(),[a,r]=(0,s.useState)({server_name:"",server_slug:"",description:"",server_route_namespace:"mcp",server_route:"",server_version:"v1.0.0"}),[i,l]=(0,s.useState)(!1),[c,o]=(0,s.useState)(!1),[d,p]=(0,s.useState)(null),m=(0,s.useCallback)(async()=>{if(p(null),!a.server_name.trim())return p((0,t.__)("Server name is required.","acrossai-mcp-manager")),!1;const s=await e(2,{new_server:a});return!!(s&&s.wizardState&&s.wizardState.server_id)},[a,e]);return R(a.server_name.trim().length>0,m),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Create a new MCP server","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Fill in a name — the rest is auto-filled. Click Continue when you're done.","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Name","acrossai-mcp-manager")}),(0,n.jsx)("span",{style:{color:"#cc1818",marginLeft:4},children:"*"}),(0,n.jsx)("input",{type:"text",value:a.server_name,onChange:e=>{return s=e.target.value,void r(e=>({...e,server_name:s,server_slug:i?e.server_slug:U(s),server_route:c?e.server_route:U(s)}));var s},required:!0,style:{display:"block",width:"100%",padding:"8px",marginTop:4}})]})}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Slug","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_slug,onChange:e=>{return s=e.target.value,l(!0),void r(e=>({...e,server_slug:s,server_route:c?e.server_route:U(s)}));var s},style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]})}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Description","acrossai-mcp-manager")}),(0,n.jsx)("textarea",{value:a.description,onChange:e=>r(s=>({...s,description:e.target.value})),rows:3,style:{display:"block",width:"100%",padding:"8px",marginTop:4}})]})}),(0,n.jsxs)("div",{style:{display:"flex",gap:12,marginBottom:16},children:[(0,n.jsxs)("label",{style:{flex:1},children:[(0,n.jsx)("strong",{children:(0,t.__)("Route namespace","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_route_namespace,onChange:e=>r(s=>({...s,server_route_namespace:e.target.value})),style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]}),(0,n.jsxs)("label",{style:{flex:1},children:[(0,n.jsx)("strong",{children:(0,t.__)("Route","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_route,onChange:e=>{o(!0),r(s=>({...s,server_route:e.target.value}))},style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]}),(0,n.jsxs)("label",{style:{flex:"0 0 120px"},children:[(0,n.jsx)("strong",{children:(0,t.__)("Version","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_version,onChange:e=>r(s=>({...s,server_version:e.target.value})),style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]})]}),d&&(0,n.jsx)("div",{style:{color:"#cc1818",marginBottom:16},role:"alert",children:d})]})},O=[{value:"",label:"No user access added by admin"},{value:"everyone",label:"Public (no login required)"},{value:"authenticated",label:"Any logged-in user"}];function F({providers:e,value:s,onChange:a}){const r=e.filter(e=>!1!==e.available);return(0,n.jsxs)("select",{className:"wpb-ac__select",value:s,onChange:e=>a(e.target.value),children:[O.map(e=>(0,n.jsx)("option",{value:e.value,children:e.label},e.value)),r.map(e=>(0,n.jsx)("option",{value:e.id,children:e.label},e.id))]})}const Q={wp_role:"Select which WordPress Role values may access this resource. Leave all unchecked to deny everyone (except administrators).",wp_capability:"Select which WordPress capabilities grant access. Users holding any of the checked capabilities are allowed. Administrators always have access.",bb_profile_type:"Select which BuddyBoss profile types grant access. Users assigned to any of the checked profile types are allowed. Administrators always have access.",mepr_membership:"Select which MemberPress memberships grant access. Users with an active subscription to any of the checked memberships are allowed. Administrators always have access."};function D({providerId:e,options:s,selectedOptions:a,onToggle:r}){const t=Q[e]||null;return(0,n.jsxs)("div",{className:"wpb-ac__options-panel",children:[t&&(0,n.jsx)("p",{className:"wpb-ac__panel-description",children:t}),(0,n.jsx)("ul",{className:"wpb-ac__checkbox-list",children:s.map(e=>(0,n.jsx)("li",{className:"wpb-ac__checkbox-item",children:(0,n.jsxs)("label",{children:[(0,n.jsx)("input",{type:"checkbox",value:e.id,checked:a.includes(e.id),onChange:()=>r(e.id)}),e.label]})},e.id))})]})}function H({pluginSlug:e,restApiRoot:a,selectedUsers:t,onAdd:i,onRemove:l}){const[c,o]=(0,s.useState)(""),[d,p]=(0,s.useState)([]),[m,u]=(0,s.useState)(!1),g=(0,s.useRef)(null),_=(0,s.useRef)(null);(0,s.useEffect)(()=>{const e=e=>{_.current&&!_.current.contains(e.target)&&u(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);const h=(0,s.useCallback)(s=>{if(!s.trim())return p([]),void u(!1);r()({url:`${a}/wpb-ac/v1/${e}/users?search=${encodeURIComponent(s)}`}).then(e=>{p(e||[]),u(!0)}).catch(()=>p([]))},[e,a]),v=(0,s.useCallback)(e=>{const s=e.target.value;o(s),clearTimeout(g.current),g.current=setTimeout(()=>h(s),300)},[h]),b=(0,s.useCallback)(e=>{i({id:e.id,login:e.login,display_name:e.display_name}),o(""),p([]),u(!1)},[i]),x=d.filter(e=>!t.find(s=>s.id===e.id));return(0,n.jsxs)("div",{className:"wpb-ac__user-panel",ref:_,children:[(0,n.jsx)("p",{className:"wpb-ac__panel-description",children:"Search by username or email and select one or more users. Administrators always have access regardless of this list."}),(0,n.jsxs)("div",{className:"wpb-ac__search-wrapper",children:[(0,n.jsx)("input",{type:"text",className:"wpb-ac__search-input",placeholder:"Search by username or email...",value:c,onChange:v,onFocus:()=>x.length&&u(!0)}),m&&x.length>0&&(0,n.jsx)("ul",{className:"wpb-ac__search-dropdown",children:x.map(e=>(0,n.jsxs)("li",{className:"wpb-ac__search-option",onMouseDown:()=>b(e),children:[e.display_name," (",e.login,")"]},e.id))})]}),t.length>0&&(0,n.jsx)("div",{className:"wpb-ac__user-tags",children:t.map(e=>(0,n.jsxs)("span",{className:"wpb-ac__user-tag",children:[e.display_name," (",e.login,")",(0,n.jsx)("button",{type:"button",className:"wpb-ac__tag-remove",onClick:()=>l(e.id),"aria-label":`Remove ${e.display_name}`,children:"×"})]},e.id))})]})}function Y({pluginSlug:e,namespace:a,resourceKey:t,restApiRoot:i,nonce:l,title:c="Access Control",description:o="Control which users are allowed to connect to this MCP server. Administrators always have access regardless of this setting.",saveLabel:d="Save Access Control",onSave:p,hideSaveButton:m=!1,hideHeader:u=!1,onChange:g}){const[_,h]=(0,s.useState)(!0),[v,b]=(0,s.useState)(!1),[x,y]=(0,s.useState)(null),[f,w]=(0,s.useState)([]),[j,C]=(0,s.useState)(""),[S,k]=(0,s.useState)([]),[N,q]=(0,s.useState)([]),A=a.split("/").map(encodeURIComponent).join("%2F"),M=(0,s.useCallback)(e=>{const s=e.map(e=>`include[]=${e}`).join("&");r()({url:`${i}/wp/v2/users?${s}&per_page=100`}).then(e=>{q(e.map(e=>({id:String(e.id),login:e.slug,display_name:e.name})))}).catch(()=>{q(e.map(e=>({id:e,login:e,display_name:e})))})},[i]);(0,s.useEffect)(()=>{if(!t)return void h(!1);h(!0),y(null),w([]),C(""),k([]),q([]);let s=!1;return Promise.all([r()({url:`${i}/wpb-ac/v1/${e}/providers`}),r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`})]).then(([e,a])=>{if(s)return;w(e);const r=a.key||"",t=a.value||[];C(r),k(t),"wp_user"===r&&t.length>0&&M(t)}).catch(()=>{}).finally(()=>{s||h(!1)}),()=>{s=!0}},[e,i,A,t]);const E=(0,s.useCallback)(e=>{C(e),k([]),q([]),y(null)},[]),z=(0,s.useCallback)(e=>{k(s=>s.includes(e)?s.filter(s=>s!==e):[...s,e])},[]),P=(0,s.useCallback)(e=>{q(s=>s.find(s=>s.id===e.id)?s:[...s,e]),k(s=>s.includes(e.id)?s:[...s,e.id])},[]),T=(0,s.useCallback)(e=>{q(s=>s.filter(s=>s.id!==e)),k(s=>s.filter(s=>s!==e))},[]),R=(0,s.useCallback)(async()=>{b(!0),y(null);try{""===j?await r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`,method:"DELETE"}):await r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`,method:"PUT",data:{ac_key:j,ac_options:S}}),y({type:"success",message:"Access control saved."}),p?.(j,S)}catch(e){y({type:"error",message:e?.message||"Failed to save."})}finally{b(!1)}},[j,S,e,A,t,i,p]);(0,s.useEffect)(()=>{_||g?.(j,S)},[j,S,_]);const $=f.find(e=>e.id===j)||null,I=$&&"wp_user"!==$.id&&$.options?.length>0,L="wp_user"===j;return _?(0,n.jsx)("div",{className:"wpb-ac wpb-ac--loading",children:"Loading…"}):(0,n.jsxs)("div",{className:"wpb-ac",children:[!u&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("h2",{className:"wpb-ac__title",children:c}),(0,n.jsx)("p",{className:"wpb-ac__description",children:o})]}),(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:"Who can access"}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(F,{providers:f,value:j,onChange:E})})]}),I&&(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:$.label}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(D,{providerId:j,options:$.options,selectedOptions:S,onToggle:z})})]}),L&&(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:$?.label||"Users"}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(H,{pluginSlug:e,restApiRoot:i,selectedUsers:N,onAdd:P,onRemove:T})})]}),x&&(0,n.jsx)("p",{className:`wpb-ac__notice wpb-ac__notice--${x.type}`,children:x.message}),!m&&(0,n.jsx)("div",{className:"wpb-ac__footer",children:(0,n.jsx)("button",{type:"button",className:"wpb-ac__save-btn",onClick:R,disabled:v,children:v?"Saving…":d})})]})}const G=({pluginSlug:e,namespace:a="acrossai-mcp-manager",resourceKey:r,restApiRoot:t="/wp-json",nonce:n="",title:i,description:l,saveLabel:c,hideSaveButton:o=!1,onChange:d,onSave:p})=>e&&r?(0,s.createElement)(Y,{pluginSlug:e,namespace:a,resourceKey:r,restApiRoot:t,nonce:n,title:i||void 0,description:l||void 0,saveLabel:c||void 0,hideSaveButton:o,onChange:d,onSave:p}):null,V=()=>{const{state:e}=z(),a=(()=>{const{advance:e}=(0,s.useContext)(P);return e})(),i=window.acrossaiMcpQuickConnect||{},[c,o]=(0,s.useState)(null),[d,p]=(0,s.useState)(!1),m=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),u=(0,s.useRef)({key:null,options:[]}),g=(0,s.useCallback)((e,s)=>{u.current={key:e,options:Array.isArray(s)?s:[]}},[]),_=(0,s.useCallback)(async()=>{if(o(null),!m||null===u.current.key||""===u.current.key)return void a();const e=i.acPluginSlug||"mcp",s=i.acNamespace||"acrossai-mcp-manager",n=`${i.restApiRoot||"/wp-json"}/wpb-ac/v1/${e}/rules/${encodeURIComponent(s)}/${m.slug}`;p(!0);try{await r()({url:n,method:"PUT",data:{ac_key:u.current.key,ac_options:u.current.options}}),a()}catch(e){o(e&&e.message||(0,t.__)("Failed to save access control. Try again.","acrossai-mcp-manager"))}finally{p(!1)}},[m,i.acPluginSlug,i.acNamespace,i.restApiRoot,a]),h=(0,s.useMemo)(()=>m?{label:(0,t.__)("Save and Continue","acrossai-mcp-manager"),onClick:_,isLoading:d,disabled:d}:null,[m,_,d]);return T(h),m?(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Who can reach this server?","acrossai-mcp-manager")}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("Only administrators can reach this server until you add an access rule below.","acrossai-mcp-manager")}),c&&(0,n.jsx)(l,{status:"error",children:c}),(0,n.jsx)(G,{pluginSlug:i.acPluginSlug||"mcp",namespace:i.acNamespace||"acrossai-mcp-manager",resourceKey:m.slug,restApiRoot:i.restApiRoot||"/wp-json",nonce:i.restNonce||"",hideSaveButton:!0,onChange:g}),(0,n.jsx)("p",{className:"qs__step-subtitle",style:{marginTop:24},children:(0,t.__)("Continue skips saving (leaves current rule as-is). Save and Continue writes your changes and moves on. You can change this anytime under the server's Access Control tab.","acrossai-mcp-manager")})]}):(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Who can reach it?","acrossai-mcp-manager")}),(0,n.jsx)("p",{children:(0,t.__)("No server selected — go back to Step 1.","acrossai-mcp-manager")})]})},K=["Blocks","Cache","Comments","Content Search","Core","Cron","Database","File Manager","Media","Plugins","Rank Math","Settings","Site Health","Themes","Users","Widgets"],J=()=>{const{state:e,refetch:a}=z(),[i,c]=(0,s.useState)(!1),[o,d]=(0,s.useState)(null),p="missing"===e.plugins.abilitiesManager,m=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id)||null,[e.servers,e.wizardState.server_id]),u=null!==m&&!1===m.type_available;R(!u);const g=(0,s.useCallback)(async()=>{c(!0),d(null);try{const e=(window.acrossaiMcpQuickConnect||{}).restUrl||"/wp-json/acrossai-mcp-manager/v1/quick-connect";await r()({url:`${e}/install-plugin`,method:"POST",data:{slug:"acrossai-abilities-manager"}}),await a()}catch(e){d(e&&e.message||(0,t.__)("Something went wrong. Try again or install the plugin manually.","acrossai-mcp-manager"))}finally{c(!1)}},[a]),_=i?p?(0,t.__)("Installing…","acrossai-mcp-manager"):(0,t.__)("Activating…","acrossai-mcp-manager"):p?(0,t.__)("Install & Continue","acrossai-mcp-manager"):(0,t.__)("Activate & Continue","acrossai-mcp-manager"),h=(0,s.useMemo)(()=>({label:_,onClick:g,isLoading:i,disabled:i}),[_,g,i]);T(h);const v=(0,n.jsxs)("span",{className:"qs__brand-mark qs__brand-mark--inline",children:[(0,n.jsx)("span",{className:"qs__brand-mark__across",children:"Across"}),(0,n.jsx)("span",{className:"qs__brand-mark__ai",children:"AI"})]}),b=(0,s.createInterpolateElement)(p?(0,t.__)("Install <brand/> Abilities Manager","acrossai-mcp-manager"):(0,t.__)("Activate <brand/> Abilities Manager","acrossai-mcp-manager"),{brand:v});return(0,n.jsxs)("div",{children:[o&&(0,n.jsx)("div",{style:{marginBottom:20},children:(0,n.jsx)(l,{status:"error",children:o})}),u&&(0,n.jsx)("div",{style:{marginBottom:20},children:(0,n.jsx)(l,{status:"warning",children:(0,t.__)("This server's type requires the AcrossAI Abilities Manager, so it cannot be enabled later in this setup without it. Install it below, or go back and choose a different server type.","acrossai-mcp-manager")})}),(0,n.jsxs)("div",{className:"qs__gate-card",children:[(window.acrossaiMcpQuickConnect||{}).logoUrl&&(0,n.jsx)("img",{className:"qs__gate-card__logo",src:window.acrossaiMcpQuickConnect.logoUrl,alt:"","aria-hidden":"true"}),(0,n.jsx)("h2",{className:"qs__step-title",children:b}),(0,n.jsxs)("div",{className:"qs__gate-categories",children:[(0,n.jsx)("p",{className:"qs__gate-categories-label",children:(0,t.__)("Includes 350+ abilities for:","acrossai-mcp-manager")}),(0,n.jsx)("ul",{className:"qs__gate-bullets qs__gate-bullets--grid",children:K.map(e=>(0,n.jsx)("li",{children:e},e))})]}),(0,n.jsx)("div",{className:"qs__gate-actions",children:(0,n.jsx)("a",{className:"qs-btn qs-btn--secondary",href:"https://wordpress.org/plugins/acrossai-abilities-manager/",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("View on WordPress.org ↗","acrossai-mcp-manager")})})]}),(0,n.jsx)("div",{style:{marginTop:24},children:(0,n.jsx)(l,{status:"info",children:(0,t.__)("You can Continue without installing — the wizard will fall back to the 3 abilities WordPress ships with. Or install the plugin now to unlock the full 350+ set. You can broaden per-ability access in the next step.","acrossai-mcp-manager")})})]})},X=["core/get-environment-info","core/get-site-info","core/get-user-info"],Z=()=>{const{state:e,saveStep:a,isLoading:r}=z(),[i,c]=(0,s.useState)(!1),o=window.acrossaiMcpQuickConnect||{},d=e.plugins.abilitiesManager,p="active"===d,m="inactive"===d,u=e.plugins.abilitiesManagerActivateUrl||"",g=e.wizardState.server_id,_=e.abilities.total,h=e.abilities.enabledForServer,v=_>0&&null!==h&&h>=_,b=(0,s.useCallback)(async()=>{c(!0);try{await a(5,{enable_all_abilities:!0})}finally{c(!1)}},[a]),x=(0,s.useMemo)(()=>p&&!v?{label:(0,t.__)("Enable all and continue","acrossai-mcp-manager"),onClick:b,isLoading:i||r,disabled:i||r}:null,[p,v,b,i,r]);return T(x),p?(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("What should AI be able to do?","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-end",gap:16,justifyContent:"center",margin:"20px 0"},children:[(0,n.jsx)("span",{style:{fontSize:60,fontWeight:700,lineHeight:.9},children:null!==h?`${h} / ${_}`:_}),(0,n.jsxs)("div",{style:{paddingBottom:8},children:[(0,n.jsx)("div",{style:{fontSize:15,fontWeight:600},children:null!==h?(0,t.__)("enabled for this server","acrossai-mcp-manager"):(0,t.__)("abilities available","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{fontSize:13,color:"#757575"},children:(0,t.__)("From AcrossAI Abilities Manager.","acrossai-mcp-manager")})]})]}),v&&(0,n.jsx)(l,{status:"success",children:(0,t.__)("All abilities enabled for this server ✓","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{display:"flex",justifyContent:"center",marginBottom:20},children:(0,n.jsx)("a",{className:"qs-btn qs-btn--secondary",href:o.adminUrl&&g?`${o.adminUrl}&action=edit&server=${g}&tab=abilities`:"#",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("Configure abilities one-by-one ↗","acrossai-mcp-manager")})}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("By default, all abilities registered by Abilities Manager can be accessed by users with the manage_options capability (admins only). You can broaden this per-ability in the Access Control step.","acrossai-mcp-manager")})]}):(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("What should AI be able to do?","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-end",gap:16,justifyContent:"center",margin:"20px 0"},children:[(0,n.jsx)("span",{style:{fontSize:60,fontWeight:700,lineHeight:.9},children:null!==h?`${h} / ${_}`:_}),(0,n.jsxs)("div",{style:{paddingBottom:8},children:[(0,n.jsx)("div",{style:{fontSize:15,fontWeight:600},children:null!==h?(0,t.__)("enabled for this server","acrossai-mcp-manager"):(0,t.__)("abilities available","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{fontSize:13,color:"#757575"},children:(0,t.__)("WordPress ships with only 3 by default.","acrossai-mcp-manager")})]})]}),(0,n.jsx)("ul",{style:{listStyle:"none",padding:0,marginBottom:24,border:"1px solid #ddd",borderRadius:2},children:X.map(e=>(0,n.jsxs)("li",{style:{padding:"11px 14px",borderBottom:"1px solid #f0f0f0",fontFamily:"monospace",fontSize:12},children:["• ",e]},e))}),(0,n.jsxs)("div",{style:{border:"1px solid #c4b5fd",background:"#faf9ff",padding:20,borderRadius:2,marginBottom:20},children:[(0,n.jsx)("h3",{style:{margin:"0 0 12px",fontSize:15,fontWeight:600,color:"#312e81"},children:m?(0,t.__)("Activate AcrossAI Abilities Manager to unlock 350+ abilities","acrossai-mcp-manager"):(0,t.__)("Unlock 350+ abilities with AcrossAI Abilities Manager","acrossai-mcp-manager")}),(0,n.jsx)("p",{style:{fontSize:13,lineHeight:1.65,color:"#4c1d95",margin:"0 0 16px"},children:m?(0,t.__)("The plugin is already installed on this site. Activate it now to add 350+ new abilities your AI client can use.","acrossai-mcp-manager"):(0,t.__)("Create pages, update content, install plugins, update WordPress core, manage your entire site — all from your AI client.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",gap:14,alignItems:"center"},children:[m&&u?(0,n.jsx)("a",{className:"qs-btn",href:u,style:{background:"#4f46e5",borderColor:"#4f46e5"},children:(0,t.__)("Activate Abilities Manager","acrossai-mcp-manager")}):(0,n.jsx)("a",{className:"qs-btn",href:"https://wordpress.org/plugins/acrossai-abilities-manager/",target:"_blank",rel:"noopener noreferrer",style:{background:"#4f46e5",borderColor:"#4f46e5"},children:(0,t.__)("Install from WordPress.org","acrossai-mcp-manager")}),(0,n.jsx)("a",{href:"https://acrossai.co/use-cases/",target:"_blank",rel:"noopener noreferrer",style:{color:"#4f46e5",textDecoration:"none"},children:(0,t.__)("View case studies →","acrossai-mcp-manager")})]})]}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("By default, all abilities registered by Abilities Manager can be accessed by users with the manage_options capability (admins only). You can broaden this per-ability in the Access Control step.","acrossai-mcp-manager")})]})},ee=()=>{const{saveStep:e}=z(),[a,r]=(0,s.useState)(!1),i=(0,s.useCallback)(async()=>{r(!0);try{await e(6,{enabled:!0})}finally{r(!1)}},[e]),c=(0,s.useMemo)(()=>({label:(0,t.__)("Enable & Continue","acrossai-mcp-manager"),onClick:i,isLoading:a,disabled:a}),[i,a]);return T(c),((e=!0)=>{const{setHideContinue:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(!!e),()=>a(!1)),[e,a])})(!0),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Turn on your MCP endpoint","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("One more step. Your server needs to be enabled before it will accept any MCP requests.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{className:"qs__gate-card qs__gate-card--warning",children:[(0,n.jsxs)("div",{className:"qs__gate-stat",children:[(0,n.jsx)("span",{className:"qs__gate-stat-icon","aria-hidden":"true",children:"⏻"}),(0,n.jsx)("span",{className:"qs__gate-stat-label qs__gate-stat-label--warning",children:(0,t.__)("Server is currently disabled","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{className:"qs__gate-copy",children:(0,t.__)("While disabled, this server rejects every MCP request — even from administrators. Enable it to start accepting connections from your AI clients.","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__gate-copy qs__gate-copy--muted",children:(0,t.__)("You can disable this server at any time from the server list.","acrossai-mcp-manager")})]}),(0,n.jsx)("div",{style:{marginTop:24},children:(0,n.jsx)(l,{status:"info",children:(0,s.createInterpolateElement)((0,t.__)("AcrossAI MCP Manager runs on top of the <a>MCP Adapter</a> framework and adds an admin safety layer: every server starts disabled so a half-configured server can never accidentally accept requests. Enable this one once you've reviewed its access rules and abilities.","acrossai-mcp-manager"),{a:(0,n.jsx)("a",{href:"https://github.com/wordpress/mcp-adapter",target:"_blank",rel:"noopener noreferrer"})})})})]})},se=(e=20)=>({width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,focusable:!1}),ae=({size:e})=>(0,n.jsxs)("svg",{...se(e),children:[(0,n.jsx)("polyline",{points:"4 17 10 11 4 5"}),(0,n.jsx)("line",{x1:"12",y1:"19",x2:"20",y2:"19"})]}),re=({size:e})=>(0,n.jsx)("svg",{...se(e),children:(0,n.jsx)("polyline",{points:"20 6 9 17 4 12"})}),te=[{key:"connectors",title:(0,t.__)("One-click OAuth (Connectors)","acrossai-mcp-manager"),description:(0,t.__)("Paste one URL into Claude, ChatGPT, Grok, or Gemini and approve. No config files.","acrossai-mcp-manager"),icon:({size:e})=>(0,n.jsxs)("svg",{...se(e),children:[(0,n.jsx)("path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"}),(0,n.jsx)("path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"})]})},{key:"client",title:(0,t.__)("MCP Client","acrossai-mcp-manager"),description:(0,t.__)("Paste a JSON config into Claude Desktop, VS Code, Cursor, and more.","acrossai-mcp-manager"),icon:({size:e})=>(0,n.jsx)("svg",{...se(e),children:(0,n.jsx)("path",{d:"M19.439 7.85c-.049.322.059.648.289.878l1.568 1.568c.47.47.706 1.087.706 1.704s-.235 1.233-.706 1.704l-1.611 1.611a.98.98 0 0 1-.837.276c-.47-.07-.802-.48-.968-.925a2.501 2.501 0 1 0-3.214 3.214c.446.166.855.497.925.968a.979.979 0 0 1-.276.837l-1.61 1.61a2.404 2.404 0 0 1-1.705.707 2.402 2.402 0 0 1-1.704-.706l-1.568-1.568a1.026 1.026 0 0 0-.877-.29c-.493.074-.84.504-1.02.968a2.5 2.5 0 1 1-3.237-3.237c.464-.18.894-.527.967-1.02a1.026 1.026 0 0 0-.289-.877l-1.568-1.568A2.402 2.402 0 0 1 1.998 12c0-.617.236-1.234.706-1.704L4.23 8.77c.24-.24.581-.353.917-.303.515.077.877.528 1.073 1.01a2.5 2.5 0 1 0 3.259-3.259c-.482-.196-.933-.558-1.01-1.073-.05-.336.062-.676.303-.917l1.525-1.525A2.402 2.402 0 0 1 12 1.998c.617 0 1.234.236 1.704.706l1.568 1.568c.23.23.556.338.877.29.493-.074.84-.504 1.02-.968a2.5 2.5 0 1 1 3.237 3.237c-.464.18-.894.527-.967 1.02Z"})})},{key:"npm",title:(0,t.__)("npm (one-line install)","acrossai-mcp-manager"),description:(0,t.__)("Run a single npx command — no config files, no JSON.","acrossai-mcp-manager"),icon:ae},{key:"wpcli",title:(0,t.__)("WP-CLI (local subprocess)","acrossai-mcp-manager"),description:(0,t.__)("Best for CI or local dev. No network credentials transmitted.","acrossai-mcp-manager"),icon:ae}],ne=()=>{const{state:e,saveStep:a}=z(),r=e.wizardState.method,[i,l]=(0,s.useState)(null);R(null!==r);const c=(0,s.useCallback)(async e=>{l(e);try{await a(7,{method:e})}finally{l(null)}},[a]);return(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("How do you want to connect?","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Pick a connection method. You can add more later from the server's edit page.","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, minmax(0, 1fr))",gap:12},role:"radiogroup","aria-label":(0,t.__)("Connection methods","acrossai-mcp-manager"),children:te.map(e=>{const s=e.icon,a="connectors"===e.key,l=i===e.key;return(0,n.jsx)($,{name:"qs-method",value:e.key,selected:r===e.key,onSelect:l?void 0:()=>c(e.key),title:(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s,{size:18})," ",e.title,a&&(0,n.jsx)("span",{className:"qs-card__badge",children:(0,t.__)("RECOMMENDED","acrossai-mcp-manager")})]}),subtitle:e.description},e.key)})})]})},ie=window.wp.compose,le=({variant:e="inline",children:a,title:r})=>{const[i,l]=(0,s.useState)(!1);(0,s.useEffect)(()=>{if(!i)return;const e=setTimeout(()=>l(!1),2e3);return()=>clearTimeout(e)},[i]);const c=(0,ie.useCopyToClipboard)("string"==typeof a?a:"",()=>l(!0));return"pane"===e?(0,n.jsxs)("div",{className:"qs-code qs-code--pane",children:[(0,n.jsxs)("div",{className:"qs-code__title-bar",children:[(0,n.jsx)("span",{children:r||(0,t.__)("code","acrossai-mcp-manager")}),(0,n.jsx)("button",{ref:c,type:"button",className:"qs-code__copy-btn","aria-label":(0,t.__)("Copy code to clipboard","acrossai-mcp-manager"),children:i?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy config","acrossai-mcp-manager")})]}),(0,n.jsx)("pre",{children:a})]}):(0,n.jsxs)("div",{className:"qs-code qs-code--inline",children:[(0,n.jsx)("code",{children:a}),(0,n.jsx)("button",{ref:c,type:"button",className:"qs-code__copy-btn","aria-label":(0,t.__)("Copy command to clipboard","acrossai-mcp-manager"),children:i?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy","acrossai-mcp-manager")})]})},ce=()=>{const{state:e}=z(),s=e.setupRequired;return s&&s.message?(0,n.jsxs)(l,{status:"warning",children:[(0,n.jsx)("p",{children:(0,n.jsx)("strong",{children:(0,t.__)("Connection details are not ready yet.","acrossai-mcp-manager")})}),(0,n.jsx)("p",{children:s.message}),(0,n.jsx)("p",{children:(0,t.__)("Install and activate it, then return to this step — the server is already enabled, so nothing else needs changing.","acrossai-mcp-manager")})]}):null},oe=()=>{const{state:e}=z(),a=window.acrossaiMcpQuickConnect||{},r=e.methods.ai_connectors||[],[i,c]=(0,s.useState)(r[0]?r[0].slug:""),o=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),d=r.find(e=>e.slug===i),p=o?`${a.siteUrl||""}/wp-json/${o.route_full}`:"",m=e.methods.ai_connector_instructions||{},u=d&&m[d.slug]||"",g=u?u.replaceAll("__ACROSSAI_MCP_URL__",String(p).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")):"";return(e=>{const{setBelowFooter:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(e||null),()=>a(null)),[e,a])})((0,s.useMemo)(()=>o&&0!==r.length&&g?(0,n.jsx)("div",{className:"acrossai-mcp-connector-panel__setup-embed",dangerouslySetInnerHTML:{__html:g}}):null,[o,r.length,g])),o?0===r.length?(0,n.jsx)(l,{status:"info",children:(0,t.__)("No AI connectors are available on this site.","acrossai-mcp-manager")}):(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("div",{role:"tablist","aria-label":(0,t.__)("Connector providers","acrossai-mcp-manager"),style:{display:"flex",gap:8,marginBottom:16,flexWrap:"wrap"},children:r.map(e=>{const s=e.slug===i;return(0,n.jsx)("button",{type:"button",role:"tab","aria-selected":s,onClick:()=>c(e.slug),className:s?"qs-btn":"qs-btn qs-btn--secondary",children:e.name||e.slug},e.slug)})}),d&&(0,n.jsxs)("div",{children:[(0,n.jsx)("h3",{style:{margin:"0 0 12px",fontSize:16},children:d.name||d.slug}),(0,n.jsx)("p",{style:{fontSize:13,color:"#757575",marginBottom:8},children:(0,t.__)("MCP URL to paste into your AI client:","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:p}),!g&&(0,n.jsx)(l,{status:"info",children:(0,t.__)("This connector supports Dynamic Client Registration only — paste the MCP URL above into your AI client and it will register itself. No manual credentials to generate.","acrossai-mcp-manager")})]})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},de=()=>{const{state:e}=z(),a=e.methods.clients||[],[i,c]=(0,s.useState)(a[0]?a[0].slug:""),[o,d]=(0,s.useState)(!1),[p,m]=(0,s.useState)(""),[u,g]=(0,s.useState)(null),[_,h]=(0,s.useState)(!1);(0,s.useEffect)(()=>{m(""),g(null),h(!1)},[i]),(0,s.useEffect)(()=>{if(!_)return;const e=setTimeout(()=>h(!1),2e3);return()=>clearTimeout(e)},[_]);const v=(0,ie.useCopyToClipboard)(p,()=>h(!0)),b=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),x=(0,s.useMemo)(()=>a.find(e=>e.slug===i),[a,i]),y=(0,s.useCallback)(async()=>{if(b&&x){d(!0),g(null),m("");try{const e=await r()({path:"/acrossai-mcp-manager/v1/generate-app-password",method:"POST",data:{server_id:b.id,name:`Quick Edit - ${x.name||x.slug}`}});e&&e.password?m(String(e.password)):g((0,t.__)("Password generation succeeded but the response was malformed.","acrossai-mcp-manager"))}catch(e){g(e&&e.message||(0,t.__)("Could not generate the Application Password.","acrossai-mcp-manager"))}finally{d(!1)}}},[b,x]);if(!b)return(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")});if(0===a.length)return(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No MCP clients registered on this site.","acrossai-mcp-manager")});const f=(0,s.useMemo)(()=>{let e=x&&x.config?"string"==typeof x.config?x.config:JSON.stringify(x.config,null,2):JSON.stringify(x||{},null,2);return p&&(e=e.split("(paste generated password here)").join(p)),e},[x,p]),w=x?`json · ${x.name||x.slug}`:"json";return(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("div",{style:{marginBottom:12},children:(0,n.jsx)("span",{style:{fontSize:11,fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase",color:"#757575"},children:(0,t.__)("Choose your client","acrossai-mcp-manager")})}),(0,n.jsx)("div",{role:"tablist","aria-label":(0,t.__)("MCP clients","acrossai-mcp-manager"),style:{display:"flex",gap:7,flexWrap:"wrap",marginBottom:16},children:a.map(e=>{const s=e.slug===i;return(0,n.jsx)("button",{type:"button",role:"tab","aria-selected":s,onClick:()=>c(e.slug),className:s?"qs-btn":"qs-btn qs-btn--secondary",children:e.name||e.slug},e.slug)})}),(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 1","acrossai-mcp-manager")}),(0,t.__)("Generate the password","acrossai-mcp-manager")]}),(0,n.jsxs)("div",{className:"qs-step-body qs-generate-section",children:[(0,n.jsx)("button",{type:"button",className:"qs-btn qs-generate-section__btn",onClick:y,disabled:o,children:o?(0,t.__)("Generating…","acrossai-mcp-manager"):(0,t.__)("Generate New Application Password","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs-generate-section__desc",children:(0,t.__)("Creates a one-time password via WordPress Application Passwords. Shown only once — store it safely.","acrossai-mcp-manager")}),p&&(0,n.jsxs)("div",{className:"qs-generate-section__reveal",children:[(0,n.jsxs)("div",{className:"qs-generate-section__reveal-row",children:[(0,n.jsx)("input",{type:"text",readOnly:!0,value:p,className:"qs-generate-section__reveal-input","aria-label":(0,t.__)("Generated Application Password","acrossai-mcp-manager")}),(0,n.jsx)("button",{ref:v,type:"button",className:"qs-btn qs-btn--secondary",children:_?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{className:"qs-generate-section__reveal-warning",children:(0,t.__)("Shown once. The config below now includes this password — copy that to grab both at once.","acrossai-mcp-manager")})]}),u&&(0,n.jsx)("div",{style:{marginTop:12},children:(0,n.jsx)(l,{status:"error",children:u})})]})]}),x?.meta?.config_file&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 2","acrossai-mcp-manager")}),(0,t.__)("Open the config file","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("input",{type:"text",readOnly:!0,value:x.meta.config_file,className:"qs-meta-input qs-meta-input--full","aria-label":(0,t.__)("Config File path","acrossai-mcp-manager")})})]}),x?.meta?.top_level_key&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 3","acrossai-mcp-manager")}),(0,t.__)("Locate the top-level key","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("input",{type:"text",readOnly:!0,value:`"${x.meta.top_level_key}"`,className:"qs-meta-input qs-meta-input--full","aria-label":(0,t.__)("Top-Level Key","acrossai-mcp-manager")})})]}),(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 4","acrossai-mcp-manager")}),(0,t.__)("Copy this config and paste it under the top-level key","acrossai-mcp-manager")]}),(0,n.jsxs)("div",{className:"qs-step-body",children:[window.acrossaiMcpQuickConnect?.tlsBypass?.enabled&&(0,n.jsx)("div",{style:{marginBottom:12},children:(0,n.jsxs)(l,{status:"warning",children:[window.acrossaiMcpQuickConnect.tlsBypass.message," ",(0,n.jsx)("a",{href:window.acrossaiMcpQuickConnect.tlsBypass.docUrl,target:"_blank",rel:"noopener noreferrer",children:window.acrossaiMcpQuickConnect.tlsBypass.linkText})]})}),(0,n.jsx)(le,{variant:"pane",title:w,children:f})]})]}),x?.restartStep&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 5","acrossai-mcp-manager")}),(0,t.__)("Restart the MCP client","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("p",{style:{margin:0},children:x.restartStep})})]}),(0,n.jsx)("div",{style:{marginTop:20},children:(0,n.jsx)(l,{status:"info",children:(0,t.__)("The generated password belongs to your current WordPress user. Access Control still applies to every MCP request, so a user who is not allowed for this server will receive an access denied response even if they have a saved config.","acrossai-mcp-manager")})})]})},pe=()=>{const{state:e}=z(),a=window.acrossaiMcpQuickConnect||{},r=e.methods.npm||[],i=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]);return i?0===r.length?(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No npm methods registered.","acrossai-mcp-manager")}):(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("span",{style:{display:"block",fontSize:11,fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase",color:"#757575",marginBottom:8},children:(0,t.__)("Command","acrossai-mcp-manager")}),r.map((e,s)=>{const r=e.command||`npx -y @acrossai/mcp-manager --siteurl=${a.siteUrl} --server=${i.slug}`;return(0,n.jsx)(le,{variant:"inline",children:r},e.slug||s)}),(0,n.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:12,marginTop:20,marginBottom:20},children:[(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16},children:[(0,n.jsx)("strong",{style:{flex:"0 0 120px"},children:(0,t.__)("Site URL","acrossai-mcp-manager")}),(0,n.jsx)("code",{style:{background:"#f0f0f0",padding:"3px 8px",borderRadius:2,fontSize:12},children:a.siteUrl})]}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16},children:[(0,n.jsx)("strong",{style:{flex:"0 0 120px"},children:(0,t.__)("Server","acrossai-mcp-manager")}),(0,n.jsx)("code",{style:{background:"#f0f0f0",padding:"3px 8px",borderRadius:2,fontSize:12},children:i.slug})]})]}),(0,n.jsx)("p",{style:{fontSize:12,color:"#757575",lineHeight:1.5},children:(0,t.__)("The CLI prompts for an Application Password on first run and stores it in your OS keychain.","acrossai-mcp-manager")})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},me=()=>{const{state:e}=z(),a=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]);return a?(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("h3",{style:{margin:"0 0 6px",fontSize:16},children:(0,t.__)("STDIO Transport (Local / Subprocess Mode)","acrossai-mcp-manager")}),(0,n.jsx)("p",{style:{fontSize:13,color:"#757575",lineHeight:1.55,marginBottom:20},children:(0,t.__)("MCP clients can also connect by launching WP-CLI as a subprocess instead of calling the HTTP endpoint. Ideal for local WordPress installs — no credentials transmitted over the network.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{marginBottom:16},children:[(0,n.jsx)("strong",{children:(0,t.__)("List all registered MCP servers","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:"wp mcp-adapter list"})]}),(0,n.jsxs)("div",{style:{marginBottom:16},children:[(0,n.jsx)("strong",{children:(0,t.__)("Start the MCP server as a subprocess","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:`wp mcp-adapter serve --server=${a.slug} --user=admin`})]}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("Choose STDIO for local dev + CI. Choose HTTP (via the MCP Client or Connectors path) when the client is a hosted app that can't launch subprocesses on your machine.","acrossai-mcp-manager")})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},ue={connectors:"One-click OAuth (Connectors)",client:"MCP Client (npx bridge)",npm:"npm CLI",wpcli:"WP-CLI (STDIO)"},ge=()=>{const{state:e,complete:a,refetch:r}=z(),i=v(),l=window.acrossaiMcpQuickConnect||{};(0,s.useEffect)(()=>{a()},[]);const c=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),o=[{label:(0,t.__)("Server","acrossai-mcp-manager"),value:c?c.name:"—"},{label:(0,t.__)("Access","acrossai-mcp-manager"),value:e.wizardState.access_saved?(0,t.__)("Rule configured","acrossai-mcp-manager"):(0,t.__)("Administrators only (default)","acrossai-mcp-manager")},{label:(0,t.__)("Abilities","acrossai-mcp-manager"),value:null!==e.abilities.enabledForServer&&e.abilities.enabledForServer>0?/* translators: 1: enabled ability count, 2: total available */ /* translators: 1: enabled ability count, 2: total available */
     2(0,t.__)("Step %1$d of %2$d, %3$s","acrossai-mcp-manager").replace("%1$d",String(a)).replace("%2$d",String(r)).replace("%3$s",s);b.current.textContent="";const i=setTimeout(()=>{b.current&&(b.current.textContent=n)},100);return()=>clearTimeout(i)},[e,a,r]);const x=Math.min(100,Math.max(0,Math.round(a/r*100))),y="1"===e||"done"===e,f="done"===e,w=["10","11","12","13"].includes(e)?(0,t.__)("Finish","acrossai-mcp-manager"):(0,t.__)("Continue","acrossai-mcp-manager"),j=o?[].concat(o).filter(Boolean):[],C=j.find(e=>e.isLoading),S=i||!!C;return(0,n.jsxs)(n.Fragment,{children:[S&&h.iconUrl&&(0,n.jsxs)("div",{className:"qs__initial-loading qs__initial-loading--overlay",role:"alert","aria-live":"assertive","aria-busy":"true",children:[(0,n.jsx)("img",{className:"qs__initial-loading-icon",src:h.iconUrl,alt:"","aria-hidden":"true"}),(0,n.jsx)("span",{className:"qs__sr-only",children:C?.label?C.label:(0,t.__)("Saving…","acrossai-mcp-manager")})]}),(0,n.jsx)("div",{className:"qs__progress",role:"progressbar","aria-valuenow":a,"aria-valuemin":1,"aria-valuemax":r,"aria-label":(0,t.__)("Wizard progress","acrossai-mcp-manager"),children:(0,n.jsx)("span",{className:"qs__progress-fill",style:{width:`${x}%`}})}),(0,n.jsxs)("header",{className:"qs__header",children:[h.logoUrl&&(0,n.jsx)("img",{className:"qs__header-logo",src:h.logoUrl,alt:"AcrossAI"}),(0,n.jsx)("span",{className:"qs__header-title",children:(0,t.__)("Connect","acrossai-mcp-manager")}),(0,n.jsx)("a",{className:"qs__header-consult",href:"https://acrossai.co/consultations/",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("Free Consultations ↗","acrossai-mcp-manager")}),!f&&(0,n.jsx)("a",{className:"qs__header-exit",href:"#",onClick:e=>{e.preventDefault(),g?.()},children:(0,t.__)("Exit setup","acrossai-mcp-manager")})]}),(0,n.jsxs)("div",{className:"qs__content",ref:v,children:[_,!f&&(()=>{const e=y||S,s=!l||S||j.some(e=>e.disabled);return(0,n.jsxs)("footer",{className:"qs__footer",children:[(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--secondary",disabled:e,"aria-disabled":e,onClick:e?void 0:m,children:(0,t.__)("Back","acrossai-mcp-manager")}),!d&&(0,n.jsx)("button",{type:"button",className:j.length?"qs-btn qs-btn--secondary":"qs-btn","aria-disabled":s,onClick:s?void 0:u,children:w}),j.map(e=>{const s=!!(a=e).disabled||!!a.isLoading;var a;const r="secondary"===e.variant?"qs-btn qs-btn--secondary":"qs-btn";return e.href?(0,n.jsx)("a",{className:r,href:e.href,target:e.target||"_self",rel:"_blank"===e.target?"noopener noreferrer":void 0,"aria-disabled":s,onClick:e.onClick,children:e.label},e.label):(0,n.jsx)("button",{type:"button",className:r,"aria-disabled":s,onClick:s?void 0:e.onClick,children:e.label},e.label)})]})})(),!f&&p]}),(0,n.jsx)("div",{className:"qs__sr-only",ref:b,"aria-live":"polite","aria-atomic":"true"})]})},d=window.wp.url,p=["1","2","3","4","5","6","7","10","11","12","13","done"],m=(e,s)=>!!("2"===e&&s.skipCreate||"4"===e&&s.skipAbilitiesGate||"5"===e&&s.skipAbilities||"6"===e&&s.skipEnable||"10"===e&&s.skipConnectorsDetail||"11"===e&&s.skipClient||"12"===e&&s.skipNpm||"13"===e&&s.skipWpcli),u=()=>{const e=window.location.search||"",s=(0,d.getQueryArg)(e,"step"),a=(0,d.getQueryArg)(e,"method"),r=(0,d.getQueryArg)(e,"mode"),t=(0,d.getQueryArg)(e,"server"),n=t?parseInt(t,10):NaN;return{step:void 0===s||""===s?"1":String(s),method:void 0===a||""===a?null:String(a),mode:void 0===r||""===r?null:String(r),server:Number.isFinite(n)&&n>0?n:null}},g=(e,s,a,r)=>{let t=window.location.pathname+window.location.search;return t=(0,d.addQueryArgs)(t,{step:e}),t=s?(0,d.addQueryArgs)(t,{method:s}):(0,d.removeQueryArgs)(t,"method"),t=a?(0,d.addQueryArgs)(t,{mode:a}):(0,d.removeQueryArgs)(t,"mode"),t=r?(0,d.addQueryArgs)(t,{server:r}):(0,d.removeQueryArgs)(t,"server"),t},_="acrossai-mcp-qs-nav",h=()=>{"undefined"!=typeof window&&"function"==typeof CustomEvent&&window.dispatchEvent(new CustomEvent(_))},v=()=>{const[e,a]=(0,s.useState)(u);(0,s.useEffect)(()=>{const e=()=>a(u());return window.addEventListener("popstate",e),window.addEventListener(_,e),()=>{window.removeEventListener("popstate",e),window.removeEventListener(_,e)}},[]);const r=(0,s.useCallback)((e,s=null,r=null)=>{if(!p.includes(e))return;const t=u(),n=g(e,s,r,t.server);window.history.pushState({},"",n),a({step:e,method:s,mode:r,server:t.server}),h()},[]),t=(0,s.useCallback)(e=>{const s=u(),r={...s,mode:e||null},t=g(s.step,s.method,r.mode,s.server);window.history.pushState({},"",t),a(r),h()},[]),n=(0,s.useCallback)(e=>{const s=Number.isFinite(e)&&e>0?e:null,r=u();if(r.server===s)return;const t=g(r.step,r.method,r.mode,s);window.history.replaceState({},"",t),a({...r,server:s}),h()},[]),i=(0,s.useCallback)(({skips:s={}}={})=>{const a=p.indexOf(e.step);if(-1===a||a>=p.length-1)return;let t=a+1;for(;t<p.length-1&&m(p[t],s);)t+=1;r(p[t],null)},[e.step,r]),l=(0,s.useCallback)(({skips:s={}}={})=>{const a=p.indexOf(e.step);if(a<=0)return;let t=a-1;for(;t>0&&m(p[t],s);)t-=1;r(p[t],null)},[e.step,r]),c=(0,s.useCallback)(()=>{const e=(window.acrossaiMcpQuickConnect||{}).adminUrl||"/wp-admin/admin.php?page=acrossai_mcp_manager";window.location.href=e},[]);return(0,s.useMemo)(()=>({step:e.step,method:e.method,mode:e.mode,server:e.server,goTo:r,setMode:t,setServer:n,advance:i,back:l,exit:c}),[e.step,e.method,e.mode,e.server,r,t,n,i,l,c])},b={status:"idle",error:null,servers:[],abilities:{total:0,enabledForServer:null,hasManagerPlugin:!1},plugins:{abilitiesManager:"missing"},methods:{npm:[],clients:[],ai_connectors:[]},wizardState:{current_step:1,server_id:null,access_saved:!1,abilities_saved:!1,enabled:!1,method:null,created_at:null}},x="HYDRATE_START",y="HYDRATE_SUCCESS",f="HYDRATE_ERROR",w="SAVE_STEP_START",j="SAVE_STEP_SUCCESS",C="SAVE_STEP_ERROR",S="COMPLETE_START",k="COMPLETE_SUCCESS",N="CLEAR_ERROR",q=(e,s)=>{switch(s.type){case x:return{...e,status:"loading",error:null};case y:{const a=s.payload||{};return{...e,status:"ready",error:null,servers:Array.isArray(a.servers)?a.servers:[],abilities:a.abilities||e.abilities,plugins:a.plugins||e.plugins,methods:a.methods||e.methods,wizardState:{...e.wizardState,...a.wizardState||{}}}}case f:return{...e,status:"error",error:s.payload};case w:return{...e,status:"saving",error:null,wizardState:{...e.wizardState,...s.optimistic||{}}};case j:{const a=s.payload||{};return{...e,status:"ready",error:null,servers:Array.isArray(a.servers)?a.servers:e.servers,abilities:a.abilities||e.abilities,wizardState:{...e.wizardState,...a.wizardState||{}}}}case C:return{...e,status:"error",error:s.payload.error,wizardState:s.payload.rollbackState||e.wizardState};case S:return{...e,status:"saving",error:null};case k:case N:return{...e,status:"ready",error:null};default:return e}},A=e=>{if(e&&"object"==typeof e){const s=e.data?.status||e.status;if(403===s)return{code:"session_expired",message:(0,t.__)("Your session has expired. Please reload the page to continue.","acrossai-mcp-manager")};if(401===s)return{code:"not_authorized",message:(0,t.__)("You are no longer signed in. Please reload the page.","acrossai-mcp-manager")};if(e.message)return{code:e.code||"error",message:String(e.message)}}return{code:"network_error",message:(0,t.__)("Something went wrong. Please try again.","acrossai-mcp-manager")}},M=(0,s.createContext)(null),E=({children:e})=>{const[a,t]=(0,s.useReducer)(q,b),i=(0,s.useRef)("");if(!i.current){const e=window.acrossaiMcpQuickConnect||{};i.current=e.restUrl||"/wp-json/acrossai-mcp-manager/v1/quick-connect"}const l=(0,s.useCallback)(async()=>{t({type:x});try{const e=new URLSearchParams(window.location.search).get("server"),s=e?`${i.current}/state?server_id=${encodeURIComponent(e)}`:`${i.current}/state`,a=await r()({url:s,method:"GET"});return t({type:y,payload:a}),a}catch(e){return t({type:f,payload:A(e)}),null}},[]),c=(0,s.useCallback)(async(e,s={})=>{const n=a.wizardState,l={current_step:e,...s};t({type:w,optimistic:l});try{const a=await r()({url:`${i.current}/step`,method:"POST",data:{step:e,data:s}});return t({type:j,payload:a}),a}catch(e){return t({type:C,payload:{error:A(e),rollbackState:n}}),null}},[a.wizardState]),o=(0,s.useCallback)(async()=>{t({type:S});try{return await r()({url:`${i.current}/complete`,method:"POST"}),t({type:k}),!0}catch(e){return t({type:f,payload:A(e)}),!1}},[]),d=(0,s.useCallback)(()=>t({type:N}),[]);(0,s.useEffect)(()=>{const e=()=>{"ready"===a.status&&l()},s=()=>{"visible"===document.visibilityState&&e()};return window.addEventListener("focus",e),document.addEventListener("visibilitychange",s),window.addEventListener("popstate",e),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",s),window.removeEventListener("popstate",e)}},[l,a.status]);const p={state:a,isLoading:"loading"===a.status||"saving"===a.status,error:a.error,refetch:l,saveStep:c,complete:o,clearError:d};return(0,n.jsx)(M.Provider,{value:p,children:e})},z=()=>{const e=(0,s.useContext)(M);if(!e)throw new Error("useWizardState must be used within <WizardStateProvider>");return e},P=(0,s.createContext)({setCanAdvance:()=>{},setBeforeAdvance:()=>{},setFooterAction:()=>{},setHideContinue:()=>{},setBelowFooter:()=>{},advance:()=>{}}),T=e=>{const{setFooterAction:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(e||null),()=>a(null)),[e,a])},R=(e,a=null)=>{const{setCanAdvance:r,setBeforeAdvance:t}=(0,s.useContext)(P);(0,s.useEffect)(()=>(r(!!e),t(()=>a),()=>{r(!0),t(()=>null)}),[e,a,r,t])},$=({selected:e=!1,onSelect:s,title:a,subtitle:r,badge:t=null,children:i=null,name:l="qs-card",value:c=""})=>(0,n.jsxs)("label",{className:"qs-card"+(e?" qs-card--selected":""),role:"radio","aria-checked":e,tabIndex:0,onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),s?.())},children:[(0,n.jsx)("input",{type:"radio",name:l,value:c,checked:e,onChange:()=>s?.(),style:{position:"absolute",opacity:0,pointerEvents:"none"},tabIndex:-1}),(0,n.jsx)("span",{className:"qs-card__radio","aria-hidden":"true"}),(0,n.jsxs)("div",{className:"qs-card__body",children:[(0,n.jsxs)("div",{className:"qs-card__title",children:[a,t]}),r&&(0,n.jsx)("div",{className:"qs-card__subtitle",children:r}),i]})]}),I=["acrossai-mcp-server","mcp-adapter-default-server"],L=I[0],B=()=>{const{state:e,saveStep:a}=z(),r=e.wizardState.server_id,i=!!e.wizardState.create_intent;(0,s.useEffect)(()=>{"ready"!==e.status||0!==e.servers.length||i||a(1,{create_intent:!0})},[e.status,e.servers.length,i,a]),(0,s.useEffect)(()=>{if("ready"!==e.status||null!==r||i||0===e.servers.length)return;const s=I.reduce((s,a)=>s||e.servers.find(e=>e.slug===a),null)||e.servers[0];s&&a(1,{server_id:s.id})},[e.status,e.servers,r,i,a]),R(null!==r||i);const l=(0,s.useMemo)(()=>{const s=e.servers||[];return[...s.filter(e=>e.slug===L),...s.filter(e=>e.slug!==L)]},[e.servers]);return(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Which server should AI connect to?","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Pick an existing MCP server, or create a new one for this setup.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{role:"radiogroup","aria-label":(0,t.__)("MCP servers","acrossai-mcp-manager"),children:[l.map(e=>(0,n.jsx)($,{name:"qs-server-pick",value:String(e.id),selected:!i&&r===e.id,onSelect:()=>(async e=>{await a(1,{server_id:e})})(e.id),title:e.name,subtitle:(0,n.jsx)("code",{children:e.route_full}),badge:(0,n.jsxs)(n.Fragment,{children:[e.slug===L?(0,n.jsx)("span",{className:"qs-card__badge qs-card__badge--recommended",children:(0,t.__)("Recommended","acrossai-mcp-manager")}):null,e.enabled?null:(0,n.jsx)("span",{className:"qs-card__badge qs-card__badge--inactive",children:(0,t.__)("Inactive","acrossai-mcp-manager")})]})},e.id)),(0,n.jsx)($,{name:"qs-server-pick",value:"__create__",selected:i,onSelect:async()=>{await a(1,{create_intent:!0})},title:(0,t.__)("+ Create a new server","acrossai-mcp-manager"),subtitle:(0,t.__)("Set up a brand-new MCP server for this wizard.","acrossai-mcp-manager")})]})]})},U=e=>String(e).toLowerCase().replace(/[^a-z0-9\-_]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-"),W=()=>{const{saveStep:e}=z(),[a,r]=(0,s.useState)({server_name:"",server_slug:"",description:"",server_route_namespace:"mcp",server_route:"",server_version:"v1.0.0"}),[i,l]=(0,s.useState)(!1),[c,o]=(0,s.useState)(!1),[d,p]=(0,s.useState)(null),m=(0,s.useCallback)(async()=>{if(p(null),!a.server_name.trim())return p((0,t.__)("Server name is required.","acrossai-mcp-manager")),!1;const s=await e(2,{new_server:a});return!!(s&&s.wizardState&&s.wizardState.server_id)},[a,e]);return R(a.server_name.trim().length>0,m),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Create a new MCP server","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Fill in a name — the rest is auto-filled. Click Continue when you're done.","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Name","acrossai-mcp-manager")}),(0,n.jsx)("span",{style:{color:"#cc1818",marginLeft:4},children:"*"}),(0,n.jsx)("input",{type:"text",value:a.server_name,onChange:e=>{return s=e.target.value,void r(e=>({...e,server_name:s,server_slug:i?e.server_slug:U(s),server_route:c?e.server_route:U(s)}));var s},required:!0,style:{display:"block",width:"100%",padding:"8px",marginTop:4}})]})}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Slug","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_slug,onChange:e=>{return s=e.target.value,l(!0),void r(e=>({...e,server_slug:s,server_route:c?e.server_route:U(s)}));var s},style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]})}),(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)("label",{children:[(0,n.jsx)("strong",{children:(0,t.__)("Description","acrossai-mcp-manager")}),(0,n.jsx)("textarea",{value:a.description,onChange:e=>r(s=>({...s,description:e.target.value})),rows:3,style:{display:"block",width:"100%",padding:"8px",marginTop:4}})]})}),(0,n.jsxs)("div",{style:{display:"flex",gap:12,marginBottom:16},children:[(0,n.jsxs)("label",{style:{flex:1},children:[(0,n.jsx)("strong",{children:(0,t.__)("Route namespace","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_route_namespace,onChange:e=>r(s=>({...s,server_route_namespace:e.target.value})),style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]}),(0,n.jsxs)("label",{style:{flex:1},children:[(0,n.jsx)("strong",{children:(0,t.__)("Route","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_route,onChange:e=>{o(!0),r(s=>({...s,server_route:e.target.value}))},style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]}),(0,n.jsxs)("label",{style:{flex:"0 0 120px"},children:[(0,n.jsx)("strong",{children:(0,t.__)("Version","acrossai-mcp-manager")}),(0,n.jsx)("input",{type:"text",value:a.server_version,onChange:e=>r(s=>({...s,server_version:e.target.value})),style:{display:"block",width:"100%",padding:"8px",marginTop:4,fontFamily:"monospace"}})]})]}),d&&(0,n.jsx)("div",{style:{color:"#cc1818",marginBottom:16},role:"alert",children:d})]})},O=[{value:"",label:"No user access added by admin"},{value:"everyone",label:"Public (no login required)"},{value:"authenticated",label:"Any logged-in user"}];function F({providers:e,value:s,onChange:a}){const r=e.filter(e=>!1!==e.available);return(0,n.jsxs)("select",{className:"wpb-ac__select",value:s,onChange:e=>a(e.target.value),children:[O.map(e=>(0,n.jsx)("option",{value:e.value,children:e.label},e.value)),r.map(e=>(0,n.jsx)("option",{value:e.id,children:e.label},e.id))]})}const Q={wp_role:"Select which WordPress Role values may access this resource. Leave all unchecked to deny everyone (except administrators).",wp_capability:"Select which WordPress capabilities grant access. Users holding any of the checked capabilities are allowed. Administrators always have access.",bb_profile_type:"Select which BuddyBoss profile types grant access. Users assigned to any of the checked profile types are allowed. Administrators always have access.",mepr_membership:"Select which MemberPress memberships grant access. Users with an active subscription to any of the checked memberships are allowed. Administrators always have access."};function D({providerId:e,options:s,selectedOptions:a,onToggle:r}){const t=Q[e]||null;return(0,n.jsxs)("div",{className:"wpb-ac__options-panel",children:[t&&(0,n.jsx)("p",{className:"wpb-ac__panel-description",children:t}),(0,n.jsx)("ul",{className:"wpb-ac__checkbox-list",children:s.map(e=>(0,n.jsx)("li",{className:"wpb-ac__checkbox-item",children:(0,n.jsxs)("label",{children:[(0,n.jsx)("input",{type:"checkbox",value:e.id,checked:a.includes(e.id),onChange:()=>r(e.id)}),e.label]})},e.id))})]})}function H({pluginSlug:e,restApiRoot:a,selectedUsers:t,onAdd:i,onRemove:l}){const[c,o]=(0,s.useState)(""),[d,p]=(0,s.useState)([]),[m,u]=(0,s.useState)(!1),g=(0,s.useRef)(null),_=(0,s.useRef)(null);(0,s.useEffect)(()=>{const e=e=>{_.current&&!_.current.contains(e.target)&&u(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);const h=(0,s.useCallback)(s=>{if(!s.trim())return p([]),void u(!1);r()({url:`${a}/wpb-ac/v1/${e}/users?search=${encodeURIComponent(s)}`}).then(e=>{p(e||[]),u(!0)}).catch(()=>p([]))},[e,a]),v=(0,s.useCallback)(e=>{const s=e.target.value;o(s),clearTimeout(g.current),g.current=setTimeout(()=>h(s),300)},[h]),b=(0,s.useCallback)(e=>{i({id:e.id,login:e.login,display_name:e.display_name}),o(""),p([]),u(!1)},[i]),x=d.filter(e=>!t.find(s=>s.id===e.id));return(0,n.jsxs)("div",{className:"wpb-ac__user-panel",ref:_,children:[(0,n.jsx)("p",{className:"wpb-ac__panel-description",children:"Search by username or email and select one or more users. Administrators always have access regardless of this list."}),(0,n.jsxs)("div",{className:"wpb-ac__search-wrapper",children:[(0,n.jsx)("input",{type:"text",className:"wpb-ac__search-input",placeholder:"Search by username or email...",value:c,onChange:v,onFocus:()=>x.length&&u(!0)}),m&&x.length>0&&(0,n.jsx)("ul",{className:"wpb-ac__search-dropdown",children:x.map(e=>(0,n.jsxs)("li",{className:"wpb-ac__search-option",onMouseDown:()=>b(e),children:[e.display_name," (",e.login,")"]},e.id))})]}),t.length>0&&(0,n.jsx)("div",{className:"wpb-ac__user-tags",children:t.map(e=>(0,n.jsxs)("span",{className:"wpb-ac__user-tag",children:[e.display_name," (",e.login,")",(0,n.jsx)("button",{type:"button",className:"wpb-ac__tag-remove",onClick:()=>l(e.id),"aria-label":`Remove ${e.display_name}`,children:"×"})]},e.id))})]})}function Y({pluginSlug:e,namespace:a,resourceKey:t,restApiRoot:i,nonce:l,title:c="Access Control",description:o="Control which users are allowed to connect to this MCP server. Administrators always have access regardless of this setting.",saveLabel:d="Save Access Control",onSave:p,hideSaveButton:m=!1,hideHeader:u=!1,onChange:g}){const[_,h]=(0,s.useState)(!0),[v,b]=(0,s.useState)(!1),[x,y]=(0,s.useState)(null),[f,w]=(0,s.useState)([]),[j,C]=(0,s.useState)(""),[S,k]=(0,s.useState)([]),[N,q]=(0,s.useState)([]),A=a.split("/").map(encodeURIComponent).join("%2F"),M=(0,s.useCallback)(e=>{const s=e.map(e=>`include[]=${e}`).join("&");r()({url:`${i}/wp/v2/users?${s}&per_page=100`}).then(e=>{q(e.map(e=>({id:String(e.id),login:e.slug,display_name:e.name})))}).catch(()=>{q(e.map(e=>({id:e,login:e,display_name:e})))})},[i]);(0,s.useEffect)(()=>{if(!t)return void h(!1);h(!0),y(null),w([]),C(""),k([]),q([]);let s=!1;return Promise.all([r()({url:`${i}/wpb-ac/v1/${e}/providers`}),r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`})]).then(([e,a])=>{if(s)return;w(e);const r=a.key||"",t=a.value||[];C(r),k(t),"wp_user"===r&&t.length>0&&M(t)}).catch(()=>{}).finally(()=>{s||h(!1)}),()=>{s=!0}},[e,i,A,t]);const E=(0,s.useCallback)(e=>{C(e),k([]),q([]),y(null)},[]),z=(0,s.useCallback)(e=>{k(s=>s.includes(e)?s.filter(s=>s!==e):[...s,e])},[]),P=(0,s.useCallback)(e=>{q(s=>s.find(s=>s.id===e.id)?s:[...s,e]),k(s=>s.includes(e.id)?s:[...s,e.id])},[]),T=(0,s.useCallback)(e=>{q(s=>s.filter(s=>s.id!==e)),k(s=>s.filter(s=>s!==e))},[]),R=(0,s.useCallback)(async()=>{b(!0),y(null);try{""===j?await r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`,method:"DELETE"}):await r()({url:`${i}/wpb-ac/v1/${e}/rules/${A}/${t}`,method:"PUT",data:{ac_key:j,ac_options:S}}),y({type:"success",message:"Access control saved."}),p?.(j,S)}catch(e){y({type:"error",message:e?.message||"Failed to save."})}finally{b(!1)}},[j,S,e,A,t,i,p]);(0,s.useEffect)(()=>{_||g?.(j,S)},[j,S,_]);const $=f.find(e=>e.id===j)||null,I=$&&"wp_user"!==$.id&&$.options?.length>0,L="wp_user"===j;return _?(0,n.jsx)("div",{className:"wpb-ac wpb-ac--loading",children:"Loading…"}):(0,n.jsxs)("div",{className:"wpb-ac",children:[!u&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("h2",{className:"wpb-ac__title",children:c}),(0,n.jsx)("p",{className:"wpb-ac__description",children:o})]}),(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:"Who can access"}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(F,{providers:f,value:j,onChange:E})})]}),I&&(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:$.label}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(D,{providerId:j,options:$.options,selectedOptions:S,onToggle:z})})]}),L&&(0,n.jsxs)("div",{className:"wpb-ac__row",children:[(0,n.jsx)("div",{className:"wpb-ac__label",children:$?.label||"Users"}),(0,n.jsx)("div",{className:"wpb-ac__control",children:(0,n.jsx)(H,{pluginSlug:e,restApiRoot:i,selectedUsers:N,onAdd:P,onRemove:T})})]}),x&&(0,n.jsx)("p",{className:`wpb-ac__notice wpb-ac__notice--${x.type}`,children:x.message}),!m&&(0,n.jsx)("div",{className:"wpb-ac__footer",children:(0,n.jsx)("button",{type:"button",className:"wpb-ac__save-btn",onClick:R,disabled:v,children:v?"Saving…":d})})]})}const G=({pluginSlug:e,namespace:a="acrossai-mcp-manager",resourceKey:r,restApiRoot:t="/wp-json",nonce:n="",title:i,description:l,saveLabel:c,hideSaveButton:o=!1,onChange:d,onSave:p})=>e&&r?(0,s.createElement)(Y,{pluginSlug:e,namespace:a,resourceKey:r,restApiRoot:t,nonce:n,title:i||void 0,description:l||void 0,saveLabel:c||void 0,hideSaveButton:o,onChange:d,onSave:p}):null,V=()=>{const{state:e}=z(),a=(()=>{const{advance:e}=(0,s.useContext)(P);return e})(),i=window.acrossaiMcpQuickConnect||{},[c,o]=(0,s.useState)(null),[d,p]=(0,s.useState)(!1),m=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),u=(0,s.useRef)({key:null,options:[]}),g=(0,s.useCallback)((e,s)=>{u.current={key:e,options:Array.isArray(s)?s:[]}},[]),_=(0,s.useCallback)(async()=>{if(o(null),!m||null===u.current.key||""===u.current.key)return void a();const e=i.acPluginSlug||"mcp",s=i.acNamespace||"acrossai-mcp-manager",n=`${i.restApiRoot||"/wp-json"}/wpb-ac/v1/${e}/rules/${encodeURIComponent(s)}/${m.slug}`;p(!0);try{await r()({url:n,method:"PUT",data:{ac_key:u.current.key,ac_options:u.current.options}}),a()}catch(e){o(e&&e.message||(0,t.__)("Failed to save access control. Try again.","acrossai-mcp-manager"))}finally{p(!1)}},[m,i.acPluginSlug,i.acNamespace,i.restApiRoot,a]),h=(0,s.useMemo)(()=>m?{label:(0,t.__)("Save and Continue","acrossai-mcp-manager"),onClick:_,isLoading:d,disabled:d}:null,[m,_,d]);return T(h),m?(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Who can reach this server?","acrossai-mcp-manager")}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("Only administrators can reach this server until you add an access rule below.","acrossai-mcp-manager")}),c&&(0,n.jsx)(l,{status:"error",children:c}),(0,n.jsx)(G,{pluginSlug:i.acPluginSlug||"mcp",namespace:i.acNamespace||"acrossai-mcp-manager",resourceKey:m.slug,restApiRoot:i.restApiRoot||"/wp-json",nonce:i.restNonce||"",hideSaveButton:!0,onChange:g}),(0,n.jsx)("p",{className:"qs__step-subtitle",style:{marginTop:24},children:(0,t.__)("Continue skips saving (leaves current rule as-is). Save and Continue writes your changes and moves on. You can change this anytime under the server's Access Control tab.","acrossai-mcp-manager")})]}):(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Who can reach it?","acrossai-mcp-manager")}),(0,n.jsx)("p",{children:(0,t.__)("No server selected — go back to Step 1.","acrossai-mcp-manager")})]})},K=["Blocks","Cache","Comments","Content Search","Core","Cron","Database","File Manager","Media","Plugins","Rank Math","Settings","Site Health","Themes","Users","Widgets"],J=()=>{const{state:e,refetch:a}=z(),[i,c]=(0,s.useState)(!1),[o,d]=(0,s.useState)(null),p="missing"===e.plugins.abilitiesManager,m=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id)||null,[e.servers,e.wizardState.server_id]),u=null!==m&&!1===m.type_available;R(!u);const g=(0,s.useCallback)(async()=>{c(!0),d(null);try{const e=(window.acrossaiMcpQuickConnect||{}).restUrl||"/wp-json/acrossai-mcp-manager/v1/quick-connect";await r()({url:`${e}/install-plugin`,method:"POST",data:{slug:"acrossai-abilities-manager"}}),await a()}catch(e){d(e&&e.message||(0,t.__)("Something went wrong. Try again or install the plugin manually.","acrossai-mcp-manager"))}finally{c(!1)}},[a]),_=i?p?(0,t.__)("Installing…","acrossai-mcp-manager"):(0,t.__)("Activating…","acrossai-mcp-manager"):p?(0,t.__)("Install & Continue","acrossai-mcp-manager"):(0,t.__)("Activate & Continue","acrossai-mcp-manager"),h=(0,s.useMemo)(()=>({label:_,onClick:g,isLoading:i,disabled:i}),[_,g,i]);T(h);const v=(0,n.jsxs)("span",{className:"qs__brand-mark qs__brand-mark--inline",children:[(0,n.jsx)("span",{className:"qs__brand-mark__across",children:"Across"}),(0,n.jsx)("span",{className:"qs__brand-mark__ai",children:"AI"})]}),b=(0,s.createInterpolateElement)(p?(0,t.__)("Install <brand/> Abilities Manager","acrossai-mcp-manager"):(0,t.__)("Activate <brand/> Abilities Manager","acrossai-mcp-manager"),{brand:v});return(0,n.jsxs)("div",{children:[o&&(0,n.jsx)("div",{style:{marginBottom:20},children:(0,n.jsx)(l,{status:"error",children:o})}),u&&(0,n.jsx)("div",{style:{marginBottom:20},children:(0,n.jsx)(l,{status:"warning",children:(0,t.__)("This server's type requires the AcrossAI Abilities Manager, so it cannot be enabled later in this setup without it. Install it below, or go back and choose a different server type.","acrossai-mcp-manager")})}),(0,n.jsxs)("div",{className:"qs__gate-card",children:[(window.acrossaiMcpQuickConnect||{}).logoUrl&&(0,n.jsx)("img",{className:"qs__gate-card__logo",src:window.acrossaiMcpQuickConnect.logoUrl,alt:"","aria-hidden":"true"}),(0,n.jsx)("h2",{className:"qs__step-title",children:b}),(0,n.jsxs)("div",{className:"qs__gate-categories",children:[(0,n.jsx)("p",{className:"qs__gate-categories-label",children:(0,t.__)("Includes 350+ abilities for:","acrossai-mcp-manager")}),(0,n.jsx)("ul",{className:"qs__gate-bullets qs__gate-bullets--grid",children:K.map(e=>(0,n.jsx)("li",{children:e},e))})]}),(0,n.jsx)("div",{className:"qs__gate-actions",children:(0,n.jsx)("a",{className:"qs-btn qs-btn--secondary",href:"https://wordpress.org/plugins/acrossai-abilities-manager/",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("View on WordPress.org ↗","acrossai-mcp-manager")})})]}),(0,n.jsx)("div",{style:{marginTop:24},children:(0,n.jsx)(l,{status:"info",children:(0,t.__)("You can Continue without installing — the wizard will fall back to the 3 abilities WordPress ships with. Or install the plugin now to unlock the full 350+ set. You can broaden per-ability access in the next step.","acrossai-mcp-manager")})})]})},X=["core/get-environment-info","core/get-site-info","core/get-user-info"],Z=()=>{const{state:e,saveStep:a,isLoading:r}=z(),[i,c]=(0,s.useState)(!1),o=window.acrossaiMcpQuickConnect||{},d=e.plugins.abilitiesManager,p="active"===d,m="inactive"===d,u=e.plugins.abilitiesManagerActivateUrl||"",g=e.wizardState.server_id,_=e.abilities.total,h=e.abilities.enabledForServer,v=_>0&&null!==h&&h>=_,b=(0,s.useCallback)(async()=>{c(!0);try{await a(5,{enable_all_abilities:!0})}finally{c(!1)}},[a]),x=(0,s.useMemo)(()=>p&&!v?{label:(0,t.__)("Enable all and continue","acrossai-mcp-manager"),onClick:b,isLoading:i||r,disabled:i||r}:null,[p,v,b,i,r]);return T(x),p?(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("What should AI be able to do?","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-end",gap:16,justifyContent:"center",margin:"20px 0"},children:[(0,n.jsx)("span",{style:{fontSize:60,fontWeight:700,lineHeight:.9},children:null!==h?`${h} / ${_}`:_}),(0,n.jsxs)("div",{style:{paddingBottom:8},children:[(0,n.jsx)("div",{style:{fontSize:15,fontWeight:600},children:null!==h?(0,t.__)("enabled for this server","acrossai-mcp-manager"):(0,t.__)("abilities available","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{fontSize:13,color:"#757575"},children:(0,t.__)("From AcrossAI Abilities Manager.","acrossai-mcp-manager")})]})]}),v&&(0,n.jsx)(l,{status:"success",children:(0,t.__)("All abilities enabled for this server ✓","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{display:"flex",justifyContent:"center",marginBottom:20},children:(0,n.jsx)("a",{className:"qs-btn qs-btn--secondary",href:o.adminUrl&&g?`${o.adminUrl}&action=edit&server=${g}&tab=abilities`:"#",target:"_blank",rel:"noopener noreferrer",children:(0,t.__)("Configure abilities one-by-one ↗","acrossai-mcp-manager")})}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("By default, all abilities registered by Abilities Manager can be accessed by users with the manage_options capability (admins only). You can broaden this per-ability in the Access Control step.","acrossai-mcp-manager")})]}):(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("What should AI be able to do?","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-end",gap:16,justifyContent:"center",margin:"20px 0"},children:[(0,n.jsx)("span",{style:{fontSize:60,fontWeight:700,lineHeight:.9},children:null!==h?`${h} / ${_}`:_}),(0,n.jsxs)("div",{style:{paddingBottom:8},children:[(0,n.jsx)("div",{style:{fontSize:15,fontWeight:600},children:null!==h?(0,t.__)("enabled for this server","acrossai-mcp-manager"):(0,t.__)("abilities available","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{fontSize:13,color:"#757575"},children:(0,t.__)("WordPress ships with only 3 by default.","acrossai-mcp-manager")})]})]}),(0,n.jsx)("ul",{style:{listStyle:"none",padding:0,marginBottom:24,border:"1px solid #ddd",borderRadius:2},children:X.map(e=>(0,n.jsxs)("li",{style:{padding:"11px 14px",borderBottom:"1px solid #f0f0f0",fontFamily:"monospace",fontSize:12},children:["• ",e]},e))}),(0,n.jsxs)("div",{style:{border:"1px solid #c4b5fd",background:"#faf9ff",padding:20,borderRadius:2,marginBottom:20},children:[(0,n.jsx)("h3",{style:{margin:"0 0 12px",fontSize:15,fontWeight:600,color:"#312e81"},children:m?(0,t.__)("Activate AcrossAI Abilities Manager to unlock 350+ abilities","acrossai-mcp-manager"):(0,t.__)("Unlock 350+ abilities with AcrossAI Abilities Manager","acrossai-mcp-manager")}),(0,n.jsx)("p",{style:{fontSize:13,lineHeight:1.65,color:"#4c1d95",margin:"0 0 16px"},children:m?(0,t.__)("The plugin is already installed on this site. Activate it now to add 350+ new abilities your AI client can use.","acrossai-mcp-manager"):(0,t.__)("Create pages, update content, install plugins, update WordPress core, manage your entire site — all from your AI client.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{display:"flex",gap:14,alignItems:"center"},children:[m&&u?(0,n.jsx)("a",{className:"qs-btn",href:u,style:{background:"#4f46e5",borderColor:"#4f46e5"},children:(0,t.__)("Activate Abilities Manager","acrossai-mcp-manager")}):(0,n.jsx)("a",{className:"qs-btn",href:"https://wordpress.org/plugins/acrossai-abilities-manager/",target:"_blank",rel:"noopener noreferrer",style:{background:"#4f46e5",borderColor:"#4f46e5"},children:(0,t.__)("Install from WordPress.org","acrossai-mcp-manager")}),(0,n.jsx)("a",{href:"https://acrossai.co/use-cases/",target:"_blank",rel:"noopener noreferrer",style:{color:"#4f46e5",textDecoration:"none"},children:(0,t.__)("View case studies →","acrossai-mcp-manager")})]})]}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("By default, all abilities registered by Abilities Manager can be accessed by users with the manage_options capability (admins only). You can broaden this per-ability in the Access Control step.","acrossai-mcp-manager")})]})},ee=()=>{const{saveStep:e}=z(),[a,r]=(0,s.useState)(!1),i=(0,s.useCallback)(async()=>{r(!0);try{await e(6,{enabled:!0})}finally{r(!1)}},[e]),c=(0,s.useMemo)(()=>({label:(0,t.__)("Enable & Continue","acrossai-mcp-manager"),onClick:i,isLoading:a,disabled:a}),[i,a]);return T(c),((e=!0)=>{const{setHideContinue:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(!!e),()=>a(!1)),[e,a])})(!0),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("Turn on your MCP endpoint","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("One more step. Your server needs to be enabled before it will accept any MCP requests.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{className:"qs__gate-card qs__gate-card--warning",children:[(0,n.jsxs)("div",{className:"qs__gate-stat",children:[(0,n.jsx)("span",{className:"qs__gate-stat-icon","aria-hidden":"true",children:"⏻"}),(0,n.jsx)("span",{className:"qs__gate-stat-label qs__gate-stat-label--warning",children:(0,t.__)("Server is currently disabled","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{className:"qs__gate-copy",children:(0,t.__)("While disabled, this server rejects every MCP request — even from administrators. Enable it to start accepting connections from your AI clients.","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__gate-copy qs__gate-copy--muted",children:(0,t.__)("You can disable this server at any time from the server list.","acrossai-mcp-manager")})]}),(0,n.jsx)("div",{style:{marginTop:24},children:(0,n.jsx)(l,{status:"info",children:(0,s.createInterpolateElement)((0,t.__)("AcrossAI MCP Manager runs on top of the <a>MCP Adapter</a> framework and adds an admin safety layer: every server starts disabled so a half-configured server can never accidentally accept requests. Enable this one once you've reviewed its access rules and abilities.","acrossai-mcp-manager"),{a:(0,n.jsx)("a",{href:"https://github.com/wordpress/mcp-adapter",target:"_blank",rel:"noopener noreferrer"})})})})]})},se=(e=20)=>({width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,focusable:!1}),ae=({size:e})=>(0,n.jsxs)("svg",{...se(e),children:[(0,n.jsx)("polyline",{points:"4 17 10 11 4 5"}),(0,n.jsx)("line",{x1:"12",y1:"19",x2:"20",y2:"19"})]}),re=({size:e})=>(0,n.jsx)("svg",{...se(e),children:(0,n.jsx)("polyline",{points:"20 6 9 17 4 12"})}),te=[{key:"connectors",title:(0,t.__)("One-click OAuth (Connectors)","acrossai-mcp-manager"),description:(0,t.__)("Paste one URL into Claude, ChatGPT, Grok, or Gemini and approve. No config files.","acrossai-mcp-manager"),icon:({size:e})=>(0,n.jsxs)("svg",{...se(e),children:[(0,n.jsx)("path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"}),(0,n.jsx)("path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"})]})},{key:"client",title:(0,t.__)("MCP Client","acrossai-mcp-manager"),description:(0,t.__)("Paste a JSON config into Claude Desktop, VS Code, Cursor, and more.","acrossai-mcp-manager"),icon:({size:e})=>(0,n.jsx)("svg",{...se(e),children:(0,n.jsx)("path",{d:"M19.439 7.85c-.049.322.059.648.289.878l1.568 1.568c.47.47.706 1.087.706 1.704s-.235 1.233-.706 1.704l-1.611 1.611a.98.98 0 0 1-.837.276c-.47-.07-.802-.48-.968-.925a2.501 2.501 0 1 0-3.214 3.214c.446.166.855.497.925.968a.979.979 0 0 1-.276.837l-1.61 1.61a2.404 2.404 0 0 1-1.705.707 2.402 2.402 0 0 1-1.704-.706l-1.568-1.568a1.026 1.026 0 0 0-.877-.29c-.493.074-.84.504-1.02.968a2.5 2.5 0 1 1-3.237-3.237c.464-.18.894-.527.967-1.02a1.026 1.026 0 0 0-.289-.877l-1.568-1.568A2.402 2.402 0 0 1 1.998 12c0-.617.236-1.234.706-1.704L4.23 8.77c.24-.24.581-.353.917-.303.515.077.877.528 1.073 1.01a2.5 2.5 0 1 0 3.259-3.259c-.482-.196-.933-.558-1.01-1.073-.05-.336.062-.676.303-.917l1.525-1.525A2.402 2.402 0 0 1 12 1.998c.617 0 1.234.236 1.704.706l1.568 1.568c.23.23.556.338.877.29.493-.074.84-.504 1.02-.968a2.5 2.5 0 1 1 3.237 3.237c-.464.18-.894.527-.967 1.02Z"})})},{key:"npm",title:(0,t.__)("npm (one-line install)","acrossai-mcp-manager"),description:(0,t.__)("Run a single npx command — no config files, no JSON.","acrossai-mcp-manager"),icon:ae},{key:"wpcli",title:(0,t.__)("WP-CLI (local subprocess)","acrossai-mcp-manager"),description:(0,t.__)("Best for CI or local dev. No network credentials transmitted.","acrossai-mcp-manager"),icon:ae}],ne=()=>{const{state:e,saveStep:a}=z(),r=e.wizardState.method,[i,l]=(0,s.useState)(null);R(null!==r);const c=(0,s.useCallback)(async e=>{l(e);try{await a(7,{method:e})}finally{l(null)}},[a]);return(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"qs__step-title",children:(0,t.__)("How do you want to connect?","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs__step-subtitle",children:(0,t.__)("Pick a connection method. You can add more later from the server's edit page.","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, minmax(0, 1fr))",gap:12},role:"radiogroup","aria-label":(0,t.__)("Connection methods","acrossai-mcp-manager"),children:te.map(e=>{const s=e.icon,a="connectors"===e.key,l=i===e.key;return(0,n.jsx)($,{name:"qs-method",value:e.key,selected:r===e.key,onSelect:l?void 0:()=>c(e.key),title:(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s,{size:18})," ",e.title,a&&(0,n.jsx)("span",{className:"qs-card__badge",children:(0,t.__)("RECOMMENDED","acrossai-mcp-manager")})]}),subtitle:e.description},e.key)})})]})},ie=window.wp.compose,le=({variant:e="inline",children:a,title:r})=>{const[i,l]=(0,s.useState)(!1);(0,s.useEffect)(()=>{if(!i)return;const e=setTimeout(()=>l(!1),2e3);return()=>clearTimeout(e)},[i]);const c=(0,ie.useCopyToClipboard)("string"==typeof a?a:"",()=>l(!0));return"pane"===e?(0,n.jsxs)("div",{className:"qs-code qs-code--pane",children:[(0,n.jsxs)("div",{className:"qs-code__title-bar",children:[(0,n.jsx)("span",{children:r||(0,t.__)("code","acrossai-mcp-manager")}),(0,n.jsx)("button",{ref:c,type:"button",className:"qs-code__copy-btn","aria-label":(0,t.__)("Copy code to clipboard","acrossai-mcp-manager"),children:i?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy config","acrossai-mcp-manager")})]}),(0,n.jsx)("pre",{children:a})]}):(0,n.jsxs)("div",{className:"qs-code qs-code--inline",children:[(0,n.jsx)("code",{children:a}),(0,n.jsx)("button",{ref:c,type:"button",className:"qs-code__copy-btn","aria-label":(0,t.__)("Copy command to clipboard","acrossai-mcp-manager"),children:i?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy","acrossai-mcp-manager")})]})},ce=()=>{const{state:e}=z(),s=e.setupRequired;return s&&s.message?(0,n.jsxs)(l,{status:"warning",children:[(0,n.jsx)("p",{children:(0,n.jsx)("strong",{children:(0,t.__)("Connection details are not ready yet.","acrossai-mcp-manager")})}),(0,n.jsx)("p",{children:s.message}),(0,n.jsx)("p",{children:(0,t.__)("Install and activate it, then return to this step — the server is already enabled, so nothing else needs changing.","acrossai-mcp-manager")})]}):null},oe=()=>{const{state:e}=z(),a=window.acrossaiMcpQuickConnect||{},r=e.methods.ai_connectors||[],[i,c]=(0,s.useState)(r[0]?r[0].slug:""),o=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),d=r.find(e=>e.slug===i),p=o?`${a.siteUrl||""}/wp-json/${o.route_full}`:"",m=e.methods.ai_connector_instructions||{},u=d&&m[d.slug]||"",g=u?u.replaceAll("__ACROSSAI_MCP_URL__",String(p).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")):"";return(e=>{const{setBelowFooter:a}=(0,s.useContext)(P);(0,s.useEffect)(()=>(a(e||null),()=>a(null)),[e,a])})((0,s.useMemo)(()=>o&&0!==r.length&&g?(0,n.jsx)("div",{className:"acrossai-mcp-connector-panel__setup-embed",dangerouslySetInnerHTML:{__html:g}}):null,[o,r.length,g])),o?0===r.length?(0,n.jsx)(l,{status:"info",children:(0,t.__)("No AI connectors are available on this site.","acrossai-mcp-manager")}):(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("div",{role:"tablist","aria-label":(0,t.__)("Connector providers","acrossai-mcp-manager"),style:{display:"flex",gap:8,marginBottom:16,flexWrap:"wrap"},children:r.map(e=>{const s=e.slug===i;return(0,n.jsx)("button",{type:"button",role:"tab","aria-selected":s,onClick:()=>c(e.slug),className:s?"qs-btn":"qs-btn qs-btn--secondary",children:e.name||e.slug},e.slug)})}),d&&(0,n.jsxs)("div",{children:[(0,n.jsx)("h3",{style:{margin:"0 0 12px",fontSize:16},children:d.name||d.slug}),(0,n.jsx)("p",{style:{fontSize:13,color:"#757575",marginBottom:8},children:(0,t.__)("MCP URL to paste into your AI client:","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:p}),!g&&(0,n.jsx)(l,{status:"info",children:(0,t.__)("This connector supports Dynamic Client Registration only — paste the MCP URL above into your AI client and it will register itself. No manual credentials to generate.","acrossai-mcp-manager")})]})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},de=()=>{const{state:e}=z(),a=e.methods.clients||[],[i,c]=(0,s.useState)(a[0]?a[0].slug:""),[o,d]=(0,s.useState)(!1),[p,m]=(0,s.useState)(""),[u,g]=(0,s.useState)(null),[_,h]=(0,s.useState)(!1);(0,s.useEffect)(()=>{m(""),g(null),h(!1)},[i]),(0,s.useEffect)(()=>{if(!_)return;const e=setTimeout(()=>h(!1),2e3);return()=>clearTimeout(e)},[_]);const v=(0,ie.useCopyToClipboard)(p,()=>h(!0)),b=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),x=(0,s.useMemo)(()=>a.find(e=>e.slug===i),[a,i]),y=(0,s.useCallback)(async()=>{if(b&&x){d(!0),g(null),m("");try{const e=await r()({path:"/acrossai-mcp-manager/v1/generate-app-password",method:"POST",data:{server_id:b.id,name:`Quick Edit - ${x.name||x.slug}`}});e&&e.password?m(String(e.password)):g((0,t.__)("Password generation succeeded but the response was malformed.","acrossai-mcp-manager"))}catch(e){g(e&&e.message||(0,t.__)("Could not generate the Application Password.","acrossai-mcp-manager"))}finally{d(!1)}}},[b,x]);if(!b)return(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")});if(0===a.length)return(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No MCP clients registered on this site.","acrossai-mcp-manager")});const f=(0,s.useMemo)(()=>{let e=x&&x.config?"string"==typeof x.config?x.config:JSON.stringify(x.config,null,2):JSON.stringify(x||{},null,2);return p&&(e=e.split("(paste generated password here)").join(p)),e},[x,p]),w=x?`json · ${x.name||x.slug}`:"json";return(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("div",{style:{marginBottom:12},children:(0,n.jsx)("span",{style:{fontSize:11,fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase",color:"#757575"},children:(0,t.__)("Choose your client","acrossai-mcp-manager")})}),(0,n.jsx)("div",{role:"tablist","aria-label":(0,t.__)("MCP clients","acrossai-mcp-manager"),style:{display:"flex",gap:7,flexWrap:"wrap",marginBottom:16},children:a.map(e=>{const s=e.slug===i;return(0,n.jsx)("button",{type:"button",role:"tab","aria-selected":s,onClick:()=>c(e.slug),className:s?"qs-btn":"qs-btn qs-btn--secondary",children:e.name||e.slug},e.slug)})}),(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 1","acrossai-mcp-manager")}),(0,t.__)("Generate the password","acrossai-mcp-manager")]}),(0,n.jsxs)("div",{className:"qs-step-body qs-generate-section",children:[(0,n.jsx)("button",{type:"button",className:"qs-btn qs-generate-section__btn",onClick:y,disabled:o,children:o?(0,t.__)("Generating…","acrossai-mcp-manager"):(0,t.__)("Generate New Application Password","acrossai-mcp-manager")}),(0,n.jsx)("p",{className:"qs-generate-section__desc",children:(0,t.__)("Creates a one-time password via WordPress Application Passwords. Shown only once — store it safely.","acrossai-mcp-manager")}),p&&(0,n.jsxs)("div",{className:"qs-generate-section__reveal",children:[(0,n.jsxs)("div",{className:"qs-generate-section__reveal-row",children:[(0,n.jsx)("input",{type:"text",readOnly:!0,value:p,className:"qs-generate-section__reveal-input","aria-label":(0,t.__)("Generated Application Password","acrossai-mcp-manager")}),(0,n.jsx)("button",{ref:v,type:"button",className:"qs-btn qs-btn--secondary",children:_?(0,t.__)("Copied!","acrossai-mcp-manager"):(0,t.__)("Copy","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{className:"qs-generate-section__reveal-warning",children:(0,t.__)("Shown once. The config below now includes this password — copy that to grab both at once.","acrossai-mcp-manager")})]}),u&&(0,n.jsx)("div",{style:{marginTop:12},children:(0,n.jsx)(l,{status:"error",children:u})})]})]}),x?.meta?.config_file&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 2","acrossai-mcp-manager")}),(0,t.__)("Open the config file","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("input",{type:"text",readOnly:!0,value:x.meta.config_file,className:"qs-meta-input qs-meta-input--full","aria-label":(0,t.__)("Config File path","acrossai-mcp-manager")})})]}),x?.meta?.top_level_key&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 3","acrossai-mcp-manager")}),(0,t.__)("Locate the top-level key","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("input",{type:"text",readOnly:!0,value:`"${x.meta.top_level_key}"`,className:"qs-meta-input qs-meta-input--full","aria-label":(0,t.__)("Top-Level Key","acrossai-mcp-manager")})})]}),(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 4","acrossai-mcp-manager")}),(0,t.__)("Copy this config and paste it under the top-level key","acrossai-mcp-manager")]}),(0,n.jsxs)("div",{className:"qs-step-body",children:[window.acrossaiMcpQuickConnect?.tlsBypass?.enabled&&(0,n.jsx)("div",{style:{marginBottom:12},children:(0,n.jsxs)(l,{status:"warning",children:[window.acrossaiMcpQuickConnect.tlsBypass.message," ",(0,n.jsx)("a",{href:window.acrossaiMcpQuickConnect.tlsBypass.docUrl,target:"_blank",rel:"noopener noreferrer",children:window.acrossaiMcpQuickConnect.tlsBypass.linkText})]})}),(0,n.jsx)(le,{variant:"pane",title:w,children:f})]})]}),x?.restartStep&&(0,n.jsxs)("div",{className:"qs-step",children:[(0,n.jsxs)("h3",{className:"qs-step-heading",children:[(0,n.jsx)("span",{className:"qs-step-heading__num",children:(0,t.__)("Step 5","acrossai-mcp-manager")}),(0,t.__)("Restart the MCP client","acrossai-mcp-manager")]}),(0,n.jsx)("div",{className:"qs-step-body",children:(0,n.jsx)("p",{style:{margin:0},children:x.restartStep})})]}),(0,n.jsx)("div",{style:{marginTop:20},children:(0,n.jsx)(l,{status:"info",children:(0,t.__)("The generated password belongs to your current WordPress user. Access Control still applies to every MCP request, so a user who is not allowed for this server will receive an access denied response even if they have a saved config.","acrossai-mcp-manager")})})]})},pe=()=>{const{state:e}=z(),a=window.acrossaiMcpQuickConnect||{},r=e.methods.npm||[],i=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]);return i?0===r.length?(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No npm methods registered.","acrossai-mcp-manager")}):(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("span",{style:{display:"block",fontSize:11,fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase",color:"#757575",marginBottom:8},children:(0,t.__)("Command","acrossai-mcp-manager")}),r.map((e,s)=>{const r=e.command||`npx -y @acrossai/mcp-manager --siteurl=${a.siteUrl} --server=${i.slug}`;return(0,n.jsx)(le,{variant:"inline",children:r},e.slug||s)}),(0,n.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:12,marginTop:20,marginBottom:20},children:[(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16},children:[(0,n.jsx)("strong",{style:{flex:"0 0 120px"},children:(0,t.__)("Site URL","acrossai-mcp-manager")}),(0,n.jsx)("code",{style:{background:"#f0f0f0",padding:"3px 8px",borderRadius:2,fontSize:12},children:a.siteUrl})]}),(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16},children:[(0,n.jsx)("strong",{style:{flex:"0 0 120px"},children:(0,t.__)("Server","acrossai-mcp-manager")}),(0,n.jsx)("code",{style:{background:"#f0f0f0",padding:"3px 8px",borderRadius:2,fontSize:12},children:i.slug})]})]}),(0,n.jsx)("p",{style:{fontSize:12,color:"#757575",lineHeight:1.5},children:(0,t.__)("The CLI prompts for an Application Password on first run and stores it in your OS keychain.","acrossai-mcp-manager")})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},me=()=>{const{state:e}=z(),a=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]);return a?(0,n.jsxs)("div",{children:[(0,n.jsx)(ce,{}),(0,n.jsx)("h3",{style:{margin:"0 0 6px",fontSize:16},children:(0,t.__)("STDIO Transport (Local / Subprocess Mode)","acrossai-mcp-manager")}),(0,n.jsx)("p",{style:{fontSize:13,color:"#757575",lineHeight:1.55,marginBottom:20},children:(0,t.__)("MCP clients can also connect by launching WP-CLI as a subprocess instead of calling the HTTP endpoint. Ideal for local WordPress installs — no credentials transmitted over the network.","acrossai-mcp-manager")}),(0,n.jsxs)("div",{style:{marginBottom:16},children:[(0,n.jsx)("strong",{children:(0,t.__)("List all registered MCP servers","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:"wp mcp-adapter list"})]}),(0,n.jsxs)("div",{style:{marginBottom:16},children:[(0,n.jsx)("strong",{children:(0,t.__)("Start the MCP server as a subprocess","acrossai-mcp-manager")}),(0,n.jsx)(le,{variant:"inline",children:`wp mcp-adapter serve --server=${a.slug} --user=admin`})]}),(0,n.jsx)(l,{status:"info",children:(0,t.__)("Choose STDIO for local dev + CI. Choose HTTP (via the MCP Client or Connectors path) when the client is a hosted app that can't launch subprocesses on your machine.","acrossai-mcp-manager")})]}):(0,n.jsx)(l,{status:"warning",children:(0,t.__)("No server selected.","acrossai-mcp-manager")})},ue={connectors:"One-click OAuth (Connectors)",client:"MCP Client (npx bridge)",npm:"npm CLI",wpcli:"WP-CLI (STDIO)"},ge=()=>{const{state:e,complete:a,refetch:r}=z(),i=v(),l=window.acrossaiMcpQuickConnect||{};(0,s.useEffect)(()=>{a()},[]);const c=(0,s.useMemo)(()=>e.servers.find(s=>s.id===e.wizardState.server_id),[e.servers,e.wizardState.server_id]),o=[{label:(0,t.__)("Server","acrossai-mcp-manager"),value:c?c.name:"—"},{label:(0,t.__)("Access","acrossai-mcp-manager"),value:e.wizardState.access_saved?(0,t.__)("Rule configured","acrossai-mcp-manager"):(0,t.__)("Administrators only (default)","acrossai-mcp-manager")},{label:(0,t.__)("Abilities","acrossai-mcp-manager"),value:null!==e.abilities.enabledForServer&&e.abilities.enabledForServer>0?/* translators: 1: enabled ability count, 2: total available */ /* translators: 1: enabled ability count, 2: total available */
    33(0,t.__)("%1$d of %2$d enabled","acrossai-mcp-manager").replace("%1$d",String(e.abilities.enabledForServer)).replace("%2$d",String(e.abilities.total)):(0,t.__)("None enabled","acrossai-mcp-manager")},{label:(0,t.__)("Connected via","acrossai-mcp-manager"),value:ue[e.wizardState.method]||"—"}];return(0,n.jsxs)("div",{style:{textAlign:"center",padding:"20px 0"},children:[(0,n.jsx)("div",{style:{width:60,height:60,borderRadius:"50%",background:"#edfaef",border:"2px solid #4ab866",display:"inline-flex",alignItems:"center",justifyContent:"center",marginBottom:20,color:"#4ab866"},"aria-hidden":"true",children:(0,n.jsx)(re,{size:32})}),(0,n.jsx)("h2",{className:"qs__step-title",style:{textAlign:"center"},children:(0,t.__)("You're all set!","acrossai-mcp-manager")}),(0,n.jsx)("div",{style:{border:"1px solid #ddd",borderRadius:2,margin:"24px auto",maxWidth:480,textAlign:"left"},children:o.map(e=>(0,n.jsxs)("div",{style:{display:"grid",gridTemplateColumns:"20px 140px 1fr",gap:12,alignItems:"center",padding:"12px 16px",borderBottom:"1px solid #f0f0f0"},children:[(0,n.jsx)("span",{style:{color:"#4ab866",fontSize:13,fontWeight:700},"aria-hidden":"true",children:"✓"}),(0,n.jsx)("span",{style:{fontSize:12.5,color:"#757575"},children:e.label}),(0,n.jsx)("span",{style:{fontSize:13,fontWeight:600},children:e.value})]},e.label))}),(0,n.jsxs)("div",{style:{display:"flex",justifyContent:"center",gap:12,flexWrap:"wrap"},children:[(0,n.jsx)("button",{type:"button",className:"qs-btn",onClick:()=>{l.adminUrl&&c&&(window.location.href=`${l.adminUrl}&action=edit&server=${c.id}`)},disabled:!c,children:(0,t.__)("Go to server dashboard","acrossai-mcp-manager")}),(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--secondary",onClick:async()=>{await r(),i.goTo("1")},children:(0,t.__)("Set up another server","acrossai-mcp-manager")}),(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--link",onClick:i.exit,children:(0,t.__)("Dismiss","acrossai-mcp-manager")})]}),(0,n.jsx)("p",{style:{fontSize:12,color:"#757575",marginTop:24},children:(0,t.__)("You can re-run this wizard anytime from the top admin bar.","acrossai-mcp-manager")})]})},_e={1:()=>(0,n.jsx)(B,{}),2:()=>(0,n.jsx)(W,{}),3:()=>(0,n.jsx)(V,{}),4:()=>(0,n.jsx)(J,{}),5:()=>(0,n.jsx)(Z,{}),6:()=>(0,n.jsx)(ee,{}),7:()=>(0,n.jsx)(ne,{}),10:()=>(0,n.jsx)(oe,{}),11:()=>(0,n.jsx)(de,{}),12:()=>(0,n.jsx)(pe,{}),13:()=>(0,n.jsx)(me,{}),done:()=>(0,n.jsx)(ge,{})},he=()=>{const e=v(),{state:a,isLoading:r,error:i,refetch:c,clearError:d}=z(),[p,m]=(0,s.useState)(!0),[u,g]=(0,s.useState)(null),[_,h]=(0,s.useState)(null),[b,x]=(0,s.useState)(!1),[y,f]=(0,s.useState)(null);(0,s.useEffect)(()=>{"idle"===a.status&&c()},[]),(0,s.useEffect)(()=>{"ready"===a.status&&e.setServer(a.wizardState.server_id)},[a.status,a.wizardState.server_id,e]);const w=(0,s.useMemo)(()=>a.servers.find(e=>e.id===a.wizardState.server_id)||null,[a.servers,a.wizardState.server_id]),j=a.wizardState.method,C=(0,s.useMemo)(()=>({skipCreate:null!==a.wizardState.server_id&&!a.wizardState.create_intent,skipAbilitiesGate:"active"===a.plugins.abilitiesManager,skipAbilities:a.abilities.total>0&&null!==a.abilities.enabledForServer&&a.abilities.enabledForServer>=a.abilities.total,skipEnable:!(!w||!w.enabled),skipConnectorsDetail:"connectors"!==j,skipClient:"client"!==j,skipNpm:"npm"!==j,skipWpcli:"wpcli"!==j}),[a.wizardState.server_id,a.wizardState.create_intent,a.plugins.abilitiesManager,a.abilities.total,a.abilities.enabledForServer,w,j]);(0,s.useEffect)(()=>{"ready"===a.status&&("2"===e.step&&C.skipCreate||"4"===e.step&&C.skipAbilitiesGate||"5"===e.step&&C.skipAbilities||"6"===e.step&&C.skipEnable||"10"===e.step&&C.skipConnectorsDetail||"11"===e.step&&C.skipClient||"12"===e.step&&C.skipNpm||"13"===e.step&&C.skipWpcli)&&e.advance({skips:C})},[e.step,a.status,C,e]),(0,s.useEffect)(()=>{if("ready"!==a.status)return;if(!_e[e.step])return void e.goTo("1");if("1"===e.step||"done"===e.step)return;const s=(r=a.wizardState).server_id||r.create_intent?null:"1";var r;s&&s!==e.step&&e.goTo(s)},[e.step,a.status,a.wizardState,e]);const S=(0,s.useMemo)(()=>[{id:1,skip:!1},{id:2,skip:C.skipCreate},{id:3,skip:!1},{id:4,skip:C.skipAbilitiesGate},{id:5,skip:C.skipAbilities},{id:6,skip:C.skipEnable},{id:7,skip:!1},{id:10,skip:C.skipConnectorsDetail},{id:11,skip:C.skipClient},{id:12,skip:C.skipNpm},{id:13,skip:C.skipWpcli}],[C]),k=(0,s.useMemo)(()=>S.filter(e=>!e.skip).length,[S]),N=(0,s.useMemo)(()=>{if("done"===e.step)return k;const s=String(e.step);let a=0;for(const e of S)if(!e.skip&&(a+=1,String(e.id)===s))return a;return a},[e.step,k,S]),q=(0,s.useCallback)(()=>{e.advance({skips:C})},[e,C]),A=(0,s.useMemo)(()=>({setCanAdvance:m,setBeforeAdvance:g,setFooterAction:h,setHideContinue:x,setBelowFooter:f,advance:q}),[m,g,h,x,f,q]),M=["10","11","12","13"].includes(e.step),E=(0,s.useCallback)(async()=>{u&&!await u()||(M?e.goTo("done"):e.advance({skips:C}))},[e,C,u,M]),T=(0,s.useRef)(!1);if("ready"===a.status&&(T.current=!0),"idle"===a.status||"loading"===a.status&&!T.current){const e=window.acrossaiMcpQuickConnect||{};return(0,n.jsxs)("div",{className:"qs__initial-loading",children:[e.iconUrl?(0,n.jsx)("img",{className:"qs__initial-loading-icon",src:e.iconUrl,alt:"","aria-hidden":"true"}):null,(0,n.jsx)("span",{className:"qs__sr-only",children:(0,t.__)("Loading setup wizard…","acrossai-mcp-manager")})]})}return(0,n.jsx)(P.Provider,{value:A,children:(0,n.jsxs)(o,{step:e.step,displayIndex:N,totalSteps:k,isLoading:r,canAdvance:p,footerAction:_,hideContinue:b,belowFooter:y,onBack:()=>e.back({skips:C}),onAdvance:E,onExit:e.exit,children:[i&&(0,n.jsxs)(l,{status:"error",children:[i.message," ",(0,n.jsx)("button",{type:"button",className:"qs-btn qs-btn--link",onClick:d,children:(0,t.__)("Dismiss","acrossai-mcp-manager")})]}),(_e[e.step]||_e[1])()]})})},ve=window.acrossaiMcpQuickConnect||{};ve.restNonce&&r().use(r().createNonceMiddleware(ve.restNonce));const be=()=>{const e=document.getElementById("acrossai-mcp-quick-connect-root");e&&(0,s.createRoot)(e).render((0,n.jsx)(E,{children:(0,n.jsx)(he,{})}))};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",be):be()})();
  • acrossai-mcp-manager/trunk/changelog.txt

    r3734601 r3766841  
    88https://github.com/acrossaico/acrossai-mcp-manager/releases
    99
     10
     11= 0.4.4 =
     12* **New: a log of what AI assistants actually did on your site.** Every request an assistant makes, and every ability that ran to fulfil it, recorded together — one "create a page" from an assistant may run several abilities, and the log keeps them linked, so you open one entry and read what happened instead of inferring it from the result. It records which assistant, how it authenticated, whether it worked, how long it took, what was asked and roughly how much of your content was read back. Find it under **MCP → Activity Log**, or on an individual server's own tab.
     13* **The log is on from the moment you update, and bounded without being configured.** Requests are kept 30 days, ability runs 7 — they are much noisier — and the whole log is capped at 50,000 entries. A daily job applies all three. Every number is adjustable and either half can be switched off on the MCP settings tab. Recording is on by default because a log nobody enabled is a log nobody has when they need it; it is bounded by default because a plugin that records without being asked should also tidy up without being asked.
     14* **It tells you when it is failing.** An empty log and a broken log look identical, which is how a logging fault stays invisible. The screen and Site Health now both report when writes are failing, when the table cannot be reached, and when the daily cleanup has not run — the last one usually meaning WordPress scheduled tasks are not running at all on the site, which affects far more than this log.
     15* **Private by design.** Values that look like credentials are redacted by key name before anything is stored, response bodies are never kept, and WordPress's own personal-data export and erase both reach the log. Erasure clears the person from the record and keeps the event, so a subject request cannot be used to delete audit history.
     16* **Changed: the connection wizard is now called "Connect".** It was "Quick Connect via AcrossAI" in the admin bar, the menu, the server list and the wizard's own header. Nothing moved and nothing behaves differently — the label just says less.
     17* **Fixed: a PHP notice on every page load.** A database table was passing an index setting in a form newer PHP versions warn about. It had never had any effect — the table was not using it — so removing it changes nothing except that the notice stops. Only visible to sites with debug logging switched on.
    1018
    1119= 0.4.3 =
  • acrossai-mcp-manager/trunk/includes/Abilities/AbilityHelpers.php

    r3685479 r3766841  
    8080                                $server_id,
    8181                                $ability->get_name(),
    82                                 is_array( $meta ) ? $meta : array()
     82                                // get_meta() declares `: array` in core — no guard needed.
     83                                $meta
    8384                        );
    8485                }
  • acrossai-mcp-manager/trunk/includes/Abilities/Discover.php

    r3702733 r3766841  
    189189                $meta = $ability->get_meta();
    190190
    191                 if ( ! is_array( $meta ) || ! isset( $meta['acrossai']['tab_group'] ) ) {
     191                // No is_array() guard: WP_Ability::get_meta() declares `: array` in core,
     192                // so the check is dead code and PHPStan level 8 flags it.
     193                if ( ! isset( $meta['acrossai']['tab_group'] ) ) {
    192194                        return '';
    193195                }
  • acrossai-mcp-manager/trunk/includes/Abilities/Execute.php

    r3702733 r3766841  
    1212namespace AcrossAI_MCP_Manager\Includes\Abilities;
    1313
     14use AcrossAI_MCP_Manager\Includes\Observability\CaptureContext;
    1415use WP\MCP\Domain\Utils\AbilityArgumentNormalizer;
    1516use WP_Error;
    … …  
    132133                $parameters = AbilityArgumentNormalizer::normalize( $ability, $parameters );
    133134
     135                $started = microtime( true );
     136
    134137                try {
    135                         $result = $ability->execute( $parameters );
     138                        // F096: same wrapper as Base_Toolset_Ability — one try/finally,
     139                        // owned by CaptureContext, so the two choke points cannot drift.
     140                        $result  = CaptureContext::instance()->around(
     141                                $ability_name,
     142                                static fn() => $ability->execute( $parameters )
     143                        );
     144                        $elapsed = ( microtime( true ) - $started ) * 1000;
     145
    136146                        if ( is_wp_error( $result ) ) {
     147                                AbilityActivityRecorder::instance()->record_bracketed(
     148                                        $ability_name,
     149                                        'error',
     150                                        array(
     151                                                'input'         => $parameters,
     152                                                'error_code'    => (string) $result->get_error_code(),
     153                                                'error_message' => $result->get_error_message(),
     154                                        ),
     155                                        $elapsed
     156                                );
     157
    137158                                return array(
    138159                                        'success' => false,
    … …  
    140161                                );
    141162                        }
     163
     164                        AbilityActivityRecorder::instance()->record_bracketed(
     165                                $ability_name,
     166                                'success',
     167                                array(
     168                                        'input'  => $parameters,
     169                                        'output' => $result,
     170                                ),
     171                                $elapsed
     172                        );
     173
    142174                        return array(
    143175                                'success' => true,
    … …  
    145177                        );
    146178                } catch ( \Throwable $e ) {
     179                        AbilityActivityRecorder::instance()->record_bracketed(
     180                                $ability_name,
     181                                'error',
     182                                array(
     183                                        'input'         => $parameters,
     184                                        'error_code'    => 'ability_threw',
     185                                        'error_message' => $e->getMessage(),
     186                                ),
     187                                ( microtime( true ) - $started ) * 1000
     188                        );
     189
    147190                        return array(
    148191                                'success' => false,
  • acrossai-mcp-manager/trunk/includes/Abilities/Toolset/AbilityGroup.php

    r3704846 r3766841  
    107107                $meta = $ability->get_meta_item( 'acrossai' );
    108108
    109                 if ( ! is_array( $meta ) || ! isset( $meta['tab_group'] ) ) {
     109                // No is_array() guard: get_meta() declares `: array` in core.
     110                if ( ! isset( $meta['tab_group'] ) ) {
    110111                        return '';
    111112                }
  • acrossai-mcp-manager/trunk/includes/Abilities/Toolset/Base_Toolset_Ability.php

    r3704846 r3766841  
    3030namespace AcrossAI_MCP_Manager\Includes\Abilities\Toolset;
    3131
     32use AcrossAI_MCP_Manager\Includes\Abilities\AbilityActivityRecorder;
     33use AcrossAI_MCP_Manager\Includes\Observability\CaptureContext;
    3234use AcrossAI_MCP_Manager\Includes\Abilities\Toolset\AbilityGroup;
    3335use AcrossAI_MCP_Manager\Includes\Abilities\Toolset\InputNormalizer;
    … …  
    10891091                );
    10901092
     1093                $started = microtime( true );
     1094
    10911095                try {
    1092                         $result = $target->execute( $parameters );
     1096                        // F096: capture is armed for the duration of this call, so an
     1097                        // ability event can be attributed to the MCP request that caused it
     1098                        // — and so Feature 097 can attribute its change rows to the same
     1099                        // call. `around()` owns the try/finally; a second hand-written
     1100                        // bracket here is how the two paths would drift apart.
     1101                        $result = CaptureContext::instance()->around(
     1102                                $name,
     1103                                static fn() => $target->execute( $parameters )
     1104                        );
    10931105                } catch ( \Throwable $e ) {
     1106                        AbilityActivityRecorder::instance()->record_bracketed(
     1107                                $name,
     1108                                'error',
     1109                                array(
     1110                                        'input'         => $parameters,
     1111                                        'error_code'    => 'ability_threw',
     1112                                        'error_message' => $e->getMessage(),
     1113                                ),
     1114                                ( microtime( true ) - $started ) * 1000
     1115                        );
     1116
    10941117                        /*
    10951118                         * An ability that throws would otherwise reach the transport as an
    … …  
    11001123                }
    11011124
     1125                $elapsed = ( microtime( true ) - $started ) * 1000;
     1126
    11021127                if ( is_wp_error( $result ) ) {
     1128                        // The only path that sees this on WordPress 6.9: core's
     1129                        // `wp_after_execute_ability` early-returns before firing on a
     1130                        // WP_Error, so a log built on the hook pair alone records
     1131                        // successes and is blind to every failure.
     1132                        AbilityActivityRecorder::instance()->record_bracketed(
     1133                                $name,
     1134                                'error',
     1135                                array(
     1136                                        'input'         => $parameters,
     1137                                        'error_code'    => (string) $result->get_error_code(),
     1138                                        'error_message' => $result->get_error_message(),
     1139                                ),
     1140                                $elapsed
     1141                        );
     1142
    11031143                        return array(
    11041144                                'action'        => 'execute',
    … …  
    11091149                        );
    11101150                }
     1151
     1152                AbilityActivityRecorder::instance()->record_bracketed(
     1153                        $name,
     1154                        'success',
     1155                        array(
     1156                                'input'  => $parameters,
     1157                                'output' => $result,
     1158                        ),
     1159                        $elapsed
     1160                );
    11111161
    11121162                return array(
  • acrossai-mcp-manager/trunk/includes/Activator.php

    r3733272 r3766841  
    99use AcrossAI_MCP_Manager\Includes\Database\OAuthDataMigration;
    1010use AcrossAI_MCP_Manager\Includes\Database\CliAuthLog\Table as CliAuthLogTable;
     11use AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Table as ActivityLogTable;
     12use AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup as ActivityLogCleanup;
    1113use AcrossAI_MCP_Manager\Includes\Database\MCPServerAbility\Table as MCPServerAbilityTable;
    1214use AcrossAI_MCP_Manager\Includes\Database\MCPServerTool\Table as MCPServerToolTable;
    … …  
    7880                MCPServerToolTable::instance()->maybe_upgrade();
    7981                CliAuthLogTable::instance()->maybe_upgrade();
     82                // F096 — the activity log. Empty-table state is the correct initial
     83                // state: both enable toggles ship off, so nothing writes until an
     84                // operator opts in.
     85                ActivityLogTable::instance()->maybe_upgrade();
    8086                // Feature 017 — per-server ability exposure overrides. No seeder call —
    8187                // the empty-table state IS the correct backwards-compatible initial state.
    … …  
    113119                                MCPServerTable::instance(),
    114120                                CliAuthLogTable::instance(),
     121                                ActivityLogTable::instance(),
    115122                                MCPServerAbilityTable::instance(),
    116123                                MCPServerToolTable::instance(),
    … …  
    134141                        wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'acrossai_mcp_manager_oauth_cleanup' );
    135142                }
     143
     144                // F096 — daily retention + ceiling sweep for the activity log. Scheduled
     145                // only while a bound is configured; `sync_schedule()` also unschedules
     146                // when both retention periods and the ceiling are 0, so an operator who
     147                // turns everything off does not keep a daily event that deletes nothing.
     148                ActivityLogCleanup::sync_schedule();
    136149
    137150                // Feature 015 — Access Control v2 adoption. Create the
  • acrossai-mcp-manager/trunk/includes/Database/MCPServerMeta/Schema.php

    r3628087 r3766841  
    5757         * `server_id_meta_key` (key, not unique) — mirrors wp_postmeta's
    5858         * `post_id` index shape; accelerates per-server key lookups.
    59          * meta_key partial-length (191) to fit within MySQL's index-key-length
    60          * limit under utf8mb4.
     59         *
     60         * NO index-level `length` key, deliberately. One used to sit on `meta_key`
     61         * (`'length' => array( 'meta_key' => 191 )`) intending a 191-character
     62         * prefix for the old 767-byte index limit. It never did anything:
     63         * BerlinDB's `Kern\Index` declares no `$length` property, so `set_vars()`
     64         * assigned it as a DYNAMIC property — deprecated from PHP 8.2 — and then
     65         * ignored it. Verified on the live table: `SUB_PART` is NULL, i.e. the
     66         * index covers the FULL column, which is what it has always done.
     67         *
     68         * It is also unnecessary. `varchar(255)` at utf8mb4 is 1020 bytes, well
     69         * inside InnoDB's 3072-byte limit under the DYNAMIC row format that MySQL
     70         * 5.7+ and 8.0 default to. The 191 figure belongs to the 767-byte era.
     71         *
     72         * Removing it is therefore zero functional change and silences a
     73         * deprecation notice that fired on EVERY request — `MCPServerMeta\Table`
     74         * is constructed in `Main::bootstrap_database_tables()`, which runs on
     75         * every page load, admin and front end alike. If a prefix is ever genuinely
     76         * needed, it has to be expressed somewhere BerlinDB reads; this key is not
     77         * that place.
    6178         *
    6279         * @var array
    … …  
    7794                        'type'    => 'key',
    7895                        'columns' => array( 'meta_key' ),
    79                         'length'  => array( 'meta_key' => 191 ),
    8096                ),
    8197        );
  • acrossai-mcp-manager/trunk/includes/Deactivator.php

    r3610897 r3766841  
    4444                // beyond the require + delegation.
    4545                wp_clear_scheduled_hook( 'acrossai_mcp_manager_oauth_cleanup' );
     46
     47                // F096 — the activity log's retention sweep. Cleared by name, matching
     48                // the OAuth hook above: the constant lives on the Cleanup class but the
     49                // contract is the string, and deactivation must not depend on that class
     50                // being loadable.
     51                wp_clear_scheduled_hook( 'acrossai_mcp_manager_activity_cleanup' );
    4652        }
    4753}
  • acrossai-mcp-manager/trunk/includes/Loader.php

    r3733272 r3766841  
    8686         *
    8787         * @since    0.0.1
    88          * @param    string $hook             The name of the WordPress action that is being registered.
    89          * @param    object $component        A reference to the instance of the object on which the action is defined.
    90          * @param    string $callback         The name of the function definition on the $component.
    91          * @param    int    $priority         Optional. The priority at which the function should be fired. Default is 10.
    92          * @param    int    $accepted_args    Optional. The number of arguments that should be passed to the $callback. Default is 1.
     88         * @param    string              $hook             The name of the WordPress action that is being registered.
     89         * @param    object|class-string $component A reference to the instance of the object on which the action is
     90         *                                            defined, or its class-string when the callback is static.
     91         * @param    string              $callback         The name of the function definition on the $component.
     92         * @param    int                 $priority         Optional. The priority at which the function should be fired. Default is 10.
     93         * @param    int                 $accepted_args    Optional. The number of arguments that should be passed to the $callback. Default is 1.
    9394         */
    9495        public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
    … …  
    100101         *
    101102         * @since    0.0.1
    102          * @param    string $hook             The name of the WordPress filter that is being registered.
    103          * @param    object $component        A reference to the instance of the object on which the filter is defined.
    104          * @param    string $callback         The name of the function definition on the $component.
    105          * @param    int    $priority         Optional. The priority at which the function should be fired. Default is 10.
    106          * @param    int    $accepted_args    Optional. The number of arguments that should be passed to the $callback. Default is 1.
     103         * @param    string              $hook             The name of the WordPress filter that is being registered.
     104         * @param    object|class-string $component A reference to the instance of the object on which the filter is
     105         *                                            defined, or its class-string when the callback is static.
     106         * @param    string              $callback         The name of the function definition on the $component.
     107         * @param    int                 $priority         Optional. The priority at which the function should be fired. Default is 10.
     108         * @param    int                 $accepted_args    Optional. The number of arguments that should be passed to the $callback. Default is 1.
    107109         */
    108110        public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
    … …  
    116118         * @since    0.0.1
    117119         * @access   private
    118          * @param    array  $hooks            The collection of hooks that is being registered (that is, actions or filters).
    119          * @param    string $hook             The name of the WordPress filter that is being registered.
    120          * @param    object $component        A reference to the instance of the object on which the filter is defined.
    121          * @param    string $callback         The name of the function definition on the $component.
    122          * @param    int    $priority         The priority at which the function should be fired.
    123          * @param    int    $accepted_args    The number of arguments that should be passed to the $callback.
     120         * @param    array               $hooks            The collection of hooks that is being registered (that is, actions or filters).
     121         * @param    string              $hook             The name of the WordPress filter that is being registered.
     122         * @param    object|class-string $component A reference to the instance of the object on which the filter is
     123         *                                            defined, or its class-string when the callback is static.
     124         * @param    string              $callback         The name of the function definition on the $component.
     125         * @param    int                 $priority         The priority at which the function should be fired.
     126         * @param    int                 $accepted_args    The number of arguments that should be passed to the $callback.
    124127         * @return   array                                  The collection of actions and filters registered with WordPress.
    125128         */
  • acrossai-mcp-manager/trunk/includes/MCP/Controller.php

    r3733272 r3766841  
    232232                                array( HttpTransport::class ),
    233233                                ErrorLogMcpErrorHandler::class,
    234                                 NullMcpObservabilityHandler::class,
     234                                // F096: our handler ONLY when request logging is on. Reading the
     235                                // toggle here rather than inside the handler is what makes a disabled
     236                                // log cost nothing at runtime — the adapter keeps the Null handler and
     237                                // the recording path is never reached (FR-029).
     238                                \AcrossAI_MCP_Manager\Includes\Observability\HandlerResolver::class_string(),
    235239                                $tools,
    236240                                $resources,
  • acrossai-mcp-manager/trunk/includes/Main.php

    r3734601 r3766841  
    116116                $this->load_dependencies();
    117117
     118                $this->register_activity_log_table();
     119
    118120                $this->set_locale();
    119121
    120122                $this->load_hooks();
     123        }
     124
     125        /**
     126         * Teach `$wpdb` the activity log's table name, on EVERY request.
     127         *
     128         * BerlinDB does not resolve a table name from the Query's `$table_name`
     129         * directly. `Query::get_table_name()` calls `get_table_prefix()`, which
     130         * reads `$wpdb->{$prefixed_name} ?? ''` — and that property is only ever
     131         * set by the Table object's own constructor. Construct no Table, and the
     132         * name resolves to the EMPTY STRING: the insert becomes
     133         * `SHOW FULL COLUMNS FROM ``` and fails, `add_item()` returns false, and
     134         * the Recorder's A15 try/catch swallows it. Nothing is written and nothing
     135         * is reported.
     136         *
     137         * Reconciliation runs on `admin_init` (see reconcile_database_schemas()),
     138         * which is enough to CREATE and migrate the table but not to make it
     139         * writable anywhere else — `admin_init` does not fire on a front-end REST
     140         * request or on WP-Cron. Both of those are load-bearing here: every MCP
     141         * call is a REST request, and the retention sweep is a cron event. The log
     142         * recorded nothing from real traffic, while every test passed, because the
     143         * test bootstrap constructs the Table itself.
     144         *
     145         * Safe to do unconditionally and this early. Table construction performs no
     146         * queries — `init()` sanitizes the name and calls `set_db_interface()`,
     147         * which only assigns `$wpdb` properties. The schema work lives in
     148         * `maybe_upgrade()`, which is NOT called here.
     149         *
     150         * Deliberately not gated on the logging toggles. The table must be
     151         * addressable for reads, retention and purge regardless of whether
     152         * recording is currently on, and an unresolvable name fails silently in
     153         * every one of those paths too.
     154         */
     155        private function register_activity_log_table(): void {
     156                \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Table::instance();
    121157        }
    122158
    … …  
    148184                $this->define( 'ACROSSAI_MCP_MANAGER_PLUGIN_NAME_SLUG', 'acrossai-mcp-manager' );
    149185                $this->define( 'ACROSSAI_MCP_MANAGER_PLUGIN_NAME', 'AcrossAI MCP Manager' );
    150                 $this->define( 'ACROSSAI_MCP_MANAGER_VERSION', '0.4.3' );
     186                $this->define( 'ACROSSAI_MCP_MANAGER_VERSION', '0.4.4' );
    151187        }
    152188
    … …  
    279315                        \AcrossAI_MCP_Manager\Includes\Database\OAuthClients\Table::instance(),
    280316                        \AcrossAI_MCP_Manager\Includes\Database\ConnectorApprovedUsers\Table::instance(),
    281                 );
     317                        // F096 — the activity log. Listed here as well as in Activator
     318                        // because WordPress skips activation hooks on a plugin UPDATE
     319                        // (B68): a site that already had this plugin active when 096
     320                        // shipped would otherwise have the toggles but no table, and every
     321                        // write would fail silently.
     322                        \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Table::instance(),
     323                );
     324
     325                $pending = 0;
    282326
    283327                foreach ( $tables as $table ) {
    284328                        $table->maybe_upgrade();
     329
     330                        if ( $table->needs_upgrade() ) {
     331                                ++$pending;
     332                        }
     333                }
     334
     335                // FR-013b. A failure recorded here is usually transient: the version is
     336                // left unstamped precisely so the migration retries on the next admin
     337                // load. Once nothing is pending, the recorded failures describe a state
     338                // that no longer exists and must stop being reported, or Site Health
     339                // shows a permanent red mark for a problem that fixed itself.
     340                //
     341                // Cleared wholesale rather than per table because BerlinDB's `Table`
     342                // exposes no public name accessor, so a stored failure cannot be matched
     343                // to a Table object from out here. "Nothing needs upgrading" covers it.
     344                if ( 0 === $pending ) {
     345                        \AcrossAI_MCP_Manager\Includes\Database\Support\SchemaFailureHealthCheck::instance()->clear_all();
    285346                }
    286347
    … …  
    863924                $this->loader->add_action( 'shutdown', $current_server_holder, 'clear', 999 );
    864925
     926                // ─────────────────────────────────────────────────────────────────
     927                // F096 — the activity log's OAuth attribution holder.
     928                //
     929                // Same A17 three-stage lifecycle as CurrentServerHolder above, for the
     930                // same reason: stage 3 (`shutdown`) is what stops a fatal leaving a
     931                // resolved OAuth identity in memory for the NEXT request to be
     932                // attributed to. A17 calls omitting it the number-one silent bug in
     933                // ad-hoc versions of this pattern, and in an activity log the symptom
     934                // would be one client's calls credited to another.
     935                //
     936                // `capture_oauth_context` listens for the scoped action TokenValidator
     937                // fires after a successful bearer validation — hooks here per A1,
     938                // never inside the validator (Principle V).
     939                // ─────────────────────────────────────────────────────────────────
     940                $auth_context_holder = \AcrossAI_MCP_Manager\Includes\Observability\AuthContextHolder::instance();
     941                $this->loader->add_action(
     942                        \AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants::ACTION_OAUTH_TOKEN_VALIDATED,
     943                        $auth_context_holder,
     944                        'capture_oauth_context',
     945                        10,
     946                        2
     947                );
     948                $this->loader->add_filter( 'rest_pre_dispatch', $auth_context_holder, 'reset_for_request', 5, 3 );
     949                $this->loader->add_filter( 'rest_post_dispatch', $auth_context_holder, 'clear', 999, 1 );
     950                $this->loader->add_action( 'shutdown', $auth_context_holder, 'clear', 999 );
     951
     952                // F096 — the activity log's REST surface and privacy callbacks.
     953                //
     954                // The exporter and eraser ship in THIS release rather than with the
     955                // governance story, because this release is what starts recording source
     956                // addresses. Clarification Q1 kept the full address on the condition
     957                // that the subject-data path accompanied it; deferring the callbacks
     958                // would keep the cost and drop the mitigation (SEC-T02).
     959                $this->loader->add_action(
     960                        'rest_api_init',
     961                        \AcrossAI_MCP_Manager\Includes\REST\ActivityLogController::instance(),
     962                        'register_routes'
     963                );
     964                $this->loader->add_filter(
     965                        'wp_privacy_personal_data_exporters',
     966                        \AcrossAI_MCP_Manager\Includes\Observability\PersonalData::class,
     967                        'register_exporter'
     968                );
     969                $this->loader->add_filter(
     970                        'wp_privacy_personal_data_erasers',
     971                        \AcrossAI_MCP_Manager\Includes\Observability\PersonalData::class,
     972                        'register_eraser'
     973                );
     974
     975                // The Activity screen: its own submenu under the shared AcrossAI parent,
     976                // not under tools.php. The asset enqueue is gated on the page hook, so
     977                // the 334 KB bundle never loads on an unrelated admin screen.
     978                $activity_page = \AcrossAI_MCP_Manager\Admin\Partials\ActivityLogPage::instance();
     979                $this->loader->add_action( 'admin_menu', $activity_page, 'register_menu', 20 );
     980                $this->loader->add_action( 'admin_enqueue_scripts', $activity_page, 'enqueue_assets' );
     981
     982                // F096 — ability capture.
     983                //
     984                // Core instruments WP_Ability::execute() for EVERY caller, so these
     985                // hooks cover MCP, the REST abilities route, WP-CLI and the admin UI
     986                // without any callback wrapping (which would duplicate core's own seam
     987                // and still miss non-MCP callers).
     988                //
     989                // The 7.1 quartet is feature-detected, NOT required: the plugin floor
     990                // is 6.9 and those hooks are @since 7.1.0. On 6.9 the guaranteed pair
     991                // records successes only — verified in core at class-wp-ability.php:634,
     992                // where a WP_Error early-returns before `wp_after_execute_ability`
     993                // fires, and at :615, where a permission denial returns before the
     994                // `before` hook fires at all. The always-on bracket in
     995                // Base_Toolset_Ability / Abilities\Execute is what covers failures and
     996                // denials for MCP-originated calls on every supported version.
     997                $ability_recorder = \AcrossAI_MCP_Manager\Includes\Abilities\AbilityActivityRecorder::instance();
     998                $this->loader->add_action( 'wp_before_execute_ability', $ability_recorder, 'on_before_execute', 10, 2 );
     999                $this->loader->add_action( 'wp_after_execute_ability', $ability_recorder, 'on_after_execute', 10, 3 );
     1000
     1001                if ( \AcrossAI_MCP_Manager\Includes\Abilities\AbilityActivityRecorder::has_rich_hooks() ) {
     1002                        $this->loader->add_filter( 'wp_ability_execute_result', $ability_recorder, 'on_execute_result', 10, 3 );
     1003                        $this->loader->add_filter( 'wp_ability_permission_result', $ability_recorder, 'on_permission_result', 10, 3 );
     1004                        $this->loader->add_filter( 'wp_ability_validate_input', $ability_recorder, 'on_validate_input', 10, 3 );
     1005                }
     1006
     1007                // The attribution context 097 attaches to. Same A17 three-stage
     1008                // lifecycle as the other two holders, for the same reason.
     1009                $capture_context = \AcrossAI_MCP_Manager\Includes\Observability\CaptureContext::instance();
     1010                $this->loader->add_filter( 'rest_pre_dispatch', $capture_context, 'reset_for_request', 5, 3 );
     1011                $this->loader->add_filter( 'rest_post_dispatch', $capture_context, 'clear', 999, 1 );
     1012                $this->loader->add_action( 'shutdown', $capture_context, 'clear', 999 );
     1013                $this->loader->add_filter( 'rest_post_dispatch', $ability_recorder, 'clear', 999, 1 );
     1014                $this->loader->add_action( 'shutdown', $ability_recorder, 'clear', 999 );
     1015
     1016                // F096 — response-size measurement (context cost).
     1017                //
     1018                // The observability seam passes tags and a duration and NEVER the result
     1019                // payload, so a response's SIZE is unreachable from the handler. These
     1020                // seven published vendor filters do see it, and are hooked purely to
     1021                // take a strlen() — no payload is retained, so there is nothing to
     1022                // redact and no truncation question.
     1023                //
     1024                // `mcp_adapter_tools_list` is the load-bearing one: tools/list has no
     1025                // ability children, so its size cannot be recovered by rolling up
     1026                // parent_id, and the tool catalogue injected at connect is usually the
     1027                // largest single context cost a server imposes.
     1028                //
     1029                // Every callback returns its input unchanged. Priority 10 with the exact
     1030                // arg counts the vendor passes.
     1031                $size_probe = \AcrossAI_MCP_Manager\Includes\Observability\ResponseSizeProbe::instance();
     1032                $this->loader->add_filter( 'mcp_adapter_tool_call_result', $size_probe, 'measure_tool_call', 10, 3 );
     1033                $this->loader->add_filter( 'mcp_adapter_tools_list', $size_probe, 'measure_tools_list', 10, 1 );
     1034                $this->loader->add_filter( 'mcp_adapter_initialize_response', $size_probe, 'measure_initialize', 10, 1 );
     1035                $this->loader->add_filter( 'mcp_adapter_prompt_get_result', $size_probe, 'measure_prompt_get', 10, 3 );
     1036                $this->loader->add_filter( 'mcp_adapter_prompts_list', $size_probe, 'measure_prompts_list', 10, 1 );
     1037                $this->loader->add_filter( 'mcp_adapter_resource_read_result', $size_probe, 'measure_resource_read', 10, 3 );
     1038                $this->loader->add_filter( 'mcp_adapter_resources_list', $size_probe, 'measure_resources_list', 10, 1 );
     1039
     1040                // F096 — the daily retention + ceiling sweep, and a re-sync whenever the
     1041                // bounds change so the schedule follows the settings rather than
     1042                // drifting from them until the next activation.
     1043                $activity_cleanup = \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::instance();
     1044                $this->loader->add_action(
     1045                        \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::CRON_HOOK,
     1046                        $activity_cleanup,
     1047                        'run'
     1048                );
     1049
     1050                // Reconcile the schedule on a normal boot, not only on activation and on
     1051                // a settings save. B68 again, and the default flip is what made it
     1052                // dangerous: WordPress skips activation hooks on a plugin UPDATE, and an
     1053                // operator who is happy with the shipped defaults never saves the
     1054                // settings form — so neither of the two paths that call
     1055                // `sync_schedule()` would ever run. While recording was OFF by default
     1056                // that was harmless: nothing was written, so a missing pruning job
     1057                // pruned nothing. Now that both halves record by default, the same gap
     1058                // means a site logs from its first request with NOTHING ever deleting a
     1059                // row. Priority 4, so the table reconciliation at 3 has already run.
     1060                $this->loader->add_action(
     1061                        'admin_init',
     1062                        \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::class,
     1063                        'sync_schedule',
     1064                        4
     1065                );
     1066
     1067                foreach (
     1068                        array(
     1069                                \AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants::OPTION_RETENTION_REQUEST_DAYS,
     1070                                \AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants::OPTION_RETENTION_ABILITY_DAYS,
     1071                                \AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants::OPTION_MAX_EVENTS,
     1072                        ) as $bound_option
     1073                ) {
     1074                        $this->loader->add_action(
     1075                                'update_option_' . $bound_option,
     1076                                \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::class,
     1077                                'sync_schedule'
     1078                        );
     1079                        $this->loader->add_action(
     1080                                'add_option_' . $bound_option,
     1081                                \AcrossAI_MCP_Manager\Includes\Database\ActivityLog\Cleanup::class,
     1082                                'sync_schedule'
     1083                        );
     1084                }
     1085
    8651086                /**
    8661087                 * Feature 040 — the OAuth admin REST controllers (ClientRegistration + ConnectorAdmin)
    … …  
    9941215                $oauth_timezone_health = \AcrossAI_MCP_Manager\Includes\Database\Support\TimezoneHealthCheck::instance();
    9951216                $this->loader->add_filter( 'site_status_tests', $oauth_timezone_health, 'add_test' );
     1217
     1218                // F096 FR-013a. The Activity Log screen already says "recording is
     1219                // failing" when the counter is non-zero; this is the half that works
     1220                // without anyone opening that screen. Both are needed: the counter
     1221                // resets on the next successful write, so an intermittent fault can
     1222                // erase its own evidence before a human looks, and support cannot ask
     1223                // an operator for a screen they have to navigate to.
     1224                $recording_health = \AcrossAI_MCP_Manager\Includes\Observability\RecordingHealthCheck::instance();
     1225                $this->loader->add_filter( 'site_status_tests', $recording_health, 'add_test' );
     1226
     1227                // F096 FR-013b. `acrossai_mcp_schema_upgrade_failed` is fired by every
     1228                // Table subclass in this plugin and, until this listener, went nowhere.
     1229                // A signal with no listener is the same as no signal.
     1230                $schema_health = \AcrossAI_MCP_Manager\Includes\Database\Support\SchemaFailureHealthCheck::instance();
     1231                $this->loader->add_action( 'acrossai_mcp_schema_upgrade_failed', $schema_health, 'record_failure', 10, 3 );
     1232                $this->loader->add_filter( 'site_status_tests', $schema_health, 'add_test' );
    9961233
    9971234                // The five built-in connector profiles. `ConnectorProfileRegistry` builds
  • acrossai-mcp-manager/trunk/includes/OAuth/TokenValidator.php

    r3733272 r3766841  
    1919use AcrossAI_MCP_Manager\Includes\OAuth\Repositories\ClientRepository;
    2020use AcrossAI_MCP_Manager\Includes\OAuth\Security\SecretsVault;
     21use AcrossAI_MCP_Manager\Includes\Utilities\ActivityLogConstants;
    2122
    2223defined( 'ABSPATH' ) || exit;
    … …  
    114115
    115116                        $resolved = (int) $row->user_id;
     117
     118                        /**
     119                         * Fires after a bearer token has been validated successfully.
     120                         *
     121                         * Fire-and-forget (D19): the return value is ignored and listeners
     122                         * must not throw — this method's own flow has to complete whatever
     123                         * happens downstream.
     124                         *
     125                         * Exists so the activity log can record HOW a client authenticated.
     126                         * This method resolves the client row and then discards it, so by
     127                         * the time the adapter's observability handler runs, nothing else
     128                         * can tell an AI connector from a bare DCR client. An action rather
     129                         * than a direct call into Observability keeps this module unaware
     130                         * of that one (Constitution Principle V); the listener is wired in
     131                         * Main.php per A1.
     132                         *
     133                         * @since 0.4.4
     134                         *
     135                         * @param string $connector_slug Connector slug, or '' for a bare client.
     136                         * @param string $client_name    Client display name, or ''.
     137                         */
     138                        do_action(
     139                                ActivityLogConstants::ACTION_OAUTH_TOKEN_VALIDATED,
     140                                isset( $row->connector_slug ) ? (string) $row->connector_slug : '',
     141                                isset( $row->client_name ) ? (string) $row->client_name : ''
     142                        );
     143
    116144                        return $resolved > 0 ? $resolved : $user_id;
    117145                } finally {
  • acrossai-mcp-manager/trunk/phpstan-baseline.neon

    r3733272 r3766841  
    584584
    585585                -
    586                         message: '#^Call to function is_array\(\) with array\<string, mixed\> will always evaluate to true\.$#'
    587                         identifier: function.alreadyNarrowedType
    588                         count: 1
    589                         path: includes/Abilities/Discover.php
    590 
    591                 -
    592586                        message: '#^Call to function method_exists\(\) with WP_Ability and ''get_meta'' will always evaluate to true\.$#'
    593587                        identifier: function.alreadyNarrowedType
    … …  
    602596
    603597                -
    604                         message: '#^Call to function is_array\(\) with array\<string, mixed\> will always evaluate to true\.$#'
    605                         identifier: function.alreadyNarrowedType
    606                         count: 1
    607                         path: includes/Abilities/GetAbilityInfo.php
    608 
    609                 -
    610598                        message: '#^Access to an undefined property object\:\:\$override_abilities_permission\.$#'
    611599                        identifier: property.notFound
    … …  
    793781                        path: includes/Database/CliAuthLog/Row.php
    794782
     783                # F096 ActivityLog\Schema — the SAME four BerlinDB warts already recorded
     784                # below for CliAuthLog\Schema, and for the same reason: BerlinDB declares
     785                # $columns/$indexes as array<Kern\Column>/array<Kern\Index> while its own
     786                # boot() offers "legacy support for pre-set $columns array" and hydrates
     787                # plain arrays into objects. No covariant type exists that is also true of
     788                # what we assign, so there is no honest fix inside the file.
     789                #
     790                # FOLLOW-UP: the documented remedy is a stub file correcting
     791                # BerlinDB\Database\Kern\Schema's two @var tags. That would retire these
     792                # four AND the four CliAuthLog entries below in one change. Not done here
     793                # because a third-party stub changes analysis for every file that touches
     794                # BerlinDB, which is not a Phase 2 decision to make unilaterally.
     795                -
     796                        message: '#^PHPDoc type array of property AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema\:\:\$columns is not covariant with PHPDoc type array\<BerlinDB\\Database\\Kern\\Column\> of overridden property BerlinDB\\Database\\Kern\\Schema\:\:\$columns\.$#'
     797                        identifier: property.phpDocType
     798                        count: 1
     799                        path: includes/Database/ActivityLog/Schema.php
     800
     801                -
     802                        message: '#^PHPDoc type array of property AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema\:\:\$indexes is not covariant with PHPDoc type array\<BerlinDB\\Database\\Kern\\Index\> of overridden property BerlinDB\\Database\\Kern\\Schema\:\:\$indexes\.$#'
     803                        identifier: property.phpDocType
     804                        count: 1
     805                        path: includes/Database/ActivityLog/Schema.php
     806
     807                -
     808                        message: '#^Property AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema\:\:\$columns type has no value type specified in iterable type array\.$#'
     809                        identifier: missingType.iterableValue
     810                        count: 1
     811                        path: includes/Database/ActivityLog/Schema.php
     812
     813                -
     814                        message: '#^Property AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema\:\:\$indexes type has no value type specified in iterable type array\.$#'
     815                        identifier: missingType.iterableValue
     816                        count: 1
     817                        path: includes/Database/ActivityLog/Schema.php
     818
    795819                -
    796820                        message: '#^PHPDoc type array of property AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Schema\:\:\$columns is not covariant with PHPDoc type array\<BerlinDB\\Database\\Kern\\Column\> of overridden property BerlinDB\\Database\\Kern\\Schema\:\:\$columns\.$#'
    … …  
    15411565                        identifier: missingType.return
    15421566                        count: 1
    1543                         path: includes/Main.php
    1544 
    1545                 -
    1546                         message: '#^Parameter \#2 \$component of method AcrossAI_MCP_Manager\\Includes\\Loader\:\:add_action\(\) expects object, string given\.$#'
    1547                         identifier: argument.type
    1548                         count: 9
    1549                         path: includes/Main.php
    1550 
    1551                 -
    1552                         message: '#^Parameter \#2 \$component of method AcrossAI_MCP_Manager\\Includes\\Loader\:\:add_filter\(\) expects object, string given\.$#'
    1553                         identifier: argument.type
    1554                         count: 4
    15551567                        path: includes/Main.php
    15561568
  • acrossai-mcp-manager/trunk/readme.txt

    r3734601 r3766841  
    55Requires PHP: 8.1
    66Tested up to: 7.1
    7 Stable tag: 0.4.3
     7Stable tag: 0.4.4
    88License: GPL-2.0-or-later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    3737* **Database**: schema and table sizes, index health, bloated autoloaded options, EXPLAIN on a slow query, serialisation-safe search-and-replace.
    3838* **Files**: browse, read, write and delete inside an administrator-defined allowlist; zip backups; wp-config constants; the debug log.
     39* **Activity log**: every MCP request and the abilities it ran, kept as a readable history with retention, a size cap and privacy controls.
    3940* **Cron, updates, diagnostics and cache**: overdue cron jobs, plugin and core updates with rollback and checksum checks, Site Health, recent fatal errors, transients and object cache.
    4041
    … …  
    7778* **File access is confined to an allowlist**, secrets are redacted from file and log reads, and database abilities never accept a raw table name.
    7879
     80= See What the AI Actually Did =
     81
     82Access control decides what an assistant **may** do. The activity log records what it **did**.
     83
     84* **Every request, and every ability behind it.** A single "create a page" from an assistant may run several abilities; the log keeps the request and its abilities together, so you can open one entry and read what actually happened rather than guessing from the result.
     85* **On from the moment you update, and bounded without being configured.** Requests are kept 30 days, ability runs 7, and the whole log is capped at 50,000 entries. A daily job applies all three. Both halves can be switched off.
     86* **Enough detail to answer the real questions**: which assistant, how it authenticated, whether it worked, how long it took, what it was asked and roughly how much of your content it read back.
     87* **It tells you when it is failing.** An empty log and a broken log look identical, so the screen and Site Health both say so when writes are failing, when the table cannot be reached, or when the daily cleanup has not run.
     88* **Private by design.** Sensitive values are redacted by key name before anything is stored, response bodies are never kept, and WordPress's own personal-data export and erase both reach it — erasing clears the person from the record while keeping the event, so the audit history stays intact.
     89
     90Find it under **MCP → Activity Log**, or on any individual server's own tab.
     91
    7992= Full Control Over Every Ability =
    8093
    … …  
    109122
    1101231. Go to **Plugins → Add New Plugin**, search for "AcrossAI MCP Manager", then click **Install Now** and **Activate**.
    111 2. The Quick Connect wizard opens automatically. Follow it, or close it and configure by hand.
     1242. The Connect wizard opens automatically. Follow it, or close it and configure by hand.
    1121253. For one-click setup, open **AcrossAI → MCP**, open a server, go to the **Connectors** tab and copy the URL into your AI client.
    1131264. For config-file clients, choose your client on the **Clients** tab, generate an Application Password, copy the JSON into your client and restart it.
    … …  
    131144= What is included? =
    132145
    133 AcrossAI is two free plugins on WordPress.org: MCP Manager (the server, connectors and access control) and Abilities Manager (the 357 abilities and their controls). Quick Connect sets up both in one click.
     146AcrossAI is two free plugins on WordPress.org: MCP Manager (the server, connectors and access control) and Abilities Manager (the 357 abilities and their controls). Connect sets up both in one click.
     147
     148= Can I see what the AI did to my site? =
     149
     150Yes. **MCP → Activity Log** records every request an assistant made and every ability that ran to fulfil it, with the two linked so you can open one entry and read the whole call. It records from the moment you update — requests kept 30 days, ability runs 7, capped at 50,000 entries, all adjustable, and either half can be switched off on the MCP settings tab.
     151
     152If recording ever fails, the screen and Site Health say so rather than showing an empty list, because a broken log and a quiet one otherwise look the same.
    134153
    135154= Is it free? =
    … …  
    241260The complete release history lives at [acrossai.co/changelog](https://acrossai.co/changelog/).
    242261
     262= 0.4.4 =
     263* **New: a log of what AI assistants actually did on your site.** Every request an assistant makes, and every ability that ran to fulfil it, recorded together — one "create a page" from an assistant may run several abilities, and the log keeps them linked, so you open one entry and read what happened instead of inferring it from the result. It records which assistant, how it authenticated, whether it worked, how long it took, what was asked and roughly how much of your content was read back. Find it under **MCP → Activity Log**, or on an individual server's own tab.
     264* **The log is on from the moment you update, and bounded without being configured.** Requests are kept 30 days, ability runs 7 — they are much noisier — and the whole log is capped at 50,000 entries. A daily job applies all three. Every number is adjustable and either half can be switched off on the MCP settings tab. Recording is on by default because a log nobody enabled is a log nobody has when they need it; it is bounded by default because a plugin that records without being asked should also tidy up without being asked.
     265* **It tells you when it is failing.** An empty log and a broken log look identical, which is how a logging fault stays invisible. The screen and Site Health now both report when writes are failing, when the table cannot be reached, and when the daily cleanup has not run — the last one usually meaning WordPress scheduled tasks are not running at all on the site, which affects far more than this log.
     266* **Private by design.** Values that look like credentials are redacted by key name before anything is stored, response bodies are never kept, and WordPress's own personal-data export and erase both reach the log. Erasure clears the person from the record and keeps the event, so a subject request cannot be used to delete audit history.
     267* **Changed: the connection wizard is now called "Connect".** It was "Quick Connect via AcrossAI" in the admin bar, the menu, the server list and the wizard's own header. Nothing moved and nothing behaves differently — the label just says less.
     268* **Fixed: a PHP notice on every page load.** A database table was passing an index setting in a form newer PHP versions warn about. It had never had any effect — the table was not using it — so removing it changes nothing except that the notice stops. Only visible to sites with debug logging switched on.
     269
    243270= 0.4.3 =
    244271* **New: a heads-up in Firefox, where tracking protection can block an assistant from connecting.** Firefox's Enhanced Tracking Protection can stop the connection part-way through — the connector is added, sign-in opens, and then nothing completes, with no error shown anywhere to explain it. Opening a connector screen in Firefox now shows a note explaining this and how to get past it: click the shield icon to the left of the address bar and switch Enhanced Tracking Protection off for this site, then connect again. The setting is remembered per site, affects nothing else you browse, and can be switched back on once the connection is working. The note appears only in Firefox and can be dismissed.
  • acrossai-mcp-manager/trunk/uninstall.php

    r3734601 r3766841  
    8484        $wpdb->prefix . 'acrossai_mcp_server_tools',     // F020 per-server tool selection.
    8585        $wpdb->prefix . 'acrossai_mcp_servers_meta',     // F037 MCPServerMeta — per-server key/value settings (Embeds tab, etc).
     86        $wpdb->prefix . 'acrossai_mcp_activity_log',     // F096 activity log — MCP requests + ability runs.
    8687        // F095 — this plugin's own OAuth tables. See the DO NOT REMOVE note above.
    8788        $wpdb->prefix . 'acrossai_mcp_oauth_clients',
  • acrossai-mcp-manager/trunk/vendor/composer/autoload_classmap.php

    r3733272 r3766841  
    88return array(
    99    'AcrossAI_MCP_Manager\\Admin\\Main' => $baseDir . '/admin/Main.php',
     10    'AcrossAI_MCP_Manager\\Admin\\Partials\\ActivityLogPage' => $baseDir . '/admin/Partials/ActivityLogPage.php',
    1011    'AcrossAI_MCP_Manager\\Admin\\Partials\\AddonsFilter' => $baseDir . '/admin/Partials/AddonsFilter.php',
    1112    'AcrossAI_MCP_Manager\\Admin\\Partials\\ApplicationPasswords' => $baseDir . '/admin/Partials/ApplicationPasswords.php',
    … …  
    4041    'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsMenu' => $baseDir . '/admin/Partials/SettingsMenu.php',
    4142    'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsRenderer' => $baseDir . '/admin/Partials/SettingsRenderer.php',
     43    'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityActivityRecorder' => $baseDir . '/includes/Abilities/AbilityActivityRecorder.php',
    4244    'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityHelpers' => $baseDir . '/includes/Abilities/AbilityHelpers.php',
    4345    'AcrossAI_MCP_Manager\\Includes\\Abilities\\CallbackReplacer' => $baseDir . '/includes/Abilities/CallbackReplacer.php',
    … …  
    8284    'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSettings' => $baseDir . '/includes/Connectors/ConnectorSettings.php',
    8385    'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSlugDisplay' => $baseDir . '/includes/Connectors/ConnectorSlugDisplay.php',
     86    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Cleanup' => $baseDir . '/includes/Database/ActivityLog/Cleanup.php',
     87    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Query' => $baseDir . '/includes/Database/ActivityLog/Query.php',
     88    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Recorder' => $baseDir . '/includes/Database/ActivityLog/Recorder.php',
     89    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Row' => $baseDir . '/includes/Database/ActivityLog/Row.php',
     90    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema' => $baseDir . '/includes/Database/ActivityLog/Schema.php',
     91    'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Table' => $baseDir . '/includes/Database/ActivityLog/Table.php',
    8492    'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Query' => $baseDir . '/includes/Database/CliAuthLog/Query.php',
    8593    'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Recorder' => $baseDir . '/includes/Database/CliAuthLog/Recorder.php',
    … …  
    134142    'AcrossAI_MCP_Manager\\Includes\\Database\\SchemaReconciler' => $baseDir . '/includes/Database/SchemaReconciler.php',
    135143    'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\DatetimeColumn' => $baseDir . '/includes/Database/Support/DatetimeColumn.php',
     144    'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\SchemaFailureHealthCheck' => $baseDir . '/includes/Database/Support/SchemaFailureHealthCheck.php',
    136145    'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\TimezoneHealthCheck' => $baseDir . '/includes/Database/Support/TimezoneHealthCheck.php',
    137146    'AcrossAI_MCP_Manager\\Includes\\Deactivator' => $baseDir . '/includes/Deactivator.php',
    … …  
    187196    'AcrossAI_MCP_Manager\\Includes\\OAuth\\TokenValidator' => $baseDir . '/includes/OAuth/TokenValidator.php',
    188197    'AcrossAI_MCP_Manager\\Includes\\OAuth\\UserLifecycle' => $baseDir . '/includes/OAuth/UserLifecycle.php',
     198    'AcrossAI_MCP_Manager\\Includes\\Observability\\ActivityObservabilityHandler' => $baseDir . '/includes/Observability/ActivityObservabilityHandler.php',
     199    'AcrossAI_MCP_Manager\\Includes\\Observability\\AuthContextHolder' => $baseDir . '/includes/Observability/AuthContextHolder.php',
     200    'AcrossAI_MCP_Manager\\Includes\\Observability\\CaptureContext' => $baseDir . '/includes/Observability/CaptureContext.php',
     201    'AcrossAI_MCP_Manager\\Includes\\Observability\\ConnectionContext' => $baseDir . '/includes/Observability/ConnectionContext.php',
     202    'AcrossAI_MCP_Manager\\Includes\\Observability\\HandlerResolver' => $baseDir . '/includes/Observability/HandlerResolver.php',
     203    'AcrossAI_MCP_Manager\\Includes\\Observability\\PersonalData' => $baseDir . '/includes/Observability/PersonalData.php',
     204    'AcrossAI_MCP_Manager\\Includes\\Observability\\RecordingHealthCheck' => $baseDir . '/includes/Observability/RecordingHealthCheck.php',
     205    'AcrossAI_MCP_Manager\\Includes\\Observability\\ResponseSizeProbe' => $baseDir . '/includes/Observability/ResponseSizeProbe.php',
    189206    'AcrossAI_MCP_Manager\\Includes\\REST\\AbilitiesController' => $baseDir . '/includes/REST/AbilitiesController.php',
     207    'AcrossAI_MCP_Manager\\Includes\\REST\\ActivityLogController' => $baseDir . '/includes/REST/ActivityLogController.php',
    190208    'AcrossAI_MCP_Manager\\Includes\\REST\\CliController' => $baseDir . '/includes/REST/CliController.php',
    191209    'AcrossAI_MCP_Manager\\Includes\\REST\\ClientRendererController' => $baseDir . '/includes/REST/ClientRendererController.php',
    192210    'AcrossAI_MCP_Manager\\Includes\\REST\\QuickConnectController' => $baseDir . '/includes/REST/QuickConnectController.php',
    193211    'AcrossAI_MCP_Manager\\Includes\\REST\\ToolsController' => $baseDir . '/includes/REST/ToolsController.php',
     212    'AcrossAI_MCP_Manager\\Includes\\Utilities\\ActivityLogConstants' => $baseDir . '/includes/Utilities/ActivityLogConstants.php',
    194213    'AcrossAI_MCP_Manager\\Includes\\Utilities\\AdminPageSlugs' => $baseDir . '/includes/Utilities/AdminPageSlugs.php',
    195214    'AcrossAI_MCP_Manager\\Includes\\Utilities\\CacheHeaders' => $baseDir . '/includes/Utilities/CacheHeaders.php',
  • acrossai-mcp-manager/trunk/vendor/composer/autoload_static.php

    r3733272 r3766841  
    7373    public static $classMap = array (
    7474        'AcrossAI_MCP_Manager\\Admin\\Main' => __DIR__ . '/../..' . '/admin/Main.php',
     75        'AcrossAI_MCP_Manager\\Admin\\Partials\\ActivityLogPage' => __DIR__ . '/../..' . '/admin/Partials/ActivityLogPage.php',
    7576        'AcrossAI_MCP_Manager\\Admin\\Partials\\AddonsFilter' => __DIR__ . '/../..' . '/admin/Partials/AddonsFilter.php',
    7677        'AcrossAI_MCP_Manager\\Admin\\Partials\\ApplicationPasswords' => __DIR__ . '/../..' . '/admin/Partials/ApplicationPasswords.php',
    … …  
    105106        'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsMenu' => __DIR__ . '/../..' . '/admin/Partials/SettingsMenu.php',
    106107        'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsRenderer' => __DIR__ . '/../..' . '/admin/Partials/SettingsRenderer.php',
     108        'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityActivityRecorder' => __DIR__ . '/../..' . '/includes/Abilities/AbilityActivityRecorder.php',
    107109        'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityHelpers' => __DIR__ . '/../..' . '/includes/Abilities/AbilityHelpers.php',
    108110        'AcrossAI_MCP_Manager\\Includes\\Abilities\\CallbackReplacer' => __DIR__ . '/../..' . '/includes/Abilities/CallbackReplacer.php',
    … …  
    147149        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSettings' => __DIR__ . '/../..' . '/includes/Connectors/ConnectorSettings.php',
    148150        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSlugDisplay' => __DIR__ . '/../..' . '/includes/Connectors/ConnectorSlugDisplay.php',
     151        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Cleanup' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Cleanup.php',
     152        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Query' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Query.php',
     153        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Recorder' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Recorder.php',
     154        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Row' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Row.php',
     155        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Schema.php',
     156        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Table' => __DIR__ . '/../..' . '/includes/Database/ActivityLog/Table.php',
    149157        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Query' => __DIR__ . '/../..' . '/includes/Database/CliAuthLog/Query.php',
    150158        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Recorder' => __DIR__ . '/../..' . '/includes/Database/CliAuthLog/Recorder.php',
    … …  
    199207        'AcrossAI_MCP_Manager\\Includes\\Database\\SchemaReconciler' => __DIR__ . '/../..' . '/includes/Database/SchemaReconciler.php',
    200208        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\DatetimeColumn' => __DIR__ . '/../..' . '/includes/Database/Support/DatetimeColumn.php',
     209        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\SchemaFailureHealthCheck' => __DIR__ . '/../..' . '/includes/Database/Support/SchemaFailureHealthCheck.php',
    201210        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\TimezoneHealthCheck' => __DIR__ . '/../..' . '/includes/Database/Support/TimezoneHealthCheck.php',
    202211        'AcrossAI_MCP_Manager\\Includes\\Deactivator' => __DIR__ . '/../..' . '/includes/Deactivator.php',
    … …  
    252261        'AcrossAI_MCP_Manager\\Includes\\OAuth\\TokenValidator' => __DIR__ . '/../..' . '/includes/OAuth/TokenValidator.php',
    253262        'AcrossAI_MCP_Manager\\Includes\\OAuth\\UserLifecycle' => __DIR__ . '/../..' . '/includes/OAuth/UserLifecycle.php',
     263        'AcrossAI_MCP_Manager\\Includes\\Observability\\ActivityObservabilityHandler' => __DIR__ . '/../..' . '/includes/Observability/ActivityObservabilityHandler.php',
     264        'AcrossAI_MCP_Manager\\Includes\\Observability\\AuthContextHolder' => __DIR__ . '/../..' . '/includes/Observability/AuthContextHolder.php',
     265        'AcrossAI_MCP_Manager\\Includes\\Observability\\CaptureContext' => __DIR__ . '/../..' . '/includes/Observability/CaptureContext.php',
     266        'AcrossAI_MCP_Manager\\Includes\\Observability\\ConnectionContext' => __DIR__ . '/../..' . '/includes/Observability/ConnectionContext.php',
     267        'AcrossAI_MCP_Manager\\Includes\\Observability\\HandlerResolver' => __DIR__ . '/../..' . '/includes/Observability/HandlerResolver.php',
     268        'AcrossAI_MCP_Manager\\Includes\\Observability\\PersonalData' => __DIR__ . '/../..' . '/includes/Observability/PersonalData.php',
     269        'AcrossAI_MCP_Manager\\Includes\\Observability\\RecordingHealthCheck' => __DIR__ . '/../..' . '/includes/Observability/RecordingHealthCheck.php',
     270        'AcrossAI_MCP_Manager\\Includes\\Observability\\ResponseSizeProbe' => __DIR__ . '/../..' . '/includes/Observability/ResponseSizeProbe.php',
    254271        'AcrossAI_MCP_Manager\\Includes\\REST\\AbilitiesController' => __DIR__ . '/../..' . '/includes/REST/AbilitiesController.php',
     272        'AcrossAI_MCP_Manager\\Includes\\REST\\ActivityLogController' => __DIR__ . '/../..' . '/includes/REST/ActivityLogController.php',
    255273        'AcrossAI_MCP_Manager\\Includes\\REST\\CliController' => __DIR__ . '/../..' . '/includes/REST/CliController.php',
    256274        'AcrossAI_MCP_Manager\\Includes\\REST\\ClientRendererController' => __DIR__ . '/../..' . '/includes/REST/ClientRendererController.php',
    257275        'AcrossAI_MCP_Manager\\Includes\\REST\\QuickConnectController' => __DIR__ . '/../..' . '/includes/REST/QuickConnectController.php',
    258276        'AcrossAI_MCP_Manager\\Includes\\REST\\ToolsController' => __DIR__ . '/../..' . '/includes/REST/ToolsController.php',
     277        'AcrossAI_MCP_Manager\\Includes\\Utilities\\ActivityLogConstants' => __DIR__ . '/../..' . '/includes/Utilities/ActivityLogConstants.php',
    259278        'AcrossAI_MCP_Manager\\Includes\\Utilities\\AdminPageSlugs' => __DIR__ . '/../..' . '/includes/Utilities/AdminPageSlugs.php',
    260279        'AcrossAI_MCP_Manager\\Includes\\Utilities\\CacheHeaders' => __DIR__ . '/../..' . '/includes/Utilities/CacheHeaders.php',
  • acrossai-mcp-manager/trunk/vendor/composer/installed.php

    r3734601 r3766841  
    22    'root' => array(
    33        'name' => 'wpboilerplate/acrossai-mcp-manager',
    4         'pretty_version' => 'v0.4.3',
    5         'version' => '0.4.3.0',
    6         'reference' => '3fe89542507880384b80f8bd2315eb976044777f',
     4        'pretty_version' => 'v0.4.4',
     5        'version' => '0.4.4.0',
     6        'reference' => '0bda489a333ca8aad4dda333bfa25e25a0ff1628',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
    … …  
    5757        ),
    5858        'wpboilerplate/acrossai-mcp-manager' => array(
    59             'pretty_version' => 'v0.4.3',
    60             'version' => '0.4.3.0',
    61             'reference' => '3fe89542507880384b80f8bd2315eb976044777f',
     59            'pretty_version' => 'v0.4.4',
     60            'version' => '0.4.4.0',
     61            'reference' => '0bda489a333ca8aad4dda333bfa25e25a0ff1628',
    6262            'type' => 'wordpress-plugin',
    6363            'install_path' => __DIR__ . '/../../',
  • acrossai-mcp-manager/trunk/vendor/composer/jetpack_autoload_classmap.php

    r3734601 r3766841  
    88return array(
    99        'AcrossAI_MCP_Manager\\Admin\\Main' => array(
    10                 'version' => '0.4.3.0',
     10                'version' => '0.4.4.0',
    1111                'path'    => $baseDir . '/admin/Main.php'
    1212        ),
     13        'AcrossAI_MCP_Manager\\Admin\\Partials\\ActivityLogPage' => array(
     14                'version' => '0.4.4.0',
     15                'path'    => $baseDir . '/admin/Partials/ActivityLogPage.php'
     16        ),
    1317        'AcrossAI_MCP_Manager\\Admin\\Partials\\AddonsFilter' => array(
    14                 'version' => '0.4.3.0',
     18                'version' => '0.4.4.0',
    1519                'path'    => $baseDir . '/admin/Partials/AddonsFilter.php'
    1620        ),
    1721        'AcrossAI_MCP_Manager\\Admin\\Partials\\ApplicationPasswords' => array(
    18                 'version' => '0.4.3.0',
     22                'version' => '0.4.4.0',
    1923                'path'    => $baseDir . '/admin/Partials/ApplicationPasswords.php'
    2024        ),
    2125        'AcrossAI_MCP_Manager\\Admin\\Partials\\CliAuthLogListTable' => array(
    22                 'version' => '0.4.3.0',
     26                'version' => '0.4.4.0',
    2327                'path'    => $baseDir . '/admin/Partials/CliAuthLogListTable.php'
    2428        ),
    2529        'AcrossAI_MCP_Manager\\Admin\\Partials\\MCPServerListTable' => array(
    26                 'version' => '0.4.3.0',
     30                'version' => '0.4.4.0',
    2731                'path'    => $baseDir . '/admin/Partials/MCPServerListTable.php'
    2832        ),
    2933        'AcrossAI_MCP_Manager\\Admin\\Partials\\Menu' => array(
    30                 'version' => '0.4.3.0',
     34                'version' => '0.4.4.0',
    3135                'path'    => $baseDir . '/admin/Partials/Menu.php'
    3236        ),
    3337        'AcrossAI_MCP_Manager\\Admin\\Partials\\Notices' => array(
    34                 'version' => '0.4.3.0',
     38                'version' => '0.4.4.0',
    3539                'path'    => $baseDir . '/admin/Partials/Notices.php'
    3640        ),
    3741        'AcrossAI_MCP_Manager\\Admin\\Partials\\QuickConnect\\ActivationRedirect' => array(
    38                 'version' => '0.4.3.0',
     42                'version' => '0.4.4.0',
    3943                'path'    => $baseDir . '/admin/Partials/QuickConnect/ActivationRedirect.php'
    4044        ),
    4145        'AcrossAI_MCP_Manager\\Admin\\Partials\\QuickConnect\\AdminBarEntry' => array(
    42                 'version' => '0.4.3.0',
     46                'version' => '0.4.4.0',
    4347                'path'    => $baseDir . '/admin/Partials/QuickConnect/AdminBarEntry.php'
    4448        ),
    4549        'AcrossAI_MCP_Manager\\Admin\\Partials\\QuickConnect\\QuickConnectPage' => array(
    46                 'version' => '0.4.3.0',
     50                'version' => '0.4.4.0',
    4751                'path'    => $baseDir . '/admin/Partials/QuickConnect/QuickConnectPage.php'
    4852        ),
    4953        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AIConnectorsTab' => array(
    50                 'version' => '0.4.3.0',
     54                'version' => '0.4.4.0',
    5155                'path'    => $baseDir . '/admin/Partials/ServerTabs/AIConnectorsTab.php'
    5256        ),
    5357        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AbilitiesTab' => array(
    54                 'version' => '0.4.3.0',
     58                'version' => '0.4.4.0',
    5559                'path'    => $baseDir . '/admin/Partials/ServerTabs/AbilitiesTab.php'
    5660        ),
    5761        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AbstractReactMountServerTab' => array(
    58                 'version' => '0.4.3.0',
     62                'version' => '0.4.4.0',
    5963                'path'    => $baseDir . '/admin/Partials/ServerTabs/AbstractReactMountServerTab.php'
    6064        ),
    6165        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AbstractServerTab' => array(
    62                 'version' => '0.4.3.0',
     66                'version' => '0.4.4.0',
    6367                'path'    => $baseDir . '/admin/Partials/ServerTabs/AbstractServerTab.php'
    6468        ),
    6569        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\AccessControlTab' => array(
    66                 'version' => '0.4.3.0',
     70                'version' => '0.4.4.0',
    6771                'path'    => $baseDir . '/admin/Partials/ServerTabs/AccessControlTab.php'
    6872        ),
    6973        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\ClientsTab' => array(
    70                 'version' => '0.4.3.0',
     74                'version' => '0.4.4.0',
    7175                'path'    => $baseDir . '/admin/Partials/ServerTabs/ClientsTab.php'
    7276        ),
    7377        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\ConnectTab' => array(
    74                 'version' => '0.4.3.0',
     78                'version' => '0.4.4.0',
    7579                'path'    => $baseDir . '/admin/Partials/ServerTabs/ConnectTab.php'
    7680        ),
    7781        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\Connect\\MethodRegistry' => array(
    78                 'version' => '0.4.3.0',
     82                'version' => '0.4.4.0',
    7983                'path'    => $baseDir . '/admin/Partials/ServerTabs/Connect/MethodRegistry.php'
    8084        ),
    8185        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\DangerZoneTab' => array(
    82                 'version' => '0.4.3.0',
     86                'version' => '0.4.4.0',
    8387                'path'    => $baseDir . '/admin/Partials/ServerTabs/DangerZoneTab.php'
    8488        ),
    8589        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\EmbedsTab' => array(
    86                 'version' => '0.4.3.0',
     90                'version' => '0.4.4.0',
    8791                'path'    => $baseDir . '/admin/Partials/ServerTabs/EmbedsTab.php'
    8892        ),
    8993        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\FilteredServerTab' => array(
    90                 'version' => '0.4.3.0',
     94                'version' => '0.4.4.0',
    9195                'path'    => $baseDir . '/admin/Partials/ServerTabs/FilteredServerTab.php'
    9296        ),
    9397        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\McpTrackerTab' => array(
    94                 'version' => '0.4.3.0',
     98                'version' => '0.4.4.0',
    9599                'path'    => $baseDir . '/admin/Partials/ServerTabs/McpTrackerTab.php'
    96100        ),
    97101        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\NpmTab' => array(
    98                 'version' => '0.4.3.0',
     102                'version' => '0.4.4.0',
    99103                'path'    => $baseDir . '/admin/Partials/ServerTabs/NpmTab.php'
    100104        ),
    101105        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\OverviewTab' => array(
    102                 'version' => '0.4.3.0',
     106                'version' => '0.4.4.0',
    103107                'path'    => $baseDir . '/admin/Partials/ServerTabs/OverviewTab.php'
    104108        ),
    105109        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\Partials\\AbilitiesManagerPromoCard' => array(
    106                 'version' => '0.4.3.0',
     110                'version' => '0.4.4.0',
    107111                'path'    => $baseDir . '/admin/Partials/ServerTabs/Partials/AbilitiesManagerPromoCard.php'
    108112        ),
    109113        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\Partials\\TypeRequirementNotice' => array(
    110                 'version' => '0.4.3.0',
     114                'version' => '0.4.4.0',
    111115                'path'    => $baseDir . '/admin/Partials/ServerTabs/Partials/TypeRequirementNotice.php'
    112116        ),
    113117        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\Registry' => array(
    114                 'version' => '0.4.3.0',
     118                'version' => '0.4.4.0',
    115119                'path'    => $baseDir . '/admin/Partials/ServerTabs/Registry.php'
    116120        ),
    117121        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\ToolsTab' => array(
    118                 'version' => '0.4.3.0',
     122                'version' => '0.4.4.0',
    119123                'path'    => $baseDir . '/admin/Partials/ServerTabs/ToolsTab.php'
    120124        ),
    121125        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\UpdateServerTab' => array(
    122                 'version' => '0.4.3.0',
     126                'version' => '0.4.4.0',
    123127                'path'    => $baseDir . '/admin/Partials/ServerTabs/UpdateServerTab.php'
    124128        ),
    125129        'AcrossAI_MCP_Manager\\Admin\\Partials\\ServerTabs\\WpCliTab' => array(
    126                 'version' => '0.4.3.0',
     130                'version' => '0.4.4.0',
    127131                'path'    => $baseDir . '/admin/Partials/ServerTabs/WpCliTab.php'
    128132        ),
    129133        'AcrossAI_MCP_Manager\\Admin\\Partials\\Settings' => array(
    130                 'version' => '0.4.3.0',
     134                'version' => '0.4.4.0',
    131135                'path'    => $baseDir . '/admin/Partials/Settings.php'
    132136        ),
    133137        'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsMenu' => array(
    134                 'version' => '0.4.3.0',
     138                'version' => '0.4.4.0',
    135139                'path'    => $baseDir . '/admin/Partials/SettingsMenu.php'
    136140        ),
    137141        'AcrossAI_MCP_Manager\\Admin\\Partials\\SettingsRenderer' => array(
    138                 'version' => '0.4.3.0',
     142                'version' => '0.4.4.0',
    139143                'path'    => $baseDir . '/admin/Partials/SettingsRenderer.php'
    140144        ),
     145        'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityActivityRecorder' => array(
     146                'version' => '0.4.4.0',
     147                'path'    => $baseDir . '/includes/Abilities/AbilityActivityRecorder.php'
     148        ),
    141149        'AcrossAI_MCP_Manager\\Includes\\Abilities\\AbilityHelpers' => array(
    142                 'version' => '0.4.3.0',
     150                'version' => '0.4.4.0',
    143151                'path'    => $baseDir . '/includes/Abilities/AbilityHelpers.php'
    144152        ),
    145153        'AcrossAI_MCP_Manager\\Includes\\Abilities\\CallbackReplacer' => array(
    146                 'version' => '0.4.3.0',
     154                'version' => '0.4.4.0',
    147155                'path'    => $baseDir . '/includes/Abilities/CallbackReplacer.php'
    148156        ),
    149157        'AcrossAI_MCP_Manager\\Includes\\Abilities\\CurrentServerHolder' => array(
    150                 'version' => '0.4.3.0',
     158                'version' => '0.4.4.0',
    151159                'path'    => $baseDir . '/includes/Abilities/CurrentServerHolder.php'
    152160        ),
    153161        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Discover' => array(
    154                 'version' => '0.4.3.0',
     162                'version' => '0.4.4.0',
    155163                'path'    => $baseDir . '/includes/Abilities/Discover.php'
    156164        ),
    157165        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Execute' => array(
    158                 'version' => '0.4.3.0',
     166                'version' => '0.4.4.0',
    159167                'path'    => $baseDir . '/includes/Abilities/Execute.php'
    160168        ),
    161169        'AcrossAI_MCP_Manager\\Includes\\Abilities\\GetAbilityInfo' => array(
    162                 'version' => '0.4.3.0',
     170                'version' => '0.4.4.0',
    163171                'path'    => $baseDir . '/includes/Abilities/GetAbilityInfo.php'
    164172        ),
    165173        'AcrossAI_MCP_Manager\\Includes\\Abilities\\PermissionOverrideProcessor' => array(
    166                 'version' => '0.4.3.0',
     174                'version' => '0.4.4.0',
    167175                'path'    => $baseDir . '/includes/Abilities/PermissionOverrideProcessor.php'
    168176        ),
    169177        'AcrossAI_MCP_Manager\\Includes\\Abilities\\ServerGuide' => array(
    170                 'version' => '0.4.3.0',
     178                'version' => '0.4.4.0',
    171179                'path'    => $baseDir . '/includes/Abilities/ServerGuide.php'
    172180        ),
    173181        'AcrossAI_MCP_Manager\\Includes\\Abilities\\SetupRequired' => array(
    174                 'version' => '0.4.3.0',
     182                'version' => '0.4.4.0',
    175183                'path'    => $baseDir . '/includes/Abilities/SetupRequired.php'
    176184        ),
    177185        'AcrossAI_MCP_Manager\\Includes\\Abilities\\ToolAbilities' => array(
    178                 'version' => '0.4.3.0',
     186                'version' => '0.4.4.0',
    179187                'path'    => $baseDir . '/includes/Abilities/ToolAbilities.php'
    180188        ),
    181189        'AcrossAI_MCP_Manager\\Includes\\Abilities\\ToolsetExposureBridge' => array(
    182                 'version' => '0.4.3.0',
     190                'version' => '0.4.4.0',
    183191                'path'    => $baseDir . '/includes/Abilities/ToolsetExposureBridge.php'
    184192        ),
    185193        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\AbilityGroup' => array(
    186                 'version' => '0.4.3.0',
     194                'version' => '0.4.4.0',
    187195                'path'    => $baseDir . '/includes/Abilities/Toolset/AbilityGroup.php'
    188196        ),
    189197        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Appearance' => array(
    190                 'version' => '0.4.3.0',
     198                'version' => '0.4.4.0',
    191199                'path'    => $baseDir . '/includes/Abilities/Toolset/Appearance.php'
    192200        ),
    193201        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Base_Toolset_Ability' => array(
    194                 'version' => '0.4.3.0',
     202                'version' => '0.4.4.0',
    195203                'path'    => $baseDir . '/includes/Abilities/Toolset/Base_Toolset_Ability.php'
    196204        ),
    197205        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Blocks' => array(
    198                 'version' => '0.4.3.0',
     206                'version' => '0.4.4.0',
    199207                'path'    => $baseDir . '/includes/Abilities/Toolset/Blocks.php'
    200208        ),
    201209        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Cache' => array(
    202                 'version' => '0.4.3.0',
     210                'version' => '0.4.4.0',
    203211                'path'    => $baseDir . '/includes/Abilities/Toolset/Cache.php'
    204212        ),
    205213        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Category_Registrar' => array(
    206                 'version' => '0.4.3.0',
     214                'version' => '0.4.4.0',
    207215                'path'    => $baseDir . '/includes/Abilities/Toolset/Category_Registrar.php'
    208216        ),
    209217        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Configuration' => array(
    210                 'version' => '0.4.3.0',
     218                'version' => '0.4.4.0',
    211219                'path'    => $baseDir . '/includes/Abilities/Toolset/Configuration.php'
    212220        ),
    213221        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Content' => array(
    214                 'version' => '0.4.3.0',
     222                'version' => '0.4.4.0',
    215223                'path'    => $baseDir . '/includes/Abilities/Toolset/Content.php'
    216224        ),
    217225        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Cron' => array(
    218                 'version' => '0.4.3.0',
     226                'version' => '0.4.4.0',
    219227                'path'    => $baseDir . '/includes/Abilities/Toolset/Cron.php'
    220228        ),
    221229        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Database' => array(
    222                 'version' => '0.4.3.0',
     230                'version' => '0.4.4.0',
    223231                'path'    => $baseDir . '/includes/Abilities/Toolset/Database.php'
    224232        ),
    225233        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Diagnostics' => array(
    226                 'version' => '0.4.3.0',
     234                'version' => '0.4.4.0',
    227235                'path'    => $baseDir . '/includes/Abilities/Toolset/Diagnostics.php'
    228236        ),
    229237        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Files' => array(
    230                 'version' => '0.4.3.0',
     238                'version' => '0.4.4.0',
    231239                'path'    => $baseDir . '/includes/Abilities/Toolset/Files.php'
    232240        ),
    233241        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Guide' => array(
    234                 'version' => '0.4.3.0',
     242                'version' => '0.4.4.0',
    235243                'path'    => $baseDir . '/includes/Abilities/Toolset/Guide.php'
    236244        ),
    237245        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\InputNormalizer' => array(
    238                 'version' => '0.4.3.0',
     246                'version' => '0.4.4.0',
    239247                'path'    => $baseDir . '/includes/Abilities/Toolset/InputNormalizer.php'
    240248        ),
    241249        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Integrations' => array(
    242                 'version' => '0.4.3.0',
     250                'version' => '0.4.4.0',
    243251                'path'    => $baseDir . '/includes/Abilities/Toolset/Integrations.php'
    244252        ),
    245253        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Registrar' => array(
    246                 'version' => '0.4.3.0',
     254                'version' => '0.4.4.0',
    247255                'path'    => $baseDir . '/includes/Abilities/Toolset/Registrar.php'
    248256        ),
    249257        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Updates' => array(
    250                 'version' => '0.4.3.0',
     258                'version' => '0.4.4.0',
    251259                'path'    => $baseDir . '/includes/Abilities/Toolset/Updates.php'
    252260        ),
    253261        'AcrossAI_MCP_Manager\\Includes\\Abilities\\Toolset\\Users' => array(
    254                 'version' => '0.4.3.0',
     262                'version' => '0.4.4.0',
    255263                'path'    => $baseDir . '/includes/Abilities/Toolset/Users.php'
    256264        ),
    257265        'AcrossAI_MCP_Manager\\Includes\\AccessControl\\AcrossAI_MCP_Access_Control' => array(
    258                 'version' => '0.4.3.0',
     266                'version' => '0.4.4.0',
    259267                'path'    => $baseDir . '/includes/AccessControl/AcrossAI_MCP_Access_Control.php'
    260268        ),
    261269        'AcrossAI_MCP_Manager\\Includes\\AccessControl\\TransportPermissionDefault' => array(
    262                 'version' => '0.4.3.0',
     270                'version' => '0.4.4.0',
    263271                'path'    => $baseDir . '/includes/AccessControl/TransportPermissionDefault.php'
    264272        ),
    265273        'AcrossAI_MCP_Manager\\Includes\\Activator' => array(
    266                 'version' => '0.4.3.0',
     274                'version' => '0.4.4.0',
    267275                'path'    => $baseDir . '/includes/Activator.php'
    268276        ),
    269277        'AcrossAI_MCP_Manager\\Includes\\Compat' => array(
    270                 'version' => '0.4.3.0',
     278                'version' => '0.4.4.0',
    271279                'path'    => $baseDir . '/includes/Compat.php'
    272280        ),
    273281        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\ChatGPTConnectorProfile' => array(
    274                 'version' => '0.4.3.0',
     282                'version' => '0.4.4.0',
    275283                'path'    => $baseDir . '/includes/ConnectorProfiles/ChatGPTConnectorProfile.php'
    276284        ),
    277285        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\ClaudeConnectorProfile' => array(
    278                 'version' => '0.4.3.0',
     286                'version' => '0.4.4.0',
    279287                'path'    => $baseDir . '/includes/ConnectorProfiles/ClaudeConnectorProfile.php'
    280288        ),
    281289        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\CursorConnectorProfile' => array(
    282                 'version' => '0.4.3.0',
     290                'version' => '0.4.4.0',
    283291                'path'    => $baseDir . '/includes/ConnectorProfiles/CursorConnectorProfile.php'
    284292        ),
    285293        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\GeminiConnectorProfile' => array(
    286                 'version' => '0.4.3.0',
     294                'version' => '0.4.4.0',
    287295                'path'    => $baseDir . '/includes/ConnectorProfiles/GeminiConnectorProfile.php'
    288296        ),
    289297        'AcrossAI_MCP_Manager\\Includes\\ConnectorProfiles\\GrokConnectorProfile' => array(
    290                 'version' => '0.4.3.0',
     298                'version' => '0.4.4.0',
    291299                'path'    => $baseDir . '/includes/ConnectorProfiles/GrokConnectorProfile.php'
    292300        ),
    293301        'AcrossAI_MCP_Manager\\Includes\\Connectors\\AbstractConnectorProfile' => array(
    294                 'version' => '0.4.3.0',
     302                'version' => '0.4.4.0',
    295303                'path'    => $baseDir . '/includes/Connectors/AbstractConnectorProfile.php'
    296304        ),
    297305        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorProfileRegistry' => array(
    298                 'version' => '0.4.3.0',
     306                'version' => '0.4.4.0',
    299307                'path'    => $baseDir . '/includes/Connectors/ConnectorProfileRegistry.php'
    300308        ),
    301309        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSettings' => array(
    302                 'version' => '0.4.3.0',
     310                'version' => '0.4.4.0',
    303311                'path'    => $baseDir . '/includes/Connectors/ConnectorSettings.php'
    304312        ),
    305313        'AcrossAI_MCP_Manager\\Includes\\Connectors\\ConnectorSlugDisplay' => array(
    306                 'version' => '0.4.3.0',
     314                'version' => '0.4.4.0',
    307315                'path'    => $baseDir . '/includes/Connectors/ConnectorSlugDisplay.php'
    308316        ),
     317        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Cleanup' => array(
     318                'version' => '0.4.4.0',
     319                'path'    => $baseDir . '/includes/Database/ActivityLog/Cleanup.php'
     320        ),
     321        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Query' => array(
     322                'version' => '0.4.4.0',
     323                'path'    => $baseDir . '/includes/Database/ActivityLog/Query.php'
     324        ),
     325        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Recorder' => array(
     326                'version' => '0.4.4.0',
     327                'path'    => $baseDir . '/includes/Database/ActivityLog/Recorder.php'
     328        ),
     329        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Row' => array(
     330                'version' => '0.4.4.0',
     331                'path'    => $baseDir . '/includes/Database/ActivityLog/Row.php'
     332        ),
     333        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Schema' => array(
     334                'version' => '0.4.4.0',
     335                'path'    => $baseDir . '/includes/Database/ActivityLog/Schema.php'
     336        ),
     337        'AcrossAI_MCP_Manager\\Includes\\Database\\ActivityLog\\Table' => array(
     338                'version' => '0.4.4.0',
     339                'path'    => $baseDir . '/includes/Database/ActivityLog/Table.php'
     340        ),
    309341        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Query' => array(
    310                 'version' => '0.4.3.0',
     342                'version' => '0.4.4.0',
    311343                'path'    => $baseDir . '/includes/Database/CliAuthLog/Query.php'
    312344        ),
    313345        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Recorder' => array(
    314                 'version' => '0.4.3.0',
     346                'version' => '0.4.4.0',
    315347                'path'    => $baseDir . '/includes/Database/CliAuthLog/Recorder.php'
    316348        ),
    317349        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Row' => array(
    318                 'version' => '0.4.3.0',
     350                'version' => '0.4.4.0',
    319351                'path'    => $baseDir . '/includes/Database/CliAuthLog/Row.php'
    320352        ),
    321353        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Schema' => array(
    322                 'version' => '0.4.3.0',
     354                'version' => '0.4.4.0',
    323355                'path'    => $baseDir . '/includes/Database/CliAuthLog/Schema.php'
    324356        ),
    325357        'AcrossAI_MCP_Manager\\Includes\\Database\\CliAuthLog\\Table' => array(
    326                 'version' => '0.4.3.0',
     358                'version' => '0.4.4.0',
    327359                'path'    => $baseDir . '/includes/Database/CliAuthLog/Table.php'
    328360        ),
    329361        'AcrossAI_MCP_Manager\\Includes\\Database\\ConnectorApprovedUsers\\Query' => array(
    330                 'version' => '0.4.3.0',
     362                'version' => '0.4.4.0',
    331363                'path'    => $baseDir . '/includes/Database/ConnectorApprovedUsers/Query.php'
    332364        ),
    333365        'AcrossAI_MCP_Manager\\Includes\\Database\\ConnectorApprovedUsers\\Row' => array(
    334                 'version' => '0.4.3.0',
     366                'version' => '0.4.4.0',
    335367                'path'    => $baseDir . '/includes/Database/ConnectorApprovedUsers/Row.php'
    336368        ),
    337369        'AcrossAI_MCP_Manager\\Includes\\Database\\ConnectorApprovedUsers\\Schema' => array(
    338                 'version' => '0.4.3.0',
     370                'version' => '0.4.4.0',
    339371                'path'    => $baseDir . '/includes/Database/ConnectorApprovedUsers/Schema.php'
    340372        ),
    341373        'AcrossAI_MCP_Manager\\Includes\\Database\\ConnectorApprovedUsers\\Table' => array(
    342                 'version' => '0.4.3.0',
     374                'version' => '0.4.4.0',
    343375                'path'    => $baseDir . '/includes/Database/ConnectorApprovedUsers/Table.php'
    344376        ),
    345377        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\ExposureResolver' => array(
    346                 'version' => '0.4.3.0',
     378                'version' => '0.4.4.0',
    347379                'path'    => $baseDir . '/includes/Database/MCPServerAbility/ExposureResolver.php'
    348380        ),
    349381        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\Query' => array(
    350                 'version' => '0.4.3.0',
     382                'version' => '0.4.4.0',
    351383                'path'    => $baseDir . '/includes/Database/MCPServerAbility/Query.php'
    352384        ),
    353385        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\Row' => array(
    354                 'version' => '0.4.3.0',
     386                'version' => '0.4.4.0',
    355387                'path'    => $baseDir . '/includes/Database/MCPServerAbility/Row.php'
    356388        ),
    357389        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\Schema' => array(
    358                 'version' => '0.4.3.0',
     390                'version' => '0.4.4.0',
    359391                'path'    => $baseDir . '/includes/Database/MCPServerAbility/Schema.php'
    360392        ),
    361393        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerAbility\\Table' => array(
    362                 'version' => '0.4.3.0',
     394                'version' => '0.4.4.0',
    363395                'path'    => $baseDir . '/includes/Database/MCPServerAbility/Table.php'
    364396        ),
    365397        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerMeta\\Query' => array(
    366                 'version' => '0.4.3.0',
     398                'version' => '0.4.4.0',
    367399                'path'    => $baseDir . '/includes/Database/MCPServerMeta/Query.php'
    368400        ),
    369401        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerMeta\\Row' => array(
    370                 'version' => '0.4.3.0',
     402                'version' => '0.4.4.0',
    371403                'path'    => $baseDir . '/includes/Database/MCPServerMeta/Row.php'
    372404        ),
    373405        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerMeta\\Schema' => array(
    374                 'version' => '0.4.3.0',
     406                'version' => '0.4.4.0',
    375407                'path'    => $baseDir . '/includes/Database/MCPServerMeta/Schema.php'
    376408        ),
    377409        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerMeta\\Table' => array(
    378                 'version' => '0.4.3.0',
     410                'version' => '0.4.4.0',
    379411                'path'    => $baseDir . '/includes/Database/MCPServerMeta/Table.php'
    380412        ),
    381413        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerTool\\Query' => array(
    382                 'version' => '0.4.3.0',
     414                'version' => '0.4.4.0',
    383415                'path'    => $baseDir . '/includes/Database/MCPServerTool/Query.php'
    384416        ),
    385417        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerTool\\Row' => array(
    386                 'version' => '0.4.3.0',
     418                'version' => '0.4.4.0',
    387419                'path'    => $baseDir . '/includes/Database/MCPServerTool/Row.php'
    388420        ),
    389421        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerTool\\Schema' => array(
    390                 'version' => '0.4.3.0',
     422                'version' => '0.4.4.0',
    391423                'path'    => $baseDir . '/includes/Database/MCPServerTool/Schema.php'
    392424        ),
    393425        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServerTool\\Table' => array(
    394                 'version' => '0.4.3.0',
     426                'version' => '0.4.4.0',
    395427                'path'    => $baseDir . '/includes/Database/MCPServerTool/Table.php'
    396428        ),
    397429        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\AbilityDiscovery' => array(
    398                 'version' => '0.4.3.0',
     430                'version' => '0.4.4.0',
    399431                'path'    => $baseDir . '/includes/Database/MCPServer/AbilityDiscovery.php'
    400432        ),
    401433        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\CreatedColumnBackfill' => array(
    402                 'version' => '0.4.3.0',
     434                'version' => '0.4.4.0',
    403435                'path'    => $baseDir . '/includes/Database/MCPServer/CreatedColumnBackfill.php'
    404436        ),
    405437        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\CuratedToolWriter' => array(
    406                 'version' => '0.4.3.0',
     438                'version' => '0.4.4.0',
    407439                'path'    => $baseDir . '/includes/Database/MCPServer/CuratedToolWriter.php'
    408440        ),
    409441        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\DefaultServerSeeder' => array(
    410                 'version' => '0.4.3.0',
     442                'version' => '0.4.4.0',
    411443                'path'    => $baseDir . '/includes/Database/MCPServer/DefaultServerSeeder.php'
    412444        ),
    413445        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\PolicyTransition' => array(
    414                 'version' => '0.4.3.0',
     446                'version' => '0.4.4.0',
    415447                'path'    => $baseDir . '/includes/Database/MCPServer/PolicyTransition.php'
    416448        ),
    417449        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ProtectedServers' => array(
    418                 'version' => '0.4.3.0',
     450                'version' => '0.4.4.0',
    419451                'path'    => $baseDir . '/includes/Database/MCPServer/ProtectedServers.php'
    420452        ),
    421453        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\Query' => array(
    422                 'version' => '0.4.3.0',
     454                'version' => '0.4.4.0',
    423455                'path'    => $baseDir . '/includes/Database/MCPServer/Query.php'
    424456        ),
    425457        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\Row' => array(
    426                 'version' => '0.4.3.0',
     458                'version' => '0.4.4.0',
    427459                'path'    => $baseDir . '/includes/Database/MCPServer/Row.php'
    428460        ),
    429461        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\Schema' => array(
    430                 'version' => '0.4.3.0',
     462                'version' => '0.4.4.0',
    431463                'path'    => $baseDir . '/includes/Database/MCPServer/Schema.php'
    432464        ),
    433465        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\SeededToolsBackfill' => array(
    434                 'version' => '0.4.3.0',
     466                'version' => '0.4.4.0',
    435467                'path'    => $baseDir . '/includes/Database/MCPServer/SeededToolsBackfill.php'
    436468        ),
    437469        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ServerEnablement' => array(
    438                 'version' => '0.4.3.0',
     470                'version' => '0.4.4.0',
    439471                'path'    => $baseDir . '/includes/Database/MCPServer/ServerEnablement.php'
    440472        ),
    441473        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ServerGuideBackfill' => array(
    442                 'version' => '0.4.3.0',
     474                'version' => '0.4.4.0',
    443475                'path'    => $baseDir . '/includes/Database/MCPServer/ServerGuideBackfill.php'
    444476        ),
    445477        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ServerTypes' => array(
    446                 'version' => '0.4.3.0',
     478                'version' => '0.4.4.0',
    447479                'path'    => $baseDir . '/includes/Database/MCPServer/ServerTypes.php'
    448480        ),
    449481        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\Table' => array(
    450                 'version' => '0.4.3.0',
     482                'version' => '0.4.4.0',
    451483                'path'    => $baseDir . '/includes/Database/MCPServer/Table.php'
    452484        ),
    453485        'AcrossAI_MCP_Manager\\Includes\\Database\\MCPServer\\ToolPolicy' => array(
    454                 'version' => '0.4.3.0',
     486                'version' => '0.4.4.0',
    455487                'path'    => $baseDir . '/includes/Database/MCPServer/ToolPolicy.php'
    456488        ),
    457489        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthAuthCodes\\Query' => array(
    458                 'version' => '0.4.3.0',
     490                'version' => '0.4.4.0',
    459491                'path'    => $baseDir . '/includes/Database/OAuthAuthCodes/Query.php'
    460492        ),
    461493        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthAuthCodes\\Row' => array(
    462                 'version' => '0.4.3.0',
     494                'version' => '0.4.4.0',
    463495                'path'    => $baseDir . '/includes/Database/OAuthAuthCodes/Row.php'
    464496        ),
    465497        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthAuthCodes\\Schema' => array(
    466                 'version' => '0.4.3.0',
     498                'version' => '0.4.4.0',
    467499                'path'    => $baseDir . '/includes/Database/OAuthAuthCodes/Schema.php'
    468500        ),
    469501        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthAuthCodes\\Table' => array(
    470                 'version' => '0.4.3.0',
     502                'version' => '0.4.4.0',
    471503                'path'    => $baseDir . '/includes/Database/OAuthAuthCodes/Table.php'
    472504        ),
    473505        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthClients\\Query' => array(
    474                 'version' => '0.4.3.0',
     506                'version' => '0.4.4.0',
    475507                'path'    => $baseDir . '/includes/Database/OAuthClients/Query.php'
    476508        ),
    477509        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthClients\\Row' => array(
    478                 'version' => '0.4.3.0',
     510                'version' => '0.4.4.0',
    479511                'path'    => $baseDir . '/includes/Database/OAuthClients/Row.php'
    480512        ),
    481513        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthClients\\Schema' => array(
    482                 'version' => '0.4.3.0',
     514                'version' => '0.4.4.0',
    483515                'path'    => $baseDir . '/includes/Database/OAuthClients/Schema.php'
    484516        ),
    485517        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthClients\\Table' => array(
    486                 'version' => '0.4.3.0',
     518                'version' => '0.4.4.0',
    487519                'path'    => $baseDir . '/includes/Database/OAuthClients/Table.php'
    488520        ),
    489521        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthDataMigration' => array(
    490                 'version' => '0.4.3.0',
     522                'version' => '0.4.4.0',
    491523                'path'    => $baseDir . '/includes/Database/OAuthDataMigration.php'
    492524        ),
    493525        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthTokens\\Query' => array(
    494                 'version' => '0.4.3.0',
     526                'version' => '0.4.4.0',
    495527                'path'    => $baseDir . '/includes/Database/OAuthTokens/Query.php'
    496528        ),
    497529        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthTokens\\Row' => array(
    498                 'version' => '0.4.3.0',
     530                'version' => '0.4.4.0',
    499531                'path'    => $baseDir . '/includes/Database/OAuthTokens/Row.php'
    500532        ),
    501533        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthTokens\\Schema' => array(
    502                 'version' => '0.4.3.0',
     534                'version' => '0.4.4.0',
    503535                'path'    => $baseDir . '/includes/Database/OAuthTokens/Schema.php'
    504536        ),
    505537        'AcrossAI_MCP_Manager\\Includes\\Database\\OAuthTokens\\Table' => array(
    506                 'version' => '0.4.3.0',
     538                'version' => '0.4.4.0',
    507539                'path'    => $baseDir . '/includes/Database/OAuthTokens/Table.php'
    508540        ),
    509541        'AcrossAI_MCP_Manager\\Includes\\Database\\SchemaReconciler' => array(
    510                 'version' => '0.4.3.0',
     542                'version' => '0.4.4.0',
    511543                'path'    => $baseDir . '/includes/Database/SchemaReconciler.php'
    512544        ),
    513545        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\DatetimeColumn' => array(
    514                 'version' => '0.4.3.0',
     546                'version' => '0.4.4.0',
    515547                'path'    => $baseDir . '/includes/Database/Support/DatetimeColumn.php'
    516548        ),
     549        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\SchemaFailureHealthCheck' => array(
     550                'version' => '0.4.4.0',
     551                'path'    => $baseDir . '/includes/Database/Support/SchemaFailureHealthCheck.php'
     552        ),
    517553        'AcrossAI_MCP_Manager\\Includes\\Database\\Support\\TimezoneHealthCheck' => array(
    518                 'version' => '0.4.3.0',
     554                'version' => '0.4.4.0',
    519555                'path'    => $baseDir . '/includes/Database/Support/TimezoneHealthCheck.php'
    520556        ),
    521557        'AcrossAI_MCP_Manager\\Includes\\Deactivator' => array(
    522                 'version' => '0.4.3.0',
     558                'version' => '0.4.4.0',
    523559                'path'    => $baseDir . '/includes/Deactivator.php'
    524560        ),
    525561        'AcrossAI_MCP_Manager\\Includes\\Discovery\\DiscoveryConnectorAdapter' => array(
    526                 'version' => '0.4.3.0',
     562                'version' => '0.4.4.0',
    527563                'path'    => $baseDir . '/includes/Discovery/DiscoveryConnectorAdapter.php'
    528564        ),
    529565        'AcrossAI_MCP_Manager\\Includes\\Embeds\\AbstractEmbedTransport' => array(
    530                 'version' => '0.4.3.0',
     566                'version' => '0.4.4.0',
    531567                'path'    => $baseDir . '/includes/Embeds/AbstractEmbedTransport.php'
    532568        ),
    533569        'AcrossAI_MCP_Manager\\Includes\\Embeds\\AiConnectorEmbedTransport' => array(
    534                 'version' => '0.4.3.0',
     570                'version' => '0.4.4.0',
    535571                'path'    => $baseDir . '/includes/Embeds/AiConnectorEmbedTransport.php'
    536572        ),
    537573        'AcrossAI_MCP_Manager\\Includes\\Embeds\\ClientEmbedTransport' => array(
    538                 'version' => '0.4.3.0',
     574                'version' => '0.4.4.0',
    539575                'path'    => $baseDir . '/includes/Embeds/ClientEmbedTransport.php'
    540576        ),
    541577        'AcrossAI_MCP_Manager\\Includes\\Embeds\\NpmEmbedTransport' => array(
    542                 'version' => '0.4.3.0',
     578                'version' => '0.4.4.0',
    543579                'path'    => $baseDir . '/includes/Embeds/NpmEmbedTransport.php'
    544580        ),
    545581        'AcrossAI_MCP_Manager\\Includes\\I18n' => array(
    546                 'version' => '0.4.3.0',
     582                'version' => '0.4.4.0',
    547583                'path'    => $baseDir . '/includes/I18n.php'
    548584        ),
    549585        'AcrossAI_MCP_Manager\\Includes\\Loader' => array(
    550                 'version' => '0.4.3.0',
     586                'version' => '0.4.4.0',
    551587                'path'    => $baseDir . '/includes/Loader.php'
    552588        ),
    553589        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\AbstractMCPClient' => array(
    554                 'version' => '0.4.3.0',
     590                'version' => '0.4.4.0',
    555591                'path'    => $baseDir . '/includes/MCPClients/AbstractMCPClient.php'
    556592        ),
    557593        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\AmazonQClient' => array(
    558                 'version' => '0.4.3.0',
     594                'version' => '0.4.4.0',
    559595                'path'    => $baseDir . '/includes/MCPClients/AmazonQClient.php'
    560596        ),
    561597        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\AntigravityClient' => array(
    562                 'version' => '0.4.3.0',
     598                'version' => '0.4.4.0',
    563599                'path'    => $baseDir . '/includes/MCPClients/AntigravityClient.php'
    564600        ),
    565601        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\ClaudeCodeClient' => array(
    566                 'version' => '0.4.3.0',
     602                'version' => '0.4.4.0',
    567603                'path'    => $baseDir . '/includes/MCPClients/ClaudeCodeClient.php'
    568604        ),
    569605        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\ClaudeDesktopClient' => array(
    570                 'version' => '0.4.3.0',
     606                'version' => '0.4.4.0',
    571607                'path'    => $baseDir . '/includes/MCPClients/ClaudeDesktopClient.php'
    572608        ),
    573609        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\ClineClient' => array(
    574                 'version' => '0.4.3.0',
     610                'version' => '0.4.4.0',
    575611                'path'    => $baseDir . '/includes/MCPClients/ClineClient.php'
    576612        ),
    577613        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\CodexClient' => array(
    578                 'version' => '0.4.3.0',
     614                'version' => '0.4.4.0',
    579615                'path'    => $baseDir . '/includes/MCPClients/CodexClient.php'
    580616        ),
    581617        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\CursorClient' => array(
    582                 'version' => '0.4.3.0',
     618                'version' => '0.4.4.0',
    583619                'path'    => $baseDir . '/includes/MCPClients/CursorClient.php'
    584620        ),
    585621        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\CustomClient' => array(
    586                 'version' => '0.4.3.0',
     622                'version' => '0.4.4.0',
    587623                'path'    => $baseDir . '/includes/MCPClients/CustomClient.php'
    588624        ),
    589625        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\GeminiClient' => array(
    590                 'version' => '0.4.3.0',
     626                'version' => '0.4.4.0',
    591627                'path'    => $baseDir . '/includes/MCPClients/GeminiClient.php'
    592628        ),
    593629        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\GitHubCopilotClient' => array(
    594                 'version' => '0.4.3.0',
     630                'version' => '0.4.4.0',
    595631                'path'    => $baseDir . '/includes/MCPClients/GitHubCopilotClient.php'
    596632        ),
    597633        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\KiloCodeClient' => array(
    598                 'version' => '0.4.3.0',
     634                'version' => '0.4.4.0',
    599635                'path'    => $baseDir . '/includes/MCPClients/KiloCodeClient.php'
    600636        ),
    601637        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\OpenCodeClient' => array(
    602                 'version' => '0.4.3.0',
     638                'version' => '0.4.4.0',
    603639                'path'    => $baseDir . '/includes/MCPClients/OpenCodeClient.php'
    604640        ),
    605641        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\RooCodeClient' => array(
    606                 'version' => '0.4.3.0',
     642                'version' => '0.4.4.0',
    607643                'path'    => $baseDir . '/includes/MCPClients/RooCodeClient.php'
    608644        ),
    609645        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\VSCodeClient' => array(
    610                 'version' => '0.4.3.0',
     646                'version' => '0.4.4.0',
    611647                'path'    => $baseDir . '/includes/MCPClients/VSCodeClient.php'
    612648        ),
    613649        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\WindsurfClient' => array(
    614                 'version' => '0.4.3.0',
     650                'version' => '0.4.4.0',
    615651                'path'    => $baseDir . '/includes/MCPClients/WindsurfClient.php'
    616652        ),
    617653        'AcrossAI_MCP_Manager\\Includes\\MCPClients\\ZedClient' => array(
    618                 'version' => '0.4.3.0',
     654                'version' => '0.4.4.0',
    619655                'path'    => $baseDir . '/includes/MCPClients/ZedClient.php'
    620656        ),
    621657        'AcrossAI_MCP_Manager\\Includes\\MCP\\AbilityExposureGate' => array(
    622                 'version' => '0.4.3.0',
     658                'version' => '0.4.4.0',
    623659                'path'    => $baseDir . '/includes/MCP/AbilityExposureGate.php'
    624660        ),
    625661        'AcrossAI_MCP_Manager\\Includes\\MCP\\Controller' => array(
    626                 'version' => '0.4.3.0',
     662                'version' => '0.4.4.0',
    627663                'path'    => $baseDir . '/includes/MCP/Controller.php'
    628664        ),
    629665        'AcrossAI_MCP_Manager\\Includes\\MCP\\ToolExposureGate' => array(
    630                 'version' => '0.4.3.0',
     666                'version' => '0.4.4.0',
    631667                'path'    => $baseDir . '/includes/MCP/ToolExposureGate.php'
    632668        ),
    633669        'AcrossAI_MCP_Manager\\Includes\\Main' => array(
    634                 'version' => '0.4.3.0',
     670                'version' => '0.4.4.0',
    635671                'path'    => $baseDir . '/includes/Main.php'
    636672        ),
    637673        'AcrossAI_MCP_Manager\\Includes\\OAuth\\AuthorizationController' => array(
    638                 'version' => '0.4.3.0',
     674                'version' => '0.4.4.0',
    639675                'path'    => $baseDir . '/includes/OAuth/AuthorizationController.php'
    640676        ),
    641677        'AcrossAI_MCP_Manager\\Includes\\OAuth\\BearerChallengeHeader' => array(
    642                 'version' => '0.4.3.0',
     678                'version' => '0.4.4.0',
    643679                'path'    => $baseDir . '/includes/OAuth/BearerChallengeHeader.php'
    644680        ),
    645681        'AcrossAI_MCP_Manager\\Includes\\OAuth\\CimdRegistry' => array(
    646                 'version' => '0.4.3.0',
     682                'version' => '0.4.4.0',
    647683                'path'    => $baseDir . '/includes/OAuth/CimdRegistry.php'
    648684        ),
    649685        'AcrossAI_MCP_Manager\\Includes\\OAuth\\CimdResolver' => array(
    650                 'version' => '0.4.3.0',
     686                'version' => '0.4.4.0',
    651687                'path'    => $baseDir . '/includes/OAuth/CimdResolver.php'
    652688        ),
    653689        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Cleanup' => array(
    654                 'version' => '0.4.3.0',
     690                'version' => '0.4.4.0',
    655691                'path'    => $baseDir . '/includes/OAuth/Cleanup.php'
    656692        ),
    657693        'AcrossAI_MCP_Manager\\Includes\\OAuth\\ClientRegistrationController' => array(
    658                 'version' => '0.4.3.0',
     694                'version' => '0.4.4.0',
    659695                'path'    => $baseDir . '/includes/OAuth/ClientRegistrationController.php'
    660696        ),
    661697        'AcrossAI_MCP_Manager\\Includes\\OAuth\\ConnectorAdminController' => array(
    662                 'version' => '0.4.3.0',
     698                'version' => '0.4.4.0',
    663699                'path'    => $baseDir . '/includes/OAuth/ConnectorAdminController.php'
    664700        ),
    665701        'AcrossAI_MCP_Manager\\Includes\\OAuth\\DiscoveryConflictGuard' => array(
    666                 'version' => '0.4.3.0',
     702                'version' => '0.4.4.0',
    667703                'path'    => $baseDir . '/includes/OAuth/DiscoveryConflictGuard.php'
    668704        ),
    669705        'AcrossAI_MCP_Manager\\Includes\\OAuth\\DiscoveryController' => array(
    670                 'version' => '0.4.3.0',
     706                'version' => '0.4.4.0',
    671707                'path'    => $baseDir . '/includes/OAuth/DiscoveryController.php'
    672708        ),
    673709        'AcrossAI_MCP_Manager\\Includes\\OAuth\\DiscoveryHealthCheck' => array(
    674                 'version' => '0.4.3.0',
     710                'version' => '0.4.4.0',
    675711                'path'    => $baseDir . '/includes/OAuth/DiscoveryHealthCheck.php'
    676712        ),
    677713        'AcrossAI_MCP_Manager\\Includes\\OAuth\\MessagePage' => array(
    678                 'version' => '0.4.3.0',
     714                'version' => '0.4.4.0',
    679715                'path'    => $baseDir . '/includes/OAuth/MessagePage.php'
    680716        ),
    681717        'AcrossAI_MCP_Manager\\Includes\\OAuth\\OAuthRouter' => array(
    682                 'version' => '0.4.3.0',
     718                'version' => '0.4.4.0',
    683719                'path'    => $baseDir . '/includes/OAuth/OAuthRouter.php'
    684720        ),
    685721        'AcrossAI_MCP_Manager\\Includes\\OAuth\\PKCE' => array(
    686                 'version' => '0.4.3.0',
     722                'version' => '0.4.4.0',
    687723                'path'    => $baseDir . '/includes/OAuth/PKCE.php'
    688724        ),
    689725        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\AccessTokenRepository' => array(
    690                 'version' => '0.4.3.0',
     726                'version' => '0.4.4.0',
    691727                'path'    => $baseDir . '/includes/OAuth/Repositories/AccessTokenRepository.php'
    692728        ),
    693729        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\AuthCodeRepository' => array(
    694                 'version' => '0.4.3.0',
     730                'version' => '0.4.4.0',
    695731                'path'    => $baseDir . '/includes/OAuth/Repositories/AuthCodeRepository.php'
    696732        ),
    697733        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\ClientRepository' => array(
    698                 'version' => '0.4.3.0',
     734                'version' => '0.4.4.0',
    699735                'path'    => $baseDir . '/includes/OAuth/Repositories/ClientRepository.php'
    700736        ),
    701737        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\RefreshTokenRepository' => array(
    702                 'version' => '0.4.3.0',
     738                'version' => '0.4.4.0',
    703739                'path'    => $baseDir . '/includes/OAuth/Repositories/RefreshTokenRepository.php'
    704740        ),
    705741        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Repositories\\ScopeRepository' => array(
    706                 'version' => '0.4.3.0',
     742                'version' => '0.4.4.0',
    707743                'path'    => $baseDir . '/includes/OAuth/Repositories/ScopeRepository.php'
    708744        ),
    709745        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Security\\RateLimiter' => array(
    710                 'version' => '0.4.3.0',
     746                'version' => '0.4.4.0',
    711747                'path'    => $baseDir . '/includes/OAuth/Security/RateLimiter.php'
    712748        ),
    713749        'AcrossAI_MCP_Manager\\Includes\\OAuth\\Security\\SecretsVault' => array(
    714                 'version' => '0.4.3.0',
     750                'version' => '0.4.4.0',
    715751                'path'    => $baseDir . '/includes/OAuth/Security/SecretsVault.php'
    716752        ),
    717753        'AcrossAI_MCP_Manager\\Includes\\OAuth\\TokenController' => array(
    718                 'version' => '0.4.3.0',
     754                'version' => '0.4.4.0',
    719755                'path'    => $baseDir . '/includes/OAuth/TokenController.php'
    720756        ),
    721757        'AcrossAI_MCP_Manager\\Includes\\OAuth\\TokenValidator' => array(
    722                 'version' => '0.4.3.0',
     758                'version' => '0.4.4.0',
    723759                'path'    => $baseDir . '/includes/OAuth/TokenValidator.php'
    724760        ),
    725761        'AcrossAI_MCP_Manager\\Includes\\OAuth\\UserLifecycle' => array(
    726                 'version' => '0.4.3.0',
     762                'version' => '0.4.4.0',
    727763                'path'    => $baseDir . '/includes/OAuth/UserLifecycle.php'
    728764        ),
     765        'AcrossAI_MCP_Manager\\Includes\\Observability\\ActivityObservabilityHandler' => array(
     766                'version' => '0.4.4.0',
     767                'path'    => $baseDir . '/includes/Observability/ActivityObservabilityHandler.php'
     768        ),
     769        'AcrossAI_MCP_Manager\\Includes\\Observability\\AuthContextHolder' => array(
     770                'version' => '0.4.4.0',
     771                'path'    => $baseDir . '/includes/Observability/AuthContextHolder.php'
     772        ),
     773        'AcrossAI_MCP_Manager\\Includes\\Observability\\CaptureContext' => array(
     774                'version' => '0.4.4.0',
     775                'path'    => $baseDir . '/includes/Observability/CaptureContext.php'
     776        ),
     777        'AcrossAI_MCP_Manager\\Includes\\Observability\\ConnectionContext' => array(
     778                'version' => '0.4.4.0',
     779                'path'    => $baseDir . '/includes/Observability/ConnectionContext.php'
     780        ),
     781        'AcrossAI_MCP_Manager\\Includes\\Observability\\HandlerResolver' => array(
     782                'version' => '0.4.4.0',
     783                'path'    => $baseDir . '/includes/Observability/HandlerResolver.php'
     784        ),
     785        'AcrossAI_MCP_Manager\\Includes\\Observability\\PersonalData' => array(
     786                'version' => '0.4.4.0',
     787                'path'    => $baseDir . '/includes/Observability/PersonalData.php'
     788        ),
     789        'AcrossAI_MCP_Manager\\Includes\\Observability\\RecordingHealthCheck' => array(
     790                'version' => '0.4.4.0',
     791                'path'    => $baseDir . '/includes/Observability/RecordingHealthCheck.php'
     792        ),
     793        'AcrossAI_MCP_Manager\\Includes\\Observability\\ResponseSizeProbe' => array(
     794                'version' => '0.4.4.0',
     795                'path'    => $baseDir . '/includes/Observability/ResponseSizeProbe.php'
     796        ),
    729797        'AcrossAI_MCP_Manager\\Includes\\REST\\AbilitiesController' => array(
    730                 'version' => '0.4.3.0',
     798                'version' => '0.4.4.0',
    731799                'path'    => $baseDir . '/includes/REST/AbilitiesController.php'
    732800        ),
     801        'AcrossAI_MCP_Manager\\Includes\\REST\\ActivityLogController' => array(
     802                'version' => '0.4.4.0',
     803                'path'    => $baseDir . '/includes/REST/ActivityLogController.php'
     804        ),
    733805        'AcrossAI_MCP_Manager\\Includes\\REST\\CliController' => array(
    734                 'version' => '0.4.3.0',
     806                'version' => '0.4.4.0',
    735807                'path'    => $baseDir . '/includes/REST/CliController.php'
    736808        ),
    737809        'AcrossAI_MCP_Manager\\Includes\\REST\\ClientRendererController' => array(
    738                 'version' => '0.4.3.0',
     810                'version' => '0.4.4.0',
    739811                'path'    => $baseDir . '/includes/REST/ClientRendererController.php'
    740812        ),
    741813        'AcrossAI_MCP_Manager\\Includes\\REST\\QuickConnectController' => array(
    742                 'version' => '0.4.3.0',
     814                'version' => '0.4.4.0',
    743815                'path'    => $baseDir . '/includes/REST/QuickConnectController.php'
    744816        ),
    745817        'AcrossAI_MCP_Manager\\Includes\\REST\\ToolsController' => array(
    746                 'version' => '0.4.3.0',
     818                'version' => '0.4.4.0',
    747819                'path'    => $baseDir . '/includes/REST/ToolsController.php'
    748820        ),
     821        'AcrossAI_MCP_Manager\\Includes\\Utilities\\ActivityLogConstants' => array(
     822                'version' => '0.4.4.0',
     823                'path'    => $baseDir . '/includes/Utilities/ActivityLogConstants.php'
     824        ),
    749825        'AcrossAI_MCP_Manager\\Includes\\Utilities\\AdminPageSlugs' => array(
    750                 'version' => '0.4.3.0',
     826                'version' => '0.4.4.0',
    751827                'path'    => $baseDir . '/includes/Utilities/AdminPageSlugs.php'
    752828        ),
    753829        'AcrossAI_MCP_Manager\\Includes\\Utilities\\CacheHeaders' => array(
    754                 'version' => '0.4.3.0',
     830                'version' => '0.4.4.0',
    755831                'path'    => $baseDir . '/includes/Utilities/CacheHeaders.php'
    756832        ),
    757833        'AcrossAI_MCP_Manager\\Includes\\Utilities\\LocalEnvironment' => array(
    758                 'version' => '0.4.3.0',
     834                'version' => '0.4.4.0',
    759835                'path'    => $baseDir . '/includes/Utilities/LocalEnvironment.php'
    760836        ),
    761837        'AcrossAI_MCP_Manager\\Includes\\Utilities\\MCPServerFieldSanitizer' => array(
    762                 'version' => '0.4.3.0',
     838                'version' => '0.4.4.0',
    763839                'path'    => $baseDir . '/includes/Utilities/MCPServerFieldSanitizer.php'
    764840        ),
    765841        'AcrossAI_MCP_Manager\\Includes\\Utilities\\RegistryEntryNormalizer' => array(
    766                 'version' => '0.4.3.0',
     842                'version' => '0.4.4.0',
    767843                'path'    => $baseDir . '/includes/Utilities/RegistryEntryNormalizer.php'
    768844        ),
    769845        'AcrossAI_MCP_Manager\\Includes\\Utilities\\SiteSlug' => array(
    770                 'version' => '0.4.3.0',
     846                'version' => '0.4.4.0',
    771847                'path'    => $baseDir . '/includes/Utilities/SiteSlug.php'
    772848        ),
    773849        'AcrossAI_MCP_Manager\\Public\\Discovery\\ConnectionMethodRegistry' => array(
    774                 'version' => '0.4.3.0',
     850                'version' => '0.4.4.0',
    775851                'path'    => $baseDir . '/public/Discovery/ConnectionMethodRegistry.php'
    776852        ),
    777853        'AcrossAI_MCP_Manager\\Public\\Partials\\FrontendAuth' => array(
    778                 'version' => '0.4.3.0',
     854                'version' => '0.4.4.0',
    779855                'path'    => $baseDir . '/public/Partials/FrontendAuth.php'
    780856        ),
    781857        'AcrossAI_MCP_Manager\\Public\\Renderers\\AbstractClientRenderer' => array(
    782                 'version' => '0.4.3.0',
     858                'version' => '0.4.4.0',
    783859                'path'    => $baseDir . '/public/Renderers/AbstractClientRenderer.php'
    784860        ),
    785861        'AcrossAI_MCP_Manager\\Public\\Renderers\\AccessControlBlock' => array(
    786                 'version' => '0.4.3.0',
     862                'version' => '0.4.4.0',
    787863                'path'    => $baseDir . '/public/Renderers/AccessControlBlock.php'
    788864        ),
    789865        'AcrossAI_MCP_Manager\\Public\\Renderers\\EmbedBlock\\EmbedBlockRenderer' => array(
    790                 'version' => '0.4.3.0',
     866                'version' => '0.4.4.0',
    791867                'path'    => $baseDir . '/public/Renderers/EmbedBlock/EmbedBlockRenderer.php'
    792868        ),
    793869        'AcrossAI_MCP_Manager\\Public\\Renderers\\MCPClientsBlock' => array(
    794                 'version' => '0.4.3.0',
     870                'version' => '0.4.4.0',
    795871                'path'    => $baseDir . '/public/Renderers/MCPClientsBlock.php'
    796872        ),
    797873        'AcrossAI_MCP_Manager\\Public\\Renderers\\NpmClientBlock' => array(
    798                 'version' => '0.4.3.0',
     874                'version' => '0.4.4.0',
    799875                'path'    => $baseDir . '/public/Renderers/NpmClientBlock.php'
    800876        ),
    801877        'AcrossAI_MCP_Manager\\Public\\Renderers\\UserServers\\AbstractUserServersRenderer' => array(
    802                 'version' => '0.4.3.0',
     878                'version' => '0.4.4.0',
    803879                'path'    => $baseDir . '/public/Renderers/UserServers/AbstractUserServersRenderer.php'
    804880        ),
    805881        'AcrossAI_MCP_Manager\\Public\\Renderers\\UserServers\\UserServersBlock' => array(
    806                 'version' => '0.4.3.0',
     882                'version' => '0.4.4.0',
    807883                'path'    => $baseDir . '/public/Renderers/UserServers/UserServersBlock.php'
    808884        ),
Note: See TracChangeset for help on using the changeset viewer.