Skip to content

release: 1.39.0 — see what a session looked at, attach files, update all Claude sessions - #48

Closed
writingdeveloper wants to merge 4 commits into
mainfrom
feat/session-images-attach-update
Closed

writingdeveloper wants to merge 4 commits into
mainfrom
feat/session-images-attach-update

Conversation

@writingdeveloper

Copy link
Copy Markdown
Owner

Summary

  • Image strip (🖼 in the tile header): the screenshots, pasted images and image files a Claude session handled, newest first, with a full-size viewer (←/→, Esc, Save). Read from the transcript — an MCP screenshot exists nowhere else — incrementally (133MB transcript: 100ms first, 1ms after). +N badge for images that arrived unseen. Works for sessions on another machine (thumbnails encoded on the host).
  • Remote image paths are viewable: clicking an image path in a remote session now shows it instead of "that file is on ".
  • Attach files: 📎 and drag-and-drop on the terminal. Local = the file's own path; remote = image converted to PNG, sent, host path typed.
  • Update all Claude sessions: on Windows claude update fails while any session holds claude.exe. When a screen shows "Auto-update failed" (or "Update installed" with others to take along): wait out turns → stop all → claude update → resume every conversation by id.
  • Hardening from review: image reads by a paired observe device are limited to the session's indexed images, realpath-contained, magic-byte sniffed; decode work capped; full views bounded so they never exceed the link frame.

Test plan

  • 1,431 unit tests, tsc
  • build, check:docs, qa:maintenance, qa:resilience, qa:session-sync, qa:audit, qa
  • new: qa:images (7), qa:images-remote (4, two instances over real TLS), qa:update (3) — fixture CLIs, isolated homes

🤖 Generated with Claude Code

https://claude.ai/code/session_016NLGwiBY5uEivJqERQzcoY

writingdeveloper and others added 4 commits October 20, 2026 10:56
…e sessions

Images a session handled, seen at a glance. Claude Desktop shows tool screenshots and pasted images
inline; a terminal cannot, so the cockpit now shows them in a strip between the header and the
terminal, newest first, with a full-size viewer (arrows step, Esc closes, Save). The source is the
transcript itself — an MCP screenshot exists nowhere else on disk, only as a base64 block in the tool
result — indexed incrementally (first look reads the last 64MB; measured 133MB transcript: 100ms,
then 1ms per unchanged re-read). The header button shows the count, and "+N" for images that arrived
while the strip was closed. Works for sessions on another machine: thumbnails are made where the
image lives, so a 4K screenshot crosses the link as a ~30KB JPEG.

A remote session's image path is now viewable: clicking one used to say "that file is on <machine>";
its pixels are read over there and shown here.

Attach files: 📎 in the header and drag-and-drop onto the terminal. Locally the file's own path is
typed into the prompt; for a session on another machine an image is converted to PNG (scaled down
until it fits the 5MB the host accepts) and sent, and the host's path is typed. Anything that could
not be attached is reported, never silently dropped.

Update all Claude sessions: on Windows the updater cannot replace claude.exe while any session runs
it, so with a deck of sessions open the background update fails forever. When a Claude screen shows
"Auto-update failed" (or "Update installed" with other sessions to take along), the header offers
"Update all (N)": wait out running turns, stop every local Claude session, run `claude update`, and
resume each conversation by id — reopened even if the update failed.

New harnesses qa:images and qa:update drive all of this in the real app with fixture CLIs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016NLGwiBY5uEivJqERQzcoY
…-all races

From review of the previous commit:
- A device holding only `observe` could read any file named like an image: containment was lexical
  (a .png symlink or junction inside a project reached outside it), undecodable bytes were sent raw,
  and all of %TEMP% counted. Now the real path must also be inside the folder, the bytes must sniff
  as an image, only Claude's scratch area and DevDeck's own pastes count in temp, and
  cockpit:sessionImage serves only ids the session's index holds.
- Image decode/encode runs on the main process: at most 3 at a time, thumbnails cached.
- A tall full-page screenshot could exceed the 8MB link frame and drop the connection; full views are
  now bounded in both dimensions and re-encoded until they fit, or not sent.
- Clicking a thumbnail after a refresh opened the newest image (stale object identity); a list
  arriving after a meta/git refresh was discarded (source compared by object, not key); the "+N"
  badge stopped counting at the 300-image cap (now tracks the last-seen id).
- Update all: a queued single-tile update no longer fires mid-way; tiles at a permission prompt are
  waited for too; past 15 minutes it gives up instead of killing a turn; the tiles are saved as
  restorable before they are closed, so a quit during the update loses nothing; several waiters on
  one tile's exit no longer clobber each other.

qa:images now also asserts that a non-image .png, a path outside the project, a relative escape, a
junction out of the project and an unindexed id are all refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016NLGwiBY5uEivJqERQzcoY
…images-remote

A tall image overflowed the viewer's stage and drew over the bottom bar (counter, caption, Save were
hidden): max-height: 100% never resolved inside a content-sized grid row. The stage is now a flex box
with a definite height and clips.

qa:images-remote pairs a host and a viewer over real TLS and drives the image strip, the full view,
a JPEG attach (sent as PNG, host path typed) and the link-side refusals from the viewer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016NLGwiBY5uEivJqERQzcoY
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016NLGwiBY5uEivJqERQzcoY
@writingdeveloper

Copy link
Copy Markdown
Owner Author

Landed on main as cd90288 via local squash merge (noreply author). Tagged v1.39.0.

writingdeveloper added a commit that referenced this pull request Oct 20, 2026
…all Claude sessions (#48)

- Image strip (header 🖼): the screenshots, pasted images and image files a Claude session handled,
  newest first, with a full-size viewer (arrows, Esc, Save) and a "+N" badge for unseen ones. Read
  from the transcript incrementally (133MB: 100ms first, 1ms after). Works for remote sessions —
  thumbnails are encoded where the image lives.
- A remote session's image path is now viewable instead of "that file is on <machine>".
- Attach files: 📎 and drag-and-drop onto the terminal. Locally the file's own path is typed; for a
  remote session an image is converted to PNG, sent, and the host's path is typed.
- Update all Claude sessions: on Windows `claude update` fails while any session holds claude.exe.
  When a screen shows "Auto-update failed" (or "Update installed" with others to take along), wait
  out turns, stop every local Claude session, run `claude update`, resume each conversation by id.
- Image reads by a paired `observe` device: only the session's indexed images, realpath-contained,
  magic-byte sniffed; decode work capped at 3; full views bounded to fit the link frame.
- New harnesses: qa:images, qa:images-remote (two instances, real TLS), qa:update.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016NLGwiBY5uEivJqERQzcoY
@writingdeveloper
writingdeveloper deleted the feat/session-images-attach-update branch October 20, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant