# pi-notify Kitty-first completion notifications for Pi. This repository maintains a source import of `@smoose/pi-notify@0.1.1` with local reliability and multi-window improvements. ## Behavior - Waits for Pi's `agent_settled` event, so retries, automatic compaction, and queued follow-ups do not notify early. - Uses Kitty OSC 99 with Base64 payloads, an ID unique to each Pi session, and explicit `a=focus`. - Defaults to `o=always`: notifications remain visible while the originating Kitty window/pane has keyboard focus; clicking a notification returns to that exact source window. - Measures the entire run across automatic retries and ignores runs shorter than three seconds by default. - Emits terminal sequences only in interactive TUI mode, never into JSON, print, or RPC output. - Uses macOS AppleScript outside Kitty and a sanitized OSC 777 fallback outside macOS. The root `my-pi` bundle loads this local source directly. For the unmodified upstream package, use: ```bash pi install npm:@smoose/pi-notify ``` Do not separately install upstream when using the bundle, or notifications will be duplicated. ## Commands - `/notify on`: enable notifications for the current session. - `/notify off`: disable notifications for the current session. - `/notify test`: send a notification immediately; click it to verify exact Kitty-window focus. - `/notify status`: show the active backend, visibility policy, and duration threshold. Command overrides are session-local. Use environment variables for persistent defaults. ## Configuration - `PI_NOTIFY_ENABLED`: `1`/`true` or `0`/`false`; default enabled. - `PI_NOTIFY_TITLE`: title template; default `π - {project}`. - `PI_NOTIFY_BODY`: body template; default `{message}`. - `PI_NOTIFY_MESSAGE_SOURCE`: `assistant`, `user`, or privacy mode `none`; default `assistant`. - `PI_NOTIFY_MESSAGE_MAX`: maximum message characters before ellipsis; default `80`, maximum `500`. - `PI_NOTIFY_MIN_SECONDS`: minimum complete run duration; default `3`, range `0`–`3600`. - `PI_NOTIFY_VISIBILITY`: Kitty policy `unfocused`, `invisible`, or `always`; default `always`. - `PI_NOTIFY_ACTION`: Kitty click action `focus` or `none`; default `focus`. - `PI_NOTIFY_SOUND_CMD`: optional shell command run after the notification. This is trusted local configuration and executes through a shell. Visibility policies: - `unfocused`: notify whenever the originating Kitty window/pane does not have keyboard focus. - `invisible`: notify only when the originating window/pane is not visible. - `always`: notify even while typing in the originating window. Inside tmux, enable passthrough and restart the tmux server after changing the setting: ```tmux set -g allow-passthrough all ``` The active tmux client type is checked so a stale `KITTY_WINDOW_ID` cannot force the Kitty backend for a non-Kitty client. ## Template variables - `{project}`: current directory name. - `{cwd}`: current working directory. - `{model}`: active model as `provider/id`. - `{model_short}`: active model ID. - `{message}`: selected message, or `Ready for input` when source is `none` or text is unavailable. - `{user_message}`: latest user text, truncated. - `{assistant_message}`: latest settled assistant text, truncated. - `{duration}` / `{duration_ms}`: complete duration including retries. - `{status}`: `ready`, or `ready · N tool errors` when tools reported errors. - `{status_icon}`: `✓` or `⚠`. This reports observed tool errors, not a definitive task-success verdict. - `{tool_error_count}`: observed tool error count. Example for multiple projects without exposing assistant text on the lock screen: ```bash export PI_NOTIFY_TITLE='π {status_icon} · {project}' export PI_NOTIFY_MESSAGE_SOURCE=none export PI_NOTIFY_VISIBILITY=unfocused ``` Kitty must be allowed under **System Settings → Notifications**. Self-built or unsigned Kitty binaries may not be able to publish macOS notifications.