Improve hooks.md UI documentation

- Add 'Key capabilities' section highlighting UI features
- Expand ctx.ui docs with custom component details
- Reference snake.ts example for custom UI
This commit is contained in:
Mario Zechner 2025-12-31 13:02:28 +01:00
parent 88e39471ea
commit 29e0ed9cd1

View file

@ -2,14 +2,21 @@
Hooks are TypeScript modules that extend pi's behavior by subscribing to lifecycle events. They can intercept tool calls, prompt the user, modify results, inject messages, and more. Hooks are TypeScript modules that extend pi's behavior by subscribing to lifecycle events. They can intercept tool calls, prompt the user, modify results, inject messages, and more.
**Example use cases:** **Key capabilities:**
- Block dangerous commands (permission gates for `rm -rf`, `sudo`) - **User interaction** - Hooks can prompt users via `ctx.ui` (select, confirm, input, notify)
- Checkpoint code state (git stash at each turn, restore on branch) - **Custom UI components** - Full TUI components with keyboard input via `ctx.ui.custom()`
- Protect paths (block writes to `.env`, `node_modules/`) - **Custom slash commands** - Register commands like `/mycommand` via `pi.registerCommand()`
- Inject messages from external sources (file watchers, webhooks) - **Event interception** - Block or modify tool calls, inject context, customize compaction
- Custom slash commands and UI components - **Session persistence** - Store hook state that survives restarts via `pi.appendEntry()`
See [examples/hooks/](../examples/hooks/) for working implementations. **Example use cases:**
- Permission gates (confirm before `rm -rf`, `sudo`, etc.)
- Git checkpointing (stash at each turn, restore on `/branch`)
- Path protection (block writes to `.env`, `node_modules/`)
- External integrations (file watchers, webhooks, CI triggers)
- Interactive tools (games, wizards, custom dialogs)
See [examples/hooks/](../examples/hooks/) for working implementations, including a [snake game](../examples/hooks/snake.ts) demonstrating custom UI.
## Quick Start ## Quick Start
@ -388,7 +395,9 @@ Every handler receives `ctx: HookContext`:
### ctx.ui ### ctx.ui
UI methods for user interaction: UI methods for user interaction. Hooks can prompt users and even render custom TUI components.
**Built-in dialogs:**
```typescript ```typescript
// Select from options // Select from options
@ -403,19 +412,31 @@ const ok = await ctx.ui.confirm("Delete?", "This cannot be undone");
const name = await ctx.ui.input("Name:", "placeholder"); const name = await ctx.ui.input("Name:", "placeholder");
// Returns string or undefined if cancelled // Returns string or undefined if cancelled
// Notification // Notification (non-blocking)
ctx.ui.notify("Done!", "info"); // "info" | "warning" | "error" ctx.ui.notify("Done!", "info"); // "info" | "warning" | "error"
```
// Custom component with keyboard focus **Custom components:**
For full control, render your own TUI component with keyboard focus:
```typescript
const handle = ctx.ui.custom(myComponent); const handle = ctx.ui.custom(myComponent);
// Returns { close: () => void, requestRender: () => void } // Returns { close: () => void, requestRender: () => void }
// Component can implement handleInput(data: string) for keyboard
// Call handle.close() when done
``` ```
Your component can:
- Implement `handleInput(data: string)` to receive keyboard input
- Implement `render(width: number): string[]` to render lines
- Implement `invalidate()` to clear cached render
- Call `handle.requestRender()` to trigger re-render
- Call `handle.close()` when done to restore normal UI
See [examples/hooks/snake.ts](../examples/hooks/snake.ts) for a complete example with game loop, keyboard handling, and state persistence.
### ctx.hasUI ### ctx.hasUI
`false` in print mode (`-p`) and RPC mode. Always check before using `ctx.ui`: `false` in print mode (`-p`), JSON print mode, and RPC mode. Always check before using `ctx.ui`:
```typescript ```typescript
if (ctx.hasUI) { if (ctx.hasUI) {