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
202
lib/cli.py
Normal file
202
lib/cli.py
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Claude Hooks CLI - Command line interface for managing hooks
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from .backup_manager import BackupManager
|
||||
from .session_state import SessionStateManager
|
||||
from .shadow_learner import ShadowLearner
|
||||
from .context_monitor import ContextMonitor
|
||||
|
||||
|
||||
def list_backups():
|
||||
"""List available backups"""
|
||||
backup_manager = BackupManager()
|
||||
backups = backup_manager.list_backups()
|
||||
|
||||
if not backups:
|
||||
print("No backups found.")
|
||||
return
|
||||
|
||||
print("Available Backups:")
|
||||
print("==================")
|
||||
|
||||
for backup in backups:
|
||||
timestamp = backup.get("timestamp", "unknown")
|
||||
backup_id = backup.get("backup_id", "unknown")
|
||||
reason = backup.get("session_state", {}).get("backup_history", [])
|
||||
if reason:
|
||||
reason = reason[-1].get("reason", "unknown")
|
||||
else:
|
||||
reason = "unknown"
|
||||
|
||||
print(f"🗂️ {backup_id}")
|
||||
print(f" 📅 {timestamp}")
|
||||
print(f" 📝 {reason}")
|
||||
print()
|
||||
|
||||
|
||||
def show_session_status():
|
||||
"""Show current session status"""
|
||||
session_manager = SessionStateManager()
|
||||
context_monitor = ContextMonitor()
|
||||
|
||||
summary = session_manager.get_session_summary()
|
||||
context_summary = context_monitor.get_session_summary()
|
||||
|
||||
print("Session Status:")
|
||||
print("===============")
|
||||
print(f"Session ID: {summary.get('session_id', 'unknown')}")
|
||||
print(f"Duration: {summary.get('session_stats', {}).get('duration_minutes', 0)} minutes")
|
||||
print(f"Context Usage: {context_summary.get('context_usage_ratio', 0):.1%}")
|
||||
print(f"Tool Calls: {summary.get('session_stats', {}).get('total_tool_calls', 0)}")
|
||||
print(f"Files Modified: {len(summary.get('modified_files', []))}")
|
||||
print(f"Commands Executed: {summary.get('session_stats', {}).get('total_commands', 0)}")
|
||||
print(f"Backups Created: {len(summary.get('backup_history', []))}")
|
||||
print()
|
||||
|
||||
if summary.get('modified_files'):
|
||||
print("Modified Files:")
|
||||
for file_path in summary['modified_files']:
|
||||
print(f" - {file_path}")
|
||||
print()
|
||||
|
||||
if context_summary.get('should_backup'):
|
||||
print("⚠️ Backup recommended (high context usage)")
|
||||
else:
|
||||
print("✅ No backup needed currently")
|
||||
|
||||
|
||||
def show_patterns():
|
||||
"""Show learned patterns"""
|
||||
shadow_learner = ShadowLearner()
|
||||
|
||||
print("Learned Patterns:")
|
||||
print("=================")
|
||||
|
||||
# Command patterns
|
||||
command_patterns = shadow_learner.db.command_patterns
|
||||
if command_patterns:
|
||||
print("\n🖥️ Command Patterns:")
|
||||
for pattern_id, pattern in list(command_patterns.items())[:10]: # Show top 10
|
||||
cmd = pattern.trigger.get("command", "unknown")
|
||||
confidence = pattern.confidence
|
||||
evidence = pattern.evidence_count
|
||||
success_rate = pattern.success_rate
|
||||
|
||||
print(f" {cmd}")
|
||||
print(f" Confidence: {confidence:.1%}")
|
||||
print(f" Evidence: {evidence} samples")
|
||||
print(f" Success Rate: {success_rate:.1%}")
|
||||
|
||||
# Context patterns
|
||||
context_patterns = shadow_learner.db.context_patterns
|
||||
if context_patterns:
|
||||
print("\n🔍 Context Patterns:")
|
||||
for pattern_id, pattern in list(context_patterns.items())[:5]: # Show top 5
|
||||
error_type = pattern.trigger.get("error_type", "unknown")
|
||||
confidence = pattern.confidence
|
||||
evidence = pattern.evidence_count
|
||||
|
||||
print(f" {error_type}")
|
||||
print(f" Confidence: {confidence:.1%}")
|
||||
print(f" Evidence: {evidence} samples")
|
||||
|
||||
if not command_patterns and not context_patterns:
|
||||
print("No patterns learned yet. Use Claude Code to start building the knowledge base!")
|
||||
|
||||
|
||||
def clear_patterns():
|
||||
"""Clear learned patterns"""
|
||||
response = input("Are you sure you want to clear all learned patterns? (y/N): ")
|
||||
if response.lower() == 'y':
|
||||
shadow_learner = ShadowLearner()
|
||||
shadow_learner.db = shadow_learner._load_database() # Reset to empty
|
||||
shadow_learner.save_database()
|
||||
print("✅ Patterns cleared successfully")
|
||||
else:
|
||||
print("Operation cancelled")
|
||||
|
||||
|
||||
def export_data():
|
||||
"""Export all hook data"""
|
||||
export_dir = Path("claude_hooks_export")
|
||||
export_dir.mkdir(exist_ok=True)
|
||||
|
||||
# Export session state
|
||||
session_manager = SessionStateManager()
|
||||
summary = session_manager.get_session_summary()
|
||||
|
||||
with open(export_dir / "session_data.json", 'w') as f:
|
||||
json.dump(summary, f, indent=2)
|
||||
|
||||
# Export patterns
|
||||
shadow_learner = ShadowLearner()
|
||||
|
||||
with open(export_dir / "patterns.json", 'w') as f:
|
||||
json.dump(shadow_learner.db.to_dict(), f, indent=2)
|
||||
|
||||
# Export logs
|
||||
logs_dir = Path(".claude_hooks/logs")
|
||||
if logs_dir.exists():
|
||||
import shutil
|
||||
shutil.copytree(logs_dir, export_dir / "logs", dirs_exist_ok=True)
|
||||
|
||||
print(f"✅ Data exported to {export_dir}")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main CLI entry point"""
|
||||
parser = argparse.ArgumentParser(description="Claude Code Hooks CLI")
|
||||
|
||||
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
||||
|
||||
# List backups
|
||||
subparsers.add_parser("list-backups", help="List available backups")
|
||||
|
||||
# Show session status
|
||||
subparsers.add_parser("status", help="Show current session status")
|
||||
|
||||
# Show patterns
|
||||
subparsers.add_parser("patterns", help="Show learned patterns")
|
||||
|
||||
# Clear patterns
|
||||
subparsers.add_parser("clear-patterns", help="Clear all learned patterns")
|
||||
|
||||
# Export data
|
||||
subparsers.add_parser("export", help="Export all hook data")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
try:
|
||||
if args.command == "list-backups":
|
||||
list_backups()
|
||||
elif args.command == "status":
|
||||
show_session_status()
|
||||
elif args.command == "patterns":
|
||||
show_patterns()
|
||||
elif args.command == "clear-patterns":
|
||||
clear_patterns()
|
||||
elif args.command == "export":
|
||||
export_data()
|
||||
else:
|
||||
print(f"Unknown command: {args.command}")
|
||||
parser.print_help()
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue