# notify-on-stop

Plays a sound, speaks a message, or fires a desktop notification every time the pi agent finishes a turn (`agent_end` event). Cuts the "is it done yet?" tab-switching tax.

Ships as part of [`@astrofoundry/pi-astro`](../../README.md). No extra install.

## Default: off

The extension does **nothing** by default. Enable it once with:

```
/notify on
```

State is persisted to `~/.pi/agent/notify-on-stop.json` and survives session restarts and `chezmoi apply`. To turn it back off:

```
/notify off
```

## Commands

| Command | Effect |
|---|---|
| `/notify on` | Enable for this and future sessions. Persists. |
| `/notify off` | Disable for this and future sessions. Persists. |
| `/notify` or `/notify status` | Print current state and the resolved command |
| `/notify test` | Run the resolved command immediately, regardless of on/off state |

Argument autocomplete is wired — type `/notify ` and tab-cycle.

## Defaults per platform

When enabled, the extension runs:

| Platform | Command |
|---|---|
| macOS | `afplay /System/Library/Sounds/Glass.aiff && say -v "Samantha (Enhanced)" "Agent done"` |
| Linux | `notify-send "pi" "Agent done"` (only if `notify-send` exists on `PATH`) |
| Windows / other | Nothing — wire your own command via `PI_STOP_NOTIFY` |

Errors from the notify command are swallowed — a broken sound or missing voice will never surface in pi output.

## macOS voice setup (one-time)

The default speaks via the `Samantha (Enhanced)` voice. If it isn't installed, the `say` command silently fails and you only hear the Glass sound. Install it once:

1. **System Settings → Accessibility → Spoken Content → System Voice → Manage Voices…**
2. Expand **English**, check **Samantha (Enhanced)**, click **Done** (downloads ~500 MB – 1 GB).
3. Verify: `say -v "Samantha (Enhanced)" hi`.

If you'd rather skip the install, override with `PI_STOP_NOTIFY_VOICE` or replace the whole command via `PI_STOP_NOTIFY` — see below.

## Configuration (env vars)

Env vars control **what** runs, not **whether**. The on/off toggle is `/notify on|off`.

Set in your shell rc (`.zshrc`/`.bashrc`) so they apply to every pi session.

### `PI_STOP_NOTIFY` — replace the full command

Wins over the platform default. Wins over `PI_STOP_NOTIFY_VOICE`.

```bash
# Just play the sound, no speech
export PI_STOP_NOTIFY='afplay /System/Library/Sounds/Glass.aiff'

# Speak something custom
export PI_STOP_NOTIFY='say "Pi just finished, get back here"'

# Linux: dunst / libnotify
export PI_STOP_NOTIFY='notify-send "pi" "Done" -u low'
```

### `PI_STOP_NOTIFY_VOICE` — change only the macOS voice

Used when you keep the default Glass+say behaviour but prefer a different voice. Ignored on Linux/Windows. Ignored when `PI_STOP_NOTIFY` is set.

```bash
export PI_STOP_NOTIFY_VOICE="Alex"
export PI_STOP_NOTIFY_VOICE="Daniel (Enhanced)"
export PI_STOP_NOTIFY_VOICE="Karen"
```

List available voices: `say -v ?`.

### `PI_STOP_NOTIFY_OFF=1` — hard kill

Overrides the persisted on/off state. Useful for CI / headless runs where you want the extension globally muted regardless of the state file.

```bash
export PI_STOP_NOTIFY_OFF=1
```

## Quick recipes

| Goal | What to do |
|---|---|
| Enable | `/notify on` |
| Disable | `/notify off` |
| Test the command without changing state | `/notify test` |
| Sound only, no voice | `PI_STOP_NOTIFY='afplay /System/Library/Sounds/Glass.aiff'` |
| Voice only, no sound | `PI_STOP_NOTIFY='say "Done"'` |
| Different macOS voice | `PI_STOP_NOTIFY_VOICE="Alex"` |
| Custom desktop notification | `PI_STOP_NOTIFY='terminal-notifier -title pi -message Done -sound Glass'` |
| Hard-mute everywhere | `export PI_STOP_NOTIFY_OFF=1` |

## Troubleshooting

- **`/notify on` says "no command resolves on this platform"** — Windows or unknown platform. Set `PI_STOP_NOTIFY` to your own command.
- **Nothing happens on macOS even though `/notify status` shows `on`** — the Samantha (Enhanced) voice is probably missing. Either install it (above) or set `PI_STOP_NOTIFY_VOICE` to a voice you have. Run `/notify test` to see whether the command itself runs.
- **Nothing happens on Linux** — install `libnotify` (`apt install libnotify-bin`) or override `PI_STOP_NOTIFY`.
- **`/notify status` shows the right command but nothing happens** — the command is launched via `/bin/sh` with a 10-second timeout, and all errors are silenced. Run the command directly in a shell to see the real error.
- **Env-var changes don't take effect** — env vars are read once when the extension loads. Restart pi after changing them. The on/off state, by contrast, applies immediately.
