omp packages

@yefengr/pi-notify0.3.5

Local terminal notifications for Pi using native OSC protocols

GitHub Actions Published 7 days ago MIT ~1.1K downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

Pi Local Terminal Notify Extension

This is the Pi local terminal notification extension maintained by yefengr. It sends desktop notifications only through notification protocols supported by the current terminal, and does not call terminal-notifier, notify-send, or any other system notification helper.

Supported Scope

Only Pi running directly on the host is considered; containers, SSH, tmux, screen, and zellij are not handled.

Terminal Protocol Title and body
Ghostty OSC 777 Separate
WezTerm OSC 777 Separate
kitty OSC 99 Separate
iTerm2 OSC 9 Merged into one text

Apple Terminal.app, the default Linux terminal, and other terminals that are not on the allowlist do not send notifications. The extension does not fall back to a fixed system icon, and it does not guess whether an unknown terminal is compatible with a given protocol.

A successful terminal protocol write only means the sequence was submitted to the terminal; it does not mean the system has displayed the notification. The terminal's own desktop notification settings still apply.

Notification Levels

The extension uses three semantic levels and sets a default display duration for each level:

Level Typical case Default duration
info Normal completion, session end, test notifications 5 seconds
warning Output reaching the length limit, states that need attention but are not fatal 8 seconds
error Agent, Provider, or tool errors 12 seconds

kitty's OSC 99 encodes the level as u=0/1/2 and requests auto-close through w=5000/8000/12000; timeoutMs in the send result is returned only when that protocol actually carries it. The OSC 777/9 used by Ghostty, WezTerm, and iTerm2 does not support unified level and duration parameters, so it still follows the notification policy of the terminal and the operating system. The extension does not send persistent notifications.

Commands

Command Description
/notify:settings Configure the global switch, Pi lifecycle events, and recap
/notify:recap-model Choose the recap model from the models currently available to Pi
/notify:test Send a test notification and display sent, unsupported, disabled, or failed

All configuration is maintained through commands; manual JSON editing is not required. The actual configuration is stored in:

~/.pi/agent/config/notify.json

Settings UI

/notify:settings opens a single panel that edits a draft copy of the configuration:

  • Enter edits the selected item: switches toggle their value, Recap 模型 opens the model sub-page, and 保存设置 writes the draft to notify.json.
  • Space toggles the selected switch; PageUp/PageDown move by the number of rows actually visible; Esc cancels and never writes the draft.
  • The model sub-page only updates the draft. It never saves by itself, and leaving it does not persist the chosen model.
  • The selected command keys follow the current Pi keybindings; the footer shows the configured bindings and highlights cancel when the panel is narrow.
  • If writing fails, the panel keeps the draft and reports the cause instead of closing.

/notify:recap-model is the independent model command: confirming a model writes it to the configuration immediately, without the draft step. On a terminal too short for a list, the panel only shows a resize hint and the cancel key, and no hidden item can be confirmed, toggled or saved.

Lifecycle Events

The extension listens only to Pi's native lifecycle and does not depend on events emitted by other extensions.

Event Default state Description
agent_end Off A single Agent run ended; it may fire repeatedly on retries
agent_settled On The Agent finished after retries, compaction, and queued continuations all ended
session_shutdown Off The session ended

/notify:settings can change the global switch and the switches for the events above. After the global switch is turned off, lifecycle events are skipped silently and return the disabled state.

agent_settled uses different levels depending on the final run result: normal completion sends info, output reaching the length limit sends warning, and other errors send error. An explicit manual abort does not send a desktop notification.

Agent Tool

Tool name: notify_user

notify_user({
  title: "Build failed",
  message: "TypeScript compilation failed. Check the build log.",
  level: "error"
})

The tool accepts message, an optional title, and an optional level; level may be info, warning, or error, and defaults to info. The tool synchronously returns the following states:

  • sent: the notification sequence has been written to the current terminal;
  • unsupported: the current terminal is not on the supported allowlist, or standard output is not a TTY;
  • disabled: global notifications are turned off;
  • failed: writing the terminal protocol sequence failed.

Only sent triggers the notify:sent event. The returned details and the sent event contain the actual level; only kitty OSC 99 contains the applied timeoutMs.

Recap

Recap is off by default and takes effect only for agent_end and agent_settled notifications of normal completions. Once enabled, the extension sends the last Assistant reply to the model chosen through /notify:recap-model and generates a one-sentence notification summary. Abnormal termination uses the actual error directly and does not call the recap model; an explicit manual abort sends no notification and does not call the recap model.

Before calling the model, the extension first checks whether the current terminal supports notification protocols. When it does not, no model is called and no extra cost is incurred. If the model request fails, no API key is available, or the returned content is empty, the extension falls back to a deterministic lifecycle message.

Enabling recap causes extra model calls and may send content from Assistant replies to the selected model service. Enable it explicitly through /notify:settings.

License

MIT. See LICENSE for details.