use std::path::{Path, PathBuf};
use super::agent::{Agent, Scope};
pub const SKILL_NAME: &str = "zenith";
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SkillTarget {
Folder(PathBuf),
Rule(PathBuf),
}
impl SkillTarget {
pub fn root(&self) -> &Path {
match self {
SkillTarget::Folder(p) | SkillTarget::Rule(p) => p,
}
}
}
pub fn home_dir() -> Option<PathBuf> {
std::env::var_os("HOME").map(PathBuf::from)
}
pub fn skill_target(agent: Agent, scope: Scope, project_root: &Path) -> Option<SkillTarget> {
let folder = |conf_project: &Path, conf_user: Option<PathBuf>| -> Option<SkillTarget> {
let base = match scope {
Scope::Project => project_root.join(conf_project),
Scope::User => conf_user?,
};
Some(SkillTarget::Folder(base.join("skills").join(SKILL_NAME)))
};
let rule =
|dir_project: PathBuf, dir_user: Option<PathBuf>, file: &str| -> Option<SkillTarget> {
let dir = match scope {
Scope::Project => project_root.join(dir_project),
Scope::User => dir_user?,
};
Some(SkillTarget::Rule(dir.join(file)))
};
let home = home_dir();
match agent {
Agent::ClaudeCode => folder(
Path::new(".claude"),
home.as_ref().map(|h| h.join(".claude")),
),
Agent::Codex => folder(
Path::new(".agents"),
home.as_ref().map(|h| h.join(".agents")),
),
Agent::OpenCode => folder(
Path::new(".opencode"),
home.as_ref().map(|h| h.join(".config").join("opencode")),
),
Agent::Cursor => rule(PathBuf::from(".cursor").join("rules"), None, "zenith.mdc"),
Agent::Windsurf => rule(PathBuf::from(".windsurf").join("rules"), None, "zenith.md"),
Agent::Aider => rule(
PathBuf::from(".aider"),
home.as_ref().map(|h| h.join(".aider")),
"zenith-skill.md",
),
Agent::Zed => rule(
PathBuf::from(".zed"),
home.as_ref().map(|h| h.join(".zed")),
"zenith-skill.md",
),
Agent::Gemini => rule(
PathBuf::from(".gemini"),
home.as_ref().map(|h| h.join(".gemini")),
"zenith-skill.md",
),
Agent::Copilot => rule(
PathBuf::from(".copilot"),
home.as_ref().map(|h| h.join(".copilot")),
"zenith-skill.md",
),
Agent::Continue => rule(
PathBuf::from(".continue").join("skills"),
home.as_ref().map(|h| h.join(".continue").join("skills")),
"zenith.md",
),
Agent::Kiro => rule(
PathBuf::from(".kiro").join("steering"),
home.as_ref().map(|h| h.join(".kiro").join("steering")),
"zenith-skill.md",
),
Agent::Antigravity => rule(
PathBuf::from(".antigravity"),
home.as_ref().map(|h| h.join(".antigravity")),
"zenith-skill.md",
),
}
}
pub fn command_dir(agent: Agent, scope: Scope, project_root: &Path) -> Option<PathBuf> {
match agent {
Agent::ClaudeCode => Some(match scope {
Scope::Project => project_root.join(".claude").join("commands"),
Scope::User => home_dir()?.join(".claude").join("commands"),
}),
Agent::OpenCode => Some(match scope {
Scope::Project => project_root.join(".opencode").join("command"),
Scope::User => home_dir()?.join(".config").join("opencode").join("command"),
}),
_ => None,
}
}