Files
harness-sync/internal/adapter/common/markdown.go
T

88 lines
2.2 KiB
Go

package common
import (
"os"
"path/filepath"
"strings"
"github.com/spf13/afero"
"gopkg.in/yaml.v3"
"github.com/lukaszraczylo/harness-sync/internal/fsx"
)
// Doc mirrors canonical.Skill / canonical.Agent without importing them.
type Doc struct {
Name string
Description string
Body string
Path string
}
// ParseFrontmatter extracts the name and description fields from a markdown
// file's YAML frontmatter block. Returns ("", "") when there is no frontmatter.
func ParseFrontmatter(b []byte) (name, description string) {
s := string(b)
if !strings.HasPrefix(s, "---\n") {
return "", ""
}
end := strings.Index(s[4:], "\n---")
if end == -1 {
return "", ""
}
var meta struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
}
_ = yaml.Unmarshal([]byte(s[4:4+end]), &meta)
return meta.Name, meta.Description
}
// ImportMarkdownTreeFS walks dir on fs and returns one Doc per matching file.
// When requiredFilename is non-empty (e.g. "SKILL.md"), only files with that
// exact basename are included; otherwise any *.md.
func ImportMarkdownTreeFS(fs fsx.FS, dir, requiredFilename string) ([]Doc, error) {
var docs []Doc
if !DirExistsFS(fs, dir) {
return docs, nil
}
err := afero.Walk(fs, dir, func(p string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if requiredFilename != "" && filepath.Base(p) != requiredFilename {
return nil
}
if requiredFilename == "" && !strings.HasSuffix(p, ".md") {
return nil
}
body, err := afero.ReadFile(fs, p)
if err != nil {
return err
}
name, desc := ParseFrontmatter(body)
if name == "" {
name = strings.TrimSuffix(filepath.Base(p), ".md")
}
rel, _ := filepath.Rel(dir, p)
docs = append(docs, Doc{
Name: name,
Description: desc,
Body: string(body),
Path: rel,
})
return nil
})
return docs, err
}
// ImportMarkdownTree walks dir and returns one Doc per markdown file. When
// requiredFilename is non-empty (e.g. "SKILL.md"), only files with that exact
// basename are included; otherwise any *.md.
func ImportMarkdownTree(dir, requiredFilename string) ([]Doc, error) {
return ImportMarkdownTreeFS(fsx.OS(), dir, requiredFilename)
}