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.26.1
11 files changed
+42−16
Cargo.lock+1−1@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "adom-shotlog"-version = "0.26.0"+version = "0.26.1" dependencies = [ "axum", "base64",
Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "adom-shotlog"-version = "0.26.0"+version = "0.26.1" edition = "2021" description = "Screenshot log viewer and CLI for Adom" license = "MIT"
README.md+1−1@@ -100,7 +100,7 @@ The viewer has a **Settings** dialog (the gear in the header). Every setting is | Setting | Default | What it does | |---|---|---| | **Auto-capture what AIs read** (read-hook) | ON | Auto-inject every image any AI thread reads into the shared `read-captures` channel. Off = only deliberate injects show. |-| **Update alerts** (orange flashes) | ON | The orange cues when new shots arrive: the webview tab highlight and the pup taskbar flash. Off = still brings the tab forward, just no flashing. |+| **Update alerts** (orange flashes) | OFF | The orange cues when new shots arrive: the webview tab highlight, the in-app channel-tab flash, and the pup taskbar flash. Tabs still come forward and unseen badges still show; turn on if you want the flashing. | | **Auto-switch to updated channel** | ON | When a shot arrives for another channel, jump that channel's tab to the front. Off = the tab just flashes + shows an unseen badge; you stay put. | | **Compact cards (image-first)** | ON | The gallery shows mostly thumbnails: info text hides behind the ⓘ chip on each image (hover to reveal); the ⛶ fullscreen button stays on every thumbnail. Off = classic text-above-image cards. | | **Default canvas** | webview | Where shotlog auto-opens a channel when nobody's watching: `webview` or `pup`. |
VERSION+1−1@@ -1 +1 @@-0.26.0+0.26.1
bin/adom-shotlog⋯ 1 unchanged line ⋯
dev-skills/adom-shotlog-dev/SKILL.md+11@@ -405,3 +405,14 @@ it is John's most-used control. <body> ships class="compact" so the default renders without a flash; boot + renderPrefs sync it from the pref. Classic mode (toggle off) is byte-identical to the old layout - .card-info is display -block static, .card-info-hot display:none.++## Orange flashes default OFF + live prefs sync (0.26.1, John)+update_alerts now defaults FALSE (serde default_false + Default impl): no+orange flashing on new shots unless the user opts in. The pref now gates ALL+three flash surfaces: the workspace webview-tab alert, the pup taskbar flash+(both already gated), AND the in-app channel-tab flashTab (was ungated).+Badges/pull-forward behavior unchanged. ALSO: prefs changes now broadcast over+ctrl_tx as {type:"prefs",prefs} and every open page applies them live (APREFS+was cached from boot before - an API prefs change didn't reach open pages+until reload; that staleness invalidated a live test once). renderPrefs uses+===true for default-false toggles (!==false is wrong once a default flips).
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-shotlog",- "version": "0.26.0",+ "version": "0.26.1", "type": "app", "title": "Shotlog - Screenshot Log", "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 Bridge child-window arrays via --meta.",
page.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-shotlog",- "version": "0.26.0",+ "version": "0.26.1", "type": "app", "title": "Shotlog - Screenshot Log", "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 Bridge child-window arrays via --meta.",
src/html/index.html+15−6@@ -587,10 +587,10 @@ body.compact .card-popups .ph { padding-top: 4px; } <div class="pref-row"> <div class="pref-info"> <div class="pref-name">Update alerts (orange flashes)</div>- <div class="pref-desc">When new shots arrive: the webview tab highlights orange and the pup window flashes its taskbar. Turn off for calmer eyeballs - shotlog still brings the tab forward, just without the flashing.</div>- <div class="ai-chip"><span class="lbl">or say to your AI</span>turn off the shotlog orange flashes</div>+ <div class="pref-desc">OFF by default. When new shots arrive: the webview tab highlights orange, the in-app channel tab flashes, and the pup window flashes its taskbar. Tabs still come forward and unseen badges still show either way - this only controls the orange flashing.</div>+ <div class="ai-chip"><span class="lbl">or say to your AI</span>turn on the shotlog orange flashes</div> </div>- <button class="toggle" id="prefAlerts" role="switch" aria-checked="true" data-tooltip="Toggle the orange update cues (webview tab highlight + pup taskbar flash) when new shots arrive."></button>+ <button class="toggle" id="prefAlerts" role="switch" aria-checked="false" data-tooltip="Off (default): no orange flashing when shots arrive. On: webview tab + in-app tab + pup taskbar flash orange."></button> </div> <div class="pref-row"> <div class="pref-info">@@ -1491,7 +1491,7 @@ body.compact .card-popups .ph { padding-top: 4px; } let lastKeep=200, lastPrune=30; function renderPrefs(p){ hook.setAttribute('aria-checked', String(!!p.read_hook));- $('prefAlerts').setAttribute('aria-checked', String(p.update_alerts!==false));+ $('prefAlerts').setAttribute('aria-checked', String(p.update_alerts===true)); $('prefAutoswitch').setAttribute('aria-checked', String(p.update_autoswitch!==false)); $('prefAutosize').setAttribute('aria-checked', String(p.webview_autosize===true)); $('prefCompact').setAttribute('aria-checked', String(p.compact!==false));@@ -1631,6 +1631,13 @@ body.compact .card-popups .ph { padding-top: 4px; } ws.onmessage = ev => { try { const msg = JSON.parse(ev.data);+ if (msg.type==='prefs' && msg.prefs) {+ // Live settings sync from the broker: another surface (or an AI via+ // the API) changed a setting - apply it here without a reload.+ APREFS=msg.prefs;+ document.body.classList.toggle('compact', APREFS.compact!==false);+ return;+ } if (msg.type==='show' && msg.channel) { // Consolidation: an AI asked to "open" a channel while this window is // already up - switch OUR tab instead of letting a second surface@@ -1660,9 +1667,11 @@ body.compact .card-popups .ph { padding-top: 4px; } renderTabs(); } else if (APREFS.update_autoswitch !== false) { // The in-app mirror of pull-to-front: jump to the updated channel.- activate(chName).then(()=>flashTab(chName));+ // The orange flash rides the update_alerts pref (off by default);+ // the switch/badge behavior is unaffected.+ activate(chName).then(()=>{ if(APREFS.update_alerts===true) flashTab(chName); }); } else {- c.unseen++; renderTabs(); flashTab(chName);+ c.unseen++; renderTabs(); if(APREFS.update_alerts===true) flashTab(chName); } } } catch {}
src/server.rs+4@@ -583,6 +583,10 @@ async fn set_prefs( p.retention_days = d; } state.store.set_app_prefs(p.clone()).await;+ // Live-sync every open page: settings changed on ONE surface (or via the+ // API) apply everywhere immediately - no reload, no stale APREFS.+ let frame = serde_json::json!({"type": "prefs", "prefs": p});+ let _ = state.store.ctrl_tx.send(frame.to_string()); Json(serde_json::json!({"ok": true, "prefs": p})) }
src/store.rs+6−4@@ -113,9 +113,11 @@ pub struct AppPrefs { /// Env SHOTLOG_RETENTION_DAYS overrides when set. #[serde(default = "default_retention_days")] pub retention_days: u64,- /// Orange update cues when NEW SHOTS arrive: the webview tab highlight and- /// the pup taskbar flash. Off = still pulls the tab forward, just no flash.- #[serde(default = "default_true")]+ /// Orange update cues when NEW SHOTS arrive: the workspace webview-tab+ /// highlight, the pup taskbar flash, and the in-app channel-tab flash.+ /// OFF by default (John found the flashing annoying) - tabs still come+ /// forward and unseen badges still show; turn on for the orange cues.+ #[serde(default = "default_false")] pub update_alerts: bool, /// Width of the skinny webview panel as a percent of the workspace (10-50). #[serde(default = "default_webview_width")]@@ -146,7 +148,7 @@ fn default_webview_width() -> u8 { 20 } impl Default for AppPrefs { fn default() -> Self { Self { default_canvas: default_canvas(), read_hook: true, max_shots: default_max_shots(), retention_days: default_retention_days(),- update_alerts: true, webview_width: default_webview_width(),+ update_alerts: false, webview_width: default_webview_width(), update_autoswitch: true, webview_autosize: false, compact: true } } }