fix(skills): resolve third-party skills installation failure (#268)

- Add skills_path field to Skill struct
- Use skills_path to construct correct source path during installation
- Fix installation for repos with custom skill subdirectories
This commit is contained in:
YoVinchen
2025-11-21 15:02:01 +08:00
committed by GitHub
parent 74969ae968
commit 5e54656d45
3 changed files with 19 additions and 4 deletions

View File

@@ -62,7 +62,7 @@ pub async fn install_skill(
.clone() .clone()
.unwrap_or_else(|| "main".to_string()), .unwrap_or_else(|| "main".to_string()),
enabled: true, enabled: true,
skills_path: None, // 安装时使用默认路径 skills_path: skill.skills_path.clone(), // 使用技能记录的 skills_path
}; };
service service

View File

@@ -32,6 +32,9 @@ pub struct Skill {
/// 分支名称 /// 分支名称
#[serde(rename = "repoBranch")] #[serde(rename = "repoBranch")]
pub repo_branch: Option<String>, pub repo_branch: Option<String>,
/// 技能所在的子目录路径 (可选, 如 "skills")
#[serde(rename = "skillsPath")]
pub skills_path: Option<String>,
} }
/// 仓库配置 /// 仓库配置
@@ -234,6 +237,7 @@ impl SkillService {
repo_owner: Some(repo.owner.clone()), repo_owner: Some(repo.owner.clone()),
repo_name: Some(repo.name.clone()), repo_name: Some(repo.name.clone()),
repo_branch: Some(repo.branch.clone()), repo_branch: Some(repo.branch.clone()),
skills_path: repo.skills_path.clone(),
}); });
} }
Err(e) => log::warn!("解析 {} 元数据失败: {}", skill_md.display(), e), Err(e) => log::warn!("解析 {} 元数据失败: {}", skill_md.display(), e),
@@ -312,6 +316,7 @@ impl SkillService {
repo_owner: None, repo_owner: None,
repo_name: None, repo_name: None,
repo_branch: None, repo_branch: None,
skills_path: None,
}); });
} }
} }
@@ -442,12 +447,21 @@ impl SkillService {
.await .await
.map_err(|_| anyhow!("下载仓库 {}/{} 超时", repo.owner, repo.name))??; .map_err(|_| anyhow!("下载仓库 {}/{} 超时", repo.owner, repo.name))??;
// 复制到安装目录 // 根据 skills_path 确定源目录路径
let source = temp_dir.join(&directory); let source = if let Some(ref skills_path) = repo.skills_path {
// 如果指定了 skills_path源路径为: temp_dir/skills_path/directory
temp_dir.join(skills_path.trim_matches('/')).join(&directory)
} else {
// 否则源路径为: temp_dir/directory
temp_dir.join(&directory)
};
if !source.exists() { if !source.exists() {
let _ = fs::remove_dir_all(&temp_dir); let _ = fs::remove_dir_all(&temp_dir);
return Err(anyhow::anyhow!("技能目录不存在")); return Err(anyhow::anyhow!(
"技能目录不存在: {}",
source.display()
));
} }
// 删除旧版本 // 删除旧版本

View File

@@ -10,6 +10,7 @@ export interface Skill {
repoOwner?: string; repoOwner?: string;
repoName?: string; repoName?: string;
repoBranch?: string; repoBranch?: string;
skillsPath?: string; // 技能所在的子目录路径,如 "skills"
} }
export interface SkillRepo { export interface SkillRepo {