Skip to content

fix(cli): prevent /reset and /new freeze on Windows by falling back to stdin prompt (#30768)#32013

Merged
teknium1 merged 2 commits into
mainfrom
fix/windows-slash-modal-freeze
May 25, 2026
Merged

fix(cli): prevent /reset and /new freeze on Windows by falling back to stdin prompt (#30768)#32013
teknium1 merged 2 commits into
mainfrom
fix/windows-slash-modal-freeze

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

/reset, /new, /curator wipe, and /exit --delete no longer freeze on Windows. The destructive-slash confirmation modal previously deadlocked because prompt_toolkit's input channel becomes unresponsive when the modal is entered from the process_loop daemon thread — keystrokes never reached the key bindings, so response_queue.get() blocked for the full 120-second timeout. Fixes #30768.

Fix

_prompt_text_input_modal falls back to the stdin-based _prompt_text_input prompt when:

  1. sys.platform == "win32" — Windows ConPTY doesn't support the modal reliably.
  2. Called from a non-main thread — prompt_toolkit key bindings can only fire from the main thread (same rationale as the existing thread guard in _prompt_text_input, PR fix(cli): drive _prompt_text_input directly when off main thread (#23185) #23454).
  3. self._app is None — unchanged, existing behavior for tests/non-interactive contexts.

macOS and Linux main-thread paths still use the rich modal — no regression.

Changes

  • cli.py — two new guard clauses at the top of _prompt_text_input_modal plus an updated docstring explaining the Windows deadlock.
  • tests/cli/test_slash_confirm_windows.py — 9 new regression tests covering: Windows detection, non-main-thread fallback, macOS/Linux modal preservation, no-app fallback (existing), empty-choices behavior, integration via _confirm_destructive_slash.
  • scripts/release.pyAUTHOR_MAP entry mapping simo.kiihamaki@gmail.com to @SimoKiihamaki for the attribution check.

Validation

Before After
/reset on Windows 120s deadlock, then timeout immediate Choice [1/2/3]: prompt, responsive
/new on Windows 120s deadlock immediate prompt
/curator wipe on Windows 120s deadlock immediate prompt
/reset on macOS/Linux Rich modal panel Rich modal panel (unchanged)
Modal called from daemon thread Deadlock on ALL platforms stdin fallback (safe)

Targeted tests: tests/cli/test_slash_confirm_windows.py (9 new) + tests/cli/test_destructive_slash_confirm.py + tests/cli/test_destructive_slash_inline_skip_e2e.py — 28/28 passing.

Salvage notes

Surgical reapply of PR #30773 by @SimoKiihamaki (commit ed136c98e, simo.kiihamaki@gmail.com). The original branch was many months stale against current main and a direct cherry-pick would have reverted 911 unrelated files (−146,163 LOC), including the entire kanban-tutorial docs tree, ntfy plugin, docker s6 infrastructure, dozens of skill files, and the multi-language locale infrastructure. The substantive ~30 LOC change in cli.py plus the new 259-line regression test file were reapplied by hand onto current main with the contributor's authorship preserved via git commit --author=.

Original PR #30773 will be closed pointing to this one. Issue #30768 will auto-close from the merge commit footer.

Infographic

windows-slash-modal-freeze

https://v3b.fal.media/files/b/0a9b9dbf/VlmYQitISHT0_YK_49yp9_yqhGQNPn.png

SimoKiihamaki and others added 2 commits May 25, 2026 03:50
…o stdin prompt

On Windows (PowerShell/Windows Terminal), the queue-based modal used for
destructive slash command confirmations deadlocks because prompt_toolkit's
input channel becomes unresponsive when entered from the process_loop daemon
thread. Keystrokes never reach the key bindings, so response_queue.get()
blocks until the 120-second timeout expires.

Fix: fall back to _prompt_text_input (stdin-based) when:
1. sys.platform == 'win32' — Windows console doesn't support the modal reliably
2. Called from non-main thread — key bindings can't fire from daemon threads
3. self._app is not set — existing behavior for tests/non-interactive

This mirrors the thread-aware guard from _prompt_text_input (PR #23454).

9 new regression tests covering Windows detection, non-main thread fallback,
macOS/Linux modal preservation, and integration with _confirm_destructive_slash.

Fixes #30768

Surgical reapply of PR #30773. Original branch was many months stale (911
files / 146k LOC of unrelated reverts); the substantive ~30 LOC change in
cli.py plus the new test file were reapplied onto current main with the
contributor's authorship preserved via --author.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: fix/windows-slash-modal-freeze vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 9257 on HEAD, 9256 on base (🆕 +1)

🆕 New issues (1):

Rule Count
unresolved-import 1
First entries
tests/cli/test_slash_confirm_windows.py:23: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`

✅ Fixed issues: none

Unchanged: 4909 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels May 25, 2026
@teknium1 teknium1 merged commit ee7789e into main May 25, 2026
32 of 34 checks passed
@teknium1 teknium1 deleted the fix/windows-slash-modal-freeze branch May 25, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: /reset and /new slash commands freeze on Windows — routes to interactive CLI menu

3 participants