pre-post-hooks — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited pre-post-hooks (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Claude Code hooks are shell commands that execute automatically in response to tool events. They enable validation, formatting, and guardrails without manual intervention.
PreToolUse --> Tool Executes --> PostToolUse
|
(session ends)
|
StopHooks live in ~/.claude/settings.json under the hooks key:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"command": "echo 'About to write a file'",
"description": "Log before file writes"
}
],
"PostToolUse": [
{
"matcher": "Edit",
"command": "npx prettier --write \"$CLAUDE_FILE_PATH\"",
"description": "Auto-format after editing JS/TS files"
}
],
"Stop": [
{
"command": "echo 'Session ended'",
"description": "Log session end"
}
]
}
}The matcher field filters which tool triggers the hook. It matches against tool names:
{
"matcher": "Edit",
"command": "..."
}Common tool names to match:
Write — file creationEdit — file modificationBash — shell command executionRead — file readingGlob — file searchGrep — content searchUse pipe | for multiple matchers:
{
"matcher": "Write|Edit",
"command": "npx prettier --write \"$CLAUDE_FILE_PATH\""
}Omit matcher entirely to match ALL tool calls (useful for Stop hooks).
Hooks receive context via environment variables:
| Variable | Description |
|---|---|
CLAUDE_FILE_PATH | The file path being operated on |
CLAUDE_TOOL_NAME | Name of the tool being called |
CLAUDE_SESSION_ID | Current session identifier |
A PreToolUse hook that exits non-zero blocks the tool from executing:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"command": "echo \"$CLAUDE_FILE_PATH\" | grep -qv '\\.md$' || (echo 'BLOCKED: Do not create markdown files' && exit 1)",
"description": "Block creation of .md files"
}
]
}
}Run checks or formatting after tool execution without blocking:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -q '\\.ts$'; then npx tsc --noEmit \"$CLAUDE_FILE_PATH\" 2>&1 | head -20; fi",
"description": "Type-check TypeScript files after edit"
}
]
}
}{
"hooks": {
"Stop": [
{
"command": "git diff --cached --name-only | xargs grep -l 'console.log' 2>/dev/null && echo 'WARNING: console.log found in staged files'",
"description": "Audit staged files for console.log before session ends"
}
]
}
}$CLAUDE_FILE_PATH instead of hardcoding file paths. Hooks should be project-agnostic.| Hook Type | Timing | Can Block? | Use Case |
|---|---|---|---|
| PreToolUse | Before tool | Yes (exit 1) | Validation, gates, warnings |
| PostToolUse | After tool | No | Formatting, type-checking, linting |
| Stop | Session end | No | Final audits, cleanup |
Config location: ~/.claude/settings.json > hooks Matcher syntax: Tool name string, pipe-separated for multiple Blocking: Only PreToolUse can block (non-zero exit code)
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.