# quit-aliases

A tiny [pi](https://pi.dev/) extension that adds more ways to exit.

## Triggers

| Input | When it exits |
| --- | --- |
| `/exit` | Slash command (appears in `/` autocomplete + command list) |
| `exit` | Bare word, exact match (trimmed, case-insensitive) |
| `quit` | Bare word, exact match |
| `:q` | Bare word, exact match |

`/quit` (pi's built-in) is untouched and still works.

All four triggers call `ctx.shutdown()` — pi's documented graceful shutdown, available in all contexts (event handlers, tools, commands, shortcuts).

## Matching rules (bare words)

- The **whole** input must equal the trigger word, after trimming and lowercasing. So `Exit`, ` QUIT `, `:Q` all exit; `exit now`, `please quit`, `just :q it` do **not** exit (they go to the agent as normal messages).
- **Option B — any time**: works even while the agent is generating. The shutdown aborts the in-flight stream gracefully.
- `event.source === "extension"` is skipped, so another extension calling `sendUserMessage("exit")` cannot accidentally trigger an exit.

## How it works

Two hooks:

1. `pi.registerCommand("exit", …)` — registers `/exit`. No built-in `/exit` exists, so it registers cleanly (no `/exit:1`/`/exit:2` suffix). Its handler calls `ctx.shutdown()`.
2. `pi.on("input", …)` — catches the bare words. The `input` event fires after the slash-command check (so bare words with no `/` reach it) and before skill/template expansion. On a match it calls `ctx.shutdown()` and returns `{ action: "handled" }` so the word is never sent to the agent.

## Install

Install from npm (global, auto-discovered):

```sh
pi install npm:pi-quit-aliases
```

Project-local (writes to `.pi/settings.json`, shared with your team):

```sh
pi install -l npm:pi-quit-aliases
```

Or install from git:

```sh
pi install git:github.com/ymy88/pi-quit-aliases
```

Then in pi: run `/reload` (or restart pi) to load it.

## Verify

After `/reload`:

- `/exit` → exits
- `exit`, `quit`, `:q`, `Exit`, ` QUIT ` → each exits
- `exit now` → does **not** exit (goes to the agent)
- `/quit` → still exits (built-in, untouched)
