feat: recursive skill discovery + tree-url type-root folding
- skills are found at any depth under the skills dir, so category-nested layouts (skills/<category>/<id>/SKILL.md) vendor correctly; the folder basename is the upstream id and the outermost SKILL.md wins over anything nested inside a skill folder - web-tree urls pointing directly at a type directory (.../tree/main/skills) now map that directory as the type root instead of nesting it under the default layout - verified against the real github.com/mattpocock/skills repository (36 skills across categories; include-selection by basename)
This commit is contained in:
Vendored
+31
-1
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -51,6 +52,7 @@ func Add(workDir string, opts AddOptions, stdout io.Writer) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg := discoveryFromTreeRoot(root)
|
||||
|
||||
repo, err := gitsource.Clone(normalized, opts.Ref)
|
||||
if err != nil {
|
||||
@@ -61,7 +63,6 @@ func Add(workDir string, opts AddOptions, stdout io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := lockfile.Discovery{Root: root}
|
||||
items, err := discovery.Scan(tree, discovery.FromLockfileDiscovery(cfg))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -117,6 +118,35 @@ func Add(workDir string, opts AddOptions, stdout io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// discoveryFromTreeRoot maps a pasted tree sub-path onto discovery config.
|
||||
// A sub-path ending in a standard type directory (e.g. ".../tree/main/skills")
|
||||
// selects that directory as the type root; anything else becomes the
|
||||
// discovery root under which the standard layout is expected.
|
||||
func discoveryFromTreeRoot(root string) lockfile.Discovery {
|
||||
if root == "" {
|
||||
return lockfile.Discovery{}
|
||||
}
|
||||
parent, base := path.Split(strings.TrimSuffix(root, "/"))
|
||||
parent = strings.TrimSuffix(parent, "/")
|
||||
d := lockfile.Discovery{Root: parent}
|
||||
switch base {
|
||||
case lockfile.TypeSkill:
|
||||
d.SkillsDir = base
|
||||
case lockfile.TypeCommand:
|
||||
d.CommandsDir = base
|
||||
case lockfile.TypeAgent:
|
||||
d.AgentsDir = base
|
||||
case lockfile.TypeMcp:
|
||||
d.McpDir = base
|
||||
default:
|
||||
return lockfile.Discovery{Root: root}
|
||||
}
|
||||
if d == (lockfile.Discovery{}) {
|
||||
return lockfile.Discovery{}
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func checkIncludeEntries(items []discovery.Item, include []string, name string) error {
|
||||
available := map[string]bool{}
|
||||
for _, it := range items {
|
||||
|
||||
Reference in New Issue
Block a user