claude_code_toolkit/cli/commands/
sync.rs1use 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 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}