refactor: Reorganize repository structure for optimal learning path
Reorder folders based on learning dependencies, complexity, and frequency of use: - 01-slash-commands (unchanged) - Quick wins for beginners - 02-memory (was 03) - Essential foundation - 03-skills (was 05) - Auto-invoked capabilities - 04-subagents (was 02) - Task delegation - 05-mcp (was 04) - External integration - 06-hooks (was 07) - Event automation - 07-plugins (was 06) - Bundled solutions - 08-checkpoints (unchanged) - Safe experimentation - 09-advanced-features (unchanged) - Power user tools Documentation improvements: - Add LEARNING-ROADMAP.md with detailed milestones and exercises - Simplify README.md for better scannability - Consolidate Quick Start and Getting Started sections - Combine Feature Comparison and Use Case Matrix tables - Reorder README sections: Learning Path → Quick Reference → Getting Started - Update all cross-references across module READMEs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
404
06-hooks/README.md
Normal file
404
06-hooks/README.md
Normal file
@@ -0,0 +1,404 @@
|
||||

|
||||
|
||||
# Hooks
|
||||
|
||||
Hooks are event-driven shell commands that execute automatically in response to Claude Code events. They enable automation, validation, and custom workflows without manual intervention.
|
||||
|
||||
## Overview
|
||||
|
||||
Hooks are shell commands that execute automatically in response to specific events in Claude Code. They enable custom workflows, validation, and automation. Hooks are triggered by:
|
||||
- **Pre-hooks**: Run before an action
|
||||
- **Post-hooks**: Run after an action
|
||||
- **Validation hooks**: Check conditions before proceeding
|
||||
|
||||
Hooks enable you to automate repetitive tasks, enforce code quality standards, and create seamless development workflows.
|
||||
|
||||
## Hook Types
|
||||
|
||||
| Hook Type | Event | Use Cases |
|
||||
|-----------|-------|-----------|
|
||||
| **Tool Hooks** | PreToolUse:*, PostToolUse:* | Auto-formatting, validation, logging |
|
||||
| **Session Hooks** | UserPromptSubmit, SessionStart, SessionEnd | Input validation, initialization, cleanup |
|
||||
| **Git Hooks** | PreCommit, PostCommit, PrePush | Testing, linting, notifications |
|
||||
|
||||
## Available Hook Types (Detailed)
|
||||
|
||||
### 1. Tool Hooks
|
||||
Execute before/after tool usage:
|
||||
- `PreToolUse:{ToolName}` - Before a tool is used
|
||||
- `PostToolUse:{ToolName}` - After a tool completes
|
||||
- Examples: `PreToolUse:Edit`, `PostToolUse:Bash`, `PreToolUse:Write`
|
||||
|
||||
### 2. Session Hooks
|
||||
Execute during session lifecycle:
|
||||
- `UserPromptSubmit` - Before processing user input
|
||||
- `SessionStart` - When a new session begins
|
||||
- `SessionEnd` - When a session ends
|
||||
|
||||
### 3. Git Hooks
|
||||
Execute during git operations:
|
||||
- `PreCommit` - Before creating a commit
|
||||
- `PostCommit` - After commit completes
|
||||
- `PrePush` - Before pushing to remote
|
||||
|
||||
## Common Hooks
|
||||
|
||||
```bash
|
||||
# Pre-commit hook - run tests
|
||||
PreCommit: "npm test"
|
||||
|
||||
# Post-write hook - format code
|
||||
PostToolUse:Write: "prettier --write ${file_path}"
|
||||
|
||||
# Pre-tool-use hook - validate
|
||||
PreToolUse:Edit: "eslint ${file_path}"
|
||||
|
||||
# User prompt validation
|
||||
UserPromptSubmit: "~/.claude/hooks/validate-prompt.sh"
|
||||
```
|
||||
|
||||
## Hook Variables
|
||||
|
||||
Available variables in hook commands:
|
||||
- `${file_path}` - Path to file being edited/written
|
||||
- `${command}` - Command being executed (Bash hooks)
|
||||
- `${tool_name}` - Name of the tool being used
|
||||
- `${session_id}` - Current session identifier
|
||||
|
||||
## Configuration
|
||||
|
||||
Hooks are configured in Claude Code settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse:Edit": "eslint --fix ${file_path}",
|
||||
"PostToolUse:Bash": "echo 'Command completed' >> /tmp/bash.log",
|
||||
"UserPromptSubmit": "~/.claude/hooks/validate-prompt.sh",
|
||||
"PreCommit": "npm test"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Auto-format Code on Edit
|
||||
|
||||
**Hook**: `PreToolUse:Write`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# ~/.claude/hooks/format-code.sh
|
||||
|
||||
FILE=$1
|
||||
|
||||
# Detect file type and format accordingly
|
||||
case "$FILE" in
|
||||
*.js|*.jsx|*.ts|*.tsx)
|
||||
prettier --write "$FILE"
|
||||
;;
|
||||
*.py)
|
||||
black "$FILE"
|
||||
;;
|
||||
*.go)
|
||||
gofmt -w "$FILE"
|
||||
;;
|
||||
esac
|
||||
```
|
||||
|
||||
**Configuration**:
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse:Write": "~/.claude/hooks/format-code.sh ${file_path}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example 2: Run Tests Before Commit
|
||||
|
||||
**Hook**: `PreCommit`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# ~/.claude/hooks/pre-commit.sh
|
||||
|
||||
echo "Running tests before commit..."
|
||||
|
||||
# Run tests
|
||||
npm test
|
||||
|
||||
# Check exit code
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Tests failed! Commit blocked."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Tests passed! Proceeding with commit."
|
||||
exit 0
|
||||
```
|
||||
|
||||
**Configuration**:
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreCommit": "~/.claude/hooks/pre-commit.sh"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example 3: Security Scan on File Write
|
||||
|
||||
**Hook**: `PostToolUse:Write`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# ~/.claude/hooks/security-scan.sh
|
||||
|
||||
FILE=$1
|
||||
|
||||
# Check for common security issues
|
||||
if grep -q "password\s*=\s*['\"]" "$FILE"; then
|
||||
echo "⚠️ WARNING: Potential hardcoded password detected in $FILE"
|
||||
fi
|
||||
|
||||
if grep -q "api[_-]key\s*=\s*['\"]" "$FILE"; then
|
||||
echo "⚠️ WARNING: Potential hardcoded API key detected in $FILE"
|
||||
fi
|
||||
|
||||
# Scan with semgrep if available
|
||||
if command -v semgrep &> /dev/null; then
|
||||
semgrep --config=auto "$FILE" --quiet
|
||||
fi
|
||||
```
|
||||
|
||||
**Configuration**:
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse:Write": "~/.claude/hooks/security-scan.sh ${file_path}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example 4: Log All Bash Commands
|
||||
|
||||
**Hook**: `PostToolUse:Bash`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# ~/.claude/hooks/log-bash.sh
|
||||
|
||||
COMMAND=$1
|
||||
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
|
||||
LOGFILE="$HOME/.claude/bash-commands.log"
|
||||
|
||||
echo "[$TIMESTAMP] $COMMAND" >> "$LOGFILE"
|
||||
```
|
||||
|
||||
**Configuration**:
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse:Bash": "~/.claude/hooks/log-bash.sh '${command}'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example 5: Validate User Prompts
|
||||
|
||||
**Hook**: `UserPromptSubmit`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# ~/.claude/hooks/validate-prompt.sh
|
||||
|
||||
# Read prompt from stdin
|
||||
PROMPT=$(cat)
|
||||
|
||||
# Check for prohibited patterns
|
||||
if echo "$PROMPT" | grep -qi "delete database"; then
|
||||
echo "❌ Blocked: Dangerous operation detected"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for required context
|
||||
if echo "$PROMPT" | grep -qi "deploy to production"; then
|
||||
if [ ! -f ".deployment-approved" ]; then
|
||||
echo "❌ Blocked: Production deployment requires approval file"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
```
|
||||
|
||||
**Configuration**:
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"UserPromptSubmit": "~/.claude/hooks/validate-prompt.sh"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Hook Exit Codes
|
||||
|
||||
Hooks communicate results via exit codes:
|
||||
- `0` - Success, continue operation
|
||||
- `1` - Failure, block operation (for pre-hooks)
|
||||
- Other codes - Treated as warnings
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Do's ✅
|
||||
- Keep hooks fast (< 1 second)
|
||||
- Use hooks for validation and automation
|
||||
- Handle errors gracefully
|
||||
- Use absolute paths
|
||||
- Log important events
|
||||
- Make hooks idempotent
|
||||
- Test hooks independently before deploying
|
||||
|
||||
### Don'ts ❌
|
||||
- Make hooks interactive
|
||||
- Use hooks for long-running tasks
|
||||
- Hardcode credentials
|
||||
- Ignore hook failures silently
|
||||
- Modify files unexpectedly
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
### Code Quality
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse:Write": "eslint --fix ${file_path}",
|
||||
"PostToolUse:Write": "prettier --check ${file_path}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Security
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse:Write": "~/.claude/hooks/security-scan.sh ${file_path}",
|
||||
"PreCommit": "git secrets --scan"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Testing
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreCommit": "npm test",
|
||||
"PostToolUse:Edit": "jest --findRelatedTests ${file_path}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Deployment
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PrePush": "npm run build && npm run test:e2e",
|
||||
"PostPush": "~/.claude/hooks/notify-team.sh"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Debugging Hooks
|
||||
|
||||
Enable hook debugging:
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"debug": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
View hook execution logs:
|
||||
```bash
|
||||
tail -f ~/.claude/hooks.log
|
||||
```
|
||||
|
||||
## Installation Instructions
|
||||
|
||||
### Step 1: Create Hooks Directory
|
||||
```bash
|
||||
mkdir -p ~/.claude/hooks
|
||||
```
|
||||
|
||||
### Step 2: Copy Example Hooks
|
||||
```bash
|
||||
cp 07-hooks/*.sh ~/.claude/hooks/
|
||||
chmod +x ~/.claude/hooks/*.sh
|
||||
```
|
||||
|
||||
### Step 3: Configure in Settings
|
||||
Edit `~/.claude/settings.json` to add hook configurations:
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse:Write": "~/.claude/hooks/format-code.sh ${file_path}",
|
||||
"PostToolUse:Write": "~/.claude/hooks/security-scan.sh ${file_path}",
|
||||
"PreCommit": "~/.claude/hooks/pre-commit.sh",
|
||||
"UserPromptSubmit": "~/.claude/hooks/validate-prompt.sh"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Make Scripts Executable
|
||||
```bash
|
||||
chmod +x ~/.claude/hooks/*.sh
|
||||
```
|
||||
|
||||
### Step 5: Test Your Hooks
|
||||
```bash
|
||||
# Enable debug mode for testing
|
||||
# Set "debug": true in hooks configuration
|
||||
tail -f ~/.claude/hooks.log
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Hook Not Executing
|
||||
1. Check hook path is correct
|
||||
2. Verify file has execute permissions
|
||||
3. Check hook name matches event exactly
|
||||
4. Enable debug mode
|
||||
|
||||
### Hook Blocking Operations
|
||||
1. Check hook exit code
|
||||
2. Review hook output/logs
|
||||
3. Test hook independently
|
||||
4. Add error handling
|
||||
|
||||
### Performance Issues
|
||||
1. Profile hook execution time
|
||||
2. Optimize slow operations
|
||||
3. Consider async execution
|
||||
4. Cache results when possible
|
||||
|
||||
## Advanced Examples
|
||||
|
||||
See the example files in this directory:
|
||||
- `format-code.sh` - Auto-format code before writing
|
||||
- `pre-commit.sh` - Run tests before commits
|
||||
- `security-scan.sh` - Scan for security issues
|
||||
- `log-bash.sh` - Log all bash commands
|
||||
- `validate-prompt.sh` - Validate user prompts
|
||||
- `notify-team.sh` - Send notifications on events
|
||||
|
||||
## Related Concepts
|
||||
|
||||
For more information on related Claude Code features, see:
|
||||
- **[Checkpoints and Rewind](../08-checkpoints/)** - Save and restore conversation state
|
||||
- **[Slash Commands](../01-slash-commands/)** - Create custom slash commands
|
||||
- **[Plugins](../07-plugins/)** - Bundled extension packages
|
||||
- **[Advanced Features](../09-advanced-features/)** - Explore advanced Claude Code capabilities
|
||||
- **[Main Concepts Guide](../claude_concepts_guide.md)** - Complete reference documentation
|
||||
46
06-hooks/format-code.sh
Normal file
46
06-hooks/format-code.sh
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# Auto-format code before writing
|
||||
# Hook: PreToolUse:Write
|
||||
|
||||
FILE=$1
|
||||
|
||||
if [ -z "$FILE" ]; then
|
||||
echo "Usage: $0 <file_path>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Detect file type and format accordingly
|
||||
case "$FILE" in
|
||||
*.js|*.jsx|*.ts|*.tsx)
|
||||
if command -v prettier &> /dev/null; then
|
||||
echo "Formatting JavaScript/TypeScript file: $FILE"
|
||||
prettier --write "$FILE"
|
||||
fi
|
||||
;;
|
||||
*.py)
|
||||
if command -v black &> /dev/null; then
|
||||
echo "Formatting Python file: $FILE"
|
||||
black "$FILE"
|
||||
fi
|
||||
;;
|
||||
*.go)
|
||||
if command -v gofmt &> /dev/null; then
|
||||
echo "Formatting Go file: $FILE"
|
||||
gofmt -w "$FILE"
|
||||
fi
|
||||
;;
|
||||
*.rs)
|
||||
if command -v rustfmt &> /dev/null; then
|
||||
echo "Formatting Rust file: $FILE"
|
||||
rustfmt "$FILE"
|
||||
fi
|
||||
;;
|
||||
*.java)
|
||||
if command -v google-java-format &> /dev/null; then
|
||||
echo "Formatting Java file: $FILE"
|
||||
google-java-format -i "$FILE"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
18
06-hooks/log-bash.sh
Normal file
18
06-hooks/log-bash.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
# Log all bash commands
|
||||
# Hook: PostToolUse:Bash
|
||||
|
||||
COMMAND="$1"
|
||||
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
|
||||
LOGFILE="$HOME/.claude/bash-commands.log"
|
||||
|
||||
# Create log directory if it doesn't exist
|
||||
mkdir -p "$(dirname "$LOGFILE")"
|
||||
|
||||
# Log the command
|
||||
echo "[$TIMESTAMP] $COMMAND" >> "$LOGFILE"
|
||||
|
||||
# Optional: Log to system log as well
|
||||
# logger -t "claude-bash" "$COMMAND"
|
||||
|
||||
exit 0
|
||||
66
06-hooks/notify-team.sh
Normal file
66
06-hooks/notify-team.sh
Normal file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
# Send notifications on events
|
||||
# Hook: PostPush
|
||||
|
||||
REPO_NAME=$(basename $(git rev-parse --show-toplevel 2>/dev/null) 2>/dev/null)
|
||||
COMMIT_MSG=$(git log -1 --pretty=%B 2>/dev/null)
|
||||
AUTHOR=$(git log -1 --pretty=%an 2>/dev/null)
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
||||
|
||||
echo "📢 Sending notification to team..."
|
||||
|
||||
# Slack webhook example (replace with your webhook URL)
|
||||
SLACK_WEBHOOK="${SLACK_WEBHOOK_URL:-}"
|
||||
|
||||
if [ -n "$SLACK_WEBHOOK" ]; then
|
||||
curl -X POST "$SLACK_WEBHOOK" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{
|
||||
\"text\": \"New push to *$REPO_NAME*\",
|
||||
\"attachments\": [{
|
||||
\"color\": \"good\",
|
||||
\"fields\": [
|
||||
{\"title\": \"Branch\", \"value\": \"$BRANCH\", \"short\": true},
|
||||
{\"title\": \"Author\", \"value\": \"$AUTHOR\", \"short\": true},
|
||||
{\"title\": \"Commit\", \"value\": \"$COMMIT_MSG\"}
|
||||
]
|
||||
}]
|
||||
}" \
|
||||
--silent --output /dev/null
|
||||
|
||||
echo "✅ Slack notification sent"
|
||||
fi
|
||||
|
||||
# Discord webhook example (replace with your webhook URL)
|
||||
DISCORD_WEBHOOK="${DISCORD_WEBHOOK_URL:-}"
|
||||
|
||||
if [ -n "$DISCORD_WEBHOOK" ]; then
|
||||
curl -X POST "$DISCORD_WEBHOOK" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{
|
||||
\"content\": \"**New push to $REPO_NAME**\",
|
||||
\"embeds\": [{
|
||||
\"title\": \"$COMMIT_MSG\",
|
||||
\"color\": 3066993,
|
||||
\"fields\": [
|
||||
{\"name\": \"Branch\", \"value\": \"$BRANCH\", \"inline\": true},
|
||||
{\"name\": \"Author\", \"value\": \"$AUTHOR\", \"inline\": true}
|
||||
]
|
||||
}]
|
||||
}" \
|
||||
--silent --output /dev/null
|
||||
|
||||
echo "✅ Discord notification sent"
|
||||
fi
|
||||
|
||||
# Email notification example
|
||||
EMAIL_TO="${TEAM_EMAIL:-}"
|
||||
|
||||
if [ -n "$EMAIL_TO" ]; then
|
||||
echo "New push to $REPO_NAME by $AUTHOR" | \
|
||||
mail -s "Git Push: $BRANCH" "$EMAIL_TO"
|
||||
|
||||
echo "✅ Email notification sent"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
48
06-hooks/pre-commit.sh
Normal file
48
06-hooks/pre-commit.sh
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
# Run tests before commit
|
||||
# Hook: PreCommit
|
||||
|
||||
echo "🧪 Running tests before commit..."
|
||||
|
||||
# Check if package.json exists (Node.js project)
|
||||
if [ -f "package.json" ]; then
|
||||
if grep -q "\"test\":" package.json; then
|
||||
npm test
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Tests failed! Commit blocked."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if pytest is available (Python project)
|
||||
if [ -f "pytest.ini" ] || [ -f "setup.py" ]; then
|
||||
if command -v pytest &> /dev/null; then
|
||||
pytest
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Tests failed! Commit blocked."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if go.mod exists (Go project)
|
||||
if [ -f "go.mod" ]; then
|
||||
go test ./...
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Tests failed! Commit blocked."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if Cargo.toml exists (Rust project)
|
||||
if [ -f "Cargo.toml" ]; then
|
||||
cargo test
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Tests failed! Commit blocked."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ All tests passed! Proceeding with commit."
|
||||
exit 0
|
||||
61
06-hooks/security-scan.sh
Normal file
61
06-hooks/security-scan.sh
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
# Security scan on file write
|
||||
# Hook: PostToolUse:Write
|
||||
|
||||
FILE=$1
|
||||
|
||||
if [ -z "$FILE" ]; then
|
||||
echo "Usage: $0 <file_path>"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "🔒 Running security scan on: $FILE"
|
||||
|
||||
ISSUES_FOUND=0
|
||||
|
||||
# Check for hardcoded passwords
|
||||
if grep -qE "(password|passwd|pwd)\s*=\s*['\"][^'\"]+['\"]" "$FILE"; then
|
||||
echo "⚠️ WARNING: Potential hardcoded password detected in $FILE"
|
||||
ISSUES_FOUND=1
|
||||
fi
|
||||
|
||||
# Check for hardcoded API keys
|
||||
if grep -qE "(api[_-]?key|apikey|access[_-]?token)\s*=\s*['\"][^'\"]+['\"]" "$FILE"; then
|
||||
echo "⚠️ WARNING: Potential hardcoded API key detected in $FILE"
|
||||
ISSUES_FOUND=1
|
||||
fi
|
||||
|
||||
# Check for hardcoded secrets
|
||||
if grep -qE "(secret|token)\s*=\s*['\"][^'\"]+['\"]" "$FILE"; then
|
||||
echo "⚠️ WARNING: Potential hardcoded secret detected in $FILE"
|
||||
ISSUES_FOUND=1
|
||||
fi
|
||||
|
||||
# Check for private keys
|
||||
if grep -q "BEGIN.*PRIVATE KEY" "$FILE"; then
|
||||
echo "⚠️ WARNING: Private key detected in $FILE"
|
||||
ISSUES_FOUND=1
|
||||
fi
|
||||
|
||||
# Check for AWS keys
|
||||
if grep -qE "AKIA[0-9A-Z]{16}" "$FILE"; then
|
||||
echo "⚠️ WARNING: AWS access key detected in $FILE"
|
||||
ISSUES_FOUND=1
|
||||
fi
|
||||
|
||||
# Scan with semgrep if available
|
||||
if command -v semgrep &> /dev/null; then
|
||||
semgrep --config=auto "$FILE" --quiet 2>/dev/null
|
||||
fi
|
||||
|
||||
# Scan with trufflehog if available
|
||||
if command -v trufflehog &> /dev/null; then
|
||||
trufflehog filesystem "$FILE" --only-verified --quiet 2>/dev/null
|
||||
fi
|
||||
|
||||
if [ $ISSUES_FOUND -eq 0 ]; then
|
||||
echo "✅ No security issues found"
|
||||
fi
|
||||
|
||||
# Don't block the operation, just warn
|
||||
exit 0
|
||||
43
06-hooks/validate-prompt.sh
Normal file
43
06-hooks/validate-prompt.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
# Validate user prompts
|
||||
# Hook: UserPromptSubmit
|
||||
|
||||
# Read prompt from stdin
|
||||
PROMPT=$(cat)
|
||||
|
||||
echo "🔍 Validating prompt..."
|
||||
|
||||
# Check for dangerous operations
|
||||
DANGEROUS_PATTERNS=(
|
||||
"rm -rf /"
|
||||
"delete database"
|
||||
"drop database"
|
||||
"format disk"
|
||||
"dd if="
|
||||
)
|
||||
|
||||
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
|
||||
if echo "$PROMPT" | grep -qi "$pattern"; then
|
||||
echo "❌ Blocked: Dangerous operation detected: $pattern"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Check for production deployments
|
||||
if echo "$PROMPT" | grep -qiE "(deploy|push).*production"; then
|
||||
if [ ! -f ".deployment-approved" ]; then
|
||||
echo "❌ Blocked: Production deployment requires approval"
|
||||
echo "Create .deployment-approved file to proceed"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for required context in certain operations
|
||||
if echo "$PROMPT" | grep -qi "refactor"; then
|
||||
if [ ! -f "tests/" ] && [ ! -f "test/" ]; then
|
||||
echo "⚠️ Warning: Refactoring without tests may be risky"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ Prompt validation passed"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user