mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-14 06:33:09 -06:00
9327c10d2b
* feat(ui): edit a queued chat message in place The pencil on a queued row, or a double-click, lifts the message and its attachments into the composer. The row stays where it is, marked Editing, so the position the corrected message will take is visible rather than promised. The composer shows an edit banner with an X to cancel. Cancelling touches storage not at all, because the row never left the queue. Sending retires the original and hands its position to the replacement, which lands in the same slot. While an edit is open the drain refuses that row, so a reconnect cannot deliver the text the operator is visibly rewriting; the queue behind it waits, which is the same contract the held position promises. * fix(ui): retire an edited queued row only with its replacement The send retired the source row first and admitted the replacement second, so a rejected store write left the operator with neither: the original gone, the replacement never persisted, and the attachments it dropped already released. Admission now carries the source id and swaps both rows in one store write, so a rejected write changes nothing and the edit stays open on the row that is still there, which is what cancelling already promises. Filtering the source before the cap check also keeps a replacement admissible on a full queue. The edit token recorded only the session key, but an outbox is scoped by session and agent, and a raw global session keeps its key while the selected agent changes underneath it. The token now carries the agent that owned the row and every reader validates the whole scope, so a send after a switch cannot retire a row in the outbox it left behind. * fix(ui): hold an edited queued row across every pane Panes share one outbox and one drain lane while composer state stays per pane, so the hold that keeps a row from being delivered while it is rewritten was invisible to the pane that drained it: a session event in a second split pane resumed every stored outbox, saw no edit, and sent the original text. The hold is now read across every pane subscribed to the outbox, which keeps one source of truth — each pane's own scope-validated edit — and needs no lifecycle of its own, so closing a pane or switching agent releases it by simply no longer being an active edit. The payloads an edit owns now travel with its token. The write that admits the replacement retires the source row and tells every pane synchronously, so by the time the send released the images the replacement had dropped, the row holding them was already gone and nothing was released. That leaked the payload and its object URL for the rest of the browser session. * fix(ui): release attachments from cancelled queue edits