Hook DevelopmentSAFE
Semi-automated research assistant for academic research and software development. Supports Claude Code, Codex CLI, Kimi Code CLI, and OpenCode across ideation, coding, experiments, writing, and publication.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
These scripts help validate, test, and lint hook implementations before deployment.
validate-hook-schema.sh
Validates hooks.json configuration files for correct structure and common issues.
Usage:
./validate-hook-schema.sh path/to/hooks.json
Checks:
- Valid JSON syntax
- Required fields present
- Valid hook event names
- Proper hook types (command/prompt)
- Timeout values in valid ranges
- Hardcoded path detection
- Prompt hook event compatibility
Example:
cd my-plugin ./validate-hook-schema.sh hooks/hooks.json
test-hook.sh
Tests individual hook scripts with sample input before deploying to Claude Code.
Usage:
./test-hook.sh [options]
Options:
-v, --verbose- Show detailed execution information-t, --timeout N- Set timeout in seconds (default: 60)--create-sample- Generate sample test input
Example:
# Create sample test input ./test-hook.sh --create-sample PreToolUse > test-input.json # Test a hook script ./test-hook.sh my-hook.sh test-input.json # Test with verbose output and custom timeout ./test-hook.sh -v -t 30 my-hook.sh test-input.json
Features:
- Sets up proper environment variables (CLAUDEPROJECTDIR, CLAUDEPLUGINROOT)
- Measures execution time
- Validates output JSON
- Shows exit codes and their meanings
- Captures environment file output
hook-linter.sh
Checks hook scripts for common issues and best practices violations.
Usage:
./hook-linter.sh [hook-script2.sh ...]
Checks:
- Shebang presence
set -euo pipefailusage- Stdin input reading
- Proper error handling
- Variable quoting (injection prevention)
- Exit code usage
- Hardcoded paths
- Long-running code detection
- Error output to stderr
- Input validation
Example:
# Lint single script ./hook-linter.sh ../examples/validate-write.sh # Lint multiple scr
29ad4d4206fbOBSERVED · 2026-10-07Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: hook-development
description: This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.
version: 0.1.0
---
# Hook Development for Claude Code Plugins
## Overview
Hooks are event-driven automation scripts that execute in response to Claude Code events. Use hooks to validate operations, enforce policies, add context, and integrate external tools into workflows.
**Key capabilities:**
- Validate tool calls before execution (PreToolUse)
- React to tool results (PostToolUse)
- Enforce completion standards (Stop, SubagentStop)
- Load project context (SessionStart)
- Automate workflows across the development lifecycle
## Hook Types
### Prompt-Based Hooks (Recommended)
Use LLM-driven decision making for context-aware validation:
```json
{
"type": "prompt",
"prompt": "Evaluate if this tool use is appropriate: $TOOL_INPUT",
"timeout": 30
}
```
**Supported events:** Stop, SubagentStop, UserPromptSubmit, PreToolUse
**Benefits:**
- Context-aware decisions based on natural language reasoning
- Flexible evaluation logic without bash scripting
- Better edge case handling
- Easier to maintain and extend
### Command Hooks
Execute bash commands for deterministic checks:
```json
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh",
"timeout": 60
}
```
**Use for:**
- Fast deterministic validations
- File system operations
- External tool integrations
- Performance-critical checks
## Hook Configuration Formats
### Plugin hooks.json Format
**For plugin hooks** in `hooks/hooks.json`, use wrapper format:
```json
{
"description": "Brief explanation of hooks (optional)",
"hooks": {
"PreToolUse": [...],
"Stop": [...],
"SessionStart": [...]
}
}
```
**Key points:**
- `description` field is optional
- `hooks` field is required wrapper containing actual hook events
- This is the **plugin-specific format**
**Example:**
```json
{
"description": "Validation hooks for code quality",
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/validate.sh"
}
]
}
]
}
}
```
### Settings Format (Direct)
**For user settings** in `.claude/settings.json`, use direct format:
```json
{
"PreToolUse": [...],
"Stop": [...],
"SessionStart": [...]
}
```
**Key points:**
- No wrapper - events directly at top level
- No description field
- This is the **settings format**
**Important:** The examples below show the hook event structure that goes inside either format. For plugin hooks.json, wrap these in `{"hooks": {...}}`.
## Hook Events
### PreToolUse
Execute before any tool runs. Use to approve, deny, or modify tool calls.
**Example (prompt-based):**
```json
{
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "prompt",
"prompt": "Validate file write safety. Check: system paths, credentials, path traversal, sensitive content. Return 'approve' or 'deny'."
}
]
}
]
}
```
**Output for PreToolUse:**
```json
{
"hookSpecificOutput": {
"permissionDecision": "allow|deny|ask",
"updatedInput": {"field": "modified_value"}
},
"systemMessage": "Explanation for Claude"
}
```
### PostToolUse
Execute after tool completes. Use to react to results, provide feedback, or log.
**Example:**
```json
{
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "prompt",
"prompt": "Analyze edit result for potential issues: syntax errors, security vulnerabilities, breaking changes. Provide feedback."
}
]
}
]
}
```
**Output behavior:**
- Exit 0: stdout shown in transcript
- Exit 2: stderr fed back to Claude
- systemMessage included in context
### Stop
Execute when main agent considers stopping. Use to validate completeness.
**Example:**
```json
{
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "prompt",
"prompt": "Verify task completion: tests run, build succeeded, questions answered. Return 'approve' to stop or 'block' with reason to continue."
}
]
}
]
}
```
**Decision output:**
```json
{
"decision": "approve|block",
"reason": "Explanation",
"systemMessage": "Additional context"
}
```
### SubagentStop
Execute when subagent considers stopping. Use to ensure subagent completed its task.
Similar to Stop hook, but for subagents.
### UserPromptSubmit
Execute when user submits a prompt. Use to add context, validate, or block prompts.
**Example:**
```json
{
"UserPromptSubmit": [
{
"matcher": "*",
"hooks": [
{
"type": "prompt",
"prompt": "Check if prompt requires security guidance. If discussing auth, permissions, or API security, return relevant warnings."
}
]
}
]
}
```
### SessionStart
Execute when Claude Code session begins. Use to load context and set environment.
**Example:**
```json
{
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh"
}
]
}
]
}
```
**Special capability:** Persist environment variables using `$CLAUDE_ENV_FILE`:
```bash
echo "export PROJECT_TYPE=nodejs" >> "$CLAUDE_ENV_FILE"
```
See `examples/load-context.sh` for complete example.
### SessionEnd
Execute when session ends. Use for cleanTrust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (1)
if [[ "$command" == sudo* ]] || [[ "$command" == su* ]]; then
Gates applied: no_behavioural_pass.
29ad4d4206fbfull audit observations/trust-audit/skill/galaxy-dawn__hook-development.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-07 | 29ad4d4206fb | SAFE | B | 89 | first audit |
Questions
What does the Hook Development skill do?
Semi-automated research assistant for academic research and software development. Supports Claude Code, Codex CLI, Kimi Code CLI, and OpenCode across ideation, coding, experiments, writing, and publication.
Is Hook Development safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can Hook Development access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
Which assistants does Hook Development work with?
Its documentation mentions claude-code. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (29ad4d4206fb), read on 2026-10-07. The repository is watched, and a new audit runs when it changes — this is the first audit.