hermes - 💡(How to fix) Fix Ctrl+Enter newline submits prompt over SSH/WSL because c-j is bound as submit

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

There are two related cases:

  1. Raw LF case:

    • Windows Terminal sends Ctrl+Enter as c-j.
    • Under WSL/SSH, Python sees sys.platform == "linux".
    • POSIX fallback binds c-j to submit so thin PTYs whose Enter arrives as LF still work.
    • That steals Ctrl+Enter from prompt_toolkit's multiline input path.
  2. Enhanced terminal protocol case:

    • Over SSH from modern terminals with Kitty keyboard protocol / xterm modifyOtherKeys enabled, Ctrl+Enter may arrive as enhanced CSI sequences instead of raw LF:
      • \x1b[13;5u
      • \x1b[27;5;13~
      • \x1b[27;5;13u
    • prompt_toolkit does not map these to Hermes' existing newline handler by default.

A previous WSL-only fix avoided binding c-j as submit in WSL, but the actual c-j newline handler was still only registered on native win32, so WSL/SSH still had a gap.

Fix Action

Fix / Workaround

Local commit with the tested patch:

Code Example

python -m pytest tests/cli/test_cli_shift_enter_newline.py \
  tests/hermes_cli/test_prompt_submit_keys.py \
  tests/cli/test_cli_init.py::TestPromptToolkitTerminalCompatibility -q
# 17 passed

python -m pytest tests/cli/test_cli_shift_enter_newline.py \
  tests/hermes_cli/test_prompt_submit_keys.py tests/cli -q
# 649 passed

---

plain_enter        -> [Keys.ControlM]
raw_ctrl_enter_lf  -> [Keys.ControlJ]
csiu_ctrl_enter    -> [Keys.Escape, Keys.ControlM]
mok_ctrl_enter     -> [Keys.Escape, Keys.ControlM]
alt_enter          -> [Keys.Escape, Keys.ControlM]

---

66942189a fix(cli): preserve Ctrl+Enter newline over SSH
RAW_BUFFERClick to expand / collapse

Bug description

In the classic Hermes CLI, Ctrl+Enter should insert a newline for multiline prompts in Windows Terminal / WSL / SSH workflows. After the recent Shift+Enter/newline changes, Ctrl+Enter can instead submit the prompt when Hermes is running under WSL or over SSH.

This is especially painful for Windows Terminal -> SSH/WSL users because Alt+Enter is often intercepted by Windows Terminal for fullscreen, so Ctrl+Enter is the discoverable Enter-involving multiline shortcut.

Reproduction / observed behavior

Environment observed locally:

  • Host: WSL2 / Linux (Linux ... microsoft-standard-WSL2)
  • Hermes checkout: NousResearch/hermes-agent main
  • Terminal behavior: Windows Terminal sends:
    • plain Enter: CR / c-m
    • Ctrl+Enter: LF / c-j

Before the fix:

  1. Start hermes in WSL or via SSH from Windows Terminal.
  2. Type a prompt.
  3. Press Ctrl+Enter intending to insert a newline.
  4. The prompt submits instead of inserting a newline, or the newline handler is not installed for the active platform.

Root cause

There are two related cases:

  1. Raw LF case:

    • Windows Terminal sends Ctrl+Enter as c-j.
    • Under WSL/SSH, Python sees sys.platform == "linux".
    • POSIX fallback binds c-j to submit so thin PTYs whose Enter arrives as LF still work.
    • That steals Ctrl+Enter from prompt_toolkit's multiline input path.
  2. Enhanced terminal protocol case:

    • Over SSH from modern terminals with Kitty keyboard protocol / xterm modifyOtherKeys enabled, Ctrl+Enter may arrive as enhanced CSI sequences instead of raw LF:
      • \x1b[13;5u
      • \x1b[27;5;13~
      • \x1b[27;5;13u
    • prompt_toolkit does not map these to Hermes' existing newline handler by default.

A previous WSL-only fix avoided binding c-j as submit in WSL, but the actual c-j newline handler was still only registered on native win32, so WSL/SSH still had a gap.

Expected behavior

  • Plain Enter submits.
  • Ctrl+Enter inserts a newline in Windows/WSL/SSH contexts where terminals deliver it as raw LF / c-j.
  • Enhanced Ctrl+Enter CSI-u / modifyOtherKeys sequences reach the same newline handler as Alt+Enter.
  • Local POSIX fallback can still bind c-j as submit outside Windows/WSL/SSH so thin PTYs are not regressed.

Proposed fix

Tested locally:

  • Add a _preserve_ctrl_enter_newline() predicate in cli.py that returns true for:
    • native Windows
    • WSL (including scrubbed env detection via /proc/* containing microsoft)
    • SSH sessions (SSH_CONNECTION, SSH_CLIENT, or SSH_TTY)
    • WT_SESSION
  • Only bind c-j to submit when that predicate is false.
  • Register the c-j newline handler whenever that predicate is true, not only on sys.platform == "win32".
  • Add install_ctrl_enter_alias() in hermes_cli/pt_input_extras.py mapping enhanced Ctrl+Enter sequences to (Keys.Escape, Keys.ControlM), reusing the existing Alt+Enter newline handler.
  • Add regression tests for WSL, SSH, raw-LF Ctrl+Enter, and enhanced Ctrl+Enter sequences.

Local validation:

python -m pytest tests/cli/test_cli_shift_enter_newline.py \
  tests/hermes_cli/test_prompt_submit_keys.py \
  tests/cli/test_cli_init.py::TestPromptToolkitTerminalCompatibility -q
# 17 passed

python -m pytest tests/cli/test_cli_shift_enter_newline.py \
  tests/hermes_cli/test_prompt_submit_keys.py tests/cli -q
# 649 passed

Local parser sanity check after the fix:

plain_enter        -> [Keys.ControlM]
raw_ctrl_enter_lf  -> [Keys.ControlJ]
csiu_ctrl_enter    -> [Keys.Escape, Keys.ControlM]
mok_ctrl_enter     -> [Keys.Escape, Keys.ControlM]
alt_enter          -> [Keys.Escape, Keys.ControlM]

Local commit with the tested patch:

66942189a fix(cli): preserve Ctrl+Enter newline over SSH

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

  • Plain Enter submits.
  • Ctrl+Enter inserts a newline in Windows/WSL/SSH contexts where terminals deliver it as raw LF / c-j.
  • Enhanced Ctrl+Enter CSI-u / modifyOtherKeys sequences reach the same newline handler as Alt+Enter.
  • Local POSIX fallback can still bind c-j as submit outside Windows/WSL/SSH so thin PTYs are not regressed.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix Ctrl+Enter newline submits prompt over SSH/WSL because c-j is bound as submit