skills/create-hook/SKILL.md
Interactive wizard that creates and installs Claude Code hooks in settings.json. Guides through lifecycle event selection, hook type (command/prompt/agent/http), matcher, and settings target, then writes the configuration. Use when user asks to "create a hook", "add a hook", "install a hook", "set up a hook for X", "make a hook that does Y", or "configure a hook". Do NOT use for general hook documentation or explaining what hooks are.
npx skillsauth add armandli/get-skilled create-hookInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a hook creation wizard. Conduct a short interview to understand what the user wants, then generate and install the hook configuration into the appropriate settings file.
Work through the steps in order. Do not skip steps. Ask each question, wait for the user's answer, then proceed.
If $ARGUMENTS is non-empty, treat it as the initial description and move to Step 2.
Otherwise, ask:
"What do you want this hook to do? Describe the behavior in plain English (e.g., 'run prettier after every file edit', 'block writes to .env', 'notify me when Claude finishes')."
Using the description, recommend the best lifecycle event from the table below. Present your recommendation with one sentence of reasoning. If two events are plausible, offer both and ask the user to choose.
| Desired behavior | Event | Matcher hint |
|---|---|---|
| Run something after file edits | PostToolUse | Edit\|Write |
| Block dangerous shell commands | PreToolUse | Bash |
| Protect specific files from edits | PreToolUse | Edit\|Write |
| Validate before any tool runs | PreToolUse | (none) |
| Log or react after a tool succeeds | PostToolUse | (tool name) |
| Notify when Claude needs attention | Notification | (none) |
| Notify / verify when Claude stops | Stop | (none) |
| Re-inject context after compaction | SessionStart | compact |
| Run setup at session start | SessionStart | startup |
| Validate or transform user input | UserPromptSubmit | (none) |
| Auto-approve known-safe permissions | PermissionRequest | (tool name) |
| Save state before compaction | PreCompact | (none) |
| Clean up when session ends | SessionEnd | (none) |
For the full event list and stdin schemas, see references/events-reference.md.
Present the four options and recommend the best fit:
| Type | When to use |
|---|---|
| command | Default. Shell command for formatting, notifications, logging, file protection. |
| prompt | The decision requires understanding intent — a Claude model answers yes/no. |
| agent | Verification requires reading files or running tools — a subagent decides. |
| http | POST event data to an external service or webhook. |
Recommend command unless the user explicitly needs LLM judgment (prompt) or codebase inspection (agent).
Ask: "What shell command should run?" If they describe behavior instead of a command, offer to generate one. Common patterns:
jq -r '.tool_input.file_path // empty' | xargs -I{} npx prettier --write "{}"osascript -e 'display notification "Claude needs input" with title "Claude Code"'notify-send 'Claude Code' 'Claude needs input'If the command is multi-line or complex, suggest creating a script at .claude/hooks/<name>.sh and referencing it by path. Remind the user to run chmod +x .claude/hooks/<name>.sh.
For blocking hooks (PreToolUse), confirm: exit 2 + stderr message blocks the action. Offer to wrap the command in a guard:
#!/usr/bin/env bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE" == *".env"* ]]; then
echo "Blocked: .env files are protected" >&2
exit 2
fi
Ask for the yes/no decision prompt text. Remind: yes = allow, no = block.
Ask for the agent prompt. Suggest a timeout (default 60s). Remind: the agent has tool access and returns a decision.
Ask for the endpoint URL. Ask if authentication headers are needed (note: headers are configured in the hook object).
Ask: "Should this hook fire only for specific tools or sources, or for every occurrence of the event?"
If they want filtering, help construct the regex:
Edit|Write, Bash, mcp__github__.*startup, resume, compact, clearpermission_prompt, idle_promptAn empty or omitted matcher fires on every occurrence of the event. Omit if the user wants global coverage.
Ask where to install the hook:
~/.claude/settings.json — applies to all projects on this machine.claude/settings.json — committed with the repo, shared with the team.claude/settings.local.json — project-specific, gitignoredRecommend:
Resolve the full path to the target settings file:
~/.claude/settings.json<cwd>/.claude/settings.json<cwd>/.claude/settings.local.jsonIf the parent directory does not exist, create it.
Read the existing settings file if it exists. If it does not exist, start with {}.
Merge the new hook into the JSON structure:
hooks.<EventName> (create the key if absent){
"matcher": "optional_regex",
"hooks": [
{
"type": "command",
"command": "your command here"
}
]
}
matcher is empty, omit the "matcher" key entirelyhooks.<EventName> arrayWrite the updated JSON back to the settings file (pretty-printed, 2-space indent).
Error handling:
.claude/ directory: create it with mkdir -pHook installed:
Event: <EventName>
Type: <command|prompt|agent|http>
Matcher: <regex or "(none — fires on all occurrences)">
Location: <full path to settings file>
<If command type and script file referenced>
Script: <path>
Action needed: run `chmod +x <path>` to make it executable
<If dependencies needed>
Dependencies: <e.g., jq, prettier, osascript>
PostToolUse or PreToolUse, note that the hook will fire on the next tool invocation — no restart required.After the skill's primary task completes, run:
python3 ${PWD}/.claude/skills/skill-stat/scripts/record-stat.py "create-hook"
tools
--- name: update-readme description: Updates a project README.md with build instructions, unit test instructions, and a mermaid architecture diagram. Use when a project README needs to be created or refreshed. Trigger phrases: "update readme", "generate readme", "create readme", "refresh readme docs". Emphasizes project interfaces, extension points, and customization hooks in the diagram — not concrete implementations. Do NOT use for documentation sites, wikis, or non-project READMEs. argument-h
business
--- name: skill-stat description: Records skill usage statistics and issue reports into .claude/skill-stats.md. Increments the Uses count for a skill name, and optionally logs an issue report that increments the Issues count and appends a row to the Issue Reports table. Use when tracking how often a skill is invoked, when a user reports a problem with a skill, or when another skill needs to log its own usage. Trigger phrases: "record skill stat", "log skill usage", "report skill issue". Do NOT u
testing
--- name: revert description: Reverts ALL git changes in the working directory: staged changes, unstaged modifications, and new untracked files. Use when user asks to "revert all changes", "undo all changes", "discard all changes", "reset all git changes", or "clean working directory". Do NOT use for reverting a specific file or a specific commit — those need targeted git commands. disable-model-invocation: true --- Revert all git changes in the working directory. This is destructive and cannot
tools
Scans a Python codebase for duplicate or near-duplicate logic patterns across functions, classes, and files, then extracts those patterns into typed utility classes in a shared module. Use when the user asks to "refactor this Python code", "find duplicate logic", "extract shared utilities", "apply DRY to Python", "deduplicate Python code", or "find repeated patterns in Python". Groups extracted helpers by the object type they operate on (strings, numbers, dates, collections, etc.). Do NOT use for performance optimization (use optimize-python), for debugging logic errors, or for explaining code. Do NOT extract code that appears only once. Run this skill before optimize-python.