diff --git a/cmd/cmd.go b/cmd/cmd.go index 257a2d157..0cafb4c1b 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -2031,7 +2031,7 @@ func NewCLI() *cobra.Command { copyCmd, deleteCmd, runnerCmd, - config.ConfigCmd(checkServerHeartbeat), + config.LaunchCmd(checkServerHeartbeat), ) return rootCmd diff --git a/cmd/config/integrations.go b/cmd/config/integrations.go index bce1cfa45..6b5f2a616 100644 --- a/cmd/config/integrations.go +++ b/cmd/config/integrations.go @@ -230,15 +230,15 @@ func runIntegration(name, modelName string) error { return r.Run(modelName) } -// ConfigCmd returns the cobra command for configuring integrations. -func ConfigCmd(checkServerHeartbeat func(cmd *cobra.Command, args []string) error) *cobra.Command { +// LaunchCmd returns the cobra command for launching integrations. +func LaunchCmd(checkServerHeartbeat func(cmd *cobra.Command, args []string) error) *cobra.Command { var modelFlag string - var launchFlag bool + var configFlag bool cmd := &cobra.Command{ - Use: "config [INTEGRATION]", - Short: "Configure an external integration to use Ollama", - Long: `Configure an external application to use Ollama models. + Use: "launch [INTEGRATION]", + Short: "Launch an integration with Ollama", + Long: `Launch an integration configured with Ollama models. Supported integrations: claude Claude Code @@ -247,9 +247,10 @@ Supported integrations: opencode OpenCode Examples: - ollama config - ollama config claude - ollama config droid --launch`, + ollama launch + ollama launch claude + ollama launch claude --model + ollama launch droid --config (does not auto-launch)`, Args: cobra.MaximumNArgs(1), PreRunE: checkServerHeartbeat, RunE: func(cmd *cobra.Command, args []string) error { @@ -272,8 +273,8 @@ Examples: return fmt.Errorf("unknown integration: %s", name) } - // If --launch without --model, use saved config if available - if launchFlag && modelFlag == "" { + // If launching without --model, use saved config if available + if !configFlag && modelFlag == "" { if config, err := loadIntegration(name); err == nil && len(config.Models) > 0 { return runIntegration(name, config.Models[0]) } @@ -334,29 +335,19 @@ Examples: } } - if slices.ContainsFunc(models, func(m string) bool { - return !strings.HasSuffix(m, "cloud") - }) { - fmt.Fprintln(os.Stderr) - fmt.Fprintln(os.Stderr, "Coding agents work best with at least 64k context. Either:") - fmt.Fprintln(os.Stderr, " - Set the context slider in Ollama app settings") - fmt.Fprintln(os.Stderr, " - Run: OLLAMA_CONTEXT_LENGTH=64000 ollama serve") + if configFlag { + if launch, _ := confirmPrompt(fmt.Sprintf("\nLaunch %s now?", r)); launch { + return runIntegration(name, models[0]) + } + fmt.Fprintf(os.Stderr, "Run 'ollama launch %s' to start with %s\n", strings.ToLower(name), models[0]) + return nil } - if launchFlag { - return runIntegration(name, models[0]) - } - - if launch, _ := confirmPrompt(fmt.Sprintf("\nLaunch %s now?", r)); launch { - return runIntegration(name, models[0]) - } - - fmt.Fprintf(os.Stderr, "Run 'ollama config %s --launch' to start with %s\n", strings.ToLower(name), models[0]) - return nil + return runIntegration(name, models[0]) }, } cmd.Flags().StringVar(&modelFlag, "model", "", "Model to use") - cmd.Flags().BoolVar(&launchFlag, "launch", false, "Launch the integration after configuring") + cmd.Flags().BoolVar(&configFlag, "config", false, "Configure without launching") return cmd } diff --git a/cmd/config/integrations_test.go b/cmd/config/integrations_test.go index d8ad10ce2..48f357db3 100644 --- a/cmd/config/integrations_test.go +++ b/cmd/config/integrations_test.go @@ -81,17 +81,17 @@ func TestHasLocalModel(t *testing.T) { } } -func TestConfigCmd(t *testing.T) { +func TestLaunchCmd(t *testing.T) { // Mock checkServerHeartbeat that always succeeds mockCheck := func(cmd *cobra.Command, args []string) error { return nil } - cmd := ConfigCmd(mockCheck) + cmd := LaunchCmd(mockCheck) t.Run("command structure", func(t *testing.T) { - if cmd.Use != "config [INTEGRATION]" { - t.Errorf("Use = %q, want %q", cmd.Use, "config [INTEGRATION]") + if cmd.Use != "launch [INTEGRATION]" { + t.Errorf("Use = %q, want %q", cmd.Use, "launch [INTEGRATION]") } if cmd.Short == "" { t.Error("Short description should not be empty") @@ -107,9 +107,9 @@ func TestConfigCmd(t *testing.T) { t.Error("--model flag should exist") } - launchFlag := cmd.Flags().Lookup("launch") - if launchFlag == nil { - t.Error("--launch flag should exist") + configFlag := cmd.Flags().Lookup("config") + if configFlag == nil { + t.Error("--config flag should exist") } }) @@ -158,11 +158,11 @@ func TestHasLocalModel_DocumentsHeuristic(t *testing.T) { } } -func TestConfigCmd_NilHeartbeat(t *testing.T) { +func TestLaunchCmd_NilHeartbeat(t *testing.T) { // This should not panic - cmd creation should work even with nil - cmd := ConfigCmd(nil) + cmd := LaunchCmd(nil) if cmd == nil { - t.Fatal("ConfigCmd returned nil") + t.Fatal("LaunchCmd returned nil") } // PreRunE should be nil when passed nil diff --git a/cmd/config/selector.go b/cmd/config/selector.go index 1ef748599..e55323849 100644 --- a/cmd/config/selector.go +++ b/cmd/config/selector.go @@ -465,7 +465,7 @@ func confirmPrompt(prompt string) (bool, error) { } defer term.Restore(fd, oldState) - fmt.Fprintf(os.Stderr, "%s [y/n] ", prompt) + fmt.Fprintf(os.Stderr, "%s (\033[1my\033[0m/n) ", prompt) buf := make([]byte, 1) for {