windows — Terminal Overview
A per-command ping tells you a terminal needs you, but it's gone the moment it fades: once you've moved to another virtual desktop or Windows Terminal window, nothing stands in for "here is everything currently waiting." The bash attention fragment and the claude notification hooks now route through ~/scripts/notify (a bell + OSC 9, a Windows toast on WSL, and — in Windows Terminal — an OSC 9;4 attention ring on the pinging tab itself); this item turns that stream of pings into a standing view — an always-on-top panel listing the terminal sessions that need attention, across every virtual desktop and WT instance, reusing the virtual desktop name overlay's WinForms, single-instance, and event-driven infrastructure.
The constraint: Windows Terminal exposes no tab state
The panel can't read WT's own "needs attention" state, because WT doesn't expose one. There is no tab-query CLI (microsoft/terminal#19818 is the open request), and the built-in tab bell indicator (#8106 / #8637) is internal UI only, with no documented way to read it from another process. Even listing tabs is non-trivial: WT tabs aren't Win32 windows, so an external enumerator has to walk the UI Automation tree (TabItem names) rather than EnumChildWindows.
So the overview is fed by our own signal, not by scraping WT: notify is already the single choke point every attention event passes through, which is why the feed rides on it.
Approach
- Attention feed.
notifyalso appends a record per event — title, command or body, exit code,$WT_SESSION, host, timestamp — to a spool the panel watches. Records clear on a TTL, on an explicit dismiss, or when their session is focused. - The panel. Reuse
virtual-desktop-overlay.ps1's scaffolding (the topmost layered WinForms window, the single-instance mutex + quit event, the event-driven repaint) to render the pending records as a list instead of a single desktop-name pill. Click a row to dismiss it. - Desktop / instance map (enrichment). Enumerate WT top-level windows and resolve each to its virtual desktop with the documented
IVirtualDesktopManager::GetWindowDesktopId(the Virtual Desktop Router already usesIVirtualDesktopManager), mapping the GUID to a name through the same registry keys the overlay reads; read per-tab titles via UI Automation. This lets the panel group waiting sessions by desktop.
Open questions
- Record-to-tab correlation. A record is keyed by
$WT_SESSION, which the shell knows but which WT exposes nowhere externally (not through UIA). Both halves of the click path exist:notify --clear --capture(Claude Code's prompt-submit hook) records the session's hosting window HWND at the one moment it is provably foreground, and at ping timenotifystamps the tab's title so thedotfilespro-focushandler can select theTabItemby UIA name match after focusing the window — so records can be grouped by window and desktop, and click-to-switch can reuse the handler wholesale. What the panel still cannot do is read tabs it hasn't focused: WT populates no UIA tree for an unrendered (background, minimized, other-desktop) window, so enumerating or annotating tabs across windows without focusing each one remains blocked on a WT-side query (microsoft/terminal#19818). - Where the spool lives so both the WSL writer and the Windows-side reader reach it cheaply — a Linux path over
\\wsl$versus a%LOCALAPPDATA%path written through interop. - OSC 9;4 as a second source.
notifyalready sets the OSC 9;4 error / warning / default state on the pinging tab and taskbar (cleared when the session regains focus), so an individual tab flags itself natively; the open question is whether the panel also reads that per-tab state to corroborate its own feed, or stays purelynotify-fed. - Packaging. Like the overlay-extraction item it sits beside, this is a standalone WinForms widget that could ship independently of the rest of the role.