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.
Create new Claude Code lifecycle hook (PreToolUse/PostToolUse/Stop/SessionStart) with bash + hooks.json.
$ npx skills add softspark/ai-toolkit --skill hook-creator -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install softspark/ai-toolkit hook-creator --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/softspark/ai-toolkit.git skills-src && mkdir -p .claude/skills && cp -r skills-src/app/skills/hook-creator .claude/skills/hook-creator && 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 "hook-creator" agent skill from https://github.com/softspark/ai-toolkit/tree/main/app/skills/hook-creator into .claude/skills/hook-creator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hook-creator", 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/softspark/ai-toolkit/tree/main/app/skills/hook-creatorType 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 softspark/ai-toolkit --skill hook-creator -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install softspark/ai-toolkit hook-creator --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/softspark/ai-toolkit.git skills-src && mkdir -p .agents/skills && cp -r skills-src/app/skills/hook-creator .agents/skills/hook-creator && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "hook-creator" agent skill from https://github.com/softspark/ai-toolkit/tree/main/app/skills/hook-creator into .agents/skills/hook-creator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hook-creator", 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 softspark/ai-toolkit --skill hook-creator -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install softspark/ai-toolkit hook-creator --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/softspark/ai-toolkit.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/app/skills/hook-creator .cursor/skills/hook-creator && 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 "hook-creator" agent skill from https://github.com/softspark/ai-toolkit/tree/main/app/skills/hook-creator into .cursor/skills/hook-creator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hook-creator", 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/softspark/ai-toolkit.git --path app/skills/hook-creator--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 softspark/ai-toolkit --skill hook-creator -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install softspark/ai-toolkit hook-creator --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/softspark/ai-toolkit.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/app/skills/hook-creator .gemini/skills/hook-creator && 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 "hook-creator" agent skill from https://github.com/softspark/ai-toolkit/tree/main/app/skills/hook-creator into .gemini/skills/hook-creator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hook-creator", 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 softspark/ai-toolkit hook-creatorInstalls 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 softspark/ai-toolkit --skill hook-creator -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/softspark/ai-toolkit.git skills-src && mkdir -p .github/skills && cp -r skills-src/app/skills/hook-creator .github/skills/hook-creator && 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 "hook-creator" agent skill from https://github.com/softspark/ai-toolkit/tree/main/app/skills/hook-creator into .github/skills/hook-creator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hook-creator", 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 softspark/ai-toolkit --skill hook-creator -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install softspark/ai-toolkit hook-creator --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/softspark/ai-toolkit.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/app/skills/hook-creator .opencode/skills/hook-creator && 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 "hook-creator" agent skill from https://github.com/softspark/ai-toolkit/tree/main/app/skills/hook-creator into .opencode/skills/hook-creator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hook-creator", 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.
hook-creatorCreate new Claude Code lifecycle hook (PreToolUse/PostToolUse/Stop/SessionStart) with bash + hooks.json.
Hook Creator is an agent skill from softspark/ai-toolkit. Create new Claude Code lifecycle hook (PreToolUse/PostToolUse/Stop/SessionStart) with bash + hooks.json. Triggers: create hook, lifecycle hook, PreToolUse, PostToolUse, hook event.
Its SKILL.md is about 3.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Agent Workflows. It works with Bash. The repository describes itself as: Professional-grade AI coding toolkit: 94 skills, 44 agents, multi-platform (Claude, Cursor, Windsurf, Copilot, Gemini, Cline, Roo Code, Aider, Augment, Antigravity, Codex CLI… The licence is Apache-2.0.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit d64db2b. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
ReadWriteEditBashGrepGlobFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
bashgitFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
code.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.
Hook Creator loads about 3.1k tokens when it runs. Until then it costs about 48 tokens; SKILL.md has 1,400 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.
allowed-tools: Read, Write, Edit, Bash, Grep, GlobAutomated 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 softspark/ai-toolkit at commit d64db2b, republished under its Apache-2.0 licence (© softspark). 1,400 words, ~3,108 tokens.
.claude/skills/hook-creator/SKILL.md (or your agent's skills folder).$ARGUMENTS
Create a new Claude Code hook following ai-toolkit conventions.
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
SessionStart | Session begins, resumes, or clears | startup|resume|clear | Context injection, rules reminder |
SessionEnd | Session is closing | any | Flush logs, save transcripts |
UserPromptSubmit | User submits a prompt | any | Prompt governance, usage tracking |
Notification | Claude sends a notification | any | OS alerts, Slack pings |
MessageDisplay | Assistant message text streams in completed-line batches | none | Return displayContent to replace the rendered batch without changing the transcript |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
PreToolUse | Before a tool executes | tool name (e.g. Bash) or if: rule | Safety guards, validation, "defer" for headless |
PostToolUse | After a tool executes | tool name | Feedback loops, logging, format-on-save |
PostToolUseFailure | After a tool fails | tool name | Failure telemetry, recovery hints |
PostToolBatch | After a batch of tool calls completes | any | Batch summaries, aggregate validation |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
Stop | Claude finishes responding | any | Quality checks, session save |
StopFailure | Turn ends due to an API error (rate limit, auth) | any | Alerting, fallback behavior |
UserPromptExpansion | Claude expands or rewrites a submitted prompt | any | Prompt policy and context shaping |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
SubagentStart | Subagent launches | any | Observability |
SubagentStop | Subagent completes | any | Result validation |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
PreCompact | Before context compaction; can block with exit 2 or {"decision":"block"} | any | Context preservation |
PostCompact | After compaction completes | any | Re-inject state that was summarized away |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
PreModelSwitch | Before a user/client model switch; exit 2 or decision: "block" cancels it | canonical target model | Model policy; requires Claude Code 2.1.251+ |
PostModelSwitch | After the session model changes; cannot block | canonical target model | Model-specific context; requires Claude Code 2.1.251+ |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
PermissionRequest | Tool awaiting permission; can return updatedInput | any | Headless approval flows |
PermissionDenied | Auto-mode classifier denied a tool call; return {retry: true} to allow retry | any | Coach the model, log denials |
Elicitation | MCP elicitation/create request arrives | any | Intercept / override MCP UI prompts |
ElicitationResult | Elicitation response ready to be sent back | any | Validate / transform elicitation replies |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
TaskCreated | New task registered via TaskCreate | any | Audit, assignment routing |
TaskCompleted | Agent Teams task finished | any | Lint, type check, notify |
TeammateIdle | Agent Teams member idle | any | Completeness reminder |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
WorktreeCreate | Worktree is being created; type: "http" can return hookSpecificOutput.worktreePath | any | Provision worktree dirs |
WorktreeRemove | Worktree is being removed | any | Cleanup |
CwdChanged | Working directory changes during a session | any | Reactive env management (e.g., direnv) |
DirectoryAdded | A working directory was added with /add-dir or SDK register_repo_root; runs asynchronously after the add and cannot block it | slash_command|register_repo_root | Prepare a newly added repository |
FileChanged | Tracked file is modified on disk | any | Re-lint, reload config |
ConfigChange | Settings / config file changed | any | Re-validate, warn on drift |
| Event | Fires When | Matcher | Typical Use |
|---|---|---|---|
Setup | First-run / initialization | any | Project bootstrap |
InstructionsLoaded | CLAUDE.md or .claude/rules/*.md loaded into context | load reason | Verify presence of mandatory rules |
Claude Code supports five handler type values in hooks.json:
| Type | Purpose | Required fields |
|---|---|---|
command | Run a shell script / binary | command (path + args) |
http | Call a local or remote HTTP endpoint | url |
prompt | Inject a prompt to the fast inline model and use its verdict | prompt |
agent | Spawn an experimental tool-using subagent to evaluate the event | prompt |
mcp_tool | Invoke an already-connected MCP tool | server, tool; optional input object |
command remains the default and ai-toolkit's hook entries all use it. The other types are documented here so you can author them by hand when needed.
PermissionRequest accepts prompt hooks but skips agent hooks. Both model-switch
events accept command, http, and mcp_tool only. MCP tool hooks use input
for arguments; arguments is not a supported handler field. MCP hooks on
SessionStart cannot run at launch before servers connect, and Setup always
skips them. Use command hooks for required initialization.
Source: https://code.claude.com/docs/en/hooks (reviewed 2026-09-23).
app/hooks/{event-name-kebab}.shapp/hooks.jsonscripts/validate.pyapp/hooks/{event-name-kebab}.sh#!/bin/bashTOOLKIT_HOOK_PROFILE env var (minimal = skip non-essential hooks){
"_source": "ai-toolkit",
"matcher": "",
"hooks": [
{
"type": "command",
"command": "\"$HOME/.softspark/ai-toolkit/hooks/{script-name}.sh\""
}
]
}Required fields:
_source: always "ai-toolkit" (used by merge/strip logic)matcher: tool name or regex for Pre/PostToolUse, empty string for global eventshooks[].type: "command", "http", "prompt", "agent", or "mcp_tool" (ai-toolkit uses "command")hooks[].command: path to script using $HOME/.softspark/ai-toolkit/hooks/ prefix (for type: command)Optional fields (read from Claude Code docs, not emitted by ai-toolkit by default):
Common to every handler type:
hooks[].if: one permission-rule filter (e.g. "Bash(git push*)"); evaluated only for tool eventshooks[].timeout: seconds to wait before canceling the handler (type and event defaults apply if omitted)hooks[].statusMessage: short message surfaced in the UI while the hook runshooks[].once: run once per session; only honored in skill frontmatter and ignored in settings files or agent frontmatterCommand-handler fields:
hooks[].args: argument vector for exec form. Prefer exec form when a command uses ${CLAUDE_PROJECT_DIR}, ${CLAUDE_PLUGIN_ROOT}, or ${CLAUDE_PLUGIN_DATA} path placeholdershooks[].async: run in the background without blocking; background hooks cannot return decisionshooks[].asyncRewake: run in the background and wake Claude on exit code 2; implies asynchooks[].shell: choose bash or powershell for shell form; ignored when args selects exec formPrompt and agent handlers both require hooks[].prompt; type: agent does not accept an agent name field. Agent handlers are experimental, so prefer command for production enforcement.
MessageDisplay has no matcher, runs once per rendered batch in interactive sessions, and defaults to a 10-second timeout. Its displayContent output changes only the screen text; Claude and the transcript retain the original response. DirectoryAdded is always asynchronous and non-blocking regardless of the handler configuration.
#!/bin/bash
# {script-name}.sh — {One-line purpose}.
#
# Fires on: {EventName}
# Matcher: {matcher or "all"}
# Skipped when TOOLKIT_HOOK_PROFILE=minimal.
PROFILE="${TOOLKIT_HOOK_PROFILE:-standard}"
[ "$PROFILE" = "minimal" ] && exit 0
# --- Hook logic here ---
exit 0hooks.jsonPre* hooks fast and deterministic — they gate every matching tool call, slow hooks throttle the whole agentPost* or Stop hook unless you intend to block further processing; exit 0 is the safe defaultTOOLKIT_HOOK_PROFILE env var. Profile minimal must be a no-op for non-essential hooks.bash app/hooks/{name}.sh) before adding it to hooks.jsonPreToolUse hooks that exit non-zero block the tool call. A slow or flaky hook (network call, lock contention) becomes a DoS against Claude's own workflow. Keep Pre hooks to pure-bash checks of local state.git log --all prints hundreds of lines the model then has to wade through — be surgical, print only what matters.hooks.json is resolved relative to the user's machine, not the ai-toolkit repo. Use $HOME/.softspark/ai-toolkit/hooks/<name>.sh as the canonical location (installer symlinks there).SessionStart with matcher startup|compact fires on both fresh starts AND after context compaction. Hooks that assume "new session" will mis-fire after compaction — check for explicit context markers if the distinction matters.posix-only in the description.After creating the hook:
app/hooks/ and is executable (chmod +x)app/hooks.json with _source: "ai-toolkit"scripts/validate.py passesbash app/hooks/{name}.sh/skill-creator/agent-creator/git-mastery or scripts/install_git_hooks.py© softspark, Apache-2.0. 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 app/skills/hook-creator of softspark/ai-toolkit.
Open the folder on GitHubat commit d64db2b
Hook Creator 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 |
|---|---|---|---|---|---|---|
| Hook Creator this skillsoftspark/ai-toolkit | 179 | — | ~3.1k | Automated safety check: Notes | Apache-2.0 | |
| Hook Development for Claude Code Pluginsanthropics/claude-plugins-official | 38k | 11 repos | ~4.1k | Automated safety check: Notes | Apache-2.0 | |
| Plugin Settings Patternanthropics/claude-plugins-official | 38k | 7 repos | ~3k | Automated safety check: Pass | Apache-2.0 | |
| Neat-Freak Knowledge CloseoutKKKKhazix/khazix-skills | 21k | — | ~1.9k | Automated safety check: Pass | MIT | |
| Crush Configurationcharmbracelet/crush | 29k | — | ~3.7k | Automated safety check: Pass | Custom licence | |
| Kimi Code DelegationCherryHQ/cherry-studio | 52k | 1 repos | ~504 | Automated safety check: Pass | AGPL-3.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
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.
KKKKhazix/khazix-skills
Brings project docs, agent rule files, authorized memory and leftover workspace files back in line with what the code and runtime actually do at the end of a work session.
charmbracelet/crush
Explains how to configure the Crush coding agent with crushrc or crush.json, covering providers, models, LSPs, MCP servers, hooks, permissions and config precedence.
CherryHQ/cherry-studio
Delegates one bounded repository task to Kimi Code in non-interactive prompt mode and reads back the final result from its JSON event stream.
github/gh-aw
Designs and verifies a deterministic grader that measures whether a GitHub Agentic Workflow run reached its real-world or repository outcome.
softspark/ai-toolkit
Prepare or verify a project QA environment with source identity, readiness, browser access, evidence paths and owned cleanup.
softspark/ai-toolkit
Accessibility validator: WCAG 2.1 AA, EN 301 549, EAA. An agent skill from softspark/ai-toolkit.
softspark/ai-toolkit
Analyzes code quality, complexity, patterns across codebase.
softspark/ai-toolkit
Drives a brief, specification, issue or existing PR through implementation, review, tests and QA to a ready PR.
softspark/ai-toolkit
Direct technical voice for docs, README, user-facing text. An agent skill from softspark/ai-toolkit.
softspark/ai-toolkit
Detect/generate/debug CI pipeline config (GitHub Actions, GitLab CI).
Works with
Categories
Create new Claude Code lifecycle hook (PreToolUse/PostToolUse/Stop/SessionStart) with bash + hooks.json. Hook Creator is an agent skill from softspark/ai-toolkit.json.
Hook Creator fits situations like: agent Workflows work in your project.
Run `npx skills add softspark/ai-toolkit --skill hook-creator -a claude-code`. Or copy the skill folder (app/skills/hook-creator in softspark/ai-toolkit) into .claude/skills/hook-creator in your project. Claude Code loads it when a task matches its description.
Run `npx skills add softspark/ai-toolkit --skill hook-creator -a codex`. Or copy the skill folder (app/skills/hook-creator in softspark/ai-toolkit) into .agents/skills/hook-creator 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 softspark/ai-toolkit --skill hook-creator -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/hook-creator, .gemini/skills/hook-creator, .github/skills/hook-creator and .opencode/skills/hook-creator in your project.
Going by SKILL.md and its folder, Hook Creator needs the command-line tools its instructions call (bash and git). Our summary lists: Python 3. Its frontmatter pre-approves these tools: Read, Write, Edit, Bash, Grep, Glob.
SKILL.md names 1 domain. As links in the text: code.claude.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Hook Creator is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.1k tokens (SKILL.md is roughly 12k 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 Hook Creator: Hook Development for Claude Code Plugins (anthropics/claude-plugins-official, 38k stars), Plugin Settings Pattern (anthropics/claude-plugins-official, 38k stars), Neat-Freak Knowledge Closeout (KKKKhazix/khazix-skills, 21k stars) and Crush Configuration (charmbracelet/crush, 29k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
softspark (a GitHub user) maintains it in softspark/ai-toolkit, which has 179 GitHub stars. The repository holds 112 skills in this directory. The repository was last updated on October 7, 2026.
Source: softspark/ai-toolkit on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.