From f86553670b1a8145a039bf6dcf3502fc7929acdf Mon Sep 17 00:00:00 2001 From: CleverThis Date: Sat, 6 Jun 2026 11:13:48 -0400 Subject: [PATCH] fix(tui): use correct DiffDisplayMode enum members + typed compose() result The diff-mode cycle in PermissionsScreen referenced DiffDisplayMode.SIDE_BY_SIDE and DiffDisplayMode.CONTEXT, but the enum only defines UNIFIED / SPLIT / AUTO. Pyright flagged both as reportAttributeAccessIssue and behave failed to import the screen module, masking the entire scenario suite under a single traceback-outside-scenario error. Also addresses the prior re-review feedback on the same PR: - compose() return type was Any; tighten to collections.abc.Iterator[Any] so the generator shape is exposed to type checkers without taking a hard textual dependency at typecheck time (Iterator[Any] is the structural type of a Textual ComposeResult; we stay importable when textual is absent). - The Bug #10488 TDD scenario asserting action methods now also covers action_dismiss_screen so a future refactor cannot silently drop the escape binding without test failure. Verified locally on this worktree: - typecheck gate: 0 errors, 4 unrelated warnings. - unit_tests gate on features/tui_permissions_screen.feature: 65/65 scenarios pass. - lint gate: clean. ISSUES CLOSED: #10488 --- features/tui_permissions_screen.feature | 1 + src/cleveragents/tui/permissions/screen.py | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/features/tui_permissions_screen.feature b/features/tui_permissions_screen.feature index 26a6f8ad1..902db9e65 100644 --- a/features/tui_permissions_screen.feature +++ b/features/tui_permissions_screen.feature @@ -396,3 +396,4 @@ Feature: TUI PermissionsScreen And PermissionsScreen should have action method "action_nav_next" And PermissionsScreen should have action method "action_nav_prev" And PermissionsScreen should have action method "action_cycle_diff" + And PermissionsScreen should have action method "action_dismiss_screen" diff --git a/src/cleveragents/tui/permissions/screen.py b/src/cleveragents/tui/permissions/screen.py index a303f6500..039444b09 100644 --- a/src/cleveragents/tui/permissions/screen.py +++ b/src/cleveragents/tui/permissions/screen.py @@ -10,6 +10,7 @@ from __future__ import annotations import contextlib import importlib +from collections.abc import Iterator from typing import Any, ClassVar from cleveragents.tui.permissions.models import ( @@ -45,8 +46,8 @@ _ScreenBase = _load_screen_base() _DIFF_MODE_CYCLE: list[DiffDisplayMode] = [ DiffDisplayMode.UNIFIED, - DiffDisplayMode.SIDE_BY_SIDE, - DiffDisplayMode.CONTEXT, + DiffDisplayMode.SPLIT, + DiffDisplayMode.AUTO, ] @@ -167,8 +168,14 @@ class PermissionsScreen(_ScreenBase): """ self._text = text - def compose(self) -> Any: - """Compose the screen layout with a Static widget showing the content.""" + def compose(self) -> Iterator[Any]: + """Compose the screen layout with a Static widget showing the content. + + Returns a generator over Textual ``Widget`` instances (the + ``ComposeResult`` type), but typed as ``Iterator[Any]`` here so + the module stays importable in environments where ``textual`` is + not installed (typecheck gate, pure-domain tests). + """ with contextlib.suppress(Exception): # pragma: no cover Static = importlib.import_module("textual.widgets").Static yield Static(self._text, id="permissions-content")