Plugin Directory

Changeset 3723403


Ignore:
Timestamp:
10/01/2026 03:27:15 PM (5 weeks ago)
Author:
cyberlord92
Message:

Fixes feedback email subject and formatting and adds 12 built-in crawlers including YandexBot, Slurp, Sogou web spider, Quora-Bot, and LinerBot

Location:
miniorange-ai-visibility
Files:
218 added
14 edited

Legend:

Unmodified
Added
Removed
  • miniorange-ai-visibility/trunk/assets/js/ai-inventory.js

    r3636134 r3723403  
    481481                var s = strings();
    482482                var $text = $( '#moai-av-inv-live-text' );
     483                var $indicator = $( '#moai-av-inv-live' );
    483484                var generated = parseGeneratedDate();
     485                var agentCount = parseInt( String( $( '[data-inv-count="agents"]' ).first().text() ).replace( /[^\d]/g, '' ), 10 ) || 0;
     486                var serverCount = parseInt( String( $( '[data-inv-count="mcp_servers"]' ).first().text() ).replace( /[^\d]/g, '' ), 10 ) || 0;
    484487                var label;
    485488
     489                if ( 0 === agentCount && 0 === serverCount ) {
     490                        $indicator.addClass( 'is-waiting' );
     491                        $text.text( s.waiting || 'Waiting for AI traffic' );
     492                        return;
     493                }
     494
     495                $indicator.removeClass( 'is-waiting' );
    486496                if ( ! generated ) {
    487497                        label = ( s.live || 'Live' ) + ' · ' + ( s.justNow || 'just now' );
  • miniorange-ai-visibility/trunk/assets/js/contact-us.js

    r3629940 r3723403  
    2121        }
    2222
     23        function pluginName() {
     24                return cfg().plugin_name || 'AI Crawlers Visibility, Analytics & Control';
     25        }
     26
     27        function buildSubject( query ) {
     28                var issue = String( query ).split( /\r?\n/ )[ 0 ].trim();
     29                var subject = 'Feedback - ' + pluginName();
     30
     31                if ( ! issue ) {
     32                        return subject;
     33                }
     34
     35                if ( issue.length > 80 ) {
     36                        issue = issue.slice( 0, 77 ) + '…';
     37                }
     38
     39                return subject + ' - ' + issue;
     40        }
     41
     42        function buildBody( email, query ) {
     43                var c = cfg();
     44                var name = ( ( c.first_name || '' ) + ' ' + ( c.last_name || '' ) ).trim();
     45
     46                return [
     47                        'Feedback - ' + pluginName(),
     48                        '',
     49                        'Plugin: ' + pluginName(),
     50                        'Version: ' + ( c.version || '' ),
     51                        'Site: ' + ( c.site_url || '' ),
     52                        'WordPress: ' + ( c.wp_version || '' ),
     53                        'PHP: ' + ( c.php_version || '' ),
     54                        'From: ' + ( name ? name + ' <' + email + '>' : email ),
     55                        '',
     56                        'Message:',
     57                        query,
     58                ].join( '\n' );
     59        }
     60
    2361        function buildPayload( email, query ) {
    2462                var c = cfg();
    25                 var prefix = '[' + ( c.plugin_name || 'AI Crawlers Visibility, Analytics & Control' ) + '] ' + ( c.version || '' ) + ' - ';
     63                var subject = buildSubject( query );
    2664
    2765                return {
    2866                        email: email,
    29                         query: prefix + query,
     67                        subject: subject,
     68                        topic: subject,
     69                        query: buildBody( email, query ),
    3070                        ccEmail: c.support_email || '',
    3171                        company: c.site_url || '',
    3272                        firstName: c.first_name || '',
    3373                        lastName: c.last_name || '',
    34                         areaOfInterest: c.area_of_interest || c.plugin_name || 'AI Crawlers Visibility, Analytics & Control',
     74                        areaOfInterest: c.area_of_interest || pluginName(),
     75                        request_type: 'plugin_support_request',
    3576                };
    3677        }
  • miniorange-ai-visibility/trunk/includes/common/controllers/class-ai-inventory-controller.php

    r3636134 r3723403  
    159159                return array(
    160160                        'live'          => __( 'Live', 'miniorange-ai-visibility' ),
     161                        'waiting'       => __( 'Waiting for AI traffic', 'miniorange-ai-visibility' ),
    161162                        'refreshed'     => __( 'refreshed %s ago', 'miniorange-ai-visibility' ),
    162163                        'justNow'       => __( 'just now', 'miniorange-ai-visibility' ),
  • miniorange-ai-visibility/trunk/includes/common/controllers/class-settings-controller.php

    r3670315 r3723403  
    288288                                        'requiredFields'    => __( 'Name and user-agent pattern are required.', 'miniorange-ai-visibility' ),
    289289                                        'genericError'      => __( 'Something went wrong. Please try again.', 'miniorange-ai-visibility' ),
    290                                         'robotsRuleAdded'   => __( 'robots.txt disallow rule added.', 'miniorange-ai-visibility' ),
    291                                         'robotsRuleRemoved' => __( 'robots.txt disallow rule removed.', 'miniorange-ai-visibility' ),
    292                                         'bulkDisallowDone'  => __( 'Category disallow template applied.', 'miniorange-ai-visibility' ),
     290                                        'robotsRuleAdded'   => __( 'The bot has been asked not to crawl in robots.txt.', 'miniorange-ai-visibility' ),
     291                                        'robotsRuleRemoved' => __( 'The robots.txt crawl restriction was removed.', 'miniorange-ai-visibility' ),
     292                                        'bulkDisallowDone'  => __( 'The selected bot category has been asked not to crawl.', 'miniorange-ai-visibility' ),
    293293                                        'bulkAllowDone'     => __( 'Category allow template applied.', 'miniorange-ai-visibility' ),
    294                                         'confirmBulkDisallow' => __( 'Disallow all crawlers in this category in robots.txt?', 'miniorange-ai-visibility' ),
     294                                        'confirmBulkDisallow' => __( 'Ask every bot in this category not to crawl your site?', 'miniorange-ai-visibility' ),
    295295                                        'confirmBulkAllow'    => __( 'Allow all crawlers in this category again (remove Disallow rules)?', 'miniorange-ai-visibility' ),
    296                                         'blocked'           => __( 'Crawler blocked via PHP.', 'miniorange-ai-visibility' ),
    297                                         'ipBlocked'         => __( 'IP address blocked via PHP.', 'miniorange-ai-visibility' ),
     296                                        'blocked'           => __( 'The bot is now hard-blocked.', 'miniorange-ai-visibility' ),
     297                                        'ipBlocked'         => __( 'The IP address is now hard-blocked.', 'miniorange-ai-visibility' ),
    298298                                        'unblocked'         => __( 'Crawler unblocked.', 'miniorange-ai-visibility' ),
    299299                                        'invalidIp'         => __( 'Enter a valid IPv4 or IPv6 address.', 'miniorange-ai-visibility' ),
    300                                         'robotsDisallowed'  => __( 'Disallowed in robots.txt', 'miniorange-ai-visibility' ),
    301                                         'phpBlocked'        => __( 'PHP blocked', 'miniorange-ai-visibility' ),
    302                                         'disallowRobots'    => __( 'Disallow in robots.txt', 'miniorange-ai-visibility' ),
     300                                        'robotsDisallowed'  => __( 'Asked not to crawl', 'miniorange-ai-visibility' ),
     301                                        'phpBlocked'        => __( 'Hard blocked', 'miniorange-ai-visibility' ),
     302                                        'disallowRobots'    => __( 'Ask not to crawl (robots.txt)', 'miniorange-ai-visibility' ),
    303303                                        'allowRobots'       => __( 'Allow in robots.txt', 'miniorange-ai-visibility' ),
    304                                         'blockPhp'          => __( 'Block via PHP (403)', 'miniorange-ai-visibility' ),
    305                                         'unblockPhp'        => __( 'Unblock PHP', 'miniorange-ai-visibility' ),
     304                                        'blockPhp'          => __( 'Hard block this bot', 'miniorange-ai-visibility' ),
     305                                        'unblockPhp'        => __( 'Remove hard block', 'miniorange-ai-visibility' ),
    306306                                        'selectCrawler'     => __( 'Please select a crawler.', 'miniorange-ai-visibility' ),
    307307                                        'alreadyDisallowed' => __( 'This crawler is already disallowed in robots.txt.', 'miniorange-ai-visibility' ),
    308308                                        'notDisallowed'     => __( 'This crawler is not disallowed in robots.txt.', 'miniorange-ai-visibility' ),
    309                                         'alreadyBlocked'    => __( 'This crawler is already PHP-blocked.', 'miniorange-ai-visibility' ),
    310                                         'enablePhpBlocking' => __( 'Enable PHP blocking first.', 'miniorange-ai-visibility' ),
     309                                        'alreadyBlocked'    => __( 'This bot is already hard-blocked.', 'miniorange-ai-visibility' ),
     310                                        'enablePhpBlocking' => __( 'Enable hard blocking first.', 'miniorange-ai-visibility' ),
    311311                                        'crawlerCount'      => __( 'Showing %1$d of %2$d crawlers.', 'miniorange-ai-visibility' ),
    312312                                        'prevPage'          => __( 'Previous', 'miniorange-ai-visibility' ),
  • miniorange-ai-visibility/trunk/includes/common/data/builtin-crawlers.php

    r3670315 r3723403  
    576576                'category' => 'scraper',
    577577        ),
     578        'YandexBot'                    => array(
     579                'name'     => 'YandexBot',
     580                'company'  => 'Yandex',
     581                'category' => 'search',
     582        ),
     583        'Slurp'                        => array(
     584                'name'     => 'Slurp',
     585                'company'  => 'Yahoo',
     586                'category' => 'search',
     587        ),
     588        'Sogou web spider'             => array(
     589                'name'     => 'Sogou web spider',
     590                'company'  => 'Sogou',
     591                'category' => 'search',
     592        ),
     593        'Quora-Bot'                    => array(
     594                'name'     => 'Quora-Bot',
     595                'company'  => 'Quora',
     596                'category' => 'assistant',
     597        ),
     598        'LinerBot'                     => array(
     599                'name'     => 'LinerBot',
     600                'company'  => 'Liner',
     601                'category' => 'search',
     602        ),
     603        'Awario'                       => array(
     604                'name'     => 'Awario',
     605                'company'  => 'Awario',
     606                'category' => 'scraper',
     607        ),
     608        'Meltwater'                    => array(
     609                'name'     => 'Meltwater',
     610                'company'  => 'Meltwater',
     611                'category' => 'scraper',
     612        ),
     613        'Poseidon Research Crawler'    => array(
     614                'name'     => 'Poseidon Research Crawler',
     615                'company'  => 'Poseidon Research',
     616                'category' => 'training',
     617        ),
     618        'Sidetrade indexer bot'        => array(
     619                'name'     => 'Sidetrade indexer bot',
     620                'company'  => 'Sidetrade',
     621                'category' => 'scraper',
     622        ),
     623        'NetEstate Imprint Crawler'    => array(
     624                'name'     => 'NetEstate Imprint Crawler',
     625                'company'  => 'NetEstate',
     626                'category' => 'scraper',
     627        ),
     628        'Scrapy'                       => array(
     629                'name'     => 'Scrapy',
     630                'company'  => 'Scrapy',
     631                'category' => 'scraper',
     632        ),
     633        'python-requests'              => array(
     634                'name'     => 'python-requests',
     635                'company'  => 'Requests',
     636                'category' => 'scraper',
     637        ),
    578638);
  • miniorange-ai-visibility/trunk/includes/common/handlers/class-contact-us-handler.php

    r3602565 r3723403  
    4141
    4242                $current_user = wp_get_current_user();
     43                $subject      = self::build_subject( $query );
    4344                $payload      = array(
    4445                        'email'          => $email,
    45                         'query'          => '[' . Plugin_Constants::PLUGIN_DISPLAY_NAME . '] ' . MOAI_AV_VERSION . ' - ' . $query,
     46                        'subject'        => $subject,
     47                        'topic'          => $subject,
     48                        'query'          => $this->build_body( $email, $query ),
    4649                        'ccEmail'        => Plugin_Constants::SUPPORT_EMAIL,
    4750                        'company'        => site_url(),
    … …  
    4952                        'lastName'       => $current_user ? (string) $current_user->user_lastname : '',
    5053                        'areaOfInterest' => Plugin_Constants::PLUGIN_DISPLAY_NAME,
     54                        'request_type'   => 'plugin_support_request',
    5155                );
    5256
    … …  
    7680                );
    7781        }
     82
     83        /**
     84         * Build the support email subject: "Feedback - <Plugin> - <issue>".
     85         *
     86         * @param string $query Message body.
     87         * @return string
     88         */
     89        public static function build_subject( string $query ): string {
     90                $subject = 'Feedback - ' . Plugin_Constants::PLUGIN_DISPLAY_NAME;
     91                $issue   = self::summarize_issue( $query );
     92
     93                if ( '' !== $issue ) {
     94                        $subject .= ' - ' . $issue;
     95                }
     96
     97                return $subject;
     98        }
     99
     100        /**
     101         * First line of the message, trimmed to a readable subject length.
     102         *
     103         * @param string $query Message body.
     104         * @return string
     105         */
     106        private static function summarize_issue( string $query ): string {
     107                $lines = preg_split( '/\R/', trim( $query ) );
     108                $issue = is_array( $lines ) ? trim( (string) reset( $lines ) ) : '';
     109
     110                if ( '' === $issue ) {
     111                        return '';
     112                }
     113
     114                if ( mb_strlen( $issue ) > 80 ) {
     115                        $issue = mb_substr( $issue, 0, 77 ) . '…';
     116                }
     117
     118                return $issue;
     119        }
     120
     121        /**
     122         * Build a readable, line-separated support email body.
     123         *
     124         * @param string $email Reply-to email.
     125         * @param string $query Message body.
     126         * @return string
     127         */
     128        private function build_body( string $email, string $query ): string {
     129                global $wp_version;
     130
     131                $current_user = wp_get_current_user();
     132                $name         = trim( ( $current_user ? (string) $current_user->user_firstname : '' ) . ' ' . ( $current_user ? (string) $current_user->user_lastname : '' ) );
     133                if ( '' === $name && $current_user ) {
     134                        $name = (string) $current_user->display_name;
     135                }
     136
     137                $lines = array(
     138                        'Feedback - ' . Plugin_Constants::PLUGIN_DISPLAY_NAME,
     139                        '',
     140                        'Plugin: ' . Plugin_Constants::PLUGIN_DISPLAY_NAME,
     141                        'Version: ' . ( defined( 'MOAI_AV_VERSION' ) ? MOAI_AV_VERSION : '' ),
     142                        'Site: ' . site_url(),
     143                        'WordPress: ' . ( isset( $wp_version ) ? (string) $wp_version : '' ),
     144                        'PHP: ' . PHP_VERSION,
     145                        'From: ' . ( '' !== $name ? $name . ' <' . $email . '>' : $email ),
     146                        '',
     147                        'Message:',
     148                        $query,
     149                );
     150
     151                return implode( "\n", $lines );
     152        }
    78153}
  • miniorange-ai-visibility/trunk/includes/common/handlers/class-deactivation-feedback-handler.php

    r3646604 r3723403  
    5757                        ),
    5858                        'plugin_deactivation_feedback',
    59                         $email
     59                        $email,
     60                        $reason_label
    6061                );
    6162
    … …  
    8384                        ),
    8485                        'plugin_deactivation_no_feedback',
    85                         $email
     86                        $email,
     87                        __( 'Deactivated without feedback', 'miniorange-ai-visibility' )
    8688                );
    8789
    … …  
    112114                        ),
    113115                        'plugin_deactivation_hook',
    114                         ''
     116                        '',
     117                        __( 'Deactivated without feedback', 'miniorange-ai-visibility' )
    115118                );
    116119        }
    … …  
    122125         * @param string             $request_type Request type tag.
    123126         * @param string             $email        Optional email override.
     127         * @param string             $issue        Short issue summary for the subject.
    124128         * @return true|\WP_Error
    125129         */
    126         private function send_notice( array $query_lines, string $request_type, string $email = '' ) {
     130        private function send_notice( array $query_lines, string $request_type, string $email = '', string $issue = '' ) {
     131                global $wp_version;
     132
    127133                $current_user = wp_get_current_user();
    128134                $user_email   = $current_user && $current_user->user_email ? (string) $current_user->user_email : '';
    … …  
    133139                }
    134140
     141                $subject = 'Feedback - ' . Plugin_Constants::PLUGIN_DISPLAY_NAME . ' - ' . __( 'Deactivation', 'miniorange-ai-visibility' );
     142                if ( '' !== $issue ) {
     143                        $subject .= ': ' . $issue;
     144                }
     145
    135146                $lines   = array_merge(
    136147                        array(
    137                                 'Deactivation Notice',
     148                                $subject,
     149                                '',
    138150                                'Plugin: ' . Plugin_Constants::PLUGIN_DISPLAY_NAME,
    139151                                'Version: ' . ( defined( 'MOAI_AV_VERSION' ) ? MOAI_AV_VERSION : '' ),
    140152                                'Site: ' . site_url(),
     153                                'WordPress: ' . ( isset( $wp_version ) ? (string) $wp_version : '' ),
     154                                'PHP: ' . PHP_VERSION,
     155                                'From: ' . $final_email,
     156                                '',
     157                                'Deactivation feedback:',
    141158                        ),
    142159                        $query_lines
    … …  
    144161                $payload = array(
    145162                        'email'          => $final_email,
     163                        'subject'        => $subject,
     164                        'topic'          => $subject,
    146165                        'query'          => implode( "\n", $lines ),
    147166                        'ccEmail'        => Plugin_Constants::SUPPORT_EMAIL,
  • miniorange-ai-visibility/trunk/includes/common/hooks/class-contact-us-hooks.php

    r3602565 r3723403  
    5656                );
    5757
     58                global $wp_version;
     59
    5860                $current_user = wp_get_current_user();
    5961                wp_localize_script(
    … …  
    6668                                'area_of_interest' => Plugin_Constants::PLUGIN_DISPLAY_NAME,
    6769                                'version'        => MOAI_AV_VERSION,
     70                                'wp_version'     => isset( $wp_version ) ? (string) $wp_version : '',
     71                                'php_version'    => PHP_VERSION,
    6872                                'site_url'       => site_url(),
    6973                                'first_name'     => $current_user ? (string) $current_user->user_firstname : '',
  • miniorange-ai-visibility/trunk/miniorange-ai-visibility.php

    r3694415 r3723403  
    44 * Plugin URI:        https://plugins.miniorange.com/
    55 * Description:       Monitor AI crawlers and MCP traffic, inventory agents and tools, control access, and improve AI visibility with llms.txt and readiness checks.
    6  * Version:           1.8.1
     6 * Version:           1.8.2
    77 * Requires at least: 5.0
    88 * Requires PHP:      7.4
  • miniorange-ai-visibility/trunk/readme.txt

    r3694415 r3723403  
    55Tested up to: 7.0.1
    66Requires PHP: 7.4
    7 Stable tag: 1.8.1
     7Stable tag: 1.8.2
    88License: Expat
    99License URI: https://plugins.miniorange.com/mit-license
    … …  
    380380== Changelog ==
    381381
     382= 1.8.2 =
     383* Fixed support and deactivation feedback emails arriving as a generic inquiry — they now use a descriptive subject: `Feedback - AI Crawlers Visibility, Analytics & Control - <issue>`.
     384* Fixed feedback email formatting: labelled lines for plugin, version, site, WordPress, PHP, and sender, with the customer message in its own block.
     385* Added 12 built-in crawlers: YandexBot, Slurp (Yahoo), Sogou web spider, Quora-Bot, LinerBot, Awario, Meltwater, Poseidon Research Crawler, Sidetrade indexer bot, NetEstate Imprint Crawler, Scrapy, and python-requests (125 total).
     386
    382387= 1.8.1 =
    383388* First-run Analytics guidance: status that crawler tracking is on, why metrics show 0, and a primary **Check Your Homepage** action.
    … …  
    535540== Upgrade Notice ==
    536541
     542= 1.8.2 =
     543Fixes feedback email subject and formatting (no longer sent as a generic inquiry) and adds 12 built-in crawlers including YandexBot, Slurp, Sogou web spider, Quora-Bot, and LinerBot (125 total).
     544
    537545= 1.8.1 =
    538546Improves first-run Analytics: tracking status, empty-state next steps, homepage Visibility Score CTA, and optional MCP cards until tool traffic appears.
  • miniorange-ai-visibility/trunk/views/src/common/components/class-app-shell-view.php

    r3636134 r3723403  
    8484                                                <?php $this->render_nav_group( __( 'Controls', 'miniorange-ai-visibility' ), $this->get_controls_items() ); ?>
    8585                                                <?php $this->render_nav_group( __( 'Monitoring', 'miniorange-ai-visibility' ), $this->get_monitoring_items() ); ?>
    86                                                 <?php $this->render_nav_group( __( 'Optimize', 'miniorange-ai-visibility' ), $this->get_optimize_items() ); ?>
     86                                                <?php $this->render_nav_group( __( 'Advanced', 'miniorange-ai-visibility' ), $this->get_advanced_items() ); ?>
    8787                                                <?php $this->render_wp_submenu_group(); ?>
    8888                                        </nav>
    … …  
    163163                return array(
    164164                        array(
     165                                'slug'  => 'visibility',
     166                                'label' => __( 'Visibility Score', 'miniorange-ai-visibility' ),
     167                                'icon'  => 'moai-i-gauge',
     168                                'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_VISIBILITY ),
     169                        ),
     170                        array(
    165171                                'slug'  => 'analytics',
    166172                                'label' => __( 'Analytics', 'miniorange-ai-visibility' ),
    … …  
    174180                                'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_ANALYTICS . '&tab=inventory' ),
    175181                        ),
     182                        array(
     183                                'slug'  => 'discoverability',
     184                                'label' => __( 'Help AI Find Your Content', 'miniorange-ai-visibility' ),
     185                                'icon'  => 'moai-i-doc',
     186                                'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_DISCOVERABILITY ),
     187                        ),
    176188                );
    177189        }
    … …  
    196208                                'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_SETTINGS . '&tab=control' ),
    197209                        ),
    198                         array(
    199                                 'slug'  => 'mcp-control',
    200                                 'label' => __( 'MCP Control', 'miniorange-ai-visibility' ),
    201                                 'icon'  => 'moai-i-lock',
    202                                 'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_MCP_CONTROL ),
    203                         ),
    204210                );
    205211        }
    … …  
    218224                                'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_ANALYTICS . '&tab=activity' ),
    219225                        ),
     226                );
     227        }
     228
     229        /**
     230         * Advanced nav items.
     231         *
     232         * @return array<int, array<string, mixed>>
     233         */
     234        private function get_advanced_items(): array {
     235                return array(
    220236                        array(
    221237                                'slug'  => 'mcp-tracker',
    222                                 'label' => __( 'MCP Log', 'miniorange-ai-visibility' ),
     238                                'label' => __( 'AI Tool Log (MCP)', 'miniorange-ai-visibility' ),
    223239                                'icon'  => 'moai-i-sparkle',
    224240                                'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_MCP_TRACKER ),
    225241                        ),
    226                 );
    227         }
    228 
    229         /**
    230          * Optimize nav items.
    231          *
    232          * @return array<int, array<string, mixed>>
    233          */
    234         private function get_optimize_items(): array {
    235                 return array(
    236                         array(
    237                                 'slug'  => 'visibility',
    238                                 'label' => __( 'Visibility Score', 'miniorange-ai-visibility' ),
    239                                 'icon'  => 'moai-i-gauge',
    240                                 'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_VISIBILITY ),
    241                         ),
    242                         array(
    243                                 'slug'  => 'discoverability',
    244                                 'label' => __( 'Discoverability', 'miniorange-ai-visibility' ),
    245                                 'icon'  => 'moai-i-doc',
    246                                 'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_DISCOVERABILITY ),
     242                        array(
     243                                'slug'  => 'mcp-control',
     244                                'label' => __( 'AI Tool Access (MCP)', 'miniorange-ai-visibility' ),
     245                                'icon'  => 'moai-i-lock',
     246                                'url'   => admin_url( 'admin.php?page=' . Plugin_Constants::MENU_SLUG_MCP_CONTROL ),
    247247                        ),
    248248                );
  • miniorange-ai-visibility/trunk/views/src/common/pages/ai-inventory/class-ai-inventory-view.php

    r3636134 r3723403  
    4545         */
    4646        public function render(): void {
     47                $snapshot     = (array) ( $this->data['snapshot'] ?? array() );
     48                $counts       = (array) ( $snapshot['counts'] ?? array() );
     49                $has_activity = ! empty( $counts['agents'] ) || ! empty( $counts['mcp_servers'] );
     50
    4751                $shell = new App_Shell_View( 'ai-inventory' );
    4852                $shell->open();
    … …  
    5054                ( new App_Header_View(
    5155                        __( 'AI Inventory', 'miniorange-ai-visibility' ),
    52                         __( 'Live catalog of agents, MCP servers, and tools touching this site', 'miniorange-ai-visibility' ),
    53                         self::get_live_indicator_html()
     56                        __( 'AI bots and connected AI tools detected on this site.', 'miniorange-ai-visibility' ),
     57                        self::get_live_indicator_html( $has_activity )
    5458                ) )->render();
    5559
    … …  
    6266         * Live indicator markup for the page header.
    6367         *
     68         * @param bool $has_activity Whether inventory data has been recorded.
    6469         * @return string
    6570         */
    66         public static function get_live_indicator_html(): string {
     71        public static function get_live_indicator_html( bool $has_activity = false ): string {
    6772                ob_start();
    6873                ?>
    69                 <div class="moai-av-live-indicator" id="moai-av-inv-live" aria-live="polite">
     74                <div class="moai-av-live-indicator<?php echo esc_attr( $has_activity ? '' : ' is-waiting' ); ?>" id="moai-av-inv-live" aria-live="polite">
    7075                        <span class="moai-av-live-dot" aria-hidden="true"></span>
    7176                        <span class="moai-av-live-indicator__text" id="moai-av-inv-live-text">
    72                                 <?php esc_html_e( 'Live · refreshed just now', 'miniorange-ai-visibility' ); ?>
     77                                <?php echo $has_activity ? esc_html__( 'Live · refreshed just now', 'miniorange-ai-visibility' ) : esc_html__( 'Waiting for AI traffic', 'miniorange-ai-visibility' ); ?>
    7378                        </span>
    7479                </div>
    … …  
    182187                                <div class="moai-av-empty-state">
    183188                                        <div class="moai-av-empty-state__icon" aria-hidden="true">🛰️</div>
    184                                         <h3><?php esc_html_e( 'No AI traffic catalogued yet', 'miniorange-ai-visibility' ); ?></h3>
    185                                         <p><?php esc_html_e( 'Once AI crawlers visit your site or an MCP client calls a tool, they will appear here automatically.', 'miniorange-ai-visibility' ); ?></p>
     189                                        <h3><?php esc_html_e( 'Waiting for your first AI visitor', 'miniorange-ai-visibility' ); ?></h3>
     190                                        <p><?php esc_html_e( 'The inventory fills automatically after an AI bot visits your site. Connected AI tools (MCP) are optional and only appear if you use them.', 'miniorange-ai-visibility' ); ?></p>
    186191                                </div>
    187192                        </div>
  • miniorange-ai-visibility/trunk/views/src/common/pages/discoverability/class-discoverability-view.php

    r3670315 r3723403  
    6565
    6666                ( new App_Header_View(
    67                         __( 'Discoverability', 'miniorange-ai-visibility' ),
    68                         __( 'Publish structured, agent-friendly versions of your site content.', 'miniorange-ai-visibility' ),
     67                        __( 'Help AI Find Your Content', 'miniorange-ai-visibility' ),
     68                        __( 'Publish clear, AI-friendly versions of your public site content.', 'miniorange-ai-visibility' ),
    6969                        '<button type="button" class="moai-av-btn moai-av-btn-primary" id="moai-av-discoverability-save">' . esc_html__( 'Save settings', 'miniorange-ai-visibility' ) . '</button>'
    7070                ) )->render();
    … …  
    7474
    7575                        <div class="moai-av-section">
    76                                 <div class="moai-av-section-switch moai-av-section-switch--discover" role="tablist" aria-label="<?php esc_attr_e( 'Discoverability tools', 'miniorange-ai-visibility' ); ?>">
     76                                <div class="moai-av-card moai-av-discover-start">
     77                                        <div class="moai-av-discover-start__content">
     78                                                <span class="moai-av-pill moai-av-pill--ok"><?php esc_html_e( 'Recommended first step', 'miniorange-ai-visibility' ); ?></span>
     79                                                <h2><?php esc_html_e( 'Publish an AI-readable map of your site', 'miniorange-ai-visibility' ); ?></h2>
     80                                                <p><?php esc_html_e( 'Turn on llms.txt to give AI assistants a simple list of your most important public content. You can review the generated file before sharing it.', 'miniorange-ai-visibility' ); ?></p>
     81                                        </div>
     82                                        <a class="moai-av-btn moai-av-btn-primary" href="#moai-av-section-llms">
     83                                                <?php echo ! empty( $llms['enabled'] ) ? esc_html__( 'Review llms.txt', 'miniorange-ai-visibility' ) : esc_html__( 'Set Up llms.txt', 'miniorange-ai-visibility' ); ?>
     84                                        </a>
     85                                </div>
     86                        </div>
     87
     88                        <div class="moai-av-section">
     89                                <div class="moai-av-section-switch moai-av-section-switch--discover">
    7790                                        <button
    7891                                                type="button"
    … …  
    8699                                                <?php esc_html_e( 'llms.txt', 'miniorange-ai-visibility' ); ?>
    87100                                        </button>
     101                                        <details class="moai-av-discover-more">
     102                                                <summary><?php esc_html_e( 'More options', 'miniorange-ai-visibility' ); ?></summary>
     103                                                <div class="moai-av-discover-more__tabs" role="tablist" aria-label="<?php esc_attr_e( 'Additional discoverability tools', 'miniorange-ai-visibility' ); ?>">
    88104                                        <button
    89105                                                type="button"
    … …  
    141157                                                <?php esc_html_e( 'IndexNow', 'miniorange-ai-visibility' ); ?>
    142158                                        </button>
     159                                                </div>
     160                                        </details>
    143161                                </div>
    144162                        </div>
    … …  
    154172                                                                printf(
    155173                                                                        /* translators: %s: llms.txt URL */
    156                                                                         esc_html__( 'Published at %s with optional llms-full.txt for complete content.', 'miniorange-ai-visibility' ),
     174                                                                        esc_html__( 'Creates a simple content map for AI assistants at %s. An optional full version can include complete content.', 'miniorange-ai-visibility' ),
    157175                                                                        '<code>/llms.txt</code>'
    158176                                                                );
  • miniorange-ai-visibility/trunk/views/src/common/pages/settings/class-settings-view.php

    r3670315 r3723403  
    8181                $header_titles       = array(
    8282                        'crawlers' => array( __( 'AI Crawlers', 'miniorange-ai-visibility' ), __( 'Choose which bots are tracked, and add your own.', 'miniorange-ai-visibility' ) ),
    83                         'control'  => array( __( 'Crawler Control', 'miniorange-ai-visibility' ), __( 'Decide who gets in — robots.txt rules and PHP blocking.', 'miniorange-ai-visibility' ) ),
     83                        'control'  => array( __( 'Crawler Control', 'miniorange-ai-visibility' ), __( 'Ask AI bots not to crawl, or force-block bots that ignore your request.', 'miniorange-ai-visibility' ) ),
    8484                        'account'  => array( __( 'Settings', 'miniorange-ai-visibility' ), __( 'Data preferences and email reports.', 'miniorange-ai-visibility' ) ),
    8585                );
    … …  
    263263                                        <div class="moai-av-section-head">
    264264                                                <div>
    265                                                         <h2><?php esc_html_e( 'robots.txt rules', 'miniorange-ai-visibility' ); ?></h2>
    266                                                         <div class="moai-av-section-desc"><?php esc_html_e( 'Disallow selected bots — changes apply the moment you save', 'miniorange-ai-visibility' ); ?></div>
     265                                                        <h2><?php esc_html_e( 'Ask bots not to crawl (robots.txt)', 'miniorange-ai-visibility' ); ?></h2>
     266                                                        <div class="moai-av-section-desc"><?php esc_html_e( 'Publish a standard request that selected bots avoid your site. Cooperative bots will respect it; others may ignore it.', 'miniorange-ai-visibility' ); ?></div>
    267267                                                </div>
    268268                                        </div>
    … …  
    286286                                                                                <?php $this->render_crawler_select( 'moai-av-robots-crawler-select', $monitored_crawlers, ! $robots_txt_enabled ); ?>
    287287                                                                                <button type="button" class="moai-av-btn moai-av-btn-ghost" id="moai-av-robots-disallow-btn"<?php disabled( ! $robots_txt_enabled ); ?>>
    288                                                                                         <?php esc_html_e( 'Disallow in robots.txt', 'miniorange-ai-visibility' ); ?>
     288                                                                                        <?php esc_html_e( 'Ask This Bot Not to Crawl', 'miniorange-ai-visibility' ); ?>
    289289                                                                                </button>
    290290                                                                        </div>
    … …  
    317317                                                                                                                printf(
    318318                                                                                                                        /* translators: %s: crawler category label */
    319                                                                                                                         esc_html__( 'Disallow all %s', 'miniorange-ai-visibility' ),
     319                                                                                                                        esc_html__( 'Ask all %s bots not to crawl', 'miniorange-ai-visibility' ),
    320320                                                                                                                        esc_html( (string) $category_label )
    321321                                                                                                                );
    … …  
    362362                                        <div class="moai-av-section-head">
    363363                                                <div>
    364                                                         <h2><?php esc_html_e( 'PHP blocking', 'miniorange-ai-visibility' ); ?></h2>
    365                                                         <div class="moai-av-section-desc"><?php esc_html_e( 'Return a 403 response instead of serving pages — bots that ignore robots.txt still get blocked', 'miniorange-ai-visibility' ); ?></div>
     364                                                        <h2><?php esc_html_e( 'Hard blocking', 'miniorange-ai-visibility' ); ?></h2>
     365                                                        <div class="moai-av-section-desc"><?php esc_html_e( 'Refuse access instead of serving the page. Use this for bots that ignore your robots.txt request.', 'miniorange-ai-visibility' ); ?></div>
    366366                                                </div>
    367367                                        </div>
    368368                                        <div class="moai-av-card moai-av-card-flush" id="moai-av-blocking-section">
    369369                                                <div class="moai-av-settings-row">
    370                                                         <div><div class="moai-av-s-label"><?php esc_html_e( 'Enable PHP blocking', 'miniorange-ai-visibility' ); ?></div></div>
     370                                                        <div><div class="moai-av-s-label"><?php esc_html_e( 'Enable hard blocking', 'miniorange-ai-visibility' ); ?></div></div>
    371371                                                        <label class="moai-av-toggle">
    372372                                                                <input type="checkbox" id="moai-av-php-blocking-enabled" <?php checked( $php_blocking_enabled ); ?> />
    … …  
    401401                                                                        <?php $this->render_crawler_select( 'moai-av-php-crawler-select', $monitored_crawlers, ! $php_blocking_enabled ); ?>
    402402                                                                        <button type="button" class="moai-av-btn moai-av-btn-ghost" id="moai-av-php-block-btn"<?php disabled( ! $php_blocking_enabled ); ?>>
    403                                                                                 <?php esc_html_e( 'Block via PHP (403)', 'miniorange-ai-visibility' ); ?>
     403                                                                                <?php esc_html_e( 'Hard Block This Bot', 'miniorange-ai-visibility' ); ?>
    404404                                                                        </button>
    405405                                                                </div>
    406406                                                        </div>
    407407                                                        <div class="moai-av-field">
    408                                                                 <label for="moai-av-php-block-message"><?php esc_html_e( 'Custom 403 message', 'miniorange-ai-visibility' ); ?></label>
     408                                                                <label for="moai-av-php-block-message"><?php esc_html_e( 'Access denied message', 'miniorange-ai-visibility' ); ?></label>
    409409                                                                <textarea
    410410                                                                        id="moai-av-php-block-message"
    … …  
    414414                                                                        <?php disabled( ! $php_blocking_enabled ); ?>
    415415                                                                ><?php echo esc_textarea( $php_block_message ); ?></textarea>
    416                                                                 <p class="moai-av-muted"><?php esc_html_e( 'Shown as plain text when a PHP-blocked crawler or IP receives a 403 response.', 'miniorange-ai-visibility' ); ?></p>
     416                                                                <p class="moai-av-muted"><?php esc_html_e( 'Shown as plain text when a hard-blocked bot or IP address is refused access.', 'miniorange-ai-visibility' ); ?></p>
    417417                                                        </div>
    418418                                                        <div class="moai-av-table-wrap moai-av-blocked-list-wrap" id="moai-av-blocked-list">
    419419                                                                <?php if ( empty( $ua_blocks ) ) : ?>
    420                                                                         <p class="moai-av-muted"><?php esc_html_e( 'No crawlers are PHP-blocked yet.', 'miniorange-ai-visibility' ); ?></p>
     420                                                                        <p class="moai-av-muted"><?php esc_html_e( 'No bots are hard-blocked yet.', 'miniorange-ai-visibility' ); ?></p>
    421421                                                                <?php else : ?>
    422422                                                                        <table class="moai-av-table">
    … …  
    447447                                                <div>
    448448                                                        <h2><?php esc_html_e( 'Blocked IP Addresses', 'miniorange-ai-visibility' ); ?></h2>
    449                                                         <div class="moai-av-section-desc"><?php esc_html_e( 'Block requests from specific IP addresses with a 403 response. Requires PHP blocking to be enabled above.', 'miniorange-ai-visibility' ); ?></div>
     449                                                        <div class="moai-av-section-desc"><?php esc_html_e( 'Refuse requests from specific IP addresses. Requires hard blocking to be enabled above.', 'miniorange-ai-visibility' ); ?></div>
    450450                                                </div>
    451451                                        </div>
    … …  
    646646                                        <?php else : ?>
    647647                                                <button type="button" class="moai-av-crawler-menu__item moai-av-robots-add" data-crawler-id="<?php echo esc_attr( $crawler_id ); ?>">
    648                                                         <?php esc_html_e( 'Disallow in robots.txt', 'miniorange-ai-visibility' ); ?>
     648                                                        <?php esc_html_e( 'Ask not to crawl (robots.txt)', 'miniorange-ai-visibility' ); ?>
    649649                                                </button>
    650650                                        <?php endif; ?>
    … …  
    655655                                        <?php else : ?>
    656656                                                <button type="button" class="moai-av-crawler-menu__item moai-av-php-block" data-crawler-id="<?php echo esc_attr( $crawler_id ); ?>">
    657                                                         <?php esc_html_e( 'Block via PHP (403)', 'miniorange-ai-visibility' ); ?>
     657                                                        <?php esc_html_e( 'Hard block this bot', 'miniorange-ai-visibility' ); ?>
    658658                                                </button>
    659659                                        <?php endif; ?>
    … …  
    857857                                <div>
    858858                                        <h3><?php esc_html_e( 'Compliance monitor', 'miniorange-ai-visibility' ); ?></h3>
    859                                         <div class="moai-av-section-desc"><?php esc_html_e( 'Top disallowed crawlers that visited in the last 30 days — escalate with PHP blocking when needed.', 'miniorange-ai-visibility' ); ?></div>
     859                                        <div class="moai-av-section-desc"><?php esc_html_e( 'Bots asked not to crawl that still visited in the last 30 days. Hard-block repeat visitors when needed.', 'miniorange-ai-visibility' ); ?></div>
    860860                                </div>
    861861                        </div>
    … …  
    900900                                                                                                <?php disabled( ! $php_blocking_enabled ); ?>
    901901                                                                                        >
    902                                                                                                 <?php esc_html_e( 'Block via PHP', 'miniorange-ai-visibility' ); ?>
     902                                                                                                <?php esc_html_e( 'Hard block', 'miniorange-ai-visibility' ); ?>
    903903                                                                                        </button>
    904904                                                                                <?php endif; ?>
Note: See TracChangeset for help on using the changeset viewer.