== Changelog ==

The complete history. The most recent releases are also in readme.txt;
everything is here, oldest at the bottom.

= 1.3.3 =
* A body sent by a connected app is narrowed before it becomes a post. The helper that turns HTML into blocks returns anything already carrying a block delimiter exactly as it arrived — right for markup this plugin wrote and reads back, wrong for markup that came from somewhere else, because a body merely beginning with one went into the post whole. The same helper was already being given narrowed input everywhere else it is used
* This is not a way in that was otherwise shut: the account behind a connection token belongs to somebody who can already publish. It matters because of where the words come from. They are written by a language model, and this plugin hands that model pages it fetched off the open web — so trusting the connection is not the same as trusting the text arriving over it, and the page that renders it is every reader's
* A test sends a script tag, an event attribute, a javascript: link and an iframe behind a block delimiter, and requires all four to be gone and the writing around them to survive

= 1.3.2 =
* Addresses the plugin did not choose are now fetched the careful way. Two were not: the research list typed into a settings field, and the results a search service hands back, which nobody on this site picked at all. Both went through the call that follows whatever it is handed — including to this server's own network, or to a cloud provider's metadata address. The voice reader had used the careful call for the same kind of input all along
* A page fetched from outside is now read only up to two megabytes. All that is wanted from one is its headings and an excerpt, both of which arrive early, and without a cap a page answering with a gigabyte is read into memory in full — and the request that dies of it is somebody's post
* The provider call deliberately keeps the plain fetch, because Ollama, LM Studio, Jan and llama.cpp all answer on localhost and the careful call refuses loopback. A test records that reason alongside the three other exemptions, so the next person to tidy this does not quietly break every local model
* The translation catalogue still announced itself as "Blogcraft" and declared the old text domain. The rename updated the filename and the scanner but not the header inside it, which is the part a translation tool actually reads. Both now come from the same constant as everything else

= 1.3.1 =
* Every AI provider now carries its own terms and privacy links. Ten of them — xAI, Moonshot, DeepSeek, Groq, OpenRouter, Mistral, Together, Fireworks, Cerebras and Hugging Face — were listed on one shared line saying the policies vary and to check whichever you pick. The directory asks for links per service, and that line had none
* Each entry also names the address it actually contacts, so what the plugin reaches and what the readme claims can be compared without reading the code
* Two picture services publish policy pages that are served to people but refuse automated readers. Both are now marked as such, the way fal.ai already was, because an automated link check reports a failure for a page that is genuinely there
* The self-hosted options — SearXNG, Ollama, LM Studio, Jan, llama.cpp and a custom endpoint — say plainly that the address is yours and reaches no third party, rather than being listed with nothing beside them
* Giving every service its own links pushed the section past the 5,000 characters the readme parser keeps, which would have cut the last services back off. It is written tighter and fits, and a test holds it there
* A test compares the readme against the code and the provider list: an address the plugin can reach and does not disclose fails, and so does a service named without either a policy link or a stated reason there is none
* Said why the two base64 calls in the key encryption are there. Both were suppressed warnings with no explanation beside them, which reads worse than the thing it was hiding

= 1.3.0 =
* Fixed: on a site whose theme adds its own article structured data, every post went out carrying two copies of it that described the same page and disagreed with each other. Two is worth less to a search engine than one, and nothing on any screen said it was happening
* The plugin already stood down for the SEO plugins it could name, because each announces itself. A theme announces nothing, so no list could ever have caught this. It is now answered by looking: the site reads one of its own published posts and counts what is actually in the page
* The overview says so when it finds a second copy, and names the switch that stops it. If both copies come from elsewhere it says that too, rather than pointing at a switch that would not help
* New setting, "Add search-engine structured data to each post", on by default. Off is for the sites whose theme already does it, which is the one case where adding ours makes the page worse
* The stand-down list knows ten SEO plugins instead of four: The SEO Framework, Slim SEO, Squirrly, SEO Simple Pack, Schema Pro and Schema & Structured Data for WP have joined Yoast, Rank Math, All In One SEO and SEOPress
* The form test introduced last release checked four screens because those were the four the bug was found on. It now checks all ten that draw a form, with rows on the screens that list things, so the forms drawn once per row are checked too

= 1.2.0 =
* Fixed, and this is the important one: the Settings screen could not save anything, and pressing "Save settings" switched how the site writes instead. The screen wrapped everything in one form and then drew nine more inside it — the mode switch, issuing a token, disconnecting an app, testing a key, saving a provider. HTML has no nested form, so the browser ended the settings form at the first of those and around seventy controls after it belonged to nothing. The only fields left inside were the mode switch's, which is what Save was submitting
* This is why pictures could not be switched on, why research stayed off, why the voice never saved and why "Delete all of it instead" never stuck. It was not those settings; it was the form around them
* The settings form is now a short element of its own and every setting names it, which is what the save button in the corner has always done. The other nine forms are ordinary siblings and work as they read
* A test renders every screen on every setup and fails if any form opens inside another, or if any setting is left in no form at all

= 1.1.0 =
* The comparison of the two ways is a table as well as two cards: thirteen rows in plain words, answering the questions people actually ask. Can it put a picture on the post, do the pictures cost anything, will it write while you are away, what does each post cost, what do you need before it works
* Fixed: the two cards stacked instead of sitting side by side. The panel around them is a row, so the fold had been sized to the width of its own heading and the columns inside had nowhere to go
* Every screen says which way this site is running — API mode or MCP mode — at the end of the tabs, and it leads to the switch. The two behave differently enough that "why is there no Calendar" should not need looking up
* A test holds the table to what the code does, because a wrong Yes in a comparison is worse than no comparison

= 1.0.0 =
* The two ways of running this can be compared after you have picked one. Both were laid out side by side while the question was open and never again, so anybody wondering whether the other suited them better had a switch button and nothing to weigh it against. It is folded under the switch on Settings, and it is the same list the question uses rather than a second one to keep in step
* "Change" on the overview lands on the switch and the comparison beside it, instead of the top of a long screen

= 0.99.0 =
* Every job on the Activity screen opens now, the number and the topic both. Only jobs still moving were clickable, so a finished one — the one worth opening, because it has a score, a list of what failed and a post at the end of it — could be reached from nowhere
* Opening a finished job shows what it scored, every check it passed and failed, and a way through to the post it wrote. Before this the screen rendered an outcome only for a draft held for review, so a completed job showed twelve unticked steps and the word "Working" over a post written days earlier
* Each failing check now says what to do about it. The scorecard has always worked that out and the connected apps have always been told; the screen a person reads showed the number it got and the number it wanted, and left them to infer the rest
* A job that has stopped is no longer polled every two seconds or described as working

= 0.98.0 =
* Fixed properly: the old Help address still answered "Sorry, you are not allowed to access this page". The fix in 0.93.0 registered the page and then removed it from the menu, which also removes the entry WordPress reads to work out who may open it — so the page stayed refused, and the test written for it checked the source code rather than opening the page. It is registered under a hidden parent now, and the test asks the function that does the refusing

= 0.97.0 =
* How it writes marks every section nobody has been into yet with a quiet "default", so you can see at a glance which parts of the brief have been answered and which are still the ones the plugin shipped with. Keeping a default is a decision too — this only answers "which of these have I not looked at", which otherwise meant opening all seven and remembering what the defaults were
* A site where none of it has been answered is told so once, at the top, with the reason: every post is written to this brief, and it is the difference between a post that sounds like your blog and one that sounds like every other AI post
* "Before you write" on the Write a post screen now lists the writing rules alongside the voice, and says what setting them up buys — a page that answers a real question in a real voice is what search engines reward, and the brief is where you say which
* A test checks every field on the blueprint belongs to exactly one section, so a field added later cannot quietly stop being watched

= 0.96.0 =
* Fixed: pictures could not be switched on at all when an AI client does the writing. The feature worked on that setup — the app asks this site for the pictures and publishing attaches them — but the card that switches them on was shown only to sites using an API key. So the composer offered to describe a picture, the tool answered "the owner turns them on under Settings", and there was no card there to turn them on with
* Fixed: "Set them up" on the Write a post screen went to Settings for both things it listed, and the voice moved to How it writes some releases ago. Each now links to the screen that actually holds it
* Fixed: that panel also offered to set up research on the client path, where an application brings its own and the settings screen carries no research card to arrive at. Same for the prompt inside the confirmation
* The line saying what a post will be no longer claims to know whether it was written from current sources when an app did the writing. That is the app's business and this site cannot see it
* A new test walks every screen on both setups and checks that each link lands on a screen that exists and an anchor that is actually there. It found three of the faults above

= 0.95.0 =
* Fixed: "What you will get" listed a featured image on every site, whether or not the picture service was switched on. It was reading the blueprint asking for a picture and never the setting that decides whether one can be fetched — so the one panel whose whole job is to say what the post will be was wrong about the most visible thing on it. It now says "No featured image, pictures are switched off" instead of quietly promising one
* The confirmation before writing ends with a line saying what the post will actually come out as: roughly how long, whether it has sources to read or is writing from memory, whether there will be pictures, and where it lands. Three of those four are settings on other screens, and nobody should have to remember whether they switched pictures on before agreeing to write a post

= 0.94.0 =
* Fixed: a post published by hand got none of the finishing. The featured image, the pictures under each heading, the links from older posts, the search title and description, and the ping to the search engines all happened inside the call that published it — so following this plugin's own advice, reading the draft and pressing Publish yourself, produced a barer post than asking your app to publish. It now finishes whichever way it goes live, and never twice
* The confirmation before writing is quicker to read: one line instead of a paragraph arguing for itself, two headings said rather than shouted, and the ten things a post can include laid out in two columns so the buttons are no longer below the fold
* That panel keeps the keyboard inside it now. Tab used to walk out into the form behind, which is still there and still fillable, so it was possible to type into a screen you could not see. Closing it puts you back where you were
* Fixed: on a phone, the panel's "Back to the brief" button folded into four stacked words. Both buttons take the full width there
* Note: pictures still need switching on under Settings before anything can add one, whichever way a post is published

= 0.93.0 =
* Fixed: four links to the documentation opened in the same tab, so following one while setting something up threw away the form you were filling in. Anything that leaves your own admin now opens a new tab, decided from the address rather than remembered link by link
* Fixed: the old Help address answered with "Sorry, you are not allowed to access this page" — WordPress's message for a permissions problem, on a page that had simply moved. It now says where the documentation went and offers a way there, for anyone who bookmarked it
* The section switcher on How it writes is a real set of tabs: it says which panel each one opens, and the arrow keys, Home and End move between them. It said which section was current before, but nothing said the buttons controlled anything, and most of the form is behind them
* Activity records what a connected app does. Drafts created, posts published or scheduled, and anything held back for scoring below your threshold — the screen that answers "what has this been doing" could not answer it at all on a site where an app does the writing
* The list of pipeline jobs is not shown on that path when there are none, rather than an empty table describing a queue that setup does not use

= 0.92.0 =
* The documentation is one page on the web rather than a copy inside the plugin and another on the website. Every help control opens the section for the control you were looking at, in a new tab, so a half-filled form is not lost to go and read about it
* The Help screen and the "How this works" panel on every settings card are gone. They were a second copy of every explanation, and it was always the older one: correcting a sentence meant shipping a release
* Requires a connection, which the shipped copy did not. That is the trade, and it buys corrections that reach you without an update, screenshots and worked examples that never fitted in an admin panel, and one copy to be right
* Smaller by about 34,000 characters of shipped text: the stylesheet lost the screen it dressed, and translators have 145 fewer strings to carry
* The four setup steps on the overview no longer fold away behind a control. Four lines and a button each is not something to hide

= 0.91.0 =
* The overview says when nothing is allowed to come and read what you publish. A post can be right in every way this plugin measures and still be invisible, and both settings that decide it live outside the plugin: WordPress's own "Discourage search engines", which is on by default on most staging sites and travels to production with the database, and a robots.txt that refuses the AI crawlers
* It names the assistants rather than the crawlers — "Perplexity", not "PerplexityBot" — because which assistant will not be citing you is the question somebody actually has. Nothing is changed on your behalf: both settings are legitimate choices and the plugin only says what they cost
* The line stays quiet when there is nothing to say, and reads as confirmation rather than a warning on a staging site, where discouraging search engines is the correct setting
* Fixed: the Questions and answers section still promised it would appear as its own search result. Google retired FAQ rich results for every site in May 2026. The section is still worth writing and the markup is still emitted, but for what it is worth to a reader rather than a result the plugin can no longer promise

= 0.90.0 =
* Fixed: a post written by a connected app was never given the score it had just been measured against, so the library, the overview and the activity screen listed everything Claude or ChatGPT wrote as "not scored" however many times it had been checked. The score is now kept when a draft is checked and when it is published, including when publishing is refused — which is the one time you go looking for it
* Fixed: every brief handed to a connected app claimed the length, the section count, the sentence limit and the link target had been chosen specially for that post. Nothing had been chosen: the form sends text, the standing rules hold numbers, and the two were compared strictly, so 2000 and "2000" counted as a change
* The byline and the publishing time on Write a post are applied instead of ignored. Both were saved with the brief and then read by nothing at all — an app has no parameter for either, so this site sets them itself
* Queueing a list of topics and pushing the queue along are no longer offered when an AI client does the writing. There is no provider on that setup, so a queued list waited for something that was never coming while the screen reported it as queued. Both endpoints refuse it too, rather than only being hidden
* Undoing a batch stays on both paths, because it works off the mark this plugin puts on posts it wrote and an app's posts carry it too
* The confirmation step says "Save this brief" where that is what pressing it does, rather than "Write it now" on the one setup where it writes nothing
* Fixed: the Settings strip read "Writing , Claude" when a token issued by hand sat beside a signed-in app, because the token had no name and the empty name was still joined into the list

= 0.89.0 =
* The connected apps list says whether each one is Active, Idle or Never used, with a dot beside the word. A date told you when something last called and left you to work out whether that meant it was still working

= 0.88.0 =
* You can pick the model for one post without changing the setting for every other one. It sits with the category and the publishing date, and offers whatever your site already knows about rather than asking you to type a name from memory
* The strip at the top of Settings says what is actually in use — which provider and model, what it may read, where pictures come from, how often it writes — rather than only that something is set up
* Removed three controls from Write a post that could not do anything when an AI client does the writing: asking the provider what to write when there is no provider, choosing whether to publish when nothing here publishes, and an estimate of a bill that goes to a subscription instead of to you
* A test now holds the rule in both directions, so a control cannot go missing from the path it belongs to either

= 0.87.0 =
* Connected apps are listed one row each, saying whether the app signed itself in or is using a token you issued, when it connected, and when it was last heard from
* Fixed: signing an app in stores two credentials, one to call with and one to renew with, and the old list showed both — so a single app appeared twice, the second row claiming it had never been used. Revoking from that list was worse than useless: take the first and the app renews itself straight back in, take the second and nothing appears to happen
* Disconnect now ends the connection and everything behind it
* The list of apps is a list rather than four buttons across the card, each row naming what that app needs from you

= 0.86.0 =
* Every point raised by the WordPress plugin review, fixed against the current code. The security checks were always being made, but through a helper one call away, so each one carried a note telling the code checker to ignore it — and the review read those notes and called it a fault. Thirty-one places now use WordPress’s own check, with the permission test beside it, and seventy-three of those notes are gone because nothing needs excusing
* Two of them were not false alarms: a pair of internal functions read submitted data on the strength of a check made by whatever called them, with nothing at those lines saying so. Both check for themselves now
* Submitted data is cleaned where it arrives rather than several steps later, with the right function for each kind — including the one that keeps a draft’s formatting intact
* Fixed two addresses that did not answer: the plugin’s own page, which is not written yet, and one image service that refuses automated requests on every page it has

= 0.85.0 =
* The sentence to say in your app has moved to where it is useful. It was a standing panel at the top of Write a post explaining what to do once you had saved a brief, sitting above the form that saves it — backwards, and unchanging, so after the second visit it was five lines of furniture. It appears once there is a brief to say it about
* The warning that no app is connected stays at the top, and only when it is true

= 0.84.0 =
* Housekeeping after the voice fix: one step layout was built from a different element than the two beside it, and the note explaining a list of duplicate style rules described deliberate work as something still to be sorted out. Neither changed how anything behaves

= 0.83.0 =
* Fixed: your voice was described in two places and the model was told both. Settings had a Describe your voice card, How it writes had a Voice tab, and they were not two views of one thing — they were two stores, and every request carried two versions of the tone, the reader, the point of view, the reading level, the banned words and the subjects to avoid. Fill in one and the model got two answers to the same question
* How it writes now owns all of it. What the blog is about, your style rules and your own experience have moved onto its Voice tab, along with the Learn from my posts button. Nothing you had typed is lost — it is carried over the first time you open the screen
* The Settings card is now a line pointing at where the voice lives

= 0.82.0 =
* Write a post keeps its whole form when an AI client does the writing. It had been cut down to a single sentence to copy, which threw away the topic field, the angle, the box for what only you know, and every per-post choice — the things that make a post yours rather than generic. Fill it in as before and press Save this brief
* Your connected app collects that brief the moment you ask it to write: the topic, the angle, your own figures, and any choice you changed for this post. It is the same brief the plugin would have written from
* Only the choices that differ from your standing rules are passed along. A brief that repeats every setting is one nothing reads to the end of
* The screen says when no app is connected, because without one the form is a wait that never ends

= 0.81.0 =
* Every screen now knows which of the two ways this site is set up. A site driven by Claude was still offered a Write a post screen that calls a provider it has no key for, and a Calendar for scheduled writing that cannot happen on that path — both failing at the moment somebody tried them, which is the worst place to find out. They are no longer offered, and following an old link to one explains what changed instead of showing a form that cannot be submitted
* The overview says which way the site writes, and its setup checklist asks for the right things. It used to tell somebody who had chosen an AI client to go and add an API key, which is telling them to undo the choice they just made
* Fixed: the preview outline on the write screen and the shape buttons on the blueprint screen shared one class name, so every style rule for either landed on both. It only looked right because of which block came last in the stylesheet
* Fixed: a Windows checkout rewrote every file to Windows line endings, which fails the coding standard on the first line of each. The same code passed and then failed without a line of it changing

= 0.80.0 =
* The shape your writing rules were started from stays marked. Pressing one fills in about twenty fields and marked the card it came from, but nothing wrote that down — so the next visit showed eight identical cards with no sign of which one built the rules in front of you
* Removed the one direct database query in the uninstaller. The running token totals it existed to sweep up are held as transients now, which expire on their own, so there is nothing left to sweep

= 0.79.0 =
* You can keep more than one provider set up and switch between them. The settings held exactly one, so comparing a cheap model against a good one, or a paid account against a local model that costs nothing, meant retyping the whole card and pasting the key back in from wherever you keep it. Most people did that once and never went back
* Name a setup, save it, and it is one button to return to. The key is stored encrypted the same way the live one is, and switching carries the whole setup — including the request shape a custom endpoint needs, which restored without it fails in a way that reads like a bad key
* Ten setups are kept. Past that the oldest goes
* A test now asserts that every provider setting is one a saved setup carries, so a setting added later cannot be silently dropped on every switch

= 0.78.0 =
* The Write a post screen is a screen you fill in, not one you read. Every field on it carried a paragraph explaining itself and several carried two — the explanation for the evidence box ran to three sentences, and the topic field had two separate paragraphs above and below it. One line each now
* That page links to the documentation, which it never did. The detail that came off the screen is there rather than gone
* Shorter wording on the research and voice prompts too, and on the settings card that explains research

= 0.77.0 =
* Every post now says what wrote it: the provider, the model, the tokens in and out, and the score. A panel on the post itself. The numbers were already being handed over on every reply and thrown away — the month total could say thirteen thousand tokens and nothing could say which post spent them, or which model wrote any given piece
* A post written from Claude or ChatGPT says so instead, and says nothing was billed here, because the model ran on their subscription
* Fixed: the AI client card still listed pictures among the things a connected app cannot use. It has been able to since the last release
* Shorter wording again across the connect card and the chooser

= 0.76.0 =
* A post written from Claude or ChatGPT is now finished the way every other post here is: a featured image, pictures under the headings, the search title, the category and tags, links added from older posts pointing at the new one, and a submission to the search engines that accept one. It used to go out with none of that — a draft that happened to be public
* A draft can be listed and read back, so a conversation that ended half way through picks the post up instead of writing it again
* Drafts can be scored by id rather than by pasting the text back, which also scores the pictures and everything else added since
* Publishing can be scheduled for a date instead of going out now
* Three new things a connected app can do: list your drafts, read one back, and add pictures before you publish
* Fixed: scheduling silently published immediately. WordPress ignores a new date on an update unless it is told the date is deliberate, and the call reported success either way, so the only sign was a post that went out early
* Less text on the settings screen, and the detail moved to the documentation each card already links to

= 0.75.0 =
* The connect card asks which app you are using and then shows the steps for that one. It used to print a general four-step list and, underneath it, a different set of steps for every app it knows about, all at once — which is not thoroughness, it is a question about which list you are meant to be following
* Fewer words on every step, and the address sits on its own with a button rather than inside a numbered instruction to copy it
* Your choice of app is remembered, so coming back to check a step does not mean picking it again

= 0.74.0 =
* You can now sign an app in, instead of copying a token into it. Paste the address, approve the connection on your own site, and that is the whole of it. This is what Claude and ChatGPT have always needed: their connector dialogs have no field for a request header, so they ask the site where to sign in, and this site had nowhere to point them. That is why it answered "couldn't connect to the server" no matter what the address was
* The approval screen says what a connected app will be able to do and, just as plainly, what it will not — it cannot touch a post it did not write, write anything while you are away, or read your settings and keys
* Tokens still work and still never expire, for editors and machines that would rather use one. Signing in is what the apps that cannot use a token now do instead
* Copy buttons on the address, the token and the command. Each of those has to arrive in another window exactly right, and losing the last character of an address produces an error that blames the server
* Step by step for each app, in the order you do them, rather than a paragraph describing the arrangement
* The result of the connection test stays on the screen until you dismiss it. It used to vanish on the next page load, which is the worst possible behaviour for the one message that explains a failure
* Says so when this site is on plain permalinks, which is the one setting that stops signing in from working, and links straight to the setting
* Fixed: deleting the plugin left the list of connected apps behind. The check that should have caught that only recognised a stored value if it had been given a particular sort of name, which is no check at all — it looks at what is stored now

= 0.73.0 =
* Fixed: no AI client could connect. The server answered every question a client asks except the one it asks before all the others. It was built against a draft of the protocol that renames the opening handshake, and no shipping application uses that name — so Claude, ChatGPT and the rest got as far as "couldn't connect to the server" and stopped. The handshake every client actually sends is answered now, and the old name still works
* Fixed: asking for the optional event stream returned "no route here" rather than "not that method". A client reads the first as proof there is no server at the address and gives up before it sends anything
* Fixed: a protocol version the site did not recognise had the whole request refused, which leaves the client nowhere to go. The version is negotiated now, and four revisions are accepted
* Fixed: the notification a client sends immediately after connecting was answered as though it were a question, which is a protocol error on our side
* The settings screen opens by asking how you want to write, with what each way includes and what it rules out, side by side. Choosing shows the settings for that way and hides the ones that would do nothing. The way back is on the screen from then on, and switching deletes nothing
* Fixed: the jump list beside the settings disagreed with the cards it pointed at, so step 02 in the list was step 03 on the screen. The list and the cards are one list now
* Choosing the AI client is honoured rather than described: scheduled writing does not run on that path, which is what the screen has always said about it

= 0.72.0 =
* Connecting an app is one button now. It used to be: tick a box, save the page, come back, find the controls that had appeared, then issue a token. Everything is on the card from the first visit, and issuing a token is what switches connections on — pressing that button is not an ambiguous statement of intent
* Issuing a token also tests it. The site calls its own address exactly as an app will and reports what came back, so a server that strips the Authorization header or blocks the REST API says so here rather than leaving you with an app that only says it could not connect
* The card names the exact options each app needs. Claude Desktop offers four ways to authenticate and three OAuth arrangements, and the one it picks by itself fails with a message about registering an OAuth client that does not say what to choose instead. Set Authentication to None and add the Authorization header; the card says so, and warns about the option that fails
* Step by step rather than three paragraphs, with the address to copy in the step that asks you to copy it, and "How this works" going to the instructions rather than unfolding a summary of them

= 0.71.0 =
* A second way to supply a model, for anyone already paying for Claude, ChatGPT or a similar app. Instead of this site calling a provider with your key, the app connects to this site and does the writing, while the writing rules, the twenty-five checks and the publishing stay here. No API key, and nothing leaves your site: the connection comes in
* Settings, Connect an AI client. Switch it on, issue a token, and paste the address and the token into whatever you use. It speaks the Model Context Protocol, so it is not tied to one app
* A connected client can read your rules, score a draft against every check, create and revise drafts, and publish — but only above the quality threshold you set, exactly as a post written here would have to be. It cannot write on a schedule, touch a post it did not create, or reach your research and picture services. Scheduled writing still needs a provider key, because something has to be running when nobody is watching
* Tokens are shown once and stored only as a fingerprint. One stops working the moment the person it was issued to loses permission to write here, so a token cannot outlive the account behind it

= 0.70.0 =
* The plugin puts nothing in the dashboard notice area at all. The one notice it had — a warning that the queue has stalled — was already capability-gated, shown only on this plugin's own screens, dismissible and switchable off, which guideline 11 permits. But that space belongs to the whole dashboard, and the surest way not to misuse it is not to occupy it. The warning is drawn as part of our own page instead, under the navigation
* It also says how to fix the thing it is warning about, which the guideline asks for and a dismiss link on its own does not do: the first link now goes to the automation instructions, and dismissing is the second

= 0.69.0 =
* The admin menu says "AI Blog Writer" rather than the full plugin name. The sidebar column is about 160px wide, so the whole name wrapped onto two lines and knocked every item below it out of alignment. add_menu_page takes the browser title and the sidebar label separately, and only the readme heading and the Plugin Name header are required to agree

= 0.68.0 =
* The old name is out of the interface as well as the header. Renaming the plugin left the previous name on every screen, in the WP-CLI commands, and in the User-Agent sent to every research service — which is where somebody would actually have read it. Thirty-four strings, four commands and the request header now carry the real name
* The documentation address no longer contains the old term either. The review named URLs specifically, and a link on the author's own domain still spells out a name that belongs to somebody else
* readme.txt names where development happens, which guideline 4 asks for: the source ships in full, but the build scripts do not, so the repository is linked
* Trimmed two paragraphs of argument out of External Services. That section had crossed the 5,000-character ceiling and would have been truncated on the listing — the same fault as the changelog, one section along, and the test only covered the changelog. It covers every section now

= 0.67.0 =
* Renamed to Dicecodes AI Blog Writer, slug dicecodes-ai-blog-writer. The directory review flagged "Blogcraft" as a term belonging to somebody else in the same field, and a name that could be read as another company's is worth losing however good it sounded. The author's own brand goes at the front, which is the pattern the directory asks for
* The text domain follows the slug, as it must. Nothing that identifies stored data moved: the option names, the capability, the admin addresses and the class names are unchanged, so an existing install keeps its settings and its record of every post written

= 0.66.0 =
* uninstall.php could run outside an uninstall. Its guard accepted WP_UNINSTALL_PLUGIN or ABSPATH, and ABSPATH is defined on every WordPress request — so the second half was always true and the file would execute wherever it was reached. Only the constant that means "WordPress is deleting this plugin" is accepted now
* The author box stylesheet is enqueued rather than printed. It echoed a <style> block into wp_head, which works but is invisible to everything else: no other plugin or theme could dequeue it, reorder it, or even see it was there. It is registered as a handle carrying inline rules, which costs the same number of requests, namely none
* The structured-data block no longer passes JSON_UNESCAPED_SLASHES, which is what would have let a literal </script> reach the page, and adds JSON_HEX_TAG so angle brackets cannot either. The suppression comment that sat beside it was silencing a warning that had something to say
* Nine places printed assembled markup behind a comment asserting it was already escaped. Every comment was accurate, and that is the problem: the safety held only while each helper stayed correct, and nobody could tell a true claim from a false one without reading the helper. They run through wp_kses against a fixed tag list now, so it is enforced rather than asserted
* The SerpApi privacy link was a 404. Both of their documents live on one page under anchors, which is where it points now
* Every external service in the readme names the host it actually contacts, so somebody reading a firewall log can match what they see against the list

= 0.65.0 =
* The plugin is now called Blogcraft AI Writer, and its text domain is blogcraft-ai-writer to match. wordpress.org generates the directory slug from the plugin name and will not change it afterwards, and the text domain has to equal that slug or the translations the directory builds never load — which is the same failure as shipping no translations at all
* Nothing that identifies your data moved. The option names, the capability, the admin addresses and the class names are all unchanged, so an existing install keeps every setting, blueprint and record of what it has written

= 0.64.0 =
* No provider is chosen for you. The setting defaulted to OpenAI, so a plugin whose whole point is that you bring your own key opened with somebody else's company already selected — a paid, card-first one, sitting above every route that costs nothing. The list now starts on "Choose a provider" and waits
* The Help screen is written to be scanned rather than read. It was twelve sections of four to seven full paragraphs, which is an essay about the plugin rather than instructions for using it. Each section now opens with one sentence and breaks into numbered steps or short lines, and a "Start here" section at the top gives the five steps in order

= 0.63.0 =
* The provider list is grouped by what it costs, free routes first. Every label already said free or paid, but in a flat list of nineteen that only helped somebody who read all nineteen — and the two at the top of it both want a card before they will answer anything
* Three more ways to spend nothing: Jan and llama.cpp join Ollama and LM Studio as models that run on your own machine with no key, and Hugging Face joins Google, Groq and Mistral as a hosted free tier. All three were reachable before through the custom endpoint, which is no use to anybody who does not already know their runtime speaks that protocol
* The Help screen's contents moved to a rail beside the writing, and now marks the section you are reading. It was a stack of twelve bare links between the heading and the first section, because the screen loaded neither the stylesheet nor the script the rest of the plugin uses

= 0.62.0 =
* The documentation link now appears on the overview, the last screen of the introduction, the wordpress.org listing and its FAQ, and three more places in the README
* Every one of those addresses comes from one place now. The plugins row wrote it out itself, so there were two copies of one URL in two files — which is how a link comes to 404 while its twin still works
* The plugin header pointed at the same page without a trailing slash, so the one address WordPress displays was a redirect rather than the address

= 0.61.0 =
* A documentation site at https://dicecodes.com/blogcraft/ — one self-contained HTML file with no CDN, no web fonts and no external request of any kind, built on the plugin's own palette and type scale
* Its section anchors are the same slugs the plugin already uses, so every "How this works" panel offers the shipped documentation and the online guide side by side, each deep-linked to the matching section
* That page was then audited against the same on-page rules the plugin applies to posts, and six of fourteen failed. The title was 82 characters and opened with the word "documentation"; the description never contained "AI writer" at all; and a page carrying fifteen questions had no structured data on it. It has three schema blocks now, with the FAQ generated from the visible answers rather than written a second time

= 0.60.0 =
* The README and the branding inside WordPress brought into line with the house style used by Open WP Migration, so somebody arriving at either plugin recognises the second
* The plugins row now offers Docs beside Set up and Settings, and the Help screen links out to the guides and to the issue tracker — kept clearly separate from the shipped documentation above them, which is always true of the version you have installed in a way an online page cannot be

= 0.59.0 =
* Two scoring bugs found by writing a real post end to end and reading the result. Neither was reachable from a unit test
* The section count was counting the plugin's own headings. Key takeaways, the questions, the numbers, the mistakes and the sources are all h2, so a post asked for two sections and written to exactly two was marked down for having four — on the heaviest check in the scorecard, on every post with any block switched on
* Figures you supplied yourself were counted as unsupported claims. The evidence field is the one the plugin weighs most heavily, and stating your own measurement cost eight points because there was no link beside it. There is nothing to link to; it is your number
* A README, which the repository did not have. Two scraped research files that should never have been committed are gone with it
* The display name is now "Blogcraft – AI Writer & SEO Content Generator". The slug, the folder name and the text domain are unchanged, so no existing install is affected

= 0.58.0 =
* Stopped asking the database to exclude a post. "exclude" in get_posts() becomes a NOT IN, which stops MySQL using its index on a table that only ever grows — and the check using it was already looping over every row it got back, so the exclusion bought a worse query plan to save an if statement

= 0.57.0 =
* Five on-page rules that the current guides all state and this plugin did not measure. The subject has to arrive in the first hundred words, early in the title rather than merely somewhere in it, in the address, and in the search-result line
* The address check carries no repair note, deliberately. The slug is decided at the outline and a rewrite cannot reach it
* Google asks, in as many words, that automation be disclosed: that it was used, how, and why that helped the reader. There is now a line in the byline saying so, on by default, with wording you can change or switch off

= 0.56.0 =
* A type scale, and spacing that lands on a grid. The stylesheets held sixteen distinct font sizes, three of them half a pixel, and sixteen off-grid spacing values. Each is invisible on its own; together they are why nothing quite lined up with anything else
* Seven sizes now, each with a job, and 172 spacing values snapped to a four-pixel grid. Three tests hold it: no hand-written font size, no spacing off the grid, and every step of the scale a multiple of four

= 0.55.0 =
* Four buttons asked a provider without checking there was one. On a fresh install, "Show the models on my account", "Learn from my posts", "Read this article" and "Suggest a topic" all returned whatever the HTTP layer said — "Request failed with HTTP 401", which is true, tells nobody what to do, and is indistinguishable from a broken plugin. One refusal now, in one place, naming the screen to go to

= 0.54.0 =
* Four prompts were handed your own material and dropped it. The pipeline sets the evidence before seven stages and four of those prompts never emitted it, which looks like working code at every call site because the call site is right
* Worst of the four was the rewrite. A pass told to cut forty words could paraphrase "three of nine were returned" into "some were returned" and nothing noticed — the heaviest check on the finished post being quietly undone by the pass meant to improve it
* The outline was among them, so the shape of the post was decided before your own material was in the room
* The provider card asks for the key before the model. It asked for the model id above the field that makes a model list possible, so on a fresh install the only thing "Show the models on my account" could do was fail — which leaves typing an id from memory as the path of least resistance, and a retired id is a setup that looks finished and errors on the first post

= 0.53.0 =
* Deleting the plugin no longer deletes everything it stored. Your settings, your writing rules and the record of every post it wrote stay where they are. Install it again and it is as you left it
* There is a box on the settings screen if you do want it all gone, and the warning that ticking it is the only confirmation there will be
* Posts are never touched either way. They are ordinary WordPress posts from the moment they are created
* The PHP matrix ran 7.4 through 8.5 and proved only that the code parses, because php -l exits 0 on a deprecation. Anything PHP has to say about a file now fails the build, which is what makes the 8.4 and 8.5 columns worth having

= 0.52.0 =
* Installing this plugin twice made it refuse to switch on. Two copies in wp-content/plugins is a fatal error, because PHP will not declare the same class twice, and WordPress rolls the activation back — which is correct and explains nothing. The second copy now stands aside and says which folder it is in, so there is something to delete

= 0.51.0 =
* The panel asking what a post will include shipped, rendered, and never opened. Its listener was appended to a file holding several immediately-invoked functions and landed in the last one, which owns a different control, so it threw before it could attach and pressing Write did what it always had
* That panel now opens with what has never been decided: whether anybody has said who the blog is for, whether the writing rules are still the shipped defaults, whether there is anything to read but the model's own memory, and whether this post carries anything only its author knows. None of it blocks — "Write it now" sits under every one of them

= 0.50.0 =
* The undo the review screen promised now exists. It said a rewrite that made things worse could be undone because "the earlier wording is in the editor history" — but a held draft has no post, so it has no history, and the sentence was simply untrue on the one screen whose whole job is being honest about a draft's state. The article, its score and its checks are kept before a pass and put back on request, with no second provider call

= 0.49.0 =
* A finished job was described as broken. The Activity table kept whatever went wrong on an earlier attempt, so a post that worked and is on the site carried a red error beside "Complete"
* Scores in the library are coloured against your threshold rather than left as bare numbers, and post status is a badge like every other table in the plugin
* The first step of the introduction was a one-way door: it asked you to go and set up a provider, then left you to find your way back to a page you had been looking at for ten seconds. The trip is marked now, and settings shows a way back while it lasts

= 0.48.0 =
* Pressing Write opens a panel listing the ten parts a post can be built from, each with a sentence on what it is for and each switchable for this post alone. It appears every time until you tick "Stop asking me this"
* Sources is the reason it exists. It was on every post because it defaults on and had no control anywhere on the write screen, so the first anybody learned of a Sources block was finding one at the bottom of a finished draft. Four other extras were in the same position
* Turning Sources off no longer costs marks. It is the only place a real external link comes from, since every drafting prompt forbids the model from writing markup, so the citation check is skipped rather than failed

= 0.47.0 =
* The review screen offers one more writing pass aimed at the faults it has just listed, and shows the new score against the old one — including when it goes down, which happens
* It will not charge for a pass that cannot change anything. "Internal links: 1, wanted 3" means the site has nothing else on the subject to point at, and no rewrite invents three related posts. Where nothing failing carries an instruction, no request is made and nobody is billed for one
* A new panel answers the narrower question of what is working against a post that can actually be checked here: whether it duplicates something you already have, whether it says anything only yours, whether anything on the site points at it, and whether it is shorter than the question deserves. It does not predict a position, and a test asserts no line ever claims to

= 0.46.0 =
* Every draft on the library screen was labelled "2028 years ago". post_date_gmt is only filled once a post is scheduled or published, so every draft this plugin writes carries 0000-00-00, which reads as the year zero
* The held-draft step list showed "Creating the post" not done with the two steps after it ticked. Naming publish alone was right only while publish was the last step
* The Write screen's outcome and readiness panels were separate children of one grid, so the second wrapped underneath the tab panels — a screen away from the fields it describes
* Removed load_plugin_textdomain(), which Plugin Check flags. It has been unnecessary for wordpress.org-hosted plugins since WordPress 4.6

= 0.45.0 =
* The job that stuck on "Creating the post". Publishing inserted the post and then, in the same request, downloaded four pictures, rewrote three older posts and told a crawler — against the one rule the pipeline is built on, that no stage may outlast PHP's execution limit on ordinary hosting. Pictures are their own stage now, one per run, and the linking is a stage after that. Neither may fail the job
* The clock restarted on refresh. It counted from when the page loaded, so refreshing a post that had been writing for four minutes reported nine seconds. It is anchored to the job now
* The progress screen had no menu entry and was reached by an id in the address, so refreshing or closing the tab left a post being written with nothing pointing back at it. The bare address finds whatever is in flight, and Activity links the jobs that have a screen to go to
* A provider request had no timeout, so one that was never going to answer left a half-filled bar for ever
* All In One SEO was detected, deferred to, and then never written to — it keeps its fields in its own table — so an AIOSEO site got neither its fields filled nor Blogcraft's own description printed
* Two full palettes carrying different values for the same roles, sixteen corner radii between three and eighteen pixels, and the Write and Blueprint screens loading no admin.css at all, which is why the navigation on the two screens people use most had no background, no border and no current-tab highlight

= 0.44.0 =
* Three screens had no colours at all. Every colour resolves through custom properties declared on .blogcraft-page, and the progress screen, the library and the welcome screen use .blogcraft-wrap — so on those three every var() fell through to nothing
* The progress screen, the one you sit and watch for several minutes, was capped at 820px, so on a normal monitor two thirds of the display was empty beside a column of ten one-line steps. The draft as it arrives takes the room now and the steps are a rail beside it
* The write screen ended in a red button that trashes a day of posts, with four raw queue counters and a leftover "run the queue now" control beneath it. Those are folded into one section that says what is inside it, and the write button is pinned to the foot of the viewport rather than sitting six tab-panels down

= 0.43.0 =
* An introduction on install. The settings screen has six cards and about forty fields, which is the right shape for adjusting a working setup and the wrong shape for somebody who activated the plugin ninety seconds ago. The new screen asks for the three that decide whether the first post is any good, in order, and says what skipping each one costs
* The outline is held to the number of sections asked for. A real run came back with ten against a ceiling of seven and the finished post was handed to its author with that check marked failed — and every section past the ceiling had also cost a provider call
* In-body pictures were never inserted, and took the whole publish stage down with them. The image block's format string sat in a double-quoted PHP string with its dollars unescaped, so sprintf was handed an unknown specifier and threw, inside a step described as best-effort that was not actually wrapped
* Alt text described the heading instead of the picture. A screen reader announced the heading, then announced the identical sentence again as the image, and came away knowing nothing about what the picture showed either time

= 0.42.0 =
* A key saved for one provider stayed sitting there when the provider was changed, and the field showed its mask — so it claimed a key was saved for a service it had never seen. Keys now record which provider they belong to
* The same key also counted towards setup being complete, so the checklist said "ready", the first post started, and it failed several stages in with an authentication error nothing on any screen explained
* Underneath that was a bigger one: every hosted provider counted as configured with no key at all. The address branch exists for the runtimes that genuinely need none, and every hosted provider has a default address too. What is asked now is whether the provider issues keys at all
* A readiness check on the brief, and a button that turns a topic into four questions only you can answer. It returns questions, never answers — filling in the evidence field would be inventing the one thing the entire quality system leans on being true

= 0.41.0 =
* A paused post looked exactly like a broken one. Hitting a rate limit does the right thing underneath — the job goes back to pending, keeps everything already written, and resumes by itself — but the screens read only "Pending", so working and waiting were indistinguishable and waiting looked broken
* A job whose next run is in the future is reported as waiting, the page stops polling, and it says what happened: the provider is rate limiting, nothing is lost, and roughly when it carries on
* The library grew a "Being written" section listing anything in flight with its step and, if it is paused, until when
* The Write screen says this before you start, since a post is eight to ten separate calls and beginning one into an exhausted quota does not fail at the door — it gets several stages in, spends what those cost, and then parks

= 0.40.0 =
* A "Written by AI" screen. A draft that finished and was never approved existed only as a job row: it had cost real money, it was complete, no post existed for it, and closing the tab made it unreachable
* Discarding a draft cancels the job rather than deleting the row, because that row is the only record the topic was ever written
* The progress screen shows what exists so far — the title as soon as the outline lands, then each planned heading filling in as its section is written. A bar that fills tells you the machine is alive; the headings tell you whether it is writing the post you asked for
* The Discard button could not discard anything. cancel() listed the three job statuses that existed before drafts could be held, so a finished draft fell through the guard and the button silently did nothing

= 0.39.0 =
* The draft is editable before it lands, in the editor you already know, which brings its Add Media button and whatever a stock-photo plugin has put there
* Edited HTML is re-wrapped into real blocks on the way back. The editor returns plain HTML, and saving that on a block-editor site produces one enormous Classic block with nothing individually editable inside it. Anything unrecognised becomes a paragraph rather than being dropped
* The review screen was inheriting a full-bleed admin width, which put "Wanted" against the edge of a monitor and ran the draft at a line length nobody reads a paragraph in. Failed checks are listed first now and the passing ones fold away
* Models emit **bold** despite every prompt forbidding markdown, and nothing converted it, so literal asterisks reached the page. They are converted rather than stripped — the model marked that phrase for a reason

= 0.38.0 =
* Writing a post lands on a screen that drives the pipeline from your browser, one stage per request, showing each step as it completes. Queueing used to answer with "the post will be written in the background", which is true only when WP-Cron fires — and on a staging site it frequently never does, leaving a job at Pending with an empty log, indistinguishable from broken
* When the draft is finished it stops. The prose, the search description, the score against your threshold and every one of the checks are shown before anything touches the site. It becomes a post when you press the button, not before
* Autopilot is unchanged. Unattended writing already has the quality gate and the review queue, so it still publishes on its own
* The content now matches the editor the site actually uses. Block delimiters are HTML comments, so they render identically either way, but in the Classic editor they are visible clutter between every paragraph

= 0.37.0 =
* Translations are now loaded. Every string in the plugin was written to be translatable and the translation file is rebuilt on every release, but nothing ever loaded it, so all of it stayed in English no matter what language the site was in
* A provider asking you to slow down is recognised by its status code rather than by reading its error message. The message is itself translated, so on a site in any other language a rate limit was mistaken for a failure and the post lost one of its three attempts to something that only needed a wait
* Title and description lengths are counted in characters, not bytes. An accent or an em dash cost extra, and a title in Greek, Hindi, Japanese or Arabic hit a sixty-character ceiling at about twenty letters
* Stock opening phrases are caught with a curly apostrophe as well as a straight one — the curly one being what actually gets written
* A banned word is matched as a whole word. "Delve" was flagged inside any longer word that happened to contain it
* Removing a dead link no longer damages a longer live link on the same domain, and if the removal cannot be done safely the log says so instead of reporting success
* API keys can be removed. A blank field means "keep what is saved", correctly, but that left no way to take a key out short of editing the database
* If a key cannot be encrypted — which happens on hosts without PHP's sodium extension — the screen now says so instead of reporting "Settings saved" over a key that was not stored
* The Gemini key travels as a header rather than in the address. In the address it was written into any proxy or server log along the way; the picture route already did this correctly
* Posts are no longer told they are missing an FAQ or key takeaways when the blueprint deliberately switched those off
* Scheduled work re-arms itself if something clears it. Schedules were set once at activation, so a migration, a staging copy or a security plugin could stop the queue with nothing on any screen saying why
* Removed two methods nothing called

= 0.36.0 =
* A byline readers can actually see. The author, reviewer and organisation markup was real and correct and entirely invisible: it spoke to parsers and said nothing to the person reading. Generated posts now end with the author's name, their bio and their profile links, taken from their own WordPress profile rather than from yet another settings field
* Posts are planned around what is already ranking. The pages covering a topic are opened, their section headings read, and the outline aimed at what they leave out — rather than arriving independently at the same shape as everybody else
* Optional IndexNow notification, off unless you switch it on. Bing, Yandex, Seznam and Naver come and look rather than waiting to find the post. Only the address is sent, never the post, and Google has said it does not take part
* Refreshing an existing post is now judged by the same rules that published it. A rewrite was scored by a superseded, older system, so the bar an existing post had to clear to be improved was a different bar, measuring different things — and nobody could tell, because both produced a number out of 100
* A refresh now weaves internal links into the sentences before scoring, as a new post does, instead of only appending a list underneath afterwards
* A post too long to show the model in full is now refused rather than trimmed. The rewrite replaces the whole post, so showing half of one and saving what came back silently deleted the half it never saw — on any post over roughly a thousand words, which is most of what this plugin writes
* The review screen's checks are rewritten after a refresh, so they describe the post as it now stands rather than as it was first written

= 0.35.0 =
* The meta description now reaches the page on sites with no SEO plugin. It was being written for every post, stored, and measured by the quality checks, and then never emitted, because WordPress prints no description tag of its own — so on a bare theme the most carefully checked sentence in the post did nothing at all. Facebook and X sharing tags come with it
* Only for posts Blogcraft wrote, and only when Yoast, Rank Math, SEOPress or All in One SEO is absent. Filling in head tags for the rest of the site is what an SEO plugin is for, and a theme that prints its own can switch these off with a filter
* Questions now come from what people actually search for. SerpApi returns "people also ask" in the same response the research sources arrive in, and it was being discarded while the model was asked to imagine questions instead. Tavily and a self-hosted SearXNG do not return them, so nothing changes there

= 0.34.0 =
* A post is never published twice. Publishing inserts the post and then spends minutes fetching pictures, which was long enough to cross the stale-job cutoff and be reclaimed while still running — and the re-run wrote a second copy. The post is now claimed the moment it exists, in two places that fail differently, and a resumed job finishes the one it already made
* Pictures are no longer re-fetched on a resumed job. Every generating service bills per image, so an interrupted attempt used to be charged for twice
* A job is no longer treated as dead after ten minutes. A single stage can legitimately take longer than that on a slow host — three provider attempts alone can reach four minutes — so reclaiming that early started a second copy of a live job rather than rescuing a stuck one. The window is now an hour, which is past every timeout the plugin permits
* A daily maximum of zero now writes nothing. It used to skip the cap entirely and allow a post every hour, while the calendar read the same zero as one and drew a schedule that would never happen
* The daily counter rolls over in your timezone, not UTC. On a site far from UTC the allowance used to reset in the middle of the working day
* Switching the plugin off now stops the automatic-writing schedule too. Only the queue schedule was being cleared, and WordPress keeps re-arming a recurring event whose plugin is gone
* "Blogcraft has not processed its queue recently" no longer shows forever on sites driven by a real system cron or WP-CLI — the arrangement the plugin's own documentation recommends. Only the WordPress-cron route recorded a heartbeat
* Plugin updates now bring the database up to date. Schema changes previously arrived only through the activation hook, which a one-click update never fires
* Deleting the plugin now removes the blueprint store and three other options it had been leaving behind, despite promising to remove every trace. Reinstalling handed the next owner the previous one's writing rules

= 0.33.0 =
* Every provider now says whether it costs money. The writing providers are marked free, "free tier" or paid, and the picture services the same way, so the first question anyone has about a list of fifteen names is answered before they pick one instead of after the first bill
* No label names a specific free allowance. Quotas move on each provider's schedule, so a number written into a plugin goes stale silently; the settings screen links to each provider's own pricing page instead

= 0.32.0 =
* The quality threshold and refresh-after-days settings are now actually saved. Both were rendered on the settings screen and read everywhere the pipeline needs them, but nothing in between wrote them to the database — the number typed in was shown back as "Settings saved" and then discarded, so every post was gated against 60 regardless of what was chosen
* The table of contents toggle is now honoured. It previously had no effect on a published post; every article with four or more sections got one whether the setting was on or off
* Sources cited now defaults on. It is the only way a real citation link can appear at all, since every prompt in this plugin forbids the model from writing markdown or HTML, so with it off the "Sources cited" check could never pass no matter what a post said
* Fixed a second bug hiding behind that one: five per-post extras, including sources, had no control on the Write screen but were still in the list the composer reads to decide what was switched off — so every single post written through the composer forced sources off regardless of the blueprint, even after the default above was fixed
* Internal links are now woven into an article before it is scored, not after. The check that counts them previously always measured a draft with none yet, so it could never pass; the review screen showed 0 internal links on every post no matter how many the published version actually carried
* A per-post picture or citation count deliberately set to zero is no longer silently discarded and replaced with the blueprint default
* Two "Finish it" links pointed at the wrong settings card

= 0.31.0 =
* Research sources and pictures now start switched off. Blogcraft contacts nothing until you turn a source on; turning it on is how you say yes to it
* Reddit is no longer read. It refuses anonymous automated requests from most shared hosting, so it returned nothing for a large share of the people who had it on, and its terms want a registered application either way
* Hacker News, Wikipedia and every paid source are unchanged, and still send only the post topic

= 0.30.0 =
* A queued post can be stopped from Activity. Queueing twenty topics and changing your mind previously left no way out but the database

= 0.29.1 =
* Fixed: 313 of the plugin's 802 translatable strings were missing from the translation template, so nearly two fifths of the interface could not be translated at all

= 0.29.0 =
* Pictures now have their own settings card next to the one for writing, instead of being buried three cards down under Automation
* Fixed: the switch for putting a picture under each section heading was read by the pipeline and rendered nowhere, so it could not be turned on
* Overview explains how the plugin is used in four steps, and keeps explaining it after the setup checklist has gone

= 0.28.0 =
* Google Gemini and xAI Grok can now draw the pictures. If you already write with either, the same key does both
* Images that arrive as data rather than a link are handled, which is how Gemini answers
* A generated image is saved with an extension matching what it actually is, so a PNG is no longer rejected for being named .jpg
* Anything that comes back not being an image is refused rather than written to your media library

= 0.27.0 =
* The documentation now ships with the plugin, under Blogcraft, Help. The help panels used to link to a page that did not exist
* Provider addresses moved into a data file, and other plugins can now add a provider with the blogcraft_providers filter
* Word count for structured data is stored against the post instead of being recalculated with regular expressions on every single page view
* Uninstall now removes the nine post meta keys it always claimed to

= 0.26.0 =
* Tested against WordPress 7.1
* On WordPress 7.0 and later, Blogcraft can route through the WordPress AI Client: no key, no signup, no model id. Offered only when a provider plugin is actually installed behind it
* Related posts no longer exclude the current post in the database query, which got slower as a site grew

= 0.25.0 =
* Five optional extra sections, written from the finished article in one extra request: who it is for and who it is not, what works and what does not, a table of the figures with their sources, mistakes worth avoiding, and the sources it was written from
* Tables and numbered lists are now rendered as real blocks. The "use tables" switch has existed since the beginning and nothing could draw one
* Fixed: six custom-endpoint settings were saved and never passed to the adapter that reads them, so a custom provider always used Authorization, Bearer and a default response path whatever you typed
* Settings sections say whether they are required or optional
* Write a post says that the topic is the only field you have to fill in

= 0.24.0 =
* Start from a shape: eight ready-made sets of rules for guides, listicles, tutorials, comparisons, data studies, opinion, explainers and reviews
* Match an article: paste any published post and Blogcraft measures how it is built, then sets the rules to match. Structure only, never wording
* The base URL hint now changes when you change provider instead of describing whichever one was saved

= 0.23.3 =
* Fixed: Pexels and Pixabay were being sent the whole image prompt as a search query, so they matched nothing and every post quietly fell back to a free generator

= 0.23.2 =
* Fixed: picture settings reported as ready when they were not, so every image quietly fell back to a free service
* The picture controls now name the service drawing them and link straight to it
* The OpenAI image key field says whether your writing key already covers it

= 0.23.1 =
* The brief tabs on Write a post now say what they are and stay in view, so Pictures and Publishing can actually be found
* Screens use the width of the window instead of a 900px column
* The help control on each settings section is a labelled button rather than a small question mark
* Queueing is blocked, with a link to fix it, when no provider is connected

= 0.23.0 =
* Fourteen named providers instead of four, including Grok, Kimi, DeepSeek, Groq, OpenRouter, Mistral and local models through Ollama or LM Studio
* Wikipedia, Reddit and Hacker News are now read for every post, free and with no key
* "Learn from my posts" fills the voice settings in from what you have already published
* Every settings section has a help control explaining what it is for
* Pictures and Publishing tabs on Write a post: art direction per post, plus category, tags, author and a publish time
* Needs review only appears when something is actually waiting
* New look throughout: translucent panels over a soft wash, with a solid fallback for anyone who has switched transparency off

= 0.22.0 =
* A field for your own figures, results and prices, used as fact and checked against the finished draft
* Internal links are now placed inside sentences where the wording matches, with the rest still listed at the end
* Overview says when posts have gone stale and refreshing is switched off

= 0.21.0 =
* Nine new checks, including answer-first openings, figures without a source, and how much of a draft merely repeats what its sources said
* Statistics, citations and first-hand experience are now measured, not just requested
* Title and meta description are checked, and the rewrite can now fix either
* Title and description length are taken from your settings instead of being hardcoded
* Publishes author, reviewer, organisation and breadcrumb structured data
* Section images no longer depend on exact block markup, so a theme or editor change cannot silently stop them appearing

= 0.20.0 =
* Pictures are now described by the model that wrote the article, instead of the headline being handed to an image model
* Added fal.ai and OpenAI as image sources, alongside the free ones
* New Pictures controls: treatment, mood, what the picture shows, shape, colours, and what it must never contain
* Text is kept out of generated images unless you ask for it
* The image prompt is shown on screen as you change the controls

= 0.19.0 =
* Overview now answers what needs doing, what is waiting, and how the last few posts scored

= 0.18.0 =
* Drafts are checked for missing alt text, skipped heading levels, and sections too thin to be worth a heading

= 0.17.0 =
* Works out which terms a subject is expected to cover, from the pages already covering it, and checks the draft against them

= 0.16.1 =
* Removed output token caps that starved reasoning models and broke drafting

= 0.16.0 =
* Articles are now written one section at a time, so long posts no longer fail part way through
* Saving a key checks it works, including on the save that completes setup

= 0.15.0 =
* Saving a key now checks it works and says so, instead of only saying "saved"
* Settings tells you which single thing is missing rather than "no provider yet"
* Save moved into the sticky rail, which now highlights the section you are in

= 0.14.0 =
* Terms that must never appear, and subjects to steer clear of, on both the brief and each post
* Settings gained jump links to each section

= 0.13.0 =
* Write a post rebuilt as a composer: the full brief for one post, on one screen
* A panel showing the shape of the post, its word budget and rough token cost, before you queue it
* Warns while you type when a topic repeats something already written or queued
* Every screen carries links to the others
* Settings links straight to the page that issues a key for the chosen provider

= 0.12.0 =
* Change the brief for one post without touching your defaults
* Needs review now shows what was measured and what was asked for, not just a number

= 0.11.0 =
* New "How it writes" screen: 48 controls over voice, structure, search, and sounding human
* A live Brief panel showing exactly what the model is told, updating as you change anything
* Per-section instructions for the opening, sections, ending and questions

= 0.10.0 =
* Every writing control now reaches the model, and measured faults are fed back for rewriting

= 0.9.7 =
* Weekday checkboxes are no longer squashed together

= 0.9.6 =
* Repeated topics in one pasted list are no longer queued twice
* Automation switched on with no days chosen now says so instead of doing nothing quietly
* The connection test asks for a key rather than spending a request to be told there isn't one
* Activity lists each job's topic, and the dashboard links a failure to its reason

= 0.9.5 =
* Accessibility: the bulk topic field is labelled, and repeated row buttons now name the topic or job they act on

= 0.9.4 =
* Schedule by weekday and start hour, in your site timezone
* New Calendar screen projecting when each queued topic will be written, with reordering
* Translation template shipped

= 0.9.3 =
* Every provider now has a default API address, so a key and a model are enough
* An empty setup says so instead of failing on a request that could not work

= 0.9.2 =
* New Activity screen showing recent jobs, why any of them stopped, and the event log
* Failed jobs can be tried again from there
* Running the queue by hand reports a failure as a failure

= 0.9.1 =
* The setup warning now appears when no provider is connected

= 0.9.0 =
* Optional image beneath each section
* Consistent card layout across every screen

= 0.8.0 =
* FAQPage structured data
* Bulk topic import and batch rollback

= 0.7.0 =
* Research step gathers sources before writing
* Quality scoring and a review queue for posts that fall short
* Link verification before publishing
* Content refresh rewrites stale posts in place
* Image provider fallback chain
* WP-CLI commands
* Per-topic instructions

= 0.6.1 =
* Redesigned settings screen
* Fixed fields that browsers autofilled incorrectly

= 0.5.0 =
* Backward internal linking and duplicate-topic detection

= 0.4.0 =
* Internal linking, structured data, featured images, scheduled generation

= 0.3.0 =
* Brand voice applied to every request

= 0.2.0 =
* Post generation pipeline

= 0.1.0 =
* Initial foundation release
