== Changelog ==

Full version history for Hack The SEO. The readme.txt carries the most recent releases; this file is the complete record, back to 1.0.0.

= 1.1.0 =
* Added: a read-only MCP server, at `/wp-json/htsfree/v1/mcp`. Claude Code, Claude Desktop and other MCP clients can read what the plugin measures: AI-crawler passages by page and over time, GEO, on-page and meta scores, the site-wide score distribution, the competing-pages report, redirects, the 404 log, llms.txt, the Markdown of a page, and the health check. Twelve abilities, and all twelve read: there is no write among them, and no setting that turns one on. It needs WordPress 6.9, where the Abilities API entered core; below that it does not register and nothing else changes.
* Added: the plugin now runs next to Yoast SEO, Rank Math, All in One SEO and SEOPress. On activation it detects the SEO plugin already in place and stops emitting whatever that plugin handles (meta tags, canonical, schema, sitemap, breadcrumbs, robots, and hreflang when a multilingual plugin owns it), so nothing is output twice. It never deactivates the other plugin and never changes its settings. A Compatibility screen lists every overlap and lets you take back any module, one by one. The AI crawler log, the GEO score and the cannibalization report have no front-end output and work regardless.
* Added: a weekly report by email. Once a week your own site sends its administrator a short message: how many times AI crawlers read the site and on how many pages, how many visitors arrived from an AI chat, which new broken links appeared, and how the site score moved. Nothing is sent on a week with nothing to report, every email carries a one-click unsubscribe link that works without logging in, and the report can be switched on or off from the AI visibility settings. It is sent by your own site through WordPress, so no third party is involved and no outbound call was added.
* Added: an "AI connection" screen. One button creates the WordPress application password and prints the line to paste into your client. The screen lists the twelve abilities with the capability each one needs, shows which client connected and when, and keeps the last fifty calls with their duration. It records what was called, never the arguments and never the answers.
* Added: the interface ships translated into French, Spanish, German, Italian and Brazilian Portuguese. Until now nothing loaded them: WordPress reads a plugin's own catalogues only when the plugin points at them, and otherwise waits for a package from translate.wordpress.org, of which none exists yet for this plugin. Both halves are fixed. Your site language is followed automatically, with no account and no setting to change. An official package, the day it exists, takes precedence on its own.
* Changed: every link leaving the plugin now goes through a single point, so it is possible to tell which screen sends people to the site and which one converts. The dashboard previously wrote tracking parameters onto an internal admin URL, where no measurement tool can ever read them; internal links now carry the originating screen instead, and the pricing page reads it back onto its outgoing links.
* Added: a way to say what is missing or broken, from the footer of every plugin screen. You write your message, optionally attach a summary of your setup (versions and active modules, never your site address and never a key), copy it, and open the support forum. Nothing is sent from the plugin and nothing is stored: the text never reaches the server, so it is never altered and there is nothing to delete later.
* Security: every MCP call is made by a signed-in WordPress user and checks a capability, `manage_options` for the site-wide readings and `edit_posts` for the four that concern a single page. An anonymous request cannot even list the tools. No ability returns unpublished or password-protected content, nor a visitor's IP address, referrer or user agent.
* Fix: the crawler report no longer lists a page that has been unpublished or password-protected since a crawler read it. Its rows stayed in the log, so its title could still appear.
* Fix: the "Set up the connection" button in the settings, and the Pro link on the AI connection screen, navigate again. Both were rendered as buttons carrying a link, which does nothing.
* Unchanged: the plugin still makes exactly the same nine outbound calls as before, and the bundled MCP library adds none. MCP is inbound: your client calls your site, and no third party is contacted.

= 1.0.25 =
* Fix: `Google-Extended` and `Applebot-Extended` have been removed from the AI crawler list. Neither is a crawler: Google documents that Google-Extended has no separate user agent string, and Apple documents that Applebot-Extended does not crawl web pages. Both were robots.txt tokens, so neither could ever have been detected. Apple is now tracked through its real crawler, `Applebot`.
* Added: `Claude-User` and `Claude-SearchBot`, Anthropic's current on-demand and search agents; `Perplexity-User`, Perplexity's on-demand fetcher; and `Google-CloudVertexBot`. Eighteen user agents are now matched, up from thirteen.
* Removed: `Gemini-Bot` and `CopilotBot`, which neither company publishes. Human visits arriving from Gemini and Copilot chats are still measured, through the referrer.

= 1.0.24 =
* Fix: updating from 1.0.22 or earlier no longer resets your settings. The rename migration ran after the modules had already written their defaults, so a module you had switched on could come back off.
* Fix: the migration now keeps each setting's autoload state instead of turning it off. WordPress 6.6 changed the wording stored in that column, and the check missed it, which added one database query per setting on every page.
* Fix: `[hts_breadcrumbs]` and `[hts_sitemap]` written in older posts render again. They were renamed in 1.0.21 without rewriting existing content, so visitors saw the raw shortcode text.
* Fix: the rename migration no longer runs when the commercial version is installed alongside. It shares the same setting names, and moving them emptied its data.
* Changed: the breadcrumbs block is now registered as `htsfree/breadcrumbs`, and the remaining French labels and untranslatable strings are translated: "Table of contents", "Breadcrumb", "Home", "Other AI", and the sitemap screen messages.

= 1.0.23 =
* Changed: every option and transient the plugin owns now carries the `htsfree_` prefix, as the directory requires. Your settings are migrated automatically on update; per-post SEO data is untouched.
* Fix: the Author URI now points to the wordpress.org profile, which answers in a second. The previous address took eleven, over the review tool's timeout.

= 1.0.21 =
* Changed: the two shortcodes are now `[htsfree_breadcrumbs]` and `[htsfree_sitemap]`, so every registered name carries a prefix longer than three characters.

= 1.0.20 =
* Fix: FAQ schema answers are no longer cut in the middle of a word. AI answer engines read this markup directly, so a truncated answer stayed truncated in their index.
* Fix: llms.txt descriptions no longer show leftover escape characters when page builders store their content as JSON.
* Improved: the AI visibility card now says "Visits from AI chats", so it is no longer mistaken for the crawler passage counter next to it.
* Changed: activating the plugin no longer redirects you. A dismissible welcome notice offers the setup instead, on the plugins list and on Hack The SEO screens only.
* Fix: with the Breadcrumbs module enabled, the breadcrumbs Gutenberg block is now offered in the block inserter. It was registered server-side only, so it rendered existing markup but could not be added to a page.
* Changed: the XML sitemap stylesheet, which is served publicly, no longer carries links to our own site and is now written in English. It previously showed French text and a "powered by" badge on every site.

= 1.0.18 =
* Fix: "Analyze my pages" no longer reports success when the requests were rejected; it now says so and gives the button back.
* Fix: redirecting or approving a 404 no longer claims success when the rule was refused; the entry stays in the list.
* Fix: the "Choose" button of the social share image is visible again and opens the media library.
* Fix: turning the XML sitemap off now flushes the rewrite rules, so /sitemap.xml stops answering with the home page.
* Fix: the "Who handles what?" step of the migration wizard now really changes what the site outputs, both ways.
* Fix: uninstalling removes the plugin transients again, and two "Repair" buttons of the Health screen do what they announce.

= 1.0.17 =
* Fix: the design system stylesheet is loaded again. In 1.0.16 the prefix rename also renamed the file path, so every admin screen rendered unstyled.

= 1.0.16 =
* Changed: every function, class, constant, hook, AJAX action, transient, nonce, admin page slug and script handle now uses the `htsfree_` prefix. Stored data keys are unchanged, so nothing is lost on update.
* Improved: inline styles and scripts no longer go through an output buffer; 33 of them are now plain strings handed to WordPress.
* Fix: `set_time_limit()` no longer shortens the execution window on hosts that allow more than 120 seconds, and never imposes one on hosts that allow unlimited.
* Fix: the breadcrumb separator saved from the settings screen is applied again.
* Fix: redirect and score queries build their `IN ()` lists from bound placeholders.
* Fix: removed an unused AJAX endpoint that could overwrite the breadcrumb settings without validation.

= 1.0.15 =
* Fix: the page title is now escaped once on output, so a meta title can never inject markup into the `<title>` tag.
* Fix: saving Schema Pro fields no longer fails with a server error when a field holds a list of values.
* Fix: the sitemap and migration notices only appear on Hack The SEO screens, and every notice can be dismissed with the standard WordPress control.
* Fix: on multisite, uninstalling now removes the cached sitemap of every subsite instead of the main site only.
* Fix: the canonical URL box in the editor is translatable, and no longer shows an icon in place of its title.
* Improved: all stylesheets are handed to WordPress instead of being written into the page.
* Improved: readme wording corrected on disk writes, translations and the paid version.

= 1.0.14 =
* New: a "First steps" checklist on the dashboard that adapts to what still needs setting up (indexing, permalinks, importing from another SEO plugin, company details, author profile, sitemap) and disappears once you are done.
* New: a guided tour of the dashboard (native highlight, no external library) that walks through your SEO score, AI visibility and the main screens. Starts from the "First steps" card and can be restarted anytime.
* New: edit the SEO meta title and description of your categories and tags directly on the term edit screen.
* Improved: the "Go Pro" and semantic-cocoon screens were redesigned to be clearer and more useful.
* Improved: the plugin is now fully internationalised, ready for translation through translate.wordpress.org.
* Fix: WooCommerce product rows in the posts list now always show an exempt state instead of an old editorial score left over from a previous version.
* Hardening: reinforced unslashing and sanitization of every admin form and request input, and reviewed all database access.
* Fix: redirects imported from another SEO plugin, and redirects whose URL contains accents or encoded characters, are now matched correctly instead of silently never firing.
* Fix: sending a post to the trash no longer replaces its redirect with a broken one.
* Fix: redirects now keep the incoming query string (utm_source, filters, sorting) when the destination has none.
* Fix: on sites using a static front page plus a posts page, the posts page now outputs its own title, description and canonical instead of the home page's.
* Fix: meta descriptions and titles are no longer corrupted on non-Latin content (Japanese, Chinese, Korean, Arabic, Cyrillic) or after an accented capital.
* Fix: category and tag archives are no longer set to noindex behind your back; only internal search and paginated pages get safe defaults.
* Fix: the meta description, schema and scores now refresh as soon as you edit a post, instead of describing the previous version for up to a week.
* Fix: the sitemap cron no longer loads the whole site in one pass (memory exhaustion on large sites), and deactivating the plugin no longer leaves /sitemap.xml answering incorrectly.
* Fix: the 404 log no longer freezes once full, and bot probes can no longer crowd out real 404s.
* Fix: the Markdown (.md) version of a post now respects membership and paywall plugins, and is no longer empty on shortcode-based page builders.
* Fix: every screen is now translatable; strings that were missing from the catalogue have been added.
* Fix: "Top pages seen by AI" counted SEO crawlers (Moz, Ahrefs, Semrush) as AI reads. Only genuine AI crawlers are counted now.
* Fix: running the analysis from the dashboard left the Actions screen claiming your pages had never been analyzed for up to five minutes. The cached views are now refreshed the moment the analysis finishes.
* Improved: OAI-SearchBot, the crawler behind ChatGPT search, is now recognised and logged.
* Improved: the "Go Pro" screen lost a redundant call-to-action that sat directly above the pricing table.

= 1.0.13 =
* New: edit the SEO meta title and meta description of your categories, tags and any public taxonomy, directly on the term edit screen. The front end already output these on category archives; you can now set them per term.
* New: a "First steps" checklist on the dashboard that guides your initial setup (make the site indexable, import from your previous SEO plugin, fill your company details, complete your author profile, submit your sitemap to Search Console). Steps are auto-detected where possible and the card disappears once everything is done.
* Translations: the new screens are fully translatable.

= 1.0.12 =
* Fix: FAQ and How-to auto-detection could truncate or miss the section on accented (e.g. French) content when the heading was preceded by multi-byte characters, because a byte offset was read as a character offset. Restored the byte-correct extraction.
* WooCommerce: product pages are no longer graded by the editorial content engine (which expects 800+ words and an H1 and therefore produced misleading low scores on products). Products now show an honest exempt state, previously stored misleading scores are cleaned up, and the overall score redistributes its weights accordingly. Meta title, description, social and advanced settings remain fully editable on products.
* Author schema: the Wikipedia, Wikidata, ORCID, Google Scholar and GitHub profile fields you fill in are now emitted as sameAs in the Person markup on the front end (they were collected but never output).
* Redirects: guard against pathologically long request paths in the regex matcher, invalid regex patterns are now rejected at CSV import instead of being silently stored, and the 404 counters now count exactly the same set of rows as the displayed list when named crawlers are filtered out.
* Hardening: DOM extension check restored in the content extractor for hosts without ext-dom.
* Interface: the "Go Pro" screen is now a full pricing page (Free / Pro / Ultra with a feature comparison), the Settings screen was redesigned and now includes the Health report as a tab, the Analytics screen was aligned with the paid layout, and the Actions and Health items were moved out of the top menu (Actions is reached from the dashboard). The dashboard "See my actions" button now points to the right screen.
* Honesty: paid-only capabilities are teased with the correct plan (Pro vs Ultra) and always as clearly labelled illustrations, never as hidden or locked data.
* Translations: the plugin is fully internationalised and the interface follows your site language; translations are delivered through translate.wordpress.org.
* Cosmetic: decorative characters removed from the schema type selector, the score panel and the sitemap pages.

= 1.0.11 =
* Fix (live front audit): llms.txt and llms-full.txt could return an unreadable (truncated) body on hosts that gzip-compress output, because an explicit Content-Length header no longer matched the compressed size. The header is no longer sent (same as robots.txt and .md pages), so the files now load correctly everywhere. Also fixed the Markdown alternate link on a static front page producing a malformed URL (domain.md); the site root no longer advertises a .md version.

= 1.0.10 =
* Second audit pass: fixed the Health screen wrongly telling you to disable a competitor, a global score that could store a stale value, competing-pages scan keeping unrelated pairs, a data-loss window for AI-bot tracking, times shown with a timezone offset, a few untranslatable strings, CSV import/export edge cases, and cleaner uninstall (multisite, author meta, on-disk sitemap cache). No functional loss.

= 1.0.9 =
* Security: password-protected posts can no longer leak their content through the Markdown (.md) routes or the llms.txt files. Reliability and SEO hardening from a full internal audit: taxonomy sitemaps are now served, no duplicate schema types, the "Service" schema is no longer emitted by mistake, redirect matching and UTF-8 handling improved, and several front-end performance paths were optimised.

= 1.0.8 =
* Schema detection improved: FAQ blocks rendered by modern Yoast are now recognised (class-based, comment-agnostic), so more of your existing FAQs produce FAQPage schema. Reference/source lists are no longer mistaken for HowTo tutorials, and numbered FAQ questions are read cleanly. Page titles aligned with the menu (Analytics, Redirects, Settings).

= 1.0.7 =
* Admin menu aligned with the rest of the Hack The SEO range: same labels and order (Dashboard, Actions, Redirects, Analytics, Content groups, Competing pages, Health, Settings, Go Pro).

= 1.0.6 =
* Markdown for agents: every published page is now also served as Markdown at /your-page.md (and via Accept: text/markdown content negotiation), with a Link rel=alternate hint in the HTML head so AI crawlers can discover it. 100% local, no request ever leaves your server. Can be turned off with the hts_free_md_enabled option.
* Automatic QAPage schema: when a page has real question/answer sections (question headings, details/summary blocks) and no FAQ schema, a single QAPage is now added to the existing JSON-LD graph. Never emitted empty, never duplicated, never on top of a FAQPage.
* Reviews: when a global Organization rating is enabled in the Schema settings, an auto-detected rating is no longer also attached to the page entity, so a page never carries two AggregateRating blocks.
* Accessibility: the blurred Pro preview is now hidden from screen readers, and the segmented tab controls are explicit buttons.

= 1.0.5 =
* Cocoons screen rebuilt as a card grid (one card per category) matching the rest of the plugin, with a clickable semantic-cocoon map drawn from your own pages. Consistent "pages below 50" and total-actions counters across the Dashboard, Actions and Cocoons screens.

= 1.0.4 =
* Three screens redesigned to match the rest of the plugin: the Site audit screen becomes an "Actions" screen with per-page action cards and estimated score impact; the AI crawlers screen gets a full analytics view (AI crawls, referred visits, per-bot cards, engagement); and the Cocoons screen now shows a realistic semantic-cocoon map built from your own pages.

= 1.0.3 =
* UI polish: the Competing pages, Health and Redirects screens now match the look of the rest of the plugin (severity dots on filters, refined status badges and iOS-style toggles, consistent loaders).

= 1.0.2 =
* Redirects & 404 log: major reliability backport from the Pro engine. Reciprocal redirect loops (A to B then B to A after a rename) are now prevented automatically. The 404 log default view now surfaces only real 404s (pages with an internal link or confirmed search traffic) instead of drowning in bot/scanner noise, with a "Show all" toggle. Anchored path matching (a probe like /console no longer hides a real /consoles-de-jeux/ page), a flood cap with one-click noise purge, deterministic pagination, and performance guards on large logs.

= 1.0.1 =
* Compatibility guard with Hack The SEO Pro: when the Pro plugin is active, the free plugin now stays fully dormant (the Pro version is a superset and takes over). Prevents any conflict if both plugins end up active at the same time.

= 1.0.0 =
* Initial public release.
* Meta tags: title, description, Open Graph, Twitter Cards, automatic alt text fallback.
* Schema JSON-LD: Article, BreadcrumbList, Person, Organization, LocalBusiness, FAQPage, HowTo, VideoObject and more.
* XML sitemap: index and per-type sitemaps, image/video/news extensions, XSL stylesheet, disk cache, noindex-aware.
* Redirects: 301, 302, 307, 410, regex rules, automatic 301 on slug change, admin table, CSV import/export. Served in PHP; the `.htaccess` file is never modified.
* 404 log with hit counts, local slug-similarity suggestions, and one-click conversion into a redirect.
* Breadcrumbs: shortcode, PHP function, Gutenberg block, BreadcrumbList JSON-LD.
* Robots: per-post noindex/nofollow and a virtual `robots.txt` served through the core `robots_txt` filter.
* Canonical URLs with conflict detection.
* Table of contents generated from H2/H3 headings (off by default).
* Optional removal of `/category/`, `/tag/` and `/product-category/` permalink bases, with automatic 301 (off by default).
* Virtual `/llms.txt` for LLM crawlers.
* Author schema (E-E-A-T) built only from user profile fields.
* SEO panel in the editor: 21 local checks, plus a composite global score and a freshness column.
* Keyword cannibalization detection, computed locally, with a recommended action per pair.
* AI crawler detection, server-side, for GPTBot, ChatGPT-User, ClaudeBot, Claude-Web, anthropic-ai, PerplexityBot, Google-Extended, Gemini-Bot, CCBot, Bytespider and Diffbot.
* Migration wizard importing from Yoast SEO, Rank Math, All in One SEO and SEOPress, including JSON-LD recovery from the rendered homepage.
* Competing-SEO-plugin detection and warning.
* Health check: sitemap, schema, canonical and HTML self-tests.
* IndexNow module, disabled by default (the only external service; see "External services").
* Uninstall preserves data by default; full deletion is opt-in.
