fix(tui): resolve lint and AmbiguousStep errors in TuiMaterializer
CI / load-versions (push) Successful in 16s
CI / push-validation (push) Successful in 28s
CI / build (push) Successful in 33s
CI / lint (push) Successful in 50s
CI / typecheck (push) Successful in 1m0s
CI / quality (push) Successful in 1m8s
CI / security (push) Successful in 1m17s
CI / helm (push) Successful in 39s
CI / unit_tests (push) Successful in 6m53s
CI / docker (push) Successful in 1m55s
CI / integration_tests (push) Successful in 10m43s
CI / coverage (push) Successful in 13m43s
CI / status-check (push) Successful in 3s
CI / load-versions (pull_request) Successful in 13s
CI / push-validation (pull_request) Successful in 34s
CI / lint (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 54s
CI / typecheck (pull_request) Successful in 59s
CI / security (pull_request) Successful in 1m12s
CI / build (pull_request) Successful in 51s
CI / helm (pull_request) Successful in 58s
CI / unit_tests (pull_request) Successful in 6m37s
CI / integration_tests (pull_request) Successful in 10m35s
CI / benchmark-publish (push) Has been cancelled
CI / benchmark-regression (push) Has been cancelled
CI / docker (pull_request) Failing after 13m18s
CI / coverage (pull_request) Failing after 28m20s
CI / status-check (pull_request) Has been cancelled
CI / load-versions (push) Successful in 16s
CI / push-validation (push) Successful in 28s
CI / build (push) Successful in 33s
CI / lint (push) Successful in 50s
CI / typecheck (push) Successful in 1m0s
CI / quality (push) Successful in 1m8s
CI / security (push) Successful in 1m17s
CI / helm (push) Successful in 39s
CI / unit_tests (push) Successful in 6m53s
CI / docker (push) Successful in 1m55s
CI / integration_tests (push) Successful in 10m43s
CI / coverage (push) Successful in 13m43s
CI / status-check (push) Successful in 3s
CI / load-versions (pull_request) Successful in 13s
CI / push-validation (pull_request) Successful in 34s
CI / lint (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 54s
CI / typecheck (pull_request) Successful in 59s
CI / security (pull_request) Successful in 1m12s
CI / build (pull_request) Successful in 51s
CI / helm (pull_request) Successful in 58s
CI / unit_tests (pull_request) Successful in 6m37s
CI / integration_tests (pull_request) Successful in 10m35s
CI / benchmark-publish (push) Has been cancelled
CI / benchmark-regression (push) Has been cancelled
CI / docker (pull_request) Failing after 13m18s
CI / coverage (pull_request) Failing after 28m20s
CI / status-check (pull_request) Has been cancelled
- Fix ruff format violations: collapse list comprehension in materializer.py, collapse function signature, collapse decorators and assertion in tui_materializer_steps.py, remove trailing whitespace in vulture_whitelist.py - Remove duplicate Behave step definitions from tui_materializer_steps.py that conflicted with output_rendering_steps.py and project_commands_coverage_steps.py: create status handle, create code handle, close panel handle, close status handle, no error should be raised - Rename render_element_for_tui step texts to avoid conflict with tui_first_run_steps.py: rendered text should contain/be empty -> render output should contain/be empty - Update tui_materializer.feature to use renamed step texts and replace no error should be raised with materializer still running ISSUES CLOSED: #11164
This commit was merged in pull request #11164.
This commit is contained in:
@@ -130,11 +130,6 @@ def step_call_on_session_begin(context: Any) -> None:
|
|||||||
context.materializer.on_session_begin(None) # type: ignore[arg-type]
|
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
|
# OutputSession integration
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -157,21 +152,11 @@ def step_create_table_handle(context: Any, title: str) -> None:
|
|||||||
context.table_handle = context.session.table(title)
|
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}"')
|
@when('I create a progress handle with label "{label}"')
|
||||||
def step_create_progress_handle(context: Any, label: str) -> None:
|
def step_create_progress_handle(context: Any, label: str) -> None:
|
||||||
context.progress_handle = context.session.progress(label, indeterminate=True)
|
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")
|
@when("I create a separator handle")
|
||||||
def step_create_separator_handle(context: Any) -> None:
|
def step_create_separator_handle(context: Any) -> None:
|
||||||
context.separator_handle = context.session.separator()
|
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])
|
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")
|
@when("I close the session")
|
||||||
def step_close_session(context: Any) -> None:
|
def step_close_session(context: Any) -> None:
|
||||||
context.session.close()
|
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)
|
context.rendered_text = render_element_for_tui(element)
|
||||||
|
|
||||||
|
|
||||||
@when(
|
@when('I render a CodeBlock element with language "{language}" and content "{content}"')
|
||||||
'I render a CodeBlock element with language "{language}" and content "{content}"'
|
|
||||||
)
|
|
||||||
def step_render_code_element(context: Any, language: str, content: str) -> None:
|
def step_render_code_element(context: Any, language: str, content: str) -> None:
|
||||||
from cleveragents.cli.output.handles._models import CodeBlock
|
from cleveragents.cli.output.handles._models import CodeBlock
|
||||||
from cleveragents.tui.materializer import render_element_for_tui
|
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)
|
context.rendered_text = render_element_for_tui(element)
|
||||||
|
|
||||||
|
|
||||||
@when(
|
@when('I render a DiffBlock element with file_a "{file_a}" and file_b "{file_b}"')
|
||||||
'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:
|
def step_render_diff_element(context: Any, file_a: str, file_b: str) -> None:
|
||||||
from cleveragents.cli.output.handles._models import DiffBlock
|
from cleveragents.cli.output.handles._models import DiffBlock
|
||||||
from cleveragents.tui.materializer import render_element_for_tui
|
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)
|
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:
|
def step_check_rendered_text_contains(context: Any, text: str) -> None:
|
||||||
assert text in context.rendered_text, (
|
assert text in context.rendered_text, (
|
||||||
f"Expected {text!r} in rendered_text={context.rendered_text!r}"
|
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:
|
def step_check_rendered_text_empty(context: Any) -> None:
|
||||||
assert context.rendered_text == "", (
|
assert context.rendered_text == "", (
|
||||||
f"Expected empty rendered_text, got: {context.rendered_text!r}"
|
f"Expected empty rendered_text, got: {context.rendered_text!r}"
|
||||||
@@ -442,9 +413,7 @@ def step_check_rendered_text_empty(context: Any) -> None:
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@when(
|
@when('I route a permission request for "{file_path}" with type "{request_type}"')
|
||||||
'I route a permission request for "{file_path}" with type "{request_type}"'
|
|
||||||
)
|
|
||||||
def step_route_permission_request(
|
def step_route_permission_request(
|
||||||
context: Any, file_path: str, request_type: str
|
context: Any, file_path: str, request_type: str
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -537,9 +506,7 @@ def step_create_multiple_status_handles_concurrently(context: Any) -> None:
|
|||||||
|
|
||||||
@then("all events should be recorded without data corruption")
|
@then("all events should be recorded without data corruption")
|
||||||
def step_check_thread_safety(context: Any) -> None:
|
def step_check_thread_safety(context: Any) -> None:
|
||||||
assert context.thread_errors == [], (
|
assert context.thread_errors == [], f"Thread errors: {context.thread_errors}"
|
||||||
f"Thread errors: {context.thread_errors}"
|
|
||||||
)
|
|
||||||
events = context.materializer.events
|
events = context.materializer.events
|
||||||
# We should have at least 10 element_created + 10 element_closed 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"]
|
created = [e for e in events if e.event_type == "element_created"]
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Feature: TUI Materializer
|
|||||||
Scenario: TuiMaterializer implements on_session_begin
|
Scenario: TuiMaterializer implements on_session_begin
|
||||||
When I create a TuiMaterializer without a callback
|
When I create a TuiMaterializer without a callback
|
||||||
And I call on_session_begin with a mock session
|
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
|
Scenario: TuiMaterializer emits element_created event for panel
|
||||||
When I create a TuiMaterializer without a callback
|
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
|
Scenario: render_element_for_tui renders Panel with title and entries
|
||||||
When I render a Panel element with title "Info" and entry "key" "value"
|
When I render a Panel element with title "Info" and entry "key" "value"
|
||||||
Then the rendered text should contain "Info"
|
Then the render output should contain "Info"
|
||||||
And the rendered text should contain "key"
|
And the render output should contain "key"
|
||||||
And the rendered text should contain "value"
|
And the render output should contain "value"
|
||||||
|
|
||||||
Scenario: render_element_for_tui renders Table with columns and rows
|
Scenario: render_element_for_tui renders Table with columns and rows
|
||||||
When I render a Table element with title "Data" and column "Name"
|
When I render a Table element with title "Data" and column "Name"
|
||||||
Then the rendered text should contain "Data"
|
Then the render output should contain "Data"
|
||||||
And the rendered text should contain "Name"
|
And the render output should contain "Name"
|
||||||
|
|
||||||
Scenario: render_element_for_tui renders StatusMessage ok level
|
Scenario: render_element_for_tui renders StatusMessage ok level
|
||||||
When I render a StatusMessage element with level "ok" and message "Success"
|
When I render a StatusMessage element with level "ok" and message "Success"
|
||||||
Then the rendered text should contain "ok"
|
Then the render output should contain "ok"
|
||||||
And the rendered text should contain "Success"
|
And the render output should contain "Success"
|
||||||
|
|
||||||
Scenario: render_element_for_tui renders StatusMessage error level
|
Scenario: render_element_for_tui renders StatusMessage error level
|
||||||
When I render a StatusMessage element with level "error" and message "Failed"
|
When I render a StatusMessage element with level "error" and message "Failed"
|
||||||
Then the rendered text should contain "error"
|
Then the render output should contain "error"
|
||||||
And the rendered text should contain "Failed"
|
And the render output should contain "Failed"
|
||||||
|
|
||||||
Scenario: render_element_for_tui renders indeterminate ProgressIndicator
|
Scenario: render_element_for_tui renders indeterminate ProgressIndicator
|
||||||
When I render an indeterminate ProgressIndicator with label "Thinking"
|
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
|
Scenario: render_element_for_tui renders determinate ProgressIndicator
|
||||||
When I render a determinate ProgressIndicator with label "Loading" current 5 total 10
|
When I render a determinate ProgressIndicator with label "Loading" current 5 total 10
|
||||||
Then the rendered text should contain "Loading"
|
Then the render output should contain "Loading"
|
||||||
And the rendered text should contain "50%"
|
And the render output should contain "50%"
|
||||||
|
|
||||||
Scenario: render_element_for_tui renders Tree with root and children
|
Scenario: render_element_for_tui renders Tree with root and children
|
||||||
When I render a Tree element with root "root" and child "child1"
|
When I render a Tree element with root "root" and child "child1"
|
||||||
Then the rendered text should contain "root"
|
Then the render output should contain "root"
|
||||||
And the rendered text should contain "child1"
|
And the render output should contain "child1"
|
||||||
|
|
||||||
Scenario: render_element_for_tui renders CodeBlock with language
|
Scenario: render_element_for_tui renders CodeBlock with language
|
||||||
When I render a CodeBlock element with language "python" and content "x = 1"
|
When I render a CodeBlock element with language "python" and content "x = 1"
|
||||||
Then the rendered text should contain "python"
|
Then the render output should contain "python"
|
||||||
And the rendered text should contain "x = 1"
|
And the render output should contain "x = 1"
|
||||||
|
|
||||||
Scenario: render_element_for_tui renders DiffBlock with hunks
|
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"
|
When I render a DiffBlock element with file_a "old.py" and file_b "new.py"
|
||||||
Then the rendered text should contain "old.py"
|
Then the render output should contain "old.py"
|
||||||
And the rendered text should contain "new.py"
|
And the render output should contain "new.py"
|
||||||
|
|
||||||
Scenario: render_element_for_tui renders Separator line style
|
Scenario: render_element_for_tui renders Separator line style
|
||||||
When I render a Separator element with style "line"
|
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
|
Scenario: render_element_for_tui renders Separator blank style
|
||||||
When I render a Separator element with style "blank"
|
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
|
Scenario: render_element_for_tui renders Separator double style
|
||||||
When I render a Separator element with style "double"
|
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
|
Scenario: render_element_for_tui renders ActionHint with commands
|
||||||
When I render an ActionHint element with command "agents plan list"
|
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
|
Scenario: render_element_for_tui renders TextBlock content
|
||||||
When I render a TextBlock element with content "Hello world"
|
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
|
Scenario: render_element_for_tui renders TextBlock with indent
|
||||||
When I render a TextBlock element with content "indented" and indent 4
|
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 ─────────────────────────────────────────────────────
|
# ── A2A event routing ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -139,11 +139,7 @@ class TuiMaterializer:
|
|||||||
Useful for testing and headless inspection.
|
Useful for testing and headless inspection.
|
||||||
"""
|
"""
|
||||||
with self._lock:
|
with self._lock:
|
||||||
parts = [
|
parts = [text for _, text in sorted(self._rendered.items()) if text]
|
||||||
text
|
|
||||||
for _, text in sorted(self._rendered.items())
|
|
||||||
if text
|
|
||||||
]
|
|
||||||
return "\n\n".join(parts)
|
return "\n\n".join(parts)
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
@@ -269,9 +265,7 @@ class TuiMaterializer:
|
|||||||
self._emit(tui_event)
|
self._emit(tui_event)
|
||||||
return tui_event
|
return tui_event
|
||||||
|
|
||||||
def route_thought_block(
|
def route_thought_block(self, thought: ThoughtBlock) -> TuiWidgetEvent:
|
||||||
self, thought: ThoughtBlock
|
|
||||||
) -> TuiWidgetEvent:
|
|
||||||
"""Route a thought block event to the TUI.
|
"""Route a thought block event to the TUI.
|
||||||
|
|
||||||
Creates a ``TuiWidgetEvent`` with ``event_type="thought_block"``
|
Creates a ``TuiWidgetEvent`` with ``event_type="thought_block"``
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ _snapshot_to_dict # noqa: B018, F821
|
|||||||
_create_strategy # noqa: B018, F821
|
_create_strategy # noqa: B018, F821
|
||||||
VALID_FORMATS # 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
|
TuiMaterializer # noqa: B018, F821
|
||||||
TuiWidgetEvent # noqa: B018, F821
|
TuiWidgetEvent # noqa: B018, F821
|
||||||
TuiWidgetEventType # noqa: B018, F821
|
TuiWidgetEventType # noqa: B018, F821
|
||||||
|
|||||||
Reference in New Issue
Block a user