Images and files in a sent or queued message now use the same 100px card
as a pasted text card. Images are cropped to fill theirs; files show an
icon and their name over their extension (HTML, PDF...) where a paste shows
PASTED. Replaces the tiny 50px images and the emoji file line.
* Turn a long text paste into a Pasted text card
Pasting a log, a spec or a file's contents filled the composer with a wall
of text. A paste of 2,000+ characters or 30+ lines now goes in the
attachment tray as a card instead, styled after claude.ai's: the opening
lines in small faint type over a PASTED badge, with an edit pencil and the
usual remove button. Clicking the card shows the whole text; the pencil
opens it for editing (saving it empty removes the card).
The paste is not a file: it is never saved to assets/. It is stored as a
text document block marked as pasted, so the sent message (and a reloaded
chat) shows the same card, and the model gets the whole text inline,
labelled as text the user pasted. Shorter pastes are unchanged.
* Keep a pasted text card in the composer draft
A long paste used to be composer text, so the draft saved it: a reload or a
trip to another project brought it back. As a card it lived only in memory
and was lost. The draft envelope now carries the cards (queued messages'
first, like their text), every add, edit or remove saves it, a restore puts
them back in the tray, and a send takes them out of the tray with the text.
Cards count toward the cloud mirror's size cap, and a card-only composer is
kept, not replaced, when the user signs in.
* Hand a pasted text card back when its send never lands
A composer send stopped before its message reached the conversation (Stop
while files upload) puts its text back in the box. A long paste used to be
part of that text; as a card it was dropped. The card now comes back with
the text. Files still don't: their blob URLs are about to be revoked.
* Send a pasted text card with a reply to a clarifying question
While the AI waits on clarifying questions, the composer's text is the
reply. A long paste used to be part of that text; as a card it was left out,
and a paste-only reply did nothing at all. The cards now go in the reply
after the typed text and leave the tray.
* Size the tray's file thumbnails like the pasted text card
Next to the 100px Pasted text card, a file was a 60px square with the file
icon stretched across it. Every tray thumbnail is now the same 100px
rounded card. An image fills it, with its name along the bottom; any other
file shows the file icon small and centred over its name. The marketing
pages' composer copies the app's tray, so it changes with it.
* Draw a queued message's pasted text as a card
The sent message shows a long paste as a Pasted text card, but the queued
message drew it as a plain 📄 Pasted text chip that did nothing. It now
uses the same card, and clicking it shows the text.
* Give each pasted text card its own name
A new card was numbered by counting the cards in the tray, so after
removing an earlier one the next paste reused a name still in use: two
"Pasted text 2" cards, and the model read both under the same label. A new
card now takes the lowest name not in use.
* Read a pasted text card as the user's words in titles and labels
A long paste used to be the message's text, so the project title, the
version label (and its GitHub commit message) and the naming/suggestion
transcript read it. As a card it is a document block those skipped: a
paste-only first message titled the project "New Chat" and its version
"Update". They now read the paste after any typed text.
* Announce a long paste that became a card
The paste never reaches the box, so a screen reader user heard nothing and
found the box empty. Say that it was attached, and under which name.
* Keep unsaved edits to a pasted card on a click outside
A click outside the Edit pasted text dialog closed it and threw the edits
away without a word. With unsaved changes it now keeps the dialog open and
puts the cursor back in the text. Cancel, the close button and Escape
still discard on purpose; an unchanged dialog still closes.
* Stop iOS from zooming in when the pasted text editor opens
The Edit pasted text dialog focuses its 12px text area itself, and iOS
Safari zooms the page into any field under 16px when it gets focus. On
screens up to 900px the text is 16px, as for the app's other dialog fields.
* Don't take a long paste into a read-only composer
While a send sets up, the composer is read-only and the browser drops a
short paste. A long one still went into the tray as a card, and the send's
draft clear then left it out of the draft.
* improve loading messages
* analytics
* drop the running build on stop, and don't count send now as abandoned
stopActiveTurn clears the build right away, so a Stop or a closed tab while
Send now's message is still being set up no longer reports the replaced build
and its wait time. Send now itself reports nothing: the user is still
building, only something else.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
* add message queueing
* fix message queue review findings
- a stopped turn that fails after the next one started shows no error card
- a message stopped during its upload always comes back to the box
- a clarify reply keeps queued messages in the draft
- a send clears only the files it sent from the tray
- a send takes its picked element when it starts
- test-pwa passes stop_svg
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>