Feature hasn't been suggested before.
Describe the enhancement you want to request
Dictation and voice input are highly requested (#4695, #9264, #11345), but implementing them as a plugin is currently difficult to deliver a reasonable user experience due to three missing extension points. This means every voice implementation either forks core (#11345) or lives entirely outside OpenCode (#4695 comment thread workarounds with Raycast, Handy, etc.).
The same gaps also block other categories of plugins — anything that needs to react to UI state, inject input, or clean up resources.
Gap 1: No active session awareness
Plugins receive sessionID in several hooks, but there is no way to know:
- Which session is currently focused in the UI
- When the user switches sessions (
tui.session.select exists internally but isn't surfaced to plugins)
Minimal addition: Surface session.focus / session.blur events through the plugin event hook, or provide a query like getActiveSession() on PluginInput.
Gap 2: No plugin-triggered input injection or custom keybinds
Plugins can intercept outbound flows but cannot inject input into the UI:
- No hook to register custom keybindings (TUI
Config.Keybinds schema is .strict())
- No API to programmatically insert text into the user's input box (while plugins can send messages or intercept outgoing chat, they cannot stage text for the user to review/edit before sending)
- No way to register commands in the web UI command palette
Minimal addition: A command hook for registering plugin commands (with optional keybind), and an input.inject method on PluginInput to programmatically insert text.
Gap 3: No shutdown/dispose lifecycle hook (previously requested in #10524 and #10003)
Plugins cannot clean up when OpenCode exits. For dictation, this leaves audio recording processes running.
Minimal addition: A shutdown hook in the Hooks interface, called before Instance.dispose().
Summary of proposed additions
export interface Hooks {
// Existing hooks...
// New: cleanup before exit (refs #10524, #10003)
shutdown?(): Promise<void>
// New: register commands (with optional keybind)
command?(): CommandDefinition[]
}
Plus surfacing session.focus / session.blur through the existing event hook, and an input.inject() helper on PluginInput.
These additions would allow dictation (and other resource-heavy or UI-interacting features) to exist purely as plugins rather than requiring forks of core.
Feature hasn't been suggested before.
Describe the enhancement you want to request
Dictation and voice input are highly requested (#4695, #9264, #11345), but implementing them as a plugin is currently difficult to deliver a reasonable user experience due to three missing extension points. This means every voice implementation either forks core (#11345) or lives entirely outside OpenCode (#4695 comment thread workarounds with Raycast, Handy, etc.).
The same gaps also block other categories of plugins — anything that needs to react to UI state, inject input, or clean up resources.
Gap 1: No active session awareness
Plugins receive
sessionIDin several hooks, but there is no way to know:tui.session.selectexists internally but isn't surfaced to plugins)Minimal addition: Surface
session.focus/session.blurevents through the plugineventhook, or provide a query likegetActiveSession()onPluginInput.Gap 2: No plugin-triggered input injection or custom keybinds
Plugins can intercept outbound flows but cannot inject input into the UI:
Config.Keybindsschema is.strict())Minimal addition: A
commandhook for registering plugin commands (with optional keybind), and aninput.injectmethod onPluginInputto programmatically insert text.Gap 3: No shutdown/dispose lifecycle hook (previously requested in #10524 and #10003)
Plugins cannot clean up when OpenCode exits. For dictation, this leaves audio recording processes running.
Minimal addition: A
shutdownhook in theHooksinterface, called beforeInstance.dispose().Summary of proposed additions
Plus surfacing
session.focus/session.blurthrough the existingeventhook, and aninput.inject()helper onPluginInput.These additions would allow dictation (and other resource-heavy or UI-interacting features) to exist purely as plugins rather than requiring forks of core.