You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FEATURE]:feat(app): support custom slash commands from .opencode/commands in GUI #17048
I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Problem The GUI only supports a hard-coded list of slash commands. Project-level commands defined in .opencode/commands/ (and global commands in ~/.config/opencode/commands/) are ignored. This prevents custom commands and breaks parity with TUI/CLI behavior.
Why this matters I’m building a plugin that relies on a /guard command to toggle a session monitor. In GUI, /guard is sent as normal text to the model and cannot be intercepted, while TUI/CLI can load custom commands from .opencode/commands/.
Expected behavior
GUI should load and register custom commands from:
.opencode/commands/
~/.config/opencode/commands/
Custom commands should appear in the slash menu and execute without sending raw text to the model.
Current behavior
/ping or any custom command shows “no such command” in GUI.
Commands only work in TUI/CLI.
References
GUI commands are hard-coded in packages/app/src/pages/session/use-session-commands.tsx
Command loading is implemented in packages/opencode/src/config/config.ts (loadCommand)
Suggested approach Expose a command list endpoint (or reuse existing config loading) and have GUI register slash commands dynamically from that list.
@adamdotdevin Do you agree this is an appropriate fix or enhancement? I recently encountered this difference between GUI and TUI behavior, and am glad to contribute a PR.
After reading through the source, the GUI infrastructure for custom commands appears to already be implemented:
bootstrap.ts calls sdk.command.list() at startup, which populates sync.data.command
prompt-input.tsx builds the slash popover from sync.data.command alongside builtins
The server-side Command.Service (packages/opencode/src/command/index.ts) loads both inline command: entries from config and file-based .md commands from all config directories (including ~/.config/opencode/command/ and ~/.opencode/command/) via ConfigCommand.load(dir)
The SlashCommand type already has source: "command" | "mcp" | "skill" and the popover renders a badge for custom commands
So the question may be whether the issue is a timing/initialization problem (commands not yet loaded when bootstrap.ts calls list()) rather than a missing implementation.
Workaround in the meantime: Inline command: entries in opencode.json using {file:path} interpolation are the most portable approach and sidestep any directory-scan timing issues:
This works in both TUI and GUI today because the config is loaded before the command service initializes, so the template is available immediately when command.list() is called. File-based .md commands in .opencode/command/ also work but depend on InstanceState being fully initialized first.
Activity
bcdady commentedon May 22, 2026
@adamdotdevin Do you agree this is an appropriate fix or enhancement? I recently encountered this difference between GUI and TUI behavior, and am glad to contribute a PR.
bcdady commentedon May 22, 2026
After reading through the source, the GUI infrastructure for custom commands appears to already be implemented:
bootstrap.tscallssdk.command.list()at startup, which populatessync.data.commandprompt-input.tsxbuilds the slash popover fromsync.data.commandalongside builtinsCommand.Service(packages/opencode/src/command/index.ts) loads both inlinecommand:entries from config and file-based.mdcommands from all config directories (including~/.config/opencode/command/and~/.opencode/command/) viaConfigCommand.load(dir)SlashCommandtype already hassource: "command" | "mcp" | "skill"and the popover renders a badge for custom commandsSo the question may be whether the issue is a timing/initialization problem (commands not yet loaded when
bootstrap.tscallslist()) rather than a missing implementation.Workaround in the meantime: Inline
command:entries inopencode.jsonusing{file:path}interpolation are the most portable approach and sidestep any directory-scan timing issues:{ "command": { "my-command": { "description": "Does something useful", "prompt": "{file:~/.opencode/command/my-command.md}" } } }This works in both TUI and GUI today because the config is loaded before the command service initializes, so the template is available immediately when
command.list()is called. File-based.mdcommands in.opencode/command/also work but depend onInstanceStatebeing fully initialized first.github-actions commentedon Jul 22, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.