Skip to main content Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/ucsandman/claude-code-capability-primer --skill claude-code-hooks명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... name claude-code-hooks description Use when configuring automated lifecycle commands (hooks) in Claude Code settings.json — event types, matcher syntax, exit codes, JSON output, path placeholders. user-invocable true
Claude Code Hooks
Hooks are shell commands, HTTP endpoints, or MCP tools that execute automatically at lifecycle points: before/after tool calls, on session start/end, when config changes, and on other events. The harness controls execution; Claude cannot suppress them.
Event Types
Hooks fire at specific cadences:
Once per session:
SessionStart — beginning, resume, or after compaction
SessionEnd — on session close
Once per turn:
UserPromptSubmit — before Claude reads prompt (can block)
UserPromptExpansion — before user command expands to prompt (can block)
Stop — after Claude responds
StopFailure — if response failed
Per tool call:
PreToolUse — before tool executes (can block)
PermissionRequest — when permission dialog appears
PermissionDenied — when tool denied; can return {retry: true}
PostToolUse — after tool succeeds
PostToolUseFailure — if tool failed
PostToolBatch — after parallel batch resolves
FileChanged — watched file modified on disk (matcher specifies files)
CwdChanged — working directory changed
ConfigChange — settings/skills file modified
InstructionsLoaded — CLAUDE.md or rules/*.md loaded
Notification — when Claude Code sends notification (matcher: notification type)
MessageDisplay — while assistant message displays
SubagentStart — subagent spawned (matcher: agent type)
SubagentStop — subagent finished
TaskCreated, TaskCompleted — task lifecycle
Setup — on --init-only or CI setup mode
PreCompact, PostCompact — context compaction boundary
Elicitation, ElicitationResult — MCP server user input
WorktreeCreate, WorktreeRemove — git worktree lifecycle
TeammateIdle — agent team teammate idle
Configuration Locations
~/.claude/settings.json — user-wide (all projects)
.claude/settings.json — project-wide (shareable, commitable)
.claude/settings.local.json — project-specific (gitignored)
Plugin hooks/hooks.json — loaded at plugin install
Skill/agent YAML frontmatter — active while component loaded
Hook Structure {
"hooks" : {
"EventName" : [
{
"matcher" : "ToolName|OtherTool" ,
"hooks" : [
{
"type" : "command|http|mcp_tool|prompt|agent" ,
"command" : "script.sh" ,
"timeout" : 30 ,
"statusMessage" : "Running validation..." ,
"async" : false ,
"if" : "Bash(git *)"
}
]
}
]
}
}
Matcher Syntax
Empty or "*" — matches all
Alphanumeric/_/| — exact match or literal alternatives: Bash, Edit|Write, mcp__github__create_issue
Other chars (including regex syntax) — regex: ^Notebook, .envrc|.env, mcp__.*__write.*
SessionStart matchers — special: startup|resume|clear|compact
Notification matchers — permission_prompt, idle_prompt, auth_success, elicitation_dialog, elicitation_complete, elicitation_response
Command Hook Type Exec form (preferred; safe for paths with special chars):
{
"type" : "command" ,
"command" : "node" ,
"args" : [ "${CLAUDE_PLUGIN_ROOT}/script.js" , "--fix" ]
}
Spawns directly without shell; ${} placeholders safe.
Shell form (full features like pipes, globs):
{
"type" : "command" ,
"command" : "grep 'error' log.txt | wc -l"
}
Runs in shell; supports &&, pipes, * globs. Avoid untrusted paths.
timeout — seconds before kill (default: varies by event)
statusMessage — user-visible spinner text
async — run in background without blocking
asyncRewake — background task, wake Claude on exit 2
if — permission rule: Bash(rm **), Edit(*.ts), Bash(git *)
once — run once per session, then remove (skills only)
shell — bash (default) or powershell
Path Placeholders
${CLAUDE_PROJECT_DIR} — project root
${CLAUDE_PLUGIN_ROOT} — plugin installation directory
${CLAUDE_PLUGIN_DATA} — plugin persistent data dir
Always use exec form with args when using placeholders.
Windows Polyglot Pattern Claude Code on Windows auto-prepends bash to .sh commands. Override by using extensionless filenames with a wrapper:
{
"command" : "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start"
}
Wrapper (run-hook.cmd): batch block for cmd.exe, shell code for bash:
: << 'CMDBLOCK'
@echo off
if exist "C:\Program Files\Git\bin\bash.exe" (
"C:\Program Files\Git\bin\bash.exe" "%~dp0%~1" %2 %3
exit /b %ERRORLEVEL%
)
where bash >nul 2>nul && bash "%~dp0%~1" %2 %3 && exit /b %ERRORLEVEL%
exit /b 0
CMDBLOCK
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
exec bash "${SCRIPT_DIR}/$1" "${@:2}"
The : << 'CMDBLOCK' trick: cmd.exe runs batch; bash sees : (no-op) and runs Unix shell code.
Exit Code Protocol Code Meaning 0 Success. Harness parses stdout for JSON output. 2 Blocking error. Stderr shown to user. Hook can deny action or block turn. Other Non-blocking error. First line of stderr shown, execution continues.
Common Input (JSON stdin)
session_id — unique identifier
cwd — current working directory
permission_mode — default, plan, acceptEdits, auto, dontAsk, bypassPermissions
hook_event_name — event name
effort.level — low, medium, high, xhigh, max
transcript_path — path to session transcript (JSONL)
agent_id, agent_type — when inside subagent
Event-specific fields (e.g., tool_name, tool_input for PreToolUse)
JSON Output (Exit 0 Only) Exit 0 with valid JSON stdout to control harness. Output format depends on your platform:
Claude Code (CLAUDE_PLUGIN_ROOT set):
{
"hookSpecificOutput" : {
"hookEventName" : "PreToolUse" ,
"additionalContext" : "Context for Claude" ,
"permissionDecision" : "deny" ,
"permissionDecisionReason" : "Blocked by policy"
}
}
Cursor (CURSOR_PLUGIN_ROOT set):
{
"additional_context" : "Context for Claude"
}
Copilot CLI (SDK standard):
{
"additionalContext" : "Context for Claude"
}
continue: false — stop entire turn
stopReason — message when stopping
suppressOutput: true — hide from transcript
systemMessage — warning shown to user
terminalSequence — OSC codes (desktop notification, window title)
HTTP Hook Type {
"type" : "http" ,
"url" : "http://localhost:8080/hook" ,
"headers" : { "Authorization" : "Bearer ${TOKEN}" } ,
"allowedEnvVars" : [ "TOKEN" ]
}
POST with stdin JSON. Whitelist env vars to pass. Return 2xx with JSON body for decisions.
MCP Tool Hook Type {
"type" : "mcp_tool" ,
"server" : "my_mcp_server" ,
"tool" : "tool_name" ,
"input" : { "file_path" : "${tool_input.file_path}" }
}
Call tool on connected MCP server. Fields can interpolate from stdin.
Prompt/Agent Hook Types {
"type" : "prompt" ,
"prompt" : "Should this be allowed? $ARGUMENTS" ,
"model" : "fast-model"
}
Sends yes/no question to Claude. Rarely needed; prefer command hooks for determinism.
Real Example: Block rm -rf {
"hooks" : {
"PreToolUse" : [
{
"matcher" : "Bash" ,
"if" : "Bash(rm -rf *)" ,
"hooks" : [ {
"type" : "command" ,
"command" : "node" ,
"args" : [ "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.js" ]
} ]
}
]
}
}
Exit code 2 to deny; stderr message shown.
Disable All Hooks {
"disableAllHooks" : true
}
Top-level key to skip all hooks (useful for debugging).
When to Use Hooks
Deterministic automation ("each time X, always do Y")
Security gates (block dangerous commands, validate secrets before commits)
Context injection (SessionStart loads docs, specs, templates)
Auto-validation (PostToolUse runs tests, blocks if fails)
Observability (log commands, audit config changes)
One-off tasks Claude should handle directly
Business logic that belongs in code
Anything requiring complex reasoning (use prompt/agent types sparingly)
Debug Hooks
/hooks command: browse configured hooks, view matchers/handlers
Exit 2 blocks silently; non-0 shows error in transcript
Test JSON with jq before deploying
Check script permissions on Unix: chmod +x script.sh
Use timeout to kill runaway scripts
Hook stderr shown in transcript (unless suppressOutput: true)
Security Hooks execute with your user permissions. Always:
Store hook scripts in .claude/ or plugin dirs (not world-writable)
Never call untrusted executables
Whitelist env vars in HTTP hooks
Review hook code before enabling