1use anyhow::{Context, Result};
2use std::io::{self, Write};
3use std::path::PathBuf;
4use std::process::{Command, Stdio};
5use std::thread;
6use std::time::Duration;
7
8pub fn get_config_storage_path() -> Result<PathBuf> {
15 let home_dir = dirs::home_dir().context("Could not find home directory")?;
16 Ok(home_dir.join(".claude").join("cc_auto_switch_setting.json"))
17}
18
19pub fn get_claude_settings_path(custom_dir: Option<&str>) -> Result<PathBuf> {
27 if let Some(dir) = custom_dir {
28 let custom_path = PathBuf::from(dir);
29 if custom_path.is_absolute() {
30 Ok(custom_path.join("settings.json"))
31 } else {
32 let home_dir = dirs::home_dir().context("Could not find home directory")?;
34 Ok(home_dir.join(custom_path).join("settings.json"))
35 }
36 } else {
37 let home_dir = dirs::home_dir().context("Could not find home directory")?;
39 Ok(home_dir.join(".claude").join("settings.json"))
40 }
41}
42
43pub fn read_input(prompt: &str) -> Result<String> {
51 print!("{prompt}");
52 io::stdout().flush().context("Failed to flush stdout")?;
53 let mut input = String::new();
54 io::stdin()
55 .read_line(&mut input)
56 .context("Failed to read input")?;
57 Ok(input.trim().to_string())
58}
59
60pub fn read_sensitive_input(prompt: &str) -> Result<String> {
68 print!("{prompt}");
69 io::stdout().flush().context("Failed to flush stdout")?;
70 let mut input = String::new();
71 io::stdin()
72 .read_line(&mut input)
73 .context("Failed to read input")?;
74 Ok(input.trim().to_string())
75}
76
77pub fn execute_claude_command(skip_permissions: bool) -> Result<()> {
82 let mut command = Command::new("claude");
83 if skip_permissions {
84 command.arg("--dangerously-skip-permissions");
85 }
86
87 command
88 .stdin(Stdio::inherit())
89 .stdout(Stdio::inherit())
90 .stderr(Stdio::inherit());
91
92 let mut child = command.spawn().with_context(
93 || "Failed to launch Claude CLI. Make sure 'claude' command is available in PATH",
94 )?;
95
96 let status = child
97 .wait()
98 .with_context(|| "Failed to wait for Claude CLI process")?;
99
100 if !status.success() {
101 anyhow::bail!("Claude CLI exited with error status: {}", status);
102 }
103
104 Ok(())
105}
106
107pub fn launch_claude() -> Result<()> {
109 println!("\nWaiting 0.5 seconds before launching Claude...");
110 thread::sleep(Duration::from_millis(500));
111
112 println!("Launching Claude CLI...");
113 let mut child = Command::new("claude")
114 .arg("--dangerously-skip-permissions")
115 .stdin(Stdio::inherit())
116 .stdout(Stdio::inherit())
117 .stderr(Stdio::inherit())
118 .spawn()
119 .with_context(
120 || "Failed to launch Claude CLI. Make sure 'claude' command is available in PATH",
121 )?;
122
123 let status = child.wait()?;
124
125 if !status.success() {
126 anyhow::bail!("Claude CLI exited with error status: {}", status);
127 }
128
129 Ok(())
130}