opencode-quick-reply
v1.0.0
Published
Suggest contextual replies when OpenCode agents are waiting for user input.
Maintainers
Readme
OpenCode Quick Reply
An OpenCode plugin that suggests contextual replies whenever an agent is waiting for your input — approval requests, confirmation prompts, clarifications, or multiple-choice questions. Suggestions land in your prompt buffer so you can accept, edit, or ignore them. Replies are never sent automatically; you always stay in control.
Think "Peek & Reply," built on OpenCode's plugin API.
Status — CLI/TUI only. This plugin works in the OpenCode CLI/TUI, where it appends suggestions to the prompt and shows a toast. The OpenCode Desktop app does not currently expose a plugin API for writing to its prompt input (it does not honor the
tui.prompt.append/tui.toast.showevents that the CLI TUI does), so suggestions are generated but not surfaced there. Desktop support is paused until OpenCode adds such an API.
Table of contents
- Requirements
- How it works
- Install
- Configuration
- Usage
- Architecture
- Known limitations
- Contributing
- Releasing
- License
Requirements
- OpenCode (any recent version that supports the
permission.askhook andsession.idleevent). - At least one provider configured in OpenCode (the plugin reuses your existing models and credentials — no separate API key required).
How it works
- The plugin listens for the
permission.askhook andsession.idleevents. - When the agent is waiting, it collects recent conversation context.
- It asks a lightweight model — via a short-lived OpenCode session — for the most likely helpful reply, reusing your already-configured provider and model.
- It shows a toast and appends the suggestion to your prompt buffer for you to edit and send.
Generation is debounced per session, cached per assistant turn, and aborted if the conversation moves on or the plugin is unloaded — so you never get stale or duplicate suggestions.
Install
From npm (recommended)
Add the plugin to your OpenCode config (opencode.json). OpenCode installs npm
plugins automatically at startup:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-quick-reply"]
}From local files
git clone https://github.com/tufantunc/opencode-quick-reply.git
cd opencode-quick-reply
bun install && bun run buildThen copy dist/index.js into .opencode/plugins/quick-reply.js (project-level) or
~/.config/opencode/plugins/quick-reply.js (global).
Configuration
Important: OpenCode's config schema is strict and rejects unknown top-level keys — so do not add a
quickReplyblock toopencode.json(it throwsConfigInvalidError). Configure via the plugin options tuple and/orQUICKREPLY_*environment variables. Defaults work with no configuration at all.
Via plugin options (npm installs)
Pass options as the second element of a [name, options] tuple in the plugin
array — OpenCode forwards them to the plugin:
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
["opencode-quick-reply", { "model": "anthropic/claude-haiku-4-5", "debounceMs": 600 }]
]
}Via environment variables (works for local-file installs too)
export QUICKREPLY_MODEL=anthropic/claude-haiku-4-5
export QUICKREPLY_DEBOUNCE_MS=600| Option | Env var | Default | Description |
| --- | --- | --- | --- |
| enabled | QUICKREPLY_ENABLED | true | Enable or disable the plugin |
| model | QUICKREPLY_MODEL | none | provider/modelID for suggestions (a small/fast model is recommended) |
| systemPrompt | QUICKREPLY_SYSTEM_PROMPT | built-in | Override the generation instruction |
| maxContextMessages | QUICKREPLY_MAX_CONTEXT_MESSAGES | 12 | Recent messages sent as context (capped at 50) |
| debounceMs | QUICKREPLY_DEBOUNCE_MS | 600 | Debounce window in ms before generating |
Environment variables take precedence over plugin options, which take precedence over
defaults. For a local-file install (no plugin array entry), use env vars.
Suggested lightweight models
Pick a small, fast, cheap model to keep latency and cost low:
anthropic/claude-haiku-4-5openai/gpt-4o-mini
Usage
There is nothing to invoke manually. When an agent asks a question or requests
approval, you'll see a toast and the suggested reply will be appended to your prompt.
Edit it (or delete it) and press Enter to send. You stay in control at all times.
To disable temporarily, set enabled: false (or QUICKREPLY_ENABLED=false) and
reload OpenCode.
Architecture
A dependency-injected pipeline of single-responsibility modules. Every collaborator
is hidden behind a narrow interface (port) typed as a Pick of the OpenCode client,
so each unit is testable in isolation and the SDK boundary is fully compile-time
checked.
permission.ask hook ─┐
session.idle event ──┴─> WaitingStateDetector (debounced)
└─> SuggestionService ─> ContextCollector ─> cache check
└─> LlmGenerator (OpenCode temp session) ─> SuggestionPresenter (toast + appendPrompt)src/
index.ts Plugin entry; dependency wiring; permission.ask / event / dispose hooks
config/ Zod-validated config (JSON block + env-var overrides)
types.ts Shared SDK client type (OpencodeClient)
util/ hash/redaction helpers, structured logger
cache/ Per-session suggestion cache (LRU-bounded)
context/ Conversation context collector (message-bounded)
detector/ Debounced waiting-state detector with resume-suppression
listener/ Defensive event normalization
llm/ LlmGenerator interface + OpenCode-native implementation
notification/ Toast/append service + pluggable SuggestionPresenter
suggestion/ Orchestration: in-flight dedup, staleness (epoch), caching, error handlingKey seams designed for future extension:
LlmGenerator— swap in a direct HTTP (OpenAI-compatible) generator behind the same interface.SuggestionPresenter— swap in a keybind-based presenter when OpenCode exposes a plugin keybind API.
Known limitations
- Desktop app not supported (yet). The plugin's presentation uses the TUI prompt
API (
tui.appendPrompt/tui.showToast). The CLI/TUI honors these; the OpenCode Desktop renderer currently does not, so suggestions are produced but never shown in Desktop. This is an OpenCode platform gap, not a plugin bug — pending an API for plugins to reach the Desktop prompt. - No custom keybinds. OpenCode does not yet expose a plugin keybind API, so
"Tab to accept" is not possible. Suggestions are appended to the prompt buffer
instead. The
SuggestionPresenterseam makes a future keybind path a drop-in. - Cannot read the prompt buffer. The TUI API can append/submit/clear but not read the prompt, so suggestions are always appended.
- Temporary-session overhead. Each suggestion creates a short-lived session that is deleted immediately; a lightweight model keeps this cheap. The plugin ignores events from its own temp sessions to avoid recursive generation.
- Event payload shapes are normalized defensively; exact
session.idle/permission.repliedproperty shapes may vary across OpenCode versions. - Runtime enable/disable. Plugins have no command hook, so toggling is
config-driven (reload to change). A
/quick-replycommand is a future enhancement.
Contributing
Contributions are welcome! Please read the contributing guide for development setup, conventions, and the pull-request process. All participants are expected to follow the Code of Conduct.
Releasing
Releases are automated via release-please
on Conventional Commits pushed to main:
- Merging
feat:/fix:/perf:commits opens a release PR that bumpspackage.jsonand updatesCHANGELOG.md. - Merging the release PR creates a
vX.Y.Ztag + GitHub Release. - The GitHub Release triggers the Publish to npm workflow, which builds and publishes to npm (with provenance).
License
MIT © tufantunc
