mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
fix(cli): kill resize scrollback duplication + light-mode visibility
Two long-standing prompt_toolkit bugs in the base hermes CLI: 1. Resize duplication. Column-shrink resize used to push 40+ rows of duplicate chrome (status bar, input rules) into terminal scrollback every resize. Same wall as pt issues #29 (open since 2014), #1675, #1933 — aider/xonsh/ipython all use alt-screen to dodge it. Root cause (verified by reading prompt_toolkit/renderer.py): _output_screen_diff (renderer.py L232-242) deliberately moves the cursor to the bottom of the canvas after every paint 'to make sure the terminal scrolls up'. In non-fullscreen mode this scrolls chrome content into terminal scrollback on every render — not just on resize. Fix: monkey-patch prompt_toolkit.renderer._output_screen_diff to bypass the reserve-vertical-space cursor move. When pt's logic checks 'if current_height > previous_screen.height', we inflate the previous screen height so the branch falls through. ~30-line wrapper, no fork of pt, no alt-screen, no DECSTBM scroll region. Verified empirically in real Terminal.app: 10 resizes (mixed shrinks/widens 1300→500→1400) during streaming produced ZERO scrollback delta, full agent response preserved, status bar pinned at bottom, no visible duplicates. pt is pinned to ==3.0.52 so the private-function patch is safe; future pt bumps will need to re-verify the signature matches. 2. Light-mode terminal visibility. Hardcoded skin colors (#FFF8DC cornsilk, #FFD700 gold, #B8860B dark goldenrod) are tuned for dark Terminal.app — invisible on light/cream backgrounds. Port ui-tui/src/theme.ts detectLightMode() to Python so the base CLI adapts. Detection priority: HERMES_LIGHT/HERMES_TUI_LIGHT env → HERMES_TUI_THEME=light|dark → HERMES_TUI_BACKGROUND=#RRGGBB → COLORFGBG env (xterm/Konsole/urxvt) → OSC 11 query (\x1b]11;?\x1b\\) with 100ms timeout → default dark. OSC 11 is tty-gated so gateway/cron/batch/subagent code paths don't pay the timeout cost. When light mode is detected, dark-mode colors auto-remap to readable equivalents (#FFF8DC → #1A1A1A, #FFD700 → #9A6B00, etc). Hooked at three points: - _hex_to_ansi() — auto-remaps any color emitted via the ANSI helper - _build_tui_style_dict() — rewrites pt style strings (chrome bg/fg) - SkinConfig.get_color() — wrapped at module load so Rich Panel borders/body text get the remap too Status-bar foreground colors (#C0C0C0, #888888, etc.) are explicitly skipped because they're paired with a dark navy bg — remapping them would make them invisible in dark mode. 3. Other visibility fixes: [thinking] reasoning preview now uses ANSI dim+italic (\x1b[2;3m) instead of #B8860B so it inherits terminal default fg color. Input/prompt area defaults to terminal default fg (was #FFF8DC cornsilk → invisible on cream). Co-authored-by: Brooklyn Nicholson <brooklyn.bb.nicholson@gmail.com>
This commit is contained in:
parent
bcca5ed34d
commit
f8745f59c2
2 changed files with 391 additions and 29 deletions
|
|
@ -849,10 +849,14 @@ def get_prompt_toolkit_style_overrides() -> Dict[str, str]:
|
|||
except Exception:
|
||||
return {}
|
||||
|
||||
prompt = skin.get_color("prompt", "#FFF8DC")
|
||||
# Input/prompt: leave unset by default so the typed text inherits
|
||||
# the terminal's foreground color (readable in both light and dark
|
||||
# color schemes). Skins can opt into a colored prompt by setting
|
||||
# `prompt` explicitly in their YAML.
|
||||
prompt = skin.get_color("prompt", "")
|
||||
input_rule = skin.get_color("input_rule", "#CD7F32")
|
||||
title = skin.get_color("banner_title", "#FFD700")
|
||||
text = skin.get_color("banner_text", prompt)
|
||||
text = skin.get_color("banner_text", "#FFF8DC")
|
||||
dim = skin.get_color("banner_dim", "#555555")
|
||||
label = skin.get_color("ui_label", title)
|
||||
warn = skin.get_color("ui_warn", "#FF8C00")
|
||||
|
|
@ -872,7 +876,11 @@ def get_prompt_toolkit_style_overrides() -> Dict[str, str]:
|
|||
menu_meta_current_bg = skin.get_color("completion_menu_meta_current_bg", menu_current_bg)
|
||||
|
||||
return {
|
||||
"input-area": prompt,
|
||||
# Typed input always uses terminal default fg/bg so it's
|
||||
# readable in both light and dark Terminal.app modes. The
|
||||
# skin's `prompt` color (if any) only styles the prompt symbol,
|
||||
# NOT the user's typed text.
|
||||
"input-area": "",
|
||||
"placeholder": f"{dim} italic",
|
||||
"prompt": prompt,
|
||||
"prompt-working": f"{dim} italic",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue