feat(web): pasting a huge screenshot now compresses it instead of erroring - #4967
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR introduces new feature behavior (compressing oversized images instead of rejecting them) with async state management and race condition handling. Additionally, there are two unresolved medium-severity review comments identifying potential bugs in the error clearing and slot reservation logic. You can customize Macroscope's approvability policy. Learn more. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e765e2c. Configure here.
* fix(desktop): restore T3 Connect sign-in (pingdotgg#4809) Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * Simplify files panel header (pingdotgg#4828) * build(desktop): reduce installed app size by ~300MB (pingdotgg#4824) * Update model version from claude-opus-4-8 to claude-opus-5 (pingdotgg#4832) * Preserve the thread shell while detail loads (pingdotgg#4830) * Reduce idle work and disk churn with native resource diagnostics (pingdotgg#2679) Co-authored-by: codex <codex@users.noreply.github.com> * fix(server): detect repositories after initialization (pingdotgg#4848) * perf(server): merge separate staged/unstaged numstat calls into single diff HEAD --numstat (pingdotgg#4843) * fix(git): disable external diff for review diff previews (pingdotgg#4854) * Fix editable file focus and live syntax highlighting (pingdotgg#3979) * fix(web): remember the rendered-markdown choice across threads (pingdotgg#4853) Co-authored-by: Simon Doba <simon.doba@orbit.de> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * chore(release): prepare v0.0.31 * fix(mobile): reduce thread feed scroll jank (pingdotgg#4874) * fix(web): restore sidebar v2 thread actions and terminal icon (pingdotgg#4712) * fix(web): settle button now works on hover, not just right-click (pingdotgg#4905) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(clients): disable add project while disconnected (pingdotgg#4834) * fix(composer): hide default Codex service tier (pingdotgg#4784) * docs: link iOS and Android app store downloads (pingdotgg#4902) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(web): align remote server update action (pingdotgg#4731) * fix(connect): suggest a serve command that matches how you ran connect (pingdotgg#4897) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(mobile): stop shared content errors in Personal Team builds (pingdotgg#4943) * perf(mobile): sends respond instantly, thread opens stop freezing (pingdotgg#4882) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(web): show Codex fast mode as a bolt (pingdotgg#4947) * docs: seed worktrees with a copy of real userdata instead of banning it (pingdotgg#4949) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(mobile): support dragged images in the composer (pingdotgg#4953) * fix(mobile): stop long iOS threads from jumping while scrolling up (pingdotgg#4867) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * fix(web): keep worktree default when switching a draft's machine (pingdotgg#4964) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * perf(mobile): reconnect environments immediately on resume (pingdotgg#4878) * feat(web): pasting a huge screenshot now compresses it instead of erroring (pingdotgg#4967) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * feat(web): regenerate thread titles from sidebar (pingdotgg#4810) * fix(web): show server update progress through reconnect (pingdotgg#4903) --------- Co-authored-by: Alex <me@pixp.cc> Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: wukko <me@wukko.me> Co-authored-by: codex <codex@users.noreply.github.com> Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com> Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com> Co-authored-by: ohbentos <72638975+ohbentos@users.noreply.github.com> Co-authored-by: Jake Leventhal <jakeleventhal@me.com> Co-authored-by: Simon Doba <simon.doba@hotmail.de> Co-authored-by: Simon Doba <simon.doba@orbit.de> Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: Gabriel De Andrade <30420087+gabrielelpidio@users.noreply.github.com> Co-authored-by: Jono Kemball <Noojuno@users.noreply.github.com> Co-authored-by: Theo Browne <me@t3.gg> Co-authored-by: Max Katz <me@maxkatz.me>
## What's Changed * fix(mobile): support dragged images in the composer by @t3dotgg in pingdotgg/t3code#4953 * fix(mobile): stop long iOS threads from jumping while scrolling up by @t3dotgg in pingdotgg/t3code#4867 * fix(web): keep worktree default when switching a draft's machine by @t3dotgg in pingdotgg/t3code#4964 * perf(mobile): reconnect environments immediately on resume by @t3dotgg in pingdotgg/t3code#4878 * feat(web): pasting a huge screenshot now compresses it instead of erroring by @t3dotgg in pingdotgg/t3code#4967 * feat(web): regenerate thread titles from sidebar by @t3dotgg in pingdotgg/t3code#4810 * fix(web): show server update progress through reconnect by @t3dotgg in pingdotgg/t3code#4903 * feat(search): find threads by conversation content by @t3dotgg in pingdotgg/t3code#4959 * fix: marketing site Vercel builds no longer die after ~100 deploys by @t3dotgg in pingdotgg/t3code#4975 **Full Changelog**: pingdotgg/t3code@v0.0.32-nightly.20260730.955...v0.0.32-nightly.20260730.956 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.32-nightly.20260730.956
27 commits from main, including the ⌘P file picker / ⇧⌘F content search (#4855), thread content search (#4959), sidebar title regeneration (#4810), image-paste compression (#4967), and the docs restructure (#4807). Notable resolutions beyond keep-both: - Thread content search is ported to the v2 surface: searchThreads joins ORCHESTRATION_V2_WS_METHODS/rpc/auth scopes, and the SQL now UNIONs orchestration_v2_projection_messages so current threads are searchable, not just legacy-projected ones. - Title regeneration's server half lived in the v1 ProviderCommandReactor this branch deletes, so the capability is deliberately not advertised: clients hide the action, the contract/UI code stays intact, and the input field is accepted as a documented no-op. TODO(orchestration-v2): port regeneration to the v2 runtime. - Main's 035_ProjectionThreadTitleRegeneration migration collided with this branch's 035-043 range; renumbered to 044. - Mobile activity grouping keeps this branch's runId/prominence semantics while adopting main's O(1) trailing-group optimization (prominence tracked in a flag instead of a per-append scan). - v1-only startup tests from main (heartbeat/auto-bootstrap against the deleted reactor-era services) are dropped; their v2 equivalents already cover the ordered startup phases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Pasting or dropping an image over 10MB into the composer just failed with "exceeds the 10MB attachment limit" — annoying for big retina screenshots that would survive compression with no meaningful quality loss.
Now oversized images are downscaled and re-encoded (WebP, JPEG fallback) to fit under the 10MB wire cap, reusing the same pipeline that already compresses images for the prompt stash.
stashImageCompression.tsbecame the sharedimageCompression.tswith a newcompressImageToByteLimitentry point; stash behavior is unchanged. Images already under the cap still pass through byte-for-byte.Sources over 50MB are refused outright — file size is a proxy for pixel count, and decoding something that large into an ImageBitmap risks OOMing the tab.
Web only: mobile's paste path has no canvas and keeps its existing 10MB reject.
Written by Claude Fable 5 via Claude Code.
🤖 Generated with Claude Code
Note
Medium Risk
Changes user-facing send/attach behavior and runs canvas decode/re-encode on large pastes in the main composer path; failures are handled but wrong timing could still strand attachments or block send unexpectedly.
Overview
Pasting or dropping images larger than the provider wire cap no longer fails with a size error — they are downscaled and re-encoded (WebP/JPEG) to fit under
PROVIDER_SEND_TURN_MAX_IMAGE_BYTES, while files already under the cap still attach byte-for-byte.stashImageCompressionis consolidated into sharedimageCompression.ts: stash behavior stays oncompressImageForStash, andcompressImageToByteLimitreturns a re-encodedFilefor the composer. A sharedreencodeWithinBudgetloop handles both paths; sources aboveMAX_COMPRESSIBLE_SOURCE_BYTES(50MB) are refused without decoding to avoid tab OOM.addComposerImagesis now async: it reserves attachment slots via a per-thread pending compression counter (so concurrent pastes respect the limit), compresses each accepted file, then updates preview/name/type from the result.submitComposerblocks send while compression is in flight and shows an info toast so a turn snapshot cannot miss an in-progress paste.Reviewed by Cursor Bugbot for commit e765e2c. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Compress oversized pasted or dropped images instead of rejecting them
compressImageToByteLimitin imageCompression.ts that downscales and re-encodes image files to WebP/JPEG to fit the provider wire cap (PROVIDER_SEND_TURN_MAX_IMAGE_BYTES); files already within the limit pass through unchanged.MAX_COMPRESSIBLE_SOURCE_BYTESare refused without decoding to avoid memory issues. Risk: users who previously received an error for large images will now see a delay before the compressed image appears.Macroscope summarized e765e2c.