fix: preview local reply images safely
Fixes local image replies so a path such as /tmp/cx-lanes/sidebar-clean-cmux.png loads inline as a bounded thumbnail and opens visibly in a WebKit file viewer.
Leo reported: "why dont we have a preview for thsi".
Changes:
- allow image reads from the chat cwd,
/tmp, and the user's home while keeping ordinary path chips on their existing project-root gate; - reject non-image extensions at the native image boundary and normalize fragments, overflow, color space, and large PNGs;
- route image/PDF file tabs through WebKit's scoped local reader;
- fetch remote-chat images from the owning host through the session attachment media reader, never from a same-named local path;
- add web, Swift, and host-side media coverage for local thumbnails, outside-root gating, remote paths, and large PNG visibility.
The image roots are read-only and image-only. Paths outside the cwd, /tmp, and home remain gated for privacy. Remote chats use their host's cwd, /tmp, home, and upload roots through the media reader; the local app never resolves those paths.
Checks:
bun test test/inline-media.test.tsx test/agent-message-card.test.tsx test/image-viewer-actions.test.tsx(62 passed)- exact-head fleet Swift package suite: pending
- exact-head fleet Rust media suite: pending
git diff --check
State: checks pending
Owner: Codex session 01a16a5b-a74a-7071-b5ae-aa82ac49b237
Head: 1fb9bd483efa730ddb11357cfb4333093efa9bef
Next: reconcile exact-head fleet checks, review, and guarded merge
Evidence: fleet jobs 6f964d89a2b297c0e2b8fb1c and 48f5b6b1cc3726ade2f3c36d
Stop: none
Agent session: huge-blue
Before / after capture
Fleet gallery advisory run 40032701815 rendered the local reply-image chat state (agent-pane.inline-media/path-in-sentence) from the merge base and landed head in both themes. The landed view shows the local image thumbnail inline.
| Light | Dark | |
|---|---|---|
| Before — #24619 base | ![]() | ![]() |
| After — landed #24619 | ![]() | ![]() |
The pre-existing Rust media-reader race is tracked in #24656: hub::media_read::tests::a_file_swapped_for_a_symlink_is_never_followed fails when run alone.
![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.
Summary by cubic
Fixes local image replies so a path like /tmp/cx-lanes/sidebar-clean-cmux.png loads inline as a bounded thumbnail and opens visibly in a WebKit file viewer.
Image scope
- Local reply images may be read from the chat's cwd,
/tmp, and the user's home; ordinary path chips stay gated to the project root. - Local
file://URLs are accepted only for the local host, and query/fragment decoration is stripped before path resolution; foreign-host URLs are rejected. - Remote chat images are read from the owning host through the acpmux media reader, so a same-named local file is never used; the host scopes paths to its own cwd,
/tmp, home, and upload roots. - The native image boundary rejects non-image extensions and normalizes PNGs (overflow, color profile, large size) before display.
Viewer
- Image and PDF tabs now route through WebKit's scoped
loadFileURLreader, which displays large RGBA PNGs that CEF painted black.



