From 0799369407a56f5c4ebbc301cbdaa3a704044668 Mon Sep 17 00:00:00 2001 From: HAL9000 Date: Sun, 19 Apr 2026 02:44:05 +0000 Subject: [PATCH 1/2] fix(tui): render inline diffs in PermissionQuestionWidget Enabled inline diff rendering by default in PermissionQuestionWidget when diffs are available. Added a public show_diff property with getter and setter to control diff visibility, and updated refresh to honor this property. Extended Behave feature scenarios to cover default diff rendering, visibility toggling, and no-diff behavior. Introduced supporting step definitions for toggling show_diff and asserting absence of diff text. ISSUES CLOSED: #8303 --- .../tui_permission_question_widget_steps.py | 23 +++++++++++++++++ .../tui_permission_question_widget.feature | 25 +++++++++++++++++++ .../tui/widgets/permission_question.py | 25 ++++++++++++++++--- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/features/steps/tui_permission_question_widget_steps.py b/features/steps/tui_permission_question_widget_steps.py index 3515df163..876843651 100644 --- a/features/steps/tui_permission_question_widget_steps.py +++ b/features/steps/tui_permission_question_widget_steps.py @@ -141,6 +141,29 @@ def step_widget_text_contains(context: object, substring: str) -> None: assert substring in text, f"Expected '{substring}' in widget text:\n{text}" +@then('the widget text should not contain "{substring}"') +def step_widget_text_not_contains(context: object, substring: str) -> None: + text = context.widget._text # type: ignore[attr-defined] + assert substring not in text, ( + f"Did not expect '{substring}' in widget text:\n{text}" + ) + + +@when("I set the widget show_diff flag to {raw_value}") +def step_set_widget_show_diff(context: object, raw_value: str) -> None: + desired = raw_value.strip().lower() == "true" + context.widget.show_diff = desired # type: ignore[attr-defined] + + +@then("the widget show_diff property should be {expected}") +def step_check_widget_show_diff(context: object, expected: str) -> None: + expected_bool = expected.strip().lower() == "true" + actual = context.widget.show_diff # type: ignore[attr-defined] + assert actual is expected_bool, ( + f"Expected show_diff={expected_bool}, got {actual}" + ) + + # --------------------------------------------------------------------------- # Key press steps # --------------------------------------------------------------------------- diff --git a/features/tui_permission_question_widget.feature b/features/tui_permission_question_widget.feature index 764231519..820ebfcaf 100644 --- a/features/tui_permission_question_widget.feature +++ b/features/tui_permission_question_widget.feature @@ -47,6 +47,31 @@ Feature: Permission Question Widget Given a PermissionQuestionWidget for "src/main.py" with type "file_write" and diff "@@ -1 +1 @@\n+x=1" Then the widget text should contain "PermissionsScreen" + Scenario: Widget creation with diff content renders diff by default + Given a PermissionQuestionWidget for "src/main.py" with type "file_write" and diff "@@ -1 +1 @@\n+x=1" + Then the widget text should contain "── diff ──" + And the widget text should contain "+x=1" + And the widget show_diff property should be True + + Scenario: Widget diff visibility can be toggled off + Given a PermissionQuestionWidget for "src/main.py" with type "file_write" and diff "@@ -1 +1 @@\n+x=1" + When I set the widget show_diff flag to False + Then the widget text should not contain "── diff ──" + And the widget show_diff property should be False + + Scenario: Widget diff visibility can be toggled on after hiding + Given a PermissionQuestionWidget for "src/main.py" with type "file_write" and diff "@@ -1 +1 @@\n+x=1" + When I set the widget show_diff flag to False + And I set the widget show_diff flag to True + Then the widget text should contain "── diff ──" + And the widget show_diff property should be True + + Scenario: Widget show_diff property stays False without diff content + When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write" + Then the widget show_diff property should be False + When I set the widget show_diff flag to True + Then the widget show_diff property should be False + # ── Allow action ────────────────────────────────────────────────────────── Scenario: Allow once via key "a" diff --git a/src/cleveragents/tui/widgets/permission_question.py b/src/cleveragents/tui/widgets/permission_question.py index 825329ece..9b8dd7ea0 100644 --- a/src/cleveragents/tui/widgets/permission_question.py +++ b/src/cleveragents/tui/widgets/permission_question.py @@ -163,10 +163,14 @@ class PermissionQuestionWidget(_StaticBase): super().__init__(*args, **kwargs) self._question = question self._selected_index: int = 0 - self._show_diff: bool = False + self._show_diff: bool = question.has_diff self._decision: PermissionDecision | None = None self._open_full_screen: bool = False - self._text = render_permission_question(question, self._selected_index) + self._text = render_permission_question( + question, + self._selected_index, + show_diff=self._show_diff, + ) self.update(self._text) # ── Public properties ───────────────────────────────────────── @@ -191,6 +195,21 @@ class PermissionQuestionWidget(_StaticBase): """Return True if the user requested the full PermissionsScreen.""" return self._open_full_screen + @property + def show_diff(self) -> bool: + """Return True when the diff content is currently visible.""" + if not self._question.has_diff: + return False + return self._show_diff + + @show_diff.setter + def show_diff(self, value: bool) -> None: + normalized_value = bool(value) and self._question.has_diff + if normalized_value == self._show_diff: + return + self._show_diff = normalized_value + self._refresh() + # ── Navigation ──────────────────────────────────────────────── def move_up(self) -> None: @@ -245,6 +264,6 @@ class PermissionQuestionWidget(_StaticBase): self._text = render_permission_question( self._question, self._selected_index, - show_diff=self._show_diff, + show_diff=self.show_diff, ) self.update(self._text) -- 2.52.0 From 96ca3ecffa1ba8aefea9cf115694257aec4f5419 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Sun, 19 Apr 2026 11:46:13 +0000 Subject: [PATCH 2/2] style: fix ruff formatting in tui_permission_question_widget_steps.py Collapse unnecessary parentheses in assert statement to satisfy ruff format check. No functional changes. --- features/steps/tui_permission_question_widget_steps.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/features/steps/tui_permission_question_widget_steps.py b/features/steps/tui_permission_question_widget_steps.py index 876843651..54e00b08c 100644 --- a/features/steps/tui_permission_question_widget_steps.py +++ b/features/steps/tui_permission_question_widget_steps.py @@ -159,9 +159,7 @@ def step_set_widget_show_diff(context: object, raw_value: str) -> None: def step_check_widget_show_diff(context: object, expected: str) -> None: expected_bool = expected.strip().lower() == "true" actual = context.widget.show_diff # type: ignore[attr-defined] - assert actual is expected_bool, ( - f"Expected show_diff={expected_bool}, got {actual}" - ) + assert actual is expected_bool, f"Expected show_diff={expected_bool}, got {actual}" # --------------------------------------------------------------------------- -- 2.52.0