listAvailableSkills prints discovered skills as a table for non-interactive callers, mirroring the information shown in the interactive picker so the output can be browsed or piped into tools like grep.
(opts *InstallOptions, skills []discovery.Skill, sel skillSelector)
| 762 | // callers, mirroring the information shown in the interactive picker so the |
| 763 | // output can be browsed or piped into tools like grep. |
| 764 | func listAvailableSkills(opts *InstallOptions, skills []discovery.Skill, sel skillSelector) error { |
| 765 | if len(skills) == 0 { |
| 766 | return fmt.Errorf("no skills found in %s", sel.sourceHint) |
| 767 | } |
| 768 | |
| 769 | if sel.fetchDescriptions != nil { |
| 770 | sel.fetchDescriptions() |
| 771 | } |
| 772 | |
| 773 | if opts.IO.IsStdoutTTY() { |
| 774 | fmt.Fprintf(opts.IO.ErrOut, "Showing %s from %s. Re-run with a skill name to install.\n\n", |
| 775 | text.Pluralize(len(skills), "skill"), sel.sourceHint) |
| 776 | } |
| 777 | |
| 778 | tw := opts.IO.TerminalWidth() |
| 779 | descWidth := tw - 40 |
| 780 | if descWidth < 20 { |
| 781 | descWidth = 20 |
| 782 | } |
| 783 | isTTY := opts.IO.IsStdoutTTY() |
| 784 | |
| 785 | table := tableprinter.New(opts.IO, tableprinter.WithHeader("SKILL", "DESCRIPTION")) |
| 786 | for _, s := range skills { |
| 787 | table.AddField(s.DisplayName()) |
| 788 | desc := s.Description |
| 789 | if isTTY { |
| 790 | desc = text.Truncate(descWidth, desc) |
| 791 | } |
| 792 | table.AddField(desc) |
| 793 | table.EndRow() |
| 794 | } |
| 795 | return table.Render() |
| 796 | } |
| 797 | |
| 798 | func matchSkillByName(opts *InstallOptions, skills []discovery.Skill) ([]discovery.Skill, error) { |
| 799 | for _, s := range skills { |
no test coverage detected