Skip to content

fix(tui): scope unread updates to focused terminal - #42471

Merged
kitlangton merged 1 commit into
v2from
tab-focus-unread
Aug 14, 2026
Merged

kitlangton merged 1 commit into
v2from
tab-focus-unread

Conversation

@kitlangton

Copy link
Copy Markdown
Contributor

What

Make the foreground TUI the sole owner of shared session-tab unread mutations. A blurred backup TUI can no longer mark a session unread or clear an unread marker merely because it has a different tab selected.

Before / After

Before

  1. TUI A is foregrounded on Session 1.
  2. TUI B is blurred on Session 2.
  3. Both TUIs receive the same execution-completed event.
  4. TUI B evaluates the event against its own selected tab and writes shared unread state.
  5. Either TUI can also clear that shared state based on its local selection, so the indicator does not reliably represent the foreground view.

After

  1. TUI A owns unread mutations while focused.
  2. TUI B still receives and folds server events, but cannot mark or clear unread state while blurred.
  3. TUI A marks only completed sessions outside its selected tab.
  4. Selecting an unread tab in TUI A clears it for the shared tab state.

How

  • packages/tui/src/context/session-tabs.tsx tracks OpenTUI focus and blur transitions and gates both completion marking and selected-tab clearing on foreground ownership.
  • Route/tab synchronization remains independent from focus changes; a narrow effect handles foreground unread clearing.
  • packages/tui/test/context/session-tabs.test.tsx runs two TUI providers against the same persisted state with divergent focus and selected sessions.

Scope

  • If every TUI is blurred when a session completes, no unread marker is recorded. This is intentional: only the foreground terminal owns unread state.
  • A newly launched interactive TUI is considered foregrounded until OpenTUI reports its first blur transition.
  • This does not change execution notifications, sounds, tab persistence, or server events.

Testing

  • bun run test test/context/session-tabs.test.tsx from packages/tui: 9 passed.
  • bun run test from packages/tui: 697 passed, 5 skipped.
  • bun typecheck from packages/tui: passed.
  • Push hook workspace typecheck: 35 packages passed.
  • bunx prettier --check src/context/session-tabs.tsx test/context/session-tabs.test.tsx: passed.

Demo

No recording included: the regression is an incorrect shared marker produced by a blurred second TUI. The concurrent two-TUI test reproduces the process topology and verifies the persisted result directly.

Flow

sequenceDiagram
    participant Server
    participant A as TUI A (focused)
    participant B as TUI B (blurred)
    participant State as Shared tab state

    Server->>A: execution completed
    Server->>B: execution completed
    B-->>State: no mutation
    alt completed session is selected in A
        A-->>State: no unread marker
    else completed session is backgrounded in A
        A->>State: mark unread
    end
    A->>State: clear when selected while focused
Loading

@kitlangton
kitlangton merged commit 82b96eb into v2 Aug 14, 2026
8 of 10 checks passed
@kitlangton
kitlangton deleted the tab-focus-unread branch August 14, 2026 01:54
jinhuang712 pushed a commit to jinhuang712/opencode that referenced this pull request Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant