mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 08:03:39 +00:00
- Custom tools: TypeScript modules that extend pi with new tools - Custom TUI rendering via renderCall/renderResult - User interaction via pi.ui (select, confirm, input, notify) - Session lifecycle via onSession callback for state reconstruction - Examples: todo.ts, question.ts, hello.ts - Hook examples: permission-gate, git-checkpoint, protected-paths - Session lifecycle centralized in AgentSession - Works across all modes (interactive, print, RPC) - Unified session event for hooks (replaces session_start/session_switch) - Box component added to pi-tui - Examples bundled in npm and binary releases Fixes #190
1.9 KiB
1.9 KiB
Hooks Examples
Example hooks for pi-coding-agent.
Examples
permission-gate.ts
Prompts for confirmation before running dangerous bash commands (rm -rf, sudo, chmod 777, etc.).
git-checkpoint.ts
Creates git stash checkpoints at each turn, allowing code restoration when branching.
protected-paths.ts
Blocks writes to protected paths (.env, .git/, node_modules/).
Usage
# Test directly
pi --hook examples/hooks/permission-gate.ts
# Or copy to hooks directory for persistent use
cp permission-gate.ts ~/.pi/agent/hooks/
Writing Hooks
See docs/hooks.md for full documentation.
Key Points
Hook structure:
import type { HookAPI } from "@mariozechner/pi-coding-agent/hooks";
export default function (pi: HookAPI) {
pi.on("session", async (event, ctx) => {
// event.reason: "start" | "switch" | "clear"
// ctx.ui, ctx.exec, ctx.cwd, ctx.sessionFile, ctx.hasUI
});
pi.on("tool_call", async (event, ctx) => {
// Can block tool execution
if (dangerous) {
return { block: true, reason: "Blocked" };
}
return undefined;
});
pi.on("tool_result", async (event, ctx) => {
// Can modify result
return { result: "modified result" };
});
}
Available events:
session- startup, session switch, clearbranch- before branching (can skip conversation restore)agent_start/agent_end- per user promptturn_start/turn_end- per LLM turntool_call- before tool execution (can block)tool_result- after tool execution (can modify)
UI methods:
const choice = await ctx.ui.select("Title", ["Option A", "Option B"]);
const confirmed = await ctx.ui.confirm("Title", "Are you sure?");
const input = await ctx.ui.input("Title", "placeholder");
ctx.ui.notify("Message", "info"); // or "warning", "error"
Sending messages:
pi.send("Message to inject into conversation");