=== DigitalM Inside SEO Agency - full changelog ===

= 1.35.223 =
* Changed: the source strings in the code are now in English. Bulgarian comes from a bundled translation file (bg_BG .po/.mo/.l10n.php).
* Added: a translation template (languages/digitalm-insideseo-agency.pot) for translators.
* Changed: the script labels are passed through the same translation, so they follow the plugin language.

= 1.35.222 =
* Plugin Check: removed old inline rule exceptions (queue time limit, image language filter, client options list).
= 1.35.221 =
* Readme: new English screenshots and captions.
= 1.35.220 =
* Added: requests to the hub carry the plugin language (X-SEOH-Lang). With English the hub answers in English - AI errors, limits, agency connection messages and text-check explanations. Agency pro on the same site is covered too.
= 1.35.219 =
* Translations: remaining visible Bulgarian texts now go through translation (page type and checkout field labels, short finding details, units); English added.
= 1.35.218 =
* Changed: "Pages with this issue" under a finding is a collapsed list - it opens on click instead of filling the screen with hundreds of addresses.
= 1.35.217 =
* Faster: the Errors screen is much lighter. Findings shared by the whole site (touch icon, many CSS/JS files, fonts and the like) were sent with one full row per page - thousands of rows; now each page is a short entry and the screen expands them back, so the list of pages is still shown. Cyrillic text is sent as is instead of escaped (about a third of the size).
= 1.35.216 =
* Fixed: "Reasons from Search Console" in the view of another language version shows only the addresses of that version (the English view listed the Bulgarian addresses).
= 1.35.215 =
* Changed: clearer wording on the crawl screen - "found N issues", "Indexing" instead of "Indexability (the gate)", "Not enough text", language version picker; the label above the deep review groups is removed.
= 1.35.214 =
* Changed: the language version menu shows a flag, the language code and where the version lives (domain, subdomain or folder). The main language is always first and is no longer marked separately.
= 1.35.205 =
* Added: language switch in Images and Rewrite on a multilingual client site. The chosen language goes to the client with every request (needs Inside SEO 0.294.199 on the client).
= 1.35.204 =
* Added: in Errors, with "All languages" each row shows its language (BG, EN).
= 1.35.203 =
* Added: on a multilingual client site the Errors tab shows the main language by default, with a switch for the other languages (needs Inside SEO 0.294.197 on the client).
= 1.35.202 =
* Added: System information shows the client site language versions (needs Inside SEO 0.294.196 on the client).
= 1.35.201 =
* Changed: in Errors, a fix from the change log crosses out a row only if it was made after the start of the last full audit. An older fix that the audit still finds is shown as not fixed. A fixed row disappears with the next full audit.
= 1.35.200 =
* Changed: a file name with no word of three or more letters counts as generic: 2, 240426_069, 201-11, L-379-35. WordPress and copy endings (-scaled, -300x200, -Copy-3) are ignored when checking.
* Fixed: the Images tab and the Errors tab use the same rules for generic names (UUID names were missed in Images).
= 1.35.199 =
* Fixed: edit links for "URL differs from the title", the content list and the rewrite series opened the agency site. They now open the editor on the client site.
* Fixed: the redirect manager link points to the client site.
= 1.35.198 =
* Fixed: in Images, an image is "ready" only when its alt is filled, not repeated on another image of the same page, and its file name is not a camera number.
* Added: "Same alt" column and filter in the Images list; the name check covers the gallery too.
* Fixed: in Errors, saving images one by one lowered the counter once per image instead of once per page.
= 1.35.197 =
* Added: one-click fixes in Errors for "Sitemap not in robots.txt", "Hero image lazy-loaded", "Canonical points elsewhere" and "Canonical missing" (needs Inside SEO 0.294.187 on the client).
= 1.35.196 =
* New: fixes straight from the Errors tab:
  - "Mixed letters" and "Cyrillic in the image file name": new file name field with the AI button; renaming adds a redirect.
  - "H1 too short" and "H1 too long": a field for the new page title (H1) with the AI button.
  - "Code shown as text": "Fix the code" button (straight quotes in the tag, code written as text becomes a link).
  - "Double space and mixed quotes": a button for the title, short description and meta fields.
  - "Image without size": "Add the sizes" button for library images in the page text.
  - "Invalid link": a field for the new address; empty removes the link and keeps its text.
  - "Links without text": a field for each link; the text is added as aria-label.
  - "Title word missing in the text": the AI suggests a sentence with the word, with a Copy button.
  Needs Inside SEO 0.294.186 or newer on the client.
= 1.35.195 =
* New: "Alt text same as the product title" lists every such image with alt and description fields and the Save and AI buttons, like "Same alt text on several images". Needs Inside SEO 0.294.185 or newer on the client.
= 1.35.194 =
* New: groups of images in the Errors tab ("Same alt text on several images", "Images without alt text") have "Suggest for all" and "Save all" buttons. "Suggest for all" needs the AI module of Inside SEO Agency Pro 1.7.128 or newer.
= 1.35.193 =
* Fix: "Code shown as text" shows the code itself and marks it.
= 1.35.192 =
* New: "Code shown as text" finding with the spot marked. Needs Inside SEO 0.294.182 or newer on the client.
= 1.35.191 =
* Fix: changing the client on a screen without the view key in its address (for example the series rewrite screen) led to an empty page, because the screen name was not carried. The screen name now comes from WordPress itself. From the series rewrite screen the change goes to the "Rewrite" list of the new client.
= 1.35.190 =
* New: "Same alt text on several images" lists every image with alt and description fields and the Save and AI buttons. Needs Inside SEO 0.294.180 or newer on the client.
* New: "Mixed letters in the image file name" marks the letters from the other alphabet, and "Double space and mixed quotes" shows an excerpt with the spot marked. Needs Inside SEO 0.294.180 or newer on the client.
* New: "Title = H1" has a field to rewrite the meta title, with the AI button.
* Change: "404 errors" is no longer listed as unchecked, and "Duplicate content" now covers pages and posts (not products).
= 1.35.189 =
* Change: in the Images tab, a suggestion from the image analysis now shows in the alt text and description fields even when the site already has saved text, as long as it is different. The saved text is shown below the field as "now: ...". Before, the suggestion showed only in empty fields and the old text stayed.
= 1.35.188 =
* New: a link can open one finding in the Errors tab directly (the address ends with "&finding=<type>"). The monthly audit uses it for its "See all in Errors" links.
* New: when an agency page stops because it ran out of memory or time, the page, the client, the running work and the memory used are saved. The last 20 are listed in "System information".
= 1.35.187 =
* Fix: opening the plugin could run out of memory: the list of fixed items read the whole change log into memory. Now the database returns only the last action for each item.
= 1.35.186 =
* Change: the contact e-mail in the plugin (signatures and contact details) is now contact@digitalmseo.com.
= 1.35.185 =
* Fix: all database queries are prepared with placeholders, with no exceptions (keyword trend, month summaries). The selected pages and categories for the client queue and the selected channels are sanitised when read.
= 1.35.184 =
* Change: when a month summary is marked for recalculation, the plugin announces it (action seoha_month_summary_forget), so the saved monthly audit is rebuilt too.
= 1.35.183 =
* New: the 12-month charts in "Mirror" have a menu at the top right: Daily, Weekly (default) or Monthly. Weeks are built from the days. Keywords appear only in the monthly view. The header of the charts is smaller and further from the chart. Daily sales come straight from the fetched sales of the client.
= 1.35.182 =
* Change: the month summaries for the 12-month charts are kept in their own table, one row per month. The current month is recalculated once a day, the last two finished months once a week and older months once a month. When new data arrives for an older month (a fetch from Google, a new client, "Recalculate"), that month is recalculated without waiting.
= 1.35.181 =
* Fix: the 12-month charts used a lot of memory: for every month they read the whole list of keywords and, on a shop, every order. Now a month is summed once and kept (new month summaries); keywords are counted in the database. The current month is refreshed every 6 hours, finished months once a week.
= 1.35.180 =
* Change: the 12-month charts in "Mirror" are taller (140 px instead of 80 px), so the lines are no longer flattened.
= 1.35.179 =
* New: "Mirror" shows two 12-month charts above the cards, in the style of Ahrefs. Sales: revenue, orders, average order and keywords, each on its own scale. Traffic: sessions of the four main channels, stacked. Hover shows the values for a month; the boxes in the legend hide or show a line.
= 1.35.178 =
* Change: the line charts in "Conversions and traffic" no longer have an empty strip on the left.
= 1.35.177 =
* Change: the column headers of the large tables (for example "Keyword return") are 12 px and bold, as in "Ranking", instead of 10 px capitals. Amounts and numbers on the right no longer break onto two lines.
= 1.35.176 =
* Change: the line charts in "Conversions and traffic" are a third lower and their lines are thin (1.2 px at any screen width), with lighter grid lines.
= 1.35.175 =
* Change: the position chart in "Positioning" now covers the last 12 months and is lower and slimmer, as a quiet visual cue.
= 1.35.174 =
* Change: the 6-month position chart now has a thin grid (a line for each month and three across) and a dot for each month, so it no longer floats in empty space. A single month now shows as one dot.
= 1.35.173 =
* New: in "Ranking" → "Positioning", every table (keywords, all pages and each page type) now has a small chart of the position over the last 6 months. Green means the position went up, red means it went down.
* New: the page tables show "Conversions from Google" for each page: orders and their value, or the number of enquiries, from visits that came from Google.
* Change: the ranking tables now use the full width of the screen and have more room in each column.
= 1.35.172 =
* Change: the plugin now loads its files only when they are needed. A normal page of the site now loads about 20 small files instead of about 100, which saves around 8 MB of memory per visit. The toolbar menu moved to its own small file.
= 1.35.171 =
* Change: for a client without a shop on an older client plugin, "Conversions" says that the value of enquiries, custom events and form enquiries need version 0.294.165 or newer.

= 1.35.170 =
* Fix: after a client updated its plugin, the agency could wait up to 12 hours before using the new live views. When a view is missing from the remembered list, the agency now asks the client again (at most once every 10 minutes).

= 1.35.169 =
* Change: when the chosen client runs an older client plugin, "Conversions" says which new parts need version 0.294.165 or newer.

= 1.35.168 =
* New: "Conversions and traffic" for a chosen client shows the same new parts as the client plugin: a "By channel" tab, up to which day Google has data and today's visits, counting by payment date, orders without payment, the number of test orders, products sold only through ads, the value per enquiry, custom events and the number of form enquiries (only counts, no personal data). Needs the client plugin 0.294.165 or newer.

= 1.35.167 =
* Change: the charts in "Conversions" and "Traffic" are line charts: the current period as a solid line and the compared period as a dashed line, with a tooltip for each day.

= 1.35.166 =
* Fix: activation no longer schedules the old image clean-up task that had no handler; it is only cleared.

= 1.35.165 =
* Image deletion, speed settings and email, wp-config constants, empty category deletion, noindex removal and opening the site now run on the client (needs free plugin 0.294.151); the changed data is pulled right after.

= 1.35.164 =
* Speed: when the client has no admin load measurements yet, the screen says so instead of leaving the row out.

= 1.35.163 =
* Fixed: after a full structure pull, pages that no longer exist on the client are removed here too (only when the pull brought at least as many pages as the client has).

= 1.35.162 =
* Fixed: with no client selected, requests stay on the agency site instead of failing with "no client"; the Guide's open and search log is kept at the agency.
* Fixed: used client slots count only active links, as the hub counts them.
* Changed: today's sales from the client are kept for 2 minutes instead of 10.
* Removed: unused code (an unused form handler, a helper and a constant).

= 1.35.161 =
* Fixed: the Inside Score and the accepted-findings cache are kept per client, so one client no longer shows another client's numbers.
* Fixed: the GEO/AEO freshness thresholds are saved on the selected client, where they apply.
* Fixed: "Check the changes", "Clear system 404s" and "Check an address" now run on the client site and pull the result back.
* Fixed: when monthly pages or monthly keywords have fewer rows here than on the client, they are pulled again (at most once a day).
* Removed: an unused second record of the selected client.

= 1.35.160 =
* Summary by page: issues and spelling moved to the left, under the keywords. Traffic and conversions removed (they are in the number boxes). New speed box: mobile and desktop scores with LCP, INP, CLS, FCP and TTFB. When the page itself is not measured, the numbers come from a measured page of the same type (product for product, category for category), and the box says which page.

= 1.35.159 =
* Summary by page — new layout: eight number boxes on top like in Issues (position, clicks, impressions, keywords, visits, sales or conversions, issues, mobile speed, with the change since last month); keywords on the left; indexing and structure on the right; issues and spelling below; speed, traffic, GEO and the change log folded. The groups fold like in Issues "By page".

= 1.35.158 =
* Summary by page: issues and spelling now use the same look as Issues "By page" and Spelling — the same rows, the same explanation and the same fix fields, opened with "Fix".
* The Issues styles moved to their own file (admin/css/seoh-findings.css), shared by Issues and the summary.

= 1.35.157 =
* Summary by page: with Agency Pro, issues and spelling can be fixed right in the card, on the client's site.

= 1.35.156 =
* Mirror: "Page card" is now "Summary by page" and sits under the sales and traffic boxes. The item list comes right after the type, then the search.
* The page card sections are in a new order: Structure and links (now with content and images), Rankings, Indexing, Issues and spelling, Speed, Traffic and conversions, GEO and AI, Change log. New look; the issues section shows its count.

= 1.35.155 =
* New: "Page card" in Mirror for the selected client, read live from the client's site.
* Issues "By issue type": an image shown on many pages is one row; site-wide theme issues are one row. Counts match the rows.
* Fix: a PHP warning when a client has no link yet.

= 1.35.154 =
* Fix: "Images without alt" now counts each image once, not once per page that shows it.

= 1.35.153 =
* Fixed: English texts for the Google data volume card, the queue filters, the background run and the web search notice.
* Changed: the page list for the "By page" view no longer turns off query filters (Plugin Check).
* Changed: readme keeps the last 20 versions; the full history is in changelog.txt.

= 1.35.152 =
* Changed: no more 500-row limits on findings. The Errors tab, the queue, the editor box, the agency view and the accepted list read every row.
* New: folders can be excluded from orphan files (service PDFs, invoices). The setting is in the Errors tab, under the orphan files finding, with quick buttons for the biggest folders.
* New: the excluded folders are saved on the client site and drop out of the pulled findings at once.

= 1.35.151 =
* Fixed: the same finding no longer shows twice on one page in the "By page" view.
* Changed: theme-level findings (many CSS or JS files, third-party fonts, missing cache or compression headers) show once under "Whole site" instead of on every page.
* New: image findings show thumbnails in the "By page" view.
* Fixed: page titles with HTML entities show as plain text.
* Changed: "Checked and accepted findings" is now a collapsed accordion with a count.
* Fixed: image thumbnails in the Errors tab were empty for client sites. The image address now stays on the client domain.

= 1.35.150 =
* New: the "By page" view has filters on top: content type, subcategory, problem and search by name.
* New: spelling findings now show under each page, with the same fix and "Not an error" buttons as the Spelling tab.
* New: "Ignore in the report" works in the "By page" view too.
* Changed: "Other addresses" is always the last group.

= 1.35.149 =
* New: "By page" view in the Errors tab. Each page shows all its findings in one accordion, grouped by content type, errors first. The same fix buttons open right under the finding.
* Changed: the Errors tab no longer stops at 500 rows per finding type. All rows are shown.

= 1.35.148 =
* Series rewrite: the client product no longer replaces the images the extension already prepared, so the image review (colour, print, shared image) and the chosen images reach the model.

= 1.35.147 =
* Own AI: the model that answered is now recorded (the WordPress request builder exposes its methods through a magic call, so the old check never saw them).

= 1.35.146 =
* Own AI account: the model that answered is remembered and can be shown; more model name variants in the preference list.

= 1.35.145 =
* Own AI account: asks WordPress for a strong model (Claude Sonnet/Opus, Gemini Pro, GPT-5) instead of the first model in the provider list. The list can be changed with a filter.

= 1.35.144 =
* Own AI account: answer limits step 16000, 8192, 4096; big tasks wait up to 240 seconds; an answer that hit the limit is not retried with a smaller one.

= 1.35.143 =
* Own AI account: big requests get 150 seconds instead of the 30 WordPress gives by default; on a timeout the other attempts are skipped, so the request does not run past the server limit.

= 1.35.142 =
* Own AI account: big requests step down to 8192 and 4096 token limits instead of 1200, and a broken answer tries the next step instead of failing at once.

= 1.35.141 =
* New check from clients: "Page that leads to a missing address" (name, explanation and how to fix).

= 1.35.140 =
* Errors list for a client: titles and descriptions are found in the client's page structure again (the address was compared in the wrong form), so the "Fix" button and the current title show for every page.

= 1.35.139 =
* Code standards: two database queries added in 1.35.137-1.35.138 are written without suppression notes.

= 1.35.138 =
* Pulling from a client: the next pull starts from when the last one began, not from the newest row seen. Rows changed during a pull (page structure, terms, links to categories) were lost before. After the update the structure, terms and their links are pulled again in full, once.
* Terms, links to categories and page structure are pulled again when the agency has fewer rows than the client (before: only when it had more).
* A title or description that cannot be checked here (the page is missing from the structure) stays as a problem instead of being marked fixed.
* Service pages (cart, checkout, account) are recognised by the client's own paths, in any language.
* No caps on data in content checks: all products, articles, terms, conflicts and words; renamed-image redirects are all kept.

= 1.35.137 =
* Pulling from a client: for accepted exceptions, money by landing page, speed history, Google speed and suggested articles and terms, only new and changed rows travel (clients 0.294.124 and newer). Rows deleted at the client are removed here by a short list of row numbers.

= 1.35.136 =
* Proofreading for a client: the client's own dictionary goes on to the hub, so accepted words are not flagged.

= 1.35.135 =
* Switching the client: on the first screen after the switch, times were shown in the previous client's time zone. Fixed.

= 1.35.134 =
* Client status: dates are in the agency's own time zone, not in the zone of the selected client.
* Marks of done work: all of them are read (before: the first 20 000).

= 1.35.133 =
* A client that does not know the agency's address yet gets it with one signed command, so it can send notices about new data.

= 1.35.132 =
* A client that finished a crawl, structure, speed test or Google import tells the agency. A minute later the agency asks the client what is new and pulls only that. The 30-minute check stays as a backup.

= 1.35.131 =
* Client status: the crawl date is when the audit ran at the client. Before, a recent visit to a missing page (404) made an old crawl look fresh.
* Client status: a started check keeps waiting up to two hours from its start, not from the old date.

= 1.35.130 =
* Marked as done: the ten newer checks (missing title words, quote spacing and others) are subtracted the same as on the client.
* "Is it still wrong": a category with the same number as a page no longer decides for the page.
* All in One SEO: title and description keys, the same as on the client.

= 1.35.129 =
* Catalog: clearer text for addresses ending in "-2" - most often separate products with the same name.

= 1.35.128 =
* Screens: explanatory sentences removed, the same as on the client. Dates and volumes stay.
* Site errors: the real count above 500 rows (was shown as 500).

= 1.35.127 =
* Pull: when the client is saving a new crawl it answers "busy"; the agency keeps the old findings and asks again in five minutes instead of showing half an audit.
* Catalog: "Sitemap address that is not on the site" and "Page missing from the sitemap".

= 1.35.126 =
* Errors: "Reasons from Search Console" counts only problems (indexed pages stay in the list but are not counted) and stands right after "Not seen by search engines", or on top when there is none.

= 1.35.125 =
* Error list: the newer checks (image file names, alt texts, old year, title word, page not in menu and others) show their names instead of internal codes.

= 1.35.124 =
* Content ideas no longer stop with an error when their table is missing; the table is created through the public route.

= 1.35.123 =
* "Status by client" shows the client's times in real time again, without the time zone shift.
* The hub is asked every hour, so a newly approved client appears without a manual refresh.
* Prices of a selected client use the client's shop currency (needs the client plugin 0.294.95).
* Ending a client removes its leftover markers and cached live answers.

= 1.35.122 =
* "Refresh from hub" for a selected client forgets the old reports first, so the screen never shows stale numbers when the hub does not answer.

= 1.35.121 =
* Own AI account: one failed request (time-out, a refused prompt) no longer marks the account as unavailable for 10 minutes. Only "no model found" does. The last error is kept so it can be shown.

= 1.35.120 =
* Near-duplicates: the finding is called "Series of near-duplicate products" and counts series. The make-unique list shows products and series.

= 1.35.119 =
* Own AI account: requests can carry images (image analysis) and ask for web search (fact checks), through the AI connection in WordPress (Settings → Connectors).

= 1.35.118 =
* Ads: a budget or export saved at the agency is no longer lost. If the client does not answer, the record waits and is sent again with the next check of the link; the next pull does not overwrite it. The uploaded export file stays linked. The screen says when the client did not answer.

= 1.35.117 =
* System info: how much data comes from Google per day at each client, and on how many days the limit was reached (needs DigitalM Inside SEO 0.294.91 at the client).

= 1.35.116 =
* Agency link: every write, queue and command request to the client is signed with the agency key. One-time number and 5-minute window - a copied request does not work twice.
* Make unique: the list shows analyses and proposals kept at the agency. New filter by state.
* Background work keeps its client: GEO steps, Asset Lab steps, the night queue and speed measurements run for the client they were started for, not for the last chosen one.

= 1.35.115 =
* Client queue: the counts on the screen refresh right after work is done. Before they could stay old for up to 15 minutes.

= 1.35.114 =
* Client queue: "Run" now works in the background, like at the client. It also runs series analysis (it showed 0 of 0 before) and writes each product with its series.
* Client queue: client and agency are in sync. When the client presses "Run", the agency takes the tasks at its next check (about 30 minutes). The night run follows the client's checkbox - one checkbox, at the client.
* Client queue: when the AI provider is out of credits or the limit is reached, the run stops and the tasks go back to waiting. The last run and its reason are shown above the queue.
* Series analysis from the agency screen is reported to the client, so the rewrite can be added to the queue.

= 1.35.113 =
* Make unique list: the column now shows how many products the series has (with the product itself), not how many others are similar.

= 1.35.112 =
* Actions on the client site: when the client refuses an action, the agency screen now shows the client's own reason (for example that the text was changed after the check) instead of a bare "refused".

= 1.35.111 =
* Change log: paging with First, Back, a page number box, Next and Last. Paging and filters now keep working past the first page.
* Change log: new filter "Effect in Google" - improved, worse, no difference, waiting (under 30 days), no Google data.
* Change log: shows its size. Rows older than 24 months are removed for each client during the daily pull.

= 1.35.110 =
* Each user of the agency site now keeps their own selected client. Two people no longer switch the client for each other. Background work still uses the last selected client.
* Uninstall also removes the agency signing keys, the agency notes on posts, the ads folder and each user's selected client.

= 1.35.109 =
* The check for an AI model no longer sends a paid request. It only asks WordPress whether a text model is set up. If a real request fails, the plugin remembers this for 10 minutes.
* Questions on the audit screen are shown in the page with clear buttons, instead of the browser's OK / Cancel window.
* The text-check screen shows each note on separate lines: the mistake, the sentence it is in, the kind and the reason, then the fix.
* The script data for the in-page questions has its own name (SEOHA_ASK_L10N), so it does not clash with the free plugin.
* The text-check screen loads the notes already found on the client site right away.
* Audit: "Only one internal link" and "Broken internal links" moved to "Slowing down ranking".
* Index check: images, documents and theme or page-builder templates (for example Flatsome blocks under /blocks/) are no longer shown as pages.
* The agency's public key is sent to the hub again (wrong class name), so the hub can pass it to approved clients.

= 1.35.108 =
* Speed test (PageSpeed): works without Action Scheduler, through WP-Cron.
* Screen scripts are passed straight to wp_add_inline_script(), with every value escaped in that call (esc_js() or wp_json_encode()). The helpers that took a ready-made string are removed.
* The print styles and the client status table styles moved into admin/css/seoh-admin.css.
* Removed the Author URI header. The Plugin URI stays.

= 1.35.107 =
* Table updates now go through dbDelta on each version change, for every client. No more manual ALTER TABLE, and no old-table cleanups.
* Uninstall deletes options through delete_option(), so the WordPress cache is cleared too.
* Every prepared query now passes its values one by one, so the number of placeholders can be checked.
* Queue items are saved one by one instead of one large multi-row query.
* The plugin no longer defines WordPress core file-permission constants; file writes give the permissions themselves.

= 1.35.106 =
* Removed code that no longer has any user: the multi-language helper for the agency's own site and an unused hook for sending changes.

= 1.35.105 =
* New read-only helpers over the client data that was already pulled (one image, image search, page rows, titles by type, duplicate meta), for the paid add-on.
* Removed the old box that resent the agency's own sales to the hub. The agency does not send its own data.
* Missing English translations added.

= 1.35.104 =
* Removed the old code that read or changed the agency's own site. Every screen and action now reads from and sends to the selected client. The agency's own site is followed as a client through the free plugin.
* FAQ blocks, saved schema, image texts, image renames and the menu tree now go to the client site.
* Uninstall no longer touches data that belongs to the free plugin on the same site.
* Faster cache clearing for client views (works with persistent object caches).

= 1.35.103 =
* Faster screens: reads from the plugin's own tables go through the WordPress object cache. Any write to these tables clears it at once, so the screens always show the current data.

= 1.35.102 =
* Removed the unused background audit runner and the helpers only it used. The audit runs on the client's site.

= 1.35.101 =
* File rules: the "keep only on chosen pages" list now shows the client's own pages and finds where each form is used on the client's site. It was not shown before.
* Removed an unused /llms.txt output and own-site page lookups (the client's site serves its own llms.txt).

= 1.35.100 =
* File-rule preview links for a client carry the client's own public nonce, so they keep working with the free plugin 0.294.72 or newer.

= 1.35.99 =
* Clean-up: removed the old copies of the screen actions that now always run on the client's site, the front-end test load and the slowdown tool (the agency does not measure its own site), and several unused classes. About 12,700 lines less; screens work as before.

= 1.35.98 =
* What you set for a client is saved on the client's site: the file rules in Speed (and their preview links use the client's own key), the llms.txt selection, and the ads figures. Needs the free plugin 0.294.71 or newer on the client site.
* Suggested questions and schema: the agency's AI writes the suggestion from the client's page, and it waits for approval on the client's site.
* "Search Console reasons" in Errors are shown again, from the client's data.

= 1.35.97 =
* A client is always selected while the agency has clients: with none chosen yet, or after the chosen one is removed, the first client in the list is picked — the same one the menu shows.
* The agency no longer measures or changes its own website: the monthly speed check and its email, the admin load timing, the file rules and the test load on the front end are off. The agency's own website is followed as a client, with the free plugin.
* Addresses on the screens (content, structure, links, PageSpeed suggestions, page inspector) are built from the selected client's site.
* The "Check in Search Console" and "Rewrite breakdowns back" buttons are back; they run on the client.

= 1.35.96 =
* Removed the agency's own Google connection. Search Console and Analytics figures always come from the selected client's site, where Google is connected. The agency's own website is followed as a client, with the free plugin.
* Removed the unused set-up wizard and the key check address that only the Google connection needed.
* A short address in the page report now opens on the selected client's site.

= 1.35.95 =
* Fixed a fatal error when another plugin reads the time zone or builds an admin address while plugins are still loading.

= 1.35.94 =
* No output buffering anywhere: ob_start() is gone. Screen parts are built as strings and returned.
* Every screen address that carries a choice (month, page, sort, search, tab) now carries a nonce for the logged-in user, checked with wp_verify_nonce() before any of it is read. Without a valid nonce the screen opens with its defaults.
* Front-end requests for the speed probe and the asset rules preview carry a nonce checked with wp_verify_nonce(), in addition to the short-lived secret key.
* The Google connection return is posted as a nonce-protected form to admin-post.php, with a capability check.
* No change in behaviour.

= 1.35.93 =
* All file operations go through WP_Filesystem (moving, deleting folders, write checks, writing and reading files) or wp_delete_file(). The ads CSV is read through WP_Filesystem and parsed in PHP.
* The HTTP/2 check no longer touches cURL: it reads the protocol agreed during the TLS handshake (ALPN), with the WordPress HTTP API response as fallback.
* Removed every phpcs:ignore / phpcs:disable comment from the code.
* No change in behaviour.

= 1.35.92 =
* Review follow-up: every table and column name in SQL now goes through the %i placeholder, including names returned by a method and schema queries (SHOW COLUMNS, ALTER, DROP, TRUNCATE, CREATE). IN lists and bulk inserts use placeholders built with array_fill(); filters are fixed SQL with placeholders instead of strings assembled in PHP.
* Request input is sanitised where it is read with WordPress functions (sanitize_text_field, sanitize_textarea_field, esc_url_raw, map_deep, absint). Data from json_decode() is cleaned value by value.
* The standalone consent page loads its CSS from a file through wp_register_style() / wp_print_styles() instead of a style tag.
* Every output buffer is closed in a finally block in the same function, so nothing can skip the close.
* No change in behaviour.

= 1.35.91 =
* Review follow-up: added a nonce to the client picker; the HTTP protocol check now uses the WordPress HTTP API instead of a direct call; passed all the plugin's own table names through prepared queries (the %i placeholder). No change in behaviour.

= 1.35.89 =
* New: a "Status by client" table in Settings. For every client it shows four checks — structure, crawl, speed and console/analytics — each with a word (current/stale) in the right gender and the client's own last-run date. A per-check refresh arrow starts the check on the client (crawl/structure as a command, both speed tests like the Speed tab) and the cell shows "refreshing" until the client's timestamp moves, then downloads only what changed; the wait continues in a 5-minute background task. Name search, pagination of 25, a "Refresh all stale" button and a per-client download arrow. The clients list is merged into this table.
* Fixes: freshness dates now come from the client's handshake (so speed no longer shows a stale date); the print layout of the overview report no longer overlaps on a narrow page; removed an unused minified script; speed reads past days from the downloaded data and asks live only for today.

= 1.35.73 =
* Review follow-up: the wp-config helper no longer keeps a copy of wp-config.php on disk and uses WP_Filesystem; moved "Tested up to" to the readme only; sanitised a few request keys and the request URI; moved all inline admin scripts and styles to wp_add_inline_script / wp_add_inline_style. No change in behaviour.

= 1.35.71 =
* Code quality: cleared all Plugin Check findings — removed a few no-op translation wrappers, used a literal text domain in the menu, passed a LIKE pattern through a parameter, annotated the internal database queries in the data layers, and noted that the agency REST endpoints verify a signed key inside their guard. No change in behaviour.

= 1.35.69 =
* New: "Your site" - follow the agency's own website with one button, without taking a client slot.
* New: a "More of our plugins" page that lists our other free plugins from WordPress.org; nothing is installed without your click.
* New: "Something not working?" form on the Guide screen, sent only on click; with your account email and consent it becomes a support ticket.
* Fixed: connecting Google for the agency's own website when the client plugin is on the same site.
* Improved: clearer texts, full English interface, and all browser pop-up dialogs replaced with on-page messages.

= 0.272.8 =
* New endpoint /wp-json/seoh/v1/agency/data — an agency you are connected
  to can read the rows behind the numbers: findings, Google history,
  monthly and daily rankings, the change log, and daily journey figures.
  Paged, incremental, ETag-cached, HTTPS only.
* Page content, individual orders, individual visitor sessions, Google
  keys and passwords never leave through it. The change log gives what
  was touched, not what it says.

= 0.272.7 =
* Fixed the audit and the structure crawl appearing to run on every admin
  page load. A run that died mid-way left its "running" flag up forever,
  and the browser kept pushing it. Both now go stale after 30 minutes of
  no progress, and the audit stops after three failed attempts.
* Structure progress is now counted per item, not per batch, so a single
  broken page no longer makes the counter stick at the same number.
* The daily structure crawl was scheduled by default and ran the full
  wipe-and-rebuild. It is now off by default, and when on it runs the
  incremental pass.
* Fixed a wrong class name (SEOHA_HubSender) that made licensed sites run
  the heavy full crawl instead of just sending data to the hub.

= 0.272.6 =
* The Agency tab now lets you give the data-sharing consent after the
  connection was made. Connections created before that consent existed
  were silently refusing every request.

= 0.272.5 =
* The agency connect page now spells out exactly which data the agency
  will receive, what it will not receive, and how the exchange works.
  A second, separate consent box is required.
* Consent is stored with a timestamp and shows in the Agency tab.
* Without that consent the summary endpoint refuses, even with a valid
  connection code.

= 0.272.4 =
* Fixed a hang when the hub lives on the same site: the plugin no longer
  makes an HTTP request to its own server, which blocked the worker
  until the request timed out. It now calls the hub in-process.

= 0.272.2 =
* Agency summary endpoint now reads the connection code from the
  X-SEOH-Agency header instead of the query string, so the code no longer
  leaks into server and proxy logs.
* The endpoint refuses plain HTTP requests.

= 0.270.5 =
* New: reviewed and accepted issues - mark a finding as reviewed with a reason and a note, so it drops out of the count, the plan and the score but stays in its own table; postponed ones return after their date.
* New speed checks (main image lazy-loaded, oversized or old format; several oversized images; third-party fonts; missing font-display; missing preconnect; tracking before consent) and a new "external calls" server measurement.
* New: an optimization log that records each speed and file-loading rule change with the before/after numbers, plus a per-page view of which CSS and JavaScript load where, cache-plugin detection and a warning when another optimization plugin is doing the same job.
* Keyword impression counts now match Google Search Console exactly, and traffic figures are shown against the previous period.
* Documentation: the readme now describes the above. This release also carries the earlier Plugin Check clean-up (file-level annotations on internal data-layer queries, recommended WordPress file functions, unslashed and sanitized admin inputs, a translators note) with the stable tag aligned to the version. No change in behaviour for the code-quality items.

= 0.267.10 =
* English interface completed. The Spelling screen and its whole panel are now translated, along with a set of labels that were still showing in the source language: the database table names on the System information screen, the "Orders" metric, and the broken-install notice. Every interface string in the plugin and its scripts now has an English translation.

= 0.267.9 =
* Plugin Check: the proofreading data layer now suppresses the direct-query warnings at file level (internal core tables, all values through prepare), clearing the last "incorrect number of replacements" warning on its post lookup.

= 0.267.8 =
* Plugin Check: aligned the stable tag with the plugin version; the new proofreading and task-queue data layers now suppress the direct-query warnings at file level (internal tables, values passed through prepare); the proofreader AJAX handlers note that the nonce and capability are verified in their guard; and the queue on/off, URL and ID inputs are now unslashed and sanitized.

= 0.267.1 =
* Money is no longer taken as proof that the meaning check succeeded - a truncated answer is paid for too. The flag travelling with the answer decides; the cost is only consulted when talking to a hub old enough not to send one. This is what was wiping grammar and style notes on a re-check.
* A single-item check reports the real number of texts read instead of always saying one.

= 0.267.0 =
* A re-check no longer erases what only the model can find. Grammar, meaning and style notes survive a pass in which the meaning check did not run - because it failed, was switched off, or the limit was gone - instead of being wiped by the dictionary-only result. They are dropped only when a real meaning pass replaces them.

= 0.266.99 =
* The Fix button no longer appears on advice. A model answering a grammar note sometimes returns an instruction - "lower case for common nouns and finish the sentence" - rather than replacement text, and writing that into the page would destroy the sentence. A suggestion now earns its button only if it reads like a literal replacement: short enough, no brackets, quotes or "e.g.", and sharing at least half its words with the text it replaces. Everything else says "fix by hand".
* The same test runs server-side, so an old page left open in a tab cannot push advice into the content either.

= 0.266.98 =
* A run that was charged for is a run that happened. If the hub billed the request, the meaning check is reported as done even when the flag travelling with it says otherwise - which it could, when an older paid plugin passed the hub's own "I handed this to the site" marker straight through.
* When it really did not run, the line now names who was asked and how many texts were sent, so the reason is on screen instead of guessed.

= 0.266.97 =
* "Do we have a working local AI" is now answered by asking it, not by trusting its own claim. Some providers report that text generation is supported and then match no model to any real request. The answer is cached - six hours for yes, ten minutes for no - so it costs a couple of tokens a day.

= 0.266.96 =
* One more fallback for "No models found": a separate system instruction is itself a capability the provider has to declare, so the last attempt folds the rules into the task text and asks without one. Four ways are now tried in order before giving up.
* When it still fails, a live probe runs four one-word requests and reports which way of asking the provider accepts - or the exact error for each - instead of a generic "check your settings".

= 0.266.95 =
* "No models found that support text_generation" is fixed at the source. The requested output ceiling is part of what WordPress matches models against, so a request asking for more than the provider advertises finds nothing. The call now retries with a smaller ceiling and then with none at all before giving up.
* Provider errors are translated: no matching model, provider quota reached, no credit - each gets a plain sentence saying what to do instead of the raw English message.

= 0.266.94 =
* The Spelling screen says out loud whether the meaning check happened. A green line - "meaning check ran through your AI account, 4 texts" - or a red one carrying the exact reason it did not. No more guessing from the absence of findings.

= 0.266.93 =
* The Spelling run shows what it costs while it runs: total spent and the average per item, measured from the actual run rather than estimated. Checking a single item reports its own cost too.

= 0.266.92 =
* A search box next to the item dropdown in the Spelling tab. Typing narrows the list as you go, so one product out of six hundred is two keystrokes away instead of a long scroll. It counts what is left, keeps the current selection if it still matches, and clears itself when the type changes.

= 0.266.91 =
* Findings are now an accordion, like the task queue: content type on top, each checked item under it, and every item keeps its own notes. Types open, items closed, counts on both levels.
* Each note shows the sentence it was found in, with the offending words highlighted inside it, so the place is visible without opening the editor.

= 0.266.90 =
* The Spelling tab is a hook, not a locked door. It appears only when the paid part has attached itself; without it there is no tab, no greyed-out button and no mention of a paid feature anywhere in the free plugin, exactly like the Pending tasks tab.

= 0.266.89 =
* Spelling check now sends only the human text. Shortcodes and their attributes, editor block comments, inline styles and scripts, CSS rules, key=value settings, links, e-mail addresses, base64 strings and letter-plus-digit codes are all removed before the text leaves the site. A page-builder page was reporting theme settings as spelling mistakes; it now reports only what a reader would see.
* The original field is untouched by this - cleaning happens on the copy that is checked, so a fix still writes back into the real content.

= 0.266.88 =
* A used-up monthly limit no longer stops the spelling run. The meaning check switches itself off, the batch is read again with the dictionary and punctuation - which cost nothing - and the run carries on to the end. The message now matches what actually happens.

= 0.266.87 =
* Spelling tab tidied: the two explanatory paragraphs are gone, the button reads "Check", the meaning checkbox says it needs an API key, and the re-read checkbox now says what it does - check the ones already checked - with the full explanation on hover.

= 0.266.86 =
* Spelling tab reads like a teacher marking an essay. Each finding is tagged by kind - spelling, grammar, punctuation, meaning, style - with its own colour, and shows the sentence it sits in.
* The free layer now includes punctuation, so a run without the paid full check already catches spacing and unclosed brackets.
* With the full check on, objects are read three at a time instead of ten, because whole descriptions are sent for marking.

= 0.266.85 =
* Spelling tab: a type filter and a second filter for one specific product, page, post or category - the same pair as in Uniqueness. Pick an item and only that item is read, straight away, whether or not it was read before.
* Audit tabs reordered: Errors, Speed, Images, Content, Uniqueness, Spelling, Pending tasks, Log, Crawl.

= 0.266.84 =
* The Spelling tab sends the site's language along with the text, so the Bulgarian dictionary is only applied to a Bulgarian site.

= 0.266.83 =
* New Audit tab: "Spelling". It reads the text already on the site - products, pages, posts and categories - across title, short description, description and the meta texts, and lists what is wrong with a suggested correction.
* Nothing is changed on its own. Each note has a "Fix" button that replaces that one word in that one field, keeping the capital letter, and a "Not an error" button that remembers the word for good.
* Each object is read once. A fingerprint of its text is stored, and it is read again only if someone changed it, so a second run over a large catalogue is nearly free.
* Words the shop itself uses everywhere are never called errors - brands and model names are skipped automatically.
* The category name is never rewritten from here, because it moves the address.

= 0.266.82 =
* Queue rows show the guard's notes. When the hub flags an expression that is not said that way in Bulgarian, the row carries a yellow box with the phrase, the reason and the better wording, right above the Save button.

= 0.266.81 =
* The image title in the media library is written too. Until now only the alt text and the description were saved, so the title stayed the camera number - "250228_205_1". It is now taken from the alt text, shortened to one clean phrase, and written at the moment you save that image.
* A human written title is never touched. The title is replaced only when it is empty, has no real word, repeats the file name or is a camera pattern like IMG_2201.
* The attachment slug stays as it was, so no address changes and no redirects are needed.
* A rename fixes the title too. Nothing runs in bulk and nothing runs on its own - one image is touched only when that image is saved.

= 0.266.80 =
* New shop vocabulary: the words this site actually uses, collected from product titles, categories, tags and attribute values, cached for a day. It exists so the text checks do not have to be written by hand for every shop.
* It also builds a stem index, so a word can be matched to the shop word it was derived from - "norkova" to "norka" - even though neither is a prefix of the other.

= 0.266.79 =
* Images tab: three checkboxes decide what gets written - file name, alt text, description - the same way the Uniqueness screen lets you pick fields. They apply both to "Save" on a single row and to "Save all filled in". An unticked field is left exactly as it is on the site.
* The search results now mark images that already have an earlier analysis with a green "suggestion ready" badge, so you can see before ticking which ones cost nothing.

= 0.266.78 =
* An image that already has an earlier Vision analysis no longer pays for a second one. When such an image enters the queue it goes straight to "waiting for review" with the stored suggestion, and the message says how many came for free.
* The search now also explains an empty image result: "the site has N such images, but all N are already waiting in the queue" - which is what "no generic file names found" actually meant while 195 image tasks were sitting in the queue.

= 0.266.77 =
* The queue's meta problems were named "Title missing / too long / too short", which reads like the H1 findings next to them in the Errors tab. They now say "Meta title", so a count of 6 for "H1 too long" is not mistaken for the meta title finding, which had 1.
* An empty search result now explains itself: how many findings the audit has for that type and why none of them qualified - already queued, address does not resolve to a page on this site, or a different content type.
* A finding address that is percent-encoded is now also tried decoded before giving up on it.

= 0.266.76 =
* Pending tasks is now two clearly separated parts. The top one, "Add to the tasks", searches the SITE by content type and problem type, lists what it finds with a tick per row, and adds the ticked ones to the queue. Things already waiting are left out of the results.
* The bottom part, "The task queue", is always fully visible and is only for processing. The content-type and problem filters no longer narrow it - they belong to the search above. Only the state filter and the six counters narrow the queue.
* The run button follows the same rule as before: with rows ticked it runs only those, otherwise everything waiting.

= 0.266.75 =
* The confirmation before a run now shows money, not just a request count: the estimated cost in euro, how much is left this month, and a warning when the job is bigger than the remainder. An article counts as about ten requests, a meta task as up to two, an image as one - so the estimate matches what is actually spent.
* When the hub has no price list yet, the wording falls back to counting requests instead of inventing a sum.

= 0.266.74 =
* Errors tab: tick individual rows and press "Add the ticked ones to the queue". The old button that took the whole finding is still there, next to the explanation.
* Fixed items now disappear from the Errors tab as soon as the queue writes them, instead of waiting for the next audit. Nothing is removed on trust - the page is re-checked live, and the row stays if the problem is still there. A renamed file is re-checked after the rename actually runs.
* The "Add to the queue" button under a finding no longer fires several times. Its handler was attached on every redraw of the explanation panel, so the request piled up.

= 0.266.73 =
* The night checkbox is renamed. "run at night too" said what the plugin does, not what you get; it now says "process in deferred (night) mode", with a tooltip explaining that saving to the site still waits for you.

= 0.266.72 =
* "Run the queue now" now respects what you ticked. With rows ticked it runs only those - at any of the three levels - and the confirmation says how many. With nothing ticked it works by the filters, as before.
* The queue can be restricted to an exact list of task ids, which is what makes the above possible.
* The tick column in Images and Uniqueness is hidden when the paid part is not installed. Without it there is nothing those ticks could do.

= 0.266.71 =
* The run button now says "Run the queue now" instead of "Run by this filter", with a tooltip and a line below it: this is the only button that calls the AI and spends requests, it runs in the background, and it processes whatever matches the filters above.

= 0.266.70 =
* Clearer wording in Pending tasks. "Approve and save the selected" is now "Save to the site", "Decline the selected" is "Do not save them", and "Remove from the queue" is "Delete from the queue". Each button has a tooltip and there is one line under them explaining all three.
* Declining a whole level now covers ready suggestions too, not just the ones still waiting. Before, a ready suggestion survived the decline and could be written later by accident.
* Fixed an undefined variable when a bulk action was run on individually ticked rows.

= 0.266.69 =
* The Mirror no longer prints a PHP warning inside the "Indirect sales" card. The channel rows come from the hub and can arrive in a different shape; a row without a name is skipped, and the name is also read from inside the row when the hub sends a numbered list.

= 0.266.68 =
* New kind of task: a new article. The queue holds a finished skeleton, shows it for review, and starts writing only when you press "Write the text". The draft is created empty at the moment of queueing and nothing is published at any point.
* The article row shows the plan, how far the writing got, and a link to open the draft.
* The list of findings the queue can take moved into one shared place, so the Errors tab and the monthly work plan offer the same set.

= 0.266.67 =
* Meta titles and descriptions are now a kind of task. "Add to the queue" in the Errors tab works for missing, too long and too short titles and descriptions; the page itself is the target, not an image.
* Duplicated titles and descriptions deliberately stay out: they are a group problem and belong with the uniqueness work, not with one page at a time.
* Reasons merge. A page already waiting because of a long title keeps that reason when it also enters because of a missing description.
* A page already waiting for uniqueness is skipped - the meta texts are written there anyway.
* The review row for a meta task shows the current text with its length and an editable field for the new one; "Save" writes into the active SEO plugin (Rank Math, Yoast, SEOPress, All in One SEO).
* Writing meta into the SEO plugin now happens in one shared place, used by both the Errors tab and the queue.
* Restored the three missing save helpers behind the queue - approving a task called methods that were not in the file, which was a fatal error.
* The "more N" link inside the insight blocks now marks itself as handled, so the pro script does not toggle it a second time.

= 0.266.66 =
* Checkboxes are square and readable again. The control-height rule was squashing them, so it was impossible to tell an empty box from a ticked one.
* Ticking a level now says so in words ("selected: 189") and a parent shows a half-state when only part of what is under it is picked. Rows loaded after the tick inherit it, so what will be affected is no longer a guess.
* New "Add to the queue" button in the Errors tab, under "How to fix it", for the image findings. One click from "141 images without alt" to a filled queue, with the same count and credit confirmation as elsewhere.

= 0.266.65 =
* Uniqueness tab: "in the queue" was misleading - it also lit up when only the product's images were queued. It now says exactly what is waiting: "queued for text" or "queued for images".
* Images: "No description" now reads "No image description", in the column header and in the filter, so it is not confused with the product description.
* The "Indirect sales" card now links to the screen that lists which pages actually assist.

= 0.266.64 =
* The plugin now tracks where each image is actually used - as a featured image and inside product galleries - and flags the ones that live in several places at once. Text written for one product would be wrong for the blog post using the same picture, so those images get their own problem type ("Shared image") that can be filtered, and a red badge with the number of places.
* The lookup deliberately reads only the two indexed meta sources. Searching post content by file name was tried and dropped: it scans the whole posts table per image and matches "dress" against "dress-2", which produced false positives.
* The usage answer is cached on the image for seven days and forgotten when the file is renamed.
* Accordion: the checkboxes now read as checkboxes with a "select" label next to them, and expanding a level uses a triangle instead of a plus sign.

= 0.266.63 =
* Pending tasks is now an accordion on three levels: kind of work, then the product or page, then the rows themselves. With hundreds of tasks the flat list was unreadable; now nothing loads until you open it.
* A checkbox on every level. Ticking a kind or a product sends a scope to the server instead of hundreds of ids through the browser, and ticking a level also ticks everything opened under it.
* Approving in bulk now happens on the server from the stored suggestions, so it no longer breaks on a row type it did not expect and no longer stops halfway.

= 0.266.62 =
* Making the text unique now runs from the queue, so "Add to be made unique" is a real button: the series root travels with the task and the finished text waits for review in the series screen.
* One product, one preparation is now active: adding a product to be made unique merges its pending image tasks into it, and images are skipped for products already waiting.
* The confirmation for "Add for analysis" warns about credits again - the analysis does go through the AI, not only the local pre-pass.
* The finished unique text is now reviewed inside the Pending tasks tab: the current value and the new one side by side for title, short and long description and the meta pair, editable before saving, plus the list of images that will be renamed. Saving goes through the same apply path the series screen uses.
* Merging image tasks into a uniqueness task no longer deletes suggestions that were already prepared and paid for - only the ones still waiting.

= 0.266.61 =
* Pending tasks: the list no longer opens filtered to "waiting for review", so the tasks waiting to be processed are visible straight away. The five counters became six (a separate "in progress") and each one is now a button that filters the list to it.
* One height for every control inside the plugin screens - buttons, selects and text fields now line up. Buttons grew a little, fields shrank a little, and both met at 32 pixels.

= 0.266.60 =
* All buttons inside the plugin screens now share one shape and height, so a WordPress button and an AI-module button no longer look different side by side.
* Uniqueness tab: a checkbox in front of every product, a state column (analysed / made unique / in the queue), and two buttons - "Add for analysis" and "Add to be made unique".
* Making a product unique requires a finished analysis. Products without one are skipped with a note instead of burning a request.
* Note: absorbing the image tasks into a uniqueness task is deliberately NOT active yet, because the unique text is still finished by hand from the series screen. Nothing is deleted, so no work is lost.
* Identical image files are recognised by content and analysed once; the text is then copied to the twins where their fields are empty. Model shots reused across every colour no longer cost one request each.

= 0.266.59 =
* New "Pending tasks" sub-tab under SEO. One screen for the whole preparation queue: counters, filters by content type, problem type and state, tasks grouped per page or product, and approval right in the row - read the suggestion, correct a word, press "Save".
* The queue now lives in its own database table (SEOHA_Queue), so it can hold thousands of rows and filter fast. Adding is free; the AI cost starts only when the processing is run.
* Images listing: a checkbox in front of every row plus "Add the selected to the queue". Before adding, the plugin counts the images behind the ticked rows and asks the hub how many AI requests are left, then asks for confirmation.
* The "Night image preparation" panel moved out of the Images tab into the new tab.
* One shared button style for the whole plugin, so "Save" and "Suggest with AI" are the same height and shape. "Update" is now "Save" where it means saving.

= 0.266.58 =
* Removed the "save automatically" checkbox from the Images tab. The night queue only prepares suggestions; nothing reaches the site without a human approving it.

= 0.266.57 =
* Image renaming now also fixes the addresses in the content. After a rename, the plugin replaces the old file path with the new one inside post content, covering the full-size file and every generated size in a single pass. Serialized meta is left untouched on purpose.
* Image renaming no longer marks the live image as pending deletion. That was a leftover flag which listed every renamed image among the ones marked for deletion. The files left over from the old name are recorded separately and a daily job removes them after 30 days.
* A suggested name containing a dot ("chair 2.0 oak") is no longer cut short; only real image extensions are stripped.
* Images tab: new "Night image preparation" panel at the top — counts of images waiting for review, done, queued and failed, a per-page list with a "Review" button, and a "Run the preparation now" button. It is drawn only when the Pro queue is present.
* New public helper SEOHA_Images::is_generic_name(), so the Pro side can decide whether a file name is nondescript enough to be replaced automatically.

= 0.266.56 =
* Images tab: new "Suggest for all" slot next to "Update all filled" — the AI module walks the listed images one by one and fills name, alt text and description.
* Images tab: new "Add to the task queue" button in the listing — sends every problematic image under the current filter to the Pro night queue.
* New helper SEOHA_Images::problem_images() returns the problematic images for a filter; image collection extracted into post_image_ids().

= 0.266.55 =
* Declared compatibility with WordPress 7.1 (Tested up to: 7.1).
* Plugin Check: fixed a LIKE query in the URL-parameter scan to pass its wildcards through a placeholder, and restored the data-layer file-level suppression that a stray phpcs:enable had cancelled, so the rankings and change-history queries no longer report direct-query warnings.

= 0.266.54 =
* Code quality for the Plugin Check tool: passed database table names through %i placeholders in the rankings, change history, database stats and audit queries, and used the full sniff names in the remaining direct-query annotations so the newer Plugin Check recognizes them.

= 0.266.53 =
* Completed the English interface translation: added the remaining page and JavaScript strings so nothing stays in Bulgarian when English is selected.
* Mirror screen: the change figure (for example "(+11,664)") now sits on its own line under the main number and is smaller, so it no longer overlaps the channel breakdown on the right.

= 0.266.52 =
* Conversions & Traffic is now available for every site type, not only WooCommerce stores. Service sites and blogs see conversion goals (calls, emails, forms, bookings, newsletter) plus a Traffic sub-tab. The menu was renamed from "Visits and sales" to "Conversions & Traffic" in both the top and side menus.
* Added a change history that records edits to titles, meta descriptions and content, with who made them and when.
* Many fixes and refinements across the audit, content, speed and settings screens.
* Code quality for the Plugin Check tool: aligned the stable tag with the plugin version, added a missing translator comment, and passed database identifiers through %i placeholders in three prepared statements.

= 0.266.3 =
* Documentation refresh: the readme now describes the full feature set (Mirror, over 100 audit checks, speed from real visitors, GEO/AEO with llms.txt, WooCommerce conversions, rankings, crawl, content planning and monthly tasks).

= 0.266.2 =
* Code quality pass for the Plugin Check tool: translator comments for all placeholder strings, input sanitizing and unslashing on admin AJAX handlers, and database identifiers passed through %i placeholders in prepared statements.
* Replaced array_is_list() with an internal helper to stay compatible with the declared WordPress 6.2 minimum.

= 0.213.5 =
* Removed all remaining paid/locked wording from the English translations and the readme.
* The site now registers with our connection service only when the user clicks "Connect Google account" (no automatic call before consent).

= 0.213.2 =
* The Google connection origin check now runs entirely inside the plugin, with no dependency on the hub database.

= 0.213.1 =
* Fixed the admin stylesheet not loading after the slug change.

= 0.213.0 =
* The "Fix" button now writes titles and meta descriptions directly into the active SEO plugin (Yoast, RankMath, SEOPress, All in One SEO) for everyone, with no restrictions.
* Text domain aligned with the plugin slug (digitalm-insideseo-agency).
* Hardened the Google account connection with an origin check on the return step.

= 0.212.0 =
* Renamed to DigitalM Inside SEO.
* Streamlined the plugin for the WordPress.org directory.
* Menu reorganized: Mirror, Conversions, Rankings, SEO, GEO/AEO, Settings, System info, About.

= 0.211.0 =
* Google connection simplified to a single button.
* Full English translation of the interface.
* Compatibility with WordPress 7.0 AI Connectors (with graceful fallback for WordPress 6.2+).

= 0.210.0 =
* Fixed input sanitization and output escaping across admin screens.
* Added translator comments for all strings with placeholders.
