@gamaraan/desktop-notify
v0.1.0
Published
Cross-platform terminal and desktop notifications for pi coding-agent.
Maintainers
Readme
@gamaraan/desktop-notify
A self-contained pi extension that surfaces completion, error, and model-requested notifications through terminal protocols and best-effort native desktop toasts.
Features
- Kitty OSC 99, OSC 9, and BEL terminal output.
- tmux passthrough, Zellij BEL fallback, and cmux surface routing.
- Linux
notify-send→gdbus, macOS/usr/bin/osascript, native Windowspowershell.exeWinRT toast, and WSL Windows-host routing with Linux fallback. - Completion/error delivery at
agent_settled, so retries and queued follow-ups produce one final notification. - Side-effect-free programmatic client at
@gamaraan/desktop-notify/client. - Optional LLM-callable
notifytool, disabled by default. - No helper installation, shell lookup, raw stdin listener, or terminal probe.
Desktop delivery is deliberately best-effort. In-band output is emitted first; missing binaries, locked-down desktops, unavailable session buses, and child launch failures are silent.
Install
pi install npm:@gamaraan/desktop-notifyFrom a checkout, add the package or src/index.ts to the pi extension list.
Restart pi after changing extension configuration.
Configuration
Flags take precedence over environment variables, which take precedence over built-in defaults:
| Flag | Environment | Default | Meaning |
| --- | --- | --- | --- |
| --notify-completion on\|off | PI_NOTIFY_COMPLETION | on | Final successful settlement |
| --notify-error on\|off | PI_NOTIFY_ERROR | on | Final error settlement |
| --notify-tool on\|off | PI_NOTIFY_TOOL | off | Register the model tool |
Global and desktop controls:
| Variable | Effect |
| --- | --- |
| PI_NOTIFICATIONS=off\|0\|false | Suppress all terminal and desktop output |
| PI_NO_DESKTOP_NOTIFY=1 | Keep terminal output, suppress desktop fan-out |
| PI_NOTIFY_PLATFORM=auto\|linux\|macos\|windows\|wsl\|off | Select or disable desktop strategy |
| PI_NOTIFY_OSC99_RICH=1 | Opt into structured Kitty OSC 99 metadata |
Every notification requires a TTY. Print, JSON, and RPC contexts are silent. The extension never automatically produces a waiting-for-input notification; ask-tool owns that future EventBus request.
EventBus integration
Sibling extensions remain standalone and do not import this package. When both are loaded, they may broadcast a string or documented object:
pi.events.emit("desktop-notify:request", {
title: "Ask",
body: "Waiting for input",
type: "ask",
});Without a listener this is a no-op. Keep the existing ctx.ui.notify behavior;
EventBus delivery is additive and best-effort. Do not use a dynamic-import
recipe or make desktop-notify a required dependency.
Client API
import { notify, isAvailable } from "@gamaraan/desktop-notify/client";
if (isAvailable()) notify({ title: "Build", body: "Complete" });The client imports no pi registration APIs. It validates plain objects, bounds fields, and sanitizes terminal-bound text before dispatch.
Native delivery limitations
- Linux needs a session D-Bus address or
$XDG_RUNTIME_DIR/busand eithernotify-sendorgdbusonPATH. - macOS uses only the built-in
/usr/bin/osascript. - Windows uses one static, base64-fed PowerShell WinRT command. Delivery can be unavailable on locked-down, Server Core, or hosts without an interactive notification identity; no third-party PowerShell module is installed.
- WSL prefers a resolved
powershell.exehost path and otherwise tries Linux D-Bus. A mocked CI test proves routing, not native toast delivery.
Before a release, run the manual smoke checklist in AGENTS.md on available
Linux, macOS, Windows, and WSL hosts. Record OS, terminal, multiplexer, and
result in release notes.
Development
bun install --frozen-lockfile
bun run typecheck
bun test
bun run verify:packageTests use an injected runtime and never spawn real notifiers. See
AGENTS.md for architecture, guardrails, parity notes, CI, and
future improvements. The detailed implementation blueprint is
IMPLEMENTATION_PLAN.md.
License
MIT. See LICENSE. Notification behavior is ported from Oh My Pi, which is itself a pi fork; their copyright notices are retained.
