fix: disable Rich Live transient mode on Windows to prevent PS 5.1 hang (#2938)

* fix: disable Rich Live transient mode on Windows to prevent PS 5.1 hang

PowerShell 5.1's legacy console host does not reliably support VT escape
sequences. Rich's Live(transient=True) attempts cursor restoration on
context exit, which hangs indefinitely on that console.

Set transient=False when sys.platform == 'win32' in both init.py (progress
tracker) and _console.py (select_with_arrows). The only cosmetic effect is
that progress output remains visible after completion on Windows.

Fixes #2927

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test: address review feedback on test quality

- Use captured['transient'] instead of .get() for clearer KeyError on failure
- Source guards now assert both the platform check AND transient=_transient usage
- Remove unused imports (MagicMock retained as it's used, removed pytest)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test: use regex in source guards for resilience to formatting changes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test: use single DOTALL regex to verify assignment flows into Live()

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: skip duplicate tracker print on Windows when transient=False

When transient is False, Rich leaves the Live output on screen. The
subsequent console.print(tracker.render()) would duplicate it. Gate
it behind _transient so Windows users see the tracker exactly once.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Manfred Riem <mnriem@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Manfred Riem
2026-06-17 06:48:42 -05:00
committed by GitHub
parent ae23a84677
commit 75aee19c6e
3 changed files with 100 additions and 3 deletions

View File

@@ -7,6 +7,7 @@ layer, not out of it, to avoid circular imports.
"""
from __future__ import annotations
import sys
from collections.abc import Callable
import readchar
@@ -192,7 +193,8 @@ def select_with_arrows(
def run_selection_loop():
nonlocal selected_key, selected_index
with Live(create_selection_panel(), console=console, transient=True, auto_refresh=False) as live:
_transient = sys.platform != "win32"
with Live(create_selection_panel(), console=console, transient=_transient, auto_refresh=False) as live:
while True:
try:
key = get_key()

View File

@@ -381,8 +381,12 @@ def register(app: typer.Typer) -> None:
]:
tracker.add(key, label)
# Disable transient mode on Windows: PowerShell 5.1's legacy console
# hangs when Rich tries to restore cursor state via VT escape sequences.
_transient = sys.platform != "win32"
with Live(
tracker.render(), console=console, refresh_per_second=8, transient=True
tracker.render(), console=console, refresh_per_second=8, transient=_transient
) as live:
tracker.attach_refresh(lambda: live.update(tracker.render()))
try:
@@ -652,7 +656,8 @@ def register(app: typer.Typer) -> None:
finally:
pass
console.print(tracker.render())
if _transient:
console.print(tracker.render())
console.print("\n[bold green]Project ready.[/bold green]")
agent_config = AGENT_CONFIG.get(selected_ai)