Skip to content

Commit 010b31a

Browse files
authored
fix(web): preview image deliverables (#149)
## Summary - Render generated image outputs directly in the deliverables card and an accessible full-size viewer. - Keep preview fetches lazy, signed, bounded to 20 MiB, and isolated from sandbox startup. - Open generated images directly in the Files editor instead of selecting their parent directory. ## Architecture The web app exchanges the existing short-lived download capability for an authenticated image blob. Object URLs stay browser-local and are revoked on cleanup. File-open requests are transient UI state sent to the trusted Code Server frame and acknowledged by the injected preview bridge. ## Decisions | Decision | Choice | Reasoning | |---|---|---| | Preview transport | Existing signed output URL | Preserves the R2 boundary and does not expose credentials | | Loading | Intersection-observer lazy loading | Avoids fetching off-screen images or waking the sandbox | | Files handoff | Exact relative workspace path with frame acknowledgement | Opens the file users selected and rejects traversal paths | | Viewer | Existing modal primitive | Preserves focus, Escape handling, and screen-reader semantics | ## Edge cases - Images over 20 MiB remain downloadable but are not loaded inline. - Empty or non-image responses show a recoverable preview error. - Unsafe filenames cannot be sent to the sandbox editor. - Requests are scoped to the active thread and exact trusted iframe origin. ## Checks - [x] `pnpm turbo typecheck` - [x] `pnpm turbo lint` - [x] `pnpm turbo build` - [ ] Production image deliverable QA after deployment
1 parent 76c5447 commit 010b31a

8 files changed

Lines changed: 574 additions & 36 deletions

File tree

apps/web/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ partial or corrupt transcript is never rendered as a duplicate assistant message
1111

1212
Deliverable parts contain durable output identity and presentation metadata, never an expiring
1313
URL. A download click calls the authenticated gateway mint endpoint, validates its bounded response,
14-
and follows the resulting short-lived capability directly to the streaming response.
14+
and follows the resulting short-lived capability directly to the streaming response. Image
15+
deliverables lazily exchange that same capability for a bounded in-memory blob when they approach
16+
the viewport, render an inline thumbnail, and reuse the blob in an accessible full-size viewer.
17+
No image capability or object URL is persisted. Opening an image in Files switches to the project
18+
workspace and asks the trusted code-server bridge to reveal the exact generated asset; an already
19+
visible Files panel selects a newly generated image without waking a closed sandbox.
1520

1621
Composer uploads always land in a writable project. If none is selected, choosing the first
1722
valid file creates and selects a general project named from that file. Files upload sequentially

0 commit comments

Comments
 (0)