feat: security hardening, tests, doctor command, CI update, CHANGELOG
All checks were successful
CI / build (push) Successful in 2m37s

- Add AES-256-GCM encryption for API keys (internal/secret)
- Add dangerous command detection in terminal
- Add muyue doctor command for system health checks
- Add scanner TTL cache, orchestrator history mutex, shared HTTP client
- Deduplicate MCP config generation, refactor skills YAML parser
- Add XDG-compliant config dir with legacy migration
- Add cleanup on all TUI quit paths
- Add 8 test files (config, workflow, skills, orchestrator, version,
  platform, scanner, secret)
- Update CI to actions/setup-go@v5
- Add CHANGELOG.md, update README and Makefile

🤖 Generated with Crush

Assisted-by: GLM-5.1 via Crush <crush@charm.land>
This commit is contained in:
Augustin
2026-04-20 19:56:07 +02:00
parent 44691225e7
commit 3494f6b40d
22 changed files with 1655 additions and 253 deletions

View File

@@ -7,6 +7,8 @@ import (
"sort"
"strings"
"time"
"gopkg.in/yaml.v3"
)
type Skill struct {
@@ -227,33 +229,13 @@ func parseSkill(data []byte) (*Skill, error) {
return &Skill{Content: content}, nil
}
frontmatter := strings.TrimSpace(content[3 : end+3])
frontmatter := content[3 : end+3]
body := strings.TrimSpace(content[end+6:])
skill := &Skill{Content: body}
for _, line := range strings.Split(frontmatter, "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "name:") {
skill.Name = strings.TrimSpace(strings.TrimPrefix(line, "name:"))
} else if strings.HasPrefix(line, "description:") {
skill.Description = strings.TrimSpace(strings.TrimPrefix(line, "description:"))
} else if strings.HasPrefix(line, "author:") {
skill.Author = strings.TrimSpace(strings.TrimPrefix(line, "author:"))
} else if strings.HasPrefix(line, "version:") {
skill.Version = strings.TrimSpace(strings.TrimPrefix(line, "version:"))
} else if strings.HasPrefix(line, "target:") {
skill.Target = strings.TrimSpace(strings.TrimPrefix(line, "target:"))
} else if strings.HasPrefix(line, "tags:") {
tagsStr := strings.TrimSpace(strings.TrimPrefix(line, "tags:"))
tagsStr = strings.Trim(tagsStr, "[]")
for _, t := range strings.Split(tagsStr, ",") {
t = strings.TrimSpace(t)
if t != "" {
skill.Tags = append(skill.Tags, t)
}
}
}
if err := yaml.Unmarshal([]byte(frontmatter), skill); err != nil {
return &Skill{Content: content}, nil
}
return skill, nil