use std::path::PathBuf;
use theway_core::{Skill, SkillDiagnostic, SkillSource};
use crate::env::native::NativeEnv;
use crate::paths::DaemonPaths;
use theway_core::load_skills;
use tokio_util::sync::CancellationToken;
pub fn skills_dirs(paths: &DaemonPaths) -> Vec<(PathBuf, SkillSource)> {
let extras = paths.current_extra_skill_dirs();
let mut dirs: Vec<(PathBuf, SkillSource)> = Vec::with_capacity(extras.len() + 9);
for extra in &extras {
dirs.push((extra.clone(), SkillSource::User));
}
dirs.push((
paths.work_dir.join(".agents").join("skills"),
SkillSource::Project,
));
dirs.push((
paths.work_dir.join(".theway").join("skills"),
SkillSource::Project,
));
dirs.push((
paths.work_dir.join(".codex").join("skills"),
SkillSource::Project,
));
dirs.push((
paths.work_dir.join(".claude").join("skills"),
SkillSource::Project,
));
dirs.push((paths.skills_root(), SkillSource::User));
dirs.push((paths.home.join(".agents").join("skills"), SkillSource::User));
dirs.push((paths.home.join("skills"), SkillSource::User));
dirs.push((paths.home.join(".codex").join("skills"), SkillSource::User));
dirs.push((paths.home.join(".claude").join("skills"), SkillSource::User));
dirs
}
pub struct LoadedSkills {
pub skills: Vec<Skill>,
pub diagnostics: Vec<SkillDiagnostic>,
}
pub async fn load_all(paths: &DaemonPaths) -> LoadedSkills {
let env = NativeEnv::new(paths.work_dir.to_string_lossy().to_string());
let cancel = CancellationToken::new();
let mut combined = Vec::<Skill>::new();
let mut diagnostics = Vec::<SkillDiagnostic>::new();
for (dir, source) in skills_dirs(paths) {
let s = dir.to_string_lossy().to_string();
let out = load_skills(&env, &[s.as_str()], cancel.clone()).await;
diagnostics.extend(out.diagnostics);
for mut skill in out.skills {
skill.source = source;
dedupe_first_wins(&mut combined, skill);
}
}
LoadedSkills {
skills: combined,
diagnostics,
}
}
fn dedupe_first_wins(combined: &mut Vec<Skill>, skill: Skill) {
if !combined.iter().any(|s| s.name == skill.name) {
combined.push(skill);
}
}
#[cfg(test)]
tests_bridge_macro::tests_bridge!("skills");