FetchBlob retrieves the content of a blob by SHA. The blob is base64-encoded inside the JSON response and decoded here, so it is returned as iostreams.Untrusted and callers must choose sanitized display or raw round-tripping.
(client *api.Client, host, owner, repo, sha string)
| 917 | // iostreams.Untrusted and callers must choose sanitized display or raw |
| 918 | // round-tripping. |
| 919 | func FetchBlob(client *api.Client, host, owner, repo, sha string) (iostreams.Untrusted, error) { |
| 920 | apiPath, err := safeurl.JoinPath("repos", owner, repo, "git", "blobs", sha) |
| 921 | if err != nil { |
| 922 | return iostreams.Untrusted{}, err |
| 923 | } |
| 924 | var resp struct { |
| 925 | SHA string `json:"sha"` |
| 926 | Content string `json:"content"` |
| 927 | Encoding string `json:"encoding"` |
| 928 | } |
| 929 | if err := client.REST(host, "GET", apiPath.String(), nil, &resp); err != nil { |
| 930 | return iostreams.Untrusted{}, fmt.Errorf("could not fetch blob: %w", err) |
| 931 | } |
| 932 | |
| 933 | if resp.Encoding != "base64" { |
| 934 | return iostreams.Untrusted{}, fmt.Errorf("unexpected blob encoding: %s", resp.Encoding) |
| 935 | } |
| 936 | |
| 937 | // GitHub API returns base64 with embedded newlines; use the StdEncoding |
| 938 | // decoder via a reader to handle them transparently. |
| 939 | decoded, err := io.ReadAll(base64.NewDecoder(base64.StdEncoding, strings.NewReader(resp.Content))) |
| 940 | if err != nil { |
| 941 | return iostreams.Untrusted{}, fmt.Errorf("could not decode blob content: %w", err) |
| 942 | } |
| 943 | |
| 944 | return iostreams.NewUntrustedBytes(decoded), nil |
| 945 | } |
| 946 | |
| 947 | // DiscoverLocalSkills finds non-hidden-dir skills in a local directory using |
| 948 | // the same conventions as remote discovery. Hidden-dir skills are excluded; use |