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