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