mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 21:03:19 +00:00
- Add OSC 99 notification support for Kitty terminal (detected via KITTY_WINDOW_ID) - Add Windows toast notifications for Windows Terminal/WSL (detected via WT_SESSION) - Refactor into separate functions for each notification method - OSC 777 remains the fallback for Ghostty, iTerm2, WezTerm, rxvt-unicode Co-authored-by: Soleone (Windows Terminal support)
55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
/**
|
|
* Pi Notify Extension
|
|
*
|
|
* Sends a native terminal notification when Pi agent is done and waiting for input.
|
|
* Supports multiple terminal protocols:
|
|
* - OSC 777: Ghostty, iTerm2, WezTerm, rxvt-unicode
|
|
* - OSC 99: Kitty
|
|
* - Windows toast: Windows Terminal (WSL)
|
|
*/
|
|
|
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
|
|
function windowsToastScript(title: string, body: string): string {
|
|
const type = "Windows.UI.Notifications";
|
|
const mgr = `[${type}.ToastNotificationManager, ${type}, ContentType = WindowsRuntime]`;
|
|
const template = `[${type}.ToastTemplateType]::ToastText01`;
|
|
const toast = `[${type}.ToastNotification]::new($xml)`;
|
|
return [
|
|
`${mgr} > $null`,
|
|
`$xml = [${type}.ToastNotificationManager]::GetTemplateContent(${template})`,
|
|
`$xml.GetElementsByTagName('text')[0].AppendChild($xml.CreateTextNode('${body}')) > $null`,
|
|
`[${type}.ToastNotificationManager]::CreateToastNotifier('${title}').Show(${toast})`,
|
|
].join("; ");
|
|
}
|
|
|
|
function notifyOSC777(title: string, body: string): void {
|
|
process.stdout.write(`\x1b]777;notify;${title};${body}\x07`);
|
|
}
|
|
|
|
function notifyOSC99(title: string, body: string): void {
|
|
// Kitty OSC 99: i=notification id, d=0 means not done yet, p=body for second part
|
|
process.stdout.write(`\x1b]99;i=1:d=0;${title}\x1b\\`);
|
|
process.stdout.write(`\x1b]99;i=1:p=body;${body}\x1b\\`);
|
|
}
|
|
|
|
function notifyWindows(title: string, body: string): void {
|
|
const { execFile } = require("child_process");
|
|
execFile("powershell.exe", ["-NoProfile", "-Command", windowsToastScript(title, body)]);
|
|
}
|
|
|
|
function notify(title: string, body: string): void {
|
|
if (process.env.WT_SESSION) {
|
|
notifyWindows(title, body);
|
|
} else if (process.env.KITTY_WINDOW_ID) {
|
|
notifyOSC99(title, body);
|
|
} else {
|
|
notifyOSC777(title, body);
|
|
}
|
|
}
|
|
|
|
export default function (pi: ExtensionAPI) {
|
|
pi.on("agent_end", async () => {
|
|
notify("Pi", "Ready for input");
|
|
});
|
|
}
|