co-mono/packages/coding-agent/examples/hooks
Helmut Januschka e781c9a466 feat(plan-mode): show todo list in chat after planning, widget during execution
- After agent creates plan: show todo list as a message in chat
- During execution: show widget under Working indicator with checkboxes
- Check off items as they complete with strikethrough
2026-01-04 18:13:28 +01:00
..
todo feat: configurable keybindings for all editor and app actions 2026-01-03 08:23:56 +01:00
auto-commit-on-exit.ts Add setEditorText/getEditorText to hook UI context, improve custom() API 2026-01-01 00:04:56 +01:00
confirm-destructive.ts Consolidate session events: remove session_before_new/session_new, add reason field to switch events 2026-01-01 23:31:26 +01:00
custom-compaction.ts Add setEditorText/getEditorText to hook UI context, improve custom() API 2026-01-01 00:04:56 +01:00
dirty-repo-guard.ts Consolidate session events: remove session_before_new/session_new, add reason field to switch events 2026-01-01 23:31:26 +01:00
file-trigger.ts feat(coding-agent): expose deliverAs option in hook sendMessage() API 2026-01-03 00:13:26 +01:00
git-checkpoint.ts Add setEditorText/getEditorText to hook UI context, improve custom() API 2026-01-01 00:04:56 +01:00
handoff.ts fix(coding-agent): prevent full re-renders during write tool streaming 2026-01-02 01:11:06 +01:00
permission-gate.ts Add setEditorText/getEditorText to hook UI context, improve custom() API 2026-01-01 00:04:56 +01:00
plan-mode.ts feat(plan-mode): show todo list in chat after planning, widget during execution 2026-01-04 18:13:28 +01:00
protected-paths.ts Add setEditorText/getEditorText to hook UI context, improve custom() API 2026-01-01 00:04:56 +01:00
qna.ts Add setEditorText/getEditorText to hook UI context, improve custom() API 2026-01-01 00:04:56 +01:00
README.md WIP: Add hook API for dynamic tool control with plan-mode hook example 2026-01-04 18:13:28 +01:00
snake.ts feat: configurable keybindings for all editor and app actions 2026-01-03 08:23:56 +01:00
status-line.ts Consolidate session events: remove session_before_new/session_new, add reason field to switch events 2026-01-01 23:31:26 +01:00

Hooks Examples

Example hooks for pi-coding-agent.

Usage

# Load a hook with --hook flag
pi --hook examples/hooks/permission-gate.ts

# Or copy to hooks directory for auto-discovery
cp permission-gate.ts ~/.pi/agent/hooks/

Examples

Hook Description
plan-mode.ts Claude Code-style plan mode for read-only exploration with /plan command
permission-gate.ts Prompts for confirmation before dangerous bash commands (rm -rf, sudo, etc.)
git-checkpoint.ts Creates git stash checkpoints at each turn for code restoration on branch
protected-paths.ts Blocks writes to protected paths (.env, .git/, node_modules/)
file-trigger.ts Watches a trigger file and injects contents into conversation
confirm-destructive.ts Confirms before destructive session actions (clear, switch, branch)
dirty-repo-guard.ts Prevents session changes with uncommitted git changes
auto-commit-on-exit.ts Auto-commits on exit using last assistant message for commit message
custom-compaction.ts Custom compaction that summarizes entire conversation
qna.ts Extracts questions from last response into editor via ctx.ui.setEditorText()
snake.ts Snake game with custom UI, keyboard handling, and session persistence
status-line.ts Shows turn progress in footer via ctx.ui.setStatus() with themed colors
handoff.ts Transfer context to a new focused session via /handoff <goal>
todo/ Adds /todos command to view todos managed by the todo custom tool

Writing Hooks

See docs/hooks.md for full documentation.

import type { HookAPI } from "@mariozechner/pi-coding-agent/hooks";

export default function (pi: HookAPI) {
  // Subscribe to events
  pi.on("tool_call", async (event, ctx) => {
    if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
      const ok = await ctx.ui.confirm("Dangerous!", "Allow rm -rf?");
      if (!ok) return { block: true, reason: "Blocked by user" };
    }
  });

  // Register custom commands
  pi.registerCommand("hello", {
    description: "Say hello",
    handler: async (args, ctx) => {
      ctx.ui.notify("Hello!", "info");
    },
  });
}