plugins: Add OSC 99 desktop notification plugin for OpenCode
This commit is contained in:
parent
a3db357b6f
commit
eef9a66d2d
1 changed files with 70 additions and 0 deletions
70
plugins/opencode/osc99-notify.js
Normal file
70
plugins/opencode/osc99-notify.js
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// OSC 99 Desktop Notifications for OpenCode
|
||||
//
|
||||
// Sends desktop notifications via the OSC 99 escape sequence protocol
|
||||
// when OpenCode needs your attention. Notifications are only shown when
|
||||
// the terminal window is unfocused (o=unfocused).
|
||||
//
|
||||
// Tested with: Kitty terminal
|
||||
// May also work with other terminals that support the OSC 99 protocol.
|
||||
//
|
||||
// Features:
|
||||
// - Notifies when a session goes idle (waiting for your input)
|
||||
// - Notifies when a question is asked (e.g. multiple choice)
|
||||
// - Notifies when a permission prompt is raised
|
||||
// - Notifies when a session error occurs
|
||||
// - Includes the project directory name in the notification title
|
||||
// - Suppresses notifications from subagent sessions (e.g. Explore Task)
|
||||
// - Suppresses notifications when the terminal window is focused
|
||||
// - Uses distinct sounds per notification type (system, question, error)
|
||||
//
|
||||
// Installation:
|
||||
// Copy this file to ~/.config/opencode/plugins/osc99-notify.js
|
||||
//
|
||||
// Notification types:
|
||||
// Idle: title -> OpenCode (project-name)
|
||||
// body -> Waiting for your input
|
||||
// sound -> system
|
||||
//
|
||||
// Question: title -> OpenCode (project-name)
|
||||
// body -> Has a question for you
|
||||
// sound -> question
|
||||
//
|
||||
// Permission: title -> OpenCode (project-name)
|
||||
// body -> Needs your permission
|
||||
// sound -> question
|
||||
//
|
||||
// Error: title -> OpenCode (project-name)
|
||||
// body -> Encountered an error
|
||||
// sound -> error
|
||||
|
||||
export const OSC99Notify = async ({ client }) => {
|
||||
const path = require('path')
|
||||
const project = path.basename(process.cwd())
|
||||
let id = 0
|
||||
|
||||
const notify = (icon, message, sound = 'system') => {
|
||||
id++
|
||||
process.stderr.write(`\x1b]99;i=${id}:d=0:s=${sound}:o=unfocused;${icon} OpenCode (${project})\x1b\\`)
|
||||
process.stderr.write(`\x1b]99;i=${id}:p=body;${message}\x1b\\`)
|
||||
}
|
||||
|
||||
return {
|
||||
event: async ({ event }) => {
|
||||
if (event.type === "message.part.updated" && event.properties.part.type === "tool" && event.properties.part.tool === "question" && event.properties.part.state?.status === "pending")
|
||||
notify('❓', 'Has a question for you', 'question')
|
||||
|
||||
if (event.type === "session.idle") {
|
||||
const session = await client.session.get({ path: { id: event.properties.sessionID } })
|
||||
if (!session.data?.parentID)
|
||||
notify('🤖', 'Waiting for your input')
|
||||
}
|
||||
if (event.type === "session.error") {
|
||||
const session = await client.session.get({ path: { id: event.properties.sessionID } })
|
||||
if (!session.data?.parentID)
|
||||
notify('🚨', 'Encountered an error', 'error')
|
||||
}
|
||||
if (event.type === "permission.updated")
|
||||
notify('🔐', 'Needs your permission', 'question')
|
||||
},
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue