Create a New Default Hook banner
timoconnellaus timoconnellaus

Create a New Default Hook

Development community intermediate

Description

I'll help you create a new default hook that can be exported from this repository and used in `.claude/hooks/hooks.ts` files.

Installation

This entry records only its repository, not the path inside it, so there is no exact command to give. Open the source below and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

README


description: Create a new default hook export for the repository

Create a New Default Hook

I'll help you create a new default hook that can be exported from this repository and used in `.claude/hooks/hooks.ts` files.

Hook Requirements

$ARGUMENTS

Understanding Hook Structure

Based on the codebase analysis, here's how to create a new default hook:

1. Hook Types

There are two categories of hooks:

**Tool Hooks** (PreToolUse, PostToolUse):

  • Require a matcher (regex pattern for tool names)
  • Have a handler function
  • Can match multiple tools with patterns like "Write|Edit|MultiEdit"

**Non-Tool Hooks** (Notification, Stop, SubagentStop):

  • Only have a handler function
  • No matcher required

2. Hook Input Types

Each hook type receives specific input:

// PreToolUse
{
  hook_event_name: 'PreToolUse',
  tool_name: string,
  tool_input: Record,
  session_id: string,
  transcript_path: string
}

// PostToolUse (same as PreToolUse plus)
{
  tool_response: Record
}

// Notification
{
  hook_event_name: 'Notification',
  message: string,
  session_id: string,
  transcript_path: string
}

// Stop/SubagentStop
{
  hook_event_name: 'Stop' | 'SubagentStop',
  stop_hook_active: boolean,
  session_id: string,
  transcript_path: string
}

3. Hook Output Types

Hooks can return structured responses:

// PreToolUse can return:
{
  decision?: 'approve' | 'block',
  reason?: string,
  continue?: boolean,
  stopReason?: string,
  suppressOutput?: boolean
}

// PostToolUse can return:
{
  decision?: 'block',
  reason?: string,
  continue?: boolean,
  stopReason?: string,
  suppressOutput?: boolean
}

// Stop/SubagentStop can return:
{
  decision?: 'block',
  reason?: string,
  continue?: boolean,
  stopReason?: string,
  suppressOutput?: boolean
}

// Notification can return:
{
  continue?: boolean,
  stopReason?: string,
  suppressOutput?: boolean
}

4. Creating a Default Hook

To create a new default hook:

  1. Create a new file in the src/hooks/ directory (e.g., src/hooks/myHook.ts)
  2. Export a hook definition using the defineHook function
  3. Add the export to src/index.ts

Important Implementation Guidelines:

**Always import types from types.ts:**

  • Import specific input types like PreToolUseInput, StopInput, etc.
  • Never manually define types that already exist in types.ts
  • Use the imported types for proper type safety

**Hook file structure:**

// src/hooks/blockDangerousCommands.ts
import { defineHook } from '../index';
import { PreToolUseInput } from '../types';  // Import proper types!

export const blockDangerousCommands = defineHook('PreToolUse', {
  matcher: 'Bash',
  handler: async (input: PreToolUseInput) => {  // Use the imported type
    const command = input.tool_input.command;
    const dangerous = ['rm -rf /', 'dd if=/dev/zero', ':(){:|:&};:'];
    
    if (dangerous.some(cmd => command?.includes(cmd))) {
      r