
Hook Development
Author Claude Code SessionStart and lifecycle hooks that auto-detect stack and inject project context before the agent works.
Overview
Hook Development is an agent skill for the Build phase that teaches Claude Code SessionStart and lifecycle hooks to detect project type and load context into CLAUDE_ENV_FILE.
Install
npx skills add https://github.com/anthropics/claude-plugins-official --skill hook-developmentWhat is this skill?
- SessionStart bash example that cd’s into CLAUDE_PROJECT_DIR and fails fast with set -euo pipefail
- Auto-detects Node, Rust, Go, Python, and Maven/Gradle Java and writes PROJECT_TYPE to CLAUDE_ENV_FILE
- Sets USES_TYPESCRIPT when tsconfig.json is present for downstream skill routing
- Scans for .github/workflows CI config to enrich environment context
- Pattern for unknown project types with explicit export PROJECT_TYPE=unknown
- Detects 5+ primary stacks: Node.js, Rust, Go, Python, and Java via Maven or Gradle manifests
Adoption & trust: 3.2k installs on skills.sh; 29.6k GitHub stars; 1/3 security scanners passed (skills.sh audits).
What problem does it solve?
Every new agent session starts blind to your stack unless you manually restate Node versus Rust versus Java and whether TypeScript or CI is in play.
Who is it for?
Solo builders shipping Claude Code plugins who want SessionStart automation across polyglot repos without hand-typing stack facts each chat.
Skip if: Teams that only need one-off deploy scripts or who do not use Claude Code hook events and CLAUDE_ENV_FILE.
When should I use this skill?
You are implementing or debugging Claude Code plugin hooks that should run at session start and persist project context.
What do I get? / Deliverables
After the skill runs you have hook scripts that export PROJECT_TYPE and related flags automatically so the agent starts with repo-accurate context.
- SessionStart hook script with stack detection branches
- CLAUDE_ENV_FILE exports for PROJECT_TYPE and optional USES_TYPESCRIPT or BUILD_SYSTEM
Recommended Skills
Journey fit
Hooks extend the coding agent itself—canonical placement is Build because you implement plugin automation alongside the repo you ship. Agent-tooling is the shelf for SKILL.md patterns, env injection, and official hook recipes rather than product feature code.
How it compares
Official hook recipes for Claude Code sessions—not a generic shell scripting tutor or an MCP server catalog entry.
Common Questions / FAQ
Who is hook-development for?
Indie and solo developers extending Claude Code with official plugin hooks who maintain real repos with package.json, Cargo.toml, go.mod, or Java build files.
When should I use hook-development?
Use it in Build when wiring SessionStart hooks before feature work, in Ship when you want CI paths detected at session open, and in Operate when standardizing env exports across teammates’ machines.
Is hook-development safe to install?
Review the Security Audits panel on this Prism page and treat hook scripts like any executable you add to the repo—inspect file writes to CLAUDE_ENV_FILE and shell side effects before enabling.
SKILL.md
READMESKILL.md - Hook Development
#!/bin/bash # Example SessionStart hook for loading project context # This script detects project type and sets environment variables set -euo pipefail # Navigate to project directory cd "$CLAUDE_PROJECT_DIR" || exit 1 echo "Loading project context..." # Detect project type and set environment if [ -f "package.json" ]; then echo "📦 Node.js project detected" echo "export PROJECT_TYPE=nodejs" >> "$CLAUDE_ENV_FILE" # Check if TypeScript if [ -f "tsconfig.json" ]; then echo "export USES_TYPESCRIPT=true" >> "$CLAUDE_ENV_FILE" fi elif [ -f "Cargo.toml" ]; then echo "🦀 Rust project detected" echo "export PROJECT_TYPE=rust" >> "$CLAUDE_ENV_FILE" elif [ -f "go.mod" ]; then echo "🐹 Go project detected" echo "export PROJECT_TYPE=go" >> "$CLAUDE_ENV_FILE" elif [ -f "pyproject.toml" ] || [ -f "setup.py" ]; then echo "🐍 Python project detected" echo "export PROJECT_TYPE=python" >> "$CLAUDE_ENV_FILE" elif [ -f "pom.xml" ]; then echo "☕ Java (Maven) project detected" echo "export PROJECT_TYPE=java" >> "$CLAUDE_ENV_FILE" echo "export BUILD_SYSTEM=maven" >> "$CLAUDE_ENV_FILE" elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then echo "☕ Java/Kotlin (Gradle) project detected" echo "export PROJECT_TYPE=java" >> "$CLAUDE_ENV_FILE" echo "export BUILD_SYSTEM=gradle" >> "$CLAUDE_ENV_FILE" else echo "❓ Unknown project type" echo "export PROJECT_TYPE=unknown" >> "$CLAUDE_ENV_FILE" fi # Check for CI configuration if [ -f ".github/workflows" ] || [ -f ".gitlab-ci.yml" ] || [ -f ".circleci/config.yml" ]; then echo "export HAS_CI=true" >> "$CLAUDE_ENV_FILE" fi echo "Project context loaded successfully" exit 0 #!/bin/bash # Example PreToolUse hook for validating Bash commands # This script demonstrates bash command validation patterns set -euo pipefail # Read input from stdin input=$(cat) # Extract command command=$(echo "$input" | jq -r '.tool_input.command // empty') # Validate command exists if [ -z "$command" ]; then echo '{"continue": true}' # No command to validate exit 0 fi # Check for obviously safe commands (quick approval) if [[ "$command" =~ ^(ls|pwd|echo|date|whoami)(\s|$) ]]; then exit 0 fi # Check for destructive operations if [[ "$command" == *"rm -rf"* ]] || [[ "$command" == *"rm -fr"* ]]; then echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "Dangerous command detected: rm -rf"}' >&2 exit 2 fi # Check for other dangerous commands if [[ "$command" == *"dd if="* ]] || [[ "$command" == *"mkfs"* ]] || [[ "$command" == *"> /dev/"* ]]; then echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "Dangerous system operation detected"}' >&2 exit 2 fi # Check for privilege escalation if [[ "$command" == sudo* ]] || [[ "$command" == su* ]]; then echo '{"hookSpecificOutput": {"permissionDecision": "ask"}, "systemMessage": "Command requires elevated privileges"}' >&2 exit 2 fi # Approve the operation exit 0 #!/bin/bash # Example PreToolUse hook for validating Write/Edit operations # This script demonstrates file write validation patterns set -euo pipefail # Read input from stdin input=$(cat) # Extract file path and content file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty') # Validate path exists if [ -z "$file_path" ]; then echo '{"continue": true}' # No path to validate exit 0 fi # Check for path traversal if [[ "$file_path" == *".."* ]]; then echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "Path traversal detected in: '"$file_path"'"}' >&2 exit 2 fi # Check for system directories if [[ "$file_path" == /etc/* ]] || [[ "$file_path" == /sys/* ]] || [[ "$file_path" == /usr/* ]]; then echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "Cannot write to system directory: '"$file_path"'"}' >&2 exit 2 fi # Check for sensitive files if [[ "$file_path" == *.env ]] || [[ "$file_path" == *secret* ]] || [[ "$file_path" == *c