claude-utils 0.2.0

Cross-platform companion toolkit for Anthropic's Claude Code CLI
Documentation
pub mod proxy;
pub mod executor;
pub mod rollback;
pub mod checkpoint_store;

use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;
use tracing::{error, warn};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TurboConfig {
    pub enabled: bool,
    pub full_yolo: bool,
    pub parallel_limit: usize,
    pub auto_retry: bool,
    pub retry_count: u32,
    pub rollback_enabled: bool,
}

impl Default for TurboConfig {
    fn default() -> Self {
        Self {
            enabled: false,
            full_yolo: false,
            parallel_limit: 4,
            auto_retry: true,
            retry_count: 3,
            rollback_enabled: true,
        }
    }
}

impl TurboConfig {
    pub fn validate(&self) -> Result<(), String> {
        if self.parallel_limit == 0 {
            return Err("Parallel limit must be at least 1".to_string());
        }
        if self.parallel_limit > 32 {
            return Err("Parallel limit should not exceed 32 for system stability".to_string());
        }
        if self.retry_count > 10 {
            return Err("Retry count should not exceed 10".to_string());
        }
        Ok(())
    }
}

pub struct TurboMode {
    pub config: Arc<RwLock<TurboConfig>>,
    pub executor: Arc<executor::ParallelExecutor>,
    pub rollback_manager: Arc<rollback::RollbackManager>,
}

impl TurboMode {
    pub async fn new(config: TurboConfig) -> crate::Result<Self> {
        let config = Arc::new(RwLock::new(config));
        let executor = Arc::new(executor::ParallelExecutor::new(
            config.read().await.parallel_limit,
        ));
        let rollback_manager = Arc::new(rollback::RollbackManager::new().await?);

        Ok(Self {
            config,
            executor,
            rollback_manager,
        })
    }

    pub async fn is_yolo(&self) -> bool {
        self.config.read().await.full_yolo
    }

    pub async fn enable_yolo(&self) {
        self.config.write().await.full_yolo = true;
        self.display_safety_warning();
    }
    
    pub fn display_safety_warning(&self) {
        warn!("╔══════════════════════════════════════════════════════════════╗");
        warn!("║                    ⚠️  TURBO MODE WARNING ⚠️                    ║");
        warn!("╠══════════════════════════════════════════════════════════════╣");
        warn!("║                                                              ║");
        warn!("║  🚀 FULL YOLO MODE ACTIVATED - EXTREME CAUTION REQUIRED!    ║");
        warn!("║                                                              ║");
        warn!("║  This mode BYPASSES ALL SAFETY CHECKS:                      ║");
        warn!("║  • ALL file operations are AUTO-APPROVED                    ║");
        warn!("║  • ALL command executions are AUTO-APPROVED                 ║");
        warn!("║  • NO permission prompts will be shown                      ║");
        warn!("║  • Claude can DELETE, MODIFY, or CREATE any files           ║");
        warn!("║                                                              ║");
        warn!("║  ⚡ RECOMMENDATIONS:                                         ║");
        warn!("║  • Ensure you have BACKUPS of important files               ║");
        warn!("║  • Use VERSION CONTROL (git) for safety                     ║");
        warn!("║  • Create a CHECKPOINT before major operations              ║");
        warn!("║  • Monitor Claude's actions carefully                       ║");
        warn!("║                                                              ║");
        warn!("║  🛡️  SAFETY FEATURES ACTIVE:                                ║");
        warn!("║  • Automatic checkpoints before major operations            ║");
        warn!("║  • Instant rollback with: claude-utils turbo rollback       ║");
        warn!("║  • Git stash integration for recovery                       ║");
        warn!("║                                                              ║");
        warn!("║  Press Ctrl+C to abort if you're not ready!                 ║");
        warn!("╚══════════════════════════════════════════════════════════════╝");
    }
    
    pub async fn create_safety_checkpoint(&self, description: &str) -> crate::Result<()> {
        if self.config.read().await.rollback_enabled {
            match self.rollback_manager.create_checkpoint(description.to_string()).await {
                Ok(_) => {
                    warn!("✅ Safety checkpoint created: {}", description);
                    Ok(())
                }
                Err(e) => {
                    error!("❌ Failed to create safety checkpoint: {}", e);
                    Err(e)
                }
            }
        } else {
            Ok(())
        }
    }
}