From 1f908069d955c35dd6fa478741dd28de7c001009 Mon Sep 17 00:00:00 2001 From: Chi-man Lay Date: Fri, 15 May 2026 22:54:30 +0100 Subject: [PATCH] fix(cli): await run_in_terminal futures to prevent RuntimeWarning prompt_toolkit 3.0+ changed run_in_terminal() to return an Awaitable[_T] (asyncio.Future). Hermes discarded it at two call sites, causing RuntimeWarning on /new, /reset, /undo confirmation. Capture the returned Future and block until completion via threading.Event + add_done_callback, with a 60s timeout. Closes #23297, closes #22970 Co-authored-by: Bartok9 <...@...> --- cli.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cli.py b/cli.py index 50e7a8c8ce9a..15790425a5c4 100644 --- a/cli.py +++ b/cli.py @@ -6482,7 +6482,12 @@ def _pick(): self._status_bar_visible = False self._app.invalidate() try: - run_in_terminal(_pick) + _future = run_in_terminal(_pick) + # run_in_terminal returns an Awaitable/Future in prompt_toolkit 3.0+. + # Block until it completes so the coroutine isn't orphaned. + _done = threading.Event() + _future.add_done_callback(lambda f: _done.set()) + _done.wait(timeout=60) finally: self._status_bar_visible = was_visible self._app.invalidate() @@ -6519,7 +6524,12 @@ def _ask(): self._status_bar_visible = False self._app.invalidate() try: - run_in_terminal(_ask) + _future = run_in_terminal(_ask) + # run_in_terminal returns an Awaitable/Future in prompt_toolkit 3.0+. + # Block until it completes so the coroutine isn't orphaned. + _done = threading.Event() + _future.add_done_callback(lambda f: _done.set()) + _done.wait(timeout=60) except Exception: # WSL / Warp / certain terminal emulators silently drop the # scheduled coroutine. Fall back to a direct input() so the