54 lines
1.8 KiB
Rust
54 lines
1.8 KiB
Rust
//! Scan all repos in a project for skills.
|
|
|
|
use crate::AppService;
|
|
use crate::error::AppError;
|
|
use models::repos::repo::Entity as RepoEntity;
|
|
use models::repos::repo::Column as RCol;
|
|
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
|
use uuid::Uuid;
|
|
|
|
use super::scanner;
|
|
|
|
impl AppService {
|
|
/// Scan all repositories in a project and sync skills from `.claude/skills/` directories.
|
|
///
|
|
/// This is called automatically during `git hook sync` and can also be triggered
|
|
/// manually via `POST /api/projects/{name}/skills/scan`.
|
|
///
|
|
/// - Discovers skills in each repo's `.claude/skills/` folder
|
|
/// - Upserts repo-sourced skills (source = "repo")
|
|
/// - Removes skills whose source repo no longer has the file
|
|
/// - Manual skills (source = "manual") are never affected
|
|
pub async fn skill_scan_repos(
|
|
&self,
|
|
project_uid: Uuid,
|
|
_caller_uid: Uuid,
|
|
) -> Result<scanner::ScanSyncResult, AppError> {
|
|
// Collect all repo IDs for this project
|
|
let repos: Vec<_> = RepoEntity::find()
|
|
.filter(RCol::Project.eq(project_uid))
|
|
.all(&self.db)
|
|
.await?;
|
|
|
|
let mut total_created = 0i64;
|
|
let mut total_updated = 0i64;
|
|
let mut total_removed = 0i64;
|
|
let mut total_discovered = 0i64;
|
|
|
|
for repo in repos {
|
|
let result = scanner::scan_and_sync_skills(&self.db, project_uid, &repo).await?;
|
|
total_created += result.created;
|
|
total_updated += result.updated;
|
|
total_removed += result.removed;
|
|
total_discovered += result.discovered;
|
|
}
|
|
|
|
Ok(scanner::ScanSyncResult {
|
|
discovered: total_discovered,
|
|
created: total_created,
|
|
updated: total_updated,
|
|
removed: total_removed,
|
|
})
|
|
}
|
|
}
|