(opts *InstallOptions, skills []discovery.Skill, targetDir string, canPrompt bool)
| 1033 | } |
| 1034 | |
| 1035 | func checkOverwrite(opts *InstallOptions, skills []discovery.Skill, targetDir string, canPrompt bool) ([]discovery.Skill, error) { |
| 1036 | var existing, fresh []discovery.Skill |
| 1037 | for _, s := range skills { |
| 1038 | dir := filepath.Join(targetDir, s.Name) |
| 1039 | if _, err := os.Stat(dir); err == nil { |
| 1040 | existing = append(existing, s) |
| 1041 | } else { |
| 1042 | fresh = append(fresh, s) |
| 1043 | } |
| 1044 | } |
| 1045 | |
| 1046 | if len(existing) == 0 { |
| 1047 | return skills, nil |
| 1048 | } |
| 1049 | |
| 1050 | if opts.Force { |
| 1051 | return skills, nil |
| 1052 | } |
| 1053 | |
| 1054 | if !canPrompt { |
| 1055 | names := make([]string, len(existing)) |
| 1056 | for i, s := range existing { |
| 1057 | names[i] = s.DisplayName() |
| 1058 | } |
| 1059 | return nil, fmt.Errorf("skills already installed: %s (use --force to overwrite)", strings.Join(names, ", ")) |
| 1060 | } |
| 1061 | |
| 1062 | var confirmed []discovery.Skill |
| 1063 | for _, s := range existing { |
| 1064 | prompt := existingSkillPrompt(targetDir, s) |
| 1065 | ok, err := opts.Prompter.Confirm(prompt, false) |
| 1066 | if err != nil { |
| 1067 | return nil, err |
| 1068 | } |
| 1069 | if ok { |
| 1070 | confirmed = append(confirmed, s) |
| 1071 | } else { |
| 1072 | fmt.Fprintf(opts.IO.ErrOut, "Skipping %s\n", s.DisplayName()) |
| 1073 | } |
| 1074 | } |
| 1075 | |
| 1076 | return append(fresh, confirmed...), nil |
| 1077 | } |
| 1078 | |
| 1079 | func existingSkillPrompt(targetDir string, incoming discovery.Skill) string { |
| 1080 | skillFile := filepath.Join(targetDir, incoming.Name, "SKILL.md") |
no test coverage detected