1. summarizeCanvas() walked only node.nodes, so everything inside Section/ColumnLayout/forms
(linkedNodes) was missing and live self-reviews could only name top-level sections. It now
walks nodes + linked slots (stable key order) and lists id, type and key props (text first,
links, main style values as style.<key>, colour-like props) as key="value", within a
documented budget (150 nodes, 6000 chars, 300 chars of props per line; detail is dropped
before nodes; cuts happen at line boundaries -- a mid-line cut used to make the server
refuse the whole review). HtmlBlock code is no longer summarised.
applyPatch no longer counts an op with nothing left to set as a change; ops that did nothing
are counted per reason. The self-review note and console say why ops were dropped (server
and editor reasons, counts only). Real-browser test 8n builds a nested page, sends the real
summary through the real WHP review lockdown (php) and checks the nested edit takes effect
while link/text edits, unknown ids and deletes are dropped.
3. Background placeholders use ?text=%E2%80%8B (measured: placehold.co then draws no glyphs;
the same-colour label left a 4-colour ghost in its PNG); the capture draws no <text> for a
zero-width or same-colour label. Pixel test on the case-4 hero markup in both browsers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185ukXgk6UunFCKyXqLe2Cq
Reproduced in the e2e mock (now stateful: history + clear_history with the
server's 409 while a job is live): the normal two-step clear works (first
click arms the confirm by design), but a confirm while a job is live -- e.g.
the self-review follow-up that starts right after a send -- was refused by the
server and the modal showed the raw code 'job_in_progress', so the chat looked
like it would not clear on the first try. Now the server's sentence is shown,
and the button is disabled (with a tooltip) while a send, resume or self-review
is running. e2e scenarios 9, 9b (failed before), 9c (Firefox + Chromium).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The render is uploaded with the new review_render_upload action (backend kind
review_render, the only image a review job accepts); mocks follow.
- summarizeCanvas() never lets a newline or a quote into a node line (the server
validates review summaries line by line); test.
- test:browser:sitesmith-cleaned (Firefox + Chromium): a page published from a
cleaned ordinary Sitesmith response requests nothing outside the allow-listed
hosts (own assets, fonts, Font Awesome CDN, images.pexels.com, placehold.co)
and has no inline handlers or javascript:/data: URL attributes; the same
response uncleaned is the control (requests example.com). All requests are
answered or aborted locally.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The self-review follow-up sends intent:'review' + review_image_ids instead of
putting the render in mockup_ids, so the backend builds a critique+patch
instruction instead of 'build toward this mockup'. Render still deleted after.
- types/sitesmith.ts: SitesmithStatus = server statuses (adds IMAGES_BUSY,
TOO_MANY_JOBS, SERVER_BUSY, ...) + client statuses (TIMEOUT, ABORTED, ...);
network status strings are narrowed with a type guard (unknown -> ERROR);
the hook builds SendResultErr without casts.
- statusMessages.ts: one specific message per status (a Record over the union,
so a new status without a message fails tsc), used by the modal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>