Select hook scope (plugin, project, global) by audience. Use when authoring a hook.
npx skills add https://github.com/athola/claude-night-market --skill hook-scope-guide
This skill helps you choose the right location for Claude Code hooks based on their purpose, audience, and persistence needs.
abstract:hook-authoring)abstract:hooks-eval)> hooks/hooks.json is automatically loaded by Claude Code when the plugin is enabled.
> Do NOT add "hooks": "./hooks/hooks.json" to your plugin.json - this causes duplicate load errors.
> The hooks field in plugin.json is only needed for additional hook files beyond the standard hooks/hooks.json.
| Scope | Location | Audience | Committed? | Persistence |
|-------|----------|----------|------------|-------------|
| Plugin | hooks/hooks.json in plugin | Plugin users | With plugin | When plugin enabled |
| Project | .claude/settings.json | Team members | Yes (repo) | Per project |
| Global | ~/.claude/settings.json | Only you | Never | All sessions |
Only plugin users → Plugin hooks
All team members on this project → Project hooks
/src/production/ configsOnly me, everywhere → Global hooks
Yes, as part of a distributable plugin → Plugin hooks
Yes, shared with team in repo → Project hooks
No, keep private → Global hooks
Only when my plugin is active → Plugin hooks
Always in this specific project → Project hooks
Always, in every project I work on → Global hooks
Location: <plugin-root>/hooks/hooks.json
When to use:
Configuration:
{
"PreToolUse": [
{
"matcher": "Read",
"hooks": [{
"type": "command",
"command": "echo \"Plugin reading: $(jq -r '.tool_input.file_path')\" >> ${CLAUDE_PLUGIN_ROOT}/log.txt"
}]
}
]
}
> Note: Use string matchers ("Read") not object matchers ({"toolName": "Read"}).
Key features:
${CLAUDE_PLUGIN_ROOT} for plugin-relative pathsExamples:
Location: .claude/settings.json (in project root)
When to use:
Configuration:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "cmd=$(jq -r '.tool_input.command // empty'); if [[ \"$cmd\" == *\"production\"* ]]; then echo 'BLOCKED: Production access requires approval'; exit 1; fi"
}]
}
]
}
}
> Note: Use string matchers ("Bash") not object matchers.
Key features:
Examples:
Location: ~/.claude/settings.json
When to use:
Configuration:
{
"hooks": {
"PreToolUse": [
{
"hooks": [{
"type": "command",
"command": "echo \"$(date): $(jq -r '.tool_name')\" >> ~/.claude/audit.log"
}]
}
]
}
}
Key features:
Examples:
Claude Code loads settings in this priority (highest first):
claude --flag).claude/settings.local.json).claude/settings.json)~/.claude/settings.json)Important: Multiple hooks from different scopes can respond to the same event. When they do, all matching hooks execute in parallel.
Is this hook part of a plugin's core functionality?
├─ YES → Plugin hooks (hooks/hooks.json in plugin)
└─ NO ↓
Should all team members on this project have this hook?
├─ YES → Project hooks (.claude/settings.json)
└─ NO ↓
Should this hook apply to all my Claude sessions?
├─ YES → Global hooks (~/.claude/settings.json)
└─ NO → Reconsider if you need a hook at all
Plugin hooks:
Project hooks:
Global hooks:
SessionStart hooks now receive additional input fields via stdin:
| Field | Type | Description |
|-------|------|-------------|
| session_id | string | Unique session identifier |
| source | enum | "startup" \| "resume" \| "clear" \| "compact" |
| agent_type | string | Agent name if --agent flag used, empty otherwise |
The agent_type field enables scope-appropriate context injection:
# Skip heavy context for review agents
input_data = json.loads(sys.stdin.read())
if input_data.get("agent_type") in ["code-reviewer", "quick-query"]:
print(json.dumps({"hookSpecificOutput": {"additionalContext": "Minimal"}}))
This is particularly useful for:
least two of the three decision questions (audience, version control, persistence).
hooks/hooks.json, .claude/settings.json, or~/.claude/settings.json) is confirmed to exist or is created at the correct path.
"hooks": "./hooks/hooks.json" to plugin.json (duplicate-loadguard); this absence is verified before the hook is deployed.
on this machine.
Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take athola/hook-scope-guide from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.