/** * quit-aliases — Extra ways to exit pi. * * Adds `/exit` as a slash command and makes the bare words * `exit`, `quit`, `:q` (case-insensitive, any time — even mid-stream) * trigger a clean shutdown, just like the built-in `/quit`. * * Triggers: * /exit — slash command (shows up in `/` autocomplete) * exit | quit | :q — bare words (exact match, trimmed, case-insensitive) * * Both paths call ctx.shutdown(), pi's documented graceful shutdown * ("available in all contexts: event handlers, tools, commands, shortcuts"). * * Install (global, auto-discovered, /reload hot-reloadable): * ~/.pi/agent/extensions/quit-aliases/index.ts → symlinked to this file * * Matching rules: * - Bare words match only when the WHOLE input (trimmed, lowercased) equals * one of the trigger words. `exit now` / `please quit` are NOT matched and * are sent to the agent as normal messages. * - Option B: works any time, including while the agent is generating * (shutdown aborts the in-flight stream gracefully). * - event.source === "extension" is skipped, so another extension's * sendUserMessage("exit") cannot accidentally trigger an exit. * * `/quit` (built-in) is untouched and still works. */ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; const BARE_QUIT_WORDS = new Set(["exit", "quit", ":q"]); export default function (pi: ExtensionAPI) { // /exit — slash-command alias for /quit. No built-in /exit exists, so this // registers cleanly (no /exit:1 / /exit:2 suffix). /quit stays built-in. pi.registerCommand("exit", { description: "Quit pi (alias for /quit)", handler: async (_args, ctx) => { ctx.shutdown(); }, }); // Bare words exit / quit / :q. Fires after the slash-command check, so these // (no leading `/`) reach here. Returning "handled" skips the agent entirely. pi.on("input", (event, ctx) => { if (event.source === "extension") return { action: "continue" }; const text = event.text.trim().toLowerCase(); if (BARE_QUIT_WORDS.has(text)) { ctx.shutdown(); return { action: "handled" }; } return { action: "continue" }; }); }