Skip to content

feat(tui): ring a turn-done notification when the terminal is unfocused - #233

Merged
Max17190 merged 1 commit into
mainfrom
tui-turn-end-notification
Aug 27, 2026
Merged

feat(tui): ring a turn-done notification when the terminal is unfocused#233
Max17190 merged 1 commit into
mainfrom
tui-turn-end-notification

Conversation

@Max17190

@Max17190 Max17190 commented Aug 27, 2026

Copy link
Copy Markdown
Owner

Why

A turn finishing while the user is in another window ends silently; the bell fires only when an approval arrives, so long turns mean polling the terminal.

Summary

Track terminal focus from focus-change reports (term_focus: Option<bool>, None until the terminal sends one). On the working-to-idle presence edge while known unfocused, emit an OSC 9 notification plus a bell. Terminals that never report focus stay silent rather than ringing at a watching user; the needs-approval bell keeps its unconditional ring. EnableFocusChange is symmetric with the other terminal modes on init and every exit path.

Test Plan

  • turn_done_ring_fires_only_on_the_unfocused_working_to_idle_edge: full truth table for the ring decision (shown red with the decision neutered).
  • focus_reports_track_terminal_focus: focus events update the tracked state (shown red with tracking neutered).
  • cargo test --workspace and cargo clippy --workspace --all-targets clean.

Greptile Summary

This change tracks terminal focus and rings when an unfocused turn becomes idle. The normal shutdown path disables focus reporting, but the panic cleanup path does not, so a crash can leave the shell receiving terminal focus escape sequences after OpenMax exits. The TUI binary test suite passed with 246 tests.

Confidence Score: 4/5

Not merge-safe until panic cleanup disables terminal focus reporting.

There is one independent P1 finding, and it is not a security issue; the required scoring table assigns a score of 4.

Files Needing Attention: crates/tui/src/main.rs: add focus-reporting cleanup to the panic path.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for a posted P1 finding and linked it to the review comment for details.
  • T-Rex created a Rust harness to exercise focus-reporting panic cleanup.
  • Generated logs showing panic cleanup behavior without panic-hook focus disable for review.
  • Generated logs showing panic cleanup behavior with panic-hook focus disable for review.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. crates/tui/src/main.rs, line 1115-1116 (link)

    P1 Panic cleanup leaves focus reporting enabled

    Focus reporting is enabled before app::run, but it is disabled only after app::run returns normally. A panic runs this hook and unwinds past the normal cleanup at line 1081; the hook restores Ratatui and the title without emitting DisableFocusChange. A compatible terminal therefore continues sending focus escape sequences to the restored shell after an OpenMax panic. Disable focus reporting in this panic cleanup path as well, or use an unwind-safe cleanup guard.

    Artifacts

    Rust harness for focus-reporting panic cleanup

    • Authored and executed a direct Rust reproduction that emits crossterm focus control sequences around an injected app-boundary panic, showing the normal cleanup is bypassed on unwind.

    Panic cleanup output without panic-hook focus disable

    • Captured command, working directory, exit code, and output for the production-equivalent panic path; it shows focus enable present and focus disable absent.

    Panic cleanup output with panic-hook focus disable

    • Captured command, working directory, exit code, and output for the comparison path with panic-hook focus cleanup; it shows both focus enable and disable sequences.

    View artifacts

    T-Rex Ran code and verified through T-Rex

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: crates/tui/src/main.rs
    Line: 1115-1116
    
    Comment:
    **Panic cleanup leaves focus reporting enabled**
    
    Focus reporting is enabled before `app::run`, but it is disabled only after `app::run` returns normally. A panic runs this hook and unwinds past the normal cleanup at line 1081; the hook restores Ratatui and the title without emitting `DisableFocusChange`. A compatible terminal therefore continues sending focus escape sequences to the restored shell after an OpenMax panic. Disable focus reporting in this panic cleanup path as well, or use an unwind-safe cleanup guard.
    
    ---
    
    For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Prompt To Fix All With AI
### Issue 1
crates/tui/src/main.rs:1115-1116
**Panic cleanup leaves focus reporting enabled**

Focus reporting is enabled before `app::run`, but it is disabled only after `app::run` returns normally. A panic runs this hook and unwinds past the normal cleanup at line 1081; the hook restores Ratatui and the title without emitting `DisableFocusChange`. A compatible terminal therefore continues sending focus escape sequences to the restored shell after an OpenMax panic. Disable focus reporting in this panic cleanup path as well, or use an unwind-safe cleanup guard.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "feat(tui): ring a turn-done notification..." | Re-trigger Greptile

@Max17190
Max17190 marked this pull request as ready for review August 27, 2026 03:53
The bell fired only on the needs-approval edge, so a turn finishing while
the user was in another window ended silently and long turns meant polling
the terminal. Track terminal focus from focus-change reports (None until
the terminal sends one, so terminals without focus reporting stay silent
rather than ringing at a watching user), and on the working-to-idle edge
while known unfocused emit an OSC 9 notification plus a bell. The
needs-approval bell keeps its unconditional ring.
@Max17190
Max17190 force-pushed the tui-turn-end-notification branch from 65caef1 to 32c4c1e Compare August 27, 2026 03:55
@Max17190
Max17190 merged commit 95d27ec into main Aug 27, 2026
4 checks passed
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.

1 participant