Created
May 3, 2026 00:16
-
-
Save matiasmasca/30175c93519fd96b469c52758d24cad7 to your computer and use it in GitHub Desktop.
Desktop notification for OpenCode on Linux and MacOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Desktop notification for OpenCode Agent | |
| * for Linux and MacOs | |
| * | |
| * Fox Linux, you will need notify-send and spd-say | |
| * notify-send utility is available on all the major Linux distributions as part of the libnotify library | |
| * spd-say is a command-line client for Speech Dispatcher that converts text to speech. | |
| * | |
| * For MacOs, you will need ´osascript´ and ´say´ | |
| * osacript: it is a command-line invoked application that can run AppleScripts and JavaScript for Automation scripts | |
| * say command: it has been included in macOS since the early days of Mac OS X, building on Apple's text-to-speech technology | |
| // base on the work of Michael Faisst on https://michael.faisst.io/blog/proper-opencode-notifications | |
| */ | |
| import { Plugin } from "@opencode-ai/plugin"; | |
| export const NotificationPlugin: Plugin = async ({ $ }) => { | |
| // const notificationSound = "~/.config/opencode/plugin/notification.mp3"; | |
| const mainSessions = new Set<string>(); | |
| const playNotification = async ( | |
| message: string, | |
| title: string = "OpenCode" | |
| ) => { | |
| const platform = process.platform; | |
| try { | |
| if (platform === 'darwin') { | |
| // macOS: notification via osascript, TTS via say | |
| await $`osascript -e 'display notification "${message}" with title "${title}"'`.catch(() => {}); | |
| await $`say "${message}"`.catch(() => {}); | |
| } else if (platform === 'linux') { | |
| // Linux: fix notify-send argument order and spd-say typo | |
| await $`notify-send --urgency=low "${title}" "${message}"`.catch(() => {}); | |
| await $`spd-say -w "${message}" -l en`.catch(() => {}); | |
| } else { | |
| console.warn(`Notification plugin: Unsupported platform ${platform}`); | |
| } | |
| } catch { | |
| // Ignore errors to prevent plugin crashes | |
| } | |
| }; | |
| return { | |
| event: async ({ event }) => { | |
| // Track main sessions (sessions without a parent) | |
| if (event.type === "session.created") { | |
| const session = event.properties.info; | |
| if (!session.parentID) { | |
| mainSessions.add(session.id); | |
| } | |
| } | |
| // Clean up tracked sessions when deleted | |
| if (event.type === "session.deleted") { | |
| mainSessions.delete(event.properties.info.id); | |
| } | |
| // Notify when main session becomes idle (not subagents) | |
| if (event.type === "session.status") { | |
| const { sessionID, status } = event.properties; | |
| if (status.type === "idle" && mainSessions.has(sessionID)) { | |
| await playNotification("Task completed!", "OpenCode"); | |
| } | |
| } | |
| // Notify when a question is asked | |
| if (event.type === "question.asked") { | |
| await playNotification( | |
| "Question waiting for your input", | |
| "OpenCode" | |
| ); | |
| } | |
| // Notify when permission is requested | |
| if (event.type === "permission.asked") { | |
| await playNotification("Permission required", "OpenCode"); | |
| } | |
| } | |
| }; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Create a package.json in your OpenCode plugin directory (~/.config/opencode/package.json) if you don't have one already, and add the plugin SDK as a dependency: | |
| { | |
| "dependencies": { | |
| "@opencode-ai/plugin": "1.1.28" | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment