← Commit history
Cargo.lock+1−1
@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"  [[package]] name = "adom-shotlog"-version = "0.18.0"+version = "0.18.1" dependencies = [  "axum",  "base64",
Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "adom-shotlog"-version = "0.18.0"+version = "0.18.1" edition = "2021" description = "Screenshot log viewer and CLI for Adom" license = "MIT"
VERSION+1−1
@@ -1 +1 @@-0.18.0+0.18.1
bin/adom-shotlog
⋯ 1 unchanged line ⋯
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-shotlog",-  "version": "0.18.0",+  "version": "0.18.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.18.0",+  "version": "0.18.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/main.rs+21−6
@@ -189,6 +189,10 @@ enum Commands {         /// comes from the broker's webview_width preference (20% unless changed).         #[arg(long)]         ratio: Option<f64>,+        /// Explicitly open the WEBVIEW canvas (same as --skinny). Without any+        /// canvas flag, `open` follows the human's default_canvas preference.+        #[arg(long)]+        webview: bool,         /// Open in the FULL-BROWSER pup canvas instead: one shared pup window         /// ('shotlog') with a tab per channel. Real zoom at near-full screen,         /// and the broker flashes the window's taskbar orange on every update.@@ -411,24 +415,35 @@ async fn main() {             run_inject(&channel, &desc, &source, port, &file, false, orig_w, orig_h, cap_meta, popups);         }         Commands::Open {-            channel, name, icon, port, skinny, ratio, pup, swap,+            channel, name, icon, port, skinny, ratio, pup, swap, webview,         } => {             // NOTE: a CLI open does NOT record a canvas choice. Only the human's             // explicit clicks in the viewer (canvas buttons) set the in-memory             // note; everything else follows the global default. AI threads             // opening channels must never masquerade as user preference.-            if pup {+            let prefs = http_get(port, "/api/prefs").ok();+            let default_canvas = prefs.as_ref()+                .and_then(|v| v.get("default_canvas").and_then(|c| c.as_str()).map(String::from))+                .unwrap_or_else(|| "webview".into());+            // Canvas resolution: explicit flag wins; otherwise the HUMAN'S+            // default. A plain `open` must never bypass their setting.+            let use_pup = pup || (!skinny && !webview && default_canvas == "pup");+            let _ = http_post(port, "/api/log", &serde_json::json!({"line": format!(+                "CLI open '{}' canvas={} ({})", channel,+                if use_pup {"pup"} else {"webview"},+                if pup {"--pup"} else if skinny || webview {"explicit webview"} else {"followed default"})}));+            if use_pup {                 open::open_pup(&channel, port, swap);             } else {-                // Resolve the panel width: explicit --ratio wins, else the-                // broker's webview_width pref, else 20%.+                // Webview is ALWAYS the managed slim panel at the preferred+                // width - an unmanaged add-tab once landed at 50% of the screen.                 let ratio = ratio.unwrap_or_else(|| {-                    http_get(port, "/api/prefs").ok()+                    prefs.as_ref()                         .and_then(|v| v.get("webview_width").and_then(|w| w.as_u64()))                         .map(|w| (w as f64 / 100.0).clamp(0.10, 0.50))                         .unwrap_or(0.2)                 });-                open::open_webview(&channel, name.as_deref(), icon.as_deref(), port, skinny, ratio);+                open::open_webview(&channel, name.as_deref(), icon.as_deref(), port, true, ratio);                 if swap {                     if open::close_pup_tab(&channel) {                         ok(&format!("closed the pup tab for '{channel}' - webview is now this channel's canvas."));
src/server.rs+16−1
@@ -82,6 +82,7 @@ pub fn create_router(state: Arc<AppState>) -> Router {         .route("/api/canvas-pref", post(set_canvas_pref))         .route("/api/prefs", get(get_prefs))         .route("/api/prefs", post(set_prefs))+        .route("/api/log", post(post_log))         .route("/prompt", get(serve_prompt))         .route("/api/paste", post(post_paste))         .route("/api/open", post(open_in_vscode))@@ -255,6 +256,20 @@ struct CanvasSwitchRequest {     to: String, } +#[derive(Deserialize)]+struct LogRequest {+    line: String,+}++/// Append a one-line event to the broker's audit trail (stdout). Used by the+/// CLI so "who opened what, how" is greppable in ONE place.+async fn post_log(Json(req): Json<LogRequest>) -> Json<serde_json::Value> {+    let mut line = req.line.replace(['\n', '\r'], " ");+    line.truncate(300);+    println!("{} {}", ts(), line);+    Json(serde_json::json!({"ok": true}))+}+ #[derive(Deserialize)] struct CanvasPrefRequest {     channel: String,@@ -878,7 +893,7 @@ async fn post_shots(     let mut hints: Vec<String> = Vec::new();     if entry.id == 1 && hint_gate(&format!("teach:new-channel:{}", req.channel), 1) {         hints.push(format!(-            "mini-skill [surfacing]: first shot in '{ch}'. The human watches via a slim right-side webview (`shotlog open -c {ch} --skinny`), a pup window, or their phone. I auto-open a 20% webview when nobody is watching, pull the channel's tab to the front with an orange alert on updates, and flash pup taskbars — never foreground anything yourself. Gate on visibility with `shotlog viewers -c {ch}` (exit 0=on-screen, 4=backgrounded, 3=nobody); see every channel with `shotlog channels`.",+            "mini-skill [surfacing]: first shot in '{ch}'. To open a viewer use PLAIN `shotlog open -c {ch}` - it follows the human's default canvas (webview or pup); only pass --skinny/--pup when the human explicitly asked for that canvas. I auto-open a 20% webview when nobody is watching, pull the channel's tab to the front with an orange alert on updates, and flash pup taskbars — never foreground anything yourself. Gate on visibility with `shotlog viewers -c {ch}` (exit 0=on-screen, 4=backgrounded, 3=nobody); see every channel with `shotlog channels`.",             ch = req.channel));     }     if source_str.contains("desktop_screenshot") && !had_meta && hint_gate(&format!("teach:meta:{}", req.channel), 2) {