(args []string, forceDefault bool)
| 114 | } |
| 115 | |
| 116 | // cmdSkill dispatches `flow skill install|uninstall|update`. |
| 117 | func cmdSkill(args []string) int { |
| 118 | if len(args) == 0 { |
| 119 | fmt.Fprintln(os.Stderr, "error: skill requires a subcommand (install|uninstall|update)") |
| 120 | return 2 |
| 121 | } |
| 122 | sub, rest := args[0], args[1:] |
| 123 | switch sub { |
| 124 | case "install": |
| 125 | return skillInstall(rest, false) |
| 126 | case "update": |
| 127 | return skillInstall(rest, true) |
| 128 | case "uninstall": |
| 129 | return skillUninstall(rest) |
| 130 | default: |
| 131 | fmt.Fprintf(os.Stderr, "error: unknown skill subcommand %q\n", sub) |
| 132 | return 2 |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | func skillInstall(args []string, forceDefault bool) int { |
| 137 | fs := flagSet("skill install") |
| 138 | force := fs.Bool("force", forceDefault, "overwrite an existing installation") |
| 139 | skipHook := fs.Bool("skip-hook", false, "don't auto-install the SessionStart hook") |
| 140 | if err := fs.Parse(args); err != nil { |
| 141 | return 2 |
| 142 | } |
| 143 | |
| 144 | h := defaultHarness() |
| 145 | dest, err := h.SkillInstallPath() |
| 146 | if err != nil { |
| 147 | fmt.Fprintf(os.Stderr, "error: %v\n", err) |
| 148 | return 1 |
| 149 | } |
| 150 | if _, err := os.Stat(dest); err == nil && !*force { |
| 151 | fmt.Fprintf(os.Stderr, "error: %s already exists; use --force to overwrite\n", dest) |
| 152 | return 1 |
| 153 | } else if err != nil && !os.IsNotExist(err) { |
| 154 | fmt.Fprintf(os.Stderr, "error: stat %s: %v\n", dest, err) |
| 155 | return 1 |
| 156 | } |
| 157 | if err := h.InstallSkill(skillFiles()); err != nil { |
| 158 | fmt.Fprintf(os.Stderr, "error: %v\n", err) |
| 159 | return 1 |
| 160 | } |
| 161 | if err := writeSkillVersion(Version); err != nil { |
| 162 | fmt.Fprintf(os.Stderr, "warning: could not record skill version: %v\n", err) |
| 163 | } |
| 164 | fmt.Printf("installed flow skill to %s\n", dest) |
| 165 | |
| 166 | if *skipHook { |
| 167 | fmt.Println("--skip-hook: leaving harness settings alone") |
| 168 | return 0 |
| 169 | } |
| 170 | if added, err := h.InstallSessionStartHook(hookCommand); err != nil { |
| 171 | fmt.Fprintf(os.Stderr, "warning: could not install SessionStart hook: %v\n", err) |
| 172 | // Non-fatal: the skill is still usable without the hook; the |
| 173 | // user can wire it manually. Return 0 so `flow init` doesn't |
no test coverage detected