DiscoverSkillByPathWithOptions looks up a single skill by its exact path in the repository, applying the given options.
(client *api.Client, host, owner, repo, commitSHA, skillPath string, opts DiscoverSkillByPathOptions)
| 714 | // DiscoverSkillByPathWithOptions looks up a single skill by its exact path in |
| 715 | // the repository, applying the given options. |
| 716 | func DiscoverSkillByPathWithOptions(client *api.Client, host, owner, repo, commitSHA, skillPath string, opts DiscoverSkillByPathOptions) (*Skill, error) { |
| 717 | skillPath = strings.TrimSuffix(skillPath, "/SKILL.md") |
| 718 | skillPath = strings.TrimSuffix(skillPath, "/") |
| 719 | |
| 720 | skillName := path.Base(skillPath) |
| 721 | if !validateName(skillName) { |
| 722 | return nil, fmt.Errorf("invalid skill name %q", skillName) |
| 723 | } |
| 724 | |
| 725 | parentPath := path.Dir(skillPath) |
| 726 | apiPath, err := safeurl.JoinPath("repos", owner, repo, "contents", parentPath) |
| 727 | if err != nil { |
| 728 | return nil, err |
| 729 | } |
| 730 | apiPath.SetQuery("ref", commitSHA) |
| 731 | |
| 732 | var contents []struct { |
| 733 | Name string `json:"name"` |
| 734 | Path string `json:"path"` |
| 735 | SHA string `json:"sha"` |
| 736 | Type string `json:"type"` |
| 737 | } |
| 738 | if err := client.REST(host, "GET", apiPath.String(), nil, &contents); err != nil { |
| 739 | return nil, fmt.Errorf("path %q not found in %s/%s: %w", parentPath, owner, repo, err) |
| 740 | } |
| 741 | |
| 742 | var treeSHA string |
| 743 | for _, entry := range contents { |
| 744 | if entry.Name == skillName && entry.Type == "dir" { |
| 745 | treeSHA = entry.SHA |
| 746 | break |
| 747 | } |
| 748 | } |
| 749 | if treeSHA == "" { |
| 750 | return nil, fmt.Errorf("skill directory %q not found in %s/%s", skillPath, owner, repo) |
| 751 | } |
| 752 | |
| 753 | skillTreePath, err := safeurl.JoinPath("repos", owner, repo, "git", "trees", treeSHA) |
| 754 | if err != nil { |
| 755 | return nil, err |
| 756 | } |
| 757 | var skillTree treeResponse |
| 758 | if err := client.REST(host, "GET", skillTreePath.String(), nil, &skillTree); err != nil { |
| 759 | return nil, fmt.Errorf("could not read skill directory: %w", err) |
| 760 | } |
| 761 | |
| 762 | var blobSHA string |
| 763 | for _, entry := range skillTree.Tree { |
| 764 | if entry.Path == "SKILL.md" && entry.Type == "blob" { |
| 765 | blobSHA = entry.SHA |
| 766 | break |
| 767 | } |
| 768 | } |
| 769 | if blobSHA == "" { |
| 770 | return nil, fmt.Errorf("no SKILL.md found in %s", skillPath) |
| 771 | } |
| 772 | |
| 773 | var namespace, convention string |