claude_code_toolkit/cli/commands/
sync.rs

1use crate::{
2  config::manager::ConfigurationManager,
3  error::*,
4  sync::SyncService,
5  utils::systemd::SystemdManager,
6};
7use console::{ Emoji, style };
8
9static SYNC: Emoji<'_, '_> = Emoji("🔄 ", "");
10static SUCCESS: Emoji<'_, '_> = Emoji("✅ ", "");
11static FAILURE: Emoji<'_, '_> = Emoji("❌ ", "");
12static INFO: Emoji<'_, '_> = Emoji("📊 ", "");
13static LOGS: Emoji<'_, '_> = Emoji("📜 ", "");
14
15pub async fn handle_sync_now() -> Result<()> {
16  println!("{}Starting sync...", SYNC);
17
18  let mut sync_service = SyncService::new_with_config().await?;
19
20  match sync_service.check_and_sync_if_needed().await {
21    Ok(()) => {
22      println!("{}Sync operation completed", SUCCESS);
23    }
24    Err(e) => {
25      eprintln!("{}Sync failed: {}", FAILURE, e);
26      std::process::exit(1);
27    }
28  }
29
30  Ok(())
31}
32
33pub async fn handle_sync_force() -> Result<()> {
34  println!("{}Starting forced sync...", SYNC);
35
36  let mut sync_service = SyncService::new_with_config().await?;
37
38  match sync_service.force_sync().await {
39    Ok(result) => {
40      println!("{}Sync completed successfully", SUCCESS);
41      println!("  Succeeded: {}, Failed: {}", result.succeeded, result.failed);
42    }
43    Err(e) => {
44      eprintln!("{}Sync failed: {}", FAILURE, e);
45      std::process::exit(1);
46    }
47  }
48
49  Ok(())
50}
51
52pub async fn handle_sync_status() -> Result<()> {
53  println!("{} {}", INFO, style("Sync Status").bold());
54  println!();
55
56  let config_manager = ConfigurationManager::new()?;
57  let state = config_manager.load_state().await?;
58
59  if state.last_sync == 0 {
60    println!("Last Sync: {}", style("Never").yellow());
61  } else {
62    let last_sync = chrono::DateTime
63      ::from_timestamp(state.last_sync, 0)
64      .unwrap_or_default()
65      .format("%Y-%m-%d %H:%M:%S UTC");
66    let time_since_sync = chrono::Utc::now().timestamp() - state.last_sync;
67    let minutes_ago = time_since_sync / 60;
68
69    println!("Last Sync: {} ({} minutes ago)", last_sync, minutes_ago);
70  }
71
72  println!();
73
74  if state.targets.is_empty() {
75    println!("{}", style("No sync targets configured").yellow());
76    println!(
77      "{}",
78      style("Use 'claude-code org add' or 'claude-code repo add' to add targets").dim()
79    );
80  } else {
81    println!("{}", style("Target Status:").bold());
82    println!();
83
84    let success_count = state.targets
85      .iter()
86      .filter(|t| matches!(t.last_sync_status, crate::types::SyncStatus::Success))
87      .count();
88    let failure_count = state.targets.len() - success_count;
89
90    println!("Total Targets: {}", state.targets.len());
91    println!("Successful: {}", style(success_count.to_string()).green());
92    println!("Failed: {}", style(failure_count.to_string()).red());
93
94    println!();
95
96    // Show individual target status
97    for target in &state.targets {
98      let icon = match target.last_sync_status {
99        crate::types::SyncStatus::Success => SUCCESS,
100        crate::types::SyncStatus::Failure => FAILURE,
101      };
102
103      let target_type = match target.target_type {
104        crate::types::TargetType::Organization => "Organization",
105        crate::types::TargetType::Repository => "Repository",
106      };
107
108      println!("{}{}: {}", icon, style(target_type).bold(), target.name);
109
110      if target.last_sync_time > 0 {
111        let sync_time = chrono::DateTime
112          ::from_timestamp(target.last_sync_time, 0)
113          .unwrap_or_default()
114          .format("%Y-%m-%d %H:%M:%S UTC");
115        println!("   Last Sync: {}", sync_time);
116      }
117
118      if let Some(ref error) = target.last_error {
119        println!("   {}: {}", style("Error").red(), error);
120      }
121
122      println!();
123    }
124  }
125
126  Ok(())
127}
128
129pub async fn handle_sync_logs(lines: usize) -> Result<()> {
130  println!("{} {} (last {} lines)", LOGS, style("Daemon Logs").bold(), lines);
131  println!();
132
133  let systemd_manager = SystemdManager::new()?;
134
135  match systemd_manager.logs(lines).await {
136    Ok(logs) => {
137      println!("{}", logs);
138    }
139    Err(e) => {
140      eprintln!("{}Error retrieving logs: {}", FAILURE, e);
141      std::process::exit(1);
142    }
143  }
144
145  Ok(())
146}