491a45dd43
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
59 lines
2.2 KiB
Bash
59 lines
2.2 KiB
Bash
#!/bin/bash
|
|
# Blocks writes to build artifacts, binary files, and dependency directories.
|
|
# Used as a PreToolUse hook for Edit|Write operations.
|
|
# Exit 2 = block the action. Exit 0 = allow.
|
|
|
|
# Requires jq for JSON parsing — fail closed if missing
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"jq is required for file protection hooks but is not installed.\"}}"
|
|
exit 2
|
|
fi
|
|
|
|
INPUT=$(cat)
|
|
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
|
|
if [ -z "$FILE_PATH" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Block dependency and build directories
|
|
case "$FILE_PATH" in
|
|
node_modules/*|*/node_modules/*)
|
|
REASON="Cannot write into node_modules/ — install dependencies via package manager instead." ;;
|
|
vendor/*|*/vendor/*)
|
|
REASON="Cannot write into vendor/ — use dependency manager instead." ;;
|
|
dist/*|*/dist/*|build/*|*/build/*|.next/*|*/.next/*)
|
|
REASON="Cannot write into build output directories — these are generated by the build process." ;;
|
|
__pycache__/*|*/__pycache__/*)
|
|
REASON="Cannot write into __pycache__/ — these are generated by Python." ;;
|
|
.venv/*|*/.venv/*|venv/*|*/venv/*)
|
|
REASON="Cannot write into virtual environment directories." ;;
|
|
*)
|
|
REASON="" ;;
|
|
esac
|
|
|
|
if [ -n "$REASON" ]; then
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"$REASON\"}}"
|
|
exit 2
|
|
fi
|
|
|
|
# Block binary and archive file extensions
|
|
BASENAME=$(basename "$FILE_PATH")
|
|
case "$BASENAME" in
|
|
*.wasm|*.so|*.dylib|*.dll|*.exe|*.o|*.a)
|
|
REASON="Cannot write binary files — these should be compiled, not hand-written." ;;
|
|
*.zip|*.tar|*.tar.gz|*.tar.bz2|*.tgz|*.rar|*.7z)
|
|
REASON="Cannot write archive files." ;;
|
|
*.mp4|*.mov|*.avi|*.mkv|*.mp3|*.wav|*.flac)
|
|
REASON="Cannot write media files — add these manually outside Claude Code." ;;
|
|
*.pyc|*.pyo|*.class)
|
|
REASON="Cannot write compiled bytecode files." ;;
|
|
esac
|
|
|
|
if [ -n "$REASON" ]; then
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"$REASON\"}}"
|
|
exit 2
|
|
fi
|
|
|
|
exit 0
|