✨ Features: - 🧠 Shadow learner that builds intelligence from command patterns - 🛡️ Smart command validation with safety checks - 💾 Automatic context monitoring and backup system - 🔄 Session continuity across Claude restarts 📚 Documentation: - Complete Diátaxis-organized documentation - Learning-oriented tutorial for getting started - Task-oriented how-to guides for specific problems - Information-oriented reference for quick lookup - Understanding-oriented explanations of architecture 🚀 Installation: - One-command installation script - Bootstrap prompt for installation via Claude - Cross-platform compatibility - Comprehensive testing suite 🎯 Ready for real-world use and community feedback! 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
169 lines
4.8 KiB
Bash
Executable File
169 lines
4.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Claude Hooks Test Script
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
CLAUDE_HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
echo -e "${BLUE}Claude Code Hooks Test Suite${NC}"
|
|
echo "============================="
|
|
|
|
# Test 1: Context Monitor
|
|
echo -n "Testing context monitor... "
|
|
if python3 "$CLAUDE_HOOKS_DIR/hooks/context_monitor.py" <<< '{"prompt": "test prompt"}' >/dev/null 2>&1; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 2: Command Validator - Safe command
|
|
echo -n "Testing command validator (safe command)... "
|
|
if python3 "$CLAUDE_HOOKS_DIR/hooks/command_validator.py" <<< '{"tool": "Bash", "parameters": {"command": "ls -la"}}' >/dev/null 2>&1; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 3: Command Validator - Dangerous command
|
|
echo -n "Testing command validator (dangerous command)... "
|
|
OUTPUT=$(python3 "$CLAUDE_HOOKS_DIR/hooks/command_validator.py" <<< '{"tool": "Bash", "parameters": {"command": "rm -rf /"}}' 2>&1)
|
|
EXIT_CODE=$?
|
|
if echo "$OUTPUT" | grep -q '"allow": false' && [ $EXIT_CODE -eq 1 ]; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
echo "Expected dangerous command to be blocked with exit code 1"
|
|
echo "Got exit code: $EXIT_CODE"
|
|
echo "Output: $OUTPUT"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 4: Session Logger
|
|
echo -n "Testing session logger... "
|
|
if python3 "$CLAUDE_HOOKS_DIR/hooks/session_logger.py" <<< '{"tool": "Read", "parameters": {"file_path": "test.txt"}, "success": true}' >/dev/null 2>&1; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 5: Session Finalizer
|
|
echo -n "Testing session finalizer... "
|
|
if python3 "$CLAUDE_HOOKS_DIR/hooks/session_finalizer.py" <<< '{}' >/dev/null 2>&1; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 6: Shadow Learner
|
|
echo -n "Testing shadow learner... "
|
|
python3 << 'EOF'
|
|
import sys
|
|
sys.path.insert(0, 'lib')
|
|
from shadow_learner import ShadowLearner
|
|
from models import ToolExecution
|
|
from datetime import datetime
|
|
|
|
learner = ShadowLearner()
|
|
execution = ToolExecution(
|
|
timestamp=datetime.now(),
|
|
tool="Bash",
|
|
parameters={"command": "test command"},
|
|
success=True
|
|
)
|
|
learner.learn_from_execution(execution)
|
|
prediction = learner.predict_command_outcome("test command")
|
|
print("Shadow learner test completed")
|
|
EOF
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 7: Context Monitor functionality
|
|
echo -n "Testing context monitor functionality... "
|
|
python3 << 'EOF'
|
|
import sys
|
|
sys.path.insert(0, 'lib')
|
|
from context_monitor import ContextMonitor
|
|
|
|
monitor = ContextMonitor()
|
|
monitor.update_from_prompt({"prompt": "test prompt"})
|
|
usage = monitor.get_context_usage_ratio()
|
|
assert 0 <= usage <= 1, f"Invalid usage ratio: {usage}"
|
|
print("Context monitor functionality test completed")
|
|
EOF
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 8: File permissions
|
|
echo -n "Testing file permissions... "
|
|
if [ -x "$CLAUDE_HOOKS_DIR/hooks/context_monitor.py" ] && \
|
|
[ -x "$CLAUDE_HOOKS_DIR/hooks/command_validator.py" ] && \
|
|
[ -x "$CLAUDE_HOOKS_DIR/hooks/session_logger.py" ] && \
|
|
[ -x "$CLAUDE_HOOKS_DIR/hooks/session_finalizer.py" ]; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
echo "Hook scripts are not executable"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 9: Configuration files
|
|
echo -n "Testing configuration files... "
|
|
if [ -f "$CLAUDE_HOOKS_DIR/config/hooks.json.template" ] && \
|
|
[ -f "$CLAUDE_HOOKS_DIR/config/settings.json" ]; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
echo "Configuration files missing"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 10: Runtime directories
|
|
echo -n "Testing runtime directories... "
|
|
if [ -d "$CLAUDE_HOOKS_DIR/.claude_hooks" ] && \
|
|
[ -d "$CLAUDE_HOOKS_DIR/.claude_hooks/backups" ] && \
|
|
[ -d "$CLAUDE_HOOKS_DIR/.claude_hooks/logs" ] && \
|
|
[ -d "$CLAUDE_HOOKS_DIR/.claude_hooks/patterns" ]; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
echo "Runtime directories missing"
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}All tests passed! 🎉${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}Hook Status:${NC}"
|
|
echo "✓ Context monitoring ready"
|
|
echo "✓ Command validation ready"
|
|
echo "✓ Session logging ready"
|
|
echo "✓ Session finalization ready"
|
|
echo "✓ Shadow learner ready"
|
|
echo ""
|
|
echo -e "${BLUE}Next Steps:${NC}"
|
|
echo "1. Configure Claude Code to use the hooks"
|
|
echo "2. Start using Claude - the hooks will activate automatically"
|
|
echo "3. Check .claude_hooks/ directory for logs and patterns"
|
|
echo ""
|
|
echo -e "${YELLOW}Note:${NC} The shadow learner will start empty and learn from your usage patterns." |