co-mono/packages/coding-agent/examples/hooks
Mario Zechner c447e62662 fix(theme): add optional themeOverride param to getSettingsListTheme/getSelectListTheme
When hooks are loaded via jiti, they get a separate module instance from
the main app. This means the global 'theme' variable in the hook's module
is never initialized. Adding an optional theme parameter allows hooks to
pass the theme from ctx.ui.custom() callback.

Usage in hooks:
  getSettingsListTheme(theme)  // theme from ctx.ui.custom callback
2026-01-04 18:39:00 +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
pirate.ts feat(hooks): add systemPromptAppend to before_agent_start, full tool registry 2026-01-04 18:21:26 +01:00
plan-mode.ts refactor: address PR feedback - merge setWidget, use KeyId for shortcuts 2026-01-04 18:13:30 +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 feat(hooks): add systemPromptAppend to before_agent_start, full tool registry 2026-01-04 18:21:26 +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
tools.ts fix(theme): add optional themeOverride param to getSettingsListTheme/getSelectListTheme 2026-01-04 18:39:00 +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
tools.ts Interactive /tools command to enable/disable tools with session persistence
pirate.ts Demonstrates systemPromptAppend to dynamically modify system prompt
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");
    },
  });
}