Pages the Reader Can Change
When I released Lede last month, I borrowed Thariq Shihipar's five kinds of HTML page (specs, code review, prototypes, reports, custom editing interfaces) and said Lede could draw four of them. The fifth was the one where the reader changes something (moves a ticket to another column, nudges a value, rewrites a prompt) and hands the result back to the agent. A Lede page had no script, so it had no way to change.
Lede 0.2 does that, and it keeps the page without a script unless you ask for one.
The checkout prototype
This new release carries the functionality:
@title Checkout prototype
# Checkout prototype
Tune the button, decide what ships, and copy the changes back to the agent.
ask owner | Who signs off on this?
param press unit=x | Press depth | 0.94 0.85 1 0.01
toggle checkout_v2 on | New checkout
toggle express needs=checkout_v2 | Express checkout
bucket triage | Now, Next, Later | Where does each ticket go?
triage: ENG-2041 Fix duplicate emails | Now
triage: ENG-2047 Rotate the signing secret | Next
triage: ENG-2052 Retry, then give up | Later
template prompt | System prompt
preset snappy | Snappy | press=0.96; checkout_v2=on
export prompt
export markdown
With the template body, it's 28 lines.
lede build --shell turns it into a 55 KB page.
The page has a text box, a slider paired with a number box, and two
switches; express checkout is greyed out until the new checkout is on,
which is what needs= says. Below them sit a three-column
triage board with a count over each column, a system prompt that fills
its {slots} from the fields above it as you type, a
button for the snappy preset and two boxes holding the
answers.
Four edits, four lines
I made four edits - entered Sam into a text box, moved a slider,
switched a toggle, and clicked a radio button. The
export prompt box then held this:
Apply these changes to Checkout prototype:
- owner: Sam (was empty)
- press: 0.9 x (was 0.94 x)
- express: on (was off)
- triage: "ENG-2047 Rotate the signing secret" moved to Now (was Next)
Unchanged: checkout_v2
That's the part I wanted. An agent reading it doesn't have to diff two
copies of a page or guess what the reader meant; each line names a
field, the new value and the old one, and the last line says what the
reader looked at and left alone. A Copy button puts it on the
clipboard. export markdown gives the same state as a
document, for when the answer is going into a PR description instead
of back into a chat.
The token savings should be huge; it no longer needs to read a database of answers, the html artifact, or a json response.
One script, pinned
The first post made a safety claim I'm not willing to give up (yet): a
page Lede writes has no script tag, so an agent that has been talked
into something by an email can't put one there. 0.2 keeps that for
every ordinary lede build. Build the checkout file
without --shell and you get a 46 KB page with zero script
tags; it shows the starting values and the controls don't do anything.
With --shell, the page gets one script. It's the same
script on every page, 8,189 bytes against a budget of 8,192, and the
build fails if it grows past that. Its hash is written into the page's
content security policy, so a browser runs that script and nothing
else. The model never writes it; the page's own fields arrive as a
JSON block the script reads. It may touch only a short list of things.
That's text content, input values, checked state and two attributes
(hidden and aria-invalid), and a test reads
the script's source on every run to keep the list that short.
Drawing while the model writes
The other library change is streaming. LedeStream in
@lede-lang/core now emits events as lines arrive, and
createIncremental in @lede-lang/html turns
them into page updates, so a page can draw while the model is still
writing it. On 178 of the 180 benchmark pages, nothing already on
screen changes when the stream ends; the other two get one correction
at the end, and either way the finished page is the one
lede build writes. There's no viewer app for this yet.
It's a library feature, and the
package README
shows the twenty or so lines that wire it up.
There's one smaller piece. lede check --artifact warns
about a local image path that a Claude Artifact can't load, since the
Artifact host serves only the page itself.
What it still can't do
The quality gap against frontier HTML hasn't moved in this release; nothing in 0.2 was aimed at it. The first post's table still stands. Against each model's own HTML, Lede pages won or tied 60% of the time for Haiku, 22% for Opus and 10% for Sonnet. The next benchmark round is what measures whether that changes, starting with a refinement test and then 55 fresh held-out tasks I sealed before touching the renderer. I don't have those numbers yet, so I'm not quoting any.
But, I'm also not convinced that this matters yet, and the blind judge is also likely wrong - I honesty prefer Lede's output in at least half the cases - but maybe that is my own bias.
The editors also stop where the format does. There's no drag and drop (a ticket moves by picking its column), no live recalculation beyond filling a template, and the page doesn't save anything; the answers stay in the tab until you copy them.
Trying it
npm install -g @lede-lang/cli gives you the
lede command at 0.2. Build
examples/parity/editors.lede from
the repository with
--shell, change four things, and paste what the prompt
box says into the agent that wrote the file. If it gets a change
wrong, or there's an editor you needed and didn't find, open an issue;
the list of what pages couldn't do is still the roadmap.