[FEATURE]: TUI should show pending permissions or questions when attaching to a session #7554

Open
opened 2026-02-16 18:07:34 -05:00 by yindo · 2 comments
Owner

Originally created by @tensor-ninja on GitHub (Jan 25, 2026).

Originally assigned to: @rekram1-node on GitHub.

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

When using opencode attach to connect to a running server, the TUI does not display permissions or questions that were asked while no TUI was attached. This blocks the detach/reattach workflow.

You can reproduce by:

  • Start opencode in server mode: opencode serve
  • Attach in another terminal: opencode attach http://127.0.0.1:4096
  • Send a prompt that triggers the AI to ask a question
  • Detach from the TUI
  • Reattach: opencode attach http://127.0.0.1:4096 --session

Expected: The pending question should be displayed in the TUI
Actual: The question is not shown; the session appears stuck on N questions asked

The TUI's sync context src/cli/cmd/tui/context/sync.tsx only populates store.permission and store.question from SSE events permission.asked, question.asked. When a TUI attaches after the event has already fired, it never receives the event and doesn't know about pending items.

The server already has endpoints to list pending items:

  • GET /permission - Lists all pending permission requests
  • GET /question - Lists all pending question requests

But the TUI doesn't call these during bootstrap.

I think we should add API calls to the bootstrap sequence in sync.tsx to fetch pending permissions and questions:

sdk.client.permission.list().then((x) => {
  const grouped: Record<string, PermissionRequest[]> = {}
  for (const p of x.data ?? []) {
    if (!grouped[p.sessionID]) grouped[p.sessionID] = []
    grouped[p.sessionID]!.push(p)
  }
  setStore("permission", reconcile(grouped))
}),
sdk.client.question.list().then((x) => {
  const grouped: Record<string, QuestionRequest[]> = {}
  for (const q of x.data ?? []) {
    if (!grouped[q.sessionID]) grouped[q.sessionID] = []
    grouped[q.sessionID]!.push(q)
  }
  setStore("question", reconcile(grouped))
}),
Originally created by @tensor-ninja on GitHub (Jan 25, 2026). Originally assigned to: @rekram1-node on GitHub. ### Feature hasn't been suggested before. - [x] I have verified this feature I'm about to request hasn't been suggested before. ### Describe the enhancement you want to request When using `opencode attach` to connect to a running server, the TUI does not display permissions or questions that were asked while no TUI was attached. This blocks the detach/reattach workflow. You can reproduce by: - Start opencode in server mode: opencode serve - Attach in another terminal: opencode attach http://127.0.0.1:4096 - Send a prompt that triggers the AI to ask a question - Detach from the TUI - Reattach: opencode attach http://127.0.0.1:4096 --session <session-id> Expected: The pending question should be displayed in the TUI Actual: The question is not shown; the session appears stuck on N questions asked The TUI's sync context `src/cli/cmd/tui/context/sync.tsx` only populates `store.permission` and `store.question` from SSE events `permission.asked`, `question.asked`. When a TUI attaches after the event has already fired, it never receives the event and doesn't know about pending items. The server already has endpoints to list pending items: - GET /permission - Lists all pending permission requests - GET /question - Lists all pending question requests But the TUI doesn't call these during bootstrap. I think we should add API calls to the bootstrap sequence in `sync.tsx` to fetch pending permissions and questions: ```javascript sdk.client.permission.list().then((x) => { const grouped: Record<string, PermissionRequest[]> = {} for (const p of x.data ?? []) { if (!grouped[p.sessionID]) grouped[p.sessionID] = [] grouped[p.sessionID]!.push(p) } setStore("permission", reconcile(grouped)) }), sdk.client.question.list().then((x) => { const grouped: Record<string, QuestionRequest[]> = {} for (const q of x.data ?? []) { if (!grouped[q.sessionID]) grouped[q.sessionID] = [] grouped[q.sessionID]!.push(q) } setStore("question", reconcile(grouped)) }), ```
yindo added the opentuidiscussion labels 2026-02-16 18:07:34 -05:00
Author
Owner

@dseravalli commented on GitHub (Feb 14, 2026):

I am building an opencode agent orchestrator and needed this functionality, so I took @tensor-ninja 's idea and tried it out. Seems to work great.
https://github.com/anomalyco/opencode/pull/13657

@dseravalli commented on GitHub (Feb 14, 2026): I am building an opencode agent orchestrator and needed this functionality, so I took @tensor-ninja 's idea and tried it out. Seems to work great. https://github.com/anomalyco/opencode/pull/13657
Author
Owner

@tensor-ninja commented on GitHub (Feb 14, 2026):

Yes! I'd love to see this merged!

@tensor-ninja commented on GitHub (Feb 14, 2026): Yes! I'd love to see this merged!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#7554