fix(window-targeting): harden tile:window:{maximize,fullscreen,center} against bad ids; correct .d.ts; add regression tests
User reported that running the maximize command while a search window
(e.g. cmd: #todo) is open in front of a content window maximizes the
content window behind it instead of the search window.
I could not reproduce the reported scenario in a Playwright test —
across three variants (manual focus call, natural open-then-open
without explicit focus, real peek://search/home.html with the manifest
key) the focus tracker correctly returned the front-most workspace
window and getFocusedVisibleWindowId resolved to it. So the production
bug must depend on additional state (cmd-panel autoclose timing,
NSPanel focus events, or something my test environment doesn't model).
Defensive fixes that close adjacent failure modes:
- Harden tile:window:maximize / fullscreen / center IPC handlers to
reject non-number args.id loudly. Previously these silently fell back
to BrowserWindow.fromWebContents(event.sender) when the caller passed
a non-number, which would let a "forgot to unwrap the envelope" caller
bug propagate as wrong-window targeting. Now returns a clear
"Invalid window id" error.
- Correct backend/electron/tile-api.d.ts: getFocusedVisibleWindowId is
declared as Promise<{success, windowId, error}>, but the preload
unwraps and returns Promise<number | null>. The wrong type silently
approves bugs where a caller treats the result as a {success, ...}
envelope.
- Three regression tests in tests/desktop/window-targeting.spec.ts that
cover the focus-tracker layer for the maximize-targeting scenario
(basic, natural-flow without explicit focus, real search tile open
with the manifest key). All currently green — they document the
contract and will catch regressions if the tracker layer ever drifts.
The user repro likely needs in-app diagnostic logging to pin down
whether the focus event isn't firing, the tracker is being overwritten,
or the cmd-panel-modal flow has a state issue. None of those are
addressable from these defensive fixes alone.