Agent chat: screenshots inline (glass thumbnails, before/after side by side); commits, hq#N, file:line link

Merged
TE
15d ago
+817-33

Agents kept describing UI in words ("a thinner group-colored line, a small gap under the header…") because the agent chat didn't show their screenshots well. Now a reply shows them:

  • Screenshots as thumbnails. ![alt](/abs/path.png), file:// URLs, https image addresses (PR pr-media links on raw.githubusercontent.com) and data URLs draw in a glass thumbnail with a fixed 16:10 frame, up to 480pt wide. Every state (waiting, Load image, unavailable, shown) uses the same frame, so a loading image never moves the reply. A click opens the existing image viewer at full size.
  • Bare image paths. A paragraph that is only image paths draws as thumbnails. An image path inside a sentence stays a path chip, and its thumbnail draws under the paragraph (or under the list item).
  • Before/after side by side. Two or more images in one paragraph form a row with equal widths, captioned by alt text or by a Before: / **After:** label. A label is one to three words ending in :; a sentence ending in : stays prose with its thumbnail under it. A label alone with one image is that image's caption. Two forms work: ![Before](a.png) ![After](b.png), or Before: /tmp/a.png and After: /tmp/b.png on two lines.
  • References link the same way #N does.
    • hq#N links to manaflow-ai/cmuxterm-hq, in agent replies only (the document editor doesn't take aliases); any other word#N stays text.
    • Commit SHAs (7–40 hex characters with a letter and a digit) and owner/repo@sha link to the commit page. A SHA inside a URL or path (app.js?v=3a7bd3e2) stays part of that chip.
    • A relative src/app.ts:42 (compiler style, which must have the line) is a path chip, in prose and in code spans. A path chip's label keeps the :42.
  • Agent docs. The cmux and acpmux skills and both MCP server instruction strings now tell agents to embed screenshots this way.

Host policy is unchanged (decision D5): files inside the session's folders load at once, a web image still needs a click under agentPane.images.remote = click, and a file outside the folders shows its card with Open.

Images and image-only paragraphs wait until a streaming paragraph has finished arriving. The relative file:line scan never restarts after a +, so long base64 runs stay linear (the test bounds 260 KB at well under 500 ms).

Tests: webviews/test/inline-media.test.tsx covers every parse case: image-only paragraphs, prose images, file:line, aliases, commits with their false-positive cases, plus rendered before/after, waiting-frame, pr-media and link cases. 96 tests across it and the neighbouring link and image suites pass on cmux16, and bun run check passes there. Gallery entry agent-pane.inline-media (before-after, labelled-lines, path-in-sentence, pr-media) gives the Linux gallery stills.

No capture: webview-only UI; the gallery advisory run captures it.

🤖 Generated with Claude Code

Agent session: cosmic-gray