claude_code_toolkit/cli/commands/
org.rs1use crate::{ config::manager::ConfigurationManager, error::*, providers::github::GitHubManager };
2use console::{ Emoji, style };
3
4static SUCCESS: Emoji<'_, '_> = Emoji("✅ ", "");
5#[allow(dead_code)]
6static WARNING: Emoji<'_, '_> = Emoji("⚠️ ", "");
7static INFO: Emoji<'_, '_> = Emoji("ℹ️ ", "");
8
9pub async fn handle_add_org(name: String) -> Result<()> {
10 println!("{}Adding organization {} for Claude secret sync", INFO, style(&name).bold());
11
12 let github_manager = GitHubManager::new();
14
15 if !github_manager.check_gh_cli().await? {
16 eprintln!("{}", style("GitHub CLI (gh) is not installed. Please install it first.").red());
17 std::process::exit(1);
18 }
19
20 if !github_manager.check_authentication().await? {
21 eprintln!(
22 "{}",
23 style("GitHub CLI is not authenticated. Please run 'gh auth login' first.").red()
24 );
25 std::process::exit(1);
26 }
27
28 let config_manager = ConfigurationManager::new()?;
30 config_manager.add_organization(name.clone()).await?;
31
32 println!("{}Successfully added organization {}", SUCCESS, style(&name).bold());
33 let config = config_manager.load_config().await?;
35 let secret_names: Vec<String> = config.credentials.field_mappings.values().cloned().collect();
36 println!("{}", style(format!("Will sync: {}", secret_names.join(", "))).dim());
37 println!("{}", style("Run 'claude-code sync now' to sync immediately").dim());
38
39 Ok(())
40}
41
42pub async fn handle_remove_org(name: String) -> Result<()> {
43 println!("{}Removing organization {}", INFO, style(&name).bold());
44
45 let config_manager = ConfigurationManager::new()?;
46 config_manager.remove_organization(&name).await?;
47
48 println!("{}Successfully removed organization {}", SUCCESS, style(&name).bold());
49
50 Ok(())
51}
52
53pub async fn handle_list_orgs() -> Result<()> {
54 let config_manager = ConfigurationManager::new()?;
55 let config = config_manager.load_config().await?;
56
57 if config.github.organizations.is_empty() {
58 println!("{}", style("No organizations configured").yellow());
59 println!("{}", style("Use 'claude-code org add <name>' to add an organization").dim());
60 return Ok(());
61 }
62
63 println!("{}", style("Configured Organizations:").bold());
64 println!();
65
66 for org in &config.github.organizations {
67 println!(" {}", style(&org.name).cyan());
68 let secret_names: Vec<String> = config.credentials.field_mappings.values().cloned().collect();
69 println!(" Secrets: {}", style(secret_names.join(", ")).dim());
70 }
71
72 println!();
73
74 println!("{}", style("Available Organizations from GitHub:").bold());
76 println!();
77
78 let github_manager = GitHubManager::new();
79
80 match github_manager.list_organizations().await {
81 Ok(available_orgs) => {
82 if available_orgs.is_empty() {
83 println!(" {}", style("No organizations found").dim());
84 } else {
85 for org in available_orgs {
86 let is_configured = config.github.organizations.iter().any(|o| o.name == org);
87 if is_configured {
88 println!(" {} {}", style("✓").green(), org);
89 } else {
90 println!(" {} {}", style("○").dim(), org);
91 }
92 }
93 }
94 }
95 Err(e) => {
96 println!(" {}", style(format!("Error fetching organizations: {}", e)).red());
97 }
98 }
99
100 Ok(())
101}