Skip to content

fix(tui): --auto shows permission attention on session tabs #52486

Open

Description

@Max10240

Description

A newly opened opencode --auto client still shows ! on tabs with pending permission requests, suggesting that manual approval is needed.

Permission markers should be hidden on all tabs in auto mode. Normal clients should keep them, and questions should still show attention in either mode.

Plugins

None in the reproduction.

OpenCode version

2.0.21 (npm release)

Steps to reproduce

  1. On a V2 server, create two sessions with pending read permission requests using the session permission API, and a third session without a pending request.
  2. Open all three as tabs in a normal client, keeping the third tab active. Both background tabs show !.
  3. Launch a new opencode --server <server-url> --auto client and open the same tabs, keeping the third active.
  4. The auto client also shows ! on both background tabs.

Reproduced in tmux with fresh clients. Both requests remained pending on the shared server.

Screenshot and/or share link

Tab-bar excerpt from the npm 2.0.21 --auto client:

! e2e-permission-one    ! e2e-permission-two    e2e-active-clean

Operating System

macOS 14.6, Apple Silicon (arm64)

Terminal

tmux 3.6a, 140×42 panes

Activity

  1. github-actions commented on Oct 1, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of or related to existing issues. Please check:

    • #44007: --auto does not handle permission requests on background tabs until they are selected.
  2. iitzkube commented on Oct 9, 2026

    @iitzkube

    Not sure if it's related but opencode v2.0.24 is also spamming iTerm2 notifications on auto mode for every tool call, in the session itself nothing is actually waiting for my permission/input

    Image
  3. opencodejr commented on Oct 28, 2026

    @opencodejr

    Thanks for the detailed report. I was able to reproduce this on 2.0.21, and it still happens on the latest dev (891a020bc).

    What I did:

    • Ran the TUI in auto-accept mode (I used session.permissions: "autoaccept" in cli.json, which is the same mode --auto selects) with a read: ask permission rule.
    • Opened three session tabs and left the third active.
    • Created read permission requests for the other two sessions through the session permission API.

    A background tab still showed ! while its request was pending, and the prompt footer showed Build auto (screenshots and recording below; the script below reproduces it). In my run only one background tab kept its !; the client resolved the other tab's request.

    Related: #44007 reports that --auto doesn't approve requests in background tabs, which is why these requests stay pending in the first place. Your PR #52489 is also linked here.

    recording.mp4

    Screenshot

    Screenshot

    Reproduction script (drive.ts)
    // Repro for anomalyco/opencode#52486: auto-accept client still shows "!" on background tabs
    // with pending permission requests. Auto mode is enabled via cli.json
    // `session.permissions: "autoaccept"`, the same mode `opencode --auto` selects
    // (packages/tui/src/context/permission.tsx).
    import { Effect, Stream } from "effect"
    import { Llm, OpenCodeDriver } from "opencode-drive"
    
    export default OpenCodeDriver.use(
      {
        ...(process.env.OC_DEV ? { opencode: { dev: process.env.OC_DEV } } : {}),
        config: { permissions: [{ action: "read", resource: "*", effect: "ask" }] } as any,
        tuiConfig: { session: { permissions: "autoaccept" } } as any,
        tui: { recording: true, viewport: { cols: 140, rows: 42 } },
      },
      ({ ui, llm, opencode }) => {
        const api = opencode as any as { permission: { create: (i: any) => Effect.Effect<any>; request: { list: () => Effect.Effect<any> } } }
        return     Effect.gen(function* () {
          // Answer every model call (including title generation) with a short text reply.
          yield* llm.serve(() => Stream.make(Llm.text("ok")))
          for (const [i, name] of ["one", "two", "three"].entries()) {
            if (i > 0) {
              yield* ui.press("x", { ctrl: true })
              yield* ui.press("n")
              yield* Effect.sleep("1 second")
            }
            yield* ui.submit(`session ${name}`)
            yield* ui.waitFor(`session ${name}`)
            yield* Effect.sleep("2 seconds")
          }
          yield* ui.screenshot("before-permissions")
          const list: any = yield* opencode.session.list()
          // The third session is the active tab; give the other two pending requests.
          const sessions = [...(list.data ?? list.items ?? list)].sort(
            (a: any, b: any) => Date.parse(a.time.created) - Date.parse(b.time.created),
          )
          yield* Effect.log(`sessions: ${sessions.map((s: any) => s.id).join(", ")}`)
          for (const s of sessions.slice(0, 2)) {
            const r = yield* api.permission.create({
              sessionID: s.id,
              action: "read",
              resources: ["src/secret.txt"],
            })
            yield* Effect.log(`created permission: ${JSON.stringify(r)}`)
          }
          yield* Effect.sleep("3 seconds")
          yield* ui.screenshot("auto-mode-tabs")
          const pending: any = yield* api.permission.request.list()
          yield* Effect.log(`pending requests: ${JSON.stringify(pending).slice(0, 600)}`)
          const frame: any = yield* ui.capture()
          const tabBar = frame.lines[0].spans.map((s: any) => s.text).join("")
          yield* Effect.log(`tab bar: ${JSON.stringify(tabBar)}`)
          yield* Effect.sleep("2 seconds")
        })
      },
    )

    Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions