| 253 | } |
| 254 | |
| 255 | func installRun(opts *InstallOptions) error { |
| 256 | cs := opts.IO.ColorScheme() |
| 257 | canPrompt := opts.IO.CanPrompt() |
| 258 | |
| 259 | if opts.localPath != "" { |
| 260 | return runLocalInstall(opts) |
| 261 | } |
| 262 | |
| 263 | repo, repoSource, err := resolveRepoArg(opts.SkillSource, canPrompt, opts.Prompter) |
| 264 | if err != nil { |
| 265 | return err |
| 266 | } |
| 267 | opts.repo = repo |
| 268 | opts.SkillSource = repoSource |
| 269 | |
| 270 | parseSkillFromOpts(opts) |
| 271 | |
| 272 | httpClient, err := opts.HttpClient() |
| 273 | if err != nil { |
| 274 | return err |
| 275 | } |
| 276 | apiClient := api.NewClientFromHTTP(httpClient) |
| 277 | |
| 278 | hostname := opts.repo.RepoHost() |
| 279 | if err := source.ValidateSupportedHost(hostname); err != nil { |
| 280 | return err |
| 281 | } |
| 282 | |
| 283 | // Kick off the visibility fetch in parallel with the install work so |
| 284 | // the extra API roundtrip doesn't add latency on the critical path. |
| 285 | // The result is consumed when the telemetry event is emitted below. |
| 286 | // Capture repo fields now to avoid a data race if opts.repo is |
| 287 | // swapped during an upstream redirect. |
| 288 | type visResult struct { |
| 289 | vis discovery.RepoVisibility |
| 290 | err error |
| 291 | } |
| 292 | visCh := make(chan visResult, 1) |
| 293 | visOwner := opts.repo.RepoOwner() |
| 294 | visRepo := opts.repo.RepoName() |
| 295 | go func() { |
| 296 | vis, err := discovery.FetchRepoVisibility(apiClient, hostname, visOwner, visRepo) |
| 297 | visCh <- visResult{vis: vis, err: err} |
| 298 | }() |
| 299 | |
| 300 | resolved, err := resolveVersion(opts, apiClient, hostname) |
| 301 | if err != nil { |
| 302 | return err |
| 303 | } |
| 304 | |
| 305 | var selectedSkills []discovery.Skill |
| 306 | |
| 307 | if discovery.IsSkillPath(opts.SkillName) { |
| 308 | opts.IO.StartProgressIndicatorWithLabel("Looking up skill") |
| 309 | skill, err := discovery.DiscoverSkillByPath(apiClient, hostname, opts.repo.RepoOwner(), opts.repo.RepoName(), resolved.SHA, opts.SkillName) |
| 310 | opts.IO.StopProgressIndicator() |
| 311 | if err != nil { |
| 312 | return err |