Skip to content
Development
Skill

/hook-development

Use when creating, modifying, or debugging Claude Code hooks — PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification. Covers the plugin `hooks/hooks.json` wrapper format vs. the user `settings.json` direct format,

From plugin
session-orchestrator
5252 skills14 agents2 commands10 hooks
+1

Claude Code

$ npx -y skills add Kanevry/session-orchestrator --skill hook-development --agent claude-code

SKILL.md

hook-development.SKILL.md
name: hook-development
description: Use when creating, modifying, or debugging Claude Code hooks — PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification. Covers the plugin `hooks/hooks.json` wrapper format vs. the user `settings.json` direct format, matchers, security patterns, `$CLAUDE_PLUGIN_ROOT` portability, lifecycle limitations, and debugging. Trigger on "add a hook", "validate tool use", "block dangerous commands", "enforce completion", "hook-based automation".
user-invocable: false
model: sonnet

Hook Development for Claude Code Plugins

Use the [official Claude Code hooks reference](https://code.claude.com/docs/en/hooks) as the source of truth for current events and schemas. This skill keeps only the conventions needed to author this plugin's hooks.

Hook types used in this plugin

Claude Code also documents `http`, `mcp_tool`, and experimental `agent` handlers. Use those only after checking their current fields and event support in the official reference.

Prompt-based (LLM-driven, for complex reasoning)

{
  "type": "prompt",
  "prompt": "Evaluate whether this event should proceed: $ARGUMENTS",
  "timeout": 30
}

Prompt hooks are supported only on events documented for that handler type. `$ARGUMENTS` contains the hook input JSON.

Use for: context-aware decisions, flexible evaluation, natural-language reasoning.

Command (deterministic, for fast checks)

{
  "type": "command",
  "command": "${CLAUDE_PLUGIN_ROOT}/hooks/validate.mjs",
  "timeout": 60
}

Use for: fast deterministic validations, file-system ops, external tools, performance-critical paths.

**Our convention:** hook logic lives in `.mjs` files — see `hooks/pre-bash-destructive-guard.mjs` and `hooks/enforce-scope.mjs`. The manifest invokes them through the repository's runtime wrapper.

Configuration formats

Keep the file location and its outer document shape explicit when copying an example.

Plugin `hooks/hooks.json` — wrapper format

{
  "description": "Plugin hook description (optional)",
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/validate.mjs" }
        ]
      }
    ]
  }
}
  • `hooks` wrapper is required
  • `description` is optional

User or project `.claude/settings.json` — settings format

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": "~/my-hook.sh" }
        ]
      }
    ]
  }
}
  • The top-level `hooks` key is required in settings.
  • Plugin `hooks/hooks.json` may additionally carry a top-level `description`.

The distinction is registration and scope: settings hooks belong to a user, project, or managed policy; plugin hooks run while the plugin is enabled. The nested event → matcher group → handler shape is the same.

Hook events

| Event | When | Use for | |-------|------|---------| | `PreToolUse` | Before tool runs | Validate, modify, block | | `PostToolUse` | After tool completes | React to result, log | | `UserPromptSubmit` | User submits prompt | Add context, validate | | `Stop` | Main agent stopping | Completeness check | | `SubagentStop` | Subagent stopping | Task validation | | `SessionStart` | Session begins or resumes | Context load | | `SessionEnd` | Session ends | Cleanup, logging | | `PreCompact` | Before compaction | Preserve critical state | | `Notification` | User notified | Logging, reactions |

PreToolUse output schema

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Why this decision was made",
    "updatedInput": { "field": "modified_value" }
  },
  "systemMessage": "Explanation shown to Claude"
}

Stop / SubagentStop output

{
  "decision": "block",
  "reason": "Why Claude should continue",
  "systemMessage": "Additional context"
}

Omit `decision` to allow stopping. `approve` is not a valid Stop decision. For non-error feedback that keeps the conversation running, use `hookSpecificOutput.additionalContext` with `hookEventName` set to `Stop` or `SubagentStop`.

SessionStart: persist env vars

echo "export PROJECT_TYPE=nodejs" >> "$CLAUDE_ENV_FILE"

`$CLAUDE_ENV_FILE` is unique to SessionStart hooks.

Input schema

All hooks receive JSON on stdin:

{
  "session_id": "abc123",
  "transcript_path": "/path/to/transcript.jsonl",
  "cwd": "/current/working/dir",
  "permission_mode": "default",
  "hook_event_name": "PreToolUse"
}

Event-specific extras:

  • `PreToolUse`: `tool_name`, `tool_input`, `tool_use_id`
  • `PostToolUse`: `tool_name`, `tool_input`, `tool_response`, `tool_use_id`
  • `UserPromptSubmit`: `prompt`
  • `Stop`: `stop_hook_active`, `last_assistant_message`; `SubagentStop` also carries agent identity and transcript fields

Event fields vary and evolve. Parse only fields needed by the hook and consult the official event section before depending on one. The `UserPromptSubmit` field name above was last checked against the official reference on 2026-09-15 (branch `codex/ecc-systematic-review`); this plugin registers no `UserPromptSubmit` handler, so no code here exercises either spelling — verify before depending on it. Prompt and agent hooks receive the complete input through `$ARGUMENTS`.

Environment variables

| Var | Scope | Purpose | |-----|-------|---------| | `$CLAUDE_PROJECT_DIR` | All | Project root | | `$CLAUDE_PLUGIN_ROOT` | Plugin hooks | Plugin directory — **use this, never hardcode paths** | | `$CLAUDE_ENV_FILE` | SessionStart only | Persist env vars | | `$CLAUDE_CODE_REMOTE` | All (conditional) | Set if running remote |

Portability rule

// ✅ Portable — works everywhere the plugin installs
{ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/guard.mjs" }

// ❌ Broken — only wo
Read more
@kanevry
Ships withsession-orchestrator

Your coding agents get an agreed plan, a check after each round of changes and a handover to the next session. A free, MIT-licensed workflow plugin for people running Claude Code, Codex CLI, Cursor IDE or Pi on a git repository.

5252 skills14 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
52
Star history of Kanevry/session-orchestrator on GitHub, a chart by star-history.com

Other skills on session-orchestrator.

autopilot

autopilot

Use this skill when running an autonomous session-orchestration loop. Chains session-start → session-plan → wave-executor →…

bootstrap

bootstrap

Use this skill when scaffolding the minimum repository structure required by session-orchestrator. Invoked automatically by the…

brainstorm

brainstorm

Use when you have a feature idea but the scope or UX is still ambiguous — runs a lightweight Socratic design dialogue (3-5 AUQ…

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.

skills10d309k
@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…

react1d252k
@facebook@facebookInstall Skill

Questions about hook-development.

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