← Commit history

Delete skills/adom-bridge-window-identity

Kyle Bergstedt ·4382e289a8 ·2mo ago ·parent 65794bd
1 file changed −106
skills/adom-bridge-window-identity/SKILL.mddeleted−106
@@ -1,106 +0,0 @@-----name: adom-bridge-window-identity-description: Make a window an AI drives present itself as YOUR app on Windows — its taskbar button, Alt-Tab entry, hover name, jump-list (right-click menu), taskbar overlay badge, and pins. Covers the AUMID model, the register+stamp two-halves rule, per-session identities, jump-list tasks + header branding, taskbar progress/overlay, and the icon-format rules (why an icon renders as a generic white document and how to fix it). Use when a bridge borrows a host window (e.g. Chrome for Testing) and it reads as the wrong app.------# Window identity and the taskbar — Adom Bridge's AUMID verbs--This is an advanced corner of the Windows shell that few APIs expose cleanly. Adom Bridge (Adom Bridge) wraps it in a small, **generic** verb family: you pass a name + icon + (optionally) a command, and Adom Bridge makes any window — even one owned by another process — present itself as *your* app across every shell surface. Adom Bridge knows nothing about which app you are; it applies what you pass.--The motivating case: a bridge drives a **Chrome for Testing** window, which otherwise reads *"Test"* with Chrome's icon in the taskbar and Alt-Tab — two brands and a confusing word. These verbs make it read as your bridge instead.--## The one concept you must hold: the AUMID--Windows groups and labels windows by their **Application User Model ID** (AUMID) — a short dotted string like `Adom.Pup.session42`. The AUMID is what the shell resolves to get:--- the **taskbar button** grouping, its **icon**, and its **name**-- the **Alt-Tab** entry (icon + name)-- the **jump list** (the right-click menu on the taskbar button) and its **header row** (the app tile above *Pin to taskbar* / *Close window*)-- **toasts** you raise, and how a user **pins** the window--A window has *some* AUMID whether you set one or not (it inherits the owning process's). Your job is to (1) give the window a **specific** AUMID and (2) tell Windows what that AUMID **means** (its name + icon). Those are two different operations — miss either and the identity is half-wrong.--## The two halves — you need BOTH--| Half | Verb | What it does |-|---|---|---|-| **Stamp the window** | `desktop_set_window_identity {hwnd, appId, iconPath, displayName, relaunchCommand}` | Puts the AUMID on the *live* HWND (`PKEY_AppUserModel_ID`) + sets the title-bar/Alt-Tab icon (`WM_SETICON`) + the Relaunch trio for the jump-list header. |-| **Register the AUMID** | `desktop_register_app_identity {appId, displayName, iconPath, shortcut?}` | Teaches Windows what that appId *means*: an HKCU `AppUserModelId\<appId>` key (name + icon) and, when `shortcut:true`, a Start Menu shortcut carrying the AUMID (what makes it **pinnable**). |--Stamp without register → Alt-Tab / the taskbar fall back to the owning exe's icon (the "Test / Chrome icon" problem). Register without stamp → nothing points the window at your AUMID. **Do both.**--`desktop_unregister_app_identity {appId}` removes the registration (HKCU key + any Start Menu shortcut carrying that AUMID) — call it when a per-session identity is done.--Everything here is **HKCU only** — no elevation, no UAC prompt, ever.--## Per-session identities (`shortcut:false`)--For a window that comes and goes (one browser session), you want a **distinct** AUMID per window so each keeps its own taskbar button, but you do NOT want a Start Menu shortcut per session (that would spray dead entries). Register with `shortcut:false`:--```-desktop_register_app_identity {appId:"Adom.Pup.session42", displayName:"Adom Pup", iconPath:"C:\\...\\pup.ico", shortcut:false}-desktop_set_window_identity   {hwnd:<cft hwnd>, appId:"Adom.Pup.session42", iconPath:"C:\\...\\pup.ico", displayName:"Adom Pup", relaunchCommand:"<how to reopen>"}-```--Registry-only registration gives Alt-Tab + taskbar hover the right name + icon with no Start Menu spam. Pair every `shortcut:false` register with an `unregister` at session close. Such an identity is **not pinnable** (no shortcut) — keep a separate shortcut-mode registration for a launcher identity you want users to pin.--## Jump lists — the right-click menu + its header--`desktop_set_window_jumplist {appId, tasks, hwnd?, headerIcon?, headerCommand?, headerName?}` attaches a custom right-click menu to the AUMID. Each task: `{title, target?, args?, iconPath?, description?}` (target defaults to Adom Bridge's bundled CLI, so a task can just be a verb + JSON). `tasks:[]` clears the list.--- Tasks appear on the taskbar right-click menu of **every** window stamped with that AUMID, so a per-session appId gives a per-window menu.-- **The header row** (the app tile above Pin/Close) is a *separate* surface. It is painted from the **window's Relaunch trio**, not the AUMID registry icon — so a `shortcut:false` AUMID shows a generic icon there unless you brand it. Pass `hwnd` + `headerIcon` (and optionally `headerCommand`/`headerName`) and Adom Bridge stamps the window's Relaunch trio so the header renders your icon **without** a Start Menu shortcut. `headerBranded:true` in the response confirms it stuck.--## Taskbar status — progress + overlay badge--`desktop_taskbar {hwnd, progress?, overlay?, flash?}` paints **glanceable status** on any window's taskbar button (works cross-process), so you can show what the AI is doing on the real app window it drives:--- `progress:{state:"normal"|"paused"|"error"|"indeterminate"|"none", value?}` — a colored bar (green / yellow = human-in-the-loop like a captcha / red / marquee).-- `overlay:{badge:"adom"|"none", icon?:<.png/.ico path or base64>, avatar?, tooltip?}` — a small badge in the button corner. For Chrome/Edge, that overlay slot holds the **profile avatar**; pass `avatar` and Adom Bridge composites your mark onto it so the user keeps work-vs-personal.-- `flash:"until_focused"|"count"|"stop"` — flash the button for attention.--`desktop_flash_window` is the lightweight flash-only cousin.--## Toasts--`notify_user` raises a native Windows toast under Adom Bridge's own identity (AUMID `inc.adom.bridge`, the Adom logo). See the `adom-bridge-notify` skill for the full toast catalog (progress, sticky reminders, buttons that round-trip a click).--## Icon formats — why an icon renders as a generic white document--This is the #1 source of "my icon doesn't show." The identity verbs return an **`iconCheck`** block that inspects the file you passed and lists concrete problems. The rules it encodes:--- **Give a multi-size `.ico`** (16 / 24 / 32 / 48 / 256). A single-size icon looks bad where the shell wants a different size.-- **The 256×256 size MUST be PNG-compressed.** Since Windows Vista, a 256px `.ico` entry stored as an uncompressed BMP/DIB renders as the **generic white-document icon** on the jump-list header and taskbar. This is subtle: the icon looks fine in an image viewer but wrong in the shell. Re-export the `.ico` with the 256px size PNG-compressed (most icon tools do this; if unsure, drop the 256px size). `iconCheck` flags this specifically.-- **A per-window `RelaunchIconResource` (the jump-list header) for a `.ico` uses a BARE path** — Adom Bridge handles this; you just pass the `.ico`. A stray `path,0` (the PE-resource form) breaks a `.ico`, because the shell then looks for "resource index 0 of a PE module," which a `.ico` is not → generic icon. (This was a real bug, fixed Adom Bridge 1.9.151.)-- **A PE module (`.exe`/`.dll`) is referenced as `<path>,<index>`.** Adom Bridge uses `,0`; pass your own index if your icon isn't resource 0. A standalone `.ico` is simpler.-- **SVG does not work** — the Win32 shell can't load it. Convert to `.ico`/`.png`.-- **The AUMID registry icon (taskbar/Alt-Tab) accepts `.ico` or `.png`; an `.exe` path there renders the blank-doc icon.** A taskbar **overlay** wants a small (~16px) image; a `.png` is ideal (Adom Bridge converts it to `.ico` internally).--If `iconCheck.ok` is false, fix the file per `iconCheck.issues` and re-stamp — don't ship the broken icon.--## The live-tile trap (the one timing gotcha)--Re-stamping the **same** appId on a **live** window with a new icon updates the title bar + Alt-Tab but **not** the taskbar tile: Win11 bakes the tile when the button is *created* and never re-reads it (WM_SETICON, ITaskbarList DeleteTab+AddTab, SHChangeNotify, RedrawWindow — all measured no-ops). The only non-disruptive way to change a live tile is to make the shell create a **new** button: register a **different** appId (registry-only, new icon) and stamp the window with it — the button is destroyed and recreated with the new tile in ~1s, no window flicker. Cost: a pin made under the old appId shows the running window as a separate button, so use a **stable** appId for identity you want pinnable and a **varying** one only when the tile must track state.--## Recipe: brand a borrowed window end-to-end--```-# 1. Teach Windows the identity (once per install for a stable id; per session for shortcut:false)-desktop_register_app_identity {appId:"MyBridge.Session7", displayName:"My Bridge", iconPath:"C:\\bridge\\icon.ico", shortcut:false}--# 2. Stamp the live window (taskbar + Alt-Tab + title bar) and brand the jump-list header (Relaunch trio)-desktop_set_window_identity {hwnd:<hwnd>, appId:"MyBridge.Session7", iconPath:"C:\\bridge\\icon.ico", displayName:"My Bridge", relaunchCommand:"mybridge --reopen 7"}--# 3. Attach a right-click menu (optional) + brand its header row-desktop_set_window_jumplist {appId:"MyBridge.Session7", hwnd:<hwnd>, headerIcon:"C:\\bridge\\icon.ico",-                             tasks:[{title:"New tab", args:"browser_open_window {}"}]}--# 4. Show live status on the button while you work (optional)-desktop_taskbar {hwnd:<hwnd>, overlay:{badge:"adom", tooltip:"My Bridge is driving"}, progress:{state:"indeterminate"}}--# 5. On session close-desktop_taskbar {hwnd:<hwnd>, progress:{state:"none"}, overlay:{badge:"none"}, flash:"stop"}-desktop_unregister_app_identity {appId:"MyBridge.Session7"}-```--Resolve `<hwnd>` with `desktop_list_windows` / `desktop_find_window`.