From 2fc2280e63964ad96419f1d532a308eb034d42db Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Fri, 29 May 2026 12:32:31 -0700 Subject: [PATCH] fix(cli): clarify panel clips choices off-screen on short terminals (#34808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(code-execution): document HERMES_* env narrowing + passthrough workaround The execute_code sandbox-child env scrub (108397726, #27303) deliberately dropped the broad HERMES_ prefix passthrough, keeping only an operational 4-var allowlist (HERMES_HOME/PROFILE/CONFIG/ENV). A script that relied on a non-secret HERMES_* var (HERMES_BASE_URL, HERMES_KANBAN_DB, HERMES_*_WEBHOOK, or a plugin-defined one) now sees it unset in the child. Document the behavior change and the two recovery routes (terminal.env_passthrough in config.yaml, or required_environment_variables in skill frontmatter), plus the debug log line that surfaces the drop for diagnosis. * fix(cli): clarify panel clips choices off-screen on short terminals The clarify multiple-choice panel is a height-less Window inside a non-full-screen HSplit. When its content exceeds the viewport, prompt_toolkit distributes height per child and clips the panel's tail — where the choices live — so options render invisible/cut off (issue #34645, reported on macOS Terminal.app). Two budget-accounting bugs let the panel overflow: - the compact-chrome decision ignored the question rows, so full chrome (3 blank separators) was kept even with no room - the '… (question truncated)' marker was not counted against the question's row budget, overshooting by one row at a 1-row budget Fix: reserve one question row in the compact decision, count the truncation marker against the budget, and drop the question entirely when the choices alone already exceed the viewport (choices are the must-see content for a selection). --- cli.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/cli.py b/cli.py index 84735ad3d80..c7832ab3794 100644 --- a/cli.py +++ b/cli.py @@ -13979,7 +13979,12 @@ class HermesCLI: reserved_below = 6 available = max(0, term_rows - reserved_below) - mandatory_full = chrome_full + len(choice_wrapped) + len(other_wrapped) + # The compact decision must reserve room for at least one question + # row on top of the choices, otherwise full chrome (3 blank + # separators) gets kept when there is no room for it and the panel + # overflows the viewport — HSplit then clips the panel's tail, + # silently dropping the choices (the reported bug). + mandatory_full = chrome_full + 1 + len(choice_wrapped) + len(other_wrapped) use_compact_chrome = mandatory_full > available chrome_rows = chrome_tight if use_compact_chrome else chrome_full @@ -13987,9 +13992,24 @@ class HermesCLI: max_question_rows = max(1, available - chrome_rows - len(choice_wrapped) - len(other_wrapped)) max_question_rows = min(max_question_rows, 12) # soft cap on huge terminals + # When the choices alone (plus compact chrome) already exceed the + # viewport, drop the question entirely — the choices are the only + # thing the user must see to make a selection. Without this the + # question would still claim its 1-row floor above and push the + # tail of the choices off-screen (HSplit clips the overflow). + choices_overflow = chrome_rows + len(choice_wrapped) + len(other_wrapped) >= available + if choices_overflow: + max_question_rows = 0 + question_wrapped = _wrap_panel_text(question, inner_text_width) - if len(question_wrapped) > max_question_rows: - keep = max(1, max_question_rows - 1) + if max_question_rows <= 0: + question_wrapped = [] + elif len(question_wrapped) > max_question_rows: + # The truncation marker is itself a row, so it must count + # against the budget. With a 1-row budget there is no room for + # both a question line and the marker — show the marker alone + # so the rendered question never exceeds max_question_rows. + keep = max(0, max_question_rows - 1) question_wrapped = question_wrapped[:keep] + ["… (question truncated)"] lines = []