← Commit history
Cargo.lock+1−1
@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"  [[package]] name = "adom-shotlog"-version = "0.23.5"+version = "0.23.6" dependencies = [  "axum",  "base64",
Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "adom-shotlog"-version = "0.23.5"+version = "0.23.6" edition = "2021" description = "Screenshot log viewer and CLI for Adom" license = "MIT"
VERSION+1−1
@@ -1 +1 @@-0.23.5+0.23.6
bin/adom-shotlog
⋯ 1 unchanged line ⋯
dev-skills/adom-shotlog-dev/SKILL.md+10
@@ -263,3 +263,13 @@ row 2 = all actions right-aligned. Reason: zone-shedding on one row crushed the channel name to 2-3 chars once the action cluster grew (canvas + top + filter + prefs + clear + LED). John: "in skinny view you probably need to go to two lines in header". Never more than two rows, and never shed the channel name.++## Ghost-surface detection (2026-07-18)+"Is shotlog showing anywhere?" has THREE sources of truth and they can ALL+disagree: (1) broker viewer-status = only LIVE WebSocket pages; (2) pup bridge+tab registry = can lose windows that still exist; (3) the OS window list+(desktop_list_windows, match title 'adom-shotlog') = ground truth for pup.+A ghost = OS window exists but registry has 0 tabs and broker has 0 pup+viewers - a stale page silently showing old shots. Detect by cross-checking+all three; kill ghosts with desktop_find_control {hwnd, name:"Close"} ->+desktop_ui_click (background UIA, no focus steal). Never process_kill chrome.
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-shotlog",-  "version": "0.23.5",+  "version": "0.23.6",   "type": "app",   "title": "Adom Shotlog",   "description": "See the shots your AI never showed you, and know it actually SAW them. adom-shotlog streams every screenshot the AI gathers into a live gallery (webview/pup/browser/phone), reports whether a human is really watching and on which surface, and ingests Adom Desktop child-window arrays via --meta.",
page.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-shotlog",-  "version": "0.23.5",+  "version": "0.23.6",   "type": "app",   "title": "Adom Shotlog",   "description": "See the shots your AI never showed you, and know it actually SAW them. adom-shotlog streams every screenshot the AI gathers into a live gallery (webview/pup/browser/phone), reports whether a human is really watching and on which surface, and ingests Adom Desktop child-window arrays via --meta.",
src/html/index.html+3−4
@@ -176,7 +176,6 @@ header { /* WHY-headline for auto-captures: the prompt IS the title (same gutter as a    description), the filename demoted to a small mono sub-line under it. */ .shot-card-why { padding: 10px 13px 0; font: 500 13.5px/1.45 'Satoshi', sans-serif; color: var(--text); overflow-wrap: anywhere; }-.shot-card-why .q { color: var(--accent); font-weight: 700; } .shot-card-sub { padding: 2px 13px 0; font-family: 'JetBrains Mono', monospace; font-size: 10px;   color: var(--text3); overflow-wrap: anywhere; } .shot-card-desc { padding: 10px 13px 5px; font-family: 'Satoshi', sans-serif; font-size: 13px;@@ -741,7 +740,7 @@ header {     const isAuto=(e.source||'').startsWith('read-hook');     if (isAuto && e.context) {       const why=document.createElement('div'); why.className='shot-card-why';-      why.innerHTML='<span class="q">"</span>'+esc(e.context)+'<span class="q">"</span>';+      why.textContent=e.context;       why.setAttribute('data-tooltip','The prompt this AI thread was working on when it read the image - the REASON this capture exists.');       c.appendChild(why);       const sub=document.createElement('div'); sub.className='shot-card-sub';@@ -813,11 +812,11 @@ header {   function openModal(e) {     mImg.src=imgUrl(e); mImg.alt=e.description||e.filename;     const isAutoM=(e.source||'').startsWith('read-hook');-    mDesc.textContent=(isAutoM&&e.context)?('"'+e.context+'"'):(e.description||'');+    mDesc.textContent=(isAutoM&&e.context)?e.context:(e.description||'');     mDesc.style.display=(mDesc.textContent)?'':'none';     let why=document.getElementById('mWhy');     if(!why){ why=document.createElement('div'); why.id='mWhy'; why.className='m-why'; mDesc.after(why); }-    if(e.context){ why.innerHTML='<span class="k">while working on</span>'+esc('"'+e.context+'"'); why.style.display=''; }+    if(e.context){ why.innerHTML='<span class="k">while working on</span>'+esc(e.context); why.style.display=''; }     else { why.style.display='none'; }     mMeta.innerHTML='';     const add=(cls,txt,tip)=>{ const s=document.createElement('span'); if(cls)s.className=cls; s.textContent=txt; if(tip)s.setAttribute('data-tooltip',tip); mMeta.appendChild(s); };