promptSelectApp runs a multi-select picker for target code agents. Shows only installed agents (binary found on PATH), matching the gh skill interactive picker format with display names.
(kind entities.Kind)
| 2015 | // Shows only installed agents (binary found on PATH), matching |
| 2016 | // the gh skill interactive picker format with display names. |
| 2017 | func promptSelectApp(kind entities.Kind) ([]string, error) { |
| 2018 | apps := entities.AppPathsFor(kind) |
| 2019 | allAgents := entities.AllAgents() |
| 2020 | |
| 2021 | var items []multiSelectItem |
| 2022 | for _, info := range allAgents { |
| 2023 | if _, ok := apps[info.ID]; !ok { |
| 2024 | continue // agent doesn't support this kind |
| 2025 | } |
| 2026 | if !entities.IsAgentInstalled(info) { |
| 2027 | continue // not installed on this system |
| 2028 | } |
| 2029 | items = append(items, multiSelectItem{ |
| 2030 | label: info.DisplayName, |
| 2031 | }) |
| 2032 | } |
| 2033 | |
| 2034 | if len(items) == 0 { |
| 2035 | return nil, fmt.Errorf("no code agents found on PATH (install one or use --app)") |
| 2036 | } |
| 2037 | |
| 2038 | selected, err := runMultiSelect("Select target agent(s):", items) |
| 2039 | if err != nil { |
| 2040 | supported := entities.SupportedApps(kind) |
| 2041 | return nil, fmt.Errorf("--app is required (one of: %s)", strings.Join(supported, ", ")) |
| 2042 | } |
| 2043 | if len(selected) == 0 { |
| 2044 | return nil, fmt.Errorf("no agent selected") |
| 2045 | } |
| 2046 | |
| 2047 | // Map display names back to IDs. |
| 2048 | var ids []string |
| 2049 | for _, displayName := range selected { |
| 2050 | for _, info := range allAgents { |
| 2051 | if info.DisplayName == displayName { |
| 2052 | ids = append(ids, info.ID) |
| 2053 | break |
| 2054 | } |
| 2055 | } |
| 2056 | } |
| 2057 | return ids, nil |
| 2058 | } |
| 2059 | |
| 2060 | // parseRepoArg splits "owner/repo" or "owner/repo@branch" into components. |
| 2061 | func parseRepoArg(arg string) (owner, repo, branch string) { |
no test coverage detected