Signal
A VS Code extension that plays a sound and can show a desktop notification when an OpenCode response finishes.
Supported: OpenCode v2 services (CLI TUI, desktop app — anything served by the background service) and v1 servers on older OpenCode builds.
Install
From the VS Code Marketplace:
code --install-extension MDX079.opencode-signal
Or search for Signal in the Extensions panel. After an update, reload VS Code if it is already running.
To install a locally packaged .vsix instead:
npm run package:vsix
code --install-extension opencode-signal-<version>.vsix
How It Works
OpenCode runs a local background service (v2). Signal discovers it on the network, authenticates with the service password, and streams its /api/event bus, watching for a session's turn lifecycle to finish (v2: session.execution.succeeded / failed / interrupted; v1: session.status → idle, session.idle, session.error). A finished response plays the completion sound and, optionally, a desktop toast.
- OpenCode v2 services are supported natively: Signal discovers the background service, authenticates with the password from
~/.config/opencode/service.json, and streams /api/event. All sessions served by that service (CLI TUI, desktop app) produce notifications.
- A v1 server's
/config endpoint still carries an opencode.ai marker; those are detected and watched the same way.
- Auto-discovery: every 30 seconds Signal scans local listening ports, probes OpenCode's v2 (
/api/project, 401-until-authenticated) and v1 (/config) signatures, and watches any server it identifies — so the OpenCode desktop app or sessions on other ports are covered too.
- One notification per completion: multiple VS Code windows often watch the same service. The first window to observe a completion notifies; the others skip it (keyed by the event id, with a short expiry so a crashed window can never eat the next notification). Distinct completions always notify.
- Questions and permission prompts alert too: when OpenCode's agent pauses for you — a
question tool form or a permission request — Signal plays the sound and shows a toast reading the session's ask (the question text, or what the action wants to do) instead of staying silent. The body falls back to "OpenCode is asking a question" / "OpenCode requests permission" when the event carries no readable text. Answer or approve in your OpenCode UI as usual; Signal only signals. (v2 wires this through form.created / permission.asked; v1 servers alert on permission.updated.)
- Open the Signal output channel (Output panel) for diagnostics: it logs watched ports, detected completions, and notification failures.
- Use Signal: Open Watched Terminal to start OpenCode from a new terminal.
- Use Signal: Test Sound to verify audio playback.
- Use Signal: Test Desktop Notification to verify that toasts appear. On Windows, Signal registers a per-user notification identity ("Signal (OpenCode)") the first time, because Windows silently drops toasts from unregistered sources. Toasts show Signal's bundled
icon.png. If a toast never appears, check Windows Settings > System > Notifications for "Signal (OpenCode)" and turn off Focus Assist / Do Not Disturb.
- Playback is retried once and falls back to the native Windows sound API if the .NET player fails, so transient audio-device hiccups no longer silence a notification.
- Sounds play first and the desktop notification follows immediately, so they land together instead of sight-then-sound.
- If Kilo Code is installed, Signal disables Kilo Code's separate attention sound so only Signal's sound plays.
- About double sounds: if OpenCode's own attention sound is enabled (
~/.config/opencode/cli.json or tui.json, attention.sound), OpenCode plays its own completion sound in addition to Signal's. Set attention.sound to false there and let Signal be the single source.
Settings
signal.enabled: enable or disable sounds.
signal.defaultPorts: ports to discover automatically (v1 servers).
signal.soundFile: optional custom sound path.
signal.showNotification: also show a VS Code notification.
signal.desktopNotification: show an operating system notification when a response finishes. always (default), unfocused (only when the VS Code window is not focused), or off.
signal.serverUsername / signal.serverPassword: credentials for a v1 server protected by OPENCODE_SERVER_PASSWORD. v2 service passwords are read automatically from ~/.config/opencode/service.json.
In Settings, the Sound File description includes a Browse for a sound file action that opens the native file picker and saves the selected path.
The included sound.wav is bundled and used by default. A custom soundFile overrides it.
Development
npm install
npm test
Press F5 in VS Code to launch an Extension Development Host.
Publish Updates
The publisher token lives outside the repository in %USERPROFILE%\.opencode-signal-pat (a Marketplace PAT with Marketplace > Manage scope) so it can never be packaged into a VSIX or committed. Then:
.\publish.ps1 # runs tests, then publishes the current package.json version
publish.ps1 fails fast if the token file is missing — never commit a token to the repository. Marketplace updates to the same version number are refused for about 7 days, so a new version number is required for every release.