diff --git a/features/steps/tui_materializer_steps.py b/features/steps/tui_materializer_steps.py index 6de8f8632..22336f4c5 100644 --- a/features/steps/tui_materializer_steps.py +++ b/features/steps/tui_materializer_steps.py @@ -130,11 +130,6 @@ def step_call_on_session_begin(context: Any) -> None: context.materializer.on_session_begin(None) # type: ignore[arg-type] -@then("no error should be raised") -def step_no_error_raised(context: Any) -> None: - pass # If we got here, no exception was raised - - # --------------------------------------------------------------------------- # OutputSession integration # --------------------------------------------------------------------------- @@ -157,21 +152,11 @@ def step_create_table_handle(context: Any, title: str) -> None: context.table_handle = context.session.table(title) -@when('I create a status handle with message "{message}"') -def step_create_status_handle(context: Any, message: str) -> None: - context.status_handle = context.session.status(message) - - @when('I create a progress handle with label "{label}"') def step_create_progress_handle(context: Any, label: str) -> None: context.progress_handle = context.session.progress(label, indeterminate=True) -@when('I create a code handle with content "{content}" and language "{language}"') -def step_create_code_handle(context: Any, content: str, language: str) -> None: - context.code_handle = context.session.code(content, language=language) - - @when("I create a separator handle") def step_create_separator_handle(context: Any) -> None: context.separator_handle = context.session.separator() @@ -182,16 +167,6 @@ def step_create_action_hint_handle(context: Any, command: str) -> None: context.action_hint_handle = context.session.action_hint([command]) -@when("I close the panel handle") -def step_close_panel_handle(context: Any) -> None: - context.panel_handle.close() - - -@when("I close the status handle") -def step_close_status_handle(context: Any) -> None: - context.status_handle.close() - - @when("I close the session") def step_close_session(context: Any) -> None: context.session.close() @@ -363,9 +338,7 @@ def step_render_tree_element(context: Any, root: str, child: str) -> None: context.rendered_text = render_element_for_tui(element) -@when( - 'I render a CodeBlock element with language "{language}" and content "{content}"' -) +@when('I render a CodeBlock element with language "{language}" and content "{content}"') def step_render_code_element(context: Any, language: str, content: str) -> None: from cleveragents.cli.output.handles._models import CodeBlock from cleveragents.tui.materializer import render_element_for_tui @@ -374,9 +347,7 @@ def step_render_code_element(context: Any, language: str, content: str) -> None: context.rendered_text = render_element_for_tui(element) -@when( - 'I render a DiffBlock element with file_a "{file_a}" and file_b "{file_b}"' -) +@when('I render a DiffBlock element with file_a "{file_a}" and file_b "{file_b}"') def step_render_diff_element(context: Any, file_a: str, file_b: str) -> None: from cleveragents.cli.output.handles._models import DiffBlock from cleveragents.tui.materializer import render_element_for_tui @@ -423,14 +394,14 @@ def step_render_text_element_with_indent( context.rendered_text = render_element_for_tui(element) -@then('the rendered text should contain "{text}"') +@then('the render output should contain "{text}"') def step_check_rendered_text_contains(context: Any, text: str) -> None: assert text in context.rendered_text, ( f"Expected {text!r} in rendered_text={context.rendered_text!r}" ) -@then("the rendered text should be empty") +@then("the render output should be empty") def step_check_rendered_text_empty(context: Any) -> None: assert context.rendered_text == "", ( f"Expected empty rendered_text, got: {context.rendered_text!r}" @@ -442,9 +413,7 @@ def step_check_rendered_text_empty(context: Any) -> None: # --------------------------------------------------------------------------- -@when( - 'I route a permission request for "{file_path}" with type "{request_type}"' -) +@when('I route a permission request for "{file_path}" with type "{request_type}"') def step_route_permission_request( context: Any, file_path: str, request_type: str ) -> None: @@ -537,9 +506,7 @@ def step_create_multiple_status_handles_concurrently(context: Any) -> None: @then("all events should be recorded without data corruption") def step_check_thread_safety(context: Any) -> None: - assert context.thread_errors == [], ( - f"Thread errors: {context.thread_errors}" - ) + assert context.thread_errors == [], f"Thread errors: {context.thread_errors}" events = context.materializer.events # We should have at least 10 element_created + 10 element_closed events created = [e for e in events if e.event_type == "element_created"] diff --git a/features/tui_materializer.feature b/features/tui_materializer.feature index fd32883cd..ade80e35c 100644 --- a/features/tui_materializer.feature +++ b/features/tui_materializer.feature @@ -31,7 +31,7 @@ Feature: TUI Materializer Scenario: TuiMaterializer implements on_session_begin When I create a TuiMaterializer without a callback And I call on_session_begin with a mock session - Then no error should be raised + Then the materializer should still be running Scenario: TuiMaterializer emits element_created event for panel When I create a TuiMaterializer without a callback @@ -141,72 +141,72 @@ Feature: TUI Materializer Scenario: render_element_for_tui renders Panel with title and entries When I render a Panel element with title "Info" and entry "key" "value" - Then the rendered text should contain "Info" - And the rendered text should contain "key" - And the rendered text should contain "value" + Then the render output should contain "Info" + And the render output should contain "key" + And the render output should contain "value" Scenario: render_element_for_tui renders Table with columns and rows When I render a Table element with title "Data" and column "Name" - Then the rendered text should contain "Data" - And the rendered text should contain "Name" + Then the render output should contain "Data" + And the render output should contain "Name" Scenario: render_element_for_tui renders StatusMessage ok level When I render a StatusMessage element with level "ok" and message "Success" - Then the rendered text should contain "ok" - And the rendered text should contain "Success" + Then the render output should contain "ok" + And the render output should contain "Success" Scenario: render_element_for_tui renders StatusMessage error level When I render a StatusMessage element with level "error" and message "Failed" - Then the rendered text should contain "error" - And the rendered text should contain "Failed" + Then the render output should contain "error" + And the render output should contain "Failed" Scenario: render_element_for_tui renders indeterminate ProgressIndicator When I render an indeterminate ProgressIndicator with label "Thinking" - Then the rendered text should contain "Thinking" + Then the render output should contain "Thinking" Scenario: render_element_for_tui renders determinate ProgressIndicator When I render a determinate ProgressIndicator with label "Loading" current 5 total 10 - Then the rendered text should contain "Loading" - And the rendered text should contain "50%" + Then the render output should contain "Loading" + And the render output should contain "50%" Scenario: render_element_for_tui renders Tree with root and children When I render a Tree element with root "root" and child "child1" - Then the rendered text should contain "root" - And the rendered text should contain "child1" + Then the render output should contain "root" + And the render output should contain "child1" Scenario: render_element_for_tui renders CodeBlock with language When I render a CodeBlock element with language "python" and content "x = 1" - Then the rendered text should contain "python" - And the rendered text should contain "x = 1" + Then the render output should contain "python" + And the render output should contain "x = 1" Scenario: render_element_for_tui renders DiffBlock with hunks When I render a DiffBlock element with file_a "old.py" and file_b "new.py" - Then the rendered text should contain "old.py" - And the rendered text should contain "new.py" + Then the render output should contain "old.py" + And the render output should contain "new.py" Scenario: render_element_for_tui renders Separator line style When I render a Separator element with style "line" - Then the rendered text should contain "-" + Then the render output should contain "-" Scenario: render_element_for_tui renders Separator blank style When I render a Separator element with style "blank" - Then the rendered text should be empty + Then the render output should be empty Scenario: render_element_for_tui renders Separator double style When I render a Separator element with style "double" - Then the rendered text should contain "=" + Then the render output should contain "=" Scenario: render_element_for_tui renders ActionHint with commands When I render an ActionHint element with command "agents plan list" - Then the rendered text should contain "agents plan list" + Then the render output should contain "agents plan list" Scenario: render_element_for_tui renders TextBlock content When I render a TextBlock element with content "Hello world" - Then the rendered text should contain "Hello world" + Then the render output should contain "Hello world" Scenario: render_element_for_tui renders TextBlock with indent When I render a TextBlock element with content "indented" and indent 4 - Then the rendered text should contain " indented" + Then the render output should contain " indented" # ── A2A event routing ───────────────────────────────────────────────────── diff --git a/src/cleveragents/tui/materializer.py b/src/cleveragents/tui/materializer.py index 674bf58f7..6a51c157a 100644 --- a/src/cleveragents/tui/materializer.py +++ b/src/cleveragents/tui/materializer.py @@ -139,11 +139,7 @@ class TuiMaterializer: Useful for testing and headless inspection. """ with self._lock: - parts = [ - text - for _, text in sorted(self._rendered.items()) - if text - ] + parts = [text for _, text in sorted(self._rendered.items()) if text] return "\n\n".join(parts) # ------------------------------------------------------------------ @@ -269,9 +265,7 @@ class TuiMaterializer: self._emit(tui_event) return tui_event - def route_thought_block( - self, thought: ThoughtBlock - ) -> TuiWidgetEvent: + def route_thought_block(self, thought: ThoughtBlock) -> TuiWidgetEvent: """Route a thought block event to the TUI. Creates a ``TuiWidgetEvent`` with ``event_type="thought_block"`` diff --git a/vulture_whitelist.py b/vulture_whitelist.py index edcbffd7b..04b29c54b 100644 --- a/vulture_whitelist.py +++ b/vulture_whitelist.py @@ -301,7 +301,7 @@ _snapshot_to_dict # noqa: B018, F821 _create_strategy # noqa: B018, F821 VALID_FORMATS # noqa: B018, F821 -# TUI materializer — bridges Output Rendering Framework to Textual widgets +# TUI materializer — bridges Output Rendering Framework to Textual widgets TuiMaterializer # noqa: B018, F821 TuiWidgetEvent # noqa: B018, F821 TuiWidgetEventType # noqa: B018, F821