74 lines
1.8 KiB
Go
74 lines
1.8 KiB
Go
package services
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"sproutclaw-web/internal/models"
|
|
)
|
|
|
|
// ListSkills returns all skills (enabled and disabled) under agentDir.
|
|
func ListSkills(agentDir string) []models.SkillInfo {
|
|
var skills []models.SkillInfo
|
|
skills = append(skills, scanSkillsDir(filepath.Join(agentDir, "skills"), true)...)
|
|
skills = append(skills, scanSkillsDir(filepath.Join(agentDir, "skills-disabled"), false)...)
|
|
return skills
|
|
}
|
|
|
|
func scanSkillsDir(dir string, enabled bool) []models.SkillInfo {
|
|
entries, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
var skills []models.SkillInfo
|
|
for _, e := range entries {
|
|
if !e.IsDir() {
|
|
continue
|
|
}
|
|
skillPath := filepath.Join(dir, e.Name())
|
|
name, desc := parseSkillMD(filepath.Join(skillPath, "SKILL.md"))
|
|
if name == "" {
|
|
name = e.Name()
|
|
}
|
|
skills = append(skills, models.SkillInfo{
|
|
Name: name,
|
|
Description: desc,
|
|
Enabled: enabled,
|
|
Toggleable: true,
|
|
Path: skillPath,
|
|
})
|
|
}
|
|
return skills
|
|
}
|
|
|
|
// ToggleSkill moves a skill between skills/ and skills-disabled/ directories.
|
|
func ToggleSkill(agentDir, skillPath string, enable bool) error {
|
|
skillsDir := filepath.Join(agentDir, "skills")
|
|
disabledDir := filepath.Join(agentDir, "skills-disabled")
|
|
|
|
if !isUnderDir(skillPath, skillsDir) && !isUnderDir(skillPath, disabledDir) {
|
|
return fmt.Errorf("skill path not in managed directories")
|
|
}
|
|
|
|
name := filepath.Base(skillPath)
|
|
var src, dst string
|
|
if enable {
|
|
src = filepath.Join(disabledDir, name)
|
|
dst = filepath.Join(skillsDir, name)
|
|
} else {
|
|
src = filepath.Join(skillsDir, name)
|
|
dst = filepath.Join(disabledDir, name)
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(dst), 0o755); err != nil {
|
|
return err
|
|
}
|
|
return os.Rename(src, dst)
|
|
}
|
|
|
|
func isUnderDir(path, dir string) bool {
|
|
return strings.HasPrefix(filepath.Clean(path), filepath.Clean(dir))
|
|
}
|