7.1 KiB
Pi Hook Survey
Status: investigation note Date: 2026-04-07
Why this exists
We were asked to find the hook surfaces exposed by pi and pi-mono, then decide which ideas transfer cleanly into Paperclip.
This note is based on direct source inspection of:
badlogic/pidefault branch andpi2branchbadlogic/pi-monopackages/coding-agent- current Paperclip plugin and adapter surfaces in this repo
Short answer
- Current
pidoes not expose a comparable extension hook API. What it exposes today is a JSON event stream frompi-agent. pi-monodoes expose a real extension hook system. It is broad, typed, and intentionally allows mutation of agent/runtime behavior.- Paperclip should copy only the safe subset:
- typed event subscriptions
- read-only run lifecycle events
- explicit worker lifecycle hooks
- plugin-to-plugin events
- Paperclip should not copy the dangerous subset:
- arbitrary mutation hooks on core control-plane decisions
- project-local plugin loading
- built-in tool shadowing by name collision
What pi has today
Current badlogic/pi is primarily a GPU pod manager plus a lightweight agent runner. It does not expose a pi.on(...)-style extension API like pi-mono.
The closest thing to hooks is the pi-agent --json event stream:
session_startuser_messageassistant_startassistant_messagethinkingtool_calltool_resulttoken_usageerrorinterrupted
That makes pi useful as an event producer, but not as a host for third-party runtime interception.
What pi-mono has
pi-mono exposes a real extension API through packages/coding-agent/src/core/extensions/types.ts.
Extension event hooks
Verified pi.on(...) hook names:
resources_discoversession_startsession_before_switchsession_before_forksession_before_compactsession_compactsession_shutdownsession_before_treesession_treecontextbefore_provider_requestbefore_agent_startagent_startagent_endturn_startturn_endmessage_startmessage_updatemessage_endtool_execution_starttool_execution_updatetool_execution_endmodel_selecttool_calltool_resultuser_bashinput
Other extension surfaces
pi-mono extensions can also:
registerTool(...)registerCommand(...)registerShortcut(...)registerFlag(...)registerMessageRenderer(...)registerProvider(...)unregisterProvider(...)- use an inter-extension event bus via
pi.events
Important behavior
pi-mono hooks are not just observers. Several can actively mutate behavior:
before_agent_startcan rewrite the effective system prompt and inject messagescontextcan replace the message set before an LLM callbefore_provider_requestcan rewrite the serialized provider payloadtool_callcan mutate tool inputs and block executiontool_resultcan rewrite tool outputuser_bashcan replace shell execution entirelyinputcan transform or fully handle user input before normal processing
That is a good fit for a local coding harness. It is not automatically a good fit for a company control plane.
What Paperclip already has
Paperclip already has several hook-like surfaces, but they are much narrower and safer:
- plugin worker lifecycle hooks such as
setup()andonHealth() - declared webhook endpoints for plugins
- scheduled jobs
- a typed plugin event bus with filtering and plugin namespacing
- adapter runtime hooks for logs/status/usage in the run pipeline
The plugin event bus is already pointed in the right direction:
- core domain events can be subscribed to
- filters are applied server-side
- plugin-emitted events are namespaced under
plugin.<pluginId>.* - plugins do not override core behavior by name collision
What transfers well to Paperclip
These ideas from pi-mono fit Paperclip with little conceptual risk:
1. Read-only run lifecycle subscriptions
Paperclip should continue exposing run and transcript events to plugins, for example:
- run started / finished
- tool started / finished
- usage reported
- issue comment created
This matches Paperclip's control-plane posture: observe, react, automate.
2. Plugin-to-plugin events
Paperclip already has this. It is worth keeping and extending.
This is the clean replacement for many ad hoc hook chains.
3. Explicit worker lifecycle hooks
Paperclip already has setup() and onHealth(). That is the right shape.
If more lifecycle is needed, it should stay explicit and host-controlled.
4. Trusted adapter-level prompt/runtime middleware
Some pi-mono ideas do belong in Paperclip, but only inside trusted adapter/runtime code:
- prompt shaping before a run starts
- provider request customization
- tool execution wrappers for local coding adapters
This should be an adapter surface, not a general company plugin surface.
What should not transfer directly
These pi-mono capabilities are a bad fit for Paperclip core:
1. Arbitrary mutation hooks on control-plane decisions
Paperclip should not let general plugins rewrite:
- issue checkout semantics
- approval outcomes
- budget enforcement
- assignment rules
- company scoping
Those are core invariants.
2. Tool shadowing by name collision
pi-mono's low-friction override model is great for a personal coding harness.
Paperclip should keep plugin tools namespaced and non-shadowing.
3. Project-local plugin loading
Paperclip is an operator-controlled control plane. Repo-local plugin auto-loading would make behavior too implicit and too hard to govern.
4. UI-session-specific hooks as first-class product surface
Hooks like:
session_before_switchsession_before_forksession_before_treemodel_selectinputuser_bash
are tied to pi-mono being an interactive terminal coding harness.
They do not map directly to Paperclip's board-and-issues model.
Recommended Paperclip direction
If we want a "hooks" story inspired by pi-mono, it should split into two layers:
Layer 1: safe control-plane plugins
Allowed surfaces:
- typed domain event subscriptions
- jobs
- webhooks
- plugin-to-plugin events
- UI slots and bridge actions
- plugin-owned tools and data endpoints
Disallowed:
- mutation of core issue/approval/budget invariants
Layer 2: trusted runtime middleware
For adapters and other trusted runtime packages only:
- prompt assembly hooks
- provider payload hooks
- tool execution wrappers
- transcript rendering helpers
This is where the best pi-mono runtime ideas belong.
Bottom line
If the question is "what hooks do pi and pi-mono have?":
pi: JSON output events, not a general extension hook systempi-mono: a broad extension hook API with 27 named event hooks plus tool/command/provider registration
If the question is "what works for Paperclip too?":
- yes: typed event subscriptions, worker lifecycle hooks, namespaced plugin events, read-only run lifecycle events
- maybe, but trusted-only: prompt/provider/tool middleware around adapter execution
- no: arbitrary mutation hooks on control-plane invariants, project-local plugin loading, tool shadowing