Download packages/coding-agent/examples/extensions/notify.ts from SaylorTwift/pi: direct link, hf CLI and curl.
- Browser
- Download file 2.07 kB
-
https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/examples/extensions/notify.ts
- Command line
-
hf download hf://SaylorTwift/pi/packages/coding-agent/examples/extensions/notify.ts
-
curl -L -o notify.ts https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/examples/extensions/notify.ts
2.07 kB
| /** | |
| * 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 "@earendil-works/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) { | |
| // `agent_end` fires after each low-level run; Pi may still retry, compact, | |
| // or continue with queued follow-ups. Notify only after the full run settles. | |
| pi.on("agent_settled", async () => { | |
| notify("Pi", "Ready for input"); | |
| }); | |
| } | |