Repository navigation
Description
Summary
In the desktop app, a permission request for a shell command renders without the explanatory line. The dock resolves settings.permissions.tool.<action>.description from the i18n bundle, but the bundle only ships keys for bash, while the server emits the action name shell. Same dock logic as #51519 (where MCP permissions show only *).
Environment
- opencode version: 2.1.4 (desktop app; the bundled
opencode-cli.exe --versionreports2.1.4as well) - OS: Windows 11 Home 25H2, build 26300, x64
- Terminal: n/a — desktop app (Electron); no
$TERM/$TERM_PROGRAMset - Shell: PowerShell 7 (
pwsh), invoked throughcmd.exe - Install/channel: release,
channel=latest, desktop build (not a dev checkout) - Active plugins:
permission-guard(local plugin, registersctx.permission.hook("evaluate")),custom-tools
Reproduction
- Add a permission rule that asks for shell commands, e.g.
{ "action": "shell", "resource": "*", "effect": "ask" }in~/.config/opencode/opencode.jsonc. - Run a shell command that no later rule allows.
- Observe the permission card in the desktop app.
Expected Behavior
The card shows a description line identifying what is being asked, plus the affected command — at minimum the same text the TUI shows.
Actual Behavior
The card shows only the title ("Permission required"), the warning icon and the three buttons. The description line is missing. When the request also carries no resources, the body is completely empty and the user cannot tell what they are approving.
Additional Context
Evidence that the description is unreachable for shell:
- The renderer builds the body from exactly two sources: the i18n key
settings.permissions.tool.${request.action}.description(rendered only when the key resolves; otherwise an empty string is used) andrequest.resources. Themessagefield is not rendered at all. - The 2.1.4 bundle contains
settings.permissions.tool.bash.titleandsettings.permissions.tool.bash.description, but nosettings.permissions.tool.shell.*entry at all. - The server uses
shellas the action name — e.g. the default agent permission rules in the shipped binary read{ "action": "shell", "resource": "*", "effect": "allow" }, and the same config vocabulary (shell,read,edit,external_directory) is accepted in user config.
So for every shell permission the description lookup fails by construction, independent of locale.
Suggested fix: add settings.permissions.tool.shell.title / .description to the i18n bundle, or map the legacy bash entries onto shell in the lookup.
Two side notes from the same investigation:
- The dock only special-cases a fixed set of action names. The bundle has entries for
bash,doom_loop,edit,external_directory,glob,grep,list,lsp,read,skill,task,todowrite,webfetch,websearch— anything else (MCP tool names, per-tool actions) silently produces no hint, which is the broader form of v2 web/desktop: MCP permission prompt shows only*, not the tool name #51519. - Unrelated packaging oddity: the version resource of
resources/opencode-cli.exein the desktop build says1.4.4, whileopencode-cli.exe --versionand the log (version=2.1.4 channel=latest) both report 2.1.4. This made version triage misleading.
Activity
opencode-agent commentedon Oct 26, 2026
Thanks for the detailed report. I reproduced this on 2.1.4, and it still happens on the latest
dev(ae876ee).With a
{ "action": "shell", "resource": "*", "effect": "ask" }rule and a model calling the shell tool onecho hello, the server's pending permission request hasaction: "shell"andresources: ["echo hello"]. The web/desktop permission dock looks upsettings.permissions.tool.shell.description, but the app's translation files only definesettings.permissions.tool.bash.*("Run shell commands"). So the description line is never shown for shell permissions, in any locale. The script below reproduces the server side and prints the key the dock looks up.I couldn't render the desktop app itself here, and I didn't test the fully empty card for a request with no
resources, since my test request always included the command. The TUI shows the shell prompt normally.Related: #51519 is the broader version of this, where MCP and other per-tool permissions get no hint at all.
Reproduction script (drive.ts)
Run it with opencode-drive:
opencode-drive run ./drive.ts. It drivesopencodefrom yourPATH; setOC_DEVto the path of an OpenCode checkout to run that from source instead.pskraemer11 commentedon Oct 26, 2026
Refinement after reading the source —
resourcesis not empty forshell.packages/core/src/tool/plugin/shell.tsondev:So a shell permission always carries the parsed command(s) in
resources, and the dock renders them as<code>lines. The body is therefore not empty — what is missing is only the description line above the command.This narrows the reported impact: the user can still see what is being run, they just get no hint line naming the action. A completely empty body, or one showing a bare
*, must come from a different action — e.g. MCP tools, whose wrapper passesresources: ["*"]. That is #51519, not this issue.The fix is unchanged: add
settings.permissions.tool.shell.title/.descriptionto the i18n bundle, or map the existingbashentries ontoshellin the lookup. The root cause — the bundle hasbashwhile the server emitsshell— is confirmed by the same file (export const name = "shell").ZXLyyds100 commentedon Oct 26, 2026
Implemented in #59405.
settings.permissions.tool.shell.titleand.description, matching the existing shell wording.The change is limited to the missing shell description; the parsed command resources remain visible, and MCP/other permission actions are unchanged. Real before/after captures from the same Chromium fixture are available as before and after.
Implemented and verified with OpenAI Codex assistance. Hosted checks currently pass for standards, compliance, and contributor labeling; human review and any remaining CI are not implied.