Skip to content

fix(tui): auto-approve background tab permissions - #62043

Open
maorlipchuk wants to merge 2 commits into
anomalyco:devfrom
maorlipchuk:background-autoaccept
Open

maorlipchuk wants to merge 2 commits into
anomalyco:devfrom
maorlipchuk:background-autoaccept

Conversation

@maorlipchuk

@maorlipchuk maorlipchuk commented Nov 5, 2026 •

Copy link
Copy Markdown

Issue for this PR

Fixes #44007. Updated implementation of the approach proposed in #44009, based on current dev.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Moves automatic permission approval out of the selected session view into the always-mounted TUI application. With autoaccept enabled, requests from open background tabs and their child sessions no longer wait for tab selection.

Approval remains scoped to the selected session, open tabs, and actual descendants. Pending requests are refreshed on reconnect; replies use once, and configured denials and questions are unchanged.

How did you verify your code works?

Reproduced the background-tab stall on unmodified dev. With this change, both a background session and child session completed actual shell commands without selecting their tabs. Verification used an isolated real server, a headless TUI client, and a deterministic local model endpoint.

bun run check passes. The full TUI suite has the same two rendering failures on pristine dev and this branch (go-upsell-art and spinner-renderable).

Visual

Illustration of the behavior change, not a terminal screenshot:

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="72" viewBox="0 0 240 72">
  <style>
    .pulse{animation:pulse 2s ease-in-out infinite}
    @keyframes pulse{50%{opacity:.35}}
    @media(prefers-reduced-motion:reduce){.pulse{animation:none}}
  </style>
  <rect x="1" y="1" width="238" height="70" rx="8" fill="none" stroke="currentColor" opacity=".25"/>
  <g fill="currentColor" font-family="monospace" font-size="11">
    <text x="12" y="23">Auto mode / background tab</text>
    <text x="12" y="49">Permission</text>
    <text x="106" y="49" opacity=".6">→</text>
    <text x="127" y="49">Continues</text>
  </g>
  <circle class="pulse" cx="215" cy="45" r="4" fill="currentColor"/>
</svg>

Screenshots / recordings

No layout changes. The headless before/after check confirms the background tab changes from waiting at ! to completing while another view remains selected.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Added by the opencode bot (AI-generated).

Related: #56907, #52486, #47545

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the background-tab stall. I ran the #44007 reproduction from source with a simulated model. On the base, the background tab waited at ! and the session only continued once I selected it (16s). With this PR the request is approved about 4s in while the other tab stays selected, and the ! is gone. The new tests pass, and the type check shows no new errors.

Public API: unchanged. It only moves client-side behaviour in the TUI, with no config keys, flags, events or SDK changes.

The approach looks sound. Pending requests are fetched again only when the set of sessions changes or on reconnect, and permission.sync is cached, so repeated changes cost little. The descendant walk keeps a selected child from approving its parent or siblings. Prompt mode is unchanged.

One request: test/background-autoaccept.test.ts is large for what it checks (229 lines, 8 cases, a hand-written fetch router and several promise resolvers). Could you cut it down to the core cases: a background tab is approved, a background tab's child is approved, and prompt mode leaves the request pending? The negative cases (tabs disabled, selected child) assert that nothing was sent after a single renderOnce(), which is a weak check.

Related: #56907, #52486, #47545

Before

After

import { tmpdir } from "./fixture/fixture"
import { directory, json } from "./fixture/tui-client"

async function fixture(options: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixture (a hand-written fetch router, five resolvers, a mutable pendingChild flag) plus 8 cases is a lot to follow for this fix. Could you trim it to the core cases (background root approved, background child approved, prompt mode left pending)? The "nothing replied" tests only check after one renderOnce(), so they would still pass if a late reply arrived afterwards.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.
simplified the fixture to the requested background root, background child, and prompt-mode cases, removing the mutable flag and extra resolvers. The prompt-mode test now waits for the pending request to survive navigation and appear in the approval UI, then verifies manual approval and UI removal. The production implementation is unchanged.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's much easier to follow. I checked 599cd8b: there are now three cases (background root, background child, and prompt mode left pending until you approve it by hand), all with a single fixture, and nothing else changed. The negative check now waits for the approval prompt to appear instead of relying on one renderOnce(). All three pass locally (bun test test/background-autoaccept.test.ts: 3 pass). Nothing more from me on the tests.

@maorlipchuk

Copy link
Copy Markdown
Author

Thanks for independently reproducing and verifying the fix. Updated the tests as requested. The targeted tests, TUI TypeScript check, and formatting check pass. The repository-wide check currently encounters an unchanged desktop benchmark type error involving gpuCache, outside this change.

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My earlier test comment is addressed: the file is now three focused cases (background root, background child, prompt mode until manual approval), and the prompt-mode check waits for the approval prompt to appear. They pass locally. The app code is unchanged since my last review, which still holds: the background-tab stall from #44007 is fixed, and the public API is unchanged. Nothing new from me.

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new commit only merges dev, and none of this PR's files changed, so my earlier review still holds: the background-tab stall from #44007 is fixed, and the public API is unchanged. The trimmed test file from the previous push addresses my earlier comment, and its three tests still pass on the new head. Nothing new from me.

@maorlipchuk
maorlipchuk force-pushed the background-autoaccept branch from e8fc1c6 to bd20322 Compare November 5, 2026 14:51

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This push only rebases onto newer dev. The diff is the same as the one I last reviewed, and the new base doesn't touch the TUI or client code, so my earlier review still holds: the background-tab stall from #44007 is fixed, and the public API is unchanged. The trimmed tests still pass. Nothing new from me.

@maorlipchuk
maorlipchuk force-pushed the background-autoaccept branch from bd20322 to 1be10af Compare November 5, 2026 17:17

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This push only rebases onto newer dev; the diff is unchanged. Because the new base touches the same TUI files, I re-ran the #44007 reproduction on the new head: the background tab's request is still auto-approved while another tab is selected. The trimmed tests pass, and the type check shows no errors in the changed files. Public API is unchanged. Nothing new from me.

@maorlipchuk
maorlipchuk force-pushed the background-autoaccept branch from 1be10af to e41f68e Compare November 6, 2026 00:41

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This push only rebases onto newer dev; the diff is unchanged and the new base doesn't touch the TUI or client code. My earlier review still holds: the background-tab stall from #44007 is fixed, and the public API is unchanged. The trimmed tests pass on the new head. Nothing new from me.

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This push only rebases onto newer dev; the diff is unchanged. Because the new base has many TUI changes, I re-ran the #44007 reproduction on the new head: the background tab's request is still auto-approved while another tab is selected. The trimmed tests pass. Public API is unchanged. Nothing new from me.

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This push only rebases onto a dev that is one commit newer and doesn't touch the TUI or client code; the diff is unchanged. My earlier review still holds: the background-tab stall from #44007 is fixed, and the public API is unchanged. The trimmed tests pass on the new head. Nothing new from me.

@TonyYanS

Copy link
Copy Markdown

Confirmed the same background-tab stall on v2.2.6 (macOS + Ghostty, session.permissions: "autoaccept" in cli.json); the responder is still route-scoped in 2.2.6, so this PR's approach still applies. Could a maintainer approve the pending fork workflow runs and review this? It is the fix for #44007, which is affecting several users running parallel tabs.

@maorlipchuk
maorlipchuk force-pushed the background-autoaccept branch from 83b46a8 to 2d54595 Compare November 11, 2026 08:15

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This push only rebases onto newer dev; the diff is unchanged. Because the new base has many TUI changes, including to tabs, I re-ran the #44007 reproduction on both checkouts. On the base, the background tab still waits until it is selected (16s). With this PR its request is approved about 4s in while the other tab stays selected. The trimmed tests pass, and the type check shows no errors in the changed files. Public API is unchanged. Nothing new from me.

Before

After

@maorlipchuk
maorlipchuk force-pushed the background-autoaccept branch from 2d54595 to 1493ac4 Compare November 11, 2026 15:51

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This push only rebases onto newer dev; the diff is unchanged, and the new base doesn't touch permission handling. My earlier review still holds: the background-tab stall from #44007 is fixed, and the public API is unchanged. The trimmed tests pass on the new head. Nothing new from me.

This branch has not been deployed

No deployments
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.

TUI --auto stalls background tabs at permission requests

2 participants