← Commit history
README.md+26−1
@@ -64,6 +64,20 @@ Everything a real user installs comes from this page. 
 The Windows GUI installer is the only promoted Windows download. There is intentionally no standalone Windows CLI download. macOS is planned; the manifest reserves a slot for it.
 
+## Staying current: updates and the restart schedule
+
+Adom Desktop polls the wiki manifest on launch and every 4 hours. Every release is Azure code-signed and its installer is SHA256-verified before it runs. What differs is urgency, and the manifest carries a `priority`:
+
+| Tier | How it is presented | Overrides your mode? |
+|---|---|---|
+| **Normal** | Almost every release. A footer banner: Install now / Later. Silent in Auto, nothing in Off. | No. |
+| **High** | A recommended fix. Auto-installs in the background (even in Prompt) with a heads-up toast, then restarts. | Overrides Prompt; still respects Off. |
+| **Emergency** | A bug bad enough to pull from the whole fleet at once. A red, non-dismissible countdown to a forced restart; AD Authenticode-verifies the installer (must be signed by Adom Industries) before it runs. | Overrides everything, even Off, even embedded. |
+
+You set your preference once in **Settings, Updates**: Prompt (default), Auto, or Off. A normal release carries no priority; the emergency tier is a deliberate, per-incident action.
+
+**When a normal update actually installs.** Adom Desktop lives in the tray and can run for weeks without a restart, so a Prompt-mode update you never click would never install. The restart schedule closes that: once an update is downloaded AND you have been away from the keyboard for about 15 minutes AND AD is not mid-task, it installs and relaunches quietly. It is idle-based, not a fixed clock, so it never interrupts active work or an overnight job, and restarting Adom Desktop has no effect on your other apps (it reconnects in seconds). Turn it off in Settings, Updates, "Restart when idle to finish updates," and a Prompt-mode update simply waits for your click. Auto installs immediately; Off never auto-installs (except an Emergency release). Embedded in Hydrogen Desktop, HD owns the restart timing.
+
 ## Screenshots
 
 Anything AD can see, it can screenshot, losslessly, with **no focus steal** (`PrintWindow` or full-screen DXGI, never a foreground grab). *Every image on this page was produced by these verbs.* `desktop_screenshot_window` returns a **`screenshots[]` array**: the window plus each owned popup or child dialog as its own image (so a confirm bubble hovering over an app comes back alongside the parent, never missed); `desktop_screenshot_screen` grabs the full virtual screen including borderless popups; `browser_screenshot` grabs the pup viewport. Every shot carries a **`coordMap`** so the AI clicks *what it sees* (`{space:"image", shotId, x, y}` to real screen px, no DPI math). It stays generic: AD returns the rich array, the AI decides. `ad_scroll` even lets the AI page AD's own window to capture content below the fold.
@@ -127,11 +141,22 @@ AD's window carries a mode-specific app identity, so the taskbar button swaps it 
 Muted "Adom Desktop" = AD by itself; vivid "Adom Desktop HD Embedded" = HD has the helm. Each mode is a registered Windows app identity, and flipping the window between them makes the shell rebuild the button with the other identity's icon and name. Because the modes are distinct identities, a taskbar pin made in one mode shows the running window as a separate button while AD is in the other mode.
 
+## Window identity (branding a window the AI drives)
+
+The same Windows shell mechanism (the Application User Model ID, or AUMID) is exposed as generic verbs so a bridge can make a window it drives present as *its* app. The motivating case: a Chrome for Testing window that would otherwise read "Test" with Chrome's icon in the taskbar, Alt-Tab, and the right-click menu.
+
+- `desktop_register_app_identity` teaches Windows what an app id means (name plus icon), HKCU only, no UAC; `shortcut:false` gives a per-session identity with no Start Menu spam.
+- `desktop_set_window_identity` stamps that id onto a live window plus its title-bar and Alt-Tab icon and the jump-list header.
+- `desktop_set_window_jumplist` attaches a custom right-click menu and brands its header row.
+- `desktop_taskbar` paints a progress bar, an overlay badge, and the hover-preview tooltip (`thumbnailTooltip`, the one uncapped text surface) and clip on any window's button.
+
+These verbs inspect any icon you pass and return an `iconCheck` that explains, in plain terms, why an icon renders as a generic white document (the 256px `.ico` size must be PNG-compressed; SVG does not load; a `.ico` uses a bare path while a `.exe` uses `path,index`), so the caller fixes the file instead of shipping a broken icon. The full guide ships as the `adom-desktop-window-identity` skill.
+
 ## Settings
 
 ![Settings](docs/settings.png)
 
-Auto-connect behavior, the update channel (**prompt** / auto / off), the shell-approval preference, Hydrogen Desktop integration (including *exit when HD exits*), and runtime prewarming. While embedded in HD, HD-owned preferences show as *managed by Hydrogen Desktop*.
+Auto-connect behavior, the update channel (**prompt** / auto / off) and *restart when idle to finish updates*, the shell-approval preference, Hydrogen Desktop integration (including *exit when HD exits*), and runtime prewarming. While embedded in HD, HD-owned preferences show as *managed by Hydrogen Desktop*.
 
 ## Security and the approval gate
 
SKILL.md+5−1
@@ -1582,7 +1582,9 @@ Two ways to use it:   - `progress`: `{state: "normal"|"paused"|"error"|"indeterminate"|"none", value?: 0..100}` — **state→color**: normal=green, **paused=yellow** (use for human-in-the-loop gates: captcha / 2FA / login), error=red, indeterminate=marquee, none=clear.
   - `overlay`: `{badge: "adom"|"none", icon?: "<PNG or .ico — file path OR base64>", tooltip?: "<hover>", avatar?, profileDir?, userDataDir?, composite?}` — built-in badges are `adom` (the Adom logo — a "driven by Adom" trust tell) and `none` (clear); 3rd-party bridges pass their **own** `icon` (a **PNG** or `.ico`, file path or base64 — AD magic-sniffs + renders at 32px). AD stays generic: it paints whatever art you hand it. `tooltip` is the overlay's accessible description.
     - **Compositing onto a Chrome/Edge profile avatar (v1.9.110, #154):** Windows gives ONE overlay slot per taskbar button, and Chrome/Edge use it for the **profile avatar** — so a bare `badge:"adom"` would EVICT the profile face (you'd lose "work vs personal"). To keep the avatar AND show "Adom is driving", pass the avatar and AD composites the mark onto it (bottom-right ~47%): `overlay:{badge:"adom", avatar:"<PNG path or base64>"}`, or name the profile with `overlay:{badge:"adom", profileDir:"Profile 1", userDataDir?:"<User Data root>"}` (AD reads `<UserData>/<profileDir>/Google Profile Picture.png`; `userDataDir` is derived from the window's exe if omitted). `composite:false` opts out (raw mark). If the avatar can't be resolved AD falls back to the plain mark — never errors. The CALLER (which knows its profile — e.g. the browser extension) supplies the avatar; AD does not reverse-engineer it (one browser process serves all profiles, so the process command line has no `--profile-directory`).
-  - Returns `{ok, hwnd, title, applied:[...]}`. Clears: `flash:"stop"`, `progress.state:"none"`, `overlay.badge:"none"` — call these on task-end / window-close to clean up.
+  - `thumbnailTooltip` (v1.9.153): the taskbar **hover-preview tooltip** (`ITaskbarList3::SetThumbnailTooltip`). The ONLY uncapped text surface on the preview — the window title truncates ~25-30 chars, this string does not (and takes newlines). e.g. `"Adom Pup / Adom wiki / LOGGED-IN view / Chrome for Testing / 3 tabs"`. Pass `""` to clear it back to the title. Works on a window AD does not own.
+  - `thumbnailClip` (v1.9.153): crop the live hover preview to a client-space region — `{x,y,w,h}`, or `null` to reset to the whole window (`SetThumbnailClip`).
+  - Returns `{ok, hwnd, title, applied:[...]}`. Clears: `flash:"stop"`, `progress.state:"none"`, `overlay.badge:"none"`, `thumbnailTooltip:""`, `thumbnailClip:null` — call these on task-end / window-close to clean up.
   - Example (long task, human gate, then done):
     ```bash
     adom-desktop desktop_taskbar '{"hwnd":133560,"overlay":{"badge":"adom","tooltip":"Adom is driving this browser"},"progress":{"state":"indeterminate"}}'
@@ -1612,6 +1614,8 @@ Two ways to use it:   - `register_app_identity` writes HKCU only (never a UAC prompt). It is gated for RELAY callers like `write_file`; a bridge calling over the loopback API is trusted by transport and ungated.
   - **Jump-list tasks (v1.9.139+): `desktop_set_window_jumplist {appId, tasks}`** puts YOUR actions on the taskbar right-click menu of every window stamped with that appId. Jump lists attach to the AUMID, so per-session appIds give each window its OWN menu. Each task: `{title (required), target? (exe, defaults to AD's bundled CLI — so `args` can simply be an AD/bridge verb + JSON), args?, iconPath?, description?}`. Tasks launch minimized (no console flash). Max 16; `tasks:[]` clears (call at session close, alongside `unregister_app_identity`). Re-set anytime to update the menu. Tier-2 gated for relay callers; loopback bridges ungated.
   - **Per-session / transient appIds (v1.9.136+): register REGISTRY-ONLY with `shortcut:false`, unregister on close.** If you stamp per-session AUMIDs (e.g. `Adom.Pup.<sessionId>` so each window keeps its own taskbar button in split mode), an UNREGISTERED AUMID makes Alt-Tab fall back to the owning exe's icon. `desktop_register_app_identity {appId, displayName, iconPath, shortcut:false}` writes just the HKCU AppUserModelId key (DisplayName + IconUri) — Alt-Tab and taskbar hover resolve the name + icon with NO Start Menu entry. Pair with `desktop_unregister_app_identity {appId}` at session close (idempotent; removes the key plus any shortcut carrying that AUMID; AD's own `inc.adom.desktop` identity is protected). Keep ONE shortcut-mode registration as the pinnable launcher.
+  - **`desktop_set_window_jumplist`** (v1.9.139+) adds the right-click menu on the taskbar button (per-AUMID; `tasks:[]` clears) and, with `hwnd`+`headerIcon`, brands the header row (the app tile above Pin/Close).
+  - **Icon format — read the `iconCheck` these verbs return (v1.9.152).** `desktop_set_window_identity` / `desktop_register_app_identity` / `desktop_set_window_jumplist` return an `iconCheck {kind,sizes,issues,ok,hint}` (or `headerIconCheck`) that magic-sniffs the file and explains why an icon would render as a generic white document: a **256px `.ico` size not PNG-compressed** (the Vista+ trap), **SVG** (the Win32 shell can't load it), a `.ico` with no small size, an `.exe` where an image is wanted. If `iconCheck.ok` is false, fix the file and re-stamp. Ship a multi-size `.ico` (16/24/32/48/256, the 256 PNG-compressed). **Full guide:** the `adom-desktop-window-identity` skill (AUMID model, the register+stamp two-halves rule, jump-list header, taskbar overlay + thumbnail, the live-tile trap, a recipe).
 - `desktop_revoke_approvals` -- Revoke all shell auto-approve permissions and deny pending approvals. The next shell command will show the approval dialog.
   - Example: `adom-desktop desktop_revoke_approvals`
 - `desktop_caption` -- Show a global caption overlay that stays visible above ALL windows (KiCad, Fusion, Chrome). Native Win32 overlay — not a browser DOM element. Click-through: mouse events pass to windows below. Captured by screen recordings (browser `getDisplayMedia`, OBS, Game Bar).
dist/linux/adom-desktop
⋯ 1 unchanged line ⋯
package.json+2−2
@@ -1,8 +1,8 @@ {
   "slug": "adom-desktop",
-  "version": "1.9.151",
+  "version": "1.9.153",
   "type": "app",
-  "description": "Two parts, two machines. DOWNLOAD (below) = the Windows desktop APP — install it on the PC you want Claude to control (the bridge + GUI, signed, auto-updating). PKG INSTALL (this command) = for a cloud AI's Linux container/Docker — it drops the adom-desktop CLI + Claude skills there so an assistant can drive that Windows PC over the relay. You need the Download on your PC; you need the pkg only inside a container. Capabilities: file transfer, screenshots, notifications, KiCad + Fusion 360, real-Chrome (Puppeteer) automation, shell, windows, and Hydrogen Desktop proxy.",
+  "description": "Installs the adom-desktop CLI and its Claude skills INTO A CLOUD CONTAINER so an AI assistant there can understand and drive Adom Desktop over the relay. This is the container side, NOT the app itself. The Adom Desktop app is the signed Windows installer under Download below: run THAT on the PC you want the AI to control. Rule of thumb: pkg install here (in your Linux container), Download there (on your Windows PC). Once installed, the AI can drive file transfer, screenshots, notifications, KiCad and Fusion 360, real-Chrome (Puppeteer) automation, the shell, windows, and the Hydrogen Desktop proxy.",
   "discovery_pitch": "Use when a cloud AI needs to reach a real Windows desktop: run shell commands, capture screenshots, drive native apps and browsers, transfer files, and control KiCad / Fusion 360 / third-party bridges.",
   "discovery_triggers": [
     "control my windows desktop from the cloud",
page.json+2−2
@@ -1,8 +1,8 @@ {   "slug": "adom-desktop",-  "version": "1.9.151",+  "version": "1.9.153",   "type": "app",-  "description": "Two parts, two machines. DOWNLOAD (below) = the Windows desktop APP — install it on the PC you want Claude to control (the bridge + GUI, signed, auto-updating). PKG INSTALL (this command) = for a cloud AI's Linux container/Docker — it drops the adom-desktop CLI + Claude skills there so an assistant can drive that Windows PC over the relay. You need the Download on your PC; you need the pkg only inside a container. Capabilities: file transfer, screenshots, notifications, KiCad + Fusion 360, real-Chrome (Puppeteer) automation, shell, windows, and Hydrogen Desktop proxy.",+  "description": "Installs the adom-desktop CLI and its Claude skills INTO A CLOUD CONTAINER so an AI assistant there can understand and drive Adom Desktop over the relay. This is the container side, NOT the app itself. The Adom Desktop app is the signed Windows installer under Download below: run THAT on the PC you want the AI to control. Rule of thumb: pkg install here (in your Linux container), Download there (on your Windows PC). Once installed, the AI can drive file transfer, screenshots, notifications, KiCad and Fusion 360, real-Chrome (Puppeteer) automation, the shell, windows, and the Hydrogen Desktop proxy.",   "keywords": [     "adom-desktop",     "tauri",
skills/adom-desktop/SKILL.md+5−1
@@ -1582,7 +1582,9 @@ Two ways to use it:   - `progress`: `{state: "normal"|"paused"|"error"|"indeterminate"|"none", value?: 0..100}` — **state→color**: normal=green, **paused=yellow** (use for human-in-the-loop gates: captcha / 2FA / login), error=red, indeterminate=marquee, none=clear.
   - `overlay`: `{badge: "adom"|"none", icon?: "<PNG or .ico — file path OR base64>", tooltip?: "<hover>", avatar?, profileDir?, userDataDir?, composite?}` — built-in badges are `adom` (the Adom logo — a "driven by Adom" trust tell) and `none` (clear); 3rd-party bridges pass their **own** `icon` (a **PNG** or `.ico`, file path or base64 — AD magic-sniffs + renders at 32px). AD stays generic: it paints whatever art you hand it. `tooltip` is the overlay's accessible description.
     - **Compositing onto a Chrome/Edge profile avatar (v1.9.110, #154):** Windows gives ONE overlay slot per taskbar button, and Chrome/Edge use it for the **profile avatar** — so a bare `badge:"adom"` would EVICT the profile face (you'd lose "work vs personal"). To keep the avatar AND show "Adom is driving", pass the avatar and AD composites the mark onto it (bottom-right ~47%): `overlay:{badge:"adom", avatar:"<PNG path or base64>"}`, or name the profile with `overlay:{badge:"adom", profileDir:"Profile 1", userDataDir?:"<User Data root>"}` (AD reads `<UserData>/<profileDir>/Google Profile Picture.png`; `userDataDir` is derived from the window's exe if omitted). `composite:false` opts out (raw mark). If the avatar can't be resolved AD falls back to the plain mark — never errors. The CALLER (which knows its profile — e.g. the browser extension) supplies the avatar; AD does not reverse-engineer it (one browser process serves all profiles, so the process command line has no `--profile-directory`).
-  - Returns `{ok, hwnd, title, applied:[...]}`. Clears: `flash:"stop"`, `progress.state:"none"`, `overlay.badge:"none"` — call these on task-end / window-close to clean up.
+  - `thumbnailTooltip` (v1.9.153): the taskbar **hover-preview tooltip** (`ITaskbarList3::SetThumbnailTooltip`). The ONLY uncapped text surface on the preview — the window title truncates ~25-30 chars, this string does not (and takes newlines). e.g. `"Adom Pup / Adom wiki / LOGGED-IN view / Chrome for Testing / 3 tabs"`. Pass `""` to clear it back to the title. Works on a window AD does not own.
+  - `thumbnailClip` (v1.9.153): crop the live hover preview to a client-space region — `{x,y,w,h}`, or `null` to reset to the whole window (`SetThumbnailClip`).
+  - Returns `{ok, hwnd, title, applied:[...]}`. Clears: `flash:"stop"`, `progress.state:"none"`, `overlay.badge:"none"`, `thumbnailTooltip:""`, `thumbnailClip:null` — call these on task-end / window-close to clean up.
   - Example (long task, human gate, then done):
     ```bash
     adom-desktop desktop_taskbar '{"hwnd":133560,"overlay":{"badge":"adom","tooltip":"Adom is driving this browser"},"progress":{"state":"indeterminate"}}'
@@ -1612,6 +1614,8 @@ Two ways to use it:   - `register_app_identity` writes HKCU only (never a UAC prompt). It is gated for RELAY callers like `write_file`; a bridge calling over the loopback API is trusted by transport and ungated.
   - **Jump-list tasks (v1.9.139+): `desktop_set_window_jumplist {appId, tasks}`** puts YOUR actions on the taskbar right-click menu of every window stamped with that appId. Jump lists attach to the AUMID, so per-session appIds give each window its OWN menu. Each task: `{title (required), target? (exe, defaults to AD's bundled CLI — so `args` can simply be an AD/bridge verb + JSON), args?, iconPath?, description?}`. Tasks launch minimized (no console flash). Max 16; `tasks:[]` clears (call at session close, alongside `unregister_app_identity`). Re-set anytime to update the menu. Tier-2 gated for relay callers; loopback bridges ungated.
   - **Per-session / transient appIds (v1.9.136+): register REGISTRY-ONLY with `shortcut:false`, unregister on close.** If you stamp per-session AUMIDs (e.g. `Adom.Pup.<sessionId>` so each window keeps its own taskbar button in split mode), an UNREGISTERED AUMID makes Alt-Tab fall back to the owning exe's icon. `desktop_register_app_identity {appId, displayName, iconPath, shortcut:false}` writes just the HKCU AppUserModelId key (DisplayName + IconUri) — Alt-Tab and taskbar hover resolve the name + icon with NO Start Menu entry. Pair with `desktop_unregister_app_identity {appId}` at session close (idempotent; removes the key plus any shortcut carrying that AUMID; AD's own `inc.adom.desktop` identity is protected). Keep ONE shortcut-mode registration as the pinnable launcher.
+  - **`desktop_set_window_jumplist`** (v1.9.139+) adds the right-click menu on the taskbar button (per-AUMID; `tasks:[]` clears) and, with `hwnd`+`headerIcon`, brands the header row (the app tile above Pin/Close).
+  - **Icon format — read the `iconCheck` these verbs return (v1.9.152).** `desktop_set_window_identity` / `desktop_register_app_identity` / `desktop_set_window_jumplist` return an `iconCheck {kind,sizes,issues,ok,hint}` (or `headerIconCheck`) that magic-sniffs the file and explains why an icon would render as a generic white document: a **256px `.ico` size not PNG-compressed** (the Vista+ trap), **SVG** (the Win32 shell can't load it), a `.ico` with no small size, an `.exe` where an image is wanted. If `iconCheck.ok` is false, fix the file and re-stamp. Ship a multi-size `.ico` (16/24/32/48/256, the 256 PNG-compressed). **Full guide:** the `adom-desktop-window-identity` skill (AUMID model, the register+stamp two-halves rule, jump-list header, taskbar overlay + thumbnail, the live-tile trap, a recipe).
 - `desktop_revoke_approvals` -- Revoke all shell auto-approve permissions and deny pending approvals. The next shell command will show the approval dialog.
   - Example: `adom-desktop desktop_revoke_approvals`
 - `desktop_caption` -- Show a global caption overlay that stays visible above ALL windows (KiCad, Fusion, Chrome). Native Win32 overlay — not a browser DOM element. Click-through: mouse events pass to windows below. Captured by screen recordings (browser `getDisplayMedia`, OBS, Game Bar).
version.json+7−7
@@ -1,14 +1,14 @@ {   "manifest_version": 1,-  "version": "1.9.151",-  "released_at": "2026-07-21T13:05:58Z",+  "version": "1.9.153",+  "released_at": "2026-07-21T14:45:00Z",   "windows": {-    "installer_url": "https://wiki.adom.inc/download/adom/adom-desktop/1.9.151/Adom.Desktop_1.9.151_windows_x64-setup.exe",-    "installer_filename": "Adom.Desktop_1.9.151_windows_x64-setup.exe",-    "installer_sha256": "49144c443a4ae5f15f176f02f228ae6bc884484cf9e2dbdcd7da16b93231633c",-    "installer_size": 13372104+    "installer_url": "https://wiki.adom.inc/download/adom/adom-desktop/1.9.153/Adom%20Desktop_1.9.153_x64-setup.exe",+    "installer_filename": "Adom Desktop_1.9.153_x64-setup.exe",+    "installer_sha256": "bc2e3d10af8800905b909d5dced9a2d7ad03723d463a07c0637b23f7d58fff8a",+    "installer_size": 13373208   },   "changelog_url": "https://wiki.adom.inc/adom/adom-desktop",   "minimum_required": "1.3.30",-  "note": "Fixes the jump-list header icon for bridge windows using a standalone .ico (a stray resource index made the shell fall back to a generic icon), and softens the emergency restart wording since restarting Adom Desktop does not affect your other apps or work."+  "note": "Taskbar hover previews (thumbnail tooltip + clip), updates that install on an idle schedule so a long-running tray app stays current without a manual restart, and an icon-format check on the window-identity verbs." }