fix github blob skill URL installs and metadata links
This commit is contained in:
parent
954ea3be14
commit
ef6fbef559
4 changed files with 65 additions and 3 deletions
|
|
@ -93,7 +93,11 @@ func (r *GitHubRegistry) SkillURL(target, version string) string {
|
||||||
return fmt.Sprintf("%s/%s", base, urlPath)
|
return fmt.Sprintf("%s/%s", base, urlPath)
|
||||||
}
|
}
|
||||||
if ref.SubPath != "" {
|
if ref.SubPath != "" {
|
||||||
return fmt.Sprintf("%s/%s/tree/%s/%s", base, urlPath, ref.Ref, ref.SubPath)
|
viewKind := "tree"
|
||||||
|
if isSkillMarkdownPath(ref.SubPath) {
|
||||||
|
viewKind = "blob"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s/%s/%s/%s/%s", base, urlPath, viewKind, ref.Ref, ref.SubPath)
|
||||||
}
|
}
|
||||||
if ref.Ref != "main" {
|
if ref.Ref != "main" {
|
||||||
return fmt.Sprintf("%s/%s/tree/%s", base, urlPath, ref.Ref)
|
return fmt.Sprintf("%s/%s/tree/%s", base, urlPath, ref.Ref)
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,11 @@ func TestGitHubRegistrySkillURLUsesProvidedVersionAndBasePath(t *testing.T) {
|
||||||
"https://ghe.example.com/git/org/repo/tree/feature/skills-registry/skills/pr-review",
|
"https://ghe.example.com/git/org/repo/tree/feature/skills-registry/skills/pr-review",
|
||||||
registry.SkillURL("org/repo/skills/pr-review", "feature/skills-registry"),
|
registry.SkillURL("org/repo/skills/pr-review", "feature/skills-registry"),
|
||||||
)
|
)
|
||||||
|
assert.Equal(
|
||||||
|
t,
|
||||||
|
"https://ghe.example.com/git/org/repo/blob/main/.agents/skills/pr-review/SKILL.md",
|
||||||
|
registry.SkillURL("https://ghe.example.com/git/org/repo/blob/main/.agents/skills/pr-review/SKILL.md", ""),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGitHubRegistryResolveInstallDirNameSupportsFullURLs(t *testing.T) {
|
func TestGitHubRegistryResolveInstallDirNameSupportsFullURLs(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ func looksLikeSkillSubPath(subPath string) bool {
|
||||||
if subPath == "" {
|
if subPath == "" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if subPath == "SKILL.md" || strings.HasSuffix(subPath, "/SKILL.md") {
|
if isSkillMarkdownPath(subPath) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
parts := strings.Split(subPath, "/")
|
parts := strings.Split(subPath, "/")
|
||||||
|
|
@ -230,6 +230,11 @@ func looksLikeSkillSubPath(subPath string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isSkillMarkdownPath(subPath string) bool {
|
||||||
|
subPath = strings.Trim(strings.TrimSpace(subPath), "/")
|
||||||
|
return subPath == "SKILL.md" || strings.HasSuffix(subPath, "/SKILL.md")
|
||||||
|
}
|
||||||
|
|
||||||
// parseGitHubRef parses a GitHub reference.
|
// parseGitHubRef parses a GitHub reference.
|
||||||
// Supports: "owner/repo", "owner/repo/path", or full URL like "https://github.com/owner/repo/tree/ref/path"
|
// Supports: "owner/repo", "owner/repo/path", or full URL like "https://github.com/owner/repo/tree/ref/path"
|
||||||
func parseGitHubRef(repo string) (GitHubRef, error) {
|
func parseGitHubRef(repo string) (GitHubRef, error) {
|
||||||
|
|
@ -462,8 +467,12 @@ func (si *SkillInstaller) getGithubDirAllFiles(ctx context.Context, apiURL, loca
|
||||||
func (si *SkillInstaller) downloadRaw(ctx context.Context, owner, repo, ref, subPath, localDir string) error {
|
func (si *SkillInstaller) downloadRaw(ctx context.Context, owner, repo, ref, subPath, localDir string) error {
|
||||||
urlPath := path.Join(owner, repo, ref)
|
urlPath := path.Join(owner, repo, ref)
|
||||||
if subPath != "" {
|
if subPath != "" {
|
||||||
|
if isSkillMarkdownPath(subPath) {
|
||||||
|
urlPath = strings.TrimSuffix(path.Join(urlPath, subPath), "/SKILL.md")
|
||||||
|
} else {
|
||||||
urlPath = path.Join(urlPath, subPath)
|
urlPath = path.Join(urlPath, subPath)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
url := fmt.Sprintf("%s/%s/SKILL.md", si.githubRawBaseURL, urlPath)
|
url := fmt.Sprintf("%s/%s/SKILL.md", si.githubRawBaseURL, urlPath)
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,50 @@ func TestSkillInstallerResolveGitHubRefUsesDefaultBranch(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSkillInstallerInstallFromGitHubToDirSupportsBlobSkillURL(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
var server *httptest.Server
|
||||||
|
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.URL.Path {
|
||||||
|
case "/api/v3/repos/org/repo/contents/.agents/skills/pr-review/SKILL.md":
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write([]byte(`{"type":"file","name":"SKILL.md"}`))
|
||||||
|
case "/raw/org/repo/main/.agents/skills/pr-review/SKILL.md":
|
||||||
|
_, _ = w.Write([]byte("---\nname: pr-review\ndescription: PR review skill\n---\n# PR Review\n"))
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected path: %s", r.URL.Path)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
installer, err := NewSkillInstallerWithBaseURL(tmpDir, server.URL, "", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewSkillInstallerWithBaseURL() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
targetDir := filepath.Join(tmpDir, "skills", "pr-review")
|
||||||
|
result, err := installer.InstallFromGitHubToDir(
|
||||||
|
context.Background(),
|
||||||
|
server.URL+"/org/repo/blob/main/.agents/skills/pr-review/SKILL.md",
|
||||||
|
"",
|
||||||
|
targetDir,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("InstallFromGitHubToDir() error = %v", err)
|
||||||
|
}
|
||||||
|
if result.Version != "main" {
|
||||||
|
t.Fatalf("version = %q, want main", result.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := os.ReadFile(filepath.Join(targetDir, "SKILL.md"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ReadFile(SKILL.md) error = %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(content), "name: pr-review") {
|
||||||
|
t.Fatalf("SKILL.md content = %q, want skill metadata", string(content))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestShouldDownload(t *testing.T) {
|
func TestShouldDownload(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue