zenith_cli/commands/plugin/
paths.rs1use std::path::{Path, PathBuf};
4
5use super::agent::{Agent, Scope};
6
7pub const SKILL_NAME: &str = "zenith";
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum SkillTarget {
13 Folder(PathBuf),
15 Rule(PathBuf),
17}
18
19impl SkillTarget {
20 pub fn root(&self) -> &Path {
22 match self {
23 SkillTarget::Folder(p) | SkillTarget::Rule(p) => p,
24 }
25 }
26}
27
28pub fn home_dir() -> Option<PathBuf> {
30 std::env::var_os("HOME").map(PathBuf::from)
31}
32
33pub fn skill_target(agent: Agent, scope: Scope, project_root: &Path) -> Option<SkillTarget> {
37 let folder = |conf_project: &Path, conf_user: Option<PathBuf>| -> Option<SkillTarget> {
39 let base = match scope {
40 Scope::Project => project_root.join(conf_project),
41 Scope::User => conf_user?,
42 };
43 Some(SkillTarget::Folder(base.join("skills").join(SKILL_NAME)))
44 };
45 let rule =
47 |dir_project: PathBuf, dir_user: Option<PathBuf>, file: &str| -> Option<SkillTarget> {
48 let dir = match scope {
49 Scope::Project => project_root.join(dir_project),
50 Scope::User => dir_user?,
51 };
52 Some(SkillTarget::Rule(dir.join(file)))
53 };
54 let home = home_dir();
55
56 match agent {
57 Agent::ClaudeCode => folder(
58 Path::new(".claude"),
59 home.as_ref().map(|h| h.join(".claude")),
60 ),
61 Agent::Codex => folder(
63 Path::new(".agents"),
64 home.as_ref().map(|h| h.join(".agents")),
65 ),
66 Agent::OpenCode => folder(
68 Path::new(".opencode"),
69 home.as_ref().map(|h| h.join(".config").join("opencode")),
70 ),
71 Agent::Cursor => rule(PathBuf::from(".cursor").join("rules"), None, "zenith.mdc"),
73 Agent::Windsurf => rule(PathBuf::from(".windsurf").join("rules"), None, "zenith.md"),
75 Agent::Aider => rule(
76 PathBuf::from(".aider"),
77 home.as_ref().map(|h| h.join(".aider")),
78 "zenith-skill.md",
79 ),
80 Agent::Zed => rule(
81 PathBuf::from(".zed"),
82 home.as_ref().map(|h| h.join(".zed")),
83 "zenith-skill.md",
84 ),
85 Agent::Gemini => rule(
86 PathBuf::from(".gemini"),
87 home.as_ref().map(|h| h.join(".gemini")),
88 "zenith-skill.md",
89 ),
90 Agent::Copilot => rule(
91 PathBuf::from(".copilot"),
92 home.as_ref().map(|h| h.join(".copilot")),
93 "zenith-skill.md",
94 ),
95 Agent::Continue => rule(
96 PathBuf::from(".continue").join("skills"),
97 home.as_ref().map(|h| h.join(".continue").join("skills")),
98 "zenith.md",
99 ),
100 Agent::Kiro => rule(
101 PathBuf::from(".kiro").join("steering"),
102 home.as_ref().map(|h| h.join(".kiro").join("steering")),
103 "zenith-skill.md",
104 ),
105 Agent::Antigravity => rule(
106 PathBuf::from(".antigravity"),
107 home.as_ref().map(|h| h.join(".antigravity")),
108 "zenith-skill.md",
109 ),
110 }
111}
112
113pub fn command_dir(agent: Agent, scope: Scope, project_root: &Path) -> Option<PathBuf> {
116 match agent {
117 Agent::ClaudeCode => Some(match scope {
118 Scope::Project => project_root.join(".claude").join("commands"),
119 Scope::User => home_dir()?.join(".claude").join("commands"),
120 }),
121 Agent::OpenCode => Some(match scope {
122 Scope::Project => project_root.join(".opencode").join("command"),
123 Scope::User => home_dir()?.join(".config").join("opencode").join("command"),
124 }),
125 _ => None,
126 }
127}