Skip to content

Permission prompt buttons unreachable for very long shell commands #40793

Description

@surmusz

Description

Describe the bug

When a shell command needs approval, a very long command pushes the Allow/Reject buttons off-screen, so they can't be clicked or reached.

To Reproduce

  1. Ask the agent to run a very long command (thousands of characters, single line)
  2. Permission prompt appears
  3. The command text is rendered unwrapped and unbounded, the action buttons are pushed below the visible area

Expected behavior

The command body should be word-wrapped / scrollable and the buttons stay visible.

Screenshots

(attach if possible)

Environment

  • OS: macOS (arm64)
  • opencode version: 1.18.13

Suggested fix

Root cause: in packages/tui/src/routes/session/permission.tsx, text bodies are rendered as plain <text> without wrapping or a height limit. A long single-line command grows the prompt body beyond the terminal height, and the button row (flexShrink={0}) gets pushed off-screen.

Fix: wrap text bodies in a bounded scrollable area with word wrapping. Key code:

// ScrollableText: bounded scrollable body with word wrap
function ScrollableText(props: { text: string; prefix?: string; muted?: boolean }) {
  const { theme } = useTheme()
  const tuiConfig = useTuiConfig()
  const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig))
  return (
    <Show when={props.text}>
      <box paddingLeft={1} flexGrow={1} minHeight={0}>
        <scrollbox height="100%" scrollAcceleration={scrollAcceleration()}
          verticalScrollbarOptions={{ trackOptions: { backgroundColor: theme.background, foregroundColor: theme.borderActive } }}>
          <text fg={props.muted ? theme.textMuted : theme.text} wrapMode="word" width="100%">
            {(props.prefix ?? "") + props.text}
          </text>
        </scrollbox>
      </box>
    </Show>
  )
}

Applied to every text-based permission body (bash, task, webfetch, websearch, read, glob, grep, list):

if (permission === "bash") {
  const command = typeof data.command === "string" ? data.command : ""
  return {
    icon: "#",
    title: "Shell command",
    body: <ScrollableText text={command} prefix="$ " />,
  }
}

Related: permission prompt text (command, urls, todo list items) can't be selected/copied with the mouse since TUI text has no native selection. A permission.prompt.copy shortcut (ctrl+y) and a hover "copy" action on todo blocks are also part of the proposed fix.

Unfortunately I don't have time to run the tests and submit a PR.

Bug 描述

需要审批的 shell 命令过长时,Allow/Reject 按钮被推出屏幕,无法点击或选中。

复现步骤

  1. 让 agent 执行一个超长命令(单行数千字符)
  2. 弹出权限审批框
  3. 命令文本无换行无高度限制,按钮被推到可视区域下方

期望行为

命令正文应自动换行/可滚动,按钮保持可见。

根因与修复

根因:packages/tui/src/routes/session/permission.tsx 中文本正文以裸 <text> 渲染,无换行、无高度限制。超长单行命令把弹窗正文撑高超过终端高度,按钮行(flexShrink={0})被挤出屏幕。

修复:将文本正文包进有界可滚动区域并启用单词换行(关键代码见英文版 ScrollableText),应用到全部基于文本的审批分支(bash、task、webfetch、websearch、read、glob、grep、list)。

相关问题:TUI 文本无原生选择能力,审批内容(命令、URL、todo 列表)无法鼠标选中复制。方案含 permission.prompt.copy 快捷键(ctrl+y)及 todo 块 hover "copy" 操作。

很抱歉我没有时间进行相关测试并提交 PR。

Plugins

No response

OpenCode version

1.18.14

Steps to reproduce

  1. Ask the agent to run a very long command (thousands of characters, single line)
  2. Permission prompt appears
  3. The command text is rendered unwrapped and unbounded, the action buttons are pushed below the visible area

Screenshot and/or share link

No response

Operating System

macOS 26.5.2 (Apple Silicon / arm64)

Terminal

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions