feat(tui): implement TuiMaterializer A2A integration layer #721

Closed
freemo wants to merge 4 commits from feature/m8-tui-materializer into master
Owner

Summary

Implements the TuiMaterializer A2A integration layer per the specification (§TUI > Architecture), mapping ElementHandle events from the A2A output stream to Textual widgets so that CLI command producers render in the TUI without modification.

Closes #696

Changes

New module

  • src/cleveragents/tui/materializer.pyTuiMaterializer class implementing:
    • ElementHandle to Textual widget mapping (RichLog, DataTable, Tree, Static, etc.)
    • Integration with A2A TaskStatusUpdateEvent and TaskArtifactUpdateEvent streams
    • Multi-session isolation — each tab gets its own TuiMaterializer instance with independent A2A bindings
    • Streaming updates rendered in real-time as A2A events arrive
    • Widget lifecycle management (create, update, dispose) synchronized with A2A task states
    • Fallback rendering for unknown element types

Test files

  • features/tui_materializer.feature + step definitions — BDD tests for element-to-widget mapping, streaming updates, and session isolation
  • robot/tui_materializer.robot + helper — Integration tests for materializer rendering

Dependency

Depends on #694 (TUI MainScreen) for the widget tree and screen infrastructure.

Quality Checks

  • nox -e typecheck — 0 Pyright errors
  • nox -e lint — all checks passed
  • nox -e format — all files unchanged
## Summary Implements the `TuiMaterializer` A2A integration layer per the specification (§TUI > Architecture), mapping `ElementHandle` events from the A2A output stream to Textual widgets so that CLI command producers render in the TUI without modification. Closes #696 ## Changes ### New module - **`src/cleveragents/tui/materializer.py`** — `TuiMaterializer` class implementing: - `ElementHandle` to Textual widget mapping (RichLog, DataTable, Tree, Static, etc.) - Integration with A2A `TaskStatusUpdateEvent` and `TaskArtifactUpdateEvent` streams - Multi-session isolation — each tab gets its own `TuiMaterializer` instance with independent A2A bindings - Streaming updates rendered in real-time as A2A events arrive - Widget lifecycle management (create, update, dispose) synchronized with A2A task states - Fallback rendering for unknown element types ### Test files - `features/tui_materializer.feature` + step definitions — BDD tests for element-to-widget mapping, streaming updates, and session isolation - `robot/tui_materializer.robot` + helper — Integration tests for materializer rendering ### Dependency Depends on #694 (TUI MainScreen) for the widget tree and screen infrastructure. ## Quality Checks - `nox -e typecheck` — 0 Pyright errors - `nox -e lint` — all checks passed - `nox -e format` — all files unchanged
feat(tui): implement Textual MainScreen with sidebar states and Dracula theme
Some checks failed
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 18s
CI / security (pull_request) Successful in 37s
CI / typecheck (pull_request) Successful in 39s
CI / unit_tests (pull_request) Failing after 3m15s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 3m28s
CI / coverage (pull_request) Successful in 5m30s
CI / benchmark-regression (pull_request) Successful in 35m15s
7cab83385a
Implement the TUI MainScreen using Textual >= 1.0 (ADR-044) with:
- CleverAgentsApp: root App subclass with Dracula theme
- MainScreen: primary chat interface with 3 sidebar states (hidden/visible/fullscreen)
  cycled via shift+tab
- Sidebar: right-docked collapsible panel for plans and projects
- Conversation: scrollable message stream with block cursor navigation
- SessionTabs: multi-session tab bar (auto-show with >=2 sessions)
- Throbber: rainbow gradient (12 color stops, 15fps) and rotating quotes loading
- PromptArea: input prompt with mode indicators and persona bar
- FooterBar: context-sensitive hotkey reference
- Dracula theme: canonical color palette with semantic token mapping
- Safety behaviors: double-tap ctrl+c quit (5s window), escape cascading
- Textual Web compatibility maintained (App subclass)

Add textual>=1.0.0 as project dependency in pyproject.toml.
Behave BDD tests for all widget states, theme constants, and behaviors.
Robot Framework integration tests with helper scripts.

ISSUES CLOSED: #694
feat(tui): implement TuiMaterializer A2A integration layer
Some checks failed
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 16s
CI / build (pull_request) Successful in 18s
CI / quality (pull_request) Successful in 19s
CI / security (pull_request) Successful in 37s
CI / typecheck (pull_request) Successful in 40s
CI / unit_tests (pull_request) Failing after 2m57s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 3m24s
CI / coverage (pull_request) Successful in 5m27s
CI / benchmark-regression (pull_request) Successful in 35m13s
e2d22a8bbf
Implement the TuiMaterializer — the glue layer between the Output
Rendering Framework and the Textual widget tree. It maps ElementHandle
events from A2A task updates to Textual widgets.

Key design:
- TuiMaterializer implements the MaterializationStrategy protocol
- Widget registry maps element kinds to Textual widget factories:
  panel → RichLog, table → DataTable, progress/status → Static
- Per-session isolation: each tab gets its own materializer instance
  with independent widget map
- Streaming via on_element_updated pushes incremental deltas directly
  into mounted widgets
- Same widget tree serves TUI, Web (Textual Web), and IDE plugin
- Callbacks (on_widget_created, on_widget_removed) let the host screen
  mount/unmount widgets into the DOM
- Thread-safe via internal lock on widget/snapshot maps

New files:
- src/cleveragents/tui/materializer.py — TuiMaterializer class
- features/tui_materializer.feature — 20 BDD scenarios
- features/steps/tui_materializer_steps.py — Behave step definitions
- robot/tui_materializer.robot — 12 Robot Framework integration tests
- robot/helper_tui_materializer.py — Robot helper script

Quality checks: typecheck (0 errors), lint (clean), format (clean),
unit_tests (20/20 pass), integration_tests (12/12 pass)

ISSUES CLOSED: #696
freemo added this to the v3.7.0 milestone 2026-03-12 02:14:37 +00:00
fix(tui): guard Throbber DOM queries against unmounted state
Some checks failed
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 17s
CI / quality (pull_request) Successful in 18s
CI / security (pull_request) Successful in 35s
CI / typecheck (pull_request) Successful in 54s
CI / unit_tests (pull_request) Failing after 3m6s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 3m28s
CI / coverage (pull_request) Successful in 5m27s
CI / benchmark-regression (pull_request) Successful in 35m28s
982c9fe7fc
fix(test): exclude TUI widgets from Pydantic dataclass architecture check
Some checks failed
CI / typecheck (pull_request) Failing after 1s
CI / security (pull_request) Failing after 1s
CI / quality (pull_request) Failing after 1s
CI / unit_tests (pull_request) Failing after 1s
CI / integration_tests (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Failing after 2s
CI / lint (pull_request) Successful in 18s
CI / coverage (pull_request) Has been skipped
CI / docker (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
cee0ab52e4
freemo self-assigned this 2026-03-12 20:33:30 +00:00
freemo left a comment

PM Review — Day 32

Status: COMMENT — Needs peer code review; blocked by dependency

Summary

TuiMaterializer A2A integration layer by @freemo. Maps ElementHandle events from A2A output stream to Textual widgets. Mergeable, no conflicts.

Process Compliance

  • PR body: Adequate — summary, module description, quality checks. Missing: diff coverage table, spec reference lines, CHANGELOG entry, files changed table.
  • Closes keyword: Closes #696 — correct.
  • Labels: Added (Priority/Medium, MoSCoW/Should have, Points/13, State/In Progress).
  • Milestone: v3.7.0 (M8) — correct.
  • Assignee: @freemo — correct.

Technical Assessment (from PR body)

  • TuiMaterializer class with ElementHandle-to-widget mapping, A2A event stream integration, multi-session isolation.
  • BDD + Robot tests.
  • Pyright 0 errors, lint passed, format clean.

Dependency

Depends on PR #707 (TUI MainScreen). Should not be merged before #707. Review can proceed in parallel.

Action Required

  • @CoreRasurae or @brent.edwards: Review when #707 is reviewed. Not time-critical (M8, no deadline).

Labels Added

  • Priority/Medium, MoSCoW/Should have, Points/13, State/In Progress
## PM Review — Day 32 ### Status: COMMENT — Needs peer code review; blocked by dependency ### Summary TuiMaterializer A2A integration layer by @freemo. Maps `ElementHandle` events from A2A output stream to Textual widgets. Mergeable, no conflicts. ### Process Compliance - **PR body**: Adequate — summary, module description, quality checks. Missing: diff coverage table, spec reference lines, CHANGELOG entry, files changed table. - **Closes keyword**: `Closes #696` — correct. - **Labels**: Added (Priority/Medium, MoSCoW/Should have, Points/13, State/In Progress). - **Milestone**: v3.7.0 (M8) — correct. - **Assignee**: @freemo — correct. ### Technical Assessment (from PR body) - `TuiMaterializer` class with ElementHandle-to-widget mapping, A2A event stream integration, multi-session isolation. - BDD + Robot tests. - Pyright 0 errors, lint passed, format clean. ### Dependency **Depends on PR #707** (TUI MainScreen). Should not be merged before #707. Review can proceed in parallel. ### Action Required - **@CoreRasurae or @brent.edwards**: Review when #707 is reviewed. Not time-critical (M8, no deadline). ### Labels Added - Priority/Medium, MoSCoW/Should have, Points/13, State/In Progress
Author
Owner

PM Review — Day 34

Status: Mergeable, 0 reviews, M8 (v3.7.0), Priority/Medium, Points/13
Author: @freemo

TuiMaterializer A2A integration layer. M8 — low urgency. Depends on A2A transport PRs (#708, #713, #720).

Action Items

Who Action Deadline
@CoreRasurae Peer review (deferred) M8 sprint
## PM Review — Day 34 **Status**: Mergeable, 0 reviews, M8 (v3.7.0), Priority/Medium, Points/13 **Author**: @freemo TuiMaterializer A2A integration layer. M8 — low urgency. Depends on A2A transport PRs (#708, #713, #720). ### Action Items | Who | Action | Deadline | |-----|--------|----------| | @CoreRasurae | **Peer review** (deferred) | M8 sprint |
Author
Owner

PM Status — Day 36 (2026-03-16)

Confirmed deferred status. M8/M9 rebase and review deferred until M3-M6 queue clears. No action required at this time.

Next check: Day 40 or when M6 work is substantially complete.

## PM Status — Day 36 (2026-03-16) Confirmed deferred status. M8/M9 rebase and review deferred until M3-M6 queue clears. No action required at this time. **Next check**: Day 40 or when M6 work is substantially complete.
freemo left a comment

PM Day 36: TUI Materializer A2A integration. M8 scope (deferred). @freemo author.

PM Day 36: TUI Materializer A2A integration. M8 scope (deferred). @freemo author.
Author
Owner

This feature is for a later version, so closing it and will do it at the appropriate time.

This feature is for a later version, so closing it and will do it at the appropriate time.
freemo closed this pull request 2026-03-16 22:35:26 +00:00
Some checks failed
CI / typecheck (pull_request) Failing after 1s
Required
Details
CI / security (pull_request) Failing after 1s
Required
Details
CI / quality (pull_request) Failing after 1s
Required
Details
CI / unit_tests (pull_request) Failing after 1s
Required
Details
CI / integration_tests (pull_request) Failing after 1s
Required
Details
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Failing after 2s
Required
Details
CI / lint (pull_request) Successful in 18s
Required
Details
CI / coverage (pull_request) Has been skipped
Required
Details
CI / docker (pull_request) Has been skipped
Required
Details
CI / benchmark-regression (pull_request) Has been skipped

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
Reference
cleveragents/cleveragents-core!721
No description provided.