← Back to Plugins
Tools

Tui Notify

lagrangee By lagrangee 👁 29 views ▲ 0 votes

OpenClaw plugin for macOS desktop notifications when terminal TUI replies finish and Ghostty is unfocused.

GitHub

Install

openclaw plugins install clawhub:openclaw-tui-notify

README

# openclaw-tui-notify

`openclaw-tui-notify` is an OpenClaw plugin for a simple workflow:

- you run `openclaw tui` inside `Ghostty`
- you switch to another app while a reply is still being generated
- when the final assistant reply finishes, you get a macOS notification

It intentionally does not notify for idle shells, tool-call intermediates, or background cron/run sessions.

## Status

This project is currently optimized for:

- macOS
- Ghostty as the terminal
- OpenClaw TUI sessions
- desktop notifications via `terminal-notifier`

## How It Works

The plugin uses two OpenClaw plugin hooks:

1. `before_dispatch`
2. `before_message_write`

It only continues when all of these are true:

- the session looks like a local interactive agent session
- the message is an `assistant` message
- `stopReason === "stop"`
- the reply is not empty
- the reply is not a tool/thinking/control artifact
- the session recently had a matching local `user` turn

After that, `notify-if-away.mjs` checks one thing:

- is the active app still `Ghostty`?

If yes, the notification is suppressed. If not, a macOS notification is sent.

## Why It Only Uses Layer 1

This project deliberately uses a narrow presence check:

- `Ghostty` frontmost or not

It does not currently try to detect:

- which Ghostty tab is focused
- which tmux window is focused
- which tmux pane originally ran the TUI session

That is intentional. In the current OpenClaw event model, this plugin runs inside `openclaw-gateway`, so it does not have a verified canonical tmux pane identity for the reply being written. The repo documents the future conditions required to add pane/window-level matching safely in [spec.md](./spec.md).

## Prerequisites

- OpenClaw with plugin support
- Ghostty
- macOS Accessibility permission for app-focus detection
- [`terminal-notifier`](https://github.com/julienXX/terminal-notifier)

Homebrew example:

```bash
brew install terminal-notifier
```

## Install

### Recommended: ClawHub

Available now. This is the most direct install path for OpenClaw users.

```bash
openclaw plugins install clawhub:openclaw-tui-notify
```

### Package Install: npm

Available now. OpenClaw will also try npm-safe plugin specs.

```bash
openclaw plugins install openclaw-tui-notify
```

### Development Install: git clone

Clone the repo anywhere you like, then install the plugin from the repository root:

```bash
openclaw plugins install --link --dangerously-force-unsafe-install /absolute/path/to/openclaw-tui-notify
```

Then restart OpenClaw Gateway.

## Configuration

Copy [config/config.env.example](./config/config.env.example) to `config.env` in the repo root:

```bash
cp config/config.env.example config.env
```

Supported settings:

- `OPENCLAW_TUI_NOTIFY_ENABLED=true|false`
- `OPENCLAW_TUI_NOTIFY_SOUND=Glass`
- `OPENCLAW_TUI_NOTIFY_DEBUG=true|false`
- `OPENCLAW_TUI_NOTIFY_STATE_DIR=/custom/path`
- `OPENCLAW_TUI_NOTIFY_TERMINAL_NOTIFIER_PATH=/path/to/terminal-notifier`
- `OPENCLAW_TUI_NOTIFY_NON_TUI_CHANNELS=feishu,telegram,...`
- `OPENCLAW_TUI_NOTIFY_SESSION_PREFIXES=agent:`
- `OPENCLAW_TUI_NOTIFY_EXCLUDE_SESSION_TOKENS=:cron:,:run:`
- `OPENCLAW_TUI_NOTIFY_FALLBACK_TITLE=OpenClaw`

Default log directory:

- macOS: `~/Library/Logs/openclaw-tui-notify`
- other systems: `~/.local/state/openclaw-tui-notify`

## Debugging

When `OPENCLAW_TUI_NOTIFY_DEBUG=true`, the project writes:

- `debug.log`

inside `OPENCLAW_TUI_NOTIFY_STATE_DIR`.

Each row includes a `source` field so you can still distinguish plugin-side filtering from notify-script decisions.

These logs use local timestamps with timezone offsets, for example:

```text
2026-04-13T00:22:41.912+08:00
```

## Manual Test

```bash
node notify-if-away.mjs "test-session" "This should appear when Ghostty is not frontmost"
```

## Limitations

- If you stay in Ghostty but switch to another tab or tmux window, the notification is still suppressed.
- OpenClaw currently labels TUI traffic as `webchat` in some environments, so channel metadata alone is not enough to distinguish browser sessions from terminal TUI sessions.
- macOS sleep / Focus modes / notification style can affect whether a banner is visibly shown even when the notification request was successfully sent.

## Notes On Session And Channel Matching

- Notification titles are derived from the trailing segment of `sessionKey`, not hardcoded to a fixed session name.
- The fallback title is configurable through `OPENCLAW_TUI_NOTIFY_FALLBACK_TITLE`.
- Session targeting is configurable through `OPENCLAW_TUI_NOTIFY_SESSION_PREFIXES` and `OPENCLAW_TUI_NOTIFY_EXCLUDE_SESSION_TOKENS`.
- Explicit non-TUI channels are configurable through `OPENCLAW_TUI_NOTIFY_NON_TUI_CHANNELS`.

## Repository Layout

- [index.ts](./index.ts): OpenClaw plugin entry
- [notify-if-away.mjs](./notify-if-away.mjs): away check + notification sender
- [package.json](./package.json): publishable package metadata
- [openclaw.plugin.json](./openclaw.plugin.json): OpenClaw plugin metadata
- [config/config.env.example](./config/config.env.example): local config template
- [spec.md](./spec.md): design notes, constraints, and future directions

## License

MIT
tools

Comments

Sign in to leave a comment

Loading comments...