koffi ABI
The FFI addon is built for Electron's ABI. Run window-enumeration spikes under Electron, not plain node.
launcher pid
Firefox's launcher relaunches into a different pid that owns the window. Identify our FF by the profile-path token in its command line, not the spawned pid.
-no-remote
It disables the remote server that -new-window forwards into. The shared model must NOT pass it for the first window.
no global WebSocket
Electron 31 main = Node 20 has none. The control server must require('ws').
UAC off ≠ elevated
A normal process still can't write Program Files. Use Start-Process -Verb RunAs (promptless with UAC off).
GetWindowLongPtr
Not a real 64-bit user32 export (it's a macro). Call GetWindowLongPtrW, or the enumeration throws mid-callback.
detached firefox
A spawn-detached Firefox survives killing the shell and holds the profile / floats orphan windows. Kill it explicitly by tag.
case-insensitive paths
Windows paths are case-insensitive: %APPDATA%\App and \app are one folder, not two. Dedupe before deleting or the counts lie.
silent stdout
Electron GUI console.log is invisible from the Windows console. Have spikes write results to a file.
koffi handles
HWNDs come back Number-or-BigInt. Normalize to BigInt at the boundary or === silently mismatches.
GPU compositing
Chromium's DirectComposition paints over native child windows. app.disableHardwareAcceleration() on the shell — it only draws chrome.
re-asserted geometry
A native window re-applies its own saved position on startup and overrides ours. Re-assert the layout a few times (400–7000 ms) until it settles.
nativeHandle = HWND
nsIBaseWindow.nativeHandle from chrome JS is the top-level HWND (a hex string) — it matches EnumWindows after BigInt-normalizing. That's per-window identity on one shared process.
start() race
A control server's start() must be concurrency-safe: hand simultaneous callers the same in-flight promise, never resolve with a port that isn't assigned yet (0).
userChrome !important
A user-origin !important beats an inline style, so you can't reveal a hidden toolbar by setting inline CSS. Gate the collapse behind :not([attr]) and toggle the attribute.