Unreleased
In progress on mainWork on main that has not yet shipped in a published build.
0.7.3
2026-10-10Fixed
- Applied planned links use the page's own design system. On a page in any design system other than GOV.UK, the links that "Apply planned links" adds in the Journey map carried a GOV.UK link class, so they showed unstyled and validation reported a class from another design system. They now use the page's own link style (NHS.UK, USWDS, Bootstrap Italia), or a plain link where the design system styles links without a class (Abstract, NSW, Scottish Government, Digital Agency (Japan)). GOV.UK pages are unchanged.
- Refine with AI no longer changes the wrong section after you move one. If you chose "Refine with AI" on a section and then moved it with Move up or Move down, the request went to whichever section had taken its old place, and could replace it. The "Refining:" chip now moves with its section. If the section changes in any other way, the chip is cleared and a message asks you to select the section again.
- Fix with AI reports on the fix it ran, and only once it has run. If the fix had to ask which section to change, or wait for you to confirm, it used to say "Still failing after the fix" before anything had changed. Now it waits. If you leave without choosing a section it says the fix didn't run, if you press Stop, it says so, and if the fix changed nothing it says that instead of "still failing".
- Fix with AI changes the section with the problem. When it can tell which section holds the failing element, it changes that section, not one you had selected for something else, and it leaves your unsent message in the chat box.
- One Fix with AI at a time. While a fix or another change is being generated, the other Fix with AI buttons wait and say why. Before, a second press was lost and the first fix was reported under the second issue. Fix with AI also waits while another request is waiting for you to choose a section or a place to add it, and on an empty page it says there is nothing to fix.
- Fix with AI's request names the elements that fail. The request for links used to describe "Change" links in a summary list, whatever the link was. It now names the links and suits any design system.
- Duplicate makes a working copy of a section. The copy's outer element now gets its own id. Radio buttons and checkboxes in a copied question stay in one group; before, each option got its own name, so you could pick more than one radio button. In the copy, conditional reveals, accordions, Bootstrap Italia collapses, dialog and popover buttons, and USWDS validation checklists now work on the copy's own parts; before, they opened or updated the original's.
- Auto-fix before Regenerate no longer overwrites a change you made while it waited. If the page changed while the "Auto-fix validation issues" dialog was open, applying the fixes wrote over the change, and could even land on another page you had switched to. Now nothing is written, and a message asks you to press Regenerate again.
- Pages are checked as soon as Refine with AI, Fix with AI or Add section changes them. A page is now validated straight after one of these changes, as it is after a whole-page generation, so its issue badge is up to date. This happens only while the page is still on screen: a page you have left reads "not checked" until you validate it.
- The spoken validation result counts every issue the panel lists. The result read out when validation finishes ("Validation complete: …") left out some of the issues in the panel, such as links that don't go to a page. It could say "HTML classes are valid" while the panel listed warnings. It now counts them all.
- Refine with AI asks which section to change when its answer is unclear. With no section selected, Refine with AI first asks the AI which section your request is about. When that answer came wrapped in an explanation, it could change the wrong section or offer to rewrite the whole page. Now it asks you to choose, with the AI's suggestions highlighted.
- A refined section keeps the page's indentation in the HTML source. A section changed by Refine with AI used to lose the indentation around it, which made the page hard to read in Code edit. It now lines up with the rest of the page. Text whose line breaks show on the page, such as preformatted text, is left exactly as written.
- Auto-fix in the Validation panel can no longer write one page's HTML into another. A preview of auto-fix changes stayed in the panel after you moved to another page by keyboard, ⌘N or the header, and Apply then replaced that page with the first page's fixed HTML. A preview is now dropped as soon as the page, its design system or its HTML changes. If an out-of-date preview still reaches Apply, nothing is written and a message asks you to preview the changes again.
- The Validation panel no longer shows another page's result as current. After you switched page, opened a project, changed design system or edited the HTML, the panel kept the last result. It could show the previous page's errors, call a page with errors valid, or relabel a GOV.UK result with another design system's name. It now shows "Not validated" until you validate what is on screen. On a page with Unresolved exits, it lists only those exits until then, and keeps them up to date as you work. Validating an empty page now says there is nothing to validate; before, the button did nothing.
- Auto-fix no longer makes text in a GOV.UK confirmation panel hard to read. It added the body text style to a plain paragraph inside the green panel, which turned the white reference number into small dark text on green, below the WCAG contrast minimum. Auto-fix now leaves text inside the panel, the header and the inverse service navigation alone, because those components style their own text.
- The "Warning" prefix in GOV.UK warning text is hidden again. Prototypes used a class from older GOV.UK Frontend versions that version 6 no longer styles, so "Warning" showed on screen and the page still validated. The class is now reported as invalid, auto-fix replaces it with govuk-visually-hidden, and Prompt to Page no longer teaches it.
- Auto-fix no longer changes a size or number it cannot be sure of. It "corrected" govuk-input--width-25 to govuk-input--width-2, shrinking the field to 2 characters and hiding the error. When the only difference is the number or size at the end of a class, auto-fix now leaves the class alone and the error stays in the Validation panel.
- USWDS question groups and alerts no longer sit on the content around them. USWDS gives a group of questions (a fieldset) no space of its own, and its visible heading does not create any, so a group sat directly under the introduction or the group before it; the content after an alert sat directly under the alert. Prompt to Page now teaches USWDS's own spacing classes for both, as USWDS's form templates use them, and auto-fix adds them where a page is missing them. It leaves a page alone where the author already set that spacing, as USWDS's sign-in template does. A paragraph or list after an alert is spaced the same way: on its own it keeps only a smaller gap. Existing pages change when you regenerate them. Auto-fix makes the same change, but the Validation panel offers auto-fix only when it lists an issue on the page.
- A USWDS section added with Add section now gets the spacing the page calls for. Auto-fix checked the new section on its own, without the content around it. So a question group added after an existing question, or a block added under an existing alert, went in touching the content above. An alert added above an existing form left the form touching the alert. In a test replay, 31 of 105 added sections did one or the other. Prompt to Page now checks the new section against the page around it. It adds the spacing the section needs and, where the section calls for it, spaces the block straight after it. Nothing else on the page changes, and Undo removes both.
- Bootstrap Italia question pages no longer overprint or run together. Prompt to Page taught Bootstrap Italia's floating-label wrapper with the hint above the field, so the label printed over the hint and, once you typed, rose into the heading. Its examples also ran a field into the button, an error into the next label and the start link into the next heading. Prompt to Page now teaches Bootstrap's own form layout: each question in its own spaced block with the label above the field and the hint below it, the start link in its own paragraph, and Back set apart from Continue.
- The small print in the Bootstrap Italia footer can be read. The "Built with Prompt to Page" statement was near-black text on the footer's dark blue band, a contrast of 1.38:1 where WCAG asks for 4.5:1, because Bootstrap Italia styles only links in that band. It is now white (12.6:1), with the same padding Bootstrap Italia gives its own small print. A new check covers the text in every design system's header, prototype banner and footer.
- Pages in the assessment evidence look as they do in the prototype. EVIDENCE.html shows each page inside the document, and there the design system's colours, text settings and web fonts did not all reach it. Text fell back to the evidence document's own near-black system font: the Bootstrap Italia footer small print was near-black on its dark blue band (1.55:1, where the page itself shows white at 12.6:1), NSW headings were 16px instead of 48px, and NSW, DADS and Abstract lost their colours. In Chrome and Edge, every page also fell back from its design system's web font. Each page in the evidence now has the colours, text and fonts of the exported page, and a Japanese page declares its language. A new check compares each design system's page in the evidence with the page file, in Chromium and WebKit.
- Pages in the assessment evidence fit their frames, whatever the size of the window. Each page in EVIDENCE.html sits in a column about 730px wide, but it took the layout the whole browser window called for. In a 1280px window, a Scottish Government page laid out 1152px wide and ran out of its frame, and the GOV.UK footer sat 15px outside it on each side. NHS, USWDS, NSW and Bootstrap Italia pages changed layout with the window. Each page in the evidence now takes the layout of a window as wide as its frame, in any window and in print, and matches the page file opened at that width. A USWDS or DADS skip link shows at the top of its page when focused, not at the top of the document. A new check covers each design system's page in windows from 800px to 1920px wide.
- USWDS pages no longer shrink to fit their text. In exported and shared USWDS pages, the content column and the prototype banner were only as wide as their text and sat in the middle of the window. A page with a heading and one short sentence was 254px wide in a 734px window. The prototype banner did the same in the preview, and page thumbnails showed the narrow column. They now span the page up to USWDS's usual width, and the footer still sits at the bottom of a short page. A new check makes sure the layout that keeps the footer down changes the width of nothing on the page, in every design system.
- A Scottish Government page started from another page's shell is laid out properly. The Scottish Government page layout is a grid of named areas, and New page with "Shell only" put the "New page" heading straight into the grid. The heading took one narrow column, 97px wide in a 1024px window, and a section added after it sat beside it as another column. The heading now sits in the page's header area, and Add section puts the first section in the content area below it, as on generated pages. The same applies to "Pick components" when no content is picked. Pages already made this way keep their layout until they are regenerated.
- NSW Design System buttons no longer touch the content above them. An NSW button has no spacing of its own, and NSW's form pattern puts the submit button in its own form group. Prompt to Page taught a bare button instead, so in a test run 358 of 371 generated NSW pages with an action button had it touching the question, list or paragraph above. The prompt and examples now teach NSW's pattern. Auto-fix also puts a bare submit button in its own form group and a Start now link after body text in a paragraph, and gives a plain <form> the nsw-form class. Existing pages change when you regenerate them. Auto-fix makes the same change, but the Validation panel offers auto-fix only when it lists an issue on the page.
- A button written as a link now goes where it says. A button ignores href, and the app removes onclick code from pages. So a button written as <button href="/eligibility"> or <button onclick="window.location.href='/change/name'"> did nothing when clicked, and Link mode could not connect it to a page. In tests:
- asked to add a button linking to another page on an NSW start page, one model wrote 2 of 5 with an href;
- another model wrote Bootstrap Italia start and Change buttons with onclick;
- earlier GOV.UK and NHS.UK journeys had Back buttons written with onclick;
- Bootstrap Italia pages had an Indietro (Back) button that ran history.back().
Auto-fix now turns these into links with the same classes, the way design systems write a Start now link: a design-system button with an href, or any button whose onclick only goes to an address. A button whose onclick only goes back becomes a back link, which goes to the previous page in the preview, in an exported prototype and on a shared one, even in a design system with no back link of its own. So does one that goes where the page's back link goes, so a generated journey can't point a Back button at the next page. Auto-fix leaves alone a button that submits a form, a reset button, a component's own button such as a tab, and an onclick that does anything else. Existing pages change when you regenerate them. Auto-fix makes the same change, but the Validation panel offers auto-fix only when it lists an issue on the page.
- A Back button in a generated journey no longer points at the next page. When it generates a journey, Prompt to Page points each page's main buttons at the next page. It took any link styled as a button for one of those, so a Back button styled that way was pointed forward: on a check-answers page from an earlier journey, "Back and edit" went to the confirmation page. A link whose whole text is Back, Go back, Back and edit, Indietro, Torna indietro or 戻る is now a back link, however it is styled, and goes to the previous page. On a page made on its own, outside a journey, the quality score no longer counts such a link with an href="#" as a button that goes nowhere. "Back to …" and "Return to …" links are unchanged.
- GOV.UK radio and checkbox options no longer show in a serif font. An option's label takes GOV.UK's text style only with the govuk-label class, which GOV.UK Frontend always adds. The examples Prompt to Page gives the model left it out, and so did 40 of 44 generated options in recent test projects: they showed in the browser's 16px Times, in black, beside 19px Arial questions. The examples are corrected, and auto-fix adds the class to any option label without it, including in projects that use the MOJ overlay. Existing pages change when you regenerate them. Auto-fix makes the same change, but the Validation panel offers auto-fix only when it lists an issue on the page.
- Validation now warns when two elements share an id. A second field with the same id as the first passed validation, although its label pointed at the first field. Each shared id is now reported as an accessibility warning.
- Validation no longer checks a page against another page's design system. While one page was generating, validating or auto-fixing a page built in a different design system used the generating page's design system instead: an NHS.UK page validated during a GOV.UK generation had its own classes reported as invalid, and auto-fix could add GOV.UK classes to it. The Validation panel now pauses while a page is generating and says why, and every check runs against the design system of the page you are looking at.
- USWDS, Bootstrap Italia, NSW and Scottish Government pages can now validate cleanly. These design systems have classes without their prefix, such as USWDS's grid-row and Bootstrap Italia's btn. Validation reported every one of them as a class from outside the design system, even when it was correct, so these pages could never show "HTML classes are valid" and lost quality points for correct markup. A known class like these now counts as part of the design system. Validation names any class it does not recognise, and suggests the likely class for a near miss such as btn-primry.
- You can now read a long validation message in full. Each issue in the Validation panel showed one line cut off with "…", and opening it showed only its type and category, so a long message, such as the list of classes it does not recognise, could not be read on screen. Opening an issue now shows its whole message.
- The Validation panel's issue count is readable on red. When a page had errors, the count in the panel header was dark text on red, below the WCAG contrast minimum. It is now white on red, and the panel's other status colours use the same readable pairs in light and dark mode.
- Validation now reports malformed HTML, and auto-fix checks the same page Validation does. Validation checked each page after the browser had quietly repaired it, so a self-closing div, a duplicate attribute or a stray closing tag never showed. Auto-fix worked on the page as written, so it proposed changes Validation never mentioned, some of them inside header or footer markup the app replaces with its own. Validation, Code edit's notices and auto-fix now check the same page: the one you wrote, without that header and footer. If a page includes header or footer markup, Validation says so and auto-fix offers to remove it. Auto-fix also merges duplicate class attributes instead of dropping the second one, so a class such as govuk-input--error is kept.
- Digital Agency Design System pages no longer have components touching. DADS components carry no space around themselves; the page they sit on has to provide it. Prompt to Page's page frame didn't, so a button sat directly under the list or question above it, two questions ran together, and the page heading or an error banner touched the form. Pages looked uneven because space appeared only where a plain paragraph happened to sit between components. Previews, exported and shared pages now space every block 24px apart. A button sits 32px below the content above it, as in DADS's own form example, and a section heading sits 48px below the content above it.
- Body text on Digital Agency Design System pages is no longer cramped. Paragraphs, list items and the answers on a check-answers page carry no DADS class, and nothing set their line height, so they fell back to the browser's tight default beside components set at 1.7. They now use DADS's standard body text style: line height 1.7 and letter spacing 0.02em. A plain heading on the page gets a line height of 1.5. Components keep their own text styles.
- Body text on Digital Agency Design System pages is no longer darker than the components. Paragraphs, list items, check-answers answers and plain headings were the browser's black, while DADS components set their text in dark grey (#333333). They now use the same dark grey. Links keep their own colour.
- The preview of a Digital Agency Design System page now matches its export. The spacing and body text fixes above reached exported and shared pages but not the preview. Generated DADS pages keep their own <main>, and the preview showed it without the page frame's class, so components still touched and body text was still cramped and black there. The preview now gives the page's main region the same class as the export, for every design system.
- USWDS, Bootstrap Italia and Scottish Government icons now show. These design systems draw each icon from a shared icon file. Prompt to Page removed the part of the icon that points at that file, so icons in generated pages were blank. Where the icon remained, the preview, the page list, the evidence check, the LAN share and any exported page opened from your computer still could not load the file, so they showed nothing either. Each page now carries the icons it uses. They show in the preview, the page list, the LAN share, the testable prototype and the evidence pack, however you open them. Pages without these icons are unchanged.
- SVG icons keep focusable="false". GOV.UK, NHS.UK, MOJ and USWDS icons carry it on their <svg> so that older browsers never put keyboard focus on an icon. Prompt to Page removed it from generated pages, added and refined sections, and exports. It now keeps it on SVG elements, with the values true, false or auto. On any other element, where it means nothing, it is still removed.
- Shared pages show their design system's images. Sharing for testing served each design system's stylesheet and scripts but not its image files. On a shared USWDS page, the tick in a checkbox and the icons in file inputs, alerts and accordions drew nothing. Scottish Government document icons were missing too, as were Abstract's arrow and external-link symbols. The share server now serves every image file the design system's exports include. A shared page also finds an image that names the file relative to the page, such as scotgov/images/documents/svg/pdf.svg.
Security
- An image inside an SVG can no longer load from another server. Prompt to Page removes an <img>'s web address unless it is relative or on this computer, so a page cannot fetch an image from elsewhere when it opens. An SVG <image> or filter image, and a gradient, pattern or text path that borrows from another file, kept theirs, whether given as href or xlink:href. Those addresses now follow the <img> rule, as do addresses inside a <template>. A link in an SVG can still go anywhere a link can.
- Styles and SVG fills can no longer load from another server. A <style> block could import a stylesheet or load an image from anywhere, and an SVG shape's fill, stroke, filter, mask, clip path or marker could name a file on another server. An exported page fetched them when it opened, and a <style> block applied in the app's preview too, where checking the page's accessibility could fetch what it imported. Prompt to Page now removes <style> blocks: pages take their styling from the design system's classes. An SVG address of this kind now follows the <img> rule, so references within the same SVG, such as a gradient fill, still work. A table's or cell's old background image attribute follows the same rule.
0.7.2
2026-10-05A third accessibility release, fixing what the Windows tests of 0.7.1 found: a second NVDA test, a first JAWS test, real Windows Contrast themes, Windows text size at 200% with the interface zoomed up to 400% in all, and the Windows UI Automation tree. Keyboard focus no longer falls to the top of the window when the control it was on goes away, every "Are you sure?" question opens in the app's own dialog, the workspace fits and scrolls in a very small window, and the preview no longer cuts off the right of a page. The app follows Increase contrast and Reduce transparency, text shows in full with wider text spacing, and small buttons are at least 24 pixels square. Screen readers hear fewer repeats and run-together words. Generated pages are checked for the hooks their design system's code needs, the prototype banner and the back link sit in landmarks, USWDS examples no longer skip heading levels, and exports no longer claim accessibility checks that didn't run. These fixes have been checked with automated tests, not yet by a person using a screen reader; the accessibility statement says what that means.
This build also carries the changes made to the Digital Agency Design System (DADS) pack after an external review, referred to here as R-DADS-01. On DADS pages, a banner that opens the page carries the page's only <h1>, check-answers lists hold only answers with a change link after each, a date of birth is asked as year, month and day, and question, eligibility and start pages are simpler. Five DADS-only checks warn when a page goes back to the old patterns. Across packs, more answers play back on check answers: dates of birth, US-order dates on USWDS pages, and addresses asked in parts. Prompt to Page is an independent project: neither the review nor these changes mean that the Digital Agency, or anyone else, endorses it. New Japanese wording in this release is proposed, pending native review.
Added
- GOV.UK and NHS.UK pages are checked for the hooks their design system's code needs. A component behaves as it should only when its element carries the right data-module. Without it, an error summary never takes focus when the page loads, and conditional questions never appear. Validation now warns when a page's error summary, character count, password input or tabs lacks its hook. It checks the same on GOV.UK's accordion, exit-this-page and enhanced file upload, and on NHS.UK's file upload and Copy code button. It also warns when radios or checkboxes with conditional questions or an exclusive "None" option lack one, and likewise a link styled as a button or a success banner, however the conditional question is wired to its option. On a generated page, each warning also lowers its quality score. The lists come from the versions the app bundles: GOV.UK Frontend 6.3.0 and NHS.UK frontend 10.5.2.
- USWDS pages are checked for the wiring USWDS's scripts need. USWDS starts its components by class, and several need more than that. An accordion button's aria-controls must name a panel on the page. A combo box or time picker needs a labelled input, and a modal needs an id, aria-labelledby and aria-describedby. A character count needs its message, a date range picker needs two date pickers, a tooltip needs a title, and Show password needs real targets. Most of these failures stop USWDS while the page loads, so every USWDS component after them on the page stops working too. Validation now warns about each one, says whether it stops the other components, and says how to fix it. The list comes from the USWDS version the app bundles (3.13.0).
- The app follows Increase contrast and Reduce transparency. With Increase contrast on (macOS, or a Windows contrast setting that reports it), borders, field edges and dividers are solid and at least 3:1 against what they sit on, secondary text is darker, and panels and dialogs are opaque, with no frosted-glass blur. With Reduce transparency on (on Windows, Transparency effects off), panels and dialogs are opaque. The macOS web view doesn't report Reduce transparency, so on macOS the app reads the setting itself, when it opens and whenever its window comes back to the front. The New page dialog is now opaque in every mode, as the question dialog is.
- The macOS menu bar has the app's commands. The menus held only the standard items, and the Help menu was empty. File now has New Page, Save Checkpoint and Export Testable Prototype; the app menu has Settings; View has the command palette, showing and hiding the Pages and Tools panels, each tool, interface zoom and the appearance theme; and Help has Help and Feedback, Keyboard Shortcuts, Accessibility Help, the user guide and the accessibility statement. Each item shows its keyboard shortcut, and the shortcuts now also work from text fields on macOS, through the menu.
- Digital Agency Design System pages have five more checks. Validation now warns when a DADS page's first heading isn't its only <h1> (for example, a banner's <h2> above the page's <h1>), when a heading sits in an <hgroup> with no shoulder line, when a description-list item holds a link, a button or a second <dd>, when a date of birth lacks separate year, month and day inputs with bday-year, bday-month and bday-day autocomplete, and when support or error text asks only for a "valid" or "correct" answer without saying what one looks like, such as 「正しく入力してください」 or 「入力内容が正しくありません」. On a generated page, each warning also lowers its quality score; none sends the page back to the local AI for repair. Pages in the other packs are not checked for these.
Changed
- The preview's SR tree is now Roles and names. The panel listed each element's role and name under the title "Screen-reader tree", but it is worked out from the page's HTML, not taken from a screen reader: it includes content a screen reader skips, such as anything marked aria-hidden, and it can name an element differently. Its button is now Roles, the panel is Roles and names, and the panel says that a screen reader may announce the page differently, so test with one as well.
- Digital Agency Design System journeys ask one thing per page. Generated question pages asked for every detail in the brief, put the service's name in their <h1>, and could give a real place as an example. A question page now asks only for its own fields, its <h1> says what it asks, and an example is fictional and given only where a field needs one. A radio or checkbox question is its own form group, not one nested inside another. The eligibility page asks a single yes/no question about the brief's conditions instead of becoming a form for every field. The start page is plain paragraphs in plain polite wording, a sentence and a list of what to have ready, and a start link labelled with what you are starting, rather than a form with a generic button.
- Digital Agency Design System pages are written in the language you ask in. The local AI is now asked for every visible string as natural copy in the brief's language. The English page names in a journey plan are planning labels, not headings to translate, and buttons and links name their action in that language instead of translating English template wording.
- The DADS pack's own text says which source it means. Text in the app, the local AI's instructions and the user guide spoke of what "the design system" has or lacks where it meant the sample code the pack bundles (version v20260825), and the user guide described the upstream accessibility target more broadly than its source does. Each now names the sample code or the documentation page it refers to.
- Gemma 4 E4B and E2B cut more Digital Agency Design System pages short. The changes above make the DADS instructions longer, which leaves less room in the 8,192-token context. In one measurement run of 27 DADS cases, each of the two models ran out of room on 6 pages, up from 3; no other model measured cut more pages short.
0.7.1
2026-09-27A second accessibility release, fixing what the tests of 0.7.0 found: a keyboard test of the installed macOS app through the macOS accessibility interface, and a test of the Windows app with the NVDA screen reader and two Windows Contrast themes. Link pages now works from the keyboard, focus no longer falls to the top of the window after common actions, focus inside the preview stays in view, and moves, page switches and deletions are announced. Screen readers hear fewer repeats and run-together names, and less is read out at once. First-run setup has help on every step, Set up local AI again can be cancelled, the finished journey summary can be closed, Clear conversation and Delete project start on Cancel, and the single-key ? shortcut is gone. Changing the model no longer gets stuck or leaves the app unable to generate, prompts only ever go to the app's own model, and form fields keep ids and names such as name in the preview and every export, so their labels work and a Prototype Kit saves their answers. These fixes have been checked with automated tests, by keyboard and in the installed macOS app, not yet by a person using a screen reader; the accessibility statement says what that means.
Added
- Help from every step of first-run setup. Help and feedback could not be reached until setup was finished. Every setup step now has a Help & feedback button at the bottom, which opens Email feedback, Copy feedback diagnostics and the feedback email address. Escape closes it.
- Set up local AI again can be cancelled. Settings → Local AI → Set up local AI again had no way back to the app without finishing setup. Its steps now have Cancel — keep current settings, and Escape does the same: the app returns to Settings → Local AI with your settings as they were. When a setup step opens, focus starts on its heading.
- The Accessibility summary links to the full statement. Settings → Help & feedback now links to the app's accessibility statement on the website, which opens in your browser.
- The finished journey summary can be closed. The Journey ready! summary stayed over the preview, through page switches, with no way to close it. It now has a close button, and it clears when you switch pages once every page has generated. A summary with pages still to retry stays until you close it.
Removed
- The single-key ? shortcut for the command palette. Pressing ? outside a text field opened the command palette. A single-character shortcut can be set off by speech input, and it could not be turned off or changed (WCAG 2.1.4). ⌘K on macOS and Ctrl K on Windows still open it.
Fixed
- Changing the model no longer gets stuck. Set up this model now started the local AI twice, and the second start could leave the app on "Model load check 5 of 360", or on "Launch was cancelled", although the model was running; only Restart local AI got it going again. A switch could also start the new model while the old one still held its port, so the new model listened on another port while the app kept sending prompts to the old one, and every generation failed until the app was restarted. The app now starts one model at a time, waits for the old one to stop, and sends prompts to the port the model is actually on. Change model ends on its Local AI is ready step again.
- Prompts only go to the app's own model. When another program was already using the local AI's usual port (8080) as the app started, the model moved to the next free port, but pages were still requested from port 8080 — so the request, with your prompt, went to that other program on this computer. Requests now go to the model's own port.
- Form fields keep their ids and names. The app's HTML cleaner removed any id or name that matched a built-in browser property, such as name, title or action. A field written as <input id="name" name="name"> lost both, so its label no longer pointed at it — in the preview, in the accessibility check (which then reported a missing label) and in every export. In a Prototype Kit hand-off the field also had no name, so its answer was never saved. A section added with Add section or changed by a refinement lost them from the page itself. They are now kept; a page that already lost them keeps the markup it has.
- The setup model picker shows which models are downloaded. In first-run setup and Set up local AI again, a model already on this device said Download and start and had no Downloaded badge (it was not downloaded again). It is now marked, as in Change model.
- Link pages works from the keyboard. About half a second after Tab reached a page in the destination picker, focus jumped back to the search box, so a keyboard or screen-reader user could not choose where a link or button goes. Focus now stays where you put it. Enter in the search box chooses the only matching page, or moves to the first page when several match, and the arrow keys move between the search box and the pages.
- Keyboard focus no longer falls to the top of the window. After some actions focus was lost, and a screen reader started again from the top. It now lands somewhere useful:
- each first-run setup step starts on its heading;
- creating, opening or importing a project moves to the chat box, whether you import from the Projects dialog or from Share & Export, and Share & Export's Export and Import keep focus while their file window is open;
- Validate keeps focus while validation runs, and so does Create project while it works;
- Collapse transcript moves to the transcript toggle, and Clear conversation to the chat box;
- moving a section to the top or bottom keeps focus on the move button, which says it is unavailable instead of being switched off;
- Cancel in the New page dialog returns to the control that opened it;
- closing a section's actions after the Sections list has closed returns to Edit section;
- each step of Change model starts on its heading, and Start using moves to the chat box.
- Moves, page switches and deletions are announced. Moving a section now says where it went, such as Moved Heading (large) to position 1 of 5., and duplicating one says so. Choosing a page in the page list says Switched to the page, and deleting one says Deleted page and its name.
- Add section and Link pages say what to do. Their instructions were never read by a screen reader, and could scroll out of view above the preview. They are now announced when the mode starts, and shown in a strip above the preview that stays in view and never covers the page. In a narrow window at Fit, the Edit section instructions no longer cover the top section.
- Keyboard focus in the preview stays in view. Moving through the page with Tab could reach a control scrolled out of the canvas, or hidden behind the expanded chat transcript, with Add here points the most likely. The canvas now scrolls a focused control into view, the transcript folds away when you move into the preview, and the accessibility-panel and Add section highlights also stop short of the transcript.
- Tab no longer enters the preview behind the HTML source view. With the code view open, Tab from the editor could move through the hidden preview's links and fields.
- The Sections list and the page-list divider work with screen readers straight away. The Sections list is now a list box, so a screen reader switches to its arrow-key mode by itself; it also comes before the preview in the Tab order, where it sits on screen. The divider that resizes the page list is a slider, and Up and Down arrows work as well as Left and Right.
- Selected and pressed controls stay readable in Windows Contrast themes. In a light Contrast theme such as Desert, selected tabs and pressed toolbar buttons showed their labels in the same colour as their fill, so they could not be read, and the accessibility panel's severity filters showed no pressed state at all. Selected and pressed controls now keep the theme's normal text and background, with a thick edge in the theme's highlight colour.
- The highlighted suggestion is visible in the dark theme. The highlighted command in the / list, the @ page list and the command palette was the same colour as the list around it. It now has a bar on its leading edge and an outline.
- An accessibility issue says which elements fail. Expanding an issue in the accessibility panel showed the rule and its description, but not which element failed unless you could see the preview highlight. It now lists every failing element with its markup, and a screen reader reads the markup with each element. An element picked out by an attribute, such as an image's file name, is no longer labelled with a fragment of it.
- Fix with AI and Add to chat can be said by voice control. In an expanded accessibility issue, their spoken names were "Fix <issue> with AI" and "Add fix for <issue> to chat", so saying the words on the button did nothing. They are now "Fix with AI: <issue>" and "Add to chat: fix for <issue>".
- Enter in the page rename field saves once. On Windows, Enter saved the new name and then opened the rename field again.
- Notifications expire again after Undo. After you pressed F6 to reach a notification and chose Undo, no later notification ever went away on its own.
- The disabled canvas modes name the right control. With the code view open, Edit section, Add section and Link pages said to choose View rendered preview, which is only a tooltip. They now name the control as it is spoken, View and edit HTML source, so voice control can use it.
- Closing the command palette returns to the control you were on in the preview. A palette opened from inside the preview returned focus to the preview page rather than the control.
- Edit section stays on while the Sections list is open. After you chose a section, the toggle read as off while the list was still showing; choosing it again now closes the list.
- Generation progress no longer covers the preview toolbar. The progress card and the journey summary covered the toolbar's Link pages and Distraction-free buttons, so a keyboard user could reach controls hidden under them. They now cover only the canvas.
- Clear conversation and Delete project start on Cancel. Both asked in the system's own dialog, which always starts on its first button, so pressing Enter cleared the conversation. They now ask in the app's own dialog: Cancel comes first and has focus, and Escape cancels. Escape in the Delete project confirmation closes only the confirmation, not the Projects dialog under it.
- Version history works from the keyboard. Opening it moves focus to the newest version's Restore button, instead of the panel being reached only after the whole preview; Escape closes it and returns to the Versions button; and after a restore, focus goes to the panel's heading rather than the whole panel being read out. The Versions and SR tree buttons now say whether their panel is expanded.
- Screen readers hear fewer repeats and run-together words. From the NVDA test of 0.7.0:
- a section change's outcome is read once, from the chat reply, not also from its notification;
- the model status (Warming up…, Ready) is read once per change;
- a tab chosen with the arrow keys is read once, already selected;
- two messages that arrive together are both read, instead of the second replacing the first;
- names no longer run together: the chat transcript button, Command palette: Search, the export review's Review buttons, accessibility issues, a project's version and page count, and each manual check's parts. The accessibility panel's severity groups are headings.
- More is said out loud. The automatic accessibility check after a change is announced with the Accessibility panel closed. Showing or hiding the page list and zooming the interface from the keyboard say what they did. A tour's first step is read when it opens. After an export, up to three warnings are read with the success message, where only their heading was read before.
- Less is read out. The chat transcript folds a reply's HTML behind Show generated HTML instead of reading it line by line. Each model in setup is described by what it is for, its size and memory, its quality and any caution, instead of its whole card. The chat box's description no longer repeats its name, and the start page's star in the journey map is read as "start page".
- The page list closes like an overlay in a narrow window. Below about 770 pixels wide, or at high interface zoom, the open page list covers the preview toolbar and the chat box. Escape now closes it and returns to the page-list button, a click or focus outside it closes it, and the canvas behind it is dimmed.
0.7.0
2026-09-26An accessibility release for the app itself. An audit of the app's own interface against WCAG 2.2 AA and Section 508, followed by keyboard testing against the macOS accessibility tree, led to fixes across keyboard focus, screen-reader announcements, control names, contrast and focus outlines, a keyboard route into Edit section, and interface zoom up to 200%. These fixes have been checked with automated tests and by keyboard, not yet with a screen reader; the new accessibility statement says what that means. Add section no longer fails on a section wrapped in the page frame, runs without showing progress, or turns down components the pack has, as it could in 0.6.1. On the built-in llama.cpp runtime, GOV.UK and USWDS pages are held to the pack's own class names as they are written, USWDS shows the model the example that matches your request and the pattern for the kind of page, and Gemma 4 E2B on Windows launches without reasoning. Journeys take their questions from the answers your description lists, ask before regenerating over your pages, and give every new Page a Path of its own, and a refinement says Updated only when the page changed. DADS prototypes gain Japanese page furniture and measured quality levels for six models, and stopping the local AI on Windows no longer pauses for two seconds.
Added
- Exports ask you to check accessibility first. Before a testable-prototype ZIP or Prototype Kit export (from the button or ⌘E), the app lists pages whose last check found open accessibility issues, or that have not been checked since they changed. Each page has a Review button that opens it in the Accessibility panel; Export anyway goes ahead and keeps the list with the export warnings. The Prototype Kit project now includes ACCESSIBILITY.md, the manual checks the prototype still needs, like the ZIP and evidence exports.
- Keep notifications open until you close them. A new Settings → Appearance option turns off the time limit on notifications. Press F6 to jump to the latest notification and F6 again to go back; Escape closes it.
- Move pages up and down without dragging. The current page's actions now include Move up and Move down, and the page-list divider has preset widths on double-click and Home/End keys.
- An accessibility statement and a keyboard guide. docs/accessibility-statement.md sets out the standard the app aims for (WCAG 2.2 AA), what has been tested, known limitations and how to report a barrier. The user guide has a new section on using the app with a keyboard or assistive technology, and Settings → Help & feedback has a short Accessibility summary.
- Interface zoom for low-vision users (WCAG 1.4.4). ⌘+ / ⌘− / ⌘0 (Ctrl on Windows) now zoom the whole app from 90% to 200%, and Settings → Appearance has an Interface zoom control; the choice is remembered. Previously the app could not be zoomed at all. The preview toolbar keeps its own canvas zoom when it has focus. At high zoom the layout reflows instead of hiding the preview: the page list opens over the canvas, secondary preview tools fold behind Preview controls, and the chat dock stays compact.
Changed
- The built-in model can no longer invent GOV.UK or USWDS class names. A local model's most common mistake on these packs is a class that looks right but does not exist, such as usa-button--primary, which the quality check then flags or a repair turn has to fix. When a model on the built-in llama.cpp runtime writes GOV.UK or USWDS markup, it is now held to the pack's own list of govuk- or usa- classes as it writes, so it cannot spell one that is not on the list; the rest of the markup is written as before. MOJ pages get the same, because they generate on GOV.UK, and their moj- classes are left free. In the checks that decided this, a model that already used only real classes scored the same, and one that did not stopped inventing them, at about the same speed. Models on MLX, Ollama and LM Studio are unchanged, and so are NHS.UK, NSW, Bootstrap Italia, Scottish Government, DADS and Abstract until each has been checked on its own. One limit: the list is the app's own, so a real class missing from it can no longer be written either.
- USWDS pages follow the variant you ask for and the kind of page more closely. For each component it retrieves, the app shows the model one example. On every pack that was the component's first example whatever you asked for, so a request for a warning alert or a bordered accordion showed the model the informational alert or the default accordion. On USWDS the example is now the one whose name best matches your request, and a start, form, check answers or confirmation page always gets the matching USWDS page pattern first, with at most one component alongside it. The form patterns' examples now carry a placeholder form action, so a page modelled on them keeps one for the app to point at the next Page. The prompt is no larger than before. A small model can copy a pinned pattern too closely, most visibly on a start page. Other packs are unchanged until each has been checked on its own.
- Gemma 4 E2B on Windows launches with reasoning switched off. It thinks before it answers by default, and on a page that thinking took about half of its output. The bundled llama.cpp server now starts it with thinking off, as it already does for Qwen3.6 35B-A3B. In the check that decided this, its GOV.UK pages scored as well or slightly better overall and took about half as long. Gemma 4 E4B and Gemma 4 12B Coder launch as before, and on macOS Gemma 4 E2B runs on MLX, which is unchanged.
- Prototype quality is now stated for six models on DADS. The model card and pack picker showed Not measured for every model on the Digital Agency Design System (Japan). The catalogue now records the levels from the 2026-09-17 DADS battery for six models on the built-in llama.cpp runtime: Qwen2.5-Coder 7B and Qwen 3 8B on both platforms, and Gemma 3 12B, Gemma 4 E4B, Gemma 4 E2B and Qwen2.5-Coder 1.5B on Windows. They were measured on English-content pages before the native review of the pack's Japanese guidance, so a re-run is owed after it. Gemma 4 12B Coder stays Not measured on DADS: under the app's launch settings it spends its output thinking on DADS pages, and no level is assumed for it. MLX models are not measured on DADS.
- DADS prototypes carry Japanese page furniture. The skip link, prototype marker, footer and default service name around a Digital Agency Design System (Japan) page were in English — Prototype, Skip to main content, Privacy, Cookies and Accessibility links, and "not a real government service" — on every Japanese page. They are now Japanese: the marker reads 架空・試作 (fictional prototype), with a line saying the page was made with Prompt to Page and is not a real government service, and the skip link reads 本文へ移動. Each piece of fixed text is marked as Japanese, so assistive technology reads it as Japanese even on a page whose content is English, and a service name you supplied is left in the language you wrote it in. The preview, a LAN share and the exports all use the new furniture, and existing projects pick it up without regenerating. The Japanese text was written by a non-native author and is listed for native review.
- A journey asks for the answers your description lists. Service templates are shared by every pack, but their default questions were written for GOV.UK: Register for something planned a National Insurance number, which a DADS project turned into a Japanese version of a UK identifier. And answers your description asked for never reached the plan, so no page asked for them while check answers still listed them. The template now sets only the order of pages. When the description lists what the service needs — two or more short items after words such as asks for or a heading such as Required information:, or in Japanese before 「が必要」 or after a heading such as 「必要な項目:」 — those are the journey's questions. An answer that matches a template question keeps its page; every other one gets a question page of its own before check answers, named in your words, and choices in brackets become radio options. Template questions you did not list are dropped. A description that lists no answers keeps the template's defaults, which no longer include a National Insurance number anywhere (Check something now asks where you live); if you need one, list it. The Describe your service field in the template picker now says this, with an example.
Fixed
- A Prototype Kit hand-off's check answers shows the answers given. The exported check answers view joined a row to its question only when the row's key matched the question's label word for word, so a date asked as day, month and year, or a question whose wording differed from the row (What type of permit do you need? for Type of permit), kept the sample from the generated page — while the exported README said the page showed what the user typed. Rows are now joined first by the answer the row names, as the preview and the testable ZIP already do, then by label, and a date group also by its legend. A date shows its parts as typed and a radio answer shows the option's label. A row the export cannot join, or an answer left blank, still shows the sample text, and the README now says so.
- Naming a component asks fewer questions. A request such as Add a warning text or Add radios asking if they are over 18 used to go to the local model to decide whether it adds or changes something, and a small model's answer could come back as Insertion. or wrapped in formatting, which the app read as unsure and turned into an Add or change? question. A request that names a real component is now treated as adding a section straight away, and the model's answer is read correctly with a trailing full stop, quotes or formatting around it. A request aimed at something already on the page — Add hint text to the date of birth — still asks, because it may be an edit.
- Choosing a section for a cleared request says so. Clearing the conversation while the preview waited for you to pick a section to change left the preview waiting, and picking a section then did nothing. It now says the request is no longer waiting for a section and asks you to send it again, as Add section already does.
- Add section no longer fails when the model wraps the new section in the page frame. The page system prompt tells the model to begin every page with the design system's page frame (for GOV.UK, the width container and main element), so a small local model can answer an Add section request with the new section inside that frame. The app rejected that as a whole page, asked once more, and then reported Insertion failed. A response that wraps only the new section is now unwrapped and inserted on the first attempt, after the same checks as any other section. A response that repeats content already on the page, or adds a page heading, is still refused, because inserting it would duplicate the page. The instructions for Add section also name the frame's classes, both first time and on the retry.
- Add section shows its progress again after you answer a question. In 0.6.1, when a request stopped to ask something first — Similar section found, Component unavailable, Add or change?, a scope conflict, or the whole-page change confirm — answering it started the generation with the progress card, elapsed time and preview Stop control switched off. On a local model that meant tens of seconds to minutes with no sign anything was happening, and then the page changed. The answer now restarts the progress card for the operation you chose, and it clears as before when the run ends.
- Choosing where to add a section never does nothing. Clearing the conversation leaves the preview in Add section mode, and choosing an Add here point for the request that had just been cleared silently did nothing. The same was true if its Page had been deleted or the conversation rewound. The app now says the request is no longer waiting for placement, marks it as not run, and asks you to send it again.
- GOV.UK no longer calls its own hint and text input components unavailable. Before adding a section, the app checks whether a named component exists in the Page's design system. It recognises every pack's spelling of a component, but only accepted the active pack's exact name, so Add hint text to the date of birth and Add an input for postcode asked whether to Create an equivalent of something GOV.UK has (Scottish Government calls it hint-text, NHS calls it input). A requested name now counts as available when every word of it, less words like text or field, appears in one of the pack's own component names. Components the pack really lacks — a multi-select, a search input, a date picker — still ask.
- Disabled canvas modes say how to re-enable them. Edit section, Add section and Link pages are unavailable while the HTML source view is open, and the code view stays open when you switch Pages, so the buttons could sit greyed out with only the reason given. Their tooltip and screen-reader description now also say to choose View rendered preview.
- Starting a journey asks before it regenerates over your pages, and keeps their history. A journey plan takes over any Page already at one of its Paths. The app asked first only when an earlier journey existed, so a first journey could regenerate over a start page you had designed, or any other page at a planned Path, without a word, and that page's Version history went with it. The confirmation now names every page with content that the new journey would regenerate over, on a first journey too; blank pages are still taken over without asking. A page that is regenerated over keeps its Version history, with the version it replaced saved as Replaced by journey generation, so you can restore it.
- Pages with the same title no longer get mixed up. A new Page took its Path straight from its title, so two pages with the same title shared a Path, and a title with no Latin letters, such as a Japanese one, became / and clashed with the start page. The preview and exports find pages by Path, so links could land on the wrong page. A new Page now gets -2, -3 and so on when its Path is taken, and /page-N when its title has no Latin letters; renaming a page to such a title keeps its current Path instead of being refused. In the page list, pages that share a title now include their Path in their names, so voice control and screen readers can tell them apart, and every thumbnail shows its Path as a tooltip.
- A Page's title follows its heading. A journey page is named after its h1, but the name stayed put when the h1 changed, so the page list and exports kept an old title after a Code edit, a refinement or a Version restore. While a Page's title still matches its h1, it now follows the new h1 whenever the page changes. A title you renamed yourself is kept, and the Path never moves.
- The evidence export no longer writes DADS versions as "vv". Pack versions that already start with a v, such as DADS's dated v20260825, appeared as vv20260825 in the assessment evidence record. They now appear once.
- A refinement says "Updated" only when the page changed. A change asked for in the chat could reply Updated: Button. when the model had handed the section back exactly as it was, with no new entry in Version history. When one of three fields with the same label was refused, the reply did not say which one, or what to do next. The reply now says Updated only when the page actually changed. Every other section is named by its label and first visible words — Form control label “Date of birth” — in page order, with the reason it was left alone, and a reply that changed nothing or refused a section ends with what to try: select the section and describe only that change, or delete it. The partial-success notification counts every section the request reached. Other fixes in the same path:
- A reply that repeats the fields next to the one you asked to change is no longer refused outright. The repeated copies are dropped and the rest must pass every check, and a section with form fields is shown to you for review first.
- Regenerate on a form with several fields of the same kind re-runs those sections instead of falling back to the whole page.
- A change that only removes a space between inline elements, or changes text inside a pre or text area, is no longer mistaken for no change and thrown away.
- A refinement leaves out the sections you say to keep. Before regenerating anything, a refinement asks the model which sections the request is about, and a request such as change the date of birth, keep the Next button as it is could pick the button too, so it was regenerated for nothing. That question now asks which sections the request says to change, and to leave out any it mentions only to keep. It is an instruction to the model, not a guarantee: in testing, a small model still sometimes missed a section it should have changed.
- Typing Japanese, Chinese or Korean no longer commits half-converted text. On macOS, the Enter that confirms an input-method conversion also counted as Enter, so renaming a page, the chat box, the command palette search, the journey description and ⌘Enter in the HTML editor acted on text you had not finished converting. They now wait for the conversion to finish, and the arrow keys and Escape no longer act on a list or a rename while you are converting.
- Form fields and selected tabs are easier to see. Text boxes, selects and text areas had edges of about 1.3:1 against the background; they now meet 3:1 in both themes. Selected tabs and segments (the Tools tabs, Journey tabs, template categories, Settings sections) now have an outline as well as a fill, and in Windows High Contrast they use the system selection colours.
- Undo notifications no longer vanish in 3 seconds. A notification with an action stays at least 10 seconds and pauses while the pointer or keyboard focus is on it. Notifications move to the top of the window when they would cover the control you are using, and their buttons are larger.
- Page thumbnails no longer take keyboard focus. The small previews in the page list could hold hidden Tab stops for the links inside them.
- Dragging a page reads out page names. Screen readers now hear "Picked up Start" and "Start is over Your name" instead of internal ids.
- Controls are named the way they look, so voice control and screen readers can find them. Several buttons had a spoken name different from their visible text, so saying what you see ("click Rotate", "click Map") did nothing, and some had no useful name at all:
- Edit section, Add section and Link pages keep one name and show on or off as a pressed state, instead of switching to "Selecting…"/"Adding…"/"Linking…".
- The back and forward arrows, the size buttons (S, M, Tab L…), the zoom readout, and the Journey and Export panel arrows have real names.
- The page switcher, Checkpoints, the chat transcript toggle, Search, the Tools tabs and the setup screen's Back button now include their visible words in their names.
- The code-view button keeps one name ("View and edit HTML source") and shows on or off as a pressed state, instead of also renaming itself "View rendered preview".
- Distraction-free and the footer's density button say their state in their names only ("Exit distraction-free mode", "Density: Compact"), and no longer also report pressed.
- Sections are named in words: "Heading (large)" instead of "Heading l", which screen readers read as "Heading el". This applies to the Sections list, the section actions, the Refining label in the chat box and the Deleted notification.
- In Projects, each project's Open, Rename, Duplicate and Delete buttons include the project's name, and the project list is read as a list.
- Forms read correctly to screen readers. Radio buttons in Settings → Local AI, the New page dialog and first-run setup are grouped under their questions ("Model source", "Start from", "What to carry over"). Each model in the model picker is read by its name, with its details as a description, instead of about sixty words at once. Theme and density take the arrow keys like other radio buttons. Field hints are read with their fields, and the reply-email fields can be filled in by the browser.
- The / and @ suggestions in the chat box are read aloud, and work from the keyboard. When suggestions open you hear how many there are, and the arrow keys now read out the highlighted command or page. The arrow keys also now move the highlight: before, it snapped back to the first suggestion when the key was released, so Enter always inserted the first one. Escape now keeps the list closed instead of reopening it. On macOS the highlighted suggestion is now exposed to VoiceOver as you move: the chat box is a combo box, as the command palette is.
- Edit section works without a mouse. Choosing a section used to need a click inside the preview. Turning on Edit section now also opens a Sections list beside the preview.
- Arrow keys, Home and End move through the page's sections; each one is outlined and scrolled into view in the preview. While the list is open, the preview moves over so the list never covers the section it outlines.
- Enter opens the same section actions as a click, with focus on the first available action. Escape returns to the list.
- After Delete, focus stays in the list, and the Undo notification now stays for 10 seconds instead of 3. Undo then says "Restored …", or that the deletion can no longer be undone, instead of nothing.
- Done or Escape closes the list and returns to the Edit section button.
- Closing the section actions no longer reopens them. The preview and the app kept re-sending each other the selected section in a loop, so closing the actions popup could bring it straight back. A section you refine now stays selected on purpose, so you can refine it again straight away, as it did before. Its actions stay closed when the change finishes, so focus stays in the chat box instead of jumping to Move up.
- More keyboard and screen-reader fixes from assistive-technology testing.
- Announcements are heard while a dialog is open. With Settings or another dialog open, messages such as a Settings error were not exposed to screen readers at all on macOS. They now are.
- Shortcuts work from inside the preview. ⌘K, ⌘1–4, ⌘B, ⌘E, ⌘S, F6 and the zoom shortcuts did nothing while keyboard focus was in the preview. ⌘1–4 now also move focus to the tab they open, and ⌘. no longer drops focus when it closes the tools panel.
- Errors in Settings belong to their field. An out-of-range port is marked invalid, described under the field and focused, instead of appearing in a general error box that also opened troubleshooting guidance.
- Focus is kept when a control changes or disappears. After choosing where a link or button goes, focus returns to it rather than to the page. After Create page (now also announced), Re-check this page, Fix with AI, an export, starting or stopping the share server, and restoring a version, focus used to fall to the top of the window.
- More things are announced and named. Export results, adding a planned link and restoring a version are announced. Version history buttons say which version they restore, planned links use page titles ("Start page to Your name") instead of addresses, and the screen-reader tree and Version history no longer run the role or time into the text.
- First-run setup works from the keyboard and with a screen reader. Choosing Ollama or LM Studio used a custom radio card that swallowed Enter, Space and the arrow keys, so its Re-check and Edit server URL buttons could not be pressed from the keyboard, arrow keys in the Server URL and Model fields switched runtime instead of moving the cursor, and a space could not be typed. Each card now holds a real radio button (arrow keys move between runtimes, and each one announces its description and status), and the controls inside the selected card behave normally, and Re-check keeps keyboard focus while it checks instead of dropping it to the top of the page. The setup screens also now expose a main landmark.
- Dark mode: primary buttons and status fills are readable. The Create page and New project buttons were white text on a near-white fill (1.04:1), and success/error banners, the accessibility panel's Fix button and the page-delete confirmation had white text on pale fills. They now use theme-aware on-colour tokens (dark text on dark mode's light fills). The troubleshooting panel no longer shows near-white text on a light grey card in dark mode, and the Tools rail's "serious" issue badge uses dark text on its orange fill in both themes.
- Light mode: status colours meet contrast. The green used for success and accents, the red for errors and the amber for warnings were too pale to read as text (3.1–4.5:1) and too pale for the white text on green and red buttons and toasts (Choose a template, the active viewport button, success and error toasts). They are now deeper shades — emerald #047857, crimson #be123c, amber #92400e for warning text — each at least 4.5:1 on every surface and under white text. Warning headings, urgent notices and code highlighting use the warning text colour; the preview's Landmarks and Headings overlay labels are readable; and a Delete action that referred to a colour token that did not exist now uses the error colour. Dark mode is unchanged.
- Every control shows a clear focus outline. Text fields (including the chat composer, Settings, setup, New page and Projects), the Accessibility panel's controls, the page-list search and rename fields and the resize handle used only a faint glow (about 1.4:1) that disappeared completely in Windows High Contrast. They now draw the same solid 2px focus outline as every other control, which High Contrast keeps. Dark mode's focus colour is lighter (#60a5fa), so the outline stays visible on dark panels.
- Keyboard focus no longer gets lost. Opening a tool from the right-hand rail moves focus to its tab, and closing the panel returns focus to the rail. The Checkpoints popup and the page switcher return focus to their button on Escape or after choosing. The page switcher now works like a proper menu (arrow keys, Home and End), and each Restore button says which checkpoint it restores. Selecting, renaming or deleting a page from the keyboard keeps focus in the page list, and deleting asks "Delete this page?" with focus on No. The getting-started tour starts on Next, keeps Tab inside itself, announces each step and returns focus when it ends. The command palette's results are no longer separate Tab stops. Choosing an exit's destination returns focus to the preview. Switching views in the Projects dialog moves focus to the new view. The Journey map's tabs follow the arrow keys. Submitting a prompt keeps focus in the composer (it is read-only while generating instead of disabled).
- Errors and progress are read out to screen-reader users. A blocked setup, a failed Settings save or model check, and a feedback or error report that couldn't be sent used to appear silently. They are now announced straight away. Startup phases ("Phase 3 of 4 · Starting the built-in model…") are announced as they change, and journey generation announces each page as it starts and the result at the end. Each page's status there is now written in text (Done, Generating, Failed) rather than shown only as a symbol and colour, and each Retry button names its page.
- Screen readers no longer read whole pages of HTML or re-read long lists. When a page is generated you now hear "Page generated." (or "Change generated.", "Section generated.") plus any note from the model, never the page's code. Opening the chat transcript no longer reads it aloud. The model download announces each 25% step and each phase instead of re-reading the whole checklist several times a second, and its progress bars have names. The Accessibility and Validation panels announce one summary when a check finishes ("Accessibility check complete: 4 issues — 1 serious, 2 moderate, 1 minor.") instead of re-reading their results. Notifications are announced reliably, with errors announced first.
- Stopping the local AI on Windows no longer pauses for two seconds. In 0.6.1, Stop, Restart local AI, a backend switch and app quit each waited the full 2 s port-release cap on Windows (about 330 ms in 0.6.0) even though the sidecar had already let go of its port. The stop path gave each connection probe the whole remaining cap as its timeout, and Windows refuses a connection to a closed loopback port only after about 2 s of SYN retransmits, so the first probe after the sidecar died blocked until the deadline. Each probe is now capped at 250 ms, the budget the startup port check already used; the 2 s cap on a port that really is still held is unchanged. The fix applies on both platforms so the installers stay on one source. macOS and Linux, which refuse a closed port immediately, were not affected. Recorded as W-WIN1 in the 0.6.1 smoke record.
0.6.1
2026-09-14A journeys release. A prototype can now branch: choose a question on a Page, say which answer goes where, and the preview, a LAN share, the testable ZIP and a Prototype Kit hand-off all follow the same decision. The rest of the release is about a Journey being honest about what it knows — renaming a Page heals the links and form actions that pointed at it, Retarget leaves one active connection per pair of Pages, and a question with no destination is reported as a decision still to make rather than quietly pointed at whatever page comes next. Each Page now also records which model and runtime produced or refined it, and that record is carried into the assessment evidence record instead of being guessed at export. The local AI handles Stop during startup, a managed restart and a failed retry without losing the reason it failed. A failed library save, a late model result landing in another project, and the preview accessibility work from 0.6.0's review are fixed here too.
Added
- Send people to different Pages depending on what they answered. A Page with a named radio group, single-select or checkbox group on one unambiguous form now offers Route by answer in the Journey tab. Choose the question, add rules — If Age group is Under 18 go to Junior application — and set the required Otherwise go to destination for a valid answer that matches none of them. Rules are checked in order and the first match wins; a checkbox answer that satisfies two rules takes the first one listed. Move up, Move down and Remove rule each name the rule they act on — "Remove rule 2" — so a screen-reader user knows which rule the control affects. The preview navigates from the answers actually submitted on that Page, never a value remembered from an earlier visit, and the design system's own validation still runs first, so an unanswered required question stays where it is. Restart clears the recorded visits and returns to the start Page. The same decision travels with the testable ZIP export, a LAN share and a Prototype Kit hand-off, where the generated route reads the submitted answers rather than stored session data. If a decision can no longer be matched to its form — the question renamed, an option removed, the Page regenerated — the problem is reported and the advancing control stays unavailable, rather than the prototype falling back to a straight line without saying so. This first version is deliberately small: one decision per Page, on one form and one question. Numeric and free-text comparisons, conditions drawn from an earlier Page, and clearing the answers that sit behind a branch you have changed are not in it, and an answer given before a branch changed can still appear on a check-answers Page.
- Each Page records which model produced it. When a generation is accepted onto a Page, the app records the model and the runtime that produced it, and adds a record for each later model-assisted change, keeping the most recent contributions rather than an unbounded log. The record is written with the project, comes back with the Page when you undo or restore from Version history, and travels with a Checkpoint. The assessment evidence record now describes those contributions per Page instead of naming one model for the whole prototype: a Page that several models touched lists each of them, a Page you edited by hand says it was manually edited after generation, and a Page made before this release says its generation details were not recorded. A catalogue quality measurement is attached only where the recorded model, runtime and pack version can actually support one, and it is labelled as read from the catalogue at export rather than a score for that Page; where it cannot be paired, the reason is given instead. Measurements from different contributors are never combined into one figure.
Fixed
- A Prototype Kit hand-off now walks the same route as the preview. Every exported view kept the Page it advances to as its form action, while the routes generated alongside those views are keyed on the Page the form was submitted from. So each submit landed one Page too far: an intermediate Page was stepped over, and a Route by answer decision was never reached. Walked for real, two of six Pages in a hand-off could not be reached at all. An exported form that submits an answer now posts to its own Path, so the kit follows the Journey the prototype describes. A form that only fetches a page, a placeholder action, an address outside the prototype and a destination the prototype cannot resolve are left exactly as they were. Hand-offs taken before this release carried the same off-by-one on a straight-line Journey.
- A check answers Page in a Prototype Kit hand-off now renders. The exported template for a summary list closed one of its values with a pair of braces that the kit's template engine reads as the end of an expression, so the view could not be parsed and the kit served an error page in place of the Page. Copy Nunjucks produced the same text. Both now close that value cleanly. This was not new in this release: no hand-off with a summary list had rendered its check answers Page before.
- A check answers Page shows the date you typed, not the sample in the generated page. A summary row for a question asked as separate day, month and year inputs could not be joined to a single stored answer, so the row kept the example date the model had written into the page and presented it as your answer — in the preview, the testable ZIP and a LAN share, on every pack. Such a row now shows the parts as they were typed, and a row that still cannot be joined, on a Page where other rows were, shows the design system's own "not provided" wording instead of leaving an invented answer in place. Two limits: the parts appear as typed rather than as a formatted date, because month names would read in English on a prototype written in another language; and where the generated inputs are named differently from the question the row is keyed to — as they are on NHS.UK — the row shows that placeholder rather than the date.
- Renaming a Page no longer leaves the Journey pointing at the old one. A rename now updates the Page's slot in the Journey plan as well as the Page itself, so a retry or a resumed generation works from the current plan instead of restoring the previous Path, and a rename that would collide with another Page's Path is refused. Healing a rename rewrites the destination carried on a submit button as well as those on links and form actions, including a control that sits outside the form it submits. Retarget now leaves one active planned connection per ordered pair of Pages, with superseded records kept as history. And a submit button's own destination no longer quietly overrides the form action the plan just set: the effective destination of each advancing control is resolved against the plan.
- A question with nowhere to go is reported instead of being given a route. When a generated page had an advancing form and the plan recorded no next Page, the guidance taught the model a made-up /next-step route and the corrective pass then tried to make it real. That route is no longer taught, and a form whose action is missing, empty or a bare # is raised as a quality warning — "This form has no usable destination. Set a next page or leave the page as a journey end." — for you to resolve. It counts as an error only where the plan did record a destination and the page ignored it. A confirmation Page is left alone: a Page that genuinely ends a Journey needs no advancing control, and one is not invented for it.
- A Prototype Kit hand-off no longer hides an unresolved destination behind the next page in order. A form whose destination was invented, empty, a bare #, or a Path the prototype does not contain used to be wired to whichever page came next in Journey order, so the exported kit walked a route the prototype had never actually connected. Such a form now gets no forward route at all — the kit still serves the page — and the unresolved destination stays visible where it can be fixed. The testable ZIP already warned about a placeholder form action rather than inventing a destination for it; that is unchanged.
- Stop, restart and retry for the local AI are more predictable. Pressing Stop while the local AI was still starting left that launch to finish on its own, so a model could come up moments after you asked for it to go away. A stop now revokes a launch that has not yet produced a process, and reaps one that appears late. A managed restart — from Settings, or from the app's own recovery — checks that the previous process has gone and its port been released before starting another, and refuses to start over it if not. A retry that fails now keeps the specific reason on screen: the connection card used to replace it with a generic health-check message, leaving nothing to act on. Overlapping Retry presses collapse onto one restart.
- Page thumbnails use each Page's own design system. In a project whose Pages sit on more than one design system, every thumbnail in the page rail was painted in whichever system was currently active, so a Page could be shown in a system it was not built in. Each thumbnail now renders from the design system that Page records, without switching the active one.
- NHS.UK, USWDS, NSW and Bootstrap Italia Pages get their own Journey guidance. Generating a Page from a Journey plan on those packs fell back to the GOV.UK wording, so the model was shown GOV.UK class names on a page that cannot use them. Each of those four packs now carries its own page guidance.
- Preview canvas actions are keyboard-reachable and stay out of the code editor. Edit section, Add section and Link pages disable while the HTML source view is open, with an accessible explanation. Command-palette shortcut badges keep their visual chips and announce each binding once. Zoom in, zoom out and zoom to fit are available from the command palette and from ⌘=/⌘-/⌘0 (Ctrl on Windows) when the preview toolbar or canvas is focused — editors and dialogs keep native document zoom.
- Start badges, icon buttons and high-contrast chrome are readable. The Start badge uses accent-hover text on the strong surface (light 5.32:1, was 2.87:1). Icon and chat-dock controls are 40px in both densities. Forced-colors mode keeps focus, selection and control borders in system colours.
- Preview zoom and canvas panels now share one layout policy. Fit and zoom-out use the same 25–200% range. Fit mode remeasures the canvas after a preset or size change; a manual zoom stays where you put it and the page stays reachable by scrolling. Accessibility overlays collapse behind Overlays when the preview column is narrow. Screen-reader tree and Version history cannot be open together, and closing either returns focus to its control. The loading pill sits on the visible canvas instead of scrolling with the page.
- A failed library save is no longer silent. Automatic writes and project actions (open, new, rename, duplicate, import, delete) now return an explicit result. A failed prerequisite save keeps the current project; Retry saving writes the latest live snapshot; Checkpoints and Export project file stay separate from library health.
- A late model result can no longer write into a different project, page, or conversation. Opening or restoring a project — including the same project id — stops the previous request and discards its page, transcript, review, clarification, parked placement and journey outcomes. Navigating to another page in the same project still lets an already-started generation finish on the page that accepted it. Clearing a conversation no longer leaves a cancellation reply behind, and Stop cannot let the cancelled request clean up the next one.
- Editing or regenerating a section change no longer silently rewrites the whole page when that section cannot be reconstructed. If the earlier version has been pruned, the stamps are missing, the page has changed, the turn is an earlier request, or the transcript never recorded which operation ran, the app now asks before a whole-page rewrite. Cancel leaves the page, transcript and any open draft untouched. A last section change that still has its base in Version history keeps repeating as a section change. Legacy replies are treated as unknown rather than guessed into a page rewrite.
- A refinement that would drop or replace form fields no longer applies without asking. The regression that started this work — refining a date fieldset to “add hint text” and receiving only the hint — now shows what would be lost (day, month and year) and waits. Cancel keeps the page; Apply reviewed change commits exactly that candidate and puts the previous page in Version history. A hint or label edit that keeps the same fields still applies with no extra question. Delete block and a hand-edited Apply are unchanged: those are deliberate edits, not model output.
Changed
- Internal: the GOV.UK class measurement is narrower and better evidenced. The measurement behind the class figures quoted about GOV.UK Frontend now judges each custom-class pass-through against the fixture and options it appears in, so a naming pattern can no longer explain away an ordinary second use, and the HTML harvest reports fewer things as findings. The earlier report is kept alongside it as a superseded record, and the shapes the packs are built from are now written down with their owners and consumers. No app behaviour depends on any of this.
0.6.0
2026-09-12A speed and correctness release for the first thing you ask of a page. A page that needs a form used to be generated twice — the quality check flagged the app's own back link as a dead button, so the corrective pass fired on almost every run and could never clear it. It now fires only when something is genuinely wrong, and the page guidance states the form contract up front, so a form page arrives in about half the time. MLX models on Apple Silicon could not start at all in 0.4.2 through 0.5.2 — including the one the setup wizard recommends — and when they do start they now receive the curated instructions that every model in the catalogue was measured against, which they never had. Accessibility checks run once per change rather than twice, run again after you switch page, and wait for a quiet moment instead of landing in the middle of your typing. A corrective pass can no longer replace a finished page with a fragment.
Fixed
- MLX models could not start at all on Apple Silicon, in 0.4.2 through 0.5.2. Choosing any MLX model — including the setup wizard's own pre-selected recommendation for your Mac — failed with "the bundled MLX Python runtime is missing", and the message told you to reinstall, which could never have helped: every installer since 0.4.2 had the same layout. Nothing was actually missing. The app checked for the Python runtime under one filename while the build had been producing another since 0.4.2, so it refused to launch a sidecar that was present and working. The fix that made MLX work on macOS 14 and 15 in 0.4.2 is the same change that introduced this, which is why the 0.4.2 notes report that one as fixed. The check now accepts either filename, derived from the same rule the build uses, and the release build and our CI both now ask the app itself whether it would start the bundled sidecar. If you tried an MLX model in the last three weeks and concluded something was wrong with your setup: it was not. The llama.cpp backend, which is the default and the only one Windows uses, was never affected.
- The MLX backend was generating without its instructions. On Apple Silicon, page generations routed to the managed MLX engine were grouped with the external backends (Ollama, LM Studio) and sent as a bare request — no system prompt at all. Every MLX model in the catalogue had its prompt profile measured on a shape the app never actually sent. Both managed engines now get the curated instructions; Ollama and LM Studio keep the messages they expect. Measured on the same page and model: quality went from failing at 80 to passing at 85. This buys quality, not speed.
- A form page no longer costs two generations. The quality check's "no placeholder primary actions" rule flagged the back link the app itself adds to every page, whose destination the app owns, so the score could never pass and a corrective pass ran on almost every page — paying for a second model round trip that had nothing to fix. The design system's own back-link class is now exempt from that scan; dead form actions and links that go nowhere still flag. Form pages are also now told up front that inputs and a submit button belong inside a form, and the example destination names the route the journey already plans rather than a placeholder the checks would reject. Measured across two sittings on the bundled default model: a form page that needs no corrective pass arrives in about 30 seconds, against 52–58 when one runs — about half the time. Pages are also now accepted on the first pass with the back link present, which the old rule made impossible. The corrective pass is not gone, though, and on the measured runs most pages still took one for other reasons. This release removes a cause that could never be satisfied; it does not make the corrective pass rare.
- A corrective pass can no longer replace a finished page with a near-empty one. That pass is sent the page plus the list of things to fix — and on a long page in a dense design system, that can leave the model almost no room to reply inside its context window. It would then return a fragment, and the fragment replaced the complete page, presented as a success. A pass that collapses the page is now rejected and the original kept. Deciding this on the quality score would not have worked: the score counts defects, and a near-empty page has almost none, so it scored higher than the full page it replaced.
- Accessibility checks run once per change, and run again after you switch page. Pressing Check while the automatic check was still waiting out its delay ran two scans of the same page. Separately, the order in which page switching cleared results and armed the next scan meant the new page's automatic scan was cancelled the instant it was scheduled, so switching page never produced a check at all. Both are fixed. Navigating away mid-scan now abandons the request in a few milliseconds instead of leaving it waiting out a fifteen-second timeout.
- Typing no longer waits for an accessibility check that starts mid-sentence. The scan engine holds the main thread for as long as it runs, so an automatic check beginning inside a burst of typing added the rest of its run to that keystroke — measured at 43–47 ms to paint on a 40-field page and 96–107 ms on a 100-field page, against about 17 ms when idle. Automatic checks now wait for an idle moment after their existing delay, with a two-second ceiling, so a scan is deferred but never dropped. Checks you ask for yourself still run immediately — the wait is the result you are waiting for.
- An NHS.UK class that does not exist is no longer offered to the model. The NHS pack's allowlist carried a single-underscore typo of the header logo class that is not a class in NHS.UK Frontend. It is now removed and denylisted, so neither an additive merge nor a harvest can re-admit it.
Changed
- Accessibility checks keep their engine loaded on demand rather than pulling it into startup JavaScript when displaying its version. The engine and scan rules are unchanged.
- Class-name correction skips candidates whose lengths make a match impossible, reducing validation work while preserving correction thresholds, Unicode handling and deterministic tie-breaking.
- Internal: measured baselines for the paths this release changes. Generation, preview rendering, accessibility scan lifecycle and model discovery now have committed benchmark harnesses and recorded artifacts, so the figures above are reproducible rather than remembered. No behaviour depends on this.
0.5.2
2026-09-09A reliability release for the second and third things you ask of a page. A generation can now be stopped from the preview as well as the chat, a failure keeps a specific title and stays on screen until you dismiss it, and closing the window mid-generation asks before dropping the unfinished result. Regenerating — or editing — a request that refined or added a section now re-runs that same operation against the page it started from, instead of silently falling back to a whole-page rewrite. Version history survives closing and reopening a project. Underneath, the code that works out what a prompt means and carries it out is now one module rather than a dispatcher spread through the app shell.
Fixed
- Version history survives closing and reopening a project. Every load path — the copy the app restores on launch, opening from the library, importing a project file, and restoring a Checkpoint — rebuilt each page without its versions, so the trail came back empty on every reload even though the file on disk held it. Undo and the version list were therefore only ever as long as the current session. Load now forwards the stored versions into page intake, which drops malformed entries and prunes as it already did for newly written ones.
- A generation can be stopped from the preview, and a failure stays until you dismiss it. Stop was only on the chat dock, which unmounts in distraction-free mode, so a long generation there could not be interrupted. The preview's progress overlay now carries its own Stop. Errors that used to appear as a generic, self-dismissing toast now raise a shell banner with a specific title and an explanation, and the New page and Projects dialogs trap focus rather than letting Tab escape behind them.
- Closing the window during a generation asks first. Quitting or closing while a page was being generated dropped the in-flight result with no warning. The window now asks, naming what is lost — saved work is unaffected, only the unfinished result — and offering Close anyway or Cancel. Confirming close destroys the window; cancelling leaves the running model and a live LAN share in place. Cmd+Q during a generation is still unguarded.
- Add or change? is one in-app sheet instead of two native confirmations. The question that resolves an ambiguous second prompt was a pair of sequential native confirms, which meant a three-way choice could not be expressed on one sheet and Escape's macOS binding decided the answer. It is now a single in-app dialog with the choices side by side, a focus trap, and Escape reliably cancelling.
- Regenerate and edit re-run the operation that made the page, on the page it started from. Regenerating a reply that had refined a section, or added one, restored the earlier version and then regenerated the whole page — losing the section scope and rewriting content the request had never been about. Both now re-run the same pipeline against the html that request started from, while the preview keeps showing the first attempt, and commit the result only if the page is still the one they expected. History reads base, first attempt with no Replaced by restore entry; a cancelled, failed or refused re-run leaves the page untouched, and the app says so. Editing the last request of such a reply follows the same rule.
- A re-run that stops to ask where resumes as a re-run. When a regenerated addition paused for a placement, or a regenerated refinement for a section, answering it used to send the request afresh against the live page — so an addition appended its section on top of the first attempt, doubling it. The paused re-run is now held with its base and its expectations, and resumes in the same mode when you choose; if the page has moved on in the meantime it says so rather than spending a generation.
- Stop during a refinement's which section? turn now cancels it. That turn ran outside the cancellable path, so pressing Stop while the model was locating the section produced a which section did you mean? question instead of a cancellation.
- A request the app cannot start now answers in the chat. If the design-system lock could not be taken — a competing pack activation — the app set a banner and appended no reply at all, so a refinement or an addition simply vanished from the transcript. Hold-acquisition failures now answer in the chat. Stopping a whole-page rewrite, or dismissing its Whole-page change confirmation, now leaves a reply saying the page is unchanged. The reply lands on the page the request was about even if you have moved to another page by then — and a confirmation you accept after moving away no longer starts the rewrite.
- Checkpoints say when they cannot save. Setup diagnostics used to grow without bound until local storage was full, so a new Checkpoint key could not be written and the save failed with no toast. Diagnostics now keep a bounded log, and a full store shows Could not save checkpoint. Local storage is full.
- A rejected desktop call is written to a bounded log. An unhandled frontend rejection, or a failed window close, is appended to frontend-errors.log in the app log directory — one line, path-redacted, rotated — instead of disappearing in a release build.
- First-run copy no longer assumes a Mac. The welcome screen promised Nothing you type leaves this Mac to Windows users, and the setup wizard's Ollama recovery steps named the macOS Terminal and menu bar. They now say this device, and terminal and menu bar or system tray.
Changed
- Internal: one Prompt operation module; one sidecar restart policy; a typed preview bridge. Deciding what a prompt means and carrying it out moved out of the app shell into a single module with two entry points (whole-page generation, and the intent-resolving dispatch that reaches refinement and addition); Settings and the connection monitor now share one rule for whether a saved change needs the local AI sidecar restarted; the pack a write uses is passed to it rather than read from global state; the open project owns its own transcript; and the messages the preview iframe exchanges with the app are a typed protocol that rejects unknown fields at compile time. No behaviour depends on these beyond the fixes above.
0.5.1
2026-09-07A page-editing release. Adding a section to a page that already has content is now its own operation, separate from refining what is there: the app works out what kind of change you are asking for before it asks where, and the new content is created at one verified point without the rest of the page being sent to the model or rewritten. It also carries fixes for confirmation sheets that answered Esc with the wrong button on macOS, for a Settings save that could leave the app without a local model, for GOV.UK Frontend behaviour that never ran in the preview, the LAN share or the exported prototype, for the testable prototype's check-answers rows on non-GOV.UK packs and for LAN shares of mixed-pack projects, plus an Abstract catalogue increment and the beta-terms wording correction.
Added
- Add section: create what is missing without touching what exists. The preview toolbar gains Add section beside Edit section. Choose a visible Add here point — a real boundary inside the page's main content (before, between, or after sibling blocks in each form, grid column, or content container; never in the header or footer), keyboard-focusable and announced to assistive technology — and an Adding: chip in the composer names the location; describe the section and generate once. Or type an additive request such as add an eligibility section: when a position named in the request (at the end, before the form) matches exactly one boundary it is used, otherwise the preview shows the Add here points and choosing one starts generation without a second submission. Generation receives only a bounded digest of the page and its surrounding container — never the page's HTML — so existing content is unreachable by construction, and the stored page stays byte-for-byte unchanged unless the new markup passes sanitisation, the pack's class allowlist, and the duplicate-ID and structure checks. Page-shaped output is rejected and retried once as a fragment; a second failure, or markup the pack's class rules refuse, changes nothing and says so in plain words. One request makes one Version history entry, even when it creates several adjacent blocks, and Undo reverses it. Pressing Esc while choosing a location leaves the page unchanged and keeps the request in the chat as Cancelled before placement with a Choose placement button; switching pages suspends a pending request on its own page rather than carrying it with you.
- Second prompts resolve their intent before their target. A request on a page with content is classified as an addition, a change to an existing section, or a whole-page regeneration before any section is asked for. Clearly additive wording enters Add section directly; ambiguous wording asks Add a new section / Change an existing section and keeps your request; a likely duplicate asks Add another / Change existing and names the possible match; a request that mixes adding and editing asks you to send them separately; and a named component the active design system does not have offers Create an equivalent / Cancel rather than inventing classes. A selected scope always wins — Refining: Date of birth plus add hint text stays a refinement — and whole-page regeneration still never happens without confirmation. The refine tour and the user guide now teach Edit what exists / Add what is missing together.
- Abstract: Resume and Schedule join the catalogue, with new variants for existing moments. Resume (returning to a saved application) and Schedule (choosing a bookable slot — one decision per page, with full slots announced in place) are new service moments; a structured start, chapter navigation, refining a result, address / date / lookup questions, and an Ineligible stop for a failed eligibility check land as variants of the Explain, Navigate, Search and Ask moments. Each was admitted by restating a capability proven on the other packs, not by copying their furniture. The evaluation harness now scores Abstract generation against the pack's own allowlist and one-primary-moment rule; that scoring is admission-shaped and does not bless the pack, whose prototype quality stays Not measured.
Fixed
- Settings › Help & feedback › Beta terms no longer says usage statistics are on by default. The bullet had described the earlier default-on beta behaviour and was never updated when lifecycle statistics became opt-in, so the in-app summary contradicted the shipped default, the desktop licence terms and this site's privacy notice. It now says the statistics are off by default, start only if you opt in under Settings → Privacy, and never include your prompts, pages or project content. No behaviour changed: the default was already off.
- Esc on a confirmation sheet no longer chooses the wrong button on macOS. macOS binds the Escape key only to a button titled exactly “Cancel”, so every sheet whose cancel button had been renamed — Keep project, Keep editing, Keep current journey, No, something else — answered Esc with its first button instead: Esc on “Delete project?” deleted the project, and Esc on Add section's “Add or change?” question started an addition. Every confirmation now keeps a literal Cancel button, the alternative it stands for is spelled out in the question, and a test refuses any renamed cancel label.
- Saving Settings with a pinned port no longer leaves the app without a local model. Restarting the local AI sidecar after a Settings change killed the old process and probed its port before the socket had closed, so with a pinned port the restart failed as “already in use” and the app showed Disconnected with no way back but another save; Automatic-port installs drifted silently to the next port instead. The stop now waits, briefly and bounded, for the port to be released before the new sidecar starts, health polling is re-armed after a failed switch, and the Settings troubleshooting card offers a retry that actually restarts the sidecar.
- GOV.UK Frontend behaviour now runs in the preview, the LAN share and the exported prototype. Since the first release the GOV.UK pack loaded GOV.UK Frontend's ES-module bundle with a classic script tag, so the browser rejected it and its initialisation never ran: accordions, tabs, character counts, error-summary focus, exit-this-page and the other enhanced components stayed static on GOV.UK pages everywhere the app renders them. The pack now ships one classic, self-initialising build of GOV.UK Frontend for the preview, the LAN share and the exported prototype — a module build cannot load inside the sandboxed preview frame or from an export opened by double-click — and a script-type gate checks every pack's bundle against the way it is loaded.
- Saving Settings no longer restarts the local AI sidecar twice. Switching backend or model from Settings restarted the sidecar once for the switch and again when the saved settings were re-synced against the running one. The second restart is now a no-op.
- Testable prototype: check-your-answers rows fill in correctly on every pack. The runtime that fills a check-answers page from earlier answers hardcoded GOV.UK classes and English copy, so on any other pack — a Bootstrap Italia Riepilogo della richiesta, for example — each row rendered as “[Not provided]” and lost its key, value and Change link together. Every pack now supplies the runtime its own value selector, “not provided” wording, yes / no wording and list class, in preview and export alike, and an answer the participant left blank shows the pack's placeholder rather than the model's sample text.
- LAN share: pages in a mixed-pack project initialise with their own design system. Every shared page used to load one initialisation script for the project's active pack; each page now loads the script for the pack it was generated on, so a project that mixes packs behaves correctly on other devices.
- Scottish Government check-answers rows are recognised by Exit resolution. The row class the pack declared does not exist in that design system, so carried fields and Change links on its check-answers pages were never aligned. Every pack's summary-row role is now one class token that both halves of the app match identically.
- Code view edits no longer flash or overwrite the Validation panel. The notice a code edit produces is now checked through a stateless port rather than the panel's own state, so the panel's result, timestamp and in-progress indicator are left alone while you edit.
- First-run setup no longer shows two Start model download buttons. When Resume or Retry is already on screen after an interrupted download, the troubleshooting panel below no longer repeats the same primary action, and its Copy diagnostics copies the same report the panel presents.
0.5.0
2026-09-02A pack and journey-integrity release. It adds the Digital Agency Design System (Japan) as the eighth base pack, stops generated journeys from guessing where a page's exits go, states prototype quality as a fact about one model on one pack, and makes the assessment evidence export self-contained. It also carries everything that was staged as 0.4.5 on 1 September but never published — the Bootstrap Italia furniture work — plus the preview, pages-rail, and Settings fixes from the external review of 0.4.4.
Added
- Digital Agency Design System (Japan) is the eighth base pack. デジタル庁デザインシステム (DADS) joins the Design system chooser for new pages and projects, with the design system's MIT-licensed component CSS and JavaScript pinned to the dated upstream release v20260825. Japanese is the pack's canonical language, and the page's language attribute follows the generated content. The pack's custom elements (switch, tabs, accordion) stay live in preview and export through sanitisation. The header and footer are a neutral Prompt to Page shell — the upstream header has no published HTML implementation — and the pack bundles no fonts (Japanese renders in the system's own typefaces, as the upstream typography guidance permits), no Digital Agency logotype, no government crests, and none of the icon or illustration materials. Prototype quality on this pack is Not measured, and the Japanese copy in the pack's guidance is still awaiting native review.
- Evidence export: Brief, Components, and Limitations. The assessment ZIP's EVIDENCE.html (and its README.md) now carry a Brief — the journey-plan description or the original first prompt, never invented, and it says so when there is none — a Components inventory of the design-system blocks actually present in the pages, and a Limitations section that replaces Known gaps: the standing limits of a static prototype, the kit hand-off refusal when it would apply to this project, and this export's own warnings. The section never claims WCAG or assistive-technology conformance.
- Code view: an always-present bar says the HTML is editable, with a per-page Copy HTML button. The bar carries an idle hint ("Edit the HTML directly. ⌘/Ctrl+Enter applies your changes."), described to assistive tech through the editor itself rather than announced on every open. Copy HTML copies the current page's source — the unapplied draft if you have one — and the result is announced, even while a generation has paused editing. The refine tour now points the code view out.
- Settings › Help: the shortcuts reference lists the keys that open the palette (⌘K / Ctrl+K from anywhere, and ? when you are not typing in a form field). They live in the keyboard handler rather than the command registry, so the generated list had never shown them.
Changed
- Generated journeys no longer guess where a page's exits go. On a freshly generated journey page, every primary control and form is pointed at the journey plan's next path and every back link at the previous one. Any other internal link or form action whose destination is not a path in the project is stamped as an unresolved exit: its destination is neutralised, it is outlined in the preview and the testable prototype, and it stays on the page's live issue list until you retarget or regenerate it. Export no longer rewrites an unresolvable form action onto the next page to make a broken journey look linear. Code edits, retargets, and imports are left alone.
- Prototype quality is stated for your model on your pack. The model card leads with the open project's pack (GOV.UK at first run), names the other packs a model has been measured on without levels, and says when the recommendation is ranked on GOV.UK results while another pack is in context. The pack picker's "has not been evaluated" caveat is replaced by one line for the selected pack — the measured level, or "Not measured". Levels are never compared across packs. The catalog now records the 2026-08-24 NSW and Bootstrap Italia battery levels for the seven GGUF models (pre-fix numbers; a post-fix re-run is owed).
- Bootstrap Italia preview and export now use the pack's own furniture. The header is three bands (slim, center, nav) and the footer is two (main + small-prints), de-branded: a Prototype tagline, with no PA emblem, flag, SPID, or official-service claim. Titillium Web, Lora, and Roboto Mono are inlined as data-URI fonts so preview and the testable ZIP match offline. Export no longer wraps the page in a second .container. Existing Italia projects pick this up on update without regenerating pages.
- New Bootstrap Italia start pages follow a scheda shape. Intro, one primary link to the next path, then optional supporting sections. Existing start pages keep their stored HTML until regenerated. Prototype quality for the pack is stated per model from the 2026-08-24 battery (see the Prototype quality entry above); no new battery was run for this release.
Fixed
- Preview: the Screen-reader tree and Version history panels no longer cover the toolbar. On narrower windows the preview toolbar wraps to two or three rows, and both panels were positioned from the top of the whole preview, so they landed on the Edit section / Link pages / code view buttons. They are now anchored inside the canvas stage below the toolbar, whatever its height.
- Preview: the code view no longer paints a second scrollbar, and its top bar is always reachable. The HTML source view now mounts in the canvas stage rather than inside the scrolling canvas, so it no longer inherits the canvas scroll position (which could push its Apply / Discard bar out of view), and the covered canvas no longer adds its own scroll gutter beside the editor's.
- Preview: distraction-free mode fits the frame to the window. Entering the mode zooms the page to fit the available canvas instead of leaving a 1280×900 desktop frame to scroll inside the stage; a viewport preset change inside the mode re-fits, and leaving the mode restores the zoom you had before.
- Pages rail: the active page card is unmistakable. It now carries an accent rail and tint (the same selected-state language as the journey template picker) instead of a background that matched the rail, and it is announced as the current page to assistive tech.
- Settings › Local AI: the chosen .gguf filename is shown beneath the path field. The path input clipped long paths at the right edge, so the filename — the part that identifies the model — was off-screen. A "Selected file" line now appears once the path looks like a model file, and hovering the input shows the full path.
- Tools panel: the Map / A11y / Valid / Share tabs are 40px tall, matching the collapsed rail's buttons.
0.4.4
2026-08-25A generation-quality release for the two newest packs. Scored 20-case and 16-case live batteries were run against the NSW Design System and Bootstrap Italia packs, and the failure patterns they surfaced — models copying markup a static prototype cannot use, or inventing class names where the bundled guidance only listed them — are fixed in the prompts and component corpora this release ships. Also picks up a dependency security update.
Changed
- NSW pack: JavaScript-enhanced components now generate usable markup. The live battery showed that where the bundled component guidance only listed class names, models invented GOV.UK-shaped nsw-* BEM tokens that match nothing in the design system's CSS. The corpus now carries the real pre-enhancement HTML trees for the JavaScript-backed components (tabs, accordion, side navigation and friends), the repeatedly-invented tokens are dropped from the guidance, and the class validator recognises the added markup — so generated NSW pages render with the design system's actual styles instead of unstyled invented classes.
- Bootstrap Italia pack: confirmation and journey pages now use static-friendly patterns. The live battery showed models copying the corpus's JavaScript notification toast (which never fires in a static prototype), the modal primary-action snippet, and Italian button labels (Continua) into English-language prototypes. The prompt and corpus now teach a visible alert-success confirmation panel, "Start now" journey links, and data-field review rows, with class-grammar examples written in English.
- Both packs now ship with a scored evaluation battery, with multi-seed medians recorded in the in-repo eval records. Pack quality scores in the model catalog are unchanged in this release.
Security
- Updated DOMPurify from 3.4.12 to 3.4.14, clearing GHSA-55q2-fjhq-7xh7 (moderate): in the affected versions, removing an IN_PLACE hook could leave a detached subtree executable. The app was not exposed to this — the sanitizer has a single call site that sanitizes to a string, and registers no hooks — but DOMPurify is the seam that scrubs model-generated markup before it reaches the preview and the export, so it is kept current on principle rather than on reachability. Shipped builds up to and including 0.4.3 carry 3.4.12.
0.4.3
2026-08-23A reliability release. Generated pages are no longer thrown away when the follow-up quality check runs out of room, quitting the app no longer leaves the model server running, and local backends work on machines with a corporate proxy configured.
Fixed
- A generated page is no longer discarded when the quality-repair turn fails. The repair pass sends the whole generated page back to the model along with the issues to fix, so it is always a larger request than the generation that just succeeded — on dense packs (Scottish Government most of all) that could overflow the context window. The page you had just watched stream in was replaced by a raw backend error. The un-repaired page is now kept instead. Stopping a generation still stops it.
- Quitting no longer leaves the model server running. On macOS, Cmd+Q delivers a shutdown event the app was not listening for, so the local model server kept running after every quit — holding several gigabytes of memory and port 8080 until the next launch swept it up. Cmd+Q, logout, restart, shutdown, and Activity Monitor's “Quit” now all shut the server down. A force quit still leaks it; the next launch reclaims it as before.
- Local backends no longer break behind a corporate proxy. The app's local HTTP connections — the built-in model sidecar, the Apple Silicon MLX sidecar's readiness and health checks, and Ollama / LM Studio connection checks and generation — were silently routed through HTTP_PROXY-style environment variables and explicit system proxy settings. A proxy asked to reach the machine's own 127.0.0.1 refuses, so running local servers looked unreachable (and MLX could sit at “starting” indefinitely) on proxied machines. Local connections now bypass proxies entirely; model downloads keep full proxy support.
- Wrong-server errors are no longer misreported as “not running”. When something answers at the configured Ollama / LM Studio address but does not return the provider's model list (wrong port, a proxy or another app on that port), connection checks now say so — with the address to check — instead of telling you to start a server that is already answering. First-run setup labels that provider “Unexpected response” rather than “Not running”, and drops the “go start the server” steps that contradicted it. The copied diagnostics report includes the raw probe cause, so connection-refused, timeout, and wrong-service failures are distinguishable in support threads.
- The “Ready” status chip no longer overflows the status bar at the bottom of the window, where it spilled past the border and the rounded window corner.
- When the app is terminated by a signal it now reports the conventional exit status (128 + signal number) instead of 0, so scripts and supervisors can tell a terminated app from a clean quit.
0.4.2
2026-08-23A fix release for the two backend problems reported against 0.4.1: the MLX backend could not start on macOS 14 or 15, and LM Studio would not connect unless CORS was switched on. Troubleshooting reports now carry the app version.
Fixed
- macOS 14/15: the MLX backend could not start on 0.4.0 and 0.4.1 (it failed with “Failed to load the default metallib … language version 4.0”). The bundled MLX runtime was built for macOS 26 because pip chose the build host's wheel platform and the interpreter came from Homebrew. The MLX bundle is now built from a pinned, checksum-verified standalone CPython and macosx_14_0_arm64 wheels regardless of the host, and the release gate verifies every library and wheel tag in the bundle against the app's macOS 14.0 floor. The llama.cpp backend was not affected. Requires installing this release (or updating in-app); there is no workaround on the affected versions.
- LM Studio showed as “Could not reach LM Studio” even when its server was running. LM Studio's local server has CORS off by default, so the app's in-WebView connection check was blocked while generation (which already ran natively) worked. Connection inspection and model discovery for Ollama and LM Studio now go through the Rust side as well, so LM Studio connects without enabling CORS. The LM Studio setup and recovery steps now name the Developer tab and the default server address.
- Copied troubleshooting reports said “App version: <unknown>”. The connection screen, first-run setup, and Settings all omitted the version when building the redacted report, which made support triage unable to tell 0.4.0 from 0.4.1. All three surfaces now stamp the running app version.
0.4.1
2026-08-23A compliance maintenance release. No new features: the GOV.UK header and footer are removed from the bundled component corpus and the generation prompt, a content-aware brand-compliance check now gates every build, and the export wording on public surfaces is corrected.
Changed
- Protected GOV.UK furniture is no longer bundled in the component corpus. The header and footer entries — whose reference markup carries the crown logotype and the OGL licence and copyright marks — are removed from the component database the app ships and retrieves from, from the scraped example corpus, and from the class list in the GOV.UK generation prompt. The app's own unbranded shell (a header bar carrying only the service name, the prototype phase banner, and a footer with no licence sentence or Crown copyright link) already supplied page furniture in preview and export, so generated pages look the same; what changes is that the protected markup is no longer on disk inside the app or shown to the model. The corpus builders now strip these entries at source so a future re-scrape cannot reintroduce them.
- Export wording corrected on public surfaces. README, the website docs and feature tour, and the marketing spec now say what the testable ZIP actually contains — local, font-stripped frontend assets — and that Prototype Kit and Nunjucks hand-offs use the receiving project's own dependencies; restricted fonts and protected marks are never bundled.
Added
- Content-aware brand-compliance check in CI. The source tree is scanned for protected-mark SVG signatures (GOV.UK crown logotype, NHS logo, MOJ crest, USWDS official banner/identifier) and for embedded restricted-font payloads (GDS Transport, Frutiger, NTA), and the macOS and Windows build jobs run the same check against the packaged app. Class names and selectors alone are allowed — they are MIT-licensed frontend code.
0.4.0
2026-08-22Three new design systems join the chooser — the NSW Design System, Bootstrap Italia and the Scottish Government Design System — taking the app to seven built-in base packs.
Added
- NSW Design System as a generally available base pack. The Design system chooser now offers NSW alongside GOV.UK, NHS.UK, Abstract, and USWDS. Preview uses a de-branded header (no Waratah, no masthead). Generation quality is not yet evaluated, so Settings shows the existing caveat. Pinned to nsw-design-system v3.26.0.
- Bootstrap Italia as a generally available base pack. The Design system chooser now offers Bootstrap Italia (bootstrap-italia 2.18.3, BSD-3-Clause) for Italian public-service prototypes. Generated pages use the framework's own markup with its pinned stylesheet, single bundled script and functional SVG sprite, served entirely offline; the Titillium Web and Lora (SIL OFL 1.1) and Roboto Mono (Apache-2.0) faces are embedded under their own licences, and the neutral shell carries only your service name and the prototype marker — no Italian public-administration logos are bundled. Generation is grounded by a dedicated system prompt and component manifest because the 2026-08-22 capability probe found local models produce no Italia-specific markup unprompted. Generation quality is not yet evaluated on the repeated-seed battery, so Settings shows the existing caveat. Pinned to the v2 line; the upstream v3 is still in beta.
Scottish Government Design System pack (beta)
- Scottish Government Design System is selectable as a base pack (@scottish-government/design-system 4.1.1, MIT). Generated pages use the system's own ds_ markup and its pinned CSS and JavaScript; the bundled Roboto faces (SIL OFL 1.1) are inlined, and the Scottish Government logo and crest are never bundled — the shell carries only your service name plus a “not a real Scottish Government service” marker.
- Grounded in official reference markup. The component corpus is curated from designsystem.gov.scot (OGL v3) and class-verified against the pinned stylesheet; six components the docs publish no markup for are deliberately left out rather than guessed.
- Measured, not assumed. Seven built-in GGUF models were run through a 20-case Scottish Government battery (five seeds each): all seven scored at or above their GOV.UK rating — six at 4 of 5 and one at 3 of 5 — with no GOV.UK class leaking into any of the 700 generated pages. The model picker shows the measured rating per model; the MLX entries and the 32 GB-class models are not yet measured on this pack and show no rating, which is why this pack ships as a beta. GOV.UK and NHS.UK generation was re-measured on the same build and is unchanged.
- Licence and brand facts are recorded in the assurance manifest with a primary-source URL and retrieval date for each, and CI refuses a build without them.
- Quality report: class residue from another design system is reported as an error in evaluation, and every automatic repair stays visible in the per-page report.
0.3.2
2026-08-21A second 32 GB-class model joins the catalogue for side-by-side comparison, and the app can now launch thinking-by-default models with reasoning switched off.
Added
- Qwen3.6 35B-A3B — a 3-of-5 comparison entry in the 32 GB bracket. A mixture-of-experts model with 3B active parameters, measured at a five-seed GOV.UK median of 82 (quality 3). That is below Qwen3-Coder 30B-A3B's 89 (quality 4) at the same RAM tier, so the coder remains the recommended choice; this entry is offered so testers can compare the two side by side. 19 GB download; it appears in the model picker only on 32 GB machines. As with every rating, this comes from Prompt to Page's own internal evaluation set — a guide to relative model performance, not an independent benchmark.
- Thinking-by-default models can be launched with reasoning off. Catalogue entries can now declare launch-time reasoning suppression, and the bundled llama.cpp server is started with thinking switched off for them so a generation spends its whole page budget on markup instead of deliberation. Only the new entry uses it; every existing model launches exactly as before.
0.3.1
2026-08-17Usage statistics are now off unless you switch them on, the model catalogue gains its highest-rated model yet, and a group of 8 GB Windows PCs that couldn't get through setup can now install and use the app.
Added
- Qwen3-Coder 30B-A3B, the highest-rated model in the catalogue. The first model to reach four of five on the headline quality rating. It's a mixture-of-experts coder, so although it's a 30B model only a small part of it runs for any given token and it answers faster than its size suggests. It needs 32 GB of RAM and appears in the model picker only on machines that have it. As with every rating, this comes from Prompt to Page's own internal evaluation set — a guide to relative model performance, not an independent benchmark.
Changed
- Usage statistics are now off until you switch them on. From 0.2.4 the two lifecycle events were on by default with an opt-out. They now require you to turn them on yourself in Settings → Privacy. Updating sets them to off for everyone, including anyone who had deliberately left them on — a genuine earlier choice can't be told apart from the old default, so the app doesn't assume one. Nothing else changed about the data: still only "app started" and "app exited", and never prompts, prototypes, project content, model names or file paths.
- More careful claims about what the app does. Copy across the site, the docs and the app itself no longer describes the built-in axe-core checks as establishing WCAG conformance. They catch common defects; user research, manual accessibility testing, content review and security review are still yours to do. System requirements now point to the per-model figures in the setup model picker rather than quoting one universal RAM minimum, because the available models span 8 GB to 32 GB.
Fixed
- 8 GB Windows PCs are no longer turned away at setup. Windows reports the memory available to programs rather than the memory installed, and the difference — reserved for firmware and integrated graphics — was enough to put a nominal 8 GB machine just under the 8 GB floor. Installed memory is now read directly from the system, and both memory checks allow a small margin for measurement. The 16, 32 and 48 GB tiers are unchanged.
- The "device not supported" screen is no longer a dead end. It appeared with no buttons and no way to close it, and because setup remembers where you got to, restarting the app — or even reinstalling it — went straight back to the same screen.
0.3.0
2026-07-30The measured-quality release: every design system now has evaluation evidence behind it, the model picker shows what was measured, and generations got faster on the models that earned it. Plus: the macOS install is now notarized — no more Terminal step.
Added
- Edit the generated code. The HTML code view is now an editor — change the markup directly and apply it verbatim, with per-page drafts and a heads-up when your edits conflict with a newer generation.
- Per-page quality report. Issues the validator finds at generation time are shown on each page, instead of being fixed or recorded silently.
- Per-design-system quality ratings. The model picker shows measured quality for each design system a model has been evaluated on — for example "Also measured — NHS.UK ●●●○○ · USWDS ●●○○○" — alongside the headline rating. These ratings come from Prompt to Page's own internal evaluation set; they are a guide to relative model performance, not an independent benchmark.
Changed
- The macOS install is now warning-free. Builds are signed with an Apple Developer ID and notarized by Apple, so the app opens straight from Applications — the first-launch Terminal command is gone.
- NHS.UK is now quality-evaluated. Six models measured at or above their GOV.UK level, and the "quality has not been evaluated" caveat is gone for NHS.UK projects.
- Faster responses on eight models. Prompt sizes were reduced only where a per-model quality gate proved no loss — including the Qwen2.5-Coder 7B and 14B lines and both Gemma 12B models.
- Better USWDS pages. Fixes from a full field review: proper prefix/suffix inputs, input masks, complete state lists, card containers, and consistent step indicators.
- Hallucinated class repair. The validator now automatically corrects two systematic model mistakes — wrong-number component families (like a singular NHS checkbox class) and overlay components written under the base system's prefix — so more pages render correctly first time.
- The bundled MLX runtime's prompt cache is now capped, preventing memory exhaustion in long generation sessions on Apple Silicon.
Fixed
- Devstral Small 2 24B is no longer offered on 24 GB Macs: loading it could crash the whole machine, so it now requires 32 GB.
- The validator catches more generation defects found in review: bare typography, misattached hints, duplicate headings, malformed forms, summary-card structure, and broken journey routes.
0.2.5
2026-07-19A fix for a startup crash in 0.2.4, plus limited, opt-out beta usage insights on by default.
Fixed
- The app opens again. On macOS, 0.2.4 could quit the moment you launched it, before its window appeared. 0.2.5 corrects the startup sequence so the app opens normally. If you're on 0.2.4 and it won't open, download 0.2.5 and reinstall — the in-app updater can't reach an app that never finishes launching.
Changed
- During the closed beta, two limited Aptabase lifecycle events are enabled by default to measure aggregate use and improve the app. They never include prompts, prototypes or project content and can be turned off in Settings → Privacy.
0.2.4
2026-07-19Limited usage analytics — on by default for the closed beta, with an opt-out — plus a preview fix.
Added
- Usage analytics (Aptabase). A limited, privacy-preserving measure of aggregate use during the closed beta — on by default, opt out any time in Settings → Privacy.
Changed
- During the closed beta, two limited Aptabase lifecycle events are enabled by default to measure aggregate use and improve the app. They never include prompts, prototypes or project content and can be turned off in Settings → Privacy.
Fixed
- Closing the block-action menu in the preview now clears the highlighted block selection.
0.2.3
2026-07-18Deterministic block actions, NHS generation refinements, and accessibility fixes.
Added
- Deterministic block actions. Delete, move and duplicate individual blocks on a page directly from a popover in the preview, without regenerating the page.
Changed
- Refined the NHS.UK generation prompts and evaluation set for better, more consistent NHS output.
Fixed
- Linked-page exit selection now resolves the correct target when choosing where a linked page's exits should go.
- The accessibility panel's AI remediation is now actionable — its guidance is usable and links to external Design System / WCAG guidance open in your browser.
- Clicking into the chat composer while the tools rail is open now focuses the composer instead of first dismissing the panel.
0.2.2
2026-07-18Multi-page working gets much sharper: pages keep their own conversations, prompts can reference other pages, and Settings is reorganised around what you're actually doing.
Added
- Page-scoped conversations. The Transcript now follows the active page — chat and generation happen per page, so refining one page no longer tangles with another's history.
- @page references. Mention another page in a prompt (e.g. @Check your answers) and its content is included in the request, so you can ask for a page that builds on or matches one you already have.
- Journey replacement guard. Generating a new journey asks for confirmation before it replaces one you've already built.
- Reorganised Settings. A two-pane Settings with Local AI, Appearance, Updates and Help & feedback sections, per-section apply and discard, a keyboard-shortcuts reference, and plainer language throughout.
Changed
- Every panel now shows the same page label (title plus path), so a page is called the same thing everywhere.
- Page-list thumbnails render in the project's active design system rather than defaulting to GOV.UK styling.
Fixed
- A newly created blank page opens genuinely blank — with an invitation to describe it — instead of showing the previous generation.
- The journey map draws branches in the order the journey plan intended.
- Dragging a page somewhere it can't go now explains why instead of silently snapping back.
- Prototypes that mark their main content with div[role="main"] now export and refine correctly, including pages without a container.
- In the accessibility panel, the selected component stays selected when you click away from the panel.
- Page validation no longer penalises header and footer furniture that the app shell provides.
0.2.1
2026-07-16The Abstract design system is generally available, and the beta's commitments are now written into the app.
Added
- Abstract base pack. A neutral, unbranded design system for prototyping services that aren't GOV.UK, now generally available in the design-system picker after a full visual pass over every component, style and spacing.
- Beta terms in the app. A plain-English summary of the beta commitments — what's free, what happens when the beta ends, and the 30-day notice promise — in Settings → Help & feedback.
Changed
- App copy now describes public service prototyping generally rather than GOV.UK-only, reflecting the switchable design systems introduced in 0.2.0.
Fixed
- Back-link interception in exported prototypes now works for every design-system pack, not just GOV.UK.
0.2.0
2026-07-15Switchable design systems, an app-managed project library, deeper exports, and in-app updates.
Added
- Switchable design-system packs. The prototyper is no longer GOV.UK-only — a base design system can be selected per project, with retrieval, class validation, page furniture, prompts and export all following the active pack.
- U.S. Web Design System (USWDS) pack with a curated component corpus and service-pattern guidance.
- Early NHS.UK pack. Initial support for generating prototypes against the NHS design system (nhsuk-frontend). Quality is early and still being tuned.
- Ministry of Justice overlay. An optional MOJ Frontend overlay layered on top of GOV.UK — early support, with a quality caveat in the design-system picker.
- App-managed project library with a per-project saved design system, so prototypes and their chosen pack are preserved and reopened together.
- In-app updates. The app checks for new versions on launch (toggle in Settings) and installs only with your consent. One-time note: 0.1.1 can't auto-update to 0.2.0 because the update signing key was rotated — download 0.2.0 manually once, and automatic updates resume from there.
- Deeper exports. Download a runnable GOV.UK Prototype Kit project (Nunjucks views plus wired routes, using the receiving project's dependencies), or an evidence pack that embeds each page alongside a fresh axe-core accessibility scan run at export time. Standalone testable ZIPs include local font-stripped frontend assets; restricted fonts and protected marks are not bundled.
- Retarget from the preview. Point a page's links and form actions at a different page without regenerating, and journeys heal their links automatically when pages are renamed.
- Feedback and error reports, on your terms. A once-ever feedback prompt and per-incident error reports — nothing is sent without an explicit Send press, and you always see exactly what would be shared.
- A "lite" model tier for low-spec Windows machines, plus clearer model guidance in the picker: quality dots, hardware tiers, and steering away from models that would run slowly on the device.
- Per-pack licensing and asset handling: dependency licensing audits, pack asset sync tooling and NOTICE coverage so each design system stays correctly attributed.
Changed
- Retrieval, validation, prompt assembly, preview and export now read from the active pack rather than hard-coded GOV.UK data, without changing GOV.UK output.
- Refinement is now structurally scoped: edits splice into the exact blocks you selected, with per-page version history, replacing the legacy whole-page Refine.
- Model downloads use parallel ranged HTTP as the primary transport for faster, resumable downloads (Windows keeps BITS as a fallback for managed-proxy networks).
- Stopped redistributing the GDS Transport font and GOV.UK crown assets, which aren't licensed for reuse outside GOV.UK services.
- Interface polish: grouped preview toolbar, a simpler Share & Export panel, progressively disclosed backend settings, and text-contrast fixes to WCAG AA.
Fixed
- Preview interactivity and confirmation dialogs now behave correctly in the packaged app (both worked in development but broke under the packaged app's stricter security policy).
- Stopped the first-run setup retry loop, and hardened generation against slow first tokens on CPU-bound machines.
- CI, build and test-hardening fixes across the pack and project-library work, including stricter pack/version consistency guards.
Security
- Remediated the July 2026 security review findings: stricter export path handling, a hardened LAN share server, and checksum verification for downloaded runtime components.
0.1.1
2026-06-26Added a Windows build to reach macOS + Windows parity.
Added
- Windows (x64) build shipped as an MSI installer alongside the macOS Apple Silicon DMG, with the bundled local-LLM backend, retrieval and validation at parity with macOS.
- Honest model "warmth" (Cold / Warming / Warm) surfaced in the UI so a slow first token no longer looks like a hang.
Changed
- Expanded the Windows model catalogue and applied each model's own chat template.
- Model downloads on Windows fall back from BITS to a direct HTTP transport when BITS can't reach the download host.
- Re-scored the model catalogue for more trustworthy quality guidance in the picker.
Fixed
- Bundled the Visual C++ runtime so the local-LLM backend starts on a clean Windows install.
- Enabled retrieval on Windows via an embedded corpus self-load, reported free disk space correctly on first run, reaped orphaned LLM sidecar processes and hardened model-switch and startup recovery.
- Shipped a Windows installer packaging hotfix.
0.1.0
Initial releaseInitial closed-beta release (macOS, Apple Silicon).
Added
- Generate GOV.UK Design System prototypes from natural-language prompts using fully local LLMs — a bundled llama.cpp sidecar, an MLX sidecar on Apple Silicon, and optional external Ollama / LM Studio backends. Nothing leaves the machine.
- Multi-page journeys with automatic reconciliation, so linked pages, back links and form-action exits stay consistent as pages are added, renamed or removed.
- Section-scoped refinement with per-page version history, to iterate on part of a page without regenerating the whole thing.
- Built-in accessibility checks (axe-core run inside the live preview, targeting WCAG 2.2 AA) and GOV.UK class validation with quality scoring.
- Export and share: ZIP or clipboard export of the generated prototype, plus a LAN share server to open prototypes on other devices on the local network.
- Guided first-run setup that recommends a model for the device and manages downloads.