Pi — Hooks
- File format
- ts
- Discovery path
-
.pi/extensions - Global install path
-
~/.pi/agent/extensions - Syllago install method
- Symlink
- Symlink support
- Yes
- Config file
-
.pi/extensions/ - Handler types
-
command
Hook events
| Canonical Event | Native Name | Category |
|---|---|---|
after_tool_execute | tool_result | Tool |
agent_stop | agent_end | Lifecycle |
before_compact | session_before_compact | Context |
before_prompt | input | Lifecycle |
before_tool_execute | tool_call | Tool |
context_update | context | Context |
message_end | message_end | Model |
message_start | message_start | Model |
model_select | model_select | Model |
session_end | session_shutdown | Lifecycle |
session_start | session_start | Lifecycle |
subagent_start | before_agent_start | Lifecycle |
turn_end | turn_end | Model |
turn_start | turn_start | Model |
user_bash | user_bash | Tool |
Features
How each feature converts to syllago's canonical format. See format conversion for what these statuses mean.
Other features
Behaviors, conventions, and capabilities that aren't tied to a single named field — things like path-based activation, discovery rules, and lifecycle behavior.
| Feature | Conversion | Summary |
|---|---|---|
handler_types | Translated Conversion type: Translated Actively mapped to the target provider’s equivalent field during conversion. Learn more → | pi_extension_typescript_native: Pi hooks support TypeScript/native extension handler type beyond shell commands |
input_modification | Translated Conversion type: Translated Actively mapped to the target provider’s equivalent field during conversion. Learn more → | pi_extension_tool_call_blocking: Pi extensions can intercept and modify tool call inputs before execution |
| Full TUI component access and UI primitives | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | ctx.ui exposes dialogs, status, widgets, header/footer replacement, and custom TUI overlays with keyboard focus. |
| Hot reload with /reload command | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | Auto-discovered extensions support /reload hot reload; CLI-flag-loaded extensions do not, and resources_discover can also trigger reload. |
| registerCommand() adds slash commands | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | Extensions register custom slash commands via pi.registerCommand(); matched commands run before the agent and bypass the turn. |
| registerProvider() and unregisterProvider() for dynamic model provider management | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | Extensions can register or override model providers at runtime (baseUrl, apiKey, API type, models, OAuth) and unregister them. |
| registerTool() adds LLM-callable tools | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | Extensions register LLM-callable tools (name, label, description, TypeBox schema, execute) via pi.registerTool(); can override built-ins. |
| Rich lifecycle event model with 21 event types | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | Extensions subscribe via pi.on() to 21+ events spanning session, agent, turn, message, tool, model, and input lifecycle phases. |
| tool_call event can block or mutate tool execution | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | tool_call handlers can return { block: true, reason } or mutate event.input in place; later handlers see prior mutations. |
| tool_result handlers chain as middleware | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | tool_result handlers chain like middleware in load order, each seeing prior changes; partial patches keep omitted fields. |
| TypeScript-native extensions loaded via jiti | Not portable Conversion type: Not portable Unique to this provider — can’t be carried across providers. Learn more → | Extensions are TypeScript modules exporting a default factory; jiti loads them at runtime with no compilation step required. |