← All Pull Requests

read-hook: give every auto-captured shot a handle derived from its filename #3

Closed opened by Ray 2026-09-02

Complements adom/adom-shotlog#2 and closes the root cause behind adom/adom-shotlog#5.

--tag shipped in 0.28.2 and works. The problem is that the read-hook never passes one, and the read-hook is what produces nearly every shot. On this box that was 151 of 151 untagged, so the human could only point at shots positionally.

Change

One derived handle, from the source filename:

TAG="$(printf %s "${base%.*}" | tr -c A-Za-z0-9._- - | sed ... | cut -c1-16)"
...
shotlog inject -c read-captures ... ${TAG:+--tag "$TAG"} ...

The filename is already what the human reads in the description, so it is the handle they would reach for anyway. A deliberate inject --tag still wins; this only fills the gap the hook itself leaves.

Verified end to end

Ran the patched hook with a simulated Read payload against the live 0.28.2 broker:

   REF  HANDLE              AGE  DESCRIPTION
  #151  —               16h ago  Auto-captured screenshot Claude read for analysis: fin_a.…
  #152  heroTagTest    just now  Auto-captured screenshot Claude read for analysis: heroTa…

152 shots · 1 tagged.

Before the change every row in that column was a dash.

  • cargo build --release clean, 7 warnings, identical to the pre-change baseline.
  • include_str!("../hooks/shotlog-on-read.sh") means the repo file IS the shipped one; confirmed the new flag is in the rebuilt binary.
  • Hook still exits 0 on every path, so it can never block a Read.

Note on scope

I deliberately did NOT try to infer a semantic handle (heroG, heroH). The hook cannot know intent, and guessing would produce worse handles than the filename. Making every auto-capture referenceable is the part that was missing.

Not merging this myself, adom-shotlog is yours.

Diff Skip to comments (1)

--- a/hooks/shotlog-on-read.sh+++ b/hooks/shotlog-on-read.sh@@ -1,106 +1,116 @@⋯ 37 unchanged lines ⋯  base="$(basename "$f")" +# HANDLE: derive a short, stable handle from the source filename so an+# auto-captured shot can be POINTED AT. Without one the human can only refer to+# shots positionally ("the top one", "your last 2"), which is exactly how a hero+# image iteration went wrong: 151 auto-captured shots, 0 tagged (issue #5).+# The filename is what the human already sees in the description, so it is the+# handle they would reach for anyway. A deliberate `inject --tag` still wins;+# this only fills the gap the hook itself leaves.+TAG="$(printf '%s' "${base%.*}" | tr -c 'A-Za-z0-9._-' '-' | sed 's/^[-._]*//; s/[-._]*$//' | cut -c1-16)"+ # Attribute the capture to the AI THREAD that read the image: the hook payload # carries session_id + transcript_path; the transcript's ai-title records hold # the thread's human-readable title.⋯ 51 unchanged lines ⋯ for attempt in 1 2 3; do   if shotlog inject -c read-captures \     -d "Auto-captured screenshot Claude read for analysis: ${base}" \-    -s "$SRC" ${THREAD:+--thread "$THREAD"} ${CONTEXT:+--context "$CONTEXT"} $META_ARGS $ORIG_ARGS "$f" >/dev/null 2>&1; then+    -s "$SRC" ${TAG:+--tag "$TAG"} ${THREAD:+--thread "$THREAD"} ${CONTEXT:+--context "$CONTEXT"} $META_ARGS $ORIG_ARGS "$f" >/dev/null 2>&1; then     break   fi   sleep 2⋯ 2 unchanged lines ⋯ done  exit 0+

Comments

John Lauer · 1mo ago

Applied in 0.28.3 with one adaptation: the handle is derived only when the filename stem is wordy (3+ letters and more letters than digits). Bridge captures are timestamp-named, and a 2026-09-02T12-59 chip on every card would be noise; those shots already have their ref. board_v3-front.png -> board_v3-front, heroG.png -> heroG, IMG_1234.png and 2026-09-02T12-59-09.647.png -> ref only. Closing rather than merging (older base); credited in the hook comment. Thanks.

Log in to comment.