Skip to content
Agentmart
Submit a tool

cc-create-hook

Create a project-level Claude Code hook.

Skill by d3v0psdan

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/d3v0psdan-cc-create-hook

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Create a project-level Claude Code hook. Use whenever the user wants to add, set up, wire up, or configure a hook — to run a script before or after a tool, validate or block a command, auto-run a linter or formatter on edits, load context at session start, or react to any Claude Code lifecycle event. Writes the hook config into .claude/settings.json and the script into .claude/hooks/. Trigger this even if the user just describes the behavior (e.g. "run prettier every time you edit a file") without saying the word "hook".

Use cases: documents, frontend, writing, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/cc-create-hook

What's inside

Skill name
cc-create-hook
Description
Create a project-level Claude Code hook. Use whenever the user wants to add, set up, wire up, or configure a hook — to run a script before or after a tool, validate or block a command, auto-run a linter or formatter on edits, load context at session start, or react to any Claude Code lifecycle event. Writes the hook config into .claude/settings.json and the script into .claude/hooks/. Trigger this even if the user just describes the behavior (e.g. "run prettier every time you edit a file") without saying the word "hook".
License
MIT
Instructions
140 lines in SKILL.md · view on GitHub

Files (2)

  • SKILL.md
  • events.md · references/

SKILL.md (first lines)

# Create a Claude Code hook

A hook is a script that fires automatically at a fixed point in Claude Code's lifecycle. Two pieces, always:

1. **The wiring** goes in `.claude/settings.json` (project-level, safe to commit).
2. **The script** goes in `.claude/hooks/`.

Work through the 5 steps below in order. Ask the user only what you can't already infer.

---

## Step 1 — Pick the event (when should it fire?)

Match the user's goal to one event. These five cover almost everything:

| Want to…                                          | Event              | Can it block? |
| :------------------------------------------------ | :----------------- | :------------ |
| Run a linter/formatter/test after a file changes  | `PostToolUse`      | no (observe)  |
| Block or validate a command/edit before it runs   | `PreToolUse`       | **yes**       |
| Add context or vet the prompt the user just sent  | `UserPromptSubmit` | yes           |
| Load context / set up env when a session starts    | `SessionStart`     | no            |
| Run a check when Claude finishes a turn            | `Stop`             | yes           |

Need something else (subagents, compaction, notifications, file watching, MCP, etc.)? See `references/events.md` for the full list of ~30 events.

## Step 2 — Pick the matcher (what narrows it?)

The matcher filters when the event fires. What it matches depends on the event:

- **Tool events** (`PreToolUse`, `PostToolUse`) match on **tool name**:
  - `"Bash"` — only Bash commands
  - `"Edit|Write"` — file edits or writes (pipe = "or")
  - `"mcp__.*"` — any MCP tool (this one's a regex)
  - `"*"` or omitted — everything
- **`SessionStart`** matches on `startup`, `resume`, `clear`, or `compact`.
- **`UserPromptSubmit`** and **`Stop`** take no matcher — they always fire.

To narrow a tool event further (e.g. only `git push`, only `.ts` files), add an `if` field to the handler in Step 4 using permission-rule syntax: `"Bash(git push *)"`, `"Edit(*.ts)"`. One rule per `if`; no `&&`/`||`.

## Step 3 — Write the script in `.claude/hooks/`

Claude Code sends the event as JSON on **stdin**. Read it, do the work, then signal the result with an **exit code**:

- `exit 0` → success. (For `PreToolUse`/`Stop`/`UserPromptSubmit`, this means "no objection".)
- `exit 2` → **block it**. Whatever you print to **stderr** is shown to Claude as the reason.
- any other code → non-blocking error, just logged.

Start from this template (`.claude/hooks/<name>.sh`):

```bash
#!/bin/bash
# Reads the event JSON from stdin.
input=$(cat)

# Pull out the field you care about (needs jq on PATH).
# For tool events, the tool's args live under .tool_input:
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
command=$(echo "$input"  | jq -r '.tool_input.command   // empty')

# --- do your thing here ---

exit 0
```

**Blocking example** — a `PreToolUse` hook that refuses `rm -rf`:

```bash
#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command // empty')

if echo "$command" | grep -q 'rm -rf'; then
  echo "Blocked: rm -rf is not allowed here." >&2
  exit 2
fi
exit 0
```

**Auto-format example** — a `PostToolUse` hook that runs prettier on the edited file:

```bash
#!/bin/bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')

[ -n "$file_path" ] && npx prettier --write "$file_path"
exit 0
```

Make it executable:

```bash
chmod +x .claude/hooks/<name>.sh
```

> Need finer control than exit codes (allow without prompting, rewrite the tool input, add context for Claude)? Print a JSON object to stdout on `exit 0` instead. The schemas are in `references/events.md`.

## Step 4 — Wire it into `.claude/settings.json`

The config nests three levels: **event → matcher group → handlers**. Use the `${CLAUDE_PROJECT_DIR}` placeholder so the path works no matter where Claude is running, and pass `args: []` (this runs the script directly, no quoting headaches).

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/<name>.sh",
            "args": []
          }
        ]
      }
    ]
  }
}
```

From d3v0psdan/claude-skills, MIT.

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Jun 19, 2026 (4 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from d3v0psdan

Cite this page

cc-create-hook skill. Agent Mart. https://agentmart.dev/skills/d3v0psdan-cc-create-hook (last updated 2026-10-24)