@yusukeshib/pi-notify
v0.1.0
Published
Native macOS notifications (via terminal-notifier) when the pi agent finishes a turn — status-aware, focus-aware, click-to-focus.
Downloads
171
Maintainers
Readme
@yusukeshib/pi-notify
A pi extension that fires a native macOS notification when the agent finishes a turn and is ready for your input — powered by terminal-notifier.
Stop babysitting a long run. Switch to another window, and pi taps you on the shoulder when it's done.
What you get
┌─────────────────────────────────────────────┐
│ Pi · ✅ done 12s │
│ Added retry logic to the upload client … │
└─────────────────────────────────────────────┘- Status-aware title —
✅ doneor❌ error, with the elapsed turn time as the subtitle. - Context in the body — a snippet of the agent's last message, so you know what happened without switching tabs.
- Focus-aware — if your terminal is already the frontmost app (you're watching it), the notification is suppressed. No spam while you read.
- Click to return — clicking the notification activates the terminal pi is
running in (via terminal-notifier's
-activate) and brings it to the front. - Graceful fallback — on non-macOS hosts, or when terminal-notifier isn't installed, it falls back to an OSC 777 desktop notification (Ghostty, iTerm2, WezTerm, …).
Install
For the rich macOS path, install terminal-notifier first:
brew install terminal-notifierThen add the extension:
pi install npm:@yusukeshib/pi-notifyVia git (no npm publish required):
pi install git:github.com/yusukeshib/pi-notifyTry it without installing:
pi -e npm:@yusukeshib/pi-notifyCommand
/notify [subcommand]
| Command | Effect |
| ----------------------- | --------------------------------------------------------- |
| /notify | Show current settings and the active backend |
| /notify on / off | Enable / disable notifications |
| /notify sound <name> | Set the notification sound (e.g. Glass, Ping) or off|
| /notify min <seconds> | Only notify for turns at least this long (default 0) |
| /notify focus on/off| Toggle "skip when terminal is frontmost" (default on) |
| /notify test | Fire a test notification right now |
Configuration via environment
Defaults can be set with environment variables; the /notify command overrides
them for the current session.
| Variable | Default | Meaning |
| ----------------------- | ------- | --------------------------------------------- |
| PI_NOTIFY_ENABLED | 1 | Set to 0 to start disabled |
| PI_NOTIFY_MIN_SECONDS | 0 | Minimum turn duration before notifying |
| PI_NOTIFY_SOUND | off | Sound name, or off for silent |
| PI_NOTIFY_FOCUS_SKIP | 1 | Set to 0 to always notify, even when focused|
How it works
The extension tracks each turn via pi's lifecycle events: agent_start resets
timing, tool_execution_end records whether any tool errored, and message_end
captures the agent's last text. On agent_end it composes a status line and
hands it to terminal-notifier.
Focus detection asks macOS (System Events) for the frontmost app's bundle id
and compares it to the terminal pi is running in — resolved from
__CFBundleIdentifier (the bundle id macOS injects into GUI-launched apps,
which survives tmux/ssh better than TERM_PROGRAM), falling back to a
TERM_PROGRAM lookup.
Only interactive (tui) sessions notify; print and JSON modes are skipped.
License
MIT
