The 20 Available Hook Types in PAI: Complete Event-Driven Automation Guide

Personal AI Infrastructure (PAI) provides 7 core hook events that trigger 20 built-in automation scripts, enabling custom TypeScript or Python execution at specific moments in Claude Code sessions.

Daniel Miessler’s Personal AI Infrastructure implements an event-driven hook system that intercepts session lifecycle moments to run custom logic. While PAI defines 7 distinct hook events (the trigger conditions), the framework ships with 20 individual hook scripts distributed across those events, providing ready-made automation for greetings, security validation, learning capture, and tool orchestration.

The 7 Core Hook Events and Their Trigger Conditions

PAI hook events fire at specific, immutable moments in the Claude Code execution flow. Each event represents a hook type that determines when associated scripts execute.

SessionStart

Trigger condition: Fires the instant a new Claude Code session (conversation) is created, before any user input is processed.

This event initializes the conversational context. Built-in hooks running here include StartupGreeting.hook.ts, LoadContext.hook.ts, and CheckVersion.hook.ts.

SessionEnd

Trigger condition: Activates when the session is explicitly terminated, such as when the user runs :exit or the process receives a shutdown signal.

This event handles cleanup and learning persistence. Hooks include WorkCompletionLearning.hook.ts, SessionSummary.hook.ts, RelationshipMemory.hook.ts, UpdateCounts.hook.ts, and IntegrityCheck.hook.ts.

UserPromptSubmit

Trigger condition: Executes immediately after the user submits a new prompt but before Claude begins processing the request.

This event captures user intent and prepares auxiliary systems. Hooks include RatingCapture.hook.ts, AutoWorkCreation.hook.ts, UpdateTabTitle.hook.ts, and SessionAutoName.hook.ts.

Stop

Trigger condition: Fires after the main agent (the “DA IDENTITY”) finishes rendering a response and control returns to the user.

This event coordinates post-response actions. The primary hook is StopOrchestrator.hook.ts, which delegates to five sub-handlers: VoiceNotification.ts, TabState.ts, RebuildSkill.ts, AlgorithmEnrichment.ts, and DocCrossRefIntegrity.ts.

PreToolUse

Trigger condition: Executes immediately before Claude Code runs any tool, including Bash, Edit, Write, Read, AskUserQuestion, Task, or Skill.

This event provides security and context gating. Hooks include VoiceGate.hook.ts, SecurityValidator.hook.ts, SetQuestionTab.hook.ts, AgentExecutionGuard.hook.ts, and SkillGuard.hook.ts.

PostToolUse

Trigger condition: Activates immediately after a tool finishes executing and returns results to the agent.

This event captures execution outcomes for learning algorithms. Hooks include QuestionAnswered.hook.ts and AlgorithmTracker.hook.ts.

PreCompact

Trigger condition: Fires just before Claude Code compacts the conversation context during long-running chats to manage token limits.

Currently, no built-in hooks are configured for this event in the default release, though the event type is available for custom implementations.

The 20 Built-In Hook Scripts by Event

PAI distributes 20 distinct hook scripts across the seven event types. The following table maps each script to its triggering event and primary function:

Hook Script Event Function
StartupGreeting.hook.ts SessionStart Displays personalized welcome message based on identity config
LoadContext.hook.ts SessionStart Loads persistent context files into session memory
CheckVersion.hook.ts SessionStart Validates PAI version compatibility
WorkCompletionLearning.hook.ts SessionEnd Extracts learning from completed work units
SessionSummary.hook.ts SessionEnd Generates conversation summaries for long-term memory
RelationshipMemory.hook.ts SessionEnd Updates relationship context between user and DA
UpdateCounts.hook.ts SessionEnd Persists usage statistics and token counts
IntegrityCheck.hook.ts SessionEnd Validates file system integrity of PAI directories
RatingCapture.hook.ts UserPromptSubmit Captures implicit quality signals from prompt patterns
AutoWorkCreation.hook.ts UserPromptSubmit Automatically creates work items from prompt intent
UpdateTabTitle.hook.ts UserPromptSubmit Updates terminal tab titles with session context
SessionAutoName.hook.ts UserPromptSubmit Generates semantic names for unnamed sessions
StopOrchestrator.hook.ts Stop Coordinates post-response actions (delegates to 5 sub-modules)
VoiceGate.hook.ts PreToolUse Blocks voice notifications for background agents
SecurityValidator.hook.ts PreToolUse Validates tool commands against security policies
SetQuestionTab.hook.ts PreToolUse Configures UI state for question-asking tools
AgentExecutionGuard.hook.ts PreToolUse Prevents recursive agent spawning
SkillGuard.hook.ts PreToolUse Validates skill file integrity before execution
QuestionAnswered.hook.ts PostToolUse Logs Q&A pairs for knowledge base building
AlgorithmTracker.hook.ts PostToolUse Tracks algorithm execution paths for optimization

The StopOrchestrator technically counts as one hook script but internally delegates to five handler modules: VoiceNotification.ts, TabState.ts, RebuildSkill.ts, AlgorithmEnrichment.ts, and DocCrossRefIntegrity.ts.

Configuring Hook Triggers in settings.json

Hook execution is controlled through ~/.claude/settings.json, which maps the seven event types to ordered arrays of hook descriptors.

Basic Configuration Structure

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "${PAI_DIR}/hooks/StartupGreeting.hook.ts"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${PAI_DIR}/hooks/SecurityValidator.hook.ts"
          }
        ]
      }
    ]
  }
}

Matcher Conditions

The matcher field filters hooks to specific tools or contexts. When present, the hook only fires if the condition matches:

  • Tool-specific matching: "matcher": "Bash" restricts the hook to Bash tool invocations
  • Pattern matching: Supports wildcards for tool name patterns
  • Absence: No matcher means the hook fires for every instance of the event type

Execution Order

Hooks execute sequentially in the order defined in the JSON array. A hook that hangs or crashes prevents subsequent hooks from running, which is why all built-in scripts exit with status 0 immediately after completing their work.

Building Custom PAI Hooks

Custom hooks read event data from STDIN as JSON payloads. Each event type provides a specific schema documented in THEHOOKSYSTEM.md.

Example: Custom PreToolUse Hook

#!/usr/bin/env bun
interface PreToolUsePayload {
  session_id: string
  transcript_path: string
  hook_event_name: "PreToolUse"
  tool_name: string
  tool_input: any
}

async function main() {
  const raw = await Bun.stdin.text()
  const data: PreToolUsePayload = JSON.parse(raw)
  
  // Custom logic: Log all file writes
  if (data.tool_name === "Write") {
    const { appendFileSync } = require('fs')
    const logPath = `${process.env.PAI_DIR}/hooks/logs/writes.log`
    const entry = `[${new Date().toISOString()}] ${data.tool_input.file_path}\n`
    appendFileSync(logPath, entry)
  }
  
  // Must exit cleanly
  process.exit(0)
}

main()

Payload Schema by Event Type

According to Releases/v3.0/.claude/skills/PAI/THEHOOKSYSTEM.md, each event delivers specific fields:

  • SessionStart/End: session_id, transcript_path, timestamp
  • UserPromptSubmit: Includes the prompt text submitted by the user
  • PreToolUse/PostToolUse: Includes tool_name and tool_input/tool_output
  • Stop: Contains the response content and token usage statistics

Summary

  • PAI defines 7 hook event types (SessionStart, SessionEnd, UserPromptSubmit, Stop, PreToolUse, PostToolUse, PreCompact) that serve as trigger conditions throughout the Claude Code lifecycle.
  • 20 built-in hook scripts are distributed across these events, handling automation for greetings, security validation, learning capture, and tool orchestration.
  • Trigger conditions are defined by the event type itself (e.g., PreToolUse fires before any tool execution) and can be refined with matcher patterns in settings.json to filter by specific tool names.
  • Configuration occurs in ~/.claude/settings.json, where hooks are mapped to events and executed sequentially in the order defined.
  • Custom hooks receive JSON payloads via STDIN and must exit with status 0 to avoid blocking subsequent automation.

Frequently Asked Questions

What is the difference between a hook event and a hook script in PAI?

A hook event (also called a hook type) is the trigger condition itself—one of the seven lifecycle moments like SessionStart or PreToolUse. A hook script is the executable file (TypeScript or Python) that runs when that event fires. PAI provides 7 event types but ships with 20 distinct hook scripts, meaning some events trigger multiple scripts sequentially.

How do I prevent a specific hook from running in certain sessions?

Remove or comment out the hook descriptor from the relevant event array in ~/.claude/settings.json. Alternatively, for tool-specific hooks, modify the matcher field to match only tool names you want to intercept. For example, changing "matcher": "Bash" to "matcher": "Read" ensures the hook only fires before Read tool execution, effectively disabling it for Bash commands.

Can I write PAI hooks in Python instead of TypeScript?

Yes. While the 20 built-in hooks are implemented in TypeScript (using the Bun runtime), PAI executes any command-line executable. Python scripts can read the JSON payload from STDIN using sys.stdin, process the event data, and exit with status 0. Ensure your Python script includes the appropriate shebang (#!/usr/bin/env python3) and is executable, or invoke it explicitly via the command field in settings.json.

What happens if a hook script fails or hangs?

Hooks execute sequentially in the order defined in settings.json. If a hook exits with a non-zero status or hangs indefinitely, it blocks all subsequent hooks in the same event group from running. PAI does not implement timeout handling by default, so a hanging hook will freeze the Claude Code session at that lifecycle point. All built-in hooks are designed to exit immediately with status 0 after completing their work to prevent this blocking behavior.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →