Hook Development for Claude Code Plugins
anthropics/claude-plugins-official
Explains how to write Claude Code plugin hooks, both prompt-based checks and bash commands, for events such as PreToolUse, Stop and SessionStart.
Covers how to build, configure and publish Claude Code hooks: event types, exit codes, JSON I/O, and PRPM packaging.
$ npx skills add pr-pm/prpm --skill creating-claude-hooks -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install pr-pm/prpm creating-claude-hooks --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/pr-pm/prpm.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/creating-claude-hooks .claude/skills/creating-claude-hooks && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "creating-claude-hooks" agent skill from https://github.com/pr-pm/prpm/tree/main/.claude/skills/creating-claude-hooks into .claude/skills/creating-claude-hooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "creating-claude-hooks", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/pr-pm/prpm/tree/main/.claude/skills/creating-claude-hooksType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add pr-pm/prpm --skill creating-claude-hooks -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install pr-pm/prpm creating-claude-hooks --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pr-pm/prpm.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/creating-claude-hooks .agents/skills/creating-claude-hooks && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "creating-claude-hooks" agent skill from https://github.com/pr-pm/prpm/tree/main/.claude/skills/creating-claude-hooks into .agents/skills/creating-claude-hooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "creating-claude-hooks", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add pr-pm/prpm --skill creating-claude-hooks -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install pr-pm/prpm creating-claude-hooks --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pr-pm/prpm.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/creating-claude-hooks .cursor/skills/creating-claude-hooks && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "creating-claude-hooks" agent skill from https://github.com/pr-pm/prpm/tree/main/.claude/skills/creating-claude-hooks into .cursor/skills/creating-claude-hooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "creating-claude-hooks", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/pr-pm/prpm.git --path .claude/skills/creating-claude-hooks--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add pr-pm/prpm --skill creating-claude-hooks -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install pr-pm/prpm creating-claude-hooks --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pr-pm/prpm.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/creating-claude-hooks .gemini/skills/creating-claude-hooks && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "creating-claude-hooks" agent skill from https://github.com/pr-pm/prpm/tree/main/.claude/skills/creating-claude-hooks into .gemini/skills/creating-claude-hooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "creating-claude-hooks", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install pr-pm/prpm creating-claude-hooksInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add pr-pm/prpm --skill creating-claude-hooks -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/pr-pm/prpm.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/creating-claude-hooks .github/skills/creating-claude-hooks && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "creating-claude-hooks" agent skill from https://github.com/pr-pm/prpm/tree/main/.claude/skills/creating-claude-hooks into .github/skills/creating-claude-hooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "creating-claude-hooks", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add pr-pm/prpm --skill creating-claude-hooks -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install pr-pm/prpm creating-claude-hooks --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pr-pm/prpm.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/creating-claude-hooks .opencode/skills/creating-claude-hooks && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "creating-claude-hooks" agent skill from https://github.com/pr-pm/prpm/tree/main/.claude/skills/creating-claude-hooks into .opencode/skills/creating-claude-hooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "creating-claude-hooks", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
creating-claude-hooksCovers how to build, configure and publish Claude Code hooks: event types, exit codes, JSON I/O, and PRPM packaging.
Two ways to wire a hook are laid out: JSON configuration in settings.json or a plugin's hooks.json, which supports both command and prompt hooks with matchers and timeouts, versus an executable file placed under .claude/hooks/<event-name>, simpler but less configurable. Command hooks run an external script in milliseconds for formatting, logging or file checks, while prompt hooks use LLM reasoning over several seconds for complex validation or security analysis.
A table of events covers PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, Stop, SubagentStop, PreCompact, Notification and PermissionRequest, noting which can block the action and typical uses for each, alongside the exit-code contract: 0 continues normally, 2 blocks the operation during PreToolUse, and any other code is logged as an error while the session continues. It also covers packaging a finished hook as a PRPM package.
6 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 5f993e6. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
jqprettierFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
docs.claude.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Creating Claude Code Hooks loads about 3.9k tokens when it runs. Until then it costs about 46 tokens; SKILL.md has 899 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
// Block .env filesif (filePath.endsWith('.env')) {console.error('Blocked: Cannot modify .env files');BLOCKED=(".env" ".env.*" "*.pem" "*.key")Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from pr-pm/prpm at commit 5f993e6, republished under its MIT licence (© pr-pm). 899 words, ~3,875 tokens.
.claude/skills/creating-claude-hooks/SKILL.md (or your agent's skills folder).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.
Activate this skill when:
Method 1: JSON Configuration (Recommended)
.claude/settings.json, ~/.claude/settings.json, or plugin's hooks.jsonMethod 2: Executable Files (Legacy)
.claude/hooks/<event-name>| Type | Description | Speed | Use Case |
|---|---|---|---|
| Command | Runs external script | Fast (ms) | Formatting, logging, file checks |
| Prompt | Uses LLM reasoning | Slow (2-10s) | Complex validation, security analysis |
| Event | When It Fires | Can Block? | Common Use Cases |
|---|---|---|---|
PreToolUse | Before tool execution | Yes (exit 2) | Validation, permission checks, input modification |
PostToolUse | After tool completes | No | Formatting, logging, cleanup |
UserPromptSubmit | Before user input processes | Yes | Prompt validation, enhancement |
SessionStart | New session begins | No | Environment setup, context loading |
Stop | When assistant finishes | No | Cleanup, summary, verification |
SubagentStop | When subagent finishes | No | Subagent result processing |
PreCompact | Before context compaction | No | Save important context |
Notification | During alerts | No | Desktop notifications, logging |
PermissionRequest | When permission needed | Yes | Custom permission handling |
| Code | Meaning | Behavior |
|---|---|---|
0 | Success | Continue normally |
2 | Block | Stop operation (PreToolUse only) |
1 or other | Error | Log error, continue |
Configure hooks in .claude/settings.json (project) or ~/.claude/settings.json (global):
{
"hooks": {
"PreToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "/path/to/validate-write.sh",
"timeout": 5000
}]
}],
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "/path/to/format-file.sh"
}]
}],
"Stop": [{
"matcher": "*",
"hooks": [{
"type": "prompt",
"prompt": "Verify all requested changes were completed."
}]
}]
}
}For PRPM packages, use hook.json:
{
"hooks": {
"PreToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh",
"timeout": 5000
}]
}]
}
}| Pattern | Matches |
|---|---|
"Write" | Only Write tool |
"Write|Edit" | Write OR Edit tools |
"Bash" | Only Bash tool |
"mcp__github__*" | All GitHub MCP tools |
"*" | All tools (use sparingly) |
{
"type": "command",
"command": "./my-hook.sh",
"timeout": 5000,
"once": true,
"continue": true,
"stopReason": "Message when blocked",
"suppressOutput": false,
"systemMessage": "Warning to show user"
}| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 60000 | Max execution time in ms |
once | boolean | false | Run only once per session |
continue | boolean | true | Continue after hook completes |
stopReason | string | - | Message when continue=false |
suppressOutput | boolean | false | Hide stdout from transcript |
systemMessage | string | - | Warning message to user |
Command hooks run external scripts. They're fast and deterministic.
#!/bin/bash
set -euo pipefail
# Read JSON input
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.input.file_path // empty')
# Validate
[[ -n "$FILE" ]] || exit 0
[[ -f "$FILE" ]] || exit 0
# Block sensitive files
case "$FILE" in
*.env|*.pem|*.key)
echo "Blocked: $FILE is sensitive" >&2
exit 2
;;
esac
exit 0#!/usr/bin/env node
import { readFileSync } from 'fs';
const input = JSON.parse(readFileSync(0, 'utf-8'));
const filePath = input.input?.file_path;
if (!filePath) process.exit(0);
// Block .env files
if (filePath.endsWith('.env')) {
console.error('Blocked: Cannot modify .env files');
process.exit(2);
}
process.exit(0);Prompt hooks use LLM reasoning for complex validation. Use sparingly - they take 2-10 seconds.
{
"hooks": {
"PreToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "prompt",
"prompt": "Check if the content being written contains hardcoded secrets, API keys, or credentials. If found, block the operation."
}]
}]
}
}{
"hooks": {
"PreToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "prompt",
"prompt": "Analyze the file content for security issues. Return your decision.",
"schema": {
"type": "object",
"properties": {
"decision": {
"type": "string",
"enum": ["allow", "block"]
},
"reason": {
"type": "string"
},
"severity": {
"type": "string",
"enum": ["low", "medium", "high", "critical"]
}
},
"required": ["decision"]
}
}]
}]
}
}Good use cases:
Avoid for:
Simpler approach - place executables directly in hooks directory.
Project hooks:
.claude/hooks/PreToolUse
.claude/hooks/PostToolUse
.claude/hooks/SessionStartUser-global hooks:
~/.claude/hooks/PreToolUse
~/.claude/hooks/StopEvery file-based hook MUST:
#!/bin/bash
#!/usr/bin/env node
#!/usr/bin/env python3chmod +x .claude/hooks/PreToolUseHandle JSON input from stdin
Exit with appropriate code
Hooks receive JSON via stdin:
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"current_dir": "/path/to/project",
"tool_name": "Write",
"input": {
"file_path": "/path/to/file.ts",
"content": "file contents...",
"command": "npm test",
"old_string": "...",
"new_string": "..."
}
}| Tool | Available Fields |
|---|---|
| Write | file_path, content |
| Edit | file_path, old_string, new_string |
| Read | file_path |
| Bash | command |
| Glob | pattern, path |
| Grep | pattern, path |
Available in hook execution:
| Variable | Description |
|---|---|
CLAUDE_PROJECT_DIR | Project root directory |
CLAUDE_CURRENT_DIR | Current working directory |
CLAUDE_PLUGIN_ROOT | Hook installation directory |
CLAUDE_ENV_FILE | File for persisting variables |
SESSION_ID | Current session identifier |
{
"hooks": {
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh",
"timeout": 5000
}]
}]
}
}{
"hooks": {
"PreToolUse": [{
"matcher": "Write|Edit|Read",
"hooks": [{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/block-sensitive.sh"
}]
}]
}
}{
"hooks": {
"Stop": [{
"matcher": "*",
"hooks": [{
"type": "prompt",
"prompt": "Before finishing, verify: 1) All tests pass 2) No linting errors 3) Types check. If any issues, list them."
}]
}]
}
}{
"hooks": {
"SessionStart": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh",
"once": true
}]
}]
}
}Combine PreToolUse (validate) with PostToolUse (verify):
{
"hooks": {
"PreToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "command",
"command": "./validate-before.sh"
}]
}],
"PostToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "command",
"command": "./verify-after.sh"
}]
}]
}
}| 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} |
Using * matcher | Runs on everything | Be specific: Write|Edit |
| Prompt hooks everywhere | Slow experience | Use only for complex logic |
Target < 100ms for PreToolUse hooks:
# Check dependencies exist
if ! command -v jq &> /dev/null; then
echo "jq not installed, skipping" >&2
exit 0
fi
# Validate input
FILE=$(echo "$INPUT" | jq -r '.input.file_path // empty')
if [[ -z "$FILE" ]]; then
echo "No file path provided" >&2
exit 1
fiAlways start with shebang:
#!/bin/bash
#!/usr/bin/env node
#!/usr/bin/env python3BLOCKED=(".env" ".env.*" "*.pem" "*.key")
for pattern in "${BLOCKED[@]}"; do
case "$FILE" in
$pattern)
echo "Blocked: $FILE is sensitive" >&2
exit 2
;;
esac
done# WRONG - breaks on spaces
prettier --write $FILE
# RIGHT - handles spaces
prettier --write "$FILE"LOG_FILE=~/.claude-hooks/debug.log
# Log to file
echo "[$(date)] Processing $FILE" >> "$LOG_FILE"
# Log to stderr (shows in transcript)
echo "Hook running..." >&2my-hook/
├── prpm.json # Package manifest
├── HOOK.md # Hook documentation
└── hook-script.sh # Hook executable{
"name": "@username/hook-name",
"version": "1.0.0",
"description": "Brief description shown in search",
"author": "Your Name",
"format": "claude",
"subtype": "hook",
"tags": ["automation", "security", "formatting"],
"main": "HOOK.md"
}---
name: session-logger
description: Logs session start/end times for tracking
event: SessionStart
language: bash
hookType: hook
---
# Session Logger Hook
Logs Claude Code session activity for tracking and debugging.
## Installation
This hook will be installed to `.claude/hooks/session-start`.
## Behavior
- Logs session start time to `~/.claude/session.log`
- Displays environment status
- Runs silent dependency checks
## Requirements
- bash 4.0+
- write access to `~/.claude/`
## Source Code
\`\`\`bash
#!/bin/bash
echo "Session started at $(date)" >> ~/.claude/session.log
echo "Environment ready"
exit 0
\`\`\`# Test locally first
prpm test
# Publish to registry
prpm publish
# Version bumps
prpm publish patch # 1.0.0 -> 1.0.1
prpm publish minor # 1.0.0 -> 1.1.0
prpm publish major # 1.0.0 -> 2.0.0# Parse JSON safely
INPUT=$(cat)
if ! FILE=$(echo "$INPUT" | jq -r '.input.file_path // empty' 2>&1); then
echo "JSON parse failed" >&2
exit 1
fi
# Validate field exists
[[ -n "$FILE" ]] || exit 1# Prevent directory traversal
if [[ "$FILE" == *".."* ]]; then
echo "Path traversal detected" >&2
exit 2
fi
# Keep in project directory
if [[ "$FILE" != "$CLAUDE_PROJECT_DIR"* ]]; then
echo "File outside project" >&2
exit 2
fiClaude Code automatically:
| Feature | Hooks | Skills | Commands |
|---|---|---|---|
| Format | Executable code | Markdown | Markdown |
| Trigger | Automatic (events) | Automatic (context) | Manual (/command) |
| Language | Any executable | N/A | N/A |
| Use Case | Automation, validation | Reference, patterns | Quick tasks |
| Security | Requires confirmation | No special permissions | Inherits from session |
Examples:
/review-pr quick code reviewBefore publishing:
chmod +x)© pr-pm, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/creating-claude-hooks of pr-pm/prpm.
Open the folder on GitHubat commit 5f993e6
We found 2 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 2 other GitHub owners. This page covers the copy in pr-pm/prpm, which our catalogue first saw on October 7, 2026.
Creating Claude Code Hooks next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Creating Claude Code Hooks this skillpr-pm/prpm | 122 | 2 repos | ~3.9k | Automated safety check: Notes | MIT | |
| Hook Development for Claude Code Pluginsanthropics/claude-plugins-official | 38k | 11 repos | ~4.1k | Automated safety check: Notes | Apache-2.0 | |
| Claude Code Agent Developmentanthropics/claude-plugins-official | 38k | 8 repos | ~2.8k | Automated safety check: Pass | Apache-2.0 | |
| Claude Code Skill Developer Guidediet103/claude-code-infrastructure-showcase | 10k | 11 repos | ~3.5k | Automated safety check: Pass | MIT | |
| Plugin Settings Patternanthropics/claude-plugins-official | 38k | 7 repos | ~3k | Automated safety check: Pass | Apache-2.0 | |
| MCP Integration for Pluginsanthropics/claude-plugins-official | 38k | 11 repos | ~3.1k | Automated safety check: Pass | Apache-2.0 |
anthropics/claude-plugins-official
Explains how to write Claude Code plugin hooks, both prompt-based checks and bash commands, for events such as PreToolUse, Stop and SessionStart.
anthropics/claude-plugins-official
Explains how to write agents for Claude Code plugins: the markdown file with YAML frontmatter, trigger descriptions, model and color settings, and system prompt design.
diet103/claude-code-infrastructure-showcase
A guide to creating and managing Claude Code skills with auto-activation: skill-rules.json triggers, hooks, enforcement levels, YAML frontmatter and progressive disclosure.
anthropics/claude-plugins-official
Shows how Claude Code plugins keep per-project settings and state in .claude/plugin-name.local.md files with YAML frontmatter and a markdown body.
anthropics/claude-plugins-official
Explains how to bundle Model Context Protocol servers in a Claude Code plugin, covering config files, stdio, SSE, HTTP and WebSocket server types, and authentication.
anthropics/claude-plugins-official
Explains how to write Claude Code slash commands: Markdown files with YAML frontmatter, arguments, file references, bash context and interactive prompts.
pr-pm/prpm
Reference for writing Claude Code agent files: location, frontmatter fields, validation limits, tool and model choices, and the required content format.
pr-pm/prpm
Shows how to write .claude/rules/ files correctly: paths frontmatter instead of globs, quoted glob patterns, global rules and conversion of Cursor rules.
pr-pm/prpm
Reference for writing portable Agent Skills packages, covering SKILL.md frontmatter limits, name rules, directory layout and where Codex CLI, GitHub Copilot and Amp look for skills.
pr-pm/prpm
A skill your agent uses when building custom Kiro AI agents or when user asks for agent configurations - provides JSON structure, tool configuration, prompt patterns, and security best practices for…
pr-pm/prpm
A skill your agent uses when creating OpenCode agents - provides markdown format with YAML frontmatter, mode/tools/permission configuration, and best practices for specialized AI assistants
pr-pm/prpm
A skill your agent uses when implementing Stripe webhook endpoints and getting 'Raw body not available' or signature verification errors - provides raw body parsing solutions and subscription period…
Categories
Covers how to build, configure and publish Claude Code hooks: event types, exit codes, JSON I/O, and PRPM packaging. claude/hooks/<event-name>, simpler but less configurable. Command hooks run an external script in milliseconds for formatting, logging or file checks, while prompt hooks use LLM reasoning over several seconds for complex validation or security analysis.
Creating Claude Code Hooks fits situations like: creating a new Claude Code hook; choosing between a command hook and a prompt hook; publishing a hook as a PRPM package; troubleshooting why a hook isn't firing or blocking as expected.
Run `npx skills add pr-pm/prpm --skill creating-claude-hooks -a claude-code`. Or copy the skill folder (.claude/skills/creating-claude-hooks in pr-pm/prpm) into .claude/skills/creating-claude-hooks in your project. Claude Code loads it when a task matches its description.
Run `npx skills add pr-pm/prpm --skill creating-claude-hooks -a codex`. Or copy the skill folder (.claude/skills/creating-claude-hooks in pr-pm/prpm) into .agents/skills/creating-claude-hooks in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add pr-pm/prpm --skill creating-claude-hooks -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/creating-claude-hooks, .gemini/skills/creating-claude-hooks, .github/skills/creating-claude-hooks and .opencode/skills/creating-claude-hooks in your project.
Going by SKILL.md and its folder, Creating Claude Code Hooks needs the command-line tools its instructions call (jq and prettier).
SKILL.md names 1 domain. As links in the text: docs.claude.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Creating Claude Code Hooks is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.9k tokens (SKILL.md is roughly 16k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Creating Claude Code Hooks: Hook Development for Claude Code Plugins (anthropics/claude-plugins-official, 38k stars), Claude Code Agent Development (anthropics/claude-plugins-official, 38k stars), Claude Code Skill Developer Guide (diet103/claude-code-infrastructure-showcase, 10k stars) and Plugin Settings Pattern (anthropics/claude-plugins-official, 38k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
pr-pm (a GitHub organization) maintains it in pr-pm/prpm, which has 122 GitHub stars. The repository holds 35 skills in this directory. The repository was last updated on October 6, 2026.
Source: pr-pm/prpm on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.