cmux NEXT composer: pasted screenshots never block typing; no image size cap

Merged
TE
12d ago
+628-152

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 by build-agent-pane-web.sh like highlight-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
base315 / 326 / 466 ms (fails, limit 120 ms)~2.1 s
this PR47 / 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 Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.