use std::path::{Path, PathBuf};
use super::paths::*;
use super::types::{ConfigType, EditorTarget};
pub fn build_targets(home: &Path) -> Vec<EditorTarget> {
vec![
EditorTarget {
name: "Claude Code",
agent_key: "claude".to_string(),
config_path: claude_mcp_json_path(home),
detect_path: detect_claude_path(),
config_type: ConfigType::McpJson,
},
EditorTarget {
name: "Codex CLI",
agent_key: "codex".to_string(),
config_path: home.join(".codex/config.toml"),
detect_path: detect_codex_path(home),
config_type: ConfigType::Codex,
},
EditorTarget {
name: "VS Code / Copilot",
agent_key: "copilot".to_string(),
config_path: vscode_mcp_path(),
detect_path: detect_vscode_path(),
config_type: ConfigType::VsCodeMcp,
},
EditorTarget {
name: "OpenCode",
agent_key: "opencode".to_string(),
config_path: opencode_config_path(home),
detect_path: opencode_config_dir(home),
config_type: ConfigType::OpenCode,
},
]
}
pub fn detect_claude_path() -> PathBuf {
let which_cmd = if cfg!(windows) { "where" } else { "which" };
if let Ok(output) = std::process::Command::new(which_cmd).arg("claude").output() {
if output.status.success() {
return PathBuf::from(String::from_utf8_lossy(&output.stdout).trim());
}
}
if let Ok(dir) = std::env::var("CLAUDE_CONFIG_DIR") {
let dir = dir.trim();
if !dir.is_empty() {
let p = PathBuf::from(dir);
if p.exists() {
return p;
}
}
}
if let Some(home) = dirs::home_dir() {
let claude_json = claude_mcp_json_path(&home);
if claude_json.exists() {
return claude_json;
}
}
PathBuf::from("/nonexistent")
}
pub fn detect_codex_path(home: &Path) -> PathBuf {
let codex_dir = home.join(".codex");
if codex_dir.exists() {
return codex_dir;
}
let which_cmd = if cfg!(windows) { "where" } else { "which" };
if let Ok(output) = std::process::Command::new(which_cmd).arg("codex").output() {
if output.status.success() {
return codex_dir;
}
}
PathBuf::from("/nonexistent")
}
pub fn detect_vscode_path() -> PathBuf {
#[cfg(target_os = "macos")]
{
if let Some(home) = dirs::home_dir() {
let vscode = home.join("Library/Application Support/Code/User/settings.json");
if vscode.exists() {
return vscode;
}
}
}
#[cfg(target_os = "linux")]
{
if let Some(home) = dirs::home_dir() {
let vscode = home.join(".config/Code/User/settings.json");
if vscode.exists() {
return vscode;
}
}
}
#[cfg(target_os = "windows")]
{
if let Ok(appdata) = std::env::var("APPDATA") {
let vscode = PathBuf::from(appdata).join("Code/User/settings.json");
if vscode.exists() {
return vscode;
}
}
}
let which_cmd = if cfg!(windows) { "where" } else { "which" };
if let Ok(output) = std::process::Command::new(which_cmd).arg("code").output() {
if output.status.success() {
return PathBuf::from(String::from_utf8_lossy(&output.stdout).trim());
}
}
PathBuf::from("/nonexistent")
}
pub fn detect_jetbrains_path(home: &Path) -> PathBuf {
#[cfg(target_os = "macos")]
{
let lib = home.join("Library/Application Support/JetBrains");
if lib.exists() {
return lib;
}
}
#[cfg(target_os = "linux")]
{
let cfg = home.join(".config/JetBrains");
if cfg.exists() {
return cfg;
}
}
#[cfg(target_os = "windows")]
{
if let Ok(appdata) = std::env::var("APPDATA") {
let jb = std::path::PathBuf::from(appdata).join("JetBrains");
if jb.exists() {
return jb;
}
}
if let Ok(local) = std::env::var("LOCALAPPDATA") {
let jb = std::path::PathBuf::from(local).join("JetBrains");
if jb.exists() {
return jb;
}
}
}
if home.join(".jb-mcp.json").exists() {
return home.join(".jb-mcp.json");
}
PathBuf::from("/nonexistent")
}
#[allow(unreachable_code)]
pub fn detect_cline_path() -> PathBuf {
#[cfg(target_os = "windows")]
{
if let Ok(appdata) = std::env::var("APPDATA") {
let p = PathBuf::from(appdata).join("Code/User/globalStorage/saoudrizwan.claude-dev");
if p.exists() {
return p;
}
}
return PathBuf::from("/nonexistent");
}
let Some(home) = dirs::home_dir() else {
return PathBuf::from("/nonexistent");
};
#[cfg(target_os = "macos")]
{
let p =
home.join("Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev");
if p.exists() {
return p;
}
}
#[cfg(target_os = "linux")]
{
let p = home.join(".config/Code/User/globalStorage/saoudrizwan.claude-dev");
if p.exists() {
return p;
}
}
PathBuf::from("/nonexistent")
}
#[allow(unreachable_code)]
pub fn detect_roo_path() -> PathBuf {
#[cfg(target_os = "windows")]
{
if let Ok(appdata) = std::env::var("APPDATA") {
let p =
PathBuf::from(appdata).join("Code/User/globalStorage/rooveterinaryinc.roo-cline");
if p.exists() {
return p;
}
}
return PathBuf::from("/nonexistent");
}
let Some(home) = dirs::home_dir() else {
return PathBuf::from("/nonexistent");
};
#[cfg(target_os = "macos")]
{
let p = home
.join("Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline");
if p.exists() {
return p;
}
}
#[cfg(target_os = "linux")]
{
let p = home.join(".config/Code/User/globalStorage/rooveterinaryinc.roo-cline");
if p.exists() {
return p;
}
}
PathBuf::from("/nonexistent")
}