UNPKG

claude-flow-multilang

Version:

Revolutionary multilingual AI orchestration framework with cultural awareness and DDD architecture

431 lines (381 loc) • 10.7 kB
/** * Safe Hook Patterns - Templates for safe Claude Code hook configurations * * These patterns prevent infinite loops that could cost thousands of dollars * by avoiding recursive hook execution when hooks call 'claude' commands. */ /** * DANGEROUS PATTERN - DO NOT USE * This creates an infinite loop that can cost thousands of dollars! */ export const DANGEROUS_PATTERN_EXAMPLE = { name: 'DANGEROUS: Stop hook calling claude command', description: 'āŒ NEVER USE THIS - Creates infinite recursion loop', pattern: { hooks: { Stop: [ { matcher: '', hooks: [ { type: 'command', command: 'claude -c -p "Update all changes to history.md"', }, ], }, ], }, }, problems: [ '🚨 Creates infinite loop: Stop → claude command → Stop → claude command...', 'šŸ’° Can cost $3600+ per day by bypassing rate limits', '🚫 Makes system unresponsive', '⚔ No built-in protection in Claude Code', ], }; /** * SAFE PATTERN 1: Flag-based updates * Set a flag instead of calling claude directly */ export const SAFE_FLAG_PATTERN = { name: 'Safe Pattern: Flag-based updates', description: 'āœ… Set flag when update needed, run manually', pattern: { hooks: { Stop: [ { matcher: '', hooks: [ { type: 'command', command: 'bash -c \'echo "History update needed at $(date)" > ~/.claude/needs_update && echo "šŸ“ History update flagged. Run: claude -c -p \\"Update history.md\\""\'', }, ], }, ], }, }, benefits: [ 'āœ… No recursion - just sets a flag', 'šŸ’° Zero risk of infinite API calls', 'šŸ”„ User controls when update runs', 'šŸ“ Clear instructions for manual execution', ], usage: [ '1. Hook sets flag when update is needed', '2. User sees notification', '3. User manually runs: claude -c -p "Update history.md"', '4. Update runs once safely', ], }; /** * SAFE PATTERN 2: PostToolUse hooks instead of Stop hooks * React to specific tool usage rather than session end */ export const SAFE_POST_TOOL_PATTERN = { name: 'Safe Pattern: PostToolUse hooks', description: 'āœ… React to specific file operations instead of Stop events', pattern: { hooks: { PostToolUse: [ { matcher: 'Write|Edit|MultiEdit', hooks: [ { type: 'command', command: "echo 'File modified: {file}' >> ~/.claude/modifications.log", }, ], }, ], }, }, benefits: [ 'āœ… Only triggers on actual file changes', 'šŸŽÆ More precise than Stop hooks', 'šŸ“ Logs specific modifications', 'šŸ”„ No risk of Stop hook recursion', ], usage: [ '1. Triggers only when files are written/edited', '2. Logs the specific file that was modified', '3. Can be used for change tracking', '4. Safe to use with any logging command', ], }; /** * SAFE PATTERN 3: Conditional execution with skip-hooks * Check for hook context before executing claude commands */ export const SAFE_CONDITIONAL_PATTERN = { name: 'Safe Pattern: Conditional execution with context check', description: 'āœ… Check if running in hook context before calling claude', pattern: { hooks: { Stop: [ { matcher: '', hooks: [ { type: 'command', command: 'bash -c \'if [ -z "$CLAUDE_HOOK_CONTEXT" ]; then claude -c -p "Update history.md" --skip-hooks; else echo "Skipping update - in hook context"; fi\'', }, ], }, ], }, }, benefits: [ 'āœ… Checks hook context before execution', 'šŸ›”ļø Uses --skip-hooks flag for safety', 'šŸ”„ Prevents recursive hook calls', 'šŸ“Š Provides clear feedback', ], usage: [ '1. Checks CLAUDE_HOOK_CONTEXT environment variable', '2. Only runs claude if not in hook context', '3. Uses --skip-hooks to prevent triggering more hooks', '4. Shows clear message when skipping', ], }; /** * SAFE PATTERN 4: Batch processing with scheduled execution * Accumulate changes and process them on a schedule */ export const SAFE_BATCH_PATTERN = { name: 'Safe Pattern: Batch processing with scheduled execution', description: 'āœ… Accumulate changes and process them separately', pattern: { hooks: { Stop: [ { matcher: '', hooks: [ { type: 'command', command: 'echo "$(date): Session ended" >> ~/.claude/session_log.txt', }, ], }, ], }, }, additionalSetup: { cronJob: '# Add to crontab (run every hour):\n# 0 * * * * /path/to/update-history.sh', updateScript: `#!/bin/bash # update-history.sh - Safe batch update script LOCK_FILE="~/.claude/update.lock" LOG_FILE="~/.claude/session_log.txt" # Check if update is already running if [ -f "$LOCK_FILE" ]; then echo "Update already in progress" exit 1 fi # Create lock file touch "$LOCK_FILE" # Check if there are new sessions to process if [ -f "$LOG_FILE" ] && [ -s "$LOG_FILE" ]; then echo "Processing accumulated changes..." claude -c -p "Update history.md with recent session data" --skip-hooks # Archive the log mv "$LOG_FILE" "~/.claude/session_log_$(date +%Y%m%d_%H%M%S).txt" fi # Remove lock file rm "$LOCK_FILE"`, }, benefits: [ 'āœ… No risk of recursion', 'ā° Scheduled processing prevents overload', 'šŸ”’ Lock file prevents concurrent updates', 'šŸ“¦ Batches multiple sessions efficiently', ], }; /** * SAFE PATTERN 5: Database/file-based queue system * Use external queue for processing commands */ export const SAFE_QUEUE_PATTERN = { name: 'Safe Pattern: Queue-based command processing', description: 'āœ… Queue commands for external processing', pattern: { hooks: { Stop: [ { matcher: '', hooks: [ { type: 'command', command: 'echo \'{"command": "update-history", "timestamp": "\'$(date -Iseconds)\'", "session": "\'$CLAUDE_SESSION_ID\'"}\' >> ~/.claude/command_queue.jsonl', }, ], }, ], }, }, processor: `#!/usr/bin/env python3 # queue-processor.py - Safe command queue processor import json import subprocess import time import os from pathlib import Path QUEUE_FILE = Path.home() / '.claude' / 'command_queue.jsonl' PROCESSING_INTERVAL = 300 # 5 minutes def process_queue(): if not QUEUE_FILE.exists(): return # Read and clear queue atomically with open(QUEUE_FILE, 'r') as f: lines = f.readlines() # Clear the queue QUEUE_FILE.unlink() # Process commands for line in lines: try: cmd_data = json.loads(line.strip()) if cmd_data['command'] == 'update-history': print(f"Processing history update for session {cmd_data['session']}") subprocess.run([ 'claude', '-c', '-p', 'Update history.md', '--skip-hooks' ], check=True) time.sleep(2) # Rate limiting except Exception as e: print(f"Error processing command: {e}") if __name__ == '__main__': while True: try: process_queue() time.sleep(PROCESSING_INTERVAL) except KeyboardInterrupt: break`, benefits: [ 'āœ… Complete separation of hook and claude execution', 'ā° Rate limited processing', 'šŸ”„ Handles multiple queued commands', 'šŸ›”ļø No risk of infinite loops', ], }; /** * Get all safe patterns for documentation generation */ export const ALL_SAFE_PATTERNS = [ SAFE_FLAG_PATTERN, SAFE_POST_TOOL_PATTERN, SAFE_CONDITIONAL_PATTERN, SAFE_BATCH_PATTERN, SAFE_QUEUE_PATTERN, ]; /** * Generate safe hooks documentation */ export function generateSafeHooksGuide() { return `# šŸ›”ļø Safe Hook Patterns for Claude Code āš ļø **CRITICAL WARNING**: Stop hooks that call 'claude' commands create infinite loops that can cost thousands of dollars per day! ## 🚨 DANGEROUS PATTERN (NEVER USE) ${DANGEROUS_PATTERN_EXAMPLE.description} \`\`\`json ${JSON.stringify(DANGEROUS_PATTERN_EXAMPLE.pattern, null, 2)} \`\`\` **Problems:** ${DANGEROUS_PATTERN_EXAMPLE.problems.map((p) => `- ${p}`).join('\n')} --- ## āœ… SAFE PATTERNS ${ALL_SAFE_PATTERNS.map( (pattern) => ` ### ${pattern.name} ${pattern.description} **Configuration:** \`\`\`json ${JSON.stringify(pattern.pattern, null, 2)} \`\`\` **Benefits:** ${pattern.benefits.map((b) => `- ${b}`).join('\n')} ${ pattern.usage ? `**Usage:** ${pattern.usage.map((u, i) => `${i + 1}. ${u}`).join('\n')}` : '' } ${ pattern.additionalSetup ? `**Additional Setup:** ${ pattern.additionalSetup.cronJob ? ` **Cron Job:** \`\`\`bash ${pattern.additionalSetup.cronJob} \`\`\` ` : '' } ${ pattern.additionalSetup.updateScript ? ` **Update Script:** \`\`\`bash ${pattern.additionalSetup.updateScript} \`\`\` ` : '' }` : '' } ${ pattern.processor ? ` **Queue Processor:** \`\`\`python ${pattern.processor} \`\`\` ` : '' } --- `, ).join('')} ## šŸš€ Quick Migration Guide ### If you currently have this DANGEROUS pattern: \`\`\`json { "hooks": { "Stop": [{"hooks": [{"type": "command", "command": "claude -c -p 'Update history'"}]}] } } \`\`\` ### Replace with this SAFE pattern: \`\`\`json { "hooks": { "Stop": [{"hooks": [{"type": "command", "command": "touch ~/.claude/needs_update && echo 'Run: claude -c -p \"Update history\"'"}]}] } } \`\`\` ## šŸ›”ļø Hook Safety Tools Use claude-flow's built-in safety tools: \`\`\`bash # Check your configuration for dangerous patterns claude-flow hook-safety validate # Enable safe mode (skips all hooks) claude-flow hook-safety safe-mode # Check current safety status claude-flow hook-safety status # Reset circuit breakers if triggered claude-flow hook-safety reset \`\`\` ## šŸ“š Additional Resources - Issue #166: https://github.com/chatman-media/claude-flow-multilang/issues/166 - Claude Code Hooks Documentation: https://docs.anthropic.com/en/docs/claude-code/hooks - Reddit Discussion: https://www.reddit.com/r/ClaudeAI/comments/1ltvi6x/anyone_else_accidentally_create_an_infinite_loop/ --- **Remember**: When in doubt, use flag-based patterns or PostToolUse hooks instead of Stop hooks! `; } export default { DANGEROUS_PATTERN_EXAMPLE, ALL_SAFE_PATTERNS, generateSafeHooksGuide, };