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.25.1
10 files changed
+51−34
Cargo.lock+1−1@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "adom-shotlog"-version = "0.25.0"+version = "0.25.1" dependencies = [ "axum", "base64",
Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "adom-shotlog"-version = "0.25.0"+version = "0.25.1" edition = "2021" description = "Screenshot log viewer and CLI for Adom" license = "MIT"
README.md+22−5@@ -7,7 +7,7 @@ Your AI screenshots your app constantly while it builds and tests, but it is tex ## Install ```-adompkg install adom/adom-shotlog+adom-wiki pkg install adom/adom-shotlog ``` The CLI installs as `adom-shotlog` (with a back-compat `shotlog` alias).@@ -32,6 +32,8 @@ Related guarantees: the broker is **single-instance per port** (a second `serve` shotlog notices which surface is watching a channel and behaves accordingly. It never steals your OS foreground. +**Which surface should you use?** For most day-to-day work, the **skinny 20%-wide webview** is the sweet spot, and it's the most-used surface: it stays docked on the right of your Hydrogen workspace, always visible while you keep working, auto-updating as shots land, without covering anything. Reach for **pup** only when you need to inspect a shot **full-size** (pup is a real full-browser window, so zooming a card uses nearly the whole screen; the skinny webview can't zoom past its own panel width). A common rhythm: live in the 20% webview, and pop a specific shot to pup (or fullscreen) when you want to read fine detail. Set your default in Settings (below); it stays per environment, so you can run webview in the cloud and pup on your desktop if you like.+ ### Webview (the default in Hydrogen): a slim 20% right-side panel The nicest setup, and the default when you run inside Hydrogen: a **~20%-wide webview panel pinned to the right** of your workspace. Open it that way:@@ -55,7 +57,7 @@ The layout adapts to the narrow screen, and while the tab is backgrounded the pa ### Pup and plain browser -Pup is the **full-browser canvas**: zooming a card uses nearly the whole screen, so fine text is readable (the skinny webview can never zoom past its panel width). Or just click the **`Pup` button in the viewer header**: every webview shows it, and it switches that channel to a full pup window (the pup view shows a `Webview` button to switch back). The button checks whether pup is available first; if Adom Desktop isn't installed it tells you how to get it (pup is a default bridge that auto-installs with Adom Desktop). Your AI can do the same switch with one command: `shotlog open -c <ch> --pup --swap` (opens a tab in the shared shotlog pup window and closes the webview tab). shotlog leaves your foreground alone; the gentle cue is an automatic **orange taskbar flash** on updates. In any plain browser tab, the same live gallery and unseen-shots title badge apply.+Pup is the **full-browser canvas**: zooming a card uses nearly the whole screen, so fine text is readable (the skinny webview can never zoom past its panel width). Or just click the **`Pup` button in the viewer header**: every webview shows it, and it switches that channel to a full pup window (the pup view shows a `Webview` button to switch back). The button checks whether pup is available first; if Adom Bridge isn't installed it tells you how to get it (pup is a default bridge that auto-installs with Adom Bridge). Your AI can do the same switch with one command: `shotlog open -c <ch> --pup --swap` (opens a tab in the shared shotlog pup window and closes the webview tab). shotlog leaves your foreground alone; the gentle cue is an automatic **orange taskbar flash** on updates. In any plain browser tab, the same live gallery and unseen-shots title badge apply. ## Is a human actually seeing it? @@ -75,7 +77,7 @@ adom-shotlog **always** records the original capture resolution, so the gallery A window capture is often not one image. A window with a dropdown, an autofill list, a confirm bubble, or a native dialog open is really a **parent window with child windows**: separate owned windows that a plain screenshot of the main window misses entirely. -Adom Desktop captures them for you. **`desktop_screenshot_window {hwnd}` returns the parent image PLUS every child window** in a `screenshots[]` array (with `ownedPopupCount`), each carrying its own hwnd, title, kind, rect, and coordMap. Pass that whole response to shotlog with `--meta`:+Adom Bridge captures them for you. **`desktop_screenshot_window {hwnd}` returns the parent image PLUS every child window** in a `screenshots[]` array (with `ownedPopupCount`), each carrying its own hwnd, title, kind, rect, and coordMap. Pass that whole response to shotlog with `--meta`: ``` adom-shotlog inject -c checkout -d "checkout form, autofill dropdown + confirm dialog open" primary.png --meta ad-response.json@@ -91,6 +93,21 @@ shotlog renders the entire array on one card, no zoom needed: So one `desktop_screenshot_window` call, one `--meta` inject, and you see the whole window story: the form, the dropdown it opened, and the dialog it raised, all in a single card. Child-window PNGs are stored beside the parent and are excluded from the gallery as standalone shots. Plain single-image injects (no `--meta`) are unchanged; child windows are purely additive. +## Settings++The viewer has a **Settings** dialog (the gear in the header). Every setting is also **AI-drivable**, ask your AI (e.g. "make shotlog default to pup") or `POST` it to `localhost:8820/api/prefs`. Settings are stored per environment in `<data-dir>/.prefs.json`, so your cloud (hw) and desktop (ah) shotlogs keep independent settings.++| 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. |+| **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. |+| **Default canvas** | webview | Where shotlog auto-opens a channel when nobody's watching: `webview` or `pup`. |+| **Auto-size the webview panel** | OFF | ON re-forces the panel to your width on every open; OFF (default) leaves the column at whatever width you dragged it to (the width below only seeds a brand-new panel). |+| **Webview panel width** | 20% | The width (10-50%) used when shotlog first creates the slim webview panel. |+| **Keep per channel** | 200 shots | The janitor keeps only the newest N shots per channel on disk; older files are deleted as new ones arrive. Env `SHOTLOG_MAX_SHOTS` overrides. |+| **Prune idle channels after** | 30 days | Channels with no new shots for this many days are deleted entirely (checked at startup + every 6h). `0` = never. Env `SHOTLOG_RETENTION_DAYS` overrides. |+ ## CLI reference | Command | Description |@@ -117,6 +134,6 @@ Installing adom-shotlog also deploys its bundled skills (see the Skills tab): | Dependency | Required? | Why | |---|---|---| | **adom-cli** | For the webview | `adom-shotlog open` adds the gallery as a Hydrogen webview tab and the broker manages it. |-| **adom-desktop** | Optional | AI agents use it to capture screenshots (and child-window arrays) that get injected. Humans can Ctrl+V paste instead. |+| **Adom Bridge** (`adom-bridge-cli`) | Optional | AI agents use it to capture screenshots (and child-window arrays) that get injected. Humans can Ctrl+V paste instead. | -No `adompkg` package dependencies. adom-shotlog is a self-contained Rust binary.+No wiki package dependencies. adom-shotlog is a self-contained Rust binary.
SKILL.md+9−9@@ -1,6 +1,6 @@ --- name: adom-shotlog-description: "Screenshot log viewer and injector. Use when: logging screenshots during debug loops, documenting visual progress, reviewing screenshot history, opening the screenshot log panel, injecting a screenshot into the log, ingesting an Adom Desktop screenshot response with child windows (owned popups). Trigger words: adom-shotlog, shotlog, screenshot log, shot log, visual log, screenshot history, log screenshot, open shotlog, screenshot viewer."+description: "Screenshot log viewer and injector. Use when: logging screenshots during debug loops, documenting visual progress, reviewing screenshot history, opening the screenshot log panel, injecting a screenshot into the log, ingesting an Adom Bridge screenshot response with child windows (owned popups). Trigger words: adom-shotlog, shotlog, screenshot log, shot log, visual log, screenshot history, log screenshot, open shotlog, screenshot viewer." --- # adom-shotlog - Screenshot Log@@ -21,7 +21,7 @@ This is the **main** (user) skill. Deeper topics ship in the same | Skill | Tier | What it's for | |-------|------|---------------|-| [adom-shotlog-surfacing](skills/adom-shotlog-surfacing/SKILL.md) | user | surfacing a shot *gently* per surface (webview activate / pup taskbar flash / phone badge), never stealing foreground; plus AD window-discovery + cue verbs |+| [adom-shotlog-surfacing](skills/adom-shotlog-surfacing/SKILL.md) | user | surfacing a shot *gently* per surface (webview activate / pup taskbar flash / phone badge), never stealing foreground; plus Adom Bridge window-discovery + cue verbs | | [adom-shotlog-child-windows](skills/adom-shotlog-child-windows/SKILL.md) | user | capturing a parent window **plus its child windows** (owned dropdowns/dialogs) via `--meta`, and how they render inline | | [adom-shotlog-dev](dev-skills/adom-shotlog-dev/SKILL.md) | dev | build/deploy, the central-broker architecture, and the layout rules (ralph-test the skinny view, no outer-html scrollbars, pretty scrollbars) | | [adom-shotlog-publishing](publish-skills/adom-shotlog-publishing/SKILL.md) | publish | publishing to wiki.adom.inc (org ownership, OSS source, hero, the wiki traps) |@@ -57,7 +57,7 @@ tells you two things: taskbar, force-opening a slim 20% webview). When you see one, surfacing is handled - do NOT open, refresh, or foreground anything yourself. - **`Hint: mini-skill [...]` lines = progressive teaching**, revealed at the- moment they're relevant (first shot in a channel, an AD capture missing+ moment they're relevant (first shot in a channel, an Adom Bridge capture missing `--meta`, a pup viewer without a `?session=` handle) and then they go quiet. Read and apply them; they are the condensed version of this skill pack. @@ -108,7 +108,7 @@ explaining the consolidation) and opens nothing new. Only when NOTHING is open does it create a surface, on the human's default canvas. NEVER load the viewer URL into your own pup session or a new window/tab-(`browser_open_window`/`browser_open_tab` with a /log/ URL) - that gives the+(`pup_open_window`/`pup_open_tab` with a /log/ URL) - that gives the human a confusing second shotlog. Always go through `adom-shotlog open`. ## Inject - one command@@ -139,7 +139,7 @@ the shot. Ways through: resized). Use only when true. 4. **Hand it the full-res image** - adom-shotlog resizes anything over 1500px (either edge) down to 1400px and records the original automatically.-5. **`--meta <ad-response.json>`** - ingest an Adom Desktop screenshot response+5. **`--meta <ad-response.json>`** - ingest an Adom Bridge screenshot response (see below). The original W×H comes from the response's `origWidth/origHeight`, so this satisfies the original-resolution rule on its own. @@ -162,9 +162,9 @@ curl -s -X POST localhost:8820/api/paste -H 'Content-Type: application/json' -d "thread":"my thread title", "context":"the prompt being served"}' ``` -## `--meta` - Adom Desktop child-window arrays+## `--meta` - Adom Bridge child-window arrays -As of adom-desktop 1.8.177, `desktop_screenshot_window {hwnd}` returns the primary+As of Adom Bridge 1.8.177, `desktop_screenshot_window {hwnd}` returns the primary window image **plus its child windows** - the owned dropdowns, confirm bubbles, and native dialogs - each captured separately, plus coordMap / DPI / screen metadata. Pass that whole response JSON via `--meta`:@@ -208,7 +208,7 @@ metadata are additive. | `--orig-w` / `--orig-h` | for pre-shrunk images | Original dims (alternative to `--orig-file`) | | `--native` | for unresized small images | Assert FILE is at original resolution | | `--thread` | no | Which AI thread produced this shot (human-readable). The read-hook fills it automatically from the session transcript; pass your thread's name when injecting deliberately so the human sees WHO. |-| `--meta` | optional | Adom Desktop screenshot-response JSON: child windows + coordMap + orig dims |+| `--meta` | optional | Adom Bridge screenshot-response JSON: child windows + coordMap + orig dims | | `FILE` | yes | Primary image path (use `-` for stdin) | ## CRITICAL: Always write great descriptions@@ -222,7 +222,7 @@ every gallery card. Make it specific. ## Fill window (zoom a shot to a lightbox) Click a shot to open the zoom modal, then click the image (or the ⛶ button) to-FILL THE WINDOW. This uses the standard Fullscreen API: in Hydrogen Desktop's+FILL THE WINDOW. This uses the standard Fullscreen API: in Adom Hydrogen's native webview it grows the panel to a 90%-of-window lightbox that escapes the skinny panel; in a pup/browser it goes true fullscreen; on a phone it fills the screen. Esc / ✕ / click-the-backdrop exits. One code path, right on every surface.
VERSION+1−1@@ -1 +1 @@-0.25.0+0.25.1
bin/adom-shotlog⋯ 1 unchanged line ⋯
package.json+3−3@@ -1,9 +1,9 @@ { "slug": "adom-shotlog",- "version": "0.25.0",+ "version": "0.25.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.",+ "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.", "license": "MIT", "dependencies": {}, "scripts": {
page.json+2−2@@ -1,9 +1,9 @@ { "slug": "adom-shotlog",- "version": "0.25.0",+ "version": "0.25.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 Desktop child-window arrays via --meta.",+ "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.", "license": "MIT", "dependencies": {}, "scripts": {
skills/adom-shotlog-child-windows/SKILL.md+4−4@@ -1,6 +1,6 @@ --- name: adom-shotlog-child-windows-description: "Capture and display a parent window PLUS its CHILD WINDOWS in shotlog - the owned dropdowns, confirm bubbles, and native dialogs that Adom Desktop returns alongside a window shot, ingested via `inject --meta`. Use when: injecting a desktop_screenshot_window response, a captured window had a dropdown/dialog open, showing multi-window captures, or asking how child windows render. Trigger words: child windows, parent window, owned windows, owned popups, ownedPopupCount, window array, desktop_screenshot_window array, --meta, coordMap, dropdown capture, dialog capture, multi-window screenshot."+description: "Capture and display a parent window PLUS its CHILD WINDOWS in shotlog - the owned dropdowns, confirm bubbles, and native dialogs that Adom Bridge returns alongside a window shot, ingested via `inject --meta`. Use when: injecting a desktop_screenshot_window response, a captured window had a dropdown/dialog open, showing multi-window captures, or asking how child windows render. Trigger words: child windows, parent window, owned windows, owned popups, ownedPopupCount, window array, desktop_screenshot_window array, --meta, coordMap, dropdown capture, dialog capture, multi-window screenshot." --- # adom-shotlog - parent window + its CHILD WINDOWS (`--meta`)@@ -10,13 +10,13 @@ autofill list, a confirm bubble, or a native dialog open is really a **parent window with child windows** - separate top-level windows owned by the parent that a plain `PrintWindow` of the parent misses entirely. -Adom Desktop surfaces them for you: **`desktop_screenshot_window {hwnd}` returns+Adom Bridge surfaces them for you: **`desktop_screenshot_window {hwnd}` returns the parent image PLUS its child windows** as a `screenshots[]` array, with `ownedPopupCount` always present (0 = none). Each child window rides back with its own `hwnd`, `title`, `kind` (`dropdown`/`dialog`/…), `rect`, and `coordMap`. This-is AD's generic "find a window's child windows" - no app-specific verb.+is Adom Bridge's generic "find a window's child windows" - no app-specific verb. -> Terminology: AD's wire fields are named `ownedPopupCount` / `screenshots[]`+> Terminology: Adom Bridge's wire fields are named `ownedPopupCount` / `screenshots[]` > (Win32 "owned windows"), but conceptually - and in the shotlog UI - these are > the parent window's **child windows**. Don't call them "popups" to the human.
skills/adom-shotlog-surfacing/SKILL.md+8−8@@ -44,11 +44,11 @@ Open the pup canvas with `shotlog open -c <ch> --pup`: one shared pup window (session `shotlog`), a tab per channel, idempotent. The URL carries `?surface=pup&session=shotlog`, the viewer reports that session over its WebSocket, and on every new shot the broker AUTOMATICALLY runs-`adom-desktop browser_alert_window {sessionId}` - the orange taskbar flash -+`adom-bridge-cli pup_alert_window {sessionId}` - the orange taskbar flash - debounced per session. Set `SHOTLOG_AD_TARGET=<desktop>` on the server when more-than one Adom Desktop is connected. No AI action needed. If a pup viewer has no+than one Adom Bridge is connected. No AI action needed. If a pup viewer has no `session=` handle the broker can't flash it; `inject` hints you to do it-yourself (`adom-desktop browser_alert_window`) - never raise/foreground the+yourself (`adom-bridge-cli pup_alert_window`) - never raise/foreground the window. The viewer's page title also shows a `● N` unseen-shot count. ### Phone / plain browser - in-page title badge@@ -96,7 +96,7 @@ broker's inject hints call it out ("did you mean to?"): resolve with `--swap`. how many are **on-screen** (visible) vs backgrounded. 2. If a viewer is **on-screen** → done; it's genuinely visible. Don't nudge. 3. If viewers exist but are **backgrounded** → nudge gently for that surface- (webview: server already blinked; pup: `browser_alert_window`); **never+ (webview: server already blinked; pup: `pup_alert_window`); **never foreground**. 4. If **nobody** is watching → open the preferred surface: `shotlog open -c <ch> --skinny`, or ask the human to load the URL / open it on@@ -104,7 +104,7 @@ broker's inject hints call it out ("did you mean to?"): resolve with `--swap`. 5. Gate precisely with `shotlog viewers -c <ch>` - exit `0` = on-screen, `4` = open but backgrounded, `3` = nobody. -## The exact gentle-cue verbs (Adom Desktop)+## The exact gentle-cue verbs (Adom Bridge) Use these to signal an update **without foregrounding**. Never use `desktop_bring_to_front` / raise / SendInput-click to force a window forward@@ -114,13 +114,13 @@ just to show a shot. |---------|-----------|------| | Webview tab | Blink the tab (auto-scrolls into view, no focus steal) | `adom-cli hydrogen alert set --name "Shots: <ch>"` - shotlog does this for you | | Webview (backgrounded editor tab) | System notification | `adom-cli hydrogen notify …` |-| Pup / any window | Orange taskbar flash (FlashWindowEx) | `adom-desktop browser_alert_window {sessionId}` (pup) or `adom-desktop desktop_flash_window {hwnd}` (any window) |-| Any window | Glanceable taskbar status (progress bar + overlay icon) | `adom-desktop desktop_taskbar {hwnd, …}` |+| Pup / any window | Orange taskbar flash (FlashWindowEx) | `adom-bridge-cli pup_alert_window {sessionId}` (pup) or `adom-bridge-cli desktop_flash_window {hwnd}` (any window) |+| Any window | Glanceable taskbar status (progress bar + overlay icon) | `adom-bridge-cli desktop_taskbar {hwnd, …}` | ## Finding & targeting the right window (READ-ONLY, no foreground) You rarely need this for shotlog itself (the server handles surfacing), but when-you must locate a viewer window to flash/screenshot it, these AD verbs do it+you must locate a viewer window to flash/screenshot it, these Adom Bridge verbs do it without stealing focus - do NOT shell out to PowerShell, AD already exposes it: | Need | Verb | Notes |