use std::path::PathBuf;
use crate::agents::planning as agent_planning;
use crate::error::AgentConfigError;
use crate::integration::{InstallReport, SkillSurface, UninstallReport};
use crate::paths;
use crate::plan::{InstallPlan, UninstallPlan};
use crate::scope::{Scope, ScopeKind};
use crate::spec::SkillSpec;
use crate::status::StatusReport;
use crate::util::{ownership, skills_dir};
use super::ClineAgent;
impl ClineAgent {
pub(super) fn skills_root(scope: &Scope) -> Result<PathBuf, AgentConfigError> {
Ok(match scope {
Scope::Global => paths::home_dir()?.join(".cline").join("skills"),
Scope::Local(p) => p.join(".cline").join("skills"),
})
}
}
impl SkillSurface for ClineAgent {
fn id(&self) -> &'static str {
"cline"
}
fn supported_skill_scopes(&self) -> &'static [ScopeKind] {
&[ScopeKind::Global, ScopeKind::Local]
}
fn skill_status(
&self,
scope: &Scope,
name: &str,
expected_owner: &str,
) -> Result<StatusReport, AgentConfigError> {
SkillSpec::validate_name(name)?;
let root = Self::skills_root(scope)?;
let (dir, manifest, ledger) = skills_dir::paths_for_status(&root, name);
let recorded = ownership::owner_of(&ledger, name)?;
Ok(StatusReport::for_skill(
name,
dir,
manifest,
ledger,
expected_owner,
recorded,
))
}
fn plan_install_skill(
&self,
scope: &Scope,
spec: &SkillSpec,
) -> Result<InstallPlan, AgentConfigError> {
agent_planning::skill_install(
SkillSurface::id(self),
scope,
spec,
Self::skills_root(scope),
)
}
fn plan_uninstall_skill(
&self,
scope: &Scope,
name: &str,
owner_tag: &str,
) -> Result<UninstallPlan, AgentConfigError> {
agent_planning::skill_uninstall(
SkillSurface::id(self),
scope,
name,
owner_tag,
Self::skills_root(scope),
)
}
fn install_skill(
&self,
scope: &Scope,
spec: &SkillSpec,
) -> Result<InstallReport, AgentConfigError> {
let root = Self::skills_root(scope)?;
scope.ensure_contained(&root)?;
skills_dir::install(&root, spec)
}
fn uninstall_skill(
&self,
scope: &Scope,
name: &str,
owner_tag: &str,
) -> Result<UninstallReport, AgentConfigError> {
let root = Self::skills_root(scope)?;
scope.ensure_contained(&root)?;
skills_dir::uninstall(&root, name, owner_tag)
}
}