Skip to content
Automation
Skill

/creating-claude-hooks-skill

Use when creating or publishing Claude Code hooks - covers executable format, event types, JSON I/O, exit codes, security requirements, and PRPM package structure

From plugin
relay
1.1k18 skills39 agents1 MCP

Claude Code

$ npx -y skills add AgentWorkforce/relay --skill creating-claude-hooks-skill --agent claude-code

SKILL.md

creating-claude-hooks-skill.SKILL.md
name: creating-claude-hooks
description: Use when creating or publishing Claude Code hooks - covers executable format, event types, JSON I/O, exit codes, security requirements, and PRPM package structure
skillType: skill
allowed-tools: Read, Write, Edit, Grep, Glob, Bash

Creating Claude Code Hooks

Use this skill when creating, improving, or publishing Claude Code hooks. Provides essential guidance on hook format, event handling, I/O conventions, and package structure.

When to Use This Skill

Activate this skill when:

  • User asks to create a new Claude Code hook
  • User wants to publish a hook as a PRPM package
  • User needs to understand hook format or events
  • User is troubleshooting hook execution
  • User asks about hook vs skill vs command differences

Quick Reference

Hook File Format

| Aspect | Requirement | | --------------- | ------------------------------------------------- | | **Location** | `.claude/hooks/<event-name>` | | **Format** | Executable file (shell, TypeScript, Python, etc.) | | **Permissions** | Must be executable (`chmod +x`) | | **Shebang** | Required (`#!/bin/bash` or `#!/usr/bin/env node`) | | **Input** | JSON via stdin | | **Output** | Text via stdout (shown to user) | | **Exit Codes** | `0` = success, `2` = block, other = error |

Available Events

| Event | When It Fires | Common Use Cases | | -------------------- | --------------------------- | ---------------------------------------- | | `session-start` | New session begins | Environment setup, logging, checks | | `user-prompt-submit` | Before user input processes | Validation, enhancement, filtering | | `tool-call` | Before tool execution | Permission checks, logging, modification | | `assistant-response` | After assistant responds | Formatting, logging, cleanup |

Hook Format Requirements

File Location

**Project hooks:**

.claude/hooks/session-start
.claude/hooks/user-prompt-submit

**User-global hooks:**

~/.claude/hooks/session-start
~/.claude/hooks/tool-call

Executable Requirements

Every hook MUST:

1. **Have a shebang line:**

#!/bin/bash
# or
#!/usr/bin/env node
# or
#!/usr/bin/env python3

2. **Be executable:**

chmod +x .claude/hooks/session-start

3. **Handle JSON input from stdin:**

#!/bin/bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.input.file_path // empty')

4. **Exit with appropriate code:**

exit 0  # Success
exit 2  # Block operation
exit 1  # Error (logs but continues)

Input/Output Format

JSON Input Structure

Hooks receive JSON via stdin with event-specific data:

{
  "event": "tool-call",
  "timestamp": "2025-01-15T10:30:00Z",
  "session_id": "abc123",
  "current_dir": "/path/to/project",
  "input": {
    "file_path": "/path/to/file.ts",
    "command": "npm test",
    "old_string": "...",
    "new_string": "..."
  }
}

Stdout Output

  • Normal output shows in transcript
  • Empty output runs silently
  • Use stderr (`>&2`) for errors

Exit Codes

| Code | Meaning | Behavior | | ------------ | ------- | -------------------------- | | `0` | Success | Continue normally | | `2` | Block | Stop operation, show error | | `1` or other | Error | Log error, continue |

Schema Validation

Hooks should validate against the JSON schema:

**Schema URL:** https://github.com/pr-pm/prpm/blob/main/packages/converters/schemas/claude-hook.schema.json

**Required frontmatter fields:**

  • `name` - Hook identifier (lowercase, hyphens only)
  • `description` - What the hook does
  • `event` - Event type (optional, inferred from filename)
  • `language` - bash, typescript, javascript, python, binary (optional)
  • `hookType: "hook"` - For round-trip conversion

Common Mistakes

| Mistake | Problem | Solution | | ---------------------- | ------------------------- | ------------------------------------ | | Not quoting variables | Breaks on spaces | Always use `"$VAR"` | | Missing shebang | Won't execute | Add `#!/bin/bash` | | Not executable | Permission denied | Run `chmod +x hook-file` | | Logging to stdout | Clutters transcript | Use stderr: `echo "log" >&2` | | Wrong exit code | Doesn't block when needed | Use `exit 2` to block | | No input validation | Security risk | Always validate JSON fields | | Slow operations | Blocks Claude | Run in background or use PostToolUse | | Absolute paths missing | Can't find scripts | Use `$CLAUDE_PLUGIN_ROOT` |

Basic Hook Examples

Shell Script Hook

#!/bin/bash
# .claude/hooks/session-start

# Log session start
echo "Session started at $(date)" >> ~/.claude/session.log

# Check environment
if ! command -v node &> /dev/null; then
  echo "Warning: Node.js not installed" >&2
fi

# Output to user
echo "Development environment ready"
exit 0

TypeScript Hook

#!/usr/bin/env node
// .claude/hooks/user-prompt-submit

import { readFileSync } from 'fs';

// Read JSON from stdin
const input = readFileSync(0, 'utf-8');
const data = JSON.parse(input);

// Validate prompt
if (data.prompt.includes('API_KEY')) {
  console.error('Warning: Prompt may contain secrets');
  process.exit(2); // Block
}

console.log('Prompt validated');
process.exit(0);

Best Practices

1. Keep Hooks Fast

Target < 100ms for PreToolUse hooks:

  • Cache results where possible
  • Run heavy operations in background
  • Use specific matchers, not wildcards
Read more
@agentworkforce
Ships withrelay

Tired of copy/pasting from Claude Code into Slack so your coworker can paste it into their agent? Ever put an important rule in a skill or AGENTS.md, only for the agent to completely ignore it? You and your teammates agents ever build the same thing?

1.1k18 skills39 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
1.1k
Star history of AgentWorkforce/relay on GitHub, a chart by star-history.com

Other skills on relay.

creating-skills-skill

creating-skills-skill

Use when creating new Claude Code skills or improving existing ones - ensures skills are discoverable, scannable, and effective…

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n11d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about creating-claude-hooks-skill.

Which coding agents can use creating-claude-hooks-skill?
creating-claude-hooks-skill installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.