0.2.0
Added
- A block can be shown only to people signed in, by binding
visibletoaccount, or only to people signed out, withhidden, on every page: on one built in advance, the browser shows the right one before it's painted, from a cookie that says only that someone is signed in. The dataaccountshas the sign-in, sign-up and account pages' addresses and words in the page's language, while public accounts are on. - Pick any icon for a collection or a global set: a searchable list of all 1,500 Phosphor icons, found by name or by what they are for ("email" finds the envelope).
- Plugins can dock a column beside the page on every screen: the
shell.dockslot withDockfrom@letterncms/ui. Atopbar.endpanel sits in every screen's bar, an editor's own tools go in that bar throughtoolbarinEntryEditorProps, andregistry.entryActionsadds lines to the editor's More menu. Routes can open over the screen they came from (overlay) and keep what they show private (private). - Skills: ready-made ways of working for agents, registered with
cms()->skills(). Every agent gets them: the assistant's/, and MCP clients as prompts. - Plugins can add to what
@and/offer in a chat withregistry.composer, and offer things from a screen withuseScreenContext({ items }). All of it is one thing, aContextItem. - Abilities can mark a change that stays a draft (
annotations: ['draft' => true]), for agents to treat as safe to undo unless a call publishes it.entries/createandentries/updatedo. - Screens can say what they show with
useScreenContext, for whatever works alongside them. An open entry shows changes made from outside as they happen, andevents.emit('content.changed')asks it to look. - Assistant: The chat works beside the page, on every screen. Chat in the top bar or
⌘Jopens it at the right edge, ready to type in. The page stays open and usable, and anything it changes shows there as it happens, in the builder too. Drag it wider, or take it to full size and back without losing your place. - Assistant: In an editor the chat floats over the page at the right of the canvas, so the inspector stays where it is and the canvas doesn't move; drag it wherever suits you. Selecting a block with the chat open attaches that block. Anywhere else, Detach does the same.
- Assistant: The chat knows what you're looking at, including what's on the page: the entry you have open, the block selected in the builder, the text you selected. Chips in the composer show what a message carries, and each comes off with its ×. Account, Users, Licence and Audit Log stay private, and show no chip.
- Assistant:
@in a message attaches anything else: a page or post, a file from the library, a global set, the collections, the design system./asks for a skill by name, such as/proofread,/build-pageor/audit-site. Plugins add to both. - Assistant: Each message shows what it carried, one click away.
- Assistant: Chats name themselves after the first reply, and a new chat suggests what to work on based on what you have on view. Both run on a small model you choose under Settings → Assistant: Claude Haiku 5.5 unless you change it. A suggestion goes into the composer for you to read before sending.
- Blocks: A block shown or hidden on
accountworks on pages built in advance: both versions are in the page, and the browser shows the one for someone signed in or out before it's painted. - Blocks: A box can be a heading (
h1toh6) or a paragraph, such as a heading that holds a link. - Media:
@in the assistant's chat finds files from the library. - Site: The starter's header shows Sign in, or My account once someone is signed in, on sites with public accounts turned on, on phones too.
- Site: Adds
/adjust-designto the assistant's chat, and a prompt for MCP clients. - Commerce: Buyers outside the EU can be taxed by Stripe Tax. Set Buyers Outside the EU to Tax From the Payment Gateway: the checkout charges the exact sales tax, GST or VAT Stripe Tax works out for the buyer's address wherever you're registered, invoices name that tax and its rate, every paid sale is recorded in Stripe Tax and refunds are taken back there. The VAT report lists these sales per country under Tax Abroad, and Go Live checks that Stripe Tax is set up. Another gateway can offer the same through the new
TaxServicecontract.
Changed
- The team has the site's account pages too, with what they bought there like anyone: signing in at
/adminand going to/accountno longer leads back to the admin. Their profile, password and data stay in the admin, and the account menu links there. A signed-in team member who opens/sign-ingoes to their account. - The store, the licence service and the website are at lettern.org, and the docs at docs.lettern.org. Sites find the store there from this version on.
- A calmer top bar in the editor. A way back and tools on the left, the page's title in the middle, actions on the right. Publishing is one control that also says where things stand: the button when there's something to publish, a quiet "Published" when there isn't. Scheduling moved into More, the last thing in the bar. Plugins can use it with
backandtitleonTopbar. - The way back in the settings and outline sidebars says where it goes, and the sidebar's name sits below it, so it can't be mistaken for closing the sidebar.
- There are never more than two side panels: one on the left and one on the right. A screen that uses the right edge says so with
useScreenContext({ rightEdge: true }), and aDockthen getsfloating, a card over the page. - The sidebar is there or it isn't, with one button at the top left and
⌘\. That button and the way back beside it never move, the top bar slides along with the sidebar, and its title stays in the middle. Left and right panels come and go with the same quick animation. It stays that way until you change it. It no longer folds to a row of icons. A screen can bring a state of its own to it withScreenSidebarfrom@letterncms/ui, like the settings one, with a way back, and folded away to start with. - On a phone the sidebar opens from that button instead of keeping a row of icons down the side, so screens get the full width.
- Assistant: Fewer approvals: a chat that has read content others may have written saves drafts without asking, since nothing is live until you publish and the history keeps what was there. Anything that goes live or can't be undone still asks, and Ask Before: Every change still asks for everything.
- Assistant: Your chats are in one place: in the chat, all of them, by age, with a column of their own at full size. They're no longer listed in the sidebar or the Ask widget.
- Assistant: New Chat is no longer a sidebar row, since the sidebar isn't always there: Chat in the top bar is on every screen. If you don't use AI, Hide Chat on the setup screen takes it out of the bar.
- Blocks: The builder gets the whole window: the admin's sidebar folds away when it opens and comes back when you leave. Bring it out with the same button and
⌘\, and it shows the outline, with a way back to the list, the way it shows the settings on a settings page. - Blocks: One bar: insert, undo and redo moved from their own row into the top bar.
- Blocks: The selected block is known to whatever works alongside the editor, such as the assistant's chat.
- Blocks: The inspector no longer shows a block's parents above its name. The outline and the canvas lead to them.
- Forms: Forms no longer check the core's
CMS_LOCKDOWN, which is gone. This version works with every 0.x of the core; the previous one stops saving on a core without lockdown. - Mcp: Prompts are now the CMS's skills, so plugins that register a skill with
cms()->skills()add a prompt too. - Navigation: Menus no longer check the core's
CMS_LOCKDOWN, which is gone. This version works with every 0.x of the core; the previous one stops saving on a core without lockdown. - Seo: Redirects no longer check the core's
CMS_LOCKDOWN, which is gone. This version works with every 0.x of the core; the previous one stops saving on a core without lockdown. - Site: The design system and custom code no longer check the core's
CMS_LOCKDOWN, which is gone. This version works with every 0.x of the core; the previous one stops saving on a core without lockdown. - Site: Preview moved from the editor's top bar into its More menu.
- Commerce: Breaking. The Private Buyers Outside the EU setting is now Buyers Outside the EU (
outside_eu), with the choices Businesses Only, Without Tax; Everyone, Without Tax; and Tax From the Payment Gateway. - Commerce: A business outside the EU can give a tax number that isn't an EU VAT number, instead of being told it doesn't look like one.
Removed
- Breaking.
CMS_LOCKDOWNis gone. Collections, settings, roles, the design system and plugins can always be changed in the admin, by the people whose role allows it. A site that sets it can drop the line.CMS_ALLOW_FILE_MODS=falsestill stops plugin files changing from the web. For plugins:Cms::lockedDown(),Cms::guardConfigWrites()andcms.lockedDownin the admin's manifest are gone with it. - Breaking. The
sidebar.historyslot, andshell.compact. UseScreenSidebar. - Commerce: Breaking. Authors in a store publish free listings only: the store's operator is the only seller. Payouts, store commission, Stripe Connect onboarding and the
PayoutGatewaycontract are gone, with the Store Commission and Days Before an Author Is Paid settings, and authors no longer give a country or VAT number when they join.
Fixed
- A URL that names a folder in the site's root no longer redirects through
http://when a proxy in front of the site handles HTTPS. New sites get this in.htaccess. On an existing site, addDirectorySlash OffbelowDirectoryIndex index.php, andRewriteOptions AllowNoSlashbelowRewriteEngine On. - A line break in rich text no longer turns into two each time it's saved.
- An entry only saves when something in it changed. A field reporting the value it already had could rewrite the page's file, and changing something back no longer counts as unsaved.
- A collection whose icon is named after a Phosphor icon, like
handshakeorbook, now shows it in the sidebar and lists instead of a plain circle. - Blocks: Saving a page keeps every block as it was. A text block with a tag such as
span, an id that interactions point at, or no text yet no longer turns into plain Markdown and loses them, two lists in a row stay two, and a screen size with no styles left is dropped instead of saved as an empty list. A page saved without changes keeps its file as it was. - Blocks: A save keeps
calc()lengths in animations, and astyleattribute that only sets CSS variables, such as a section's own colours. - Blocks: Clicking into text on the canvas and leaving it no longer saves the page. Text the browser writes differently, such as a non-breaking space, counted as an edit and was changed without anyone typing.
- Blocks: The admin's shortcuts, such as
⌘J,⌘Kand⌘\, work with the cursor on the canvas. - Blocks: A page whose blocks have short ids, or an id used twice, no longer opens with an empty canvas in the editor.
- Forms: A form embedded in a page shows its fields on the builder's canvas, not only its submit button, from the moment the page opens.