fix(cmux-next): a local reply image loads when the host answers its path
Summary
A local image in an agent's reply (a file inside the chat's folders) never loaded; it stayed as its alt text. The chips/linkStore.ts hooks subscribed to a version number and read the path and site maps beside it. The React Compiler cached those reads by path, so when the host's link.inspect answer arrived, the image re-rendered with the old "still asking" value.
The hooks now read each value through its own useSyncExternalStore snapshot. This also fixes link favicons and titles (useSiteInfo), ReplyMedia, and the reply policy, which had the same stale cache. A full store's clear now notifies, so hooks ask again for keys it forgot.
The gallery entry agent-pane.reply-image#local no longer seeds the path's answer. It waits on the host's answer, as in the app.
Changelog
- Fixed: images an agent shows from files in the chat's folders load instead of staying as their alt text.
Test
cd webviews && CMUX_BROWSER_TESTS=1 bun test test/gallery-agent-pane-entries.test.ts -t reply-image
- red (test commit, old
linkStore.ts):agent-pane.reply-image#localfails because no image loaded - head: passes. The whole file: 14 pass.
Compiling linkStore.ts with babel-plugin-react-compiler shows the old output caching paths.get(path) and asking.has(path) keyed on path alone. The new output caches only the reader closures.
Observed / Not run
- Observed: the red and green runs above.
url-chip-hover,reply-image-reload,link-cards,pr-hover-cardandbare-pr-refs: 17 pass.url-chip-hover's coalescing check now seeds keys its probe reads, because a key no hook reads no longer renders anything. An independent review subagent passed it.prepush-gate.py: no new violations. - Not run: a native capture. This is web-only.
No capture: web pane behavior fix, shown by the gallery entry agent-pane.reply-image#local.
Agent session: huge-blue
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes local reply images (images an agent shows from files in the chat's folders) loading instead of staying as their alt text.
The linkStore hooks subscribed to a store version number and read the path and site maps beside it. When the host's answer arrived, the React Compiler's cached reads by path returned the old "still asking" value, so the image never re-rendered with the answer. The hooks now read each value through its own useSyncExternalStore snapshot. This also fixes the same stale cache in link favicons/titles, ReplyMedia, and the reply policy. Clearing the whole store now notifies listeners so hooks re-ask for keys they forgot.
The gallery entry agent-pane.reply-image#local no longer seeds the path's answer; it waits on the host's answer as in the app.