Feature: TUI App Coverage
  Scenarios exercising previously uncovered code paths in
  cleveragents.tui.app module, including the Textual-based
  application class behind a mocked Textual import gate.

  Background:
    Given the TUI app module is imported with mocked Textual

  # --- Module-level import gate (lines 31-38) ---

  Scenario: Mocked Textual import makes _TEXTUAL_AVAILABLE True
    Then the reloaded app module should have _TEXTUAL_AVAILABLE True

  Scenario: Mocked Textual import assigns _TextualApp from textual.app
    Then the reloaded app module should expose _TextualCleverAgentsTuiApp

  # --- textual_available function (line 43-45) ---

  Scenario: textual_available returns True when Textual is mocked
    Then textual_available should return True on the reloaded module

  # --- SessionView dataclass (lines 48-54) ---

  Scenario: SessionView can be created with session_id and transcript
    When I create a SessionView with session_id "sess-1" and transcript entries
    Then the SessionView session_id should be "sess-1"
    And the SessionView transcript should contain 2 entries

  # --- _CommandRouter protocol (lines 56-61) ---

  Scenario: A class implementing _CommandRouter protocol can be used
    When I create a _CommandRouter implementation
    Then calling handle on the implementation should return a response

  # --- _TextualCleverAgentsTuiApp.__init__ (lines 91-100) ---

  Scenario: The Textual TUI app can be instantiated with mocked Textual
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    Then the app should have a _session with session_id "default"
    And the app should store the command router
    And the app should store the persona state

  # --- CSS_PATH and BINDINGS class variables (lines 84-89) ---

  Scenario: The Textual TUI app has correct class variables
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    Then the app class should have CSS_PATH set to "cleveragents.tcss"
    And the app class should have 4 key bindings

  # --- compose method (lines 102-112) ---

  Scenario: compose yields the expected widget tree
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call compose on the app
    Then compose should yield at least 5 widgets

  # --- on_mount method (lines 114-121) ---

  Scenario: on_mount initialises persona bar and overlays
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    Then the persona bar should have content set
    And the help panel should be hidden on mount
    And the reference picker should have suggestions initialised
    And the slash overlay should be hidden on mount

  # --- action_help method (lines 123-125) ---

  Scenario: action_help opens a main-screen help panel
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I call action_help on the app
    Then the help panel text should contain "Help: Main Screen"
    And the help panel text should contain "ctrl+q"

  Scenario: action_help reflects slash command context
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I set the prompt text to "/persona list"
    And I call action_help on the app
    Then the help panel text should contain "Help: Slash Commands"

  Scenario: action_help reflects shell mode context
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I set the prompt text to "!ls"
    And I call action_help on the app
    Then the help panel text should contain "Help: Shell Mode"

  Scenario: action_help toggles the visible help panel off
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I call action_help on the app
    And I call action_help on the app
    Then the help panel should be hidden on mount

  # --- action_cycle_preset method (lines 127-129) ---

  Scenario: action_cycle_preset cycles the preset and refreshes the bar
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I call action_cycle_preset on the app
    Then the persona bar content should be refreshed

  # --- _refresh_persona_bar method (lines 131-142) ---

  Scenario: _refresh_persona_bar builds scope text from active persona
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call _refresh_persona_bar on the app
    Then the persona bar should display the persona name and scope

  # --- on_input_submitted with empty text (lines 144-150) ---

  Scenario: on_input_submitted with empty text returns early
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I submit empty text to the app
    Then the conversation widget should not be updated by input

  # --- on_input_submitted with command mode (lines 152-167) ---

  Scenario: on_input_submitted routes slash commands
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I submit "/help" to the app
    Then the conversation widget should contain "handled:help"

  # --- on_input_submitted with shell mode (lines 168-177) ---

  Scenario: on_input_submitted routes shell commands
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I submit "!echo tui_shell_test" to the app
    Then the conversation widget should contain "tui_shell_test"

  # --- on_input_submitted with shell returning None (lines 170-171) ---

  Scenario: on_input_submitted handles None shell result
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I submit shell text that produces a None shell result
    Then the conversation widget should contain "(no shell output)"

  # --- on_input_submitted normal mode with @ reference (lines 179-185) ---

  Scenario: on_input_submitted handles normal text with @ references
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I submit "check @README" to the app
    Then the conversation widget should contain "check"
    And the reference picker should have been updated

  # --- on_input_submitted normal mode without @ (line 179, 185) ---

  Scenario: on_input_submitted handles normal text without references
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I submit "plain message" to the app
    Then the conversation widget should contain "plain message"

  # --- CleverAgentsTuiApp alias (line 189) ---

  Scenario: CleverAgentsTuiApp resolves to the Textual app when available
    Then CleverAgentsTuiApp should be _TextualCleverAgentsTuiApp on the reloaded module

  # --- on_input_submitted shell with stdout output (lines 173-176) ---

  Scenario: on_input_submitted displays shell stdout and command
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I submit "!echo coverage_run" to the app
    Then the conversation widget should contain "$ echo coverage_run"

  # --- on_input_submitted shell with empty output (line 174) ---

  Scenario: on_input_submitted shows empty output for silent shell commands
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I submit "!true" to the app
    Then the conversation widget should contain "(empty output)"

  # --- THEME class variable (issue #4742) ---

  @tdd_issue @tdd_issue_4742
  Scenario: The Textual TUI app has THEME set to dracula by default
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    Then the app class should have THEME set to "dracula"

  # --- action_escape cascade (issue #6450) ---

  Scenario: action_escape cascades overlays toward the prompt
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I set the prompt text to "draft @README.md"
    And I show the actor selection overlay
    And I show the help panel overlay for context "Main Screen"
    And I show the slash overlay for query "help"
    And I show the reference picker overlay for query "README.md"
    And I call action_escape on the app
    Then the actor selection overlay should be hidden
    And the help panel should remain visible
    When I call action_escape on the app
    Then the help panel should be hidden on mount
    And the slash overlay should remain visible
    When I call action_escape on the app
    Then the slash overlay should be hidden
    And the reference picker overlay should remain visible
    When I call action_escape on the app
    Then the reference picker overlay should be hidden
    And the prompt text should be "draft"

  # --- on_input_changed handler (live overlay updates) ---

  Scenario: on_input_changed with slash prefix filters slash commands live
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I trigger on_input_changed with text "/ses"
    Then the slash overlay should show only commands matching "ses"
    And the reference picker should be reset to empty

  Scenario: on_input_changed with at-sign updates reference picker live
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I trigger on_input_changed with text "@proj"
    Then the reference picker should have been updated
    And the slash overlay should be reset to all commands

  Scenario: on_input_changed with plain text resets both overlays
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I trigger on_input_changed with text "hello world"
    Then the slash overlay should be reset to all commands
    And the reference picker should be reset to empty

  Scenario: on_input_changed with empty at-sign resets reference picker
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I trigger on_input_changed with text "send @"
    Then the reference picker should be reset to empty

  Scenario: on_input_changed with empty text resets both overlays
    Given a mock command router and persona state
    When I instantiate the Textual TUI app
    And I call on_mount on the app
    And I trigger on_input_changed with empty text
    Then the slash overlay should be reset to all commands
    And the reference picker should be reset to empty
