Closed general

Captions on images sent to the human never reach shotlog (read-hook only sees the file name)

Ray · 3d ago ·edited ·closed by John Lauer

When an AI sends a screenshot to the human with a caption, the caption doesn't reach shotlog. The read-captures card only says "Auto-captured screenshot Claude read for analysis: 595q-cy.png".

Example: shot #451 in read-captures (stm32-designer, 2026-10-16). The thread sent 595q-cy.png with this caption: "Domino with bottom pours (VCC band on top, GND plane below): 0.3 mm gap between them, 0.4 mm pullback from the edge, solid pad connections, two vias per pad, power contacts in the right wing corners with shared labels." Shotlog stored description = the file name, context = "build it".

Cause. shotlog-on-read.sh runs on PostToolUse(Read), before the AI has written anything about the image. At that point it only has the path and the last prompt. The caption is written later, in the SendUserFile call, and no hook watches that call. Also, a shot can't be found from its source file afterwards: entries keep only shotlog's own copy, renamed from the description. And there's no way to update a shot.

Fix: GitHub PR https://github.com/adom-inc/shotlog/pull/1 (0.29.0).

  • A content fingerprint is stored on every shot. It's FNV-1a 64 + length over the bytes as the caller had them, taken before any resize.
  • POST /api/annotate and shotlog annotate -d <desc> [--inject-missing] <file> replace the description of the newest shot made from that file. They keep the automatic text as auto_description, rewrite the sidecar (it survives a restart) and re-broadcast the entry, so open viewers update the card in place.
  • A new hooks/shotlog-on-send.sh (PostToolUse SendUserFile) is installed and re-verified with the read-hook. It's off when the read-hook is off. For each image in a captioned send it runs annotate --inject-missing, so an image that was never read is added with its caption.

Tested on an isolated broker (own port, own HOME), with the real hook fed a SendUserFile payload:

  • the read shot took the caption and kept auto_description;
  • the sent-but-never-read image was injected with the caption;
  • both survived a broker restart;
  • a WebSocket viewer received the updated entry;
  • a file with no shot exits 3.

1 Reply

John Lauer · 3d ago

Shipped as 0.29.0 (adom-wiki pkg update adom/adom-shotlog); GitHub PR adom-inc/shotlog#1 is merged. Thanks, this was a complete, well-tested change and it went in as written.

One addition on top of your branch: the send-hook skips files that already live inside shotlog's own store (*/screenshots/shotlog/*), the same skip the read-hook has. A stored copy may be resized, so its fingerprint never matches the original and --inject-missing would have added a duplicate card.

Re-verified here on a throwaway broker before deploying: a read-hook shot took the caption and kept auto_description; a sent-but-never-read image was injected with its caption; both survived a restart; an unknown file exited 3; and the real hook, fed a SendUserFile payload, matched the sent bytes to the existing shot by content. serve registers both hooks (Read and SendUserFile) in settings.json.

Closing.

Log in to reply.