Initial commit: Claude Code Hooks with Diátaxis documentation
✨ 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>
This commit is contained in:
commit
162ca67098
34 changed files with 5904 additions and 0 deletions
124
hooks/session_logger.py
Executable file
124
hooks/session_logger.py
Executable file
|
|
@ -0,0 +1,124 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Session Logger Hook - PostToolUse[*] hook
|
||||
Logs all tool usage and feeds data to shadow learner
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
# Add lib directory to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "lib"))
|
||||
|
||||
from shadow_learner import ShadowLearner
|
||||
from session_state import SessionStateManager
|
||||
from context_monitor import ContextMonitor
|
||||
from models import ToolExecution
|
||||
|
||||
|
||||
def main():
|
||||
"""Main hook entry point"""
|
||||
try:
|
||||
# Read input from Claude Code
|
||||
input_data = json.loads(sys.stdin.read())
|
||||
|
||||
# Extract tool execution data
|
||||
tool = input_data.get("tool", "")
|
||||
parameters = input_data.get("parameters", {})
|
||||
success = input_data.get("success", True)
|
||||
error = input_data.get("error", "")
|
||||
execution_time = input_data.get("execution_time", 0.0)
|
||||
|
||||
# Create tool execution record
|
||||
execution = ToolExecution(
|
||||
timestamp=datetime.now(),
|
||||
tool=tool,
|
||||
parameters=parameters,
|
||||
success=success,
|
||||
error_message=error if error else None,
|
||||
execution_time=execution_time,
|
||||
context={}
|
||||
)
|
||||
|
||||
# Initialize components
|
||||
shadow_learner = ShadowLearner()
|
||||
session_manager = SessionStateManager()
|
||||
context_monitor = ContextMonitor()
|
||||
|
||||
# Feed execution to shadow learner
|
||||
shadow_learner.learn_from_execution(execution)
|
||||
|
||||
# Update session state
|
||||
session_manager.update_from_tool_use(input_data)
|
||||
|
||||
# Update context monitor
|
||||
context_monitor.update_from_tool_use(input_data)
|
||||
|
||||
# Save learned patterns periodically
|
||||
# (Only save every 10 executions to avoid too much disk I/O)
|
||||
if context_monitor.tool_executions % 10 == 0:
|
||||
shadow_learner.save_database()
|
||||
|
||||
# Log execution to file for debugging (optional)
|
||||
log_execution(execution)
|
||||
|
||||
# Always allow - this is a post-execution hook
|
||||
response = {
|
||||
"allow": True,
|
||||
"message": f"Logged {tool} execution"
|
||||
}
|
||||
|
||||
print(json.dumps(response))
|
||||
sys.exit(0)
|
||||
|
||||
except Exception as e:
|
||||
# Post-execution hooks should never block
|
||||
response = {
|
||||
"allow": True,
|
||||
"message": f"Logging error: {str(e)}"
|
||||
}
|
||||
print(json.dumps(response))
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def log_execution(execution: ToolExecution):
|
||||
"""Log execution to file for debugging and analysis"""
|
||||
try:
|
||||
log_dir = Path(".claude_hooks/logs")
|
||||
log_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create daily log file
|
||||
log_file = log_dir / f"executions_{datetime.now().strftime('%Y%m%d')}.jsonl"
|
||||
|
||||
# Append execution record
|
||||
with open(log_file, 'a') as f:
|
||||
f.write(json.dumps(execution.to_dict()) + "\n")
|
||||
|
||||
# Clean up old log files (keep last 7 days)
|
||||
cleanup_old_logs(log_dir)
|
||||
|
||||
except Exception:
|
||||
# Don't let logging errors break the hook
|
||||
pass
|
||||
|
||||
|
||||
def cleanup_old_logs(log_dir: Path):
|
||||
"""Clean up log files older than 7 days"""
|
||||
try:
|
||||
import time
|
||||
|
||||
cutoff_time = time.time() - (7 * 24 * 3600) # 7 days ago
|
||||
|
||||
for log_file in log_dir.glob("executions_*.jsonl"):
|
||||
if log_file.stat().st_mtime < cutoff_time:
|
||||
log_file.unlink()
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue