cmux NEXT composer: pasted screenshots never block typing; no image size cap
Leo, 2026-10-24, pasting Retina screenshots from the clipboard: "the attachments, they freeze. They still fucking freeze. I thought we fixed this before, but they freeze the composer. They literally, like this cannot be acceptable... I thought we removed the file size limit attachment situation... we shouldn't have this limit."
Why it came back. The earlier fix (#23885) showed a placeholder in the paste's own frame but left the image work on the main thread. #24652 then removed the "already fits" shortcut, so every screenshot is decoded and re-encoded (PNG, then JPEG when the PNG is over budget) and base64'd on the main thread, and the chip decodes it a second time for its thumbnail. A 3456x2234 screenshot stalls the page for hundreds of ms, once per image.
What changes
- The decode, scale, encode, base64 and thumbnail run in a module worker beside the page (
image-worker.js, built bybuild-agent-pane-web.shlikehighlight-worker.js, served under the same no-network resource policy). The Vite dev server serves the module itself. Where no worker starts, the worker can't draw (no OffscreenCanvas there), or a job goes unanswered for 20 s, the page does the work as before. - The chip's thumbnail comes from the same decode (kept by chip id), not a second decode.
- No size cap: an image past every fit step goes as its smallest try (a 512 px JPEG), never refused as "too large". An image the engine can't decode goes as a file, as a convertible one already did.
Red then green (webviews/test/agent-pane-paste-large-screenshots.test.ts, Chromium): pastes three 8.5 MB Retina-sized PNGs, types while they attach, and records the main thread's longest stall with a 4 ms heartbeat.
| longest stall (3 runs) | chips ready | |
|---|---|---|
| base | 315 / 326 / 466 ms (fails, limit 120 ms) | ~2.1 s |
| this PR | 47 / 56 / 42 ms | ~1.7 s |
Tests: the new test, composer-image-fit and attachment-session-paths (updated: the thumbnail is drawn in the same pass, and "too large" is gone), agent-pane-attach-typing, attachment-thumbnails. Other attachment browser tests fail the same way on base. The WebKit engine doesn't launch on this host, so WebKit got no local run; CI's browser lane covers it.
Risk: the worker is new. If it fails to start or answer, the page falls back to the old main-thread path, so the worst case is today's behaviour. The stuck-placeholder half of Leo's report (spinner, cancel, retry, host deadlines) is the stacked follow-up.
Agent session: huge-blue
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.