*/ function recommended_settings(): array { $seo_active = active_seo_plugin() !== null; return array( // Discovery — all on, low cost, no conflicts. 'ajaco_api_catalog_enabled' => true, 'ajaco_mcp_server_card_enabled' => true, 'ajaco_agent_skills_index_enabled' => true, 'ajaco_llms_txt_enabled' => true, // IndexNow off — requires API key + production environment. 'ajaco_indexnow_enabled' => false, // Presentation — on by default; JSON-LD off when an SEO plugin is active // (auto-suppression would no-op anyway, but turning it off makes the UI honest). 'ajaco_markdown_enabled' => true, 'ajaco_json_ld_enabled' => ! $seo_active, 'ajaco_openapi_enabled' => true, 'ajaco_webmcp_enabled' => true, // Discovery/auth — on: a truthful, static document. 'ajaco_auth_md_enabled' => true, // Declarations — on. 'ajaco_content_signals_enabled' => true, 'ajaco_ai_bot_rules_enabled' => true, ); } /** * Handle the wizard form submission. * * @return void */ function handle_wizard_submit(): void { if ( ! current_user_can( required_capability() ) ) { wp_die( esc_html__( 'You do not have permission to run the AJ Agent Crawl Optimizer setup wizard.', 'aj-agent-crawl-optimizer' ), '', array( 'response' => 403 ) ); } check_admin_referer( 'ajaco_apply_wizard' ); $action = isset( $_POST['ajaco_wizard_action'] ) ? sanitize_text_field( wp_unslash( $_POST['ajaco_wizard_action'] ) ) : ''; if ( 'apply' === $action ) { // Only write options THIS form rendered. An absent checkbox otherwise // reads as "the user unchecked it" — which silently disables features // when the open page was rendered by an older version of the plugin // (whose form had no field for options added since), or when the POST // was truncated by PHP's max_input_vars. $rendered = isset( $_POST['ajaco_wizard_fields'] ) ? array_filter( array_map( 'trim', explode( ',', sanitize_text_field( wp_unslash( $_POST['ajaco_wizard_fields'] ) ) ) ) ) : array(); foreach ( array_keys( recommended_settings() ) as $option ) { if ( ! in_array( $option, $rendered, true ) ) { continue; // Not on the submitted form — leave it exactly as it is. } $checked = isset( $_POST[ $option ] ) && '1' === $_POST[ $option ]; update_option( $option, $checked ); } set_transient( WIZARD_APPLIED_FLAG, 1, 60 ); } // Apply or skip — either way, dismiss the wizard (re-runnable any time // from the settings page link). delete_option( WIZARD_PENDING_OPTION ); update_option( WIZARD_DONE_OPTION, 1, false ); wp_safe_redirect( settings_page_url() ); exit; } /** * Show a flash notice after the wizard's settings are applied. * * @return void */ function maybe_show_wizard_applied_notice(): void { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; // The settings screen id depends on its parent menu — match the page slug // instead of hardcoding the pre-2.0 'settings_page_' prefix. if ( ! $screen || false === strpos( (string) $screen->id, 'aj-agent-crawl-optimizer' ) ) { return; } if ( ! get_transient( WIZARD_APPLIED_FLAG ) ) { return; } delete_transient( WIZARD_APPLIED_FLAG ); ?>

'ajaco_apply_wizard', 'ajaco_wizard_action' => 'skip', ), admin_url( 'admin-post.php' ) ), 'ajaco_apply_wizard' ); $rows = array( // label, option name, recommended-by-default, description. array( 'discovery', __( 'API Catalog', 'aj-agent-crawl-optimizer' ), 'ajaco_api_catalog_enabled', __( '/.well-known/api-catalog manifest plus a Link header on every response (RFC 9727).', 'aj-agent-crawl-optimizer' ) ), array( 'discovery', __( 'MCP Server Card', 'aj-agent-crawl-optimizer' ), 'ajaco_mcp_server_card_enabled', __( '/.well-known/mcp/server-card.json descriptor for MCP-aware agents.', 'aj-agent-crawl-optimizer' ) ), array( 'discovery', __( 'Agent Skills Index', 'aj-agent-crawl-optimizer' ), 'ajaco_agent_skills_index_enabled', __( '/.well-known/agent-skills/index.json plus per-skill SKILL.md artifacts.', 'aj-agent-crawl-optimizer' ) ), array( 'discovery', __( 'llms.txt', 'aj-agent-crawl-optimizer' ), 'ajaco_llms_txt_enabled', __( 'A curated, LLM-readable index at /llms.txt (per llmstxt.org).', 'aj-agent-crawl-optimizer' ) ), array( 'discovery', __( 'IndexNow', 'aj-agent-crawl-optimizer' ), 'ajaco_indexnow_enabled', __( 'Pings Bing/Yandex on publish. Requires a key from bing.com/webmasters/indexnow — leave off for now and configure later.', 'aj-agent-crawl-optimizer' ) ), array( 'discovery', __( 'auth.md', 'aj-agent-crawl-optimizer' ), 'ajaco_auth_md_enabled', __( '/auth.md documenting Application Password authentication for agents.', 'aj-agent-crawl-optimizer' ) ), array( 'presentation', __( 'Markdown Negotiation', 'aj-agent-crawl-optimizer' ), 'ajaco_markdown_enabled', __( 'Returns clean Markdown when an agent sends Accept: text/markdown. Browsers are unaffected.', 'aj-agent-crawl-optimizer' ) ), array( 'presentation', __( 'JSON-LD Schema', 'aj-agent-crawl-optimizer' ), 'ajaco_json_ld_enabled', __( 'WebSite, Organization, Article, BreadcrumbList, FAQPage structured data.', 'aj-agent-crawl-optimizer' ) ), array( 'presentation', __( 'OpenAPI Spec', 'aj-agent-crawl-optimizer' ), 'ajaco_openapi_enabled', __( 'OpenAPI 3.0.3 document at /openapi.json, generated from REST routes.', 'aj-agent-crawl-optimizer' ) ), array( 'presentation', __( 'WebMCP Tools', 'aj-agent-crawl-optimizer' ), 'ajaco_webmcp_enabled', __( 'Frontend script registering tools via navigator.modelContext (Chrome experimental).', 'aj-agent-crawl-optimizer' ) ), array( 'declarations', __( 'AI Bot Rules', 'aj-agent-crawl-optimizer' ), 'ajaco_ai_bot_rules_enabled', __( 'Explicit robots.txt User-agent groups for the 15 AI crawlers scanners check.', 'aj-agent-crawl-optimizer' ) ), array( 'declarations', __( 'Content-Signals', 'aj-agent-crawl-optimizer' ), 'ajaco_content_signals_enabled', __( 'Adds a Content-Signal directive to robots.txt declaring AI-usage preferences.', 'aj-agent-crawl-optimizer' ) ), ); $section_titles = array( 'discovery' => __( 'Discovery', 'aj-agent-crawl-optimizer' ), 'presentation' => __( 'Presentation', 'aj-agent-crawl-optimizer' ), 'declarations' => __( 'Declarations', 'aj-agent-crawl-optimizer' ), ); $current_section = ''; ?>

' . esc_html( $seo_plugin ) . '' ); ?>

' . esc_html( $section_titles[ $section ] ) . ''; } $checked = ! empty( $rec[ $option ] ); ?>