Skip to content
Development
Skill

/hook-developer

Complete Claude Code hooks reference - input/output schemas, registration, testing patterns

From plugin
vibecosystem
541200 skills138 agents7 hooks

Claude Code

$ npx -y skills add vibeeval/vibecosystem --skill hook-developer --agent claude-code

SKILL.md

hook-developer.SKILL.md
name: hook-developer
description: Complete Claude Code hooks reference - input/output schemas, registration, testing patterns

Hook Developer

Complete reference for developing Claude Code hooks. Use this to write hooks with correct input/output schemas.

When to Use

  • Creating a new hook
  • Debugging hook input/output format
  • Understanding what fields are available
  • Setting up hook registration in settings.json
  • Learning what hooks can block vs inject context

Quick Reference

| Hook | Fires When | Can Block? | Primary Use | |------|-----------|------------|-------------| | **PreToolUse** | Before tool executes | YES | Block/modify tool calls | | **PostToolUse** | After tool completes | Partial | React to tool results | | **UserPromptSubmit** | User sends prompt | YES | Validate/inject context | | **PermissionRequest** | Permission dialog shows | YES | Auto-approve/deny | | **SessionStart** | Session begins | NO | Load context, set env vars | | **SessionEnd** | Session ends | NO | Cleanup/save state | | **Stop** | Agent finishes | YES | Force continuation | | **SubagentStart** | Subagent spawns | NO | Pattern coordination | | **SubagentStop** | Subagent finishes | YES | Force continuation | | **PreCompact** | Before compaction | NO | Save state | | **Notification** | Notification sent | NO | Custom alerts |

**Hook type options:** `type: "command"` (bash) or `type: "prompt"` (LLM evaluation)

---

Hook Input/Output Schemas

PreToolUse

**Purpose:** Block or modify tool execution before it happens.

**Input:**

{
  "session_id": "string",
  "transcript_path": "string",
  "cwd": "string",
  "permission_mode": "default|plan|acceptEdits|bypassPermissions",
  "hook_event_name": "PreToolUse",
  "tool_name": "string",
  "tool_input": {
    "file_path": "string",
    "command": "string"
  },
  "tool_use_id": "string"
}

**Output (JSON):**

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow|deny|ask",
    "permissionDecisionReason": "string",
    "updatedInput": {}
  },
  "continue": true,
  "stopReason": "string",
  "systemMessage": "string",
  "suppressOutput": true
}

**Exit code 2:** Blocks tool, stderr shown to Claude.

**Common matchers:** `Bash`, `Edit|Write`, `Read`, `Task`, `mcp__.*`

---

PostToolUse

**Purpose:** React to tool execution results, provide feedback to Claude.

**Input:**

{
  "session_id": "string",
  "transcript_path": "string",
  "cwd": "string",
  "permission_mode": "string",
  "hook_event_name": "PostToolUse",
  "tool_name": "string",
  "tool_input": {},
  "tool_response": {
    "filePath": "string",
    "success": true,
    "output": "string",
    "exitCode": 0
  },
  "tool_use_id": "string"
}

**CRITICAL:** The response field is `tool_response`, NOT `tool_result`.

**Output (JSON):**

{
  "decision": "block",
  "reason": "string",
  "hookSpecificOutput": {
    "hookEventName": "PostToolUse",
    "additionalContext": "string"
  },
  "continue": true,
  "stopReason": "string",
  "suppressOutput": true
}

**Blocking:** `"decision": "block"` with `"reason"` prompts Claude to address the issue.

**Common matchers:** `Edit|Write`, `Bash`

---

UserPromptSubmit

**Purpose:** Validate user prompts, inject context before Claude processes.

**Input:**

{
  "session_id": "string",
  "transcript_path": "string",
  "cwd": "string",
  "permission_mode": "string",
  "hook_event_name": "UserPromptSubmit",
  "prompt": "string"
}

**Output (Plain text):**

Any stdout text is added to context for Claude.

**Output (JSON):**

{
  "decision": "block",
  "reason": "string",
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": "string"
  }
}

**Blocking:** `"decision": "block"` erases prompt, shows `"reason"` to user only (not Claude).

**Exit code 2:** Blocks prompt, shows stderr to user only.

---

PermissionRequest

**Purpose:** Automate permission dialog decisions.

**Input:**

{
  "session_id": "string",
  "transcript_path": "string",
  "cwd": "string",
  "permission_mode": "string",
  "hook_event_name": "PermissionRequest",
  "tool_name": "string",
  "tool_input": {}
}

**Output:**

{
  "hookSpecificOutput": {
    "hookEventName": "PermissionRequest",
    "decision": {
      "behavior": "allow|deny",
      "updatedInput": {},
      "message": "string",
      "interrupt": false
    }
  }
}

---

SessionStart

**Purpose:** Initialize session, load context, set environment variables.

**Input:**

{
  "session_id": "string",
  "transcript_path": "string",
  "cwd": "string",
  "permission_mode": "string",
  "hook_event_name": "SessionStart",
  "source": "startup|resume|clear|compact"
}

**Environment variable:** `CLAUDE_ENV_FILE` - write `export VAR=value` to persist env vars.

**Output (Plain text or JSON):**

{
  "hookSpecificOutput": {
    "hookEventName": "SessionStart",
    "additionalContext": "string"
  },
  "suppressOutput": true
}

Plain text stdout is added as context.

---

SessionEnd

**Purpose:** Cleanup, save state, log session.

**Input:**

{
  "session_id": "string",
  "transcript_path": "string",
  "cwd": "string",
  "permission_mode": "string",
  "hook_event_name": "SessionEnd",
  "reason": "clear|logout|prompt_input_exit|other"
}

**Output:** Cannot affect session (already ending). Use for cleanup only.

---

Stop

**Purpose:** Control when Claude stops, force continuation.

**Input:**

{
  "session_id": "string",
  "transcript_path": "string",
  "cwd": "string",
  "permission_mode": "string",
  "hook_event_name": "Stop",
  "stop_hook_active"
Read more
@vibeeval
Ships withvibecosystem

Your AI software team. Built on Claude Code. vibecosystem turns Claude Code into a full AI software team — 138 specialized agents that plan, build, review, test, and learn from every mistake. No configuration needed — just install and code.

541200 skills138 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
541
Star history of vibeeval/vibecosystem on GitHub, a chart by star-history.com

Other skills on vibecosystem.

achievements

achievements

Steam-style achievement system with XP, levels, streaks, and skill trees. Gamifies the development workflow. 25 achievements…

agent-benchmark

agent-benchmark

Framework for measuring and tracking agent response quality over time. Detects regressions before they reach production. Use when…

agent-linter

agent-linter

Agent ve skill dosyalarinin yapisal dogrulamasi. Frontmatter kontrol, naming convention, zorunlu bolum kontrolu, tutarlilik…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about hook-developer.

Which coding agents can use hook-developer?
hook-developer 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.