Automates bash commands and file modifications before and after specific tool usage and at session start.
/plugin marketplace add brite-nites/brite-claude-plugins/plugin install workflows@brite-claude-pluginsDefined in hooks/hooks.json
{
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "INPUT=$(cat); printf '%s\\n' \"$INPUT\" | grep -Eiq 'rm[[:space:]]+-[a-zA-Z]*r[a-zA-Z]*f|rm[[:space:]]+-[a-zA-Z]*f[a-zA-Z]*r|git[[:space:]]+push.*[[:space:]]-f|git[[:space:]]+push.*--force([[:space:]]|\"|$)|drop[[:space:]]+(table|database)|chmod[[:space:]]+777|(curl|wget)[^\"]*[|][[:space:]]*(bash|sh|zsh)' && echo '{\"ok\":false,\"reason\":\"Blocked: destructive command detected (rm -rf, force push, DROP, chmod 777, or piped download)\"}' || echo '{\"ok\":true}'",
"timeout": 5,
"statusMessage": "Scanning for destructive commands..."
},
{
"type": "prompt",
"model": "haiku",
"prompt": "You are a security reviewer. Evaluate whether the Bash command in this tool call contains dangerous patterns.\n\nCheck for:\n1. Destructive commands: rm -rf, git push --force, DROP TABLE, kill -9, chmod 777, mkfs, dd, format\n2. Piped downloads: curl|bash, wget|sh, or any pipe from a URL into a shell\n3. Credential exposure: commands that echo/print/log secrets, API keys, passwords, or tokens\n4. Unsafe network operations: downloading and executing unknown scripts\n\nIf ANY dangerous pattern is found, respond with {\"ok\": false, \"reason\": \"<specific risk description>\"}.\nIf the command is safe, respond with {\"ok\": true}.",
"timeout": 10,
"statusMessage": "Security check..."
},
{
"type": "command",
"command": "INPUT=$(cat); CMD=$(printf '%s\\n' \"$INPUT\" | grep -o '\"command\":\"[^\"]*\"' | head -1 | sed 's/\"command\":\"//;s/\"//'); if ! printf '%s\\n' \"$CMD\" | grep -Eq '(^|[;&|[:space:]])git[[:space:]]+commit([[:space:]]|$)'; then echo '{\"ok\":true}'; exit 0; fi; errors=0; OLD_IFS=$IFS; IFS=$'\\n'; staged=$(git diff --cached --name-only --diff-filter=d 2>/dev/null || true); if [ -z \"$staged\" ]; then IFS=$OLD_IFS; echo '{\"ok\":true}'; exit 0; fi; if [ -f package.json ]; then js_files=''; for f in $staged; do case \"$f\" in *.js|*.jsx|*.ts|*.tsx) js_files=\"$js_files\\0$f\" ;; esac; done; if [ -n \"$js_files\" ]; then if command -v npx >/dev/null 2>&1 && npx --no-install eslint --version >/dev/null 2>&1; then printf '%b' \"$js_files\" | xargs -0 npx --no-install eslint --no-error-on-unmatched-pattern -- >/dev/null 2>&1 || errors=$((errors + 1)); fi; if [ -f tsconfig.json ] && command -v npx >/dev/null 2>&1 && npx --no-install tsc --version >/dev/null 2>&1; then npx --no-install tsc --noEmit >/dev/null 2>&1 || errors=$((errors + 1)); fi; fi; fi; if [ -f pyproject.toml ] || [ -f setup.py ]; then py_files=''; for f in $staged; do case \"$f\" in *.py) py_files=\"$py_files\\0$f\" ;; esac; done; if [ -n \"$py_files\" ] && command -v ruff >/dev/null 2>&1; then printf '%b' \"$py_files\" | xargs -0 ruff check -- >/dev/null 2>&1 || errors=$((errors + 1)); fi; fi; IFS=$OLD_IFS; if [ \"$errors\" -gt 0 ]; then echo '{\"ok\":false,\"reason\":\"Pre-commit quality checks failed. Run linters locally to see details: ESLint (JS/TS), tsc --noEmit (TS), or ruff check (Python).\"}'; else echo '{\"ok\":true}'; fi",
"timeout": 60,
"statusMessage": "Running pre-commit quality checks..."
}
],
"matcher": "Bash"
},
{
"hooks": [
{
"type": "command",
"command": "INPUT=$(cat); printf '%s\\n' \"$INPUT\" | grep -Eq 'sk-[a-zA-Z0-9]{20,}|sk-proj-[a-zA-Z0-9]{10,}|AKIA[A-Z0-9]{12,}|gh[ps]_[a-zA-Z0-9]{20,}|sk_(live|test)_[a-zA-Z0-9]{10,}' && echo '{\"ok\":false,\"reason\":\"Blocked: potential secret or API key detected in file content\"}' || echo '{\"ok\":true}'",
"timeout": 5,
"statusMessage": "Scanning for secrets..."
},
{
"type": "prompt",
"model": "haiku",
"prompt": "You are a security reviewer. Evaluate whether the file content in this tool call contains secrets or vulnerabilities.\n\nCheck for:\n1. Hardcoded secrets: API keys, passwords, tokens, private keys, connection strings with credentials\n2. Patterns like: AKIA (AWS keys), sk- (Stripe/OpenAI keys), ghp_ (GitHub tokens), Bearer <token>, password=, secret=, key= followed by actual values\n3. .env file contents being written to non-.env files\n4. Dangerous code patterns: dynamic code execution with user input, innerHTML with unsanitized data, SQL string concatenation, shell command injection via string interpolation\n\nIf ANY security issue is found, respond with {\"ok\": false, \"reason\": \"<specific risk description>\"}.\nIf the content is safe, respond with {\"ok\": true}.",
"timeout": 10,
"statusMessage": "Security check..."
}
],
"matcher": "Write|Edit"
}
],
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "INPUT=$(cat); file_path=$(printf '%s\\n' \"$INPUT\" | grep -o '\"file_path\":\"[^\"]*\"' | head -1 | sed 's/\"file_path\":\"//;s/\"//'); [ -z \"$file_path\" ] && exit 0; ext=\"${file_path##*.}\"; case \"$ext\" in js|jsx|ts|tsx) command -v npx >/dev/null 2>&1 && npx --no-install eslint --no-error-on-unmatched-pattern -- \"$file_path\" 2>/dev/null || true ;; py) command -v ruff >/dev/null 2>&1 && ruff check --fix -- \"$file_path\" 2>/dev/null || true ;; esac; exit 0",
"timeout": 30,
"statusMessage": "Running linter..."
}
],
"matcher": "Write|Edit"
}
],
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "printf '๐ง Brite Session Context\\n\\n'; git_ok='โ'; node_ok='โ'; gh_ok='โ'; npx_ok='โ'; git_ver=''; node_ver=''; gh_user=''; if command -v git >/dev/null 2>&1; then git_ok='โ'; git_ver=\" ($(git --version 2>&1 | sed 's/git version //'))\"; fi; if command -v node >/dev/null 2>&1; then node_ok='โ'; node_ver=\" ($(node --version 2>&1))\"; fi; if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then gh_ok='โ'; gh_user=\" ($(gh api user --jq '.login' 2>/dev/null || echo 'authed'))\"; elif command -v gh >/dev/null 2>&1; then gh_ok='โ '; gh_user=' (not authenticated โ run gh auth login)'; fi; if command -v npx >/dev/null 2>&1; then npx_ok='โ'; fi; printf 'Environment:\\n git ........... %s%s\\n node .......... %s%s\\n gh ............ %s%s\\n npx ........... %s\\n\\n' \"$git_ok\" \"$git_ver\" \"$node_ok\" \"$node_ver\" \"$gh_ok\" \"$gh_user\" \"$npx_ok\"; printf 'Key commands:\\n /workflows:sprint-planning โ Plan sprint & assign to cycle\\n /workflows:session-start โ Pick issue & create execution plan\\n /workflows:review โ Run review agents in parallel\\n /workflows:ship โ Create PR & compound learnings\\n /workflows:code-review โ Quick code review\\n /workflows:smoke-test โ Diagnose plugin environment\\n\\nConventions: Check /workflows:tech-stack for the project stack. Use react-best-practices for React/Next.js, python-best-practices for FastAPI/Python.\\n'",
"timeout": 5,
"statusMessage": "Loading Brite context..."
}
],
"matcher": "startup"
}
]
}{
"riskFlags": {
"touchesBash": true,
"matchAllTools": false,
"touchesFileWrites": true
},
"typeStats": {
"prompt": 2,
"command": 5
},
"eventStats": {
"PreToolUse": 5,
"PostToolUse": 1,
"SessionStart": 1
},
"originCounts": {
"absolutePaths": 0,
"pluginScripts": 0,
"projectScripts": 0
},
"timeoutStats": {
"commandsWithoutTimeout": 0
}
}