This guide shows how to create an OpenCode CLI plugin that plays an audio notification when OpenCode needs user permissions. The solution consists of two components:
- A shell script to play system audio
- An OpenCode plugin that listens for the
permission.askedevent
Create ~/opencode-notify.sh:
#!/bin/bash
# Plays system notification sound
if command -v aplay &> /dev/null; then
# Linux (ALSA)
aplay /usr/share/sounds/freedesktop/stereo/message.oga
elif command -v afplay &> /dev/null; then
# macOS
afplay /System/Library/Sounds/Glass.aiff
elif command -v powershell.exe &> /dev/null; then
# WSL2 on Windows
powershell.exe -c "[System.Media.SystemSounds]::Asterisk.Play()" 2>/dev/null
fiMake it executable:
chmod +x ~/opencode-notify.shTest it:
~/opencode-notify.shmkdir -p ~/.config/opencode/pluginCreate ~/.config/opencode/plugin/notify.js:
import { exec } from "child_process";
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return {
event: async ({ event }) => {
if (event.type === "permission.asked") {
exec("~/opencode-notify.sh");
}
},
};
};Restart OpenCode. Verify plugin loading:
opencode debug configYou should see:
{
"plugin": [
"file:///home/<user>/.config/opencode/plugin/notify.js"
]
}SEE: https://opencode.ai/docs/plugins/
Extend your plugin to handle multiple events:
export const NotificationPlugin = async (ctx) => {
return {
event: async ({ event }) => {
// Permission requested
if (event.type === "permission.asked") {
exec("~/opencode-notify.sh");
}
// Session idle
if (event.type === "session.idle") {
exec("~/opencode-notify.sh");
}
// Prompt appended
if (event.type === "tui.prompt.append") {
exec("~/opencode-notify.sh");
}
},
};
};Test your notification script:
~/opencode-notify.shCheck plugin syntax:
node -c ~/.config/opencode/plugin/notify.jsAdd debug logging:
import { appendFileSync } from "fs";
const LOG_FILE = "/home/<user>/opencode-notify.log";
export const NotificationPlugin = async (ctx) => {
return {
event: async ({ event }) => {
appendFileSync(LOG_FILE, `${new Date().toISOString()} - ${event.type}\n`);
if (event.type === "permission.asked") {
exec("~/opencode-notify.sh");
}
},
};
};- OpenCode fires the
permission.askedevent when requiring permission - The plugin receives the event and executes
~/opencode-notify.sh - The script plays the appropriate system notification sound
- You get alerted acoustically even when the terminal is in the background
Visual Notification with MessageBox:
#!/bin/bash
powershell.exe -c "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('OpenCode needs your attention', 'OpenCode')"Combine Audio + Visual:
#!/bin/bash
powershell.exe -c "[System.Media.SystemSounds]::Asterisk.Play()"
powershell.exe -c "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('OpenCode needs your attention', 'OpenCode')"
If you want to have fun ๐ on macos you can use
say --voice="Zarvox" Waiting๐ there are quite funny voices you can use and also you can replaceWaitingwith whatever phrase you want.Also opencode released Desktop app which have notifications build in as alternative to TUI.