{"id":288885,"date":"2026-04-05T19:28:33","date_gmt":"2026-04-05T19:28:33","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/llms-txt-curator\/"},"modified":"2026-04-05T19:29:14","modified_gmt":"2026-04-05T19:29:14","slug":"llms-txt-curator","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/llms-txt-curator\/","author":23463407,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.4.6","stable_tag":"1.4.6","tested":"6.9.4","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"LLMs.txt Curator","header_author":"Sean Mullins","header_description":"Generate and maintain llms.txt and llms-full.txt files that tell AI systems which pages on your site are most important. Features drag-and-drop curation, validation, quality scoring, AI crawler detection, WooCommerce support, and SEO plugin integration.","assets_banners_color":"09488b","last_updated":"2026-04-05 19:29:14","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/www.seostrategy.co.uk\/vibe-coding-services\/","header_author_uri":"https:\/\/www.seostrategy.co.uk\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":28,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.4.6":{"tag":"1.4.6","author":"seanmullins","date":"2026-04-05 19:29:14"}},"upgrade_notice":{"1.4.6":"<p>Adds explicit PHPCS ignore annotations for JSON blob input lines and updates Tested up to to 6.9. No functional changes.<\/p>","1.4.5":"<p>Security fix: type validation hardening in sanitize_all_settings() and helper methods. No breaking changes.<\/p>","1.4.4":"<p>Security fix: sanitizes preview AJAX input through the same sanitize_all_settings() pipeline used by save. No breaking changes.<\/p>","1.4.0":"<p>Adds 30-day crawler analytics chart, last-crawled banner, first\/last seen per bot, CSV export, and two new REST API endpoints. No breaking changes \u2014 existing data is preserved and the new daily aggregate store builds automatically from future visits.<\/p>","1.3.5":"<p>Internal prefix change (llms_txt_ \u2192 llmscu_) for WordPress guidelines compliance. If you installed from the plugin repository, existing settings are preserved. If upgrading from a direct download, existing stored data will be re-initialised on first save.<\/p>","1.3.3":"<p>Critical fix: resolves llms.txt 404 introduced in v1.3.2. Upgrade immediately if on v1.3.2.<\/p>","1.3.2":"<p>Fixes UTF-8 encoding bug (em dashes rendering as \u00e2\u20ac&quot;). Adds X-Robots-Tag: noindex option (on by default). No breaking changes \u2014 existing config preserved.<\/p>","1.3.1":"<p>Security and robustness hardening: nosniff header, import size\/schema validation, file size guard, query performance flags, diagnostics panel, health banner. Translation-ready. No breaking changes.<\/p>","1.3.0":"<p>Adds full WordPress Multisite support. Existing single-site installs are unaffected. No breaking changes.<\/p>","1.2.2":"<p>Adds 7-day AI crawler analytics. No breaking changes.<\/p>","1.2.1":"<p>Adds Scheduled Regeneration and Safety Mode. No breaking changes.<\/p>","1.2.0":"<p>Major quality-of-life release. Description Suggestions, Quality Score, Change Detection, Title Overrides. No breaking changes.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3499336,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3499336,"resolution":"256x256","location":"assets","locale":""}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3499336,"resolution":"1544x500","location":"assets","locale":""},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3499336,"resolution":"772x250","location":"assets","locale":""}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.4.6"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3499316,"resolution":"1","location":"assets","locale":""},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3499316,"resolution":"2","location":"assets","locale":""},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3499316,"resolution":"3","location":"assets","locale":""},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3499316,"resolution":"4","location":"assets","locale":""},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3499316,"resolution":"5","location":"assets","locale":""},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3499316,"resolution":"6","location":"assets","locale":""}},"screenshots":{"1":"Content &amp; Sections -- drag-and-drop curation with description previews and title override buttons","2":"Description Suggestions -- one-click gap-filling with filled\/review summary","3":"Settings -- Update Mode selector and Safety Mode validation card","4":"AI Crawler Analytics -- 7-day bot activity bar chart","5":"Preview &amp; Validate -- live llms.txt output with Quality Score footer","6":"Change Detection -- banner alerting when curated pages have been updated"},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[236374,246076,216196,226124,244604],"plugin_category":[],"plugin_contributors":[259478],"plugin_business_model":[],"class_list":["post-288885","plugin","type-plugin","status-publish","hentry","plugin_tags-ai-seo","plugin_tags-ai-visibility","plugin_tags-chatgpt","plugin_tags-llm","plugin_tags-llms-txt","plugin_contributors-seanmullins","plugin_committers-seanmullins"],"banners":{"banner":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/banner-772x250.png?rev=3499336","banner_2x":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/banner-1544x500.png?rev=3499336","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/icon-128x128.png?rev=3499336","icon_2x":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/icon-256x256.png?rev=3499336","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/screenshot-1.png?rev=3499316","caption":"Content &amp; Sections -- drag-and-drop curation with description previews and title override buttons"},{"src":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/screenshot-2.png?rev=3499316","caption":"Description Suggestions -- one-click gap-filling with filled\/review summary"},{"src":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/screenshot-3.png?rev=3499316","caption":"Settings -- Update Mode selector and Safety Mode validation card"},{"src":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/screenshot-4.png?rev=3499316","caption":"AI Crawler Analytics -- 7-day bot activity bar chart"},{"src":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/screenshot-5.png?rev=3499316","caption":"Preview &amp; Validate -- live llms.txt output with Quality Score footer"},{"src":"https:\/\/ps.w.org\/llms-txt-curator\/assets\/screenshot-6.png?rev=3499316","caption":"Change Detection -- banner alerting when curated pages have been updated"}],"raw_content":"<!--section=description-->\n<p><strong>LLMs.txt Curator<\/strong> helps site owners generate and curate a high-quality <code>llms.txt<\/code> file for AI assistants and retrieval systems, ensuring only relevant, well-described content is exposed to large language models.<\/p>\n\n<p>It generates and maintains <code>llms.txt<\/code> and <code>llms-full.txt<\/code> \u2014 the emerging standard for telling AI systems (ChatGPT, Claude, Perplexity, Gemini, and others) which pages on your site matter most and what they contain.<\/p>\n\n<p>Unlike auto-generators that dump every URL into a flat file, LLMs.txt Curator takes a <strong>curation-first approach<\/strong>. You choose the pages, organise them into sections, fill descriptions, override titles for AI, validate quality, and see exactly which AI bots are reading your file \u2014 all from a single interface.<\/p>\n\n<h4>What makes this different<\/h4>\n\n<p>Most llms.txt plugins treat the file as a static output. LLMs.txt Curator treats it as a living asset:<\/p>\n\n<ul>\n<li><strong>Quality Score<\/strong> \u2014 every generated file shows your coverage percentage, which pages have descriptions, and which still need attention.<\/li>\n<li><strong>Description Suggestions<\/strong> \u2014 one click fills all missing descriptions from a five-step fallback chain (SEO meta \u2192 excerpt \u2192 Open Graph \u2192 page content). Never overwrites what you've set manually.<\/li>\n<li><strong>Change Detection<\/strong> \u2014 a banner appears in your admin when curated pages have been updated since the last generation, with a Regenerate Now button. Your llms.txt stays current without manual checking.<\/li>\n<li><strong>Per-Page Title Override<\/strong> \u2014 set a different title for each page specifically for AI consumption, without touching your on-site SEO.<\/li>\n<li><strong>Safety Mode<\/strong> \u2014 blocks generation if validation errors exist, preventing a broken file from going live. Includes an on-demand validator with plain-English results.<\/li>\n<li><strong>AI Crawler Analytics<\/strong> \u2014 see which bots visited in the last 7 days, with a visual bar chart. OpenAI, Anthropic, Perplexity, Google \u2014 know who is actually reading your file.<\/li>\n<\/ul>\n\n<h4>Core features<\/h4>\n\n<ul>\n<li><strong>Drag-and-drop curation<\/strong> \u2014 reorder sections and pages visually; each section becomes an <code>##<\/code> heading per the spec<\/li>\n<li><strong>llms-full.txt generation<\/strong> \u2014 the companion file with full Markdown content for each curated page<\/li>\n<li><strong>Five SEO plugin integrations<\/strong> \u2014 Rank Math, Yoast SEO, All in One SEO, SEOPress, The SEO Framework<\/li>\n<li><strong>Schema-aware descriptions<\/strong> \u2014 uses structured data before falling back through the description chain<\/li>\n<li><strong>Scheduled regeneration<\/strong> \u2014 choose Instant (on publish), Daily, Weekly, or Manual<\/li>\n<li><strong>WooCommerce support<\/strong> \u2014 SKU, price, stock, categories, dimensions; respects product visibility<\/li>\n<li><strong>WordPress Multisite<\/strong> \u2014 network-activate across all sites; each site manages its own independent llms.txt; Network Admin overview with per-site and bulk regenerate<\/li>\n<li><strong>Pre-built templates<\/strong> \u2014 Business, E-commerce, SaaS, Blog, Local Business<\/li>\n<li><strong>Live preview<\/strong> \u2014 see your exact llms.txt output before saving<\/li>\n<li><strong>Import \/ export<\/strong> \u2014 move your configuration between sites as JSON<\/li>\n<li><strong>WP-CLI<\/strong> \u2014 <code>wp llms-txt regenerate<\/code>, <code>wp llms-txt status<\/code>, <code>wp llms-txt crawler-log<\/code><\/li>\n<li><strong>REST API<\/strong> \u2014 <code>POST \/wp-json\/llms-txt\/v1\/regenerate<\/code>, <code>GET \/wp-json\/llms-txt\/v1\/status<\/code><\/li>\n<li><strong>Atomic file writes<\/strong> \u2014 temp file \u2192 rename; no half-written files served to bots<\/li>\n<li><strong>ETag\/304 caching<\/strong> \u2014 proper HTTP headers for CDN revalidation<\/li>\n<li><strong>Subdirectory \/ Bedrock support<\/strong> \u2014 correctly finds the site root on non-standard installs<\/li>\n<li><strong>Robots.txt reference<\/strong> \u2014 automatically adds a spec-compliant comment<\/li>\n<\/ul>\n\n<h4>Description Suggestions in detail<\/h4>\n\n<p>When pages lack descriptions, AI systems get less context. The suggestion engine fills the gap automatically:<\/p>\n\n<ol>\n<li>Schema markup (Rank Math, custom <code>_schema_json<\/code>)<\/li>\n<li>SEO plugin meta description<\/li>\n<li>WordPress excerpt<\/li>\n<li>Open Graph description (<code>_og_description<\/code> \/ <code>og_description<\/code>)<\/li>\n<li>First 160 characters of post content<\/li>\n<\/ol>\n\n<p>Already-set descriptions are never touched. Pages that can't be filled automatically are listed for manual review.<\/p>\n\n<h4>Quality Score<\/h4>\n\n<p>Every generated <code>llms.txt<\/code> ends with a coverage report:<\/p>\n\n<pre><code>Quality Score: 94%\nPages included: 48\nPages with descriptions: 45\nPages missing descriptions: 3\n<\/code><\/pre>\n\n<p>This is visible to the AI systems reading your file, and to you in the Preview tab.<\/p>\n\n<h4>AI Crawler Analytics<\/h4>\n\n<p>Track 12 known bots: GPTBot, ChatGPT-User, ClaudeBot, PerplexityBot, Google-Extended, Applebot-Extended, Meta-ExternalAgent, Bytespider, CCBot, Cohere, DeepSeek, Amazonbot.<\/p>\n\n<p>The 7-day analytics card shows a visual bar chart of recent activity. All-time totals are kept separately. IP addresses are anonymised before storage \u2014 last octet zeroed for IPv4, last 80 bits for IPv6. No data leaves your server.<\/p>\n\n<h4>Safety Mode<\/h4>\n\n<p>Before generation, the validator checks:<\/p>\n\n<ul>\n<li>Pages missing or unpublished<\/li>\n<li>Duplicate URLs across sections<\/li>\n<li>Noindex conflicts<\/li>\n<li>Canonical mismatches<\/li>\n<li>Password-protected pages<\/li>\n<li>Thin content (&lt; 100 words, no meta, no excerpt)<\/li>\n<li>File size &gt; 50 KB<\/li>\n<li>Too many pages (&gt; 80)<\/li>\n<\/ul>\n\n<p>When Safety Mode is on, errors block generation and the results are shown immediately. Warnings are surfaced but don't block. Everything is explained in plain English.<\/p>\n\n<h4>Scheduled regeneration<\/h4>\n\n<ul>\n<li><strong>Instant<\/strong> \u2014 regenerates ~30 seconds after any page is published or trashed (default)<\/li>\n<li><strong>Daily<\/strong> \u2014 once per day, via WP-Cron recurring event<\/li>\n<li><strong>Weekly<\/strong> \u2014 once per week<\/li>\n<li><strong>Manual<\/strong> \u2014 only when you click Save &amp; Generate<\/li>\n<\/ul>\n\n<h4>How to get started<\/h4>\n\n<ol>\n<li>Install and activate. The plugin auto-scans your content and creates initial sections.<\/li>\n<li>Curate: drag, drop, add, remove. Aim for 20-60 pages that best represent your site.<\/li>\n<li>Click <strong>Generate Missing Descriptions<\/strong> to fill gaps automatically.<\/li>\n<li>Fix any warnings shown in the Safety Mode card.<\/li>\n<li>Set the update mode that suits your workflow.<\/li>\n<li>Save &amp; Generate. Your files are live at <code>\/llms.txt<\/code> and <code>\/llms-full.txt<\/code>.<\/li>\n<li>Enable the AI Crawler Log to see which bots start visiting.<\/li>\n<\/ol>\n\n<h4>WooCommerce integration<\/h4>\n\n<p>When WooCommerce is active, the plugin automatically includes SKU, price, and stock status in <code>llms.txt<\/code> descriptions, and full product details in <code>llms-full.txt<\/code>. Products with \"hidden\" visibility are excluded, and you can optionally exclude out-of-stock products.<\/p>\n\n<h4>Developer hooks<\/h4>\n\n<ul>\n<li><strong><code>llmscu_capability<\/code><\/strong> filter \u2014 override the required capability (default: <code>manage_options<\/code>)<\/li>\n<li><strong><code>llmscu_post_limit<\/code><\/strong> filter \u2014 scanner post limit per type (default: 500)<\/li>\n<li><strong><code>llmscu_full_word_limit<\/code><\/strong> filter \u2014 per-page word cap in <code>llms-full.txt<\/code> (default: unlimited)<\/li>\n<li><strong><code>llmscu_regenerated<\/code><\/strong> action \u2014 fires after each successful regeneration with the content string<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>llms-txt-curator<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate through the 'Plugins' menu.<\/li>\n<li>Go to <strong>Settings -&gt; LLMs.txt Curator<\/strong> to begin curating.<\/li>\n<\/ol>\n\n<p>Or install directly from the WordPress plugin repository by searching for \"LLMs.txt Curator\".<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20is%20llms.txt%3F\"><h3>What is llms.txt?<\/h3><\/dt>\n<dd><p>llms.txt is a proposed standard (llmstxt.org) that provides AI systems with a curated, Markdown-formatted overview of a website's most important content. A strategic selection of the pages you want AI to know about -- not a sitemap.<\/p><\/dd>\n<dt id=\"what%20is%20llms-full.txt%3F\"><h3>What is llms-full.txt?<\/h3><\/dt>\n<dd><p>The companion file defined in the same spec. While <code>llms.txt<\/code> contains links and short descriptions, <code>llms-full.txt<\/code> contains the full Markdown content of each page. Optional -- enable it in Settings when ready.<\/p><\/dd>\n<dt id=\"do%20i%20need%20both%20files%3F\"><h3>Do I need both files?<\/h3><\/dt>\n<dd><p>No. <code>llms.txt<\/code> alone is sufficient. <code>llms-full.txt<\/code> is useful if you want AI systems to have immediate access to your full content without additional crawling.<\/p><\/dd>\n<dt id=\"what%20does%20description%20suggestions%20do%3F\"><h3>What does Description Suggestions do?<\/h3><\/dt>\n<dd><p>Scans every curated page and fills missing descriptions using a five-step fallback chain: schema markup -&gt; SEO meta -&gt; excerpt -&gt; Open Graph -&gt; page content. Pages with descriptions already set are never touched.<\/p><\/dd>\n<dt id=\"what%20is%20the%20quality%20score%3F\"><h3>What is the Quality Score?<\/h3><\/dt>\n<dd><p>A percentage showing how many listed pages have descriptions. It appears at the bottom of your generated <code>llms.txt<\/code>, visible to both you and any AI systems reading the file.<\/p><\/dd>\n<dt id=\"what%20does%20title%20override%20do%3F\"><h3>What does Title Override do?<\/h3><\/dt>\n<dd><p>Lets you set a different title for a page in your llms.txt output without changing it on your site. Useful when your WordPress title includes your site name but you want AI to see a cleaner, more descriptive title.<\/p><\/dd>\n<dt id=\"what%20does%20safety%20mode%20do%3F\"><h3>What does Safety Mode do?<\/h3><\/dt>\n<dd><p>Runs validation before every generation. If errors are found, generation is blocked and results shown immediately. Prevents broken or malformed files going live.<\/p><\/dd>\n<dt id=\"which%20seo%20plugins%20are%20supported%3F\"><h3>Which SEO plugins are supported?<\/h3><\/dt>\n<dd><p>Rank Math, Yoast SEO, All in One SEO, SEOPress, and The SEO Framework.<\/p><\/dd>\n<dt id=\"which%20ai%20bots%20does%20the%20crawler%20log%20detect%3F\"><h3>Which AI bots does the crawler log detect?<\/h3><\/dt>\n<dd><p>GPTBot (OpenAI), ChatGPT-User, ClaudeBot (Anthropic), PerplexityBot, Google-Extended, Applebot-Extended, Meta-ExternalAgent, Bytespider (ByteDance), CCBot (Common Crawl), Cohere, DeepSeek, and Amazonbot.<\/p><\/dd>\n<dt id=\"what%20if%20my%20host%20blocks%20file%20writes%3F\"><h3>What if my host blocks file writes?<\/h3><\/dt>\n<dd><p>The plugin has a rewrite rule fallback that serves both files via WordPress. Choose between \"Direct file\", \"Rewrite rule only\", or \"Both\" (recommended) in Settings.<\/p><\/dd>\n<dt id=\"does%20this%20work%20on%20multisite%3F\"><h3>Does this work on multisite?<\/h3><\/dt>\n<dd><p>Yes. Activate network-wide from Network Admin &gt; Plugins, or activate per-site on individual sub-sites.<\/p>\n\n<p>Each site manages its own independent <code>llms.txt<\/code> \u2014 there is no shared network file. The Network Admin overview page (Network Admin &gt; Settings &gt; LLMs.txt Curator) shows every site's generation status and lets you regenerate any site, or all sites at once, without leaving the network admin.<\/p>\n\n<p>On subdirectory networks (<code>example.com<\/code>, <code>example.com\/site1<\/code>) each site writes a physical file at its own path. On subdomain networks (<code>example.com<\/code>, <code>site1.example.com<\/code>) sub-sites share a filesystem root, so they serve <code>llms.txt<\/code> via WordPress rewrite rule from the database instead \u2014 this is fully correct and functionally identical.<\/p>\n\n<p>WP-CLI works per-site using the standard <code>--url=<\/code> flag: <code>wp llms-txt regenerate --url=https:\/\/site1.example.com<\/code><\/p><\/dd>\n<dt id=\"is%20any%20data%20sent%20externally%3F\"><h3>Is any data sent externally?<\/h3><\/dt>\n<dd><p>No. Everything stays on your server. No telemetry, no external API calls, no cookies. Crawler IP addresses are anonymised before storage.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.4.6<\/h4>\n\n<ul>\n<li>Fix: Added explicit <code>WordPress.Security.ValidatedSanitizedInput.InputNotSanitized<\/code> phpcs:ignore annotations to the three JSON blob input lines (<code>ajax_save_settings<\/code>, <code>ajax_preview<\/code>, <code>ajax_import<\/code>). Sanitization occurs correctly after <code>json_decode()<\/code> via <code>sanitize_all_settings()<\/code>; the annotations document this intent for static analysis tools.<\/li>\n<li>Fix: <code>Tested up to<\/code> updated to 6.9 to match the current WordPress major version.<\/li>\n<\/ul>\n\n<h4>1.4.5<\/h4>\n\n<ul>\n<li>Fix: <code>sanitize_all_settings()<\/code> now validates that <code>sections<\/code>, <code>post_types<\/code>, <code>descriptions<\/code>, and <code>title_overrides<\/code> are arrays before passing them to helper functions or <code>array_map()<\/code>. Previously used <code>?? array()<\/code> fallbacks which guard against null but not wrong types from malformed JSON, risking a <code>TypeError<\/code> on PHP 8+.<\/li>\n<li>Fix: <code>sanitize_sections()<\/code> now validates <code>pages<\/code> is an array before iterating it.<\/li>\n<li>Fix: <code>sanitize_descriptions()<\/code> and <code>sanitize_title_overrides()<\/code> now skip non-string values.<\/li>\n<li>Fix: <code>post_types<\/code> output wrapped in <code>array_values( array_filter() )<\/code> to strip any empty keys produced by <code>sanitize_key()<\/code>.<\/li>\n<\/ul>\n\n<h4>1.4.4<\/h4>\n\n<ul>\n<li>Fix: <code>ajax_preview()<\/code> now passes POST data through <code>sanitize_all_settings()<\/code> before use, consistent with <code>ajax_save_settings()<\/code>. Previously used <code>wp_parse_args()<\/code> without sanitization.<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>New: 30-day AI crawler activity chart \u2014 stacked bar chart showing daily visits per bot, auto-compressed to weekly buckets for readability.<\/li>\n<li>New: \"Last AI crawler visit\" banner at the top of the Crawler tab \u2014 shows a live \"X minutes\/hours\/days ago\" timestamp at a glance.<\/li>\n<li>New: First Seen \/ Last Seen columns in the all-time bot summary table.<\/li>\n<li>New: Export CSV button \u2014 downloads the full crawler log as a CSV file for use in client reports.<\/li>\n<li>New: Daily aggregate storage (90-day rolling window) \u2014 daily visit counts are now stored separately from the raw log, enabling the timeline chart without scanning every log entry.<\/li>\n<li>New: REST API endpoint <code>GET \/wp-json\/llms-txt\/v1\/crawler-stats<\/code> \u2014 returns all-time, 7-day, 30-day, daily, and per-bot first\/last seen data.<\/li>\n<li>New: REST API endpoint <code>GET \/wp-json\/llms-txt\/v1\/pages<\/code> \u2014 returns all curated sections and pages as JSON, useful for external dashboards.<\/li>\n<li>Improvement: All-time bot table now includes Last 7 Days column alongside All-Time for quick comparison.<\/li>\n<\/ul>\n\n<h4>1.3.5<\/h4>\n\n<ul>\n<li>Fix: All PHP declarations, stored data keys, and WordPress registrations updated to use the distinct <code>llmscu_<\/code> \/ <code>LLMSCU_<\/code> prefix throughout, replacing the generic <code>llms_txt_<\/code> \/ <code>LLMS_Txt_<\/code> prefix. No data migration required \u2014 existing stored options are unaffected.<\/li>\n<li>Fix: Readme comparative claims removed per WordPress plugin guidelines.<\/li>\n<\/ul>\n\n<h4>1.3.3<\/h4>\n\n<ul>\n<li>Fix: Reverted v1.3.2 RewriteRule approach which caused llms.txt 404 on some hosts. Replaced with a safe  + mod_headers .htaccess block that sets Content-Type charset and X-Robots-Tag without touching WordPress rewrite rules.<\/li>\n<\/ul>\n\n<h4>1.3.2<\/h4>\n\n<ul>\n<li>Fix: UTF-8 encoding bug causing em dashes and other multibyte characters to render as \u00e2\u20ac\" in browsers and AI crawlers. Physical llms.txt file is now always routed through WordPress via .htaccess rules so the correct Content-Type: text\/plain; charset=utf-8 header is always sent.<\/li>\n<li>New: X-Robots-Tag: noindex header option \u2014 prevents Google indexing llms.txt as a page in search results. Enabled by default; toggle in Settings tab under Search Indexing.<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Security: <code>X-Content-Type-Options: nosniff<\/code> header added when serving llms.txt and llms-full.txt.<\/li>\n<li>Security: Import JSON payload capped at 256 KB \u2014 rejected before decode with a plain-English error.<\/li>\n<li>Security: Import schema sanity check \u2014 requires at least 2 expected top-level keys before accepting a configuration file.<\/li>\n<li>Robustness: 2 MB file size guard before <code>file_get_contents()<\/code> \u2014 falls through to DB option if the physical file exceeds the cap.<\/li>\n<li>Performance: <code>no_found_rows<\/code>, <code>update_post_meta_cache =&gt; false<\/code>, <code>update_post_term_cache =&gt; false<\/code> added to all <code>get_posts()<\/code> queries.<\/li>\n<li>New: Site Diagnostics panel on the Preview &amp; Validate tab \u2014 shows computed root, writable status, delivery mode, file\/DB state, rewrite health, last live test result, and environment versions.<\/li>\n<li>New: \"Last verified\" status bar row \u2014 persisted after every live test so it survives page reloads.<\/li>\n<li>New: Reachability health banner \u2014 shown above tabs when the last live test failed; includes one-click \"Fix: Flush Rewrite Rules\" button that reruns the test automatically.<\/li>\n<li>Fix: Multisite uninstall loop changed from a fixed 500-site cap to a paginated do\/while loop (100 per page) \u2014 handles networks of any size.<\/li>\n<li>Fix: <code>@package<\/code> docblock corrected from <code>LLMS_Txt_Manager<\/code> to <code>LLMS_Txt_Curator<\/code> across all PHP files.<\/li>\n<li>Fix: <code>load_plugin_textdomain()<\/code> added \u2014 plugin is now translation-ready.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New: Multisite support (Chunks A\u2013E \u2014 complete). Plugin header <code>Network: true<\/code>, network activation, per-site isolation, file path safety, network admin overview, and cron verification all done.<\/li>\n<li>New: Network Admin overview page (Network Admin &gt; Settings &gt; LLMs.txt Curator) with summary strip, per-site status table, per-site Regenerate button, and Regenerate All Sites bulk action. Table updates live via AJAX without a page reload.<\/li>\n<li>New: File mode column in network table \u2014 \"Physical\" (subdirectory) or \"Rewrite\" (subdomain\/domain-mapped) with tooltip.<\/li>\n<li>New: Regen schedule shown per-site in the network table.<\/li>\n<li>New: Network Settings action link in the Network Admin plugins list.<\/li>\n<li>New: <code>llms_txt_is_network_activated()<\/code> helper function.<\/li>\n<li>New: <code>llms_txt_file_write_safe()<\/code> helper \u2014 prevents subdomain sub-sites from overwriting the main site's physical llms.txt. Those sites serve via rewrite rule instead.<\/li>\n<li>New: <code>next_regen<\/code> key in <code>get_file_status()<\/code> \u2014 formatted next scheduled regeneration time (daily\/weekly\/instant debounce) for the current site.<\/li>\n<li>Improvement: <code>maybe_schedule_recurring_regen()<\/code> now returns early on <code>is_network_admin()<\/code> \u2014 prevents the main site's cron schedule being unnecessarily re-synced on every network admin page load.<\/li>\n<li>Improvement: All four cron methods updated with explicit multisite docblocks confirming per-site safety.<\/li>\n<li>Improvement: WP-CLI handler docblock updated with <code>--url=<\/code> guidance for per-site usage on multisite networks.<\/li>\n<li>Improvement: <code>delete_file()<\/code> in the generator guarded against subdomain sub-sites deleting a shared file.<\/li>\n<li>Improvement: Activation hook accepts <code>$network_wide<\/code>; deactivation clears cron events across all sites.<\/li>\n<li>Improvement: Uninstall iterates all sites; cleans up options, transients, cron, and files per-site.<\/li>\n<li>Improvement: <code>LLMS_Txt_Admin<\/code> guarded from instantiating in network admin context.<\/li>\n<li>Improvement: <code>get_file_status()<\/code> returns <code>is_network_activated<\/code>, <code>is_subdomain_network<\/code>, <code>file_write_safe<\/code>, <code>network_overview_url<\/code>, and <code>next_regen<\/code>.<\/li>\n<li>Improvement: Validator surfaces info message on subdomain sub-sites confirming rewrite serving is intentional.<\/li>\n<li>Improvement: Admin status panel and multisite notice contextually correct per site type.<\/li>\n<li>Confirmed (docblocked): WP-Cron, option storage, transients, nonces, and capability checks are all natively per-site in multisite. No <code>switch_to_blog()<\/code> wrapping required in any cron path.<\/li>\n<li>Removed: <code>wp_die()<\/code> block that previously blocked activation on non-main sites.<\/li>\n<\/ul>\n\n<h4>1.2.2<\/h4>\n\n<ul>\n<li>New: AI Crawler Analytics -- 7-day bot activity bar chart on the Crawler Log tab, showing visit counts per bot. Refreshes without a page reload.<\/li>\n<li>Improvement: Crawler Log tab restructured -- analytics card at top, all-time summary below, full visit log at the bottom.<\/li>\n<li>Update: readme.txt updated to reflect all features added in v1.2.x.<\/li>\n<li>Update: Stable tag updated to 1.2.2.<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>New: Scheduled Regeneration -- choose between Instant, Daily, Weekly, or Manual update modes. Daily\/Weekly use proper WP-Cron recurring events with next-run time displayed in the UI.<\/li>\n<li>New: Safety Mode -- toggle to block generation on validation errors, with an on-demand validation card showing errors, warnings, and a plain-English stats summary.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>New: Description Suggestions -- one-click fills missing descriptions using a five-step fallback chain. Never overwrites manually-set descriptions.<\/li>\n<li>New: Quality Score footer -- every generated file includes a Coverage Report showing quality score %, pages with descriptions, and pages needing attention.<\/li>\n<li>New: Change Detection -- admin banner alerts when curated pages have been updated since last generation, with direct Regenerate Now action.<\/li>\n<li>New: Per-page Title Override -- set an AI-optimised title for any page without touching on-site SEO.<\/li>\n<li>Improvement: OpenGraph description added as step 4 in the description fallback chain.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>New: llms-full.txt generation -- full Markdown content for each curated page, per the llmstxt.org spec.<\/li>\n<li>New: AI crawler detection -- logs visits from 12 known AI bots with anonymised IPs.<\/li>\n<li>New: WooCommerce integration -- product data (SKU, price, stock, categories, dimensions) automatically included.<\/li>\n<li>New: AI Crawler Log tab with summary stats and detailed visit log.<\/li>\n<li>New: WP-CLI commands: <code>status<\/code>, <code>crawler-log<\/code>, <code>crawler-clear<\/code>.<\/li>\n<li>New: REST API status endpoint.<\/li>\n<li>New: robots.txt reference and rewrite rule for llms-full.txt.<\/li>\n<\/ul>\n\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>Initial public release. Drag-and-drop curation, validation engine, SEO plugin integration, schema-aware descriptions, pre-built templates, auto-regeneration, live preview, import\/export, WP-CLI, REST API, atomic file writes, ETag caching.<\/li>\n<\/ul>","raw_excerpt":"Curate, score, and maintain your llms.txt with quality scoring, description suggestions, change detection, and AI crawler analytics.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/288885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=288885"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/seanmullins"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=288885"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=288885"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=288885"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=288885"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=288885"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=288885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}