Skip to content

fix(tui): redraw after sandbox shell exits#2230

Open
johntmyers wants to merge 2 commits into
mainfrom
fix/2229-restore-tui-after-shell/johntmyers
Open

fix(tui): redraw after sandbox shell exits#2230
johntmyers wants to merge 2 commits into
mainfrom
fix/2229-restore-tui-after-shell/johntmyers

Conversation

@johntmyers

Copy link
Copy Markdown
Collaborator

🏗️ build-from-issue-agent

Summary

Restore and render the TUI immediately after an interactive sandbox shell exits, before synchronous gateway refresh calls can delay the next event-loop frame. Propagate terminal suspend/resume failures from both SSH handoff paths instead of silently leaving the terminal in an unknown state.

Related Issue

Closes #2229

Changes

  • crates/openshell-tui/src/lib.rs: return Result from interactive shell and exec-command handoffs and propagate crossterm/ratatui lifecycle failures.
  • crates/openshell-tui/src/lib.rs: draw the current sandbox frame immediately after alternate-screen restoration and before the post-shell gateway refresh.

Deviations from Plan

None — implemented as planned.

Testing

  • mise run pre-commit passes
  • Existing unit and integration suites pass
  • Manual Ubuntu PTY regression check passes
  • E2E tests not required (no files under e2e/ changed; existing lanes do not drive interactive TTY/SSH handoffs)

Tests added:

  • Unit: N/A — raw mode and alternate-screen restoration require a real PTY.
  • Integration: Manual PTY: opened openshell term, entered a ready sandbox with s, ran exit, and observed a complete TUI frame within one second instead of the prior blank screen.
  • E2E: N/A.

Checklist

  • Follows Conventional Commits
  • Commit is signed off (DCO)

Documentation updated:

  • None needed; this restores the existing documented behavior without changing commands or configuration.

Closes #2229

Render the restored terminal before synchronous gateway refreshes and propagate terminal lifecycle failures from both SSH handoff paths.

Signed-off-by: John T. Myers <9696606+johntmyers@users.noreply.github.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 11, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Discard stale events accumulated around the suspended TUI and let the normal periodic tick refresh state after resuming.

Signed-off-by: John T. Myers <9696606+johntmyers@users.noreply.github.com>
@johntmyers

Copy link
Copy Markdown
Collaborator Author

🏗️ build-from-issue-agent

Follow-up: input starvation fixed

Manual testing of the first revision showed that the TUI frame returned but keyboard input remained starved on Ubuntu. A syscall trace confirmed stdin successfully read q; the key was queued behind stale/recurring Tick events, whose synchronous refresh work could keep the event loop from reaching keyboard events.

Commit ce657286 completes the fix:

  • keep terminal polling paused through restoration;
  • discard stale events accumulated around the suspended TUI;
  • resume polling from a clean event queue;
  • remove the redundant immediate post-shell refresh and rely on the normal periodic refresh.

Ubuntu PTY validation now passes across two consecutive shell cycles:

  1. shell → exit → immediate Esc navigated to the dashboard;
  2. shell → exit → immediate q cleanly exited the TUI.

The reporter confirms the original failure does not reproduce on macOS, consistent with this being a Linux timing-sensitive event-queue issue.

mise run pre-commit completed after the change; focused openshell-tui tests pass (24/24).

@johntmyers

Copy link
Copy Markdown
Collaborator Author

/ok to test ce65728

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: TUI shows a black screen after exiting a sandbox shell

1 participant