Initial commit
This commit is contained in:
28
hooks/hooks.json
Normal file
28
hooks/hooks.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Task",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre-agent-invoke.sh",
|
||||
"description": "Verify Rails project exists before agents run"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Task",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-agent-invoke.sh",
|
||||
"description": "Validate agent output and run tests"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
66
hooks/post-agent-invoke.sh
Executable file
66
hooks/post-agent-invoke.sh
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
# Post-agent invocation hook
|
||||
# Validates agent output and optionally runs tests
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔍 Validating agent output..."
|
||||
|
||||
AGENT_NAME=$1
|
||||
FILES_CHANGED=$2
|
||||
|
||||
# Check for common security issues
|
||||
echo "Checking for security issues..."
|
||||
|
||||
# Strong parameters check in controllers
|
||||
if echo "$FILES_CHANGED" | grep -q "controller"; then
|
||||
echo "Validating strong parameters in controllers..."
|
||||
for file in $FILES_CHANGED; do
|
||||
case "$file" in
|
||||
*controller*)
|
||||
if [ -f "$file" ]; then
|
||||
if grep -qE "def (create|update)" "$file"; then
|
||||
if ! grep -q "_params" "$file"; then
|
||||
echo "⚠️ Warning: $file may be missing strong parameters"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# SQL injection check (raw SQL usage)
|
||||
if grep -rn "\.where(\".*#\{" $FILES_CHANGED 2>/dev/null; then
|
||||
echo "⚠️ Warning: String interpolation in SQL detected - verify parameterization"
|
||||
fi
|
||||
|
||||
# Check for Rails conventions
|
||||
echo "Validating Rails conventions..."
|
||||
|
||||
# Model file naming
|
||||
for file in $FILES_CHANGED; do
|
||||
case "$file" in
|
||||
app/models/*)
|
||||
if [ -f "$file" ]; then
|
||||
filename=$(basename "$file" .rb)
|
||||
# Simple check - could be enhanced
|
||||
echo "✓ Model file: $file"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Run tests if test files were modified or created
|
||||
if echo "$FILES_CHANGED" | grep -qE "(spec|test)/"; then
|
||||
echo "Test files modified - tests should be run..."
|
||||
|
||||
if [ -f "bin/rspec" ]; then
|
||||
echo "ℹ️ RSpec detected - run: bundle exec rspec"
|
||||
elif [ -f "bin/rails" ]; then
|
||||
echo "ℹ️ Minitest detected - run: bundle exec rails test"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ Post-agent validation complete"
|
||||
exit 0
|
||||
21
hooks/pre-agent-invoke.sh
Executable file
21
hooks/pre-agent-invoke.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Pre-agent invocation hook - Optimized
|
||||
# Verifies Rails project exists before agents run
|
||||
|
||||
set -e
|
||||
|
||||
# Combined check: Gemfile exists AND contains rails gem AND has app/ directory
|
||||
if [ ! -f "Gemfile" ] || [ ! -d "app" ] || ! grep -q "gem ['\"]rails['\"]" Gemfile 2>/dev/null; then
|
||||
echo "❌ Not a Rails project (missing Gemfile, app/, or rails gem)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Quick version detection from Gemfile.lock (most accurate) or Gemfile
|
||||
if [ -f "Gemfile.lock" ]; then
|
||||
RAILS_VERSION=$(grep -A1 "^ rails " Gemfile.lock 2>/dev/null | head -1 | tr -d ' ' || echo "")
|
||||
else
|
||||
RAILS_VERSION=$(grep "gem ['\"]rails['\"]" Gemfile | sed -n 's/.*[~>= ]*\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p' | head -1)
|
||||
fi
|
||||
|
||||
echo "✅ Rails ${RAILS_VERSION:-?} project verified"
|
||||
exit 0
|
||||
74
hooks/pre-commit.sh
Executable file
74
hooks/pre-commit.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# Pre-commit hook
|
||||
# Security and quality checks before git commits
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔒 Running pre-commit security checks..."
|
||||
|
||||
# Get staged files
|
||||
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep "\.rb$" || true)
|
||||
|
||||
if [ -z "$STAGED_FILES" ]; then
|
||||
echo "No Ruby files staged for commit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Checking staged files..."
|
||||
|
||||
# Check for secrets/credentials
|
||||
echo "Checking for exposed secrets..."
|
||||
if git diff --cached | grep -iE "(password|secret|api_key|token)[[:space:]]*[:=]" | grep -v "params\.require" | grep -v "#" | grep -v "ENV\["; then
|
||||
echo "❌ Error: Potential secrets detected in staged changes"
|
||||
echo "Remove sensitive data before committing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for debugger statements
|
||||
echo "Checking for debugger statements..."
|
||||
if echo "$STAGED_FILES" | xargs grep -nE "(binding\.pry|debugger|byebug)" 2>/dev/null | grep -v "#"; then
|
||||
echo "❌ Error: Debugger statements detected"
|
||||
echo "Remove debugging code before committing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for strong parameters in controllers
|
||||
echo "Checking strong parameters..."
|
||||
CONTROLLER_FILES=$(echo "$STAGED_FILES" | grep "controller" || true)
|
||||
for file in $CONTROLLER_FILES; do
|
||||
if [ -f "$file" ]; then
|
||||
# Check if file has create or update actions
|
||||
if grep -qE "def (create|update)" "$file"; then
|
||||
if ! grep -Eq "params\.require|params\.permit" "$file"; then
|
||||
echo "⚠️ Warning: $file has create/update actions but no strong parameters visible"
|
||||
echo "Verify strong parameters are properly defined"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Check for SQL injection vulnerabilities
|
||||
echo "Checking for SQL injection risks..."
|
||||
if echo "$STAGED_FILES" | xargs grep -nE "\.where\(\".*#\{" 2>/dev/null; then
|
||||
echo "❌ Error: String interpolation in SQL detected"
|
||||
echo "Use parameterized queries to prevent SQL injection"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for missing migration reversibility
|
||||
echo "Checking migration reversibility..."
|
||||
MIGRATION_FILES=$(echo "$STAGED_FILES" | grep "db/migrate" || true)
|
||||
for file in $MIGRATION_FILES; do
|
||||
if [ -f "$file" ]; then
|
||||
# Check for dangerous operations without reversible block
|
||||
if grep -qE "remove_column|drop_table" "$file"; then
|
||||
if ! grep -Eq "reversible do|def down" "$file"; then
|
||||
echo "⚠️ Warning: $file has destructive operation without reversible block"
|
||||
echo "Add reversible block or down method"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Pre-commit checks passed"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user