Issue
In the Hermes interactive TUI on macOS, Shift+Enter submits the message instead of inserting a newline. The only working multi-line input method is Escape then Enter.
Ctrl+Enter has the same problem — it submits rather than inserting a newline.
Expected behavior
Shift+Enter → insert newline (standard convention across chat apps and most AI agent CLIs)
Ctrl+Enter → insert newline
Alt/Option+Enter → insert newline (works with Option-as-Meta terminal setting)
Esc then Enter → insert newline (currently works, but not discoverable)
Enter → submit
Actual behavior
Shift+Enter and Ctrl+Enter are not distinguished from plain Enter — all three submit immediately.
Root Cause Analysis
macOS Terminal.app and Alacritty send the same byte (\\r) for Enter, Shift+Enter, and Ctrl+Enter. The key modifier is lost at the terminal/OS layer and never reaches prompt_toolkit. So there is no byte sequence for Hermes to intercept and rebind.
The existing ANSI escape aliases in hermes_cli/pt_input_extras.py (for \\x1b[13;2u, \\x1b[27;2;13~, etc.) only fire in terminals that implement the Kitty keyboard protocol or xterm modifyOtherKeys — which macOS Terminal.app and Alacritty do not enable by default.
Alt/Option+Enter works because macOS terminals can send Option as "Meta" (Escape prefix), producing \\x1b\\r (Escape + Enter), which prompt_toolkit sees as (Escape, Enter) and triggers the existing kb.add('escape', 'enter') newline handler.
Terminals Tested
| Terminal |
OS |
Shift+Enter |
Ctrl+Enter |
Alt/Option+Enter |
Esc+Enter |
| Terminal.app |
macOS 26.4.1 |
Submit |
Submit |
Newline (Meta enabled) |
Newline |
| Alacritty |
macOS 26.4.1 |
Submit |
Submit |
Newline (Meta enabled) |
Newline |
Note: _preserve_ctrl_enter_newline() in cli.py (line 1913) returns False on native macOS, so c-j is bound to submit (line 1959) rather than newline. This is correct for SSH/docker-over-TTY where \\n IS the Enter key, but it means Ctrl+Enter has no newline path on POSIX.
Proposed Solutions
Option 1: Document a workaround (lowest effort)
Add a note to the docs / /help output explaining that on macOS Terminal.app and Alacritty, users must either:
- Enable Option-as-Meta for
Alt+Enter newline
- Use
Esc then Enter
This is honest but does not improve the UX.
Option 2: Add a config setting for a dedicated newline key (medium effort)
Allow users to bind an additional key to "insert newline" in config.yaml:
tui:
newline_key: c-n # or "c-o", "m-enter", etc.
Users who find Esc+Enter awkward could pick Ctrl+N (or another unused key) as their newline. This would require adding a config knob and wiring it into the keybinding section of cli.py (_bind_prompt_submit_keys area, around line 1944-1960).
Option 3: Double-Enter for multi-line (highest UX impact)
Detect when the user types Enter on an empty line or at the end of their input to insert a newline, and only submit on a second Enter. This is how some chat apps work (e.g., Slack in certain modes). Would require a small change to the submit handler logic.
Option 4: Kitty keyboard protocol support in TUI
Enable the Kitty keyboard protocol in the prompt_appkit TUI (the app already enables some kitty features at line 1906-1908). If prompt_toolkit supports Kitty keyboard mode natively or via a plugin, enabling it could make Shift+Enter/Ctrl+Enter emit distinct CSI-u sequences, making the existing pt_input_extras.py mappings work.
Related Issues
Issue
In the Hermes interactive TUI on macOS,
Shift+Entersubmits the message instead of inserting a newline. The only working multi-line input method isEscapethenEnter.Ctrl+Enterhas the same problem — it submits rather than inserting a newline.Expected behavior
Shift+Enter→ insert newline (standard convention across chat apps and most AI agent CLIs)Ctrl+Enter→ insert newlineAlt/Option+Enter→ insert newline (works with Option-as-Meta terminal setting)EscthenEnter→ insert newline (currently works, but not discoverable)Enter→ submitActual behavior
Shift+EnterandCtrl+Enterare not distinguished from plainEnter— all three submit immediately.Root Cause Analysis
macOS Terminal.app and Alacritty send the same byte (
\\r) forEnter,Shift+Enter, andCtrl+Enter. The key modifier is lost at the terminal/OS layer and never reachesprompt_toolkit. So there is no byte sequence for Hermes to intercept and rebind.The existing ANSI escape aliases in
hermes_cli/pt_input_extras.py(for\\x1b[13;2u,\\x1b[27;2;13~, etc.) only fire in terminals that implement the Kitty keyboard protocol or xtermmodifyOtherKeys— which macOS Terminal.app and Alacritty do not enable by default.Alt/Option+Enterworks because macOS terminals can send Option as "Meta" (Escape prefix), producing\\x1b\\r(Escape + Enter), whichprompt_toolkitsees as(Escape, Enter)and triggers the existingkb.add('escape', 'enter')newline handler.Terminals Tested
Note:
_preserve_ctrl_enter_newline()incli.py(line 1913) returnsFalseon native macOS, soc-jis bound to submit (line 1959) rather than newline. This is correct for SSH/docker-over-TTY where\\nIS the Enter key, but it meansCtrl+Enterhas no newline path on POSIX.Proposed Solutions
Option 1: Document a workaround (lowest effort)
Add a note to the docs /
/helpoutput explaining that on macOS Terminal.app and Alacritty, users must either:Alt+EnternewlineEscthenEnterThis is honest but does not improve the UX.
Option 2: Add a config setting for a dedicated newline key (medium effort)
Allow users to bind an additional key to "insert newline" in
config.yaml:Users who find
Esc+Enterawkward could pickCtrl+N(or another unused key) as their newline. This would require adding a config knob and wiring it into the keybinding section ofcli.py(_bind_prompt_submit_keysarea, around line 1944-1960).Option 3: Double-Enter for multi-line (highest UX impact)
Detect when the user types
Enteron an empty line or at the end of their input to insert a newline, and only submit on a secondEnter. This is how some chat apps work (e.g., Slack in certain modes). Would require a small change to the submit handler logic.Option 4: Kitty keyboard protocol support in TUI
Enable the Kitty keyboard protocol in the prompt_appkit TUI (the app already enables some kitty features at line 1906-1908). If prompt_toolkit supports Kitty keyboard mode natively or via a plugin, enabling it could make
Shift+Enter/Ctrl+Enteremit distinct CSI-u sequences, making the existingpt_input_extras.pymappings work.Related Issues