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