app
Shotlog - Screenshot Log
Public Made by Adomby adom
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 Bridge child-window arrays via --meta.
← Commit history
Publish 0.22.1
7 files changed
+44−7
Cargo.lock+1−1@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "adom-shotlog"-version = "0.22.0"+version = "0.22.1" dependencies = [ "axum", "base64",
Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "adom-shotlog"-version = "0.22.0"+version = "0.22.1" edition = "2021" description = "Screenshot log viewer and CLI for Adom" license = "MIT"
VERSION+1−1@@ -1 +1 @@-0.22.0+0.22.1
bin/adom-shotlog⋯ 1 unchanged line ⋯
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-shotlog",- "version": "0.22.0",+ "version": "0.22.1", "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.22.0",+ "version": "0.22.1", "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/open.rs+39−2@@ -223,8 +223,10 @@ pub fn open_pup(channel: &str, port: u16, swap: bool) { }; let (listed, list_out) = ad(&["browser_list_tabs", "{\"sessionId\":\"shotlog\"}"]); let mut opened = false;+ let mut via_window = false; if !listed || list_out.contains("session_not_found") { opened = open_window(&ad);+ via_window = true; } else { let existing = serde_json::from_str::<serde_json::Value>(&list_out).ok() .and_then(|v| v.get("tabs").and_then(|t| t.as_array()).and_then(|tabs| {@@ -233,10 +235,32 @@ pub fn open_pup(channel: &str, port: u16, swap: bool) { })); if let Some(tid) = existing { let sw = format!("{{\"sessionId\":\"shotlog\",\"tabId\":\"{tid}\"}}");- opened = ad(&["browser_switch_tab", &sw]).0 || open_window(&ad);+ opened = ad(&["browser_switch_tab", &sw]).0; } else { let tab_json = format!("{{\"sessionId\":\"shotlog\",\"url\":\"{url}\"}}");- opened = ad(&["browser_open_tab", &tab_json]).0 || open_window(&ad);+ opened = ad(&["browser_open_tab", &tab_json]).0;+ }+ if !opened {+ opened = open_window(&ad);+ via_window = true;+ }+ }+ // TRUST BUT VERIFY: the bridge's registry can outlive the real Chrome+ // window and fake tab-verb success (switch_tab "ok" into the void). A pup+ // viewer's WebSocket CONNECTING to the broker is the only real proof -+ // poll briefly; if nobody connects, force a fresh window.+ if opened && !via_window {+ let mut connected = false;+ for _ in 0..4 {+ std::thread::sleep(std::time::Duration::from_secs(2));+ if broker_has_pup_viewer(port) {+ connected = true;+ break;+ }+ }+ if !connected {+ eprintln!("Hint: pup tab verbs succeeded but no viewer connected (ghost session) - opening a fresh window.");+ opened = open_window(&ad); } } @@ -266,6 +290,19 @@ pub fn open_pup(channel: &str, port: u16, swap: bool) { } } +/// Does the broker currently see ANY pup viewer connected (the real proof a+/// pup page is alive)? Minimal HTTP GET, no external deps.+fn broker_has_pup_viewer(port: u16) -> bool {+ use std::io::{Read, Write};+ let Ok(mut st) = std::net::TcpStream::connect(("127.0.0.1", port)) else { return false };+ let _ = st.set_read_timeout(Some(std::time::Duration::from_secs(3)));+ let req = format!("GET /api/viewer-status?channel=_all HTTP/1.1\r\nHost: 127.0.0.1:{port}\r\nConnection: close\r\n\r\n");+ if st.write_all(req.as_bytes()).is_err() { return false; }+ let mut buf = String::new();+ let _ = st.read_to_string(&mut buf);+ buf.contains("\"pup\"")+}+ /// Close this channel's tab in the shared shotlog pup window (if present). /// Used when swapping a channel back to the webview canvas. pub fn close_pup_tab(channel: &str) -> bool {