Summary
Expose termherd's window screenshot (the F-capture rung-1 PNG, #108) as an MCP
screenshot tool, so a driving Claude session can see the rendered UI — the
pixel companion to the text snapshot (#212). Child of #90.
Why it is its own slice
Unlike snapshot/list_sessions, a screenshot is not a pure read of
core::App state. The pixels come from an async iced window::screenshot
Task (see Shell::perform_capture), so answering the tool needs a different
bridge shape than the timeout-bounded state read the current bridge provides:
the shell must trigger the window screenshot, await it, encode a PNG, and return
bytes. That async round-trip (and how MCP carries the image content) is the real
work here, kept out of #212 so the snapshot slice stayed a clean state read.
Scope
Depends on
#212 (perception surface) and #193 (live bridge). Reuses the F-capture PNG
pipeline (#108).
Summary
Expose termherd's window screenshot (the F-capture rung-1 PNG, #108) as an MCP
screenshottool, so a driving Claude session can see the rendered UI — thepixel companion to the text
snapshot(#212). Child of #90.Why it is its own slice
Unlike
snapshot/list_sessions, a screenshot is not a pure read ofcore::Appstate. The pixels come from an async icedwindow::screenshotTask (see
Shell::perform_capture), so answering the tool needs a differentbridge shape than the timeout-bounded state read the current bridge provides:
the shell must trigger the window screenshot, await it, encode a PNG, and return
bytes. That async round-trip (and how MCP carries the image content) is the real
work here, kept out of #212 so the snapshot slice stayed a clean state read.
Scope
bytes (or a saved path), bounded by a timeout like the state read.
screenshotMCP tool returning image content.the text
snapshotstaying the reliable path.Depends on
#212 (perception surface) and #193 (live bridge). Reuses the F-capture PNG
pipeline (#108).