Skip to content

fix(tui): dismiss stale permission prompts - #40960

Merged
kitlangton merged 2 commits into
v2from
fix-stale-permission
Aug 7, 2026
Merged

fix(tui): dismiss stale permission prompts#40960
kitlangton merged 2 commits into
v2from
fix-stale-permission

Conversation

@kitlangton

@kitlangton kitlangton commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What

Dismiss stale TUI permission prompts when the server reports that the request no longer exists.

The full TUI now routes manual and automatic permission replies through its data layer. Once a reply succeeds, or returns PermissionNotFoundError, that exact request is removed from local state. Other failures remain visible and surface through the existing toast.

Before / After

Before

  1. The TUI received permission.asked and displayed the approval dialog.
  2. The server-side request disappeared before the user replied, for example when the waiting execution was interrupted.
  3. Selecting Allow posted the stale request ID and received 404 PermissionNotFoundError.
  4. The rejected promise was ignored, so the same dialog remained and every Enter retried the same expired request forever.

After

  1. The reply endpoint succeeds or authoritatively reports that the request is already absent.
  2. The data layer removes that exact request ID from the owning session's local permission list.
  3. The dialog closes while any unrelated pending permissions remain intact.
  4. Transport and unexpected server errors still retain the prompt and show an error.

How

  • packages/tui/src/context/data.tsx owns reply settlement and reuses one idempotent removal path for API outcomes and permission.replied events.
  • packages/tui/src/routes/session/permission.tsx closes over the active request and passes only the varying reply and optional message.
  • packages/tui/src/routes/session/index.tsx uses the same path for automatic approval.
  • packages/tui/test/cli/tui/data.test.tsx reproduces a cached request whose reply returns the tagged 404 and verifies that it is dismissed without another list request.

Scope

This PR does not change the server's ephemeral permission lifecycle or add a new cancellation event. It makes the full TUI robust when a reply races with server-side cleanup or a terminal permission event is missed. The Mini TUI has a separate transport projection and remains out of scope.

Testing

  • bun run test test/cli/tui/data.test.tsx test/cli/tui/permission.test.ts from packages/tui: 41 passed
  • bun typecheck from packages/tui: passed
  • Push hook workspace typecheck: 32 packages passed
  • bun run lint -- <changed files>: 0 errors; existing warnings remain in the touched large files
  • Live reproduction on 0.0.0-next-16927: repeated replies for one expired permission returned 404; delivering its missing terminal event dismissed the prompt without restarting the shared service

Demo

No recording is attached because the live reproduction contained a private session transcript and temporary filesystem paths. The regression test covers the exact visible transition: cached permission dialog to no pending permission after the tagged 404.

Flow

sequenceDiagram
    participant User
    participant TUI
    participant Server

    User->>TUI: Allow permission
    TUI->>Server: Reply with request ID
    alt Request is pending
        Server-->>TUI: Success
    else Request already disappeared
        Server-->>TUI: PermissionNotFoundError
    else Unexpected failure
        Server-->>TUI: Error
        TUI-->>User: Keep dialog and show toast
    end
    TUI->>TUI: Remove settled request ID
    TUI-->>User: Dismiss dialog
Loading

@kitlangton
kitlangton merged commit 047d434 into v2 Aug 7, 2026
10 checks passed
@kitlangton
kitlangton deleted the fix-stale-permission branch August 7, 2026 01:43
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