fix(dashboard): repaint stdscr immediately after modal closes
test / unit (pull_request) Successful in 18s
test / integration (pull_request) Successful in 1m7s

After the operator pressed `y` on the preflight modal (or
picked an agent in the picker), the modal's curses sub-window
stayed on screen until the dashboard's main loop ticked again
— which during a 5-10s launch made it look like the
confirmation never registered.

Add `_erase_modal` (touchwin + refresh on stdscr) and call it
at every exit from `_preflight_modal` and `_picker_modal`.
The pre-modal frame buffered on stdscr immediately overwrites
the sub-window's area; the launch proceeds with a clean
dashboard underneath.
This commit is contained in:
2026-05-26 15:01:56 -04:00
parent 0936c40428
commit e90d7dba76
+18
View File
@@ -445,6 +445,7 @@ def _picker_modal(
try:
key = stdscr.getch()
except KeyboardInterrupt:
_erase_modal(stdscr)
return None
if key == 27: # Esc
@@ -452,9 +453,11 @@ def _picker_modal(
query = ""
selected = 0
continue
_erase_modal(stdscr)
return None
if key in (curses.KEY_ENTER, 10, 13):
if filtered:
_erase_modal(stdscr)
return filtered[selected]
continue
if key in (curses.KEY_DOWN, ord("\x0e")): # KEY_DOWN, Ctrl-N
@@ -578,13 +581,28 @@ def _preflight_modal(
try:
key = stdscr.getch()
except KeyboardInterrupt:
_erase_modal(stdscr)
return False
if key in (ord("y"), ord("Y")):
_erase_modal(stdscr)
return True
if key in (ord("n"), ord("N"), 27, curses.KEY_ENTER, 10, 13):
_erase_modal(stdscr)
return False
def _erase_modal(stdscr: "curses._CursesWindow") -> None:
"""Force-redraw the dashboard's pre-modal frame so a modal
sub-window's content stops showing. Curses tracks the modal
via the newwin sub-window we created; touchwin + refresh
on stdscr repaints stdscr's last buffered frame over the
sub-window's area. Without this, the modal stays on screen
until the dashboard's main loop ticks again — which during
a long-running launch is several seconds away."""
stdscr.touchwin()
stdscr.refresh()
def _capture_preflight_text(plan) -> str:
"""Capture `plan.print` output by temporarily redirecting
stderr. Plan rendering is stderr-bound (existing behavior the